#10383: feat(hooks): add agentId to hook mappings
gateway
stale
## Summary
- Add optional `agentId` field to hook mappings, allowing webhooks to route to a specific agent instead of always using the default agent
- `runCronIsolatedAgentTurn` already accepts `agentId` — this wires it through the full hook dispatch chain
- Supports Mustache templates (e.g. `{{payload.agent}}`) for dynamic routing
## Motivation
When running multiple agents with distinct roles (e.g. research, coding, ops), incoming webhooks always route to the default agent because `agentId` is never passed from hooks to `runCronIsolatedAgentTurn`. This forces workarounds like encoding agent IDs in session keys or patching the dispatch manually.
## Changes (6 files, 18 lines added)
1. `src/config/types.hooks.ts` — Add `agentId?: string` to `HookMappingConfig`
2. `src/config/zod-schema.hooks.ts` — Add `agentId: z.string().optional()` to Zod schema
3. `src/gateway/hooks-mapping.ts` — Thread `agentId` through `HookMappingResolved`, `HookAction`, `HookTransformResult`, `normalizeHookMapping`, `buildActionFromMapping`, `mergeAction`
4. `src/gateway/hooks.ts` — Add `agentId` to `HookAgentPayload` and `normalizeAgentPayload`
5. `src/gateway/server-http.ts` — Add `agentId` to `HookDispatchers` type and mapped dispatch call
6. `src/gateway/server/hooks.ts` — Pass `value.agentId` to `runCronIsolatedAgentTurn`
## Usage
```json
{
"hooks": {
"mappings": [
{
"match": { "path": "notify" },
"action": "agent",
"agentId": "{{payload.agent}}",
"messageTemplate": "{{payload.message}}"
}
]
}
}
```
## Test plan
- [ ] Verify hook mapping with static `agentId` routes to the correct agent
- [ ] Verify hook mapping with template `agentId` (e.g. `{{payload.agent}}`) resolves dynamically
- [ ] Verify omitting `agentId` falls back to default agent (backward compatible)
- [ ] Verify transform overrides work with `agentId`
🤖 Generated with [Claude Code](https://claude.com/claude-code)
<!-- greptile_comment -->
<h2>Greptile Overview</h2>
<h3>Greptile Summary</h3>
- Extends hook mapping config/schema to accept an optional `agentId` string.
- Threads `agentId` through hook mapping resolution/templating, agent payload normalization, and HTTP hook dispatch.
- Updates gateway hook server to pass `agentId` into `runCronIsolatedAgentTurn`, enabling per-hook agent routing (static or template-rendered).
<h3>Confidence Score: 4/5</h3>
- Mostly safe to merge, but there is a real config validation inconsistency to fix first.
- The `agentId` threading is straightforward and stays optional end-to-end, but the hook mapping Zod schema’s `channel` union is now more likely to reject a valid `googlechat` value that the TS config types allow, causing runtime config load failures for users with that mapping.
- src/config/zod-schema.hooks.ts
<!-- greptile_other_comments_section -->
<sub>(2/5) Greptile learns from your feedback when you react with thumbs up/down!</sub>
<!-- /greptile_comment -->
Most Similar PRs
#10663: feat(hooks): add agentId support for webhook routing
by nityatrish · 2026-02-06
93.8%
#9800: feat(hooks): allow webhook mappings to route to specific agents via a…
by bogdanClawdy · 2026-02-05
90.7%
#7846: feat: add agentId param to webhook agent endpoint
by Bre77 · 2026-02-03
81.2%
#7301: fix(hooks): use resolveAgentIdFromSessionKey instead of split(":")[0]
by tsukhani · 2026-02-02
80.9%
#19565: feat: add agent lifecycle hook events (session, message, error)
by tag-assistant · 2026-02-17
75.7%
#12635: Gateway: add inbound webhook dispatch framework
by jhs129 · 2026-02-09
74.7%
#6630: feat(hooks): add agent:turn_start and agent:turn_end lifecycle events
by drdigital13 · 2026-02-01
74.6%
#7771: Hooks: wire lifecycle events and tests
by rabsef-bicrym · 2026-02-03
74.2%
#8855: feat(hooks): add configurable compliance logging plugin
by 100menotu001 · 2026-02-04
73.9%
#19177: fix: use parseAgentSessionKey instead of fragile split pattern
by El-Patronum · 2026-02-17
73.5%