fix(tts): evaluate OPENAI_TTS_BASE_URL at runtime (#2816)
This commit is contained in:
parent
b559a5ab87
commit
5756387848
@ -758,10 +758,21 @@ export const OPENAI_TTS_MODELS = ["gpt-4o-mini-tts", "tts-1", "tts-1-hd"] as con
|
|||||||
* When set, model/voice validation is relaxed to allow non-OpenAI models.
|
* When set, model/voice validation is relaxed to allow non-OpenAI models.
|
||||||
* Example: OPENAI_TTS_BASE_URL=http://localhost:8880/v1
|
* Example: OPENAI_TTS_BASE_URL=http://localhost:8880/v1
|
||||||
*/
|
*/
|
||||||
const OPENAI_TTS_BASE_URL = (
|
const DEFAULT_OPENAI_TTS_BASE_URL = "https://api.openai.com/v1";
|
||||||
process.env.OPENAI_TTS_BASE_URL?.trim() || "https://api.openai.com/v1"
|
/**
|
||||||
).replace(/\/+$/, "");
|
* Custom OpenAI-compatible TTS endpoint.
|
||||||
const isCustomOpenAIEndpoint = OPENAI_TTS_BASE_URL !== "https://api.openai.com/v1";
|
* When set, model/voice validation is relaxed to allow non-OpenAI models.
|
||||||
|
* Example: OPENAI_TTS_BASE_URL=http://localhost:8880/v1
|
||||||
|
*/
|
||||||
|
function getOpenAITtsBaseUrl(): string {
|
||||||
|
return (
|
||||||
|
process.env.OPENAI_TTS_BASE_URL?.trim() || DEFAULT_OPENAI_TTS_BASE_URL
|
||||||
|
).replace(/\/+$/, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
function isCustomOpenAIEndpoint(): boolean {
|
||||||
|
return getOpenAITtsBaseUrl() !== DEFAULT_OPENAI_TTS_BASE_URL;
|
||||||
|
}
|
||||||
export const OPENAI_TTS_VOICES = [
|
export const OPENAI_TTS_VOICES = [
|
||||||
"alloy",
|
"alloy",
|
||||||
"ash",
|
"ash",
|
||||||
@ -778,13 +789,13 @@ type OpenAiTtsVoice = (typeof OPENAI_TTS_VOICES)[number];
|
|||||||
|
|
||||||
function isValidOpenAIModel(model: string): boolean {
|
function isValidOpenAIModel(model: string): boolean {
|
||||||
// Allow any model when using custom endpoint (e.g., Kokoro, LocalAI)
|
// Allow any model when using custom endpoint (e.g., Kokoro, LocalAI)
|
||||||
if (isCustomOpenAIEndpoint) return true;
|
if (isCustomOpenAIEndpoint()) return true;
|
||||||
return OPENAI_TTS_MODELS.includes(model as (typeof OPENAI_TTS_MODELS)[number]);
|
return OPENAI_TTS_MODELS.includes(model as (typeof OPENAI_TTS_MODELS)[number]);
|
||||||
}
|
}
|
||||||
|
|
||||||
function isValidOpenAIVoice(voice: string): voice is OpenAiTtsVoice {
|
function isValidOpenAIVoice(voice: string): voice is OpenAiTtsVoice {
|
||||||
// Allow any voice when using custom endpoint (e.g., Kokoro Chinese voices)
|
// Allow any voice when using custom endpoint (e.g., Kokoro Chinese voices)
|
||||||
if (isCustomOpenAIEndpoint) return true;
|
if (isCustomOpenAIEndpoint()) return true;
|
||||||
return OPENAI_TTS_VOICES.includes(voice as OpenAiTtsVoice);
|
return OPENAI_TTS_VOICES.includes(voice as OpenAiTtsVoice);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1011,7 +1022,7 @@ async function openaiTTS(params: {
|
|||||||
const timeout = setTimeout(() => controller.abort(), timeoutMs);
|
const timeout = setTimeout(() => controller.abort(), timeoutMs);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await fetch(`${OPENAI_TTS_BASE_URL}/audio/speech`, {
|
const response = await fetch(`${getOpenAITtsBaseUrl()}/audio/speech`, {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: {
|
headers: {
|
||||||
Authorization: `Bearer ${apiKey}`,
|
Authorization: `Bearer ${apiKey}`,
|
||||||
@ -1365,9 +1376,9 @@ export async function maybeApplyTtsToPayload(params: {
|
|||||||
visibleText === text.trim()
|
visibleText === text.trim()
|
||||||
? params.payload
|
? params.payload
|
||||||
: {
|
: {
|
||||||
...params.payload,
|
...params.payload,
|
||||||
text: visibleText.length > 0 ? visibleText : undefined,
|
text: visibleText.length > 0 ? visibleText : undefined,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (autoMode === "tagged" && !directives.hasDirective) return nextPayload;
|
if (autoMode === "tagged" && !directives.hasDirective) return nextPayload;
|
||||||
if (autoMode === "inbound" && params.inboundAudio !== true) return nextPayload;
|
if (autoMode === "inbound" && params.inboundAudio !== true) return nextPayload;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user