openclaw
Version:
Multi-channel AI gateway with extensible messaging integrations
137 lines (136 loc) • 5.68 kB
JavaScript
import { c as normalizeOptionalString, s as normalizeOptionalLowercaseString } from "./string-coerce-mnp54Vah.js";
import { o as isRecord } from "./record-coerce-DHZ4bFlT.js";
import { d as resolveConfigDir, p as resolveUserPath } from "./utils-CCC-BEJH.js";
import { p as tryReadJsonSync } from "./json-files-2umMHm0W.js";
import { S as normalizeTtsAutoMode, v as resolveEffectiveTtsConfig } from "./gateway-startup-plugin-ids-3X_G47Qt.js";
import path from "node:path";
//#region src/tts/status-config.ts
const DEFAULT_TTS_MAX_LENGTH = 1500;
const DEFAULT_TTS_SUMMARIZE = true;
const DEFAULT_OPENAI_TTS_BASE_URL = "https://api.openai.com/v1";
const MAX_STATUS_DETAIL_LENGTH = 96;
function resolveConfiguredTtsAutoMode(raw) {
return normalizeTtsAutoMode(raw.auto) ?? (raw.enabled ? "always" : "off");
}
function normalizeConfiguredSpeechProviderId(providerId) {
const normalized = normalizeOptionalLowercaseString(providerId);
if (!normalized) return;
return normalized === "edge" ? "microsoft" : normalized;
}
function normalizeTtsPersonaId(personaId) {
return normalizeOptionalLowercaseString(personaId ?? void 0);
}
function resolvePersonaPreferredProvider(raw, personaId) {
if (!personaId || !raw.personas) return;
for (const [id, persona] of Object.entries(raw.personas)) {
if (normalizeTtsPersonaId(id) !== personaId) continue;
return normalizeOptionalString(normalizeConfiguredSpeechProviderId(persona.provider) ?? persona.provider);
}
}
function resolveTtsPrefsPathValue(prefsPath) {
const configuredPath = normalizeOptionalString(prefsPath);
if (configuredPath) return resolveUserPath(configuredPath);
const envPath = normalizeOptionalString(process.env.OPENCLAW_TTS_PREFS);
if (envPath) return resolveUserPath(envPath);
return path.join(resolveConfigDir(process.env), "settings", "tts.json");
}
function readPrefs(prefsPath) {
return tryReadJsonSync(prefsPath) ?? {};
}
function resolveTtsAutoModeFromPrefs(prefs) {
const auto = normalizeTtsAutoMode(prefs.tts?.auto);
if (auto) return auto;
if (typeof prefs.tts?.enabled === "boolean") return prefs.tts.enabled ? "always" : "off";
}
function normalizeStatusDetail(value, maxLength = MAX_STATUS_DETAIL_LENGTH) {
if (typeof value !== "string") return;
const normalized = value.trim().replace(/\s+/g, " ");
if (!normalized) return;
return normalized.length > maxLength ? `${normalized.slice(0, maxLength - 3)}...` : normalized;
}
function sanitizeBaseUrlForStatus(value) {
const raw = normalizeStatusDetail(value, 180);
if (!raw) return;
try {
const parsed = new URL(raw);
parsed.username = "";
parsed.password = "";
parsed.search = "";
parsed.hash = "";
return normalizeStatusDetail(parsed.toString().replace(/\/+$/, ""), 120);
} catch {
return "[invalid-url]";
}
}
function isCustomOpenAiTtsBaseUrl(baseUrl) {
return baseUrl ? baseUrl.replace(/\/+$/, "") !== DEFAULT_OPENAI_TTS_BASE_URL : false;
}
function firstStatusDetail(record, keys) {
if (!record) return;
for (const key of keys) {
const value = normalizeStatusDetail(record[key]);
if (value) return value;
}
}
function resolveProviderConfigRecord(raw, provider) {
const rawRecord = isRecord(raw) ? raw : {};
const providers = isRecord(raw.providers) ? raw.providers : {};
if (provider === "microsoft") return {
...isRecord(rawRecord.edge) ? rawRecord.edge : {},
...isRecord(rawRecord.microsoft) ? rawRecord.microsoft : {},
...isRecord(providers.edge) ? providers.edge : {},
...isRecord(providers.microsoft) ? providers.microsoft : {}
};
const direct = rawRecord[provider];
const providerScoped = providers[provider];
if (isRecord(providerScoped)) return providerScoped;
if (isRecord(direct)) return direct;
return rawRecord;
}
function resolveStatusProviderDetails(raw, provider) {
if (provider === "auto") return {};
const record = resolveProviderConfigRecord(raw, provider);
const sanitizedBaseUrl = sanitizeBaseUrlForStatus(record?.baseUrl);
const customBaseUrl = provider === "openai" && isCustomOpenAiTtsBaseUrl(sanitizedBaseUrl);
const details = {};
const displayName = firstStatusDetail(record, ["displayName"]);
if (displayName) details.displayName = displayName;
const model = firstStatusDetail(record, ["model", "modelId"]);
if (model) details.model = model;
const voice = firstStatusDetail(record, [
"speakerVoice",
"speakerVoiceId",
"voice",
"voiceId",
"voiceName"
]);
if (voice) details.voice = voice;
if (sanitizedBaseUrl && (provider !== "openai" || customBaseUrl)) {
details.baseUrl = sanitizedBaseUrl;
details.customBaseUrl = customBaseUrl;
}
return details;
}
function resolveStatusTtsSnapshot(params) {
const context = {
agentId: params.agentId,
channelId: params.channelId,
accountId: params.accountId
};
const raw = resolveEffectiveTtsConfig(params.cfg, context);
const prefs = readPrefs(resolveTtsPrefsPathValue(raw.prefsPath));
const autoMode = normalizeTtsAutoMode(params.sessionAuto) ?? resolveTtsAutoModeFromPrefs(prefs) ?? resolveConfiguredTtsAutoMode(raw);
if (autoMode === "off") return null;
const persona = prefs.tts && Object.hasOwn(prefs.tts, "persona") ? normalizeTtsPersonaId(prefs.tts.persona) : normalizeTtsPersonaId(raw.persona);
const provider = normalizeConfiguredSpeechProviderId(prefs.tts?.provider) ?? resolvePersonaPreferredProvider(raw, persona) ?? normalizeConfiguredSpeechProviderId(raw.provider) ?? "auto";
return {
autoMode,
provider,
...resolveStatusProviderDetails(raw, provider),
...persona ? { persona } : {},
maxLength: prefs.tts?.maxLength ?? DEFAULT_TTS_MAX_LENGTH,
summarize: prefs.tts?.summarize ?? DEFAULT_TTS_SUMMARIZE
};
}
//#endregion
export { resolveStatusTtsSnapshot as t };