@axiom-lattice/react-sdk 2.0.3 → 2.1.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.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
@@ -89,7 +102,7 @@ function useChat(threadId, options = {}) {
89
102
  stopStreamingRef.current = null;
90
103
  }
91
104
  const { input, command, streaming = true } = data;
92
- const { message: message2, files, ...rest } = input || {};
105
+ const { message: message3, files, ...rest } = input || {};
93
106
  setState((prev) => ({
94
107
  ...prev,
95
108
  isLoading: true,
@@ -98,7 +111,7 @@ function useChat(threadId, options = {}) {
98
111
  }));
99
112
  const userMessage = {
100
113
  id: Date.now().toString(),
101
- content: message2 || command?.resume?.message || "",
114
+ content: message3 || command?.resume?.message || "",
102
115
  files,
103
116
  role: "human"
104
117
  };
@@ -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
  }));
@@ -540,8 +553,8 @@ import ReactMarkdown from "react-markdown";
540
553
  import { Prism } from "react-syntax-highlighter";
541
554
  import { dark } from "react-syntax-highlighter/dist/cjs/styles/prism";
542
555
  import remarkGfm from "remark-gfm";
543
- import { useMemo as useMemo2, useRef as useRef4, useState as useState7 } from "react";
544
- import { createStyles as createStyles4 } from "antd-style";
556
+ import { useMemo as useMemo3, useRef as useRef5, useState as useState11 } from "react";
557
+ import { createStyles as createStyles6 } from "antd-style";
545
558
  import rehypeRaw from "rehype-raw";
546
559
 
547
560
  // src/components/GenUI/elements/confirm_feedback.tsx
@@ -565,7 +578,7 @@ var ConfirmFeedback = ({
565
578
  eventHandler,
566
579
  interactive = true
567
580
  }) => {
568
- const { message: message2, type, config, feedback, options } = data ?? {};
581
+ const { message: message3, type, config, feedback, options } = data ?? {};
569
582
  const [clicked, setClicked] = useState5(false);
570
583
  const { styles } = useStyle();
571
584
  return /* @__PURE__ */ jsx2(Card, { size: "small", className: `shadow-sm ${styles.card}`, bordered: false, children: /* @__PURE__ */ jsxs(Space, { direction: "vertical", style: { width: "100%" }, children: [
@@ -584,7 +597,7 @@ var ConfirmFeedback = ({
584
597
  children: "\u8BF7\u6C42\u786E\u8BA4"
585
598
  }
586
599
  ),
587
- /* @__PURE__ */ jsx2(MDResponse, { content: message2 }),
600
+ /* @__PURE__ */ jsx2(MDResponse, { content: message3 }),
588
601
  options ? /* @__PURE__ */ jsx2(Space, { style: { justifyContent: "flex-end", width: "100%" }, children: options?.map((option) => /* @__PURE__ */ jsx2(
589
602
  Button,
590
603
  {
@@ -665,7 +678,7 @@ var GenericDataTable = ({
665
678
  interactive = true,
666
679
  default_open_in_side_app = true
667
680
  }) => {
668
- const { dataSource, message: message2 } = data ?? {};
681
+ const { dataSource, message: message3 } = data ?? {};
669
682
  const [expandedRowKeys, setExpandedRowKeys] = useState6([]);
670
683
  const processedData = dataSource?.map((item, index) => ({
671
684
  ...item,
@@ -747,7 +760,7 @@ var GenericDataTable = ({
747
760
  {
748
761
  size: "small",
749
762
  title: () => /* @__PURE__ */ jsxs2(Flex, { justify: "space-between", align: "center", children: [
750
- /* @__PURE__ */ jsx3(Space2, { children: /* @__PURE__ */ jsx3(Text2, { strong: true, style: { fontSize: 16 }, children: message2 || "" }) }),
763
+ /* @__PURE__ */ jsx3(Space2, { children: /* @__PURE__ */ jsx3(Text2, { strong: true, style: { fontSize: 16 }, children: message3 || "" }) }),
751
764
  /* @__PURE__ */ jsxs2(Space2, { children: [
752
765
  /* @__PURE__ */ jsx3(
753
766
  Button2,
@@ -770,8 +783,8 @@ var GenericDataTable = ({
770
783
  "__open_side_app",
771
784
  {
772
785
  component_key: "generic_data_table",
773
- message: message2 || "",
774
- data: { dataSource, message: message2 },
786
+ message: message3 || "",
787
+ data: { dataSource, message: message3 },
775
788
  size: "large"
776
789
  },
777
790
  ""
@@ -1006,9 +1019,12 @@ function getStatusIcon(status) {
1006
1019
  return /* @__PURE__ */ jsx6(LoadingOutlined, { style: { color: "#1890ff" } });
1007
1020
  }
1008
1021
  }
1009
- var ToolCall = ({ data }) => {
1022
+ var ToolCall = ({ data, eventHandler }) => {
1010
1023
  const toolCallData = data;
1011
1024
  const formatToolName = (name) => {
1025
+ if (!name) {
1026
+ return "";
1027
+ }
1012
1028
  return name.replace(/([a-z])([A-Z])/g, "$1 $2").split(/[_-]/).map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
1013
1029
  };
1014
1030
  const formatArgsPreview = (args) => {
@@ -1065,6 +1081,14 @@ var ToolCall = ({ data }) => {
1065
1081
  const expandIcon = ({ isActive }) => {
1066
1082
  return getStatusIcon(toolCallData.status);
1067
1083
  };
1084
+ const toolCallElement = getElement(toolCallData.name.toLowerCase());
1085
+ if (toolCallElement) {
1086
+ return toolCallElement.card_view({
1087
+ data: toolCallData,
1088
+ component_key: toolCallData.id,
1089
+ eventHandler
1090
+ });
1091
+ }
1068
1092
  return /* @__PURE__ */ jsx6(
1069
1093
  Collapse,
1070
1094
  {
@@ -1100,8 +1124,8 @@ var useStyle3 = createStyles3(({ token, css }) => ({
1100
1124
  max-width: 1200px;
1101
1125
  background: linear-gradient(
1102
1126
  919deg,
1103
- rgb(67 232 157 / 8%),
1104
- rgb(206 250 235 / 28%) 43%
1127
+ rgb(67 81 232 / 8%),
1128
+ rgb(249 249 249 / 28%) 43%
1105
1129
  );
1106
1130
  `,
1107
1131
  todoItem: css`
@@ -1220,7 +1244,1028 @@ var Todo = ({
1220
1244
  ] }) });
1221
1245
  };
1222
1246
 
1223
- // src/components/GenUI/elements/index.tsx
1247
+ // src/components/GenUI/elements/WriteTodos.tsx
1248
+ import { Space as Space6, Collapse as Collapse2, Typography as Typography6 } from "antd";
1249
+ import { UnorderedListOutlined } from "@ant-design/icons";
1250
+ import CollapsePanel2 from "antd/es/collapse/CollapsePanel";
1251
+ import { jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
1252
+ var { Text: Text5 } = Typography6;
1253
+ var WriteTodos = ({
1254
+ data,
1255
+ component_key,
1256
+ eventHandler,
1257
+ interactive = true
1258
+ }) => {
1259
+ const toolCallData = data;
1260
+ const todos = toolCallData?.args?.todos || [];
1261
+ const totalCount = todos.length;
1262
+ const completedCount = todos.filter(
1263
+ (item) => item.status === "completed"
1264
+ ).length;
1265
+ const expandIcon = () => {
1266
+ return /* @__PURE__ */ jsx8(UnorderedListOutlined, {});
1267
+ };
1268
+ const header = /* @__PURE__ */ jsxs6(Space6, { children: [
1269
+ /* @__PURE__ */ jsx8(Text5, { strong: true, children: "Todos" }),
1270
+ /* @__PURE__ */ jsxs6(Text5, { style: { fontSize: 12 }, type: "secondary", children: [
1271
+ completedCount,
1272
+ "/",
1273
+ totalCount,
1274
+ " Done"
1275
+ ] })
1276
+ ] });
1277
+ if (!toolCallData) {
1278
+ return null;
1279
+ }
1280
+ return /* @__PURE__ */ jsx8(
1281
+ Collapse2,
1282
+ {
1283
+ size: "small",
1284
+ bordered: false,
1285
+ defaultActiveKey: [],
1286
+ expandIcon,
1287
+ children: /* @__PURE__ */ jsx8(
1288
+ CollapsePanel2,
1289
+ {
1290
+ header,
1291
+ style: { minWidth: 400 },
1292
+ children: /* @__PURE__ */ jsx8(
1293
+ Todo,
1294
+ {
1295
+ data: data.args.todos,
1296
+ component_key,
1297
+ eventHandler,
1298
+ interactive
1299
+ }
1300
+ )
1301
+ },
1302
+ toolCallData.id
1303
+ )
1304
+ }
1305
+ );
1306
+ };
1307
+
1308
+ // src/components/GenUI/FileExplorer.tsx
1309
+ import { useState as useState7, useEffect as useEffect4, useMemo as useMemo2 } from "react";
1310
+ import { Splitter, Tree, Empty, Button as Button3, Tooltip, message } from "antd";
1311
+ import {
1312
+ FolderOutlined,
1313
+ FolderOpenOutlined,
1314
+ CopyOutlined,
1315
+ DownloadOutlined as DownloadOutlined2,
1316
+ CheckOutlined
1317
+ } from "@ant-design/icons";
1318
+ import { createStyles as createStyles4 } from "antd-style";
1319
+
1320
+ // src/components/GenUI/elements/getFileIcon.tsx
1321
+ import {
1322
+ CodeOutlined as CodeOutlined2,
1323
+ FileImageOutlined,
1324
+ FileMarkdownOutlined,
1325
+ FileOutlined,
1326
+ FileTextOutlined,
1327
+ FileUnknownOutlined,
1328
+ Html5Outlined
1329
+ } from "@ant-design/icons";
1330
+ import { jsx as jsx9 } from "react/jsx-runtime";
1331
+ var getFileIcon = (filename) => {
1332
+ const ext = filename?.split(".")?.pop()?.toLowerCase();
1333
+ const iconStyle = { fontSize: 14, marginRight: 4, verticalAlign: "middle" };
1334
+ switch (ext) {
1335
+ case "ts":
1336
+ case "tsx":
1337
+ return /* @__PURE__ */ jsx9(CodeOutlined2, { style: { ...iconStyle, color: "#3178c6" } });
1338
+ case "js":
1339
+ case "jsx":
1340
+ return /* @__PURE__ */ jsx9(CodeOutlined2, { style: { ...iconStyle, color: "#f7df1e" } });
1341
+ case "html":
1342
+ return /* @__PURE__ */ jsx9(Html5Outlined, { style: { ...iconStyle, color: "#e34c26" } });
1343
+ case "css":
1344
+ case "less":
1345
+ case "scss":
1346
+ return /* @__PURE__ */ jsx9(FileUnknownOutlined, { style: { ...iconStyle, color: "#563d7c" } });
1347
+ case "md":
1348
+ return /* @__PURE__ */ jsx9(FileMarkdownOutlined, { style: { ...iconStyle, color: "#083fa1" } });
1349
+ case "json":
1350
+ return /* @__PURE__ */ jsx9(FileTextOutlined, { style: { ...iconStyle, color: "#fbc02d" } });
1351
+ case "png":
1352
+ case "jpg":
1353
+ case "jpeg":
1354
+ case "gif":
1355
+ case "svg":
1356
+ return /* @__PURE__ */ jsx9(FileImageOutlined, { style: { ...iconStyle, color: "#4caf50" } });
1357
+ default:
1358
+ return /* @__PURE__ */ jsx9(FileOutlined, { style: { ...iconStyle, color: "#9e9e9e" } });
1359
+ }
1360
+ };
1361
+
1362
+ // src/components/GenUI/FileExplorer.tsx
1363
+ import { jsx as jsx10, jsxs as jsxs7 } from "react/jsx-runtime";
1364
+ var useStyles = createStyles4(({ token, css }) => ({
1365
+ container: css`
1366
+ height: 100%;
1367
+ background: ${token.colorBgContainer};
1368
+ border: 1px solid ${token.colorBorder};
1369
+ border-radius: ${token.borderRadiusLG}px;
1370
+ overflow: hidden;
1371
+ display: flex;
1372
+ flex-direction: column;
1373
+ `,
1374
+ splitter: css`
1375
+ height: 100%;
1376
+ .ant-splitter-bar-dragger {
1377
+ background: transparent !important;
1378
+ &:hover {
1379
+ background: ${token.colorPrimary} !important;
1380
+ }
1381
+ }
1382
+ `,
1383
+ leftPanel: css`
1384
+ height: 100%;
1385
+ overflow: auto;
1386
+ padding: 0;
1387
+ background: ${token.colorBgContainer};
1388
+ border-right: 1px solid ${token.colorBorderSecondary};
1389
+
1390
+ /* Custom scrollbar for tree */
1391
+ &::-webkit-scrollbar {
1392
+ width: 6px;
1393
+ height: 6px;
1394
+ }
1395
+ &::-webkit-scrollbar-thumb {
1396
+ background: ${token.colorBorder};
1397
+ border-radius: 3px;
1398
+ }
1399
+ `,
1400
+ rightPanel: css`
1401
+ height: 100%;
1402
+ overflow: auto;
1403
+ padding: 0;
1404
+ background: ${token.colorBgLayout};
1405
+ position: relative;
1406
+ `,
1407
+ header: css`
1408
+ display: flex;
1409
+ justify-content: flex-end;
1410
+ padding: 8px 16px;
1411
+ background: ${token.colorBgContainer + "30"};
1412
+ backdrop-filter: blur(4px);
1413
+ -webkit-backdrop-filter: blur(4px);
1414
+ gap: 8px;
1415
+ position: sticky;
1416
+ top: 0;
1417
+ z-index: 10;
1418
+ `,
1419
+ contentBody: css`
1420
+ padding: 24px;
1421
+ min-height: 100%;
1422
+
1423
+ pre {
1424
+ margin: 0 !important;
1425
+ border-radius: ${token.borderRadius}px !important;
1426
+ }
1427
+ `,
1428
+ emptyState: css`
1429
+ display: flex;
1430
+ flex-direction: column;
1431
+ align-items: center;
1432
+ justify-content: center;
1433
+ height: 100%;
1434
+ color: ${token.colorTextQuaternary};
1435
+ `,
1436
+ fileTree: css`
1437
+ background: transparent;
1438
+ font-size: 13px;
1439
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
1440
+ "Helvetica Neue", Arial, sans-serif;
1441
+
1442
+ .ant-tree-treenode {
1443
+ padding-bottom: 0 !important;
1444
+ width: 100%;
1445
+ &:hover {
1446
+ background-color: ${token.colorFillQuaternary};
1447
+ }
1448
+ }
1449
+
1450
+ .ant-tree-node-content-wrapper {
1451
+ padding: 0 4px;
1452
+ border-radius: 0;
1453
+ transition: none;
1454
+ line-height: 24px;
1455
+ min-height: 24px;
1456
+
1457
+ &:hover {
1458
+ background-color: transparent;
1459
+ }
1460
+
1461
+ &.ant-tree-node-selected {
1462
+ background-color: ${token.controlItemBgActive} !important;
1463
+ color: ${token.colorText};
1464
+ font-weight: 500;
1465
+ }
1466
+ }
1467
+
1468
+ .ant-tree-indent-unit {
1469
+ width: 16px;
1470
+ }
1471
+
1472
+ .ant-tree-switcher {
1473
+ width: 20px;
1474
+ line-height: 24px;
1475
+
1476
+ .anticon {
1477
+ font-size: 10px;
1478
+ color: ${token.colorTextSecondary};
1479
+ }
1480
+ }
1481
+
1482
+ .ant-tree-title {
1483
+ display: inline-block;
1484
+ margin-left: 4px;
1485
+ }
1486
+ `
1487
+ }));
1488
+ var getFolderIcon = (expanded) => {
1489
+ const iconStyle = {
1490
+ fontSize: 14,
1491
+ marginRight: 4,
1492
+ color: "#dcb67a",
1493
+ verticalAlign: "middle"
1494
+ };
1495
+ return expanded ? /* @__PURE__ */ jsx10(FolderOpenOutlined, { style: iconStyle }) : /* @__PURE__ */ jsx10(FolderOutlined, { style: iconStyle });
1496
+ };
1497
+ var sortTreeNodes = (nodes) => {
1498
+ return nodes.sort((a, b) => {
1499
+ if (!!a.isLeaf === !!b.isLeaf) {
1500
+ return a.title.localeCompare(b.title);
1501
+ }
1502
+ return a.isLeaf ? 1 : -1;
1503
+ }).map((node) => {
1504
+ if (node.children) {
1505
+ return { ...node, children: sortTreeNodes(node.children) };
1506
+ }
1507
+ return node;
1508
+ });
1509
+ };
1510
+ var buildTreeData = (files, expandedKeys) => {
1511
+ const root = [];
1512
+ files.forEach((file) => {
1513
+ const parts = file.name.split("/");
1514
+ let currentLevel = root;
1515
+ parts.forEach((part, index) => {
1516
+ const isFile = index === parts.length - 1;
1517
+ const key = parts.slice(0, index + 1).join("/");
1518
+ let existingNode = currentLevel.find((node) => node.key === key);
1519
+ if (!existingNode) {
1520
+ const title = part === "" && index === 0 ? /* @__PURE__ */ jsx10(
1521
+ "span",
1522
+ {
1523
+ style: {
1524
+ color: "rgba(0, 0, 0, 0.45)",
1525
+ fontStyle: "italic",
1526
+ fontSize: 12
1527
+ },
1528
+ children: "<root>"
1529
+ }
1530
+ ) : part;
1531
+ const newNode = {
1532
+ title,
1533
+ key,
1534
+ isLeaf: isFile,
1535
+ icon: isFile ? getFileIcon(part) : getFolderIcon(expandedKeys.includes(key)),
1536
+ children: isFile ? void 0 : []
1537
+ };
1538
+ currentLevel.push(newNode);
1539
+ existingNode = newNode;
1540
+ }
1541
+ if (!isFile && existingNode.children) {
1542
+ currentLevel = existingNode.children;
1543
+ }
1544
+ });
1545
+ });
1546
+ return sortTreeNodes(root);
1547
+ };
1548
+ var FileExplorer = ({
1549
+ data,
1550
+ eventHandler,
1551
+ interactive = true,
1552
+ default_open_in_side_app = true
1553
+ }) => {
1554
+ const { files } = data ?? {};
1555
+ const { styles, cx } = useStyles();
1556
+ const [fileList, setFileList] = useState7([]);
1557
+ const [selectedKey, setSelectedKey] = useState7("");
1558
+ const [expandedKeys, setExpandedKeys] = useState7([]);
1559
+ const [copied, setCopied] = useState7(false);
1560
+ useEffect4(() => {
1561
+ if (copied) {
1562
+ const timer = setTimeout(() => setCopied(false), 2e3);
1563
+ return () => clearTimeout(timer);
1564
+ }
1565
+ }, [copied]);
1566
+ useEffect4(() => {
1567
+ let list = [];
1568
+ if (Array.isArray(files)) {
1569
+ list = files;
1570
+ } else {
1571
+ list = Object.keys(files).map((key) => ({
1572
+ ...files[key],
1573
+ name: key
1574
+ }));
1575
+ }
1576
+ setFileList(list);
1577
+ if (list.length > 0 && !selectedKey) {
1578
+ const firstFile = list[0];
1579
+ setSelectedKey(list[0].name);
1580
+ }
1581
+ }, [files]);
1582
+ const treeData = useMemo2(
1583
+ () => buildTreeData(fileList, expandedKeys),
1584
+ [fileList, expandedKeys]
1585
+ );
1586
+ useEffect4(() => {
1587
+ if (treeData.length > 0 && expandedKeys.length === 0) {
1588
+ const getAllKeys = (nodes) => {
1589
+ let keys = [];
1590
+ nodes.forEach((node) => {
1591
+ if (!node.isLeaf) {
1592
+ keys.push(node.key);
1593
+ if (node.children) {
1594
+ keys = keys.concat(getAllKeys(node.children));
1595
+ }
1596
+ }
1597
+ });
1598
+ return keys;
1599
+ };
1600
+ setExpandedKeys(getAllKeys(treeData));
1601
+ }
1602
+ }, [treeData.length]);
1603
+ const selectedFile = useMemo2(() => {
1604
+ return fileList.find((f) => f.name === selectedKey);
1605
+ }, [fileList, selectedKey]);
1606
+ const handleCopy = () => {
1607
+ if (!selectedFile) return;
1608
+ const content = Array.isArray(selectedFile.content) ? selectedFile.content.join("\n") : selectedFile.content;
1609
+ navigator.clipboard.writeText(content).then(() => {
1610
+ setCopied(true);
1611
+ message.success("Copied to clipboard");
1612
+ });
1613
+ };
1614
+ const handleDownload = () => {
1615
+ if (!selectedFile) return;
1616
+ const content = Array.isArray(selectedFile.content) ? selectedFile.content.join("\n") : selectedFile.content;
1617
+ const blob = new Blob([content], { type: "text/plain" });
1618
+ const url = URL.createObjectURL(blob);
1619
+ const a = document.createElement("a");
1620
+ a.href = url;
1621
+ const fileName = selectedFile.name.split("/").pop() || selectedFile.name;
1622
+ a.download = fileName;
1623
+ document.body.appendChild(a);
1624
+ a.click();
1625
+ document.body.removeChild(a);
1626
+ URL.revokeObjectURL(url);
1627
+ };
1628
+ const renderContent = () => {
1629
+ if (!selectedFile) {
1630
+ return /* @__PURE__ */ jsx10("div", { className: styles.emptyState, children: /* @__PURE__ */ jsx10(
1631
+ Empty,
1632
+ {
1633
+ description: "Select a file to preview",
1634
+ image: Empty.PRESENTED_IMAGE_SIMPLE
1635
+ }
1636
+ ) });
1637
+ }
1638
+ const content = Array.isArray(selectedFile.content) ? selectedFile.content.join("\n") : selectedFile.content;
1639
+ return /* @__PURE__ */ jsxs7(
1640
+ "div",
1641
+ {
1642
+ style: { minHeight: "100%", display: "flex", flexDirection: "column" },
1643
+ children: [
1644
+ /* @__PURE__ */ jsxs7("div", { className: styles.header, children: [
1645
+ /* @__PURE__ */ jsx10(Tooltip, { title: "Copy Content", children: /* @__PURE__ */ jsx10(
1646
+ Button3,
1647
+ {
1648
+ type: "text",
1649
+ icon: copied ? /* @__PURE__ */ jsx10(CheckOutlined, {}) : /* @__PURE__ */ jsx10(CopyOutlined, {}),
1650
+ onClick: handleCopy,
1651
+ size: "small"
1652
+ }
1653
+ ) }),
1654
+ /* @__PURE__ */ jsx10(Tooltip, { title: "Download File", children: /* @__PURE__ */ jsx10(
1655
+ Button3,
1656
+ {
1657
+ type: "text",
1658
+ icon: /* @__PURE__ */ jsx10(DownloadOutlined2, {}),
1659
+ onClick: handleDownload,
1660
+ size: "small"
1661
+ }
1662
+ ) })
1663
+ ] }),
1664
+ /* @__PURE__ */ jsx10("div", { className: styles.contentBody, children: /* @__PURE__ */ jsx10(MDResponse, { content }) })
1665
+ ]
1666
+ }
1667
+ );
1668
+ };
1669
+ return /* @__PURE__ */ jsx10("div", { className: styles.container, children: /* @__PURE__ */ jsxs7(Splitter, { className: styles.splitter, children: [
1670
+ /* @__PURE__ */ jsx10(Splitter.Panel, { defaultSize: "25%", min: "15%", max: "40%", children: /* @__PURE__ */ jsx10("div", { className: styles.leftPanel, children: /* @__PURE__ */ jsx10(
1671
+ Tree,
1672
+ {
1673
+ showIcon: true,
1674
+ blockNode: true,
1675
+ showLine: true,
1676
+ className: styles.fileTree,
1677
+ treeData,
1678
+ selectedKeys: selectedKey ? [selectedKey] : [],
1679
+ expandedKeys,
1680
+ onExpand: setExpandedKeys,
1681
+ onSelect: (keys, info) => {
1682
+ if (keys.length > 0) {
1683
+ const key = keys[0];
1684
+ const file = fileList.find((f) => f.name === key);
1685
+ if (file) {
1686
+ setSelectedKey(key);
1687
+ } else {
1688
+ if (expandedKeys.includes(key)) {
1689
+ setExpandedKeys(expandedKeys.filter((k) => k !== key));
1690
+ } else {
1691
+ setExpandedKeys([...expandedKeys, key]);
1692
+ }
1693
+ }
1694
+ } else if (info.node.key) {
1695
+ const key = info.node.key;
1696
+ const file = fileList.find((f) => f.name === key);
1697
+ if (!file) {
1698
+ if (expandedKeys.includes(key)) {
1699
+ setExpandedKeys(expandedKeys.filter((k) => k !== key));
1700
+ } else {
1701
+ setExpandedKeys([...expandedKeys, key]);
1702
+ }
1703
+ }
1704
+ }
1705
+ }
1706
+ }
1707
+ ) }) }),
1708
+ /* @__PURE__ */ jsx10(Splitter.Panel, { children: /* @__PURE__ */ jsx10("div", { className: styles.rightPanel, children: renderContent() }) })
1709
+ ] }) });
1710
+ };
1711
+
1712
+ // src/components/GenUI/elements/attachments_card.tsx
1713
+ import { Attachments } from "@ant-design/x";
1714
+ import {
1715
+ Card as Card5,
1716
+ Flex as Flex3,
1717
+ Space as Space7,
1718
+ Typography as Typography7,
1719
+ Row,
1720
+ Col,
1721
+ Button as Button4
1722
+ } from "antd";
1723
+ import dayjs from "dayjs";
1724
+ import { useState as useState8 } from "react";
1725
+ import { jsx as jsx11, jsxs as jsxs8 } from "react/jsx-runtime";
1726
+ var AttachmentsCard = ({
1727
+ data,
1728
+ eventHandler,
1729
+ component_key,
1730
+ size = "medium",
1731
+ columns = 1,
1732
+ showDownloadButton = false
1733
+ }) => {
1734
+ const { Text: Text8 } = Typography7;
1735
+ const [showAll, setShowAll] = useState8(false);
1736
+ const getStyles = () => {
1737
+ switch (size) {
1738
+ case "small":
1739
+ return {
1740
+ padding: "0px",
1741
+ fontSize: "10px",
1742
+ cardSize: "small"
1743
+ };
1744
+ case "large":
1745
+ return {
1746
+ padding: "16px",
1747
+ fontSize: "16px",
1748
+ cardSize: "default"
1749
+ };
1750
+ default:
1751
+ return {
1752
+ padding: "8px",
1753
+ fontSize: "14px",
1754
+ cardSize: "small"
1755
+ };
1756
+ }
1757
+ };
1758
+ const styles = getStyles();
1759
+ const handleItemClick = (item) => {
1760
+ eventHandler?.(
1761
+ "__open_side_app",
1762
+ {
1763
+ component_key: "attachments",
1764
+ data: { file_id: item.id, message: "\u9884\u89C8\uFF1A" + item.name }
1765
+ },
1766
+ ""
1767
+ );
1768
+ };
1769
+ const getCardStyle = (item) => {
1770
+ if (item.is_failure && columns > 1) {
1771
+ return {
1772
+ padding: 0
1773
+ };
1774
+ }
1775
+ return { padding: 0, cursor: "pointer" };
1776
+ };
1777
+ const getFileCardStyle = (item) => {
1778
+ const baseStyle = {
1779
+ width: "100%",
1780
+ backgroundColor: "transparent",
1781
+ fontSize: styles.fontSize,
1782
+ padding: styles.padding,
1783
+ position: "relative"
1784
+ // 添加相对定位,用于绝对定位下载按钮
1785
+ };
1786
+ if (item.is_failure && columns > 1) {
1787
+ return {
1788
+ ...baseStyle,
1789
+ color: "gray"
1790
+ };
1791
+ }
1792
+ return baseStyle;
1793
+ };
1794
+ const DownloadButton = ({ item }) => {
1795
+ if (!showDownloadButton) return null;
1796
+ return /* @__PURE__ */ jsx11(
1797
+ "div",
1798
+ {
1799
+ style: {
1800
+ position: "absolute",
1801
+ top: "50%",
1802
+ right: 8,
1803
+ transform: "translateY(-50%)",
1804
+ zIndex: 10
1805
+ },
1806
+ onClick: (e) => e.stopPropagation()
1807
+ }
1808
+ );
1809
+ };
1810
+ const renderFileDescription = (item) => /* @__PURE__ */ jsx11(Space7, { direction: "vertical", size: size === "small" ? 2 : 4, children: /* @__PURE__ */ jsx11(Space7, { children: /* @__PURE__ */ jsx11(
1811
+ Text8,
1812
+ {
1813
+ type: "secondary",
1814
+ style: {
1815
+ fontSize: size === "small" ? "10px" : void 0
1816
+ },
1817
+ children: item.created_at && dayjs(item.created_at).format("YYYY-MM-DD HH:mm:ss")
1818
+ }
1819
+ ) }) });
1820
+ if (columns > 1) {
1821
+ const displayData2 = data || [];
1822
+ const shouldShowViewMore2 = displayData2.length > 4;
1823
+ const visibleData2 = showAll ? displayData2 : displayData2.slice(0, 4);
1824
+ return /* @__PURE__ */ jsxs8(Flex3, { vertical: true, gap: "small", children: [
1825
+ /* @__PURE__ */ jsx11(Row, { gutter: [8, 8], children: visibleData2.map((item) => /* @__PURE__ */ jsx11(Col, { span: 24 / columns, children: /* @__PURE__ */ jsx11(
1826
+ "div",
1827
+ {
1828
+ onClick: (evt) => {
1829
+ evt.stopPropagation();
1830
+ handleItemClick(item);
1831
+ },
1832
+ children: /* @__PURE__ */ jsxs8(Card5, { size: styles.cardSize, style: getCardStyle(item), children: [
1833
+ /* @__PURE__ */ jsx11(DownloadButton, { item }),
1834
+ /* @__PURE__ */ jsx11(
1835
+ Attachments.FileCard,
1836
+ {
1837
+ style: getFileCardStyle(item),
1838
+ item: {
1839
+ name: item.name,
1840
+ size: item.size,
1841
+ uid: item.id,
1842
+ description: renderFileDescription(item)
1843
+ }
1844
+ }
1845
+ ),
1846
+ item.files && /* @__PURE__ */ jsx11(
1847
+ AttachmentsCard,
1848
+ {
1849
+ data: item.files,
1850
+ component_key: `${component_key}_${item.id}`,
1851
+ eventHandler,
1852
+ size: "small",
1853
+ columns: 2,
1854
+ showDownloadButton
1855
+ }
1856
+ )
1857
+ ] })
1858
+ }
1859
+ ) }, item.id)) }),
1860
+ shouldShowViewMore2 && /* @__PURE__ */ jsx11(
1861
+ Button4,
1862
+ {
1863
+ type: "link",
1864
+ onClick: () => setShowAll(!showAll),
1865
+ style: { alignSelf: "center" },
1866
+ children: showAll ? "\u663E\u793A\u66F4\u5C11" : `\u663E\u793A\u66F4\u591A (${displayData2.length - 4})`
1867
+ }
1868
+ )
1869
+ ] });
1870
+ }
1871
+ const displayData = data || [];
1872
+ const shouldShowViewMore = displayData.length > 4;
1873
+ const visibleData = showAll ? displayData : displayData.slice(0, 4);
1874
+ return /* @__PURE__ */ jsxs8(Flex3, { vertical: true, gap: size === "small" ? "small" : "middle", children: [
1875
+ visibleData.map((item) => /* @__PURE__ */ jsx11("div", { onClick: () => handleItemClick(item), children: /* @__PURE__ */ jsxs8(Card5, { size: styles.cardSize, style: getCardStyle(item), children: [
1876
+ /* @__PURE__ */ jsx11(DownloadButton, { item }),
1877
+ /* @__PURE__ */ jsx11(
1878
+ Attachments.FileCard,
1879
+ {
1880
+ style: getFileCardStyle(item),
1881
+ item: {
1882
+ name: item.name,
1883
+ size: item.size,
1884
+ uid: item.id,
1885
+ description: renderFileDescription(item)
1886
+ }
1887
+ }
1888
+ ),
1889
+ item.files && /* @__PURE__ */ jsxs8("div", { style: { paddingLeft: "12px" }, children: [
1890
+ /* @__PURE__ */ jsxs8(Text8, { type: "secondary", style: { fontSize: "12px" }, children: [
1891
+ "\u5305\u542B\u6587\u4EF6(",
1892
+ item.files.length,
1893
+ ")"
1894
+ ] }),
1895
+ /* @__PURE__ */ jsx11(
1896
+ AttachmentsCard,
1897
+ {
1898
+ data: item.files,
1899
+ component_key: `${component_key}_${item.id}`,
1900
+ eventHandler,
1901
+ size: "small",
1902
+ columns: 2,
1903
+ showDownloadButton
1904
+ }
1905
+ )
1906
+ ] })
1907
+ ] }) }, item.id)),
1908
+ shouldShowViewMore && /* @__PURE__ */ jsx11(
1909
+ Button4,
1910
+ {
1911
+ type: "link",
1912
+ size: "small",
1913
+ onClick: (evt) => {
1914
+ evt.stopPropagation();
1915
+ setShowAll(!showAll);
1916
+ },
1917
+ style: { alignSelf: "center" },
1918
+ children: showAll ? "\u663E\u793A\u66F4\u5C11" : `\u663E\u793A\u66F4\u591A (${displayData.length - 4})`
1919
+ }
1920
+ )
1921
+ ] });
1922
+ };
1923
+
1924
+ // src/components/GenUI/elements/attachments_viewer_side_app.tsx
1925
+ import { Button as Button5, Empty as Empty2, Skeleton } from "antd";
1926
+ import { useState as useState9 } from "react";
1927
+ import { Fragment, jsx as jsx12, jsxs as jsxs9 } from "react/jsx-runtime";
1928
+ function AttachmentsViewerSideApp({
1929
+ data,
1930
+ eventHandler,
1931
+ component_key
1932
+ }) {
1933
+ const [fileUri, setFileUri] = useState9();
1934
+ const [loading, setLoading] = useState9(true);
1935
+ const { file_id } = data ?? {};
1936
+ if (loading) {
1937
+ return /* @__PURE__ */ jsx12(Skeleton, { active: true });
1938
+ }
1939
+ const canPreviewInIframe = (fileName) => {
1940
+ if (!fileName) return false;
1941
+ const extension = fileName?.split(".").pop()?.toLowerCase() || "";
1942
+ const previewableExtensions = [
1943
+ // PDF文档
1944
+ "pdf",
1945
+ // 图片类型
1946
+ "jpg",
1947
+ "jpeg",
1948
+ "png",
1949
+ "gif",
1950
+ "svg",
1951
+ "bmp",
1952
+ "webp",
1953
+ // 文本类型
1954
+ "txt",
1955
+ "csv",
1956
+ "json",
1957
+ "xml",
1958
+ // 网页类型
1959
+ "html",
1960
+ "htm",
1961
+ // 音频类型
1962
+ "mp3",
1963
+ "wav",
1964
+ "ogg",
1965
+ // 视频类型
1966
+ "mp4",
1967
+ "webm"
1968
+ ];
1969
+ return previewableExtensions.includes(extension);
1970
+ };
1971
+ const isPreviewable = fileUri?.fileName ? canPreviewInIframe(fileUri.fileName) : false;
1972
+ return isPreviewable ? /* @__PURE__ */ jsx12(
1973
+ "iframe",
1974
+ {
1975
+ style: { width: "100%", height: "100%", border: 0 },
1976
+ src: fileUri?.url
1977
+ }
1978
+ ) : /* @__PURE__ */ jsx12(
1979
+ Empty2,
1980
+ {
1981
+ description: /* @__PURE__ */ jsxs9(Fragment, { children: [
1982
+ /* @__PURE__ */ jsx12("div", { children: "\u6682\u65F6\u4E0D\u652F\u6301\u9884\u89C8\uFF0C\u8BF7\u4E0B\u8F7D\u540E\u67E5\u770B\u3002" }),
1983
+ /* @__PURE__ */ jsxs9(Button5, { type: "link", href: fileUri?.url, download: fileUri?.fileName, children: [
1984
+ "\u4E0B\u8F7D",
1985
+ fileUri?.fileName
1986
+ ] })
1987
+ ] }),
1988
+ image: Empty2.PRESENTED_IMAGE_DEFAULT
1989
+ }
1990
+ );
1991
+ }
1992
+
1993
+ // src/components/GenUI/elements/WriteFile.tsx
1994
+ import { Button as Button6, Space as Space8, Typography as Typography8 } from "antd";
1995
+
1996
+ // src/components/GenUI/elements/ContentPreviewCollapse.tsx
1997
+ import { useRef as useRef3, useState as useState10, useEffect as useEffect6, useCallback as useCallback5 } from "react";
1998
+ import { Collapse as Collapse4 } from "antd";
1999
+ import { createStyles as createStyles5 } from "antd-style";
2000
+ import { DownOutlined as DownOutlined2, UpOutlined } from "@ant-design/icons";
2001
+ import CollapsePanel3 from "antd/es/collapse/CollapsePanel";
2002
+ import { Fragment as Fragment2, jsx as jsx13, jsxs as jsxs10 } from "react/jsx-runtime";
2003
+ var DEFAULT_COLLAPSED_MAX_HEIGHT = 180;
2004
+ var DEFAULT_EXPANDED_MAX_HEIGHT = 500;
2005
+ var useStyle4 = createStyles5(
2006
+ ({ css }, { showShadow }) => ({
2007
+ collapse: css`
2008
+ .ant-collapse-header {
2009
+ position: relative;
2010
+ z-index: 1;
2011
+ transition: box-shadow 0.2s ease;
2012
+ box-shadow: ${showShadow ? "0 4px 8px -2px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)" : "none"};
2013
+ }
2014
+
2015
+ .ant-collapse-content-box {
2016
+ padding-top: 0 !important;
2017
+ }
2018
+ `,
2019
+ contentContainer: css`
2020
+ position: relative;
2021
+ overflow: hidden;
2022
+ display: flex;
2023
+ flex-direction: column;
2024
+ justify-content: flex-end;
2025
+
2026
+ &.expanded {
2027
+ overflow: auto;
2028
+ display: block;
2029
+ }
2030
+ `,
2031
+ content: css`
2032
+ flex-shrink: 0;
2033
+ `,
2034
+ toggleButton: css`
2035
+ display: flex;
2036
+ align-items: center;
2037
+ justify-content: center;
2038
+ gap: 4px;
2039
+ padding: 8px 0;
2040
+ margin-top: 8px;
2041
+ border-top: 1px solid rgba(0, 0, 0, 0.06);
2042
+ cursor: pointer;
2043
+ color: #1890ff;
2044
+ font-size: 12px;
2045
+ user-select: none;
2046
+ transition: color 0.2s;
2047
+
2048
+ &:hover {
2049
+ color: #40a9ff;
2050
+ }
2051
+ `
2052
+ })
2053
+ );
2054
+ var ContentPreviewCollapse = ({
2055
+ panelKey,
2056
+ header,
2057
+ extra,
2058
+ expandIcon,
2059
+ children,
2060
+ collapsedMaxHeight = DEFAULT_COLLAPSED_MAX_HEIGHT,
2061
+ expandedMaxHeight = DEFAULT_EXPANDED_MAX_HEIGHT,
2062
+ defaultExpanded = true,
2063
+ minWidth = 400,
2064
+ showAllText = "Show all content",
2065
+ showLessText = "Show less"
2066
+ }) => {
2067
+ const [showFullContent, setShowFullContent] = useState10(false);
2068
+ const [isOverflowing, setIsOverflowing] = useState10(false);
2069
+ const contentRef = useRef3(null);
2070
+ const showShadow = isOverflowing && !showFullContent;
2071
+ const { styles, cx } = useStyle4({ showShadow });
2072
+ const checkOverflow = useCallback5(() => {
2073
+ if (contentRef.current) {
2074
+ const scrollHeight = contentRef.current.scrollHeight;
2075
+ setIsOverflowing(scrollHeight > collapsedMaxHeight);
2076
+ }
2077
+ }, [collapsedMaxHeight]);
2078
+ useEffect6(() => {
2079
+ const element = contentRef.current;
2080
+ if (!element) return;
2081
+ checkOverflow();
2082
+ const resizeObserver = new ResizeObserver(() => {
2083
+ checkOverflow();
2084
+ });
2085
+ resizeObserver.observe(element);
2086
+ return () => {
2087
+ resizeObserver.disconnect();
2088
+ };
2089
+ }, [children, checkOverflow]);
2090
+ const handleToggleContent = (e) => {
2091
+ e.stopPropagation();
2092
+ setShowFullContent(!showFullContent);
2093
+ };
2094
+ return /* @__PURE__ */ jsx13(
2095
+ Collapse4,
2096
+ {
2097
+ className: styles.collapse,
2098
+ size: "small",
2099
+ bordered: false,
2100
+ defaultActiveKey: defaultExpanded ? [panelKey] : [],
2101
+ expandIcon,
2102
+ children: /* @__PURE__ */ jsxs10(
2103
+ CollapsePanel3,
2104
+ {
2105
+ header,
2106
+ extra,
2107
+ style: { minWidth },
2108
+ children: [
2109
+ /* @__PURE__ */ jsx13(
2110
+ "div",
2111
+ {
2112
+ className: cx(styles.contentContainer, showFullContent && "expanded"),
2113
+ style: {
2114
+ maxHeight: showFullContent ? expandedMaxHeight : collapsedMaxHeight
2115
+ },
2116
+ children: /* @__PURE__ */ jsx13("div", { ref: contentRef, className: styles.content, children })
2117
+ }
2118
+ ),
2119
+ isOverflowing && /* @__PURE__ */ jsx13("div", { className: styles.toggleButton, onClick: handleToggleContent, children: showFullContent ? /* @__PURE__ */ jsxs10(Fragment2, { children: [
2120
+ /* @__PURE__ */ jsx13(UpOutlined, { style: { fontSize: 10 } }),
2121
+ /* @__PURE__ */ jsx13("span", { children: showLessText })
2122
+ ] }) : /* @__PURE__ */ jsxs10(Fragment2, { children: [
2123
+ /* @__PURE__ */ jsx13(DownOutlined2, { style: { fontSize: 10 } }),
2124
+ /* @__PURE__ */ jsx13("span", { children: showAllText })
2125
+ ] }) })
2126
+ ]
2127
+ },
2128
+ panelKey
2129
+ )
2130
+ }
2131
+ );
2132
+ };
2133
+
2134
+ // src/components/GenUI/elements/WriteFile.tsx
2135
+ import { jsx as jsx14, jsxs as jsxs11 } from "react/jsx-runtime";
2136
+ var { Text: Text6 } = Typography8;
2137
+ var WriteFile = ({
2138
+ data,
2139
+ component_key,
2140
+ eventHandler,
2141
+ interactive = true
2142
+ }) => {
2143
+ const toolCallData = data;
2144
+ const { file_path, content } = toolCallData?.args || {};
2145
+ if (!toolCallData) {
2146
+ return null;
2147
+ }
2148
+ const expandIcon = () => getFileIcon(file_path);
2149
+ const header = /* @__PURE__ */ jsxs11(Space8, { children: [
2150
+ /* @__PURE__ */ jsx14(Text6, { strong: true, children: "New" }),
2151
+ /* @__PURE__ */ jsx14(Text6, { title: file_path, children: file_path?.split("/")?.pop() || "" })
2152
+ ] });
2153
+ const handleItemClick = (toolCallData2) => {
2154
+ eventHandler?.(
2155
+ "__open_side_app",
2156
+ {
2157
+ component_key: "file_content_diff_view",
2158
+ message: file_path,
2159
+ data: {
2160
+ old_code: "",
2161
+ new_code: content
2162
+ }
2163
+ },
2164
+ ""
2165
+ );
2166
+ };
2167
+ return /* @__PURE__ */ jsx14(
2168
+ ContentPreviewCollapse,
2169
+ {
2170
+ panelKey: toolCallData.id,
2171
+ header,
2172
+ expandIcon,
2173
+ extra: /* @__PURE__ */ jsx14(
2174
+ Button6,
2175
+ {
2176
+ type: "link",
2177
+ size: "small",
2178
+ onClick: (evt) => {
2179
+ evt.stopPropagation();
2180
+ handleItemClick(toolCallData);
2181
+ },
2182
+ children: "Diff View"
2183
+ }
2184
+ ),
2185
+ children: /* @__PURE__ */ jsx14(MDResponse, { content })
2186
+ }
2187
+ );
2188
+ };
2189
+
2190
+ // src/components/GenUI/elements/file_content_diff_view.tsx
2191
+ import ReactDiffViewer from "@alexbruf/react-diff-viewer";
2192
+ import "@alexbruf/react-diff-viewer/index.css";
2193
+ import { jsx as jsx15 } from "react/jsx-runtime";
2194
+ var FileContentDiffView = ({
2195
+ data,
2196
+ eventHandler,
2197
+ interactive = true,
2198
+ default_open_in_side_app = true
2199
+ }) => {
2200
+ const { old_code, new_code } = data;
2201
+ return /* @__PURE__ */ jsx15(
2202
+ ReactDiffViewer,
2203
+ {
2204
+ oldValue: old_code,
2205
+ newValue: new_code,
2206
+ splitView: false
2207
+ }
2208
+ );
2209
+ };
2210
+
2211
+ // src/components/GenUI/elements/EditFile.tsx
2212
+ import { Button as Button7, Space as Space9, Typography as Typography9 } from "antd";
2213
+ import { jsx as jsx16, jsxs as jsxs12 } from "react/jsx-runtime";
2214
+ var { Text: Text7 } = Typography9;
2215
+ var EditFile = ({
2216
+ data,
2217
+ component_key,
2218
+ eventHandler,
2219
+ interactive = true
2220
+ }) => {
2221
+ const toolCallData = data;
2222
+ const { file_path, new_string, old_string } = toolCallData?.args || {};
2223
+ if (!toolCallData) {
2224
+ return null;
2225
+ }
2226
+ const expandIcon = () => getFileIcon(file_path);
2227
+ const header = /* @__PURE__ */ jsxs12(Space9, { children: [
2228
+ /* @__PURE__ */ jsx16(Text7, { strong: true, children: "Edit" }),
2229
+ /* @__PURE__ */ jsx16(Text7, { title: file_path, children: file_path?.split("/")?.pop() || "" })
2230
+ ] });
2231
+ const handleItemClick = (toolCallData2) => {
2232
+ eventHandler?.(
2233
+ "__open_side_app",
2234
+ {
2235
+ component_key: "file_content_diff_view",
2236
+ message: file_path,
2237
+ data: {
2238
+ old_code: old_string,
2239
+ new_code: new_string
2240
+ }
2241
+ },
2242
+ ""
2243
+ );
2244
+ };
2245
+ return /* @__PURE__ */ jsx16(
2246
+ ContentPreviewCollapse,
2247
+ {
2248
+ panelKey: toolCallData.id,
2249
+ header,
2250
+ expandIcon,
2251
+ extra: /* @__PURE__ */ jsx16(
2252
+ Button7,
2253
+ {
2254
+ type: "link",
2255
+ size: "small",
2256
+ onClick: (evt) => {
2257
+ evt.stopPropagation();
2258
+ handleItemClick(toolCallData);
2259
+ },
2260
+ children: "Diff View"
2261
+ }
2262
+ ),
2263
+ children: /* @__PURE__ */ jsx16(MDResponse, { content: new_string })
2264
+ }
2265
+ );
2266
+ };
2267
+
2268
+ // src/components/GenUI/elements/builtIns.tsx
1224
2269
  var elements = {
1225
2270
  action_show_attachments_uploader: {
1226
2271
  card_view: () => null,
@@ -1243,8 +2288,31 @@ var elements = {
1243
2288
  },
1244
2289
  todo_list: {
1245
2290
  card_view: Todo
2291
+ },
2292
+ write_todos: {
2293
+ card_view: WriteTodos
2294
+ },
2295
+ write_file: {
2296
+ card_view: WriteFile
2297
+ },
2298
+ edit_file: {
2299
+ card_view: EditFile
2300
+ },
2301
+ file_explorer: {
2302
+ card_view: () => null,
2303
+ side_app_view: FileExplorer
2304
+ },
2305
+ attachments: {
2306
+ card_view: AttachmentsCard,
2307
+ side_app_view: AttachmentsViewerSideApp
2308
+ },
2309
+ file_content_diff_view: {
2310
+ card_view: FileContentDiffView,
2311
+ side_app_view: FileContentDiffView
1246
2312
  }
1247
2313
  };
2314
+
2315
+ // src/components/GenUI/elements/index.tsx
1248
2316
  var getElement = (language) => {
1249
2317
  if (language && elements[language]) {
1250
2318
  return elements[language];
@@ -1259,15 +2327,15 @@ var regsiterElement = (language, ElementMeta) => {
1259
2327
 
1260
2328
  // src/components/GenUI/MDMermaid.tsx
1261
2329
  import mermaid from "mermaid";
1262
- import { useEffect as useEffect4, useRef as useRef3 } from "react";
2330
+ import { useEffect as useEffect7, useRef as useRef4 } from "react";
1263
2331
  import { v4 } from "uuid";
1264
- import { jsx as jsx8 } from "react/jsx-runtime";
2332
+ import { jsx as jsx17 } from "react/jsx-runtime";
1265
2333
  var MDMermaid = ({ children = [] }) => {
1266
- const domId = useRef3(`dom${v4()}`);
2334
+ const domId = useRef4(`dom${v4()}`);
1267
2335
  const code = String(children);
1268
- const target = useRef3(null);
1269
- const targetInternal = useRef3(null);
1270
- useEffect4(() => {
2336
+ const target = useRef4(null);
2337
+ const targetInternal = useRef4(null);
2338
+ useEffect7(() => {
1271
2339
  if (target.current && code) {
1272
2340
  mermaid.initialize({
1273
2341
  startOnLoad: true,
@@ -1329,13 +2397,13 @@ var MDMermaid = ({ children = [] }) => {
1329
2397
  });
1330
2398
  }
1331
2399
  }, [code]);
1332
- return /* @__PURE__ */ jsx8("div", { style: { minWidth: 750 }, ref: target, children: /* @__PURE__ */ jsx8("code", { id: domId.current, style: { display: "none" } }) });
2400
+ return /* @__PURE__ */ jsx17("div", { style: { minWidth: 750 }, ref: target, children: /* @__PURE__ */ jsx17("code", { id: domId.current, style: { display: "none" } }) });
1333
2401
  };
1334
2402
 
1335
2403
  // src/components/GenUI/MDResponse.tsx
1336
- import { jsx as jsx9 } from "react/jsx-runtime";
2404
+ import { jsx as jsx18 } from "react/jsx-runtime";
1337
2405
  var SyntaxHighlighter = Prism;
1338
- var useStyles = createStyles4(({ token, css }) => ({
2406
+ var useStyles2 = createStyles6(({ token, css }) => ({
1339
2407
  markdownTableContainer: css`
1340
2408
  overflow-x: auto;
1341
2409
  width: 100%;
@@ -1424,26 +2492,26 @@ var MDResponse = ({
1424
2492
  noGenUI,
1425
2493
  eventHandler
1426
2494
  }) => {
1427
- const { styles } = useStyles();
1428
- const config = useMemo2(
2495
+ const { styles } = useStyles2();
2496
+ const config = useMemo3(
1429
2497
  () => ({
1430
2498
  components: {
1431
2499
  a({ node, ...props }) {
1432
2500
  if (embeddedLink) {
1433
- return /* @__PURE__ */ jsx9(IFrameCard, { src: props.href });
1434
- } else return /* @__PURE__ */ jsx9("a", { ...props });
2501
+ return /* @__PURE__ */ jsx18(IFrameCard, { src: props.href });
2502
+ } else return /* @__PURE__ */ jsx18("a", { ...props });
1435
2503
  },
1436
2504
  table({ node, ...props }) {
1437
- return /* @__PURE__ */ jsx9("div", { className: styles.markdownTableContainer, children: /* @__PURE__ */ jsx9("table", { className: styles.markdownTable, ...props }) });
2505
+ return /* @__PURE__ */ jsx18("div", { className: styles.markdownTableContainer, children: /* @__PURE__ */ jsx18("table", { className: styles.markdownTable, ...props }) });
1438
2506
  },
1439
2507
  th({ node, ...props }) {
1440
- return /* @__PURE__ */ jsx9("th", { className: styles.markdownTh, ...props });
2508
+ return /* @__PURE__ */ jsx18("th", { className: styles.markdownTh, ...props });
1441
2509
  },
1442
2510
  td({ node, ...props }) {
1443
- return /* @__PURE__ */ jsx9("td", { className: styles.markdownTd, ...props });
2511
+ return /* @__PURE__ */ jsx18("td", { className: styles.markdownTd, ...props });
1444
2512
  },
1445
2513
  tr({ node, ...props }) {
1446
- return /* @__PURE__ */ jsx9("tr", { className: styles.markdownTr, ...props });
2514
+ return /* @__PURE__ */ jsx18("tr", { className: styles.markdownTr, ...props });
1447
2515
  },
1448
2516
  code({ children, className, node, ...rest }) {
1449
2517
  const match = /language-(\w+)/.exec(className || "");
@@ -1456,23 +2524,23 @@ var MDResponse = ({
1456
2524
  childrenData = JSON.parse(children);
1457
2525
  } catch (error) {
1458
2526
  }
1459
- return /* @__PURE__ */ jsx9(
2527
+ return /* @__PURE__ */ jsx18(
1460
2528
  Element,
1461
2529
  {
1462
2530
  interactive,
1463
2531
  component_key: language,
1464
2532
  data: childrenData,
1465
- eventHandler: (e, data, message2, agent) => {
1466
- eventHandler?.(e, data, message2, agent);
2533
+ eventHandler: (e, data, message3, agent) => {
2534
+ eventHandler?.(e, data, message3, agent);
1467
2535
  }
1468
2536
  }
1469
2537
  );
1470
2538
  }
1471
2539
  switch (language) {
1472
2540
  case "mermaid":
1473
- return /* @__PURE__ */ jsx9(MDMermaid, { children });
2541
+ return /* @__PURE__ */ jsx18(MDMermaid, { children });
1474
2542
  default:
1475
- return /* @__PURE__ */ jsx9(
2543
+ return /* @__PURE__ */ jsx18(
1476
2544
  SyntaxHighlighter,
1477
2545
  {
1478
2546
  ...rest,
@@ -1484,7 +2552,7 @@ var MDResponse = ({
1484
2552
  );
1485
2553
  }
1486
2554
  } else {
1487
- return /* @__PURE__ */ jsx9("code", { ...rest, className, children });
2555
+ return /* @__PURE__ */ jsx18("code", { ...rest, className, children });
1488
2556
  }
1489
2557
  }
1490
2558
  },
@@ -1493,15 +2561,15 @@ var MDResponse = ({
1493
2561
  }),
1494
2562
  [userData, interactive, embeddedLink, styles]
1495
2563
  );
1496
- return /* @__PURE__ */ jsx9("div", { className: styles.markdownContainer, children: /* @__PURE__ */ jsx9(ReactMarkdown, { ...config, children: content }) });
2564
+ return /* @__PURE__ */ jsx18("div", { className: styles.markdownContainer, children: /* @__PURE__ */ jsx18(ReactMarkdown, { ...config, children: content }) });
1497
2565
  };
1498
2566
  var MDViewFormItem = ({ value }) => {
1499
- return /* @__PURE__ */ jsx9(MDResponse, { content: value || "" });
2567
+ return /* @__PURE__ */ jsx18(MDResponse, { content: value || "" });
1500
2568
  };
1501
2569
  var IFrameCard = ({ src }) => {
1502
- const containerRef = useRef4(null);
1503
- const [width, setWidth] = useState7("640px");
1504
- const [height, setHeight] = useState7("320px");
2570
+ const containerRef = useRef5(null);
2571
+ const [width, setWidth] = useState11("640px");
2572
+ const [height, setHeight] = useState11("320px");
1505
2573
  const valid_images = [
1506
2574
  "jpg",
1507
2575
  "jpeg",
@@ -1518,19 +2586,20 @@ var IFrameCard = ({ src }) => {
1518
2586
  }
1519
2587
  const spitedSrc = src.split(".");
1520
2588
  if (valid_images.includes(spitedSrc[spitedSrc.length - 1].toLowerCase())) {
1521
- return /* @__PURE__ */ jsx9("div", { children: /* @__PURE__ */ jsx9("img", { src, style: { width: "100%" } }) });
2589
+ return /* @__PURE__ */ jsx18("div", { children: /* @__PURE__ */ jsx18("img", { src, style: { width: "100%" } }) });
1522
2590
  } else {
1523
- return /* @__PURE__ */ jsx9("div", { children: /* @__PURE__ */ jsx9("a", { href: src, target: "_black", children: src }) });
2591
+ return /* @__PURE__ */ jsx18("div", { children: /* @__PURE__ */ jsx18("a", { href: src, target: "_black", children: src }) });
1524
2592
  }
1525
2593
  };
1526
2594
 
1527
2595
  // src/components/Chat/Chating.tsx
1528
2596
  import {
1529
2597
  CloudUploadOutlined,
1530
- PaperClipOutlined
2598
+ PaperClipOutlined,
2599
+ FileTextOutlined as FileTextOutlined3
1531
2600
  } from "@ant-design/icons";
1532
2601
  import {
1533
- Attachments,
2602
+ Attachments as Attachments2,
1534
2603
  Bubble,
1535
2604
  Prompts,
1536
2605
  Sender,
@@ -1540,31 +2609,34 @@ import {
1540
2609
  Alert as Alert2,
1541
2610
  Avatar,
1542
2611
  Badge,
1543
- Button as Button3,
1544
- Flex as Flex3,
1545
- Space as Space6,
1546
- message
2612
+ Button as Button8,
2613
+ Flex as Flex5,
2614
+ Space as Space10,
2615
+ message as message2,
2616
+ Tooltip as Tooltip2,
2617
+ Popover,
2618
+ Progress
1547
2619
  } from "antd";
1548
2620
  import ErrorBoundary from "antd/es/alert/ErrorBoundary";
1549
- import React2, {
2621
+ import React4, {
1550
2622
  memo,
1551
- useCallback as useCallback5,
1552
- useEffect as useEffect5,
1553
- useMemo as useMemo3,
1554
- useRef as useRef5,
1555
- useState as useState8
2623
+ useCallback as useCallback6,
2624
+ useEffect as useEffect8,
2625
+ useMemo as useMemo4,
2626
+ useRef as useRef6,
2627
+ useState as useState12
1556
2628
  } from "react";
1557
2629
  import { useTranslation } from "react-i18next";
1558
- import { Fragment, jsx as jsx10, jsxs as jsxs6 } from "react/jsx-runtime";
2630
+ import { Fragment as Fragment3, jsx as jsx19, jsxs as jsxs13 } from "react/jsx-runtime";
1559
2631
  var LazyBubble = ({
1560
- message: message2,
2632
+ message: message3,
1561
2633
  renderContent,
1562
2634
  autoLoadRightPanel
1563
2635
  }) => {
1564
- const ref = useRef5(null);
1565
- const [isVisible, setIsVisible] = useState8(false);
1566
- const [wasEverVisible, setWasEverVisible] = useState8(false);
1567
- useEffect5(() => {
2636
+ const ref = useRef6(null);
2637
+ const [isVisible, setIsVisible] = useState12(false);
2638
+ const [wasEverVisible, setWasEverVisible] = useState12(false);
2639
+ useEffect8(() => {
1568
2640
  const observer = new IntersectionObserver(
1569
2641
  ([entry]) => {
1570
2642
  const visible = entry.isIntersecting;
@@ -1584,21 +2656,21 @@ var LazyBubble = ({
1584
2656
  }
1585
2657
  };
1586
2658
  }, [wasEverVisible]);
1587
- useEffect5(() => {
2659
+ useEffect8(() => {
1588
2660
  autoLoadRightPanel?.();
1589
2661
  }, []);
1590
2662
  const getPlaceholder = () => {
1591
- const estimatedHeight = message2.content ? Math.min(100, message2.content.length / 5) : 100;
1592
- return /* @__PURE__ */ jsx10("div", { style: { height: `${estimatedHeight}px`, minHeight: "50px" } });
2663
+ const estimatedHeight = message3.content ? Math.min(100, message3.content.length / 5) : 100;
2664
+ return /* @__PURE__ */ jsx19("div", { style: { height: `${estimatedHeight}px`, minHeight: "50px" } });
1593
2665
  };
1594
- return /* @__PURE__ */ jsx10(ErrorBoundary, { children: /* @__PURE__ */ jsx10("div", { ref, style: { width: "100%" }, children: isVisible || wasEverVisible ? renderContent(message2) : getPlaceholder() }) });
2666
+ return /* @__PURE__ */ jsx19(ErrorBoundary, { children: /* @__PURE__ */ jsx19("div", { ref, style: { width: "100%" }, children: isVisible || wasEverVisible ? renderContent(message3) : getPlaceholder() }) });
1595
2667
  };
1596
2668
  var MemoizedBubbleList = memo(
1597
2669
  ({
1598
2670
  items,
1599
2671
  roles,
1600
2672
  className
1601
- }) => /* @__PURE__ */ jsx10(
2673
+ }) => /* @__PURE__ */ jsx19(
1602
2674
  Bubble.List,
1603
2675
  {
1604
2676
  autoScroll: true,
@@ -1631,15 +2703,17 @@ var Chating = ({
1631
2703
  extra,
1632
2704
  attachment_placeholder,
1633
2705
  extraMeta = [],
1634
- uploadAction = "/api/file_storage/upload?path=temp"
2706
+ uploadAction = "/api/file_storage/upload?path=temp",
2707
+ files,
2708
+ todos
1635
2709
  }) => {
1636
2710
  const { t } = useTranslation();
1637
- const [content, setContent] = useState8("");
1638
- const [attachedFiles, setAttachedFiles] = useState8([]);
1639
- const [headerOpen, setHeaderOpen] = useState8(false);
1640
- const attachmentsRef = useRef5(null);
1641
- const senderRef = React2.useRef(null);
1642
- useEffect5(() => {
2711
+ const [content, setContent] = useState12("");
2712
+ const [attachedFiles, setAttachedFiles] = useState12([]);
2713
+ const [headerOpen, setHeaderOpen] = useState12(false);
2714
+ const attachmentsRef = useRef6(null);
2715
+ const senderRef = React4.useRef(null);
2716
+ useEffect8(() => {
1643
2717
  regsiterElement("action_show_attachments_uploader", {
1644
2718
  card_view: () => null,
1645
2719
  action: (data) => {
@@ -1648,19 +2722,19 @@ var Chating = ({
1648
2722
  }
1649
2723
  });
1650
2724
  }, []);
1651
- const messageLengthRef = useRef5(messages?.length ?? 0);
1652
- useEffect5(() => {
2725
+ const messageLengthRef = useRef6(messages?.length ?? 0);
2726
+ useEffect8(() => {
1653
2727
  if (messages?.length) {
1654
2728
  messageLengthRef.current = messages?.length;
1655
2729
  }
1656
2730
  }, [messages?.length]);
1657
- const renderContent = useCallback5(
1658
- (message2) => {
1659
- const { content: content2, files, id } = message2;
2731
+ const renderContent = useCallback6(
2732
+ (message3) => {
2733
+ const { content: content2, files: files2, id } = message3;
1660
2734
  try {
1661
2735
  const json = JSON.parse(content2);
1662
2736
  if (json.action && json.message) {
1663
- return /* @__PURE__ */ jsx10(
2737
+ return /* @__PURE__ */ jsx19(
1664
2738
  MDResponse,
1665
2739
  {
1666
2740
  content: json.message,
@@ -1670,13 +2744,13 @@ var Chating = ({
1670
2744
  }
1671
2745
  } catch (error2) {
1672
2746
  }
1673
- const tool_calls_md = message2.tool_calls?.map((tool_call) => {
2747
+ const tool_calls_md = message3.tool_calls?.map((tool_call) => {
1674
2748
  return `\`\`\`tool_call
1675
2749
  ${JSON.stringify(tool_call)}
1676
2750
  \`\`\``;
1677
2751
  }) || [];
1678
2752
  const content_md = [content2, ...tool_calls_md].join("\n");
1679
- return /* @__PURE__ */ jsx10(Space6, { direction: "vertical", style: { width: "100%" }, children: /* @__PURE__ */ jsx10(
2753
+ return /* @__PURE__ */ jsx19(Space10, { direction: "vertical", style: { width: "100%" }, children: /* @__PURE__ */ jsx19(
1680
2754
  MDResponse,
1681
2755
  {
1682
2756
  content: content_md,
@@ -1686,18 +2760,18 @@ ${JSON.stringify(tool_call)}
1686
2760
  },
1687
2761
  [handleMDResponseEvent]
1688
2762
  );
1689
- const items = useMemo3(
1690
- () => messages.map((message2, index) => ({
1691
- key: message2.id,
1692
- role: message2.role,
2763
+ const items = useMemo4(
2764
+ () => messages.map((message3, index) => ({
2765
+ key: message3.id,
2766
+ role: message3.role,
1693
2767
  typing: false,
1694
- content: /* @__PURE__ */ jsx10(
2768
+ content: /* @__PURE__ */ jsx19(
1695
2769
  LazyBubble,
1696
2770
  {
1697
- message: message2,
2771
+ message: message3,
1698
2772
  renderContent,
1699
2773
  autoLoadRightPanel: () => {
1700
- const { content: content2, role } = message2;
2774
+ const { content: content2, role } = message3;
1701
2775
  const isNewAddedMessage = messageLengthRef.current > 1 && messageLengthRef.current + 1 === messages.length;
1702
2776
  if (index === messages.length - 1 && isNewAddedMessage && role === "ai") {
1703
2777
  try {
@@ -1741,13 +2815,13 @@ ${JSON.stringify(tool_call)}
1741
2815
  const onSubmit = (nextContent) => {
1742
2816
  if (!nextContent && attachedFiles.length === 0) return;
1743
2817
  if (attachedFiles.filter((f) => f.status !== "done").length > 0) {
1744
- message.warning("\u6587\u4EF6\u8FD8\u5728\u4E0A\u4F20\u4E2D...");
2818
+ message2.warning("\u6587\u4EF6\u8FD8\u5728\u4E0A\u4F20\u4E2D...");
1745
2819
  return;
1746
2820
  }
1747
2821
  if (!nextContent && attachedFiles.length > 0) {
1748
2822
  nextContent = default_submit_message || "\u8BB0\u8D26";
1749
2823
  }
1750
- const files = attachedFiles.map(
2824
+ const files2 = attachedFiles.map(
1751
2825
  (file) => isArchiveFile(file) ? {
1752
2826
  name: file.response.zipFileName || file.response.rarFileName,
1753
2827
  id: file.response.zipFileId || file.response.rarFileId,
@@ -1765,14 +2839,14 @@ ${JSON.stringify(tool_call)}
1765
2839
  id: file.response.id
1766
2840
  }
1767
2841
  );
1768
- const files_md = files.length > 0 ? [
2842
+ const files_md = files2.length > 0 ? [
1769
2843
  "",
1770
2844
  "\u6211\u5DF2\u7ECF\u63D0\u4EA4\u4E86\u4EE5\u4E0B\u6587\u4EF6\uFF1A",
1771
2845
  "```attachments",
1772
- JSON.stringify(files),
2846
+ JSON.stringify(files2),
1773
2847
  "```"
1774
2848
  ].join("\n") : "";
1775
- sendMessage({ input: { message: nextContent + files_md, files } });
2849
+ sendMessage({ input: { message: nextContent + files_md, files: files2 } });
1776
2850
  setContent("");
1777
2851
  setAttachedFiles([]);
1778
2852
  setHeaderOpen(false);
@@ -1785,7 +2859,7 @@ ${JSON.stringify(tool_call)}
1785
2859
  setHeaderOpen(true);
1786
2860
  }
1787
2861
  if (info.file?.response?.error || info.file.status === "error") {
1788
- message.error(
2862
+ message2.error(
1789
2863
  `${info.file.name} file upload failed.${info.file?.response?.message}`
1790
2864
  );
1791
2865
  }
@@ -1797,22 +2871,22 @@ ${JSON.stringify(tool_call)}
1797
2871
  const beforeUpload = (file) => {
1798
2872
  const isLessThan20MB = file.size / 1024 / 1024 < 20;
1799
2873
  if (!isLessThan20MB) {
1800
- message.error(
2874
+ message2.error(
1801
2875
  `File must be smaller than 20MB! ${file.name} is too large.`
1802
2876
  );
1803
2877
  return false;
1804
2878
  }
1805
2879
  return true;
1806
2880
  };
1807
- const attachmentsNode = /* @__PURE__ */ jsx10(Badge, { dot: attachedFiles.length > 0 && !headerOpen, children: /* @__PURE__ */ jsx10(
1808
- Button3,
2881
+ const attachmentsNode = /* @__PURE__ */ jsx19(Badge, { dot: attachedFiles.length > 0 && !headerOpen, children: /* @__PURE__ */ jsx19(
2882
+ Button8,
1809
2883
  {
1810
2884
  type: "text",
1811
- icon: /* @__PURE__ */ jsx10(PaperClipOutlined, {}),
2885
+ icon: /* @__PURE__ */ jsx19(PaperClipOutlined, {}),
1812
2886
  onClick: () => setHeaderOpen(!headerOpen)
1813
2887
  }
1814
2888
  ) });
1815
- const senderHeader = /* @__PURE__ */ jsx10(
2889
+ const senderHeader = /* @__PURE__ */ jsx19(
1816
2890
  Sender.Header,
1817
2891
  {
1818
2892
  title: "Attachments",
@@ -1824,8 +2898,8 @@ ${JSON.stringify(tool_call)}
1824
2898
  }
1825
2899
  },
1826
2900
  forceRender: true,
1827
- children: /* @__PURE__ */ jsx10(
1828
- Attachments,
2901
+ children: /* @__PURE__ */ jsx19(
2902
+ Attachments2,
1829
2903
  {
1830
2904
  ref: attachmentsRef,
1831
2905
  items: attachedFiles,
@@ -1846,7 +2920,7 @@ ${JSON.stringify(tool_call)}
1846
2920
  multiple: true,
1847
2921
  maxCount: 10,
1848
2922
  placeholder: (type) => ({
1849
- icon: /* @__PURE__ */ jsx10(CloudUploadOutlined, {}),
2923
+ icon: /* @__PURE__ */ jsx19(CloudUploadOutlined, {}),
1850
2924
  title: "\u4E0A\u4F20\u6587\u4EF6",
1851
2925
  description: attachment_placeholder
1852
2926
  })
@@ -1878,7 +2952,7 @@ ${JSON.stringify(tool_call)}
1878
2952
  }
1879
2953
  }
1880
2954
  };
1881
- const extraMetaComponents = useMemo3(() => {
2955
+ const extraMetaComponents = useMemo4(() => {
1882
2956
  if (extraMeta?.length > 0) {
1883
2957
  return extraMeta.map((meta) => {
1884
2958
  const Element = getElement(meta.id)?.card_view;
@@ -1887,13 +2961,13 @@ ${JSON.stringify(tool_call)}
1887
2961
  try {
1888
2962
  } catch (error2) {
1889
2963
  }
1890
- return /* @__PURE__ */ jsx10(
2964
+ return /* @__PURE__ */ jsx19(
1891
2965
  Element,
1892
2966
  {
1893
2967
  component_key: meta.id,
1894
2968
  data: childrenData,
1895
- eventHandler: (e, data, message2, agent) => {
1896
- handleMDResponseEvent?.(e, data, message2, agent);
2969
+ eventHandler: (e, data, message3, agent) => {
2970
+ handleMDResponseEvent?.(e, data, message3, agent);
1897
2971
  }
1898
2972
  },
1899
2973
  meta.id
@@ -1903,20 +2977,98 @@ ${JSON.stringify(tool_call)}
1903
2977
  }
1904
2978
  return void 0;
1905
2979
  }, [extraMeta]);
1906
- return /* @__PURE__ */ jsxs6(Fragment, { children: [
1907
- /* @__PURE__ */ jsxs6("div", { children: [
1908
- /* @__PURE__ */ jsx10(
2980
+ return /* @__PURE__ */ jsxs13(Fragment3, { children: [
2981
+ /* @__PURE__ */ jsxs13("div", { children: [
2982
+ /* @__PURE__ */ jsx19(
1909
2983
  Welcome,
1910
2984
  {
1911
2985
  style: { padding: 8 },
1912
2986
  variant: "borderless",
1913
2987
  description,
1914
- icon: /* @__PURE__ */ jsx10(Avatar, { src: avatar || "/images/avatar.jpeg", size: 48 }),
2988
+ icon: /* @__PURE__ */ jsx19(Avatar, { src: avatar || "/images/avatar.jpeg", size: 48 }),
1915
2989
  title: name || "Fina",
1916
- extra: extra || extraMetaComponents && /* @__PURE__ */ jsx10(Space6, { align: "center", style: { marginRight: 16 }, children: extraMetaComponents })
2990
+ extra: /* @__PURE__ */ jsxs13(Space10, { children: [
2991
+ extra,
2992
+ todos && todos.length > 0 && /* @__PURE__ */ jsx19(
2993
+ Popover,
2994
+ {
2995
+ content: /* @__PURE__ */ jsx19("div", { style: { width: 400 }, children: /* @__PURE__ */ jsx19(
2996
+ Todo,
2997
+ {
2998
+ data: todos,
2999
+ component_key: "header_todos",
3000
+ eventHandler: handleMDResponseEvent
3001
+ }
3002
+ ) }),
3003
+ title: "Todos",
3004
+ trigger: "click",
3005
+ placement: "bottomRight",
3006
+ children: /* @__PURE__ */ jsx19(
3007
+ Tooltip2,
3008
+ {
3009
+ title: `${todos.filter((item) => item.status === "completed").length} / ${todos.length} tasks completed`,
3010
+ children: /* @__PURE__ */ jsx19("div", { style: { cursor: "pointer", display: "inline-flex" }, children: /* @__PURE__ */ jsx19(
3011
+ Progress,
3012
+ {
3013
+ type: "circle",
3014
+ strokeColor: {
3015
+ "0%": "#91caff",
3016
+ "100%": "#003eb3"
3017
+ },
3018
+ percent: Math.round(
3019
+ todos.filter((item) => item.status === "completed").length / todos.length * 100
3020
+ ),
3021
+ status: todos.some((item) => item.status === "in_progress") ? "active" : "normal",
3022
+ width: 30,
3023
+ format: () => /* @__PURE__ */ jsx19(
3024
+ "div",
3025
+ {
3026
+ style: {
3027
+ display: "flex",
3028
+ flexDirection: "column",
3029
+ alignItems: "center",
3030
+ lineHeight: 1
3031
+ },
3032
+ children: /* @__PURE__ */ jsxs13("span", { style: { fontSize: 8 }, children: [
3033
+ todos.filter(
3034
+ (item) => item.status === "completed"
3035
+ ).length,
3036
+ "/",
3037
+ todos.length
3038
+ ] })
3039
+ }
3040
+ )
3041
+ }
3042
+ ) })
3043
+ }
3044
+ )
3045
+ }
3046
+ ),
3047
+ files && Object.keys(files).length > 0 && /* @__PURE__ */ jsx19(Tooltip2, { title: "File Explorer", children: /* @__PURE__ */ jsx19(
3048
+ Badge,
3049
+ {
3050
+ count: Object.keys(files).length,
3051
+ size: "small",
3052
+ color: "blue",
3053
+ children: /* @__PURE__ */ jsx19(
3054
+ Button8,
3055
+ {
3056
+ type: "text",
3057
+ icon: /* @__PURE__ */ jsx19(FileTextOutlined3, {}),
3058
+ onClick: () => onOpenSidePanel({
3059
+ component_key: "file_explorer",
3060
+ message: "File Explorer",
3061
+ data: { files }
3062
+ })
3063
+ }
3064
+ )
3065
+ }
3066
+ ) }),
3067
+ extraMetaComponents && /* @__PURE__ */ jsx19(Space10, { align: "center", style: { marginRight: 16 }, children: extraMetaComponents })
3068
+ ] })
1917
3069
  }
1918
3070
  ),
1919
- /* @__PURE__ */ jsx10(
3071
+ /* @__PURE__ */ jsx19(
1920
3072
  "div",
1921
3073
  {
1922
3074
  style: {
@@ -1925,16 +3077,16 @@ ${JSON.stringify(tool_call)}
1925
3077
  }
1926
3078
  )
1927
3079
  ] }),
1928
- items.length > 0 ? /* @__PURE__ */ jsx10(
3080
+ items.length > 0 ? /* @__PURE__ */ jsx19(
1929
3081
  MemoizedBubbleList,
1930
3082
  {
1931
3083
  items,
1932
3084
  roles,
1933
3085
  className: styles.messages
1934
3086
  }
1935
- ) : /* @__PURE__ */ jsx10("div", { style: { flex: 1 } }),
1936
- isLoading ? /* @__PURE__ */ jsx10("div", { children: /* @__PURE__ */ jsx10(Bubble, { loading: isLoading, variant: "borderless" }) }) : /* @__PURE__ */ jsx10(Prompts, { items: senderPromptsItems, onItemClick: onPromptsItemClick }),
1937
- error && /* @__PURE__ */ jsx10("div", { style: { padding: "0 16px 8px" }, children: /* @__PURE__ */ jsx10(
3087
+ ) : /* @__PURE__ */ jsx19("div", { style: { flex: 1 } }),
3088
+ isLoading ? /* @__PURE__ */ jsx19("div", { children: /* @__PURE__ */ jsx19(Bubble, { loading: isLoading, variant: "borderless" }) }) : /* @__PURE__ */ jsx19(Prompts, { items: senderPromptsItems, onItemClick: onPromptsItemClick }),
3089
+ error && /* @__PURE__ */ jsx19("div", { style: { padding: "0 16px 8px" }, children: /* @__PURE__ */ jsx19(
1938
3090
  Alert2,
1939
3091
  {
1940
3092
  type: "error",
@@ -1944,7 +3096,7 @@ ${JSON.stringify(tool_call)}
1944
3096
  message: `${error.message}`
1945
3097
  }
1946
3098
  ) }),
1947
- /* @__PURE__ */ jsx10(
3099
+ /* @__PURE__ */ jsx19(
1948
3100
  Sender,
1949
3101
  {
1950
3102
  allowSpeech: true,
@@ -1959,7 +3111,7 @@ ${JSON.stringify(tool_call)}
1959
3111
  className: styles.sender,
1960
3112
  actions: (ori, { components }) => {
1961
3113
  const { SendButton, LoadingButton } = components;
1962
- return /* @__PURE__ */ jsx10(Flex3, { justify: "space-between", align: "center", children: isLoading ? /* @__PURE__ */ jsx10(LoadingButton, { type: "default" }) : /* @__PURE__ */ jsx10(
3114
+ return /* @__PURE__ */ jsx19(Flex5, { justify: "space-between", align: "center", children: isLoading ? /* @__PURE__ */ jsx19(LoadingButton, { type: "default" }) : /* @__PURE__ */ jsx19(
1963
3115
  SendButton,
1964
3116
  {
1965
3117
  type: "primary",
@@ -1968,8 +3120,8 @@ ${JSON.stringify(tool_call)}
1968
3120
  }
1969
3121
  ) });
1970
3122
  },
1971
- onPasteFile: (_, files) => {
1972
- Array.from(files).forEach((file) => {
3123
+ onPasteFile: (_, files2) => {
3124
+ Array.from(files2).forEach((file) => {
1973
3125
  attachmentsRef.current?.upload(file);
1974
3126
  });
1975
3127
  setHeaderOpen(true);
@@ -1983,54 +3135,54 @@ ${JSON.stringify(tool_call)}
1983
3135
  import {
1984
3136
  CheckCircleOutlined as CheckCircleOutlined3,
1985
3137
  InfoCircleOutlined as InfoCircleOutlined2,
1986
- LoadingOutlined as LoadingOutlined3
3138
+ LoadingOutlined as LoadingOutlined4
1987
3139
  } from "@ant-design/icons";
1988
3140
  import {
1989
3141
  ThoughtChain
1990
3142
  } from "@ant-design/x";
1991
- import { jsx as jsx11 } from "react/jsx-runtime";
3143
+ import { jsx as jsx20 } from "react/jsx-runtime";
1992
3144
  function getStatusIcon2(status) {
1993
3145
  switch (status) {
1994
3146
  case "success":
1995
- return /* @__PURE__ */ jsx11(CheckCircleOutlined3, {});
3147
+ return /* @__PURE__ */ jsx20(CheckCircleOutlined3, {});
1996
3148
  case "error":
1997
- return /* @__PURE__ */ jsx11(InfoCircleOutlined2, {});
3149
+ return /* @__PURE__ */ jsx20(InfoCircleOutlined2, {});
1998
3150
  case "pending":
1999
- return /* @__PURE__ */ jsx11(LoadingOutlined3, {});
3151
+ return /* @__PURE__ */ jsx20(LoadingOutlined4, {});
2000
3152
  default:
2001
- return /* @__PURE__ */ jsx11(CheckCircleOutlined3, {});
3153
+ return /* @__PURE__ */ jsx20(CheckCircleOutlined3, {});
2002
3154
  }
2003
3155
  }
2004
- var ThinkingChain = ({ message: message2 }) => {
2005
- const title = message2.name || message2.content.split("\n")[0];
3156
+ var ThinkingChain = ({ message: message3 }) => {
3157
+ const title = message3.name || message3.content.split("\n")[0];
2006
3158
  const items = [
2007
3159
  {
2008
- key: message2.id,
3160
+ key: message3.id,
2009
3161
  title,
2010
- content: /* @__PURE__ */ jsx11(MDResponse, { content: message2.content }),
2011
- status: message2.status,
2012
- icon: getStatusIcon2(message2.status)
3162
+ content: /* @__PURE__ */ jsx20(MDResponse, { content: message3.content }),
3163
+ status: message3.status,
3164
+ icon: getStatusIcon2(message3.status)
2013
3165
  }
2014
3166
  ];
2015
- return /* @__PURE__ */ jsx11(
3167
+ return /* @__PURE__ */ jsx20(
2016
3168
  ThoughtChain,
2017
3169
  {
2018
3170
  items,
2019
- collapsible: message2.status === "success" ? true : false,
3171
+ collapsible: message3.status === "success" ? true : false,
2020
3172
  size: "small"
2021
3173
  }
2022
3174
  );
2023
3175
  };
2024
- var ThinkingChainGroup = ({ message: message2 }) => {
3176
+ var ThinkingChainGroup = ({ message: message3 }) => {
2025
3177
  const title = "\u601D\u8003\u8FC7\u7A0B";
2026
- const children = message2.items?.map((item) => ({
3178
+ const children = message3.items?.map((item) => ({
2027
3179
  key: item.id,
2028
3180
  title: item.name || item.content.split("\n")[0],
2029
- content: /* @__PURE__ */ jsx11(MDResponse, { content: item.content }),
3181
+ content: /* @__PURE__ */ jsx20(MDResponse, { content: item.content }),
2030
3182
  status: item.status,
2031
3183
  icon: getStatusIcon2(item.status)
2032
3184
  }));
2033
- return /* @__PURE__ */ jsx11(ThoughtChain, { items: children, collapsible: true, size: "small" });
3185
+ return /* @__PURE__ */ jsx20(ThoughtChain, { items: children, collapsible: true, size: "small" });
2034
3186
  };
2035
3187
 
2036
3188
  // src/components/Chat/SideAppViewBrowser.tsx
@@ -2040,11 +3192,11 @@ import {
2040
3192
  ExpandOutlined,
2041
3193
  FullscreenOutlined
2042
3194
  } from "@ant-design/icons";
2043
- import { Button as Button4, Tabs } from "antd";
2044
- import { createStyles as createStyles5 } from "antd-style";
2045
- import { useEffect as useEffect6, useState as useState9 } from "react";
2046
- import { jsx as jsx12, jsxs as jsxs7 } from "react/jsx-runtime";
2047
- var useStyle4 = createStyles5(({ token, css }) => {
3195
+ import { Button as Button9, Tabs } from "antd";
3196
+ import { createStyles as createStyles7 } from "antd-style";
3197
+ import { useEffect as useEffect9, useState as useState13 } from "react";
3198
+ import { jsx as jsx21, jsxs as jsxs14 } from "react/jsx-runtime";
3199
+ var useStyle5 = createStyles7(({ token, css }) => {
2048
3200
  return {
2049
3201
  tabContainer: css`
2050
3202
  .ant-tabs-content-holder {
@@ -2063,9 +3215,9 @@ var useStyle4 = createStyles5(({ token, css }) => {
2063
3215
  };
2064
3216
  });
2065
3217
  var EmptySideAppView = ({ component_key, data }) => {
2066
- return /* @__PURE__ */ jsxs7("div", { children: [
2067
- /* @__PURE__ */ jsx12("p", { children: "\u672A\u627E\u5230\u5BF9\u5E94\u7684\u7EC4\u4EF6\u89C6\u56FE" }),
2068
- /* @__PURE__ */ jsx12("pre", { children: JSON.stringify({ component_key, data }, null, 2) })
3218
+ return /* @__PURE__ */ jsxs14("div", { children: [
3219
+ /* @__PURE__ */ jsx21("p", { children: "\u672A\u627E\u5230\u5BF9\u5E94\u7684\u7EC4\u4EF6\u89C6\u56FE" }),
3220
+ /* @__PURE__ */ jsx21("pre", { children: JSON.stringify({ component_key, data }, null, 2) })
2069
3221
  ] });
2070
3222
  };
2071
3223
  var SideAppViewBrowser = ({
@@ -2074,10 +3226,10 @@ var SideAppViewBrowser = ({
2074
3226
  onClose,
2075
3227
  onChangeSize
2076
3228
  }) => {
2077
- const { styles } = useStyle4();
2078
- const [activeKey, setActiveKey] = useState9(JSON.stringify(open_uri));
2079
- const [currentSize, setCurrentSize] = useState9(open_uri.size || "large");
2080
- const [items, setItems] = useState9([]);
3229
+ const { styles } = useStyle5();
3230
+ const [activeKey, setActiveKey] = useState13(JSON.stringify(open_uri));
3231
+ const [currentSize, setCurrentSize] = useState13(open_uri.size || "large");
3232
+ const [items, setItems] = useState13([]);
2081
3233
  const add = (key, label, children) => {
2082
3234
  const newActiveKey = key;
2083
3235
  const newPanes = [...items];
@@ -2113,7 +3265,7 @@ var SideAppViewBrowser = ({
2113
3265
  remove(targetKey);
2114
3266
  }
2115
3267
  };
2116
- useEffect6(() => {
3268
+ useEffect9(() => {
2117
3269
  const SideAppView = getElement(open_uri.component_key).side_app_view || EmptySideAppView;
2118
3270
  const key = JSON.stringify(open_uri);
2119
3271
  if (items.find((item) => item.key === key)) {
@@ -2123,7 +3275,7 @@ var SideAppViewBrowser = ({
2123
3275
  add(
2124
3276
  key,
2125
3277
  open_uri.message || open_uri.data.message || "\u672A\u547D\u540D",
2126
- /* @__PURE__ */ jsx12(
3278
+ /* @__PURE__ */ jsx21(
2127
3279
  SideAppView,
2128
3280
  {
2129
3281
  component_key: open_uri.component_key,
@@ -2133,7 +3285,7 @@ var SideAppViewBrowser = ({
2133
3285
  )
2134
3286
  );
2135
3287
  }, [open_uri]);
2136
- useEffect6(() => {
3288
+ useEffect9(() => {
2137
3289
  if (open_uri.size && open_uri.size !== currentSize) {
2138
3290
  setCurrentSize(open_uri.size);
2139
3291
  }
@@ -2171,16 +3323,16 @@ var SideAppViewBrowser = ({
2171
3323
  const getSizeIcon = (size) => {
2172
3324
  switch (size) {
2173
3325
  case "middle":
2174
- return /* @__PURE__ */ jsx12(CompressOutlined, {});
3326
+ return /* @__PURE__ */ jsx21(CompressOutlined, {});
2175
3327
  case "large":
2176
- return /* @__PURE__ */ jsx12(ExpandOutlined, {});
3328
+ return /* @__PURE__ */ jsx21(ExpandOutlined, {});
2177
3329
  case "full":
2178
- return /* @__PURE__ */ jsx12(FullscreenOutlined, {});
3330
+ return /* @__PURE__ */ jsx21(FullscreenOutlined, {});
2179
3331
  default:
2180
- return /* @__PURE__ */ jsx12(ExpandOutlined, {});
3332
+ return /* @__PURE__ */ jsx21(ExpandOutlined, {});
2181
3333
  }
2182
3334
  };
2183
- return /* @__PURE__ */ jsx12(
3335
+ return /* @__PURE__ */ jsx21(
2184
3336
  Tabs,
2185
3337
  {
2186
3338
  className: styles.tabContainer,
@@ -2188,9 +3340,9 @@ var SideAppViewBrowser = ({
2188
3340
  style: { height: "100%" },
2189
3341
  hideAdd: true,
2190
3342
  tabBarExtraContent: {
2191
- right: /* @__PURE__ */ jsxs7("div", { style: { display: "flex", gap: "4px" }, children: [
2192
- /* @__PURE__ */ jsx12(
2193
- Button4,
3343
+ right: /* @__PURE__ */ jsxs14("div", { style: { display: "flex", gap: "4px" }, children: [
3344
+ /* @__PURE__ */ jsx21(
3345
+ Button9,
2194
3346
  {
2195
3347
  style: { margin: "8px 0" },
2196
3348
  size: "large",
@@ -2200,13 +3352,13 @@ var SideAppViewBrowser = ({
2200
3352
  title: `\u5F53\u524D\u5C3A\u5BF8: ${getSizeLabel(currentSize)}, \u70B9\u51FB\u5207\u6362`
2201
3353
  }
2202
3354
  ),
2203
- /* @__PURE__ */ jsx12(
2204
- Button4,
3355
+ /* @__PURE__ */ jsx21(
3356
+ Button9,
2205
3357
  {
2206
3358
  style: { margin: "8px 0" },
2207
3359
  size: "large",
2208
3360
  type: "text",
2209
- icon: /* @__PURE__ */ jsx12(CloseOutlined, {}),
3361
+ icon: /* @__PURE__ */ jsx21(CloseOutlined, {}),
2210
3362
  onClick: () => {
2211
3363
  onClose();
2212
3364
  }
@@ -2225,12 +3377,13 @@ var SideAppViewBrowser = ({
2225
3377
  // src/components/Chat/context.tsx
2226
3378
  import { createContext as createContext2 } from "react";
2227
3379
  var chatContext = createContext2({
2228
- eventHandler: (component_key, data, message2) => {
3380
+ eventHandler: (component_key, data, message3) => {
2229
3381
  }
2230
3382
  });
2231
3383
  export {
2232
3384
  AxiomLatticeProvider,
2233
3385
  Chating,
3386
+ FileExplorer,
2234
3387
  MDMermaid,
2235
3388
  MDResponse,
2236
3389
  MDViewFormItem,
@@ -2238,7 +3391,6 @@ export {
2238
3391
  ThinkingChain,
2239
3392
  ThinkingChainGroup,
2240
3393
  chatContext,
2241
- elements,
2242
3394
  getElement,
2243
3395
  regsiterElement,
2244
3396
  useAgentGraph,