Python: Stream results for tools executed during approval resolution#7259
Closed
kartikmadan11 wants to merge 1 commit into
Closed
Python: Stream results for tools executed during approval resolution#7259kartikmadan11 wants to merge 1 commit into
kartikmadan11 wants to merge 1 commit into
Conversation
Tools executed while resolving approvals went through the prepped_messages branch of _process_function_requests, which spliced their results into the message history but returned update_role=None, so the streaming loop never yielded them. Consumers such as the AG-UI transport therefore never observed the result: for a deferred provider-injected tool the side effect fired but no result update was streamed, unlike a statically executed approval. Return the executed function_result items with update_role="tool" and add the matching yield gate after the first _process_function_requests call so these results stream like any other tool result. The non-streaming path is unaffected (it does not consume update_role and already carries the result via the spliced messages). Add a streaming regression test asserting an approved tool's result is streamed. Fixes microsoft#7241.
kartikmadan11
temporarily deployed
to
github-app-auth
July 22, 2026 12:57 — with
GitHub Actions
Inactive
kartikmadan11
temporarily deployed
to
github-app-auth
July 22, 2026 12:57 — with
GitHub Actions
Inactive
kartikmadan11
temporarily deployed
to
github-app-auth
July 22, 2026 12:57 — with
GitHub Actions
Inactive
kartikmadan11
temporarily deployed
to
github-app-auth
July 22, 2026 12:57 — with
GitHub Actions
Inactive
Contributor
There was a problem hiding this comment.
Pull request overview
This PR fixes a streaming gap in the Python function-invocation layer where tool calls executed during approval resolution were executed and spliced into message history, but their function_result was not emitted as a streamed update—so streaming consumers (notably the AG-UI transport) never observed a TOOL_CALL_RESULT.
Changes:
- In
_process_function_requests’ approval-resolution (prepped_messages) branch, return executedfunction_resultitems viaupdate_role="tool"+function_call_results. - In the streaming loop, add a yield gate after the first
_process_function_requestscall so those approval-executed tool results are actually streamed. - Add a regression test asserting exactly one streamed
function_resultappears after resuming with an approval response.
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 | Surfaces approval-executed tool results to the stream and yields them during streaming approval resolution. |
| python/packages/core/tests/core/test_function_invocation_logic.py | Adds a streaming regression test to ensure approved tool results are streamed exactly once. |
Comment on lines
+2784
to
+2790
| # Emit results for tools executed while resolving approvals (e.g. deferred | ||
| # provider-injected tools) so streaming consumers see them like normal tool results. | ||
| if role := approval_result.get("update_role"): | ||
| yield ChatResponseUpdate( | ||
| contents=approval_result.get("function_call_results") or [], | ||
| role=role, | ||
| ) |
Contributor
Author
|
Closing as a duplicate of #7243, which was opened first and takes the same approach (return the executed results with |
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
Tools executed while resolving an approval did not stream their result, so streaming consumers never observed it. This is the follow-on issue found while implementing #7043 / PR #7091: once provider-injected tools are deferred and executed in-run (instead of being rejected), their
function_resultwas consumed insideagent.runand never surfaced, so the AG-UI transport emitted noTOOL_CALL_RESULTfor them, unlike statically executed approvals.Fixes #7241
Description & Review Guide
What are the major changes?
_process_function_requests(_tools.py) executes the approved calls and splices results into the message history, but returnedupdate_role=None, so the streaming loop never yielded them. It now returns the executedfunction_resultitems withupdate_role="tool"._process_function_requestscall site in the streaming loop had no yield gate (unlike the second call site). Added the matching gate so these results stream like any other tool result. The existing AG-UI emitter then produces exactly oneTOOL_CALL_RESULT, with correct ordering and no transport changes.What is the impact of these changes?
update_roleand already carries the result via the spliced messages. No public API changes.What do you want reviewers to focus on?
prepped_messagesand fed to the next model call, which does not echo tool results back as content; the second_process_function_requestscall operates on the model response, not the already-executed approval. The added test asserts exactly one streamedfunction_resultper call.Related Issue
Fixes #7241
Contribution Checklist