fix(chat): guard abort and early idle races

This commit is contained in:
2026-06-07 20:22:05 +08:00
parent 2295bdcb97
commit 6f3b72628f
2 changed files with 30 additions and 2 deletions
+23 -1
View File
@@ -323,6 +323,7 @@ export const streamPromptResponse = async ({
let firstToolEventLogged = false;
let lastSessionStatus: string | null = null;
let lastSessionStatusMessage: string | null = null;
let sawResponseActivity = false;
let emittedText = false;
let toolCallCount = 0;
let done = false;
@@ -529,6 +530,7 @@ export const streamPromptResponse = async ({
}
if (isSkillEvent(event)) {
sawResponseActivity = true;
const { name, reason, payload } = extractSkillAuditInfo(event);
logDevelopmentDebug("skill event received", {
...debugContext,
@@ -552,7 +554,15 @@ export const streamPromptResponse = async ({
});
}
if (event.type === "message.updated") {
if (event.properties.info.role === "assistant") {
sawResponseActivity = true;
}
continue;
}
if (event.type === "message.part.delta" && event.properties.field === "text") {
sawResponseActivity = true;
const partType = partTypes.get(event.properties.partID);
if (partType === "text") {
if (!firstTokenLogged) {
@@ -591,6 +601,7 @@ export const streamPromptResponse = async ({
}
if (event.type === "message.part.updated") {
sawResponseActivity = true;
const part = event.properties.part;
partTypes.set(part.id, part.type);
if (part.type === "text") {
@@ -720,6 +731,7 @@ export const streamPromptResponse = async ({
}
if (event.type === "todo.updated") {
sawResponseActivity = true;
const completed = event.properties.todos.filter(
(todo) => todo.status === "completed",
).length;
@@ -736,6 +748,7 @@ export const streamPromptResponse = async ({
}
if (event.type === "session.error") {
sawResponseActivity = true;
logDevelopmentDebug("session error received", {
...debugContext,
elapsedMs: Math.max(0, Date.now() - requestStartedAt),
@@ -757,6 +770,13 @@ export const streamPromptResponse = async ({
}
if (event.type === "session.idle") {
if (!sawResponseActivity) {
logDevelopmentDebug("ignoring session idle before response activity", {
...debugContext,
elapsedMs: Math.max(0, Date.now() - requestStartedAt),
});
continue;
}
logDevelopmentDebug("session idle received", {
...debugContext,
emittedText,
@@ -832,8 +852,10 @@ export const streamPromptResponse = async ({
return { aborted: false, failed: false, toolCallCount };
} finally {
await iterator.return?.(undefined);
if (!promptSettled) {
if (!promptSettled && !aborted) {
await promptPromise.catch(() => undefined);
} else if (!promptSettled) {
void promptPromise.catch(() => undefined);
}
logDevelopmentDebug("chat stream cleanup finished", {
...debugContext,