This commit is contained in:
2026-07-29 11:42:41 +08:00
commit 48b7391365
71 changed files with 28910 additions and 0 deletions

View File

@ -0,0 +1,60 @@
import { apiError } from "@/lib/api";
import {
getBuilderRunEvents,
getOrStartBuilderRun,
} from "@/lib/builder-runs";
import { encodeSse, sseResponse } from "@/lib/sse";
import { builderRequestSchema } from "@/lib/validation";
export const runtime = "nodejs";
export const maxDuration = 120;
const terminalStatuses = new Set(["complete", "stopped", "error"]);
export async function POST(request: Request) {
try {
const input = builderRequestSchema.parse(await request.json());
const run = getOrStartBuilderRun(input);
let cursor = input.afterSeq;
const stream = new ReadableStream<Uint8Array>({
async start(controller) {
try {
while (!request.signal.aborted) {
const snapshot = getBuilderRunEvents(run.id, cursor);
if (!snapshot) {
controller.enqueue(
encodeSse({ type: "error", message: "节点任务已过期" }),
);
controller.close();
return;
}
for (const event of snapshot.events) {
controller.enqueue(encodeSse(event));
cursor = Math.max(cursor, event.seq ?? cursor);
}
if (terminalStatuses.has(snapshot.status)) {
controller.close();
return;
}
await new Promise((resolve) => setTimeout(resolve, 100));
}
} catch {
try {
controller.close();
} catch {
// A disconnected editor can reconnect with the last event seq.
}
}
},
});
return sseResponse(stream);
} catch (error) {
return apiError(error, "无法处理 Skill 对话");
}
}