Skip to content

[Improvement]: hooks: lifecycle hooks for tool execution (beforeToolCall / afterToolCall) #9

@Arry8

Description

@Arry8

Summary

Add beforeToolCall and afterToolCall lifecycle hooks to the agent tool execution path, allowing user scripts to enforce tool policies, audit tool usage, or abort specific tool calls.

Problem

Agent tool calls (Bash, Read, Write, web search, etc.) execute with no user-configurable interception. There is no config-driven way to: block specific tools by name or pattern, log tool inputs/outputs to an audit trail, enforce tool-level rate limits, or alert on high-cost or sensitive tool calls.

Acceptance criteria

  • beforeToolCall hook fires before a tool executes; returning { abort: true } skips the call and returns an error result to the agent
  • afterToolCall hook fires after tool completion with tool name, input, output summary, duration, and status
  • Hooks are configurable via openclaw.json with filter.tool (tool name allowlist/denylist) support
  • Hook failures are logged but never crash the agent
  • Unit tests cover: abort by tool name, pass-through, error isolation, tool name filter

Implementation plan

  1. Locate the tool dispatch point — src/agents/pi-tool-definition-adapter.ts (wraps tool calls) already has before-tool-call internal hooks; evaluate extending vs. adding alongside
  2. Add user-script hook calls before and after tool.run() in the adapter
  3. Re-use runCronHooks / loadHookEntries with workflow: 'tool'
  4. Add ToolHooksConfig type with optional filter.tool: string[] field
  5. Add Zod schema and config loading
  6. Add unit tests

Files affected

  • src/cron/hooks.ts (reuse — may need filter.tool added to CronHookEntry)
  • src/config/types.hooks.ts (add ToolHooksConfig)
  • src/config/zod-schema.ts (Zod schema)
  • src/agents/pi-tool-definition-adapter.ts (wire hook call sites)
  • src/agents/pi-tool-definition-adapter.hooks.test.ts (new — tests)

Additional notes

  • src/agents/pi-tools.before-tool-call.ts already implements an internal before-tool-call hook (used for tool loop detection and param adjustment). This is a separate, user-configurable layer — do not replace the internal hook
  • Implement last of the four: most granular, highest call frequency, needs careful performance consideration (hook overhead per tool call)
  • ctx should include: toolName, toolInput (sanitized), agentId, sessionKey, meta bag
  • May require adding filter.tool to the shared CronHookEntry / HookEntry type

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions