@athenaintel/react 0.6.5 → 0.7.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
@@ -24473,6 +24473,70 @@ const themes = {
24473
24473
  radius: "0.625rem"
24474
24474
  }
24475
24475
  };
24476
+ const QuoteCtx = createContext(null);
24477
+ function QuoteProvider({ children }) {
24478
+ const [quote, setQuote] = useState(null);
24479
+ const clearQuote = useCallback(() => setQuote(null), []);
24480
+ const value = useMemo(() => ({ quote, setQuote, clearQuote }), [quote, setQuote, clearQuote]);
24481
+ return /* @__PURE__ */ jsx(QuoteCtx.Provider, { value, children });
24482
+ }
24483
+ function useQuote() {
24484
+ const ctx = useContext(QuoteCtx);
24485
+ if (!ctx) {
24486
+ throw new Error("[AthenaSDK] useQuote must be used within <QuoteProvider>");
24487
+ }
24488
+ return ctx;
24489
+ }
24490
+ function useQuoteFromPostMessage() {
24491
+ const { setQuote } = useQuote();
24492
+ useEffect(() => {
24493
+ const handleKeydown = (e) => {
24494
+ var _a2;
24495
+ if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === "l") {
24496
+ const sel = window.getSelection();
24497
+ const selection = (_a2 = sel == null ? void 0 : sel.toString()) == null ? void 0 : _a2.trim();
24498
+ if (selection && selection.length > 0) {
24499
+ e.preventDefault();
24500
+ let messageId;
24501
+ let role;
24502
+ let node = sel == null ? void 0 : sel.anchorNode;
24503
+ while (node && node !== document.body) {
24504
+ if (node instanceof HTMLElement) {
24505
+ const dataRole = node.getAttribute("data-role");
24506
+ if (dataRole === "assistant" || dataRole === "user") {
24507
+ role = dataRole;
24508
+ messageId = node.getAttribute("data-message-id") ?? void 0;
24509
+ break;
24510
+ }
24511
+ }
24512
+ node = node.parentElement;
24513
+ }
24514
+ setQuote({ text: selection, sourceRole: role, sourceMessageId: messageId });
24515
+ }
24516
+ }
24517
+ };
24518
+ const handleMessage = (event) => {
24519
+ const data = event.data;
24520
+ if (data && typeof data === "object" && data.type === "athena-add-to-composer" && typeof data.text === "string" && data.text.trim().length > 0) {
24521
+ setQuote({
24522
+ text: data.text,
24523
+ sourceTitle: data.sourceTitle,
24524
+ sourceAssetId: data.sourceAssetId
24525
+ });
24526
+ }
24527
+ };
24528
+ document.addEventListener("keydown", handleKeydown, true);
24529
+ window.addEventListener("message", handleMessage);
24530
+ return () => {
24531
+ document.removeEventListener("keydown", handleKeydown, true);
24532
+ window.removeEventListener("message", handleMessage);
24533
+ };
24534
+ }, [setQuote]);
24535
+ }
24536
+ function QuotePostMessageBridge() {
24537
+ useQuoteFromPostMessage();
24538
+ return null;
24539
+ }
24476
24540
  function AthenaStandalone({
24477
24541
  children,
24478
24542
  apiUrl,
@@ -24509,7 +24573,10 @@ function AthenaStandalone({
24509
24573
  () => ({ backendUrl, apiKey, token }),
24510
24574
  [backendUrl, apiKey, token]
24511
24575
  );
24512
- return /* @__PURE__ */ jsx(AssistantRuntimeProvider, { aui, runtime, children: /* @__PURE__ */ jsx(AthenaContext.Provider, { value: athenaConfig, children: /* @__PURE__ */ jsx(TooltipProvider, { children }) }) });
24576
+ return /* @__PURE__ */ jsx(AssistantRuntimeProvider, { aui, runtime, children: /* @__PURE__ */ jsx(AthenaContext.Provider, { value: athenaConfig, children: /* @__PURE__ */ jsxs(QuoteProvider, { children: [
24577
+ /* @__PURE__ */ jsx(QuotePostMessageBridge, {}),
24578
+ /* @__PURE__ */ jsx(TooltipProvider, { children })
24579
+ ] }) }) });
24513
24580
  }
24514
24581
  function useAthenaRuntimeHook(config2) {
24515
24582
  const remoteId = useAthenaThreadId();
@@ -24588,7 +24655,10 @@ function AthenaWithThreadList({
24588
24655
  () => ({ backendUrl, apiKey, token }),
24589
24656
  [backendUrl, apiKey, token]
24590
24657
  );
24591
- return /* @__PURE__ */ jsx(AssistantRuntimeProvider, { aui, runtime, children: /* @__PURE__ */ jsx(AthenaContext.Provider, { value: athenaConfig, children: /* @__PURE__ */ jsx(TooltipProvider, { children }) }) });
24658
+ return /* @__PURE__ */ jsx(AssistantRuntimeProvider, { aui, runtime, children: /* @__PURE__ */ jsx(AthenaContext.Provider, { value: athenaConfig, children: /* @__PURE__ */ jsxs(QuoteProvider, { children: [
24659
+ /* @__PURE__ */ jsx(QuotePostMessageBridge, {}),
24660
+ /* @__PURE__ */ jsx(TooltipProvider, { children })
24661
+ ] }) }) });
24592
24662
  }
24593
24663
  function AthenaProvider({
24594
24664
  children,
@@ -58364,6 +58434,18 @@ const TiptapText = ({ text: text2 }) => {
58364
58434
  return /* @__PURE__ */ jsx(EditorContent, { editor });
58365
58435
  };
58366
58436
  var index_default$1 = Placeholder;
58437
+ const EditorCtx = createContext(null);
58438
+ function ComposerEditorProvider({ children }) {
58439
+ const ref = useRef(null);
58440
+ return /* @__PURE__ */ jsx(EditorCtx.Provider, { value: ref, children });
58441
+ }
58442
+ function useComposerEditorRef() {
58443
+ const ctx = useContext(EditorCtx);
58444
+ if (!ctx) {
58445
+ throw new Error("[AthenaSDK] useComposerEditorRef must be used within <ComposerEditorProvider>");
58446
+ }
58447
+ return ctx;
58448
+ }
58367
58449
  const isMentionPopupActive = (editor) => {
58368
58450
  var _a2, _b;
58369
58451
  return Boolean(
@@ -58397,8 +58479,6 @@ const ComposerKeybinds = Extension.create({
58397
58479
  if (editor.isActive("bulletList") || editor.isActive("orderedList")) {
58398
58480
  return false;
58399
58481
  }
58400
- const hasContent = editor.getText().trim().length > 0;
58401
- if (!hasContent) return false;
58402
58482
  this.options.onSubmit();
58403
58483
  return true;
58404
58484
  },
@@ -60401,19 +60481,95 @@ function useMentionSuggestions(tools) {
60401
60481
  }, [tools, store]);
60402
60482
  return store;
60403
60483
  }
60484
+ const AttachmentCtx = createContext(null);
60485
+ function AttachmentProvider({ children }) {
60486
+ const [attachments, setAttachments] = useState([]);
60487
+ const [isUploading, setIsUploading] = useState(false);
60488
+ const addAttachments = useCallback((assets) => {
60489
+ setAttachments((prev) => [...prev, ...assets]);
60490
+ }, []);
60491
+ const removeAttachment = useCallback((id) => {
60492
+ setAttachments((prev) => prev.filter((a) => a.id !== id));
60493
+ }, []);
60494
+ const clearAttachments = useCallback(() => setAttachments([]), []);
60495
+ const value = useMemo(
60496
+ () => ({ attachments, addAttachments, removeAttachment, clearAttachments, isUploading, setIsUploading }),
60497
+ [attachments, addAttachments, removeAttachment, clearAttachments, isUploading]
60498
+ );
60499
+ return /* @__PURE__ */ jsx(AttachmentCtx.Provider, { value, children });
60500
+ }
60501
+ function useAttachments() {
60502
+ const ctx = useContext(AttachmentCtx);
60503
+ if (!ctx) {
60504
+ throw new Error("[AthenaSDK] useAttachments must be used within <AttachmentProvider>");
60505
+ }
60506
+ return ctx;
60507
+ }
60508
+ function buildAttachmentMarkdown(attachments) {
60509
+ if (attachments.length === 0) return "";
60510
+ return attachments.map((a) => `[@${a.title}](https://app.athenaintel.com/dashboard/spaces?asset_id=${a.id})`).join("\n");
60511
+ }
60512
+ function buildComposedMessage(opts) {
60513
+ var _a2;
60514
+ const parts = [];
60515
+ if (opts.attachments && opts.attachments.length > 0) {
60516
+ const attachmentMd = buildAttachmentMarkdown(opts.attachments);
60517
+ if (attachmentMd) parts.push(attachmentMd);
60518
+ }
60519
+ if (opts.quote) {
60520
+ const quotedLines = opts.quote.text.split("\n").map((l) => `> ${l}`).join("\n");
60521
+ const sourceLabel = opts.quote.sourceTitle ? `From "${opts.quote.sourceTitle}"` : opts.quote.sourceRole === "assistant" ? "Quoting assistant" : "Quoting";
60522
+ parts.push(`${sourceLabel}:
60523
+ ${quotedLines}`);
60524
+ }
60525
+ const trimmed = (_a2 = opts.userText) == null ? void 0 : _a2.trim();
60526
+ if (trimmed) parts.push(trimmed);
60527
+ return parts.join("\n\n");
60528
+ }
60404
60529
  const TiptapComposer = ({ tools = [] }) => {
60530
+ const aui = useAui();
60405
60531
  const composerRuntime = useComposerRuntime();
60406
60532
  const editorRef = useRef(null);
60533
+ const composerEditorRef = useComposerEditorRef();
60407
60534
  const mentionStore = useMentionSuggestions(tools);
60535
+ const { attachments, clearAttachments, isUploading } = useAttachments();
60536
+ const { quote, clearQuote } = useQuote();
60537
+ const attachmentsRef = useRef(attachments);
60538
+ attachmentsRef.current = attachments;
60539
+ const quoteRef = useRef(quote);
60540
+ quoteRef.current = quote;
60541
+ const isUploadingRef = useRef(isUploading);
60542
+ isUploadingRef.current = isUploading;
60408
60543
  const handleSubmit = useCallback(() => {
60409
60544
  var _a2;
60545
+ if (isUploadingRef.current) return;
60410
60546
  const editor2 = editorRef.current;
60411
- if (!editor2 || editor2.isEmpty) return;
60547
+ if (!editor2) return;
60548
+ const currentAttachments = attachmentsRef.current;
60549
+ const currentQuote = quoteRef.current;
60550
+ const hasExtras = currentAttachments.length > 0 || !!currentQuote;
60551
+ if (editor2.isEmpty && !hasExtras) return;
60412
60552
  const markdown = ((_a2 = editor2.storage.markdown) == null ? void 0 : _a2.getMarkdown()) ?? editor2.getText();
60413
- composerRuntime.setText(markdown);
60414
- composerRuntime.send();
60553
+ if (hasExtras) {
60554
+ const fullMessage = buildComposedMessage({
60555
+ attachments: currentAttachments,
60556
+ quote: currentQuote,
60557
+ userText: markdown
60558
+ });
60559
+ if (fullMessage) {
60560
+ aui.thread().append({
60561
+ role: "user",
60562
+ content: [{ type: "text", text: fullMessage }]
60563
+ });
60564
+ }
60565
+ clearAttachments();
60566
+ clearQuote();
60567
+ } else {
60568
+ composerRuntime.setText(markdown);
60569
+ composerRuntime.send();
60570
+ }
60415
60571
  editor2.commands.clearContent();
60416
- }, [composerRuntime]);
60572
+ }, [aui, composerRuntime, clearAttachments, clearQuote]);
60417
60573
  const editor = useEditor({
60418
60574
  immediatelyRender: true,
60419
60575
  extensions: [
@@ -60456,7 +60612,18 @@ const TiptapComposer = ({ tools = [] }) => {
60456
60612
  });
60457
60613
  useEffect(() => {
60458
60614
  editorRef.current = editor;
60459
- }, [editor]);
60615
+ composerEditorRef.current = editor ? {
60616
+ getMarkdown: () => {
60617
+ var _a2;
60618
+ return ((_a2 = editor.storage.markdown) == null ? void 0 : _a2.getMarkdown()) ?? editor.getText();
60619
+ },
60620
+ clear: () => editor.commands.clearContent(),
60621
+ isEmpty: () => editor.isEmpty,
60622
+ insertText: (text2) => {
60623
+ editor.chain().focus().insertContentAt(editor.state.doc.content.size, text2).run();
60624
+ }
60625
+ } : null;
60626
+ }, [editor, composerEditorRef]);
60460
60627
  return /* @__PURE__ */ jsx(EditorContent, { editor });
60461
60628
  };
60462
60629
  /**
@@ -60589,40 +60756,40 @@ const createLucideIcon = (iconName, iconNode) => {
60589
60756
  * This source code is licensed under the ISC license.
60590
60757
  * See the LICENSE file in the root directory of this source tree.
60591
60758
  */
60592
- const __iconNode$J = [
60759
+ const __iconNode$L = [
60593
60760
  ["path", { d: "M12 5v14", key: "s699le" }],
60594
60761
  ["path", { d: "m19 12-7 7-7-7", key: "1idqje" }]
60595
60762
  ];
60596
- const ArrowDown = createLucideIcon("arrow-down", __iconNode$J);
60763
+ const ArrowDown = createLucideIcon("arrow-down", __iconNode$L);
60597
60764
  /**
60598
60765
  * @license lucide-react v0.575.0 - ISC
60599
60766
  *
60600
60767
  * This source code is licensed under the ISC license.
60601
60768
  * See the LICENSE file in the root directory of this source tree.
60602
60769
  */
60603
- const __iconNode$I = [
60770
+ const __iconNode$K = [
60604
60771
  ["path", { d: "M5 12h14", key: "1ays0h" }],
60605
60772
  ["path", { d: "m12 5 7 7-7 7", key: "xquz4c" }]
60606
60773
  ];
60607
- const ArrowRight = createLucideIcon("arrow-right", __iconNode$I);
60774
+ const ArrowRight = createLucideIcon("arrow-right", __iconNode$K);
60608
60775
  /**
60609
60776
  * @license lucide-react v0.575.0 - ISC
60610
60777
  *
60611
60778
  * This source code is licensed under the ISC license.
60612
60779
  * See the LICENSE file in the root directory of this source tree.
60613
60780
  */
60614
- const __iconNode$H = [
60781
+ const __iconNode$J = [
60615
60782
  ["path", { d: "m5 12 7-7 7 7", key: "hav0vg" }],
60616
60783
  ["path", { d: "M12 19V5", key: "x0mq9r" }]
60617
60784
  ];
60618
- const ArrowUp = createLucideIcon("arrow-up", __iconNode$H);
60785
+ const ArrowUp = createLucideIcon("arrow-up", __iconNode$J);
60619
60786
  /**
60620
60787
  * @license lucide-react v0.575.0 - ISC
60621
60788
  *
60622
60789
  * This source code is licensed under the ISC license.
60623
60790
  * See the LICENSE file in the root directory of this source tree.
60624
60791
  */
60625
- const __iconNode$G = [
60792
+ const __iconNode$I = [
60626
60793
  ["path", { d: "M12 7v14", key: "1akyts" }],
60627
60794
  [
60628
60795
  "path",
@@ -60632,14 +60799,14 @@ const __iconNode$G = [
60632
60799
  }
60633
60800
  ]
60634
60801
  ];
60635
- const BookOpen = createLucideIcon("book-open", __iconNode$G);
60802
+ const BookOpen = createLucideIcon("book-open", __iconNode$I);
60636
60803
  /**
60637
60804
  * @license lucide-react v0.575.0 - ISC
60638
60805
  *
60639
60806
  * This source code is licensed under the ISC license.
60640
60807
  * See the LICENSE file in the root directory of this source tree.
60641
60808
  */
60642
- const __iconNode$F = [
60809
+ const __iconNode$H = [
60643
60810
  ["path", { d: "M12 18V5", key: "adv99a" }],
60644
60811
  ["path", { d: "M15 13a4.17 4.17 0 0 1-3-4 4.17 4.17 0 0 1-3 4", key: "1e3is1" }],
60645
60812
  ["path", { d: "M17.598 6.5A3 3 0 1 0 12 5a3 3 0 1 0-5.598 1.5", key: "1gqd8o" }],
@@ -60649,148 +60816,148 @@ const __iconNode$F = [
60649
60816
  ["path", { d: "M6 18a4 4 0 0 1-2-7.464", key: "k1g0md" }],
60650
60817
  ["path", { d: "M6.003 5.125a4 4 0 0 0-2.526 5.77", key: "q97ue3" }]
60651
60818
  ];
60652
- const Brain = createLucideIcon("brain", __iconNode$F);
60819
+ const Brain = createLucideIcon("brain", __iconNode$H);
60653
60820
  /**
60654
60821
  * @license lucide-react v0.575.0 - ISC
60655
60822
  *
60656
60823
  * This source code is licensed under the ISC license.
60657
60824
  * See the LICENSE file in the root directory of this source tree.
60658
60825
  */
60659
- const __iconNode$E = [
60826
+ const __iconNode$G = [
60660
60827
  ["path", { d: "M3 3v16a2 2 0 0 0 2 2h16", key: "c24i48" }],
60661
60828
  ["path", { d: "M18 17V9", key: "2bz60n" }],
60662
60829
  ["path", { d: "M13 17V5", key: "1frdt8" }],
60663
60830
  ["path", { d: "M8 17v-3", key: "17ska0" }]
60664
60831
  ];
60665
- const ChartColumn = createLucideIcon("chart-column", __iconNode$E);
60832
+ const ChartColumn = createLucideIcon("chart-column", __iconNode$G);
60666
60833
  /**
60667
60834
  * @license lucide-react v0.575.0 - ISC
60668
60835
  *
60669
60836
  * This source code is licensed under the ISC license.
60670
60837
  * See the LICENSE file in the root directory of this source tree.
60671
60838
  */
60672
- const __iconNode$D = [["path", { d: "M20 6 9 17l-5-5", key: "1gmf2c" }]];
60673
- const Check = createLucideIcon("check", __iconNode$D);
60839
+ const __iconNode$F = [["path", { d: "M20 6 9 17l-5-5", key: "1gmf2c" }]];
60840
+ const Check = createLucideIcon("check", __iconNode$F);
60674
60841
  /**
60675
60842
  * @license lucide-react v0.575.0 - ISC
60676
60843
  *
60677
60844
  * This source code is licensed under the ISC license.
60678
60845
  * See the LICENSE file in the root directory of this source tree.
60679
60846
  */
60680
- const __iconNode$C = [["path", { d: "m6 9 6 6 6-6", key: "qrunsl" }]];
60681
- const ChevronDown = createLucideIcon("chevron-down", __iconNode$C);
60847
+ const __iconNode$E = [["path", { d: "m6 9 6 6 6-6", key: "qrunsl" }]];
60848
+ const ChevronDown = createLucideIcon("chevron-down", __iconNode$E);
60682
60849
  /**
60683
60850
  * @license lucide-react v0.575.0 - ISC
60684
60851
  *
60685
60852
  * This source code is licensed under the ISC license.
60686
60853
  * See the LICENSE file in the root directory of this source tree.
60687
60854
  */
60688
- const __iconNode$B = [
60855
+ const __iconNode$D = [
60689
60856
  ["circle", { cx: "12", cy: "12", r: "10", key: "1mglay" }],
60690
60857
  ["line", { x1: "12", x2: "12", y1: "8", y2: "12", key: "1pkeuh" }],
60691
60858
  ["line", { x1: "12", x2: "12.01", y1: "16", y2: "16", key: "4dfq90" }]
60692
60859
  ];
60693
- const CircleAlert = createLucideIcon("circle-alert", __iconNode$B);
60860
+ const CircleAlert = createLucideIcon("circle-alert", __iconNode$D);
60694
60861
  /**
60695
60862
  * @license lucide-react v0.575.0 - ISC
60696
60863
  *
60697
60864
  * This source code is licensed under the ISC license.
60698
60865
  * See the LICENSE file in the root directory of this source tree.
60699
60866
  */
60700
- const __iconNode$A = [
60867
+ const __iconNode$C = [
60701
60868
  ["circle", { cx: "12", cy: "12", r: "10", key: "1mglay" }],
60702
60869
  ["path", { d: "m9 12 2 2 4-4", key: "dzmm74" }]
60703
60870
  ];
60704
- const CircleCheck = createLucideIcon("circle-check", __iconNode$A);
60871
+ const CircleCheck = createLucideIcon("circle-check", __iconNode$C);
60705
60872
  /**
60706
60873
  * @license lucide-react v0.575.0 - ISC
60707
60874
  *
60708
60875
  * This source code is licensed under the ISC license.
60709
60876
  * See the LICENSE file in the root directory of this source tree.
60710
60877
  */
60711
- const __iconNode$z = [
60878
+ const __iconNode$B = [
60712
60879
  ["circle", { cx: "12", cy: "12", r: "10", key: "1mglay" }],
60713
60880
  ["path", { d: "m15 9-6 6", key: "1uzhvr" }],
60714
60881
  ["path", { d: "m9 9 6 6", key: "z0biqf" }]
60715
60882
  ];
60716
- const CircleX = createLucideIcon("circle-x", __iconNode$z);
60883
+ const CircleX = createLucideIcon("circle-x", __iconNode$B);
60717
60884
  /**
60718
60885
  * @license lucide-react v0.575.0 - ISC
60719
60886
  *
60720
60887
  * This source code is licensed under the ISC license.
60721
60888
  * See the LICENSE file in the root directory of this source tree.
60722
60889
  */
60723
- const __iconNode$y = [
60890
+ const __iconNode$A = [
60724
60891
  ["path", { d: "m16 18 6-6-6-6", key: "eg8j8" }],
60725
60892
  ["path", { d: "m8 6-6 6 6 6", key: "ppft3o" }]
60726
60893
  ];
60727
- const Code = createLucideIcon("code", __iconNode$y);
60894
+ const Code = createLucideIcon("code", __iconNode$A);
60728
60895
  /**
60729
60896
  * @license lucide-react v0.575.0 - ISC
60730
60897
  *
60731
60898
  * This source code is licensed under the ISC license.
60732
60899
  * See the LICENSE file in the root directory of this source tree.
60733
60900
  */
60734
- const __iconNode$x = [
60901
+ const __iconNode$z = [
60735
60902
  ["rect", { width: "14", height: "14", x: "8", y: "8", rx: "2", ry: "2", key: "17jyea" }],
60736
60903
  ["path", { d: "M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2", key: "zix9uf" }]
60737
60904
  ];
60738
- const Copy = createLucideIcon("copy", __iconNode$x);
60905
+ const Copy = createLucideIcon("copy", __iconNode$z);
60739
60906
  /**
60740
60907
  * @license lucide-react v0.575.0 - ISC
60741
60908
  *
60742
60909
  * This source code is licensed under the ISC license.
60743
60910
  * See the LICENSE file in the root directory of this source tree.
60744
60911
  */
60745
- const __iconNode$w = [
60912
+ const __iconNode$y = [
60746
60913
  ["ellipse", { cx: "12", cy: "5", rx: "9", ry: "3", key: "msslwz" }],
60747
60914
  ["path", { d: "M3 5V19A9 3 0 0 0 21 19V5", key: "1wlel7" }],
60748
60915
  ["path", { d: "M3 12A9 3 0 0 0 21 12", key: "mv7ke4" }]
60749
60916
  ];
60750
- const Database = createLucideIcon("database", __iconNode$w);
60917
+ const Database = createLucideIcon("database", __iconNode$y);
60751
60918
  /**
60752
60919
  * @license lucide-react v0.575.0 - ISC
60753
60920
  *
60754
60921
  * This source code is licensed under the ISC license.
60755
60922
  * See the LICENSE file in the root directory of this source tree.
60756
60923
  */
60757
- const __iconNode$v = [
60924
+ const __iconNode$x = [
60758
60925
  ["path", { d: "M12 15V3", key: "m9g1x1" }],
60759
60926
  ["path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4", key: "ih7n3h" }],
60760
60927
  ["path", { d: "m7 10 5 5 5-5", key: "brsn70" }]
60761
60928
  ];
60762
- const Download = createLucideIcon("download", __iconNode$v);
60929
+ const Download = createLucideIcon("download", __iconNode$x);
60763
60930
  /**
60764
60931
  * @license lucide-react v0.575.0 - ISC
60765
60932
  *
60766
60933
  * This source code is licensed under the ISC license.
60767
60934
  * See the LICENSE file in the root directory of this source tree.
60768
60935
  */
60769
- const __iconNode$u = [
60936
+ const __iconNode$w = [
60770
60937
  ["circle", { cx: "12", cy: "12", r: "1", key: "41hilf" }],
60771
60938
  ["circle", { cx: "19", cy: "12", r: "1", key: "1wjl8i" }],
60772
60939
  ["circle", { cx: "5", cy: "12", r: "1", key: "1pcz8c" }]
60773
60940
  ];
60774
- const Ellipsis = createLucideIcon("ellipsis", __iconNode$u);
60941
+ const Ellipsis = createLucideIcon("ellipsis", __iconNode$w);
60775
60942
  /**
60776
60943
  * @license lucide-react v0.575.0 - ISC
60777
60944
  *
60778
60945
  * This source code is licensed under the ISC license.
60779
60946
  * See the LICENSE file in the root directory of this source tree.
60780
60947
  */
60781
- const __iconNode$t = [
60948
+ const __iconNode$v = [
60782
60949
  ["path", { d: "M15 3h6v6", key: "1q9fwt" }],
60783
60950
  ["path", { d: "M10 14 21 3", key: "gplh6r" }],
60784
60951
  ["path", { d: "M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6", key: "a6xqqp" }]
60785
60952
  ];
60786
- const ExternalLink = createLucideIcon("external-link", __iconNode$t);
60953
+ const ExternalLink = createLucideIcon("external-link", __iconNode$v);
60787
60954
  /**
60788
60955
  * @license lucide-react v0.575.0 - ISC
60789
60956
  *
60790
60957
  * This source code is licensed under the ISC license.
60791
60958
  * See the LICENSE file in the root directory of this source tree.
60792
60959
  */
60793
- const __iconNode$s = [
60960
+ const __iconNode$u = [
60794
60961
  [
60795
60962
  "path",
60796
60963
  {
@@ -60802,14 +60969,14 @@ const __iconNode$s = [
60802
60969
  ["path", { d: "M9 15h6", key: "cctwl0" }],
60803
60970
  ["path", { d: "M12 18v-6", key: "17g6i2" }]
60804
60971
  ];
60805
- const FilePlus = createLucideIcon("file-plus", __iconNode$s);
60972
+ const FilePlus = createLucideIcon("file-plus", __iconNode$u);
60806
60973
  /**
60807
60974
  * @license lucide-react v0.575.0 - ISC
60808
60975
  *
60809
60976
  * This source code is licensed under the ISC license.
60810
60977
  * See the LICENSE file in the root directory of this source tree.
60811
60978
  */
60812
- const __iconNode$r = [
60979
+ const __iconNode$t = [
60813
60980
  [
60814
60981
  "path",
60815
60982
  {
@@ -60823,14 +60990,14 @@ const __iconNode$r = [
60823
60990
  ["path", { d: "M8 17h2", key: "2yhykz" }],
60824
60991
  ["path", { d: "M14 17h2", key: "10kma7" }]
60825
60992
  ];
60826
- const FileSpreadsheet = createLucideIcon("file-spreadsheet", __iconNode$r);
60993
+ const FileSpreadsheet = createLucideIcon("file-spreadsheet", __iconNode$t);
60827
60994
  /**
60828
60995
  * @license lucide-react v0.575.0 - ISC
60829
60996
  *
60830
60997
  * This source code is licensed under the ISC license.
60831
60998
  * See the LICENSE file in the root directory of this source tree.
60832
60999
  */
60833
- const __iconNode$q = [
61000
+ const __iconNode$s = [
60834
61001
  [
60835
61002
  "path",
60836
61003
  {
@@ -60843,14 +61010,14 @@ const __iconNode$q = [
60843
61010
  ["path", { d: "M16 13H8", key: "t4e002" }],
60844
61011
  ["path", { d: "M16 17H8", key: "z1uh3a" }]
60845
61012
  ];
60846
- const FileText = createLucideIcon("file-text", __iconNode$q);
61013
+ const FileText = createLucideIcon("file-text", __iconNode$s);
60847
61014
  /**
60848
61015
  * @license lucide-react v0.575.0 - ISC
60849
61016
  *
60850
61017
  * This source code is licensed under the ISC license.
60851
61018
  * See the LICENSE file in the root directory of this source tree.
60852
61019
  */
60853
- const __iconNode$p = [
61020
+ const __iconNode$r = [
60854
61021
  [
60855
61022
  "path",
60856
61023
  {
@@ -60860,14 +61027,14 @@ const __iconNode$p = [
60860
61027
  ],
60861
61028
  ["path", { d: "M14 2v5a1 1 0 0 0 1 1h5", key: "wfsgrz" }]
60862
61029
  ];
60863
- const File$1 = createLucideIcon("file", __iconNode$p);
61030
+ const File$1 = createLucideIcon("file", __iconNode$r);
60864
61031
  /**
60865
61032
  * @license lucide-react v0.575.0 - ISC
60866
61033
  *
60867
61034
  * This source code is licensed under the ISC license.
60868
61035
  * See the LICENSE file in the root directory of this source tree.
60869
61036
  */
60870
- const __iconNode$o = [
61037
+ const __iconNode$q = [
60871
61038
  [
60872
61039
  "path",
60873
61040
  {
@@ -60876,38 +61043,38 @@ const __iconNode$o = [
60876
61043
  }
60877
61044
  ]
60878
61045
  ];
60879
- const FolderOpen = createLucideIcon("folder-open", __iconNode$o);
61046
+ const FolderOpen = createLucideIcon("folder-open", __iconNode$q);
60880
61047
  /**
60881
61048
  * @license lucide-react v0.575.0 - ISC
60882
61049
  *
60883
61050
  * This source code is licensed under the ISC license.
60884
61051
  * See the LICENSE file in the root directory of this source tree.
60885
61052
  */
60886
- const __iconNode$n = [
61053
+ const __iconNode$p = [
60887
61054
  ["circle", { cx: "12", cy: "12", r: "10", key: "1mglay" }],
60888
61055
  ["path", { d: "M12 2a14.5 14.5 0 0 0 0 20 14.5 14.5 0 0 0 0-20", key: "13o1zl" }],
60889
61056
  ["path", { d: "M2 12h20", key: "9i4pu4" }]
60890
61057
  ];
60891
- const Globe = createLucideIcon("globe", __iconNode$n);
61058
+ const Globe = createLucideIcon("globe", __iconNode$p);
60892
61059
  /**
60893
61060
  * @license lucide-react v0.575.0 - ISC
60894
61061
  *
60895
61062
  * This source code is licensed under the ISC license.
60896
61063
  * See the LICENSE file in the root directory of this source tree.
60897
61064
  */
60898
- const __iconNode$m = [
61065
+ const __iconNode$o = [
60899
61066
  ["rect", { width: "18", height: "18", x: "3", y: "3", rx: "2", ry: "2", key: "1m3agn" }],
60900
61067
  ["circle", { cx: "9", cy: "9", r: "2", key: "af1f0g" }],
60901
61068
  ["path", { d: "m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21", key: "1xmnt7" }]
60902
61069
  ];
60903
- const Image = createLucideIcon("image", __iconNode$m);
61070
+ const Image = createLucideIcon("image", __iconNode$o);
60904
61071
  /**
60905
61072
  * @license lucide-react v0.575.0 - ISC
60906
61073
  *
60907
61074
  * This source code is licensed under the ISC license.
60908
61075
  * See the LICENSE file in the root directory of this source tree.
60909
61076
  */
60910
- const __iconNode$l = [
61077
+ const __iconNode$n = [
60911
61078
  [
60912
61079
  "path",
60913
61080
  {
@@ -60930,46 +61097,46 @@ const __iconNode$l = [
60930
61097
  }
60931
61098
  ]
60932
61099
  ];
60933
- const Layers = createLucideIcon("layers", __iconNode$l);
61100
+ const Layers = createLucideIcon("layers", __iconNode$n);
60934
61101
  /**
60935
61102
  * @license lucide-react v0.575.0 - ISC
60936
61103
  *
60937
61104
  * This source code is licensed under the ISC license.
60938
61105
  * See the LICENSE file in the root directory of this source tree.
60939
61106
  */
60940
- const __iconNode$k = [
61107
+ const __iconNode$m = [
60941
61108
  ["rect", { width: "7", height: "7", x: "3", y: "3", rx: "1", key: "1g98yp" }],
60942
61109
  ["rect", { width: "7", height: "7", x: "14", y: "3", rx: "1", key: "6d4xhi" }],
60943
61110
  ["rect", { width: "7", height: "7", x: "14", y: "14", rx: "1", key: "nxv5o0" }],
60944
61111
  ["rect", { width: "7", height: "7", x: "3", y: "14", rx: "1", key: "1bb6yr" }]
60945
61112
  ];
60946
- const LayoutGrid = createLucideIcon("layout-grid", __iconNode$k);
61113
+ const LayoutGrid = createLucideIcon("layout-grid", __iconNode$m);
60947
61114
  /**
60948
61115
  * @license lucide-react v0.575.0 - ISC
60949
61116
  *
60950
61117
  * This source code is licensed under the ISC license.
60951
61118
  * See the LICENSE file in the root directory of this source tree.
60952
61119
  */
60953
- const __iconNode$j = [
61120
+ const __iconNode$l = [
60954
61121
  ["path", { d: "M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71", key: "1cjeqo" }],
60955
61122
  ["path", { d: "M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71", key: "19qd67" }]
60956
61123
  ];
60957
- const Link = createLucideIcon("link", __iconNode$j);
61124
+ const Link = createLucideIcon("link", __iconNode$l);
60958
61125
  /**
60959
61126
  * @license lucide-react v0.575.0 - ISC
60960
61127
  *
60961
61128
  * This source code is licensed under the ISC license.
60962
61129
  * See the LICENSE file in the root directory of this source tree.
60963
61130
  */
60964
- const __iconNode$i = [["path", { d: "M21 12a9 9 0 1 1-6.219-8.56", key: "13zald" }]];
60965
- const LoaderCircle = createLucideIcon("loader-circle", __iconNode$i);
61131
+ const __iconNode$k = [["path", { d: "M21 12a9 9 0 1 1-6.219-8.56", key: "13zald" }]];
61132
+ const LoaderCircle = createLucideIcon("loader-circle", __iconNode$k);
60966
61133
  /**
60967
61134
  * @license lucide-react v0.575.0 - ISC
60968
61135
  *
60969
61136
  * This source code is licensed under the ISC license.
60970
61137
  * See the LICENSE file in the root directory of this source tree.
60971
61138
  */
60972
- const __iconNode$h = [
61139
+ const __iconNode$j = [
60973
61140
  ["path", { d: "M12 2v4", key: "3427ic" }],
60974
61141
  ["path", { d: "m16.2 7.8 2.9-2.9", key: "r700ao" }],
60975
61142
  ["path", { d: "M18 12h4", key: "wj9ykh" }],
@@ -60979,38 +61146,38 @@ const __iconNode$h = [
60979
61146
  ["path", { d: "M2 12h4", key: "j09sii" }],
60980
61147
  ["path", { d: "m4.9 4.9 2.9 2.9", key: "giyufr" }]
60981
61148
  ];
60982
- const Loader = createLucideIcon("loader", __iconNode$h);
61149
+ const Loader = createLucideIcon("loader", __iconNode$j);
60983
61150
  /**
60984
61151
  * @license lucide-react v0.575.0 - ISC
60985
61152
  *
60986
61153
  * This source code is licensed under the ISC license.
60987
61154
  * See the LICENSE file in the root directory of this source tree.
60988
61155
  */
60989
- const __iconNode$g = [
61156
+ const __iconNode$i = [
60990
61157
  ["path", { d: "m22 7-8.991 5.727a2 2 0 0 1-2.009 0L2 7", key: "132q7q" }],
60991
61158
  ["rect", { x: "2", y: "4", width: "20", height: "16", rx: "2", key: "izxlao" }]
60992
61159
  ];
60993
- const Mail = createLucideIcon("mail", __iconNode$g);
61160
+ const Mail = createLucideIcon("mail", __iconNode$i);
60994
61161
  /**
60995
61162
  * @license lucide-react v0.575.0 - ISC
60996
61163
  *
60997
61164
  * This source code is licensed under the ISC license.
60998
61165
  * See the LICENSE file in the root directory of this source tree.
60999
61166
  */
61000
- const __iconNode$f = [
61167
+ const __iconNode$h = [
61001
61168
  ["path", { d: "M15 3h6v6", key: "1q9fwt" }],
61002
61169
  ["path", { d: "m21 3-7 7", key: "1l2asr" }],
61003
61170
  ["path", { d: "m3 21 7-7", key: "tjx5ai" }],
61004
61171
  ["path", { d: "M9 21H3v-6", key: "wtvkvv" }]
61005
61172
  ];
61006
- const Maximize2 = createLucideIcon("maximize-2", __iconNode$f);
61173
+ const Maximize2 = createLucideIcon("maximize-2", __iconNode$h);
61007
61174
  /**
61008
61175
  * @license lucide-react v0.575.0 - ISC
61009
61176
  *
61010
61177
  * This source code is licensed under the ISC license.
61011
61178
  * See the LICENSE file in the root directory of this source tree.
61012
61179
  */
61013
- const __iconNode$e = [
61180
+ const __iconNode$g = [
61014
61181
  [
61015
61182
  "path",
61016
61183
  {
@@ -61019,39 +61186,39 @@ const __iconNode$e = [
61019
61186
  }
61020
61187
  ]
61021
61188
  ];
61022
- const MessageSquare = createLucideIcon("message-square", __iconNode$e);
61189
+ const MessageSquare = createLucideIcon("message-square", __iconNode$g);
61023
61190
  /**
61024
61191
  * @license lucide-react v0.575.0 - ISC
61025
61192
  *
61026
61193
  * This source code is licensed under the ISC license.
61027
61194
  * See the LICENSE file in the root directory of this source tree.
61028
61195
  */
61029
- const __iconNode$d = [
61196
+ const __iconNode$f = [
61030
61197
  ["path", { d: "m14 10 7-7", key: "oa77jy" }],
61031
61198
  ["path", { d: "M20 10h-6V4", key: "mjg0md" }],
61032
61199
  ["path", { d: "m3 21 7-7", key: "tjx5ai" }],
61033
61200
  ["path", { d: "M4 14h6v6", key: "rmj7iw" }]
61034
61201
  ];
61035
- const Minimize2 = createLucideIcon("minimize-2", __iconNode$d);
61202
+ const Minimize2 = createLucideIcon("minimize-2", __iconNode$f);
61036
61203
  /**
61037
61204
  * @license lucide-react v0.575.0 - ISC
61038
61205
  *
61039
61206
  * This source code is licensed under the ISC license.
61040
61207
  * See the LICENSE file in the root directory of this source tree.
61041
61208
  */
61042
- const __iconNode$c = [
61209
+ const __iconNode$e = [
61043
61210
  ["rect", { width: "20", height: "14", x: "2", y: "3", rx: "2", key: "48i651" }],
61044
61211
  ["line", { x1: "8", x2: "16", y1: "21", y2: "21", key: "1svkeh" }],
61045
61212
  ["line", { x1: "12", x2: "12", y1: "17", y2: "21", key: "vw1qmm" }]
61046
61213
  ];
61047
- const Monitor = createLucideIcon("monitor", __iconNode$c);
61214
+ const Monitor = createLucideIcon("monitor", __iconNode$e);
61048
61215
  /**
61049
61216
  * @license lucide-react v0.575.0 - ISC
61050
61217
  *
61051
61218
  * This source code is licensed under the ISC license.
61052
61219
  * See the LICENSE file in the root directory of this source tree.
61053
61220
  */
61054
- const __iconNode$b = [
61221
+ const __iconNode$d = [
61055
61222
  ["path", { d: "M13.4 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-7.4", key: "re6nr2" }],
61056
61223
  ["path", { d: "M2 6h4", key: "aawbzj" }],
61057
61224
  ["path", { d: "M2 10h4", key: "l0bgd4" }],
@@ -61065,14 +61232,30 @@ const __iconNode$b = [
61065
61232
  }
61066
61233
  ]
61067
61234
  ];
61068
- const NotebookPen = createLucideIcon("notebook-pen", __iconNode$b);
61235
+ const NotebookPen = createLucideIcon("notebook-pen", __iconNode$d);
61069
61236
  /**
61070
61237
  * @license lucide-react v0.575.0 - ISC
61071
61238
  *
61072
61239
  * This source code is licensed under the ISC license.
61073
61240
  * See the LICENSE file in the root directory of this source tree.
61074
61241
  */
61075
- const __iconNode$a = [
61242
+ const __iconNode$c = [
61243
+ [
61244
+ "path",
61245
+ {
61246
+ d: "m16 6-8.414 8.586a2 2 0 0 0 2.829 2.829l8.414-8.586a4 4 0 1 0-5.657-5.657l-8.379 8.551a6 6 0 1 0 8.485 8.485l8.379-8.551",
61247
+ key: "1miecu"
61248
+ }
61249
+ ]
61250
+ ];
61251
+ const Paperclip = createLucideIcon("paperclip", __iconNode$c);
61252
+ /**
61253
+ * @license lucide-react v0.575.0 - ISC
61254
+ *
61255
+ * This source code is licensed under the ISC license.
61256
+ * See the LICENSE file in the root directory of this source tree.
61257
+ */
61258
+ const __iconNode$b = [
61076
61259
  ["path", { d: "M13 21h8", key: "1jsn5i" }],
61077
61260
  [
61078
61261
  "path",
@@ -61082,30 +61265,53 @@ const __iconNode$a = [
61082
61265
  }
61083
61266
  ]
61084
61267
  ];
61085
- const PenLine = createLucideIcon("pen-line", __iconNode$a);
61268
+ const PenLine = createLucideIcon("pen-line", __iconNode$b);
61086
61269
  /**
61087
61270
  * @license lucide-react v0.575.0 - ISC
61088
61271
  *
61089
61272
  * This source code is licensed under the ISC license.
61090
61273
  * See the LICENSE file in the root directory of this source tree.
61091
61274
  */
61092
- const __iconNode$9 = [
61275
+ const __iconNode$a = [
61093
61276
  ["path", { d: "M5 12h14", key: "1ays0h" }],
61094
61277
  ["path", { d: "M12 5v14", key: "s699le" }]
61095
61278
  ];
61096
- const Plus = createLucideIcon("plus", __iconNode$9);
61279
+ const Plus = createLucideIcon("plus", __iconNode$a);
61097
61280
  /**
61098
61281
  * @license lucide-react v0.575.0 - ISC
61099
61282
  *
61100
61283
  * This source code is licensed under the ISC license.
61101
61284
  * See the LICENSE file in the root directory of this source tree.
61102
61285
  */
61103
- const __iconNode$8 = [
61286
+ const __iconNode$9 = [
61104
61287
  ["path", { d: "M2 3h20", key: "91anmk" }],
61105
61288
  ["path", { d: "M21 3v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V3", key: "2k9sn8" }],
61106
61289
  ["path", { d: "m7 21 5-5 5 5", key: "bip4we" }]
61107
61290
  ];
61108
- const Presentation = createLucideIcon("presentation", __iconNode$8);
61291
+ const Presentation = createLucideIcon("presentation", __iconNode$9);
61292
+ /**
61293
+ * @license lucide-react v0.575.0 - ISC
61294
+ *
61295
+ * This source code is licensed under the ISC license.
61296
+ * See the LICENSE file in the root directory of this source tree.
61297
+ */
61298
+ const __iconNode$8 = [
61299
+ [
61300
+ "path",
61301
+ {
61302
+ d: "M16 3a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2 1 1 0 0 1 1 1v1a2 2 0 0 1-2 2 1 1 0 0 0-1 1v2a1 1 0 0 0 1 1 6 6 0 0 0 6-6V5a2 2 0 0 0-2-2z",
61303
+ key: "rib7q0"
61304
+ }
61305
+ ],
61306
+ [
61307
+ "path",
61308
+ {
61309
+ d: "M5 3a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2 1 1 0 0 1 1 1v1a2 2 0 0 1-2 2 1 1 0 0 0-1 1v2a1 1 0 0 0 1 1 6 6 0 0 0 6-6V5a2 2 0 0 0-2-2z",
61310
+ key: "1ymkrd"
61311
+ }
61312
+ ]
61313
+ ];
61314
+ const Quote = createLucideIcon("quote", __iconNode$8);
61109
61315
  /**
61110
61316
  * @license lucide-react v0.575.0 - ISC
61111
61317
  *
@@ -61298,7 +61504,6 @@ const TOOL_META = {
61298
61504
  execute_presentation_code: { displayName: "Generating slides", icon: Monitor },
61299
61505
  // Code & Data
61300
61506
  run_python_code: { displayName: "Running analysis", icon: Code },
61301
- // Debug: temporarily log all tool names hitting the fallback
61302
61507
  run_sql_query_tool: { displayName: "Querying data", icon: Database },
61303
61508
  create_database: { displayName: "Setting up database", icon: Database },
61304
61509
  run_database_sql: { displayName: "Querying database", icon: Database },
@@ -62587,23 +62792,28 @@ function parsePythonResult(result) {
62587
62792
  const createdAssets = Array.isArray(data.created_assets) ? data.created_assets : [];
62588
62793
  return { stdout, stderr, value, error: error2, exception, imagePng, plotlyJson, createdAssets };
62589
62794
  }
62795
+ function getPlotly() {
62796
+ return window.Plotly;
62797
+ }
62590
62798
  let plotlyLoadPromise = null;
62591
62799
  function ensurePlotlyLoaded() {
62592
- if (window.Plotly) return Promise.resolve();
62800
+ if (getPlotly()) return Promise.resolve();
62593
62801
  if (plotlyLoadPromise) return plotlyLoadPromise;
62594
62802
  plotlyLoadPromise = new Promise((resolve, reject) => {
62595
62803
  const script = document.createElement("script");
62596
62804
  script.src = "https://cdn.plot.ly/plotly-2.35.2.min.js";
62805
+ script.crossOrigin = "anonymous";
62597
62806
  script.onload = () => resolve();
62598
62807
  script.onerror = () => {
62599
62808
  plotlyLoadPromise = null;
62809
+ document.head.removeChild(script);
62600
62810
  reject(new Error("Failed to load Plotly"));
62601
62811
  };
62602
62812
  document.head.appendChild(script);
62603
62813
  });
62604
62814
  return plotlyLoadPromise;
62605
62815
  }
62606
- const PlotlyChart = ({ json }) => {
62816
+ const PlotlyChart = ({ json, height = 500 }) => {
62607
62817
  const chartRef = useRef(null);
62608
62818
  const [error2, setError] = useState(null);
62609
62819
  useEffect(() => {
@@ -62611,7 +62821,8 @@ const PlotlyChart = ({ json }) => {
62611
62821
  ensurePlotlyLoaded().then(() => {
62612
62822
  if (cancelled || !chartRef.current) return;
62613
62823
  const parsed = JSON.parse(json);
62614
- const Plotly = window.Plotly;
62824
+ const Plotly = getPlotly();
62825
+ if (!Plotly) return;
62615
62826
  Plotly.newPlot(
62616
62827
  chartRef.current,
62617
62828
  parsed.data || [],
@@ -62624,15 +62835,58 @@ const PlotlyChart = ({ json }) => {
62624
62835
  return () => {
62625
62836
  cancelled = true;
62626
62837
  if (chartRef.current) {
62627
- const Plotly = window.Plotly;
62628
- if (Plotly == null ? void 0 : Plotly.purge) Plotly.purge(chartRef.current);
62838
+ const Plotly = getPlotly();
62839
+ if (Plotly) Plotly.purge(chartRef.current);
62629
62840
  }
62630
62841
  };
62631
62842
  }, [json]);
62632
62843
  if (error2) {
62633
62844
  return /* @__PURE__ */ jsx("p", { className: "text-xs text-destructive", children: error2 });
62634
62845
  }
62635
- return /* @__PURE__ */ jsx("div", { ref: chartRef, className: "w-full overflow-hidden", style: { height: 500 } });
62846
+ return /* @__PURE__ */ jsx("div", { ref: chartRef, className: "w-full overflow-hidden", style: { height } });
62847
+ };
62848
+ const PlotlyChartSection = ({ json }) => {
62849
+ const [isFullscreen, setIsFullscreen] = useState(false);
62850
+ return /* @__PURE__ */ jsxs(Fragment$2, { children: [
62851
+ /* @__PURE__ */ jsxs("div", { className: "border-t border-border/40 px-4 py-2.5", children: [
62852
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between mb-1.5", children: [
62853
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5", children: [
62854
+ /* @__PURE__ */ jsx(ChartColumn, { className: "size-3 text-muted-foreground" }),
62855
+ /* @__PURE__ */ jsx("span", { className: "text-[11px] font-medium text-muted-foreground", children: "Interactive chart" })
62856
+ ] }),
62857
+ /* @__PURE__ */ jsx(
62858
+ "button",
62859
+ {
62860
+ type: "button",
62861
+ onClick: () => setIsFullscreen(true),
62862
+ className: "flex items-center gap-1 rounded-md px-1.5 py-1 text-[11px] text-muted-foreground transition-colors hover:bg-muted/50 hover:text-foreground",
62863
+ title: "View full screen",
62864
+ children: /* @__PURE__ */ jsx(Maximize2, { className: "size-3.5" })
62865
+ }
62866
+ )
62867
+ ] }),
62868
+ /* @__PURE__ */ jsx(PlotlyChart, { json })
62869
+ ] }),
62870
+ isFullscreen && /* @__PURE__ */ jsxs("div", { className: "fixed inset-0 z-[9999] flex flex-col bg-background", children: [
62871
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between px-6 py-3 border-b border-border", children: [
62872
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
62873
+ /* @__PURE__ */ jsx(ChartColumn, { className: "size-4 text-muted-foreground" }),
62874
+ /* @__PURE__ */ jsx("span", { className: "text-sm font-medium", children: "Interactive chart" })
62875
+ ] }),
62876
+ /* @__PURE__ */ jsx(
62877
+ "button",
62878
+ {
62879
+ type: "button",
62880
+ onClick: () => setIsFullscreen(false),
62881
+ className: "flex items-center justify-center rounded-md p-1.5 text-muted-foreground transition-colors hover:bg-muted/50 hover:text-foreground",
62882
+ title: "Close full screen",
62883
+ children: /* @__PURE__ */ jsx(X, { className: "size-5" })
62884
+ }
62885
+ )
62886
+ ] }),
62887
+ /* @__PURE__ */ jsx("div", { className: "flex-1 min-h-0 p-4", children: /* @__PURE__ */ jsx(PlotlyChart, { json, height: "100%" }) })
62888
+ ] })
62889
+ ] });
62636
62890
  };
62637
62891
  const SyntaxHighlightedCode = memo(({ code: code2 }) => {
62638
62892
  const highlighted = useMemo(() => highlightPython(code2), [code2]);
@@ -62849,13 +63103,7 @@ const RunPythonCodeToolUIImpl = ({
62849
63103
  ] }),
62850
63104
  /* @__PURE__ */ jsx("pre", { className: "max-h-48 overflow-auto whitespace-pre-wrap break-words rounded-md bg-destructive/5 p-2 text-[11px] leading-relaxed font-mono text-destructive/80", children: ((_a2 = parsed.exception) == null ? void 0 : _a2.traceback) ?? parsed.error })
62851
63105
  ] }),
62852
- isComplete && hasPlotly && /* @__PURE__ */ jsxs("div", { className: "border-t border-border/40 px-4 py-2.5", children: [
62853
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5 mb-1.5", children: [
62854
- /* @__PURE__ */ jsx(ChartColumn, { className: "size-3 text-muted-foreground" }),
62855
- /* @__PURE__ */ jsx("span", { className: "text-[11px] font-medium text-muted-foreground", children: "Interactive chart" })
62856
- ] }),
62857
- /* @__PURE__ */ jsx(PlotlyChart, { json: parsed.plotlyJson })
62858
- ] }),
63106
+ isComplete && hasPlotly && /* @__PURE__ */ jsx(PlotlyChartSection, { json: parsed.plotlyJson }),
62859
63107
  isComplete && hasImage && !hasPlotly && /* @__PURE__ */ jsxs("div", { className: "border-t border-border/40 px-4 py-2.5", children: [
62860
63108
  /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5 mb-1.5", children: [
62861
63109
  /* @__PURE__ */ jsx(Image, { className: "size-3 text-muted-foreground" }),
@@ -63086,6 +63334,305 @@ const TooltipIconButton = forwardRef(
63086
63334
  }
63087
63335
  );
63088
63336
  TooltipIconButton.displayName = "TooltipIconButton";
63337
+ const MAX_FILE_SIZE = 5 * 1024 * 1024 * 1024;
63338
+ function useFileUpload() {
63339
+ const { backendUrl, apiKey, token } = useAthenaConfig();
63340
+ const [isUploading, setIsUploading] = useState(false);
63341
+ const [progress, setProgress] = useState(null);
63342
+ const [error2, setError] = useState(null);
63343
+ const xhrRef = useRef(null);
63344
+ useEffect(() => {
63345
+ return () => {
63346
+ var _a2;
63347
+ (_a2 = xhrRef.current) == null ? void 0 : _a2.abort();
63348
+ };
63349
+ }, []);
63350
+ const clearError = useCallback(() => setError(null), []);
63351
+ const upload = useCallback(
63352
+ async (files) => {
63353
+ var _a2;
63354
+ if (files.length === 0) return [];
63355
+ for (const file of files) {
63356
+ if (file.size > MAX_FILE_SIZE) {
63357
+ const msg = `File "${file.name}" exceeds the maximum size of 5 GB.`;
63358
+ setError(msg);
63359
+ throw new Error(msg);
63360
+ }
63361
+ }
63362
+ setIsUploading(true);
63363
+ setError(null);
63364
+ setProgress({ current: 0, total: files.length, fileName: ((_a2 = files[0]) == null ? void 0 : _a2.name) ?? "", percent: 0 });
63365
+ try {
63366
+ const formData = new FormData();
63367
+ for (const file of files) {
63368
+ formData.append("files", file, file.name);
63369
+ }
63370
+ const baseUrl = backendUrl.replace(/\/api\/assistant-ui\/?$/, "");
63371
+ if (baseUrl === backendUrl) {
63372
+ console.warn("[AthenaSDK] useFileUpload: backendUrl does not end with /api/assistant-ui — upload URL may be incorrect:", `${baseUrl}/api/upload/`);
63373
+ }
63374
+ const uploadUrl = `${baseUrl}/api/upload/`;
63375
+ const headers = {};
63376
+ if (token) {
63377
+ headers["Authorization"] = `Bearer ${token}`;
63378
+ } else if (apiKey) {
63379
+ headers["X-API-KEY"] = apiKey;
63380
+ }
63381
+ const xhr = new XMLHttpRequest();
63382
+ xhrRef.current = xhr;
63383
+ const result = await new Promise((resolve, reject) => {
63384
+ xhr.upload.addEventListener("progress", (e) => {
63385
+ var _a3;
63386
+ if (e.lengthComputable) {
63387
+ const percent = e.loaded / e.total;
63388
+ const fileIndex = Math.min(
63389
+ Math.floor(percent * files.length),
63390
+ files.length - 1
63391
+ );
63392
+ setProgress({
63393
+ current: fileIndex + 1,
63394
+ total: files.length,
63395
+ fileName: ((_a3 = files[fileIndex]) == null ? void 0 : _a3.name) ?? "",
63396
+ percent
63397
+ });
63398
+ }
63399
+ });
63400
+ xhr.addEventListener("load", () => {
63401
+ if (xhr.status >= 200 && xhr.status < 300) {
63402
+ try {
63403
+ const data = JSON.parse(xhr.responseText);
63404
+ const assets = (data.success ?? []).map((a) => ({
63405
+ id: a.id,
63406
+ title: a.title ?? a.file_name,
63407
+ fileName: a.file_name,
63408
+ fileSize: a.file_size,
63409
+ mediaType: a.media_type
63410
+ }));
63411
+ resolve({ success: assets, errors: data.errors ?? [] });
63412
+ } catch {
63413
+ reject(new Error("Failed to parse upload response"));
63414
+ }
63415
+ } else if (xhr.status === 401 || xhr.status === 403) {
63416
+ reject(new Error("Authentication failed. Check your API key or token."));
63417
+ } else {
63418
+ reject(new Error(`Upload failed with status ${xhr.status}`));
63419
+ }
63420
+ });
63421
+ xhr.addEventListener("error", () => reject(new Error("Network error during upload")));
63422
+ xhr.addEventListener("abort", () => reject(new Error("Upload was cancelled")));
63423
+ xhr.open("POST", uploadUrl);
63424
+ for (const [key, value] of Object.entries(headers)) {
63425
+ xhr.setRequestHeader(key, value);
63426
+ }
63427
+ xhr.withCredentials = !token && !apiKey;
63428
+ xhr.send(formData);
63429
+ });
63430
+ if (result.errors.length > 0) {
63431
+ const errMsg = result.errors.map((e) => `${e.file.filename}: ${e.error}`).join("; ");
63432
+ if (result.success.length === 0) {
63433
+ setError(errMsg);
63434
+ throw new Error(errMsg);
63435
+ }
63436
+ setError(errMsg);
63437
+ }
63438
+ return result.success;
63439
+ } catch (err) {
63440
+ const msg = err instanceof Error ? err.message : "Upload failed";
63441
+ setError(msg);
63442
+ throw err;
63443
+ } finally {
63444
+ xhrRef.current = null;
63445
+ setIsUploading(false);
63446
+ setProgress(null);
63447
+ }
63448
+ },
63449
+ [backendUrl, apiKey, token]
63450
+ );
63451
+ return { upload, isUploading, progress, error: error2, clearError };
63452
+ }
63453
+ const FileUploadButton = ({
63454
+ className,
63455
+ onUpload,
63456
+ accept
63457
+ }) => {
63458
+ const inputRef = useRef(null);
63459
+ const { upload, isUploading, error: error2, clearError } = useFileUpload();
63460
+ const { addAttachments, setIsUploading } = useAttachments();
63461
+ const handleClick2 = useCallback(() => {
63462
+ var _a2;
63463
+ clearError();
63464
+ (_a2 = inputRef.current) == null ? void 0 : _a2.click();
63465
+ }, [clearError]);
63466
+ const handleFiles = useCallback(
63467
+ async (files) => {
63468
+ if (!files || files.length === 0) return;
63469
+ const fileArray = Array.from(files);
63470
+ setIsUploading(true);
63471
+ try {
63472
+ const assets = await upload(fileArray);
63473
+ if (assets.length > 0) {
63474
+ addAttachments(assets);
63475
+ onUpload == null ? void 0 : onUpload(assets);
63476
+ }
63477
+ } catch {
63478
+ } finally {
63479
+ setIsUploading(false);
63480
+ }
63481
+ if (inputRef.current) {
63482
+ inputRef.current.value = "";
63483
+ }
63484
+ },
63485
+ [upload, addAttachments, setIsUploading, onUpload]
63486
+ );
63487
+ return /* @__PURE__ */ jsxs(Fragment$2, { children: [
63488
+ /* @__PURE__ */ jsx(
63489
+ "input",
63490
+ {
63491
+ ref: inputRef,
63492
+ type: "file",
63493
+ multiple: true,
63494
+ accept,
63495
+ className: "hidden",
63496
+ onChange: (e) => handleFiles(e.target.files),
63497
+ "aria-label": "Upload files"
63498
+ }
63499
+ ),
63500
+ /* @__PURE__ */ jsx(
63501
+ "button",
63502
+ {
63503
+ type: "button",
63504
+ onClick: handleClick2,
63505
+ disabled: isUploading,
63506
+ className: cn(
63507
+ "aui-file-upload-btn flex items-center justify-center rounded-md p-1.5 text-muted-foreground transition-colors hover:bg-muted hover:text-foreground disabled:opacity-50 disabled:pointer-events-none",
63508
+ error2 && "text-destructive",
63509
+ className
63510
+ ),
63511
+ title: error2 ?? (isUploading ? "Uploading..." : "Attach files"),
63512
+ "aria-label": isUploading ? "Uploading files" : "Attach files",
63513
+ children: isUploading ? /* @__PURE__ */ jsx(LoaderCircle, { className: "size-4 animate-spin" }) : error2 ? /* @__PURE__ */ jsx(CircleAlert, { className: "size-4" }) : /* @__PURE__ */ jsx(Paperclip, { className: "size-4" })
63514
+ }
63515
+ )
63516
+ ] });
63517
+ };
63518
+ const ComposerQuotePreview = ({ className }) => {
63519
+ const { quote, clearQuote } = useQuote();
63520
+ if (!quote) return null;
63521
+ const previewText = quote.text.length > 200 ? quote.text.slice(0, 200).trimEnd() + "…" : quote.text;
63522
+ return /* @__PURE__ */ jsxs(
63523
+ "div",
63524
+ {
63525
+ className: cn(
63526
+ "aui-quote-preview mx-3 mt-2 flex items-start gap-2 rounded-lg border border-border/60 bg-muted/40 px-3 py-2 text-sm",
63527
+ className
63528
+ ),
63529
+ children: [
63530
+ /* @__PURE__ */ jsx(Quote, { className: "mt-0.5 size-3.5 shrink-0 text-muted-foreground/60" }),
63531
+ /* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
63532
+ quote.sourceTitle && /* @__PURE__ */ jsxs("div", { className: "mb-0.5 truncate text-xs font-medium text-muted-foreground", children: [
63533
+ "From ",
63534
+ quote.sourceTitle
63535
+ ] }),
63536
+ /* @__PURE__ */ jsx("div", { className: "line-clamp-3 whitespace-pre-wrap text-xs text-foreground/80 leading-relaxed", children: previewText })
63537
+ ] }),
63538
+ /* @__PURE__ */ jsx(
63539
+ "button",
63540
+ {
63541
+ type: "button",
63542
+ onClick: clearQuote,
63543
+ className: "mt-0.5 shrink-0 rounded p-0.5 text-muted-foreground hover:bg-muted hover:text-foreground transition-colors",
63544
+ "aria-label": "Remove quote",
63545
+ children: /* @__PURE__ */ jsx(X, { className: "size-3.5" })
63546
+ }
63547
+ )
63548
+ ]
63549
+ }
63550
+ );
63551
+ };
63552
+ const ComposerAttachmentPreview = ({ className }) => {
63553
+ const { attachments, removeAttachment } = useAttachments();
63554
+ if (attachments.length === 0) return null;
63555
+ return /* @__PURE__ */ jsx("div", { className: cn("aui-attachment-preview mx-3 mt-2 flex flex-wrap gap-1.5", className), children: attachments.map((asset) => /* @__PURE__ */ jsxs(
63556
+ "div",
63557
+ {
63558
+ className: "flex items-center gap-1.5 rounded-lg border border-border/60 bg-muted/40 px-2.5 py-1.5 text-xs",
63559
+ children: [
63560
+ /* @__PURE__ */ jsx(Paperclip, { className: "size-3 shrink-0 text-muted-foreground/60" }),
63561
+ /* @__PURE__ */ jsx("span", { className: "max-w-[180px] truncate text-foreground/80", children: asset.title }),
63562
+ /* @__PURE__ */ jsx(
63563
+ "button",
63564
+ {
63565
+ type: "button",
63566
+ onClick: () => removeAttachment(asset.id),
63567
+ className: "shrink-0 rounded p-0.5 text-muted-foreground hover:bg-muted hover:text-foreground transition-colors",
63568
+ "aria-label": `Remove ${asset.title}`,
63569
+ children: /* @__PURE__ */ jsx(X, { className: "size-3" })
63570
+ }
63571
+ )
63572
+ ]
63573
+ },
63574
+ asset.id
63575
+ )) });
63576
+ };
63577
+ const ComposerDropZone = ({
63578
+ children,
63579
+ className,
63580
+ onUpload
63581
+ }) => {
63582
+ const [isDragOver, setIsDragOver] = useState(false);
63583
+ const { upload, isUploading } = useFileUpload();
63584
+ const { addAttachments, setIsUploading } = useAttachments();
63585
+ const handleDragOver = useCallback((e) => {
63586
+ e.preventDefault();
63587
+ e.stopPropagation();
63588
+ if (e.dataTransfer.types.includes("Files")) {
63589
+ setIsDragOver(true);
63590
+ }
63591
+ }, []);
63592
+ const handleDragLeave = useCallback((e) => {
63593
+ e.preventDefault();
63594
+ e.stopPropagation();
63595
+ const rect = e.currentTarget.getBoundingClientRect();
63596
+ const { clientX, clientY } = e;
63597
+ if (clientX < rect.left || clientX > rect.right || clientY < rect.top || clientY > rect.bottom) {
63598
+ setIsDragOver(false);
63599
+ }
63600
+ }, []);
63601
+ const handleDrop2 = useCallback(
63602
+ async (e) => {
63603
+ e.preventDefault();
63604
+ e.stopPropagation();
63605
+ setIsDragOver(false);
63606
+ const files = Array.from(e.dataTransfer.files);
63607
+ if (files.length === 0) return;
63608
+ setIsUploading(true);
63609
+ try {
63610
+ const assets = await upload(files);
63611
+ if (assets.length > 0) {
63612
+ addAttachments(assets);
63613
+ onUpload == null ? void 0 : onUpload(assets);
63614
+ }
63615
+ } catch {
63616
+ } finally {
63617
+ setIsUploading(false);
63618
+ }
63619
+ },
63620
+ [upload, addAttachments, setIsUploading, onUpload]
63621
+ );
63622
+ return /* @__PURE__ */ jsxs(
63623
+ "div",
63624
+ {
63625
+ className: cn("relative", className),
63626
+ onDragOver: handleDragOver,
63627
+ onDragLeave: handleDragLeave,
63628
+ onDrop: handleDrop2,
63629
+ children: [
63630
+ children,
63631
+ isDragOver && !isUploading && /* @__PURE__ */ jsx("div", { className: "aui-drop-overlay pointer-events-none absolute inset-0 z-20 flex items-center justify-center rounded-2xl border-2 border-dashed border-primary/50 bg-primary/5", children: /* @__PURE__ */ jsx("span", { className: "text-sm font-medium text-primary", children: "Drop files to upload" }) })
63632
+ ]
63633
+ }
63634
+ );
63635
+ };
63089
63636
  const EMPTY_MENTION_TOOLS = [];
63090
63637
  const DEFAULT_SUGGESTIONS = [
63091
63638
  {
@@ -63172,7 +63719,7 @@ const AthenaChat = ({
63172
63719
  /* @__PURE__ */ jsx(AuiIf, { condition: (s) => s.thread.isEmpty, children: /* @__PURE__ */ jsx("div", { className: "aui-thread-welcome-root mx-auto my-auto flex w-full max-w-(--thread-max-width) grow flex-col", children: /* @__PURE__ */ jsx("div", { className: "aui-thread-welcome-center flex w-full grow flex-col items-center justify-center", children: /* @__PURE__ */ jsxs("div", { className: "aui-thread-welcome-message flex size-full flex-col justify-center px-4", children: [
63173
63720
  /* @__PURE__ */ jsx("h1", { className: "aui-thread-welcome-message-inner fade-in slide-in-from-bottom-1 animate-in fill-mode-both font-semibold text-2xl duration-200", children: welcomeMessage }),
63174
63721
  welcomeSubtext && /* @__PURE__ */ jsx("p", { className: "aui-thread-welcome-message-inner fade-in slide-in-from-bottom-1 animate-in fill-mode-both text-muted-foreground text-lg delay-75 duration-200", children: welcomeSubtext }),
63175
- welcomeSuggestions.length > 0 && /* @__PURE__ */ jsx("div", { className: "mt-6 grid grid-cols-1 gap-2.5 sm:grid-cols-2", children: welcomeSuggestions.map((s, i) => /* @__PURE__ */ jsx(SuggestionCard, { suggestion: s, index: i }, i)) })
63722
+ welcomeSuggestions.length > 0 && /* @__PURE__ */ jsx("div", { className: "mt-6 grid grid-cols-1 gap-2.5 sm:grid-cols-2", children: welcomeSuggestions.map((s, i) => /* @__PURE__ */ jsx(SuggestionCard, { suggestion: s, index: i }, s.title)) })
63176
63723
  ] }) }) }) }),
63177
63724
  /* @__PURE__ */ jsx(
63178
63725
  ThreadPrimitiveMessages,
@@ -63185,10 +63732,12 @@ const AthenaChat = ({
63185
63732
  ),
63186
63733
  /* @__PURE__ */ jsxs(ThreadPrimitiveViewportFooter, { className: "aui-thread-viewport-footer sticky bottom-0 mx-auto mt-auto flex w-full max-w-(--thread-max-width) flex-col gap-4 overflow-visible rounded-t-3xl bg-background pb-4 md:pb-6", children: [
63187
63734
  /* @__PURE__ */ jsx(ThreadScrollToBottom, {}),
63188
- /* @__PURE__ */ jsxs(ComposerPrimitiveRoot, { className: "aui-composer-root relative flex w-full flex-col rounded-2xl border border-input bg-background px-1 pt-2 outline-none transition-shadow focus-within:border-ring focus-within:ring-2 focus-within:ring-ring/20", children: [
63735
+ /* @__PURE__ */ jsx(AttachmentProvider, { children: /* @__PURE__ */ jsx(ComposerEditorProvider, { children: /* @__PURE__ */ jsx(ComposerDropZone, { children: /* @__PURE__ */ jsxs(ComposerPrimitiveRoot, { className: "aui-composer-root relative flex w-full flex-col rounded-2xl border border-input bg-background px-1 outline-none transition-shadow focus-within:border-ring focus-within:ring-2 focus-within:ring-ring/20", children: [
63736
+ /* @__PURE__ */ jsx(ComposerQuotePreview, {}),
63737
+ /* @__PURE__ */ jsx(ComposerAttachmentPreview, {}),
63189
63738
  /* @__PURE__ */ jsx(TiptapComposer, { tools }),
63190
63739
  /* @__PURE__ */ jsx(ComposerAction, {})
63191
- ] })
63740
+ ] }) }) }) })
63192
63741
  ] })
63193
63742
  ]
63194
63743
  }
@@ -63199,7 +63748,14 @@ const AthenaChat = ({
63199
63748
  };
63200
63749
  const ThreadLoadingOverlay = () => {
63201
63750
  const remoteId = useAthenaThreadId();
63202
- if (!remoteId) return null;
63751
+ const [timedOut, setTimedOut] = useState(false);
63752
+ useEffect(() => {
63753
+ if (!remoteId) return;
63754
+ setTimedOut(false);
63755
+ const timer = setTimeout(() => setTimedOut(true), 15e3);
63756
+ return () => clearTimeout(timer);
63757
+ }, [remoteId]);
63758
+ if (!remoteId || timedOut) return null;
63203
63759
  return /* @__PURE__ */ jsx(AuiIf, { condition: (s) => s.thread.isEmpty, children: /* @__PURE__ */ jsx("div", { className: "absolute inset-0 z-10 flex items-center justify-center bg-background/80", children: /* @__PURE__ */ jsx("div", { className: "size-5 animate-spin rounded-full border-2 border-muted-foreground border-t-transparent" }) }) });
63204
63760
  };
63205
63761
  const ThreadScrollToBottom = () => /* @__PURE__ */ jsx(ThreadPrimitiveScrollToBottom, { asChild: true, children: /* @__PURE__ */ jsx(
@@ -63211,8 +63767,66 @@ const ThreadScrollToBottom = () => /* @__PURE__ */ jsx(ThreadPrimitiveScrollToBo
63211
63767
  children: /* @__PURE__ */ jsx(ArrowDown, {})
63212
63768
  }
63213
63769
  ) });
63214
- const ComposerAction = () => /* @__PURE__ */ jsxs("div", { className: "aui-composer-action-wrapper relative mx-2 mb-2 flex items-center justify-end", children: [
63215
- /* @__PURE__ */ jsx(AuiIf, { condition: (s) => !s.thread.isRunning, children: /* @__PURE__ */ jsx(ComposerPrimitiveSend, { asChild: true, children: /* @__PURE__ */ jsx(
63770
+ const ComposerAction = () => /* @__PURE__ */ jsxs("div", { className: "aui-composer-action-wrapper relative mx-2 mb-2 flex items-center justify-between", children: [
63771
+ /* @__PURE__ */ jsx("div", { className: "flex items-center gap-1", children: /* @__PURE__ */ jsx(FileUploadButton, {}) }),
63772
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center", children: [
63773
+ /* @__PURE__ */ jsx(AuiIf, { condition: (s) => !s.thread.isRunning, children: /* @__PURE__ */ jsx(ComposerSendWithQuote, {}) }),
63774
+ /* @__PURE__ */ jsx(AuiIf, { condition: (s) => s.thread.isRunning, children: /* @__PURE__ */ jsx(ComposerPrimitiveCancel, { asChild: true, children: /* @__PURE__ */ jsx(
63775
+ Button,
63776
+ {
63777
+ type: "button",
63778
+ variant: "default",
63779
+ size: "icon",
63780
+ className: "aui-composer-cancel size-8 rounded-full",
63781
+ "aria-label": "Stop generating",
63782
+ children: /* @__PURE__ */ jsx(Square, { className: "aui-composer-cancel-icon size-3 fill-current" })
63783
+ }
63784
+ ) }) })
63785
+ ] })
63786
+ ] });
63787
+ const ComposerSendWithQuote = () => {
63788
+ const aui = useAui();
63789
+ const { quote, clearQuote } = useQuote();
63790
+ const { attachments, clearAttachments, isUploading } = useAttachments();
63791
+ const editorRef = useComposerEditorRef();
63792
+ const hasExtras = !!quote || attachments.length > 0;
63793
+ const handleSend = useCallback(() => {
63794
+ var _a2;
63795
+ if (isUploading) return;
63796
+ const editor = editorRef.current;
63797
+ const userText = ((_a2 = editor == null ? void 0 : editor.getMarkdown()) == null ? void 0 : _a2.trim()) ?? "";
63798
+ const fullMessage = buildComposedMessage({
63799
+ attachments,
63800
+ quote,
63801
+ userText
63802
+ });
63803
+ if (!fullMessage) return;
63804
+ aui.thread().append({
63805
+ role: "user",
63806
+ content: [{ type: "text", text: fullMessage }]
63807
+ });
63808
+ editor == null ? void 0 : editor.clear();
63809
+ clearQuote();
63810
+ clearAttachments();
63811
+ }, [aui, quote, attachments, isUploading, clearQuote, clearAttachments, editorRef]);
63812
+ if (hasExtras) {
63813
+ return /* @__PURE__ */ jsx(
63814
+ TooltipIconButton,
63815
+ {
63816
+ tooltip: isUploading ? "Upload in progress..." : "Send message",
63817
+ side: "bottom",
63818
+ type: "button",
63819
+ variant: "default",
63820
+ size: "icon",
63821
+ className: "aui-composer-send size-8 rounded-full",
63822
+ "aria-label": "Send message",
63823
+ onClick: handleSend,
63824
+ disabled: isUploading,
63825
+ children: /* @__PURE__ */ jsx(ArrowUp, { className: "aui-composer-send-icon size-4" })
63826
+ }
63827
+ );
63828
+ }
63829
+ return /* @__PURE__ */ jsx(ComposerPrimitiveSend, { asChild: true, children: /* @__PURE__ */ jsx(
63216
63830
  TooltipIconButton,
63217
63831
  {
63218
63832
  tooltip: "Send message",
@@ -63224,19 +63838,8 @@ const ComposerAction = () => /* @__PURE__ */ jsxs("div", { className: "aui-compo
63224
63838
  "aria-label": "Send message",
63225
63839
  children: /* @__PURE__ */ jsx(ArrowUp, { className: "aui-composer-send-icon size-4" })
63226
63840
  }
63227
- ) }) }),
63228
- /* @__PURE__ */ jsx(AuiIf, { condition: (s) => s.thread.isRunning, children: /* @__PURE__ */ jsx(ComposerPrimitiveCancel, { asChild: true, children: /* @__PURE__ */ jsx(
63229
- Button,
63230
- {
63231
- type: "button",
63232
- variant: "default",
63233
- size: "icon",
63234
- className: "aui-composer-cancel size-8 rounded-full",
63235
- "aria-label": "Stop generating",
63236
- children: /* @__PURE__ */ jsx(Square, { className: "aui-composer-cancel-icon size-3 fill-current" })
63237
- }
63238
- ) }) })
63239
- ] });
63841
+ ) });
63842
+ };
63240
63843
  const MessageError = () => /* @__PURE__ */ jsx(MessagePrimitiveError, { children: /* @__PURE__ */ jsxs(ErrorPrimitiveRoot, { className: "aui-message-error-root mt-2 flex items-start gap-2 rounded-md border border-destructive bg-destructive/10 p-3 text-destructive text-sm dark:bg-destructive/5 dark:text-red-200", children: [
63241
63844
  /* @__PURE__ */ jsx(CircleAlert, { className: "mt-0.5 size-4 shrink-0" }),
63242
63845
  /* @__PURE__ */ jsx(ErrorPrimitiveMessage, { className: "aui-message-error-message grow" }),
@@ -63757,6 +64360,8 @@ export {
63757
64360
  Collapsible,
63758
64361
  CollapsibleContent,
63759
64362
  CollapsibleTrigger,
64363
+ ComposerDropZone,
64364
+ ComposerQuotePreview,
63760
64365
  CreateDocumentToolUI,
63761
64366
  CreateEmailDraftToolUI,
63762
64367
  CreateNotebookToolUI,
@@ -63764,6 +64369,8 @@ export {
63764
64369
  CreateSheetToolUI,
63765
64370
  DEFAULT_BACKEND_URL,
63766
64371
  EmailSearchToolUI,
64372
+ ExpandableSection,
64373
+ FileUploadButton,
63767
64374
  OpenAssetToolUI,
63768
64375
  ReadAssetToolUI,
63769
64376
  RunPythonCodeToolUI,
@@ -63771,6 +64378,7 @@ export {
63771
64378
  ThreadList,
63772
64379
  TiptapComposer,
63773
64380
  TiptapText,
64381
+ ToolCard,
63774
64382
  ToolFallback,
63775
64383
  ToolFallbackArgs,
63776
64384
  ToolFallbackContent,
@@ -63789,10 +64397,13 @@ export {
63789
64397
  clearAutoOpenedAssets,
63790
64398
  cn,
63791
64399
  createAssetToolUI,
64400
+ formatToolName,
63792
64401
  getAssetInfo,
64402
+ normalizeResult,
63793
64403
  resetAssetAutoOpen,
63794
64404
  themeToStyleVars,
63795
64405
  themes,
64406
+ truncate,
63796
64407
  tryParseJson$1 as tryParseJson,
63797
64408
  useAppendToComposer,
63798
64409
  useAssetEmbed,
@@ -63800,7 +64411,9 @@ export {
63800
64411
  useAthenaConfig,
63801
64412
  useAthenaRuntime,
63802
64413
  useComposerAttachment,
64414
+ useFileUpload,
63803
64415
  useMentionSuggestions,
63804
- useParentAuth
64416
+ useParentAuth,
64417
+ useQuote
63805
64418
  };
63806
64419
  //# sourceMappingURL=index.js.map