-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Description
Bug Description
UseAIContextProviders merges AIContext.Tools from context providers (e.g., FileAgentSkillsProvider) into ChatOptions.Tools on every API call, but never clears previously injected tools. When ChatOptions.Tools is a shared mutable list reference, tools from context providers accumulate across calls.
Steps to Reproduce
- Register a
FileAgentSkillsProviderviaUseAIContextProviders - Pass a
List<AITool>toChatOptions.Tools(shared reference) - Make multiple API calls through the agent
After the first call, ChatOptions.Tools contains load_skill and read_skill_resource (injected by the provider). After the second call, it contains two copies of each. After N calls, N copies.
Impact
- Anthropic API rejects the request with HTTP 400:
"tools: Tool names must be unique." - OpenAI API silently accepts duplicates, so the bug goes unnoticed there
- The tool list grows unboundedly across calls, wasting tokens
Expected Behavior
Context provider tools should be merged into a per-request copy of ChatOptions.Tools, not into the original shared list. The original list should remain unmodified so subsequent calls start from a clean baseline.
Workaround
We reset ChatOptions.Tools to a fresh snapshot of our baseline tool list before each call in a DelegatingChatClient, so the framework's merge always starts clean:
// In a DelegatingChatClient sitting before UseAIContextProviders in the pipeline
private void ResetToolsFromBaseline(ChatOptions? options)
{
if (options is null) return;
options.Tools = new List<AITool>(baseline);
}Environment
Microsoft.Agents.AIv1.0.0-rc4- Provider: Anthropic (Claude) via
Microsoft.Extensions.AI - .NET 10