@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
@@ -1,18 +1,21 @@
1
- import { jsxs, jsx, Fragment } from "react/jsx-runtime";
1
+ import { jsx, jsxs, Fragment } from "react/jsx-runtime";
2
2
  import { cn } from "../../lib/utils.js";
3
3
  import { DropdownMenu } from "../../overlay/DropdownMenu.js";
4
4
  import { Icon } from "../Icon.js";
5
5
  import { effortLevelLabel, DEFAULT_REASONING_EFFORTS, effortLevelIcon, effortLevelColor } from "../chat/effort-icons.js";
6
- import { providerIcon, providerIconColor } from "../chat/provider-icons.js";
6
+ import { providerIcon } from "../chat/provider-icons.js";
7
+ import { runtimeModelMatches, runtimeFamilyBrand } from "./RuntimeBar.model.js";
8
+ import { RuntimeBarCombo } from "./RuntimeBarCombo.js";
7
9
  import { SpecInput } from "./SpecRuntimeEditor/fields.js";
8
10
  import { withOptionalRoot, withRoot } from "./SpecRuntimeEditor/update.js";
9
11
  import { effortOptionsForModel, reconcileModelCapabilities } from "./model-capabilities.js";
10
- import { selectionForBackend, SPEC_RUNTIME_FAMILIES, familyById, firstMode, modelsForFamily, runtimeModeOptions, backendForFamilyMode, modelBelongsToFamily } from "./runtime-mode.js";
12
+ import { selectionForBackend, SPEC_RUNTIME_FAMILIES, familyById, firstMode, modelsForFamily, backendForFamilyMode, modelBelongsToFamily, runtimeModeOptions, unsupportedModeTitle } from "./runtime-mode.js";
11
13
  import { UiChevronDown } from "../../icons/components/UiChevronDown.js";
12
14
  import { UiCheck } from "../../icons/components/UiCheck.js";
13
15
  function RuntimeBar({
14
16
  value,
15
17
  onChange,
18
+ variant = "segmented",
16
19
  models = [],
17
20
  families = SPEC_RUNTIME_FAMILIES,
18
21
  reasoningEfforts = DEFAULT_REASONING_EFFORTS,
@@ -23,19 +26,63 @@ function RuntimeBar({
23
26
  const family = familyById(families, selection.family);
24
27
  const mode = family.modes.find((entry) => entry.id === selection.mode) ?? firstMode(family);
25
28
  const modelOptions = modelsForFamily(models, family, value.backend);
26
- const selectedModel = models.find((entry) => entry.id === value.model);
27
- const supportedEfforts = effortOptionsForModel(selectedModel, reasoningEfforts);
29
+ const selectedModel = models.find(
30
+ (entry) => {
31
+ var _a;
32
+ return ((_a = entry.runtime) == null ? void 0 : _a.backend) === value.backend && runtimeModelMatches(entry, value);
33
+ }
34
+ );
35
+ const resolvedModel = selectedModel ?? models.find((entry) => runtimeModelMatches(entry, value));
36
+ const supportedEfforts = effortOptionsForModel(
37
+ resolvedModel,
38
+ reasoningEfforts
39
+ );
28
40
  const applyBackend = (familyId, modeId) => {
29
41
  const backend = backendForFamilyMode(families, familyId, modeId);
30
42
  if (backend === (value.backend ?? "")) return;
31
- let next = withOptionalRoot(withRoot(value, { backend }), "cliArgs", void 0);
32
- if (!modelBelongsToFamily(value.model, models, familyById(families, familyId), backend)) {
33
- next = withOptionalRoot(next, "model", void 0);
43
+ let next = withOptionalRoot(
44
+ withRoot(value, { backend }),
45
+ "cliArgs",
46
+ void 0
47
+ );
48
+ if (!modelBelongsToFamily(
49
+ value.model,
50
+ models,
51
+ familyById(families, familyId),
52
+ backend
53
+ )) {
54
+ next = withoutCatalogModel(next);
34
55
  }
35
56
  onChange(next);
36
57
  };
37
- const brand = familyBrand(family);
38
- const modelLabel = (selectedModel == null ? void 0 : selectedModel.label) ?? value.model ?? "Default";
58
+ const applyCustomModel = (model) => onChange(withOptionalRoot(withoutCatalogModel(value), "model", model));
59
+ const applyModel = (model) => onChange(reconcileModelCapabilities(value, model, reasoningEfforts));
60
+ const clearModel = () => onChange(withoutCatalogModel(value));
61
+ const applyEffort = (effort) => onChange(withOptionalRoot(value, "effort", effort));
62
+ if (variant === "combo") {
63
+ return /* @__PURE__ */ jsx(
64
+ RuntimeBarCombo,
65
+ {
66
+ value,
67
+ families,
68
+ family,
69
+ mode,
70
+ selectedMode: selection.mode,
71
+ models: modelOptions,
72
+ selectedModel: resolvedModel,
73
+ supportedEfforts,
74
+ ariaLabel,
75
+ className,
76
+ onFamilyChange: (familyId) => applyBackend(familyId, selection.mode),
77
+ onModeChange: (modeId) => applyBackend(family.id, modeId),
78
+ onModelSelect: applyModel,
79
+ onModelClear: clearModel,
80
+ onEffortChange: applyEffort
81
+ }
82
+ );
83
+ }
84
+ const brand = runtimeFamilyBrand(family);
85
+ const modelLabel = (resolvedModel == null ? void 0 : resolvedModel.label) ?? value.model ?? "Default";
39
86
  return /* @__PURE__ */ jsxs(
40
87
  "div",
41
88
  {
@@ -62,7 +109,13 @@ function RuntimeBar({
62
109
  onSelect: (familyId) => applyBackend(familyId, selection.mode)
63
110
  }),
64
111
  children: [
65
- brand.icon && /* @__PURE__ */ jsx(Icon, { icon: brand.icon, className: cn("size-4 shrink-0", brand.color) }),
112
+ brand.icon && /* @__PURE__ */ jsx(
113
+ Icon,
114
+ {
115
+ icon: brand.icon,
116
+ className: cn("size-4 shrink-0", brand.color)
117
+ }
118
+ ),
66
119
  /* @__PURE__ */ jsx("span", { className: CAPTION_CLASS, children: family.label })
67
120
  ]
68
121
  }
@@ -79,7 +132,13 @@ function RuntimeBar({
79
132
  onSelect: (modeId) => applyBackend(family.id, modeId)
80
133
  }),
81
134
  children: [
82
- mode.icon && /* @__PURE__ */ jsx(Icon, { icon: mode.icon, className: "size-4 shrink-0 text-muted-foreground" }),
135
+ mode.icon && /* @__PURE__ */ jsx(
136
+ Icon,
137
+ {
138
+ icon: mode.icon,
139
+ className: "size-4 shrink-0 text-muted-foreground"
140
+ }
141
+ ),
83
142
  /* @__PURE__ */ jsx("span", { className: CAPTION_CLASS, children: mode.label })
84
143
  ]
85
144
  }
@@ -96,7 +155,7 @@ function RuntimeBar({
96
155
  SpecInput,
97
156
  {
98
157
  value: value.model,
99
- onChange: (model) => onChange(withOptionalRoot(value, "model", model)),
158
+ onChange: applyCustomModel,
100
159
  ariaLabel: "Model id",
101
160
  mono: true
102
161
  }
@@ -105,15 +164,9 @@ function RuntimeBar({
105
164
  items: modelItems({
106
165
  models: modelOptions,
107
166
  group: `${family.label} models`,
108
- selectedId: value.model,
109
- onSelect: (model) => onChange(
110
- reconcileModelCapabilities(
111
- value,
112
- models.find((entry) => entry.id === model),
113
- reasoningEfforts
114
- )
115
- ),
116
- onClear: () => onChange(withOptionalRoot(value, "model", void 0))
167
+ selectedId: (resolvedModel == null ? void 0 : resolvedModel.id) ?? value.model,
168
+ onSelect: applyModel,
169
+ onClear: clearModel
117
170
  }),
118
171
  children: /* @__PURE__ */ jsx("span", { className: "min-w-0 truncate font-mono text-xs text-foreground", children: modelLabel })
119
172
  }
@@ -124,10 +177,14 @@ function RuntimeBar({
124
177
  menuLabel: "Reasoning effort",
125
178
  title: "Reasoning effort",
126
179
  items: effortItems({
127
- offered: effortUniverse(reasoningEfforts, supportedEfforts, value.effort),
180
+ offered: effortUniverse(
181
+ reasoningEfforts,
182
+ supportedEfforts,
183
+ value.effort
184
+ ),
128
185
  supported: supportedEfforts,
129
186
  selected: value.effort,
130
- onSelect: (effort) => onChange(withOptionalRoot(value, "effort", effort))
187
+ onSelect: applyEffort
131
188
  }),
132
189
  children: [
133
190
  /* @__PURE__ */ jsx("span", { className: KEY_CLASS, children: "Effort" }),
@@ -140,6 +197,13 @@ function RuntimeBar({
140
197
  }
141
198
  );
142
199
  }
200
+ function withoutCatalogModel(value) {
201
+ return withOptionalRoot(
202
+ withOptionalRoot(value, "model", void 0),
203
+ "id",
204
+ void 0
205
+ );
206
+ }
143
207
  const CAPTION_CLASS = "truncate text-xs font-semibold text-foreground";
144
208
  const KEY_CLASS = "text-[11px] font-semibold uppercase leading-none tracking-wide text-muted-foreground";
145
209
  function RuntimeSegment({
@@ -187,7 +251,10 @@ function EffortGlyph({ effort }) {
187
251
  Icon,
188
252
  {
189
253
  icon: glyph,
190
- className: cn("size-4 shrink-0", effort ? effortLevelColor(effort) : void 0)
254
+ className: cn(
255
+ "size-4 shrink-0",
256
+ effort ? effortLevelColor(effort) : void 0
257
+ )
191
258
  }
192
259
  );
193
260
  }
@@ -207,7 +274,10 @@ function itemLabel({
207
274
  Icon,
208
275
  {
209
276
  icon: UiCheck,
210
- className: cn("size-3.5 shrink-0 text-primary", !selected && "invisible")
277
+ className: cn(
278
+ "size-3.5 shrink-0 text-primary",
279
+ !selected && "invisible"
280
+ )
211
281
  }
212
282
  )
213
283
  ] });
@@ -219,7 +289,7 @@ function familyItems({
219
289
  onSelect
220
290
  }) {
221
291
  return families.map((family) => {
222
- const brand = familyBrand(family);
292
+ const brand = runtimeFamilyBrand(family);
223
293
  const count = modelsForFamily(models, family).length;
224
294
  return {
225
295
  group: "Family",
@@ -233,10 +303,6 @@ function familyItems({
233
303
  };
234
304
  });
235
305
  }
236
- function familyBrand(family) {
237
- const key = providerIcon(family.id) ? family.id : family.provider;
238
- return { icon: providerIcon(key), color: providerIconColor(key) };
239
- }
240
306
  function modeItems({
241
307
  families,
242
308
  family,
@@ -245,7 +311,7 @@ function modeItems({
245
311
  }) {
246
312
  return runtimeModeOptions(families).map((mode) => {
247
313
  const supported = family.modes.find((entry) => entry.id === mode.id);
248
- const hint = (supported == null ? void 0 : supported.title) ?? `not on ${family.label}`;
314
+ const hint = (supported == null ? void 0 : supported.title) ?? unsupportedModeTitle(family);
249
315
  return {
250
316
  group: "Mode · runtime",
251
317
  label: itemLabel({
@@ -279,7 +345,9 @@ function modelItems({
279
345
  return [
280
346
  clear,
281
347
  ...models.map((model) => {
282
- const glyph = providerIcon(model.provider);
348
+ const glyph = providerIcon(
349
+ model.provider
350
+ );
283
351
  return {
284
352
  group,
285
353
  label: itemLabel({
@@ -290,7 +358,7 @@ function modelItems({
290
358
  }),
291
359
  ...glyph ? { icon: glyph } : {},
292
360
  disabled: model.configured === false,
293
- onSelect: () => onSelect(model.id)
361
+ onSelect: () => onSelect(model)
294
362
  };
295
363
  })
296
364
  ];
@@ -304,7 +372,11 @@ function effortItems({
304
372
  const current = (selected == null ? void 0 : selected.trim()) ?? "";
305
373
  const none = {
306
374
  group: "Reasoning effort",
307
- label: itemLabel({ text: "None", hint: "single pass", selected: current === "" }),
375
+ label: itemLabel({
376
+ text: "None",
377
+ hint: "single pass",
378
+ selected: current === ""
379
+ }),
308
380
  onSelect: () => onSelect("")
309
381
  };
310
382
  return [
@@ -1 +1 @@
1
- {"version":3,"file":"RuntimeBar.js","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":[],"mappings":"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"}
1
+ {"version":3,"file":"RuntimeBar.js","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":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const providerIcons = require("../chat/provider-icons.cjs");
4
+ function runtimeFamilyBrand(family) {
5
+ const key = providerIcons.providerIcon(family.id) ? family.id : family.provider;
6
+ return { icon: providerIcons.providerIcon(key), color: providerIcons.providerIconColor(key) };
7
+ }
8
+ function runtimeModelMatches(model, value) {
9
+ var _a, _b;
10
+ return value.id !== void 0 && (model.id === value.id || ((_a = model.runtime) == null ? void 0 : _a.id) === value.id) || value.model !== void 0 && (model.id === value.model || ((_b = model.runtime) == null ? void 0 : _b.model) === value.model);
11
+ }
12
+ exports.runtimeFamilyBrand = runtimeFamilyBrand;
13
+ exports.runtimeModelMatches = runtimeModelMatches;
14
+ //# sourceMappingURL=RuntimeBar.model.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RuntimeBar.model.cjs","sources":["../../../src/data/ai/RuntimeBar.model.ts"],"sourcesContent":["import type { StaticIconComponent } from \"../Icon\";\nimport { providerIcon, providerIconColor } from \"../chat/provider-icons\";\nimport type { ChatModel } from \"../chat/types\";\nimport type { AISpecRuntimeValue } from \"./SpecRuntimeEditor.model\";\nimport type { SpecRuntimeFamily } from \"./runtime-mode\";\n\nexport function runtimeFamilyBrand(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\nexport function runtimeModelMatches(\n model: ChatModel,\n value: AISpecRuntimeValue,\n): boolean {\n return (\n (value.id !== undefined &&\n (model.id === value.id || model.runtime?.id === value.id)) ||\n (value.model !== undefined &&\n (model.id === value.model || model.runtime?.model === value.model))\n );\n}\n"],"names":["providerIcon","providerIconColor"],"mappings":";;;AAMO,SAAS,mBAAmB,QAGjC;AACA,QAAM,MAAMA,cAAAA,aAAa,OAAO,EAAE,IAAI,OAAO,KAAK,OAAO;AACzD,SAAO,EAAE,MAAMA,2BAAa,GAAG,GAAG,OAAOC,cAAAA,kBAAkB,GAAG,EAAA;AAChE;AAEO,SAAS,oBACd,OACA,OACS;;AACT,SACG,MAAM,OAAO,WACX,MAAM,OAAO,MAAM,QAAM,WAAM,YAAN,mBAAe,QAAO,MAAM,OACvD,MAAM,UAAU,WACd,MAAM,OAAO,MAAM,WAAS,WAAM,YAAN,mBAAe,WAAU,MAAM;AAElE;;;"}
@@ -0,0 +1,10 @@
1
+ import { StaticIconComponent } from '../Icon';
2
+ import { ChatModel } from '../chat/types';
3
+ import { AISpecRuntimeValue } from './SpecRuntimeEditor.model';
4
+ import { SpecRuntimeFamily } from './runtime-mode';
5
+ export declare function runtimeFamilyBrand(family: SpecRuntimeFamily): {
6
+ icon: StaticIconComponent | undefined;
7
+ color: string | undefined;
8
+ };
9
+ export declare function runtimeModelMatches(model: ChatModel, value: AISpecRuntimeValue): boolean;
10
+ //# sourceMappingURL=RuntimeBar.model.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RuntimeBar.model.d.ts","sourceRoot":"","sources":["../../../src/data/ai/RuntimeBar.model.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAEnD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AACpE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAExD,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,iBAAiB,GAAG;IAC7D,IAAI,EAAE,mBAAmB,GAAG,SAAS,CAAC;IACtC,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;CAC3B,CAGA;AAED,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,SAAS,EAChB,KAAK,EAAE,kBAAkB,GACxB,OAAO,CAOT"}
@@ -0,0 +1,14 @@
1
+ import { providerIcon, providerIconColor } from "../chat/provider-icons.js";
2
+ function runtimeFamilyBrand(family) {
3
+ const key = providerIcon(family.id) ? family.id : family.provider;
4
+ return { icon: providerIcon(key), color: providerIconColor(key) };
5
+ }
6
+ function runtimeModelMatches(model, value) {
7
+ var _a, _b;
8
+ return value.id !== void 0 && (model.id === value.id || ((_a = model.runtime) == null ? void 0 : _a.id) === value.id) || value.model !== void 0 && (model.id === value.model || ((_b = model.runtime) == null ? void 0 : _b.model) === value.model);
9
+ }
10
+ export {
11
+ runtimeFamilyBrand,
12
+ runtimeModelMatches
13
+ };
14
+ //# sourceMappingURL=RuntimeBar.model.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RuntimeBar.model.js","sources":["../../../src/data/ai/RuntimeBar.model.ts"],"sourcesContent":["import type { StaticIconComponent } from \"../Icon\";\nimport { providerIcon, providerIconColor } from \"../chat/provider-icons\";\nimport type { ChatModel } from \"../chat/types\";\nimport type { AISpecRuntimeValue } from \"./SpecRuntimeEditor.model\";\nimport type { SpecRuntimeFamily } from \"./runtime-mode\";\n\nexport function runtimeFamilyBrand(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\nexport function runtimeModelMatches(\n model: ChatModel,\n value: AISpecRuntimeValue,\n): boolean {\n return (\n (value.id !== undefined &&\n (model.id === value.id || model.runtime?.id === value.id)) ||\n (value.model !== undefined &&\n (model.id === value.model || model.runtime?.model === value.model))\n );\n}\n"],"names":[],"mappings":";AAMO,SAAS,mBAAmB,QAGjC;AACA,QAAM,MAAM,aAAa,OAAO,EAAE,IAAI,OAAO,KAAK,OAAO;AACzD,SAAO,EAAE,MAAM,aAAa,GAAG,GAAG,OAAO,kBAAkB,GAAG,EAAA;AAChE;AAEO,SAAS,oBACd,OACA,OACS;;AACT,SACG,MAAM,OAAO,WACX,MAAM,OAAO,MAAM,QAAM,WAAM,YAAN,mBAAe,QAAO,MAAM,OACvD,MAAM,UAAU,WACd,MAAM,OAAO,MAAM,WAAS,WAAM,YAAN,mBAAe,WAAU,MAAM;AAElE;"}