-
Notifications
You must be signed in to change notification settings - Fork 1k
Description
Context
I have a custom AITool implementation that needs to resolve method parameters from an IServiceProvider (using the AIFunctionFactoryOptions.ParameterBindingOptions extensibility in Microsoft.Extensions.AI.Abstractions). I won't go into the details in case it distracts from the core issue.
This scenario used to work well in earlier builds (last one I tried was commit 3ee9ddd, about 1 month old). However, starting today, I noticed that my custom AITool implementation is no longer working because AIFunctionArguments.Services always returns EmptyServiceProvider. Before it would return the IServiceProvider that gets passed to ChatClientBuilder.Build(IServiceProvider).
Repro Steps
Here's the code I had before, where the IChatClient infrastructure correctly used my provided IServiceProvider for binding to AITool parameters.
IServiceProvider sp = // ...
IChatClient chatClient = new AzureOpenAIClient(new Uri(azureOpenAiEndpoint), credential)
.GetChatClient(azureOpenAiDeploymentName)
.AsIChatClient()
.UseFunctionInvocation()
.Build(sp); // <-- add my service provider
ChatClientAgent agentClient = new(chatClient, agentOptions);
await agentClient.RunStreamingAsync(...); // <-- invokes AITool infrastructureInvestigation
The issue seems to be here:
agent-framework/dotnet/src/Microsoft.Extensions.AI.Agents/ChatCompletion/ChatClientExtensions.cs
Lines 22 to 27 in 78125f0
| chatBuilder.Use((IChatClient innerClient, IServiceProvider services) => | |
| { | |
| var loggerFactory = services.GetService<ILoggerFactory>(); | |
| return new NewFunctionInvokingChatClient(innerClient, loggerFactory, services); | |
| }); |
For some reason, the NewFunctionInvokingChatClient is always given EmptyServiceProvider as the services parameter. It somehow loses the IServiceProvider that I gave to my IChatClient originally.
Workaround
I worked around this by creating a custom IChatClient that implements NewFunctionInvokingChatClient and passing in my IServiceProvider there. That causes the code I highlighted above to get skipped, allowing my scenario to start working again. It took quite a bit of debugging to figure this out, though and it feels very fragile.
Hoping there is a simple fix to ensure that I don't have to rely on fragile workarounds. But it seems that the Agent Framework wrappers are breaking existing stable Microsoft.Extensions.AI behavior/expectations (custom parameter binding, in my case), so probably worth fixing.
Metadata
Metadata
Assignees
Labels
Type
Projects
Status