Hooks Mechanism
The Hooks system allows plugins to inject custom logic at key lifecycle events -- message interception, tool call wrapping, session management, audit logging, and more.
Available Hooks
Source: src/plugins/hooks.ts
Hook Reference
| Hook Name | Triggered When | Typical Use |
|---|---|---|
gateway-start | Gateway startup complete | Initialize external services |
gateway-stop | Before Gateway shutdown | Clean up resources |
session-start | Session begins | Load session context |
session-end | Session ends | Save session state |
before-agent-start | Before Agent execution | Inject context |
message-received | User message received | Message interception, filtering |
message-sending | Before sending a message | Message modification, auditing |
message-sent | After message sent successfully | Logging |
before-tool-call | Before tool execution | Permission checks, argument modification |
after-tool-call | After tool execution | Result processing, auditing |
before-compaction | Before context compaction | Preserve important information |
after-compaction | After context compaction | Restore state |
tool-result-persist | When tool results are persisted | Data archiving |
Hook Registration
typescript
// src/plugins/hooks.ts (simplified)
interface PluginHookRegistration<K extends PluginHookName> {
event: K; // Hook event name
handler: PluginHookHandler<K>; // Handler function
priority?: number; // Execution priority (lower = earlier)
}Plugins register hooks through the API:
typescript
// Example: audit logging hook
api.registerHook({
event: "message-sent",
handler: async (ctx) => {
await auditLog.record({
sessionKey: ctx.sessionKey,
channel: ctx.channel,
direction: ctx.direction,
timestamp: Date.now(),
});
},
priority: 100, // Run after other hooks
});Hook Context Types
Each hook type receives a different context:
Agent Context
typescript
interface PluginHookAgentContext {
runId: string; // Agent run ID
config: AgentConfig; // Agent configuration
workspaceDir: string; // Workspace directory
agentDir: string; // Agent directory
}Message Context
typescript
interface PluginHookMessageContext {
sessionKey: string; // Session key
channel: string; // Source channel
senderId: string; // Sender identifier
direction: "received" | "sending" | "sent"; // Message direction
}Tool Context
typescript
interface PluginHookToolContext {
runId: string; // Agent run ID
toolName: string; // Tool being called
// before: includes args
// after: includes result
}Session Context
typescript
interface PluginHookSessionContext {
sessionKey: string; // Session key
channel: string; // Channel
}Execution Model
Key execution characteristics:
| Characteristic | Description |
|---|---|
| Parallel execution | Multiple handlers for the same event run in parallel |
| Error isolation | A single handler throwing does not affect other handlers |
| Priority ordering | Lower numbers execute first |
| Fire-and-forget | Most hooks do not wait for results |
Gateway Hooks
Source: src/gateway/hooks.ts, src/gateway/hooks-mapping.ts
The Gateway layer has its own hooks mapping, which maps config-defined hook definitions to runtime registrations:
typescript
// src/gateway/hooks-mapping.ts (simplified)
// Maps config-defined hooks to runtime registrations
// Supports file-based hook definitions
// Validates hook event names and handler pathsSummary
- 13 hook events cover five lifecycles: Gateway, Session, Agent, Message, and Tool
- Hooks are sorted by priority, executed in parallel, with error isolation
- Four context types provide event-relevant data
- Plugins register hooks via
api.registerHook(), supporting dynamic addition - The Gateway layer additionally supports config-file-based hook definitions
Next: CLI Overview