You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

89 lines
2.5 KiB

import { defineEventHandler, getQuery } from "h3";
import { R } from "#server/utils/response";
import { getCurrentUser } from "#server/utils/context";
import { getTempTokenFromCookie } from "#server/service/agent/temp-token";
import { getSessionByIdAndUser } from "#server/service/agent/session";
import { getStreamBuffer, subscribeToBuffer } from "#server/service/agent/stream-buffer";
import log4js from "logger";
const logger = log4js.getLogger("APP");
export default defineEventHandler(async (event) => {
const user = await getCurrentUser(event);
const tempToken = getTempTokenFromCookie(event);
if (!user && !tempToken) {
throw createError({ statusCode: 401, statusMessage: "请先登录或创建临时会话" });
}
const query = getQuery(event);
const sessionId = query.sessionId as string | undefined;
if (!sessionId) {
throw createError({ statusCode: 400, statusMessage: "缺少 sessionId 参数" });
}
const session = await getSessionByIdAndUser(sessionId, user?.id ?? null, tempToken);
if (!session) {
throw createError({ statusCode: 404, statusMessage: "会话不存在" });
}
const buf = getStreamBuffer(sessionId);
if (!buf) {
return R.success({ active: false, reason: "no-buffer" });
}
if (buf.done && buf.chunks.length === 0) {
return R.success({ active: false, reason: "already-done", modelId: buf.modelId });
}
const stream = new ReadableStream<Uint8Array>({
start(controller) {
for (const chunk of buf.chunks) {
controller.enqueue(chunk);
}
if (buf.done) {
controller.close();
return;
}
const unsubscribe = subscribeToBuffer(
sessionId,
(chunk) => {
try {
controller.enqueue(chunk);
} catch (e) {
logger.error("[STREAM-RESUME] enqueue error: %s", e instanceof Error ? e.message : String(e));
}
},
() => {
try {
controller.close();
} catch {
}
},
);
event.node.req.on("close", () => {
unsubscribe();
try {
controller.close();
} catch {
}
});
},
});
return new Response(stream, {
headers: {
"Content-Type": "text/event-stream; charset=utf-8",
"Cache-Control": "no-cache",
"Connection": "keep-alive",
"X-Stream-Resume": "true",
"X-Stream-Model-Id": String(buf.modelId ?? ""),
"X-Stream-User-Message-Id": buf.userMessageId ?? "",
},
});
});