@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.
@@ -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-DwBgs2Sq.js";
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 <= now) cache.seenUntil.delete(key);
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 > now) return true;
45
- cache.seenUntil.set(replayKey, now + REPLAY_WINDOW_MS);
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-DwBgs2Sq.js";
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 + 5e3);
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 = Date.now() + params.timeoutMs;
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
- call.endedAt ? `endedAt=${new Date(call.endedAt).toISOString()}` : void 0
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-DwBgs2Sq.js";
2
- import { n as reconstructWebhookUrl, r as verifyPlivoWebhook, t as guardedJsonApiRequest } from "./guarded-json-api-hXuXY1dk.js";
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
- this.pendingStreamTokens.set(token, {
582
- expiry: Date.now() + STREAM_TOKEN_TTL_MS,
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 (Date.now() > entry.expiry) this.pendingStreamTokens.delete(candidate);
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 (Date.now() > entry.expiry) return null;
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-DwBgs2Sq.js";
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 ?? params.ctx.config.maxDurationSeconds * 1e3;
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
- }, delaySec * 1e3);
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 * 1e3;
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 * 1e3;
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-C8EHsqMw.js");
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(now) {
3098
- for (const [key, entry] of this.replayResponses) if (entry.expiresAt <= now) this.replayResponses.delete(key);
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: now + WEBHOOK_REPLAY_RESPONSE_TTL_MS,
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-C8sgJugJ.js");
3287
+ telnyxProviderPromise ??= import("./telnyx-hEvdLe74.js");
3272
3288
  return telnyxProviderPromise;
3273
3289
  }
3274
3290
  function loadTwilioProvider() {
3275
- twilioProviderPromise ??= import("./twilio-CpBg6Ir5.js");
3291
+ twilioProviderPromise ??= import("./twilio-DWgnLf2U.js");
3276
3292
  return twilioProviderPromise;
3277
3293
  }
3278
3294
  function loadPlivoProvider() {
3279
- plivoProviderPromise ??= import("./plivo-CVgE_V_c.js");
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-DQDCDHv2.js");
3307
+ realtimeHandlerPromise ??= import("./realtime-handler-CtztDOAd.js");
3292
3308
  return realtimeHandlerPromise;
3293
3309
  }
3294
3310
  function resolveVoiceCallConsultSessionKey(call) {
@@ -1,2 +1,2 @@
1
- import { t as createVoiceCallRuntime } from "./runtime-entry-DwBgs2Sq.js";
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-hXuXY1dk.js";
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-DwBgs2Sq.js";
4
- import { a as verifyTwilioWebhook, t as guardedJsonApiRequest } from "./guarded-json-api-hXuXY1dk.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-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";
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@openclaw/voice-call",
3
- "version": "2026.5.28-beta.4",
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.28-beta.4",
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.28-beta.4"
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.28-beta.4",
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.28-beta.4"
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.28-beta.4"
34
+ "pluginApi": ">=2026.5.30-beta.1"
35
35
  },
36
36
  "build": {
37
- "openclawVersion": "2026.5.28-beta.4"
37
+ "openclawVersion": "2026.5.30-beta.1"
38
38
  },
39
39
  "release": {
40
40
  "publishToClawHub": true,