@flanksource/clicky-ui 0.3.16 → 0.3.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (158) hide show
  1. package/dist/data/DataTable.cjs +30 -10
  2. package/dist/data/DataTable.cjs.map +1 -1
  3. package/dist/data/DataTable.d.ts +2 -0
  4. package/dist/data/DataTable.d.ts.map +1 -1
  5. package/dist/data/DataTable.js +30 -10
  6. package/dist/data/DataTable.js.map +1 -1
  7. package/dist/data/ServerTimingBadge.cjs +64 -0
  8. package/dist/data/ServerTimingBadge.cjs.map +1 -0
  9. package/dist/data/ServerTimingBadge.d.ts +9 -0
  10. package/dist/data/ServerTimingBadge.d.ts.map +1 -0
  11. package/dist/data/ServerTimingBadge.js +64 -0
  12. package/dist/data/ServerTimingBadge.js.map +1 -0
  13. package/dist/data/ai/ChatWindow.cjs +9 -1
  14. package/dist/data/ai/ChatWindow.cjs.map +1 -1
  15. package/dist/data/ai/ChatWindow.d.ts.map +1 -1
  16. package/dist/data/ai/ChatWindow.js +9 -1
  17. package/dist/data/ai/ChatWindow.js.map +1 -1
  18. package/dist/data/ai/ChatWindow.thread-status.cjs +14 -0
  19. package/dist/data/ai/ChatWindow.thread-status.cjs.map +1 -0
  20. package/dist/data/ai/ChatWindow.thread-status.d.ts +5 -0
  21. package/dist/data/ai/ChatWindow.thread-status.d.ts.map +1 -0
  22. package/dist/data/ai/ChatWindow.thread-status.js +14 -0
  23. package/dist/data/ai/ChatWindow.thread-status.js.map +1 -0
  24. package/dist/data/ai/ChatWindow.thread.cjs +68 -0
  25. package/dist/data/ai/ChatWindow.thread.cjs.map +1 -0
  26. package/dist/data/ai/ChatWindow.thread.d.ts +16 -0
  27. package/dist/data/ai/ChatWindow.thread.d.ts.map +1 -0
  28. package/dist/data/ai/ChatWindow.thread.js +68 -0
  29. package/dist/data/ai/ChatWindow.thread.js.map +1 -0
  30. package/dist/data/ai/PromptRunEditor/index.cjs +100 -88
  31. package/dist/data/ai/PromptRunEditor/index.cjs.map +1 -1
  32. package/dist/data/ai/PromptRunEditor/index.d.ts +5 -9
  33. package/dist/data/ai/PromptRunEditor/index.d.ts.map +1 -1
  34. package/dist/data/ai/PromptRunEditor/index.js +103 -91
  35. package/dist/data/ai/PromptRunEditor/index.js.map +1 -1
  36. package/dist/data/ai/PromptRunEditor/model.cjs +47 -0
  37. package/dist/data/ai/PromptRunEditor/model.cjs.map +1 -0
  38. package/dist/data/ai/PromptRunEditor/model.d.ts +17 -0
  39. package/dist/data/ai/PromptRunEditor/model.d.ts.map +1 -0
  40. package/dist/data/ai/PromptRunEditor/model.js +47 -0
  41. package/dist/data/ai/PromptRunEditor/model.js.map +1 -0
  42. package/dist/data/ai/RuntimeBar.cjs +104 -32
  43. package/dist/data/ai/RuntimeBar.cjs.map +1 -1
  44. package/dist/data/ai/RuntimeBar.d.ts +4 -11
  45. package/dist/data/ai/RuntimeBar.d.ts.map +1 -1
  46. package/dist/data/ai/RuntimeBar.js +107 -35
  47. package/dist/data/ai/RuntimeBar.js.map +1 -1
  48. package/dist/data/ai/RuntimeBar.model.cjs +14 -0
  49. package/dist/data/ai/RuntimeBar.model.cjs.map +1 -0
  50. package/dist/data/ai/RuntimeBar.model.d.ts +10 -0
  51. package/dist/data/ai/RuntimeBar.model.d.ts.map +1 -0
  52. package/dist/data/ai/RuntimeBar.model.js +14 -0
  53. package/dist/data/ai/RuntimeBar.model.js.map +1 -0
  54. package/dist/data/ai/RuntimeBarCombo.cjs +359 -0
  55. package/dist/data/ai/RuntimeBarCombo.cjs.map +1 -0
  56. package/dist/data/ai/RuntimeBarCombo.d.ts +22 -0
  57. package/dist/data/ai/RuntimeBarCombo.d.ts.map +1 -0
  58. package/dist/data/ai/RuntimeBarCombo.js +359 -0
  59. package/dist/data/ai/RuntimeBarCombo.js.map +1 -0
  60. package/dist/data/ai/SessionViewer.header.cjs +17 -9
  61. package/dist/data/ai/SessionViewer.header.cjs.map +1 -1
  62. package/dist/data/ai/SessionViewer.header.d.ts.map +1 -1
  63. package/dist/data/ai/SessionViewer.header.js +17 -9
  64. package/dist/data/ai/SessionViewer.header.js.map +1 -1
  65. package/dist/data/ai/SessionViewer.model.cjs +2 -0
  66. package/dist/data/ai/SessionViewer.model.cjs.map +1 -1
  67. package/dist/data/ai/SessionViewer.model.d.ts +4 -0
  68. package/dist/data/ai/SessionViewer.model.d.ts.map +1 -1
  69. package/dist/data/ai/SessionViewer.model.js +2 -0
  70. package/dist/data/ai/SessionViewer.model.js.map +1 -1
  71. package/dist/data/ai/SessionViewer.unified.d.ts +1 -0
  72. package/dist/data/ai/SessionViewer.unified.d.ts.map +1 -1
  73. package/dist/data/ai/SpecRuntimeEditor/fields.js +1 -1
  74. package/dist/data/ai/ThreadPicker.cjs.map +1 -1
  75. package/dist/data/ai/ThreadPicker.d.ts +2 -0
  76. package/dist/data/ai/ThreadPicker.d.ts.map +1 -1
  77. package/dist/data/ai/ThreadPicker.js.map +1 -1
  78. package/dist/data/ai/index.d.ts +1 -0
  79. package/dist/data/ai/index.d.ts.map +1 -1
  80. package/dist/data/ai/model-capabilities.cjs +12 -1
  81. package/dist/data/ai/model-capabilities.cjs.map +1 -1
  82. package/dist/data/ai/model-capabilities.d.ts +2 -6
  83. package/dist/data/ai/model-capabilities.d.ts.map +1 -1
  84. package/dist/data/ai/model-capabilities.js +12 -1
  85. package/dist/data/ai/model-capabilities.js.map +1 -1
  86. package/dist/data/ai/runtime-mode.cjs +10 -1
  87. package/dist/data/ai/runtime-mode.cjs.map +1 -1
  88. package/dist/data/ai/runtime-mode.d.ts +1 -0
  89. package/dist/data/ai/runtime-mode.d.ts.map +1 -1
  90. package/dist/data/ai/runtime-mode.js +11 -2
  91. package/dist/data/ai/runtime-mode.js.map +1 -1
  92. package/dist/data/chat/Chat.cjs +90 -21
  93. package/dist/data/chat/Chat.cjs.map +1 -1
  94. package/dist/data/chat/Chat.d.ts +4 -1
  95. package/dist/data/chat/Chat.d.ts.map +1 -1
  96. package/dist/data/chat/Chat.js +90 -21
  97. package/dist/data/chat/Chat.js.map +1 -1
  98. package/dist/data/chat/ContextMeter.cjs +144 -73
  99. package/dist/data/chat/ContextMeter.cjs.map +1 -1
  100. package/dist/data/chat/ContextMeter.d.ts +8 -3
  101. package/dist/data/chat/ContextMeter.d.ts.map +1 -1
  102. package/dist/data/chat/ContextMeter.js +144 -73
  103. package/dist/data/chat/ContextMeter.js.map +1 -1
  104. package/dist/data/chat/approval.cjs +21 -0
  105. package/dist/data/chat/approval.cjs.map +1 -0
  106. package/dist/data/chat/approval.d.ts +11 -0
  107. package/dist/data/chat/approval.d.ts.map +1 -0
  108. package/dist/data/chat/approval.js +21 -0
  109. package/dist/data/chat/approval.js.map +1 -0
  110. package/dist/data/chat/types.cjs.map +1 -1
  111. package/dist/data/chat/types.d.ts +12 -0
  112. package/dist/data/chat/types.d.ts.map +1 -1
  113. package/dist/data/chat/types.js.map +1 -1
  114. package/dist/data/server-timing.cjs +120 -0
  115. package/dist/data/server-timing.cjs.map +1 -0
  116. package/dist/data/server-timing.d.ts +11 -0
  117. package/dist/data/server-timing.d.ts.map +1 -0
  118. package/dist/data/server-timing.js +120 -0
  119. package/dist/data/server-timing.js.map +1 -0
  120. package/dist/data/version-info.cjs +3 -3
  121. package/dist/data/version-info.js +3 -3
  122. package/dist/data.cjs +7 -0
  123. package/dist/data.cjs.map +1 -1
  124. package/dist/data.d.ts +2 -0
  125. package/dist/data.d.ts.map +1 -1
  126. package/dist/data.js +7 -0
  127. package/dist/data.js.map +1 -1
  128. package/dist/index.cjs +7 -0
  129. package/dist/index.cjs.map +1 -1
  130. package/dist/index.js +7 -0
  131. package/dist/index.js.map +1 -1
  132. package/dist/layout/AppShell.cjs +1 -1
  133. package/dist/layout/AppShell.cjs.map +1 -1
  134. package/dist/layout/AppShell.js +1 -1
  135. package/dist/layout/AppShell.js.map +1 -1
  136. package/dist/overlay/HoverCard.cjs.map +1 -1
  137. package/dist/overlay/HoverCard.d.ts +2 -2
  138. package/dist/overlay/HoverCard.d.ts.map +1 -1
  139. package/dist/overlay/HoverCard.js.map +1 -1
  140. package/dist/rpc/OperationCatalog.cjs +28 -51
  141. package/dist/rpc/OperationCatalog.cjs.map +1 -1
  142. package/dist/rpc/OperationCatalog.d.ts +1 -6
  143. package/dist/rpc/OperationCatalog.d.ts.map +1 -1
  144. package/dist/rpc/OperationCatalog.js +29 -52
  145. package/dist/rpc/OperationCatalog.js.map +1 -1
  146. package/dist/rpc/OperationResultView.cjs +42 -0
  147. package/dist/rpc/OperationResultView.cjs.map +1 -1
  148. package/dist/rpc/OperationResultView.d.ts +2 -1
  149. package/dist/rpc/OperationResultView.d.ts.map +1 -1
  150. package/dist/rpc/OperationResultView.js +42 -0
  151. package/dist/rpc/OperationResultView.js.map +1 -1
  152. package/dist/styles.css +1 -1
  153. package/dist/tailwind-preset.cjs +4 -0
  154. package/dist/tailwind-preset.cjs.map +1 -1
  155. package/dist/tailwind-preset.d.ts.map +1 -1
  156. package/dist/tailwind-preset.js +4 -0
  157. package/dist/tailwind-preset.js.map +1 -1
  158. package/package.json +1 -1
@@ -6,6 +6,8 @@ const DropdownMenu = require("../../overlay/DropdownMenu.cjs");
6
6
  const Icon = require("../Icon.cjs");
7
7
  const effortIcons = require("../chat/effort-icons.cjs");
8
8
  const providerIcons = require("../chat/provider-icons.cjs");
9
+ const RuntimeBar_model = require("./RuntimeBar.model.cjs");
10
+ const RuntimeBarCombo = require("./RuntimeBarCombo.cjs");
9
11
  const fields = require("./SpecRuntimeEditor/fields.cjs");
10
12
  const update = require("./SpecRuntimeEditor/update.cjs");
11
13
  const modelCapabilities = require("./model-capabilities.cjs");
@@ -15,6 +17,7 @@ const UiCheck = require("../../icons/components/UiCheck.cjs");
15
17
  function RuntimeBar({
16
18
  value,
17
19
  onChange,
20
+ variant = "segmented",
18
21
  models = [],
19
22
  families = runtimeMode.SPEC_RUNTIME_FAMILIES,
20
23
  reasoningEfforts = effortIcons.DEFAULT_REASONING_EFFORTS,
@@ -25,19 +28,63 @@ function RuntimeBar({
25
28
  const family = runtimeMode.familyById(families, selection.family);
26
29
  const mode = family.modes.find((entry) => entry.id === selection.mode) ?? runtimeMode.firstMode(family);
27
30
  const modelOptions = runtimeMode.modelsForFamily(models, family, value.backend);
28
- const selectedModel = models.find((entry) => entry.id === value.model);
29
- const supportedEfforts = modelCapabilities.effortOptionsForModel(selectedModel, reasoningEfforts);
31
+ const selectedModel = models.find(
32
+ (entry) => {
33
+ var _a;
34
+ return ((_a = entry.runtime) == null ? void 0 : _a.backend) === value.backend && RuntimeBar_model.runtimeModelMatches(entry, value);
35
+ }
36
+ );
37
+ const resolvedModel = selectedModel ?? models.find((entry) => RuntimeBar_model.runtimeModelMatches(entry, value));
38
+ const supportedEfforts = modelCapabilities.effortOptionsForModel(
39
+ resolvedModel,
40
+ reasoningEfforts
41
+ );
30
42
  const applyBackend = (familyId, modeId) => {
31
43
  const backend = runtimeMode.backendForFamilyMode(families, familyId, modeId);
32
44
  if (backend === (value.backend ?? "")) return;
33
- let next = update.withOptionalRoot(update.withRoot(value, { backend }), "cliArgs", void 0);
34
- if (!runtimeMode.modelBelongsToFamily(value.model, models, runtimeMode.familyById(families, familyId), backend)) {
35
- next = update.withOptionalRoot(next, "model", void 0);
45
+ let next = update.withOptionalRoot(
46
+ update.withRoot(value, { backend }),
47
+ "cliArgs",
48
+ void 0
49
+ );
50
+ if (!runtimeMode.modelBelongsToFamily(
51
+ value.model,
52
+ models,
53
+ runtimeMode.familyById(families, familyId),
54
+ backend
55
+ )) {
56
+ next = withoutCatalogModel(next);
36
57
  }
37
58
  onChange(next);
38
59
  };
39
- const brand = familyBrand(family);
40
- const modelLabel = (selectedModel == null ? void 0 : selectedModel.label) ?? value.model ?? "Default";
60
+ const applyCustomModel = (model) => onChange(update.withOptionalRoot(withoutCatalogModel(value), "model", model));
61
+ const applyModel = (model) => onChange(modelCapabilities.reconcileModelCapabilities(value, model, reasoningEfforts));
62
+ const clearModel = () => onChange(withoutCatalogModel(value));
63
+ const applyEffort = (effort) => onChange(update.withOptionalRoot(value, "effort", effort));
64
+ if (variant === "combo") {
65
+ return /* @__PURE__ */ jsxRuntime.jsx(
66
+ RuntimeBarCombo.RuntimeBarCombo,
67
+ {
68
+ value,
69
+ families,
70
+ family,
71
+ mode,
72
+ selectedMode: selection.mode,
73
+ models: modelOptions,
74
+ selectedModel: resolvedModel,
75
+ supportedEfforts,
76
+ ariaLabel,
77
+ className,
78
+ onFamilyChange: (familyId) => applyBackend(familyId, selection.mode),
79
+ onModeChange: (modeId) => applyBackend(family.id, modeId),
80
+ onModelSelect: applyModel,
81
+ onModelClear: clearModel,
82
+ onEffortChange: applyEffort
83
+ }
84
+ );
85
+ }
86
+ const brand = RuntimeBar_model.runtimeFamilyBrand(family);
87
+ const modelLabel = (resolvedModel == null ? void 0 : resolvedModel.label) ?? value.model ?? "Default";
41
88
  return /* @__PURE__ */ jsxRuntime.jsxs(
42
89
  "div",
43
90
  {
@@ -64,7 +111,13 @@ function RuntimeBar({
64
111
  onSelect: (familyId) => applyBackend(familyId, selection.mode)
65
112
  }),
66
113
  children: [
67
- brand.icon && /* @__PURE__ */ jsxRuntime.jsx(Icon.Icon, { icon: brand.icon, className: utils.cn("size-4 shrink-0", brand.color) }),
114
+ brand.icon && /* @__PURE__ */ jsxRuntime.jsx(
115
+ Icon.Icon,
116
+ {
117
+ icon: brand.icon,
118
+ className: utils.cn("size-4 shrink-0", brand.color)
119
+ }
120
+ ),
68
121
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: CAPTION_CLASS, children: family.label })
69
122
  ]
70
123
  }
@@ -81,7 +134,13 @@ function RuntimeBar({
81
134
  onSelect: (modeId) => applyBackend(family.id, modeId)
82
135
  }),
83
136
  children: [
84
- mode.icon && /* @__PURE__ */ jsxRuntime.jsx(Icon.Icon, { icon: mode.icon, className: "size-4 shrink-0 text-muted-foreground" }),
137
+ mode.icon && /* @__PURE__ */ jsxRuntime.jsx(
138
+ Icon.Icon,
139
+ {
140
+ icon: mode.icon,
141
+ className: "size-4 shrink-0 text-muted-foreground"
142
+ }
143
+ ),
85
144
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: CAPTION_CLASS, children: mode.label })
86
145
  ]
87
146
  }
@@ -98,7 +157,7 @@ function RuntimeBar({
98
157
  fields.SpecInput,
99
158
  {
100
159
  value: value.model,
101
- onChange: (model) => onChange(update.withOptionalRoot(value, "model", model)),
160
+ onChange: applyCustomModel,
102
161
  ariaLabel: "Model id",
103
162
  mono: true
104
163
  }
@@ -107,15 +166,9 @@ function RuntimeBar({
107
166
  items: modelItems({
108
167
  models: modelOptions,
109
168
  group: `${family.label} models`,
110
- selectedId: value.model,
111
- onSelect: (model) => onChange(
112
- modelCapabilities.reconcileModelCapabilities(
113
- value,
114
- models.find((entry) => entry.id === model),
115
- reasoningEfforts
116
- )
117
- ),
118
- onClear: () => onChange(update.withOptionalRoot(value, "model", void 0))
169
+ selectedId: (resolvedModel == null ? void 0 : resolvedModel.id) ?? value.model,
170
+ onSelect: applyModel,
171
+ onClear: clearModel
119
172
  }),
120
173
  children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "min-w-0 truncate font-mono text-xs text-foreground", children: modelLabel })
121
174
  }
@@ -126,10 +179,14 @@ function RuntimeBar({
126
179
  menuLabel: "Reasoning effort",
127
180
  title: "Reasoning effort",
128
181
  items: effortItems({
129
- offered: effortUniverse(reasoningEfforts, supportedEfforts, value.effort),
182
+ offered: effortUniverse(
183
+ reasoningEfforts,
184
+ supportedEfforts,
185
+ value.effort
186
+ ),
130
187
  supported: supportedEfforts,
131
188
  selected: value.effort,
132
- onSelect: (effort) => onChange(update.withOptionalRoot(value, "effort", effort))
189
+ onSelect: applyEffort
133
190
  }),
134
191
  children: [
135
192
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: KEY_CLASS, children: "Effort" }),
@@ -142,6 +199,13 @@ function RuntimeBar({
142
199
  }
143
200
  );
144
201
  }
202
+ function withoutCatalogModel(value) {
203
+ return update.withOptionalRoot(
204
+ update.withOptionalRoot(value, "model", void 0),
205
+ "id",
206
+ void 0
207
+ );
208
+ }
145
209
  const CAPTION_CLASS = "truncate text-xs font-semibold text-foreground";
146
210
  const KEY_CLASS = "text-[11px] font-semibold uppercase leading-none tracking-wide text-muted-foreground";
147
211
  function RuntimeSegment({
@@ -189,7 +253,10 @@ function EffortGlyph({ effort }) {
189
253
  Icon.Icon,
190
254
  {
191
255
  icon: glyph,
192
- className: utils.cn("size-4 shrink-0", effort ? effortIcons.effortLevelColor(effort) : void 0)
256
+ className: utils.cn(
257
+ "size-4 shrink-0",
258
+ effort ? effortIcons.effortLevelColor(effort) : void 0
259
+ )
193
260
  }
194
261
  );
195
262
  }
@@ -209,7 +276,10 @@ function itemLabel({
209
276
  Icon.Icon,
210
277
  {
211
278
  icon: UiCheck.UiCheck,
212
- className: utils.cn("size-3.5 shrink-0 text-primary", !selected && "invisible")
279
+ className: utils.cn(
280
+ "size-3.5 shrink-0 text-primary",
281
+ !selected && "invisible"
282
+ )
213
283
  }
214
284
  )
215
285
  ] });
@@ -221,7 +291,7 @@ function familyItems({
221
291
  onSelect
222
292
  }) {
223
293
  return families.map((family) => {
224
- const brand = familyBrand(family);
294
+ const brand = RuntimeBar_model.runtimeFamilyBrand(family);
225
295
  const count = runtimeMode.modelsForFamily(models, family).length;
226
296
  return {
227
297
  group: "Family",
@@ -235,10 +305,6 @@ function familyItems({
235
305
  };
236
306
  });
237
307
  }
238
- function familyBrand(family) {
239
- const key = providerIcons.providerIcon(family.id) ? family.id : family.provider;
240
- return { icon: providerIcons.providerIcon(key), color: providerIcons.providerIconColor(key) };
241
- }
242
308
  function modeItems({
243
309
  families,
244
310
  family,
@@ -247,7 +313,7 @@ function modeItems({
247
313
  }) {
248
314
  return runtimeMode.runtimeModeOptions(families).map((mode) => {
249
315
  const supported = family.modes.find((entry) => entry.id === mode.id);
250
- const hint = (supported == null ? void 0 : supported.title) ?? `not on ${family.label}`;
316
+ const hint = (supported == null ? void 0 : supported.title) ?? runtimeMode.unsupportedModeTitle(family);
251
317
  return {
252
318
  group: "Mode · runtime",
253
319
  label: itemLabel({
@@ -281,7 +347,9 @@ function modelItems({
281
347
  return [
282
348
  clear,
283
349
  ...models.map((model) => {
284
- const glyph = providerIcons.providerIcon(model.provider);
350
+ const glyph = providerIcons.providerIcon(
351
+ model.provider
352
+ );
285
353
  return {
286
354
  group,
287
355
  label: itemLabel({
@@ -292,7 +360,7 @@ function modelItems({
292
360
  }),
293
361
  ...glyph ? { icon: glyph } : {},
294
362
  disabled: model.configured === false,
295
- onSelect: () => onSelect(model.id)
363
+ onSelect: () => onSelect(model)
296
364
  };
297
365
  })
298
366
  ];
@@ -306,7 +374,11 @@ function effortItems({
306
374
  const current = (selected == null ? void 0 : selected.trim()) ?? "";
307
375
  const none = {
308
376
  group: "Reasoning effort",
309
- label: itemLabel({ text: "None", hint: "single pass", selected: current === "" }),
377
+ label: itemLabel({
378
+ text: "None",
379
+ hint: "single pass",
380
+ selected: current === ""
381
+ }),
310
382
  onSelect: () => onSelect("")
311
383
  };
312
384
  return [
@@ -1 +1 @@
1
- {"version":3,"file":"RuntimeBar.cjs","sources":["../../../src/data/ai/RuntimeBar.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport { UiCheck, UiChevronDown } from \"../../icons\";\nimport { cn } from \"../../lib/utils\";\nimport { DropdownMenu, type DropdownMenuItem } from \"../../overlay/DropdownMenu\";\nimport { Icon, type StaticIconComponent } from \"../Icon\";\nimport {\n DEFAULT_REASONING_EFFORTS,\n effortLevelColor,\n effortLevelIcon,\n effortLevelLabel,\n} from \"../chat/effort-icons\";\nimport { providerIcon, providerIconColor } from \"../chat/provider-icons\";\nimport type { ChatModel } from \"../chat/types\";\nimport type { AISpecRuntimeValue } from \"./SpecRuntimeEditor.model\";\nimport { SpecInput } from \"./SpecRuntimeEditor/fields\";\nimport { withOptionalRoot, withRoot } from \"./SpecRuntimeEditor/update\";\nimport { effortOptionsForModel, reconcileModelCapabilities } from \"./model-capabilities\";\nimport {\n SPEC_RUNTIME_FAMILIES,\n backendForFamilyMode,\n familyById,\n firstMode,\n modelBelongsToFamily,\n modelsForFamily,\n runtimeModeOptions,\n selectionForBackend,\n type SpecRuntimeFamily,\n} from \"./runtime-mode\";\n\nexport type RuntimeBarProps = {\n value: AISpecRuntimeValue;\n onChange: (value: AISpecRuntimeValue) => void;\n /** Model catalog. Only the selected family's models are listed; a family the\n * catalog does not describe is served by the segment's free-text entry. */\n models?: ChatModel[] | undefined;\n families?: SpecRuntimeFamily[] | undefined;\n /** Effort tiers offered when the catalog does not describe the model. */\n reasoningEfforts?: string[] | undefined;\n ariaLabel?: string | undefined;\n className?: string | undefined;\n};\n\n/**\n * The runtime as one self-describing row: family, mode, model and reasoning\n * effort as four menu segments in a single bordered bar. Each segment carries\n * its own value, so the bar needs no field labels above it and its width tracks\n * the content instead of the form grid. Unsupported combinations (a mode the\n * family lacks, an effort the model rejects) stay in place and disabled, so the\n * constraint reads before it is hit. The Model segment is always present — a\n * family with no catalog models is typed into the menu's free-text entry rather\n * than pushed out into a separate field.\n */\nexport function RuntimeBar({\n value,\n onChange,\n models = [],\n families = SPEC_RUNTIME_FAMILIES,\n reasoningEfforts = DEFAULT_REASONING_EFFORTS,\n ariaLabel = \"Runtime\",\n className,\n}: RuntimeBarProps) {\n const selection = selectionForBackend(families, value.backend);\n const family = familyById(families, selection.family);\n const mode =\n family.modes.find((entry) => entry.id === selection.mode) ?? firstMode(family);\n const modelOptions = modelsForFamily(models, family, value.backend);\n const selectedModel = models.find((entry) => entry.id === value.model);\n const supportedEfforts = effortOptionsForModel(selectedModel, reasoningEfforts);\n\n const applyBackend = (familyId: string, modeId: string) => {\n const backend = backendForFamilyMode(families, familyId, modeId);\n if (backend === (value.backend ?? \"\")) return;\n // A backend switch invalidates the previous backend's cmux CLI-arg values.\n let next = withOptionalRoot(withRoot(value, { backend }), \"cliArgs\", undefined);\n if (!modelBelongsToFamily(value.model, models, familyById(families, familyId), backend)) {\n next = withOptionalRoot(next, \"model\", undefined);\n }\n onChange(next);\n };\n\n const brand = familyBrand(family);\n const modelLabel = selectedModel?.label ?? value.model ?? \"Default\";\n\n return (\n <div\n role=\"group\"\n aria-label={ariaLabel}\n className={cn(\n // `w-fit` so the bar hugs its segments instead of being stretched by a\n // grid/flex parent — the row is content-sized, not a form field.\n // The outer edge is a control border (`--input`); the segment dividers\n // inside it are the subtler `--border`, so the bar reads as one object.\n \"inline-flex h-control-h w-fit max-w-full items-stretch overflow-hidden rounded-md border border-input bg-background\",\n className,\n )}\n >\n <RuntimeSegment\n menuLabel=\"Family\"\n title={`Family — ${family.label}`}\n items={familyItems({\n families,\n models,\n selectedId: family.id,\n onSelect: (familyId) => applyBackend(familyId, selection.mode),\n })}\n >\n {brand.icon && (\n <Icon icon={brand.icon} className={cn(\"size-4 shrink-0\", brand.color)} />\n )}\n <span className={CAPTION_CLASS}>{family.label}</span>\n </RuntimeSegment>\n <RuntimeSegment\n menuLabel=\"Runtime mode\"\n title={mode.title ?? \"Runtime mode\"}\n items={modeItems({\n families,\n family,\n selectedId: selection.mode,\n onSelect: (modeId) => applyBackend(family.id, modeId),\n })}\n >\n {mode.icon && (\n <Icon icon={mode.icon} className=\"size-4 shrink-0 text-muted-foreground\" />\n )}\n <span className={CAPTION_CLASS}>{mode.label}</span>\n </RuntimeSegment>\n <RuntimeSegment\n menuLabel=\"Model\"\n title={value.model ? `Model — ${value.model}` : \"Model — prompt default\"}\n className=\"min-w-0 max-w-56\"\n header={\n <div className=\"grid gap-1\">\n <span className={KEY_CLASS}>Model id</span>\n <SpecInput\n value={value.model}\n onChange={(model) => onChange(withOptionalRoot(value, \"model\", model))}\n ariaLabel=\"Model id\"\n mono\n />\n </div>\n }\n items={modelItems({\n models: modelOptions,\n group: `${family.label} models`,\n selectedId: value.model,\n onSelect: (model) =>\n onChange(\n reconcileModelCapabilities(\n value,\n models.find((entry) => entry.id === model),\n reasoningEfforts,\n ),\n ),\n onClear: () => onChange(withOptionalRoot(value, \"model\", undefined)),\n })}\n >\n <span className=\"min-w-0 truncate font-mono text-xs text-foreground\">\n {modelLabel}\n </span>\n </RuntimeSegment>\n {supportedEfforts.length > 0 && (\n <RuntimeSegment\n menuLabel=\"Reasoning effort\"\n title=\"Reasoning effort\"\n items={effortItems({\n offered: effortUniverse(reasoningEfforts, supportedEfforts, value.effort),\n supported: supportedEfforts,\n selected: value.effort,\n onSelect: (effort) => onChange(withOptionalRoot(value, \"effort\", effort)),\n })}\n >\n <span className={KEY_CLASS}>Effort</span>\n <EffortGlyph effort={value.effort} />\n <span className={CAPTION_CLASS}>\n {value.effort ? effortLevelLabel(value.effort) : \"None\"}\n </span>\n </RuntimeSegment>\n )}\n </div>\n );\n}\n\nconst CAPTION_CLASS = \"truncate text-xs font-semibold text-foreground\";\nconst KEY_CLASS =\n \"text-[11px] font-semibold uppercase leading-none tracking-wide text-muted-foreground\";\n\nfunction RuntimeSegment({\n items,\n menuLabel,\n title,\n header,\n className,\n children,\n}: {\n items: DropdownMenuItem[];\n menuLabel: string;\n title: string;\n header?: ReactNode;\n className?: string | undefined;\n children: ReactNode;\n}) {\n return (\n <DropdownMenu\n align=\"left\"\n menuLabel={menuLabel}\n items={items}\n {...(header ? { header } : {})}\n menuClassName=\"min-w-56 max-w-80\"\n className={cn(\"border-l border-border first:border-l-0\", className)}\n trigger={\n <button\n type=\"button\"\n title={title}\n className=\"inline-flex h-full min-w-0 items-center gap-1.5 px-density-2 transition-colors hover:bg-muted focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-ring [[aria-expanded=true]_&]:bg-muted\"\n >\n {children}\n <Icon\n icon={UiChevronDown}\n className=\"size-3 shrink-0 text-muted-foreground/70\"\n />\n </button>\n }\n />\n );\n}\n\nfunction EffortGlyph({ effort }: { effort?: string | undefined }) {\n const glyph = effort ? effortLevelIcon(effort) : undefined;\n if (!glyph) return null;\n return (\n <Icon\n icon={glyph}\n className={cn(\"size-4 shrink-0\", effort ? effortLevelColor(effort) : undefined)}\n />\n );\n}\n\n// Menu rows share one grid: label, hint, and a check that stays in the layout\n// when unselected so the rows do not shift. Short hints (\"3 models\", \"not on\n// Claude\") sit inline on the right; a `stacked` hint — a model id, which is as\n// long as the label and would truncate both — gets its own line underneath.\nfunction itemLabel({\n text,\n hint,\n selected,\n stacked = false,\n}: {\n text: string;\n hint?: string | undefined;\n selected: boolean;\n stacked?: boolean | undefined;\n}): ReactNode {\n return (\n <>\n <span className=\"min-w-0 flex-1\">\n <span className={cn(\"block truncate\", selected && \"font-semibold\")}>\n {text}\n </span>\n {hint && stacked && (\n <span className=\"block truncate font-mono text-[11px] text-muted-foreground\">\n {hint}\n </span>\n )}\n </span>\n {hint && !stacked && (\n <span className=\"shrink-0 text-[11px] text-muted-foreground\">{hint}</span>\n )}\n <Icon\n icon={UiCheck}\n className={cn(\"size-3.5 shrink-0 text-primary\", !selected && \"invisible\")}\n />\n </>\n );\n}\n\nfunction familyItems({\n families,\n models,\n selectedId,\n onSelect,\n}: {\n families: SpecRuntimeFamily[];\n models: ChatModel[];\n selectedId: string;\n onSelect: (familyId: string) => void;\n}): DropdownMenuItem[] {\n return families.map((family) => {\n const brand = familyBrand(family);\n const count = modelsForFamily(models, family).length;\n return {\n group: \"Family\",\n label: itemLabel({\n text: family.label,\n ...(count > 0 ? { hint: `${count} models` } : {}),\n selected: family.id === selectedId,\n }),\n ...(brand.icon ? { icon: brand.icon } : {}),\n onSelect: () => onSelect(family.id),\n };\n });\n}\n\n// Families key their brand mark off the family id (\"claude\"), falling back to\n// the catalog provider (\"googleai\"); the raw backend provider (\"claude-agent\")\n// is not a brand.\nfunction familyBrand(family: SpecRuntimeFamily): {\n icon: StaticIconComponent | undefined;\n color: string | undefined;\n} {\n const key = providerIcon(family.id) ? family.id : family.provider;\n return { icon: providerIcon(key), color: providerIconColor(key) };\n}\n\nfunction modeItems({\n families,\n family,\n selectedId,\n onSelect,\n}: {\n families: SpecRuntimeFamily[];\n family: SpecRuntimeFamily;\n selectedId: string;\n onSelect: (modeId: string) => void;\n}): DropdownMenuItem[] {\n return runtimeModeOptions(families).map((mode) => {\n const supported = family.modes.find((entry) => entry.id === mode.id);\n const hint = supported?.title ?? `not on ${family.label}`;\n return {\n group: \"Mode · runtime\",\n label: itemLabel({\n text: supported?.label ?? mode.label,\n hint,\n selected: mode.id === selectedId,\n }),\n ...(mode.icon ? { icon: mode.icon } : {}),\n title: hint,\n disabled: !supported,\n onSelect: () => onSelect(mode.id),\n };\n });\n}\n\nfunction modelItems({\n models,\n group,\n selectedId,\n onSelect,\n onClear,\n}: {\n models: ChatModel[];\n group: string;\n selectedId?: string | undefined;\n onSelect: (modelId: string) => void;\n onClear: () => void;\n}): DropdownMenuItem[] {\n const clear: DropdownMenuItem = {\n group: \"Model\",\n label: itemLabel({\n text: \"Prompt default\",\n hint: \"no override\",\n selected: !selectedId,\n }),\n onSelect: onClear,\n };\n return [\n clear,\n ...models.map((model) => {\n const glyph: StaticIconComponent | undefined = providerIcon(model.provider);\n return {\n group,\n label: itemLabel({\n text: model.label,\n ...(model.id === model.label ? {} : { hint: model.id }),\n selected: model.id === selectedId,\n stacked: true,\n }),\n ...(glyph ? { icon: glyph } : {}),\n disabled: model.configured === false,\n onSelect: () => onSelect(model.id),\n };\n }),\n ];\n}\n\nfunction effortItems({\n offered,\n supported,\n selected,\n onSelect,\n}: {\n offered: string[];\n supported: string[];\n selected?: string | undefined;\n onSelect: (effort: string) => void;\n}): DropdownMenuItem[] {\n const current = selected?.trim() ?? \"\";\n const none: DropdownMenuItem = {\n group: \"Reasoning effort\",\n label: itemLabel({ text: \"None\", hint: \"single pass\", selected: current === \"\" }),\n onSelect: () => onSelect(\"\"),\n };\n return [\n none,\n ...offered.map((effort) => {\n const glyph = effortLevelIcon(effort);\n const usable = supported.includes(effort);\n return {\n group: \"Reasoning effort\",\n label: itemLabel({\n text: effortLevelLabel(effort),\n ...(usable ? {} : { hint: \"unsupported\" }),\n selected: effort === current,\n }),\n ...(glyph ? { icon: glyph } : {}),\n disabled: !usable,\n onSelect: () => onSelect(effort),\n };\n }),\n ];\n}\n\n// The tiers the menu shows: everything offered by the catalog default, plus any\n// model-specific tier and the current selection, so a value set elsewhere is\n// never silently absent from its own menu.\nfunction effortUniverse(\n offered: readonly string[],\n supported: readonly string[],\n selected: string | undefined,\n): string[] {\n const all = [...offered, ...supported, selected ?? \"\"]\n .map((effort) => effort.trim())\n .filter(Boolean);\n return [...new Set(all)];\n}\n"],"names":["SPEC_RUNTIME_FAMILIES","DEFAULT_REASONING_EFFORTS","selectionForBackend","familyById","firstMode","modelsForFamily","effortOptionsForModel","backendForFamilyMode","withOptionalRoot","withRoot","modelBelongsToFamily","jsxs","cn","jsx","Icon","SpecInput","reconcileModelCapabilities","effortLevelLabel","DropdownMenu","UiChevronDown","effortLevelIcon","effortLevelColor","Fragment","UiCheck","providerIcon","providerIconColor","runtimeModeOptions"],"mappings":"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"}
1
+ {"version":3,"file":"RuntimeBar.cjs","sources":["../../../src/data/ai/RuntimeBar.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport { UiCheck, UiChevronDown } from \"../../icons\";\nimport { cn } from \"../../lib/utils\";\nimport {\n DropdownMenu,\n type DropdownMenuItem,\n} from \"../../overlay/DropdownMenu\";\nimport { Icon, type StaticIconComponent } from \"../Icon\";\nimport {\n DEFAULT_REASONING_EFFORTS,\n effortLevelColor,\n effortLevelIcon,\n effortLevelLabel,\n} from \"../chat/effort-icons\";\nimport { providerIcon } from \"../chat/provider-icons\";\nimport type { ChatModel } from \"../chat/types\";\nimport { runtimeFamilyBrand, runtimeModelMatches } from \"./RuntimeBar.model\";\nimport { RuntimeBarCombo } from \"./RuntimeBarCombo\";\nimport type { AISpecRuntimeValue } from \"./SpecRuntimeEditor.model\";\nimport { SpecInput } from \"./SpecRuntimeEditor/fields\";\nimport { withOptionalRoot, withRoot } from \"./SpecRuntimeEditor/update\";\nimport {\n effortOptionsForModel,\n reconcileModelCapabilities,\n} from \"./model-capabilities\";\nimport {\n SPEC_RUNTIME_FAMILIES,\n backendForFamilyMode,\n familyById,\n firstMode,\n modelBelongsToFamily,\n modelsForFamily,\n runtimeModeOptions,\n selectionForBackend,\n unsupportedModeTitle,\n type SpecRuntimeFamily,\n} from \"./runtime-mode\";\n\nexport type RuntimeBarProps = {\n value: AISpecRuntimeValue;\n onChange: (value: AISpecRuntimeValue) => void;\n /** `segmented` uses field triggers; `combo` uses one direct-edit menu. */\n variant?: \"combo\" | \"segmented\";\n /** Model catalog. Only the selected family's models are listed; a family the\n * catalog does not describe is served by the segment's free-text entry. */\n models?: ChatModel[] | undefined;\n families?: SpecRuntimeFamily[] | undefined;\n /** Effort tiers offered when the catalog does not describe the model. */\n reasoningEfforts?: string[] | undefined;\n ariaLabel?: string | undefined;\n className?: string | undefined;\n};\n\n/** Self-describing runtime controls with segmented and combo presentations. */\nexport function RuntimeBar({\n value,\n onChange,\n variant = \"segmented\",\n models = [],\n families = SPEC_RUNTIME_FAMILIES,\n reasoningEfforts = DEFAULT_REASONING_EFFORTS,\n ariaLabel = \"Runtime\",\n className,\n}: RuntimeBarProps) {\n const selection = selectionForBackend(families, value.backend);\n const family = familyById(families, selection.family);\n const mode =\n family.modes.find((entry) => entry.id === selection.mode) ??\n firstMode(family);\n const modelOptions = modelsForFamily(models, family, value.backend);\n const selectedModel = models.find(\n (entry) =>\n entry.runtime?.backend === value.backend &&\n runtimeModelMatches(entry, value),\n );\n const resolvedModel =\n selectedModel ?? models.find((entry) => runtimeModelMatches(entry, value));\n const supportedEfforts = effortOptionsForModel(\n resolvedModel,\n reasoningEfforts,\n );\n\n const applyBackend = (familyId: string, modeId: string) => {\n const backend = backendForFamilyMode(families, familyId, modeId);\n if (backend === (value.backend ?? \"\")) return;\n // A backend switch invalidates the previous backend's cmux CLI-arg values.\n let next = withOptionalRoot(\n withRoot(value, { backend }),\n \"cliArgs\",\n undefined,\n );\n if (\n !modelBelongsToFamily(\n value.model,\n models,\n familyById(families, familyId),\n backend,\n )\n ) {\n next = withoutCatalogModel(next);\n }\n onChange(next);\n };\n\n // `id` is the catalog row a `model` came from and `runtimeModelMatches` reads\n // it first, so it has to travel with `model` — a surviving `id` would keep\n // resolving the previous provider's row against a new backend.\n const applyCustomModel = (model: string) =>\n onChange(withOptionalRoot(withoutCatalogModel(value), \"model\", model));\n const applyModel = (model: ChatModel) =>\n onChange(reconcileModelCapabilities(value, model, reasoningEfforts));\n const clearModel = () => onChange(withoutCatalogModel(value));\n const applyEffort = (effort: string) =>\n onChange(withOptionalRoot(value, \"effort\", effort));\n\n if (variant === \"combo\") {\n return (\n <RuntimeBarCombo\n value={value}\n families={families}\n family={family}\n mode={mode}\n selectedMode={selection.mode}\n models={modelOptions}\n selectedModel={resolvedModel}\n supportedEfforts={supportedEfforts}\n ariaLabel={ariaLabel}\n className={className}\n onFamilyChange={(familyId) => applyBackend(familyId, selection.mode)}\n onModeChange={(modeId) => applyBackend(family.id, modeId)}\n onModelSelect={applyModel}\n onModelClear={clearModel}\n onEffortChange={applyEffort}\n />\n );\n }\n\n const brand = runtimeFamilyBrand(family);\n const modelLabel = resolvedModel?.label ?? value.model ?? \"Default\";\n\n return (\n <div\n role=\"group\"\n aria-label={ariaLabel}\n className={cn(\n // `w-fit` so the bar hugs its segments instead of being stretched by a\n // grid/flex parent — the row is content-sized, not a form field.\n // The outer edge is a control border (`--input`); the segment dividers\n // inside it are the subtler `--border`, so the bar reads as one object.\n \"inline-flex h-control-h w-fit max-w-full items-stretch overflow-hidden rounded-md border border-input bg-background\",\n className,\n )}\n >\n <RuntimeSegment\n menuLabel=\"Family\"\n title={`Family — ${family.label}`}\n items={familyItems({\n families,\n models,\n selectedId: family.id,\n onSelect: (familyId) => applyBackend(familyId, selection.mode),\n })}\n >\n {brand.icon && (\n <Icon\n icon={brand.icon}\n className={cn(\"size-4 shrink-0\", brand.color)}\n />\n )}\n <span className={CAPTION_CLASS}>{family.label}</span>\n </RuntimeSegment>\n <RuntimeSegment\n menuLabel=\"Runtime mode\"\n title={mode.title ?? \"Runtime mode\"}\n items={modeItems({\n families,\n family,\n selectedId: selection.mode,\n onSelect: (modeId) => applyBackend(family.id, modeId),\n })}\n >\n {mode.icon && (\n <Icon\n icon={mode.icon}\n className=\"size-4 shrink-0 text-muted-foreground\"\n />\n )}\n <span className={CAPTION_CLASS}>{mode.label}</span>\n </RuntimeSegment>\n <RuntimeSegment\n menuLabel=\"Model\"\n title={\n value.model ? `Model — ${value.model}` : \"Model — prompt default\"\n }\n className=\"min-w-0 max-w-56\"\n header={\n <div className=\"grid gap-1\">\n <span className={KEY_CLASS}>Model id</span>\n <SpecInput\n value={value.model}\n onChange={applyCustomModel}\n ariaLabel=\"Model id\"\n mono\n />\n </div>\n }\n items={modelItems({\n models: modelOptions,\n group: `${family.label} models`,\n selectedId: resolvedModel?.id ?? value.model,\n onSelect: applyModel,\n onClear: clearModel,\n })}\n >\n <span className=\"min-w-0 truncate font-mono text-xs text-foreground\">\n {modelLabel}\n </span>\n </RuntimeSegment>\n {supportedEfforts.length > 0 && (\n <RuntimeSegment\n menuLabel=\"Reasoning effort\"\n title=\"Reasoning effort\"\n items={effortItems({\n offered: effortUniverse(\n reasoningEfforts,\n supportedEfforts,\n value.effort,\n ),\n supported: supportedEfforts,\n selected: value.effort,\n onSelect: applyEffort,\n })}\n >\n <span className={KEY_CLASS}>Effort</span>\n <EffortGlyph effort={value.effort} />\n <span className={CAPTION_CLASS}>\n {value.effort ? effortLevelLabel(value.effort) : \"None\"}\n </span>\n </RuntimeSegment>\n )}\n </div>\n );\n}\n\nfunction withoutCatalogModel(value: AISpecRuntimeValue): AISpecRuntimeValue {\n return withOptionalRoot(\n withOptionalRoot(value, \"model\", undefined),\n \"id\",\n undefined,\n );\n}\n\nconst CAPTION_CLASS = \"truncate text-xs font-semibold text-foreground\";\nconst KEY_CLASS =\n \"text-[11px] font-semibold uppercase leading-none tracking-wide text-muted-foreground\";\n\nfunction RuntimeSegment({\n items,\n menuLabel,\n title,\n header,\n className,\n children,\n}: {\n items: DropdownMenuItem[];\n menuLabel: string;\n title: string;\n header?: ReactNode;\n className?: string | undefined;\n children: ReactNode;\n}) {\n return (\n <DropdownMenu\n align=\"left\"\n menuLabel={menuLabel}\n items={items}\n {...(header ? { header } : {})}\n menuClassName=\"min-w-56 max-w-80\"\n className={cn(\"border-l border-border first:border-l-0\", className)}\n trigger={\n <button\n type=\"button\"\n title={title}\n className=\"inline-flex h-full min-w-0 items-center gap-1.5 px-density-2 transition-colors hover:bg-muted focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-ring [[aria-expanded=true]_&]:bg-muted\"\n >\n {children}\n <Icon\n icon={UiChevronDown}\n className=\"size-3 shrink-0 text-muted-foreground/70\"\n />\n </button>\n }\n />\n );\n}\n\nfunction EffortGlyph({ effort }: { effort?: string | undefined }) {\n const glyph = effort ? effortLevelIcon(effort) : undefined;\n if (!glyph) return null;\n return (\n <Icon\n icon={glyph}\n className={cn(\n \"size-4 shrink-0\",\n effort ? effortLevelColor(effort) : undefined,\n )}\n />\n );\n}\n\n// Menu rows share one grid: label, hint, and a check that stays in the layout\n// when unselected so the rows do not shift. Short hints (\"3 models\", \"not on\n// Claude\") sit inline on the right; a `stacked` hint — a model id, which is as\n// long as the label and would truncate both — gets its own line underneath.\nfunction itemLabel({\n text,\n hint,\n selected,\n stacked = false,\n}: {\n text: string;\n hint?: string | undefined;\n selected: boolean;\n stacked?: boolean | undefined;\n}): ReactNode {\n return (\n <>\n <span className=\"min-w-0 flex-1\">\n <span className={cn(\"block truncate\", selected && \"font-semibold\")}>\n {text}\n </span>\n {hint && stacked && (\n <span className=\"block truncate font-mono text-[11px] text-muted-foreground\">\n {hint}\n </span>\n )}\n </span>\n {hint && !stacked && (\n <span className=\"shrink-0 text-[11px] text-muted-foreground\">\n {hint}\n </span>\n )}\n <Icon\n icon={UiCheck}\n className={cn(\n \"size-3.5 shrink-0 text-primary\",\n !selected && \"invisible\",\n )}\n />\n </>\n );\n}\n\nfunction familyItems({\n families,\n models,\n selectedId,\n onSelect,\n}: {\n families: SpecRuntimeFamily[];\n models: ChatModel[];\n selectedId: string;\n onSelect: (familyId: string) => void;\n}): DropdownMenuItem[] {\n return families.map((family) => {\n const brand = runtimeFamilyBrand(family);\n const count = modelsForFamily(models, family).length;\n return {\n group: \"Family\",\n label: itemLabel({\n text: family.label,\n ...(count > 0 ? { hint: `${count} models` } : {}),\n selected: family.id === selectedId,\n }),\n ...(brand.icon ? { icon: brand.icon } : {}),\n onSelect: () => onSelect(family.id),\n };\n });\n}\n\nfunction modeItems({\n families,\n family,\n selectedId,\n onSelect,\n}: {\n families: SpecRuntimeFamily[];\n family: SpecRuntimeFamily;\n selectedId: string;\n onSelect: (modeId: string) => void;\n}): DropdownMenuItem[] {\n return runtimeModeOptions(families).map((mode) => {\n const supported = family.modes.find((entry) => entry.id === mode.id);\n const hint = supported?.title ?? unsupportedModeTitle(family);\n return {\n group: \"Mode · runtime\",\n label: itemLabel({\n text: supported?.label ?? mode.label,\n hint,\n selected: mode.id === selectedId,\n }),\n ...(mode.icon ? { icon: mode.icon } : {}),\n title: hint,\n disabled: !supported,\n onSelect: () => onSelect(mode.id),\n };\n });\n}\n\nfunction modelItems({\n models,\n group,\n selectedId,\n onSelect,\n onClear,\n}: {\n models: ChatModel[];\n group: string;\n selectedId?: string | undefined;\n onSelect: (model: ChatModel) => void;\n onClear: () => void;\n}): DropdownMenuItem[] {\n const clear: DropdownMenuItem = {\n group: \"Model\",\n label: itemLabel({\n text: \"Prompt default\",\n hint: \"no override\",\n selected: !selectedId,\n }),\n onSelect: onClear,\n };\n return [\n clear,\n ...models.map((model) => {\n const glyph: StaticIconComponent | undefined = providerIcon(\n model.provider,\n );\n return {\n group,\n label: itemLabel({\n text: model.label,\n ...(model.id === model.label ? {} : { hint: model.id }),\n selected: model.id === selectedId,\n stacked: true,\n }),\n ...(glyph ? { icon: glyph } : {}),\n disabled: model.configured === false,\n onSelect: () => onSelect(model),\n };\n }),\n ];\n}\n\nfunction effortItems({\n offered,\n supported,\n selected,\n onSelect,\n}: {\n offered: string[];\n supported: string[];\n selected?: string | undefined;\n onSelect: (effort: string) => void;\n}): DropdownMenuItem[] {\n const current = selected?.trim() ?? \"\";\n const none: DropdownMenuItem = {\n group: \"Reasoning effort\",\n label: itemLabel({\n text: \"None\",\n hint: \"single pass\",\n selected: current === \"\",\n }),\n onSelect: () => onSelect(\"\"),\n };\n return [\n none,\n ...offered.map((effort) => {\n const glyph = effortLevelIcon(effort);\n const usable = supported.includes(effort);\n return {\n group: \"Reasoning effort\",\n label: itemLabel({\n text: effortLevelLabel(effort),\n ...(usable ? {} : { hint: \"unsupported\" }),\n selected: effort === current,\n }),\n ...(glyph ? { icon: glyph } : {}),\n disabled: !usable,\n onSelect: () => onSelect(effort),\n };\n }),\n ];\n}\n\n// The tiers the menu shows: everything offered by the catalog default, plus any\n// model-specific tier and the current selection, so a value set elsewhere is\n// never silently absent from its own menu.\nfunction effortUniverse(\n offered: readonly string[],\n supported: readonly string[],\n selected: string | undefined,\n): string[] {\n const all = [...offered, ...supported, selected ?? \"\"]\n .map((effort) => effort.trim())\n .filter(Boolean);\n return [...new Set(all)];\n}\n"],"names":["SPEC_RUNTIME_FAMILIES","DEFAULT_REASONING_EFFORTS","selectionForBackend","familyById","firstMode","modelsForFamily","runtimeModelMatches","effortOptionsForModel","backendForFamilyMode","withOptionalRoot","withRoot","modelBelongsToFamily","reconcileModelCapabilities","jsx","RuntimeBarCombo","runtimeFamilyBrand","jsxs","cn","Icon","SpecInput","effortLevelLabel","DropdownMenu","UiChevronDown","effortLevelIcon","effortLevelColor","Fragment","UiCheck","runtimeModeOptions","unsupportedModeTitle","providerIcon"],"mappings":"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"}
@@ -4,6 +4,8 @@ import { SpecRuntimeFamily } from './runtime-mode';
4
4
  export type RuntimeBarProps = {
5
5
  value: AISpecRuntimeValue;
6
6
  onChange: (value: AISpecRuntimeValue) => void;
7
+ /** `segmented` uses field triggers; `combo` uses one direct-edit menu. */
8
+ variant?: "combo" | "segmented";
7
9
  /** Model catalog. Only the selected family's models are listed; a family the
8
10
  * catalog does not describe is served by the segment's free-text entry. */
9
11
  models?: ChatModel[] | undefined;
@@ -13,15 +15,6 @@ export type RuntimeBarProps = {
13
15
  ariaLabel?: string | undefined;
14
16
  className?: string | undefined;
15
17
  };
16
- /**
17
- * The runtime as one self-describing row: family, mode, model and reasoning
18
- * effort as four menu segments in a single bordered bar. Each segment carries
19
- * its own value, so the bar needs no field labels above it and its width tracks
20
- * the content instead of the form grid. Unsupported combinations (a mode the
21
- * family lacks, an effort the model rejects) stay in place and disabled, so the
22
- * constraint reads before it is hit. The Model segment is always present — a
23
- * family with no catalog models is typed into the menu's free-text entry rather
24
- * than pushed out into a separate field.
25
- */
26
- export declare function RuntimeBar({ value, onChange, models, families, reasoningEfforts, ariaLabel, className, }: RuntimeBarProps): import("react/jsx-runtime").JSX.Element;
18
+ /** Self-describing runtime controls with segmented and combo presentations. */
19
+ export declare function RuntimeBar({ value, onChange, variant, models, families, reasoningEfforts, ariaLabel, className, }: RuntimeBarProps): import("react/jsx-runtime").JSX.Element;
27
20
  //# sourceMappingURL=RuntimeBar.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"RuntimeBar.d.ts","sourceRoot":"","sources":["../../../src/data/ai/RuntimeBar.tsx"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAIpE,OAAO,EASL,KAAK,iBAAiB,EACvB,MAAM,gBAAgB,CAAC;AAExB,MAAM,MAAM,eAAe,GAAG;IAC5B,KAAK,EAAE,kBAAkB,CAAC;IAC1B,QAAQ,EAAE,CAAC,KAAK,EAAE,kBAAkB,KAAK,IAAI,CAAC;IAC9C;gFAC4E;IAC5E,MAAM,CAAC,EAAE,SAAS,EAAE,GAAG,SAAS,CAAC;IACjC,QAAQ,CAAC,EAAE,iBAAiB,EAAE,GAAG,SAAS,CAAC;IAC3C,yEAAyE;IACzE,gBAAgB,CAAC,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;IACxC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAChC,CAAC;AAEF;;;;;;;;;GASG;AACH,wBAAgB,UAAU,CAAC,EACzB,KAAK,EACL,QAAQ,EACR,MAAW,EACX,QAAgC,EAChC,gBAA4C,EAC5C,SAAqB,EACrB,SAAS,GACV,EAAE,eAAe,2CAwHjB"}
1
+ {"version":3,"file":"RuntimeBar.d.ts","sourceRoot":"","sources":["../../../src/data/ai/RuntimeBar.tsx"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAG/C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAOpE,OAAO,EAUL,KAAK,iBAAiB,EACvB,MAAM,gBAAgB,CAAC;AAExB,MAAM,MAAM,eAAe,GAAG;IAC5B,KAAK,EAAE,kBAAkB,CAAC;IAC1B,QAAQ,EAAE,CAAC,KAAK,EAAE,kBAAkB,KAAK,IAAI,CAAC;IAC9C,0EAA0E;IAC1E,OAAO,CAAC,EAAE,OAAO,GAAG,WAAW,CAAC;IAChC;gFAC4E;IAC5E,MAAM,CAAC,EAAE,SAAS,EAAE,GAAG,SAAS,CAAC;IACjC,QAAQ,CAAC,EAAE,iBAAiB,EAAE,GAAG,SAAS,CAAC;IAC3C,yEAAyE;IACzE,gBAAgB,CAAC,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;IACxC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAChC,CAAC;AAEF,+EAA+E;AAC/E,wBAAgB,UAAU,CAAC,EACzB,KAAK,EACL,QAAQ,EACR,OAAqB,EACrB,MAAW,EACX,QAAgC,EAChC,gBAA4C,EAC5C,SAAqB,EACrB,SAAS,GACV,EAAE,eAAe,2CAmLjB"}