@cntyclub/agent-react 0.18.0 → 0.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
- import { cn, Button, ThinkingOrb, Tooltip, TooltipTrigger, TooltipContent, ChatMessage, ChatMessageBubble, Markdown, AuroraText, Spinner, Checkbox, Collapsible, CollapsibleTrigger, ChatToolChip, CollapsiblePanel, ChatToolCard, ChatToolCardHeader, ChatToolCardActions, Group, Menu, MenuTrigger, MenuPopup, MenuItem, ChatHeader, ChatHeaderAvatar, ChatHeaderTitle, ChatHeaderActions, ContextMeter, Chat, ChatEmptyState, ChatEmptyStateIcon, ChatEmptyStateTitle, ChatEmptyStateDescription, ChatSuggestions, ChatSuggestion, useMediaQuery, TooltipProvider, DataTablePaged } from '@cntyclub/ui-react';
2
- import { XIcon, Trash2Icon, SquareIcon, PauseIcon, PlayIcon, CheckIcon, FileTextIcon, PaperclipIcon, MicIcon, ArrowUpIcon, CopyIcon, Maximize2Icon, ListChecksIcon, ChevronDownIcon, ShieldAlertIcon, CheckCheckIcon, UploadCloudIcon, HistoryIcon, SquarePenIcon, Minimize2Icon, ChevronsRightIcon, SparklesIcon, DownloadIcon, CodeIcon } from 'lucide-react';
3
- import * as React12 from 'react';
1
+ import { cn, Button, ThinkingOrb, Tooltip, TooltipTrigger, TooltipContent, Popover, PopoverTrigger, PopoverPopup, ChatMessage, ChatMessageBubble, Markdown, AuroraText, Spinner, Checkbox, Collapsible, CollapsibleTrigger, ChatToolChip, CollapsiblePanel, ChatToolCard, ChatToolCardHeader, ChatToolCardActions, Group, Menu, MenuTrigger, MenuPopup, MenuItem, ChatHeader, ChatHeaderAvatar, ChatHeaderTitle, AvatarGroup, ChatHeaderActions, ContextMeter, Chat, ChatEmptyState, ChatEmptyStateIcon, ChatEmptyStateTitle, ChatEmptyStateDescription, ChatSuggestions, ChatSuggestion, useMediaQuery, TooltipProvider, DataTablePaged } from '@cntyclub/ui-react';
2
+ import { XIcon, Trash2Icon, SquareIcon, PauseIcon, PlayIcon, CheckIcon, FileTextIcon, PaperclipIcon, MicIcon, ArrowUpIcon, UsersIcon, LockIcon, GlobeIcon, CopyIcon, Maximize2Icon, ListChecksIcon, ChevronDownIcon, ShieldAlertIcon, CheckCheckIcon, UploadCloudIcon, HistoryIcon, SquarePenIcon, Minimize2Icon, ChevronsRightIcon, SparklesIcon, DownloadIcon, CodeIcon } from 'lucide-react';
3
+ import * as React13 from 'react';
4
4
  import { AnimatePresence, motion } from 'motion/react';
5
5
  import { createPortal } from 'react-dom';
6
6
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
@@ -484,7 +484,7 @@ function formatBytes(bytes) {
484
484
  return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
485
485
  }
486
486
  function AgentImageLightbox({ src, alt, onClose }) {
487
- React12.useEffect(() => {
487
+ React13.useEffect(() => {
488
488
  if (!src) return;
489
489
  const onKey = (event) => {
490
490
  if (event.key === "Escape") onClose();
@@ -554,24 +554,24 @@ function pickMimeType() {
554
554
  return "";
555
555
  }
556
556
  function AgentVoiceRecorder({ maxSeconds, transcribe, onDone, onCancel, onError }) {
557
- const [phase, setPhase] = React12.useState("recording");
558
- const [elapsed, setElapsed] = React12.useState(0);
559
- const [playing, setPlaying] = React12.useState(false);
560
- const recorderRef = React12.useRef(null);
561
- const streamRef = React12.useRef(null);
562
- const chunksRef = React12.useRef([]);
563
- const blobRef = React12.useRef(null);
564
- const audioUrlRef = React12.useRef(null);
565
- const audioRef = React12.useRef(null);
566
- const timerRef = React12.useRef(null);
567
- const canvasRef = React12.useRef(null);
568
- const audioContextRef = React12.useRef(null);
569
- const analyserRef = React12.useRef(null);
570
- const rafRef = React12.useRef(null);
571
- const levelsRef = React12.useRef(new Array(MAX_BARS).fill(0));
572
- const onErrorRef = React12.useRef(onError);
557
+ const [phase, setPhase] = React13.useState("recording");
558
+ const [elapsed, setElapsed] = React13.useState(0);
559
+ const [playing, setPlaying] = React13.useState(false);
560
+ const recorderRef = React13.useRef(null);
561
+ const streamRef = React13.useRef(null);
562
+ const chunksRef = React13.useRef([]);
563
+ const blobRef = React13.useRef(null);
564
+ const audioUrlRef = React13.useRef(null);
565
+ const audioRef = React13.useRef(null);
566
+ const timerRef = React13.useRef(null);
567
+ const canvasRef = React13.useRef(null);
568
+ const audioContextRef = React13.useRef(null);
569
+ const analyserRef = React13.useRef(null);
570
+ const rafRef = React13.useRef(null);
571
+ const levelsRef = React13.useRef(new Array(MAX_BARS).fill(0));
572
+ const onErrorRef = React13.useRef(onError);
573
573
  onErrorRef.current = onError;
574
- const stopMeter = React12.useCallback(() => {
574
+ const stopMeter = React13.useCallback(() => {
575
575
  if (rafRef.current != null) {
576
576
  cancelAnimationFrame(rafRef.current);
577
577
  rafRef.current = null;
@@ -582,7 +582,7 @@ function AgentVoiceRecorder({ maxSeconds, transcribe, onDone, onCancel, onError
582
582
  if (ctx && ctx.state !== "closed") void ctx.close().catch(() => {
583
583
  });
584
584
  }, []);
585
- const stopTracks = React12.useCallback(() => {
585
+ const stopTracks = React13.useCallback(() => {
586
586
  streamRef.current?.getTracks().forEach((track) => track.stop());
587
587
  streamRef.current = null;
588
588
  if (timerRef.current) {
@@ -591,7 +591,7 @@ function AgentVoiceRecorder({ maxSeconds, transcribe, onDone, onCancel, onError
591
591
  }
592
592
  stopMeter();
593
593
  }, [stopMeter]);
594
- const startMeter = React12.useCallback((stream) => {
594
+ const startMeter = React13.useCallback((stream) => {
595
595
  const Ctor = typeof window === "undefined" ? void 0 : window.AudioContext ?? window.webkitAudioContext;
596
596
  if (!Ctor) return;
597
597
  let context;
@@ -661,7 +661,7 @@ function AgentVoiceRecorder({ maxSeconds, transcribe, onDone, onCancel, onError
661
661
  };
662
662
  rafRef.current = requestAnimationFrame(draw);
663
663
  }, []);
664
- React12.useEffect(() => {
664
+ React13.useEffect(() => {
665
665
  let cancelled = false;
666
666
  void (async () => {
667
667
  if (typeof navigator === "undefined" || !navigator.mediaDevices?.getUserMedia) {
@@ -814,40 +814,40 @@ function AgentComposer({
814
814
  voiceEnabled,
815
815
  voiceMaxSeconds = 600
816
816
  }) {
817
- const textareaRef = React12.useRef(null);
818
- const inputRef = React12.useRef(null);
819
- const [recording, setRecording] = React12.useState(false);
820
- const [lightboxSrc, setLightboxSrc] = React12.useState(null);
817
+ const textareaRef = React13.useRef(null);
818
+ const inputRef = React13.useRef(null);
819
+ const [recording, setRecording] = React13.useState(false);
820
+ const [lightboxSrc, setLightboxSrc] = React13.useState(null);
821
821
  const canSubmit = !disabled && !busy && (value.trim().length > 0 || files.length > 0);
822
822
  const voiceAvailable = Boolean(voiceEnabled && onTranscribe);
823
- const submit = React12.useCallback(() => {
823
+ const submit = React13.useCallback(() => {
824
824
  if (!canSubmit) return;
825
825
  onSubmit(value.trim());
826
826
  textareaRef.current?.focus();
827
827
  }, [canSubmit, onSubmit, value]);
828
- React12.useEffect(() => {
828
+ React13.useEffect(() => {
829
829
  if (!disabled) textareaRef.current?.focus();
830
830
  }, [disabled]);
831
- React12.useEffect(() => {
831
+ React13.useEffect(() => {
832
832
  const textarea = textareaRef.current;
833
833
  if (!textarea) return;
834
834
  textarea.style.height = "auto";
835
835
  textarea.style.height = `${Math.min(textarea.scrollHeight, 144)}px`;
836
836
  }, [value]);
837
- const previews = React12.useMemo(
837
+ const previews = React13.useMemo(
838
838
  () => files.map((file, originalIndex) => {
839
839
  const image = isImageFile(file);
840
840
  return { file, image, originalIndex, url: image ? URL.createObjectURL(file) : null };
841
841
  }),
842
842
  [files]
843
843
  );
844
- React12.useEffect(
844
+ React13.useEffect(
845
845
  () => () => {
846
846
  previews.forEach((preview) => preview.url && URL.revokeObjectURL(preview.url));
847
847
  },
848
848
  [previews]
849
849
  );
850
- const ordered = React12.useMemo(
850
+ const ordered = React13.useMemo(
851
851
  () => [...previews].sort((a, b) => Number(b.image) - Number(a.image)),
852
852
  [previews]
853
853
  );
@@ -1091,16 +1091,114 @@ function groupMessages(messages) {
1091
1091
  flush();
1092
1092
  return items;
1093
1093
  }
1094
+ function audienceLabel(scope) {
1095
+ return scope === "event" ? "this event's organizers" : "your team";
1096
+ }
1097
+ function AgentVisibilityControl({ config, conversation, onSetVisibility }) {
1098
+ const [open, setOpen] = React13.useState(false);
1099
+ const collab = config.collaboration;
1100
+ const scope = collab?.scope;
1101
+ const isPublic = conversation.visibility === "public";
1102
+ if (collab?.enabled === false) return null;
1103
+ if (!conversation.can_toggle_visibility) {
1104
+ if (!isPublic) return null;
1105
+ return /* @__PURE__ */ jsxs(Tooltip, { children: [
1106
+ /* @__PURE__ */ jsx(
1107
+ TooltipTrigger,
1108
+ {
1109
+ render: /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1 rounded-full bg-primary/10 px-2 py-0.5 text-primary text-xs", children: [
1110
+ /* @__PURE__ */ jsx(UsersIcon, { className: "size-3" }),
1111
+ "Shared"
1112
+ ] })
1113
+ }
1114
+ ),
1115
+ /* @__PURE__ */ jsxs(TooltipContent, { children: [
1116
+ "Shared with ",
1117
+ audienceLabel(scope)
1118
+ ] })
1119
+ ] });
1120
+ }
1121
+ const eventId = scope === "event" ? collab?.getEventId?.() ?? null : null;
1122
+ const missingEvent = scope === "event" && !eventId;
1123
+ const makePublic = () => {
1124
+ onSetVisibility("public", eventId ? { scopeEventId: eventId } : void 0);
1125
+ setOpen(false);
1126
+ };
1127
+ const makePrivate = () => {
1128
+ onSetVisibility("private");
1129
+ setOpen(false);
1130
+ };
1131
+ return /* @__PURE__ */ jsxs(Popover, { onOpenChange: setOpen, open, children: [
1132
+ /* @__PURE__ */ jsxs(Tooltip, { children: [
1133
+ /* @__PURE__ */ jsx(
1134
+ TooltipTrigger,
1135
+ {
1136
+ render: /* @__PURE__ */ jsx(
1137
+ PopoverTrigger,
1138
+ {
1139
+ render: /* @__PURE__ */ jsx(
1140
+ Button,
1141
+ {
1142
+ "aria-label": isPublic ? "Shared conversation" : "Private conversation",
1143
+ size: "icon-sm",
1144
+ variant: "ghost",
1145
+ children: isPublic ? /* @__PURE__ */ jsx(UsersIcon, { className: "text-primary" }) : /* @__PURE__ */ jsx(LockIcon, {})
1146
+ }
1147
+ )
1148
+ }
1149
+ )
1150
+ }
1151
+ ),
1152
+ /* @__PURE__ */ jsx(TooltipContent, { children: isPublic ? "Shared \u2014 manage access" : "Private \u2014 share" })
1153
+ ] }),
1154
+ /* @__PURE__ */ jsx(PopoverPopup, { className: "w-72 p-3", children: isPublic ? /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2", children: [
1155
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 font-medium text-sm", children: [
1156
+ /* @__PURE__ */ jsx(GlobeIcon, { className: "size-4 text-primary" }),
1157
+ "Shared conversation"
1158
+ ] }),
1159
+ /* @__PURE__ */ jsxs("p", { className: "text-muted-foreground text-xs", children: [
1160
+ "Everyone in ",
1161
+ audienceLabel(scope),
1162
+ " can see this conversation and everything in it."
1163
+ ] }),
1164
+ /* @__PURE__ */ jsx(
1165
+ Button,
1166
+ {
1167
+ className: "mt-1 w-full",
1168
+ disabled: !conversation.can_go_private,
1169
+ onClick: makePrivate,
1170
+ size: "sm",
1171
+ variant: "outline",
1172
+ children: "Make private"
1173
+ }
1174
+ ),
1175
+ !conversation.can_go_private ? /* @__PURE__ */ jsx("p", { className: "text-muted-foreground text-xs", children: "Others have already taken part, so this can no longer be made private." }) : null
1176
+ ] }) : /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2", children: [
1177
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 font-medium text-sm", children: [
1178
+ /* @__PURE__ */ jsx(UsersIcon, { className: "size-4" }),
1179
+ "Share this conversation"
1180
+ ] }),
1181
+ /* @__PURE__ */ jsxs("p", { className: "text-muted-foreground text-xs", children: [
1182
+ audienceLabel(scope),
1183
+ " will be able to see this conversation",
1184
+ /* @__PURE__ */ jsx("strong", { children: " and its full history" }),
1185
+ ", and take part in it."
1186
+ ] }),
1187
+ missingEvent ? /* @__PURE__ */ jsx("p", { className: "text-destructive text-xs", children: "Open an event first \u2014 a shared conversation is tied to a specific event." }) : null,
1188
+ /* @__PURE__ */ jsx(Button, { className: "mt-1 w-full", disabled: missingEvent, onClick: makePublic, size: "sm", children: "Make public" })
1189
+ ] }) })
1190
+ ] });
1191
+ }
1094
1192
  function ChatScroller({ children, className, ...props }) {
1095
- const viewportRef = React12.useRef(null);
1096
- const pinnedRef = React12.useRef(true);
1097
- const handleScroll = React12.useCallback(() => {
1193
+ const viewportRef = React13.useRef(null);
1194
+ const pinnedRef = React13.useRef(true);
1195
+ const handleScroll = React13.useCallback(() => {
1098
1196
  const viewport = viewportRef.current;
1099
1197
  if (!viewport) return;
1100
1198
  const distanceFromBottom = viewport.scrollHeight - viewport.scrollTop - viewport.clientHeight;
1101
1199
  pinnedRef.current = distanceFromBottom < 64;
1102
1200
  }, []);
1103
- React12.useEffect(() => {
1201
+ React13.useEffect(() => {
1104
1202
  const viewport = viewportRef.current;
1105
1203
  if (!viewport || !pinnedRef.current) return;
1106
1204
  viewport.scrollTop = viewport.scrollHeight;
@@ -1120,10 +1218,10 @@ function ChatScroller({ children, className, ...props }) {
1120
1218
  var MIN_CHARS_PER_FRAME = 2;
1121
1219
  var CATCH_UP = 0.22;
1122
1220
  function usePrefersReducedMotion() {
1123
- const [reduced, setReduced] = React12.useState(
1221
+ const [reduced, setReduced] = React13.useState(
1124
1222
  () => typeof matchMedia !== "undefined" && matchMedia("(prefers-reduced-motion: reduce)").matches
1125
1223
  );
1126
- React12.useEffect(() => {
1224
+ React13.useEffect(() => {
1127
1225
  if (typeof matchMedia === "undefined") return;
1128
1226
  const mq = matchMedia("(prefers-reduced-motion: reduce)");
1129
1227
  const onChange = (event) => setReduced(event.matches);
@@ -1135,12 +1233,12 @@ function usePrefersReducedMotion() {
1135
1233
  function useSmoothText(target, animate) {
1136
1234
  const prefersReduced = usePrefersReducedMotion();
1137
1235
  const enabled = animate && !prefersReduced;
1138
- const [count, setCount] = React12.useState(() => enabled ? 0 : target.length);
1139
- const countRef = React12.useRef(count);
1236
+ const [count, setCount] = React13.useState(() => enabled ? 0 : target.length);
1237
+ const countRef = React13.useRef(count);
1140
1238
  countRef.current = count;
1141
- const everEnabled = React12.useRef(enabled);
1239
+ const everEnabled = React13.useRef(enabled);
1142
1240
  if (enabled) everEnabled.current = true;
1143
- React12.useEffect(() => {
1241
+ React13.useEffect(() => {
1144
1242
  if (!everEnabled.current) {
1145
1243
  if (countRef.current !== target.length) setCount(target.length);
1146
1244
  return;
@@ -1169,14 +1267,14 @@ function useSmoothText(target, animate) {
1169
1267
  return everEnabled.current ? target.slice(0, Math.floor(count)) : target;
1170
1268
  }
1171
1269
  function CopyButton({ className, text }) {
1172
- const [copied, setCopied] = React12.useState(false);
1173
- const timerRef = React12.useRef(null);
1174
- React12.useEffect(() => {
1270
+ const [copied, setCopied] = React13.useState(false);
1271
+ const timerRef = React13.useRef(null);
1272
+ React13.useEffect(() => {
1175
1273
  return () => {
1176
1274
  if (timerRef.current) clearTimeout(timerRef.current);
1177
1275
  };
1178
1276
  }, []);
1179
- const copy = React12.useCallback(async () => {
1277
+ const copy = React13.useCallback(async () => {
1180
1278
  try {
1181
1279
  await navigator.clipboard.writeText(text);
1182
1280
  } catch {
@@ -1209,7 +1307,7 @@ function CopyButton({ className, text }) {
1209
1307
  }
1210
1308
  var isImageAttachment = (format) => IMAGE_ACCEPT.includes(`.${format.toLowerCase()}`);
1211
1309
  function MessageItem({ animate = false, message }) {
1212
- const [lightboxSrc, setLightboxSrc] = React12.useState(null);
1310
+ const [lightboxSrc, setLightboxSrc] = React13.useState(null);
1213
1311
  const displayed = useSmoothText(message.content ?? "", animate && message.role === "assistant");
1214
1312
  if (message.role === "user") {
1215
1313
  const attachments = message.attachments ?? [];
@@ -1294,8 +1392,8 @@ var DEFAULT_PHRASES = [
1294
1392
  ];
1295
1393
  function ThinkingIndicator({ className, intervalMs = 1800, phrases }) {
1296
1394
  const words = phrases && phrases.length ? phrases : DEFAULT_PHRASES;
1297
- const [index, setIndex] = React12.useState(0);
1298
- React12.useEffect(() => {
1395
+ const [index, setIndex] = React13.useState(0);
1396
+ React13.useEffect(() => {
1299
1397
  setIndex(0);
1300
1398
  const timer = setInterval(() => {
1301
1399
  setIndex((current) => (current + 1) % words.length);
@@ -1543,7 +1641,7 @@ function DownloadButton({ block, size = "sm" }) {
1543
1641
  );
1544
1642
  }
1545
1643
  function DocumentViewer({ block, onClose }) {
1546
- React12.useEffect(() => {
1644
+ React13.useEffect(() => {
1547
1645
  const onKey = (event) => event.key === "Escape" && onClose();
1548
1646
  window.addEventListener("keydown", onKey);
1549
1647
  return () => window.removeEventListener("keydown", onKey);
@@ -1568,7 +1666,7 @@ function DocumentViewer({ block, onClose }) {
1568
1666
  ] });
1569
1667
  }
1570
1668
  function DocumentCard({ block }) {
1571
- const [open, setOpen] = React12.useState(false);
1669
+ const [open, setOpen] = React13.useState(false);
1572
1670
  const previewLines = (block.preview || "").split("\n").slice(0, 6).join("\n");
1573
1671
  return /* @__PURE__ */ jsxs("div", { className: "w-full max-w-full overflow-hidden rounded-xl border border-border bg-card shadow-xs", children: [
1574
1672
  /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 border-border/72 border-b px-3 py-2", children: [
@@ -1690,7 +1788,7 @@ function StepDetail({
1690
1788
  ] });
1691
1789
  }
1692
1790
  function ToolActivityGroup({ describeToolCall, steps }) {
1693
- const [open, setOpen] = React12.useState(false);
1791
+ const [open, setOpen] = React13.useState(false);
1694
1792
  if (steps.length === 0) return null;
1695
1793
  const last = steps[steps.length - 1];
1696
1794
  const anyRunning = steps.some((step) => step.status === "running");
@@ -1801,12 +1899,12 @@ function AgentPanel({
1801
1899
  onClose,
1802
1900
  onToggleAgentMode
1803
1901
  }) {
1804
- const [draft, setDraft] = React12.useState("");
1805
- const [view, setView] = React12.useState("chat");
1806
- const [files, setFiles] = React12.useState([]);
1807
- const [uploadError, setUploadError] = React12.useState(null);
1808
- const [dragging, setDragging] = React12.useState(false);
1809
- const dragDepth = React12.useRef(0);
1902
+ const [draft, setDraft] = React13.useState("");
1903
+ const [view, setView] = React13.useState("chat");
1904
+ const [files, setFiles] = React13.useState([]);
1905
+ const [uploadError, setUploadError] = React13.useState(null);
1906
+ const [dragging, setDragging] = React13.useState(false);
1907
+ const dragDepth = React13.useRef(0);
1810
1908
  const agentName = config.agentName ?? chat.agentInfo?.name ?? "Assistant";
1811
1909
  const caps = {
1812
1910
  visionEnabled: chat.agentInfo?.vision_enabled,
@@ -1817,7 +1915,25 @@ function AgentPanel({
1817
1915
  "What can you help me with?",
1818
1916
  "Give me a quick summary of my data."
1819
1917
  ];
1820
- const addFiles = React12.useCallback(
1918
+ const typingLabel = React13.useMemo(() => {
1919
+ const names = Object.values(chat.typingUsers);
1920
+ if (!names.length) return null;
1921
+ if (names.length === 1) return `${names[0]} is typing\u2026`;
1922
+ if (names.length === 2) return `${names[0]} and ${names[1]} are typing\u2026`;
1923
+ return `${names.length} people are typing\u2026`;
1924
+ }, [chat.typingUsers]);
1925
+ const draftEpochRef = React13.useRef(-1);
1926
+ React13.useEffect(() => {
1927
+ if (draftEpochRef.current === chat.conversationEpoch) return;
1928
+ draftEpochRef.current = chat.conversationEpoch;
1929
+ setDraft(chat.myState?.draft_text ?? "");
1930
+ }, [chat.conversationEpoch, chat.myState?.draft_text]);
1931
+ React13.useEffect(() => {
1932
+ if (!chat.conversationId) return;
1933
+ const handle = setTimeout(() => chat.saveDraft(draft), 600);
1934
+ return () => clearTimeout(handle);
1935
+ }, [draft, chat.conversationId, chat.saveDraft]);
1936
+ const addFiles = React13.useCallback(
1821
1937
  (incoming) => {
1822
1938
  const accepted = [];
1823
1939
  let rejection = null;
@@ -1834,10 +1950,10 @@ function AgentPanel({
1834
1950
  },
1835
1951
  [config, caps.visionEnabled, caps.visionMaxMb]
1836
1952
  );
1837
- const removeFile = React12.useCallback((index) => {
1953
+ const removeFile = React13.useCallback((index) => {
1838
1954
  setFiles((current) => current.filter((_, i) => i !== index));
1839
1955
  }, []);
1840
- const handleSubmit = React12.useCallback(
1956
+ const handleSubmit = React13.useCallback(
1841
1957
  (text) => {
1842
1958
  const staged = files;
1843
1959
  setDraft("");
@@ -1847,7 +1963,7 @@ function AgentPanel({
1847
1963
  },
1848
1964
  [chat, files]
1849
1965
  );
1850
- const onDragEnter = React12.useCallback(
1966
+ const onDragEnter = React13.useCallback(
1851
1967
  (event) => {
1852
1968
  if (!uploadEnabled || !event.dataTransfer?.types?.includes("Files")) return;
1853
1969
  dragDepth.current += 1;
@@ -1855,12 +1971,12 @@ function AgentPanel({
1855
1971
  },
1856
1972
  [uploadEnabled]
1857
1973
  );
1858
- const onDragLeave = React12.useCallback((event) => {
1974
+ const onDragLeave = React13.useCallback((event) => {
1859
1975
  if (!event.dataTransfer?.types?.includes("Files")) return;
1860
1976
  dragDepth.current = Math.max(0, dragDepth.current - 1);
1861
1977
  if (dragDepth.current === 0) setDragging(false);
1862
1978
  }, []);
1863
- const onDrop = React12.useCallback(
1979
+ const onDrop = React13.useCallback(
1864
1980
  (event) => {
1865
1981
  if (!uploadEnabled) return;
1866
1982
  event.preventDefault();
@@ -1871,7 +1987,7 @@ function AgentPanel({
1871
1987
  },
1872
1988
  [addFiles, uploadEnabled]
1873
1989
  );
1874
- const openHistory = React12.useCallback(() => {
1990
+ const openHistory = React13.useCallback(() => {
1875
1991
  setView("history");
1876
1992
  void chat.refreshConversations();
1877
1993
  }, [chat]);
@@ -1902,10 +2018,32 @@ function AgentPanel({
1902
2018
  /* @__PURE__ */ jsx(ChatHeaderAvatar, {}),
1903
2019
  /* @__PURE__ */ jsxs(ChatHeaderTitle, { children: [
1904
2020
  /* @__PURE__ */ jsx("div", { className: "truncate font-medium text-sm", children: agentName }),
1905
- config.tagline ? /* @__PURE__ */ jsx("div", { className: "truncate text-muted-foreground text-xs", children: config.tagline }) : null
1906
- ] })
2021
+ typingLabel ? /* @__PURE__ */ jsx("div", { className: "truncate text-primary text-xs", children: typingLabel }) : config.tagline ? /* @__PURE__ */ jsx("div", { className: "truncate text-muted-foreground text-xs", children: config.tagline }) : null
2022
+ ] }),
2023
+ chat.participants.length > 1 ? /* @__PURE__ */ jsx(
2024
+ AvatarGroup,
2025
+ {
2026
+ className: "ml-0.5",
2027
+ items: chat.participants.map((participant) => ({
2028
+ alt: participant.name,
2029
+ name: participant.name,
2030
+ src: participant.avatar_url ?? void 0
2031
+ })),
2032
+ max: 4,
2033
+ showNameOnHover: true,
2034
+ size: "sm"
2035
+ }
2036
+ ) : null
1907
2037
  ] }),
1908
2038
  /* @__PURE__ */ jsxs(ChatHeaderActions, { children: [
2039
+ chat.currentConversation ? /* @__PURE__ */ jsx(
2040
+ AgentVisibilityControl,
2041
+ {
2042
+ config,
2043
+ conversation: chat.currentConversation,
2044
+ onSetVisibility: chat.setVisibility
2045
+ }
2046
+ ) : null,
1909
2047
  chat.contextMeter && chat.contextMeter.pct > 0 ? /* @__PURE__ */ jsxs(Tooltip, { children: [
1910
2048
  /* @__PURE__ */ jsx(
1911
2049
  TooltipTrigger,
@@ -2071,7 +2209,7 @@ function AgentPanel({
2071
2209
  }
2072
2210
  }
2073
2211
  }
2074
- return grouped.map((item) => /* @__PURE__ */ jsxs(React12.Fragment, { children: [
2212
+ return grouped.map((item) => /* @__PURE__ */ jsxs(React13.Fragment, { children: [
2075
2213
  item.key === anchorKey ? /* @__PURE__ */ jsx(NewMessagesDivider, {}) : null,
2076
2214
  /* @__PURE__ */ jsx(
2077
2215
  motion.div,
@@ -2208,25 +2346,25 @@ function buildOptimisticUserMessage(text, files) {
2208
2346
  };
2209
2347
  }
2210
2348
  function useAgentChat(config) {
2211
- const client = React12.useMemo(() => new AgentApiClient(config), [config]);
2212
- const configRef = React12.useRef(config);
2349
+ const client = React13.useMemo(() => new AgentApiClient(config), [config]);
2350
+ const configRef = React13.useRef(config);
2213
2351
  configRef.current = config;
2214
- const [agentInfo, setAgentInfo] = React12.useState(null);
2215
- const [conversationId, setConversationId] = React12.useState(null);
2216
- const [conversationEpoch, setConversationEpoch] = React12.useState(0);
2217
- const [conversations, setConversations] = React12.useState([]);
2218
- const [messages, setMessages] = React12.useState([]);
2219
- const [pendingApprovals, setPendingApprovals] = React12.useState([]);
2220
- const [sending, setSending] = React12.useState(false);
2221
- const [resolvingApprovalId, setResolvingApprovalId] = React12.useState(null);
2222
- const [error, setError] = React12.useState(null);
2223
- const [currentConversation, setCurrentConversation] = React12.useState(null);
2224
- const [contextMeter, setContextMeter] = React12.useState(null);
2225
- const [participants, setParticipants] = React12.useState([]);
2226
- const [myState, setMyState] = React12.useState(null);
2227
- const [typingUsers, setTypingUsers] = React12.useState({});
2228
- const [realtimeStatus, setRealtimeStatus] = React12.useState("idle");
2229
- React12.useEffect(() => {
2352
+ const [agentInfo, setAgentInfo] = React13.useState(null);
2353
+ const [conversationId, setConversationId] = React13.useState(null);
2354
+ const [conversationEpoch, setConversationEpoch] = React13.useState(0);
2355
+ const [conversations, setConversations] = React13.useState([]);
2356
+ const [messages, setMessages] = React13.useState([]);
2357
+ const [pendingApprovals, setPendingApprovals] = React13.useState([]);
2358
+ const [sending, setSending] = React13.useState(false);
2359
+ const [resolvingApprovalId, setResolvingApprovalId] = React13.useState(null);
2360
+ const [error, setError] = React13.useState(null);
2361
+ const [currentConversation, setCurrentConversation] = React13.useState(null);
2362
+ const [contextMeter, setContextMeter] = React13.useState(null);
2363
+ const [participants, setParticipants] = React13.useState([]);
2364
+ const [myState, setMyState] = React13.useState(null);
2365
+ const [typingUsers, setTypingUsers] = React13.useState({});
2366
+ const [realtimeStatus, setRealtimeStatus] = React13.useState("idle");
2367
+ React13.useEffect(() => {
2230
2368
  let cancelled = false;
2231
2369
  client.getConfig().then((info) => {
2232
2370
  if (!cancelled) setAgentInfo(info);
@@ -2236,11 +2374,11 @@ function useAgentChat(config) {
2236
2374
  cancelled = true;
2237
2375
  };
2238
2376
  }, [client]);
2239
- const handleFailure = React12.useCallback((err) => {
2377
+ const handleFailure = React13.useCallback((err) => {
2240
2378
  const message = err instanceof AgentApiError ? err.message : "Something went wrong. Please try again.";
2241
2379
  setError(message);
2242
2380
  }, []);
2243
- const applyResponse = React12.useCallback(
2381
+ const applyResponse = React13.useCallback(
2244
2382
  (response) => {
2245
2383
  if (response.status === "error" && !response.messages?.length) {
2246
2384
  setError(response.message ?? "The assistant could not answer.");
@@ -2270,7 +2408,7 @@ function useAgentChat(config) {
2270
2408
  },
2271
2409
  []
2272
2410
  );
2273
- const handleStreamEvent = React12.useCallback(
2411
+ const handleStreamEvent = React13.useCallback(
2274
2412
  (event, ctx) => {
2275
2413
  switch (event.type) {
2276
2414
  case "conversation":
@@ -2348,7 +2486,7 @@ function useAgentChat(config) {
2348
2486
  },
2349
2487
  []
2350
2488
  );
2351
- const applyRealtime = React12.useCallback((event) => {
2489
+ const applyRealtime = React13.useCallback((event) => {
2352
2490
  switch (event.type) {
2353
2491
  case "sync":
2354
2492
  setMessages((current) => mergeMessages(current, event.messages ?? []));
@@ -2388,7 +2526,7 @@ function useAgentChat(config) {
2388
2526
  const realtimeEnabled = config.realtime?.enabled !== false;
2389
2527
  const isPublic = currentConversation?.visibility === "public";
2390
2528
  const baselineSeq = currentConversation?.last_seq ?? 0;
2391
- React12.useEffect(() => {
2529
+ React13.useEffect(() => {
2392
2530
  if (!realtimeEnabled || !conversationId || !isPublic) {
2393
2531
  setRealtimeStatus("idle");
2394
2532
  return;
@@ -2405,7 +2543,7 @@ function useAgentChat(config) {
2405
2543
  };
2406
2544
  }, [applyRealtime, baselineSeq, conversationId, isPublic, realtimeEnabled]);
2407
2545
  const streamingEnabled = config.streaming !== false && typeof ReadableStream !== "undefined";
2408
- const send = React12.useCallback(
2546
+ const send = React13.useCallback(
2409
2547
  async (text, files) => {
2410
2548
  if (sending) return;
2411
2549
  if (!text.trim() && !(files && files.length)) return;
@@ -2444,14 +2582,14 @@ function useAgentChat(config) {
2444
2582
  },
2445
2583
  [applyResponse, client, conversationId, handleFailure, handleStreamEvent, sending, streamingEnabled]
2446
2584
  );
2447
- const transcribe = React12.useCallback(
2585
+ const transcribe = React13.useCallback(
2448
2586
  async (audio) => {
2449
2587
  const { text } = await client.transcribe(audio);
2450
2588
  return text;
2451
2589
  },
2452
2590
  [client]
2453
2591
  );
2454
- const resolveApproval = React12.useCallback(
2592
+ const resolveApproval = React13.useCallback(
2455
2593
  async (callId, approve) => {
2456
2594
  if (resolvingApprovalId) return;
2457
2595
  setResolvingApprovalId(callId);
@@ -2480,7 +2618,7 @@ function useAgentChat(config) {
2480
2618
  },
2481
2619
  [applyResponse, client, handleFailure, handleStreamEvent, resolvingApprovalId, streamingEnabled]
2482
2620
  );
2483
- const newChat = React12.useCallback(() => {
2621
+ const newChat = React13.useCallback(() => {
2484
2622
  setConversationId(null);
2485
2623
  setMessages([]);
2486
2624
  setPendingApprovals([]);
@@ -2492,7 +2630,7 @@ function useAgentChat(config) {
2492
2630
  setTypingUsers({});
2493
2631
  setConversationEpoch((e) => e + 1);
2494
2632
  }, []);
2495
- const refreshConversations = React12.useCallback(async () => {
2633
+ const refreshConversations = React13.useCallback(async () => {
2496
2634
  try {
2497
2635
  const { conversations: list } = await client.listConversations();
2498
2636
  setConversations(list);
@@ -2502,7 +2640,7 @@ function useAgentChat(config) {
2502
2640
  return [];
2503
2641
  }
2504
2642
  }, [client, handleFailure]);
2505
- const openConversation = React12.useCallback(
2643
+ const openConversation = React13.useCallback(
2506
2644
  async (id) => {
2507
2645
  setError(null);
2508
2646
  try {
@@ -2534,7 +2672,7 @@ function useAgentChat(config) {
2534
2672
  },
2535
2673
  [client, handleFailure]
2536
2674
  );
2537
- const deleteConversation = React12.useCallback(
2675
+ const deleteConversation = React13.useCallback(
2538
2676
  async (id) => {
2539
2677
  try {
2540
2678
  await client.deleteConversation(id);
@@ -2546,7 +2684,63 @@ function useAgentChat(config) {
2546
2684
  },
2547
2685
  [client, conversationId, handleFailure, newChat]
2548
2686
  );
2549
- const clearError = React12.useCallback(() => setError(null), []);
2687
+ const setVisibility = React13.useCallback(
2688
+ async (visibility, opts) => {
2689
+ if (!conversationId) return;
2690
+ setError(null);
2691
+ try {
2692
+ const scope = configRef.current.collaboration?.scope;
2693
+ const res = await client.setVisibility(
2694
+ conversationId,
2695
+ visibility,
2696
+ visibility === "public" ? { scopeType: scope, scopeEventId: opts?.scopeEventId } : void 0
2697
+ );
2698
+ if (res.status === "error") {
2699
+ setError(res.message ?? "Could not change the conversation's visibility.");
2700
+ return;
2701
+ }
2702
+ setCurrentConversation(
2703
+ (current) => current ? { ...current, visibility, can_go_private: Boolean(res.can_go_private) } : current
2704
+ );
2705
+ void client.listParticipants(conversationId).then((p) => setParticipants(p.participants ?? [])).catch(() => {
2706
+ });
2707
+ } catch (err) {
2708
+ handleFailure(err);
2709
+ }
2710
+ },
2711
+ [client, conversationId, handleFailure]
2712
+ );
2713
+ const markRead = React13.useCallback(
2714
+ (seq) => {
2715
+ if (!conversationId || seq <= 0) return;
2716
+ setMyState(
2717
+ (current) => current && seq > current.last_read_seq ? { ...current, last_read_seq: seq } : current
2718
+ );
2719
+ void client.markRead(conversationId, seq).catch(() => {
2720
+ });
2721
+ },
2722
+ [client, conversationId]
2723
+ );
2724
+ const saveDraft = React13.useCallback(
2725
+ (text) => {
2726
+ if (!conversationId) return;
2727
+ void client.saveDraft(conversationId, text).catch(() => {
2728
+ });
2729
+ },
2730
+ [client, conversationId]
2731
+ );
2732
+ const summarize = React13.useCallback(async () => {
2733
+ if (!conversationId) return;
2734
+ setError(null);
2735
+ try {
2736
+ await client.summarize(conversationId);
2737
+ const detail = await client.getConversation(conversationId);
2738
+ setContextMeter(detail.context_meter ?? null);
2739
+ } catch (err) {
2740
+ handleFailure(err);
2741
+ }
2742
+ }, [client, conversationId, handleFailure]);
2743
+ const clearError = React13.useCallback(() => setError(null), []);
2550
2744
  return {
2551
2745
  agentInfo,
2552
2746
  clearError,
@@ -2557,6 +2751,7 @@ function useAgentChat(config) {
2557
2751
  currentConversation,
2558
2752
  deleteConversation,
2559
2753
  error,
2754
+ markRead,
2560
2755
  messages,
2561
2756
  myState,
2562
2757
  newChat,
@@ -2567,8 +2762,11 @@ function useAgentChat(config) {
2567
2762
  refreshConversations,
2568
2763
  resolveApproval,
2569
2764
  resolvingApprovalId,
2765
+ saveDraft,
2570
2766
  send,
2571
2767
  sending,
2768
+ setVisibility,
2769
+ summarize,
2572
2770
  transcribe,
2573
2771
  typingUsers
2574
2772
  };
@@ -2589,11 +2787,11 @@ function readStored(clientId) {
2589
2787
  }
2590
2788
  }
2591
2789
  function useAlwaysApprove(clientId) {
2592
- const [approved, setApproved] = React12.useState(() => /* @__PURE__ */ new Set());
2593
- React12.useEffect(() => {
2790
+ const [approved, setApproved] = React13.useState(() => /* @__PURE__ */ new Set());
2791
+ React13.useEffect(() => {
2594
2792
  setApproved(readStored(clientId));
2595
2793
  }, [clientId]);
2596
- const persist = React12.useCallback(
2794
+ const persist = React13.useCallback(
2597
2795
  (next) => {
2598
2796
  setApproved(next);
2599
2797
  if (typeof window === "undefined") return;
@@ -2604,8 +2802,8 @@ function useAlwaysApprove(clientId) {
2604
2802
  },
2605
2803
  [clientId]
2606
2804
  );
2607
- const isAlwaysApproved = React12.useCallback((toolName) => approved.has(toolName), [approved]);
2608
- const setAlwaysApprove = React12.useCallback(
2805
+ const isAlwaysApproved = React13.useCallback((toolName) => approved.has(toolName), [approved]);
2806
+ const setAlwaysApprove = React13.useCallback(
2609
2807
  (toolName) => {
2610
2808
  if (approved.has(toolName)) return;
2611
2809
  const next = new Set(approved);
@@ -2614,7 +2812,7 @@ function useAlwaysApprove(clientId) {
2614
2812
  },
2615
2813
  [approved, persist]
2616
2814
  );
2617
- const clearAlwaysApprove = React12.useCallback(
2815
+ const clearAlwaysApprove = React13.useCallback(
2618
2816
  (toolName) => {
2619
2817
  if (!approved.has(toolName)) return;
2620
2818
  const next = new Set(approved);
@@ -2640,10 +2838,10 @@ function AgentWidget({
2640
2838
  const isControlled = controlledOpen !== void 0;
2641
2839
  const isDocked = presentation === "docked";
2642
2840
  const storageKey2 = `cc-agent-open:${config.clientId}`;
2643
- const [uncontrolledOpen, setUncontrolledOpen] = React12.useState(false);
2841
+ const [uncontrolledOpen, setUncontrolledOpen] = React13.useState(false);
2644
2842
  const open = controlledOpen ?? uncontrolledOpen;
2645
- const [bootstrapDone, setBootstrapDone] = React12.useState(isControlled);
2646
- const persist = React12.useCallback(
2843
+ const [bootstrapDone, setBootstrapDone] = React13.useState(isControlled);
2844
+ const persist = React13.useCallback(
2647
2845
  (next) => {
2648
2846
  if (isControlled || !behavior.persistOpenState) return;
2649
2847
  try {
@@ -2653,7 +2851,7 @@ function AgentWidget({
2653
2851
  },
2654
2852
  [behavior.persistOpenState, isControlled, storageKey2]
2655
2853
  );
2656
- const setOpen = React12.useCallback(
2854
+ const setOpen = React13.useCallback(
2657
2855
  (next) => {
2658
2856
  setUncontrolledOpen(next);
2659
2857
  persist(next);
@@ -2661,14 +2859,14 @@ function AgentWidget({
2661
2859
  },
2662
2860
  [onOpenChange, persist]
2663
2861
  );
2664
- const [agentMode, setAgentMode] = React12.useState(false);
2862
+ const [agentMode, setAgentMode] = React13.useState(false);
2665
2863
  const isDesktop = useMediaQuery("(min-width: 640px)", { defaultSSRValue: true, ssr: true });
2666
2864
  const fullscreen = !isDesktop || agentMode;
2667
2865
  const chat = useAgentChat(config);
2668
2866
  const alwaysApprove = useAlwaysApprove(config.clientId);
2669
2867
  const { messages, pendingApprovals, resolveApproval, resolvingApprovalId, sending } = chat;
2670
- const bootRef = React12.useRef(false);
2671
- React12.useEffect(() => {
2868
+ const bootRef = React13.useRef(false);
2869
+ React13.useEffect(() => {
2672
2870
  if (bootRef.current) return;
2673
2871
  if (isControlled && !isDocked) return;
2674
2872
  bootRef.current = true;
@@ -2700,15 +2898,15 @@ function AgentWidget({
2700
2898
  cancelled = true;
2701
2899
  };
2702
2900
  }, []);
2703
- const seenCountRef = React12.useRef(0);
2704
- const [baselined, setBaselined] = React12.useState(false);
2705
- const [anchorId, setAnchorId] = React12.useState(null);
2706
- React12.useEffect(() => {
2901
+ const seenCountRef = React13.useRef(0);
2902
+ const [baselined, setBaselined] = React13.useState(false);
2903
+ const [anchorId, setAnchorId] = React13.useState(null);
2904
+ React13.useEffect(() => {
2707
2905
  if (baselined || !bootstrapDone) return;
2708
2906
  seenCountRef.current = messages.length;
2709
2907
  setBaselined(true);
2710
2908
  }, [baselined, bootstrapDone, messages.length]);
2711
- React12.useEffect(() => {
2909
+ React13.useEffect(() => {
2712
2910
  if (open) {
2713
2911
  if (messages.length > seenCountRef.current) {
2714
2912
  const firstUnread = messages[seenCountRef.current];
@@ -2718,7 +2916,7 @@ function AgentWidget({
2718
2916
  }
2719
2917
  }, [open, messages]);
2720
2918
  const unreadCount = open || !baselined ? 0 : messages.slice(seenCountRef.current).filter(isUnreadable).length;
2721
- const workLabel = React12.useMemo(() => {
2919
+ const workLabel = React13.useMemo(() => {
2722
2920
  if (!sending) return null;
2723
2921
  const last = messages[messages.length - 1];
2724
2922
  if (last?.role === "tool") return "Calling tools\u2026";
@@ -2727,14 +2925,14 @@ function AgentWidget({
2727
2925
  }, [sending, messages]);
2728
2926
  const approvalWaiting = pendingApprovals.length > 0;
2729
2927
  const { isAlwaysApproved } = alwaysApprove;
2730
- React12.useEffect(() => {
2928
+ React13.useEffect(() => {
2731
2929
  if (resolvingApprovalId) return;
2732
2930
  const target = pendingApprovals.find((approval) => isAlwaysApproved(approval.tool_name));
2733
2931
  if (target) void resolveApproval(target.id, true);
2734
2932
  }, [pendingApprovals, resolvingApprovalId, isAlwaysApproved, resolveApproval]);
2735
- const firedWriteIds = React12.useRef(/* @__PURE__ */ new Set());
2933
+ const firedWriteIds = React13.useRef(/* @__PURE__ */ new Set());
2736
2934
  const { onWriteSuccess } = config;
2737
- React12.useEffect(() => {
2935
+ React13.useEffect(() => {
2738
2936
  if (!onWriteSuccess) return;
2739
2937
  for (const message of messages) {
2740
2938
  if (message.role !== "tool" || !message.is_write || message.tool_status !== "success") continue;
@@ -2744,9 +2942,9 @@ function AgentWidget({
2744
2942
  onWriteSuccess({ arguments: args, toolName: message.tool_name ?? "" });
2745
2943
  }
2746
2944
  }, [messages, onWriteSuccess]);
2747
- const lastNavigatedMessageId = React12.useRef(null);
2748
- const navEpochRef = React12.useRef(-1);
2749
- React12.useEffect(() => {
2945
+ const lastNavigatedMessageId = React13.useRef(null);
2946
+ const navEpochRef = React13.useRef(-1);
2947
+ React13.useEffect(() => {
2750
2948
  if (!open || fullscreen || !config.navigate || !config.pages?.length) return;
2751
2949
  const toolMessages = messages.filter((message) => message.role === "tool");
2752
2950
  const latest = toolMessages[toolMessages.length - 1];
@@ -2765,7 +2963,7 @@ function AgentWidget({
2765
2963
  const scrollTo = typeof mapping.scrollTo === "function" ? mapping.scrollTo(args) : mapping.scrollTo;
2766
2964
  config.navigate(path, { scrollTo: scrollTo ?? null });
2767
2965
  }, [chat.conversationEpoch, config, fullscreen, messages, open]);
2768
- const closePanel = React12.useCallback(() => {
2966
+ const closePanel = React13.useCallback(() => {
2769
2967
  setOpen(false);
2770
2968
  setAgentMode(false);
2771
2969
  }, [setOpen]);
@@ -2938,6 +3136,6 @@ function defineAgentConfig(config) {
2938
3136
  return config;
2939
3137
  }
2940
3138
 
2941
- export { AgentApiClient, AgentApiError, AgentComposer, AgentImageLightbox, AgentPanel, AgentRealtimeClient, AgentVoiceRecorder, AgentWidget, ChatScroller, CopyButton, DEFAULT_ACCEPT, DocumentCard, IMAGE_ACCEPT, MessageItem, TaskChecklist, ThinkingIndicator, ToolActivityGroup, ToolApprovalCard, acceptAttribute, acceptedExtensions, attachmentsEnabled, defineAgentConfig, deriveDetails, fileUploadEnabled, formatBytes, groupMessages, humanizeToolName, isImageFile, resolveToolPresentation, textExtensions, useAgentChat, useAlwaysApprove, useSmoothText, validateFile };
3139
+ export { AgentApiClient, AgentApiError, AgentComposer, AgentImageLightbox, AgentPanel, AgentRealtimeClient, AgentVisibilityControl, AgentVoiceRecorder, AgentWidget, ChatScroller, CopyButton, DEFAULT_ACCEPT, DocumentCard, IMAGE_ACCEPT, MessageItem, TaskChecklist, ThinkingIndicator, ToolActivityGroup, ToolApprovalCard, acceptAttribute, acceptedExtensions, attachmentsEnabled, defineAgentConfig, deriveDetails, fileUploadEnabled, formatBytes, groupMessages, humanizeToolName, isImageFile, resolveToolPresentation, textExtensions, useAgentChat, useAlwaysApprove, useSmoothText, validateFile };
2942
3140
  //# sourceMappingURL=index.js.map
2943
3141
  //# sourceMappingURL=index.js.map