@xynogen/pix-models 0.1.6 → 0.1.8

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 (2) hide show
  1. package/package.json +3 -2
  2. package/src/models.ts +30 -35
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xynogen/pix-models",
3
- "version": "0.1.6",
3
+ "version": "0.1.8",
4
4
  "description": "Pi extension — enhanced /models picker with BenchLM ranks",
5
5
  "type": "module",
6
6
  "main": "src/index.ts",
@@ -38,7 +38,8 @@
38
38
  "access": "public"
39
39
  },
40
40
  "dependencies": {
41
- "@xynogen/pix-data": "*"
41
+ "@xynogen/pix-data": "*",
42
+ "@xynogen/pix-pretty": "*"
42
43
  },
43
44
  "peerDependencies": {
44
45
  "@earendil-works/pi-coding-agent": "*",
package/src/models.ts CHANGED
@@ -12,15 +12,12 @@ import type {
12
12
  ExtensionAPI,
13
13
  ExtensionContext,
14
14
  } from "@earendil-works/pi-coding-agent";
15
- import { DynamicBorder } from "@earendil-works/pi-coding-agent";
16
15
  import {
17
- Container,
18
16
  fuzzyFilter,
19
17
  Input,
20
18
  matchesKey,
21
19
  type SelectItem,
22
20
  SelectList,
23
- Text,
24
21
  visibleWidth,
25
22
  } from "@earendil-works/pi-tui";
26
23
  import {
@@ -28,6 +25,7 @@ import {
28
25
  lookupBenchmark,
29
26
  lookupModelsDev,
30
27
  } from "@xynogen/pix-data";
28
+ import { frameLines, modalWidth } from "@xynogen/pix-pretty/modal-frame";
31
29
  import { patchOutBuiltinModelCommand } from "./patch-builtin";
32
30
 
33
31
  // ─── Pure logic (exported for tests) ─────────────────────────────────────────
@@ -148,7 +146,6 @@ async function showEnhancedPicker(
148
146
 
149
147
  const result = await ctx.ui.custom<string | null>(
150
148
  (_tui, theme, _kb, done) => {
151
- const container = new Container();
152
149
  const accent = "accent";
153
150
 
154
151
  // Find max rank width across all benchmarked rows for # padding
@@ -179,8 +176,9 @@ async function showEnhancedPicker(
179
176
  let rankPrefix: string;
180
177
  if (localRank) {
181
178
  const rankStr = String(localRank).padEnd(maxRankWidth);
182
- const rankColor =
183
- localRank <= 3 ? "success" : localRank <= 7 ? "warning" : "error";
179
+ // Color rank by the model's bench score (same scale as ⚡score),
180
+ // not by list position keeps the two colors consistent.
181
+ const rankColor = benchScoreColor(bench?.overallScore);
184
182
  rankPrefix = mute("#") + theme.fg(rankColor, rankStr);
185
183
  } else {
186
184
  rankPrefix = " ".repeat(maxRankWidth + 1);
@@ -235,19 +233,6 @@ async function showEnhancedPicker(
235
233
  )
236
234
  : 0;
237
235
 
238
- container.addChild(new DynamicBorder((s) => theme.fg(accent, s)));
239
- container.addChild(
240
- new Text(theme.fg(accent, theme.bold("󰚩 Select model"))),
241
- );
242
- container.addChild(
243
- new Text(
244
- theme.fg(
245
- "dim",
246
- "context · pricing · coding rank & score from modelgrep.com",
247
- ),
248
- ),
249
- );
250
-
251
236
  // Widest label (visible width, ANSI-stripped) so the model name
252
237
  // column never truncates to "…". Add gap headroom.
253
238
  const widestLabel = items.reduce(
@@ -316,25 +301,34 @@ async function showEnhancedPicker(
316
301
  internal.invalidate();
317
302
  };
318
303
 
319
- container.addChild(new Text(theme.fg("muted", "Search:")));
320
- container.addChild(search);
321
- container.addChild(list);
322
- container.addChild(
323
- new Text(
324
- theme.fg(
325
- "dim",
326
- "fuzzy search · ↑↓ navigate · enter select · esc cancel",
327
- ),
328
- ),
329
- );
330
- container.addChild(new DynamicBorder((s) => theme.fg(accent, s)));
331
-
332
304
  return {
333
305
  render(w: number) {
334
- return container.render(w);
306
+ const mw = modalWidth(w);
307
+ const inner = mw - 4; // CHROME = 2 border + 2 padding
308
+ const lines: string[] = [
309
+ theme.fg(accent, theme.bold("󰈩 Select model")),
310
+ theme.fg(
311
+ "dim",
312
+ "context · pricing · coding rank & score from modelgrep.com",
313
+ ),
314
+ theme.fg("muted", "Search:"),
315
+ ...search.render(inner),
316
+ ...list.render(inner),
317
+ theme.fg(
318
+ "dim",
319
+ "fuzzy search · ↑↓ navigate · enter select · esc cancel",
320
+ ),
321
+ ];
322
+ return frameLines({
323
+ width: mw,
324
+ lines,
325
+ color: (s) => theme.fg(accent, s),
326
+ bg: (s) => theme.bg("customMessageBg", s),
327
+ });
335
328
  },
336
329
  invalidate() {
337
- container.invalidate();
330
+ list.invalidate();
331
+ search.invalidate();
338
332
  },
339
333
  handleInput(data: string) {
340
334
  // Detect keys via pi-tui's own parser — the same recognition
@@ -349,10 +343,11 @@ async function showEnhancedPicker(
349
343
  search.handleInput?.(data);
350
344
  applyFuzzy(search.getValue?.() ?? "");
351
345
  }
352
- container.invalidate();
346
+ list.invalidate();
353
347
  },
354
348
  };
355
349
  },
350
+ { overlay: true },
356
351
  );
357
352
 
358
353
  if (!result) return;