From 0a645b72126bd832c39dd4f161fe36c87cfd736f Mon Sep 17 00:00:00 2001 From: Aska Date: Mon, 7 Sep 2026 18:44:58 +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=9D=A2=E6=9D=BF=E5=B9=B6=E5=85=A5=E5=B7=B2=E5=AD=98?= =?UTF-8?q?=E8=AE=B0=E5=BD=95=E2=80=94=E2=80=94=E4=B8=8D=E5=86=8D=E5=8F=AA?= =?UTF-8?q?=E8=AF=BBWS=E5=AE=9E=E6=97=B6=E4=BA=8B=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 后台思考页此前只读 /ws/chat 的 backthink/thinking WS 实时事件(后台任务完成才有),DB里 270 条 backthink_records 看不到。新增 adminBackthink() 拉 GET /api/v1/admin/backthink + useAutoReload(10s),与 WS 事件按 id 去重、按 at 倒序展示;空态/数据源说明更新。 验收: npm run build 99模块全绿 --- frontend/web/src/admin/modules/Backthink.tsx | 25 ++++++++++++++------ frontend/web/src/lib/api.ts | 6 +++++ 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/frontend/web/src/admin/modules/Backthink.tsx b/frontend/web/src/admin/modules/Backthink.tsx index 523e3bc..1ca4187 100644 --- a/frontend/web/src/admin/modules/Backthink.tsx +++ b/frontend/web/src/admin/modules/Backthink.tsx @@ -6,6 +6,9 @@ import { Button, EmptyState, Surface, Tag } from "../../components/primitives"; import type { BackthinkItem } from "../../lib/types"; 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); @@ -54,12 +57,20 @@ export function BackthinkModule(): React.ReactNode { const log = useAuditStore((s) => s.log); const [filter, setFilter] = useState<"all" | "notify" | "silent">("all"); const [interveneHint, setInterveneHint] = useState(false); - - const items = backthink.filter((b) => { - if (filter === "notify") return b.shouldNotify === true; - if (filter === "silent") return b.shouldNotify !== true; - return true; - }); + // 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. + 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); + const items = Array.from(byId.values()) + .sort((a, b) => (b.at ?? 0) - (a.at ?? 0)) + .filter((b) => { + if (filter === "notify") return b.shouldNotify === true; + if (filter === "silent") return b.shouldNotify !== true; + return true; + }); return (
@@ -99,7 +110,7 @@ export function BackthinkModule(): React.ReactNode {
)} - 数据源:/ws/chat 下行 backthink / thinking 与 graph_update 事件(实时)。干预为后端 M10+ 提供,当前为只读展示。 + 数据源:GET /api/v1/admin/backthink(已存记录,每 10s 刷新)+ /ws/chat 下行 backthink / thinking 与 graph_update 事件(实时)合并去重。干预为后端 M10+ 提供,当前为只读展示。 ); } diff --git a/frontend/web/src/lib/api.ts b/frontend/web/src/lib/api.ts index b122687..f98c038 100644 --- a/frontend/web/src/lib/api.ts +++ b/frontend/web/src/lib/api.ts @@ -14,6 +14,7 @@ import type { ApiErrorShape, ApiKeyIssueResult, AuditRecord, + BackthinkItem, AutomationCreateResult, AutomationRunResult, ChannelTestResult, @@ -683,3 +684,8 @@ export function adminObservabilityAudit(limit?: number): Promise function limitQuery(limit?: number): string { return limit && limit > 0 ? `?limit=${limit}` : ""; } + +/** GET /api/v1/admin/backthink — persisted background-think records (newest first). */ +export function adminBackthink(limit?: number): Promise { + return request(`/admin/backthink${limitQuery(limit)}`); +}