dsh-llm-fallbacks 0.2.2 → 0.3.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.md +67 -9
- package/README.zh-CN.md +66 -8
- package/dist/client/FallbacksCard.d.ts +27 -13
- package/dist/client/GeneralFallbacksRow.d.ts +1 -1
- package/dist/client/fallbacks-store.d.ts +48 -4
- package/dist/client/index.js +2349 -938
- package/dist/client/locales.d.ts +118 -26
- package/dist/client/use-snapshot.d.ts +11 -0
- package/dist/commands.d.ts +18 -7
- package/dist/config.d.ts +22 -1
- package/dist/index.d.ts +7 -4
- package/dist/index.js +467 -15
- package/dist/roles.d.ts +12 -5
- package/dist/time-slots.d.ts +104 -0
- package/dist/virtual-adapter.d.ts +90 -0
- package/package.json +26 -23
- package/scripts/build-client.ts +9 -9
package/dist/client/locales.d.ts
CHANGED
|
@@ -41,15 +41,61 @@ export declare const zh: {
|
|
|
41
41
|
'roleAutoMatch.hint': string;
|
|
42
42
|
'roleAutoMatch.tooltip': string;
|
|
43
43
|
'rootChain.label': string;
|
|
44
|
-
'rootChain.firstLine': string;
|
|
45
|
-
'rootChain.hint': string;
|
|
46
44
|
'rootChain.tooltip': string;
|
|
47
|
-
'
|
|
45
|
+
'defaultModel.label': string;
|
|
48
46
|
'chains.selector.remove': string;
|
|
49
47
|
'chains.selector.providerPlaceholder': string;
|
|
50
48
|
'chains.selector.modelPlaceholder': string;
|
|
51
49
|
'chains.selector.wildcardLegacy': string;
|
|
52
50
|
'chains.selector.noModelsStrict': string;
|
|
51
|
+
'mainAgent.label': string;
|
|
52
|
+
'subagents.label': string;
|
|
53
|
+
'timeSlots.label': string;
|
|
54
|
+
'timeSlots.hint': string;
|
|
55
|
+
'timeSlots.tz.label': string;
|
|
56
|
+
'timeSlots.drag': string;
|
|
57
|
+
'timeSlots.name': string;
|
|
58
|
+
'timeSlots.expand': string;
|
|
59
|
+
'timeSlots.collapse': string;
|
|
60
|
+
'timeSlots.tooltip': string;
|
|
61
|
+
'timeSlots.addPreset': string;
|
|
62
|
+
'timeSlots.addCustom': string;
|
|
63
|
+
'timeSlots.presetPlaceholder': string;
|
|
64
|
+
'timeSlots.remove': string;
|
|
65
|
+
'timeSlots.moveUp': string;
|
|
66
|
+
'timeSlots.moveDown': string;
|
|
67
|
+
'timeSlots.start': string;
|
|
68
|
+
'timeSlots.end': string;
|
|
69
|
+
'timeSlots.days': string;
|
|
70
|
+
'timeSlots.days.hint': string;
|
|
71
|
+
'timeSlots.preset.name': string;
|
|
72
|
+
'timeSlots.preset.windowLabel': string;
|
|
73
|
+
'timeSlots.preset.chainsOnly': string;
|
|
74
|
+
'timeSlots.preset.liang-peak.label': string;
|
|
75
|
+
'timeSlots.preset.liang-peak.window': string;
|
|
76
|
+
'timeSlots.preset.liang-valley.label': string;
|
|
77
|
+
'timeSlots.preset.liang-valley.window': string;
|
|
78
|
+
'timeSlots.preset.glm-peak.label': string;
|
|
79
|
+
'timeSlots.preset.glm-peak.window': string;
|
|
80
|
+
'timeSlots.preset.glm-valley.label': string;
|
|
81
|
+
'timeSlots.preset.glm-valley.window': string;
|
|
82
|
+
'timeSlots.preset.glm.note': string;
|
|
83
|
+
'timeSlots.preset.highCost': string;
|
|
84
|
+
'timeSlots.preset.multiplier': string;
|
|
85
|
+
'timeSlots.active': string;
|
|
86
|
+
'timeSlots.preset.glm.unconfigured': string;
|
|
87
|
+
'timeSlots.day.sun': string;
|
|
88
|
+
'timeSlots.day.mon': string;
|
|
89
|
+
'timeSlots.day.tue': string;
|
|
90
|
+
'timeSlots.day.wed': string;
|
|
91
|
+
'timeSlots.day.thu': string;
|
|
92
|
+
'timeSlots.day.fri': string;
|
|
93
|
+
'timeSlots.day.sat': string;
|
|
94
|
+
'timeSlots.selector.add': string;
|
|
95
|
+
'allDay.hint': string;
|
|
96
|
+
'allDay.flash': string;
|
|
97
|
+
'allDay.pro': string;
|
|
98
|
+
'allDay.nonconforming': string;
|
|
53
99
|
'roles.list.label': string;
|
|
54
100
|
'roles.list.hint': string;
|
|
55
101
|
'roles.list.tooltip': string;
|
|
@@ -67,14 +113,12 @@ export declare const zh: {
|
|
|
67
113
|
'roles.fallback.none': string;
|
|
68
114
|
'roles.add': string;
|
|
69
115
|
'roles.remove': string;
|
|
116
|
+
'roles.expand': string;
|
|
117
|
+
'roles.collapse': string;
|
|
70
118
|
'roles.selector.add': string;
|
|
71
119
|
'roles.rules': string;
|
|
72
120
|
'roles.rules.hint': string;
|
|
73
121
|
'roles.rules.tooltip': string;
|
|
74
|
-
'roles.rule.origin': string;
|
|
75
|
-
'roles.rule.origin.any': string;
|
|
76
|
-
'roles.rule.origin.root': string;
|
|
77
|
-
'roles.rule.origin.subagent': string;
|
|
78
122
|
'roles.rule.provider': string;
|
|
79
123
|
'roles.rule.provider.any': string;
|
|
80
124
|
'roles.rule.model': string;
|
|
@@ -92,6 +136,14 @@ export declare const zh: {
|
|
|
92
136
|
'validation.ruleRoleUndeclared': string;
|
|
93
137
|
'validation.ruleRoleRequired': string;
|
|
94
138
|
'validation.roleChainRequired': string;
|
|
139
|
+
'validation.allDayRequired': string;
|
|
140
|
+
'validation.slotChainRequired': string;
|
|
141
|
+
'validation.slotWindow': string;
|
|
142
|
+
'validation.slotDays': string;
|
|
143
|
+
'validation.slotKind': string;
|
|
144
|
+
'validation.slotPresetUnknown': string;
|
|
145
|
+
'validation.slotPresetDuplicate': string;
|
|
146
|
+
'validation.slotPresetFrozen': string;
|
|
95
147
|
'validation.selector': string;
|
|
96
148
|
'legacy.banner': string;
|
|
97
149
|
'catalog.empty': string;
|
|
@@ -128,12 +180,6 @@ export declare const zh: {
|
|
|
128
180
|
'save.saving': string;
|
|
129
181
|
'save.error': string;
|
|
130
182
|
close: string;
|
|
131
|
-
reset: string;
|
|
132
|
-
'reset.confirmTitle': string;
|
|
133
|
-
'reset.confirm': string;
|
|
134
|
-
'reset.confirm.cancel': string;
|
|
135
|
-
'reset.confirm.action': string;
|
|
136
|
-
'reset.saving': string;
|
|
137
183
|
loading: string;
|
|
138
184
|
unavailable: string;
|
|
139
185
|
'error.generic': string;
|
|
@@ -182,15 +228,61 @@ export declare const en: {
|
|
|
182
228
|
'roleAutoMatch.hint': string;
|
|
183
229
|
'roleAutoMatch.tooltip': string;
|
|
184
230
|
'rootChain.label': string;
|
|
185
|
-
'rootChain.firstLine': string;
|
|
186
|
-
'rootChain.hint': string;
|
|
187
231
|
'rootChain.tooltip': string;
|
|
188
|
-
'
|
|
232
|
+
'defaultModel.label': string;
|
|
189
233
|
'chains.selector.remove': string;
|
|
190
234
|
'chains.selector.providerPlaceholder': string;
|
|
191
235
|
'chains.selector.modelPlaceholder': string;
|
|
192
236
|
'chains.selector.wildcardLegacy': string;
|
|
193
237
|
'chains.selector.noModelsStrict': string;
|
|
238
|
+
'mainAgent.label': string;
|
|
239
|
+
'subagents.label': string;
|
|
240
|
+
'timeSlots.label': string;
|
|
241
|
+
'timeSlots.hint': string;
|
|
242
|
+
'timeSlots.tz.label': string;
|
|
243
|
+
'timeSlots.drag': string;
|
|
244
|
+
'timeSlots.name': string;
|
|
245
|
+
'timeSlots.expand': string;
|
|
246
|
+
'timeSlots.collapse': string;
|
|
247
|
+
'timeSlots.tooltip': string;
|
|
248
|
+
'timeSlots.addPreset': string;
|
|
249
|
+
'timeSlots.addCustom': string;
|
|
250
|
+
'timeSlots.presetPlaceholder': string;
|
|
251
|
+
'timeSlots.remove': string;
|
|
252
|
+
'timeSlots.moveUp': string;
|
|
253
|
+
'timeSlots.moveDown': string;
|
|
254
|
+
'timeSlots.start': string;
|
|
255
|
+
'timeSlots.end': string;
|
|
256
|
+
'timeSlots.days': string;
|
|
257
|
+
'timeSlots.days.hint': string;
|
|
258
|
+
'timeSlots.preset.name': string;
|
|
259
|
+
'timeSlots.preset.windowLabel': string;
|
|
260
|
+
'timeSlots.preset.chainsOnly': string;
|
|
261
|
+
'timeSlots.preset.liang-peak.label': string;
|
|
262
|
+
'timeSlots.preset.liang-peak.window': string;
|
|
263
|
+
'timeSlots.preset.liang-valley.label': string;
|
|
264
|
+
'timeSlots.preset.liang-valley.window': string;
|
|
265
|
+
'timeSlots.preset.glm-peak.label': string;
|
|
266
|
+
'timeSlots.preset.glm-peak.window': string;
|
|
267
|
+
'timeSlots.preset.glm-valley.label': string;
|
|
268
|
+
'timeSlots.preset.glm-valley.window': string;
|
|
269
|
+
'timeSlots.preset.glm.note': string;
|
|
270
|
+
'timeSlots.preset.highCost': string;
|
|
271
|
+
'timeSlots.preset.multiplier': string;
|
|
272
|
+
'timeSlots.active': string;
|
|
273
|
+
'timeSlots.preset.glm.unconfigured': string;
|
|
274
|
+
'timeSlots.day.sun': string;
|
|
275
|
+
'timeSlots.day.mon': string;
|
|
276
|
+
'timeSlots.day.tue': string;
|
|
277
|
+
'timeSlots.day.wed': string;
|
|
278
|
+
'timeSlots.day.thu': string;
|
|
279
|
+
'timeSlots.day.fri': string;
|
|
280
|
+
'timeSlots.day.sat': string;
|
|
281
|
+
'timeSlots.selector.add': string;
|
|
282
|
+
'allDay.hint': string;
|
|
283
|
+
'allDay.flash': string;
|
|
284
|
+
'allDay.pro': string;
|
|
285
|
+
'allDay.nonconforming': string;
|
|
194
286
|
'roles.list.label': string;
|
|
195
287
|
'roles.list.hint': string;
|
|
196
288
|
'roles.list.tooltip': string;
|
|
@@ -208,14 +300,12 @@ export declare const en: {
|
|
|
208
300
|
'roles.fallback.none': string;
|
|
209
301
|
'roles.add': string;
|
|
210
302
|
'roles.remove': string;
|
|
303
|
+
'roles.expand': string;
|
|
304
|
+
'roles.collapse': string;
|
|
211
305
|
'roles.selector.add': string;
|
|
212
306
|
'roles.rules': string;
|
|
213
307
|
'roles.rules.hint': string;
|
|
214
308
|
'roles.rules.tooltip': string;
|
|
215
|
-
'roles.rule.origin': string;
|
|
216
|
-
'roles.rule.origin.any': string;
|
|
217
|
-
'roles.rule.origin.root': string;
|
|
218
|
-
'roles.rule.origin.subagent': string;
|
|
219
309
|
'roles.rule.provider': string;
|
|
220
310
|
'roles.rule.provider.any': string;
|
|
221
311
|
'roles.rule.model': string;
|
|
@@ -233,6 +323,14 @@ export declare const en: {
|
|
|
233
323
|
'validation.ruleRoleUndeclared': string;
|
|
234
324
|
'validation.ruleRoleRequired': string;
|
|
235
325
|
'validation.roleChainRequired': string;
|
|
326
|
+
'validation.allDayRequired': string;
|
|
327
|
+
'validation.slotChainRequired': string;
|
|
328
|
+
'validation.slotWindow': string;
|
|
329
|
+
'validation.slotDays': string;
|
|
330
|
+
'validation.slotKind': string;
|
|
331
|
+
'validation.slotPresetUnknown': string;
|
|
332
|
+
'validation.slotPresetDuplicate': string;
|
|
333
|
+
'validation.slotPresetFrozen': string;
|
|
236
334
|
'validation.selector': string;
|
|
237
335
|
'legacy.banner': string;
|
|
238
336
|
'catalog.empty': string;
|
|
@@ -269,12 +367,6 @@ export declare const en: {
|
|
|
269
367
|
'save.saving': string;
|
|
270
368
|
'save.error': string;
|
|
271
369
|
close: string;
|
|
272
|
-
reset: string;
|
|
273
|
-
'reset.confirmTitle': string;
|
|
274
|
-
'reset.confirm': string;
|
|
275
|
-
'reset.confirm.cancel': string;
|
|
276
|
-
'reset.confirm.action': string;
|
|
277
|
-
'reset.saving': string;
|
|
278
370
|
loading: string;
|
|
279
371
|
unavailable: string;
|
|
280
372
|
'error.generic': string;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { HostObservable, SnapshotSelectorHook } from '@deepseek-ai/dsh-client-ui-slots';
|
|
2
|
+
export type { SnapshotSelectorHook } from '@deepseek-ai/dsh-client-ui-slots';
|
|
3
|
+
/**
|
|
4
|
+
* Bind a bare observable source to a typed uSES selector hook.
|
|
5
|
+
* subscribe/getSnapshot are captured once per source into stable closures
|
|
6
|
+
* (also re-binds `this` for method-based sources), so components never
|
|
7
|
+
* resubscribe across renders. Equality defaults to Object.is.
|
|
8
|
+
* @param w - snapshot source (engine store, Session object, store instance).
|
|
9
|
+
* @returns the selector hook.
|
|
10
|
+
*/
|
|
11
|
+
export declare function bindSnapshotSelector<T>(w: HostObservable<T>): SnapshotSelectorHook<T>;
|
package/dist/commands.d.ts
CHANGED
|
@@ -24,6 +24,7 @@ import type { CommandDefinition } from '@deepseek-ai/dsh-commands';
|
|
|
24
24
|
import { type FallbacksRole } from './config.ts';
|
|
25
25
|
import type { Origin } from './roles.ts';
|
|
26
26
|
import type { FallbacksSwitchEventData } from './events.ts';
|
|
27
|
+
import type { SlotRowConfig } from './time-slots.ts';
|
|
27
28
|
/** How many recent `fallbacks/switch` events `/fallbacks` shows (newest first). */
|
|
28
29
|
export declare const RECENT_SWITCHES_LIMIT = 5;
|
|
29
30
|
/** Minimal command registry surface (satisfied by the dsh `CommandService`). */
|
|
@@ -68,7 +69,15 @@ export interface FallbacksCommandSnapshot {
|
|
|
68
69
|
* `fallback` is `'inherit-root'` — or the role is unknown — and rootChain
|
|
69
70
|
* is non-empty; the diagnostic annotation source, spec §7.4). */
|
|
70
71
|
readonly inherit: boolean;
|
|
71
|
-
/**
|
|
72
|
+
/** Current time-slot winner + display label (P5/P7): the 分时切换 side of
|
|
73
|
+
* the status strip. The switches section below is the 降级切换 side —
|
|
74
|
+
* the copy never mixes. */
|
|
75
|
+
readonly slot: {
|
|
76
|
+
readonly winner: SlotRowConfig | 'all-day';
|
|
77
|
+
readonly label: string;
|
|
78
|
+
};
|
|
79
|
+
/** Recent `fallbacks/switch` events (failure walks — 降级切换), newest
|
|
80
|
+
* first, capped at {@link RECENT_SWITCHES_LIMIT}. */
|
|
72
81
|
readonly switches: readonly FallbacksSwitchEventData[];
|
|
73
82
|
/** Active cooldown entries for the agent. */
|
|
74
83
|
readonly cooldown: readonly FallbacksCooldownEntry[];
|
|
@@ -118,7 +127,7 @@ export interface FallbacksCommandController {
|
|
|
118
127
|
export declare const FALLBACKS_COMMAND_LOCALES: {
|
|
119
128
|
readonly zh: {
|
|
120
129
|
readonly title: "当前会话 fallback 诊断(只读)";
|
|
121
|
-
readonly description: "
|
|
130
|
+
readonly description: "查看当前会话的降级链、最近降级切换与冷却状态(只读)";
|
|
122
131
|
readonly usageConfig: "查看组合后的 fallbacks 配置(设置回读)";
|
|
123
132
|
readonly usage: " /fallbacks config 查看组合后的 fallbacks 配置(设置回读)";
|
|
124
133
|
readonly origin: "会话来源";
|
|
@@ -126,7 +135,8 @@ export declare const FALLBACKS_COMMAND_LOCALES: {
|
|
|
126
135
|
readonly chain: "链";
|
|
127
136
|
readonly inheritRoot: "(inherit-root)";
|
|
128
137
|
readonly chainNone: "未配置";
|
|
129
|
-
readonly
|
|
138
|
+
readonly slot: "分时";
|
|
139
|
+
readonly switches: "最近降级切换";
|
|
130
140
|
readonly switchesNone: "本会话暂无 fallback 切换";
|
|
131
141
|
readonly switchLine: "{from} → {to}(role={role},reason={reason})";
|
|
132
142
|
readonly cooldown: "冷却";
|
|
@@ -156,7 +166,7 @@ export declare const FALLBACKS_COMMAND_LOCALES: {
|
|
|
156
166
|
};
|
|
157
167
|
readonly en: {
|
|
158
168
|
readonly title: "Session fallback diagnostics (read-only)";
|
|
159
|
-
readonly description: "Inspect fallback chain, recent switches, and cooldown for this session (read-only)";
|
|
169
|
+
readonly description: "Inspect fallback chain, recent fallback switches, and cooldown for this session (read-only)";
|
|
160
170
|
readonly usageConfig: "show the composed fallbacks config (settings readback)";
|
|
161
171
|
readonly usage: " /fallbacks config show the composed fallbacks config (settings readback)";
|
|
162
172
|
readonly origin: "Session origin";
|
|
@@ -164,7 +174,8 @@ export declare const FALLBACKS_COMMAND_LOCALES: {
|
|
|
164
174
|
readonly chain: "Chain";
|
|
165
175
|
readonly inheritRoot: " (inherit-root)";
|
|
166
176
|
readonly chainNone: "not configured";
|
|
167
|
-
readonly
|
|
177
|
+
readonly slot: "Time slot";
|
|
178
|
+
readonly switches: "Recent fallback switches";
|
|
168
179
|
readonly switchesNone: "No fallback switches in this session";
|
|
169
180
|
readonly switchLine: "{from} → {to} (role={role}, reason={reason})";
|
|
170
181
|
readonly cooldown: "Cooldown";
|
|
@@ -253,8 +264,8 @@ export declare const FALLBACKS_CONFIG_LIST_CAP = 5;
|
|
|
253
264
|
export declare function fallbacksConfigText(summary: FallbacksConfigSummary, locale?: FallbacksCommandLocale): string;
|
|
254
265
|
/**
|
|
255
266
|
* Render the `/fallbacks` status surface for one snapshot. Kept minimal and
|
|
256
|
-
* truthful: origin → role → chain (+ inherit tail) →
|
|
257
|
-
* cooldown.
|
|
267
|
+
* truthful: origin → role → chain (+ inherit tail) → current slot (分时) →
|
|
268
|
+
* recent switches (降级切换) → cooldown.
|
|
258
269
|
*/
|
|
259
270
|
export declare function fallbacksCommandText(snapshot: FallbacksCommandSnapshot, locale?: FallbacksCommandLocale): string;
|
|
260
271
|
/**
|
package/dist/config.d.ts
CHANGED
|
@@ -27,10 +27,17 @@
|
|
|
27
27
|
*
|
|
28
28
|
* @module dsh-llm-fallbacks/config
|
|
29
29
|
*/
|
|
30
|
+
import type { SlotRowConfig } from './time-slots.ts';
|
|
30
31
|
/** How a cooled-down model comes back (spec §4). */
|
|
31
32
|
export type RevertPolicy = 'cooldown-expiry' | 'never';
|
|
32
|
-
/** A single role rule: match on
|
|
33
|
+
/** A single role rule: match on provider/model patterns (spec §3). */
|
|
33
34
|
export interface FallbacksRoleRule {
|
|
35
|
+
/**
|
|
36
|
+
* Legacy persisted wire field (PR #62 feedback): rules are subagent-only,
|
|
37
|
+
* so this constraint is IGNORED at match time — root requests never
|
|
38
|
+
* match rules. Kept in the type/schema so pre-feedback `settings.yaml`
|
|
39
|
+
* files that carry `origin` still parse, validate, and save unchanged.
|
|
40
|
+
*/
|
|
34
41
|
origin?: 'root' | 'subagent';
|
|
35
42
|
provider?: string;
|
|
36
43
|
model?: string;
|
|
@@ -104,6 +111,20 @@ export interface FallbacksConfig {
|
|
|
104
111
|
* for direct constructors that omit it).
|
|
105
112
|
*/
|
|
106
113
|
roleAutoMatch?: boolean;
|
|
114
|
+
/**
|
|
115
|
+
* Extra time-slot rows (plan fallbacks-timeslots Task 1, P5): the FIRST
|
|
116
|
+
* matching row's chain becomes the effective root chain at request time;
|
|
117
|
+
* `rootChain` (the all-day chain) is always the last row.
|
|
118
|
+
* Optional on purpose, mirroring `presets` — additive, non-breaking for
|
|
119
|
+
* library consumers. Malformed rows warn once and are skipped by the
|
|
120
|
+
* resolver; the gateway rejects them on save (Task 3).
|
|
121
|
+
*/
|
|
122
|
+
timeSlots?: SlotRowConfig[];
|
|
123
|
+
/**
|
|
124
|
+
* Config-level timezone for slot matching (default `Asia/Shanghai`,
|
|
125
|
+
* UTC+8). Not per-slot.
|
|
126
|
+
*/
|
|
127
|
+
tz?: string;
|
|
107
128
|
}
|
|
108
129
|
/**
|
|
109
130
|
* Spec §4 defaults — `Config({})` must equal this (no-op install).
|
package/dist/index.d.ts
CHANGED
|
@@ -17,10 +17,13 @@
|
|
|
17
17
|
* `{ kind: 'retry' }` (own recovery, no `next()`).
|
|
18
18
|
* - `agent/request` waterfall: apply a pending switch after `await next()`
|
|
19
19
|
* (provider/model override, inherited `reasoningEffort` dropped — the
|
|
20
|
-
* `installModelSelection` `withoutInheritedEffort` pattern)
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
20
|
+
* `installModelSelection` `withoutInheritedEffort` pattern); a
|
|
21
|
+
* root-origin `FallbacksChain/Auto` seed then overrides to the
|
|
22
|
+
* effective chain's first exact head (select-is-primary, plan
|
|
23
|
+
* fallbacks-virtual-chain Task 2); then the always-mode cap check (count
|
|
24
|
+
* `llm/retry` events for the current turn/step/provider; ≥
|
|
25
|
+
* `alwaysModeRetryCap` → same decision path, reason `always-cap` —
|
|
26
|
+
* ADR-2).
|
|
24
27
|
* - Per-agent state (`FallbackStateStore`): `agent/disposed` removes it,
|
|
25
28
|
* `agent/status` idle prunes per-step state defensively, plugin dispose
|
|
26
29
|
* clears everything (spec §6 — no residual state).
|