Add agent_id/agent_type to tool-lifecycle hook inputs#628
Merged
qing-ant merged 1 commit intoanthropics:mainfrom Mar 3, 2026
Merged
Conversation
Surfaces the sub-agent attribution fields the CLI started sending in v2.1.64 (anthropics/claude-cli-internal#20180). When multiple Task sub-agents run in parallel, their PreToolUse/PostToolUse hooks interleave over the same control channel with nothing tying each callback to the sub-agent that fired it. agent_id is that correlation key — it matches the agent_id on that sub-agent's SubagentStart. Implemented as a _SubagentContextMixin rather than fields on BaseHookInput: SubagentStartHookInput/SubagentStopHookInput already declare these as required, and PEP 655 forbids narrowing NotRequired->Required in a TypedDict subclass. The mixin is applied to exactly the four tool-lifecycle types the CLI populates (PreToolUse, PostToolUse, PostToolUseFailure, PermissionRequest). CHANGELOG and CLI bump intentionally omitted: both are handled by the auto-release workflow, which keys on the exact bump-commit message. Including either here would either fail test_changelog.py or silently skip the 2.1.64 auto-release trigger.
50642ca to
0b527ca
Compare
wolffiex
approved these changes
Mar 3, 2026
qing-ant
approved these changes
Mar 3, 2026
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.
What
Surfaces the
agent_id/agent_typefields the CLI started sending in v2.1.64 (anthropics/claude-cli-internal#20180) on the four tool-lifecycle hook input types:PreToolUseHookInput,PostToolUseHookInput,PostToolUseFailureHookInput,PermissionRequestHookInput.Why
When the parent spawns multiple
Tasksub-agents in parallel, theirPreToolUse/PostToolUsehooks interleave over the same control channel with nothing tying each callback to the sub-agent that fired it:session_idandtranscript_pathare both parent-level and don't discriminate between sub-agents. Once more than one sub-agent is unblocked, there's no heuristic that can disambiguate — an older sub-agent might be writing its final response or about to fire a follow-up query; both states look identical from the hook stream.agent_idis the correlation key: it's the same value the CLI emits in that sub-agent'sSubagentStart/SubagentStop. For main-thread tool calls it's absent (check.get("agent_id") is None).Implementation note
The CLI puts these on
BaseHookInput, but doing that here would conflict withSubagentStartHookInput/SubagentStopHookInput, which already declareagent_id: stras required — PEP 655 forbids narrowingNotRequired→Requiredin a TypedDict subclass. So this uses atotal=Falsemixin applied to exactly the four hook types the CLI populates. Those are also the only callsites where the CLI has atoolUseContextin scope, so it's a wash semantically.Scope
Types only.
CHANGELOG.mdand_cli_version.pyare intentionally untouched: the auto-release workflow generates changelog entries and keys on the exactchore: bump bundled CLI version to X.Y.Zcommit message to trigger a release. Bundling the bump here would silently skip the 2.1.64 auto-release.The
NotRequiredfields are inert until the bundled CLI reaches 2.1.64 via the normal bump-commit flow, at which point both sides line up.Test plan
ruff check/ruff format— cleanmypy src/claude_agent_sdk/types.py— cleanpytest tests/— 246/246 pass (2 new)PreToolUseHookInputwithagent_idpresent (sub-agent) and absent (main thread) — both type-validPostToolUseHookInputwithagent_idpresent