dsh-input-traffic 0.2.10-beta.3 → 0.2.11-beta.2
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/CHANGELOG.md +17 -9
- package/INSTALL.md +11 -0
- package/INSTALL.zh.md +11 -0
- package/README.md +7 -7
- package/dsh.plugin.json +4 -1
- package/lib/client.js +30 -30
- package/lib/client.js.map +1 -1
- package/lib/types/client/freeze-button.d.ts +16 -16
- package/lib/types/client/index.d.ts +1 -1
- package/lib/types/client/index.d.ts.map +1 -1
- package/lib/types/client/index.js +117 -117
- package/lib/types/client/index.js.map +1 -1
- package/package.json +16 -7
- package/lib/types/client/auto-continue-core.d.ts +0 -103
- package/lib/types/client/auto-continue-core.d.ts.map +0 -1
- package/lib/types/client/auto-continue-core.js +0 -131
- package/lib/types/client/auto-continue-core.js.map +0 -1
- package/lib/types/client/auto-continue-store.d.ts +0 -41
- package/lib/types/client/auto-continue-store.d.ts.map +0 -1
- package/lib/types/client/auto-continue-store.js +0 -93
- package/lib/types/client/auto-continue-store.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/client/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,OAAO,KAAK,EAAE,aAAa,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/client/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,OAAO,KAAK,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAiBnE;;;;;;;;;;GAUG;AACH,eAAO,MAAM,gBAAgB,OAAO,CAAA;AAkBpC,6CAA6C;AAC7C,eAAO,MAAM,MAAM,UAAmE,CAAA;AAEtF;;;;GAIG;AACH,wBAAgB,KAAK,CAAC,GAAG,EAAE,aAAa,GAAG,IAAI,CAyE9C"}
|
|
@@ -1,118 +1,118 @@
|
|
|
1
|
-
import { NS, en, zh } from "./locales.js";
|
|
2
|
-
import { SteerQueueDock } from "./steer-queue-dock.js";
|
|
3
|
-
import { FreezeButton } from "./freeze-button.js";
|
|
4
|
-
import { HideEnterRow } from "./hide-enter-row.js";
|
|
5
|
-
/** Durable conversation settings namespace owned by ui-conversation. */
|
|
6
|
-
const CONVERSATION_SETTINGS_NAMESPACE = 'ui-conversation';
|
|
7
|
-
/** Busy-Enter field inside that namespace; the plugin pins it to queue. */
|
|
8
|
-
const BUSY_ENTER_FIELD = 'busyEnter';
|
|
9
|
-
/**
|
|
10
|
-
* Display order of the queue strip inside `conversation.input.dock`.
|
|
11
|
-
*
|
|
12
|
-
* List rows render sorted by `order` ascending, so a value above every other
|
|
13
|
-
* contributor keeps the strip as the bottom-most entry of the band — directly
|
|
14
|
-
* on top of the composer card. Known contributors in both 0.1.1-rc.2 and
|
|
15
|
-
* 0.1.2-rc.1: `todo` 0, `goal` 10, official `queue` 20, `dsh-perm-gate.notice`
|
|
16
|
-
* 30. DSH has no "last" slot semantics, so this is a convention, not a
|
|
17
|
-
* structural guarantee: a third party registering a larger value could still
|
|
18
|
-
* land below us.
|
|
19
|
-
*/
|
|
20
|
-
export const QUEUE_DOCK_ORDER = 1000;
|
|
21
|
-
/**
|
|
22
|
-
* Deliver one plain-text message into the session's next step. The exposed
|
|
23
|
-
* conversation `send` verb only queues into the next turn, so resume steers
|
|
24
|
-
* through the session face's steer-mode prompt instead (no harness change).
|
|
25
|
-
* @param ctx - root context (resolves the session face behind the scope).
|
|
26
|
-
* @param actx - agent-scoped context of the owning session.
|
|
27
|
-
* @param text - message text to deliver.
|
|
28
|
-
*/
|
|
29
|
-
function steerPrompt(actx, text) {
|
|
30
|
-
// steer-mode prompt 面在本版(main@0.2.8)契约中未声明;resume 落到 conversation.send
|
|
31
|
-
// (排队到下一轮)交付 safe_point 文本,与 feature 分支语义对齐但取当前可用 API。
|
|
32
|
-
const conversation = actx.get('conversation');
|
|
33
|
-
if (conversation === undefined)
|
|
34
|
-
return Promise.reject(new Error('steer resume: conversation service unavailable'));
|
|
35
|
-
return conversation.send(text);
|
|
36
|
-
}
|
|
37
|
-
/** Services required by the browser half. */
|
|
38
|
-
export const inject = ['slots', 'locale', 'sessions', 'conversation', 'settingsScope'];
|
|
39
|
-
/**
|
|
40
|
-
* Client plugin body: dictionaries, busy-Enter pinning, and the two slot
|
|
41
|
-
* shadowings.
|
|
42
|
-
* @param ctx - client root context.
|
|
43
|
-
*/
|
|
44
|
-
export function apply(ctx) {
|
|
45
|
-
ctx.effect(() => ctx.locale.register(NS, { zh, en }), 'dsh-input-traffic: dictionaries');
|
|
46
|
-
// Take over the busy-Enter behavior: plain Enter stays queue-later while
|
|
47
|
-
// the official row is hidden. Pinning here also repairs a persisted `steer`
|
|
48
|
-
// preference that would otherwise keep working invisibly behind the hidden
|
|
49
|
-
// row. Best-effort: a memory-mode host simply accepts it locally.
|
|
50
|
-
const conversationSettings = ctx.settingsScope.bind({
|
|
51
|
-
namespace: CONVERSATION_SETTINGS_NAMESPACE,
|
|
52
|
-
});
|
|
53
|
-
void conversationSettings.set(BUSY_ENTER_FIELD, 'queue');
|
|
54
|
-
// Shadow the official queue dock with the three-tier planning strip. The
|
|
55
|
-
// high `order` keeps it the bottom-most entry of the band (see the file
|
|
56
|
-
// header); `priority: -1` is what wins the official `queue` cell.
|
|
57
|
-
ctx.slots.inject('conversation.input.dock', () => ctx.slots.register({
|
|
58
|
-
name: 'conversation.input.dock',
|
|
59
|
-
id: 'queue',
|
|
60
|
-
order: QUEUE_DOCK_ORDER,
|
|
61
|
-
priority: -1,
|
|
62
|
-
locale: NS,
|
|
63
|
-
inject: (sessionId) => {
|
|
64
|
-
const actx = ctx.sessions.scope(sessionId);
|
|
65
|
-
if (actx === undefined)
|
|
66
|
-
throw new Error(`steer dock: session "${sessionId}" resolved no scope`);
|
|
67
|
-
const conversation = actx.get('conversation');
|
|
68
|
-
if (conversation === undefined)
|
|
69
|
-
throw new Error('steer dock: conversation service unavailable');
|
|
70
|
-
return {
|
|
71
|
-
updateQueue: (itemId, action) => conversation.updateQueue(itemId, action),
|
|
72
|
-
cancel: () => conversation.cancel(),
|
|
73
|
-
send: (text) => conversation.send(text),
|
|
74
|
-
setDraft: (text) => { conversation.input.for(actx).actions.setDraft(text); },
|
|
75
|
-
notify: (level, text) => { conversation.input.for(actx).notify(level, text); },
|
|
76
|
-
};
|
|
77
|
-
},
|
|
78
|
-
}, SteerQueueDock));
|
|
79
|
-
// Composer-right freeze/resume control (reachable before anything queues).
|
|
80
|
-
ctx.slots.inject('conversation.input.right', () => ctx.slots.register({
|
|
81
|
-
name: 'conversation.input.right',
|
|
82
|
-
id: 'steer-freeze',
|
|
83
|
-
order: 30,
|
|
84
|
-
locale: NS,
|
|
85
|
-
inject: (sessionId) => {
|
|
86
|
-
const actx = ctx.sessions.scope(sessionId);
|
|
87
|
-
if (actx === undefined)
|
|
88
|
-
throw new Error(`steer freeze: session "${sessionId}" resolved no scope`);
|
|
89
|
-
const conversation = actx.get('conversation');
|
|
90
|
-
if (conversation === undefined)
|
|
91
|
-
throw new Error('steer freeze: conversation service unavailable');
|
|
92
|
-
return {
|
|
93
|
-
updateQueue: (itemId, action) => conversation.updateQueue(itemId, action),
|
|
94
|
-
cancel: () => conversation.cancel(),
|
|
95
|
-
send: (text) => conversation.send(text),
|
|
96
|
-
// safe_point 恢复经 conversation.send 排队到下一轮(本版契约无 steer prompt 面)。
|
|
97
|
-
sendSteer: (text) => steerPrompt(actx, text),
|
|
98
|
-
sessionId: String(sessionId),
|
|
99
|
-
setDraft: (text) => { conversation.input.for(actx).actions.setDraft(text); },
|
|
100
|
-
notify: (level, text) => { conversation.input.for(actx).notify(level, text); },
|
|
101
|
-
// 冻结期间 raise composer block:composer 变 inert(回车/发送按钮全部失效),
|
|
102
|
-
// 输入不会漏进对话;恢复时清除。block 不锁 input.right(恢复按钮仍可点)。
|
|
103
|
-
setComposerBlock: (reason) => {
|
|
104
|
-
conversation.blocks.set(sessionId, reason === undefined ? undefined : { reason });
|
|
105
|
-
},
|
|
106
|
-
};
|
|
107
|
-
},
|
|
108
|
-
}, FreezeButton));
|
|
109
|
-
// Hide the official busy-Enter settings row (null render wins the cell).
|
|
110
|
-
ctx.slots.inject('settings.general.item', () => ctx.slots.register({
|
|
111
|
-
name: 'settings.general.item',
|
|
112
|
-
id: 'composer-enter',
|
|
113
|
-
order: 20,
|
|
114
|
-
priority: -1,
|
|
115
|
-
locale: NS,
|
|
116
|
-
}, HideEnterRow));
|
|
117
|
-
}
|
|
1
|
+
import { NS, en, zh } from "./locales.js";
|
|
2
|
+
import { SteerQueueDock } from "./steer-queue-dock.js";
|
|
3
|
+
import { FreezeButton } from "./freeze-button.js";
|
|
4
|
+
import { HideEnterRow } from "./hide-enter-row.js";
|
|
5
|
+
/** Durable conversation settings namespace owned by ui-conversation. */
|
|
6
|
+
const CONVERSATION_SETTINGS_NAMESPACE = 'ui-conversation';
|
|
7
|
+
/** Busy-Enter field inside that namespace; the plugin pins it to queue. */
|
|
8
|
+
const BUSY_ENTER_FIELD = 'busyEnter';
|
|
9
|
+
/**
|
|
10
|
+
* Display order of the queue strip inside `conversation.input.dock`.
|
|
11
|
+
*
|
|
12
|
+
* List rows render sorted by `order` ascending, so a value above every other
|
|
13
|
+
* contributor keeps the strip as the bottom-most entry of the band — directly
|
|
14
|
+
* on top of the composer card. Known contributors in both 0.1.1-rc.2 and
|
|
15
|
+
* 0.1.2-rc.1: `todo` 0, `goal` 10, official `queue` 20, `dsh-perm-gate.notice`
|
|
16
|
+
* 30. DSH has no "last" slot semantics, so this is a convention, not a
|
|
17
|
+
* structural guarantee: a third party registering a larger value could still
|
|
18
|
+
* land below us.
|
|
19
|
+
*/
|
|
20
|
+
export const QUEUE_DOCK_ORDER = 1000;
|
|
21
|
+
/**
|
|
22
|
+
* Deliver one plain-text message into the session's next step. The exposed
|
|
23
|
+
* conversation `send` verb only queues into the next turn, so resume steers
|
|
24
|
+
* through the session face's steer-mode prompt instead (no harness change).
|
|
25
|
+
* @param ctx - root context (resolves the session face behind the scope).
|
|
26
|
+
* @param actx - agent-scoped context of the owning session.
|
|
27
|
+
* @param text - message text to deliver.
|
|
28
|
+
*/
|
|
29
|
+
function steerPrompt(actx, text) {
|
|
30
|
+
// steer-mode prompt 面在本版(main@0.2.8)契约中未声明;resume 落到 conversation.send
|
|
31
|
+
// (排队到下一轮)交付 safe_point 文本,与 feature 分支语义对齐但取当前可用 API。
|
|
32
|
+
const conversation = actx.get('conversation');
|
|
33
|
+
if (conversation === undefined)
|
|
34
|
+
return Promise.reject(new Error('steer resume: conversation service unavailable'));
|
|
35
|
+
return conversation.send(text);
|
|
36
|
+
}
|
|
37
|
+
/** Services required by the browser half. */
|
|
38
|
+
export const inject = ['slots', 'locale', 'sessions', 'conversation', 'settingsScope'];
|
|
39
|
+
/**
|
|
40
|
+
* Client plugin body: dictionaries, busy-Enter pinning, and the two slot
|
|
41
|
+
* shadowings.
|
|
42
|
+
* @param ctx - client root context.
|
|
43
|
+
*/
|
|
44
|
+
export function apply(ctx) {
|
|
45
|
+
ctx.effect(() => ctx.locale.register(NS, { zh, en }), 'dsh-input-traffic: dictionaries');
|
|
46
|
+
// Take over the busy-Enter behavior: plain Enter stays queue-later while
|
|
47
|
+
// the official row is hidden. Pinning here also repairs a persisted `steer`
|
|
48
|
+
// preference that would otherwise keep working invisibly behind the hidden
|
|
49
|
+
// row. Best-effort: a memory-mode host simply accepts it locally.
|
|
50
|
+
const conversationSettings = ctx.settingsScope.bind({
|
|
51
|
+
namespace: CONVERSATION_SETTINGS_NAMESPACE,
|
|
52
|
+
});
|
|
53
|
+
void conversationSettings.set(BUSY_ENTER_FIELD, 'queue');
|
|
54
|
+
// Shadow the official queue dock with the three-tier planning strip. The
|
|
55
|
+
// high `order` keeps it the bottom-most entry of the band (see the file
|
|
56
|
+
// header); `priority: -1` is what wins the official `queue` cell.
|
|
57
|
+
ctx.slots.inject('conversation.input.dock', () => ctx.slots.register({
|
|
58
|
+
name: 'conversation.input.dock',
|
|
59
|
+
id: 'queue',
|
|
60
|
+
order: QUEUE_DOCK_ORDER,
|
|
61
|
+
priority: -1,
|
|
62
|
+
locale: NS,
|
|
63
|
+
inject: (sessionId) => {
|
|
64
|
+
const actx = ctx.sessions.scope(sessionId);
|
|
65
|
+
if (actx === undefined)
|
|
66
|
+
throw new Error(`steer dock: session "${sessionId}" resolved no scope`);
|
|
67
|
+
const conversation = actx.get('conversation');
|
|
68
|
+
if (conversation === undefined)
|
|
69
|
+
throw new Error('steer dock: conversation service unavailable');
|
|
70
|
+
return {
|
|
71
|
+
updateQueue: (itemId, action) => conversation.updateQueue(itemId, action),
|
|
72
|
+
cancel: () => conversation.cancel(),
|
|
73
|
+
send: (text) => conversation.send(text),
|
|
74
|
+
setDraft: (text) => { conversation.input.for(actx).actions.setDraft(text); },
|
|
75
|
+
notify: (level, text) => { conversation.input.for(actx).notify(level, text); },
|
|
76
|
+
};
|
|
77
|
+
},
|
|
78
|
+
}, SteerQueueDock));
|
|
79
|
+
// Composer-right freeze/resume control (reachable before anything queues).
|
|
80
|
+
ctx.slots.inject('conversation.input.right', () => ctx.slots.register({
|
|
81
|
+
name: 'conversation.input.right',
|
|
82
|
+
id: 'steer-freeze',
|
|
83
|
+
order: 30,
|
|
84
|
+
locale: NS,
|
|
85
|
+
inject: (sessionId) => {
|
|
86
|
+
const actx = ctx.sessions.scope(sessionId);
|
|
87
|
+
if (actx === undefined)
|
|
88
|
+
throw new Error(`steer freeze: session "${sessionId}" resolved no scope`);
|
|
89
|
+
const conversation = actx.get('conversation');
|
|
90
|
+
if (conversation === undefined)
|
|
91
|
+
throw new Error('steer freeze: conversation service unavailable');
|
|
92
|
+
return {
|
|
93
|
+
updateQueue: (itemId, action) => conversation.updateQueue(itemId, action),
|
|
94
|
+
cancel: () => conversation.cancel(),
|
|
95
|
+
send: (text) => conversation.send(text),
|
|
96
|
+
// safe_point 恢复经 conversation.send 排队到下一轮(本版契约无 steer prompt 面)。
|
|
97
|
+
sendSteer: (text) => steerPrompt(actx, text),
|
|
98
|
+
sessionId: String(sessionId),
|
|
99
|
+
setDraft: (text) => { conversation.input.for(actx).actions.setDraft(text); },
|
|
100
|
+
notify: (level, text) => { conversation.input.for(actx).notify(level, text); },
|
|
101
|
+
// 冻结期间 raise composer block:composer 变 inert(回车/发送按钮全部失效),
|
|
102
|
+
// 输入不会漏进对话;恢复时清除。block 不锁 input.right(恢复按钮仍可点)。
|
|
103
|
+
setComposerBlock: (reason) => {
|
|
104
|
+
conversation.blocks.set(sessionId, reason === undefined ? undefined : { reason });
|
|
105
|
+
},
|
|
106
|
+
};
|
|
107
|
+
},
|
|
108
|
+
}, FreezeButton));
|
|
109
|
+
// Hide the official busy-Enter settings row (null render wins the cell).
|
|
110
|
+
ctx.slots.inject('settings.general.item', () => ctx.slots.register({
|
|
111
|
+
name: 'settings.general.item',
|
|
112
|
+
id: 'composer-enter',
|
|
113
|
+
order: 20,
|
|
114
|
+
priority: -1,
|
|
115
|
+
locale: NS,
|
|
116
|
+
}, HideEnterRow));
|
|
117
|
+
}
|
|
118
118
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/client/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/client/index.ts"],"names":[],"mappings":"AA+BA,OAAO,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,MAAM,cAAc,CAAA;AACzC,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAwB,CAAA;AAEvD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAqB,CAAA;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAsB,CAAA;AAEnD,wEAAwE;AACxE,MAAM,+BAA+B,GAAG,iBAAiB,CAAA;AAEzD,2EAA2E;AAC3E,MAAM,gBAAgB,GAAG,WAAW,CAAA;AAEpC;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,IAAI,CAAA;AAEpC;;;;;;;GAOG;AACH,SAAS,WAAW,CAAC,IAAmB,EAAE,IAAY;IACpD,uEAAuE;IACvE,uDAAuD;IACvD,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,cAAc,CAAC,CAAA;IAC7C,IAAI,YAAY,KAAK,SAAS;QAAE,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAC,CAAA;IAClH,OAAO,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AAChC,CAAC;AAED,6CAA6C;AAC7C,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,cAAc,EAAE,eAAe,CAAC,CAAA;AAEtF;;;;GAIG;AACH,MAAM,UAAU,KAAK,CAAC,GAAkB;IACtC,GAAG,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,iCAAiC,CAAC,CAAA;IAExF,yEAAyE;IACzE,4EAA4E;IAC5E,2EAA2E;IAC3E,kEAAkE;IAClE,MAAM,oBAAoB,GAAG,GAAG,CAAC,aAAa,CAAC,IAAI,CAAmC;QACpF,SAAS,EAAE,+BAA+B;KAC3C,CAAC,CAAA;IACF,KAAK,oBAAoB,CAAC,GAAG,CAAC,gBAAgB,EAAE,OAAO,CAAC,CAAA;IAExD,yEAAyE;IACzE,wEAAwE;IACxE,kEAAkE;IAClE,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,yBAAyB,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC;QACnE,IAAI,EAAE,yBAAyB;QAC/B,EAAE,EAAE,OAAO;QACX,KAAK,EAAE,gBAAgB;QACvB,QAAQ,EAAE,CAAC,CAAC;QACZ,MAAM,EAAE,EAAE;QACV,MAAM,EAAE,CAAC,SAAoB,EAA0B,EAAE;YACvD,MAAM,IAAI,GAAG,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,SAAS,CAAC,CAAA;YAC1C,IAAI,IAAI,KAAK,SAAS;gBAAE,MAAM,IAAI,KAAK,CAAC,wBAAwB,SAAS,qBAAqB,CAAC,CAAA;YAC/F,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,cAAc,CAAC,CAAA;YAC7C,IAAI,YAAY,KAAK,SAAS;gBAAE,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAA;YAC/F,OAAO;gBACL,WAAW,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,CAAC,YAAY,CAAC,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC;gBACzE,MAAM,EAAE,GAAG,EAAE,CAAC,YAAY,CAAC,MAAM,EAAE;gBACnC,IAAI,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC;gBACvC,QAAQ,EAAE,CAAC,IAAI,EAAE,EAAE,GAAG,YAAY,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAA,CAAC,CAAC;gBAC3E,MAAM,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,GAAG,YAAY,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,CAAA,CAAC,CAAC;aAC9E,CAAA;QACH,CAAC;KACF,EAAE,cAAc,CAAC,CAAC,CAAA;IAEnB,2EAA2E;IAC3E,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,0BAA0B,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC;QACpE,IAAI,EAAE,0BAA0B;QAChC,EAAE,EAAE,cAAc;QAClB,KAAK,EAAE,EAAE;QACT,MAAM,EAAE,EAAE;QACV,MAAM,EAAE,CAAC,SAAoB,EAA0B,EAAE;YACvD,MAAM,IAAI,GAAG,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,SAAS,CAAC,CAAA;YAC1C,IAAI,IAAI,KAAK,SAAS;gBAAE,MAAM,IAAI,KAAK,CAAC,0BAA0B,SAAS,qBAAqB,CAAC,CAAA;YACjG,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,cAAc,CAAC,CAAA;YAC7C,IAAI,YAAY,KAAK,SAAS;gBAAE,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAA;YACjG,OAAO;gBACL,WAAW,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,CAAC,YAAY,CAAC,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC;gBACzE,MAAM,EAAE,GAAG,EAAE,CAAC,YAAY,CAAC,MAAM,EAAE;gBACnC,IAAI,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC;gBACvC,iEAAiE;gBACjE,SAAS,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,WAAW,CAAC,IAAI,EAAE,IAAI,CAAC;gBAC5C,SAAS,EAAE,MAAM,CAAC,SAAS,CAAC;gBAC5B,QAAQ,EAAE,CAAC,IAAI,EAAE,EAAE,GAAG,YAAY,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAA,CAAC,CAAC;gBAC3E,MAAM,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,GAAG,YAAY,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,CAAA,CAAC,CAAC;gBAC7E,2DAA2D;gBAC3D,gDAAgD;gBAChD,gBAAgB,EAAE,CAAC,MAAM,EAAE,EAAE;oBAC3B,YAAY,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,EAAE,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAA;gBACnF,CAAC;aACF,CAAA;QACH,CAAC;KACF,EAAE,YAAY,CAAC,CAAC,CAAA;IAEjB,yEAAyE;IACzE,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,uBAAuB,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC;QACjE,IAAI,EAAE,uBAAuB;QAC7B,EAAE,EAAE,gBAAgB;QACpB,KAAK,EAAE,EAAE;QACT,QAAQ,EAAE,CAAC,CAAC;QACZ,MAAM,EAAE,EAAE;KACX,EAAE,YAAY,CAAC,CAAC,CAAA;AACnB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-input-traffic",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.11-beta.2",
|
|
4
|
+
"publishConfig": {
|
|
5
|
+
"registry": "https://registry.npmjs.org",
|
|
6
|
+
"access": "public",
|
|
7
|
+
"tag": "beta"
|
|
8
|
+
},
|
|
4
9
|
"type": "module",
|
|
5
10
|
"description": "Busy-time input queue for the DeepSeek Harness web GUI: three-tier (now/next/later) planning, queue editing with drag-to-reorder and concurrency protection, interject (steer) and interrupt, batch clear with confirm, session freeze - a cordis client plugin, no dsh source changes, no PR required",
|
|
6
11
|
"repository": {
|
|
@@ -59,16 +64,17 @@
|
|
|
59
64
|
},
|
|
60
65
|
"engines": {
|
|
61
66
|
"node": ">=20",
|
|
62
|
-
"dsh": ">=0.1.
|
|
67
|
+
"dsh": ">=0.1.2-alpha.1 <0.2.0-0"
|
|
63
68
|
},
|
|
64
69
|
"license": "MIT",
|
|
65
70
|
"peerDependencies": {
|
|
66
71
|
"@deepseek-ai/cordis": "^4.0.1",
|
|
67
|
-
"@deepseek-ai/dsh-client-locale": "
|
|
68
|
-
"@deepseek-ai/dsh-client-ui-conversation": "
|
|
69
|
-
"@deepseek-ai/dsh-client-ui-primitives": "
|
|
70
|
-
"@deepseek-ai/dsh-client-ui-settings": "
|
|
71
|
-
"@deepseek-ai/dsh-client-ui-slots": "
|
|
72
|
+
"@deepseek-ai/dsh-client-locale": ">=0.1.2-alpha.1 <0.2.0-0",
|
|
73
|
+
"@deepseek-ai/dsh-client-ui-conversation": ">=0.1.2-alpha.1 <0.2.0-0",
|
|
74
|
+
"@deepseek-ai/dsh-client-ui-primitives": ">=0.1.2-alpha.1 <0.2.0-0",
|
|
75
|
+
"@deepseek-ai/dsh-client-ui-settings": ">=0.1.2-alpha.1 <0.2.0-0",
|
|
76
|
+
"@deepseek-ai/dsh-client-ui-slots": ">=0.1.2-alpha.1 <0.2.0-0",
|
|
77
|
+
"@deepseek-ai/dsh-session": ">=0.1.2-alpha.1 <0.2.0-0"
|
|
72
78
|
},
|
|
73
79
|
"peerDependenciesMeta": {
|
|
74
80
|
"@deepseek-ai/cordis": {
|
|
@@ -88,6 +94,9 @@
|
|
|
88
94
|
},
|
|
89
95
|
"@deepseek-ai/dsh-client-ui-slots": {
|
|
90
96
|
"optional": true
|
|
97
|
+
},
|
|
98
|
+
"@deepseek-ai/dsh-session": {
|
|
99
|
+
"optional": true
|
|
91
100
|
}
|
|
92
101
|
},
|
|
93
102
|
"devDependencies": {
|
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Auto-continue core — 平台无关的纯逻辑, 吸收自 dsh-auto-continue
|
|
3
|
-
* (https://github.com/HsiangNianian/dsh-auto-continue, MIT, v0.8.1 的
|
|
4
|
-
* src/shared/core.ts), 按 input-traffic 的纯 client 定位裁剪:
|
|
5
|
-
*
|
|
6
|
-
* - 只吸收「错误分类 / 自适应退避 / 幂等护栏 / 模板填充」这些无宿主依赖的纯函数;
|
|
7
|
-
* - 不吸收宿主引擎(host firehose / agent.followup / SSE 桥)——那会破坏本插件
|
|
8
|
-
* 「纯浏览器侧、不改官方源码」的定位, 且与「冻结会话省钱」方向相反(见 README 兼容性);
|
|
9
|
-
* - 全部函数无任何 @deepseek-ai/* 值导入, 通过 client bundle purity gate。
|
|
10
|
-
*
|
|
11
|
-
* 应用场景: dock 的「续跑」——检测到会话停下但排队消息未处理完(疑似中断)时,
|
|
12
|
-
* 分类失败、按退避节奏重发, 永久性错误则停止并提示人工介入。
|
|
13
|
-
*/
|
|
14
|
-
/** 一次发送失败的可分类事实(从 send 的 reject error 里提取)。 */
|
|
15
|
-
export interface FailureFacts {
|
|
16
|
-
/** 稳定机器路由码(如 UPSTREAM、RATE_LIMIT_EXCEEDED)。 */
|
|
17
|
-
code?: string;
|
|
18
|
-
/** 人类可读的失败描述。 */
|
|
19
|
-
message: string;
|
|
20
|
-
/** 供应商 HTTP 状态码(可用时)。 */
|
|
21
|
-
status?: number;
|
|
22
|
-
}
|
|
23
|
-
/**
|
|
24
|
-
* 错误分类: 该失败是否值得重试续跑。
|
|
25
|
-
* 永久性失败(认证/余额/模型不存在/上下文超限等)重试也不会成功, 应停止并提示用户;
|
|
26
|
-
* 其余(网络、超时、5xx、429 等)视为临时性失败, 允许自动重发。
|
|
27
|
-
*/
|
|
28
|
-
export declare function isTransientFailure(failure: FailureFacts): boolean;
|
|
29
|
-
/**
|
|
30
|
-
* 消息文本分类: 仅明确属于网络/传输类的临时错误才值得重试。
|
|
31
|
-
* 其余(序列化失败、配置/宿主内部错误等)视为永久性——重试无益。
|
|
32
|
-
*/
|
|
33
|
-
export declare function isTransientAgentError(message: string): boolean;
|
|
34
|
-
/** 自适应退避: 同一会话连续失败时的有效重试间隔。 */
|
|
35
|
-
export declare function effectiveCooldown(consecutive: number, base: number, factor: number, max: number): number;
|
|
36
|
-
/** 模板填充所需上下文(全部可选, 缺失的占位符填为空串)。 */
|
|
37
|
-
export interface TemplateContext {
|
|
38
|
-
/** 失败事实(错误码/消息/HTTP 状态), 对应 {code}/{message}/{status}。 */
|
|
39
|
-
facts?: FailureFacts;
|
|
40
|
-
/** 失败前最后一次工具调用的名称, 对应 {tool}。 */
|
|
41
|
-
tool?: string;
|
|
42
|
-
/** 连续失败次数(含本次), 对应 {errorCount}。 */
|
|
43
|
-
errorCount?: number;
|
|
44
|
-
/** 自失败发生以来的毫秒数, 对应 {elapsed}。 */
|
|
45
|
-
elapsedMs?: number;
|
|
46
|
-
/** 上一步工具结果摘要(截断), 对应 {result}(护栏模板用)。 */
|
|
47
|
-
result?: string;
|
|
48
|
-
}
|
|
49
|
-
/** 把毫秒格式化为人类可读的经过时长(如 65s → 1m5s)。 */
|
|
50
|
-
export declare function formatElapsed(ms: number | undefined): string;
|
|
51
|
-
/** 用失败事实填充续跑模板占位符({code}/{message}/{status}/{tool}/{errorCount}/{elapsed}/{result})。 */
|
|
52
|
-
export declare function fillTemplate(template: string, ctx: TemplateContext): string;
|
|
53
|
-
/** 上一步工具调用的判定结果: 是否已确认完成, 以及文本摘要。 */
|
|
54
|
-
export interface ToolResultFacts {
|
|
55
|
-
/** 工具是否成功完成(内部失败或 isError 视为未成功)。 */
|
|
56
|
-
ok: boolean;
|
|
57
|
-
/** 工具输出的文本摘要(截断)。 */
|
|
58
|
-
excerpt: string;
|
|
59
|
-
}
|
|
60
|
-
/** 从 tool/result 事件载荷提取成功与否与文本摘要(幂等护栏: 续跑时提示别重复执行)。 */
|
|
61
|
-
export declare function toolResultFacts(data: {
|
|
62
|
-
error?: {
|
|
63
|
-
name?: string;
|
|
64
|
-
code?: string;
|
|
65
|
-
};
|
|
66
|
-
message?: {
|
|
67
|
-
content?: Array<{
|
|
68
|
-
type?: string;
|
|
69
|
-
content?: unknown;
|
|
70
|
-
isError?: boolean;
|
|
71
|
-
}>;
|
|
72
|
-
};
|
|
73
|
-
}): ToolResultFacts;
|
|
74
|
-
/** 续跑配置(全部可选, 解析时回落默认值)。 */
|
|
75
|
-
export interface AutoContinueSettings {
|
|
76
|
-
/** 续跑时自动发送的消息文本(可含模板占位符)。 */
|
|
77
|
-
continueText?: string;
|
|
78
|
-
/** 宽限期: 停下多久后视为中断再自动重发(ms)。 */
|
|
79
|
-
graceMs?: number;
|
|
80
|
-
/** 同一会话两次自动续跑的最小间隔(ms)。 */
|
|
81
|
-
cooldownMs?: number;
|
|
82
|
-
/** 连续自动续跑上限; 超过后停止, 直到用户介入或成功回合。 */
|
|
83
|
-
maxConsecutive?: number;
|
|
84
|
-
/** 连续失败时的退避系数。 */
|
|
85
|
-
backoffFactor?: number;
|
|
86
|
-
/** 自适应退避的上限(ms)。 */
|
|
87
|
-
backoffMaxMs?: number;
|
|
88
|
-
/**
|
|
89
|
-
* 自动续跑: 检测到疑似中断时自动重发排队消息。
|
|
90
|
-
* 默认关闭——纯 client 拿不到 turn/end reason, 无法区分「用户主动停止」与
|
|
91
|
-
* 「非人为中断」, 故默认只提示不擅自续跑(与 auto-continue 的 paused 不同)。
|
|
92
|
-
*/
|
|
93
|
-
autoResume?: boolean;
|
|
94
|
-
/** 全局暂停续跑(如冻结期间)。 */
|
|
95
|
-
paused?: boolean;
|
|
96
|
-
}
|
|
97
|
-
/** 完全解析后的续跑配置(内置默认值 + 用户覆盖)。 */
|
|
98
|
-
export type AutoContinueConfig = Required<AutoContinueSettings>;
|
|
99
|
-
/** 内置默认值(与 dock 的 localStorage 持久化键一致)。 */
|
|
100
|
-
export declare const DEFAULT_CONFIG: AutoContinueConfig;
|
|
101
|
-
/** 把(可能不完整的)配置解析为完整配置(合法数字/布尔校验 + 兜底默认)。 */
|
|
102
|
-
export declare function resolveConfig(section: AutoContinueSettings | undefined): AutoContinueConfig;
|
|
103
|
-
//# sourceMappingURL=auto-continue-core.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"auto-continue-core.d.ts","sourceRoot":"","sources":["../../../src/client/auto-continue-core.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,+CAA+C;AAC/C,MAAM,WAAW,YAAY;IAC3B,+CAA+C;IAC/C,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,iBAAiB;IACjB,OAAO,EAAE,MAAM,CAAA;IACf,yBAAyB;IACzB,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAWjE;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAE9D;AAED,+BAA+B;AAC/B,wBAAgB,iBAAiB,CAC/B,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,MAAM,GACV,MAAM,CAIR;AAED,mCAAmC;AACnC,MAAM,WAAW,eAAe;IAC9B,0DAA0D;IAC1D,KAAK,CAAC,EAAE,YAAY,CAAA;IACpB,iCAAiC;IACjC,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,oCAAoC;IACpC,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,iCAAiC;IACjC,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,yCAAyC;IACzC,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED,sCAAsC;AACtC,wBAAgB,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAM5D;AAED,wFAAwF;AACxF,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,eAAe,GAAG,MAAM,CAS3E;AA0BD,qCAAqC;AACrC,MAAM,WAAW,eAAe;IAC9B,qCAAqC;IACrC,EAAE,EAAE,OAAO,CAAA;IACX,qBAAqB;IACrB,OAAO,EAAE,MAAM,CAAA;CAChB;AAED,uDAAuD;AACvD,wBAAgB,eAAe,CAAC,IAAI,EAAE;IACpC,KAAK,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IACxC,OAAO,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,KAAK,CAAC;YAAE,IAAI,CAAC,EAAE,MAAM,CAAC;YAAC,OAAO,CAAC,EAAE,OAAO,CAAC;YAAC,OAAO,CAAC,EAAE,OAAO,CAAA;SAAE,CAAC,CAAA;KAAE,CAAA;CACvF,GAAG,eAAe,CAGlB;AAED,4BAA4B;AAC5B,MAAM,WAAW,oBAAoB;IACnC,6BAA6B;IAC7B,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,+BAA+B;IAC/B,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,2BAA2B;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,oCAAoC;IACpC,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,kBAAkB;IAClB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,oBAAoB;IACpB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB;;;;OAIG;IACH,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,qBAAqB;IACrB,MAAM,CAAC,EAAE,OAAO,CAAA;CACjB;AAED,gCAAgC;AAChC,MAAM,MAAM,kBAAkB,GAAG,QAAQ,CAAC,oBAAoB,CAAC,CAAA;AAE/D,2CAA2C;AAC3C,eAAO,MAAM,cAAc,EAAE,kBAS5B,CAAA;AAUD,4CAA4C;AAC5C,wBAAgB,aAAa,CAAC,OAAO,EAAE,oBAAoB,GAAG,SAAS,GAAG,kBAAkB,CAgB3F"}
|
|
@@ -1,131 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Auto-continue core — 平台无关的纯逻辑, 吸收自 dsh-auto-continue
|
|
3
|
-
* (https://github.com/HsiangNianian/dsh-auto-continue, MIT, v0.8.1 的
|
|
4
|
-
* src/shared/core.ts), 按 input-traffic 的纯 client 定位裁剪:
|
|
5
|
-
*
|
|
6
|
-
* - 只吸收「错误分类 / 自适应退避 / 幂等护栏 / 模板填充」这些无宿主依赖的纯函数;
|
|
7
|
-
* - 不吸收宿主引擎(host firehose / agent.followup / SSE 桥)——那会破坏本插件
|
|
8
|
-
* 「纯浏览器侧、不改官方源码」的定位, 且与「冻结会话省钱」方向相反(见 README 兼容性);
|
|
9
|
-
* - 全部函数无任何 @deepseek-ai/* 值导入, 通过 client bundle purity gate。
|
|
10
|
-
*
|
|
11
|
-
* 应用场景: dock 的「续跑」——检测到会话停下但排队消息未处理完(疑似中断)时,
|
|
12
|
-
* 分类失败、按退避节奏重发, 永久性错误则停止并提示人工介入。
|
|
13
|
-
*/
|
|
14
|
-
/**
|
|
15
|
-
* 错误分类: 该失败是否值得重试续跑。
|
|
16
|
-
* 永久性失败(认证/余额/模型不存在/上下文超限等)重试也不会成功, 应停止并提示用户;
|
|
17
|
-
* 其余(网络、超时、5xx、429 等)视为临时性失败, 允许自动重发。
|
|
18
|
-
*/
|
|
19
|
-
export function isTransientFailure(failure) {
|
|
20
|
-
const haystack = `${failure.code ?? ''} ${failure.message}`.toLowerCase();
|
|
21
|
-
const status = failure.status;
|
|
22
|
-
if (status !== undefined && (status === 401 || status === 403))
|
|
23
|
-
return false;
|
|
24
|
-
const permanent = /auth|unauthor|forbidden|credential|api[_-]?key|permission/i.test(haystack) ||
|
|
25
|
-
/insufficient.*(balance|quota)|billing|payment|quota.*exceeded.*(?!retry)/i.test(haystack) ||
|
|
26
|
-
/model[^a-z]*not[^a-z]*found|unknown[_-]?model|not.*support.*model/i.test(haystack) ||
|
|
27
|
-
/context.*(length|limit|overflow|exceed)|token.*limit|max.*context/i.test(haystack) ||
|
|
28
|
-
/invalid[_-]?request|bad[_-]?request/i.test(haystack);
|
|
29
|
-
return !permanent;
|
|
30
|
-
}
|
|
31
|
-
/**
|
|
32
|
-
* 消息文本分类: 仅明确属于网络/传输类的临时错误才值得重试。
|
|
33
|
-
* 其余(序列化失败、配置/宿主内部错误等)视为永久性——重试无益。
|
|
34
|
-
*/
|
|
35
|
-
export function isTransientAgentError(message) {
|
|
36
|
-
return /network|timeout|timed ?out|econn|etimedout|socket|5\d\d|\b429\b|upstream|temporar/i.test(message);
|
|
37
|
-
}
|
|
38
|
-
/** 自适应退避: 同一会话连续失败时的有效重试间隔。 */
|
|
39
|
-
export function effectiveCooldown(consecutive, base, factor, max) {
|
|
40
|
-
// consecutive = 已连续自动重发的次数; 第 1 次后开始按 factor 递增
|
|
41
|
-
const multiplier = Math.pow(factor, consecutive);
|
|
42
|
-
return Math.min(Math.max(base, base * multiplier), Math.max(base, max));
|
|
43
|
-
}
|
|
44
|
-
/** 把毫秒格式化为人类可读的经过时长(如 65s → 1m5s)。 */
|
|
45
|
-
export function formatElapsed(ms) {
|
|
46
|
-
if (ms === undefined || !Number.isFinite(ms) || ms < 0)
|
|
47
|
-
return '';
|
|
48
|
-
if (ms < 1000)
|
|
49
|
-
return `${Math.round(ms)}ms`;
|
|
50
|
-
const s = Math.round(ms / 1000);
|
|
51
|
-
if (s < 60)
|
|
52
|
-
return `${s}s`;
|
|
53
|
-
return `${Math.floor(s / 60)}m${s % 60 > 0 ? `${s % 60}s` : ''}`;
|
|
54
|
-
}
|
|
55
|
-
/** 用失败事实填充续跑模板占位符({code}/{message}/{status}/{tool}/{errorCount}/{elapsed}/{result})。 */
|
|
56
|
-
export function fillTemplate(template, ctx) {
|
|
57
|
-
return template
|
|
58
|
-
.replace(/\{code\}/g, ctx.facts?.code ?? '')
|
|
59
|
-
.replace(/\{message\}/g, ctx.facts?.message ?? '')
|
|
60
|
-
.replace(/\{status\}/g, ctx.facts?.status !== undefined ? String(ctx.facts.status) : '')
|
|
61
|
-
.replace(/\{tool\}/g, ctx.tool ?? '')
|
|
62
|
-
.replace(/\{errorCount\}/g, ctx.errorCount !== undefined ? String(ctx.errorCount) : '')
|
|
63
|
-
.replace(/\{elapsed\}/g, formatElapsed(ctx.elapsedMs))
|
|
64
|
-
.replace(/\{result\}/g, ctx.result ?? '');
|
|
65
|
-
}
|
|
66
|
-
/** 工具结果摘要的最大长度(护栏模板 {result} 用)。 */
|
|
67
|
-
const TOOL_RESULT_CAP = 160;
|
|
68
|
-
/** 从任意内容块里递归收集文本(结果为模型可见的工具输出)。 */
|
|
69
|
-
function extractText(blocks, cap) {
|
|
70
|
-
let out = '';
|
|
71
|
-
const walk = (value) => {
|
|
72
|
-
if (out.length >= cap)
|
|
73
|
-
return;
|
|
74
|
-
if (Array.isArray(value)) {
|
|
75
|
-
for (const item of value)
|
|
76
|
-
walk(item);
|
|
77
|
-
return;
|
|
78
|
-
}
|
|
79
|
-
if (typeof value !== 'object' || value === null)
|
|
80
|
-
return;
|
|
81
|
-
const record = value;
|
|
82
|
-
if (record['type'] === 'text' && typeof record['text'] === 'string') {
|
|
83
|
-
out += record['text'];
|
|
84
|
-
return;
|
|
85
|
-
}
|
|
86
|
-
for (const child of Object.values(record))
|
|
87
|
-
walk(child);
|
|
88
|
-
};
|
|
89
|
-
walk(blocks);
|
|
90
|
-
return out.slice(0, cap);
|
|
91
|
-
}
|
|
92
|
-
/** 从 tool/result 事件载荷提取成功与否与文本摘要(幂等护栏: 续跑时提示别重复执行)。 */
|
|
93
|
-
export function toolResultFacts(data) {
|
|
94
|
-
const failed = data.error !== undefined || data.message?.content?.[0]?.isError === true;
|
|
95
|
-
return { ok: !failed, excerpt: extractText(data.message?.content?.[0]?.content, TOOL_RESULT_CAP) };
|
|
96
|
-
}
|
|
97
|
-
/** 内置默认值(与 dock 的 localStorage 持久化键一致)。 */
|
|
98
|
-
export const DEFAULT_CONFIG = {
|
|
99
|
-
continueText: '继续',
|
|
100
|
-
graceMs: 3000,
|
|
101
|
-
cooldownMs: 20000,
|
|
102
|
-
maxConsecutive: 3,
|
|
103
|
-
backoffFactor: 2,
|
|
104
|
-
backoffMaxMs: 300000,
|
|
105
|
-
autoResume: false,
|
|
106
|
-
paused: false,
|
|
107
|
-
};
|
|
108
|
-
function numberOr(value, fallback) {
|
|
109
|
-
return typeof value === 'number' && Number.isFinite(value) && value >= 0 ? value : fallback;
|
|
110
|
-
}
|
|
111
|
-
function booleanOr(value, fallback) {
|
|
112
|
-
return typeof value === 'boolean' ? value : fallback;
|
|
113
|
-
}
|
|
114
|
-
/** 把(可能不完整的)配置解析为完整配置(合法数字/布尔校验 + 兜底默认)。 */
|
|
115
|
-
export function resolveConfig(section) {
|
|
116
|
-
const value = section ?? {};
|
|
117
|
-
const text = typeof value.continueText === 'string' && value.continueText.trim() !== ''
|
|
118
|
-
? value.continueText
|
|
119
|
-
: DEFAULT_CONFIG.continueText;
|
|
120
|
-
return {
|
|
121
|
-
continueText: text,
|
|
122
|
-
graceMs: numberOr(value.graceMs, DEFAULT_CONFIG.graceMs),
|
|
123
|
-
cooldownMs: numberOr(value.cooldownMs, DEFAULT_CONFIG.cooldownMs),
|
|
124
|
-
maxConsecutive: Math.max(1, numberOr(value.maxConsecutive, DEFAULT_CONFIG.maxConsecutive)),
|
|
125
|
-
backoffFactor: Math.max(1, numberOr(value.backoffFactor, DEFAULT_CONFIG.backoffFactor)),
|
|
126
|
-
backoffMaxMs: numberOr(value.backoffMaxMs, DEFAULT_CONFIG.backoffMaxMs),
|
|
127
|
-
autoResume: booleanOr(value.autoResume, DEFAULT_CONFIG.autoResume),
|
|
128
|
-
paused: booleanOr(value.paused, DEFAULT_CONFIG.paused),
|
|
129
|
-
};
|
|
130
|
-
}
|
|
131
|
-
//# sourceMappingURL=auto-continue-core.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"auto-continue-core.js","sourceRoot":"","sources":["../../../src/client/auto-continue-core.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Auto-continue store — 中断检测与续跑配置的共享状态。
|
|
3
|
-
*
|
|
4
|
-
* 与 freeze-store 同构(无运行时依赖、稳定 identity per mount、可测试):
|
|
5
|
-
* - interrupted: 检测到「会话停下但排队消息未处理完」(疑似非人为中断)时置位,
|
|
6
|
-
* dock 据此显示续跑提示条;
|
|
7
|
-
* - 续跑配置持久化到 localStorage(键 `dsh-input-traffic:auto-continue`),
|
|
8
|
-
* 自动续跑默认关闭(纯 client 拿不到 turn/end reason, 无法与用户主动停止
|
|
9
|
-
* 区分, 故默认只提示、不擅自续跑)。
|
|
10
|
-
*/
|
|
11
|
-
import { type AutoContinueConfig, type AutoContinueSettings } from './auto-continue-core.ts';
|
|
12
|
-
/** localStorage 持久化键(续跑配置)。 */
|
|
13
|
-
export declare const CONFIG_KEY = "dsh-input-traffic:auto-continue";
|
|
14
|
-
export interface AutoContinueState {
|
|
15
|
-
/** 是否检测到疑似中断(提示条可见性)。 */
|
|
16
|
-
interrupted: boolean;
|
|
17
|
-
/** 连续自动续跑次数(按配置上限封顶)。 */
|
|
18
|
-
consecutive: number;
|
|
19
|
-
/** 上次续跑尝试时间戳(退避节流用)。 */
|
|
20
|
-
lastAttemptAt: number;
|
|
21
|
-
}
|
|
22
|
-
/** 最小快照 store(与 freeze-store 同构)。 */
|
|
23
|
-
export declare const autoContinueStore: {
|
|
24
|
-
getSnapshot(): AutoContinueState;
|
|
25
|
-
subscribe(listener: () => void): () => void;
|
|
26
|
-
};
|
|
27
|
-
/** 当前解析后的续跑配置。 */
|
|
28
|
-
export declare function readAutoContinueConfig(): AutoContinueConfig;
|
|
29
|
-
/** 持久化续跑配置(部分覆盖, 缺失回落默认)。 */
|
|
30
|
-
export declare function setAutoContinueConfig(patch: AutoContinueSettings): void;
|
|
31
|
-
/** 标记检测到疑似中断(dock 显示提示条)。 */
|
|
32
|
-
export declare function markInterrupted(): void;
|
|
33
|
-
/** 清除中断标志(用户手动续跑 / 队列清空 / 会话重新运行)。 */
|
|
34
|
-
export declare function clearInterrupted(): void;
|
|
35
|
-
/** 记录一次续跑尝试(推进连续计数与退避节流)。 */
|
|
36
|
-
export declare function noteRetry(consecutive: number): void;
|
|
37
|
-
/** 重置续跑状态(成功回合 / 用户介入后)。 */
|
|
38
|
-
export declare function resetAutoContinue(): void;
|
|
39
|
-
/** 测试重置。 */
|
|
40
|
-
export declare function resetAutoContinueStore(): void;
|
|
41
|
-
//# sourceMappingURL=auto-continue-store.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"auto-continue-store.d.ts","sourceRoot":"","sources":["../../../src/client/auto-continue-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EAAiB,KAAK,kBAAkB,EAAE,KAAK,oBAAoB,EAAE,MAAM,yBAAyB,CAAA;AAE3G,+BAA+B;AAC/B,eAAO,MAAM,UAAU,oCAAoC,CAAA;AAE3D,MAAM,WAAW,iBAAiB;IAChC,yBAAyB;IACzB,WAAW,EAAE,OAAO,CAAA;IACpB,yBAAyB;IACzB,WAAW,EAAE,MAAM,CAAA;IACnB,wBAAwB;IACxB,aAAa,EAAE,MAAM,CAAA;CACtB;AAsBD,qCAAqC;AACrC,eAAO,MAAM,iBAAiB;mBACb,iBAAiB;wBAGZ,MAAM,IAAI,GAAG,MAAM,IAAI;CAI5C,CAAA;AAED,kBAAkB;AAClB,wBAAgB,sBAAsB,IAAI,kBAAkB,CAE3D;AAED,6BAA6B;AAC7B,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,oBAAoB,GAAG,IAAI,CAUvE;AAED,6BAA6B;AAC7B,wBAAgB,eAAe,IAAI,IAAI,CAGtC;AAED,sCAAsC;AACtC,wBAAgB,gBAAgB,IAAI,IAAI,CAGvC;AAED,6BAA6B;AAC7B,wBAAgB,SAAS,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAGnD;AAED,4BAA4B;AAC5B,wBAAgB,iBAAiB,IAAI,IAAI,CAGxC;AAED,YAAY;AACZ,wBAAgB,sBAAsB,IAAI,IAAI,CAS7C"}
|