@ai-matrx/agents 0.59.197 → 0.59.199

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.
@@ -31,7 +31,7 @@ __export(react_exports, {
31
31
  useSettingsSelector: () => useSettingsSelector
32
32
  });
33
33
  module.exports = __toCommonJS(react_exports);
34
- var import_react5 = require("react");
34
+ var import_react3 = require("react");
35
35
 
36
36
  // generated/llm-enums.ts
37
37
  var LLM_PARAMS_KEYS = [
@@ -110,168 +110,6 @@ var LLM_PARAMS_KEYS = [
110
110
  "tts_quality"
111
111
  ];
112
112
 
113
- // models/capabilities.ts
114
- function isManagedAgentModelCapability(capabilities) {
115
- return capabilities.interaction === "agent";
116
- }
117
- function isDecisionModelCapability(capabilities) {
118
- return capabilities.interaction === "decision";
119
- }
120
- function acceptsTextInstructions(capabilities) {
121
- if (capabilities.interaction === "realtime") return true;
122
- const input = capabilities.input ?? [];
123
- return input.length === 0 || input.includes("text");
124
- }
125
-
126
- // models/feature-map.ts
127
- var FEATURE_BUCKET_ORDER = [
128
- "thinking",
129
- "tools",
130
- "schema",
131
- "search",
132
- "extraction",
133
- "x_search",
134
- "other"
135
- ];
136
- var FEATURE_BUCKETS = {
137
- schema: { label: "Schema", description: "Structured & JSON output" },
138
- tools: { label: "Tools", description: "Function & tool calling" },
139
- search: { label: "Search", description: "Web search" },
140
- x_search: { label: "X Search", description: "X (Twitter) platform search" },
141
- thinking: { label: "Thinking", description: "Reasoning & extended thinking" },
142
- extraction: {
143
- label: "Extraction",
144
- description: "NER, classification & entity extraction"
145
- },
146
- other: { label: "Other", description: "Uncategorized or niche features" }
147
- };
148
-
149
- // models/format.ts
150
- var RATING_TO_TIER = {
151
- 1: "$",
152
- 2: "$$",
153
- 3: "$$$",
154
- 4: "$$$$",
155
- 5: "$$$$$",
156
- 6: "$$$$$+"
157
- // renders as the "5+" band
158
- };
159
- var TOP_TIER_COST_RATING = 6;
160
- var TOP_TIER_LOCKED_TITLE = "This model is limited to approved accounts";
161
- function isTopTierRating(rating) {
162
- return typeof rating === "number" && rating >= TOP_TIER_COST_RATING;
163
- }
164
- function costRatingTier(rating) {
165
- if (typeof rating !== "number") return null;
166
- return RATING_TO_TIER[rating] ?? null;
167
- }
168
- function speedRatingLabel(rating) {
169
- if (typeof rating !== "number") return null;
170
- return rating >= 6 ? "5+" : String(rating);
171
- }
172
- function speedRatingWord(rating) {
173
- if (typeof rating !== "number") return "\u2014";
174
- if (rating <= 2) return "Slow";
175
- if (rating === 3) return "Med";
176
- if (rating === 4) return "Fast";
177
- if (rating === 5) return "Fast+";
178
- return "Max";
179
- }
180
- function costRatingWord(rating) {
181
- if (typeof rating !== "number") return "\u2014";
182
- if (rating <= 1) return "Low";
183
- if (rating === 2) return "Low+";
184
- if (rating === 3) return "Med";
185
- if (rating === 4) return "High";
186
- if (rating === 5) return "High+";
187
- return "Max";
188
- }
189
- function priceTierRating(tier) {
190
- return tier.endsWith("+") ? 6 : tier.length;
191
- }
192
-
193
- // models/service-label.ts
194
- var SERVICE_LABEL = "Service";
195
- var SERVICE_LABEL_PLURAL = "Services";
196
- function serviceCountLabel(count) {
197
- const noun = (count === 1 ? SERVICE_LABEL : SERVICE_LABEL_PLURAL).toLowerCase();
198
- return `${count} ${noun}`;
199
- }
200
-
201
- // models/catalog/types.ts
202
- var INPUT_MODALITIES = ["text", "image", "audio", "video"];
203
- var OUTPUT_MODALITIES = [
204
- "text",
205
- "image",
206
- "audio",
207
- "video",
208
- "entities",
209
- "decision"
210
- ];
211
-
212
- // models/succession.ts
213
- var MAX_SUCCESSION_HOPS = 8;
214
- function buildSuccessionIndex(models) {
215
- return new Map(models.map((m) => [m.id, m]));
216
- }
217
- function isSupersedable(node) {
218
- return node.isDeprecated || node.retiredAt != null;
219
- }
220
- var loggedBroken = /* @__PURE__ */ new Set();
221
- function logBroken(modelId, reason) {
222
- if (loggedBroken.has(modelId)) return;
223
- loggedBroken.add(modelId);
224
- console.warn(`[models/succession] ${modelId}: successor chain broken (${reason}); keeping the original model.`);
225
- }
226
- function resolveSuccessor(modelId, index) {
227
- const start = index.get(modelId);
228
- if (!start || !isSupersedable(start) || !start.successorId) return modelId;
229
- const seen = /* @__PURE__ */ new Set([modelId]);
230
- let current = start;
231
- for (let hop = 0; hop < MAX_SUCCESSION_HOPS; hop += 1) {
232
- const nextId = current.successorId;
233
- if (!nextId) {
234
- logBroken(modelId, `${current.id} is superseded and names no successor`);
235
- return modelId;
236
- }
237
- if (seen.has(nextId)) {
238
- logBroken(modelId, `cycle at ${nextId}`);
239
- return modelId;
240
- }
241
- const next = index.get(nextId);
242
- if (!next) {
243
- logBroken(modelId, `successor ${nextId} is not in the catalog`);
244
- return modelId;
245
- }
246
- if (!isSupersedable(next)) return next.id;
247
- seen.add(nextId);
248
- current = next;
249
- }
250
- logBroken(modelId, `more than ${MAX_SUCCESSION_HOPS} hops`);
251
- return modelId;
252
- }
253
-
254
- // models/fit.ts
255
- var featuresOf = (c) => {
256
- const f = c.features;
257
- if (!f) return [];
258
- return Array.isArray(f) ? f : f.raw ?? [];
259
- };
260
- function seesImages(c) {
261
- return (c.input ?? []).includes("image") || featuresOf(c).includes("vision");
262
- }
263
- function takesInput(c, modality) {
264
- if (modality === "image") return seesImages(c);
265
- return (c.input ?? []).includes(modality);
266
- }
267
- var MEDIA_GENERATION_FEATURES = /* @__PURE__ */ new Set(["image_generation", "video_generation", "audio_generation", "music_generation"]);
268
- function isChatModelCapability(c) {
269
- if (c.interaction !== "turn") return false;
270
- if (!(c.input ?? []).includes("text")) return false;
271
- if (!(c.output ?? []).includes("text")) return false;
272
- return !featuresOf(c).some((f) => MEDIA_GENERATION_FEATURES.has(f));
273
- }
274
-
275
113
  // settings/ui-gates.ts
276
114
  var UI_GATE_KEYS = [
277
115
  "tools",
@@ -299,2107 +137,82 @@ var ALL_KNOWN_KEYS = /* @__PURE__ */ new Set([
299
137
  "end_image",
300
138
  "enhance_prompt",
301
139
  "first_frame_image",
302
- "generate_audio",
303
- "image",
304
- "image_format",
305
- "image_input",
306
- "image_inputs",
307
- "image_size",
308
- "image_url",
309
- "include_rai_reason",
310
- "input_fidelity",
311
- "input_images",
312
- "last_frame",
313
- "last_frame_image",
314
- "mask",
315
- "media",
316
- "moderation",
317
- "num_outputs",
318
- "number_of_images",
319
- "output_compression",
320
- "output_mime_type",
321
- "output_quality",
322
- "partial_images",
323
- "person_generation",
324
- "prompt_image",
325
- "quality",
326
- "ratio",
327
- "reference_strength",
328
- "render_quality",
329
- "resolution",
330
- "seconds",
331
- "start_image",
332
- "start_image_url",
333
- "style",
334
- "video_action",
335
- "video_input",
336
- "multi_speaker",
337
- // Legacy DB keys — normalizer converts at Redux boundary, but we still recognize them
338
- "max_tokens",
339
- "output_format",
340
- "n",
341
- // Frontend-only capability flags (never sent to the API)
342
- "tools",
343
- "file_urls",
344
- "image_urls",
345
- "youtube_videos",
346
- "multi_speaker",
347
- "internal_web_search",
348
- "internal_url_context",
349
- // Backend param not yet in generated types
350
- "image_loras",
351
- // Stop sequences
352
- "stop_sequences"
353
- ]);
354
- var UI_ONLY_SET = new Set(UI_GATE_KEYS);
355
- function mergeEffectiveSettings(defaults, overrides) {
356
- const merged = { ...defaults };
357
- for (const [key, value] of Object.entries(overrides)) {
358
- if (value === null) delete merged[key];
359
- else if (value !== void 0) merged[key] = value;
360
- }
361
- return merged;
362
- }
363
-
364
- // settings/store.ts
365
- var EMPTY = Object.freeze({});
366
- function readSettingsEntry(state, agentId) {
367
- return agentId ? state.entries[agentId] : void 0;
368
- }
369
- function readEffectiveSettings(entry) {
370
- return entry ? mergeEffectiveSettings(entry.defaults, entry.overrides) : EMPTY;
371
- }
372
-
373
- // settings/react/ModelSettingsPanel.tsx
374
- var import_design_system5 = require("@ai-matrx/design-system");
375
- var import_controls4 = require("@ai-matrx/design-system/controls");
376
-
377
- // models/react/context.tsx
378
- var import_react = require("react");
379
- var import_jsx_runtime = require("react/jsx-runtime");
380
- var ModelCatalogContext = (0, import_react.createContext)(null);
381
- function useBinding(hook) {
382
- const binding = (0, import_react.useContext)(ModelCatalogContext);
383
- if (!binding) {
384
- throw new Error(`${hook}() needs <ModelCatalogProvider catalog={createModelCatalog(...)} favorites={createModelFavorites(...)}> above it. A picker with no catalog is a lie on screen.`);
385
- }
386
- return binding;
387
- }
388
- var useModelCatalogUiPorts = () => useBinding("useModelCatalogUiPorts").ports;
389
- function useModelCatalog(variant) {
390
- const { catalog } = useBinding("useModelCatalog");
391
- const state = (0, import_react.useSyncExternalStore)(catalog.subscribe, catalog.getState, catalog.getState);
392
- (0, import_react.useEffect)(() => {
393
- void catalog.load(variant);
394
- }, [catalog, variant]);
395
- const v = state[variant];
396
- const loading = v.status === "idle" || v.status === "loading";
397
- return {
398
- models: loading ? [] : v.models,
399
- isLoading: loading,
400
- error: loading ? null : v.error,
401
- reload: () => {
402
- void catalog.reload(variant);
403
- }
404
- };
405
- }
406
- function useModelFavorites(active) {
407
- const { favorites } = useBinding("useModelFavorites");
408
- const state = (0, import_react.useSyncExternalStore)(favorites.subscribe, favorites.getState, favorites.getState);
409
- (0, import_react.useEffect)(() => {
410
- void favorites.reconcile();
411
- }, [favorites, active]);
412
- const favoriteSet = (0, import_react.useMemo)(() => new Set(state.favoriteIds), [state.favoriteIds]);
413
- return { favoriteIds: state.favoriteIds, favoriteSet, toggleFavorite: favorites.toggle };
414
- }
415
- var NO_LOCAL_MODELS = [];
416
- var noopSubscribe = () => () => {
417
- };
418
- function useLocalModels(override) {
419
- const contextPort = useBinding("useLocalModels").ports.localModels;
420
- const port = override ?? contextPort;
421
- const models = (0, import_react.useSyncExternalStore)(
422
- port ? port.subscribe : noopSubscribe,
423
- port ? port.getModels : () => NO_LOCAL_MODELS,
424
- port ? port.getModels : () => NO_LOCAL_MODELS
425
- );
426
- return { models, groupLabel: port?.groupLabel ?? "On this computer", open: port?.open ? (id) => port.open?.(id) : void 0 };
427
- }
428
-
429
- // models/react/ModelListDropdown.tsx
430
- var import_format = require("@ai-matrx/kit/format");
431
- var import_react2 = require("react");
432
- var import_design_system = require("@ai-matrx/design-system");
433
- var import_controls = require("@ai-matrx/design-system/controls");
434
- var import_brand_glyphs = require("@ai-matrx/icons/brand-glyphs");
435
-
436
- // catalog/shared/icon-paths.ts
437
- var SHAPES = {
438
- star: {
439
- paths: [
440
- "M11.5 3.2a.6.6 0 0 1 1 0l2.3 4.7 5.2.8a.6.6 0 0 1 .3 1l-3.8 3.7.9 5.2a.6.6 0 0 1-.9.6L12 16.8l-4.6 2.4a.6.6 0 0 1-.9-.6l.9-5.2-3.8-3.7a.6.6 0 0 1 .3-1l5.2-.8Z"
441
- ],
442
- fillable: true
443
- },
444
- chevronRight: { paths: ["m9 18 6-6-6-6"] },
445
- chevronDown: { paths: ["m6 9 6 6 6-6"] },
446
- search: {
447
- paths: ["m21 21-4.3-4.3"],
448
- circles: [{ cx: 11, cy: 11, r: 8 }]
449
- },
450
- x: { paths: ["M18 6 6 18", "m6 6 12 12"] },
451
- check: { paths: ["M20 6 9 17l-5-5"] },
452
- arrowUpDown: {
453
- paths: ["m21 16-4 4-4-4", "M17 20V4", "m3 8 4-4 4 4", "M7 4v16"]
454
- },
455
- folder: {
456
- paths: [
457
- "M20 20a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.9a2 2 0 0 1-1.69-.9L9.6 3.9A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2Z"
458
- ]
459
- },
460
- tag: {
461
- paths: [
462
- "M12.586 2.586A2 2 0 0 0 11.172 2H4a2 2 0 0 0-2 2v7.172a2 2 0 0 0 .586 1.414l8.704 8.704a2.426 2.426 0 0 0 3.42 0l6.58-6.58a2.426 2.426 0 0 0 0-3.42z"
463
- ],
464
- circles: [{ cx: 7.5, cy: 7.5, r: 0.5, filled: true }]
465
- },
466
- rotateCcw: {
467
- paths: [
468
- "M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8",
469
- "M3 3v5h5"
470
- ]
471
- },
472
- loader: { paths: ["M21 12a9 9 0 1 1-6.219-8.56"] },
473
- alertTriangle: {
474
- paths: [
475
- "m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3",
476
- "M12 9v4",
477
- "M12 17h.01"
478
- ]
479
- },
480
- /**
481
- * The Orchestra marker (Lucide `music-4`): the glyph the Workflow Studio's
482
- * picker used for a conductor, kept identical so the same agent wears the
483
- * same mark in every client.
484
- */
485
- music4: {
486
- paths: ["M9 18V5l12-2v13", "m9 9 12-2"],
487
- circles: [
488
- { cx: 6, cy: 18, r: 3 },
489
- { cx: 18, cy: 16, r: 3 }
490
- ]
491
- },
492
- clock: {
493
- paths: ["M12 6v6l4 2"],
494
- circles: [{ cx: 12, cy: 12, r: 10 }]
495
- },
496
- globe: {
497
- paths: ["M12 2a14.5 14.5 0 0 0 0 20 14.5 14.5 0 0 0 0-20", "M2 12h20"],
498
- circles: [{ cx: 12, cy: 12, r: 10 }]
499
- },
500
- users: {
501
- paths: [
502
- "M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2",
503
- "M22 21v-2a4 4 0 0 0-3-3.87",
504
- "M16 3.13a4 4 0 0 1 0 7.75"
505
- ],
506
- circles: [{ cx: 9, cy: 7, r: 4 }]
507
- },
508
- externalLink: {
509
- paths: [
510
- "M15 3h6v6",
511
- "M10 14 21 3",
512
- "M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"
513
- ]
514
- },
515
- messageCircle: { paths: ["M7.9 20A9 9 0 1 0 4 16.1L2 22Z"] },
516
- rocket: {
517
- paths: [
518
- "M4.5 16.5c-1.5 1.26-2 5-2 5s3.74-.5 5-2c.71-.84.7-2.13-.09-2.91a2.18 2.18 0 0 0-2.91 0",
519
- "m12 15-3-3a22 22 0 0 1 2-3.95A12.88 12.88 0 0 1 22 2c0 2.72-.78 7.5-6 11a22.35 22.35 0 0 1-4 2",
520
- "M9 12H4s.55-3.03 2-4c1.62-1.08 5 0 5 0",
521
- "M12 15v5s3.03-.55 4-2c1.08-1.62 0-5 0-5"
522
- ]
523
- },
524
- /**
525
- * THE ARCHIVE GLYPH (Lucide `archive`) — the ONE mark of the platform
526
- * archive filter, drawn identically in every Matrx client so the control a
527
- * person learns on one surface is recognizable on all of them.
528
- */
529
- archive: {
530
- paths: [
531
- "M3 3h18a1 1 0 0 1 1 1v3a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1z",
532
- "M4 8v11a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8",
533
- "M10 12h4"
534
- ]
535
- },
536
- circleCheck: {
537
- paths: ["m9 12 2 2 4-4"],
538
- circles: [{ cx: 12, cy: 12, r: 10 }]
539
- }
540
- };
541
- var ICON_PATHS = SHAPES;
542
- var ICON_NAMES = Object.keys(ICON_PATHS);
543
-
544
- // catalog/react/icons.tsx
545
- var import_jsx_runtime2 = require("react/jsx-runtime");
546
- function Svg({ children, ...props }) {
547
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
548
- "svg",
549
- {
550
- xmlns: "http://www.w3.org/2000/svg",
551
- viewBox: "0 0 24 24",
552
- fill: "none",
553
- stroke: "currentColor",
554
- strokeWidth: 2,
555
- strokeLinecap: "round",
556
- strokeLinejoin: "round",
557
- "aria-hidden": "true",
558
- ...props,
559
- children
560
- }
561
- );
562
- }
563
- function Shape({ name, filled }) {
564
- const shape = ICON_PATHS[name];
565
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
566
- shape.paths.map((d, index) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
567
- "path",
568
- {
569
- d,
570
- ...filled && shape.fillable ? { fill: "currentColor" } : {}
571
- },
572
- `p${index}`
573
- )),
574
- (shape.circles ?? []).map((circle, index) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
575
- "circle",
576
- {
577
- cx: circle.cx,
578
- cy: circle.cy,
579
- r: circle.r,
580
- ...circle.filled ? { fill: "currentColor" } : {}
581
- },
582
- `c${index}`
583
- ))
584
- ] });
585
- }
586
- function makeIcon(name) {
587
- return function Icon(props) {
588
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Svg, { ...props, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Shape, { name, filled: false }) });
589
- };
590
- }
591
- var ArrowUpDownIcon = makeIcon("arrowUpDown");
592
- var FolderIcon = makeIcon("folder");
593
- var TagIcon = makeIcon("tag");
594
- var RotateCcwIcon = makeIcon("rotateCcw");
595
- var LoaderIcon = makeIcon("loader");
596
- var UsersIcon = makeIcon("users");
597
- var MessageCircleIcon = makeIcon("messageCircle");
598
- var RocketIcon = makeIcon("rocket");
599
- var CircleCheckIcon = makeIcon("circleCheck");
600
- var AlertTriangleIcon = makeIcon("alertTriangle");
601
- var Music4Icon = makeIcon("music4");
602
- function MousePointerClickIcon(props) {
603
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Svg, { ...props, children: [
604
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M14 4.1 12 6" }),
605
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "m5.1 8-2.9-.8" }),
606
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "m6 12-1.9 2" }),
607
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M7.2 2.2 8 5.1" }),
608
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M9.037 9.69a.498.498 0 0 1 .653-.653l11 4.5a.5.5 0 0 1-.074.949l-4.349 1.041a1 1 0 0 0-.74.739l-1.04 4.35a.5.5 0 0 1-.95.074z" })
609
- ] });
610
- }
611
-
612
- // models/react/icons.tsx
613
- var import_jsx_runtime3 = require("react/jsx-runtime");
614
- function Svg2({ children, ...props }) {
615
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
616
- "svg",
617
- {
618
- xmlns: "http://www.w3.org/2000/svg",
619
- viewBox: "0 0 24 24",
620
- fill: "none",
621
- stroke: "currentColor",
622
- strokeWidth: 2,
623
- strokeLinecap: "round",
624
- strokeLinejoin: "round",
625
- "aria-hidden": "true",
626
- ...props,
627
- children
628
- }
629
- );
630
- }
631
- function ShieldIcon(props) {
632
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Svg2, { ...props, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z" }) });
633
- }
634
- function SlidersHorizontalIcon(props) {
635
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Svg2, { ...props, children: [
636
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M10 5H3" }),
637
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M12 19H3" }),
638
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M14 3v4" }),
639
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M16 17v4" }),
640
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M21 12h-9" }),
641
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M21 19h-5" }),
642
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M21 5h-7" }),
643
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M8 10v4" }),
644
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M8 12H3" })
645
- ] });
646
- }
647
- function TypeIcon(props) {
648
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Svg2, { ...props, children: [
649
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M12 4v16" }),
650
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M4 7V5a1 1 0 0 1 1-1h14a1 1 0 0 1 1 1v2" }),
651
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M9 20h6" })
652
- ] });
653
- }
654
- function ImageIcon(props) {
655
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Svg2, { ...props, children: [
656
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("rect", { width: "18", height: "18", x: "3", y: "3", rx: "2", ry: "2" }),
657
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("circle", { cx: "9", cy: "9", r: "2" }),
658
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21" })
659
- ] });
660
- }
661
- function AudioLinesIcon(props) {
662
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Svg2, { ...props, children: [
663
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M2 10v3" }),
664
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M6 6v11" }),
665
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M10 3v18" }),
666
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M14 8v7" }),
667
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M18 5v13" }),
668
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M22 10v3" })
669
- ] });
670
- }
671
- function BoxesIcon(props) {
672
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Svg2, { ...props, children: [
673
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M2.97 12.92A2 2 0 0 0 2 14.63v3.24a2 2 0 0 0 .97 1.71l3 1.8a2 2 0 0 0 2.06 0L12 19v-5.5l-5-3-4.03 2.42Z" }),
674
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "m7 16.5-4.74-2.85" }),
675
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "m7 16.5 5-3" }),
676
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M7 16.5v5.17" }),
677
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M12 13.5V19l3.97 2.38a2 2 0 0 0 2.06 0l3-1.8a2 2 0 0 0 .97-1.71v-3.24a2 2 0 0 0-.97-1.71L17 10.5l-5 3Z" }),
678
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "m17 16.5-5-3" }),
679
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "m17 16.5 4.74-2.85" }),
680
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M17 16.5v5.17" }),
681
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M7.97 4.42A2 2 0 0 0 7 6.13v4.37l5 3 5-3V6.13a2 2 0 0 0-.97-1.71l-3-1.8a2 2 0 0 0-2.06 0l-3 1.8Z" }),
682
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M12 8 7.26 5.15" }),
683
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "m12 8 4.74-2.85" }),
684
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M12 13.5V8" })
685
- ] });
686
- }
687
- function FileTextIcon(props) {
688
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Svg2, { ...props, children: [
689
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z" }),
690
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M14 2v5a1 1 0 0 0 1 1h5" }),
691
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M10 9H8" }),
692
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M16 13H8" }),
693
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M16 17H8" })
694
- ] });
695
- }
696
- function LayersIcon(props) {
697
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Svg2, { ...props, children: [
698
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M12.83 2.18a2 2 0 0 0-1.66 0L2.6 6.08a1 1 0 0 0 0 1.83l8.58 3.91a2 2 0 0 0 1.66 0l8.58-3.9a1 1 0 0 0 0-1.83z" }),
699
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M2 12a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9A1 1 0 0 0 22 12" }),
700
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M2 17a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9A1 1 0 0 0 22 17" })
701
- ] });
702
- }
703
- function ScaleIcon(props) {
704
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Svg2, { ...props, children: [
705
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M12 3v18" }),
706
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "m19 8 3 8a5 5 0 0 1-6 0zV7" }),
707
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M3 7h1a17 17 0 0 0 8-2 17 17 0 0 0 8 2h1" }),
708
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "m5 8 3 8a5 5 0 0 1-6 0zV7" }),
709
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M7 21h10" })
710
- ] });
711
- }
712
- function LanguagesIcon(props) {
713
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Svg2, { ...props, children: [
714
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "m5 8 6 6" }),
715
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "m4 14 6-6 2-3" }),
716
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M2 5h12" }),
717
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M7 2h1" }),
718
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "m22 22-5-10-5 10" }),
719
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M14 18h6" })
720
- ] });
721
- }
722
-
723
- // models/react/ModelListDropdown.tsx
724
- var import_icons3 = require("@ai-matrx/design-system/icons");
725
- var import_jsx_runtime4 = require("react/jsx-runtime");
726
- var PANEL_HEIGHT = 640;
727
- var LIST_MAX_HEIGHT = `min(${PANEL_HEIGHT}px, var(--radix-popper-available-height, 70dvh))`;
728
- var LIST_WIDTH = 520;
729
- var DETAIL_WIDTH = 540;
730
- var INLINE_LIST_MIN_WIDTH = 400;
731
- var INLINE_DETAIL_MIN_WIDTH = 280;
732
- var ADMIN_PANEL_WIDTH = 400;
733
- var ADMIN_ONLY_SORTS = /* @__PURE__ */ new Set([
734
- "vendor",
735
- "api",
736
- "deprecated",
737
- "availability",
738
- "premium"
739
- ]);
740
- var MODALITY_ICON = {
741
- text: TypeIcon,
742
- image: ImageIcon,
743
- audio: AudioLinesIcon,
744
- video: import_icons3.VideoIcon,
745
- document: FileTextIcon,
746
- entities: BoxesIcon,
747
- embedding: LayersIcon,
748
- decision: ScaleIcon
749
- };
750
- var INTERACTION_LABEL = {
751
- turn: "Standard",
752
- single: "Single-shot",
753
- extraction: "Extraction",
754
- realtime: "Realtime",
755
- embedding: "Embedding",
756
- agent: "Background agent",
757
- decision: "Decision",
758
- adapter: "Adapter",
759
- detection: "Detector"
760
- };
761
- function SpeedDots({ value }) {
762
- const label = speedRatingLabel(value);
763
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
764
- "span",
765
- {
766
- className: "inline-flex items-center gap-1",
767
- title: label == null ? "No speed rating yet" : `Speed ${label}/5`,
768
- children: [
769
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "text-[11px] font-medium tabular-nums text-foreground/80", children: speedRatingWord(value) }),
770
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { className: "inline-flex items-center gap-0.5", children: [
771
- [0, 1, 2, 3, 4].map((i) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
772
- "span",
773
- {
774
- className: (0, import_design_system.cn)(
775
- "h-1.5 w-1.5 rounded-full",
776
- value != null && i < value ? "bg-foreground/70" : "bg-muted-foreground/25"
777
- )
778
- },
779
- i
780
- )),
781
- value != null && value >= 6 && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "text-[9px] leading-none text-amber-500", children: "+" })
782
- ] })
783
- ]
784
- }
785
- );
786
- }
787
- function SpeedCell({ value }) {
788
- const word = speedRatingWord(value);
789
- const label = speedRatingLabel(value);
790
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
791
- DelayedHint,
792
- {
793
- label: label == null ? "No speed rating yet" : `Speed ${word} (${label}/5)`,
794
- children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "inline-block w-11 text-right text-[11px] font-medium tabular-nums text-foreground/80", children: word })
795
- }
796
- );
797
- }
798
- function CostTier({ tier }) {
799
- if (!tier)
800
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "text-[11px] text-muted-foreground/50", children: "\u2014" });
801
- const rating = priceTierRating(tier);
802
- const word = costRatingWord(rating);
803
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
804
- DelayedHint,
805
- {
806
- label: `Relative cost ${word} (${rating >= 6 ? "5+" : rating}/5 compared with other models)`,
807
- children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "inline-block w-11 text-right text-[11px] font-medium tabular-nums text-foreground/80", children: word })
808
- }
809
- );
810
- }
811
- function ModalityIcons({ list }) {
812
- if (list.length === 0)
813
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "text-[11px] text-muted-foreground/50", children: "\u2014" });
814
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "inline-flex flex-nowrap items-center gap-1 whitespace-nowrap", children: list.map((m) => {
815
- const Icon = MODALITY_ICON[m];
816
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
817
- "span",
818
- {
819
- className: "inline-flex shrink-0 items-center gap-0.5 text-xs text-foreground/70",
820
- title: m,
821
- children: [
822
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Icon, { className: "h-3 w-3" }),
823
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "capitalize", children: m })
824
- ]
825
- },
826
- m
827
- );
828
- }) });
829
- }
830
- function AdminRow({
831
- label,
832
- value,
833
- mono
834
- }) {
835
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "flex items-baseline gap-2 whitespace-nowrap", children: [
836
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "w-[76px] shrink-0 text-[10px] uppercase tracking-wide text-muted-foreground", children: label }),
837
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
838
- "span",
839
- {
840
- className: (0, import_design_system.cn)(
841
- "min-w-0 truncate text-[11px] text-foreground/90",
842
- mono && "font-mono"
843
- ),
844
- title: value ?? void 0,
845
- children: value ?? "\u2014"
846
- }
847
- )
848
- ] });
849
- }
850
- function fmtUsd(n) {
851
- return n == null ? "\u2014" : `$${n}`;
852
- }
853
- function fmtPoints(n) {
854
- return n == null ? "\u2014" : n.toLocaleString();
855
- }
856
- function fmtPointsCompact(n) {
857
- return (0, import_format.formatCount)(n, { style: "compact" });
858
- }
859
- function AdminOfferingBlock({
860
- offering,
861
- index,
862
- total
863
- }) {
864
- const unit = offering.usageBasis ? `/ ${offering.usageBasis}` : "/ 1M tokens";
865
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "rounded-md border border-border p-2", children: [
866
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "mb-1.5 flex items-center justify-between gap-2", children: [
867
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { className: "truncate text-[11px] font-semibold text-foreground", children: [
868
- "Offering ",
869
- index + 1,
870
- " of ",
871
- total,
872
- index === 0 ? " \u2014 preferred" : ""
873
- ] }),
874
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
875
- "span",
876
- {
877
- className: (0, import_design_system.cn)(
878
- "shrink-0 rounded px-1.5 py-0.5 text-[9px] font-medium",
879
- offering.isAvailable ? "bg-primary/10 text-foreground/80" : "bg-destructive/15 text-destructive-ink"
880
- ),
881
- children: offering.isAvailable ? "Available" : "Unavailable"
882
- }
883
- )
884
- ] }),
885
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "space-y-0.5", children: [
886
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(AdminRow, { label: "Model", value: offering.providerModelId, mono: true }),
887
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(AdminRow, { label: "Vendor", value: offering.vendor, mono: true }),
888
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(AdminRow, { label: "API", value: offering.apiName, mono: true }),
889
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(AdminRow, { label: "Translator", value: offering.translatorKey, mono: true }),
890
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(AdminRow, { label: "Transport", value: offering.transport, mono: true }),
891
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
892
- AdminRow,
893
- {
894
- label: "Endpoint",
895
- value: offering.endpointDisplayName || offering.endpointInternalName ? `${offering.endpointDisplayName ?? "\u2014"} (${offering.endpointInternalName ?? "\u2014"})` : null
896
- }
897
- ),
898
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(AdminRow, { label: "Priority", value: String(offering.priority), mono: true }),
899
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
900
- AdminRow,
901
- {
902
- label: "Points in",
903
- value: offering.pointsInput == null ? null : `${fmtPoints(offering.pointsInput)} / 1M`,
904
- mono: true
905
- }
906
- ),
907
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
908
- AdminRow,
909
- {
910
- label: "Points out",
911
- value: offering.pointsOutput == null ? null : `${fmtPoints(offering.pointsOutput)} / 1M`,
912
- mono: true
913
- }
914
- ),
915
- offering.pointsCachedInput != null && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
916
- AdminRow,
917
- {
918
- label: "Points cached",
919
- value: `${fmtPoints(offering.pointsCachedInput)} / 1M`,
920
- mono: true
921
- }
922
- ),
923
- offering.pricing.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(AdminRow, { label: "Pricing", value: "\u2014 (no pricing rows)" }) : offering.pricing.map((band, i) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "space-y-0.5", children: [
924
- band.maxTokens != null && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
925
- AdminRow,
926
- {
927
- label: `Band ${i + 1}`,
928
- value: `\u2264 ${(0, import_format.formatCount)(band.maxTokens)} tokens`
929
- }
930
- ),
931
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
932
- AdminRow,
933
- {
934
- label: "Input $",
935
- value: `${fmtUsd(band.inputPrice)} ${unit}`,
936
- mono: true
937
- }
938
- ),
939
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
940
- AdminRow,
941
- {
942
- label: "Output $",
943
- value: `${fmtUsd(band.outputPrice)} ${unit}`,
944
- mono: true
945
- }
946
- ),
947
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
948
- AdminRow,
949
- {
950
- label: "Cached $",
951
- value: `${fmtUsd(band.cachedInputPrice)} ${unit}`,
952
- mono: true
953
- }
954
- )
955
- ] }, i)),
956
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
957
- AdminRow,
958
- {
959
- label: "Billing",
960
- value: offering.usageBasis ? `Usage basis: ${offering.usageBasis}` : offering.tokenBilled ? "Token-billed (provider-reported tokens)" : "Standard $ / 1M tokens"
961
- }
962
- ),
963
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(AdminRow, { label: "Offering", value: offering.offeringId, mono: true })
964
- ] })
965
- ] });
966
- }
967
- function AdminOfferingsSection({ model }) {
968
- const offerings = model.admin?.offerings ?? [];
969
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "flex h-full flex-col", children: [
970
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "shrink-0 border-b border-border px-3 py-2 text-[10px] uppercase tracking-wide text-muted-foreground", children: [
971
- "Offerings \u2014 real vendor / wire data (",
972
- offerings.length,
973
- ")"
974
- ] }),
975
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "min-h-0 flex-1 space-y-2 overflow-y-auto p-2", children: offerings.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "rounded-md border border-destructive/40 bg-destructive/10 p-2 text-[11px] text-destructive-ink", children: "No offerings \u2014 this model is not callable (a model without an `ai.offering` row cannot be routed)." }) : offerings.map((o, i) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
976
- AdminOfferingBlock,
977
- {
978
- offering: o,
979
- index: i,
980
- total: offerings.length
981
- },
982
- o.offeringId
983
- )) })
984
- ] });
985
- }
986
- var SERVICE_CHIP_SELECTED = "rounded border border-primary/40 bg-primary/10 px-1.5 py-0.5 text-[10px] font-medium text-foreground";
987
- var SERVICE_CHIP_UNSELECTED = "rounded border border-border px-1.5 py-0.5 text-[10px] text-foreground/80";
988
- function ModelDetailCard({
989
- model,
990
- tier,
991
- variant,
992
- onSelect,
993
- isCurrentModel,
994
- pinnedOfferingId,
995
- onPinOffering,
996
- includeAdminSection
997
- }) {
998
- const pinnedHere = (t) => !!isCurrentModel && !!pinnedOfferingId && t.offeringId === pinnedOfferingId;
999
- const anyPinnedHere = model.tiers.some(pinnedHere);
1000
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "flex h-full flex-col", children: [
1001
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "min-h-0 flex-1 overflow-y-auto p-4", children: [
1002
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "flex items-start justify-between gap-2", children: [
1003
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "min-w-0", children: [
1004
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "truncate text-sm font-semibold text-foreground", children: model.name }),
1005
- model.maker && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "mt-0.5 flex items-center gap-1 text-xs text-muted-foreground", children: [
1006
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1007
- import_brand_glyphs.MakerBrandGlyph,
1008
- {
1009
- maker: model.maker,
1010
- colored: true,
1011
- className: "h-3.5 w-3.5"
1012
- }
1013
- ),
1014
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: model.maker })
1015
- ] })
1016
- ] }),
1017
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "flex shrink-0 flex-col items-end gap-1", children: [
1018
- model.isPrimary && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "rounded bg-muted px-1.5 py-0.5 text-[10px] font-medium text-foreground/70", children: "Default" }),
1019
- model.isPremium && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "rounded bg-muted px-1.5 py-0.5 text-[10px] font-medium text-foreground/70", children: "Premium" }),
1020
- model.isDeprecated && !model.retiredAt && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1021
- "span",
1022
- {
1023
- className: "rounded bg-destructive/15 px-1.5 py-0.5 text-[10px] font-medium text-destructive-ink",
1024
- title: "Still runs normally; hidden from default selection.",
1025
- children: "Deprecated"
1026
- }
1027
- ),
1028
- model.retiredAt && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1029
- "span",
1030
- {
1031
- className: "rounded bg-destructive/15 px-1.5 py-0.5 text-[10px] font-medium text-destructive-ink",
1032
- title: `The provider no longer serves this model (retired ${model.retiredAt.slice(0, 10)}). It cannot be selected.`,
1033
- children: "Retired"
1034
- }
1035
- )
1036
- ] })
1037
- ] }),
1038
- model.description && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mt-2 line-clamp-3 text-xs text-muted-foreground", children: model.description }),
1039
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("dl", { className: "mt-3 space-y-2 text-xs", children: [
1040
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { children: [
1041
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("dt", { className: "mb-0.5 text-[10px] uppercase tracking-wide text-muted-foreground", children: "Input" }),
1042
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("dd", { children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ModalityIcons, { list: model.input }) })
1043
- ] }),
1044
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { children: [
1045
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("dt", { className: "mb-0.5 text-[10px] uppercase tracking-wide text-muted-foreground", children: "Output" }),
1046
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("dd", { children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ModalityIcons, { list: model.output }) })
1047
- ] }),
1048
- model.features.buckets.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { children: [
1049
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("dt", { className: "mb-0.5 text-[10px] uppercase tracking-wide text-muted-foreground", children: "Features" }),
1050
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("dd", { className: "flex flex-wrap gap-1", children: model.features.buckets.map((b) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1051
- "span",
1052
- {
1053
- className: "whitespace-nowrap rounded border border-border px-1.5 py-0.5 text-[10px] text-foreground/80",
1054
- title: FEATURE_BUCKETS[b].description,
1055
- children: FEATURE_BUCKETS[b].label
1056
- },
1057
- b
1058
- )) })
1059
- ] }),
1060
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "grid grid-cols-2 gap-2", children: [
1061
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "col-span-2", children: [
1062
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("dt", { className: "text-[10px] uppercase tracking-wide text-muted-foreground", children: "Points / 1M tokens" }),
1063
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1064
- "dd",
1065
- {
1066
- className: "whitespace-nowrap text-sm font-semibold tabular-nums text-foreground",
1067
- title: "Points per 1 million tokens \u2014 what usage actually costs you",
1068
- children: model.pointsInput == null && model.pointsOutput == null ? "\u2014" : `${fmtPoints(model.pointsInput)} in \xB7 ${fmtPoints(model.pointsOutput)} out`
1069
- }
1070
- )
1071
- ] }),
1072
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { children: [
1073
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("dt", { className: "text-[10px] uppercase tracking-wide text-muted-foreground", children: "Context window" }),
1074
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("dd", { className: "tabular-nums text-foreground/80", children: model.contextWindow?.toLocaleString() ?? "\u2014" })
1075
- ] }),
1076
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { children: [
1077
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("dt", { className: "text-[10px] uppercase tracking-wide text-muted-foreground", children: "Max output" }),
1078
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("dd", { className: "tabular-nums text-foreground/80", children: model.maxTokens?.toLocaleString() ?? "\u2014" })
1079
- ] }),
1080
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { children: [
1081
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("dt", { className: "text-[10px] uppercase tracking-wide text-muted-foreground", children: "Cost" }),
1082
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("dd", { children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(CostTier, { tier }) })
1083
- ] }),
1084
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { children: [
1085
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("dt", { className: "text-[10px] uppercase tracking-wide text-muted-foreground", children: "Speed" }),
1086
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("dd", { children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(SpeedDots, { value: model.speedRating }) })
1087
- ] }),
1088
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { children: [
1089
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("dt", { className: "text-[10px] uppercase tracking-wide text-muted-foreground", children: "Interaction" }),
1090
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("dd", { className: "text-foreground/80", children: INTERACTION_LABEL[model.interaction] })
1091
- ] })
1092
- ] }),
1093
- model.tiers[0]?.servedVia && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { children: [
1094
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("dt", { className: "mb-0.5 text-[10px] uppercase tracking-wide text-muted-foreground", children: model.tiers.length === 1 ? SERVICE_LABEL : SERVICE_LABEL_PLURAL }),
1095
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("dd", { className: "flex flex-wrap gap-1", children: onPinOffering ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
1096
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1097
- "button",
1098
- {
1099
- type: "button",
1100
- onClick: () => onPinOffering(model, void 0),
1101
- title: "Auto \u2014 the server picks the preferred Service for each call",
1102
- className: (0, import_design_system.cn)(
1103
- "transition-colors",
1104
- !anyPinnedHere ? SERVICE_CHIP_SELECTED : (0, import_design_system.cn)(
1105
- SERVICE_CHIP_UNSELECTED,
1106
- "hover:bg-muted/60 hover:text-foreground"
1107
- )
1108
- ),
1109
- children: "Auto"
1110
- }
1111
- ),
1112
- model.tiers.map((t) => {
1113
- const pinned = pinnedHere(t);
1114
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1115
- "button",
1116
- {
1117
- type: "button",
1118
- onClick: () => onPinOffering(
1119
- model,
1120
- pinned ? void 0 : t.offeringId
1121
- ),
1122
- title: pinned ? "Pinned \u2014 every call uses this Service. Click to return to Auto." : `Pin every call to ${t.servedVia}`,
1123
- className: (0, import_design_system.cn)(
1124
- "transition-colors",
1125
- pinned ? SERVICE_CHIP_SELECTED : (0, import_design_system.cn)(
1126
- SERVICE_CHIP_UNSELECTED,
1127
- "hover:bg-muted/60 hover:text-foreground"
1128
- )
1129
- ),
1130
- children: t.servedVia
1131
- },
1132
- t.offeringId
1133
- );
1134
- })
1135
- ] }) : model.tiers.map((t, i) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1136
- "span",
1137
- {
1138
- className: i === 0 ? SERVICE_CHIP_SELECTED : SERVICE_CHIP_UNSELECTED,
1139
- title: i === 0 ? "Default serving tier" : "Also available on this tier",
1140
- children: t.servedVia
1141
- },
1142
- t.offeringId
1143
- )) })
1144
- ] }),
1145
- model.multilingual && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "flex items-center gap-1 text-foreground/80", children: [
1146
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(LanguagesIcon, { className: "h-3.5 w-3.5" }),
1147
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: "Multilingual" })
1148
- ] }),
1149
- model.features.raw.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { children: [
1150
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("dt", { className: "text-[10px] uppercase tracking-wide text-muted-foreground", children: "All capability flags" }),
1151
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("dd", { className: "font-mono text-[10px] leading-relaxed text-muted-foreground/80", children: model.features.raw.join(", ") })
1152
- ] })
1153
- ] }),
1154
- includeAdminSection && variant === "admin" && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "mt-3 rounded-md border border-border", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(AdminOfferingsSection, { model }) })
1155
- ] }),
1156
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "shrink-0 border-t border-border p-3", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1157
- "button",
1158
- {
1159
- type: "button",
1160
- onClick: onSelect,
1161
- className: "w-full rounded-md bg-primary py-1.5 text-xs font-medium text-primary-foreground transition-colors hover:bg-primary/90",
1162
- children: "Select model"
1163
- }
1164
- ) })
1165
- ] });
1166
- }
1167
- var HOVER_DELAY_MS = 400;
1168
- function DelayedHint({
1169
- label,
1170
- children
1171
- }) {
1172
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_design_system.Tooltip, { children: [
1173
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_design_system.TooltipTrigger, { asChild: true, children }),
1174
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_design_system.TooltipContent, { side: "top", sideOffset: 6, className: "max-w-64 text-xs", children: label })
1175
- ] });
1176
- }
1177
- function ChipRow({ children }) {
1178
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "flex flex-nowrap gap-1 overflow-x-auto pb-0.5", children });
1179
- }
1180
- function ChipToggle({
1181
- active,
1182
- onClick,
1183
- children,
1184
- className
1185
- }) {
1186
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1187
- "button",
1188
- {
1189
- type: "button",
1190
- onClick,
1191
- className: (0, import_design_system.cn)(
1192
- "inline-flex shrink-0 items-center rounded-md border px-2 py-0.5 text-[11px] transition-colors",
1193
- active ? "border-primary bg-primary/10 text-foreground" : "border-border text-muted-foreground hover:text-foreground",
1194
- className
1195
- ),
1196
- children
1197
- }
1198
- );
1199
- }
1200
- function MakerFilterButton({
1201
- maker,
1202
- active,
1203
- onClick
1204
- }) {
1205
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
1206
- "button",
1207
- {
1208
- type: "button",
1209
- "aria-pressed": active,
1210
- "aria-label": `Filter by ${maker}`,
1211
- onClick,
1212
- className: (0, import_design_system.cn)(
1213
- "flex min-w-0 items-center gap-1.5 rounded-md border px-1.5 py-1 text-left transition-colors",
1214
- active ? "border-primary bg-primary/10 text-foreground" : "border-border text-muted-foreground hover:text-foreground"
1215
- ),
1216
- children: [
1217
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_brand_glyphs.MakerBrandGlyph, { maker, colored: true, className: "h-4 w-4 shrink-0" }),
1218
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(DelayedHint, { label: maker, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "min-w-0 truncate text-[11px] font-medium leading-tight", children: maker }) })
1219
- ]
1220
- }
1221
- );
1222
- }
1223
- function ServiceFilterButton({
1224
- service,
1225
- active,
1226
- onClick
1227
- }) {
1228
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
1229
- "button",
1230
- {
1231
- type: "button",
1232
- "aria-pressed": active,
1233
- "aria-label": `Filter by ${service}`,
1234
- onClick,
1235
- className: (0, import_design_system.cn)(
1236
- "flex min-w-0 items-center gap-1.5 rounded-md border px-1.5 py-1 text-left transition-colors",
1237
- active ? "border-primary bg-primary/10 text-foreground" : "border-border text-muted-foreground hover:text-foreground"
1238
- ),
1239
- children: [
1240
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_brand_glyphs.ServiceBrandGlyph, { service, className: "h-4 w-4 shrink-0" }),
1241
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(DelayedHint, { label: service, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "min-w-0 truncate text-[11px] font-medium leading-tight", children: service }) })
1242
- ]
1243
- }
1244
- );
1245
- }
1246
- function TriStateChips({
1247
- value,
1248
- onChange,
1249
- yesLabel,
1250
- noLabel
1251
- }) {
1252
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "flex flex-wrap gap-1", children: [
1253
- ["any", "Any"],
1254
- ["yes", yesLabel],
1255
- ["no", noLabel]
1256
- ].map(([key, label]) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1257
- ChipToggle,
1258
- {
1259
- active: value === key,
1260
- onClick: () => onChange(key),
1261
- children: label
1262
- },
1263
- key
1264
- )) });
1265
- }
1266
- function FilterSection({
1267
- label,
1268
- children
1269
- }) {
1270
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { children: [
1271
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "mb-1 text-[10px] uppercase tracking-wide text-muted-foreground", children: label }),
1272
- children
1273
- ] });
1274
- }
1275
- function FiltersPanel({
1276
- filters,
1277
- setFilters,
1278
- variant,
1279
- makerOptions,
1280
- serviceOptions,
1281
- vendorOptions,
1282
- apiOptions
1283
- }) {
1284
- const toggleModality = (kind, m) => setFilters((f) => {
1285
- const next = new Set(f[kind]);
1286
- if (next.has(m)) next.delete(m);
1287
- else next.add(m);
1288
- return { ...f, [kind]: next };
1289
- });
1290
- const toggleFeature = (b) => setFilters((f) => {
1291
- const next = new Set(f.features);
1292
- if (next.has(b)) next.delete(b);
1293
- else next.add(b);
1294
- return { ...f, features: next };
1295
- });
1296
- const toggleSetValue = (kind, value) => setFilters((f) => {
1297
- const next = new Set(f[kind]);
1298
- if (next.has(value)) next.delete(value);
1299
- else next.add(value);
1300
- return { ...f, [kind]: next };
1301
- });
1302
- const sortOptions = [
1303
- { key: "name", label: "Name" },
1304
- { key: "maker", label: "Maker" },
1305
- { key: "service", label: SERVICE_LABEL },
1306
- { key: "context", label: "Context window" },
1307
- { key: "price", label: variant === "admin" ? "Price ($/M out)" : "Cost" },
1308
- ...variant === "admin" ? [
1309
- { key: "vendor", label: "Vendor" },
1310
- { key: "api", label: "API" },
1311
- { key: "deprecated", label: "Deprecated" },
1312
- { key: "availability", label: "Availability" },
1313
- { key: "premium", label: "Premium" }
1314
- ] : []
1315
- ];
1316
- const setChip = (kind) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "flex flex-wrap gap-1", children: [
1317
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1318
- ChipToggle,
1319
- {
1320
- active: filters[kind].size === 0,
1321
- onClick: () => setFilters((f) => ({ ...f, [kind]: /* @__PURE__ */ new Set() })),
1322
- children: "Any"
1323
- }
1324
- ),
1325
- (kind === "makers" ? makerOptions : kind === "services" ? serviceOptions : kind === "vendors" ? vendorOptions : apiOptions).map((v) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1326
- ChipToggle,
1327
- {
1328
- active: filters[kind].has(v),
1329
- onClick: () => toggleSetValue(kind, v),
1330
- children: v
1331
- },
1332
- v
1333
- ))
1334
- ] });
1335
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "flex h-full flex-col text-xs", children: [
1336
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "min-h-0 flex-1 space-y-3 overflow-y-auto p-3 pb-4", children: [
1337
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(FilterSection, { label: "Sort by", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ChipRow, { children: sortOptions.map((o) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1338
- ChipToggle,
1339
- {
1340
- active: filters.sort === o.key,
1341
- onClick: () => setFilters((f) => ({ ...f, sort: o.key })),
1342
- children: o.label
1343
- },
1344
- o.key
1345
- )) }) }),
1346
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(FilterSection, { label: "Input", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(ChipRow, { children: [
1347
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1348
- ChipToggle,
1349
- {
1350
- active: filters.input.size === 0,
1351
- onClick: () => setFilters((f) => ({ ...f, input: /* @__PURE__ */ new Set() })),
1352
- children: "Any"
1353
- }
1354
- ),
1355
- INPUT_MODALITIES.map((m) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1356
- ChipToggle,
1357
- {
1358
- active: filters.input.has(m),
1359
- onClick: () => toggleModality("input", m),
1360
- children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "capitalize", children: m })
1361
- },
1362
- m
1363
- ))
1364
- ] }) }),
1365
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(FilterSection, { label: "Output", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(ChipRow, { children: [
1366
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1367
- ChipToggle,
1368
- {
1369
- active: filters.output.size === 0,
1370
- onClick: () => setFilters((f) => ({ ...f, output: /* @__PURE__ */ new Set() })),
1371
- children: "Any"
1372
- }
1373
- ),
1374
- OUTPUT_MODALITIES.map((m) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1375
- ChipToggle,
1376
- {
1377
- active: filters.output.has(m),
1378
- onClick: () => toggleModality("output", m),
1379
- children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "capitalize", children: m })
1380
- },
1381
- m
1382
- ))
1383
- ] }) }),
1384
- variant === "admin" && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
1385
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(FilterSection, { label: "Deprecated", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1386
- TriStateChips,
1387
- {
1388
- value: filters.deprecated,
1389
- onChange: (v) => setFilters((f) => ({ ...f, deprecated: v })),
1390
- yesLabel: "Deprecated only",
1391
- noLabel: "Active only"
1392
- }
1393
- ) }),
1394
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(FilterSection, { label: "Availability", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1395
- TriStateChips,
1396
- {
1397
- value: filters.availability,
1398
- onChange: (v) => setFilters((f) => ({ ...f, availability: v })),
1399
- yesLabel: "Available",
1400
- noLabel: "Unavailable"
1401
- }
1402
- ) }),
1403
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(FilterSection, { label: "Premium", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1404
- TriStateChips,
1405
- {
1406
- value: filters.premium,
1407
- onChange: (v) => setFilters((f) => ({ ...f, premium: v })),
1408
- yesLabel: "Premium only",
1409
- noLabel: "Standard only"
1410
- }
1411
- ) }),
1412
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(FilterSection, { label: "Vendor", children: setChip("vendors") }),
1413
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(FilterSection, { label: "API", children: setChip("apis") })
1414
- ] }),
1415
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(FilterSection, { label: "Maker", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "grid grid-cols-3 gap-1", children: [
1416
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1417
- ChipToggle,
1418
- {
1419
- active: filters.makers.size === 0,
1420
- onClick: () => setFilters((f) => ({ ...f, makers: /* @__PURE__ */ new Set() })),
1421
- className: "justify-center py-1",
1422
- children: "Any"
1423
- }
1424
- ),
1425
- makerOptions.map((maker) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1426
- MakerFilterButton,
1427
- {
1428
- maker,
1429
- active: filters.makers.has(maker),
1430
- onClick: () => toggleSetValue("makers", maker)
1431
- },
1432
- maker
1433
- ))
1434
- ] }) }),
1435
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(FilterSection, { label: SERVICE_LABEL, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "grid grid-cols-3 gap-1", children: [
1436
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1437
- ChipToggle,
1438
- {
1439
- active: filters.services.size === 0,
1440
- onClick: () => setFilters((f) => ({ ...f, services: /* @__PURE__ */ new Set() })),
1441
- className: "justify-center py-1",
1442
- children: "Any"
1443
- }
1444
- ),
1445
- serviceOptions.map((service) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1446
- ServiceFilterButton,
1447
- {
1448
- service,
1449
- active: filters.services.has(service),
1450
- onClick: () => toggleSetValue("services", service)
1451
- },
1452
- service
1453
- ))
1454
- ] }) }),
1455
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(FilterSection, { label: "Features", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "flex flex-wrap gap-1", children: FEATURE_BUCKET_ORDER.map((b) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1456
- ChipToggle,
1457
- {
1458
- active: filters.features.has(b),
1459
- onClick: () => toggleFeature(b),
1460
- children: FEATURE_BUCKETS[b].label
1461
- },
1462
- b
1463
- )) }) }),
1464
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(FilterSection, { label: "Interaction", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "flex flex-wrap gap-1", children: ["any", "turn", "single", "extraction", "realtime"].map(
1465
- (i) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1466
- ChipToggle,
1467
- {
1468
- active: filters.interaction === i,
1469
- onClick: () => setFilters((f) => ({ ...f, interaction: i })),
1470
- children: i === "any" ? "Any" : INTERACTION_LABEL[i]
1471
- },
1472
- i
1473
- )
1474
- ) }) })
1475
- ] }),
1476
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "z-10 flex shrink-0 flex-nowrap items-center gap-1 border-t border-border bg-popover px-3 py-2", children: [
1477
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1478
- ChipToggle,
1479
- {
1480
- active: filters.multilingualOnly,
1481
- onClick: () => setFilters((f) => ({ ...f, multilingualOnly: !f.multilingualOnly })),
1482
- className: "flex-1 justify-center",
1483
- children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { className: "inline-flex items-center gap-1", children: [
1484
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(LanguagesIcon, { className: "h-3 w-3" }),
1485
- " Multilingual"
1486
- ] })
1487
- }
1488
- ),
1489
- variant === "user" && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1490
- ChipToggle,
1491
- {
1492
- active: filters.includeDeprecated,
1493
- onClick: () => setFilters((f) => ({
1494
- ...f,
1495
- includeDeprecated: !f.includeDeprecated
1496
- })),
1497
- className: "flex-1 justify-center",
1498
- children: "Include deprecated"
1499
- }
1500
- )
1501
- ] })
1502
- ] });
1503
- }
1504
- function ModelRow({
1505
- model,
1506
- classTier,
1507
- tier,
1508
- variant,
1509
- selected,
1510
- isFavorite,
1511
- locked = false,
1512
- onSelect,
1513
- onHover,
1514
- onToggleFavorite
1515
- }) {
1516
- const unavailable = variant === "admin" && !(model.admin?.offerings ?? []).some((o) => o.isAvailable);
1517
- const retired = model.retiredAt != null;
1518
- const retiredTitle = retired ? `Retired ${model.retiredAt?.slice(0, 10)} \u2014 the provider no longer serves this model, so it cannot be selected.` : locked ? TOP_TIER_LOCKED_TITLE : void 0;
1519
- const blocked = retired || locked;
1520
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
1521
- "div",
1522
- {
1523
- role: "button",
1524
- tabIndex: 0,
1525
- "aria-disabled": blocked || void 0,
1526
- title: retiredTitle,
1527
- onClick: blocked ? void 0 : onSelect,
1528
- onKeyDown: (e) => {
1529
- if (blocked) return;
1530
- if (e.key === "Enter" || e.key === " ") {
1531
- e.preventDefault();
1532
- onSelect();
1533
- }
1534
- },
1535
- onMouseEnter: onHover,
1536
- className: (0, import_design_system.cn)(
1537
- "grid w-full grid-cols-[16px_20px_minmax(0,1fr)_2.75rem_3rem_2.75rem] items-center gap-2 rounded px-2 py-1 transition-colors",
1538
- blocked ? "cursor-not-allowed opacity-60" : "cursor-pointer hover:bg-muted/60 focus:bg-muted/60 focus:outline-none",
1539
- selected && "bg-muted"
1540
- ),
1541
- children: [
1542
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1543
- "button",
1544
- {
1545
- type: "button",
1546
- onClick: (e) => {
1547
- e.stopPropagation();
1548
- onToggleFavorite();
1549
- },
1550
- title: isFavorite ? "Remove favorite" : "Add favorite",
1551
- "aria-label": isFavorite ? "Remove favorite" : "Add favorite",
1552
- className: (0, import_design_system.cn)(
1553
- "flex h-4 w-4 items-center justify-center rounded transition-colors",
1554
- isFavorite ? "text-amber-400" : "text-muted-foreground/30 hover:text-muted-foreground"
1555
- ),
1556
- children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_icons3.StarIcon, { className: (0, import_design_system.cn)("h-3 w-3", isFavorite && "fill-amber-400") })
1557
- }
1558
- ),
1559
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1560
- "span",
1561
- {
1562
- className: "flex w-5 justify-center",
1563
- title: model.maker ?? void 0,
1564
- children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_brand_glyphs.MakerBrandGlyph, { maker: model.maker, colored: true, className: "h-3.5 w-3.5" })
1565
- }
1566
- ),
1567
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { className: "flex min-w-0 items-center gap-1.5", children: [
1568
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(DelayedHint, { label: model.name, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "truncate text-xs font-medium text-foreground", children: model.name }) }),
1569
- isDecisionModelCapability(model) && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1570
- "span",
1571
- {
1572
- className: "shrink-0 rounded border border-primary/40 bg-primary/10 px-1 text-[9px] font-medium text-foreground/80",
1573
- title: "Decision model \u2014 it answers a Questions part with probabilities and generates no text.",
1574
- children: "decision"
1575
- }
1576
- ),
1577
- model.isDeprecated && !retired && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1578
- "span",
1579
- {
1580
- className: "shrink-0 rounded bg-destructive/15 px-1 text-[9px] text-destructive-ink",
1581
- title: "Deprecated \u2014 still runs; hidden from default selection",
1582
- children: "dep"
1583
- }
1584
- ),
1585
- retired && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1586
- "span",
1587
- {
1588
- className: "shrink-0 rounded bg-destructive/15 px-1 text-[9px] text-destructive-ink",
1589
- title: retiredTitle,
1590
- children: "retired"
1591
- }
1592
- ),
1593
- unavailable && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1594
- "span",
1595
- {
1596
- className: "shrink-0 rounded bg-destructive/15 px-1 text-[9px] text-destructive-ink",
1597
- title: "No available offerings \u2014 not callable",
1598
- children: "off"
1599
- }
1600
- ),
1601
- classTier ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1602
- "span",
1603
- {
1604
- className: "shrink-0 rounded border border-primary/40 bg-primary/10 px-1 text-[9px] font-medium text-foreground/80",
1605
- title: `Runs on ${classTier.servedVia}`,
1606
- children: classTier.servedVia
1607
- }
1608
- ) : model.tiers.length > 1 && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1609
- "span",
1610
- {
1611
- className: "shrink-0 rounded border border-primary/40 bg-primary/10 px-1 text-[9px] font-medium text-foreground/80",
1612
- title: model.tiers.map((t) => t.servedVia).join(" \xB7 "),
1613
- children: serviceCountLabel(model.tiers.length)
1614
- }
1615
- )
1616
- ] }),
1617
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(SpeedCell, { value: model.speedRating }),
1618
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1619
- DelayedHint,
1620
- {
1621
- label: model.contextWindow == null ? "No context window listed" : `Context window ${(0, import_format.formatCount)(model.contextWindow)} tokens`,
1622
- children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "block w-12 whitespace-nowrap text-right font-mono text-[11px] tabular-nums text-foreground/80", children: model.contextWindow == null ? "\u2014" : fmtPointsCompact(model.contextWindow) })
1623
- }
1624
- ),
1625
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1626
- DelayedHint,
1627
- {
1628
- label: tier == null ? "No relative cost rating yet" : `Relative cost ${tier.replace("+", "")}${tier.endsWith("+") ? "+" : ""} \u2014 more $ is more expensive`,
1629
- children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "block w-[2.75rem] text-right", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(CostTier, { tier }) })
1630
- }
1631
- )
1632
- ]
1633
- }
1634
- );
140
+ "generate_audio",
141
+ "image",
142
+ "image_format",
143
+ "image_input",
144
+ "image_inputs",
145
+ "image_size",
146
+ "image_url",
147
+ "include_rai_reason",
148
+ "input_fidelity",
149
+ "input_images",
150
+ "last_frame",
151
+ "last_frame_image",
152
+ "mask",
153
+ "media",
154
+ "moderation",
155
+ "num_outputs",
156
+ "number_of_images",
157
+ "output_compression",
158
+ "output_mime_type",
159
+ "output_quality",
160
+ "partial_images",
161
+ "person_generation",
162
+ "prompt_image",
163
+ "quality",
164
+ "ratio",
165
+ "reference_strength",
166
+ "render_quality",
167
+ "resolution",
168
+ "seconds",
169
+ "start_image",
170
+ "start_image_url",
171
+ "style",
172
+ "video_action",
173
+ "video_input",
174
+ "multi_speaker",
175
+ // Legacy DB keys — normalizer converts at Redux boundary, but we still recognize them
176
+ "max_tokens",
177
+ "output_format",
178
+ "n",
179
+ // Frontend-only capability flags (never sent to the API)
180
+ "tools",
181
+ "file_urls",
182
+ "image_urls",
183
+ "youtube_videos",
184
+ "multi_speaker",
185
+ "internal_web_search",
186
+ "internal_url_context",
187
+ // Backend param not yet in generated types
188
+ "image_loras",
189
+ // Stop sequences
190
+ "stop_sequences"
191
+ ]);
192
+ var UI_ONLY_SET = new Set(UI_GATE_KEYS);
193
+ function mergeEffectiveSettings(defaults, overrides) {
194
+ const merged = { ...defaults };
195
+ for (const [key, value] of Object.entries(overrides)) {
196
+ if (value === null) delete merged[key];
197
+ else if (value !== void 0) merged[key] = value;
198
+ }
199
+ return merged;
1635
200
  }
1636
- function LocalModelRow({ model, selected, onSelect }) {
1637
- const dim = model.needsMoreMemory === true;
1638
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
1639
- "div",
1640
- {
1641
- role: "button",
1642
- tabIndex: 0,
1643
- "data-local-model": model.id,
1644
- title: dim ? "Needs more memory than this computer has free" : void 0,
1645
- onClick: onSelect,
1646
- onKeyDown: (e) => {
1647
- if (e.key === "Enter" || e.key === " ") {
1648
- e.preventDefault();
1649
- onSelect();
1650
- }
1651
- },
1652
- className: (0, import_design_system.cn)(
1653
- "grid w-full cursor-pointer grid-cols-[16px_20px_minmax(0,1fr)_2.75rem_3rem_2.75rem] items-center gap-2 rounded px-2 py-1 transition-colors hover:bg-muted/60 focus:bg-muted/60 focus:outline-none",
1654
- dim && "opacity-60",
1655
- selected && "bg-muted"
1656
- ),
1657
- children: [
1658
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "w-4" }),
1659
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "flex w-5 justify-center", title: model.maker ?? void 0, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_brand_glyphs.MakerBrandGlyph, { maker: model.maker ?? null, colored: true, className: "h-3.5 w-3.5" }) }),
1660
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { className: "flex min-w-0 items-center gap-1.5", children: [
1661
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "truncate text-xs font-medium text-foreground", children: model.name }),
1662
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1663
- "span",
1664
- {
1665
- className: "shrink-0 rounded border border-primary/40 bg-primary/10 px-1 text-[9px] font-medium text-foreground/80",
1666
- title: "Runs on this computer",
1667
- children: "local"
1668
- }
1669
- ),
1670
- dim && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "shrink-0 rounded bg-muted px-1 text-[9px] text-muted-foreground", title: "Needs more memory than this computer has free", children: "needs memory" })
1671
- ] }),
1672
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "w-11" }),
1673
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "block w-12 whitespace-nowrap text-right font-mono text-[11px] tabular-nums text-foreground/80", children: model.contextWindow == null ? "\u2014" : fmtPointsCompact(model.contextWindow) }),
1674
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "w-[2.75rem]" })
1675
- ]
1676
- }
1677
- );
201
+
202
+ // settings/store.ts
203
+ var EMPTY = Object.freeze({});
204
+ function readSettingsEntry(state, agentId) {
205
+ return agentId ? state.entries[agentId] : void 0;
1678
206
  }
1679
- var GROUP_HEADING = "px-2 pb-0.5 pt-1.5 text-[10px] uppercase tracking-wide text-muted-foreground";
1680
- function ModelListDropdown({
1681
- value: savedValue,
1682
- localModels: localModelsProp,
1683
- onValueChange,
1684
- inputModalities,
1685
- outputModalities,
1686
- selectionPurpose,
1687
- allowedModelIds,
1688
- catalogVariant,
1689
- emptyOptionLabel,
1690
- onClear,
1691
- placeholder = "Select a model\u2026",
1692
- priorityModelIds,
1693
- pinnedOfferingId,
1694
- onOfferingPinChange,
1695
- modelOnly,
1696
- className,
1697
- triggerVariant = "default",
1698
- presentation = "picker",
1699
- id,
1700
- disabled = false,
1701
- disabledTitle,
1702
- "aria-label": ariaLabel,
1703
- "aria-labelledby": ariaLabelledBy
1704
- }) {
1705
- const isMobile = (0, import_design_system.useIsMobile)();
1706
- const dialogContainer = (0, import_design_system.useDialogContainer)();
1707
- const [pickerOpen, setOpen] = (0, import_react2.useState)(false);
1708
- const inline = presentation === "inline";
1709
- const open = inline || pickerOpen;
1710
- const { favoriteSet, toggleFavorite } = useModelFavorites(open);
1711
- const ports = useModelCatalogUiPorts();
1712
- const canUseTopTier = ports.canUseTopTier ?? false;
1713
- const isSuperAdmin = ports.isSuperAdmin ?? false;
1714
- const LinkComponent = ports.LinkComponent;
1715
- const hiddenModelIds = ports.hiddenModelIds;
1716
- const [adminMode, setAdminMode] = (0, import_react2.useState)(false);
1717
- const variant = catalogVariant ?? (adminMode && isSuperAdmin ? "admin" : "user");
1718
- const effectiveSelectionPurpose = selectionPurpose ?? (variant === "admin" ? "admin" : "chat");
1719
- const { models, isLoading, error } = useModelCatalog(variant);
1720
- const successionIndex = (0, import_react2.useMemo)(() => buildSuccessionIndex(models), [models]);
1721
- const value = savedValue ? resolveSuccessor(savedValue, successionIndex) : savedValue;
1722
- const healedFrom = (0, import_react2.useRef)(null);
1723
- (0, import_react2.useEffect)(() => {
1724
- if (!savedValue || !value || value === savedValue || healedFrom.current === savedValue) return;
1725
- healedFrom.current = savedValue;
1726
- if (onOfferingPinChange && pinnedOfferingId) onOfferingPinChange(void 0);
1727
- onValueChange(value);
1728
- }, [savedValue, value, onOfferingPinChange, pinnedOfferingId, onValueChange]);
1729
- const [query, setQuery] = (0, import_react2.useState)("");
1730
- const [tab, setTab] = (0, import_react2.useState)("all");
1731
- const [rightPanel, setRightPanel] = (0, import_react2.useState)(null);
1732
- const [hovered, setHovered] = (0, import_react2.useState)(null);
1733
- const [hoveredClass, setHoveredClass] = (0, import_react2.useState)(null);
1734
- const [mobileDetail, setMobileDetail] = (0, import_react2.useState)(null);
1735
- const [mobileDetailClass, setMobileDetailClass] = (0, import_react2.useState)(null);
1736
- const [mobileFilters, setMobileFilters] = (0, import_react2.useState)(false);
1737
- const inputRef = (0, import_react2.useRef)(null);
1738
- const [filters, setFilters] = (0, import_react2.useState)(() => ({
1739
- input: new Set(inputModalities),
1740
- output: new Set(outputModalities ?? []),
1741
- features: /* @__PURE__ */ new Set(),
1742
- makers: /* @__PURE__ */ new Set(),
1743
- services: /* @__PURE__ */ new Set(),
1744
- interaction: "any",
1745
- multilingualOnly: false,
1746
- sort: "name",
1747
- vendors: /* @__PURE__ */ new Set(),
1748
- apis: /* @__PURE__ */ new Set(),
1749
- includeDeprecated: false,
1750
- deprecated: "any",
1751
- availability: "any",
1752
- premium: "any"
1753
- }));
1754
- const setVariantMode = (nextAdmin) => {
1755
- setAdminMode(nextAdmin);
1756
- setHovered(null);
1757
- if (!nextAdmin) {
1758
- setFilters((f) => ({
1759
- ...f,
1760
- vendors: /* @__PURE__ */ new Set(),
1761
- apis: /* @__PURE__ */ new Set(),
1762
- deprecated: "any",
1763
- availability: "any",
1764
- premium: "any",
1765
- sort: ADMIN_ONLY_SORTS.has(f.sort) ? "name" : f.sort
1766
- }));
1767
- }
1768
- };
1769
- const allowedModelSet = allowedModelIds ? new Set(allowedModelIds) : null;
1770
- const priorityModelSet = priorityModelIds ? new Set(priorityModelIds) : null;
1771
- const eligibleModels = allowedModelSet ? models.filter((model) => allowedModelSet.has(model.id)) : models;
1772
- const selected = models.find((m) => m.id === value) ?? null;
1773
- const { models: localAll, groupLabel: localGroupLabel, open: openLocal } = useLocalModels(localModelsProp);
1774
- const selectedLocal = localAll.find((m) => m.id === value) ?? null;
1775
- const localEligible = !modelOnly && variant === "user" && !allowedModelSet && (effectiveSelectionPurpose === "chat" || effectiveSelectionPurpose === "agent");
1776
- const localRows = (0, import_react2.useMemo)(() => {
1777
- if (!localEligible || tab !== "all") return [];
1778
- const q = query.trim().toLowerCase();
1779
- return q ? localAll.filter((m) => [m.name, m.maker, "local"].some((f) => f?.toLowerCase().includes(q))) : localAll;
1780
- }, [localEligible, tab, query, localAll]);
1781
- const shown = selected ?? (selectedLocal ? { name: selectedLocal.name, maker: selectedLocal.maker ?? null } : null);
1782
- const makerOptions = (0, import_react2.useMemo)(
1783
- () => [
1784
- ...new Set(
1785
- eligibleModels.map((m) => m.maker).filter((v) => !!v)
1786
- )
1787
- ].sort((a, b) => a.localeCompare(b)),
1788
- [eligibleModels]
1789
- );
1790
- const serviceOptions = (0, import_react2.useMemo)(
1791
- () => [
1792
- ...new Set(
1793
- eligibleModels.flatMap((m) => m.tiers.map((t) => t.servedVia)).filter(Boolean)
1794
- )
1795
- ].sort((a, b) => a.localeCompare(b)),
1796
- [eligibleModels]
1797
- );
1798
- const vendorOptions = (0, import_react2.useMemo)(
1799
- () => [
1800
- ...new Set(
1801
- eligibleModels.flatMap((m) => (m.admin?.offerings ?? []).map((o) => o.vendor)).filter((v) => !!v)
1802
- )
1803
- ].sort((a, b) => a.localeCompare(b)),
1804
- [eligibleModels]
1805
- );
1806
- const apiOptions = (0, import_react2.useMemo)(
1807
- () => [
1808
- ...new Set(
1809
- eligibleModels.flatMap((m) => (m.admin?.offerings ?? []).map((o) => o.apiName)).filter((v) => !!v)
1810
- )
1811
- ].sort((a, b) => a.localeCompare(b)),
1812
- [eligibleModels]
1813
- );
1814
- const chatFitApplies = effectiveSelectionPurpose === "chat" && !(outputModalities ?? []).some((o) => o !== "text");
1815
- const filtered = (0, import_react2.useMemo)(() => {
1816
- const q = query.trim().toLowerCase();
1817
- const hasAvailable = (m) => (m.admin?.offerings ?? []).some((o) => o.isAvailable);
1818
- const rows = eligibleModels.filter((m) => {
1819
- const isDecision = isDecisionModelCapability(m);
1820
- if (effectiveSelectionPurpose === "chat" && isDecision) return false;
1821
- if (effectiveSelectionPurpose === "decision" && !isDecision) return false;
1822
- if (effectiveSelectionPurpose !== "admin" && !acceptsTextInstructions(m))
1823
- return false;
1824
- if (effectiveSelectionPurpose === "chat" && isManagedAgentModelCapability(m))
1825
- return false;
1826
- if (chatFitApplies && !isChatModelCapability(m)) return false;
1827
- if (tab === "favorites" && !favoriteSet.has(m.id)) return false;
1828
- const haystack = [
1829
- m.name,
1830
- m.maker,
1831
- ...m.tiers.map((t) => t.servedVia),
1832
- ...variant === "admin" ? (m.admin?.offerings ?? []).flatMap((o) => [
1833
- o.vendor,
1834
- o.apiName,
1835
- o.providerModelId
1836
- ]) : []
1837
- ];
1838
- if (q && !haystack.some((f) => f?.toLowerCase().includes(q)))
1839
- return false;
1840
- if (filters.makers.size > 0 && (!m.maker || !filters.makers.has(m.maker)))
1841
- return false;
1842
- if (filters.services.size > 0 && !m.tiers.some((t) => filters.services.has(t.servedVia)))
1843
- return false;
1844
- if (filters.vendors.size > 0 && !(m.admin?.offerings ?? []).some(
1845
- (o) => o.vendor != null && filters.vendors.has(o.vendor)
1846
- ))
1847
- return false;
1848
- if (filters.apis.size > 0 && !(m.admin?.offerings ?? []).some(
1849
- (o) => o.apiName != null && filters.apis.has(o.apiName)
1850
- ))
1851
- return false;
1852
- if (variant === "user" && m.id !== value && hiddenModelIds?.includes(m.id))
1853
- return false;
1854
- if (variant === "user" && !filters.includeDeprecated && m.isDeprecated && m.id !== value)
1855
- return false;
1856
- if (variant === "user" && resolveSuccessor(m.id, successionIndex) !== m.id) return false;
1857
- if (filters.deprecated !== "any") {
1858
- if (filters.deprecated === "yes" !== m.isDeprecated) return false;
1859
- }
1860
- if (filters.availability !== "any") {
1861
- if (filters.availability === "yes" !== hasAvailable(m)) return false;
1862
- }
1863
- if (filters.premium !== "any") {
1864
- if (filters.premium === "yes" !== m.isPremium) return false;
1865
- }
1866
- for (const m2 of filters.input) if (!takesInput(m, m2)) return false;
1867
- const outputSatisfied = (want) => m.output.includes(want) || effectiveSelectionPurpose === "agent" && isDecision && want === "text";
1868
- for (const m2 of filters.output) if (!outputSatisfied(m2)) return false;
1869
- for (const b of filters.features)
1870
- if (!m.features.buckets.includes(b)) return false;
1871
- if (filters.interaction !== "any" && m.interaction !== filters.interaction)
1872
- return false;
1873
- if (filters.multilingualOnly && !m.multilingual) return false;
1874
- return true;
1875
- });
1876
- const cmp = (a, b) => {
1877
- switch (filters.sort) {
1878
- case "maker":
1879
- return (a.maker ?? "").localeCompare(b.maker ?? "");
1880
- case "service":
1881
- return (a.tiers[0]?.servedVia ?? "\uFFFF").localeCompare(
1882
- b.tiers[0]?.servedVia ?? "\uFFFF"
1883
- ) || b.tiers.length - a.tiers.length;
1884
- case "context":
1885
- return (b.contextWindow ?? 0) - (a.contextWindow ?? 0);
1886
- case "price": {
1887
- const price = (m) => (variant === "admin" ? m.outputCost : m.costRating) ?? Infinity;
1888
- return price(a) - price(b) || a.name.localeCompare(b.name);
1889
- }
1890
- case "vendor":
1891
- return (a.admin?.offerings[0]?.vendor ?? "\uFFFF").localeCompare(
1892
- b.admin?.offerings[0]?.vendor ?? "\uFFFF"
1893
- ) || a.name.localeCompare(b.name);
1894
- case "api":
1895
- return (a.admin?.offerings[0]?.apiName ?? "\uFFFF").localeCompare(
1896
- b.admin?.offerings[0]?.apiName ?? "\uFFFF"
1897
- ) || a.name.localeCompare(b.name);
1898
- case "deprecated":
1899
- return Number(a.isDeprecated) - Number(b.isDeprecated) || a.name.localeCompare(b.name);
1900
- case "availability": {
1901
- const avail = (m) => (m.admin?.offerings ?? []).filter((o) => o.isAvailable).length;
1902
- return avail(b) - avail(a) || a.name.localeCompare(b.name);
1903
- }
1904
- case "premium":
1905
- return Number(b.isPremium) - Number(a.isPremium) || a.name.localeCompare(b.name);
1906
- default:
1907
- return a.name.localeCompare(b.name);
1908
- }
1909
- };
1910
- const sorted = [...rows].sort(cmp);
1911
- const prioritize = (items) => {
1912
- if (!priorityModelSet || priorityModelSet.size === 0) return items;
1913
- const priority = items.filter((m) => priorityModelSet.has(m.id));
1914
- const rest = items.filter((m) => !priorityModelSet.has(m.id));
1915
- return [...priority, ...rest];
1916
- };
1917
- if (tab === "all") {
1918
- const favs = sorted.filter((m) => favoriteSet.has(m.id));
1919
- const rest = sorted.filter((m) => !favoriteSet.has(m.id));
1920
- return [...prioritize(favs), ...prioritize(rest)];
1921
- }
1922
- return prioritize(sorted);
1923
- }, [
1924
- eligibleModels,
1925
- query,
1926
- filters,
1927
- tab,
1928
- favoriteSet,
1929
- variant,
1930
- priorityModelSet,
1931
- effectiveSelectionPurpose,
1932
- chatFitApplies,
1933
- hiddenModelIds,
1934
- value,
1935
- successionIndex
1936
- ]);
1937
- const listRows = (0, import_react2.useMemo)(
1938
- () => filtered.flatMap((m) => {
1939
- if (modelOnly || m.tiers.length < 2) {
1940
- return [{ model: m, classTier: null }];
1941
- }
1942
- const classes = filters.services.size > 0 ? m.tiers.filter((t) => filters.services.has(t.servedVia)) : m.tiers;
1943
- return classes.map((t) => ({ model: m, classTier: t }));
1944
- }),
1945
- [filtered, modelOnly, filters.services]
1946
- );
1947
- const selectedClass = selected ? selected.tiers.find((t) => t.offeringId === pinnedOfferingId) ?? selected.tiers[0] ?? null : null;
1948
- const selectedClassLabel = !modelOnly && selected && selected.tiers.length > 1 ? selectedClass?.servedVia : void 0;
1949
- const activeFilterCount = filters.input.size + filters.output.size + filters.features.size + filters.makers.size + filters.services.size + filters.vendors.size + filters.apis.size + (filters.deprecated !== "any" ? 1 : 0) + (filters.availability !== "any" ? 1 : 0) + (filters.premium !== "any" ? 1 : 0) + (filters.interaction !== "any" ? 1 : 0) + (filters.multilingualOnly ? 1 : 0) + (filters.includeDeprecated ? 1 : 0);
1950
- const handleOpen = (next) => {
1951
- setOpen(next);
1952
- if (next) {
1953
- setTimeout(() => inputRef.current?.focus(), 50);
1954
- } else {
1955
- setRightPanel(null);
1956
- setHovered(null);
1957
- setMobileDetail(null);
1958
- setMobileFilters(false);
1959
- setQuery("");
1960
- }
1961
- };
1962
- const refuseIfRetired = (id2) => {
1963
- const target = models.find((m) => m.id === id2);
1964
- if (target && !canUseTopTier && isTopTierRating(target.costRating)) {
1965
- console.warn(`[ModelListDropdown] Refused to select ${target.name} (${id2}): ${TOP_TIER_LOCKED_TITLE}.`);
1966
- return true;
1967
- }
1968
- if (!target?.retiredAt) return false;
1969
- console.warn(
1970
- `[ModelListDropdown] Refused to select ${target.name} (${id2}): retired ${target.retiredAt} \u2014 the provider no longer serves it.`
1971
- );
1972
- return true;
1973
- };
1974
- const handleSelectClass = (model, classTier) => {
1975
- if (refuseIfRetired(model.id)) return;
1976
- if (onOfferingPinChange) {
1977
- const nextPin = classTier && model.tiers.length > 1 ? classTier.offeringId : void 0;
1978
- if (nextPin !== (pinnedOfferingId ?? void 0)) onOfferingPinChange(nextPin);
1979
- }
1980
- onValueChange(model.id);
1981
- handleOpen(false);
1982
- };
1983
- const handleSelect = (id2, tappedClass) => {
1984
- const next = models.find((m) => m.id === id2);
1985
- if (!next) return;
1986
- const pinnedHere = next.tiers.find((t) => t.offeringId === pinnedOfferingId) ?? null;
1987
- handleSelectClass(next, tappedClass ?? pinnedHere ?? next.tiers[0] ?? null);
1988
- };
1989
- const handleSelectLocal = (local) => {
1990
- if (openLocal) {
1991
- openLocal(local.id);
1992
- handleOpen(false);
1993
- return;
1994
- }
1995
- if (onOfferingPinChange && pinnedOfferingId) onOfferingPinChange(void 0);
1996
- onValueChange(local.id);
1997
- handleOpen(false);
1998
- };
1999
- const handleClear = () => {
2000
- onClear?.();
2001
- handleOpen(false);
2002
- };
2003
- const handlePinOffering = (model, offeringId) => {
2004
- if (!onOfferingPinChange) return;
2005
- if (refuseIfRetired(model.id)) return;
2006
- onOfferingPinChange(offeringId);
2007
- if (model.id !== value) onValueChange(model.id);
2008
- };
2009
- const trigger = /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
2010
- "button",
2011
- {
2012
- type: "button",
2013
- id,
2014
- disabled,
2015
- title: disabled ? disabledTitle : void 0,
2016
- "aria-label": ariaLabel,
2017
- "aria-labelledby": ariaLabelledBy,
2018
- "aria-disabled": disabled || void 0,
2019
- className: (0, import_design_system.cn)(
2020
- triggerVariant === "settings" ? (0, import_design_system.selectTriggerVariants)({
2021
- size: "default",
2022
- className: "h-auto min-h-9 max-lg:min-h-11 pointer-coarse:min-h-11 w-full min-w-0 max-w-full whitespace-normal text-left font-medium text-foreground"
2023
- }) : "inline-flex h-7 min-w-0 max-w-full items-center gap-1 overflow-hidden rounded-md bg-transparent px-1 text-xs font-medium text-foreground/80 transition-colors hover:text-foreground",
2024
- disabled && "cursor-not-allowed opacity-50 hover:text-foreground/80",
2025
- className
2026
- ),
2027
- children: [
2028
- triggerVariant === "settings" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "flex min-w-0 flex-1 items-center gap-1.5", children: shown ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
2029
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
2030
- import_brand_glyphs.MakerBrandGlyph,
2031
- {
2032
- maker: shown.maker,
2033
- colored: true,
2034
- className: "h-3.5 w-3.5 shrink-0"
2035
- }
2036
- ),
2037
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { className: "min-w-0 whitespace-normal text-left leading-tight", children: [
2038
- shown.name,
2039
- selectedClassLabel && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { className: "text-muted-foreground", children: [
2040
- " \xB7 ",
2041
- selectedClassLabel
2042
- ] })
2043
- ] })
2044
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "min-w-0 whitespace-normal text-left leading-tight text-muted-foreground", children: isLoading ? "Loading models\u2026" : emptyOptionLabel && !value ? emptyOptionLabel : placeholder }) }) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "flex min-w-0 flex-1 items-center gap-1.5", children: shown ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
2045
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
2046
- import_brand_glyphs.MakerBrandGlyph,
2047
- {
2048
- maker: shown.maker,
2049
- colored: true,
2050
- className: "h-3.5 w-3.5 shrink-0"
2051
- }
2052
- ),
2053
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { className: "min-w-0 truncate", children: [
2054
- shown.name,
2055
- selectedClassLabel && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { className: "text-muted-foreground", children: [
2056
- " \xB7 ",
2057
- selectedClassLabel
2058
- ] })
2059
- ] })
2060
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "min-w-0 truncate text-muted-foreground", children: isLoading ? "Loading models\u2026" : emptyOptionLabel && !value ? emptyOptionLabel : placeholder }) }),
2061
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
2062
- import_icons3.ChevronDownIcon,
2063
- {
2064
- className: (0, import_design_system.cn)(
2065
- "shrink-0 text-muted-foreground/60",
2066
- triggerVariant === "settings" ? "h-4 w-4" : "h-3 w-3"
2067
- )
2068
- }
2069
- )
2070
- ]
2071
- }
2072
- );
2073
- const listPanel = /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "flex h-full flex-col", children: [
2074
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "flex items-center gap-1.5 border-b border-border p-2", children: [
2075
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "relative flex-1", children: [
2076
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_icons3.SearchIcon, { className: "absolute left-2 top-1/2 h-3.5 w-3.5 -translate-y-1/2 text-muted-foreground" }),
2077
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
2078
- import_controls.Input,
2079
- {
2080
- adornment: "start",
2081
- ref: inputRef,
2082
- value: query,
2083
- onChange: (e) => setQuery(e.target.value),
2084
- placeholder: "Search models\u2026"
2085
- }
2086
- )
2087
- ] }),
2088
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
2089
- "button",
2090
- {
2091
- type: "button",
2092
- onClick: () => isMobile ? setMobileFilters(true) : setRightPanel(rightPanel === "filters" ? null : "filters"),
2093
- className: (0, import_design_system.cn)(
2094
- "inline-flex h-7 items-center gap-1 rounded-md border px-2 text-[11px] transition-colors",
2095
- rightPanel === "filters" ? "border-primary bg-primary/10 text-foreground" : "border-border text-muted-foreground hover:text-foreground"
2096
- ),
2097
- children: [
2098
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(SlidersHorizontalIcon, { className: "h-3.5 w-3.5" }),
2099
- "Filters",
2100
- activeFilterCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "text-primary", children: activeFilterCount })
2101
- ]
2102
- }
2103
- )
2104
- ] }),
2105
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "flex items-center gap-1 border-b border-border px-2 py-1", children: ["all", "favorites"].map((t) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
2106
- "button",
2107
- {
2108
- type: "button",
2109
- onClick: () => setTab(t),
2110
- className: (0, import_design_system.cn)(
2111
- "inline-flex items-center gap-1 rounded px-2 py-0.5 text-[11px] transition-colors",
2112
- tab === t ? "bg-accent text-foreground" : "text-muted-foreground hover:text-foreground"
2113
- ),
2114
- children: [
2115
- t === "favorites" && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
2116
- import_icons3.StarIcon,
2117
- {
2118
- className: (0, import_design_system.cn)(
2119
- "h-3 w-3",
2120
- tab === t && "fill-amber-400 text-amber-400"
2121
- )
2122
- }
2123
- ),
2124
- t === "all" ? "All" : "Favorites",
2125
- t === "favorites" && favoriteSet.size > 0 && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "text-muted-foreground", children: favoriteSet.size })
2126
- ]
2127
- },
2128
- t
2129
- )) }),
2130
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "grid grid-cols-[16px_20px_minmax(0,1fr)_2.75rem_3rem_2.75rem] gap-2 border-b border-border px-2 py-1 text-[10px] uppercase tracking-wide text-muted-foreground", children: [
2131
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "w-4" }),
2132
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "w-5", title: "Maker", "aria-label": "Maker" }),
2133
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: "Name" }),
2134
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "w-11 text-right", children: "Speed" }),
2135
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(DelayedHint, { label: "How many tokens this model can hold in one conversation", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "block w-12 text-right", title: "Context window", children: "Window" }) }),
2136
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(DelayedHint, { label: "Relative cost band \u2014 more $ is more expensive. Not your personal usage.", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "block w-[2.75rem] text-right", children: "Cost" }) })
2137
- ] }),
2138
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "min-h-0 flex-1 overflow-y-auto p-1", children: error ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "p-3 text-xs text-destructive", children: [
2139
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "font-medium", children: [
2140
- "Failed to load ",
2141
- variant,
2142
- " catalog"
2143
- ] }),
2144
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "mt-0.5 font-mono text-[11px] opacity-80", children: error }),
2145
- variant === "admin" && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "mt-1 text-[11px] text-muted-foreground", children: "If this is a 42501, the admin_model_catalog RPC rejected your role (super admin required)." }),
2146
- ports.renderErrorAction?.(void 0)
2147
- ] }) : isLoading ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "p-4 text-center text-xs text-muted-foreground", children: "Loading catalog\u2026" }) : /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
2148
- emptyOptionLabel && onClear && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
2149
- "button",
2150
- {
2151
- type: "button",
2152
- onClick: handleClear,
2153
- className: (0, import_design_system.cn)(
2154
- "mb-1 w-full rounded px-2 py-1.5 text-left text-xs transition-colors hover:bg-muted/60 focus:bg-muted/60 focus:outline-none",
2155
- !value ? "bg-muted font-medium text-foreground" : "text-muted-foreground"
2156
- ),
2157
- children: emptyOptionLabel
2158
- }
2159
- ),
2160
- localRows.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
2161
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: GROUP_HEADING, children: localGroupLabel }),
2162
- localRows.map((l) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(LocalModelRow, { model: l, selected: l.id === value, onSelect: () => handleSelectLocal(l) }, l.id)),
2163
- filtered.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: GROUP_HEADING, children: "Cloud" })
2164
- ] }),
2165
- filtered.length === 0 ? localRows.length > 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "p-4 text-center text-xs text-muted-foreground", children: "No models match your filters." }) : listRows.map(({ model: m, classTier }) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
2166
- ModelRow,
2167
- {
2168
- model: m,
2169
- classTier,
2170
- tier: costRatingTier(m.costRating),
2171
- variant,
2172
- selected: m.id === value && (classTier == null || classTier.offeringId === selectedClass?.offeringId),
2173
- isFavorite: favoriteSet.has(m.id),
2174
- locked: !canUseTopTier && isTopTierRating(m.costRating),
2175
- onToggleFavorite: () => toggleFavorite(m.id),
2176
- onSelect: () => isMobile ? (setMobileDetail(m), setMobileDetailClass(classTier)) : handleSelectClass(m, classTier),
2177
- onHover: isMobile ? void 0 : () => {
2178
- setHovered(m);
2179
- setHoveredClass(classTier);
2180
- if (rightPanel !== "filters") setRightPanel("detail");
2181
- }
2182
- },
2183
- classTier ? `${m.id}:${classTier.offeringId}` : m.id
2184
- ))
2185
- ] }) }),
2186
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "flex items-center justify-between gap-2 border-t border-border px-2 py-1 text-[10px] text-muted-foreground", children: [
2187
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: error ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
2188
- "Models couldn't be loaded",
2189
- ports.renderErrorAction?.(String(error))
2190
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
2191
- listRows.length + localRows.length,
2192
- " model",
2193
- listRows.length + localRows.length === 1 ? "" : "s",
2194
- variant === "user" && (hiddenModelIds?.length ?? 0) > 0 ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
2195
- " \xB7 ",
2196
- ports.settingsHref && LinkComponent ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(LinkComponent, { href: ports.settingsHref, className: "underline hover:text-foreground", children: [
2197
- hiddenModelIds?.length,
2198
- " hidden by you"
2199
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
2200
- hiddenModelIds?.length,
2201
- " hidden by you"
2202
- ] })
2203
- ] }) : null
2204
- ] }) }),
2205
- isSuperAdmin && catalogVariant == null && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
2206
- "button",
2207
- {
2208
- type: "button",
2209
- onClick: () => setVariantMode(variant !== "admin"),
2210
- title: variant === "admin" ? "Admin view \u2014 real vendor/api/$ data. Click to return to the user view." : "Switch to the admin view (real vendor/api/$ data)",
2211
- className: (0, import_design_system.cn)(
2212
- "inline-flex items-center gap-1 rounded px-1.5 py-0.5 transition-colors",
2213
- variant === "admin" ? "bg-primary/10 text-foreground" : "hover:text-foreground"
2214
- ),
2215
- children: [
2216
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ShieldIcon, { className: "h-3 w-3" }),
2217
- "Admin"
2218
- ]
2219
- }
2220
- )
2221
- ] })
2222
- ] });
2223
- if (disabled) {
2224
- return trigger;
2225
- }
2226
- const mobileBody = /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "flex min-h-0 flex-1 flex-col overflow-hidden", children: mobileDetail ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
2227
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
2228
- "button",
2229
- {
2230
- onClick: () => setMobileDetail(null),
2231
- className: "flex shrink-0 items-center gap-1.5 border-b border-border px-3 py-2.5 text-sm font-medium text-primary",
2232
- children: [
2233
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_icons3.ChevronRightIcon, { className: "h-4 w-4 rotate-180" }),
2234
- " Back"
2235
- ]
2236
- }
2237
- ),
2238
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "min-h-0 flex-1 overflow-y-auto", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
2239
- ModelDetailCard,
2240
- {
2241
- model: mobileDetail,
2242
- tier: costRatingTier(mobileDetail.costRating),
2243
- variant,
2244
- onSelect: () => handleSelect(mobileDetail.id, mobileDetailClass),
2245
- isCurrentModel: mobileDetail.id === value,
2246
- pinnedOfferingId,
2247
- onPinOffering: onOfferingPinChange ? handlePinOffering : void 0,
2248
- includeAdminSection: true
2249
- }
2250
- ) })
2251
- ] }) : mobileFilters ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
2252
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
2253
- "button",
2254
- {
2255
- onClick: () => setMobileFilters(false),
2256
- className: "flex shrink-0 items-center gap-1.5 border-b border-border px-3 py-2.5 text-sm font-medium text-primary",
2257
- children: [
2258
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_icons3.ChevronRightIcon, { className: "h-4 w-4 rotate-180" }),
2259
- " Back"
2260
- ]
2261
- }
2262
- ),
2263
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "min-h-0 flex-1", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
2264
- FiltersPanel,
2265
- {
2266
- filters,
2267
- setFilters,
2268
- variant,
2269
- makerOptions,
2270
- serviceOptions,
2271
- vendorOptions,
2272
- apiOptions
2273
- }
2274
- ) })
2275
- ] }) : listPanel });
2276
- if (isMobile && inline) {
2277
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_design_system.TooltipProvider, { delayDuration: HOVER_DELAY_MS, skipDelayDuration: HOVER_DELAY_MS, children: mobileBody });
2278
- }
2279
- if (isMobile) {
2280
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_design_system.Drawer, { open, onOpenChange: handleOpen, children: [
2281
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_design_system.DrawerTrigger, { asChild: true, children: trigger }),
2282
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_design_system.DrawerContent, { className: "h-[85dvh]", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
2283
- import_design_system.TooltipProvider,
2284
- {
2285
- delayDuration: HOVER_DELAY_MS,
2286
- skipDelayDuration: HOVER_DELAY_MS,
2287
- children: [
2288
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_design_system.DrawerTitle, { className: "sr-only", children: "Select model" }),
2289
- mobileBody
2290
- ]
2291
- }
2292
- ) })
2293
- ] });
2294
- }
2295
- const popoverWidth = LIST_WIDTH + DETAIL_WIDTH + (variant === "admin" ? ADMIN_PANEL_WIDTH : 0);
2296
- const adminPanelModel = hovered ?? selected;
2297
- const desktopBody = /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
2298
- import_design_system.TooltipProvider,
2299
- {
2300
- delayDuration: HOVER_DELAY_MS,
2301
- skipDelayDuration: HOVER_DELAY_MS,
2302
- children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "h-full overflow-x-auto overflow-y-hidden", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
2303
- "div",
2304
- {
2305
- className: "flex h-full",
2306
- style: inline ? void 0 : { minWidth: popoverWidth },
2307
- children: [
2308
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
2309
- "div",
2310
- {
2311
- className: "flex h-full min-h-0 flex-col border-r border-border",
2312
- style: inline ? { flex: `0 1 ${LIST_WIDTH}px`, minWidth: INLINE_LIST_MIN_WIDTH } : { width: LIST_WIDTH, flexShrink: 0 },
2313
- children: listPanel
2314
- }
2315
- ),
2316
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
2317
- "div",
2318
- {
2319
- className: "flex h-full min-h-0 flex-col overflow-hidden",
2320
- style: inline ? { flex: "1 1 0", minWidth: INLINE_DETAIL_MIN_WIDTH } : { width: DETAIL_WIDTH, flexShrink: 0 },
2321
- children: rightPanel === "filters" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
2322
- FiltersPanel,
2323
- {
2324
- filters,
2325
- setFilters,
2326
- variant,
2327
- makerOptions,
2328
- serviceOptions,
2329
- vendorOptions,
2330
- apiOptions
2331
- }
2332
- ) : rightPanel === "detail" && hovered ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
2333
- "div",
2334
- {
2335
- className: "h-full animate-in fade-in-0 duration-300",
2336
- children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
2337
- ModelDetailCard,
2338
- {
2339
- model: hovered,
2340
- tier: costRatingTier(hovered.costRating),
2341
- variant,
2342
- onSelect: () => handleSelect(hovered.id, hoveredClass),
2343
- isCurrentModel: hovered.id === value,
2344
- pinnedOfferingId,
2345
- onPinOffering: onOfferingPinChange ? handlePinOffering : void 0
2346
- }
2347
- )
2348
- },
2349
- hovered.id
2350
- ) : /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "flex flex-1 flex-col items-center justify-center gap-2 px-6 text-center", children: [
2351
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(MousePointerClickIcon, { className: "h-6 w-6 text-muted-foreground/40" }),
2352
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "text-xs leading-relaxed text-muted-foreground/70", children: "Hover a model to preview its details, or click to select." })
2353
- ] })
2354
- }
2355
- ),
2356
- variant === "admin" && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
2357
- "div",
2358
- {
2359
- className: "flex h-full min-h-0 shrink-0 flex-col overflow-hidden border-l border-border",
2360
- style: { width: ADMIN_PANEL_WIDTH },
2361
- children: adminPanelModel ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(AdminOfferingsSection, { model: adminPanelModel }) : /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "flex flex-1 flex-col items-center justify-center gap-2 px-6 text-center", children: [
2362
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ShieldIcon, { className: "h-6 w-6 text-muted-foreground/40" }),
2363
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "text-xs leading-relaxed text-muted-foreground/70", children: "Hover a model to see every offering's real vendor, api, provider model id and $ pricing." })
2364
- ] })
2365
- }
2366
- )
2367
- ]
2368
- }
2369
- ) })
2370
- }
2371
- );
2372
- if (inline) {
2373
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "h-full w-full min-w-0", children: desktopBody });
2374
- }
2375
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_design_system.Popover, { open, onOpenChange: handleOpen, modal: false, children: [
2376
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_design_system.PopoverTrigger, { asChild: true, children: trigger }),
2377
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
2378
- import_design_system.PopoverContent,
2379
- {
2380
- align: "start",
2381
- sideOffset: 4,
2382
- collisionPadding: 12,
2383
- sticky: "always",
2384
- ...dialogContainer ? { container: dialogContainer } : {},
2385
- className: "overflow-hidden p-0",
2386
- style: {
2387
- // PopoverContent's 1px border is inside this border-box width.
2388
- // Give the fixed columns those two pixels at their natural desktop width;
2389
- // maxWidth still turns the inner panel into a horizontal scrollport.
2390
- width: popoverWidth + 2,
2391
- maxWidth: "calc(100vw - 24px)",
2392
- height: PANEL_HEIGHT,
2393
- // See LIST_MAX_HEIGHT — this clamp is what keeps the search row on
2394
- // screen at an 800px-tall window.
2395
- maxHeight: LIST_MAX_HEIGHT
2396
- },
2397
- children: desktopBody
2398
- }
2399
- )
2400
- ] });
207
+ function readEffectiveSettings(entry) {
208
+ return entry ? mergeEffectiveSettings(entry.defaults, entry.overrides) : EMPTY;
2401
209
  }
2402
210
 
211
+ // settings/react/ModelSettingsPanel.tsx
212
+ var import_design_system4 = require("@ai-matrx/design-system");
213
+ var import_controls3 = require("@ai-matrx/design-system/controls");
214
+ var import_react2 = require("@ai-matrx/agents/models/react");
215
+
2403
216
  // settings/settings-catalogue.ts
2404
217
  var import_text_case = require("@ai-matrx/kit/text-case");
2405
218
  var CONTROL_TYPES = [
@@ -2610,13 +423,13 @@ function isOffValue(value, control) {
2610
423
  }
2611
424
 
2612
425
  // settings/react/InputCapabilitiesEditor.tsx
2613
- var import_design_system3 = require("@ai-matrx/design-system");
2614
- var import_controls2 = require("@ai-matrx/design-system/controls");
426
+ var import_design_system2 = require("@ai-matrx/design-system");
427
+ var import_controls = require("@ai-matrx/design-system/controls");
2615
428
 
2616
429
  // settings/react/settings-icons.tsx
2617
- var import_jsx_runtime5 = require("react/jsx-runtime");
2618
- function Svg3({ className, children }) {
2619
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
430
+ var import_jsx_runtime = require("react/jsx-runtime");
431
+ function Svg({ className, children }) {
432
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
2620
433
  "svg",
2621
434
  {
2622
435
  xmlns: "http://www.w3.org/2000/svg",
@@ -2632,98 +445,98 @@ function Svg3({ className, children }) {
2632
445
  }
2633
446
  );
2634
447
  }
2635
- var CircleCheckGlyph = ({ className }) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Svg3, { className, children: [
2636
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("circle", { cx: "12", cy: "12", r: "10" }),
2637
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "m16 9-5.5 5.5L8 12" })
448
+ var CircleCheckGlyph = ({ className }) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Svg, { className, children: [
449
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: "12", cy: "12", r: "10" }),
450
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "m16 9-5.5 5.5L8 12" })
2638
451
  ] });
2639
- var TriangleAlertGlyph = ({ className }) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Svg3, { className, children: [
2640
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3" }),
2641
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M12 9v4" }),
2642
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M12 17h.01" })
452
+ var TriangleAlertGlyph = ({ className }) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Svg, { className, children: [
453
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3" }),
454
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M12 9v4" }),
455
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M12 17h.01" })
2643
456
  ] });
2644
- var VariableGlyph = ({ className }) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Svg3, { className, children: [
2645
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M8 21s-4-3-4-9 4-9 4-9" }),
2646
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M16 3s4 3 4 9-4 9-4 9" }),
2647
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("line", { x1: "15", x2: "9", y1: "9", y2: "15" }),
2648
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("line", { x1: "9", x2: "15", y1: "9", y2: "15" })
457
+ var VariableGlyph = ({ className }) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Svg, { className, children: [
458
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M8 21s-4-3-4-9 4-9 4-9" }),
459
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M16 3s4 3 4 9-4 9-4 9" }),
460
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: "15", x2: "9", y1: "9", y2: "15" }),
461
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: "9", x2: "15", y1: "9", y2: "15" })
2649
462
  ] });
2650
- var UnlinkGlyph = ({ className }) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Svg3, { className, children: [
2651
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "m18.84 12.25 1.72-1.71h-.02a5.004 5.004 0 0 0-.12-7.07 5.006 5.006 0 0 0-6.95 0l-1.72 1.71" }),
2652
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "m5.17 11.75-1.71 1.71a5.004 5.004 0 0 0 .12 7.07 5.006 5.006 0 0 0 6.95 0l1.71-1.71" }),
2653
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("line", { x1: "8", x2: "8", y1: "2", y2: "5" }),
2654
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("line", { x1: "2", x2: "5", y1: "8", y2: "8" }),
2655
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("line", { x1: "16", x2: "16", y1: "19", y2: "22" }),
2656
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("line", { x1: "19", x2: "22", y1: "16", y2: "16" })
463
+ var UnlinkGlyph = ({ className }) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Svg, { className, children: [
464
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "m18.84 12.25 1.72-1.71h-.02a5.004 5.004 0 0 0-.12-7.07 5.006 5.006 0 0 0-6.95 0l-1.72 1.71" }),
465
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "m5.17 11.75-1.71 1.71a5.004 5.004 0 0 0 .12 7.07 5.006 5.006 0 0 0 6.95 0l1.71-1.71" }),
466
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: "8", x2: "8", y1: "2", y2: "5" }),
467
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: "2", x2: "5", y1: "8", y2: "8" }),
468
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: "16", x2: "16", y1: "19", y2: "22" }),
469
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: "19", x2: "22", y1: "16", y2: "16" })
2657
470
  ] });
2658
- var WrenchGlyph = ({ className }) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Svg3, { className, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.106-3.105c.32-.322.863-.22.983.218a6 6 0 0 1-8.259 7.057l-7.91 7.91a1 1 0 0 1-2.999-3l7.91-7.91a6 6 0 0 1 7.057-8.259c.438.12.54.662.219.984z" }) });
2659
- var Trash2Glyph = ({ className }) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Svg3, { className, children: [
2660
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M10 11v6" }),
2661
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M14 11v6" }),
2662
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6" }),
2663
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M3 6h18" }),
2664
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" })
471
+ var WrenchGlyph = ({ className }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Svg, { className, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.106-3.105c.32-.322.863-.22.983.218a6 6 0 0 1-8.259 7.057l-7.91 7.91a1 1 0 0 1-2.999-3l7.91-7.91a6 6 0 0 1 7.057-8.259c.438.12.54.662.219.984z" }) });
472
+ var Trash2Glyph = ({ className }) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Svg, { className, children: [
473
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M10 11v6" }),
474
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M14 11v6" }),
475
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6" }),
476
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M3 6h18" }),
477
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" })
2665
478
  ] });
2666
- var RotateCcwGlyph = ({ className }) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Svg3, { className, children: [
2667
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8" }),
2668
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M3 3v5h5" })
479
+ var RotateCcwGlyph = ({ className }) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Svg, { className, children: [
480
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8" }),
481
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M3 3v5h5" })
2669
482
  ] });
2670
- var ImageGlyph = ({ className }) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Svg3, { className, children: [
2671
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("rect", { width: "18", height: "18", x: "3", y: "3", rx: "2", ry: "2" }),
2672
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("circle", { cx: "9", cy: "9", r: "2" }),
2673
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21" })
483
+ var ImageGlyph = ({ className }) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Svg, { className, children: [
484
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("rect", { width: "18", height: "18", x: "3", y: "3", rx: "2", ry: "2" }),
485
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: "9", cy: "9", r: "2" }),
486
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21" })
2674
487
  ] });
2675
- var FileTextGlyph = ({ className }) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Svg3, { className, children: [
2676
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z" }),
2677
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M14 2v4a2 2 0 0 0 2 2h4" }),
2678
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M10 9H8" }),
2679
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M16 13H8" }),
2680
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M16 17H8" })
488
+ var FileTextGlyph = ({ className }) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Svg, { className, children: [
489
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z" }),
490
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M14 2v4a2 2 0 0 0 2 2h4" }),
491
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M10 9H8" }),
492
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M16 13H8" }),
493
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M16 17H8" })
2681
494
  ] });
2682
- var YoutubeGlyph = ({ className }) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Svg3, { className, children: [
2683
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M2.5 17a24.12 24.12 0 0 1 0-10 2 2 0 0 1 1.4-1.4 49.56 49.56 0 0 1 16.2 0A2 2 0 0 1 21.5 7a24.12 24.12 0 0 1 0 10 2 2 0 0 1-1.4 1.4 49.55 49.55 0 0 1-16.2 0A2 2 0 0 1 2.5 17" }),
2684
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "m10 15 5-3-5-3z" })
495
+ var YoutubeGlyph = ({ className }) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Svg, { className, children: [
496
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M2.5 17a24.12 24.12 0 0 1 0-10 2 2 0 0 1 1.4-1.4 49.56 49.56 0 0 1 16.2 0A2 2 0 0 1 21.5 7a24.12 24.12 0 0 1 0 10 2 2 0 0 1-1.4 1.4 49.55 49.55 0 0 1-16.2 0A2 2 0 0 1 2.5 17" }),
497
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "m10 15 5-3-5-3z" })
2685
498
  ] });
2686
499
 
2687
500
  // settings/react/SettingRowFrame.tsx
2688
- var import_design_system2 = require("@ai-matrx/design-system");
2689
- var import_jsx_runtime6 = require("react/jsx-runtime");
2690
- var cn2 = (...parts) => parts.filter(Boolean).join(" ");
501
+ var import_design_system = require("@ai-matrx/design-system");
502
+ var import_jsx_runtime2 = require("react/jsx-runtime");
503
+ var cn = (...parts) => parts.filter(Boolean).join(" ");
2691
504
  function formatSettingValue(value) {
2692
505
  if (typeof value === "boolean") return value ? "On" : "Off";
2693
506
  if (value !== null && typeof value === "object") return JSON.stringify(value);
2694
507
  return String(value);
2695
508
  }
2696
509
  function SettingRowFrame({ rowKey, state, leading, label, children, actions }) {
2697
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
510
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
2698
511
  "div",
2699
512
  {
2700
513
  "data-setting-row": rowKey,
2701
514
  "data-setting-state": state,
2702
515
  className: "grid grid-cols-[1rem_minmax(0,1fr)_auto] items-start gap-x-2 gap-y-1 py-1 @md:grid-cols-[1rem_9rem_minmax(0,1fr)_auto]",
2703
516
  children: [
2704
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "flex h-7 items-center", children: leading }),
2705
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "flex min-h-7 min-w-0 items-center", children: label }),
2706
- children !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "col-span-2 col-start-2 row-start-2 min-w-0 @md:col-span-1 @md:col-start-3 @md:row-start-1", children }) : null,
2707
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "col-start-3 row-start-1 flex min-h-7 items-center justify-end @md:col-start-4", children: actions })
517
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "flex h-7 items-center", children: leading }),
518
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "flex min-h-7 min-w-0 items-center", children: label }),
519
+ children !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "col-span-2 col-start-2 row-start-2 min-w-0 @md:col-span-1 @md:col-start-3 @md:row-start-1", children }) : null,
520
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "col-start-3 row-start-1 flex min-h-7 items-center justify-end @md:col-start-4", children: actions })
2708
521
  ]
2709
522
  }
2710
523
  );
2711
524
  }
2712
525
  function RowLabel({ htmlFor, muted, children }) {
2713
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_design_system2.Label, { htmlFor, className: cn2("min-w-0 truncate type-body", muted ? "text-muted-foreground" : "text-foreground"), children });
526
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_design_system.Label, { htmlFor, className: cn("min-w-0 truncate type-body", muted ? "text-muted-foreground" : "text-foreground"), children });
2714
527
  }
2715
528
  function RowText({ children, mono }) {
2716
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: cn2("flex min-h-7 items-center truncate type-secondary text-muted-foreground", mono && "font-mono"), children });
529
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: cn("flex min-h-7 items-center truncate type-secondary text-muted-foreground", mono && "font-mono"), children });
2717
530
  }
2718
531
  function SettingsGroupSection({ id, title, children }) {
2719
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("section", { "data-settings-group": id, className: title ? "mt-2 border-t border-border pt-2" : void 0, children: [
2720
- title ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("h3", { className: "pb-1 type-title text-foreground", children: title }) : null,
532
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("section", { "data-settings-group": id, className: title ? "mt-2 border-t border-border pt-2" : void 0, children: [
533
+ title ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("h3", { className: "pb-1 type-title text-foreground", children: title }) : null,
2721
534
  children
2722
535
  ] });
2723
536
  }
2724
537
 
2725
538
  // settings/react/InputCapabilitiesEditor.tsx
2726
- var import_jsx_runtime7 = require("react/jsx-runtime");
539
+ var import_jsx_runtime3 = require("react/jsx-runtime");
2727
540
  var GATE_META = {
2728
541
  image_urls: {
2729
542
  label: "Image URLs",
@@ -2752,24 +565,24 @@ function InputCapabilitiesEditor({
2752
565
  title = "Input Capabilities",
2753
566
  disabled = false
2754
567
  }) {
2755
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(SettingsGroupSection, { id: "input-capabilities", title, children: [
568
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(SettingsGroupSection, { id: "input-capabilities", title, children: [
2756
569
  UI_GATE_EDITABLE_KEYS.map((key) => {
2757
570
  const { label, description, Icon } = GATE_META[key];
2758
571
  const switchId = `${idPrefix}-${key}`;
2759
572
  const changed = changedKeys?.has(key) === true;
2760
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
573
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2761
574
  SettingRowFrame,
2762
575
  {
2763
576
  rowKey: key,
2764
577
  state: values[key] === true ? "on" : "off",
2765
- leading: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Icon, { className: "h-4 w-4 text-muted-foreground" }),
2766
- label: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(RowLabel, { htmlFor: switchId, children: label }),
2767
- actions: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
2768
- changed && onReset ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2769
- import_controls2.Button,
578
+ leading: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Icon, { className: "h-4 w-4 text-muted-foreground" }),
579
+ label: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(RowLabel, { htmlFor: switchId, children: label }),
580
+ actions: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
581
+ changed && onReset ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
582
+ import_controls.Button,
2770
583
  {
2771
584
  variant: "quiet",
2772
- icon: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(RotateCcwGlyph, {}),
585
+ icon: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(RotateCcwGlyph, {}),
2773
586
  onClick: () => onReset(key),
2774
587
  disabled,
2775
588
  "aria-label": `${resetLabel}: ${label}`,
@@ -2777,8 +590,8 @@ function InputCapabilitiesEditor({
2777
590
  "data-setting-reset": key
2778
591
  }
2779
592
  ) : null,
2780
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2781
- import_controls2.Switch,
593
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
594
+ import_controls.Switch,
2782
595
  {
2783
596
  id: switchId,
2784
597
  checked: values[key] === true,
@@ -2787,31 +600,31 @@ function InputCapabilitiesEditor({
2787
600
  }
2788
601
  )
2789
602
  ] }),
2790
- children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(RowText, { children: description })
603
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(RowText, { children: description })
2791
604
  },
2792
605
  key
2793
606
  );
2794
607
  }),
2795
- error ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_design_system3.ErrorBox, { as: "p", className: "py-1 type-meta text-destructive", message: error }) : null
608
+ error ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_design_system2.ErrorBox, { as: "p", className: "py-1 type-meta text-destructive", message: error }) : null
2796
609
  ] });
2797
610
  }
2798
611
 
2799
612
  // settings/react/SettingControlInput.tsx
2800
- var import_react3 = require("react");
2801
- var import_design_system4 = require("@ai-matrx/design-system");
2802
- var import_controls3 = require("@ai-matrx/design-system/controls");
2803
- var import_jsx_runtime8 = require("react/jsx-runtime");
613
+ var import_react = require("react");
614
+ var import_design_system3 = require("@ai-matrx/design-system");
615
+ var import_controls2 = require("@ai-matrx/design-system/controls");
616
+ var import_jsx_runtime4 = require("react/jsx-runtime");
2804
617
  var SELECT_MAX_OPTIONS = 12;
2805
618
  function choiceFor(options) {
2806
- if ((0, import_controls3.isAspectRatioOptionSet)(options)) return "aspect-ratio";
619
+ if ((0, import_controls2.isAspectRatioOptionSet)(options)) return "aspect-ratio";
2807
620
  if (options.length > SELECT_MAX_OPTIONS) return "searchable";
2808
621
  return "select";
2809
622
  }
2810
623
  function WarningIcon({ className }) {
2811
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", className, children: [
2812
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("path", { d: "m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3" }),
2813
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("path", { d: "M12 9v4" }),
2814
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("path", { d: "M12 17h.01" })
624
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", className, children: [
625
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { d: "m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3" }),
626
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { d: "M12 9v4" }),
627
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { d: "M12 17h.01" })
2815
628
  ] });
2816
629
  }
2817
630
  function flattenTypeObject(value) {
@@ -2835,8 +648,8 @@ function SettingControlInput({
2835
648
  const isValueMismatch = stringValue !== "" && !control.enum.includes(stringValue);
2836
649
  const emit = (v) => onChange(settingKey === "response_format" ? { type: v } : v);
2837
650
  const choice = choiceFor(control.enum);
2838
- const picker = choice === "aspect-ratio" ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2839
- import_controls3.AspectRatioSelect,
651
+ const picker = choice === "aspect-ratio" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
652
+ import_controls2.AspectRatioSelect,
2840
653
  {
2841
654
  value: isValueMismatch ? "" : stringValue,
2842
655
  onChange: emit,
@@ -2846,8 +659,8 @@ function SettingControlInput({
2846
659
  id: inputId,
2847
660
  placeholder: "Default"
2848
661
  }
2849
- ) : choice === "searchable" ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2850
- import_controls3.OptionCombobox,
662
+ ) : choice === "searchable" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
663
+ import_controls2.OptionCombobox,
2851
664
  {
2852
665
  value: isValueMismatch ? "" : stringValue,
2853
666
  onChange: emit,
@@ -2858,24 +671,24 @@ function SettingControlInput({
2858
671
  placeholder: "Default"
2859
672
  }
2860
673
  ) : null;
2861
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "flex flex-1 items-center gap-1.5", children: [
2862
- picker ?? /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
2863
- import_design_system4.Select,
674
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "flex flex-1 items-center gap-1.5", children: [
675
+ picker ?? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
676
+ import_design_system3.Select,
2864
677
  {
2865
678
  value: isValueMismatch ? "" : stringValue,
2866
679
  onValueChange: emit,
2867
680
  disabled,
2868
681
  children: [
2869
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2870
- import_design_system4.SelectTrigger,
682
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
683
+ import_design_system3.SelectTrigger,
2871
684
  {
2872
685
  id: inputId,
2873
686
  className: "h-7 flex-1 border-0 bg-transparent px-1 text-xs font-medium text-foreground shadow-none hover:bg-transparent focus:ring-0 pointer-coarse:h-11 [&_svg]:h-3 [&_svg]:w-3",
2874
- children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_design_system4.SelectValue, { placeholder: isValueMismatch ? stringValue : "Default" })
687
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_design_system3.SelectValue, { placeholder: isValueMismatch ? stringValue : "Default" })
2875
688
  }
2876
689
  ),
2877
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_design_system4.SelectContent, { className: "text-xs", children: control.enum.map((option) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2878
- import_design_system4.SelectItem,
690
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_design_system3.SelectContent, { className: "text-xs", children: control.enum.map((option) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
691
+ import_design_system3.SelectItem,
2879
692
  {
2880
693
  value: option,
2881
694
  className: "py-1 text-xs",
@@ -2886,9 +699,9 @@ function SettingControlInput({
2886
699
  ]
2887
700
  }
2888
701
  ),
2889
- isValueMismatch && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_design_system4.TooltipProvider, { delayDuration: 200, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_design_system4.Tooltip, { children: [
2890
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_design_system4.TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "shrink-0 cursor-help text-amber-500", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(WarningIcon, { className: "h-3.5 w-3.5" }) }) }),
2891
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_design_system4.TooltipContent, { side: "top", className: "max-w-[220px] type-secondary", children: [
702
+ isValueMismatch && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_design_system3.TooltipProvider, { delayDuration: 200, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_design_system3.Tooltip, { children: [
703
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_design_system3.TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "shrink-0 cursor-help text-amber-500", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(WarningIcon, { className: "h-3.5 w-3.5" }) }) }),
704
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_design_system3.TooltipContent, { side: "top", className: "max-w-[220px] type-secondary", children: [
2892
705
  '"',
2893
706
  stringValue,
2894
707
  '" is not a recognized option for this model'
@@ -2897,9 +710,9 @@ function SettingControlInput({
2897
710
  ] });
2898
711
  }
2899
712
  if (control.type === "boolean") {
2900
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "flex items-center gap-2", children: [
2901
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2902
- import_design_system4.Checkbox,
713
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "flex items-center gap-2", children: [
714
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
715
+ import_design_system3.Checkbox,
2903
716
  {
2904
717
  id: inputId,
2905
718
  checked: value === true,
@@ -2908,8 +721,8 @@ function SettingControlInput({
2908
721
  className: "cursor-pointer"
2909
722
  }
2910
723
  ),
2911
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2912
- import_design_system4.Label,
724
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
725
+ import_design_system3.Label,
2913
726
  {
2914
727
  htmlFor: inputId,
2915
728
  className: "cursor-pointer text-xs text-muted-foreground",
@@ -2921,7 +734,7 @@ function SettingControlInput({
2921
734
  if (control.type === "number" || control.type === "integer") {
2922
735
  const numeric = typeof value === "number" ? value : void 0;
2923
736
  const hasRange = control.min !== void 0 && control.max !== void 0;
2924
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
737
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
2925
738
  NumberInput,
2926
739
  {
2927
740
  value: numeric,
@@ -2939,8 +752,8 @@ function SettingControlInput({
2939
752
  }
2940
753
  if (control.type === "string_array") {
2941
754
  const arrayValue = Array.isArray(value) ? value.join("\n") : "";
2942
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2943
- import_design_system4.Textarea,
755
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
756
+ import_design_system3.Textarea,
2944
757
  {
2945
758
  id: inputId,
2946
759
  value: arrayValue,
@@ -2952,7 +765,7 @@ function SettingControlInput({
2952
765
  );
2953
766
  }
2954
767
  if (control.type === "array" || control.type === "object_array" || typeof value === "object" && value !== null) {
2955
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
768
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
2956
769
  JsonValueInput,
2957
770
  {
2958
771
  id: inputId,
@@ -2962,8 +775,8 @@ function SettingControlInput({
2962
775
  }
2963
776
  );
2964
777
  }
2965
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2966
- import_design_system4.Input,
778
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
779
+ import_design_system3.Input,
2967
780
  {
2968
781
  id: inputId,
2969
782
  type: "text",
@@ -2981,15 +794,15 @@ function JsonValueInput({
2981
794
  disabled
2982
795
  }) {
2983
796
  const toText = (v) => v === void 0 || v === null ? "" : JSON.stringify(v, null, 2);
2984
- const [draft, setDraft] = (0, import_react3.useState)(() => toText(value));
2985
- const [jsonError, setJsonError] = (0, import_react3.useState)(null);
2986
- (0, import_react3.useEffect)(() => {
797
+ const [draft, setDraft] = (0, import_react.useState)(() => toText(value));
798
+ const [jsonError, setJsonError] = (0, import_react.useState)(null);
799
+ (0, import_react.useEffect)(() => {
2987
800
  setDraft(toText(value));
2988
801
  setJsonError(null);
2989
802
  }, [JSON.stringify(value)]);
2990
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "flex flex-col gap-1", children: [
2991
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2992
- import_design_system4.Textarea,
803
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "flex flex-col gap-1", children: [
804
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
805
+ import_design_system3.Textarea,
2993
806
  {
2994
807
  id,
2995
808
  value: draft,
@@ -3015,7 +828,7 @@ function JsonValueInput({
3015
828
  spellCheck: false
3016
829
  }
3017
830
  ),
3018
- jsonError && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { className: "type-meta text-amber-600 dark:text-amber-400", children: jsonError })
831
+ jsonError && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "type-meta text-amber-600 dark:text-amber-400", children: jsonError })
3019
832
  ] });
3020
833
  }
3021
834
  function NumberInput({
@@ -3031,7 +844,7 @@ function NumberInput({
3031
844
  withSlider = false
3032
845
  }) {
3033
846
  const boxClass = "h-7 px-2 text-xs tabular-nums pointer-coarse:h-11";
3034
- const [draftState, setDraftState] = (0, import_react3.useState)(() => ({
847
+ const [draftState, setDraftState] = (0, import_react.useState)(() => ({
3035
848
  sourceValue: value,
3036
849
  text: value === void 0 ? "" : String(value)
3037
850
  }));
@@ -3049,13 +862,13 @@ function NumberInput({
3049
862
  } else setDraft(shown);
3050
863
  };
3051
864
  if (withSlider) {
3052
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
865
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
3053
866
  "div",
3054
867
  {
3055
868
  className: "grid grid-cols-[1fr_4.5rem] items-center gap-2",
3056
869
  children: [
3057
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
3058
- import_design_system4.Slider,
870
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
871
+ import_design_system3.Slider,
3059
872
  {
3060
873
  ...min !== void 0 ? { min } : {},
3061
874
  ...max !== void 0 ? { max } : {},
@@ -3072,8 +885,8 @@ function NumberInput({
3072
885
  disabled
3073
886
  }
3074
887
  ),
3075
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
3076
- import_design_system4.Input,
888
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
889
+ import_design_system3.Input,
3077
890
  {
3078
891
  type: "text",
3079
892
  inputMode: "decimal",
@@ -3093,8 +906,8 @@ function NumberInput({
3093
906
  }
3094
907
  );
3095
908
  }
3096
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
3097
- import_design_system4.Input,
909
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
910
+ import_design_system3.Input,
3098
911
  {
3099
912
  type: "text",
3100
913
  inputMode: "decimal",
@@ -3113,28 +926,28 @@ function NumberInput({
3113
926
  }
3114
927
 
3115
928
  // settings/react/ModelSettingsPanel.tsx
3116
- var import_jsx_runtime9 = require("react/jsx-runtime");
929
+ var import_jsx_runtime5 = require("react/jsx-runtime");
3117
930
  function StatusGlyph({ issue, source }) {
3118
931
  const title = issue ? issue.message : source ? `Valid \xB7 ${source}` : "Valid";
3119
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
932
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
3120
933
  "span",
3121
934
  {
3122
- className: cn2("inline-flex h-7 w-6 shrink-0 items-center justify-center", issue ? "text-warning" : "text-success"),
935
+ className: cn("inline-flex h-7 w-6 shrink-0 items-center justify-center", issue ? "text-warning" : "text-success"),
3123
936
  role: "img",
3124
937
  "aria-label": title,
3125
938
  title,
3126
- children: issue ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(TriangleAlertGlyph, { className: "h-3.5 w-3.5" }) : /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(CircleCheckGlyph, { className: "h-3.5 w-3.5" })
939
+ children: issue ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(TriangleAlertGlyph, { className: "h-3.5 w-3.5" }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(CircleCheckGlyph, { className: "h-3.5 w-3.5" })
3127
940
  }
3128
941
  );
3129
942
  }
3130
943
  function ModelSettingRow({ row, control, target, idPrefix, disabled }) {
3131
944
  const read = target.read(row.key, control);
3132
945
  const resetLabel = target.resetLabel ?? "Reset to agent";
3133
- const reset = read.changedHere && target.resetToInherited ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
3134
- import_controls4.Button,
946
+ const reset = read.changedHere && target.resetToInherited ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
947
+ import_controls3.Button,
3135
948
  {
3136
949
  variant: "quiet",
3137
- icon: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(RotateCcwGlyph, {}),
950
+ icon: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(RotateCcwGlyph, {}),
3138
951
  onClick: () => target.resetToInherited?.(row.key),
3139
952
  disabled,
3140
953
  "aria-label": `${resetLabel}: ${row.label}`,
@@ -3143,20 +956,20 @@ function ModelSettingRow({ row, control, target, idPrefix, disabled }) {
3143
956
  }
3144
957
  ) : null;
3145
958
  if (read.state === "bound") {
3146
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
959
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
3147
960
  SettingRowFrame,
3148
961
  {
3149
962
  rowKey: row.key,
3150
963
  state: "bound",
3151
- leading: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_design_system5.Checkbox, { checked: true, disabled: true, "aria-label": `${row.label} is a run input` }),
3152
- label: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(RowLabel, { children: row.label }),
3153
- actions: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
964
+ leading: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_design_system4.Checkbox, { checked: true, disabled: true, "aria-label": `${row.label} is a run input` }),
965
+ label: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(RowLabel, { children: row.label }),
966
+ actions: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
3154
967
  reset,
3155
- target.unbind ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
3156
- import_controls4.Button,
968
+ target.unbind ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
969
+ import_controls3.Button,
3157
970
  {
3158
971
  variant: "quiet",
3159
- icon: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(UnlinkGlyph, {}),
972
+ icon: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(UnlinkGlyph, {}),
3160
973
  onClick: () => target.unbind?.(row.key, control),
3161
974
  disabled,
3162
975
  "aria-label": `Make ${row.label} a fixed setting`,
@@ -3164,9 +977,9 @@ function ModelSettingRow({ row, control, target, idPrefix, disabled }) {
3164
977
  }
3165
978
  ) : null
3166
979
  ] }),
3167
- children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { className: "flex min-h-7 min-w-0 items-center gap-2", "data-bound-control": row.key, children: [
3168
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_controls4.Chip, { tone: "primary", icon: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(VariableGlyph, {}), label: `{{${read.variableName}}}` }),
3169
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "truncate type-meta text-muted-foreground", children: read.value === void 0 || read.value === null || read.value === "" ? "Model default" : formatSettingValue(read.value) })
980
+ children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { className: "flex min-h-7 min-w-0 items-center gap-2", "data-bound-control": row.key, children: [
981
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_controls3.Chip, { tone: "primary", icon: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(VariableGlyph, {}), label: `{{${read.variableName}}}` }),
982
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "truncate type-meta text-muted-foreground", children: read.value === void 0 || read.value === null || read.value === "" ? "Model default" : formatSettingValue(read.value) })
3170
983
  ] })
3171
984
  }
3172
985
  );
@@ -3176,13 +989,13 @@ function ModelSettingRow({ row, control, target, idPrefix, disabled }) {
3176
989
  const isOff = isSet && isOffValue(value, control);
3177
990
  const checkboxId = `${idPrefix}-setting-${row.key}`;
3178
991
  const canBind = Boolean(target.bind) && (target.canBind?.(row.key) ?? true);
3179
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
992
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
3180
993
  SettingRowFrame,
3181
994
  {
3182
995
  rowKey: row.key,
3183
996
  state: isOff ? "off" : read.state,
3184
- leading: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
3185
- import_design_system5.Checkbox,
997
+ leading: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
998
+ import_design_system4.Checkbox,
3186
999
  {
3187
1000
  id: checkboxId,
3188
1001
  checked: isSet,
@@ -3190,14 +1003,14 @@ function ModelSettingRow({ row, control, target, idPrefix, disabled }) {
3190
1003
  onCheckedChange: (next) => next === true ? target.turnOn(row.key, control) : target.clear(row.key)
3191
1004
  }
3192
1005
  ),
3193
- label: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(RowLabel, { htmlFor: checkboxId, muted: !isSet, children: row.label }),
3194
- actions: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
3195
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(StatusGlyph, { issue: read.issue, source: read.source }),
3196
- canBind ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
3197
- import_controls4.Button,
1006
+ label: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(RowLabel, { htmlFor: checkboxId, muted: !isSet, children: row.label }),
1007
+ actions: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
1008
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(StatusGlyph, { issue: read.issue, source: read.source }),
1009
+ canBind ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1010
+ import_controls3.Button,
3198
1011
  {
3199
1012
  variant: "quiet",
3200
- icon: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(VariableGlyph, {}),
1013
+ icon: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(VariableGlyph, {}),
3201
1014
  onClick: () => target.bind?.(row.key, control),
3202
1015
  disabled,
3203
1016
  "aria-label": `Make ${row.label} a run input`,
@@ -3205,11 +1018,11 @@ function ModelSettingRow({ row, control, target, idPrefix, disabled }) {
3205
1018
  "data-bind-control": row.key
3206
1019
  }
3207
1020
  ) : null,
3208
- isSet && read.issue?.fixable && target.fix ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
3209
- import_controls4.Button,
1021
+ isSet && read.issue?.fixable && target.fix ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1022
+ import_controls3.Button,
3210
1023
  {
3211
1024
  variant: "quiet",
3212
- icon: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(WrenchGlyph, {}),
1025
+ icon: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(WrenchGlyph, {}),
3213
1026
  onClick: () => target.fix?.(row.key),
3214
1027
  disabled,
3215
1028
  "aria-label": `Fix ${row.label} automatically`,
@@ -3217,12 +1030,12 @@ function ModelSettingRow({ row, control, target, idPrefix, disabled }) {
3217
1030
  }
3218
1031
  ) : null,
3219
1032
  reset,
3220
- isSet ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
3221
- import_controls4.Button,
1033
+ isSet ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1034
+ import_controls3.Button,
3222
1035
  {
3223
1036
  variant: "quiet",
3224
1037
  removes: true,
3225
- icon: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Trash2Glyph, {}),
1038
+ icon: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Trash2Glyph, {}),
3226
1039
  onClick: () => target.clear(row.key),
3227
1040
  disabled,
3228
1041
  "aria-label": `Clear ${row.label} to not set`,
@@ -3231,8 +1044,8 @@ function ModelSettingRow({ row, control, target, idPrefix, disabled }) {
3231
1044
  }
3232
1045
  ) : null
3233
1046
  ] }),
3234
- children: isSet ? /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
3235
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1047
+ children: isSet ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
1048
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
3236
1049
  SettingControlInput,
3237
1050
  {
3238
1051
  settingKey: row.key,
@@ -3243,40 +1056,40 @@ function ModelSettingRow({ row, control, target, idPrefix, disabled }) {
3243
1056
  id: `${idPrefix}-control-${row.key}`
3244
1057
  }
3245
1058
  ),
3246
- read.issue ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("p", { className: "pt-1 type-meta text-warning-ink", children: read.issue.message }) : null
3247
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(RowText, { children: read.modelDefault !== void 0 && read.modelDefault !== null ? `Not set \xB7 Model default: ${formatSettingValue(read.modelDefault)}` : "Not set" })
1059
+ read.issue ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "pt-1 type-meta text-warning-ink", children: read.issue.message }) : null
1060
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(RowText, { children: read.modelDefault !== void 0 && read.modelDefault !== null ? `Not set \xB7 Model default: ${formatSettingValue(read.modelDefault)}` : "Not set" })
3248
1061
  }
3249
1062
  );
3250
1063
  }
3251
1064
  function ExtraSettingRow({ rowKey, label, value, kind, onClear, onReset, resetLabel = "Reset to agent", disabled = false }) {
3252
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1065
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
3253
1066
  SettingRowFrame,
3254
1067
  {
3255
1068
  rowKey,
3256
1069
  state: kind,
3257
- label: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(RowLabel, { children: label }),
3258
- actions: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
3259
- kind === "translated" ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_controls4.Chip, { tone: "sky", label: "Translated", title: "Kept as set and sent as this model's closest equivalent" }) : /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_controls4.Chip, { tone: "warning", label: "Not on this model", title: "This model has no such setting" }),
3260
- onReset ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_controls4.Button, { variant: "quiet", icon: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(RotateCcwGlyph, {}), onClick: onReset, disabled, "aria-label": `${resetLabel}: ${label}`, title: resetLabel, "data-setting-reset": rowKey }) : /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_controls4.Button, { variant: "quiet", removes: true, icon: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Trash2Glyph, {}), onClick: onClear, disabled, "aria-label": `Clear ${label}`, title: "Clear to not set", "data-setting-clear": rowKey })
1070
+ label: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(RowLabel, { children: label }),
1071
+ actions: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
1072
+ kind === "translated" ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_controls3.Chip, { tone: "sky", label: "Translated", title: "Kept as set and sent as this model's closest equivalent" }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_controls3.Chip, { tone: "warning", label: "Not on this model", title: "This model has no such setting" }),
1073
+ onReset ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_controls3.Button, { variant: "quiet", icon: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(RotateCcwGlyph, {}), onClick: onReset, disabled, "aria-label": `${resetLabel}: ${label}`, title: resetLabel, "data-setting-reset": rowKey }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_controls3.Button, { variant: "quiet", removes: true, icon: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Trash2Glyph, {}), onClick: onClear, disabled, "aria-label": `Clear ${label}`, title: "Clear to not set", "data-setting-clear": rowKey })
3261
1074
  ] }),
3262
- children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(RowText, { mono: value !== void 0 && value !== null, children: value === void 0 || value === null ? "Not set" : isOffValue(value, null) ? "Off" : formatSettingValue(value) })
1075
+ children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(RowText, { mono: value !== void 0 && value !== null, children: value === void 0 || value === null ? "Not set" : isOffValue(value, null) ? "Off" : formatSettingValue(value) })
3263
1076
  }
3264
1077
  );
3265
1078
  }
3266
- function ModelRow2({ model, resetLabel, idPrefix, disabled }) {
1079
+ function ModelRow({ model, resetLabel, idPrefix, disabled }) {
3267
1080
  const off = disabled || model.disabled === true;
3268
1081
  const oneMessageId = `${idPrefix}-model-one-message`;
3269
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1082
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
3270
1083
  SettingRowFrame,
3271
1084
  {
3272
1085
  rowKey: "model",
3273
1086
  state: model.value ? "set" : "unset",
3274
- label: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(RowLabel, { children: "Model" }),
3275
- actions: model.changedHere && model.resetToInherited ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
3276
- import_controls4.Button,
1087
+ label: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(RowLabel, { children: "Model" }),
1088
+ actions: model.changedHere && model.resetToInherited ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1089
+ import_controls3.Button,
3277
1090
  {
3278
1091
  variant: "quiet",
3279
- icon: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(RotateCcwGlyph, {}),
1092
+ icon: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(RotateCcwGlyph, {}),
3280
1093
  onClick: () => model.resetToInherited?.(),
3281
1094
  disabled: off,
3282
1095
  "aria-label": `${resetLabel}: Model`,
@@ -3284,9 +1097,9 @@ function ModelRow2({ model, resetLabel, idPrefix, disabled }) {
3284
1097
  "data-setting-reset": "model"
3285
1098
  }
3286
1099
  ) : null,
3287
- children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex min-h-7 min-w-0 flex-wrap items-center gap-x-2", children: [
3288
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
3289
- ModelListDropdown,
1100
+ children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "flex min-h-7 min-w-0 flex-wrap items-center gap-x-2", children: [
1101
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1102
+ import_react2.ModelListDropdown,
3290
1103
  {
3291
1104
  "aria-label": "Model",
3292
1105
  value: model.value,
@@ -3301,9 +1114,9 @@ function ModelRow2({ model, resetLabel, idPrefix, disabled }) {
3301
1114
  ...model.disabledTitle ? { disabledTitle: model.disabledTitle } : {}
3302
1115
  }
3303
1116
  ),
3304
- model.oneMessage ? /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("label", { htmlFor: oneMessageId, className: "flex min-h-7 items-center gap-1 type-secondary text-muted-foreground", title: "Use this model for the next message, then go back", children: [
3305
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
3306
- import_controls4.Switch,
1117
+ model.oneMessage ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("label", { htmlFor: oneMessageId, className: "flex min-h-7 items-center gap-1 type-secondary text-muted-foreground", title: "Use this model for the next message, then go back", children: [
1118
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1119
+ import_controls3.Switch,
3307
1120
  {
3308
1121
  id: oneMessageId,
3309
1122
  checked: model.oneMessage.on,
@@ -3332,7 +1145,7 @@ function ModelSettingsPanel({
3332
1145
  const groups = controls ? buildSettingsRows(controls, values).filter((group) => group.rows.length > 0) : [];
3333
1146
  const extras = extraSettingKeys(controls, values, target.changedKeys);
3334
1147
  const resetLabel = target.resetLabel ?? "Reset to agent";
3335
- const extraRow = (key, kind) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1148
+ const extraRow = (key, kind) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
3336
1149
  ExtraSettingRow,
3337
1150
  {
3338
1151
  rowKey: key,
@@ -3346,17 +1159,17 @@ function ModelSettingsPanel({
3346
1159
  },
3347
1160
  key
3348
1161
  );
3349
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { "data-model-settings-panel": "", className: "@container flex min-w-0 flex-col", children: [
3350
- model ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ModelRow2, { model, resetLabel, idPrefix, disabled }) : null,
1162
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { "data-model-settings-panel": "", className: "@container flex min-w-0 flex-col", children: [
1163
+ model ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ModelRow, { model, resetLabel, idPrefix, disabled }) : null,
3351
1164
  notices,
3352
1165
  extras.unsupported.map((key) => extraRow(key, "unsupported")),
3353
- extras.translated.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(SettingsGroupSection, { id: "translated", title: "Translated for this model", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { "data-translated-settings": "", children: extras.translated.map((key) => extraRow(key, "translated")) }) }) : null,
3354
- groups.length === 0 && emptyNote ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "py-2 type-secondary text-muted-foreground", children: emptyNote }) : null,
3355
- groups.map((group) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(SettingsGroupSection, { id: group.id, title: group.label || void 0, children: group.rows.map((row) => {
1166
+ extras.translated.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(SettingsGroupSection, { id: "translated", title: "Translated for this model", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { "data-translated-settings": "", children: extras.translated.map((key) => extraRow(key, "translated")) }) }) : null,
1167
+ groups.length === 0 && emptyNote ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "py-2 type-secondary text-muted-foreground", children: emptyNote }) : null,
1168
+ groups.map((group) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(SettingsGroupSection, { id: group.id, title: group.label || void 0, children: group.rows.map((row) => {
3356
1169
  const custom = renderRow?.(row);
3357
- if (custom !== void 0) return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { children: custom }, row.key);
1170
+ if (custom !== void 0) return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { children: custom }, row.key);
3358
1171
  if (!row.control) return null;
3359
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1172
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
3360
1173
  ModelSettingRow,
3361
1174
  {
3362
1175
  row,
@@ -3368,7 +1181,7 @@ function ModelSettingsPanel({
3368
1181
  row.key
3369
1182
  );
3370
1183
  }) }, group.id)),
3371
- capabilities ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1184
+ capabilities ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
3372
1185
  InputCapabilitiesEditor,
3373
1186
  {
3374
1187
  values: capabilities.values,
@@ -3386,7 +1199,7 @@ function ModelSettingsPanel({
3386
1199
 
3387
1200
  // settings/react/index.ts
3388
1201
  function useSettingsSelector(store, select) {
3389
- return (0, import_react5.useSyncExternalStore)(
1202
+ return (0, import_react3.useSyncExternalStore)(
3390
1203
  store.subscribe,
3391
1204
  () => select(store.getState()),
3392
1205
  () => select(store.getState())