fix(core): register MagicDocs on tool-result push, not only assistant push - #6160
Merged
Conversation
bug-ops
enabled auto-merge (squash)
July 12, 2026 18:28
bug-ops
force-pushed
the
fix/6127-magicdocs-bare-mode
branch
from
July 12, 2026 18:33
16c6c2a to
be2d2fb
Compare
… push MagicDocs registration never fired for a single read-then-respond turn (the canonical `--bare -p "read X"` shape) or for a turn that exited the native tool loop via shutdown/user-cancel/doom-loop/max-iterations with an unpaired tool result as the last message. detect_magic_docs_in_messages() only scanned when the last pushed message was Role::Assistant, deferring detection to the next assistant push. Two terminal-response sites in tier_loop.rs also bypassed push_message() entirely via a raw self.msg.messages.push(), so the detector never ran for the turn's final text response. Both raw pushes now route through push_message(), and the detection guard also scans when the last message is a Role::User message carrying ToolResult/ToolOutput parts, so detection fires uniformly at the point the content actually arrives, covering all native-loop exit paths. As a side effect, the two corrected push sites now also update cached_prompt_tokens and last_assistant_at, closing a pre-existing token-accounting gap on the semantic-cache-hit and plain-text-response paths. Not a `--bare`-conditional gate: with_bare_mode required no change. This was a general tool-loop message-push coverage gap that --bare's single-shot invocation pattern exposed deterministically. Closes #6127
bug-ops
force-pushed
the
fix/6127-magicdocs-bare-mode
branch
from
July 12, 2026 18:43
be2d2fb to
5d3817f
Compare
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.
Summary
--bare -p "read X"shape), or for a turn that exited the native tool loop via shutdown/user-cancel/doom-loop/max-iterations with an unpaired tool result as the last message.detect_magic_docs_in_messages()only scanned when the last pushed message wasRole::Assistant, deferring detection to the next assistant push. Two terminal-response sites intier_loop.rsalso bypassedpush_message()via a rawself.msg.messages.push(), so the detector never ran for the turn's final response.push_message(), and the detection guard also scans when the last message is aRole::Usermessage carryingToolResult/ToolOutputparts, so detection fires uniformly at the point content actually arrives, covering all native-loop exit paths (not just the two terminal push sites).cached_prompt_tokensandlast_assistant_at, closing a pre-existing token-accounting gap on the semantic-cache-hit and plain-text-response paths.--bare-conditional gate:with_bare_moderequired no change. This was a general tool-loop message-push coverage gap that--bare's single-shot invocation pattern exposed deterministically; interactive multi-tool-call sessions usually masked it via a retroactive scan on the next assistant push.Closes #6127
Test plan
crates/zeph-core/src/agent/tool_execution/tests/sanitize_and_native_tests.rs, each driving the realAgent::process_response()path (not a hand-built message history): single read-then-respond turn, semantic-cache-hit branch, and loop-exit viamax_iterationsexhaustion with an unpaired trailing tool result. All confirmed to fail on pre-fix code and pass on the fix.cargo +nightly fmt --checkcleancargo clippy --profile ci --workspace --all-targets --features "desktop,ide,server,chat,pdf,scheduler,testing" -- -D warningscleancargo nextest run --config-file .github/nextest.toml --workspace --features "desktop,ide,server,chat,pdf,scheduler" --lib --bins— 13180 passed, 35 skipped, no regressionsRUSTFLAGS="-D warnings" RUSTDOCFLAGS="--deny rustdoc::broken_intra_doc_links" cargo doc --no-deps --workspace --features "desktop,ide,server,chat,pdf,scheduler"clean