fix: honor telephony tts directives

This commit is contained in:
Peter Steinberger
2026-05-01 22:48:27 +01:00
parent 236bd42bb3
commit 4389ceedac
11 changed files with 397 additions and 33 deletions

View File

@@ -10,6 +10,7 @@ import type {
SpeechProviderPlugin,
SpeechProviderPrepareSynthesisContext,
SpeechSynthesisRequest,
SpeechTelephonySynthesisRequest,
} from "openclaw/plugin-sdk/speech-core";
import { afterEach, describe, expect, it, vi } from "vitest";
@@ -542,6 +543,47 @@ describe("speech-core native voice-note routing", () => {
expect(result.attempts?.[0]).not.toHaveProperty("personaBinding");
});
it("passes directive overrides to telephony synthesis providers", async () => {
const synthesizeTelephony = vi.fn(async (_request: SpeechTelephonySynthesisRequest) => ({
audioBuffer: Buffer.from("voice"),
outputFormat: "pcm",
sampleRate: 24000,
}));
installSpeechProviders([
createMockSpeechProvider("mock", {
synthesizeTelephony,
}),
]);
const result = await textToSpeechTelephony({
text: "Use a directed telephony voice.",
cfg: {
messages: {
tts: {
enabled: true,
provider: "mock",
},
},
},
overrides: {
providerOverrides: {
mock: {
voice: "directed-voice",
},
},
},
});
expect(result.success).toBe(true);
expect(synthesizeTelephony).toHaveBeenCalledWith(
expect.objectContaining({
providerOverrides: {
voice: "directed-voice",
},
}),
);
});
it("uses provider defaults when fallback policy allows missing persona bindings", async () => {
await synthesizeSpeech({
text: "Use neutral provider defaults.",

View File

@@ -1318,11 +1318,13 @@ export async function textToSpeechTelephony(params: {
text: string;
cfg: OpenClawConfig;
prefsPath?: string;
overrides?: TtsDirectiveOverrides;
}): Promise<TtsTelephonyResult> {
const setup = resolveTtsRequestSetup({
text: params.text,
cfg: params.cfg,
prefsPath: params.prefsPath,
providerOverride: params.overrides?.provider,
});
if ("error" in setup) {
return { success: false, error: setup.error };
@@ -1371,6 +1373,7 @@ export async function textToSpeechTelephony(params: {
text: params.text,
cfg,
providerConfig: resolvedProvider.providerConfig,
providerOverrides: params.overrides?.providerOverrides?.[resolvedProvider.provider.id],
persona: resolvedProvider.synthesisPersona,
personaProviderConfig: resolvedProvider.personaProviderConfig,
target: "telephony",
@@ -1380,6 +1383,7 @@ export async function textToSpeechTelephony(params: {
text: prepared.text,
cfg,
providerConfig: prepared.providerConfig,
providerOverrides: prepared.providerOverrides,
timeoutMs: config.timeoutMs,
});
const latencyMs = Date.now() - providerStart;