feat(flow): 链路图本地落盘 + 多轮历史回放(design/19 §P3,契约 v0.73)
主人要求「链路流程应该有本地数据,不然每次重载之后页面就没数据了」: - 落盘:迁移 0022_flow_graphs(session_id/turn_id/graph_json/时间戳 + 唯一键 upsert)+ internal/runtime/flowgraph(RecordRound/Graph/Latest/Turns/Turn + 保留期 GC) - 写入:loop.EndRound **每轮一条**(锁外深拷贝后写;失败 WARN 且不打印图内容);只落发布会话白名单(复用 flowSessionAllowed) - 读回:端点加 turnId + source(live/persisted/none) + turns[](最新在前,空为 []);**内存优先、miss 才落盘**(最新一轮永远最新) - 前端:flowGraphs 纳入 persistOptions.partialize(**刷新即刻有图**,version 3→4 + migrate)+ 历史轮选择器 + 诚实文案;顺带收 L1 转交的 flow/NodeDetail.tsx 节点日志倒序 - 新 env 键:FLOW_GRAPH_RETENTION=168h / FLOW_GRAPH_GC_INTERVAL=1h - 变异实测:每 span 一行 / 保留期守卫失效 / partialize 去掉 flowGraphs / 去掉内存优先 / 白名单失效 ⇒ 全部打红 - 3 个禁动面文件的纯追加改动(Flow.tsx 挂选择器、FlowSnapshotHint 纠已成假话的文案、其渲染断言随之更新)由主会话裁定认可 - 登记存疑:图桶持久化无体积上限;useFlowTurns 的 effect 无自动化证据(项目无 jsdom)
This commit is contained in:
1 parent
84c124f5a9
commit
a6cb44b8a8
38 files changed
+3047
-91
No files matched your search
@@ -47,28 +47,43 @@ export function adminBackthink(limit?: number): Promise<BackthinkItem[]> {
|
||||
return request<BackthinkItem[]>(`/admin/backthink${limitQuery(limit)}`);
|
||||
}
|
||||
|
||||
/** 最近一轮链路图快照的后端响应(契约 v0.71 §4.11(a))。`graph` **恒在**
|
||||
* (`null` 而不是缺席):`null` = 该会话**确实**还没有图,客户端必须据此
|
||||
* 渲染空态,绝不允许补画任何节点或假图。 */
|
||||
export interface AdminFlowGraphResponse {
|
||||
sessionId: string;
|
||||
graph: FlowGraph | null;
|
||||
/** 一条**已落盘轮次**的摘要(契约 v0.73 §4.11 的 `turns[]`)。面板用它渲染历史轮
|
||||
* 选择器:把 `turnId` 回带给 `adminFlowGraph` 即可精确取回那一轮。 */
|
||||
export interface AdminFlowTurn {
|
||||
turnId: string;
|
||||
createdAt: string;
|
||||
}
|
||||
|
||||
/** GET /api/v1/admin/flow/graph?sessionId= — **最近一轮**链路图快照(契约
|
||||
* v0.71 §4.11,只读、不审计,owner/admin 档)。
|
||||
/** 链路图端点的后端响应(契约 v0.71 起;**v0.73 新增 `turnId`/`source`/`turns`**)。
|
||||
*
|
||||
* 为什么需要它:`graph_update` 是**纯实时**帧、从不重放,且前端图桶
|
||||
* (`flowGraphs`)**不持久化** ⇒ 「轮次结束后才打开页面」或「刷新过页面」
|
||||
* 此前只能看到空态。打开页面时拉一次即可补上最近一轮。
|
||||
* `graph` **恒在**(`null` 而不是缺席):`null` = 该轮**确实**没有图,客户端必须据此
|
||||
* 渲染空态,绝不允许补画任何节点或假图。
|
||||
*
|
||||
* ⚠️ 它只回**每会话最近一轮**:后台思考行上点开的图可能不是该行那一轮
|
||||
* (多轮历史回放仍未实现,`design/19 §4` P3)⇒ 面板必须在图上说明。
|
||||
* `source` 告诉客户端这张图是哪来的:`live` = 内存里最近一轮(实时图);`persisted` =
|
||||
* 从本地库读回的历史轮;`none` = 没有图。`turns` 是该会话已落盘的轮次摘要(最新在前),
|
||||
* 没有时为 `[]`(后端保证非 null 数组)。 */
|
||||
export interface AdminFlowGraphResponse {
|
||||
sessionId: string;
|
||||
turnId: string;
|
||||
source: "live" | "persisted" | "none";
|
||||
graph: FlowGraph | null;
|
||||
turns: AdminFlowTurn[];
|
||||
}
|
||||
|
||||
/** GET /api/v1/admin/flow/graph?sessionId=&turnId= — **链路图快照 + 多轮历史回放**(契约
|
||||
* v0.71 起,v0.73 增量;只读、不审计,owner/admin 档)。
|
||||
*
|
||||
* `sessionId` 省略时后端默认主会话 `web`。 */
|
||||
export function adminFlowGraph(sessionId: string): Promise<AdminFlowGraphResponse> {
|
||||
* 为什么需要它:`graph_update` 是**纯实时**帧、从不重放。v0.71 补了「打开页面拉最近一轮
|
||||
* 快照」;v0.73 把图**每轮落盘**,于是可以:
|
||||
* - **省略 `turnId`** ⇒ 最近一轮(后端**先查内存、miss 才落盘** ⇒ 最新一轮永远最新);
|
||||
* - **给了 `turnId`** ⇒ 精确取该会话已落盘的某一轮(历史回放)。
|
||||
*
|
||||
* `turns`(同一响应里)就是给选择器用的历史轮列表。⚠️ 白名单之外的会话(群聊/陌生人)
|
||||
* 从不建图、也从不落盘 ⇒ 它们**永远**是空态,这不是缺陷。 */
|
||||
export function adminFlowGraph(sessionId: string, turnId?: string): Promise<AdminFlowGraphResponse> {
|
||||
const qs = new URLSearchParams();
|
||||
if (sessionId) qs.set("sessionId", sessionId);
|
||||
if (turnId) qs.set("turnId", turnId);
|
||||
const q = qs.toString();
|
||||
return request<AdminFlowGraphResponse>(`/admin/flow/graph${q ? `?${q}` : ""}`);
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user