anthropics / anthropics/claude-agent-sdk-python
Hook/progress messages corrupt parentUuid chain causing one-message delay
- Ngôn ngữ chính
- Python
- Star
- 8.1k
- Fork
- 1.3k
- Merge trung bình
- 2 ngày 31 phút
- Pull request đã merge (30 ngày)
- 1
Mô tả
## Bug Description
When using `ClaudeSDKClient` for multi-turn conversations, the SDK's JSONL transcript writer assigns `parentUuid` based on a rolling "last UUID" cursor that advances for **every** message type, including `hook_progress` and `stop_hook_summary` system events. This causes the next user message to be parented to a hook/progress entry instead of the assistant's response, breaking the conversation chain.
## Observed Behavior
User messages get parented to `hook_progress` system messages instead of assistant responses, causing Claude to effectively "miss" a message. The user must send an additional message to get the response they expected from the previous one — a "one-message delay" effect.
## JSONL Evidence
From a real session transcript:
```
21:59:47.801Z | assistant (uuid=5a5caa75, parent=01df9ff2) ← Normal response
22:00:32.409Z | progress/hook_progress (uuid=187ee328, parent=5a5caa75) ← SDK hook runs AFTER turn
22:00:37.631Z | user (uuid=a6d699bb, parent=187ee328) ← WRONG: parented to hook, not assistant
```
The user message at `22:00:37` should have `parentUuid=5a5caa75` (the assistant response), but instead gets `parentUuid=187ee328` (a `SessionStart:resume` hook_progress event that the SDK wrote between turns).
## Root Cause
Investigated with both Claude and OpenAI Codex independently — both reached the same conclusion:
The bundled CLI's `insertMessageChain(...)` assigns `parentUuid` from a rolling prior UUID and advances that cursor for every message, including hook/progress events. When hooks run after `ResultMessage` (stop hooks, session start hooks on resume, etc.), they become the "last message" in the chain, and the next user query gets parented to the hook instead of the assistant response.
This is an SDK/CLI persistence issue, **not** a consumer-side issue — the bridge cannot fix this by draining hook messages from the stream, because `parentUuid` is already assigned when the entry is written to JSONL.
## Expected Behavior
Hook/progress/system messages should not advance the conversational parent cursor. The SDK should track a `last_conversation_uuid` (assistant/user messages only) separately from the raw event ordering, and use that for parenting new user messages.
## Reproduction
1. Use `ClaudeSDKClient` for a multi-turn conversation
2. Send a query that triggers hooks (e.g., any query on a session with `SessionStart` hooks)
3. After the response completes and hooks run, send another query
4. Inspect the JSONL — the second user message will be parented to the hook instead of the assistant response
## Environment
- `claude-agent-sdk` 0.1.27 (also confirmed on 0.1.35)
- Python 3.14.2 (Homebrew)
- macOS
Hướng dẫn đóng góp
Chưa lập chỉ mục được hướng dẫn đóng góp cho kho mã nguồn này
Đánh giá
Issue này chưa được đánh giá.