@openclaw/voice-call 2026.5.28-beta.4 → 2026.5.30-beta.1
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/{guarded-json-api-hXuXY1dk.js → guarded-json-api-BeaXjPdi.js} +6 -4
- package/dist/index.js +10 -6
- package/dist/{plivo-CVgE_V_c.js → plivo-sYOZg1xm.js} +2 -2
- package/dist/{realtime-handler-DQDCDHv2.js → realtime-handler-CtztDOAd.js} +7 -4
- package/dist/{response-generator-C8EHsqMw.js → response-generator-BdzG0ajq.js} +1 -1
- package/dist/{runtime-entry-DwBgs2Sq.js → runtime-entry-CDCNtGtn.js} +32 -16
- package/dist/runtime-entry.js +1 -1
- package/dist/{telnyx-C8sgJugJ.js → telnyx-hEvdLe74.js} +1 -1
- package/dist/{twilio-CpBg6Ir5.js → twilio-DWgnLf2U.js} +2 -2
- package/npm-shrinkwrap.json +3 -3
- package/package.json +4 -4
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { fetchWithSsrFGuard } from "./runtime-api.js";
|
|
2
2
|
import "./api.js";
|
|
3
|
-
import { a as getHeader } from "./runtime-entry-
|
|
3
|
+
import { a as getHeader } from "./runtime-entry-CDCNtGtn.js";
|
|
4
4
|
import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
|
|
5
5
|
import { isLoopbackHost } from "openclaw/plugin-sdk/gateway-runtime";
|
|
6
|
+
import { isFutureDateTimestampMs, resolveExpiresAtMsFromDurationMs } from "openclaw/plugin-sdk/number-runtime";
|
|
6
7
|
import { normalizeLowercaseStringOrEmpty, normalizeStringEntries } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
7
8
|
import crypto from "node:crypto";
|
|
8
9
|
import { safeEqualSecret } from "openclaw/plugin-sdk/security-runtime";
|
|
@@ -29,7 +30,7 @@ function createSkippedVerificationReplayKey(provider, ctx) {
|
|
|
29
30
|
return `${provider}:skip:${sha256Hex(`${ctx.method}\n${ctx.url}\n${ctx.rawBody}`)}`;
|
|
30
31
|
}
|
|
31
32
|
function pruneReplayCache(cache, now) {
|
|
32
|
-
for (const [key, expiresAt] of cache.seenUntil) if (expiresAt
|
|
33
|
+
for (const [key, expiresAt] of cache.seenUntil) if (!isFutureDateTimestampMs(expiresAt, { nowMs: now })) cache.seenUntil.delete(key);
|
|
33
34
|
while (cache.seenUntil.size > REPLAY_CACHE_MAX_ENTRIES) {
|
|
34
35
|
const oldest = cache.seenUntil.keys().next().value;
|
|
35
36
|
if (!oldest) break;
|
|
@@ -41,8 +42,9 @@ function markReplay(cache, replayKey) {
|
|
|
41
42
|
cache.calls += 1;
|
|
42
43
|
if (cache.calls % REPLAY_CACHE_PRUNE_INTERVAL === 0) pruneReplayCache(cache, now);
|
|
43
44
|
const existing = cache.seenUntil.get(replayKey);
|
|
44
|
-
if (existing && existing
|
|
45
|
-
|
|
45
|
+
if (existing !== void 0 && isFutureDateTimestampMs(existing, { nowMs: now })) return true;
|
|
46
|
+
const expiresAt = resolveExpiresAtMsFromDurationMs(REPLAY_WINDOW_MS, { nowMs: now });
|
|
47
|
+
if (expiresAt !== void 0) cache.seenUntil.set(replayKey, expiresAt);
|
|
46
48
|
if (cache.seenUntil.size > REPLAY_CACHE_MAX_ENTRIES) pruneReplayCache(cache, now);
|
|
47
49
|
return false;
|
|
48
50
|
}
|
package/dist/index.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { definePluginEntry, sleep } from "./runtime-api.js";
|
|
2
2
|
import "./api.js";
|
|
3
3
|
import { i as resolveVoiceCallConfig, s as validateProviderConfig } from "./config-U-rgixyY.js";
|
|
4
|
-
import { c as getTailscaleSelfInfo, l as setupTailscaleExposureRoute, o as resolveWebhookExposureStatus, p as resolveUserPath, s as cleanupTailscaleExposureRoute, t as createVoiceCallRuntime } from "./runtime-entry-
|
|
4
|
+
import { c as getTailscaleSelfInfo, l as setupTailscaleExposureRoute, o as resolveWebhookExposureStatus, p as resolveUserPath, s as cleanupTailscaleExposureRoute, t as createVoiceCallRuntime } from "./runtime-entry-CDCNtGtn.js";
|
|
5
5
|
import { i as parseVoiceCallPluginConfig, r as normalizeVoiceCallLegacyConfigInput, t as formatVoiceCallLegacyConfigWarnings } from "./config-compat-CokN3Zzr.js";
|
|
6
6
|
import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
|
|
7
7
|
import { ErrorCodes, callGatewayFromCli, errorShape } from "openclaw/plugin-sdk/gateway-runtime";
|
|
8
|
+
import { MAX_TCP_PORT, MAX_TIMER_TIMEOUT_MS, addTimerTimeoutGraceMs, clampTimerTimeoutMs, parseStrictNonNegativeInteger, timestampMsToIsoString } from "openclaw/plugin-sdk/number-runtime";
|
|
8
9
|
import { isRecord, normalizeOptionalLowercaseString, normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
9
10
|
import { Type } from "typebox";
|
|
10
11
|
import fs from "node:fs";
|
|
@@ -12,7 +13,6 @@ import os from "node:os";
|
|
|
12
13
|
import path from "node:path";
|
|
13
14
|
import { randomUUID } from "node:crypto";
|
|
14
15
|
import { format } from "node:util";
|
|
15
|
-
import { MAX_TCP_PORT, parseStrictNonNegativeInteger } from "openclaw/plugin-sdk/number-runtime";
|
|
16
16
|
//#region extensions/voice-call/src/cli.ts
|
|
17
17
|
const VOICE_CALL_GATEWAY_DEFAULT_TIMEOUT_MS = 5e3;
|
|
18
18
|
const VOICE_CALL_GATEWAY_OPERATION_TIMEOUT_MS = 3e4;
|
|
@@ -54,10 +54,13 @@ async function callVoiceCallGateway(method, params, opts) {
|
|
|
54
54
|
}
|
|
55
55
|
}
|
|
56
56
|
function resolveGatewayOperationTimeoutMs(config) {
|
|
57
|
-
return Math.max(VOICE_CALL_GATEWAY_OPERATION_TIMEOUT_MS, config.ringTimeoutMs
|
|
57
|
+
return Math.max(VOICE_CALL_GATEWAY_OPERATION_TIMEOUT_MS, addTimerTimeoutGraceMs(config.ringTimeoutMs) ?? 1);
|
|
58
58
|
}
|
|
59
59
|
function resolveGatewayContinueTimeoutMs(config) {
|
|
60
|
-
return config.transcriptTimeoutMs + VOICE_CALL_GATEWAY_OPERATION_TIMEOUT_MS + VOICE_CALL_GATEWAY_TRANSCRIPT_BUFFER_MS;
|
|
60
|
+
return clampTimerTimeoutMs(config.transcriptTimeoutMs + VOICE_CALL_GATEWAY_OPERATION_TIMEOUT_MS + VOICE_CALL_GATEWAY_TRANSCRIPT_BUFFER_MS) ?? 1;
|
|
61
|
+
}
|
|
62
|
+
function resolveVoiceCallDeadlineMs(timeoutMs, nowMs = Date.now()) {
|
|
63
|
+
return nowMs + (clampTimerTimeoutMs(timeoutMs) ?? MAX_TIMER_TIMEOUT_MS);
|
|
61
64
|
}
|
|
62
65
|
function isUnknownGatewayMethod(err, method) {
|
|
63
66
|
return formatErrorMessage(err).includes(`unknown method: ${method}`);
|
|
@@ -84,7 +87,7 @@ function readCompletedContinueResult(payload) {
|
|
|
84
87
|
throw new Error("voicecall gateway response has unknown operation status");
|
|
85
88
|
}
|
|
86
89
|
async function pollVoiceCallContinueGateway(params) {
|
|
87
|
-
const deadlineMs =
|
|
90
|
+
const deadlineMs = resolveVoiceCallDeadlineMs(params.timeoutMs);
|
|
88
91
|
while (Date.now() <= deadlineMs) {
|
|
89
92
|
const gateway = await callVoiceCallGateway("voicecall.continue.result", { operationId: params.operationId }, { timeoutMs: VOICE_CALL_GATEWAY_DEFAULT_TIMEOUT_MS });
|
|
90
93
|
if (!gateway.ok) throw new Error(`gateway unavailable while waiting for voicecall continue result: ${formatErrorMessage(gateway.error)}`);
|
|
@@ -954,10 +957,11 @@ var voice_call_default = definePluginEntry({
|
|
|
954
957
|
const describeHistoricalCall = async (rt, callId) => {
|
|
955
958
|
const call = (await rt.manager.getCallHistory(100)).toReversed().find((candidate) => candidate.callId === callId || candidate.providerCallId === callId);
|
|
956
959
|
if (!call) return;
|
|
960
|
+
const endedAt = timestampMsToIsoString(call.endedAt);
|
|
957
961
|
return `call is not active (${[
|
|
958
962
|
`last state=${call.state}`,
|
|
959
963
|
call.endReason ? `endReason=${call.endReason}` : void 0,
|
|
960
|
-
|
|
964
|
+
endedAt ? `endedAt=${endedAt}` : void 0
|
|
961
965
|
].filter(Boolean).join(", ")})`;
|
|
962
966
|
};
|
|
963
967
|
const resolveCallMessageRequest = async (params) => {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { a as getHeader, m as escapeXml } from "./runtime-entry-
|
|
2
|
-
import { n as reconstructWebhookUrl, r as verifyPlivoWebhook, t as guardedJsonApiRequest } from "./guarded-json-api-
|
|
1
|
+
import { a as getHeader, m as escapeXml } from "./runtime-entry-CDCNtGtn.js";
|
|
2
|
+
import { n as reconstructWebhookUrl, r as verifyPlivoWebhook, t as guardedJsonApiRequest } from "./guarded-json-api-BeaXjPdi.js";
|
|
3
3
|
import { normalizeLowercaseStringOrEmpty, normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
4
4
|
import crypto from "node:crypto";
|
|
5
5
|
//#region extensions/voice-call/src/providers/plivo.ts
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
|
|
2
|
+
import { isFutureDateTimestampMs, resolveExpiresAtMsFromDurationMs } from "openclaw/plugin-sdk/number-runtime";
|
|
2
3
|
import { createSubsystemLogger } from "openclaw/plugin-sdk/runtime-env";
|
|
3
4
|
import { REALTIME_VOICE_AGENT_CONSULT_TOOL_NAME, buildRealtimeVoiceAgentConsultWorkingResponse, createRealtimeVoiceBridgeSession, createRealtimeVoiceForcedConsultCoordinator, createTalkSessionController, readRealtimeVoiceConsultQuestion, readSpeakableRealtimeVoiceToolResult, recordTalkObservabilityEvent } from "openclaw/plugin-sdk/realtime-voice";
|
|
4
5
|
import { randomUUID } from "node:crypto";
|
|
@@ -578,18 +579,20 @@ var RealtimeCallHandler = class {
|
|
|
578
579
|
}
|
|
579
580
|
issueStreamToken(meta = {}) {
|
|
580
581
|
const token = randomUUID();
|
|
581
|
-
|
|
582
|
-
|
|
582
|
+
const now = Date.now();
|
|
583
|
+
const expiry = resolveExpiresAtMsFromDurationMs(STREAM_TOKEN_TTL_MS, { nowMs: now });
|
|
584
|
+
if (expiry !== void 0) this.pendingStreamTokens.set(token, {
|
|
585
|
+
expiry,
|
|
583
586
|
...meta
|
|
584
587
|
});
|
|
585
|
-
for (const [candidate, entry] of this.pendingStreamTokens) if (
|
|
588
|
+
for (const [candidate, entry] of this.pendingStreamTokens) if (!isFutureDateTimestampMs(entry.expiry, { nowMs: now })) this.pendingStreamTokens.delete(candidate);
|
|
586
589
|
return token;
|
|
587
590
|
}
|
|
588
591
|
consumeStreamToken(token) {
|
|
589
592
|
const entry = this.pendingStreamTokens.get(token);
|
|
590
593
|
if (!entry) return null;
|
|
591
594
|
this.pendingStreamTokens.delete(token);
|
|
592
|
-
if (
|
|
595
|
+
if (!isFutureDateTimestampMs(entry.expiry)) return null;
|
|
593
596
|
return {
|
|
594
597
|
from: entry.from,
|
|
595
598
|
to: entry.to,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { o as resolveVoiceCallSessionKey } from "./config-U-rgixyY.js";
|
|
2
|
-
import { f as resolveVoiceResponseModel } from "./runtime-entry-
|
|
2
|
+
import { f as resolveVoiceResponseModel } from "./runtime-entry-CDCNtGtn.js";
|
|
3
3
|
import { isRecord, normalizeLowercaseStringOrEmpty, normalizeStringEntries } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
4
4
|
import crypto from "node:crypto";
|
|
5
5
|
import { applyModelOverrideToSessionEntry } from "openclaw/plugin-sdk/model-session-runtime";
|
|
@@ -3,6 +3,7 @@ import "./api.js";
|
|
|
3
3
|
import { a as resolveVoiceCallEffectiveConfig, c as deepMergeDefined, i as resolveVoiceCallConfig, n as normalizeVoiceCallConfig, o as resolveVoiceCallSessionKey, r as resolveTwilioAuthToken, s as validateProviderConfig } from "./config-U-rgixyY.js";
|
|
4
4
|
import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
|
|
5
5
|
import { isLoopbackHost } from "openclaw/plugin-sdk/gateway-runtime";
|
|
6
|
+
import { MAX_TIMER_TIMEOUT_MS, asDateTimestampMs, resolveExpiresAtMsFromDurationMs, resolveTimerTimeoutMs } from "openclaw/plugin-sdk/number-runtime";
|
|
6
7
|
import { normalizeLowercaseStringOrEmpty, normalizeOptionalLowercaseString, normalizeOptionalString, normalizeStringEntries } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
7
8
|
import { REALTIME_VOICE_AGENT_CONSULT_TOOL_NAME, buildRealtimeVoiceAgentConsultPolicyInstructions, consultRealtimeVoiceAgent, convertPcmToMulaw8k, createTalkSessionController, recordTalkObservabilityEvent, resolveRealtimeVoiceAgentConsultTools, resolveRealtimeVoiceAgentConsultToolsAllow, resolveRealtimeVoiceFastContextConsult } from "openclaw/plugin-sdk/realtime-voice";
|
|
8
9
|
import { z } from "zod";
|
|
@@ -241,6 +242,16 @@ async function getCallHistoryFromStore(storePath, limit = 50) {
|
|
|
241
242
|
return calls;
|
|
242
243
|
}
|
|
243
244
|
//#endregion
|
|
245
|
+
//#region extensions/voice-call/src/manager/timer-delays.ts
|
|
246
|
+
function resolveVoiceCallSecondsTimerDelayMs(seconds, minMs = 1) {
|
|
247
|
+
if (!Number.isFinite(seconds)) return resolveTimerTimeoutMs(MAX_TIMER_TIMEOUT_MS, MAX_TIMER_TIMEOUT_MS, minMs);
|
|
248
|
+
const timeoutMs = Math.floor(seconds * 1e3);
|
|
249
|
+
return resolveTimerTimeoutMs(Number.isFinite(timeoutMs) ? timeoutMs : MAX_TIMER_TIMEOUT_MS, minMs, minMs);
|
|
250
|
+
}
|
|
251
|
+
function resolveVoiceCallTimerDelayMs(timeoutMs, fallbackMs = 1) {
|
|
252
|
+
return resolveTimerTimeoutMs(timeoutMs, fallbackMs);
|
|
253
|
+
}
|
|
254
|
+
//#endregion
|
|
244
255
|
//#region extensions/voice-call/src/manager/timers.ts
|
|
245
256
|
function clearMaxDurationTimer(ctx, callId) {
|
|
246
257
|
const timer = ctx.maxDurationTimers.get(callId);
|
|
@@ -251,7 +262,7 @@ function clearMaxDurationTimer(ctx, callId) {
|
|
|
251
262
|
}
|
|
252
263
|
function startMaxDurationTimer(params) {
|
|
253
264
|
clearMaxDurationTimer(params.ctx, params.callId);
|
|
254
|
-
const maxDurationMs = params.timeoutMs
|
|
265
|
+
const maxDurationMs = params.timeoutMs === void 0 ? resolveVoiceCallSecondsTimerDelayMs(params.ctx.config.maxDurationSeconds) : resolveVoiceCallTimerDelayMs(params.timeoutMs);
|
|
255
266
|
console.log(`[voice-call] Starting max duration timer (${Math.ceil(maxDurationMs / 1e3)}s) for call ${params.callId}`);
|
|
256
267
|
const timer = setTimeout(async () => {
|
|
257
268
|
params.ctx.maxDurationTimers.delete(params.callId);
|
|
@@ -287,7 +298,7 @@ function resolveTranscriptWaiter(ctx, callId, transcript, turnToken) {
|
|
|
287
298
|
}
|
|
288
299
|
function waitForFinalTranscript(ctx, callId, turnToken) {
|
|
289
300
|
if (ctx.transcriptWaiters.has(callId)) return Promise.reject(/* @__PURE__ */ new Error("Already waiting for transcript"));
|
|
290
|
-
const timeoutMs = ctx.config.transcriptTimeoutMs;
|
|
301
|
+
const timeoutMs = resolveVoiceCallTimerDelayMs(ctx.config.transcriptTimeoutMs);
|
|
291
302
|
return new Promise((resolve, reject) => {
|
|
292
303
|
const timeout = setTimeout(() => {
|
|
293
304
|
ctx.transcriptWaiters.delete(callId);
|
|
@@ -654,6 +665,7 @@ async function speakInitialMessage(ctx, providerCallId) {
|
|
|
654
665
|
}
|
|
655
666
|
if (mode === "notify") {
|
|
656
667
|
const delaySec = ctx.config.outbound.notifyHangupDelaySec;
|
|
668
|
+
const delayMs = resolveVoiceCallSecondsTimerDelayMs(delaySec, 0);
|
|
657
669
|
console.log(`[voice-call] Notify mode: auto-hangup in ${delaySec}s for call ${call.callId}`);
|
|
658
670
|
setTimeout(async () => {
|
|
659
671
|
const currentCall = ctx.activeCalls.get(call.callId);
|
|
@@ -661,7 +673,7 @@ async function speakInitialMessage(ctx, providerCallId) {
|
|
|
661
673
|
console.log(`[voice-call] Notify mode: hanging up call ${call.callId}`);
|
|
662
674
|
await endCall(ctx, call.callId);
|
|
663
675
|
}
|
|
664
|
-
},
|
|
676
|
+
}, delayMs);
|
|
665
677
|
} else if (mode === "conversation" && ctx.provider && shouldStartListeningAfterInitialMessage(ctx)) {
|
|
666
678
|
transitionState(call, "listening");
|
|
667
679
|
persistCallRecord(ctx.storePath, call);
|
|
@@ -1047,7 +1059,7 @@ var CallManager = class {
|
|
|
1047
1059
|
let skippedAlreadyElapsedTimers = 0;
|
|
1048
1060
|
for (const [callId, call] of verified) if (call.answeredAt && !TerminalStates.has(call.state)) {
|
|
1049
1061
|
const elapsed = Date.now() - call.answeredAt;
|
|
1050
|
-
const maxDurationMs = this.config.maxDurationSeconds
|
|
1062
|
+
const maxDurationMs = resolveVoiceCallSecondsTimerDelayMs(this.config.maxDurationSeconds);
|
|
1051
1063
|
if (elapsed >= maxDurationMs) {
|
|
1052
1064
|
verified.delete(callId);
|
|
1053
1065
|
if (call.providerCallId) this.providerCallIdMap.delete(call.providerCallId);
|
|
@@ -1074,7 +1086,7 @@ var CallManager = class {
|
|
|
1074
1086
|
*/
|
|
1075
1087
|
async verifyRestoredCalls(provider, candidates) {
|
|
1076
1088
|
if (candidates.size === 0) return /* @__PURE__ */ new Map();
|
|
1077
|
-
const maxAgeMs = this.config.maxDurationSeconds
|
|
1089
|
+
const maxAgeMs = resolveVoiceCallSecondsTimerDelayMs(this.config.maxDurationSeconds);
|
|
1078
1090
|
const now = Date.now();
|
|
1079
1091
|
const verified = /* @__PURE__ */ new Map();
|
|
1080
1092
|
const verifyTasks = [];
|
|
@@ -2588,7 +2600,7 @@ function loadRealtimeTranscriptionRuntime() {
|
|
|
2588
2600
|
return realtimeTranscriptionRuntimePromise;
|
|
2589
2601
|
}
|
|
2590
2602
|
function loadResponseGeneratorModule() {
|
|
2591
|
-
responseGeneratorModulePromise ??= import("./response-generator-
|
|
2603
|
+
responseGeneratorModulePromise ??= import("./response-generator-BdzG0ajq.js");
|
|
2592
2604
|
return responseGeneratorModulePromise;
|
|
2593
2605
|
}
|
|
2594
2606
|
function sanitizeTranscriptForLog(value) {
|
|
@@ -3094,8 +3106,11 @@ var VoiceCallWebhookServer = class {
|
|
|
3094
3106
|
this.webhookInFlightLimiter.release(inFlightKey);
|
|
3095
3107
|
}
|
|
3096
3108
|
}
|
|
3097
|
-
pruneReplayResponses(
|
|
3098
|
-
|
|
3109
|
+
pruneReplayResponses(rawNow) {
|
|
3110
|
+
const now = asDateTimestampMs(rawNow);
|
|
3111
|
+
if (now !== void 0) {
|
|
3112
|
+
for (const [key, entry] of this.replayResponses) if (entry.expiresAt <= now) this.replayResponses.delete(key);
|
|
3113
|
+
}
|
|
3099
3114
|
while (this.replayResponses.size > WEBHOOK_REPLAY_RESPONSE_MAX_ENTRIES) {
|
|
3100
3115
|
const oldest = this.replayResponses.keys().next().value;
|
|
3101
3116
|
if (!oldest) break;
|
|
@@ -3103,9 +3118,9 @@ var VoiceCallWebhookServer = class {
|
|
|
3103
3118
|
}
|
|
3104
3119
|
}
|
|
3105
3120
|
async getCachedReplayResponse(key) {
|
|
3106
|
-
const now = Date.now();
|
|
3121
|
+
const now = asDateTimestampMs(Date.now());
|
|
3107
3122
|
const entry = this.replayResponses.get(key);
|
|
3108
|
-
if (!entry) return null;
|
|
3123
|
+
if (!entry || now === void 0) return null;
|
|
3109
3124
|
if (entry.expiresAt <= now) {
|
|
3110
3125
|
this.replayResponses.delete(key);
|
|
3111
3126
|
return null;
|
|
@@ -3114,14 +3129,15 @@ var VoiceCallWebhookServer = class {
|
|
|
3114
3129
|
}
|
|
3115
3130
|
async cacheReplayResponse(key, buildResponse) {
|
|
3116
3131
|
const now = Date.now();
|
|
3132
|
+
const expiresAt = resolveExpiresAtMsFromDurationMs(WEBHOOK_REPLAY_RESPONSE_TTL_MS, { nowMs: now });
|
|
3117
3133
|
this.replayResponseCacheCalls += 1;
|
|
3118
3134
|
if (this.replayResponseCacheCalls % WEBHOOK_REPLAY_RESPONSE_PRUNE_INTERVAL === 0) this.pruneReplayResponses(now);
|
|
3119
3135
|
const response = buildResponse().then(cloneWebhookResponsePayload).catch((err) => {
|
|
3120
3136
|
this.replayResponses.delete(key);
|
|
3121
3137
|
throw err;
|
|
3122
3138
|
});
|
|
3123
|
-
this.replayResponses.set(key, {
|
|
3124
|
-
expiresAt
|
|
3139
|
+
if (expiresAt !== void 0) this.replayResponses.set(key, {
|
|
3140
|
+
expiresAt,
|
|
3125
3141
|
response
|
|
3126
3142
|
});
|
|
3127
3143
|
if (this.replayResponses.size > WEBHOOK_REPLAY_RESPONSE_MAX_ENTRIES) this.pruneReplayResponses(now);
|
|
@@ -3268,15 +3284,15 @@ let mockProviderPromise;
|
|
|
3268
3284
|
let realtimeVoiceRuntimePromise;
|
|
3269
3285
|
let realtimeHandlerPromise;
|
|
3270
3286
|
function loadTelnyxProvider() {
|
|
3271
|
-
telnyxProviderPromise ??= import("./telnyx-
|
|
3287
|
+
telnyxProviderPromise ??= import("./telnyx-hEvdLe74.js");
|
|
3272
3288
|
return telnyxProviderPromise;
|
|
3273
3289
|
}
|
|
3274
3290
|
function loadTwilioProvider() {
|
|
3275
|
-
twilioProviderPromise ??= import("./twilio-
|
|
3291
|
+
twilioProviderPromise ??= import("./twilio-DWgnLf2U.js");
|
|
3276
3292
|
return twilioProviderPromise;
|
|
3277
3293
|
}
|
|
3278
3294
|
function loadPlivoProvider() {
|
|
3279
|
-
plivoProviderPromise ??= import("./plivo-
|
|
3295
|
+
plivoProviderPromise ??= import("./plivo-sYOZg1xm.js");
|
|
3280
3296
|
return plivoProviderPromise;
|
|
3281
3297
|
}
|
|
3282
3298
|
function loadMockProvider() {
|
|
@@ -3288,7 +3304,7 @@ function loadRealtimeVoiceRuntime() {
|
|
|
3288
3304
|
return realtimeVoiceRuntimePromise;
|
|
3289
3305
|
}
|
|
3290
3306
|
function loadRealtimeHandler() {
|
|
3291
|
-
realtimeHandlerPromise ??= import("./realtime-handler-
|
|
3307
|
+
realtimeHandlerPromise ??= import("./realtime-handler-CtztDOAd.js");
|
|
3292
3308
|
return realtimeHandlerPromise;
|
|
3293
3309
|
}
|
|
3294
3310
|
function resolveVoiceCallConsultSessionKey(call) {
|
package/dist/runtime-entry.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as createVoiceCallRuntime } from "./runtime-entry-
|
|
1
|
+
import { t as createVoiceCallRuntime } from "./runtime-entry-CDCNtGtn.js";
|
|
2
2
|
export { createVoiceCallRuntime };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { i as verifyTelnyxWebhook, t as guardedJsonApiRequest } from "./guarded-json-api-
|
|
1
|
+
import { i as verifyTelnyxWebhook, t as guardedJsonApiRequest } from "./guarded-json-api-BeaXjPdi.js";
|
|
2
2
|
import crypto from "node:crypto";
|
|
3
3
|
//#region extensions/voice-call/src/providers/telnyx.ts
|
|
4
4
|
function normalizeTelnyxDirection(direction) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { fetchWithSsrFGuard } from "./runtime-api.js";
|
|
2
2
|
import "./api.js";
|
|
3
|
-
import { a as getHeader, d as chunkAudio, h as mapVoiceToPolly, i as normalizeProviderStatus, m as escapeXml, n as isProviderStatusTerminal, r as mapProviderStatusToEndReason } from "./runtime-entry-
|
|
4
|
-
import { a as verifyTwilioWebhook, t as guardedJsonApiRequest } from "./guarded-json-api-
|
|
3
|
+
import { a as getHeader, d as chunkAudio, h as mapVoiceToPolly, i as normalizeProviderStatus, m as escapeXml, n as isProviderStatusTerminal, r as mapProviderStatusToEndReason } from "./runtime-entry-CDCNtGtn.js";
|
|
4
|
+
import { a as verifyTwilioWebhook, t as guardedJsonApiRequest } from "./guarded-json-api-BeaXjPdi.js";
|
|
5
5
|
import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
6
6
|
import crypto from "node:crypto";
|
|
7
7
|
import { safeEqualSecret } from "openclaw/plugin-sdk/security-runtime";
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openclaw/voice-call",
|
|
3
|
-
"version": "2026.5.
|
|
3
|
+
"version": "2026.5.30-beta.1",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@openclaw/voice-call",
|
|
9
|
-
"version": "2026.5.
|
|
9
|
+
"version": "2026.5.30-beta.1",
|
|
10
10
|
"dependencies": {
|
|
11
11
|
"commander": "14.0.3",
|
|
12
12
|
"typebox": "1.1.38",
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
"zod": "4.4.3"
|
|
15
15
|
},
|
|
16
16
|
"peerDependencies": {
|
|
17
|
-
"openclaw": ">=2026.5.
|
|
17
|
+
"openclaw": ">=2026.5.30-beta.1"
|
|
18
18
|
},
|
|
19
19
|
"peerDependenciesMeta": {
|
|
20
20
|
"openclaw": {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openclaw/voice-call",
|
|
3
|
-
"version": "2026.5.
|
|
3
|
+
"version": "2026.5.30-beta.1",
|
|
4
4
|
"description": "OpenClaw voice-call plugin for Twilio, Telnyx, and Plivo phone calls.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
"zod": "4.4.3"
|
|
15
15
|
},
|
|
16
16
|
"peerDependencies": {
|
|
17
|
-
"openclaw": ">=2026.5.
|
|
17
|
+
"openclaw": ">=2026.5.30-beta.1"
|
|
18
18
|
},
|
|
19
19
|
"peerDependenciesMeta": {
|
|
20
20
|
"openclaw": {
|
|
@@ -31,10 +31,10 @@
|
|
|
31
31
|
"minHostVersion": ">=2026.4.10"
|
|
32
32
|
},
|
|
33
33
|
"compat": {
|
|
34
|
-
"pluginApi": ">=2026.5.
|
|
34
|
+
"pluginApi": ">=2026.5.30-beta.1"
|
|
35
35
|
},
|
|
36
36
|
"build": {
|
|
37
|
-
"openclawVersion": "2026.5.
|
|
37
|
+
"openclawVersion": "2026.5.30-beta.1"
|
|
38
38
|
},
|
|
39
39
|
"release": {
|
|
40
40
|
"publishToClawHub": true,
|