Repository navigation
Conversation
…linked sub-agent chunks A custom registration that IS the CodeBuddy CLI (multi-account or env-isolated setups — `codebuddy`, `codebuddy-*` in the registry) streams exactly the shapes the built-in agent does, but every CodeBuddy quirk was gated on `AgentType::CodeBuddy` alone: its sub-agent thought/message chunks leaked into the main stream (each also rendered inside the Agent pill's window, out of order), and it missed the Agent-pill title rewrite and the deferred-MCP unwraps. `is_codebuddy_family` (the built-in, or a `codebuddy` / `codebuddy-*` custom id) now gates all eight sites; the id-prefix scope keeps every quirk on agents that ARE the CodeBuddy CLI, so no unrelated agent's `codebuddy.ai/*` keys can alias in. Suppression of sub-agent chunks becomes the FALLBACK. Measured on CodeBuddy 2.164.0: every sub-agent thought/message chunk carries a flat `_meta["codebuddy.ai/parentToolCallId"]` (main-thread chunks never do), so a linked chunk is routed exactly like Claude's parented chunks — forwarded with its attribution, and the frontend files it into the live Agent capsule, so the sub-agent's thinking/text survives into the settled card instead of vanishing with the suppressed stream. The attribution reader is renamed to `subagent_chunk_parent_tool_use_id` (two wire shapes today: Claude's nested `_meta.claudeCode.parentToolUseId` and the family's flat key), and each family's own id space stays separate so neither can alias the other. Tests: the family scope, the custom variant's suppression + meta classification path, and the flat-key reader (family-only, empty/wrong-type absent).
|
@Liang-HZ hi, and thank you for this PR! 🙏 The problem is real, and the description pins it down well: a custom registration that runs the CodeBuddy CLI streams exactly what the built-in agent streams, yet none of codeg's CodeBuddy-specific handling in the connection layer reaches it, so sub-agent chunks spill into the main thread. The measurement is what makes the second half possible, and it holds up. I unpacked That said, I'm not going to merge it in its current form. The core reason is that with this PR, codeg would show a conversation one way while it streams and another way after it's reopened. Below is everything in one place (the two places where live and history disagree, a concern about how the family is recognized, a suggested way forward, smaller issues in the diff, and tests) to make the next round easier. If you think I got something wrong, please push back 🙂 Summary
1. Main issue: custom registrations only get the live half
The projection test (paste it into the
|
… timeline, emit-path tests - drop is_codebuddy_family and every id-prefix gate: the quirk handling keys on AgentType::CodeBuddy exactly, so custom registrations whose id merely starts with "codebuddy" get none of it (pinned by a negative test) - remove the unreachable parent-link branch in codebuddy_chunk_marks_subagent and rewrite its doc around the measured 2.164.0 behavior - build agent_stats.timeline from the sub-agent transcript — thinking and text interleaved with tool markers, role-guarded, truncated per entry — and keep agent_stats for a text-only sub-agent (None only when the transcript has neither calls nor prose) - hoist TIMELINE_ENTRY_MAX_CHARS to parsers/mod.rs - drive emit_conversation_update end to end in a tokio test over several updates sharing one CodeBuddyLiveState: a linked chunk is emitted with its parent, an unlinked one is suppressed, and a main-thread chunk after the Agent call completes carries no parent - sync the store/types/context comments that documented the old shape
|
Thanks for the thorough review — we re-verified every point locally and you're right on all of them. This round implements piece 1 of your suggested split (built-in CodeBuddy: routing + its history together); for custom registrations we'd like to settle direction first, as you proposed. What changed:
§4.2 custom registrations — we'd prefer (b), native accounts via #919, and would rather not start the projection work until we agree: (1) does #919's per-account |
…-quirks # Conflicts: # src-tauri/src/parsers/claude.rs # src-tauri/src/parsers/codebuddy.rs
The problem
CodeBuddy's ACP stream needs a handful of special-case handling in codeg — sub-agent chunks that must not leak into the main thread, the Agent-pill title rewrite, deferred-
ExecuteToolunwrapping. Every one of those gates was written asagent_type == AgentType::CodeBuddy(or!=, for the guards), i.e. it only recognized the built-in agent.A custom registration that is the CodeBuddy CLI — the common multi-account / env-isolated setup (
codebuddy,codebuddy-cn,codebuddy-intl… in the registry) — streams exactly the same shapes, but matched none of the gates:ExecuteToolenvelope.What this changes
1.
is_codebuddy_familygates all eight quirk sites — the built-in, or a custom id that iscodebuddy/codebuddy-*. The id-prefix scope is deliberate: it keeps every quirk on agents that ARE the CodeBuddy CLI, so no unrelated agent'scodebuddy.ai/*_metakeys can alias into the handling.2. Suppression becomes the fallback; linked chunks are routed. Suppression was the only tool before: a chunk whose wire carried its own link was dropped with everything else once it fell outside the tracking window, so the settled Agent capsule lost the sub-agent's thinking/text. Measured on CodeBuddy 2.164.0: every sub-agent thought/message chunk carries a flat
_meta["codebuddy.ai/parentToolCallId"], and no main-thread chunk does — so a linked chunk can be routed exactly like Claude's parented chunks (forwarded with its attribution; the frontend files it into the live Agent capsule).should_suppress_subagent_chunknow yields to a link and only catches unlinked chunks.The attribution reader is renamed
claude_chunk_parent_tool_use_id→subagent_chunk_parent_tool_use_id, since it now serves two wire shapes: Claude Code's nested_meta.claudeCode.parentToolUseId(claude-agent-acp ≥0.63 with thesubagent-transcriptcapability) and the family's flat key. Each family's own id space stays separate — the flat key on a Claude chunk and the nested key on a CodeBuddy chunk both read as absent.Verification
cargo test/cargo clippy -- -D warnings: green on the branch.None), and the routing fallback (linked chunk not suppressed even inside an open window; unlinked chunk still suppressed).custom:codebuddy-intl), sub-agent thinking/text reappears inside the Agent capsule after the turn settles, and a re-opened session rebuilds the same capsules (the finish/route path runs identically at parse time).