@openclaw/voice-call 2026.10.2 → 2026.10.5-beta.2
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/README.md +118 -3
- package/dist/.setup/{guarded-json-api-x55yqHvW.mjs → carrier-api-BYKw_fsQ.mjs} +94 -90
- package/dist/.setup/{cli-Cn1leykM.mjs → cli-dyyK8Upw.mjs} +66 -84
- package/dist/.setup/{config-CX9J-053.mjs → config-CsrGuamE.mjs} +95 -69
- package/dist/.setup/{mock-eLv_Dc4o.mjs → mock-rySvj-G6.mjs} +12 -3
- package/dist/.setup/{plivo-CpPIENu4.mjs → plivo-COfD-Kuc.mjs} +35 -89
- package/dist/.setup/{realtime-handler-Do7Sz7Gh.mjs → realtime-handler-BdAuKAC2.mjs} +749 -464
- package/dist/.setup/{response-generator-DAhbXEta.mjs → response-generator-COu0_8-d.mjs} +14 -32
- package/dist/.setup/{runtime-entry-CbSKxSKk.mjs → runtime-entry-STjFmi_B.mjs} +1053 -446
- package/dist/.setup/{telnyx-DPilutCH.mjs → telnyx-B4P0peEe.mjs} +30 -61
- package/dist/.setup/{twilio-BWFNGyVx.mjs → twilio-BzAYgH7M.mjs} +75 -90
- package/dist/.setup/{voice-mapping-B_iAUkER.mjs → voice-mapping-1lzFmzOF.mjs} +0 -10
- package/dist/cli-output-mode.js +1 -0
- package/dist/doctor-contract-api.js +19 -23
- package/dist/index.js +212 -89
- package/dist/runtime-entry.js +1 -1
- package/dist/setup-api.js +7 -6
- package/openclaw.plugin.json +210 -2
- package/package.json +4 -4
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { c as resolveVoiceCallSessionKey } from "./config-
|
|
2
|
-
import { m as
|
|
1
|
+
import { c as resolveVoiceCallSessionKey } from "./config-CsrGuamE.mjs";
|
|
2
|
+
import { m as resolveVoiceResponseModel, x as resolveCallAgentId } from "./runtime-entry-STjFmi_B.mjs";
|
|
3
3
|
import { normalizeLowercaseStringOrEmpty, normalizeStringEntries } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
4
4
|
import { resolveAgentConfig } from "openclaw/plugin-sdk/agent-scope-runtime";
|
|
5
5
|
import { isValidAgentHarnessSessionStoreEntry } from "openclaw/plugin-sdk/session-store-runtime";
|
|
@@ -8,10 +8,6 @@ import { truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
|
|
|
8
8
|
import { resolveDefaultModelForAgent } from "openclaw/plugin-sdk/agent-runtime";
|
|
9
9
|
import { ModelSelectionLockedError, applyModelOverrideWithAuthProfileCompatibility, resolvePersistedSessionRuntimeId } from "openclaw/plugin-sdk/model-session-runtime";
|
|
10
10
|
//#region extensions/voice-call/src/response-generator.ts
|
|
11
|
-
/**
|
|
12
|
-
* Voice call response generator - uses the embedded OpenClaw agent for tool support.
|
|
13
|
-
* Routes voice responses through the same agent infrastructure as messaging.
|
|
14
|
-
*/
|
|
15
11
|
const VOICE_SPOKEN_OUTPUT_CONTRACT = [
|
|
16
12
|
"Output format requirements:",
|
|
17
13
|
"- Return only valid JSON in this exact shape: {\"spoken\":\"...\"}",
|
|
@@ -103,36 +99,18 @@ function extractSpokenTextFromPayloads(payloads) {
|
|
|
103
99
|
if (payload.isError || payload.isReasoning) continue;
|
|
104
100
|
const rawText = payload.text?.trim() ?? "";
|
|
105
101
|
if (!rawText) continue;
|
|
106
|
-
const
|
|
107
|
-
if (
|
|
108
|
-
if (structured.length > 0) spokenSegments.push(structured);
|
|
109
|
-
continue;
|
|
110
|
-
}
|
|
111
|
-
const plain = sanitizePlainSpokenText(rawText);
|
|
112
|
-
if (plain) spokenSegments.push(plain);
|
|
113
|
-
}
|
|
114
|
-
return spokenSegments.length > 0 ? spokenSegments.join(" ").trim() : null;
|
|
115
|
-
}
|
|
116
|
-
async function deliverEarlyText(callback, text) {
|
|
117
|
-
try {
|
|
118
|
-
return await callback(text);
|
|
119
|
-
} catch (error) {
|
|
120
|
-
console.error("[voice-call] Early TTS delivery failed:", error);
|
|
121
|
-
return false;
|
|
102
|
+
const spoken = tryParseSpokenJson(rawText) ?? sanitizePlainSpokenText(rawText);
|
|
103
|
+
if (spoken) spokenSegments.push(spoken);
|
|
122
104
|
}
|
|
105
|
+
return spokenSegments.join(" ") || null;
|
|
123
106
|
}
|
|
124
107
|
function resolveVoiceSandboxSessionKey(agentId, sessionKey) {
|
|
125
108
|
const trimmed = sessionKey.trim();
|
|
126
109
|
if (trimmed.toLowerCase().startsWith("agent:")) return trimmed;
|
|
127
110
|
return `agent:${agentId}:${trimmed}`;
|
|
128
111
|
}
|
|
129
|
-
/**
|
|
130
|
-
* Generate a voice response using the embedded OpenClaw agent with full tool support.
|
|
131
|
-
* Uses the same agent infrastructure as messaging for consistent behavior.
|
|
132
|
-
*/
|
|
133
112
|
async function generateVoiceResponse(params) {
|
|
134
|
-
const { voiceConfig, callId, sessionKey, from, senderIsOwner, transcript, userMessage, coreConfig, agentRuntime, onEarlyText } = params;
|
|
135
|
-
const cfg = coreConfig;
|
|
113
|
+
const { voiceConfig, callId, sessionKey, from, senderIsOwner, transcript, userMessage, coreConfig: cfg, agentRuntime, onEarlyText } = params;
|
|
136
114
|
const agentId = resolveCallAgentId(params);
|
|
137
115
|
const resolvedSessionKey = resolveVoiceCallSessionKey({
|
|
138
116
|
config: {
|
|
@@ -142,7 +120,7 @@ async function generateVoiceResponse(params) {
|
|
|
142
120
|
callId,
|
|
143
121
|
phone: from,
|
|
144
122
|
explicitSessionKey: sessionKey,
|
|
145
|
-
coreSession:
|
|
123
|
+
coreSession: cfg.session
|
|
146
124
|
});
|
|
147
125
|
const toolsAllow = resolveAgentConfig(cfg, agentId)?.tools?.allow;
|
|
148
126
|
const storePath = agentRuntime.session.resolveStorePath(cfg.session?.store, { agentId });
|
|
@@ -155,7 +133,7 @@ async function generateVoiceResponse(params) {
|
|
|
155
133
|
const workspaceDir = agentRuntime.resolveAgentWorkspaceDir(cfg, agentId);
|
|
156
134
|
await agentRuntime.ensureAgentWorkspace({ dir: workspaceDir });
|
|
157
135
|
const now = Date.now();
|
|
158
|
-
|
|
136
|
+
let sessionEntry = agentRuntime.session.getSessionEntry({
|
|
159
137
|
storePath,
|
|
160
138
|
sessionKey: resolvedSessionKey
|
|
161
139
|
});
|
|
@@ -167,7 +145,6 @@ async function generateVoiceResponse(params) {
|
|
|
167
145
|
cfg,
|
|
168
146
|
agentId
|
|
169
147
|
});
|
|
170
|
-
let sessionEntry = existingSessionEntry;
|
|
171
148
|
if (sessionEntry?.modelSelectionLocked === true && voiceConfig.responseModel) throw new ModelSelectionLockedError();
|
|
172
149
|
if (!sessionEntry?.sessionId || voiceConfig.responseModel) sessionEntry = await agentRuntime.session.patchSessionEntry({
|
|
173
150
|
storePath,
|
|
@@ -292,7 +269,12 @@ async function generateVoiceResponse(params) {
|
|
|
292
269
|
const text = extractSpokenTextFromPayloads(pendingPayloads);
|
|
293
270
|
if (!text) return;
|
|
294
271
|
lastFlushedText = text;
|
|
295
|
-
|
|
272
|
+
try {
|
|
273
|
+
deliveredEarly = await onEarlyText(text);
|
|
274
|
+
} catch (error) {
|
|
275
|
+
console.error("[voice-call] Early TTS delivery failed:", error);
|
|
276
|
+
deliveredEarly = false;
|
|
277
|
+
}
|
|
296
278
|
}
|
|
297
279
|
});
|
|
298
280
|
const text = extractSpokenTextFromPayloads(result.payloads ?? []) ?? lastFlushedText ?? extractSpokenTextFromPayloads(blockReplyPayloads);
|