@cntyclub/agent-react 0.9.1 → 0.9.2

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.
@@ -0,0 +1,9 @@
1
+ import * as React from "react";
2
+ export interface CopyButtonProps {
3
+ /** The text copied to the clipboard (the assistant reply's raw markdown). */
4
+ text: string;
5
+ className?: string;
6
+ }
7
+ /** Small ghost icon button that copies `text` and briefly flips to a check. */
8
+ export declare function CopyButton({ className, text }: CopyButtonProps): React.JSX.Element;
9
+ //# sourceMappingURL=copy-button.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"copy-button.d.ts","sourceRoot":"","sources":["../../src/components/copy-button.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,MAAM,WAAW,eAAe;IAC9B,6EAA6E;IAC7E,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,+EAA+E;AAC/E,wBAAgB,UAAU,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,eAAe,qBAwC9D"}
@@ -1 +1 @@
1
- {"version":3,"file":"message-item.d.ts","sourceRoot":"","sources":["../../src/components/message-item.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAE7C;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,EAAE,OAAO,EAAE,EAAE;IAAE,OAAO,EAAE,YAAY,CAAA;CAAE,4BAmCjE"}
1
+ {"version":3,"file":"message-item.d.ts","sourceRoot":"","sources":["../../src/components/message-item.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAG7C;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,EAAE,OAAO,EAAE,EAAE;IAAE,OAAO,EAAE,YAAY,CAAA;CAAE,4BA8CjE"}
package/dist/index.d.ts CHANGED
@@ -3,6 +3,7 @@ export { AgentComposer, type AgentComposerProps } from "./components/agent-compo
3
3
  export { AgentPanel, type AgentPanelProps } from "./components/agent-panel";
4
4
  export { AgentWidget, type AgentWidgetProps } from "./components/agent-widget";
5
5
  export { ChatScroller, type ChatScrollerProps } from "./components/chat-scroller";
6
+ export { CopyButton, type CopyButtonProps } from "./components/copy-button";
6
7
  export { DocumentCard } from "./components/document-card";
7
8
  export { MessageItem } from "./components/message-item";
8
9
  export { TaskChecklist } from "./components/task-checklist";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7D,OAAO,EAAE,aAAa,EAAE,KAAK,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AACrF,OAAO,EAAE,UAAU,EAAE,KAAK,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAC5E,OAAO,EAAE,WAAW,EAAE,KAAK,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAC/E,OAAO,EAAE,YAAY,EAAE,KAAK,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAClF,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,EAAE,iBAAiB,EAAE,KAAK,sBAAsB,EAAE,MAAM,iCAAiC,CAAC;AACjG,OAAO,EAAE,iBAAiB,EAAE,KAAK,sBAAsB,EAAE,MAAM,kCAAkC,CAAC;AAClG,OAAO,EAAE,gBAAgB,EAAE,KAAK,qBAAqB,EAAE,MAAM,iCAAiC,CAAC;AAC/F,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAC7C,OAAO,EACL,eAAe,EACf,kBAAkB,EAClB,cAAc,EACd,iBAAiB,EACjB,WAAW,EACX,YAAY,GACb,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,aAAa,EAAE,KAAK,UAAU,EAAE,KAAK,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAChF,OAAO,EACL,aAAa,EACb,gBAAgB,EAChB,uBAAuB,EACvB,KAAK,wBAAwB,GAC9B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,gBAAgB,EAAE,KAAK,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AACjF,YAAY,EACV,WAAW,EACX,YAAY,EACZ,gBAAgB,EAChB,gBAAgB,EAChB,iBAAiB,EACjB,gBAAgB,EAChB,eAAe,EACf,cAAc,EACd,WAAW,EACX,YAAY,EACZ,mBAAmB,EACnB,gBAAgB,EAChB,aAAa,EACb,cAAc,EACd,YAAY,EACZ,eAAe,EACf,UAAU,EACV,QAAQ,EACR,UAAU,EACV,UAAU,EACV,mBAAmB,EACnB,cAAc,EACd,YAAY,EACZ,iBAAiB,GAClB,MAAM,SAAS,CAAC;AAEjB,YAAY,EACV,UAAU,IAAI,mBAAmB,EACjC,UAAU,IAAI,mBAAmB,EACjC,KAAK,IAAI,cAAc,GACxB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,YAAY,EACZ,KAAK,gBAAgB,EACrB,KAAK,cAAc,GACpB,MAAM,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7D,OAAO,EAAE,aAAa,EAAE,KAAK,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AACrF,OAAO,EAAE,UAAU,EAAE,KAAK,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAC5E,OAAO,EAAE,WAAW,EAAE,KAAK,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAC/E,OAAO,EAAE,YAAY,EAAE,KAAK,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAClF,OAAO,EAAE,UAAU,EAAE,KAAK,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAC5E,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,EAAE,iBAAiB,EAAE,KAAK,sBAAsB,EAAE,MAAM,iCAAiC,CAAC;AACjG,OAAO,EAAE,iBAAiB,EAAE,KAAK,sBAAsB,EAAE,MAAM,kCAAkC,CAAC;AAClG,OAAO,EAAE,gBAAgB,EAAE,KAAK,qBAAqB,EAAE,MAAM,iCAAiC,CAAC;AAC/F,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAC7C,OAAO,EACL,eAAe,EACf,kBAAkB,EAClB,cAAc,EACd,iBAAiB,EACjB,WAAW,EACX,YAAY,GACb,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,aAAa,EAAE,KAAK,UAAU,EAAE,KAAK,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAChF,OAAO,EACL,aAAa,EACb,gBAAgB,EAChB,uBAAuB,EACvB,KAAK,wBAAwB,GAC9B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,gBAAgB,EAAE,KAAK,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AACjF,YAAY,EACV,WAAW,EACX,YAAY,EACZ,gBAAgB,EAChB,gBAAgB,EAChB,iBAAiB,EACjB,gBAAgB,EAChB,eAAe,EACf,cAAc,EACd,WAAW,EACX,YAAY,EACZ,mBAAmB,EACnB,gBAAgB,EAChB,aAAa,EACb,cAAc,EACd,YAAY,EACZ,eAAe,EACf,UAAU,EACV,QAAQ,EACR,UAAU,EACV,UAAU,EACV,mBAAmB,EACnB,cAAc,EACd,YAAY,EACZ,iBAAiB,GAClB,MAAM,SAAS,CAAC;AAEjB,YAAY,EACV,UAAU,IAAI,mBAAmB,EACjC,UAAU,IAAI,mBAAmB,EACjC,KAAK,IAAI,cAAc,GACxB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,YAAY,EACZ,KAAK,gBAAgB,EACrB,KAAK,cAAc,GACpB,MAAM,kBAAkB,CAAC"}
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
- import { Button, cn, ChatMessage, ChatMessageBubble, Markdown, Spinner, Checkbox, Collapsible, CollapsibleTrigger, ChatToolChip, CollapsiblePanel, ChatToolCard, ChatToolCardHeader, ChatToolCardActions, Group, Menu, MenuTrigger, MenuPopup, MenuItem, ChatHeader, ChatHeaderAvatar, ChatHeaderTitle, ChatHeaderActions, Tooltip, TooltipTrigger, TooltipContent, Chat, ChatEmptyState, ChatEmptyStateIcon, ChatEmptyStateTitle, ChatEmptyStateDescription, ChatSuggestions, ChatSuggestion, useMediaQuery, TooltipProvider, Fab, DataTablePaged } from '@cntyclub/ui-react';
2
- import { FileTextIcon, XIcon, PaperclipIcon, ArrowUpIcon, Maximize2Icon, ListChecksIcon, ChevronDownIcon, CheckIcon, ShieldAlertIcon, CheckCheckIcon, UploadCloudIcon, HistoryIcon, SquarePenIcon, Minimize2Icon, Trash2Icon, SparklesIcon, DownloadIcon, CodeIcon } from 'lucide-react';
3
- import * as React7 from 'react';
1
+ import { Button, cn, Tooltip, TooltipTrigger, TooltipContent, ChatMessage, ChatMessageBubble, Markdown, Spinner, Checkbox, Collapsible, CollapsibleTrigger, ChatToolChip, CollapsiblePanel, ChatToolCard, ChatToolCardHeader, ChatToolCardActions, Group, Menu, MenuTrigger, MenuPopup, MenuItem, ChatHeader, ChatHeaderAvatar, ChatHeaderTitle, ChatHeaderActions, Chat, ChatEmptyState, ChatEmptyStateIcon, ChatEmptyStateTitle, ChatEmptyStateDescription, ChatSuggestions, ChatSuggestion, useMediaQuery, TooltipProvider, Fab, DataTablePaged } from '@cntyclub/ui-react';
2
+ import { FileTextIcon, XIcon, PaperclipIcon, ArrowUpIcon, CheckIcon, CopyIcon, Maximize2Icon, ListChecksIcon, ChevronDownIcon, ShieldAlertIcon, CheckCheckIcon, UploadCloudIcon, HistoryIcon, SquarePenIcon, Minimize2Icon, Trash2Icon, SparklesIcon, DownloadIcon, CodeIcon } from 'lucide-react';
3
+ import * as React8 from 'react';
4
4
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
5
5
 
6
6
  // src/api-client.ts
@@ -230,18 +230,18 @@ function AgentComposer({
230
230
  placeholder = "Ask anything\u2026",
231
231
  value
232
232
  }) {
233
- const textareaRef = React7.useRef(null);
234
- const inputRef = React7.useRef(null);
233
+ const textareaRef = React8.useRef(null);
234
+ const inputRef = React8.useRef(null);
235
235
  const canSubmit = !disabled && !busy && (value.trim().length > 0 || files.length > 0);
236
- const submit = React7.useCallback(() => {
236
+ const submit = React8.useCallback(() => {
237
237
  if (!canSubmit) return;
238
238
  onSubmit(value.trim());
239
239
  textareaRef.current?.focus();
240
240
  }, [canSubmit, onSubmit, value]);
241
- React7.useEffect(() => {
241
+ React8.useEffect(() => {
242
242
  if (!disabled) textareaRef.current?.focus();
243
243
  }, [disabled]);
244
- React7.useEffect(() => {
244
+ React8.useEffect(() => {
245
245
  const textarea = textareaRef.current;
246
246
  if (!textarea) return;
247
247
  textarea.style.height = "auto";
@@ -423,15 +423,15 @@ function groupMessages(messages) {
423
423
  return items;
424
424
  }
425
425
  function ChatScroller({ children, className, ...props }) {
426
- const viewportRef = React7.useRef(null);
427
- const pinnedRef = React7.useRef(true);
428
- const handleScroll = React7.useCallback(() => {
426
+ const viewportRef = React8.useRef(null);
427
+ const pinnedRef = React8.useRef(true);
428
+ const handleScroll = React8.useCallback(() => {
429
429
  const viewport = viewportRef.current;
430
430
  if (!viewport) return;
431
431
  const distanceFromBottom = viewport.scrollHeight - viewport.scrollTop - viewport.clientHeight;
432
432
  pinnedRef.current = distanceFromBottom < 64;
433
433
  }, []);
434
- React7.useEffect(() => {
434
+ React8.useEffect(() => {
435
435
  const viewport = viewportRef.current;
436
436
  if (!viewport || !pinnedRef.current) return;
437
437
  viewport.scrollTop = viewport.scrollHeight;
@@ -448,6 +448,45 @@ function ChatScroller({ children, className, ...props }) {
448
448
  }
449
449
  );
450
450
  }
451
+ function CopyButton({ className, text }) {
452
+ const [copied, setCopied] = React8.useState(false);
453
+ const timerRef = React8.useRef(null);
454
+ React8.useEffect(() => {
455
+ return () => {
456
+ if (timerRef.current) clearTimeout(timerRef.current);
457
+ };
458
+ }, []);
459
+ const copy = React8.useCallback(async () => {
460
+ try {
461
+ await navigator.clipboard.writeText(text);
462
+ } catch {
463
+ return;
464
+ }
465
+ setCopied(true);
466
+ if (timerRef.current) clearTimeout(timerRef.current);
467
+ timerRef.current = setTimeout(() => setCopied(false), 1500);
468
+ }, [text]);
469
+ return /* @__PURE__ */ jsxs(Tooltip, { children: [
470
+ /* @__PURE__ */ jsx(
471
+ TooltipTrigger,
472
+ {
473
+ render: /* @__PURE__ */ jsx(
474
+ Button,
475
+ {
476
+ "aria-label": copied ? "Copied" : "Copy message",
477
+ className: cn("text-muted-foreground", className),
478
+ onClick: copy,
479
+ size: "icon-xs",
480
+ type: "button",
481
+ variant: "ghost",
482
+ children: copied ? /* @__PURE__ */ jsx(CheckIcon, { className: "text-success" }) : /* @__PURE__ */ jsx(CopyIcon, {})
483
+ }
484
+ )
485
+ }
486
+ ),
487
+ /* @__PURE__ */ jsx(TooltipContent, { children: copied ? "Copied!" : "Copy" })
488
+ ] });
489
+ }
451
490
  function MessageItem({ message }) {
452
491
  if (message.role === "user") {
453
492
  const attachments = message.attachments ?? [];
@@ -468,7 +507,19 @@ function MessageItem({ message }) {
468
507
  }
469
508
  if (message.role === "assistant") {
470
509
  if (!message.content || !message.content.trim()) return null;
471
- return /* @__PURE__ */ jsx(ChatMessage, { from: "assistant", children: /* @__PURE__ */ jsx(ChatMessageBubble, { from: "assistant", children: /* @__PURE__ */ jsx(Markdown, { children: message.content }) }) });
510
+ return /* @__PURE__ */ jsxs(ChatMessage, { className: "group", from: "assistant", children: [
511
+ /* @__PURE__ */ jsx(ChatMessageBubble, { from: "assistant", children: /* @__PURE__ */ jsx(Markdown, { children: message.content }) }),
512
+ /* @__PURE__ */ jsx(
513
+ "div",
514
+ {
515
+ className: cn(
516
+ "mt-0.5 flex opacity-0 transition-opacity",
517
+ "group-hover:opacity-100 focus-within:opacity-100"
518
+ ),
519
+ children: /* @__PURE__ */ jsx(CopyButton, { text: message.content })
520
+ }
521
+ )
522
+ ] });
472
523
  }
473
524
  return null;
474
525
  }
@@ -482,8 +533,8 @@ var DEFAULT_PHRASES = [
482
533
  ];
483
534
  function ThinkingIndicator({ className, intervalMs = 1800, phrases }) {
484
535
  const words = phrases && phrases.length ? phrases : DEFAULT_PHRASES;
485
- const [index, setIndex] = React7.useState(0);
486
- React7.useEffect(() => {
536
+ const [index, setIndex] = React8.useState(0);
537
+ React8.useEffect(() => {
487
538
  setIndex(0);
488
539
  const timer = setInterval(() => {
489
540
  setIndex((current) => (current + 1) % words.length);
@@ -745,7 +796,7 @@ function DownloadButton({ block, size = "sm" }) {
745
796
  );
746
797
  }
747
798
  function DocumentViewer({ block, onClose }) {
748
- React7.useEffect(() => {
799
+ React8.useEffect(() => {
749
800
  const onKey = (event) => event.key === "Escape" && onClose();
750
801
  window.addEventListener("keydown", onKey);
751
802
  return () => window.removeEventListener("keydown", onKey);
@@ -770,7 +821,7 @@ function DocumentViewer({ block, onClose }) {
770
821
  ] });
771
822
  }
772
823
  function DocumentCard({ block }) {
773
- const [open, setOpen] = React7.useState(false);
824
+ const [open, setOpen] = React8.useState(false);
774
825
  const previewLines = (block.preview || "").split("\n").slice(0, 6).join("\n");
775
826
  return /* @__PURE__ */ jsxs("div", { className: "w-full max-w-full overflow-hidden rounded-xl border border-border bg-card shadow-xs", children: [
776
827
  /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 border-border/72 border-b px-3 py-2", children: [
@@ -892,7 +943,7 @@ function StepDetail({
892
943
  ] });
893
944
  }
894
945
  function ToolActivityGroup({ describeToolCall, steps }) {
895
- const [open, setOpen] = React7.useState(false);
946
+ const [open, setOpen] = React8.useState(false);
896
947
  if (steps.length === 0) return null;
897
948
  const last = steps[steps.length - 1];
898
949
  const anyRunning = steps.some((step) => step.status === "running");
@@ -995,19 +1046,19 @@ function AgentPanel({
995
1046
  onClose,
996
1047
  onToggleAgentMode
997
1048
  }) {
998
- const [draft, setDraft] = React7.useState("");
999
- const [view, setView] = React7.useState("chat");
1000
- const [files, setFiles] = React7.useState([]);
1001
- const [uploadError, setUploadError] = React7.useState(null);
1002
- const [dragging, setDragging] = React7.useState(false);
1003
- const dragDepth = React7.useRef(0);
1049
+ const [draft, setDraft] = React8.useState("");
1050
+ const [view, setView] = React8.useState("chat");
1051
+ const [files, setFiles] = React8.useState([]);
1052
+ const [uploadError, setUploadError] = React8.useState(null);
1053
+ const [dragging, setDragging] = React8.useState(false);
1054
+ const dragDepth = React8.useRef(0);
1004
1055
  const agentName = config.agentName ?? chat.agentInfo?.name ?? "Assistant";
1005
1056
  const uploadEnabled = fileUploadEnabled(config);
1006
1057
  const suggestions = config.suggestions ?? [
1007
1058
  "What can you help me with?",
1008
1059
  "Give me a quick summary of my data."
1009
1060
  ];
1010
- const addFiles = React7.useCallback(
1061
+ const addFiles = React8.useCallback(
1011
1062
  (incoming) => {
1012
1063
  const accepted = [];
1013
1064
  let rejection = null;
@@ -1024,10 +1075,10 @@ function AgentPanel({
1024
1075
  },
1025
1076
  [config]
1026
1077
  );
1027
- const removeFile = React7.useCallback((index) => {
1078
+ const removeFile = React8.useCallback((index) => {
1028
1079
  setFiles((current) => current.filter((_, i) => i !== index));
1029
1080
  }, []);
1030
- const handleSubmit = React7.useCallback(
1081
+ const handleSubmit = React8.useCallback(
1031
1082
  (text) => {
1032
1083
  const staged = files;
1033
1084
  setDraft("");
@@ -1037,7 +1088,7 @@ function AgentPanel({
1037
1088
  },
1038
1089
  [chat, files]
1039
1090
  );
1040
- const onDragEnter = React7.useCallback(
1091
+ const onDragEnter = React8.useCallback(
1041
1092
  (event) => {
1042
1093
  if (!uploadEnabled || !event.dataTransfer?.types?.includes("Files")) return;
1043
1094
  dragDepth.current += 1;
@@ -1045,12 +1096,12 @@ function AgentPanel({
1045
1096
  },
1046
1097
  [uploadEnabled]
1047
1098
  );
1048
- const onDragLeave = React7.useCallback((event) => {
1099
+ const onDragLeave = React8.useCallback((event) => {
1049
1100
  if (!event.dataTransfer?.types?.includes("Files")) return;
1050
1101
  dragDepth.current = Math.max(0, dragDepth.current - 1);
1051
1102
  if (dragDepth.current === 0) setDragging(false);
1052
1103
  }, []);
1053
- const onDrop = React7.useCallback(
1104
+ const onDrop = React8.useCallback(
1054
1105
  (event) => {
1055
1106
  if (!uploadEnabled) return;
1056
1107
  event.preventDefault();
@@ -1061,7 +1112,7 @@ function AgentPanel({
1061
1112
  },
1062
1113
  [addFiles, uploadEnabled]
1063
1114
  );
1064
- const openHistory = React7.useCallback(() => {
1115
+ const openHistory = React8.useCallback(() => {
1065
1116
  setView("history");
1066
1117
  void chat.refreshConversations();
1067
1118
  }, [chat]);
@@ -1284,16 +1335,16 @@ function buildOptimisticUserMessage(text, files) {
1284
1335
  };
1285
1336
  }
1286
1337
  function useAgentChat(config) {
1287
- const client = React7.useMemo(() => new AgentApiClient(config), [config]);
1288
- const [agentInfo, setAgentInfo] = React7.useState(null);
1289
- const [conversationId, setConversationId] = React7.useState(null);
1290
- const [conversations, setConversations] = React7.useState([]);
1291
- const [messages, setMessages] = React7.useState([]);
1292
- const [pendingApprovals, setPendingApprovals] = React7.useState([]);
1293
- const [sending, setSending] = React7.useState(false);
1294
- const [resolvingApprovalId, setResolvingApprovalId] = React7.useState(null);
1295
- const [error, setError] = React7.useState(null);
1296
- React7.useEffect(() => {
1338
+ const client = React8.useMemo(() => new AgentApiClient(config), [config]);
1339
+ const [agentInfo, setAgentInfo] = React8.useState(null);
1340
+ const [conversationId, setConversationId] = React8.useState(null);
1341
+ const [conversations, setConversations] = React8.useState([]);
1342
+ const [messages, setMessages] = React8.useState([]);
1343
+ const [pendingApprovals, setPendingApprovals] = React8.useState([]);
1344
+ const [sending, setSending] = React8.useState(false);
1345
+ const [resolvingApprovalId, setResolvingApprovalId] = React8.useState(null);
1346
+ const [error, setError] = React8.useState(null);
1347
+ React8.useEffect(() => {
1297
1348
  let cancelled = false;
1298
1349
  client.getConfig().then((info) => {
1299
1350
  if (!cancelled) setAgentInfo(info);
@@ -1303,11 +1354,11 @@ function useAgentChat(config) {
1303
1354
  cancelled = true;
1304
1355
  };
1305
1356
  }, [client]);
1306
- const handleFailure = React7.useCallback((err) => {
1357
+ const handleFailure = React8.useCallback((err) => {
1307
1358
  const message = err instanceof AgentApiError ? err.message : "Something went wrong. Please try again.";
1308
1359
  setError(message);
1309
1360
  }, []);
1310
- const applyResponse = React7.useCallback(
1361
+ const applyResponse = React8.useCallback(
1311
1362
  (response) => {
1312
1363
  if (response.status === "error" && !response.messages?.length) {
1313
1364
  setError(response.message ?? "The assistant could not answer.");
@@ -1329,7 +1380,7 @@ function useAgentChat(config) {
1329
1380
  },
1330
1381
  []
1331
1382
  );
1332
- const handleStreamEvent = React7.useCallback(
1383
+ const handleStreamEvent = React8.useCallback(
1333
1384
  (event, ctx) => {
1334
1385
  switch (event.type) {
1335
1386
  case "conversation":
@@ -1394,7 +1445,7 @@ function useAgentChat(config) {
1394
1445
  []
1395
1446
  );
1396
1447
  const streamingEnabled = config.streaming !== false && typeof ReadableStream !== "undefined";
1397
- const send = React7.useCallback(
1448
+ const send = React8.useCallback(
1398
1449
  async (text, files) => {
1399
1450
  if (sending) return;
1400
1451
  if (!text.trim() && !(files && files.length)) return;
@@ -1425,7 +1476,7 @@ function useAgentChat(config) {
1425
1476
  },
1426
1477
  [applyResponse, client, conversationId, handleFailure, handleStreamEvent, sending, streamingEnabled]
1427
1478
  );
1428
- const resolveApproval = React7.useCallback(
1479
+ const resolveApproval = React8.useCallback(
1429
1480
  async (callId, approve) => {
1430
1481
  if (resolvingApprovalId) return;
1431
1482
  setResolvingApprovalId(callId);
@@ -1454,13 +1505,13 @@ function useAgentChat(config) {
1454
1505
  },
1455
1506
  [applyResponse, client, handleFailure, handleStreamEvent, resolvingApprovalId, streamingEnabled]
1456
1507
  );
1457
- const newChat = React7.useCallback(() => {
1508
+ const newChat = React8.useCallback(() => {
1458
1509
  setConversationId(null);
1459
1510
  setMessages([]);
1460
1511
  setPendingApprovals([]);
1461
1512
  setError(null);
1462
1513
  }, []);
1463
- const refreshConversations = React7.useCallback(async () => {
1514
+ const refreshConversations = React8.useCallback(async () => {
1464
1515
  try {
1465
1516
  const { conversations: list } = await client.listConversations();
1466
1517
  setConversations(list);
@@ -1468,7 +1519,7 @@ function useAgentChat(config) {
1468
1519
  handleFailure(err);
1469
1520
  }
1470
1521
  }, [client, handleFailure]);
1471
- const openConversation = React7.useCallback(
1522
+ const openConversation = React8.useCallback(
1472
1523
  async (id) => {
1473
1524
  setError(null);
1474
1525
  try {
@@ -1482,7 +1533,7 @@ function useAgentChat(config) {
1482
1533
  },
1483
1534
  [client, handleFailure]
1484
1535
  );
1485
- const deleteConversation = React7.useCallback(
1536
+ const deleteConversation = React8.useCallback(
1486
1537
  async (id) => {
1487
1538
  try {
1488
1539
  await client.deleteConversation(id);
@@ -1494,7 +1545,7 @@ function useAgentChat(config) {
1494
1545
  },
1495
1546
  [client, conversationId, handleFailure, newChat]
1496
1547
  );
1497
- const clearError = React7.useCallback(() => setError(null), []);
1548
+ const clearError = React8.useCallback(() => setError(null), []);
1498
1549
  return {
1499
1550
  agentInfo,
1500
1551
  clearError,
@@ -1529,11 +1580,11 @@ function readStored(clientId) {
1529
1580
  }
1530
1581
  }
1531
1582
  function useAlwaysApprove(clientId) {
1532
- const [approved, setApproved] = React7.useState(() => /* @__PURE__ */ new Set());
1533
- React7.useEffect(() => {
1583
+ const [approved, setApproved] = React8.useState(() => /* @__PURE__ */ new Set());
1584
+ React8.useEffect(() => {
1534
1585
  setApproved(readStored(clientId));
1535
1586
  }, [clientId]);
1536
- const persist = React7.useCallback(
1587
+ const persist = React8.useCallback(
1537
1588
  (next) => {
1538
1589
  setApproved(next);
1539
1590
  if (typeof window === "undefined") return;
@@ -1544,8 +1595,8 @@ function useAlwaysApprove(clientId) {
1544
1595
  },
1545
1596
  [clientId]
1546
1597
  );
1547
- const isAlwaysApproved = React7.useCallback((toolName) => approved.has(toolName), [approved]);
1548
- const setAlwaysApprove = React7.useCallback(
1598
+ const isAlwaysApproved = React8.useCallback((toolName) => approved.has(toolName), [approved]);
1599
+ const setAlwaysApprove = React8.useCallback(
1549
1600
  (toolName) => {
1550
1601
  if (approved.has(toolName)) return;
1551
1602
  const next = new Set(approved);
@@ -1554,7 +1605,7 @@ function useAlwaysApprove(clientId) {
1554
1605
  },
1555
1606
  [approved, persist]
1556
1607
  );
1557
- const clearAlwaysApprove = React7.useCallback(
1608
+ const clearAlwaysApprove = React8.useCallback(
1558
1609
  (toolName) => {
1559
1610
  if (!approved.has(toolName)) return;
1560
1611
  const next = new Set(approved);
@@ -1566,16 +1617,16 @@ function useAlwaysApprove(clientId) {
1566
1617
  return { clearAlwaysApprove, isAlwaysApproved, setAlwaysApprove };
1567
1618
  }
1568
1619
  function AgentWidget({ config, onOpenChange, open: controlledOpen }) {
1569
- const [uncontrolledOpen, setUncontrolledOpen] = React7.useState(false);
1620
+ const [uncontrolledOpen, setUncontrolledOpen] = React8.useState(false);
1570
1621
  const open = controlledOpen ?? uncontrolledOpen;
1571
- const setOpen = React7.useCallback(
1622
+ const setOpen = React8.useCallback(
1572
1623
  (next) => {
1573
1624
  setUncontrolledOpen(next);
1574
1625
  onOpenChange?.(next);
1575
1626
  },
1576
1627
  [onOpenChange]
1577
1628
  );
1578
- const [agentMode, setAgentMode] = React7.useState(false);
1629
+ const [agentMode, setAgentMode] = React8.useState(false);
1579
1630
  const isDesktop = useMediaQuery("(min-width: 640px)", {
1580
1631
  defaultSSRValue: true,
1581
1632
  ssr: true
@@ -1585,14 +1636,14 @@ function AgentWidget({ config, onOpenChange, open: controlledOpen }) {
1585
1636
  const alwaysApprove = useAlwaysApprove(config.clientId);
1586
1637
  const { pendingApprovals, resolveApproval, resolvingApprovalId } = chat;
1587
1638
  const { isAlwaysApproved } = alwaysApprove;
1588
- React7.useEffect(() => {
1639
+ React8.useEffect(() => {
1589
1640
  if (!open || resolvingApprovalId) return;
1590
1641
  const target = pendingApprovals.find((approval) => isAlwaysApproved(approval.tool_name));
1591
1642
  if (target) void resolveApproval(target.id, true);
1592
1643
  }, [open, pendingApprovals, resolvingApprovalId, isAlwaysApproved, resolveApproval]);
1593
- const firedWriteIds = React7.useRef(/* @__PURE__ */ new Set());
1644
+ const firedWriteIds = React8.useRef(/* @__PURE__ */ new Set());
1594
1645
  const { onWriteSuccess } = config;
1595
- React7.useEffect(() => {
1646
+ React8.useEffect(() => {
1596
1647
  if (!onWriteSuccess) return;
1597
1648
  for (const message of chat.messages) {
1598
1649
  if (message.role !== "tool" || !message.is_write || message.tool_status !== "success") continue;
@@ -1602,9 +1653,9 @@ function AgentWidget({ config, onOpenChange, open: controlledOpen }) {
1602
1653
  onWriteSuccess({ arguments: args, toolName: message.tool_name ?? "" });
1603
1654
  }
1604
1655
  }, [chat.messages, onWriteSuccess]);
1605
- const lastNavigatedMessageId = React7.useRef(null);
1656
+ const lastNavigatedMessageId = React8.useRef(null);
1606
1657
  const { messages } = chat;
1607
- React7.useEffect(() => {
1658
+ React8.useEffect(() => {
1608
1659
  if (!open || fullscreen || !config.navigate || !config.pages?.length) return;
1609
1660
  const toolMessages = messages.filter((message) => message.role === "tool");
1610
1661
  const latest = toolMessages[toolMessages.length - 1];
@@ -1616,7 +1667,7 @@ function AgentWidget({ config, onOpenChange, open: controlledOpen }) {
1616
1667
  const path = mapping.buildRoute ? mapping.buildRoute(args) : mapping.route;
1617
1668
  if (path) config.navigate(path);
1618
1669
  }, [config, fullscreen, messages, open]);
1619
- const closePanel = React7.useCallback(() => {
1670
+ const closePanel = React8.useCallback(() => {
1620
1671
  setOpen(false);
1621
1672
  setAgentMode(false);
1622
1673
  }, [setOpen]);
@@ -1695,6 +1746,6 @@ function defineAgentConfig(config) {
1695
1746
  return config;
1696
1747
  }
1697
1748
 
1698
- export { AgentApiClient, AgentApiError, AgentComposer, AgentPanel, AgentWidget, ChatScroller, DEFAULT_ACCEPT, DocumentCard, MessageItem, TaskChecklist, ThinkingIndicator, ToolActivityGroup, ToolApprovalCard, acceptAttribute, acceptedExtensions, defineAgentConfig, deriveDetails, fileUploadEnabled, formatBytes, groupMessages, humanizeToolName, resolveToolPresentation, useAgentChat, useAlwaysApprove, validateFile };
1749
+ export { AgentApiClient, AgentApiError, AgentComposer, AgentPanel, AgentWidget, ChatScroller, CopyButton, DEFAULT_ACCEPT, DocumentCard, MessageItem, TaskChecklist, ThinkingIndicator, ToolActivityGroup, ToolApprovalCard, acceptAttribute, acceptedExtensions, defineAgentConfig, deriveDetails, fileUploadEnabled, formatBytes, groupMessages, humanizeToolName, resolveToolPresentation, useAgentChat, useAlwaysApprove, validateFile };
1699
1750
  //# sourceMappingURL=index.js.map
1700
1751
  //# sourceMappingURL=index.js.map