dsh-plugin-prompt-tool 0.4.2 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (188) hide show
  1. package/README.md +125 -222
  2. package/engine/compaction-epoch.mjs +139 -0
  3. package/engine/compositions/library/bootstrap-filesystem.yml +19 -0
  4. package/engine/compositions/library/compaction.yml +52 -0
  5. package/engine/compositions/library/context-gate.yml +40 -0
  6. package/engine/compositions/library/custom-bash.yml +14 -0
  7. package/engine/compositions/library/delegation.yml +85 -0
  8. package/engine/compositions/library/official-agent-instructions.yml +17 -0
  9. package/engine/compositions/library/official-persistent-shell.yml +56 -0
  10. package/engine/compositions/library/official-skill-filesystem-cordis.yml +10 -0
  11. package/engine/compositions/library/official-tool-bash.yml +6 -0
  12. package/engine/compositions/library/official-tool-cordis.yml +13 -0
  13. package/engine/compositions/library/official-tool-presentation.yml +7 -0
  14. package/engine/compositions/library/official-tool-skill.yml +14 -0
  15. package/engine/compositions/library/persistent-shell.yml +36 -0
  16. package/engine/compositions/library/persona.yml +9 -0
  17. package/engine/compositions/library/planning.yml +41 -0
  18. package/engine/compositions/library/prompt-config-engine.yml +16 -0
  19. package/engine/compositions/library/router-first-turn.yml +9 -0
  20. package/engine/compositions/library/run-code-env.yml +15 -0
  21. package/engine/compositions/library/skill-filesystem.yml +13 -0
  22. package/engine/compositions/library/skill-search.yml +14 -0
  23. package/engine/compositions/library/str-replace-editor.yml +10 -0
  24. package/engine/compositions/library/tool-ask-user.yml +8 -0
  25. package/engine/compositions/library/tool-bash.yml +16 -0
  26. package/engine/compositions/library/tool-bootstrap.yml +16 -0
  27. package/engine/compositions/library/tool-filter.yml +12 -0
  28. package/engine/compositions/library/tool-fs-search.yml +18 -0
  29. package/engine/compositions/library/tool-fs.yml +10 -0
  30. package/engine/compositions/library/tool-goal.yml +19 -0
  31. package/engine/compositions/library/tool-jobs.yml +23 -0
  32. package/engine/compositions/library/tool-pwsh.yml +12 -0
  33. package/engine/compositions/library/tool-todo.yml +11 -0
  34. package/engine/compositions/library/tool-web.yml +9 -0
  35. package/engine/compositions/source/local/context-gate.yml +37 -0
  36. package/engine/compositions/source/local/custom-bash.yml +11 -0
  37. package/engine/compositions/source/local/prompt-config-engine.yml +13 -0
  38. package/engine/compositions/source/local/router-first-turn.yml +5 -0
  39. package/engine/compositions/source/local/run-code-env.yml +12 -0
  40. package/engine/compositions/source/local/skill-search.yml +11 -0
  41. package/engine/compositions/source/local/tool-bootstrap.yml +13 -0
  42. package/engine/context-gate.mjs +305 -0
  43. package/{preset → engine}/custom-bash.mjs +243 -243
  44. package/engine/executor.mjs +271 -0
  45. package/engine/fillers.mjs +273 -0
  46. package/engine/layers.mjs +220 -0
  47. package/engine/prompt-config-engine.mjs +49 -0
  48. package/{preset → engine}/router-first-turn.mjs +85 -73
  49. package/engine/run-code-env.mjs +208 -0
  50. package/engine/schema.mjs +294 -0
  51. package/{preset → engine}/shared.mjs +54 -0
  52. package/engine/strategies.mjs +223 -0
  53. package/{preset → engine}/tool-bootstrap.mjs +350 -282
  54. package/engine/tool-filter.mjs +80 -0
  55. package/engine/vendor/yaml/LICENSE +13 -0
  56. package/engine/vendor/yaml/dist/compose/compose-collection.js +88 -0
  57. package/engine/vendor/yaml/dist/compose/compose-doc.js +43 -0
  58. package/engine/vendor/yaml/dist/compose/compose-node.js +109 -0
  59. package/engine/vendor/yaml/dist/compose/compose-scalar.js +86 -0
  60. package/engine/vendor/yaml/dist/compose/composer.js +219 -0
  61. package/engine/vendor/yaml/dist/compose/resolve-block-map.js +115 -0
  62. package/engine/vendor/yaml/dist/compose/resolve-block-scalar.js +198 -0
  63. package/engine/vendor/yaml/dist/compose/resolve-block-seq.js +49 -0
  64. package/engine/vendor/yaml/dist/compose/resolve-end.js +37 -0
  65. package/engine/vendor/yaml/dist/compose/resolve-flow-collection.js +207 -0
  66. package/engine/vendor/yaml/dist/compose/resolve-flow-scalar.js +225 -0
  67. package/engine/vendor/yaml/dist/compose/resolve-props.js +146 -0
  68. package/engine/vendor/yaml/dist/compose/util-contains-newline.js +34 -0
  69. package/engine/vendor/yaml/dist/compose/util-empty-scalar-position.js +26 -0
  70. package/engine/vendor/yaml/dist/compose/util-flow-indent-check.js +15 -0
  71. package/engine/vendor/yaml/dist/compose/util-map-includes.js +13 -0
  72. package/engine/vendor/yaml/dist/doc/Document.js +335 -0
  73. package/engine/vendor/yaml/dist/doc/anchors.js +71 -0
  74. package/engine/vendor/yaml/dist/doc/applyReviver.js +55 -0
  75. package/engine/vendor/yaml/dist/doc/createNode.js +88 -0
  76. package/engine/vendor/yaml/dist/doc/directives.js +176 -0
  77. package/engine/vendor/yaml/dist/errors.js +57 -0
  78. package/engine/vendor/yaml/dist/index.js +17 -0
  79. package/engine/vendor/yaml/dist/log.js +11 -0
  80. package/engine/vendor/yaml/dist/nodes/Alias.js +116 -0
  81. package/engine/vendor/yaml/dist/nodes/Collection.js +147 -0
  82. package/engine/vendor/yaml/dist/nodes/Node.js +38 -0
  83. package/engine/vendor/yaml/dist/nodes/Pair.js +36 -0
  84. package/engine/vendor/yaml/dist/nodes/Scalar.js +24 -0
  85. package/engine/vendor/yaml/dist/nodes/YAMLMap.js +144 -0
  86. package/engine/vendor/yaml/dist/nodes/YAMLSeq.js +113 -0
  87. package/engine/vendor/yaml/dist/nodes/addPairToJSMap.js +63 -0
  88. package/engine/vendor/yaml/dist/nodes/identity.js +36 -0
  89. package/engine/vendor/yaml/dist/nodes/toJS.js +37 -0
  90. package/engine/vendor/yaml/dist/parse/cst-scalar.js +214 -0
  91. package/engine/vendor/yaml/dist/parse/cst-stringify.js +61 -0
  92. package/engine/vendor/yaml/dist/parse/cst-visit.js +97 -0
  93. package/engine/vendor/yaml/dist/parse/cst.js +98 -0
  94. package/engine/vendor/yaml/dist/parse/lexer.js +721 -0
  95. package/engine/vendor/yaml/dist/parse/line-counter.js +39 -0
  96. package/engine/vendor/yaml/dist/parse/parser.js +975 -0
  97. package/engine/vendor/yaml/dist/public-api.js +102 -0
  98. package/engine/vendor/yaml/dist/schema/Schema.js +37 -0
  99. package/engine/vendor/yaml/dist/schema/common/map.js +17 -0
  100. package/engine/vendor/yaml/dist/schema/common/null.js +15 -0
  101. package/engine/vendor/yaml/dist/schema/common/seq.js +17 -0
  102. package/engine/vendor/yaml/dist/schema/common/string.js +14 -0
  103. package/engine/vendor/yaml/dist/schema/core/bool.js +19 -0
  104. package/engine/vendor/yaml/dist/schema/core/float.js +43 -0
  105. package/engine/vendor/yaml/dist/schema/core/int.js +38 -0
  106. package/engine/vendor/yaml/dist/schema/core/schema.js +23 -0
  107. package/engine/vendor/yaml/dist/schema/json/schema.js +62 -0
  108. package/engine/vendor/yaml/dist/schema/tags.js +96 -0
  109. package/engine/vendor/yaml/dist/schema/yaml-1.1/binary.js +58 -0
  110. package/engine/vendor/yaml/dist/schema/yaml-1.1/bool.js +26 -0
  111. package/engine/vendor/yaml/dist/schema/yaml-1.1/float.js +46 -0
  112. package/engine/vendor/yaml/dist/schema/yaml-1.1/int.js +71 -0
  113. package/engine/vendor/yaml/dist/schema/yaml-1.1/merge.js +67 -0
  114. package/engine/vendor/yaml/dist/schema/yaml-1.1/omap.js +74 -0
  115. package/engine/vendor/yaml/dist/schema/yaml-1.1/pairs.js +78 -0
  116. package/engine/vendor/yaml/dist/schema/yaml-1.1/schema.js +39 -0
  117. package/engine/vendor/yaml/dist/schema/yaml-1.1/set.js +93 -0
  118. package/engine/vendor/yaml/dist/schema/yaml-1.1/timestamp.js +101 -0
  119. package/engine/vendor/yaml/dist/stringify/foldFlowLines.js +146 -0
  120. package/engine/vendor/yaml/dist/stringify/stringify.js +129 -0
  121. package/engine/vendor/yaml/dist/stringify/stringifyCollection.js +153 -0
  122. package/engine/vendor/yaml/dist/stringify/stringifyComment.js +20 -0
  123. package/engine/vendor/yaml/dist/stringify/stringifyDocument.js +85 -0
  124. package/engine/vendor/yaml/dist/stringify/stringifyNumber.js +25 -0
  125. package/engine/vendor/yaml/dist/stringify/stringifyPair.js +150 -0
  126. package/engine/vendor/yaml/dist/stringify/stringifyString.js +336 -0
  127. package/engine/vendor/yaml/dist/util.js +11 -0
  128. package/engine/vendor/yaml/dist/visit.js +233 -0
  129. package/engine/vendor/yaml/index.js +5 -0
  130. package/engine/vendor/yaml/package.json +11 -0
  131. package/lib/client.js +4421 -781
  132. package/lib/client.js.map +1 -1
  133. package/lib/index.d.mts +504 -51
  134. package/lib/index.mjs +3871 -731
  135. package/lib/preset-core.d.mts +7 -37
  136. package/lib/preset-core.mjs +44 -283
  137. package/lib/prompt-configs-BcP6miu9.d.mts +102 -0
  138. package/lib/prompt-configs-k7wuZs0C.mjs +719 -0
  139. package/package.json +104 -98
  140. package/preset/anchored/preset.yml +344 -0
  141. package/preset/creative/preset.yml +62 -0
  142. package/preset/custom/preset.yml +13 -0
  143. package/preset/liangshen/preset.yml +66 -0
  144. package/preset/minimal/preset.yml +41 -0
  145. package/preset/ptc/preset.yml +50 -0
  146. package/preset/standard/preset.yml +49 -0
  147. package/skills/manifest.json +7 -0
  148. package/skills/sandboxmod/SKILL.md +49 -49
  149. package/skills/web ui/SKILL.md +42 -0
  150. package/templates/10-pre-step.yml +28 -0
  151. package/templates/11-merged-a.yml +11 -0
  152. package/templates/13-anchor.yml +19 -0
  153. package/templates/14-first-turn-anchor.yml +27 -0
  154. package/templates/15-guide-auto.yml +25 -0
  155. package/templates/16-custom-fallback.yml +21 -0
  156. package/templates/17-instruction-hint.yml +23 -0
  157. package/templates/18-placeholder-env-facts.yml +11 -0
  158. package/templates/19-placeholder-skill-catalog.yml +19 -0
  159. package/templates/20-system-section.yml +14 -0
  160. package/templates/30-runtime-context.yml +10 -0
  161. package/templates/31-runtime-context-placeholder.yml +18 -0
  162. package/templates/40-agent-request.yml +11 -0
  163. package/templates/50-llm-stream.yml +9 -0
  164. package/templates/60-tool-pipeline.yml +12 -0
  165. package/AGENTS.md +0 -4
  166. package/plan.md +0 -312
  167. package/preset/agent.cordis.yml +0 -443
  168. package/preset/compaction-epoch.mjs +0 -81
  169. package/preset/context-gate.mjs +0 -165
  170. package/preset/instruction-hint.mjs +0 -217
  171. package/preset/near-anchor.mjs +0 -101
  172. package/preset/preset.yml +0 -3
  173. package/preset/prompt-injector.mjs +0 -112
  174. package/preset/router-guide.mjs +0 -79
  175. package/preset.md +0 -115
  176. package/upstream/dsh-anchored-standard/LICENSE +0 -22
  177. package/upstream/dsh-anchored-standard/NOTICE +0 -19
  178. package/upstream/dsh-anchored-standard/REVISION +0 -1
  179. package/upstream/dsh-anchored-standard/preset/agent.cordis.yml +0 -440
  180. package/upstream/dsh-anchored-standard/preset/compaction-epoch.mjs +0 -81
  181. package/upstream/dsh-anchored-standard/preset/context-gate.mjs +0 -202
  182. package/upstream/dsh-anchored-standard/preset/custom-bash.mjs +0 -219
  183. package/upstream/dsh-anchored-standard/preset/dev-tool-search.mjs +0 -131
  184. package/upstream/dsh-anchored-standard/preset/instruction-hint.mjs +0 -231
  185. package/upstream/dsh-anchored-standard/preset/preset.yml +0 -3
  186. package/upstream/dsh-anchored-standard/preset/skill-search.mjs +0 -142
  187. package/upstream/dsh-anchored-standard/preset/tool-bootstrap.mjs +0 -301
  188. /package/{preset → engine}/skill-search.mjs +0 -0
package/README.md CHANGED
@@ -1,222 +1,125 @@
1
- # 提示词工具(dsh-plugin-prompt-tool
2
-
3
- 把「Anchored Standard + dsh-router-standard 最优组合」做成 DSH 全家桶里的一键安装插件:插件启动时生成并维护 `~/.dsh/.agent-presets/prompt-tool/` 预设,首轮模型请求只看到官方 Minimal 精确双工具——持久 `bash` 与 `str_replace_editor`——和正确的 persona,没有运行时上下文与指令注入;锚定建立后进入 resident 目录,恢复常规注入,并在确认轨迹后注入 `preset.md`。同时提供 Web 界面在线编辑 `preset.md` / `AGENTS.md`、切换全部开关,以及可开关的 skills 技能层(含一键打开技能目录、设置自定义技能目录)。全部通过官方插件接口实现,不修改 DSH 源码。
4
-
5
- ## 原理
6
-
7
- DeepSeek V4 会强烈依赖 API 中可见的**首轮工具目录与 persona** 选择执行轨迹。完整 Standard 目录与自动注入在场会破坏 Minimal 轨迹,而全程 Minimal 又会失去重型工具。本项目把「首次轨迹选择」与「后续完整工具能力」拆开:
8
-
9
- 1. **干净首轮**:`context-gate` 清空首轮 runtime-context 并剥离自动注入;`tool-bootstrap` 只暴露 Minimal 双工具;`router-first-turn` 按主会话模型替换 persona——Pro 使用训练原句,Flash 自动采用 dsh-router-standard 的 Flash 弱路由人设(build/fix 分类 + 回顾锚 + 反跑题锚 + 先深想再产出)。
10
- 2. **晋升**:首次持久 `tool/call` 或 `assistant/message`(先到者为准)落地后,按 `usePtcMode` 开关选择 wire 形态——默认开启时切换为 Code Mode(PTC,单一 `run_code`),完整插件工具经生成 SDK 调用;关闭时恢复原生完整工具目录。
11
- 3. **任务引导**:可选 `near-anchor` 在首条真实用户消息后追加一次近距离首句引导(we/let 按任务自动选择);Flash 主会话晋升后 `router-guide` 按任务复杂度追加每轮深度引导。
12
- 4. **提示词注入**:we 锚定确认后把 `preset.md` 作为用户消息注入一次;we 未确认最多等一轮兜底,绝不卡死。
13
- 5. **子代理**:目录直接全量放行(仍受调用方工具白名单过滤);可选 `subagentFlash` 固定 Flash 路由 + 任务分类人设 + 三锚。
14
-
15
- 阶段全部从持久 session events 推导,resume / reload 不丢失状态。
16
-
17
- ## 稳定化控制
18
-
19
- 全部在生成 preset 的 `agent.cordis.yml` 行中配置:
20
-
21
- - `bootstrapMaxTokens`:首轮输出封顶。`0` = 本项目默认不设封顶(Web 界面显示 256000,即不设上限);正整数 = 请求 #1 的 `maxTokens`,晋升后自动剥离,不会焊进后续请求。不锁定 1024,任意正整数均可。
22
- - `context-gate`:未晋升期间关闭两条统一注入路径,pre-step 只保留 claimed 批次 + `allowKinds`(放行用户技能手势与 `near-anchor` / `router-guide`);晋升后差分恢复一条 runtime-context 消息。
23
- - `tool-bootstrap`:`promoteOn: either` 避免纯文字首答永久困在双工具;compaction 后回到 bootstrap + `compactionTools` 受控阶段。
24
- - `usePtcMode`(默认开启):晋升后把 wire 切换为 Code Mode(PTC,单一 `run_code`),完整插件工具经生成 SDK 调用;关闭时恢复原生完整工具目录。两种模式都不再依赖 `dev_tool_search`,生成 preset 时直接移除该行且不复制 `dev-tool-search.mjs`。
25
- - `router-first-turn`:只替换 persona 段,保留 plan-mode 段与第三方 section;首轮隐藏 `mnemon:*` 自动注入段,晋升后恢复。
26
- - `near-anchor`:行为引导放在真实用户消息之后(近距离零衰减),只要求首句一次;复杂规划任务放行 Let 深度路径,日常任务锚 We。
27
- - `router-guide`:简单任务快速收敛,复杂任务深度引导;子代理不注入,首轮不注入。
28
- - `prompt-injector`:注入状态以持久事件为准,跨进程重启 / 插件热重载不重复注入。
29
- - `injectAgentsPrompt`:开启时用 `AGENTS.md` 内容替换本地 instruction-hint 的默认提示文本;关闭时使用本地默认 hint(列出参考文件、按需读取)。
30
- - `skillSwitches`:扫描 `skills/*/SKILL.md` 注册可开关技能,未列出的技能默认开启。
31
- - `subagentFlash`:检测不到 DeepSeek 模型路由时 Web/TUI 禁用并强制降级为关闭。
32
-
33
- ## 安装
34
-
35
- 依据官方[《打包与安装插件》](https://deepseek-harness.github.io/deepseek-harness/develop/basic/publish)准则:
36
- `dsh plugin add` 只把**声明了 `dsh.bundle` 的直接依赖**追加进
37
- `dsh.profile.bundles`;`@deepseek-ai/dsh-web-app` 是随 DSH 安装自带的 in-box
38
- bundle(从 dsh 安装目录解析,不需要也不应写进 `dependencies`)。
39
-
40
- ### npm 安装与源码安装
41
-
42
- 两种安装源等价,后续初始化流程相同:
43
-
44
- ```sh
45
- # 方式 A:npm / registry 安装
46
- dsh plugin --profile prompt-tool add dsh-plugin-prompt-tool
47
-
48
- # 方式 B:本地源码安装(link 会覆盖 registry 依赖)
49
- dsh plugin --profile prompt-tool add link:<本仓库绝对路径>
50
- ```
51
-
52
- ### 初始化:启动一次即可
53
-
54
- ```sh
55
- dsh --profile prompt-tool
56
- ```
57
-
58
- 第一次启动只负责完成初始化。首次进程尚未挂载 Web 表面,这是预期行为;
59
- 自愈完成后**插件会自动退出(exit 0)**,无需手动停止:
60
-
61
- ```text
62
- prompt-tool: auto-added @deepseek-ai/dsh-web-app to dsh.profile.bundles for profile "prompt-tool"; next launch will mount the Web surface ...
63
- prompt-tool: initialization complete exiting so the repaired profile can be launched
64
- ```
65
-
66
- 这一次启动会自动完成:
67
-
68
- 1. **prompt-tool profile**:把 `@deepseek-ai/dsh-web-app` 补进
69
- `dsh.profile.bundles`,最终为
70
- `base web-app → dsh-plugin-prompt-tool`;
71
- 2. **web profile**:若存在,把 `dsh-plugin-prompt-tool` 写进它的
72
- `dependencies` + `bundles`(dependency 写法复用当前 profile 的安装
73
- spec)。**只写 package.json,不手工创建 node_modules 链接**;
74
- 3. **dsh-tui profile**:若存在且确实装有
75
- `@deepseek-harness-tui/dsh-tui`,同样写进 `dsh-plugin-prompt-tool`;
76
- **没有 dsh-tui 则整体跳过,不写入本插件**。dsh-tui 不需要
77
- `@deepseek-ai/dsh-web-app`,因此不会给它补 web-app。
78
-
79
- 所有写入幂等:文件已正确时不做任何改动。
80
-
81
- ### 初始化之后直接使用
82
-
83
- ```sh
84
- # Web:官方内置 profile,本插件已自动写入
85
- dsh web
86
-
87
- # TUI:dsh-tui 的安装流程已经物化过其 profile 依赖
88
- dsh-tui
89
- ```
90
-
91
- `dsh web` 随 dsh 安装必然存在;`dsh-tui` 则在其自身安装说明中已经执行过
92
- profile 依赖物化。因此初始化只需写入 package.json,不需要额外 `install`。
93
-
94
- 如果还想直接使用 `prompt-tool` 这个 profile 本身,再运行一次即可
95
- (第二次启动时 web-app 已由官方装配路径加载):
96
-
97
- ```sh
98
- dsh --profile prompt-tool
99
- ```
100
-
101
- > TUI 前提:先安装/初始化过 `@deepseek-harness-tui/dsh-tui` 并已生成
102
- > `dsh-tui` profile,再执行上面的初始化启动;否则按设计会跳过 dsh-tui
103
- > profile。之后补装 dsh-tui 时,重新执行一次
104
- > `dsh --profile prompt-tool` 即可把本插件补进 dsh-tui profile。
105
-
106
- ### 备选:直接把本插件装进官方 `web` 模板 profile
107
-
108
- `web` 是官方内置模板,初始 bundles 已含
109
- `@deepseek-ai/dsh-base` + `@deepseek-ai/dsh-web-app`:
110
-
111
- ```sh
112
- # registry 安装
113
- dsh plugin --profile web add dsh-plugin-prompt-tool
114
- # 本地开发安装
115
- dsh plugin --profile web add link:<本仓库绝对路径>
116
-
117
- # 启动
118
- dsh --profile web
119
- ```
120
-
121
- 完成初始化后,用 `dsh web`、`dsh-tui` 或 `dsh --profile prompt-tool` 启动,
122
- 新建空 session,预设选择 **prompt-tool**。插件会在启动时生成并刷新
123
- `~/.dsh/.agent-presets/prompt-tool/`(升级插件后重启即自动更新)。
124
-
125
- ### 卸载
126
-
127
- ```sh
128
- dsh plugin --profile prompt-tool remove dsh-plugin-prompt-tool
129
- ```
130
-
131
- 首次启动还会把包内 `skills/` 增量复制到**本插件自己的 profile** 目录下的
132
- `$DSH_HOME/profiles/prompt-tool/skills`,并优先使用这份副本(从 `dsh web`
133
- 或 `dsh-tui` 启动也一样写这里,不会写到 web/dsh-tui profile):已有同名文件不覆盖,
134
- 用户对副本的编辑会保留;包内新增技能文件会在下次启动补齐。想改回包内原始
135
- skills,删除该 `skills` 目录后重启即可(或在配置里显式设置 `skillsDir`)。
136
-
137
- ## 验证
138
-
139
- 导出 session JSONL,检查 `request/header`:
140
-
141
- - 第一份 header 的 `tools` 应恰好是 `["bash", "str_replace_editor"]`;
142
- - 第一轮只包含用户消息与首句锚点:没有 workspace 指令 baseline、运行时快照、skill 目录消息;
143
- - 首次工具调用或首次助手回复后,下一份变更 header 应包含 resident 目录:bootstrap 双工具 + `dev_tool_search` / `skill_search` / `skill_load` + 已解锁工具;
144
- - 此后的请求保持 resident 集,只经 `dev_tool_search` 显式解锁增长;
145
- - `we` 锚定确认后,事件流出现一次 `source.plugin === 'prompt-injector'` 的消息;未确认时最多等一轮兜底。
146
-
147
- 本项目测试:
148
-
149
- ```sh
150
- pnpm test # pnpm build + node --test
151
- pnpm typecheck # Host 与 Client 两个 tsc program
152
- pnpm lint # oxlint
153
- ```
154
-
155
- ## 行为与限制
156
-
157
- - Windows:DSH 的 PTY 后端仅支持 linux/darwin,持久 shell 组禁用;phase-1 的 `bash` 切换为 `custom-bash`——同名且 schema 与 Minimal 兼容,经普通跨平台子进程通道调起 Git Bash(运行时探测安装路径,不硬编码)。
158
- - Linux/macOS:持久 shell 的 `shellPath` 自适应——`/bin/bash` 存在时保持默认,不存在(如 NixOS)回退 PATH 里的 `bash`。
159
- - 首轮能力类提问可能基于被裁剪的双工具视图作答,晋升后由后续工具纠正;需要时可开启任务引导或直接首轮问任务类问题。
160
- - 工具目录只变化一次(晋升点),因此第一、二次请求之间发生一次前缀缓存变化;之后每次 `dev_tool_search` 解锁再变化。
161
- - preset 与 shell 访问具有相同信任等级,安装前可自行审阅 `upstream/` 与生成目录。
162
- - 插件只监听本机回环设置桥,不发起网络请求,也不增加遥测。
163
- - 不要在已经产生内容的会话中途切换 preset。
164
- - 需要 DSH 0.1.0-rc.7+(preset 机制、`system-prompt/assemble` 钩子与 keyed `settings.plugin.item` 插槽)。
165
-
166
- ## 构建与上游管理
167
-
168
- ```sh
169
- pnpm install
170
- pnpm build # 生成 lib/
171
- pnpm prepare # npm publish / git install 前自动触发
172
- pnpm sync:anchored # 从上游 main 刷新内联快照(可加 ref 参数)
173
- ```
174
-
175
- 上游 `dsh-anchored-standard` 以内联快照形式固化在 `upstream/dsh-anchored-standard/`(含 `LICENSE`、`NOTICE`、`REVISION`),对应提交见 `REVISION`。本项目运行时不直读上游任何文件:`preset/` 已自有化全部 `agent.cordis.yml` 与预设 JS 脚本(shared / context-gate / compaction-epoch / custom-bash / instruction-hint / skill-search / tool-bootstrap),生成时只注入 `usePtcMode` / `bootstrapMaxTokens` / `subagentFlash` 动态项;`upstream/` 仅用于溯源与 sync 对照。上游已转入维护期(2026-08-17);其 Project2 的 98/99/99 成绩来自当前实现之前的旧配置(issue #60),轨迹锚定有独立复现(#65),能力增益在小样本下未决(#51)。
176
-
177
- ## 许可
178
-
179
- 插件本体 MIT(Czerror)。首轮锚定机制源自 [xiaobright/dsh-anchored-standard](https://github.com/xiaobright/dsh-anchored-standard)(MIT),任务引导与 Flash 方案参考 [yjh051108/dsh-router-standard](https://github.com/yjh051108/dsh-router-standard)(MIT),缓存与工具面成本原则参考 [yjh051108/dsh-super-injector](https://github.com/yjh051108/dsh-super-injector)(MIT)。本地 `preset/` 下的 cordis 模板与 JS 脚本基于 DeepSeek Harness Standard 预设与上游 anchored-standard 修改,原始 DeepSeek 版权与 MIT 声明保留在 `upstream/dsh-anchored-standard/NOTICE` 与 `LICENSE`。
180
-
181
- ## 配置参考
182
-
183
- 挂载配置(cordis.patch.yml / profile patch):
184
-
185
- ```yaml
186
- - insert:
187
- - id: prompt-tool
188
- name: dsh-plugin-prompt-tool
189
- config:
190
- text: '' # 覆盖 preset.md 文本;默认读项目文件
191
- agentsText: '' # 覆盖 AGENTS.md 文本;默认读项目文件
192
- injectAgentsPrompt: false # 用 AGENTS.md 替换 instruction-hint 提示文本
193
- writeAgents: true # 写 ~/.dsh/AGENTS.md 受管块
194
- writePreset: true # 启用锚定预设(总开关)
195
- injectPrompt: true # we 确认后注入 preset.md
196
- skillSwitches: {} # 按 skills/* 目录名开关,未列出默认开启
197
- anchorFirstTurn: false # 追加任务引导
198
- anchorText: '' # 自定义引导文本(首句)
199
- anchorCustom: false # 使用自定义引导(首句)
200
- guideText: '' # 自定义引导文本(每轮)
201
- guideCustom: false # 使用自定义引导(每轮)
202
- subagentFlash: false # 子代理固定 Flash 模型
203
- subagentFlashProvider: 'deepseek-official'
204
- subagentFlashModel: 'deepseek-v4-flash'
205
- bootstrapMaxTokens: 0 # 首轮输出封顶:0=关闭;正整数=请求 #1 maxTokens
206
- usePtcMode: true # 使用 PTC 模式:true=晋升后切换为 Code Mode(run_code);false=恢复原生完整目录
207
- skillsDir: '' # 用户自定义技能目录;空 = 自动使用 prompt-tool profile 下 skills/ 副本
208
- skillRankBase: 250 # 技能候选排序基数
209
- residentAgentsPath: '' # 默认 ~/.dsh/AGENTS.md
210
- presetDir: '' # 默认 ~/.dsh/.agent-presets/prompt-tool/
211
- presetOrder: 5 # preset 显示顺序
212
- fallbackText: '' # preset.md 缺失或不可读时的回退文本
213
- ```
214
-
215
- TUI 命令:
216
-
217
- ```text
218
- /prompt-tool status
219
- /prompt-tool on|off|toggle <开关>
220
- /prompt-tool skill <技能目录名> on|off|toggle
221
- /prompt-tool bootstrapMaxTokens <正整数|0>
222
- ```
1
+ # dsh-plugin-prompt-tool — 层级提示词注入器
2
+
3
+ > 一切皆可注入:把 DSH 官方开放的全部注入层级收敛为一个可配置提示词注入引擎——注入什么、注入到哪一层、何时注入,全由提示词配置决定。
4
+
5
+ DSH 生态的提示词注入标准层:一个 `prompt-config-engine.mjs` 接线官方六个注入层级(`agent/pre-step`、`systemPrompt.section`、`systemPrompt.context`、`agent/request`、`llm/stream`、`tools/*`),内置 anchored 默认预设,开箱即用。
6
+
7
+ > 策略来源:工具目录锚定 [dsh-anchored-standard](https://github.com/xiaobright/dsh-anchored-standard)、近距离引导 [dsh-router-standard](https://github.com/yjh051108/dsh-router-standard)、缓存铁律 [dsh-super-injector](https://github.com/yjh051108/dsh-super-injector)。
8
+
9
+ ## 安装
10
+
11
+ ```bash
12
+ dsh plugin --profile prompt-tool add dsh-plugin-prompt-tool # npm 安装
13
+ dsh plugin --profile prompt-tool add link:<本仓库绝对路径> # 本地源码(link 覆盖 registry)
14
+ dsh --profile prompt-tool # 首次启动自动补 dsh-web-app,二次启动生效
15
+ ```
16
+
17
+ 需要 DSH `0.1.1-rc.1+`。
18
+
19
+ ## 特性
20
+
21
+ - 🔌 **六层一次接线**:一个引擎注册全部可注入层级,共享同一套过滤与降级语义
22
+ - ✍️ **一切皆可配置**:`layer / strategy / position / promotion / subagents / modelScope / mergeMode / order / text / texts / fill / variables / params` 全开放
23
+ - 🧑‍🤝‍🧑 **子代理三态**:`subagents: none / inherit / only`,身份类提示词可只注入子代理
24
+ - 🗂️ **内容与执行分离**:每条提示词配置一个 yml/json `prompt-configs/`,引擎按文件名数字前缀顺序扫描
25
+ - 🧩 **三源合并**:默认提示词配置 < 目录文件 < settings 数组,同名 `id` 覆盖
26
+ - 🖥️ **独立工作台**:侧边栏「提示词工具」入口(主会话/子代理/注入层/技能设置/预设配置五页)+ 设置面板提示词配置页(列表/表单/模板插入/保存前校验)
27
+ - 🧪 **七种内容策略**:`static / first-turn-anchor / guide-auto / custom-fallback / instruction-hint / placeholder / world-book`
28
+ - 🛡️ **失败不伤会话**:单条失败跳过 + `warnOnce`;配置错误挂载时 fail loud;`dedupe: session` 持久幂等
29
+ - 🎭 **SillyTavern 导入**:JSON 预设卡片一键转换为本地预设——`prompts[]` 映射提示词配置、采样参数进 `params.model*`、`enable_web_search` 按开关装配工具
30
+ - 🎴 **角色卡库**:SillyTavern 角色卡(PNG tEXt chunk `ccv3`/`chara`,或 chara_card JSON)导入独立库(`.characters/<id>/`,含原图/转换参数/角色记忆),按需「导入到当前预设」(`chara-<卡>-` 前缀合并、幂等可移除),多文件自动合并
31
+ - 📚 **世界书**:`character_book` world-book 策略配置(`keys` 命中触发 / `constant` 常驻 / `useRegex` 正则),与模块卡片同一存储与编辑(模块列表「世界书」过滤 + 批量启用/禁用);ST 变量规则(`setvar`/`getvar` 含默认值)由 params fallback 插值承载
32
+
33
+ ## 预设参数体系
34
+
35
+ 预设行为由一份 `preset.yml` 单一配置源下发,共四层默认值,各层职责不重叠:
36
+
37
+ | | 职责 |
38
+ |---|---|
39
+ | `hostDefaults` | settings 层默认值(开关/路径),被用户 settings 覆盖 |
40
+ | `params` | 引擎行为默认(锚定/引导/PTC/门控/模型/工具),被运行时 settings 覆盖 |
41
+ | `moduleConfigs` | 引擎组合行级 config(persona 文本/超时/白名单) |
42
+ | `promptConfigs` | 注入提示词配置(策略/层/位置/时机),与目录、settings 三源合并 |
43
+
44
+ ### params 一览(全部可选,缺省 = 官方默认)
45
+
46
+ | 分类 | |
47
+ |---|---|
48
+ | 锚定 | `firstTurnAnchor` `firstTurnCustom` `firstTurnText` `firstTurnWord` `firstTurnBuild` `firstTurnInspect` `firstTurnDeep` |
49
+ | 引导 | `guideCustom` `guideText` `guideComplexPattern` `guideWeak` `guideDeep` `buildPattern` `complexPattern` |
50
+ | PTC/门控 | `usePtcMode` `bootstrapMaxTokens` `injectPrompt` `allowKinds` |
51
+ | 主对话模型 | `modelProvider` `modelName` `modelReasoningEffort` `modelTemperature` `modelMaxTokens` |
52
+ | 子代理模型 | `subagentModelProvider` `subagentModelName` `subagentReasoningEffort` `subagentTemperature` `subagentMaxTokens` |
53
+ | 人设 | `mainPersona`(主对话 Flash 档)`subagentPersona`(子代理,回退 `mainPersona` → 继承主会话) |
54
+ | 工具集 | `toolFilterAllow` `toolFilterDeny`(子代理 toolFilter;主对话 tool-filter 模块共用) |
55
+ | 深度 | `maxDepth`(0 禁止委派 / `provider-managed` / 正整数) |
56
+
57
+ > 根目录 **`preset.yml`** 是配置参数齐全、逐项注释的完整模板,复制即得自定义预设起点。
58
+
59
+ ## 提示词配置(六层全家桶)
60
+
61
+ | `layer` | 官方通道 | 关键参数 |
62
+ |---|---|---|
63
+ | `pre-step` | `agent/pre-step` 消息批(默认层) | `position / dedupe / promotion / subagents / modelScope / strategy` |
64
+ | `system-section` | `ctx.systemPrompt.section` 静态段 | `order / text / templateFile / variables / params.complete / params.sectionName` |
65
+ | `runtime-context` | `ctx.systemPrompt.context` 动态快照 | `order / text / variables / params.contextName` |
66
+ | `agent-request` | `agent/request`(LlmCallConfig) | `params.patch`(浅合并)/ `params.replace`(整体替换) |
67
+ | `llm-stream` | `llm/stream`(流包装) | `params.mode=pass\|replace` |
68
+ | `tool-pipeline` | `tools/*`(pre/execute/post) | `params.toolNames`、`preDecision=allow\|deny\|ask`、`postAction=accept\|replace\|block` |
69
+
70
+ 默认四条:`00-near-anchor`(首句锚点)、`10-router-guide`(每轮引导)、`20-prompt-injector`(we 确认后注入 preset.md 一次)、`30-instruction-hint`(指令文件提示)。
71
+
72
+ - `mergeMode`:`separate`(默认)同位置多条为独立消息;`merged` 同位置拼接为一条
73
+ - `order`:数值小者更靠近插入锚点,同时决定 `merged` 组内拼接顺序
74
+ - 文本插值:仅 `pre-step` 支持内置环境变量与 filler 变量;`system-section` 额外走官方 `{{variable}}` 渲染
75
+
76
+
77
+ ## SillyTavern 导入
78
+
79
+ 工作台「预设配置」页导入 SillyTavern JSON 预设卡片(导入包无定义文件、仅含单个 `.json` 时自动识别转换),按注入层级映射为本地预设:
80
+
81
+ - `prompts[]` → `promptConfigs`:`system_prompt + role=system` → `system-section`(多条可 `mergeMode: merged` 拼接);其余 → `pre-step`(`injection_position=0` → `before-all`,否则 `after-user`);OFF 状态与 `injection_order` 原样保留
82
+ - 采样参数 → 顶层 `params.model*`:`temperature` / `openai_max_tokens` / `reasoning_effort`
83
+ - `enable_web_search`:`true` → 组装 `tool-web`(fetch 启用);`false` → 不组装,改加 `tool-filter` 黑名单 `web_search / web_fetch`
84
+ - `modules` 按需装配:`prompt-config-engine` 始终;含 system-section 时补 `persona`(`complete: false` 允许 system 段生效)
85
+
86
+ 转换结果是一个普通预设(id 由文件名生成),可在工作台预设切换器中直接使用。字段级参数对照与完整示例见 [SillyTavern.md](SillyTavern.md)。
87
+
88
+ ### 角色卡(PNG / JSON)与角色卡库
89
+
90
+ 工作台「角色管理」页导入角色卡到**角色卡库**(`~/.dsh/.agent-presets/.characters/<id>/`):
91
+
92
+ - **PNG**:tEXt chunk(`ccv3` 优先 / `chara` 兜底)base64 解析,原图存 `avatar.png`(字节无损)
93
+ - **JSON**:chara_card_v2/v3 直接转换;多文件(角色卡 × 响应预设)自动合并
94
+ - 正文映射:`first_mes` → 开场白(`dedupe: session`)、`alternate_greetings` 备用开场白、
95
+ `description/personality/scenario` 角色设定、采样参数 → `params.model*`
96
+ - **导入到当前预设**:参数合并进当前预设 promptConfigs(`chara-<卡>-` 前缀、幂等);可一键移除
97
+ - **角色记忆**:`memory.md` 跟随角色卡跨预设,应用时合并为 world-book constant 配置注入
98
+
99
+ ### 世界书(world-book 策略)
100
+
101
+ `character_book` 条目转 world-book 策略配置(与普通模块同一存储/编辑):
102
+
103
+ - **注入语义**:`constant` 常驻注入;有 `keys` 命中聊天内容才注入;无 keys 全局每次注入
104
+ - **匹配选项**:`caseSensitive` / `wholeWords` / `useRegex`(keys 按正则)
105
+ - **管理**:模块列表顶部下拉选「世界书」过滤(完整模块卡片编辑 + 批量启用/禁用);
106
+ 模型工具 `world_book_list/upsert/delete`(`note` 写入角色卡记忆)
107
+ - **ST 变量**:`setvar` 收集进 params、`getvar`(含默认值)改写为 `{{key}}` 由引擎插值兜底;
108
+ `trim`/注释/ERA 剥离,`{{user}}`/`{{char}}` 替换;TavernHelper 扩展注入物自动剥离
109
+
110
+ 详细转换规则见 [SillyTavern.md](SillyTavern.md)。
111
+
112
+ ## 开发与验证
113
+
114
+ ```sh
115
+ pnpm install && pnpm build
116
+ pnpm test # 235 单测:渲染/合并/六层接线/preset 生成
117
+ pnpm typecheck && pnpm lint
118
+ pnpm sync:anchored # 刷新 upstream/dsh-anchored-standard 内联快照
119
+ pnpm sync:yaml # 刷新 engine/vendor/yaml(生成目录运行时 YAML 解析器)
120
+ pnpm rebuild:composition # 从官方内置预设源码重建组合模块
121
+ ```
122
+
123
+ ## 许可
124
+
125
+ 插件本体 MIT(Czerror)。默认预设策略来源见顶部引用;`preset/` 下 cordis 模板与脚本基于 DeepSeek Harness 官方 Standard 预设修改,版权声明见 `upstream/dsh-anchored-standard/`。
@@ -0,0 +1,139 @@
1
+ /**
2
+ * Epoch-aware promotion tracker shared by the bootstrap and baseline-gate
3
+ * plugins of the anchored presets.
4
+ *
5
+ * A compaction rewrites the model-visible surface: the pre-compaction
6
+ * conversation collapses into one synthetic summary message, and the
7
+ * workspace-instruction baseline is re-injected from scratch. The first
8
+ * post-compaction request is therefore a "second first request" — the same
9
+ * first-token conditions the anchored presets exist to control. Promotion is
10
+ * epoch-aware: only a durable promotion signal (`tool/call` and/or
11
+ * `assistant/message`, per the caller's `promoteEvents`) recorded AFTER the
12
+ * last `compaction/end` boundary counts as promoted. Before any compaction
13
+ * the boundary is -1, which preserves the original one-shot semantics.
14
+ *
15
+ * State is memoized per session id and maintained incrementally through
16
+ * `observe()`; a cold session scans its durable log once (so resume and
17
+ * reload reconstruct the same phase), then O(1).
18
+ *
19
+ * By default subagents (`delegationDepth > 0`) are treated as already
20
+ * promoted so their first request can use tools. Set `includeSubagents: true`
21
+ * to make subagents follow the same bootstrap/anchor phase as top-level
22
+ * sessions.
23
+ *
24
+ * GATE MODE (liangshen 稳定化扩展, source: xiaobright/dsh-anchored-standard
25
+ * MIT + phase-1 quarantine): `promoteGate: true` gates the promotion on the
26
+ * first reasoning block classifying minimal-like (`we` present, no `let me`),
27
+ * with a `maxPromoteSteps` (default 4) fallback; `promoteAfterFirstResponse:
28
+ * true` promotes a tool-less first response once it has responded, and also
29
+ * releases an anchor-gated session when its first turn ends. Gate mode uses
30
+ * the durable-event state machine below and ignores `promoteEvents` (fixed
31
+ * either semantics: `tool/call` and `assistant/message` are both tracked).
32
+ * Non-gate mode keeps the original event-set semantics byte-for-byte.
33
+ */
34
+
35
+ /** 首段 reasoning 块分类(liangshen 移植):we 且无 let me = minimal-like。 */
36
+ export function classifyReasoning(text) {
37
+ const trimmed = String(text ?? '').trim()
38
+ const we = [...trimmed.matchAll(/\bwe\b/gi)].length
39
+ const letMe = [...trimmed.matchAll(/\blet me\b/gi)].length
40
+ const metrics = { we, letMe }
41
+ if (we > 0 && letMe === 0) return { label: 'minimal-like', score: 4, metrics }
42
+ if (letMe > 0) return { label: 'standard-like', score: -4, metrics }
43
+ return { label: 'ambiguous', score: 0, metrics }
44
+ }
45
+
46
+ /** 首段 reasoning 块是否为 minimal-like(后续块不覆盖首个标准样块)。 */
47
+ export function hasAnchoredReasoning(content) {
48
+ if (!Array.isArray(content)) return false
49
+ const first = content.find((block) => block?.type === 'reasoning')
50
+ return first !== undefined && classifyReasoning(first.text).label === 'minimal-like'
51
+ }
52
+
53
+ /** Build one epoch-aware promotion tracker. */
54
+ export function createEpochPromotion(promoteEvents, options = {}) {
55
+ const includeSubagents = options.includeSubagents === true
56
+ const promoteGate = options.promoteGate === true
57
+ const promoteAfterFirstResponse = options.promoteAfterFirstResponse === true
58
+ const maxPromoteSteps = Number.isSafeInteger(options.maxPromoteSteps) && options.maxPromoteSteps > 0
59
+ ? options.maxPromoteSteps
60
+ : 4
61
+ const promote = new Set(promoteEvents)
62
+ const gated = promoteGate || promoteAfterFirstResponse
63
+ /** sessionId -> entry(boundary/promoted + 门控字段) */
64
+ const state = new Map()
65
+
66
+ const freshEntry = (boundary) => ({
67
+ boundary,
68
+ promoted: false,
69
+ toolCalled: false,
70
+ responded: false,
71
+ anchored: false,
72
+ turnEnded: false,
73
+ steps: 0,
74
+ })
75
+
76
+ /** 门控晋升判定(liangshen decidePromotion 移植)。 */
77
+ const decideGate = (entry) => {
78
+ if (entry.promoted) return true
79
+ if (entry.toolCalled && !promoteGate) return true
80
+ if (entry.toolCalled && promoteGate && (entry.anchored || entry.steps >= maxPromoteSteps)) return true
81
+ if (entry.toolCalled && promoteGate && promoteAfterFirstResponse && entry.turnEnded) return true
82
+ if (!entry.toolCalled && entry.responded && promoteAfterFirstResponse) return true
83
+ return false
84
+ }
85
+
86
+ /** 应用一个事件;compaction/end 返回新 entry(旧状态清零、boundary 前推)。 */
87
+ const applyEvent = (entry, event) => {
88
+ const seq = event.seq ?? 0
89
+ if (event.type === 'compaction/end') return freshEntry(seq)
90
+ if (seq <= entry.boundary) return entry
91
+ if (gated) {
92
+ if (event.type === 'tool/call') entry.toolCalled = true
93
+ else if (event.type === 'step/start') entry.steps += 1
94
+ else if (event.type === 'turn/end') entry.turnEnded = true
95
+ else if (event.type === 'assistant/message') {
96
+ entry.responded = true
97
+ if (!entry.anchored) entry.anchored = hasAnchoredReasoning(event.data?.message?.content)
98
+ }
99
+ if (decideGate(entry)) entry.promoted = true
100
+ return entry
101
+ }
102
+ if (promote.has(event.type)) entry.promoted = true
103
+ return entry
104
+ }
105
+
106
+ /** Scan a session's durable log from scratch (cold start / resume). */
107
+ const scan = (session) => {
108
+ let entry = freshEntry(-1)
109
+ for (const event of session.events) entry = applyEvent(entry, event)
110
+ state.set(session.id, entry)
111
+ return entry
112
+ }
113
+
114
+ return {
115
+ /**
116
+ * Current phase of the agent's session.
117
+ * @param agent - the assembly/pre-step agent, or undefined outside an agent.
118
+ * @returns { boundary, promoted } — `boundary` is the last compaction/end
119
+ * seq (-1 before any compaction); `promoted` is true when a durable
120
+ * promotion signal exists after that boundary.
121
+ */
122
+ status(agent) {
123
+ if (agent === undefined) return { boundary: -1, promoted: true }
124
+ const session = agent.session
125
+ if (session === undefined) return { boundary: -1, promoted: true }
126
+ // By default subagents keep the full catalog from their very first
127
+ // request; includeSubagents makes them follow the normal bootstrap phase.
128
+ if (!includeSubagents && (session.header?.delegationDepth ?? 0) > 0) return { boundary: -1, promoted: true }
129
+ return state.get(session.id) ?? scan(session)
130
+ },
131
+ /** Incremental feed: call on every `session/event`. */
132
+ observe(session, event) {
133
+ const entry = state.get(session.id)
134
+ if (entry === undefined) return
135
+ const next = applyEvent(entry, event)
136
+ if (next !== entry) state.set(session.id, next)
137
+ },
138
+ }
139
+ }
@@ -0,0 +1,19 @@
1
+ # module: bootstrap-filesystem
2
+ # source: E:\Documents\GitHub\deepseek-harness/apps/cli/config/agent-presets/minimal/agent.cordis.yml
3
+ # local patches: 1
4
+
5
+ - id: bootstrap-filesystem
6
+ name: cordis:group
7
+ group: true
8
+ isolate:
9
+ fs: true
10
+ config:
11
+ - id: fs-local
12
+ name: '@deepseek-ai/dsh-fs-local'
13
+ config:
14
+ cwd: !!js process.env.DSH_CWD ?? process.cwd()
15
+
16
+ - id: str-replace-editor
17
+ name: '@deepseek-ai/dsh-tool-str-replace-editor'
18
+ config:
19
+ maxOutputChars: 16000
@@ -0,0 +1,52 @@
1
+ # module: compaction
2
+ # source: E:\Documents\GitHub\deepseek-harness/apps/cli/config/agent-presets/standard/agent.cordis.yml
3
+ # local patches: 0
4
+
5
+ # ── compaction ──────────────────────────────────────────────────────────────
6
+
7
+ # `compaction-basic` reads `toolResultPrune` through `ctx.get`, so the pruner must
8
+ # share this realm rather than sit outside it.
9
+ #
10
+ # `tokenMeter` is deliberately NOT in this realm: the meter stays on the HOST
11
+ # plane, and the rows here resolve that one instance. It takes no configuration,
12
+ # keys every fold by Session, and owns the context-meter projection units the
13
+ # browser reads for every session — behind a realm those units would come and go
14
+ # with whichever presets happen to be mounted. What a preset chooses is whether
15
+ # its agent compacts at all, which is `compaction-basic` below.
16
+ - id: compaction
17
+ name: cordis:group
18
+ group: true
19
+ isolate:
20
+ compaction: true
21
+ toolResultPruner: true
22
+ config:
23
+ - id: compaction-basic
24
+ name: '@deepseek-ai/dsh-compaction-basic'
25
+
26
+ - id: command-compact
27
+ name: '@deepseek-ai/dsh-command-compact'
28
+
29
+ - id: tool-result-pruner
30
+ name: '@deepseek-ai/dsh-compaction-tool-result-pruner'
31
+ config:
32
+ thresholdChars: 8192
33
+ headChars: 4096
34
+ tailChars: 1024
35
+
36
+ # ── delegation and workflows ────────────────────────────────────────────────
37
+
38
+ # The `subagents` registry and its spawn/fork backends live in the HOST
39
+ # composition: the registry is a process singleton whose cross-session queries
40
+ # the api-proxy serves to the browser, and a provider name may only be
41
+ # registered once. This preset contributes the delegation TOOLS, which resolve
42
+ # that host registry.
43
+ #
44
+ # `workflows` is different — nothing outside an agent reads it — so every row
45
+ # that reaches it shares one entry-local realm here, and a consumer left
46
+ # outside would resolve a host registry this preset does not populate.
47
+ #
48
+ # `tool-subagent-report` is host-plane for the same reason as the registry,
49
+ # not because a preset may not want it: it registers a CONTINUABLE SETUP on
50
+ # that singleton rather than a tool this agent calls, and the setup list is
51
+ # not scope-aware — one copy per mounted preset means every child gets
52
+ # `report` registered once per live session, which throws on the second.
@@ -0,0 +1,40 @@
1
+ # module: context-gate
2
+ # source: preset/engine/compositions/source/local/context-gate.yml (本地附加,非官方模块)
3
+
4
+ - id: context-gate
5
+ name: ./engine/context-gate.mjs
6
+ config:
7
+ promoteOn: either
8
+ includeSubagents: false
9
+ allowKinds: __ALLOW_KINDS__
10
+
11
+ # ── bootstrap ───────────────────────────────────────────────────────────────
12
+
13
+ # Tool catalog control (mode-owned tool-bootstrap.mjs). V4 Pro conditions
14
+ # strongly on the API tool catalog AND the first request output budget:
15
+ # request #1 exposes the OFFICIAL Minimal preset's real tool pair —
16
+ # persistent `bash` + `str_replace_editor` — which anchors at the
17
+ # adapter-default maxTokens (256000) with no output cap needed (issue #11:
18
+ # 5/5 anchored vs 11/11 standard-like for every standard-family schema);
19
+ # after the session records its first durable promotion signal (a tool call OR
20
+ # the first assistant message, default `promoteOn: either`), later steps keep
21
+ # the assembled catalog and usePtcMode optionally switches the wire to Code
22
+ # Mode (PTC). `bootstrapMaxTokens` is
23
+ # opt-in for standard-schema bootstraps; unset, the adapter default flows. See
24
+ # tool-bootstrap.mjs for the other triggers. Context stripping is NOT here —
25
+ # the context-gate row above owns it.
26
+ #
27
+ # POST-PROMOTION (prompt-tool local addition): both modes keep the assembled
28
+ # catalog after promotion. `usePtcMode` switches the wire presentation to Code
29
+ # Mode (PTC, a single run_code backed by the full registry SDK) instead of
30
+ # narrowing the resident set; the pre-promotion and post-compaction controlled
31
+ # phase below still stays on the bootstrap pair + `compactionTools`.
32
+ #
33
+ # COMPACTION (local addition): after `compaction/end` the session falls back
34
+ # to the controlled phase — bootstrap pair + `compactionTools` — until a NEW
35
+ # durable promotion signal exists past the boundary (epoch-aware, see
36
+ # compaction-epoch.mjs).
37
+ #
38
+ # `includeSubagents: true` keeps the subagent phase in sync with the
39
+ # context-gate row: a subagent's first request sees the bootstrap pair, then
40
+ # its own first reply or tool call promotes it to the assembled catalog.
@@ -0,0 +1,14 @@
1
+ # module: custom-bash
2
+ # source: preset/engine/compositions/source/local/custom-bash.yml (本地附加,非官方模块)
3
+
4
+ - id: custom-bash
5
+ name: ./engine/custom-bash.mjs
6
+ disabled: !!js process.platform !== 'win32'
7
+ config:
8
+ timeoutMs: 120000
9
+ maxOutputBytes: 64000
10
+
11
+ # ── filesystem ──────────────────────────────────────────────────────────────
12
+
13
+ # Both register into the host `tools` registry and provide nothing, so
14
+ # they need no realm. The `fs` service and its policy stay in the host.