#20053: feat(voicewake): trigger-based routing to agent/session
docs
app: macos
app: web-ui
gateway
scripts
size: L
Cluster:
Memory Leak Fixes and Cleanup
Clean replacement for #17994 (which was auto-closed as dirty after an upstream merge).\n\nIncludes:\n- voiceWakeTrigger routing config + gateway methods\n- session/agent route resolution + validation for known agents\n- protocol model sync + tests for routing behavior\n- macOS forwarding integration and docs\n\nAlso carries the prior CI stabilization tweak in scripts/test-parallel.mjs (2 workers on macOS).
<!-- greptile_comment -->
<h3>Greptile Summary</h3>
This PR adds trigger-based voice wake routing, allowing different wake words to route messages to specific agents or sessions. The implementation spans the full stack: Swift wake-word detection (`WakeWordGate`, `VoiceWakeRuntime`, `VoiceWakeForwarder`), the gateway protocol and RPC layer (`voicewake.routing.get/set`), infra storage with normalization (`voicewake-routing.ts`), and the agent handler's route resolution logic.
- **Routing config store**: New `VoiceWakeRoutingConfig` type with `defaultTarget` and per-trigger `routes`, persisted to `settings/voicewake-routing.json`. Normalization handles whitespace collapsing, empty-trigger filtering, and exclusive discriminant validation (`mode` vs `agentId` vs `sessionKey`).
- **Agent handler integration**: When `voiceWakeTrigger` is provided and no explicit `agentId`/`replyTo`/`to` is set, the handler resolves a route from the config. Routed targets are validated against known agents, with graceful fallback + warning logs for unknown/malformed targets.
- **Protocol sync**: Swift `GatewayModels` updated in both `apps/macos` and `apps/shared` (kept identical). `WakeWordGateMatch` now carries the matched trigger string through the detection → capture → forward pipeline.
- **Event broadcasting**: `voicewake.routing.changed` event pushed to nodes on connect and on config updates, matching the existing `voicewake.changed` pattern.
- **CI fix**: macOS CI workers bumped from 1 to 2 to reduce cross-file state leakage flakes.
- **Issues found**: Missing `VoiceWakeRoutingConfig` type import in `server.impl.ts` (should cause TS compilation error), and `null` config passes the `voicewake.routing.set` validation guard due to `typeof null === "object"`.
<h3>Confidence Score: 3/5</h3>
- Likely safe with two issues to address: a missing type import that may break TypeScript compilation, and a null-config validation gap in the routing set handler.
- The feature is well-structured with thorough tests (unit, e2e, agent handler tests), proper validation, and clean protocol sync. However, the missing VoiceWakeRoutingConfig import in server.impl.ts is a potential compilation error, and the null config validation gap could cause unexpected config resets. Both are straightforward fixes.
- `src/gateway/server.impl.ts` (missing type import), `src/gateway/server-methods/voicewake-routing.ts` (null config validation)
<sub>Last reviewed commit: 38a720a</sub>
<!-- greptile_other_comments_section -->
<sub>(3/5) Reply to the agent's comments like "Can you suggest a fix for this @greptileai?" or ask follow-up questions!</sub>
<!-- /greptile_comment -->
Most Similar PRs
#9703: feat(macos): Voice settings restructure + Whisper transcription sup...
by nsd97 · 2026-02-05
72.8%
#22480: fix: memory leak, silent WS failures, and connection error handling
by Chase-Xuu · 2026-02-21
72.5%
#23572: feat(voice): enable voice note conversation loop for Telegram and W...
by davidrudduck · 2026-02-22
72.4%
#19073: feat(voice-call): streaming TTS, barge-in, silence filler, hangup, ...
by odrobnik · 2026-02-17
72.3%
#11788: feat: inter-agent communication via CLI scripts
by jingkang0822 · 2026-02-08
71.6%
#16685: Fix cli agents/approvals/discord routing edge cases
by craftowen · 2026-02-15
71.1%
#14458: fix(voicewake): avoid crash on foreign transcript ranges
by guchang · 2026-02-12
70.8%
#21566: feat(voice-call): bridge call transcripts to main agent session
by MegaPhoenix92 · 2026-02-20
70.5%
#10748: feat: Add sessions.spawn gateway method for direct subagent spawning
by fox-openclaw · 2026-02-06
70.4%
#18801: fix(routing): use fresh config in resolveAgentRoute to prevent stal...
by mcaxtr · 2026-02-17
69.9%