diff --git a/frontend/server.ts b/frontend/server.ts index c05efc5..a429435 100644 --- a/frontend/server.ts +++ b/frontend/server.ts @@ -384,17 +384,38 @@ app.use("*", async (c, next) => { }); app.all("/api/copilotkit/*", async (c) => { - // CopilotChat fires POST …/agent//connect for explicit threadIds and - // the runtime's in-memory runner replays THIS PROCESS's event history — - // stale relative to the DB store (it resurrects cleared conversations and - // double-feeds page-load hydration). The empty-messages hydration run - // against MAF is our single restore path, so connect gets an - // immediately-completed stream instead. - if (new URL(c.req.url).pathname.endsWith("/connect")) { - return new Response("", { + // CopilotChat fires "connect" on every mount with an explicit threadId, + // and the runtime's in-memory runner answers it by replaying THIS + // PROCESS's event history — every run since the server started, across + // "Nueva conversación" clears (the DB delete can't touch process memory). + // That resurrected cleared conversations on navigation. The + // empty-messages hydration run against MAF's snapshot store is our single + // restore path, so connect gets an immediately-completed stream instead. + // + // Two transports must be caught: multi-route (POST …/agent//connect) + // and single-route (POST /api/copilotkit with {method:"agent/connect"} in + // the body — the one CopilotKit actually uses here; the URL-only check + // silently missed it). + const emptyStream = () => + new Response("", { status: 200, headers: { "Content-Type": "text/event-stream" }, }); + if (new URL(c.req.url).pathname.endsWith("/connect")) { + return emptyStream(); + } + if ( + c.req.method === "POST" && + (c.req.header("content-type") ?? "").includes("application/json") + ) { + try { + const envelope = (await c.req.raw.clone().json()) as { method?: string }; + if (envelope?.method === "agent/connect") { + return emptyStream(); + } + } catch { + // not JSON — fall through to the runtime + } } const cookieHeader = c.req.header("cookie") ?? "";