@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.
@@ -227,7 +227,15 @@ function normalizedModelIdentity(id) {
227
227
  };
228
228
  }
229
229
 
230
- function toCapabilityProfile(gatewayId, match, matchType, confidence) {
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
- return { ...candidate, profile: null, contextWindow: null };
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
- function normalizeModels(body) {
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
- out.push({ id, owned_by: owned, kind: classifyKind(id) });
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@polderlabs/bizar",
3
- "version": "10.19.6",
3
+ "version": "10.19.7",
4
4
  "description": "Autonomous, human-in-the-loop multi-agent harness for Claude Code with guarded workflows, typed SDK primitives, and MCP tools.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -1,5 +1,5 @@
1
1
  /**
2
2
  * SDK version constant. Keep synchronized with the workspace package versions.
3
3
  */
4
- export declare const SDK_VERSION: "10.19.6";
4
+ export declare const SDK_VERSION: "10.19.7";
5
5
  //# sourceMappingURL=version.d.ts.map
@@ -1,5 +1,5 @@
1
1
  /**
2
2
  * SDK version constant. Keep synchronized with the workspace package versions.
3
3
  */
4
- export const SDK_VERSION = "10.19.6";
4
+ export const SDK_VERSION = "10.19.7";
5
5
  //# sourceMappingURL=version.js.map
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@polderlabs/bizar-sdk",
3
- "version": "10.19.6",
3
+ "version": "10.19.7",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",