GPU_GUARD_MONOREPO/docs/code-wiki/concepts/session-tree-runtime.md
2026-05-20 21:39:12 +08:00

6.9 KiB
Raw Blame History

title created updated type tags sources
Session Tree 运行时 2026-04-21 2026-04-26 concept
runtime
agent
backend
database
packages/backend/src/modules/netaclaw/session-tree/provider.ts
packages/backend/src/modules/netaclaw/session-tree/types.ts
packages/backend/src/modules/netaclaw/session-tree/snapshot.ts
packages/backend/src/modules/netaclaw/session-tree/context_builder.ts
packages/backend/src/modules/netaclaw/session-tree/mysql_provider.ts
packages/backend/src/modules/netaclaw/session-tree/file_provider.ts
packages/backend/src/modules/netaclaw/gateway/session.ts
packages/frontend/src/modules/agent/store/chat.ts

Session Tree 运行时

Session Tree 是 NetaClaw 新 Agent runtime 的会话状态模型。它把对话从线性消息列表升级为“节点树 + 当前叶子 + 活动路径 + 运行时上下文”的结构,使刷新恢复、分支、压缩、子 Agent 批次、标签、模型切换都能进入同一套持久化和投影机制。

它是 agent-runtimecontext-compactionsubagent-sessionfrontend-architecture 的共同底座。

Provider 抽象

SessionTreeProvider 定义统一接口,当前有 file 和 mysql 两种 provider。

主要能力包括:

  • createSession
  • getSession
  • updateSession
  • deleteSession
  • listEntries
  • appendEntry
  • appendMessage
  • appendThinkingLevelChange
  • appendModelChange
  • appendCompaction
  • appendBranchSummary
  • appendLabelChange
  • appendSessionInfo
  • updateEntry
  • switchLeaf
  • resetLeaf
  • createBranchedSession
  • getActivePath
  • getSnapshot

这层抽象让运行时不直接绑定 MySQL 或本地文件,也为未来多 workspace、本地优先存储、导入导出保留空间。

Snapshot 结构

SessionTreeSnapshot 是前后端对齐的核心投影:

字段 含义
session 会话元信息,包括 provider、rootEntryId、leafEntryId、cwd、agentId 等
entries 当前会话所有树节点
activePath 从 root 到 leaf 的当前上下文路径
childrenByParentId 前端重建树结构所需的父子索引
labelsByEntryId 节点标签状态
runtimeContext 供模型调用使用的消息、thinking level、模型引用

前端刷新恢复应优先加载 snapshot而不是依赖 localStorage 保存完整聊天记录。

Entry 类型

当前树节点类型包括:

类型 用途
message system/user/assistant/tool 模型消息
thinking_level_change 会话内 thinking level 切换
model_change 会话内模型切换
compaction 压缩摘要节点,详见 context-compaction
branch_summary 分支摘要
custom 不直接展示的自定义数据
custom_message 可展示的自定义消息
label 对目标节点设置或清除标签
session_info 会话信息变更
subagent_batch 子 Agent 批次节点,详见 subagent-session
subagent_result 子 Agent 批次结果节点

Active Path 与上下文构建

模型上下文不再等于“所有历史消息”。运行时会从当前 leafEntryId 回溯得到 activePath,再由 context_builder.ts 转成 runtimeContext.messages

这带来几个结果:

  • 分支切换只需要切换 leaf。
  • 压缩摘要可以替代被压缩的历史段。
  • 子 Agent、分支摘要、custom message 可以参与展示,但不一定进入模型上下文。
  • thinking/model 变更可以沿路径生效。

持久化位置

Session Tree 支持两类持久化:

  • MySQL provider适合生产和多端共享。
  • File provider适合本地优先、单机 workspace、调试和导入导出。

浏览器 localStorage 只保存最近 session/agent 之类的轻量指针,不是对话历史主存储。

删除语义

Session Tree 删除必须按会话实际所属的 provider 执行:

  • 前端 chat.ts 删除请求优先携带会话列表中该 session 的 agentId
  • 后端 gateway/session.ts 在删除前先从 netaclaw_agent_session 反查 sessionId 所属 agentId,再解析该 Agent 的 session backend。
  • MySQL provider 删除 netaclaw_agent_session_entrynetaclaw_agent_sessionfile provider 删除对应 JSONL 文件。
  • 随后后端再清理 legacy session/message、subagent_session 和 session-tree 兼容表记录。

这避免了 MySQL 会话在当前选中 Agent 不一致、或前端缺少 agentId 时走默认 file provider导致“点击删除没有效果”。

前端消费

packages/frontend/src/modules/agent/store/chat.ts 负责消费 snapshot

  • sessionMeta 保存会话元信息。
  • entriesentryById 保存节点。
  • childrenByParentId 支持树结构恢复。
  • activePathIds 控制当前可见路径。
  • visibleEntries 将树节点投影成对话 UI。
  • subagentRuntimeByBatchIdtoolRuntimeRoutesByBatchId 记录子 Agent 工具路由展示数据。

对话页滚动、刷新恢复、历史批次展示都应该围绕这些状态实现。

相关页面

2026-04-22 Subagent Result Metadata

subagent_result carries durable metadata needed to replay subagent execution after refresh.

  • metadata.processEvents: normalized worker event timeline for UI replay.
  • metadata.evidenceSummaries: structured evidence projection built from subagent tool results.
  • metadata.toolRuntimeRoutes: tool routing diagnostics for the delegated batch.

The frontend store should project these fields into dedicated maps keyed by entry id, rather than letting view components parse raw metadata directly.

2026-04-23 Continue-From-Entry And Projection Contract

Session Tree 现在不仅负责“存什么”,还决定“从哪里继续对话”:

  • 前端 chat.ts 维护 selectedEntryIdswitchingLeafEntryIdpendingLeafConfirmation,允许用户选中任意节点后继续发送,而不是只能沿当前 leaf 末尾追加。
  • 如果选中的是普通 user 节点,继续发送会基于它的父节点重放该条 user message形成新的分支。
  • 如果选中的是 branch_summarycompaction 或非当前 leaf 节点,前端会先切换 leaf再沿该路径继续。
  • 这些交互都以 session.leafEntryIdactivePath 和 snapshot 中的树结构为依据,不依赖前端自行缓存一份线性历史。

对子 Agent 相关节点,当前 snapshot 契约也更明确:

  • subagent_result.metadata.subagentProjection 是会话树边界输出的 canonical projection。
  • projection 内的 diagnostics.selectedSourceinputSourcesfallbackUsed 用来说明当前展示究竟来自 subagent_result、旧 tool message还是历史 metadata fallback。
  • 这让 Session Tree 不再只是原始数据容器,而是把“兼容历史记录”和“为当前 UI 供给稳定形态”一起纳入运行时模型。