refactor: dedupe elevenlabs provider helpers

This commit is contained in:
Peter Steinberger
2026-04-06 19:41:40 +01:00
parent d6d999eda6
commit a336c31962
3 changed files with 15 additions and 26 deletions

View File

@@ -0,0 +1,10 @@
export const DEFAULT_ELEVENLABS_BASE_URL = "https://api.elevenlabs.io";
export function isValidElevenLabsVoiceId(voiceId: string): boolean {
return /^[a-zA-Z0-9]{10,40}$/.test(voiceId);
}
export function normalizeElevenLabsBaseUrl(baseUrl?: string): string {
const trimmed = baseUrl?.trim();
return trimmed?.replace(/\/+$/, "") || DEFAULT_ELEVENLABS_BASE_URL;
}

View File

@@ -17,9 +17,8 @@ import {
trimToUndefined,
} from "openclaw/plugin-sdk/speech";
import { resolveElevenLabsApiKeyWithProfileFallback } from "./config-api.js";
import { isValidElevenLabsVoiceId, normalizeElevenLabsBaseUrl } from "./shared.js";
import { elevenLabsTTS } from "./tts.js";
const DEFAULT_ELEVENLABS_BASE_URL = "https://api.elevenlabs.io";
const DEFAULT_ELEVENLABS_VOICE_ID = "pMsXgVXv3BLzUgSXRplE";
const DEFAULT_ELEVENLABS_MODEL_ID = "eleven_multilingual_v2";
const DEFAULT_ELEVENLABS_VOICE_SETTINGS = {
@@ -69,14 +68,7 @@ function parseNumberValue(value: string): number | undefined {
return Number.isFinite(parsed) ? parsed : undefined;
}
export function isValidVoiceId(voiceId: string): boolean {
return /^[a-zA-Z0-9]{10,40}$/.test(voiceId);
}
function normalizeElevenLabsBaseUrl(baseUrl: string | undefined): string {
const trimmed = baseUrl?.trim();
return trimmed?.replace(/\/+$/, "") || DEFAULT_ELEVENLABS_BASE_URL;
}
export const isValidVoiceId = isValidElevenLabsVoiceId;
function normalizeElevenLabsProviderConfig(
rawConfig: Record<string, unknown>,
@@ -162,7 +154,7 @@ function parseDirectiveToken(ctx: SpeechDirectiveTokenParseContext) {
if (!ctx.policy.allowVoice) {
return { handled: true };
}
if (!isValidVoiceId(ctx.value)) {
if (!isValidElevenLabsVoiceId(ctx.value)) {
return { handled: true, warnings: [`invalid ElevenLabs voiceId "${ctx.value}"`] };
}
return {

View File

@@ -8,20 +8,7 @@ import {
trimToUndefined,
truncateErrorDetail,
} from "openclaw/plugin-sdk/speech";
const DEFAULT_ELEVENLABS_BASE_URL = "https://api.elevenlabs.io";
function isValidVoiceId(voiceId: string): boolean {
return /^[a-zA-Z0-9]{10,40}$/.test(voiceId);
}
function normalizeElevenLabsBaseUrl(baseUrl?: string): string {
const trimmed = baseUrl?.trim();
if (!trimmed) {
return DEFAULT_ELEVENLABS_BASE_URL;
}
return trimmed.replace(/\/+$/, "");
}
import { isValidElevenLabsVoiceId, normalizeElevenLabsBaseUrl } from "./shared.js";
function formatElevenLabsErrorPayload(payload: unknown): string | undefined {
const root = asObject(payload);
@@ -109,7 +96,7 @@ export async function elevenLabsTTS(params: {
voiceSettings,
timeoutMs,
} = params;
if (!isValidVoiceId(voiceId)) {
if (!isValidElevenLabsVoiceId(voiceId)) {
throw new Error("Invalid voiceId format");
}
assertElevenLabsVoiceSettings(voiceSettings);