Skip to content

Preserve input attribution and expose command lifecycle events - #1358

Open
tanm22 wants to merge 1 commit into
anthropics:mainfrom
tanm22:fix/user-message-attribution-lifecycle
Open

tanm22 wants to merge 1 commit into
anthropics:mainfrom
tanm22:fix/user-message-attribution-lifecycle

Conversation

@tanm22

@tanm22 tanm22 commented Oct 6, 2026

Copy link
Copy Markdown

The CLI emits input-attribution metadata and top-level command_lifecycle frames, but Python currently discards both. Hosts that queue multiple prompts cannot reliably correlate replies with submitted inputs or observe each input's lifecycle through the public message iterators.

This preserves user_message_uuid and user_message_uuids on assistant messages, stream events, and results, plus queued_turn_count on results. The fields are optional and appended to the existing dataclasses so older CLI output and positional constructors remain compatible.

It also adds a public CommandLifecycleMessage for the CLI's command_uuid, state, uuid, and session_id fields. States remain open strings so future lifecycle states pass through. Both public streaming APIs deliver these messages, including completion after a result. receive_response() still stops at ResultMessage; the docs explain when callers should continuously consume receive_messages() instead.

The attribution portion overlaps #1271. This PR also addresses the dropped lifecycle frames reported in the newer comment on #1270. Regression tests cover exact message types, absent and merged attribution, zero queue counts, all existing constructor positions, caller UUID serialization, future lifecycle states, and delivery before and after results. The docs explain that the producer's 64-entry attribution list can be incomplete and that queued sends do not correspond one-to-one with results.

Closes #1270.

Validation

  • Focused parser, query, and client tests: 227 passed, with the new async tests covering asyncio and trio.
  • Standard test configuration: 1,625 passed and 6 optional skips with both MCP 2.3.0 and the supported 1.23.0 floor.
  • With optional dependencies and local PostgreSQL, Redis, and S3-compatible services enabled: 1,706 passed, no skips, and 4 PostgreSQL fixture setup errors in both configurations. The same errors reproduce against untouched upstream source. Two synchronous tests request async fixtures without AnyIO handling, and later fixture setup errors follow. The three async PostgreSQL tests pass independently. No unrelated fixture changes are included here.
  • A live CLI 2.1.291 /help probe delivered queued, started, and completed with matching wire fields, including completion after ResultMessage. The same probe against upstream delivered no lifecycle messages. This required no model API calls.
  • Ruff lint, formatting, mypy, and git diff --check passed. The separate real Claude API test suite was not run because API credentials were unavailable.

@tanm22

tanm22 commented Oct 6, 2026

Copy link
Copy Markdown
Author

@ashwin-ant @qing-ant, could you take a look when you have a chance? This addresses #1270 by preserving input attribution and exposing command lifecycle events. Thanks!

@sigley sigley left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Validated exact head bfb99e6. The focused parser/query/client slice passes 227 tests, compileall is clean, and the current main drift is limited to release/CI/version files. I also checked the older #1271 overlap: this PR carries that attribution subset forward while adding the previously dropped command_lifecycle frames and preserving existing positional constructors. I do not see a blocking correctness or mergeability issue.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Python SDK parity: expose user-message attribution and queued-turn fields

2 participants