@qltk/pi-mnemo
Persistent memory for the pi coding agent — auto recall/extract/dream, file-based (MEMORY.md index + topic files), global + project dual scope. Port of mnemo (opencode).
Package details
Install @qltk/pi-mnemo from npm and Pi will load the resources declared by the package manifest.
$ pi install npm:@qltk/pi-mnemo- Package
@qltk/pi-mnemo- Version
0.6.4- Published
- Sep 7, 2026
- Downloads
- 1,948/mo · 1,948/wk
- Author
- lby3523
- License
- MIT
- Types
- extension
- Size
- 119.4 KB
- Dependencies
- 0 dependencies · 1 peer
Pi manifest JSON
{
"extensions": [
"./index.ts"
]
}Security note
Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.
README
pi-mnemo
pi coding agent 的持久记忆扩展。mnemo(opencode 版)的 pi 移植:文件式、四类型、MEMORY.md 索引 + topic 文件、三段全自动。
纯 TypeScript 扩展,无 native 依赖、无 Docker、不用 RAG/向量检索。相关性靠 LLM-judge(注入索引 → agent 扫标题 → 按需读 topic)。
工作机制(三段)
| 段 | 触发 | 机制 |
|---|---|---|
| Recall | 每次用户提交 prompt(before_agent_start) |
把 inject.md 指令 + global/project 两个 MEMORY.md 索引追加进 system prompt |
| Extract | 会话安定(agent_settled),节流后 |
spawn 分离的无头 worker pi -p --no-session,自读会话 JSONL、抽取新记忆写 topic 文件 |
| Dream | 会话安定 + 24h 节流 + 夜间窗口 | 无头 worker 合并/去重/软删(deprecated_by)/修正漂移/清理索引 |
另有 citation 闭环:主 agent 用 read 工具读过某 topic 文件 → 自动 bump 该 topic 的 usage_count / last_used(不依赖模型自觉);dream 据此修剪长期未引用的过期 topic。
主 agent 只在用户显式说"记住"时直接写;其余抽取由后台 worker 负责。
安装
# npm(推荐;pi.dev gallery 自动收录带 pi-package 关键字的包)
pi install npm:@qltk/pi-mnemo
# git 源
pi install git:gitee.com/liubola/pi-mnemo
# 本地开发(放自动发现目录,支持 /reload 热重载)
ln -s /path/to/pi-mnemo ~/.pi/agent/extensions/pi-mnemo
使用
装好后全自动。命令:
/mnemo— 状态(memory root、slug、topic 数、上次 dream 时间)/mnemo extract— 手动触发本会话抽取/mnemo dream— 手动触发整理/mnemo refresh— 丢弃本会话记忆快照,下轮注入最新索引(代价:一次全量 prefill)
对模型说"记住 …"会立即写入(见 inject.md 指令)。
记忆快照语义:每个会话首条消息时冻结一份记忆索引快照,会话内字节固定——为了让本地推理(llama.cpp 等 KV 前缀缓存)不为后台记忆更新付全量重算的代价。会话中途后台 extract/dream 写入的新记忆,下一会话可见;急需时 /mnemo refresh 主动换新(本会话付一次全量 prefill)。
记忆落盘位置
~/.pi/agent/mnemo/ ← memoryRoot
├── MEMORY.md global 索引(user 类型,跨项目)
├── <topic>.md user 类型 topic
├── projects/<slug>/ per-project(slug 由项目路径末段生成,保留 CJK:`旅游` → `projects/旅游/`;仅符号/空目录名落 default 桶)
│ ├── MEMORY.md project 索引
│ └── <topic>.md project/feedback/reference 类型
├── .plugin.log 调试日志
├── .state.json extract/dream 节流游标
└── .dream.lock dream 互斥锁
双跑提示(mnemo / pi-mnemo):两边记忆格式完全兼容(frontmatter + MEMORY.md 索引),可整目录迁移复制;不建议双端同时指向同一 store——state/索引的跨进程写保护未做(见 docs/adr/0001)。
四类型 → scope
| type | scope | 记什么 |
|---|---|---|
| user | global | 用户角色、跨项目偏好 |
| feedback | project | 协作纠正(规则 + 原因 + 适用范围) |
| project | project | 代码/git 推导不出的背景、决策、约束 |
| reference | project | 外部系统链接 |
配置
推荐用配置文件 ~/.pi/agent/mnemo.json(或 $PI_MNEMO_CONFIG 指定路径),优先级 文件 > env > 默认。改完重启 pi 生效(pi-web:systemctl --user restart pi-web)。
{
"extractModel": "zen/big-pickle", // 抽取 worker(免费档即可)
"dreamModel": "zai-coding-cn/glm-5.3-flash", // 整理 worker(建议大窗口)
"dreamWindow": "18:30-08:30", // dream 夜间窗口,"" = 全天
"disabled": false
}
全部字段(表由 npm run gen:config 从 CONFIG_FIELDS 生成,勿手改):
| file key | env | 默认 | 说明 |
|---|---|---|---|
memoryRoot |
PI_MNEMO_ROOT |
~/.pi/agent/mnemo | 记忆根目录(global 索引 + topic + projects//) |
promptsDir |
PI_MNEMO_PROMPTS_DIR |
/prompts | prompt 模板目录(开发期一般不动) |
extractModel |
PI_MNEMO_EXTRACT_MODEL |
(pi 默认模型) | extract worker 模型(provider/id;空 = pi 当前默认) |
dreamModel |
PI_MNEMO_DREAM_MODEL |
同 extract | dream worker 模型(建议大窗口) |
workerTools |
PI_MNEMO_WORKER_TOOLS |
read,grep,find,edit,write,bash | worker 工具白名单(必须是 pi 内置名:find 不是 glob) |
workerExtensions |
PI_MNEMO_WORKER_EXTENSIONS |
(空) | worker 额外加载的扩展(逗号分隔:路径 / npm: / git: 源)——--no-extensions 仍挡自动发现,此处仅显式放行(如网关类 provider) |
dreamIntervalMs |
PI_MNEMO_DREAM_INTERVAL_MS |
86400000 | dream 节流(per-slug,24h) |
dreamWindow |
PI_MNEMO_DREAM_WINDOW_START/END |
18:30-08:30 | dream 夜间窗口(文件 "18:30-08:30";空 = 全天) |
extractMinNewMessages |
PI_MNEMO_EXTRACT_MIN_NEW_MESSAGES |
5 | 触发 extract 的最小新增 JSONL 行数 |
extractMinIntervalMs |
PI_MNEMO_EXTRACT_MIN_INTERVAL_MS |
1800000 | 同一会话两次 extract 最小间隔 |
dreamBacklogDays |
PI_MNEMO_DREAM_BACKLOG_DAYS |
2 | dream-backlog(待实现):超过 N 天未 dream 的 slug 补做 |
dreamBacklogPerIdle |
PI_MNEMO_DREAM_BACKLOG_PER_IDLE |
1 | dream-backlog(待实现):每次空闲补几个 slug |
pruneAgeDays |
PI_MNEMO_PRUNE_AGE_DAYS |
30 | dream 修剪硬阈值(天数 + 低使用) |
coldStartDays |
PI_MNEMO_COLD_START_DAYS |
14 | usage 统计冷启动(此前不按 usage 修剪) |
topicSoftMaxKB |
PI_MNEMO_TOPIC_SOFT_MAX_KB |
8 | topic 文件软上限(KB) |
logMaxBytes |
PI_MNEMO_LOG_MAX_BYTES |
1048576 | .plugin.log / .worker.log 滚动阈值 |
workerIdleTimeoutMs |
PI_MNEMO_WORKER_IDLE_TIMEOUT_MS |
300000 | worker 无活跃判定窗(防挂死不防慢) |
workerHardCapMs |
PI_MNEMO_WORKER_HARD_CAP_MS |
3600000 | worker 总时长硬顶 |
disabled |
PI_MNEMO_DISABLED |
0 | true / 1 = 关后台(只留 recall + 手动命令) |
另有两个 env-only(不在 CONFIG_FIELDS 内):PI_MNEMO_CONFIG(配置文件路径,默认 ~/.pi/agent/mnemo.json)、PI_MNEMO_PI_BIN(spawn worker 用的 pi 可执行文件,默认 pi)。配置文件里的未知 key 启动时会在 stderr 警告并忽略;数值字段写坏会警告并回退默认值。
与 mnemo(opencode 版)的差异
| mnemo | pi-mnemo | |
|---|---|---|
| Recall 钩子 | experimental.chat.system.transform |
before_agent_start(每轮注入最新索引) |
| Extract 执行 | opencode server fork session + promptAsync |
分离进程 pi -p --no-session,自读会话 JSONL |
| 会话泄漏防护 | forkSessions Map + session.delete |
不需要(--no-session 不落盘,进程退出即清理) |
| Citation 观测 | 拉取 server transcript | 直接扫会话 JSONL 文件的 toolCall 行 |
| Extract 游标 | message id | JSONL 行号(天然增量和断点) |
| 额外钩子 | — | session_shutdown 兜底 flush |
License
MIT