dsh-plugin-prompt-tool 0.3.0 → 0.4.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 +77 -85
- package/lib/client.js +96 -5
- package/lib/client.js.map +1 -1
- package/lib/index.d.mts +7 -3
- package/lib/index.mjs +58 -61
- package/lib/preset-core.d.mts +7 -3
- package/lib/preset-core.mjs +133 -29
- package/package.json +20 -20
- package/plan.md +22 -2
- package/preset/agent.cordis.yml +443 -0
- package/preset/compaction-epoch.mjs +81 -0
- package/preset/context-gate.mjs +165 -0
- package/preset/custom-bash.mjs +243 -0
- package/preset/instruction-hint.mjs +217 -0
- package/preset/near-anchor.mjs +6 -19
- package/preset/prompt-injector.mjs +111 -126
- package/preset/router-first-turn.mjs +73 -70
- package/preset/router-guide.mjs +14 -20
- package/preset/shared.mjs +83 -0
- package/preset/skill-search.mjs +142 -0
- package/preset/tool-bootstrap.mjs +282 -0
- package/upstream/dsh-anchored-standard/REVISION +1 -1
- package/upstream/dsh-anchored-standard/preset/agent.cordis.yml +22 -11
- package/upstream/dsh-anchored-standard/preset/custom-bash.mjs +98 -5
package/README.md
CHANGED
|
@@ -1,53 +1,49 @@
|
|
|
1
1
|
# 提示词工具(dsh-plugin-prompt-tool)
|
|
2
2
|
|
|
3
|
-
DSH
|
|
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
4
|
|
|
5
|
-
##
|
|
5
|
+
## 原理
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|---|---|---|
|
|
9
|
-
| [xiaobright/dsh-anchored-standard](https://github.com/xiaobright/dsh-anchored-standard) | 上游,内联快照 | 两阶段首轮锚定、tool-bootstrap、context-gate、resident 目录与按需解锁 |
|
|
10
|
-
| [yjh051108/dsh-router-standard](https://github.com/yjh051108/dsh-router-standard) | 参考 | 首轮结构、追加任务引导、Flash 弱路由人设与三锚、子代理方案 |
|
|
11
|
-
| [yjh051108/dsh-super-injector](https://github.com/yjh051108/dsh-super-injector) | 参考 | 缓存铁律、工具面成本原则 |
|
|
7
|
+
DeepSeek V4 会强烈依赖 API 中可见的**首轮工具目录与 persona** 选择执行轨迹。完整 Standard 目录与自动注入在场会破坏 Minimal 轨迹,而全程 Minimal 又会失去重型工具。本项目把「首次轨迹选择」与「后续完整工具能力」拆开:
|
|
12
8
|
|
|
13
|
-
|
|
14
|
-
|
|
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 路由 + 任务分类人设 + 三锚。
|
|
15
14
|
|
|
16
|
-
|
|
15
|
+
阶段全部从持久 session events 推导,resume / reload 不丢失状态。
|
|
17
16
|
|
|
18
|
-
|
|
19
|
-
- **按需层**:扫描 `skills/*/SKILL.md` 注册可开关技能,内容只来自技能自身。
|
|
20
|
-
- **锚定层**:生成独立的 `~/.dsh/.agent-presets/prompt-tool/` 预设,承载首轮工具引导、上下文闸门、任务引导注入与提示词注入。
|
|
21
|
-
- **Web 界面**:自建回环设置桥,在线编辑 `preset.md` 与 `AGENTS.md`,切换全部开关;不占用模型设置区。
|
|
22
|
-
- **TUI(终端界面)命令**:`/prompt-tool status` 查看状态,`/prompt-tool on|off|toggle <开关>` 切换。
|
|
23
|
-
- **上游管理**:上游 dsh-anchored-standard 以内联快照形式放在 `upstream/`,`pnpm sync:anchored` 刷新;不再使用 git 子模块。
|
|
17
|
+
## 稳定化控制
|
|
24
18
|
|
|
25
|
-
|
|
19
|
+
全部在生成 preset 的 `agent.cordis.yml` 行中配置:
|
|
26
20
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
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 禁用并强制降级为关闭。
|
|
36
32
|
|
|
37
|
-
|
|
33
|
+
## 安装
|
|
38
34
|
|
|
39
35
|
```sh
|
|
40
36
|
# 1. 先安装宿主服务(提供 webServer 等本插件依赖的服务)
|
|
41
37
|
dsh plugin --profile prompt-tool add @deepseek-ai/dsh-web-app
|
|
42
38
|
# 或使用 dsh-tui:dsh plugin --profile prompt-tool add @deepseek-harness-tui/dsh-tui
|
|
43
39
|
|
|
44
|
-
# 2.
|
|
40
|
+
# 2. 安装本插件(官方插件指令,自动加入 profile bundles)
|
|
45
41
|
dsh plugin --profile prompt-tool add dsh-plugin-prompt-tool
|
|
46
42
|
|
|
47
|
-
# 3.
|
|
43
|
+
# 3. 本地开发安装(任选其一,会覆盖 registry 依赖)
|
|
48
44
|
dsh plugin --profile prompt-tool add link:<本仓库绝对路径>
|
|
49
45
|
|
|
50
|
-
# 4.
|
|
46
|
+
# 4. 启动
|
|
51
47
|
dsh --profile prompt-tool
|
|
52
48
|
dsh web
|
|
53
49
|
dsh-tui
|
|
@@ -56,45 +52,51 @@ dsh-tui
|
|
|
56
52
|
dsh plugin --profile prompt-tool remove dsh-plugin-prompt-tool
|
|
57
53
|
```
|
|
58
54
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
服务,先执行第 1 步。等价的 profile 清单如下:
|
|
63
|
-
|
|
64
|
-
```jsonc
|
|
65
|
-
// <DSH_HOME>/profiles/prompt-tool/package.json
|
|
66
|
-
"dsh": {
|
|
67
|
-
"profile": {
|
|
68
|
-
"bundles": [
|
|
69
|
-
"@deepseek-ai/dsh-base",
|
|
70
|
-
"@deepseek-ai/dsh-web-app",
|
|
71
|
-
"dsh-plugin-prompt-tool"
|
|
72
|
-
]
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
```
|
|
55
|
+
装完**完整重启 `dsh web`**,新建空 session,预设选择 **prompt-tool**。插件会在启动时生成并刷新 `~/.dsh/.agent-presets/prompt-tool/`(升级插件后重启即自动更新)。
|
|
56
|
+
|
|
57
|
+
## 验证
|
|
76
58
|
|
|
77
|
-
|
|
59
|
+
导出 session JSONL,检查 `request/header`:
|
|
60
|
+
|
|
61
|
+
- 第一份 header 的 `tools` 应恰好是 `["bash", "str_replace_editor"]`;
|
|
62
|
+
- 第一轮只包含用户消息与首句锚点:没有 workspace 指令 baseline、运行时快照、skill 目录消息;
|
|
63
|
+
- 首次工具调用或首次助手回复后,下一份变更 header 应包含 resident 目录:bootstrap 双工具 + `dev_tool_search` / `skill_search` / `skill_load` + 已解锁工具;
|
|
64
|
+
- 此后的请求保持 resident 集,只经 `dev_tool_search` 显式解锁增长;
|
|
65
|
+
- `we` 锚定确认后,事件流出现一次 `source.plugin === 'prompt-injector'` 的消息;未确认时最多等一轮兜底。
|
|
66
|
+
|
|
67
|
+
本项目测试:
|
|
78
68
|
|
|
79
69
|
```sh
|
|
80
|
-
|
|
70
|
+
pnpm test # pnpm build + node --test
|
|
71
|
+
pnpm typecheck # Host 与 Client 两个 tsc program
|
|
72
|
+
pnpm lint # oxlint
|
|
81
73
|
```
|
|
82
74
|
|
|
83
|
-
|
|
75
|
+
## 行为与限制
|
|
84
76
|
|
|
85
|
-
|
|
77
|
+
- Windows:DSH 的 PTY 后端仅支持 linux/darwin,持久 shell 组禁用;phase-1 的 `bash` 切换为 `custom-bash`——同名且 schema 与 Minimal 兼容,经普通跨平台子进程通道调起 Git Bash(运行时探测安装路径,不硬编码)。
|
|
78
|
+
- Linux/macOS:持久 shell 的 `shellPath` 自适应——`/bin/bash` 存在时保持默认,不存在(如 NixOS)回退 PATH 里的 `bash`。
|
|
79
|
+
- 首轮能力类提问可能基于被裁剪的双工具视图作答,晋升后由后续工具纠正;需要时可开启任务引导或直接首轮问任务类问题。
|
|
80
|
+
- 工具目录只变化一次(晋升点),因此第一、二次请求之间发生一次前缀缓存变化;之后每次 `dev_tool_search` 解锁再变化。
|
|
81
|
+
- preset 与 shell 访问具有相同信任等级,安装前可自行审阅 `upstream/` 与生成目录。
|
|
82
|
+
- 插件只监听本机回环设置桥,不发起网络请求,也不增加遥测。
|
|
83
|
+
- 不要在已经产生内容的会话中途切换 preset。
|
|
84
|
+
- 需要 DSH 0.1.0-rc.7+(preset 机制、`system-prompt/assemble` 钩子与 keyed `settings.plugin.item` 插槽)。
|
|
86
85
|
|
|
87
|
-
|
|
86
|
+
## 构建与上游管理
|
|
88
87
|
|
|
89
|
-
|
|
88
|
+
```sh
|
|
89
|
+
pnpm install
|
|
90
|
+
pnpm build # 生成 lib/
|
|
91
|
+
pnpm prepare # npm publish / git install 前自动触发
|
|
92
|
+
pnpm sync:anchored # 从上游 main 刷新内联快照(可加 ref 参数)
|
|
93
|
+
```
|
|
90
94
|
|
|
91
|
-
|
|
92
|
-
2. **晋升**:首次工具调用或助手回复落地后,目录进入 resident(常驻)集,上下文与注入恢复;工具按需解锁。
|
|
93
|
-
3. **追加任务引导**:可选 `near-anchor`,在首条真实用户消息之后追加一次引导——默认按任务自动选择 we/let 首句,也可固定使用自定义文本。Flash 主会话晋升后,`router-guide` 还会在每个真实用户消息后追加固定深度引导;首句与每轮分别有独立的自定义开关和文本框。
|
|
94
|
-
4. **提示词注入**:we 锚定确认后,把 `preset.md` 作为用户消息注入一次;未确认最多等一轮兜底。
|
|
95
|
-
5. **子代理**:目录直接全量放行(实际仍受调用方工具白名单过滤);开启 `subagentFlash` 时,采用 dsh-router-standard 的 Flash 方案——固定 Flash 路由、任务分类人设与三锚。
|
|
95
|
+
上游 `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)。
|
|
96
96
|
|
|
97
|
-
|
|
97
|
+
## 许可
|
|
98
|
+
|
|
99
|
+
插件本体 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`。
|
|
98
100
|
|
|
99
101
|
## 配置参考
|
|
100
102
|
|
|
@@ -108,19 +110,20 @@ dsh --profile prompt-tool --patch <cordis.yml>
|
|
|
108
110
|
text: '' # 覆盖 preset.md 文本;默认读项目文件
|
|
109
111
|
agentsText: '' # 覆盖 AGENTS.md 文本;默认读项目文件
|
|
110
112
|
injectAgentsPrompt: false # 用 AGENTS.md 替换 instruction-hint 提示文本
|
|
111
|
-
writeAgents: true # 写 ~/.dsh/AGENTS.md
|
|
112
|
-
writePreset: true #
|
|
113
|
-
injectPrompt: true # we 确认后注入 preset.md
|
|
113
|
+
writeAgents: true # 写 ~/.dsh/AGENTS.md 受管块
|
|
114
|
+
writePreset: true # 启用锚定预设(总开关)
|
|
115
|
+
injectPrompt: true # we 确认后注入 preset.md
|
|
114
116
|
skillSwitches: {} # 按 skills/* 目录名开关,未列出默认开启
|
|
115
|
-
anchorFirstTurn: false #
|
|
117
|
+
anchorFirstTurn: false # 追加任务引导
|
|
116
118
|
anchorText: '' # 自定义引导文本(首句)
|
|
117
119
|
anchorCustom: false # 使用自定义引导(首句)
|
|
118
|
-
guideText: '' #
|
|
119
|
-
guideCustom: false #
|
|
120
|
-
subagentFlash: false # 子代理固定 Flash
|
|
120
|
+
guideText: '' # 自定义引导文本(每轮)
|
|
121
|
+
guideCustom: false # 使用自定义引导(每轮)
|
|
122
|
+
subagentFlash: false # 子代理固定 Flash 模型
|
|
121
123
|
subagentFlashProvider: 'deepseek-official'
|
|
122
124
|
subagentFlashModel: 'deepseek-v4-flash'
|
|
123
|
-
|
|
125
|
+
bootstrapMaxTokens: 0 # 首轮输出封顶:0=关闭;正整数=请求 #1 maxTokens
|
|
126
|
+
usePtcMode: true # 使用 PTC 模式:true=晋升后切换为 Code Mode(run_code);false=恢复原生完整目录
|
|
124
127
|
skillsDir: '' # 可选技能目录(默认包内 skills/)
|
|
125
128
|
skillRankBase: 250 # 技能候选排序基数
|
|
126
129
|
residentAgentsPath: '' # 默认 ~/.dsh/AGENTS.md
|
|
@@ -129,22 +132,11 @@ dsh --profile prompt-tool --patch <cordis.yml>
|
|
|
129
132
|
fallbackText: '' # preset.md 缺失或不可读时的回退文本
|
|
130
133
|
```
|
|
131
134
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
- **启用锚定预设**:总开关。开启时生成并刷新 `~/.dsh/.agent-presets/prompt-tool/`;关闭时移除已生成目录,锚定相关开关失效。
|
|
135
|
-
- **追加任务引导**:开启时挂载 `near-anchor`,在首条真实用户消息后追加一次任务引导。
|
|
136
|
-
- **使用自定义引导(首句)**:开启时固定使用 `anchorText`;关闭时按任务自动选择 we/let 首句。开启且文本为空时不注入。
|
|
137
|
-
- **使用自定义引导(每轮)**:开启时每轮固定使用 `guideText`,Pro 与 Flash 都注入(便于对照测试);关闭时按任务自动选择快速收敛/深度引导,仅 Flash 主会话晋升后由 router-guide 注入。留空则不注入。
|
|
138
|
-
- **子代理固定 Flash 模型**:开启时采用 dsh-router-standard 的 Flash 子代理方案——通用子代理行加固定 Flash 路由、任务分类人设与三锚;宿主直派子代理(含 dsh-mnemon)自动补 Flash 路由,调用方显式模型优先。检测不到 DeepSeek 模型路由时 Web/TUI 禁用,且运行时强制降级为关闭。
|
|
139
|
-
- **自定义 bash 路径**:上游若带作者机器固定路径,生成 preset 时归一化为该值,默认 PATH 查找 `bash.exe`。
|
|
140
|
-
- 其他字段语义见上方配置注释;设置文件优先级高于挂载配置,首次安装时用项目文件内容初始化设置。
|
|
141
|
-
|
|
142
|
-
## 版权
|
|
135
|
+
TUI 命令:
|
|
143
136
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
-
|
|
148
|
-
-
|
|
149
|
-
|
|
150
|
-
- 本项目 `LICENSE` 见仓库根目录;随上游快照发布的 `upstream/dsh-anchored-standard/LICENSE` 与 `NOTICE` 继续保留。
|
|
137
|
+
```text
|
|
138
|
+
/prompt-tool status
|
|
139
|
+
/prompt-tool on|off|toggle <开关>
|
|
140
|
+
/prompt-tool skill <技能目录名> on|off|toggle
|
|
141
|
+
/prompt-tool bootstrapMaxTokens <正整数|0>
|
|
142
|
+
```
|
package/lib/client.js
CHANGED
|
@@ -23,7 +23,7 @@ window.__ModuleLoader__.load({
|
|
|
23
23
|
}
|
|
24
24
|
//#endregion
|
|
25
25
|
//#region \0dsh-css:E:\Documents\GitHub\dsh-plugin-prompt-tool\src\client\PromptEditor.module.css.mjs
|
|
26
|
-
const css = ".Ru2OGG_card{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);border-radius:12px;list-style:none;transition:border-color .16s,background .16s}.Ru2OGG_card:hover{border-color:var(--dsw-alias-label-dimmed)}.Ru2OGG_cardOpen{background:var(--dsw-alias-bg-layer-2);border-color:var(--dsw-alias-label-dimmed)}.Ru2OGG_header{appearance:none;width:100%;font:inherit;color:inherit;text-align:left;cursor:pointer;background:0 0;border:0;border-radius:12px;align-items:center;gap:12px;padding:14px 16px;display:flex}.Ru2OGG_header:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:-2px}.Ru2OGG_headText{flex-direction:column;flex:1;gap:4px;min-width:0;display:flex}.Ru2OGG_name{color:var(--dsw-alias-label-primary);font-size:15px;font-weight:600;line-height:1.4}.Ru2OGG_description{color:var(--dsw-alias-label-tertiary);font-size:13px;line-height:1.5}.Ru2OGG_chevron{color:var(--dsw-alias-label-tertiary);flex:none;transition:transform .16s}.Ru2OGG_chevronOpen{transform:rotate(180deg)}.Ru2OGG_pending{white-space:nowrap;background:var(--dsw-alias-bg-module-platform);color:var(--dsw-alias-label-secondary);border-radius:999px;flex:none;padding:1px 8px;font-size:11px;font-weight:500;line-height:17px}.Ru2OGG_body{border-top:1px solid var(--dsw-alias-border-l2);flex-direction:column;gap:14px;margin:0 16px;padding:14px 0 16px;display:flex}.Ru2OGG_loading{color:var(--dsw-alias-label-tertiary);font-size:12px;display:inline-block}.Ru2OGG_group{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);border-radius:12px;flex-direction:column;gap:8px;padding:12px 14px;display:flex}.Ru2OGG_groupTitle{color:var(--dsw-alias-label-secondary);font-size:13px;font-weight:600}.Ru2OGG_subSection{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);border-radius:12px;flex-direction:column;display:flex;overflow:hidden}.Ru2OGG_subHeader{appearance:none;width:100%;font:inherit;color:inherit;text-align:left;cursor:pointer;background:0 0;border:0;align-items:center;gap:12px;padding:12px 14px;display:flex}.Ru2OGG_subHeader:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:-2px}.Ru2OGG_subTitle{color:var(--dsw-alias-label-primary);flex:1;font-size:13px;font-weight:600;line-height:1.5}.Ru2OGG_subCount{color:var(--dsw-alias-label-tertiary);flex:none;font-size:12px}.Ru2OGG_subBody{flex-direction:column;gap:8px;padding:2px 14px 12px;display:flex}.Ru2OGG_subEmpty{color:var(--dsw-alias-label-tertiary);padding:4px 0 8px;font-size:12px}.Ru2OGG_row{cursor:pointer;align-items:flex-start;gap:10px;padding:6px 0;display:flex}.Ru2OGG_rowStack{flex-direction:column;align-items:stretch;gap:8px;padding:6px 0;display:flex}.Ru2OGG_row input{flex:none;margin-top:3px}.Ru2OGG_rowText{flex-direction:column;gap:2px;display:flex}.Ru2OGG_rowName{color:var(--dsw-alias-label-primary);font-size:13px;line-height:1.5}.Ru2OGG_rowDesc{color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:1.5}.Ru2OGG_rowDisabled{opacity:.55}.Ru2OGG_anchorInput{box-sizing:border-box;width:100%;min-height:64px;color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l2);resize:vertical;border-radius:8px;padding:8px 10px;font-family:ui-monospace,monospace;font-size:12px;line-height:1.6}.Ru2OGG_textarea{box-sizing:border-box;width:100%;min-height:420px;color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l2);resize:vertical;border-radius:8px;padding:10px;font-family:ui-monospace,monospace;font-size:13px;line-height:1.6}.Ru2OGG_actions{flex-wrap:wrap;align-items:center;gap:8px;display:flex}.Ru2OGG_primary,.Ru2OGG_secondary{appearance:none;font:inherit;cursor:pointer;border:1px solid #0000;border-radius:8px;padding:5px 14px;font-size:13px;line-height:1.5}.Ru2OGG_primary{background:var(--dsw-alias-label-primary);color:var(--dsw-alias-bg-layer-3)}.Ru2OGG_secondary{border-color:var(--dsw-alias-border-l2);color:var(--dsw-alias-label-secondary);background:0 0}.Ru2OGG_primary:disabled,.Ru2OGG_secondary:disabled{opacity:.55;cursor:default}.Ru2OGG_primary:focus-visible,.Ru2OGG_secondary:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:1px}.Ru2OGG_notice{color:var(--dsw-alias-state-success-primary);font-size:12px}.Ru2OGG_noticeError{color:var(--dsw-alias-state-error-primary,#d5484d)}";
|
|
26
|
+
const css = ".Ru2OGG_card{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);border-radius:12px;list-style:none;transition:border-color .16s,background .16s}.Ru2OGG_card:hover{border-color:var(--dsw-alias-label-dimmed)}.Ru2OGG_cardOpen{background:var(--dsw-alias-bg-layer-2);border-color:var(--dsw-alias-label-dimmed)}.Ru2OGG_header{appearance:none;width:100%;font:inherit;color:inherit;text-align:left;cursor:pointer;background:0 0;border:0;border-radius:12px;align-items:center;gap:12px;padding:14px 16px;display:flex}.Ru2OGG_header:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:-2px}.Ru2OGG_headText{flex-direction:column;flex:1;gap:4px;min-width:0;display:flex}.Ru2OGG_name{color:var(--dsw-alias-label-primary);font-size:15px;font-weight:600;line-height:1.4}.Ru2OGG_description{color:var(--dsw-alias-label-tertiary);font-size:13px;line-height:1.5}.Ru2OGG_chevron{color:var(--dsw-alias-label-tertiary);flex:none;transition:transform .16s}.Ru2OGG_chevronOpen{transform:rotate(180deg)}.Ru2OGG_pending{white-space:nowrap;background:var(--dsw-alias-bg-module-platform);color:var(--dsw-alias-label-secondary);border-radius:999px;flex:none;padding:1px 8px;font-size:11px;font-weight:500;line-height:17px}.Ru2OGG_body{border-top:1px solid var(--dsw-alias-border-l2);flex-direction:column;gap:14px;margin:0 16px;padding:14px 0 16px;display:flex}.Ru2OGG_loading{color:var(--dsw-alias-label-tertiary);font-size:12px;display:inline-block}.Ru2OGG_group{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);border-radius:12px;flex-direction:column;gap:8px;padding:12px 14px;display:flex}.Ru2OGG_groupTitle{color:var(--dsw-alias-label-secondary);font-size:13px;font-weight:600}.Ru2OGG_subSection{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);border-radius:12px;flex-direction:column;display:flex;overflow:hidden}.Ru2OGG_subHeader{appearance:none;width:100%;font:inherit;color:inherit;text-align:left;cursor:pointer;background:0 0;border:0;align-items:center;gap:12px;padding:12px 14px;display:flex}.Ru2OGG_subHeader:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:-2px}.Ru2OGG_subTitle{color:var(--dsw-alias-label-primary);flex:1;font-size:13px;font-weight:600;line-height:1.5}.Ru2OGG_subCount{color:var(--dsw-alias-label-tertiary);flex:none;font-size:12px}.Ru2OGG_subBody{flex-direction:column;gap:8px;padding:2px 14px 12px;display:flex}.Ru2OGG_subEmpty{color:var(--dsw-alias-label-tertiary);padding:4px 0 8px;font-size:12px}.Ru2OGG_row{cursor:pointer;align-items:flex-start;gap:10px;padding:6px 0;display:flex}.Ru2OGG_rowStack{flex-direction:column;align-items:stretch;gap:8px;padding:6px 0;display:flex}.Ru2OGG_row input{flex:none;margin-top:3px}.Ru2OGG_rowText{flex-direction:column;gap:2px;display:flex}.Ru2OGG_rowName{color:var(--dsw-alias-label-primary);font-size:13px;line-height:1.5}.Ru2OGG_rowDesc{color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:1.5}.Ru2OGG_rowDisabled{opacity:.55}.Ru2OGG_anchorInput{box-sizing:border-box;width:100%;min-height:64px;color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l2);resize:vertical;border-radius:8px;padding:8px 10px;font-family:ui-monospace,monospace;font-size:12px;line-height:1.6}.Ru2OGG_textarea{box-sizing:border-box;width:100%;min-height:420px;color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l2);resize:vertical;border-radius:8px;padding:10px;font-family:ui-monospace,monospace;font-size:13px;line-height:1.6}.Ru2OGG_actions{flex-wrap:wrap;align-items:center;gap:8px;display:flex}.Ru2OGG_primary,.Ru2OGG_secondary{appearance:none;font:inherit;cursor:pointer;border:1px solid #0000;border-radius:8px;padding:5px 14px;font-size:13px;line-height:1.5}.Ru2OGG_primary{background:var(--dsw-alias-label-primary);color:var(--dsw-alias-bg-layer-3)}.Ru2OGG_secondary{border-color:var(--dsw-alias-border-l2);color:var(--dsw-alias-label-secondary);background:0 0}.Ru2OGG_primary:disabled,.Ru2OGG_secondary:disabled{opacity:.55;cursor:default}.Ru2OGG_primary:focus-visible,.Ru2OGG_secondary:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:1px}.Ru2OGG_notice{color:var(--dsw-alias-state-success-primary);font-size:12px}.Ru2OGG_noticeError{color:var(--dsw-alias-state-error-primary,#d5484d)}.Ru2OGG_bootstrapTokensInput{box-sizing:border-box;width:96px;min-height:36px;max-height:48px;color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l2);text-align:right;border-radius:8px;flex:none;align-self:stretch;margin:0 0 0 auto;padding:4px 8px;font-size:12px;line-height:1.4}.Ru2OGG_bootstrapTokensInput:disabled{opacity:.55;cursor:default}";
|
|
27
27
|
const tagId = "dsh-plugin-prompt-tool/PromptEditor.module.css";
|
|
28
28
|
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
|
|
29
29
|
const tag = document.createElement("style");
|
|
@@ -36,6 +36,7 @@ window.__ModuleLoader__.load({
|
|
|
36
36
|
"actions": "Ru2OGG_actions",
|
|
37
37
|
"anchorInput": "Ru2OGG_anchorInput",
|
|
38
38
|
"body": "Ru2OGG_body",
|
|
39
|
+
"bootstrapTokensInput": "Ru2OGG_bootstrapTokensInput",
|
|
39
40
|
"card": "Ru2OGG_card",
|
|
40
41
|
"cardOpen": "Ru2OGG_cardOpen",
|
|
41
42
|
"chevron": "Ru2OGG_chevron",
|
|
@@ -100,6 +101,8 @@ window.__ModuleLoader__.load({
|
|
|
100
101
|
guideText: "",
|
|
101
102
|
guideCustom: false,
|
|
102
103
|
subagentFlash: false,
|
|
104
|
+
bootstrapMaxTokens: 0,
|
|
105
|
+
usePtcMode: true,
|
|
103
106
|
injectPrompt: true,
|
|
104
107
|
skillSwitches: {},
|
|
105
108
|
skillCatalog: [],
|
|
@@ -114,11 +117,15 @@ window.__ModuleLoader__.load({
|
|
|
114
117
|
guideText: "",
|
|
115
118
|
guideCustom: false,
|
|
116
119
|
subagentFlash: false,
|
|
120
|
+
bootstrapMaxTokens: 0,
|
|
121
|
+
usePtcMode: true,
|
|
117
122
|
injectPrompt: true,
|
|
118
123
|
skillSwitches: {},
|
|
119
124
|
writeAgents: true,
|
|
120
125
|
writePreset: true
|
|
121
126
|
};
|
|
127
|
+
/** 本项目默认不设上限时的显示值(adapter 默认 maxTokens)。 */
|
|
128
|
+
const DEFAULT_BOOTSTRAP_DISPLAY = "256000";
|
|
122
129
|
const snapshotSwitches = (fields) => ({
|
|
123
130
|
injectAgentsPrompt: fields.injectAgentsPrompt,
|
|
124
131
|
anchorFirstTurn: fields.anchorFirstTurn,
|
|
@@ -127,12 +134,14 @@ window.__ModuleLoader__.load({
|
|
|
127
134
|
guideText: fields.guideText,
|
|
128
135
|
guideCustom: fields.guideCustom,
|
|
129
136
|
subagentFlash: fields.subagentFlash,
|
|
137
|
+
bootstrapMaxTokens: fields.bootstrapMaxTokens,
|
|
138
|
+
usePtcMode: fields.usePtcMode,
|
|
130
139
|
injectPrompt: fields.injectPrompt,
|
|
131
140
|
skillSwitches: { ...fields.skillSwitches },
|
|
132
141
|
writeAgents: fields.writeAgents,
|
|
133
142
|
writePreset: fields.writePreset
|
|
134
143
|
});
|
|
135
|
-
const switchesEqual = (a, b) => a.injectAgentsPrompt === b.injectAgentsPrompt && a.anchorFirstTurn === b.anchorFirstTurn && a.anchorText === b.anchorText && a.anchorCustom === b.anchorCustom && a.guideText === b.guideText && a.guideCustom === b.guideCustom && a.subagentFlash === b.subagentFlash && a.injectPrompt === b.injectPrompt && JSON.stringify(a.skillSwitches) === JSON.stringify(b.skillSwitches) && a.writeAgents === b.writeAgents && a.writePreset === b.writePreset;
|
|
144
|
+
const switchesEqual = (a, b) => a.injectAgentsPrompt === b.injectAgentsPrompt && a.anchorFirstTurn === b.anchorFirstTurn && a.anchorText === b.anchorText && a.anchorCustom === b.anchorCustom && a.guideText === b.guideText && a.guideCustom === b.guideCustom && a.subagentFlash === b.subagentFlash && a.bootstrapMaxTokens === b.bootstrapMaxTokens && a.usePtcMode === b.usePtcMode && a.injectPrompt === b.injectPrompt && JSON.stringify(a.skillSwitches) === JSON.stringify(b.skillSwitches) && a.writeAgents === b.writeAgents && a.writePreset === b.writePreset;
|
|
136
145
|
const asRecord = (value) => value !== null && typeof value === "object" ? value : {};
|
|
137
146
|
const readString = (source, key) => {
|
|
138
147
|
const value = source[key];
|
|
@@ -142,6 +151,10 @@ window.__ModuleLoader__.load({
|
|
|
142
151
|
const value = source[key];
|
|
143
152
|
return typeof value === "boolean" ? value : fallback;
|
|
144
153
|
};
|
|
154
|
+
const readNumber = (source, key, fallback) => {
|
|
155
|
+
const value = source[key];
|
|
156
|
+
return typeof value === "number" && Number.isSafeInteger(value) && value >= 0 ? value : fallback;
|
|
157
|
+
};
|
|
145
158
|
const readSkillSwitches = (source, key) => {
|
|
146
159
|
const value = source[key];
|
|
147
160
|
if (value === null || typeof value !== "object") return {};
|
|
@@ -204,6 +217,7 @@ window.__ModuleLoader__.load({
|
|
|
204
217
|
const [deepseekError, setDeepseekError] = (0, react.useState)("");
|
|
205
218
|
const [loaded, setLoaded] = (0, react.useState)(false);
|
|
206
219
|
const [fields, setFields] = (0, react.useState)(EMPTY);
|
|
220
|
+
const [bootstrapTokensDraft, setBootstrapTokensDraft] = (0, react.useState)(DEFAULT_BOOTSTRAP_DISPLAY);
|
|
207
221
|
const [savedPromptText, setSavedPromptText] = (0, react.useState)("");
|
|
208
222
|
const [savedAgentsText, setSavedAgentsText] = (0, react.useState)("");
|
|
209
223
|
const [savedSwitches, setSavedSwitches] = (0, react.useState)(EMPTY_SWITCHES);
|
|
@@ -247,6 +261,8 @@ window.__ModuleLoader__.load({
|
|
|
247
261
|
guideText: readString(value, "guideText") ?? readString(base, "guideText") ?? "",
|
|
248
262
|
guideCustom: readBoolean(value, "guideCustom", readBoolean(base, "guideCustom", false)),
|
|
249
263
|
subagentFlash: readBoolean(value, "subagentFlash", readBoolean(base, "subagentFlash", false)),
|
|
264
|
+
bootstrapMaxTokens: readNumber(value, "bootstrapMaxTokens", readNumber(base, "bootstrapMaxTokens", 0)),
|
|
265
|
+
usePtcMode: readBoolean(value, "usePtcMode", readBoolean(base, "usePtcMode", true)),
|
|
250
266
|
injectPrompt: readBoolean(value, "injectPrompt", readBoolean(base, "injectPrompt", true)),
|
|
251
267
|
skillSwitches: value.skillSwitches !== void 0 || base.skillSwitches !== void 0 ? {
|
|
252
268
|
...readSkillSwitches(base, "skillSwitches"),
|
|
@@ -258,6 +274,7 @@ window.__ModuleLoader__.load({
|
|
|
258
274
|
};
|
|
259
275
|
fieldsRef.current = next;
|
|
260
276
|
setFields(next);
|
|
277
|
+
setBootstrapTokensDraft(next.bootstrapMaxTokens > 0 ? String(next.bootstrapMaxTokens) : DEFAULT_BOOTSTRAP_DISPLAY);
|
|
261
278
|
setSavedPromptText(next.promptText);
|
|
262
279
|
setSavedAgentsText(next.agentsText);
|
|
263
280
|
setSavedSwitches(snapshotSwitches(next));
|
|
@@ -416,6 +433,16 @@ window.__ModuleLoader__.load({
|
|
|
416
433
|
path: ["subagentFlash"],
|
|
417
434
|
value: fieldsRef.current.subagentFlash
|
|
418
435
|
},
|
|
436
|
+
{
|
|
437
|
+
op: "set",
|
|
438
|
+
path: ["bootstrapMaxTokens"],
|
|
439
|
+
value: fieldsRef.current.bootstrapMaxTokens
|
|
440
|
+
},
|
|
441
|
+
{
|
|
442
|
+
op: "set",
|
|
443
|
+
path: ["usePtcMode"],
|
|
444
|
+
value: fieldsRef.current.usePtcMode
|
|
445
|
+
},
|
|
419
446
|
{
|
|
420
447
|
op: "set",
|
|
421
448
|
path: ["injectPrompt"],
|
|
@@ -445,6 +472,20 @@ window.__ModuleLoader__.load({
|
|
|
445
472
|
patch({ [key]: !fieldsRef.current[key] });
|
|
446
473
|
persistSwitches();
|
|
447
474
|
};
|
|
475
|
+
const toggleBootstrapMaxTokens = () => {
|
|
476
|
+
const next = fieldsRef.current.bootstrapMaxTokens > 0 ? 0 : 256e3;
|
|
477
|
+
patch({ bootstrapMaxTokens: next });
|
|
478
|
+
setBootstrapTokensDraft(DEFAULT_BOOTSTRAP_DISPLAY);
|
|
479
|
+
persistSwitches();
|
|
480
|
+
};
|
|
481
|
+
const commitBootstrapTokensDraft = () => {
|
|
482
|
+
const parsed = Number(bootstrapTokensDraft);
|
|
483
|
+
if (!Number.isSafeInteger(parsed) || parsed <= 0) {
|
|
484
|
+
setBootstrapTokensDraft(DEFAULT_BOOTSTRAP_DISPLAY);
|
|
485
|
+
patch({ bootstrapMaxTokens: 256e3 });
|
|
486
|
+
} else patch({ bootstrapMaxTokens: parsed });
|
|
487
|
+
persistSwitches();
|
|
488
|
+
};
|
|
448
489
|
const skillEnabled = (folder) => fields.skillSwitches[folder] !== false;
|
|
449
490
|
const toggleSkill = (folder) => {
|
|
450
491
|
const enabled = fieldsRef.current.skillSwitches[folder] !== false;
|
|
@@ -462,7 +503,7 @@ window.__ModuleLoader__.load({
|
|
|
462
503
|
const promptSwitchDirty = fields.injectPrompt !== savedSwitches.injectPrompt;
|
|
463
504
|
const agentsSwitchDirty = fields.injectAgentsPrompt !== savedSwitches.injectAgentsPrompt || fields.writeAgents !== savedSwitches.writeAgents;
|
|
464
505
|
const skillsSwitchDirty = JSON.stringify(fields.skillSwitches) !== JSON.stringify(savedSwitches.skillSwitches);
|
|
465
|
-
const presetSwitchDirty = fields.writePreset !== savedSwitches.writePreset || fields.anchorFirstTurn !== savedSwitches.anchorFirstTurn || fields.anchorText !== savedSwitches.anchorText;
|
|
506
|
+
const presetSwitchDirty = fields.writePreset !== savedSwitches.writePreset || fields.anchorFirstTurn !== savedSwitches.anchorFirstTurn || fields.anchorText !== savedSwitches.anchorText || fields.bootstrapMaxTokens !== savedSwitches.bootstrapMaxTokens || fields.usePtcMode !== savedSwitches.usePtcMode;
|
|
466
507
|
const discardPrompt = () => patch({ promptText: savedPromptText });
|
|
467
508
|
const discardAgents = () => patch({ agentsText: savedAgentsText });
|
|
468
509
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", {
|
|
@@ -696,6 +737,57 @@ window.__ModuleLoader__.load({
|
|
|
696
737
|
})]
|
|
697
738
|
})]
|
|
698
739
|
}),
|
|
740
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
|
|
741
|
+
className: PromptEditor_module_css_default.row,
|
|
742
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
743
|
+
type: "checkbox",
|
|
744
|
+
checked: fields.usePtcMode,
|
|
745
|
+
disabled: !fields.writePreset,
|
|
746
|
+
onChange: () => toggle("usePtcMode")
|
|
747
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
748
|
+
className: PromptEditor_module_css_default.rowText,
|
|
749
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
750
|
+
className: PromptEditor_module_css_default.rowName,
|
|
751
|
+
children: "使用 PTC 模式"
|
|
752
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
753
|
+
className: PromptEditor_module_css_default.rowDesc,
|
|
754
|
+
children: "默认开启:晋升后把 wire 切换为 Code Mode(PTC,单一 run_code),完整插件工具通过生成 SDK 调用。关闭后恢复原生完整工具目录"
|
|
755
|
+
})]
|
|
756
|
+
})]
|
|
757
|
+
}),
|
|
758
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
759
|
+
className: PromptEditor_module_css_default.row,
|
|
760
|
+
children: [
|
|
761
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
762
|
+
id: "prompt-tool-bootstrap-max-tokens",
|
|
763
|
+
type: "checkbox",
|
|
764
|
+
checked: fields.bootstrapMaxTokens > 0,
|
|
765
|
+
disabled: !fields.writePreset,
|
|
766
|
+
onChange: toggleBootstrapMaxTokens
|
|
767
|
+
}),
|
|
768
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
|
|
769
|
+
htmlFor: "prompt-tool-bootstrap-max-tokens",
|
|
770
|
+
className: PromptEditor_module_css_default.rowText,
|
|
771
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
772
|
+
className: PromptEditor_module_css_default.rowName,
|
|
773
|
+
children: "首轮输出封顶"
|
|
774
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
775
|
+
className: PromptEditor_module_css_default.rowDesc,
|
|
776
|
+
children: "关闭时显示项目默认 256000(不设上限);开启后右侧数值生效,晋升后自动剥离。清空或输入 0 会恢复 256000,不关闭开关"
|
|
777
|
+
})]
|
|
778
|
+
}),
|
|
779
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
780
|
+
className: PromptEditor_module_css_default.bootstrapTokensInput,
|
|
781
|
+
type: "number",
|
|
782
|
+
min: 1,
|
|
783
|
+
step: 1,
|
|
784
|
+
value: bootstrapTokensDraft,
|
|
785
|
+
disabled: !fields.writePreset || fields.bootstrapMaxTokens === 0,
|
|
786
|
+
onChange: (e) => setBootstrapTokensDraft(e.target.value),
|
|
787
|
+
onBlur: commitBootstrapTokensDraft
|
|
788
|
+
})
|
|
789
|
+
]
|
|
790
|
+
}),
|
|
699
791
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
|
|
700
792
|
className: PromptEditor_module_css_default.row,
|
|
701
793
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
@@ -826,8 +918,7 @@ window.__ModuleLoader__.load({
|
|
|
826
918
|
const injected = () => ({ api: connection.api });
|
|
827
919
|
ctx.slots.inject("settings.plugin.item", () => ctx.slots.register({
|
|
828
920
|
name: "settings.plugin.item",
|
|
829
|
-
|
|
830
|
-
order: 30,
|
|
921
|
+
key: "prompt-tool",
|
|
831
922
|
inject: injected
|
|
832
923
|
}, PromptEditor));
|
|
833
924
|
}
|