deskpaw-memory/README.md

177 lines
15 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# deskpaw-memory
## 当前:链式记忆与 Computer 增量经历
两阶段对象整理已于 **2026-10-14 00:34 配套部署**:[实现、参数、阅读方法与自查](OBJECT_MEMORY.md)。compact 只缩短时间轴并登记待归档事件;每小时 organize 更新对象档案,允许 archive_only 终态;deep 另做全库审阅。对象 Markdown 目录已生成,存量仍在后台整理,不能视作已全部整理完成。下文旧“三入口、compact 同时写对象”是历史基线,以新文档为准。
2026-10-13 待部署修复位于 `fix/memory-organizer-recovery`:新增分类重试状态、失败历史和自动整理失败通知,允许 Worker 按批次超时设置租约;对象正文上限放宽至 16,000 字符。`memory.organize.notices` 先取待通知作业,以 `{ack: job_id}` 确认;`memory.chain.status` 返回 retry 和最近五次 failures。通知在 Agent 持久接收后才确认,历史自动失败会补通知,但不自动重跑。对应 Agent 输出默认 32,768、截断增长至默认 131,072 token,整批五分钟。完整说明见 [整理恢复](../deskpaw_agent/CHAIN_MEMORY.md#16-2026-10-13-整理失败恢复与输出额度)。下文部署记录为 10 月 12 日基线,不代表本修复已上线。
SQLite 保存原始事件、活动时间轴节点、长期对象图、检索词项、核心文件版本和持久整理队列。Super 主动同步召回;Memory 独占长期记忆语义整理权。无 embedding、无旧索引依赖、无联系人隔离。2026-10-12 21:26 已从原目录重新部署,累计修改整理合入本地 main,未推送远端。
最近 Agent/Memory 所有改动、实际参数、备份、验证与 main 合并记录见相邻 Agent 仓库的 [发布汇总](../deskpaw_agent/AGENT_MEMORY_RELEASE_2026-10-12.md)(本机 `/home/kickpi/deskpaw_agent/AGENT_MEMORY_RELEASE_2026-10-12.md`)。本轮 Memory 47/47、Agent 91/91 回归通过。下文旧分支、旧测试数量和 HTTP 402 是历史记录,不代表当前部署或余额状态。
Computer 现在直接将执行文本增量写入共享时间轴,不等整个任务结束;本机持久队列由 Agent 管理,断线重试。普通事件不唤醒 Super,长期整理仍采用阈值、主动和夜间三类入口。`timeline.query` 新增可选 `task_id` 及对应 SQLite 索引;Computer 可只读使用长期记忆,任务内检查点不是本服务的长期整理。
完整跨仓库说明与自查位于相邻 Agent 仓库的 `CHAIN_MEMORY.md`(本机 `/home/kickpi/deskpaw_agent/CHAIN_MEMORY.md`)。
- `chain-store.js` / `object-organizer.js`:时间轴摘取、持久归档、每小时扫描、夜间对象审阅;分批检查点、失败隔离及轮转。compact 与对象写入是独立事务阶段。
- `object-projection.js` / `inspect.js`:一对象一份 Markdown 档案,以及对象和原始事件的只读查询命令。
- `chain-graph.js`:人物、任务、待办、日程、知识、交叉项目、凭据引用;来源和版本,别名/词项/cues 索引、有限关系展开、分页读取。新项目为候选,需逐字用户证据确认。精简目录常驻 Super,事实按需召回。
- `core-projection.js`:SOUL/USER/AGENTS 三份文件,每份最多 2,400 字符;数据库权威版本与可编辑文件投影,下一轮热加载。凭据真实值禁止存入。
整理模型由 Agent 进程中的独立 `MemoryWorker` 调用,不是 Super 会话,也不是 Computer Pi。默认沿用 Super 模型;可分别配置 `DESKPAW_MEMORY_MODEL_PROVIDER/MODEL/BASE_URL/API_KEY`,日期使用 `DESKPAW_MEMORY_TIMEZONE`(默认 Asia/Shanghai)。本服务负责读取、校验和提交,不直接调用模型。
新增 JSON-line 方法:
| 方法 | 用途 |
|---|---|
| `memory.chain.context` | max_tokens 估算 token 预算与独立 max_bytes 传输限额;返回最近节点、truncated/omitted_nodes。仅同步未就绪返回 ready=false |
| `memory.chain.find/read/node` | 对象目录检索、详情与关系、原始证据按范围展开 |
| `memory.chain.browse` | after/limit 按稳定 ID 分页浏览全库,包括归档对象;供 Memory 全局整理使用 |
| `memory.chain.tick/status` | 触发检查、整理状态和容量/投影诊断 |
| `memory.chain.core.bootstrap/update` | 首次核心导入、受信管理端按 expected_revision 更新 |
| `memory.chain.project_decision` | 当前用户证据确认/放弃候选项目 |
| `memory.organize.request/claim/inspect/commit/fail` | 持久请求、领取有限批次、补读旧记忆、原子发布、失败退避 |
时间轴替换与归档入队同事务,对象写入与事件处置另用独立事务;两者均有幂等回执、版本与租约校验。原文、审计和版本不会因摘要缩短而删除,仍需磁盘监控和备份。未实现自动回收、会议采集、任意同义检索保证或密钥库全量元数据同步。Memory 故障保留待同步内容,不阻止 Agent 接收任务。
`token-budget.js` 与 Agent 使用同一 portable-v1 文本 token 估算规则,未引入模型专属 tokenizer。`tick.threshold_tokens` 和 `stats.estimated_tokens` 使用 token 单位,`stats.bytes` 仅为存储/传输诊断,二者不能相加。Super 超限时截断输入视图并向模型明确说明,原始记忆不删除,语义整理仍由 Memory 完成。`status.jobs[].object_review` 表示深度任务的对象总量和已成功提交的审阅量,不证明模型语义判断必然正确。
测试:`npm test`,使用隔离数据库、临时核心文件和 socket;包括原子回滚、重启租约、夜间安静窗口、大事件跨批不丢尾部、项目确认、中文召回、敏感值拒绝及投影热更新。真实模型语义质量、长稳与断电需另外验收。
2026-10-12:部署前本仓库 42 项测试全部通过,相邻 Agent 10 组定向测试 76 项通过。部署实测后新增失败缩批回归,本仓库 **43 项**全部通过;Agent 完整链路补测输出截断重试和同轮多查询。服务已重启,未推送仓库。compact 初始最多八个节点、deep 最多十二个,失败重试会进一步缩小,不丢弃未处理片段。
后续修改加入 token 口径、显式截断和全库深度审阅,**46 项隔离测试全部通过**,现已按用户要求切换到线上进程。服务健康不等于真实模型验收通过;本次接口返回余额不足,详情见 Agent 的部署记录。
## 原始时间轴协议(仍为当前链式记忆的数据底座)
`feat/super-agent-v2` 新增独立经历时间轴,使用 `timeline` 与 `timeline_terms` 表,不查询下文的旧任务/话题索引,不使用 embedding。Super v2 不再启动下层夜间旧记忆整理;以下原有接口保留供旧调用方和数据审计使用。
JSON-line 接口为 `timeline.append/query/read/expand`。append 包含稳定 `id`、`kind`、毫秒时间 `at`(省略时使用进入时间)和不超过 32,000 字符的 `text`,`source` 仅接收来源/任务/文件引用白名单字段。敏感文本经过过滤,重复 ID 不覆盖原始记录。长工具结果保留在 Agent 作业表,时间轴只保存有限摘要和引用。
query 支持 `query/from/to/after/limit/task_id`:中英文词项倒排检索、时间范围、可选任务过滤、最多 50 个索引头,每头最多 1,200 字符;命中数和时间排序。无查询词时按 seq 正序分页。read/expand 接受 `id/offset/limit` 返回原文范围与 next_offset。没有用户分区。
原始行保持不可变,压缩与子节点关系使用新的 `memory_nodes`,不改写原文。旧 `parent_id/covered_from/covered_to` 字段不承担当前链式节点发布。Agent 的持久待同步表支持离线补写。
服务启动会检查已有 socket 所有者,不删除活跃实例的 socket;单请求连接限制 1 MB、5 秒和最多 64 并发连接。测试执行 `npm test`,新增时间轴存储、敏感过滤和真实 Unix socket 的隔离测试,不操作生产状态。
## 以下为 v1 存量机制
DeskPaw 的本地记忆与上下文整理模块。它作为 `deskpaw-agent` 的平级服务运行,通过本地 socket 提供:
- 任务卡和执行结果的持久化;
- 新旧任务关联度提示;
- 日程附属资料夹;
- 每轮执行前的有限上下文包;
- 按 03:30 工作日组织的话题经历、长期事实和技能草稿;
- 主动整理记录与可观测事件。
- 版本化事件接入、可恢复观察批次、带证据的经历与中文倒排索引。
模块不保存隐藏思考,不接管日程执行,不直接操作电脑或发送消息。Agent 不依赖本服务才能运行;服务离线时自动降级。
`deploy/deskpaw-memory.service` 是当前 KickPi 部署模板。`bin/run-memory` 会读取设备配置中的 `DESKPAW_NODE_BIN`,避免 systemd 找不到 NVM 安装的 Node。服务应先于 Agent 启动;它故障重启时不会要求 Agent 一起重启。
## 启动
Linux 默认 socket 为 `~/.deskpaw/runtime/memory.sock`:
```bash
npm start
```
正式状态统一保存在 `~/.deskpaw/memory/`:SQLite 数据库位于
`data/memory.sqlite3`,日程和项目资料位于 `bundles/`。旧版 Python
记忆服务的数据应迁到 `~/.deskpaw/memory-legacy/`,不要与本模块共用数据库。
可配置:
```text
DESKPAW_STATE_DIR=/path/to/state
DESKPAW_MEMORY_SOCKET=/path/to/memory.sock
DESKPAW_MEMORY_DB=/path/to/memory.sqlite
DESKPAW_MEMORY_BUNDLES=/path/to/bundles
```
协议为单请求连接的 JSON Lines。请求包含 `id、method、params`,响应包含 `id、ok、result/error`。
接口:`health`、`memory.recall`、`interaction.remember`、`transition.assess`、`context.prepare`、`task.complete`、`task.list`、`consolidation.record`、`memory.maintenance.status/plan/commit`、`memory.topic.get`、`memory.skill.list/get/set_status`、`bundle.get/list/document.put`。修改资料使用 `expected_revision`,防止猫窝和桌喵同时编辑时旧内容覆盖新内容。
## 顶层记忆
DeskPaw 使用一个 Session。`feat/supervisor-memory-v1` 将问答和任务结果同步移至持久事件驱动的后台队列,
上层不再先等写入完成。每次召回有持久请求 ID,本地检索最多占用上层 75 毫秒的等待预算;
未完成返回 `pending`,后台继续,不能解释为查无记忆。完成结果缓存并进入上层只读收件箱。
核心画像保留小型缓存;实时任务状态始终从 Runtime 读取。
Memory 返回相关问答、任务卡、资料包和新经历,供顶层回答历史问题。
来源仅作为 `source` 元数据保存,不作为检索过滤条件。同步按 `interaction_id` 幂等写入,
并经 `safeMemoryText` 过滤敏感文本;不要在记忆资料中放入凭据或隐藏推理。
`memory.recall` 请求示例:
```json
{"id":"request-1","method":"memory.recall","params":{"query":"之前 UFO 检查怎么样了","limit":8}}
```
结果保留旧的任务卡、问答和资料包字段,并新增 `recent_workdays`、`related_topics`、
`core_facts`、`related_facts` 和 `relevant_skills`。话题按标题和概括召回,长期事实按范围和内容匹配;
上层会裁剪候选数量,详细经历通过 `memory.topic.get` 按话题 ID 分页读取。
旧任务卡检索仍只扫描最近 100 张、逐条问答检索仍只扫描最近 200 条;
话题检索目前扫描全部话题并排序,尚未建立全文索引;数据量显著增长后应换成索引召回。
`transition.assess` 只提示任务切换,
不决定经历是否合并。
## 话题与整理
记忆中的 `topic_id` 是话题单元,既可表示执行任务,也可表示闲聊和讨论;它与 Agent 执行队列的
`task_id` 不同。一个话题可跨工作日继续。工作日固定为北京时间 03:30 至次日 03:29:59,
与实际压缩作业是否延期无关。SQLite 中的 `topic_interactions` 只建立关联,不改写原始交互;
`topic_segments` 保存每日极简概括。旧接口仍返回最近三个有话题片段的工作日;
新上层不再固定注入三天全部概览,按问题相关性选择内容,旧话题仍可检索。
原始执行日志仍由 Agent 运行时 SQLite 保存;Agent 按话题读取详情时,利用关联的执行任务 ID
补充有限的执行日志,不在 Memory 中复制无界工具输出。
后台 Worker 在空闲时分批调用 `memory.maintenance.plan`,使用记忆角色模型归类话题、概括结果与问题,
然后用 `memory.maintenance.commit` 原子写入。每条交互必须恰好分配一次;重启中断不会删除原始记录。
一小时无用户或执行活动后会整理未归档交互;跨过 03:30 时,在下层空闲后复核前一工作日。
自动整理不再占用 Pi 的执行队列,也不清空正在运行的 Pi 上下文。
旧的已排队 `memory_maintenance` 项保留兼容处理。Memory 服务本身不调用模型或 Executor。
长期事实必须附可逐字核对的证据,但不要求每批对话都提炼事实。`profile` 只收来自用户原话的
稳定身份、交流偏好和职业工作方式,并须标明 `profile_kind`;当前推进的工作用 `project`,
只按相关性提供,不常驻顶层画像。具体日程、临时位置、输入法状态、软件是否已打开和单次测试结果
留在话题经历,不提炼为稳定画像。`environment` 仅限受控设备范围;无论观察来自用户原话还是
任务结果,单个工作日都只能是 `candidate`,跨两个有效工作日有独立证据才会变成 `active`。
仅有上层回复复述不算验证;三天未获佐证的候选在日审中停用。已停用的事实不会被整理作业自动重启。
少量全局 `profile` 常驻上层,`project` 和已确认的设备事实按问题相关性挑选。
用户指导产生的技能只进入 `draft`,须用户本轮明确要求启用后才能
`set_status` 为 `active`;执行层可以读取草稿用于审阅,但只有已启用技能可作为执行参考。
不要把凭据、隐藏思考或无界工具输出写入记忆。
服务故障不会暂停执行队列。上层区分待查询、可用和不可用,后台按持久事件游标重试同步。
## 连续记忆 v1
完整设计见 [架构](docs/architecture.md),已实现范围、协议和验证方法见
[第一阶段说明](docs/implementation-v1.md)。
新接口:`memory.events.ingest`、`memory.observation.claim/commit/fail`、
`memory.continuity.recall`、`memory.evidence.get`。它们与旧话题/事实接口并存,不删除旧记忆。
新经历通过中文/英文倒排索引召回,不受旧任务卡的最近 100 条窗口限制。
事件所属设备由 `owner` 限定;当前部署仍是受信本地 socket、单设备统一会话,不是多租户权限系统。
## 资料夹
日程第一次运行时会按稳定 `schedule_id` 建立:
```text
bundles/schedule/<schedule_id>/
INDEX.md
requirements.md
preferences.md
lessons.md
state.json
runs/<run_id>/summary.md
```
数据库保存权威状态,以上文件用于猫窝展示和按需阅读。