dsh-plugin-rollout-scout 1.4.0 → 1.4.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.
- package/README.en.md +5 -1
- package/README.md +5 -1
- package/_wrap-client.mjs +1 -1
- package/lib/client.js +4 -3
- package/lib/index.js +32 -19
- package/package.json +67 -54
- package/plugin.client.js +4 -3
package/README.en.md
CHANGED
|
@@ -3,8 +3,9 @@
|
|
|
3
3
|
English | [简体中文](README.md)
|
|
4
4
|
|
|
5
5
|
[](https://www.npmjs.com/package/dsh-plugin-rollout-scout)
|
|
6
|
+
[](https://github.com/SpookySandwich/dsh-plugin-rollout-scout/actions/workflows/ci.yml)
|
|
6
7
|
[](LICENSE)
|
|
7
|
-
[](https://github.com/deepseek-ai/deepseek-harness)
|
|
8
9
|
[](https://github.com/SpookySandwich/dsh-plugin-rollout-scout/stargazers)
|
|
9
10
|
|
|
10
11
|
Providers sometimes roll a new conversation model out gradually, so which one you get is luck of the draw. Rollout Scout opens throwaway conversations on your own account, reads each one's chain-of-thought **as it streams**, and scores how the reasoning is written — cancelling the ones that read like the model you already have, and keeping the ones that don't.
|
|
@@ -134,6 +135,9 @@ Implementation notes live in [`docs/`](docs/) — [architecture](docs/architectu
|
|
|
134
135
|
|
|
135
136
|
## Compatibility
|
|
136
137
|
|
|
138
|
+
This release targets DSH `0.1.2-rc.1`. Run `npm ci`, `npm test`, and `npm run check:package` to verify the build and package. Restart DSH after updating.
|
|
139
|
+
|
|
140
|
+
|
|
137
141
|
The launcher takes a `sidebar.footer.action` seat (a list slot, so it sits beside any other footer action rather than displacing one) and the console renders on the frame-wide `shell.overlay` layer. Neither is per-session, so it conflicts with no session plugin. Requires a DSH whose sidebar declares that seat; without it the console has no way in. Part of the same family as [dsh-plugin-smooth-stream](https://github.com/SpookySandwich/dsh-plugin-smooth-stream), [dsh-plugin-no-workspace](https://github.com/SpookySandwich/dsh-plugin-no-workspace) and [dsh-plugin-message-edit](https://github.com/SpookySandwich/dsh-plugin-message-edit).
|
|
138
142
|
|
|
139
143
|
## A note on cost
|
package/README.md
CHANGED
|
@@ -3,8 +3,9 @@
|
|
|
3
3
|
[English](README.en.md) | 简体中文
|
|
4
4
|
|
|
5
5
|
[](https://www.npmjs.com/package/dsh-plugin-rollout-scout)
|
|
6
|
+
[](https://github.com/SpookySandwich/dsh-plugin-rollout-scout/actions/workflows/ci.yml)
|
|
6
7
|
[](LICENSE)
|
|
7
|
-
[](https://github.com/deepseek-ai/deepseek-harness)
|
|
8
9
|
[](https://github.com/SpookySandwich/dsh-plugin-rollout-scout/stargazers)
|
|
9
10
|
|
|
10
11
|
服务商有时会灰度发布新的对话模型,你分到哪一个全看运气。灰度侦察会用你自己的账号开启一批临时会话,**在思维链流式输出的同时**读取它,并按「推理是怎么写的」打分——读起来像你手上这个旧模型的立刻中止,不像的留下来。
|
|
@@ -132,6 +133,9 @@ dsh plugin --profile web add github:SpookySandwich/dsh-plugin-rollout-scout
|
|
|
132
133
|
|
|
133
134
|
## 兼容性
|
|
134
135
|
|
|
136
|
+
本次兼容目标为 DSH `0.1.2-rc.1`。运行 `npm ci`、`npm test` 和 `npm run check:package` 可验证构建及发布包。更新后请重启 DSH。
|
|
137
|
+
|
|
138
|
+
|
|
135
139
|
入口占用 `sidebar.footer.action` 座位(list 类型,会与其它底部操作并排,而不是把谁挤掉),控制台本体渲染在全局 `shell.overlay` 层。两者都不属于会话作用域,因此不与任何会话内插件冲突。需要侧边栏声明了该座位的 DSH 版本;否则控制台将没有入口。与 [dsh-plugin-smooth-stream](https://github.com/SpookySandwich/dsh-plugin-smooth-stream)、[dsh-plugin-no-workspace](https://github.com/SpookySandwich/dsh-plugin-no-workspace)、[dsh-plugin-message-edit](https://github.com/SpookySandwich/dsh-plugin-message-edit) 同族。
|
|
136
140
|
|
|
137
141
|
## 关于额度
|
package/_wrap-client.mjs
CHANGED
package/lib/client.js
CHANGED
|
@@ -489,13 +489,14 @@ const CSS = [
|
|
|
489
489
|
].join('');
|
|
490
490
|
|
|
491
491
|
return {
|
|
492
|
+
inject: ['slots', 'sessions', 'locale'],
|
|
492
493
|
apply(ctx) {
|
|
493
494
|
const slots = ctx.get('slots');
|
|
494
|
-
if (slots === undefined)
|
|
495
|
+
if (slots === undefined) throw new Error('[dsh-plugin-rollout-scout] Missing DSH slots service; check client dependencies.');
|
|
495
496
|
ctx.effect(function () { return styles.insert(CSS); });
|
|
496
497
|
|
|
497
|
-
|
|
498
|
-
|
|
498
|
+
const sessions = ctx.get('sessions');
|
|
499
|
+
if (!sessions || typeof sessions.open !== 'function') throw new Error('[dsh-plugin-rollout-scout] Missing DSH session navigation service.');
|
|
499
500
|
|
|
500
501
|
const I18N_NS = 'dsh-plugin-rollout-scout';
|
|
501
502
|
const I18N = {
|
package/lib/index.js
CHANGED
|
@@ -1192,20 +1192,7 @@ function pump(ctx) {
|
|
|
1192
1192
|
state.attempts.unshift(attempt);
|
|
1193
1193
|
trimHistory();
|
|
1194
1194
|
const task = launch(ctx, attempt).catch((error) => {
|
|
1195
|
-
|
|
1196
|
-
if (attempt.stopReason === null) attempt.error = message;
|
|
1197
|
-
// Only a launch that never reached 'streaming' counts towards the
|
|
1198
|
-
// breaker: a failure after the turn started is the probe's problem,
|
|
1199
|
-
// not a sign that launching itself is broken.
|
|
1200
|
-
if (!attempt.streamed && attempt.stopReason === null) {
|
|
1201
|
-
state.launchFailures += 1;
|
|
1202
|
-
if (state.launchFailures >= LAUNCH_FAILURE_LIMIT) {
|
|
1203
|
-
state.running = false;
|
|
1204
|
-
state.paused = true;
|
|
1205
|
-
state.note = 'launch-failed';
|
|
1206
|
-
state.lastError = message;
|
|
1207
|
-
}
|
|
1208
|
-
}
|
|
1195
|
+
if (attempt.stopReason === null) recordProbeFailure(attempt, error);
|
|
1209
1196
|
finish(ctx, attempt);
|
|
1210
1197
|
}).finally(() => {
|
|
1211
1198
|
attempt.launching = false;
|
|
@@ -1314,7 +1301,7 @@ async function launch(ctx, attempt) {
|
|
|
1314
1301
|
const handle = await ctx.agents.create({
|
|
1315
1302
|
sessionId,
|
|
1316
1303
|
meta: { cwd: workspace.path },
|
|
1317
|
-
agentOptions:
|
|
1304
|
+
agentOptions: selection,
|
|
1318
1305
|
signal: attempt.launchController.signal,
|
|
1319
1306
|
setup: (agentCtx) => {
|
|
1320
1307
|
if (installModelSelection) {
|
|
@@ -1340,9 +1327,6 @@ async function launch(ctx, attempt) {
|
|
|
1340
1327
|
}
|
|
1341
1328
|
|
|
1342
1329
|
attempt.execution = 'running';
|
|
1343
|
-
attempt.streamed = true;
|
|
1344
|
-
// One probe that got as far as its first turn clears the breaker.
|
|
1345
|
-
state.launchFailures = 0;
|
|
1346
1330
|
titleAttempt(ctx, attempt, 'probe');
|
|
1347
1331
|
attempt.promptSentAt = Date.now();
|
|
1348
1332
|
armWatchdog(ctx, attempt);
|
|
@@ -1381,10 +1365,39 @@ function onSessionEvent(ctx, attempt, event) {
|
|
|
1381
1365
|
return;
|
|
1382
1366
|
}
|
|
1383
1367
|
if (event.type === 'turn/end') {
|
|
1368
|
+
// Current DSH reports request/model failures as terminal session events,
|
|
1369
|
+
// after create() and followup() have succeeded. Treating those as normal
|
|
1370
|
+
// empty replies misclassifies them and can launch replacements forever.
|
|
1371
|
+
if (attempt.stopReason === null) {
|
|
1372
|
+
if (event.data?.reason?.kind === 'error') {
|
|
1373
|
+
recordProbeFailure(attempt, event.data.reason.error);
|
|
1374
|
+
} else if (!attempt.error) {
|
|
1375
|
+
state.launchFailures = 0;
|
|
1376
|
+
}
|
|
1377
|
+
}
|
|
1384
1378
|
finish(ctx, attempt);
|
|
1385
1379
|
}
|
|
1386
1380
|
}
|
|
1387
1381
|
|
|
1382
|
+
function recordProbeFailure(attempt, error) {
|
|
1383
|
+
attempt.error = error?.message ?? String(error);
|
|
1384
|
+
if (!retained(attempt)) {
|
|
1385
|
+
attempt.verdict = 'unknown';
|
|
1386
|
+
attempt.reason = 'error';
|
|
1387
|
+
attempt.discard = 'none';
|
|
1388
|
+
resetFadeGrace(attempt);
|
|
1389
|
+
}
|
|
1390
|
+
if (attempt.failureCounted) return;
|
|
1391
|
+
attempt.failureCounted = true;
|
|
1392
|
+
state.launchFailures += 1;
|
|
1393
|
+
if (state.launchFailures >= LAUNCH_FAILURE_LIMIT) {
|
|
1394
|
+
state.running = false;
|
|
1395
|
+
state.paused = true;
|
|
1396
|
+
state.note = 'launch-failed';
|
|
1397
|
+
state.lastError = attempt.error;
|
|
1398
|
+
}
|
|
1399
|
+
}
|
|
1400
|
+
|
|
1388
1401
|
/**
|
|
1389
1402
|
* The fade grace has one owner and three derived phases:
|
|
1390
1403
|
* idle — no timer, deadline or saved remainder
|
|
@@ -2115,7 +2128,7 @@ function finish(ctx, attempt) {
|
|
|
2115
2128
|
attempt.endedAt = Date.now();
|
|
2116
2129
|
clearWatchdog(attempt);
|
|
2117
2130
|
clearCancelTimer(attempt);
|
|
2118
|
-
if (attempt.stopReason === null) {
|
|
2131
|
+
if (attempt.stopReason === null && !attempt.error) {
|
|
2119
2132
|
evaluate(ctx, attempt, true);
|
|
2120
2133
|
}
|
|
2121
2134
|
if (attempt.verdict === null) {
|
package/package.json
CHANGED
|
@@ -1,54 +1,67 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "dsh-plugin-rollout-scout",
|
|
3
|
-
"version": "1.4.
|
|
4
|
-
"description": "Detect which conversation model your DeepSeek Harness account is served: score probe conversations' live chain-of-thought, cancel old-model probes in seconds, keep confident catches.",
|
|
5
|
-
"type": "module",
|
|
6
|
-
"main": "lib/index.js",
|
|
7
|
-
"exports": {
|
|
8
|
-
".": {
|
|
9
|
-
"default": "./lib/index.js"
|
|
10
|
-
},
|
|
11
|
-
"./client": {
|
|
12
|
-
"default": "./lib/client.js"
|
|
13
|
-
},
|
|
14
|
-
"./cordis.patch.yml": "./cordis.patch.yml",
|
|
15
|
-
"./package.json": "./package.json"
|
|
16
|
-
},
|
|
17
|
-
"files": [
|
|
18
|
-
"lib",
|
|
19
|
-
"cordis.patch.yml",
|
|
20
|
-
"plugin.client.js",
|
|
21
|
-
"_wrap-client.mjs"
|
|
22
|
-
],
|
|
23
|
-
"license": "MIT",
|
|
24
|
-
"repository": {
|
|
25
|
-
"type": "git",
|
|
26
|
-
"url": "git+https://github.com/SpookySandwich/dsh-plugin-rollout-scout.git"
|
|
27
|
-
},
|
|
28
|
-
"keywords": [
|
|
29
|
-
"dsh",
|
|
30
|
-
"dsh-plugin",
|
|
31
|
-
"deepseek-harness",
|
|
32
|
-
"cordis-plugin",
|
|
33
|
-
"rollout",
|
|
34
|
-
"ab-test",
|
|
35
|
-
"model-detection"
|
|
36
|
-
],
|
|
37
|
-
"dsh": {
|
|
38
|
-
"bundle": {
|
|
39
|
-
"patch": "./cordis.patch.yml"
|
|
40
|
-
},
|
|
41
|
-
"client": {
|
|
42
|
-
"platform": "web",
|
|
43
|
-
"inject": [
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
1
|
+
{
|
|
2
|
+
"name": "dsh-plugin-rollout-scout",
|
|
3
|
+
"version": "1.4.1",
|
|
4
|
+
"description": "Detect which conversation model your DeepSeek Harness account is served: score probe conversations' live chain-of-thought, cancel old-model probes in seconds, keep confident catches.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "lib/index.js",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"default": "./lib/index.js"
|
|
10
|
+
},
|
|
11
|
+
"./client": {
|
|
12
|
+
"default": "./lib/client.js"
|
|
13
|
+
},
|
|
14
|
+
"./cordis.patch.yml": "./cordis.patch.yml",
|
|
15
|
+
"./package.json": "./package.json"
|
|
16
|
+
},
|
|
17
|
+
"files": [
|
|
18
|
+
"lib",
|
|
19
|
+
"cordis.patch.yml",
|
|
20
|
+
"plugin.client.js",
|
|
21
|
+
"_wrap-client.mjs"
|
|
22
|
+
],
|
|
23
|
+
"license": "MIT",
|
|
24
|
+
"repository": {
|
|
25
|
+
"type": "git",
|
|
26
|
+
"url": "git+https://github.com/SpookySandwich/dsh-plugin-rollout-scout.git"
|
|
27
|
+
},
|
|
28
|
+
"keywords": [
|
|
29
|
+
"dsh",
|
|
30
|
+
"dsh-plugin",
|
|
31
|
+
"deepseek-harness",
|
|
32
|
+
"cordis-plugin",
|
|
33
|
+
"rollout",
|
|
34
|
+
"ab-test",
|
|
35
|
+
"model-detection"
|
|
36
|
+
],
|
|
37
|
+
"dsh": {
|
|
38
|
+
"bundle": {
|
|
39
|
+
"patch": "./cordis.patch.yml"
|
|
40
|
+
},
|
|
41
|
+
"client": {
|
|
42
|
+
"platform": "web",
|
|
43
|
+
"inject": [
|
|
44
|
+
"@deepseek-ai/dsh-api-session-controller",
|
|
45
|
+
"@deepseek-ai/dsh-client-locale",
|
|
46
|
+
"@deepseek-ai/dsh-client-ui-slots",
|
|
47
|
+
"@deepseek-ai/dsh-client-ui-layout",
|
|
48
|
+
"@deepseek-ai/dsh-client-modules"
|
|
49
|
+
]
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
"scripts": {
|
|
53
|
+
"build": "node _wrap-client.mjs",
|
|
54
|
+
"prepare": "node _wrap-client.mjs",
|
|
55
|
+
"prepack": "node _wrap-client.mjs",
|
|
56
|
+
"pretest": "node _wrap-client.mjs",
|
|
57
|
+
"test": "node test/classifier.test.mjs && node test/route.test.mjs && node test/pump.test.mjs && node test/delete.test.mjs && node test/lifecycle.test.mjs && node test/ownership.test.mjs && node test/manifest.test.mjs && node test/manifest-concurrency.test.mjs && node test/manifest-process.test.mjs && node test/history.test.mjs && node test/state-machine.test.mjs && node test/client-review.test.mjs && node test/client-anchor.test.mjs && node test/client-css.test.mjs && node --test test/client-loading.test.mjs && node --test test/probe-errors.test.mjs",
|
|
58
|
+
"check:client": "node _wrap-client.mjs && git diff --exit-code -- lib/client.js",
|
|
59
|
+
"check:package": "node scripts/check-package.mjs"
|
|
60
|
+
},
|
|
61
|
+
"devDependencies": {
|
|
62
|
+
"@deepseek-ai/cordis": "^4.0.2",
|
|
63
|
+
"jsdom": "^29.1.1",
|
|
64
|
+
"react": "^18.3.1",
|
|
65
|
+
"react-dom": "^18.3.1"
|
|
66
|
+
}
|
|
67
|
+
}
|
package/plugin.client.js
CHANGED
|
@@ -469,13 +469,14 @@ const CSS = [
|
|
|
469
469
|
].join('');
|
|
470
470
|
|
|
471
471
|
return {
|
|
472
|
+
inject: ['slots', 'sessions', 'locale'],
|
|
472
473
|
apply(ctx) {
|
|
473
474
|
const slots = ctx.get('slots');
|
|
474
|
-
if (slots === undefined)
|
|
475
|
+
if (slots === undefined) throw new Error('[dsh-plugin-rollout-scout] Missing DSH slots service; check client dependencies.');
|
|
475
476
|
ctx.effect(function () { return styles.insert(CSS); });
|
|
476
477
|
|
|
477
|
-
|
|
478
|
-
|
|
478
|
+
const sessions = ctx.get('sessions');
|
|
479
|
+
if (!sessions || typeof sessions.open !== 'function') throw new Error('[dsh-plugin-rollout-scout] Missing DSH session navigation service.');
|
|
479
480
|
|
|
480
481
|
const I18N_NS = 'dsh-plugin-rollout-scout';
|
|
481
482
|
const I18N = {
|