@axiom-lattice/react-sdk 2.0.2 → 2.0.4

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.mjs CHANGED
@@ -71,9 +71,22 @@ function useChat(threadId, options = {}) {
71
71
  }, [options.initialMessages]);
72
72
  const handleStreamEvent = useCallback((chunk) => {
73
73
  chunkMessageMerger.current.push(chunk);
74
+ let todos;
75
+ if (chunk.type === "tool" && chunk.data && typeof chunk.data.content === "string" && chunk.data.content.startsWith("```todo_list")) {
76
+ try {
77
+ const content = chunk.data.content;
78
+ const match = content.match(/```todo_list\s*([\s\S]*?)\s*```/);
79
+ if (match && match[1]) {
80
+ todos = JSON.parse(match[1]);
81
+ }
82
+ } catch (e) {
83
+ console.error("Failed to parse todo list from chunk", e);
84
+ }
85
+ }
74
86
  const updatedMessages = chunkMessageMerger.current.getMessages();
75
87
  setState((prev) => ({
76
88
  ...prev,
89
+ todos: todos || prev.todos,
77
90
  messages: updatedMessages,
78
91
  isLoading: true,
79
92
  streamingMessage: null
@@ -204,14 +217,14 @@ function useChat(threadId, options = {}) {
204
217
  }
205
218
  setState((prev) => ({ ...prev, isLoading: true, error: null }));
206
219
  try {
207
- const fetchedMessages = await client.getMessages({
208
- threadId,
209
- limit
210
- });
220
+ const agentState = await client.getAgentState(threadId);
221
+ const fetchedMessages = await client.getMessages({ threadId });
211
222
  chunkMessageMerger.current.reset();
212
223
  chunkMessageMerger.current.initialMessages(fetchedMessages);
213
224
  setState((prev) => ({
214
225
  ...prev,
226
+ agentState,
227
+ todos: agentState?.values?.todos,
215
228
  messages: chunkMessageMerger.current.getMessages(),
216
229
  isLoading: false
217
230
  }));
@@ -268,6 +281,12 @@ function useChat(threadId, options = {}) {
268
281
  streamingMessage: null
269
282
  }));
270
283
  }, []);
284
+ const clearError = useCallback(() => {
285
+ setState((prev) => ({
286
+ ...prev,
287
+ error: null
288
+ }));
289
+ }, []);
271
290
  useEffect(() => {
272
291
  if (threadId) {
273
292
  loadMessages();
@@ -286,7 +305,8 @@ function useChat(threadId, options = {}) {
286
305
  sendMessage,
287
306
  stopStreaming,
288
307
  loadMessages,
289
- clearMessages
308
+ clearMessages,
309
+ clearError
290
310
  };
291
311
  }
292
312
 
@@ -1520,7 +1540,9 @@ var IFrameCard = ({ src }) => {
1520
1540
  // src/components/Chat/Chating.tsx
1521
1541
  import {
1522
1542
  CloudUploadOutlined,
1523
- PaperClipOutlined
1543
+ PaperClipOutlined,
1544
+ FileTextOutlined as FileTextOutlined2,
1545
+ CheckSquareOutlined
1524
1546
  } from "@ant-design/icons";
1525
1547
  import {
1526
1548
  Attachments,
@@ -1530,33 +1552,227 @@ import {
1530
1552
  Welcome
1531
1553
  } from "@ant-design/x";
1532
1554
  import {
1555
+ Alert as Alert2,
1533
1556
  Avatar,
1534
1557
  Badge,
1535
1558
  Button as Button3,
1536
1559
  Flex as Flex3,
1537
1560
  Space as Space6,
1538
- message
1561
+ message,
1562
+ Modal,
1563
+ Tooltip,
1564
+ Popover
1539
1565
  } from "antd";
1540
1566
  import ErrorBoundary from "antd/es/alert/ErrorBoundary";
1541
- import React2, {
1567
+ import React3, {
1542
1568
  memo,
1543
1569
  useCallback as useCallback5,
1544
- useEffect as useEffect5,
1545
- useMemo as useMemo3,
1570
+ useEffect as useEffect6,
1571
+ useMemo as useMemo4,
1546
1572
  useRef as useRef5,
1547
- useState as useState8
1573
+ useState as useState9
1548
1574
  } from "react";
1549
1575
  import { useTranslation } from "react-i18next";
1550
- import { Fragment, jsx as jsx10, jsxs as jsxs6 } from "react/jsx-runtime";
1576
+
1577
+ // src/components/FileExplorer.tsx
1578
+ import { useState as useState8, useEffect as useEffect5, useMemo as useMemo3 } from "react";
1579
+ import { Tabs, Empty } from "antd";
1580
+ import {
1581
+ FileOutlined,
1582
+ FileTextOutlined,
1583
+ FileMarkdownOutlined,
1584
+ FileImageOutlined,
1585
+ CodeOutlined as CodeOutlined2,
1586
+ Html5Outlined,
1587
+ FileUnknownOutlined
1588
+ } from "@ant-design/icons";
1589
+ import { createStyles as createStyles5 } from "antd-style";
1590
+ import { jsx as jsx10, jsxs as jsxs6 } from "react/jsx-runtime";
1591
+ var useStyles2 = createStyles5(({ token, css }) => ({
1592
+ container: css`
1593
+ height: 100%;
1594
+ background: ${token.colorBgContainer};
1595
+ border: 1px solid ${token.colorBorder};
1596
+ border-radius: ${token.borderRadiusLG}px;
1597
+ overflow: hidden;
1598
+ display: flex;
1599
+ flex-direction: column;
1600
+ `,
1601
+ tabs: css`
1602
+ height: 100%;
1603
+
1604
+ .ant-tabs-nav {
1605
+ margin-bottom: 0 !important;
1606
+ padding: 0 16px;
1607
+ border-bottom: 1px solid ${token.colorBorderSecondary};
1608
+ }
1609
+
1610
+ .ant-tabs-content-holder {
1611
+ height: 100%;
1612
+ overflow: hidden;
1613
+ }
1614
+
1615
+ .ant-tabs-content {
1616
+ height: 100%;
1617
+ }
1618
+
1619
+ .ant-tabs-tabpane {
1620
+ height: 100%;
1621
+ outline: none;
1622
+ }
1623
+ `,
1624
+ contentBody: css`
1625
+ padding: 24px;
1626
+ height: 100%;
1627
+ overflow-y: auto;
1628
+
1629
+ pre {
1630
+ margin: 0 !important;
1631
+ border-radius: ${token.borderRadius}px !important;
1632
+ }
1633
+ `,
1634
+ emptyState: css`
1635
+ display: flex;
1636
+ flex-direction: column;
1637
+ align-items: center;
1638
+ justify-content: center;
1639
+ height: 100%;
1640
+ color: ${token.colorTextQuaternary};
1641
+ `
1642
+ }));
1643
+ var getFileIcon = (filename) => {
1644
+ const ext = filename.split(".").pop()?.toLowerCase();
1645
+ switch (ext) {
1646
+ case "ts":
1647
+ case "tsx":
1648
+ case "js":
1649
+ case "jsx":
1650
+ return /* @__PURE__ */ jsx10(CodeOutlined2, {});
1651
+ case "html":
1652
+ return /* @__PURE__ */ jsx10(Html5Outlined, {});
1653
+ case "css":
1654
+ case "less":
1655
+ case "scss":
1656
+ return /* @__PURE__ */ jsx10(FileUnknownOutlined, {});
1657
+ // Or a style icon if available
1658
+ case "md":
1659
+ return /* @__PURE__ */ jsx10(FileMarkdownOutlined, {});
1660
+ case "json":
1661
+ return /* @__PURE__ */ jsx10(FileTextOutlined, {});
1662
+ case "png":
1663
+ case "jpg":
1664
+ case "jpeg":
1665
+ case "gif":
1666
+ case "svg":
1667
+ return /* @__PURE__ */ jsx10(FileImageOutlined, {});
1668
+ default:
1669
+ return /* @__PURE__ */ jsx10(FileOutlined, {});
1670
+ }
1671
+ };
1672
+ function getLanguageFromFileName(filename) {
1673
+ const ext = filename.split(".").pop()?.toLowerCase();
1674
+ switch (ext) {
1675
+ case "ts":
1676
+ case "tsx":
1677
+ return "typescript";
1678
+ case "js":
1679
+ case "jsx":
1680
+ return "javascript";
1681
+ case "py":
1682
+ return "python";
1683
+ case "md":
1684
+ return "markdown";
1685
+ case "json":
1686
+ return "json";
1687
+ case "html":
1688
+ return "html";
1689
+ case "css":
1690
+ return "css";
1691
+ case "java":
1692
+ return "java";
1693
+ case "go":
1694
+ return "go";
1695
+ case "rs":
1696
+ return "rust";
1697
+ case "c":
1698
+ return "c";
1699
+ case "cpp":
1700
+ return "cpp";
1701
+ case "yaml":
1702
+ case "yml":
1703
+ return "yaml";
1704
+ case "sql":
1705
+ return "sql";
1706
+ case "sh":
1707
+ case "bash":
1708
+ return "bash";
1709
+ default:
1710
+ return "text";
1711
+ }
1712
+ }
1713
+ var FileExplorer = ({
1714
+ files = [],
1715
+ className,
1716
+ style,
1717
+ title = "EXPLORER"
1718
+ }) => {
1719
+ const { styles, cx } = useStyles2();
1720
+ const [fileList, setFileList] = useState8([]);
1721
+ useEffect5(() => {
1722
+ if (Array.isArray(files)) {
1723
+ setFileList(files);
1724
+ } else {
1725
+ const list = Object.keys(files).map((key) => ({
1726
+ name: key,
1727
+ content: files[key]
1728
+ }));
1729
+ setFileList(list);
1730
+ }
1731
+ }, [files]);
1732
+ const items = useMemo3(() => {
1733
+ return fileList.map((file) => {
1734
+ const language = file.language || getLanguageFromFileName(file.name);
1735
+ const content = `\`\`\`${language}
1736
+ ${file.content}
1737
+ \`\`\``;
1738
+ return {
1739
+ key: file.name,
1740
+ label: /* @__PURE__ */ jsxs6("span", { style: { display: "flex", alignItems: "center", gap: 8 }, children: [
1741
+ getFileIcon(file.name),
1742
+ file.name
1743
+ ] }),
1744
+ children: /* @__PURE__ */ jsx10("div", { className: styles.contentBody, children: /* @__PURE__ */ jsx10(MDResponse, { content }) })
1745
+ };
1746
+ });
1747
+ }, [fileList, styles]);
1748
+ return /* @__PURE__ */ jsx10("div", { className: cx(styles.container, className), style, children: fileList.length > 0 ? /* @__PURE__ */ jsx10(
1749
+ Tabs,
1750
+ {
1751
+ defaultActiveKey: fileList[0]?.name,
1752
+ items,
1753
+ className: styles.tabs,
1754
+ tabBarStyle: { margin: 0 }
1755
+ }
1756
+ ) : /* @__PURE__ */ jsx10("div", { className: styles.emptyState, children: /* @__PURE__ */ jsx10(
1757
+ Empty,
1758
+ {
1759
+ description: "No file selected",
1760
+ image: Empty.PRESENTED_IMAGE_SIMPLE
1761
+ }
1762
+ ) }) });
1763
+ };
1764
+
1765
+ // src/components/Chat/Chating.tsx
1766
+ import { Fragment, jsx as jsx11, jsxs as jsxs7 } from "react/jsx-runtime";
1551
1767
  var LazyBubble = ({
1552
1768
  message: message2,
1553
1769
  renderContent,
1554
1770
  autoLoadRightPanel
1555
1771
  }) => {
1556
1772
  const ref = useRef5(null);
1557
- const [isVisible, setIsVisible] = useState8(false);
1558
- const [wasEverVisible, setWasEverVisible] = useState8(false);
1559
- useEffect5(() => {
1773
+ const [isVisible, setIsVisible] = useState9(false);
1774
+ const [wasEverVisible, setWasEverVisible] = useState9(false);
1775
+ useEffect6(() => {
1560
1776
  const observer = new IntersectionObserver(
1561
1777
  ([entry]) => {
1562
1778
  const visible = entry.isIntersecting;
@@ -1576,21 +1792,21 @@ var LazyBubble = ({
1576
1792
  }
1577
1793
  };
1578
1794
  }, [wasEverVisible]);
1579
- useEffect5(() => {
1795
+ useEffect6(() => {
1580
1796
  autoLoadRightPanel?.();
1581
1797
  }, []);
1582
1798
  const getPlaceholder = () => {
1583
1799
  const estimatedHeight = message2.content ? Math.min(100, message2.content.length / 5) : 100;
1584
- return /* @__PURE__ */ jsx10("div", { style: { height: `${estimatedHeight}px`, minHeight: "50px" } });
1800
+ return /* @__PURE__ */ jsx11("div", { style: { height: `${estimatedHeight}px`, minHeight: "50px" } });
1585
1801
  };
1586
- return /* @__PURE__ */ jsx10(ErrorBoundary, { children: /* @__PURE__ */ jsx10("div", { ref, style: { width: "100%" }, children: isVisible || wasEverVisible ? renderContent(message2) : getPlaceholder() }) });
1802
+ return /* @__PURE__ */ jsx11(ErrorBoundary, { children: /* @__PURE__ */ jsx11("div", { ref, style: { width: "100%" }, children: isVisible || wasEverVisible ? renderContent(message2) : getPlaceholder() }) });
1587
1803
  };
1588
1804
  var MemoizedBubbleList = memo(
1589
1805
  ({
1590
1806
  items,
1591
1807
  roles,
1592
1808
  className
1593
- }) => /* @__PURE__ */ jsx10(
1809
+ }) => /* @__PURE__ */ jsx11(
1594
1810
  Bubble.List,
1595
1811
  {
1596
1812
  autoScroll: true,
@@ -1610,10 +1826,12 @@ var Chating = ({
1610
1826
  tenant_id,
1611
1827
  messages,
1612
1828
  isLoading,
1829
+ error,
1613
1830
  sendMessage,
1614
1831
  stopStreaming,
1615
1832
  onOpenSidePanel,
1616
1833
  onReminderClick,
1834
+ onClearError,
1617
1835
  styles,
1618
1836
  reminderCount,
1619
1837
  handleMDResponseEvent,
@@ -1621,15 +1839,18 @@ var Chating = ({
1621
1839
  extra,
1622
1840
  attachment_placeholder,
1623
1841
  extraMeta = [],
1624
- uploadAction = "/api/file_storage/upload?path=temp"
1842
+ uploadAction = "/api/file_storage/upload?path=temp",
1843
+ files,
1844
+ todos
1625
1845
  }) => {
1626
1846
  const { t } = useTranslation();
1627
- const [content, setContent] = useState8("");
1628
- const [attachedFiles, setAttachedFiles] = useState8([]);
1629
- const [headerOpen, setHeaderOpen] = useState8(false);
1847
+ const [content, setContent] = useState9("");
1848
+ const [attachedFiles, setAttachedFiles] = useState9([]);
1849
+ const [headerOpen, setHeaderOpen] = useState9(false);
1850
+ const [fileExplorerVisible, setFileExplorerVisible] = useState9(false);
1630
1851
  const attachmentsRef = useRef5(null);
1631
- const senderRef = React2.useRef(null);
1632
- useEffect5(() => {
1852
+ const senderRef = React3.useRef(null);
1853
+ useEffect6(() => {
1633
1854
  regsiterElement("action_show_attachments_uploader", {
1634
1855
  card_view: () => null,
1635
1856
  action: (data) => {
@@ -1639,18 +1860,18 @@ var Chating = ({
1639
1860
  });
1640
1861
  }, []);
1641
1862
  const messageLengthRef = useRef5(messages?.length ?? 0);
1642
- useEffect5(() => {
1863
+ useEffect6(() => {
1643
1864
  if (messages?.length) {
1644
1865
  messageLengthRef.current = messages?.length;
1645
1866
  }
1646
1867
  }, [messages?.length]);
1647
1868
  const renderContent = useCallback5(
1648
1869
  (message2) => {
1649
- const { content: content2, files, id } = message2;
1870
+ const { content: content2, files: files2, id } = message2;
1650
1871
  try {
1651
1872
  const json = JSON.parse(content2);
1652
1873
  if (json.action && json.message) {
1653
- return /* @__PURE__ */ jsx10(
1874
+ return /* @__PURE__ */ jsx11(
1654
1875
  MDResponse,
1655
1876
  {
1656
1877
  content: json.message,
@@ -1658,7 +1879,7 @@ var Chating = ({
1658
1879
  }
1659
1880
  );
1660
1881
  }
1661
- } catch (error) {
1882
+ } catch (error2) {
1662
1883
  }
1663
1884
  const tool_calls_md = message2.tool_calls?.map((tool_call) => {
1664
1885
  return `\`\`\`tool_call
@@ -1666,7 +1887,7 @@ ${JSON.stringify(tool_call)}
1666
1887
  \`\`\``;
1667
1888
  }) || [];
1668
1889
  const content_md = [content2, ...tool_calls_md].join("\n");
1669
- return /* @__PURE__ */ jsx10(Space6, { direction: "vertical", style: { width: "100%" }, children: /* @__PURE__ */ jsx10(
1890
+ return /* @__PURE__ */ jsx11(Space6, { direction: "vertical", style: { width: "100%" }, children: /* @__PURE__ */ jsx11(
1670
1891
  MDResponse,
1671
1892
  {
1672
1893
  content: content_md,
@@ -1676,12 +1897,12 @@ ${JSON.stringify(tool_call)}
1676
1897
  },
1677
1898
  [handleMDResponseEvent]
1678
1899
  );
1679
- const items = useMemo3(
1900
+ const items = useMemo4(
1680
1901
  () => messages.map((message2, index) => ({
1681
1902
  key: message2.id,
1682
1903
  role: message2.role,
1683
1904
  typing: false,
1684
- content: /* @__PURE__ */ jsx10(
1905
+ content: /* @__PURE__ */ jsx11(
1685
1906
  LazyBubble,
1686
1907
  {
1687
1908
  message: message2,
@@ -1708,8 +1929,8 @@ ${JSON.stringify(tool_call)}
1708
1929
  element.action(jsonData);
1709
1930
  }
1710
1931
  }
1711
- } catch (error) {
1712
- console.error(error);
1932
+ } catch (error2) {
1933
+ console.error(error2);
1713
1934
  }
1714
1935
  }
1715
1936
  }
@@ -1737,7 +1958,7 @@ ${JSON.stringify(tool_call)}
1737
1958
  if (!nextContent && attachedFiles.length > 0) {
1738
1959
  nextContent = default_submit_message || "\u8BB0\u8D26";
1739
1960
  }
1740
- const files = attachedFiles.map(
1961
+ const files2 = attachedFiles.map(
1741
1962
  (file) => isArchiveFile(file) ? {
1742
1963
  name: file.response.zipFileName || file.response.rarFileName,
1743
1964
  id: file.response.zipFileId || file.response.rarFileId,
@@ -1755,14 +1976,14 @@ ${JSON.stringify(tool_call)}
1755
1976
  id: file.response.id
1756
1977
  }
1757
1978
  );
1758
- const files_md = files.length > 0 ? [
1979
+ const files_md = files2.length > 0 ? [
1759
1980
  "",
1760
1981
  "\u6211\u5DF2\u7ECF\u63D0\u4EA4\u4E86\u4EE5\u4E0B\u6587\u4EF6\uFF1A",
1761
1982
  "```attachments",
1762
- JSON.stringify(files),
1983
+ JSON.stringify(files2),
1763
1984
  "```"
1764
1985
  ].join("\n") : "";
1765
- sendMessage({ input: { message: nextContent + files_md, files } });
1986
+ sendMessage({ input: { message: nextContent + files_md, files: files2 } });
1766
1987
  setContent("");
1767
1988
  setAttachedFiles([]);
1768
1989
  setHeaderOpen(false);
@@ -1794,15 +2015,15 @@ ${JSON.stringify(tool_call)}
1794
2015
  }
1795
2016
  return true;
1796
2017
  };
1797
- const attachmentsNode = /* @__PURE__ */ jsx10(Badge, { dot: attachedFiles.length > 0 && !headerOpen, children: /* @__PURE__ */ jsx10(
2018
+ const attachmentsNode = /* @__PURE__ */ jsx11(Badge, { dot: attachedFiles.length > 0 && !headerOpen, children: /* @__PURE__ */ jsx11(
1798
2019
  Button3,
1799
2020
  {
1800
2021
  type: "text",
1801
- icon: /* @__PURE__ */ jsx10(PaperClipOutlined, {}),
2022
+ icon: /* @__PURE__ */ jsx11(PaperClipOutlined, {}),
1802
2023
  onClick: () => setHeaderOpen(!headerOpen)
1803
2024
  }
1804
2025
  ) });
1805
- const senderHeader = /* @__PURE__ */ jsx10(
2026
+ const senderHeader = /* @__PURE__ */ jsx11(
1806
2027
  Sender.Header,
1807
2028
  {
1808
2029
  title: "Attachments",
@@ -1814,7 +2035,7 @@ ${JSON.stringify(tool_call)}
1814
2035
  }
1815
2036
  },
1816
2037
  forceRender: true,
1817
- children: /* @__PURE__ */ jsx10(
2038
+ children: /* @__PURE__ */ jsx11(
1818
2039
  Attachments,
1819
2040
  {
1820
2041
  ref: attachmentsRef,
@@ -1836,7 +2057,7 @@ ${JSON.stringify(tool_call)}
1836
2057
  multiple: true,
1837
2058
  maxCount: 10,
1838
2059
  placeholder: (type) => ({
1839
- icon: /* @__PURE__ */ jsx10(CloudUploadOutlined, {}),
2060
+ icon: /* @__PURE__ */ jsx11(CloudUploadOutlined, {}),
1840
2061
  title: "\u4E0A\u4F20\u6587\u4EF6",
1841
2062
  description: attachment_placeholder
1842
2063
  })
@@ -1868,16 +2089,16 @@ ${JSON.stringify(tool_call)}
1868
2089
  }
1869
2090
  }
1870
2091
  };
1871
- const extraMetaComponents = useMemo3(() => {
2092
+ const extraMetaComponents = useMemo4(() => {
1872
2093
  if (extraMeta?.length > 0) {
1873
2094
  return extraMeta.map((meta) => {
1874
2095
  const Element = getElement(meta.id)?.card_view;
1875
2096
  if (Element) {
1876
2097
  let childrenData;
1877
2098
  try {
1878
- } catch (error) {
2099
+ } catch (error2) {
1879
2100
  }
1880
- return /* @__PURE__ */ jsx10(
2101
+ return /* @__PURE__ */ jsx11(
1881
2102
  Element,
1882
2103
  {
1883
2104
  component_key: meta.id,
@@ -1893,20 +2114,63 @@ ${JSON.stringify(tool_call)}
1893
2114
  }
1894
2115
  return void 0;
1895
2116
  }, [extraMeta]);
1896
- return /* @__PURE__ */ jsxs6(Fragment, { children: [
1897
- /* @__PURE__ */ jsxs6("div", { children: [
1898
- /* @__PURE__ */ jsx10(
2117
+ return /* @__PURE__ */ jsxs7(Fragment, { children: [
2118
+ /* @__PURE__ */ jsxs7("div", { children: [
2119
+ /* @__PURE__ */ jsx11(
1899
2120
  Welcome,
1900
2121
  {
1901
2122
  style: { padding: 8 },
1902
2123
  variant: "borderless",
1903
2124
  description,
1904
- icon: /* @__PURE__ */ jsx10(Avatar, { src: avatar || "/images/avatar.jpeg", size: 48 }),
2125
+ icon: /* @__PURE__ */ jsx11(Avatar, { src: avatar || "/images/avatar.jpeg", size: 48 }),
1905
2126
  title: name || "Fina",
1906
- extra: extra || extraMetaComponents && /* @__PURE__ */ jsx10(Space6, { align: "center", style: { marginRight: 16 }, children: extraMetaComponents })
2127
+ extra: /* @__PURE__ */ jsxs7(Space6, { children: [
2128
+ extra,
2129
+ todos && todos.length > 0 && /* @__PURE__ */ jsx11(
2130
+ Popover,
2131
+ {
2132
+ content: /* @__PURE__ */ jsx11("div", { style: { width: 400 }, children: /* @__PURE__ */ jsx11(
2133
+ Todo,
2134
+ {
2135
+ data: todos,
2136
+ component_key: "header_todos",
2137
+ eventHandler: handleMDResponseEvent
2138
+ }
2139
+ ) }),
2140
+ title: "Todos",
2141
+ trigger: "click",
2142
+ placement: "bottomRight",
2143
+ children: /* @__PURE__ */ jsx11(Tooltip, { title: "Todos", children: /* @__PURE__ */ jsx11(
2144
+ Badge,
2145
+ {
2146
+ count: todos.filter((item) => item.status !== "completed").length,
2147
+ size: "small",
2148
+ children: /* @__PURE__ */ jsx11(Button3, { icon: /* @__PURE__ */ jsx11(CheckSquareOutlined, {}), type: "text" })
2149
+ }
2150
+ ) })
2151
+ }
2152
+ ),
2153
+ files && Object.keys(files).length > 0 && /* @__PURE__ */ jsx11(Tooltip, { title: "File Explorer", children: /* @__PURE__ */ jsx11(
2154
+ Badge,
2155
+ {
2156
+ count: Object.keys(files).length,
2157
+ size: "small",
2158
+ color: "blue",
2159
+ children: /* @__PURE__ */ jsx11(
2160
+ Button3,
2161
+ {
2162
+ type: "text",
2163
+ icon: /* @__PURE__ */ jsx11(FileTextOutlined2, {}),
2164
+ onClick: () => setFileExplorerVisible(true)
2165
+ }
2166
+ )
2167
+ }
2168
+ ) }),
2169
+ extraMetaComponents && /* @__PURE__ */ jsx11(Space6, { align: "center", style: { marginRight: 16 }, children: extraMetaComponents })
2170
+ ] })
1907
2171
  }
1908
2172
  ),
1909
- /* @__PURE__ */ jsx10(
2173
+ /* @__PURE__ */ jsx11(
1910
2174
  "div",
1911
2175
  {
1912
2176
  style: {
@@ -1915,16 +2179,45 @@ ${JSON.stringify(tool_call)}
1915
2179
  }
1916
2180
  )
1917
2181
  ] }),
1918
- items.length > 0 ? /* @__PURE__ */ jsx10(
2182
+ /* @__PURE__ */ jsx11(
2183
+ Modal,
2184
+ {
2185
+ title: "File Explorer",
2186
+ open: fileExplorerVisible,
2187
+ onCancel: () => setFileExplorerVisible(false),
2188
+ footer: null,
2189
+ width: 1e3,
2190
+ destroyOnClose: true,
2191
+ styles: { body: { height: "70vh", padding: 0 } },
2192
+ children: /* @__PURE__ */ jsx11(
2193
+ FileExplorer,
2194
+ {
2195
+ files,
2196
+ style: { height: "100%", border: "none" }
2197
+ }
2198
+ )
2199
+ }
2200
+ ),
2201
+ items.length > 0 ? /* @__PURE__ */ jsx11(
1919
2202
  MemoizedBubbleList,
1920
2203
  {
1921
2204
  items,
1922
2205
  roles,
1923
2206
  className: styles.messages
1924
2207
  }
1925
- ) : /* @__PURE__ */ jsx10("div", { style: { flex: 1 } }),
1926
- isLoading ? /* @__PURE__ */ jsx10("div", { children: /* @__PURE__ */ jsx10(Bubble, { loading: isLoading, variant: "borderless" }) }) : /* @__PURE__ */ jsx10(Prompts, { items: senderPromptsItems, onItemClick: onPromptsItemClick }),
1927
- /* @__PURE__ */ jsx10(
2208
+ ) : /* @__PURE__ */ jsx11("div", { style: { flex: 1 } }),
2209
+ isLoading ? /* @__PURE__ */ jsx11("div", { children: /* @__PURE__ */ jsx11(Bubble, { loading: isLoading, variant: "borderless" }) }) : /* @__PURE__ */ jsx11(Prompts, { items: senderPromptsItems, onItemClick: onPromptsItemClick }),
2210
+ error && /* @__PURE__ */ jsx11("div", { style: { padding: "0 16px 8px" }, children: /* @__PURE__ */ jsx11(
2211
+ Alert2,
2212
+ {
2213
+ type: "error",
2214
+ banner: true,
2215
+ closable: true,
2216
+ onClose: () => onClearError?.(),
2217
+ message: `${error.message}`
2218
+ }
2219
+ ) }),
2220
+ /* @__PURE__ */ jsx11(
1928
2221
  Sender,
1929
2222
  {
1930
2223
  allowSpeech: true,
@@ -1939,7 +2232,7 @@ ${JSON.stringify(tool_call)}
1939
2232
  className: styles.sender,
1940
2233
  actions: (ori, { components }) => {
1941
2234
  const { SendButton, LoadingButton } = components;
1942
- return /* @__PURE__ */ jsx10(Flex3, { justify: "space-between", align: "center", children: isLoading ? /* @__PURE__ */ jsx10(LoadingButton, { type: "default" }) : /* @__PURE__ */ jsx10(
2235
+ return /* @__PURE__ */ jsx11(Flex3, { justify: "space-between", align: "center", children: isLoading ? /* @__PURE__ */ jsx11(LoadingButton, { type: "default" }) : /* @__PURE__ */ jsx11(
1943
2236
  SendButton,
1944
2237
  {
1945
2238
  type: "primary",
@@ -1948,8 +2241,8 @@ ${JSON.stringify(tool_call)}
1948
2241
  }
1949
2242
  ) });
1950
2243
  },
1951
- onPasteFile: (_, files) => {
1952
- Array.from(files).forEach((file) => {
2244
+ onPasteFile: (_, files2) => {
2245
+ Array.from(files2).forEach((file) => {
1953
2246
  attachmentsRef.current?.upload(file);
1954
2247
  });
1955
2248
  setHeaderOpen(true);
@@ -1968,17 +2261,17 @@ import {
1968
2261
  import {
1969
2262
  ThoughtChain
1970
2263
  } from "@ant-design/x";
1971
- import { jsx as jsx11 } from "react/jsx-runtime";
2264
+ import { jsx as jsx12 } from "react/jsx-runtime";
1972
2265
  function getStatusIcon2(status) {
1973
2266
  switch (status) {
1974
2267
  case "success":
1975
- return /* @__PURE__ */ jsx11(CheckCircleOutlined3, {});
2268
+ return /* @__PURE__ */ jsx12(CheckCircleOutlined3, {});
1976
2269
  case "error":
1977
- return /* @__PURE__ */ jsx11(InfoCircleOutlined2, {});
2270
+ return /* @__PURE__ */ jsx12(InfoCircleOutlined2, {});
1978
2271
  case "pending":
1979
- return /* @__PURE__ */ jsx11(LoadingOutlined3, {});
2272
+ return /* @__PURE__ */ jsx12(LoadingOutlined3, {});
1980
2273
  default:
1981
- return /* @__PURE__ */ jsx11(CheckCircleOutlined3, {});
2274
+ return /* @__PURE__ */ jsx12(CheckCircleOutlined3, {});
1982
2275
  }
1983
2276
  }
1984
2277
  var ThinkingChain = ({ message: message2 }) => {
@@ -1987,12 +2280,12 @@ var ThinkingChain = ({ message: message2 }) => {
1987
2280
  {
1988
2281
  key: message2.id,
1989
2282
  title,
1990
- content: /* @__PURE__ */ jsx11(MDResponse, { content: message2.content }),
2283
+ content: /* @__PURE__ */ jsx12(MDResponse, { content: message2.content }),
1991
2284
  status: message2.status,
1992
2285
  icon: getStatusIcon2(message2.status)
1993
2286
  }
1994
2287
  ];
1995
- return /* @__PURE__ */ jsx11(
2288
+ return /* @__PURE__ */ jsx12(
1996
2289
  ThoughtChain,
1997
2290
  {
1998
2291
  items,
@@ -2006,11 +2299,11 @@ var ThinkingChainGroup = ({ message: message2 }) => {
2006
2299
  const children = message2.items?.map((item) => ({
2007
2300
  key: item.id,
2008
2301
  title: item.name || item.content.split("\n")[0],
2009
- content: /* @__PURE__ */ jsx11(MDResponse, { content: item.content }),
2302
+ content: /* @__PURE__ */ jsx12(MDResponse, { content: item.content }),
2010
2303
  status: item.status,
2011
2304
  icon: getStatusIcon2(item.status)
2012
2305
  }));
2013
- return /* @__PURE__ */ jsx11(ThoughtChain, { items: children, collapsible: true, size: "small" });
2306
+ return /* @__PURE__ */ jsx12(ThoughtChain, { items: children, collapsible: true, size: "small" });
2014
2307
  };
2015
2308
 
2016
2309
  // src/components/Chat/SideAppViewBrowser.tsx
@@ -2020,11 +2313,11 @@ import {
2020
2313
  ExpandOutlined,
2021
2314
  FullscreenOutlined
2022
2315
  } from "@ant-design/icons";
2023
- import { Button as Button4, Tabs } from "antd";
2024
- import { createStyles as createStyles5 } from "antd-style";
2025
- import { useEffect as useEffect6, useState as useState9 } from "react";
2026
- import { jsx as jsx12, jsxs as jsxs7 } from "react/jsx-runtime";
2027
- var useStyle4 = createStyles5(({ token, css }) => {
2316
+ import { Button as Button4, Tabs as Tabs2 } from "antd";
2317
+ import { createStyles as createStyles6 } from "antd-style";
2318
+ import { useEffect as useEffect7, useState as useState10 } from "react";
2319
+ import { jsx as jsx13, jsxs as jsxs8 } from "react/jsx-runtime";
2320
+ var useStyle4 = createStyles6(({ token, css }) => {
2028
2321
  return {
2029
2322
  tabContainer: css`
2030
2323
  .ant-tabs-content-holder {
@@ -2043,9 +2336,9 @@ var useStyle4 = createStyles5(({ token, css }) => {
2043
2336
  };
2044
2337
  });
2045
2338
  var EmptySideAppView = ({ component_key, data }) => {
2046
- return /* @__PURE__ */ jsxs7("div", { children: [
2047
- /* @__PURE__ */ jsx12("p", { children: "\u672A\u627E\u5230\u5BF9\u5E94\u7684\u7EC4\u4EF6\u89C6\u56FE" }),
2048
- /* @__PURE__ */ jsx12("pre", { children: JSON.stringify({ component_key, data }, null, 2) })
2339
+ return /* @__PURE__ */ jsxs8("div", { children: [
2340
+ /* @__PURE__ */ jsx13("p", { children: "\u672A\u627E\u5230\u5BF9\u5E94\u7684\u7EC4\u4EF6\u89C6\u56FE" }),
2341
+ /* @__PURE__ */ jsx13("pre", { children: JSON.stringify({ component_key, data }, null, 2) })
2049
2342
  ] });
2050
2343
  };
2051
2344
  var SideAppViewBrowser = ({
@@ -2055,9 +2348,9 @@ var SideAppViewBrowser = ({
2055
2348
  onChangeSize
2056
2349
  }) => {
2057
2350
  const { styles } = useStyle4();
2058
- const [activeKey, setActiveKey] = useState9(JSON.stringify(open_uri));
2059
- const [currentSize, setCurrentSize] = useState9(open_uri.size || "large");
2060
- const [items, setItems] = useState9([]);
2351
+ const [activeKey, setActiveKey] = useState10(JSON.stringify(open_uri));
2352
+ const [currentSize, setCurrentSize] = useState10(open_uri.size || "large");
2353
+ const [items, setItems] = useState10([]);
2061
2354
  const add = (key, label, children) => {
2062
2355
  const newActiveKey = key;
2063
2356
  const newPanes = [...items];
@@ -2093,7 +2386,7 @@ var SideAppViewBrowser = ({
2093
2386
  remove(targetKey);
2094
2387
  }
2095
2388
  };
2096
- useEffect6(() => {
2389
+ useEffect7(() => {
2097
2390
  const SideAppView = getElement(open_uri.component_key).side_app_view || EmptySideAppView;
2098
2391
  const key = JSON.stringify(open_uri);
2099
2392
  if (items.find((item) => item.key === key)) {
@@ -2103,7 +2396,7 @@ var SideAppViewBrowser = ({
2103
2396
  add(
2104
2397
  key,
2105
2398
  open_uri.message || open_uri.data.message || "\u672A\u547D\u540D",
2106
- /* @__PURE__ */ jsx12(
2399
+ /* @__PURE__ */ jsx13(
2107
2400
  SideAppView,
2108
2401
  {
2109
2402
  component_key: open_uri.component_key,
@@ -2113,7 +2406,7 @@ var SideAppViewBrowser = ({
2113
2406
  )
2114
2407
  );
2115
2408
  }, [open_uri]);
2116
- useEffect6(() => {
2409
+ useEffect7(() => {
2117
2410
  if (open_uri.size && open_uri.size !== currentSize) {
2118
2411
  setCurrentSize(open_uri.size);
2119
2412
  }
@@ -2151,25 +2444,25 @@ var SideAppViewBrowser = ({
2151
2444
  const getSizeIcon = (size) => {
2152
2445
  switch (size) {
2153
2446
  case "middle":
2154
- return /* @__PURE__ */ jsx12(CompressOutlined, {});
2447
+ return /* @__PURE__ */ jsx13(CompressOutlined, {});
2155
2448
  case "large":
2156
- return /* @__PURE__ */ jsx12(ExpandOutlined, {});
2449
+ return /* @__PURE__ */ jsx13(ExpandOutlined, {});
2157
2450
  case "full":
2158
- return /* @__PURE__ */ jsx12(FullscreenOutlined, {});
2451
+ return /* @__PURE__ */ jsx13(FullscreenOutlined, {});
2159
2452
  default:
2160
- return /* @__PURE__ */ jsx12(ExpandOutlined, {});
2453
+ return /* @__PURE__ */ jsx13(ExpandOutlined, {});
2161
2454
  }
2162
2455
  };
2163
- return /* @__PURE__ */ jsx12(
2164
- Tabs,
2456
+ return /* @__PURE__ */ jsx13(
2457
+ Tabs2,
2165
2458
  {
2166
2459
  className: styles.tabContainer,
2167
2460
  type: "editable-card",
2168
2461
  style: { height: "100%" },
2169
2462
  hideAdd: true,
2170
2463
  tabBarExtraContent: {
2171
- right: /* @__PURE__ */ jsxs7("div", { style: { display: "flex", gap: "4px" }, children: [
2172
- /* @__PURE__ */ jsx12(
2464
+ right: /* @__PURE__ */ jsxs8("div", { style: { display: "flex", gap: "4px" }, children: [
2465
+ /* @__PURE__ */ jsx13(
2173
2466
  Button4,
2174
2467
  {
2175
2468
  style: { margin: "8px 0" },
@@ -2180,13 +2473,13 @@ var SideAppViewBrowser = ({
2180
2473
  title: `\u5F53\u524D\u5C3A\u5BF8: ${getSizeLabel(currentSize)}, \u70B9\u51FB\u5207\u6362`
2181
2474
  }
2182
2475
  ),
2183
- /* @__PURE__ */ jsx12(
2476
+ /* @__PURE__ */ jsx13(
2184
2477
  Button4,
2185
2478
  {
2186
2479
  style: { margin: "8px 0" },
2187
2480
  size: "large",
2188
2481
  type: "text",
2189
- icon: /* @__PURE__ */ jsx12(CloseOutlined, {}),
2482
+ icon: /* @__PURE__ */ jsx13(CloseOutlined, {}),
2190
2483
  onClick: () => {
2191
2484
  onClose();
2192
2485
  }
@@ -2211,6 +2504,7 @@ var chatContext = createContext2({
2211
2504
  export {
2212
2505
  AxiomLatticeProvider,
2213
2506
  Chating,
2507
+ FileExplorer,
2214
2508
  MDMermaid,
2215
2509
  MDResponse,
2216
2510
  MDViewFormItem,