@agenticmail/core 0.9.38 → 0.9.39

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -1610,6 +1610,7 @@ __export(index_exports, {
1610
1610
  getTelegramMe: () => getTelegramMe,
1611
1611
  getTelegramUpdates: () => getTelegramUpdates,
1612
1612
  getTelegramWebhookInfo: () => getTelegramWebhookInfo,
1613
+ getVoiceProvider: () => getVoiceProvider,
1613
1614
  hostSessionStoragePath: () => hostSessionStoragePath,
1614
1615
  inferPhoneRegion: () => inferPhoneRegion,
1615
1616
  invalidateSkillCache: () => invalidateSkillCache,
@@ -1622,6 +1623,7 @@ __export(index_exports, {
1622
1623
  isTelegramStopCommand: () => isTelegramStopCommand,
1623
1624
  isValidPhoneNumber: () => isValidPhoneNumber,
1624
1625
  listSkills: () => listSkills,
1626
+ listVoiceProviders: () => listVoiceProviders,
1625
1627
  loadAgentPersona: () => loadAgentPersona,
1626
1628
  loadHostSession: () => loadHostSession,
1627
1629
  loadSkill: () => loadSkill,
@@ -1650,6 +1652,7 @@ __export(index_exports, {
1650
1652
  redactSecret: () => redactSecret,
1651
1653
  redactSmsConfig: () => redactSmsConfig,
1652
1654
  redactTelegramConfig: () => redactTelegramConfig,
1655
+ registerVoiceProvider: () => registerVoiceProvider,
1653
1656
  renderSkillAsPrompt: () => renderSkillAsPrompt,
1654
1657
  requireBinary: () => requireBinary,
1655
1658
  requireWhisperModel: () => requireWhisperModel,
@@ -1657,6 +1660,7 @@ __export(index_exports, {
1657
1660
  resolveConfig: () => resolveConfig,
1658
1661
  resolveExtensionPolicy: () => resolveExtensionPolicy,
1659
1662
  resolveTlsRejectUnauthorized: () => resolveTlsRejectUnauthorized,
1663
+ resolveVoiceRuntime: () => resolveVoiceRuntime,
1660
1664
  safeJoin: () => safeJoin,
1661
1665
  sanitizeEmail: () => sanitizeEmail,
1662
1666
  saveAgentPersona: () => saveAgentPersona,
@@ -2588,6 +2592,13 @@ function resolveConfig(overrides) {
2588
2592
  dataDir: env.AGENTICMAIL_DATA_DIR?.replace(/^~(?=\/|$)/, (0, import_node_os.homedir)()) ?? DEFAULT_CONFIG.dataDir
2589
2593
  };
2590
2594
  if (env.OPENAI_API_KEY) config.openaiApiKey = env.OPENAI_API_KEY;
2595
+ if (env.XAI_API_KEY) {
2596
+ config.voiceProviderKeys = config.voiceProviderKeys ?? {};
2597
+ config.voiceProviderKeys.grok = env.XAI_API_KEY;
2598
+ }
2599
+ if (env.AGENTICMAIL_VOICE_RUNTIME && env.AGENTICMAIL_VOICE_RUNTIME.trim()) {
2600
+ config.voiceRuntime = env.AGENTICMAIL_VOICE_RUNTIME.trim();
2601
+ }
2591
2602
  const configPath = (0, import_node_path.join)(config.dataDir, "config.json");
2592
2603
  if ((0, import_node_fs.existsSync)(configPath)) {
2593
2604
  try {
@@ -12203,6 +12214,94 @@ function withTimeout(promise, ms) {
12203
12214
  return Promise.race([promise, timeout]).finally(() => clearTimeout(timer));
12204
12215
  }
12205
12216
 
12217
+ // src/phone/voice-providers/registry.ts
12218
+ var PROVIDERS2 = /* @__PURE__ */ new Map();
12219
+ function registerVoiceProvider(provider) {
12220
+ if (PROVIDERS2.has(provider.id)) {
12221
+ throw new Error(`Voice provider "${provider.id}" registered twice \u2014 id collision.`);
12222
+ }
12223
+ PROVIDERS2.set(provider.id, provider);
12224
+ }
12225
+ function listVoiceProviders() {
12226
+ return Array.from(PROVIDERS2.values());
12227
+ }
12228
+ function getVoiceProvider(id) {
12229
+ return PROVIDERS2.get(id);
12230
+ }
12231
+ function resolveVoiceRuntime(providerId, config, options = {}) {
12232
+ const id = (providerId || "openai").trim() || "openai";
12233
+ const provider = PROVIDERS2.get(id);
12234
+ if (!provider) {
12235
+ const known = Array.from(PROVIDERS2.keys()).join(", ") || "(none registered)";
12236
+ throw new Error(
12237
+ `Unknown voice runtime "${id}". Known providers: ${known}. Add a new one by dropping a file into packages/core/src/phone/voice-providers/.`
12238
+ );
12239
+ }
12240
+ let apiKey = "";
12241
+ let apiKeySource = "";
12242
+ if (provider.apiKeyConfigField) {
12243
+ const legacy = config[provider.apiKeyConfigField];
12244
+ if (legacy && legacy.trim()) {
12245
+ apiKey = legacy.trim();
12246
+ apiKeySource = `config.${provider.apiKeyConfigField}`;
12247
+ }
12248
+ }
12249
+ if (!apiKey) {
12250
+ const fromMap = config.voiceProviderKeys?.[provider.id];
12251
+ if (fromMap && fromMap.trim()) {
12252
+ apiKey = fromMap.trim();
12253
+ apiKeySource = `config.voiceProviderKeys.${provider.id}`;
12254
+ }
12255
+ }
12256
+ if (!apiKey) {
12257
+ const fromEnv = process.env[provider.apiKeyEnvVar];
12258
+ if (fromEnv && fromEnv.trim()) {
12259
+ apiKey = fromEnv.trim();
12260
+ apiKeySource = `env ${provider.apiKeyEnvVar}`;
12261
+ }
12262
+ }
12263
+ if (!apiKey) {
12264
+ throw new Error(
12265
+ `Voice provider "${provider.id}" (${provider.displayName}) selected, but no API key is configured. Set ${provider.apiKeyEnvVar} in your environment or save it to ~/.agenticmail/config.json under voiceProviderKeys.${provider.id}.`
12266
+ );
12267
+ }
12268
+ const model = options.model && options.model.trim() || provider.defaultModel;
12269
+ const url = `${provider.websocketBaseUrl}?model=${encodeURIComponent(model)}`;
12270
+ return {
12271
+ providerId: provider.id,
12272
+ providerDisplayName: provider.displayName,
12273
+ url,
12274
+ model,
12275
+ apiKey,
12276
+ apiKeySource
12277
+ };
12278
+ }
12279
+
12280
+ // src/phone/voice-providers/openai.ts
12281
+ registerVoiceProvider({
12282
+ id: "openai",
12283
+ displayName: "OpenAI Realtime (gpt-realtime)",
12284
+ websocketBaseUrl: "wss://api.openai.com/v1/realtime",
12285
+ defaultModel: "gpt-realtime",
12286
+ apiKeyEnvVar: "OPENAI_API_KEY",
12287
+ // Legacy: the original config.json schema used a dedicated
12288
+ // `openaiApiKey` field for this key. The resolver checks that field
12289
+ // before the generic voiceProviderKeys map so existing installs
12290
+ // continue to work without migration.
12291
+ apiKeyConfigField: "openaiApiKey",
12292
+ description: "OpenAI Realtime (gpt-realtime). Default voice runtime; supports linear PCM @ 24 kHz (46elks) and G.711 \xB5-law @ 8 kHz (Twilio) without transcoding."
12293
+ });
12294
+
12295
+ // src/phone/voice-providers/grok.ts
12296
+ registerVoiceProvider({
12297
+ id: "grok",
12298
+ displayName: "xAI Grok Voice Agent",
12299
+ websocketBaseUrl: "wss://api.x.ai/v1/realtime",
12300
+ defaultModel: "grok-voice-latest",
12301
+ apiKeyEnvVar: "XAI_API_KEY",
12302
+ description: 'xAI Grok Voice Agent \u2014 OpenAI-Realtime-compatible WebSocket protocol; select via mission policy.voiceRuntime="grok" or env AGENTICMAIL_VOICE_RUNTIME=grok.'
12303
+ });
12304
+
12206
12305
  // src/telemetry.ts
12207
12306
  var import_crypto = require("crypto");
12208
12307
  var import_fs = require("fs");
@@ -16517,6 +16616,7 @@ function saveAgentPersona(agentName, content) {
16517
16616
  getTelegramMe,
16518
16617
  getTelegramUpdates,
16519
16618
  getTelegramWebhookInfo,
16619
+ getVoiceProvider,
16520
16620
  hostSessionStoragePath,
16521
16621
  inferPhoneRegion,
16522
16622
  invalidateSkillCache,
@@ -16529,6 +16629,7 @@ function saveAgentPersona(agentName, content) {
16529
16629
  isTelegramStopCommand,
16530
16630
  isValidPhoneNumber,
16531
16631
  listSkills,
16632
+ listVoiceProviders,
16532
16633
  loadAgentPersona,
16533
16634
  loadHostSession,
16534
16635
  loadSkill,
@@ -16557,6 +16658,7 @@ function saveAgentPersona(agentName, content) {
16557
16658
  redactSecret,
16558
16659
  redactSmsConfig,
16559
16660
  redactTelegramConfig,
16661
+ registerVoiceProvider,
16560
16662
  renderSkillAsPrompt,
16561
16663
  requireBinary,
16562
16664
  requireWhisperModel,
@@ -16564,6 +16666,7 @@ function saveAgentPersona(agentName, content) {
16564
16666
  resolveConfig,
16565
16667
  resolveExtensionPolicy,
16566
16668
  resolveTlsRejectUnauthorized,
16669
+ resolveVoiceRuntime,
16567
16670
  safeJoin,
16568
16671
  sanitizeEmail,
16569
16672
  saveAgentPersona,
package/dist/index.d.cts CHANGED
@@ -229,6 +229,22 @@ interface AgenticMailConfig {
229
229
  * `config.json`. Optional — no other feature depends on it.
230
230
  */
231
231
  openaiApiKey?: string;
232
+ /**
233
+ * v0.9.93 — voice-runtime provider keys. Each is a thin Bearer-token
234
+ * for a provider's realtime API; required only when that provider
235
+ * is selected as the runtime for a call. New providers register
236
+ * themselves in `packages/core/src/phone/voice-providers/` and
237
+ * declare which key field they consume — this record is the central
238
+ * pool. Read from per-provider env vars (e.g. `XAI_API_KEY`) at boot.
239
+ */
240
+ voiceProviderKeys?: Record<string, string>;
241
+ /**
242
+ * v0.9.93 — default voice-runtime provider id for phone missions
243
+ * that don't pin one on their own policy. `'openai'` (the existing
244
+ * default) or any provider registered in `voice-providers/`.
245
+ * Read from `AGENTICMAIL_VOICE_RUNTIME` env var or `config.json`.
246
+ */
247
+ voiceRuntime?: string;
232
248
  masterKey: string;
233
249
  dataDir: string;
234
250
  }
@@ -3824,6 +3840,127 @@ declare class RealtimeVoiceBridge {
3824
3840
  private safeSend;
3825
3841
  }
3826
3842
 
3843
+ /**
3844
+ * Voice-runtime provider plugin interface.
3845
+ *
3846
+ * Each backend (OpenAI Realtime, Grok Voice Agent, future Anthropic
3847
+ * realtime, Cartesia, ElevenLabs ConvAI, etc.) lives in its own file
3848
+ * under `packages/core/src/phone/voice-providers/` and registers
3849
+ * itself with the registry by calling {@link registerVoiceProvider}
3850
+ * at module load.
3851
+ *
3852
+ * Adding a new provider is meant to be a literal FILE DROP:
3853
+ *
3854
+ * 1. Create `voice-providers/<id>.ts` exporting a {@link VoiceProvider}.
3855
+ * 2. Add a single `import './<id>.js';` line to `voice-providers/index.ts`
3856
+ * so the side-effect registration runs.
3857
+ * 3. (Optional) document the env var the provider expects.
3858
+ *
3859
+ * No other file in the codebase needs to know about the new provider —
3860
+ * the realtime bridge looks providers up by id through the registry.
3861
+ *
3862
+ * Currently every supported provider is an OpenAI-Realtime-compatible
3863
+ * WebSocket. If a future provider diverges enough to need its own wire
3864
+ * protocol (custom event shape, gRPC, WebRTC SDP, etc.), the seam to
3865
+ * extend is here: add `buildSessionUpdate` / `parseInboundEvent` /
3866
+ * etc. hooks to {@link VoiceProvider}, then make `realtime-bridge.ts`
3867
+ * route through them instead of speaking OpenAI Realtime directly.
3868
+ */
3869
+ /**
3870
+ * One voice-runtime provider. Carries enough information for the
3871
+ * bridge to open the right WebSocket with the right auth + model.
3872
+ */
3873
+ interface VoiceProvider {
3874
+ /**
3875
+ * Stable identifier used in mission policy / config (`'openai'`,
3876
+ * `'grok'`, …). Keep lowercase, no spaces — this is what operators
3877
+ * type into `AGENTICMAIL_VOICE_RUNTIME=` or pass via mission policy.
3878
+ */
3879
+ id: string;
3880
+ /** Human-readable display name for logs + the web UI. */
3881
+ displayName: string;
3882
+ /** WebSocket base URL (the bridge appends `?model=…`). */
3883
+ websocketBaseUrl: string;
3884
+ /**
3885
+ * Default model when the caller doesn't pin one. Sent as the
3886
+ * `?model=…` query string AND echoed in the session.update.
3887
+ */
3888
+ defaultModel: string;
3889
+ /**
3890
+ * The env var the operator sets for this provider's API key
3891
+ * (`OPENAI_API_KEY`, `XAI_API_KEY`, …). The bootstrap / config
3892
+ * loader reads from this name and stores into
3893
+ * `AgenticMailConfig.voiceProviderKeys[<id>]`. Used in the
3894
+ * "you didn't set the key" error message too.
3895
+ */
3896
+ apiKeyEnvVar: string;
3897
+ /**
3898
+ * Optional fallback config-field name. When the provider's API key
3899
+ * has a long-standing dedicated config field (e.g. OpenAI's
3900
+ * `config.openaiApiKey`), this lets the resolver check that field
3901
+ * BEFORE looking in the generic `voiceProviderKeys` map — so
3902
+ * existing installs don't need to migrate. Leave undefined for
3903
+ * new providers.
3904
+ */
3905
+ apiKeyConfigField?: 'openaiApiKey';
3906
+ /**
3907
+ * Per-provider notes that surface in error / boot-log messages.
3908
+ * Optional — defaults are fine for the standard providers.
3909
+ */
3910
+ description?: string;
3911
+ }
3912
+ /**
3913
+ * The bridge needs all the inputs needed to open a session in one
3914
+ * resolved struct — URL with model encoded, the API key, the source
3915
+ * for logging. {@link resolveVoiceRuntime} produces this.
3916
+ */
3917
+ interface VoiceRuntimeConnection {
3918
+ providerId: string;
3919
+ providerDisplayName: string;
3920
+ /** Full WebSocket URL including `?model=…`. */
3921
+ url: string;
3922
+ /** Resolved model name (also passed in the URL). */
3923
+ model: string;
3924
+ /** Bearer token for the `Authorization` header. */
3925
+ apiKey: string;
3926
+ /** Human-readable source of the key, for boot logs only (e.g. `"env XAI_API_KEY"`). */
3927
+ apiKeySource: string;
3928
+ }
3929
+
3930
+ /**
3931
+ * Voice-provider registry — drop-in plugin discovery.
3932
+ *
3933
+ * Providers register themselves at module-load time via
3934
+ * {@link registerVoiceProvider}. The barrel `voice-providers/index.ts`
3935
+ * imports each provider file for its side effect, populating this map
3936
+ * before any caller asks for one.
3937
+ *
3938
+ * No reflection, no filesystem scan, no decorator magic — adding a
3939
+ * provider is "create a file + add one import line". That gives us
3940
+ * both first-class TypeScript types AND the file-drop ergonomics.
3941
+ */
3942
+
3943
+ /**
3944
+ * Register a provider. Called once per file at module load. Throws on
3945
+ * duplicate id so an accidental copy-paste collision is loud, not
3946
+ * silently overriding.
3947
+ */
3948
+ declare function registerVoiceProvider(provider: VoiceProvider): void;
3949
+ /** All registered providers — for `agenticmail voice list` / web UI menus. */
3950
+ declare function listVoiceProviders(): VoiceProvider[];
3951
+ /** Look up a provider by id. Returns undefined for unknown ids. */
3952
+ declare function getVoiceProvider(id: string): VoiceProvider | undefined;
3953
+ /**
3954
+ * Resolve a provider id + the runtime's config / overrides into the
3955
+ * connection struct the bridge consumes (URL with model, api key,
3956
+ * source). Throws if the provider id is unknown or its API key isn't
3957
+ * configured — the realtime-ws layer turns the throw into a clear
3958
+ * startup error instead of a mid-call surprise.
3959
+ */
3960
+ declare function resolveVoiceRuntime(providerId: string | undefined, config: AgenticMailConfig, options?: {
3961
+ model?: string;
3962
+ }): VoiceRuntimeConnection;
3963
+
3827
3964
  type PhoneTransportProvider = '46elks' | 'twilio';
3828
3965
  /** Providers that support starting outbound call-control missions. */
3829
3966
  declare const PHONE_CALL_CONTROL_PROVIDERS: readonly PhoneTransportProvider[];
@@ -6248,4 +6385,4 @@ declare function loadAgentPersona(agentName: string): string;
6248
6385
  */
6249
6386
  declare function saveAgentPersona(agentName: string, content: string): string;
6250
6387
 
6251
- export { AGENT_ROLES, AGENT_STATE_ROOT, ASK_OPERATOR_TOOL, AccountManager, type AddressInfo, type Agent, AgentDeletionService, type AgentMemoryEntry, type AgentMemoryFields, AgentMemoryManager, type AgentMemoryOptions, type AgentMemoryRead, AgentMemoryStore, type AgentRole, AgenticMailClient, type AgenticMailClientOptions, type AgenticMailConfig, type ArchiveAndDeleteOptions, type ArchivedEmail, type Attachment, type AttachmentAdvisory, type AudioAction, type AudioEditOptions, BRIDGE_OPERATOR_LIVE_WINDOW_MS, type BridgeMailContext, type BridgeWakeError, type BridgeWakePromptArgs, type BridgeWakeResult, type BridgeWakeRoute, type CachedMessage, CloudflareClient, type CreateAgentOptions, type CreateMemoryInput, DEFAULT_AGENT_NAME, DEFAULT_AGENT_ROLE, DEFAULT_CALLBACK_POLICY, DEFAULT_EXTENSION_POLICY, DEFAULT_REALTIME_AUDIO_FORMAT, DEFAULT_REALTIME_MODEL, DEFAULT_REALTIME_VOICE, DEFAULT_SESSION_MAX_AGE_MS, DEFAULT_WEB_SEARCH_ENDPOINT, DNSConfigurator, type Database, type DeletionReport, type DeletionSummary, DependencyChecker, DependencyInstaller, type DependencyStatus, type DnsRecord, type DnsSetupResult, type DomainInfo, DomainManager, type DomainModeConfig, type DomainPurchaseResult, DomainPurchaser, type DomainSearchResult, type DomainSetupResult, ELKS_REALTIME_AUDIO_FORMATS, ELKS_REALTIME_WS_PATH, END_CALL_TOOL, EXTEND_CALL_TIME_TOOL, type ElksRealtimeAudioFormat, type ElksRealtimeAudioMessage, type ElksRealtimeByeMessage, type ElksRealtimeHelloMessage, type ElksRealtimeInboundMessage, type ElksRealtimeOutboundMessage, ElksRealtimeTransport, type EmailEnvelope, type EmailRouteAction, type EmailRouteClass, type EmailRouteClassification, type EmailRouteInput, EmailSearchIndex, type FolderInfo, GET_CALL_STATUS_TOOL, GET_DATETIME_TOOL, type GatewayConfig, GatewayManager, type GatewayManagerOptions, type GatewayMode, type GatewayStatus, type GetDatetimeOptions, type GetUpdatesOptions, type HostName, type HostSession, type HostSessionResumeMode, type ImageAction, type ImageEditOptions, type InboundEmail, type InboundSmsEvent, type InboxEvent, type InboxExpungeEvent, type InboxFlagsEvent, type InboxNewEvent, InboxWatcher, type InboxWatcherOptions, type InstallProgress, LOAD_SKILL_TOOL, type LinkAdvisory, type LocalSmtpConfig, MEMORY_CATEGORIES, MailReceiver, type MailReceiverOptions, MailSender, type MailSenderOptions, type MailboxInfo, type MediaBinary, type MediaCapability, type MediaCapabilityReport, type MediaFileResult, type MediaInfoResult, MediaManager, type MediaManagerOptions, type MediaStreamInfo, type MemoryCategory, type MemoryImportance, type MemoryQueryOptions, type MemoryRecaller, MemorySearchIndex, type MemorySource, type MemoryStats, OPENAI_REALTIME_URL, OPERATOR_QUERY_POLL_INTERVAL_MS, OPERATOR_QUERY_SUBJECT_TAG, OPERATOR_QUERY_TIMEOUT_MS, OPERATOR_QUERY_TIMEOUT_SENTINEL, type OpenClawPhoneMissionPolicy, type OperatorQueryNotificationInput, type OperatorQueryPollOptions, type OperatorQueryUrgency, type OperatorReplyKind, type OutboundCategory, type OutboundScanInput, type OutboundScanResult, type OutboundWarning, PERSONA_FILENAME, PHONE_CALLBACK_MAX_DELAY_SECONDS, PHONE_CALLBACK_MIN_DELAY_SECONDS, PHONE_CALL_CONTROL_PROVIDERS, PHONE_MAX_CONCURRENT_MISSIONS, PHONE_MIN_WEBHOOK_SECRET_LENGTH, PHONE_MISSION_STATES, PHONE_RATE_LIMIT_PER_HOUR, PHONE_RATE_LIMIT_PER_MINUTE, PHONE_REGION_SCOPES, PHONE_SERVER_MAX_ATTEMPTS, PHONE_SERVER_MAX_CALLBACK_CHAIN, PHONE_SERVER_MAX_CALL_DURATION_SECONDS, PHONE_SERVER_MAX_COST_PER_MISSION, PHONE_SERVER_MAX_EXTENSION_REQUESTS_PER_CALL, PHONE_SERVER_MAX_EXTENSION_SECONDS_PER_REQUEST, PHONE_SERVER_MAX_TOTAL_EXTENSION_SECONDS, PHONE_TASK_MAX_LENGTH, type ParsedAttachment, type ParsedEmail, type ParsedOperatorReply, type ParsedSms, type ParsedTelegramMessage, PathTraversalError, type PhoneAlternativePolicy, type PhoneCallMission, type PhoneCallbackPolicy, type PhoneConfirmPolicy, type PhoneExtensionPolicy, PhoneManager, type PhoneMissionStartValidationResult, type PhoneMissionState, type PhoneMissionTranscriptEntry, type PhoneMissionValidationIssue, type PhoneMissionValidationResult, type PhoneNumberRisk, type PhoneOperatorQuery, PhoneRateLimitError, type PhoneRegionScope, type PhoneScheduledCallback, type PhoneTransportConfig, type PhoneTransportProfile, type PhoneTransportProvider, type PhoneTransportValidationResult, PhoneWebhookAuthError, type PhoneWebhookResult, type PlanBridgeWakeArgs, type PurchasedDomain, REALTIME_AUDIO_SAMPLE_RATE, REALTIME_MAX_AUDIO_FRAME_BASE64, REALTIME_TOOL_CALL_TIMEOUT_MS, REALTIME_TOOL_DEFINITIONS, RECALL_MEMORY_TOOL, REDACTED, RELAY_PRESETS, type RealtimeBridgePort, type RealtimeBridgeTranscriptEntry, type RealtimeInboundEvent, type RealtimeInstructionOptions, type RealtimeSessionConfigOptions, type RealtimeToolCall, type RealtimeToolDefinition, type RealtimeToolHandler, type RealtimeToolResult, type RealtimeTransportAdapter, type RealtimeTransportProvider, RealtimeVoiceBridge, type RealtimeVoiceBridgeOptions, RelayBridge, type RelayBridgeOptions, type RelayConfig, RelayGateway, type RelayProvider, type RelaySearchResult, type ResumeErrorClassificationOptions, SCHEDULE_CALLBACK_TOOL, SEARCH_EMAIL_TOOL, SEARCH_SKILLS_TOOL, SPAM_THRESHOLD, type SafeJoinOptions, type SanitizeDetection, type SanitizeResult, type ScheduledCallbackRequest, type SearchCriteria, type SearchableEmail, type SecurityAdvisory, type SendMailOptions, type SendResult, type SendResultWithRaw, type SendSmsInput, type SendSmsResult, type SendTelegramMessageOptions, type SendTelegramMessageResult, ServiceManager, type ServiceStatus, type SetWebhookOptions, type SetupConfig, SetupManager, type SetupResult, type Severity, type Skill, type SkillCategory, type SkillContext, type SkillExitStrategy, type SkillSummary, type SkillTactic, type SkillValidationError, type SmsConfig, SmsManager, type SmsMessage, SmsPoller, type SmsProvider, type SpamCategory, type SpamResult, type SpamRuleMatch, StalwartAdmin, type StalwartAdminOptions, type StalwartPrincipal, type StartPhoneCallOptions, type StartPhoneCallResult, type StartPhoneMissionInput, TELEGRAM_API_BASE, TELEGRAM_CHUNK_SIZE, TELEGRAM_MESSAGE_LIMIT, TELEGRAM_MIN_WEBHOOK_SECRET_LENGTH, TELEGRAM_OPERATOR_QUERY_TAG, TELEGRAM_STOP_WORDS, TELEGRAM_WEBHOOK_SECRET_RE, TELEPHONY_TRANSPORT_CAPABILITIES, TWILIO_MEDIA_SAMPLE_RATE, TWILIO_REALTIME_WS_PATH, TelegramApiError, type TelegramApiOptions, type TelegramBotInfo, type TelegramChatType, type TelegramConfig, TelegramManager, type TelegramMessage, type TelegramMode, type TelephonyTransportCapability, ThreadCache, type ThreadCacheEntry, type ThreadCacheOptions, type ThreadIdInput, type ToolExecutor, type TtsGenerateOptions, type TunnelConfig, TunnelManager, type TwilioConnectedMessage, type TwilioMarkMessage, type TwilioMediaMessage, type TwilioRealtimeInboundMessage, type TwilioRealtimeOutboundMessage, TwilioRealtimeTransport, type TwilioStartMessage, type TwilioStopMessage, type TwilioStreamTwiMLOptions, UnsafeApiUrlError, type UpdateMemoryInput, type ValidatedPhoneMissionStart, type VideoAction, type VideoEditOptions, type VideoTimelineEntry, type VideoUnderstandOptions, type VideoUnderstandResult, type VoiceCloneOptions, WARNING_THRESHOLD, WEB_SEARCH_TOOL, WEB_SEARCH_UNTRUSTED_PREFIX, type WatcherOptions, type WebSearchOptions, assertWithinBase, bridgeWakeErrorMessage, bridgeWakeLastSeenAgeMs, buildApiUrl, buildDefaultPersona, buildElksAudioMessage, buildElksByeMessage, buildElksHandshakeMessages, buildElksInterruptMessage, buildElksListeningMessage, buildElksSendingMessage, buildInboundSecurityAdvisory, buildOpenAIRealtimeUrl, buildPhoneTransportConfig, buildRealtimeInstructions, buildRealtimeSessionConfig, buildRealtimeToolGuidance, buildTwilioClearMessage, buildTwilioMarkMessage, buildTwilioMediaMessage, buildTwilioSayTwiML, buildTwilioSignature, buildTwilioStreamTwiML, callTelegramApi, classifyEmailRoute, classifyPhoneNumberRisk, classifyResumeError, clearMediaCapabilityCache, closeDatabase, composeBridgeWakePrompt, createRealtimeTransport, createTestDatabase, createToolExecutor, debug, debugWarn, deleteTelegramWebhook, detectBinary, ensureDataDir, escapeXml, extractEmailAddress, extractVerificationCode, flushTelemetry, forgetHostSession, formatOperatorQueryTelegramMessage, getDatabase, getDatetime, getMediaCapabilities, getOperatorEmail, getSmsProvider, getTelegramChat, getTelegramMe, getTelegramUpdates, getTelegramWebhookInfo, hostSessionStoragePath, inferPhoneRegion, invalidateSkillCache, isInternalEmail, isLoopbackMailHost, isOperatorReplySender, isPhoneRegionAllowed, isSessionFresh, isTelegramChatAllowed, isTelegramStopCommand, isValidPhoneNumber, listSkills, loadAgentPersona, loadHostSession, loadSkill, mapProviderSmsStatus, nextTelegramOffset, normalizeAddress, normalizePhoneNumber, normalizeSubject, operatorPrefsStoragePath, operatorQuerySubject, parseElksRealtimeMessage, parseEmail, parseGoogleVoiceSms, parseOperatorQueryReply, parseTelegramOperatorReply, parseTelegramUpdate, parseTwilioRealtimeMessage, personaPathFor, planBridgeWake, pollForOperatorAnswer, recallMemory, recordToolCall, redactBotToken, redactObject, redactPhoneTransportConfig, redactSecret, redactSmsConfig, redactTelegramConfig, renderSkillAsPrompt, requireBinary, requireWhisperModel, resolveCallbackPolicy, resolveConfig, resolveExtensionPolicy, resolveTlsRejectUnauthorized, safeJoin, sanitizeEmail, saveAgentPersona, saveConfig, saveHostSession, saveUserSkill, scanOutboundEmail, scoreEmail, searchSkills, sendTelegramMessage, setOperatorEmail, setTelegramWebhook, setTelemetryVersion, shouldSkipBridgeWakeForLiveOperator, splitTelegramMessage, startRelayBridge, stem, stripTelegramMarkdown, threadIdFor, tokenize, tryJoin, userSkillsDir, validateApiUrl, validatePhoneMissionPolicy, validatePhoneMissionStart, validatePhoneTransportProfile, validateSkill, validateTwilioSignature, webSearch };
6388
+ export { AGENT_ROLES, AGENT_STATE_ROOT, ASK_OPERATOR_TOOL, AccountManager, type AddressInfo, type Agent, AgentDeletionService, type AgentMemoryEntry, type AgentMemoryFields, AgentMemoryManager, type AgentMemoryOptions, type AgentMemoryRead, AgentMemoryStore, type AgentRole, AgenticMailClient, type AgenticMailClientOptions, type AgenticMailConfig, type ArchiveAndDeleteOptions, type ArchivedEmail, type Attachment, type AttachmentAdvisory, type AudioAction, type AudioEditOptions, BRIDGE_OPERATOR_LIVE_WINDOW_MS, type BridgeMailContext, type BridgeWakeError, type BridgeWakePromptArgs, type BridgeWakeResult, type BridgeWakeRoute, type CachedMessage, CloudflareClient, type CreateAgentOptions, type CreateMemoryInput, DEFAULT_AGENT_NAME, DEFAULT_AGENT_ROLE, DEFAULT_CALLBACK_POLICY, DEFAULT_EXTENSION_POLICY, DEFAULT_REALTIME_AUDIO_FORMAT, DEFAULT_REALTIME_MODEL, DEFAULT_REALTIME_VOICE, DEFAULT_SESSION_MAX_AGE_MS, DEFAULT_WEB_SEARCH_ENDPOINT, DNSConfigurator, type Database, type DeletionReport, type DeletionSummary, DependencyChecker, DependencyInstaller, type DependencyStatus, type DnsRecord, type DnsSetupResult, type DomainInfo, DomainManager, type DomainModeConfig, type DomainPurchaseResult, DomainPurchaser, type DomainSearchResult, type DomainSetupResult, ELKS_REALTIME_AUDIO_FORMATS, ELKS_REALTIME_WS_PATH, END_CALL_TOOL, EXTEND_CALL_TIME_TOOL, type ElksRealtimeAudioFormat, type ElksRealtimeAudioMessage, type ElksRealtimeByeMessage, type ElksRealtimeHelloMessage, type ElksRealtimeInboundMessage, type ElksRealtimeOutboundMessage, ElksRealtimeTransport, type EmailEnvelope, type EmailRouteAction, type EmailRouteClass, type EmailRouteClassification, type EmailRouteInput, EmailSearchIndex, type FolderInfo, GET_CALL_STATUS_TOOL, GET_DATETIME_TOOL, type GatewayConfig, GatewayManager, type GatewayManagerOptions, type GatewayMode, type GatewayStatus, type GetDatetimeOptions, type GetUpdatesOptions, type HostName, type HostSession, type HostSessionResumeMode, type ImageAction, type ImageEditOptions, type InboundEmail, type InboundSmsEvent, type InboxEvent, type InboxExpungeEvent, type InboxFlagsEvent, type InboxNewEvent, InboxWatcher, type InboxWatcherOptions, type InstallProgress, LOAD_SKILL_TOOL, type LinkAdvisory, type LocalSmtpConfig, MEMORY_CATEGORIES, MailReceiver, type MailReceiverOptions, MailSender, type MailSenderOptions, type MailboxInfo, type MediaBinary, type MediaCapability, type MediaCapabilityReport, type MediaFileResult, type MediaInfoResult, MediaManager, type MediaManagerOptions, type MediaStreamInfo, type MemoryCategory, type MemoryImportance, type MemoryQueryOptions, type MemoryRecaller, MemorySearchIndex, type MemorySource, type MemoryStats, OPENAI_REALTIME_URL, OPERATOR_QUERY_POLL_INTERVAL_MS, OPERATOR_QUERY_SUBJECT_TAG, OPERATOR_QUERY_TIMEOUT_MS, OPERATOR_QUERY_TIMEOUT_SENTINEL, type OpenClawPhoneMissionPolicy, type OperatorQueryNotificationInput, type OperatorQueryPollOptions, type OperatorQueryUrgency, type OperatorReplyKind, type OutboundCategory, type OutboundScanInput, type OutboundScanResult, type OutboundWarning, PERSONA_FILENAME, PHONE_CALLBACK_MAX_DELAY_SECONDS, PHONE_CALLBACK_MIN_DELAY_SECONDS, PHONE_CALL_CONTROL_PROVIDERS, PHONE_MAX_CONCURRENT_MISSIONS, PHONE_MIN_WEBHOOK_SECRET_LENGTH, PHONE_MISSION_STATES, PHONE_RATE_LIMIT_PER_HOUR, PHONE_RATE_LIMIT_PER_MINUTE, PHONE_REGION_SCOPES, PHONE_SERVER_MAX_ATTEMPTS, PHONE_SERVER_MAX_CALLBACK_CHAIN, PHONE_SERVER_MAX_CALL_DURATION_SECONDS, PHONE_SERVER_MAX_COST_PER_MISSION, PHONE_SERVER_MAX_EXTENSION_REQUESTS_PER_CALL, PHONE_SERVER_MAX_EXTENSION_SECONDS_PER_REQUEST, PHONE_SERVER_MAX_TOTAL_EXTENSION_SECONDS, PHONE_TASK_MAX_LENGTH, type ParsedAttachment, type ParsedEmail, type ParsedOperatorReply, type ParsedSms, type ParsedTelegramMessage, PathTraversalError, type PhoneAlternativePolicy, type PhoneCallMission, type PhoneCallbackPolicy, type PhoneConfirmPolicy, type PhoneExtensionPolicy, PhoneManager, type PhoneMissionStartValidationResult, type PhoneMissionState, type PhoneMissionTranscriptEntry, type PhoneMissionValidationIssue, type PhoneMissionValidationResult, type PhoneNumberRisk, type PhoneOperatorQuery, PhoneRateLimitError, type PhoneRegionScope, type PhoneScheduledCallback, type PhoneTransportConfig, type PhoneTransportProfile, type PhoneTransportProvider, type PhoneTransportValidationResult, PhoneWebhookAuthError, type PhoneWebhookResult, type PlanBridgeWakeArgs, type PurchasedDomain, REALTIME_AUDIO_SAMPLE_RATE, REALTIME_MAX_AUDIO_FRAME_BASE64, REALTIME_TOOL_CALL_TIMEOUT_MS, REALTIME_TOOL_DEFINITIONS, RECALL_MEMORY_TOOL, REDACTED, RELAY_PRESETS, type RealtimeBridgePort, type RealtimeBridgeTranscriptEntry, type RealtimeInboundEvent, type RealtimeInstructionOptions, type RealtimeSessionConfigOptions, type RealtimeToolCall, type RealtimeToolDefinition, type RealtimeToolHandler, type RealtimeToolResult, type RealtimeTransportAdapter, type RealtimeTransportProvider, RealtimeVoiceBridge, type RealtimeVoiceBridgeOptions, RelayBridge, type RelayBridgeOptions, type RelayConfig, RelayGateway, type RelayProvider, type RelaySearchResult, type ResumeErrorClassificationOptions, SCHEDULE_CALLBACK_TOOL, SEARCH_EMAIL_TOOL, SEARCH_SKILLS_TOOL, SPAM_THRESHOLD, type SafeJoinOptions, type SanitizeDetection, type SanitizeResult, type ScheduledCallbackRequest, type SearchCriteria, type SearchableEmail, type SecurityAdvisory, type SendMailOptions, type SendResult, type SendResultWithRaw, type SendSmsInput, type SendSmsResult, type SendTelegramMessageOptions, type SendTelegramMessageResult, ServiceManager, type ServiceStatus, type SetWebhookOptions, type SetupConfig, SetupManager, type SetupResult, type Severity, type Skill, type SkillCategory, type SkillContext, type SkillExitStrategy, type SkillSummary, type SkillTactic, type SkillValidationError, type SmsConfig, SmsManager, type SmsMessage, SmsPoller, type SmsProvider, type SpamCategory, type SpamResult, type SpamRuleMatch, StalwartAdmin, type StalwartAdminOptions, type StalwartPrincipal, type StartPhoneCallOptions, type StartPhoneCallResult, type StartPhoneMissionInput, TELEGRAM_API_BASE, TELEGRAM_CHUNK_SIZE, TELEGRAM_MESSAGE_LIMIT, TELEGRAM_MIN_WEBHOOK_SECRET_LENGTH, TELEGRAM_OPERATOR_QUERY_TAG, TELEGRAM_STOP_WORDS, TELEGRAM_WEBHOOK_SECRET_RE, TELEPHONY_TRANSPORT_CAPABILITIES, TWILIO_MEDIA_SAMPLE_RATE, TWILIO_REALTIME_WS_PATH, TelegramApiError, type TelegramApiOptions, type TelegramBotInfo, type TelegramChatType, type TelegramConfig, TelegramManager, type TelegramMessage, type TelegramMode, type TelephonyTransportCapability, ThreadCache, type ThreadCacheEntry, type ThreadCacheOptions, type ThreadIdInput, type ToolExecutor, type TtsGenerateOptions, type TunnelConfig, TunnelManager, type TwilioConnectedMessage, type TwilioMarkMessage, type TwilioMediaMessage, type TwilioRealtimeInboundMessage, type TwilioRealtimeOutboundMessage, TwilioRealtimeTransport, type TwilioStartMessage, type TwilioStopMessage, type TwilioStreamTwiMLOptions, UnsafeApiUrlError, type UpdateMemoryInput, type ValidatedPhoneMissionStart, type VideoAction, type VideoEditOptions, type VideoTimelineEntry, type VideoUnderstandOptions, type VideoUnderstandResult, type VoiceCloneOptions, type VoiceProvider, type VoiceRuntimeConnection, WARNING_THRESHOLD, WEB_SEARCH_TOOL, WEB_SEARCH_UNTRUSTED_PREFIX, type WatcherOptions, type WebSearchOptions, assertWithinBase, bridgeWakeErrorMessage, bridgeWakeLastSeenAgeMs, buildApiUrl, buildDefaultPersona, buildElksAudioMessage, buildElksByeMessage, buildElksHandshakeMessages, buildElksInterruptMessage, buildElksListeningMessage, buildElksSendingMessage, buildInboundSecurityAdvisory, buildOpenAIRealtimeUrl, buildPhoneTransportConfig, buildRealtimeInstructions, buildRealtimeSessionConfig, buildRealtimeToolGuidance, buildTwilioClearMessage, buildTwilioMarkMessage, buildTwilioMediaMessage, buildTwilioSayTwiML, buildTwilioSignature, buildTwilioStreamTwiML, callTelegramApi, classifyEmailRoute, classifyPhoneNumberRisk, classifyResumeError, clearMediaCapabilityCache, closeDatabase, composeBridgeWakePrompt, createRealtimeTransport, createTestDatabase, createToolExecutor, debug, debugWarn, deleteTelegramWebhook, detectBinary, ensureDataDir, escapeXml, extractEmailAddress, extractVerificationCode, flushTelemetry, forgetHostSession, formatOperatorQueryTelegramMessage, getDatabase, getDatetime, getMediaCapabilities, getOperatorEmail, getSmsProvider, getTelegramChat, getTelegramMe, getTelegramUpdates, getTelegramWebhookInfo, getVoiceProvider, hostSessionStoragePath, inferPhoneRegion, invalidateSkillCache, isInternalEmail, isLoopbackMailHost, isOperatorReplySender, isPhoneRegionAllowed, isSessionFresh, isTelegramChatAllowed, isTelegramStopCommand, isValidPhoneNumber, listSkills, listVoiceProviders, loadAgentPersona, loadHostSession, loadSkill, mapProviderSmsStatus, nextTelegramOffset, normalizeAddress, normalizePhoneNumber, normalizeSubject, operatorPrefsStoragePath, operatorQuerySubject, parseElksRealtimeMessage, parseEmail, parseGoogleVoiceSms, parseOperatorQueryReply, parseTelegramOperatorReply, parseTelegramUpdate, parseTwilioRealtimeMessage, personaPathFor, planBridgeWake, pollForOperatorAnswer, recallMemory, recordToolCall, redactBotToken, redactObject, redactPhoneTransportConfig, redactSecret, redactSmsConfig, redactTelegramConfig, registerVoiceProvider, renderSkillAsPrompt, requireBinary, requireWhisperModel, resolveCallbackPolicy, resolveConfig, resolveExtensionPolicy, resolveTlsRejectUnauthorized, resolveVoiceRuntime, safeJoin, sanitizeEmail, saveAgentPersona, saveConfig, saveHostSession, saveUserSkill, scanOutboundEmail, scoreEmail, searchSkills, sendTelegramMessage, setOperatorEmail, setTelegramWebhook, setTelemetryVersion, shouldSkipBridgeWakeForLiveOperator, splitTelegramMessage, startRelayBridge, stem, stripTelegramMarkdown, threadIdFor, tokenize, tryJoin, userSkillsDir, validateApiUrl, validatePhoneMissionPolicy, validatePhoneMissionStart, validatePhoneTransportProfile, validateSkill, validateTwilioSignature, webSearch };
package/dist/index.d.ts CHANGED
@@ -229,6 +229,22 @@ interface AgenticMailConfig {
229
229
  * `config.json`. Optional — no other feature depends on it.
230
230
  */
231
231
  openaiApiKey?: string;
232
+ /**
233
+ * v0.9.93 — voice-runtime provider keys. Each is a thin Bearer-token
234
+ * for a provider's realtime API; required only when that provider
235
+ * is selected as the runtime for a call. New providers register
236
+ * themselves in `packages/core/src/phone/voice-providers/` and
237
+ * declare which key field they consume — this record is the central
238
+ * pool. Read from per-provider env vars (e.g. `XAI_API_KEY`) at boot.
239
+ */
240
+ voiceProviderKeys?: Record<string, string>;
241
+ /**
242
+ * v0.9.93 — default voice-runtime provider id for phone missions
243
+ * that don't pin one on their own policy. `'openai'` (the existing
244
+ * default) or any provider registered in `voice-providers/`.
245
+ * Read from `AGENTICMAIL_VOICE_RUNTIME` env var or `config.json`.
246
+ */
247
+ voiceRuntime?: string;
232
248
  masterKey: string;
233
249
  dataDir: string;
234
250
  }
@@ -3824,6 +3840,127 @@ declare class RealtimeVoiceBridge {
3824
3840
  private safeSend;
3825
3841
  }
3826
3842
 
3843
+ /**
3844
+ * Voice-runtime provider plugin interface.
3845
+ *
3846
+ * Each backend (OpenAI Realtime, Grok Voice Agent, future Anthropic
3847
+ * realtime, Cartesia, ElevenLabs ConvAI, etc.) lives in its own file
3848
+ * under `packages/core/src/phone/voice-providers/` and registers
3849
+ * itself with the registry by calling {@link registerVoiceProvider}
3850
+ * at module load.
3851
+ *
3852
+ * Adding a new provider is meant to be a literal FILE DROP:
3853
+ *
3854
+ * 1. Create `voice-providers/<id>.ts` exporting a {@link VoiceProvider}.
3855
+ * 2. Add a single `import './<id>.js';` line to `voice-providers/index.ts`
3856
+ * so the side-effect registration runs.
3857
+ * 3. (Optional) document the env var the provider expects.
3858
+ *
3859
+ * No other file in the codebase needs to know about the new provider —
3860
+ * the realtime bridge looks providers up by id through the registry.
3861
+ *
3862
+ * Currently every supported provider is an OpenAI-Realtime-compatible
3863
+ * WebSocket. If a future provider diverges enough to need its own wire
3864
+ * protocol (custom event shape, gRPC, WebRTC SDP, etc.), the seam to
3865
+ * extend is here: add `buildSessionUpdate` / `parseInboundEvent` /
3866
+ * etc. hooks to {@link VoiceProvider}, then make `realtime-bridge.ts`
3867
+ * route through them instead of speaking OpenAI Realtime directly.
3868
+ */
3869
+ /**
3870
+ * One voice-runtime provider. Carries enough information for the
3871
+ * bridge to open the right WebSocket with the right auth + model.
3872
+ */
3873
+ interface VoiceProvider {
3874
+ /**
3875
+ * Stable identifier used in mission policy / config (`'openai'`,
3876
+ * `'grok'`, …). Keep lowercase, no spaces — this is what operators
3877
+ * type into `AGENTICMAIL_VOICE_RUNTIME=` or pass via mission policy.
3878
+ */
3879
+ id: string;
3880
+ /** Human-readable display name for logs + the web UI. */
3881
+ displayName: string;
3882
+ /** WebSocket base URL (the bridge appends `?model=…`). */
3883
+ websocketBaseUrl: string;
3884
+ /**
3885
+ * Default model when the caller doesn't pin one. Sent as the
3886
+ * `?model=…` query string AND echoed in the session.update.
3887
+ */
3888
+ defaultModel: string;
3889
+ /**
3890
+ * The env var the operator sets for this provider's API key
3891
+ * (`OPENAI_API_KEY`, `XAI_API_KEY`, …). The bootstrap / config
3892
+ * loader reads from this name and stores into
3893
+ * `AgenticMailConfig.voiceProviderKeys[<id>]`. Used in the
3894
+ * "you didn't set the key" error message too.
3895
+ */
3896
+ apiKeyEnvVar: string;
3897
+ /**
3898
+ * Optional fallback config-field name. When the provider's API key
3899
+ * has a long-standing dedicated config field (e.g. OpenAI's
3900
+ * `config.openaiApiKey`), this lets the resolver check that field
3901
+ * BEFORE looking in the generic `voiceProviderKeys` map — so
3902
+ * existing installs don't need to migrate. Leave undefined for
3903
+ * new providers.
3904
+ */
3905
+ apiKeyConfigField?: 'openaiApiKey';
3906
+ /**
3907
+ * Per-provider notes that surface in error / boot-log messages.
3908
+ * Optional — defaults are fine for the standard providers.
3909
+ */
3910
+ description?: string;
3911
+ }
3912
+ /**
3913
+ * The bridge needs all the inputs needed to open a session in one
3914
+ * resolved struct — URL with model encoded, the API key, the source
3915
+ * for logging. {@link resolveVoiceRuntime} produces this.
3916
+ */
3917
+ interface VoiceRuntimeConnection {
3918
+ providerId: string;
3919
+ providerDisplayName: string;
3920
+ /** Full WebSocket URL including `?model=…`. */
3921
+ url: string;
3922
+ /** Resolved model name (also passed in the URL). */
3923
+ model: string;
3924
+ /** Bearer token for the `Authorization` header. */
3925
+ apiKey: string;
3926
+ /** Human-readable source of the key, for boot logs only (e.g. `"env XAI_API_KEY"`). */
3927
+ apiKeySource: string;
3928
+ }
3929
+
3930
+ /**
3931
+ * Voice-provider registry — drop-in plugin discovery.
3932
+ *
3933
+ * Providers register themselves at module-load time via
3934
+ * {@link registerVoiceProvider}. The barrel `voice-providers/index.ts`
3935
+ * imports each provider file for its side effect, populating this map
3936
+ * before any caller asks for one.
3937
+ *
3938
+ * No reflection, no filesystem scan, no decorator magic — adding a
3939
+ * provider is "create a file + add one import line". That gives us
3940
+ * both first-class TypeScript types AND the file-drop ergonomics.
3941
+ */
3942
+
3943
+ /**
3944
+ * Register a provider. Called once per file at module load. Throws on
3945
+ * duplicate id so an accidental copy-paste collision is loud, not
3946
+ * silently overriding.
3947
+ */
3948
+ declare function registerVoiceProvider(provider: VoiceProvider): void;
3949
+ /** All registered providers — for `agenticmail voice list` / web UI menus. */
3950
+ declare function listVoiceProviders(): VoiceProvider[];
3951
+ /** Look up a provider by id. Returns undefined for unknown ids. */
3952
+ declare function getVoiceProvider(id: string): VoiceProvider | undefined;
3953
+ /**
3954
+ * Resolve a provider id + the runtime's config / overrides into the
3955
+ * connection struct the bridge consumes (URL with model, api key,
3956
+ * source). Throws if the provider id is unknown or its API key isn't
3957
+ * configured — the realtime-ws layer turns the throw into a clear
3958
+ * startup error instead of a mid-call surprise.
3959
+ */
3960
+ declare function resolveVoiceRuntime(providerId: string | undefined, config: AgenticMailConfig, options?: {
3961
+ model?: string;
3962
+ }): VoiceRuntimeConnection;
3963
+
3827
3964
  type PhoneTransportProvider = '46elks' | 'twilio';
3828
3965
  /** Providers that support starting outbound call-control missions. */
3829
3966
  declare const PHONE_CALL_CONTROL_PROVIDERS: readonly PhoneTransportProvider[];
@@ -6248,4 +6385,4 @@ declare function loadAgentPersona(agentName: string): string;
6248
6385
  */
6249
6386
  declare function saveAgentPersona(agentName: string, content: string): string;
6250
6387
 
6251
- export { AGENT_ROLES, AGENT_STATE_ROOT, ASK_OPERATOR_TOOL, AccountManager, type AddressInfo, type Agent, AgentDeletionService, type AgentMemoryEntry, type AgentMemoryFields, AgentMemoryManager, type AgentMemoryOptions, type AgentMemoryRead, AgentMemoryStore, type AgentRole, AgenticMailClient, type AgenticMailClientOptions, type AgenticMailConfig, type ArchiveAndDeleteOptions, type ArchivedEmail, type Attachment, type AttachmentAdvisory, type AudioAction, type AudioEditOptions, BRIDGE_OPERATOR_LIVE_WINDOW_MS, type BridgeMailContext, type BridgeWakeError, type BridgeWakePromptArgs, type BridgeWakeResult, type BridgeWakeRoute, type CachedMessage, CloudflareClient, type CreateAgentOptions, type CreateMemoryInput, DEFAULT_AGENT_NAME, DEFAULT_AGENT_ROLE, DEFAULT_CALLBACK_POLICY, DEFAULT_EXTENSION_POLICY, DEFAULT_REALTIME_AUDIO_FORMAT, DEFAULT_REALTIME_MODEL, DEFAULT_REALTIME_VOICE, DEFAULT_SESSION_MAX_AGE_MS, DEFAULT_WEB_SEARCH_ENDPOINT, DNSConfigurator, type Database, type DeletionReport, type DeletionSummary, DependencyChecker, DependencyInstaller, type DependencyStatus, type DnsRecord, type DnsSetupResult, type DomainInfo, DomainManager, type DomainModeConfig, type DomainPurchaseResult, DomainPurchaser, type DomainSearchResult, type DomainSetupResult, ELKS_REALTIME_AUDIO_FORMATS, ELKS_REALTIME_WS_PATH, END_CALL_TOOL, EXTEND_CALL_TIME_TOOL, type ElksRealtimeAudioFormat, type ElksRealtimeAudioMessage, type ElksRealtimeByeMessage, type ElksRealtimeHelloMessage, type ElksRealtimeInboundMessage, type ElksRealtimeOutboundMessage, ElksRealtimeTransport, type EmailEnvelope, type EmailRouteAction, type EmailRouteClass, type EmailRouteClassification, type EmailRouteInput, EmailSearchIndex, type FolderInfo, GET_CALL_STATUS_TOOL, GET_DATETIME_TOOL, type GatewayConfig, GatewayManager, type GatewayManagerOptions, type GatewayMode, type GatewayStatus, type GetDatetimeOptions, type GetUpdatesOptions, type HostName, type HostSession, type HostSessionResumeMode, type ImageAction, type ImageEditOptions, type InboundEmail, type InboundSmsEvent, type InboxEvent, type InboxExpungeEvent, type InboxFlagsEvent, type InboxNewEvent, InboxWatcher, type InboxWatcherOptions, type InstallProgress, LOAD_SKILL_TOOL, type LinkAdvisory, type LocalSmtpConfig, MEMORY_CATEGORIES, MailReceiver, type MailReceiverOptions, MailSender, type MailSenderOptions, type MailboxInfo, type MediaBinary, type MediaCapability, type MediaCapabilityReport, type MediaFileResult, type MediaInfoResult, MediaManager, type MediaManagerOptions, type MediaStreamInfo, type MemoryCategory, type MemoryImportance, type MemoryQueryOptions, type MemoryRecaller, MemorySearchIndex, type MemorySource, type MemoryStats, OPENAI_REALTIME_URL, OPERATOR_QUERY_POLL_INTERVAL_MS, OPERATOR_QUERY_SUBJECT_TAG, OPERATOR_QUERY_TIMEOUT_MS, OPERATOR_QUERY_TIMEOUT_SENTINEL, type OpenClawPhoneMissionPolicy, type OperatorQueryNotificationInput, type OperatorQueryPollOptions, type OperatorQueryUrgency, type OperatorReplyKind, type OutboundCategory, type OutboundScanInput, type OutboundScanResult, type OutboundWarning, PERSONA_FILENAME, PHONE_CALLBACK_MAX_DELAY_SECONDS, PHONE_CALLBACK_MIN_DELAY_SECONDS, PHONE_CALL_CONTROL_PROVIDERS, PHONE_MAX_CONCURRENT_MISSIONS, PHONE_MIN_WEBHOOK_SECRET_LENGTH, PHONE_MISSION_STATES, PHONE_RATE_LIMIT_PER_HOUR, PHONE_RATE_LIMIT_PER_MINUTE, PHONE_REGION_SCOPES, PHONE_SERVER_MAX_ATTEMPTS, PHONE_SERVER_MAX_CALLBACK_CHAIN, PHONE_SERVER_MAX_CALL_DURATION_SECONDS, PHONE_SERVER_MAX_COST_PER_MISSION, PHONE_SERVER_MAX_EXTENSION_REQUESTS_PER_CALL, PHONE_SERVER_MAX_EXTENSION_SECONDS_PER_REQUEST, PHONE_SERVER_MAX_TOTAL_EXTENSION_SECONDS, PHONE_TASK_MAX_LENGTH, type ParsedAttachment, type ParsedEmail, type ParsedOperatorReply, type ParsedSms, type ParsedTelegramMessage, PathTraversalError, type PhoneAlternativePolicy, type PhoneCallMission, type PhoneCallbackPolicy, type PhoneConfirmPolicy, type PhoneExtensionPolicy, PhoneManager, type PhoneMissionStartValidationResult, type PhoneMissionState, type PhoneMissionTranscriptEntry, type PhoneMissionValidationIssue, type PhoneMissionValidationResult, type PhoneNumberRisk, type PhoneOperatorQuery, PhoneRateLimitError, type PhoneRegionScope, type PhoneScheduledCallback, type PhoneTransportConfig, type PhoneTransportProfile, type PhoneTransportProvider, type PhoneTransportValidationResult, PhoneWebhookAuthError, type PhoneWebhookResult, type PlanBridgeWakeArgs, type PurchasedDomain, REALTIME_AUDIO_SAMPLE_RATE, REALTIME_MAX_AUDIO_FRAME_BASE64, REALTIME_TOOL_CALL_TIMEOUT_MS, REALTIME_TOOL_DEFINITIONS, RECALL_MEMORY_TOOL, REDACTED, RELAY_PRESETS, type RealtimeBridgePort, type RealtimeBridgeTranscriptEntry, type RealtimeInboundEvent, type RealtimeInstructionOptions, type RealtimeSessionConfigOptions, type RealtimeToolCall, type RealtimeToolDefinition, type RealtimeToolHandler, type RealtimeToolResult, type RealtimeTransportAdapter, type RealtimeTransportProvider, RealtimeVoiceBridge, type RealtimeVoiceBridgeOptions, RelayBridge, type RelayBridgeOptions, type RelayConfig, RelayGateway, type RelayProvider, type RelaySearchResult, type ResumeErrorClassificationOptions, SCHEDULE_CALLBACK_TOOL, SEARCH_EMAIL_TOOL, SEARCH_SKILLS_TOOL, SPAM_THRESHOLD, type SafeJoinOptions, type SanitizeDetection, type SanitizeResult, type ScheduledCallbackRequest, type SearchCriteria, type SearchableEmail, type SecurityAdvisory, type SendMailOptions, type SendResult, type SendResultWithRaw, type SendSmsInput, type SendSmsResult, type SendTelegramMessageOptions, type SendTelegramMessageResult, ServiceManager, type ServiceStatus, type SetWebhookOptions, type SetupConfig, SetupManager, type SetupResult, type Severity, type Skill, type SkillCategory, type SkillContext, type SkillExitStrategy, type SkillSummary, type SkillTactic, type SkillValidationError, type SmsConfig, SmsManager, type SmsMessage, SmsPoller, type SmsProvider, type SpamCategory, type SpamResult, type SpamRuleMatch, StalwartAdmin, type StalwartAdminOptions, type StalwartPrincipal, type StartPhoneCallOptions, type StartPhoneCallResult, type StartPhoneMissionInput, TELEGRAM_API_BASE, TELEGRAM_CHUNK_SIZE, TELEGRAM_MESSAGE_LIMIT, TELEGRAM_MIN_WEBHOOK_SECRET_LENGTH, TELEGRAM_OPERATOR_QUERY_TAG, TELEGRAM_STOP_WORDS, TELEGRAM_WEBHOOK_SECRET_RE, TELEPHONY_TRANSPORT_CAPABILITIES, TWILIO_MEDIA_SAMPLE_RATE, TWILIO_REALTIME_WS_PATH, TelegramApiError, type TelegramApiOptions, type TelegramBotInfo, type TelegramChatType, type TelegramConfig, TelegramManager, type TelegramMessage, type TelegramMode, type TelephonyTransportCapability, ThreadCache, type ThreadCacheEntry, type ThreadCacheOptions, type ThreadIdInput, type ToolExecutor, type TtsGenerateOptions, type TunnelConfig, TunnelManager, type TwilioConnectedMessage, type TwilioMarkMessage, type TwilioMediaMessage, type TwilioRealtimeInboundMessage, type TwilioRealtimeOutboundMessage, TwilioRealtimeTransport, type TwilioStartMessage, type TwilioStopMessage, type TwilioStreamTwiMLOptions, UnsafeApiUrlError, type UpdateMemoryInput, type ValidatedPhoneMissionStart, type VideoAction, type VideoEditOptions, type VideoTimelineEntry, type VideoUnderstandOptions, type VideoUnderstandResult, type VoiceCloneOptions, WARNING_THRESHOLD, WEB_SEARCH_TOOL, WEB_SEARCH_UNTRUSTED_PREFIX, type WatcherOptions, type WebSearchOptions, assertWithinBase, bridgeWakeErrorMessage, bridgeWakeLastSeenAgeMs, buildApiUrl, buildDefaultPersona, buildElksAudioMessage, buildElksByeMessage, buildElksHandshakeMessages, buildElksInterruptMessage, buildElksListeningMessage, buildElksSendingMessage, buildInboundSecurityAdvisory, buildOpenAIRealtimeUrl, buildPhoneTransportConfig, buildRealtimeInstructions, buildRealtimeSessionConfig, buildRealtimeToolGuidance, buildTwilioClearMessage, buildTwilioMarkMessage, buildTwilioMediaMessage, buildTwilioSayTwiML, buildTwilioSignature, buildTwilioStreamTwiML, callTelegramApi, classifyEmailRoute, classifyPhoneNumberRisk, classifyResumeError, clearMediaCapabilityCache, closeDatabase, composeBridgeWakePrompt, createRealtimeTransport, createTestDatabase, createToolExecutor, debug, debugWarn, deleteTelegramWebhook, detectBinary, ensureDataDir, escapeXml, extractEmailAddress, extractVerificationCode, flushTelemetry, forgetHostSession, formatOperatorQueryTelegramMessage, getDatabase, getDatetime, getMediaCapabilities, getOperatorEmail, getSmsProvider, getTelegramChat, getTelegramMe, getTelegramUpdates, getTelegramWebhookInfo, hostSessionStoragePath, inferPhoneRegion, invalidateSkillCache, isInternalEmail, isLoopbackMailHost, isOperatorReplySender, isPhoneRegionAllowed, isSessionFresh, isTelegramChatAllowed, isTelegramStopCommand, isValidPhoneNumber, listSkills, loadAgentPersona, loadHostSession, loadSkill, mapProviderSmsStatus, nextTelegramOffset, normalizeAddress, normalizePhoneNumber, normalizeSubject, operatorPrefsStoragePath, operatorQuerySubject, parseElksRealtimeMessage, parseEmail, parseGoogleVoiceSms, parseOperatorQueryReply, parseTelegramOperatorReply, parseTelegramUpdate, parseTwilioRealtimeMessage, personaPathFor, planBridgeWake, pollForOperatorAnswer, recallMemory, recordToolCall, redactBotToken, redactObject, redactPhoneTransportConfig, redactSecret, redactSmsConfig, redactTelegramConfig, renderSkillAsPrompt, requireBinary, requireWhisperModel, resolveCallbackPolicy, resolveConfig, resolveExtensionPolicy, resolveTlsRejectUnauthorized, safeJoin, sanitizeEmail, saveAgentPersona, saveConfig, saveHostSession, saveUserSkill, scanOutboundEmail, scoreEmail, searchSkills, sendTelegramMessage, setOperatorEmail, setTelegramWebhook, setTelemetryVersion, shouldSkipBridgeWakeForLiveOperator, splitTelegramMessage, startRelayBridge, stem, stripTelegramMarkdown, threadIdFor, tokenize, tryJoin, userSkillsDir, validateApiUrl, validatePhoneMissionPolicy, validatePhoneMissionStart, validatePhoneTransportProfile, validateSkill, validateTwilioSignature, webSearch };
6388
+ export { AGENT_ROLES, AGENT_STATE_ROOT, ASK_OPERATOR_TOOL, AccountManager, type AddressInfo, type Agent, AgentDeletionService, type AgentMemoryEntry, type AgentMemoryFields, AgentMemoryManager, type AgentMemoryOptions, type AgentMemoryRead, AgentMemoryStore, type AgentRole, AgenticMailClient, type AgenticMailClientOptions, type AgenticMailConfig, type ArchiveAndDeleteOptions, type ArchivedEmail, type Attachment, type AttachmentAdvisory, type AudioAction, type AudioEditOptions, BRIDGE_OPERATOR_LIVE_WINDOW_MS, type BridgeMailContext, type BridgeWakeError, type BridgeWakePromptArgs, type BridgeWakeResult, type BridgeWakeRoute, type CachedMessage, CloudflareClient, type CreateAgentOptions, type CreateMemoryInput, DEFAULT_AGENT_NAME, DEFAULT_AGENT_ROLE, DEFAULT_CALLBACK_POLICY, DEFAULT_EXTENSION_POLICY, DEFAULT_REALTIME_AUDIO_FORMAT, DEFAULT_REALTIME_MODEL, DEFAULT_REALTIME_VOICE, DEFAULT_SESSION_MAX_AGE_MS, DEFAULT_WEB_SEARCH_ENDPOINT, DNSConfigurator, type Database, type DeletionReport, type DeletionSummary, DependencyChecker, DependencyInstaller, type DependencyStatus, type DnsRecord, type DnsSetupResult, type DomainInfo, DomainManager, type DomainModeConfig, type DomainPurchaseResult, DomainPurchaser, type DomainSearchResult, type DomainSetupResult, ELKS_REALTIME_AUDIO_FORMATS, ELKS_REALTIME_WS_PATH, END_CALL_TOOL, EXTEND_CALL_TIME_TOOL, type ElksRealtimeAudioFormat, type ElksRealtimeAudioMessage, type ElksRealtimeByeMessage, type ElksRealtimeHelloMessage, type ElksRealtimeInboundMessage, type ElksRealtimeOutboundMessage, ElksRealtimeTransport, type EmailEnvelope, type EmailRouteAction, type EmailRouteClass, type EmailRouteClassification, type EmailRouteInput, EmailSearchIndex, type FolderInfo, GET_CALL_STATUS_TOOL, GET_DATETIME_TOOL, type GatewayConfig, GatewayManager, type GatewayManagerOptions, type GatewayMode, type GatewayStatus, type GetDatetimeOptions, type GetUpdatesOptions, type HostName, type HostSession, type HostSessionResumeMode, type ImageAction, type ImageEditOptions, type InboundEmail, type InboundSmsEvent, type InboxEvent, type InboxExpungeEvent, type InboxFlagsEvent, type InboxNewEvent, InboxWatcher, type InboxWatcherOptions, type InstallProgress, LOAD_SKILL_TOOL, type LinkAdvisory, type LocalSmtpConfig, MEMORY_CATEGORIES, MailReceiver, type MailReceiverOptions, MailSender, type MailSenderOptions, type MailboxInfo, type MediaBinary, type MediaCapability, type MediaCapabilityReport, type MediaFileResult, type MediaInfoResult, MediaManager, type MediaManagerOptions, type MediaStreamInfo, type MemoryCategory, type MemoryImportance, type MemoryQueryOptions, type MemoryRecaller, MemorySearchIndex, type MemorySource, type MemoryStats, OPENAI_REALTIME_URL, OPERATOR_QUERY_POLL_INTERVAL_MS, OPERATOR_QUERY_SUBJECT_TAG, OPERATOR_QUERY_TIMEOUT_MS, OPERATOR_QUERY_TIMEOUT_SENTINEL, type OpenClawPhoneMissionPolicy, type OperatorQueryNotificationInput, type OperatorQueryPollOptions, type OperatorQueryUrgency, type OperatorReplyKind, type OutboundCategory, type OutboundScanInput, type OutboundScanResult, type OutboundWarning, PERSONA_FILENAME, PHONE_CALLBACK_MAX_DELAY_SECONDS, PHONE_CALLBACK_MIN_DELAY_SECONDS, PHONE_CALL_CONTROL_PROVIDERS, PHONE_MAX_CONCURRENT_MISSIONS, PHONE_MIN_WEBHOOK_SECRET_LENGTH, PHONE_MISSION_STATES, PHONE_RATE_LIMIT_PER_HOUR, PHONE_RATE_LIMIT_PER_MINUTE, PHONE_REGION_SCOPES, PHONE_SERVER_MAX_ATTEMPTS, PHONE_SERVER_MAX_CALLBACK_CHAIN, PHONE_SERVER_MAX_CALL_DURATION_SECONDS, PHONE_SERVER_MAX_COST_PER_MISSION, PHONE_SERVER_MAX_EXTENSION_REQUESTS_PER_CALL, PHONE_SERVER_MAX_EXTENSION_SECONDS_PER_REQUEST, PHONE_SERVER_MAX_TOTAL_EXTENSION_SECONDS, PHONE_TASK_MAX_LENGTH, type ParsedAttachment, type ParsedEmail, type ParsedOperatorReply, type ParsedSms, type ParsedTelegramMessage, PathTraversalError, type PhoneAlternativePolicy, type PhoneCallMission, type PhoneCallbackPolicy, type PhoneConfirmPolicy, type PhoneExtensionPolicy, PhoneManager, type PhoneMissionStartValidationResult, type PhoneMissionState, type PhoneMissionTranscriptEntry, type PhoneMissionValidationIssue, type PhoneMissionValidationResult, type PhoneNumberRisk, type PhoneOperatorQuery, PhoneRateLimitError, type PhoneRegionScope, type PhoneScheduledCallback, type PhoneTransportConfig, type PhoneTransportProfile, type PhoneTransportProvider, type PhoneTransportValidationResult, PhoneWebhookAuthError, type PhoneWebhookResult, type PlanBridgeWakeArgs, type PurchasedDomain, REALTIME_AUDIO_SAMPLE_RATE, REALTIME_MAX_AUDIO_FRAME_BASE64, REALTIME_TOOL_CALL_TIMEOUT_MS, REALTIME_TOOL_DEFINITIONS, RECALL_MEMORY_TOOL, REDACTED, RELAY_PRESETS, type RealtimeBridgePort, type RealtimeBridgeTranscriptEntry, type RealtimeInboundEvent, type RealtimeInstructionOptions, type RealtimeSessionConfigOptions, type RealtimeToolCall, type RealtimeToolDefinition, type RealtimeToolHandler, type RealtimeToolResult, type RealtimeTransportAdapter, type RealtimeTransportProvider, RealtimeVoiceBridge, type RealtimeVoiceBridgeOptions, RelayBridge, type RelayBridgeOptions, type RelayConfig, RelayGateway, type RelayProvider, type RelaySearchResult, type ResumeErrorClassificationOptions, SCHEDULE_CALLBACK_TOOL, SEARCH_EMAIL_TOOL, SEARCH_SKILLS_TOOL, SPAM_THRESHOLD, type SafeJoinOptions, type SanitizeDetection, type SanitizeResult, type ScheduledCallbackRequest, type SearchCriteria, type SearchableEmail, type SecurityAdvisory, type SendMailOptions, type SendResult, type SendResultWithRaw, type SendSmsInput, type SendSmsResult, type SendTelegramMessageOptions, type SendTelegramMessageResult, ServiceManager, type ServiceStatus, type SetWebhookOptions, type SetupConfig, SetupManager, type SetupResult, type Severity, type Skill, type SkillCategory, type SkillContext, type SkillExitStrategy, type SkillSummary, type SkillTactic, type SkillValidationError, type SmsConfig, SmsManager, type SmsMessage, SmsPoller, type SmsProvider, type SpamCategory, type SpamResult, type SpamRuleMatch, StalwartAdmin, type StalwartAdminOptions, type StalwartPrincipal, type StartPhoneCallOptions, type StartPhoneCallResult, type StartPhoneMissionInput, TELEGRAM_API_BASE, TELEGRAM_CHUNK_SIZE, TELEGRAM_MESSAGE_LIMIT, TELEGRAM_MIN_WEBHOOK_SECRET_LENGTH, TELEGRAM_OPERATOR_QUERY_TAG, TELEGRAM_STOP_WORDS, TELEGRAM_WEBHOOK_SECRET_RE, TELEPHONY_TRANSPORT_CAPABILITIES, TWILIO_MEDIA_SAMPLE_RATE, TWILIO_REALTIME_WS_PATH, TelegramApiError, type TelegramApiOptions, type TelegramBotInfo, type TelegramChatType, type TelegramConfig, TelegramManager, type TelegramMessage, type TelegramMode, type TelephonyTransportCapability, ThreadCache, type ThreadCacheEntry, type ThreadCacheOptions, type ThreadIdInput, type ToolExecutor, type TtsGenerateOptions, type TunnelConfig, TunnelManager, type TwilioConnectedMessage, type TwilioMarkMessage, type TwilioMediaMessage, type TwilioRealtimeInboundMessage, type TwilioRealtimeOutboundMessage, TwilioRealtimeTransport, type TwilioStartMessage, type TwilioStopMessage, type TwilioStreamTwiMLOptions, UnsafeApiUrlError, type UpdateMemoryInput, type ValidatedPhoneMissionStart, type VideoAction, type VideoEditOptions, type VideoTimelineEntry, type VideoUnderstandOptions, type VideoUnderstandResult, type VoiceCloneOptions, type VoiceProvider, type VoiceRuntimeConnection, WARNING_THRESHOLD, WEB_SEARCH_TOOL, WEB_SEARCH_UNTRUSTED_PREFIX, type WatcherOptions, type WebSearchOptions, assertWithinBase, bridgeWakeErrorMessage, bridgeWakeLastSeenAgeMs, buildApiUrl, buildDefaultPersona, buildElksAudioMessage, buildElksByeMessage, buildElksHandshakeMessages, buildElksInterruptMessage, buildElksListeningMessage, buildElksSendingMessage, buildInboundSecurityAdvisory, buildOpenAIRealtimeUrl, buildPhoneTransportConfig, buildRealtimeInstructions, buildRealtimeSessionConfig, buildRealtimeToolGuidance, buildTwilioClearMessage, buildTwilioMarkMessage, buildTwilioMediaMessage, buildTwilioSayTwiML, buildTwilioSignature, buildTwilioStreamTwiML, callTelegramApi, classifyEmailRoute, classifyPhoneNumberRisk, classifyResumeError, clearMediaCapabilityCache, closeDatabase, composeBridgeWakePrompt, createRealtimeTransport, createTestDatabase, createToolExecutor, debug, debugWarn, deleteTelegramWebhook, detectBinary, ensureDataDir, escapeXml, extractEmailAddress, extractVerificationCode, flushTelemetry, forgetHostSession, formatOperatorQueryTelegramMessage, getDatabase, getDatetime, getMediaCapabilities, getOperatorEmail, getSmsProvider, getTelegramChat, getTelegramMe, getTelegramUpdates, getTelegramWebhookInfo, getVoiceProvider, hostSessionStoragePath, inferPhoneRegion, invalidateSkillCache, isInternalEmail, isLoopbackMailHost, isOperatorReplySender, isPhoneRegionAllowed, isSessionFresh, isTelegramChatAllowed, isTelegramStopCommand, isValidPhoneNumber, listSkills, listVoiceProviders, loadAgentPersona, loadHostSession, loadSkill, mapProviderSmsStatus, nextTelegramOffset, normalizeAddress, normalizePhoneNumber, normalizeSubject, operatorPrefsStoragePath, operatorQuerySubject, parseElksRealtimeMessage, parseEmail, parseGoogleVoiceSms, parseOperatorQueryReply, parseTelegramOperatorReply, parseTelegramUpdate, parseTwilioRealtimeMessage, personaPathFor, planBridgeWake, pollForOperatorAnswer, recallMemory, recordToolCall, redactBotToken, redactObject, redactPhoneTransportConfig, redactSecret, redactSmsConfig, redactTelegramConfig, registerVoiceProvider, renderSkillAsPrompt, requireBinary, requireWhisperModel, resolveCallbackPolicy, resolveConfig, resolveExtensionPolicy, resolveTlsRejectUnauthorized, resolveVoiceRuntime, safeJoin, sanitizeEmail, saveAgentPersona, saveConfig, saveHostSession, saveUserSkill, scanOutboundEmail, scoreEmail, searchSkills, sendTelegramMessage, setOperatorEmail, setTelegramWebhook, setTelemetryVersion, shouldSkipBridgeWakeForLiveOperator, splitTelegramMessage, startRelayBridge, stem, stripTelegramMarkdown, threadIdFor, tokenize, tryJoin, userSkillsDir, validateApiUrl, validatePhoneMissionPolicy, validatePhoneMissionStart, validatePhoneTransportProfile, validateSkill, validateTwilioSignature, webSearch };
package/dist/index.js CHANGED
@@ -920,6 +920,13 @@ function resolveConfig(overrides) {
920
920
  dataDir: env.AGENTICMAIL_DATA_DIR?.replace(/^~(?=\/|$)/, homedir()) ?? DEFAULT_CONFIG.dataDir
921
921
  };
922
922
  if (env.OPENAI_API_KEY) config.openaiApiKey = env.OPENAI_API_KEY;
923
+ if (env.XAI_API_KEY) {
924
+ config.voiceProviderKeys = config.voiceProviderKeys ?? {};
925
+ config.voiceProviderKeys.grok = env.XAI_API_KEY;
926
+ }
927
+ if (env.AGENTICMAIL_VOICE_RUNTIME && env.AGENTICMAIL_VOICE_RUNTIME.trim()) {
928
+ config.voiceRuntime = env.AGENTICMAIL_VOICE_RUNTIME.trim();
929
+ }
923
930
  const configPath = join(config.dataDir, "config.json");
924
931
  if (existsSync(configPath)) {
925
932
  try {
@@ -10530,6 +10537,94 @@ function withTimeout(promise, ms) {
10530
10537
  return Promise.race([promise, timeout]).finally(() => clearTimeout(timer));
10531
10538
  }
10532
10539
 
10540
+ // src/phone/voice-providers/registry.ts
10541
+ var PROVIDERS2 = /* @__PURE__ */ new Map();
10542
+ function registerVoiceProvider(provider) {
10543
+ if (PROVIDERS2.has(provider.id)) {
10544
+ throw new Error(`Voice provider "${provider.id}" registered twice \u2014 id collision.`);
10545
+ }
10546
+ PROVIDERS2.set(provider.id, provider);
10547
+ }
10548
+ function listVoiceProviders() {
10549
+ return Array.from(PROVIDERS2.values());
10550
+ }
10551
+ function getVoiceProvider(id) {
10552
+ return PROVIDERS2.get(id);
10553
+ }
10554
+ function resolveVoiceRuntime(providerId, config, options = {}) {
10555
+ const id = (providerId || "openai").trim() || "openai";
10556
+ const provider = PROVIDERS2.get(id);
10557
+ if (!provider) {
10558
+ const known = Array.from(PROVIDERS2.keys()).join(", ") || "(none registered)";
10559
+ throw new Error(
10560
+ `Unknown voice runtime "${id}". Known providers: ${known}. Add a new one by dropping a file into packages/core/src/phone/voice-providers/.`
10561
+ );
10562
+ }
10563
+ let apiKey = "";
10564
+ let apiKeySource = "";
10565
+ if (provider.apiKeyConfigField) {
10566
+ const legacy = config[provider.apiKeyConfigField];
10567
+ if (legacy && legacy.trim()) {
10568
+ apiKey = legacy.trim();
10569
+ apiKeySource = `config.${provider.apiKeyConfigField}`;
10570
+ }
10571
+ }
10572
+ if (!apiKey) {
10573
+ const fromMap = config.voiceProviderKeys?.[provider.id];
10574
+ if (fromMap && fromMap.trim()) {
10575
+ apiKey = fromMap.trim();
10576
+ apiKeySource = `config.voiceProviderKeys.${provider.id}`;
10577
+ }
10578
+ }
10579
+ if (!apiKey) {
10580
+ const fromEnv = process.env[provider.apiKeyEnvVar];
10581
+ if (fromEnv && fromEnv.trim()) {
10582
+ apiKey = fromEnv.trim();
10583
+ apiKeySource = `env ${provider.apiKeyEnvVar}`;
10584
+ }
10585
+ }
10586
+ if (!apiKey) {
10587
+ throw new Error(
10588
+ `Voice provider "${provider.id}" (${provider.displayName}) selected, but no API key is configured. Set ${provider.apiKeyEnvVar} in your environment or save it to ~/.agenticmail/config.json under voiceProviderKeys.${provider.id}.`
10589
+ );
10590
+ }
10591
+ const model = options.model && options.model.trim() || provider.defaultModel;
10592
+ const url = `${provider.websocketBaseUrl}?model=${encodeURIComponent(model)}`;
10593
+ return {
10594
+ providerId: provider.id,
10595
+ providerDisplayName: provider.displayName,
10596
+ url,
10597
+ model,
10598
+ apiKey,
10599
+ apiKeySource
10600
+ };
10601
+ }
10602
+
10603
+ // src/phone/voice-providers/openai.ts
10604
+ registerVoiceProvider({
10605
+ id: "openai",
10606
+ displayName: "OpenAI Realtime (gpt-realtime)",
10607
+ websocketBaseUrl: "wss://api.openai.com/v1/realtime",
10608
+ defaultModel: "gpt-realtime",
10609
+ apiKeyEnvVar: "OPENAI_API_KEY",
10610
+ // Legacy: the original config.json schema used a dedicated
10611
+ // `openaiApiKey` field for this key. The resolver checks that field
10612
+ // before the generic voiceProviderKeys map so existing installs
10613
+ // continue to work without migration.
10614
+ apiKeyConfigField: "openaiApiKey",
10615
+ description: "OpenAI Realtime (gpt-realtime). Default voice runtime; supports linear PCM @ 24 kHz (46elks) and G.711 \xB5-law @ 8 kHz (Twilio) without transcoding."
10616
+ });
10617
+
10618
+ // src/phone/voice-providers/grok.ts
10619
+ registerVoiceProvider({
10620
+ id: "grok",
10621
+ displayName: "xAI Grok Voice Agent",
10622
+ websocketBaseUrl: "wss://api.x.ai/v1/realtime",
10623
+ defaultModel: "grok-voice-latest",
10624
+ apiKeyEnvVar: "XAI_API_KEY",
10625
+ description: 'xAI Grok Voice Agent \u2014 OpenAI-Realtime-compatible WebSocket protocol; select via mission policy.voiceRuntime="grok" or env AGENTICMAIL_VOICE_RUNTIME=grok.'
10626
+ });
10627
+
10533
10628
  // src/telemetry.ts
10534
10629
  import { randomUUID as randomUUID2 } from "crypto";
10535
10630
  import { readFileSync as readFileSync2, writeFileSync as writeFileSync3, mkdirSync as mkdirSync3, existsSync as existsSync3 } from "fs";
@@ -14859,6 +14954,7 @@ export {
14859
14954
  getTelegramMe,
14860
14955
  getTelegramUpdates,
14861
14956
  getTelegramWebhookInfo,
14957
+ getVoiceProvider,
14862
14958
  hostSessionStoragePath,
14863
14959
  inferPhoneRegion,
14864
14960
  invalidateSkillCache,
@@ -14871,6 +14967,7 @@ export {
14871
14967
  isTelegramStopCommand,
14872
14968
  isValidPhoneNumber,
14873
14969
  listSkills,
14970
+ listVoiceProviders,
14874
14971
  loadAgentPersona,
14875
14972
  loadHostSession,
14876
14973
  loadSkill,
@@ -14899,6 +14996,7 @@ export {
14899
14996
  redactSecret,
14900
14997
  redactSmsConfig,
14901
14998
  redactTelegramConfig,
14999
+ registerVoiceProvider,
14902
15000
  renderSkillAsPrompt,
14903
15001
  requireBinary,
14904
15002
  requireWhisperModel,
@@ -14906,6 +15004,7 @@ export {
14906
15004
  resolveConfig,
14907
15005
  resolveExtensionPolicy,
14908
15006
  resolveTlsRejectUnauthorized,
15007
+ resolveVoiceRuntime,
14909
15008
  safeJoin,
14910
15009
  sanitizeEmail,
14911
15010
  saveAgentPersona,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agenticmail/core",
3
- "version": "0.9.38",
3
+ "version": "0.9.39",
4
4
  "description": "Core SDK for AgenticMail — email, SMS, and phone call-control for AI agents",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",