dsh-fast-mode 1.5.14 → 1.5.15
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/BENCHMARK.md +17 -0
- package/CHANGELOG.md +7 -0
- package/README.en.md +3 -2
- package/README.md +3 -2
- package/client.js +21 -3
- package/docs/REFERENCE.en.md +4 -3
- package/docs/REFERENCE.md +4 -3
- package/index.js +1 -1
- package/package.json +1 -1
package/BENCHMARK.md
CHANGED
|
@@ -1952,3 +1952,20 @@ python3 bench/suite-run.py --tasks debugfix,ledger,codeimpl --arms off,def15,bud
|
|
|
1952
1952
|
6. 不通过就维持默认 `0`,并在文档里写「第二次提醒无效/有害」,不再重试第三次。
|
|
1953
1953
|
|
|
1954
1954
|
**已知上限。** 单块 n=6 的检出下限约 ±15 %(见「空转对照」一节:同臂对同臂 9 对的范围是 0.889–1.342×)。所以这里只认「几何 ≤ 0.95× 且赢面 4/6 以上」这种**远大于噪声**的结果;0.96–1.04× 一律判空。
|
|
1955
|
+
|
|
1956
|
+
## 结果:`D2G` 预注册判据判 **HOLD**(2026-10-28,21 对跑完)
|
|
1957
|
+
|
|
1958
|
+
**数字。** 21 对里 14 对更快,合并几何 **0.756×**、中位 **0.719×**、总时长 **0.685×**,质量 0 回归。分块:
|
|
1959
|
+
|
|
1960
|
+
| 块 | n | 几何 | 中位 | 更快 | 步数几何 | 输出几何 | 范围 | 判据 |
|
|
1961
|
+
|---|---|---|---|---|---|---|---|---|
|
|
1962
|
+
| `D2G_IMPL`(`codeimpl`) | 8 | 0.889× | 0.905× | 5/8 | 0.753× | 0.910× | 0.373–2.093× | 过 |
|
|
1963
|
+
| `D2G_DBG`(`debugfix`) | 7 | **0.903×** | 0.794× | 4/7 | 0.987× | 0.731× | 0.669–1.368× | **不过(要 ≤ 0.80)** |
|
|
1964
|
+
| `D2G_MIG`(`migrate`) | 6 | **0.495×** | 0.426× | 5/6 | 0.964× | 0.478× | 0.259–1.601× | 过 |
|
|
1965
|
+
|
|
1966
|
+
**判定。** 第 2 条把 `debugfix` 的门槛设在 0.80×,实测 0.903×;第 4 条合并 0.756× / 中位 0.719× 与第 3 条 `migrate` 0.495× 都远好于门槛,第 1 条 `IMPL` 0.889× 也过,但预注册规则写的是「五条全满足才建议改默认」,所以**不挑指标发版**:默认永久停在 4,这条线结束。逐格看,输的三格(`codeimpl p6` 2.093×、`migrate p3` 1.601×、`debugfix p5` 1.368×)都是本来就没有探索空间的直线任务,提前提醒让它们多走一两步;赢的三格(`migrate p1` 0.259×、`migrate p2` 0.312×、`codeimpl p3` 0.373×)都是长任务。方向按家族与长度分层,不做线拟合。
|
|
1967
|
+
|
|
1968
|
+
**两处与预注册的偏差,记在这里不掩盖:**
|
|
1969
|
+
|
|
1970
|
+
1. **判据 5 的「下发条件」没被脚本执行。** 预注册写的是「`D2G_IMPL` 8/8 仍在**第 4 步**收到,`D2G_DBG`/`D2G_MIG` 在第 2 步收到」。实际逐会话扫描:`def15` 8/8/6/7 全在第 4 步,`d2g` 在 `IMPL` 是**第 3 步**、在 `DBG`/`MIG` 是第 2 步。`IMPL` 按设计应在 `disciplineEarlyCalls: 2` 下退化成第 4 步,实际提前到了第 3 步 —— 这解释了它为什么没像预期那样完全退化(0.889× 而不是 ≈1.00×),也说明判据 5 的「按条件命中」这一半同样没通过。`d2greport.sh` 的 gate 5 只校验 `exact`/`green`,没有校验下发步位,这是脚本与预注册之间的缺口,后续 gate 脚本要把步位断言写进去。
|
|
1971
|
+
2. **`delivery audit` 探针不可用。** 报告按固定句式找完成通报,命中 0/16、2/14、0/12。这个探针在本套 fixture 上恒为 0,不能当「任务没交付」的证据;质量结论只引用 `exact`/`green`(21 对全部 1/1)与判据 5 的 0 坏格。
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.5.15(右键面板第三行;`D2G` 预注册判据判 HOLD)
|
|
4
|
+
|
|
5
|
+
- **面板第三行「工作区清单」**:写共享字段 `workspaceMap`(默认 `false`),三行面板第三项,`readonly` / 写入中禁用,写失败回滚。与另两行一样只写共享字段、不带 `sessions`,不碰按会话的开关状态。`client.test.js` 新增一行测试覆盖「默认关、写入不带 `sessions`、写后按 host 值重绘、再点关掉」,全套 **270 pass**。
|
|
6
|
+
- **文案与检查**:`ui-copy-lint` **21 error / 2 warning**(与 HEAD 逐行相同,全是文件级 React props 误报),`zh-lint` **0 error**(37 warning 为既有),`style-lint` 通过。
|
|
7
|
+
- **`D2G` 预注册判据:HOLD,默认维持第 4 步**。21 对(`D2G_IMPL` 8 / `D2G_DBG` 7 / `D2G_MIG` 6)里 14/21 更快,合并几何 **0.756×**、中位 **0.719×**、总时长 **0.685×**,质量 0 回归;但第 2 条在 `debugfix` 上是 **0.903×**,没进预设的 **≤ 0.80**。按预注册规则,其余判据全过也不能挑指标发版。分块数字:`IMPL` 0.889× / 5-8 更快 / 步数 0.753×;`DBG` 0.903× / 4-7 / 步数 0.987×;`MIG` **0.495×** / 5-6 / 步数 0.964× —— 迁移类省得最多,调试类基本打平。离群点:`codeimpl p6` 2.093×、`migrate p3` 1.601×、`debugfix p5` 1.368×,都在「本来就没有探索空间」的短直线上多走了几步。
|
|
8
|
+
- **交付审计的限度**:报告里的 `delivery audit` 按固定句式找完成通报,命中 0/16、2/14、0/12,这个探针在本套任务上不可用;质量结论只引用 `exact` / `green`(全部 1/1)与判据 5 的 0 个坏格。
|
|
9
|
+
|
|
3
10
|
## 1.5.14(`D2G` 判据仍在跑,未据此改默认)
|
|
4
11
|
|
|
5
12
|
- **闪电右键面板(新)**:只有两行,都是共享设置、下一个回合生效 —— 「更少中间输出」(写 `outputDiscipline`,`late` ↔ `false`,默认开)与「步数上限」(写 `stepBudget`,循环 `0 / 15 / 30`,默认 `0` 不限)。面板只读取值、只挑一个已测过的安全上限,没有暴露 `disciplineAfterSteps`、`shapeGate`、`finishLineSteps`、`shellParallel` 这些未证实或已淘汰的旋钮。步数上限的写入不带 `sessions` 字段,避免动到按会话的开关状态;`client.js` 的 `write()` 因此加了 `{ touchSession: false }` 路径。文案按界面规则压到标签/值/后果三件,`ui-copy-lint` 与 HEAD 同为 21 error / 2 warning(全部是文件级 React props 误报),`zh-lint` 0 error。
|
package/README.en.md
CHANGED
|
@@ -87,12 +87,13 @@ Legacy `fast` / `turbo` / `max` / `ludicrous` values are read as `auto` with a d
|
|
|
87
87
|
|
|
88
88
|
## The switch
|
|
89
89
|
|
|
90
|
-
The bolt is the switch: one click writes on/off, per conversation, restored on reload. Right-click it for
|
|
90
|
+
The bolt is the switch: one click writes on/off, per conversation, restored on reload. Right-click it for three shared settings:
|
|
91
91
|
|
|
92
92
|
- **Less narration** — master switch for the step-4 reminder; with it off, long tasks take about 2.7x longer and write about twice as much. On by default.
|
|
93
93
|
- **Step cap** — `15` / `30` / off, off by default. At the cap it reports instead of truncating the task.
|
|
94
|
+
- **Workspace inventory** — before the turn's first tool call, one inventory notice (relative paths + byte sizes + visible test entry points) so the turn does not open with `ls`/`find`. Off by default; over 23 pairs it measured 0.927x geometric with a slower tail and 10% more steps, so it stays a switch to try rather than a default.
|
|
94
95
|
|
|
95
|
-
|
|
96
|
+
All three apply from the next request. No dropdown, no multiplier estimate.
|
|
96
97
|
|
|
97
98
|
The idea draws on `dsh-batch-tool-calls` and `dsh-ops` (batched calls, bounded execution), but their widths are static while this width comes from the conversation's own call evidence; do not install all three. Context-compaction plugins coexist.
|
|
98
99
|
|
package/README.md
CHANGED
|
@@ -87,12 +87,13 @@
|
|
|
87
87
|
|
|
88
88
|
## 开关
|
|
89
89
|
|
|
90
|
-
|
|
90
|
+
闪电就是开关:开/关即写,按会话独立,重启按会话恢复。右键闪电是一块三行的面板:
|
|
91
91
|
|
|
92
92
|
- **更少中间输出**:第 4 步那句「省着写」提醒的总开关,关掉后输出会变长、墙钟变慢(长任务约 2.7×),默认开。
|
|
93
93
|
- **步数上限**:`15` / `30` / 不限,默认不限。到上限只先汇报,不截断任务。
|
|
94
|
+
- **工作区清单**:开启后,回合的第一次工具调用之前先收到一份工作目录清单(相对路径 + 字节数 + 可见的测试入口),省掉开头的 `ls`/`find` 探路。默认关;23 个配对实测几何 0.927×,尾部变慢、步数 +10%,没有达到进默认的门槛,只作为可试的开关。
|
|
94
95
|
|
|
95
|
-
|
|
96
|
+
三项都是共享设置,对下一个回合生效。没有下拉,没有倍数估算。
|
|
96
97
|
|
|
97
98
|
思路参考了 `dsh-batch-tool-calls` 与 `dsh-ops`(批量调用、有界执行),但它们的规则是静态的,这里的宽度来自会话自身的调用证据;不需要同时装。压缩类插件可以共存。
|
|
98
99
|
|
package/client.js
CHANGED
|
@@ -99,6 +99,7 @@ window.__ModuleLoader__.load({
|
|
|
99
99
|
'panel.budgetSteps': '{n} 步',
|
|
100
100
|
'panel.allSessions': '所有会话',
|
|
101
101
|
'panel.budgetTitle': '到上限先汇报,不截断任务',
|
|
102
|
+
'panel.map': '工作区清单',
|
|
102
103
|
}
|
|
103
104
|
|
|
104
105
|
const en = {
|
|
@@ -119,6 +120,7 @@ window.__ModuleLoader__.load({
|
|
|
119
120
|
'panel.budgetSteps': '{n} steps',
|
|
120
121
|
'panel.allSessions': 'All conversations',
|
|
121
122
|
'panel.budgetTitle': 'Reports at the cap; never truncates the task',
|
|
123
|
+
'panel.map': 'Workspace inventory',
|
|
122
124
|
}
|
|
123
125
|
|
|
124
126
|
const CSS = [
|
|
@@ -176,6 +178,8 @@ window.__ModuleLoader__.load({
|
|
|
176
178
|
* pretending it is per-conversation.
|
|
177
179
|
*/
|
|
178
180
|
discipline: true,
|
|
181
|
+
/** The shared workspace inventory switch, off by default. */
|
|
182
|
+
inventory: false,
|
|
179
183
|
/** The shared step cap: 0 means no cap. */
|
|
180
184
|
stepBudget: 0,
|
|
181
185
|
/** The right-click panel is open. Store-backed, like every other paint. */
|
|
@@ -492,6 +496,7 @@ window.__ModuleLoader__.load({
|
|
|
492
496
|
store.gear = seenGear
|
|
493
497
|
store.discipline = value.outputDiscipline !== false
|
|
494
498
|
store.stepBudget = typeof value.stepBudget === 'number' ? value.stepBudget : 0
|
|
499
|
+
store.inventory = value.workspaceMap === true
|
|
495
500
|
// A write we have not seen echoed yet wins: the Loader applies the new
|
|
496
501
|
// section asynchronously, and flipping back to the old paint in that
|
|
497
502
|
// window would read as a failed click.
|
|
@@ -558,6 +563,7 @@ window.__ModuleLoader__.load({
|
|
|
558
563
|
}
|
|
559
564
|
if (typeof patch.gear === 'string') store.gear = patch.gear
|
|
560
565
|
if (typeof patch.stepBudget === 'number') store.stepBudget = patch.stepBudget
|
|
566
|
+
if (typeof patch.workspaceMap === 'boolean') store.inventory = patch.workspaceMap
|
|
561
567
|
emit()
|
|
562
568
|
try {
|
|
563
569
|
unwrap(await withTimeout(remote.settings.update(store.ns, outgoing, store.revision), 15000, 'settings/update'))
|
|
@@ -571,6 +577,7 @@ window.__ModuleLoader__.load({
|
|
|
571
577
|
store.gear = before.gear
|
|
572
578
|
store.sessions = before.sessions
|
|
573
579
|
store.stepBudget = before.stepBudget
|
|
580
|
+
store.inventory = before.inventory
|
|
574
581
|
store.pending = undefined
|
|
575
582
|
store.writeError = describeError(error)
|
|
576
583
|
emit()
|
|
@@ -740,13 +747,13 @@ window.__ModuleLoader__.load({
|
|
|
740
747
|
* Props are assigned one by one because a dense key/value literal reads as
|
|
741
748
|
* a status dump to the copy linter, and this is a control, not a dump.
|
|
742
749
|
*/
|
|
743
|
-
const row = (role, label, value, live, act) => {
|
|
750
|
+
const row = (role, label, value, live, act, checked) => {
|
|
744
751
|
const props = {}
|
|
745
752
|
props.className = 'fm-panel__row'
|
|
746
753
|
props.role = role
|
|
747
754
|
props.disabled = !live
|
|
748
755
|
props.onClick = act
|
|
749
|
-
if (role === 'menuitemcheckbox') props['aria-checked'] =
|
|
756
|
+
if (role === 'menuitemcheckbox') props['aria-checked'] = checked === true
|
|
750
757
|
return react.createElement(
|
|
751
758
|
'button',
|
|
752
759
|
props,
|
|
@@ -761,12 +768,23 @@ window.__ModuleLoader__.load({
|
|
|
761
768
|
emit()
|
|
762
769
|
}
|
|
763
770
|
|
|
771
|
+
/**
|
|
772
|
+
* The inventory is a shared field as well: it belongs to the composition,
|
|
773
|
+
* not to one conversation, so the write skips the per-session entry.
|
|
774
|
+
*/
|
|
775
|
+
const toggleMap = () => {
|
|
776
|
+
void write(remote, { workspaceMap: !store.inventory }, { touchSession: false })
|
|
777
|
+
store.panelOpen = false
|
|
778
|
+
emit()
|
|
779
|
+
}
|
|
780
|
+
|
|
764
781
|
return react.createElement(
|
|
765
782
|
'div',
|
|
766
783
|
{ className: 'fm-panel', role: 'menu', 'aria-label': t('panel.title') },
|
|
767
784
|
react.createElement('div', { className: 'fm-panel__title' }, t('panel.title')),
|
|
768
|
-
row('menuitemcheckbox', t('panel.prose'), t(store.discipline ? 'panel.on' : 'panel.off'), canWrite, toggleProse),
|
|
785
|
+
row('menuitemcheckbox', t('panel.prose'), t(store.discipline ? 'panel.on' : 'panel.off'), canWrite, toggleProse, store.discipline),
|
|
769
786
|
row('menuitem', t('panel.budget'), budgetText, canWrite, () => void cycleBudget(remote)),
|
|
787
|
+
row('menuitemcheckbox', t('panel.map'), t(store.inventory ? 'panel.on' : 'panel.off'), canWrite, toggleMap, store.inventory),
|
|
770
788
|
react.createElement('div', { className: 'fm-panel__scope' }, t('panel.allSessions')),
|
|
771
789
|
)
|
|
772
790
|
}
|
package/docs/REFERENCE.en.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Reference: principles, configuration and limits
|
|
2
2
|
|
|
3
|
-
This manual describes what **dsh-fast-mode 1.5.
|
|
3
|
+
This manual describes what **dsh-fast-mode 1.5.15** actually does (injection behaviour under the default config is identical to 1.5.0; 1.5.14 added the right-click panel and 1.5.15 makes it three rows), matching `index.js`, `src/` and `client.js` in the repository. It is not a brochure: where something can be measured it gets a number, and where it has not been measured it says so.
|
|
4
4
|
|
|
5
5
|
**The one contract: fast mode never changes reasoning effort, the thinking budget, or the model.** The `agent/request` hook does exactly one thing — `await next()`, read the `reasoningEffort` the request already carries for measurement, then return it unchanged. Whatever effort the user picked (the per-session choice in the UI, or the effort pinned by the profile's agent-default-model) is the effort every request uses.
|
|
6
6
|
|
|
@@ -8,7 +8,8 @@ Speed comes from three things only: fewer round trips, less narration, less tool
|
|
|
8
8
|
|
|
9
9
|
## Interaction details: the bolt switch and which conversation it applies to
|
|
10
10
|
|
|
11
|
-
- **One icon, and it is the switch.** The conversation input's activity slot (`conversation.input.activity`) holds a single bolt button: hollow when off, filled when on. One click toggles it, another click toggles back. There is no gear selector, no caret, no second-level "choose a gear" menu
|
|
11
|
+
- **One icon, and it is the switch.** The conversation input's activity slot (`conversation.input.activity`) holds a single bolt button: hollow when off, filled when on. One click toggles it, another click toggles back, and that click writes only this conversation. There is no gear selector, no caret, no second-level "choose a gear" menu.
|
|
12
|
+
- **Right-click is the panel.** Right-clicking the bolt opens three shared settings: less narration (`outputDiscipline`), step cap (`stepBudget`, cycling 0/15/30), and workspace inventory (`workspaceMap`). All three write shared fields only, never `sessions`, and apply from the next request; the whole block is disabled while read-only or mid-write, and a refused write rolls back. The panel does not expose `disciplineAfterSteps`, `disciplineEarlyCalls`, `shapeGate`, `finishLineSteps`, `shellParallel` or `disciplineRepeatAtSteps` — untested or held.
|
|
12
13
|
- **The button answers one question: is this conversation on.** `aria-pressed` is the state, and the tooltip spells out "this conversation · effort unchanged · click to turn off". What makes the mode faster, where the speed comes from, and the per-call ceiling live in the plugin description (`meta.description` and the config descriptions), not in the composer.
|
|
13
14
|
- **The live line quotes the number being enforced**, not an adjective:
|
|
14
15
|
- on, with a guard ceiling: `Automatic · parallel 2–8 · one call ≤ 2 min`
|
|
@@ -361,7 +362,7 @@ Module layout:
|
|
|
361
362
|
- `src/metrics.js`: JSONL metrics and summaries;
|
|
362
363
|
- `src/benchmark.js`: per-session hash assignment;
|
|
363
364
|
- `src/peers.js`: conflicting-plugin detection;
|
|
364
|
-
- `client.js`: the bolt switch (
|
|
365
|
+
- `client.js`: the bolt switch, the right-click panel (three shared settings) and the per-conversation write.
|
|
365
366
|
|
|
366
367
|
Run the tests:
|
|
367
368
|
|
package/docs/REFERENCE.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# 参考手册:原理、配置与边界
|
|
2
2
|
|
|
3
|
-
本手册描述 **dsh-fast-mode 1.5.
|
|
3
|
+
本手册描述 **dsh-fast-mode 1.5.15** 的实际行为(默认配置下的注入行为与 1.5.0 一致;1.5.14 起多了右键面板,1.5.15 面板为三行),对应仓库里的 `index.js`、`src/` 与 `client.js`。它不是宣传页:凡是能测量的地方给出数字,凡是没测量的地方直接说没测量。
|
|
4
4
|
|
|
5
5
|
**唯一的契约:Fast 模式从不改变思考强度、thinking 预算或模型。** `agent/request` 钩子只做一件事——`await next()`,读一下请求携带的 `reasoningEffort` 记进测量,然后原样返回。用户选的是哪一档(会话里的 UI 选择,或者 profile 里 agent-default-model 固定下来的那一档),每个请求就用哪一档。
|
|
6
6
|
|
|
@@ -8,7 +8,8 @@
|
|
|
8
8
|
|
|
9
9
|
## 交互细节:闪电开关与会话归属
|
|
10
10
|
|
|
11
|
-
- **一个图标就是开关。** 会话输入区的活动槽(`conversation.input.activity
|
|
11
|
+
- **一个图标就是开关。** 会话输入区的活动槽(`conversation.input.activity`)里只有一个闪电按钮:关闭时空心,开启时实心。点一下切换,再点一下切回;这一下只写当前会话。没有档位选择器,没有箭头,没有"选择 gear"的二级菜单。
|
|
12
|
+
- **右键是面板。** 右键闪电打开三行共享设置:"更少中间输出"(`outputDiscipline`)、"步数上限"(`stepBudget`,循环 0/15/30)、"工作区清单"(`workspaceMap`)。三行都只写共享字段、不带 `sessions`,下一个回合生效;只读或写入中时整块禁用,写失败回滚。面板不暴露 `disciplineAfterSteps`、`disciplineEarlyCalls`、`shapeGate`、`finishLineSteps`、`shellParallel`、`disciplineRepeatAtSteps` 这些未证实或已判 HOLD 的旋钮。
|
|
12
13
|
- **按钮只表达一个问题:这个会话开不开。** `aria-pressed` 就是状态,tooltip 写清"仅本会话 · 思考强度不变 · 点击关闭"。为什么快、快在哪里、单次调用上限这类说明放在插件介绍(`meta.description` 与配置项描述)里,不再占用输入区。
|
|
13
14
|
- **实时行引用的是被执行的数字**,而不是产品形容词:
|
|
14
15
|
- 开启、看门狗有上限:`自动调度 · 并行 2–8 · 单次调用 ≤ 2 分`
|
|
@@ -365,7 +366,7 @@ dsh-fast-mode-experiment stop # 结束实验
|
|
|
365
366
|
- `src/metrics.js`:JSONL 计量与汇总;
|
|
366
367
|
- `src/benchmark.js`:按会话哈希分配;
|
|
367
368
|
- `src/peers.js`:冲突插件探测;
|
|
368
|
-
- `client.js
|
|
369
|
+
- `client.js`:闪电开关、右键面板(三行共享设置)与按会话的写入。
|
|
369
370
|
|
|
370
371
|
跑测试:
|
|
371
372
|
|
package/index.js
CHANGED
|
@@ -95,7 +95,7 @@ const TAG = '[fast-mode]'
|
|
|
95
95
|
* Shipped identity of this build. Traced into the debug log so a stale install is
|
|
96
96
|
* visible at a glance, and pinned by a test against `package.json`.
|
|
97
97
|
*/
|
|
98
|
-
export const VERSION = '1.5.
|
|
98
|
+
export const VERSION = '1.5.15'
|
|
99
99
|
const GLOBAL_AGENT = '__global__'
|
|
100
100
|
|
|
101
101
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-fast-mode",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.15",
|
|
4
4
|
"description": "DeepSeek Harness fast mode: same thinking effort, fewer round trips. An adaptive parallel tool fan-out, output discipline that never trims the answer, and a cancellable stall guard. Never changes reasoning effort, the model, or the request body. Provider-agnostic, one dependency (@deepseek-ai/schemastery).",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|