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)}`); +}