From 9e7b4ebaaccb718b99badf5d260ab8d1f2b50e34 Mon Sep 17 00:00:00 2001 From: Aska Date: Mon, 7 Sep 2026 18:46:04 +0800 Subject: [PATCH] =?UTF-8?q?feat(backthink):=20=E5=90=8E=E5=8F=B0=E6=80=9D?= =?UTF-8?q?=E8=80=83=E9=A1=B5=E5=85=A8=20WS=20=E5=AE=9E=E6=97=B6=E9=A9=B1?= =?UTF-8?q?=E5=8A=A8=E2=80=94=E2=80=94=E5=8E=BB=E6=8E=89=E8=BD=AE=E8=AF=A2?= =?UTF-8?q?=E6=95=B4=E9=A1=B5=E9=87=8D=E6=B8=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 后端每次思考落库发 ws.backthink → useAppStore.backthink head-insert。页面临近打开时 冷拉一次历史(adminBackthink),此后靠 WS 事件增量更新;去掉 useAutoReload(10s)轮询替换 数组(会整页重渲)。行 key=id → React 只插入新记录、不动已有行。build 99模块绿。 --- frontend/web/src/admin/modules/Backthink.tsx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/frontend/web/src/admin/modules/Backthink.tsx b/frontend/web/src/admin/modules/Backthink.tsx index 1ca4187..17c70af 100644 --- a/frontend/web/src/admin/modules/Backthink.tsx +++ b/frontend/web/src/admin/modules/Backthink.tsx @@ -8,7 +8,6 @@ import { Icon } from "../../components/Icon"; import { FlowGraphView } from "./FlowGraph"; import { adminBackthink } from "../../lib/api"; import { useAsyncData } from "../../lib/useAsyncData"; -import { useAutoReload } from "../hooks"; function BackthinkRow({ item }: { item: BackthinkItem }): React.ReactNode { const markPushed = useAppStore((s) => s.markBackthinkPushed); @@ -57,10 +56,11 @@ export function BackthinkModule(): React.ReactNode { const log = useAuditStore((s) => s.log); const [filter, setFilter] = useState<"all" | "notify" | "silent">("all"); const [interveneHint, setInterveneHint] = useState(false); - // Persisted records (design/12 §4) + live WS backthink events, deduped by id, - // newest first. The panel previously only showed live WS events and hid history. + // Cold-load persisted history once (design/12 §4); real-time updates come from the + // WS `backthink` events already feeding useAppStore.backthink (head-inserted), so we + // do NOT poll-replace the array (which would re-render the whole list). Rows are keyed + // by id → React reconciles incrementally, appending only NEW records. const rec = useAsyncData(() => adminBackthink(100), []); - useAutoReload(rec.reload, 10000); const byId = new Map(); for (const b of backthink) if (b.id) byId.set(b.id, b); for (const b of rec.data ?? []) if (b.id) byId.set(b.id, b); @@ -110,7 +110,7 @@ export function BackthinkModule(): React.ReactNode { )} - 数据源:GET /api/v1/admin/backthink(已存记录,每 10s 刷新)+ /ws/chat 下行 backthink / thinking 与 graph_update 事件(实时)合并去重。干预为后端 M10+ 提供,当前为只读展示。 + 数据源:/ws/chat 下行 backthink / thinking 事件(实时,主驱动)+ 打开时一次拉取 GET /api/v1/admin/backthink 历史,两者按 id 去重、按时间倒序,新记录增量插入(不整页重渲)。干预为后端 M10+ 提供,当前为只读展示。 ); }