@zero-library/chat-copilot 3.1.8 → 3.1.10

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
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';
2
2
  import { Attachments, Sender, FileCard, Bubble, Think, XProvider, Mermaid, CodeHighlighter, Welcome, Prompts, Conversations } from '@ant-design/x-v2';
3
- import { useRefState, useDebounce, createTokenManager, useSyncInput, isEmptyObj, markdownToText, RenderWrapper, shouldRender, isFunction, downloadFile, LuyaFilePreview, MarkdownEditor, useDeepEffect, isObject, useWebSocket, isNullOrUnDef, isNumber, getFileSuffixName, FileIcon, copyText, LazyComponent, isBoolean, UserAvatar, htmlToMarkdown, buildUrlParams, isExternal, deepCopy, transforms, deepMerge, createRequest, HttpStatus, isArray, isString, transform, emit, 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, Drawer, Empty, Modal, Checkbox, Input, message, List, Card, Table, Progress as Progress$1, Switch as Switch$1 } from 'antd';
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';
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';
@@ -43,7 +43,7 @@ var styles_module_default = {
43
43
  chatAttachments: "styles_module_chatAttachments",
44
44
  chatSender: "styles_module_chatSender"};
45
45
  var Attachments_default = forwardRef(({ fileUpload, fileUploadConfig, fileList = [], onChange, extraParams }, ref) => {
46
- const { message: message2 } = App.useApp();
46
+ const { message: message3 } = App.useApp();
47
47
  const chatStore = useChatStore();
48
48
  useSnapshot(chatStore.agent);
49
49
  const fileListRef = useRef([]);
@@ -71,7 +71,7 @@ var Attachments_default = forwardRef(({ fileUpload, fileUploadConfig, fileList =
71
71
  onChange(files);
72
72
  }, [attachedFiles]);
73
73
  const onErrorTip = useDebounce((errorMsg) => {
74
- message2.error(errorMsg);
74
+ message3.error(errorMsg);
75
75
  }, 300);
76
76
  const findConfig = (file) => {
77
77
  return fileUploadConfig?.allowedTypes?.find((type) => type === getFileSuffixName(file.name)) || "";
@@ -265,6 +265,41 @@ var classifyTime = (timestamp) => {
265
265
  return "\u66F4\u65E9";
266
266
  }
267
267
  };
268
+ var variablesToObject = (variables) => {
269
+ if (!isArray(variables)) return {};
270
+ const jsonTypes = ["OBJECT", "ARRAY", "ARRAY_STRING", "ARRAY_NUMBER", "ARRAY_DECIMAL", "ARRAY_BOOLEAN", "ARRAY_OBJECT"];
271
+ return variables.reduce(
272
+ (acc, cur) => {
273
+ if (cur.type === "BOOLEAN") {
274
+ if (isDef(cur.value) && !isNull(cur.value)) {
275
+ acc[cur.name] = cur.value;
276
+ }
277
+ } else if (jsonTypes.includes(cur.type)) {
278
+ if (isDef(cur.value) && !isNull(cur.value)) {
279
+ if (typeof cur.value === "string") {
280
+ if (cur.value === "") {
281
+ acc[cur.name] = cur.type === "OBJECT" ? {} : [];
282
+ } else {
283
+ try {
284
+ acc[cur.name] = JSON.parse(cur.value);
285
+ } catch (e) {
286
+ acc[cur.name] = cur.type === "OBJECT" ? {} : [];
287
+ }
288
+ }
289
+ } else {
290
+ acc[cur.name] = cur.value;
291
+ }
292
+ }
293
+ } else {
294
+ if (isDef(cur.value) && !isNull(cur.value) && cur.value !== "") {
295
+ acc[cur.name] = cur.value;
296
+ }
297
+ }
298
+ return acc;
299
+ },
300
+ {}
301
+ );
302
+ };
268
303
  var getChatSocketUrl = (baseURL, params) => {
269
304
  return buildUrlParams(params, getWebSocketUrl(`${baseURL}/ws`), "comma");
270
305
  };
@@ -302,6 +337,15 @@ var getFileUrl = (params, baseUrl, url) => {
302
337
  };
303
338
  return buildUrlParams(data, url || `${baseUrl}/files/access`);
304
339
  };
340
+ var formatFileSize = (size = 0) => {
341
+ if (size < 1024) return `${size} B`;
342
+ const kb = size / 1024;
343
+ if (kb < 1024) return `${kb.toFixed(2)} KB`;
344
+ const mb = kb / 1024;
345
+ if (mb < 1024) return `${mb.toFixed(2)} MB`;
346
+ const gb = mb / 1024;
347
+ return `${gb.toFixed(2)} GB`;
348
+ };
305
349
  function GroupPicker({
306
350
  groups,
307
351
  selectedIndex,
@@ -372,6 +416,13 @@ function formatResourceName(resourceName) {
372
416
  if (name.length <= 6) return `${name}${extension}`;
373
417
  return `${name.slice(0, 3)}***${name.slice(-3)}${extension}`;
374
418
  }
419
+ function ReadonlyResourceTag({ resource }) {
420
+ return /* @__PURE__ */ jsx("div", { className: index_module_default.resourceTag, children: /* @__PURE__ */ jsxs(Tag, { color: "blue", children: [
421
+ resource.resourceLabel,
422
+ "\uFF1A",
423
+ formatResourceName(resource.resourceName)
424
+ ] }) });
425
+ }
375
426
  function ResourceTag({ resource }) {
376
427
  const [editor] = useLexicalComposerContext();
377
428
  const handleClose = (event) => {
@@ -459,7 +510,7 @@ var VariableNode = class _VariableNode extends DecoratorNode {
459
510
  * 生成节点的纯文本表达,便于发送、存储和重新初始化编辑器内容。
460
511
  */
461
512
  getTextContent() {
462
- return `${this.__resourceType}://${this.__resourceId}?name=${this.__resourceName}&label=${this.__resourceLabel}`;
513
+ return ` ${this.__resourceType}://${this.__resourceId}?name=${this.__resourceName}&label=${this.__resourceLabel} `;
463
514
  }
464
515
  /**
465
516
  * 将变量节点渲染为可交互的资源标签组件。
@@ -527,6 +578,7 @@ function VariablePickerPlugin({ commandConfig = {} }) {
527
578
  useEffect(() => {
528
579
  setCommandDataSource(commandConfig);
529
580
  }, [commandConfig]);
581
+ const commandKeys = useMemo(() => Object.keys(commandConfig), [commandConfig]);
530
582
  const commandKey = queryString?.[0] || "";
531
583
  const searchKeyword = queryString?.slice(commandKey.length).trim().toLocaleLowerCase() || "";
532
584
  const categoryConfig = useMemo(
@@ -639,15 +691,15 @@ function VariablePickerPlugin({ commandConfig = {} }) {
639
691
  onQueryChange: (query) => setQueryString(query),
640
692
  onSelectOption,
641
693
  triggerFn: (text) => {
642
- const match = new RegExp(
643
- `(?:${Object.keys(commandConfig).map((key) => key.replace(/[.*+?^${}()|[\\]\\]/g, "\\$&")).join("|")})([^\\s]*)$`
644
- ).exec(text);
694
+ if (!commandKeys.length) return null;
695
+ const match = new RegExp(`(?:${commandKeys.map((key) => key.replace(/[.*+?^${}()|[\\]\\]/g, "\\$&")).join("|")})([^\\s]*)$`).exec(text);
645
696
  if (!match) return null;
646
697
  return { leadOffset: match.index, matchingString: match[0], replaceableString: match[0] };
647
698
  },
648
699
  options: commandOptions,
649
700
  menuRenderFn: (anchorElementRef, { selectedIndex, setHighlightedIndex, selectOptionAndCleanUp }) => {
650
- if (!isEditorFocused || !anchorElementRef.current || searchKeyword && !commandGroups.length) return null;
701
+ if (!isEditorFocused || !anchorElementRef.current || !commandKeys.length || !commandGroups.length && !searchKeyword) return null;
702
+ if (searchKeyword && !commandGroups.length) return null;
651
703
  return ReactDOM.createPortal(
652
704
  /* @__PURE__ */ jsx(ResourcePickerMenu, { anchorElementRef, children: /* @__PURE__ */ jsx(
653
705
  GroupPicker,
@@ -977,7 +1029,8 @@ var defaultLayout = {
977
1029
  messageList: true,
978
1030
  senderHeader: false,
979
1031
  senderFooter: false,
980
- disclaimerNotice: true
1032
+ disclaimerNotice: true,
1033
+ userInput: false
981
1034
  };
982
1035
  function createChatStore() {
983
1036
  const config = proxy({
@@ -1090,6 +1143,17 @@ function createChatStore() {
1090
1143
  agent.model = { ...agent.model, ...model };
1091
1144
  config.hooks?.onAfterSwitchModel?.(model);
1092
1145
  };
1146
+ const getUserInput = async (agentId) => {
1147
+ agent.loading = true;
1148
+ try {
1149
+ const { data } = await config.services.request.getAgentUserInput(agentId);
1150
+ if (data?.inputs && !agent.agentInfo.userInput?.length) {
1151
+ agent.agentInfo.userInput = data.inputs.filter((item) => item.enableEdit);
1152
+ }
1153
+ } finally {
1154
+ agent.loading = false;
1155
+ }
1156
+ };
1093
1157
  const setAgent = (agentInfo) => {
1094
1158
  agent.agentInfo = agentInfo;
1095
1159
  if (agentInfo.agentType === 2 /* AUTONOMOUS */) {
@@ -1097,6 +1161,13 @@ function createChatStore() {
1097
1161
  modelName: agent.agentInfo.spec?.model?.modelName || "",
1098
1162
  providerName: agent.agentInfo.spec?.model?.providerName || ""
1099
1163
  });
1164
+ } else if (config.layout.userInput) {
1165
+ getUserInput(agent.agentInfo.id);
1166
+ }
1167
+ };
1168
+ const setUserInput = (userInput) => {
1169
+ if (agent.agentInfo.agentType === 1 /* FLOW */) {
1170
+ agent.agentInfo.userInput = userInput;
1100
1171
  }
1101
1172
  };
1102
1173
  const getAgentInfo = async (id) => {
@@ -1223,7 +1294,8 @@ function createChatStore() {
1223
1294
  /** 当前激活的会话信息 */
1224
1295
  active: {
1225
1296
  id: "",
1226
- spec: {}
1297
+ spec: {},
1298
+ userInput: []
1227
1299
  },
1228
1300
  /** 每个会话的消息存储,以会话ID为键 */
1229
1301
  messages: {},
@@ -1255,9 +1327,12 @@ function createChatStore() {
1255
1327
  };
1256
1328
  const setConversationSpec = (spec) => {
1257
1329
  if (isObject(spec)) {
1258
- Object.assign(conversation.active.spec, spec);
1330
+ Object.assign(conversation.active.spec || {}, spec);
1259
1331
  }
1260
1332
  };
1333
+ const setConversationUserInput = (userInput) => {
1334
+ conversation.active.userInput = userInput;
1335
+ };
1261
1336
  const feedback = async (executionId, feedback2, index) => {
1262
1337
  try {
1263
1338
  conversation.feedback.loading = true;
@@ -1474,11 +1549,22 @@ function createChatStore() {
1474
1549
  conversation.messages[msg.conversationId].loading = false;
1475
1550
  const messages = conversation.messages[msg.conversationId]?.message;
1476
1551
  if (messages) {
1552
+ const idx = findExecutionMsgIndex(msg, messages);
1553
+ const contentItem = msg.content[0];
1477
1554
  messages.forEach((item) => {
1478
1555
  if (item.executionId === msg.executionId) {
1479
1556
  item.generating = false;
1480
1557
  }
1481
1558
  });
1559
+ if (contentItem?.type === "runFailed") {
1560
+ if (idx !== -1) {
1561
+ const prevContent = messages[idx]?.content || [];
1562
+ messages[idx].content = [...prevContent, contentItem];
1563
+ } else {
1564
+ const finalMsg = { ...msg, generating: false };
1565
+ messages.push(finalMsg);
1566
+ }
1567
+ }
1482
1568
  }
1483
1569
  config.hooks?.onAfterAcceptMessage?.(msg);
1484
1570
  }
@@ -1642,9 +1728,9 @@ function createChatStore() {
1642
1728
  }
1643
1729
  }
1644
1730
  }
1645
- function processMessageContent(message2) {
1731
+ function processMessageContent(message3) {
1646
1732
  const newMessage = {
1647
- ...message2,
1733
+ ...message3,
1648
1734
  agentId: agent.agentInfo.id
1649
1735
  };
1650
1736
  const contentList = Array.isArray(newMessage.content) ? newMessage.content : [];
@@ -1692,14 +1778,14 @@ function createChatStore() {
1692
1778
  }
1693
1779
  processMessageContent(newMessage);
1694
1780
  };
1695
- const sendMessage = async (message2, msgFiles = [], params) => {
1781
+ const sendMessage = async (message3, msgFiles = [], params) => {
1696
1782
  const conversationId = conversation.active.id;
1697
1783
  if (conversation.messages[conversationId].loading) return;
1698
1784
  let msgContent = "", files;
1699
1785
  const references = conversation.messages[conversationId].references;
1700
- if (message2) {
1701
- msgContent = message2;
1702
- files = msgFiles;
1786
+ if (message3) {
1787
+ msgContent = message3;
1788
+ files = [...msgFiles, ...conversation.messages[conversationId].files || []];
1703
1789
  } else {
1704
1790
  if (references?.type === 1 && references?.content?.msgContent) {
1705
1791
  msgContent = references.content.msgContent + "\n\n";
@@ -1710,6 +1796,22 @@ function createChatStore() {
1710
1796
  if (!msgContent) return;
1711
1797
  const canProceed = await config.hooks?.onBeforeSend?.(msgContent, files || []);
1712
1798
  if (canProceed === false) return;
1799
+ if (conversation.active.userInput?.length) {
1800
+ const invalid = conversation.active.userInput.some((item) => {
1801
+ const isRequired = item.rules?.some((r) => r.type === "required");
1802
+ if (isRequired) {
1803
+ if (item.type === "BOOLEAN") {
1804
+ return isNullOrUnDef(item.value);
1805
+ }
1806
+ return isNullOrUnDef(item.value) || item.value === "";
1807
+ }
1808
+ return false;
1809
+ });
1810
+ if (invalid) {
1811
+ message.error("\u8BF7\u68C0\u67E5\u8F93\u5165\u53C2\u6570");
1812
+ return;
1813
+ }
1814
+ }
1713
1815
  conversation.messages[conversationId].loading = true;
1714
1816
  const idx = conversations.list.items.findIndex((item) => item.id === conversationId);
1715
1817
  if (idx !== -1 && !conversations.list.items[idx].label) {
@@ -1728,15 +1830,16 @@ function createChatStore() {
1728
1830
  responseMode: 2
1729
1831
  };
1730
1832
  const extraParams = deepCopy(config.params?.params || {});
1731
- Object.assign(extraParams, message2 ? {} : { ...references?.params }, params);
1833
+ const userInputParams = variablesToObject(conversation.active.userInput || []);
1834
+ Object.assign(extraParams, message3 ? {} : { ...references?.params }, params, userInputParams);
1732
1835
  sendParams.params = extraParams;
1733
- if (!message2) {
1836
+ if (!message3) {
1734
1837
  setContent("");
1735
1838
  setContentParams();
1736
- setFileList([]);
1737
1839
  setReferences();
1738
- setHeaderOpen(false);
1739
1840
  }
1841
+ setFileList([]);
1842
+ setHeaderOpen(false);
1740
1843
  try {
1741
1844
  const dealedParams = await config.hooks?.onHandleSendParams?.(sendParams);
1742
1845
  await config.services.request.sendMessageStream(dealedParams || sendParams, agent.agentInfo?.id || "");
@@ -1794,7 +1897,7 @@ function createChatStore() {
1794
1897
  /** 设置智能体 */
1795
1898
  setAgent,
1796
1899
  /** 设置智能体用户输入 */
1797
- // setUserInput,
1900
+ setUserInput,
1798
1901
  /** 设置会话配置 */
1799
1902
  setConversationSpec,
1800
1903
  /** 历史会话状态 */
@@ -1828,9 +1931,11 @@ function createChatStore() {
1828
1931
  /** 接收消息 */
1829
1932
  acceptMessage,
1830
1933
  /** 获取智能体用户输入 */
1831
- // getUserInput,
1934
+ getUserInput,
1832
1935
  /** 消息反馈 */
1833
- feedback
1936
+ feedback,
1937
+ /** 设置会话用户输入 */
1938
+ setConversationUserInput
1834
1939
  };
1835
1940
  }
1836
1941
  var AuthImage = ({ path, size, shape = "square" }) => {
@@ -1924,6 +2029,7 @@ var styles_module_default2 = {
1924
2029
  chatWelcome: "styles_module_chatWelcome",
1925
2030
  promptItem: "styles_module_promptItem",
1926
2031
  bubbleList: "styles_module_bubbleList",
2032
+ userInputCollapse: "styles_module_userInputCollapse",
1927
2033
  logoArea: "styles_module_logoArea",
1928
2034
  logoContainer: "styles_module_logoContainer",
1929
2035
  staticHalo: "styles_module_staticHalo",
@@ -2496,6 +2602,7 @@ var AgentNavigate_default = memo(({ data }) => {
2496
2602
  }, [data]);
2497
2603
  const handleClick = () => {
2498
2604
  if (!content?.emit) return;
2605
+ emit(content.emit, { ...content.data, name: "luya-web-drawer" }, "nearest");
2499
2606
  };
2500
2607
  return /* @__PURE__ */ jsx(Button, { onClick: handleClick, style: { padding: 0 }, type: "link", children: content?.name || "\u70B9\u51FB\u6B64\u5904" });
2501
2608
  });
@@ -2657,12 +2764,12 @@ var DocDrawer_default = ({ title, open, onClose, paramsStr }) => {
2657
2764
  }, [paramsStr]);
2658
2765
  return /* @__PURE__ */ jsx(Drawer, { title, push: false, size: "100%", open, onClose, children: /* @__PURE__ */ jsx(Spin, { spinning: loading, children: content ? /* @__PURE__ */ jsx(XMarkdown, { content }) : /* @__PURE__ */ jsx(Empty, { className: "m-t-32" }) }) });
2659
2766
  };
2660
- var IndexQuote_default = ({ data, loading, message: message2 }) => {
2767
+ var IndexQuote_default = ({ data, loading, message: message3 }) => {
2661
2768
  const [open, setOpen] = useState(false);
2662
2769
  const citation = useMemo(() => {
2663
- const citations = message2.content?.find((item) => item.type === "citation")?.citations ?? [];
2770
+ const citations = message3.content?.find((item) => item.type === "citation")?.citations ?? [];
2664
2771
  return citations?.find((item) => String(item.citationId) === String(data.citationId));
2665
- }, [data.citationId, message2.content]);
2772
+ }, [data.citationId, message3.content]);
2666
2773
  const onClick = () => {
2667
2774
  if (!citation?.citationUrl) return;
2668
2775
  if (isExternal(citation.citationUrl)) {
@@ -2677,7 +2784,7 @@ var IndexQuote_default = ({ data, loading, message: message2 }) => {
2677
2784
  open && /* @__PURE__ */ jsx(DocDrawer_default, { paramsStr: citation?.citationUrl, title: citation?.citationName, open, onClose: () => setOpen(false) })
2678
2785
  ] });
2679
2786
  };
2680
- var MarkImg_default = ({ data, loading, message: message2, ...rest }) => {
2787
+ var MarkImg_default = ({ data, loading, message: message3, ...rest }) => {
2681
2788
  const getPreviewFileUrl = (src) => {
2682
2789
  return buildUrlParams({ [TOKEN_KEY]: tokenManager.get() || "" }, src);
2683
2790
  };
@@ -2704,11 +2811,9 @@ var MdEdit_default = ({ data, loading }) => {
2704
2811
  !loading && /* @__PURE__ */ jsx(Flex, { justify: "end", className: "m-t-16", children: /* @__PURE__ */ jsx(Button, { color: "primary", variant: "outlined", onClick: onOk, children: btnText }) })
2705
2812
  ] });
2706
2813
  };
2707
- var PreviewLink_default = ({ data, loading, message: message2, ...rest }) => {
2814
+ var PreviewLink_default = ({ data, loading, message: message3, ...rest }) => {
2708
2815
  const chatStore = useChatStore();
2709
- const getLinkFileName = (href) => {
2710
- const url = new URL(href, window.location.origin);
2711
- const path = url.searchParams.get("path") || url.pathname;
2816
+ const getLinkFileName = (path) => {
2712
2817
  const lastSegment = path.split("/").pop();
2713
2818
  if (!lastSegment) {
2714
2819
  return "link";
@@ -2719,25 +2824,13 @@ var PreviewLink_default = ({ data, loading, message: message2, ...rest }) => {
2719
2824
  return lastSegment;
2720
2825
  }
2721
2826
  };
2722
- const getPreviewFileUrl = (href) => {
2723
- return buildUrlParams({ [TOKEN_KEY]: tokenManager.get() || "" }, href);
2724
- };
2725
- const handlePreviewLink = (href) => {
2726
- const fileName = getLinkFileName(href);
2727
- const suffix = getFileSuffixName(fileName);
2728
- chatStore.setPreview({
2729
- fileUrl: getPreviewFileUrl(href),
2730
- fileName,
2731
- suffix
2732
- });
2733
- };
2734
- const handlePathToUrl = (href) => {
2735
- const fileName = getLinkFileName(href);
2827
+ const handlePreviewByPath = (path) => {
2828
+ const fileName = getLinkFileName(path);
2736
2829
  const suffix = getFileSuffixName(fileName);
2737
2830
  chatStore.setPreview({
2738
2831
  fileUrl: chatStore.config.services.request.getPreviewUrl({
2739
- path: href,
2740
- workspaceId: message2.conversationId
2832
+ path,
2833
+ workspaceId: message3.conversationId
2741
2834
  }),
2742
2835
  fileName,
2743
2836
  suffix
@@ -2750,12 +2843,18 @@ var PreviewLink_default = ({ data, loading, message: message2, ...rest }) => {
2750
2843
  return;
2751
2844
  }
2752
2845
  e.preventDefault();
2753
- if (String(rest.href).startsWith("/luya")) {
2754
- handlePreviewLink(href);
2846
+ if (String(rest.href).startsWith("/luya") || String(rest.href).startsWith("/agents")) {
2847
+ const url = new URL(href, window.location.origin);
2848
+ const path = url.searchParams.get("path");
2849
+ if (!path) {
2850
+ window.open(href, "_blank");
2851
+ return;
2852
+ }
2853
+ handlePreviewByPath(path);
2755
2854
  return;
2756
2855
  }
2757
2856
  if (String(rest.href).startsWith("/workspace")) {
2758
- handlePathToUrl(href);
2857
+ handlePreviewByPath(href);
2759
2858
  return;
2760
2859
  }
2761
2860
  window.open(href, "_blank");
@@ -2844,7 +2943,7 @@ var adaptMarkdownComponent = (Component, payloadMapRef, messageRef) => {
2844
2943
  return WrappedComponent;
2845
2944
  };
2846
2945
  var adaptMarkdownComponents = (components, payloadMapRef, messageRef) => Object.fromEntries(Object.entries(components ?? {}).map(([key, Component]) => [key, adaptMarkdownComponent(Component, payloadMapRef, messageRef)]));
2847
- var XMarkdown_default = memo(({ message: message2, components = {}, content = "", ...rest }) => {
2946
+ var XMarkdown_default = memo(({ message: message3, components = {}, content = "", ...rest }) => {
2848
2947
  const config = useMemo(() => getMarkdownConfig(), []);
2849
2948
  const formattedContent = useMemo(() => formatMixedContent(content), [content]);
2850
2949
  const newComponents = useMemo(
@@ -2870,9 +2969,9 @@ var XMarkdown_default = memo(({ message: message2, components = {}, content = ""
2870
2969
  [formattedContent, payloadTagPattern]
2871
2970
  );
2872
2971
  const payloadMapRef = useRef(payloadMap);
2873
- const messageRef = useRef(message2);
2972
+ const messageRef = useRef(message3);
2874
2973
  payloadMapRef.current = payloadMap;
2875
- messageRef.current = message2;
2974
+ messageRef.current = message3;
2876
2975
  const markdownComponents = useMemo(() => adaptMarkdownComponents(newComponents, payloadMapRef, messageRef), [payloadTagPattern]);
2877
2976
  return /* @__PURE__ */ jsx(
2878
2977
  XMarkdown,
@@ -3264,11 +3363,8 @@ var A2uiComponents = {
3264
3363
 
3265
3364
  // src/components/CustomComponents/A2uiRuntime/controller/extract.ts
3266
3365
  var A2UI_TAG_REGEX = /<A2UI\s+id="([^"]*)"\s*>([\s\S]*?)<\/A2UI>/g;
3267
- function hasA2uiTag(text) {
3268
- return typeof text === "string" && text.includes("<A2UI");
3269
- }
3270
3366
  function parseA2uiTagsFromText(text) {
3271
- if (!hasA2uiTag(text)) return [];
3367
+ if (typeof text !== "string" || !text.includes("<A2UI")) return [];
3272
3368
  const tags = [];
3273
3369
  const regex = new RegExp(A2UI_TAG_REGEX);
3274
3370
  let match;
@@ -3286,88 +3382,42 @@ function parseA2uiTagsFromText(text) {
3286
3382
  return tags;
3287
3383
  }
3288
3384
  function stripA2uiTags(text) {
3289
- if (!hasA2uiTag(text)) return text;
3290
- let result = text.replace(A2UI_TAG_REGEX, "");
3291
- result = result.replace(/<A2UI\b[\s\S]*$/, "");
3292
- return result.trim();
3293
- }
3294
- function splitA2uiTextSegments(text) {
3295
- if (typeof text !== "string" || !text.includes("<A2UI")) {
3296
- return text ? [{ type: "text", content: text }] : [];
3297
- }
3298
- const segments = [];
3299
- const regex = new RegExp(A2UI_TAG_REGEX);
3300
- let lastIndex = 0;
3301
- let match;
3302
- while ((match = regex.exec(text)) !== null) {
3303
- if (match.index > lastIndex) {
3304
- const before = text.slice(lastIndex, match.index);
3305
- if (before) segments.push({ type: "text", content: before });
3306
- }
3307
- const json = match[2].trim();
3308
- if (json) {
3309
- try {
3310
- const parsed = JSON.parse(json);
3311
- const commands = Array.isArray(parsed) ? parsed : [parsed];
3312
- const surfaceIds = commands.map((cmd) => String(cmd?.createSurface?.surfaceId || "").trim()).filter(Boolean);
3313
- if (surfaceIds.length) {
3314
- segments.push({ type: "a2ui", surfaceIds });
3315
- }
3316
- } catch {
3317
- }
3318
- }
3319
- lastIndex = regex.lastIndex;
3320
- }
3321
- if (lastIndex < text.length) {
3322
- let remaining = text.slice(lastIndex);
3323
- remaining = remaining.replace(/<A2UI\b[\s\S]*$/, "");
3324
- if (remaining) segments.push({ type: "text", content: remaining });
3325
- }
3326
- return segments.length ? segments : [];
3385
+ if (typeof text !== "string" || !text.includes("<A2UI")) return text;
3386
+ return text.replace(A2UI_TAG_REGEX, "").trim();
3327
3387
  }
3328
- function extractInlineSurfaceIdsFromMessage(message2) {
3329
- const surfaceIds = /* @__PURE__ */ new Set();
3330
- const items = Array.isArray(message2?.content) ? message2.content : [];
3331
- for (const item of items) {
3332
- if (item?.type !== "text") continue;
3333
- const text = item.messageContent || item.text || "";
3334
- if (typeof text !== "string" || !text.includes("<A2UI")) continue;
3335
- const tags = parseA2uiTagsFromText(text);
3336
- for (const tag of tags) {
3337
- for (const cmd of tag.commands) {
3338
- const sid = String(cmd?.createSurface?.surfaceId || "").trim();
3339
- if (sid) surfaceIds.add(sid);
3340
- }
3341
- }
3388
+ function extractItemTextForA2ui(item) {
3389
+ if (!item || item.type !== "toolCall") return "";
3390
+ const result = item.result;
3391
+ if (typeof result === "string") return result;
3392
+ if (result && typeof result === "object" && typeof result.stdout === "string") {
3393
+ return result.stdout;
3342
3394
  }
3343
- return surfaceIds;
3395
+ return "";
3344
3396
  }
3345
3397
  function extractDismissedSurfaceIdsFromMessages(messages) {
3346
3398
  const lastCreateIndexBySurface = /* @__PURE__ */ new Map();
3347
3399
  const lastActionIndexBySurface = /* @__PURE__ */ new Map();
3348
3400
  for (let messageIndex = 0; messageIndex < messages.length; messageIndex++) {
3349
- const message2 = messages[messageIndex];
3350
- const items = Array.isArray(message2?.content) ? message2.content : [];
3401
+ const message3 = messages[messageIndex];
3402
+ const items = Array.isArray(message3?.content) ? message3.content : [];
3351
3403
  for (const item of items) {
3352
- if (message2?.role !== 1) {
3404
+ if (message3?.role !== 1) {
3353
3405
  if (item?.type === "a2uiCommand" && item.command) {
3354
3406
  const surfaceId = String(item.command?.createSurface?.surfaceId || "").trim();
3355
3407
  if (surfaceId) lastCreateIndexBySurface.set(surfaceId, messageIndex);
3356
3408
  }
3357
- if (item?.type === "text") {
3358
- const text = item.messageContent || item.text || "";
3359
- if (typeof text === "string" && text.includes("<A2UI")) {
3360
- const tags = parseA2uiTagsFromText(text);
3361
- for (const tag of tags) {
3362
- for (const cmd of tag.commands) {
3363
- const surfaceId = String(cmd?.createSurface?.surfaceId || "").trim();
3364
- if (surfaceId) lastCreateIndexBySurface.set(surfaceId, messageIndex);
3365
- }
3409
+ const text = extractItemTextForA2ui(item);
3410
+ if (typeof text === "string" && text.includes("<A2UI")) {
3411
+ const tags = parseA2uiTagsFromText(text);
3412
+ for (const tag of tags) {
3413
+ for (const cmd of tag.commands) {
3414
+ const surfaceId = String(cmd?.createSurface?.surfaceId || "").trim();
3415
+ if (surfaceId) lastCreateIndexBySurface.set(surfaceId, messageIndex);
3366
3416
  }
3367
3417
  }
3368
3418
  }
3369
3419
  }
3370
- if (message2?.role === 1 && item?.type === "text") {
3420
+ if (message3?.role === 1 && item?.type === "text") {
3371
3421
  const text = item.messageContent || item.text || "";
3372
3422
  if (typeof text !== "string" || !text.includes("a2ui_action.v1")) continue;
3373
3423
  try {
@@ -3889,28 +3939,6 @@ function sanitizeA2uiCommands(commands) {
3889
3939
  return rest;
3890
3940
  });
3891
3941
  }
3892
- function diffConversationMessages(messages, prevCursors) {
3893
- if (messages.length < prevCursors.length) {
3894
- return { shouldReplayAll: true, nextCursors: [], pendingItems: [] };
3895
- }
3896
- const nextCursors = [];
3897
- const pendingItems = [];
3898
- for (let messageIndex = 0; messageIndex < messages.length; messageIndex += 1) {
3899
- const message2 = messages[messageIndex];
3900
- const messageId = String(message2?.messageId ?? messageIndex);
3901
- const items = Array.isArray(message2?.content) ? message2.content : [];
3902
- const prevCursor = prevCursors[messageIndex];
3903
- const startIndex = prevCursor ? prevCursor.contentLength : 0;
3904
- if (prevCursor && (prevCursor.messageId !== messageId || items.length < prevCursor.contentLength)) {
3905
- return { shouldReplayAll: true, nextCursors: [], pendingItems: [] };
3906
- }
3907
- for (let itemIndex = startIndex; itemIndex < items.length; itemIndex += 1) {
3908
- pendingItems.push({ messageIndex, messageId, item: items[itemIndex] });
3909
- }
3910
- nextCursors.push({ messageId, contentLength: items.length });
3911
- }
3912
- return { shouldReplayAll: false, nextCursors, pendingItems };
3913
- }
3914
3942
  function initializeWizardSurface(state, surfaceId, effects, nextWizardSteps) {
3915
3943
  const wizard = state.wizardSchemaBySurface[surfaceId];
3916
3944
  const createCommandIndex = state.latestCreateCommandIndexBySurface[surfaceId];
@@ -3930,6 +3958,10 @@ function initializeWizardSurface(state, surfaceId, effects, nextWizardSteps) {
3930
3958
  function processA2uiCommand(cmd, messageIndex, messageId, nextState, effects, deletedSurfaceIds, nextWizardSteps) {
3931
3959
  nextState.serverCommands.push(cmd);
3932
3960
  nextState.lastA2uiHost = { id: messageId, index: messageIndex };
3961
+ const wizardSchema = normalizeWizardSchema(cmd);
3962
+ if (wizardSchema) {
3963
+ nextState.wizardSchemaBySurface[wizardSchema.surfaceId] = wizardSchema;
3964
+ }
3933
3965
  const surfaceId = extractSurfaceId2(cmd);
3934
3966
  if (!surfaceId) return;
3935
3967
  if (cmd?.createSurface) {
@@ -3940,6 +3972,11 @@ function processA2uiCommand(cmd, messageIndex, messageId, nextState, effects, de
3940
3972
  if (cmd?.createSurface) {
3941
3973
  nextState.latestCreateCommandIndexBySurface[surfaceId] = nextState.serverCommands.length - 1;
3942
3974
  nextState.optimisticallyDismissedSurfaceIds = nextState.optimisticallyDismissedSurfaceIds.filter((id) => id !== surfaceId);
3975
+ const schemaSource = cmd.createSurface.schema ?? cmd.createSurface.wizard ?? cmd.createSurface.plan;
3976
+ const schema = normalizeWizardSchema(schemaSource) ?? normalizeWizardSchema(cmd.createSurface);
3977
+ if (schema) {
3978
+ nextState.wizardSchemaBySurface[surfaceId] = schema;
3979
+ }
3943
3980
  initializeWizardSurface(nextState, surfaceId, effects, nextWizardSteps);
3944
3981
  }
3945
3982
  if (cmd?.updateDataModel) {
@@ -3956,16 +3993,37 @@ function processA2uiCommand(cmd, messageIndex, messageId, nextState, effects, de
3956
3993
  delete nextState.modelPathBySurface[surfaceId];
3957
3994
  }
3958
3995
  }
3996
+ function diffConversationMessages(messages, prevCursors) {
3997
+ if (messages.length < prevCursors.length) {
3998
+ return { shouldReplayAll: true, nextCursors: [], pendingItems: [] };
3999
+ }
4000
+ const nextCursors = [];
4001
+ const pendingItems = [];
4002
+ for (let messageIndex = 0; messageIndex < messages.length; messageIndex += 1) {
4003
+ const message3 = messages[messageIndex];
4004
+ const messageId = String(message3?.messageId ?? messageIndex);
4005
+ const items = Array.isArray(message3?.content) ? message3.content : [];
4006
+ const prevCursor = prevCursors[messageIndex];
4007
+ const startIndex = prevCursor ? prevCursor.contentLength : 0;
4008
+ if (prevCursor && (prevCursor.messageId !== messageId || items.length < prevCursor.contentLength)) {
4009
+ return { shouldReplayAll: true, nextCursors: [], pendingItems: [] };
4010
+ }
4011
+ for (let itemIndex = startIndex; itemIndex < items.length; itemIndex += 1) {
4012
+ pendingItems.push({ messageIndex, messageId, item: items[itemIndex] });
4013
+ }
4014
+ nextCursors.push({ messageId, contentLength: items.length });
4015
+ }
4016
+ return { shouldReplayAll: false, nextCursors, pendingItems };
4017
+ }
3959
4018
  function scanA2uiTagsFromMessages(messages, processedTagIds) {
3960
4019
  const newTags = [];
3961
4020
  const newTagIds = [];
3962
4021
  for (let messageIndex = 0; messageIndex < messages.length; messageIndex += 1) {
3963
- const message2 = messages[messageIndex];
3964
- const messageId = String(message2?.messageId ?? messageIndex);
3965
- const items = Array.isArray(message2?.content) ? message2.content : [];
4022
+ const message3 = messages[messageIndex];
4023
+ const messageId = String(message3?.messageId ?? messageIndex);
4024
+ const items = Array.isArray(message3?.content) ? message3.content : [];
3966
4025
  for (const item of items) {
3967
- if (item?.type !== "text") continue;
3968
- const text = item.messageContent || item.text || "";
4026
+ const text = extractItemTextForA2ui(item);
3969
4027
  if (typeof text !== "string" || !text.includes("<A2UI")) continue;
3970
4028
  const tags = parseA2uiTagsFromText(text);
3971
4029
  for (const tag of tags) {
@@ -3980,14 +4038,9 @@ function scanA2uiTagsFromMessages(messages, processedTagIds) {
3980
4038
  }
3981
4039
  function reduceA2uiRuntimeMessages(state, messages) {
3982
4040
  const { shouldReplayAll, pendingItems, nextCursors } = diffConversationMessages(messages || [], state.processedMessageCursors);
3983
- const itemsToProcess = shouldReplayAll ? messages.flatMap((message2, messageIndex) => {
3984
- const messageId = String(message2?.messageId ?? messageIndex);
3985
- const items = Array.isArray(message2?.content) ? message2.content : [];
3986
- return items.map((item) => ({ messageIndex, messageId, item }));
3987
- }) : pendingItems;
3988
4041
  const tagProcessedSet = new Set(shouldReplayAll ? [] : state.processedTagIds);
3989
4042
  const { newTags, newTagIds } = scanA2uiTagsFromMessages(messages || [], tagProcessedSet);
3990
- if (!shouldReplayAll && itemsToProcess.length === 0 && newTags.length === 0) {
4043
+ if (!shouldReplayAll && pendingItems.length === 0 && newTags.length === 0) {
3991
4044
  return { state, effects: [] };
3992
4045
  }
3993
4046
  const nextState = shouldReplayAll ? createA2uiRuntimeState() : { ...state };
@@ -4006,7 +4059,7 @@ function reduceA2uiRuntimeMessages(state, messages) {
4006
4059
  const effects = shouldReplayAll ? [{ type: "reset-model-store" }] : [];
4007
4060
  const deletedSurfaceIds = /* @__PURE__ */ new Set();
4008
4061
  const nextWizardSteps = {};
4009
- itemsToProcess.forEach(({ item, messageIndex, messageId }) => {
4062
+ pendingItems.forEach(({ item, messageIndex, messageId }) => {
4010
4063
  if (item?.type === "a2uiSchema") {
4011
4064
  const schema = normalizeWizardSchema(item.schema);
4012
4065
  if (schema) {
@@ -4024,9 +4077,9 @@ function reduceA2uiRuntimeMessages(state, messages) {
4024
4077
  processA2uiCommand(cmd, messageIndex, messageId, nextState, effects, deletedSurfaceIds, nextWizardSteps);
4025
4078
  }
4026
4079
  });
4027
- nextState.processedMessageCursors = shouldReplayAll ? messages.map((message2, messageIndex) => ({
4028
- messageId: String(message2?.messageId ?? messageIndex),
4029
- contentLength: Array.isArray(message2?.content) ? message2.content.length : 0
4080
+ nextState.processedMessageCursors = shouldReplayAll ? messages.map((message3, messageIndex) => ({
4081
+ messageId: String(message3?.messageId ?? messageIndex),
4082
+ contentLength: Array.isArray(message3?.content) ? message3.content.length : 0
4030
4083
  })) : nextCursors;
4031
4084
  nextState.wizardStepBySurface = { ...nextState.wizardStepBySurface, ...nextWizardSteps };
4032
4085
  if (deletedSurfaceIds.size) {
@@ -4175,11 +4228,9 @@ var A2uiRuntimeContext = React10__default.createContext({
4175
4228
  function useA2uiRuntimeView() {
4176
4229
  return React10__default.useContext(A2uiRuntimeContext);
4177
4230
  }
4178
- function A2uiMessageCards({ messageIndex, message: message2 }) {
4231
+ function A2uiMessageCards({ messageIndex }) {
4179
4232
  const { surfaceIdsByMessageIndex } = useA2uiRuntimeView();
4180
- const allSurfaceIds = surfaceIdsByMessageIndex[messageIndex] || [];
4181
- const inlineSurfaceIds = message2 ? extractInlineSurfaceIdsFromMessage(message2) : /* @__PURE__ */ new Set();
4182
- const surfaceIds = allSurfaceIds.filter((id) => !inlineSurfaceIds.has(id));
4233
+ const surfaceIds = surfaceIdsByMessageIndex[messageIndex] || [];
4183
4234
  if (!surfaceIds.length) return null;
4184
4235
  return /* @__PURE__ */ jsx("div", { children: surfaceIds.map((surfaceId) => /* @__PURE__ */ jsx(XCard.Card, { id: surfaceId }, surfaceId)) });
4185
4236
  }
@@ -4376,8 +4427,8 @@ function readContextModelPath(context) {
4376
4427
  function buildLatestCommandIndexBySurface(messages) {
4377
4428
  const indexBySurface = {};
4378
4429
  let commandIndex = -1;
4379
- for (const message2 of messages) {
4380
- const items = Array.isArray(message2?.content) ? message2.content : [];
4430
+ for (const message3 of messages) {
4431
+ const items = Array.isArray(message3?.content) ? message3.content : [];
4381
4432
  for (const item of items) {
4382
4433
  if (item?.type === "a2uiCommand" && item.command) {
4383
4434
  commandIndex += 1;
@@ -4385,16 +4436,14 @@ function buildLatestCommandIndexBySurface(messages) {
4385
4436
  if (surfaceId) indexBySurface[surfaceId] = commandIndex;
4386
4437
  continue;
4387
4438
  }
4388
- if (item?.type === "text") {
4389
- const text = item.messageContent || item.text || "";
4390
- if (typeof text !== "string" || !text.includes("<A2UI")) continue;
4391
- const tags = parseA2uiTagsFromText(text);
4392
- for (const tag of tags) {
4393
- for (const cmd of tag.commands) {
4394
- commandIndex += 1;
4395
- const surfaceId = extractSurfaceId3(cmd);
4396
- if (surfaceId) indexBySurface[surfaceId] = commandIndex;
4397
- }
4439
+ const text = extractItemTextForA2ui(item);
4440
+ if (typeof text !== "string" || !text.includes("<A2UI")) continue;
4441
+ const tags = parseA2uiTagsFromText(text);
4442
+ for (const tag of tags) {
4443
+ for (const cmd of tag.commands) {
4444
+ commandIndex += 1;
4445
+ const surfaceId = extractSurfaceId3(cmd);
4446
+ if (surfaceId) indexBySurface[surfaceId] = commandIndex;
4398
4447
  }
4399
4448
  }
4400
4449
  }
@@ -4533,6 +4582,8 @@ var RunStartedNode = React10__default.memo(({ loading }) => {
4533
4582
  if (!loading) return null;
4534
4583
  return /* @__PURE__ */ jsx(Flex, { gap: 8, align: "center", className: style_module_default2.runStartedNode, children: /* @__PURE__ */ jsx(LoadingOutlined, { style: { color: "#1677ff" } }) });
4535
4584
  });
4585
+ var RESOURCE_MARKDOWN_TAG = "resourcetag";
4586
+ var RESOURCE_TOKEN_REGEX = /(\w+):\/\/([^?\s]+)\?name=([^&\s]+)&label=([^\s]+)/g;
4536
4587
  function QuestionSummary({ content }) {
4537
4588
  const answer = content.replace(/^Question:\s*/, "").trim() || "\u5DF2\u56DE\u7B54";
4538
4589
  return /* @__PURE__ */ jsxs("span", { style: { display: "inline-flex", flexDirection: "column", gap: 4 }, children: [
@@ -4540,38 +4591,41 @@ function QuestionSummary({ content }) {
4540
4591
  /* @__PURE__ */ jsx("span", { style: { fontSize: 13, color: "#262626", lineHeight: 1.6, whiteSpace: "pre-wrap" }, children: answer })
4541
4592
  ] });
4542
4593
  }
4594
+ function MessageResourceTag({ data }) {
4595
+ const resource = data;
4596
+ if (!resource) return null;
4597
+ return /* @__PURE__ */ jsx(ReadonlyResourceTag, { resource });
4598
+ }
4599
+ function transformResourceText(content) {
4600
+ return content.replace(RESOURCE_TOKEN_REGEX, (_, resourceType, resourceId, resourceName, resourceLabel) => {
4601
+ const resource = {
4602
+ resourceType: decodeURIComponent(resourceType),
4603
+ resourceId: decodeURIComponent(resourceId),
4604
+ resourceName: decodeURIComponent(resourceName),
4605
+ resourceLabel: decodeURIComponent(resourceLabel)
4606
+ };
4607
+ return `<${RESOURCE_MARKDOWN_TAG}>${JSON.stringify(resource)}</${RESOURCE_MARKDOWN_TAG}>`;
4608
+ });
4609
+ }
4543
4610
  var TextNode2 = React10__default.memo(
4544
4611
  ({
4545
4612
  item,
4546
4613
  role,
4547
4614
  customComponents,
4548
- message: message2,
4549
- messageIndex = -1
4615
+ message: message3
4550
4616
  }) => {
4551
- const { surfaceIdsByMessageIndex } = useA2uiRuntimeView();
4552
- const rawContent = toA2uiDisplayText(role, item?.messageContent);
4553
- const segments = splitA2uiTextSegments(rawContent);
4554
- const visibleSurfaceIds = messageIndex >= 0 ? new Set(surfaceIdsByMessageIndex[messageIndex] || []) : null;
4555
- const firstSeg = segments[0];
4556
- const isPureText = segments.length === 0 || segments.length === 1 && firstSeg.type === "text";
4557
- if (isPureText) {
4558
- const content = firstSeg && firstSeg.type === "text" ? firstSeg.content : "";
4559
- if (typeof content === "string" && content.startsWith("Question:")) {
4560
- return /* @__PURE__ */ jsx(QuestionSummary, { content });
4561
- }
4562
- return /* @__PURE__ */ jsxs(Fragment, { children: [
4563
- !!item.reasoningContent && /* @__PURE__ */ jsx(Think, { title: "\u6DF1\u5EA6\u601D\u8003", children: item.reasoningContent }),
4564
- !!content && /* @__PURE__ */ jsx(XMarkdown_default, { message: message2, components: customComponents, content })
4565
- ] });
4617
+ const content = toA2uiDisplayText(role, item?.messageContent);
4618
+ const markdownComponents = {
4619
+ [RESOURCE_MARKDOWN_TAG]: MessageResourceTag,
4620
+ ...customComponents
4621
+ };
4622
+ if (typeof content === "string" && content.startsWith("Question:")) {
4623
+ return /* @__PURE__ */ jsx(QuestionSummary, { content });
4566
4624
  }
4625
+ const markdownContent = typeof content === "string" ? transformResourceText(content) : content;
4567
4626
  return /* @__PURE__ */ jsxs(Fragment, { children: [
4568
4627
  !!item.reasoningContent && /* @__PURE__ */ jsx(Think, { title: "\u6DF1\u5EA6\u601D\u8003", children: item.reasoningContent }),
4569
- segments.map((seg, i) => {
4570
- if (seg.type === "text") {
4571
- return seg.content.trim() ? /* @__PURE__ */ jsx(XMarkdown_default, { message: message2, components: customComponents, content: seg.content }, `text-${i}`) : null;
4572
- }
4573
- return seg.surfaceIds.filter((sid) => !visibleSurfaceIds || visibleSurfaceIds.has(sid)).map((sid) => /* @__PURE__ */ jsx(XCard.Card, { id: sid }, `a2ui-${i}-${sid}`));
4574
- })
4628
+ !!markdownContent && /* @__PURE__ */ jsx(XMarkdown_default, { message: message3, components: markdownComponents, content: markdownContent })
4575
4629
  ] });
4576
4630
  }
4577
4631
  );
@@ -4669,6 +4723,15 @@ var getToolRenderConfig = (toolName) => {
4669
4723
  alwaysShowContent: false
4670
4724
  };
4671
4725
  };
4726
+ function stripA2uiTagsFromResult(result) {
4727
+ if (!result || typeof result !== "object" || Array.isArray(result)) return result;
4728
+ const cleaned = {};
4729
+ for (const [key, value] of Object.entries(result)) {
4730
+ cleaned[key] = typeof value === "string" && value.includes("<A2UI") ? stripA2uiTags(value) : value;
4731
+ }
4732
+ const hasVisible = Object.values(cleaned).some((v) => v !== "" && v !== null && v !== void 0);
4733
+ return hasVisible ? cleaned : null;
4734
+ }
4672
4735
  var formatContent = (content) => {
4673
4736
  try {
4674
4737
  if (!content) return { text: "", isJson: false, parsed: null };
@@ -4679,9 +4742,11 @@ var formatContent = (content) => {
4679
4742
  if (typeof parsed === "object" && parsed !== null) {
4680
4743
  return { text: JSON.stringify(parsed, null, 2), isJson: true, parsed };
4681
4744
  }
4682
- return { text: content, isJson: false, parsed: null };
4745
+ const stripped = content.includes("<A2UI") ? stripA2uiTags(content) : content;
4746
+ return { text: stripped, isJson: false, parsed: null };
4683
4747
  } catch {
4684
- return { text: typeof content === "string" ? content : "", isJson: false, parsed: null };
4748
+ const text = typeof content === "string" ? content.includes("<A2UI") ? stripA2uiTags(content) : content : "";
4749
+ return { text, isJson: false, parsed: null };
4685
4750
  }
4686
4751
  };
4687
4752
  var ToolCallItem = ({ item }) => {
@@ -4695,7 +4760,12 @@ var ToolCallItem = ({ item }) => {
4695
4760
  return "running";
4696
4761
  }, [item.status, item.errorMessage, item.result]);
4697
4762
  const argsContent = useMemo(() => formatContent(item.arguments || item.content), [item.arguments, item.content]);
4698
- const resultContent = useMemo(() => item.result ? formatContent(item.result) : null, [item.result]);
4763
+ const resultContent = useMemo(() => {
4764
+ if (!item.result) return null;
4765
+ const cleanedResult = stripA2uiTagsFromResult(item.result);
4766
+ if (!cleanedResult) return null;
4767
+ return formatContent(cleanedResult);
4768
+ }, [item.result]);
4699
4769
  const hasContent = useMemo(() => {
4700
4770
  if (renderConfig.disableExpandOnError && status === "error") return false;
4701
4771
  let alwaysShow = false;
@@ -4786,10 +4856,10 @@ var ToolCallItem = ({ item }) => {
4786
4856
  );
4787
4857
  };
4788
4858
  var tool_call_item_default = ToolCallItem;
4789
- var RENDERABLE_MESSAGE_TYPES = ["runStarted", "toolCall", "toolResult", "text", "stepError", "files", "plan"];
4790
- var MessageRender_default = React10__default.memo(({ role, message: message2, messageIndex = -1, loading, containerRef, customComponents }) => {
4859
+ var RENDERABLE_MESSAGE_TYPES = ["runStarted", "toolCall", "toolResult", "text", "stepError", "runFailed", "files", "plan"];
4860
+ var MessageRender_default = React10__default.memo(({ role, message: message3, messageIndex = -1, loading, containerRef, customComponents }) => {
4791
4861
  const content = useMemo(() => {
4792
- return (message2.content || []).filter((item) => {
4862
+ return (message3.content || []).filter((item) => {
4793
4863
  if (!RENDERABLE_MESSAGE_TYPES.includes(item.type)) {
4794
4864
  return false;
4795
4865
  }
@@ -4801,18 +4871,16 @@ var MessageRender_default = React10__default.memo(({ role, message: message2, me
4801
4871
  }
4802
4872
  if (item.type === "text") {
4803
4873
  const rawText = item.messageContent || item.text || "";
4804
- const visibleText = stripA2uiTags(rawText);
4805
- const hasA2uiTag2 = typeof rawText === "string" && rawText.includes("<A2UI");
4806
- return !!visibleText.trim() || !!item.reasoningContent || hasA2uiTag2;
4874
+ return !!rawText.trim() || !!item.reasoningContent;
4807
4875
  }
4808
4876
  return true;
4809
4877
  });
4810
- }, [loading, message2.content]);
4878
+ }, [loading, message3.content]);
4811
4879
  const quoteMsg = useMemo(() => {
4812
4880
  const quoteMsg2 = {};
4813
- if (message2.params) {
4881
+ if (message3.params) {
4814
4882
  try {
4815
- const citation = JSON.parse(message2.params).citation;
4883
+ const citation = JSON.parse(message3.params).citation;
4816
4884
  if (citation) {
4817
4885
  quoteMsg2.messageContent = citation;
4818
4886
  }
@@ -4820,11 +4888,18 @@ var MessageRender_default = React10__default.memo(({ role, message: message2, me
4820
4888
  }
4821
4889
  }
4822
4890
  return isEmptyObj(quoteMsg2) ? null : quoteMsg2;
4823
- }, [message2.params, message2.quoteMsg]);
4891
+ }, [message3.params, message3.quoteMsg]);
4824
4892
  if (content.length === 0) return null;
4893
+ const lastToolCallIndex = (() => {
4894
+ let lastIdx = -1;
4895
+ content.forEach((item, i) => {
4896
+ if (item.type === "toolCall" || item.type === "toolResult") lastIdx = i;
4897
+ });
4898
+ return lastIdx;
4899
+ })();
4825
4900
  return /* @__PURE__ */ jsxs(Flex, { ref: containerRef, vertical: true, gap: 8, children: [
4826
- content.map((item, index) => {
4827
- return /* @__PURE__ */ jsx(
4901
+ content.map((item, index) => /* @__PURE__ */ jsxs(React10__default.Fragment, { children: [
4902
+ /* @__PURE__ */ jsx(
4828
4903
  Bubble,
4829
4904
  {
4830
4905
  role: role.user,
@@ -4833,17 +4908,26 @@ var MessageRender_default = React10__default.memo(({ role, message: message2, me
4833
4908
  content: /* @__PURE__ */ jsxs(Fragment, { children: [
4834
4909
  item.type === "runStarted" && /* @__PURE__ */ jsx(RunStartedNode, { loading }, `flow-start-${index}`),
4835
4910
  (item.type === "toolCall" || item.type === "toolResult") && /* @__PURE__ */ jsx(tool_call_item_default, { item }, `tool-call-${item.toolCallId || index}`),
4836
- item.type === "text" && /* @__PURE__ */ jsx(TextNode2, { item, role: message2.role, customComponents, message: message2, messageIndex }, `message-${index}`),
4837
- item.type === "stepError" && (item.errorMessage ? /* @__PURE__ */ jsx(XMarkdown_default, { message: message2, components: customComponents, content: item.errorMessage }) : null),
4911
+ item.type === "text" && /* @__PURE__ */ jsx(
4912
+ TextNode2,
4913
+ {
4914
+ item,
4915
+ role: message3.role,
4916
+ customComponents,
4917
+ message: message3,
4918
+ messageIndex
4919
+ },
4920
+ `message-${index}`
4921
+ ),
4922
+ (item.type === "stepError" || item.type === "runFailed") && (item.errorMessage ? /* @__PURE__ */ jsx(XMarkdown_default, { message: message3, components: customComponents, content: item.errorMessage }) : null),
4838
4923
  item.type === "files" && /* @__PURE__ */ jsx(FilesNode, { item }, `files-${index}`),
4839
4924
  item.type === "plan" && /* @__PURE__ */ jsx(A2uiPlanNode, { item }, `plan-${index}`)
4840
4925
  ] })
4841
- },
4842
- `message-${index}`
4843
- );
4844
- }),
4845
- quoteMsg && /* @__PURE__ */ jsx(QuoteMsgNode, { quoteMsg, role }),
4846
- messageIndex >= 0 ? /* @__PURE__ */ jsx(A2uiMessageCards, { messageIndex, message: message2 }) : null
4926
+ }
4927
+ ),
4928
+ index === lastToolCallIndex && messageIndex >= 0 ? /* @__PURE__ */ jsx(A2uiMessageCards, { messageIndex, message: message3 }) : null
4929
+ ] }, `message-${index}`)),
4930
+ quoteMsg && /* @__PURE__ */ jsx(QuoteMsgNode, { quoteMsg, role })
4847
4931
  ] });
4848
4932
  });
4849
4933
  var WelcomeItem_default = ({ icon = true, title = true, description = true, prompts = true }) => {
@@ -4936,13 +5020,13 @@ var BubbleListItems_default = ({
4936
5020
  const messageRefs = useRef({});
4937
5021
  const chatRecords = useMemo(() => {
4938
5022
  const chatRecords2 = [];
4939
- conversationMessages.forEach((message2, messageIndex) => {
4940
- const role = getRole(message2.role);
5023
+ conversationMessages.forEach((message3, messageIndex) => {
5024
+ const role = getRole(message3.role);
4941
5025
  const isLeftBubble = role.user === "agent";
4942
- const isMessageLoading = !!message2.generating;
4943
- const baseKey = `${message2.executionId}-${messageIndex}`;
5026
+ const isMessageLoading = !!message3.generating;
5027
+ const baseKey = `${message3.executionId}-${messageIndex}`;
4944
5028
  const footerNode = !isMessageLoading ? /* @__PURE__ */ jsxs(Flex, { align: "center", gap: 8, children: [
4945
- message2.stopFlag && isLeftBubble && /* @__PURE__ */ jsx(Text3, { type: "secondary", style: { flex: "none" }, children: "\u5DF2\u505C\u6B62" }),
5029
+ message3.stopFlag && isLeftBubble && /* @__PURE__ */ jsx(Text3, { type: "secondary", style: { flex: "none" }, children: "\u5DF2\u505C\u6B62" }),
4946
5030
  /* @__PURE__ */ jsx(Flex, { align: "center", gap: 4, children: role.user === "agent" && /* @__PURE__ */ jsxs(Fragment, { children: [
4947
5031
  /* @__PURE__ */ jsx(
4948
5032
  Button,
@@ -4962,21 +5046,21 @@ var BubbleListItems_default = ({
4962
5046
  /* @__PURE__ */ jsx(
4963
5047
  Button,
4964
5048
  {
4965
- color: message2.feedback === 1 ? "primary" : "default",
5049
+ color: message3.feedback === 1 ? "primary" : "default",
4966
5050
  size: "small",
4967
5051
  variant: "text",
4968
5052
  icon: /* @__PURE__ */ jsx(LikeOutlined, {}),
4969
- onClick: () => chatStore.feedback(message2.executionId, 1, messageIndex)
5053
+ onClick: () => chatStore.feedback(message3.executionId, 1, messageIndex)
4970
5054
  }
4971
5055
  ),
4972
5056
  /* @__PURE__ */ jsx(
4973
5057
  Button,
4974
5058
  {
4975
- color: message2.feedback === 2 ? "primary" : "default",
5059
+ color: message3.feedback === 2 ? "primary" : "default",
4976
5060
  size: "small",
4977
5061
  variant: "text",
4978
5062
  icon: /* @__PURE__ */ jsx(DislikeOutlined, {}),
4979
- onClick: () => chatStore.feedback(message2.executionId, 2, messageIndex)
5063
+ onClick: () => chatStore.feedback(message3.executionId, 2, messageIndex)
4980
5064
  }
4981
5065
  ),
4982
5066
  /* @__PURE__ */ jsx(
@@ -4984,7 +5068,7 @@ var BubbleListItems_default = ({
4984
5068
  {
4985
5069
  control: agentActions,
4986
5070
  ctx: {
4987
- message: message2,
5071
+ message: message3,
4988
5072
  get dom() {
4989
5073
  return messageRefs.current[baseKey];
4990
5074
  }
@@ -5002,7 +5086,7 @@ var BubbleListItems_default = ({
5002
5086
  MessageRender_default,
5003
5087
  {
5004
5088
  role,
5005
- message: message2,
5089
+ message: message3,
5006
5090
  messageIndex,
5007
5091
  customComponents,
5008
5092
  loading: isMessageLoading,
@@ -5581,6 +5665,313 @@ var ChatSenderHeader = () => {
5581
5665
  ] });
5582
5666
  };
5583
5667
  var ChatSenderHeader_default = ChatSenderHeader;
5668
+ var MonacoEditor = ({ value = "", onChange, placeholder, height = 200, readOnly = false, style }) => {
5669
+ const handleKeyDownCapture = useCallback((e) => {
5670
+ if (e.key === " " || e.code === "Space") {
5671
+ e.stopPropagation();
5672
+ }
5673
+ }, []);
5674
+ const handleKeyUpCapture = useCallback((e) => {
5675
+ if (e.key === " " || e.code === "Space") {
5676
+ e.stopPropagation();
5677
+ }
5678
+ }, []);
5679
+ const handleScriptChange = useCallback(
5680
+ (event) => {
5681
+ onChange?.(event.target.value || "");
5682
+ },
5683
+ [onChange]
5684
+ );
5685
+ return /* @__PURE__ */ jsx("div", { style, onKeyDownCapture: handleKeyDownCapture, onKeyUpCapture: handleKeyUpCapture, children: /* @__PURE__ */ jsx(
5686
+ Input.TextArea,
5687
+ {
5688
+ value,
5689
+ onChange: handleScriptChange,
5690
+ readOnly,
5691
+ placeholder,
5692
+ autoSize: false,
5693
+ style: {
5694
+ height,
5695
+ resize: "vertical",
5696
+ fontFamily: 'Monaco, Menlo, Consolas, "Courier New", monospace',
5697
+ ...style
5698
+ }
5699
+ }
5700
+ ) });
5701
+ };
5702
+ var MonacoEditor_default = MonacoEditor;
5703
+ var { Text: Text8 } = Typography;
5704
+ var FormFileUpload = ({ value, onChange, multiple = false }) => {
5705
+ const { token } = theme.useToken();
5706
+ const fileList = Array.isArray(value) ? value : value ? [value] : [];
5707
+ const chatStore = useChatStore();
5708
+ const conversationState = useSnapshot(chatStore.conversation);
5709
+ const agentState = useSnapshot(chatStore.agent);
5710
+ const configState = useSnapshot(chatStore.config);
5711
+ const customRequest = async (options) => {
5712
+ const { file, onSuccess, onError } = options;
5713
+ try {
5714
+ const formData = new FormData();
5715
+ formData.append("file", file);
5716
+ const params = {
5717
+ workspaceType: "conversation" /* CONVERSATION */,
5718
+ agentId: agentState.agentInfo.id,
5719
+ workspaceId: conversationState.active.id
5720
+ };
5721
+ const res = await configState.services.request.chatUpload(params, formData);
5722
+ if (res.code === 200 && res.data?.length) {
5723
+ const uploadedFile = res.data[0];
5724
+ onSuccess(uploadedFile);
5725
+ if (multiple) {
5726
+ onChange?.([...fileList, uploadedFile]);
5727
+ } else {
5728
+ onChange?.([uploadedFile]);
5729
+ }
5730
+ } else {
5731
+ message.error(res.message || "\u4E0A\u4F20\u5931\u8D25");
5732
+ onError(new Error(res.message));
5733
+ }
5734
+ } catch (error) {
5735
+ onError(error);
5736
+ }
5737
+ };
5738
+ const handleRemove = (fileToRemove) => {
5739
+ const newList = fileList.filter((f) => f.id !== fileToRemove.id);
5740
+ onChange?.(newList.length > 0 ? newList : void 0);
5741
+ };
5742
+ return /* @__PURE__ */ jsxs(Flex, { vertical: true, gap: 12, style: { width: "100%" }, children: [
5743
+ !multiple && fileList.length >= 1 ? null : /* @__PURE__ */ jsx(Upload, { multiple, customRequest, showUploadList: false, children: /* @__PURE__ */ jsx(Button, { icon: /* @__PURE__ */ jsx(CloudUploadOutlined, {}), children: "\u4ECE\u672C\u5730\u4E0A\u4F20" }) }),
5744
+ fileList.length > 0 && /* @__PURE__ */ jsx(Flex, { vertical: true, gap: 8, children: fileList.map((file) => /* @__PURE__ */ jsxs(
5745
+ Flex,
5746
+ {
5747
+ align: "center",
5748
+ justify: "space-between",
5749
+ style: {
5750
+ padding: "8px 12px",
5751
+ backgroundColor: token.colorFillAlter,
5752
+ borderRadius: token.borderRadiusLG || 8,
5753
+ border: `1px solid ${token.colorBorderSecondary}`
5754
+ },
5755
+ children: [
5756
+ /* @__PURE__ */ jsxs(Flex, { align: "center", gap: 12, style: { overflow: "hidden", flex: 1 }, children: [
5757
+ /* @__PURE__ */ jsx(
5758
+ "div",
5759
+ {
5760
+ style: {
5761
+ width: 40,
5762
+ height: 40,
5763
+ backgroundColor: "#000",
5764
+ borderRadius: token.borderRadiusSM || 4,
5765
+ display: "flex",
5766
+ alignItems: "center",
5767
+ justifyContent: "center",
5768
+ flexShrink: 0
5769
+ },
5770
+ children: getFileIcon(file.extension || getFileSuffixName(file.name), 20)
5771
+ }
5772
+ ),
5773
+ /* @__PURE__ */ jsxs("div", { style: { overflow: "hidden", display: "flex", flexDirection: "column", flex: 1 }, children: [
5774
+ /* @__PURE__ */ jsx(Text8, { ellipsis: true, style: { width: "100%", fontSize: 14, fontWeight: 500 }, children: file.name }),
5775
+ /* @__PURE__ */ jsxs(Text8, { type: "secondary", style: { fontSize: 12 }, children: [
5776
+ (file.extension || getFileSuffixName(file.name)).toUpperCase(),
5777
+ " \u2022 ",
5778
+ formatFileSize(file.size)
5779
+ ] })
5780
+ ] })
5781
+ ] }),
5782
+ /* @__PURE__ */ jsx(Button, { type: "text", icon: /* @__PURE__ */ jsx(DeleteOutlined, {}), onClick: () => handleRemove(file), style: { color: token.colorTextSecondary } })
5783
+ ]
5784
+ },
5785
+ file.id || file.uid
5786
+ )) })
5787
+ ] });
5788
+ };
5789
+ var FormMonacoEditor = ({ value, onChange }) => {
5790
+ const { token } = theme.useToken();
5791
+ return /* @__PURE__ */ jsx("div", { style: { backgroundColor: token.colorFillAlter, padding: 8, borderRadius: token.borderRadius }, children: /* @__PURE__ */ jsx(MonacoEditor_default, { language: "json", placeholder: "\u8BF7\u8F93\u5165\u503C...", height: 80, value, onChange }) });
5792
+ };
5793
+ var UserInputPanel = () => {
5794
+ const chatStore = useChatStore();
5795
+ const agentState = useSnapshot(chatStore.agent);
5796
+ const [form] = Form.useForm();
5797
+ const [activeKey, setActiveKey] = useState(["1"]);
5798
+ const inputs = useMemo(() => {
5799
+ if (agentState.agentInfo.userInput?.length > 0) {
5800
+ return agentState.agentInfo.userInput;
5801
+ }
5802
+ }, [agentState.agentInfo.userInput]);
5803
+ useEffect(() => {
5804
+ if (inputs.length > 0) {
5805
+ const initialValues = inputs.reduce((acc, cur) => {
5806
+ let value = cur.value;
5807
+ acc[cur.name] = value;
5808
+ return acc;
5809
+ }, {});
5810
+ form.setFieldsValue(initialValues);
5811
+ }
5812
+ }, [inputs, form]);
5813
+ const handleValuesChange = (changedValues) => {
5814
+ if (agentState.agentInfo.userInput?.length > 0) {
5815
+ const newInput = agentState.agentInfo.userInput.map((v) => {
5816
+ if (v.name in changedValues) {
5817
+ const newValue = changedValues[v.name];
5818
+ return { ...v, value: newValue };
5819
+ }
5820
+ return v;
5821
+ });
5822
+ chatStore.setConversationUserInput(newInput);
5823
+ return;
5824
+ }
5825
+ };
5826
+ const handleStartChat = () => {
5827
+ form.validateFields().then(() => {
5828
+ setActiveKey([]);
5829
+ }).catch(() => {
5830
+ message.error("\u8BF7\u68C0\u67E5\u8F93\u5165\u53C2\u6570");
5831
+ });
5832
+ };
5833
+ const renderFormItem = (item) => {
5834
+ const itemStyle = { marginBottom: 0 };
5835
+ const commonProps = {
5836
+ label: item.name,
5837
+ name: item.name,
5838
+ style: itemStyle,
5839
+ rules: item.rules?.map((r) => {
5840
+ const valStr = String(r.value || "");
5841
+ if (r.type === "required") return { required: true, message: r.message };
5842
+ if (r.type === "email") return { type: "email", message: r.message };
5843
+ if (r.type === "pattern") return { pattern: new RegExp(valStr), message: r.message };
5844
+ if (r.type === "max" || r.type === "min") {
5845
+ return {
5846
+ validator: (_, val) => {
5847
+ if (val === void 0 || val === null || val === "") return Promise.resolve();
5848
+ const numVal = Number(val);
5849
+ if (isNaN(numVal)) return Promise.resolve();
5850
+ if (r.type === "max" && numVal > Number(valStr)) return Promise.reject(new Error(r.message));
5851
+ if (r.type === "min" && numVal < Number(valStr)) return Promise.reject(new Error(r.message));
5852
+ return Promise.resolve();
5853
+ }
5854
+ };
5855
+ }
5856
+ if (r.type === "length") {
5857
+ const [min, max] = valStr.split(",").map((v) => v ? Number(v) : void 0);
5858
+ return {
5859
+ validator: (_, val) => {
5860
+ if (val === void 0 || val === null || val === "") return Promise.resolve();
5861
+ const strVal = String(val);
5862
+ if (min !== void 0 && strVal.length < min) return Promise.reject(new Error(r.message));
5863
+ if (max !== void 0 && strVal.length > max) return Promise.reject(new Error(r.message));
5864
+ return Promise.resolve();
5865
+ }
5866
+ };
5867
+ }
5868
+ if (r.type === "size") {
5869
+ const [min, max] = valStr.split(",").map((v) => v ? Number(v) : void 0);
5870
+ return {
5871
+ validator: (_, val) => {
5872
+ if (val === void 0 || val === null || val === "") return Promise.resolve();
5873
+ let len = 0;
5874
+ if (Array.isArray(val)) {
5875
+ len = val.length;
5876
+ } else if (typeof val === "string") {
5877
+ try {
5878
+ const parsed = JSON.parse(val);
5879
+ if (Array.isArray(parsed)) len = parsed.length;
5880
+ else return Promise.resolve();
5881
+ } catch (e) {
5882
+ return Promise.resolve();
5883
+ }
5884
+ } else {
5885
+ return Promise.resolve();
5886
+ }
5887
+ if (min !== void 0 && len < min) return Promise.reject(new Error(r.message));
5888
+ if (max !== void 0 && len > max) return Promise.reject(new Error(r.message));
5889
+ return Promise.resolve();
5890
+ }
5891
+ };
5892
+ }
5893
+ if (r.type === "enum") {
5894
+ const options = valStr.split(",").map((s) => s.trim());
5895
+ return {
5896
+ validator: (_, val) => {
5897
+ if (val === void 0 || val === null || val === "") return Promise.resolve();
5898
+ if (options.includes(String(val))) return Promise.resolve();
5899
+ return Promise.reject(new Error(r.message));
5900
+ }
5901
+ };
5902
+ }
5903
+ return {};
5904
+ })
5905
+ };
5906
+ if (["STRING", "LONG"].includes(item.type)) {
5907
+ return /* @__PURE__ */ jsx(Form.Item, { ...commonProps, children: /* @__PURE__ */ jsx(Input, { placeholder: "\u8BF7\u8F93\u5165\u503C" }) });
5908
+ }
5909
+ if (["NUMBER"].includes(item.type)) {
5910
+ return /* @__PURE__ */ jsx(Form.Item, { ...commonProps, children: /* @__PURE__ */ jsx(InputNumber, { style: { width: "100%" }, placeholder: "\u8BF7\u8F93\u5165\u6570\u503C" }) });
5911
+ }
5912
+ if (item.type === "BOOLEAN") {
5913
+ return /* @__PURE__ */ jsx(Form.Item, { style: itemStyle, name: item.name, valuePropName: "checked", children: /* @__PURE__ */ jsxs(Flex, { justify: "space-between", align: "center", children: [
5914
+ /* @__PURE__ */ jsx("span", { children: item.name }),
5915
+ /* @__PURE__ */ jsx(Switch$1, { size: "small" })
5916
+ ] }) });
5917
+ }
5918
+ if (item.type === "FILE") {
5919
+ return /* @__PURE__ */ jsx(Form.Item, { ...commonProps, children: /* @__PURE__ */ jsx(FormFileUpload, { multiple: false }) });
5920
+ }
5921
+ if (item.type === "ARRAY_FILE") {
5922
+ return /* @__PURE__ */ jsx(Form.Item, { ...commonProps, children: /* @__PURE__ */ jsx(FormFileUpload, { multiple: true }) });
5923
+ }
5924
+ if (["OBJECT", "ARRAY", "ARRAY_STRING", "ARRAY_NUMBER", "ARRAY_DECIMAL", "ARRAY_BOOLEAN", "ARRAY_OBJECT"].includes(item.type)) {
5925
+ return /* @__PURE__ */ jsx(Form.Item, { ...commonProps, children: /* @__PURE__ */ jsx(FormMonacoEditor, {}) });
5926
+ }
5927
+ return /* @__PURE__ */ jsx(Form.Item, { ...commonProps, children: /* @__PURE__ */ jsx(Input, { placeholder: "\u8BF7\u8F93\u5165\u503C" }) });
5928
+ };
5929
+ const genExtra = () => {
5930
+ if (activeKey.includes("1")) return null;
5931
+ return /* @__PURE__ */ jsx(
5932
+ Button,
5933
+ {
5934
+ type: "text",
5935
+ size: "small",
5936
+ onClick: (e) => {
5937
+ e.stopPropagation();
5938
+ setActiveKey(["1"]);
5939
+ },
5940
+ children: "\u7F16\u8F91"
5941
+ }
5942
+ );
5943
+ };
5944
+ const items = [
5945
+ {
5946
+ key: "1",
5947
+ label: "\u53C2\u6570\u8BBE\u7F6E",
5948
+ extra: genExtra(),
5949
+ children: /* @__PURE__ */ jsxs(Fragment, { children: [
5950
+ /* @__PURE__ */ jsx(Form, { form, layout: "vertical", onValuesChange: handleValuesChange, style: { maxHeight: 500, overflow: "auto", paddingRight: 16 }, children: inputs.length > 0 ? /* @__PURE__ */ jsx(Flex, { vertical: true, gap: 12, children: inputs.map((item) => /* @__PURE__ */ jsx(React10__default.Fragment, { children: renderFormItem(item) }, item.name)) }) : /* @__PURE__ */ jsx("div", { style: { padding: "10px", color: "#999", textAlign: "center" }, children: "\u6682\u65E0\u7528\u6237\u8F93\u5165\u5B57\u6BB5" }) }),
5951
+ /* @__PURE__ */ jsx(Flex, { align: "center", justify: "center", className: "m-t-16", children: /* @__PURE__ */ jsx(Button, { type: "primary", onClick: handleStartChat, children: "\u5F00\u59CB\u4F1A\u8BDD" }) })
5952
+ ] })
5953
+ }
5954
+ ];
5955
+ return /* @__PURE__ */ jsx("div", { className: styles_module_default2.userInputCollapse, children: /* @__PURE__ */ jsx(
5956
+ Collapse,
5957
+ {
5958
+ activeKey,
5959
+ onChange: (keys) => {
5960
+ const newKeys = typeof keys === "string" ? [keys] : keys;
5961
+ setActiveKey(newKeys);
5962
+ },
5963
+ items,
5964
+ className: "m-16",
5965
+ styles: {
5966
+ body: {
5967
+ paddingRight: 0,
5968
+ paddingBottom: 10
5969
+ }
5970
+ }
5971
+ }
5972
+ ) });
5973
+ };
5974
+ var UserInputPanel_default = UserInputPanel;
5584
5975
 
5585
5976
  // src/ui/layouts/components/styles.module.less
5586
5977
  var styles_module_default5 = {
@@ -5605,9 +5996,11 @@ var ChatMainPanel = memo(
5605
5996
  []
5606
5997
  );
5607
5998
  const configState = useSnapshot(chatStore.config);
5999
+ const agentState = useSnapshot(chatStore.agent);
5608
6000
  return /* @__PURE__ */ jsxs(Flex, { vertical: true, className: classNames2("height-full"), children: [
5609
6001
  /* @__PURE__ */ jsx(RenderWrapper, { control: configState.layout.chatHeader, DefaultComponent: ChatHeader_default }),
5610
6002
  /* @__PURE__ */ jsxs(Flex, { align: "center", vertical: true, gap: 24, className: classNames2("height-full", styles_module_default5.bodyWidth), children: [
6003
+ shouldRender(agentState.agentInfo.userInput && agentState.agentInfo.userInput.length > 0) && /* @__PURE__ */ jsx(RenderWrapper, { control: configState.layout.userInput, DefaultComponent: UserInputPanel_default }),
5611
6004
  shouldRender(configState.layout.messageList) && /* @__PURE__ */ jsx("div", { className: "full-scroll", style: { width: "100%" }, children: /* @__PURE__ */ jsx(RenderWrapper, { control: configState.layout.messageList, DefaultComponent: BubbleListItems_default }) }),
5612
6005
  /* @__PURE__ */ jsx(RenderWrapper, { control: configState.layout.senderHeader, DefaultComponent: /* @__PURE__ */ jsx(ChatSenderHeader_default, {}) }),
5613
6006
  /* @__PURE__ */ jsxs(Flex, { className: styles_module_default5.inputContainer, vertical: true, gap: 8, children: [
@@ -5686,7 +6079,7 @@ var index_module_default3 = {
5686
6079
  animatedSplitter: "index_module_animatedSplitter",
5687
6080
  hideSplitterBar: "index_module_hideSplitterBar"
5688
6081
  };
5689
- var layouts_default = forwardRef(({ theme: theme4, params, hooks, layout, config, services }, _ref) => {
6082
+ var layouts_default = forwardRef(({ theme: theme5, params, hooks, layout, config, services }, _ref) => {
5690
6083
  const chatStore = useMemo(() => createChatStore(), []);
5691
6084
  const senderRef = useRef(null);
5692
6085
  useImperativeHandle(
@@ -5733,6 +6126,11 @@ var layouts_default = forwardRef(({ theme: theme4, params, hooks, layout, config
5733
6126
  chatStore.setAgent({ ...agentState.agentInfo, config: config.agent.config || {} });
5734
6127
  }
5735
6128
  }, [agentState.agentInfo.id, config.agent?.config]);
6129
+ useDeepEffect(() => {
6130
+ if (agentState.agentInfo.id) {
6131
+ chatStore.setUserInput(config.agent.userInput);
6132
+ }
6133
+ }, [agentState.agentInfo.id, config.agent?.userInput]);
5736
6134
  useDeepEffect(() => {
5737
6135
  if (config?.agent?.id) {
5738
6136
  chatStore.getAgentInfo(config.agent.id);
@@ -5759,20 +6157,20 @@ var layouts_default = forwardRef(({ theme: theme4, params, hooks, layout, config
5759
6157
  }, [hasPreView]);
5760
6158
  useWebSocket({
5761
6159
  url: configState.services.websocketUrls?.[0],
5762
- onMessage: (message2) => chatStore.acceptMessage(message2.payload),
6160
+ onMessage: (message3) => chatStore.acceptMessage(message3.payload),
5763
6161
  clientHeartbeat: false,
5764
6162
  reconnectInterval: 1e4
5765
6163
  });
5766
6164
  useWebSocket({
5767
6165
  url: configState.services.websocketUrls?.[1],
5768
- onMessage: (message2) => chatStore.acceptMessage(message2.payload),
6166
+ onMessage: (message3) => chatStore.acceptMessage(message3.payload),
5769
6167
  clientHeartbeat: false,
5770
6168
  reconnectInterval: 1e4
5771
6169
  });
5772
6170
  useEffect(() => {
5773
6171
  hooks?.onBeforeInit?.();
5774
6172
  }, []);
5775
- return /* @__PURE__ */ jsx(XProvider, { theme: { cssVar: {}, ...theme4 }, children: /* @__PURE__ */ jsx(ChatProvider, { store: chatStore, children: /* @__PURE__ */ jsx(Spin, { spinning: configState.loading, classNames: { root: "full-spin" }, children: /* @__PURE__ */ jsxs(Flex, { vertical: true, className: classNames2(index_module_default3.chatLayout, "zero-chat-layout", "height-full"), children: [
6173
+ return /* @__PURE__ */ jsx(XProvider, { theme: { cssVar: {}, ...theme5 }, children: /* @__PURE__ */ jsx(ChatProvider, { store: chatStore, children: /* @__PURE__ */ jsx(Spin, { spinning: configState.loading, classNames: { root: "full-spin" }, children: /* @__PURE__ */ jsxs(Flex, { vertical: true, className: classNames2(index_module_default3.chatLayout, "zero-chat-layout", "height-full"), children: [
5776
6174
  /* @__PURE__ */ jsx(RenderWrapper, { control: configState.layout.globalHeader, DefaultComponent: ChatHeader_default }),
5777
6175
  /* @__PURE__ */ jsxs(Flex, { ref: containerRef, className: "full-scroll", children: [
5778
6176
  /* @__PURE__ */ jsx(RenderWrapper, { control: configState.layout.leftPanel }),