import { useEffect, useState } from "react"; import { invoke } from "@tauri-apps/api/core"; import { listen } from "@tauri-apps/api/event"; import { Crosshair, Power } from "lucide-react"; import NodeSphere from "../components/NodeSphere"; import Terminal from "../components/Terminal"; import { openWindow } from "../utils/navigation"; const engineStatusContent = { idle: { title: "微信引擎未运行", description: "启动后等待并处理本地微信消息。" }, running: { title: "微信引擎运行中", description: "已处理 26 条消息 · 当前队列 0" }, error: { title: "微信引擎运行异常", description: "启动失败,请查看运行日志并检查本地配置。" }, }; const requiredAnnotationTypes = ["contact_list", "chat_content", "input_box", "unread_message"]; const initialChecks = [ { id: "model", label: "大模型连接情况", detail: "配置完整,连接延迟 324ms", status: "waiting", passed: true }, { id: "annotation", label: "微信区域标注情况", detail: "联系人、聊天内容、输入框和发送区域完整", status: "waiting", passed: true }, { id: "window", label: "微信窗口连接情况", detail: "已找到 WeChat 主窗口", status: "waiting", passed: true }, ]; function hasCompleteAnnotation(annotation) { const regionTypes = new Set(annotation?.regions?.map((region) => region.type) || []); return requiredAnnotationTypes.every((regionType) => regionTypes.has(regionType)); } const wait = (duration) => new Promise((resolve) => setTimeout(resolve, duration)); export default function ClonePage() { const [engineStatus, setEngineStatus] = useState("idle"); const [engineBusy, setEngineBusy] = useState(false); const [annotationBusy, setAnnotationBusy] = useState(false); const [annotationComplete, setAnnotationComplete] = useState(false); const [agentLogs, setAgentLogs] = useState([{ level: "info", message: "[12:30:01] 等待启动" }]); const [checkOpen, setCheckOpen] = useState(false); const [checks, setChecks] = useState(initialChecks); const [checkPhase, setCheckPhase] = useState("idle"); const [autoSendPaused, setAutoSendPaused] = useState(false); const engineRunning = engineStatus === "running"; const statusContent = engineStatusContent[engineStatus]; useEffect(() => { if (!window.__TAURI_INTERNALS__) return undefined; let unlisten; let cancelled = false; listen("engine-state-changed", (event) => { const running = event.payload?.enabled === true; setEngineStatus(running ? "running" : "idle"); if (!running) setAutoSendPaused(false); setEngineBusy(false); }).then((cleanup) => { if (cancelled) cleanup(); else unlisten = cleanup; }); return () => { cancelled = true; if (unlisten) unlisten(); }; }, []); useEffect(() => { if (!window.__TAURI_INTERNALS__) return undefined; let unlisten; let cancelled = false; async function observeAnnotationCompletion() { const cleanup = await listen("annotation-completion-changed", (event) => setAnnotationComplete(event.payload === true)); if (cancelled) { cleanup(); return; } unlisten = cleanup; const annotation = await invoke("load_regions").catch(() => null); if (!cancelled) setAnnotationComplete(hasCompleteAnnotation(annotation)); } void observeAnnotationCompletion(); return () => { cancelled = true; if (unlisten) unlisten(); }; }, []); async function toggleAgent() { if (engineBusy) return false; if (!window.__TAURI_INTERNALS__) { setEngineStatus(engineRunning ? "idle" : "running"); setAutoSendPaused(false); setAgentLogs((current) => [...current, { level: "info", message: engineRunning ? "[12:38:30] 引擎已停止" : "[12:38:21] 引擎启动成功" }]); return true; } setEngineBusy(true); try { if (engineRunning) { await invoke("stop_agent"); await invoke("stop_vision_stream"); setEngineStatus("idle"); setAutoSendPaused(false); setAgentLogs((current) => [...current.slice(-300), { level: "warning", message: "引擎已停用,暂未读取 Rust 日志" }]); } else { await invoke("start_vision_stream"); try { await invoke("start_agent"); } catch (error) { await invoke("stop_vision_stream").catch(() => {}); throw new Error(`agent 启动失败:${String(error)}`); } setEngineStatus("running"); setAutoSendPaused(false); setAgentLogs((current) => [...current.slice(-300), { level: "info", message: "引擎已启动,暂未读取 Rust 日志" }]); } return true; } catch (error) { setEngineStatus("error"); setAgentLogs((current) => [...current, { level: "error", message: String(error) }]); return false; } finally { setEngineBusy(false); } } function toggleAutoSend() { setAutoSendPaused((paused) => { const nextPaused = !paused; setAgentLogs((current) => [ ...current.slice(-300), { level: nextPaused ? "warning" : "info", message: nextPaused ? "已暂停自动发送" : "已恢复自动发送", }, ]); return nextPaused; }); } function requestToggle() { if (engineRunning) { void toggleAgent(); return; } setChecks(initialChecks); setCheckPhase("idle"); setCheckOpen(true); setTimeout(runStartupChecks, 220); } async function runStartupChecks() { setCheckPhase("checking"); setChecks(initialChecks); for (let index = 0; index < initialChecks.length; index += 1) { setChecks((items) => items.map((item, itemIndex) => ({ ...item, status: itemIndex === index ? "checking" : itemIndex < index ? "passed" : "waiting" }))); await wait(950); const check = initialChecks[index]; if (!check.passed) { setChecks((items) => items.map((item, itemIndex) => ({ ...item, status: itemIndex === index ? "failed" : item.status }))); setCheckPhase("failed"); await wait(1600); setCheckOpen(false); return; } setChecks((items) => items.map((item, itemIndex) => ({ ...item, status: itemIndex === index ? "passed" : item.status }))); } setCheckPhase("starting"); const started = await toggleAgent(); if (started) { setCheckPhase("passed"); await wait(900); setCheckOpen(false); } else { setCheckPhase("failed-start"); await wait(1600); setCheckOpen(false); } } async function startAnnotation() { if (annotationBusy) return; if (!window.__TAURI_INTERNALS__) { setAgentLogs((current) => [...current.slice(-300), { level: "warning", message: "窗口选择标注请在 Tauri Windows 应用中使用" }]); return; } setAnnotationBusy(true); try { await invoke("enter_window_select_mode"); setAgentLogs((current) => [...current.slice(-300), { level: "info", message: "已进入窗口选择模式,请点击需要标注的窗口" }]); } catch (error) { setAgentLogs((current) => [...current.slice(-300), { level: "error", message: String(error) }]); } finally { setAnnotationBusy(false); } } return (

{statusContent.title}

{statusContent.description}

{engineRunning ? (
) : annotationComplete ? ( ) : ( )}
openWindow("/window/engine-logs")} onClear={() => setAgentLogs([])} /> {checkOpen ? : null}
); } function StartupCheckModal({ checks, phase }) { const visibleChecks = checks.filter((item) => item.status !== "waiting"); const progress = phase === "starting" || phase === "passed" ? 100 : Math.round((visibleChecks.length / checks.length) * 100); return (

正在检测引擎启动环境

{visibleChecks.map((item) => (
{item.label}
))}
{phase === "starting" ?

全部检查成功,正在启动引擎...

: null} {phase === "failed" || phase === "failed-start" ?

检查失败,启动流程已终止。

: null}
); }