@polderlabs/bizar 10.19.6 → 10.19.7
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/cli/commands/models.mjs
CHANGED
|
@@ -227,7 +227,15 @@ function normalizedModelIdentity(id) {
|
|
|
227
227
|
};
|
|
228
228
|
}
|
|
229
229
|
|
|
230
|
-
|
|
230
|
+
/**
|
|
231
|
+
* Build a per-model profile object from a Models.dev catalog row.
|
|
232
|
+
*
|
|
233
|
+
* Phase 1 (v10.19.7): in addition to the long-standing `name` / `family` /
|
|
234
|
+
* `capabilities` / `limits` / `metadata` fields, propagate Models.dev's
|
|
235
|
+
* `description` and `summary` onto the profile so Phase 3's status screen
|
|
236
|
+
* (10.19.9) can render the description without re-querying the catalog.
|
|
237
|
+
*/
|
|
238
|
+
export function toCapabilityProfile(gatewayId, match, matchType, confidence) {
|
|
231
239
|
const limit = match.limit && typeof match.limit === 'object' ? match.limit : {};
|
|
232
240
|
const modalities = match.modalities && typeof match.modalities === 'object' ? match.modalities : {};
|
|
233
241
|
return {
|
|
@@ -235,6 +243,8 @@ function toCapabilityProfile(gatewayId, match, matchType, confidence) {
|
|
|
235
243
|
baseModel: match.id,
|
|
236
244
|
name: typeof match.name === 'string' ? match.name : match.id,
|
|
237
245
|
family: typeof match.family === 'string' ? match.family : null,
|
|
246
|
+
description: typeof match.description === 'string' ? match.description : null,
|
|
247
|
+
summary: typeof match.summary === 'string' ? match.summary : null,
|
|
238
248
|
capabilities: {
|
|
239
249
|
attachment: match.attachment === true,
|
|
240
250
|
reasoning: match.reasoning === true,
|
|
@@ -265,6 +275,15 @@ function toCapabilityProfile(gatewayId, match, matchType, confidence) {
|
|
|
265
275
|
* Enrich gateway-discovered models with Models.dev profiles. Exact IDs win.
|
|
266
276
|
* A normalized/suffix match is accepted only when unique; ambiguous models
|
|
267
277
|
* remain unmatched rather than receiving guessed capabilities.
|
|
278
|
+
*
|
|
279
|
+
* Phase 1 (v10.19.7): when Models.dev has no row for the candidate AND the
|
|
280
|
+
* candidate carries gateway-supplied `_gateway.name` / `_gateway.description`,
|
|
281
|
+
* build a minimal `profile` so the picker row renderer can read
|
|
282
|
+
* `profile.name` / `profile.description` directly without dereferencing
|
|
283
|
+
* `_gateway`. Candidates whose `normalizeModels` output had no `_gateway`
|
|
284
|
+
* fields keep the legacy `profile === null` contract so `capabilityLabel`
|
|
285
|
+
* still returns `'metadata unavailable'` (Phase 2 owns the rewrite that
|
|
286
|
+
* lets a non-null profile render the `'metadata unavailable'` label).
|
|
268
287
|
*/
|
|
269
288
|
export function enrichModelsWithCapabilities(candidates, catalog) {
|
|
270
289
|
const entries = flattenModelsDevCatalog(catalog);
|
|
@@ -286,7 +305,47 @@ export function enrichModelsWithCapabilities(candidates, catalog) {
|
|
|
286
305
|
const profile = toCapabilityProfile(gatewayId, matches[0], 'unique-normalized-id', 0.7);
|
|
287
306
|
return { ...candidate, profile, contextWindow: profile.limits.contextTokens };
|
|
288
307
|
}
|
|
289
|
-
|
|
308
|
+
// Models.dev miss: if the candidate carries gateway-supplied label /
|
|
309
|
+
// description, build a minimal `profile` so the picker row renderer
|
|
310
|
+
// can read `profile.name` / `profile.description` directly. Candidates
|
|
311
|
+
// that arrived from `normalizeModels` WITHOUT any `_gateway` data keep
|
|
312
|
+
// the legacy `profile === null` contract so `capabilityLabel(null)`
|
|
313
|
+
// still returns `'metadata unavailable'` (Phase 2 owns that rewrite).
|
|
314
|
+
const gw = (candidate && typeof candidate._gateway === 'object' && candidate._gateway) || {};
|
|
315
|
+
const gatewayName = typeof gw.name === 'string' ? gw.name
|
|
316
|
+
: (typeof gw.display_name === 'string' ? gw.display_name : null);
|
|
317
|
+
const gatewayDescription = typeof gw.description === 'string' ? gw.description : null;
|
|
318
|
+
if (gatewayName === null && gatewayDescription === null) {
|
|
319
|
+
return { ...candidate, profile: null, contextWindow: null };
|
|
320
|
+
}
|
|
321
|
+
const fallbackProfile = {
|
|
322
|
+
gatewayId,
|
|
323
|
+
baseModel: gatewayId,
|
|
324
|
+
name: gatewayName,
|
|
325
|
+
family: null,
|
|
326
|
+
description: gatewayDescription,
|
|
327
|
+
summary: null,
|
|
328
|
+
capabilities: {
|
|
329
|
+
attachment: false,
|
|
330
|
+
reasoning: false,
|
|
331
|
+
toolCall: false,
|
|
332
|
+
structuredOutput: false,
|
|
333
|
+
temperature: true,
|
|
334
|
+
inputModalities: ['text'],
|
|
335
|
+
outputModalities: ['text'],
|
|
336
|
+
},
|
|
337
|
+
limits: { contextTokens: null, inputTokens: null, outputTokens: null },
|
|
338
|
+
releaseDate: null,
|
|
339
|
+
lastUpdated: null,
|
|
340
|
+
metadata: {
|
|
341
|
+
source: 'gateway-fallback',
|
|
342
|
+
sourceUrl: null,
|
|
343
|
+
retrievedAt: new Date().toISOString(),
|
|
344
|
+
matchType: 'gateway-fallback',
|
|
345
|
+
confidence: 0,
|
|
346
|
+
},
|
|
347
|
+
};
|
|
348
|
+
return { ...candidate, profile: fallbackProfile, contextWindow: null };
|
|
290
349
|
});
|
|
291
350
|
}
|
|
292
351
|
|
|
@@ -379,7 +438,24 @@ async function fetchOnce({ doFetch, url, authToken, timeoutMs }) {
|
|
|
379
438
|
}
|
|
380
439
|
}
|
|
381
440
|
|
|
382
|
-
|
|
441
|
+
/**
|
|
442
|
+
* Normalize the gateway `/models` response into the candidate-pool shape
|
|
443
|
+
* consumed by the picker.
|
|
444
|
+
*
|
|
445
|
+
* Phase 1 (v10.19.7): in addition to the existing `id` / `owned_by` / `kind`
|
|
446
|
+
* fields, preserve the gateway's optional `name` / `display_name` /
|
|
447
|
+
* `description` payload under a new `_gateway` sub-object. The picker row
|
|
448
|
+
* renderer reads `profile.name` / `profile.description`, so when the
|
|
449
|
+
* Models.dev enrichment misses (Phase 2) the renderer can still surface a
|
|
450
|
+
* gateway-supplied label or description rather than an id-derived fallback.
|
|
451
|
+
*
|
|
452
|
+
* NOTE: `_gateway` is in-memory only. `applyModels` never writes it to
|
|
453
|
+
* `model-router.json`; the persisted shape stays as it was before this
|
|
454
|
+
* change. See `models-namespace-sync.test.mjs#normalizeModels does not
|
|
455
|
+
* persist _gateway into userSelected on round-trip` for the regression
|
|
456
|
+
* pin.
|
|
457
|
+
*/
|
|
458
|
+
export function normalizeModels(body) {
|
|
383
459
|
if (!body || typeof body !== 'object') return [];
|
|
384
460
|
const list = Array.isArray(body.data) ? body.data : Array.isArray(body) ? body : [];
|
|
385
461
|
const out = [];
|
|
@@ -388,7 +464,11 @@ function normalizeModels(body) {
|
|
|
388
464
|
const id = typeof m.id === 'string' ? m.id.trim() : '';
|
|
389
465
|
if (!id) continue;
|
|
390
466
|
const owned = typeof m.owned_by === 'string' ? m.owned_by : '';
|
|
391
|
-
|
|
467
|
+
const gw = {};
|
|
468
|
+
if (typeof m.name === 'string' && m.name) gw.name = m.name;
|
|
469
|
+
if (typeof m.display_name === 'string' && m.display_name) gw.display_name = m.display_name;
|
|
470
|
+
if (typeof m.description === 'string' && m.description) gw.description = m.description;
|
|
471
|
+
out.push({ id, owned_by: owned, kind: classifyKind(id), _gateway: gw });
|
|
392
472
|
}
|
|
393
473
|
// Stable order — by id — so the picker does not shuffle between runs.
|
|
394
474
|
out.sort((a, b) => (a.id < b.id ? -1 : a.id > b.id ? 1 : 0));
|
package/package.json
CHANGED