Skip to content

fix(hooks): match tool hooks against the model-facing Agent name#3236

Open
abhay-codes07 wants to merge 1 commit into
letta-ai:mainfrom
abhay-codes07:fix/agent-tool-hook-matching
Open

fix(hooks): match tool hooks against the model-facing Agent name#3236
abhay-codes07 wants to merge 1 commit into
letta-ai:mainfrom
abhay-codes07:fix/agent-tool-hook-matching

Conversation

@abhay-codes07

Copy link
Copy Markdown
Contributor

Summary

  • PreToolUse/PostToolUse/PostToolUseFailure hooks for built-in tools were matched against the internal tool name, but the subagent tool executes internally as Task while users, the docs, and the model all see it as Agent. A hook registered with matcher "Agent" therefore never fired for subagent dispatches (server-executed tools already matched on the model-facing name, so the two paths disagreed).
  • The tool manager now passes both names to the hook runners: matchers fire on either the model-facing name or the internal name — so existing "Task" matchers keep working — and hook payloads report the model-facing name as tool_name. This also covers the Gemini toolset mappings (e.g. matcher glob now matches internal glob_gemini).
  • Documented the Agent matcher in the hooks reference.

Fixes #3150.

Test plan

  • bun test src/hooks/ — new loader tests for alias matching (fail without the fix) and integration tests asserting an Agent matcher fires for a ["Agent", "Task"] call with tool_name: "Agent" in the payload, plus legacy Task matcher compatibility
  • bun run check
  • Full unit suite — no new failures vs a clean main baseline on the same machine
  • Manually verified on Windows (integration suite is skipped there): a .letta/settings.json PreToolUse hook with matcher Agent executes 0 times with the old call shape and once with the new one

AI disclosure

Following the policy proposed in #3139: this PR was developed with AI assistance (Claude Code) — the investigation, patch, and tests were AI-assisted. I directed the work, reviewed the change, and ran the validation above locally.

cc @jnjpng — you seem closest to src/hooks/; happy to adjust if you'd prefer the payload to keep reporting the internal name.

PreToolUse/PostToolUse hooks for built-in tools were matched against the
internal tool name, but the subagent tool executes internally as Task
while users, docs, and the model all see it as Agent. A hook registered
with matcher "Agent" therefore never fired for subagent dispatches.

Pass both names to the tool hook runners: matchers now fire on either
the model-facing name or the internal name (so existing "Task"
matchers keep working), and hook payloads report the model-facing name
as tool_name.

Fixes letta-ai#3150
Copilot AI review requested due to automatic review settings July 6, 2026 15:40

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

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.

PreToolUse hooks do not fire for Agent (Task) tool calls

2 participants