fix: 修复点击退出按钮没有中断的问题;兼容了工具调用中断后过滤一遍message;
This commit is contained in:
parent
e4c31b3b1e
commit
b97e96d29e
|
|
@ -504,10 +504,15 @@ export default function ChatPage() {
|
||||||
<Button
|
<Button
|
||||||
className="w-full bg-[#f9f8fa] hover:bg-[#8E47F0] hover:text-white"
|
className="w-full bg-[#f9f8fa] hover:bg-[#8E47F0] hover:text-white"
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
onClick={() => {
|
onClick={async () => {
|
||||||
|
// 如果正在生成,先终止再退出
|
||||||
|
if (thread.isLoading) {
|
||||||
|
await handleStop();
|
||||||
|
}
|
||||||
setShowExitDialog(false);
|
setShowExitDialog(false);
|
||||||
router.push("/workspace/chats/new");
|
// 使用完整页面刷新确保组件重新挂载,isNewThread 为 true
|
||||||
}}
|
window.location.href = "/workspace/chats/new";
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
确定
|
确定
|
||||||
</Button>
|
</Button>
|
||||||
|
|
|
||||||
|
|
@ -33,9 +33,47 @@ export function groupMessages<T>(
|
||||||
if (messages.length === 0) {
|
if (messages.length === 0) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 预处理:收集所有 ToolMessage 的 tool_call_id
|
||||||
|
const toolMessageIds = new Set<string>();
|
||||||
|
for (const message of messages) {
|
||||||
|
if (message.type === "tool" && message.tool_call_id) {
|
||||||
|
toolMessageIds.add(message.tool_call_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 预处理:检查哪些 tool_calls 没有对应的响应
|
||||||
|
const danglingToolCallIds = new Set<string>();
|
||||||
|
for (const message of messages) {
|
||||||
|
if (message.type === "ai" && message.tool_calls) {
|
||||||
|
for (const tc of message.tool_calls) {
|
||||||
|
const tcId = tc.id;
|
||||||
|
if (tcId && !toolMessageIds.has(tcId)) {
|
||||||
|
danglingToolCallIds.add(tcId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 过滤掉只有悬空 tool_calls 且没有其他内容的 AI 消息
|
||||||
|
const filteredMessages = messages.filter((message) => {
|
||||||
|
if (message.type === "ai" && hasToolCalls(message)) {
|
||||||
|
// 检查是否所有 tool_calls 都是悬空的
|
||||||
|
const allDangling = message.tool_calls?.every((tc) =>
|
||||||
|
danglingToolCallIds.has(tc.id!),
|
||||||
|
);
|
||||||
|
// 如果全部悬空且没有其他内容,跳过该消息
|
||||||
|
if (allDangling && !hasReasoning(message) && !hasContent(message)) {
|
||||||
|
console.warn("过滤只有悬空 tool_calls 的 AI 消息:", message.id);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
const groups: MessageGroup[] = [];
|
const groups: MessageGroup[] = [];
|
||||||
|
|
||||||
for (const message of messages) {
|
for (const message of filteredMessages) {
|
||||||
const lastGroup = groups[groups.length - 1];
|
const lastGroup = groups[groups.length - 1];
|
||||||
if (message.type === "human") {
|
if (message.type === "human") {
|
||||||
groups.push({
|
groups.push({
|
||||||
|
|
@ -44,9 +82,9 @@ export function groupMessages<T>(
|
||||||
messages: [message],
|
messages: [message],
|
||||||
});
|
});
|
||||||
} else if (message.type === "tool") {
|
} else if (message.type === "tool") {
|
||||||
// Check if this is a clarification tool message
|
// 检查是否为澄清问题的工具消息
|
||||||
if (isClarificationToolMessage(message)) {
|
if (isClarificationToolMessage(message)) {
|
||||||
// Add to processing group if available (to maintain tool call association)
|
// 如果有可用的处理组,添加到其中(保持工具调用关联)
|
||||||
if (
|
if (
|
||||||
lastGroup &&
|
lastGroup &&
|
||||||
lastGroup.type !== "human" &&
|
lastGroup.type !== "human" &&
|
||||||
|
|
@ -55,7 +93,7 @@ export function groupMessages<T>(
|
||||||
) {
|
) {
|
||||||
lastGroup.messages.push(message);
|
lastGroup.messages.push(message);
|
||||||
}
|
}
|
||||||
// Also create a separate clarification group for prominent display
|
// 同时创建单独的澄清组以便突出显示
|
||||||
groups.push({
|
groups.push({
|
||||||
id: message.id,
|
id: message.id,
|
||||||
type: "assistant:clarification",
|
type: "assistant:clarification",
|
||||||
|
|
@ -69,9 +107,17 @@ export function groupMessages<T>(
|
||||||
) {
|
) {
|
||||||
lastGroup.messages.push(message);
|
lastGroup.messages.push(message);
|
||||||
} else {
|
} else {
|
||||||
throw new Error(
|
// 悬空的工具消息(如生成被中断导致)
|
||||||
"Tool message must be matched with a previous assistant message with tool calls",
|
// 创建独立的处理组以便显示
|
||||||
|
console.warn(
|
||||||
|
"检测到悬空的工具消息,创建独立组:",
|
||||||
|
message.tool_call_id,
|
||||||
);
|
);
|
||||||
|
groups.push({
|
||||||
|
id: message.id,
|
||||||
|
type: "assistant:processing",
|
||||||
|
messages: [message],
|
||||||
|
});
|
||||||
}
|
}
|
||||||
} else if (message.type === "ai") {
|
} else if (message.type === "ai") {
|
||||||
if (hasReasoning(message) || hasToolCalls(message)) {
|
if (hasReasoning(message) || hasToolCalls(message)) {
|
||||||
|
|
@ -100,7 +146,7 @@ export function groupMessages<T>(
|
||||||
currentGroup.messages.push(message);
|
currentGroup.messages.push(message);
|
||||||
} else {
|
} else {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
"Assistant message with reasoning or tool calls must be preceded by a processing group",
|
"带有推理或工具调用的 AI 消息必须位于处理组之后",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue