morlay/better-session--packages-better-session ↗★ 0
@morlay/better-session
Example dsh profile bundle: assembles @morlay/session-rdb and @morlay/ui-conversation-message-actions into a web profile — rewind / retry / fork closed loop on RDB persistence.
安装
npx -p @deepseek-ai/dsh dsh plugin --profile web add github:morlay/better-session#8ec5bcec558e8e419ae563d81367c7fb6637bbf3&path:packages/better-session说明文档
阅读完整 README ↗better-session
DeepSeek Harness 的会话持久化与分支式会话编辑 monorepo——多层 cordis plugin,
在不修改上游 @deepseek-ai/* 代码的前提下,为 rewind / retry / fork 提供
完整的持久化闭环。
包结构(三层)
packages/
├── session-branch/ # 契约层 @morlay/session-branch
│ └── SessionBranchProvider 抽象 + SessionBranch 服务 + 版本树投影
├── ui-conversation-message-actions/ # 编排层 + UI @morlay/ui-conversation-message-actions
│ ├── SessionEditor:edit / reroll / retry / rewind / fork / timeline(host)
│ └── client bundle:替换 conversation.chat.node,user 消息行内编辑 / 重试
└── session-rdb/ # 实现层 @morlay/session-rdb(持久化 + 分支双服务)
├── SessionPersistenceRdb(SQLite / PostgreSQL,上游 PersistenceBackend)
└── SessionBranchRdb(SessionBranchProvider 的 rdb 实现,随包自动注册 ctx.sessionBranch)
契约层 @morlay/session-branch
SessionBranchProvider:额外的 provider 抽象(与上游PersistenceBackend平行)——readBranchPrefix(闭合边界定位)、forkFrom(纯 append 派生)、rewind(显式授权截断)。数据层后端实现它;一个后端可同时实现PersistenceBackend与SessionBranchProvider(rdb 即此,形成闭环)。SessionBranch:ctx.sessionBranch抽象服务(rewind / forkFrom / timeline)。buildTimeline:版本树共享投影(parentSession+seedLengthlineage)。
实现层 @morlay/session-rdb
在既有 RDB 持久化之上实现 SessionBranchProvider(故命名为 session-rdb
而非 session-persistence-rdb——它同时实现两个服务):
forkFrom走标准 coordinator 路径(create+append)——纯 append, seed 前缀按新会话 log 保序重编号;rewind是上游没有的原语:直接操作后端事务(DELETE 尾部 + head 回退 + revision bump),随后重新 load 同步 coordinator 状态(revision 变化触发isPreparedSourceCurrent失效 → 重新 adopt),并更新WriteGuard确认 head; 支持 live 会话(内存 log 截断 + 派生缓存复位 + coordinator cursor 同步);- 插件构造时自动发布
ctx.sessionBranch(SessionBranchRdb),形成 session-persistence + session-branch 双服务闭环。
编排层 + UI @morlay/ui-conversation-message-actions
组合 ctx.sessionBranch + ctx.sessionPersistence + ctx.sessions(可选
agents 服务 duck-typed 驱动),提供完整功能(对齐
dsh-message-edit 的产品语义):
edit:编辑已落定文本块并从其轮次边界分支;reroll:重生成最后一条已落定助手回复;retry:重试任意历史回合(truncate/preserve级联);rewind:截断式回退(原会话回退到闭合边界);fork:从任意闭合边界派生新会话;timeline:完整版本树投影。
开发
just dep # nub install(pnpm 兼容 workspace)
just lint # oxlint
just test # vitest(全部包)
just build # 各包 prepare(tsdown)
just pg test # PostgreSQL 契约测试(docker compose)
工具链(tsdown / typescript / vitest / oxlint / @deepseek-ai/dsh)在根,包只声明 自身运行时依赖。
本地 web 启动(better-session 聚合)
just dev # build + setup-dsh + 启动 web:dsh --profile web(DSH_HOME=.dsh-store)
packages/better-session 是 profile 聚合 bundle:dsh.profile.bundles 声明
官方 web-app + 本仓库插件的聚合,其 cordis.patch.yml disable 官方 JSONL
持久化(rdb 作为唯一 ctx.sessionPersistence)。setup-dsh 的 add 顺序
保证聚合层先于 rdb 收编。
设计要点
- 不改上游代码:
rewind / retry / fork全部在插件层实现。 - 就地编辑:edit / retry / reroll 用
rewind截断 +append重写同一 会话(session id 不变、版本树单根);只有fork创建新 id。 rewind支持 live 会话:GUI 打开中的会话(agent 驻留)也能就地编辑—— 截断 RDB 的同时截断 live 内存 log(复位派生缓存)、同步 coordinator cursor、重置 agent 请求头标记,不要求 cold owner。ignorable语义尊重:分支版本效果(session-branch/version)是 seed/内存事件(live log 可见),因携带ignorable: true不进 canonical log——core / 非 branch 后端读它安全跳过;cold 会话的 timeline 退化为 lineage 骨架(无效果详情)。- 浏览器半:
conversation.chat.node全 key shadow 替换(priority -1), user 消息行内挂编辑 / 重试(编辑弹窗复用 dsh Modal + composer-card 视觉, 重试带确认);client bundle 单文件约束(见packages/ui-conversation-message-actionsREADME)。