hongweifei/dsh-memory ↗★ 0

@dsh-external/dsh-memory

Qoder-Agent-SDK-style persistent memory for DSH: a background generation pass writes knowledge into per-scope memory files after each turn, and a consumption pass loads them into Agent context on session start or explicit refresh. DSH 持久记忆插件:按 Qoder SDK 的做法分离「生成」与「消费」,user/project 双作用域,token 预算加载。 适合需要双作用域持久记忆、精细控制Token预算的复杂Agent任务。

パッケージ
@dsh-external/dsh-memory
互換性
未検証
バージョン
0.1.0
最終更新
2026/09/29

同名パッケージの別リポジトリ

インストール

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

ドキュメント

README 全文を読む ↗

3. 配置

在 profile 的 cordis.patch.yml 覆盖(不要改插件自带的 patch,升级会被覆盖):

- id: memory
  name: '@dsh-external/dsh-memory'
  config:
    enabled: true
    mode: native              # native | custom
    userScope: true           # $DSH_HOME/memory/
    projectScope: true        # $DSH_HOME/projects/
/memory/  (不在仓库里)
    projectRootMarkers: []    # 空=会话 cwd 就是项目(harness 的分组方式);['.git']=整个仓库一份记忆
    excludes: []              # gitignore 风格 glob(picomatch),只对项目作用域生效
    #   - '**/*.draft.md'
    imports:                  # 记忆文件里的 @ 引用展开(Qoder 的 ImportProcessor)
      enabled: true
      format: tree            # tree | flat
      maxDepth: 5
      allowExternal: false    # 放行越出允许目录的导入
      approvedProjects: []    # 按项目目录放行:['D:/code/checkout']
    trust:
      enabled: false          # Qoder 的 security.folderTrust.enabled;关=所有目录都受信任
      folders: []             # 显式信任的目录(绝对路径,或相对会话 cwd)
    generation:
      maxOutputTokens: 0      # 0=不给回复设上限,用适配器/模型自己的默认值(见下方说明)
      maxWrites: 4            # 单轮最多写几个文件
      maxWriteBytes: 16384    # 单文件字节上限
      provider: ''            # 留空则用会话自身模型路由
      model: ''
      prompt: ''              # 附加记录策略
      roots: []               # custom 模式下的自定义根
      #   - { id: team, path: D:/knowledge/team, access: read }
      turnComplete:
        enabled: true
        minPromptChars: 40    # 内置闸门:短于此长度不生成
        timeoutMs: 10000
        onGateError: skip     # skip | report_failed
        # shouldGenerate: !!js 'async (input, { signal }) => ({ run: input.prompt.length > 40 })'
      incremental:
        everyTurns: 1         # Qoder 的 extractionEveryNTurns:每 N 轮跑一次生成
        midTurn: false        # true 时长回合中途也生成(Qoder 的实验开关 auto_memory_incremental_generation)
      dream:
        enabled: false        # 巩固 pass(Qoder 的 AutoDream),默认关:它多花一次模型调用
        minHours: 24
      # onResult: !!js '(r) => console.log("memory", r.status)'
    consumption:
      enabled: true
      maxTokens: 2000
      overflow: truncate       # truncate | fail_query
      failureMode: best_effort # best_effort | fail_query
      # files:                 # custom 模式下替代自动发现
      #   - { id: conventions, path: D:/knowledge/CONVENTIONS.md, required: true }
      # onResult: !!js '(r) => console.log("memory", r.status)'

shouldGenerate 与 onResult 用 YAML 的 !!js 表达式传入(Loader 会求值成真正的函数)。

native 与 custom 的差别照 SDK 的规则:native 下运行时决定记什么、存哪里、何时加载, 且拒绝 generation.* / consumption.* 的覆盖;custom 只覆盖你显式给出的部分。

关于 maxOutputTokens:SDK 的 SerializableMemoryGenerationOptions 里没有这个字段 (只有 enabled / roots / prompt / turnComplete),所以它是本插件自己的旋钮, maxWrites / maxWriteBytes 同理。默认 0=不设上限,让适配器套用模型自己的默认值—— 这是唯一对所有模型都成立的选择:pass 是用工具调用写文件的,文件正文就在工具参数里, 固定小上限会让推理模型在吐出工具调用之前就撞上上限(本插件第一版抄了 Qoder summarizer-* 任务类型的 2e3,那适用于摘要,不适用于写作)。要控成本就显式设一个值;上限撞上且那一轮 没有可用的工具调用时,pass 会失败并在原因里说清(generation reached maxOutputTokens…); 若撞上但工具调用已经完整,那些写入照常落地再结束循环。

环境变量覆写

Qoder 用「品牌前缀 + 名字」拼环境变量(Pr(name) => ${prefix}${name}``),布尔词汇是 1/true/yes/on 与 0/false/no/off(去空格、忽略大小写),其他值当未设置。本插件沿用同一套词汇,前缀换 DSH_:

变量作用
DSH_MEMORY_HEADLESS=false整体关闭记忆
DSH_MEMORY_PROJECT / DSH_MEMORY_USER覆写两个作用域开关
DSH_MEMORY_DREAM覆写巩固 pass 开关

环境变量优先于配置,且只有这四个开关能从环境进来。