mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 11:10:45 +00:00
refactor: trim voice call helper exports
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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<typeof TelnyxConfigSchema>;
|
||||
|
||||
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<typeof PlivoConfigSchema>;
|
||||
|
||||
export { TtsAutoSchema, TtsConfigSchema, TtsModeSchema, TtsProviderSchema };
|
||||
export type VoiceCallTtsConfig = z.infer<typeof TtsConfigSchema>;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// 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<typeof VoiceCallWebhookSecurityConfi
|
||||
* - "notify": Deliver message and auto-hangup after delay (one-way notification)
|
||||
* - "conversation": Stay open for back-and-forth until explicit end or timeout
|
||||
*/
|
||||
export const CallModeSchema = z.enum(["notify", "conversation"]);
|
||||
const CallModeSchema = z.enum(["notify", "conversation"]);
|
||||
export type CallMode = z.infer<typeof CallModeSchema>;
|
||||
|
||||
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<typeof RealtimeToolSchema>;
|
||||
type RealtimeToolConfig = z.infer<typeof RealtimeToolSchema>;
|
||||
|
||||
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<typeof VoiceCallRealtimeConfigSche
|
||||
// Streaming Configuration (Realtime Transcription)
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
export const VoiceCallStreamingConfigSchema = z
|
||||
const VoiceCallStreamingConfigSchema = z
|
||||
.object({
|
||||
/** Enable real-time audio streaming (requires WebSocket support) */
|
||||
enabled: z.boolean().default(false),
|
||||
|
||||
@@ -35,13 +35,13 @@ type VoiceCallContinueOperation =
|
||||
error: string;
|
||||
};
|
||||
|
||||
export type VoiceCallContinueOperationStartPayload = {
|
||||
type VoiceCallContinueOperationStartPayload = {
|
||||
operationId: string;
|
||||
status: "pending";
|
||||
pollTimeoutMs: number;
|
||||
};
|
||||
|
||||
export type VoiceCallContinueOperationResultPayload =
|
||||
type VoiceCallContinueOperationResultPayload =
|
||||
| {
|
||||
operationId: string;
|
||||
status: "pending";
|
||||
@@ -58,7 +58,7 @@ export type VoiceCallContinueOperationResultPayload =
|
||||
error: string;
|
||||
};
|
||||
|
||||
export type VoiceCallContinueOperationRequest = {
|
||||
type VoiceCallContinueOperationRequest = {
|
||||
rt: VoiceCallRuntime;
|
||||
callId: string;
|
||||
message: string;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/text-runtime";
|
||||
|
||||
export type HttpHeaderMap = Record<string, string | string[] | undefined>;
|
||||
type HttpHeaderMap = Record<string, string | string[] | undefined>;
|
||||
|
||||
export function getHeader(headers: HttpHeaderMap, name: string): string | undefined {
|
||||
const target = normalizeLowercaseStringOrEmpty(name);
|
||||
|
||||
@@ -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<CallId, CallRecord>;
|
||||
providerCallIdMap: Map<string, CallId>;
|
||||
processedEventIds: Set<string>;
|
||||
@@ -17,21 +17,21 @@ export type CallManagerRuntimeState = {
|
||||
rejectedProviderCallIds: Set<string>;
|
||||
};
|
||||
|
||||
export type CallManagerRuntimeDeps = {
|
||||
type CallManagerRuntimeDeps = {
|
||||
provider: VoiceCallProvider | null;
|
||||
config: VoiceCallConfig;
|
||||
storePath: string;
|
||||
webhookUrl: string | null;
|
||||
};
|
||||
|
||||
export type CallManagerTransientState = {
|
||||
type CallManagerTransientState = {
|
||||
activeTurnCalls: Set<CallId>;
|
||||
transcriptWaiters: Map<CallId, TranscriptWaiter>;
|
||||
maxDurationTimers: Map<CallId, NodeJS.Timeout>;
|
||||
initialMessageInFlight: Set<CallId>;
|
||||
};
|
||||
|
||||
export type CallManagerHooks = {
|
||||
type CallManagerHooks = {
|
||||
/** Optional runtime hook invoked after an event transitions a call into answered state. */
|
||||
onCallAnswered?: (call: CallRecord) => void;
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 };
|
||||
|
||||
|
||||
@@ -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<typeof ProviderNameSchema>;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
@@ -16,13 +16,13 @@ export type ProviderName = z.infer<typeof ProviderNameSchema>;
|
||||
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<CallState>([
|
||||
"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<typeof NormalizedEventSchema>;
|
||||
// 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(),
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user