fix: preserve wire fields in parse_message via data field#1061
Open
itxaiohanglover wants to merge 1 commit into
Open
fix: preserve wire fields in parse_message via data field#1061itxaiohanglover wants to merge 1 commit into
itxaiohanglover wants to merge 1 commit into
Conversation
Add `data: dict[str, Any] | None = None` to AssistantMessage and ResultMessage, mirroring the existing SystemMessage.data pattern. The parser now passes the raw frame dict as `data=data`, so newer CLI wire fields (ttft_ms, terminal_reason, fast_mode_state, stop_details, diagnostics, context_management, caller, request_id) are reachable before they are explicitly modeled. Fixes anthropics#1026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
parse_message()silently drops newer CLI wire fields likettft_ms,terminal_reason,fast_mode_state,stop_details,diagnostics,context_management,caller, andrequest_id. UnlikeSystemMessage(which keeps the raw frame as.data),AssistantMessageandResultMessagedon't retain the original frame, so SDK consumers cannot access these fields at all without bypassing the SDK and re-parsing the wire themselves.This implements option 2 from the issue: add a
data: dict[str, Any] | None = Nonefield to bothAssistantMessageandResultMessage(matching theSystemMessage.datapattern), then passdata=datain the parser. This is a forward-compatible escape hatch so new CLI fields are reachable before they're explicitly modeled.Changes
types.py: Addeddata: dict[str, Any] | None = Nonefield toAssistantMessageandResultMessagedataclasses (defaults toNonefor manually constructed messages, so existing code is unaffected).message_parser.py: Passdata=data(the raw message dict) when constructingAssistantMessageandResultMessage.test_message_parser.py: Added 5 tests verifying that unmodeled wire fields survive parsing on both message types, thatdatadefaults toNonefor manual construction, and that per-content-blockcalleris reachable viadata.Fixes #1026
Test plan
ruff checkpassesruff format --checkpassesmypy src/passes (strict mode, 0 issues)pytest tests/ -v— 755 passed, 5 skippedttft_ms,terminal_reason,fast_mode_state,stop_details,diagnostics,context_management,caller, andrequest_idare all reachable via.datadatafield defaults toNone— backward compatible with existingAssistantMessage(...)/ResultMessage(...)construction