Python: Drop post-limit streamed function calls#7334
Open
scarab-systems wants to merge 2 commits into
Open
Conversation
Filter function_call content from streaming updates once max_function_calls has forced tool_choice=none, so a provider-disobeyed post-limit call is not forwarded without a matching result. Keep existing fallback text behavior when no visible final content remains, and strip function_call content from limit fallback responses before returning them. Add a regression test that simulates a streaming provider returning another function_call after the call budget is exhausted. Validation: uv run pytest packages/core/tests/core/test_function_invocation_logic.py -q -k 'streaming_max_function_calls_drops_post_limit_function_call_update'; uv run pytest packages/core/tests/core/test_function_invocation_logic.py -q -k 'max_function_calls or max_iterations'; uv run pytest packages/core/tests/core/test_function_invocation_logic.py -q; uv run poe check -P core.
scarab-systems
temporarily deployed
to
github-app-auth
July 26, 2026 16:29 — with
GitHub Actions
Inactive
scarab-systems
temporarily deployed
to
github-app-auth
July 26, 2026 16:29 — with
GitHub Actions
Inactive
scarab-systems
temporarily deployed
to
github-app-auth
July 26, 2026 16:29 — with
GitHub Actions
Inactive
scarab-systems
temporarily deployed
to
github-app-auth
July 26, 2026 16:29 — with
GitHub Actions
Inactive
scarab-systems
temporarily deployed
to
github-app-auth
July 26, 2026 16:29 — with
GitHub Actions
Inactive
Contributor
There was a problem hiding this comment.
Pull request overview
This PR fixes a streaming edge case in the Python Agent Framework function-invocation limit path: when max_function_calls is reached and the framework requests a final tool_choice="none" response, any provider that still streams function_call content could cause clients (e.g., AG-UI) to observe tool-call starts without a corresponding tool result.
Changes:
- Strip
function_callcontent from post-limit streaming updates before forwarding them to callers. - Strip
function_callcontent from finalized responses in the max-function-calls fallback path before deciding whether to synthesize fallback text. - Add a regression test covering a streaming provider emitting another
function_callaftermax_function_callsis exhausted.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| python/packages/core/agent_framework/_tools.py | Filters post-limit streamed tool-call content and ensures finalized responses don’t retain over-limit function_call items. |
| python/packages/core/tests/core/test_function_invocation_logic.py | Adds coverage to ensure post-limit streamed function_call updates are not forwarded and no orphaned tool calls appear. |
Keep post-limit streaming updates when function_call content is stripped but the chunk still carries meaningful metadata, such as finish_reason, continuation_token, ids, provider metadata, or raw provider representation. Add regression coverage for a provider chunk that includes both a disallowed post-limit function_call and finish/provider metadata. Validation: uv run pytest packages/core/tests/core/test_function_invocation_logic.py -q -k 'streaming_max_function_calls_drops_post_limit_function_call_update or streaming_max_function_calls_preserves_post_limit_update_metadata'; uv run pytest packages/core/tests/core/test_function_invocation_logic.py -q -k 'max_function_calls or max_iterations'; uv run poe check -P core; SDS workspace-execution pytest-function-limit-copilot-review.
scarab-systems
temporarily deployed
to
github-app-auth
July 26, 2026 16:50 — with
GitHub Actions
Inactive
scarab-systems
marked this pull request as ready for review
July 26, 2026 16:55
scarab-systems
temporarily deployed
to
github-app-auth
July 26, 2026 16:55 — with
GitHub Actions
Inactive
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation & Context
Fixes #7045.
When
max_function_callsis reached, Agent Framework asks the provider for a final response withtool_choice="none". If a streaming provider still returns a function call on that final turn, forwarding it exposes a tool call that the framework will not execute, so transports such as AG-UI can be left waiting for a matching tool result.Disclosure: This PR was prepared with AI assistance under human direction and review.
Description & Review Guide
function_callcontent from post-limit streaming updates before forwarding them to callers.function_callcontent from limit fallback responses before deciding whether fallback text is needed.function_callaftermax_function_callsis exhausted.Related Issue
Fixes #7045
Contribution Checklist
breaking changelabel (or add "[BREAKING]" to the title prefix, before or after any language prefix) -- a workflow keeps the label and title prefix in sync automatically.