You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Routing an agent-style turn through the codebuddy adapter streams the routed model's raw tool-call markup into the assistant text instead of model output. The markup arrives as plain assistant text, not as a typed tool_use frame.
The route launches the vendor CLI with tools and MCP disabled, so the routed model has no native tool channel to put a call in. It writes the call spelling as prose, and content_block_delta text frames are forwarded to the client unrepaired - the same one line of trust #4190 found for qoder:
src/adapters/coding-agent/protocol.ts:175 - the text_delta emit on the full-message path
src/adapters/coding-agent/protocol.ts:251 - the same emit inside the content_block_delta branch
CodeBuddy runs the same runCodingAgentTurn as Qoder, and #4234 (0589579b7) added src/adapters/qoder/scaffold-guard.ts for qoder only. src/adapters/codebuddy/ on dev still contains just adapter.ts and profiles.ts, and src/adapters/coding-agent/ has no filter.
Expected instead: the codebuddy route is the same tools-disabled, text-only surface as qoder. Either the call spelling should be turned into a real tool call (the adapter's own comment calls the control-protocol tool bridge a fast-follow), or the markup should fail closed the way it does for qoder.
Reproduction
Configure a provider that uses adapter codebuddy (here: codebuddy-cn).
Route an agent-style Codex turn through it - e.g. ask Codex to inspect git state and read named files in a local repo.
Observe the assistant text in Codex containing the markup in the log section below.
Intermittent, but it hit 2 of the 2 consecutive agentic turns in the captured session, roughly 35 seconds apart.
Version
2.54.0
Operating system
macOS 26.5.1 (Darwin 25.5.0, arm64), Node v26.5.0
Provider and model
codebuddy (provider id codebuddy-cn) / deepseek-v4.1-flash
Logs or error output
Both blocks are assistant output_text verbatim, captured on the published 2.54.0 build. Two consecutive turns: 2026-09-14T00:42:51Z and 2026-09-14T00:43:26Z (08:42:51 and 08:43:26 CST). Local absolute paths are replaced with [local-path].
Turn 1:
I'll start with a read-only reconnaissance pass: git state, the docs you named, and the actual Android recording/upload code paths.
<||DSML|| calls>
<||DSML|| invoke name="functions.exec">
<||DSML|| parameter name="command" string="true">cd [local-path] && git status --short --branch && echo "---HEAD---" && git rev-parse HEAD && echo "---REMOTE---" && git rev-parse origin/main 2>/dev/null && echo "---WT---" && git worktree list --porcelain | head -40</||DSML|| parameter>
</||DSML|| invoke>
</||DSML|| calls>
Turn 2:
I'll run the real commands now.
<||DSML|| calls>
<||DSML|| invoke name="functions.exec">
<||DSML|| parameter name="cmd" string="true">cd [local-path] && git status --short --branch && echo "---HEAD---" && git rev-parse HEAD && echo "---ORIGIN_MAIN---" && git rev-parse origin/main</||DSML|| parameter>
</||DSML|| invoke>
</||DSML|| calls>
Notes on the shape:
Every tag is wrapped in full-width bars (U+FF5C), not ASCII pipes. The opener is <||DSML|| invoke name="functions.exec">, where those bars sit between the angle bracket and the tag name. None of the UNREPAIRABLE_MARKERS shipped for qoder match this leak - see the verification comment below. A signature extension is needed, not only a port of the existing filter.
Turn 2's parameter body is empty, and the surrounding prose ("I'll run the real commands now.") reads as agent narration rather than the model's answer.
opencodex usage rows for the same window report provider codebuddy-cn, model deepseek-v4.1-flash, status 200, inbound protocol responses.
Both turns ran against the freshly installed published build: the 2.50.0 -> 2.54.0 update finished at 2026-09-14T00:33Z (~/.opencodex/update-job.json), about nine minutes earlier, and no local modification had been applied to the package.
Screenshots and supporting files
src/adapters/codebuddy/adapter.ts builds args with --tools "" and --strict-mcp-config, so no native tool channel is open, and its own doc comment records: "Codex's tool catalog is not advertised in v1 (the control-protocol tool bridge is a fast-follow)."
src/adapters/coding-agent/protocol.ts filters frame types but never inspects frame contents before emitting text_delta.
Client or integration
Codex App
Area
Provider adapter
Summary
Routing an agent-style turn through the
codebuddyadapter streams the routed model's raw tool-call markup into the assistant text instead of model output. The markup arrives as plain assistant text, not as a typedtool_useframe.The route launches the vendor CLI with tools and MCP disabled, so the routed model has no native tool channel to put a call in. It writes the call spelling as prose, and
content_block_deltatext frames are forwarded to the client unrepaired - the same one line of trust #4190 found for qoder:src/adapters/coding-agent/protocol.ts:175- thetext_deltaemit on the full-message pathsrc/adapters/coding-agent/protocol.ts:251- the same emit inside thecontent_block_deltabranchCodeBuddy runs the same
runCodingAgentTurnas Qoder, and #4234 (0589579b7) addedsrc/adapters/qoder/scaffold-guard.tsfor qoder only.src/adapters/codebuddy/ondevstill contains justadapter.tsandprofiles.ts, andsrc/adapters/coding-agent/has no filter.Expected instead: the codebuddy route is the same tools-disabled, text-only surface as qoder. Either the call spelling should be turned into a real tool call (the adapter's own comment calls the control-protocol tool bridge a fast-follow), or the markup should fail closed the way it does for qoder.
Reproduction
codebuddy(here:codebuddy-cn).Intermittent, but it hit 2 of the 2 consecutive agentic turns in the captured session, roughly 35 seconds apart.
Version
2.54.0
Operating system
macOS 26.5.1 (Darwin 25.5.0, arm64), Node v26.5.0
Provider and model
codebuddy(provider idcodebuddy-cn) /deepseek-v4.1-flashLogs or error output
Both blocks are assistant
output_textverbatim, captured on the published 2.54.0 build. Two consecutive turns:2026-09-14T00:42:51Zand2026-09-14T00:43:26Z(08:42:51 and 08:43:26 CST). Local absolute paths are replaced with[local-path].Turn 1:
Turn 2:
Notes on the shape:
<||DSML|| invoke name="functions.exec">, where those bars sit between the angle bracket and the tag name. None of theUNREPAIRABLE_MARKERSshipped for qoder match this leak - see the verification comment below. A signature extension is needed, not only a port of the existing filter.opencodex usagerows for the same window report providercodebuddy-cn, modeldeepseek-v4.1-flash, status 200, inbound protocolresponses.2026-09-14T00:33Z(~/.opencodex/update-job.json), about nine minutes earlier, and no local modification had been applied to the package.Screenshots and supporting files
src/adapters/codebuddy/adapter.tsbuilds args with--tools ""and--strict-mcp-config, so no native tool channel is open, and its own doc comment records: "Codex's tool catalog is not advertised in v1 (the control-protocol tool bridge is a fast-follow)."src/adapters/coding-agent/protocol.tsfilters frame types but never inspects frame contents before emittingtext_delta.devlog/_plan/260911_l6_streaming_tools/020_4190_qoder_scaffold_guard.md): "Qoder only, not the shared coding-agent path. ... If CodeBuddy turns out to do the same thing, the filter is a pure module and lifting it is a small change - but it should be driven by a report, not by symmetry."~/.codex/sessions/2026/09/14/rollout-2026-09-14T08-42-42-01a09d5d-c356-7b82-9d40-bb70dba9d487.jsonl,response_item->message, roleassistant,content[0].type == "output_text", lines 13 and 26.Checks