@tangle-network/sandbox-ui 0.106.0 → 0.108.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.
@@ -1,6 +1,3 @@
1
- import {
2
- formatBytes
3
- } from "./chunk-TK46XFLM.js";
4
1
  import {
5
2
  cn
6
3
  } from "./chunk-EI44GEQ5.js";
@@ -145,504 +142,17 @@ function ReasoningLevelPicker({
145
142
  ] });
146
143
  }
147
144
 
148
- // src/chat/agent-composer.tsx
149
- import {
150
- ArrowUp,
151
- Folder,
152
- Loader2,
153
- Paperclip,
154
- RotateCcw,
155
- Square,
156
- Upload,
157
- X
158
- } from "lucide-react";
159
- import * as React from "react";
160
-
161
- // src/chat/attachment-validation.ts
162
- function isAcceptedType(file, accept) {
163
- if (!accept || accept.trim().length === 0) return true;
164
- const patterns = accept.split(",").map((pattern) => pattern.trim()).filter((pattern) => pattern.length > 0);
165
- if (patterns.length === 0) return true;
166
- const name = file.name.toLowerCase();
167
- const type = (file.type || "").toLowerCase();
168
- return patterns.some((pattern) => {
169
- const lowerPattern = pattern.toLowerCase();
170
- if (lowerPattern.startsWith(".")) {
171
- return name.endsWith(lowerPattern);
172
- }
173
- if (lowerPattern.endsWith("/*")) {
174
- const prefix = lowerPattern.slice(0, -1);
175
- return type.startsWith(prefix);
176
- }
177
- return type === lowerPattern;
178
- });
179
- }
180
- function validateComposerFiles(files, config) {
181
- const { maxSizeBytes, maxCount, currentCount = 0, accept } = config;
182
- const list = Array.isArray(files) ? files : Array.from(files);
183
- const accepted = [];
184
- const rejected = [];
185
- for (const file of list) {
186
- if (!isAcceptedType(file, accept)) {
187
- rejected.push({
188
- file,
189
- reason: `"${file.name}" is not an accepted file type (${accept}).`
190
- });
191
- continue;
192
- }
193
- if (maxSizeBytes !== void 0 && file.size > maxSizeBytes) {
194
- rejected.push({
195
- file,
196
- reason: `"${file.name}" (${formatBytes(file.size)}) exceeds the ${formatBytes(maxSizeBytes)} limit.`
197
- });
198
- continue;
199
- }
200
- if (maxCount !== void 0 && currentCount + accepted.length >= maxCount) {
201
- rejected.push({
202
- file,
203
- reason: `"${file.name}" was not added \u2014 the ${maxCount}-file limit is already reached.`
204
- });
205
- continue;
206
- }
207
- accepted.push(file);
208
- }
209
- return { accepted, rejected };
210
- }
211
-
212
- // src/chat/agent-composer.tsx
213
- import { Fragment, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
214
- var IMAGE_EXTENSION_BY_MIME = {
215
- "image/png": "png",
216
- "image/jpeg": "jpg",
217
- "image/jpg": "jpg",
218
- "image/gif": "gif",
219
- "image/webp": "webp",
220
- "image/bmp": "bmp",
221
- "image/svg+xml": "svg"
222
- };
223
- function isGenericImageName(name) {
224
- return /^(image)?(\.[a-z0-9]+)?$/i.test(name.trim());
225
- }
226
- function imageExtension(file) {
227
- const fromMime = IMAGE_EXTENSION_BY_MIME[file.type.toLowerCase()];
228
- if (fromMime) return fromMime;
229
- const fromName = /\.([a-z0-9]+)$/i.exec(file.name)?.[1];
230
- return fromName?.toLowerCase() ?? "png";
231
- }
232
- var MentionEditor = React.lazy(() => import("./mention-editor-Q3TKSZDL.js"));
233
- function AgentComposer({
234
- value,
235
- onChange,
236
- onSubmit,
237
- placeholder = "Send a message\u2026",
238
- disabled,
239
- busy,
240
- onCancel,
241
- controls,
242
- trailing,
243
- contextItems = [],
244
- onAttach,
245
- onAttachFolder,
246
- attachments = [],
247
- onRemoveFile,
248
- onRetryFile,
249
- accept,
250
- onRejectFiles,
251
- dropTitle = "Drop files to add context",
252
- dropDescription = "They attach to your next message.",
253
- canSubmitWhileBusy = false,
254
- canSubmitAttachmentsOnly = false,
255
- mention,
256
- focusShortcut = false,
257
- minRows = 2,
258
- maxHeight = 200,
259
- className,
260
- sendLabel = "Send",
261
- autoFocus
262
- }) {
263
- const textareaRef = React.useRef(null);
264
- const richFocusRef = React.useRef(null);
265
- const fileInputRef = React.useRef(null);
266
- const folderInputRef = React.useRef(null);
267
- const [dragOver, setDragOver] = React.useState(false);
268
- const dragDepth = React.useRef(0);
269
- const pastedImageCount = React.useRef(0);
270
- const resize = React.useCallback(
271
- (el) => {
272
- el.style.height = "auto";
273
- el.style.height = `${Math.min(el.scrollHeight, maxHeight)}px`;
274
- },
275
- [maxHeight]
276
- );
277
- React.useEffect(() => {
278
- if (textareaRef.current) resize(textareaRef.current);
279
- }, [value, resize]);
280
- React.useEffect(() => {
281
- if (!focusShortcut || disabled) return;
282
- function onKeyDown(event) {
283
- if ((event.metaKey || event.ctrlKey) && event.key.toLowerCase() === "l") {
284
- event.preventDefault();
285
- if (mention) richFocusRef.current?.();
286
- else textareaRef.current?.focus();
287
- }
288
- }
289
- document.addEventListener("keydown", onKeyDown);
290
- return () => document.removeEventListener("keydown", onKeyDown);
291
- }, [focusShortcut, disabled, mention]);
292
- const canSend = !disabled && (!busy || canSubmitWhileBusy) && (value.trim().length > 0 || canSubmitAttachmentsOnly && attachments.length > 0);
293
- const submit = () => {
294
- if (!canSend) return;
295
- onSubmit();
296
- };
297
- const registerRichFocus = React.useCallback((focus) => {
298
- richFocusRef.current = focus;
299
- }, []);
300
- const dropEnabled = Boolean(onAttach);
301
- const handleDragEnter = (event) => {
302
- if (!dropEnabled) return;
303
- event.preventDefault();
304
- event.stopPropagation();
305
- dragDepth.current++;
306
- if (event.dataTransfer?.types.includes("Files")) setDragOver(true);
307
- };
308
- const handleDragLeave = (event) => {
309
- if (!dropEnabled) return;
310
- event.preventDefault();
311
- event.stopPropagation();
312
- dragDepth.current--;
313
- if (dragDepth.current <= 0) {
314
- dragDepth.current = 0;
315
- setDragOver(false);
316
- }
317
- };
318
- const handleDragOver = (event) => {
319
- if (!dropEnabled) return;
320
- event.preventDefault();
321
- event.stopPropagation();
322
- if (event.dataTransfer) event.dataTransfer.dropEffect = "copy";
323
- };
324
- const deliverFiles = (files) => {
325
- if (!onAttach || files.length === 0) return;
326
- const { accepted, rejected } = validateComposerFiles(files, { accept });
327
- if (rejected.length > 0) onRejectFiles?.(rejected);
328
- if (accepted.length === 0) return;
329
- const dt = new DataTransfer();
330
- for (const file of accepted) dt.items.add(file);
331
- onAttach(dt.files);
332
- };
333
- const handleDrop = (event) => {
334
- if (!dropEnabled) return;
335
- event.preventDefault();
336
- event.stopPropagation();
337
- dragDepth.current = 0;
338
- setDragOver(false);
339
- const files = event.dataTransfer?.files;
340
- if (files?.length) deliverFiles(Array.from(files));
341
- };
342
- const renamePastedFiles = (files) => files.map((file) => {
343
- if (file.type.startsWith("image/") && isGenericImageName(file.name)) {
344
- pastedImageCount.current += 1;
345
- return new File(
346
- [file],
347
- `pasted-image-${pastedImageCount.current}.${imageExtension(file)}`,
348
- { type: file.type }
349
- );
350
- }
351
- return file;
352
- });
353
- const handlePaste = (event) => {
354
- if (!onAttach) return;
355
- const clipboardFiles = event.clipboardData?.files;
356
- if (!clipboardFiles || clipboardFiles.length === 0) return;
357
- event.preventDefault();
358
- deliverFiles(renamePastedFiles(Array.from(clipboardFiles)));
359
- };
360
- const handleEditorPasteFiles = (clipboardFiles) => {
361
- if (!onAttach || clipboardFiles.length === 0) return false;
362
- deliverFiles(renamePastedFiles(Array.from(clipboardFiles)));
363
- return true;
364
- };
365
- const folderChips = attachments.filter((file) => file.kind === "folder");
366
- const fileChips = attachments.filter((file) => file.kind !== "folder");
367
- const attachButtonClass = cn(
368
- "flex size-8 shrink-0 items-center justify-center rounded-lg text-muted-foreground transition-colors",
369
- "hover:bg-surface-container-highest hover:text-foreground focus:outline-none focus-visible:ring-1 focus-visible:ring-ring",
370
- "disabled:cursor-not-allowed disabled:opacity-50"
371
- );
372
- return /* @__PURE__ */ jsxs2("div", { className: cn("relative", className), children: [
373
- dragOver && /* @__PURE__ */ jsx2("div", { className: "pointer-events-none absolute inset-0 z-10 flex items-center justify-center rounded-2xl border-2 border-dashed border-primary/50 bg-surface-container-high/95", children: /* @__PURE__ */ jsxs2("div", { className: "text-center", children: [
374
- /* @__PURE__ */ jsx2("span", { className: "mx-auto mb-2 flex size-11 items-center justify-center rounded-xl bg-primary/10 text-primary", children: /* @__PURE__ */ jsx2(Upload, { className: "size-5" }) }),
375
- /* @__PURE__ */ jsx2("p", { className: "font-semibold text-foreground text-sm", children: dropTitle }),
376
- /* @__PURE__ */ jsx2("p", { className: "mt-0.5 text-muted-foreground text-xs", children: dropDescription })
377
- ] }) }),
378
- /* @__PURE__ */ jsxs2(
379
- "div",
380
- {
381
- "data-testid": "agent-composer",
382
- onDragEnter: handleDragEnter,
383
- onDragLeave: handleDragLeave,
384
- onDragOver: handleDragOver,
385
- onDrop: handleDrop,
386
- className: cn(
387
- "flex flex-col gap-2 rounded-2xl border border-[var(--md3-outline-variant)] bg-surface-container-high p-2.5 shadow-sm transition-colors",
388
- "focus-within:border-primary/60",
389
- disabled && "opacity-60"
390
- ),
391
- children: [
392
- contextItems.length > 0 && /* @__PURE__ */ jsx2(
393
- "div",
394
- {
395
- "aria-label": "Message context",
396
- className: "flex min-w-0 flex-wrap gap-1.5",
397
- children: contextItems.map((item) => /* @__PURE__ */ jsxs2(
398
- "span",
399
- {
400
- className: "inline-flex min-w-0 max-w-full items-center gap-1.5 rounded-md border border-primary/30 bg-primary/10 px-2.5 py-1 text-primary text-xs",
401
- children: [
402
- item.icon && /* @__PURE__ */ jsx2("span", { className: "shrink-0", "aria-hidden": "true", children: item.icon }),
403
- /* @__PURE__ */ jsx2("span", { className: "min-w-0 truncate", children: item.label }),
404
- item.onRemove && /* @__PURE__ */ jsx2(
405
- "button",
406
- {
407
- type: "button",
408
- "aria-label": `Remove context ${item.label}`,
409
- onClick: item.onRemove,
410
- className: "shrink-0 rounded p-0.5 text-primary/70 transition-colors hover:text-primary focus:outline-none focus-visible:ring-1 focus-visible:ring-ring",
411
- children: /* @__PURE__ */ jsx2(X, { className: "size-3" })
412
- }
413
- )
414
- ]
415
- },
416
- item.id
417
- ))
418
- }
419
- ),
420
- attachments.length > 0 && /* @__PURE__ */ jsx2("div", { className: "flex flex-wrap gap-1.5", children: [...folderChips, ...fileChips].map((file) => {
421
- const isError = file.status === "error";
422
- const isPending = file.status === "pending";
423
- return /* @__PURE__ */ jsxs2(
424
- "span",
425
- {
426
- title: isError ? file.errorMessage : void 0,
427
- className: cn(
428
- "inline-flex items-center gap-1.5 rounded-full border px-2.5 py-1 text-xs",
429
- isError ? "border-[var(--status-error,#ff4d6d)]/40 text-[var(--status-error,#ff4d6d)]" : "border-[var(--md3-outline-variant)] bg-surface-container text-foreground",
430
- isPending && "opacity-60"
431
- ),
432
- children: [
433
- file.kind !== "folder" && file.previewUrl ? /* @__PURE__ */ jsx2(
434
- "img",
435
- {
436
- src: file.previewUrl,
437
- alt: "",
438
- className: "size-8 rounded object-cover"
439
- }
440
- ) : file.kind === "folder" ? /* @__PURE__ */ jsx2(Folder, { className: "size-3 shrink-0" }) : /* @__PURE__ */ jsx2(Paperclip, { className: "size-3 shrink-0" }),
441
- /* @__PURE__ */ jsx2("span", { className: "max-w-[150px] truncate", children: file.name }),
442
- file.fileCount !== void 0 && /* @__PURE__ */ jsxs2("span", { className: "text-muted-foreground", children: [
443
- "(",
444
- file.fileCount,
445
- ")"
446
- ] }),
447
- file.status === "uploading" && /* @__PURE__ */ jsx2(Loader2, { className: "size-3 animate-spin", "data-motion": "essential" }),
448
- isError && file.errorMessage && /* @__PURE__ */ jsx2("span", { className: "max-w-[150px] truncate text-[var(--status-error,#ff4d6d)]/80", children: file.errorMessage }),
449
- isError && onRetryFile && /* @__PURE__ */ jsx2(
450
- "button",
451
- {
452
- type: "button",
453
- "aria-label": `Retry upload ${file.name}`,
454
- onClick: () => onRetryFile(file.id),
455
- className: "rounded p-0.5 text-muted-foreground transition-colors hover:text-foreground focus:outline-none focus-visible:ring-1 focus-visible:ring-ring",
456
- children: /* @__PURE__ */ jsx2(RotateCcw, { className: "size-3" })
457
- }
458
- ),
459
- onRemoveFile && /* @__PURE__ */ jsx2(
460
- "button",
461
- {
462
- type: "button",
463
- "aria-label": `Remove ${file.name}`,
464
- onClick: () => onRemoveFile(file.id),
465
- className: "rounded p-0.5 text-muted-foreground transition-colors hover:text-foreground focus:outline-none focus-visible:ring-1 focus-visible:ring-ring",
466
- children: /* @__PURE__ */ jsx2(X, { className: "size-3" })
467
- }
468
- )
469
- ]
470
- },
471
- file.id
472
- );
473
- }) }),
474
- mention ? /* @__PURE__ */ jsx2(
475
- React.Suspense,
476
- {
477
- fallback: /* @__PURE__ */ jsx2(
478
- "textarea",
479
- {
480
- rows: minRows,
481
- value,
482
- disabled: true,
483
- placeholder,
484
- "aria-label": "Message input",
485
- className: cn(
486
- "w-full resize-none bg-transparent px-2 py-1 text-sm leading-relaxed text-foreground outline-none",
487
- "placeholder:text-muted-foreground"
488
- )
489
- }
490
- ),
491
- children: /* @__PURE__ */ jsx2(
492
- MentionEditor,
493
- {
494
- value,
495
- onChange,
496
- onSubmit: submit,
497
- placeholder,
498
- disabled,
499
- autoFocus,
500
- minRows,
501
- maxHeight,
502
- mention,
503
- registerFocus: registerRichFocus,
504
- onPasteFiles: onAttach ? handleEditorPasteFiles : void 0
505
- }
506
- )
507
- }
508
- ) : /* @__PURE__ */ jsx2(
509
- "textarea",
510
- {
511
- ref: textareaRef,
512
- rows: minRows,
513
- value,
514
- disabled,
515
- autoFocus,
516
- onChange: (event) => onChange(event.target.value),
517
- onInput: (event) => resize(event.currentTarget),
518
- onPaste: handlePaste,
519
- onKeyDown: (event) => {
520
- if (event.key === "Enter" && !event.shiftKey && !event.nativeEvent.isComposing && event.keyCode !== 229) {
521
- event.preventDefault();
522
- submit();
523
- }
524
- },
525
- placeholder,
526
- "aria-label": "Message input",
527
- className: cn(
528
- "w-full resize-none bg-transparent px-2 py-1 text-sm leading-relaxed text-foreground outline-none",
529
- "placeholder:text-muted-foreground"
530
- )
531
- }
532
- ),
533
- /* @__PURE__ */ jsxs2("div", { className: "flex items-end gap-2", children: [
534
- onAttach && /* @__PURE__ */ jsxs2(Fragment, { children: [
535
- /* @__PURE__ */ jsx2(
536
- "button",
537
- {
538
- type: "button",
539
- onClick: () => fileInputRef.current?.click(),
540
- disabled,
541
- "aria-label": "Attach files",
542
- title: "Attach files",
543
- className: attachButtonClass,
544
- children: /* @__PURE__ */ jsx2(Paperclip, { className: "size-4" })
545
- }
546
- ),
547
- /* @__PURE__ */ jsx2(
548
- "input",
549
- {
550
- ref: fileInputRef,
551
- type: "file",
552
- multiple: true,
553
- className: "hidden",
554
- accept,
555
- onChange: (event) => {
556
- if (event.target.files?.length)
557
- deliverFiles(Array.from(event.target.files));
558
- event.target.value = "";
559
- }
560
- }
561
- )
562
- ] }),
563
- onAttachFolder && /* @__PURE__ */ jsxs2(Fragment, { children: [
564
- /* @__PURE__ */ jsx2(
565
- "button",
566
- {
567
- type: "button",
568
- onClick: () => folderInputRef.current?.click(),
569
- disabled,
570
- "aria-label": "Attach folder",
571
- title: "Attach folder",
572
- className: attachButtonClass,
573
- children: /* @__PURE__ */ jsx2(Folder, { className: "size-4" })
574
- }
575
- ),
576
- /* @__PURE__ */ jsx2(
577
- "input",
578
- {
579
- ref: folderInputRef,
580
- type: "file",
581
- multiple: true,
582
- className: "hidden",
583
- onChange: (event) => {
584
- if (event.target.files?.length)
585
- (onAttachFolder ?? onAttach)?.(event.target.files);
586
- event.target.value = "";
587
- },
588
- ...{ webkitdirectory: "" }
589
- }
590
- )
591
- ] }),
592
- /* @__PURE__ */ jsxs2("div", { className: "flex min-w-0 flex-1 items-center gap-2 overflow-x-auto overscroll-x-contain [-ms-overflow-style:none] [scrollbar-width:none] [&::-webkit-scrollbar]:hidden", children: [
593
- controls,
594
- trailing && /* @__PURE__ */ jsx2("div", { className: "ml-auto flex shrink-0 items-center gap-2", children: trailing })
595
- ] }),
596
- busy && onCancel ? /* @__PURE__ */ jsx2(
597
- "button",
598
- {
599
- type: "button",
600
- onClick: onCancel,
601
- "aria-label": "Stop response",
602
- className: cn(
603
- "flex size-9 shrink-0 items-center justify-center rounded-full",
604
- "bg-[var(--status-error,#ff4d6d)]/15 text-[var(--status-error,#ff4d6d)] transition-colors",
605
- "hover:bg-[var(--status-error,#ff4d6d)]/25"
606
- ),
607
- children: /* @__PURE__ */ jsx2(Square, { className: "size-3.5 fill-current" })
608
- }
609
- ) : /* @__PURE__ */ jsx2(
610
- "button",
611
- {
612
- type: "button",
613
- onClick: submit,
614
- disabled: !canSend,
615
- "aria-label": sendLabel,
616
- className: cn(
617
- "flex size-9 shrink-0 items-center justify-center rounded-full bg-primary text-primary-foreground",
618
- "transition-opacity hover:opacity-90 disabled:opacity-40"
619
- ),
620
- children: busy ? /* @__PURE__ */ jsx2(Loader2, { className: "size-4 animate-spin", "data-motion": "essential" }) : /* @__PURE__ */ jsx2(ArrowUp, { className: "size-4" })
621
- }
622
- )
623
- ] })
624
- ]
625
- }
626
- ),
627
- focusShortcut && /* @__PURE__ */ jsx2("div", { className: "mt-1.5 flex justify-end px-1", children: /* @__PURE__ */ jsxs2("span", { className: "text-muted-foreground text-xs", children: [
628
- /* @__PURE__ */ jsx2("kbd", { className: "rounded border border-[var(--md3-outline-variant)] bg-surface-container px-1 py-0.5 text-[10px]", children: "Cmd" }),
629
- /* @__PURE__ */ jsx2("kbd", { className: "ml-0.5 rounded border border-[var(--md3-outline-variant)] bg-surface-container px-1 py-0.5 text-[10px]", children: "L" }),
630
- /* @__PURE__ */ jsx2("span", { className: "ml-1", children: "to focus" })
631
- ] }) })
632
- ] });
633
- }
634
-
635
145
  // src/chat/agent-profile-picker.tsx
636
146
  import { Bot, Check, ChevronDown as ChevronDown2, Pencil, Plus as Plus2, Trash2 } from "lucide-react";
637
- import * as React5 from "react";
147
+ import * as React4 from "react";
638
148
 
639
149
  // src/lib/use-click-outside.ts
640
- import * as React2 from "react";
150
+ import * as React from "react";
641
151
  function useClickOutside(onOutside, extras) {
642
- const ref = React2.useRef(null);
643
- const extrasRef = React2.useRef(extras);
152
+ const ref = React.useRef(null);
153
+ const extrasRef = React.useRef(extras);
644
154
  extrasRef.current = extras;
645
- React2.useEffect(() => {
155
+ React.useEffect(() => {
646
156
  function handler(event) {
647
157
  const target = event.target;
648
158
  if (!ref.current || ref.current.contains(target)) return;
@@ -656,19 +166,19 @@ function useClickOutside(onOutside, extras) {
656
166
  }
657
167
 
658
168
  // src/chat/anchored-popover.tsx
659
- import * as React3 from "react";
169
+ import * as React2 from "react";
660
170
  import { createPortal } from "react-dom";
661
- import { jsx as jsx3 } from "react/jsx-runtime";
662
- var AnchoredPopover = React3.forwardRef(
171
+ import { jsx as jsx2 } from "react/jsx-runtime";
172
+ var AnchoredPopover = React2.forwardRef(
663
173
  function AnchoredPopover2({ anchorRef, side, children, className, style, ...rest }, forwardedRef) {
664
- const innerRef = React3.useRef(null);
174
+ const innerRef = React2.useRef(null);
665
175
  const setRefs = (node) => {
666
176
  innerRef.current = node;
667
177
  if (typeof forwardedRef === "function") forwardedRef(node);
668
178
  else if (forwardedRef) forwardedRef.current = node;
669
179
  };
670
- const [position, setPosition] = React3.useState(null);
671
- const place = React3.useCallback(() => {
180
+ const [position, setPosition] = React2.useState(null);
181
+ const place = React2.useCallback(() => {
672
182
  const anchor = anchorRef.current;
673
183
  if (!anchor) return;
674
184
  const rect = anchor.getBoundingClientRect();
@@ -682,7 +192,7 @@ var AnchoredPopover = React3.forwardRef(
682
192
  side === "top" ? { left, bottom: window.innerHeight - rect.top + margin } : { left, top: rect.bottom + margin }
683
193
  );
684
194
  }, [anchorRef, side]);
685
- React3.useLayoutEffect(() => {
195
+ React2.useLayoutEffect(() => {
686
196
  place();
687
197
  window.addEventListener("resize", place);
688
198
  window.addEventListener("scroll", place, true);
@@ -692,7 +202,7 @@ var AnchoredPopover = React3.forwardRef(
692
202
  };
693
203
  }, [place]);
694
204
  return createPortal(
695
- /* @__PURE__ */ jsx3(
205
+ /* @__PURE__ */ jsx2(
696
206
  "div",
697
207
  {
698
208
  ...rest,
@@ -713,8 +223,8 @@ var AnchoredPopover = React3.forwardRef(
713
223
 
714
224
  // src/chat/informative-lock.tsx
715
225
  import { Lock, Plus } from "lucide-react";
716
- import * as React4 from "react";
717
- import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
226
+ import * as React3 from "react";
227
+ import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
718
228
  function InformativeLock({
719
229
  children,
720
230
  ariaLabel,
@@ -727,22 +237,22 @@ function InformativeLock({
727
237
  popoverClassName,
728
238
  side = "top"
729
239
  }) {
730
- const [open, setOpen] = React4.useState(false);
731
- const closeTimer = React4.useRef(null);
732
- const popoverRef = React4.useRef(null);
240
+ const [open, setOpen] = React3.useState(false);
241
+ const closeTimer = React3.useRef(null);
242
+ const popoverRef = React3.useRef(null);
733
243
  const ref = useClickOutside(() => setOpen(false), [popoverRef]);
734
- const cancelClose = React4.useCallback(() => {
244
+ const cancelClose = React3.useCallback(() => {
735
245
  if (closeTimer.current) {
736
246
  clearTimeout(closeTimer.current);
737
247
  closeTimer.current = null;
738
248
  }
739
249
  }, []);
740
- const scheduleClose = React4.useCallback(() => {
250
+ const scheduleClose = React3.useCallback(() => {
741
251
  cancelClose();
742
252
  closeTimer.current = setTimeout(() => setOpen(false), 150);
743
253
  }, [cancelClose]);
744
- React4.useEffect(() => cancelClose, [cancelClose]);
745
- return /* @__PURE__ */ jsxs3(
254
+ React3.useEffect(() => cancelClose, [cancelClose]);
255
+ return /* @__PURE__ */ jsxs2(
746
256
  "div",
747
257
  {
748
258
  ref,
@@ -756,7 +266,7 @@ function InformativeLock({
756
266
  if (event.key === "Escape") setOpen(false);
757
267
  },
758
268
  children: [
759
- /* @__PURE__ */ jsx4(
269
+ /* @__PURE__ */ jsx3(
760
270
  "button",
761
271
  {
762
272
  type: "button",
@@ -775,7 +285,7 @@ function InformativeLock({
775
285
  children
776
286
  }
777
287
  ),
778
- open && /* @__PURE__ */ jsxs3(
288
+ open && /* @__PURE__ */ jsxs2(
779
289
  AnchoredPopover,
780
290
  {
781
291
  ref: popoverRef,
@@ -793,12 +303,12 @@ function InformativeLock({
793
303
  popoverClassName
794
304
  ),
795
305
  children: [
796
- /* @__PURE__ */ jsxs3("p", { className: "flex items-start gap-2 text-sm font-medium text-foreground", children: [
797
- /* @__PURE__ */ jsx4(Lock, { className: "mt-0.5 h-3.5 w-3.5 shrink-0 text-muted-foreground" }),
798
- /* @__PURE__ */ jsx4("span", { children: lockTitle })
306
+ /* @__PURE__ */ jsxs2("p", { className: "flex items-start gap-2 text-sm font-medium text-foreground", children: [
307
+ /* @__PURE__ */ jsx3(Lock, { className: "mt-0.5 h-3.5 w-3.5 shrink-0 text-muted-foreground" }),
308
+ /* @__PURE__ */ jsx3("span", { children: lockTitle })
799
309
  ] }),
800
- /* @__PURE__ */ jsx4("p", { className: "mt-1.5 text-xs text-muted-foreground", children: lockBody }),
801
- /* @__PURE__ */ jsxs3(
310
+ /* @__PURE__ */ jsx3("p", { className: "mt-1.5 text-xs text-muted-foreground", children: lockBody }),
311
+ /* @__PURE__ */ jsxs2(
802
312
  "button",
803
313
  {
804
314
  type: "button",
@@ -812,7 +322,7 @@ function InformativeLock({
812
322
  "hover:bg-primary/15 focus:outline-none focus-visible:ring-1 focus-visible:ring-ring"
813
323
  ),
814
324
  children: [
815
- /* @__PURE__ */ jsx4(Plus, { className: "h-4 w-4" }),
325
+ /* @__PURE__ */ jsx3(Plus, { className: "h-4 w-4" }),
816
326
  newChatLabel
817
327
  ]
818
328
  }
@@ -826,7 +336,7 @@ function InformativeLock({
826
336
  }
827
337
 
828
338
  // src/chat/agent-profile-picker.tsx
829
- import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
339
+ import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
830
340
  function profileSubtitle(profile) {
831
341
  if (profile.description) return profile.description;
832
342
  const count = profile.capabilities?.length ?? 0;
@@ -849,11 +359,11 @@ function AgentProfilePicker({
849
359
  popoverClassName,
850
360
  side = "top"
851
361
  }) {
852
- const [open, setOpen] = React5.useState(false);
853
- const [composing, setComposing] = React5.useState(
362
+ const [open, setOpen] = React4.useState(false);
363
+ const [composing, setComposing] = React4.useState(
854
364
  null
855
365
  );
856
- const popoverRef = React5.useRef(null);
366
+ const popoverRef = React4.useRef(null);
857
367
  const ref = useClickOutside(() => {
858
368
  setOpen(false);
859
369
  setComposing(null);
@@ -863,7 +373,7 @@ function AgentProfilePicker({
863
373
  const custom = profiles.filter((profile) => !profile.builtin);
864
374
  const selected = profiles.find((profile) => profile.id === value);
865
375
  const selectedName = selected?.name ?? value;
866
- React5.useEffect(() => {
376
+ React4.useEffect(() => {
867
377
  if (!locked) return;
868
378
  setOpen(false);
869
379
  setComposing(null);
@@ -878,7 +388,7 @@ function AgentProfilePicker({
878
388
  setComposing(null);
879
389
  }
880
390
  if (locked && onNewChat) {
881
- return /* @__PURE__ */ jsxs4(
391
+ return /* @__PURE__ */ jsxs3(
882
392
  InformativeLock,
883
393
  {
884
394
  ariaLabel: "Agent profile (locked)",
@@ -891,14 +401,14 @@ function AgentProfilePicker({
891
401
  popoverClassName,
892
402
  side,
893
403
  children: [
894
- /* @__PURE__ */ jsx5(Bot, { className: "h-3.5 w-3.5 text-muted-foreground" }),
895
- /* @__PURE__ */ jsx5("span", { className: "max-w-[140px] truncate", children: selectedName })
404
+ /* @__PURE__ */ jsx4(Bot, { className: "h-3.5 w-3.5 text-muted-foreground" }),
405
+ /* @__PURE__ */ jsx4("span", { className: "max-w-[140px] truncate", children: selectedName })
896
406
  ]
897
407
  }
898
408
  );
899
409
  }
900
- return /* @__PURE__ */ jsxs4("div", { ref, className: cn("relative inline-flex", className), children: [
901
- /* @__PURE__ */ jsxs4(
410
+ return /* @__PURE__ */ jsxs3("div", { ref, className: cn("relative inline-flex", className), children: [
411
+ /* @__PURE__ */ jsxs3(
902
412
  "button",
903
413
  {
904
414
  type: "button",
@@ -916,13 +426,13 @@ function AgentProfilePicker({
916
426
  "data-state": open ? "open" : "closed",
917
427
  "aria-label": "Agent profile",
918
428
  children: [
919
- /* @__PURE__ */ jsx5(Bot, { className: "h-3.5 w-3.5 text-muted-foreground" }),
920
- /* @__PURE__ */ jsx5("span", { className: "max-w-[140px] truncate", children: selectedName }),
921
- !locked && /* @__PURE__ */ jsx5(ChevronDown2, { className: "ml-auto h-3.5 w-3.5 shrink-0 text-muted-foreground" })
429
+ /* @__PURE__ */ jsx4(Bot, { className: "h-3.5 w-3.5 text-muted-foreground" }),
430
+ /* @__PURE__ */ jsx4("span", { className: "max-w-[140px] truncate", children: selectedName }),
431
+ !locked && /* @__PURE__ */ jsx4(ChevronDown2, { className: "ml-auto h-3.5 w-3.5 shrink-0 text-muted-foreground" })
922
432
  ]
923
433
  }
924
434
  ),
925
- open && !locked && /* @__PURE__ */ jsx5(
435
+ open && !locked && /* @__PURE__ */ jsx4(
926
436
  AnchoredPopover,
927
437
  {
928
438
  ref: popoverRef,
@@ -934,7 +444,7 @@ function AgentProfilePicker({
934
444
  popoverClassName
935
445
  ),
936
446
  "data-testid": "agent-profile-popover",
937
- children: composing ? /* @__PURE__ */ jsx5(
447
+ children: composing ? /* @__PURE__ */ jsx4(
938
448
  ProfileForm,
939
449
  {
940
450
  capabilities: capabilities ?? [],
@@ -942,9 +452,9 @@ function AgentProfilePicker({
942
452
  onCancel: () => setComposing(null),
943
453
  onSave: save
944
454
  }
945
- ) : /* @__PURE__ */ jsxs4("div", { className: "max-h-[min(60vh,420px)] overflow-y-auto", children: [
946
- /* @__PURE__ */ jsx5(SectionHeader, { children: "Modes" }),
947
- builtins.map((profile) => /* @__PURE__ */ jsx5(
455
+ ) : /* @__PURE__ */ jsxs3("div", { className: "max-h-[min(60vh,420px)] overflow-y-auto", children: [
456
+ /* @__PURE__ */ jsx4(SectionHeader, { children: "Modes" }),
457
+ builtins.map((profile) => /* @__PURE__ */ jsx4(
948
458
  ProfileRow,
949
459
  {
950
460
  active: profile.id === value,
@@ -954,8 +464,8 @@ function AgentProfilePicker({
954
464
  },
955
465
  profile.id
956
466
  )),
957
- custom.length > 0 && /* @__PURE__ */ jsx5(SectionHeader, { children: "Your agents" }),
958
- custom.map((profile) => /* @__PURE__ */ jsx5(
467
+ custom.length > 0 && /* @__PURE__ */ jsx4(SectionHeader, { children: "Your agents" }),
468
+ custom.map((profile) => /* @__PURE__ */ jsx4(
959
469
  ProfileRow,
960
470
  {
961
471
  active: profile.id === value,
@@ -967,14 +477,14 @@ function AgentProfilePicker({
967
477
  },
968
478
  profile.id
969
479
  )),
970
- canAuthor && /* @__PURE__ */ jsxs4(
480
+ canAuthor && /* @__PURE__ */ jsxs3(
971
481
  "button",
972
482
  {
973
483
  type: "button",
974
484
  onClick: () => setComposing("new"),
975
485
  className: "mt-1 flex w-full items-center gap-2 rounded-md px-2.5 py-2 text-left text-sm text-[var(--accent-text)] transition-colors hover:bg-accent/40",
976
486
  children: [
977
- /* @__PURE__ */ jsx5(Plus2, { className: "h-4 w-4" }),
487
+ /* @__PURE__ */ jsx4(Plus2, { className: "h-4 w-4" }),
978
488
  " New agent\u2026"
979
489
  ]
980
490
  }
@@ -985,7 +495,7 @@ function AgentProfilePicker({
985
495
  ] });
986
496
  }
987
497
  function SectionHeader({ children }) {
988
- return /* @__PURE__ */ jsx5("div", { className: "px-2.5 pb-1 pt-2 text-[10px] font-semibold uppercase tracking-wide text-muted-foreground/70", children });
498
+ return /* @__PURE__ */ jsx4("div", { className: "px-2.5 pb-1 pt-2 text-[10px] font-semibold uppercase tracking-wide text-muted-foreground/70", children });
989
499
  }
990
500
  function ProfileRow({
991
501
  active,
@@ -995,7 +505,7 @@ function ProfileRow({
995
505
  onEdit,
996
506
  onDelete
997
507
  }) {
998
- return /* @__PURE__ */ jsxs4(
508
+ return /* @__PURE__ */ jsxs3(
999
509
  "div",
1000
510
  {
1001
511
  className: cn(
@@ -1003,40 +513,40 @@ function ProfileRow({
1003
513
  active ? "bg-[var(--accent-surface-soft)] text-[var(--accent-text)]" : "hover:bg-accent/40"
1004
514
  ),
1005
515
  children: [
1006
- /* @__PURE__ */ jsxs4(
516
+ /* @__PURE__ */ jsxs3(
1007
517
  "button",
1008
518
  {
1009
519
  type: "button",
1010
520
  onClick: onSelect,
1011
521
  className: "flex min-w-0 flex-1 items-center gap-2 text-left",
1012
522
  children: [
1013
- /* @__PURE__ */ jsx5("span", { className: "flex h-4 w-4 shrink-0 items-center justify-center", children: active && /* @__PURE__ */ jsx5(Check, { className: "h-3.5 w-3.5" }) }),
1014
- /* @__PURE__ */ jsxs4("span", { className: "min-w-0", children: [
1015
- /* @__PURE__ */ jsx5("span", { className: "block truncate font-medium", children: title }),
1016
- /* @__PURE__ */ jsx5("span", { className: "block truncate text-xs text-muted-foreground", children: subtitle })
523
+ /* @__PURE__ */ jsx4("span", { className: "flex h-4 w-4 shrink-0 items-center justify-center", children: active && /* @__PURE__ */ jsx4(Check, { className: "h-3.5 w-3.5" }) }),
524
+ /* @__PURE__ */ jsxs3("span", { className: "min-w-0", children: [
525
+ /* @__PURE__ */ jsx4("span", { className: "block truncate font-medium", children: title }),
526
+ /* @__PURE__ */ jsx4("span", { className: "block truncate text-xs text-muted-foreground", children: subtitle })
1017
527
  ] })
1018
528
  ]
1019
529
  }
1020
530
  ),
1021
- (onEdit || onDelete) && /* @__PURE__ */ jsxs4("span", { className: "flex shrink-0 items-center gap-1 opacity-0 transition-opacity group-hover:opacity-100", children: [
1022
- onEdit && /* @__PURE__ */ jsx5(
531
+ (onEdit || onDelete) && /* @__PURE__ */ jsxs3("span", { className: "flex shrink-0 items-center gap-1 opacity-0 transition-opacity group-hover:opacity-100", children: [
532
+ onEdit && /* @__PURE__ */ jsx4(
1023
533
  "button",
1024
534
  {
1025
535
  type: "button",
1026
536
  onClick: onEdit,
1027
537
  title: "Edit",
1028
538
  className: "rounded p-1 text-muted-foreground hover:text-foreground",
1029
- children: /* @__PURE__ */ jsx5(Pencil, { className: "h-3 w-3" })
539
+ children: /* @__PURE__ */ jsx4(Pencil, { className: "h-3 w-3" })
1030
540
  }
1031
541
  ),
1032
- onDelete && /* @__PURE__ */ jsx5(
542
+ onDelete && /* @__PURE__ */ jsx4(
1033
543
  "button",
1034
544
  {
1035
545
  type: "button",
1036
546
  onClick: onDelete,
1037
547
  title: "Delete",
1038
548
  className: "rounded p-1 text-muted-foreground hover:text-[var(--status-error,#ff4d6d)]",
1039
- children: /* @__PURE__ */ jsx5(Trash2, { className: "h-3 w-3" })
549
+ children: /* @__PURE__ */ jsx4(Trash2, { className: "h-3 w-3" })
1040
550
  }
1041
551
  )
1042
552
  ] })
@@ -1050,16 +560,16 @@ function ProfileForm({
1050
560
  onCancel,
1051
561
  onSave
1052
562
  }) {
1053
- const [name, setName] = React5.useState(initial?.name ?? "");
1054
- const [caps, setCaps] = React5.useState(
563
+ const [name, setName] = React4.useState(initial?.name ?? "");
564
+ const [caps, setCaps] = React4.useState(
1055
565
  initial?.capabilities ? [...initial.capabilities] : capabilities.map((c) => c.id)
1056
566
  );
1057
- const [instructions, setInstructions] = React5.useState(initial?.instructions ?? "");
567
+ const [instructions, setInstructions] = React4.useState(initial?.instructions ?? "");
1058
568
  const toggle = (id) => setCaps(
1059
569
  (prev) => prev.includes(id) ? prev.filter((c) => c !== id) : [...prev, id]
1060
570
  );
1061
- return /* @__PURE__ */ jsxs4("div", { className: "space-y-3 p-2.5", children: [
1062
- /* @__PURE__ */ jsx5(
571
+ return /* @__PURE__ */ jsxs3("div", { className: "space-y-3 p-2.5", children: [
572
+ /* @__PURE__ */ jsx4(
1063
573
  "input",
1064
574
  {
1065
575
  autoFocus: true,
@@ -1069,14 +579,14 @@ function ProfileForm({
1069
579
  className: "w-full rounded-lg border border-[var(--md3-outline-variant)] bg-surface-container px-3 py-2 text-sm outline-none focus:border-primary"
1070
580
  }
1071
581
  ),
1072
- capabilities.length > 0 && /* @__PURE__ */ jsxs4("div", { children: [
1073
- /* @__PURE__ */ jsx5("p", { className: "mb-1.5 text-[10px] font-semibold uppercase tracking-wide text-muted-foreground/70", children: "Tools" }),
1074
- /* @__PURE__ */ jsx5("div", { className: "space-y-0.5", children: capabilities.map((cap) => /* @__PURE__ */ jsxs4(
582
+ capabilities.length > 0 && /* @__PURE__ */ jsxs3("div", { children: [
583
+ /* @__PURE__ */ jsx4("p", { className: "mb-1.5 text-[10px] font-semibold uppercase tracking-wide text-muted-foreground/70", children: "Tools" }),
584
+ /* @__PURE__ */ jsx4("div", { className: "space-y-0.5", children: capabilities.map((cap) => /* @__PURE__ */ jsxs3(
1075
585
  "label",
1076
586
  {
1077
587
  className: "flex cursor-pointer items-start gap-2 rounded-md px-2 py-1.5 hover:bg-accent/40",
1078
588
  children: [
1079
- /* @__PURE__ */ jsx5(
589
+ /* @__PURE__ */ jsx4(
1080
590
  "input",
1081
591
  {
1082
592
  type: "checkbox",
@@ -1085,16 +595,16 @@ function ProfileForm({
1085
595
  className: "mt-0.5"
1086
596
  }
1087
597
  ),
1088
- /* @__PURE__ */ jsxs4("span", { className: "min-w-0", children: [
1089
- /* @__PURE__ */ jsx5("span", { className: "block text-sm font-medium", children: cap.label }),
1090
- cap.description && /* @__PURE__ */ jsx5("span", { className: "block text-xs text-muted-foreground", children: cap.description })
598
+ /* @__PURE__ */ jsxs3("span", { className: "min-w-0", children: [
599
+ /* @__PURE__ */ jsx4("span", { className: "block text-sm font-medium", children: cap.label }),
600
+ cap.description && /* @__PURE__ */ jsx4("span", { className: "block text-xs text-muted-foreground", children: cap.description })
1091
601
  ] })
1092
602
  ]
1093
603
  },
1094
604
  cap.id
1095
605
  )) })
1096
606
  ] }),
1097
- /* @__PURE__ */ jsx5(
607
+ /* @__PURE__ */ jsx4(
1098
608
  "textarea",
1099
609
  {
1100
610
  value: instructions,
@@ -1104,8 +614,8 @@ function ProfileForm({
1104
614
  className: "w-full resize-none rounded-lg border border-[var(--md3-outline-variant)] bg-surface-container px-3 py-2 text-sm outline-none focus:border-primary"
1105
615
  }
1106
616
  ),
1107
- /* @__PURE__ */ jsxs4("div", { className: "flex justify-end gap-2", children: [
1108
- /* @__PURE__ */ jsx5(
617
+ /* @__PURE__ */ jsxs3("div", { className: "flex justify-end gap-2", children: [
618
+ /* @__PURE__ */ jsx4(
1109
619
  "button",
1110
620
  {
1111
621
  type: "button",
@@ -1114,7 +624,7 @@ function ProfileForm({
1114
624
  children: "Cancel"
1115
625
  }
1116
626
  ),
1117
- /* @__PURE__ */ jsx5(
627
+ /* @__PURE__ */ jsx4(
1118
628
  "button",
1119
629
  {
1120
630
  type: "button",
@@ -1137,10 +647,10 @@ function ProfileForm({
1137
647
  import { modelProvider, snapHarnessToModel } from "@tangle-network/agent-interface";
1138
648
 
1139
649
  // src/chat/artifact-agent-dock.tsx
1140
- import * as React6 from "react";
1141
- import { Sparkles as Sparkles2, Send, Square as Square2, X as X2 } from "lucide-react";
650
+ import * as React5 from "react";
651
+ import { Sparkles as Sparkles2, Send, Square, X } from "lucide-react";
1142
652
  import { ChatMessage } from "@tangle-network/ui/chat";
1143
- import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
653
+ import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
1144
654
  function defaultScopeLabel(scope) {
1145
655
  if (scope.label) return scope.label;
1146
656
  switch (scope.kind) {
@@ -1186,23 +696,23 @@ function ArtifactAgentDock({
1186
696
  onError,
1187
697
  className
1188
698
  }) {
1189
- const [threadId, setThreadId] = React6.useState(null);
1190
- const [messages, setMessages] = React6.useState([]);
1191
- const [composer, setComposer] = React6.useState(defaultPrompt ?? "");
1192
- const [streamContent, setStreamContent] = React6.useState("");
1193
- const [sending, setSending] = React6.useState(false);
1194
- const [loading, setLoading] = React6.useState(false);
1195
- const abortRef = React6.useRef(null);
1196
- const scrollRef = React6.useRef(null);
1197
- const scopeTokenRef = React6.useRef(0);
1198
- const reportError = React6.useCallback(
699
+ const [threadId, setThreadId] = React5.useState(null);
700
+ const [messages, setMessages] = React5.useState([]);
701
+ const [composer, setComposer] = React5.useState(defaultPrompt ?? "");
702
+ const [streamContent, setStreamContent] = React5.useState("");
703
+ const [sending, setSending] = React5.useState(false);
704
+ const [loading, setLoading] = React5.useState(false);
705
+ const abortRef = React5.useRef(null);
706
+ const scrollRef = React5.useRef(null);
707
+ const scopeTokenRef = React5.useRef(0);
708
+ const reportError = React5.useCallback(
1199
709
  (message) => {
1200
710
  if (onError) onError(message);
1201
711
  else if (typeof console !== "undefined") console.error("[ArtifactAgentDock]", message);
1202
712
  },
1203
713
  [onError]
1204
714
  );
1205
- React6.useEffect(() => {
715
+ React5.useEffect(() => {
1206
716
  if (!open) return;
1207
717
  scopeTokenRef.current += 1;
1208
718
  abortRef.current?.abort();
@@ -1238,11 +748,11 @@ function ArtifactAgentDock({
1238
748
  cancelled = true;
1239
749
  };
1240
750
  }, [open, scope.kind, scope.key, transport, reportError]);
1241
- React6.useEffect(() => {
751
+ React5.useEffect(() => {
1242
752
  if (!scrollRef.current) return;
1243
753
  scrollRef.current.scrollTop = scrollRef.current.scrollHeight;
1244
754
  }, [messages.length, streamContent]);
1245
- const send = React6.useCallback(async () => {
755
+ const send = React5.useCallback(async () => {
1246
756
  const text = composer.trim();
1247
757
  if (!text || !threadId || sending) return;
1248
758
  const token = scopeTokenRef.current;
@@ -1292,7 +802,7 @@ function ArtifactAgentDock({
1292
802
  if (abortRef.current === controller) abortRef.current = null;
1293
803
  }
1294
804
  }, [composer, threadId, sending, transport, reportError]);
1295
- const cancel = React6.useCallback(() => {
805
+ const cancel = React5.useCallback(() => {
1296
806
  if (threadId && transport.cancel) {
1297
807
  try {
1298
808
  void Promise.resolve(transport.cancel({ threadId })).catch(() => {
@@ -1306,7 +816,7 @@ function ArtifactAgentDock({
1306
816
  }, [threadId, transport]);
1307
817
  if (!open) return null;
1308
818
  const heading = defaultScopeLabel(scope);
1309
- return /* @__PURE__ */ jsxs5(
819
+ return /* @__PURE__ */ jsxs4(
1310
820
  "aside",
1311
821
  {
1312
822
  className: cn(
@@ -1315,38 +825,38 @@ function ArtifactAgentDock({
1315
825
  ),
1316
826
  "aria-label": `Agent chat about ${heading}`,
1317
827
  children: [
1318
- /* @__PURE__ */ jsxs5("header", { className: "flex items-center justify-between border-b border-[var(--md3-outline-variant)] bg-surface-container-low px-4 py-3", children: [
1319
- /* @__PURE__ */ jsxs5("div", { className: "flex min-w-0 items-center gap-2", children: [
1320
- /* @__PURE__ */ jsx6(Sparkles2, { className: "h-4 w-4 shrink-0 text-muted-foreground" }),
1321
- /* @__PURE__ */ jsxs5("div", { className: "min-w-0", children: [
1322
- /* @__PURE__ */ jsx6("div", { className: "text-[10px] font-medium uppercase tracking-wider text-muted-foreground", children: "Discussing" }),
1323
- /* @__PURE__ */ jsx6("div", { className: "truncate text-sm font-semibold text-foreground", children: heading })
828
+ /* @__PURE__ */ jsxs4("header", { className: "flex items-center justify-between border-b border-[var(--md3-outline-variant)] bg-surface-container-low px-4 py-3", children: [
829
+ /* @__PURE__ */ jsxs4("div", { className: "flex min-w-0 items-center gap-2", children: [
830
+ /* @__PURE__ */ jsx5(Sparkles2, { className: "h-4 w-4 shrink-0 text-muted-foreground" }),
831
+ /* @__PURE__ */ jsxs4("div", { className: "min-w-0", children: [
832
+ /* @__PURE__ */ jsx5("div", { className: "text-[10px] font-medium uppercase tracking-wider text-muted-foreground", children: "Discussing" }),
833
+ /* @__PURE__ */ jsx5("div", { className: "truncate text-sm font-semibold text-foreground", children: heading })
1324
834
  ] })
1325
835
  ] }),
1326
- /* @__PURE__ */ jsx6(
836
+ /* @__PURE__ */ jsx5(
1327
837
  "button",
1328
838
  {
1329
839
  type: "button",
1330
840
  onClick: () => onOpenChange(false),
1331
841
  "aria-label": "Close artifact chat",
1332
842
  className: "rounded-md p-1 text-muted-foreground transition-colors hover:bg-surface-container-high hover:text-foreground",
1333
- children: /* @__PURE__ */ jsx6(X2, { className: "h-4 w-4" })
843
+ children: /* @__PURE__ */ jsx5(X, { className: "h-4 w-4" })
1334
844
  }
1335
845
  )
1336
846
  ] }),
1337
- /* @__PURE__ */ jsx6("div", { ref: scrollRef, className: "flex-1 overflow-y-auto px-3 py-4", children: loading ? /* @__PURE__ */ jsx6("div", { className: "px-3 py-8 text-center text-xs text-muted-foreground", children: "Loading conversation\u2026" }) : messages.length === 0 && !streamContent ? /* @__PURE__ */ jsxs5("div", { className: "px-3 py-12 text-center", children: [
1338
- /* @__PURE__ */ jsx6(Sparkles2, { className: "mx-auto mb-3 h-5 w-5 text-muted-foreground/40" }),
1339
- /* @__PURE__ */ jsxs5("p", { className: "text-sm text-foreground", children: [
847
+ /* @__PURE__ */ jsx5("div", { ref: scrollRef, className: "flex-1 overflow-y-auto px-3 py-4", children: loading ? /* @__PURE__ */ jsx5("div", { className: "px-3 py-8 text-center text-xs text-muted-foreground", children: "Loading conversation\u2026" }) : messages.length === 0 && !streamContent ? /* @__PURE__ */ jsxs4("div", { className: "px-3 py-12 text-center", children: [
848
+ /* @__PURE__ */ jsx5(Sparkles2, { className: "mx-auto mb-3 h-5 w-5 text-muted-foreground/40" }),
849
+ /* @__PURE__ */ jsxs4("p", { className: "text-sm text-foreground", children: [
1340
850
  "Ask the agent about this ",
1341
851
  scope.kind === "vault-file" ? "document" : scope.kind,
1342
852
  "."
1343
853
  ] }),
1344
- /* @__PURE__ */ jsx6("p", { className: "mt-1 text-xs text-muted-foreground", children: "It can read the current contents and propose edits, rewrites, or follow-ups." })
1345
- ] }) : /* @__PURE__ */ jsxs5("div", { className: "space-y-3", children: [
1346
- messages.map((m) => /* @__PURE__ */ jsx6(ChatMessage, { role: m.role, content: m.content, timestamp: m.createdAt }, m.id)),
1347
- streamContent && /* @__PURE__ */ jsx6(ChatMessage, { role: "assistant", content: streamContent, isStreaming: true })
854
+ /* @__PURE__ */ jsx5("p", { className: "mt-1 text-xs text-muted-foreground", children: "It can read the current contents and propose edits, rewrites, or follow-ups." })
855
+ ] }) : /* @__PURE__ */ jsxs4("div", { className: "space-y-3", children: [
856
+ messages.map((m) => /* @__PURE__ */ jsx5(ChatMessage, { role: m.role, content: m.content, timestamp: m.createdAt }, m.id)),
857
+ streamContent && /* @__PURE__ */ jsx5(ChatMessage, { role: "assistant", content: streamContent, isStreaming: true })
1348
858
  ] }) }),
1349
- /* @__PURE__ */ jsx6(
859
+ /* @__PURE__ */ jsx5(
1350
860
  "form",
1351
861
  {
1352
862
  className: "border-t border-[var(--md3-outline-variant)] bg-surface-container-low p-3",
@@ -1354,8 +864,8 @@ function ArtifactAgentDock({
1354
864
  e.preventDefault();
1355
865
  void send();
1356
866
  },
1357
- children: /* @__PURE__ */ jsxs5("div", { className: "flex items-end gap-2", children: [
1358
- /* @__PURE__ */ jsx6(
867
+ children: /* @__PURE__ */ jsxs4("div", { className: "flex items-end gap-2", children: [
868
+ /* @__PURE__ */ jsx5(
1359
869
  "textarea",
1360
870
  {
1361
871
  value: composer,
@@ -1372,23 +882,23 @@ function ArtifactAgentDock({
1372
882
  className: "min-h-[44px] flex-1 resize-none rounded-[20px] border border-[var(--md3-outline-variant)] bg-surface-dim px-3.5 py-2 text-sm text-foreground placeholder:text-muted-foreground transition-colors focus:outline-none focus:border-[var(--border-accent)] disabled:opacity-50"
1373
883
  }
1374
884
  ),
1375
- sending ? /* @__PURE__ */ jsx6(
885
+ sending ? /* @__PURE__ */ jsx5(
1376
886
  "button",
1377
887
  {
1378
888
  type: "button",
1379
889
  onClick: cancel,
1380
890
  "aria-label": "Cancel",
1381
891
  className: "inline-flex h-9 w-9 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-surface-container-high hover:text-foreground",
1382
- children: /* @__PURE__ */ jsx6(Square2, { className: "h-4 w-4" })
892
+ children: /* @__PURE__ */ jsx5(Square, { className: "h-4 w-4" })
1383
893
  }
1384
- ) : /* @__PURE__ */ jsx6(
894
+ ) : /* @__PURE__ */ jsx5(
1385
895
  "button",
1386
896
  {
1387
897
  type: "submit",
1388
898
  disabled: !composer.trim() || !threadId,
1389
899
  "aria-label": "Send",
1390
900
  className: "inline-flex h-9 w-9 items-center justify-center rounded-full bg-primary text-primary-foreground transition-colors hover:bg-primary/90 disabled:opacity-50",
1391
- children: /* @__PURE__ */ jsx6(Send, { className: "h-4 w-4" })
901
+ children: /* @__PURE__ */ jsx5(Send, { className: "h-4 w-4" })
1392
902
  }
1393
903
  )
1394
904
  ] })
@@ -1478,9 +988,6 @@ export {
1478
988
  DEFAULT_REASONING_LEVEL_OPTIONS,
1479
989
  HARNESS_REASONING_OPTIONS,
1480
990
  ReasoningLevelPicker,
1481
- isAcceptedType,
1482
- validateComposerFiles,
1483
- AgentComposer,
1484
991
  AgentProfilePicker,
1485
992
  modelProvider,
1486
993
  snapHarnessToModel,