-
Notifications
You must be signed in to change notification settings - Fork 849
Closed
Labels
area-aiMicrosoft.Extensions.AI librariesMicrosoft.Extensions.AI librariesbugThis issue describes a behavior which is not expected - a bug.This issue describes a behavior which is not expected - a bug.
Description
Description
Encountered a bug when parallel tool calling and ApprovalRequiredAIFunction. If no MessageId is set ChatMessages, the fallback mapping would incorrectly map the parallel calls and results into separate messages. This would then fail with APIs that require strict ordering of tool calls and tool results.
A work around is to remember setting the MessageId, but the mapping logic should also be fixed.
Reproduction Steps
using Microsoft.Extensions.AI;
var chatClient = new ChatClientBuilder(innerClient)
.UseFunctionInvocation()
.Build();
var tool = new ApprovalRequiredAIFunction(
AIFunctionFactory.Create(() => "result", "my_tool"));
var options = new ChatOptions { Tools = [tool] };
List<ChatMessage> messages =
[
new(ChatRole.User, "Please use the tools"),
// Assistant message with approval requests - NOTE: no MessageId set
new(ChatRole.Assistant,
[
new FunctionApprovalRequestContent("call_1", new FunctionCallContent("call_1", "my_tool")),
new FunctionApprovalRequestContent("call_2", new FunctionCallContent("call_2", "my_tool")),
]),
// User approved both
new(ChatRole.User,
[
new FunctionApprovalResponseContent("call_1", approved: true, new FunctionCallContent("call_1", "my_tool")),
new FunctionApprovalResponseContent("call_2", approved: true, new FunctionCallContent("call_2", "my_tool")),
]),
];
// BUG: This will send TWO separate assistant messages to the inner client:
// Assistant: [FunctionCallContent("call_1")]
// Assistant: [FunctionCallContent("call_2")]
// Tool: [FunctionResultContent("call_1"), FunctionResultContent("call_2")]
//
// EXPECTED: ONE assistant message with both FCCs:
// Assistant: [FunctionCallContent("call_1"), FunctionCallContent("call_2")]
// Tool: [FunctionResultContent("call_1"), FunctionResultContent("call_2")]
//
// This causes Anthropic to reject with:
// "unexpected tool_use_id found in tool_result blocks... Each tool_result block
// must have a corresponding tool_use block in the previous message."
var response = await chatClient.GetResponseAsync(messages, options);Expected behavior
Parallel tool calls should be mapped the same way whether MessageId is set or not
Actual behavior
Parallel tool calls are mapped incorrectly when MessageId is not set.
Regression?
No response
Known Workarounds
Set MessageId on ChatMessage
Configuration
No response
Other information
No response
Metadata
Metadata
Assignees
Labels
area-aiMicrosoft.Extensions.AI librariesMicrosoft.Extensions.AI librariesbugThis issue describes a behavior which is not expected - a bug.This issue describes a behavior which is not expected - a bug.