npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

opencode-memory-dream

v0.4.0

Published

Auto-memory and auto-dream plugin for OpenCode - persistent project knowledge with periodic consolidation

Readme

OpenCode Auto-Memory & Auto-Dream 插件文档

文档版本:v1.0 | 日期:2026-04-13 | 状态:初稿


目录

  1. 需求背景
  2. 插件定位与能力概览
  3. 核心架构
  4. Auto-Memory:自动记忆提取
  5. Auto-Dream:周期性记忆整理
  6. 检索增强与显式记忆工具
  7. 存储结构与数据格式
  8. 安装与配置方式
  9. 当前边界与后续方向

1. 需求背景

1.1 问题定义

AI 编程助手在长周期协作里会遇到一个根本问题:会话结束后,上下文容易断裂。用户曾明确说过的偏好、项目中的非代码事实、时间线信息、事故背景、外部参考资料,往往不会自然沉淀下来。下一次进入新会话时,模型即使“知道如何写代码”,也不一定还“记得为什么这么写”。

在实际工作中,最容易丢失的不是源码本身,而是这些无法从代码和 git 直接反推的长期上下文,例如:

  • 用户是谁、负责什么、偏好怎样的回答方式
  • 当前项目为什么要做、截止时间是什么、谁在推进什么事项
  • 某次事故发生在哪一天、复盘何时完成、哪些外部文档最关键

1.2 目标

本插件的目标,是在 OpenCode 的插件体系上复刻一套可落地的持久化记忆系统,让模型具备以下能力:

  • 在对话结束后自动提取值得长期保留的信息
  • 在新一轮对话开始前,自动召回与当前问题最相关的记忆
  • 定期对已有记忆做整理、去重、合并和过期清理
  • 支持用户显式要求“记住某件事”或“忘掉某件事”

1.3 插件定位

当前包名为 opencode-memory-dream,运行时插件 ID 为 opencode-memory-plugin。它是一个 OpenCode server plugin,不提供独立 UI,而是通过 hook、后台子会话和工具定义,增强现有对话流。


2. 插件定位与能力概览

2.1 能力全景

插件不是单点工具,而是一套完整的“记忆生命周期”方案,包含四条主链路:

| 能力 | 触发方式 | 作用 | |------|---------|------| | 隐式信号捕获 | chat.message | 从新消息中提取时间、身份、职责、技术栈等 durable signal | | 自动记忆提取 | session.idle | 在对话告一段落后创建子会话,把最近消息沉淀为持久化记忆文件 | | 记忆召回增强 | experimental.chat.system.transform | 根据当前用户问题注入相关记忆和捕获信号,提高连续性 | | 自动 / 手动 dream 整理 | session.idle / dream tool | 周期性整理记忆库,合并重复、清理陈旧、更新索引 |

除此之外,插件还提供四个显式工具:

  • remember:立即保存显式记忆
  • forget:删除或更新已记忆内容
  • dream:手动触发一次整理
  • dream_config:查看、开启、关闭或切换自动 dream

2.2 适合保存什么

插件明确区分“值得记忆的长期上下文”和“应从代码中实时获取的信息”。

适合记忆的内容:

  • 用户身份、职责、目标、偏好
  • 项目背景、事故时间线、里程碑、外部事实
  • 用户对回答方式和协作流程的反馈
  • 外部系统或文档的引用线索

不适合记忆的内容:

  • 代码结构、文件路径、实现细节
  • git 历史、commit 事实
  • 已经写进仓库的规范和约定
  • 当前会话的临时任务状态

3. 核心架构

3.1 总体链路

用户新消息
  ↓
chat.message
  ├─ 记录 last query
  └─ 抽取 captured signals(temporal / identity / responsibility / stack)

模型开始下一轮响应
  ↓
experimental.chat.system.transform
  ├─ 注入 memory-policy
  ├─ 注入 MEMORY.md 索引(可选)
  ├─ 注入与当前 query 相关的 curated memories
  ├─ 注入 captured signals 摘要
  └─ 注入上一轮后台维护反馈

会话空闲
  ↓
session.idle
  ├─ 运行 auto-memory extraction
  ├─ 记录 dream 候选 session
  └─ 满足门槛时触发 auto-dream consolidation

3.2 关键设计原则

设计一:主代理负责对话,子会话负责整理

插件不会让主对话线程直接承担记忆整理逻辑,而是在空闲时创建受限子会话完成提取或 consolidation。这让主链路保持轻量,也便于把记忆操作限制在 .opencode/memory 目录内。

设计二:显式记忆与隐式记忆分层

  • 显式记忆:只有当用户明确要求“记住/忘掉”时,才调用 remember / forget
  • 隐式记忆:依靠后台 auto-memory 自动沉淀 durable context

这种分层避免了模型把每一句用户输入都机械保存成长期记忆。

设计三:先捕获原始信号,再决定是否晋升为 curated memory

插件先把明显的 durable signal 写入 captured-signals.json,再在 auto-memory 阶段结合最近对话窗口和现有记忆清单,决定哪些内容值得晋升为正式 .md 记忆文件。这一层设计让系统既不容易漏掉高价值事实,也不会过早把低置信度内容写死。


4. Auto-Memory:自动记忆提取

4.1 触发机制

Auto-memory 在根会话收到 session.idle 事件后触发,只处理根会话,跳过所有子会话,避免背景任务再次触发背景任务。

触发后,插件会:

  1. 拉取当前会话消息
  2. 依据 .extraction-state.json 找到尚未处理的新消息窗口
  3. 扫描现有记忆文件,生成 manifest
  4. 创建名为 Auto-Memory Extraction 的子会话
  5. 用受限权限提示词驱动该子会话只在 memory 目录内读写
  6. 对比前后快照,识别新增或变更的记忆文件

4.2 核心能力

增量处理

插件不会每次都重扫完整会话,而是用 lastProcessedMessageID 维护游标,仅处理上次提取之后的新消息。

并发合并

若上一次 extraction 尚未结束,新触发不会并行再跑一份,而是把最新请求合并为 pending,待当前轮结束后再补跑一次,避免重叠写入。

主代理直写保护

如果最近消息中已经出现对 memory 目录的直接写入,auto-memory 会跳过本轮提取,避免后台子会话覆盖主代理刚完成的记忆修改。

降级兜底

当模型提取失败、超时或子会话异常时,插件会退回本地 fallback 逻辑,至少把时间线或系统概览这类高价值事实沉淀下来,而不是直接丢失本轮信息。

4.3 Prompt 约束

提取子会话使用的 prompt 明确要求:

  • 仅允许在 memory 目录内 Read / Grep / Glob / Write / Edit
  • 不允许使用 Bash
  • 只基于最近消息窗口做判断
  • 优先更新已有记忆,避免制造重复文件
  • 把相对时间转换为绝对日期

这使得 auto-memory 更像一个“受控资料整理器”,而不是无边界的通用代理。

4.4 捕获信号的角色

在正式 extraction 之前,插件会从新消息中尝试提取四类高价值信号:

| 类别 | 典型内容 | |------|---------| | temporal | 事故发生日期、复盘完成日期、带日期的项目事实 | | identity | 用户姓名、身份、公司、角色 | | responsibility | 用户负责的模块、维护范围、当前职责 | | stack | 前后端、数据库、缓存、部署等技术栈线索 |

这些信号先作为原始记录保存,随后在 extraction 中被用作高置信度输入。


5. Auto-Dream:周期性记忆整理

5.1 目标

Auto-memory 负责“把新信息写进去”,Auto-dream 负责“让记忆库长期保持干净”。它解决的是另一个问题:随着使用时间增长,记忆文件会越来越多,可能重复、过时、互相矛盾,MEMORY.md 索引也可能变臃肿。

Dream 的职责是:

  • 合并重复或主题重叠的记忆文件
  • 用新信息覆盖旧事实
  • 删除陈旧、无用或冲突条目
  • 更新 MEMORY.md 索引,控制规模

5.2 自动触发门槛

默认配置下,自动 dream 需要同时满足以下条件:

  • 距离上一次 dream 已超过 24 小时
  • 期间累计了至少 5 个 dream 候选根会话
  • 当前不是另一个 dream 正在执行的状态

此外,插件还带有两个保护机制:

  • 扫描节流:候选 session 扫描每 10 分钟最多做一次
  • best-effort 锁文件互斥:通过 .dream-lock 结合 PID 与 stale-reclaim 语义,尽量避免正常运行中出现重叠 dream

5.3 执行方式(两层 consolidation pipeline)

满足门槛后,dream 不再直接进入一次性语义整理,而是采用两层流水线:

  1. 确定性规范化层(deterministic normalization)
  2. 语义 consolidation 层(semantic consolidation)

先跑确定性层,再根据剩余问题决定是否进入语义层。

5.4 确定性规范化层

这一层只处理结构性、可确定修复的问题,不依赖模型语义判断。当前覆盖:

  • 索引结构清理:移除 MEMORY.md 中失效链接、越界链接、重复链接等无效项
  • frontmatter 规范化:为缺失或不完整的记忆文件补齐合法 frontmatter
  • 精确重复折叠:对内容完全重复的 memory 文件执行去重并同步索引

如果在这一层已经完成全部可修复项,dream 会直接结束,不触发语义层。

5.5 语义 consolidation 层(按需触发)

当确定性层结束后仍存在高歧义、需要语义判断的问题(当前主要是 contradiction bundles / candidates)时,才会触发语义 consolidation:

  1. 汇总自上次 dream 以来的候选根会话
  2. 生成 session summary(而不是注入全部转录)
  3. 创建名为 Auto-Dream Consolidation 的子会话
  4. 仅授予 memory 目录内的有限读写权限
  5. 让子会话基于记忆清单、异常摘要、候选摘要做保守整理

这里的 contradiction flow 不再只给模型一组松散的“左右文件冲突提示”,而是优先构造成 contradiction bundles。每个 bundle 会把同一主题下的冲突证据按结构化字段组织起来,让 semantic dream 在同一推理上下文中直接处理:

  • subject
  • attribute
  • competing current claims
  • historical claims
  • preferred current value when locally inferable(仅在本地规则能够 infer 出更可信当前值时提供)

这意味着 dream 在进入语义层时,看到的是“哪个主体的哪个属性存在当前态冲突、哪些说法应视为历史、以及本地是否已经推断出一个更可能保留的当前值”,而不是只看到未分组的 contradiction candidate 列表。这样可以更稳定地区分“当前事实互相冲突”和“新事实覆盖旧历史事实”。

更重要的是,contradiction bundles 不再只是 reasoning context,而是 semantic edit targets。语义 dream 在执行时必须按 subject + attribute 粒度完成一次 current-state 决策,并对 memory 文件落实编辑结果:

  • 基于同一 subject + attribute 的 competing claims,选择一个 winning current-state value
  • 将其余 competing current-state claims 明确判定为 stale
  • 将 stale current-state wording 从 memory 文件中删除,或改写为 historical wording

只有当 memory 文件里同一 subject + attribute 最终只剩一个 current-state value(其余表述已被移除或历史化)时,这轮 contradiction resolution 才算真正完成。

5.6 Dream 结果语义

dream 的完成态现在显式区分:

  • completed_changed:本次 consolidation 实际修改了一个或多个 memory 文件(返回 changedFiles
  • completed_noop:本次 consolidation 成功执行,但无需修改任何文件
  • completed_unresolved:语义 consolidation 已运行,但仍存在未解决的 contradiction bundles,不会再被误报为普通 noop

这使“执行成功但无改动”和“执行成功且已改动”在工具层可被稳定区分。


6. 检索增强与显式记忆工具

6.1 检索增强

experimental.chat.system.transform 阶段,插件会根据当前 query 做两类召回:

Curated memory 召回

.md 记忆文件中按分数选出最相关内容。打分策略是词法命中 + 语义词组扩展 + 类型提示 + 新鲜度加权的混合规则,不依赖向量库。

当前内置的语义词组重点覆盖:

  • 技术栈 / 前后端 / 数据库 / 部署
  • 事故 / 时间线 / 日期 / 复盘
  • 偏好 / 风格 / 规则
  • 名字 / 身份 / 角色 / 公司

这套规则已经覆盖中英文混合问法,测试里也验证了中文提问下的召回效果。

Captured signal 召回

如果 curated memory 还不够完整,插件会进一步补充 captured-signals.json 中与当前 query 相关的原始信号,避免“记忆文件只覆盖了一半答案”的情况。

6.2 显式工具

remember

当用户明确要求“记住某件事”时调用,直接生成标准 frontmatter 的记忆文件并同步更新 MEMORY.md

支持的 memory type:

  • user
  • feedback
  • project
  • reference

forget

当用户明确要求“忘掉某件事”时调用。它先用当前查询去做相关性匹配,再优先删除最准确命中的记忆文件,而不是暴力清空整个记忆库。

dream

允许用户手动触发一次整理,不依赖自动门槛。

dream_config

支持四种动作:

  • status
  • enable
  • disable
  • toggle

自动 dream 的开关状态保存在 .dream-settings.json,默认启用。

6.3 系统提示里的行为约束

插件会额外注入一段 memory-policy,明确要求模型:

  • 只有在用户明确提出记忆管理需求时才调用 remember / forget
  • 只有在用户明确问及自动 dream 状态时才调用 dream_config
  • 不要因为用户随手提到一个事实,就立即显式保存

这使工具行为更可控,也减少误触发。


7. 存储结构与数据格式

7.1 存储根目录

插件的持久化目录默认位于:

<worktree-or-directory>/.opencode/memory

其中根目录解析策略为:

  • 如果当前是 global 项目且 directory 不是根路径,则优先使用 directory
  • 否则优先使用 worktree
  • 再次退化时使用 directory

这样可以兼容普通仓库会话和全局临时会话两种场景。

7.2 目录内容

典型结构如下:

.opencode/memory/
├── MEMORY.md
├── captured-signals.json
├── .dream-settings.json
├── .dream-lock
├── .dream-sessions.json
├── .extraction-state.json
├── user_*.md
├── feedback_*.md
├── project_*.md
└── reference_*.md

7.3 记忆文件格式

每个正式记忆文件都使用 frontmatter:

---
name: release freeze
description: release freeze date and handling guidance
type: project
---

Release freeze starts on 2026-04-20.
Why: This date controls risky changes.
How to apply: Avoid planning invasive refactors after this point.

MEMORY.md 则作为轻量索引,每条记录是一行链接:

- [Release freeze](project_release_freeze_xxxxxxxx.md) — release freeze date and handling guidance

8. 安装与配置方式

8.1 安装方式

如果环境可以访问 npm,可以直接通过 OpenCode 的插件安装流程接入:

opencode plugin [email protected] -g

也可以手动将它写入工作区的 .opencode/opencode.jsonc

{
  "plugin": [
    "[email protected]"
  ]
}

如果你在本地开发插件,也可以直接使用本地路径:

opencode plugin /absolute/path/to/opencode-memory-plugin -g -f

8.2 离线安装包

如果用户处在内网、无法直接访问 npm,推荐使用插件自带的离线 bundle:

npm run bundle:offline

该命令会在 release/ 下生成两份产物:

  • opencode-memory-dream-0.4.0-offline/
  • opencode-memory-dream-0.4.0-offline.tar.gz

把目录或压缩包发给离线用户后,对方只需要解压并执行:

./install.sh

或者手动安装:

opencode plugin /path/to/opencode-memory-dream-0.4.0-offline/plugin -g -f

这个离线 bundle 已经包含插件运行时需要的依赖,适合无法同步内源、也无法直接 npm install 的环境。

8.3 带选项的配置

插件支持通过 tuple 传入 server plugin 选项:

{
  "plugin": [
    [
      "opencode-memory-dream",
      {
        "dreamMinHours": 24,
        "dreamMinSessions": 5,
        "retrievalMaxFiles": 4,
        "retrievalMinScore": 3,
        "includeIndexFallback": true,
        "dreamLockStaleMs": 3600000
      }
    ]
  ]
}

8.4 配置项说明

| 配置项 | 默认值 | 作用 | |-------|-------|------| | dreamMinHours | 24 | 两次自动 dream 之间的最小小时数 | | dreamMinSessions | 5 | 触发自动 dream 所需的最少候选根会话数 | | retrievalMaxFiles | 4 | 每轮最多注入多少份相关记忆 | | retrievalMinScore | 3 | 记忆召回最低分阈值 | | includeIndexFallback | true | 是否把 MEMORY.md 作为索引上下文一起注入 | | dreamLockStaleMs | 3600000 | dream 锁过期时间,默认 1 小时 |


9. 当前边界与后续方向

9.1 当前边界

当前实现已经完整跑通,但也有明确边界:

  • 检索仍是规则打分,不是向量检索
  • 隐式信号捕获目前只覆盖 temporal / identity / responsibility / stack 四类
  • 记忆是否陈旧主要依赖时间和新信息覆盖,还没有更强的事实冲突判定
  • 插件只提供 server 能力,没有单独的可视化 memory 管理界面

9.2 已有实现成熟度

从源码和测试覆盖来看,当前版本已经具备较完整的工程闭环:

  • 验证了 extraction 游标持久化
  • 验证了模型失败时的 fallback memory 写入
  • 验证了中文/英文混合提问下的记忆召回
  • 验证了全局会话与工作区会话下的存储根目录解析
  • 验证了 dream 开关的持久化行为

9.3 后续可继续增强的方向

  • 引入更强的冲突检测与事实合并策略
  • 为 memory 库增加可视化管理面板
  • 把 captured signals 扩展到更多 durable categories
  • 在更大规模记忆库场景下引入向量检索或分层索引

总结

opencode-memory-dream 不是“给模型加一个 remember 命令”这么简单,而是在 OpenCode 插件框架内实现了一套完整的长期记忆机制:

  • 前台会话负责正常协作
  • 后台子会话负责提取与整理
  • 系统提示负责召回与约束
  • 显式工具负责用户可控的记忆管理

如果说普通会话式 AI 擅长“解决眼前问题”,那么这个插件要补齐的,就是它在长期协作里最欠缺的部分:持续记住那些代码之外、但对协作真正重要的事实。