Address review feedback: log a warning when the stale call reaper
fails to end a call instead of silently discarding the error.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adds a periodic reaper that automatically ends calls older than a
configurable threshold. This catches calls stuck in unexpected states,
such as notify-mode calls that never receive a terminal webhook from
the provider.
New config option:
staleCallReaperSeconds: number (default: 0 = disabled)
When enabled, checks every 30 seconds and ends calls exceeding the
max age. Recommended value: 120-300 for production deployments.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Address review feedback: the in-memory deletion of initialMessage is
not persisted to disk, which is acceptable because a gateway restart
would also sever the media stream, making replay impossible.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Pre-generates TTS audio for the configured inboundGreeting at startup
and serves it instantly when an inbound call connects, eliminating the
500ms+ TTS synthesis delay on the first ring.
Changes:
- twilio.ts: Add cachedGreetingAudio storage with getter/setter
- runtime.ts: Pre-synthesize greeting TTS after provider initialization
- webhook.ts: Play cached audio directly via media stream on inbound
connect, falling back to the original TTS path for outbound calls
or when no cached audio is available
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Bare numeric Discord IDs (e.g. '1470130713209602050') in cron
delivery.to caused 'Ambiguous Discord recipient' errors and silent
delivery failures.
Adds normalizeDiscordOutboundTarget() to the existing Discord
normalize module (channels/plugins/normalize/discord.ts) alongside
normalizeDiscordMessagingTarget. Defaults bare numeric IDs to
'channel:<id>', matching existing behavior.
Both the Discord extension plugin and standalone outbound adapter
use the shared helper via a one-liner resolveTarget.
Fixes#14753. Related: #13927