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.
@@ -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.wildcard': string;
45
- 'chains.selector.noModels': string;
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.label': string;
53
- 'roles.description': string;
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.wildcard': string;
174
- 'chains.selector.noModels': string;
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.label': string;
182
- 'roles.description': string;
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: plugin config schema + defaults.
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/label/description/prompt?/permissions?/chain?/fallback) and
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 this schema with `installSettingsSection` under the `fallbacks`
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
- label: string;
53
- description: string;
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). `label`/`description` are free text and are deliberately not
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, and
123
- * `roles.rules[].role` values that reference no declared `roles.list` id
124
- * and are not the built-in `'inherit'`. Returns descriptive key/role names;
125
- * the gateway attaches them as `get().legacyKeys` so the client can show a
126
- * migration banner (spec §9 — the source is read directly because
127
- * schemastery retains unknown keys, verified plan Task 1 Step 1).
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 { Config, detectLegacyKeys, validateFallbacksConfig, type FallbacksConfig } from './config.ts';
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
- for (const item of roles.list) if (isRecordLike(item) && typeof item.id === "string") declared.add(item.id);
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
- label: z.string().default(""),
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()),
@@ -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.2",
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": {
@@ -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
  /**