feat(voice-call): route inbound calls per number

This commit is contained in:
Peter Steinberger
2026-05-02 09:44:32 +01:00
parent de67311b96
commit 39a931f1bf
15 changed files with 385 additions and 15 deletions

View File

@@ -1,4 +1,4 @@
a7158716d9262edba32ef9a18ab04d9f48f83cb903444b6f87b991977b6be52f config-baseline.json
366770fd037ace1092595b351fbd83473ee1ecce188bceb0ab4510a5579a9073 config-baseline.json
2d132b4c2e3b0e0f2524fc1cc889d3be658ad0e40c970b2d367bf27348883658 config-baseline.core.json
f42329d45c095881bd226bdb192c235980658fd250606d0c0badc2b12f12f5d3 config-baseline.channel.json
de03faf42db470fe419a3f93a5777161f830f0355912603c6795945e42f39735 config-baseline.plugin.json
fffe0e74eab92a88c3c57952a70bc932438ce3a7f5f9982688437f2cdaee0bcb config-baseline.plugin.json

View File

@@ -110,6 +110,17 @@ Voice-call credentials accept SecretRefs. `plugins.entries.voice-call.config.twi
fromNumber: "+15550001234", // or TWILIO_FROM_NUMBER for Twilio
toNumber: "+15550005678",
sessionScope: "per-phone", // per-phone | per-call
numbers: {
"+15550009999": {
inboundGreeting: "Silver Fox Cards, how can I help?",
responseSystemPrompt: "You are a concise baseball card specialist.",
tts: {
providers: {
openai: { voice: "alloy" },
},
},
},
},
twilio: {
accountSid: "ACxxxxxxxx",
@@ -500,6 +511,57 @@ identity.
Auto-responses use the agent system. Tune with `responseModel`,
`responseSystemPrompt`, and `responseTimeoutMs`.
### Per-number Routing
Use `numbers` when one Voice Call plugin receives calls for multiple phone
numbers and each number should behave like a different line. For example, one
number can use a casual personal assistant while another uses a business
persona, a different response agent, and a different TTS voice.
Routes are selected from the provider-supplied dialed `To` number. Keys must be
E.164 numbers. When a call arrives, Voice Call resolves the matching route once,
stores the matched route on the call record, and reuses that effective config
for the greeting, classic auto-response path, realtime consult path, and TTS
playback. If no route matches, the global Voice Call config is used.
Outbound calls do not use `numbers`; pass the outbound target, message, and
session explicitly when initiating the call.
Route overrides currently support:
- `inboundGreeting`
- `tts`
- `agentId`
- `responseModel`
- `responseSystemPrompt`
- `responseTimeoutMs`
The `tts` route value deep-merges over the global Voice Call `tts` config, so
you can usually override only the provider voice:
```json5
{
inboundGreeting: "Hello from the main line.",
responseSystemPrompt: "You are the default voice assistant.",
tts: {
provider: "openai",
providers: {
openai: { voice: "coral" },
},
},
numbers: {
"+15550001111": {
inboundGreeting: "Silver Fox Cards, how can I help?",
responseSystemPrompt: "You are a concise baseball card specialist.",
tts: {
providers: {
openai: { voice: "alloy" },
},
},
},
},
}
```
### Spoken output contract
For auto-responses, Voice Call appends a strict spoken-output contract to