dsh-llm-fallbacks 0.6.1 → 0.6.3
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 +19 -12
- package/README.zh-CN.md +19 -12
- package/dist/client/FallbacksCard.d.ts +71 -71
- package/dist/client/fallbacks-store.d.ts +6 -5
- package/dist/client/index.js +1447 -1561
- package/dist/client/locales.d.ts +0 -18
- package/dist/commands.d.ts +6 -1
- package/dist/config.d.ts +24 -7
- package/dist/gateway.d.ts +8 -2
- package/dist/index.d.ts +2 -1
- package/dist/index.js +14 -23
- package/dist/tui-settings.d.ts +5 -2
- package/dist/virtual-adapter.d.ts +15 -10
- package/icon.svg +16 -0
- package/locale/en.json +6 -0
- package/locale/zh.json +6 -0
- package/package.json +5 -2
- package/scripts/build-client.ts +0 -1
package/dist/client/locales.d.ts
CHANGED
|
@@ -1,18 +1,9 @@
|
|
|
1
1
|
import type { FallbackSwitchReason } from '../events.ts';
|
|
2
2
|
/** Simplified Chinese dictionary (the key-set source of truth). */
|
|
3
3
|
export declare const zh: {
|
|
4
|
-
title: string;
|
|
5
|
-
intro: string;
|
|
6
|
-
collapse: string;
|
|
7
|
-
expand: string;
|
|
8
|
-
unsaved: string;
|
|
9
4
|
discard: string;
|
|
10
5
|
retry: string;
|
|
11
6
|
readOnly: string;
|
|
12
|
-
'enabled.label': string;
|
|
13
|
-
'enabled.hint': string;
|
|
14
|
-
'enabled.tooltip': string;
|
|
15
|
-
'enabled.off': string;
|
|
16
7
|
'triggerCodes.label': string;
|
|
17
8
|
'triggerCodes.hint': string;
|
|
18
9
|
'triggerCodes.tooltip': string;
|
|
@@ -199,18 +190,9 @@ export declare const zh: {
|
|
|
199
190
|
export type FallbacksKey = keyof typeof zh;
|
|
200
191
|
/** English dictionary, checked complete against the zh key set. */
|
|
201
192
|
export declare const en: {
|
|
202
|
-
title: string;
|
|
203
|
-
intro: string;
|
|
204
|
-
collapse: string;
|
|
205
|
-
expand: string;
|
|
206
|
-
unsaved: string;
|
|
207
193
|
discard: string;
|
|
208
194
|
retry: string;
|
|
209
195
|
readOnly: string;
|
|
210
|
-
'enabled.label': string;
|
|
211
|
-
'enabled.hint': string;
|
|
212
|
-
'enabled.tooltip': string;
|
|
213
|
-
'enabled.off': string;
|
|
214
196
|
'triggerCodes.label': string;
|
|
215
197
|
'triggerCodes.hint': string;
|
|
216
198
|
'triggerCodes.tooltip': string;
|
package/dist/commands.d.ts
CHANGED
|
@@ -109,7 +109,12 @@ export interface FallbacksCommandSnapshot {
|
|
|
109
109
|
* runtime) is summarized as `''` and rendered as `*`.
|
|
110
110
|
*/
|
|
111
111
|
export interface FallbacksConfigSummary {
|
|
112
|
-
|
|
112
|
+
/**
|
|
113
|
+
* Content-presence gate (`isFallbackActive`, plan fallbacks-web-ux-alignment
|
|
114
|
+
* T2 — the removed config-level `enabled` switch re-keyed): the plugin
|
|
115
|
+
* intervenes exactly when a chain/time-slot/role is configured.
|
|
116
|
+
*/
|
|
117
|
+
readonly active: boolean;
|
|
113
118
|
readonly triggerCodes: readonly string[];
|
|
114
119
|
readonly rootChain: readonly string[];
|
|
115
120
|
/** Summarized time-slot rows (preset rows carry `preset`, custom rows carry `start`/`end`; both may carry a day mask). */
|
package/dist/config.d.ts
CHANGED
|
@@ -17,8 +17,14 @@
|
|
|
17
17
|
* Spec §4 is authoritative for field names and default values — notably
|
|
18
18
|
* `triggerCodes` defaults to dsh's stable failure codes `['AUTH', 'QUOTA',
|
|
19
19
|
* 'RATE_LIMIT']` (there is no `QUOTA_EXCEEDED` code in dsh), and an
|
|
20
|
-
* unconfigured install (
|
|
21
|
-
*
|
|
20
|
+
* unconfigured install (empty `rootChain`, no time slots, empty roles) is a
|
|
21
|
+
* no-op pass-through exactly like an uninstalled plugin (AC-8 —
|
|
22
|
+
* {@link isFallbackActive}). There is NO config-level `enabled` switch
|
|
23
|
+
* (plan fallbacks-web-ux-alignment T2): the Plugins-page row toggle is the
|
|
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.
|
|
22
28
|
*
|
|
23
29
|
* This module is pure logic: it must not import any `@deepseek-ai/*` package
|
|
24
30
|
* (types included) — `FallbacksConfig` is the plugin's own type. Task 3
|
|
@@ -82,7 +88,6 @@ export interface FallbacksRoles {
|
|
|
82
88
|
* field names).
|
|
83
89
|
*/
|
|
84
90
|
export interface FallbacksConfig {
|
|
85
|
-
enabled: boolean;
|
|
86
91
|
triggerCodes: string[];
|
|
87
92
|
rootChain: string[];
|
|
88
93
|
roles: FallbacksRoles;
|
|
@@ -142,10 +147,10 @@ export interface FallbacksConfig {
|
|
|
142
147
|
}
|
|
143
148
|
/**
|
|
144
149
|
* Spec §4 defaults — `Config({})` must equal this (no-op install).
|
|
145
|
-
*
|
|
146
|
-
*
|
|
147
|
-
*
|
|
148
|
-
*
|
|
150
|
+
* There is no `enabled` default (the key is removed — the Plugins-page row
|
|
151
|
+
* toggle is the master switch): an unconfigured install (empty rootChain,
|
|
152
|
+
* no time slots, empty roles) behaves exactly like an uninstalled plugin
|
|
153
|
+
* (AC-3 / no-op invariant, {@link isFallbackActive}).
|
|
149
154
|
*/
|
|
150
155
|
export declare const defaultFallbacksConfig: FallbacksConfig;
|
|
151
156
|
/**
|
|
@@ -153,6 +158,18 @@ export declare const defaultFallbacksConfig: FallbacksConfig;
|
|
|
153
158
|
* the no-rule-match fallback, but FORBIDDEN in `roles.list[].id`.
|
|
154
159
|
*/
|
|
155
160
|
export declare const INHERIT_ROLE_ID = "inherit";
|
|
161
|
+
/**
|
|
162
|
+
* The no-op gate (AC-8), re-keyed from the removed `enabled` switch to
|
|
163
|
+
* CONTENT PRESENCE (plan fallbacks-web-ux-alignment T2): the plugin
|
|
164
|
+
* intervenes exactly when something is configured — a non-empty `rootChain`
|
|
165
|
+
* (the all-day chain), at least one time-slot row, or at least one declared
|
|
166
|
+
* role. An inactive config is a pass-through exactly like an uninstalled
|
|
167
|
+
* plugin; the Plugins-page row toggle remains the master switch (row
|
|
168
|
+
* disable = fiber destroy). ONE helper for every runtime gate — the former
|
|
169
|
+
* `config.enabled` sites (request waterfalls, picker-row registration, TUI
|
|
170
|
+
* summary, General-row badge) all read through this.
|
|
171
|
+
*/
|
|
172
|
+
export declare function isFallbackActive(config: FallbacksConfig): boolean;
|
|
156
173
|
/** Role id format (aligned with yet-another-subagent `isValidProfileId`). */
|
|
157
174
|
export declare const ROLE_ID_PATTERN: RegExp;
|
|
158
175
|
/**
|
package/dist/gateway.d.ts
CHANGED
|
@@ -28,7 +28,12 @@
|
|
|
28
28
|
* profile patch). There is NO hard-gate resolver (unlike advisor's
|
|
29
29
|
* `resolveAdvisorConfig`): the fallbacks decision path runs at
|
|
30
30
|
* `agent/request` time in `src/index.ts`, so the gateway returns the raw
|
|
31
|
-
* composed config
|
|
31
|
+
* composed config. There is NO config-level `enabled` key on the contract
|
|
32
|
+
* (plan fallbacks-web-ux-alignment T2): the Plugins-page row toggle is the
|
|
33
|
+
* master switch, the runtime gates read content presence
|
|
34
|
+
* (`isFallbackActive` in `src/config.ts`), and a stored `enabled:` line is
|
|
35
|
+
* tolerated-and-stripped ({@link LEGACY_KEYS} — never read, never
|
|
36
|
+
* re-persisted).
|
|
32
37
|
* `set` validates the patch against the `Config` schema first (unknown-key
|
|
33
38
|
* rejection unchanged — the settings service itself is non-strict and would
|
|
34
39
|
* merge the unknown key through), then writes the plugin's profile-entry
|
|
@@ -213,7 +218,8 @@ export declare class FallbacksConfigGateway extends TypertRemoteService {
|
|
|
213
218
|
/**
|
|
214
219
|
* Read the current composed config (schema defaults → entry base → profile
|
|
215
220
|
* patch). No hard-gate resolver (ADR-2): the raw composed config is
|
|
216
|
-
* the wire value
|
|
221
|
+
* the wire value. The removed `enabled` key never crosses the wire (the
|
|
222
|
+
* read whitelist drops it — the snapshot-strip half of LEGACY_KEYS).
|
|
217
223
|
* @returns the wire-normalized composed config plus `legacyKeys` — legacy
|
|
218
224
|
* two-block-era fields (`chains` / `roles.default` / undeclared rule
|
|
219
225
|
* role refs) detected on the composed source (schemastery retains them,
|
package/dist/index.d.ts
CHANGED
|
@@ -11,7 +11,8 @@
|
|
|
11
11
|
* `apply` reads the Loader's live config reference, and the
|
|
12
12
|
* `settings/document-updated` listener re-derives the runtime caches —
|
|
13
13
|
* the old `installSection` setSource/onChange contract, spec §4).
|
|
14
|
-
* - `agent/request-error` waterfall:
|
|
14
|
+
* - `agent/request-error` waterfall: inactive config (`isFallbackActive`) /
|
|
15
|
+
* code ∉ `triggerCodes`
|
|
15
16
|
* (**always mode included**) → `next()`; otherwise resolve role + chain,
|
|
16
17
|
* and when a candidate survives the filter (current / cooldown /
|
|
17
18
|
* step-failed / `provider/*`-missing-id) write the pending switch +
|
package/dist/index.js
CHANGED
|
@@ -323,7 +323,6 @@ var RecoveryStore = class {
|
|
|
323
323
|
//#endregion
|
|
324
324
|
//#region .build/host/config.js
|
|
325
325
|
const defaultFallbacksConfig = {
|
|
326
|
-
enabled: false,
|
|
327
326
|
triggerCodes: [
|
|
328
327
|
"AUTH",
|
|
329
328
|
"QUOTA",
|
|
@@ -345,6 +344,9 @@ const defaultFallbacksConfig = {
|
|
|
345
344
|
recovery: "timer"
|
|
346
345
|
};
|
|
347
346
|
const INHERIT_ROLE_ID = "inherit";
|
|
347
|
+
function isFallbackActive(config) {
|
|
348
|
+
return config.rootChain.length > 0 || (config.timeSlots?.length ?? 0) > 0 || config.roles.list.length > 0;
|
|
349
|
+
}
|
|
348
350
|
const ROLE_ID_PATTERN = /^[a-z0-9-]{1,32}$/;
|
|
349
351
|
function validateFallbacksConfig(config, logger) {
|
|
350
352
|
const declaredIds = new Set();
|
|
@@ -412,7 +414,6 @@ function isRecordLike(value) {
|
|
|
412
414
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
413
415
|
}
|
|
414
416
|
const Config = z.object({
|
|
415
|
-
enabled: z.boolean().default(false),
|
|
416
417
|
triggerCodes: z.array(z.string()).default([
|
|
417
418
|
"AUTH",
|
|
418
419
|
"QUOTA",
|
|
@@ -874,7 +875,7 @@ const ROLE_STATE_SCHEMA = { parse(value) {
|
|
|
874
875
|
};
|
|
875
876
|
}
|
|
876
877
|
}
|
|
877
|
-
|
|
878
|
+
return null;
|
|
878
879
|
} };
|
|
879
880
|
function isInheritedEventCount(value) {
|
|
880
881
|
return typeof value === "number" && Number.isSafeInteger(value) && value >= 0;
|
|
@@ -1515,7 +1516,6 @@ function overrideConfigWithRouteRule(seed, to, explicitEffort) {
|
|
|
1515
1516
|
//#region .build/host/gateway.js
|
|
1516
1517
|
const FALLBACKS_PROFILE_ENTRY = "llm-fallbacks";
|
|
1517
1518
|
const CONFIG_KEYS = {
|
|
1518
|
-
enabled: true,
|
|
1519
1519
|
triggerCodes: true,
|
|
1520
1520
|
rootChain: true,
|
|
1521
1521
|
roles: true,
|
|
@@ -1533,6 +1533,7 @@ const ROLES_KEYS = {
|
|
|
1533
1533
|
list: true,
|
|
1534
1534
|
rules: true
|
|
1535
1535
|
};
|
|
1536
|
+
const LEGACY_KEYS = new Set(["enabled"]);
|
|
1536
1537
|
const SLOT_ROW_KEYS = {
|
|
1537
1538
|
kind: true,
|
|
1538
1539
|
preset: true,
|
|
@@ -1568,7 +1569,7 @@ var FallbacksConfigGateway = class extends TypertRemoteService {
|
|
|
1568
1569
|
if (Object.keys(patch).length === 0) return this.readResult();
|
|
1569
1570
|
const settings = this.settings;
|
|
1570
1571
|
if (settings === void 0) throw new Error("fallbacks: settings service is unavailable — configuration cannot be written");
|
|
1571
|
-
const normalized = Object.fromEntries(Object.entries(patch).filter(([, value]) => value !== null));
|
|
1572
|
+
const normalized = Object.fromEntries(Object.entries(patch).filter(([key, value]) => !LEGACY_KEYS.has(key) && value !== null));
|
|
1572
1573
|
if (Object.keys(normalized).length === 0) return this.readResult();
|
|
1573
1574
|
await settings.update(FALLBACKS_PROFILE_ENTRY, normalized);
|
|
1574
1575
|
return this.readResult();
|
|
@@ -1665,7 +1666,7 @@ function normalizeRoles(value) {
|
|
|
1665
1666
|
function validateConfigPatch(patch) {
|
|
1666
1667
|
if (patch === null || typeof patch !== "object" || Array.isArray(patch)) throw new TypeError("dsh-llm-fallbacks: configuration patch must be a plain object");
|
|
1667
1668
|
for (const key of Object.keys(patch)) {
|
|
1668
|
-
if (!Object.hasOwn(CONFIG_KEYS, key)) throw new Error(`dsh-llm-fallbacks: unknown config key "${key}"`);
|
|
1669
|
+
if (!Object.hasOwn(CONFIG_KEYS, key) && !LEGACY_KEYS.has(key)) throw new Error(`dsh-llm-fallbacks: unknown config key "${key}"`);
|
|
1669
1670
|
if (key === "roles") {
|
|
1670
1671
|
const roles = patch[key];
|
|
1671
1672
|
if (roles !== null && typeof roles === "object" && !Array.isArray(roles)) {
|
|
@@ -2021,7 +2022,7 @@ function formatConfigRules(rules, t) {
|
|
|
2021
2022
|
function fallbacksConfigText(summary, locale = "zh") {
|
|
2022
2023
|
const t = FALLBACKS_COMMAND_LOCALES[locale];
|
|
2023
2024
|
return [
|
|
2024
|
-
`${t.configTitle}: ${summary.
|
|
2025
|
+
`${t.configTitle}: ${summary.active ? t.configEnabled : t.configDisabled}`,
|
|
2025
2026
|
`${t.configTriggerCodes}: ${summary.triggerCodes.length === 0 ? t.configEmpty : formatConfigList(summary.triggerCodes)}`,
|
|
2026
2027
|
`${t.configRootChain}: ${summary.rootChain.length === 0 ? t.configEmpty : formatConfigList(summary.rootChain)}`,
|
|
2027
2028
|
`${t.configTimeSlots}: ${summary.timeSlots.length === 0 ? t.configEmpty : formatConfigTimeSlots(summary.timeSlots, t)}`,
|
|
@@ -2513,16 +2514,6 @@ function buildFallbacksTuiSection() {
|
|
|
2513
2514
|
}
|
|
2514
2515
|
],
|
|
2515
2516
|
fields: [
|
|
2516
|
-
{
|
|
2517
|
-
path: ["enabled"],
|
|
2518
|
-
label: "Enabled",
|
|
2519
|
-
descriptions: {
|
|
2520
|
-
zh: "启用回退",
|
|
2521
|
-
en: "Enabled"
|
|
2522
|
-
},
|
|
2523
|
-
group: "general",
|
|
2524
|
-
kind: "boolean"
|
|
2525
|
-
},
|
|
2526
2517
|
{
|
|
2527
2518
|
path: ["roleAutoMatch"],
|
|
2528
2519
|
label: "LLM role auto-match",
|
|
@@ -2886,7 +2877,7 @@ function installFallbacksAdapter(ctx, readConfig) {
|
|
|
2886
2877
|
const logger = ctx.logger("llm-fallbacks");
|
|
2887
2878
|
const adapter = new FallbacksChainAdapter(readConfig, () => llm);
|
|
2888
2879
|
const reconcile = () => {
|
|
2889
|
-
const shouldRegister = readConfig()
|
|
2880
|
+
const shouldRegister = isFallbackActive(readConfig());
|
|
2890
2881
|
if (shouldRegister && !registered) {
|
|
2891
2882
|
if (llm === void 0) return;
|
|
2892
2883
|
try {
|
|
@@ -3296,7 +3287,7 @@ function apply(ctx, config = defaultFallbacksConfig) {
|
|
|
3296
3287
|
}
|
|
3297
3288
|
ctx.on("agent/request-error", async ({ agent, turn, step, provider, failure }, next) => {
|
|
3298
3289
|
const config = source();
|
|
3299
|
-
if (!config
|
|
3290
|
+
if (!isFallbackActive(config) || !config.triggerCodes.includes(failure.code)) return next();
|
|
3300
3291
|
const current = currentModel(agent, provider, config, new Date());
|
|
3301
3292
|
if (!current.model) return next();
|
|
3302
3293
|
try {
|
|
@@ -3322,7 +3313,7 @@ function apply(ctx, config = defaultFallbacksConfig) {
|
|
|
3322
3313
|
const applied = state === void 0 ? void 0 : states.applyPending(state, turn, step);
|
|
3323
3314
|
if (applied !== void 0) return overrideConfig(seed, applied.to);
|
|
3324
3315
|
const config = source();
|
|
3325
|
-
if (config
|
|
3316
|
+
if (isFallbackActive(config) && isAllDayConforming(config.rootChain) && (config.timeSlots?.length ?? 0) > 0 && agent.session?.header?.origin !== "subagent") {
|
|
3326
3317
|
const slot = resolveSlotState(config, new Date(), config.tz ?? "Asia/Shanghai");
|
|
3327
3318
|
const key = slotWinnerKey(slot.winner);
|
|
3328
3319
|
const previous = slotWinners.get(agent.id);
|
|
@@ -3332,7 +3323,7 @@ function apply(ctx, config = defaultFallbacksConfig) {
|
|
|
3332
3323
|
label: slot.label
|
|
3333
3324
|
});
|
|
3334
3325
|
}
|
|
3335
|
-
if (config
|
|
3326
|
+
if (isFallbackActive(config) && hasChains && agent.session?.header?.origin === "subagent" && !dispatchInjected.has(agent.id)) {
|
|
3336
3327
|
dispatchInjected.add(agent.id);
|
|
3337
3328
|
try {
|
|
3338
3329
|
const settingsRead = readGuardedPolicySettings(ctx, agent.id, lastKnownPolicySettings, logger.warn);
|
|
@@ -3390,7 +3381,7 @@ function apply(ctx, config = defaultFallbacksConfig) {
|
|
|
3390
3381
|
logger.warn("llm-fallbacks: dispatch role-injection failed, proceeding with the request unchanged: %s", error?.message ?? String(error));
|
|
3391
3382
|
}
|
|
3392
3383
|
}
|
|
3393
|
-
if (hasChains && config
|
|
3384
|
+
if (hasChains && isFallbackActive(config) && config.alwaysModeRetryCap > 0 && countRetryEvents(agent.session, turn, step, seed.provider) >= config.alwaysModeRetryCap) {
|
|
3394
3385
|
const decisionState = states.peek(agent.id);
|
|
3395
3386
|
const capRoute = anchorServedRoute(config, {
|
|
3396
3387
|
provider: seed.provider,
|
|
@@ -3469,7 +3460,7 @@ function apply(ctx, config = defaultFallbacksConfig) {
|
|
|
3469
3460
|
getConfig() {
|
|
3470
3461
|
const config = source();
|
|
3471
3462
|
return {
|
|
3472
|
-
|
|
3463
|
+
active: isFallbackActive(config),
|
|
3473
3464
|
triggerCodes: config.triggerCodes,
|
|
3474
3465
|
rootChain: config.rootChain,
|
|
3475
3466
|
timeSlots: (config.timeSlots ?? []).map((row) => row.kind === "preset" ? {
|
package/dist/tui-settings.d.ts
CHANGED
|
@@ -114,9 +114,12 @@ export declare const FALLBACKS_TUI_SECTION_NS = "fallbacks";
|
|
|
114
114
|
*/
|
|
115
115
|
export declare const JSON_FIELD_MAX_DRAFT_BYTES: number;
|
|
116
116
|
/**
|
|
117
|
-
* The `fallbacks` /settings section:
|
|
117
|
+
* The `fallbacks` /settings section: 12 fields covering all 14 web-card
|
|
118
118
|
* capabilities (the default-model choice rides `rootChain`'s last entry and
|
|
119
|
-
* the per-role fallback strategy rides `roles.list` JSON
|
|
119
|
+
* the per-role fallback strategy rides `roles.list` JSON; the config-level
|
|
120
|
+
* `enabled` switch is REMOVED — plan fallbacks-web-ux-alignment T2, the
|
|
121
|
+
* Plugins-page row toggle is the master switch and the runtime gates read
|
|
122
|
+
* content presence). Scalar
|
|
120
123
|
* capabilities use native kinds (boolean/number/select); complex structures
|
|
121
124
|
* use `text` fields with custom `format`/`parse` that mirror the gateway's
|
|
122
125
|
* validation. Built fresh per call — the host deep-freezes whatever it
|
|
@@ -9,15 +9,20 @@
|
|
|
9
9
|
* `ctx.inject(['llm'])` child — absent `llm` service (test harness) is a
|
|
10
10
|
* clean no-op, and fiber unload ⇒ the child's disposer unregisters the
|
|
11
11
|
* route. Registration is an idempotent transition-reconcile on COMMITTED
|
|
12
|
-
* config snapshots: register
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
12
|
+
* config snapshots: register when nothing is configured → something is
|
|
13
|
+
* (`isFallbackActive` — content presence, plan fallbacks-web-ux-alignment
|
|
14
|
+
* T2), unregister on the reverse, driven by the settings `onChange` hook
|
|
15
|
+
* (the returned reconcile thunk, wired by `apply()`) plus child activation.
|
|
16
|
+
* The row is visible whenever something is configured — a non-conforming
|
|
17
|
+
* all-day chain does NOT hide it (PR #62 feedback); conformance still gates
|
|
18
|
+
* a successful delegate (`effectiveHeadOf` below refuses a non-conforming
|
|
19
|
+
* all-day). The registration gate is `isFallbackActive` content presence
|
|
20
|
+
* (`rootChain` / `timeSlots` / declared roles): a slot-row edit that flips
|
|
21
|
+
* that gate (e.g. removing the only slot while `rootChain` and roles are
|
|
22
|
+
* empty) intentionally churns registration — the content-presence contract
|
|
23
|
+
* (plan fallbacks-web-ux-alignment T2), not churn to design away; do NOT
|
|
24
|
+
* re-narrow the condition to ignore `timeSlots`. Conformance-only chain
|
|
25
|
+
* edits still never churn (conformance gates the delegate, not the row).
|
|
21
26
|
*
|
|
22
27
|
* Adapter behavior (P1/P3): `listModels` advertises exactly the one virtual
|
|
23
28
|
* row; `stream()` is a THIN single-hop delegate to the effective chain head
|
|
@@ -34,7 +39,7 @@
|
|
|
34
39
|
*/
|
|
35
40
|
import type { Context } from '@deepseek-ai/cordis';
|
|
36
41
|
import { LlmAdapter, type GenerateOptions, type LlmImageRequestPricing, type LlmModelInfo, type LlmResolvedModelInfo, type LlmRuntime, type ResolvedRetryPolicy, type StreamChunk } from '@deepseek-ai/dsh-llm';
|
|
37
|
-
import type
|
|
42
|
+
import { type FallbacksConfig } from './config.ts';
|
|
38
43
|
/** Provider route of the virtual adapter (exact string, spec lock). */
|
|
39
44
|
export declare const FALLBACKS_PROVIDER = "FallbacksChain";
|
|
40
45
|
/**
|
package/icon.svg
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
<svg width="36" height="36" viewBox="0 0 36 36" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<defs>
|
|
3
|
+
<linearGradient id="dsh-llm-fallbacks-icon-a" x1="14.9894" y1="9.0697" x2="14.9894" y2="21.3063" gradientUnits="userSpaceOnUse">
|
|
4
|
+
<stop stop-color="#69B9FF"/>
|
|
5
|
+
<stop offset="1" stop-color="#324DE2"/>
|
|
6
|
+
</linearGradient>
|
|
7
|
+
<linearGradient id="dsh-llm-fallbacks-icon-b" x1="21.1075" y1="15.1877" x2="21.1075" y2="27.4243" gradientUnits="userSpaceOnUse">
|
|
8
|
+
<stop stop-color="#45E7A4"/>
|
|
9
|
+
<stop offset="1" stop-color="#05909D"/>
|
|
10
|
+
</linearGradient>
|
|
11
|
+
</defs>
|
|
12
|
+
<rect x="8.87109" y="9.0697" width="12.2365" height="12.2365" rx="2" fill="url(#dsh-llm-fallbacks-icon-a)" fill-opacity="0.8"/>
|
|
13
|
+
<rect x="14.9893" y="15.1877" width="12.2365" height="12.2365" rx="2" fill="url(#dsh-llm-fallbacks-icon-b)" fill-opacity="0.8"/>
|
|
14
|
+
<path d="M13.3 13.3L19.4 19.4" stroke="#F9FAFB" stroke-opacity="0.95" stroke-width="1.7" stroke-linecap="round"/>
|
|
15
|
+
<path d="M19.4 15.9V19.4H15.9" stroke="#F9FAFB" stroke-opacity="0.95" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"/>
|
|
16
|
+
</svg>
|
package/locale/en.json
ADDED
package/locale/zh.json
ADDED
package/package.json
CHANGED
|
@@ -5,10 +5,11 @@
|
|
|
5
5
|
"dsh",
|
|
6
6
|
"dsh-plugin"
|
|
7
7
|
],
|
|
8
|
-
"version": "0.6.
|
|
8
|
+
"version": "0.6.3",
|
|
9
9
|
"type": "module",
|
|
10
10
|
"main": "./dist/index.js",
|
|
11
11
|
"types": "./dist/index.d.ts",
|
|
12
|
+
"icon": "./icon.svg",
|
|
12
13
|
"exports": {
|
|
13
14
|
".": {
|
|
14
15
|
"types": "./dist/index.d.ts",
|
|
@@ -18,12 +19,15 @@
|
|
|
18
19
|
"types": "./dist/client/index.d.ts",
|
|
19
20
|
"default": "./dist/client/index.js"
|
|
20
21
|
},
|
|
22
|
+
"./locale/*.json": "./locale/*.json",
|
|
21
23
|
"./bundle/cordis.patch.yml": "./bundle/cordis.patch.yml",
|
|
22
24
|
"./package.json": "./package.json"
|
|
23
25
|
},
|
|
24
26
|
"files": [
|
|
25
27
|
"dist",
|
|
26
28
|
"bundle",
|
|
29
|
+
"locale",
|
|
30
|
+
"icon.svg",
|
|
27
31
|
"scripts"
|
|
28
32
|
],
|
|
29
33
|
"dsh": {
|
|
@@ -71,7 +75,6 @@
|
|
|
71
75
|
"@deepseek-ai/dsh-client-ui-chat": "^0.1.7-rc.2",
|
|
72
76
|
"@deepseek-ai/dsh-client-ui-conversation": "^0.1.7-rc.2",
|
|
73
77
|
"@deepseek-ai/dsh-client-ui-plugin-manager": "^0.1.7-rc.2",
|
|
74
|
-
"@deepseek-ai/dsh-client-ui-primitives": "^0.1.7-rc.2",
|
|
75
78
|
"@deepseek-ai/dsh-client-ui-renderer": "^0.1.7-rc.2",
|
|
76
79
|
"@deepseek-ai/dsh-client-ui-settings": "^0.1.7-rc.2",
|
|
77
80
|
"@deepseek-ai/dsh-client-ui-slots": "^0.1.7-rc.2",
|