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/config.d.ts
CHANGED
|
@@ -4,32 +4,27 @@
|
|
|
4
4
|
* module must stay free of `@deepseek-ai/*` value imports so the client
|
|
5
5
|
* bundle never reaches schemastery).
|
|
6
6
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* (id
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
7
|
+
* Named virtual chains (config v2, plan named-virtual-chains): N named
|
|
8
|
+
* chains each selectable as `FallbacksChain/<chain id>`, carrying their own
|
|
9
|
+
* `entries` (默认降级链 + 链尾) and `timeSlots`. Declared roles keep identity
|
|
10
|
+
* (`id`/`persona`/`prompt?`/`permissions?`) plus an OPTIONAL `chain`
|
|
11
|
+
* POINTER — a manually specified chain id (「指定降级链」), never an auto
|
|
12
|
+
* mode: absent/empty = NOT SPECIFIED, the plugin does not intervene and the
|
|
13
|
+
* child inherits the delegating agent's route. The v1 two-block model
|
|
14
|
+
* (`rootChain` + per-role inline chains + `roles.rules`) is deleted; the
|
|
15
|
+
* runtime consumes the v2 shape directly and flags surviving v1 keys at
|
|
16
|
+
* startup via `detectLegacyKeys` (warn-only migration — no auto-write).
|
|
16
17
|
*
|
|
17
|
-
* Spec §
|
|
18
|
+
* Spec §1 is authoritative for field names and default values — notably
|
|
18
19
|
* `triggerCodes` defaults to dsh's stable failure codes `['AUTH', 'QUOTA',
|
|
19
|
-
* 'RATE_LIMIT']
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
* master switch (row disable = fiber destroy), and the runtime gates re-key
|
|
25
|
-
* to content presence. A stored profile still carrying the removed
|
|
26
|
-
* `enabled:` key loads cleanly — the gateway tolerates and strips it (the
|
|
27
|
-
* advisor LEGACY_KEYS mechanism), it is never read and never re-persisted.
|
|
20
|
+
* 'RATE_LIMIT']`. An unconfigured install (empty `chains`) is a no-op
|
|
21
|
+
* pass-through exactly like an uninstalled plugin — there is NO config-level
|
|
22
|
+
* `enabled` switch: the Plugins-page row toggle is the master switch and the
|
|
23
|
+
* runtime gates re-key to `isFallbackActive` (`chains.length > 0`). Nothing
|
|
24
|
+
* pre-creates a default chain: empty `chains` is the ONLY first-run state.
|
|
28
25
|
*
|
|
29
26
|
* This module is pure logic: it must not import any `@deepseek-ai/*` package
|
|
30
|
-
* (types included) — `FallbacksConfig` is the plugin's own type.
|
|
31
|
-
* registers the schemastery schema (see `./schema.ts`) with
|
|
32
|
-
* `installSettingsSection` under the `fallbacks` settings namespace.
|
|
27
|
+
* (types included) — `FallbacksConfig` is the plugin's own type.
|
|
33
28
|
*
|
|
34
29
|
* @module dsh-llm-fallbacks/config
|
|
35
30
|
*/
|
|
@@ -38,31 +33,31 @@ import type { SlotRowConfig } from './time-slots.ts';
|
|
|
38
33
|
export type RecoveryPolicy = 'timer' | 'half-open';
|
|
39
34
|
/** How a cooled-down model comes back (spec §4). */
|
|
40
35
|
export type RevertPolicy = 'cooldown-expiry' | 'never';
|
|
41
|
-
/**
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
* so this constraint is IGNORED at match time — root requests never
|
|
46
|
-
* match rules. Kept in the type/schema so pre-feedback `settings.yaml`
|
|
47
|
-
* files that carry `origin` still parse, validate, and save unchanged.
|
|
48
|
-
*/
|
|
49
|
-
origin?: 'root' | 'subagent';
|
|
50
|
-
provider?: string;
|
|
51
|
-
model?: string;
|
|
52
|
-
role: string;
|
|
53
|
-
}
|
|
36
|
+
/** Chain id format (v2): case-sensitive, uppercase allowed so the migrated
|
|
37
|
+
* default id is exactly `Auto`. Deliberately NOT {@link ROLE_ID_PATTERN},
|
|
38
|
+
* which keeps governing role ids. */
|
|
39
|
+
export declare const CHAIN_ID_PATTERN: RegExp;
|
|
54
40
|
/**
|
|
55
|
-
*
|
|
56
|
-
*
|
|
57
|
-
* `
|
|
41
|
+
* One named virtual chain (v2). `id` doubles as the picker model id —
|
|
42
|
+
* renaming it would orphan every saved selection, so only `label` is
|
|
43
|
+
* editable in the UI. The LAST `entries` element is the 链尾: exactly one
|
|
44
|
+
* official model. The FIRST matching `timeSlots` row REPLACES `entries`.
|
|
58
45
|
*/
|
|
59
|
-
export
|
|
46
|
+
export interface NamedChain {
|
|
47
|
+
id: string;
|
|
48
|
+
/** Settings tab title + picker display prefix (display-only). */
|
|
49
|
+
label: string;
|
|
50
|
+
/** 默认降级链 + 链尾. */
|
|
51
|
+
entries: string[];
|
|
52
|
+
/** 分时 rows scoped to this chain; first match replaces {@link entries}. */
|
|
53
|
+
timeSlots?: SlotRowConfig[];
|
|
54
|
+
}
|
|
60
55
|
/**
|
|
61
|
-
* A declared role entity (
|
|
56
|
+
* A declared role entity (v2): identity + an optional chain POINTER.
|
|
62
57
|
*
|
|
63
58
|
* `prompt` / `permissions` are schema-reserved for the next iteration
|
|
64
|
-
*
|
|
65
|
-
*
|
|
59
|
+
* — no consumer this round, and writing them does NOT change this
|
|
60
|
+
* round's degradation behavior.
|
|
66
61
|
*/
|
|
67
62
|
export interface FallbacksRole {
|
|
68
63
|
id: string;
|
|
@@ -75,58 +70,59 @@ export interface FallbacksRole {
|
|
|
75
70
|
allow?: string[];
|
|
76
71
|
deny?: string[];
|
|
77
72
|
};
|
|
78
|
-
|
|
79
|
-
|
|
73
|
+
/**
|
|
74
|
+
* Manually specified named chain id for children dispatched under this
|
|
75
|
+
* role (「指定降级链」) — a POINTER into `chains[]`, never a chain
|
|
76
|
+
* definition. Absent or empty ⇒ NOT SPECIFIED: the plugin does not
|
|
77
|
+
* intervene and the child inherits the delegating agent's route. The
|
|
78
|
+
* plugin never picks a chain on its own.
|
|
79
|
+
*/
|
|
80
|
+
chain?: string;
|
|
80
81
|
}
|
|
81
|
-
/** Role grouping
|
|
82
|
+
/** Role grouping (v2): declared entities only — `rules` is deleted. */
|
|
82
83
|
export interface FallbacksRoles {
|
|
83
84
|
list: FallbacksRole[];
|
|
84
|
-
rules: FallbacksRoleRule[];
|
|
85
85
|
}
|
|
86
86
|
/**
|
|
87
|
-
*
|
|
87
|
+
* One declared role as the SCHEMA may compose it: identical to
|
|
88
|
+
* {@link FallbacksRole} except that a v1 profile still carries the ARRAY form
|
|
89
|
+
* of `chain`. The schema must accept it (composition happens in cordis BEFORE
|
|
90
|
+
* `apply()`, so a rejection there kills the fiber and no migration can run);
|
|
91
|
+
* {@link migrateLegacyConfig} narrows it to the string pointer.
|
|
92
|
+
*/
|
|
93
|
+
export interface FallbacksRoleSource extends Omit<FallbacksRole, 'chain'> {
|
|
94
|
+
chain?: string | string[];
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* The composed settings shape produced by the schemastery `Config` — the input
|
|
98
|
+
* of {@link migrateLegacyConfig}, not the shape the runtime consumes.
|
|
99
|
+
*/
|
|
100
|
+
export interface FallbacksConfigSource extends Omit<FallbacksConfig, 'roles'> {
|
|
101
|
+
roles: {
|
|
102
|
+
list: FallbacksRoleSource[];
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* The full `fallbacks` settings shape (named virtual chains, verbatim
|
|
88
107
|
* field names).
|
|
89
108
|
*/
|
|
90
109
|
export interface FallbacksConfig {
|
|
91
110
|
triggerCodes: string[];
|
|
92
|
-
|
|
111
|
+
chains: NamedChain[];
|
|
93
112
|
roles: FallbacksRoles;
|
|
94
113
|
cooldownMs: number;
|
|
95
114
|
revertPolicy: RevertPolicy;
|
|
96
115
|
maxSwitchesPerStep: number;
|
|
97
|
-
alwaysModeRetryCap: number;
|
|
98
116
|
/**
|
|
99
117
|
* Preset-role injection switch: `'bundled'` declares the 5 preset roles
|
|
100
118
|
* (spec §9.2) as seed rows on apply; `'none'` disables declaration.
|
|
101
119
|
* Optional on purpose — a required field would break library consumers
|
|
102
|
-
* that construct `FallbacksConfig` literals
|
|
103
|
-
*
|
|
104
|
-
*
|
|
105
|
-
*
|
|
120
|
+
* that construct `FallbacksConfig` literals. The value domain is guarded
|
|
121
|
+
* by the schema (`Config` in `src/schema.ts`), NOT by
|
|
122
|
+
* `validateFallbacksConfig`, and every resolved config carries a value
|
|
123
|
+
* via the schema default.
|
|
106
124
|
*/
|
|
107
125
|
presets?: 'bundled' | 'none';
|
|
108
|
-
/**
|
|
109
|
-
* Dispatch-time LLM role auto-match switch (plan fallbacks-role-automatch
|
|
110
|
-
* Task 1): when `true` (default), a subagent-origin request with no
|
|
111
|
-
* explicit/rules-resolved role may have the best-fit declared role picked
|
|
112
|
-
* by the LLM; `false` reproduces today's behavior exactly. Optional on
|
|
113
|
-
* purpose, mirroring `presets` — a required field would break library
|
|
114
|
-
* consumers that construct `FallbacksConfig` literals with the existing
|
|
115
|
-
* keys (additive, non-breaking). The value domain is guarded by the
|
|
116
|
-
* schema (`z.boolean().default(true)` in `src/schema.ts`), and the
|
|
117
|
-
* runtime reads it defensively as `config.roleAutoMatch ?? true` (safe
|
|
118
|
-
* for direct constructors that omit it).
|
|
119
|
-
*/
|
|
120
|
-
roleAutoMatch?: boolean;
|
|
121
|
-
/**
|
|
122
|
-
* Extra time-slot rows (plan fallbacks-timeslots Task 1, P5): the FIRST
|
|
123
|
-
* matching row's chain becomes the effective root chain at request time;
|
|
124
|
-
* `rootChain` (the all-day chain) is always the last row.
|
|
125
|
-
* Optional on purpose, mirroring `presets` — additive, non-breaking for
|
|
126
|
-
* library consumers. Malformed rows warn once and are skipped by the
|
|
127
|
-
* resolver; the gateway rejects them on save (Task 3).
|
|
128
|
-
*/
|
|
129
|
-
timeSlots?: SlotRowConfig[];
|
|
130
126
|
/**
|
|
131
127
|
* Config-level timezone for slot matching (default `Asia/Shanghai`,
|
|
132
128
|
* UTC+8). Not per-slot.
|
|
@@ -137,41 +133,40 @@ export interface FallbacksConfig {
|
|
|
137
133
|
* 1): `'timer'` restores the preferred candidate when the cooldown
|
|
138
134
|
* expires (today's behavior); `'half-open'` leaves the route half-open
|
|
139
135
|
* for one logged probe instead. Optional on purpose, mirroring
|
|
140
|
-
* `presets
|
|
141
|
-
*
|
|
142
|
-
*
|
|
143
|
-
* (`Config` in `src/schema.ts`), NOT by `validateFallbacksConfig`, and
|
|
144
|
-
* every resolved config carries a value via the schema default.
|
|
136
|
+
* `presets`. The value domain is guarded by the schema, NOT by
|
|
137
|
+
* `validateFallbacksConfig`, and every resolved config carries a value
|
|
138
|
+
* via the schema default.
|
|
145
139
|
*/
|
|
146
140
|
recovery?: RecoveryPolicy;
|
|
147
141
|
}
|
|
148
142
|
/**
|
|
149
|
-
* Spec §
|
|
150
|
-
*
|
|
151
|
-
*
|
|
152
|
-
*
|
|
153
|
-
* (
|
|
143
|
+
* Spec §1 defaults — `Config({})` must equal this (no-op install).
|
|
144
|
+
* Empty `chains` is the ONLY first-run state: nothing pre-creates an
|
|
145
|
+
* `Auto` chain and nothing seeds `entries` — the picker row appears only
|
|
146
|
+
* after the user creates a chain in the card. The migrated/seeded default
|
|
147
|
+
* chain (`{ id: 'Auto', label: '默认链', entries, timeSlots }`) exists only
|
|
148
|
+
* in the migration table (docs) applied by hand — warn-only migration.
|
|
154
149
|
*/
|
|
155
150
|
export declare const defaultFallbacksConfig: FallbacksConfig;
|
|
151
|
+
/** Role id format (aligned with yet-another-subagent `isValidProfileId`). */
|
|
152
|
+
export declare const ROLE_ID_PATTERN: RegExp;
|
|
156
153
|
/**
|
|
157
|
-
* Reserved role id:
|
|
158
|
-
*
|
|
154
|
+
* Reserved role id: FORBIDDEN in `roles.list[].id` (the validator's reserved
|
|
155
|
+
* warn) and in seed declarations (`seeds.ts` reserved-id skip). `rules` that
|
|
156
|
+
* could target it are deleted (v2), but the id itself stays reserved so a
|
|
157
|
+
* declared role can never shadow the "no specific role" meaning.
|
|
159
158
|
*/
|
|
160
159
|
export declare const INHERIT_ROLE_ID = "inherit";
|
|
161
160
|
/**
|
|
162
|
-
* The no-op gate (AC-8)
|
|
163
|
-
*
|
|
164
|
-
*
|
|
165
|
-
*
|
|
166
|
-
*
|
|
167
|
-
*
|
|
168
|
-
*
|
|
169
|
-
* `config.enabled` sites (request waterfalls, picker-row registration, TUI
|
|
170
|
-
* summary, General-row badge) all read through this.
|
|
161
|
+
* The no-op gate (AC-8): the plugin intervenes exactly when at least one
|
|
162
|
+
* named chain is configured. Roles alone no longer activate (a role
|
|
163
|
+
* without a chain is pure identity). An inactive config is a pass-through
|
|
164
|
+
* exactly like an uninstalled plugin; the Plugins-page row toggle remains
|
|
165
|
+
* the master switch (row disable = fiber destroy). A non-empty chain with
|
|
166
|
+
* empty `entries` still registers the picker row (content presence) but
|
|
167
|
+
* refuses to delegate (conformance gate in the walk).
|
|
171
168
|
*/
|
|
172
169
|
export declare function isFallbackActive(config: FallbacksConfig): boolean;
|
|
173
|
-
/** Role id format (aligned with yet-another-subagent `isValidProfileId`). */
|
|
174
|
-
export declare const ROLE_ID_PATTERN: RegExp;
|
|
175
170
|
/**
|
|
176
171
|
* Minimal logger surface {@link validateFallbacksConfig} warns through —
|
|
177
172
|
* keeps this module free of `@deepseek-ai/*` imports (a cordis Logger is
|
|
@@ -182,27 +177,67 @@ export interface FallbacksConfigLogger {
|
|
|
182
177
|
}
|
|
183
178
|
/**
|
|
184
179
|
* Validate a fallbacks config (pure, warn-only — never throws, never
|
|
185
|
-
* mutates):
|
|
186
|
-
*
|
|
187
|
-
*
|
|
188
|
-
*
|
|
189
|
-
*
|
|
190
|
-
*
|
|
191
|
-
*
|
|
192
|
-
*
|
|
193
|
-
*
|
|
180
|
+
* mutates). Per chain: id format (case-sensitive, {@link CHAIN_ID_PATTERN})
|
|
181
|
+
* + cross-chain uniqueness, tail conformance (the LAST entry must be
|
|
182
|
+
* exactly one official model — a non-conforming chain's slot rows and
|
|
183
|
+
* delegate stay inert), selector legality per entry, and the slot-row
|
|
184
|
+
* guards (unknown preset, duplicate preset per chain, preset rows carrying
|
|
185
|
+
* their own windows). Per role (after the chain loop, so the declared id
|
|
186
|
+
* set is complete): the existing id format/reserved/duplicate warns, and a
|
|
187
|
+
* non-empty `chain` pointer naming no declared chain id earns ONE warn and
|
|
188
|
+
* behaves as NOT SPECIFIED. Each violation emits one `llm-fallbacks: ...`
|
|
189
|
+
* warn — the config stays usable (warn-not-crash semantics). `persona` and
|
|
190
|
+
* `label` are free text and deliberately not validated.
|
|
194
191
|
*/
|
|
195
192
|
export declare function validateFallbacksConfig(config: FallbacksConfig, logger: FallbacksConfigLogger): void;
|
|
196
193
|
/**
|
|
197
|
-
* Detect legacy
|
|
198
|
-
*
|
|
199
|
-
*
|
|
200
|
-
*
|
|
201
|
-
*
|
|
202
|
-
*
|
|
203
|
-
*
|
|
204
|
-
*
|
|
205
|
-
*
|
|
206
|
-
*
|
|
194
|
+
* Detect legacy config leftovers in a config SOURCE — the composed object
|
|
195
|
+
* `source()` returns, or a raw settings document. Two generations:
|
|
196
|
+
*
|
|
197
|
+
* - Older removals: `alwaysModeRetryCap`, `roleAutoMatch` (direction C),
|
|
198
|
+
* `roles.default`, and the renamed role-entity fields
|
|
199
|
+
* `roles.list[].label` / `roles.list[].description`.
|
|
200
|
+
* - v1 two-block keys (named-virtual-chains): `rootChain`, top-level
|
|
201
|
+
* `timeSlots`, `roles.rules`, `roles.list[].fallback`, and the v1 ARRAY
|
|
202
|
+
* form of `roles.list[].chain` (an array where v2 declares a string —
|
|
203
|
+
* stripped rather than coerced).
|
|
204
|
+
*
|
|
205
|
+
* Returns descriptive key names; the gateway attaches them as
|
|
206
|
+
* `get().legacyKeys` so the client can show a migration banner. Warn-only:
|
|
207
|
+
* no legacy value is ever read or re-persisted.
|
|
207
208
|
*/
|
|
208
209
|
export declare function detectLegacyKeys(source: Record<string, unknown>): string[];
|
|
210
|
+
/**
|
|
211
|
+
* The chain a v1 `rootChain` migrates into (plan fallbacks-v1-auto-migration):
|
|
212
|
+
* the id is stable so an already-selected `FallbacksChain/Auto` route keeps
|
|
213
|
+
* resolving, and the label is display-only.
|
|
214
|
+
*/
|
|
215
|
+
export declare const MIGRATED_CHAIN_ID = "Auto";
|
|
216
|
+
/** Display label of {@link MIGRATED_CHAIN_ID}. */
|
|
217
|
+
export declare const MIGRATED_CHAIN_LABEL = "\u9ED8\u8BA4\u94FE";
|
|
218
|
+
/**
|
|
219
|
+
* Upgrade a config SOURCE to the v2 named-chain shape — in memory, at every
|
|
220
|
+
* read. Pure, total, idempotent: a v2 config comes back unchanged, a v1 one is
|
|
221
|
+
* converted, and any malformed shape degrades to the defaults instead of
|
|
222
|
+
* throwing (the banner keeps reporting the raw leftovers, so honesty survives
|
|
223
|
+
* the coercion).
|
|
224
|
+
*
|
|
225
|
+
* Conversion rules (plan §Goal):
|
|
226
|
+
* 1. v1 `rootChain` + top-level `timeSlots` become chain #0
|
|
227
|
+
* (`{ id: 'Auto', label: '默认链', entries, timeSlots }`), so the picker
|
|
228
|
+
* route the user already selected keeps working.
|
|
229
|
+
* 2. `roles.list[]` survive as identity rows (`id` / `persona` / reserved
|
|
230
|
+
* `prompt` / `permissions`); a v1 ARRAY `chain` is dropped (NOT SPECIFIED —
|
|
231
|
+
* the card's 指定降级链 select takes over) and `fallback` is dropped;
|
|
232
|
+
* `roles.rules` / `roles.default` / `enabled` never reach the output.
|
|
233
|
+
* 3. A config that already carries a non-empty `chains` array keeps it and only
|
|
234
|
+
* loses the v1 leftovers. An EMPTY `chains` alongside a v1 `rootChain` is a
|
|
235
|
+
* profile that never had v2 content, so it migrates (otherwise the user's
|
|
236
|
+
* chain would silently vanish).
|
|
237
|
+
*
|
|
238
|
+
* No file is rewritten here — the next explicit save persists the v2 shape.
|
|
239
|
+
* @param source - the composed config (schema defaults → plugin row → user
|
|
240
|
+
* layer) or any raw document.
|
|
241
|
+
* @returns a complete {@link FallbacksConfig}; never the input object itself.
|
|
242
|
+
*/
|
|
243
|
+
export declare function migrateLegacyConfig(source: unknown): FallbacksConfig;
|
package/dist/cooldown.d.ts
CHANGED
|
@@ -1,15 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Cooldown store
|
|
2
|
+
* Cooldown store (spec §5.1; plan Task 2).
|
|
3
3
|
*
|
|
4
4
|
* `CooldownStore` maps `provider/model` keys to an expiry epoch ms with lazy
|
|
5
5
|
* evaluation: expired entries are dropped on read. `revertPolicy: 'never'`
|
|
6
6
|
* is expressed by suppressing with `Infinity` — the entry never expires
|
|
7
7
|
* within the session.
|
|
8
8
|
*
|
|
9
|
-
* `StepFailureSet` is the step's failed-model set (spec §5.1 `failed`).
|
|
10
|
-
* `switchCount` / `maxSwitchesPerStep` judgement belongs to the caller
|
|
11
|
-
* (Task 3) — this task only provides the data structure.
|
|
12
|
-
*
|
|
13
9
|
* @module dsh-llm-fallbacks/cooldown
|
|
14
10
|
*/
|
|
15
11
|
/**
|
|
@@ -45,13 +41,3 @@ export declare class CooldownStore {
|
|
|
45
41
|
untilEpochMs: number;
|
|
46
42
|
}>;
|
|
47
43
|
}
|
|
48
|
-
/**
|
|
49
|
-
* The current step's failed-model set (`${provider}/${model}` keys).
|
|
50
|
-
*/
|
|
51
|
-
export declare class StepFailureSet {
|
|
52
|
-
private keys;
|
|
53
|
-
get size(): number;
|
|
54
|
-
add(key: string): void;
|
|
55
|
-
has(key: string): boolean;
|
|
56
|
-
reset(): void;
|
|
57
|
-
}
|
package/dist/events.d.ts
CHANGED
|
@@ -15,15 +15,15 @@
|
|
|
15
15
|
* @module dsh-llm-fallbacks/events
|
|
16
16
|
*/
|
|
17
17
|
/**
|
|
18
|
-
* Why a switch was decided
|
|
18
|
+
* Why a switch was decided — a **history and bookkeeping vocabulary** since
|
|
19
|
+
* direction C, not a set of live decision paths.
|
|
19
20
|
*
|
|
20
|
-
* `
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
* renderers
|
|
25
|
-
*
|
|
26
|
-
* no pending switch / cooldown / failure bookkeeping (no `commit()`).
|
|
21
|
+
* `trigger-code` is the only reason the current code produces (the walk's
|
|
22
|
+
* swallowed trigger failure, and the blocked-attempt record that mirrors it).
|
|
23
|
+
* `always-cap` (retired always-mode cap) and `role-inject` (retired
|
|
24
|
+
* dispatch-time request override) survive only so legacy `fallbacks/switch`
|
|
25
|
+
* events and their renderers keep a label; nothing writes them any more, and
|
|
26
|
+
* an unknown reason still renders raw (AC-5).
|
|
27
27
|
*/
|
|
28
28
|
export type FallbackSwitchReason = 'trigger-code' | 'always-cap' | 'role-inject';
|
|
29
29
|
/** Durable payload of one provider/model switch (spec §5 table). */
|