@tangle-network/sandbox-ui 0.10.9 → 0.11.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/dist/{chunk-Z5PSS3VD.js → chunk-NKUPJC34.js} +453 -80
- package/dist/dashboard.d.ts +1 -1
- package/dist/dashboard.js +13 -1
- package/dist/globals.css +21 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +13 -1
- package/dist/styles.css +21 -0
- package/dist/{variant-list-DAhiR-7S.d.ts → variant-list-BrHYcBCk.d.ts} +120 -1
- package/package.json +1 -1
|
@@ -1274,9 +1274,376 @@ function BackendSelector({
|
|
|
1274
1274
|
] });
|
|
1275
1275
|
}
|
|
1276
1276
|
|
|
1277
|
+
// src/dashboard/harness-picker.tsx
|
|
1278
|
+
import { jsx as jsx12 } from "react/jsx-runtime";
|
|
1279
|
+
var HARNESS_OPTIONS = [
|
|
1280
|
+
{
|
|
1281
|
+
type: "opencode",
|
|
1282
|
+
label: "OpenCode",
|
|
1283
|
+
description: "Default agent \u2014 broad model support, deterministic streaming"
|
|
1284
|
+
},
|
|
1285
|
+
{
|
|
1286
|
+
type: "claude-code",
|
|
1287
|
+
label: "Claude Code",
|
|
1288
|
+
description: "Native Claude skills and tools (requires ANTHROPIC_API_KEY)"
|
|
1289
|
+
},
|
|
1290
|
+
{
|
|
1291
|
+
type: "codex",
|
|
1292
|
+
label: "Codex",
|
|
1293
|
+
description: "OpenAI Codex CLI (requires OPENAI_API_KEY)"
|
|
1294
|
+
},
|
|
1295
|
+
{
|
|
1296
|
+
type: "amp",
|
|
1297
|
+
label: "AMP",
|
|
1298
|
+
description: "Sourcegraph AMP agent"
|
|
1299
|
+
},
|
|
1300
|
+
{
|
|
1301
|
+
type: "factory-droids",
|
|
1302
|
+
label: "Factory Droids",
|
|
1303
|
+
description: "Factory Droid agent"
|
|
1304
|
+
},
|
|
1305
|
+
{
|
|
1306
|
+
type: "cli-base",
|
|
1307
|
+
label: "CLI base (no agent)",
|
|
1308
|
+
description: "Shell tools only \u2014 for non-AI scheduled tasks"
|
|
1309
|
+
}
|
|
1310
|
+
];
|
|
1311
|
+
function HarnessPicker({
|
|
1312
|
+
value,
|
|
1313
|
+
onChange,
|
|
1314
|
+
available,
|
|
1315
|
+
optionsOverride,
|
|
1316
|
+
label = "Agent harness",
|
|
1317
|
+
...rest
|
|
1318
|
+
}) {
|
|
1319
|
+
const allowed = new Set(available ?? HARNESS_OPTIONS.map((h) => h.type));
|
|
1320
|
+
const backends = HARNESS_OPTIONS.filter((h) => allowed.has(h.type)).map((h) => {
|
|
1321
|
+
const override = optionsOverride?.[h.type];
|
|
1322
|
+
return {
|
|
1323
|
+
type: h.type,
|
|
1324
|
+
label: override?.label ?? h.label,
|
|
1325
|
+
description: override?.description ?? h.description
|
|
1326
|
+
};
|
|
1327
|
+
});
|
|
1328
|
+
return /* @__PURE__ */ jsx12(
|
|
1329
|
+
BackendSelector,
|
|
1330
|
+
{
|
|
1331
|
+
backends,
|
|
1332
|
+
selected: value,
|
|
1333
|
+
onChange: (next) => onChange(next),
|
|
1334
|
+
label,
|
|
1335
|
+
...rest
|
|
1336
|
+
}
|
|
1337
|
+
);
|
|
1338
|
+
}
|
|
1339
|
+
|
|
1340
|
+
// src/dashboard/model-picker.tsx
|
|
1341
|
+
import * as React4 from "react";
|
|
1342
|
+
import { ChevronDown as ChevronDown2, Search, Sparkles, Zap, Brain, Star, Loader2 } from "lucide-react";
|
|
1343
|
+
import * as Popover from "@radix-ui/react-dropdown-menu";
|
|
1344
|
+
import { Fragment as Fragment7, jsx as jsx13, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
1345
|
+
function canonicalModelId(model) {
|
|
1346
|
+
const id = model.id;
|
|
1347
|
+
if (id.includes("/")) return id;
|
|
1348
|
+
const provider = model._provider ?? model.provider;
|
|
1349
|
+
return provider ? `${provider}/${id}` : id;
|
|
1350
|
+
}
|
|
1351
|
+
function formatPricing(pricing) {
|
|
1352
|
+
const prompt = Number(pricing?.prompt ?? 0);
|
|
1353
|
+
const completion = Number(pricing?.completion ?? 0);
|
|
1354
|
+
if (!prompt && !completion) return null;
|
|
1355
|
+
const fmt = (n) => {
|
|
1356
|
+
const perM = n * 1e6;
|
|
1357
|
+
if (perM === 0) return "0";
|
|
1358
|
+
if (perM >= 1) return `$${perM.toFixed(2)}`;
|
|
1359
|
+
return `$${perM.toFixed(2)}`;
|
|
1360
|
+
};
|
|
1361
|
+
return `${fmt(prompt)} / ${fmt(completion)} per 1M`;
|
|
1362
|
+
}
|
|
1363
|
+
function formatContext(ctx) {
|
|
1364
|
+
if (!ctx) return null;
|
|
1365
|
+
if (ctx >= 1e6) return `${(ctx / 1e6).toFixed(1)}M ctx`;
|
|
1366
|
+
if (ctx >= 1e3) return `${Math.round(ctx / 1e3)}k ctx`;
|
|
1367
|
+
return `${ctx} ctx`;
|
|
1368
|
+
}
|
|
1369
|
+
var DEFAULT_PRESETS = [
|
|
1370
|
+
{
|
|
1371
|
+
id: "fast",
|
|
1372
|
+
label: "Fast",
|
|
1373
|
+
hint: "Cheapest, lowest latency",
|
|
1374
|
+
icon: Zap,
|
|
1375
|
+
match: (models) => {
|
|
1376
|
+
const ids = models.map(canonicalModelId);
|
|
1377
|
+
return ids.find((m) => /gpt-5\.\d+-mini$/.test(m)) ?? ids.find((m) => /gpt-5-mini$/.test(m)) ?? ids.find((m) => m.endsWith("/claude-haiku-4.5")) ?? ids.find((m) => /haiku/.test(m));
|
|
1378
|
+
}
|
|
1379
|
+
},
|
|
1380
|
+
{
|
|
1381
|
+
id: "balanced",
|
|
1382
|
+
label: "Balanced",
|
|
1383
|
+
hint: "Best value for most chat",
|
|
1384
|
+
icon: Sparkles,
|
|
1385
|
+
match: (models) => {
|
|
1386
|
+
const ids = models.map(canonicalModelId);
|
|
1387
|
+
return ids.find((m) => /^openai\/gpt-5\.\d+$/.test(m)) ?? ids.find((m) => /^openai\/gpt-5$/.test(m)) ?? ids.find((m) => m.endsWith("/claude-sonnet-4-6")) ?? ids.find((m) => /sonnet/.test(m));
|
|
1388
|
+
}
|
|
1389
|
+
},
|
|
1390
|
+
{
|
|
1391
|
+
id: "best",
|
|
1392
|
+
label: "Best",
|
|
1393
|
+
hint: "Hardest reasoning, highest quality",
|
|
1394
|
+
icon: Brain,
|
|
1395
|
+
match: (models) => {
|
|
1396
|
+
const ids = models.map(canonicalModelId);
|
|
1397
|
+
return ids.find((m) => /^openai\/gpt-5\.\d+-pro$/.test(m)) ?? ids.find((m) => /^openai\/o3$/.test(m)) ?? ids.find((m) => m.endsWith("/claude-opus-4-7")) ?? ids.find((m) => /opus/.test(m));
|
|
1398
|
+
}
|
|
1399
|
+
}
|
|
1400
|
+
];
|
|
1401
|
+
function ModelPicker({
|
|
1402
|
+
value,
|
|
1403
|
+
onChange,
|
|
1404
|
+
models,
|
|
1405
|
+
loading = false,
|
|
1406
|
+
recents,
|
|
1407
|
+
presets = DEFAULT_PRESETS,
|
|
1408
|
+
excludeProviders,
|
|
1409
|
+
modalities,
|
|
1410
|
+
variant = "field",
|
|
1411
|
+
label = "Model",
|
|
1412
|
+
placeholder = "Choose a model",
|
|
1413
|
+
className,
|
|
1414
|
+
disabled
|
|
1415
|
+
}) {
|
|
1416
|
+
const [query, setQuery] = React4.useState("");
|
|
1417
|
+
const [open, setOpen] = React4.useState(false);
|
|
1418
|
+
const filtered = React4.useMemo(() => {
|
|
1419
|
+
const excluded = new Set((excludeProviders ?? []).map((p) => p.toLowerCase()));
|
|
1420
|
+
const allowedModalities = modalities ? new Set(modalities) : null;
|
|
1421
|
+
const q = query.trim().toLowerCase();
|
|
1422
|
+
return models.filter((m) => {
|
|
1423
|
+
const provider = (m._provider ?? m.provider ?? "").toLowerCase();
|
|
1424
|
+
if (excluded.has(provider)) return false;
|
|
1425
|
+
if (allowedModalities && m.architecture?.modality && !allowedModalities.has(m.architecture.modality)) return false;
|
|
1426
|
+
if (!q) return true;
|
|
1427
|
+
const id = canonicalModelId(m).toLowerCase();
|
|
1428
|
+
const name = (m.name ?? "").toLowerCase();
|
|
1429
|
+
return id.includes(q) || name.includes(q) || provider.includes(q);
|
|
1430
|
+
});
|
|
1431
|
+
}, [models, query, modalities, excludeProviders]);
|
|
1432
|
+
const grouped = React4.useMemo(() => {
|
|
1433
|
+
const groups = /* @__PURE__ */ new Map();
|
|
1434
|
+
for (const m of filtered) {
|
|
1435
|
+
const provider = m._provider ?? m.provider ?? "other";
|
|
1436
|
+
const list = groups.get(provider);
|
|
1437
|
+
if (list) list.push(m);
|
|
1438
|
+
else groups.set(provider, [m]);
|
|
1439
|
+
}
|
|
1440
|
+
return Array.from(groups.entries()).sort(([a], [b]) => a.localeCompare(b));
|
|
1441
|
+
}, [filtered]);
|
|
1442
|
+
const current = React4.useMemo(
|
|
1443
|
+
() => models.find((m) => canonicalModelId(m) === value),
|
|
1444
|
+
[models, value]
|
|
1445
|
+
);
|
|
1446
|
+
const currentLabel = current?.name ?? current?.id ?? value;
|
|
1447
|
+
const recentIds = React4.useMemo(() => {
|
|
1448
|
+
if (!recents?.length) return [];
|
|
1449
|
+
const lookup = new Map(models.map((m) => [canonicalModelId(m), m]));
|
|
1450
|
+
return recents.map((id) => lookup.get(id)).filter((m) => Boolean(m)).slice(0, 4);
|
|
1451
|
+
}, [recents, models]);
|
|
1452
|
+
const handleSelect = (id) => {
|
|
1453
|
+
onChange(id);
|
|
1454
|
+
setOpen(false);
|
|
1455
|
+
setQuery("");
|
|
1456
|
+
};
|
|
1457
|
+
const trigger = variant === "pill" ? /* @__PURE__ */ jsxs11(
|
|
1458
|
+
"button",
|
|
1459
|
+
{
|
|
1460
|
+
type: "button",
|
|
1461
|
+
disabled,
|
|
1462
|
+
className: cn(
|
|
1463
|
+
"inline-flex items-center gap-1.5 rounded-full border border-border bg-card",
|
|
1464
|
+
"px-2.5 py-1 text-xs font-medium text-foreground",
|
|
1465
|
+
"transition-colors duration-[var(--transition-fast)]",
|
|
1466
|
+
"hover:border-primary/30 hover:bg-accent/30",
|
|
1467
|
+
"focus:outline-none focus:border-primary/40",
|
|
1468
|
+
"data-[state=open]:border-primary/40 data-[state=open]:bg-accent/30",
|
|
1469
|
+
"disabled:opacity-50 disabled:cursor-not-allowed",
|
|
1470
|
+
className
|
|
1471
|
+
),
|
|
1472
|
+
children: [
|
|
1473
|
+
/* @__PURE__ */ jsx13(Sparkles, { className: "h-3 w-3 text-muted-foreground" }),
|
|
1474
|
+
/* @__PURE__ */ jsx13("span", { className: "truncate max-w-[160px]", children: currentLabel || placeholder }),
|
|
1475
|
+
/* @__PURE__ */ jsx13(ChevronDown2, { className: "h-3 w-3 text-muted-foreground transition-transform data-[state=open]:rotate-180" })
|
|
1476
|
+
]
|
|
1477
|
+
}
|
|
1478
|
+
) : /* @__PURE__ */ jsxs11(
|
|
1479
|
+
"button",
|
|
1480
|
+
{
|
|
1481
|
+
type: "button",
|
|
1482
|
+
disabled,
|
|
1483
|
+
className: cn(
|
|
1484
|
+
"flex w-full items-center justify-between gap-2 rounded-[var(--radius-md)]",
|
|
1485
|
+
"border border-border bg-card px-3 py-2.5 text-sm text-left",
|
|
1486
|
+
"transition-colors duration-[var(--transition-fast)]",
|
|
1487
|
+
"hover:border-primary/20 hover:bg-accent/30",
|
|
1488
|
+
"focus:outline-none focus:border-primary/30",
|
|
1489
|
+
"data-[state=open]:border-primary/30 data-[state=open]:bg-accent/30",
|
|
1490
|
+
"disabled:opacity-50 disabled:cursor-not-allowed",
|
|
1491
|
+
className
|
|
1492
|
+
),
|
|
1493
|
+
children: [
|
|
1494
|
+
/* @__PURE__ */ jsx13("span", { className: cn("truncate", current ? "text-foreground font-medium" : "text-muted-foreground"), children: currentLabel || placeholder }),
|
|
1495
|
+
/* @__PURE__ */ jsx13(ChevronDown2, { className: "h-4 w-4 shrink-0 text-muted-foreground transition-transform data-[state=open]:rotate-180" })
|
|
1496
|
+
]
|
|
1497
|
+
}
|
|
1498
|
+
);
|
|
1499
|
+
return /* @__PURE__ */ jsxs11("div", { className: cn(variant === "field" ? "space-y-1.5" : "inline-flex", variant === "field" ? className : void 0), children: [
|
|
1500
|
+
variant === "field" && label && /* @__PURE__ */ jsx13("label", { className: "block text-xs font-medium text-muted-foreground uppercase tracking-[0.06em]", children: label }),
|
|
1501
|
+
/* @__PURE__ */ jsxs11(Popover.Root, { open, onOpenChange: setOpen, children: [
|
|
1502
|
+
/* @__PURE__ */ jsx13(Popover.Trigger, { asChild: true, children: trigger }),
|
|
1503
|
+
/* @__PURE__ */ jsx13(Popover.Portal, { children: /* @__PURE__ */ jsxs11(
|
|
1504
|
+
Popover.Content,
|
|
1505
|
+
{
|
|
1506
|
+
sideOffset: 4,
|
|
1507
|
+
align: variant === "pill" ? "start" : "start",
|
|
1508
|
+
className: cn(
|
|
1509
|
+
"z-50 w-[var(--radix-dropdown-menu-trigger-width)] min-w-[320px] max-w-[460px]",
|
|
1510
|
+
"max-h-[440px] overflow-hidden flex flex-col",
|
|
1511
|
+
"rounded-[var(--radius-md)] border border-border bg-card shadow-[var(--shadow-dropdown)]",
|
|
1512
|
+
"data-[state=open]:animate-in data-[state=closed]:animate-out",
|
|
1513
|
+
"data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
|
|
1514
|
+
"data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95"
|
|
1515
|
+
),
|
|
1516
|
+
children: [
|
|
1517
|
+
/* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-2 border-b border-border px-3 py-2", children: [
|
|
1518
|
+
/* @__PURE__ */ jsx13(Search, { className: "h-3.5 w-3.5 shrink-0 text-muted-foreground" }),
|
|
1519
|
+
/* @__PURE__ */ jsx13(
|
|
1520
|
+
"input",
|
|
1521
|
+
{
|
|
1522
|
+
type: "text",
|
|
1523
|
+
value: query,
|
|
1524
|
+
onChange: (e) => setQuery(e.target.value),
|
|
1525
|
+
placeholder: "Search models...",
|
|
1526
|
+
autoFocus: true,
|
|
1527
|
+
className: "flex-1 bg-transparent text-sm outline-none placeholder:text-muted-foreground"
|
|
1528
|
+
}
|
|
1529
|
+
),
|
|
1530
|
+
loading && /* @__PURE__ */ jsx13(Loader2, { className: "h-3.5 w-3.5 animate-spin text-muted-foreground" })
|
|
1531
|
+
] }),
|
|
1532
|
+
/* @__PURE__ */ jsxs11("div", { className: "flex-1 overflow-y-auto", children: [
|
|
1533
|
+
!query && presets.length > 0 && /* @__PURE__ */ jsx13(Section, { label: "Presets", children: presets.map((preset) => {
|
|
1534
|
+
const Icon2 = preset.icon ?? Star;
|
|
1535
|
+
const matchedId = preset.match(models);
|
|
1536
|
+
if (!matchedId) return null;
|
|
1537
|
+
const matched = models.find((m) => canonicalModelId(m) === matchedId);
|
|
1538
|
+
const isCurrent = matchedId === value;
|
|
1539
|
+
return /* @__PURE__ */ jsxs11(
|
|
1540
|
+
PickerItem,
|
|
1541
|
+
{
|
|
1542
|
+
onSelect: () => handleSelect(matchedId),
|
|
1543
|
+
active: isCurrent,
|
|
1544
|
+
children: [
|
|
1545
|
+
/* @__PURE__ */ jsx13(Icon2, { className: "h-3.5 w-3.5 shrink-0 text-[var(--accent-text)]" }),
|
|
1546
|
+
/* @__PURE__ */ jsxs11("div", { className: "min-w-0 flex-1", children: [
|
|
1547
|
+
/* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-1.5", children: [
|
|
1548
|
+
/* @__PURE__ */ jsx13("span", { className: "text-sm font-medium", children: preset.label }),
|
|
1549
|
+
/* @__PURE__ */ jsxs11("span", { className: "text-[10px] text-muted-foreground truncate", children: [
|
|
1550
|
+
"\u2192 ",
|
|
1551
|
+
matched?.name ?? matchedId
|
|
1552
|
+
] })
|
|
1553
|
+
] }),
|
|
1554
|
+
/* @__PURE__ */ jsx13("span", { className: "text-xs text-muted-foreground", children: preset.hint })
|
|
1555
|
+
] })
|
|
1556
|
+
]
|
|
1557
|
+
},
|
|
1558
|
+
preset.id
|
|
1559
|
+
);
|
|
1560
|
+
}) }),
|
|
1561
|
+
!query && recentIds.length > 0 && /* @__PURE__ */ jsx13(Section, { label: "Recent", children: recentIds.map((m) => /* @__PURE__ */ jsx13(
|
|
1562
|
+
ModelRow,
|
|
1563
|
+
{
|
|
1564
|
+
model: m,
|
|
1565
|
+
active: canonicalModelId(m) === value,
|
|
1566
|
+
onSelect: handleSelect
|
|
1567
|
+
},
|
|
1568
|
+
`recent-${canonicalModelId(m)}`
|
|
1569
|
+
)) }),
|
|
1570
|
+
grouped.length === 0 ? /* @__PURE__ */ jsx13("div", { className: "px-3 py-8 text-center text-xs text-muted-foreground", children: loading ? "Loading models..." : query ? "No models match." : "No models available." }) : grouped.map(([provider, list]) => /* @__PURE__ */ jsx13(Section, { label: provider, children: list.map((m) => /* @__PURE__ */ jsx13(
|
|
1571
|
+
ModelRow,
|
|
1572
|
+
{
|
|
1573
|
+
model: m,
|
|
1574
|
+
active: canonicalModelId(m) === value,
|
|
1575
|
+
onSelect: handleSelect
|
|
1576
|
+
},
|
|
1577
|
+
canonicalModelId(m)
|
|
1578
|
+
)) }, provider))
|
|
1579
|
+
] }),
|
|
1580
|
+
/* @__PURE__ */ jsxs11("div", { className: "border-t border-border px-3 py-1.5 text-[10px] text-muted-foreground", children: [
|
|
1581
|
+
filtered.length,
|
|
1582
|
+
" of ",
|
|
1583
|
+
models.length,
|
|
1584
|
+
" model",
|
|
1585
|
+
models.length === 1 ? "" : "s"
|
|
1586
|
+
] })
|
|
1587
|
+
]
|
|
1588
|
+
}
|
|
1589
|
+
) })
|
|
1590
|
+
] })
|
|
1591
|
+
] });
|
|
1592
|
+
}
|
|
1593
|
+
function Section({ label, children }) {
|
|
1594
|
+
return /* @__PURE__ */ jsxs11("div", { className: "py-1", children: [
|
|
1595
|
+
/* @__PURE__ */ jsx13("div", { className: "px-3 pt-1.5 pb-0.5 text-[10px] font-mono uppercase tracking-widest text-muted-foreground", children: label }),
|
|
1596
|
+
/* @__PURE__ */ jsx13("div", { children })
|
|
1597
|
+
] });
|
|
1598
|
+
}
|
|
1599
|
+
function PickerItem({
|
|
1600
|
+
onSelect,
|
|
1601
|
+
active,
|
|
1602
|
+
children
|
|
1603
|
+
}) {
|
|
1604
|
+
return /* @__PURE__ */ jsx13(
|
|
1605
|
+
Popover.Item,
|
|
1606
|
+
{
|
|
1607
|
+
onSelect: (e) => {
|
|
1608
|
+
e.preventDefault();
|
|
1609
|
+
onSelect();
|
|
1610
|
+
},
|
|
1611
|
+
className: cn(
|
|
1612
|
+
"flex cursor-pointer items-start gap-2 px-3 py-2 outline-none",
|
|
1613
|
+
"transition-colors duration-[var(--transition-fast)]",
|
|
1614
|
+
"hover:bg-accent/40 focus:bg-accent/40",
|
|
1615
|
+
active && "bg-[var(--accent-surface-soft)] text-[var(--accent-text)]"
|
|
1616
|
+
),
|
|
1617
|
+
children
|
|
1618
|
+
}
|
|
1619
|
+
);
|
|
1620
|
+
}
|
|
1621
|
+
function ModelRow({
|
|
1622
|
+
model,
|
|
1623
|
+
active,
|
|
1624
|
+
onSelect
|
|
1625
|
+
}) {
|
|
1626
|
+
const id = canonicalModelId(model);
|
|
1627
|
+
const pricing = formatPricing(model.pricing);
|
|
1628
|
+
const ctx = formatContext(model.context_length);
|
|
1629
|
+
return /* @__PURE__ */ jsx13(PickerItem, { onSelect: () => onSelect(id), active, children: /* @__PURE__ */ jsxs11("div", { className: "min-w-0 flex-1", children: [
|
|
1630
|
+
/* @__PURE__ */ jsxs11("div", { className: "flex items-baseline justify-between gap-2", children: [
|
|
1631
|
+
/* @__PURE__ */ jsx13("span", { className: "text-sm font-medium truncate", children: model.name ?? model.id }),
|
|
1632
|
+
ctx && /* @__PURE__ */ jsx13("span", { className: "shrink-0 text-[10px] text-muted-foreground", children: ctx })
|
|
1633
|
+
] }),
|
|
1634
|
+
/* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-2 text-[11px] text-muted-foreground", children: [
|
|
1635
|
+
/* @__PURE__ */ jsx13("span", { className: "truncate", children: id }),
|
|
1636
|
+
pricing && /* @__PURE__ */ jsxs11(Fragment7, { children: [
|
|
1637
|
+
/* @__PURE__ */ jsx13("span", { className: "shrink-0", children: "\xB7" }),
|
|
1638
|
+
/* @__PURE__ */ jsx13("span", { className: "shrink-0 font-mono", children: pricing })
|
|
1639
|
+
] })
|
|
1640
|
+
] })
|
|
1641
|
+
] }) });
|
|
1642
|
+
}
|
|
1643
|
+
|
|
1277
1644
|
// src/dashboard/profile-selector.tsx
|
|
1278
|
-
import { Check as Check2, ChevronDown as
|
|
1279
|
-
import { Fragment as
|
|
1645
|
+
import { Check as Check2, ChevronDown as ChevronDown3, Plus as Plus3, Settings } from "lucide-react";
|
|
1646
|
+
import { Fragment as Fragment8, jsx as jsx14, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
1280
1647
|
function ProfileSelector({
|
|
1281
1648
|
profiles,
|
|
1282
1649
|
selectedId,
|
|
@@ -1291,77 +1658,77 @@ function ProfileSelector({
|
|
|
1291
1658
|
const selected = profiles.find((p) => p.id === selectedId);
|
|
1292
1659
|
const builtinProfiles = profiles.filter((p) => p.is_builtin);
|
|
1293
1660
|
const customProfiles = profiles.filter((p) => !p.is_builtin);
|
|
1294
|
-
return /* @__PURE__ */
|
|
1295
|
-
label && /* @__PURE__ */
|
|
1296
|
-
/* @__PURE__ */
|
|
1297
|
-
/* @__PURE__ */
|
|
1298
|
-
/* @__PURE__ */
|
|
1299
|
-
/* @__PURE__ */
|
|
1661
|
+
return /* @__PURE__ */ jsxs12("div", { className, children: [
|
|
1662
|
+
label && /* @__PURE__ */ jsx14("label", { className: "mb-2 block font-medium text-sm", children: label }),
|
|
1663
|
+
/* @__PURE__ */ jsxs12(DropdownMenu, { children: [
|
|
1664
|
+
/* @__PURE__ */ jsx14(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxs12(Button, { variant: "outline", className: "w-full justify-between", children: [
|
|
1665
|
+
/* @__PURE__ */ jsx14("span", { className: "truncate", children: selected ? selected.name : placeholder }),
|
|
1666
|
+
/* @__PURE__ */ jsx14(ChevronDown3, { className: "ml-2 h-4 w-4 shrink-0 opacity-50" })
|
|
1300
1667
|
] }) }),
|
|
1301
|
-
/* @__PURE__ */
|
|
1302
|
-
/* @__PURE__ */
|
|
1668
|
+
/* @__PURE__ */ jsxs12(DropdownMenuContent, { className: "w-[300px]", align: "start", children: [
|
|
1669
|
+
/* @__PURE__ */ jsxs12(
|
|
1303
1670
|
DropdownMenuItem,
|
|
1304
1671
|
{
|
|
1305
1672
|
onClick: () => onSelect(null),
|
|
1306
1673
|
className: "flex items-center justify-between",
|
|
1307
1674
|
children: [
|
|
1308
|
-
/* @__PURE__ */
|
|
1309
|
-
!selectedId && /* @__PURE__ */
|
|
1675
|
+
/* @__PURE__ */ jsx14("span", { children: placeholder }),
|
|
1676
|
+
!selectedId && /* @__PURE__ */ jsx14(Check2, { className: "h-4 w-4 text-[var(--surface-success-text)]" })
|
|
1310
1677
|
]
|
|
1311
1678
|
}
|
|
1312
1679
|
),
|
|
1313
|
-
builtinProfiles.length > 0 && /* @__PURE__ */
|
|
1314
|
-
/* @__PURE__ */
|
|
1315
|
-
/* @__PURE__ */
|
|
1316
|
-
builtinProfiles.map((profile) => /* @__PURE__ */
|
|
1680
|
+
builtinProfiles.length > 0 && /* @__PURE__ */ jsxs12(Fragment8, { children: [
|
|
1681
|
+
/* @__PURE__ */ jsx14(DropdownMenuSeparator, {}),
|
|
1682
|
+
/* @__PURE__ */ jsx14(DropdownMenuLabel, { children: "Built-in Profiles" }),
|
|
1683
|
+
builtinProfiles.map((profile) => /* @__PURE__ */ jsxs12(
|
|
1317
1684
|
DropdownMenuItem,
|
|
1318
1685
|
{
|
|
1319
1686
|
onClick: () => onSelect(profile),
|
|
1320
1687
|
className: "flex flex-col items-start gap-1",
|
|
1321
1688
|
children: [
|
|
1322
|
-
/* @__PURE__ */
|
|
1323
|
-
/* @__PURE__ */
|
|
1324
|
-
/* @__PURE__ */
|
|
1325
|
-
profile.extends && /* @__PURE__ */
|
|
1689
|
+
/* @__PURE__ */ jsxs12("div", { className: "flex w-full items-center justify-between", children: [
|
|
1690
|
+
/* @__PURE__ */ jsxs12("div", { className: "flex items-center gap-2", children: [
|
|
1691
|
+
/* @__PURE__ */ jsx14("span", { className: "font-medium", children: profile.name }),
|
|
1692
|
+
profile.extends && /* @__PURE__ */ jsxs12(Badge, { variant: "secondary", className: "border-0 text-xs", children: [
|
|
1326
1693
|
"extends ",
|
|
1327
1694
|
profile.extends
|
|
1328
1695
|
] })
|
|
1329
1696
|
] }),
|
|
1330
|
-
selectedId === profile.id && /* @__PURE__ */
|
|
1697
|
+
selectedId === profile.id && /* @__PURE__ */ jsx14(Check2, { className: "h-4 w-4 text-[var(--surface-success-text)]" })
|
|
1331
1698
|
] }),
|
|
1332
|
-
profile.description && /* @__PURE__ */
|
|
1699
|
+
profile.description && /* @__PURE__ */ jsx14("span", { className: "line-clamp-1 text-muted-foreground text-xs", children: profile.description })
|
|
1333
1700
|
]
|
|
1334
1701
|
},
|
|
1335
1702
|
profile.id
|
|
1336
1703
|
))
|
|
1337
1704
|
] }),
|
|
1338
|
-
customProfiles.length > 0 && /* @__PURE__ */
|
|
1339
|
-
/* @__PURE__ */
|
|
1340
|
-
/* @__PURE__ */
|
|
1341
|
-
customProfiles.map((profile) => /* @__PURE__ */
|
|
1705
|
+
customProfiles.length > 0 && /* @__PURE__ */ jsxs12(Fragment8, { children: [
|
|
1706
|
+
/* @__PURE__ */ jsx14(DropdownMenuSeparator, {}),
|
|
1707
|
+
/* @__PURE__ */ jsx14(DropdownMenuLabel, { children: "Custom Profiles" }),
|
|
1708
|
+
customProfiles.map((profile) => /* @__PURE__ */ jsxs12(
|
|
1342
1709
|
DropdownMenuItem,
|
|
1343
1710
|
{
|
|
1344
1711
|
onClick: () => onSelect(profile),
|
|
1345
1712
|
className: "flex flex-col items-start gap-1",
|
|
1346
1713
|
children: [
|
|
1347
|
-
/* @__PURE__ */
|
|
1348
|
-
/* @__PURE__ */
|
|
1349
|
-
/* @__PURE__ */
|
|
1350
|
-
profile.model && /* @__PURE__ */
|
|
1714
|
+
/* @__PURE__ */ jsxs12("div", { className: "flex w-full items-center justify-between", children: [
|
|
1715
|
+
/* @__PURE__ */ jsxs12("div", { className: "flex items-center gap-2", children: [
|
|
1716
|
+
/* @__PURE__ */ jsx14("span", { className: "font-medium", children: profile.name }),
|
|
1717
|
+
profile.model && /* @__PURE__ */ jsx14(Badge, { variant: "secondary", className: "border-0 text-xs", children: profile.model.split("/").pop() })
|
|
1351
1718
|
] }),
|
|
1352
|
-
selectedId === profile.id && /* @__PURE__ */
|
|
1719
|
+
selectedId === profile.id && /* @__PURE__ */ jsx14(Check2, { className: "h-4 w-4 text-[var(--surface-success-text)]" })
|
|
1353
1720
|
] }),
|
|
1354
|
-
profile.description && /* @__PURE__ */
|
|
1355
|
-
showMetrics && profile.metrics && profile.metrics.total_runs > 0 && /* @__PURE__ */
|
|
1356
|
-
/* @__PURE__ */
|
|
1721
|
+
profile.description && /* @__PURE__ */ jsx14("span", { className: "line-clamp-1 text-muted-foreground text-xs", children: profile.description }),
|
|
1722
|
+
showMetrics && profile.metrics && profile.metrics.total_runs > 0 && /* @__PURE__ */ jsxs12("div", { className: "flex gap-3 text-muted-foreground text-xs", children: [
|
|
1723
|
+
/* @__PURE__ */ jsxs12("span", { children: [
|
|
1357
1724
|
profile.metrics.total_runs,
|
|
1358
1725
|
" runs"
|
|
1359
1726
|
] }),
|
|
1360
|
-
/* @__PURE__ */
|
|
1727
|
+
/* @__PURE__ */ jsxs12("span", { children: [
|
|
1361
1728
|
profile.metrics.success_rate.toFixed(0),
|
|
1362
1729
|
"% success"
|
|
1363
1730
|
] }),
|
|
1364
|
-
/* @__PURE__ */
|
|
1731
|
+
/* @__PURE__ */ jsxs12("span", { children: [
|
|
1365
1732
|
"~",
|
|
1366
1733
|
(profile.metrics.avg_duration_ms / 1e3).toFixed(1),
|
|
1367
1734
|
"s avg"
|
|
@@ -1372,26 +1739,26 @@ function ProfileSelector({
|
|
|
1372
1739
|
profile.id
|
|
1373
1740
|
))
|
|
1374
1741
|
] }),
|
|
1375
|
-
(onCreateClick || onManageClick) && /* @__PURE__ */
|
|
1376
|
-
/* @__PURE__ */
|
|
1377
|
-
onCreateClick && /* @__PURE__ */
|
|
1742
|
+
(onCreateClick || onManageClick) && /* @__PURE__ */ jsxs12(Fragment8, { children: [
|
|
1743
|
+
/* @__PURE__ */ jsx14(DropdownMenuSeparator, {}),
|
|
1744
|
+
onCreateClick && /* @__PURE__ */ jsxs12(
|
|
1378
1745
|
DropdownMenuItem,
|
|
1379
1746
|
{
|
|
1380
1747
|
onClick: onCreateClick,
|
|
1381
1748
|
className: "text-[var(--surface-info-text)]",
|
|
1382
1749
|
children: [
|
|
1383
|
-
/* @__PURE__ */
|
|
1750
|
+
/* @__PURE__ */ jsx14(Plus3, { className: "mr-2 h-4 w-4" }),
|
|
1384
1751
|
"Create New Profile"
|
|
1385
1752
|
]
|
|
1386
1753
|
}
|
|
1387
1754
|
),
|
|
1388
|
-
onManageClick && /* @__PURE__ */
|
|
1755
|
+
onManageClick && /* @__PURE__ */ jsxs12(
|
|
1389
1756
|
DropdownMenuItem,
|
|
1390
1757
|
{
|
|
1391
1758
|
onClick: onManageClick,
|
|
1392
1759
|
className: "text-muted-foreground",
|
|
1393
1760
|
children: [
|
|
1394
|
-
/* @__PURE__ */
|
|
1761
|
+
/* @__PURE__ */ jsx14(Settings, { className: "mr-2 h-4 w-4" }),
|
|
1395
1762
|
"Manage Profiles"
|
|
1396
1763
|
]
|
|
1397
1764
|
}
|
|
@@ -1417,26 +1784,26 @@ function ProfileComparison({
|
|
|
1417
1784
|
const fastestProfile = profilesWithMetrics.reduce(
|
|
1418
1785
|
(best, p) => (p.metrics?.avg_duration_ms ?? Number.POSITIVE_INFINITY) < (best.metrics?.avg_duration_ms ?? Number.POSITIVE_INFINITY) ? p : best
|
|
1419
1786
|
);
|
|
1420
|
-
return /* @__PURE__ */
|
|
1421
|
-
/* @__PURE__ */
|
|
1422
|
-
/* @__PURE__ */
|
|
1787
|
+
return /* @__PURE__ */ jsxs12("div", { className: `rounded-lg border border-border p-4 ${className ?? ""}`, children: [
|
|
1788
|
+
/* @__PURE__ */ jsx14("h4", { className: "mb-3 font-medium text-sm", children: "Profile Performance" }),
|
|
1789
|
+
/* @__PURE__ */ jsx14("div", { className: "space-y-3", children: profilesWithMetrics.map((profile) => {
|
|
1423
1790
|
const isBestSuccess = profile.id === bestSuccess.id;
|
|
1424
1791
|
const isFastest = profile.id === fastestProfile.id;
|
|
1425
|
-
return /* @__PURE__ */
|
|
1792
|
+
return /* @__PURE__ */ jsxs12(
|
|
1426
1793
|
"div",
|
|
1427
1794
|
{
|
|
1428
1795
|
className: "flex items-center justify-between gap-4",
|
|
1429
1796
|
children: [
|
|
1430
|
-
/* @__PURE__ */
|
|
1431
|
-
/* @__PURE__ */
|
|
1432
|
-
isBestSuccess && /* @__PURE__ */
|
|
1433
|
-
isFastest && !isBestSuccess && /* @__PURE__ */
|
|
1797
|
+
/* @__PURE__ */ jsxs12("div", { className: "flex items-center gap-2", children: [
|
|
1798
|
+
/* @__PURE__ */ jsx14("span", { className: "font-medium", children: profile.name }),
|
|
1799
|
+
isBestSuccess && /* @__PURE__ */ jsx14(Badge, { className: "border border-[var(--surface-success-border)] bg-[var(--surface-success-bg)] text-[var(--surface-success-text)] text-xs", children: "Best Success" }),
|
|
1800
|
+
isFastest && !isBestSuccess && /* @__PURE__ */ jsx14(Badge, { className: "border border-[var(--surface-info-border)] bg-[var(--surface-info-bg)] text-[var(--surface-info-text)] text-xs", children: "Fastest" })
|
|
1434
1801
|
] }),
|
|
1435
|
-
/* @__PURE__ */
|
|
1436
|
-
/* @__PURE__ */
|
|
1437
|
-
/* @__PURE__ */
|
|
1802
|
+
/* @__PURE__ */ jsxs12("div", { className: "flex items-center gap-4 text-sm", children: [
|
|
1803
|
+
/* @__PURE__ */ jsxs12("span", { children: [
|
|
1804
|
+
/* @__PURE__ */ jsx14("span", { className: "text-muted-foreground", children: "Success:" }),
|
|
1438
1805
|
" ",
|
|
1439
|
-
/* @__PURE__ */
|
|
1806
|
+
/* @__PURE__ */ jsxs12(
|
|
1440
1807
|
"span",
|
|
1441
1808
|
{
|
|
1442
1809
|
className: (profile.metrics?.success_rate ?? 0) >= 80 ? "text-[var(--surface-success-text)]" : (profile.metrics?.success_rate ?? 0) >= 50 ? "text-[var(--surface-warning-text)]" : "text-[var(--surface-danger-text)]",
|
|
@@ -1447,13 +1814,13 @@ function ProfileComparison({
|
|
|
1447
1814
|
}
|
|
1448
1815
|
)
|
|
1449
1816
|
] }),
|
|
1450
|
-
/* @__PURE__ */
|
|
1451
|
-
/* @__PURE__ */
|
|
1817
|
+
/* @__PURE__ */ jsxs12("span", { children: [
|
|
1818
|
+
/* @__PURE__ */ jsx14("span", { className: "text-muted-foreground", children: "Avg:" }),
|
|
1452
1819
|
" ",
|
|
1453
1820
|
((profile.metrics?.avg_duration_ms ?? 0) / 1e3).toFixed(1),
|
|
1454
1821
|
"s"
|
|
1455
1822
|
] }),
|
|
1456
|
-
/* @__PURE__ */
|
|
1823
|
+
/* @__PURE__ */ jsxs12("span", { className: "text-muted-foreground", children: [
|
|
1457
1824
|
profile.metrics?.total_runs,
|
|
1458
1825
|
" runs"
|
|
1459
1826
|
] })
|
|
@@ -1472,12 +1839,12 @@ import {
|
|
|
1472
1839
|
CheckCircle2,
|
|
1473
1840
|
Clock as Clock2,
|
|
1474
1841
|
ExternalLink,
|
|
1475
|
-
Loader2,
|
|
1842
|
+
Loader2 as Loader22,
|
|
1476
1843
|
Timer,
|
|
1477
1844
|
X,
|
|
1478
1845
|
XCircle
|
|
1479
1846
|
} from "lucide-react";
|
|
1480
|
-
import { Fragment as
|
|
1847
|
+
import { Fragment as Fragment9, jsx as jsx15, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
1481
1848
|
var statusConfig = {
|
|
1482
1849
|
pending: {
|
|
1483
1850
|
icon: Clock2,
|
|
@@ -1488,7 +1855,7 @@ var statusConfig = {
|
|
|
1488
1855
|
animate: false
|
|
1489
1856
|
},
|
|
1490
1857
|
running: {
|
|
1491
|
-
icon:
|
|
1858
|
+
icon: Loader22,
|
|
1492
1859
|
color: "text-primary",
|
|
1493
1860
|
bg: "bg-[var(--accent-surface-soft)]",
|
|
1494
1861
|
border: "border-border",
|
|
@@ -1561,19 +1928,19 @@ function VariantList({
|
|
|
1561
1928
|
isActioning,
|
|
1562
1929
|
className
|
|
1563
1930
|
}) {
|
|
1564
|
-
return /* @__PURE__ */
|
|
1931
|
+
return /* @__PURE__ */ jsx15("div", { className: `space-y-2 ${className || ""}`, children: variants.map((variant) => {
|
|
1565
1932
|
const status = statusConfig[variant.status];
|
|
1566
1933
|
const StatusIcon = status.icon;
|
|
1567
1934
|
const isSelected = variant.id === selectedId;
|
|
1568
|
-
return /* @__PURE__ */
|
|
1935
|
+
return /* @__PURE__ */ jsxs13(
|
|
1569
1936
|
"div",
|
|
1570
1937
|
{
|
|
1571
1938
|
className: `cursor-pointer rounded-lg border px-3 py-2.5 transition-colors ${isSelected ? "border-primary/30 bg-[var(--accent-surface-soft)]" : "border-border bg-card hover:border-primary/20 hover:bg-muted/50"}`,
|
|
1572
1939
|
onClick: () => onSelect?.(variant.id),
|
|
1573
1940
|
children: [
|
|
1574
|
-
/* @__PURE__ */
|
|
1575
|
-
/* @__PURE__ */
|
|
1576
|
-
/* @__PURE__ */
|
|
1941
|
+
/* @__PURE__ */ jsxs13("div", { className: "flex items-center gap-2", children: [
|
|
1942
|
+
/* @__PURE__ */ jsxs13(Badge, { className: `shrink-0 ${status.bg} ${status.border} ${status.color}`, children: [
|
|
1943
|
+
/* @__PURE__ */ jsx15(
|
|
1577
1944
|
StatusIcon,
|
|
1578
1945
|
{
|
|
1579
1946
|
className: `mr-1 h-3 w-3 ${status.animate ? "animate-spin" : ""}`
|
|
@@ -1581,27 +1948,27 @@ function VariantList({
|
|
|
1581
1948
|
),
|
|
1582
1949
|
status.label
|
|
1583
1950
|
] }),
|
|
1584
|
-
/* @__PURE__ */
|
|
1585
|
-
variant.sublabel && /* @__PURE__ */
|
|
1951
|
+
/* @__PURE__ */ jsx15("span", { className: "truncate text-sm font-medium text-foreground", children: variant.label }),
|
|
1952
|
+
variant.sublabel && /* @__PURE__ */ jsxs13("span", { className: "shrink-0 text-xs text-muted-foreground", children: [
|
|
1586
1953
|
"(",
|
|
1587
1954
|
variant.sublabel,
|
|
1588
1955
|
")"
|
|
1589
1956
|
] }),
|
|
1590
|
-
variant.durationMs && /* @__PURE__ */
|
|
1591
|
-
/* @__PURE__ */
|
|
1957
|
+
variant.durationMs && /* @__PURE__ */ jsxs13("span", { className: "flex shrink-0 items-center gap-1 text-xs text-muted-foreground", children: [
|
|
1958
|
+
/* @__PURE__ */ jsx15(Timer, { className: "h-3 w-3" }),
|
|
1592
1959
|
(variant.durationMs / 1e3).toFixed(1),
|
|
1593
1960
|
"s"
|
|
1594
1961
|
] }),
|
|
1595
|
-
/* @__PURE__ */
|
|
1596
|
-
variant.outcome && /* @__PURE__ */
|
|
1962
|
+
/* @__PURE__ */ jsxs13("div", { className: "ml-auto flex shrink-0 items-center gap-1.5", children: [
|
|
1963
|
+
variant.outcome && /* @__PURE__ */ jsx15(
|
|
1597
1964
|
Badge,
|
|
1598
1965
|
{
|
|
1599
1966
|
className: `${outcomeConfig[variant.outcome].bg} ${outcomeConfig[variant.outcome].border} ${outcomeConfig[variant.outcome].color}`,
|
|
1600
1967
|
children: outcomeConfig[variant.outcome].label
|
|
1601
1968
|
}
|
|
1602
1969
|
),
|
|
1603
|
-
variant.status === "completed" && variant.outcome === "pending_review" && onAccept && onReject && /* @__PURE__ */
|
|
1604
|
-
/* @__PURE__ */
|
|
1970
|
+
variant.status === "completed" && variant.outcome === "pending_review" && onAccept && onReject && /* @__PURE__ */ jsxs13(Fragment9, { children: [
|
|
1971
|
+
/* @__PURE__ */ jsxs13(
|
|
1605
1972
|
Button,
|
|
1606
1973
|
{
|
|
1607
1974
|
variant: "outline",
|
|
@@ -1613,12 +1980,12 @@ function VariantList({
|
|
|
1613
1980
|
},
|
|
1614
1981
|
disabled: isActioning === variant.id,
|
|
1615
1982
|
children: [
|
|
1616
|
-
/* @__PURE__ */
|
|
1983
|
+
/* @__PURE__ */ jsx15(Check3, { className: "mr-1 h-3 w-3" }),
|
|
1617
1984
|
"Accept"
|
|
1618
1985
|
]
|
|
1619
1986
|
}
|
|
1620
1987
|
),
|
|
1621
|
-
/* @__PURE__ */
|
|
1988
|
+
/* @__PURE__ */ jsxs13(
|
|
1622
1989
|
Button,
|
|
1623
1990
|
{
|
|
1624
1991
|
variant: "outline",
|
|
@@ -1630,13 +1997,13 @@ function VariantList({
|
|
|
1630
1997
|
},
|
|
1631
1998
|
disabled: isActioning === variant.id,
|
|
1632
1999
|
children: [
|
|
1633
|
-
/* @__PURE__ */
|
|
2000
|
+
/* @__PURE__ */ jsx15(X, { className: "mr-1 h-3 w-3" }),
|
|
1634
2001
|
"Reject"
|
|
1635
2002
|
]
|
|
1636
2003
|
}
|
|
1637
2004
|
)
|
|
1638
2005
|
] }),
|
|
1639
|
-
variant.detailsUrl && /* @__PURE__ */
|
|
2006
|
+
variant.detailsUrl && /* @__PURE__ */ jsx15(
|
|
1640
2007
|
Button,
|
|
1641
2008
|
{
|
|
1642
2009
|
variant: "ghost",
|
|
@@ -1646,13 +2013,13 @@ function VariantList({
|
|
|
1646
2013
|
e.stopPropagation();
|
|
1647
2014
|
window.open(variant.detailsUrl, "_blank");
|
|
1648
2015
|
},
|
|
1649
|
-
children: /* @__PURE__ */
|
|
2016
|
+
children: /* @__PURE__ */ jsx15(ExternalLink, { className: "h-3.5 w-3.5" })
|
|
1650
2017
|
}
|
|
1651
2018
|
)
|
|
1652
2019
|
] })
|
|
1653
2020
|
] }),
|
|
1654
|
-
variant.error && /* @__PURE__ */
|
|
1655
|
-
variant.summary && /* @__PURE__ */
|
|
2021
|
+
variant.error && /* @__PURE__ */ jsx15("p", { className: "mt-1.5 text-xs text-[var(--surface-danger-text)]", children: variant.error }),
|
|
2022
|
+
variant.summary && /* @__PURE__ */ jsx15("p", { className: "mt-1.5 line-clamp-2 text-xs text-muted-foreground", children: variant.summary })
|
|
1656
2023
|
]
|
|
1657
2024
|
},
|
|
1658
2025
|
variant.id
|
|
@@ -1691,6 +2058,12 @@ export {
|
|
|
1691
2058
|
NewSandboxCard,
|
|
1692
2059
|
SandboxTable,
|
|
1693
2060
|
BackendSelector,
|
|
2061
|
+
HARNESS_OPTIONS,
|
|
2062
|
+
HarnessPicker,
|
|
2063
|
+
canonicalModelId,
|
|
2064
|
+
formatPricing,
|
|
2065
|
+
formatContext,
|
|
2066
|
+
ModelPicker,
|
|
1694
2067
|
ProfileSelector,
|
|
1695
2068
|
ProfileComparison,
|
|
1696
2069
|
VariantList
|
package/dist/dashboard.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { B as Backend, a as BackendSelector, b as BackendSelectorProps, C as ClusterStatusBar, c as ClusterStatusBarProps, d as ClusterStatusItem, e as CreditBalance, f as CreditBalanceProps, D as DashboardLayout, g as DashboardLayoutProps,
|
|
1
|
+
export { B as Backend, a as BackendSelector, b as BackendSelectorProps, C as ClusterStatusBar, c as ClusterStatusBarProps, d as ClusterStatusItem, e as CreditBalance, f as CreditBalanceProps, D as DashboardLayout, g as DashboardLayoutProps, at as DashboardProfile, h as DashboardUser, H as HARNESS_OPTIONS, i as HarnessPicker, j as HarnessPickerProps, k as HarnessType, I as Invoice, l as InvoiceTable, m as InvoiceTableProps, M as ModelInfo, n as ModelPicker, o as ModelPickerProps, p as ModelPickerVariant, q as ModelPreset, N as NavItem, r as NewSandboxCard, s as NewSandboxCardProps, t as PlanCardData, u as PlanCards, v as PlanCardsProps, au as PlanFeature, w as ProductVariant, x as ProfileAvatar, y as ProfileAvatarProps, z as ProfileComparison, A as ProfileComparisonProps, E as ProfileSelector, F as ProfileSelectorProps, R as RailButton, G as RailButtonProps, J as RailModeButton, K as RailModeButtonProps, L as RailSeparator, O as RailSeparatorProps, Q as ResourceMeter, S as ResourceMeterProps, T as SIDEBAR_MOBILE_WIDTH, U as SIDEBAR_PANEL_WIDTH, V as SIDEBAR_RAIL_WIDTH, W as SIDEBAR_TOTAL_WIDTH, X as SandboxCard, Y as SandboxCardData, Z as SandboxCardProps, _ as SandboxStatus, $ as SandboxTable, a0 as SandboxTableProps, a1 as Sidebar, a2 as SidebarContent, a3 as SidebarContentProps, a4 as SidebarPanel, a5 as SidebarPanelContent, a6 as SidebarPanelContentProps, a7 as SidebarPanelHeader, a8 as SidebarPanelHeaderProps, a9 as SidebarPanelProps, aa as SidebarProps, ab as SidebarProvider, ac as SidebarProviderProps, ad as SidebarRail, ae as SidebarRailFooter, af as SidebarRailFooterProps, ag as SidebarRailHeader, ah as SidebarRailHeaderProps, ai as SidebarRailNav, aj as SidebarRailNavProps, ak as SidebarRailProps, al as SidebarUser, av as TeamRole, aw as Variant, an as VariantList, ao as VariantListProps, ax as VariantOutcome, ay as VariantStatus, az as canAdminSandbox, ap as canonicalModelId, aq as formatContext, ar as formatPricing, as as useSidebar } from './variant-list-BrHYcBCk.js';
|
|
2
2
|
export { a as BillingBalance, c as BillingDashboard, d as BillingDashboardProps, B as BillingSubscription, b as BillingUsage, e as PricingPage, f as PricingPageProps, P as PricingTier, g as UsageChart, h as UsageChartProps, U as UsageDataPoint, i as formatPrice } from './usage-chart-CPTcNlGs.js';
|
|
3
3
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
4
4
|
export { a as TemplateCard, T as TemplateCardData, b as TemplateCardProps } from './template-card-BAtvcAkU.js';
|
package/dist/dashboard.js
CHANGED
|
@@ -7,7 +7,10 @@ import {
|
|
|
7
7
|
ClusterStatusBar,
|
|
8
8
|
CreditBalance,
|
|
9
9
|
DashboardLayout,
|
|
10
|
+
HARNESS_OPTIONS,
|
|
11
|
+
HarnessPicker,
|
|
10
12
|
InvoiceTable,
|
|
13
|
+
ModelPicker,
|
|
11
14
|
NewSandboxCard,
|
|
12
15
|
PlanCards,
|
|
13
16
|
ProfileAvatar,
|
|
@@ -35,8 +38,11 @@ import {
|
|
|
35
38
|
SidebarRailNav,
|
|
36
39
|
VariantList,
|
|
37
40
|
canAdminSandbox,
|
|
41
|
+
canonicalModelId,
|
|
42
|
+
formatContext,
|
|
43
|
+
formatPricing,
|
|
38
44
|
useSidebar
|
|
39
|
-
} from "./chunk-
|
|
45
|
+
} from "./chunk-NKUPJC34.js";
|
|
40
46
|
import {
|
|
41
47
|
BillingDashboard,
|
|
42
48
|
PricingPage,
|
|
@@ -931,8 +937,11 @@ export {
|
|
|
931
937
|
CreditBalance,
|
|
932
938
|
DashboardLayout,
|
|
933
939
|
GitPanel,
|
|
940
|
+
HARNESS_OPTIONS,
|
|
941
|
+
HarnessPicker,
|
|
934
942
|
InfoPanel,
|
|
935
943
|
InvoiceTable,
|
|
944
|
+
ModelPicker,
|
|
936
945
|
NetworkConfig,
|
|
937
946
|
NewSandboxCard,
|
|
938
947
|
PlanCards,
|
|
@@ -970,6 +979,9 @@ export {
|
|
|
970
979
|
UsageSummary,
|
|
971
980
|
VariantList,
|
|
972
981
|
canAdminSandbox,
|
|
982
|
+
canonicalModelId,
|
|
983
|
+
formatContext,
|
|
973
984
|
formatPrice,
|
|
985
|
+
formatPricing,
|
|
974
986
|
useSidebar
|
|
975
987
|
};
|
package/dist/globals.css
CHANGED
|
@@ -1139,6 +1139,9 @@
|
|
|
1139
1139
|
.max-h-\[160px\] {
|
|
1140
1140
|
max-height: 160px;
|
|
1141
1141
|
}
|
|
1142
|
+
.max-h-\[440px\] {
|
|
1143
|
+
max-height: 440px;
|
|
1144
|
+
}
|
|
1142
1145
|
.min-h-0 {
|
|
1143
1146
|
min-height: calc(var(--spacing) * 0);
|
|
1144
1147
|
}
|
|
@@ -1343,6 +1346,9 @@
|
|
|
1343
1346
|
.w-\[var\(--indicator-dot-size\)\] {
|
|
1344
1347
|
width: var(--indicator-dot-size);
|
|
1345
1348
|
}
|
|
1349
|
+
.w-\[var\(--radix-dropdown-menu-trigger-width\)\] {
|
|
1350
|
+
width: var(--radix-dropdown-menu-trigger-width);
|
|
1351
|
+
}
|
|
1346
1352
|
.w-\[var\(--radix-select-trigger-width\)\] {
|
|
1347
1353
|
width: var(--radix-select-trigger-width);
|
|
1348
1354
|
}
|
|
@@ -1403,12 +1409,18 @@
|
|
|
1403
1409
|
.max-w-\[150px\] {
|
|
1404
1410
|
max-width: 150px;
|
|
1405
1411
|
}
|
|
1412
|
+
.max-w-\[160px\] {
|
|
1413
|
+
max-width: 160px;
|
|
1414
|
+
}
|
|
1406
1415
|
.max-w-\[250px\] {
|
|
1407
1416
|
max-width: 250px;
|
|
1408
1417
|
}
|
|
1409
1418
|
.max-w-\[300px\] {
|
|
1410
1419
|
max-width: 300px;
|
|
1411
1420
|
}
|
|
1421
|
+
.max-w-\[460px\] {
|
|
1422
|
+
max-width: 460px;
|
|
1423
|
+
}
|
|
1412
1424
|
.max-w-full {
|
|
1413
1425
|
max-width: 100%;
|
|
1414
1426
|
}
|
|
@@ -1448,6 +1460,9 @@
|
|
|
1448
1460
|
.min-w-\[180px\] {
|
|
1449
1461
|
min-width: 180px;
|
|
1450
1462
|
}
|
|
1463
|
+
.min-w-\[320px\] {
|
|
1464
|
+
min-width: 320px;
|
|
1465
|
+
}
|
|
1451
1466
|
.min-w-\[var\(--radix-select-trigger-width\)\] {
|
|
1452
1467
|
min-width: var(--radix-select-trigger-width);
|
|
1453
1468
|
}
|
|
@@ -2602,6 +2617,9 @@
|
|
|
2602
2617
|
.pt-1 {
|
|
2603
2618
|
padding-top: calc(var(--spacing) * 1);
|
|
2604
2619
|
}
|
|
2620
|
+
.pt-1\.5 {
|
|
2621
|
+
padding-top: calc(var(--spacing) * 1.5);
|
|
2622
|
+
}
|
|
2605
2623
|
.pt-2 {
|
|
2606
2624
|
padding-top: calc(var(--spacing) * 2);
|
|
2607
2625
|
}
|
|
@@ -2641,6 +2659,9 @@
|
|
|
2641
2659
|
.pb-0 {
|
|
2642
2660
|
padding-bottom: calc(var(--spacing) * 0);
|
|
2643
2661
|
}
|
|
2662
|
+
.pb-0\.5 {
|
|
2663
|
+
padding-bottom: calc(var(--spacing) * 0.5);
|
|
2664
|
+
}
|
|
2644
2665
|
.pb-1 {
|
|
2645
2666
|
padding-bottom: calc(var(--spacing) * 1);
|
|
2646
2667
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -15,7 +15,7 @@ import { b as ToolPart } from './parts-CyGkM6Fp.js';
|
|
|
15
15
|
export { R as ReasoningPart, S as SessionMessage, a as SessionPart, T as TextPart, c as ToolState, d as ToolStatus, e as ToolTime } from './parts-CyGkM6Fp.js';
|
|
16
16
|
export { F as FileNode, a as FileTabData, b as FileTabs, c as FileTabsProps, d as FileTree, e as FileTreeProps, f as FileTreeVisibilityOptions, g as filterFileTree } from './file-tabs-BLfxfmAH.js';
|
|
17
17
|
export { FileArtifactPane, FileArtifactPaneProps, FilePreview, FilePreviewProps } from './files.js';
|
|
18
|
-
export { B as Backend, a as BackendSelector, b as BackendSelectorProps, C as ClusterStatusBar, c as ClusterStatusBarProps, d as ClusterStatusItem, e as CreditBalance, f as CreditBalanceProps, D as DashboardLayout, g as DashboardLayoutProps, h as DashboardUser, I as Invoice,
|
|
18
|
+
export { B as Backend, a as BackendSelector, b as BackendSelectorProps, C as ClusterStatusBar, c as ClusterStatusBarProps, d as ClusterStatusItem, e as CreditBalance, f as CreditBalanceProps, D as DashboardLayout, g as DashboardLayoutProps, h as DashboardUser, H as HARNESS_OPTIONS, i as HarnessPicker, j as HarnessPickerProps, k as HarnessType, I as Invoice, l as InvoiceTable, m as InvoiceTableProps, M as ModelInfo, n as ModelPicker, o as ModelPickerProps, p as ModelPickerVariant, q as ModelPreset, N as NavItem, r as NewSandboxCard, s as NewSandboxCardProps, P as PanelConfig, t as PlanCardData, u as PlanCards, v as PlanCardsProps, w as ProductVariant, x as ProfileAvatar, y as ProfileAvatarProps, z as ProfileComparison, A as ProfileComparisonProps, E as ProfileSelector, F as ProfileSelectorProps, R as RailButton, G as RailButtonProps, J as RailModeButton, K as RailModeButtonProps, L as RailSeparator, O as RailSeparatorProps, Q as ResourceMeter, S as ResourceMeterProps, T as SIDEBAR_MOBILE_WIDTH, U as SIDEBAR_PANEL_WIDTH, V as SIDEBAR_RAIL_WIDTH, W as SIDEBAR_TOTAL_WIDTH, X as SandboxCard, Y as SandboxCardData, Z as SandboxCardProps, _ as SandboxStatus, $ as SandboxTable, a0 as SandboxTableProps, a1 as Sidebar, a2 as SidebarContent, a3 as SidebarContentProps, a4 as SidebarPanel, a5 as SidebarPanelContent, a6 as SidebarPanelContentProps, a7 as SidebarPanelHeader, a8 as SidebarPanelHeaderProps, a9 as SidebarPanelProps, aa as SidebarProps, ab as SidebarProvider, ac as SidebarProviderProps, ad as SidebarRail, ae as SidebarRailFooter, af as SidebarRailFooterProps, ag as SidebarRailHeader, ah as SidebarRailHeaderProps, ai as SidebarRailNav, aj as SidebarRailNavProps, ak as SidebarRailProps, al as SidebarUser, am as TopNavLink, an as VariantList, ao as VariantListProps, ap as canonicalModelId, aq as formatContext, ar as formatPricing, as as useSidebar } from './variant-list-BrHYcBCk.js';
|
|
19
19
|
export { c as BillingDashboard, d as BillingDashboardProps, e as PricingCards, f as PricingPageProps, g as UsageChart, h as UsageChartProps, U as UsageDataPoint } from './usage-chart-CPTcNlGs.js';
|
|
20
20
|
export { AuthHeader, GitHubLoginButton, LoginLayout, LoginLayoutProps, UserMenu } from './auth.js';
|
|
21
21
|
export { CodeBlock, CodeBlock as CodeBlockDisplay, CopyButton, Markdown, MarkdownProps } from './markdown.js';
|
package/dist/index.js
CHANGED
|
@@ -189,7 +189,10 @@ import {
|
|
|
189
189
|
ClusterStatusBar,
|
|
190
190
|
CreditBalance,
|
|
191
191
|
DashboardLayout,
|
|
192
|
+
HARNESS_OPTIONS,
|
|
193
|
+
HarnessPicker,
|
|
192
194
|
InvoiceTable,
|
|
195
|
+
ModelPicker,
|
|
193
196
|
NewSandboxCard,
|
|
194
197
|
PlanCards,
|
|
195
198
|
ProfileAvatar,
|
|
@@ -216,8 +219,11 @@ import {
|
|
|
216
219
|
SidebarRailHeader,
|
|
217
220
|
SidebarRailNav,
|
|
218
221
|
VariantList,
|
|
222
|
+
canonicalModelId,
|
|
223
|
+
formatContext,
|
|
224
|
+
formatPricing,
|
|
219
225
|
useSidebar
|
|
220
|
-
} from "./chunk-
|
|
226
|
+
} from "./chunk-NKUPJC34.js";
|
|
221
227
|
import {
|
|
222
228
|
BillingDashboard,
|
|
223
229
|
PricingPage,
|
|
@@ -428,6 +434,8 @@ export {
|
|
|
428
434
|
GitHubLoginButton,
|
|
429
435
|
GlobResultsPreview,
|
|
430
436
|
GrepResultsPreview,
|
|
437
|
+
HARNESS_OPTIONS,
|
|
438
|
+
HarnessPicker,
|
|
431
439
|
InlineCode,
|
|
432
440
|
InlineThinkingItem,
|
|
433
441
|
InlineToolItem,
|
|
@@ -438,6 +446,7 @@ export {
|
|
|
438
446
|
Logo,
|
|
439
447
|
Markdown,
|
|
440
448
|
MessageList,
|
|
449
|
+
ModelPicker,
|
|
441
450
|
NewSandboxCard,
|
|
442
451
|
OpenUIArtifactRenderer,
|
|
443
452
|
PlanCards,
|
|
@@ -530,12 +539,15 @@ export {
|
|
|
530
539
|
WriteFilePreview,
|
|
531
540
|
badgeVariants,
|
|
532
541
|
buttonVariants,
|
|
542
|
+
canonicalModelId,
|
|
533
543
|
cn,
|
|
534
544
|
copyText,
|
|
535
545
|
createAuthFetcher,
|
|
536
546
|
filterFileTree,
|
|
537
547
|
formatBytes,
|
|
548
|
+
formatContext,
|
|
538
549
|
formatDuration,
|
|
550
|
+
formatPricing,
|
|
539
551
|
formatUptime,
|
|
540
552
|
getToolCategory,
|
|
541
553
|
getToolDisplayMetadata,
|
package/dist/styles.css
CHANGED
|
@@ -1139,6 +1139,9 @@
|
|
|
1139
1139
|
.max-h-\[160px\] {
|
|
1140
1140
|
max-height: 160px;
|
|
1141
1141
|
}
|
|
1142
|
+
.max-h-\[440px\] {
|
|
1143
|
+
max-height: 440px;
|
|
1144
|
+
}
|
|
1142
1145
|
.min-h-0 {
|
|
1143
1146
|
min-height: calc(var(--spacing) * 0);
|
|
1144
1147
|
}
|
|
@@ -1343,6 +1346,9 @@
|
|
|
1343
1346
|
.w-\[var\(--indicator-dot-size\)\] {
|
|
1344
1347
|
width: var(--indicator-dot-size);
|
|
1345
1348
|
}
|
|
1349
|
+
.w-\[var\(--radix-dropdown-menu-trigger-width\)\] {
|
|
1350
|
+
width: var(--radix-dropdown-menu-trigger-width);
|
|
1351
|
+
}
|
|
1346
1352
|
.w-\[var\(--radix-select-trigger-width\)\] {
|
|
1347
1353
|
width: var(--radix-select-trigger-width);
|
|
1348
1354
|
}
|
|
@@ -1403,12 +1409,18 @@
|
|
|
1403
1409
|
.max-w-\[150px\] {
|
|
1404
1410
|
max-width: 150px;
|
|
1405
1411
|
}
|
|
1412
|
+
.max-w-\[160px\] {
|
|
1413
|
+
max-width: 160px;
|
|
1414
|
+
}
|
|
1406
1415
|
.max-w-\[250px\] {
|
|
1407
1416
|
max-width: 250px;
|
|
1408
1417
|
}
|
|
1409
1418
|
.max-w-\[300px\] {
|
|
1410
1419
|
max-width: 300px;
|
|
1411
1420
|
}
|
|
1421
|
+
.max-w-\[460px\] {
|
|
1422
|
+
max-width: 460px;
|
|
1423
|
+
}
|
|
1412
1424
|
.max-w-full {
|
|
1413
1425
|
max-width: 100%;
|
|
1414
1426
|
}
|
|
@@ -1448,6 +1460,9 @@
|
|
|
1448
1460
|
.min-w-\[180px\] {
|
|
1449
1461
|
min-width: 180px;
|
|
1450
1462
|
}
|
|
1463
|
+
.min-w-\[320px\] {
|
|
1464
|
+
min-width: 320px;
|
|
1465
|
+
}
|
|
1451
1466
|
.min-w-\[var\(--radix-select-trigger-width\)\] {
|
|
1452
1467
|
min-width: var(--radix-select-trigger-width);
|
|
1453
1468
|
}
|
|
@@ -2602,6 +2617,9 @@
|
|
|
2602
2617
|
.pt-1 {
|
|
2603
2618
|
padding-top: calc(var(--spacing) * 1);
|
|
2604
2619
|
}
|
|
2620
|
+
.pt-1\.5 {
|
|
2621
|
+
padding-top: calc(var(--spacing) * 1.5);
|
|
2622
|
+
}
|
|
2605
2623
|
.pt-2 {
|
|
2606
2624
|
padding-top: calc(var(--spacing) * 2);
|
|
2607
2625
|
}
|
|
@@ -2641,6 +2659,9 @@
|
|
|
2641
2659
|
.pb-0 {
|
|
2642
2660
|
padding-bottom: calc(var(--spacing) * 0);
|
|
2643
2661
|
}
|
|
2662
|
+
.pb-0\.5 {
|
|
2663
|
+
padding-bottom: calc(var(--spacing) * 0.5);
|
|
2664
|
+
}
|
|
2644
2665
|
.pb-1 {
|
|
2645
2666
|
padding-bottom: calc(var(--spacing) * 1);
|
|
2646
2667
|
}
|
|
@@ -358,6 +358,125 @@ interface BackendSelectorProps {
|
|
|
358
358
|
}
|
|
359
359
|
declare function BackendSelector({ backends, selected, onChange, label, placeholder, className, }: BackendSelectorProps): react_jsx_runtime.JSX.Element;
|
|
360
360
|
|
|
361
|
+
/**
|
|
362
|
+
* Sandbox agent harness types — mirrors `BackendType` from
|
|
363
|
+
* `@tangle-network/sandbox` SDK. Kept in lockstep with that enum:
|
|
364
|
+
* if the SDK adds a backend, add it here too.
|
|
365
|
+
*/
|
|
366
|
+
type HarnessType = "opencode" | "claude-code" | "codex" | "amp" | "factory-droids" | "cli-base";
|
|
367
|
+
interface HarnessOption extends Backend {
|
|
368
|
+
type: HarnessType;
|
|
369
|
+
}
|
|
370
|
+
/**
|
|
371
|
+
* Default option list with human-readable copy. Order is curated so the
|
|
372
|
+
* recommended choice (`opencode`) appears first; `cli-base` (no agent) last.
|
|
373
|
+
*/
|
|
374
|
+
declare const HARNESS_OPTIONS: readonly HarnessOption[];
|
|
375
|
+
interface HarnessPickerProps extends Omit<BackendSelectorProps, "backends" | "selected" | "onChange"> {
|
|
376
|
+
value: HarnessType;
|
|
377
|
+
onChange: (next: HarnessType) => void;
|
|
378
|
+
/** Filter the available harnesses (e.g. by plan tier). Defaults to all. */
|
|
379
|
+
available?: ReadonlyArray<HarnessType>;
|
|
380
|
+
/** Override or extend the option metadata. Keys are HarnessType. */
|
|
381
|
+
optionsOverride?: Partial<Record<HarnessType, Partial<Omit<HarnessOption, "type">>>>;
|
|
382
|
+
}
|
|
383
|
+
/**
|
|
384
|
+
* Type-safe harness/backend selector for sandbox-backed agent products.
|
|
385
|
+
*
|
|
386
|
+
* Wraps the generic {@link BackendSelector} with the canonical harness list
|
|
387
|
+
* baked in, so consumers don't have to re-declare it (or risk drifting from
|
|
388
|
+
* the SDK enum).
|
|
389
|
+
*/
|
|
390
|
+
declare function HarnessPicker({ value, onChange, available, optionsOverride, label, ...rest }: HarnessPickerProps): react_jsx_runtime.JSX.Element;
|
|
391
|
+
|
|
392
|
+
/**
|
|
393
|
+
* Wire-format model entry as returned by `/v1/models` on the Tangle Router
|
|
394
|
+
* (and most OpenAI-compatible gateways). Field names match the upstream
|
|
395
|
+
* response so consumers can pass `data.data` straight through.
|
|
396
|
+
*/
|
|
397
|
+
interface ModelInfo {
|
|
398
|
+
/** Provider-local id, e.g. "gpt-5.4" or "anthropic/claude-sonnet-4-6". */
|
|
399
|
+
id: string;
|
|
400
|
+
/** Human label (defaults to id if absent). */
|
|
401
|
+
name?: string;
|
|
402
|
+
/** Provider key, e.g. "openai", "anthropic". Underscored for compat with router. */
|
|
403
|
+
_provider?: string;
|
|
404
|
+
/** Alternative provider field on some gateways. */
|
|
405
|
+
provider?: string;
|
|
406
|
+
/**
|
|
407
|
+
* Per-token prices in USD as decimal strings. Multiply by 1_000_000 for
|
|
408
|
+
* the conventional $/M tokens display.
|
|
409
|
+
*/
|
|
410
|
+
pricing?: {
|
|
411
|
+
prompt?: string | null;
|
|
412
|
+
completion?: string | null;
|
|
413
|
+
};
|
|
414
|
+
context_length?: number;
|
|
415
|
+
description?: string | null;
|
|
416
|
+
architecture?: {
|
|
417
|
+
modality?: string;
|
|
418
|
+
input_modalities?: string[];
|
|
419
|
+
output_modalities?: string[];
|
|
420
|
+
};
|
|
421
|
+
}
|
|
422
|
+
/**
|
|
423
|
+
* Curated preset bucket. Three are surfaced by default — they map to typical
|
|
424
|
+
* cost/quality tradeoffs without forcing the consumer to pick a specific
|
|
425
|
+
* model. `match` resolves the preset against the loaded model list.
|
|
426
|
+
*/
|
|
427
|
+
interface ModelPreset {
|
|
428
|
+
id: "fast" | "balanced" | "best" | string;
|
|
429
|
+
label: string;
|
|
430
|
+
hint: string;
|
|
431
|
+
icon?: React.ComponentType<{
|
|
432
|
+
className?: string;
|
|
433
|
+
}>;
|
|
434
|
+
/**
|
|
435
|
+
* Pick the canonical model id for this preset given the loaded list.
|
|
436
|
+
* Should return undefined if no acceptable model is loaded yet.
|
|
437
|
+
*/
|
|
438
|
+
match: (models: ModelInfo[]) => string | undefined;
|
|
439
|
+
}
|
|
440
|
+
type ModelPickerVariant = "field" | "pill";
|
|
441
|
+
interface ModelPickerProps {
|
|
442
|
+
/** Canonical model id (provider-prefixed, e.g. "openai/gpt-5.4"). */
|
|
443
|
+
value: string;
|
|
444
|
+
onChange: (modelId: string) => void;
|
|
445
|
+
/** Models to choose from. Pass `[]` while loading. */
|
|
446
|
+
models: ModelInfo[];
|
|
447
|
+
/** Show the loading state (overrides empty-list copy). */
|
|
448
|
+
loading?: boolean;
|
|
449
|
+
/** Recently-used canonical ids to surface at the top. */
|
|
450
|
+
recents?: ReadonlyArray<string>;
|
|
451
|
+
/**
|
|
452
|
+
* Curated presets shown above the full list. Defaults to Fast/Balanced/Best
|
|
453
|
+
* resolved against common gpt-5/Claude families.
|
|
454
|
+
*/
|
|
455
|
+
presets?: ReadonlyArray<ModelPreset>;
|
|
456
|
+
/** Drop providers from the picker entirely (e.g. "audio", "embedding"). */
|
|
457
|
+
excludeProviders?: ReadonlyArray<string>;
|
|
458
|
+
/** Restrict to these architectures (e.g. ["text"]). Default: all. */
|
|
459
|
+
modalities?: ReadonlyArray<string>;
|
|
460
|
+
/** Trigger appearance. "field" = full-width form field; "pill" = inline chat input pill. */
|
|
461
|
+
variant?: ModelPickerVariant;
|
|
462
|
+
label?: string;
|
|
463
|
+
placeholder?: string;
|
|
464
|
+
className?: string;
|
|
465
|
+
disabled?: boolean;
|
|
466
|
+
}
|
|
467
|
+
/**
|
|
468
|
+
* Resolve the canonical id for a model. Some upstreams already prefix the
|
|
469
|
+
* provider in the id (e.g. "anthropic/claude-haiku-4.5"); others put it in
|
|
470
|
+
* `_provider` and leave the id bare. Always returns "<provider>/<model>"
|
|
471
|
+
* unless the id is already prefixed.
|
|
472
|
+
*/
|
|
473
|
+
declare function canonicalModelId(model: ModelInfo): string;
|
|
474
|
+
/** Format $/M tokens. Returns null if pricing is missing or zero. */
|
|
475
|
+
declare function formatPricing(pricing: ModelInfo["pricing"]): string | null;
|
|
476
|
+
/** Format context length compactly (e.g. 200_000 → "200k"). */
|
|
477
|
+
declare function formatContext(ctx: number | undefined): string | null;
|
|
478
|
+
declare function ModelPicker({ value, onChange, models, loading, recents, presets, excludeProviders, modalities, variant, label, placeholder, className, disabled, }: ModelPickerProps): react_jsx_runtime.JSX.Element;
|
|
479
|
+
|
|
361
480
|
interface Profile {
|
|
362
481
|
id: string;
|
|
363
482
|
name: string;
|
|
@@ -418,4 +537,4 @@ interface VariantListProps {
|
|
|
418
537
|
}
|
|
419
538
|
declare function VariantList({ variants, selectedId, onSelect, onAccept, onReject, isActioning, className, }: VariantListProps): react_jsx_runtime.JSX.Element;
|
|
420
539
|
|
|
421
|
-
export {
|
|
540
|
+
export { SandboxTable as $, type ProfileComparisonProps as A, type Backend as B, ClusterStatusBar as C, DashboardLayout as D, ProfileSelector as E, type ProfileSelectorProps as F, type RailButtonProps as G, HARNESS_OPTIONS as H, type Invoice as I, RailModeButton as J, type RailModeButtonProps as K, RailSeparator as L, type ModelInfo as M, type NavItem as N, type RailSeparatorProps as O, type PanelConfig as P, ResourceMeter as Q, RailButton as R, type ResourceMeterProps as S, SIDEBAR_MOBILE_WIDTH as T, SIDEBAR_PANEL_WIDTH as U, SIDEBAR_RAIL_WIDTH as V, SIDEBAR_TOTAL_WIDTH as W, SandboxCard as X, type SandboxCardData as Y, type SandboxCardProps as Z, type SandboxStatus as _, BackendSelector as a, type SandboxTableProps as a0, Sidebar as a1, SidebarContent as a2, type SidebarContentProps as a3, SidebarPanel as a4, SidebarPanelContent as a5, type SidebarPanelContentProps as a6, SidebarPanelHeader as a7, type SidebarPanelHeaderProps as a8, type SidebarPanelProps as a9, type SidebarProps as aa, SidebarProvider as ab, type SidebarProviderProps as ac, SidebarRail as ad, SidebarRailFooter as ae, type SidebarRailFooterProps as af, SidebarRailHeader as ag, type SidebarRailHeaderProps as ah, SidebarRailNav as ai, type SidebarRailNavProps as aj, type SidebarRailProps as ak, type SidebarUser as al, type TopNavLink as am, VariantList as an, type VariantListProps as ao, canonicalModelId as ap, formatContext as aq, formatPricing as ar, useSidebar as as, type Profile as at, type PlanFeature as au, type TeamRole as av, type Variant as aw, type VariantOutcome as ax, type VariantStatus as ay, canAdminSandbox as az, type BackendSelectorProps as b, type ClusterStatusBarProps as c, type ClusterStatusItem as d, CreditBalance as e, type CreditBalanceProps as f, type DashboardLayoutProps as g, type DashboardUser as h, HarnessPicker as i, type HarnessPickerProps as j, type HarnessType as k, InvoiceTable as l, type InvoiceTableProps as m, ModelPicker as n, type ModelPickerProps as o, type ModelPickerVariant as p, type ModelPreset as q, NewSandboxCard as r, type NewSandboxCardProps as s, type PlanCardData as t, PlanCards as u, type PlanCardsProps as v, type ProductVariant as w, ProfileAvatar as x, type ProfileAvatarProps as y, ProfileComparison as z };
|
package/package.json
CHANGED