@agents24/chat-react 0.5.29 → 0.5.31

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/README.md +28 -1
  2. package/dist/chunk-INO5DSSJ.js +86 -0
  3. package/dist/chunk-INO5DSSJ.js.map +1 -0
  4. package/dist/generated/delegation-types.d.ts +129 -0
  5. package/dist/registry/agents24-chat.json +267 -0
  6. package/dist/runtime/index.cjs +53 -1
  7. package/dist/runtime/index.cjs.map +1 -1
  8. package/dist/runtime/index.d.ts +2 -0
  9. package/dist/runtime/index.js +62 -78
  10. package/dist/runtime/index.js.map +1 -1
  11. package/dist/runtime/input-contract.d.ts +3 -1
  12. package/dist/runtime/use-delegation-tasks.d.ts +20 -0
  13. package/dist/scaffold/app.d.ts +3 -0
  14. package/dist/scaffold/components/chat/chat-composer.d.ts +5 -3
  15. package/dist/scaffold/components/chat/subagent-tasks.d.ts +3 -0
  16. package/dist/scaffold/components/chat/theme-menu.d.ts +1 -1
  17. package/dist/scaffold/components/theme-provider.d.ts +3 -1
  18. package/dist/scaffold/index.cjs +420 -333
  19. package/dist/scaffold/index.cjs.map +1 -1
  20. package/dist/scaffold/index.d.ts +5 -2
  21. package/dist/scaffold/index.js +415 -332
  22. package/dist/scaffold/index.js.map +1 -1
  23. package/dist/styles.css +14 -0
  24. package/dist/ui/adapters.d.ts +5 -2
  25. package/dist/ui/agent-chat-composer.d.ts +8 -2
  26. package/dist/ui/agent-chat-queue.d.ts +0 -2
  27. package/dist/ui/index.cjs +817 -623
  28. package/dist/ui/index.cjs.map +1 -1
  29. package/dist/ui/index.d.ts +1 -0
  30. package/dist/ui/index.js +776 -622
  31. package/dist/ui/index.js.map +1 -1
  32. package/dist/ui/tool-sessions.d.ts +10 -2
  33. package/dist/ui/use-agent-chat-composer.d.ts +47 -0
  34. package/dist/ui/use-audio-recorder.d.ts +5 -3
  35. package/package.json +11 -6
  36. package/scaffold/host-styles.css +3 -0
  37. package/scaffold/inherit.css +4 -0
  38. package/scaffold/manifest.json +2 -2
  39. package/scaffold/src/app.tsx +5 -0
  40. package/scaffold/src/chat.css +35 -1
  41. package/scaffold/src/components/chat/chat-composer.tsx +31 -97
  42. package/scaffold/src/components/chat/chat-shell.tsx +7 -5
  43. package/scaffold/src/components/chat/external-link-dialog.tsx +6 -5
  44. package/scaffold/src/components/chat/identity-control.tsx +0 -1
  45. package/scaffold/src/components/chat/subagent-tasks.tsx +109 -0
  46. package/scaffold/src/components/chat/theme-menu.tsx +3 -1
  47. package/scaffold/src/components/theme-provider.tsx +28 -23
  48. package/scaffold/src/components/ui/tooltip.tsx +3 -0
  49. package/scaffold/src/host.css +11 -0
  50. package/scaffold/src/index.css +1 -213
  51. package/scaffold/src/index.tsx +9 -2
  52. package/scaffold/src/theme.css +215 -0
@@ -1,4 +1,5 @@
1
1
  "use strict";
2
+ "use client";
2
3
  var __create = Object.create;
3
4
  var __defProp = Object.defineProperty;
4
5
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
@@ -30,6 +31,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
30
31
  // scaffold/src/index.tsx
31
32
  var src_exports = {};
32
33
  __export(src_exports, {
34
+ Agents24ChatComposer: () => ChatComposer,
33
35
  Agents24ChatScaffold: () => Agents24ChatScaffold,
34
36
  Agents24ChatScaffoldApp: () => App,
35
37
  Agents24ChatThemeProvider: () => ThemeProvider,
@@ -40,19 +42,18 @@ module.exports = __toCommonJS(src_exports);
40
42
  // scaffold/src/app.tsx
41
43
  var import_browser = require("@agents24/client/browser");
42
44
  var import_runtime3 = require("@agents24/chat-react/runtime");
43
- var import_react2 = require("@agents24/react");
45
+ var import_react3 = require("@agents24/react");
44
46
 
45
47
  // scaffold/src/components/chat/chat-shell.tsx
46
48
  var import_runtime2 = require("@agents24/chat-react/runtime");
47
- var import_ui4 = require("@agents24/chat-react/ui");
49
+ var import_ui5 = require("@agents24/chat-react/ui");
48
50
  var import_lucide_react11 = require("lucide-react");
49
- var React8 = __toESM(require("react"), 1);
51
+ var React9 = __toESM(require("react"), 1);
50
52
 
51
53
  // scaffold/src/components/chat/chat-composer.tsx
52
54
  var import_lucide_react3 = require("lucide-react");
53
55
  var React2 = __toESM(require("react"), 1);
54
56
  var import_ui = require("@agents24/chat-react/ui");
55
- var import_runtime = require("@agents24/chat-react/runtime");
56
57
 
57
58
  // scaffold/src/components/ui/button.tsx
58
59
  var import_class_variance_authority = require("class-variance-authority");
@@ -124,6 +125,21 @@ var import_lucide_react = require("lucide-react");
124
125
  var React = __toESM(require("react"), 1);
125
126
  var import_jsx_runtime2 = require("react/jsx-runtime");
126
127
  var ThemeContext = React.createContext(null);
128
+ var appearanceEvent = "agents24-chat-appearance-change";
129
+ var subscribeAppearance = (notify) => {
130
+ window.addEventListener("storage", notify);
131
+ window.addEventListener(appearanceEvent, notify);
132
+ return () => {
133
+ window.removeEventListener("storage", notify);
134
+ window.removeEventListener(appearanceEvent, notify);
135
+ };
136
+ };
137
+ var subscribeDarkMode = (notify) => {
138
+ const media = window.matchMedia?.("(prefers-color-scheme: dark)");
139
+ media?.addEventListener("change", notify);
140
+ return () => media?.removeEventListener("change", notify);
141
+ };
142
+ var getDarkMode = () => window.matchMedia?.("(prefers-color-scheme: dark)").matches ?? false;
127
143
  var storageKey = "agents24-chat-appearance";
128
144
  function storedAppearance() {
129
145
  try {
@@ -136,43 +152,33 @@ function storedAppearance() {
136
152
  function ThemeProvider({
137
153
  children,
138
154
  controller,
139
- theme = "soft"
155
+ theme = "soft",
156
+ mode = "isolated"
140
157
  }) {
141
- const [internalAppearance, setInternalAppearance] = React.useState("system");
142
- const [resolvedAppearance, setResolvedAppearance] = React.useState("light");
143
- const [mounted, setMounted] = React.useState(false);
158
+ const [sessionAppearance, setSessionAppearance] = React.useState(null);
159
+ const stored = React.useSyncExternalStore(subscribeAppearance, storedAppearance, () => "system");
160
+ const systemDark = React.useSyncExternalStore(subscribeDarkMode, getDarkMode, () => false);
144
161
  const [portalContainer, setPortalContainer] = React.useState(null);
145
- const appearance = controller?.appearance ?? internalAppearance;
146
- React.useEffect(() => {
147
- if (!controller) setInternalAppearance(storedAppearance());
148
- setMounted(true);
149
- }, [controller]);
150
- React.useEffect(() => {
151
- if (!mounted || typeof window === "undefined" || typeof window.matchMedia !== "function") return;
152
- const media = window.matchMedia("(prefers-color-scheme: dark)");
153
- const apply = () => setResolvedAppearance(
154
- appearance === "system" ? media.matches ? "dark" : "light" : appearance
155
- );
156
- apply();
157
- media.addEventListener("change", apply);
158
- return () => media.removeEventListener("change", apply);
159
- }, [appearance, mounted]);
162
+ const appearance = controller?.appearance ?? sessionAppearance ?? stored;
163
+ const resolvedAppearance = appearance === "system" ? systemDark ? "dark" : "light" : appearance;
160
164
  const change = React.useCallback((next) => {
161
165
  if (controller) {
162
166
  controller.setAppearance(next);
163
167
  return;
164
168
  }
169
+ setSessionAppearance(next);
165
170
  try {
166
171
  window.localStorage.setItem(storageKey, next);
167
172
  } catch {
168
173
  }
169
- setInternalAppearance(next);
174
+ window.dispatchEvent(new Event(appearanceEvent));
170
175
  }, [controller]);
171
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ThemeContext.Provider, { value: { appearance, portalContainer, setAppearance: change }, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
176
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ThemeContext.Provider, { value: { appearance, portalContainer, setAppearance: change, inherited: mode === "inherit" }, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
172
177
  "div",
173
178
  {
174
179
  ref: setPortalContainer,
175
- className: `${resolvedAppearance} size-full`,
180
+ className: mode === "inherit" ? "size-full" : `${resolvedAppearance} size-full`,
181
+ "data-agents24-theme-mode": mode,
176
182
  "data-agents24-theme": theme,
177
183
  "data-agents24-theme-root": "",
178
184
  children
@@ -474,6 +480,7 @@ function TooltipTrigger({
474
480
  asChild: _asChild,
475
481
  ...props
476
482
  }) {
483
+ void _asChild;
477
484
  return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_radix_ui4.Slot.Root, { "data-slot": "tooltip-trigger", ...props });
478
485
  }
479
486
  function TooltipContent({
@@ -483,6 +490,8 @@ function TooltipContent({
483
490
  sideOffset: _sideOffset,
484
491
  ...props
485
492
  }) {
493
+ void _align;
494
+ void _sideOffset;
486
495
  return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
487
496
  "span",
488
497
  {
@@ -506,6 +515,8 @@ function TooltipContent({
506
515
  var import_jsx_runtime7 = require("react/jsx-runtime");
507
516
  function ChatComposer({
508
517
  inputContract,
518
+ queue,
519
+ onRecordingStreamChange,
509
520
  disabled,
510
521
  contextWindow,
511
522
  focusKey,
@@ -523,49 +534,35 @@ function ChatComposer({
523
534
  restoredDraft,
524
535
  utilityRow = "inline"
525
536
  }) {
526
- const [text, setText] = React2.useState("");
527
- const [files, setFiles] = React2.useState([]);
528
- const [attachmentError, setAttachmentError] = React2.useState(null);
529
537
  const inputRef = React2.useRef(null);
530
- const textareaRef = React2.useRef(null);
531
- const filesRef = React2.useRef([]);
532
- const inFlightFilesRef = React2.useRef([]);
533
- const submittingRef = React2.useRef(false);
534
- const draftRevisionRef = React2.useRef(0);
535
- const attachmentMimeTypes = (0, import_runtime.inputMimeTypes)(inputContract);
536
- const allowAttachments = attachmentMimeTypes.length > 0;
537
- const recordingAllowed = inputContract.modalities.audio.recording_enabled;
538
- React2.useEffect(() => {
539
- filesRef.current = files;
540
- }, [files]);
541
- React2.useEffect(() => () => {
542
- (0, import_ui.revokeAgentChatComposerFiles)(filesRef.current);
543
- (0, import_ui.revokeAgentChatComposerFiles)(inFlightFilesRef.current);
544
- }, []);
545
- const focusComposer = (0, import_ui.useChatComposerFocus)({
538
+ const {
539
+ text,
540
+ setText,
541
+ files,
542
+ removeFile,
543
+ addFiles,
546
544
  textareaRef,
547
- disabled: Boolean(disabled),
545
+ submit,
546
+ attachmentError,
547
+ attachmentMimeTypes,
548
+ allowAttachments,
549
+ recordingAllowed,
550
+ recorder,
551
+ isExpanded,
552
+ validationError,
553
+ action,
554
+ canSubmit
555
+ } = (0, import_ui.useAgentChatComposer)({
556
+ inputContract,
557
+ disabled,
548
558
  focusKey,
559
+ forceExpanded,
560
+ isCancelling,
561
+ isRunning,
562
+ onSubmit,
549
563
  restoredDraft,
550
- onRestore: (draft) => {
551
- draftRevisionRef.current += 1;
552
- (0, import_ui.revokeAgentChatComposerFiles)(filesRef.current);
553
- setText(draft.text);
554
- setFiles(draft.files);
555
- }
564
+ onRecordingStreamChange
556
565
  });
557
- const addRecording = React2.useCallback((file) => {
558
- draftRevisionRef.current += 1;
559
- setFiles((current) => [...current, (0, import_ui.createAgentChatComposerFile)(file)]);
560
- }, []);
561
- const recorder = (0, import_ui.useAudioRecorder)(addRecording);
562
- const isExpanded = forceExpanded || text.includes("\n") || text.length > 62;
563
- const validationError = (0, import_runtime.validateAgentChatSubmission)(
564
- inputContract,
565
- text,
566
- files.map((file) => ({ data: file.source || new Uint8Array(), mediaType: file.mediaType }))
567
- );
568
- const action = (0, import_ui.chatComposerAction)({ hasDraft: Boolean(text.trim() || files.length), isRunning, isCancelling });
569
566
  const selectedAgent = agents.find((item) => item.id === agentId);
570
567
  const selectedModel = models.find((item) => item.id === modelId);
571
568
  const modelSelector = models.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "w-fit max-w-40", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Select, { disabled: disabled || isRunning, onValueChange: onModelChange, value: modelId || void 0, children: [
@@ -605,66 +602,35 @@ function ChatComposer({
605
602
  ] }) : modelSelector;
606
603
  const hasContextWindow = Number.isFinite(Number(contextWindow?.max_tokens)) && Number(contextWindow?.max_tokens) > 0;
607
604
  const showUtilityRow = utilityRow === "below";
608
- const submit = async () => {
609
- if (disabled || isCancelling || submittingRef.current || validationError) return;
610
- const value = text;
611
- const selectedFiles = files;
612
- const clearedRevision = draftRevisionRef.current + 1;
613
- draftRevisionRef.current = clearedRevision;
614
- submittingRef.current = true;
615
- inFlightFilesRef.current = selectedFiles;
616
- setText("");
617
- setFiles([]);
618
- focusComposer();
619
- try {
620
- await onSubmit(value, selectedFiles);
621
- (0, import_ui.revokeAgentChatComposerFiles)(selectedFiles);
622
- inFlightFilesRef.current = [];
623
- } catch {
624
- if (draftRevisionRef.current === clearedRevision) {
625
- draftRevisionRef.current += 1;
626
- setText(value);
627
- setFiles(selectedFiles);
628
- inFlightFilesRef.current = [];
629
- } else {
630
- (0, import_ui.revokeAgentChatComposerFiles)(selectedFiles);
631
- inFlightFilesRef.current = [];
632
- }
633
- } finally {
634
- submittingRef.current = false;
635
- }
636
- };
637
605
  return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
638
606
  "div",
639
607
  {
640
608
  className: "relative z-10 w-full pb-[max(1rem,env(safe-area-inset-bottom))]",
641
609
  "data-agents24-chat-composer": "",
642
610
  children: [
643
- allowAttachments && files.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "mb-2 min-w-0", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
644
- import_ui.ChatAttachmentRows,
645
- {
646
- attachments: files,
647
- onRemove: (attachment) => {
648
- if (!attachment.id) return;
649
- draftRevisionRef.current += 1;
650
- setFiles((current) => {
651
- const removed = current.find((file) => file.id === attachment.id);
652
- if (removed) (0, import_ui.revokeAgentChatComposerFiles)([removed]);
653
- return current.filter((file) => file.id !== attachment.id);
654
- });
655
- }
656
- }
657
- ) }),
611
+ queue,
658
612
  attachmentError || recorder.error ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { className: "mb-2 text-xs text-destructive", role: "alert", children: attachmentError || recorder.error }) : null,
659
613
  /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
660
614
  "div",
661
615
  {
662
616
  "data-expanded": isExpanded || void 0,
617
+ "data-attachments": files.length > 0 || void 0,
663
618
  className: cn(
664
619
  "agents24-composer-grid grid min-w-0 items-center gap-2 rounded-xl border bg-background shadow-sm",
665
620
  isExpanded ? "p-2" : "p-1.5"
666
621
  ),
667
622
  children: [
623
+ allowAttachments && files.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "agents24-composer-attachments min-w-0", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
624
+ import_ui.ChatAttachmentRows,
625
+ {
626
+ layout: "composer",
627
+ attachments: files,
628
+ onRemove: (attachment) => {
629
+ if (!attachment.id) return;
630
+ removeFile(attachment.id);
631
+ }
632
+ }
633
+ ) }),
668
634
  allowAttachments ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
669
635
  /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
670
636
  "input",
@@ -673,11 +639,9 @@ function ChatComposer({
673
639
  className: "sr-only",
674
640
  type: "file",
675
641
  multiple: true,
676
- accept: (0, import_runtime.attachmentFileAccept)(attachmentMimeTypes),
642
+ accept: attachmentMimeTypes.join(","),
677
643
  onChange: (event) => {
678
- const selected = Array.from(event.target.files ?? []);
679
- setFiles((current) => [...current, ...selected.map(import_ui.createAgentChatComposerFile)]);
680
- setAttachmentError(null);
644
+ addFiles(Array.from(event.target.files ?? []));
681
645
  event.currentTarget.value = "";
682
646
  }
683
647
  }
@@ -698,7 +662,6 @@ function ChatComposer({
698
662
  isExpanded ? "py-2" : "h-9 py-2"
699
663
  ),
700
664
  onChange: (event) => {
701
- draftRevisionRef.current += 1;
702
665
  setText(event.target.value);
703
666
  },
704
667
  onKeyDown: (event) => {
@@ -738,7 +701,7 @@ function ChatComposer({
738
701
  ) : validationError ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Tooltip, { children: [
739
702
  /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { tabIndex: 0, "aria-label": validationError, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Button, { size: "icon", "aria-label": isRunning ? "Queue message" : "Send message", disabled: true, onClick: () => void submit(), children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_lucide_react3.ArrowUp, {}) }) }) }),
740
703
  /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(TooltipContent, { children: validationError })
741
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Button, { size: "icon", "aria-label": isRunning ? "Queue message" : "Send message", disabled, onClick: () => void submit(), children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_lucide_react3.ArrowUp, {}) })
704
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Button, { size: "icon", "aria-label": isRunning ? "Queue message" : "Send message", disabled: !canSubmit, onClick: () => void submit(), children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_lucide_react3.ArrowUp, {}) })
742
705
  ] })
743
706
  ]
744
707
  }
@@ -947,19 +910,20 @@ function DialogDescription({
947
910
  var import_jsx_runtime10 = require("react/jsx-runtime");
948
911
  function ExternalLinkDialog({ isOpen, onClose, onConfirm, url }) {
949
912
  const [copied, setCopied] = React4.useState(false);
950
- React4.useEffect(() => {
951
- if (!isOpen) setCopied(false);
952
- }, [isOpen]);
913
+ const close = () => {
914
+ setCopied(false);
915
+ onClose();
916
+ };
953
917
  const copyUrl = async () => {
954
918
  await navigator.clipboard.writeText(url);
955
919
  setCopied(true);
956
920
  };
957
921
  const openUrl = () => {
958
922
  onConfirm();
959
- onClose();
923
+ close();
960
924
  };
961
925
  return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Dialog, { open: isOpen, onOpenChange: (open) => {
962
- if (!open) onClose();
926
+ if (!open) close();
963
927
  }, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(DialogContent, { className: "max-h-[calc(100dvh-2rem)] min-w-0 overflow-hidden sm:max-w-md", children: [
964
928
  /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(DialogHeader, { children: [
965
929
  /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(DialogTitle, { children: "Open external link?" }),
@@ -1221,23 +1185,147 @@ function ChatMessage({
1221
1185
  ] }) });
1222
1186
  }
1223
1187
 
1224
- // scaffold/src/components/chat/theme-menu.tsx
1225
- var import_lucide_react6 = require("lucide-react");
1188
+ // scaffold/src/components/chat/subagent-tasks.tsx
1226
1189
  var React5 = __toESM(require("react"), 1);
1190
+ var import_react = require("@agents24/react");
1191
+ var import_ui4 = require("@agents24/chat-react/ui");
1192
+ var import_runtime = require("@agents24/chat-react/runtime");
1227
1193
  var import_jsx_runtime15 = require("react/jsx-runtime");
1194
+ function SubagentTasks({ threadId }) {
1195
+ const client = (0, import_react.useAgentClient)();
1196
+ const source = React5.useMemo(() => ({ events: (input) => client.threads.delegations.events(input) }), [client]);
1197
+ const { tasks, error, refresh } = (0, import_runtime.useDelegationTasks)({ threadId, source });
1198
+ const [selection, setSelection] = React5.useState({ threadId: null, handle: null });
1199
+ const selected = selection.threadId === threadId ? selection.handle : null;
1200
+ if (!threadId || !tasks.length && !error) return null;
1201
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("section", { "aria-label": "Subagent tasks", className: "mx-auto w-full max-w-3xl px-4 py-2 text-sm", children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("details", { children: [
1202
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("summary", { className: "cursor-pointer font-medium", children: [
1203
+ "Tasks (",
1204
+ tasks.length,
1205
+ ")"
1206
+ ] }),
1207
+ error ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("p", { role: "alert", children: "Task updates are unavailable. Retrying\u2026" }) : null,
1208
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("ul", { className: "max-h-56 overflow-y-auto", children: tasks.map((task) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("li", { style: { paddingInlineStart: Math.max(0, task.depth - 1) * 12 }, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
1209
+ "button",
1210
+ {
1211
+ type: "button",
1212
+ className: "flex w-full items-center justify-between gap-3 rounded-md px-2 py-2 text-start hover:bg-muted",
1213
+ onClick: () => setSelection({ threadId, handle: selected === task.handle ? null : task.handle }),
1214
+ "aria-expanded": selected === task.handle,
1215
+ children: [
1216
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("span", { className: "min-w-0 truncate", children: [
1217
+ task.name,
1218
+ task.background ? " \xB7 Background" : ""
1219
+ ] }),
1220
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "shrink-0 text-xs text-muted-foreground", children: task.status.replaceAll("_", " ") })
1221
+ ]
1222
+ }
1223
+ ) }, task.handle)) }),
1224
+ tasks.filter((task) => task.handle === selected).map((task) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(TaskConversation, { threadId, task, onChanged: refresh }, `${threadId}:${task.handle}`))
1225
+ ] }) });
1226
+ }
1227
+ function TaskConversation({ threadId, task, onChanged }) {
1228
+ const client = (0, import_react.useAgentClient)();
1229
+ const [history, setHistory] = React5.useState(null);
1230
+ const [earlier, setEarlier] = React5.useState([]);
1231
+ const historyInitialized = React5.useRef(false);
1232
+ const [before, setBefore] = React5.useState(null);
1233
+ const [error, setError] = React5.useState(null);
1234
+ const [busy, setBusy] = React5.useState(false);
1235
+ const operation = React5.useRef(null);
1236
+ React5.useEffect(() => {
1237
+ const controller = new AbortController();
1238
+ let timer;
1239
+ const refresh = async () => {
1240
+ try {
1241
+ const page = await client.threads.delegations.history({ threadId, handle: task.handle, signal: controller.signal });
1242
+ if (controller.signal.aborted) return;
1243
+ setHistory(page);
1244
+ if (!historyInitialized.current) {
1245
+ historyInitialized.current = true;
1246
+ setBefore(page.paging.next_before_turn_index);
1247
+ }
1248
+ } catch {
1249
+ if (!controller.signal.aborted) setError("Task history could not be loaded.");
1250
+ } finally {
1251
+ if (!controller.signal.aborted) timer = setTimeout(refresh, 2e3);
1252
+ }
1253
+ };
1254
+ void refresh();
1255
+ return () => {
1256
+ controller.abort();
1257
+ clearTimeout(timer);
1258
+ };
1259
+ }, [client, threadId, task.handle]);
1260
+ const loadEarlier = async () => {
1261
+ if (before === null) return;
1262
+ setBusy(true);
1263
+ try {
1264
+ const page = await client.threads.delegations.history({ threadId, handle: task.handle, before });
1265
+ setEarlier((current) => [...page.turns, ...current]);
1266
+ setBefore(page.paging.next_before_turn_index);
1267
+ } catch {
1268
+ setError("Earlier task history could not be loaded.");
1269
+ } finally {
1270
+ setBusy(false);
1271
+ }
1272
+ };
1273
+ const act = async (action) => {
1274
+ setBusy(true);
1275
+ setError(null);
1276
+ if (operation.current?.action !== action) operation.current = { action, id: crypto.randomUUID() };
1277
+ try {
1278
+ await client.threads.delegations.act({
1279
+ threadId,
1280
+ handle: task.handle,
1281
+ action: { action, operation_id: operation.current.id }
1282
+ });
1283
+ operation.current = null;
1284
+ onChanged();
1285
+ } catch {
1286
+ setError("The task action could not be completed. Try again.");
1287
+ } finally {
1288
+ setBusy(false);
1289
+ }
1290
+ };
1291
+ const turns = Array.from(new Map([...earlier, ...history?.turns || []].map((turn) => [turn.id, turn])).values()).sort((a, b) => a.turn_index - b.turn_index);
1292
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "space-y-3 rounded-md bg-muted/30 p-3", children: [
1293
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("h3", { className: "font-medium", children: task.name }),
1294
+ error ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("p", { role: "alert", children: error }) : null,
1295
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "flex flex-wrap gap-2", children: [
1296
+ task.capabilities.interrupt ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Button, { variant: "secondary", size: "sm", disabled: busy, onClick: () => void act("interrupt"), children: "Interrupt" }) : null,
1297
+ task.capabilities.cancel ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Button, { variant: "secondary", size: "sm", disabled: busy, onClick: () => void act("cancel"), children: "Cancel task" }) : null,
1298
+ before !== null ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Button, { variant: "ghost", size: "sm", disabled: busy, onClick: () => void loadEarlier(), children: "Earlier exchanges" }) : null
1299
+ ] }),
1300
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "max-h-[55dvh] space-y-4 overflow-y-auto break-words", children: turns.map((turn) => /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("article", { className: "space-y-2", children: [
1301
+ turn.assignment_instruction ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("p", { className: "whitespace-pre-wrap text-muted-foreground", children: turn.assignment_instruction }) : null,
1302
+ turn.user_input_text ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("p", { className: "whitespace-pre-wrap", children: turn.user_input_text }) : null,
1303
+ turn.exchanges?.map((exchange) => /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "whitespace-pre-wrap break-words text-sm", children: [
1304
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("p", { className: "text-xs font-medium", children: exchange.sender === "parent" ? "Parent Agent" : "Subagent update" }),
1305
+ exchange.text
1306
+ ] }, exchange.id)),
1307
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_ui4.AgentResponseTimeline, { message: { id: turn.id, role: "assistant", createdAt: turn.created_at, content: turn.assistant_output_text || "", parts: (0, import_react.partsFromResponseBlocks)(turn.response_blocks) } })
1308
+ ] }, turn.id)) })
1309
+ ] });
1310
+ }
1311
+
1312
+ // scaffold/src/components/chat/theme-menu.tsx
1313
+ var import_lucide_react6 = require("lucide-react");
1314
+ var React6 = __toESM(require("react"), 1);
1315
+ var import_jsx_runtime16 = require("react/jsx-runtime");
1228
1316
  var options = [
1229
1317
  { value: "system", label: "System", icon: import_lucide_react6.Laptop },
1230
1318
  { value: "light", label: "Light", icon: import_lucide_react6.Sun },
1231
1319
  { value: "dark", label: "Dark", icon: import_lucide_react6.Moon }
1232
1320
  ];
1233
1321
  function ThemeMenu() {
1234
- const { appearance, setAppearance } = useTheme();
1235
- const [open, setOpen] = React5.useState(false);
1236
- const rootRef = React5.useRef(null);
1237
- const firstItemRef = React5.useRef(null);
1238
- const menuId = React5.useId();
1322
+ const { appearance, setAppearance, inherited } = useTheme();
1323
+ const [open, setOpen] = React6.useState(false);
1324
+ const rootRef = React6.useRef(null);
1325
+ const firstItemRef = React6.useRef(null);
1326
+ const menuId = React6.useId();
1239
1327
  const ActiveIcon = options.find((item) => item.value === appearance)?.icon ?? import_lucide_react6.Laptop;
1240
- React5.useEffect(() => {
1328
+ React6.useEffect(() => {
1241
1329
  if (!open) return;
1242
1330
  firstItemRef.current?.focus();
1243
1331
  const closeOnOutsidePointer = (event) => {
@@ -1253,9 +1341,10 @@ function ThemeMenu() {
1253
1341
  document.removeEventListener("keydown", closeOnEscape);
1254
1342
  };
1255
1343
  }, [open]);
1344
+ if (inherited) return null;
1256
1345
  const label = appearance === "system" ? "System" : appearance === "light" ? "Light" : "Dark";
1257
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { ref: rootRef, className: "relative", children: [
1258
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1346
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { ref: rootRef, className: "relative", children: [
1347
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
1259
1348
  Button,
1260
1349
  {
1261
1350
  "aria-controls": menuId,
@@ -1265,16 +1354,16 @@ function ThemeMenu() {
1265
1354
  onClick: () => setOpen((value) => !value),
1266
1355
  size: "icon-sm",
1267
1356
  variant: "ghost",
1268
- children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ActiveIcon, {})
1357
+ children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(ActiveIcon, {})
1269
1358
  }
1270
1359
  ),
1271
- open ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1360
+ open ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
1272
1361
  "div",
1273
1362
  {
1274
1363
  id: menuId,
1275
1364
  className: "absolute end-0 top-full z-50 mt-1 flex min-w-44 flex-col rounded-xl border bg-popover p-1 text-popover-foreground shadow-md",
1276
1365
  role: "menu",
1277
- children: options.map(({ value, label: optionLabel, icon: Icon }, index) => /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
1366
+ children: options.map(({ value, label: optionLabel, icon: Icon }, index) => /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
1278
1367
  Button,
1279
1368
  {
1280
1369
  ref: index === 0 ? firstItemRef : void 0,
@@ -1288,7 +1377,7 @@ function ThemeMenu() {
1288
1377
  size: "sm",
1289
1378
  variant: "ghost",
1290
1379
  children: [
1291
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Icon, {}),
1380
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Icon, {}),
1292
1381
  " ",
1293
1382
  optionLabel
1294
1383
  ]
@@ -1301,23 +1390,23 @@ function ThemeMenu() {
1301
1390
  }
1302
1391
 
1303
1392
  // scaffold/src/components/chat/thread-sidebar.tsx
1304
- var import_react = require("@agents24/react");
1393
+ var import_react2 = require("@agents24/react");
1305
1394
  var import_lucide_react10 = require("lucide-react");
1306
1395
 
1307
1396
  // scaffold/src/components/chat/identity-control.tsx
1308
1397
  var import_lucide_react9 = require("lucide-react");
1309
1398
 
1310
1399
  // scaffold/src/components/ui/sidebar.tsx
1311
- var React7 = __toESM(require("react"), 1);
1400
+ var React8 = __toESM(require("react"), 1);
1312
1401
  var import_class_variance_authority3 = require("class-variance-authority");
1313
1402
  var import_radix_ui9 = require("radix-ui");
1314
1403
 
1315
1404
  // scaffold/src/hooks/use-mobile.ts
1316
- var React6 = __toESM(require("react"), 1);
1405
+ var React7 = __toESM(require("react"), 1);
1317
1406
  var MOBILE_BREAKPOINT = 768;
1318
1407
  function useIsMobile() {
1319
- const [isMobile, setIsMobile] = React6.useState(void 0);
1320
- React6.useEffect(() => {
1408
+ const [isMobile, setIsMobile] = React7.useState(void 0);
1409
+ React7.useEffect(() => {
1321
1410
  const onChange = () => {
1322
1411
  setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
1323
1412
  };
@@ -1335,31 +1424,31 @@ function useIsMobile() {
1335
1424
  }
1336
1425
 
1337
1426
  // scaffold/src/components/ui/input.tsx
1338
- var import_jsx_runtime16 = require("react/jsx-runtime");
1427
+ var import_jsx_runtime17 = require("react/jsx-runtime");
1339
1428
 
1340
1429
  // scaffold/src/components/ui/separator.tsx
1341
1430
  var import_radix_ui7 = require("radix-ui");
1342
- var import_jsx_runtime17 = require("react/jsx-runtime");
1431
+ var import_jsx_runtime18 = require("react/jsx-runtime");
1343
1432
 
1344
1433
  // scaffold/src/components/ui/sheet.tsx
1345
1434
  var import_radix_ui8 = require("radix-ui");
1346
1435
  var import_lucide_react7 = require("lucide-react");
1347
- var import_jsx_runtime18 = require("react/jsx-runtime");
1436
+ var import_jsx_runtime19 = require("react/jsx-runtime");
1348
1437
  function Sheet({ ...props }) {
1349
- return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_radix_ui8.Dialog.Root, { "data-slot": "sheet", ...props });
1438
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_radix_ui8.Dialog.Root, { "data-slot": "sheet", ...props });
1350
1439
  }
1351
1440
  function SheetPortal({
1352
1441
  container,
1353
1442
  ...props
1354
1443
  }) {
1355
1444
  const themeContainer = useThemePortalContainer();
1356
- return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_radix_ui8.Dialog.Portal, { container: container || themeContainer || void 0, "data-slot": "sheet-portal", ...props });
1445
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_radix_ui8.Dialog.Portal, { container: container || themeContainer || void 0, "data-slot": "sheet-portal", ...props });
1357
1446
  }
1358
1447
  function SheetOverlay({
1359
1448
  className,
1360
1449
  ...props
1361
1450
  }) {
1362
- return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
1451
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
1363
1452
  import_radix_ui8.Dialog.Overlay,
1364
1453
  {
1365
1454
  "data-slot": "sheet-overlay",
@@ -1378,9 +1467,9 @@ function SheetContent({
1378
1467
  showCloseButton = true,
1379
1468
  ...props
1380
1469
  }) {
1381
- return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(SheetPortal, { children: [
1382
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(SheetOverlay, {}),
1383
- /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
1470
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(SheetPortal, { children: [
1471
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(SheetOverlay, {}),
1472
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
1384
1473
  import_radix_ui8.Dialog.Content,
1385
1474
  {
1386
1475
  "data-slot": "sheet-content",
@@ -1392,18 +1481,18 @@ function SheetContent({
1392
1481
  ...props,
1393
1482
  children: [
1394
1483
  children,
1395
- showCloseButton && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_radix_ui8.Dialog.Close, { "data-slot": "sheet-close", asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
1484
+ showCloseButton && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_radix_ui8.Dialog.Close, { "data-slot": "sheet-close", asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
1396
1485
  Button,
1397
1486
  {
1398
1487
  variant: "ghost",
1399
1488
  className: "absolute top-4 right-4 bg-secondary",
1400
1489
  size: "icon-sm",
1401
1490
  children: [
1402
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
1491
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
1403
1492
  import_lucide_react7.XIcon,
1404
1493
  {}
1405
1494
  ),
1406
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "sr-only", children: "Close" })
1495
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "sr-only", children: "Close" })
1407
1496
  ]
1408
1497
  }
1409
1498
  ) })
@@ -1413,7 +1502,7 @@ function SheetContent({
1413
1502
  ] });
1414
1503
  }
1415
1504
  function SheetHeader({ className, ...props }) {
1416
- return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
1505
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
1417
1506
  "div",
1418
1507
  {
1419
1508
  "data-slot": "sheet-header",
@@ -1426,7 +1515,7 @@ function SheetTitle({
1426
1515
  className,
1427
1516
  ...props
1428
1517
  }) {
1429
- return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
1518
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
1430
1519
  import_radix_ui8.Dialog.Title,
1431
1520
  {
1432
1521
  "data-slot": "sheet-title",
@@ -1442,7 +1531,7 @@ function SheetDescription({
1442
1531
  className,
1443
1532
  ...props
1444
1533
  }) {
1445
- return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
1534
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
1446
1535
  import_radix_ui8.Dialog.Description,
1447
1536
  {
1448
1537
  "data-slot": "sheet-description",
@@ -1453,17 +1542,17 @@ function SheetDescription({
1453
1542
  }
1454
1543
 
1455
1544
  // scaffold/src/components/ui/skeleton.tsx
1456
- var import_jsx_runtime19 = require("react/jsx-runtime");
1545
+ var import_jsx_runtime20 = require("react/jsx-runtime");
1457
1546
 
1458
1547
  // scaffold/src/components/ui/sidebar.tsx
1459
1548
  var import_lucide_react8 = require("lucide-react");
1460
- var import_jsx_runtime20 = require("react/jsx-runtime");
1549
+ var import_jsx_runtime21 = require("react/jsx-runtime");
1461
1550
  var SIDEBAR_COOKIE_NAME = "sidebar_state";
1462
1551
  var SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7;
1463
1552
  var SIDEBAR_KEYBOARD_SHORTCUT = "b";
1464
- var SidebarContext = React7.createContext(null);
1553
+ var SidebarContext = React8.createContext(null);
1465
1554
  function useSidebar() {
1466
- const context = React7.useContext(SidebarContext);
1555
+ const context = React8.useContext(SidebarContext);
1467
1556
  if (!context) {
1468
1557
  throw new Error("useSidebar must be used within a SidebarProvider.");
1469
1558
  }
@@ -1478,10 +1567,10 @@ function SidebarProvider({
1478
1567
  ...props
1479
1568
  }) {
1480
1569
  const isMobile = useIsMobile();
1481
- const [openMobile, setOpenMobile] = React7.useState(false);
1482
- const [_open, _setOpen] = React7.useState(defaultOpen);
1570
+ const [openMobile, setOpenMobile] = React8.useState(false);
1571
+ const [_open, _setOpen] = React8.useState(defaultOpen);
1483
1572
  const open = openProp ?? _open;
1484
- const setOpen = React7.useCallback(
1573
+ const setOpen = React8.useCallback(
1485
1574
  (value) => {
1486
1575
  const openState = typeof value === "function" ? value(open) : value;
1487
1576
  if (setOpenProp) {
@@ -1493,10 +1582,10 @@ function SidebarProvider({
1493
1582
  },
1494
1583
  [setOpenProp, open]
1495
1584
  );
1496
- const toggleSidebar = React7.useCallback(() => {
1585
+ const toggleSidebar = React8.useCallback(() => {
1497
1586
  return isMobile ? setOpenMobile((open2) => !open2) : setOpen((open2) => !open2);
1498
1587
  }, [isMobile, setOpen, setOpenMobile]);
1499
- React7.useEffect(() => {
1588
+ React8.useEffect(() => {
1500
1589
  const handleKeyDown = (event) => {
1501
1590
  if (event.key === SIDEBAR_KEYBOARD_SHORTCUT && (event.metaKey || event.ctrlKey)) {
1502
1591
  event.preventDefault();
@@ -1507,7 +1596,7 @@ function SidebarProvider({
1507
1596
  return () => window.removeEventListener("keydown", handleKeyDown);
1508
1597
  }, [toggleSidebar]);
1509
1598
  const state = open ? "expanded" : "collapsed";
1510
- const contextValue = React7.useMemo(
1599
+ const contextValue = React8.useMemo(
1511
1600
  () => ({
1512
1601
  state,
1513
1602
  open,
@@ -1519,7 +1608,7 @@ function SidebarProvider({
1519
1608
  }),
1520
1609
  [state, open, setOpen, isMobile, openMobile, setOpenMobile, toggleSidebar]
1521
1610
  );
1522
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(SidebarContext.Provider, { value: contextValue, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
1611
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(SidebarContext.Provider, { value: contextValue, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
1523
1612
  "div",
1524
1613
  {
1525
1614
  "data-slot": "sidebar-wrapper",
@@ -1543,7 +1632,7 @@ function Sidebar({
1543
1632
  }) {
1544
1633
  const { isMobile, state, openMobile, setOpenMobile } = useSidebar();
1545
1634
  if (collapsible === "none") {
1546
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
1635
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
1547
1636
  "div",
1548
1637
  {
1549
1638
  "data-slot": "sidebar",
@@ -1557,7 +1646,7 @@ function Sidebar({
1557
1646
  );
1558
1647
  }
1559
1648
  if (isMobile) {
1560
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Sheet, { open: openMobile, onOpenChange: setOpenMobile, ...props, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
1649
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(Sheet, { open: openMobile, onOpenChange: setOpenMobile, ...props, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
1561
1650
  SheetContent,
1562
1651
  {
1563
1652
  dir,
@@ -1567,16 +1656,16 @@ function Sidebar({
1567
1656
  className: "w-(--sidebar-width) bg-sidebar p-0 text-sidebar-foreground [--sidebar-width:18rem] [&>button]:hidden",
1568
1657
  side,
1569
1658
  children: [
1570
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(SheetHeader, { className: "sr-only", children: [
1571
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(SheetTitle, { children: "Sidebar" }),
1572
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(SheetDescription, { children: "Displays the mobile sidebar." })
1659
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(SheetHeader, { className: "sr-only", children: [
1660
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(SheetTitle, { children: "Sidebar" }),
1661
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(SheetDescription, { children: "Displays the mobile sidebar." })
1573
1662
  ] }),
1574
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "flex h-full w-full flex-col", children })
1663
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "flex h-full w-full flex-col", children })
1575
1664
  ]
1576
1665
  }
1577
1666
  ) });
1578
1667
  }
1579
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
1668
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
1580
1669
  "div",
1581
1670
  {
1582
1671
  className: "group peer hidden text-sidebar-foreground md:block",
@@ -1586,7 +1675,7 @@ function Sidebar({
1586
1675
  "data-side": side,
1587
1676
  "data-slot": "sidebar",
1588
1677
  children: [
1589
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
1678
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
1590
1679
  "div",
1591
1680
  {
1592
1681
  "data-slot": "sidebar-gap",
@@ -1598,7 +1687,7 @@ function Sidebar({
1598
1687
  )
1599
1688
  }
1600
1689
  ),
1601
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
1690
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
1602
1691
  "div",
1603
1692
  {
1604
1693
  "data-slot": "sidebar-container",
@@ -1610,7 +1699,7 @@ function Sidebar({
1610
1699
  className
1611
1700
  ),
1612
1701
  ...props,
1613
- children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
1702
+ children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
1614
1703
  "div",
1615
1704
  {
1616
1705
  "data-sidebar": "sidebar",
@@ -1631,7 +1720,7 @@ function SidebarTrigger({
1631
1720
  ...props
1632
1721
  }) {
1633
1722
  const { toggleSidebar } = useSidebar();
1634
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
1723
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
1635
1724
  Button,
1636
1725
  {
1637
1726
  "data-sidebar": "trigger",
@@ -1645,15 +1734,15 @@ function SidebarTrigger({
1645
1734
  },
1646
1735
  ...props,
1647
1736
  children: [
1648
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react8.PanelLeftIcon, {}),
1649
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "sr-only", children: "Toggle Sidebar" })
1737
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react8.PanelLeftIcon, {}),
1738
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "sr-only", children: "Toggle Sidebar" })
1650
1739
  ]
1651
1740
  }
1652
1741
  );
1653
1742
  }
1654
1743
  function SidebarRail({ className, ...props }) {
1655
1744
  const { toggleSidebar } = useSidebar();
1656
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
1745
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
1657
1746
  "button",
1658
1747
  {
1659
1748
  "data-sidebar": "rail",
@@ -1676,7 +1765,7 @@ function SidebarRail({ className, ...props }) {
1676
1765
  );
1677
1766
  }
1678
1767
  function SidebarInset({ className, ...props }) {
1679
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
1768
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
1680
1769
  "main",
1681
1770
  {
1682
1771
  "data-slot": "sidebar-inset",
@@ -1689,7 +1778,7 @@ function SidebarInset({ className, ...props }) {
1689
1778
  );
1690
1779
  }
1691
1780
  function SidebarHeader({ className, ...props }) {
1692
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
1781
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
1693
1782
  "div",
1694
1783
  {
1695
1784
  "data-slot": "sidebar-header",
@@ -1703,7 +1792,7 @@ function SidebarHeader({ className, ...props }) {
1703
1792
  );
1704
1793
  }
1705
1794
  function SidebarFooter({ className, ...props }) {
1706
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
1795
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
1707
1796
  "div",
1708
1797
  {
1709
1798
  "data-slot": "sidebar-footer",
@@ -1714,7 +1803,7 @@ function SidebarFooter({ className, ...props }) {
1714
1803
  );
1715
1804
  }
1716
1805
  function SidebarContent({ className, ...props }) {
1717
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
1806
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
1718
1807
  "div",
1719
1808
  {
1720
1809
  "data-slot": "sidebar-content",
@@ -1728,7 +1817,7 @@ function SidebarContent({ className, ...props }) {
1728
1817
  );
1729
1818
  }
1730
1819
  function SidebarGroup({ className, ...props }) {
1731
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
1820
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
1732
1821
  "div",
1733
1822
  {
1734
1823
  "data-slot": "sidebar-group",
@@ -1742,7 +1831,7 @@ function SidebarGroupContent({
1742
1831
  className,
1743
1832
  ...props
1744
1833
  }) {
1745
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
1834
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
1746
1835
  "div",
1747
1836
  {
1748
1837
  "data-slot": "sidebar-group-content",
@@ -1753,7 +1842,7 @@ function SidebarGroupContent({
1753
1842
  );
1754
1843
  }
1755
1844
  function SidebarMenu({ className, ...props }) {
1756
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
1845
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
1757
1846
  "ul",
1758
1847
  {
1759
1848
  "data-slot": "sidebar-menu",
@@ -1764,7 +1853,7 @@ function SidebarMenu({ className, ...props }) {
1764
1853
  );
1765
1854
  }
1766
1855
  function SidebarMenuItem({ className, ...props }) {
1767
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
1856
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
1768
1857
  "li",
1769
1858
  {
1770
1859
  "data-slot": "sidebar-menu-item",
@@ -1805,7 +1894,7 @@ function SidebarMenuButton({
1805
1894
  }) {
1806
1895
  const Comp = asChild ? import_radix_ui9.Slot.Root : "button";
1807
1896
  const { isMobile, state } = useSidebar();
1808
- const button = /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
1897
+ const button = /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
1809
1898
  Comp,
1810
1899
  {
1811
1900
  "data-slot": "sidebar-menu-button",
@@ -1824,9 +1913,9 @@ function SidebarMenuButton({
1824
1913
  children: tooltip
1825
1914
  };
1826
1915
  }
1827
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(Tooltip, { children: [
1828
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(TooltipTrigger, { asChild: true, children: button }),
1829
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
1916
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(Tooltip, { children: [
1917
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(TooltipTrigger, { asChild: true, children: button }),
1918
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
1830
1919
  TooltipContent,
1831
1920
  {
1832
1921
  side: "right",
@@ -1844,7 +1933,7 @@ function SidebarMenuAction({
1844
1933
  ...props
1845
1934
  }) {
1846
1935
  const Comp = asChild ? import_radix_ui9.Slot.Root : "button";
1847
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
1936
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
1848
1937
  Comp,
1849
1938
  {
1850
1939
  "data-slot": "sidebar-menu-action",
@@ -1860,7 +1949,7 @@ function SidebarMenuAction({
1860
1949
  }
1861
1950
 
1862
1951
  // scaffold/src/components/chat/identity-control.tsx
1863
- var import_jsx_runtime21 = require("react/jsx-runtime");
1952
+ var import_jsx_runtime22 = require("react/jsx-runtime");
1864
1953
  function identityLabel(identity) {
1865
1954
  if (identity.displayName) return identity.displayName;
1866
1955
  if (identity.state === "authenticated") return "Signed in";
@@ -1870,44 +1959,43 @@ function identityLabel(identity) {
1870
1959
  return "Guest";
1871
1960
  }
1872
1961
  function IdentityAvatar({ identity }) {
1873
- const label = identityLabel(identity);
1874
1962
  if (identity.avatarUrl) {
1875
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("img", { alt: "", className: "size-6 rounded-full object-cover", src: identity.avatarUrl });
1963
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("img", { alt: "", className: "size-6 rounded-full object-cover", src: identity.avatarUrl });
1876
1964
  }
1877
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "flex size-6 items-center justify-center rounded-full bg-sidebar-accent text-[10px] font-semibold", "aria-hidden": "true", children: identity.displayName ? identity.displayName.slice(0, 1).toUpperCase() : /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react9.UserRound, { className: "size-3.5" }) });
1965
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "flex size-6 items-center justify-center rounded-full bg-sidebar-accent text-[10px] font-semibold", "aria-hidden": "true", children: identity.displayName ? identity.displayName.slice(0, 1).toUpperCase() : /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_lucide_react9.UserRound, { className: "size-3.5" }) });
1878
1966
  }
1879
1967
  function IdentityControl({ identity }) {
1880
1968
  const label = identityLabel(identity);
1881
1969
  const canSignOut = identity.state === "authenticated" && Boolean(identity.onSignOut);
1882
1970
  const canSignIn = (identity.state === "guest" || identity.state === "signed_out" || identity.state === "error") && Boolean(identity.onSignIn);
1883
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(SidebarMenu, { className: "w-full min-w-0", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(SidebarMenuItem, { className: "w-full min-w-0", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(DropdownMenu, { children: [
1884
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
1971
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(SidebarMenu, { className: "w-full min-w-0", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(SidebarMenuItem, { className: "w-full min-w-0", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(DropdownMenu, { children: [
1972
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
1885
1973
  SidebarMenuButton,
1886
1974
  {
1887
1975
  size: "lg",
1888
1976
  "aria-label": `Account: ${label}`,
1889
1977
  className: "w-full min-w-0 justify-start",
1890
1978
  children: [
1891
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(IdentityAvatar, { identity }),
1892
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("span", { className: "min-w-0 flex-1 overflow-hidden text-start", children: [
1893
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "block truncate text-sm font-medium", children: label }),
1894
- identity.secondaryText ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "block truncate text-xs text-muted-foreground", children: identity.secondaryText }) : null
1979
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(IdentityAvatar, { identity }),
1980
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("span", { className: "min-w-0 flex-1 overflow-hidden text-start", children: [
1981
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "block truncate text-sm font-medium", children: label }),
1982
+ identity.secondaryText ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "block truncate text-xs text-muted-foreground", children: identity.secondaryText }) : null
1895
1983
  ] })
1896
1984
  ]
1897
1985
  }
1898
1986
  ) }),
1899
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(DropdownMenuContent, { align: "start", side: "top", sideOffset: 8, children: [
1900
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(DropdownMenuLabel, { children: [
1901
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "block truncate", children: label }),
1902
- identity.secondaryText ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "mt-0.5 block truncate text-xs font-normal text-muted-foreground", children: identity.secondaryText }) : null
1987
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(DropdownMenuContent, { align: "start", side: "top", sideOffset: 8, children: [
1988
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(DropdownMenuLabel, { children: [
1989
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "block truncate", children: label }),
1990
+ identity.secondaryText ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "mt-0.5 block truncate text-xs font-normal text-muted-foreground", children: identity.secondaryText }) : null
1903
1991
  ] }),
1904
- canSignIn || canSignOut ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(DropdownMenuSeparator, {}) : null,
1905
- canSignIn ? /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(DropdownMenuItem, { onSelect: () => identity.onSignIn?.(), children: [
1906
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react9.LogIn, {}),
1992
+ canSignIn || canSignOut ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(DropdownMenuSeparator, {}) : null,
1993
+ canSignIn ? /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(DropdownMenuItem, { onSelect: () => identity.onSignIn?.(), children: [
1994
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_lucide_react9.LogIn, {}),
1907
1995
  "Sign in"
1908
1996
  ] }) : null,
1909
- canSignOut ? /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(DropdownMenuItem, { onSelect: () => identity.onSignOut?.(), children: [
1910
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react9.LogOut, {}),
1997
+ canSignOut ? /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(DropdownMenuItem, { onSelect: () => identity.onSignOut?.(), children: [
1998
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_lucide_react9.LogOut, {}),
1911
1999
  "Sign out"
1912
2000
  ] }) : null
1913
2001
  ] })
@@ -1915,25 +2003,25 @@ function IdentityControl({ identity }) {
1915
2003
  }
1916
2004
 
1917
2005
  // scaffold/src/components/chat/thread-sidebar.tsx
1918
- var import_jsx_runtime22 = require("react/jsx-runtime");
2006
+ var import_jsx_runtime23 = require("react/jsx-runtime");
1919
2007
  function ThreadStatus({ thread }) {
1920
- const activity = (0, import_react.getThreadActivity)(thread);
2008
+ const activity = (0, import_react2.getThreadActivity)(thread);
1921
2009
  if (!activity.isSpinning) return null;
1922
2010
  const label = activity.status === "cancelling" ? "Cancelling" : activity.status === "queued" ? "Queued" : "Running";
1923
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2011
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
1924
2012
  "span",
1925
2013
  {
1926
2014
  className: "pointer-events-none absolute end-1 top-1/2 hidden size-5 -translate-y-1/2 items-center justify-center text-muted-foreground transition-opacity group-hover/menu-item:opacity-0 md:flex",
1927
2015
  role: "status",
1928
2016
  "aria-label": label,
1929
2017
  title: label,
1930
- children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_lucide_react10.LoaderCircle, { className: "size-3.5 animate-spin" })
2018
+ children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react10.LoaderCircle, { className: "size-3.5 animate-spin" })
1931
2019
  }
1932
2020
  );
1933
2021
  }
1934
2022
  function ThreadSidebar({ activeThreadId, hasMore, identity, isLoading, isLoadingMore, onDelete, onLoadMore, onNew, onOpen, threads }) {
1935
2023
  const { setOpenMobile } = useSidebar();
1936
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
2024
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
1937
2025
  Sidebar,
1938
2026
  {
1939
2027
  "aria-label": "Conversations",
@@ -1941,19 +2029,19 @@ function ThreadSidebar({ activeThreadId, hasMore, identity, isLoading, isLoading
1941
2029
  "data-agents24-chat-sidebar": "",
1942
2030
  role: "navigation",
1943
2031
  children: [
1944
- /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(SidebarHeader, { className: "gap-1 p-2", children: [
1945
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "h-8 shrink-0", "aria-hidden": "true" }),
1946
- /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(Button, { className: "w-full justify-start", variant: "ghost", onClick: () => {
2032
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(SidebarHeader, { className: "gap-1 p-2", children: [
2033
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "h-8 shrink-0", "aria-hidden": "true" }),
2034
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(Button, { className: "w-full justify-start", variant: "ghost", onClick: () => {
1947
2035
  onNew();
1948
2036
  setOpenMobile(false);
1949
2037
  }, children: [
1950
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_lucide_react10.SquarePen, {}),
2038
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react10.SquarePen, {}),
1951
2039
  " New chat"
1952
2040
  ] })
1953
2041
  ] }),
1954
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(SidebarContent, { children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(SidebarGroup, { children: /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(SidebarGroupContent, { children: [
1955
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(SidebarMenu, { children: threads.map((thread) => /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(SidebarMenuItem, { children: [
1956
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2042
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(SidebarContent, { children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(SidebarGroup, { children: /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(SidebarGroupContent, { children: [
2043
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(SidebarMenu, { children: threads.map((thread) => /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(SidebarMenuItem, { children: [
2044
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
1957
2045
  SidebarMenuButton,
1958
2046
  {
1959
2047
  className: "pr-8 pl-3",
@@ -1963,11 +2051,11 @@ function ThreadSidebar({ activeThreadId, hasMore, identity, isLoading, isLoading
1963
2051
  void onOpen(thread.id).catch(() => void 0);
1964
2052
  setOpenMobile(false);
1965
2053
  },
1966
- children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "min-w-0 truncate", children: String(thread.title || "New conversation") })
2054
+ children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "min-w-0 truncate", children: String(thread.title || "New conversation") })
1967
2055
  }
1968
2056
  ),
1969
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(ThreadStatus, { thread }),
1970
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2057
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(ThreadStatus, { thread }),
2058
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
1971
2059
  SidebarMenuAction,
1972
2060
  {
1973
2061
  showOnHover: true,
@@ -1977,12 +2065,12 @@ function ThreadSidebar({ activeThreadId, hasMore, identity, isLoading, isLoading
1977
2065
  event.stopPropagation();
1978
2066
  if (window.confirm("Delete this conversation?")) void onDelete(thread.id).catch(() => void 0);
1979
2067
  },
1980
- children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_lucide_react10.Trash2, {})
2068
+ children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react10.Trash2, {})
1981
2069
  }
1982
2070
  )
1983
2071
  ] }, thread.id)) }),
1984
- !isLoading && threads.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("p", { className: "px-2 py-8 text-center text-xs text-muted-foreground", children: "No conversations" }),
1985
- hasMore && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
2072
+ !isLoading && threads.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { className: "px-2 py-8 text-center text-xs text-muted-foreground", children: "No conversations" }),
2073
+ hasMore && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
1986
2074
  Button,
1987
2075
  {
1988
2076
  className: "mt-2 w-full",
@@ -1991,14 +2079,14 @@ function ThreadSidebar({ activeThreadId, hasMore, identity, isLoading, isLoading
1991
2079
  variant: "ghost",
1992
2080
  onClick: () => void onLoadMore().catch(() => void 0),
1993
2081
  children: [
1994
- isLoadingMore && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_lucide_react10.LoaderCircle, { className: "animate-spin" }),
2082
+ isLoadingMore && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react10.LoaderCircle, { className: "animate-spin" }),
1995
2083
  "Load more"
1996
2084
  ]
1997
2085
  }
1998
2086
  )
1999
2087
  ] }) }) }),
2000
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(SidebarFooter, { className: "w-full min-w-0 p-2", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(IdentityControl, { identity }) }),
2001
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(SidebarRail, {})
2088
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(SidebarFooter, { className: "w-full min-w-0 p-2", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(IdentityControl, { identity }) }),
2089
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(SidebarRail, {})
2002
2090
  ]
2003
2091
  }
2004
2092
  );
@@ -2006,7 +2094,7 @@ function ThreadSidebar({ activeThreadId, hasMore, identity, isLoading, isLoading
2006
2094
 
2007
2095
  // scaffold/src/components/chat/turn-outline.tsx
2008
2096
  var import_chat_react = require("@agents24/chat-react");
2009
- var import_jsx_runtime23 = require("react/jsx-runtime");
2097
+ var import_jsx_runtime24 = require("react/jsx-runtime");
2010
2098
  function turnsFromMessages(messages) {
2011
2099
  return messages.reduce((turns, message) => {
2012
2100
  if (message.role === "user") {
@@ -2025,7 +2113,7 @@ function turnsFromMessages(messages) {
2025
2113
  }, []);
2026
2114
  }
2027
2115
  function TurnOutline({ messages }) {
2028
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
2116
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
2029
2117
  import_chat_react.LatestThreadScroller.Outline,
2030
2118
  {
2031
2119
  items: turnsFromMessages(messages),
@@ -2049,7 +2137,7 @@ function isScaffoldTimelineLoading({
2049
2137
 
2050
2138
  // scaffold/src/components/chat/chat-shell.tsx
2051
2139
  var import_chat_react2 = require("@agents24/chat-react");
2052
- var import_jsx_runtime24 = require("react/jsx-runtime");
2140
+ var import_jsx_runtime25 = require("react/jsx-runtime");
2053
2141
  var LOADING_INPUT_CONTRACT = {
2054
2142
  version: "agents24.runtime-inputs.v2",
2055
2143
  modalities: {
@@ -2062,31 +2150,31 @@ var LOADING_INPUT_CONTRACT = {
2062
2150
  retention: { mode: "thread_lifetime" }
2063
2151
  };
2064
2152
  function PersistentSidebarTrigger() {
2065
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "pointer-events-none fixed start-3 top-0 z-[60] flex h-12 items-center", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(SidebarTrigger, { className: "pointer-events-auto [&_svg]:size-[18px]" }) });
2153
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "pointer-events-none fixed start-3 top-0 z-[60] flex h-12 items-center", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(SidebarTrigger, { className: "pointer-events-auto [&_svg]:size-[18px]" }) });
2066
2154
  }
2067
2155
  function CollapsedHeaderActions({ onNew }) {
2068
2156
  const { isMobile, openMobile, state } = useSidebar();
2069
2157
  const sidebarVisible = isMobile ? openMobile : state === "expanded";
2070
2158
  if (sidebarVisible) return null;
2071
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_jsx_runtime24.Fragment, { children: [
2072
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "h-8 w-17 shrink-0", "aria-hidden": "true" }),
2073
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "pointer-events-none fixed start-12 top-0 z-[60] flex h-12 items-center", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(Button, { className: "pointer-events-auto", variant: "ghost", size: "icon-sm", "aria-label": "New chat", onClick: onNew, children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react11.SquarePen, {}) }) })
2159
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(import_jsx_runtime25.Fragment, { children: [
2160
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "h-8 w-17 shrink-0", "aria-hidden": "true" }),
2161
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "pointer-events-none fixed start-12 top-0 z-[60] flex h-12 items-center", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Button, { className: "pointer-events-auto", variant: "ghost", size: "icon-sm", "aria-label": "New chat", onClick: onNew, children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react11.SquarePen, {}) }) })
2074
2162
  ] });
2075
2163
  }
2076
2164
  function OperationErrorNotice({ runtime }) {
2077
2165
  const error = runtime.operationError || runtime.backgroundError;
2078
2166
  if (!error) return null;
2079
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "pointer-events-none absolute inset-x-0 top-3 z-40 flex justify-center px-4", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "pointer-events-auto flex max-w-lg items-start gap-2 rounded-lg border border-destructive/20 bg-background px-3 py-2 text-sm shadow-md", role: "alert", children: [
2080
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react11.CircleAlert, { className: "mt-0.5 size-4 shrink-0 text-destructive" }),
2081
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "min-w-0 flex-1 wrap-break-word", children: (0, import_runtime2.agentChatRuntimeErrorMessage)(error) || "The chat could not complete that action." }),
2082
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
2167
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "pointer-events-none absolute inset-x-0 top-3 z-40 flex justify-center px-4", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "pointer-events-auto flex max-w-lg items-start gap-2 rounded-lg border border-destructive/20 bg-background px-3 py-2 text-sm shadow-md", role: "alert", children: [
2168
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react11.CircleAlert, { className: "mt-0.5 size-4 shrink-0 text-destructive" }),
2169
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "min-w-0 flex-1 wrap-break-word", children: (0, import_runtime2.agentChatRuntimeErrorMessage)(error) || "The chat could not complete that action." }),
2170
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
2083
2171
  Button,
2084
2172
  {
2085
2173
  "aria-label": "Dismiss error",
2086
2174
  onClick: runtime.operationError ? runtime.clearOperationError : runtime.controller.clearBackgroundError,
2087
2175
  size: "icon-xs",
2088
2176
  variant: "ghost",
2089
- children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react11.X, {})
2177
+ children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react11.X, {})
2090
2178
  }
2091
2179
  )
2092
2180
  ] }) });
@@ -2097,28 +2185,29 @@ function ChatShell({
2097
2185
  runtime,
2098
2186
  sidebar
2099
2187
  }) {
2188
+ const Composer = components?.Composer || ChatComposer;
2100
2189
  const { controller } = runtime;
2101
2190
  const isUploading = controller.runState === "uploading";
2102
2191
  const isRunning = controller.runState === "streaming" || controller.runState === "reconnecting" || controller.runState === "paused" || controller.runState === "cancelling";
2103
2192
  const isCancelling = controller.runState === "cancelling";
2104
- const wasLiveRun = (0, import_ui4.useLiveCompletionRuns)(controller.activeRunId, isRunning);
2193
+ const wasLiveRun = (0, import_ui5.useLiveCompletionRuns)(controller.activeRunId, isRunning);
2105
2194
  const activeTitle = controller.threads.find((thread) => thread.id === controller.activeThreadId)?.title;
2106
2195
  const hasBlockingError = Boolean(runtime.fatalError && controller.messages.length === 0);
2107
2196
  const isEmptyState = controller.activeThreadId === null && controller.messages.length === 0 && !hasBlockingError;
2108
2197
  const latestAnchorId = (0, import_chat_react2.latestThreadAnchorId)(controller.messages);
2109
- const composerOverlayRef = React8.useRef(null);
2110
- const [composerOverlayHeight, setComposerOverlayHeight] = React8.useState(192);
2111
- const [restoredDraft, setRestoredDraft] = React8.useState(null);
2112
- const draftRevisionRef = React8.useRef(0);
2113
- const retractForEdit = React8.useCallback(async (message) => {
2198
+ const composerOverlayRef = React9.useRef(null);
2199
+ const [composerOverlayHeight, setComposerOverlayHeight] = React9.useState(192);
2200
+ const [restoredDraft, setRestoredDraft] = React9.useState(null);
2201
+ const draftRevisionRef = React9.useRef(0);
2202
+ const retractForEdit = React9.useCallback(async (message) => {
2114
2203
  const draft = await controller.retractPendingMessage(message);
2115
2204
  setRestoredDraft({
2116
2205
  revision: ++draftRevisionRef.current,
2117
2206
  text: draft.text,
2118
- files: (0, import_ui4.queuedMessageComposerFiles)(draft)
2207
+ files: (0, import_ui5.queuedMessageComposerFiles)(draft)
2119
2208
  });
2120
2209
  }, [controller]);
2121
- React8.useLayoutEffect(() => {
2210
+ React9.useLayoutEffect(() => {
2122
2211
  const overlay = composerOverlayRef.current;
2123
2212
  if (!overlay || isEmptyState) return;
2124
2213
  const updateHeight = () => {
@@ -2129,15 +2218,15 @@ function ChatShell({
2129
2218
  resizeObserver.observe(overlay);
2130
2219
  return () => resizeObserver.disconnect();
2131
2220
  }, [isEmptyState]);
2132
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
2221
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
2133
2222
  SidebarProvider,
2134
2223
  {
2135
2224
  className: "h-svh min-h-0 overflow-hidden",
2136
2225
  "data-agents24-chat": "",
2137
2226
  "data-agents24-chat-layout": "",
2138
2227
  children: [
2139
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(PersistentSidebarTrigger, {}),
2140
- sidebar || /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
2228
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(PersistentSidebarTrigger, {}),
2229
+ sidebar || /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
2141
2230
  ThreadSidebar,
2142
2231
  {
2143
2232
  activeThreadId: controller.activeThreadId,
@@ -2152,57 +2241,58 @@ function ChatShell({
2152
2241
  onOpen: runtime.openThread
2153
2242
  }
2154
2243
  ),
2155
- /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(SidebarInset, { className: "h-svh min-h-0 overflow-hidden bg-background", children: [
2156
- /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
2244
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(SidebarInset, { className: "h-svh min-h-0 overflow-hidden bg-background", children: [
2245
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
2157
2246
  "header",
2158
2247
  {
2159
2248
  className: "flex h-12 shrink-0 items-center gap-2 border-b border-border/50 px-3 sm:px-4",
2160
2249
  "data-agents24-chat-header": "",
2161
2250
  children: [
2162
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(CollapsedHeaderActions, { onNew: runtime.newThread }),
2163
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "min-w-0 flex-1", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("h1", { className: "truncate text-sm font-medium", children: String(activeTitle || "New chat") }) }),
2164
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(ThemeMenu, {})
2251
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(CollapsedHeaderActions, { onNew: runtime.newThread }),
2252
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "min-w-0 flex-1", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("h1", { className: "truncate text-sm font-medium", children: String(activeTitle || "New chat") }) }),
2253
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(ThemeMenu, {})
2165
2254
  ]
2166
2255
  }
2167
2256
  ),
2168
- /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
2257
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
2169
2258
  "section",
2170
2259
  {
2171
2260
  "aria-label": "Conversation",
2172
2261
  className: "relative flex min-h-0 flex-1 flex-col overflow-hidden",
2173
2262
  "data-agents24-chat-transcript": "",
2174
2263
  children: [
2175
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(OperationErrorNotice, { runtime }),
2176
- /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_chat_react2.LatestThreadScroller.Provider, { autoScroll: true, defaultScrollPosition: "last-anchor", scrollPreviousItemPeek: 64, children: [
2177
- !isEmptyState && /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_chat_react2.LatestThreadScroller.Root, { className: "relative min-h-0 flex-1", children: [
2178
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_chat_react2.LatestThreadScroller.Viewport, { preserveScrollOnPrepend: true, children: /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
2264
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(OperationErrorNotice, { runtime }),
2265
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(SubagentTasks, { threadId: controller.activeThreadId }),
2266
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(import_chat_react2.LatestThreadScroller.Provider, { autoScroll: true, defaultScrollPosition: "last-anchor", scrollPreviousItemPeek: 64, children: [
2267
+ !isEmptyState && /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(import_chat_react2.LatestThreadScroller.Root, { className: "relative min-h-0 flex-1", children: [
2268
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_chat_react2.LatestThreadScroller.Viewport, { preserveScrollOnPrepend: true, children: /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
2179
2269
  import_chat_react2.LatestThreadScroller.Content,
2180
2270
  {
2181
2271
  className: "mx-auto w-full max-w-3xl gap-3 px-4 pt-8 pb-0 sm:px-6 sm:pt-12",
2182
2272
  style: { paddingBottom: composerOverlayHeight + 72 },
2183
2273
  children: [
2184
- controller.hasOlderTurns && /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(Button, { className: "self-center", variant: "ghost", size: "sm", disabled: controller.isLoadingOlder, onClick: () => {
2274
+ controller.hasOlderTurns && /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(Button, { className: "self-center", variant: "ghost", size: "sm", disabled: controller.isLoadingOlder, onClick: () => {
2185
2275
  void controller.loadOlder().catch(() => void 0);
2186
2276
  }, children: [
2187
- controller.isLoadingOlder && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react11.LoaderCircle, { className: "animate-spin" }),
2277
+ controller.isLoadingOlder && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react11.LoaderCircle, { className: "animate-spin" }),
2188
2278
  " Load earlier messages"
2189
2279
  ] }),
2190
- runtime.isBootstrapping && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { "aria-label": "Loading conversation", className: "flex flex-1 items-center justify-center py-24 text-muted-foreground", role: "status", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react11.LoaderCircle, { className: "size-4 animate-spin" }) }),
2191
- hasBlockingError && /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex flex-1 flex-col items-center justify-center gap-3 py-24 text-center", children: [
2192
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react11.CircleAlert, { className: "size-5 text-destructive" }),
2193
- /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { children: [
2194
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("h2", { className: "font-medium", children: "Couldn\u2019t connect" }),
2195
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("p", { className: "mt-1 max-w-md text-sm text-muted-foreground", children: runtime.errorMessage })
2280
+ runtime.isBootstrapping && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { "aria-label": "Loading conversation", className: "flex flex-1 items-center justify-center py-24 text-muted-foreground", role: "status", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react11.LoaderCircle, { className: "size-4 animate-spin" }) }),
2281
+ hasBlockingError && /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex flex-1 flex-col items-center justify-center gap-3 py-24 text-center", children: [
2282
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react11.CircleAlert, { className: "size-5 text-destructive" }),
2283
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { children: [
2284
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("h2", { className: "font-medium", children: "Couldn\u2019t connect" }),
2285
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("p", { className: "mt-1 max-w-md text-sm text-muted-foreground", children: runtime.errorMessage })
2196
2286
  ] }),
2197
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(Button, { variant: "outline", onClick: () => void runtime.retryBootstrap(), children: "Try again" })
2287
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Button, { variant: "outline", onClick: () => void runtime.retryBootstrap(), children: "Try again" })
2198
2288
  ] }),
2199
- controller.messages.map((message) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
2289
+ controller.messages.map((message) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
2200
2290
  import_chat_react2.LatestThreadScroller.Item,
2201
2291
  {
2202
2292
  messageId: message.id,
2203
2293
  scrollAnchor: isRunning && message.id === latestAnchorId,
2204
2294
  className: "overflow-visible [content-visibility:visible]",
2205
- children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
2295
+ children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
2206
2296
  ChatMessage,
2207
2297
  {
2208
2298
  animateCompletion: wasLiveRun(message.runId),
@@ -2228,9 +2318,9 @@ function ChatShell({
2228
2318
  ]
2229
2319
  }
2230
2320
  ) }),
2231
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(TurnOutline, { messages: controller.messages })
2321
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(TurnOutline, { messages: controller.messages })
2232
2322
  ] }),
2233
- /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
2323
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
2234
2324
  "div",
2235
2325
  {
2236
2326
  ref: composerOverlayRef,
@@ -2239,56 +2329,52 @@ function ChatShell({
2239
2329
  background: "linear-gradient(to bottom, transparent 0%, color-mix(in oklch, var(--background) 85%, transparent) 45%, var(--background) 65%, var(--background) 100%)"
2240
2330
  },
2241
2331
  children: [
2242
- isEmptyState ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "mx-auto mb-8 w-full max-w-3xl px-4 text-center sm:px-6", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("h2", { className: "text-3xl font-semibold tracking-tight sm:text-4xl", children: "Ready when you are." }) }) : /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "pointer-events-auto absolute inset-x-0 top-0 flex -translate-y-full justify-center pb-3", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_chat_react2.LatestThreadScroller.Button, { className: "!relative !inset-auto !translate-x-0 rtl:!translate-x-0" }) }),
2243
- /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "pointer-events-auto mx-auto w-full max-w-3xl px-4 sm:px-6", children: [
2244
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
2245
- import_ui4.AgentChatQueue,
2246
- {
2247
- pending: controller.pendingMessages,
2248
- queue: controller.messageQueue,
2249
- canSteer: controller.runState === "streaming",
2250
- onSteer: controller.steerPendingMessage,
2251
- onRemove: controller.removePendingMessage,
2252
- onEdit: retractForEdit,
2253
- onResume: controller.resumeQueue
2254
- }
2255
- ),
2256
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
2257
- ChatComposer,
2258
- {
2259
- restoredDraft,
2260
- inputContract: runtime.inputContract || LOADING_INPUT_CONTRACT,
2261
- contextWindow: runtime.contextWindow,
2262
- disabled: runtime.isBootstrapping || runtime.isChangingAgent || isUploading || hasBlockingError,
2263
- focusKey: controller.activeThreadId,
2264
- forceExpanded: isEmptyState,
2265
- isCancelling,
2266
- isRunning,
2267
- agentId: runtime.agentId,
2268
- agents: runtime.agents,
2269
- onAgentChange: (agentId) => {
2270
- void runtime.changeAgent(agentId);
2271
- },
2272
- onStop: () => {
2273
- void controller.cancelRun().catch(() => void 0);
2274
- },
2275
- modelId: runtime.modelId,
2276
- models: runtime.models,
2277
- onModelChange: runtime.changeModel,
2278
- onSubmit: (text, files) => runtime.submit({
2279
- text,
2280
- files: files.filter((file) => file.source).map((file) => ({
2281
- data: file.source,
2282
- mediaType: file.mediaType,
2283
- name: file.filename
2284
- })),
2285
- attachmentIds: files.flatMap((file) => file.persistedAttachmentId ? [file.persistedAttachmentId] : []),
2286
- attachments: files
2287
- }),
2288
- utilityRow: isEmptyState ? "inline" : "below"
2289
- }
2290
- )
2291
- ] })
2332
+ isEmptyState ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "mx-auto mb-8 w-full max-w-3xl px-4 text-center sm:px-6", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("h2", { className: "text-3xl font-semibold tracking-tight sm:text-4xl", children: "Ready when you are." }) }) : /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "pointer-events-auto absolute inset-x-0 top-0 flex -translate-y-full justify-center pb-3", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_chat_react2.LatestThreadScroller.Button, { className: "!relative !inset-auto !translate-x-0 rtl:!translate-x-0" }) }),
2333
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "pointer-events-auto mx-auto w-full max-w-3xl px-4 sm:px-6", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
2334
+ Composer,
2335
+ {
2336
+ queue: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
2337
+ import_ui5.AgentChatQueue,
2338
+ {
2339
+ pending: controller.pendingMessages,
2340
+ queue: controller.messageQueue,
2341
+ onRemove: controller.removePendingMessage,
2342
+ onEdit: retractForEdit,
2343
+ onResume: controller.resumeQueue
2344
+ }
2345
+ ),
2346
+ restoredDraft,
2347
+ inputContract: runtime.inputContract || LOADING_INPUT_CONTRACT,
2348
+ contextWindow: runtime.contextWindow,
2349
+ disabled: runtime.isBootstrapping || runtime.isChangingAgent || isUploading || hasBlockingError,
2350
+ focusKey: controller.activeThreadId,
2351
+ forceExpanded: isEmptyState,
2352
+ isCancelling,
2353
+ isRunning,
2354
+ agentId: runtime.agentId,
2355
+ agents: runtime.agents,
2356
+ onAgentChange: (agentId) => {
2357
+ void runtime.changeAgent(agentId);
2358
+ },
2359
+ onStop: () => {
2360
+ void controller.cancelRun().catch(() => void 0);
2361
+ },
2362
+ modelId: runtime.modelId,
2363
+ models: runtime.models,
2364
+ onModelChange: runtime.changeModel,
2365
+ onSubmit: (text, files) => runtime.submit({
2366
+ text,
2367
+ files: files.filter((file) => file.source).map((file) => ({
2368
+ data: file.source,
2369
+ mediaType: file.mediaType,
2370
+ name: file.filename
2371
+ })),
2372
+ attachmentIds: files.flatMap((file) => file.persistedAttachmentId ? [file.persistedAttachmentId] : []),
2373
+ attachments: files
2374
+ }),
2375
+ utilityRow: isEmptyState ? "inline" : "below"
2376
+ }
2377
+ ) })
2292
2378
  ]
2293
2379
  }
2294
2380
  )
@@ -2306,7 +2392,7 @@ function ChatShell({
2306
2392
  var GUEST_CHAT_IDENTITY = { state: "guest" };
2307
2393
 
2308
2394
  // scaffold/src/app.tsx
2309
- var import_jsx_runtime25 = require("react/jsx-runtime");
2395
+ var import_jsx_runtime26 = require("react/jsx-runtime");
2310
2396
  var createBrowserAbortController = () => new AbortController();
2311
2397
  var browserVisibility = (0, import_browser.createBrowserVisibility)();
2312
2398
  function RuntimeChat({
@@ -2318,20 +2404,21 @@ function RuntimeChat({
2318
2404
  ...props,
2319
2405
  mcpRedirectUri: props.mcpRedirectUri || (typeof window === "undefined" ? void 0 : window.location.href)
2320
2406
  });
2321
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(ChatShell, { components, identity, runtime, sidebar: props.sidebar });
2407
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(ChatShell, { components, identity, runtime, sidebar: props.sidebar });
2322
2408
  }
2323
2409
  function App(props) {
2324
2410
  const identity = props.identity || GUEST_CHAT_IDENTITY;
2325
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_react2.Agents24Provider, { client: props.client, createAbortController: createBrowserAbortController, visibility: browserVisibility, children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(RuntimeChat, { ...props }, identity.state) });
2411
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_react3.Agents24Provider, { client: props.client, createAbortController: createBrowserAbortController, visibility: browserVisibility, children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(RuntimeChat, { ...props }, identity.state) });
2326
2412
  }
2327
2413
 
2328
2414
  // scaffold/src/index.tsx
2329
- var import_jsx_runtime26 = require("react/jsx-runtime");
2330
- function Agents24ChatScaffold({ appearanceController, theme, ...props }) {
2331
- return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(ThemeProvider, { controller: appearanceController, theme, children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(TooltipProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(App, { ...props }) }) });
2415
+ var import_jsx_runtime27 = require("react/jsx-runtime");
2416
+ function Agents24ChatScaffold({ appearanceController, theme, themeMode, ...props }) {
2417
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(ThemeProvider, { controller: appearanceController, theme, mode: themeMode, children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(TooltipProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(App, { ...props }) }) });
2332
2418
  }
2333
2419
  // Annotate the CommonJS export names for ESM import in node:
2334
2420
  0 && (module.exports = {
2421
+ Agents24ChatComposer,
2335
2422
  Agents24ChatScaffold,
2336
2423
  Agents24ChatScaffoldApp,
2337
2424
  Agents24ChatThemeProvider,