@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任务。
같은 패키지 이름의 다른 저장소
설치
npx -p @deepseek-ai/dsh dsh plugin --profile web add github:hongweifei/dsh-memory3. 配置
在 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 开关 |
环境变量优先于配置,且只有这四个开关能从环境进来。