Skip to content

Commit 1580f5a

Browse files
speedstorm1copybara-github
authored andcommitted
feat: Add support for models.embed_content(), models.get(), models.update(), and models.delete() in C# SDK
PiperOrigin-RevId: 834430387
1 parent 8c8eee1 commit 1580f5a

36 files changed

+8726
-82
lines changed
Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
/*
2+
* Copyright 2025 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
using System;
18+
using System.Collections.Generic;
19+
using System.Linq;
20+
using System.Threading.Tasks;
21+
22+
using Google.GenAI;
23+
using Google.GenAI.Types;
24+
25+
using Microsoft.VisualStudio.TestTools.UnitTesting;
26+
27+
using TestServerSdk;
28+
29+
[TestClass]
30+
public class EmbedContentTest {
31+
private static TestServerProcess? _server;
32+
private Client vertexClient;
33+
private Client geminiClient;
34+
private string modelName;
35+
public TestContext TestContext { get; set; }
36+
37+
[ClassInitialize]
38+
public static void ClassInit(TestContext _) {
39+
_server = TestServer.StartTestServer();
40+
}
41+
42+
[ClassCleanup]
43+
public static void ClassCleanup() {
44+
TestServer.StopTestServer(_server);
45+
}
46+
47+
[TestInitialize]
48+
public void TestInit() {
49+
// Test server specific setup.
50+
if (_server == null) {
51+
throw new InvalidOperationException("Test server is not initialized.");
52+
}
53+
var geminiClientHttpOptions = new HttpOptions {
54+
Headers = new Dictionary<string, string> { { "Test-Name",
55+
$"{GetType().Name}.{TestContext.TestName}" } },
56+
BaseUrl = "http://localhost:1453"
57+
};
58+
var vertexClientHttpOptions = new HttpOptions {
59+
Headers = new Dictionary<string, string> { { "Test-Name",
60+
$"{GetType().Name}.{TestContext.TestName}" } },
61+
BaseUrl = "http://localhost:1454"
62+
};
63+
64+
// Common setup for both clients.
65+
string project = System.Environment.GetEnvironmentVariable("GOOGLE_CLOUD_PROJECT");
66+
string location =
67+
System.Environment.GetEnvironmentVariable("GOOGLE_CLOUD_LOCATION") ?? "us-central1";
68+
string apiKey = System.Environment.GetEnvironmentVariable("GOOGLE_API_KEY");
69+
vertexClient = new Client(project: project, location: location, vertexAI: true,
70+
credential: TestServer.GetCredentialForTestMode(),
71+
httpOptions: vertexClientHttpOptions);
72+
geminiClient =
73+
new Client(apiKey: apiKey, vertexAI: false, httpOptions: geminiClientHttpOptions);
74+
75+
// Specific setup for this test class
76+
modelName = "text-embedding-004";
77+
}
78+
79+
[TestMethod]
80+
public async Task EmbedContentSimpleTextVertexTest() {
81+
var contents = new List<Content> {
82+
new Content { Parts = new List<Part> { new Part { Text = "What is your name?" } } }
83+
};
84+
var vertexResponse = await vertexClient.Models.EmbedContentAsync(
85+
model: modelName, contents: contents, config: null);
86+
87+
Assert.IsNotNull(vertexResponse.Embeddings);
88+
}
89+
90+
[TestMethod]
91+
public async Task EmbedContentSimpleTextGeminiTest() {
92+
var contents = new List<Content> {
93+
new Content { Parts = new List<Part> { new Part { Text = "What is your name?" } } }
94+
};
95+
var geminiResponse = await geminiClient.Models.EmbedContentAsync(
96+
model: modelName, contents: contents, config: null);
97+
98+
Assert.IsNotNull(geminiResponse.Embeddings);
99+
}
100+
101+
[TestMethod]
102+
public async Task EmbedContentSingleStringVertexTest() {
103+
var vertexResponse = await vertexClient.Models.EmbedContentAsync(
104+
model: modelName, contents: "What is your name?", config: null);
105+
106+
Assert.IsNotNull(vertexResponse.Embeddings);
107+
}
108+
109+
[TestMethod]
110+
public async Task EmbedContentSingleStringGeminiTest() {
111+
var geminiResponse = await geminiClient.Models.EmbedContentAsync(
112+
model: modelName, contents: "What is your name?", config: null);
113+
114+
Assert.IsNotNull(geminiResponse.Embeddings);
115+
}
116+
117+
[TestMethod]
118+
public async Task EmbedContentMultiTextVertexTest() {
119+
var contents = new List<Content> {
120+
new Content { Parts = new List<Part> { new Part { Text = "What is your name?" } } },
121+
new Content { Parts = new List<Part> { new Part { Text = "I am a model." } } }
122+
};
123+
var config = new EmbedContentConfig { OutputDimensionality = 10, Title = "test_title",
124+
TaskType = "RETRIEVAL_DOCUMENT" };
125+
var vertexResponse =
126+
await vertexClient.Models.EmbedContentAsync(model: modelName, contents: contents, config: config);
127+
128+
Assert.IsNotNull(vertexResponse.Embeddings);
129+
Assert.AreEqual(2, vertexResponse.Embeddings.Count);
130+
}
131+
132+
[TestMethod]
133+
public async Task EmbedContentMultiTextGeminiTest() {
134+
var contents = new List<Content> {
135+
new Content { Parts = new List<Part> { new Part { Text = "What is your name?" } } },
136+
new Content { Parts = new List<Part> { new Part { Text = "I am a model." } } }
137+
};
138+
var config = new EmbedContentConfig { OutputDimensionality = 10, Title = "test_title",
139+
TaskType = "RETRIEVAL_DOCUMENT" };
140+
var geminiResponse =
141+
await geminiClient.Models.EmbedContentAsync(model: modelName, contents: contents, config: config);
142+
143+
Assert.IsNotNull(geminiResponse.Embeddings);
144+
Assert.AreEqual(2, geminiResponse.Embeddings.Count);
145+
}
146+
}
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
/*
2+
* Copyright 2025 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
using System;
18+
using System.Collections.Generic;
19+
using System.Linq;
20+
using System.Threading.Tasks;
21+
22+
using Google.GenAI;
23+
using Google.GenAI.Types;
24+
25+
using Microsoft.VisualStudio.TestTools.UnitTesting;
26+
27+
using TestServerSdk;
28+
29+
[TestClass]
30+
public class DeleteModelTest {
31+
private static TestServerProcess? _server;
32+
private Client vertexClient;
33+
private Client geminiClient;
34+
public TestContext TestContext { get; set; }
35+
36+
[ClassInitialize]
37+
public static void ClassInit(TestContext _) {
38+
_server = TestServer.StartTestServer();
39+
}
40+
41+
[ClassCleanup]
42+
public static void ClassCleanup() {
43+
TestServer.StopTestServer(_server);
44+
}
45+
46+
[TestInitialize]
47+
public void TestInit() {
48+
// Test server specific setup.
49+
if (_server == null) {
50+
throw new InvalidOperationException("Test server is not initialized.");
51+
}
52+
var geminiClientHttpOptions = new HttpOptions {
53+
Headers = new Dictionary<string, string> { { "Test-Name",
54+
$"{GetType().Name}.{TestContext.TestName}" } },
55+
BaseUrl = "http://localhost:1453"
56+
};
57+
var vertexClientHttpOptions = new HttpOptions {
58+
Headers = new Dictionary<string, string> { { "Test-Name",
59+
$"{GetType().Name}.{TestContext.TestName}" } },
60+
BaseUrl = "http://localhost:1454"
61+
};
62+
63+
// Common setup for both clients.
64+
string project = System.Environment.GetEnvironmentVariable("GOOGLE_CLOUD_PROJECT");
65+
string location =
66+
System.Environment.GetEnvironmentVariable("GOOGLE_CLOUD_LOCATION") ?? "us-central1";
67+
string apiKey = System.Environment.GetEnvironmentVariable("GOOGLE_API_KEY");
68+
vertexClient = new Client(project: project, location: location, vertexAI: true,
69+
credential: TestServer.GetCredentialForTestMode(),
70+
httpOptions: vertexClientHttpOptions);
71+
geminiClient =
72+
new Client(apiKey: apiKey, vertexAI: false, httpOptions: geminiClientHttpOptions);
73+
}
74+
75+
[TestMethod]
76+
public async Task DeleteModelVertexTest() {
77+
var vertexResponse =
78+
await vertexClient.Models.DeleteAsync(model: "models/89657476663738368", config: null);
79+
80+
Assert.IsNotNull(vertexResponse);
81+
}
82+
83+
[TestMethod]
84+
public async Task DeleteModelGeminiTest() {
85+
var geminiResponse =
86+
await geminiClient.Models.DeleteAsync(model: "tunedModels/generate-num-1896", config: null);
87+
88+
Assert.IsNotNull(geminiResponse);
89+
}
90+
}
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
/*
2+
* Copyright 2025 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
using System;
18+
using System.Collections.Generic;
19+
using System.Linq;
20+
using System.Threading.Tasks;
21+
22+
using Google.GenAI;
23+
using Google.GenAI.Types;
24+
25+
using Microsoft.VisualStudio.TestTools.UnitTesting;
26+
27+
using TestServerSdk;
28+
29+
[TestClass]
30+
public class GetModelTest {
31+
private static TestServerProcess? _server;
32+
private Client vertexClient;
33+
private Client geminiClient;
34+
private string modelName;
35+
public TestContext TestContext { get; set; }
36+
37+
[ClassInitialize]
38+
public static void ClassInit(TestContext _) {
39+
_server = TestServer.StartTestServer();
40+
}
41+
42+
[ClassCleanup]
43+
public static void ClassCleanup() {
44+
TestServer.StopTestServer(_server);
45+
}
46+
47+
[TestInitialize]
48+
public void TestInit() {
49+
// Test server specific setup.
50+
if (_server == null) {
51+
throw new InvalidOperationException("Test server is not initialized.");
52+
}
53+
var geminiClientHttpOptions = new HttpOptions {
54+
Headers = new Dictionary<string, string> { { "Test-Name",
55+
$"{GetType().Name}.{TestContext.TestName}" } },
56+
BaseUrl = "http://localhost:1453"
57+
};
58+
var vertexClientHttpOptions = new HttpOptions {
59+
Headers = new Dictionary<string, string> { { "Test-Name",
60+
$"{GetType().Name}.{TestContext.TestName}" } },
61+
BaseUrl = "http://localhost:1454"
62+
};
63+
64+
// Common setup for both clients.
65+
string project = System.Environment.GetEnvironmentVariable("GOOGLE_CLOUD_PROJECT");
66+
string location =
67+
System.Environment.GetEnvironmentVariable("GOOGLE_CLOUD_LOCATION") ?? "us-central1";
68+
string apiKey = System.Environment.GetEnvironmentVariable("GOOGLE_API_KEY");
69+
vertexClient = new Client(project: project, location: location, vertexAI: true,
70+
credential: TestServer.GetCredentialForTestMode(),
71+
httpOptions: vertexClientHttpOptions);
72+
geminiClient =
73+
new Client(apiKey: apiKey, vertexAI: false, httpOptions: geminiClientHttpOptions);
74+
75+
// Specific setup for this test class
76+
modelName = "gemini-2.5-flash";
77+
}
78+
79+
[TestMethod]
80+
public async Task GetModelTunedVertexTest() {
81+
string tunedModel = "models/8611312396578848768";
82+
var vertexResponse = await vertexClient.Models.GetAsync(model: tunedModel, config: null);
83+
84+
Assert.IsNotNull(vertexResponse);
85+
}
86+
87+
[TestMethod]
88+
public async Task GetModelTunedGeminiTest() {
89+
string tunedModel = "tunedModels/generate-num-8498";
90+
var geminiResponse = await geminiClient.Models.GetAsync(model: tunedModel, config: null);
91+
92+
Assert.IsNotNull(geminiResponse);
93+
}
94+
}

0 commit comments

Comments
 (0)