Skip to content

Commit c8be251

Browse files
Copilotrogerbarreto
andcommitted
Split ChatClient extensions into AddGoogleGenAIChatClient and AddGoogleVertexAIChatClient
Co-authored-by: rogerbarreto <[email protected]>
1 parent f9f08fb commit c8be251

File tree

10 files changed

+706
-101
lines changed

10 files changed

+706
-101
lines changed

dotnet/src/Connectors/Connectors.Google.UnitTests/Extensions/GoogleAIServiceCollectionExtensionsTests.cs

Lines changed: 52 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -117,13 +117,13 @@ public void GoogleAIEmbeddingGeneratorShouldBeRegisteredInServiceCollection()
117117

118118
#if NET
119119
[Fact]
120-
public void GoogleAIChatClientShouldBeRegisteredInKernelServicesWithApiKey()
120+
public void GoogleGenAIChatClientShouldBeRegisteredInKernelServicesWithApiKey()
121121
{
122122
// Arrange
123123
var kernelBuilder = Kernel.CreateBuilder();
124124

125125
// Act
126-
kernelBuilder.AddGoogleAIChatClient("modelId", "apiKey");
126+
kernelBuilder.AddGoogleGenAIChatClient("modelId", "apiKey");
127127
var kernel = kernelBuilder.Build();
128128

129129
// Assert
@@ -132,20 +132,50 @@ public void GoogleAIChatClientShouldBeRegisteredInKernelServicesWithApiKey()
132132
}
133133

134134
[Fact]
135-
public void GoogleAIChatClientShouldBeRegisteredInServiceCollectionWithApiKey()
135+
public void GoogleGenAIChatClientShouldBeRegisteredInServiceCollectionWithApiKey()
136136
{
137137
// Arrange
138138
var services = new ServiceCollection();
139139

140140
// Act
141-
services.AddGoogleAIChatClient("modelId", "apiKey");
141+
services.AddGoogleGenAIChatClient("modelId", "apiKey");
142142
var serviceProvider = services.BuildServiceProvider();
143143

144144
// Assert
145145
var chatClient = serviceProvider.GetRequiredService<IChatClient>();
146146
Assert.NotNull(chatClient);
147147
}
148148

149+
[Fact]
150+
public void GoogleVertexAIChatClientShouldBeRegisteredInKernelServices()
151+
{
152+
// Arrange
153+
var kernelBuilder = Kernel.CreateBuilder();
154+
155+
// Act
156+
kernelBuilder.AddGoogleVertexAIChatClient("modelId", project: "test-project", location: "us-central1");
157+
158+
// Assert - just verify no exception during registration
159+
// Resolution requires real credentials, so skip that in unit tests
160+
var kernel = kernelBuilder.Build();
161+
Assert.NotNull(kernel.Services);
162+
}
163+
164+
[Fact]
165+
public void GoogleVertexAIChatClientShouldBeRegisteredInServiceCollection()
166+
{
167+
// Arrange
168+
var services = new ServiceCollection();
169+
170+
// Act
171+
services.AddGoogleVertexAIChatClient("modelId", project: "test-project", location: "us-central1");
172+
var serviceProvider = services.BuildServiceProvider();
173+
174+
// Assert - just verify no exception during registration
175+
// Resolution requires real credentials, so skip that in unit tests
176+
Assert.NotNull(serviceProvider);
177+
}
178+
149179
[Fact]
150180
public void GoogleAIChatClientShouldBeRegisteredInKernelServicesWithClient()
151181
{
@@ -179,21 +209,37 @@ public void GoogleAIChatClientShouldBeRegisteredInServiceCollectionWithClient()
179209
}
180210

181211
[Fact]
182-
public void GoogleAIChatClientShouldBeRegisteredWithServiceId()
212+
public void GoogleGenAIChatClientShouldBeRegisteredWithServiceId()
183213
{
184214
// Arrange
185215
var services = new ServiceCollection();
186216
const string serviceId = "test-service-id";
187217

188218
// Act
189-
services.AddGoogleAIChatClient("modelId", "apiKey", serviceId: serviceId);
219+
services.AddGoogleGenAIChatClient("modelId", "apiKey", serviceId: serviceId);
190220
var serviceProvider = services.BuildServiceProvider();
191221

192222
// Assert
193223
var chatClient = serviceProvider.GetKeyedService<IChatClient>(serviceId);
194224
Assert.NotNull(chatClient);
195225
}
196226

227+
[Fact]
228+
public void GoogleVertexAIChatClientShouldBeRegisteredWithServiceId()
229+
{
230+
// Arrange
231+
var services = new ServiceCollection();
232+
const string serviceId = "test-service-id";
233+
234+
// Act
235+
services.AddGoogleVertexAIChatClient("modelId", project: "test-project", location: "us-central1", serviceId: serviceId);
236+
var serviceProvider = services.BuildServiceProvider();
237+
238+
// Assert - just verify no exception during registration
239+
// Resolution requires real credentials, so skip that in unit tests
240+
Assert.NotNull(serviceProvider);
241+
}
242+
197243
[Fact]
198244
public void GoogleAIChatClientShouldResolveFromServiceProviderWhenClientNotProvided()
199245
{

dotnet/src/Connectors/Connectors.Google.UnitTests/Services/GoogleGeminiChatClientTests.cs

Lines changed: 65 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,22 +13,38 @@ namespace SemanticKernel.Connectors.Google.UnitTests.Services;
1313
public sealed class GoogleGeminiChatClientTests
1414
{
1515
[Fact]
16-
public void ChatClientShouldBeCreatedWithApiKey()
16+
public void GenAIChatClientShouldBeCreatedWithApiKey()
1717
{
1818
// Arrange
1919
string modelId = "gemini-1.5-pro";
2020
string apiKey = "test-api-key";
2121

2222
// Act
2323
var kernelBuilder = Kernel.CreateBuilder();
24-
kernelBuilder.AddGoogleAIChatClient(modelId, apiKey);
24+
kernelBuilder.AddGoogleGenAIChatClient(modelId, apiKey);
2525
var kernel = kernelBuilder.Build();
2626

2727
// Assert
2828
var chatClient = kernel.GetRequiredService<IChatClient>();
2929
Assert.NotNull(chatClient);
3030
}
3131

32+
[Fact]
33+
public void VertexAIChatClientShouldBeCreated()
34+
{
35+
// Arrange
36+
string modelId = "gemini-1.5-pro";
37+
38+
// Act
39+
var kernelBuilder = Kernel.CreateBuilder();
40+
kernelBuilder.AddGoogleVertexAIChatClient(modelId, project: "test-project", location: "us-central1");
41+
var kernel = kernelBuilder.Build();
42+
43+
// Assert - just verify no exception during registration
44+
// Resolution requires real credentials, so skip that in unit tests
45+
Assert.NotNull(kernel.Services);
46+
}
47+
3248
[Fact]
3349
public void ChatClientShouldBeCreatedWithGoogleClient()
3450
{
@@ -47,7 +63,7 @@ public void ChatClientShouldBeCreatedWithGoogleClient()
4763
}
4864

4965
[Fact]
50-
public void ChatClientShouldBeCreatedWithServiceId()
66+
public void GenAIChatClientShouldBeCreatedWithServiceId()
5167
{
5268
// Arrange
5369
string modelId = "gemini-1.5-pro";
@@ -56,7 +72,7 @@ public void ChatClientShouldBeCreatedWithServiceId()
5672

5773
// Act
5874
var kernelBuilder = Kernel.CreateBuilder();
59-
kernelBuilder.AddGoogleAIChatClient(modelId, apiKey, serviceId: serviceId);
75+
kernelBuilder.AddGoogleGenAIChatClient(modelId, apiKey, serviceId: serviceId);
6076
var kernel = kernelBuilder.Build();
6177

6278
// Assert
@@ -65,43 +81,80 @@ public void ChatClientShouldBeCreatedWithServiceId()
6581
}
6682

6783
[Fact]
68-
public void ChatClientThrowsForNullModelId()
84+
public void VertexAIChatClientShouldBeCreatedWithServiceId()
85+
{
86+
// Arrange
87+
string modelId = "gemini-1.5-pro";
88+
string serviceId = "test-service";
89+
90+
// Act
91+
var kernelBuilder = Kernel.CreateBuilder();
92+
kernelBuilder.AddGoogleVertexAIChatClient(modelId, project: "test-project", location: "us-central1", serviceId: serviceId);
93+
var kernel = kernelBuilder.Build();
94+
95+
// Assert - just verify no exception during registration
96+
// Resolution requires real credentials, so skip that in unit tests
97+
Assert.NotNull(kernel.Services);
98+
}
99+
100+
[Fact]
101+
public void GenAIChatClientThrowsForNullModelId()
102+
{
103+
// Arrange
104+
var kernelBuilder = Kernel.CreateBuilder();
105+
106+
// Act & Assert
107+
Assert.ThrowsAny<ArgumentException>(() => kernelBuilder.AddGoogleGenAIChatClient(null!, "apiKey"));
108+
}
109+
110+
[Fact]
111+
public void GenAIChatClientThrowsForEmptyModelId()
112+
{
113+
// Arrange
114+
var kernelBuilder = Kernel.CreateBuilder();
115+
116+
// Act & Assert
117+
Assert.ThrowsAny<ArgumentException>(() => kernelBuilder.AddGoogleGenAIChatClient("", "apiKey"));
118+
}
119+
120+
[Fact]
121+
public void GenAIChatClientThrowsForNullApiKey()
69122
{
70123
// Arrange
71124
var kernelBuilder = Kernel.CreateBuilder();
72125

73126
// Act & Assert
74-
Assert.ThrowsAny<ArgumentException>(() => kernelBuilder.AddGoogleAIChatClient(null!, "apiKey"));
127+
Assert.ThrowsAny<ArgumentException>(() => kernelBuilder.AddGoogleGenAIChatClient("modelId", null!));
75128
}
76129

77130
[Fact]
78-
public void ChatClientThrowsForEmptyModelId()
131+
public void GenAIChatClientThrowsForEmptyApiKey()
79132
{
80133
// Arrange
81134
var kernelBuilder = Kernel.CreateBuilder();
82135

83136
// Act & Assert
84-
Assert.ThrowsAny<ArgumentException>(() => kernelBuilder.AddGoogleAIChatClient("", "apiKey"));
137+
Assert.ThrowsAny<ArgumentException>(() => kernelBuilder.AddGoogleGenAIChatClient("modelId", ""));
85138
}
86139

87140
[Fact]
88-
public void ChatClientThrowsForNullApiKey()
141+
public void VertexAIChatClientThrowsForNullModelId()
89142
{
90143
// Arrange
91144
var kernelBuilder = Kernel.CreateBuilder();
92145

93146
// Act & Assert
94-
Assert.ThrowsAny<ArgumentException>(() => kernelBuilder.AddGoogleAIChatClient("modelId", (string)null!));
147+
Assert.ThrowsAny<ArgumentException>(() => kernelBuilder.AddGoogleVertexAIChatClient(null!, project: "test-project", location: "us-central1"));
95148
}
96149

97150
[Fact]
98-
public void ChatClientThrowsForEmptyApiKey()
151+
public void VertexAIChatClientThrowsForEmptyModelId()
99152
{
100153
// Arrange
101154
var kernelBuilder = Kernel.CreateBuilder();
102155

103156
// Act & Assert
104-
Assert.ThrowsAny<ArgumentException>(() => kernelBuilder.AddGoogleAIChatClient("modelId", ""));
157+
Assert.ThrowsAny<ArgumentException>(() => kernelBuilder.AddGoogleVertexAIChatClient("", project: "test-project", location: "us-central1"));
105158
}
106159
}
107160

dotnet/src/Connectors/Connectors.Google/Connectors.Google.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626

2727
<ItemGroup Condition="'$(TargetFramework)' == 'net8.0' or '$(TargetFramework)' == 'net9.0' or '$(TargetFramework)' == 'net10.0'">
2828
<PackageReference Include="Google.GenAI" />
29+
<PackageReference Include="Google.Apis.Auth" />
2930
</ItemGroup>
3031

3132
<ItemGroup>

dotnet/src/Connectors/Connectors.Google/Extensions/GoogleAIKernelBuilderExtensions.cs

Lines changed: 40 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -121,31 +121,64 @@ public static IKernelBuilder AddGoogleAIEmbeddingGenerator(
121121

122122
#if NET
123123
/// <summary>
124-
/// Add Google AI <see cref="IChatClient"/> to the <see cref="IKernelBuilder.Services"/>.
124+
/// Add Google GenAI <see cref="IChatClient"/> to the <see cref="IKernelBuilder.Services"/>.
125125
/// </summary>
126126
/// <param name="builder">The kernel builder.</param>
127127
/// <param name="modelId">The model for chat completion.</param>
128-
/// <param name="apiKey">The API key for authentication with the Google AI API.</param>
129-
/// <param name="vertexAI">Whether to use Vertex AI.</param>
128+
/// <param name="apiKey">The API key for authentication with the Google GenAI API.</param>
130129
/// <param name="serviceId">The optional service ID.</param>
131130
/// <param name="openTelemetrySourceName">An optional name for the OpenTelemetry source.</param>
132131
/// <param name="openTelemetryConfig">An optional callback that can be used to configure the <see cref="OpenTelemetryChatClient"/> instance.</param>
133132
/// <returns>The updated kernel builder.</returns>
134-
public static IKernelBuilder AddGoogleAIChatClient(
133+
public static IKernelBuilder AddGoogleGenAIChatClient(
135134
this IKernelBuilder builder,
136135
string modelId,
137136
string apiKey,
138-
bool vertexAI = false,
139137
string? serviceId = null,
140138
string? openTelemetrySourceName = null,
141139
Action<OpenTelemetryChatClient>? openTelemetryConfig = null)
142140
{
143141
Verify.NotNull(builder);
144142

145-
builder.Services.AddGoogleAIChatClient(
143+
builder.Services.AddGoogleGenAIChatClient(
146144
modelId,
147145
apiKey,
148-
vertexAI,
146+
serviceId,
147+
openTelemetrySourceName,
148+
openTelemetryConfig);
149+
150+
return builder;
151+
}
152+
153+
/// <summary>
154+
/// Add Google Vertex AI <see cref="IChatClient"/> to the <see cref="IKernelBuilder.Services"/>.
155+
/// </summary>
156+
/// <param name="builder">The kernel builder.</param>
157+
/// <param name="modelId">The model for chat completion.</param>
158+
/// <param name="project">The Google Cloud project ID. If null, will attempt to use the GOOGLE_CLOUD_PROJECT environment variable.</param>
159+
/// <param name="location">The Google Cloud location (e.g., "us-central1"). If null, will attempt to use the GOOGLE_CLOUD_LOCATION environment variable.</param>
160+
/// <param name="credential">The optional <see cref="Google.Apis.Auth.OAuth2.ICredential"/> for authentication. If null, the client will use its internal discovery implementation to get credentials from the environment.</param>
161+
/// <param name="serviceId">The optional service ID.</param>
162+
/// <param name="openTelemetrySourceName">An optional name for the OpenTelemetry source.</param>
163+
/// <param name="openTelemetryConfig">An optional callback that can be used to configure the <see cref="OpenTelemetryChatClient"/> instance.</param>
164+
/// <returns>The updated kernel builder.</returns>
165+
public static IKernelBuilder AddGoogleVertexAIChatClient(
166+
this IKernelBuilder builder,
167+
string modelId,
168+
string? project = null,
169+
string? location = null,
170+
Google.Apis.Auth.OAuth2.ICredential? credential = null,
171+
string? serviceId = null,
172+
string? openTelemetrySourceName = null,
173+
Action<OpenTelemetryChatClient>? openTelemetryConfig = null)
174+
{
175+
Verify.NotNull(builder);
176+
177+
builder.Services.AddGoogleVertexAIChatClient(
178+
modelId,
179+
project,
180+
location,
181+
credential,
149182
serviceId,
150183
openTelemetrySourceName,
151184
openTelemetryConfig);

0 commit comments

Comments
 (0)