You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
FunctionInvokingChatClient: FunctionInvocationContext.Terminate is ignored when the function throws #7800
If an AIFunction sets FunctionInvokingChatClient.CurrentContext.Terminate = true and then throws, the function-invocation loop does not terminate. The exception is captured and turned into an error FunctionResultContent, but the termination request is dropped. The loop then calls the inner IChatClient again.
This is a common pattern. A tool hits an unrecoverable error (an auth failure, a policy violation, a budget exceeded) and needs to stop the agent loop right away, rather than let the model retry or keep going.
Expected: the response ends with the Tool message holding the error result, and the inner client is called only once. Actual: the inner client is called a second time with the error result, and the loop goes on.
The same thing happens with GetStreamingResponseAsync, with approved ApprovalRequiredAIFunction calls, and with FunctionInvokingRealtimeClientSession.
Root cause
In src/Libraries/Microsoft.Extensions.AI/Common/FunctionInvocationProcessor.cs, ProcessSingleFunctionCallAsync hard-codes terminate: false in the exception path:
When calls run one at a time, a throwing function that requested termination stops the remaining calls in that turn, the same as a terminating function that doesn't throw.
With AllowConcurrentInvocation = true, all calls in the turn finish, then the loop stops.
FunctionInvocationResult can now have Terminate == true with Status == Exception.
The realtime session also stops without sending results, the same as it does for non-throwing termination.
I have a fix with unit tests ready (chat streaming and non-streaming, serial and concurrent, approvals, realtime) and am happy to open a PR.
Activity