Repository navigation
Python: [Bug]: Mixed approval and Host results give a tool result the user role #8700
Description
Description
On current main (834eb7ff12c83aadee56d468e3b01b4f0fc4084c), AgentExecutor._resume_with_pending_responses assigns one role to an entire resumed response batch:
role = "tool" if all(r.type == "function_result" for r in self._pending_responses_to_agent) else "user"When one paused workflow turn contains both a declaration-only (Host-owned) function call and an approval request, the Host's terminal function_result and the function_approval_response can arrive in the same batch. The approval response makes the condition false, so the resumed SupportsAgentRun.run receives user(function_result, function_approval_response). With the reverse input order it receives user(function_approval_response, function_result). In both cases the Host result has the wrong role at the executor boundary.
I expect the terminal result to remain in a tool-role message and the approval response in a user-role message, preserving input order and grouping only adjacent contents of the same role. For three interleaved responses this yields tool(function_result), user(function_approval_response), tool(function_result). This follows the Python core guidance and function-calling-loop specification.
A repository-local regression using a capturing fake agent checks both streaming and non-streaming resumes, both response orders, and interleaved Host results. All 5 focused cases fail against unchanged main at the role assertion and pass with a focused role-splitting change. The change applies cleanly to the above main; its workflow test file passes 19 tests, and the Python workspace suite passes 15,168 tests (541 skipped, 2 xfailed). Provider-specific serialization or a live provider failure has not been demonstrated; the observed bug is at the executor-to-agent boundary.
Code Sample
A minimal reproduction can be added to python/packages/core/tests/workflow/test_agent_executor_tool_calls.py: pause an AgentExecutor workflow whose captured agent response has one declaration-only function_call and one function_approval_request; resume with:
responses = {
host_request.request_id: Content.from_function_result(
call_id=host_request.data.call_id, result="Host result"
),
approval_request.request_id: approval_request.data.to_function_approval_response(
approved=True
),
}
await workflow.run(responses=responses)
# The capturing agent should receive tool(function_result), user(function_approval_response).Error Messages / Stack Traces
The regression fails on the role sequence. No provider error or stack trace was observed.
Package Versions
agent-framework-core: current source main at 834eb7ff12c83aadee56d468e3b01b4f0fc4084c; released package version not verified.
Python Version
Python 3.12 in the local locked test environment.
Additional Context
This is distinct from #8573, which concerns ownership/correlation of Host responses to the active batch, and from #6385, which concerns which calls receive approval wrappers. This issue concerns the role of already-collected responses during AgentExecutor resume.
The Python contribution guidance asks external contributors to check with the core team before changing function-loop/approval-resume behavior. Could a maintainer confirm whether splitting this mixed batch into ordered tool/user messages at AgentExecutor._resume_with_pending_responses is the intended contract, or point to a preferred approach? I have a focused change and regression tests prepared, and will wait for direction before opening a PR.
Metadata
Metadata
Labels
Type
Projects
- StatusShow more project fieldsDone
Activity
github-actions commentedon Sep 23, 2026
🤖 Automated triage reproduction notes (agent-authored — trust but verify)
Agent analysis
Repro:
python/packages/core/agent_framework/_workflows/_agent_executor.py::_resume_with_pending_responseslines 445-455 assigns one user role when pending responses contain both a Hostfunction_resultandfunction_approval_response. Minimal repro: runtest_agent_executor_mixed_resume_preserves_content_roles, which pauses a mixed declaration-only/approval workflow and resumes with the Host result followed by approval. The captured agent input isuser(function_result, function_approval_response)rather than orderedtool(function_result), user(function_approval_response).python/packages/core/tests/workflow/test_agent_executor_tool_calls.py::test_agent_executor_mixed_resume_preserves_content_roles1.19.0ryo-whaletech commentedon Sep 23, 2026
Thanks for the automated reproduction.
I already have a focused patch and regression tests prepared locally. To avoid duplicate work, I'd be happy to open it as a Draft PR if that would be useful, but given the contribution guidance for function-calling and approval changes, I'll wait for core-team confirmation before opening it.