UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

172 lines (171 loc) 6.75 kB
import { c as normalizeOptionalString } from "./string-coerce-mnp54Vah.js"; import { c as asFiniteNumberInRange } from "./number-coercion-CJQ8TR--.js"; import { u as normalizeResolvedSecretInputString } from "./types.secrets-_0JOMGE5.js"; import { n as asObject } from "./provider-http-errors-DqaqQLLZ.js"; import "./string-coerce-runtime-CEGJWkQ_.js"; import { t as parseSpeechDirectiveNumberOverride } from "./speech-core-s8tZcO7c.js"; import "./secret-input-DVCzFGxN.js"; import { t as volcengineTTS } from "./tts-C2il47fa.js"; //#region extensions/volcengine/speech-provider.ts const DEFAULT_VOICE = "en_female_anna_mars_bigtts"; const DEFAULT_CLUSTER = "volcano_tts"; const DEFAULT_RESOURCE_ID = "seed-tts-1.0"; const DEFAULT_APP_KEY = "aGjiRDfUWi"; const VOLCENGINE_VOICES = [ "en_female_anna_mars_bigtts", "en_male_adam_mars_bigtts", "en_female_sarah_mars_bigtts", "en_male_smith_mars_bigtts", "zh_female_cancan_mars_bigtts", "zh_female_qingxinnvsheng_mars_bigtts", "zh_female_linjia_mars_bigtts", "zh_male_wennuanahu_moon_bigtts", "zh_male_shaonianzixin_moon_bigtts", "zh_female_shuangkuaisisi_moon_bigtts" ]; function normalizeSpeedRatio(value) { return asFiniteNumberInRange(value, { min: .2, max: 3 }); } function normalizeVolcengineProviderConfig(rawConfig) { const raw = asObject(asObject(rawConfig.providers)?.volcengine) ?? asObject(rawConfig.volcengine); return { apiKey: normalizeResolvedSecretInputString({ value: raw?.apiKey, path: "messages.tts.providers.volcengine.apiKey" }), appId: normalizeOptionalString(raw?.appId), token: normalizeResolvedSecretInputString({ value: raw?.token, path: "messages.tts.providers.volcengine.token" }), voice: normalizeOptionalString(raw?.voice) ?? normalizeOptionalString(process.env.VOLCENGINE_TTS_VOICE) ?? DEFAULT_VOICE, cluster: normalizeOptionalString(raw?.cluster) ?? normalizeOptionalString(process.env.VOLCENGINE_TTS_CLUSTER) ?? DEFAULT_CLUSTER, resourceId: normalizeOptionalString(raw?.resourceId) ?? normalizeOptionalString(process.env.VOLCENGINE_TTS_RESOURCE_ID) ?? DEFAULT_RESOURCE_ID, appKey: normalizeOptionalString(raw?.appKey) ?? normalizeOptionalString(process.env.VOLCENGINE_TTS_APP_KEY) ?? DEFAULT_APP_KEY, baseUrl: normalizeOptionalString(raw?.baseUrl) ?? normalizeOptionalString(process.env.VOLCENGINE_TTS_BASE_URL), speedRatio: normalizeSpeedRatio(raw?.speedRatio), emotion: normalizeOptionalString(raw?.emotion) }; } function resolveSeedSpeechApiKey(configApiKey) { return configApiKey ?? normalizeOptionalString(process.env.VOLCENGINE_TTS_API_KEY) ?? normalizeOptionalString(process.env.BYTEPLUS_SEED_SPEECH_API_KEY); } function readProviderConfig(config) { const normalized = normalizeVolcengineProviderConfig({}); return { apiKey: normalizeResolvedSecretInputString({ value: config.apiKey, path: "messages.tts.providers.volcengine.apiKey" }) ?? normalized.apiKey, appId: normalizeOptionalString(config.appId) ?? normalized.appId, token: normalizeOptionalString(config.token) ?? normalized.token, voice: normalizeOptionalString(config.voice) ?? normalized.voice, cluster: normalizeOptionalString(config.cluster) ?? normalized.cluster, resourceId: normalizeOptionalString(config.resourceId) ?? normalized.resourceId, appKey: normalizeOptionalString(config.appKey) ?? normalized.appKey, baseUrl: normalizeOptionalString(config.baseUrl) ?? normalized.baseUrl, speedRatio: normalizeSpeedRatio(config.speedRatio) ?? normalized.speedRatio, emotion: normalizeOptionalString(config.emotion) ?? normalized.emotion }; } function readVolcengineOverrides(overrides) { if (!overrides) return {}; return { voice: normalizeOptionalString(overrides.voice), speedRatio: normalizeSpeedRatio(overrides.speedRatio), emotion: normalizeOptionalString(overrides.emotion) }; } function parseDirectiveToken(ctx) { switch (ctx.key) { case "voice": case "volcengine_voice": case "volcenginevoice": if (!ctx.policy.allowVoice) return { handled: true }; return { handled: true, overrides: { ...ctx.currentOverrides, voice: ctx.value } }; case "speed": case "speedratio": case "speed_ratio": return parseSpeechDirectiveNumberOverride({ ctx, overrideKey: "speedRatio", range: { min: .2, max: 3 }, warning: (value) => `invalid Volcengine speedRatio "${value}"`, mergeCurrentOverrides: true }); case "emotion": if (!ctx.policy.allowVoiceSettings) return { handled: true }; return { handled: true, overrides: { ...ctx.currentOverrides, emotion: ctx.value } }; default: return { handled: false }; } } function buildVolcengineSpeechProvider() { return { id: "volcengine", label: "Volcengine", autoSelectOrder: 90, aliases: ["bytedance", "doubao"], voices: VOLCENGINE_VOICES, resolveConfig: ({ rawConfig }) => normalizeVolcengineProviderConfig(rawConfig), parseDirectiveToken, listVoices: async () => VOLCENGINE_VOICES.map((v) => ({ id: v, name: v.replace(/^(?:en|zh)_(female|male)_/, "").replace(/_.*$/, ""), locale: v.startsWith("en_") ? "en-US" : "zh-CN", gender: v.includes("_female_") ? "female" : "male" })), isConfigured: ({ providerConfig }) => { const cfg = readProviderConfig(providerConfig); return Boolean(resolveSeedSpeechApiKey(cfg.apiKey) || (cfg.appId || process.env.VOLCENGINE_TTS_APPID) && (cfg.token || process.env.VOLCENGINE_TTS_TOKEN)); }, synthesize: async (req) => { const cfg = readProviderConfig(req.providerConfig); const overrides = readVolcengineOverrides(req.providerOverrides); const apiKey = resolveSeedSpeechApiKey(cfg.apiKey); const appId = cfg.appId || process.env.VOLCENGINE_TTS_APPID; const token = cfg.token || process.env.VOLCENGINE_TTS_TOKEN; if (!apiKey && (!appId || !token)) throw new Error("Volcengine TTS credentials missing. Set VOLCENGINE_TTS_API_KEY, BYTEPLUS_SEED_SPEECH_API_KEY, or legacy VOLCENGINE_TTS_APPID and VOLCENGINE_TTS_TOKEN."); const isVoiceNote = req.target === "voice-note"; const encoding = isVoiceNote ? "ogg_opus" : "mp3"; return { audioBuffer: await volcengineTTS({ text: req.text, apiKey, appId, token, voice: overrides.voice ?? cfg.voice, cluster: cfg.cluster, resourceId: cfg.resourceId, appKey: cfg.appKey, baseUrl: cfg.baseUrl, speedRatio: overrides.speedRatio ?? cfg.speedRatio, emotion: overrides.emotion ?? cfg.emotion, encoding, timeoutMs: req.timeoutMs }), outputFormat: encoding === "ogg_opus" ? "opus" : "mp3", fileExtension: encoding === "ogg_opus" ? ".opus" : ".mp3", voiceCompatible: isVoiceNote }; } }; } //#endregion export { buildVolcengineSpeechProvider as t };