Repository navigation
[Kiro] Multiple outputs for one Codex exec call produce duplicate toolResult entries #3734
Description
Client or integration
Codex App
Provider or upstream service
Kiro
OpenCodex version
2.44.0 / af344a2
Endpoint or capability
POST /v1/responses, Codex code-mode exec tool results
Current behaviour
A single Codex code-mode exec call can emit several adjacent custom_tool_call_output items with the same call_id when the script calls notify() before its final text() result. The Kiro adapter currently translates every output into a separate toolResult with the same toolUseId. Kiro consumes the tool use with the first result, then rejects the next duplicate result because no unmatched tool use remains.
Expected behaviour
The Kiro adapter should emit one toolResult for adjacent outputs belonging to the same call_id. It should append their content in input order, retain images, and propagate error status if any merged output is an error. If the same call_id reappears after a different call's result, the adapter should continue rejecting that ambiguous ordering.
Minimal redacted request or reproduction
Run one Codex exec tool call whose script emits:
notify("update-1");
notify("update-2");
text("final-result");On the next model request, the Responses input contains three adjacent outputs associated with the same call_id.
Actual response or error
Kiro tool result has no matching tool use "call_58be3e59-ef13-4c50-8863-c48a9126183b"
Upstream documentation
No public Kiro or CodeWhisperer specification was found for multiple results on one toolUseId. The concrete client requirement is the observed Codex code-mode output sequence together with Kiro's validation that accepts one result for each tool use.
Suggested mapping or implementation notes
While converting Responses messages to Kiro messages, merge only immediately adjacent results whose toolUseId matches the last emitted toolResult. Append text and images without reordering them and change the merged status to error if a later adjacent result is an error. Do not search earlier turns or merge across another tool's result, because that could hide invalid parallel ordering.
A focused regression test should cover three adjacent outputs becoming one ordered result, plus call-a, call-b, call-a remaining invalid.
Additional context and attachments
The same report was previously opened as #3731 and closed only because it did not use a recognized issue template.
A local fix was validated with 83 Kiro adapter tests, typecheck, and git diff --check. The focused cases cover ordered text, retained images, propagated error status, call-a / call-b / call-a rejection, and rejection when user input interrupts two results for the same call. A live Codex smoke test completed a code-mode call with notifications and a final result through Kiro. The broad changed-test suite was not rerun because a previous run exhausted system memory and the Linux kernel terminated Chromium; affected suites were run independently.
Checks
- I searched existing provider and compatibility issues.
- The request and response were redacted.
- The expected behaviour is based on an upstream specification or a concrete client requirement.
Activity
yrlan-montagnier commentedon Sep 6, 2026
I implemented and validated a focused local patch against base commit
af344a28eabcee09a5e04c48ab897449792719c2(the currentorigin/devat the time of testing).The implementation tracks adjacency in the original parsed message sequence, rather than only looking at the normalized Kiro user turn. This matters because normalization can combine adjacent user-side content: a user/developer message or assistant message resets the merge candidate. Only a directly following result with the same normalized
toolUseIdis appended to the last Kiro result.The regression coverage verifies ordered text, image retention, error propagation, rejection of
call-a / call-b / call-a, and rejection when user input interrupts two results for the same call.Local patch
Validation:
bun test tests/providers/kiro/kiro-adapter.test.ts: 83 pass, 0 failbun run typecheck: passedgit diff --check: passednotify()calls followed bytext()returned all three outputs without a duplicatetoolResulterrorThe patch is currently uncommitted, so this comment records the exact proposed implementation rather than pointing to a branch that may change.
Ingwannu commentedon Sep 6, 2026
Confirmed the local failure on exact
devheadaf344a28eabcee09a5e04c48ab897449792719c2, without making an upstream request. A singlecustom_tool_call_outputbuilds successfully; three adjacent outputs for that same call are preserved as three parser results and then fail Kiro's local conversation validation withKiro tool result has no matching tool use.The relevant boundary is
src/adapters/kiro.ts:pushUser()appends separate result entries, whilevalidateKiroConversationState()consumes each pending tool use once. This is an adapter compatibility defect, not evidence that the code-mode call itself failed.Thanks for posting the proposed patch. Please submit your existing change as a focused PR targeting
dev, with its regression tests and a short note in the adapter/transport documentation. Tracking adjacency in the original message sequence, not just the collapsed Kiro user turn, is important: keep the intervening user/developer/assistant andcall-a / call-b / call-anegative cases. Retain the image/error-status cases too.My isolated diagnostic checks included the single-output control and the failing multi-output case; they establish the current bug, not approval of the proposed fix or a fresh live Kiro test. Keeping this open until a reviewed fix lands; I will not duplicate your implementation under another author.
lidge-jun commentedon Sep 6, 2026
리뷰 · 우선순위 73 / 80
이 이슈는 Codex code-mode
exec가 한 번의 호출에서notify()여러 번 + 최종text()를 내면, 같은call_id의custom_tool_call_output이 여러 개 인접하고, Kiro 어댑터가 각각을 별도 toolResult로 보내 두 번째부터Kiro tool result has no matching tool use로 죽는 문제입니다. 지금dev(HEADaf344a28e)의src/adapters/kiro.ts는pushUser()로 toolResults를 붙이고,validateKiroConversationState()는 pending tool use를 결과 하나당 한 번만 소비합니다. 파서는 인접 출력을 여러toolResult로 유지하므로, 어댑터 호환 결함입니다(코드 실행 자체가 실패한 증거가 아님). OWNER(Ingwannu)가 단일 출력은 성공·다중 인접 출력은 로컬 검증 실패로 HEAD에서 확인했습니다.보고자 패치는 원본 메시지 순서로 adjacency를 추적합니다. user/developer/assistant가 나오면 후보를 리셋하고, 직전 toolResult와 같은
toolUseId인 인접 결과만 텍스트·이미지를 append하며, 에러면 status를 error로 올립니다.call-a / call-b / call-a나 중간에 user 입력이 끼면 계속 거부합니다.tests/providers/kiro/kiro-adapter.test.ts에 순서·이미지·에러·비연속 거부 회귀를 넣었고, 라이브 스모크도 했다고 적었습니다. Ingwannu는 이 패치를 focused PR로dev에 제출하고, adjacency를 collapsed Kiro user turn이 아니라 원본 시퀀스 기준으로 유지하며, 어댑터/전송 문서에 짧은 노트를 남기라고 했습니다. 이전 템플릿 없는#3731후속입니다.우선순위 73인 이유다. Kiro+Codex exec/notify는 실사용 도구 경로이고, 재현·패치·메인테이너 확인이 끝났습니다.
#2819/#2835등 Kiro 종료·중복 답변 불변식과는 겹치되, 이번은 “한 call_id의 다중 결과 병합”이라 별 이슈로 두는 게 맞습니다. HEAD의kiro.ts에는 아직adjacentToolResultId가 없습니다.경로/심볼 -
src/adapters/kiro.tspushUser/validateKiroConversationState- 결과마다 tool use 1회 소비. 다중 인접 출력에서 실패경로/심볼 - 제안 패치
adjacentToolResultId- 원본 메시지 루프에서만 병합, user/assistant면 리셋경로 -
tests/providers/kiro/kiro-adapter.test.ts- 3인접→1결과, 이미지/에러, call-a/b/a, user 개입 거부경로/심볼 - 관련 닫힌
#3731(템플릿 없음). HEADaf344a28e에서 Ingwannu 재현 확인경로/심볼 - 에러 문구 -
Kiro tool result has no matching tool use "call_…"메인테이너의 판단이 필요한 지점
kiro어댑터 README/devlog 어디에 둘지너의 추천
Ingwannu 지시대로 회귀·문서 노트 포함한 집중 PR을
dev에 열어 주세요. 구현을 다른 작성자가 다시 짜지 말고 보고자 패치를 리뷰 트랙에 올리는 쪽이 맞습니다. 머지 후 이 이슈를 닫으면 됩니다.이 댓글은 grok-bot이 작성했습니다
Sfrui commentedon Sep 6, 2026
Hi @lidge-jun, I'd like to work on #3734 if nobody is already handling it.
My current understanding is that when a Codex exec call produces multiple outputs, the translated adapter emits duplicate
toolResultentries instead of preserving a single ordered result sequence.Before changing the implementation, I plan to:
I will keep authentication, provider configuration, and unrelated refactoring out of scope. Does this direction match the intended protocol behavior?
lidge-jun commentedon Sep 6, 2026
Fixed on dev by #3750 (merge c5ccd5d). Adjacent outputs now coalesce only for the same original call ID; collision, message-boundary and duplicate/orphan guards remain. Full hosted Linux/macOS/gates passed at 36d1e55: https://github.com/lidge-jun/opencodex/actions/runs/34017511752. Independent review passed. Verification used synthetic regression fixtures; available saved local metadata lacked a current reproduction, and no live Kiro request was made because quota was unavailable.