dsh-llm-fallbacks 0.6.13 → 0.8.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 +34 -30
- package/README.zh-CN.md +32 -28
- package/dist/chain-walk.d.ts +197 -0
- package/dist/chains.d.ts +35 -82
- package/dist/client/FallbacksCard.d.ts +27 -80
- package/dist/client/fallbacks-store.d.ts +71 -225
- package/dist/client/index.d.ts +0 -1
- package/dist/client/index.js +1332 -2110
- package/dist/client/locales.d.ts +61 -117
- package/dist/commands.d.ts +70 -112
- package/dist/config.d.ts +152 -117
- package/dist/cooldown.d.ts +1 -15
- package/dist/events.d.ts +8 -8
- package/dist/gateway.d.ts +66 -110
- package/dist/index.d.ts +21 -64
- package/dist/index.js +900 -1313
- package/dist/role-resolution.d.ts +15 -83
- package/dist/schema.d.ts +6 -5
- package/dist/seeds.d.ts +5 -7
- package/dist/state.d.ts +15 -141
- package/dist/subagents-seam.d.ts +51 -14
- package/dist/time-slots.d.ts +21 -24
- package/dist/tui-settings.d.ts +5 -6
- package/dist/virtual-adapter.d.ts +70 -119
- package/docs/DETAIL.md +1 -0
- package/docs/DETAIL.zh.md +1 -0
- package/docs/preview.svg +47 -0
- package/docs/preview.zh.svg +47 -0
- package/locale/en.json +2 -1
- package/locale/zh.json +2 -1
- package/package.json +29 -25
- package/dist/authorized-route.d.ts +0 -68
- package/dist/automatch.d.ts +0 -98
- package/dist/client/GeneralFallbacksRow.d.ts +0 -19
- package/dist/override.d.ts +0 -39
- package/dist/roles.d.ts +0 -90
- package/dist/route-allowlist.d.ts +0 -43
- package/dist/subagent-policy.d.ts +0 -123
package/dist/client/locales.d.ts
CHANGED
|
@@ -22,15 +22,10 @@ export declare const zh: {
|
|
|
22
22
|
'maxSwitchesPerStep.label': string;
|
|
23
23
|
'maxSwitchesPerStep.hint': string;
|
|
24
24
|
'maxSwitchesPerStep.tooltip': string;
|
|
25
|
-
'
|
|
26
|
-
'alwaysModeRetryCap.hint': string;
|
|
27
|
-
'alwaysModeRetryCap.tooltip': string;
|
|
25
|
+
'virtualOnly.rule': string;
|
|
28
26
|
'advanced.label': string;
|
|
29
27
|
'advanced.expand': string;
|
|
30
28
|
'advanced.collapse': string;
|
|
31
|
-
'roleAutoMatch.label': string;
|
|
32
|
-
'roleAutoMatch.hint': string;
|
|
33
|
-
'roleAutoMatch.tooltip': string;
|
|
34
29
|
'rootChain.label': string;
|
|
35
30
|
'rootChain.tooltip': string;
|
|
36
31
|
'defaultModel.label': string;
|
|
@@ -42,21 +37,26 @@ export declare const zh: {
|
|
|
42
37
|
'chains.selector.modelPlaceholder': string;
|
|
43
38
|
'chains.selector.wildcardLegacy': string;
|
|
44
39
|
'chains.selector.noModelsStrict': string;
|
|
45
|
-
'mainAgent.label': string;
|
|
46
40
|
'subagents.label': string;
|
|
47
|
-
'
|
|
48
|
-
'
|
|
49
|
-
'
|
|
50
|
-
'
|
|
51
|
-
'
|
|
52
|
-
'
|
|
53
|
-
'
|
|
54
|
-
'
|
|
55
|
-
'
|
|
56
|
-
'
|
|
57
|
-
'
|
|
58
|
-
'
|
|
59
|
-
'
|
|
41
|
+
'virtualChain.label': string;
|
|
42
|
+
'virtualChain.hint': string;
|
|
43
|
+
'chains.tab.add': string;
|
|
44
|
+
'chains.tab.menu': string;
|
|
45
|
+
'chains.name.label': string;
|
|
46
|
+
'chains.name.hint': string;
|
|
47
|
+
'chains.name.tooltip': string;
|
|
48
|
+
'chains.tab.renameLabel': string;
|
|
49
|
+
'chains.tab.renameDone': string;
|
|
50
|
+
'chains.tab.delete': string;
|
|
51
|
+
'chains.tab.deleteDisabled': string;
|
|
52
|
+
'chains.tab.dirty': string;
|
|
53
|
+
'chains.tab.error': string;
|
|
54
|
+
'chains.empty.title': string;
|
|
55
|
+
'chains.empty.body': string;
|
|
56
|
+
'chains.empty.create': string;
|
|
57
|
+
'chains.chainFoot.hint': string;
|
|
58
|
+
'chains.chainFoot.discard': string;
|
|
59
|
+
'chains.chainFoot.save': string;
|
|
60
60
|
'timeSlots.label': string;
|
|
61
61
|
'timeSlots.hint': string;
|
|
62
62
|
'timeSlots.tz.label': string;
|
|
@@ -104,8 +104,6 @@ export declare const zh: {
|
|
|
104
104
|
'allDay.pro': string;
|
|
105
105
|
'allDay.nonconforming': string;
|
|
106
106
|
'roles.list.label': string;
|
|
107
|
-
'roles.list.hint': string;
|
|
108
|
-
'roles.list.tooltip': string;
|
|
109
107
|
'roles.id': string;
|
|
110
108
|
'roles.id.hint': string;
|
|
111
109
|
'roles.idPlaceholder': string;
|
|
@@ -117,35 +115,24 @@ export declare const zh: {
|
|
|
117
115
|
'roles.seedSource.bundled': string;
|
|
118
116
|
'roles.seedSource.external': string;
|
|
119
117
|
'roles.seedSource.user': string;
|
|
120
|
-
'roles.
|
|
121
|
-
'roles.
|
|
122
|
-
'roles.
|
|
123
|
-
'roles.
|
|
118
|
+
'roles.list.hint': string;
|
|
119
|
+
'roles.chain.label': string;
|
|
120
|
+
'roles.chain.unspecified': string;
|
|
121
|
+
'roles.chain.hint': string;
|
|
122
|
+
'roles.chain.tooltip': string;
|
|
123
|
+
'roles.chainMeta.unspecified': string;
|
|
124
124
|
'roles.add': string;
|
|
125
125
|
'roles.remove': string;
|
|
126
126
|
'roles.expand': string;
|
|
127
127
|
'roles.collapse': string;
|
|
128
|
-
'roles.selector.add': string;
|
|
129
|
-
'roles.rules': string;
|
|
130
|
-
'roles.rules.hint': string;
|
|
131
|
-
'roles.rules.tooltip': string;
|
|
132
|
-
'roles.rule.provider': string;
|
|
133
|
-
'roles.rule.provider.any': string;
|
|
134
|
-
'roles.rule.model': string;
|
|
135
|
-
'roles.rule.model.any': string;
|
|
136
|
-
'roles.rule.role': string;
|
|
137
|
-
'roles.rule.role.inherit': string;
|
|
138
|
-
'roles.rule.roleSelectPlaceholder': string;
|
|
139
|
-
'roles.rule.roleUndeclared.short': string;
|
|
140
|
-
'roles.addRule': string;
|
|
141
|
-
'roles.removeRule': string;
|
|
142
128
|
'validation.blocked': string;
|
|
143
129
|
'validation.roleIdFormat': string;
|
|
144
130
|
'validation.roleIdReserved': string;
|
|
145
131
|
'validation.roleIdDuplicate': string;
|
|
146
|
-
'validation.
|
|
147
|
-
'validation.
|
|
148
|
-
'validation.
|
|
132
|
+
'validation.chainIdFormat': string;
|
|
133
|
+
'validation.chainIdDuplicate': string;
|
|
134
|
+
'validation.chainLabelRequired': string;
|
|
135
|
+
'validation.chainEntriesRequired': string;
|
|
149
136
|
'validation.allDayRequired': string;
|
|
150
137
|
'validation.slotChainRequired': string;
|
|
151
138
|
'validation.slotWindow': string;
|
|
@@ -163,24 +150,9 @@ export declare const zh: {
|
|
|
163
150
|
'catalog.outside.tooltip': string;
|
|
164
151
|
'catalog.outside.short': string;
|
|
165
152
|
'catalog.unconfigured.short': string;
|
|
166
|
-
'status.title': string;
|
|
167
|
-
'status.switches.label': string;
|
|
168
|
-
'status.switches.empty': string;
|
|
169
|
-
'status.switches.error': string;
|
|
170
|
-
'status.switches.compact': string;
|
|
171
|
-
'status.switches.compact.roleInject': string;
|
|
172
153
|
'status.switches.reason.trigger-code': string;
|
|
173
154
|
'status.switches.reason.always-cap': string;
|
|
174
155
|
'status.switches.reason.role-inject': string;
|
|
175
|
-
'general.title': string;
|
|
176
|
-
'general.enabled': string;
|
|
177
|
-
'general.disabled': string;
|
|
178
|
-
'general.unknown': string;
|
|
179
|
-
'general.unavailable': string;
|
|
180
|
-
'general.switch': string;
|
|
181
|
-
'general.switch.roleInject': string;
|
|
182
|
-
'general.switch.empty': string;
|
|
183
|
-
'general.error': string;
|
|
184
156
|
'chat.switch.title': string;
|
|
185
157
|
'chat.switch.summary': string;
|
|
186
158
|
'chat.switch.summary.roleInject': string;
|
|
@@ -220,15 +192,10 @@ export declare const en: {
|
|
|
220
192
|
'maxSwitchesPerStep.label': string;
|
|
221
193
|
'maxSwitchesPerStep.hint': string;
|
|
222
194
|
'maxSwitchesPerStep.tooltip': string;
|
|
223
|
-
'
|
|
224
|
-
'alwaysModeRetryCap.hint': string;
|
|
225
|
-
'alwaysModeRetryCap.tooltip': string;
|
|
195
|
+
'virtualOnly.rule': string;
|
|
226
196
|
'advanced.label': string;
|
|
227
197
|
'advanced.expand': string;
|
|
228
198
|
'advanced.collapse': string;
|
|
229
|
-
'roleAutoMatch.label': string;
|
|
230
|
-
'roleAutoMatch.hint': string;
|
|
231
|
-
'roleAutoMatch.tooltip': string;
|
|
232
199
|
'rootChain.label': string;
|
|
233
200
|
'rootChain.tooltip': string;
|
|
234
201
|
'defaultModel.label': string;
|
|
@@ -240,21 +207,26 @@ export declare const en: {
|
|
|
240
207
|
'chains.selector.modelPlaceholder': string;
|
|
241
208
|
'chains.selector.wildcardLegacy': string;
|
|
242
209
|
'chains.selector.noModelsStrict': string;
|
|
243
|
-
'mainAgent.label': string;
|
|
244
210
|
'subagents.label': string;
|
|
245
|
-
'
|
|
246
|
-
'
|
|
247
|
-
'
|
|
248
|
-
'
|
|
249
|
-
'
|
|
250
|
-
'
|
|
251
|
-
'
|
|
252
|
-
'
|
|
253
|
-
'
|
|
254
|
-
'
|
|
255
|
-
'
|
|
256
|
-
'
|
|
257
|
-
'
|
|
211
|
+
'virtualChain.label': string;
|
|
212
|
+
'virtualChain.hint': string;
|
|
213
|
+
'chains.tab.add': string;
|
|
214
|
+
'chains.tab.menu': string;
|
|
215
|
+
'chains.name.label': string;
|
|
216
|
+
'chains.name.hint': string;
|
|
217
|
+
'chains.name.tooltip': string;
|
|
218
|
+
'chains.tab.renameLabel': string;
|
|
219
|
+
'chains.tab.renameDone': string;
|
|
220
|
+
'chains.tab.delete': string;
|
|
221
|
+
'chains.tab.deleteDisabled': string;
|
|
222
|
+
'chains.tab.dirty': string;
|
|
223
|
+
'chains.tab.error': string;
|
|
224
|
+
'chains.empty.title': string;
|
|
225
|
+
'chains.empty.body': string;
|
|
226
|
+
'chains.empty.create': string;
|
|
227
|
+
'chains.chainFoot.hint': string;
|
|
228
|
+
'chains.chainFoot.discard': string;
|
|
229
|
+
'chains.chainFoot.save': string;
|
|
258
230
|
'timeSlots.label': string;
|
|
259
231
|
'timeSlots.hint': string;
|
|
260
232
|
'timeSlots.tz.label': string;
|
|
@@ -303,7 +275,6 @@ export declare const en: {
|
|
|
303
275
|
'allDay.nonconforming': string;
|
|
304
276
|
'roles.list.label': string;
|
|
305
277
|
'roles.list.hint': string;
|
|
306
|
-
'roles.list.tooltip': string;
|
|
307
278
|
'roles.id': string;
|
|
308
279
|
'roles.id.hint': string;
|
|
309
280
|
'roles.idPlaceholder': string;
|
|
@@ -315,35 +286,23 @@ export declare const en: {
|
|
|
315
286
|
'roles.seedSource.bundled': string;
|
|
316
287
|
'roles.seedSource.external': string;
|
|
317
288
|
'roles.seedSource.user': string;
|
|
318
|
-
'roles.
|
|
319
|
-
'roles.
|
|
320
|
-
'roles.
|
|
321
|
-
'roles.
|
|
289
|
+
'roles.chain.label': string;
|
|
290
|
+
'roles.chain.unspecified': string;
|
|
291
|
+
'roles.chain.hint': string;
|
|
292
|
+
'roles.chain.tooltip': string;
|
|
293
|
+
'roles.chainMeta.unspecified': string;
|
|
322
294
|
'roles.add': string;
|
|
323
295
|
'roles.remove': string;
|
|
324
296
|
'roles.expand': string;
|
|
325
297
|
'roles.collapse': string;
|
|
326
|
-
'roles.selector.add': string;
|
|
327
|
-
'roles.rules': string;
|
|
328
|
-
'roles.rules.hint': string;
|
|
329
|
-
'roles.rules.tooltip': string;
|
|
330
|
-
'roles.rule.provider': string;
|
|
331
|
-
'roles.rule.provider.any': string;
|
|
332
|
-
'roles.rule.model': string;
|
|
333
|
-
'roles.rule.model.any': string;
|
|
334
|
-
'roles.rule.role': string;
|
|
335
|
-
'roles.rule.role.inherit': string;
|
|
336
|
-
'roles.rule.roleSelectPlaceholder': string;
|
|
337
|
-
'roles.rule.roleUndeclared.short': string;
|
|
338
|
-
'roles.addRule': string;
|
|
339
|
-
'roles.removeRule': string;
|
|
340
298
|
'validation.blocked': string;
|
|
341
299
|
'validation.roleIdFormat': string;
|
|
342
300
|
'validation.roleIdReserved': string;
|
|
343
301
|
'validation.roleIdDuplicate': string;
|
|
344
|
-
'validation.
|
|
345
|
-
'validation.
|
|
346
|
-
'validation.
|
|
302
|
+
'validation.chainIdFormat': string;
|
|
303
|
+
'validation.chainIdDuplicate': string;
|
|
304
|
+
'validation.chainLabelRequired': string;
|
|
305
|
+
'validation.chainEntriesRequired': string;
|
|
347
306
|
'validation.allDayRequired': string;
|
|
348
307
|
'validation.slotChainRequired': string;
|
|
349
308
|
'validation.slotWindow': string;
|
|
@@ -361,24 +320,9 @@ export declare const en: {
|
|
|
361
320
|
'catalog.outside.tooltip': string;
|
|
362
321
|
'catalog.outside.short': string;
|
|
363
322
|
'catalog.unconfigured.short': string;
|
|
364
|
-
'status.title': string;
|
|
365
|
-
'status.switches.label': string;
|
|
366
|
-
'status.switches.empty': string;
|
|
367
|
-
'status.switches.error': string;
|
|
368
|
-
'status.switches.compact': string;
|
|
369
|
-
'status.switches.compact.roleInject': string;
|
|
370
323
|
'status.switches.reason.trigger-code': string;
|
|
371
324
|
'status.switches.reason.always-cap': string;
|
|
372
325
|
'status.switches.reason.role-inject': string;
|
|
373
|
-
'general.title': string;
|
|
374
|
-
'general.enabled': string;
|
|
375
|
-
'general.disabled': string;
|
|
376
|
-
'general.unknown': string;
|
|
377
|
-
'general.unavailable': string;
|
|
378
|
-
'general.switch': string;
|
|
379
|
-
'general.switch.roleInject': string;
|
|
380
|
-
'general.switch.empty': string;
|
|
381
|
-
'general.error': string;
|
|
382
326
|
'chat.switch.title': string;
|
|
383
327
|
'chat.switch.summary': string;
|
|
384
328
|
'chat.switch.summary.roleInject': string;
|
|
@@ -402,8 +346,8 @@ declare module '@deepseek-ai/dsh-client-ui-slots' {
|
|
|
402
346
|
}
|
|
403
347
|
}
|
|
404
348
|
/**
|
|
405
|
-
* Reason → locale key map for switch summaries (
|
|
406
|
-
*
|
|
349
|
+
* Reason → locale key map for switch summaries (shared by the conversation
|
|
350
|
+
* node). All
|
|
407
351
|
* reasons resolve from ONE key family (`status.switches.reason.*`) — the
|
|
408
352
|
* shared reason vocabulary must not mix dictionary families (qc1 F-004). The
|
|
409
353
|
* session log is durable and forward-compatible: a reason value outside the
|
package/dist/commands.d.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* `/fallbacks` slash command (plan fallbacks-role-runtime T3, AC-5).
|
|
3
3
|
*
|
|
4
|
-
* Session-scoped, read-only diagnostic: current session origin → resolved
|
|
5
|
-
* role
|
|
6
|
-
* tail
|
|
7
|
-
* (newest first, capped) → cooldown status.
|
|
4
|
+
* Session-scoped, read-only diagnostic: current session origin → the resolved
|
|
5
|
+
* dispatch role (+ its specified chain pointer) → every configured named chain
|
|
6
|
+
* with its tail and current slot label, the calling agent's selection marked →
|
|
7
|
+
* recent `fallbacks/switch` events (newest first, capped) → cooldown status.
|
|
8
|
+
* Mirrors dsh-advisor's
|
|
8
9
|
* `/advisor` command pattern: a conditional `ctx.inject(['commands'])` child
|
|
9
10
|
* in `src/index.ts` calls {@link registerFallbacksCommands} with a
|
|
10
11
|
* factory-bound handler; `commands` never joins the top-level inject list, so
|
|
@@ -26,11 +27,9 @@
|
|
|
26
27
|
* @module dsh-llm-fallbacks/commands
|
|
27
28
|
*/
|
|
28
29
|
import type { CommandDefinition } from '@deepseek-ai/dsh-commands';
|
|
29
|
-
|
|
30
|
-
import type { Origin } from './roles.ts';
|
|
30
|
+
type Origin = 'root' | 'subagent';
|
|
31
31
|
import type { FallbacksSwitchEventData } from './events.ts';
|
|
32
32
|
import type { SeedRevertFailReason } from './seeds.ts';
|
|
33
|
-
import { type SlotRowConfig } from './time-slots.ts';
|
|
34
33
|
/** How many recent `fallbacks/switch` events `/fallbacks` shows (newest first). */
|
|
35
34
|
export declare const RECENT_SWITCHES_LIMIT = 5;
|
|
36
35
|
/** Minimal command registry surface (satisfied by the dsh `CommandService`). */
|
|
@@ -64,26 +63,21 @@ export interface FallbacksCooldownEntry {
|
|
|
64
63
|
export interface FallbacksCommandSnapshot {
|
|
65
64
|
/** Session origin: `'root'` when the agent carries no header origin. */
|
|
66
65
|
readonly origin: Origin;
|
|
67
|
-
/** Resolved role (
|
|
66
|
+
/** Resolved dispatch role (the seam record), `''` when none resolved. */
|
|
68
67
|
readonly role: string;
|
|
69
|
-
/**
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
*
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
/** True when rootChain is appended as the inherit fallback tail (role's
|
|
77
|
-
* `fallback` is `'inherit-root'` — or the role is unknown — and rootChain
|
|
78
|
-
* is non-empty; the diagnostic annotation source, spec §7.4). */
|
|
79
|
-
readonly inherit: boolean;
|
|
80
|
-
/** Current time-slot winner + display label (P5/P7): the 分时切换 side of
|
|
81
|
-
* the status strip. The switches section below is the 降级切换 side —
|
|
82
|
-
* the copy never mixes. */
|
|
83
|
-
readonly slot: {
|
|
84
|
-
readonly winner: SlotRowConfig | 'all-day';
|
|
68
|
+
/** The resolved role's declared chain POINTER (「指定降级链」), `undefined`
|
|
69
|
+
* when the role is unresolved or specifies nothing (NOT SPECIFIED). */
|
|
70
|
+
readonly roleChain?: string;
|
|
71
|
+
/** Every configured named chain with its slot state; `selected` marks the
|
|
72
|
+
* calling agent's chain (its route names the chain id). */
|
|
73
|
+
readonly chains: readonly {
|
|
74
|
+
readonly id: string;
|
|
85
75
|
readonly label: string;
|
|
86
|
-
|
|
76
|
+
readonly entries: readonly string[];
|
|
77
|
+
/** Current slot label for the chain (`'all-day'` when no row matches). */
|
|
78
|
+
readonly slotLabel: string;
|
|
79
|
+
readonly selected: boolean;
|
|
80
|
+
}[];
|
|
87
81
|
/** Recent `fallbacks/switch` events (failure walks — 降级切换), newest
|
|
88
82
|
* first, capped at {@link RECENT_SWITCHES_LIMIT}. */
|
|
89
83
|
readonly switches: readonly FallbacksSwitchEventData[];
|
|
@@ -91,65 +85,56 @@ export interface FallbacksCommandSnapshot {
|
|
|
91
85
|
readonly cooldown: readonly FallbacksCooldownEntry[];
|
|
92
86
|
}
|
|
93
87
|
/**
|
|
94
|
-
* The composed-config surface `/fallbacks config` renders
|
|
95
|
-
* fallbacks
|
|
96
|
-
*
|
|
97
|
-
*
|
|
98
|
-
*
|
|
99
|
-
*
|
|
100
|
-
* chain count, never a rules dump.
|
|
88
|
+
* The composed-config surface `/fallbacks config` renders: the composed
|
|
89
|
+
* `fallbacks` namespace as the runtime sees it (settings user layer included).
|
|
90
|
+
* It carries every named chain (`{ id, label, entries, timeSlots }`) and the
|
|
91
|
+
* declared roles as `{ id, chain? }` — the role's optional POINTER into
|
|
92
|
+
* `chains[].id` (「指定降级链」), rendered as its `FallbacksChain/<id>` route or
|
|
93
|
+
* as NOT SPECIFIED. There is no rules dump (rules are gone).
|
|
101
94
|
*
|
|
102
|
-
*
|
|
103
|
-
*
|
|
104
|
-
*
|
|
105
|
-
*
|
|
106
|
-
*
|
|
107
|
-
* PRESETS); custom rows carry `{ start, end, chainCount }`. Rules rows carry
|
|
108
|
-
* `{ provider, model, role }` — an omitted provider/model (wildcard match at
|
|
109
|
-
* runtime) is summarized as `''` and rendered as `*`.
|
|
95
|
+
* The config-level `tz` joins the summary so TUI operators can verify
|
|
96
|
+
* `/settings` edits. One summarized time-slot row: preset rows carry
|
|
97
|
+
* `{ preset, chainCount }` (windows are frozen code constants in
|
|
98
|
+
* {@link PRESETS} and never stored on the row — the render resolves the window
|
|
99
|
+
* text from PRESETS); custom rows carry `{ start, end, chainCount }`.
|
|
110
100
|
*/
|
|
111
101
|
export interface FallbacksConfigSummary {
|
|
112
102
|
/**
|
|
113
|
-
* Content-presence gate (`isFallbackActive
|
|
114
|
-
*
|
|
115
|
-
*
|
|
103
|
+
* Content-presence gate (`isFallbackActive`): the plugin intervenes exactly
|
|
104
|
+
* when the named-chain list is non-empty (`chains.length > 0`). Slot rows and
|
|
105
|
+
* declared roles alone do NOT activate it — they are per-chain / optional.
|
|
116
106
|
*/
|
|
117
107
|
readonly active: boolean;
|
|
118
108
|
readonly triggerCodes: readonly string[];
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
109
|
+
/** Named chains (v2): id/label/entries + summarized per-chain slot rows. */
|
|
110
|
+
readonly chains: readonly {
|
|
111
|
+
id: string;
|
|
112
|
+
label: string;
|
|
113
|
+
entries: readonly string[];
|
|
114
|
+
timeSlots: readonly {
|
|
115
|
+
preset?: string;
|
|
116
|
+
start?: string;
|
|
117
|
+
end?: string;
|
|
118
|
+
days?: readonly number[];
|
|
119
|
+
chainCount: number;
|
|
120
|
+
}[];
|
|
127
121
|
}[];
|
|
128
122
|
/** Config-level timezone for slot matching (default `Asia/Shanghai`). */
|
|
129
123
|
readonly tz: string;
|
|
130
124
|
readonly roles: readonly {
|
|
131
125
|
id: string;
|
|
132
|
-
|
|
133
|
-
}[];
|
|
134
|
-
/** Summarized role rules: provider/model patterns → declared role (or the built-in `'inherit'`). */
|
|
135
|
-
readonly rules: readonly {
|
|
136
|
-
provider: string;
|
|
137
|
-
model: string;
|
|
138
|
-
role: string;
|
|
126
|
+
chain?: string;
|
|
139
127
|
}[];
|
|
140
128
|
readonly cooldownMs: number;
|
|
141
129
|
readonly revertPolicy: string;
|
|
142
130
|
readonly maxSwitchesPerStep: number;
|
|
143
|
-
readonly alwaysModeRetryCap: number;
|
|
144
131
|
readonly presets: 'bundled' | 'none';
|
|
145
|
-
/** Dispatch-time LLM role auto-match switch (default true). */
|
|
146
|
-
readonly roleAutoMatch: boolean;
|
|
147
132
|
}
|
|
148
133
|
/**
|
|
149
134
|
* The session-scoped read-only operations the `/fallbacks` handler drives.
|
|
150
135
|
* Implemented by the wiring (`src/index.ts`) against the live config source
|
|
151
|
-
* (`
|
|
152
|
-
* state store; faked in unit tests.
|
|
136
|
+
* (`chains` / `roles.list`), the dispatch seam's per-child record and the
|
|
137
|
+
* per-agent state store; faked in unit tests.
|
|
153
138
|
*/
|
|
154
139
|
export interface FallbacksCommandController {
|
|
155
140
|
/** Snapshot the session's fallback diagnostics. Never mutates state. */
|
|
@@ -189,7 +174,6 @@ export declare const FALLBACKS_COMMAND_LOCALES: {
|
|
|
189
174
|
readonly origin: "会话来源";
|
|
190
175
|
readonly role: "角色";
|
|
191
176
|
readonly chain: "链";
|
|
192
|
-
readonly inheritRoot: "(inherit-root)";
|
|
193
177
|
readonly chainNone: "未配置";
|
|
194
178
|
readonly slot: "分时";
|
|
195
179
|
readonly switches: "最近降级切换";
|
|
@@ -208,22 +192,20 @@ export declare const FALLBACKS_COMMAND_LOCALES: {
|
|
|
208
192
|
readonly configEnabled: "已启用";
|
|
209
193
|
readonly configDisabled: "未启用";
|
|
210
194
|
readonly configTriggerCodes: "触发码";
|
|
211
|
-
readonly
|
|
195
|
+
readonly configChains: "虚拟链";
|
|
212
196
|
readonly configEmpty: "(空)";
|
|
213
|
-
readonly
|
|
197
|
+
readonly configChainItem: "{id}({label}): {entries}|分时槽: {slots}";
|
|
214
198
|
readonly configSlotPresetItem: "{preset}(chain: {n}, window {window})";
|
|
215
199
|
readonly configSlotPresetBare: "{preset}(chain: {n})";
|
|
216
200
|
readonly configSlotCustomItem: "custom {start}-{end}(chain: {n})";
|
|
217
201
|
readonly configTz: "时区";
|
|
218
202
|
readonly configRoles: "角色";
|
|
219
|
-
readonly configRoleItem: "{id}
|
|
220
|
-
readonly
|
|
203
|
+
readonly configRoleItem: "{id}(指定降级链: {chain})";
|
|
204
|
+
readonly configRoleUnspecified: "未指定(沿用 dsh 默认)";
|
|
221
205
|
readonly configCooldown: "冷却";
|
|
222
206
|
readonly configRevert: "回主策略";
|
|
223
|
-
readonly configMaxSwitches: "
|
|
224
|
-
readonly configAlwaysCap: "always 上限";
|
|
207
|
+
readonly configMaxSwitches: "单次请求行走最大切换";
|
|
225
208
|
readonly configPresets: "预置";
|
|
226
|
-
readonly configRoleAutoMatch: "角色自动匹配";
|
|
227
209
|
readonly configEdit: "编辑:/settings(TUI 设置界面)或 ~/.dsh/profiles/<profile>/cordis.patch.yml(插件行)/ $DSH_HOME/settings.yaml(fallbacks: 分节)";
|
|
228
210
|
readonly configEditHint: "TUI 通过 /settings 修改配置;文件编辑仍然可用";
|
|
229
211
|
readonly revertSeedOk: "角色 {id} 已还原为 Seed 默认";
|
|
@@ -244,7 +226,6 @@ export declare const FALLBACKS_COMMAND_LOCALES: {
|
|
|
244
226
|
readonly origin: "Session origin";
|
|
245
227
|
readonly role: "Role";
|
|
246
228
|
readonly chain: "Chain";
|
|
247
|
-
readonly inheritRoot: " (inherit-root)";
|
|
248
229
|
readonly chainNone: "not configured";
|
|
249
230
|
readonly slot: "Time slot";
|
|
250
231
|
readonly switches: "Recent fallback switches";
|
|
@@ -263,22 +244,20 @@ export declare const FALLBACKS_COMMAND_LOCALES: {
|
|
|
263
244
|
readonly configEnabled: "enabled";
|
|
264
245
|
readonly configDisabled: "disabled";
|
|
265
246
|
readonly configTriggerCodes: "Trigger codes";
|
|
266
|
-
readonly
|
|
247
|
+
readonly configChains: "Chains";
|
|
267
248
|
readonly configEmpty: "(empty)";
|
|
268
|
-
readonly
|
|
249
|
+
readonly configChainItem: "{id} ({label}): {entries} | slots: {slots}";
|
|
269
250
|
readonly configSlotPresetItem: "{preset} (chain: {n}, window {window})";
|
|
270
251
|
readonly configSlotPresetBare: "{preset} (chain: {n})";
|
|
271
252
|
readonly configSlotCustomItem: "custom {start}-{end} (chain: {n})";
|
|
272
253
|
readonly configTz: "TZ";
|
|
273
254
|
readonly configRoles: "Roles";
|
|
274
|
-
readonly configRoleItem: "{id} (chain: {
|
|
275
|
-
readonly
|
|
255
|
+
readonly configRoleItem: "{id} (specified chain: {chain})";
|
|
256
|
+
readonly configRoleUnspecified: "not specified (dsh default)";
|
|
276
257
|
readonly configCooldown: "Cooldown";
|
|
277
258
|
readonly configRevert: "Revert";
|
|
278
|
-
readonly configMaxSwitches: "Max switches
|
|
279
|
-
readonly configAlwaysCap: "Always-mode cap";
|
|
259
|
+
readonly configMaxSwitches: "Max switches per request walk";
|
|
280
260
|
readonly configPresets: "Presets";
|
|
281
|
-
readonly configRoleAutoMatch: "Auto-match";
|
|
282
261
|
readonly configEdit: "Edit: /settings (TUI settings screen) or ~/.dsh/profiles/<profile>/cordis.patch.yml (plugin row) / $DSH_HOME/settings.yaml (fallbacks: section)";
|
|
283
262
|
readonly configEditHint: "TUI edits config via /settings; file editing still works";
|
|
284
263
|
readonly revertSeedOk: "role {id} reverted to its seed default";
|
|
@@ -319,31 +298,6 @@ export declare function parseFallbacksSubcommand(rawInput: string): FallbacksSub
|
|
|
319
298
|
* `SessionEventMap` type, and the durable log can outlive schema versions).
|
|
320
299
|
*/
|
|
321
300
|
export declare function recentFallbacksSwitches(events: readonly unknown[], limit: number): FallbacksSwitchEventData[];
|
|
322
|
-
/**
|
|
323
|
-
* The chain entries `/fallbacks` shows for a role (spec §7.4): the declared
|
|
324
|
-
* role's own chain when non-empty (`chainRole: true`); an empty own chain
|
|
325
|
-
* defers to `rootChain` unless `fallback: 'none'` — then nothing is appended
|
|
326
|
-
* and the display chain is empty, mirroring `resolveChainViews`'s
|
|
327
|
-
* `[...[], ...[]]` exactly; undeclared ids and the built-in `'inherit'`
|
|
328
|
-
* role resolve to `rootChain`. `inherit: true` marks the append-not-replace
|
|
329
|
-
* tail — the role's `fallback` is `'inherit-root'` (the default) or the role
|
|
330
|
-
* is unknown/built-in `'inherit'`, and `rootChain` is non-empty. Mirrors
|
|
331
|
-
* `resolveChainViews`'s concatenation (see {@link buildRoleEntries} —
|
|
332
|
-
* `src/chains.ts`; the diagnostic keeps its display semantics: the role's
|
|
333
|
-
* own chain renders in full, `rootChain` only when the role has no own
|
|
334
|
-
* chain, with the inherit tail as an annotation) without a failing model to
|
|
335
|
-
* resolve against (the diagnostic is model-independent).
|
|
336
|
-
*
|
|
337
|
-
* `warn` mirrors {@link resolveChainViews}' defensive unknown-role warn
|
|
338
|
-
* (qc2 F-002 — routed through the injected logger; the `/fallbacks` path
|
|
339
|
-
* never reaches here unsanitized, as {@link resolveRole} resolves to a
|
|
340
|
-
* declared id or `'inherit'` first, so this is direct-caller parity).
|
|
341
|
-
*/
|
|
342
|
-
export declare function resolveChainForDiagnostic(roles: readonly FallbacksRole[], rootChain: readonly string[], role: string, warn?: (message: string) => void): {
|
|
343
|
-
readonly chainRole: boolean;
|
|
344
|
-
readonly chain: readonly string[];
|
|
345
|
-
readonly inherit: boolean;
|
|
346
|
-
};
|
|
347
301
|
/**
|
|
348
302
|
* Cap for the composed-config readback's LIST lines — Trigger codes, Root
|
|
349
303
|
* chain, Time slots, Roles, and Rules (qc2 Task-2 Minor): beyond this many
|
|
@@ -352,12 +306,13 @@ export declare function resolveChainForDiagnostic(roles: readonly FallbacksRole[
|
|
|
352
306
|
*/
|
|
353
307
|
export declare const FALLBACKS_CONFIG_LIST_CAP = 5;
|
|
354
308
|
/**
|
|
355
|
-
* Render the `/fallbacks config` surface
|
|
356
|
-
*
|
|
357
|
-
*
|
|
358
|
-
*
|
|
359
|
-
*
|
|
360
|
-
* `/settings` TUI edit surface while keeping the
|
|
309
|
+
* Render the `/fallbacks config` surface: the composed `fallbacks` namespace
|
|
310
|
+
* as the runtime reads it — every named chain with its label, entries and
|
|
311
|
+
* time-slot rows (preset rows resolve their frozen window from
|
|
312
|
+
* {@link PRESETS}), the config timezone, and each role with its `chain`
|
|
313
|
+
* POINTER (the `FallbacksChain/<id>` it specifies, or NOT SPECIFIED) — plus
|
|
314
|
+
* edit hints pointing at the `/settings` TUI edit surface while keeping the
|
|
315
|
+
* file-edit documentation.
|
|
361
316
|
* The FIRST LINE marks the composed-config readback — distinct from the
|
|
362
317
|
* diagnostic title and never merged into {@link fallbacksCommandText} (two
|
|
363
318
|
* operator surfaces, product lock). Locale defaults to `zh` (the command
|
|
@@ -366,8 +321,10 @@ export declare const FALLBACKS_CONFIG_LIST_CAP = 5;
|
|
|
366
321
|
export declare function fallbacksConfigText(summary: FallbacksConfigSummary, locale?: FallbacksCommandLocale): string;
|
|
367
322
|
/**
|
|
368
323
|
* Render the `/fallbacks` status surface for one snapshot. Kept minimal and
|
|
369
|
-
* truthful: origin → role
|
|
370
|
-
*
|
|
324
|
+
* truthful: origin → role (+ its specified chain pointer) → every configured
|
|
325
|
+
* chain with tail + slot state, the calling agent's selection marked →
|
|
326
|
+
* recent switches (降级切换) → cooldown. No chain-id argument (named virtual
|
|
327
|
+
* chains §1): the snapshot lists every chain.
|
|
371
328
|
*/
|
|
372
329
|
export declare function fallbacksCommandText(snapshot: FallbacksCommandSnapshot, locale?: FallbacksCommandLocale): string;
|
|
373
330
|
/**
|
|
@@ -378,3 +335,4 @@ export declare function fallbacksCommandText(snapshot: FallbacksCommandSnapshot,
|
|
|
378
335
|
* @returns the registry disposer (the inject child owns its lifetime).
|
|
379
336
|
*/
|
|
380
337
|
export declare function registerFallbacksCommands(registry: FallbacksCommandRegistry, controller: FallbacksCommandController, locale?: FallbacksCommandLocale): () => void;
|
|
338
|
+
export {};
|