dsh-llm-fallbacks 0.1.2 → 0.1.4
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 +5 -5
- package/README.zh-CN.md +5 -5
- package/dist/client/fallbacks-store.d.ts +9 -3
- package/dist/client/index.js +399 -463
- package/dist/client/locales.d.ts +14 -8
- package/dist/config.d.ts +18 -24
- package/dist/index.d.ts +2 -1
- package/dist/index.js +8 -4
- package/dist/schema.d.ts +26 -0
- package/package.json +2 -1
- package/scripts/build-client.ts +0 -5
package/dist/client/locales.d.ts
CHANGED
|
@@ -34,6 +34,9 @@ export declare const zh: {
|
|
|
34
34
|
'alwaysModeRetryCap.label': string;
|
|
35
35
|
'alwaysModeRetryCap.hint': string;
|
|
36
36
|
'alwaysModeRetryCap.tooltip': string;
|
|
37
|
+
'advanced.label': string;
|
|
38
|
+
'advanced.expand': string;
|
|
39
|
+
'advanced.collapse': string;
|
|
37
40
|
'rootChain.label': string;
|
|
38
41
|
'rootChain.hint': string;
|
|
39
42
|
'rootChain.tooltip': string;
|
|
@@ -41,16 +44,16 @@ export declare const zh: {
|
|
|
41
44
|
'chains.selector.remove': string;
|
|
42
45
|
'chains.selector.providerPlaceholder': string;
|
|
43
46
|
'chains.selector.modelPlaceholder': string;
|
|
44
|
-
'chains.selector.
|
|
45
|
-
'chains.selector.
|
|
47
|
+
'chains.selector.wildcardLegacy': string;
|
|
48
|
+
'chains.selector.noModelsStrict': string;
|
|
46
49
|
'roles.list.label': string;
|
|
47
50
|
'roles.list.hint': string;
|
|
48
51
|
'roles.list.tooltip': string;
|
|
49
52
|
'roles.id': string;
|
|
50
53
|
'roles.id.hint': string;
|
|
51
54
|
'roles.idPlaceholder': string;
|
|
52
|
-
'roles.
|
|
53
|
-
'roles.
|
|
55
|
+
'roles.persona': string;
|
|
56
|
+
'roles.personaPlaceholder': string;
|
|
54
57
|
'roles.fallback': string;
|
|
55
58
|
'roles.fallback.inherit-root': string;
|
|
56
59
|
'roles.fallback.none': string;
|
|
@@ -163,6 +166,9 @@ export declare const en: {
|
|
|
163
166
|
'alwaysModeRetryCap.label': string;
|
|
164
167
|
'alwaysModeRetryCap.hint': string;
|
|
165
168
|
'alwaysModeRetryCap.tooltip': string;
|
|
169
|
+
'advanced.label': string;
|
|
170
|
+
'advanced.expand': string;
|
|
171
|
+
'advanced.collapse': string;
|
|
166
172
|
'rootChain.label': string;
|
|
167
173
|
'rootChain.hint': string;
|
|
168
174
|
'rootChain.tooltip': string;
|
|
@@ -170,16 +176,16 @@ export declare const en: {
|
|
|
170
176
|
'chains.selector.remove': string;
|
|
171
177
|
'chains.selector.providerPlaceholder': string;
|
|
172
178
|
'chains.selector.modelPlaceholder': string;
|
|
173
|
-
'chains.selector.
|
|
174
|
-
'chains.selector.
|
|
179
|
+
'chains.selector.wildcardLegacy': string;
|
|
180
|
+
'chains.selector.noModelsStrict': string;
|
|
175
181
|
'roles.list.label': string;
|
|
176
182
|
'roles.list.hint': string;
|
|
177
183
|
'roles.list.tooltip': string;
|
|
178
184
|
'roles.id': string;
|
|
179
185
|
'roles.id.hint': string;
|
|
180
186
|
'roles.idPlaceholder': string;
|
|
181
|
-
'roles.
|
|
182
|
-
'roles.
|
|
187
|
+
'roles.persona': string;
|
|
188
|
+
'roles.personaPlaceholder': string;
|
|
183
189
|
'roles.fallback': string;
|
|
184
190
|
'roles.fallback.inherit-root': string;
|
|
185
191
|
'roles.fallback.none': string;
|
package/dist/config.d.ts
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The `fallbacks` settings namespace:
|
|
2
|
+
* The `fallbacks` settings namespace: config types + defaults (the
|
|
3
|
+
* schemastery `Config` schema lives in `./schema.ts`, host-only — this
|
|
4
|
+
* module must stay free of `@deepseek-ai/*` value imports so the client
|
|
5
|
+
* bundle never reaches schemastery).
|
|
3
6
|
*
|
|
4
7
|
* Two-block config model (plan fallbacks-role-config-model): block 1
|
|
5
8
|
* `rootChain` — the root agent's single fallback chain (empty = no
|
|
6
9
|
* degradation) — plus block 2 declared role entities: `roles.list`
|
|
7
|
-
* (id/
|
|
10
|
+
* (id/persona/prompt?/permissions?/chain?/fallback) and
|
|
8
11
|
* `roles.rules` enum references into the declared ids (or the built-in
|
|
9
12
|
* `'inherit'` role). The legacy `chains` / `roles.default` keys are gone
|
|
10
13
|
* from the schema and type (zero residual, migration table excepted); the
|
|
@@ -19,12 +22,11 @@
|
|
|
19
22
|
*
|
|
20
23
|
* This module is pure logic: it must not import any `@deepseek-ai/*` package
|
|
21
24
|
* (types included) — `FallbacksConfig` is the plugin's own type. Task 3
|
|
22
|
-
* registers
|
|
23
|
-
* settings namespace.
|
|
25
|
+
* registers the schemastery schema (see `./schema.ts`) with
|
|
26
|
+
* `installSettingsSection` under the `fallbacks` settings namespace.
|
|
24
27
|
*
|
|
25
28
|
* @module dsh-llm-fallbacks/config
|
|
26
29
|
*/
|
|
27
|
-
import z from '@deepseek-ai/schemastery';
|
|
28
30
|
/** How a cooled-down model comes back (spec §4). */
|
|
29
31
|
export type RevertPolicy = 'cooldown-expiry' | 'never';
|
|
30
32
|
/** A single role rule: match on origin/provider/model patterns (spec §3). */
|
|
@@ -49,8 +51,8 @@ export type FallbackStrategy = 'inherit-root' | 'none';
|
|
|
49
51
|
*/
|
|
50
52
|
export interface FallbacksRole {
|
|
51
53
|
id: string;
|
|
52
|
-
|
|
53
|
-
|
|
54
|
+
/** Personality hint (人格提示) — free text, never validated. */
|
|
55
|
+
persona: string;
|
|
54
56
|
/** Reserved for next iteration — no consumer this round. */
|
|
55
57
|
prompt?: string;
|
|
56
58
|
/** Reserved for next iteration — no consumer this round. */
|
|
@@ -110,7 +112,7 @@ export interface FallbacksConfigLogger {
|
|
|
110
112
|
* `rootChain`/role-chain selector legality, and the role model-config
|
|
111
113
|
* requirement (a declared role with a missing/empty chain warns — a role
|
|
112
114
|
* without a model config is meaningless, plan fallbacks-feedback-round
|
|
113
|
-
* T2). `
|
|
115
|
+
* T2). `persona` is free text and is deliberately not
|
|
114
116
|
* validated. Each violation emits one `llm-fallbacks: ...` warn and "does
|
|
115
117
|
* not take effect" — the config stays usable (spec §4 / AC-4
|
|
116
118
|
* warn-not-crash semantics).
|
|
@@ -119,21 +121,13 @@ export declare function validateFallbacksConfig(config: FallbacksConfig, logger:
|
|
|
119
121
|
/**
|
|
120
122
|
* Detect legacy (two-block-era) leftovers in a config SOURCE — the composed
|
|
121
123
|
* object `source()` returns, or a raw settings document. Recognizes the
|
|
122
|
-
* removed `chains` key, the removed `roles.default` field,
|
|
123
|
-
* `roles.
|
|
124
|
-
*
|
|
125
|
-
*
|
|
126
|
-
*
|
|
127
|
-
*
|
|
124
|
+
* removed `chains` key, the removed `roles.default` field, the removed
|
|
125
|
+
* role-entity fields `roles.list[].label` / `roles.list[].description`
|
|
126
|
+
* (renamed to `persona`), and `roles.rules[].role` values that reference no
|
|
127
|
+
* declared `roles.list` id and are not the built-in `'inherit'`. Returns
|
|
128
|
+
* descriptive key/role names; the gateway attaches them as `get().legacyKeys`
|
|
129
|
+
* so the client can show a migration banner (spec §9 — the source is read
|
|
130
|
+
* directly because schemastery retains unknown keys, verified plan Task 1
|
|
131
|
+
* Step 1).
|
|
128
132
|
*/
|
|
129
133
|
export declare function detectLegacyKeys(source: Record<string, unknown>): string[];
|
|
130
|
-
/**
|
|
131
|
-
* Plugin Config schema (schemastery), mirroring {@link FallbacksConfig}.
|
|
132
|
-
* Object fields are optional by default in schemastery; `.default()` fills
|
|
133
|
-
* the spec defaults, `.required()` keeps mandatory fields. Unknown keys are
|
|
134
|
-
* RETAINED by the composition (verified plan Task 1 Step 1) — that is what
|
|
135
|
-
* lets `detectLegacyKeys` flag two-block-era leftovers (`chains` /
|
|
136
|
-
* `roles.default`) on the composed object at startup (warn + gateway
|
|
137
|
-
* `legacyKeys`, see `src/index.ts` apply()).
|
|
138
|
-
*/
|
|
139
|
-
export declare const Config: z<FallbacksConfig>;
|
package/dist/index.d.ts
CHANGED
|
@@ -29,7 +29,8 @@
|
|
|
29
29
|
*/
|
|
30
30
|
import type { Context } from '@deepseek-ai/cordis';
|
|
31
31
|
import type { Session } from '@deepseek-ai/dsh-session';
|
|
32
|
-
import {
|
|
32
|
+
import { detectLegacyKeys, validateFallbacksConfig, type FallbacksConfig } from './config.ts';
|
|
33
|
+
import { Config } from './schema.ts';
|
|
33
34
|
import { resolveChain } from './chains.ts';
|
|
34
35
|
import { resolveRole } from './roles.ts';
|
|
35
36
|
import { FallbackStateStore } from './state.ts';
|
package/dist/index.js
CHANGED
|
@@ -86,8 +86,11 @@ function detectLegacyKeys(source) {
|
|
|
86
86
|
if (isRecordLike(roles)) {
|
|
87
87
|
if (Object.hasOwn(roles, "default")) keys.push("roles.default");
|
|
88
88
|
const declared = new Set();
|
|
89
|
-
if (Array.isArray(roles.list)) {
|
|
90
|
-
|
|
89
|
+
if (Array.isArray(roles.list)) for (const item of roles.list) {
|
|
90
|
+
if (!isRecordLike(item)) continue;
|
|
91
|
+
if (typeof item.id === "string") declared.add(item.id);
|
|
92
|
+
if (Object.hasOwn(item, "label")) keys.push("roles.list[].label");
|
|
93
|
+
if (Object.hasOwn(item, "description")) keys.push("roles.list[].description");
|
|
91
94
|
}
|
|
92
95
|
if (Array.isArray(roles.rules)) {
|
|
93
96
|
for (const rule of roles.rules) if (isRecordLike(rule) && typeof rule.role === "string" && rule.role !== "inherit" && !declared.has(rule.role)) keys.push(`roles.rules[].role: ${rule.role}`);
|
|
@@ -98,6 +101,8 @@ function detectLegacyKeys(source) {
|
|
|
98
101
|
function isRecordLike(value) {
|
|
99
102
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
100
103
|
}
|
|
104
|
+
//#endregion
|
|
105
|
+
//#region .build/host/schema.js
|
|
101
106
|
const Config = z.object({
|
|
102
107
|
enabled: z.boolean().default(false),
|
|
103
108
|
triggerCodes: z.array(z.string()).default([
|
|
@@ -109,8 +114,7 @@ const Config = z.object({
|
|
|
109
114
|
roles: z.object({
|
|
110
115
|
list: z.array(z.object({
|
|
111
116
|
id: z.string().required(),
|
|
112
|
-
|
|
113
|
-
description: z.string().default(""),
|
|
117
|
+
persona: z.string().default(""),
|
|
114
118
|
prompt: z.string(),
|
|
115
119
|
permissions: z.object({
|
|
116
120
|
allow: z.array(z.string()),
|
package/dist/schema.d.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The `fallbacks` settings schema (schemastery), mirroring
|
|
3
|
+
* {@link FallbacksConfig}.
|
|
4
|
+
*
|
|
5
|
+
* Host-only module: `Config` is the schemastery schema the settings section
|
|
6
|
+
* validates/composes against, and `@deepseek-ai/schemastery` is an
|
|
7
|
+
* `@deepseek-ai/*` RUNTIME value import — it must never enter the client
|
|
8
|
+
* bundle, because the web loader module table cannot answer that require
|
|
9
|
+
* (build-time externals drift, 20260815: the client bundle previously
|
|
10
|
+
* externalized `@deepseek-ai/schemastery` and the web settings card failed
|
|
11
|
+
* to load). The client half consumes `FallbacksConfig` and the other
|
|
12
|
+
* config types from `./config.ts` type-only, so the schema stays here, out
|
|
13
|
+
* of the client module graph.
|
|
14
|
+
*
|
|
15
|
+
* Object fields are optional by default in schemastery; `.default()` fills
|
|
16
|
+
* the spec defaults, `.required()` keeps mandatory fields. Unknown keys are
|
|
17
|
+
* RETAINED by the composition (verified plan Task 1 Step 1) — that is what
|
|
18
|
+
* lets `detectLegacyKeys` flag two-block-era leftovers (`chains` /
|
|
19
|
+
* `roles.default`) on the composed object at startup (warn + gateway
|
|
20
|
+
* `legacyKeys`, see `src/index.ts` apply()).
|
|
21
|
+
*
|
|
22
|
+
* @module dsh-llm-fallbacks/schema
|
|
23
|
+
*/
|
|
24
|
+
import z from '@deepseek-ai/schemastery';
|
|
25
|
+
import type { FallbacksConfig } from './config.ts';
|
|
26
|
+
export declare const Config: z<FallbacksConfig>;
|
package/package.json
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"dsh",
|
|
6
6
|
"dsh-plugin"
|
|
7
7
|
],
|
|
8
|
-
"version": "0.1.
|
|
8
|
+
"version": "0.1.4",
|
|
9
9
|
"type": "module",
|
|
10
10
|
"main": "./dist/index.js",
|
|
11
11
|
"types": "./dist/index.d.ts",
|
|
@@ -49,6 +49,7 @@
|
|
|
49
49
|
"release:prepare": "tsx scripts/prepare-release.ts",
|
|
50
50
|
"release:validate": "tsx scripts/validate-release-version.ts",
|
|
51
51
|
"test": "vitest run",
|
|
52
|
+
"typecheck": "tsc -p tsconfig.build.json --noEmit && tsc --noEmit",
|
|
52
53
|
"prepare": "pnpm run build"
|
|
53
54
|
},
|
|
54
55
|
"engines": {
|
package/scripts/build-client.ts
CHANGED
|
@@ -66,11 +66,6 @@ export const CLIENT_EXTERNALS: readonly string[] = [
|
|
|
66
66
|
'@deepseek-ai/dsh-client-ui-attachment',
|
|
67
67
|
'@deepseek-ai/dsh-client-schema-form',
|
|
68
68
|
'@deepseek-ai/dsh-client-runtime/client',
|
|
69
|
-
// @deepseek-ai/schemastery: config.ts's schema value import reaches the
|
|
70
|
-
// client module graph (client consumes FallbacksConfig types via config.ts);
|
|
71
|
-
// the dsh host provides the package in-box (dsh-settings depends on it), so
|
|
72
|
-
// it stays external like the other @deepseek-ai/* runtime faces.
|
|
73
|
-
'@deepseek-ai/schemastery',
|
|
74
69
|
]
|
|
75
70
|
|
|
76
71
|
/**
|