From 848275fb86ed715e7f74cee19d476fcadb3f18ed Mon Sep 17 00:00:00 2001 From: akdeb Date: Fri, 17 Apr 2026 14:21:48 +0530 Subject: [PATCH] brand new durable object --- server-cloudflare/models/openai.ts | 47 ++++++++++++------------------ server-cloudflare/src/index.ts | 8 +---- 2 files changed, 20 insertions(+), 35 deletions(-) diff --git a/server-cloudflare/models/openai.ts b/server-cloudflare/models/openai.ts index 3ea1e79..7bc524a 100644 --- a/server-cloudflare/models/openai.ts +++ b/server-cloudflare/models/openai.ts @@ -12,10 +12,6 @@ interface OpenAIChatMessage { content: string; } -interface SessionState { - history: OpenAIChatMessage[]; -} - function createAuthMessage() { return { type: "auth", @@ -114,18 +110,23 @@ export class ElatoOpenAiVoiceAgent extends DurableObject { private hasStartedConversation = false; private transcriberSession: TranscriberSession | null = null; private currentWebSocket: WebSocket | null = null; + private history: OpenAIChatMessage[] = []; constructor(ctx: DurableObjectState, env: Env) { super(ctx, env); } - private async loadSessionState(): Promise { - const stored = await this.ctx.storage.get("session_state"); - return stored || { history: [] }; - } - - private async saveSessionState(state: SessionState) { - await this.ctx.storage.put("session_state", state); + private resetSession() { + this.isGenerating = false; + this.hasStartedConversation = false; + this.currentWebSocket = null; + this.history = []; + this.transcriberSession?.close(); + this.transcriberSession = null; + if (this.opusPromise) { + void this.opusPromise.then((opus) => opus.close()).catch(() => {}); + this.opusPromise = null; + } } private getOpusPacketizer(websocket: WebSocket) { @@ -220,14 +221,12 @@ export class ElatoOpenAiVoiceAgent extends DurableObject { console.log(`[cloudflare][stt] transcript: ${transcript}`); /* Add user transcript DB call here */ - const session = await this.loadSessionState(); - const reply = await generateOpenAIReply(this.env, transcript, session.history); + const reply = await generateOpenAIReply(this.env, transcript, this.history); console.log(`[cloudflare][llm] generated reply (${reply.length} chars)`); - session.history.push( + this.history.push( { role: "user", content: transcript }, { role: "assistant", content: reply }, ); - await this.saveSessionState(session); /* Add AI transcript DB call here */ await this.streamAssistantReply(websocket, reply); } @@ -241,11 +240,9 @@ export class ElatoOpenAiVoiceAgent extends DurableObject { this.isGenerating = true; try { - const session = await this.loadSessionState(); - const reply = await generateOpenAIReply(this.env, null, session.history); + const reply = await generateOpenAIReply(this.env, null, this.history); console.log(`[cloudflare][llm] initial reply (${reply.length} chars)`); - session.history.push({ role: "assistant", content: reply }); - await this.saveSessionState(session); + this.history.push({ role: "assistant", content: reply }); /* Add AI transcript DB call here */ await this.streamAssistantReply(websocket, reply); } catch (error) { @@ -260,6 +257,8 @@ export class ElatoOpenAiVoiceAgent extends DurableObject { return new Response("Expected websocket", { status: 426 }); } + this.resetSession(); + const pair = new WebSocketPair(); const [client, server] = Object.values(pair); server.accept(); @@ -320,15 +319,7 @@ export class ElatoOpenAiVoiceAgent extends DurableObject { }); server.addEventListener("close", () => { - this.isGenerating = false; - this.hasStartedConversation = false; - this.currentWebSocket = null; - this.transcriberSession?.close(); - this.transcriberSession = null; - if (this.opusPromise) { - void this.opusPromise.then((opus) => opus.close()).catch(() => {}); - this.opusPromise = null; - } + this.resetSession(); }); return new Response(null, { status: 101, webSocket: client }); diff --git a/server-cloudflare/src/index.ts b/server-cloudflare/src/index.ts index cb7b452..f140328 100644 --- a/server-cloudflare/src/index.ts +++ b/server-cloudflare/src/index.ts @@ -2,12 +2,6 @@ import type { Env } from "./types"; export { ElatoOpenAiVoiceAgent } from "../models/openai"; -function sessionNameFromRequest(request: Request): string { - const url = new URL(request.url); - const pathParts = url.pathname.split("/").filter(Boolean); - return pathParts[2] || url.searchParams.get("session") || "default"; -} - export default { async fetch(request: Request, env: Env): Promise { const url = new URL(request.url); @@ -20,7 +14,7 @@ export default { /* Add AUTH here */ const stub = env.ElatoOpenAiVoiceAgent.get( - env.ElatoOpenAiVoiceAgent.idFromName(sessionNameFromRequest(request)), + env.ElatoOpenAiVoiceAgent.newUniqueId(), ); return stub.fetch(request); }