From 496bf38fcf037827f81da186aaa255cc2979ddaf Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Fri, 1 May 2026 17:42:21 +0100 Subject: [PATCH] refactor: trim voice call helper exports --- extensions/voice-call/src/config-compat.ts | 2 +- extensions/voice-call/src/config.ts | 45 +++++++++---------- .../src/gateway-continue-operation.ts | 6 +-- extensions/voice-call/src/http-headers.ts | 2 +- extensions/voice-call/src/manager/context.ts | 10 ++--- .../src/providers/twilio/twiml-policy.ts | 6 +-- .../voice-call/src/realtime-fast-context.ts | 2 +- extensions/voice-call/src/types.ts | 14 +++--- .../voice-call/src/webhook/tailscale.ts | 2 +- 9 files changed, 43 insertions(+), 46 deletions(-) diff --git a/extensions/voice-call/src/config-compat.ts b/extensions/voice-call/src/config-compat.ts index f83fea5d93d..42ae7bfa86a 100644 --- a/extensions/voice-call/src/config-compat.ts +++ b/extensions/voice-call/src/config-compat.ts @@ -4,7 +4,7 @@ import { VoiceCallConfigSchema } from "./config.js"; export const VOICE_CALL_LEGACY_CONFIG_REMOVAL_VERSION = "2026.6.0"; -export type VoiceCallLegacyConfigIssue = { +type VoiceCallLegacyConfigIssue = { path: string; replacement: string; message: string; diff --git a/extensions/voice-call/src/config.ts b/extensions/voice-call/src/config.ts index 505430f5c40..ad3105d8b5d 100644 --- a/extensions/voice-call/src/config.ts +++ b/extensions/voice-call/src/config.ts @@ -6,12 +6,10 @@ import { type SecretInput, } from "openclaw/plugin-sdk/secret-input"; import { z } from "openclaw/plugin-sdk/zod"; -import { TtsAutoSchema, TtsConfigSchema, TtsModeSchema, TtsProviderSchema } from "../api.js"; +import { TtsConfigSchema } from "../api.js"; import { deepMergeDefined } from "./deep-merge.js"; import { DEFAULT_VOICE_CALL_REALTIME_INSTRUCTIONS } from "./realtime-defaults.js"; -export { DEFAULT_VOICE_CALL_REALTIME_INSTRUCTIONS } from "./realtime-defaults.js"; - // ----------------------------------------------------------------------------- // Phone Number Validation // ----------------------------------------------------------------------------- @@ -20,7 +18,7 @@ export { DEFAULT_VOICE_CALL_REALTIME_INSTRUCTIONS } from "./realtime-defaults.js * E.164 phone number format: +[country code][number] * Examples use 555 prefix (reserved for fictional numbers) */ -export const E164Schema = z +const E164Schema = z .string() .regex(/^\+[1-9]\d{1,14}$/, "Expected E.164 format, e.g. +15550001234"); @@ -35,7 +33,7 @@ export const E164Schema = z * - "pairing": Unknown callers can request pairing (future) * - "open": Accept all inbound calls (dangerous!) */ -export const InboundPolicySchema = z.enum(["disabled", "allowlist", "pairing", "open"]); +const InboundPolicySchema = z.enum(["disabled", "allowlist", "pairing", "open"]); // ----------------------------------------------------------------------------- // Provider-Specific Configuration @@ -43,7 +41,7 @@ export const InboundPolicySchema = z.enum(["disabled", "allowlist", "pairing", " const SecretInputSchema = buildSecretInputSchema(); -export const TelnyxConfigSchema = z +const TelnyxConfigSchema = z .object({ /** Telnyx API v2 key */ apiKey: z.string().min(1).optional(), @@ -55,7 +53,7 @@ export const TelnyxConfigSchema = z .strict(); export type TelnyxConfig = z.infer; -export const TwilioConfigSchema = z +const TwilioConfigSchema = z .object({ /** Twilio Account SID */ accountSid: z.string().min(1).optional(), @@ -64,7 +62,7 @@ export const TwilioConfigSchema = z }) .strict(); -export const PlivoConfigSchema = z +const PlivoConfigSchema = z .object({ /** Plivo Auth ID (starts with MA/SA) */ authId: z.string().min(1).optional(), @@ -74,14 +72,13 @@ export const PlivoConfigSchema = z .strict(); export type PlivoConfig = z.infer; -export { TtsAutoSchema, TtsConfigSchema, TtsModeSchema, TtsProviderSchema }; export type VoiceCallTtsConfig = z.infer; // ----------------------------------------------------------------------------- // Webhook Server Configuration // ----------------------------------------------------------------------------- -export const VoiceCallServeConfigSchema = z +const VoiceCallServeConfigSchema = z .object({ /** Port to listen on */ port: z.number().int().positive().default(3334), @@ -93,7 +90,7 @@ export const VoiceCallServeConfigSchema = z .strict() .default({ port: 3334, bind: "127.0.0.1", path: "/voice/webhook" }); -export const VoiceCallTailscaleConfigSchema = z +const VoiceCallTailscaleConfigSchema = z .object({ /** * Tailscale exposure mode: @@ -112,7 +109,7 @@ export const VoiceCallTailscaleConfigSchema = z // Tunnel Configuration (unified ngrok/tailscale) // ----------------------------------------------------------------------------- -export const VoiceCallTunnelConfigSchema = z +const VoiceCallTunnelConfigSchema = z .object({ /** * Tunnel provider: @@ -142,7 +139,7 @@ export const VoiceCallTunnelConfigSchema = z // Webhook Security Configuration // ----------------------------------------------------------------------------- -export const VoiceCallWebhookSecurityConfigSchema = z +const VoiceCallWebhookSecurityConfigSchema = z .object({ /** * Allowed hostnames for webhook URL reconstruction. @@ -173,10 +170,10 @@ export type WebhookSecurityConfig = z.infer; -export const OutboundConfigSchema = z +const OutboundConfigSchema = z .object({ /** Default call mode for outbound calls */ defaultMode: CallModeSchema.default("notify"), @@ -190,7 +187,7 @@ export const OutboundConfigSchema = z // Realtime Voice Configuration // ----------------------------------------------------------------------------- -export const RealtimeToolSchema = z +const RealtimeToolSchema = z .object({ type: z.literal("function"), name: z.string().min(1), @@ -202,17 +199,17 @@ export const RealtimeToolSchema = z }), }) .strict(); -export type RealtimeToolConfig = z.infer; +type RealtimeToolConfig = z.infer; -export const VoiceCallRealtimeProvidersConfigSchema = z +const VoiceCallRealtimeProvidersConfigSchema = z .record(z.string(), z.record(z.string(), z.unknown())) .default({}); -export const VoiceCallRealtimeToolPolicySchema = z.enum(REALTIME_VOICE_AGENT_CONSULT_TOOL_POLICIES); +const VoiceCallRealtimeToolPolicySchema = z.enum(REALTIME_VOICE_AGENT_CONSULT_TOOL_POLICIES); -export const VoiceCallRealtimeFastContextSourceSchema = z.enum(["memory", "sessions"]); +const VoiceCallRealtimeFastContextSourceSchema = z.enum(["memory", "sessions"]); -export const VoiceCallRealtimeFastContextConfigSchema = z +const VoiceCallRealtimeFastContextConfigSchema = z .object({ /** Enable bounded memory/session lookup before the full consult agent. */ enabled: z.boolean().default(false), @@ -240,11 +237,11 @@ export type VoiceCallRealtimeFastContextConfig = z.infer< typeof VoiceCallRealtimeFastContextConfigSchema >; -export const VoiceCallStreamingProvidersConfigSchema = z +const VoiceCallStreamingProvidersConfigSchema = z .record(z.string(), z.record(z.string(), z.unknown())) .default({}); -export const VoiceCallRealtimeConfigSchema = z +const VoiceCallRealtimeConfigSchema = z .object({ /** Enable realtime voice-to-voice mode. */ enabled: z.boolean().default(false), @@ -284,7 +281,7 @@ export type VoiceCallRealtimeConfig = z.infer; +type HttpHeaderMap = Record; export function getHeader(headers: HttpHeaderMap, name: string): string | undefined { const target = normalizeLowercaseStringOrEmpty(name); diff --git a/extensions/voice-call/src/manager/context.ts b/extensions/voice-call/src/manager/context.ts index b271f1f132e..bc544da040c 100644 --- a/extensions/voice-call/src/manager/context.ts +++ b/extensions/voice-call/src/manager/context.ts @@ -2,14 +2,14 @@ import type { VoiceCallConfig } from "../config.js"; import type { VoiceCallProvider } from "../providers/base.js"; import type { CallId, CallRecord } from "../types.js"; -export type TranscriptWaiter = { +type TranscriptWaiter = { resolve: (text: string) => void; reject: (err: Error) => void; timeout: NodeJS.Timeout; turnToken?: string; }; -export type CallManagerRuntimeState = { +type CallManagerRuntimeState = { activeCalls: Map; providerCallIdMap: Map; processedEventIds: Set; @@ -17,21 +17,21 @@ export type CallManagerRuntimeState = { rejectedProviderCallIds: Set; }; -export type CallManagerRuntimeDeps = { +type CallManagerRuntimeDeps = { provider: VoiceCallProvider | null; config: VoiceCallConfig; storePath: string; webhookUrl: string | null; }; -export type CallManagerTransientState = { +type CallManagerTransientState = { activeTurnCalls: Set; transcriptWaiters: Map; maxDurationTimers: Map; initialMessageInFlight: Set; }; -export type CallManagerHooks = { +type CallManagerHooks = { /** Optional runtime hook invoked after an event transitions a call into answered state. */ onCallAnswered?: (call: CallRecord) => void; }; diff --git a/extensions/voice-call/src/providers/twilio/twiml-policy.ts b/extensions/voice-call/src/providers/twilio/twiml-policy.ts index 679fc692ea9..310d3c7c980 100644 --- a/extensions/voice-call/src/providers/twilio/twiml-policy.ts +++ b/extensions/voice-call/src/providers/twilio/twiml-policy.ts @@ -1,7 +1,7 @@ import { normalizeOptionalString } from "openclaw/plugin-sdk/text-runtime"; import type { WebhookContext } from "../../types.js"; -export type TwimlRequestView = { +type TwimlRequestView = { callStatus: string | null; direction: string | null; isStatusCallback: boolean; @@ -9,14 +9,14 @@ export type TwimlRequestView = { callIdFromQuery?: string; }; -export type TwimlPolicyInput = TwimlRequestView & { +type TwimlPolicyInput = TwimlRequestView & { hasStoredTwiml: boolean; isNotifyCall: boolean; hasActiveStreams: boolean; canStream: boolean; }; -export type TwimlDecision = +type TwimlDecision = | { kind: "empty" | "pause" | "queue"; consumeStoredTwimlCallId?: string; diff --git a/extensions/voice-call/src/realtime-fast-context.ts b/extensions/voice-call/src/realtime-fast-context.ts index 19927f2307c..3e95b3dfd8e 100644 --- a/extensions/voice-call/src/realtime-fast-context.ts +++ b/extensions/voice-call/src/realtime-fast-context.ts @@ -25,7 +25,7 @@ type FastContextLookupResult = | { status: "unavailable"; error?: string } | { status: "hits"; hits: MemorySearchHit[] }; -export type RealtimeFastContextConsultResult = +type RealtimeFastContextConsultResult = | { handled: false } | { handled: true; result: RealtimeVoiceAgentConsultResult }; diff --git a/extensions/voice-call/src/types.ts b/extensions/voice-call/src/types.ts index c5a333d49cc..a5fb6f85f74 100644 --- a/extensions/voice-call/src/types.ts +++ b/extensions/voice-call/src/types.ts @@ -5,7 +5,7 @@ import type { CallMode } from "./config.js"; // Provider Identifiers // ----------------------------------------------------------------------------- -export const ProviderNameSchema = z.enum(["telnyx", "twilio", "plivo", "mock"]); +const ProviderNameSchema = z.enum(["telnyx", "twilio", "plivo", "mock"]); export type ProviderName = z.infer; // ----------------------------------------------------------------------------- @@ -16,13 +16,13 @@ export type ProviderName = z.infer; export type CallId = string; /** Provider-specific call identifier */ -export type ProviderCallId = string; +type ProviderCallId = string; // ----------------------------------------------------------------------------- // Call Lifecycle States // ----------------------------------------------------------------------------- -export const CallStateSchema = z.enum([ +const CallStateSchema = z.enum([ // Non-terminal states "initiated", "ringing", @@ -55,7 +55,7 @@ export const TerminalStates = new Set([ "voicemail", ]); -export const EndReasonSchema = z.enum([ +const EndReasonSchema = z.enum([ "completed", "hangup-user", "hangup-bot", @@ -87,7 +87,7 @@ const BaseEventSchema = z.object({ to: z.string().optional(), }); -export const NormalizedEventSchema = z.discriminatedUnion("type", [ +const NormalizedEventSchema = z.discriminatedUnion("type", [ BaseEventSchema.extend({ type: z.literal("call.initiated"), }), @@ -134,13 +134,13 @@ export type NormalizedEvent = z.infer; // Call Direction // ----------------------------------------------------------------------------- -export const CallDirectionSchema = z.enum(["outbound", "inbound"]); +const CallDirectionSchema = z.enum(["outbound", "inbound"]); // ----------------------------------------------------------------------------- // Call Record // ----------------------------------------------------------------------------- -export const TranscriptEntrySchema = z.object({ +const TranscriptEntrySchema = z.object({ timestamp: z.number(), speaker: z.enum(["bot", "user"]), text: z.string(), diff --git a/extensions/voice-call/src/webhook/tailscale.ts b/extensions/voice-call/src/webhook/tailscale.ts index 03717ad932b..60476979ca8 100644 --- a/extensions/voice-call/src/webhook/tailscale.ts +++ b/extensions/voice-call/src/webhook/tailscale.ts @@ -1,7 +1,7 @@ import { spawn } from "node:child_process"; import type { VoiceCallConfig } from "../config.js"; -export type TailscaleSelfInfo = { +type TailscaleSelfInfo = { dnsName: string | null; nodeId: string | null; };