@openclaw/voice-call 2026.3.13 → 2026.5.2-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/README.md +27 -5
- package/api.ts +16 -0
- package/cli-metadata.ts +10 -0
- package/config-api.ts +12 -0
- package/index.test.ts +943 -0
- package/index.ts +379 -149
- package/openclaw.plugin.json +384 -157
- package/package.json +35 -5
- package/runtime-api.ts +20 -0
- package/runtime-entry.ts +1 -0
- package/setup-api.ts +47 -0
- package/src/allowlist.test.ts +18 -0
- package/src/cli.ts +533 -68
- package/src/config-compat.test.ts +120 -0
- package/src/config-compat.ts +227 -0
- package/src/config.test.ts +273 -12
- package/src/config.ts +355 -72
- package/src/core-bridge.ts +2 -147
- package/src/deep-merge.test.ts +40 -0
- package/src/gateway-continue-operation.ts +200 -0
- package/src/http-headers.ts +6 -3
- package/src/manager/context.ts +6 -5
- package/src/manager/events.test.ts +243 -19
- package/src/manager/events.ts +61 -31
- package/src/manager/lifecycle.ts +53 -0
- package/src/manager/lookup.test.ts +52 -0
- package/src/manager/outbound.test.ts +528 -0
- package/src/manager/outbound.ts +163 -57
- package/src/manager/store.ts +18 -6
- package/src/manager/timers.test.ts +129 -0
- package/src/manager/timers.ts +4 -3
- package/src/manager/twiml.test.ts +13 -0
- package/src/manager/twiml.ts +8 -0
- package/src/manager.closed-loop.test.ts +30 -12
- package/src/manager.inbound-allowlist.test.ts +77 -10
- package/src/manager.notify.test.ts +344 -20
- package/src/manager.restore.test.ts +95 -8
- package/src/manager.test-harness.ts +8 -6
- package/src/manager.ts +79 -5
- package/src/media-stream.test.ts +578 -81
- package/src/media-stream.ts +235 -54
- package/src/providers/base.ts +19 -0
- package/src/providers/mock.ts +7 -1
- package/src/providers/plivo.test.ts +50 -6
- package/src/providers/plivo.ts +14 -6
- package/src/providers/shared/call-status.ts +2 -1
- package/src/providers/shared/guarded-json-api.test.ts +106 -0
- package/src/providers/shared/guarded-json-api.ts +1 -1
- package/src/providers/telnyx.test.ts +178 -6
- package/src/providers/telnyx.ts +40 -3
- package/src/providers/twilio/api.test.ts +145 -0
- package/src/providers/twilio/api.ts +67 -16
- package/src/providers/twilio/twiml-policy.ts +6 -10
- package/src/providers/twilio/webhook.ts +1 -1
- package/src/providers/twilio.test.ts +425 -25
- package/src/providers/twilio.ts +230 -77
- package/src/providers/twilio.types.ts +17 -0
- package/src/realtime-defaults.ts +3 -0
- package/src/realtime-fast-context.test.ts +88 -0
- package/src/realtime-fast-context.ts +165 -0
- package/src/realtime-transcription.runtime.ts +4 -0
- package/src/realtime-voice.runtime.ts +5 -0
- package/src/response-generator.test.ts +321 -0
- package/src/response-generator.ts +213 -53
- package/src/response-model.test.ts +71 -0
- package/src/response-model.ts +23 -0
- package/src/runtime.test.ts +429 -0
- package/src/runtime.ts +270 -24
- package/src/telephony-audio.test.ts +61 -0
- package/src/telephony-audio.ts +1 -79
- package/src/telephony-tts.test.ts +133 -12
- package/src/telephony-tts.ts +155 -2
- package/src/test-fixtures.ts +28 -7
- package/src/tts-provider-voice.test.ts +34 -0
- package/src/tts-provider-voice.ts +21 -0
- package/src/tunnel.test.ts +166 -0
- package/src/tunnel.ts +1 -1
- package/src/types.ts +24 -37
- package/src/utils.test.ts +17 -0
- package/src/voice-mapping.test.ts +34 -0
- package/src/voice-mapping.ts +3 -2
- package/src/webhook/realtime-handler.test.ts +598 -0
- package/src/webhook/realtime-handler.ts +485 -0
- package/src/webhook/stale-call-reaper.test.ts +88 -0
- package/src/webhook/stale-call-reaper.ts +5 -0
- package/src/webhook/tailscale.test.ts +214 -0
- package/src/webhook/tailscale.ts +19 -5
- package/src/webhook-exposure.test.ts +33 -0
- package/src/webhook-exposure.ts +84 -0
- package/src/webhook-security.test.ts +172 -21
- package/src/webhook-security.ts +43 -29
- package/src/webhook.hangup-once.lifecycle.test.ts +135 -0
- package/src/webhook.test.ts +1145 -27
- package/src/webhook.ts +523 -102
- package/src/webhook.types.ts +5 -0
- package/src/websocket-test-support.ts +72 -0
- package/tsconfig.json +16 -0
- package/CHANGELOG.md +0 -121
- package/src/providers/index.ts +0 -10
- package/src/providers/stt-openai-realtime.test.ts +0 -42
- package/src/providers/stt-openai-realtime.ts +0 -311
- package/src/providers/tts-openai.test.ts +0 -43
- package/src/providers/tts-openai.ts +0 -221
package/package.json
CHANGED
|
@@ -1,17 +1,47 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openclaw/voice-call",
|
|
3
|
-
"version": "2026.
|
|
3
|
+
"version": "2026.5.2-beta.1",
|
|
4
4
|
"description": "OpenClaw voice-call plugin",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "https://github.com/openclaw/openclaw"
|
|
8
|
+
},
|
|
5
9
|
"type": "module",
|
|
6
10
|
"dependencies": {
|
|
7
|
-
"@sinclair/typebox": "0.34.48",
|
|
8
11
|
"commander": "^14.0.3",
|
|
9
|
-
"
|
|
10
|
-
"
|
|
12
|
+
"typebox": "1.1.37",
|
|
13
|
+
"ws": "^8.20.0"
|
|
14
|
+
},
|
|
15
|
+
"devDependencies": {
|
|
16
|
+
"@openclaw/plugin-sdk": "workspace:*",
|
|
17
|
+
"openclaw": "workspace:*"
|
|
18
|
+
},
|
|
19
|
+
"peerDependencies": {
|
|
20
|
+
"openclaw": ">=2026.5.2-beta.1"
|
|
21
|
+
},
|
|
22
|
+
"peerDependenciesMeta": {
|
|
23
|
+
"openclaw": {
|
|
24
|
+
"optional": true
|
|
25
|
+
}
|
|
11
26
|
},
|
|
12
27
|
"openclaw": {
|
|
13
28
|
"extensions": [
|
|
14
29
|
"./index.ts"
|
|
15
|
-
]
|
|
30
|
+
],
|
|
31
|
+
"install": {
|
|
32
|
+
"npmSpec": "@openclaw/voice-call",
|
|
33
|
+
"defaultChoice": "npm",
|
|
34
|
+
"minHostVersion": ">=2026.4.10"
|
|
35
|
+
},
|
|
36
|
+
"compat": {
|
|
37
|
+
"pluginApi": ">=2026.5.2-beta.1"
|
|
38
|
+
},
|
|
39
|
+
"build": {
|
|
40
|
+
"openclawVersion": "2026.5.2-beta.1"
|
|
41
|
+
},
|
|
42
|
+
"release": {
|
|
43
|
+
"publishToClawHub": true,
|
|
44
|
+
"publishToNpm": true
|
|
45
|
+
}
|
|
16
46
|
}
|
|
17
47
|
}
|
package/runtime-api.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
// Private runtime barrel for the bundled Voice Call extension.
|
|
2
|
+
// Keep this barrel thin and aligned with the local extension surface.
|
|
3
|
+
|
|
4
|
+
export { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";
|
|
5
|
+
export type { OpenClawPluginApi } from "openclaw/plugin-sdk/plugin-entry";
|
|
6
|
+
export type { GatewayRequestHandlerOptions } from "openclaw/plugin-sdk/gateway-runtime";
|
|
7
|
+
export {
|
|
8
|
+
isRequestBodyLimitError,
|
|
9
|
+
readRequestBodyWithLimit,
|
|
10
|
+
requestBodyErrorToText,
|
|
11
|
+
} from "openclaw/plugin-sdk/webhook-request-guards";
|
|
12
|
+
export { fetchWithSsrFGuard, isBlockedHostnameOrIp } from "openclaw/plugin-sdk/ssrf-runtime";
|
|
13
|
+
export type { SessionEntry } from "openclaw/plugin-sdk/session-store-runtime";
|
|
14
|
+
export {
|
|
15
|
+
TtsAutoSchema,
|
|
16
|
+
TtsConfigSchema,
|
|
17
|
+
TtsModeSchema,
|
|
18
|
+
TtsProviderSchema,
|
|
19
|
+
} from "openclaw/plugin-sdk/tts-runtime";
|
|
20
|
+
export { sleep } from "openclaw/plugin-sdk/runtime-env";
|
package/runtime-entry.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { createVoiceCallRuntime, type VoiceCallRuntime } from "./src/runtime.js";
|
package/setup-api.ts
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { OpenClawConfig } from "openclaw/plugin-sdk/plugin-entry";
|
|
2
|
+
import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";
|
|
3
|
+
import { isRecord } from "openclaw/plugin-sdk/text-runtime";
|
|
4
|
+
import { migrateVoiceCallLegacyConfigInput } from "./config-api.js";
|
|
5
|
+
|
|
6
|
+
function migrateVoiceCallPluginConfig(config: OpenClawConfig): {
|
|
7
|
+
config: OpenClawConfig;
|
|
8
|
+
changes: string[];
|
|
9
|
+
} | null {
|
|
10
|
+
const rawVoiceCallConfig = config.plugins?.entries?.["voice-call"]?.config;
|
|
11
|
+
if (!isRecord(rawVoiceCallConfig)) {
|
|
12
|
+
return null;
|
|
13
|
+
}
|
|
14
|
+
const migration = migrateVoiceCallLegacyConfigInput({
|
|
15
|
+
value: rawVoiceCallConfig,
|
|
16
|
+
configPathPrefix: "plugins.entries.voice-call.config",
|
|
17
|
+
});
|
|
18
|
+
if (migration.changes.length === 0) {
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
const plugins = structuredClone(config.plugins ?? {});
|
|
22
|
+
const entries = { ...plugins.entries };
|
|
23
|
+
const existingVoiceCallEntry = isRecord(entries["voice-call"])
|
|
24
|
+
? (entries["voice-call"] as Record<string, unknown>)
|
|
25
|
+
: {};
|
|
26
|
+
entries["voice-call"] = {
|
|
27
|
+
...existingVoiceCallEntry,
|
|
28
|
+
config: migration.config,
|
|
29
|
+
};
|
|
30
|
+
plugins.entries = entries;
|
|
31
|
+
return {
|
|
32
|
+
config: {
|
|
33
|
+
...config,
|
|
34
|
+
plugins,
|
|
35
|
+
},
|
|
36
|
+
changes: migration.changes,
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export default definePluginEntry({
|
|
41
|
+
id: "voice-call",
|
|
42
|
+
name: "Voice Call Setup",
|
|
43
|
+
description: "Lightweight Voice Call setup hooks",
|
|
44
|
+
register(api) {
|
|
45
|
+
api.registerConfigMigration((config) => migrateVoiceCallPluginConfig(config));
|
|
46
|
+
},
|
|
47
|
+
});
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { isAllowlistedCaller, normalizePhoneNumber } from "./allowlist.js";
|
|
3
|
+
|
|
4
|
+
describe("voice-call allowlist", () => {
|
|
5
|
+
it("normalizes phone numbers by stripping non-digits", () => {
|
|
6
|
+
expect(normalizePhoneNumber("+1 (415) 555-0123")).toBe("14155550123");
|
|
7
|
+
expect(normalizePhoneNumber(" 020-7946-0958 ")).toBe("02079460958");
|
|
8
|
+
expect(normalizePhoneNumber("")).toBe("");
|
|
9
|
+
expect(normalizePhoneNumber()).toBe("");
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
it("matches normalized allowlist entries and rejects blank callers", () => {
|
|
13
|
+
expect(isAllowlistedCaller("14155550123", ["+1 (415) 555-0123", " 020-7946-0958 "])).toBe(true);
|
|
14
|
+
expect(isAllowlistedCaller("02079460958", ["+1 (415) 555-0123", " 020-7946-0958 "])).toBe(true);
|
|
15
|
+
expect(isAllowlistedCaller("", ["+1 (415) 555-0123"])).toBe(false);
|
|
16
|
+
expect(isAllowlistedCaller("14155550123", ["", "abc"])).toBe(false);
|
|
17
|
+
});
|
|
18
|
+
});
|