fix(chat): heal task bubble pending after completed run

This commit is contained in:
weichen
2026-09-26 04:30:38 +00:00
parent a5ca6fdcfd
commit ccce44dfc0
37 changed files with 1164 additions and 202 deletions
+12 -1
View File
@@ -108,6 +108,7 @@ export async function readTaskRunSSEOnce(
/**
* 订阅任务 SSE:意外 EOF / 不完整 chunked 时按最后 seq 重订阅同一 run,禁止调用方据此 POST 新 run。
* 重连前可经 onGap 轮询 run 终态:若已 completed 等则停止订阅(避免 done 丢失后永久 pending)。
*/
export async function subscribeTaskRunEvents(
runId: string,
@@ -117,6 +118,8 @@ export async function subscribeTaskRunEvents(
maxReconnects?: number;
reconnectDelayMs?: number;
sleep?: (ms: number) => Promise<void>;
/** Return true to stop reconnecting (caller already settled from GET /runs). */
onGap?: (ctx: { afterSeq: number; attempt: number }) => Promise<boolean>;
},
signal?: AbortSignal,
): Promise<void> {
@@ -131,12 +134,20 @@ export async function subscribeTaskRunEvents(
const { terminal, lastSeq } = await readTaskRunSSEOnce(runId, afterSeq, handlers.onEvent, signal);
afterSeq = Math.max(afterSeq, lastSeq);
if (terminal) return;
// 意外 EOF:未见到 done/error,按 after_seq 重连
// 意外 EOF:未见到 done/error — 先问 onGap,再按 after_seq 重连
if (handlers.onGap) {
const stop = await handlers.onGap({ afterSeq, attempt });
if (stop) return;
}
} catch (err) {
if (signal?.aborted) return;
if (err instanceof TaskRunHttpError && isNonRetryableStatus(err.status)) {
throw err;
}
if (handlers.onGap) {
const stop = await handlers.onGap({ afterSeq, attempt }).catch(() => false);
if (stop) return;
}
if (attempt >= maxReconnects) throw err;
}
if (attempt >= maxReconnects) {