Repository navigation
fix(runner): route combined tool responses to each parallel branch - #7698
Open
xxwtiancai wants to merge 1 commit into
Open
xxwtiancai wants to merge 1 commit into
xxwtiancai wants to merge 1 commit into
Conversation
xxwtiancai
force-pushed
the
fix/multi-branch-confirmation-7685
branch
from
October 23, 2026 16:55
dd6e8f1 to
50af2d6
Compare
xxwtiancai
marked this pull request as draft
October 23, 2026 17:26
xxwtiancai
marked this pull request as ready for review
October 23, 2026 17:26
A user message answering confirmation calls from two parallel branches was stamped with the first matching call's branch, so the other branch never saw its approval: its tool did not run and its model received the pending-confirmation placeholder. Persist the message as one event per matching (branch, isolation_scope) context, linked by an internal message group id that confirmation selection uses to collect the whole message, and apply the state delta once. Fixes google#7685
xxwtiancai
force-pushed
the
fix/multi-branch-confirmation-7685
branch
from
October 23, 2026 17:28
50af2d6 to
a784ad8
Compare
xxwtiancai
marked this pull request as draft
October 23, 2026 17:28
xxwtiancai
marked this pull request as ready for review
October 23, 2026 17:28
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.
Link to Issue or Description of Change
Closes #7685.
When one incoming message confirms tool calls from two parallel branches,
Runner currently assigns the whole message to the first matching call's
branch. The other branch cannot see its confirmation, so its approved tool
does not execute and its model receives the pending-confirmation placeholder.
Reversing the response order changes which tool executes.
Persist the message as one event per matching
(branch, isolation_scope)context. Each response stays with its originating call; the existing branch
and isolation filters remain intact. Apply the supplied state delta once,
preserve response order within each context, and yield all resulting user
events when requested.
Give these events a shared internal message identifier. Confirmation selection
can then collect the latest message's visible responses when an ancestor sees
multiple projected events, including after storage reorders equal-timestamp
events. Selection remains restricted to that message and invocation. Messages
whose responses all share one context retain the single-event path.
Testing Plan
Update: the branch has since been rebased onto main at
cbca417c(the seven upstream additions touch plugins, eval, CLI, descriptors,MCP handling, McpTool auth and the MongoDB memory service — none overlap these
files).
On the rebased branch, Python 3.11.14 / macOS arm64: all 58 new cases pass, the
full runner, flows and workflow suites pass (2770 passed, 2 skipped, 4
xfailed), the base-commit control still reproduces 16 failed / 32 passed
without the fix, and pre-commit and mypy on the changed files are clean.
Unit tests
toxmatrix.The 48 public-Runner cases cover Workflow and resumable ParallelAgent, both
response orders, all four approval/rejection combinations, an unaffected third
branch approved later, separate-message controls, ancestor/descendant branch
views, and a shared branch with distinct isolation scopes. Against the base
commit, this matrix has 16 failed, 32 passed. With the fix, all 48 pass.
Ten additional memory/SQLite cases check context routing, single/same-context
controls, unique event IDs, preserved metadata, storage reload, input ownership,
and applying state updates once. All 58 new cases pass.
Focused Runner, confirmation, invocation-context, workflow-interruption and
event suites, using this source tree and pre-existing local test environments:
Full Python 3.11 suite, with no test exclusions:
Both failures reproduce on the unchanged base in the same environment:
test_reading_directory_raises: the macOS fixture does not raise the expectedOSError; it also fails outside the sandbox.test_completions_http_client_streams_longer_than_request_timeout: the sandboxrejects binding a local listener to
127.0.0.1. It passes outside the sandbox.The full supported-version matrix in fresh tox environments has not been run;
the focused runs above reuse installed dependencies. Pre-commit checks for the
changed files and
git diff --checkpass. Mypy on Runner and the workflowentrypoint reports the same 236 existing errors as the base after normalizing
line numbers, with no new diagnostics. Wheel and source distribution builds pass.
The optional
addlicenseexecutable is absent, so its hook skips the tool;existing file headers are preserved.
Independent Astra xhigh review approves the final patch. Its separate checks
include four SQLite append/reload/resume cases with deliberately reversed event
order and three stale-message controls, all passing, plus 73 selected repository
tests. The SQLite resume probe migrates an actual paused in-memory session into
SQLite before exercising the changed persistence path; it does not claim full
dynamic-workflow startup coverage on SQLite.
Manual end-to-end tests
Use the exact scripted
BaseLlmreproduction from #7685 asrepro_issue_7685.py.It requires no model service or API key. From the checkout with test dependencies
available:
The combined-message run before this fix prints:
Both commands after the fix print:
Also ran both commands using the extracted locally built wheel as
PYTHONPATH,with existing test dependencies; both pass. This is a wheel-source smoke check,
not a fresh dependency-install test.
Checklist
No public API or stored model schema changes, and no downstream changes are
required.