@jianxx/dsh-cc-model-aliases 0.3.0 → 0.4.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/lib/resolver.js CHANGED
@@ -10,21 +10,50 @@
10
10
  * live settings edits take effect on the next spawn without re-registering
11
11
  * anything.
12
12
  *
13
- * Only the four builtin alias names have a fallback when they are unconfigured
14
- * — they resolve to "inherit the parent route" (`undefined`), matching the
15
- * deployment decision that a zero-config `model: sonnet` agent silently uses
16
- * the parent's current model. A custom (open-set) alias that is unconfigured
17
- * has no fallback: it passes through verbatim as a literal model id, with a
18
- * warning when it looks like an intended alias.
13
+ * Builtin alias names (Claude Code family plus the dsh-cc lane names) have a
14
+ * fallback when they are unconfigured — they resolve to "inherit the parent
15
+ * route" (`undefined`), matching the deployment decision that a zero-config
16
+ * `model: sonnet` / `model: draft` agent silently uses the parent's current
17
+ * model. A custom (open-set) alias that is unconfigured has no fallback: it
18
+ * passes through verbatim as a literal model id, with a warning when it looks
19
+ * like an intended alias.
19
20
  *
20
21
  * @module @jianxx/dsh-cc-model-aliases/resolver
21
22
  */
23
+ /**
24
+ * Claude Code family aliases. Unconfigured → inherit the parent route.
25
+ * Case-insensitive; a configured value still wins over this fallback.
26
+ */
27
+ export const CC_ALIASES = ['fable', 'opus', 'sonnet', 'haiku'];
28
+ /**
29
+ * dsh-cc lane aliases. Unconfigured, a lane follows its CC peer
30
+ * ({@link LANE_PEERS}) so `model: sketch` shares a configured `haiku`
31
+ * route without a second settings entry. `architect` has no peer and
32
+ * inherits the parent (main-thread) route. A configured string-form
33
+ * target that names another alias is followed one hop.
34
+ *
35
+ * | lane | role | CC peer when unconfigured |
36
+ * |---|---|---|
37
+ * | `sketch` | fast, lightweight execution | haiku |
38
+ * | `draft` | balanced everyday coding | sonnet |
39
+ * | `blueprint` | deep reasoning | opus |
40
+ * | `masterplan` | maximum reasoning | fable |
41
+ * | `architect` | planning / orchestration | inherit (main thread) |
42
+ */
43
+ export const LANE_ALIASES = ['sketch', 'draft', 'blueprint', 'masterplan', 'architect'];
44
+ /** Unconfigured lane → CC family alias it shares a route with. */
45
+ export const LANE_PEERS = {
46
+ sketch: 'haiku',
47
+ draft: 'sonnet',
48
+ blueprint: 'opus',
49
+ masterplan: 'fable',
50
+ };
22
51
  /**
23
52
  * The builtin alias names that fall back to "inherit the parent route" when
24
53
  * unconfigured. Case-insensitive; a configured value still wins over this
25
54
  * fallback.
26
55
  */
27
- export const BUILTIN_ALIASES = ['fable', 'opus', 'sonnet', 'haiku'];
56
+ export const BUILTIN_ALIASES = [...CC_ALIASES, ...LANE_ALIASES];
28
57
  /** The set of builtin names, lowercased, for O(1) membership checks. */
29
58
  const BUILTIN_SET = new Set(BUILTIN_ALIASES);
30
59
  /**
@@ -55,45 +84,133 @@ export function mergeAliasMaps(config, settings) {
55
84
  }
56
85
  return merged;
57
86
  }
87
+ export function createModelResolver(getAliases, options) {
88
+ const inspect = createModelInspector(getAliases, options);
89
+ const resolveDetailed = (model) => {
90
+ const verdict = inspect(model);
91
+ if (verdict.kind === 'inherit') {
92
+ return { selector: model === undefined || model.trim().length === 0 ? undefined : model.trim(), via: 'inherit', route: undefined };
93
+ }
94
+ const selector = model?.trim();
95
+ if (verdict.kind === 'route') {
96
+ return { selector, via: 'alias', route: verdict.route };
97
+ }
98
+ // Upstream's inspector reports the literal passthrough for BOTH a custom
99
+ // alias name and a followed string-form target; our `DetailedRoute` keeps
100
+ // the finer split: when the literal route's model differs from the
101
+ // selector, the selector was a CONFIGURED alias followed to its target,
102
+ // so the provenance is `alias`, not `literal`.
103
+ const followed = verdict.route !== undefined && verdict.route.model !== undefined && verdict.route.model !== selector;
104
+ return { selector: followed ? selector : verdict.route?.model, via: followed ? 'alias' : 'literal', route: verdict.route };
105
+ };
106
+ // `resolve` is derived from `resolveDetailed` so the classification and the
107
+ // route always come from the SAME merged map — no double lookup, and the
108
+ // legacy route behavior stays byte-identical by construction.
109
+ const resolve = (model) => resolveDetailed(model).route;
110
+ return Object.assign(resolve, { resolveDetailed });
111
+ }
58
112
  /**
59
- * Build a `resolveModel` closure for an agent provider. The alias source is a
60
- * thunk evaluated on every invocation, so the closure reads the live settings
61
- * and merges fresh each spawn (see the plan's liveness requirement).
62
- * @param getAliases - returns the effective alias map for this invocation (the
63
- * caller composes config + live settings via {@link mergeAliasMaps}).
64
- * @param options - optional warning hook for unsigned custom aliases; the
65
- * message is emitted (defaulting to `console.warn`) when a model that is not
66
- * a configured alias and not a builtin looks like an intended alias (a bare
67
- * lowercase alphabetic word) and is passed through verbatim.
68
- * @returns the resolution function mapping a frontmatter `model` to a route, or
69
- * `undefined` for no override.
113
+ * Build an inspector that classifies one frontmatter `model` the same way
114
+ * {@link createModelResolver} resolves it, additionally reporting provenance
115
+ * (kind / via / hop) for tooling like `/doctor`. The `route` field is exactly
116
+ * what `resolve()` returns for the same input.
117
+ * @param getAliases - returns the effective alias map for this invocation.
118
+ * @param options - same warning hook as {@link createModelResolver}.
119
+ * @returns the inspection function mapping a frontmatter `model` to an
120
+ * {@link AliasInspection}.
70
121
  */
71
- export function createModelResolver(getAliases, options) {
122
+ export function createModelInspector(getAliases, options) {
72
123
  const warn = options?.warn ?? ((message) => console.warn(message));
73
124
  return (model) => {
74
125
  if (model === undefined || model.trim().length === 0)
75
- return undefined;
126
+ return { kind: 'inherit' };
76
127
  const trimmed = model.trim();
77
128
  const folded = trimmed.toLowerCase();
78
129
  if (folded === 'inherit')
79
- return undefined;
130
+ return { kind: 'inherit' };
80
131
  const aliases = getAliases();
81
132
  const hit = aliases.get(folded);
82
133
  if (hit !== undefined && hit !== null) {
83
- return typeof hit === 'string' ? { model: hit } : { provider: hit.provider, model: hit.model };
134
+ if (typeof hit === 'string') {
135
+ const followed = followStringTarget(hit, aliases, folded);
136
+ const foldedTarget = hit.trim().toLowerCase();
137
+ if (followed.kind === 'route')
138
+ return { kind: 'route', via: 'one-hop', hop: foldedTarget, route: followed.route };
139
+ if (followed.kind === 'inherit')
140
+ return { kind: 'inherit', via: 'one-hop', hop: foldedTarget };
141
+ return { kind: 'literal', route: { model: hit } };
142
+ }
143
+ // Object form: forward the route fields that are present. `provider` and
144
+ // `reasoningEffort` are optional (absent = inherit / no stamp); `model`
145
+ // is always set on a schema-valid object entry. Object targets are
146
+ // concrete routes — they are not followed as alias names.
147
+ return {
148
+ kind: 'route',
149
+ via: 'configured',
150
+ route: {
151
+ ...(hit.provider === undefined ? {} : { provider: hit.provider }),
152
+ ...(hit.model === undefined ? {} : { model: hit.model }),
153
+ ...(hit.reasoningEffort === undefined ? {} : { reasoningEffort: hit.reasoningEffort }),
154
+ },
155
+ };
156
+ }
157
+ // Unconfigured lane → follow its CC peer (`sketch` → `haiku`, …).
158
+ // `architect` has no peer and falls through to inherit. Choice: when the
159
+ // peer resolves to a configured route we report `via: 'alias'` (the lane
160
+ // shares the peer alias's route); when the peer is itself unconfigured the
161
+ // lane inherits, so `via: 'inherit'` — matching today's `resolve()`.
162
+ const peer = LANE_PEERS[folded];
163
+ if (peer !== undefined) {
164
+ const followed = followStringTarget(peer, aliases, folded);
165
+ if (followed.kind === 'route')
166
+ return { kind: 'route', via: 'peer', hop: peer, route: followed.route };
167
+ return { kind: 'inherit', via: 'peer', hop: peer };
84
168
  }
85
169
  // Unconfigured builtin alias → inherit the parent route ("current model").
86
170
  if (BUILTIN_SET.has(folded))
87
- return undefined;
171
+ return { kind: 'inherit', via: 'builtin' };
88
172
  // Custom alias that is unconfigured: warn when it looks like an intended
89
173
  // alias, then pass through verbatim as a literal model id (no regression
90
174
  // for literal ids such as `deepseek-chat`).
91
175
  if (/^[a-z]+$/.test(folded)) {
92
176
  warn(`cc-model-aliases: model "${trimmed}" is not a configured alias and is not builtin; passing through verbatim as a literal model id`);
93
177
  }
94
- return { model: trimmed };
178
+ return { kind: 'literal', route: { model: trimmed } };
95
179
  };
96
180
  }
181
+ /**
182
+ * Follow a string-form target one hop when it names another alias.
183
+ *
184
+ * - `sketch: haiku` with haiku configured → haiku's route
185
+ * - `sketch: haiku` with haiku unconfigured (builtin) → inherit
186
+ * - `sketch: inherit` → inherit
187
+ * - `sketch: deepseek-chat` (not an alias) → literal, caller keeps the string
188
+ *
189
+ * A second hop is not followed (`sketch: draft` + `draft: haiku` stops at
190
+ * the literal `"haiku"`), which keeps cycles from looping. Object-form
191
+ * targets are never followed as names.
192
+ */
193
+ function followStringTarget(target, aliases, from) {
194
+ const folded = target.trim().toLowerCase();
195
+ if (folded.length === 0 || folded === from || folded === 'inherit')
196
+ return { kind: 'inherit' };
197
+ const next = aliases.get(folded);
198
+ if (next !== undefined && next !== null) {
199
+ if (typeof next === 'string')
200
+ return { kind: 'route', route: { model: next } };
201
+ return {
202
+ kind: 'route',
203
+ route: {
204
+ ...(next.provider === undefined ? {} : { provider: next.provider }),
205
+ ...(next.model === undefined ? {} : { model: next.model }),
206
+ ...(next.reasoningEffort === undefined ? {} : { reasoningEffort: next.reasoningEffort }),
207
+ },
208
+ };
209
+ }
210
+ if (BUILTIN_SET.has(folded))
211
+ return { kind: 'inherit' };
212
+ return { kind: 'literal' };
213
+ }
97
214
  /** Compact-fill a record's own string keys, folding each to lowercase. */
98
215
  function foldKeys(record) {
99
216
  const out = new Map();
@@ -1 +1 @@
1
- {"version":3,"file":"resolver.js","sourceRoot":"","sources":["../src/resolver.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"resolver.js","sourceRoot":"","sources":["../src/resolver.ts"],"names":[],"mappings":"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"}
package/lib/schema.d.ts CHANGED
@@ -6,9 +6,10 @@
6
6
  * delete an alias — values are a model id or an explicit `{provider, model}`
7
7
  * route. The settings overlay (`model-aliases` namespace) may additionally be
8
8
  * `null` for a key, which deletes a same-named config-default entry during
9
- * merge. Object-form targets require a non-empty `provider` and `model` so a
10
- * half-written route is rejected at schema-validation time rather than
11
- * surfacing as an empty-field override at spawn.
9
+ * merge. Object-form targets require a non-empty `model`; `provider` is
10
+ * optional (inherit the parent provider) but must be non-empty when present.
11
+ * A half-written route is rejected at the service write-time validate rather
12
+ * than surfacing as an empty-field override at spawn.
12
13
  *
13
14
  * The settings overlay is a shallow record keyed by alias name; the 5-cascade
14
15
  * layer merge inside settings is recursively deep (existing cascade
@@ -28,9 +29,11 @@ import type { AliasTarget } from './types.ts';
28
29
  export declare const ConfigAliasSchema: z<string | ({
29
30
  provider?: string | null;
30
31
  model?: string | null;
32
+ reasoningEffort?: string | null;
31
33
  } & import("@deepseek-ai/cosmokit").Dict), string | Schemastery.ObjectT<{
32
34
  provider: z<string, string>;
33
35
  model: z<string, string>;
36
+ reasoningEffort: z<string, string>;
34
37
  }>>;
35
38
  /**
36
39
  * Schema for a settings `model-aliases` value: a model id, an explicit route,
@@ -39,9 +42,11 @@ export declare const ConfigAliasSchema: z<string | ({
39
42
  export declare const SettingsAliasSchema: z<string | ({
40
43
  provider?: string | null;
41
44
  model?: string | null;
45
+ reasoningEffort?: string | null;
42
46
  } & import("@deepseek-ai/cosmokit").Dict) | null, string | Schemastery.ObjectT<{
43
47
  provider: z<string, string>;
44
48
  model: z<string, string>;
49
+ reasoningEffort: z<string, string>;
45
50
  }> | null>;
46
51
  /**
47
52
  * Schema for the whole config `modelAliases` record.
@@ -49,9 +54,11 @@ export declare const SettingsAliasSchema: z<string | ({
49
54
  export declare const ConfigAliasesSchema: z<import("@deepseek-ai/cosmokit").Dict<string | ({
50
55
  provider?: string | null;
51
56
  model?: string | null;
57
+ reasoningEffort?: string | null;
52
58
  } & import("@deepseek-ai/cosmokit").Dict), string>, import("@deepseek-ai/cosmokit").Dict<string | Schemastery.ObjectT<{
53
59
  provider: z<string, string>;
54
60
  model: z<string, string>;
61
+ reasoningEffort: z<string, string>;
55
62
  }>, string>>;
56
63
  /**
57
64
  * Schema for the whole settings `model-aliases` section.
@@ -59,9 +66,11 @@ export declare const ConfigAliasesSchema: z<import("@deepseek-ai/cosmokit").Dict
59
66
  export declare const SettingsAliasesSchema: z<import("@deepseek-ai/cosmokit").Dict<string | ({
60
67
  provider?: string | null;
61
68
  model?: string | null;
69
+ reasoningEffort?: string | null;
62
70
  } & import("@deepseek-ai/cosmokit").Dict) | null, string>, import("@deepseek-ai/cosmokit").Dict<string | Schemastery.ObjectT<{
63
71
  provider: z<string, string>;
64
72
  model: z<string, string>;
73
+ reasoningEffort: z<string, string>;
65
74
  }> | null, string>>;
66
75
  /** The validated shape of one config entry (modelled on the schema). */
67
76
  export type ConfigAliasEntry = Exclude<AliasTarget, null>;
@@ -1 +1 @@
1
- {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,CAAC,MAAM,0BAA0B,CAAA;AACxC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAW7C;;;;GAIG;AACH,eAAO,MAAM,iBAAiB;;;;;;GAAwC,CAAA;AAEtE;;;GAGG;AACH,eAAO,MAAM,mBAAmB;;;;;;UAAuD,CAAA;AAEvF;;GAEG;AACH,eAAO,MAAM,mBAAmB;;;;;;YAA4B,CAAA;AAE5D;;GAEG;AACH,eAAO,MAAM,qBAAqB;;;;;;mBAA8B,CAAA;AAEhE,wEAAwE;AACxE,MAAM,MAAM,gBAAgB,GAAG,OAAO,CAAC,WAAW,EAAE,IAAI,CAAC,CAAA;AACzD,2EAA2E;AAC3E,MAAM,MAAM,kBAAkB,GAAG,WAAW,CAAA"}
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,CAAC,MAAM,0BAA0B,CAAA;AACxC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAiB7C;;;;GAIG;AACH,eAAO,MAAM,iBAAiB;;;;;;;;GAAwC,CAAA;AAEtE;;;GAGG;AACH,eAAO,MAAM,mBAAmB;;;;;;;;UAAuD,CAAA;AAEvF;;GAEG;AACH,eAAO,MAAM,mBAAmB;;;;;;;;YAA4B,CAAA;AAE5D;;GAEG;AACH,eAAO,MAAM,qBAAqB;;;;;;;;mBAA8B,CAAA;AAEhE,wEAAwE;AACxE,MAAM,MAAM,gBAAgB,GAAG,OAAO,CAAC,WAAW,EAAE,IAAI,CAAC,CAAA;AACzD,2EAA2E;AAC3E,MAAM,MAAM,kBAAkB,GAAG,WAAW,CAAA"}
package/lib/schema.js CHANGED
@@ -6,9 +6,10 @@
6
6
  * delete an alias — values are a model id or an explicit `{provider, model}`
7
7
  * route. The settings overlay (`model-aliases` namespace) may additionally be
8
8
  * `null` for a key, which deletes a same-named config-default entry during
9
- * merge. Object-form targets require a non-empty `provider` and `model` so a
10
- * half-written route is rejected at schema-validation time rather than
11
- * surfacing as an empty-field override at spawn.
9
+ * merge. Object-form targets require a non-empty `model`; `provider` is
10
+ * optional (inherit the parent provider) but must be non-empty when present.
11
+ * A half-written route is rejected at the service write-time validate rather
12
+ * than surfacing as an empty-field override at spawn.
12
13
  *
13
14
  * The settings overlay is a shallow record keyed by alias name; the 5-cascade
14
15
  * layer merge inside settings is recursively deep (existing cascade
@@ -21,10 +22,16 @@
21
22
  import z from '@deepseek-ai/schemastery';
22
23
  /** A target that only names a model id (provider inherits the parent route). */
23
24
  const MODEL_ONLY = z.string().min(1);
24
- /** A target that pins an explicit `{provider, model}` route. */
25
+ /**
26
+ * A target that pins an explicit route: `model` is required; `provider` is
27
+ * optional (inherit the parent provider) but must be non-empty when present;
28
+ * `reasoningEffort` is an optional opaque non-empty string whose legal
29
+ * spellings belong to the target model's adapter.
30
+ */
25
31
  const EXPLICIT_ROUTE = z.object({
26
32
  provider: z.string().min(1),
27
33
  model: z.string().min(1),
34
+ reasoningEffort: z.string().min(1),
28
35
  });
29
36
  /**
30
37
  * Schema for a deployment `config` alias value: a model id or an explicit
package/lib/schema.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"schema.js","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,CAAC,MAAM,0BAA0B,CAAA;AAGxC,gFAAgF;AAChF,MAAM,UAAU,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAA;AAEpC,gEAAgE;AAChE,MAAM,cAAc,GAAG,CAAC,CAAC,MAAM,CAAC;IAC9B,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC3B,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;CACzB,CAAC,CAAA;AAEF;;;;GAIG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,UAAU,EAAE,cAAc,CAAC,CAAC,CAAA;AAEtE;;;GAGG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,UAAU,EAAE,cAAc,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;AAEvF;;GAEG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAA;AAE5D;;GAEG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAA"}
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,CAAC,MAAM,0BAA0B,CAAA;AAGxC,gFAAgF;AAChF,MAAM,UAAU,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAA;AAEpC;;;;;GAKG;AACH,MAAM,cAAc,GAAG,CAAC,CAAC,MAAM,CAAC;IAC9B,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC3B,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACxB,eAAe,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;CACnC,CAAC,CAAA;AAEF;;;;GAIG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,UAAU,EAAE,cAAc,CAAC,CAAC,CAAA;AAEtE;;;GAGG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,UAAU,EAAE,cAAc,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;AAEvF;;GAEG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAA;AAE5D;;GAEG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAA"}
package/lib/service.d.ts CHANGED
@@ -16,7 +16,7 @@
16
16
  */
17
17
  import z from '@deepseek-ai/schemastery';
18
18
  import type { Context } from '@deepseek-ai/cordis';
19
- import type { AliasTarget, ResolvedRoute } from './types.ts';
19
+ import type { AliasInspection, AliasTarget, DetailedRoute, ResolvedRoute } from './types.ts';
20
20
  /** Plugin configuration: deployment-default alias map. */
21
21
  export interface Config {
22
22
  /** Deployment defaults (alias name → model id or `{provider, model}` route). */
@@ -24,10 +24,20 @@ export interface Config {
24
24
  }
25
25
  /** Runtime config schema (config-layer aliases never hold null). */
26
26
  export declare const Config: z<Config>;
27
+ /** The settings namespace carrying the live `model-aliases` overlay. */
28
+ export declare const MODEL_ALIASES_NAMESPACE: import("@deepseek-ai/dsh-settings").SettingsNamespace;
27
29
  /** The shape consumers resolve through. */
28
30
  export interface ModelRoutes {
29
31
  /** Resolve one frontmatter `model` to a dsh route, or undefined to inherit. */
30
32
  resolve(model: string | undefined): ResolvedRoute | undefined;
33
+ /**
34
+ * Atomic detailed resolution: `{selector, via, route}` from ONE settings
35
+ * snapshot — `via` records how the selector was classified (alias / literal
36
+ * / inherit) so callers can capture provenance without a second, racy lookup.
37
+ */
38
+ resolveDetailed(model: string | undefined): DetailedRoute;
39
+ /** Inspect one frontmatter `model` with provenance (for `/doctor` reporting). */
40
+ inspect(model: string | undefined): AliasInspection;
31
41
  }
32
42
  /** Cordis plugin id. */
33
43
  export declare const name = "cc-model-routes";
@@ -38,4 +48,24 @@ export declare const name = "cc-model-routes";
38
48
  * @param config - deployment defaults.
39
49
  */
40
50
  export declare function apply(ctx: Context, config?: Config): void;
51
+ /**
52
+ * Host-plane alias read WITHOUT owning the namespace: resolve through the
53
+ * `ccModelRoutes` service when one is mounted, otherwise read the live
54
+ * `model-aliases` settings overlay directly. Never re-registers the namespace
55
+ * — the isolated `cc-model-routes` plugin row already owns that registration,
56
+ * and `settings.register` throws on a duplicate namespace.
57
+ * @param ctx - the host context (no plugin instance required).
58
+ * @param alias - frontmatter model alias, or undefined to inherit.
59
+ * @returns the resolved route, or undefined to inherit the parent route.
60
+ */
61
+ export declare function resolveAlias(ctx: Context, alias: string | undefined): ResolvedRoute | undefined;
62
+ /**
63
+ * Host-plane DETAILED alias read: the provenance-carrying counterpart of
64
+ * {@link resolveAlias}, with the same service-then-overlay fallback and the
65
+ * same single-snapshot guarantee (classification and route from one map).
66
+ * @param ctx - the host context (no plugin instance required).
67
+ * @param alias - frontmatter model alias, or undefined to inherit.
68
+ * @returns the atomic detailed resolution for the alias.
69
+ */
70
+ export declare function resolveDetailedAlias(ctx: Context, alias: string | undefined): DetailedRoute;
41
71
  //# sourceMappingURL=service.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,CAAC,MAAM,0BAA0B,CAAA;AACxC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAKlD,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAE5D,0DAA0D;AAC1D,MAAM,WAAW,MAAM;IACrB,gFAAgF;IAChF,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC,CAAA;CAC1D;AAED,oEAAoE;AACpE,eAAO,MAAM,MAAM,EAAE,CAAC,CAAC,MAAM,CAAmD,CAAA;AAKhF,2CAA2C;AAC3C,MAAM,WAAW,WAAW;IAC1B,+EAA+E;IAC/E,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,aAAa,GAAG,SAAS,CAAA;CAC9D;AAED,wBAAwB;AACxB,eAAO,MAAM,IAAI,oBAAoB,CAAA;AAErC;;;;;GAKG;AACH,wBAAgB,KAAK,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,GAAE,MAAW,GAAG,IAAI,CAuB7D"}
1
+ {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,CAAC,MAAM,0BAA0B,CAAA;AACxC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AASlD,OAAO,KAAK,EAAE,eAAe,EAAE,WAAW,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAE5F,0DAA0D;AAC1D,MAAM,WAAW,MAAM;IACrB,gFAAgF;IAChF,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC,CAAA;CAC1D;AAED,oEAAoE;AACpE,eAAO,MAAM,MAAM,EAAE,CAAC,CAAC,MAAM,CAAmD,CAAA;AAEhF,wEAAwE;AACxE,eAAO,MAAM,uBAAuB,uDAAqC,CAAA;AAEzE,2CAA2C;AAC3C,MAAM,WAAW,WAAW;IAC1B,+EAA+E;IAC/E,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,aAAa,GAAG,SAAS,CAAA;IAC7D;;;;OAIG;IACH,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,aAAa,CAAA;IACzD,iFAAiF;IACjF,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,eAAe,CAAA;CACpD;AAED,wBAAwB;AACxB,eAAO,MAAM,IAAI,oBAAoB,CAAA;AAErC;;;;;GAKG;AACH,wBAAgB,KAAK,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,GAAE,MAAW,GAAG,IAAI,CA2C7D;AAED;;;;;;;;;GASG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,aAAa,GAAG,SAAS,CAS/F;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,aAAa,CAS3F"}
package/lib/service.js CHANGED
@@ -17,11 +17,12 @@
17
17
  import z from '@deepseek-ai/schemastery';
18
18
  import { settingsNamespace } from '@deepseek-ai/dsh-settings';
19
19
  import { ConfigAliasesSchema, SettingsAliasesSchema } from "./schema.js";
20
- import { createModelResolver, mergeAliasMaps } from "./resolver.js";
20
+ import { createModelInspector, createModelResolver, mergeAliasMaps } from "./resolver.js";
21
+ import { overlayStampedEffort, stampedEffortOf } from "./effort.js";
21
22
  /** Runtime config schema (config-layer aliases never hold null). */
22
23
  export const Config = z.object({ modelAliases: ConfigAliasesSchema });
23
24
  /** The settings namespace carrying the live `model-aliases` overlay. */
24
- const MODEL_ALIASES_NAMESPACE = settingsNamespace('model-aliases');
25
+ export const MODEL_ALIASES_NAMESPACE = settingsNamespace('model-aliases');
25
26
  /** Cordis plugin id. */
26
27
  export const name = 'cc-model-routes';
27
28
  /**
@@ -38,14 +39,70 @@ export function apply(ctx, config = {}) {
38
39
  validate: (value) => {
39
40
  for (const [alias, target] of Object.entries(value)) {
40
41
  if (target !== null && typeof target === 'object') {
41
- if (target.provider.trim().length === 0 || target.model.trim().length === 0) {
42
- throw new Error(`cc-model-aliases: model alias "${alias}" must specify a non-empty provider and model`);
42
+ if (typeof target.model !== 'string' || target.model.trim().length === 0) {
43
+ throw new Error(`cc-model-aliases: model alias "${alias}" must specify a non-empty model`);
44
+ }
45
+ if (target.provider !== undefined && target.provider.trim().length === 0) {
46
+ throw new Error(`cc-model-aliases: model alias "${alias}" must specify a non-empty provider when present`);
43
47
  }
44
48
  }
45
49
  }
46
50
  },
47
51
  });
48
- const resolve = createModelResolver(() => mergeAliasMaps(config.modelAliases, scope?.get?.()), { warn: message => ctx.logger.warn(message) });
49
- ctx.provide('ccModelRoutes', { resolve });
52
+ const aliasSources = () => mergeAliasMaps(config.modelAliases, scope?.get?.());
53
+ const warnOptions = { warn: (message) => ctx.logger.warn(message) };
54
+ const resolver = createModelResolver(aliasSources, warnOptions);
55
+ const inspect = createModelInspector(aliasSources, warnOptions);
56
+ const resolveDetailed = resolver.resolveDetailed;
57
+ // Both consumption shapes must be published: the Task tool's resume-pin
58
+ // capture calls `resolveDetailed` — publishing only `resolve` makes every
59
+ // captured background spawn throw TypeError at spawn time. `inspect` keeps
60
+ // the upstream provenance form (`/doctor`) available alongside.
61
+ ctx.provide('ccModelRoutes', { resolve: resolver, resolveDetailed, inspect });
62
+ // Host-side effort overlay: a child spawned through an alias whose route
63
+ // declared `reasoningEffort` carries it on its options as an undeclared
64
+ // runtime extra key (stamped by the Task tool / plugin-loader). buildRequest
65
+ // deep-freezes its seed config and may restore an explicit parent /effort
66
+ // from a fork seed's request/header — the alias contract wins, so overlay
67
+ // AFTER `next()` with a shallow copy (never in place). Root agents carry no
68
+ // stamp on options, so this is a no-op for them.
69
+ ctx.on('agent/request', async ({ agent }, next) => {
70
+ const resolved = await next();
71
+ return overlayStampedEffort(resolved, stampedEffortOf(agent.options));
72
+ });
73
+ }
74
+ /**
75
+ * Host-plane alias read WITHOUT owning the namespace: resolve through the
76
+ * `ccModelRoutes` service when one is mounted, otherwise read the live
77
+ * `model-aliases` settings overlay directly. Never re-registers the namespace
78
+ * — the isolated `cc-model-routes` plugin row already owns that registration,
79
+ * and `settings.register` throws on a duplicate namespace.
80
+ * @param ctx - the host context (no plugin instance required).
81
+ * @param alias - frontmatter model alias, or undefined to inherit.
82
+ * @returns the resolved route, or undefined to inherit the parent route.
83
+ */
84
+ export function resolveAlias(ctx, alias) {
85
+ const routes = ctx.get('ccModelRoutes');
86
+ if (routes !== undefined)
87
+ return routes.resolve(alias);
88
+ const settings = ctx.get('settings');
89
+ const overlay = settings?.get?.(MODEL_ALIASES_NAMESPACE);
90
+ return createModelResolver(() => mergeAliasMaps(undefined, overlay), { warn: message => ctx.logger.warn(message) })(alias);
91
+ }
92
+ /**
93
+ * Host-plane DETAILED alias read: the provenance-carrying counterpart of
94
+ * {@link resolveAlias}, with the same service-then-overlay fallback and the
95
+ * same single-snapshot guarantee (classification and route from one map).
96
+ * @param ctx - the host context (no plugin instance required).
97
+ * @param alias - frontmatter model alias, or undefined to inherit.
98
+ * @returns the atomic detailed resolution for the alias.
99
+ */
100
+ export function resolveDetailedAlias(ctx, alias) {
101
+ const routes = ctx.get('ccModelRoutes');
102
+ if (routes !== undefined)
103
+ return routes.resolveDetailed(alias);
104
+ const settings = ctx.get('settings');
105
+ const overlay = settings?.get?.(MODEL_ALIASES_NAMESPACE);
106
+ return createModelResolver(() => mergeAliasMaps(undefined, overlay), { warn: message => ctx.logger.warn(message) }).resolveDetailed(alias);
50
107
  }
51
108
  //# sourceMappingURL=service.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"service.js","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,CAAC,MAAM,0BAA0B,CAAA;AAGxC,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAA;AAC7D,OAAO,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAA;AACxE,OAAO,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AASnE,oEAAoE;AACpE,MAAM,CAAC,MAAM,MAAM,GAAc,CAAC,CAAC,MAAM,CAAC,EAAE,YAAY,EAAE,mBAAmB,EAAE,CAAC,CAAA;AAEhF,wEAAwE;AACxE,MAAM,uBAAuB,GAAG,iBAAiB,CAAC,eAAe,CAAC,CAAA;AAQlE,wBAAwB;AACxB,MAAM,CAAC,MAAM,IAAI,GAAG,iBAAiB,CAAA;AAErC;;;;;GAKG;AACH,MAAM,UAAU,KAAK,CAAC,GAAY,EAAE,SAAiB,EAAE;IACrD,MAAM,QAAQ,GAAG,GAAG,CAAC,GAAG,CAAC,UAAU,CAAiC,CAAA;IACpE,MAAM,KAAK,GAAG,QAAQ,EAAE,QAAQ,CAAC,uBAAuB,EAAE,qBAAqB,EAAE;QAC/E,2EAA2E;QAC3E,0CAA0C;QAC1C,QAAQ,EAAE,CAAC,KAAyC,EAAE,EAAE;YACtD,KAAK,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;gBACpD,IAAI,MAAM,KAAK,IAAI,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;oBAClD,IAAI,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;wBAC5E,MAAM,IAAI,KAAK,CAAC,kCAAkC,KAAK,+CAA+C,CAAC,CAAA;oBACzG,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;KACF,CAAC,CAAA;IACF,MAAM,OAAO,GAAG,mBAAmB,CACjC,GAAG,EAAE,CAAC,cAAc,CAClB,MAAM,CAAC,YAAY,EACnB,KAAK,EAAE,GAAG,EAAE,EAAoD,CACjE,EACD,EAAE,IAAI,EAAE,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAC9C,CAAA;IACD,GAAG,CAAC,OAAO,CAAC,eAAe,EAAE,EAAE,OAAO,EAAE,CAAC,CAAA;AAC3C,CAAC"}
1
+ {"version":3,"file":"service.js","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"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"}
package/lib/types.d.ts CHANGED
@@ -17,28 +17,83 @@
17
17
  * When `start()` passes this on as `agentOptions`, only the fields that are
18
18
  * present (`provider` and/or `model`) override the delegation; a route omitting
19
19
  * `provider` inherits the parent's provider, and one omitting `model` inherits
20
- * the parent's model. `undefined` means "no override" — the child inherits the
21
- * parent route wholesale (the `inherit` sentinel and the builtin fallback both
22
- * resolve to this).
20
+ * the parent's model. `reasoningEffort`, when present, is stamped onto the
21
+ * child's options (a runtime extra key) and applied to every child request by
22
+ * the host `agent/request` listener in the routes service. `undefined` means
23
+ * "no override" — the child inherits the parent route wholesale (the `inherit`
24
+ * sentinel and the builtin fallback both resolve to this).
23
25
  */
24
26
  export interface ResolvedRoute {
25
27
  /** The provider to route to; omit to inherit the parent's provider. */
26
28
  readonly provider?: string | undefined;
27
29
  /** The model id (or resolved alias model) to use; omit to inherit. */
28
30
  readonly model?: string | undefined;
31
+ /**
32
+ * Reasoning effort stamped from the alias target (object form only); an
33
+ * opaque non-empty string whose legal spellings belong to the target model's
34
+ * adapter (`max`, `xhigh`, `high`, …). Absent → no effort stamp.
35
+ */
36
+ readonly reasoningEffort?: string | undefined;
37
+ }
38
+ /**
39
+ * What an alias lookup resolved to, for provenance reporting (`/doctor`).
40
+ *
41
+ * - `route`: a concrete route was produced (configured object, or a followed
42
+ * string/peer target).
43
+ * - `inherit`: no override — the child inherits the parent route.
44
+ * - `literal`: the alias name is passed through verbatim as a model id.
45
+ */
46
+ export type AliasInspectKind = 'route' | 'inherit' | 'literal';
47
+ /**
48
+ * Where the classification came from: a directly configured entry, a peer
49
+ * lane's entry, a one-hop string target, or the builtin fallback.
50
+ */
51
+ export type AliasInspectVia = 'configured' | 'peer' | 'one-hop' | 'builtin';
52
+ /**
53
+ * Provenance of one alias resolution. `route` is exactly what
54
+ * `resolve()` returned for the same input; `via`/`hop` are omitted when not
55
+ * meaningful (e.g. the literal passthrough and the bare inherit cases).
56
+ */
57
+ export interface AliasInspection {
58
+ readonly kind: AliasInspectKind;
59
+ readonly route?: ResolvedRoute;
60
+ readonly via?: AliasInspectVia;
61
+ readonly hop?: string;
62
+ }
63
+ /**
64
+ * One atomic resolution result: the effective route PLUS its provenance,
65
+ * captured from a single settings snapshot (never re-derived later). `via`
66
+ * records how `selector` was classified:
67
+ * - `inherit`: no override (`undefined`, blank, the `inherit` sentinel, an
68
+ * unconfigured builtin, or an unresolvable lane peer) — the parent route
69
+ * stands and `route` is undefined.
70
+ * - `alias`: a configured alias (or a lane peer sharing a configured peer's
71
+ * route) — `route` is the alias's resolved route.
72
+ * - `literal`: passed through verbatim as a model id — `route` is
73
+ * `{ model: selector }` with `provider` absent.
74
+ */
75
+ export interface DetailedRoute {
76
+ /** The trimmed selector that was resolved (undefined for blank/undefined input). */
77
+ readonly selector: string | undefined;
78
+ /** How the selector was classified, from the same snapshot as `route`. */
79
+ readonly via: 'alias' | 'literal' | 'inherit';
80
+ /** The resolved route (undefined exactly when `via` is `inherit`). */
81
+ readonly route: ResolvedRoute | undefined;
29
82
  }
30
83
  /**
31
84
  * One alias target as authored in config or settings.
32
85
  *
33
86
  * A string form names only a model id (`sonnet: deepseek-chat`); the provider
34
87
  * inherits the parent route. An object form additionally pins a provider
35
- * (`opus: { provider: ..., model: ... }`), breaking the current frontmatter
36
- * limitation of never being able to override the provider. In the settings
37
- * layer a configured entry may instead be `null`, which deletes a same-named
38
- * config-default entry (see {@link mergeAliasMaps}).
88
+ * (`opus: { provider: ..., model: ... }`) — `provider` is optional so an alias
89
+ * can inherit the parent provider while still pinning a model and effort — and
90
+ * may carry a `reasoningEffort` stamped onto spawns of this alias. In the
91
+ * settings layer a configured entry may instead be `null`, which deletes a
92
+ * same-named config-default entry (see {@link mergeAliasMaps}).
39
93
  */
40
94
  export type AliasTarget = string | {
41
- readonly provider: string;
95
+ readonly provider?: string;
42
96
  readonly model: string;
97
+ readonly reasoningEffort?: string;
43
98
  } | null;
44
99
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH;;;;;;;;;GASG;AACH,MAAM,WAAW,aAAa;IAC5B,uEAAuE;IACvE,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IACtC,sEAAsE;IACtE,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CACpC;AAED;;;;;;;;;GASG;AACH,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG;IAAE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAA"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,aAAa;IAC5B,uEAAuE;IACvE,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IACtC,sEAAsE;IACtE,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IACnC;;;;OAIG;IACH,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAC9C;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,gBAAgB,GAAG,OAAO,GAAG,SAAS,GAAG,SAAS,CAAA;AAE9D;;;GAGG;AACH,MAAM,MAAM,eAAe,GAAG,YAAY,GAAG,MAAM,GAAG,SAAS,GAAG,SAAS,CAAA;AAE3E;;;;GAIG;AACH,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,IAAI,EAAE,gBAAgB,CAAA;IAC/B,QAAQ,CAAC,KAAK,CAAC,EAAE,aAAa,CAAA;IAC9B,QAAQ,CAAC,GAAG,CAAC,EAAE,eAAe,CAAA;IAC9B,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CACtB;AAED;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,aAAa;IAC5B,oFAAoF;IACpF,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAA;IACrC,0EAA0E;IAC1E,QAAQ,CAAC,GAAG,EAAE,OAAO,GAAG,SAAS,GAAG,SAAS,CAAA;IAC7C,sEAAsE;IACtE,QAAQ,CAAC,KAAK,EAAE,aAAa,GAAG,SAAS,CAAA;CAC1C;AAED;;;;;;;;;;GAUG;AACH,MAAM,MAAM,WAAW,GACjB,MAAM,GACN;IAAE,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAA;CAAE,GACzF,IAAI,CAAA"}