diff --git a/server-cloudflare/models/openai.ts b/server-cloudflare/models/openai.ts index cf78849..ff15b48 100644 --- a/server-cloudflare/models/openai.ts +++ b/server-cloudflare/models/openai.ts @@ -97,6 +97,7 @@ async function synthesizeSpeech(env: Env, text: string): Promise { export class ElatoOpenAiVoiceAgent extends DurableObject { private audioBuffer = new Uint8Array(0); private isGenerating = false; + private opusPromise: Promise>> | null = null; constructor(ctx: DurableObjectState, env: Env) { super(ctx, env); @@ -122,10 +123,17 @@ export class ElatoOpenAiVoiceAgent extends DurableObject { this.audioBuffer = new Uint8Array(0); } + private getOpusPacketizer(websocket: WebSocket) { + if (!this.opusPromise) { + this.opusPromise = createOpusPacketizer((packet) => websocket.send(packet)); + } + return this.opusPromise; + } + private async handleTurn( websocket: WebSocket, - opus: Awaited>, ) { + const opus = await this.getOpusPacketizer(websocket); const pcm = this.audioBuffer; this.resetBufferedAudio(); @@ -184,7 +192,6 @@ export class ElatoOpenAiVoiceAgent extends DurableObject { const pair = new WebSocketPair(); const [client, server] = Object.values(pair); server.accept(); - const opus = await createOpusPacketizer((packet) => server.send(packet)); server.send(JSON.stringify(createAuthMessage())); @@ -210,7 +217,7 @@ export class ElatoOpenAiVoiceAgent extends DurableObject { } this.isGenerating = true; try { - await this.handleTurn(server, opus); + await this.handleTurn(server); } catch { server.send(createServerMessage("RESPONSE.ERROR")); } finally { @@ -236,7 +243,10 @@ export class ElatoOpenAiVoiceAgent extends DurableObject { server.addEventListener("close", () => { this.isGenerating = false; this.resetBufferedAudio(); - opus.close(); + if (this.opusPromise) { + void this.opusPromise.then((opus) => opus.close()).catch(() => {}); + this.opusPromise = null; + } }); return new Response(null, { status: 101, webSocket: client }); diff --git a/server-cloudflare/wrangler.toml b/server-cloudflare/wrangler.toml index 22d73be..fad0787 100644 --- a/server-cloudflare/wrangler.toml +++ b/server-cloudflare/wrangler.toml @@ -1,4 +1,4 @@ -name = "elato-cloudflare-voice" +name = "elato" main = "src/index.ts" compatibility_date = "2026-04-17" compatibility_flags = ["nodejs_compat"] @@ -16,5 +16,5 @@ new_sqlite_classes = ["ElatoOpenAiVoiceAgent"] [observability] [observability.logs] -enabled = false -invocation_logs = true \ No newline at end of file +enabled = true +invocation_logs = true