Skip to content

Commit a2bbb00

Browse files
matthew29tangcopybara-github
authored andcommitted
feat: Add ImageResizeMode for GenerateVideos
FUTURE_COPYBARA_INTEGRATE_REVIEW=https://github.com/google-gemini/private-dotnet-genai/pull/75 from google-gemini:vertex b423641c927b1c5e587c4ddb533afec002844b2d PiperOrigin-RevId: 869306823
1 parent 75b52c7 commit a2bbb00

24 files changed

Lines changed: 1072 additions & 676 deletions
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
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.Net.Http;
21+
using System.Threading.Tasks;
22+
23+
using Google.GenAI;
24+
using Google.GenAI.Types;
25+
26+
using Microsoft.VisualStudio.TestTools.UnitTesting;
27+
28+
using TestServerSdk;
29+
30+
[TestClass]
31+
public class GenerateContentSimpleTestCustomClient {
32+
private static TestServerProcess? _server;
33+
private Client vertexClient;
34+
private Client geminiClient;
35+
private string modelName;
36+
public TestContext TestContext { get; set; }
37+
38+
[ClassInitialize]
39+
public static void ClassInit(TestContext _) {
40+
_server = TestServer.StartTestServer();
41+
}
42+
43+
[ClassCleanup]
44+
public static void ClassCleanup() {
45+
TestServer.StopTestServer(_server);
46+
}
47+
48+
[TestInitialize]
49+
public void TestInit() {
50+
// Test server specific setup.
51+
if (_server == null) {
52+
throw new InvalidOperationException("Test server is not initialized.");
53+
}
54+
var geminiClientHttpOptions = new HttpOptions {
55+
Headers = new Dictionary<string, string> { { "Test-Name",
56+
$"{GetType().Name}.{TestContext.TestName}" } },
57+
BaseUrl = "http://localhost:1453"
58+
};
59+
var vertexClientHttpOptions = new HttpOptions {
60+
Headers = new Dictionary<string, string> { { "Test-Name",
61+
$"{GetType().Name}.{TestContext.TestName}" } },
62+
BaseUrl = "http://localhost:1454"
63+
};
64+
65+
// Common setup for both clients.
66+
string project = System.Environment.GetEnvironmentVariable("GOOGLE_CLOUD_PROJECT");
67+
string location =
68+
System.Environment.GetEnvironmentVariable("GOOGLE_CLOUD_LOCATION") ?? "us-central1";
69+
string apiKey = System.Environment.GetEnvironmentVariable("GOOGLE_API_KEY");
70+
vertexClient = new Client(project: project, location: location, vertexAI: true,
71+
credential: TestServer.GetCredentialForTestMode(),
72+
httpOptions: vertexClientHttpOptions,
73+
clientOptions: new ClientOptions {
74+
HttpClientFactory = () => new HttpClient(new HttpClientHandler()) {
75+
Timeout = TimeSpan.FromMinutes(5)
76+
}
77+
});
78+
geminiClient =
79+
new Client(apiKey: apiKey, vertexAI: false, httpOptions: geminiClientHttpOptions,
80+
clientOptions: new ClientOptions {
81+
HttpClientFactory = () => new HttpClient(new HttpClientHandler()) {
82+
Timeout = TimeSpan.FromMinutes(5)
83+
}
84+
});
85+
86+
// Specific setup for this test class
87+
modelName = "gemini-2.5-flash";
88+
}
89+
90+
[TestMethod]
91+
public async Task GenerateContentSimpleTextVertexTest() {
92+
var vertexResponse = await vertexClient.Models.GenerateContentAsync(
93+
model: modelName, contents: "What is the capital of France?");
94+
95+
Assert.IsNotNull(vertexResponse.Candidates);
96+
StringAssert.Contains(vertexResponse.Text, "Paris");
97+
}
98+
99+
[TestMethod]
100+
public async Task GenerateContentSimpleTextGeminiTest() {
101+
var geminiResponse = await geminiClient.Models.GenerateContentAsync(
102+
model: modelName, contents: "What is the capital of France?");
103+
104+
Assert.IsNotNull(geminiResponse.Candidates);
105+
StringAssert.Contains(geminiResponse.Text, "Paris");
106+
}
107+
}

Google.GenAI.E2E.Tests/GenerateVideos/GenerateVideosTest.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -226,8 +226,12 @@ public async Task GenerateVideosSourceImageTextVertexTest() {
226226
Prompt = "A neon hologram of a cat driving at top speed.",
227227
Image = Image.FromFile("TestAssets/bridge1.png"),
228228
};
229+
var config = new GenerateVideosConfig {
230+
NumberOfVideos = 1,
231+
ResizeMode = ImageResizeMode.Crop,
232+
};
229233
var operation = await vertexClient.Models.GenerateVideosAsync(
230-
model: modelName, source: source, config: null);
234+
model: "veo-3.1-generate-001", source: source, config: config);
231235

232236
Assert.IsNotNull(operation.Name);
233237
while (operation.Done != true) {
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
{
2+
"recordID": "GenerateContentSimpleTestCustomClient.GenerateContentSimpleTextGeminiTest",
3+
"interactions": [
4+
{
5+
"request": {
6+
"method": "POST",
7+
"url": "/v1beta/models/gemini-2.5-flash:generateContent",
8+
"request": "POST /v1beta/models/gemini-2.5-flash:generateContent HTTP/1.1",
9+
"headers": {
10+
"Content-Length": "82",
11+
"Content-Type": "application/json; charset=utf-8",
12+
"Test-Name": "GenerateContentSimpleTestCustomClient.GenerateContentSimpleTextGeminiTest"
13+
},
14+
"bodySegments": [
15+
{
16+
"contents": [
17+
{
18+
"parts": [
19+
{
20+
"text": "What is the capital of France?"
21+
}
22+
],
23+
"role": "user"
24+
}
25+
]
26+
}
27+
],
28+
"previousRequest": "b4d6e60a9b97e7b98c63df9308728c5c88c0b40c398046772c63447b94608b4d",
29+
"serverAddress": "generativelanguage.googleapis.com",
30+
"port": 443,
31+
"protocol": "https"
32+
},
33+
"shaSum": "bd8f07a7b3a292d81133f2159caef97891d4d75fbef8f7920f918d41df3aeebf",
34+
"response": {
35+
"statusCode": 200,
36+
"headers": {
37+
"Content-Type": "application/json; charset=UTF-8",
38+
"Date": "Wed, 08 Apr 2026 17:28:13 GMT",
39+
"Server": "scaffolding on HTTPServer2",
40+
"Server-Timing": "gfet4t7; dur=965",
41+
"Vary": "Origin, X-Origin, Referer",
42+
"X-Content-Type-Options": "nosniff",
43+
"X-Frame-Options": "SAMEORIGIN",
44+
"X-Gemini-Service-Tier": "standard",
45+
"X-Xss-Protection": "0"
46+
},
47+
"bodySegments": [
48+
{
49+
"candidates": [
50+
{
51+
"content": {
52+
"parts": [
53+
{
54+
"text": "The capital of France is **Paris**."
55+
}
56+
],
57+
"role": "model"
58+
},
59+
"finishReason": "STOP",
60+
"index": 0
61+
}
62+
],
63+
"modelVersion": "gemini-2.5-flash",
64+
"responseId": "LJDWadScJp2hjrEPw9nW2Ac",
65+
"turnToken": "v1_ChdMSkRXYWRTY0pwMmhqckVQdzluVzJBYxIXTEpEV2FkU2NKcDJoanJFUHc5blcyQWM",
66+
"usageMetadata": {
67+
"candidatesTokenCount": 8,
68+
"promptTokenCount": 8,
69+
"promptTokensDetails": [
70+
{
71+
"modality": "TEXT",
72+
"tokenCount": 8
73+
}
74+
],
75+
"thoughtsTokenCount": 24,
76+
"totalTokenCount": 40
77+
}
78+
}
79+
]
80+
}
81+
}
82+
]
83+
}
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
{
2+
"recordID": "GenerateContentSimpleTestCustomClient.GenerateContentSimpleTextVertexTest",
3+
"interactions": [
4+
{
5+
"request": {
6+
"method": "POST",
7+
"url": "/v1beta1/projects/REDACTED/locations/us-central1/publishers/google/models/gemini-2.5-flash:generateContent",
8+
"request": "POST /v1beta1/projects/REDACTED/locations/us-central1/publishers/google/models/gemini-2.5-flash:generateContent HTTP/1.1",
9+
"headers": {
10+
"Content-Length": "82",
11+
"Content-Type": "application/json; charset=utf-8",
12+
"Test-Name": "GenerateContentSimpleTestCustomClient.GenerateContentSimpleTextVertexTest"
13+
},
14+
"bodySegments": [
15+
{
16+
"contents": [
17+
{
18+
"parts": [
19+
{
20+
"text": "What is the capital of France?"
21+
}
22+
],
23+
"role": "user"
24+
}
25+
]
26+
}
27+
],
28+
"previousRequest": "b4d6e60a9b97e7b98c63df9308728c5c88c0b40c398046772c63447b94608b4d",
29+
"serverAddress": "us-central1-aiplatform.googleapis.com",
30+
"port": 443,
31+
"protocol": "https"
32+
},
33+
"shaSum": "e80d8e3fa830f895d8061c7fa8abadf26b873aaf78d0d72a8ac12cd411739398",
34+
"response": {
35+
"statusCode": 200,
36+
"headers": {
37+
"Content-Type": "application/json; charset=UTF-8",
38+
"Date": "Wed, 08 Apr 2026 17:28:12 GMT",
39+
"Server": "scaffolding on HTTPServer2",
40+
"Vary": "Origin, X-Origin, Referer",
41+
"X-Content-Type-Options": "nosniff",
42+
"X-Frame-Options": "SAMEORIGIN",
43+
"X-Xss-Protection": "0"
44+
},
45+
"bodySegments": [
46+
{
47+
"candidates": [
48+
{
49+
"avgLogprobs": -1.4877158403396606,
50+
"content": {
51+
"parts": [
52+
{
53+
"text": "The capital of France is **Paris**."
54+
}
55+
],
56+
"role": "model"
57+
},
58+
"finishReason": "STOP",
59+
"score": -11.901726722717285
60+
}
61+
],
62+
"createTime": "2026-04-08T17:28:11.415288Z",
63+
"modelVersion": "gemini-2.5-flash",
64+
"responseId": "K5DWabisGaeAtrIP6s2YmQk",
65+
"usageMetadata": {
66+
"billablePromptUsage": {
67+
"textCount": 25
68+
},
69+
"candidatesTokenCount": 8,
70+
"candidatesTokensDetails": [
71+
{
72+
"modality": "TEXT",
73+
"tokenCount": 8
74+
}
75+
],
76+
"promptTokenCount": 7,
77+
"promptTokensDetails": [
78+
{
79+
"modality": "TEXT",
80+
"tokenCount": 7
81+
}
82+
],
83+
"thoughtsTokenCount": 69,
84+
"totalTokenCount": 84,
85+
"trafficType": "ON_DEMAND"
86+
}
87+
}
88+
]
89+
}
90+
}
91+
]
92+
}

0 commit comments

Comments
 (0)