Repository navigation
fix(ai): honor Kiro model selection and group parallel tool results (#6166) - #6169
Conversation
…eachan-Heo#6166) - Set userInputMessage.origin=AI_EDITOR; without it CodeWhisperer ignores modelId and routes every request to auto. - Send every trailing result of a parallel tool batch in currentMessage; splitting them across history and currentMessage is rejected with TOOL_USE_RESULT_MISMATCH (HTTP 400).
probepark
left a comment
There was a problem hiding this comment.
Review (head b21e1af, gajae-reviewer on behalf of probepark)
CI: green — all non-skipped checks passed; approve gate ALLOW at this head.
Scope: +178 / -3, 3 files — packages/ai provider, request-body regression tests, changelog fragment.
Conventions: CHANGELOG fragment present, generated files none, labels none.
Notable:
packages/ai/src/providers/kiro-codewhisperer.ts:395-435— checked trailing parallel tool-result grouping and current-message serialization; all trailing results are kept together and earlier completed batches remain grouped in history.packages/ai/src/providers/kiro-codewhisperer.ts:503-508— checked that every user wire message carries the requiredAI_EDITORorigin alongside the model ID.
Blocking: none
Verdict: gaja.pr-review-verdict.v1 merge-approved sha256:44012aac2ff54034cb5362e9a261cc94b5df9061790a8e5cdc84650da4154ab2 reviewer:human reviewer-id:probepark evidence:ci-green;approve-gate-allow;parallel-results-grouped;origin-covered;changelog-fragment;generated-files-none
snowykr
left a comment
There was a problem hiding this comment.
Verdict
APPROVED
Summary
The OAuth CodeWhisperer serializer now sets AI_EDITOR on every user-input message and keeps the entire trailing parallel tool-result batch in currentMessage, rather than splitting it across history and the current turn. The change is appropriately scoped and preserves completed historical batches, tool-result IDs, and the separate API-key transport. Complementary review subagents completed all five axes; no attributable merge-blocking defect was established.
Reviewed head: b21e1af8595ab23e8ddf5efeaa5b786267db7d0e. Base and merge-base: 467f6c1d39e506aeca8366c4baf6ee0639e82fac.
Findings / Required Changes
No blocking or actionable findings.
Non-blocking Observations
The affected-test planner's existing exact-basename matching does not associate a future provider-only edit with the new suffixed kiro-codewhisperer-request-body.test.ts suite. An explicit behavioral-owner mapping would improve future regression coverage. This is an optional improvement, not a defect in this PR's verification: the changed test file selected itself and its exact-head CI job succeeded.
CI / Verification
Dev CI run 36717747139 completed successfully for the exact reviewed head. Authenticated GitHub API results show 18 successful checks, seven skipped checks, and no failures. Relevant successes include the direct request-body test, check:@gajae-code/ai, and the final Affected path validation aggregate. The planner, required-task evidence validation, and aggregate handling were inspected; skipped checks are not counted as test evidence.
The new mocked-fetch tests inspect outgoing JSON, asserting origin and normalized model ID across user entries, all three trailing result IDs in the current message, and preservation of an earlier completed batch. Existing tool-history tests were inspected, but their inspection is not a claim that the full AI suite ran. No PR code or tests were executed locally. The successful conditional virtual-integration wrapper is not Kiro-specific integration evidence.
Axis Coverage
| Axis | Verdict | Coverage |
|---|---|---|
| A1 — Intent / Policy / Contract | APPROVED | Compared declared OAuth-only scope with pinned diff, private wire contract, model catalog and changelog policy; no separate intent projection was available. |
| A2 — Architecture / Correctness / Failure | APPROVED | Traced contiguous agent result production, completion ordering, per-record emission guards, ID-based wire association, history/current partition, and unchanged error propagation. |
| A3 — Security / Privacy / Trust | APPROVED | Checked fixed origin, unchanged payload contents and recipient, region validation/redirect rejection, and downstream active-tool/argument/policy checks; no new authority boundary crossing established. |
| A4 — Verification / Tests / CI | APPROVED | Inspected observable request-body assertions and exact-head CI selection/results through final aggregate validation; optional future selection improvement noted above. |
| A5 — Context / Compatibility / Platform | APPROVED | Traced built-in dispatch and separate API-key route, public exports, generated catalog and release packaging. Existing converters/normalizer are reused; no materially preferable shared serializer was identified. |
Limitations
This was a static, read-only review supplemented by exact-head CI metadata and public job pages. CI job logs and artifact contents were not inspected. Mocked request-body tests demonstrate serialization, not Kiro's server-side model selection or acceptance; the PR's reported live-service experiments were not independently reproduced. No defect is inferred for the distinct API-key endpoint solely from similar serialization code.
…6166) (#6169) - Set userInputMessage.origin=AI_EDITOR; without it CodeWhisperer ignores modelId and routes every request to auto. - Send every trailing result of a parallel tool batch in currentMessage; splitting them across history and currentMessage is rejected with TOOL_USE_RESULT_MISMATCH (HTTP 400).
What
Two request-body fixes in the Kiro OAuth CodeWhisperer transport (
packages/ai/src/providers/kiro-codewhisperer.ts), findings 1 and 2 of #6166:userInputMessage.origin: "AI_EDITOR"on every user message.currentMessage.userInputMessageContext.toolResultsinstead of leaving the earlier ones as a separate history entry.Scoped per the maintainer note on #6166: no hunks from #6159 (non-eventstream 200 body, #6158) or #6165 (target / content-type / tools wrapper / event parsing, #6164). The diff only touches the user-message shape, the history/current split, and the
origintype.Why
Both verified against the live service with a Kiro Power (Google login) OAuth bearer:
modelId— every response frame reportsmodelId: "auto". Withorigin: "AI_EDITOR"the frames report the requested model (e.g.claude-haiku-4.5). So selectingkiro/claude-opus-5.5currently has no effect.messages.4: tool_use ids were found without tool_result blocks immediately after: … (TOOL_USE_RESULT_MISMATCH). The transport put only the lasttoolResultincurrentMessage. Replaying a captured session with 8 parallel results succeeded after this change.Refs #6166.
Testing
packages/ai/test/kiro-codewhisperer-request-body.test.ts(request-body capture, no network):sets origin on every user message so modelId is honored— fails ondevwithout the fix, passes with it.sends every trailing parallel tool result in currentMessage— fails ondevwithout the fix, passes with it.keeps an earlier completed parallel batch grouped in history— regression guard for the existing history grouping (passes before and after).bun test test/kiro-*.test.ts test/aws-region-credential-destination.test.ts→ 106 pass, 0 fail.packages/ai:bun run check(biome + tsc) passes.Approval
Merges to
devrequire one approving GitHub review from a write-access maintainer on the current head. Agent reviews (architect/critic) are advisory comments.devbun checkpasses (packages/ai)packages/ai/changelog.d/