Repository navigation
feat(hooks): include tool_use_id in PreToolUse and PostToolUse hook input - #6217
Open
xxwtiancai wants to merge 1 commit into
Open
xxwtiancai wants to merge 1 commit into
xxwtiancai wants to merge 1 commit into
Conversation
…nput Tool hooks received the tool name, input and response but nothing identifying the tool call itself, so a hook watching two identical calls (parallel or retried) could not pair a call with its result. The Claude Code hook contract this module follows carries tool_use_id for exactly that. Add an optional tool_use_id to HookEvent, populated from the ActionEvent's tool_call_id for PreToolUse and the paired ObservationEvent's tool_call_id for PostToolUse, so both hooks for one call see the same value; non-tool hook events leave it null. The field reaches command hooks through the existing stdin JSON and prompt/agent hooks through the existing serialized event, and the run_pre_tool_use/run_post_tool_use keyword argument is optional, so existing callers and scripts keep working. The TypeScript client HookEvent mirror and the hooks example README document the field. Closes OpenHands#6214 Co-authored-by: openhands <openhands@all-hands.dev>
xxwtiancai
marked this pull request as ready for review
October 25, 2026 09:03
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.
HUMAN:
Summary
Add
tool_use_idtoHookEventfor Pre/PostToolUse hooks, enabling consumers to pair tool invocations with results during parallel execution and retries while aligning with Claude Code hook compatibility.Problem
PreToolUseandPostToolUsehooks lacked a unique identifier for tool executions. During concurrent calls or retry attempts, audit, logging, and policy hooks could not correlate actions with their matching observations. Additionally, this missing field diverged from Claude Code's hook format, which exposestool_use_id.Changes
tool_use_idtoHookEvent(Prepulls fromActionEvent.tool_call_id,Postpulls the matching ID fromObservationEvent).Verification
null, and ensured backward compatibility with older hook invocations.tests/sdk/hookspassed (153 passed); TS suite passed (394 passed).AGENT:
Why
PreToolUseandPostToolUsehooks receive the tool name, its input and (forPostToolUse) its response, but nothing that identifies the tool call itself. When the agent runs the same tool twice with the same input — parallel tool calls or a retried command — a hook that sees both events cannot tell which result belongs to which call, which breaks audit, logging, and policy hooks that want to record a call and its result as one entry. The hooks contract documents Claude Code compatibility, and Claude Code's hook input includestool_use_idfor exactly this.Summary
HookEventgains an optionaltool_use_idfield (openhands/sdk/hooks/types.py): theActionEvent.tool_call_idforPreToolUseand the pairedObservationEvent.tool_call_idforPostToolUse, so both hooks for one call see the same value;UserPromptSubmit/SessionStart/SessionEnd/Stopleave itnull.HookManager.run_pre_tool_use/run_post_tool_useaccept an optional keyword-onlytool_use_id;HookEventProcessorpasses the event'stool_call_idfrom both_handle_pre_tool_useand_handle_post_tool_use. The field reaches command hooks through the existing stdin JSON and prompt/agent hooks through the existing serialized event — no separate plumbing.clients/typescript/src/hooks/types.tsmirrors the same optionaltool_use_idon theHookEventinterface.examples/01_standalone_sdk/33_hooks/README.mddocuments the field in a new "Hook Input" section.Issue Number
Closes #6214
How to Test
New tests in
tests/sdk/hooks/test_tool_use_id.pyexercise the real execution path: a command hook writes its stdin JSON to a file forPreToolUseandPostToolUse, and the test asserts both carry the sametool_use_id(call-abc-123) for one paired action/observation; aUserPromptSubmithook assertstool_use_idarrives asnull; and a directrun_pre_tool_usecall without the new argument asserts existing callers keep working. Fulltests/sdk/hookssuite passes (153 tests) and the TypeScript client builds with all 394 tests passing.Video/Screenshots
Not a visual change.
Design Doc
Single additive field following the existing HookEvent shape; no design doc added.
Type
Notes
tool_use_idwas chosen overtool_call_idto match the Claude Code hook contract naming the module already claims to follow.