Skip to content

Commit 5dac187

Browse files
author
Gunpal Jain
committed
add: added Google Text embedding model and updated Google_GenerativeAI sdk to latest version
1 parent 81fc988 commit 5dac187

File tree

8 files changed

+244
-8
lines changed

8 files changed

+244
-8
lines changed
Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,38 @@
11
namespace LangChain.Providers.Google;
22

33
/// <summary>
4+
/// Configuration options for the Google AI provider.
45
/// </summary>
56
public class GoogleConfiguration
67
{
78
/// <summary>
9+
/// Gets or sets the API key used for authentication with the Google AI service.
810
/// </summary>
911
public string? ApiKey { get; set; }
1012

1113
/// <summary>
12-
/// ID of the model to use. <br />
14+
/// Gets or sets the ID of the model to use. The default value is "gemini-1.5-flash".
1315
/// </summary>
14-
public string? ModelId { get; set; } = "gemini-pro";
16+
public string? ModelId { get; set; } = "gemini-1.5-flash";
1517

1618
/// <summary>
19+
/// Gets or sets the Top-K sampling value, which determines the number of highest-probability tokens considered during decoding.
1720
/// </summary>
1821
public int? TopK { get; set; } = default!;
1922

2023
/// <summary>
24+
/// Gets or sets the Top-P sampling value, which determines the cumulative probability threshold for token selection during decoding.
2125
/// </summary>
2226
public double? TopP { get; set; } = default!;
2327

2428
/// <summary>
29+
/// Gets or sets the temperature value, which controls the randomness of the output.
30+
/// Higher values produce more random results, while lower values make the output more deterministic. The default is 1.0.
2531
/// </summary>
2632
public double? Temperature { get; set; } = 1D;
2733

2834
/// <summary>
29-
/// Maximum Output Tokens
35+
/// Gets or sets the maximum number of output tokens allowed in the response.
3036
/// </summary>
3137
public int? MaxOutputTokens { get; set; } = default!;
3238
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
using GenerativeAI;
2+
using GenerativeAI.Exceptions;
3+
using GenerativeAI.Types;
4+
using LangChain.Providers.OpenAI;
5+
using tryAGI.OpenAI;
6+
7+
namespace LangChain.Providers.Google;
8+
9+
using System.Diagnostics;
10+
11+
public class GoogleEmbeddingModel(
12+
GoogleProvider provider,
13+
string id)
14+
: Model<EmbeddingSettings>(id), IEmbeddingModel
15+
{
16+
public GoogleEmbeddingModel(
17+
GoogleProvider provider,
18+
CreateEmbeddingRequestModel id)
19+
: this(provider, id.ToValueString())
20+
{
21+
}
22+
23+
public EmbeddingModel EmbeddingModel { get; } =
24+
new EmbeddingModel(provider.ApiKey, id, httpClient: provider.HttpClient);
25+
26+
27+
public async Task<EmbeddingResponse> CreateEmbeddingsAsync(EmbeddingRequest request,
28+
EmbeddingSettings? settings = null,
29+
CancellationToken cancellationToken = default)
30+
{
31+
request = request ?? throw new ArgumentNullException(nameof(request));
32+
33+
var watch = Stopwatch.StartNew();
34+
35+
var usedSettings = GoogleEmbeddingSettings.Calculate(
36+
requestSettings: settings,
37+
modelSettings: Settings,
38+
providerSettings: provider.EmbeddingSettings);
39+
40+
var embedRequest = new EmbedContentRequest();
41+
embedRequest.Content = new Content();
42+
embedRequest.Content.AddParts(request.Strings.Select(s => new Part(s)));
43+
44+
embedRequest.OutputDimensionality = usedSettings.OutputDimensionality;
45+
var embedResponse = await this.EmbeddingModel.EmbedContentAsync(embedRequest, cancellationToken)
46+
.ConfigureAwait(false);
47+
48+
var usage = Usage.Empty with
49+
{
50+
Time = watch.Elapsed,
51+
};
52+
AddUsage(usage);
53+
provider.AddUsage(usage);
54+
55+
if (embedResponse.Embedding == null)
56+
throw new GenerativeAIException("Failed to create embeddings.", "");
57+
var values = embedResponse.Embedding.Values.ToList();
58+
59+
return new EmbeddingResponse
60+
{
61+
Values = new[] { values.ToArray() }.ToArray(),
62+
Usage = Usage.Empty,
63+
UsedSettings = usedSettings,
64+
Dimensions = values.Count,
65+
};
66+
}
67+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
using GenerativeAI.Types;
2+
3+
namespace LangChain.Providers.Google;
4+
5+
public class GoogleEmbeddingSettings:EmbeddingSettings
6+
{
7+
/// <summary>
8+
/// Optional. Optional reduced dimension for the output embedding. If set, excessive values in the output embedding are truncated from the end. Supported by newer models since 2024 only. You cannot set this value if using the earlier model (models/embedding-001).
9+
/// </summary>
10+
public int? OutputDimensionality { get; set; }
11+
public new static GoogleEmbeddingSettings Default { get; } = new()
12+
{
13+
OutputDimensionality = null
14+
};
15+
16+
/// <summary>
17+
/// Calculate the settings to use for the request.
18+
/// </summary>
19+
/// <param name="requestSettings"></param>
20+
/// <param name="modelSettings"></param>
21+
/// <param name="providerSettings"></param>
22+
/// <returns></returns>
23+
/// <exception cref="InvalidOperationException"></exception>
24+
public new static GoogleEmbeddingSettings Calculate(
25+
EmbeddingSettings? requestSettings,
26+
EmbeddingSettings? modelSettings,
27+
EmbeddingSettings? providerSettings)
28+
{
29+
var requestSettingsCasted = requestSettings as GoogleEmbeddingSettings;
30+
var modelSettingsCasted = modelSettings as GoogleEmbeddingSettings;
31+
var providerSettingsCasted = providerSettings as GoogleEmbeddingSettings;
32+
33+
return new GoogleEmbeddingSettings
34+
{
35+
OutputDimensionality =
36+
requestSettingsCasted?.OutputDimensionality ??
37+
modelSettingsCasted?.OutputDimensionality ??
38+
providerSettingsCasted?.OutputDimensionality ??
39+
Default.OutputDimensionality
40+
};
41+
}
42+
}

src/Google/src/GoogleProvider.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ public static GoogleProvider ToGoogleProvider(string message)
3131
/// <summary>
3232
/// </summary>
3333
public GoogleConfiguration? Configuration { get; set; }
34+
35+
public GoogleEmbeddingSettings? EmbeddingSettings { get; set; }
3436

3537
#endregion
3638

src/Google/src/LangChain.Providers.Google.csproj

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

2121
<ItemGroup>
2222
<ProjectReference Include="..\..\Abstractions\src\LangChain.Providers.Abstractions.csproj"/>
23+
<ProjectReference Include="..\..\OpenAI\src\LangChain.Providers.OpenAI.csproj" />
2324
</ItemGroup>
2425

2526
</Project>
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
using GenerativeAI;
2+
3+
namespace LangChain.Providers.Google.Predefined;
4+
5+
/// <inheritdoc cref="GoogleAIModels.GeminiPro" />
6+
public class GoogleTextEmbedding(GoogleProvider provider)
7+
: GoogleEmbeddingModel(
8+
provider, GoogleAIModels.TextEmbedding);
9+

src/IntegrationTests/BaseTests.cs

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,4 +261,116 @@ public async Task Tools_Books(ProviderType providerType)
261261

262262
Console.WriteLine(response.Messages.AsHistory());
263263
}
264+
265+
[Explicit]
266+
public async Task GoogleEmbeddingTest()
267+
{
268+
var (llm,embeddingModel , _) = Helpers.GetModels(ProviderType.Google);
269+
270+
var embeddings = await embeddingModel.CreateEmbeddingsAsync(new EmbeddingRequest()
271+
{
272+
Strings = new List<string>
273+
{
274+
"The quick brown fox jumps over the lazy dog.",
275+
"She sells seashells by the seashore.",
276+
"How much wood would a woodchuck chuck if a woodchuck could chuck wood?",
277+
"A journey of a thousand miles begins with a single step.",
278+
"To be or not to be, that is the question.",
279+
"All that glitters is not gold.",
280+
"A picture is worth a thousand words.",
281+
"Actions speak louder than words.",
282+
"Better late than never.",
283+
"The early bird catches the worm.",
284+
"Fortune favors the bold.",
285+
"Ignorance is bliss.",
286+
"Look before you leap.",
287+
"Barking up the wrong tree.",
288+
"Birds of a feather flock together.",
289+
"Don't bite the hand that feeds you.",
290+
"Every cloud has a silver lining.",
291+
"Haste makes waste.",
292+
"Strike while the iron is hot.",
293+
"Time and tide wait for no man.",
294+
"When in Rome, do as the Romans do.",
295+
"Where there's smoke, there's fire.",
296+
"You can't judge a book by its cover.",
297+
"Practice makes perfect.",
298+
"Rome wasn't built in a day.",
299+
"Two heads are better than one.",
300+
"A rolling stone gathers no moss.",
301+
"Absence makes the heart grow fonder.",
302+
"Beauty is in the eye of the beholder.",
303+
"Cleanliness is next to godliness.",
304+
"Curiosity killed the cat.",
305+
"Don't count your chickens before they hatch.",
306+
"Honesty is the best policy.",
307+
"Necessity is the mother of invention.",
308+
"No man is an island.",
309+
"The pen is mightier than the sword.",
310+
"The squeaky wheel gets the grease.",
311+
"There's no place like home.",
312+
"Too many cooks spoil the broth.",
313+
"You can't have your cake and eat it too.",
314+
"A fool and his money are soon parted.",
315+
"Actions have consequences.",
316+
"An apple a day keeps the doctor away.",
317+
"As you sow, so shall you reap.",
318+
"Don't bite off more than you can chew.",
319+
"Don't put all your eggs in one basket.",
320+
"Early to bed and early to rise makes a man healthy, wealthy, and wise.",
321+
"Give credit where credit is due.",
322+
"Good things come to those who wait.",
323+
"If it ain't broke, don't fix it.",
324+
"If you can't beat 'em, join 'em.",
325+
"It's always darkest before the dawn.",
326+
"Keep your friends close and your enemies closer.",
327+
"Knowledge is power.",
328+
"Laughter is the best medicine.",
329+
"Let sleeping dogs lie.",
330+
"Out of sight, out of mind.",
331+
"The grass is always greener on the other side of the fence.",
332+
"The road to hell is paved with good intentions.",
333+
"Variety is the spice of life.",
334+
"What goes around comes around.",
335+
"You reap what you sow.",
336+
"Every rose has its thorn.",
337+
"Don't judge a person until you've walked a mile in their shoes.",
338+
"A watched pot never boils.",
339+
"Better safe than sorry.",
340+
"Beggars can't be choosers.",
341+
"Cut your coat according to your cloth.",
342+
"Don't make a mountain out of a molehill.",
343+
"Every dog has its day.",
344+
"Great minds think alike.",
345+
"If it sounds too good to be true, it probably is.",
346+
"Lend your money and lose your friend.",
347+
"Keep your chin up.",
348+
"Actions create reactions.",
349+
"Don't throw the baby out with the bathwater.",
350+
"A stitch in time saves nine.",
351+
"Out of the frying pan and into the fire.",
352+
"The customer is always right.",
353+
"The proof of the pudding is in the eating.",
354+
"There's no such thing as a free lunch.",
355+
"This too shall pass.",
356+
"To err is human; to forgive, divine.",
357+
"You can't please everyone.",
358+
"What doesn't kill you makes you stronger.",
359+
"Don't cry over spilled milk.",
360+
"Good fences make good neighbors.",
361+
"Hope for the best but prepare for the worst.",
362+
"It's no use crying over spilt milk.",
363+
"Life is what you make it.",
364+
"Live and let live.",
365+
"Never look a gift horse in the mouth.",
366+
"When the going gets tough, the tough get going.",
367+
"You can't have it both ways.",
368+
"You can't make an omelette without breaking eggs.",
369+
"Necessity knows no law.",
370+
"Failing to prepare is preparing to fail."
371+
}
372+
});
373+
embeddings.Values.Should().HaveCountGreaterThan(0);
374+
embeddings.Values.First().Should().HaveCountGreaterThan(0);
375+
}
264376
}

src/IntegrationTests/Helpers.cs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -120,11 +120,8 @@ public static (IChatModel ChatModel, IEmbeddingModel EmbeddingModel, IProvider P
120120
throw new InconclusiveException("GOOGLE_API_KEY is not set"),
121121
httpClient: new HttpClient());
122122
var llm = new Gemini15FlashModel(provider);
123-
124-
// Use OpenAI embeddings for now because Google doesn't have embeddings yet
125-
var embeddings = new TextEmbeddingV3SmallModel(
126-
Environment.GetEnvironmentVariable("OPENAI_API_KEY") ??
127-
throw new InconclusiveException("OPENAI_API_KEY is not set"));
123+
124+
var embeddings = new GoogleTextEmbedding(provider);
128125

129126
return (llm, embeddings, provider);
130127
}

0 commit comments

Comments
 (0)