@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/README.i18n.yaml +2 -2
- package/README.md +88 -10
- package/README.zh.md +46 -6
- package/lib/agentOptions.d.ts +33 -0
- package/lib/agentOptions.d.ts.map +1 -0
- package/lib/agentOptions.js +48 -0
- package/lib/agentOptions.js.map +1 -0
- package/lib/effort.d.ts +39 -0
- package/lib/effort.d.ts.map +1 -0
- package/lib/effort.js +48 -0
- package/lib/effort.js.map +1 -0
- package/lib/index.d.ts +5 -3
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +4 -2
- package/lib/index.js.map +1 -1
- package/lib/resolver.d.ts +52 -9
- package/lib/resolver.d.ts.map +1 -1
- package/lib/resolver.js +141 -24
- package/lib/resolver.js.map +1 -1
- package/lib/schema.d.ts +12 -3
- package/lib/schema.d.ts.map +1 -1
- package/lib/schema.js +11 -4
- package/lib/schema.js.map +1 -1
- package/lib/service.d.ts +31 -1
- package/lib/service.d.ts.map +1 -1
- package/lib/service.js +63 -6
- package/lib/service.js.map +1 -1
- package/lib/types.d.ts +63 -8
- package/lib/types.d.ts.map +1 -1
- package/package.json +14 -2
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
|
-
*
|
|
14
|
-
* — they resolve to "inherit the parent
|
|
15
|
-
* deployment decision that a zero-config
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
* warning when it looks
|
|
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 = [
|
|
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
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
*
|
|
64
|
-
* @param options -
|
|
65
|
-
*
|
|
66
|
-
*
|
|
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
|
|
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
|
|
126
|
+
return { kind: 'inherit' };
|
|
76
127
|
const trimmed = model.trim();
|
|
77
128
|
const folded = trimmed.toLowerCase();
|
|
78
129
|
if (folded === 'inherit')
|
|
79
|
-
return
|
|
130
|
+
return { kind: 'inherit' };
|
|
80
131
|
const aliases = getAliases();
|
|
81
132
|
const hit = aliases.get(folded);
|
|
82
133
|
if (hit !== undefined && hit !== null) {
|
|
83
|
-
|
|
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
|
|
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();
|
package/lib/resolver.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolver.js","sourceRoot":"","sources":["../src/resolver.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"resolver.js","sourceRoot":"","sources":["../src/resolver.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAIH;;;GAGG;AACH,MAAM,CAAC,MAAM,UAAU,GAAsB,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAA;AAEjF;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,MAAM,YAAY,GAAsB,CAAC,QAAQ,EAAE,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,WAAW,CAAC,CAAA;AAE1G,kEAAkE;AAClE,MAAM,CAAC,MAAM,UAAU,GAAqC;IAC1D,MAAM,EAAE,OAAO;IACf,KAAK,EAAE,QAAQ;IACf,SAAS,EAAE,MAAM;IACjB,UAAU,EAAE,OAAO;CACpB,CAAA;AAED;;;;GAIG;AACH,MAAM,CAAC,MAAM,eAAe,GAAsB,CAAC,GAAG,UAAU,EAAE,GAAG,YAAY,CAAC,CAAA;AAElF,wEAAwE;AACxE,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,eAAe,CAAC,CAAA;AAE5C;;;;;;;;;;GAUG;AACH,MAAM,UAAU,cAAc,CAC5B,MAAyD,EACzD,QAAkE;IAElE,MAAM,MAAM,GAAG,IAAI,GAAG,EAAuB,CAAA;IAC7C,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QAC5C,6EAA6E;QAC7E,uEAAuE;QACvE,wDAAwD;QACxD,IAAI,KAAK,KAAK,IAAI;YAAE,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAA;IAC5C,CAAC;IACD,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC9C,IAAI,KAAK,KAAK,IAAI;YAAE,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;;YACjC,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAA;IAC7B,CAAC;IACD,OAAO,MAAM,CAAA;AACf,CAAC;AAsBD,MAAM,UAAU,mBAAmB,CACjC,UAAkD,EAClD,OAA8C;IAE9C,MAAM,OAAO,GAAG,oBAAoB,CAAC,UAAU,EAAE,OAAO,CAAC,CAAA;IACzD,MAAM,eAAe,GAAG,CAAC,KAAyB,EAAiB,EAAE;QACnE,MAAM,OAAO,GAAoB,OAAO,CAAC,KAAK,CAAC,CAAA;QAC/C,IAAI,OAAO,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YAC/B,OAAO,EAAE,QAAQ,EAAE,KAAK,KAAK,SAAS,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,GAAG,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,CAAA;QACpI,CAAC;QACD,MAAM,QAAQ,GAAG,KAAK,EAAE,IAAI,EAAE,CAAA;QAC9B,IAAI,OAAO,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;YAC7B,OAAO,EAAE,QAAQ,EAAE,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAAA;QACzD,CAAC;QACD,yEAAyE;QACzE,0EAA0E;QAC1E,mEAAmE;QACnE,wEAAwE;QACxE,+CAA+C;QAC/C,MAAM,QAAQ,GAAG,OAAO,CAAC,KAAK,KAAK,SAAS,IAAI,OAAO,CAAC,KAAK,CAAC,KAAK,KAAK,SAAS,IAAI,OAAO,CAAC,KAAK,CAAC,KAAK,KAAK,QAAQ,CAAA;QACrH,OAAO,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAAA;IAC5H,CAAC,CAAA;IACD,4EAA4E;IAC5E,yEAAyE;IACzE,8DAA8D;IAC9D,MAAM,OAAO,GAAG,CAAC,KAAyB,EAAE,EAAE,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC,KAAK,CAAA;IAC3E,OAAO,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,EAAE,eAAe,EAAE,CAAC,CAAA;AACpD,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,oBAAoB,CAClC,UAAkD,EAClD,OAA8C;IAE9C,MAAM,IAAI,GAAG,OAAO,EAAE,IAAI,IAAI,CAAC,CAAC,OAAe,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAA;IAC1E,OAAO,CAAC,KAAK,EAAE,EAAE;QACf,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,CAAA;QAChF,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAA;QAC5B,MAAM,MAAM,GAAG,OAAO,CAAC,WAAW,EAAE,CAAA;QACpC,IAAI,MAAM,KAAK,SAAS;YAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,CAAA;QAEpD,MAAM,OAAO,GAAG,UAAU,EAAE,CAAA;QAC5B,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;QAC/B,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;YACtC,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;gBAC5B,MAAM,QAAQ,GAAG,kBAAkB,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,CAAC,CAAA;gBACzD,MAAM,YAAY,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAA;gBAC7C,IAAI,QAAQ,CAAC,IAAI,KAAK,OAAO;oBAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,SAAS,EAAE,GAAG,EAAE,YAAY,EAAE,KAAK,EAAE,QAAQ,CAAC,KAAK,EAAE,CAAA;gBACjH,IAAI,QAAQ,CAAC,IAAI,KAAK,SAAS;oBAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,EAAE,SAAS,EAAE,GAAG,EAAE,YAAY,EAAE,CAAA;gBAC9F,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE,CAAA;YACnD,CAAC;YACD,yEAAyE;YACzE,wEAAwE;YACxE,mEAAmE;YACnE,0DAA0D;YAC1D,OAAO;gBACL,IAAI,EAAE,OAAO;gBACb,GAAG,EAAE,YAAY;gBACjB,KAAK,EAAE;oBACL,GAAG,CAAC,GAAG,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,GAAG,CAAC,QAAQ,EAAE,CAAC;oBACjE,GAAG,CAAC,GAAG,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,CAAC;oBACxD,GAAG,CAAC,GAAG,CAAC,eAAe,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,eAAe,EAAE,GAAG,CAAC,eAAe,EAAE,CAAC;iBACvF;aACF,CAAA;QACH,CAAC;QAED,kEAAkE;QAClE,yEAAyE;QACzE,yEAAyE;QACzE,2EAA2E;QAC3E,qEAAqE;QACrE,MAAM,IAAI,GAAG,UAAU,CAAC,MAAM,CAAC,CAAA;QAC/B,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;YACvB,MAAM,QAAQ,GAAG,kBAAkB,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,CAAC,CAAA;YAC1D,IAAI,QAAQ,CAAC,IAAI,KAAK,OAAO;gBAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,CAAC,KAAK,EAAE,CAAA;YACtG,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,CAAA;QACpD,CAAC;QAED,2EAA2E;QAC3E,IAAI,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC;YAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,EAAE,SAAS,EAAE,CAAA;QAEvE,yEAAyE;QACzE,yEAAyE;QACzE,4CAA4C;QAC5C,IAAI,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;YAC5B,IAAI,CAAC,4BAA4B,OAAO,gGAAgG,CAAC,CAAA;QAC3I,CAAC;QACD,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,CAAA;IACvD,CAAC,CAAA;AACH,CAAC;AAOD;;;;;;;;;;;GAWG;AACH,SAAS,kBAAkB,CACzB,MAAc,EACd,OAAyC,EACzC,IAAY;IAEZ,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAA;IAC1C,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,IAAI,MAAM,KAAK,IAAI,IAAI,MAAM,KAAK,SAAS;QAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,CAAA;IAC9F,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;IAChC,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;QACxC,IAAI,OAAO,IAAI,KAAK,QAAQ;YAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,CAAA;QAC9E,OAAO;YACL,IAAI,EAAE,OAAO;YACb,KAAK,EAAE;gBACL,GAAG,CAAC,IAAI,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACnE,GAAG,CAAC,IAAI,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC;gBAC1D,GAAG,CAAC,IAAI,CAAC,eAAe,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,eAAe,EAAE,IAAI,CAAC,eAAe,EAAE,CAAC;aACzF;SACF,CAAA;IACH,CAAC;IACD,IAAI,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC;QAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,CAAA;IACvD,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,CAAA;AAC5B,CAAC;AAED,0EAA0E;AAC1E,SAAS,QAAQ,CAAC,MAAgE;IAChF,MAAM,GAAG,GAAG,IAAI,GAAG,EAA8B,CAAA;IACjD,IAAI,MAAM,KAAK,SAAS;QAAE,OAAO,GAAG,CAAA;IACpC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAClD,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,WAAW,EAAE,EAAE,KAAK,CAAC,CAAA;IACnC,CAAC;IACD,OAAO,GAAG,CAAA;AACZ,CAAC"}
|
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 `
|
|
10
|
-
*
|
|
11
|
-
*
|
|
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>;
|
package/lib/schema.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAAA
|
|
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 `
|
|
10
|
-
*
|
|
11
|
-
*
|
|
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
|
-
/**
|
|
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
|
|
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
|
package/lib/service.d.ts.map
CHANGED
|
@@ -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;
|
|
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.
|
|
42
|
-
throw new Error(`cc-model-aliases: model alias "${alias}" must specify a non-empty
|
|
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
|
|
49
|
-
ctx.
|
|
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
|
package/lib/service.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service.js","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,CAAC,MAAM,0BAA0B,CAAA;
|
|
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. `
|
|
21
|
-
*
|
|
22
|
-
*
|
|
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: ... }`)
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
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
|
|
95
|
+
readonly provider?: string;
|
|
42
96
|
readonly model: string;
|
|
97
|
+
readonly reasoningEffort?: string;
|
|
43
98
|
} | null;
|
|
44
99
|
//# sourceMappingURL=types.d.ts.map
|
package/lib/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH
|
|
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"}
|