dsh-plugin-prompt-tool 2.1.0 → 3.0.1

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 (206) hide show
  1. package/README.md +100 -233
  2. package/engine/actions/append-context.mjs +3 -24
  3. package/engine/actions/assembly.mjs +70 -94
  4. package/engine/actions/catalog.mjs +65 -28
  5. package/engine/actions/content.mjs +8 -152
  6. package/engine/actions/examples.mjs +8 -4
  7. package/engine/actions/inbox-prepend.mjs +4 -5
  8. package/engine/actions/index.mjs +17 -9
  9. package/engine/actions/inject-text.mjs +24 -4
  10. package/engine/actions/pre-step-filter.mjs +3 -4
  11. package/engine/actions/registration.mjs +20 -28
  12. package/engine/actions/request-params.mjs +21 -1
  13. package/engine/actions/shared.mjs +22 -13
  14. package/engine/actions/stream-output.mjs +26 -0
  15. package/engine/actions/tool-gate.mjs +31 -0
  16. package/engine/actions/tool-result.mjs +36 -0
  17. package/engine/actions/tool-visibility.mjs +248 -0
  18. package/engine/agent-capability.mjs +67 -0
  19. package/engine/anchor-match.mjs +14 -21
  20. package/engine/audience.d.mts +2 -0
  21. package/engine/audience.mjs +102 -0
  22. package/engine/branch.d.mts +4 -0
  23. package/engine/branch.mjs +61 -18
  24. package/engine/compaction-epoch.d.mts +25 -0
  25. package/engine/compaction-epoch.mjs +27 -4
  26. package/engine/compositions/source/local/filesystem-editor.yml +3 -3
  27. package/engine/compositions/source/local/instruction-hint.yml +2 -4
  28. package/engine/compositions/source/local/module-file-tools.yml +2 -0
  29. package/engine/compositions/source/local/module-import-tools.yml +4 -0
  30. package/engine/compositions/source/local/module-manifest-tools.yml +2 -0
  31. package/engine/compositions/source/local/module-rule-tools.yml +5 -0
  32. package/engine/compositions/source/local/module-variable-tools.yml +5 -0
  33. package/engine/compositions/source/local/present-as.yml +26 -0
  34. package/engine/compositions/source/local/tool-config-engine.yml +2 -3
  35. package/engine/compositions/source/local/tool-search.yml +11 -0
  36. package/engine/condition-facts.mjs +84 -0
  37. package/engine/conditions/anchor.mjs +63 -23
  38. package/engine/conditions/availability.mjs +1 -1
  39. package/engine/conditions/composite.mjs +3 -3
  40. package/engine/conditions/count.mjs +42 -11
  41. package/engine/conditions/evaluation.mjs +74 -19
  42. package/engine/conditions/examples.mjs +2 -1
  43. package/engine/conditions/index.d.mts +15 -0
  44. package/engine/conditions/index.mjs +23 -9
  45. package/engine/conditions/operators.mjs +4 -0
  46. package/engine/conditions/phase.mjs +9 -3
  47. package/engine/conditions/preset.mjs +1 -1
  48. package/engine/conditions/session.mjs +8 -2
  49. package/engine/conditions/subject.mjs +144 -65
  50. package/engine/conditions/text.mjs +26 -8
  51. package/engine/conditions/variable.mjs +83 -0
  52. package/engine/context-activation.d.mts +11 -0
  53. package/engine/{st-world-book.mjs → context-activation.mjs} +104 -64
  54. package/engine/delivery.d.mts +2 -0
  55. package/engine/delivery.mjs +93 -0
  56. package/engine/discovery.d.mts +38 -0
  57. package/engine/discovery.mjs +146 -0
  58. package/engine/env-safety.mjs +14 -0
  59. package/engine/executor.d.mts +28 -0
  60. package/engine/executor.mjs +290 -205
  61. package/engine/fillers.mjs +39 -8
  62. package/engine/fixed-registration.mjs +12 -0
  63. package/engine/history.mjs +71 -0
  64. package/engine/instruction-blocks.d.mts +13 -0
  65. package/engine/instruction-blocks.mjs +21 -0
  66. package/engine/instruction-files.d.mts +5 -0
  67. package/engine/instruction-files.mjs +97 -0
  68. package/engine/instruction-hint.mjs +69 -103
  69. package/engine/interpolate.d.mts +7 -0
  70. package/engine/interpolate.mjs +44 -13
  71. package/engine/layers.mjs +163 -227
  72. package/engine/machine-paths.mjs +40 -0
  73. package/engine/module-file-tools.mjs +8 -0
  74. package/engine/module-import-tools.mjs +10 -0
  75. package/engine/module-manifest-tools.mjs +8 -0
  76. package/engine/module-rule-tools.mjs +10 -0
  77. package/engine/module-variable-tools.mjs +10 -0
  78. package/engine/order.d.mts +14 -0
  79. package/engine/order.mjs +0 -3
  80. package/engine/path-safety.d.mts +2 -0
  81. package/engine/path-safety.mjs +58 -0
  82. package/engine/pre-step-source.d.mts +69 -0
  83. package/engine/pre-step-source.mjs +103 -0
  84. package/engine/present-as.mjs +77 -0
  85. package/engine/promotion-pool.d.mts +9 -0
  86. package/engine/promotion-pool.mjs +69 -0
  87. package/engine/record.mjs +2 -0
  88. package/engine/rule-engine.mjs +3 -2
  89. package/engine/rule-facts.d.mts +11 -0
  90. package/engine/rule-facts.mjs +60 -0
  91. package/engine/rule-runtime.d.mts +46 -0
  92. package/engine/rule-runtime.mjs +98 -13
  93. package/engine/rule-spec.d.mts +106 -0
  94. package/engine/rule-spec.mjs +301 -27
  95. package/engine/run-code-env.mjs +73 -19
  96. package/engine/schema.mjs +165 -243
  97. package/engine/sdk-strip.mjs +2 -2
  98. package/engine/service-names.d.mts +10 -0
  99. package/engine/service-names.mjs +10 -0
  100. package/engine/shared.d.mts +21 -0
  101. package/engine/shared.mjs +46 -13
  102. package/engine/skill-search.mjs +125 -53
  103. package/engine/source-kind.d.mts +9 -0
  104. package/engine/source-kind.mjs +16 -0
  105. package/engine/strategy-ids.mjs +5 -0
  106. package/engine/template-evaluation.d.mts +16 -0
  107. package/engine/template-evaluation.mjs +178 -0
  108. package/engine/template-frame.d.mts +16 -0
  109. package/engine/template-frame.mjs +69 -0
  110. package/engine/tool-config-engine.mjs +38 -34
  111. package/engine/tool-definition.d.mts +4 -0
  112. package/engine/tool-definition.mjs +5 -1
  113. package/engine/tool-git-bash.mjs +5 -1
  114. package/engine/tool-scope.mjs +22 -0
  115. package/engine/{dev-tool-search.mjs → tool-search.mjs} +63 -65
  116. package/engine/trigger.mjs +15 -270
  117. package/engine/vendor/yaml/dist/compose/resolve-flow-scalar.js +19 -18
  118. package/engine/vendor/yaml/dist/nodes/Alias.js +25 -23
  119. package/engine/vendor/yaml/package.json +1 -1
  120. package/lib/client.js +8312 -6724
  121. package/lib/client.js.map +1 -1
  122. package/lib/index.d.mts +16 -2120
  123. package/lib/index.mjs +26914 -5816
  124. package/modules/ponytail/module.yml +83 -203
  125. package/modules/ptc-mode/module.yml +45 -0
  126. package/modules/soul/assets/core-hard.md +6 -0
  127. package/modules/soul/assets/criteria.md +12 -0
  128. package/modules/soul/assets/echo.md +12 -0
  129. package/modules/soul/assets/layers.md +11 -0
  130. package/modules/soul/assets/ledger.md +9 -0
  131. package/modules/soul/assets/manifest.yml +20 -0
  132. package/modules/soul/assets/reference/00-layers.md +27 -0
  133. package/modules/soul/assets/reference/01-criteria.md +32 -0
  134. package/modules/soul/assets/reference/02-echo.md +161 -0
  135. package/modules/soul/assets/reference/03-vital.md +183 -0
  136. package/modules/soul/assets/reference/04-manifest.json +106 -0
  137. package/modules/soul/assets/reference/05-doctor.md +67 -0
  138. package/modules/soul/assets/reference/06-reference.md +189 -0
  139. package/modules/soul/assets/reference/07-bundle.json +431 -0
  140. package/modules/soul/assets/reference/08-/350/270/251/345/235/221/345/256/236/345/275/225.md +59 -0
  141. package/modules/soul/assets/reference/09-dev-workflow.md +109 -0
  142. package/modules/soul/assets/reference/10-echo-anatomy.md +109 -0
  143. package/modules/soul/assets/reference/11-self.md +80 -0
  144. package/modules/soul/assets/reference/12-ledger.md +159 -0
  145. package/modules/soul/assets/reference/ECHO-/346/235/203/345/250/201/345/217/243/345/276/204.md +202 -0
  146. package/modules/soul/assets/reference/ECHO/345/205/255/345/261/202/344/270/216mnemon/345/215/217/345/220/214/350/257/264/346/230/216/344/271/246.md +229 -0
  147. package/modules/soul/assets/reference/README.md +12 -0
  148. package/modules/soul/assets/templates/agents-template.md +6 -0
  149. package/modules/soul/assets/vital.md +9 -0
  150. package/modules/soul/module.yml +311 -0
  151. package/modules/superpowers/module.yml +122 -0
  152. package/modules/tool-surface/module.yml +51 -47
  153. package/package.json +37 -40
  154. package/skills/dsh-module/SKILL.md +67 -147
  155. package/skills/dsh-module/reference.md +113 -86
  156. package/templates/10-pre-step.yml +2 -3
  157. package/templates/14-first-turn-anchor.yml +10 -14
  158. package/templates/15-guide-auto.yml +32 -28
  159. package/templates/16-custom-fallback.yml +33 -21
  160. package/templates/20-system-section.yml +1 -4
  161. package/templates/50-llm-stream.yml +4 -10
  162. package/templates/60-tool-pipeline.yml +12 -10
  163. package/templates/63-append-context.yml +4 -6
  164. package/templates/65-turn-stop.yml +2 -2
  165. package/templates/67-inbox-prepend.yml +2 -2
  166. package/templates/70-subagent-maintenance.yml +9 -10
  167. package/templates/75-subagent-end.yml +2 -2
  168. package/templates/80-tool-surface.yml +41 -57
  169. package/templates/tools/40-delegate-module-import.yml +22 -0
  170. package/templates/tools/50-delegate-module-rules.yml +14 -0
  171. package/templates/tools/60-delegate-module-variables.yml +17 -0
  172. package/templates/tools/70-delegate-module-rules-edit.yml +31 -0
  173. package/engine/actions/decision.mjs +0 -54
  174. package/engine/actions/guard.mjs +0 -80
  175. package/engine/actions/sdk-strip.mjs +0 -30
  176. package/engine/character-tools.mjs +0 -8
  177. package/engine/classify-task.mjs +0 -53
  178. package/engine/compositions/source/local/character-tools.yml +0 -5
  179. package/engine/compositions/source/local/dev-tool-search.yml +0 -11
  180. package/engine/compositions/source/local/session-var-tools.yml +0 -5
  181. package/engine/compositions/source/local/subagent-tool-policy.yml +0 -21
  182. package/engine/compositions/source/local/world-book-tools.yml +0 -5
  183. package/engine/condition.mjs +0 -96
  184. package/engine/declared-triggers.mjs +0 -93
  185. package/engine/session-var-tools.mjs +0 -8
  186. package/engine/session-vars.mjs +0 -54
  187. package/engine/st-macros.d.mts +0 -22
  188. package/engine/st-macros.mjs +0 -208
  189. package/engine/st-render.mjs +0 -109
  190. package/engine/st-world-book.d.mts +0 -10
  191. package/engine/subagent-tool-policy-core.mjs +0 -400
  192. package/engine/subagent-tool-policy.mjs +0 -352
  193. package/engine/trigger-spec.mjs +0 -173
  194. package/engine/world-book-tools.mjs +0 -8
  195. package/lib/migrate-rules.d.mts +0 -1
  196. package/lib/migrate-rules.mjs +0 -610
  197. package/lib/module-package-DqJZaE71.mjs +0 -2
  198. package/lib/module-package-q2gDRu9H.mjs +0 -2869
  199. package/lib/rule-builder-DMrJten6.mjs +0 -14767
  200. package/templates/61-deny-tools-presentation.yml +0 -27
  201. package/templates/62-guard-deny-tools.yml +0 -20
  202. package/templates/policies/legacy-defaults.yml +0 -34
  203. package/templates/tools/40-delegate-character.yml +0 -15
  204. package/templates/tools/50-delegate-worldbook.yml +0 -15
  205. package/templates/tools/60-delegate-session-var.yml +0 -15
  206. package/templates/tools/70-delegate-worldbook-upsert.yml +0 -36
@@ -1,8 +1,9 @@
1
1
  # 模板:子代理状态 / 记忆维护(audience=subagent 专用注入)
2
2
  # 用途:把 ST 的「角色状态跟踪 + 关系记忆」委派给子代理完成——引擎保持确定性
3
3
  # (插值/匹配/注入),智能判断(何时更新、更新成什么)交给委派子代理,
4
- # 写入经确定性工具边界(session_var 会话状态 / world_book note 持久记忆)。
5
- # 接入:模板选择器「消息批层」插入;默认关闭,插入后启用并按需改 stateKeys。
4
+ # 写入经 module_variables 持久变量与 module_file_append 文件工具。
5
+ # 接入:声明 module-variable-tools、module-file-tools;默认关闭。
6
+ # 先在工作台的模块变量卡手动建立 stateKeys,例如「心情, 接受值, 关系进度」。
6
7
  id: subagent-maintenance
7
8
  name: 子代理状态/记忆维护
8
9
  enabled: false
@@ -31,14 +32,12 @@ then:
31
32
  value: subagent-maintenance
32
33
  text: |-
33
34
  你是本会话的「状态与记忆维护者」,与创作类子代理职责互补:
34
- - 状态(本会话临时,模板变量注入用):观察互动中明确的角色状态变化
35
- (心情、态度、接受度等),用 session_var 工具 set 更新——变量名见下方
36
- 「状态变量」清单;状态未变化时不要重复写入。
37
- - 记忆(跨会话持久):有人际关系进展或重要事实时,用 world_book_upsert
38
- 的 note 参数写入来源角色卡记忆(条目 id 带 chara- 前缀 → 角色卡
39
- memory.md,跨会话跟随角色卡);无归属条目写入模块记忆。
35
+ - 状态(当前模块跨会话持久):观察互动中明确的角色状态变化。
36
+ 先用 module_variables 的 scope=module、action=list 读取身份与版本,
37
+ 再用 action=set 和显式字符串 value 更新下方清单中的变量;带回读取时
38
+ 的 expectedModuleId 与 expectedRevisions,冲突时重读,不覆盖未知修改。
39
+ - 记忆(当前模块 memory.md):重要事实先用 module_file_read 核对(path 为 memory.md),
40
+ 确有新增时用 module_file_append 追加(path 为 memory.md);记忆不会自动变成注入规则。
40
41
  - 克制:仅在状态确实变化时更新;不确定时保留原值;不编造未发生的内容。
41
42
  状态变量清单:{{stateKeys}}
42
- variables:
43
- stateKeys: 心情, 接受值, 关系进度
44
43
  params: {}
@@ -1,8 +1,8 @@
1
1
  # 模板:subagent-end 子代理结束层
2
2
  # 默认仅记录。将 params.action 改为 inject-main 并填写 text,
3
3
  # 通过官方 Agent.inject 向所属主会话投递上下文;不改写子代理结果、不唤醒空闲主会话。
4
- # 接入:subject 缺省 subagentInfo(事件载荷序列化文本,含子代理 id/runId);不写 match
5
- # 即每个子代理结束都记录。载荷里没有稳定角色名,需要筛的时候按实际 runId 补 match。
4
+ # 接入:条件写在规则 if;subagent-end 不再有 config.subject/match。
5
+ # 载荷里没有稳定角色名,需要筛的时候按实际 runId 在 if 里写条件。
6
6
  # 默认关闭:它只写日志,需要审计子代理收尾时再打开。
7
7
  id: example-subagent-end
8
8
  name: 子代理结束记录(只观察)
@@ -1,66 +1,50 @@
1
1
  # 模板:工具面收窄(核心文件与任务集)+ 按需解锁
2
2
  #
3
- # 为什么:工具面实测 **156 个工具、描述合计 46894 字符(≈12K token)**,每个请求都付。
4
- # 收窄到核心集后只剩约 10 个工具,其余按需解锁。
3
+ # `tool-visibility` 声明常驻集、目录与 SDK 正文的呈现、执行闸和发现来源。
4
+ # 首轮提示由同规则的普通注入动作组合;常驻名单只写一次。
5
5
  #
6
- # 与已退场的 `tool-bootstrap` 原型的关键差别:那份**只在受控相位收窄**
7
- # (`promoted: false`),晋升后原样放开;本模板**覆盖全部相位**——晋升后放开等于白省,
8
- # 而工具描述是每请求的固定开销。若要旧语义,给 `phase` 加 `promoted: false` 并把
9
- # `compacted` 拆成两条即可。
6
+ # 本模板只带规则、不带 `modules` 声明:装配里没有提供方时 `bash` 就是缺失名,
7
+ # `requireMatch` 反过来把整条收窄废掉——用模板建模块时要自己把提供方行带进装配。
8
+ # 写错名字的后果很隐蔽:allow 里的名字不存在会触发 requireMatch 的 fail-open,
9
+ # 表现为「收窄没生效」而不是报错。
10
10
  #
11
- # 配套两件(缺一不可):
12
- # 1. `dev_tool_search` 工具(组合源 engine/compositions/source/local/dev-tool-search.yml)
13
- # ——唯一发现入口,模型靠它搜索并解锁。
14
- # 2. `allowFrom`(engine/actions/assembly.mjs)——从历史 `tool/call` 参数回收解锁名单。
15
- # 只挂插件不配 allowFrom 的话,解锁是**一次性的**(当次请求用完即被裁)。
16
- #
17
- # 工具名必须与**实际装配名**一致。本项目 harness 是 `pwsh`(不是 `bash`)、
18
- # `edit` + `write`(不是 `str_replace_editor`)。写错名字有两个后果,都很隐蔽:
19
- # - 写进 allow 的名字不存在 → `requireMatch` 触发 fail-open,**静默暴露完整目录**;
20
- # - 该在的没写进去 → 该工具被裁掉,模型只能用别的方式硬凑。
21
- #
22
- # `requireMatch: true` 是刻意的:任一 allow 工具缺失(或模型解锁了一个不存在的名字)
23
- # 就放弃裁剪、暴露完整目录。宁可多给上下文,也不静默裁成空目录——收窄错了会让当前
24
- # 工作流调不到工具,那是比多花 token 严重得多的故障。
25
- #
26
- # **本模板走规则路径,不能声明 `waterfallPosition`**(那是声明式路径的字段,规则路径会以
27
- # unknown fields 拒绝)。`assembly` 的改写发生在通道下游结算之后,与相邻动作的先后由规则
28
- # 顺序与模块顺序决定。需要 `outermost`(`prepend: true`:保证本动作落在普通注册之外、
29
- # 先看到装配)时,模块层没有出口——`declared-triggers` 与顶层 `triggers` 都已退役
30
- # (写进 `modules` 或定义顶层即 409),只能回到插件侧声明。
11
+ # 发现适配器由 `tool-search` 行提供(模块必须列该行);解锁名从持久 `tool/call` 参数回收,
12
+ # 因此下一步请求即可见,压缩遮蔽后仍然保留。
31
13
  id: tool-surface-resident
32
14
  name: 工具面收窄(核心文件与任务集)
33
15
  enabled: true
34
- if:
35
- # 覆盖全部相位。为什么不能只写 `phase: { promoteOn, includeSubagents }`:
36
- # `promoted` 的缺省是 **true**(= 只匹配已晋升),不是「任意」;而 `compacted` 未声明才是
37
- # 「不判该维度」(engine/conditions/phase.mjs:27-48)。更麻烦的是 `promoted: 'ignore'`
38
- # 要求同时声明 `compacted`,而 `compacted` 只接受布尔值——**没有任何单节点组合能表达
39
- # 「两个相位都命中」**,必须用 `any` 拼两支(phase.mjs:30-35 的注释正是在讲这个表达力边界)。
40
- # 支 1 `promoted: true` → 已晋升(不论压缩与否)
41
- # 支 2 `{compacted: true, promoted: false}` → 压缩后未晋升(受控相位的压缩回退)
42
- # 未晋升且未压缩的**首轮不收窄**:与「首轮保全文」同一取舍——先让模型看到完整目录,
43
- # 再随相位推进收窄。收窄的价值在于工具描述是**每请求固定开销**(实测 46894 字符),
44
- # 而长会话必然进入上面两支,所以省下的正是大头。
45
- any:
46
- - phase: { promoteOn: either, includeSubagents: true, promoted: true }
47
- - phase: { promoteOn: either, includeSubagents: true, compacted: true, promoted: false }
48
16
  then:
49
17
  - id: narrow-tools
50
- kind: assembly
51
- target:
52
- tools:
53
- allow:
54
- - pwsh
55
- - read
56
- - write
57
- - edit
58
- - glob
59
- - grep
60
- - todo_write
61
- - skill_search
62
- - skill_load
63
- - dev_tool_search
64
- # 解锁项从 dev_tool_search 的持久调用参数回收({ tool, key } 精确匹配)。
65
- allowFrom: { tool: dev_tool_search, key: toolNames }
66
- requireMatch: true
18
+ kind: tool-visibility
19
+ allow:
20
+ - pwsh
21
+ - read
22
+ - write
23
+ - edit
24
+ - glob
25
+ - grep
26
+ - todo_write
27
+ - skill_search
28
+ - skill_load
29
+ - tool_search
30
+ # 平台各自的 bash 名:装配里没有提供方时这里就是缺失名,收窄整体失效。
31
+ - bash
32
+ discovery: { kind: tools }
33
+ # 任一常驻工具缺失就放弃裁剪、暴露完整目录(fail-open),避免静默裁成空目录。
34
+ requireMatch: true
35
+ - if:
36
+ count:
37
+ of: user-message
38
+ max: 1
39
+ then:
40
+ - id: discovery-notice
41
+ kind: inject-text
42
+ config:
43
+ layer: pre-step
44
+ strategy: placeholder
45
+ fill: tool-catalog
46
+ position: after-all
47
+ dedupe: session
48
+ text: 常驻工具:{{RESIDENT_TOOLS}}。缺少所需工具时,先用 {{DISCOVERY_TOOL}} 搜索并解锁。
49
+ params:
50
+ action: narrow-tools
@@ -0,0 +1,22 @@
1
+ # 模块导入预览;保存模板时按实际工具目录补装 module-import-tools。
2
+ id: delegate-module-import
3
+ name: my_module_import_preview
4
+ description: 预览模块导入来源、降级报告与版本凭据
5
+ parameters:
6
+ files:
7
+ type: json
8
+ required: true
9
+ description: 文件数组,每项包含相对 path、content 和可选 encoding
10
+ output:
11
+ schema:
12
+ type: object
13
+ additionalProperties: true
14
+ properties:
15
+ ok: { type: boolean }
16
+ value: { type: json }
17
+ execute:
18
+ kind: delegate
19
+ tool: module_import
20
+ args:
21
+ files: '{{args.files}}'
22
+ preview: true
@@ -0,0 +1,14 @@
1
+ # 完整规则读取;保存模板时补装 module-rule-tools。
2
+ id: delegate-module-rules-read
3
+ name: my_module_rules_read
4
+ description: 读取当前模块的完整规则树和版本
5
+ output:
6
+ schema:
7
+ type: object
8
+ additionalProperties: true
9
+ properties:
10
+ ok: { type: boolean }
11
+ value: { type: json }
12
+ execute:
13
+ kind: delegate
14
+ tool: module_rules_read
@@ -0,0 +1,17 @@
1
+ # 持久变量读取;保存模板时补装 module-variable-tools。
2
+ id: delegate-module-variables
3
+ name: my_module_variables
4
+ description: 列出当前模块的有效持久变量、覆盖来源和版本
5
+ output:
6
+ schema:
7
+ type: object
8
+ additionalProperties: true
9
+ properties:
10
+ ok: { type: boolean }
11
+ value: { type: json }
12
+ execute:
13
+ kind: delegate
14
+ tool: module_variables
15
+ args:
16
+ scope: module
17
+ action: list
@@ -0,0 +1,31 @@
1
+ # 完整规则事务;先读取规则和版本,只改需要的字段。
2
+ id: delegate-module-rules-edit
3
+ name: my_module_rules_edit
4
+ description: 按读取版本编辑当前模块的完整规则
5
+ parameters:
6
+ moduleId:
7
+ type: string
8
+ required: true
9
+ description: 读取时返回的模块身份
10
+ revisions:
11
+ type: json
12
+ required: true
13
+ description: 读取时返回的按域版本
14
+ edits:
15
+ type: json
16
+ required: true
17
+ description: 完整规则修改数组,整规则删除须显式 rule 为 null
18
+ output:
19
+ schema:
20
+ type: object
21
+ additionalProperties: true
22
+ properties:
23
+ ok: { type: boolean }
24
+ value: { type: json }
25
+ execute:
26
+ kind: delegate
27
+ tool: module_rules_edit
28
+ args:
29
+ expectedModuleId: '{{args.moduleId}}'
30
+ expectedRevisions: '{{args.revisions}}'
31
+ edits: '{{args.edits}}'
@@ -1,54 +0,0 @@
1
- import { labelOf, toolNameSet } from './shared.mjs'
2
-
3
- export function prepareDecision(action, plugin) {
4
- const label = labelOf(action)
5
- const names = toolNameSet(action.toolNames, plugin, `${label}.toolNames`)
6
- const matchesTool = (exec) => names === undefined || names.has(exec?.name)
7
- const hit = (exec, result) => typeof action.match !== 'function' || action.match(exec, result) === true
8
- const phase = action.phase === undefined ? 'pre' : action.phase
9
- if (!['pre', 'post'].includes(phase)) {
10
- throw new TypeError(`${plugin}: ${label}.phase must be one of pre, post`)
11
- }
12
- if (phase === 'pre') {
13
- const decision = action.decision ?? 'allow'
14
- if (!['allow', 'deny', 'ask'].includes(decision)) {
15
- throw new TypeError(`${plugin}: ${label}.decision must be one of allow, deny, ask`)
16
- }
17
- return (_ctx, { warnOnce, on, collect, take }) => collect(on('tools/pre-execute', async (exec, next) => {
18
- try {
19
- if (!matchesTool(exec) || !hit(exec)) return next()
20
- if (decision === 'allow') return next()
21
- const outcome = decision === 'deny'
22
- ? { kind: 'deny', reason: String(action.reason ?? `${label}: denied by action`) }
23
- : { kind: 'ask' }
24
- return take(exec) ? outcome : next()
25
- } catch (error) {
26
- warnOnce(`${plugin}: decision(pre) action ${label} failed: ${String(error?.message ?? error)}`)
27
- return next()
28
- }
29
- }))
30
- }
31
- const postAction = action.action ?? 'accept'
32
- if (!['accept', 'replace', 'block'].includes(postAction)) {
33
- throw new TypeError(`${plugin}: ${label}.action must be one of accept, replace, block`)
34
- }
35
- const text = typeof action.text === 'string' ? action.text : ''
36
- return (_ctx, { warnOnce, on, collect, take }) => collect(on('tools/post-execute', async (exec, result, next) => {
37
- try {
38
- if (!matchesTool(exec) || !hit(exec, result)) return next()
39
- if (postAction === 'accept') return next()
40
- if (postAction === 'replace' && text.length > 0) {
41
- if (!take(exec)) return next()
42
- return { kind: 'accept', content: [{ type: 'text', text }] }
43
- }
44
- if (postAction === 'block') {
45
- if (!take(exec)) return next()
46
- return { kind: 'block', feedback: [{ type: 'text', text: text.length > 0 ? text : `${label}: blocked by action` }] }
47
- }
48
- return next()
49
- } catch (error) {
50
- warnOnce(`${plugin}: decision(post) action ${label} failed: ${String(error?.message ?? error)}`)
51
- return next()
52
- }
53
- }))
54
- }
@@ -1,80 +0,0 @@
1
- import { labelOf, createMask, RUN_CODE } from './shared.mjs'
2
-
3
- export function prepareGuard(action, plugin) {
4
- const label = labelOf(action)
5
- const mask = createMask(action.mask ?? action, `${label}.mask`, plugin)
6
- const includeSubagents = action.includeSubagents === true
7
- const reasonFor = (toolName) => String(action.reason ?? `${label}: tool ${JSON.stringify(toolName)} is denied by action`)
8
-
9
- return (_ctx, { warnOnce, on, collect }) => {
10
- /** session -> { ctx, disposers }:同一 agent.ctx 只注册一次,重绑后按新 ctx 重注册。 */
11
- const appliedBySession = new WeakMap()
12
- const states = new Set()
13
- const releaseState = (state) => {
14
- states.delete(state)
15
- for (const dispose of state.disposers.splice(0)) {
16
- try { dispose() } catch { /* 释放失败不得反过来打断卸载 */ }
17
- }
18
- }
19
- const releaseAll = () => { for (const state of [...states]) releaseState(state) }
20
-
21
- const applyTo = (agent) => {
22
- const session = agent?.session
23
- const scoped = agent?.ctx
24
- if (session === undefined || scoped === undefined) return
25
- // 受众不在本动作的裁决面内就不注册(子代理的 guard 由它自己的 assembly 决定;
26
- // 万一父 guard 经 scope 链被走到,guard 体内的同一道受众判定仍然放行)。
27
- const depth = session.header?.delegationDepth ?? 0
28
- if (depth > 0 ? !includeSubagents : action.audience === 'subagent') return
29
- const existing = appliedBySession.get(session)
30
- if (existing !== undefined) {
31
- // 预设切换/重绑会换掉 agent.ctx:旧 scope 的 guard 随旧 scope 失效,必须重注册。
32
- if (existing.ctx === scoped) return
33
- releaseState(existing)
34
- appliedBySession.delete(session)
35
- }
36
- const tools = scoped.tools
37
- if (tools === undefined || typeof tools.guard !== 'function') {
38
- warnOnce(`${plugin}: guard action ${label} found no agent-scoped tools service — execution guard not registered`)
39
- return
40
- }
41
- const state = { ctx: scoped, disposers: [] }
42
- states.add(state)
43
- appliedBySession.set(session, state)
44
- const denials = {
45
- ...(mask.allow !== undefined ? { allow: [...mask.allow] } : {}),
46
- ...(mask.deny !== undefined ? { deny: [...mask.deny] } : {}),
47
- }
48
- // restrict 沿父 scope 链传播且不识别受众;只在子代理也受限时复用。
49
- if (includeSubagents && typeof tools.restrict === 'function') {
50
- try {
51
- const dispose = tools.restrict(denials)
52
- if (typeof dispose === 'function') state.disposers.push(dispose)
53
- } catch (error) {
54
- // restrict 只收继承面:本层/晚到工具不在它的可限制集合里,交给 guard 裁决。
55
- warnOnce(`${plugin}: guard action ${label} restrict skipped (own-layer/late tools stay covered by the guard): ${String(error?.message ?? error)}`)
56
- }
57
- }
58
- state.disposers.push(tools.guard((exec) => {
59
- const toolName = exec?.name
60
- if (toolName === RUN_CODE || typeof toolName !== 'string' || toolName.length === 0) return undefined
61
- const depth = exec?.agent?.session?.header?.delegationDepth ?? 0
62
- // 主子代理隔离:scope 注册之外再按受众判定一次(子代理 scope 可能挂在父链上)。
63
- if (depth > 0 ? !includeSubagents : action.audience === 'subagent') return undefined
64
- return mask.blocks(toolName) ? reasonFor(toolName) : undefined
65
- }))
66
- }
67
-
68
- collect(releaseAll)
69
- collect(on('system-prompt/assemble', async (assembly, context, next) => {
70
- // Downstream errors propagate untouched; only this action's own logic is guarded.
71
- const assembled = await next()
72
- try {
73
- applyTo(context?.agent)
74
- } catch (error) {
75
- warnOnce(`${plugin}: guard action ${label} failed to register: ${String(error?.message ?? error)}`)
76
- }
77
- return assembled
78
- }))
79
- }
80
- }
@@ -1,30 +0,0 @@
1
- import { labelOf, createMask } from './shared.mjs'
2
- import { SDK_SECTION_NAME, sdkToolNames, stripSdkDeclarations } from '../sdk-strip.mjs'
3
-
4
- export function prepareSdkStrip(action, plugin) {
5
- const label = labelOf(action)
6
- const mask = createMask(action.mask ?? action, `${label}.mask`, plugin)
7
- return (_ctx, { warnOnce, on, collect, take }) => collect(on('system-prompt/assemble', async (assembly, context, next) => {
8
- // Downstream errors propagate untouched; only this action's own logic is guarded.
9
- const assembled = await next()
10
- try {
11
- if (!Array.isArray(assembled.sections)) return assembled
12
- let changed = false
13
- const sections = assembled.sections.map((section) => {
14
- if (section?.name !== SDK_SECTION_NAME || typeof section.text !== 'string') return section
15
- const names = mask.allow === undefined
16
- ? mask.deny
17
- : new Set([...sdkToolNames(section.text)].filter((toolName) => mask.blocks(toolName)))
18
- if (names === undefined || names.size === 0) return section
19
- const stripped = stripSdkDeclarations(section.text, names)
20
- if (stripped === section.text) return section
21
- changed = true
22
- return { ...section, text: stripped }
23
- })
24
- return changed && take(context) ? { ...assembled, sections } : assembled
25
- } catch (error) {
26
- warnOnce(`${plugin}: sdk-strip action ${label} failed, keeping the original SDK text: ${String(error?.message ?? error)}`)
27
- return assembled
28
- }
29
- }))
30
- }
@@ -1,8 +0,0 @@
1
- /** 角色卡库工具预设模块。 */
2
- export const name = "character-tools"
3
-
4
- export function apply(ctx) {
5
- ctx.inject(["pt-character-tools"], (scopeCtx) => {
6
- scopeCtx.effect(() => scopeCtx.get("pt-character-tools").mount(scopeCtx), name + ": mount")
7
- })
8
- }
@@ -1,53 +0,0 @@
1
- /**
2
- * classify-task — 任务分类器(能力归一)。
3
- *
4
- * buildPattern(构建任务正则)与 complexPattern(复杂任务正则)→ 三档分类
5
- * (complex / build / fix)。锚定策略(first-turn-anchor)三档判定与引导策略
6
- * (guide-auto)复杂判定共用本分类器——正则构建与判定逻辑单一实现,
7
- * 避免两个策略各自 new RegExp + test(历史重复实现)。
8
- *
9
- * 参数缺省 = 对应分类不生效:buildRe/complexRe 未配置时跳过该分支
10
- * (classify 落 fix;isComplex 恒 false)。
11
- */
12
- export function createTaskClassifier({ buildPattern, complexPattern }) {
13
- const buildRe = typeof buildPattern === 'string' && buildPattern.length > 0
14
- ? new RegExp(buildPattern, 'i')
15
- : undefined
16
- const complexRe = typeof complexPattern === 'string' && complexPattern.length > 0
17
- ? new RegExp(complexPattern, 'i')
18
- : undefined
19
- return {
20
- /** 锚定三档判定可用:两档正则都配置。 */
21
- get ready() {
22
- return buildRe !== undefined && complexRe !== undefined
23
- },
24
- /** 三档分类:complex > build > fix(fix 为兜底档)。 */
25
- classify(text) {
26
- if (complexRe !== undefined && complexRe.test(text)) return 'complex'
27
- if (buildRe !== undefined && buildRe.test(text)) return 'build'
28
- return 'fix'
29
- },
30
- /** 复杂判定(引导 fallback 用;正则未配置 = false)。 */
31
- isComplex(text) {
32
- return complexRe !== undefined && complexRe.test(text)
33
- },
34
- }
35
- }
36
-
37
- /**
38
- * 通用有序任务规则分类器(subagentToolPolicy.taskRules 单一实现)。
39
- * 规则:order 升序(同 order 按数组顺序)、首个匹配获胜;输入为
40
- * description + "\n" + prompt;无匹配回落 undefined(调用方用 default)。
41
- * 规则在保存时已编译(非法 pattern 拒绝整次保存),此处只按顺序 test。
42
- */
43
- export function createOrderedTaskClassifier(rules) {
44
- const ordered = [...(Array.isArray(rules) ? rules : [])]
45
- .filter((rule) => rule !== null && typeof rule === 'object' && typeof rule.re?.test === 'function')
46
- .sort((a, b) => (a.order - b.order) || 0)
47
- return (text) => {
48
- for (const rule of ordered) {
49
- if (rule.re.test(String(text ?? ''))) return rule.id
50
- }
51
- return undefined
52
- }
53
- }
@@ -1,5 +0,0 @@
1
- # module: character-tools
2
- # source: engine/compositions/source/local/character-tools.yml (本地附加,非官方模块)
3
-
4
- - id: character-tools
5
- name: ./engine/character-tools.mjs
@@ -1,11 +0,0 @@
1
- # module: dev-tool-search
2
- # source: engine/compositions/source/local/dev-tool-search.yml (本地附加,非官方模块)
3
- #
4
- # 工具面的按需发现与解锁。与 assembly 动作的 allowFrom 配对使用:
5
- # 本工具把解锁名写进持久 tool/call 参数 → allowFrom 读回 → 下次请求起生效。
6
- # 只挂本行而不配 allowFrom 的话,解锁是一次性的(当次请求用完即被裁掉)。
7
- #
8
- # 常驻集由模板声明(见 templates/ 的工具面收窄模板),本行只负责发现入口。
9
-
10
- - id: dev-tool-search
11
- name: ./engine/dev-tool-search.mjs
@@ -1,5 +0,0 @@
1
- # module: session-var-tools
2
- # source: engine/compositions/source/local/session-var-tools.yml (本地附加,非官方模块)
3
-
4
- - id: session-var-tools
5
- name: ./engine/session-var-tools.mjs
@@ -1,21 +0,0 @@
1
- # module: subagent-tool-policy
2
- # source: 本地新增(子代理实例级工具策略:agent-scoped subagent/subagent_fork shadow)
3
- # 策略数据源 = 预设目录 subagent-tools/policy.yml(writePreset 从 preset.yml 顶层
4
- # subagentToolPolicy 物化)。策略启用时参数桥不再把主代理 toolFilter 写入
5
- # delegation.toolFilter;未启用策略的预设完全保持官方 delegation 行为。
6
- #
7
- # 能力提供者边界(T4):本行是**能力提供者**(给模型提供 subagent/subagent_fork 两个
8
- # 可调用工具),**不接入** engine/trigger.mjs。判据:会给模型提供可调用能力
9
- # (注册工具/域)的 → 能力提供者;干预流程(改提示词、改装配、裁决、追加)的 →
10
- # 声明式触发器。登记数据在 engine/subagent-tool-policy.mjs 的 `engineProvider`
11
- # 导出,与 `engineTriggers`(声明式触发器)互斥;守卫见
12
- # test/engine/provider-boundary.test.mjs。模块内扩权审批门与 fail loud 语义是安全
13
- # 边界,改装配方式时不得放宽。
14
-
15
- - id: subagent-tool-policy
16
- name: ./engine/subagent-tool-policy.mjs
17
- config:
18
- policyFile: ../subagent-tools/policy.yml
19
- spawnProvider: spawn
20
- forkProvider: fork
21
- maxDepth: 3
@@ -1,5 +0,0 @@
1
- # module: world-book-tools
2
- # source: engine/compositions/source/local/world-book-tools.yml (本地附加,非官方模块)
3
-
4
- - id: world-book-tools
5
- name: ./engine/world-book-tools.mjs
@@ -1,96 +0,0 @@
1
- /**
2
- * condition — 声明式条件判定的共享实现(pre-step / tool-pipeline / 事件层共用)。
3
- *
4
- * 匹配语义来自 anchor-match.mjs:键集合由 schema.mjs 在挂载期归一化并预编译为
5
- * `config.matchScan`(非法 logic / 空键集合 / 非法正则在挂载期 fail loud)。
6
- * 本模块只负责「按 subject 取文本」与「是否命中」两件事。
7
- *
8
- * 语义约定:
9
- * - 未声明 match 的配置是**无条件**的(与引入条件判定前逐字一致);
10
- * - 取不到匹配文本(字段缺失、类型不符、序列化失败)一律按空串处理,即不命中;
11
- * - 判定异常不抛出:门配错不应该阻断正常链路。
12
- */
13
-
14
- import { extractText, sessionEvents } from './shared.mjs'
15
-
16
- /** subject → 载荷字段名。改这里等于改所有层的匹配对象。 */
17
- export const SUBJECT_FIELDS = {
18
- toolArgs: 'argsText',
19
- toolResult: 'resultText',
20
- userMessage: 'userText',
21
- assistantText: 'assistantText',
22
- subagentInfo: 'subagentText',
23
- }
24
-
25
- /** 按 subject 取参与匹配的文本;取不到一律空串(不命中,不抛错)。 */
26
- export function subjectTextOf(subject, payload) {
27
- if (payload === undefined || payload === null) return ''
28
- const field = SUBJECT_FIELDS[subject]
29
- return field !== undefined && typeof payload[field] === 'string' ? payload[field] : ''
30
- }
31
-
32
- /**
33
- * 条件判定:未声明 match 恒真。
34
- * 消费 schema 预编译的 `config.matchScan`;外部手工构造的 config 没有该函数时按无条件处理。
35
- */
36
- export function conditionHit(config, payload) {
37
- if (config?.match === undefined) return true
38
- const scan = config.matchScan
39
- if (typeof scan !== 'function') return true
40
- try {
41
- return scan(subjectTextOf(config.subject, payload)).active === true
42
- } catch {
43
- return true
44
- }
45
- }
46
-
47
- /** 工具参数的可匹配文本:对象按 JSON 序列化,字符串原样;序列化失败按空串。 */
48
- export function toolArgsText(args) {
49
- if (typeof args === 'string') return args
50
- try {
51
- return JSON.stringify(args ?? {})
52
- } catch {
53
- return ''
54
- }
55
- }
56
-
57
- /**
58
- * pre-step 的缺省匹配对象:本批**真实对话**的用户消息文本。
59
- *
60
- * 只收真人输入:引擎自己注入的消息同样是 user-role(`executor.mjs` 的
61
- * `role: PRE_STEP_ROLE`、`pluginMessage` 的 `source` 是 `plugin:<name>` 生产者身份),
62
- * 把它们算进来会让 `text.match` 匹配到自己注入过的正文——规则正文里出现「重构」
63
- * 「实现」这类词就会自我命中,且命中判定在去重之前,`dedupe` 挡不住。
64
- * 过滤判据与 `st-world-book.mjs#stChatMessages` 的同名约定一致(那是最早做对的一处),
65
- * 两处必须保持同语义。
66
- */
67
- export function userMessagesText(messages) {
68
- if (!Array.isArray(messages)) return ''
69
- return messages
70
- .filter((message) => message?.role === 'user'
71
- && message.source?.plugin === undefined
72
- && message.source?.kind !== 'plugin'
73
- && !(typeof message.source?.kind === 'string' && message.source.kind.startsWith('plugin:'))
74
- && (message.source?.kind === undefined || message.source.kind === 'user'))
75
- .map((message) => extractText(message))
76
- .filter((text) => text.length > 0)
77
- .join('\n')
78
- }
79
-
80
- /** 最后一条 assistant 消息的文本(turn-stop 的缺省匹配对象)。 */
81
- export function lastAssistantText(session) {
82
- const events = sessionEvents(session)
83
- for (let index = events.length - 1; index >= 0; index -= 1) {
84
- if (events[index]?.type === 'assistant/message') return extractText(events[index].data)
85
- }
86
- return ''
87
- }
88
-
89
- /** 子代理事件的匹配文本:事件载荷序列化,取不到即空串。 */
90
- export function subagentTextOf(info) {
91
- try {
92
- return JSON.stringify(info ?? {})
93
- } catch {
94
- return ''
95
- }
96
- }