council-review 0.1.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.
Files changed (108) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +374 -0
  3. package/dist/bin.d.ts +3 -0
  4. package/dist/bin.d.ts.map +1 -0
  5. package/dist/bin.js +19 -0
  6. package/dist/bin.js.map +1 -0
  7. package/dist/cli.d.ts +14 -0
  8. package/dist/cli.d.ts.map +1 -0
  9. package/dist/cli.js +829 -0
  10. package/dist/cli.js.map +1 -0
  11. package/dist/config.d.ts +61 -0
  12. package/dist/config.d.ts.map +1 -0
  13. package/dist/config.js +235 -0
  14. package/dist/config.js.map +1 -0
  15. package/dist/herdr.d.ts +36 -0
  16. package/dist/herdr.d.ts.map +1 -0
  17. package/dist/herdr.js +196 -0
  18. package/dist/herdr.js.map +1 -0
  19. package/dist/index.d.ts +30 -0
  20. package/dist/index.d.ts.map +1 -0
  21. package/dist/index.js +30 -0
  22. package/dist/index.js.map +1 -0
  23. package/dist/levels.d.ts +9 -0
  24. package/dist/levels.d.ts.map +1 -0
  25. package/dist/levels.js +19 -0
  26. package/dist/levels.js.map +1 -0
  27. package/dist/merge.d.ts +90 -0
  28. package/dist/merge.d.ts.map +1 -0
  29. package/dist/merge.js +441 -0
  30. package/dist/merge.js.map +1 -0
  31. package/dist/node-guard.d.ts +9 -0
  32. package/dist/node-guard.d.ts.map +1 -0
  33. package/dist/node-guard.js +21 -0
  34. package/dist/node-guard.js.map +1 -0
  35. package/dist/panel.d.ts +89 -0
  36. package/dist/panel.d.ts.map +1 -0
  37. package/dist/panel.js +275 -0
  38. package/dist/panel.js.map +1 -0
  39. package/dist/picker.d.ts +24 -0
  40. package/dist/picker.d.ts.map +1 -0
  41. package/dist/picker.js +182 -0
  42. package/dist/picker.js.map +1 -0
  43. package/dist/providers.d.ts +66 -0
  44. package/dist/providers.d.ts.map +1 -0
  45. package/dist/providers.js +544 -0
  46. package/dist/providers.js.map +1 -0
  47. package/dist/report.d.ts +116 -0
  48. package/dist/report.d.ts.map +1 -0
  49. package/dist/report.js +493 -0
  50. package/dist/report.js.map +1 -0
  51. package/dist/resolve.d.ts +58 -0
  52. package/dist/resolve.d.ts.map +1 -0
  53. package/dist/resolve.js +147 -0
  54. package/dist/resolve.js.map +1 -0
  55. package/dist/reviewer-spawn.d.ts +67 -0
  56. package/dist/reviewer-spawn.d.ts.map +1 -0
  57. package/dist/reviewer-spawn.js +94 -0
  58. package/dist/reviewer-spawn.js.map +1 -0
  59. package/dist/reviewer-tools.d.ts +113 -0
  60. package/dist/reviewer-tools.d.ts.map +1 -0
  61. package/dist/reviewer-tools.js +557 -0
  62. package/dist/reviewer-tools.js.map +1 -0
  63. package/dist/runner.d.ts +79 -0
  64. package/dist/runner.d.ts.map +1 -0
  65. package/dist/runner.js +811 -0
  66. package/dist/runner.js.map +1 -0
  67. package/dist/schema.d.ts +63 -0
  68. package/dist/schema.d.ts.map +1 -0
  69. package/dist/schema.js +302 -0
  70. package/dist/schema.js.map +1 -0
  71. package/dist/scope.d.ts +40 -0
  72. package/dist/scope.d.ts.map +1 -0
  73. package/dist/scope.js +372 -0
  74. package/dist/scope.js.map +1 -0
  75. package/dist/snapshot.d.ts +57 -0
  76. package/dist/snapshot.d.ts.map +1 -0
  77. package/dist/snapshot.js +471 -0
  78. package/dist/snapshot.js.map +1 -0
  79. package/dist/status.d.ts +90 -0
  80. package/dist/status.d.ts.map +1 -0
  81. package/dist/status.js +336 -0
  82. package/dist/status.js.map +1 -0
  83. package/dist/thinking.d.ts +53 -0
  84. package/dist/thinking.d.ts.map +1 -0
  85. package/dist/thinking.js +116 -0
  86. package/dist/thinking.js.map +1 -0
  87. package/package.json +81 -0
  88. package/src/bin.ts +20 -0
  89. package/src/cli.ts +996 -0
  90. package/src/config.ts +338 -0
  91. package/src/herdr.ts +231 -0
  92. package/src/index.ts +30 -0
  93. package/src/levels.ts +23 -0
  94. package/src/merge.ts +548 -0
  95. package/src/node-guard.ts +25 -0
  96. package/src/panel.ts +354 -0
  97. package/src/picker.ts +230 -0
  98. package/src/providers.ts +778 -0
  99. package/src/report.ts +594 -0
  100. package/src/resolve.ts +179 -0
  101. package/src/reviewer-spawn.ts +131 -0
  102. package/src/reviewer-tools.ts +715 -0
  103. package/src/runner.ts +1120 -0
  104. package/src/schema.ts +373 -0
  105. package/src/scope.ts +448 -0
  106. package/src/snapshot.ts +536 -0
  107. package/src/status.ts +470 -0
  108. package/src/thinking.ts +148 -0
@@ -0,0 +1,544 @@
1
+ /**
2
+ * Model discovery and vendor mapping.
3
+ *
4
+ * Reads the review agent host's model catalog (or, failing that, its model-listing command) to
5
+ * learn which providers and models are available, without ever making a model call and without
6
+ * ever opening the host's credential store. See `openspec/changes/add-council-review/specs/
7
+ * council-review/model-discovery/spec.md` for the requirements this module satisfies.
8
+ */
9
+ import { spawn } from 'node:child_process';
10
+ import { readFile } from 'node:fs/promises';
11
+ import { homedir } from 'node:os';
12
+ import { join } from 'node:path';
13
+ import process from 'node:process';
14
+ import { isThinkingLevel } from './levels.js';
15
+ export class DiscoveryError extends Error {
16
+ exitCode = 2;
17
+ constructor(message) {
18
+ super(message);
19
+ this.name = 'DiscoveryError';
20
+ }
21
+ }
22
+ const VENDOR_PREFIX_TABLE = [
23
+ ['anthropic', 'anthropic'],
24
+ ['claude', 'anthropic'],
25
+ ['openai', 'openai'],
26
+ ['gpt', 'openai'],
27
+ ['codex', 'openai'],
28
+ ['o1', 'openai'],
29
+ ['o3', 'openai'],
30
+ ['google', 'google'],
31
+ ['gemini', 'google'],
32
+ ['meta', 'meta'],
33
+ ['llama', 'meta'],
34
+ ['mistral', 'mistral'],
35
+ ['deepseek', 'deepseek'],
36
+ ['qwen', 'qwen'],
37
+ ['minimax', 'minimax'],
38
+ ['moonshot', 'moonshot'],
39
+ ['kimi', 'moonshot'],
40
+ ['xai', 'xai'],
41
+ ['grok', 'xai'],
42
+ ['cohere', 'cohere'],
43
+ ['amazon', 'amazon'],
44
+ ['nova', 'amazon'],
45
+ ['zhipu', 'zhipu'],
46
+ ['glm', 'zhipu'],
47
+ ]
48
+ .slice()
49
+ .sort((a, b) => b[0].length - a[0].length);
50
+ /** Strips a leading run of punctuation/sigil characters some gateways prepend to an id. */
51
+ function stripPrefixMarker(segment) {
52
+ return segment.replace(/^[^a-zA-Z0-9]+/, '');
53
+ }
54
+ function matchPrefixTable(modelId) {
55
+ const lower = modelId.toLowerCase();
56
+ for (const [prefix, vendor] of VENDOR_PREFIX_TABLE) {
57
+ if (lower.startsWith(prefix))
58
+ return vendor;
59
+ }
60
+ return null;
61
+ }
62
+ export function deriveVendor(provider, modelId, overrides) {
63
+ const overrideKey = `${provider}/${modelId}`;
64
+ if (Object.prototype.hasOwnProperty.call(overrides, overrideKey)) {
65
+ return overrides[overrideKey];
66
+ }
67
+ const slashIdx = modelId.indexOf('/');
68
+ if (slashIdx > 0) {
69
+ const leading = stripPrefixMarker(modelId.slice(0, slashIdx));
70
+ if (leading.length > 0)
71
+ return leading;
72
+ }
73
+ const flatVendor = matchPrefixTable(modelId);
74
+ if (flatVendor)
75
+ return flatVendor;
76
+ return 'unknown';
77
+ }
78
+ /** vendor -> ['provider/modelId', ...]; only groups with >1 member matter to callers, but return all. */
79
+ export function collapsedVendorGroups(models) {
80
+ const groups = new Map();
81
+ for (const model of models) {
82
+ const key = `${model.provider}/${model.id}`;
83
+ const existing = groups.get(model.vendor);
84
+ if (existing) {
85
+ existing.push(key);
86
+ }
87
+ else {
88
+ groups.set(model.vendor, [key]);
89
+ }
90
+ }
91
+ return groups;
92
+ }
93
+ function toNumberOrNull(v) {
94
+ return typeof v === 'number' && Number.isFinite(v) ? v : null;
95
+ }
96
+ /**
97
+ * Like `toNumberOrNull`, but additionally rejects a negative value. A per-token rate cannot
98
+ * legitimately be negative — some gateways (observed: OpenRouter's `auto`/`auto-beta` routing
99
+ * models) store a large negative number (e.g. `-1000000`) as a sentinel for "dynamic pricing,
100
+ * no fixed rate exists", rather than omitting `cost` outright. Passing that through as a real
101
+ * rate would compute a negative run cost and make a "cheapest first" ranking pick it every
102
+ * time, so it is treated exactly like an absent rate: unknown, mapped to `null`.
103
+ */
104
+ function toCostRateOrNull(v) {
105
+ return typeof v === 'number' && Number.isFinite(v) && v >= 0 ? v : null;
106
+ }
107
+ function toThinkingLevelMap(v) {
108
+ if (typeof v !== 'object' || v === null || Array.isArray(v))
109
+ return undefined;
110
+ const out = {};
111
+ for (const [key, value] of Object.entries(v)) {
112
+ if (!isThinkingLevel(key))
113
+ continue;
114
+ if (value === null) {
115
+ out[key] = null;
116
+ }
117
+ else if (typeof value === 'string') {
118
+ out[key] = value;
119
+ }
120
+ // Any other shape for this key is ignored rather than propagated as garbage.
121
+ }
122
+ return out;
123
+ }
124
+ /** `override.field ?? existing.field` merge, mirroring the host's `applyModelOverride`. */
125
+ function applyRawModelOverride(model, overrideUnknown) {
126
+ const override = overrideUnknown;
127
+ const existingCost = typeof model.cost === 'object' && model.cost !== null
128
+ ? model.cost
129
+ : undefined;
130
+ const overrideCost = typeof override.cost === 'object' && override.cost !== null
131
+ ? override.cost
132
+ : undefined;
133
+ const existingMap = typeof model.thinkingLevelMap === 'object' && model.thinkingLevelMap !== null
134
+ ? model.thinkingLevelMap
135
+ : undefined;
136
+ const overrideMap = typeof override.thinkingLevelMap === 'object' && override.thinkingLevelMap !== null
137
+ ? override.thinkingLevelMap
138
+ : undefined;
139
+ return {
140
+ ...model,
141
+ name: typeof override.name === 'string' && override.name.length > 0 ? override.name : model.name,
142
+ reasoning: override.reasoning ?? model.reasoning,
143
+ thinkingLevelMap: overrideMap ? { ...existingMap, ...overrideMap } : model.thinkingLevelMap,
144
+ cost: overrideCost
145
+ ? {
146
+ input: overrideCost.input ?? existingCost?.input,
147
+ output: overrideCost.output ?? existingCost?.output,
148
+ }
149
+ : model.cost,
150
+ contextWindow: override.contextWindow ?? model.contextWindow,
151
+ maxTokens: override.maxTokens ?? model.maxTokens,
152
+ };
153
+ }
154
+ /** Builds a fresh raw model entry from a `models[]` definition, mirroring `modelFromJson`. */
155
+ function rawModelFromDefinition(providerId, definitionUnknown) {
156
+ const definition = definitionUnknown;
157
+ if (typeof definition.id !== 'string' || definition.id.length === 0)
158
+ return null;
159
+ return {
160
+ id: definition.id,
161
+ name: typeof definition.name === 'string' && definition.name.length > 0
162
+ ? definition.name
163
+ : definition.id,
164
+ provider: providerId,
165
+ reasoning: definition.reasoning ?? false,
166
+ thinkingLevelMap: definition.thinkingLevelMap,
167
+ cost: definition.cost ?? { input: 0, output: 0 },
168
+ contextWindow: definition.contextWindow ?? 128_000,
169
+ maxTokens: definition.maxTokens ?? 16_384,
170
+ };
171
+ }
172
+ /** Applies one provider's `models.json` config over that provider's raw store models. */
173
+ function mergeProviderModelsJson(providerId, baseModelsUnknown, configUnknown) {
174
+ let models = baseModelsUnknown.map((m) => ({ ...m }));
175
+ const config = configUnknown;
176
+ const definitions = Array.isArray(config.models) ? config.models : [];
177
+ for (const rawDefinition of definitions) {
178
+ const built = rawModelFromDefinition(providerId, rawDefinition);
179
+ if (built === null)
180
+ continue; // malformed models.json definition (no id) — dropped
181
+ const existingIndex = models.findIndex((m) => m.id === built.id);
182
+ if (existingIndex >= 0) {
183
+ models[existingIndex] = built;
184
+ }
185
+ else {
186
+ models.push(built);
187
+ }
188
+ }
189
+ const overrides = config.modelOverrides;
190
+ if (overrides && typeof overrides === 'object') {
191
+ models = models.map((m) => {
192
+ if (typeof m.id !== 'string')
193
+ return m;
194
+ const override = overrides[m.id];
195
+ return override !== undefined ? applyRawModelOverride(m, override) : m;
196
+ });
197
+ }
198
+ return models;
199
+ }
200
+ /**
201
+ * Layers a parsed `models.json` document over a parsed `models-store.json` document, producing
202
+ * a store-shaped document that `catalogFromStore` can consume unchanged. `modelsJson === null`
203
+ * (missing or malformed) returns `store` untouched.
204
+ */
205
+ function mergeModelsJson(store, modelsJson) {
206
+ const providerConfigs = modelsJson?.providers;
207
+ if (!providerConfigs || typeof providerConfigs !== 'object')
208
+ return store;
209
+ const merged = { ...store };
210
+ const providerIds = new Set([...Object.keys(store), ...Object.keys(providerConfigs)]);
211
+ for (const providerId of providerIds) {
212
+ const config = providerConfigs[providerId];
213
+ if (config === undefined)
214
+ continue; // no models.json entry for this provider — store stands as-is
215
+ const storeBlock = store[providerId];
216
+ const baseModels = Array.isArray(storeBlock?.models) ? storeBlock.models : [];
217
+ merged[providerId] = { models: mergeProviderModelsJson(providerId, baseModels, config) };
218
+ }
219
+ return merged;
220
+ }
221
+ async function loadModelsJson(homeDir) {
222
+ const modelsJsonPath = join(homeDir, '.pi', 'agent', 'models.json');
223
+ let text;
224
+ try {
225
+ text = await readFile(modelsJsonPath, 'utf8');
226
+ }
227
+ catch {
228
+ return null; // missing (or unreadable) — the store is used unmodified
229
+ }
230
+ try {
231
+ const parsed = JSON.parse(text);
232
+ if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed))
233
+ return null;
234
+ return parsed;
235
+ }
236
+ catch {
237
+ return null; // corrupt models.json — treated the same as "absent"
238
+ }
239
+ }
240
+ /**
241
+ * Builds catalog models from an already-parsed `models-store.json` document, skipping malformed
242
+ * entries individually. Returns the usable models plus how many entries were skipped.
243
+ */
244
+ function catalogFromStore(store, overrides) {
245
+ const models = [];
246
+ let skipped = 0;
247
+ for (const providerBlock of Object.values(store)) {
248
+ if (typeof providerBlock !== 'object' || providerBlock === null)
249
+ continue;
250
+ const rawModels = providerBlock.models;
251
+ if (!Array.isArray(rawModels))
252
+ continue;
253
+ for (const entryUnknown of rawModels) {
254
+ const entry = entryUnknown;
255
+ const id = entry.id;
256
+ const name = entry.name;
257
+ const provider = entry.provider;
258
+ if (typeof id !== 'string' ||
259
+ id.length === 0 ||
260
+ typeof name !== 'string' ||
261
+ name.length === 0 ||
262
+ typeof provider !== 'string' ||
263
+ provider.length === 0) {
264
+ skipped += 1;
265
+ continue;
266
+ }
267
+ const cost = typeof entry.cost === 'object' && entry.cost !== null
268
+ ? entry.cost
269
+ : undefined;
270
+ models.push({
271
+ id,
272
+ name,
273
+ provider,
274
+ vendor: deriveVendor(provider, id, overrides),
275
+ contextWindow: toNumberOrNull(entry.contextWindow),
276
+ maxOutputTokens: toNumberOrNull(entry.maxTokens),
277
+ inputCostPerMTok: toCostRateOrNull(cost?.input),
278
+ outputCostPerMTok: toCostRateOrNull(cost?.output),
279
+ reasoning: Boolean(entry.reasoning),
280
+ thinkingLevelMap: toThinkingLevelMap(entry.thinkingLevelMap),
281
+ });
282
+ }
283
+ }
284
+ return { models, skipped };
285
+ }
286
+ /**
287
+ * Parses a size column like `204.8K`, `1.0M` or a bare integer into a token count. The host
288
+ * renders these already rounded, so the result is approximate — this is the fallback path, used
289
+ * only when the catalog store is unavailable.
290
+ */
291
+ function parseSizeToken(token) {
292
+ const match = /^([0-9]+(?:\.[0-9]+)?)([KM])?$/i.exec(token);
293
+ if (!match)
294
+ return null;
295
+ const value = Number.parseFloat(match[1]);
296
+ const suffix = match[2]?.toUpperCase();
297
+ if (suffix === 'K')
298
+ return Math.round(value * 1_000);
299
+ if (suffix === 'M')
300
+ return Math.round(value * 1_000_000);
301
+ return Math.round(value);
302
+ }
303
+ /**
304
+ * Parses the plain-text table printed by `pi --list-models`. Only lines matching the exact
305
+ * six-column data shape (provider, model, context, max-out, thinking, images) after the header
306
+ * are treated as models; everything else — the header itself, blank lines, and extension banner
307
+ * lines printed at startup (which happen to also tokenize into a handful of words) — is dropped
308
+ * silently, because banner lines never carry a `yes`/`no` thinking column.
309
+ */
310
+ export function parseListModelsOutput(text) {
311
+ const out = [];
312
+ for (const rawLine of text.split('\n')) {
313
+ const line = rawLine.trim();
314
+ if (line.length === 0)
315
+ continue;
316
+ const tokens = line.split(/\s+/);
317
+ if (tokens.length !== 6)
318
+ continue;
319
+ const [provider, id, contextTok, maxOutTok, thinkingTok] = tokens;
320
+ if (provider.toLowerCase() === 'provider')
321
+ continue; // header row
322
+ if (/[[\]]/.test(provider) || /[[\]]/.test(id))
323
+ continue; // e.g. "[Playwright" banner tokens
324
+ const thinkingLower = thinkingTok.toLowerCase();
325
+ if (thinkingLower !== 'yes' && thinkingLower !== 'no')
326
+ continue;
327
+ out.push({
328
+ provider,
329
+ id,
330
+ contextWindow: parseSizeToken(contextTok),
331
+ maxOutputTokens: parseSizeToken(maxOutTok),
332
+ reasoning: thinkingLower === 'yes',
333
+ });
334
+ }
335
+ return out;
336
+ }
337
+ function listedModelsToCatalogModels(listed, overrides) {
338
+ return listed.map((m) => ({
339
+ id: m.id,
340
+ name: m.id, // no separate display name is available from the listing command
341
+ provider: m.provider,
342
+ vendor: deriveVendor(m.provider, m.id, overrides),
343
+ contextWindow: m.contextWindow,
344
+ maxOutputTokens: m.maxOutputTokens,
345
+ inputCostPerMTok: null, // not exposed by the listing command
346
+ outputCostPerMTok: null,
347
+ reasoning: m.reasoning,
348
+ thinkingLevelMap: undefined, // per-level support is not exposed by the listing command
349
+ }));
350
+ }
351
+ // ---------------------------------------------------------------------------------------------
352
+ // Host process helpers
353
+ // ---------------------------------------------------------------------------------------------
354
+ const COMMAND_TIMEOUT_MS = 15_000;
355
+ /**
356
+ * Runs a host command to completion and always resolves with whatever it printed, regardless of
357
+ * exit code — `pi auth check` exits non-zero for a not-ready provider while still printing a
358
+ * valid JSON status object on stdout, and callers need that body. Only rejects when the process
359
+ * itself could not be spawned or run, or when it hangs past the timeout.
360
+ */
361
+ function runCommand(bin, args) {
362
+ return new Promise((resolve, reject) => {
363
+ let child;
364
+ try {
365
+ child = spawn(bin, args, { stdio: ['ignore', 'pipe', 'pipe'] });
366
+ }
367
+ catch (err) {
368
+ reject(err instanceof Error ? err : new Error(String(err)));
369
+ return;
370
+ }
371
+ let stdout = '';
372
+ let stderr = '';
373
+ let settled = false;
374
+ const timer = setTimeout(() => {
375
+ if (settled)
376
+ return;
377
+ settled = true;
378
+ child.kill();
379
+ reject(new Error(`command timed out after ${COMMAND_TIMEOUT_MS}ms: ${bin} ${args.join(' ')}`));
380
+ }, COMMAND_TIMEOUT_MS);
381
+ child.stdout?.on('data', (chunk) => {
382
+ stdout += chunk.toString('utf8');
383
+ });
384
+ child.stderr?.on('data', (chunk) => {
385
+ stderr += chunk.toString('utf8');
386
+ });
387
+ child.on('error', (err) => {
388
+ if (settled)
389
+ return;
390
+ settled = true;
391
+ clearTimeout(timer);
392
+ reject(err);
393
+ });
394
+ child.on('close', (code) => {
395
+ if (settled)
396
+ return;
397
+ settled = true;
398
+ clearTimeout(timer);
399
+ resolve({ stdout, stderr, code });
400
+ });
401
+ });
402
+ }
403
+ function errorMessage(err) {
404
+ return err instanceof Error ? err.message : String(err);
405
+ }
406
+ function resolvePiBin(opts) {
407
+ return opts?.piBin ?? process.env.COUNCIL_PI_BIN ?? 'pi';
408
+ }
409
+ /**
410
+ * Determines whether one provider is ready via the host's own auth-status interface. Parses
411
+ * ONLY the `status`/`authType`/`reason` fields of its JSON output. This is the one place this
412
+ * module talks to `pi auth`, and it invokes nothing beyond the `check` subcommand shown below —
413
+ * no flag or subcommand that would cause the host to print or copy a live token.
414
+ */
415
+ async function checkProviderReady(piBin, provider) {
416
+ try {
417
+ const { stdout } = await runCommand(piBin, ['auth', 'check', '--provider', provider, '--json']);
418
+ const trimmed = stdout.trim();
419
+ if (trimmed.length === 0) {
420
+ return { ready: false, authType: null, reason: 'auth check produced no output' };
421
+ }
422
+ let parsed;
423
+ try {
424
+ parsed = JSON.parse(trimmed);
425
+ }
426
+ catch {
427
+ return { ready: false, authType: null, reason: 'auth check produced unparseable output' };
428
+ }
429
+ if (typeof parsed !== 'object' || parsed === null) {
430
+ return { ready: false, authType: null, reason: 'auth check produced an unexpected shape' };
431
+ }
432
+ const status = parsed.status;
433
+ const authTypeRaw = parsed.authType;
434
+ const reasonRaw = parsed.reason;
435
+ if (status === 'ready') {
436
+ return {
437
+ ready: true,
438
+ authType: typeof authTypeRaw === 'string' ? authTypeRaw : null,
439
+ reason: null,
440
+ };
441
+ }
442
+ return {
443
+ ready: false,
444
+ authType: null,
445
+ reason: typeof reasonRaw === 'string'
446
+ ? reasonRaw
447
+ : typeof status === 'string'
448
+ ? status
449
+ : 'not ready',
450
+ };
451
+ }
452
+ catch (err) {
453
+ return { ready: false, authType: null, reason: `auth check failed: ${errorMessage(err)}` };
454
+ }
455
+ }
456
+ // ---------------------------------------------------------------------------------------------
457
+ // Catalog assembly
458
+ // ---------------------------------------------------------------------------------------------
459
+ async function buildProviderInfos(piBin, models) {
460
+ const providerIds = Array.from(new Set(models.map((m) => m.provider))).sort();
461
+ const readiness = await Promise.all(providerIds.map((id) => checkProviderReady(piBin, id)));
462
+ return providerIds.map((id, i) => {
463
+ const r = readiness[i];
464
+ return {
465
+ id,
466
+ ready: r.ready,
467
+ authType: r.authType,
468
+ reason: r.reason,
469
+ modelCount: models.filter((m) => m.provider === id).length,
470
+ };
471
+ });
472
+ }
473
+ async function loadFromStore(homeDir) {
474
+ const storePath = join(homeDir, '.pi', 'agent', 'models-store.json');
475
+ let text;
476
+ try {
477
+ text = await readFile(storePath, 'utf8');
478
+ }
479
+ catch {
480
+ return null; // missing (or unreadable) — caller falls back to the listing command
481
+ }
482
+ try {
483
+ const parsed = JSON.parse(text);
484
+ if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed))
485
+ return null;
486
+ return parsed;
487
+ }
488
+ catch {
489
+ return null; // corrupt store file — treated the same as "unavailable"
490
+ }
491
+ }
492
+ async function loadFromListing(piBin, overrides) {
493
+ let result;
494
+ try {
495
+ result = await runCommand(piBin, ['--list-models', '-ne']);
496
+ }
497
+ catch {
498
+ return null;
499
+ }
500
+ if (result.code !== 0)
501
+ return null;
502
+ const listed = parseListModelsOutput(result.stdout);
503
+ if (listed.length === 0)
504
+ return null;
505
+ return listedModelsToCatalogModels(listed, overrides);
506
+ }
507
+ function warnSkipped(count) {
508
+ if (count <= 0)
509
+ return;
510
+ const noun = count === 1 ? 'entry' : 'entries';
511
+ process.stderr.write(`council-review: skipped ${count} malformed catalog ${noun}\n`);
512
+ }
513
+ export async function loadCatalog(opts) {
514
+ const overrides = opts?.vendorOverrides ?? {};
515
+ const homeDir = opts?.homeDir ?? homedir();
516
+ const piBin = resolvePiBin(opts);
517
+ const store = await loadFromStore(homeDir);
518
+ if (store !== null) {
519
+ // The host's effective catalog layers `models.json` (overrides + additions) on top of the
520
+ // store; when we spawn the host itself (the listing fallback below) it has already done
521
+ // this merge before printing, but reading the store file directly bypasses that, so it must
522
+ // be replicated here.
523
+ const modelsJson = await loadModelsJson(homeDir);
524
+ const mergedStore = mergeModelsJson(store, modelsJson);
525
+ const { models, skipped } = catalogFromStore(mergedStore, overrides);
526
+ warnSkipped(skipped);
527
+ const providers = await buildProviderInfos(piBin, models);
528
+ return { providers, models, skipped, source: 'store' };
529
+ }
530
+ const listingModels = await loadFromListing(piBin, overrides);
531
+ if (listingModels === null) {
532
+ throw new DiscoveryError('No models could be discovered: the model catalog is missing and the host listing command failed or is unavailable.');
533
+ }
534
+ const providers = await buildProviderInfos(piBin, listingModels);
535
+ return { providers, models: listingModels, skipped: 0, source: 'listing' };
536
+ }
537
+ export function readyModels(c) {
538
+ const readyProviderIds = new Set(c.providers.filter((p) => p.ready).map((p) => p.id));
539
+ return c.models.filter((m) => readyProviderIds.has(m.provider));
540
+ }
541
+ export function findModel(c, provider, modelId) {
542
+ return c.models.find((m) => m.provider === provider && m.id === modelId);
543
+ }
544
+ //# sourceMappingURL=providers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"providers.js","sourceRoot":"","sources":["../src/providers.ts"],"names":[],"mappings":"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"}