Skip to content

Commit 6f32d22

Browse files
committed
Fix DI, upgrade dependencies, update example, fix warnings
1 parent acdc08f commit 6f32d22

File tree

8 files changed

+109
-47
lines changed

8 files changed

+109
-47
lines changed

dotnet/ClientLib/MemoryWebClient.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,12 @@ public class MemoryWebClient : IKernelMemory
1919
{
2020
private readonly HttpClient _client;
2121

22-
public MemoryWebClient(string endpoint, string apiKey = "", string apiKeyHeader = "Authorization")
22+
public MemoryWebClient(string endpoint, string? apiKey = "", string apiKeyHeader = "Authorization")
2323
: this(endpoint, new HttpClient(), apiKey: apiKey, apiKeyHeader: apiKeyHeader)
2424
{
2525
}
2626

27-
public MemoryWebClient(string endpoint, HttpClient client, string apiKey = "", string apiKeyHeader = "Authorization")
27+
public MemoryWebClient(string endpoint, HttpClient client, string? apiKey = "", string apiKeyHeader = "Authorization")
2828
{
2929
this._client = client;
3030
this._client.BaseAddress = new Uri(endpoint);

dotnet/CoreLib/AI/AzureOpenAI/DependencyInjection.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,8 @@ public static IServiceCollection AddAzureOpenAIEmbeddingGeneration(this IService
5757
public static IServiceCollection AddAzureOpenAITextGeneration(this IServiceCollection services, AzureOpenAIConfig config)
5858
{
5959
return services
60-
.AddSingleton<AzureOpenAIConfig>(config)
61-
.AddSingleton<ITextGeneration, AzureTextGeneration>();
60+
.AddSingleton<ITextGeneration>(serviceProvider => new AzureTextGeneration(
61+
config: config,
62+
log: serviceProvider.GetService<ILogger<AzureTextGeneration>>()));
6263
}
6364
}

dotnet/CoreLib/CoreLib.csproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,11 @@
3535
</ItemGroup>
3636

3737
<ItemGroup>
38-
<PackageReference Include="Microsoft.SemanticKernel.Core" VersionOverride="1.0.0-beta7">
38+
<PackageReference Include="Microsoft.SemanticKernel.Core" VersionOverride="1.0.0-beta8">
3939
<PrivateAssets>none</PrivateAssets>
4040
<IncludeAssets>all</IncludeAssets>
4141
</PackageReference>
42-
<PackageReference Include="Microsoft.SemanticKernel.Connectors.AI.OpenAI" VersionOverride="1.0.0-beta7">
42+
<PackageReference Include="Microsoft.SemanticKernel.Connectors.AI.OpenAI" VersionOverride="1.0.0-beta8">
4343
<PrivateAssets>none</PrivateAssets>
4444
<IncludeAssets>all</IncludeAssets>
4545
</PackageReference>

examples/011-using-MemoryPlugin/011-using-MemoryPlugin.csproj

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,11 @@
77
<AssemblyName/>
88
<RootNamespace/>
99
<UserSecretsId>5ee045b0-aea3-4f08-8d31-32d1a6f8fed0</UserSecretsId>
10+
<NoWarn>CA1050</NoWarn>
1011
</PropertyGroup>
1112

1213
<ItemGroup>
13-
<PackageReference Include="Microsoft.SemanticKernel" VersionOverride="1.0.0-beta5"/>
14+
<PackageReference Include="Microsoft.SemanticKernel" VersionOverride="1.0.0-beta8"/>
1415
</ItemGroup>
1516

1617
<ItemGroup>

examples/011-using-MemoryPlugin/Program.cs

Lines changed: 48 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,10 @@ public static async Task Main()
1919
// You can use any LLM, replacing `WithAzureChatCompletionService` with other LLM options.
2020

2121
var builder = new KernelBuilder();
22-
builder.WithAzureChatCompletionService(
23-
deploymentName: Environment.GetEnvironmentVariable("AOAI_DEPLOYMENT"),
24-
endpoint: Environment.GetEnvironmentVariable("AOAI_ENDPOINT"),
25-
apiKey: Environment.GetEnvironmentVariable("AOAI_API_KEY"));
22+
builder.WithAzureOpenAIChatCompletionService(
23+
deploymentName: EnvVar("AOAI_DEPLOYMENT_TEXT"),
24+
endpoint: EnvVar("AOAI_ENDPOINT"),
25+
apiKey: EnvVar("AOAI_API_KEY"));
2626

2727
var kernel = builder.Build();
2828

@@ -32,49 +32,82 @@ public static async Task Main()
3232
// answer provided by the memory service.
3333

3434
var skPrompt = """
35-
Question to Kernel Memory: {{$input}}
35+
Question to Kernel Memory: {{$input}}
3636
37-
Kernel Memory Answer: {{memory.ask $input}}
37+
Kernel Memory Answer: {{memory.ask $input}}
3838
39-
If the answer is empty say 'I don't know' otherwise reply with a preview of the answer, truncated to 15 words.
40-
""";
39+
If the answer is empty say 'I don't know' otherwise reply with a preview of the answer, truncated to 15 words.
40+
""";
4141

42-
var doesItKnowFunction = kernel.CreateSemanticFunction(skPrompt);
42+
var oracleFunction = kernel.CreateSemanticFunction(skPrompt);
4343

4444
// === PREPARE MEMORY PLUGIN ===
4545
// Load the Kernel Memory plugin into Semantic Kernel.
4646
// We're using a local instance here, so remember to start the service locally first,
4747
// otherwise change the URL pointing to your KM endpoint.
4848

49-
var memory = new MemoryWebClient("http://127.0.0.1:9001/");
50-
kernel.ImportFunctions(new MemoryPlugin(memory), "memory");
49+
var memoryConnector = GetMemoryConnector();
50+
var memoryPlugin = kernel.ImportFunctions(new MemoryPlugin(memoryConnector), "memory");
5151

5252
// === LOAD DOCUMENT INTO MEMORY ===
5353
// Load some data in memory, in this case use a PDF file, though
5454
// you can also load web pages, Word docs, raw text, etc.
5555

56-
await memory.ImportDocumentAsync(Document, documentId: "NASA001");
56+
await memoryConnector.ImportDocumentAsync(Document, documentId: "NASA001");
5757

5858
// === RUN SEMANTIC FUNCTION ===
5959
// Run some example questions, showing how the answer is grounded on the document uploaded.
6060
// Only the first question can be answered, because the document uploaded doesn't contain any
6161
// information about Question2 and Question3.
6262

6363
Console.WriteLine("---------");
64-
KernelResult answer = await kernel.RunAsync(Question1, doesItKnowFunction);
6564
Console.WriteLine(Question1 + "\n");
65+
FunctionResult answer = await oracleFunction.InvokeAsync(Question1, kernel);
6666
Console.WriteLine("Answer: " + answer);
6767

6868
Console.WriteLine("---------");
69-
answer = await kernel.RunAsync(Question2, doesItKnowFunction);
7069
Console.WriteLine(Question2 + "\n");
70+
answer = await oracleFunction.InvokeAsync(Question2, kernel);
7171
Console.WriteLine("Answer: " + answer);
7272

7373
Console.WriteLine("---------");
74-
answer = await kernel.RunAsync(Question3, doesItKnowFunction);
7574
Console.WriteLine(Question3 + "\n");
75+
answer = await oracleFunction.InvokeAsync(Question3, kernel);
7676
Console.WriteLine("Answer: " + answer);
7777
}
78+
79+
private static IKernelMemory GetMemoryConnector(bool serverless = false)
80+
{
81+
// if (serverless)
82+
// {
83+
// return new KernelMemoryBuilder()
84+
// .WithAzureOpenAIEmbeddingGeneration(new AzureOpenAIConfig
85+
// {
86+
// APIType = AzureOpenAIConfig.APITypes.EmbeddingGeneration,
87+
// Endpoint = EnvVar("AOAI_ENDPOINT"),
88+
// Deployment = EnvVar("AOAI_DEPLOYMENT_EMBEDDING"),
89+
// Auth = AzureOpenAIConfig.AuthTypes.APIKey,
90+
// APIKey = EnvVar("AOAI_API_KEY"),
91+
// })
92+
// .WithAzureOpenAITextGeneration(new AzureOpenAIConfig
93+
// {
94+
// APIType = AzureOpenAIConfig.APITypes.ChatCompletion,
95+
// Endpoint = EnvVar("AOAI_ENDPOINT"),
96+
// Deployment = EnvVar("AOAI_DEPLOYMENT_TEXT"),
97+
// Auth = AzureOpenAIConfig.AuthTypes.APIKey,
98+
// APIKey = EnvVar("AOAI_API_KEY"),
99+
// })
100+
// .BuildServerlessClient();
101+
// }
102+
103+
return new MemoryWebClient("http://127.0.0.1:9001/", Environment.GetEnvironmentVariable("MEMORY_API_KEY"));
104+
}
105+
106+
private static string EnvVar(string name)
107+
{
108+
return Environment.GetEnvironmentVariable(name)
109+
?? throw new ArgumentException($"Env var {name} not set");
110+
}
78111
}
79112

80113
/* ===== OUTPUT =====

plugins/dotnet/Microsoft.KernelMemory.Plugin/MemoryPlugin.cs

Lines changed: 49 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
using Microsoft.KernelMemory.Plugin;
1010
using Microsoft.SemanticKernel;
1111

12+
#pragma warning disable IDE0130 // reduce number of "using" statements
1213
// ReSharper disable once CheckNamespace
1314
// ReSharper disable ArrangeAttributes
1415
namespace Microsoft.KernelMemory;
@@ -58,6 +59,11 @@ public class MemoryPlugin
5859
/// </summary>
5960
public const string StepsParam = "steps";
6061

62+
/// <summary>
63+
/// Name of the input variable used to specify custom minimum relevance for the memories to retrieve.
64+
/// </summary>
65+
public const string MinRelevanceParam = "minRelevance";
66+
6167
/// <summary>
6268
/// Default document ID. When null, a new value is generated every time some information
6369
/// is saved into memory.
@@ -208,20 +214,24 @@ public async Task<string> SaveAsync(
208214
ILoggerFactory? loggerFactory = null,
209215
CancellationToken cancellationToken = default)
210216
{
211-
if (this._waitForIngestionToComplete)
217+
Task<string> Do(CancellationToken token)
212218
{
213-
var cs = new CancellationTokenSource(this._maxIngestionWait);
214-
cancellationToken = cs.Token;
215-
}
216-
217-
return await this._memory.ImportTextAsync(
219+
return this._memory.ImportTextAsync(
218220
text: input,
219221
documentId: documentId,
220222
index: index ?? this._defaultIndex,
221223
tags: tags ?? this._defaultIngestionTags,
222224
steps: steps ?? this._defaultIngestionSteps,
223-
cancellationToken: cancellationToken)
224-
.ConfigureAwait(false);
225+
cancellationToken: token);
226+
}
227+
228+
if (this._waitForIngestionToComplete)
229+
{
230+
using var cs = new CancellationTokenSource(this._maxIngestionWait);
231+
return await Do(cs.Token).ConfigureAwait(false);
232+
}
233+
234+
return await Do(cancellationToken).ConfigureAwait(false);
225235
}
226236

227237
[SKFunction, Description("Store in memory the information extracted from a file")]
@@ -239,31 +249,37 @@ public async Task<string> SaveFileAsync(
239249
ILoggerFactory? loggerFactory = null,
240250
CancellationToken cancellationToken = default)
241251
{
242-
if (this._waitForIngestionToComplete)
252+
Task<string> Do(CancellationToken token)
243253
{
244-
var cs = new CancellationTokenSource(this._maxIngestionWait);
245-
cancellationToken = cs.Token;
246-
}
247-
248-
return await this._memory.ImportTextAsync(
249-
text: input,
254+
return this._memory.ImportDocumentAsync(
255+
filePath: input,
250256
documentId: documentId,
251257
index: index ?? this._defaultIndex,
252258
tags: tags ?? this._defaultIngestionTags,
253259
steps: steps ?? this._defaultIngestionSteps,
254-
cancellationToken: cancellationToken)
255-
.ConfigureAwait(false);
260+
cancellationToken: token);
261+
}
262+
263+
if (this._waitForIngestionToComplete)
264+
{
265+
using var cs = new CancellationTokenSource(this._maxIngestionWait);
266+
return await Do(cs.Token).ConfigureAwait(false);
267+
}
268+
269+
return await Do(cancellationToken).ConfigureAwait(false);
256270
}
257271

258272
[SKFunction, Description("Store in memory the information extracted from a web page")]
259273
public async Task<string> SaveWebPageAsync()
260274
{
275+
await Task.Delay(0).ConfigureAwait(false);
261276
throw new NotImplementedException();
262277
}
263278

264279
[SKFunction, Description("Return up to N memories related to the input text")]
265280
public async Task<string> SearchAsync()
266281
{
282+
await Task.Delay(0).ConfigureAwait(false);
267283
throw new NotImplementedException();
268284
}
269285

@@ -278,28 +294,37 @@ public async Task<string> SearchAsync()
278294
public async Task<string> AskAsync(
279295
[Description("The question to answer")]
280296
string input,
281-
[SKName(IndexParam), Description("Memories index to search for answers"), DefaultValue(null)]
297+
[SKName(IndexParam), Description("Memories index to search for answers"), DefaultValue("")]
282298
string? index = null,
283-
[SKName(IndexParam), Description("Memories index to search for answers"), DefaultValue(null)]
299+
[SKName(MinRelevanceParam), Description("Memories index to search for answers"), DefaultValue(0d)]
284300
double minRelevance = 0,
285301
ILoggerFactory? loggerFactory = null,
286302
CancellationToken cancellationToken = default)
287-
288303
{
304+
Task<MemoryAnswer> Do(CancellationToken token)
305+
{
306+
return this._memory.AskAsync(question: input, cancellationToken: token);
307+
}
308+
309+
MemoryAnswer? answer;
289310
if (this._waitForIngestionToComplete)
290311
{
291-
// var cs = new CancellationTokenSource(this._maxIngestionWait);
292-
var cs = new CancellationTokenSource(TimeSpan.FromMilliseconds(1));
293-
cancellationToken = cs.Token;
312+
// using var cs = new CancellationTokenSource(this._maxIngestionWait);
313+
using var cs = new CancellationTokenSource(TimeSpan.FromMilliseconds(1));
314+
answer = await Do(cs.Token).ConfigureAwait(false);
315+
}
316+
else
317+
{
318+
answer = await Do(cancellationToken).ConfigureAwait(false);
294319
}
295320

296-
MemoryAnswer? answer = await this._memory.AskAsync(question: input, cancellationToken: cancellationToken).ConfigureAwait(false);
297321
return answer?.Result ?? string.Empty;
298322
}
299323

300324
[SKFunction, Description("Remobe from memory all the information extracted from the given document ID")]
301325
public async Task<string> DeleteAsync()
302326
{
327+
await Task.Delay(0).ConfigureAwait(false);
303328
throw new NotImplementedException();
304329
}
305330
}

plugins/dotnet/Microsoft.KernelMemory.Plugin/Microsoft.KernelMemory.Plugin.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
</ItemGroup>
1313

1414
<ItemGroup>
15-
<PackageReference Include="Microsoft.SemanticKernel.Abstractions" VersionOverride="1.0.0-beta5" />
15+
<PackageReference Include="Microsoft.SemanticKernel.Abstractions" VersionOverride="1.0.0-beta8" />
1616
</ItemGroup>
1717

1818
<Import Project="../../../dotnet/nuget/nuget-package.props"/>

plugins/dotnet/Microsoft.KernelMemory.Plugin/TypeConverter.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ public class ListOfStringsWrapper : List<string>
1818
{
1919
}
2020

21+
#pragma warning disable CA1812 // required by SK
2122
internal sealed class TypeConverter : System.ComponentModel.TypeConverter
2223
{
2324
public override bool CanConvertFrom(ITypeDescriptorContext? context, Type sourceType) => true;
@@ -40,3 +41,4 @@ internal sealed class TypeConverter : System.ComponentModel.TypeConverter
4041
return JsonSerializer.Serialize(value);
4142
}
4243
}
44+
#pragma warning restore CA1812

0 commit comments

Comments
 (0)