test new tts

This commit is contained in:
akdeb 2026-04-17 13:46:46 +05:30
parent 6bfa6b33e2
commit 7e494607b9

View file

@ -1,5 +1,5 @@
import { DurableObject } from "cloudflare:workers"; import { DurableObject } from "cloudflare:workers";
import { WorkersAIFluxSTT, type TranscriberSession } from "@cloudflare/voice"; import { WorkersAIFluxSTT, WorkersAITTS, type TranscriberSession } from "@cloudflare/voice";
import type { Env } from "../src/types"; import type { Env } from "../src/types";
import { createOpusPacketizer } from "../src/opus"; import { createOpusPacketizer } from "../src/opus";
import { getFirstMessagePrompt, getSystemPrompt } from "../src/prompt"; import { getFirstMessagePrompt, getSystemPrompt } from "../src/prompt";
@ -88,24 +88,22 @@ async function generateOpenAIReply(
); );
} }
async function synthesizeSpeech(env: Env, text: string): Promise<Response> { const ttsProviderFor = (env: Env) => new WorkersAITTS(env.AI, {
model: "@cf/deepgram/aura-1",
speaker: "asteria",
});
async function synthesizeSpeech(env: Env, text: string): Promise<ArrayBuffer> {
if (!env.AI) { if (!env.AI) {
throw new Error("Cloudflare AI binding is missing"); throw new Error("Cloudflare AI binding is missing");
} }
return env.AI.run( const audio = await ttsProviderFor(env).synthesize(text);
"@cf/deepgram/aura-1", if (!audio) {
{ throw new Error("WorkersAITTS returned no audio");
text, }
speaker: "asteria",
encoding: "linear16", return audio;
container: "none",
sample_rate: AUDIO_OUTPUT_SAMPLE_RATE,
},
{
returnRawResponse: true,
},
) as Promise<Response>;
} }
export class ElatoOpenAiVoiceAgent extends DurableObject<Env> { export class ElatoOpenAiVoiceAgent extends DurableObject<Env> {
@ -189,29 +187,15 @@ export class ElatoOpenAiVoiceAgent extends DurableObject<Env> {
opus.reset(); opus.reset();
websocket.send(createServerMessage("RESPONSE.CREATED")); websocket.send(createServerMessage("RESPONSE.CREATED"));
const ttsResponse = await synthesizeSpeech(this.env, reply);
if (!ttsResponse.ok || !ttsResponse.body) {
console.error(
`[cloudflare][tts] request failed: ${ttsResponse.status} ${ttsResponse.statusText}`,
);
websocket.send(createServerMessage("RESPONSE.ERROR"));
return;
}
const reader = ttsResponse.body.getReader();
try { try {
while (true) { const audio = await synthesizeSpeech(this.env, reply);
const { done, value } = await reader.read(); opus.push(new Uint8Array(audio));
if (done) break;
if (value) {
opus.push(value);
}
}
opus.flush(true); opus.flush(true);
websocket.send(createServerMessage("RESPONSE.COMPLETE", { volume_control: 100 })); websocket.send(createServerMessage("RESPONSE.COMPLETE", { volume_control: 100 }));
console.log(`[cloudflare][tts] streamed reply successfully (${reply.length} chars)`); console.log(`[cloudflare][tts] synthesized reply successfully via WorkersAITTS (${reply.length} chars)`);
} finally { } catch (error) {
reader.releaseLock(); console.error(`[cloudflare][tts] ${errorMessage(error)}`);
websocket.send(createServerMessage("RESPONSE.ERROR"));
} }
} }