Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Jan 14, 2026

  • Understand the problem: When FunctionInvokingChatClient reaches its maximum iterations limit, it should not include any AIFunctionDeclaration tools in the ChatOptions.Tools it sends to the inner service

Changes

  • Added PrepareOptionsForLastIteration helper method that removes AIFunctionDeclaration tools from options
  • Modified GetResponseAsync to call this method when iteration >= MaximumIterationsPerRequest
  • Modified GetStreamingResponseAsync similarly
  • If no tools remain after filtering, also clears ToolMode
  • Added 4 comprehensive tests for the new behavior

Tests Added

  • LastIteration_RemovesFunctionDeclarationTools_NonStreaming - Verifies tools are removed on last iteration
  • LastIteration_RemovesFunctionDeclarationTools_Streaming - Verifies tools are removed on last iteration for streaming
  • LastIteration_PreservesNonFunctionDeclarationTools - Verifies non-AIFunctionDeclaration tools (like HostedWebSearchTool) are preserved
  • LastIteration_DoesNotModifyOriginalOptions - Verifies original options are not mutated

Verification

  • All 56 FunctionInvokingChatClientTests pass on net9.0
  • Code review feedback addressed
Original prompt

FunctionInvokingChatClient exposes a max iterations setting, where it will stop making additional calls to the inner client once it reaches that limit. Please update it so that when it's on its last iteration, it doesn't include any tools AIFunctionDeclarations in the ChatOptions.Tools it sends to the inner service (and if that drops the Tools count to 0, clear the ToolsMode setting). Otherwise, the final request to the inner client can end up coming back with tool requests. Please ensure this is thoroughly tested, adding any necessary tests to existing test files.


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Microsoft Reviewers: Open in CodeFlow

Copilot AI and others added 2 commits January 14, 2026 14:48
- Add PrepareOptionsForLastIteration helper method that removes
  AIFunctionDeclaration tools from options on the last iteration
- Modify GetResponseAsync to call PrepareOptionsForLastIteration when
  iteration >= MaximumIterationsPerRequest
- Modify GetStreamingResponseAsync similarly
- If no tools remain after filtering, also clear ToolMode
- Add 4 comprehensive tests for the new behavior

Co-authored-by: stephentoub <2642209+stephentoub@users.noreply.github.com>
- Simplify condition logic in PrepareOptionsForLastIteration by using a local variable for remaining count
- Simplify test assertions for better readability

Co-authored-by: stephentoub <2642209+stephentoub@users.noreply.github.com>
Copilot AI changed the title [WIP] Update FunctionInvokingChatClient max iterations behavior Remove AIFunctionDeclaration tools on last iteration in FunctionInvokingChatClient Jan 14, 2026
Copilot AI requested a review from stephentoub January 14, 2026 14:54
@stephentoub stephentoub marked this pull request as ready for review January 14, 2026 16:23
@stephentoub stephentoub requested a review from a team as a code owner January 14, 2026 16:23
Copilot AI review requested due to automatic review settings January 14, 2026 16:23
@stephentoub
Copy link
Member

@westey-m , @rogerbarreto , @eiriktsarpalis I've opened this after seeing microsoft/agent-framework#3113. Good idea? Better to leave as is?

- Remove all Arrange/Act/Assert comments from tests
- Replace MockNonFunctionTool with HostedWebSearchTool
- Delete the MockNonFunctionTool class

Co-authored-by: stephentoub <2642209+stephentoub@users.noreply.github.com>
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR addresses an issue where FunctionInvokingChatClient would send function declaration tools to the inner client on the final iteration (when the maximum iterations limit is reached), potentially causing the inner client to return tool call requests that would never be executed.

Changes:

  • Added PrepareOptionsForLastIteration helper method that filters out AIFunctionDeclaration tools when reaching the iteration limit
  • Applied this filtering to both GetResponseAsync and GetStreamingResponseAsync methods
  • Options are cloned before modification to preserve the original caller's options
  • ToolMode is cleared when all tools are removed (all were AIFunctionDeclaration), but preserved when non-function tools remain

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
src/Libraries/Microsoft.Extensions.AI/ChatCompletion/FunctionInvokingChatClient.cs Added PrepareOptionsForLastIteration method and integrated it into both streaming and non-streaming code paths to remove AIFunctionDeclaration tools on the last iteration
test/Libraries/Microsoft.Extensions.AI.Tests/ChatCompletion/FunctionInvokingChatClientTests.cs Added comprehensive tests covering non-streaming, streaming, non-function tool preservation, and original options immutability scenarios

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants