Skip to content

fix(codebuddy): serialize parallel tool-use blocks without corrupting calls - #5929

Closed
mdwsk88 wants to merge 2 commits into
lidge-jun:devfrom
mdwsk88:fix/codebuddy-parallel-tool-use
Closed

mdwsk88 wants to merge 2 commits into
lidge-jun:devfrom
mdwsk88:fix/codebuddy-parallel-tool-use

Conversation

@mdwsk88

@mdwsk88 mdwsk88 commented Sep 26, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • Preserve separate arguments when CodeBuddy emits interleaved tool-use blocks or reuses one content-block index for consecutive calls. Buffer each block and emit its complete start/delta/end sequence to the downstream bridge, which supports one open call at a time.
  • Refuse turn completion if any opened block remains incomplete. Regression coverage exercises distinct-index interleaving, same-index reuse, and terminal accounting.
  • Split the CodeBuddy fix out of fix(responses): route direct mcp tool calls through code-mode exec #5925 so it can be reviewed independently. This carries local commit 8b980c5b0 as c79968248 and documents the event contract.

Verification

  • bun test tests/providers/codebuddy-protocol.test.ts tests/providers/codebuddy-tool-bridge-turn.test.ts: 57 passed, 0 failed.
  • bun run typecheck: passed.
  • The earlier combined branch's broad changed-test run exceeded its 900-second watchdog and reported failures; it is not passing evidence for this PR. Full cross-platform validation remains outstanding. This PR stays draft while that broader coverage and maintainer review are pending.

Checklist

  • Scope stays focused and avoids unrelated cleanup.
  • Docs or release notes were updated when needed.
  • Security-sensitive changes were reviewed for secrets, auth, and unsafe defaults. This patch changes stream bookkeeping only and adds no credentials or logging.

Review readiness checklist

This PR stays in draft until every box below is ticked. Tick all four boxes once the requirements are met:

  • Required local validation passed; commands, results, and any full-suite exception are documented.

  • I pushed my PR to a recent dev commit (at most 10 behind; a maintainer may still ask for the exact tip before merge).

  • I resolved all correct Codex and CodeRabbit findings.

  • My PR is ready for review.

…ex reuse

CodeBuddy CLI parallel tool calls arrive as several tool_use blocks on ONE
shared content-block index: intermediate blocks never receive a
content_block_stop and only the final block does, while thinking deltas on
other indices interleave freely. The single open-call slot mis-attributed
argument fragments and miscounted completions (two starts, one counted
stop), so the turn failed closed with "Coding-agent CLI ended with an
incomplete tool call" 502s at message_stop — visible in Codex Desktop as
reconnect banners on CodeBuddy turns that make parallel tool calls.

Buffer each block under its own content-block index and emit it atomically
(start, deltas, end) when it closes: at its own stop, or when a new
tool_use start reuses its index — parallel argument streams are sequential,
so the block open on a reused index is complete. Index-less start frames
fall back to synthetic keys; index-less delta/stop frames resolve only when
exactly one block is open, otherwise the turn still fails closed.
@coderabbitai

coderabbitai Bot commented Sep 26, 2026

Copy link
Copy Markdown
Contributor

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

Copy link
Copy Markdown
Contributor

✅ Deterministic PR hygiene checks passed.

@github-actions github-actions Bot added the bug Something isn't working label Sep 26, 2026
@github-actions

Copy link
Copy Markdown
Contributor

⏳ DRAFT

  • review readiness checklist open (0/4 boxes ticked).

What to do

  • Tick all four boxes in the PR description once you're done (currently 0/4).

Review readiness checklist

  • ⬜ Required local validation passed; commands, results, and any full-suite exception are documented.
  • ⬜ I pushed my PR to a recent dev commit (at most 10 behind; a maintainer may still ask for the exact tip before merge).
  • ⬜ I resolved all correct Codex and CodeRabbit findings.
  • ⬜ My PR is ready for review.

0/4 boxes ticked.

This PR stays in draft until every box above is ticked.

@lidge-jun

Copy link
Copy Markdown
Owner

리뷰 · 우선순위 63 / 80

CodeBuddy가 도구를 여러 개 한꺼번에 부르면, 턴이 502로 죽던 문제를 고치는 PR이다. 베이스는 dev다.

예전 코드는 진행 중인 도구 호출을 한 칸만 기억했다. CodeBuddy는 같은 블록 번호에 도구를 여러 개 이어서 보내고, 중간 호출에는 끝(stop)을 보내지 않는다. 생각하는 내용의 조각은 다른 번호로 사이에 끼어든다. 그래서 인자 조각이 엉뚱한 호출에 붙거나, 시작은 두 번인데 끝은 한 번으로 세었다. 마지막에 "도구 호출이 안 끝났다"는 502가 났고, Codex Desktop에는 다시 연결하는 배너가 떴다.

이 PR은 블록 번호마다 호출을 따로 모아 둔다. 그 번호의 stop이 오거나, 같은 번호로 새 도구가 시작되면, 모아 둔 것을 시작, 인자, 끝 순서로 한 덩어리로 내보낸다. 아래쪽 다리는 한 번에 도구 하나만 열 수 있어서 이렇게 보낸다. 연 블록이 안 닫히면 턴을 성공으로 끝내지 않는다. 번호가 다른 호출이 겹치는 경우와, 같은 번호를 다시 쓰는 경우를 테스트로 넣었다.

#5925에서 CodeBuddy 수정만 떼어 온 초안이다. 작성자는 이 두 테스트와 타입체크는 통과했다고 적었다. 더 넓은 테스트는 900초를 넘기고 실패해서, 그 결과는 통과 근거로 쓰지 않는다고 했다. 리뷰 준비 체크는 0/4다.

src/adapters/coding-agent/turn.ts:453 - 도구 다리의 init 검사는 tool_call_start를 받을 때 돈다. 이 PR부터 그 이벤트는 블록이 시작될 때가 아니라, 블록을 닫을 때 나온다. 시작 프레임이 init보다 먼저 오고, 그 다음 init이 지나간 뒤 stop이 오면 검사가 통과한다. 같은 함수 주석(457-458)은 바로 이 순서를 막으려고, 호출이 도착하는 시점에 검사한다고 적혀 있다. 호출 개수 제한(toolCallStarts)도 닫힐 때까지 세지 않는다.

src/adapters/coding-agent/protocol.ts:438 - 같은 번호로 새 시작이 오면, 앞에 열려 있던 호출의 인자가 이미 끝났다고 보고 바로 닫는다. 2026-09-26 캡처(호출 두 개, 인자가 차례로 끝난 뒤 다음 시작)에는 맞다. 같은 번호에서 인자 조각이 겹치면 앞 호출은 그때까지 모인 조각만으로 닫히고, 뒤 조각은 다음 호출에 붙는다. 턴은 실패로 멈추지 않는다.

#5925 - 그 PR은 아직 열려 있다. 이 CodeBuddy 수정과, mcp__ 이름을 code-mode exec로 보내는 수정이 같이 있다. types.ts는 #5925에만 있다. 둘 다 머지하면 protocol.ts와 turn.ts의 CodeBuddy 수정이 두 번 들어간다.

메인테이너의 판단이 필요한 지점

같은 번호 재사용을, 캡처처럼 인자가 항상 끝난 뒤로 볼지 정해야 한다. 겹칠 수 있다고 보면 조용히 섞는 대신 실패로 막는 쪽이 맞다.

#5925에 남아 있는 CodeBuddy 커밋을 뺄지 정해야 한다. types.ts를 건드리는 code-mode 수정은 그 PR에만 있고, 이 PR과 범위가 다르다.

너의 추천

init 검사와 호출 개수 제한은 블록을 여는 content_block_start 시점으로 옮긴다. 닫을 때 내보내는 tool_call_start와 검사를 분리하면, 사이에 init이 끼어도 일찍 온 호출을 통과시키지 않는다.

같은 번호로 닫기 전에 인자가 비어 있으면 성공으로 넘기지 말고, 지금처럼 502로 막는다. 캡처에 맞는 정상 경로는 이미 테스트가 있으니, 빈 인자로 닫히는 경우만 하나 더 넣으면 된다.

#5925에서는 CodeBuddy 커밋을 빼고 code-mode 수정만 남긴다. 이 PR은 초안인 채로 두고, 작성자가 말한 넓은 테스트가 정리된 뒤에 머지 여부를 본다.

이 댓글은 grok-bot이 작성했습니다

lidge-jun added a commit that referenced this pull request Sep 26, 2026
…acy-gate hang) (#5945)

* fix(codebuddy): serialize parallel tool-use blocks without corrupting calls (#5929)

Carried from #5929 as one squashed commit.

Co-authored-by: mdwsk88 <924038395@qq.com>

* fix(codebuddy): validate bridge init at tool-use start arrival

* fix(codebuddy): reject ambiguous indexless tool argument deltas

* docs(devlog): batch 8 plan

* fix(test): bound privacy gate aggregate child

The macOS control batch stopped at the first aggregate-gate shell invocation and hit the 300s batch watchdog even though spawnSync specified 5s. Replace the synchronous call with an async spawn, ignored stdin, and an independent SIGKILL deadline that reports the child by name. Cover event-loop progress and the deadline path.

---------

Co-authored-by: mdwsk88 <924038395@qq.com>
@lidge-jun

Copy link
Copy Markdown
Owner

Thanks! This landed on dev through the bug-PR merge train batch #5945 (merge fa46080). Your change is one commit on dev with you as the author and a Co-authored-by trailer. Two follow-ups on top of your change, each with a regression that fails without it: the tool-bridge init check now runs when a tool-use start frame arrives, not when the buffered call closes, and an argument delta without an index fails the turn while more than one tool block is open instead of being dropped. Closing since the content is now on dev.

@lidge-jun lidge-jun closed this Sep 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants