Re-s/dsh-memory-s31

dsh-memory-s3

基于云端存储的 DSH 跨会话记忆插件:支持将结构化记忆和向量检索持久化至 S3 兼容的对象存储(如 AWS S3、MinIO、R2、OSS),具备本地缓存和写入审批机制。

AI 分析

核心用途是为 DSH 提供跨设备、跨会话的长期记忆能力。适合需要在多台机器上同步 AI 记忆、且注重数据自主掌控的用户。必要条件是需拥有一个 S3 兼容的对象存储桶。

包名
dsh-memory-s3
版本
0.2.3
许可证
MIT
最近更新
2026年9月5日

安装

$npx -p @deepseek-ai/dsh dsh plugin --profile web add github:Re-s/dsh-memory-s3

方式三:SSH 方式(需配置 GitHub SSH key)

npx @deepseek-ai/dsh plugin --profile web add git@github.com:Re-s/dsh-memory-s3.git


本地开发(源码调试,link 方式):

```bash
git clone https://github.com/Re-s/dsh-memory-s3.git
npx @deepseek-ai/dsh plugin --profile web add "link:/path/to/dsh-memory-s3"

配置环境变量:


# S3 凭据(必需;进程内读取,不落盘,绝不进配置文档)
export AWS_ACCESS_KEY_ID=...
export AWS_SECRET_ACCESS_KEY=...
export AWS_SESSION_TOKEN=...   # 可选,临时凭据

### 配置(符合 DSH 官方设置缝 `ctx.settings`)

> 本插件已接入 DSH 官方 `ctx.settings` 缝。配置经三层解析:
> **schema 默认值 → 该插件条目配置(`cordis.patch.yml` 的 entry config,composition base)→ 用户设置段(`settings.yaml` 顶层 `memory-s3:`)**。
> 未挂载 settings 服务的 profile 自动回退到 entry config alone(官方契约:无 provider 时插件不受影响)。
>
> S3 凭据只从环境变量读取(`accessKeyEnv`/`secretKeyEnv`,默认 `AWS_ACCESS_KEY_ID`/`AWS_SECRET_ACCESS_KEY`),绝不落盘、绝不进设置文档。

**装完还没配 bucket 时会怎样(0.2.2+)**:插件保持存活但待机,不注册任何工具/注入,启动日志给出一条告警:

[memory-s3] bucket not configured; plugin stands by (no tools/injection registered). Set a bucket in the "memory-s3" settings section, then restart the profile.


profile 正常启动、GUI 正常打开,插件在设置的 **Plugin list** 只读清单里可见。填好 bucket 后重启生效(配置变更契约为 `applies: 'restart'`)——配置请改 `settings.yaml`,本插件没有 GUI 表单入口,原因见下节。

> 0.2.1 及更早版本存在启动死锁:`bucket` 在 schema 层必填,而 cordis 加载器在 `apply()` 之前校验 entry config,未配置时直接抛 `$.bucket missing required value` 并使**整个 profile 启动失败**,连 GUI 都打不开,也就无从配置。若你卡在这个版本,临时解法是在 profile 的 `cordis.patch.yml` 里给 `- id: memory-s3` 补一个 `config.bucket` 占位值;建议直接升级到 0.2.2+。

#### 关于 GUI:为什么设置里没有本插件的表单入口

Web 设置的 **Plugins** 分区有两个标签页,本插件只出现在前者:

| 标签页 | 由谁提供 | 本插件 |
|---|---|---|
| **Plugin list**(只读清单) | `dsh-client-ui-settings-plugin-inventory` | ✅ 可见 |
| **Plugin configuration**(可编辑表单) | `dsh-client-ui-settings-plugins` | ❌ 无入口 |

官方对 Plugin configuration 标签页的渲染规则是**双账本交集**:

> The tab reads which settings namespaces the Host serves and dispatches one slot key per namespace, so what renders is the intersection of two ledgers: the namespaces a live Host plugin registered, and the cards registered under those keys. **A served namespace no card claims renders nothing.**

即:注册了 settings 命名空间**只是必要条件**,还需要一张认领该命名空间的「卡片」。而卡片必须由插件自带浏览器半侧,官方在 Known Limitations 中明确了门槛:

> **A card still needs a browser bundle** — the browser half must be a `dsh.client` package built in the client module system's lazy-CJS factory format, and the `clientBundle` preset that emits it lives in `packages/client/tsdown.client.ts` rather than a published package, **so a plugin outside this repository has to reproduce that build itself.**

本插件是纯 Host 侧插件、不含浏览器 bundle,因此没有可视化表单。**这不影响配置能力**:`settings.yaml` 的 `memory-s3:` 段照常参与官方三层解析(schema 默认 → entry config → 用户设置段),命名空间也已正常注册(否则该段不会生效)。

> 另一条官方限制值得知道:命名空间的注册**不会**主动推送给前端——「the wire announces settings-document commits and connection resets, not registrations」,所以新注册的命名空间要等下一次设置文档提交或重连才会进入前端列表。

#### 方式一:官方设置缝(推荐)——`$DSH_HOME/settings.yaml`

在 `settings.yaml` **顶层**写 `memory-s3:` 段(不是旧文档的 `plugins.memory-s3` 子段):

```yaml
memory-s3:
  enabled: true
  bucket: my-memory-bucket
  prefix: dsh-memory-s3 # ⚠️ 多设备共享时必须逐字一致,详见下节「prefix 必须跨设备一致」
  endpoint: ""          # 留空用 AWS;MinIO/R2 填 https://...
  region: us-east-1
  writePolicy: ask      # ask | auto | off
  snapshotOrder: -50    # systemPrompt 注入段顺序
  maxInjectedItems: 5   # 快照注入条数上限
  importanceThreshold: 3 # 进入"事实层"注入候选的重要性下限
  embedder:
    provider: openai-compatible
    endpoint: https://api.openai.com/v1/embeddings
    apiKeyEnv: OPENAI_API_KEY
    model: text-embedding-3-small
    dimensions: 768    # 显式覆盖;text-embedding-3-small 常见 1536,此处代码默认 768
  cacheDir: ""          # 留空 = $DSH_HOME/dsh-memory-s3/cache
  auditRetentionDays: 0 # 0 = 永久保留
  maxFileBytes: 20971520      # 附件大小上限(字节;默认 20MB,>100MB 时加载告警)
  allowedFileTypes: [png, jpg, jpeg, gif, webp, pdf, zip, txt, md, json, csv]  # 附件扩展名白名单(小写,无点)

方式二:entry config(composition base)

在 profile 的 cordis.patch.yml 以小写 id 覆盖该条目的 config(整体替换语义):

- id: memory-s3
  config:
    enabled: true
    bucket: my-memory-bucket
    endpoint: ""
    region: us-east-1
    writePolicy: ask
    embedder:
      provider: none

用户设置段(方式一)中出现的字段会覆盖 entry config 的同名字段;entry config 又覆盖 schema 默认值。

使用