Skip to content

feat(hooks): populate agent_name on tool-use hook events#3110

Open
t-mizumoto1203 wants to merge 1 commit into
docker:mainfrom
t-mizumoto1203:feat/tool-hooks-agent-name
Open

feat(hooks): populate agent_name on tool-use hook events#3110
t-mizumoto1203 wants to merge 1 commit into
docker:mainfrom
t-mizumoto1203:feat/tool-hooks-agent-name

Conversation

@t-mizumoto1203

@t-mizumoto1203 t-mizumoto1203 commented Jun 14, 2026

Copy link
Copy Markdown
Contributor

What

Tool-use hook events (pre_tool_use / post_tool_use) now carry
agent_name in their hooks.Input, matching every other event type.

Fixes #3109.

Why

hooks.Input.AgentName exists and is documented as "identifies the agent
dispatching the event", and session / turn / before|after_llm_call /
on_agent_switch events all set it. But tool events build their Input via
toolexec.NewHooksInput, which receives no agent, so agent_name shipped
empty — even though the shared dispatchHook path already has the agent.
This blocks any pre_tool_use consumer (auditing, per-agent rate limits,
external policy engines) from knowing which agent issued a tool call.

How

Auto-fill AgentName in dispatchHook (the shared path that already
receives the agent), only when it is empty so explicit caller values win,
mirroring how Executor.Dispatch auto-fills Cwd. The field is omitempty,
so this is backward compatible, and it covers both pre_tool_use and
post_tool_use (both flow through the same path).

Semantics: agent_name = the agent that directly issues the tool call
(a.Name()); on transfer/handoff it follows the active sub-agent.

Testing

  • go test ./pkg/runtime/... — added TestPreToolUseHook_ReceivesAgentName;
    all pre_tool_use hook tests pass.
  • go build ./..., go vet ./pkg/runtime/..., gofmt — clean.
  • End-to-end on a real agent run with a pre_tool_use hook dumping its stdin:
    • single agent: {"agent_name":"root","tool_name":"think"}
    • multi-agent (root delegates to a sub-agent via transfer_task):
      {"agent_name":"root",   "tool_name":"think"}
      {"agent_name":"root",   "tool_name":"transfer_task"}
      {"agent_name":"worker", "tool_name":"think"}
      
      confirming agent_name follows the active agent across delegation.

Tool events (pre/post_tool_use) build their hooks.Input via
toolexec.NewHooksInput, which has no agent reference, so they shipped an
empty agent_name while every other event sets it explicitly. Auto-fill
AgentName in the shared dispatchHook path (which already receives the
agent), mirroring how Executor.Dispatch auto-fills Cwd. Caller-set values
still win, and the field is omitempty, so the change is backward compatible.

This lets pre_tool_use hooks and external policy engines see which agent
issued a tool call (per-agent governance / auditing).

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: kiriha1203 <mizumoto.takefumi@gmail.com>
@t-mizumoto1203 t-mizumoto1203 requested a review from a team as a code owner June 14, 2026 02:34
@aheritier aheritier added area/agent For work that has to do with the general agent loop/agentic features of the app area/tools For features/issues/fixes related to the usage of built-in and MCP tools kind/feat PR adds a new feature (maps to feat: commit prefix) labels Jun 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/agent For work that has to do with the general agent loop/agentic features of the app area/tools For features/issues/fixes related to the usage of built-in and MCP tools kind/feat PR adds a new feature (maps to feat: commit prefix)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Tool-use hook events omit agent_name that other event types populate

2 participants