Skip to content

feat: add HooksManager lifecycle hook system to callModel#7

Open
mattapperson wants to merge 3 commits intomainfrom
feat/hooks-manager
Open

feat: add HooksManager lifecycle hook system to callModel#7
mattapperson wants to merge 3 commits intomainfrom
feat/hooks-manager

Conversation

@mattapperson
Copy link
Copy Markdown
Collaborator

Summary

  • Adds an extensible hook system for callModel inspired by the Claude Agent SDK hooks pattern
  • Two usage modes: inline config (plain object for quick setup) and HooksManager class (custom hooks, dynamic registration, programmatic emit)
  • 8 built-in hooks: PreToolUse, PostToolUse, PostToolUseFailure, UserPromptSubmit, Stop, PermissionRequest, SessionStart, SessionEnd
  • Features: tool matchers (string/RegExp/function), filter predicates, mutation piping, short-circuit on block/reject, async fire-and-forget handlers, configurable error handling
  • Custom hook definitions via Zod schema pairs with full TypeScript autocomplete
  • Additive API — existing onTurnStart, onTurnEnd, requireApproval remain unchanged

Re-creation of OpenRouterTeam/openrouter-web#16735 on the standalone agent SDK repo.

Test plan

  • 35 new unit tests across 4 test files (matchers, emit engine, manager class, resolver)
  • All 186 unit tests pass
  • Build (pnpm build) passes cleanly
  • Lint (pnpm lint) passes cleanly
  • E2E testing with real API calls (PreToolUse block, mutation piping, Stop forceResume)

Implements an extensible hook system for callModel inspired by the
Claude Agent SDK hooks pattern. Supports inline config for quick
declarative usage and a HooksManager class for custom hooks,
dynamic registration, and programmatic emit.

Built-in hooks: PreToolUse, PostToolUse, PostToolUseFailure,
UserPromptSubmit, Stop, PermissionRequest, SessionStart, SessionEnd.

Features: tool matchers (string/RegExp/function), filter predicates,
mutation piping, short-circuit on block/reject, async fire-and-forget
handlers, configurable error handling, and custom hook definitions
via Zod schema pairs.
81 edge-case tests covering handler chain execution, manager lifecycle,
tool matchers, resolver normalization, and async output detection.
Surfaces real issues: filter throws bypass error handling, global RegExp
stateful .test(), and function matcher lacking boolean coercion.
test: add adversarial unit tests for hooks system
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.

1 participant