brand new durable object
This commit is contained in:
parent
1b566f7df3
commit
848275fb86
2 changed files with 20 additions and 35 deletions
|
|
@ -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<Env> {
|
|||
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<SessionState> {
|
||||
const stored = await this.ctx.storage.get<SessionState>("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<Env> {
|
|||
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<Env> {
|
|||
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<Env> {
|
|||
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<Env> {
|
|||
});
|
||||
|
||||
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 });
|
||||
|
|
|
|||
|
|
@ -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<Response> {
|
||||
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);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue