@zero-library/chat-copilot 3.1.10 → 3.1.11

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.esm.js CHANGED
@@ -1,7 +1,7 @@
1
- import { CloudUploadOutlined, PaperClipOutlined, createFromIconfontCN, LoadingOutlined, EnterOutlined, DownloadOutlined, CloseOutlined, PlayCircleOutlined, CopyOutlined, DotChartOutlined, LikeOutlined, DislikeOutlined, ToolOutlined, SearchOutlined, UpOutlined, DownOutlined, PlusOutlined, CommentOutlined, RedoOutlined, DeleteOutlined, ClockCircleOutlined, CheckCircleOutlined, FileImageOutlined, FilePdfOutlined, FileWordOutlined, FileExcelOutlined, FilePptOutlined, FileZipOutlined, FileTextOutlined, FileUnknownOutlined } from '@ant-design/icons';
1
+ import { CloudUploadOutlined, PaperClipOutlined, createFromIconfontCN, EnterOutlined, DownloadOutlined, CloseOutlined, PlayCircleOutlined, CopyOutlined, DotChartOutlined, LoadingOutlined, RightOutlined, LikeOutlined, DislikeOutlined, ToolOutlined, SearchOutlined, UpOutlined, DownOutlined, PlusOutlined, CommentOutlined, RedoOutlined, DeleteOutlined, ClockCircleOutlined, CheckCircleOutlined, FileImageOutlined, FilePdfOutlined, FileWordOutlined, FileExcelOutlined, FilePptOutlined, FileZipOutlined, FileTextOutlined, FileUnknownOutlined } from '@ant-design/icons';
2
2
  import { Attachments, Sender, FileCard, Bubble, Think, XProvider, Mermaid, CodeHighlighter, Welcome, Prompts, Conversations } from '@ant-design/x-v2';
3
3
  import { useRefState, useDebounce, createTokenManager, useSyncInput, isEmptyObj, markdownToText, RenderWrapper, shouldRender, isFunction, downloadFile, LuyaFilePreview, MarkdownEditor, useDeepEffect, isObject, useWebSocket, isNullOrUnDef, isNumber, getFileSuffixName, emit, FileIcon, copyText, LazyComponent, isBoolean, UserAvatar, htmlToMarkdown, buildUrlParams, isExternal, deepCopy, transforms, deepMerge, createRequest, HttpStatus, isArray, isString, isDef, isNull, transform, getWebSocketUrl, safeParseJson } from '@zero-library/common';
4
- import { App, Badge, Button, Flex, Typography, Tooltip, Layout, Tag, Spin, Splitter, Image as Image$1, Popover, Skeleton, Alert, theme, Collapse, Divider as Divider$1, Select as Select$1, Avatar, Space, Form, Drawer, Empty, Modal, Checkbox, Input, InputNumber, Switch as Switch$1, message, List, Upload, Card, Table, Progress as Progress$1 } from 'antd';
4
+ import { App, Badge, Button, Flex, Typography, Tooltip, Layout, Tag, Spin, Splitter, Image as Image$1, Popover, Skeleton, Alert, theme, Collapse, Divider as Divider$1, Select as Select$1, Avatar, Space, Form, Drawer, Empty, Modal, Checkbox, Input, InputNumber, Switch as Switch$1, message, Upload, List, Card, Table, Progress as Progress$1 } from 'antd';
5
5
  import * as React10 from 'react';
6
6
  import React10__default, { createContext, forwardRef, useRef, useEffect, useImperativeHandle, useMemo, memo, useState, useContext, useCallback, useLayoutEffect } from 'react';
7
7
  import { useSnapshot, proxy } from 'valtio';
@@ -1372,9 +1372,14 @@ function createChatStore() {
1372
1372
  });
1373
1373
  conversation.messages[conversationId].message = [];
1374
1374
  if (data?.length) {
1375
- data.forEach((msg) => {
1375
+ const mainMessages = data.filter((msg) => !msg.toolCallId);
1376
+ const subAgentMessages = data.filter((msg) => msg.toolCallId);
1377
+ mainMessages.forEach((msg) => {
1376
1378
  processMessageContent(msg);
1377
1379
  });
1380
+ subAgentMessages.forEach((msg) => {
1381
+ routeSubAgentMessage(msg);
1382
+ });
1378
1383
  finalizeHistoryMessages(conversationId);
1379
1384
  normalizeMessagesByExecutionAndRole(conversation.messages[conversationId].message);
1380
1385
  }
@@ -1440,9 +1445,7 @@ function createChatStore() {
1440
1445
  item.generating = false;
1441
1446
  });
1442
1447
  }
1443
- function startCallback(msg) {
1444
- const messages = conversation.messages[msg.conversationId]?.message;
1445
- if (!messages) return;
1448
+ function startCallback(msg, messages, isMain) {
1446
1449
  const idx = findExecutionMsgIndex(msg, messages);
1447
1450
  const contentItem = msg.content[0];
1448
1451
  if (contentItem.type !== "runStarted") return;
@@ -1453,23 +1456,24 @@ function createChatStore() {
1453
1456
  generating: true
1454
1457
  };
1455
1458
  messages.push(finalMsg);
1456
- const targetConversation = conversations.list.items.find((item) => item.id === msg.conversationId);
1457
- if (targetConversation && msg.createdAt) {
1458
- updateConversations({
1459
- ...targetConversation,
1460
- id: targetConversation.id,
1461
- title: targetConversation.label,
1462
- updatedAt: msg.createdAt
1463
- });
1459
+ if (isMain) {
1460
+ const targetConversation = conversations.list.items.find((item) => item.id === msg.conversationId);
1461
+ if (targetConversation && msg.createdAt) {
1462
+ updateConversations({
1463
+ ...targetConversation,
1464
+ id: targetConversation.id,
1465
+ title: targetConversation.label,
1466
+ updatedAt: msg.createdAt
1467
+ });
1468
+ }
1464
1469
  }
1465
1470
  } else {
1466
1471
  const prevContent = messages[idx]?.content || [];
1467
1472
  messages[idx].content = [...prevContent, contentItem];
1468
1473
  }
1469
- conversation.messages[msg.conversationId].loading = true;
1474
+ if (isMain) conversation.messages[msg.conversationId].loading = true;
1470
1475
  }
1471
- function textCallback(msg) {
1472
- const messages = conversation.messages[msg.conversationId]?.message;
1476
+ function textCallback(msg, messages, isMain) {
1473
1477
  const idx = findExecutionMsgIndex(msg, messages);
1474
1478
  const contents = idx !== -1 && messages[idx] ? messages[idx].content || [] : [];
1475
1479
  const nextContent = msg.content[0];
@@ -1498,13 +1502,12 @@ function createChatStore() {
1498
1502
  messages[idx].content = [...contents, normalizedNextContent];
1499
1503
  }
1500
1504
  }
1501
- conversation.messages[msg.conversationId].loading = true;
1505
+ if (isMain) conversation.messages[msg.conversationId].loading = true;
1502
1506
  }
1503
- function stepStartedCallback(msg) {
1504
- const messages = conversation.messages[msg.conversationId]?.message;
1507
+ function stepStartedCallback(msg, messages, isMain) {
1505
1508
  const idx = findExecutionMsgIndex(msg, messages);
1506
1509
  const contentItem = msg.content[0];
1507
- conversation.messages[msg.conversationId].loading = true;
1510
+ if (isMain) conversation.messages[msg.conversationId].loading = true;
1508
1511
  if (idx !== -1 && messages[idx]) {
1509
1512
  const contentList = messages[idx].content || [];
1510
1513
  const runStartedIndex = contentList.findIndex((item) => item.type === "runStarted");
@@ -1514,38 +1517,34 @@ function createChatStore() {
1514
1517
  messages[idx].content = contentList.map((item, i) => i === runStartedIndex ? nextRunStartedItem : item);
1515
1518
  }
1516
1519
  }
1520
+ if (isMain) config.hooks?.onStepMessage?.(msg);
1517
1521
  config.hooks?.onStepMessage?.(msg);
1518
1522
  }
1519
- function stepFinishedCallback(msg) {
1520
- conversation.messages[msg.conversationId].loading = true;
1521
- config.hooks?.onStepMessage?.(msg);
1523
+ function stepFinishedCallback(msg, _messages, isMain) {
1524
+ if (isMain) conversation.messages[msg.conversationId].loading = true;
1525
+ if (isMain) config.hooks?.onStepMessage?.(msg);
1522
1526
  }
1523
- function stepErrCallback(msg) {
1524
- conversation.messages[msg.conversationId].loading = false;
1525
- const messages = conversation.messages[msg.conversationId]?.message;
1526
- if (messages) {
1527
- const idx = findExecutionMsgIndex(msg, messages);
1528
- const contentItem = msg.content[0];
1529
- messages.forEach((item) => {
1530
- if (item.executionId === msg.executionId) {
1531
- item.generating = false;
1532
- }
1533
- });
1534
- if (idx !== -1) {
1535
- messages[idx].generating = false;
1536
- }
1537
- if (idx !== -1) {
1538
- const prevContent = messages[idx]?.content || [];
1539
- messages[idx].content = [...prevContent, contentItem];
1540
- } else {
1541
- const finalMsg = { ...msg };
1542
- finalMsg.generating = false;
1543
- messages.push(finalMsg);
1527
+ function stepErrCallback(msg, messages, isMain) {
1528
+ if (isMain) conversation.messages[msg.conversationId].loading = false;
1529
+ const idx = findExecutionMsgIndex(msg, messages);
1530
+ const contentItem = msg.content[0];
1531
+ messages.forEach((item) => {
1532
+ if (item.executionId === msg.executionId) {
1533
+ item.generating = false;
1544
1534
  }
1535
+ });
1536
+ if (idx !== -1) {
1537
+ messages[idx].generating = false;
1538
+ const prevContent = messages[idx]?.content || [];
1539
+ messages[idx].content = [...prevContent, contentItem];
1540
+ } else {
1541
+ const finalMsg = { ...msg };
1542
+ finalMsg.generating = false;
1543
+ messages.push(finalMsg);
1545
1544
  }
1546
- config.hooks?.onStepMessage?.(msg);
1545
+ if (isMain) config.hooks?.onStepMessage?.(msg);
1547
1546
  }
1548
- function doneCallback(msg) {
1547
+ function doneCallback(msg, message3, isMain) {
1549
1548
  conversation.messages[msg.conversationId].loading = false;
1550
1549
  const messages = conversation.messages[msg.conversationId]?.message;
1551
1550
  if (messages) {
@@ -1566,11 +1565,12 @@ function createChatStore() {
1566
1565
  }
1567
1566
  }
1568
1567
  }
1569
- config.hooks?.onAfterAcceptMessage?.(msg);
1568
+ if (isMain) config.hooks?.onAfterAcceptMessage?.(msg);
1570
1569
  }
1571
- function titleCallback(msg) {
1570
+ function titleCallback(msg, _messages, isMain) {
1572
1571
  const content = msg.content[0];
1573
1572
  if (content.type !== "conversationNewTitle") return;
1573
+ if (!isMain) return;
1574
1574
  const title = content.title || "";
1575
1575
  const conversationId = msg.conversationId || "";
1576
1576
  if (content && conversations.list.items.length) {
@@ -1579,9 +1579,7 @@ function createChatStore() {
1579
1579
  conversations.list.items[idx].label = title;
1580
1580
  }
1581
1581
  }
1582
- function toolCallCallback(msg) {
1583
- const messages = conversation.messages[msg.conversationId]?.message;
1584
- if (!messages) return;
1582
+ function toolCallCallback(msg, messages, isMain) {
1585
1583
  let idx = -1;
1586
1584
  const contentItem = msg.content[0];
1587
1585
  if (contentItem.type !== "toolCall") return;
@@ -1617,16 +1615,20 @@ function createChatStore() {
1617
1615
  if (contentItem.status) {
1618
1616
  nextItem.status = contentItem.status;
1619
1617
  }
1618
+ if (contentItem.toolIcon) {
1619
+ nextItem.toolIcon = contentItem.toolIcon;
1620
+ }
1621
+ if (contentItem.display) {
1622
+ nextItem.display = (existingItem.display || "") + contentItem.display;
1623
+ }
1620
1624
  messages[idx].content = contents.map((item, i) => i === existingItemIndex ? nextItem : item);
1621
1625
  } else {
1622
1626
  messages[idx].content = [...contents, contentItem];
1623
1627
  }
1624
1628
  }
1625
- conversation.messages[msg.conversationId].loading = true;
1629
+ if (isMain) conversation.messages[msg.conversationId].loading = true;
1626
1630
  }
1627
- function toolResultCallback(msg) {
1628
- const messages = conversation.messages[msg.conversationId]?.message;
1629
- if (!messages) return;
1631
+ function toolResultCallback(msg, messages, isMain) {
1630
1632
  const contentItem = msg.content[0];
1631
1633
  if (contentItem.type !== "toolResult") return;
1632
1634
  let idx = -1;
@@ -1657,15 +1659,16 @@ function createChatStore() {
1657
1659
  if (contentItem.title) {
1658
1660
  nextToolCallItem.title = contentItem.title;
1659
1661
  }
1662
+ if (contentItem.display !== void 0) {
1663
+ nextToolCallItem.display = contentItem.display;
1664
+ }
1660
1665
  messages[idx].content = contents.map((item, i) => i === toolCallIndex ? nextToolCallItem : item);
1661
1666
  } else {
1662
1667
  messages[idx].content = [...contents, contentItem];
1663
1668
  }
1664
- conversation.messages[msg.conversationId].loading = true;
1669
+ if (isMain) conversation.messages[msg.conversationId].loading = true;
1665
1670
  }
1666
- function a2uiCommandCallback(msg) {
1667
- const messages = conversation.messages[msg.conversationId]?.message;
1668
- if (!messages) return;
1671
+ function a2uiCommandCallback(msg, messages, isMain) {
1669
1672
  const idx = findExecutionMsgIndex(msg, messages);
1670
1673
  const contentItem = msg.content[0];
1671
1674
  if (contentItem.type !== "a2uiCommand") return;
@@ -1676,45 +1679,147 @@ function createChatStore() {
1676
1679
  const prevContent = messages[idx]?.content || [];
1677
1680
  messages[idx].content = [...prevContent, contentItem];
1678
1681
  }
1679
- conversation.messages[msg.conversationId].loading = true;
1682
+ if (isMain) conversation.messages[msg.conversationId].loading = true;
1683
+ }
1684
+ function toolCallDeltaCallback(msg, messages, isMain) {
1685
+ const contentItem = msg.content[0];
1686
+ if (contentItem.type !== "toolCallDelta") return;
1687
+ let idx = -1;
1688
+ if (contentItem.toolCallId) {
1689
+ idx = messages.findLastIndex(
1690
+ (m) => m.content?.some((c) => (c.type === "toolCall" || c.type === "toolCallDelta") && c.toolCallId === contentItem.toolCallId)
1691
+ );
1692
+ }
1693
+ if (idx === -1) idx = findExecutionMsgIndex(msg, messages);
1694
+ if (idx === -1) {
1695
+ messages.push({
1696
+ ...msg,
1697
+ content: [
1698
+ {
1699
+ type: "toolCall",
1700
+ toolCallId: contentItem.toolCallId,
1701
+ toolName: contentItem.toolName || void 0,
1702
+ toolIcon: contentItem.toolIcon,
1703
+ title: contentItem.title,
1704
+ content: contentItem.argumentsDelta || "",
1705
+ display: contentItem.display,
1706
+ status: contentItem.status || "running"
1707
+ }
1708
+ ],
1709
+ generating: true
1710
+ });
1711
+ } else {
1712
+ const contents = messages[idx].content;
1713
+ const itemIdx = contents.findIndex(
1714
+ (c) => (c.type === "toolCall" || c.type === "toolCallDelta") && c.toolCallId === contentItem.toolCallId
1715
+ );
1716
+ if (itemIdx !== -1) {
1717
+ const existing = contents[itemIdx];
1718
+ const nextItem = {
1719
+ ...existing,
1720
+ type: "toolCall",
1721
+ content: (existing.content || "") + (contentItem.argumentsDelta || "")
1722
+ };
1723
+ if (contentItem.toolName) nextItem.toolName = contentItem.toolName;
1724
+ if (contentItem.title) nextItem.title = contentItem.title;
1725
+ if (contentItem.status) nextItem.status = contentItem.status;
1726
+ if (contentItem.toolIcon) nextItem.toolIcon = contentItem.toolIcon;
1727
+ if (contentItem.display) nextItem.display = (existing.display || "") + contentItem.display;
1728
+ messages[idx].content = contents.map((c, i) => i === itemIdx ? nextItem : c);
1729
+ } else {
1730
+ messages[idx].content = [
1731
+ ...contents,
1732
+ {
1733
+ type: "toolCall",
1734
+ toolCallId: contentItem.toolCallId,
1735
+ toolName: contentItem.toolName || void 0,
1736
+ toolIcon: contentItem.toolIcon,
1737
+ title: contentItem.title,
1738
+ content: contentItem.argumentsDelta || "",
1739
+ display: contentItem.display,
1740
+ status: contentItem.status || "running"
1741
+ }
1742
+ ];
1743
+ }
1744
+ }
1745
+ if (isMain) conversation.messages[msg.conversationId].loading = true;
1746
+ }
1747
+ function findToolCallItemRecursive(messages, toolCallId) {
1748
+ for (let i = messages.length - 1; i >= 0; i--) {
1749
+ const msg = messages[i];
1750
+ const contents = msg.content || [];
1751
+ const itemIdx = contents.findIndex((c) => c.type === "toolCall" && c.toolCallId === toolCallId);
1752
+ if (itemIdx !== -1) {
1753
+ return { messageList: msg, itemIndex: itemIdx };
1754
+ }
1755
+ for (const content of contents) {
1756
+ if (content.type === "toolCall") {
1757
+ const subMessages = content.subMessages;
1758
+ if (subMessages?.length) {
1759
+ const found = findToolCallItemRecursive(subMessages, toolCallId);
1760
+ if (found) return found;
1761
+ }
1762
+ }
1763
+ }
1764
+ }
1765
+ return null;
1766
+ }
1767
+ function routeSubAgentMessage(msg) {
1768
+ const conversationId = msg.conversationId;
1769
+ const mainMessages = conversation.messages[conversationId]?.message;
1770
+ if (!mainMessages) return;
1771
+ const found = findToolCallItemRecursive(mainMessages, msg.toolCallId);
1772
+ if (!found) {
1773
+ return;
1774
+ }
1775
+ const { messageList, itemIndex } = found;
1776
+ const contents = messageList.content;
1777
+ const toolCallItem = contents[itemIndex];
1778
+ toolCallItem.hasSubAgent = true;
1779
+ if (!toolCallItem.subMessages) {
1780
+ toolCallItem.subMessages = [];
1781
+ }
1782
+ processMessageContent(msg, toolCallItem.subMessages);
1783
+ messageList.content = contents.map((c, i) => i === itemIndex ? { ...toolCallItem } : c);
1680
1784
  }
1681
- function processSingleMessageContent(newMessage) {
1785
+ function processSingleMessageContent(newMessage, messages, isMain) {
1682
1786
  switch (newMessage.content[0].type) {
1683
1787
  case "runStarted":
1684
- startCallback(newMessage);
1788
+ startCallback(newMessage, messages, isMain);
1685
1789
  break;
1686
1790
  case "text":
1687
- textCallback(newMessage);
1791
+ textCallback(newMessage, messages, isMain);
1688
1792
  break;
1689
1793
  case "stepStarted":
1690
- stepStartedCallback(newMessage);
1794
+ stepStartedCallback(newMessage, messages, isMain);
1691
1795
  break;
1692
1796
  case "stepFinished":
1693
- stepFinishedCallback(newMessage);
1797
+ stepFinishedCallback(newMessage, messages, isMain);
1694
1798
  break;
1695
1799
  case "stepError":
1696
- stepErrCallback(newMessage);
1800
+ stepErrCallback(newMessage, messages, isMain);
1697
1801
  break;
1698
1802
  case "runFinished":
1699
1803
  case "runFailed":
1700
1804
  case "runStopped":
1701
- doneCallback(newMessage);
1805
+ doneCallback(newMessage, messages, isMain);
1702
1806
  break;
1703
1807
  case "conversationNewTitle":
1704
- titleCallback(newMessage);
1808
+ titleCallback(newMessage, messages, isMain);
1705
1809
  break;
1706
1810
  case "toolCall":
1707
- toolCallCallback(newMessage);
1811
+ toolCallCallback(newMessage, messages, isMain);
1812
+ break;
1813
+ case "toolCallDelta":
1814
+ toolCallDeltaCallback(newMessage, messages, isMain);
1708
1815
  break;
1709
1816
  case "toolResult":
1710
- toolResultCallback(newMessage);
1817
+ toolResultCallback(newMessage, messages, isMain);
1711
1818
  break;
1712
1819
  case "a2uiCommand":
1713
- a2uiCommandCallback(newMessage);
1820
+ a2uiCommandCallback(newMessage, messages, isMain);
1714
1821
  break;
1715
1822
  default: {
1716
- const messages = conversation.messages[newMessage.conversationId]?.message;
1717
- if (!messages) return;
1718
1823
  const idx = findExecutionMsgIndex(newMessage, messages);
1719
1824
  if (idx === -1) {
1720
1825
  const finalMsg = { ...newMessage, generating: true };
@@ -1723,20 +1828,21 @@ function createChatStore() {
1723
1828
  const prevContent = messages[idx]?.content || [];
1724
1829
  messages[idx].content = [...prevContent, ...newMessage.content];
1725
1830
  }
1726
- conversation.messages[newMessage.conversationId].loading = true;
1831
+ if (isMain) conversation.messages[newMessage.conversationId].loading = true;
1727
1832
  break;
1728
1833
  }
1729
1834
  }
1730
1835
  }
1731
- function processMessageContent(message3) {
1836
+ function processMessageContent(message3, targetMessages) {
1732
1837
  const newMessage = {
1733
1838
  ...message3,
1734
1839
  agentId: agent.agentInfo.id
1735
1840
  };
1841
+ const isMain = !targetMessages;
1842
+ const messages = targetMessages ?? conversation.messages[newMessage.conversationId]?.message;
1843
+ if (!messages) return;
1736
1844
  const contentList = Array.isArray(newMessage.content) ? newMessage.content : [];
1737
1845
  if (contentList.length === 0) {
1738
- const messages = conversation.messages[newMessage.conversationId]?.message;
1739
- if (!messages) return;
1740
1846
  const idx = findExecutionMsgIndex(newMessage, messages);
1741
1847
  if (idx === -1) {
1742
1848
  messages.push({ ...newMessage });
@@ -1752,17 +1858,32 @@ function createChatStore() {
1752
1858
  return;
1753
1859
  }
1754
1860
  contentList.forEach((contentItem) => {
1755
- processSingleMessageContent({
1756
- ...newMessage,
1757
- content: [contentItem]
1758
- });
1861
+ processSingleMessageContent(
1862
+ {
1863
+ ...newMessage,
1864
+ content: [contentItem]
1865
+ },
1866
+ messages,
1867
+ isMain
1868
+ );
1759
1869
  });
1760
- normalizeMessagesByExecutionAndRole(conversation.messages[newMessage.conversationId]?.message);
1870
+ normalizeMessagesByExecutionAndRole(messages);
1761
1871
  }
1762
1872
  function isStoppedIncomingMessage(newMessage) {
1763
1873
  const messages = conversation.messages[newMessage.conversationId]?.message;
1764
1874
  if (!messages) return false;
1765
- return messages.some((item) => item.stopFlag && item.executionId === newMessage.executionId);
1875
+ if (messages.some((item) => item.stopFlag && item.executionId === newMessage.executionId)) {
1876
+ return true;
1877
+ }
1878
+ return messages.some(
1879
+ (msg) => msg.content?.some((c) => {
1880
+ if (c.type === "toolCall") {
1881
+ const subMessages = c.subMessages;
1882
+ return subMessages?.some((sub) => sub.stopFlag && sub.executionId === newMessage.executionId);
1883
+ }
1884
+ return false;
1885
+ })
1886
+ );
1766
1887
  }
1767
1888
  const acceptMessage = async (newMessage) => {
1768
1889
  const conversationId = newMessage.conversationId;
@@ -1772,6 +1893,10 @@ function createChatStore() {
1772
1893
  if (canProceed === false) {
1773
1894
  throw new Error("\u64CD\u4F5C\u88AB\u963B\u6B62");
1774
1895
  }
1896
+ if (newMessage.toolCallId) {
1897
+ routeSubAgentMessage(newMessage);
1898
+ return;
1899
+ }
1775
1900
  if (isStoppedIncomingMessage(newMessage)) {
1776
1901
  conversation.messages[conversationId].loading = false;
1777
1902
  return;
@@ -1853,19 +1978,25 @@ function createChatStore() {
1853
1978
  const lastMsg = messages[messages.length - 1];
1854
1979
  if (lastMsg.executionId) {
1855
1980
  await config.services.request.cancelMessage(lastMsg.executionId);
1856
- messages.forEach((item) => {
1857
- if (item.executionId === lastMsg.executionId) {
1858
- item.generating = false;
1859
- item.stopFlag = true;
1981
+ const markStopped = (msgList, matchExecutionId) => {
1982
+ msgList.forEach((item) => {
1983
+ if (item.executionId === lastMsg.executionId) {
1984
+ item.generating = false;
1985
+ item.stopFlag = true;
1986
+ }
1860
1987
  if (item.content && Array.isArray(item.content)) {
1861
1988
  item.content.forEach((contentItem) => {
1862
1989
  if (contentItem.type === "toolCall" && contentItem.status !== "success" && contentItem.status !== "error") {
1863
1990
  contentItem.status = "error";
1864
1991
  }
1992
+ if (contentItem.subMessages?.length) {
1993
+ markStopped(contentItem.subMessages);
1994
+ }
1865
1995
  });
1866
1996
  }
1867
- }
1868
- });
1997
+ });
1998
+ };
1999
+ markStopped(messages);
1869
2000
  } else {
1870
2001
  lastMsg.stopFlag = true;
1871
2002
  lastMsg.generating = false;
@@ -4547,7 +4678,8 @@ var FilesNode = React10__default.memo(({ item }) => {
4547
4678
 
4548
4679
  // src/components/CustomComponents/MessageNode/style.module.less
4549
4680
  var style_module_default2 = {
4550
- runStartedNode: "style_module_runStartedNode"};
4681
+ runStartedNode: "style_module_runStartedNode",
4682
+ dot: "style_module_dot"};
4551
4683
  var QuoteMsgNode = React10__default.memo(({ quoteMsg, role }) => {
4552
4684
  if (!quoteMsg || !quoteMsg.messageContent) return null;
4553
4685
  return /* @__PURE__ */ jsx(
@@ -4578,9 +4710,12 @@ var QuoteMsgNode = React10__default.memo(({ quoteMsg, role }) => {
4578
4710
  }
4579
4711
  );
4580
4712
  });
4581
- var RunStartedNode = React10__default.memo(({ loading }) => {
4582
- if (!loading) return null;
4583
- return /* @__PURE__ */ jsx(Flex, { gap: 8, align: "center", className: style_module_default2.runStartedNode, children: /* @__PURE__ */ jsx(LoadingOutlined, { style: { color: "#1677ff" } }) });
4713
+ var RunStartedNode = React10__default.memo(() => {
4714
+ return /* @__PURE__ */ jsxs("span", { className: style_module_default2.runStartedNode, children: [
4715
+ /* @__PURE__ */ jsx("span", { className: style_module_default2.dot }),
4716
+ /* @__PURE__ */ jsx("span", { className: style_module_default2.dot }),
4717
+ /* @__PURE__ */ jsx("span", { className: style_module_default2.dot })
4718
+ ] });
4584
4719
  });
4585
4720
  var RESOURCE_MARKDOWN_TAG = "resourcetag";
4586
4721
  var RESOURCE_TOKEN_REGEX = /(\w+):\/\/([^?\s]+)\?name=([^&\s]+)&label=([^\s]+)/g;
@@ -4634,11 +4769,17 @@ var TextNode2 = React10__default.memo(
4634
4769
  var index_module_default2 = {
4635
4770
  iconContainer: "index_module_iconContainer",
4636
4771
  toolName: "index_module_toolName",
4772
+ toolNamePending: "index_module_toolNamePending",
4773
+ dot: "index_module_dot",
4637
4774
  duration: "index_module_duration",
4638
4775
  statusIcon: "index_module_statusIcon",
4776
+ expandIcon: "index_module_expandIcon",
4777
+ expanded: "index_module_expanded",
4639
4778
  sectionLabel: "index_module_sectionLabel",
4779
+ plainTextContainer: "index_module_plainTextContainer",
4640
4780
  markdownContainer: "index_module_markdownContainer",
4641
4781
  sectionBlock: "index_module_sectionBlock",
4782
+ contentScrollContainer: "index_module_contentScrollContainer",
4642
4783
  todoList: "index_module_todoList",
4643
4784
  todoItem: "index_module_todoItem",
4644
4785
  statusIconWrapper: "index_module_statusIconWrapper",
@@ -4648,6 +4789,9 @@ var index_module_default2 = {
4648
4789
  emptyText: "index_module_emptyText"
4649
4790
  };
4650
4791
  var DefaultToolRender = ({ argsContent, resultContent, errorMessage, item }) => {
4792
+ if (item.display) {
4793
+ return /* @__PURE__ */ jsx("pre", { className: index_module_default2.plainTextContainer, children: item.display });
4794
+ }
4651
4795
  return /* @__PURE__ */ jsxs(Fragment, { children: [
4652
4796
  (item.content || item.arguments) && argsContent && /* @__PURE__ */ jsxs("div", { className: index_module_default2.sectionBlock, children: [
4653
4797
  /* @__PURE__ */ jsx(Typography.Text, { className: index_module_default2.sectionLabel, children: "\u8F93\u5165\u53C2\u6570" }),
@@ -4751,7 +4895,7 @@ var formatContent = (content) => {
4751
4895
  };
4752
4896
  var ToolCallItem = ({ item }) => {
4753
4897
  const { token } = theme.useToken();
4754
- const renderConfig = getToolRenderConfig(item.toolName);
4898
+ const renderConfig = getToolRenderConfig(item);
4755
4899
  const CustomRender = renderConfig.component;
4756
4900
  const status = useMemo(() => {
4757
4901
  if (item.status) return item.status;
@@ -4775,35 +4919,30 @@ var ToolCallItem = ({ item }) => {
4775
4919
  alwaysShow = renderConfig.alwaysShowContent;
4776
4920
  }
4777
4921
  if (alwaysShow) return true;
4778
- return Boolean(item.errorMessage);
4779
- }, [renderConfig.disableExpandOnError, renderConfig.alwaysShowContent, item.errorMessage, status, argsContent.parsed, resultContent?.parsed]);
4922
+ if (item.display) return true;
4923
+ if (item.errorMessage) return true;
4924
+ if (argsContent.text) return true;
4925
+ if (resultContent?.text) return true;
4926
+ return false;
4927
+ }, [
4928
+ renderConfig.disableExpandOnError,
4929
+ renderConfig.alwaysShowContent,
4930
+ item.display,
4931
+ item.errorMessage,
4932
+ status,
4933
+ argsContent.parsed,
4934
+ resultContent?.parsed,
4935
+ argsContent.text,
4936
+ resultContent?.text
4937
+ ]);
4780
4938
  const isDefaultExpanded = useMemo(() => {
4781
4939
  if (typeof renderConfig.defaultExpanded === "function") {
4782
4940
  return renderConfig.defaultExpanded(argsContent.parsed, resultContent?.parsed);
4783
4941
  }
4784
4942
  return renderConfig.defaultExpanded;
4785
4943
  }, [renderConfig.defaultExpanded, argsContent.parsed, resultContent?.parsed]);
4786
- const statusConfig = {
4787
- running: {
4788
- icon: /* @__PURE__ */ jsx(LoadingOutlined, {}),
4789
- color: token.colorPrimary
4790
- },
4791
- success: {
4792
- icon: null,
4793
- color: token.colorSuccess
4794
- },
4795
- error: {
4796
- icon: null,
4797
- color: token.colorSuccess
4798
- },
4799
- pending: {
4800
- icon: /* @__PURE__ */ jsx(LoadingOutlined, {}),
4801
- color: token.colorTextSecondary
4802
- }
4803
- }[status] || {
4804
- icon: /* @__PURE__ */ jsx(LoadingOutlined, {}),
4805
- color: token.colorPrimary
4806
- };
4944
+ const showLoading = status === "running" || status === "pending";
4945
+ const displayName = item.title || (showLoading ? "" : item.toolName || "Unknown Tool");
4807
4946
  const renderIcon = () => {
4808
4947
  if (!item.toolIcon) {
4809
4948
  return /* @__PURE__ */ jsx(ToolOutlined, { style: { fontSize: 14, color: token.colorTextSecondary } });
@@ -4821,9 +4960,11 @@ var ToolCallItem = ({ item }) => {
4821
4960
  collapsible: hasContent ? void 0 : "disabled",
4822
4961
  defaultActiveKey: isDefaultExpanded && hasContent ? [item.toolCallId || "fallback-key"] : void 0,
4823
4962
  expandIconPlacement: "end",
4963
+ expandIcon: ({ isActive }) => hasContent ? /* @__PURE__ */ jsx(RightOutlined, { className: `${index_module_default2.expandIcon} ${isActive ? index_module_default2.expanded : ""}` }) : null,
4824
4964
  styles: {
4825
4965
  header: {
4826
- padding: "6px 10px"
4966
+ padding: "6px 10px",
4967
+ overflow: "hidden"
4827
4968
  }
4828
4969
  },
4829
4970
  items: [
@@ -4832,14 +4973,18 @@ var ToolCallItem = ({ item }) => {
4832
4973
  showArrow: hasContent,
4833
4974
  label: /* @__PURE__ */ jsxs(Flex, { align: "center", gap: 8, style: { flex: 1, minWidth: 0 }, children: [
4834
4975
  /* @__PURE__ */ jsx("div", { className: index_module_default2.iconContainer, children: renderIcon() }),
4835
- /* @__PURE__ */ jsx("span", { className: index_module_default2.toolName, children: item.title || item.toolName || "Unknown Tool" }),
4836
- (status === "running" || status === "pending") && /* @__PURE__ */ jsx("div", { className: index_module_default2.statusIcon, style: { color: statusConfig.color }, children: statusConfig.icon }),
4976
+ displayName ? /* @__PURE__ */ jsx("span", { className: index_module_default2.toolName, children: displayName }) : /* @__PURE__ */ jsxs("span", { className: index_module_default2.toolNamePending, children: [
4977
+ /* @__PURE__ */ jsx("span", { className: index_module_default2.dot }),
4978
+ /* @__PURE__ */ jsx("span", { className: index_module_default2.dot }),
4979
+ /* @__PURE__ */ jsx("span", { className: index_module_default2.dot })
4980
+ ] }),
4981
+ showLoading && /* @__PURE__ */ jsx("div", { className: index_module_default2.statusIcon, style: { color: token.colorPrimary }, children: /* @__PURE__ */ jsx(LoadingOutlined, {}) }),
4837
4982
  item.duration && /* @__PURE__ */ jsxs(Typography.Text, { className: index_module_default2.duration, children: [
4838
4983
  item.duration,
4839
4984
  "ms"
4840
4985
  ] })
4841
4986
  ] }),
4842
- children: /* @__PURE__ */ jsx(
4987
+ children: /* @__PURE__ */ jsx("div", { className: index_module_default2.contentScrollContainer, children: /* @__PURE__ */ jsx(
4843
4988
  CustomRender,
4844
4989
  {
4845
4990
  item,
@@ -4849,7 +4994,7 @@ var ToolCallItem = ({ item }) => {
4849
4994
  resultContent,
4850
4995
  errorMessage: item.errorMessage
4851
4996
  }
4852
- )
4997
+ ) })
4853
4998
  }
4854
4999
  ]
4855
5000
  }
@@ -4863,9 +5008,6 @@ var MessageRender_default = React10__default.memo(({ role, message: message3, me
4863
5008
  if (!RENDERABLE_MESSAGE_TYPES.includes(item.type)) {
4864
5009
  return false;
4865
5010
  }
4866
- if (item.type === "runStarted") {
4867
- return !!loading;
4868
- }
4869
5011
  if (item.type === "plan") {
4870
5012
  return !shouldHideA2uiPlan(item);
4871
5013
  }
@@ -4875,7 +5017,7 @@ var MessageRender_default = React10__default.memo(({ role, message: message3, me
4875
5017
  }
4876
5018
  return true;
4877
5019
  });
4878
- }, [loading, message3.content]);
5020
+ }, [message3.content]);
4879
5021
  const quoteMsg = useMemo(() => {
4880
5022
  const quoteMsg2 = {};
4881
5023
  if (message3.params) {
@@ -4889,7 +5031,8 @@ var MessageRender_default = React10__default.memo(({ role, message: message3, me
4889
5031
  }
4890
5032
  return isEmptyObj(quoteMsg2) ? null : quoteMsg2;
4891
5033
  }, [message3.params, message3.quoteMsg]);
4892
- if (content.length === 0) return null;
5034
+ const showPending = loading && (content.length === 0 || content[content.length - 1].type !== "text");
5035
+ if (content.length === 0 && !showPending) return null;
4893
5036
  const lastToolCallIndex = (() => {
4894
5037
  let lastIdx = -1;
4895
5038
  content.forEach((item, i) => {
@@ -4906,7 +5049,6 @@ var MessageRender_default = React10__default.memo(({ role, message: message3, me
4906
5049
  placement: role.placement,
4907
5050
  variant: item.type === "files" ? "borderless" : void 0,
4908
5051
  content: /* @__PURE__ */ jsxs(Fragment, { children: [
4909
- item.type === "runStarted" && /* @__PURE__ */ jsx(RunStartedNode, { loading }, `flow-start-${index}`),
4910
5052
  (item.type === "toolCall" || item.type === "toolResult") && /* @__PURE__ */ jsx(tool_call_item_default, { item }, `tool-call-${item.toolCallId || index}`),
4911
5053
  item.type === "text" && /* @__PURE__ */ jsx(
4912
5054
  TextNode2,
@@ -4927,6 +5069,7 @@ var MessageRender_default = React10__default.memo(({ role, message: message3, me
4927
5069
  ),
4928
5070
  index === lastToolCallIndex && messageIndex >= 0 ? /* @__PURE__ */ jsx(A2uiMessageCards, { messageIndex, message: message3 }) : null
4929
5071
  ] }, `message-${index}`)),
5072
+ showPending && /* @__PURE__ */ jsx(Bubble, { role: role.user, placement: role.placement, content: /* @__PURE__ */ jsx(RunStartedNode, {}) }),
4930
5073
  quoteMsg && /* @__PURE__ */ jsx(QuoteMsgNode, { quoteMsg, role })
4931
5074
  ] });
4932
5075
  });