@agenticmail/core 0.9.38 → 0.9.40
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 +229 -3
- package/dist/index.d.cts +248 -6
- package/dist/index.d.ts +248 -6
- package/dist/index.js +223 -3
- package/package.json +1 -1
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,
|
|
@@ -1642,6 +1644,7 @@ __export(index_exports, {
|
|
|
1642
1644
|
personaPathFor: () => personaPathFor,
|
|
1643
1645
|
planBridgeWake: () => planBridgeWake,
|
|
1644
1646
|
pollForOperatorAnswer: () => pollForOperatorAnswer,
|
|
1647
|
+
readAgentPersonaFile: () => readAgentPersonaFile,
|
|
1645
1648
|
recallMemory: () => recallMemory,
|
|
1646
1649
|
recordToolCall: () => recordToolCall,
|
|
1647
1650
|
redactBotToken: () => redactBotToken,
|
|
@@ -1650,6 +1653,7 @@ __export(index_exports, {
|
|
|
1650
1653
|
redactSecret: () => redactSecret,
|
|
1651
1654
|
redactSmsConfig: () => redactSmsConfig,
|
|
1652
1655
|
redactTelegramConfig: () => redactTelegramConfig,
|
|
1656
|
+
registerVoiceProvider: () => registerVoiceProvider,
|
|
1653
1657
|
renderSkillAsPrompt: () => renderSkillAsPrompt,
|
|
1654
1658
|
requireBinary: () => requireBinary,
|
|
1655
1659
|
requireWhisperModel: () => requireWhisperModel,
|
|
@@ -1657,6 +1661,7 @@ __export(index_exports, {
|
|
|
1657
1661
|
resolveConfig: () => resolveConfig,
|
|
1658
1662
|
resolveExtensionPolicy: () => resolveExtensionPolicy,
|
|
1659
1663
|
resolveTlsRejectUnauthorized: () => resolveTlsRejectUnauthorized,
|
|
1664
|
+
resolveVoiceRuntime: () => resolveVoiceRuntime,
|
|
1660
1665
|
safeJoin: () => safeJoin,
|
|
1661
1666
|
sanitizeEmail: () => sanitizeEmail,
|
|
1662
1667
|
saveAgentPersona: () => saveAgentPersona,
|
|
@@ -1678,6 +1683,7 @@ __export(index_exports, {
|
|
|
1678
1683
|
threadIdFor: () => threadIdFor,
|
|
1679
1684
|
tokenize: () => tokenize,
|
|
1680
1685
|
tryJoin: () => tryJoin,
|
|
1686
|
+
updateAgentPersonaFrontmatter: () => updateAgentPersonaFrontmatter,
|
|
1681
1687
|
userSkillsDir: () => userSkillsDir,
|
|
1682
1688
|
validateApiUrl: () => validateApiUrl,
|
|
1683
1689
|
validatePhoneMissionPolicy: () => validatePhoneMissionPolicy,
|
|
@@ -2588,6 +2594,13 @@ function resolveConfig(overrides) {
|
|
|
2588
2594
|
dataDir: env.AGENTICMAIL_DATA_DIR?.replace(/^~(?=\/|$)/, (0, import_node_os.homedir)()) ?? DEFAULT_CONFIG.dataDir
|
|
2589
2595
|
};
|
|
2590
2596
|
if (env.OPENAI_API_KEY) config.openaiApiKey = env.OPENAI_API_KEY;
|
|
2597
|
+
if (env.XAI_API_KEY) {
|
|
2598
|
+
config.voiceProviderKeys = config.voiceProviderKeys ?? {};
|
|
2599
|
+
config.voiceProviderKeys.grok = env.XAI_API_KEY;
|
|
2600
|
+
}
|
|
2601
|
+
if (env.AGENTICMAIL_VOICE_RUNTIME && env.AGENTICMAIL_VOICE_RUNTIME.trim()) {
|
|
2602
|
+
config.voiceRuntime = env.AGENTICMAIL_VOICE_RUNTIME.trim();
|
|
2603
|
+
}
|
|
2591
2604
|
const configPath = (0, import_node_path.join)(config.dataDir, "config.json");
|
|
2592
2605
|
if ((0, import_node_fs.existsSync)(configPath)) {
|
|
2593
2606
|
try {
|
|
@@ -7802,7 +7815,14 @@ function validatePhoneMissionPolicy(policy) {
|
|
|
7802
7815
|
// manager) can read a concrete value without juggling undefined.
|
|
7803
7816
|
// Caller-omitted → DEFAULT_*. Caller-set → clamped to server caps.
|
|
7804
7817
|
extensionPolicy: resolveExtensionPolicy(policy.extensionPolicy),
|
|
7805
|
-
callbackPolicy: resolveCallbackPolicy(policy.callbackPolicy)
|
|
7818
|
+
callbackPolicy: resolveCallbackPolicy(policy.callbackPolicy),
|
|
7819
|
+
// v0.9.95 — voice-runtime overrides. Pass-through; the registry
|
|
7820
|
+
// validates the provider id and voice-against-catalogue at
|
|
7821
|
+
// session-open time so we don't have to import the registry
|
|
7822
|
+
// here (would create a cycle with realtime-bridge.ts).
|
|
7823
|
+
voiceRuntime: typeof policy.voiceRuntime === "string" && policy.voiceRuntime.trim() ? policy.voiceRuntime.trim() : void 0,
|
|
7824
|
+
voiceModel: typeof policy.voiceModel === "string" && policy.voiceModel.trim() ? policy.voiceModel.trim() : void 0,
|
|
7825
|
+
voice: typeof policy.voice === "string" && policy.voice.trim() ? policy.voice.trim() : void 0
|
|
7806
7826
|
},
|
|
7807
7827
|
issues: []
|
|
7808
7828
|
};
|
|
@@ -12203,6 +12223,140 @@ function withTimeout(promise, ms) {
|
|
|
12203
12223
|
return Promise.race([promise, timeout]).finally(() => clearTimeout(timer));
|
|
12204
12224
|
}
|
|
12205
12225
|
|
|
12226
|
+
// src/phone/voice-providers/registry.ts
|
|
12227
|
+
var PROVIDERS2 = /* @__PURE__ */ new Map();
|
|
12228
|
+
function registerVoiceProvider(provider) {
|
|
12229
|
+
if (PROVIDERS2.has(provider.id)) {
|
|
12230
|
+
throw new Error(`Voice provider "${provider.id}" registered twice \u2014 id collision.`);
|
|
12231
|
+
}
|
|
12232
|
+
PROVIDERS2.set(provider.id, provider);
|
|
12233
|
+
}
|
|
12234
|
+
function listVoiceProviders() {
|
|
12235
|
+
return Array.from(PROVIDERS2.values());
|
|
12236
|
+
}
|
|
12237
|
+
function getVoiceProvider(id) {
|
|
12238
|
+
return PROVIDERS2.get(id);
|
|
12239
|
+
}
|
|
12240
|
+
function resolveVoiceRuntime(providerId, config, options = {}) {
|
|
12241
|
+
const id = (providerId || "openai").trim() || "openai";
|
|
12242
|
+
const provider = PROVIDERS2.get(id);
|
|
12243
|
+
if (!provider) {
|
|
12244
|
+
const known = Array.from(PROVIDERS2.keys()).join(", ") || "(none registered)";
|
|
12245
|
+
throw new Error(
|
|
12246
|
+
`Unknown voice runtime "${id}". Known providers: ${known}. Add a new one by dropping a file into packages/core/src/phone/voice-providers/.`
|
|
12247
|
+
);
|
|
12248
|
+
}
|
|
12249
|
+
let apiKey = "";
|
|
12250
|
+
let apiKeySource = "";
|
|
12251
|
+
if (provider.apiKeyConfigField) {
|
|
12252
|
+
const legacy = config[provider.apiKeyConfigField];
|
|
12253
|
+
if (legacy && legacy.trim()) {
|
|
12254
|
+
apiKey = legacy.trim();
|
|
12255
|
+
apiKeySource = `config.${provider.apiKeyConfigField}`;
|
|
12256
|
+
}
|
|
12257
|
+
}
|
|
12258
|
+
if (!apiKey) {
|
|
12259
|
+
const fromMap = config.voiceProviderKeys?.[provider.id];
|
|
12260
|
+
if (fromMap && fromMap.trim()) {
|
|
12261
|
+
apiKey = fromMap.trim();
|
|
12262
|
+
apiKeySource = `config.voiceProviderKeys.${provider.id}`;
|
|
12263
|
+
}
|
|
12264
|
+
}
|
|
12265
|
+
if (!apiKey) {
|
|
12266
|
+
const fromEnv = process.env[provider.apiKeyEnvVar];
|
|
12267
|
+
if (fromEnv && fromEnv.trim()) {
|
|
12268
|
+
apiKey = fromEnv.trim();
|
|
12269
|
+
apiKeySource = `env ${provider.apiKeyEnvVar}`;
|
|
12270
|
+
}
|
|
12271
|
+
}
|
|
12272
|
+
if (!apiKey) {
|
|
12273
|
+
throw new Error(
|
|
12274
|
+
`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}.`
|
|
12275
|
+
);
|
|
12276
|
+
}
|
|
12277
|
+
const model = options.model && options.model.trim() || provider.defaultModel;
|
|
12278
|
+
const url = `${provider.websocketBaseUrl}?model=${encodeURIComponent(model)}`;
|
|
12279
|
+
let voice = "";
|
|
12280
|
+
let voiceSource = "";
|
|
12281
|
+
const requested = (options.voice || "").trim();
|
|
12282
|
+
if (requested) {
|
|
12283
|
+
if (provider.voices.includes(requested) || provider.customVoicesSupported) {
|
|
12284
|
+
voice = requested;
|
|
12285
|
+
voiceSource = "mission policy";
|
|
12286
|
+
} else {
|
|
12287
|
+
console.warn(
|
|
12288
|
+
`[voice-providers] Voice "${requested}" is not in ${provider.id}'s catalogue (${provider.voices.join(", ")}). Falling through to ${provider.defaultVoice}.`
|
|
12289
|
+
);
|
|
12290
|
+
}
|
|
12291
|
+
}
|
|
12292
|
+
if (!voice) {
|
|
12293
|
+
const installDefault = config.voiceProviderVoices?.[provider.id];
|
|
12294
|
+
if (installDefault && installDefault.trim()) {
|
|
12295
|
+
const v = installDefault.trim();
|
|
12296
|
+
if (provider.voices.includes(v) || provider.customVoicesSupported) {
|
|
12297
|
+
voice = v;
|
|
12298
|
+
voiceSource = `config.voiceProviderVoices.${provider.id}`;
|
|
12299
|
+
}
|
|
12300
|
+
}
|
|
12301
|
+
}
|
|
12302
|
+
if (!voice) {
|
|
12303
|
+
voice = provider.defaultVoice;
|
|
12304
|
+
voiceSource = `${provider.id} default`;
|
|
12305
|
+
}
|
|
12306
|
+
return {
|
|
12307
|
+
providerId: provider.id,
|
|
12308
|
+
providerDisplayName: provider.displayName,
|
|
12309
|
+
url,
|
|
12310
|
+
model,
|
|
12311
|
+
apiKey,
|
|
12312
|
+
apiKeySource,
|
|
12313
|
+
voice,
|
|
12314
|
+
voiceSource
|
|
12315
|
+
};
|
|
12316
|
+
}
|
|
12317
|
+
|
|
12318
|
+
// src/phone/voice-providers/openai.ts
|
|
12319
|
+
registerVoiceProvider({
|
|
12320
|
+
id: "openai",
|
|
12321
|
+
displayName: "OpenAI Realtime (gpt-realtime)",
|
|
12322
|
+
websocketBaseUrl: "wss://api.openai.com/v1/realtime",
|
|
12323
|
+
defaultModel: "gpt-realtime",
|
|
12324
|
+
apiKeyEnvVar: "OPENAI_API_KEY",
|
|
12325
|
+
// Legacy: the original config.json schema used a dedicated
|
|
12326
|
+
// `openaiApiKey` field for this key. The resolver checks that field
|
|
12327
|
+
// before the generic voiceProviderKeys map so existing installs
|
|
12328
|
+
// continue to work without migration.
|
|
12329
|
+
apiKeyConfigField: "openaiApiKey",
|
|
12330
|
+
description: "OpenAI Realtime (gpt-realtime). Default voice runtime; supports linear PCM @ 24 kHz (46elks) and G.711 \xB5-law @ 8 kHz (Twilio) without transcoding.",
|
|
12331
|
+
// v0.9.95 — voice catalogue. Names match what the Realtime session
|
|
12332
|
+
// accepts under `audio.output.voice`. `marin` and `cedar` are the
|
|
12333
|
+
// GA gpt-realtime additions; the rest are the legacy roster carried
|
|
12334
|
+
// forward from gpt-4o-realtime-preview.
|
|
12335
|
+
voices: ["alloy", "ash", "ballad", "cedar", "coral", "echo", "marin", "sage", "shimmer", "verse"],
|
|
12336
|
+
defaultVoice: "marin"
|
|
12337
|
+
});
|
|
12338
|
+
|
|
12339
|
+
// src/phone/voice-providers/grok.ts
|
|
12340
|
+
registerVoiceProvider({
|
|
12341
|
+
id: "grok",
|
|
12342
|
+
displayName: "xAI Grok Voice Agent",
|
|
12343
|
+
websocketBaseUrl: "wss://api.x.ai/v1/realtime",
|
|
12344
|
+
defaultModel: "grok-voice-latest",
|
|
12345
|
+
apiKeyEnvVar: "XAI_API_KEY",
|
|
12346
|
+
description: 'xAI Grok Voice Agent \u2014 OpenAI-Realtime-compatible WebSocket protocol; select via mission policy.voiceRuntime="grok" or env AGENTICMAIL_VOICE_RUNTIME=grok.',
|
|
12347
|
+
// v0.9.95 — voice catalogue. xAI ships 5 expressive built-in
|
|
12348
|
+
// voices for the realtime Voice Agent. Three are explicitly named
|
|
12349
|
+
// in the announcement (Ara, Eve, Leo); the other two are
|
|
12350
|
+
// browsable in console.x.ai's Voice Library along with the
|
|
12351
|
+
// broader 80+ voice catalogue. The full live list is at
|
|
12352
|
+
// GET /v1/tts/voices. We don't try to enumerate all 80+ here —
|
|
12353
|
+
// customVoicesSupported lets operators paste any voice_id from
|
|
12354
|
+
// their console.
|
|
12355
|
+
voices: ["ara", "eve", "leo"],
|
|
12356
|
+
defaultVoice: "ara",
|
|
12357
|
+
customVoicesSupported: true
|
|
12358
|
+
});
|
|
12359
|
+
|
|
12206
12360
|
// src/telemetry.ts
|
|
12207
12361
|
var import_crypto = require("crypto");
|
|
12208
12362
|
var import_fs = require("fs");
|
|
@@ -16336,8 +16490,19 @@ function loadAgentPersona(agentName) {
|
|
|
16336
16490
|
const path2 = personaPathFor(agentName);
|
|
16337
16491
|
try {
|
|
16338
16492
|
if ((0, import_node_fs15.existsSync)(path2)) {
|
|
16339
|
-
const
|
|
16340
|
-
if (
|
|
16493
|
+
const raw = (0, import_node_fs15.readFileSync)(path2, "utf-8");
|
|
16494
|
+
if (raw.trim()) {
|
|
16495
|
+
const text = raw.replace(/\r\n/g, "\n");
|
|
16496
|
+
if (text.startsWith("---\n")) {
|
|
16497
|
+
const close = text.indexOf("\n---", 4);
|
|
16498
|
+
if (close > 0) {
|
|
16499
|
+
let cursor = close + 4;
|
|
16500
|
+
while (cursor < text.length && (text[cursor] === "\n" || text[cursor] === "\r")) cursor++;
|
|
16501
|
+
return text.slice(cursor).trim();
|
|
16502
|
+
}
|
|
16503
|
+
}
|
|
16504
|
+
return text.trim();
|
|
16505
|
+
}
|
|
16341
16506
|
}
|
|
16342
16507
|
} catch {
|
|
16343
16508
|
}
|
|
@@ -16357,6 +16522,61 @@ function saveAgentPersona(agentName, content) {
|
|
|
16357
16522
|
(0, import_node_fs15.writeFileSync)(path2, content.trim() + "\n", { mode: 420 });
|
|
16358
16523
|
return path2;
|
|
16359
16524
|
}
|
|
16525
|
+
function readAgentPersonaFile(agentName) {
|
|
16526
|
+
const path2 = personaPathFor(agentName);
|
|
16527
|
+
let raw = "";
|
|
16528
|
+
try {
|
|
16529
|
+
if ((0, import_node_fs15.existsSync)(path2)) raw = (0, import_node_fs15.readFileSync)(path2, "utf-8");
|
|
16530
|
+
} catch {
|
|
16531
|
+
}
|
|
16532
|
+
if (!raw.trim()) {
|
|
16533
|
+
return { frontmatter: {}, body: loadAgentPersona(agentName) };
|
|
16534
|
+
}
|
|
16535
|
+
const text = raw.replace(/\r\n/g, "\n");
|
|
16536
|
+
if (!text.startsWith("---\n")) {
|
|
16537
|
+
return { frontmatter: {}, body: text.trim() };
|
|
16538
|
+
}
|
|
16539
|
+
const close = text.indexOf("\n---", 4);
|
|
16540
|
+
if (close < 0) {
|
|
16541
|
+
return { frontmatter: {}, body: text.trim() };
|
|
16542
|
+
}
|
|
16543
|
+
const yamlBlock = text.slice(4, close);
|
|
16544
|
+
const bodyStart = close + 4;
|
|
16545
|
+
let cursor = bodyStart;
|
|
16546
|
+
while (cursor < text.length && (text[cursor] === "\n" || text[cursor] === "\r")) cursor++;
|
|
16547
|
+
const body = text.slice(cursor).trim();
|
|
16548
|
+
const frontmatter = {};
|
|
16549
|
+
for (const line of yamlBlock.split("\n")) {
|
|
16550
|
+
const m = /^\s*([A-Za-z][A-Za-z0-9_-]*)\s*:\s*(.*?)\s*$/.exec(line);
|
|
16551
|
+
if (!m) continue;
|
|
16552
|
+
const key = m[1];
|
|
16553
|
+
const value = m[2].replace(/^["']|["']$/g, "");
|
|
16554
|
+
if (key === "voice") frontmatter.voice = value;
|
|
16555
|
+
else if (key === "voiceRuntime") frontmatter.voiceRuntime = value;
|
|
16556
|
+
}
|
|
16557
|
+
return { frontmatter, body };
|
|
16558
|
+
}
|
|
16559
|
+
function updateAgentPersonaFrontmatter(agentName, patch) {
|
|
16560
|
+
const { frontmatter, body } = readAgentPersonaFile(agentName);
|
|
16561
|
+
const merged = { ...frontmatter };
|
|
16562
|
+
if (patch.voice !== void 0) merged.voice = patch.voice;
|
|
16563
|
+
if (patch.voiceRuntime !== void 0) merged.voiceRuntime = patch.voiceRuntime;
|
|
16564
|
+
const lines = [];
|
|
16565
|
+
if (merged.voice && merged.voice.trim()) lines.push(`voice: ${merged.voice.trim()}`);
|
|
16566
|
+
if (merged.voiceRuntime && merged.voiceRuntime.trim()) lines.push(`voiceRuntime: ${merged.voiceRuntime.trim()}`);
|
|
16567
|
+
const path2 = personaPathFor(agentName);
|
|
16568
|
+
const dir2 = path2.substring(0, path2.lastIndexOf("/"));
|
|
16569
|
+
if (!(0, import_node_fs15.existsSync)(dir2)) (0, import_node_fs15.mkdirSync)(dir2, { recursive: true });
|
|
16570
|
+
const content = lines.length > 0 ? `---
|
|
16571
|
+
${lines.join("\n")}
|
|
16572
|
+
---
|
|
16573
|
+
|
|
16574
|
+
${body}
|
|
16575
|
+
` : `${body}
|
|
16576
|
+
`;
|
|
16577
|
+
(0, import_node_fs15.writeFileSync)(path2, content, { mode: 420 });
|
|
16578
|
+
return path2;
|
|
16579
|
+
}
|
|
16360
16580
|
// Annotate the CommonJS export names for ESM import in node:
|
|
16361
16581
|
0 && (module.exports = {
|
|
16362
16582
|
AGENT_ROLES,
|
|
@@ -16517,6 +16737,7 @@ function saveAgentPersona(agentName, content) {
|
|
|
16517
16737
|
getTelegramMe,
|
|
16518
16738
|
getTelegramUpdates,
|
|
16519
16739
|
getTelegramWebhookInfo,
|
|
16740
|
+
getVoiceProvider,
|
|
16520
16741
|
hostSessionStoragePath,
|
|
16521
16742
|
inferPhoneRegion,
|
|
16522
16743
|
invalidateSkillCache,
|
|
@@ -16529,6 +16750,7 @@ function saveAgentPersona(agentName, content) {
|
|
|
16529
16750
|
isTelegramStopCommand,
|
|
16530
16751
|
isValidPhoneNumber,
|
|
16531
16752
|
listSkills,
|
|
16753
|
+
listVoiceProviders,
|
|
16532
16754
|
loadAgentPersona,
|
|
16533
16755
|
loadHostSession,
|
|
16534
16756
|
loadSkill,
|
|
@@ -16549,6 +16771,7 @@ function saveAgentPersona(agentName, content) {
|
|
|
16549
16771
|
personaPathFor,
|
|
16550
16772
|
planBridgeWake,
|
|
16551
16773
|
pollForOperatorAnswer,
|
|
16774
|
+
readAgentPersonaFile,
|
|
16552
16775
|
recallMemory,
|
|
16553
16776
|
recordToolCall,
|
|
16554
16777
|
redactBotToken,
|
|
@@ -16557,6 +16780,7 @@ function saveAgentPersona(agentName, content) {
|
|
|
16557
16780
|
redactSecret,
|
|
16558
16781
|
redactSmsConfig,
|
|
16559
16782
|
redactTelegramConfig,
|
|
16783
|
+
registerVoiceProvider,
|
|
16560
16784
|
renderSkillAsPrompt,
|
|
16561
16785
|
requireBinary,
|
|
16562
16786
|
requireWhisperModel,
|
|
@@ -16564,6 +16788,7 @@ function saveAgentPersona(agentName, content) {
|
|
|
16564
16788
|
resolveConfig,
|
|
16565
16789
|
resolveExtensionPolicy,
|
|
16566
16790
|
resolveTlsRejectUnauthorized,
|
|
16791
|
+
resolveVoiceRuntime,
|
|
16567
16792
|
safeJoin,
|
|
16568
16793
|
sanitizeEmail,
|
|
16569
16794
|
saveAgentPersona,
|
|
@@ -16585,6 +16810,7 @@ function saveAgentPersona(agentName, content) {
|
|
|
16585
16810
|
threadIdFor,
|
|
16586
16811
|
tokenize,
|
|
16587
16812
|
tryJoin,
|
|
16813
|
+
updateAgentPersonaFrontmatter,
|
|
16588
16814
|
userSkillsDir,
|
|
16589
16815
|
validateApiUrl,
|
|
16590
16816
|
validatePhoneMissionPolicy,
|
package/dist/index.d.cts
CHANGED
|
@@ -229,6 +229,31 @@ 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.95 — install-wide default voice CHARACTER per provider
|
|
243
|
+
* (e.g. `{ openai: 'cedar', grok: 'ara' }`). Optional — when a
|
|
244
|
+
* provider's slot is empty, the bridge falls back to the
|
|
245
|
+
* provider's own `defaultVoice`. Per-agent persona + per-call
|
|
246
|
+
* mission policy still beat this. The CLI's `agenticmail
|
|
247
|
+
* setup-voice` voice picker writes here.
|
|
248
|
+
*/
|
|
249
|
+
voiceProviderVoices?: Record<string, string>;
|
|
250
|
+
/**
|
|
251
|
+
* v0.9.93 — default voice-runtime provider id for phone missions
|
|
252
|
+
* that don't pin one on their own policy. `'openai'` (the existing
|
|
253
|
+
* default) or any provider registered in `voice-providers/`.
|
|
254
|
+
* Read from `AGENTICMAIL_VOICE_RUNTIME` env var or `config.json`.
|
|
255
|
+
*/
|
|
256
|
+
voiceRuntime?: string;
|
|
232
257
|
masterKey: string;
|
|
233
258
|
dataDir: string;
|
|
234
259
|
}
|
|
@@ -2748,6 +2773,25 @@ interface OpenClawPhoneMissionPolicy {
|
|
|
2748
2773
|
* {@link DEFAULT_CALLBACK_POLICY} when omitted.
|
|
2749
2774
|
*/
|
|
2750
2775
|
callbackPolicy?: PhoneCallbackPolicy;
|
|
2776
|
+
/**
|
|
2777
|
+
* v0.9.95 — voice-runtime provider id ('openai', 'grok', any
|
|
2778
|
+
* future plugin). Per-call override that beats agent persona
|
|
2779
|
+
* frontmatter, install default, and bridge default. Optional.
|
|
2780
|
+
*/
|
|
2781
|
+
voiceRuntime?: string;
|
|
2782
|
+
/**
|
|
2783
|
+
* v0.9.95 — model name override (e.g. `'gpt-realtime-mini'` for
|
|
2784
|
+
* cost-tuning, `'grok-voice-fast'` for latency). Optional.
|
|
2785
|
+
*/
|
|
2786
|
+
voiceModel?: string;
|
|
2787
|
+
/**
|
|
2788
|
+
* v0.9.95 — voice CHARACTER override (e.g. `'cedar'`, `'ara'`, or
|
|
2789
|
+
* a custom-voice id from Grok). Optional. Validated against the
|
|
2790
|
+
* provider's catalogue at session-open time; unknown names against
|
|
2791
|
+
* a fixed-catalogue provider fall through to the provider default
|
|
2792
|
+
* with a log warning.
|
|
2793
|
+
*/
|
|
2794
|
+
voice?: string;
|
|
2751
2795
|
}
|
|
2752
2796
|
interface StartPhoneMissionInput {
|
|
2753
2797
|
to: string;
|
|
@@ -3824,6 +3868,161 @@ declare class RealtimeVoiceBridge {
|
|
|
3824
3868
|
private safeSend;
|
|
3825
3869
|
}
|
|
3826
3870
|
|
|
3871
|
+
/**
|
|
3872
|
+
* Voice-runtime provider plugin interface.
|
|
3873
|
+
*
|
|
3874
|
+
* Each backend (OpenAI Realtime, Grok Voice Agent, future Anthropic
|
|
3875
|
+
* realtime, Cartesia, ElevenLabs ConvAI, etc.) lives in its own file
|
|
3876
|
+
* under `packages/core/src/phone/voice-providers/` and registers
|
|
3877
|
+
* itself with the registry by calling {@link registerVoiceProvider}
|
|
3878
|
+
* at module load.
|
|
3879
|
+
*
|
|
3880
|
+
* Adding a new provider is meant to be a literal FILE DROP:
|
|
3881
|
+
*
|
|
3882
|
+
* 1. Create `voice-providers/<id>.ts` exporting a {@link VoiceProvider}.
|
|
3883
|
+
* 2. Add a single `import './<id>.js';` line to `voice-providers/index.ts`
|
|
3884
|
+
* so the side-effect registration runs.
|
|
3885
|
+
* 3. (Optional) document the env var the provider expects.
|
|
3886
|
+
*
|
|
3887
|
+
* No other file in the codebase needs to know about the new provider —
|
|
3888
|
+
* the realtime bridge looks providers up by id through the registry.
|
|
3889
|
+
*
|
|
3890
|
+
* Currently every supported provider is an OpenAI-Realtime-compatible
|
|
3891
|
+
* WebSocket. If a future provider diverges enough to need its own wire
|
|
3892
|
+
* protocol (custom event shape, gRPC, WebRTC SDP, etc.), the seam to
|
|
3893
|
+
* extend is here: add `buildSessionUpdate` / `parseInboundEvent` /
|
|
3894
|
+
* etc. hooks to {@link VoiceProvider}, then make `realtime-bridge.ts`
|
|
3895
|
+
* route through them instead of speaking OpenAI Realtime directly.
|
|
3896
|
+
*/
|
|
3897
|
+
/**
|
|
3898
|
+
* One voice-runtime provider. Carries enough information for the
|
|
3899
|
+
* bridge to open the right WebSocket with the right auth + model.
|
|
3900
|
+
*/
|
|
3901
|
+
interface VoiceProvider {
|
|
3902
|
+
/**
|
|
3903
|
+
* Stable identifier used in mission policy / config (`'openai'`,
|
|
3904
|
+
* `'grok'`, …). Keep lowercase, no spaces — this is what operators
|
|
3905
|
+
* type into `AGENTICMAIL_VOICE_RUNTIME=` or pass via mission policy.
|
|
3906
|
+
*/
|
|
3907
|
+
id: string;
|
|
3908
|
+
/** Human-readable display name for logs + the web UI. */
|
|
3909
|
+
displayName: string;
|
|
3910
|
+
/** WebSocket base URL (the bridge appends `?model=…`). */
|
|
3911
|
+
websocketBaseUrl: string;
|
|
3912
|
+
/**
|
|
3913
|
+
* Default model when the caller doesn't pin one. Sent as the
|
|
3914
|
+
* `?model=…` query string AND echoed in the session.update.
|
|
3915
|
+
*/
|
|
3916
|
+
defaultModel: string;
|
|
3917
|
+
/**
|
|
3918
|
+
* The env var the operator sets for this provider's API key
|
|
3919
|
+
* (`OPENAI_API_KEY`, `XAI_API_KEY`, …). The bootstrap / config
|
|
3920
|
+
* loader reads from this name and stores into
|
|
3921
|
+
* `AgenticMailConfig.voiceProviderKeys[<id>]`. Used in the
|
|
3922
|
+
* "you didn't set the key" error message too.
|
|
3923
|
+
*/
|
|
3924
|
+
apiKeyEnvVar: string;
|
|
3925
|
+
/**
|
|
3926
|
+
* Optional fallback config-field name. When the provider's API key
|
|
3927
|
+
* has a long-standing dedicated config field (e.g. OpenAI's
|
|
3928
|
+
* `config.openaiApiKey`), this lets the resolver check that field
|
|
3929
|
+
* BEFORE looking in the generic `voiceProviderKeys` map — so
|
|
3930
|
+
* existing installs don't need to migrate. Leave undefined for
|
|
3931
|
+
* new providers.
|
|
3932
|
+
*/
|
|
3933
|
+
apiKeyConfigField?: 'openaiApiKey';
|
|
3934
|
+
/**
|
|
3935
|
+
* Per-provider notes that surface in error / boot-log messages.
|
|
3936
|
+
* Optional — defaults are fine for the standard providers.
|
|
3937
|
+
*/
|
|
3938
|
+
description?: string;
|
|
3939
|
+
/**
|
|
3940
|
+
* v0.9.95 — built-in voice catalogue. The names the operator can
|
|
3941
|
+
* pick when configuring a default voice for the agent or pinning
|
|
3942
|
+
* one per-call. Empty array means "use whatever defaultVoice we
|
|
3943
|
+
* ship" — used by providers like Grok that support arbitrary
|
|
3944
|
+
* voice ids (cloned voices) instead of a fixed list.
|
|
3945
|
+
*/
|
|
3946
|
+
voices: string[];
|
|
3947
|
+
/**
|
|
3948
|
+
* v0.9.95 — default voice the bridge picks when neither the
|
|
3949
|
+
* mission policy nor the agent persona pins one. Per-provider:
|
|
3950
|
+
* OpenAI defaults to "marin"; Grok lets the provider pick.
|
|
3951
|
+
*/
|
|
3952
|
+
defaultVoice: string;
|
|
3953
|
+
/**
|
|
3954
|
+
* v0.9.95 — true when the provider accepts arbitrary voice ids
|
|
3955
|
+
* beyond `voices` (e.g. Grok's Custom Voices API returns a
|
|
3956
|
+
* `voice_id` that plugs in here). Tells the CLI picker to show a
|
|
3957
|
+
* free-text input + a "paste a custom voice id" option after the
|
|
3958
|
+
* built-in list.
|
|
3959
|
+
*/
|
|
3960
|
+
customVoicesSupported?: boolean;
|
|
3961
|
+
}
|
|
3962
|
+
/**
|
|
3963
|
+
* The bridge needs all the inputs needed to open a session in one
|
|
3964
|
+
* resolved struct — URL with model encoded, the API key, the source
|
|
3965
|
+
* for logging. {@link resolveVoiceRuntime} produces this.
|
|
3966
|
+
*/
|
|
3967
|
+
interface VoiceRuntimeConnection {
|
|
3968
|
+
providerId: string;
|
|
3969
|
+
providerDisplayName: string;
|
|
3970
|
+
/** Full WebSocket URL including `?model=…`. */
|
|
3971
|
+
url: string;
|
|
3972
|
+
/** Resolved model name (also passed in the URL). */
|
|
3973
|
+
model: string;
|
|
3974
|
+
/** Bearer token for the `Authorization` header. */
|
|
3975
|
+
apiKey: string;
|
|
3976
|
+
/** Human-readable source of the key, for boot logs only (e.g. `"env XAI_API_KEY"`). */
|
|
3977
|
+
apiKeySource: string;
|
|
3978
|
+
/**
|
|
3979
|
+
* v0.9.95 — resolved voice name (sent in session.update under
|
|
3980
|
+
* `audio.output.voice`). Picked from (in order):
|
|
3981
|
+
* 1. caller-passed `options.voice` (mission policy)
|
|
3982
|
+
* 2. agent persona's `voice:` frontmatter
|
|
3983
|
+
* 3. install default in `config.voiceProviderVoices[<providerId>]`
|
|
3984
|
+
* 4. provider's `defaultVoice` (e.g. OpenAI "marin", Grok "ara")
|
|
3985
|
+
*/
|
|
3986
|
+
voice: string;
|
|
3987
|
+
/** Human-readable source of the voice pick, for boot logs / audit. */
|
|
3988
|
+
voiceSource: string;
|
|
3989
|
+
}
|
|
3990
|
+
|
|
3991
|
+
/**
|
|
3992
|
+
* Voice-provider registry — drop-in plugin discovery.
|
|
3993
|
+
*
|
|
3994
|
+
* Providers register themselves at module-load time via
|
|
3995
|
+
* {@link registerVoiceProvider}. The barrel `voice-providers/index.ts`
|
|
3996
|
+
* imports each provider file for its side effect, populating this map
|
|
3997
|
+
* before any caller asks for one.
|
|
3998
|
+
*
|
|
3999
|
+
* No reflection, no filesystem scan, no decorator magic — adding a
|
|
4000
|
+
* provider is "create a file + add one import line". That gives us
|
|
4001
|
+
* both first-class TypeScript types AND the file-drop ergonomics.
|
|
4002
|
+
*/
|
|
4003
|
+
|
|
4004
|
+
/**
|
|
4005
|
+
* Register a provider. Called once per file at module load. Throws on
|
|
4006
|
+
* duplicate id so an accidental copy-paste collision is loud, not
|
|
4007
|
+
* silently overriding.
|
|
4008
|
+
*/
|
|
4009
|
+
declare function registerVoiceProvider(provider: VoiceProvider): void;
|
|
4010
|
+
/** All registered providers — for `agenticmail voice list` / web UI menus. */
|
|
4011
|
+
declare function listVoiceProviders(): VoiceProvider[];
|
|
4012
|
+
/** Look up a provider by id. Returns undefined for unknown ids. */
|
|
4013
|
+
declare function getVoiceProvider(id: string): VoiceProvider | undefined;
|
|
4014
|
+
/**
|
|
4015
|
+
* Resolve a provider id + the runtime's config / overrides into the
|
|
4016
|
+
* connection struct the bridge consumes (URL with model, api key,
|
|
4017
|
+
* source). Throws if the provider id is unknown or its API key isn't
|
|
4018
|
+
* configured — the realtime-ws layer turns the throw into a clear
|
|
4019
|
+
* startup error instead of a mid-call surprise.
|
|
4020
|
+
*/
|
|
4021
|
+
declare function resolveVoiceRuntime(providerId: string | undefined, config: AgenticMailConfig, options?: {
|
|
4022
|
+
model?: string;
|
|
4023
|
+
voice?: string;
|
|
4024
|
+
}): VoiceRuntimeConnection;
|
|
4025
|
+
|
|
3827
4026
|
type PhoneTransportProvider = '46elks' | 'twilio';
|
|
3828
4027
|
/** Providers that support starting outbound call-control missions. */
|
|
3829
4028
|
declare const PHONE_CALL_CONTROL_PROVIDERS: readonly PhoneTransportProvider[];
|
|
@@ -6235,11 +6434,16 @@ declare function buildDefaultPersona(agentName: string): string;
|
|
|
6235
6434
|
/** Resolve the per-agent persona path on disk. */
|
|
6236
6435
|
declare function personaPathFor(agentName: string): string;
|
|
6237
6436
|
/**
|
|
6238
|
-
* Load the persona for {@link agentName}. Auto-creates the file
|
|
6239
|
-
* {@link buildDefaultPersona} content on first read. Idempotent
|
|
6240
|
-
*
|
|
6241
|
-
*
|
|
6242
|
-
*
|
|
6437
|
+
* Load the persona BODY for {@link agentName}. Auto-creates the file
|
|
6438
|
+
* with {@link buildDefaultPersona} content on first read. Idempotent.
|
|
6439
|
+
* Never throws — a permission error or filesystem quirk falls back
|
|
6440
|
+
* to the in-memory default so the voice / email / telegram path is
|
|
6441
|
+
* never crashed by a missing file.
|
|
6442
|
+
*
|
|
6443
|
+
* v0.9.95 — if the file has YAML frontmatter (voice / voiceRuntime
|
|
6444
|
+
* keys, written by `agenticmail persona --voice <name>`), the
|
|
6445
|
+
* frontmatter is stripped from the returned string. Use
|
|
6446
|
+
* {@link readAgentPersonaFile} to get the parsed frontmatter too.
|
|
6243
6447
|
*/
|
|
6244
6448
|
declare function loadAgentPersona(agentName: string): string;
|
|
6245
6449
|
/**
|
|
@@ -6247,5 +6451,43 @@ declare function loadAgentPersona(agentName: string): string;
|
|
|
6247
6451
|
* edit command. Returns the path written to.
|
|
6248
6452
|
*/
|
|
6249
6453
|
declare function saveAgentPersona(agentName: string, content: string): string;
|
|
6454
|
+
/**
|
|
6455
|
+
* v0.9.95 — structured per-agent voice preferences. Stored as YAML
|
|
6456
|
+
* frontmatter at the top of the persona file:
|
|
6457
|
+
*
|
|
6458
|
+
* ---
|
|
6459
|
+
* voice: cedar
|
|
6460
|
+
* voiceRuntime: openai
|
|
6461
|
+
* ---
|
|
6462
|
+
* # Who you are
|
|
6463
|
+
* ...
|
|
6464
|
+
*
|
|
6465
|
+
* Both fields optional. Unknown keys are ignored on read. The CLI's
|
|
6466
|
+
* `agenticmail persona --voice <name>` writes here. The realtime
|
|
6467
|
+
* bridge consults this between the mission policy and the install
|
|
6468
|
+
* default so an agent can have a consistent voice across every call
|
|
6469
|
+
* without the caller pinning it on every invocation.
|
|
6470
|
+
*/
|
|
6471
|
+
interface AgentPersonaFrontmatter {
|
|
6472
|
+
voice?: string;
|
|
6473
|
+
voiceRuntime?: string;
|
|
6474
|
+
}
|
|
6475
|
+
/**
|
|
6476
|
+
* Read frontmatter + body from the persona file. Best-effort; missing
|
|
6477
|
+
* file returns empty frontmatter + an auto-seeded body. Robust to:
|
|
6478
|
+
* - No frontmatter at all (legacy files written before 0.9.95).
|
|
6479
|
+
* - Frontmatter with leading whitespace / CRLF.
|
|
6480
|
+
* - Junk lines in the YAML block — we only pick the keys we know.
|
|
6481
|
+
*/
|
|
6482
|
+
declare function readAgentPersonaFile(agentName: string): {
|
|
6483
|
+
frontmatter: AgentPersonaFrontmatter;
|
|
6484
|
+
body: string;
|
|
6485
|
+
};
|
|
6486
|
+
/**
|
|
6487
|
+
* Update one or more frontmatter keys on an agent's persona file.
|
|
6488
|
+
* Preserves the existing body. Auto-seeds the body if the file
|
|
6489
|
+
* didn't exist yet.
|
|
6490
|
+
*/
|
|
6491
|
+
declare function updateAgentPersonaFrontmatter(agentName: string, patch: AgentPersonaFrontmatter): string;
|
|
6250
6492
|
|
|
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 };
|
|
6493
|
+
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 AgentPersonaFrontmatter, 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, readAgentPersonaFile, 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, updateAgentPersonaFrontmatter, userSkillsDir, validateApiUrl, validatePhoneMissionPolicy, validatePhoneMissionStart, validatePhoneTransportProfile, validateSkill, validateTwilioSignature, webSearch };
|
package/dist/index.d.ts
CHANGED
|
@@ -229,6 +229,31 @@ 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.95 — install-wide default voice CHARACTER per provider
|
|
243
|
+
* (e.g. `{ openai: 'cedar', grok: 'ara' }`). Optional — when a
|
|
244
|
+
* provider's slot is empty, the bridge falls back to the
|
|
245
|
+
* provider's own `defaultVoice`. Per-agent persona + per-call
|
|
246
|
+
* mission policy still beat this. The CLI's `agenticmail
|
|
247
|
+
* setup-voice` voice picker writes here.
|
|
248
|
+
*/
|
|
249
|
+
voiceProviderVoices?: Record<string, string>;
|
|
250
|
+
/**
|
|
251
|
+
* v0.9.93 — default voice-runtime provider id for phone missions
|
|
252
|
+
* that don't pin one on their own policy. `'openai'` (the existing
|
|
253
|
+
* default) or any provider registered in `voice-providers/`.
|
|
254
|
+
* Read from `AGENTICMAIL_VOICE_RUNTIME` env var or `config.json`.
|
|
255
|
+
*/
|
|
256
|
+
voiceRuntime?: string;
|
|
232
257
|
masterKey: string;
|
|
233
258
|
dataDir: string;
|
|
234
259
|
}
|
|
@@ -2748,6 +2773,25 @@ interface OpenClawPhoneMissionPolicy {
|
|
|
2748
2773
|
* {@link DEFAULT_CALLBACK_POLICY} when omitted.
|
|
2749
2774
|
*/
|
|
2750
2775
|
callbackPolicy?: PhoneCallbackPolicy;
|
|
2776
|
+
/**
|
|
2777
|
+
* v0.9.95 — voice-runtime provider id ('openai', 'grok', any
|
|
2778
|
+
* future plugin). Per-call override that beats agent persona
|
|
2779
|
+
* frontmatter, install default, and bridge default. Optional.
|
|
2780
|
+
*/
|
|
2781
|
+
voiceRuntime?: string;
|
|
2782
|
+
/**
|
|
2783
|
+
* v0.9.95 — model name override (e.g. `'gpt-realtime-mini'` for
|
|
2784
|
+
* cost-tuning, `'grok-voice-fast'` for latency). Optional.
|
|
2785
|
+
*/
|
|
2786
|
+
voiceModel?: string;
|
|
2787
|
+
/**
|
|
2788
|
+
* v0.9.95 — voice CHARACTER override (e.g. `'cedar'`, `'ara'`, or
|
|
2789
|
+
* a custom-voice id from Grok). Optional. Validated against the
|
|
2790
|
+
* provider's catalogue at session-open time; unknown names against
|
|
2791
|
+
* a fixed-catalogue provider fall through to the provider default
|
|
2792
|
+
* with a log warning.
|
|
2793
|
+
*/
|
|
2794
|
+
voice?: string;
|
|
2751
2795
|
}
|
|
2752
2796
|
interface StartPhoneMissionInput {
|
|
2753
2797
|
to: string;
|
|
@@ -3824,6 +3868,161 @@ declare class RealtimeVoiceBridge {
|
|
|
3824
3868
|
private safeSend;
|
|
3825
3869
|
}
|
|
3826
3870
|
|
|
3871
|
+
/**
|
|
3872
|
+
* Voice-runtime provider plugin interface.
|
|
3873
|
+
*
|
|
3874
|
+
* Each backend (OpenAI Realtime, Grok Voice Agent, future Anthropic
|
|
3875
|
+
* realtime, Cartesia, ElevenLabs ConvAI, etc.) lives in its own file
|
|
3876
|
+
* under `packages/core/src/phone/voice-providers/` and registers
|
|
3877
|
+
* itself with the registry by calling {@link registerVoiceProvider}
|
|
3878
|
+
* at module load.
|
|
3879
|
+
*
|
|
3880
|
+
* Adding a new provider is meant to be a literal FILE DROP:
|
|
3881
|
+
*
|
|
3882
|
+
* 1. Create `voice-providers/<id>.ts` exporting a {@link VoiceProvider}.
|
|
3883
|
+
* 2. Add a single `import './<id>.js';` line to `voice-providers/index.ts`
|
|
3884
|
+
* so the side-effect registration runs.
|
|
3885
|
+
* 3. (Optional) document the env var the provider expects.
|
|
3886
|
+
*
|
|
3887
|
+
* No other file in the codebase needs to know about the new provider —
|
|
3888
|
+
* the realtime bridge looks providers up by id through the registry.
|
|
3889
|
+
*
|
|
3890
|
+
* Currently every supported provider is an OpenAI-Realtime-compatible
|
|
3891
|
+
* WebSocket. If a future provider diverges enough to need its own wire
|
|
3892
|
+
* protocol (custom event shape, gRPC, WebRTC SDP, etc.), the seam to
|
|
3893
|
+
* extend is here: add `buildSessionUpdate` / `parseInboundEvent` /
|
|
3894
|
+
* etc. hooks to {@link VoiceProvider}, then make `realtime-bridge.ts`
|
|
3895
|
+
* route through them instead of speaking OpenAI Realtime directly.
|
|
3896
|
+
*/
|
|
3897
|
+
/**
|
|
3898
|
+
* One voice-runtime provider. Carries enough information for the
|
|
3899
|
+
* bridge to open the right WebSocket with the right auth + model.
|
|
3900
|
+
*/
|
|
3901
|
+
interface VoiceProvider {
|
|
3902
|
+
/**
|
|
3903
|
+
* Stable identifier used in mission policy / config (`'openai'`,
|
|
3904
|
+
* `'grok'`, …). Keep lowercase, no spaces — this is what operators
|
|
3905
|
+
* type into `AGENTICMAIL_VOICE_RUNTIME=` or pass via mission policy.
|
|
3906
|
+
*/
|
|
3907
|
+
id: string;
|
|
3908
|
+
/** Human-readable display name for logs + the web UI. */
|
|
3909
|
+
displayName: string;
|
|
3910
|
+
/** WebSocket base URL (the bridge appends `?model=…`). */
|
|
3911
|
+
websocketBaseUrl: string;
|
|
3912
|
+
/**
|
|
3913
|
+
* Default model when the caller doesn't pin one. Sent as the
|
|
3914
|
+
* `?model=…` query string AND echoed in the session.update.
|
|
3915
|
+
*/
|
|
3916
|
+
defaultModel: string;
|
|
3917
|
+
/**
|
|
3918
|
+
* The env var the operator sets for this provider's API key
|
|
3919
|
+
* (`OPENAI_API_KEY`, `XAI_API_KEY`, …). The bootstrap / config
|
|
3920
|
+
* loader reads from this name and stores into
|
|
3921
|
+
* `AgenticMailConfig.voiceProviderKeys[<id>]`. Used in the
|
|
3922
|
+
* "you didn't set the key" error message too.
|
|
3923
|
+
*/
|
|
3924
|
+
apiKeyEnvVar: string;
|
|
3925
|
+
/**
|
|
3926
|
+
* Optional fallback config-field name. When the provider's API key
|
|
3927
|
+
* has a long-standing dedicated config field (e.g. OpenAI's
|
|
3928
|
+
* `config.openaiApiKey`), this lets the resolver check that field
|
|
3929
|
+
* BEFORE looking in the generic `voiceProviderKeys` map — so
|
|
3930
|
+
* existing installs don't need to migrate. Leave undefined for
|
|
3931
|
+
* new providers.
|
|
3932
|
+
*/
|
|
3933
|
+
apiKeyConfigField?: 'openaiApiKey';
|
|
3934
|
+
/**
|
|
3935
|
+
* Per-provider notes that surface in error / boot-log messages.
|
|
3936
|
+
* Optional — defaults are fine for the standard providers.
|
|
3937
|
+
*/
|
|
3938
|
+
description?: string;
|
|
3939
|
+
/**
|
|
3940
|
+
* v0.9.95 — built-in voice catalogue. The names the operator can
|
|
3941
|
+
* pick when configuring a default voice for the agent or pinning
|
|
3942
|
+
* one per-call. Empty array means "use whatever defaultVoice we
|
|
3943
|
+
* ship" — used by providers like Grok that support arbitrary
|
|
3944
|
+
* voice ids (cloned voices) instead of a fixed list.
|
|
3945
|
+
*/
|
|
3946
|
+
voices: string[];
|
|
3947
|
+
/**
|
|
3948
|
+
* v0.9.95 — default voice the bridge picks when neither the
|
|
3949
|
+
* mission policy nor the agent persona pins one. Per-provider:
|
|
3950
|
+
* OpenAI defaults to "marin"; Grok lets the provider pick.
|
|
3951
|
+
*/
|
|
3952
|
+
defaultVoice: string;
|
|
3953
|
+
/**
|
|
3954
|
+
* v0.9.95 — true when the provider accepts arbitrary voice ids
|
|
3955
|
+
* beyond `voices` (e.g. Grok's Custom Voices API returns a
|
|
3956
|
+
* `voice_id` that plugs in here). Tells the CLI picker to show a
|
|
3957
|
+
* free-text input + a "paste a custom voice id" option after the
|
|
3958
|
+
* built-in list.
|
|
3959
|
+
*/
|
|
3960
|
+
customVoicesSupported?: boolean;
|
|
3961
|
+
}
|
|
3962
|
+
/**
|
|
3963
|
+
* The bridge needs all the inputs needed to open a session in one
|
|
3964
|
+
* resolved struct — URL with model encoded, the API key, the source
|
|
3965
|
+
* for logging. {@link resolveVoiceRuntime} produces this.
|
|
3966
|
+
*/
|
|
3967
|
+
interface VoiceRuntimeConnection {
|
|
3968
|
+
providerId: string;
|
|
3969
|
+
providerDisplayName: string;
|
|
3970
|
+
/** Full WebSocket URL including `?model=…`. */
|
|
3971
|
+
url: string;
|
|
3972
|
+
/** Resolved model name (also passed in the URL). */
|
|
3973
|
+
model: string;
|
|
3974
|
+
/** Bearer token for the `Authorization` header. */
|
|
3975
|
+
apiKey: string;
|
|
3976
|
+
/** Human-readable source of the key, for boot logs only (e.g. `"env XAI_API_KEY"`). */
|
|
3977
|
+
apiKeySource: string;
|
|
3978
|
+
/**
|
|
3979
|
+
* v0.9.95 — resolved voice name (sent in session.update under
|
|
3980
|
+
* `audio.output.voice`). Picked from (in order):
|
|
3981
|
+
* 1. caller-passed `options.voice` (mission policy)
|
|
3982
|
+
* 2. agent persona's `voice:` frontmatter
|
|
3983
|
+
* 3. install default in `config.voiceProviderVoices[<providerId>]`
|
|
3984
|
+
* 4. provider's `defaultVoice` (e.g. OpenAI "marin", Grok "ara")
|
|
3985
|
+
*/
|
|
3986
|
+
voice: string;
|
|
3987
|
+
/** Human-readable source of the voice pick, for boot logs / audit. */
|
|
3988
|
+
voiceSource: string;
|
|
3989
|
+
}
|
|
3990
|
+
|
|
3991
|
+
/**
|
|
3992
|
+
* Voice-provider registry — drop-in plugin discovery.
|
|
3993
|
+
*
|
|
3994
|
+
* Providers register themselves at module-load time via
|
|
3995
|
+
* {@link registerVoiceProvider}. The barrel `voice-providers/index.ts`
|
|
3996
|
+
* imports each provider file for its side effect, populating this map
|
|
3997
|
+
* before any caller asks for one.
|
|
3998
|
+
*
|
|
3999
|
+
* No reflection, no filesystem scan, no decorator magic — adding a
|
|
4000
|
+
* provider is "create a file + add one import line". That gives us
|
|
4001
|
+
* both first-class TypeScript types AND the file-drop ergonomics.
|
|
4002
|
+
*/
|
|
4003
|
+
|
|
4004
|
+
/**
|
|
4005
|
+
* Register a provider. Called once per file at module load. Throws on
|
|
4006
|
+
* duplicate id so an accidental copy-paste collision is loud, not
|
|
4007
|
+
* silently overriding.
|
|
4008
|
+
*/
|
|
4009
|
+
declare function registerVoiceProvider(provider: VoiceProvider): void;
|
|
4010
|
+
/** All registered providers — for `agenticmail voice list` / web UI menus. */
|
|
4011
|
+
declare function listVoiceProviders(): VoiceProvider[];
|
|
4012
|
+
/** Look up a provider by id. Returns undefined for unknown ids. */
|
|
4013
|
+
declare function getVoiceProvider(id: string): VoiceProvider | undefined;
|
|
4014
|
+
/**
|
|
4015
|
+
* Resolve a provider id + the runtime's config / overrides into the
|
|
4016
|
+
* connection struct the bridge consumes (URL with model, api key,
|
|
4017
|
+
* source). Throws if the provider id is unknown or its API key isn't
|
|
4018
|
+
* configured — the realtime-ws layer turns the throw into a clear
|
|
4019
|
+
* startup error instead of a mid-call surprise.
|
|
4020
|
+
*/
|
|
4021
|
+
declare function resolveVoiceRuntime(providerId: string | undefined, config: AgenticMailConfig, options?: {
|
|
4022
|
+
model?: string;
|
|
4023
|
+
voice?: string;
|
|
4024
|
+
}): VoiceRuntimeConnection;
|
|
4025
|
+
|
|
3827
4026
|
type PhoneTransportProvider = '46elks' | 'twilio';
|
|
3828
4027
|
/** Providers that support starting outbound call-control missions. */
|
|
3829
4028
|
declare const PHONE_CALL_CONTROL_PROVIDERS: readonly PhoneTransportProvider[];
|
|
@@ -6235,11 +6434,16 @@ declare function buildDefaultPersona(agentName: string): string;
|
|
|
6235
6434
|
/** Resolve the per-agent persona path on disk. */
|
|
6236
6435
|
declare function personaPathFor(agentName: string): string;
|
|
6237
6436
|
/**
|
|
6238
|
-
* Load the persona for {@link agentName}. Auto-creates the file
|
|
6239
|
-
* {@link buildDefaultPersona} content on first read. Idempotent
|
|
6240
|
-
*
|
|
6241
|
-
*
|
|
6242
|
-
*
|
|
6437
|
+
* Load the persona BODY for {@link agentName}. Auto-creates the file
|
|
6438
|
+
* with {@link buildDefaultPersona} content on first read. Idempotent.
|
|
6439
|
+
* Never throws — a permission error or filesystem quirk falls back
|
|
6440
|
+
* to the in-memory default so the voice / email / telegram path is
|
|
6441
|
+
* never crashed by a missing file.
|
|
6442
|
+
*
|
|
6443
|
+
* v0.9.95 — if the file has YAML frontmatter (voice / voiceRuntime
|
|
6444
|
+
* keys, written by `agenticmail persona --voice <name>`), the
|
|
6445
|
+
* frontmatter is stripped from the returned string. Use
|
|
6446
|
+
* {@link readAgentPersonaFile} to get the parsed frontmatter too.
|
|
6243
6447
|
*/
|
|
6244
6448
|
declare function loadAgentPersona(agentName: string): string;
|
|
6245
6449
|
/**
|
|
@@ -6247,5 +6451,43 @@ declare function loadAgentPersona(agentName: string): string;
|
|
|
6247
6451
|
* edit command. Returns the path written to.
|
|
6248
6452
|
*/
|
|
6249
6453
|
declare function saveAgentPersona(agentName: string, content: string): string;
|
|
6454
|
+
/**
|
|
6455
|
+
* v0.9.95 — structured per-agent voice preferences. Stored as YAML
|
|
6456
|
+
* frontmatter at the top of the persona file:
|
|
6457
|
+
*
|
|
6458
|
+
* ---
|
|
6459
|
+
* voice: cedar
|
|
6460
|
+
* voiceRuntime: openai
|
|
6461
|
+
* ---
|
|
6462
|
+
* # Who you are
|
|
6463
|
+
* ...
|
|
6464
|
+
*
|
|
6465
|
+
* Both fields optional. Unknown keys are ignored on read. The CLI's
|
|
6466
|
+
* `agenticmail persona --voice <name>` writes here. The realtime
|
|
6467
|
+
* bridge consults this between the mission policy and the install
|
|
6468
|
+
* default so an agent can have a consistent voice across every call
|
|
6469
|
+
* without the caller pinning it on every invocation.
|
|
6470
|
+
*/
|
|
6471
|
+
interface AgentPersonaFrontmatter {
|
|
6472
|
+
voice?: string;
|
|
6473
|
+
voiceRuntime?: string;
|
|
6474
|
+
}
|
|
6475
|
+
/**
|
|
6476
|
+
* Read frontmatter + body from the persona file. Best-effort; missing
|
|
6477
|
+
* file returns empty frontmatter + an auto-seeded body. Robust to:
|
|
6478
|
+
* - No frontmatter at all (legacy files written before 0.9.95).
|
|
6479
|
+
* - Frontmatter with leading whitespace / CRLF.
|
|
6480
|
+
* - Junk lines in the YAML block — we only pick the keys we know.
|
|
6481
|
+
*/
|
|
6482
|
+
declare function readAgentPersonaFile(agentName: string): {
|
|
6483
|
+
frontmatter: AgentPersonaFrontmatter;
|
|
6484
|
+
body: string;
|
|
6485
|
+
};
|
|
6486
|
+
/**
|
|
6487
|
+
* Update one or more frontmatter keys on an agent's persona file.
|
|
6488
|
+
* Preserves the existing body. Auto-seeds the body if the file
|
|
6489
|
+
* didn't exist yet.
|
|
6490
|
+
*/
|
|
6491
|
+
declare function updateAgentPersonaFrontmatter(agentName: string, patch: AgentPersonaFrontmatter): string;
|
|
6250
6492
|
|
|
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 };
|
|
6493
|
+
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 AgentPersonaFrontmatter, 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, readAgentPersonaFile, 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, updateAgentPersonaFrontmatter, 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 {
|
|
@@ -6129,7 +6136,14 @@ function validatePhoneMissionPolicy(policy) {
|
|
|
6129
6136
|
// manager) can read a concrete value without juggling undefined.
|
|
6130
6137
|
// Caller-omitted → DEFAULT_*. Caller-set → clamped to server caps.
|
|
6131
6138
|
extensionPolicy: resolveExtensionPolicy(policy.extensionPolicy),
|
|
6132
|
-
callbackPolicy: resolveCallbackPolicy(policy.callbackPolicy)
|
|
6139
|
+
callbackPolicy: resolveCallbackPolicy(policy.callbackPolicy),
|
|
6140
|
+
// v0.9.95 — voice-runtime overrides. Pass-through; the registry
|
|
6141
|
+
// validates the provider id and voice-against-catalogue at
|
|
6142
|
+
// session-open time so we don't have to import the registry
|
|
6143
|
+
// here (would create a cycle with realtime-bridge.ts).
|
|
6144
|
+
voiceRuntime: typeof policy.voiceRuntime === "string" && policy.voiceRuntime.trim() ? policy.voiceRuntime.trim() : void 0,
|
|
6145
|
+
voiceModel: typeof policy.voiceModel === "string" && policy.voiceModel.trim() ? policy.voiceModel.trim() : void 0,
|
|
6146
|
+
voice: typeof policy.voice === "string" && policy.voice.trim() ? policy.voice.trim() : void 0
|
|
6133
6147
|
},
|
|
6134
6148
|
issues: []
|
|
6135
6149
|
};
|
|
@@ -10530,6 +10544,140 @@ function withTimeout(promise, ms) {
|
|
|
10530
10544
|
return Promise.race([promise, timeout]).finally(() => clearTimeout(timer));
|
|
10531
10545
|
}
|
|
10532
10546
|
|
|
10547
|
+
// src/phone/voice-providers/registry.ts
|
|
10548
|
+
var PROVIDERS2 = /* @__PURE__ */ new Map();
|
|
10549
|
+
function registerVoiceProvider(provider) {
|
|
10550
|
+
if (PROVIDERS2.has(provider.id)) {
|
|
10551
|
+
throw new Error(`Voice provider "${provider.id}" registered twice \u2014 id collision.`);
|
|
10552
|
+
}
|
|
10553
|
+
PROVIDERS2.set(provider.id, provider);
|
|
10554
|
+
}
|
|
10555
|
+
function listVoiceProviders() {
|
|
10556
|
+
return Array.from(PROVIDERS2.values());
|
|
10557
|
+
}
|
|
10558
|
+
function getVoiceProvider(id) {
|
|
10559
|
+
return PROVIDERS2.get(id);
|
|
10560
|
+
}
|
|
10561
|
+
function resolveVoiceRuntime(providerId, config, options = {}) {
|
|
10562
|
+
const id = (providerId || "openai").trim() || "openai";
|
|
10563
|
+
const provider = PROVIDERS2.get(id);
|
|
10564
|
+
if (!provider) {
|
|
10565
|
+
const known = Array.from(PROVIDERS2.keys()).join(", ") || "(none registered)";
|
|
10566
|
+
throw new Error(
|
|
10567
|
+
`Unknown voice runtime "${id}". Known providers: ${known}. Add a new one by dropping a file into packages/core/src/phone/voice-providers/.`
|
|
10568
|
+
);
|
|
10569
|
+
}
|
|
10570
|
+
let apiKey = "";
|
|
10571
|
+
let apiKeySource = "";
|
|
10572
|
+
if (provider.apiKeyConfigField) {
|
|
10573
|
+
const legacy = config[provider.apiKeyConfigField];
|
|
10574
|
+
if (legacy && legacy.trim()) {
|
|
10575
|
+
apiKey = legacy.trim();
|
|
10576
|
+
apiKeySource = `config.${provider.apiKeyConfigField}`;
|
|
10577
|
+
}
|
|
10578
|
+
}
|
|
10579
|
+
if (!apiKey) {
|
|
10580
|
+
const fromMap = config.voiceProviderKeys?.[provider.id];
|
|
10581
|
+
if (fromMap && fromMap.trim()) {
|
|
10582
|
+
apiKey = fromMap.trim();
|
|
10583
|
+
apiKeySource = `config.voiceProviderKeys.${provider.id}`;
|
|
10584
|
+
}
|
|
10585
|
+
}
|
|
10586
|
+
if (!apiKey) {
|
|
10587
|
+
const fromEnv = process.env[provider.apiKeyEnvVar];
|
|
10588
|
+
if (fromEnv && fromEnv.trim()) {
|
|
10589
|
+
apiKey = fromEnv.trim();
|
|
10590
|
+
apiKeySource = `env ${provider.apiKeyEnvVar}`;
|
|
10591
|
+
}
|
|
10592
|
+
}
|
|
10593
|
+
if (!apiKey) {
|
|
10594
|
+
throw new Error(
|
|
10595
|
+
`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}.`
|
|
10596
|
+
);
|
|
10597
|
+
}
|
|
10598
|
+
const model = options.model && options.model.trim() || provider.defaultModel;
|
|
10599
|
+
const url = `${provider.websocketBaseUrl}?model=${encodeURIComponent(model)}`;
|
|
10600
|
+
let voice = "";
|
|
10601
|
+
let voiceSource = "";
|
|
10602
|
+
const requested = (options.voice || "").trim();
|
|
10603
|
+
if (requested) {
|
|
10604
|
+
if (provider.voices.includes(requested) || provider.customVoicesSupported) {
|
|
10605
|
+
voice = requested;
|
|
10606
|
+
voiceSource = "mission policy";
|
|
10607
|
+
} else {
|
|
10608
|
+
console.warn(
|
|
10609
|
+
`[voice-providers] Voice "${requested}" is not in ${provider.id}'s catalogue (${provider.voices.join(", ")}). Falling through to ${provider.defaultVoice}.`
|
|
10610
|
+
);
|
|
10611
|
+
}
|
|
10612
|
+
}
|
|
10613
|
+
if (!voice) {
|
|
10614
|
+
const installDefault = config.voiceProviderVoices?.[provider.id];
|
|
10615
|
+
if (installDefault && installDefault.trim()) {
|
|
10616
|
+
const v = installDefault.trim();
|
|
10617
|
+
if (provider.voices.includes(v) || provider.customVoicesSupported) {
|
|
10618
|
+
voice = v;
|
|
10619
|
+
voiceSource = `config.voiceProviderVoices.${provider.id}`;
|
|
10620
|
+
}
|
|
10621
|
+
}
|
|
10622
|
+
}
|
|
10623
|
+
if (!voice) {
|
|
10624
|
+
voice = provider.defaultVoice;
|
|
10625
|
+
voiceSource = `${provider.id} default`;
|
|
10626
|
+
}
|
|
10627
|
+
return {
|
|
10628
|
+
providerId: provider.id,
|
|
10629
|
+
providerDisplayName: provider.displayName,
|
|
10630
|
+
url,
|
|
10631
|
+
model,
|
|
10632
|
+
apiKey,
|
|
10633
|
+
apiKeySource,
|
|
10634
|
+
voice,
|
|
10635
|
+
voiceSource
|
|
10636
|
+
};
|
|
10637
|
+
}
|
|
10638
|
+
|
|
10639
|
+
// src/phone/voice-providers/openai.ts
|
|
10640
|
+
registerVoiceProvider({
|
|
10641
|
+
id: "openai",
|
|
10642
|
+
displayName: "OpenAI Realtime (gpt-realtime)",
|
|
10643
|
+
websocketBaseUrl: "wss://api.openai.com/v1/realtime",
|
|
10644
|
+
defaultModel: "gpt-realtime",
|
|
10645
|
+
apiKeyEnvVar: "OPENAI_API_KEY",
|
|
10646
|
+
// Legacy: the original config.json schema used a dedicated
|
|
10647
|
+
// `openaiApiKey` field for this key. The resolver checks that field
|
|
10648
|
+
// before the generic voiceProviderKeys map so existing installs
|
|
10649
|
+
// continue to work without migration.
|
|
10650
|
+
apiKeyConfigField: "openaiApiKey",
|
|
10651
|
+
description: "OpenAI Realtime (gpt-realtime). Default voice runtime; supports linear PCM @ 24 kHz (46elks) and G.711 \xB5-law @ 8 kHz (Twilio) without transcoding.",
|
|
10652
|
+
// v0.9.95 — voice catalogue. Names match what the Realtime session
|
|
10653
|
+
// accepts under `audio.output.voice`. `marin` and `cedar` are the
|
|
10654
|
+
// GA gpt-realtime additions; the rest are the legacy roster carried
|
|
10655
|
+
// forward from gpt-4o-realtime-preview.
|
|
10656
|
+
voices: ["alloy", "ash", "ballad", "cedar", "coral", "echo", "marin", "sage", "shimmer", "verse"],
|
|
10657
|
+
defaultVoice: "marin"
|
|
10658
|
+
});
|
|
10659
|
+
|
|
10660
|
+
// src/phone/voice-providers/grok.ts
|
|
10661
|
+
registerVoiceProvider({
|
|
10662
|
+
id: "grok",
|
|
10663
|
+
displayName: "xAI Grok Voice Agent",
|
|
10664
|
+
websocketBaseUrl: "wss://api.x.ai/v1/realtime",
|
|
10665
|
+
defaultModel: "grok-voice-latest",
|
|
10666
|
+
apiKeyEnvVar: "XAI_API_KEY",
|
|
10667
|
+
description: 'xAI Grok Voice Agent \u2014 OpenAI-Realtime-compatible WebSocket protocol; select via mission policy.voiceRuntime="grok" or env AGENTICMAIL_VOICE_RUNTIME=grok.',
|
|
10668
|
+
// v0.9.95 — voice catalogue. xAI ships 5 expressive built-in
|
|
10669
|
+
// voices for the realtime Voice Agent. Three are explicitly named
|
|
10670
|
+
// in the announcement (Ara, Eve, Leo); the other two are
|
|
10671
|
+
// browsable in console.x.ai's Voice Library along with the
|
|
10672
|
+
// broader 80+ voice catalogue. The full live list is at
|
|
10673
|
+
// GET /v1/tts/voices. We don't try to enumerate all 80+ here —
|
|
10674
|
+
// customVoicesSupported lets operators paste any voice_id from
|
|
10675
|
+
// their console.
|
|
10676
|
+
voices: ["ara", "eve", "leo"],
|
|
10677
|
+
defaultVoice: "ara",
|
|
10678
|
+
customVoicesSupported: true
|
|
10679
|
+
});
|
|
10680
|
+
|
|
10533
10681
|
// src/telemetry.ts
|
|
10534
10682
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
10535
10683
|
import { readFileSync as readFileSync2, writeFileSync as writeFileSync3, mkdirSync as mkdirSync3, existsSync as existsSync3 } from "fs";
|
|
@@ -14679,8 +14827,19 @@ function loadAgentPersona(agentName) {
|
|
|
14679
14827
|
const path2 = personaPathFor(agentName);
|
|
14680
14828
|
try {
|
|
14681
14829
|
if (existsSync14(path2)) {
|
|
14682
|
-
const
|
|
14683
|
-
if (
|
|
14830
|
+
const raw = readFileSync10(path2, "utf-8");
|
|
14831
|
+
if (raw.trim()) {
|
|
14832
|
+
const text = raw.replace(/\r\n/g, "\n");
|
|
14833
|
+
if (text.startsWith("---\n")) {
|
|
14834
|
+
const close = text.indexOf("\n---", 4);
|
|
14835
|
+
if (close > 0) {
|
|
14836
|
+
let cursor = close + 4;
|
|
14837
|
+
while (cursor < text.length && (text[cursor] === "\n" || text[cursor] === "\r")) cursor++;
|
|
14838
|
+
return text.slice(cursor).trim();
|
|
14839
|
+
}
|
|
14840
|
+
}
|
|
14841
|
+
return text.trim();
|
|
14842
|
+
}
|
|
14684
14843
|
}
|
|
14685
14844
|
} catch {
|
|
14686
14845
|
}
|
|
@@ -14700,6 +14859,61 @@ function saveAgentPersona(agentName, content) {
|
|
|
14700
14859
|
writeFileSync11(path2, content.trim() + "\n", { mode: 420 });
|
|
14701
14860
|
return path2;
|
|
14702
14861
|
}
|
|
14862
|
+
function readAgentPersonaFile(agentName) {
|
|
14863
|
+
const path2 = personaPathFor(agentName);
|
|
14864
|
+
let raw = "";
|
|
14865
|
+
try {
|
|
14866
|
+
if (existsSync14(path2)) raw = readFileSync10(path2, "utf-8");
|
|
14867
|
+
} catch {
|
|
14868
|
+
}
|
|
14869
|
+
if (!raw.trim()) {
|
|
14870
|
+
return { frontmatter: {}, body: loadAgentPersona(agentName) };
|
|
14871
|
+
}
|
|
14872
|
+
const text = raw.replace(/\r\n/g, "\n");
|
|
14873
|
+
if (!text.startsWith("---\n")) {
|
|
14874
|
+
return { frontmatter: {}, body: text.trim() };
|
|
14875
|
+
}
|
|
14876
|
+
const close = text.indexOf("\n---", 4);
|
|
14877
|
+
if (close < 0) {
|
|
14878
|
+
return { frontmatter: {}, body: text.trim() };
|
|
14879
|
+
}
|
|
14880
|
+
const yamlBlock = text.slice(4, close);
|
|
14881
|
+
const bodyStart = close + 4;
|
|
14882
|
+
let cursor = bodyStart;
|
|
14883
|
+
while (cursor < text.length && (text[cursor] === "\n" || text[cursor] === "\r")) cursor++;
|
|
14884
|
+
const body = text.slice(cursor).trim();
|
|
14885
|
+
const frontmatter = {};
|
|
14886
|
+
for (const line of yamlBlock.split("\n")) {
|
|
14887
|
+
const m = /^\s*([A-Za-z][A-Za-z0-9_-]*)\s*:\s*(.*?)\s*$/.exec(line);
|
|
14888
|
+
if (!m) continue;
|
|
14889
|
+
const key = m[1];
|
|
14890
|
+
const value = m[2].replace(/^["']|["']$/g, "");
|
|
14891
|
+
if (key === "voice") frontmatter.voice = value;
|
|
14892
|
+
else if (key === "voiceRuntime") frontmatter.voiceRuntime = value;
|
|
14893
|
+
}
|
|
14894
|
+
return { frontmatter, body };
|
|
14895
|
+
}
|
|
14896
|
+
function updateAgentPersonaFrontmatter(agentName, patch) {
|
|
14897
|
+
const { frontmatter, body } = readAgentPersonaFile(agentName);
|
|
14898
|
+
const merged = { ...frontmatter };
|
|
14899
|
+
if (patch.voice !== void 0) merged.voice = patch.voice;
|
|
14900
|
+
if (patch.voiceRuntime !== void 0) merged.voiceRuntime = patch.voiceRuntime;
|
|
14901
|
+
const lines = [];
|
|
14902
|
+
if (merged.voice && merged.voice.trim()) lines.push(`voice: ${merged.voice.trim()}`);
|
|
14903
|
+
if (merged.voiceRuntime && merged.voiceRuntime.trim()) lines.push(`voiceRuntime: ${merged.voiceRuntime.trim()}`);
|
|
14904
|
+
const path2 = personaPathFor(agentName);
|
|
14905
|
+
const dir2 = path2.substring(0, path2.lastIndexOf("/"));
|
|
14906
|
+
if (!existsSync14(dir2)) mkdirSync12(dir2, { recursive: true });
|
|
14907
|
+
const content = lines.length > 0 ? `---
|
|
14908
|
+
${lines.join("\n")}
|
|
14909
|
+
---
|
|
14910
|
+
|
|
14911
|
+
${body}
|
|
14912
|
+
` : `${body}
|
|
14913
|
+
`;
|
|
14914
|
+
writeFileSync11(path2, content, { mode: 420 });
|
|
14915
|
+
return path2;
|
|
14916
|
+
}
|
|
14703
14917
|
export {
|
|
14704
14918
|
AGENT_ROLES,
|
|
14705
14919
|
AGENT_STATE_ROOT,
|
|
@@ -14859,6 +15073,7 @@ export {
|
|
|
14859
15073
|
getTelegramMe,
|
|
14860
15074
|
getTelegramUpdates,
|
|
14861
15075
|
getTelegramWebhookInfo,
|
|
15076
|
+
getVoiceProvider,
|
|
14862
15077
|
hostSessionStoragePath,
|
|
14863
15078
|
inferPhoneRegion,
|
|
14864
15079
|
invalidateSkillCache,
|
|
@@ -14871,6 +15086,7 @@ export {
|
|
|
14871
15086
|
isTelegramStopCommand,
|
|
14872
15087
|
isValidPhoneNumber,
|
|
14873
15088
|
listSkills,
|
|
15089
|
+
listVoiceProviders,
|
|
14874
15090
|
loadAgentPersona,
|
|
14875
15091
|
loadHostSession,
|
|
14876
15092
|
loadSkill,
|
|
@@ -14891,6 +15107,7 @@ export {
|
|
|
14891
15107
|
personaPathFor,
|
|
14892
15108
|
planBridgeWake,
|
|
14893
15109
|
pollForOperatorAnswer,
|
|
15110
|
+
readAgentPersonaFile,
|
|
14894
15111
|
recallMemory,
|
|
14895
15112
|
recordToolCall,
|
|
14896
15113
|
redactBotToken,
|
|
@@ -14899,6 +15116,7 @@ export {
|
|
|
14899
15116
|
redactSecret,
|
|
14900
15117
|
redactSmsConfig,
|
|
14901
15118
|
redactTelegramConfig,
|
|
15119
|
+
registerVoiceProvider,
|
|
14902
15120
|
renderSkillAsPrompt,
|
|
14903
15121
|
requireBinary,
|
|
14904
15122
|
requireWhisperModel,
|
|
@@ -14906,6 +15124,7 @@ export {
|
|
|
14906
15124
|
resolveConfig,
|
|
14907
15125
|
resolveExtensionPolicy,
|
|
14908
15126
|
resolveTlsRejectUnauthorized,
|
|
15127
|
+
resolveVoiceRuntime,
|
|
14909
15128
|
safeJoin,
|
|
14910
15129
|
sanitizeEmail,
|
|
14911
15130
|
saveAgentPersona,
|
|
@@ -14927,6 +15146,7 @@ export {
|
|
|
14927
15146
|
threadIdFor,
|
|
14928
15147
|
tokenize,
|
|
14929
15148
|
tryJoin,
|
|
15149
|
+
updateAgentPersonaFrontmatter,
|
|
14930
15150
|
userSkillsDir,
|
|
14931
15151
|
validateApiUrl,
|
|
14932
15152
|
validatePhoneMissionPolicy,
|