fix(chat): update question abort state

This commit is contained in:
2026-06-08 18:39:45 +08:00
parent b23cb6acdd
commit 3a36c693cd
3 changed files with 255 additions and 27 deletions
@@ -785,6 +785,29 @@ describe("useAgentChatSession", () => {
],
createdAt: 1001,
} satisfies StreamEvent);
onEvent({
type: "permission_request",
sessionId: "session-1",
requestId: "perm-abort",
permission: "bash",
patterns: ["npm test"],
metadata: { command: "npm test" },
always: ["npm test"],
createdAt: 1002,
} satisfies StreamEvent);
onEvent({
type: "question_request",
sessionId: "session-1",
requestId: "question-abort",
questions: [
{
header: "范围",
question: "请选择范围",
options: [{ label: "城区", description: "中心城区" }],
},
],
createdAt: 1003,
} satisfies StreamEvent);
signal?.addEventListener("abort", () => {
reject(new Error("aborted"));
@@ -842,6 +865,22 @@ describe("useAgentChatSession", () => {
],
}),
],
permissions: [
expect.objectContaining({
requestId: "perm-abort",
status: "rejected",
repliedAt: expect.any(Number),
error: undefined,
}),
],
questions: [
expect.objectContaining({
requestId: "question-abort",
status: "rejected",
repliedAt: expect.any(Number),
error: undefined,
}),
],
}),
);
expect(abortAgentChat).toHaveBeenCalledWith("session-1");
@@ -217,7 +217,7 @@ const getQuestionContentSignature = (
description: option.description,
})),
multiple: question.multiple ?? false,
custom: question.custom ?? false,
custom: question.custom !== false,
})),
);
@@ -366,12 +366,64 @@ const upsertTodoUpdate = (
},
];
const rejectOpenPermissionsAfterAbort = (
permissions: AgentPermissionRequest[] | undefined,
) => {
if (!permissions?.length) return permissions;
let changed = false;
const nextPermissions = permissions.map((permission) => {
if (
permission.status !== "pending" &&
permission.status !== "submitting" &&
permission.status !== "error"
) {
return permission;
}
changed = true;
return {
...permission,
status: "rejected" as const,
repliedAt: Date.now(),
error: undefined,
};
});
return changed ? nextPermissions : permissions;
};
const rejectOpenQuestionsAfterAbort = (
questions: AgentQuestionRequest[] | undefined,
) => {
if (!questions?.length) return questions;
let changed = false;
const nextQuestions = questions.map((question) => {
if (
question.status !== "pending" &&
question.status !== "submitting" &&
question.status !== "error"
) {
return question;
}
changed = true;
return {
...question,
status: "rejected" as const,
repliedAt: Date.now(),
error: undefined,
};
});
return changed ? nextQuestions : questions;
};
const finalizeAssistantMessageAfterAbort = (message: Message): Message => {
const completedProgress = completeRunningProgress(message.progress);
const cancelledTodos = cancelRunningTodos(message.todos);
const rejectedPermissions = rejectOpenPermissionsAfterAbort(message.permissions);
const rejectedQuestions = rejectOpenQuestionsAfterAbort(message.questions);
const hasVisibleOutput =
message.content.trim().length > 0 ||
Boolean(message.artifacts?.length) ||
Boolean(rejectedPermissions?.length) ||
Boolean(rejectedQuestions?.length) ||
Boolean(completedProgress?.length) ||
Boolean(cancelledTodos?.length);
@@ -384,6 +436,8 @@ const finalizeAssistantMessageAfterAbort = (message: Message): Message => {
content: message.content || "⚠️ **请求已中断**",
isError: true,
progress: completedProgress,
permissions: rejectedPermissions,
questions: rejectedQuestions,
todos: cancelledTodos,
};
};