@neuronection/assistant-ui 0.13.0 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +46 -0
- package/dist/{chunk-LY2B3UJH.js → chunk-OGQF4XJB.js} +3 -3
- package/dist/{chunk-LY2B3UJH.js.map → chunk-OGQF4XJB.js.map} +1 -1
- package/dist/{chunk-YCOMDDJ7.js → chunk-RBEPQY2A.js} +63 -11
- package/dist/chunk-RBEPQY2A.js.map +1 -0
- package/dist/chunk-VULOVVKF.js +188 -0
- package/dist/chunk-VULOVVKF.js.map +1 -0
- package/dist/connection-test-row.js +1 -1
- package/dist/index.js +3 -3
- package/dist/model-registry.d.ts +21 -0
- package/dist/model-registry.js +1 -1
- package/dist/styles.css +1 -1
- package/dist/task-assignment-picker.d.ts +12 -0
- package/dist/task-assignment-picker.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-G2UBF7WF.js +0 -114
- package/dist/chunk-G2UBF7WF.js.map +0 -1
- package/dist/chunk-YCOMDDJ7.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,51 @@
|
|
|
1
1
|
# @neuronection/assistant-ui
|
|
2
2
|
|
|
3
|
+
## 0.14.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [`d94e5a8`](https://github.com/neuronection/assistant-ui/commit/d94e5a82e3ddaa67e7157a8775b42347b2a6ecdb) Thanks [@constLiakos](https://github.com/constLiakos)! - `ModelRegistry` gains an app-supplied extra-field slot and a per-row enable
|
|
8
|
+
toggle. `extraFields` (`{ key, label, placeholder?, multiline? }[]`) renders
|
|
9
|
+
app-declared fields inside the add/edit modal — e.g. health-assistant's model
|
|
10
|
+
description — with the string values carried verbatim on
|
|
11
|
+
`Model.extra`/`Draft.extra`/`Patch.extra` (included in a patch only when the
|
|
12
|
+
user touched a field or the model already carried non-empty values).
|
|
13
|
+
`onToggleEnabled(model, enabled)` renders a native per-row checkbox
|
|
14
|
+
(`Enabled — <id>` accessible name, hidden for read-only providers) so apps can
|
|
15
|
+
persist the model's enabled flag from the row itself. Note: the visual
|
|
16
|
+
baseline for `model-registry--model-registry-story` needs a CI rebaseline.
|
|
17
|
+
|
|
18
|
+
- [`4401664`](https://github.com/neuronection/assistant-ui/commit/4401664b46b0a76a70fbca4711c31f5277913982) Thanks [@constLiakos](https://github.com/constLiakos)! - `TaskAssignmentTask` gains `secondaryOnly` — renders ONLY the fallback picker
|
|
19
|
+
line for that row (Fallback badge + picker + info + clear, no primary line)
|
|
20
|
+
for tasks whose assignment itself is a fallback, e.g. an app's single global
|
|
21
|
+
default model; the value round-trips via `secondaryValue`/`onAssignSecondary`.
|
|
22
|
+
It implies `secondary`, so it works flat or inside a section without the
|
|
23
|
+
section-level flag.
|
|
24
|
+
|
|
25
|
+
### Patch Changes
|
|
26
|
+
|
|
27
|
+
- [`2e1fe5a`](https://github.com/neuronection/assistant-ui/commit/2e1fe5a0383d810cb01ed1d40c13dea30a7b9292) Thanks [@constLiakos](https://github.com/constLiakos)! - `ConnectionTestRow` wraps long error messages (`whitespace-pre-wrap` +
|
|
28
|
+
`break-words` instead of a single clipped line) so full provider API errors —
|
|
29
|
+
e.g. OpenAI's multi-line 400 payloads — stay readable in app cards.
|
|
30
|
+
|
|
31
|
+
- [`6d6d6b4`](https://github.com/neuronection/assistant-ui/commit/6d6d6b4c4b8ea8fc73cfd1ff37956bbbe73e5aa2) Thanks [@constLiakos](https://github.com/constLiakos)! - `ModelRegistry` providers accept a `readOnly` flag: read-only providers render their model rows without the Edit/Remove controls and without the Add-model button — for org-managed providers the current user may not modify.
|
|
32
|
+
|
|
33
|
+
## 0.13.1
|
|
34
|
+
|
|
35
|
+
### Patch Changes
|
|
36
|
+
|
|
37
|
+
- [`aff5f8d`](https://github.com/neuronection/assistant-ui/commit/aff5f8df4834e704a0d329ed621a3fcac6df96ad) Thanks [@constLiakos](https://github.com/constLiakos)! - UX clarity from live testing: `ModelRegistry` gains `capsHint` (muted explainer under the capability chips in the catalog modal), and `TaskAssignmentPicker` renders a visible uppercase fallback marker before the secondary picker so the primary/fallback pair is self-explanatory.
|
|
38
|
+
|
|
39
|
+
- [`aff5f8d`](https://github.com/neuronection/assistant-ui/commit/aff5f8df4834e704a0d329ed621a3fcac6df96ad) Thanks [@constLiakos](https://github.com/constLiakos)! - `TaskAssignmentPicker` marks the primary/fallback pickers with compact badges (`primaryLabel`, default "Primary"; the fallback uses `secondaryLabel`) and optional `primaryInfo`/`fallbackInfo` popups (via the library InfoButton) explaining when each is used.
|
|
40
|
+
|
|
41
|
+
- [`ab46892`](https://github.com/neuronection/assistant-ui/commit/ab468925f37d6bc4a56c91cff4541fab8f8ace22) Thanks [@constLiakos](https://github.com/constLiakos)! - `TaskAssignmentPicker` defaults rows use a column layout: the Primary and Fallback badges act as column headers with their pickers aligned beneath (fixed widths keep the columns stuck across rows); override rows render a single unbadged picker; the task title block can no longer be squeezed out by the action columns.
|
|
42
|
+
|
|
43
|
+
- [`67fed2e`](https://github.com/neuronection/assistant-ui/commit/67fed2ea4a85b96c46cbdf524fcc7590ad7675f8) Thanks [@constLiakos](https://github.com/constLiakos)! - `TaskAssignmentPicker` fallback rows get their own clear button (visible when a fallback is assigned) alongside the primary one — each row's X clears exactly its own assignment.
|
|
44
|
+
|
|
45
|
+
- [`77913e3`](https://github.com/neuronection/assistant-ui/commit/77913e369c260bad9370a1a93376d45efebb3305) Thanks [@constLiakos](https://github.com/constLiakos)! - `TaskAssignmentPicker` info buttons are always visible and their popups open on click only — no hover-triggered description popups while moving across the rows.
|
|
46
|
+
|
|
47
|
+
- [`783ae31`](https://github.com/neuronection/assistant-ui/commit/783ae317463213a084ab95f8d558bf18d5d1af7f) Thanks [@constLiakos](https://github.com/constLiakos)! - `TaskAssignmentPicker` defaults cards stack the pickers in rows instead of columns — the fallback picker sits on the first row, the primary picker (with the assignment clear button) on the second; override rows keep a single unbadged picker row.
|
|
48
|
+
|
|
3
49
|
## 0.13.0
|
|
4
50
|
|
|
5
51
|
### Minor Changes
|
|
@@ -53,7 +53,7 @@ var ConnectionTestRow = React.forwardRef(function ConnectionTestRow2({
|
|
|
53
53
|
latencyLabel
|
|
54
54
|
] }) : null
|
|
55
55
|
] }) : null,
|
|
56
|
-
status === "fail" && errorMessage ? /* @__PURE__ */ jsx("span", { className: "
|
|
56
|
+
status === "fail" && errorMessage ? /* @__PURE__ */ jsx("span", { className: "min-w-0 whitespace-pre-wrap break-words text-xs text-[var(--as-danger)]", children: errorMessage }) : null,
|
|
57
57
|
meta ? /* @__PURE__ */ jsx("span", { className: "text-xs text-[var(--as-muted-fg)]", children: meta }) : null
|
|
58
58
|
] }),
|
|
59
59
|
onTest ? /* @__PURE__ */ jsxs(
|
|
@@ -75,5 +75,5 @@ var ConnectionTestRow = React.forwardRef(function ConnectionTestRow2({
|
|
|
75
75
|
});
|
|
76
76
|
|
|
77
77
|
export { ConnectionTestRow };
|
|
78
|
-
//# sourceMappingURL=chunk-
|
|
79
|
-
//# sourceMappingURL=chunk-
|
|
78
|
+
//# sourceMappingURL=chunk-OGQF4XJB.js.map
|
|
79
|
+
//# sourceMappingURL=chunk-OGQF4XJB.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/connection-test-row/ConnectionTestRow.tsx"],"names":["ConnectionTestRow"],"mappings":";;;;;;AA6BO,IAAM,iBAAA,GAA0B,KAAA,CAAA,UAAA,CAGrC,SAASA,kBAAAA,CACT;AAAA,EACE,MAAA;AAAA,EACA,SAAA;AAAA,EACA,KAAA,GAAQ,YAAA;AAAA,EACR,SAAA,GAAY,MAAA;AAAA,EACZ,OAAA,GAAU,WAAA;AAAA,EACV,SAAA,GAAY,QAAA;AAAA,EACZ,YAAA,GAAe,IAAA;AAAA,EACf,YAAA;AAAA,EACA,MAAA;AAAA,EACA,QAAA,GAAW,KAAA;AAAA,EACX,OAAA,GAAU,KAAA;AAAA,EACV,IAAA;AAAA,EACA;AACF,CAAA,EACA,GAAA,EACA;AACA,EAAA,MAAM,QACJ,MAAA,KAAW,IAAA,GACP,EAAE,IAAA,EAAM,OAAA,EAAS,sBAAM,GAAA,CAAC,KAAA,EAAA,EAAM,SAAA,EAAU,UAAA,EAAW,eAAW,IAAA,EAAC,CAAA,EAAI,MAAM,0BAAA,EAA2B,GACpG,WAAW,MAAA,GACT;AAAA,IACE,IAAA,EAAM,SAAA;AAAA,IACN,sBAAM,GAAA,CAAC,aAAA,EAAA,EAAc,SAAA,EAAU,UAAA,EAAW,eAAW,IAAA,EAAC,CAAA;AAAA,IACtD,IAAA,EAAM;AAAA,GACR,GACA,IAAA;AAER,EAAA,uBACE,IAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,GAAA;AAAA,MACA,SAAA,EAAQ,qBAAA;AAAA,MACR,aAAA,EAAa,MAAA;AAAA,MACb,cAAA,EAAc,OAAA;AAAA,MACd,SAAA,EAAW,EAAA;AAAA,QACT,8EAAA;AAAA,QACA,YAAY,KAAA,IAAS,yDAAA;AAAA,QACrB,YAAY,QAAA,IAAY,WAAA;AAAA,QACxB;AAAA,OACF;AAAA,MAEA,QAAA,EAAA;AAAA,wBAAA,IAAA,CAAC,KAAA,EAAA,EAAI,WAAU,yCAAA,EACb,QAAA,EAAA;AAAA,0BAAA,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,iCAAA,EAAmC,QAAA,EAAA,KAAA,EAAM,CAAA;AAAA,UACxD,WAAW,SAAA,mBACV,IAAA,CAAC,UAAK,SAAA,EAAU,qDAAA,EAAsD,MAAK,QAAA,EACzE,QAAA,EAAA;AAAA,4BAAA,GAAA,CAAC,OAAA,EAAA,EAAQ,MAAK,IAAA,EAAK,CAAA;AAAA,YAClB,SAAA;AAAA,YAAU;AAAA,WAAA,EACb,CAAA,GACE,wBACF,IAAA,CAAC,MAAA,EAAA,EAAK,WAAW,EAAA,CAAG,qCAAA,EAAuC,KAAA,CAAM,IAAI,CAAA,EAClE,QAAA,EAAA;AAAA,YAAA,KAAA,CAAM,IAAA;AAAA,YACN,KAAA,CAAM,IAAA;AAAA,YACN,WAAW,IAAA,IAAQ,SAAA,IAAa,uBAC/B,IAAA,CAAC,MAAA,EAAA,EAAK,WAAU,uCAAA,EAAwC,QAAA,EAAA;AAAA,cAAA,OAAA;AAAA,cACnD,SAAA;AAAA,cACF;AAAA,aAAA,EACH,CAAA,GACE;AAAA,WAAA,EACN,CAAA,GACE,IAAA;AAAA,UACH,MAAA,KAAW,UAAU,YAAA,mBACpB,GAAA,CAAC,UAAK,SAAA,EAAU,
|
|
1
|
+
{"version":3,"sources":["../src/components/connection-test-row/ConnectionTestRow.tsx"],"names":["ConnectionTestRow"],"mappings":"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","file":"chunk-OGQF4XJB.js","sourcesContent":["import * as React from 'react'\nimport { Check, TriangleAlert, X } from 'lucide-react'\nimport { cn } from '../../lib/utils'\nimport { Spinner } from '../spinner/Spinner'\n\nexport type ConnectionTestStatus = 'idle' | 'testing' | 'ok' | 'fail'\n\nexport interface ConnectionTestRowProps {\n status: ConnectionTestStatus\n latencyMs?: number | null\n label?: string\n testLabel?: string\n okLabel?: string\n failLabel?: string\n latencyLabel?: string\n errorMessage?: string | null\n onTest?: () => void\n disabled?: boolean\n /** `row` = standalone bordered row; `inline` = bare, for embedding in app cards. */\n variant?: 'row' | 'inline'\n /** Extra app-side context rendered after the status (e.g. model count). */\n meta?: React.ReactNode\n className?: string\n}\n\n/**\n * Presentational connection-test row (idle/testing/ok/fail + latency).\n * The actual ping is app-side: flip `status` from the test handler.\n */\nexport const ConnectionTestRow = React.forwardRef<\n HTMLDivElement,\n ConnectionTestRowProps\n>(function ConnectionTestRow(\n {\n status,\n latencyMs,\n label = 'Connection',\n testLabel = 'Test',\n okLabel = 'Connected',\n failLabel = 'Failed',\n latencyLabel = 'ms',\n errorMessage,\n onTest,\n disabled = false,\n variant = 'row',\n meta,\n className,\n },\n ref,\n) {\n const state =\n status === 'ok'\n ? { text: okLabel, icon: <Check className=\"size-3.5\" aria-hidden />, tone: 'text-[var(--as-success)]' }\n : status === 'fail'\n ? {\n text: failLabel,\n icon: <TriangleAlert className=\"size-3.5\" aria-hidden />,\n tone: 'text-[var(--as-danger)]',\n }\n : null\n\n return (\n <div\n ref={ref}\n data-as=\"connection-test-row\"\n data-status={status}\n data-variant={variant}\n className={cn(\n 'flex items-center justify-between gap-3 rounded-[var(--as-radius)] px-3 py-2',\n variant === 'row' && 'border border-[var(--as-border)] bg-[var(--as-surface)]',\n variant === 'inline' && 'px-0 py-0',\n className,\n )}\n >\n <div className=\"flex min-w-0 items-center gap-2 text-sm\">\n <span className=\"font-medium text-[var(--as-fg)]\">{label}</span>\n {status === 'testing' ? (\n <span className=\"flex items-center gap-1.5 text-[var(--as-muted-fg)]\" role=\"status\">\n <Spinner size=\"sm\" />\n {testLabel}…\n </span>\n ) : state ? (\n <span className={cn('flex items-center gap-1 font-medium', state.tone)}>\n {state.icon}\n {state.text}\n {status === 'ok' && latencyMs != null ? (\n <span className=\"font-normal text-[var(--as-muted-fg)]\">\n · {latencyMs}\n {latencyLabel}\n </span>\n ) : null}\n </span>\n ) : null}\n {status === 'fail' && errorMessage ? (\n <span className=\"min-w-0 whitespace-pre-wrap break-words text-xs text-[var(--as-danger)]\">\n {errorMessage}\n </span>\n ) : null}\n {meta ? <span className=\"text-xs text-[var(--as-muted-fg)]\">{meta}</span> : null}\n </div>\n {onTest ? (\n <button\n type=\"button\"\n onClick={onTest}\n disabled={disabled || status === 'testing'}\n className=\"shrink-0 cursor-pointer rounded-[var(--as-radius-sm)] border border-[var(--as-border)] px-2.5 py-1 text-xs font-medium text-[var(--as-fg)] transition-colors hover:bg-[var(--as-secondary)] focus-visible:outline-2 focus-visible:outline-offset-1 focus-visible:outline-[var(--as-focus-ring)] disabled:pointer-events-none disabled:opacity-50\"\n >\n {status === 'fail' ? <X className=\"mr-1 inline size-3\" aria-hidden /> : null}\n {testLabel}\n </button>\n ) : null}\n </div>\n )\n})\n"]}
|
|
@@ -92,6 +92,9 @@ var ModelRegistry = React.forwardRef(
|
|
|
92
92
|
onAddAll,
|
|
93
93
|
onUpdateModel,
|
|
94
94
|
onDeleteModel,
|
|
95
|
+
onToggleEnabled,
|
|
96
|
+
enableLabel = "Enabled",
|
|
97
|
+
extraFields,
|
|
95
98
|
reasoningEffortOptions,
|
|
96
99
|
addLabel = "Add model",
|
|
97
100
|
addAllLabel = "Add all",
|
|
@@ -103,6 +106,7 @@ var ModelRegistry = React.forwardRef(
|
|
|
103
106
|
removeLabel = "Remove",
|
|
104
107
|
missingLabel = "Missing",
|
|
105
108
|
capsLabel = "Capabilities",
|
|
109
|
+
capsHint,
|
|
106
110
|
searchPlaceholder = "Search models\u2026",
|
|
107
111
|
searchLabel = "Search models",
|
|
108
112
|
emptyProviderLabel = "No models yet \u2014 use Add model to pick from the live catalog.",
|
|
@@ -146,6 +150,8 @@ var ModelRegistry = React.forwardRef(
|
|
|
146
150
|
reasoningCustom: false,
|
|
147
151
|
temperature: "",
|
|
148
152
|
maxTokens: "",
|
|
153
|
+
extra: {},
|
|
154
|
+
extraTouched: false,
|
|
149
155
|
labelTouched: false,
|
|
150
156
|
manual: false
|
|
151
157
|
});
|
|
@@ -163,11 +169,18 @@ var ModelRegistry = React.forwardRef(
|
|
|
163
169
|
reasoningCustom: model.reasoningEffort != null && model.reasoningEffort !== "" && !(reasoningEffortOptions ?? []).includes(model.reasoningEffort),
|
|
164
170
|
temperature: model.temperature != null ? String(model.temperature) : "",
|
|
165
171
|
maxTokens: model.maxTokens != null ? String(model.maxTokens) : "",
|
|
172
|
+
extra: { ...model.extra ?? {} },
|
|
173
|
+
extraTouched: false,
|
|
166
174
|
model,
|
|
167
175
|
manual: false
|
|
168
176
|
});
|
|
169
177
|
setDraftError(null);
|
|
170
178
|
};
|
|
179
|
+
const patchExtraField = (key, value) => {
|
|
180
|
+
setModal(
|
|
181
|
+
(current) => current ? { ...current, extra: { ...current.extra, [key]: value }, extraTouched: true } : current
|
|
182
|
+
);
|
|
183
|
+
};
|
|
171
184
|
const selectRemote = (remoteId) => {
|
|
172
185
|
const remote = (remoteModels ?? []).find((entry) => entry.id === remoteId);
|
|
173
186
|
setModal(
|
|
@@ -203,13 +216,15 @@ var ModelRegistry = React.forwardRef(
|
|
|
203
216
|
setDraftError(externalIdRequiredLabel);
|
|
204
217
|
return;
|
|
205
218
|
}
|
|
219
|
+
const extra = modal.extraTouched || Object.values(modal.extra).some((value) => value.trim() !== "") ? { ...modal.extra } : void 0;
|
|
206
220
|
const payload = {
|
|
207
221
|
externalId,
|
|
208
222
|
label: modal.label.trim() || void 0,
|
|
209
223
|
caps: modal.caps,
|
|
210
224
|
reasoningEffort: modal.reasoningEffort.trim(),
|
|
211
225
|
temperature: numberOr(modal.temperature),
|
|
212
|
-
maxTokens: numberOr(modal.maxTokens)
|
|
226
|
+
maxTokens: numberOr(modal.maxTokens),
|
|
227
|
+
...extra !== void 0 ? { extra } : {}
|
|
213
228
|
};
|
|
214
229
|
if (modal.mode === "add") {
|
|
215
230
|
onAddModel(modal.providerId, payload);
|
|
@@ -331,7 +346,8 @@ var ModelRegistry = React.forwardRef(
|
|
|
331
346
|
onToggle: toggleDraftCap,
|
|
332
347
|
ariaLabel: capsLabel
|
|
333
348
|
}
|
|
334
|
-
)
|
|
349
|
+
),
|
|
350
|
+
capsHint ? /* @__PURE__ */ jsx("p", { className: "text-xs text-[var(--as-muted-fg)]", children: capsHint }) : null
|
|
335
351
|
] }),
|
|
336
352
|
reasoningEffortOptions ? /* @__PURE__ */ jsxs("label", { className: "block space-y-1 text-sm", children: [
|
|
337
353
|
/* @__PURE__ */ jsx("span", { className: "text-sm font-medium text-[var(--as-fg)]", children: reasoningEffortLabel }),
|
|
@@ -389,6 +405,32 @@ var ModelRegistry = React.forwardRef(
|
|
|
389
405
|
}
|
|
390
406
|
)
|
|
391
407
|
] }),
|
|
408
|
+
(extraFields ?? []).map((field) => {
|
|
409
|
+
const value = modal.extra[field.key] ?? "";
|
|
410
|
+
const common = "w-full rounded-[var(--as-radius)] border border-[var(--as-border)] bg-[var(--as-surface)] px-3 py-2 text-sm text-[var(--as-fg)]";
|
|
411
|
+
return /* @__PURE__ */ jsxs("label", { className: "block space-y-1 text-sm", children: [
|
|
412
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm font-medium text-[var(--as-fg)]", children: field.label }),
|
|
413
|
+
field.multiline ? /* @__PURE__ */ jsx(
|
|
414
|
+
"textarea",
|
|
415
|
+
{
|
|
416
|
+
rows: 2,
|
|
417
|
+
value,
|
|
418
|
+
placeholder: field.placeholder,
|
|
419
|
+
onChange: (event) => patchExtraField(field.key, event.target.value),
|
|
420
|
+
className: common
|
|
421
|
+
}
|
|
422
|
+
) : /* @__PURE__ */ jsx(
|
|
423
|
+
"input",
|
|
424
|
+
{
|
|
425
|
+
type: "text",
|
|
426
|
+
value,
|
|
427
|
+
placeholder: field.placeholder,
|
|
428
|
+
onChange: (event) => patchExtraField(field.key, event.target.value),
|
|
429
|
+
className: common
|
|
430
|
+
}
|
|
431
|
+
)
|
|
432
|
+
] }, field.key);
|
|
433
|
+
}),
|
|
392
434
|
draftError ? /* @__PURE__ */ jsx("p", { role: "alert", className: "text-xs text-[var(--as-danger)]", children: draftError }) : null
|
|
393
435
|
] }),
|
|
394
436
|
/* @__PURE__ */ jsxs(ModalFooter, { children: [
|
|
@@ -485,7 +527,7 @@ var ModelRegistry = React.forwardRef(
|
|
|
485
527
|
}
|
|
486
528
|
),
|
|
487
529
|
expanded ? /* @__PURE__ */ jsxs("div", { className: "as-anim-fade flex flex-col gap-2 border-t border-[var(--as-border)] p-4", children: [
|
|
488
|
-
providerModels.length === 0 ? /* @__PURE__ */ jsx("p", { className: "text-xs text-[var(--as-muted-fg)]", children: emptyProviderLabel }) : null,
|
|
530
|
+
!provider.readOnly && providerModels.length === 0 ? /* @__PURE__ */ jsx("p", { className: "text-xs text-[var(--as-muted-fg)]", children: emptyProviderLabel }) : null,
|
|
489
531
|
providerModels.map((model) => {
|
|
490
532
|
return /* @__PURE__ */ jsxs(
|
|
491
533
|
"div",
|
|
@@ -495,6 +537,16 @@ var ModelRegistry = React.forwardRef(
|
|
|
495
537
|
model.missing && "opacity-50"
|
|
496
538
|
),
|
|
497
539
|
children: [
|
|
540
|
+
onToggleEnabled && !provider.readOnly ? /* @__PURE__ */ jsx(
|
|
541
|
+
"input",
|
|
542
|
+
{
|
|
543
|
+
type: "checkbox",
|
|
544
|
+
"aria-label": `${enableLabel} \u2014 ${model.externalId}`,
|
|
545
|
+
checked: model.enabled,
|
|
546
|
+
onChange: (event) => onToggleEnabled(model, event.target.checked),
|
|
547
|
+
className: "size-4 shrink-0 cursor-pointer accent-[var(--as-primary)]"
|
|
548
|
+
}
|
|
549
|
+
) : null,
|
|
498
550
|
/* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate font-mono text-xs text-[var(--as-fg)]", children: model.externalId }),
|
|
499
551
|
model.missing ? /* @__PURE__ */ jsx("span", { className: "text-xs text-[var(--as-warning)]", children: missingLabel }) : null,
|
|
500
552
|
/* @__PURE__ */ jsx(
|
|
@@ -505,7 +557,7 @@ var ModelRegistry = React.forwardRef(
|
|
|
505
557
|
selected: model.caps
|
|
506
558
|
}
|
|
507
559
|
),
|
|
508
|
-
/* @__PURE__ */ jsxs(
|
|
560
|
+
!provider.readOnly ? /* @__PURE__ */ jsxs(
|
|
509
561
|
Button,
|
|
510
562
|
{
|
|
511
563
|
variant: "outline",
|
|
@@ -517,8 +569,8 @@ var ModelRegistry = React.forwardRef(
|
|
|
517
569
|
editLabel
|
|
518
570
|
]
|
|
519
571
|
}
|
|
520
|
-
),
|
|
521
|
-
/* @__PURE__ */ jsx(
|
|
572
|
+
) : null,
|
|
573
|
+
!provider.readOnly ? /* @__PURE__ */ jsx(
|
|
522
574
|
"button",
|
|
523
575
|
{
|
|
524
576
|
type: "button",
|
|
@@ -527,13 +579,13 @@ var ModelRegistry = React.forwardRef(
|
|
|
527
579
|
className: "cursor-pointer rounded-[var(--as-radius-sm)] p-1.5 text-[var(--as-muted-fg)] transition-colors hover:bg-[var(--as-muted)] hover:text-[var(--as-fg)] focus-visible:outline-2 focus-visible:outline-offset-1 focus-visible:outline-[var(--as-focus-ring)]",
|
|
528
580
|
children: /* @__PURE__ */ jsx(X, { className: "size-4", "aria-hidden": true })
|
|
529
581
|
}
|
|
530
|
-
)
|
|
582
|
+
) : null
|
|
531
583
|
]
|
|
532
584
|
},
|
|
533
585
|
model.id
|
|
534
586
|
);
|
|
535
587
|
}),
|
|
536
|
-
/* @__PURE__ */ jsx("div", { className: "pt-1", children: /* @__PURE__ */ jsxs(
|
|
588
|
+
!provider.readOnly ? /* @__PURE__ */ jsx("div", { className: "pt-1", children: /* @__PURE__ */ jsxs(
|
|
537
589
|
Button,
|
|
538
590
|
{
|
|
539
591
|
variant: "outline",
|
|
@@ -545,7 +597,7 @@ var ModelRegistry = React.forwardRef(
|
|
|
545
597
|
addLabel
|
|
546
598
|
]
|
|
547
599
|
}
|
|
548
|
-
) })
|
|
600
|
+
) }) : null
|
|
549
601
|
] }) : null
|
|
550
602
|
]
|
|
551
603
|
},
|
|
@@ -564,5 +616,5 @@ var ModelRegistry = React.forwardRef(
|
|
|
564
616
|
);
|
|
565
617
|
|
|
566
618
|
export { ModelRegistry };
|
|
567
|
-
//# sourceMappingURL=chunk-
|
|
568
|
-
//# sourceMappingURL=chunk-
|
|
619
|
+
//# sourceMappingURL=chunk-RBEPQY2A.js.map
|
|
620
|
+
//# sourceMappingURL=chunk-RBEPQY2A.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/model-registry/ModelRegistry.tsx"],"names":["ModelRegistry"],"mappings":"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","file":"chunk-RBEPQY2A.js","sourcesContent":["import * as React from 'react'\nimport { Check, ChevronDown, ChevronRight, ChevronUp, Pencil, Plus, X } from 'lucide-react'\nimport { cn } from '../../lib/utils'\nimport { Button } from '../button'\nimport { CapabilityChips, type CapabilityDescriptor } from '../capability-chips'\nimport { Modal, ModalContent, ModalHeader, ModalTitle, ModalFooter } from '../modal/Modal'\nimport { ModelPicker, type ModelPickerProvider } from '../model-picker/ModelPicker'\nimport { Spinner } from '../spinner'\nimport { beautifyId } from '../../lib/fuzzy'\n\nexport interface ModelRegistryProvider {\n id: string\n name: string\n type?: string\n baseUrl?: string\n /** Read-only provider: hides Add/Edit/Remove (e.g. org-managed providers). */\n readOnly?: boolean\n}\n\nexport interface ModelRegistryModel {\n id: string\n providerId: string\n externalId: string\n label?: string\n caps: string[]\n enabled: boolean\n reasoningEffort?: string\n temperature?: number | null\n maxTokens?: number | null\n /** App-defined extra fields (see `extraFields`), carried verbatim. */\n extra?: Record<string, string>\n missing?: boolean\n}\n\nexport interface ModelRegistryRemoteModel {\n id: string\n caps: string[]\n}\n\nexport interface ModelRegistryDraft {\n externalId: string\n label?: string\n caps: string[]\n reasoningEffort?: string\n temperature?: number | null\n maxTokens?: number | null\n extra?: Record<string, string>\n}\n\nexport interface ModelRegistryPatch {\n label?: string\n caps?: string[]\n reasoningEffort?: string\n temperature?: number | null\n maxTokens?: number | null\n extra?: Record<string, string>\n}\n\nexport interface ModelRegistryExtraField {\n key: string\n label: string\n placeholder?: string\n /** Render a multi-line textarea instead of a single-line input. */\n multiline?: boolean\n}\n\nexport type ModelRegistryRemoteState = 'loading' | 'error' | 'ready'\n\nexport interface ModelRegistryProps {\n providers: ModelRegistryProvider[]\n models: ModelRegistryModel[]\n caps: CapabilityDescriptor[]\n expandedProviderId?: string | null\n onExpandedProviderChange: (providerId: string | null) => void\n remoteModels?: ModelRegistryRemoteModel[]\n remoteState?: ModelRegistryRemoteState\n remoteError?: string | null\n onRetryRemote?: () => void\n onAddModel: (providerId: string, draft: ModelRegistryDraft) => void\n onAddAll?: (providerId: string, drafts: ModelRegistryDraft[]) => void\n onUpdateModel: (model: ModelRegistryModel, patch: ModelRegistryPatch) => void\n onDeleteModel: (model: ModelRegistryModel) => void\n /** Toggle a model's enabled flag; renders the row checkbox when set. */\n onToggleEnabled?: (model: ModelRegistryModel, enabled: boolean) => void\n enableLabel?: string\n /** App-declared extra fields rendered in the add/edit modal (e.g. a\n * description line); values ride `extra` on Draft/Patch/Model. */\n extraFields?: ModelRegistryExtraField[]\n reasoningEffortOptions?: string[]\n addLabel?: string\n addAllLabel?: string\n addTitle?: string\n editTitle?: string\n selectModelLabel?: string\n manualIdToggleLabel?: string\n editLabel?: string\n removeLabel?: string\n missingLabel?: string\n capsLabel?: string\n /** Muted explainer under the capability chips (what they gate). */\n capsHint?: string\n searchPlaceholder?: string\n searchLabel?: string\n emptyProviderLabel?: string\n externalIdRequiredLabel?: string\n remoteEmptyLabel?: string\n remoteLoadingLabel?: string\n retryLabel?: string\n customOptionLabel?: string\n temperatureLabel?: string\n maxTokensLabel?: string\n labelLabel?: string\n reasoningEffortLabel?: string\n saveLabel?: string\n cancelLabel?: string\n addDraftLabel?: string\n providersEmptyLabel?: string\n emptyAction?: React.ReactNode\n className?: string\n}\n\nconst CUSTOM = '__custom__'\ninterface NumberFieldProps {\n label: string\n value: string\n onChange: (value: string) => void\n onClear: () => void\n step?: string\n min?: string\n max?: string\n}\n\nfunction NumberField({\n label,\n value,\n onChange,\n onClear,\n step = '1',\n min,\n max,\n}: NumberFieldProps) {\n const bump = (delta: number) => {\n const current = value.trim() === '' ? 0 : Number(value)\n if (!Number.isFinite(current)) return\n const next = current + delta\n onChange(String(min != null && next < Number(min) ? Number(min) : next))\n }\n return (\n <label className=\"block space-y-1 text-sm\">\n <span className=\"text-sm font-medium text-[var(--as-fg)]\">{label}</span>\n <span className=\"relative block\">\n <input\n type=\"number\"\n step={step}\n min={min}\n max={max}\n value={value}\n onChange={(event) => onChange(event.target.value)}\n className=\"w-full rounded-[var(--as-radius)] border border-[var(--as-border)] bg-[var(--as-surface)] px-3 py-2 pr-16 text-sm text-[var(--as-fg)] [appearance:textfield] [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:appearance-none\"\n />\n <span className=\"absolute inset-y-0 right-1.5 flex items-center gap-1\">\n {value !== '' ? (\n <button\n type=\"button\"\n aria-label={`${label} clear`}\n onClick={onClear}\n className=\"cursor-pointer text-[var(--as-muted-fg)] hover:text-[var(--as-fg)]\"\n >\n <X className=\"size-4\" aria-hidden />\n </button>\n ) : null}\n <span className=\"flex flex-col\">\n <button\n type=\"button\"\n aria-label={`${label} increment`}\n onClick={() => bump(Number(step))}\n className=\"cursor-pointer leading-none text-[var(--as-muted-fg)] hover:text-[var(--as-fg)]\"\n >\n <ChevronUp className=\"size-3.5\" aria-hidden />\n </button>\n <button\n type=\"button\"\n aria-label={`${label} decrement`}\n onClick={() => bump(-Number(step))}\n className=\"cursor-pointer leading-none text-[var(--as-muted-fg)] hover:text-[var(--as-fg)]\"\n >\n <ChevronDown className=\"size-3.5\" aria-hidden />\n </button>\n </span>\n </span>\n </span>\n </label>\n )\n}\n\ninterface ModalState {\n mode: 'add' | 'edit'\n providerId: string\n externalId: string\n label: string\n caps: string[]\n reasoningEffort: string\n reasoningCustom: boolean\n temperature: string\n maxTokens: string\n extra: Record<string, string>\n extraTouched: boolean\n labelTouched: boolean\n model?: ModelRegistryModel\n manual: boolean\n}\n\nexport const ModelRegistry = React.forwardRef<HTMLDivElement, ModelRegistryProps>(\n function ModelRegistry(\n {\n providers,\n models,\n caps,\n expandedProviderId,\n onExpandedProviderChange,\n remoteModels,\n remoteState = 'ready',\n remoteError,\n onRetryRemote,\n onAddModel,\n onAddAll,\n onUpdateModel,\n onDeleteModel,\n onToggleEnabled,\n enableLabel = 'Enabled',\n extraFields,\n reasoningEffortOptions,\n addLabel = 'Add model',\n addAllLabel = 'Add all',\n addTitle = 'Add model',\n editTitle = 'Edit model',\n selectModelLabel = 'Model',\n manualIdToggleLabel = 'Enter the model id manually',\n editLabel = 'Edit',\n removeLabel = 'Remove',\n missingLabel = 'Missing',\n capsLabel = 'Capabilities',\n capsHint,\n searchPlaceholder = 'Search models…',\n searchLabel = 'Search models',\n emptyProviderLabel = 'No models yet — use Add model to pick from the live catalog.',\n externalIdRequiredLabel = 'The model id is required.',\n remoteEmptyLabel = 'The provider listed no models.',\n remoteLoadingLabel = 'Loading models…',\n retryLabel = 'Retry',\n customOptionLabel = 'Custom…',\n temperatureLabel = 'Temperature',\n maxTokensLabel = 'Max tokens',\n labelLabel = 'Display label',\n reasoningEffortLabel = 'Reasoning effort',\n saveLabel = 'Save',\n cancelLabel = 'Cancel',\n addDraftLabel = 'Add model',\n providersEmptyLabel = 'No providers yet.',\n emptyAction,\n className,\n },\n ref,\n ) {\n const [modal, setModal] = React.useState<ModalState | null>(null)\n const [draftError, setDraftError] = React.useState<string | null>(null)\n\n const descriptorFor = React.useCallback(\n (value: string): CapabilityDescriptor =>\n caps.find((cap) => cap.value === value) ?? { value, label: value },\n [caps],\n )\n\n const resetModal = React.useCallback(() => {\n setModal(null)\n setDraftError(null)\n }, [])\n\n const toggleProvider = (providerId: string) => {\n onExpandedProviderChange(expandedProviderId === providerId ? null : providerId)\n }\n\n const openAddModal = (providerId: string) => {\n setModal({\n mode: 'add',\n providerId,\n externalId: '',\n label: '',\n caps: caps[0] ? [caps[0].value] : [],\n reasoningEffort: '',\n reasoningCustom: false,\n temperature: '',\n maxTokens: '',\n extra: {},\n extraTouched: false,\n labelTouched: false,\n manual: false,\n })\n setDraftError(null)\n }\n\n const openEditModal = (model: ModelRegistryModel) => {\n setModal({\n mode: 'edit',\n providerId: model.providerId,\n externalId: model.externalId,\n label: model.label ?? '',\n caps: [...model.caps],\n labelTouched: true,\n reasoningEffort: model.reasoningEffort ?? '',\n reasoningCustom:\n model.reasoningEffort != null &&\n model.reasoningEffort !== '' &&\n !(reasoningEffortOptions ?? []).includes(model.reasoningEffort),\n temperature: model.temperature != null ? String(model.temperature) : '',\n maxTokens: model.maxTokens != null ? String(model.maxTokens) : '',\n extra: { ...(model.extra ?? {}) },\n extraTouched: false,\n model,\n manual: false,\n })\n setDraftError(null)\n }\n\n const patchExtraField = (key: string, value: string) => {\n setModal((current) =>\n current\n ? { ...current, extra: { ...current.extra, [key]: value }, extraTouched: true }\n : current,\n )\n }\n\n const selectRemote = (remoteId: string) => {\n const remote = (remoteModels ?? []).find((entry) => entry.id === remoteId)\n setModal((current) =>\n current\n ? {\n ...current,\n externalId: remoteId,\n caps: remote ? [...remote.caps] : current.caps,\n label: current.labelTouched ? current.label : beautifyId(remoteId),\n }\n : current,\n )\n }\n\n const toggleDraftCap = (value: string) => {\n setModal((current) =>\n current\n ? {\n ...current,\n caps: current.caps.includes(value)\n ? current.caps.filter((entry) => entry !== value)\n : [...current.caps, value],\n }\n : current,\n )\n }\n\n const patchField = (field: keyof ModalState, value: string) => {\n setModal((current) => (current ? { ...current, [field]: value } : current))\n }\n\n const numberOr = (raw: string): number | null => {\n const trimmed = raw.trim()\n if (!trimmed) return null\n const parsed = Number(trimmed)\n return Number.isFinite(parsed) ? parsed : null\n }\n\n const submitModal = () => {\n if (!modal) return\n const externalId = modal.externalId.trim()\n if (!externalId) {\n setDraftError(externalIdRequiredLabel)\n return\n }\n const extra: Record<string, string> | undefined =\n modal.extraTouched || Object.values(modal.extra).some((value) => value.trim() !== '')\n ? { ...modal.extra }\n : undefined\n const payload: ModelRegistryDraft = {\n externalId,\n label: modal.label.trim() || undefined,\n caps: modal.caps,\n reasoningEffort: modal.reasoningEffort.trim(),\n temperature: numberOr(modal.temperature),\n maxTokens: numberOr(modal.maxTokens),\n ...(extra !== undefined ? { extra } : {}),\n }\n if (modal.mode === 'add') {\n onAddModel(modal.providerId, payload)\n } else if (modal.model) {\n onUpdateModel(modal.model, payload)\n }\n resetModal()\n }\n\n const remoteForProvider = (provider: ModelRegistryProvider): ModelPickerProvider[] => {\n const items = remoteModels ?? []\n if (items.length === 0) return []\n return [\n {\n id: provider.id,\n name: provider.name,\n models: items.map((entry) => ({\n id: entry.id,\n name: entry.id,\n capabilities: entry.caps,\n })),\n },\n ]\n }\n\n const renderModal = () => {\n if (!modal) return null\n const provider = providers.find((entry) => entry.id === modal.providerId)\n const catalog = provider ? remoteForProvider(provider) : []\n const pendingCount = (remoteModels ?? []).filter(\n (remote) =>\n !models.some(\n (model) => model.providerId === modal.providerId && model.externalId === remote.id,\n ),\n ).length\n return (\n <Modal open onOpenChange={(open: boolean) => (!open ? resetModal() : undefined)}>\n <ModalContent className=\"max-h-[85vh] w-full max-w-lg overflow-y-auto\">\n <ModalHeader>\n <ModalTitle className=\"text-base\">\n {modal.mode === 'add' ? addTitle : `${editTitle} — ${modal.externalId}`}\n </ModalTitle>\n </ModalHeader>\n <div className=\"flex flex-col gap-4 p-4\">\n {modal.mode === 'add' ? (\n remoteState === 'loading' ? (\n <p className=\"flex items-center justify-center gap-2 py-4 text-xs text-[var(--as-muted-fg)]\">\n <Spinner size=\"sm\" />\n {remoteLoadingLabel}\n </p>\n ) : remoteState === 'error' ? (\n <>\n <div className=\"flex items-center justify-between gap-2\">\n <p className=\"truncate text-xs text-[var(--as-danger)]\">{remoteError}</p>\n {onRetryRemote ? (\n <Button variant=\"outline\" size=\"sm\" onClick={onRetryRemote}>\n {retryLabel}\n </Button>\n ) : null}\n </div>\n {modal.manual ? (\n <label className=\"block space-y-1 text-sm\">\n <span className=\"text-sm font-medium text-[var(--as-fg)]\">\n {selectModelLabel}\n </span>\n <input\n type=\"text\"\n value={modal.externalId}\n onChange={(event) => patchField('externalId', event.target.value)}\n className=\"w-full rounded-[var(--as-radius)] border border-[var(--as-border)] bg-[var(--as-surface)] px-3 py-2 font-mono text-sm text-[var(--as-fg)]\"\n />\n </label>\n ) : (\n <button\n type=\"button\"\n className=\"cursor-pointer self-start text-xs text-[var(--as-muted-fg)] underline-offset-2 hover:text-[var(--as-fg)] hover:underline\"\n onClick={() => setModal((c) => (c ? { ...c, manual: true } : c))}\n >\n {manualIdToggleLabel}\n </button>\n )}\n </>\n ) : (\n <>\n {modal.manual ? (\n <label className=\"block space-y-1 text-sm\">\n <span className=\"text-sm font-medium text-[var(--as-fg)]\">\n {selectModelLabel}\n </span>\n <input\n type=\"text\"\n value={modal.externalId}\n onChange={(event) => patchField('externalId', event.target.value)}\n className=\"w-full rounded-[var(--as-radius)] border border-[var(--as-border)] bg-[var(--as-surface)] px-3 py-2 font-mono text-sm text-[var(--as-fg)]\"\n />\n </label>\n ) : (\n <ModelPicker\n providers={catalog}\n value={modal.externalId}\n onChange={(modelId) => (modelId ? selectRemote(modelId) : undefined)}\n label={selectModelLabel}\n searchPlaceholder={searchPlaceholder}\n searchLabel={searchLabel}\n emptyLabel={remoteEmptyLabel}\n />\n )}\n <button\n type=\"button\"\n className=\"cursor-pointer self-start text-xs text-[var(--as-muted-fg)] underline-offset-2 hover:text-[var(--as-fg)] hover:underline\"\n onClick={() => setModal((c) => (c ? { ...c, manual: !c.manual } : c))}\n >\n {manualIdToggleLabel}\n </button>\n </>\n )\n ) : (\n <p className=\"font-mono text-sm text-[var(--as-fg)]\">{modal.externalId}</p>\n )}\n <label className=\"block space-y-1 text-sm\">\n <span className=\"text-sm font-medium text-[var(--as-fg)]\">{labelLabel}</span>\n <input\n type=\"text\"\n value={modal.label}\n onChange={(event) =>\n setModal((current) =>\n current\n ? { ...current, label: event.target.value, labelTouched: true }\n : current,\n )\n }\n className=\"w-full rounded-[var(--as-radius)] border border-[var(--as-border)] bg-[var(--as-surface)] px-3 py-2 text-sm text-[var(--as-fg)]\"\n />\n </label>\n <div className=\"space-y-1\">\n <span className=\"text-sm font-medium text-[var(--as-fg)]\">{capsLabel}</span>\n <CapabilityChips\n caps={caps}\n selected={modal.caps}\n onToggle={toggleDraftCap}\n ariaLabel={capsLabel}\n />\n {capsHint ? (\n <p className=\"text-xs text-[var(--as-muted-fg)]\">{capsHint}</p>\n ) : null}\n </div>\n {reasoningEffortOptions ? (\n <label className=\"block space-y-1 text-sm\">\n <span className=\"text-sm font-medium text-[var(--as-fg)]\">\n {reasoningEffortLabel}\n </span>\n <div className=\"flex flex-col gap-2 sm:flex-row\">\n {modal.reasoningCustom ? (\n <input\n type=\"text\"\n value={modal.reasoningEffort}\n placeholder={customOptionLabel}\n onChange={(event) => patchField('reasoningEffort', event.target.value)}\n className=\"w-full rounded-[var(--as-radius)] border border-[var(--as-border)] bg-[var(--as-surface)] px-3 py-2 font-mono text-sm text-[var(--as-fg)] sm:flex-1\"\n />\n ) : (\n <select\n value={modal.reasoningCustom ? CUSTOM : modal.reasoningEffort}\n onChange={(event) =>\n setModal((current) =>\n current\n ? {\n ...current,\n reasoningCustom: event.target.value === CUSTOM,\n reasoningEffort:\n event.target.value === CUSTOM\n ? current.reasoningEffort\n : event.target.value,\n }\n : current,\n )\n }\n className=\"w-full rounded-[var(--as-radius)] border border-[var(--as-border)] bg-[var(--as-surface)] px-3 py-2 text-sm text-[var(--as-fg)] sm:w-40\"\n >\n <option value=\"\">—</option>\n {reasoningEffortOptions.map((option) => (\n <option key={option} value={option}>\n {option}\n </option>\n ))}\n <option value={CUSTOM}>{customOptionLabel}</option>\n </select>\n )}\n </div>\n </label>\n ) : null}\n <div className=\"grid grid-cols-1 gap-3 sm:grid-cols-2\">\n <NumberField\n label={temperatureLabel}\n value={modal.temperature}\n onChange={(value) => patchField('temperature', value)}\n onClear={() => patchField('temperature', '')}\n step=\"0.1\"\n min=\"0\"\n max=\"2\"\n />\n <NumberField\n label={maxTokensLabel}\n value={modal.maxTokens}\n onChange={(value) => patchField('maxTokens', value)}\n onClear={() => patchField('maxTokens', '')}\n step=\"256\"\n min=\"1\"\n />\n </div>\n {(extraFields ?? []).map((field) => {\n const value = modal.extra[field.key] ?? ''\n const common =\n 'w-full rounded-[var(--as-radius)] border border-[var(--as-border)] bg-[var(--as-surface)] px-3 py-2 text-sm text-[var(--as-fg)]'\n return (\n <label key={field.key} className=\"block space-y-1 text-sm\">\n <span className=\"text-sm font-medium text-[var(--as-fg)]\">{field.label}</span>\n {field.multiline ? (\n <textarea\n rows={2}\n value={value}\n placeholder={field.placeholder}\n onChange={(event) => patchExtraField(field.key, event.target.value)}\n className={common}\n />\n ) : (\n <input\n type=\"text\"\n value={value}\n placeholder={field.placeholder}\n onChange={(event) => patchExtraField(field.key, event.target.value)}\n className={common}\n />\n )}\n </label>\n )\n })}\n {draftError ? (\n <p role=\"alert\" className=\"text-xs text-[var(--as-danger)]\">\n {draftError}\n </p>\n ) : null}\n </div>\n <ModalFooter>\n {modal.mode === 'add' && onAddAll ? (\n <Button\n variant=\"outline\"\n size=\"sm\"\n disabled={remoteState !== 'ready' || pendingCount === 0}\n onClick={() => {\n onAddAll(\n modal.providerId,\n (remoteModels ?? [])\n .filter(\n (remote) =>\n !models.some(\n (model) =>\n model.providerId === modal.providerId &&\n model.externalId === remote.id,\n ),\n )\n .map((remote) => ({\n externalId: remote.id,\n caps: remote.caps,\n reasoningEffort: '',\n temperature: null,\n maxTokens: null,\n })),\n )\n resetModal()\n }}\n >\n <Plus aria-hidden />\n {addAllLabel} ({pendingCount})\n </Button>\n ) : null}\n <Button variant=\"ghost\" size=\"sm\" onClick={resetModal}>\n {cancelLabel}\n </Button>\n <Button size=\"sm\" onClick={submitModal}>\n <Check aria-hidden />\n {modal.mode === 'add' ? addDraftLabel : saveLabel}\n </Button>\n </ModalFooter>\n </ModalContent>\n </Modal>\n )\n }\n\n return (\n <div\n ref={ref}\n data-as=\"model-registry\"\n className={cn('flex w-full flex-col gap-4', className)}\n >\n {providers.map((provider) => {\n const expanded = expandedProviderId === provider.id\n const providerModels = models.filter((model) => model.providerId === provider.id)\n return (\n <div\n key={provider.id}\n data-as=\"model-registry-provider\"\n className={cn(\n 'rounded-[var(--as-radius-lg)] border bg-[var(--as-surface)] transition-all',\n expanded\n ? 'border-[var(--as-primary)] shadow-[var(--as-shadow-1)]'\n : 'border-[var(--as-border)]',\n )}\n >\n <button\n type=\"button\"\n aria-expanded={expanded}\n onClick={() => toggleProvider(provider.id)}\n className=\"group flex w-full cursor-pointer items-center gap-4 p-4 text-left focus-visible:outline-2 focus-visible:outline-offset-1 focus-visible:outline-[var(--as-focus-ring)]\"\n >\n <span\n className={cn(\n 'flex size-9 shrink-0 items-center justify-center rounded-[var(--as-radius)] transition-colors',\n expanded\n ? 'bg-[var(--as-primary)] text-[var(--as-primary-fg)]'\n : 'bg-[var(--as-muted)] text-[var(--as-muted-fg)] group-hover:bg-[var(--as-primary)]/10 group-hover:text-[var(--as-primary)]',\n )}\n >\n {expanded ? (\n <ChevronDown className=\"size-5\" aria-hidden />\n ) : (\n <ChevronRight className=\"size-5\" aria-hidden />\n )}\n </span>\n <span className=\"min-w-0 flex-1\">\n <span className=\"flex flex-wrap items-center gap-2 text-sm font-semibold text-[var(--as-fg)]\">\n {provider.name}\n {provider.type ? (\n <span className=\"rounded-full border border-[var(--as-border)] px-2 py-0.5 text-[10px] font-medium uppercase tracking-wide text-[var(--as-muted-fg)]\">\n {provider.type}\n </span>\n ) : null}\n {providerModels.length ? (\n <span className=\"rounded-full bg-[var(--as-muted)] px-2.5 py-0.5 text-[10px] font-semibold uppercase tracking-widest text-[var(--as-muted-fg)]\">\n {providerModels.filter((model) => model.enabled).length}/\n {providerModels.length}\n </span>\n ) : null}\n </span>\n {provider.baseUrl ? (\n <span className=\"block truncate font-mono text-xs text-[var(--as-muted-fg)]\">\n {provider.baseUrl}\n </span>\n ) : null}\n </span>\n </button>\n {expanded ? (\n <div className=\"as-anim-fade flex flex-col gap-2 border-t border-[var(--as-border)] p-4\">\n {!provider.readOnly && providerModels.length === 0 ? (\n <p className=\"text-xs text-[var(--as-muted-fg)]\">\n {emptyProviderLabel}\n </p>\n ) : null}\n {providerModels.map((model) => {\n return (\n <div\n key={model.id}\n className={cn(\n 'flex min-w-0 items-center gap-2 rounded-[var(--as-radius-sm)] border border-[var(--as-border)] px-3 py-2 text-sm',\n model.missing && 'opacity-50',\n )}\n >\n {onToggleEnabled && !provider.readOnly ? (\n <input\n type=\"checkbox\"\n aria-label={`${enableLabel} — ${model.externalId}`}\n checked={model.enabled}\n onChange={(event) => onToggleEnabled(model, event.target.checked)}\n className=\"size-4 shrink-0 cursor-pointer accent-[var(--as-primary)]\"\n />\n ) : null}\n <span className=\"min-w-0 flex-1 truncate font-mono text-xs text-[var(--as-fg)]\">\n {model.externalId}\n </span>\n {model.missing ? (\n <span className=\"text-xs text-[var(--as-warning)]\">\n {missingLabel}\n </span>\n ) : null}\n <CapabilityChips\n variant=\"badge\"\n caps={model.caps.map(descriptorFor)}\n selected={model.caps}\n />\n {!provider.readOnly ? (\n <Button\n variant=\"outline\"\n size=\"sm\"\n aria-label={`${editLabel} ${model.externalId}`}\n onClick={() => openEditModal(model)}\n >\n <Pencil aria-hidden />\n {editLabel}\n </Button>\n ) : null}\n {!provider.readOnly ? (\n <button\n type=\"button\"\n aria-label={`${removeLabel} ${model.externalId}`}\n onClick={() => onDeleteModel(model)}\n className=\"cursor-pointer rounded-[var(--as-radius-sm)] p-1.5 text-[var(--as-muted-fg)] transition-colors hover:bg-[var(--as-muted)] hover:text-[var(--as-fg)] focus-visible:outline-2 focus-visible:outline-offset-1 focus-visible:outline-[var(--as-focus-ring)]\"\n >\n <X className=\"size-4\" aria-hidden />\n </button>\n ) : null}\n </div>\n )\n })}\n {!provider.readOnly ? (\n <div className=\"pt-1\">\n <Button\n variant=\"outline\"\n size=\"sm\"\n aria-expanded={modal?.mode === 'add' && modal.providerId === provider.id}\n onClick={() => openAddModal(provider.id)}\n >\n <Plus aria-hidden />\n {addLabel}\n </Button>\n </div>\n ) : null}\n </div>\n ) : null}\n </div>\n )\n })}\n {providers.length === 0 ? (\n <div className=\"flex flex-col items-center gap-2 py-8 text-center\">\n <p className=\"text-sm text-[var(--as-muted-fg)]\">{providersEmptyLabel}</p>\n {emptyAction}\n </div>\n ) : null}\n {renderModal()}\n </div>\n )\n },\n)\n\n"]}
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
import { ModelPicker } from './chunk-SVQK7TXU.js';
|
|
2
|
+
import { InfoButton } from './chunk-OT6EQFMP.js';
|
|
3
|
+
import { cn } from './chunk-BLJWR4ZV.js';
|
|
4
|
+
import * as React from 'react';
|
|
5
|
+
import { Cpu, X, Star } from 'lucide-react';
|
|
6
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
7
|
+
|
|
8
|
+
function filterProviders(providers, requires) {
|
|
9
|
+
if (!requires) return providers;
|
|
10
|
+
const matches = (model) => model.capability === requires || (model.capabilities?.includes(requires) ?? false);
|
|
11
|
+
return providers.map((provider) => ({
|
|
12
|
+
...provider,
|
|
13
|
+
models: provider.models.filter(matches)
|
|
14
|
+
})).filter((provider) => provider.models.length > 0);
|
|
15
|
+
}
|
|
16
|
+
var TaskAssignmentPicker = React.forwardRef(function TaskAssignmentPicker2({
|
|
17
|
+
tasks = [],
|
|
18
|
+
sections,
|
|
19
|
+
providers,
|
|
20
|
+
value,
|
|
21
|
+
onAssign,
|
|
22
|
+
secondaryValue,
|
|
23
|
+
onAssignSecondary,
|
|
24
|
+
secondaryLabel = "Fallback",
|
|
25
|
+
primaryLabel = "Primary",
|
|
26
|
+
primaryInfo,
|
|
27
|
+
fallbackInfo,
|
|
28
|
+
renderMeta,
|
|
29
|
+
clearLabel = "Clear assignment",
|
|
30
|
+
disabled = false,
|
|
31
|
+
className
|
|
32
|
+
}, ref) {
|
|
33
|
+
const renderRow = (task, showSecondary) => {
|
|
34
|
+
const catalog = filterProviders(providers, task.requires);
|
|
35
|
+
const fallbackOnly = task.secondaryOnly === true;
|
|
36
|
+
return /* @__PURE__ */ jsxs(
|
|
37
|
+
"div",
|
|
38
|
+
{
|
|
39
|
+
className: "flex flex-col gap-2 rounded-[var(--as-radius-lg)] border border-[var(--as-border)] bg-[var(--as-surface-raised)] p-3 sm:flex-row sm:items-center sm:justify-between",
|
|
40
|
+
children: [
|
|
41
|
+
/* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-1 items-center gap-3", children: [
|
|
42
|
+
/* @__PURE__ */ jsx("span", { className: "flex size-9 shrink-0 items-center justify-center rounded-[var(--as-radius)] bg-[var(--as-muted)] text-[var(--as-muted-fg)]", children: (() => {
|
|
43
|
+
const Icon = task.icon ?? Cpu;
|
|
44
|
+
return /* @__PURE__ */ jsx(Icon, { className: "size-4", "aria-hidden": true });
|
|
45
|
+
})() }),
|
|
46
|
+
/* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
|
|
47
|
+
/* @__PURE__ */ jsx("p", { className: "truncate text-sm font-semibold text-[var(--as-fg)]", children: task.label }),
|
|
48
|
+
task.description ? /* @__PURE__ */ jsx("p", { className: "truncate text-xs text-[var(--as-muted-fg)]", children: task.description }) : null,
|
|
49
|
+
renderMeta ? renderMeta(task) : null
|
|
50
|
+
] })
|
|
51
|
+
] }),
|
|
52
|
+
showSecondary && onAssignSecondary ? /* @__PURE__ */ jsxs("div", { className: "flex shrink-0 flex-col items-start gap-2 self-center", children: [
|
|
53
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5", children: [
|
|
54
|
+
/* @__PURE__ */ jsx("span", { className: "inline-flex items-center gap-1 rounded-full bg-[var(--as-muted)] px-2 py-0.5 text-[10px] font-semibold uppercase tracking-wider text-[var(--as-muted-fg)]", children: secondaryLabel }),
|
|
55
|
+
/* @__PURE__ */ jsx(
|
|
56
|
+
ModelPicker,
|
|
57
|
+
{
|
|
58
|
+
providers: catalog,
|
|
59
|
+
value: secondaryValue?.[task.id] ?? "",
|
|
60
|
+
onChange: (modelId) => onAssignSecondary(task.id, modelId),
|
|
61
|
+
disabled,
|
|
62
|
+
clearable: false,
|
|
63
|
+
clearLabel,
|
|
64
|
+
label: `${secondaryLabel} \u2014 ${task.label}`,
|
|
65
|
+
hideLabel: true,
|
|
66
|
+
className: "w-52"
|
|
67
|
+
}
|
|
68
|
+
),
|
|
69
|
+
fallbackInfo ? /* @__PURE__ */ jsx(
|
|
70
|
+
InfoButton,
|
|
71
|
+
{
|
|
72
|
+
label: `${secondaryLabel} \u2014 ${task.label}`,
|
|
73
|
+
showOnHover: false,
|
|
74
|
+
openOnHover: false,
|
|
75
|
+
children: fallbackInfo
|
|
76
|
+
}
|
|
77
|
+
) : null,
|
|
78
|
+
secondaryValue?.[task.id] ? /* @__PURE__ */ jsx(
|
|
79
|
+
"button",
|
|
80
|
+
{
|
|
81
|
+
type: "button",
|
|
82
|
+
"aria-label": `${clearLabel} \u2014 ${secondaryLabel} ${task.label}`,
|
|
83
|
+
disabled,
|
|
84
|
+
onClick: () => onAssignSecondary(task.id, null),
|
|
85
|
+
className: "cursor-pointer rounded-[var(--as-radius-sm)] p-1.5 text-[var(--as-muted-fg)] transition-colors hover:bg-[var(--as-muted)] hover:text-[var(--as-fg)] focus-visible:outline-2 focus-visible:outline-offset-1 focus-visible:outline-[var(--as-focus-ring)] disabled:pointer-events-none disabled:opacity-50",
|
|
86
|
+
children: /* @__PURE__ */ jsx(X, { className: "size-4", "aria-hidden": true })
|
|
87
|
+
}
|
|
88
|
+
) : null
|
|
89
|
+
] }),
|
|
90
|
+
!fallbackOnly ? /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5", children: [
|
|
91
|
+
/* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1 rounded-full bg-[var(--as-muted)] px-2 py-0.5 text-[10px] font-semibold uppercase tracking-wider text-[var(--as-muted-fg)]", children: [
|
|
92
|
+
/* @__PURE__ */ jsx(Star, { className: "size-2.5", "aria-hidden": true }),
|
|
93
|
+
primaryLabel
|
|
94
|
+
] }),
|
|
95
|
+
/* @__PURE__ */ jsx(
|
|
96
|
+
ModelPicker,
|
|
97
|
+
{
|
|
98
|
+
providers: catalog,
|
|
99
|
+
value: value[task.id] ?? "",
|
|
100
|
+
onChange: (modelId) => onAssign(task.id, modelId),
|
|
101
|
+
disabled,
|
|
102
|
+
clearable: false,
|
|
103
|
+
clearLabel,
|
|
104
|
+
label: task.label,
|
|
105
|
+
hideLabel: true,
|
|
106
|
+
className: "w-52"
|
|
107
|
+
}
|
|
108
|
+
),
|
|
109
|
+
primaryInfo ? /* @__PURE__ */ jsx(
|
|
110
|
+
InfoButton,
|
|
111
|
+
{
|
|
112
|
+
label: `${primaryLabel} \u2014 ${task.label}`,
|
|
113
|
+
showOnHover: false,
|
|
114
|
+
openOnHover: false,
|
|
115
|
+
children: primaryInfo
|
|
116
|
+
}
|
|
117
|
+
) : null,
|
|
118
|
+
value[task.id] ? /* @__PURE__ */ jsx(
|
|
119
|
+
"button",
|
|
120
|
+
{
|
|
121
|
+
type: "button",
|
|
122
|
+
"aria-label": `${clearLabel} \u2014 ${task.label}`,
|
|
123
|
+
disabled,
|
|
124
|
+
onClick: () => onAssign(task.id, null),
|
|
125
|
+
className: "cursor-pointer rounded-[var(--as-radius-sm)] p-1.5 text-[var(--as-muted-fg)] transition-colors hover:bg-[var(--as-muted)] hover:text-[var(--as-fg)] focus-visible:outline-2 focus-visible:outline-offset-1 focus-visible:outline-[var(--as-focus-ring)] disabled:pointer-events-none disabled:opacity-50",
|
|
126
|
+
children: /* @__PURE__ */ jsx(X, { className: "size-4", "aria-hidden": true })
|
|
127
|
+
}
|
|
128
|
+
) : null
|
|
129
|
+
] }) : null
|
|
130
|
+
] }) : /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5 self-center", children: [
|
|
131
|
+
/* @__PURE__ */ jsx(
|
|
132
|
+
ModelPicker,
|
|
133
|
+
{
|
|
134
|
+
providers: catalog,
|
|
135
|
+
value: value[task.id] ?? "",
|
|
136
|
+
onChange: (modelId) => onAssign(task.id, modelId),
|
|
137
|
+
disabled,
|
|
138
|
+
clearable: false,
|
|
139
|
+
clearLabel,
|
|
140
|
+
label: task.label,
|
|
141
|
+
hideLabel: true,
|
|
142
|
+
className: "w-56"
|
|
143
|
+
}
|
|
144
|
+
),
|
|
145
|
+
value[task.id] ? /* @__PURE__ */ jsx(
|
|
146
|
+
"button",
|
|
147
|
+
{
|
|
148
|
+
type: "button",
|
|
149
|
+
"aria-label": `${clearLabel} \u2014 ${task.label}`,
|
|
150
|
+
disabled,
|
|
151
|
+
onClick: () => onAssign(task.id, null),
|
|
152
|
+
className: "cursor-pointer rounded-[var(--as-radius-sm)] p-1.5 text-[var(--as-muted-fg)] transition-colors hover:bg-[var(--as-muted)] hover:text-[var(--as-fg)] focus-visible:outline-2 focus-visible:outline-offset-1 focus-visible:outline-[var(--as-focus-ring)] disabled:pointer-events-none disabled:opacity-50",
|
|
153
|
+
children: /* @__PURE__ */ jsx(X, { className: "size-4", "aria-hidden": true })
|
|
154
|
+
}
|
|
155
|
+
) : null
|
|
156
|
+
] })
|
|
157
|
+
]
|
|
158
|
+
},
|
|
159
|
+
task.id
|
|
160
|
+
);
|
|
161
|
+
};
|
|
162
|
+
return /* @__PURE__ */ jsx(
|
|
163
|
+
"div",
|
|
164
|
+
{
|
|
165
|
+
ref,
|
|
166
|
+
"data-as": "task-assignment-picker",
|
|
167
|
+
className: cn("flex w-full flex-col gap-3", className),
|
|
168
|
+
children: sections ? sections.map((section) => /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2", children: [
|
|
169
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
170
|
+
/* @__PURE__ */ jsx("p", { className: "text-xs font-semibold uppercase tracking-wide text-[var(--as-muted-fg)]", children: section.label }),
|
|
171
|
+
section.description ? /* @__PURE__ */ jsx("p", { className: "mt-0.5 text-xs text-[var(--as-muted-fg)]", children: section.description }) : null
|
|
172
|
+
] }),
|
|
173
|
+
section.tasks.map(
|
|
174
|
+
(task) => renderRow(
|
|
175
|
+
task,
|
|
176
|
+
section.secondary || Boolean(task.secondary) || task.secondaryOnly === true
|
|
177
|
+
)
|
|
178
|
+
)
|
|
179
|
+
] }, section.id)) : tasks.map(
|
|
180
|
+
(task) => renderRow(task, Boolean(task.secondary) || task.secondaryOnly === true)
|
|
181
|
+
)
|
|
182
|
+
}
|
|
183
|
+
);
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
export { TaskAssignmentPicker };
|
|
187
|
+
//# sourceMappingURL=chunk-VULOVVKF.js.map
|
|
188
|
+
//# sourceMappingURL=chunk-VULOVVKF.js.map
|