@neuronection/assistant-ui 0.9.0 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +22 -0
- package/README.md +3 -2
- package/dist/about.d.ts +31 -1
- package/dist/about.js +1 -1
- package/dist/capability-chips.d.ts +21 -0
- package/dist/capability-chips.js +3 -0
- package/dist/capability-chips.js.map +1 -0
- package/dist/{chunk-3QGVWTBU.js → chunk-7RTSSBBR.js} +157 -4
- package/dist/chunk-7RTSSBBR.js.map +1 -0
- package/dist/{chunk-RJSN4TVT.js → chunk-A3A4J5M5.js} +4 -3
- package/dist/chunk-A3A4J5M5.js.map +1 -0
- package/dist/chunk-G3DWN2DJ.js +80 -0
- package/dist/chunk-G3DWN2DJ.js.map +1 -0
- package/dist/{chunk-UWHUCQC6.js → chunk-LY2B3UJH.js} +10 -4
- package/dist/chunk-LY2B3UJH.js.map +1 -0
- package/dist/chunk-M67KF4W2.js +130 -0
- package/dist/chunk-M67KF4W2.js.map +1 -0
- package/dist/chunk-N5V5LVZX.js +517 -0
- package/dist/chunk-N5V5LVZX.js.map +1 -0
- package/dist/{chunk-OPTH3VUY.js → chunk-RI6CEWWF.js} +2 -2
- package/dist/chunk-RI6CEWWF.js.map +1 -0
- package/dist/connection-test-row.d.ts +4 -0
- package/dist/connection-test-row.js +1 -1
- package/dist/index.d.ts +4 -2
- package/dist/index.js +9 -7
- package/dist/index.js.map +1 -1
- package/dist/model-picker.d.ts +2 -0
- package/dist/model-picker.js +1 -1
- package/dist/model-registry.d.ts +86 -0
- package/dist/model-registry.js +3 -0
- package/dist/model-registry.js.map +1 -0
- package/dist/provider-form.d.ts +2 -0
- package/dist/provider-form.js +1 -1
- package/dist/styles.css +1 -1
- package/dist/task-assignment-picker.d.ts +25 -6
- package/dist/task-assignment-picker.js +1 -1
- package/package.json +9 -1
- package/dist/chunk-3QGVWTBU.js.map +0 -1
- package/dist/chunk-OPTH3VUY.js.map +0 -1
- package/dist/chunk-RJSN4TVT.js.map +0 -1
- package/dist/chunk-TN35RR2R.js +0 -92
- package/dist/chunk-TN35RR2R.js.map +0 -1
- package/dist/chunk-UWHUCQC6.js.map +0 -1
|
@@ -0,0 +1,517 @@
|
|
|
1
|
+
import { SearchInput } from './chunk-H5U4KNXF.js';
|
|
2
|
+
import { CapabilityChips } from './chunk-G3DWN2DJ.js';
|
|
3
|
+
import { Button } from './chunk-GTXGTQ6F.js';
|
|
4
|
+
import { Spinner } from './chunk-INTST5VG.js';
|
|
5
|
+
import { cn } from './chunk-BLJWR4ZV.js';
|
|
6
|
+
import * as React from 'react';
|
|
7
|
+
import { ChevronDown, ChevronRight, Plus, Pencil, Trash2, Check } from 'lucide-react';
|
|
8
|
+
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
9
|
+
|
|
10
|
+
var UNCLASSIFIED = "__unclassified__";
|
|
11
|
+
var ModelRegistry = React.forwardRef(
|
|
12
|
+
function ModelRegistry2({
|
|
13
|
+
providers,
|
|
14
|
+
models,
|
|
15
|
+
caps,
|
|
16
|
+
expandedProviderId,
|
|
17
|
+
onExpandedProviderChange,
|
|
18
|
+
remoteModels,
|
|
19
|
+
remoteState = "ready",
|
|
20
|
+
remoteError,
|
|
21
|
+
onRetryRemote,
|
|
22
|
+
onAddModel,
|
|
23
|
+
onAddAll,
|
|
24
|
+
onUpdateModel,
|
|
25
|
+
onDeleteModel,
|
|
26
|
+
rank,
|
|
27
|
+
reasoningEffortOptions,
|
|
28
|
+
addLabel = "Add",
|
|
29
|
+
addedLabel = "Added",
|
|
30
|
+
addAllLabel = "Add all",
|
|
31
|
+
configureLabel = "Configure",
|
|
32
|
+
editLabel = "Edit",
|
|
33
|
+
removeLabel = "Remove",
|
|
34
|
+
missingLabel = "Missing",
|
|
35
|
+
capsLabel = "Capabilities",
|
|
36
|
+
searchPlaceholder = "Search models\u2026",
|
|
37
|
+
searchLabel = "Search models",
|
|
38
|
+
capFilterLabel = "Filter by capability",
|
|
39
|
+
unclassifiedLabel = "Unclassified",
|
|
40
|
+
emptyProviderLabel = "No models yet \u2014 add from the catalog below.",
|
|
41
|
+
remoteEmptyLabel = "No models match.",
|
|
42
|
+
remoteLoadingLabel = "Loading models\u2026",
|
|
43
|
+
retryLabel = "Retry",
|
|
44
|
+
browseLabel = "Browse catalog",
|
|
45
|
+
manualAddLabel = "Add manually",
|
|
46
|
+
externalIdLabel = "Model ID",
|
|
47
|
+
labelLabel = "Display label",
|
|
48
|
+
reasoningEffortLabel = "Reasoning effort",
|
|
49
|
+
reasoningEffortPlaceholder,
|
|
50
|
+
saveLabel = "Save",
|
|
51
|
+
cancelLabel = "Cancel",
|
|
52
|
+
addDraftLabel = "Add model",
|
|
53
|
+
providersEmptyLabel = "No providers yet.",
|
|
54
|
+
emptyAction,
|
|
55
|
+
className
|
|
56
|
+
}, ref) {
|
|
57
|
+
const [query, setQuery] = React.useState("");
|
|
58
|
+
const [capFilter, setCapFilter] = React.useState(null);
|
|
59
|
+
const [draft, setDraft] = React.useState(null);
|
|
60
|
+
const [draftError, setDraftError] = React.useState(null);
|
|
61
|
+
const [catalogOpen, setCatalogOpen] = React.useState(false);
|
|
62
|
+
const descriptorFor = React.useCallback(
|
|
63
|
+
(value) => caps.find((cap) => cap.value === value) ?? { value, label: value },
|
|
64
|
+
[caps]
|
|
65
|
+
);
|
|
66
|
+
const filteredRemote = React.useMemo(() => {
|
|
67
|
+
const items = remoteModels ?? [];
|
|
68
|
+
const needle = query.trim().toLowerCase();
|
|
69
|
+
const ranked = needle && rank ? rank(items, query) : items;
|
|
70
|
+
const searched = needle && !rank ? ranked.filter((item) => item.id.toLowerCase().includes(needle)) : ranked;
|
|
71
|
+
if (capFilter === UNCLASSIFIED) return searched.filter((item) => item.caps.length === 0);
|
|
72
|
+
if (capFilter) return searched.filter((item) => item.caps.includes(capFilter));
|
|
73
|
+
return searched;
|
|
74
|
+
}, [remoteModels, query, capFilter, rank]);
|
|
75
|
+
const filterDescriptors = React.useMemo(
|
|
76
|
+
() => [...caps, { value: UNCLASSIFIED, label: unclassifiedLabel }],
|
|
77
|
+
[caps, unclassifiedLabel]
|
|
78
|
+
);
|
|
79
|
+
const pendingRemote = React.useMemo(() => {
|
|
80
|
+
const expanded = providers.find((provider) => provider.id === expandedProviderId);
|
|
81
|
+
if (!expanded) return [];
|
|
82
|
+
const existingIds = new Set(
|
|
83
|
+
models.filter((model) => model.providerId === expanded.id).map((model) => model.externalId)
|
|
84
|
+
);
|
|
85
|
+
return filteredRemote.filter((remote) => !existingIds.has(remote.id));
|
|
86
|
+
}, [filteredRemote, providers, expandedProviderId, models]);
|
|
87
|
+
const resetDraft = React.useCallback(() => {
|
|
88
|
+
setDraft(null);
|
|
89
|
+
setDraftError(null);
|
|
90
|
+
}, []);
|
|
91
|
+
const toggleProvider = (providerId) => {
|
|
92
|
+
const next = expandedProviderId === providerId ? null : providerId;
|
|
93
|
+
onExpandedProviderChange(next);
|
|
94
|
+
setQuery("");
|
|
95
|
+
setCapFilter(null);
|
|
96
|
+
setCatalogOpen(false);
|
|
97
|
+
resetDraft();
|
|
98
|
+
};
|
|
99
|
+
const openAddDraft = (providerId, remote) => {
|
|
100
|
+
setDraft({
|
|
101
|
+
key: `remote:${remote.id}`,
|
|
102
|
+
mode: "add",
|
|
103
|
+
providerId,
|
|
104
|
+
externalId: remote.id,
|
|
105
|
+
label: "",
|
|
106
|
+
caps: [...remote.caps],
|
|
107
|
+
reasoningEffort: ""
|
|
108
|
+
});
|
|
109
|
+
setDraftError(null);
|
|
110
|
+
};
|
|
111
|
+
const openManualDraft = (providerId) => {
|
|
112
|
+
setDraft({
|
|
113
|
+
key: `manual:${providerId}`,
|
|
114
|
+
mode: "add",
|
|
115
|
+
providerId,
|
|
116
|
+
externalId: "",
|
|
117
|
+
label: "",
|
|
118
|
+
caps: caps[0] ? [caps[0].value] : [],
|
|
119
|
+
reasoningEffort: ""
|
|
120
|
+
});
|
|
121
|
+
setDraftError(null);
|
|
122
|
+
};
|
|
123
|
+
const openEditDraft = (model) => {
|
|
124
|
+
setDraft({
|
|
125
|
+
key: `model:${model.id}`,
|
|
126
|
+
mode: "edit",
|
|
127
|
+
providerId: model.providerId,
|
|
128
|
+
externalId: model.externalId,
|
|
129
|
+
label: model.label ?? "",
|
|
130
|
+
caps: [...model.caps],
|
|
131
|
+
reasoningEffort: model.reasoningEffort ?? "",
|
|
132
|
+
model
|
|
133
|
+
});
|
|
134
|
+
setDraftError(null);
|
|
135
|
+
};
|
|
136
|
+
const toggleDraftCap = (value) => {
|
|
137
|
+
setDraft(
|
|
138
|
+
(current) => current ? {
|
|
139
|
+
...current,
|
|
140
|
+
caps: current.caps.includes(value) ? current.caps.filter((entry) => entry !== value) : [...current.caps, value]
|
|
141
|
+
} : current
|
|
142
|
+
);
|
|
143
|
+
};
|
|
144
|
+
const submitDraft = () => {
|
|
145
|
+
if (!draft) return;
|
|
146
|
+
const externalId = draft.externalId.trim();
|
|
147
|
+
if (!externalId) {
|
|
148
|
+
setDraftError(externalIdLabel);
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
const payload = {
|
|
152
|
+
externalId,
|
|
153
|
+
label: draft.label.trim() || void 0,
|
|
154
|
+
caps: draft.caps,
|
|
155
|
+
reasoningEffort: draft.reasoningEffort.trim()
|
|
156
|
+
};
|
|
157
|
+
if (draft.mode === "add") {
|
|
158
|
+
onAddModel(draft.providerId, payload);
|
|
159
|
+
} else if (draft.model) {
|
|
160
|
+
onUpdateModel(draft.model, payload);
|
|
161
|
+
}
|
|
162
|
+
resetDraft();
|
|
163
|
+
};
|
|
164
|
+
const renderDraftPanel = () => {
|
|
165
|
+
if (!draft) return null;
|
|
166
|
+
const confirmDisabled = draft.mode === "add" && !draft.externalId.trim();
|
|
167
|
+
return /* @__PURE__ */ jsxs(
|
|
168
|
+
"div",
|
|
169
|
+
{
|
|
170
|
+
"data-as": "model-registry-draft",
|
|
171
|
+
className: "flex flex-col gap-3 rounded-[var(--as-radius)] border border-[var(--as-border)] bg-[var(--as-surface-raised)] p-3",
|
|
172
|
+
children: [
|
|
173
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2 sm:flex-row", children: [
|
|
174
|
+
/* @__PURE__ */ jsxs("label", { className: "min-w-0 flex-1 space-y-1 text-xs", children: [
|
|
175
|
+
/* @__PURE__ */ jsx("span", { className: "text-[var(--as-muted-fg)]", children: externalIdLabel }),
|
|
176
|
+
/* @__PURE__ */ jsx(
|
|
177
|
+
"input",
|
|
178
|
+
{
|
|
179
|
+
type: "text",
|
|
180
|
+
value: draft.externalId,
|
|
181
|
+
disabled: draft.mode === "edit",
|
|
182
|
+
onChange: (event) => setDraft(
|
|
183
|
+
(current) => current ? { ...current, externalId: event.target.value } : current
|
|
184
|
+
),
|
|
185
|
+
className: "w-full rounded-[var(--as-radius-sm)] border border-[var(--as-border)] bg-[var(--as-surface)] px-2 py-1.5 font-mono text-xs text-[var(--as-fg)] disabled:opacity-60"
|
|
186
|
+
}
|
|
187
|
+
)
|
|
188
|
+
] }),
|
|
189
|
+
/* @__PURE__ */ jsxs("label", { className: "min-w-0 flex-1 space-y-1 text-xs", children: [
|
|
190
|
+
/* @__PURE__ */ jsx("span", { className: "text-[var(--as-muted-fg)]", children: labelLabel }),
|
|
191
|
+
/* @__PURE__ */ jsx(
|
|
192
|
+
"input",
|
|
193
|
+
{
|
|
194
|
+
type: "text",
|
|
195
|
+
value: draft.label,
|
|
196
|
+
onChange: (event) => setDraft(
|
|
197
|
+
(current) => current ? { ...current, label: event.target.value } : current
|
|
198
|
+
),
|
|
199
|
+
className: "w-full rounded-[var(--as-radius-sm)] border border-[var(--as-border)] bg-[var(--as-surface)] px-2 py-1.5 text-xs text-[var(--as-fg)]"
|
|
200
|
+
}
|
|
201
|
+
)
|
|
202
|
+
] })
|
|
203
|
+
] }),
|
|
204
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
|
|
205
|
+
/* @__PURE__ */ jsx("span", { className: "text-[var(--as-muted-fg)]", children: capsLabel }),
|
|
206
|
+
/* @__PURE__ */ jsx(
|
|
207
|
+
CapabilityChips,
|
|
208
|
+
{
|
|
209
|
+
caps,
|
|
210
|
+
selected: draft.caps,
|
|
211
|
+
onToggle: toggleDraftCap,
|
|
212
|
+
ariaLabel: capsLabel
|
|
213
|
+
}
|
|
214
|
+
)
|
|
215
|
+
] }),
|
|
216
|
+
reasoningEffortOptions ? /* @__PURE__ */ jsxs("label", { className: "space-y-1 text-xs", children: [
|
|
217
|
+
/* @__PURE__ */ jsx("span", { className: "text-[var(--as-muted-fg)]", children: reasoningEffortLabel }),
|
|
218
|
+
/* @__PURE__ */ jsx(
|
|
219
|
+
"input",
|
|
220
|
+
{
|
|
221
|
+
type: "text",
|
|
222
|
+
value: draft.reasoningEffort,
|
|
223
|
+
placeholder: reasoningEffortPlaceholder,
|
|
224
|
+
list: "as-reasoning-effort-options",
|
|
225
|
+
onChange: (event) => setDraft(
|
|
226
|
+
(current) => current ? { ...current, reasoningEffort: event.target.value } : current
|
|
227
|
+
),
|
|
228
|
+
className: "w-full rounded-[var(--as-radius-sm)] border border-[var(--as-border)] bg-[var(--as-surface)] px-2 py-1.5 text-xs text-[var(--as-fg)]"
|
|
229
|
+
}
|
|
230
|
+
),
|
|
231
|
+
/* @__PURE__ */ jsx("datalist", { id: "as-reasoning-effort-options", children: reasoningEffortOptions.map((option) => /* @__PURE__ */ jsx("option", { value: option }, option)) })
|
|
232
|
+
] }) : null,
|
|
233
|
+
draftError ? /* @__PURE__ */ jsx("p", { className: "text-xs text-[var(--as-danger)]", children: draftError }) : null,
|
|
234
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-end gap-2", children: [
|
|
235
|
+
/* @__PURE__ */ jsx(Button, { variant: "ghost", size: "sm", onClick: resetDraft, children: cancelLabel }),
|
|
236
|
+
/* @__PURE__ */ jsxs(
|
|
237
|
+
Button,
|
|
238
|
+
{
|
|
239
|
+
size: "sm",
|
|
240
|
+
disabled: confirmDisabled,
|
|
241
|
+
onClick: submitDraft,
|
|
242
|
+
children: [
|
|
243
|
+
/* @__PURE__ */ jsx(Plus, { "aria-hidden": true }),
|
|
244
|
+
draft.mode === "add" ? addDraftLabel : saveLabel
|
|
245
|
+
]
|
|
246
|
+
}
|
|
247
|
+
)
|
|
248
|
+
] })
|
|
249
|
+
]
|
|
250
|
+
}
|
|
251
|
+
);
|
|
252
|
+
};
|
|
253
|
+
const renderRemoteRows = (providerId) => {
|
|
254
|
+
const providerModels = models.filter((model) => model.providerId === providerId);
|
|
255
|
+
const existingFor = (externalId) => providerModels.find((model) => model.externalId === externalId);
|
|
256
|
+
if (remoteState === "loading") {
|
|
257
|
+
return /* @__PURE__ */ jsxs("p", { className: "flex items-center justify-center gap-2 py-4 text-xs text-[var(--as-muted-fg)]", children: [
|
|
258
|
+
/* @__PURE__ */ jsx(Spinner, { size: "sm" }),
|
|
259
|
+
remoteLoadingLabel
|
|
260
|
+
] });
|
|
261
|
+
}
|
|
262
|
+
if (remoteState === "error") {
|
|
263
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2 py-2", children: [
|
|
264
|
+
/* @__PURE__ */ jsx("p", { className: "truncate text-xs text-[var(--as-danger)]", children: remoteError }),
|
|
265
|
+
onRetryRemote ? /* @__PURE__ */ jsx(Button, { variant: "outline", size: "sm", onClick: onRetryRemote, children: retryLabel }) : null
|
|
266
|
+
] });
|
|
267
|
+
}
|
|
268
|
+
if (filteredRemote.length === 0) {
|
|
269
|
+
return /* @__PURE__ */ jsx("p", { className: "py-3 text-center text-xs text-[var(--as-muted-fg)]", children: remoteEmptyLabel });
|
|
270
|
+
}
|
|
271
|
+
return /* @__PURE__ */ jsx("div", { "data-as": "model-registry-catalog", className: "flex flex-col gap-1", children: filteredRemote.map((remote) => {
|
|
272
|
+
const existing = existingFor(remote.id);
|
|
273
|
+
const expandedRow = draft?.key === `remote:${remote.id}`;
|
|
274
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2", children: [
|
|
275
|
+
/* @__PURE__ */ jsxs("div", { className: "flex min-w-0 items-center gap-2 rounded-[var(--as-radius-sm)] border border-[var(--as-border)] px-3 py-2", children: [
|
|
276
|
+
/* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate font-mono text-xs text-[var(--as-fg)]", children: remote.id }),
|
|
277
|
+
/* @__PURE__ */ jsx(
|
|
278
|
+
CapabilityChips,
|
|
279
|
+
{
|
|
280
|
+
variant: "badge",
|
|
281
|
+
caps: remote.caps.map(descriptorFor),
|
|
282
|
+
selected: remote.caps
|
|
283
|
+
}
|
|
284
|
+
),
|
|
285
|
+
/* @__PURE__ */ jsx(
|
|
286
|
+
"button",
|
|
287
|
+
{
|
|
288
|
+
type: "button",
|
|
289
|
+
"aria-expanded": expandedRow,
|
|
290
|
+
"aria-label": `${existing ? editLabel : configureLabel} ${remote.id}`,
|
|
291
|
+
onClick: () => {
|
|
292
|
+
if (expandedRow) {
|
|
293
|
+
resetDraft();
|
|
294
|
+
} else if (existing) {
|
|
295
|
+
openEditDraft(existing);
|
|
296
|
+
} else {
|
|
297
|
+
openAddDraft(providerId, remote);
|
|
298
|
+
}
|
|
299
|
+
},
|
|
300
|
+
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)]",
|
|
301
|
+
children: expandedRow ? /* @__PURE__ */ jsx(ChevronDown, { className: "size-4", "aria-hidden": true }) : /* @__PURE__ */ jsx(ChevronRight, { className: "size-4", "aria-hidden": true })
|
|
302
|
+
}
|
|
303
|
+
),
|
|
304
|
+
existing?.enabled ? /* @__PURE__ */ jsxs("span", { className: "flex shrink-0 items-center gap-1 text-[11px] text-[var(--as-muted-fg)]", children: [
|
|
305
|
+
/* @__PURE__ */ jsx(Check, { className: "size-3", "aria-hidden": true }),
|
|
306
|
+
addedLabel
|
|
307
|
+
] }) : /* @__PURE__ */ jsxs(
|
|
308
|
+
Button,
|
|
309
|
+
{
|
|
310
|
+
variant: "outline",
|
|
311
|
+
size: "sm",
|
|
312
|
+
"aria-label": `${addLabel} ${remote.id}`,
|
|
313
|
+
onClick: () => onAddModel(providerId, { externalId: remote.id, caps: remote.caps }),
|
|
314
|
+
children: [
|
|
315
|
+
/* @__PURE__ */ jsx(Plus, { "aria-hidden": true }),
|
|
316
|
+
addLabel
|
|
317
|
+
]
|
|
318
|
+
}
|
|
319
|
+
)
|
|
320
|
+
] }),
|
|
321
|
+
expandedRow ? renderDraftPanel() : null
|
|
322
|
+
] }, remote.id);
|
|
323
|
+
}) });
|
|
324
|
+
};
|
|
325
|
+
const renderModelRow = (model) => {
|
|
326
|
+
const expandedRow = draft?.key === `model:${model.id}`;
|
|
327
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2", children: [
|
|
328
|
+
/* @__PURE__ */ jsxs(
|
|
329
|
+
"div",
|
|
330
|
+
{
|
|
331
|
+
className: cn(
|
|
332
|
+
"flex min-w-0 items-center gap-2 rounded-[var(--as-radius-sm)] px-2 py-1.5 text-sm",
|
|
333
|
+
model.missing && "opacity-50"
|
|
334
|
+
),
|
|
335
|
+
children: [
|
|
336
|
+
/* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate font-mono text-xs text-[var(--as-fg)]", children: model.externalId }),
|
|
337
|
+
model.missing ? /* @__PURE__ */ jsx("span", { className: "text-xs text-[var(--as-warning)]", children: missingLabel }) : null,
|
|
338
|
+
/* @__PURE__ */ jsx(
|
|
339
|
+
CapabilityChips,
|
|
340
|
+
{
|
|
341
|
+
variant: "badge",
|
|
342
|
+
caps: model.caps.map(descriptorFor),
|
|
343
|
+
selected: model.caps
|
|
344
|
+
}
|
|
345
|
+
),
|
|
346
|
+
/* @__PURE__ */ jsx(
|
|
347
|
+
"button",
|
|
348
|
+
{
|
|
349
|
+
type: "button",
|
|
350
|
+
"aria-expanded": expandedRow,
|
|
351
|
+
"aria-label": `${editLabel} ${model.externalId}`,
|
|
352
|
+
onClick: () => expandedRow ? resetDraft() : openEditDraft(model),
|
|
353
|
+
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)]",
|
|
354
|
+
children: /* @__PURE__ */ jsx(Pencil, { className: "size-3.5", "aria-hidden": true })
|
|
355
|
+
}
|
|
356
|
+
),
|
|
357
|
+
/* @__PURE__ */ jsx(
|
|
358
|
+
"button",
|
|
359
|
+
{
|
|
360
|
+
type: "button",
|
|
361
|
+
"aria-label": `${removeLabel} ${model.externalId}`,
|
|
362
|
+
onClick: () => {
|
|
363
|
+
if (expandedRow) resetDraft();
|
|
364
|
+
onDeleteModel(model);
|
|
365
|
+
},
|
|
366
|
+
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)]",
|
|
367
|
+
children: /* @__PURE__ */ jsx(Trash2, { className: "size-3.5", "aria-hidden": true })
|
|
368
|
+
}
|
|
369
|
+
)
|
|
370
|
+
]
|
|
371
|
+
}
|
|
372
|
+
),
|
|
373
|
+
expandedRow ? renderDraftPanel() : null
|
|
374
|
+
] }, model.id);
|
|
375
|
+
};
|
|
376
|
+
return /* @__PURE__ */ jsxs(
|
|
377
|
+
"div",
|
|
378
|
+
{
|
|
379
|
+
ref,
|
|
380
|
+
"data-as": "model-registry",
|
|
381
|
+
className: cn("flex w-full flex-col gap-4", className),
|
|
382
|
+
children: [
|
|
383
|
+
providers.map((provider) => {
|
|
384
|
+
const expanded = expandedProviderId === provider.id;
|
|
385
|
+
const providerModels = models.filter((model) => model.providerId === provider.id);
|
|
386
|
+
return /* @__PURE__ */ jsxs(
|
|
387
|
+
"div",
|
|
388
|
+
{
|
|
389
|
+
"data-as": "model-registry-provider",
|
|
390
|
+
className: cn(
|
|
391
|
+
"rounded-[var(--as-radius-lg)] border bg-[var(--as-surface)] transition-all",
|
|
392
|
+
expanded ? "border-[var(--as-primary)] shadow-[var(--as-shadow-1)]" : "border-[var(--as-border)]"
|
|
393
|
+
),
|
|
394
|
+
children: [
|
|
395
|
+
/* @__PURE__ */ jsxs(
|
|
396
|
+
"button",
|
|
397
|
+
{
|
|
398
|
+
type: "button",
|
|
399
|
+
"aria-expanded": expanded,
|
|
400
|
+
onClick: () => toggleProvider(provider.id),
|
|
401
|
+
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)]",
|
|
402
|
+
children: [
|
|
403
|
+
/* @__PURE__ */ jsx(
|
|
404
|
+
"span",
|
|
405
|
+
{
|
|
406
|
+
className: cn(
|
|
407
|
+
"flex size-9 shrink-0 items-center justify-center rounded-[var(--as-radius)] transition-colors",
|
|
408
|
+
expanded ? "bg-[var(--as-primary)] text-[var(--as-primary-fg)]" : "bg-[var(--as-muted)] text-[var(--as-muted-fg)] group-hover:bg-[var(--as-primary)]/10 group-hover:text-[var(--as-primary)]"
|
|
409
|
+
),
|
|
410
|
+
children: expanded ? /* @__PURE__ */ jsx(ChevronDown, { className: "size-5", "aria-hidden": true }) : /* @__PURE__ */ jsx(ChevronRight, { className: "size-5", "aria-hidden": true })
|
|
411
|
+
}
|
|
412
|
+
),
|
|
413
|
+
/* @__PURE__ */ jsxs("span", { className: "min-w-0 flex-1", children: [
|
|
414
|
+
/* @__PURE__ */ jsxs("span", { className: "flex flex-wrap items-center gap-2 text-sm font-semibold text-[var(--as-fg)]", children: [
|
|
415
|
+
provider.name,
|
|
416
|
+
provider.type ? /* @__PURE__ */ jsx("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)]", children: provider.type }) : null,
|
|
417
|
+
providerModels.length ? /* @__PURE__ */ jsxs("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)]", children: [
|
|
418
|
+
providerModels.filter((model) => model.enabled).length,
|
|
419
|
+
"/",
|
|
420
|
+
providerModels.length
|
|
421
|
+
] }) : null
|
|
422
|
+
] }),
|
|
423
|
+
provider.baseUrl ? /* @__PURE__ */ jsx("span", { className: "block truncate font-mono text-xs text-[var(--as-muted-fg)]", children: provider.baseUrl }) : null
|
|
424
|
+
] })
|
|
425
|
+
]
|
|
426
|
+
}
|
|
427
|
+
),
|
|
428
|
+
expanded ? /* @__PURE__ */ jsxs("div", { className: "as-anim-fade flex flex-col gap-3 border-t border-[var(--as-border)] p-4", children: [
|
|
429
|
+
providerModels.length === 0 ? /* @__PURE__ */ jsx("p", { className: "text-xs text-[var(--as-muted-fg)]", children: emptyProviderLabel }) : /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-1", children: providerModels.map(renderModelRow) }),
|
|
430
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2 border-t border-[var(--as-border)] pt-3", children: [
|
|
431
|
+
/* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsxs(
|
|
432
|
+
Button,
|
|
433
|
+
{
|
|
434
|
+
variant: "outline",
|
|
435
|
+
size: "sm",
|
|
436
|
+
"aria-expanded": catalogOpen,
|
|
437
|
+
onClick: () => setCatalogOpen((open) => !open),
|
|
438
|
+
children: [
|
|
439
|
+
/* @__PURE__ */ jsx(Plus, { "aria-hidden": true }),
|
|
440
|
+
browseLabel
|
|
441
|
+
]
|
|
442
|
+
}
|
|
443
|
+
) }),
|
|
444
|
+
catalogOpen ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
445
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
|
|
446
|
+
/* @__PURE__ */ jsx(
|
|
447
|
+
SearchInput,
|
|
448
|
+
{
|
|
449
|
+
value: query,
|
|
450
|
+
onChange: (next) => {
|
|
451
|
+
setQuery(next);
|
|
452
|
+
resetDraft();
|
|
453
|
+
},
|
|
454
|
+
placeholder: searchPlaceholder,
|
|
455
|
+
ariaLabel: searchLabel,
|
|
456
|
+
className: "max-w-xs flex-1"
|
|
457
|
+
}
|
|
458
|
+
),
|
|
459
|
+
/* @__PURE__ */ jsx(
|
|
460
|
+
CapabilityChips,
|
|
461
|
+
{
|
|
462
|
+
caps: filterDescriptors,
|
|
463
|
+
selected: capFilter ? [capFilter] : [],
|
|
464
|
+
onToggle: (value) => setCapFilter((current) => current === value ? null : value),
|
|
465
|
+
ariaLabel: capFilterLabel
|
|
466
|
+
}
|
|
467
|
+
),
|
|
468
|
+
/* @__PURE__ */ jsxs(Button, { variant: "ghost", size: "sm", onClick: () => openManualDraft(provider.id), children: [
|
|
469
|
+
/* @__PURE__ */ jsx(Plus, { "aria-hidden": true }),
|
|
470
|
+
manualAddLabel
|
|
471
|
+
] }),
|
|
472
|
+
onAddAll ? /* @__PURE__ */ jsxs(
|
|
473
|
+
Button,
|
|
474
|
+
{
|
|
475
|
+
variant: "outline",
|
|
476
|
+
size: "sm",
|
|
477
|
+
disabled: remoteState !== "ready" || pendingRemote.length === 0,
|
|
478
|
+
onClick: () => onAddAll(
|
|
479
|
+
provider.id,
|
|
480
|
+
pendingRemote.map((remote) => ({
|
|
481
|
+
externalId: remote.id,
|
|
482
|
+
caps: remote.caps
|
|
483
|
+
}))
|
|
484
|
+
),
|
|
485
|
+
children: [
|
|
486
|
+
/* @__PURE__ */ jsx(Plus, { "aria-hidden": true }),
|
|
487
|
+
addAllLabel,
|
|
488
|
+
" (",
|
|
489
|
+
pendingRemote.length,
|
|
490
|
+
")"
|
|
491
|
+
]
|
|
492
|
+
}
|
|
493
|
+
) : null
|
|
494
|
+
] }),
|
|
495
|
+
draft?.key.startsWith("manual:") ? renderDraftPanel() : null,
|
|
496
|
+
renderRemoteRows(provider.id)
|
|
497
|
+
] }) : null
|
|
498
|
+
] })
|
|
499
|
+
] }) : null
|
|
500
|
+
]
|
|
501
|
+
},
|
|
502
|
+
provider.id
|
|
503
|
+
);
|
|
504
|
+
}),
|
|
505
|
+
providers.length === 0 ? /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-2 py-8 text-center", children: [
|
|
506
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm text-[var(--as-muted-fg)]", children: providersEmptyLabel }),
|
|
507
|
+
emptyAction
|
|
508
|
+
] }) : null
|
|
509
|
+
]
|
|
510
|
+
}
|
|
511
|
+
);
|
|
512
|
+
}
|
|
513
|
+
);
|
|
514
|
+
|
|
515
|
+
export { ModelRegistry };
|
|
516
|
+
//# sourceMappingURL=chunk-N5V5LVZX.js.map
|
|
517
|
+
//# sourceMappingURL=chunk-N5V5LVZX.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/model-registry/ModelRegistry.tsx"],"names":["ModelRegistry"],"mappings":"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","file":"chunk-N5V5LVZX.js","sourcesContent":["import * as React from 'react'\nimport { Check, ChevronDown, ChevronRight, Pencil, Plus, Trash2 } from 'lucide-react'\nimport { cn } from '../../lib/utils'\nimport { Button } from '../button'\nimport { CapabilityChips, type CapabilityDescriptor } from '../capability-chips'\nimport { SearchInput } from '../search-input'\nimport { Spinner } from '../spinner'\n\nexport interface ModelRegistryProvider {\n id: string\n name: string\n type?: string\n baseUrl?: string\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 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}\n\nexport interface ModelRegistryPatch {\n label?: string\n caps?: string[]\n enabled?: boolean\n reasoningEffort?: string\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 rank?: (items: ModelRegistryRemoteModel[], query: string) => ModelRegistryRemoteModel[]\n reasoningEffortOptions?: string[]\n addLabel?: string\n addedLabel?: string\n addAllLabel?: string\n configureLabel?: string\n editLabel?: string\n removeLabel?: string\n missingLabel?: string\n capsLabel?: string\n searchPlaceholder?: string\n searchLabel?: string\n capFilterLabel?: string\n unclassifiedLabel?: string\n emptyProviderLabel?: string\n remoteEmptyLabel?: string\n remoteLoadingLabel?: string\n retryLabel?: string\n /** Catalog disclosure trigger; the search/filter zone renders only when opened. */\n browseLabel?: string\n manualAddLabel?: string\n externalIdLabel?: string\n labelLabel?: string\n reasoningEffortLabel?: string\n reasoningEffortPlaceholder?: string\n saveLabel?: string\n cancelLabel?: string\n addDraftLabel?: string\n providersEmptyLabel?: string\n emptyAction?: React.ReactNode\n className?: string\n}\n\nconst UNCLASSIFIED = '__unclassified__'\n\ninterface DraftState {\n key: string\n mode: 'add' | 'edit'\n providerId: string\n externalId: string\n label: string\n caps: string[]\n reasoningEffort: string\n model?: ModelRegistryModel\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 rank,\n reasoningEffortOptions,\n addLabel = 'Add',\n addedLabel = 'Added',\n addAllLabel = 'Add all',\n configureLabel = 'Configure',\n editLabel = 'Edit',\n removeLabel = 'Remove',\n missingLabel = 'Missing',\n capsLabel = 'Capabilities',\n searchPlaceholder = 'Search models…',\n searchLabel = 'Search models',\n capFilterLabel = 'Filter by capability',\n unclassifiedLabel = 'Unclassified',\n emptyProviderLabel = 'No models yet — add from the catalog below.',\n remoteEmptyLabel = 'No models match.',\n remoteLoadingLabel = 'Loading models…',\n retryLabel = 'Retry',\n browseLabel = 'Browse catalog',\n manualAddLabel = 'Add manually',\n externalIdLabel = 'Model ID',\n labelLabel = 'Display label',\n reasoningEffortLabel = 'Reasoning effort',\n reasoningEffortPlaceholder,\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 [query, setQuery] = React.useState('')\n const [capFilter, setCapFilter] = React.useState<string | null>(null)\n const [draft, setDraft] = React.useState<DraftState | null>(null)\n const [draftError, setDraftError] = React.useState<string | null>(null)\n const [catalogOpen, setCatalogOpen] = React.useState(false)\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 filteredRemote = React.useMemo(() => {\n const items = remoteModels ?? []\n const needle = query.trim().toLowerCase()\n const ranked =\n needle && rank ? rank(items, query) : items\n const searched =\n needle && !rank\n ? ranked.filter((item) => item.id.toLowerCase().includes(needle))\n : ranked\n if (capFilter === UNCLASSIFIED) return searched.filter((item) => item.caps.length === 0)\n if (capFilter) return searched.filter((item) => item.caps.includes(capFilter))\n return searched\n }, [remoteModels, query, capFilter, rank])\n\n const filterDescriptors: CapabilityDescriptor[] = React.useMemo(\n () => [...caps, { value: UNCLASSIFIED, label: unclassifiedLabel }],\n [caps, unclassifiedLabel],\n )\n\n const pendingRemote = React.useMemo(() => {\n const expanded = providers.find((provider) => provider.id === expandedProviderId)\n if (!expanded) return []\n const existingIds = new Set(\n models\n .filter((model) => model.providerId === expanded.id)\n .map((model) => model.externalId),\n )\n return filteredRemote.filter((remote) => !existingIds.has(remote.id))\n }, [filteredRemote, providers, expandedProviderId, models])\n\n const resetDraft = React.useCallback(() => {\n setDraft(null)\n setDraftError(null)\n }, [])\n\n const toggleProvider = (providerId: string) => {\n const next = expandedProviderId === providerId ? null : providerId\n onExpandedProviderChange(next)\n setQuery('')\n setCapFilter(null)\n setCatalogOpen(false)\n resetDraft()\n }\n\n const openAddDraft = (providerId: string, remote: ModelRegistryRemoteModel) => {\n setDraft({\n key: `remote:${remote.id}`,\n mode: 'add',\n providerId,\n externalId: remote.id,\n label: '',\n caps: [...remote.caps],\n reasoningEffort: '',\n })\n setDraftError(null)\n }\n\n const openManualDraft = (providerId: string) => {\n setDraft({\n key: `manual:${providerId}`,\n mode: 'add',\n providerId,\n externalId: '',\n label: '',\n caps: caps[0] ? [caps[0].value] : [],\n reasoningEffort: '',\n })\n setDraftError(null)\n }\n\n const openEditDraft = (model: ModelRegistryModel) => {\n setDraft({\n key: `model:${model.id}`,\n mode: 'edit',\n providerId: model.providerId,\n externalId: model.externalId,\n label: model.label ?? '',\n caps: [...model.caps],\n reasoningEffort: model.reasoningEffort ?? '',\n model,\n })\n setDraftError(null)\n }\n\n const toggleDraftCap = (value: string) => {\n setDraft((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 submitDraft = () => {\n if (!draft) return\n const externalId = draft.externalId.trim()\n if (!externalId) {\n setDraftError(externalIdLabel)\n return\n }\n const payload: ModelRegistryDraft = {\n externalId,\n label: draft.label.trim() || undefined,\n caps: draft.caps,\n reasoningEffort: draft.reasoningEffort.trim(),\n }\n if (draft.mode === 'add') {\n onAddModel(draft.providerId, payload)\n } else if (draft.model) {\n onUpdateModel(draft.model, payload)\n }\n resetDraft()\n }\n\n const renderDraftPanel = () => {\n if (!draft) return null\n const confirmDisabled = draft.mode === 'add' && !draft.externalId.trim()\n return (\n <div\n data-as=\"model-registry-draft\"\n className=\"flex flex-col gap-3 rounded-[var(--as-radius)] border border-[var(--as-border)] bg-[var(--as-surface-raised)] p-3\"\n >\n <div className=\"flex flex-col gap-2 sm:flex-row\">\n <label className=\"min-w-0 flex-1 space-y-1 text-xs\">\n <span className=\"text-[var(--as-muted-fg)]\">{externalIdLabel}</span>\n <input\n type=\"text\"\n value={draft.externalId}\n disabled={draft.mode === 'edit'}\n onChange={(event) =>\n setDraft((current) =>\n current ? { ...current, externalId: event.target.value } : current,\n )\n }\n className=\"w-full rounded-[var(--as-radius-sm)] border border-[var(--as-border)] bg-[var(--as-surface)] px-2 py-1.5 font-mono text-xs text-[var(--as-fg)] disabled:opacity-60\"\n />\n </label>\n <label className=\"min-w-0 flex-1 space-y-1 text-xs\">\n <span className=\"text-[var(--as-muted-fg)]\">{labelLabel}</span>\n <input\n type=\"text\"\n value={draft.label}\n onChange={(event) =>\n setDraft((current) =>\n current ? { ...current, label: event.target.value } : current,\n )\n }\n className=\"w-full rounded-[var(--as-radius-sm)] border border-[var(--as-border)] bg-[var(--as-surface)] px-2 py-1.5 text-xs text-[var(--as-fg)]\"\n />\n </label>\n </div>\n <div className=\"space-y-1\">\n <span className=\"text-[var(--as-muted-fg)]\">{capsLabel}</span>\n <CapabilityChips\n caps={caps}\n selected={draft.caps}\n onToggle={toggleDraftCap}\n ariaLabel={capsLabel}\n />\n </div>\n {reasoningEffortOptions ? (\n <label className=\"space-y-1 text-xs\">\n <span className=\"text-[var(--as-muted-fg)]\">{reasoningEffortLabel}</span>\n <input\n type=\"text\"\n value={draft.reasoningEffort}\n placeholder={reasoningEffortPlaceholder}\n list=\"as-reasoning-effort-options\"\n onChange={(event) =>\n setDraft((current) =>\n current ? { ...current, reasoningEffort: event.target.value } : current,\n )\n }\n className=\"w-full rounded-[var(--as-radius-sm)] border border-[var(--as-border)] bg-[var(--as-surface)] px-2 py-1.5 text-xs text-[var(--as-fg)]\"\n />\n <datalist id=\"as-reasoning-effort-options\">\n {reasoningEffortOptions.map((option) => (\n <option key={option} value={option} />\n ))}\n </datalist>\n </label>\n ) : null}\n {draftError ? (\n <p className=\"text-xs text-[var(--as-danger)]\">{draftError}</p>\n ) : null}\n <div className=\"flex items-center justify-end gap-2\">\n <Button variant=\"ghost\" size=\"sm\" onClick={resetDraft}>\n {cancelLabel}\n </Button>\n <Button\n size=\"sm\"\n disabled={confirmDisabled}\n onClick={submitDraft}\n >\n <Plus aria-hidden />\n {draft.mode === 'add' ? addDraftLabel : saveLabel}\n </Button>\n </div>\n </div>\n )\n }\n\n const renderRemoteRows = (providerId: string) => {\n const providerModels = models.filter((model) => model.providerId === providerId)\n const existingFor = (externalId: string) =>\n providerModels.find((model) => model.externalId === externalId)\n if (remoteState === 'loading') {\n return (\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 )\n }\n if (remoteState === 'error') {\n return (\n <div className=\"flex items-center justify-between gap-2 py-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 )\n }\n if (filteredRemote.length === 0) {\n return (\n <p className=\"py-3 text-center text-xs text-[var(--as-muted-fg)]\">\n {remoteEmptyLabel}\n </p>\n )\n }\n return (\n <div data-as=\"model-registry-catalog\" className=\"flex flex-col gap-1\">\n {filteredRemote.map((remote) => {\n const existing = existingFor(remote.id)\n const expandedRow = draft?.key === `remote:${remote.id}`\n return (\n <div key={remote.id} className=\"flex flex-col gap-2\">\n <div className=\"flex min-w-0 items-center gap-2 rounded-[var(--as-radius-sm)] border border-[var(--as-border)] px-3 py-2\">\n <span className=\"min-w-0 flex-1 truncate font-mono text-xs text-[var(--as-fg)]\">\n {remote.id}\n </span>\n <CapabilityChips\n variant=\"badge\"\n caps={remote.caps.map(descriptorFor)}\n selected={remote.caps}\n />\n <button\n type=\"button\"\n aria-expanded={expandedRow}\n aria-label={`${existing ? editLabel : configureLabel} ${remote.id}`}\n onClick={() => {\n if (expandedRow) {\n resetDraft()\n } else if (existing) {\n openEditDraft(existing)\n } else {\n openAddDraft(providerId, remote)\n }\n }}\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 {expandedRow ? (\n <ChevronDown className=\"size-4\" aria-hidden />\n ) : (\n <ChevronRight className=\"size-4\" aria-hidden />\n )}\n </button>\n {existing?.enabled ? (\n <span className=\"flex shrink-0 items-center gap-1 text-[11px] text-[var(--as-muted-fg)]\">\n <Check className=\"size-3\" aria-hidden />\n {addedLabel}\n </span>\n ) : (\n <Button\n variant=\"outline\"\n size=\"sm\"\n aria-label={`${addLabel} ${remote.id}`}\n onClick={() =>\n onAddModel(providerId, { externalId: remote.id, caps: remote.caps })\n }\n >\n <Plus aria-hidden />\n {addLabel}\n </Button>\n )}\n </div>\n {expandedRow ? renderDraftPanel() : null}\n </div>\n )\n })}\n </div>\n )\n }\n\n const renderModelRow = (model: ModelRegistryModel) => {\n const expandedRow = draft?.key === `model:${model.id}`\n return (\n <div key={model.id} className=\"flex flex-col gap-2\">\n <div\n className={cn(\n 'flex min-w-0 items-center gap-2 rounded-[var(--as-radius-sm)] px-2 py-1.5 text-sm',\n model.missing && 'opacity-50',\n )}\n >\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)]\">{missingLabel}</span>\n ) : null}\n <CapabilityChips\n variant=\"badge\"\n caps={model.caps.map(descriptorFor)}\n selected={model.caps}\n />\n <button\n type=\"button\"\n aria-expanded={expandedRow}\n aria-label={`${editLabel} ${model.externalId}`}\n onClick={() => (expandedRow ? resetDraft() : openEditDraft(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 <Pencil className=\"size-3.5\" aria-hidden />\n </button>\n <button\n type=\"button\"\n aria-label={`${removeLabel} ${model.externalId}`}\n onClick={() => {\n if (expandedRow) resetDraft()\n onDeleteModel(model)\n }}\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 <Trash2 className=\"size-3.5\" aria-hidden />\n </button>\n </div>\n {expandedRow ? renderDraftPanel() : null}\n </div>\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-3 border-t border-[var(--as-border)] p-4\">\n {providerModels.length === 0 ? (\n <p className=\"text-xs text-[var(--as-muted-fg)]\">{emptyProviderLabel}</p>\n ) : (\n <div className=\"flex flex-col gap-1\">\n {providerModels.map(renderModelRow)}\n </div>\n )}\n <div className=\"flex flex-col gap-2 border-t border-[var(--as-border)] pt-3\">\n <div>\n <Button\n variant=\"outline\"\n size=\"sm\"\n aria-expanded={catalogOpen}\n onClick={() => setCatalogOpen((open) => !open)}\n >\n <Plus aria-hidden />\n {browseLabel}\n </Button>\n </div>\n {catalogOpen ? (\n <>\n <div className=\"flex flex-wrap items-center gap-2\">\n <SearchInput\n value={query}\n onChange={(next) => {\n setQuery(next)\n resetDraft()\n }}\n placeholder={searchPlaceholder}\n ariaLabel={searchLabel}\n className=\"max-w-xs flex-1\"\n />\n <CapabilityChips\n caps={filterDescriptors}\n selected={capFilter ? [capFilter] : []}\n onToggle={(value) =>\n setCapFilter((current) => (current === value ? null : value))\n }\n ariaLabel={capFilterLabel}\n />\n <Button variant=\"ghost\" size=\"sm\" onClick={() => openManualDraft(provider.id)}>\n <Plus aria-hidden />\n {manualAddLabel}\n </Button>\n {onAddAll ? (\n <Button\n variant=\"outline\"\n size=\"sm\"\n disabled={remoteState !== 'ready' || pendingRemote.length === 0}\n onClick={() =>\n onAddAll(\n provider.id,\n pendingRemote.map((remote) => ({\n externalId: remote.id,\n caps: remote.caps,\n })),\n )\n }\n >\n <Plus aria-hidden />\n {addAllLabel} ({pendingRemote.length})\n </Button>\n ) : null}\n </div>\n {draft?.key.startsWith('manual:') ? renderDraftPanel() : null}\n {renderRemoteRows(provider.id)}\n </>\n ) : null}\n </div>\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 </div>\n )\n },\n)\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/model-picker/ModelPicker.tsx"],"names":["ModelPicker"],"mappings":";;;;;AA6CO,IAAM,WAAA,GAAoB,KAAA,CAAA,UAAA;AAAA,EAC/B,SAASA,YAAAA,CACP;AAAA,IACE,SAAA;AAAA,IACA,KAAA;AAAA,IACA,QAAA;AAAA,IACA,WAAA,GAAc,sBAAA;AAAA,IACd,iBAAA,GAAoB,qBAAA;AAAA,IACpB,WAAA;AAAA,IACA,UAAA;AAAA,IACA,OAAA,GAAU,KAAA;AAAA,IACV,QAAA,GAAW,KAAA;AAAA,IACX,SAAA,GAAY,KAAA;AAAA,IACZ,UAAA;AAAA,IACA,KAAA;AAAA,IACA,KAAA;AAAA,IACA,EAAA;AAAA,IACA,SAAA;AAAA,IACA;AAAA,KAEF,GAAA,EACA;AACA,IAAA,MAAM,OAAA,GAAkC,KAAA,CAAA,OAAA;AAAA,MACtC,MACE,SAAA,CAAU,OAAA;AAAA,QAAQ,CAAC,QAAA,KACjB,QAAA,CAAS,MAAA,CAAO,GAAA,CAAI,CAAC,KAAA,MAAW;AAAA,UAC9B,OAAO,KAAA,CAAM,EAAA;AAAA,UACb,OAAO,KAAA,CAAM,IAAA;AAAA,UACb,OAAO,QAAA,CAAS,IAAA;AAAA,UAChB,OAAO,KAAA,CAAM;AAAA,SACf,CAAE;AAAA,OACJ;AAAA,MACF,CAAC,SAAS;AAAA,KACZ;AAEA,IAAA,uBACE,GAAA;AAAA,MAAC,QAAA;AAAA,MAAA;AAAA,QACC,GAAA;AAAA,QACA,OAAA;AAAA,QACA,KAAA;AAAA,QACA,QAAA;AAAA,QACA,WAAA;AAAA,QACA,iBAAA;AAAA,QACA,WAAA;AAAA,QACA,UAAA;AAAA,QACA,OAAA;AAAA,QACA,QAAA;AAAA,QACA,SAAA;AAAA,QACA,UAAA;AAAA,QACA,KAAA;AAAA,QACA,KAAA;AAAA,QACA,EAAA;AAAA,QACA,SAAA,EAAW,EAAA,CAAG,QAAA,EAAU,SAAS,CAAA;AAAA,QACjC;AAAA;AAAA,KACF;AAAA,EAEJ;AACF","file":"chunk-RI6CEWWF.js","sourcesContent":["import * as React from 'react'\nimport { cn } from '../../lib/utils'\nimport {\n Combobox,\n type ComboboxOption,\n} from '../combobox'\n\nexport interface ModelPickerModel {\n id: string\n name: string\n /** Short capability chip, e.g. `vision` or `tools`. */\n capability?: string\n /** Full capability set, matched by TaskAssignmentPicker `requires`. */\n capabilities?: string[]\n}\n\nexport interface ModelPickerProvider {\n id: string\n name: string\n models: ModelPickerModel[]\n}\n\nexport interface ModelPickerProps {\n providers: ModelPickerProvider[]\n value?: string\n onChange: (modelId: string) => void\n placeholder?: string\n searchPlaceholder?: string\n searchLabel?: string\n emptyLabel?: string\n loading?: boolean\n disabled?: boolean\n clearable?: boolean\n clearLabel?: string\n label?: string\n error?: string\n id?: string\n className?: string\n panelClassName?: string\n}\n\n/**\n * Grouped, searchable provider → model picker. Presentational: the model\n * list comes in via props, selection goes out via `onChange`.\n */\nexport const ModelPicker = React.forwardRef<HTMLButtonElement, ModelPickerProps>(\n function ModelPicker(\n {\n providers,\n value,\n onChange,\n placeholder = 'Select a model…',\n searchPlaceholder = 'Search models…',\n searchLabel,\n emptyLabel,\n loading = false,\n disabled = false,\n clearable = false,\n clearLabel,\n label,\n error,\n id,\n className,\n panelClassName,\n },\n ref,\n ) {\n const options: ComboboxOption[] = React.useMemo(\n () =>\n providers.flatMap((provider) =>\n provider.models.map((model) => ({\n value: model.id,\n label: model.name,\n group: provider.name,\n badge: model.capability,\n })),\n ),\n [providers],\n )\n\n return (\n <Combobox\n ref={ref}\n options={options}\n value={value}\n onChange={onChange}\n placeholder={placeholder}\n searchPlaceholder={searchPlaceholder}\n searchLabel={searchLabel}\n emptyLabel={emptyLabel}\n loading={loading}\n disabled={disabled}\n clearable={clearable}\n clearLabel={clearLabel}\n label={label}\n error={error}\n id={id}\n className={cn('w-full', className)}\n panelClassName={panelClassName}\n />\n )\n },\n)\n"]}
|
|
@@ -12,6 +12,10 @@ interface ConnectionTestRowProps {
|
|
|
12
12
|
errorMessage?: string | null;
|
|
13
13
|
onTest?: () => void;
|
|
14
14
|
disabled?: boolean;
|
|
15
|
+
/** `row` = standalone bordered row; `inline` = bare, for embedding in app cards. */
|
|
16
|
+
variant?: 'row' | 'inline';
|
|
17
|
+
/** Extra app-side context rendered after the status (e.g. model count). */
|
|
18
|
+
meta?: React.ReactNode;
|
|
15
19
|
className?: string;
|
|
16
20
|
}
|
|
17
21
|
/**
|