dsh-plugin-prompt-tool 2.0.1 → 2.1.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.
- package/README.md +6 -6
- package/engine/actions/catalog.mjs +1 -1
- package/engine/actions/inbox-prepend.mjs +1 -2
- package/engine/actions/shared.mjs +1 -2
- package/engine/branch.mjs +1 -1
- package/engine/compositions/source/local/instruction-hint.yml +2 -3
- package/engine/conditions/composite.mjs +1 -1
- package/engine/conditions/count.mjs +1 -2
- package/engine/conditions/phase.mjs +1 -2
- package/engine/conditions/subject.mjs +1 -1
- package/engine/layers.mjs +3 -4
- package/engine/rule-spec.mjs +1 -1
- package/engine/shared.mjs +1 -13
- package/engine/subagent-tool-policy.mjs +2 -2
- package/engine/tool-config-engine.mjs +1 -1
- package/engine/trigger-spec.mjs +3 -3
- package/engine/trigger.mjs +2 -2
- package/lib/index.d.mts +1380 -1
- package/lib/index.mjs +33 -3
- package/lib/migrate-rules.mjs +572 -1
- package/lib/{module-package-CHPFweqK.mjs → module-package-DqJZaE71.mjs} +1 -1
- package/lib/{module-package-Cnd1_mwx.mjs → module-package-q2gDRu9H.mjs} +19 -22
- package/lib/{rules-migration-DJ6vASB5.mjs → rule-builder-DMrJten6.mjs} +28 -595
- package/package.json +4 -2
- package/skills/dsh-module/SKILL.md +199 -0
- package/skills/dsh-module/reference.md +158 -0
- package/templates/61-deny-tools-presentation.yml +27 -0
- package/templates/62-guard-deny-tools.yml +20 -0
- package/templates/63-append-context.yml +22 -0
- package/templates/64-pre-step-filter.yml +23 -0
- package/templates/67-inbox-prepend.yml +22 -0
- package/templates/80-tool-surface.yml +6 -6
- package/engine/compositions/library/agent-instructions.yml +0 -9
- package/engine/compositions/library/command-goal.yml +0 -7
- package/engine/compositions/library/compaction.yml +0 -22
- package/engine/compositions/library/delegation-ptc.yml +0 -58
- package/engine/compositions/library/delegation.yml +0 -56
- package/engine/compositions/library/persistent-shell.yml +0 -50
- package/engine/compositions/library/planning.yml +0 -26
- package/engine/compositions/library/skill-filesystem-cordis.yml +0 -10
- package/engine/compositions/library/skill-filesystem.yml +0 -7
- package/engine/compositions/library/tool-ask-user.yml +0 -7
- package/engine/compositions/library/tool-bash.yml +0 -8
- package/engine/compositions/library/tool-cordis.yml +0 -7
- package/engine/compositions/library/tool-fs-search.yml +0 -9
- package/engine/compositions/library/tool-fs.yml +0 -7
- package/engine/compositions/library/tool-goal.yml +0 -7
- package/engine/compositions/library/tool-jobs.yml +0 -7
- package/engine/compositions/library/tool-plugin-manager-disabled.yml +0 -8
- package/engine/compositions/library/tool-plugin-manager.yml +0 -8
- package/engine/compositions/library/tool-present.yml +0 -7
- package/engine/compositions/library/tool-presentation.yml +0 -9
- package/engine/compositions/library/tool-pwsh.yml +0 -8
- package/engine/compositions/library/tool-skill.yml +0 -7
- package/engine/compositions/library/tool-todo.yml +0 -9
- package/engine/compositions/library/tool-web.yml +0 -10
- package/engine/compositions/source/local/declared-triggers.yml +0 -12
- package/lib/paths-CyP0IkaM.d.mts +0 -1390
- package/lib/preset-transfer.d.mts +0 -2
- package/lib/preset-transfer.mjs +0 -3
package/README.md
CHANGED
|
@@ -22,7 +22,7 @@ dsh --profile prompt-tool
|
|
|
22
22
|
|
|
23
23
|
从 web 模板初始化会让 profile 自带 `@deepseek-ai/dsh-base` 与 `@deepseek-ai/dsh-web-app` 两层,无需额外的 Web 自愈步骤。`--from-default-profile` 只在 profile 不存在时创建,不要对既有 profile 反复执行;已初始化的 profile 不会被改写。
|
|
24
24
|
|
|
25
|
-
技能**留在各自的来源目录里**(项目 `.dsh/skills`、项目 `.agents/skills`、你添加的技能文件夹、`$DSH_HOME/skills`、`~/.agents/skills`、官方内置)。引用目录复用官方 filesystem provider
|
|
25
|
+
技能**留在各自的来源目录里**(项目 `.dsh/skills`、项目 `.agents/skills`、你添加的技能文件夹、`$DSH_HOME/skills`、`~/.agents/skills`、官方内置)。引用目录复用官方 filesystem provider 发现与监听;管理页按当前会话快照标注生效、同名遮蔽和未确认状态。用户根与显式引用目录中的普通技能均可开关、删除;删除移入对应来源根的回收站,保留资源和恢复记录。插件随包分发内置技能(`skills/dsh-module`),安装与每次启动按「只补缺失」补建到 `$DSH_HOME/skills`——已有同名目录保持原样,用户改过或删过的不会被铺回来;新增技能可创建或复制导入,同名导入先确认,成功后不保存技能历史版本。
|
|
26
26
|
|
|
27
27
|
**停用 = 改写技能文件的调用策略**:模型端写 `disable-model-invocation`、用户端写 `user-invocable`。单端开关只修改该端,保留另一端的最新状态;正文、注释和未知字段保留,提交前校验原文并原子替换。官方工具与可选 `skill_search/skill_load` 都执行调用策略。状态文件 `$DSH_HOME/skills/.system/prompt-tool/skills.yml` 只保存引用目录 `folders`(v4);技能清单与调用策略均不进入 settings。详见 [docs/skills-management.md](docs/skills-management.md)。
|
|
28
28
|
|
|
@@ -57,7 +57,7 @@ pnpm --dir $Repo migrate:rules -- --root '<DSH_HOME>/.prompt-tool/modules' --cha
|
|
|
57
57
|
- 🗂️ **完整定义与校验切片**:module.yml 保存完整行为,rules/<id>.yml 保存正文,_settings.yml 保存顺序和启停,variables.yml 保存模板变量;失配单向恢复,不生成旧宿主装配产物。
|
|
58
58
|
- 🧩 **显式互斥**:同模块同组中任一卡声明互斥时,启用目标卡会原子关闭同组其他卡的总开关;重排不改变启用状态。
|
|
59
59
|
- 🖥️ **可拖动悬浮工作台入口**:工作台经官方 `shell.overlay` 渲染悬浮触发器与 body portal 抽屉;按钮可拖动、位置存插件自己的 localStorage、窗口变化自动夹回可见区(不读宿主布局树,已移除 `sidebar.footer.action` 几何探针);五页(主会话/子代理/工具预览/技能设置/模块)在抽屉内渲染,抽屉用 fixed + z-index 置顶,不被宿主导航栏遮挡
|
|
60
|
-
- 🧪 **条件与内容分离**:`
|
|
60
|
+
- 🧪 **条件与内容分离**:`if` 支持组合判断(另有 `else` 分支);注入动作支持 `static / first-turn-anchor / guide-auto / anchor-notice / placeholder / world-book`。旧 `custom-fallback` 拆为锚点条件与通知内容。
|
|
61
61
|
- 🛡️ **失败不伤会话**:单条失败跳过 + `warnOnce`;配置错误挂载时 fail loud;`dedupe: session` 持久幂等
|
|
62
62
|
- 🧭 **通用 instruction-hint 引擎**:模块可通过 `strategy: placeholder` 与 `fill: instruction-hint` 提示指令文件存在;实现位于 `engine/instruction-hint.mjs`。`layerSettings.pre-step.instructionHint` 可启用该能力,按模型可见 surface 去重,重挂不重复,被压缩遮蔽后才再次提示
|
|
63
63
|
- 📦 **Bridge 载荷**:JSON 请求统一 32 MiB 硬上限并明确返回 413;角色卡原始图片走 64 MiB 流式通道,按 PNG 魔数识别。
|
|
@@ -76,9 +76,9 @@ pnpm --dir $Repo migrate:rules -- --root '<DSH_HOME>/.prompt-tool/modules' --cha
|
|
|
76
76
|
|
|
77
77
|
## Web 客户端结构
|
|
78
78
|
|
|
79
|
-
|
|
79
|
+
每条配置保留一张卡,复用原卡壳、折叠箭头和拖拽样式,指令文件卡置顶。卡内通过“规则 / JSON / 设置”平级侧边导航编辑,窄屏改为横向页签。**规则面板按条件作用域组织**:规则级 `if` 是一张条件卡,它管住的 `then` 节点在一段竖线作用域里各自成卡——动作卡与分支卡(卡头即「当 ⟨条件⟩ → ⟨动作⟩」);每张卡默认收起、卡头单行省略给出「条件 → 动作」一览,展开才编辑,`×` 删除整张卡,`then`/`else` 里的分支节点 `{if, then, else}` 可展开编辑、可继续嵌套。上移、下移与拖拽按钮位于卡头总开关旁。Linear 风格统一桌面控件为 28px、按钮与下拉为胶囊;短输入按字符宽度收紧,下拉按最长选项文案限宽,数字 96px,正文与 JSON 保留完整编辑宽度。粗指针的 44px 触控目标扩大控件本体,不覆盖外部空白。
|
|
80
80
|
|
|
81
|
-
规则编辑器通过 `/rules` 保存局部修改与完整文件版本,保留在途新输入、未知字段和未完成 JSON 草稿。动态注入支持 `when
|
|
81
|
+
规则编辑器通过 `/rules` 保存局部修改与完整文件版本,保留在途新输入、未知字段和未完成 JSON 草稿。动态注入支持 `if` / `then` / `else`(旧名 `when` / `do` 已退役,撞上会显式报错);固定注册的独占、抑制及安全守卫拒绝不支持的动态条件。具体支持范围见 [引擎复用指南](docs/engine-reuse.md#声明的条件与动作边界)。
|
|
82
82
|
|
|
83
83
|
Web 客户端按四层组织:
|
|
84
84
|
|
|
@@ -131,7 +131,7 @@ src/client/
|
|
|
131
131
|
|---|---|
|
|
132
132
|
| `layerSettings.<层名>` | 模块共享参数;磁盘归属由参数目录的 `storageLayer` 固定,不随 UI 分组改变 |
|
|
133
133
|
| `moduleConfigs` | 行级 config 直写通道(参数桥未覆盖的键:超时/环境白名单/ST 导入等),不锁定覆盖 UI 可管理参数 |
|
|
134
|
-
| `rules` | 独立身份、条件树 `
|
|
134
|
+
| `rules` | 独立身份、条件树 `if` 与动作数组 `then` / `else`;注入正文与参数归相应动作 |
|
|
135
135
|
| `configOrder` | 规则 ID 到序号的完整定义映射;运行切片中为 _settings.yml.rules[id].order,文件名不带序号 |
|
|
136
136
|
|
|
137
137
|
### 共享参数一览(全部可选,缺省按对应模块解释)
|
|
@@ -220,7 +220,7 @@ UI / 写盘按上表分组;这是展示顺序,不是模型提示词优先级
|
|
|
220
220
|
- 采样参数(`temperature` / `openai_max_tokens` / `reasoning_effort`)**剥离**——模型参数统一由「模型设置」UI / 宿主默认管理
|
|
221
221
|
- ST 变量:保留可启停的赋值模板,在运行时顺序求值;声明变量在合并和角色卡应用时保持局部绑定
|
|
222
222
|
- ST 管理工具:始终装配 `character-tools`、`session-var-tools` 与 `tool-config-engine`
|
|
223
|
-
- `enable_web_search`:`true` →
|
|
223
|
+
- `enable_web_search`:`true` → 本插件**不再组装 web 工具行**(`tool-web` 已随预设解耦从模块库退役,联网能力由会话原有预设提供),只在转换报告里如实提示;`false` → 产出三条规则(`assembly` 呈现剔除 + `sdk-strip` 裁 `tools:sdk` 正文 + `guard` 执行层拒绝,共用同一份 `deny: [web_search, web_fetch]`),PTC 下同样生效
|
|
224
224
|
- 含有效 `character_book` 条目时自动追加 `world-book-tools` 模块,使导入预设可直接调用世界书管理工具
|
|
225
225
|
- 世界书条目级条件:`delayUntilRecursion`(延迟到递归扫描的层级池)、`useGroupScoring`(组内评分淘汰)、`matchCreatorNotes` / `matchCharacterDepthPrompt`(按需扫描卡片备注与深度提示词)按 ST 语义求值;`characterFilter`(角色/标签过滤)、`automationId`(STscript 自动化)、`outletName` 与向量检索**不实现**,只保留来源事实并在预览卡里逐条告警
|
|
226
226
|
- 触发键里的 ST 宏(例如只存在于 ST 全局 persona 的 `{{user}}`)登记为「模板变量」空占位并产出诊断:未赋值时该键不参与匹配(不会退化成字面量误判),在模板变量里赋值后按既有匹配路径生效
|
|
@@ -12,8 +12,7 @@ export function prepareInboxPrepend(action, plugin) {
|
|
|
12
12
|
if (text.length === 0) return
|
|
13
13
|
return (_ctx, { warnOnce, on, collect, take }) => collect(on('agent/inbox/inserted', ({ agent, message } = {}) => {
|
|
14
14
|
try {
|
|
15
|
-
// 无 session 的 agent 不锚定(与原 `anchor-turn`
|
|
16
|
-
// `test/engine/declarations/anchor-turn.yml` 的 session 谓词):锚定是**会话**
|
|
15
|
+
// 无 session 的 agent 不锚定(与原 `anchor-turn` 的守卫逐条对齐):锚定是**会话**
|
|
17
16
|
// 首轮语义,没有会话就没有「首轮」;缺这条会让匿名/临时 agent 也被插一条合成消息
|
|
18
17
|
// (对拍实测:声明路径多插 2 条)。
|
|
19
18
|
if (agent?.session === undefined) return
|
|
@@ -41,8 +41,7 @@ export function createMask(source, label, plugin, allowExtra) {
|
|
|
41
41
|
allowExtra,
|
|
42
42
|
/**
|
|
43
43
|
* fail-open 兜底开关(**可选**,缺省 false):原 `tool-bootstrap` 的语义是
|
|
44
|
-
* 「keep 名单里的工具在本次装配目录里一个都不存在 →
|
|
45
|
-
* `test/engine/declarations/tool-bootstrap.yml` 的 `requireMatch: true`),而原
|
|
44
|
+
* 「keep 名单里的工具在本次装配目录里一个都不存在 → 放弃裁剪、暴露完整目录」,而原
|
|
46
45
|
* `tool-filter` 的同名场景是**照名单裁成空目录**。两种语义都真实存在,所以这里
|
|
47
46
|
* **不设默认**——要兜底的声明自己写 `requireMatch: true`。把某一个模块的特有语义当成
|
|
48
47
|
* 通用默认,会让另一个声明路径的行为被悄悄改掉(这正是对拍抓出来的)。
|
package/engine/branch.mjs
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
# module: instruction-hint
|
|
2
2
|
# source: engine/compositions/source/local/instruction-hint.yml (本地附加,非官方模块)
|
|
3
|
-
# context-gate 的 instructionHint
|
|
4
|
-
# context-gate.mjs:64-66,替换点 :243-248,pre-step 挂载 :226-255:晋升后把
|
|
3
|
+
# 本行承接已退场的 `context-gate` 的 instructionHint 转换:晋升后把
|
|
5
4
|
# agent-instructions 全文换成一次性非命令式 hint,后续全文 dump 丢弃。
|
|
6
5
|
# opt-in:enabled 默认 false(与原 instructionHint 默认 false 同值),由参数桥
|
|
7
6
|
# params.instructionHint(→ 本行 enabled)或本行 config.enabled: true 打开;
|
|
8
|
-
# 相位词汇与
|
|
7
|
+
# 相位词汇与 compaction-epoch.mjs 同源。
|
|
9
8
|
#
|
|
10
9
|
# 四个模板必须随行给全(2026-10-05 修):`instruction-hint.mjs#apply` 的首行是
|
|
11
10
|
# `if (!enabled || templateOf(source, 'messageTemplate').trim().length === 0) return`
|
|
@@ -70,7 +70,7 @@ export function composite(node) {
|
|
|
70
70
|
// 组合层必须**转发子谓词的 observe**(B7 T1 的跨能力缺口修复):两条挂载路径的观察器
|
|
71
71
|
// 接线都按 `when.observe` 过滤(`trigger.mjs` 的 `wireTriggerObservers`),被组合包住的
|
|
72
72
|
// phase / count / session 谓词否则永远收不到活的 `session/event`——状态按 `session.id`
|
|
73
|
-
// 缓存后不再重扫(`shared.mjs` 的 `
|
|
73
|
+
// 缓存后不再重扫(`shared.mjs` 的 `sessionState`),判定会停在冷扫那一刻(计数恒旧值、
|
|
74
74
|
// 相位永不晋升)。`phase` 有 `subscribe: false` 可绕(代价是每次判定冷扫),
|
|
75
75
|
// `count` / `session` 没有该档,所以这条转发是它们唯一的活路。
|
|
76
76
|
const observers = children.filter((child) => typeof child.observe === 'function')
|
|
@@ -50,8 +50,7 @@ export function createCountPredicate(options = {}) {
|
|
|
50
50
|
const min = boundOf(options.min, 'min')
|
|
51
51
|
const max = boundOf(options.max, 'max')
|
|
52
52
|
// 节奏判据(2026-09-22 用户拍板⑤「改用可重建计数」的核心语义):`every: N` = 每 N 次命中一次。
|
|
53
|
-
// 原 `progress-reminder` 的 `results % every === 0`
|
|
54
|
-
// (声明侧见 `test/engine/declarations/progress-reminder.yml` 的 `count.every`),
|
|
53
|
+
// 原 `progress-reminder` 的 `results % every === 0` 配的是**自增后**的计数,
|
|
55
54
|
// 所以这里必须要求 `count > 0`——否则 `0 % N === 0` 会让第 0 次就命中。
|
|
56
55
|
const every = options.every === undefined
|
|
57
56
|
? undefined
|
|
@@ -30,8 +30,7 @@ export function createPhasePredicate(options = {}) {
|
|
|
30
30
|
// 为什么需要它(对拍实测):原实现把 `compacted` 与 `promoted` 写成**合取**,于是可表达的
|
|
31
31
|
// 原子只有 `P`、`C∧P`、`¬C∧P`——三者在 **¬P 的会话上全为 false**,用 `any`/`all`/`not`/
|
|
32
32
|
// `notAny` 的任何组合都表达不出原 `tool-bootstrap` compaction 回退要的 **`C ∧ ¬P`**
|
|
33
|
-
// (受控相位 +
|
|
34
|
-
// `test/engine/declarations/tool-bootstrap.yml` 声明 2)。解耦后
|
|
33
|
+
// (受控相位 + 已压缩:压缩后回到受控工具集)。解耦后
|
|
35
34
|
// `{ compacted: true, promoted: false }` 就是 `C ∧ ¬P`。
|
|
36
35
|
const promotedOption = options.promoted
|
|
37
36
|
if (promotedOption !== undefined && promotedOption !== true && promotedOption !== false && promotedOption !== 'ignore') {
|
|
@@ -78,7 +78,7 @@ export function subjectOf(channel, args, warn, ctx) {
|
|
|
78
78
|
case 'agent/turn-stopping': return { assistantText: lastAssistantText(args[0]?.agent?.session) }
|
|
79
79
|
// 子代理事件的 `name` = provider(`SubagentRunInfo` 里唯一稳定的分类事实:
|
|
80
80
|
// spawn / fork / acp / codex / claude-code / dsh-sdk)。`names` 谓词读的就是
|
|
81
|
-
// `payload.name`,因此 `
|
|
81
|
+
// `payload.name`,因此 `if: { names: { allow: ['fork'] } }` 在此可用。
|
|
82
82
|
// provider 可能缺席(官方注释:已接受的 one-shot 变 ready 或持久 Activation 冷恢复时
|
|
83
83
|
// 提供方未必仍注册)——那时不写键,让 `names` 走 UNAVAILABLE,而不是塞空串当「已知为空」。
|
|
84
84
|
case 'subagent/start':
|
package/engine/layers.mjs
CHANGED
|
@@ -359,8 +359,7 @@ function wireRuntimeContexts(ctx, configs, registry, warnOnce, keep, on) {
|
|
|
359
359
|
* - `replace: true`:整体替换为 `patch`(不叠加 base,故 `unset` 无比较对象);
|
|
360
360
|
* - `unset`:**按值条件删键** —— 仅当合并结果里的值**恰好等于**声明值时删除该键
|
|
361
361
|
* (`Object.is` 比较)。这来自原 `tool-bootstrap` 剥离 `bootstrapMaxTokens` 的语义
|
|
362
|
-
* (「仅当解析后的 maxTokens
|
|
363
|
-
* `test/engine/declarations/tool-bootstrap.yml` 声明 4 的 `do.unset`),不是"存在即删"
|
|
362
|
+
* (「仅当解析后的 maxTokens 恰好等于本声明注入的那个值时才删」),不是"存在即删"
|
|
364
363
|
* ——模型或其它插件设置的同名参数不会被删。
|
|
365
364
|
* 浅合并做不到删键,故删键必须走显式通道。
|
|
366
365
|
* @param params 提示词配置的 `params`(或动作的等价声明)。
|
|
@@ -537,7 +536,7 @@ export function createTurnStopBudget() {
|
|
|
537
536
|
/**
|
|
538
537
|
* 会话预算条目(`sessionState`:统一访问接口,策略逐条声明)。
|
|
539
538
|
*
|
|
540
|
-
* 键类型 `session.id`;淘汰策略超限 `clear()`
|
|
539
|
+
* 键类型 `session.id`;淘汰策略超限 `clear()` 全清(与迁移前的会话态记账同档:
|
|
541
540
|
* 第 `MAX_TRACKED_SESSIONS` 个会话仍会清空整个容器);**不声明复位**——预算是纯增量、
|
|
542
541
|
* 不可从事件流重建的计数(与 `progress-reminder` 同档),丢失时机必须与迁移前逐字一致,
|
|
543
542
|
* compaction 也不重置它。
|
|
@@ -551,7 +550,7 @@ export function createTurnStopBudget() {
|
|
|
551
550
|
|
|
552
551
|
const stateOf = (sessionId, turn) => {
|
|
553
552
|
// 对外仍是 `(sessionId, turn)`:按 id 造一次性键宿主,`keyOf` 取的就是 `.id`,与旧的
|
|
554
|
-
//
|
|
553
|
+
// 记账写法写进同一个槽位、同一个 clear 时机。
|
|
555
554
|
// 唯一差异在**无 id 的会话**(`sessionId === undefined`):`sessionState` 刻意不记账
|
|
556
555
|
// (见 shared.mjs),旧写法把 `undefined` 当一个共享槽位。两个调用点(actions.mjs 的
|
|
557
556
|
// append-context 与下方 turn-stop 层)都在 `entry()` 之前守卫 `session?.id === undefined`,
|
package/engine/rule-spec.mjs
CHANGED
|
@@ -7,7 +7,7 @@ import { ACTION_EXAMPLES } from './actions/examples.mjs'
|
|
|
7
7
|
import { PREDICATE_EXAMPLES } from './conditions/examples.mjs'
|
|
8
8
|
import { conjunction, expandActions } from './branch.mjs'
|
|
9
9
|
|
|
10
|
-
/**
|
|
10
|
+
/** 规则字段:只有 `if`/`then`/`else`;旧名 `when`/`do` 留在名单里,只为把 unknown fields 换成一句「已退役,改用 X」。 */
|
|
11
11
|
const RULE_FIELDS = new Set(['id', 'name', 'enabled', 'layer', 'group', 'exclusive', 'if', 'then', 'else', 'when', 'do'])
|
|
12
12
|
const record = value => value !== null && typeof value === 'object' && !Array.isArray(value)
|
|
13
13
|
const nonempty = value => typeof value === 'string' && value.trim().length > 0
|
package/engine/shared.mjs
CHANGED
|
@@ -151,24 +151,12 @@ export function keepDisposer(ctx, disposer, label) {
|
|
|
151
151
|
* (进程内快路径,真相在 durable 事件流,清空仅触发一次冷扫重建)。 */
|
|
152
152
|
export const MAX_TRACKED_SESSIONS = 4096
|
|
153
153
|
|
|
154
|
-
/** 按会话 key 取 Map 条目;超限时清空后重建(防 session 数无界增长)。 */
|
|
155
|
-
export function sessionMapGet(map, key, create) {
|
|
156
|
-
let entry = map.get(key)
|
|
157
|
-
if (entry === undefined) {
|
|
158
|
-
if (map.size >= MAX_TRACKED_SESSIONS) map.clear()
|
|
159
|
-
entry = create()
|
|
160
|
-
map.set(key, entry)
|
|
161
|
-
}
|
|
162
|
-
return entry
|
|
163
|
-
}
|
|
164
|
-
|
|
165
154
|
/**
|
|
166
155
|
* 会话态声明的统一访问接口(B4 T1 步骤一)。
|
|
167
156
|
*
|
|
168
157
|
* 收敛「每个模块自己维护会话态 Map、自己决定上限与清空策略、自己决定复位时机」,
|
|
169
158
|
* 但**不改变任何既有策略**:键类型、淘汰策略、复位语义逐项由调用方按现状声明,
|
|
170
|
-
*
|
|
171
|
-
* 「按 id + 超限全清」这一档的实现,本函数在 `evict` 缺省且按 id 索引时逐字复用它)。
|
|
159
|
+
* 本函数只把它们收进同一套读写入口。
|
|
172
160
|
*
|
|
173
161
|
* ## 三个必答项(正好对应现状的三处差异)
|
|
174
162
|
*
|
|
@@ -10,8 +10,8 @@
|
|
|
10
10
|
* tool-config-engine.yml 及 test/engine/provider-boundary.test.mjs 同一份措辞):
|
|
11
11
|
* - 会给模型提供可调用能力(注册工具 / 域 / 服务)的 → 能力提供者;
|
|
12
12
|
* - 干预流程(改提示词、改装配、裁决、追加)的 → 声明式触发器。
|
|
13
|
-
* 因此本模块**不接入** engine/trigger.mjs:它不订阅装配 waterfall
|
|
14
|
-
*
|
|
13
|
+
* 因此本模块**不接入** engine/trigger.mjs:它不订阅装配 waterfall,也没有声明式
|
|
14
|
+
* 触发器(`if`/`then` 声明),只在 agent 创建时向该 agent 的 scope 注册两个可调用工具。影子工具解决的是
|
|
15
15
|
* 「子代理能用什么工具」,属于能力面,不是流程干预面。
|
|
16
16
|
*
|
|
17
17
|
* 样板收敛:
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
* - 会给模型提供可调用能力(注册工具 / 域 / 服务)的 → 能力提供者;
|
|
28
28
|
* - 干预流程(改提示词、改装配、裁决、追加)的 → 声明式触发器。
|
|
29
29
|
* 因此本模块**不接入** engine/trigger.mjs:它不订阅装配 waterfall,也没有
|
|
30
|
-
*
|
|
30
|
+
* 声明式触发器(`if`/`then` 声明),只在装配期把 module.yml 的 customTools 段编译出的工具注册进官方
|
|
31
31
|
* registry。强行并进触发器会让引擎同时承担「提供能力」与「干预流程」两种职责。
|
|
32
32
|
*
|
|
33
33
|
* 样板收敛:
|
package/engine/trigger-spec.mjs
CHANGED
|
@@ -7,7 +7,7 @@ export { compileWhen, COMPOSITE_OPERATORS, PREDICATE_FACTORIES } from './conditi
|
|
|
7
7
|
const DECLARATION_FIELDS = Object.freeze(['id', 'channel', 'channelOrder', 'waterfallPosition', 'phase', 'if', 'then', 'else', 'when', 'do'])
|
|
8
8
|
const ACTION_PHASES = Object.freeze(['before-next', 'after-next'])
|
|
9
9
|
|
|
10
|
-
/** `then
|
|
10
|
+
/** `then`(单个动作或数组)归一化为动作声明数组;分支节点留到 `expandActions` 展开。 */
|
|
11
11
|
function actionList(value, label) {
|
|
12
12
|
const list = Array.isArray(value) ? value : [value]
|
|
13
13
|
if (list.length === 0) throw new TypeError(`${label} must be an action declaration or a non-empty array of them`)
|
|
@@ -40,9 +40,9 @@ function actionGate(declarationWhen, action) {
|
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
/**
|
|
43
|
-
* 编译一条声明:校验字段 + 编译 `
|
|
43
|
+
* 编译一条声明:校验字段 + 编译 `if` 判定 + 归一化 `then` 动作。
|
|
44
44
|
*
|
|
45
|
-
* @param {object} spec 声明(`{ id, channel,
|
|
45
|
+
* @param {object} spec 声明(`{ id, channel, if?, then, else?, channelOrder?, waterfallPosition?, phase? }`)
|
|
46
46
|
* @param {object} [context] 同 {@link compileWhen},另可提供 promptConfigOptions(createPromptConfigs 的模板/策略编译选项)。
|
|
47
47
|
* @returns {{id: string, channel: string, channelOrder: number, waterfallPosition: string, phase: string, when: Function|undefined, actions: object[], promptConfigOptions?: object}}
|
|
48
48
|
*/
|
package/engine/trigger.mjs
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
* trigger — 触发器引擎(B3):把「声明」变成「注册」。
|
|
3
3
|
*
|
|
4
4
|
* 本文件负责调度层,**不含**判断原语与动作实现:
|
|
5
|
-
* - `when`
|
|
6
|
-
* - `do`
|
|
5
|
+
* - `when` 判定由 `engine/conditions/` 提供(九个判断原语 + all/any/not/notAny 组合);
|
|
6
|
+
* - `do` 动作由 `engine/actions/` 提供(九类动作);`predicates.mjs` / `actions.mjs` 只留重导出入口。
|
|
7
7
|
* - 本文件只做:声明校验(复用 B2 的 fields.mjs)、同通道内的稳定排序、
|
|
8
8
|
* 宿主 waterfall 位置映射、注册与 disposer、降级与统一告警、会话态生命周期。
|
|
9
9
|
*
|