fix(canvas): 文本生成 - 修复分镜超时并贯通 Agent 与创作页流式返回

This commit is contained in:
ddCat
2026-08-27 22:39:30 +08:00
parent 482d8bdbc2
commit 7cb6aed27d
18 changed files with 944 additions and 44 deletions

View File

@@ -0,0 +1,57 @@
export type TaskTextStreamEvent = {
event: string;
id?: number;
data?: unknown;
};
export type TaskTextStreamParser = {
buffer: string;
};
export function createTaskTextStreamParser(): TaskTextStreamParser {
return { buffer: "" };
}
export function consumeTaskTextStream(
parser: TaskTextStreamParser,
chunk: string,
onEvent: (event: TaskTextStreamEvent) => void,
flush = false,
) {
parser.buffer += chunk;
for (;;) {
const boundary = parser.buffer.match(/\r?\n\r?\n/);
if (!boundary) break;
const index = boundary.index ?? 0;
emitTaskTextStreamBlock(parser.buffer.slice(0, index), onEvent);
parser.buffer = parser.buffer.slice(index + boundary[0].length);
}
if (flush && parser.buffer.trim()) {
emitTaskTextStreamBlock(parser.buffer, onEvent);
parser.buffer = "";
}
}
function emitTaskTextStreamBlock(block: string, onEvent: (event: TaskTextStreamEvent) => void) {
let event = "message";
let id: number | undefined;
const data: string[] = [];
for (const line of block.split(/\r?\n/)) {
if (!line || line.startsWith(":")) continue;
const separator = line.indexOf(":");
const field = separator >= 0 ? line.slice(0, separator) : line;
const value = separator >= 0 ? line.slice(separator + 1).replace(/^ /, "") : "";
if (field === "event") event = value || "message";
else if (field === "id" && /^\d+$/.test(value)) id = Number(value);
else if (field === "data") data.push(value);
}
if (!data.length) return;
const raw = data.join("\n");
let parsed: unknown;
try {
parsed = JSON.parse(raw);
} catch {
throw new Error("任务文本流返回了无效数据");
}
onEvent({ event, ...(id !== undefined ? { id } : {}), data: parsed });
}