@workerdeck/ui 0.12.0 → 0.13.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/build/{SessionPanel-NQ8ksCfj.mjs → SessionPanel-CKQa4i0Y.mjs} +113 -110
- package/build/SessionPanel-CKQa4i0Y.mjs.map +1 -0
- package/build/{SessionPanel-Dy9lQrOV.d.mts → SessionPanel-CZMA44NM.d.mts} +30 -1
- package/build/index.d.mts +66 -7
- package/build/index.mjs +283 -152
- package/build/index.mjs.map +1 -1
- package/build/workspace.d.mts +9 -1
- package/build/workspace.mjs +4 -2
- package/build/workspace.mjs.map +1 -1
- package/package.json +4 -4
- package/src/components/agent/Composer.tsx +18 -10
- package/src/components/agent/EngineIcon.tsx +97 -0
- package/src/components/agent/Loader.tsx +4 -1
- package/src/components/agent/Message.tsx +10 -6
- package/src/components/agent/QuestionPrompt.tsx +1 -1
- package/src/components/agent/SessionBrowser.tsx +235 -117
- package/src/components/agent/SessionPanel.tsx +61 -13
- package/src/components/agent/SessionWorkspace.tsx +10 -0
- package/src/components/agent/StatusBar.tsx +9 -2
- package/src/components/agent/Transcript.tsx +2 -3
- package/src/components/agent/line-prompt.tsx +2 -2
- package/src/components/ui/Menu.tsx +1 -1
- package/src/components/ui/Select.tsx +1 -1
- package/src/components/ui/Tooltip.tsx +1 -1
- package/src/index.ts +9 -1
- package/src/styles/theme.css +45 -15
- package/build/SessionPanel-NQ8ksCfj.mjs.map +0 -1
package/build/index.mjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { $ as Tip, A as
|
|
1
|
+
import { $ as Tip, A as SkillsDialog, B as commandTrigger, C as isMutatingTool, Ct as Button, D as permissionModeChoices, E as PermissionModeSelect, F as skillPrompt, G as plainTextToSegments, H as mentionTrigger, I as TranscriptDensityProvider, J as Splitter, K as segmentsToPlainText, L as TranscriptVariantProvider, M as HostFilesDialog, N as ContextDialog, O as permissionModeMeta, P as Composer, Q as copyText, R as useTranscriptDensity, S as Response, St as badgeVariants, T as PERMISSION_MODES, Tt as cn, U as usePromptAreaState, V as hashtagTrigger, W as PromptArea, X as Spinner, Y as CodeBlock, Z as CopyButton, _ as SessionInfoDialog, _t as SelectItemText, a as SessionEmptyState, at as DialogContent, b as parseUserQuestions, bt as Input, c as Message, ct as DialogTrigger, d as FileCard, dt as MenuItem, et as TooltipContent, f as Conversation, ft as MenuSeparator, g as STATUS_META, gt as SelectItem, h as StatusBar, ht as SelectContent, i as ToolCallCard, it as DialogClose, j as McpDialog, k as ModelSelect, l as MessageContent, lt as Menu, m as ConversationScrollButton, mt as Select, n as UsageDialog, nt as Dialog, o as Reasoning, ot as DialogHeader, p as ConversationContent, pt as MenuTrigger, q as ProgressRing, r as Transcript, rt as DialogBody, s as PromptTokenText, st as DialogRow, t as SessionPanel, tt as TooltipProvider, u as Loader, ut as MenuContent, v as QUESTION_BEHAVIORS, vt as SelectTrigger, w as toolIcon, wt as buttonVariants, x as PermissionPrompt, xt as Badge, y as QuestionPrompt, yt as SelectValue, z as useTranscriptVariant } from "./SessionPanel-CKQa4i0Y.mjs";
|
|
2
2
|
import { a as formatDuration, c as formatRelativeTime, d as rateLimitWindowSeconds, f as toolInputPreview, i as formatCountdown, l as formatTokens, n as formatBytes, o as formatRateLimitWindow, r as formatCost, s as formatRateLimitWindowLong, t as formatAgoPrecise, u as friendlyModel } from "./format-DqR56Y8l.mjs";
|
|
3
3
|
import { forwardRef, useEffect, useMemo, useRef, useState } from "react";
|
|
4
4
|
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
5
|
-
import { Pencil, Search, Trash2, X } from "lucide-react";
|
|
5
|
+
import { BellRing, CircleAlert, CircleSlash, Moon, PauseCircle, Pencil, Search, Trash2, X } from "lucide-react";
|
|
6
6
|
import { AlertDialog as AlertDialog$1 } from "@base-ui/react/alert-dialog";
|
|
7
7
|
import { Toaster as Toaster$1, toast } from "sonner";
|
|
8
8
|
import { STATE_LABELS, STATE_ORDER, adaptersOf, clearFilters, filterRows, groupRows, hasFacetFilter, sessionLabel, subsetSummary } from "@workerdeck/protocol";
|
|
@@ -158,7 +158,26 @@ function SessionList({ sessions, activeId, onSelect, onDelete, emptyText = "No s
|
|
|
158
158
|
}
|
|
159
159
|
//#endregion
|
|
160
160
|
//#region src/components/agent/SessionBrowser.tsx
|
|
161
|
-
|
|
161
|
+
/**
|
|
162
|
+
* How a list row is drawn, in one place, so `SidebarRow` in `web` matches this
|
|
163
|
+
* exactly rather than approximating it — the dashboard's other three sidebars
|
|
164
|
+
* are that component, and a sessions list that hovered differently from the
|
|
165
|
+
* gateways list beside it would read as a different product.
|
|
166
|
+
*
|
|
167
|
+
* Two rules are load-bearing:
|
|
168
|
+
*
|
|
169
|
+
* - **Fill means hover, and only hover.** It stays on the row whether or not
|
|
170
|
+
* the row is selected, because a selected row still has to answer the
|
|
171
|
+
* pointer. Selection gets the gutter instead.
|
|
172
|
+
* - **`ml-0` on the selected row is not cosmetic.** It hands the accent border
|
|
173
|
+
* the 4px the margin was holding, so the text does not shift sideways as a
|
|
174
|
+
* row becomes the selected one. The squared left corners are what let the bar
|
|
175
|
+
* sit flush against the sidebar edge.
|
|
176
|
+
*/
|
|
177
|
+
function rowShapeClass(active) {
|
|
178
|
+
return cn("px-2 py-1.5 hover:bg-row-hover", active ? "mr-1 ml-0 rounded-r-md border-l-4 border-l-accent" : "mx-1 rounded-md");
|
|
179
|
+
}
|
|
180
|
+
function SessionBrowser({ rows, config, onConfigChange, scope, activeId, onSelect, onDelete, onRename, emptyState, showControls = true, className }) {
|
|
162
181
|
const visible = useMemo(() => filterRows(rows, config, scope), [
|
|
163
182
|
rows,
|
|
164
183
|
config,
|
|
@@ -184,10 +203,10 @@ function SessionBrowser({ rows, config, onConfigChange, scope, activeId, onSelec
|
|
|
184
203
|
className: cn("flex flex-col gap-3", className),
|
|
185
204
|
children: [
|
|
186
205
|
/* @__PURE__ */ jsxs("div", {
|
|
187
|
-
className: "flex flex-
|
|
206
|
+
className: cn("flex flex-col gap-1.5 px-2", !showControls && "hidden"),
|
|
188
207
|
children: [
|
|
189
208
|
/* @__PURE__ */ jsxs("div", {
|
|
190
|
-
className: "relative
|
|
209
|
+
className: "relative",
|
|
191
210
|
children: [/* @__PURE__ */ jsx(Search, { className: "pointer-events-none absolute top-1/2 left-2.5 size-3.5 -translate-y-1/2 text-fg-4" }), /* @__PURE__ */ jsx(Input, {
|
|
192
211
|
value: config.search,
|
|
193
212
|
onChange: (e) => set({ search: e.target.value }),
|
|
@@ -196,83 +215,98 @@ function SessionBrowser({ rows, config, onConfigChange, scope, activeId, onSelec
|
|
|
196
215
|
className: "pl-8"
|
|
197
216
|
})]
|
|
198
217
|
}),
|
|
199
|
-
/* @__PURE__ */ jsx(
|
|
218
|
+
/* @__PURE__ */ jsx(FilterRow, {
|
|
200
219
|
label: "State",
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
value:
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
220
|
+
children: /* @__PURE__ */ jsx(FacetSelect, {
|
|
221
|
+
label: "State",
|
|
222
|
+
value: config.states,
|
|
223
|
+
options: STATE_ORDER.map((s) => ({
|
|
224
|
+
value: s,
|
|
225
|
+
label: STATE_LABELS[s]
|
|
226
|
+
})),
|
|
227
|
+
onChange: (states) => set({ states })
|
|
228
|
+
})
|
|
207
229
|
}),
|
|
208
|
-
adapters.length > 1 ? /* @__PURE__ */ jsx(
|
|
230
|
+
adapters.length > 1 ? /* @__PURE__ */ jsx(FilterRow, {
|
|
209
231
|
label: "Engine",
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
value:
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
232
|
+
children: /* @__PURE__ */ jsx(FacetSelect, {
|
|
233
|
+
label: "Engine",
|
|
234
|
+
value: config.adapters,
|
|
235
|
+
options: adapters.map((a) => ({
|
|
236
|
+
value: a,
|
|
237
|
+
label: a
|
|
238
|
+
})),
|
|
239
|
+
onChange: (adapters) => set({ adapters })
|
|
240
|
+
})
|
|
216
241
|
}) : null,
|
|
217
|
-
gateways.length > 1 ? /* @__PURE__ */ jsx(
|
|
242
|
+
gateways.length > 1 ? /* @__PURE__ */ jsx(FilterRow, {
|
|
218
243
|
label: "Gateway",
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
value:
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
244
|
+
children: /* @__PURE__ */ jsx(FacetSelect, {
|
|
245
|
+
label: "Gateway",
|
|
246
|
+
value: config.gateways,
|
|
247
|
+
options: gateways.map((g) => ({
|
|
248
|
+
value: g.id,
|
|
249
|
+
label: g.name
|
|
250
|
+
})),
|
|
251
|
+
onChange: (gateways) => set({ gateways })
|
|
252
|
+
})
|
|
225
253
|
}) : null,
|
|
226
|
-
/* @__PURE__ */ jsx(
|
|
254
|
+
/* @__PURE__ */ jsx(FilterRow, {
|
|
227
255
|
label: "Group",
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
256
|
+
children: /* @__PURE__ */ jsx(OneOfSelect, {
|
|
257
|
+
label: "Group",
|
|
258
|
+
value: config.groupBy,
|
|
259
|
+
options: [
|
|
260
|
+
{
|
|
261
|
+
value: "none",
|
|
262
|
+
label: "No grouping"
|
|
263
|
+
},
|
|
264
|
+
{
|
|
265
|
+
value: "state",
|
|
266
|
+
label: "By state"
|
|
267
|
+
},
|
|
268
|
+
{
|
|
269
|
+
value: "adapter",
|
|
270
|
+
label: "By engine"
|
|
271
|
+
},
|
|
272
|
+
...gateways.length > 1 ? [{
|
|
273
|
+
value: "gateway",
|
|
274
|
+
label: "By gateway"
|
|
275
|
+
}] : []
|
|
276
|
+
],
|
|
277
|
+
onChange: (groupBy) => set({ groupBy })
|
|
278
|
+
})
|
|
248
279
|
}),
|
|
249
|
-
/* @__PURE__ */ jsx(
|
|
280
|
+
/* @__PURE__ */ jsx(FilterRow, {
|
|
250
281
|
label: "Sort",
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
282
|
+
children: /* @__PURE__ */ jsx(OneOfSelect, {
|
|
283
|
+
label: "Sort",
|
|
284
|
+
value: config.sortBy,
|
|
285
|
+
options: [
|
|
286
|
+
{
|
|
287
|
+
value: "recent",
|
|
288
|
+
label: "Recent"
|
|
289
|
+
},
|
|
290
|
+
{
|
|
291
|
+
value: "name",
|
|
292
|
+
label: "Name"
|
|
293
|
+
},
|
|
294
|
+
{
|
|
295
|
+
value: "state",
|
|
296
|
+
label: "State"
|
|
297
|
+
},
|
|
298
|
+
...gateways.length > 1 ? [{
|
|
299
|
+
value: "gateway",
|
|
300
|
+
label: "Gateway"
|
|
301
|
+
}] : []
|
|
302
|
+
],
|
|
303
|
+
onChange: (sortBy) => set({ sortBy })
|
|
304
|
+
})
|
|
271
305
|
})
|
|
272
306
|
]
|
|
273
307
|
}),
|
|
274
308
|
subset ? /* @__PURE__ */ jsxs("div", {
|
|
275
|
-
className: "flex items-center gap-2 text-label text-fg-4",
|
|
309
|
+
className: "flex items-center gap-2 px-3 text-label text-fg-4",
|
|
276
310
|
children: [/* @__PURE__ */ jsxs("span", { children: [
|
|
277
311
|
subset.shown,
|
|
278
312
|
" of ",
|
|
@@ -299,7 +333,7 @@ function SessionBrowser({ rows, config, onConfigChange, scope, activeId, onSelec
|
|
|
299
333
|
children: groups.map((group) => /* @__PURE__ */ jsxs("div", {
|
|
300
334
|
className: "flex flex-col gap-1",
|
|
301
335
|
children: [config.groupBy !== "none" && group.label ? /* @__PURE__ */ jsxs("div", {
|
|
302
|
-
className: "flex items-baseline gap-2 px-
|
|
336
|
+
className: "flex items-baseline gap-2 px-3 text-label font-medium text-fg-4",
|
|
303
337
|
children: [/* @__PURE__ */ jsx("span", {
|
|
304
338
|
className: "uppercase tracking-wide",
|
|
305
339
|
children: group.label
|
|
@@ -322,98 +356,99 @@ function SessionBrowser({ rows, config, onConfigChange, scope, activeId, onSelec
|
|
|
322
356
|
}
|
|
323
357
|
function Empty({ children }) {
|
|
324
358
|
return /* @__PURE__ */ jsx("div", {
|
|
325
|
-
className: "px-
|
|
359
|
+
className: "px-3 py-6 text-center text-body-sm text-fg-4",
|
|
326
360
|
children
|
|
327
361
|
});
|
|
328
362
|
}
|
|
329
363
|
function SessionRowItem({ row, active, showGateway, onSelect, onDelete, onRename }) {
|
|
330
364
|
const { info } = row;
|
|
331
|
-
const meta = STATUS_META[info.status];
|
|
332
365
|
const [editing, setEditing] = useState(false);
|
|
366
|
+
const folder = info.cwd.split("/").filter(Boolean).pop() ?? info.cwd;
|
|
367
|
+
const details = [
|
|
368
|
+
showGateway ? row.hostName : void 0,
|
|
369
|
+
friendlyModel(info.model),
|
|
370
|
+
folder,
|
|
371
|
+
info.profile ? `@${info.profile}` : void 0,
|
|
372
|
+
formatCost(info.totalCostUsd)
|
|
373
|
+
].filter(Boolean);
|
|
333
374
|
return /* @__PURE__ */ jsxs("div", {
|
|
334
375
|
"data-slot": "session-row",
|
|
335
376
|
"data-active": active || void 0,
|
|
336
|
-
className: cn("group flex
|
|
337
|
-
children: [
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
]
|
|
369
|
-
}), /* @__PURE__ */ jsxs("button", {
|
|
377
|
+
className: cn("group flex cursor-pointer flex-col gap-0.5 text-left transition-colors", rowShapeClass(active === true)),
|
|
378
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
379
|
+
className: "flex items-center gap-1.5",
|
|
380
|
+
children: [
|
|
381
|
+
editing && onRename ? /* @__PURE__ */ jsx(NameEditor, {
|
|
382
|
+
initial: info.title ?? "",
|
|
383
|
+
onCommit: (title) => {
|
|
384
|
+
setEditing(false);
|
|
385
|
+
onRename(row, title);
|
|
386
|
+
},
|
|
387
|
+
onCancel: () => setEditing(false)
|
|
388
|
+
}) : /* @__PURE__ */ jsx("button", {
|
|
389
|
+
type: "button",
|
|
390
|
+
onClick: () => onSelect?.(row),
|
|
391
|
+
className: cn("min-w-0 flex-1 truncate text-left text-body-sm outline-none", active ? "font-medium text-fg-1" : "text-fg-2"),
|
|
392
|
+
children: sessionLabel(info)
|
|
393
|
+
}),
|
|
394
|
+
row.unseen > 0 ? /* @__PURE__ */ jsx("span", {
|
|
395
|
+
title: `${row.unseen} new`,
|
|
396
|
+
className: "shrink-0 rounded-full bg-accent px-1.5 text-label text-accent-fg",
|
|
397
|
+
children: row.unseen
|
|
398
|
+
}) : null,
|
|
399
|
+
/* @__PURE__ */ jsx("span", {
|
|
400
|
+
className: "shrink-0 text-label text-fg-4",
|
|
401
|
+
children: formatRelativeTime(info.lastActivityAt ?? info.createdAt)
|
|
402
|
+
}),
|
|
403
|
+
/* @__PURE__ */ jsx(SessionStatusIcon, { row })
|
|
404
|
+
]
|
|
405
|
+
}), /* @__PURE__ */ jsxs("div", {
|
|
406
|
+
className: "flex items-center gap-1 text-label text-fg-4",
|
|
407
|
+
children: [
|
|
408
|
+
/* @__PURE__ */ jsx("button", {
|
|
370
409
|
type: "button",
|
|
371
410
|
onClick: () => !editing && onSelect?.(row),
|
|
372
|
-
className: "
|
|
373
|
-
children:
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
})
|
|
394
|
-
]
|
|
395
|
-
})]
|
|
396
|
-
}),
|
|
397
|
-
onRename && !editing ? /* @__PURE__ */ jsx(Button, {
|
|
398
|
-
variant: "ghost",
|
|
399
|
-
size: "icon-sm",
|
|
400
|
-
"aria-label": "Rename session",
|
|
401
|
-
className: "opacity-0 transition-opacity group-hover:opacity-100",
|
|
402
|
-
onClick: () => setEditing(true),
|
|
403
|
-
children: /* @__PURE__ */ jsx(Pencil, { className: "size-3.5 text-fg-3" })
|
|
404
|
-
}) : null,
|
|
405
|
-
onDelete ? /* @__PURE__ */ jsx(Button, {
|
|
406
|
-
variant: "ghost",
|
|
407
|
-
size: "icon-sm",
|
|
408
|
-
"aria-label": "Close session",
|
|
409
|
-
className: "opacity-0 transition-opacity group-hover:opacity-100",
|
|
410
|
-
onClick: () => onDelete(row),
|
|
411
|
-
children: /* @__PURE__ */ jsx(Trash2, { className: "size-3.5 text-fg-3" })
|
|
412
|
-
}) : null
|
|
413
|
-
]
|
|
411
|
+
className: "min-w-0 flex-1 truncate text-left font-mono outline-none",
|
|
412
|
+
children: details.join(" · ")
|
|
413
|
+
}),
|
|
414
|
+
onRename && !editing ? /* @__PURE__ */ jsx(Button, {
|
|
415
|
+
variant: "ghost",
|
|
416
|
+
size: "icon-sm",
|
|
417
|
+
"aria-label": "Rename session",
|
|
418
|
+
className: "size-5 shrink-0 opacity-0 transition-opacity group-hover:opacity-100",
|
|
419
|
+
onClick: () => setEditing(true),
|
|
420
|
+
children: /* @__PURE__ */ jsx(Pencil, { className: "size-3 text-fg-3" })
|
|
421
|
+
}) : null,
|
|
422
|
+
onDelete ? /* @__PURE__ */ jsx(Button, {
|
|
423
|
+
variant: "ghost",
|
|
424
|
+
size: "icon-sm",
|
|
425
|
+
"aria-label": "Close session",
|
|
426
|
+
className: "size-5 shrink-0 opacity-0 transition-opacity group-hover:opacity-100",
|
|
427
|
+
onClick: () => onDelete(row),
|
|
428
|
+
children: /* @__PURE__ */ jsx(Trash2, { className: "size-3 text-fg-3" })
|
|
429
|
+
}) : null
|
|
430
|
+
]
|
|
431
|
+
})]
|
|
414
432
|
});
|
|
415
433
|
}
|
|
416
434
|
/**
|
|
435
|
+
* State as one glyph on the right edge — a ringing bell when it wants a human, a
|
|
436
|
+
* spinner while it works, a moon when it is only sleeping. Replaces the text
|
|
437
|
+
* badge: in a sidebar the word costs more room than it earns, and the states
|
|
438
|
+
* that matter are the two you can recognise without reading.
|
|
439
|
+
*/
|
|
440
|
+
function SessionStatusIcon({ row }) {
|
|
441
|
+
const { info } = row;
|
|
442
|
+
if (info.pendingPermissionCount > 0 || info.status === "awaiting_approval") return /* @__PURE__ */ jsx(BellRing, { className: "size-3.5 shrink-0 animate-pulse text-warning" });
|
|
443
|
+
if (info.status === "running" || info.status === "starting") return /* @__PURE__ */ jsx(Spinner, { className: "size-3.5 shrink-0 text-info" });
|
|
444
|
+
switch (info.status) {
|
|
445
|
+
case "failed": return /* @__PURE__ */ jsx(CircleAlert, { className: "size-3.5 shrink-0 text-danger" });
|
|
446
|
+
case "closed": return /* @__PURE__ */ jsx(CircleSlash, { className: "size-3.5 shrink-0 text-fg-4" });
|
|
447
|
+
case "parked": return /* @__PURE__ */ jsx(PauseCircle, { className: "size-3.5 shrink-0 text-fg-3" });
|
|
448
|
+
default: return /* @__PURE__ */ jsx(Moon, { className: "size-3.5 shrink-0 text-fg-4" });
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
/**
|
|
417
452
|
* Inline rename. Enter commits, Escape cancels, blur commits — but only a blur
|
|
418
453
|
* that is still inside this document: switching windows must not silently commit,
|
|
419
454
|
* nor kill the editor in the frame it opened.
|
|
@@ -442,6 +477,24 @@ function NameEditor({ initial, onCommit, onCancel }) {
|
|
|
442
477
|
}
|
|
443
478
|
/** A multi-select facet. Empty = no filter, which is why the trigger reads the
|
|
444
479
|
* facet's name rather than "All": nothing is being excluded. */
|
|
480
|
+
/**
|
|
481
|
+
* One labelled control row. The label column is fixed so every control starts
|
|
482
|
+
* on the same x — the thing that makes a stack of them read as a form rather
|
|
483
|
+
* than as five unrelated widgets.
|
|
484
|
+
*/
|
|
485
|
+
function FilterRow({ label, children }) {
|
|
486
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
487
|
+
className: "flex items-center gap-2",
|
|
488
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
489
|
+
"aria-hidden": true,
|
|
490
|
+
className: "w-14 shrink-0 truncate text-label text-fg-3",
|
|
491
|
+
children: label
|
|
492
|
+
}), /* @__PURE__ */ jsx("div", {
|
|
493
|
+
className: "min-w-0 flex-1",
|
|
494
|
+
children
|
|
495
|
+
})]
|
|
496
|
+
});
|
|
497
|
+
}
|
|
445
498
|
function FacetSelect({ label, value, options, onChange }) {
|
|
446
499
|
return /* @__PURE__ */ jsxs("div", {
|
|
447
500
|
className: "flex items-center gap-1",
|
|
@@ -451,8 +504,8 @@ function FacetSelect({ label, value, options, onChange }) {
|
|
|
451
504
|
onValueChange: (v) => onChange(v),
|
|
452
505
|
children: [/* @__PURE__ */ jsx(SelectTrigger, {
|
|
453
506
|
"aria-label": label,
|
|
454
|
-
className: "min-w-
|
|
455
|
-
children: /* @__PURE__ */ jsx(SelectValue, { children: value.length === 0 ?
|
|
507
|
+
className: "min-w-0 flex-1",
|
|
508
|
+
children: /* @__PURE__ */ jsx(SelectValue, { children: value.length === 0 ? "All" : value.length === 1 ? options.find((o) => o.value === value[0])?.label ?? "All" : `${value.length} selected` })
|
|
456
509
|
}), /* @__PURE__ */ jsx(SelectContent, { children: options.map((option) => /* @__PURE__ */ jsx(SelectItem, {
|
|
457
510
|
value: option.value,
|
|
458
511
|
children: /* @__PURE__ */ jsx(SelectItemText, { children: option.label })
|
|
@@ -472,7 +525,7 @@ function OneOfSelect({ label, value, options, onChange }) {
|
|
|
472
525
|
onValueChange: (v) => onChange(v),
|
|
473
526
|
children: [/* @__PURE__ */ jsx(SelectTrigger, {
|
|
474
527
|
"aria-label": label,
|
|
475
|
-
className: "min-w-
|
|
528
|
+
className: "w-full min-w-0",
|
|
476
529
|
children: /* @__PURE__ */ jsx(SelectValue, { children: options.find((o) => o.value === value)?.label ?? label })
|
|
477
530
|
}), /* @__PURE__ */ jsx(SelectContent, { children: options.map((option) => /* @__PURE__ */ jsx(SelectItem, {
|
|
478
531
|
value: option.value,
|
|
@@ -481,6 +534,84 @@ function OneOfSelect({ label, value, options, onChange }) {
|
|
|
481
534
|
});
|
|
482
535
|
}
|
|
483
536
|
//#endregion
|
|
484
|
-
|
|
537
|
+
//#region src/components/agent/EngineIcon.tsx
|
|
538
|
+
/**
|
|
539
|
+
* The engine's own mark, monochrome.
|
|
540
|
+
*
|
|
541
|
+
* Inlined rather than depended on: the React package these come from
|
|
542
|
+
* (`@lobehub/icons`) pulls antd, `@lobehub/ui` and a second copy of
|
|
543
|
+
* lucide-react — an absurd amount of bundle for a few glyphs in a sidebar.
|
|
544
|
+
* These are paths from `@lobehub/icons-static-svg` (MIT, © LobeHub), already
|
|
545
|
+
* `fill="currentColor"` single-path marks, so they take the row's colour like
|
|
546
|
+
* any other glyph and need no light/dark variants.
|
|
547
|
+
*
|
|
548
|
+
* The marks are trademarks of their owners (Anthropic, OpenAI, Google,
|
|
549
|
+
* DeepSeek, Moonshot), used here only to identify which engine a session runs
|
|
550
|
+
* on.
|
|
551
|
+
*
|
|
552
|
+
* Codex is drawn as OpenAI: the session's engine *is* OpenAI's, and OpenAI's
|
|
553
|
+
* mark is the one a person recognises at 12px.
|
|
554
|
+
*/
|
|
555
|
+
const PATHS = {
|
|
556
|
+
claude: {
|
|
557
|
+
title: "Claude",
|
|
558
|
+
d: "M4.709 15.955l4.72-2.647.08-.23-.08-.128H9.2l-.79-.048-2.698-.073-2.339-.097-2.266-.122-.571-.121L0 11.784l.055-.352.48-.321.686.06 1.52.103 2.278.158 1.652.097 2.449.255h.389l.055-.157-.134-.098-.103-.097-2.358-1.596-2.552-1.688-1.336-.972-.724-.491-.364-.462-.158-1.008.656-.722.881.06.225.061.893.686 1.908 1.476 2.491 1.833.365.304.145-.103.019-.073-.164-.274-1.355-2.446-1.446-2.49-.644-1.032-.17-.619a2.97 2.97 0 01-.104-.729L6.283.134 6.696 0l.996.134.42.364.62 1.414 1.002 2.229 1.555 3.03.456.898.243.832.091.255h.158V9.01l.128-1.706.237-2.095.23-2.695.08-.76.376-.91.747-.492.584.28.48.685-.067.444-.286 1.851-.559 2.903-.364 1.942h.212l.243-.242.985-1.306 1.652-2.064.73-.82.85-.904.547-.431h1.033l.76 1.129-.34 1.166-1.064 1.347-.881 1.142-1.264 1.7-.79 1.36.073.11.188-.02 2.856-.606 1.543-.28 1.841-.315.833.388.091.395-.328.807-1.969.486-2.309.462-3.439.813-.042.03.049.061 1.549.146.662.036h1.622l3.02.225.79.522.474.638-.079.485-1.215.62-1.64-.389-3.829-.91-1.312-.329h-.182v.11l1.093 1.068 2.006 1.81 2.509 2.33.127.578-.322.455-.34-.049-2.205-1.657-.851-.747-1.926-1.62h-.128v.17l.444.649 2.345 3.521.122 1.08-.17.353-.608.213-.668-.122-1.374-1.925-1.415-2.167-1.143-1.943-.14.08-.674 7.254-.316.37-.729.28-.607-.461-.322-.747.322-1.476.389-1.924.315-1.53.286-1.9.17-.632-.012-.042-.14.018-1.434 1.967-2.18 2.945-1.726 1.845-.414.164-.717-.37.067-.662.401-.589 2.388-3.036 1.44-1.882.93-1.086-.006-.158h-.055L4.132 18.56l-1.13.146-.487-.456.061-.746.231-.243 1.908-1.312-.006.006z"
|
|
559
|
+
},
|
|
560
|
+
codex: {
|
|
561
|
+
title: "OpenAI",
|
|
562
|
+
d: "M9.205 8.658v-2.26c0-.19.072-.333.238-.428l4.543-2.616c.619-.357 1.356-.523 2.117-.523 2.854 0 4.662 2.212 4.662 4.566 0 .167 0 .357-.024.547l-4.71-2.759a.797.797 0 00-.856 0l-5.97 3.473zm10.609 8.8V12.06c0-.333-.143-.57-.429-.737l-5.97-3.473 1.95-1.118a.433.433 0 01.476 0l4.543 2.617c1.309.76 2.189 2.378 2.189 3.948 0 1.808-1.07 3.473-2.76 4.163zM7.802 12.703l-1.95-1.142c-.167-.095-.239-.238-.239-.428V5.899c0-2.545 1.95-4.472 4.591-4.472 1 0 1.927.333 2.712.928L8.23 5.067c-.285.166-.428.404-.428.737v6.898zM12 15.128l-2.795-1.57v-3.33L12 8.658l2.795 1.57v3.33L12 15.128zm1.796 7.23c-1 0-1.927-.332-2.712-.927l4.686-2.712c.285-.166.428-.404.428-.737v-6.898l1.974 1.142c.167.095.238.238.238.428v5.233c0 2.545-1.974 4.472-4.614 4.472zm-5.637-5.303l-4.544-2.617c-1.308-.761-2.188-2.378-2.188-3.948A4.482 4.482 0 014.21 6.327v5.423c0 .333.143.571.428.738l5.947 3.449-1.95 1.118a.432.432 0 01-.476 0zm-.262 3.9c-2.688 0-4.662-2.021-4.662-4.519 0-.19.024-.38.047-.57l4.686 2.71c.286.167.571.167.856 0l5.97-3.448v2.26c0 .19-.07.333-.237.428l-4.543 2.616c-.619.357-1.356.523-2.117.523zm5.899 2.83a5.947 5.947 0 005.827-4.756C22.287 18.339 24 15.84 24 13.296c0-1.665-.713-3.282-1.998-4.448.119-.5.19-.999.19-1.498 0-3.401-2.759-5.947-5.946-5.947-.642 0-1.26.095-1.88.31A5.962 5.962 0 0010.205 0a5.947 5.947 0 00-5.827 4.757C1.713 5.447 0 7.945 0 10.49c0 1.666.713 3.283 1.998 4.448-.119.5-.19 1-.19 1.499 0 3.401 2.759 5.946 5.946 5.946.642 0 1.26-.095 1.88-.309a5.96 5.96 0 004.162 1.713z"
|
|
563
|
+
},
|
|
564
|
+
gemini: {
|
|
565
|
+
title: "Gemini",
|
|
566
|
+
d: "M20.616 10.835a14.147 14.147 0 01-4.45-3.001 14.111 14.111 0 01-3.678-6.452.503.503 0 00-.975 0 14.134 14.134 0 01-3.679 6.452 14.155 14.155 0 01-4.45 3.001c-.65.28-1.318.505-2.002.678a.502.502 0 000 .975c.684.172 1.35.397 2.002.677a14.147 14.147 0 014.45 3.001 14.112 14.112 0 013.679 6.453.502.502 0 00.975 0c.172-.685.397-1.351.677-2.003a14.145 14.145 0 013.001-4.45 14.113 14.113 0 016.453-3.678.503.503 0 000-.975 13.245 13.245 0 01-2.003-.678z"
|
|
567
|
+
},
|
|
568
|
+
deepseek: {
|
|
569
|
+
title: "DeepSeek",
|
|
570
|
+
d: "M23.748 4.482c-.254-.124-.364.113-.512.234-.051.039-.094.09-.137.136-.372.397-.806.657-1.373.626-.829-.046-1.537.214-2.163.848-.133-.782-.575-1.248-1.247-1.548-.352-.156-.708-.311-.955-.65-.172-.241-.219-.51-.305-.774-.055-.16-.11-.323-.293-.35-.2-.031-.278.136-.356.276-.313.572-.434 1.202-.422 1.84.027 1.436.633 2.58 1.838 3.393.137.093.172.187.129.323-.082.28-.18.552-.266.833-.055.179-.137.217-.329.14a5.526 5.526 0 01-1.736-1.18c-.857-.828-1.631-1.742-2.597-2.458a11.365 11.365 0 00-.689-.471c-.985-.957.13-1.743.388-1.836.27-.098.093-.432-.779-.428-.872.004-1.67.295-2.687.684a3.055 3.055 0 01-.465.137 9.597 9.597 0 00-2.883-.102c-1.885.21-3.39 1.102-4.497 2.623C.082 8.606-.231 10.684.152 12.85c.403 2.284 1.569 4.175 3.36 5.653 1.858 1.533 3.997 2.284 6.438 2.14 1.482-.085 3.133-.284 4.994-1.86.47.234.962.327 1.78.397.63.059 1.236-.03 1.705-.128.735-.156.684-.837.419-.961-2.155-1.004-1.682-.595-2.113-.926 1.096-1.296 2.746-2.642 3.392-7.003.05-.347.007-.565 0-.845-.004-.17.035-.237.23-.256a4.173 4.173 0 001.545-.475c1.396-.763 1.96-2.015 2.093-3.517.02-.23-.004-.467-.247-.588zM11.581 18c-2.089-1.642-3.102-2.183-3.52-2.16-.392.024-.321.471-.235.763.09.288.207.486.371.739.114.167.192.416-.113.603-.673.416-1.842-.14-1.897-.167-1.361-.802-2.5-1.86-3.301-3.307-.774-1.393-1.224-2.887-1.298-4.482-.02-.386.093-.522.477-.592a4.696 4.696 0 011.529-.039c2.132.312 3.946 1.265 5.468 2.774.868.86 1.525 1.887 2.202 2.891.72 1.066 1.494 2.082 2.48 2.914.348.292.625.514.891.677-.802.09-2.14.11-3.054-.614zm1-6.44a.306.306 0 01.415-.287.302.302 0 01.2.288.306.306 0 01-.31.307.303.303 0 01-.304-.308zm3.11 1.596c-.2.081-.399.151-.59.16a1.245 1.245 0 01-.798-.254c-.274-.23-.47-.358-.552-.758a1.73 1.73 0 01.016-.588c.07-.327-.008-.537-.239-.727-.187-.156-.426-.199-.688-.199a.559.559 0 01-.254-.078c-.11-.054-.2-.19-.114-.358.028-.054.16-.186.192-.21.356-.202.767-.136 1.146.016.352.144.618.408 1.001.782.391.451.462.576.685.914.176.265.336.537.445.848.067.195-.019.354-.25.452z"
|
|
571
|
+
},
|
|
572
|
+
moonshot: {
|
|
573
|
+
title: "Moonshot",
|
|
574
|
+
d: "M1.052 16.916l9.539 2.552a21.007 21.007 0 00.06 2.033l5.956 1.593a11.997 11.997 0 01-5.586.865l-.18-.016-.044-.004-.084-.009-.094-.01a11.605 11.605 0 01-.157-.02l-.107-.014-.11-.016a11.962 11.962 0 01-.32-.051l-.042-.008-.075-.013-.107-.02-.07-.015-.093-.019-.075-.016-.095-.02-.097-.023-.094-.022-.068-.017-.088-.022-.09-.024-.095-.025-.082-.023-.109-.03-.062-.02-.084-.025-.093-.028-.105-.034-.058-.019-.08-.026-.09-.031-.066-.024a6.293 6.293 0 01-.044-.015l-.068-.025-.101-.037-.057-.022-.08-.03-.087-.035-.088-.035-.079-.032-.095-.04-.063-.028-.063-.027a5.655 5.655 0 01-.041-.018l-.066-.03-.103-.047-.052-.024-.096-.046-.062-.03-.084-.04-.086-.044-.093-.047-.052-.027-.103-.055-.057-.03-.058-.032a6.49 6.49 0 01-.046-.026l-.094-.053-.06-.034-.051-.03-.072-.041-.082-.05-.093-.056-.052-.032-.084-.053-.061-.039-.079-.05-.07-.047-.053-.035a7.785 7.785 0 01-.054-.036l-.044-.03-.044-.03a6.066 6.066 0 01-.04-.028l-.057-.04-.076-.054-.069-.05-.074-.054-.056-.042-.076-.057-.076-.059-.086-.067-.045-.035-.064-.052-.074-.06-.089-.073-.046-.039-.046-.039a7.516 7.516 0 01-.043-.037l-.045-.04-.061-.053-.07-.062-.068-.06-.062-.058-.067-.062-.053-.05-.088-.084a13.28 13.28 0 01-.099-.097l-.029-.028-.041-.042-.069-.07-.05-.051-.05-.053a6.457 6.457 0 01-.168-.179l-.08-.088-.062-.07-.071-.08-.042-.049-.053-.062-.058-.068-.046-.056a7.175 7.175 0 01-.027-.033l-.045-.055-.066-.082-.041-.052-.05-.064-.02-.025a11.99 11.99 0 01-1.44-2.402zm-1.02-5.794l11.353 3.037a20.468 20.468 0 00-.469 2.011l10.817 2.894a12.076 12.076 0 01-1.845 2.005L.657 15.923l-.016-.046-.035-.104a11.965 11.965 0 01-.05-.153l-.007-.023a11.896 11.896 0 01-.207-.741l-.03-.126-.018-.08-.021-.097-.018-.081-.018-.09-.017-.084-.018-.094c-.026-.141-.05-.283-.071-.426l-.017-.118-.011-.083-.013-.102a12.01 12.01 0 01-.019-.161l-.005-.047a12.12 12.12 0 01-.034-2.145zm1.593-5.15l11.948 3.196c-.368.605-.705 1.231-1.01 1.875l11.295 3.022c-.142.82-.368 1.612-.668 2.365l-11.55-3.09L.124 10.26l.015-.1.008-.049.01-.067.015-.087.018-.098c.026-.148.056-.295.088-.442l.028-.124.02-.085.024-.097c.022-.09.045-.18.07-.268l.028-.102.023-.083.03-.1.025-.082.03-.096.026-.082.031-.095a11.896 11.896 0 011.01-2.232zm4.442-4.4L17.352 4.59a20.77 20.77 0 00-1.688 1.721l7.823 2.093c.267.852.442 1.744.513 2.665L2.106 5.213l.045-.065.027-.04.04-.055.046-.065.055-.076.054-.072.064-.086.05-.065.057-.073.055-.07.06-.074.055-.069.065-.077.054-.066.066-.077.053-.06.072-.082.053-.06.067-.074.054-.058.073-.078.058-.06.063-.067.168-.17.1-.098.059-.056.076-.071a12.084 12.084 0 012.272-1.677zM12.017 0h.097l.082.001.069.001.054.002.068.002.046.001.076.003.047.002.06.003.054.002.087.005.105.007.144.011.088.007.044.004.077.008.082.008.047.005.102.012.05.006.108.014.081.01.042.006.065.01.207.032.07.012.065.011.14.026.092.018.11.022.046.01.075.016.041.01L14.7.3l.042.01.065.015.049.012.071.017.096.024.112.03.113.03.113.032.05.015.07.02.078.024.073.023.05.016.05.016.076.025.099.033.102.036.048.017.064.023.093.034.11.041.116.045.1.04.047.02.06.024.041.018.063.026.04.018.057.025.11.048.1.046.074.035.075.036.06.028.092.046.091.045.102.052.053.028.049.026.046.024.06.033.041.022.052.029.088.05.106.06.087.051.057.034.053.032.096.059.088.055.098.062.036.024.064.041.084.056.04.027.062.042.062.043.023.017c.054.037.108.075.161.114l.083.06.065.048.056.043.086.065.082.064.04.03.05.041.086.069.079.065.085.071c.712.6 1.353 1.283 1.909 2.031L7.222.994l.062-.027.065-.028.081-.034.086-.035c.113-.045.227-.09.341-.131l.096-.035.093-.033.084-.03.096-.031c.087-.03.176-.058.264-.085l.091-.027.086-.025.102-.03.085-.023.1-.026L9.04.37l.09-.023.091-.022.095-.022.09-.02.098-.021.091-.02.095-.018.092-.018.1-.018.091-.016.098-.017.092-.014.097-.015.092-.013.102-.013.091-.012.105-.012.09-.01.105-.01c.093-.01.186-.018.28-.024l.106-.008.09-.005.11-.006.093-.004.1-.004.097-.002.099-.002.197-.002z"
|
|
575
|
+
}
|
|
576
|
+
};
|
|
577
|
+
/**
|
|
578
|
+
* Which mark a session wears.
|
|
579
|
+
*
|
|
580
|
+
* The two first-party engines are named directly. A `provider` session is
|
|
581
|
+
* whatever the host wired up, so its *model* is the only thing that says whose
|
|
582
|
+
* it is — sniffed loosely on purpose (`gemini-2.5-pro`, `deepseek-chat`,
|
|
583
|
+
* `kimi-k2`), and falling through to no mark rather than guessing wrong.
|
|
584
|
+
*/
|
|
585
|
+
function engineMark(engine, model) {
|
|
586
|
+
if (engine === "claude") return "claude";
|
|
587
|
+
if (engine === "codex") return "codex";
|
|
588
|
+
const id = model?.toLowerCase() ?? "";
|
|
589
|
+
if (!id) return void 0;
|
|
590
|
+
if (id.includes("gemini")) return "gemini";
|
|
591
|
+
if (id.includes("deepseek")) return "deepseek";
|
|
592
|
+
if (id.includes("moonshot") || id.includes("kimi")) return "moonshot";
|
|
593
|
+
if (id.includes("claude")) return "claude";
|
|
594
|
+
if (id.startsWith("gpt") || id.startsWith("o1") || id.startsWith("o3") || id.includes("openai")) return "codex";
|
|
595
|
+
}
|
|
596
|
+
function EngineIcon({ engine, model, className }) {
|
|
597
|
+
const mark = PATHS[engineMark(engine, model) ?? ""];
|
|
598
|
+
if (!mark) return /* @__PURE__ */ jsx("span", {
|
|
599
|
+
"aria-hidden": true,
|
|
600
|
+
title: engine,
|
|
601
|
+
className: cn("shrink-0 text-fg-3", className),
|
|
602
|
+
children: "·"
|
|
603
|
+
});
|
|
604
|
+
return /* @__PURE__ */ jsxs("svg", {
|
|
605
|
+
viewBox: "0 0 24 24",
|
|
606
|
+
fill: "currentColor",
|
|
607
|
+
fillRule: "evenodd",
|
|
608
|
+
role: "img",
|
|
609
|
+
"aria-label": mark.title,
|
|
610
|
+
className: cn("size-3 shrink-0 text-fg-3", className),
|
|
611
|
+
children: [/* @__PURE__ */ jsx("title", { children: mark.title }), /* @__PURE__ */ jsx("path", { d: mark.d })]
|
|
612
|
+
});
|
|
613
|
+
}
|
|
614
|
+
//#endregion
|
|
615
|
+
export { AlertDialog, AlertDialogClose, AlertDialogContent, AlertDialogDescription, AlertDialogTitle, AlertDialogTrigger, Badge, Button, Card, CardContent, CardHeader, CardTitle, CodeBlock, Composer, ContextDialog, Conversation, ConversationContent, ConversationScrollButton, CopyButton, Dialog, DialogBody, DialogClose, DialogContent, DialogHeader, DialogRow, DialogTrigger, EngineIcon, FileCard, HostFilesDialog, Input, Loader, McpDialog, Menu, MenuContent, MenuItem, MenuSeparator, MenuTrigger, Message, MessageContent, ModelSelect, PERMISSION_MODES, PermissionModeSelect, PermissionPrompt, ProgressRing, PromptArea, PromptTokenText, QUESTION_BEHAVIORS, QuestionPrompt, Reasoning, Response, STATUS_META, Select, SelectContent, SelectItem, SelectItemText, SelectTrigger, SelectValue, SessionBrowser, SessionEmptyState, SessionInfoDialog, SessionList, SessionListItem, SessionPanel, SessionStatusIcon, SkillsDialog, Spinner, Splitter, StatusBar, Textarea, Tip, Toaster, ToolCallCard, TooltipContent, TooltipProvider, Transcript, TranscriptDensityProvider, TranscriptVariantProvider, UsageDialog, badgeVariants, buttonVariants, cn, commandTrigger, copyText, formatAgoPrecise, formatBytes, formatCost, formatCountdown, formatDuration, formatRateLimitWindow, formatRateLimitWindowLong, formatRelativeTime, formatTokens, friendlyModel, getChipsByTrigger, hashtagTrigger, isMutatingTool, isSegmentsEmpty, mentionTrigger, parseUserQuestions, permissionModeChoices, permissionModeMeta, plainTextToSegments, rateLimitWindowSeconds, rowShapeClass, segmentsToPlainText, skillPrompt, toast, toolIcon, toolInputPreview, usePromptAreaState, useTranscriptDensity, useTranscriptVariant };
|
|
485
616
|
|
|
486
617
|
//# sourceMappingURL=index.mjs.map
|