@sagmans/dsh-tui 0.7.0 → 0.9.0
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/.agents/skills/dsh-tui-dogfood/SKILL.md +5 -1
- package/.agents/skills/dsh-tui-dogfood/scripts/run-plugin-from-worktree.sh +26 -2
- package/.agents/skills/dsh-tui-update-models/SKILL.md +95 -17
- package/.agents/skills/dsh-tui-update-models/references/model-wiring.md +158 -28
- package/.agents/skills/dsh-tui-update-models/scripts/dump-model-catalog.mjs +152 -16
- package/README.md +117 -53
- package/lib/agent/history.d.ts +0 -2
- package/lib/agent/history.d.ts.map +1 -1
- package/lib/agent/history.js +1 -1
- package/lib/agent/history.js.map +1 -1
- package/lib/agent/host.d.ts +0 -25
- package/lib/agent/host.d.ts.map +1 -1
- package/lib/agent/host.js +2 -2
- package/lib/agent/host.js.map +1 -1
- package/lib/agent/model.d.ts +38 -6
- package/lib/agent/model.d.ts.map +1 -1
- package/lib/agent/model.js +38 -14
- package/lib/agent/model.js.map +1 -1
- package/lib/agent/prompt-history.d.ts +7 -12
- package/lib/agent/prompt-history.d.ts.map +1 -1
- package/lib/agent/prompt-history.js +10 -31
- package/lib/agent/prompt-history.js.map +1 -1
- package/lib/cards/composition.d.ts +1 -1
- package/lib/cards/composition.d.ts.map +1 -1
- package/lib/cards/composition.js +7 -0
- package/lib/cards/composition.js.map +1 -1
- package/lib/cards/presenter.d.ts.map +1 -1
- package/lib/cards/presenter.js +32 -2
- package/lib/cards/presenter.js.map +1 -1
- package/lib/cards.d.ts +27 -2
- package/lib/cards.d.ts.map +1 -1
- package/lib/cards.js +17 -3
- package/lib/cards.js.map +1 -1
- package/lib/compat/probe.js +1 -1
- package/lib/compat/probe.js.map +1 -1
- package/lib/config.d.ts +10 -0
- package/lib/config.d.ts.map +1 -1
- package/lib/config.js +18 -0
- package/lib/config.js.map +1 -1
- package/lib/contracts.d.ts +2 -0
- package/lib/contracts.d.ts.map +1 -1
- package/lib/export.d.ts +12 -0
- package/lib/export.d.ts.map +1 -1
- package/lib/export.js +34 -3
- package/lib/export.js.map +1 -1
- package/lib/herdr/client.d.ts +8 -9
- package/lib/herdr/client.d.ts.map +1 -1
- package/lib/herdr/client.js +14 -2
- package/lib/herdr/client.js.map +1 -1
- package/lib/herdr/constants.d.ts +18 -0
- package/lib/herdr/constants.d.ts.map +1 -1
- package/lib/herdr/constants.js +18 -0
- package/lib/herdr/constants.js.map +1 -1
- package/lib/herdr/reporter.d.ts +20 -4
- package/lib/herdr/reporter.d.ts.map +1 -1
- package/lib/herdr/reporter.js +70 -20
- package/lib/herdr/reporter.js.map +1 -1
- package/lib/herdr/state.d.ts +10 -10
- package/lib/herdr/state.d.ts.map +1 -1
- package/lib/herdr/state.js +22 -5
- package/lib/herdr/state.js.map +1 -1
- package/lib/identity.d.ts +0 -2
- package/lib/identity.d.ts.map +1 -1
- package/lib/identity.js +0 -1
- package/lib/identity.js.map +1 -1
- package/lib/index.d.ts +1 -4
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +15 -5
- package/lib/index.js.map +1 -1
- package/lib/input/keymap.d.ts +1 -7
- package/lib/input/keymap.d.ts.map +1 -1
- package/lib/input/keymap.js +3 -11
- package/lib/input/keymap.js.map +1 -1
- package/lib/input/submission.js +2 -2
- package/lib/input/submission.js.map +1 -1
- package/lib/install-skills.d.ts +20 -1
- package/lib/install-skills.d.ts.map +1 -1
- package/lib/install-skills.js +84 -9
- package/lib/install-skills.js.map +1 -1
- package/lib/model-list.d.ts.map +1 -1
- package/lib/model-list.js +17 -5
- package/lib/model-list.js.map +1 -1
- package/lib/queue.d.ts +0 -2
- package/lib/queue.d.ts.map +1 -1
- package/lib/queue.js +1 -1
- package/lib/queue.js.map +1 -1
- package/lib/settings-notice.d.ts +10 -1
- package/lib/settings-notice.d.ts.map +1 -1
- package/lib/settings-notice.js +17 -7
- package/lib/settings-notice.js.map +1 -1
- package/lib/spacing.d.ts +40 -0
- package/lib/spacing.d.ts.map +1 -0
- package/lib/spacing.js +54 -0
- package/lib/spacing.js.map +1 -0
- package/lib/stash/paths.d.ts +19 -10
- package/lib/stash/paths.d.ts.map +1 -1
- package/lib/stash/paths.js +52 -23
- package/lib/stash/paths.js.map +1 -1
- package/lib/stash/schema.d.ts +13 -12
- package/lib/stash/schema.d.ts.map +1 -1
- package/lib/stash/schema.js +11 -9
- package/lib/stash/schema.js.map +1 -1
- package/lib/stash/store.d.ts.map +1 -1
- package/lib/stash/store.js +9 -19
- package/lib/stash/store.js.map +1 -1
- package/lib/stash.d.ts +17 -10
- package/lib/stash.d.ts.map +1 -1
- package/lib/stash.js +31 -20
- package/lib/stash.js.map +1 -1
- package/lib/subagents.d.ts +0 -4
- package/lib/subagents.d.ts.map +1 -1
- package/lib/subagents.js +2 -2
- package/lib/subagents.js.map +1 -1
- package/lib/surface/appearance.d.ts +3 -0
- package/lib/surface/appearance.d.ts.map +1 -1
- package/lib/surface/appearance.js +5 -0
- package/lib/surface/appearance.js.map +1 -1
- package/lib/surface/background-work.d.ts +2 -0
- package/lib/surface/background-work.d.ts.map +1 -1
- package/lib/surface/background-work.js +45 -3
- package/lib/surface/background-work.js.map +1 -1
- package/lib/surface/commands.d.ts +2 -0
- package/lib/surface/commands.d.ts.map +1 -1
- package/lib/surface/commands.js +32 -6
- package/lib/surface/commands.js.map +1 -1
- package/lib/surface/modal-input.d.ts +3 -2
- package/lib/surface/modal-input.d.ts.map +1 -1
- package/lib/surface/modal-input.js +25 -8
- package/lib/surface/modal-input.js.map +1 -1
- package/lib/surface/model-choice.d.ts.map +1 -1
- package/lib/surface/model-choice.js +18 -18
- package/lib/surface/model-choice.js.map +1 -1
- package/lib/surface/preset-choice.d.ts.map +1 -1
- package/lib/surface/preset-choice.js +18 -10
- package/lib/surface/preset-choice.js.map +1 -1
- package/lib/surface/prompt-memory.d.ts +3 -1
- package/lib/surface/prompt-memory.d.ts.map +1 -1
- package/lib/surface/prompt-memory.js +10 -11
- package/lib/surface/prompt-memory.js.map +1 -1
- package/lib/surface/session-lifecycle.d.ts +6 -1
- package/lib/surface/session-lifecycle.d.ts.map +1 -1
- package/lib/surface/session-lifecycle.js +30 -8
- package/lib/surface/session-lifecycle.js.map +1 -1
- package/lib/surface/session-view.d.ts.map +1 -1
- package/lib/surface/session-view.js +1 -3
- package/lib/surface/session-view.js.map +1 -1
- package/lib/surface/staged-turns.d.ts +0 -2
- package/lib/surface/staged-turns.d.ts.map +1 -1
- package/lib/surface/staged-turns.js +37 -6
- package/lib/surface/staged-turns.js.map +1 -1
- package/lib/terminal/external-editor.d.ts +16 -0
- package/lib/terminal/external-editor.d.ts.map +1 -1
- package/lib/terminal/external-editor.js +38 -6
- package/lib/terminal/external-editor.js.map +1 -1
- package/lib/terminal/host-writes.d.ts +15 -2
- package/lib/terminal/host-writes.d.ts.map +1 -1
- package/lib/terminal/host-writes.js +10 -1
- package/lib/terminal/host-writes.js.map +1 -1
- package/lib/terminal/restore.d.ts +1 -2
- package/lib/terminal/restore.d.ts.map +1 -1
- package/lib/terminal/restore.js +1 -9
- package/lib/terminal/restore.js.map +1 -1
- package/lib/terminal/signals.d.ts +0 -1
- package/lib/terminal/signals.d.ts.map +1 -1
- package/lib/terminal/signals.js +1 -1
- package/lib/terminal/signals.js.map +1 -1
- package/lib/terminal/title.d.ts.map +1 -1
- package/lib/terminal/title.js +14 -3
- package/lib/terminal/title.js.map +1 -1
- package/lib/terminal/warning-screen.d.ts.map +1 -1
- package/lib/terminal/warning-screen.js +12 -1
- package/lib/terminal/warning-screen.js.map +1 -1
- package/lib/theme-capability.d.ts +0 -2
- package/lib/theme-capability.d.ts.map +1 -1
- package/lib/theme-capability.js +1 -1
- package/lib/theme-capability.js.map +1 -1
- package/lib/theme-defaults.d.ts.map +1 -1
- package/lib/theme-defaults.js +7 -0
- package/lib/theme-defaults.js.map +1 -1
- package/lib/theme-files.d.ts +1 -1
- package/lib/theme-files.d.ts.map +1 -1
- package/lib/theme-files.js +1 -1
- package/lib/theme-files.js.map +1 -1
- package/lib/theme-schema.d.ts +6 -6
- package/lib/theme-settings.d.ts +13 -8
- package/lib/theme-settings.d.ts.map +1 -1
- package/lib/theme-settings.js +17 -3
- package/lib/theme-settings.js.map +1 -1
- package/lib/theme-tokens.d.ts +1 -1
- package/lib/theme-tokens.d.ts.map +1 -1
- package/lib/theme-tokens.js +7 -2
- package/lib/theme-tokens.js.map +1 -1
- package/lib/transcript.d.ts +2 -2
- package/lib/transcript.d.ts.map +1 -1
- package/lib/transcript.js +9 -4
- package/lib/transcript.js.map +1 -1
- package/lib/ui/dock.d.ts +2 -0
- package/lib/ui/dock.d.ts.map +1 -1
- package/lib/ui/dock.js +18 -3
- package/lib/ui/dock.js.map +1 -1
- package/lib/ui/gap.d.ts +28 -0
- package/lib/ui/gap.d.ts.map +1 -0
- package/lib/ui/gap.js +47 -0
- package/lib/ui/gap.js.map +1 -0
- package/lib/ui/gutter.d.ts +25 -0
- package/lib/ui/gutter.d.ts.map +1 -0
- package/lib/ui/gutter.js +31 -0
- package/lib/ui/gutter.js.map +1 -0
- package/lib/ui/layout.d.ts +13 -1
- package/lib/ui/layout.d.ts.map +1 -1
- package/lib/ui/layout.js +32 -6
- package/lib/ui/layout.js.map +1 -1
- package/lib/ui/queue.d.ts +0 -4
- package/lib/ui/queue.d.ts.map +1 -1
- package/lib/ui/queue.js +2 -2
- package/lib/ui/queue.js.map +1 -1
- package/lib/ui/rows.d.ts +0 -8
- package/lib/ui/rows.d.ts.map +1 -1
- package/lib/ui/rows.js +1 -9
- package/lib/ui/rows.js.map +1 -1
- package/lib/ui/stash-picker.d.ts +2 -2
- package/lib/ui/stash-picker.d.ts.map +1 -1
- package/lib/ui/stash-picker.js +3 -3
- package/lib/ui/stash-picker.js.map +1 -1
- package/lib/ui/view/gate-card.d.ts.map +1 -1
- package/lib/ui/view/gate-card.js +4 -1
- package/lib/ui/view/gate-card.js.map +1 -1
- package/lib/ui/view/tool-card.d.ts +17 -2
- package/lib/ui/view/tool-card.d.ts.map +1 -1
- package/lib/ui/view/tool-card.js +40 -8
- package/lib/ui/view/tool-card.js.map +1 -1
- package/lib/ui/view/transcript-message.d.ts +3 -0
- package/lib/ui/view/transcript-message.d.ts.map +1 -1
- package/lib/ui/view/transcript-message.js +8 -1
- package/lib/ui/view/transcript-message.js.map +1 -1
- package/lib/ui/view.d.ts +36 -9
- package/lib/ui/view.d.ts.map +1 -1
- package/lib/ui/view.js +90 -32
- package/lib/ui/view.js.map +1 -1
- package/package.json +3 -1
- package/themes/deepseek-blue.yaml +3 -0
- package/themes/violet-orbit.yaml +16 -9
|
@@ -8,11 +8,23 @@
|
|
|
8
8
|
* invisible in the UI. This reads the same two inputs the resolver does - the
|
|
9
9
|
* owned catalog in the profile patch, and the installed pi-ai provider data -
|
|
10
10
|
* and names where each number came from: "installed" for the source's own
|
|
11
|
-
* entry, "template:<id>" for a clone, "
|
|
11
|
+
* entry, "template:<id>" for a clone, "route" for the protocol a sourceless
|
|
12
|
+
* route declares once for every model it serves, "metadata" for what the
|
|
13
|
+
* catalog declares.
|
|
14
|
+
*
|
|
12
15
|
* An entry the catalog spells out completely needs no installed entry at all,
|
|
13
|
-
* so a missing harness install must not hide it.
|
|
16
|
+
* so a missing harness install must not hide it. A `filter` route is the
|
|
17
|
+
* exception: its membership is the installed catalog's, so it cannot be read
|
|
18
|
+
* without that install. A declaration the plugin's resolver would refuse is
|
|
19
|
+
* reported as a refusal here too, because a catalog that cannot compose serves
|
|
20
|
+
* nothing.
|
|
21
|
+
*
|
|
22
|
+
* Usage: dump-model-catalog.mjs [--home <dsh home>] [--profile <name>]
|
|
23
|
+
* [--data <pi-ai data dir>] [--json]
|
|
14
24
|
*
|
|
15
|
-
*
|
|
25
|
+
* `--data` names the installed provider-data directory to inherit from, which
|
|
26
|
+
* is how a reading is checked where no harness is installed - a `filter` route
|
|
27
|
+
* and every template clone need one.
|
|
16
28
|
*/
|
|
17
29
|
import { execFileSync } from 'node:child_process'
|
|
18
30
|
import { readFileSync, realpathSync } from 'node:fs'
|
|
@@ -23,9 +35,15 @@ import { fileURLToPath } from 'node:url'
|
|
|
23
35
|
const LEVELS = ['off', 'minimal', 'low', 'medium', 'high', 'xhigh', 'max']
|
|
24
36
|
/** Fields a catalog entry may inherit, and the layer each value came from. */
|
|
25
37
|
const INHERITED_FIELDS = ['contextWindow', 'maxTokens', 'cost', 'input', 'reasoning', 'thinkingLevelMap', 'api']
|
|
38
|
+
/** What a model with no installed sibling and no template must state itself. */
|
|
39
|
+
const REQUIRED_METADATA = ['api', 'reasoning', 'input', 'cost', 'contextWindow', 'maxTokens']
|
|
40
|
+
const COST_FIELDS = ['input', 'output', 'cacheRead', 'cacheWrite']
|
|
26
41
|
const INSTALLED = 'installed'
|
|
27
42
|
const METADATA = 'metadata'
|
|
43
|
+
const ROUTE = 'route'
|
|
28
44
|
const ABSENT = 'none'
|
|
45
|
+
/** The only wildcard a `filter` pattern carries; every other character is itself. */
|
|
46
|
+
const WILDCARD = '*'
|
|
29
47
|
|
|
30
48
|
/** The levels pi-ai offers: a null mapping removes one, and xhigh/max need one. */
|
|
31
49
|
export function supportedLevels(levelMap) {
|
|
@@ -38,12 +56,13 @@ export function supportedLevels(levelMap) {
|
|
|
38
56
|
}
|
|
39
57
|
|
|
40
58
|
function parseArgs(argv) {
|
|
41
|
-
const options = { home: process.env.DSH_HOME ?? join(homedir(), '.dsh'), profile: 'tui', json: false }
|
|
59
|
+
const options = { home: process.env.DSH_HOME ?? join(homedir(), '.dsh'), profile: 'tui', data: undefined, json: false }
|
|
42
60
|
for (let index = 0; index < argv.length; index += 1) {
|
|
43
61
|
const flag = argv[index]
|
|
44
62
|
if (flag === '--json') options.json = true
|
|
45
63
|
else if (flag === '--home') options.home = argv[++index]
|
|
46
64
|
else if (flag === '--profile') options.profile = argv[++index]
|
|
65
|
+
else if (flag === '--data') options.data = argv[++index]
|
|
47
66
|
else throw new Error('unknown argument ' + flag)
|
|
48
67
|
}
|
|
49
68
|
return options
|
|
@@ -74,7 +93,7 @@ export function catalogConfig(patch) {
|
|
|
74
93
|
}
|
|
75
94
|
|
|
76
95
|
export function providerData(directory, source) {
|
|
77
|
-
if (directory === undefined) return undefined
|
|
96
|
+
if (directory === undefined || source === undefined) return undefined
|
|
78
97
|
try {
|
|
79
98
|
return JSON.parse(readFileSync(join(directory, source + '.json'), 'utf8'))
|
|
80
99
|
} catch {
|
|
@@ -82,6 +101,28 @@ export function providerData(directory, source) {
|
|
|
82
101
|
}
|
|
83
102
|
}
|
|
84
103
|
|
|
104
|
+
/** Installed models in the order the source publishes them, one api map at a time. */
|
|
105
|
+
function installedModels(data) {
|
|
106
|
+
if (data === undefined) return []
|
|
107
|
+
return Object.entries(data).flatMap(([api, models]) => Object.entries(models)
|
|
108
|
+
.map(([id, model]) => ({ ...model, id, api: model.api ?? api })))
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/** Mirror the resolver's pattern rule so a filter reads the same here and there. */
|
|
112
|
+
function patternToRegExp(pattern) {
|
|
113
|
+
const escaped = pattern.split(WILDCARD).map(part => part.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'))
|
|
114
|
+
return new RegExp('^' + escaped.join('.*') + '$')
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/** A filter keeps installed facts and order, then drops what exclude names. */
|
|
118
|
+
export function expandFilter(data, filter) {
|
|
119
|
+
const include = filter?.include === undefined ? undefined : filter.include.map(patternToRegExp)
|
|
120
|
+
const exclude = filter?.exclude === undefined ? [] : filter.exclude.map(patternToRegExp)
|
|
121
|
+
return installedModels(data)
|
|
122
|
+
.filter(model => (include === undefined || include.some(pattern => pattern.test(model.id)))
|
|
123
|
+
&& !exclude.some(pattern => pattern.test(model.id)))
|
|
124
|
+
}
|
|
125
|
+
|
|
85
126
|
/** Look one id up across a provider's api maps; an api in the spec disambiguates. */
|
|
86
127
|
function lookup(data, id, api) {
|
|
87
128
|
if (data === undefined) return undefined
|
|
@@ -91,8 +132,13 @@ function lookup(data, id, api) {
|
|
|
91
132
|
return undefined
|
|
92
133
|
}
|
|
93
134
|
|
|
135
|
+
function costOf(cost) {
|
|
136
|
+
if (cost === undefined) return undefined
|
|
137
|
+
return '$' + COST_FIELDS.map(field => cost[field]).join('/') + ' per 1M'
|
|
138
|
+
}
|
|
139
|
+
|
|
94
140
|
/** Resolve one catalog entry against the installed data it may inherit from. */
|
|
95
|
-
export function resolve(spec, data) {
|
|
141
|
+
export function resolve(spec, data, routeApi) {
|
|
96
142
|
const metadata = spec.metadata ?? {}
|
|
97
143
|
const declared = Object.keys(metadata).length > 0
|
|
98
144
|
const cloneOf = spec.template ?? spec.id
|
|
@@ -101,37 +147,88 @@ export function resolve(spec, data) {
|
|
|
101
147
|
return { error: 'no source entry for ' + cloneOf + '; declare a template or metadata' }
|
|
102
148
|
}
|
|
103
149
|
const merged = { ...base, ...metadata, id: spec.id, name: spec.name ?? base?.name ?? spec.id }
|
|
104
|
-
|
|
150
|
+
// A route that names no source states its protocol once, for every model.
|
|
151
|
+
if (merged.api === undefined && routeApi !== undefined) merged.api = routeApi
|
|
152
|
+
// Capacity and the request default are different numbers, and the resolver
|
|
153
|
+
// caps one by the other: folding them would hide the mistake it refuses.
|
|
154
|
+
const capacity = metadata.maxTokens ?? base?.maxTokens
|
|
155
|
+
const missing = base === undefined
|
|
156
|
+
? REQUIRED_METADATA.filter(field => field === 'api' ? merged.api === undefined : metadata[field] === undefined)
|
|
157
|
+
: []
|
|
158
|
+
if (missing.length > 0) return { error: 'unknown model requires complete metadata: missing ' + missing.join(', ') }
|
|
159
|
+
if (spec.defaultMaxTokens !== undefined && capacity !== undefined && spec.defaultMaxTokens > capacity) {
|
|
160
|
+
return { error: 'defaultMaxTokens ' + spec.defaultMaxTokens + ' exceeds model maxTokens ' + capacity }
|
|
161
|
+
}
|
|
105
162
|
const origins = {}
|
|
106
163
|
for (const field of INHERITED_FIELDS) {
|
|
107
|
-
|
|
108
|
-
if (
|
|
164
|
+
if (metadata[field] !== undefined) origins[field] = METADATA
|
|
165
|
+
else if (field === 'api' && base === undefined && routeApi !== undefined) origins[field] = ROUTE
|
|
109
166
|
else if (base === undefined) origins[field] = ABSENT
|
|
110
167
|
else origins[field] = spec.template === undefined ? INSTALLED : 'template:' + spec.template
|
|
111
168
|
}
|
|
112
|
-
return {
|
|
169
|
+
return {
|
|
170
|
+
model: { ...merged, maxTokens: capacity },
|
|
171
|
+
origins,
|
|
172
|
+
levels: supportedLevels(merged.thinkingLevelMap),
|
|
173
|
+
...(spec.defaultMaxTokens === undefined ? {} : { requestMax: spec.defaultMaxTokens }),
|
|
174
|
+
...(spec.aliases === undefined ? {} : { aliases: spec.aliases.join(',') }),
|
|
175
|
+
...(metadata.cost?.tiers === undefined ? {} : {
|
|
176
|
+
tiers: metadata.cost.tiers.map(tier => 'above ' + tier.inputTokensAbove + ': ' + costOf(tier)).join('; '),
|
|
177
|
+
}),
|
|
178
|
+
}
|
|
113
179
|
}
|
|
114
180
|
|
|
115
181
|
function rowsOf(catalog, directory) {
|
|
116
182
|
const rows = []
|
|
117
183
|
for (const provider of catalog.providers ?? []) {
|
|
118
184
|
const data = providerData(directory, provider.source)
|
|
185
|
+
const hasModels = 'models' in provider
|
|
186
|
+
const hasFilter = 'filter' in provider
|
|
187
|
+
// The resolver refuses both and neither; saying so here beats serving half.
|
|
188
|
+
if (hasModels === hasFilter) {
|
|
189
|
+
rows.push({ route: provider.id, error: 'declare exactly one of models or filter' })
|
|
190
|
+
continue
|
|
191
|
+
}
|
|
192
|
+
if (hasFilter) {
|
|
193
|
+
if (data === undefined) {
|
|
194
|
+
rows.push({
|
|
195
|
+
route: provider.id,
|
|
196
|
+
error: 'filter expands the installed catalog of source "' + provider.source + '"; no harness install found',
|
|
197
|
+
})
|
|
198
|
+
continue
|
|
199
|
+
}
|
|
200
|
+
for (const model of expandFilter(data, provider.filter)) {
|
|
201
|
+
rows.push({
|
|
202
|
+
route: provider.id + '/' + model.id,
|
|
203
|
+
name: model.name ?? model.id,
|
|
204
|
+
api: model.api,
|
|
205
|
+
contextWindow: model.contextWindow,
|
|
206
|
+
maxTokens: model.maxTokens,
|
|
207
|
+
cost: costOf(model.cost),
|
|
208
|
+
levels: supportedLevels(model.thinkingLevelMap).join(','),
|
|
209
|
+
origins: 'filter:' + (provider.filter.include ?? [WILDCARD]).join(',') + ' all installed',
|
|
210
|
+
})
|
|
211
|
+
}
|
|
212
|
+
continue
|
|
213
|
+
}
|
|
119
214
|
for (const spec of provider.models ?? []) {
|
|
120
|
-
const result = resolve(spec, data)
|
|
215
|
+
const result = resolve(spec, data, provider.api)
|
|
121
216
|
const route = provider.id + '/' + spec.id
|
|
122
217
|
if (result.error !== undefined) {
|
|
123
218
|
rows.push({ route, error: result.error })
|
|
124
219
|
continue
|
|
125
220
|
}
|
|
126
|
-
const cost = result.model.cost ?? {}
|
|
127
221
|
rows.push({
|
|
128
222
|
route,
|
|
129
223
|
name: result.model.name,
|
|
130
224
|
api: result.model.api,
|
|
131
225
|
contextWindow: result.model.contextWindow,
|
|
132
226
|
maxTokens: result.model.maxTokens,
|
|
133
|
-
cost:
|
|
227
|
+
cost: costOf(result.model.cost),
|
|
134
228
|
levels: result.levels.join(','),
|
|
229
|
+
...(result.requestMax === undefined ? {} : { requestMax: result.requestMax }),
|
|
230
|
+
...(result.aliases === undefined ? {} : { aliases: result.aliases }),
|
|
231
|
+
...(result.tiers === undefined ? {} : { tiers: result.tiers }),
|
|
135
232
|
origins: INHERITED_FIELDS
|
|
136
233
|
.map(field => [field, result.origins[field]])
|
|
137
234
|
.filter(([, origin]) => origin !== INSTALLED)
|
|
@@ -143,6 +240,39 @@ function rowsOf(catalog, directory) {
|
|
|
143
240
|
return rows
|
|
144
241
|
}
|
|
145
242
|
|
|
243
|
+
/**
|
|
244
|
+
* The default is part of the catalog, not a comment beside it: the resolver
|
|
245
|
+
* refuses a selection nothing serves, so a reading that skipped it would call a
|
|
246
|
+
* broken catalog readable.
|
|
247
|
+
*/
|
|
248
|
+
export function checkDefault(catalog, rows) {
|
|
249
|
+
const served = rows.filter(row => row.error === undefined)
|
|
250
|
+
const selection = catalog.default ?? null
|
|
251
|
+
if (served.length === 0) {
|
|
252
|
+
return selection === null ? [] : [{ route: 'default', error: 'an empty catalog requires default null' }]
|
|
253
|
+
}
|
|
254
|
+
if (selection === null || typeof selection !== 'object') {
|
|
255
|
+
return [{ route: 'default', error: 'a served catalog requires a default selection' }]
|
|
256
|
+
}
|
|
257
|
+
const alias = new Map()
|
|
258
|
+
for (const provider of catalog.providers ?? []) {
|
|
259
|
+
for (const model of provider.models ?? []) {
|
|
260
|
+
for (const name of [model.id, ...(model.aliases ?? [])]) alias.set(provider.id + '/' + name, model.id)
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
const route = selection.provider + '/' + selection.model
|
|
264
|
+
const canonical = alias.get(route)
|
|
265
|
+
const row = served.find(candidate => candidate.route === selection.provider + '/' + (canonical ?? selection.model))
|
|
266
|
+
if (row === undefined) {
|
|
267
|
+
return [{ route: 'default', error: 'provider/model is outside the managed selection: ' + route }]
|
|
268
|
+
}
|
|
269
|
+
const effort = selection.reasoningEffort
|
|
270
|
+
if (effort !== undefined && !String(row.levels).split(',').includes(effort)) {
|
|
271
|
+
return [{ route: 'default', error: 'effort is not supported by the selected model: ' + effort }]
|
|
272
|
+
}
|
|
273
|
+
return []
|
|
274
|
+
}
|
|
275
|
+
|
|
146
276
|
function main() {
|
|
147
277
|
const options = parseArgs(process.argv.slice(2))
|
|
148
278
|
const patch = join(options.home, 'profiles', options.profile, 'cordis.patch.yml')
|
|
@@ -152,11 +282,12 @@ function main() {
|
|
|
152
282
|
+ 'this profile wires models another way; see references/model-wiring.md\n')
|
|
153
283
|
process.exit(1)
|
|
154
284
|
}
|
|
155
|
-
const directory = dataDirectory()
|
|
285
|
+
const directory = options.data ?? dataDirectory()
|
|
156
286
|
if (directory === undefined) {
|
|
157
287
|
process.stderr.write('no harness install found; entries that inherit from it cannot be checked\n')
|
|
158
288
|
}
|
|
159
|
-
const
|
|
289
|
+
const served = rowsOf(catalog, directory)
|
|
290
|
+
const rows = [...served, ...checkDefault(catalog, served)]
|
|
160
291
|
const unresolved = rows.filter(row => row.error !== undefined).length
|
|
161
292
|
if (options.json) {
|
|
162
293
|
process.stdout.write(JSON.stringify({ default: catalog.default ?? null, rows }, null, 2) + '\n')
|
|
@@ -167,7 +298,12 @@ function main() {
|
|
|
167
298
|
continue
|
|
168
299
|
}
|
|
169
300
|
process.stdout.write(row.route + '\n ' + row.name + ' | ' + row.api + ' | ctx ' + row.contextWindow
|
|
170
|
-
+ ' | max ' + row.maxTokens
|
|
301
|
+
+ ' | max ' + row.maxTokens
|
|
302
|
+
+ (row.requestMax === undefined ? '' : ' | req ' + row.requestMax)
|
|
303
|
+
+ ' | ' + row.cost
|
|
304
|
+
+ (row.tiers === undefined ? '' : ' | tiers ' + row.tiers)
|
|
305
|
+
+ ' | efforts ' + row.levels
|
|
306
|
+
+ (row.aliases === undefined ? '' : ' | aliases ' + row.aliases) + '\n inherited: ' + row.origins + '\n')
|
|
171
307
|
}
|
|
172
308
|
process.stdout.write('default: ' + JSON.stringify(catalog.default ?? null) + '\n')
|
|
173
309
|
}
|