























@@ -192,6 +192,189 @@ describe("buildOpenAISpeechProvider", () => {
192192});
193193});
194194195+it("parses preferred-OpenAI speed directive within the supported range", () => {
196+const provider = buildOpenAISpeechProvider();
197+198+expect(
199+provider.parseDirectiveToken?.({
200+key: "speed",
201+value: "1.5",
202+policy: {
203+allowVoice: true,
204+allowModelId: true,
205+allowVoiceSettings: true,
206+},
207+providerConfig: {
208+baseUrl: "https://api.openai.com/v1/",
209+},
210+} as never),
211+).toEqual({
212+handled: true,
213+overrides: { speed: 1.5 },
214+});
215+});
216+217+it("parses explicit openai_speed alias", () => {
218+const provider = buildOpenAISpeechProvider();
219+220+expect(
221+provider.parseDirectiveToken?.({
222+key: "openai_speed",
223+value: "0.75",
224+policy: {
225+allowVoice: true,
226+allowModelId: true,
227+allowVoiceSettings: true,
228+},
229+providerConfig: {
230+baseUrl: "https://api.openai.com/v1/",
231+},
232+} as never),
233+).toEqual({
234+handled: true,
235+overrides: { speed: 0.75 },
236+});
237+});
238+239+it("ignores OpenAI speed directives when allowVoiceSettings is disabled", () => {
240+const provider = buildOpenAISpeechProvider();
241+242+expect(
243+provider.parseDirectiveToken?.({
244+key: "speed",
245+value: "1.5",
246+policy: {
247+allowVoice: true,
248+allowModelId: true,
249+allowVoiceSettings: false,
250+},
251+providerConfig: {
252+baseUrl: "https://api.openai.com/v1/",
253+},
254+} as never),
255+).toEqual({
256+handled: true,
257+});
258+});
259+260+it("warns on non-numeric OpenAI speed values", () => {
261+const provider = buildOpenAISpeechProvider();
262+263+expect(
264+provider.parseDirectiveToken?.({
265+key: "speed",
266+value: "fast",
267+policy: {
268+allowVoice: true,
269+allowModelId: true,
270+allowVoiceSettings: true,
271+},
272+providerConfig: {
273+baseUrl: "https://api.openai.com/v1/",
274+},
275+} as never),
276+).toEqual({
277+handled: true,
278+warnings: ['invalid OpenAI speed "fast" (0.25-4.0)'],
279+});
280+});
281+282+it("warns on partial OpenAI speed values", () => {
283+const provider = buildOpenAISpeechProvider();
284+285+expect(
286+provider.parseDirectiveToken?.({
287+key: "speed",
288+value: "1.5abc",
289+policy: {
290+allowVoice: true,
291+allowModelId: true,
292+allowVoiceSettings: true,
293+},
294+providerConfig: {
295+baseUrl: "https://api.openai.com/v1/",
296+},
297+} as never),
298+).toEqual({
299+handled: true,
300+warnings: ['invalid OpenAI speed "1.5abc" (0.25-4.0)'],
301+});
302+});
303+304+it("warns on OpenAI speed values outside the supported 0.25..4 range", () => {
305+const provider = buildOpenAISpeechProvider();
306+307+expect(
308+provider.parseDirectiveToken?.({
309+key: "speed",
310+value: "5",
311+policy: {
312+allowVoice: true,
313+allowModelId: true,
314+allowVoiceSettings: true,
315+},
316+providerConfig: {
317+baseUrl: "https://api.openai.com/v1/",
318+},
319+} as never),
320+).toEqual({
321+handled: true,
322+warnings: ['invalid OpenAI speed "5" (0.25-4.0)'],
323+});
324+});
325+326+it("passes custom endpoint OpenAI-compatible speed directives through", () => {
327+const provider = buildOpenAISpeechProvider();
328+329+expect(
330+provider.parseDirectiveToken?.({
331+key: "speed",
332+value: "4.5",
333+policy: {
334+allowVoice: true,
335+allowModelId: true,
336+allowVoiceSettings: true,
337+},
338+providerConfig: {
339+baseUrl: "https://tts.example.com/v1",
340+},
341+} as never),
342+).toEqual({
343+handled: true,
344+overrides: { speed: 4.5 },
345+});
346+});
347+348+it("uses OPENAI_TTS_BASE_URL when parsing OpenAI-compatible speed directives", () => {
349+const previousBaseUrl = process.env.OPENAI_TTS_BASE_URL;
350+process.env.OPENAI_TTS_BASE_URL = "https://tts.example.com/v1";
351+try {
352+const provider = buildOpenAISpeechProvider();
353+354+expect(
355+provider.parseDirectiveToken?.({
356+key: "speed",
357+value: "4.5",
358+policy: {
359+allowVoice: true,
360+allowModelId: true,
361+allowVoiceSettings: true,
362+},
363+providerConfig: {},
364+} as never),
365+).toEqual({
366+handled: true,
367+overrides: { speed: 4.5 },
368+});
369+} finally {
370+if (previousBaseUrl === undefined) {
371+delete process.env.OPENAI_TTS_BASE_URL;
372+} else {
373+process.env.OPENAI_TTS_BASE_URL = previousBaseUrl;
374+}
375+}
376+});
377+195378it("preserves talk responseFormat overrides", () => {
196379const provider = buildOpenAISpeechProvider();
197380此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。