fix(runtime): 运行恢复整合 - 合并 PR #253 本地任务恢复改动

This commit is contained in:
ddCat
2026-08-18 20:27:06 +08:00
13 changed files with 736 additions and 67 deletions

View File

@@ -10,7 +10,18 @@ import { createClientId } from "@/lib/client-id";
import { getLocalRuntimeSessionClient, useLocalRuntimeStore } from "@/stores/use-local-runtime-store";
import { useThemeStore } from "@/stores/use-theme-store";
import { useUserStore } from "@/stores/use-user-store";
import { useCanvasAgentStore, type AgentAttachment, type AgentChatItem, type AgentEventLog, type AgentPanelTab, type AgentPendingToolCall, type AgentThreadSummary } from "@/stores/canvas/use-canvas-agent-store";
import {
canvasAgentConnectionStatusText,
canvasAgentConnectionStartingPatch,
canvasAgentTransientDisconnectPatch,
useCanvasAgentStore,
type AgentAttachment,
type AgentChatItem,
type AgentEventLog,
type AgentPanelTab,
type AgentPendingToolCall,
type AgentThreadSummary,
} from "@/stores/canvas/use-canvas-agent-store";
import { previewCanvasAgentOps, summarizeCanvasAgentOps, type CanvasAgentOp, type CanvasAgentSnapshot } from "@/lib/canvas/canvas-agent-ops";
import { isProjectAgentReadTool, isProjectAgentToolName, runProjectAgentTool } from "@/services/api/project-agent-tools";
import { AgentChatComposer, AgentChatMessage, AgentPanelTabs, AgentPendingToolCard, AgentWorkingMessage, type CanvasAgentChatAttachment } from "./canvas-agent-chat-ui";
@@ -236,7 +247,7 @@ export const CanvasLocalAgentPanel = memo(function CanvasLocalAgentPanel({
}
errorLoggedRef.current = true;
connectedRef.current = false;
clearAgentSession({ activity: wasConnected ? "正在重连" : "连接失败", connected: false, connectError: text });
setAgentState(canvasAgentTransientDisconnectPatch(wasConnected ? "正在重连" : "连接失败", text));
await waitForCanvasRuntimeReconnect(controller.signal);
}
}
@@ -402,28 +413,15 @@ export const CanvasLocalAgentPanel = memo(function CanvasLocalAgentPanel({
if (connected) syncState(clientIdRef.current, restored);
};
const toggleAgentConnection = async () => {
const toggleAgentConnection = () => {
if (enabled) {
connectionControllerRef.current?.abort();
clearAgentSession({ enabled: false, connected: false, activity: "离线", connectError: "" });
pendingToolRef.current = null;
setAgentState({ enabled: false, connected: false, activity: "离线", connectError: "", waiting: false, sending: false, pendingTool: null });
return;
}
const controller = new AbortController();
connectionControllerRef.current = controller;
setAgentState({ connected: false, activity: "连接中", connectError: "", activeTab: "setup" });
try {
await prepareCanvasRuntimeConnection(useLocalRuntimeStore, controller.signal);
if (controller.signal.aborted) return;
errorLoggedRef.current = false;
setAgentState({ enabled: true, connected: false, activity: "连接中", connectError: "", activeTab: "setup" });
} catch (error) {
if (controller.signal.aborted) return;
const text = error instanceof Error ? error.message : "本机 Runtime 连接失败";
setAgentState({ connectError: text });
if (!headless) message.warning(text);
} finally {
if (connectionControllerRef.current === controller) connectionControllerRef.current = null;
}
errorLoggedRef.current = false;
setAgentState(canvasAgentConnectionStartingPatch());
};
useEffect(() => {
@@ -432,21 +430,6 @@ export const CanvasLocalAgentPanel = memo(function CanvasLocalAgentPanel({
void toggleAgentConnection();
}, [autoConnect, connected, enabled]);
function clearAgentSession(patch: Parameters<typeof setAgentState>[0] = {}) {
setAgentState({
messages: [],
threads: [],
activeThreadId: "",
workspacePath: "",
loadingThreads: false,
waiting: false,
sending: false,
pendingTool: null,
...patch,
});
pendingToolRef.current = null;
}
const startNewThread = async () => {
const projectId = snapshotRef.current.projectId;
if (!connected || !projectId) return;
@@ -786,8 +769,8 @@ function AgentConnectView({
connectError: string;
onToggleEnabled: () => void;
}) {
const statusText = connectError ? "连接失败" : connected ? activity : enabled ? "连接中" : "未连接";
const statusColor = connectError ? "#dc2626" : connected ? "#16a34a" : enabled ? "#d97706" : theme.node.muted;
const statusText = canvasAgentConnectionStatusText({ enabled, connected, activity, connectError });
const statusColor = statusText === "连接失败" ? "#dc2626" : connected ? "#16a34a" : enabled ? "#d97706" : theme.node.muted;
return (
<div className="thin-scrollbar min-h-0 flex-1 overflow-y-auto p-4">
<div className="space-y-4">