fix(server): key AskUserQuestion answers by question text#2404
fix(server): key AskUserQuestion answers by question text#2404juliusmarminge merged 2 commits intopingdotgg:mainfrom
Conversation
Claude SDK >= 2.1.121 changed `mapToolResultToToolResultBlockParam` to look up `AskUserQuestion` answers by the full question text. T3 was setting `UserInputQuestion.id` to `header`, so the UI's draft key (and therefore the answers record returned to the SDK) was the header instead of the question text. Every lookup missed and the model received an empty interpolation in `tool_result`. Use the full question text as the parsed `id` so the entire chain (UI drafts -> server -> SDK) keys answers consistently with what the SDK now expects. Fixes pingdotgg#2388
…1.121 Render the adapter's `updatedInput.answers` payload through both Claude SDK iteration patterns we have observed in the wild: - 2.1.119 used a key-agnostic `Object.entries(answers)` map, so any key produced a non-empty `tool_result`. - 2.1.121 looks up `answers[question]` by full question text — keys that don't match are dropped, which is what caused pingdotgg#2388. Asserting both renderings stay non-empty locks in the keying contract on either side of the regression so we don't quietly break older CLIs or re-introduce the original bug. Refs pingdotgg#2388
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
ApprovabilityVerdict: Approved Straightforward bug fix that changes answer key lookup from header to question text to match Claude SDK 2.1.121 expectations. Single line production change with comprehensive regression tests documenting compatibility with multiple SDK versions. You can customize Macroscope's approvability policy. Learn more. |
What Changed
UserInputQuestion.id(parsed inClaudeAdapter.handleAskUserQuestion) is now derived from the fullquestiontext instead ofheader. The web UI keys its draft answers byquestion.id, so the answers record returned to the SDK inupdatedInput.answersis now keyed by question text, exactly what Claude SDK ≥ 2.1.121 looks up.headerstays UI-display only.A regression assertion in the existing
"handles AskUserQuestion via user-input.requested/resolved lifecycle"test renders the adapter'supdatedInput.answersthrough both SDK iteration patterns (2.1.119's key-agnosticObject.entriesand 2.1.121'sanswers[question]lookup) and asserts both produce a non-emptytool_result, locking the keying contract on either side of the regression.Why
Fixes #2388.
Between Claude CLI 2.1.119 and 2.1.121 the SDK's
mapToolResultToToolResultBlockParamforAskUserQuestionswitched from a key-agnosticObject.entries(answers)map to a lookup by full question text:T3 was submitting
answerskeyed byheader(e.g."Approach"), not by the fullquestiontext (e.g."Which approach do you prefer?"). Under 2.1.121 every lookup missed, every entry was filtered out, and the model received an empty interpolation:Keying by question text is also what the documented
outputSchemashape calls for, so this aligns T3 with the spec rather than relying on the older SDK's lax behavior. The change is backwards compatible with 2.1.119, itsObject.entriesiteration accepts any key, so older CLI users keep working (and now see semantically richer rendered answers, e.g."Which approach?"="Option A"instead of"Approach"="Option A").idinUserInputQuestionisTrimmedNonEmptyStringSchemawith no length cap and is only used as aRecord<string, …>key inpendingUserInput.tsandsession-logic.ts, never as a URL/route key, so widening it to the full question text is safe.Checklist
Note
Key
AskUserQuestionanswers by full question text instead of headeridfield of eachUserInputQuestionis now set to the full question text (falling back toq-<idx>if empty) rather thanq.header.idvalues in emitteduser-input.requestedpayloads will differ from previous behavior, so any consumers keying answers by the old header-derived id will need to update.Macroscope summarized 1d6d905.