Vendor OpenClaw source as Adolf fork baseline
Some checks failed
ClawSweeper Dispatch / dispatch (push) Has been cancelled
CodeQL / Security High (actions) (push) Has been cancelled
CodeQL / Security High (channel-runtime-boundary) (push) Has been cancelled
CodeQL / Security High (core-auth-secrets) (push) Has been cancelled
CodeQL / Security High (mcp-process-tool-boundary) (push) Has been cancelled
CodeQL / Security High (network-ssrf-boundary) (push) Has been cancelled
CodeQL / Security High (plugin-trust-boundary) (push) Has been cancelled
CodeQL / Security High (process-exec-boundary) (push) Has been cancelled
Docs Sync Publish Repo / sync-publish-repo (push) Has been cancelled
Docs / docs (push) Has been cancelled
OpenClaw Stable Main Closeout / Resolve stable release closeout inputs (push) Has been cancelled
OpenClaw Stable Main Closeout / Verify stable main closeout (push) Has been cancelled
Workflow Sanity / no-tabs (push) Has been cancelled
Workflow Sanity / actionlint (push) Has been cancelled
Workflow Sanity / generated-doc-baselines (push) Has been cancelled
CI / runner-admission (push) Has been cancelled
CI / preflight (push) Has been cancelled
CI / security-fast (push) Has been cancelled
CI / pnpm-store-warmup (push) Has been cancelled
CI / build-artifacts (push) Has been cancelled
CI / native-i18n (push) Has been cancelled
CI / ${{ matrix.check_name }} (push) Has been cancelled
CI / ${{ matrix.checkName }} (push) Has been cancelled
CI / checks-node-compat-node22 (push) Has been cancelled
CI / check-bundled-channel-config-metadata (push) Has been cancelled
CI / check-dependencies (push) Has been cancelled
CI / check-guards (push) Has been cancelled
CI / check-lint (push) Has been cancelled
CI / check-prod-types (push) Has been cancelled
CI / check-shrinkwrap (push) Has been cancelled
CI / check-test-types (push) Has been cancelled
CI / check-additional-boundaries-a (push) Has been cancelled
CI / check-additional-boundaries-bcd (push) Has been cancelled
CI / check-additional-extension-bundled (push) Has been cancelled
CI / check-additional-extension-channels (push) Has been cancelled
CI / check-additional-extension-package-boundary (push) Has been cancelled
CI / check-additional-runtime-topology-architecture (push) Has been cancelled
CI / check-session-accessor-boundary (push) Has been cancelled
CI / check-session-transcript-reader-boundary (push) Has been cancelled
CI / check-docs (push) Has been cancelled
CI / skills-python (push) Has been cancelled
CI / macos-swift (push) Has been cancelled
CI / ios-build (push) Has been cancelled
CI / ci-timings-summary (push) Has been cancelled
Native App Locale Refresh / Refresh native fa (push) Has been cancelled
Native App Locale Refresh / Refresh native fr (push) Has been cancelled
Native App Locale Refresh / Refresh native hi (push) Has been cancelled
Native App Locale Refresh / Refresh native id (push) Has been cancelled
Native App Locale Refresh / Refresh native it (push) Has been cancelled
Native App Locale Refresh / Refresh native ja-JP (push) Has been cancelled
Control UI Locale Refresh / plan (push) Has been cancelled
Control UI Locale Refresh / Refresh ${{ matrix.locale }} (push) Has been cancelled
Control UI Locale Refresh / Commit control UI locale refresh (push) Has been cancelled
Live Media Runner Image / Build live media runner image (push) Has been cancelled
Native App Locale Refresh / Refresh native ar (push) Has been cancelled
Native App Locale Refresh / Refresh native de (push) Has been cancelled
Native App Locale Refresh / Refresh native es (push) Has been cancelled
Native App Locale Refresh / Refresh native ko (push) Has been cancelled
Native App Locale Refresh / Refresh native nl (push) Has been cancelled
Native App Locale Refresh / Refresh native pl (push) Has been cancelled
Native App Locale Refresh / Refresh native pt-BR (push) Has been cancelled
Native App Locale Refresh / Refresh native ru (push) Has been cancelled
Native App Locale Refresh / Refresh native sv (push) Has been cancelled
Native App Locale Refresh / Refresh native th (push) Has been cancelled
Native App Locale Refresh / Refresh native tr (push) Has been cancelled
Native App Locale Refresh / Refresh native uk (push) Has been cancelled
Native App Locale Refresh / Refresh native vi (push) Has been cancelled
Native App Locale Refresh / Refresh native zh-CN (push) Has been cancelled
Native App Locale Refresh / Refresh native zh-TW (push) Has been cancelled
Native App Locale Refresh / Commit native locale refresh (push) Has been cancelled
Plugin Init Scaffold Validation / Validate provider scaffold (push) Has been cancelled
Plugin NPM Release / preview_plugins_npm (push) Has been cancelled
Plugin NPM Release / Validate release publish approval (push) Has been cancelled
Plugin NPM Release / preview_plugin_pack (push) Has been cancelled
Plugin NPM Release / publish_plugins_npm (push) Has been cancelled
Sandbox Common Smoke / sandbox-common-smoke (push) Has been cancelled
Website Installer Sync / static (push) Has been cancelled
Website Installer Sync / linux-docker (push) Has been cancelled
Website Installer Sync / macos-installer (push) Has been cancelled
Website Installer Sync / windows-installer (push) Has been cancelled
Website Installer Sync / sync-website (push) Has been cancelled
Some checks failed
ClawSweeper Dispatch / dispatch (push) Has been cancelled
CodeQL / Security High (actions) (push) Has been cancelled
CodeQL / Security High (channel-runtime-boundary) (push) Has been cancelled
CodeQL / Security High (core-auth-secrets) (push) Has been cancelled
CodeQL / Security High (mcp-process-tool-boundary) (push) Has been cancelled
CodeQL / Security High (network-ssrf-boundary) (push) Has been cancelled
CodeQL / Security High (plugin-trust-boundary) (push) Has been cancelled
CodeQL / Security High (process-exec-boundary) (push) Has been cancelled
Docs Sync Publish Repo / sync-publish-repo (push) Has been cancelled
Docs / docs (push) Has been cancelled
OpenClaw Stable Main Closeout / Resolve stable release closeout inputs (push) Has been cancelled
OpenClaw Stable Main Closeout / Verify stable main closeout (push) Has been cancelled
Workflow Sanity / no-tabs (push) Has been cancelled
Workflow Sanity / actionlint (push) Has been cancelled
Workflow Sanity / generated-doc-baselines (push) Has been cancelled
CI / runner-admission (push) Has been cancelled
CI / preflight (push) Has been cancelled
CI / security-fast (push) Has been cancelled
CI / pnpm-store-warmup (push) Has been cancelled
CI / build-artifacts (push) Has been cancelled
CI / native-i18n (push) Has been cancelled
CI / ${{ matrix.check_name }} (push) Has been cancelled
CI / ${{ matrix.checkName }} (push) Has been cancelled
CI / checks-node-compat-node22 (push) Has been cancelled
CI / check-bundled-channel-config-metadata (push) Has been cancelled
CI / check-dependencies (push) Has been cancelled
CI / check-guards (push) Has been cancelled
CI / check-lint (push) Has been cancelled
CI / check-prod-types (push) Has been cancelled
CI / check-shrinkwrap (push) Has been cancelled
CI / check-test-types (push) Has been cancelled
CI / check-additional-boundaries-a (push) Has been cancelled
CI / check-additional-boundaries-bcd (push) Has been cancelled
CI / check-additional-extension-bundled (push) Has been cancelled
CI / check-additional-extension-channels (push) Has been cancelled
CI / check-additional-extension-package-boundary (push) Has been cancelled
CI / check-additional-runtime-topology-architecture (push) Has been cancelled
CI / check-session-accessor-boundary (push) Has been cancelled
CI / check-session-transcript-reader-boundary (push) Has been cancelled
CI / check-docs (push) Has been cancelled
CI / skills-python (push) Has been cancelled
CI / macos-swift (push) Has been cancelled
CI / ios-build (push) Has been cancelled
CI / ci-timings-summary (push) Has been cancelled
Native App Locale Refresh / Refresh native fa (push) Has been cancelled
Native App Locale Refresh / Refresh native fr (push) Has been cancelled
Native App Locale Refresh / Refresh native hi (push) Has been cancelled
Native App Locale Refresh / Refresh native id (push) Has been cancelled
Native App Locale Refresh / Refresh native it (push) Has been cancelled
Native App Locale Refresh / Refresh native ja-JP (push) Has been cancelled
Control UI Locale Refresh / plan (push) Has been cancelled
Control UI Locale Refresh / Refresh ${{ matrix.locale }} (push) Has been cancelled
Control UI Locale Refresh / Commit control UI locale refresh (push) Has been cancelled
Live Media Runner Image / Build live media runner image (push) Has been cancelled
Native App Locale Refresh / Refresh native ar (push) Has been cancelled
Native App Locale Refresh / Refresh native de (push) Has been cancelled
Native App Locale Refresh / Refresh native es (push) Has been cancelled
Native App Locale Refresh / Refresh native ko (push) Has been cancelled
Native App Locale Refresh / Refresh native nl (push) Has been cancelled
Native App Locale Refresh / Refresh native pl (push) Has been cancelled
Native App Locale Refresh / Refresh native pt-BR (push) Has been cancelled
Native App Locale Refresh / Refresh native ru (push) Has been cancelled
Native App Locale Refresh / Refresh native sv (push) Has been cancelled
Native App Locale Refresh / Refresh native th (push) Has been cancelled
Native App Locale Refresh / Refresh native tr (push) Has been cancelled
Native App Locale Refresh / Refresh native uk (push) Has been cancelled
Native App Locale Refresh / Refresh native vi (push) Has been cancelled
Native App Locale Refresh / Refresh native zh-CN (push) Has been cancelled
Native App Locale Refresh / Refresh native zh-TW (push) Has been cancelled
Native App Locale Refresh / Commit native locale refresh (push) Has been cancelled
Plugin Init Scaffold Validation / Validate provider scaffold (push) Has been cancelled
Plugin NPM Release / preview_plugins_npm (push) Has been cancelled
Plugin NPM Release / Validate release publish approval (push) Has been cancelled
Plugin NPM Release / preview_plugin_pack (push) Has been cancelled
Plugin NPM Release / publish_plugins_npm (push) Has been cancelled
Sandbox Common Smoke / sandbox-common-smoke (push) Has been cancelled
Website Installer Sync / static (push) Has been cancelled
Website Installer Sync / linux-docker (push) Has been cancelled
Website Installer Sync / macos-installer (push) Has been cancelled
Website Installer Sync / windows-installer (push) Has been cancelled
Website Installer Sync / sync-website (push) Has been cancelled
Adolf is a fork/vendored clone of github.com/openclaw/openclaw (v2026.6.11), free to diverge. Tree copied sans upstream .git; upstream remote added for future syncs. Node pinned to 24 (.nvmrc); engines already require >=22.19. Preserves docs/ARCHITECTURE.md. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LeqyaxJF2nbRXJtae2kNB2
This commit is contained in:
299
extensions/elevenlabs/realtime-transcription-provider.ts
Normal file
299
extensions/elevenlabs/realtime-transcription-provider.ts
Normal file
@@ -0,0 +1,299 @@
|
||||
// Elevenlabs provider module implements model/runtime integration.
|
||||
import {
|
||||
createRealtimeTranscriptionWebSocketSession,
|
||||
type RealtimeTranscriptionProviderConfig,
|
||||
type RealtimeTranscriptionProviderPlugin,
|
||||
type RealtimeTranscriptionSession,
|
||||
type RealtimeTranscriptionSessionCreateRequest,
|
||||
type RealtimeTranscriptionWebSocketTransport,
|
||||
} from "openclaw/plugin-sdk/realtime-transcription";
|
||||
import { normalizeResolvedSecretInputString } from "openclaw/plugin-sdk/secret-input";
|
||||
import {
|
||||
asOptionalRecord as readRecord,
|
||||
normalizeOptionalString,
|
||||
parseFiniteNumber as readFiniteNumber,
|
||||
} from "openclaw/plugin-sdk/string-coerce-runtime";
|
||||
import { resolveElevenLabsApiKeyWithProfileFallback } from "./config-api.js";
|
||||
import { normalizeElevenLabsBaseUrl } from "./shared.js";
|
||||
|
||||
type ElevenLabsRealtimeTranscriptionProviderConfig = {
|
||||
apiKey?: string;
|
||||
baseUrl?: string;
|
||||
modelId?: string;
|
||||
audioFormat?: string;
|
||||
sampleRate?: number;
|
||||
languageCode?: string;
|
||||
commitStrategy?: "manual" | "vad";
|
||||
vadSilenceThresholdSecs?: number;
|
||||
vadThreshold?: number;
|
||||
minSpeechDurationMs?: number;
|
||||
minSilenceDurationMs?: number;
|
||||
};
|
||||
|
||||
type ElevenLabsRealtimeTranscriptionSessionConfig = RealtimeTranscriptionSessionCreateRequest & {
|
||||
apiKey: string;
|
||||
baseUrl: string;
|
||||
modelId: string;
|
||||
audioFormat: string;
|
||||
sampleRate: number;
|
||||
commitStrategy: "manual" | "vad";
|
||||
languageCode?: string;
|
||||
vadSilenceThresholdSecs?: number;
|
||||
vadThreshold?: number;
|
||||
minSpeechDurationMs?: number;
|
||||
minSilenceDurationMs?: number;
|
||||
};
|
||||
|
||||
type ElevenLabsRealtimeTranscriptionEvent = {
|
||||
message_type?: string;
|
||||
text?: string;
|
||||
error?: string;
|
||||
message?: string;
|
||||
code?: string;
|
||||
};
|
||||
|
||||
const ELEVENLABS_REALTIME_DEFAULT_MODEL = "scribe_v2_realtime";
|
||||
const ELEVENLABS_REALTIME_DEFAULT_AUDIO_FORMAT = "ulaw_8000";
|
||||
const ELEVENLABS_REALTIME_DEFAULT_SAMPLE_RATE = 8000;
|
||||
const ELEVENLABS_REALTIME_DEFAULT_COMMIT_STRATEGY: "manual" | "vad" = "vad";
|
||||
const ELEVENLABS_REALTIME_CONNECT_TIMEOUT_MS = 10_000;
|
||||
const ELEVENLABS_REALTIME_CLOSE_TIMEOUT_MS = 5_000;
|
||||
const ELEVENLABS_REALTIME_MAX_RECONNECT_ATTEMPTS = 5;
|
||||
const ELEVENLABS_REALTIME_RECONNECT_DELAY_MS = 1000;
|
||||
const ELEVENLABS_REALTIME_MAX_QUEUED_BYTES = 2 * 1024 * 1024;
|
||||
|
||||
function readNestedElevenLabsConfig(rawConfig: RealtimeTranscriptionProviderConfig) {
|
||||
const raw = readRecord(rawConfig);
|
||||
const providers = readRecord(raw?.providers);
|
||||
return readRecord(providers?.elevenlabs ?? raw?.elevenlabs ?? raw) ?? {};
|
||||
}
|
||||
|
||||
function normalizeCommitStrategy(value: unknown): "manual" | "vad" | undefined {
|
||||
const normalized = normalizeOptionalString(value)?.toLowerCase();
|
||||
if (!normalized) {
|
||||
return undefined;
|
||||
}
|
||||
if (normalized === "manual" || normalized === "vad") {
|
||||
return normalized;
|
||||
}
|
||||
throw new Error(`Invalid ElevenLabs realtime transcription commit strategy: ${normalized}`);
|
||||
}
|
||||
|
||||
function normalizePositiveSafeInteger(value: unknown): number | undefined {
|
||||
const parsed = readFiniteNumber(value);
|
||||
return parsed !== undefined && Number.isSafeInteger(parsed) && parsed > 0 ? parsed : undefined;
|
||||
}
|
||||
|
||||
function normalizeFiniteRange(value: unknown, min: number, max: number): number | undefined {
|
||||
const parsed = readFiniteNumber(value);
|
||||
return parsed !== undefined && parsed >= min && parsed <= max ? parsed : undefined;
|
||||
}
|
||||
|
||||
function normalizeIntegerRange(value: unknown, min: number, max: number): number | undefined {
|
||||
const parsed = readFiniteNumber(value);
|
||||
return parsed !== undefined && Number.isSafeInteger(parsed) && parsed >= min && parsed <= max
|
||||
? parsed
|
||||
: undefined;
|
||||
}
|
||||
|
||||
function normalizeProviderConfig(
|
||||
config: RealtimeTranscriptionProviderConfig,
|
||||
): ElevenLabsRealtimeTranscriptionProviderConfig {
|
||||
const raw = readNestedElevenLabsConfig(config);
|
||||
return {
|
||||
apiKey: normalizeResolvedSecretInputString({
|
||||
value: raw.apiKey,
|
||||
path: "plugins.entries.voice-call.config.streaming.providers.elevenlabs.apiKey",
|
||||
}),
|
||||
baseUrl: normalizeOptionalString(raw.baseUrl),
|
||||
modelId: normalizeOptionalString(raw.modelId ?? raw.model ?? raw.sttModel),
|
||||
audioFormat: normalizeOptionalString(raw.audioFormat ?? raw.audio_format ?? raw.encoding),
|
||||
sampleRate: normalizePositiveSafeInteger(raw.sampleRate ?? raw.sample_rate),
|
||||
languageCode: normalizeOptionalString(raw.languageCode ?? raw.language),
|
||||
commitStrategy: normalizeCommitStrategy(raw.commitStrategy ?? raw.commit_strategy),
|
||||
vadSilenceThresholdSecs: normalizeFiniteRange(
|
||||
raw.vadSilenceThresholdSecs ?? raw.vad_silence_threshold_secs,
|
||||
0.3,
|
||||
3,
|
||||
),
|
||||
vadThreshold: normalizeFiniteRange(raw.vadThreshold ?? raw.vad_threshold, 0.1, 0.9),
|
||||
minSpeechDurationMs: normalizeIntegerRange(
|
||||
raw.minSpeechDurationMs ?? raw.min_speech_duration_ms,
|
||||
50,
|
||||
2_000,
|
||||
),
|
||||
minSilenceDurationMs: normalizeIntegerRange(
|
||||
raw.minSilenceDurationMs ?? raw.min_silence_duration_ms,
|
||||
50,
|
||||
2_000,
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
function normalizeElevenLabsRealtimeBaseUrl(value?: string): string {
|
||||
const url = new URL(normalizeElevenLabsBaseUrl(value));
|
||||
url.protocol = url.protocol === "http:" ? "ws:" : "wss:";
|
||||
return url.toString().replace(/\/+$/, "");
|
||||
}
|
||||
|
||||
function toElevenLabsRealtimeWsUrl(config: ElevenLabsRealtimeTranscriptionSessionConfig): string {
|
||||
const url = new URL(
|
||||
`${normalizeElevenLabsRealtimeBaseUrl(config.baseUrl)}/v1/speech-to-text/realtime`,
|
||||
);
|
||||
url.searchParams.set("model_id", config.modelId);
|
||||
url.searchParams.set("audio_format", config.audioFormat);
|
||||
url.searchParams.set("commit_strategy", config.commitStrategy);
|
||||
url.searchParams.set("include_timestamps", "false");
|
||||
url.searchParams.set("include_language_detection", "false");
|
||||
if (config.languageCode) {
|
||||
url.searchParams.set("language_code", config.languageCode);
|
||||
}
|
||||
if (config.vadSilenceThresholdSecs != null) {
|
||||
url.searchParams.set("vad_silence_threshold_secs", String(config.vadSilenceThresholdSecs));
|
||||
}
|
||||
if (config.vadThreshold != null) {
|
||||
url.searchParams.set("vad_threshold", String(config.vadThreshold));
|
||||
}
|
||||
if (config.minSpeechDurationMs != null) {
|
||||
url.searchParams.set("min_speech_duration_ms", String(config.minSpeechDurationMs));
|
||||
}
|
||||
if (config.minSilenceDurationMs != null) {
|
||||
url.searchParams.set("min_silence_duration_ms", String(config.minSilenceDurationMs));
|
||||
}
|
||||
return url.toString();
|
||||
}
|
||||
|
||||
function readErrorDetail(event: ElevenLabsRealtimeTranscriptionEvent): string {
|
||||
return (
|
||||
normalizeOptionalString(event.error) ??
|
||||
normalizeOptionalString(event.message) ??
|
||||
normalizeOptionalString(event.code) ??
|
||||
"ElevenLabs realtime transcription error"
|
||||
);
|
||||
}
|
||||
|
||||
function createElevenLabsRealtimeTranscriptionSession(
|
||||
config: ElevenLabsRealtimeTranscriptionSessionConfig,
|
||||
): RealtimeTranscriptionSession {
|
||||
let lastTranscript: string | undefined;
|
||||
|
||||
const emitTranscript = (text: string) => {
|
||||
if (text === lastTranscript) {
|
||||
return;
|
||||
}
|
||||
lastTranscript = text;
|
||||
config.onTranscript?.(text);
|
||||
};
|
||||
|
||||
const sendAudioChunk = (
|
||||
audio: Buffer,
|
||||
transport: RealtimeTranscriptionWebSocketTransport,
|
||||
): void => {
|
||||
transport.sendJson({
|
||||
message_type: "input_audio_chunk",
|
||||
audio_base_64: audio.toString("base64"),
|
||||
sample_rate: config.sampleRate,
|
||||
...(config.commitStrategy === "manual" ? { commit: true } : {}),
|
||||
});
|
||||
};
|
||||
|
||||
const handleEvent = (
|
||||
event: ElevenLabsRealtimeTranscriptionEvent,
|
||||
transport: RealtimeTranscriptionWebSocketTransport,
|
||||
) => {
|
||||
if (event.message_type === "session_started") {
|
||||
transport.markReady();
|
||||
return;
|
||||
}
|
||||
if (!transport.isReady() && event.message_type?.includes("error")) {
|
||||
transport.failConnect(new Error(readErrorDetail(event)));
|
||||
return;
|
||||
}
|
||||
switch (event.message_type) {
|
||||
case "partial_transcript":
|
||||
if (event.text) {
|
||||
config.onPartial?.(event.text);
|
||||
}
|
||||
return;
|
||||
case "committed_transcript":
|
||||
case "committed_transcript_with_timestamps":
|
||||
if (event.text) {
|
||||
emitTranscript(event.text);
|
||||
}
|
||||
return;
|
||||
default:
|
||||
if (event.message_type?.includes("error")) {
|
||||
config.onError?.(new Error(readErrorDetail(event)));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return createRealtimeTranscriptionWebSocketSession<ElevenLabsRealtimeTranscriptionEvent>({
|
||||
providerId: "elevenlabs",
|
||||
callbacks: config,
|
||||
url: () => toElevenLabsRealtimeWsUrl(config),
|
||||
headers: { "xi-api-key": config.apiKey },
|
||||
connectTimeoutMs: ELEVENLABS_REALTIME_CONNECT_TIMEOUT_MS,
|
||||
closeTimeoutMs: ELEVENLABS_REALTIME_CLOSE_TIMEOUT_MS,
|
||||
maxReconnectAttempts: ELEVENLABS_REALTIME_MAX_RECONNECT_ATTEMPTS,
|
||||
reconnectDelayMs: ELEVENLABS_REALTIME_RECONNECT_DELAY_MS,
|
||||
maxQueuedBytes: ELEVENLABS_REALTIME_MAX_QUEUED_BYTES,
|
||||
connectTimeoutMessage: "ElevenLabs realtime transcription connection timeout",
|
||||
reconnectLimitMessage: "ElevenLabs realtime transcription reconnect limit reached",
|
||||
sendAudio: sendAudioChunk,
|
||||
onClose: (transport) => {
|
||||
transport.sendJson({
|
||||
message_type: "input_audio_chunk",
|
||||
audio_base_64: "",
|
||||
sample_rate: config.sampleRate,
|
||||
commit: true,
|
||||
});
|
||||
},
|
||||
onMessage: handleEvent,
|
||||
});
|
||||
}
|
||||
|
||||
export function buildElevenLabsRealtimeTranscriptionProvider(): RealtimeTranscriptionProviderPlugin {
|
||||
return {
|
||||
id: "elevenlabs",
|
||||
label: "ElevenLabs Realtime Transcription",
|
||||
aliases: ["elevenlabs-realtime", "scribe-v2-realtime"],
|
||||
defaultModel: ELEVENLABS_REALTIME_DEFAULT_MODEL,
|
||||
autoSelectOrder: 40,
|
||||
resolveConfig: ({ rawConfig }) => normalizeProviderConfig(rawConfig),
|
||||
isConfigured: ({ providerConfig }) =>
|
||||
Boolean(
|
||||
normalizeProviderConfig(providerConfig).apiKey ||
|
||||
resolveElevenLabsApiKeyWithProfileFallback() ||
|
||||
process.env.XI_API_KEY,
|
||||
),
|
||||
createSession: (req) => {
|
||||
const config = normalizeProviderConfig(req.providerConfig);
|
||||
const apiKey =
|
||||
config.apiKey || resolveElevenLabsApiKeyWithProfileFallback() || process.env.XI_API_KEY;
|
||||
if (!apiKey) {
|
||||
throw new Error("ElevenLabs API key missing");
|
||||
}
|
||||
return createElevenLabsRealtimeTranscriptionSession({
|
||||
...req,
|
||||
apiKey,
|
||||
baseUrl: normalizeElevenLabsBaseUrl(config.baseUrl),
|
||||
modelId: config.modelId ?? ELEVENLABS_REALTIME_DEFAULT_MODEL,
|
||||
audioFormat: config.audioFormat ?? ELEVENLABS_REALTIME_DEFAULT_AUDIO_FORMAT,
|
||||
sampleRate: config.sampleRate ?? ELEVENLABS_REALTIME_DEFAULT_SAMPLE_RATE,
|
||||
commitStrategy: config.commitStrategy ?? ELEVENLABS_REALTIME_DEFAULT_COMMIT_STRATEGY,
|
||||
languageCode: config.languageCode,
|
||||
vadSilenceThresholdSecs: config.vadSilenceThresholdSecs,
|
||||
vadThreshold: config.vadThreshold,
|
||||
minSpeechDurationMs: config.minSpeechDurationMs,
|
||||
minSilenceDurationMs: config.minSilenceDurationMs,
|
||||
});
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export const testing = {
|
||||
normalizeProviderConfig,
|
||||
toElevenLabsRealtimeWsUrl,
|
||||
};
|
||||
export { testing as __testing };
|
||||
Reference in New Issue
Block a user