@zero-library/chat-copilot 3.1.7 → 3.1.9

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,9 +1,9 @@
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, FileIcon, copyText, LazyComponent, isBoolean, UserAvatar, htmlToMarkdown, buildUrlParams, isExternal, deepCopy, transforms, deepMerge, createRequest, HttpStatus, isArray, isString, isDef, isNull, 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, 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
- import React10__default, { createContext, forwardRef, useRef, useEffect, useImperativeHandle, useMemo, useCallback, memo, useState, useContext, useLayoutEffect } from 'react';
6
+ import React10__default, { createContext, forwardRef, useRef, useEffect, useImperativeHandle, useMemo, memo, useState, useContext, useCallback, useLayoutEffect } from 'react';
7
7
  import { useSnapshot, proxy } from 'valtio';
8
8
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
9
9
  import { LexicalComposer } from '@lexical/react/LexicalComposer';
@@ -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,
@@ -825,8 +877,8 @@ var ChatSender_default = forwardRef(
825
877
  const isFocusedRef = useRef(false);
826
878
  const commandConfigRef = useRef(commandConfig);
827
879
  commandConfigRef.current = commandConfig;
828
- const inputComponent = useCallback(
829
- (inputProps) => /* @__PURE__ */ jsx(ChatInput_default, { ...inputProps, commandConfig: commandConfigRef.current }),
880
+ const inputComponent = useMemo(
881
+ () => forwardRef((inputProps, ref2) => /* @__PURE__ */ jsx(ChatInput_default, { ...inputProps, ref: ref2, commandConfig: commandConfigRef.current })),
830
882
  []
831
883
  );
832
884
  useEffect(() => {
@@ -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: {},
@@ -1258,6 +1330,9 @@ function createChatStore() {
1258
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;
@@ -1642,9 +1717,9 @@ function createChatStore() {
1642
1717
  }
1643
1718
  }
1644
1719
  }
1645
- function processMessageContent(message2) {
1720
+ function processMessageContent(message3) {
1646
1721
  const newMessage = {
1647
- ...message2,
1722
+ ...message3,
1648
1723
  agentId: agent.agentInfo.id
1649
1724
  };
1650
1725
  const contentList = Array.isArray(newMessage.content) ? newMessage.content : [];
@@ -1692,14 +1767,14 @@ function createChatStore() {
1692
1767
  }
1693
1768
  processMessageContent(newMessage);
1694
1769
  };
1695
- const sendMessage = async (message2, msgFiles = [], params) => {
1770
+ const sendMessage = async (message3, msgFiles = [], params) => {
1696
1771
  const conversationId = conversation.active.id;
1697
1772
  if (conversation.messages[conversationId].loading) return;
1698
1773
  let msgContent = "", files;
1699
1774
  const references = conversation.messages[conversationId].references;
1700
- if (message2) {
1701
- msgContent = message2;
1702
- files = msgFiles;
1775
+ if (message3) {
1776
+ msgContent = message3;
1777
+ files = [...msgFiles, ...conversation.messages[conversationId].files || []];
1703
1778
  } else {
1704
1779
  if (references?.type === 1 && references?.content?.msgContent) {
1705
1780
  msgContent = references.content.msgContent + "\n\n";
@@ -1710,6 +1785,22 @@ function createChatStore() {
1710
1785
  if (!msgContent) return;
1711
1786
  const canProceed = await config.hooks?.onBeforeSend?.(msgContent, files || []);
1712
1787
  if (canProceed === false) return;
1788
+ if (conversation.active.userInput?.length) {
1789
+ const invalid = conversation.active.userInput.some((item) => {
1790
+ const isRequired = item.rules?.some((r) => r.type === "required");
1791
+ if (isRequired) {
1792
+ if (item.type === "BOOLEAN") {
1793
+ return isNullOrUnDef(item.value);
1794
+ }
1795
+ return isNullOrUnDef(item.value) || item.value === "";
1796
+ }
1797
+ return false;
1798
+ });
1799
+ if (invalid) {
1800
+ message.error("\u8BF7\u68C0\u67E5\u8F93\u5165\u53C2\u6570");
1801
+ return;
1802
+ }
1803
+ }
1713
1804
  conversation.messages[conversationId].loading = true;
1714
1805
  const idx = conversations.list.items.findIndex((item) => item.id === conversationId);
1715
1806
  if (idx !== -1 && !conversations.list.items[idx].label) {
@@ -1728,15 +1819,16 @@ function createChatStore() {
1728
1819
  responseMode: 2
1729
1820
  };
1730
1821
  const extraParams = deepCopy(config.params?.params || {});
1731
- Object.assign(extraParams, message2 ? {} : { ...references?.params }, params);
1822
+ const userInputParams = variablesToObject(conversation.active.userInput || []);
1823
+ Object.assign(extraParams, message3 ? {} : { ...references?.params }, params, userInputParams);
1732
1824
  sendParams.params = extraParams;
1733
- if (!message2) {
1825
+ if (!message3) {
1734
1826
  setContent("");
1735
1827
  setContentParams();
1736
- setFileList([]);
1737
1828
  setReferences();
1738
- setHeaderOpen(false);
1739
1829
  }
1830
+ setFileList([]);
1831
+ setHeaderOpen(false);
1740
1832
  try {
1741
1833
  const dealedParams = await config.hooks?.onHandleSendParams?.(sendParams);
1742
1834
  await config.services.request.sendMessageStream(dealedParams || sendParams, agent.agentInfo?.id || "");
@@ -1794,7 +1886,7 @@ function createChatStore() {
1794
1886
  /** 设置智能体 */
1795
1887
  setAgent,
1796
1888
  /** 设置智能体用户输入 */
1797
- // setUserInput,
1889
+ setUserInput,
1798
1890
  /** 设置会话配置 */
1799
1891
  setConversationSpec,
1800
1892
  /** 历史会话状态 */
@@ -1828,9 +1920,11 @@ function createChatStore() {
1828
1920
  /** 接收消息 */
1829
1921
  acceptMessage,
1830
1922
  /** 获取智能体用户输入 */
1831
- // getUserInput,
1923
+ getUserInput,
1832
1924
  /** 消息反馈 */
1833
- feedback
1925
+ feedback,
1926
+ /** 设置会话用户输入 */
1927
+ setConversationUserInput
1834
1928
  };
1835
1929
  }
1836
1930
  var AuthImage = ({ path, size, shape = "square" }) => {
@@ -1924,6 +2018,7 @@ var styles_module_default2 = {
1924
2018
  chatWelcome: "styles_module_chatWelcome",
1925
2019
  promptItem: "styles_module_promptItem",
1926
2020
  bubbleList: "styles_module_bubbleList",
2021
+ userInputCollapse: "styles_module_userInputCollapse",
1927
2022
  logoArea: "styles_module_logoArea",
1928
2023
  logoContainer: "styles_module_logoContainer",
1929
2024
  staticHalo: "styles_module_staticHalo",
@@ -2657,12 +2752,12 @@ var DocDrawer_default = ({ title, open, onClose, paramsStr }) => {
2657
2752
  }, [paramsStr]);
2658
2753
  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
2754
  };
2660
- var IndexQuote_default = ({ data, loading, message: message2 }) => {
2755
+ var IndexQuote_default = ({ data, loading, message: message3 }) => {
2661
2756
  const [open, setOpen] = useState(false);
2662
2757
  const citation = useMemo(() => {
2663
- const citations = message2.content?.find((item) => item.type === "citation")?.citations ?? [];
2758
+ const citations = message3.content?.find((item) => item.type === "citation")?.citations ?? [];
2664
2759
  return citations?.find((item) => String(item.citationId) === String(data.citationId));
2665
- }, [data.citationId, message2.content]);
2760
+ }, [data.citationId, message3.content]);
2666
2761
  const onClick = () => {
2667
2762
  if (!citation?.citationUrl) return;
2668
2763
  if (isExternal(citation.citationUrl)) {
@@ -2677,7 +2772,7 @@ var IndexQuote_default = ({ data, loading, message: message2 }) => {
2677
2772
  open && /* @__PURE__ */ jsx(DocDrawer_default, { paramsStr: citation?.citationUrl, title: citation?.citationName, open, onClose: () => setOpen(false) })
2678
2773
  ] });
2679
2774
  };
2680
- var MarkImg_default = ({ data, loading, message: message2, ...rest }) => {
2775
+ var MarkImg_default = ({ data, loading, message: message3, ...rest }) => {
2681
2776
  const getPreviewFileUrl = (src) => {
2682
2777
  return buildUrlParams({ [TOKEN_KEY]: tokenManager.get() || "" }, src);
2683
2778
  };
@@ -2704,7 +2799,7 @@ var MdEdit_default = ({ data, loading }) => {
2704
2799
  !loading && /* @__PURE__ */ jsx(Flex, { justify: "end", className: "m-t-16", children: /* @__PURE__ */ jsx(Button, { color: "primary", variant: "outlined", onClick: onOk, children: btnText }) })
2705
2800
  ] });
2706
2801
  };
2707
- var PreviewLink_default = ({ data, loading, message: message2, ...rest }) => {
2802
+ var PreviewLink_default = ({ data, loading, message: message3, ...rest }) => {
2708
2803
  const chatStore = useChatStore();
2709
2804
  const getLinkFileName = (href) => {
2710
2805
  const url = new URL(href, window.location.origin);
@@ -2737,7 +2832,7 @@ var PreviewLink_default = ({ data, loading, message: message2, ...rest }) => {
2737
2832
  chatStore.setPreview({
2738
2833
  fileUrl: chatStore.config.services.request.getPreviewUrl({
2739
2834
  path: href,
2740
- workspaceId: message2.conversationId
2835
+ workspaceId: message3.conversationId
2741
2836
  }),
2742
2837
  fileName,
2743
2838
  suffix
@@ -2844,7 +2939,7 @@ var adaptMarkdownComponent = (Component, payloadMapRef, messageRef) => {
2844
2939
  return WrappedComponent;
2845
2940
  };
2846
2941
  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 }) => {
2942
+ var XMarkdown_default = memo(({ message: message3, components = {}, content = "", ...rest }) => {
2848
2943
  const config = useMemo(() => getMarkdownConfig(), []);
2849
2944
  const formattedContent = useMemo(() => formatMixedContent(content), [content]);
2850
2945
  const newComponents = useMemo(
@@ -2870,9 +2965,9 @@ var XMarkdown_default = memo(({ message: message2, components = {}, content = ""
2870
2965
  [formattedContent, payloadTagPattern]
2871
2966
  );
2872
2967
  const payloadMapRef = useRef(payloadMap);
2873
- const messageRef = useRef(message2);
2968
+ const messageRef = useRef(message3);
2874
2969
  payloadMapRef.current = payloadMap;
2875
- messageRef.current = message2;
2970
+ messageRef.current = message3;
2876
2971
  const markdownComponents = useMemo(() => adaptMarkdownComponents(newComponents, payloadMapRef, messageRef), [payloadTagPattern]);
2877
2972
  return /* @__PURE__ */ jsx(
2878
2973
  XMarkdown,
@@ -3325,9 +3420,9 @@ function splitA2uiTextSegments(text) {
3325
3420
  }
3326
3421
  return segments.length ? segments : [];
3327
3422
  }
3328
- function extractInlineSurfaceIdsFromMessage(message2) {
3423
+ function extractInlineSurfaceIdsFromMessage(message3) {
3329
3424
  const surfaceIds = /* @__PURE__ */ new Set();
3330
- const items = Array.isArray(message2?.content) ? message2.content : [];
3425
+ const items = Array.isArray(message3?.content) ? message3.content : [];
3331
3426
  for (const item of items) {
3332
3427
  if (item?.type !== "text") continue;
3333
3428
  const text = item.messageContent || item.text || "";
@@ -3346,10 +3441,10 @@ function extractDismissedSurfaceIdsFromMessages(messages) {
3346
3441
  const lastCreateIndexBySurface = /* @__PURE__ */ new Map();
3347
3442
  const lastActionIndexBySurface = /* @__PURE__ */ new Map();
3348
3443
  for (let messageIndex = 0; messageIndex < messages.length; messageIndex++) {
3349
- const message2 = messages[messageIndex];
3350
- const items = Array.isArray(message2?.content) ? message2.content : [];
3444
+ const message3 = messages[messageIndex];
3445
+ const items = Array.isArray(message3?.content) ? message3.content : [];
3351
3446
  for (const item of items) {
3352
- if (message2?.role !== 1) {
3447
+ if (message3?.role !== 1) {
3353
3448
  if (item?.type === "a2uiCommand" && item.command) {
3354
3449
  const surfaceId = String(item.command?.createSurface?.surfaceId || "").trim();
3355
3450
  if (surfaceId) lastCreateIndexBySurface.set(surfaceId, messageIndex);
@@ -3367,7 +3462,7 @@ function extractDismissedSurfaceIdsFromMessages(messages) {
3367
3462
  }
3368
3463
  }
3369
3464
  }
3370
- if (message2?.role === 1 && item?.type === "text") {
3465
+ if (message3?.role === 1 && item?.type === "text") {
3371
3466
  const text = item.messageContent || item.text || "";
3372
3467
  if (typeof text !== "string" || !text.includes("a2ui_action.v1")) continue;
3373
3468
  try {
@@ -3880,6 +3975,15 @@ function extractSurfaceId2(command) {
3880
3975
  function getA2uiRuntimeCommands(state) {
3881
3976
  return [...state.serverCommands, ...state.localCommands];
3882
3977
  }
3978
+ function sanitizeA2uiCommands(commands) {
3979
+ return commands.map((cmd) => {
3980
+ if (!cmd || typeof cmd !== "object" || !cmd.updateDataModel) return cmd;
3981
+ const { path } = cmd.updateDataModel;
3982
+ if (typeof path === "string" && path.trim()) return cmd;
3983
+ const { updateDataModel: _, ...rest } = cmd;
3984
+ return rest;
3985
+ });
3986
+ }
3883
3987
  function diffConversationMessages(messages, prevCursors) {
3884
3988
  if (messages.length < prevCursors.length) {
3885
3989
  return { shouldReplayAll: true, nextCursors: [], pendingItems: [] };
@@ -3887,9 +3991,9 @@ function diffConversationMessages(messages, prevCursors) {
3887
3991
  const nextCursors = [];
3888
3992
  const pendingItems = [];
3889
3993
  for (let messageIndex = 0; messageIndex < messages.length; messageIndex += 1) {
3890
- const message2 = messages[messageIndex];
3891
- const messageId = String(message2?.messageId ?? messageIndex);
3892
- const items = Array.isArray(message2?.content) ? message2.content : [];
3994
+ const message3 = messages[messageIndex];
3995
+ const messageId = String(message3?.messageId ?? messageIndex);
3996
+ const items = Array.isArray(message3?.content) ? message3.content : [];
3893
3997
  const prevCursor = prevCursors[messageIndex];
3894
3998
  const startIndex = prevCursor ? prevCursor.contentLength : 0;
3895
3999
  if (prevCursor && (prevCursor.messageId !== messageId || items.length < prevCursor.contentLength)) {
@@ -3951,9 +4055,9 @@ function scanA2uiTagsFromMessages(messages, processedTagIds) {
3951
4055
  const newTags = [];
3952
4056
  const newTagIds = [];
3953
4057
  for (let messageIndex = 0; messageIndex < messages.length; messageIndex += 1) {
3954
- const message2 = messages[messageIndex];
3955
- const messageId = String(message2?.messageId ?? messageIndex);
3956
- const items = Array.isArray(message2?.content) ? message2.content : [];
4058
+ const message3 = messages[messageIndex];
4059
+ const messageId = String(message3?.messageId ?? messageIndex);
4060
+ const items = Array.isArray(message3?.content) ? message3.content : [];
3957
4061
  for (const item of items) {
3958
4062
  if (item?.type !== "text") continue;
3959
4063
  const text = item.messageContent || item.text || "";
@@ -3971,9 +4075,9 @@ function scanA2uiTagsFromMessages(messages, processedTagIds) {
3971
4075
  }
3972
4076
  function reduceA2uiRuntimeMessages(state, messages) {
3973
4077
  const { shouldReplayAll, pendingItems, nextCursors } = diffConversationMessages(messages || [], state.processedMessageCursors);
3974
- const itemsToProcess = shouldReplayAll ? messages.flatMap((message2, messageIndex) => {
3975
- const messageId = String(message2?.messageId ?? messageIndex);
3976
- const items = Array.isArray(message2?.content) ? message2.content : [];
4078
+ const itemsToProcess = shouldReplayAll ? messages.flatMap((message3, messageIndex) => {
4079
+ const messageId = String(message3?.messageId ?? messageIndex);
4080
+ const items = Array.isArray(message3?.content) ? message3.content : [];
3977
4081
  return items.map((item) => ({ messageIndex, messageId, item }));
3978
4082
  }) : pendingItems;
3979
4083
  const tagProcessedSet = new Set(shouldReplayAll ? [] : state.processedTagIds);
@@ -4015,9 +4119,9 @@ function reduceA2uiRuntimeMessages(state, messages) {
4015
4119
  processA2uiCommand(cmd, messageIndex, messageId, nextState, effects, deletedSurfaceIds, nextWizardSteps);
4016
4120
  }
4017
4121
  });
4018
- nextState.processedMessageCursors = shouldReplayAll ? messages.map((message2, messageIndex) => ({
4019
- messageId: String(message2?.messageId ?? messageIndex),
4020
- contentLength: Array.isArray(message2?.content) ? message2.content.length : 0
4122
+ nextState.processedMessageCursors = shouldReplayAll ? messages.map((message3, messageIndex) => ({
4123
+ messageId: String(message3?.messageId ?? messageIndex),
4124
+ contentLength: Array.isArray(message3?.content) ? message3.content.length : 0
4021
4125
  })) : nextCursors;
4022
4126
  nextState.wizardStepBySurface = { ...nextState.wizardStepBySurface, ...nextWizardSteps };
4023
4127
  if (deletedSurfaceIds.size) {
@@ -4077,7 +4181,7 @@ function selectA2uiRuntimeView(state, dismissedSurfaceIds) {
4077
4181
  const mergedDismissedSurfaceIds = Array.from(
4078
4182
  new Set([...dismissedSurfaceIds || [], ...state.optimisticallyDismissedSurfaceIds].filter((surfaceId) => surfaceId?.trim?.()))
4079
4183
  );
4080
- const commands = getA2uiRuntimeCommands(state);
4184
+ const commands = sanitizeA2uiCommands(getA2uiRuntimeCommands(state));
4081
4185
  const visibleSurfaceIds = resolveVisibleSurfaceIds(commands, mergedDismissedSurfaceIds);
4082
4186
  const anchoredSurfaceIdsByMessageIndex = {};
4083
4187
  visibleSurfaceIds.forEach((surfaceId) => {
@@ -4166,10 +4270,10 @@ var A2uiRuntimeContext = React10__default.createContext({
4166
4270
  function useA2uiRuntimeView() {
4167
4271
  return React10__default.useContext(A2uiRuntimeContext);
4168
4272
  }
4169
- function A2uiMessageCards({ messageIndex, message: message2 }) {
4273
+ function A2uiMessageCards({ messageIndex, message: message3 }) {
4170
4274
  const { surfaceIdsByMessageIndex } = useA2uiRuntimeView();
4171
4275
  const allSurfaceIds = surfaceIdsByMessageIndex[messageIndex] || [];
4172
- const inlineSurfaceIds = message2 ? extractInlineSurfaceIdsFromMessage(message2) : /* @__PURE__ */ new Set();
4276
+ const inlineSurfaceIds = message3 ? extractInlineSurfaceIdsFromMessage(message3) : /* @__PURE__ */ new Set();
4173
4277
  const surfaceIds = allSurfaceIds.filter((id) => !inlineSurfaceIds.has(id));
4174
4278
  if (!surfaceIds.length) return null;
4175
4279
  return /* @__PURE__ */ jsx("div", { children: surfaceIds.map((surfaceId) => /* @__PURE__ */ jsx(XCard.Card, { id: surfaceId }, surfaceId)) });
@@ -4367,8 +4471,8 @@ function readContextModelPath(context) {
4367
4471
  function buildLatestCommandIndexBySurface(messages) {
4368
4472
  const indexBySurface = {};
4369
4473
  let commandIndex = -1;
4370
- for (const message2 of messages) {
4371
- const items = Array.isArray(message2?.content) ? message2.content : [];
4474
+ for (const message3 of messages) {
4475
+ const items = Array.isArray(message3?.content) ? message3.content : [];
4372
4476
  for (const item of items) {
4373
4477
  if (item?.type === "a2uiCommand" && item.command) {
4374
4478
  commandIndex += 1;
@@ -4524,6 +4628,8 @@ var RunStartedNode = React10__default.memo(({ loading }) => {
4524
4628
  if (!loading) return null;
4525
4629
  return /* @__PURE__ */ jsx(Flex, { gap: 8, align: "center", className: style_module_default2.runStartedNode, children: /* @__PURE__ */ jsx(LoadingOutlined, { style: { color: "#1677ff" } }) });
4526
4630
  });
4631
+ var RESOURCE_MARKDOWN_TAG = "resourcetag";
4632
+ var RESOURCE_TOKEN_REGEX = /(\w+):\/\/([^?\s]+)\?name=([^&\s]+)&label=([^\s]+)/g;
4527
4633
  function QuestionSummary({ content }) {
4528
4634
  const answer = content.replace(/^Question:\s*/, "").trim() || "\u5DF2\u56DE\u7B54";
4529
4635
  return /* @__PURE__ */ jsxs("span", { style: { display: "inline-flex", flexDirection: "column", gap: 4 }, children: [
@@ -4531,17 +4637,37 @@ function QuestionSummary({ content }) {
4531
4637
  /* @__PURE__ */ jsx("span", { style: { fontSize: 13, color: "#262626", lineHeight: 1.6, whiteSpace: "pre-wrap" }, children: answer })
4532
4638
  ] });
4533
4639
  }
4640
+ function MessageResourceTag({ data }) {
4641
+ const resource = data;
4642
+ if (!resource) return null;
4643
+ return /* @__PURE__ */ jsx(ReadonlyResourceTag, { resource });
4644
+ }
4645
+ function transformResourceText(content) {
4646
+ return content.replace(RESOURCE_TOKEN_REGEX, (_, resourceType, resourceId, resourceName, resourceLabel) => {
4647
+ const resource = {
4648
+ resourceType: decodeURIComponent(resourceType),
4649
+ resourceId: decodeURIComponent(resourceId),
4650
+ resourceName: decodeURIComponent(resourceName),
4651
+ resourceLabel: decodeURIComponent(resourceLabel)
4652
+ };
4653
+ return `<${RESOURCE_MARKDOWN_TAG}>${JSON.stringify(resource)}</${RESOURCE_MARKDOWN_TAG}>`;
4654
+ });
4655
+ }
4534
4656
  var TextNode2 = React10__default.memo(
4535
4657
  ({
4536
4658
  item,
4537
4659
  role,
4538
4660
  customComponents,
4539
- message: message2,
4661
+ message: message3,
4540
4662
  messageIndex = -1
4541
4663
  }) => {
4542
4664
  const { surfaceIdsByMessageIndex } = useA2uiRuntimeView();
4543
4665
  const rawContent = toA2uiDisplayText(role, item?.messageContent);
4544
4666
  const segments = splitA2uiTextSegments(rawContent);
4667
+ const markdownComponents = {
4668
+ [RESOURCE_MARKDOWN_TAG]: MessageResourceTag,
4669
+ ...customComponents
4670
+ };
4545
4671
  const visibleSurfaceIds = messageIndex >= 0 ? new Set(surfaceIdsByMessageIndex[messageIndex] || []) : null;
4546
4672
  const firstSeg = segments[0];
4547
4673
  const isPureText = segments.length === 0 || segments.length === 1 && firstSeg.type === "text";
@@ -4550,16 +4676,18 @@ var TextNode2 = React10__default.memo(
4550
4676
  if (typeof content === "string" && content.startsWith("Question:")) {
4551
4677
  return /* @__PURE__ */ jsx(QuestionSummary, { content });
4552
4678
  }
4679
+ const markdownContent = typeof content === "string" ? transformResourceText(content) : content;
4553
4680
  return /* @__PURE__ */ jsxs(Fragment, { children: [
4554
4681
  !!item.reasoningContent && /* @__PURE__ */ jsx(Think, { title: "\u6DF1\u5EA6\u601D\u8003", children: item.reasoningContent }),
4555
- !!content && /* @__PURE__ */ jsx(XMarkdown_default, { message: message2, components: customComponents, content })
4682
+ !!markdownContent && /* @__PURE__ */ jsx(XMarkdown_default, { message: message3, components: markdownComponents, content: markdownContent })
4556
4683
  ] });
4557
4684
  }
4558
4685
  return /* @__PURE__ */ jsxs(Fragment, { children: [
4559
4686
  !!item.reasoningContent && /* @__PURE__ */ jsx(Think, { title: "\u6DF1\u5EA6\u601D\u8003", children: item.reasoningContent }),
4560
4687
  segments.map((seg, i) => {
4561
4688
  if (seg.type === "text") {
4562
- return seg.content.trim() ? /* @__PURE__ */ jsx(XMarkdown_default, { message: message2, components: customComponents, content: seg.content }, `text-${i}`) : null;
4689
+ const markdownContent = transformResourceText(seg.content);
4690
+ return seg.content.trim() ? /* @__PURE__ */ jsx(XMarkdown_default, { message: message3, components: markdownComponents, content: markdownContent }, `text-${i}`) : null;
4563
4691
  }
4564
4692
  return seg.surfaceIds.filter((sid) => !visibleSurfaceIds || visibleSurfaceIds.has(sid)).map((sid) => /* @__PURE__ */ jsx(XCard.Card, { id: sid }, `a2ui-${i}-${sid}`));
4565
4693
  })
@@ -4778,9 +4906,9 @@ var ToolCallItem = ({ item }) => {
4778
4906
  };
4779
4907
  var tool_call_item_default = ToolCallItem;
4780
4908
  var RENDERABLE_MESSAGE_TYPES = ["runStarted", "toolCall", "toolResult", "text", "stepError", "files", "plan"];
4781
- var MessageRender_default = React10__default.memo(({ role, message: message2, messageIndex = -1, loading, containerRef, customComponents }) => {
4909
+ var MessageRender_default = React10__default.memo(({ role, message: message3, messageIndex = -1, loading, containerRef, customComponents }) => {
4782
4910
  const content = useMemo(() => {
4783
- return (message2.content || []).filter((item) => {
4911
+ return (message3.content || []).filter((item) => {
4784
4912
  if (!RENDERABLE_MESSAGE_TYPES.includes(item.type)) {
4785
4913
  return false;
4786
4914
  }
@@ -4798,12 +4926,12 @@ var MessageRender_default = React10__default.memo(({ role, message: message2, me
4798
4926
  }
4799
4927
  return true;
4800
4928
  });
4801
- }, [loading, message2.content]);
4929
+ }, [loading, message3.content]);
4802
4930
  const quoteMsg = useMemo(() => {
4803
4931
  const quoteMsg2 = {};
4804
- if (message2.params) {
4932
+ if (message3.params) {
4805
4933
  try {
4806
- const citation = JSON.parse(message2.params).citation;
4934
+ const citation = JSON.parse(message3.params).citation;
4807
4935
  if (citation) {
4808
4936
  quoteMsg2.messageContent = citation;
4809
4937
  }
@@ -4811,7 +4939,7 @@ var MessageRender_default = React10__default.memo(({ role, message: message2, me
4811
4939
  }
4812
4940
  }
4813
4941
  return isEmptyObj(quoteMsg2) ? null : quoteMsg2;
4814
- }, [message2.params, message2.quoteMsg]);
4942
+ }, [message3.params, message3.quoteMsg]);
4815
4943
  if (content.length === 0) return null;
4816
4944
  return /* @__PURE__ */ jsxs(Flex, { ref: containerRef, vertical: true, gap: 8, children: [
4817
4945
  content.map((item, index) => {
@@ -4824,8 +4952,8 @@ var MessageRender_default = React10__default.memo(({ role, message: message2, me
4824
4952
  content: /* @__PURE__ */ jsxs(Fragment, { children: [
4825
4953
  item.type === "runStarted" && /* @__PURE__ */ jsx(RunStartedNode, { loading }, `flow-start-${index}`),
4826
4954
  (item.type === "toolCall" || item.type === "toolResult") && /* @__PURE__ */ jsx(tool_call_item_default, { item }, `tool-call-${item.toolCallId || index}`),
4827
- item.type === "text" && /* @__PURE__ */ jsx(TextNode2, { item, role: message2.role, customComponents, message: message2, messageIndex }, `message-${index}`),
4828
- item.type === "stepError" && (item.errorMessage ? /* @__PURE__ */ jsx(XMarkdown_default, { message: message2, components: customComponents, content: item.errorMessage }) : null),
4955
+ item.type === "text" && /* @__PURE__ */ jsx(TextNode2, { item, role: message3.role, customComponents, message: message3, messageIndex }, `message-${index}`),
4956
+ item.type === "stepError" && (item.errorMessage ? /* @__PURE__ */ jsx(XMarkdown_default, { message: message3, components: customComponents, content: item.errorMessage }) : null),
4829
4957
  item.type === "files" && /* @__PURE__ */ jsx(FilesNode, { item }, `files-${index}`),
4830
4958
  item.type === "plan" && /* @__PURE__ */ jsx(A2uiPlanNode, { item }, `plan-${index}`)
4831
4959
  ] })
@@ -4834,7 +4962,7 @@ var MessageRender_default = React10__default.memo(({ role, message: message2, me
4834
4962
  );
4835
4963
  }),
4836
4964
  quoteMsg && /* @__PURE__ */ jsx(QuoteMsgNode, { quoteMsg, role }),
4837
- messageIndex >= 0 ? /* @__PURE__ */ jsx(A2uiMessageCards, { messageIndex, message: message2 }) : null
4965
+ messageIndex >= 0 ? /* @__PURE__ */ jsx(A2uiMessageCards, { messageIndex, message: message3 }) : null
4838
4966
  ] });
4839
4967
  });
4840
4968
  var WelcomeItem_default = ({ icon = true, title = true, description = true, prompts = true }) => {
@@ -4927,13 +5055,13 @@ var BubbleListItems_default = ({
4927
5055
  const messageRefs = useRef({});
4928
5056
  const chatRecords = useMemo(() => {
4929
5057
  const chatRecords2 = [];
4930
- conversationMessages.forEach((message2, messageIndex) => {
4931
- const role = getRole(message2.role);
5058
+ conversationMessages.forEach((message3, messageIndex) => {
5059
+ const role = getRole(message3.role);
4932
5060
  const isLeftBubble = role.user === "agent";
4933
- const isMessageLoading = !!message2.generating;
4934
- const baseKey = `${message2.executionId}-${messageIndex}`;
5061
+ const isMessageLoading = !!message3.generating;
5062
+ const baseKey = `${message3.executionId}-${messageIndex}`;
4935
5063
  const footerNode = !isMessageLoading ? /* @__PURE__ */ jsxs(Flex, { align: "center", gap: 8, children: [
4936
- message2.stopFlag && isLeftBubble && /* @__PURE__ */ jsx(Text3, { type: "secondary", style: { flex: "none" }, children: "\u5DF2\u505C\u6B62" }),
5064
+ message3.stopFlag && isLeftBubble && /* @__PURE__ */ jsx(Text3, { type: "secondary", style: { flex: "none" }, children: "\u5DF2\u505C\u6B62" }),
4937
5065
  /* @__PURE__ */ jsx(Flex, { align: "center", gap: 4, children: role.user === "agent" && /* @__PURE__ */ jsxs(Fragment, { children: [
4938
5066
  /* @__PURE__ */ jsx(
4939
5067
  Button,
@@ -4953,21 +5081,21 @@ var BubbleListItems_default = ({
4953
5081
  /* @__PURE__ */ jsx(
4954
5082
  Button,
4955
5083
  {
4956
- color: message2.feedback === 1 ? "primary" : "default",
5084
+ color: message3.feedback === 1 ? "primary" : "default",
4957
5085
  size: "small",
4958
5086
  variant: "text",
4959
5087
  icon: /* @__PURE__ */ jsx(LikeOutlined, {}),
4960
- onClick: () => chatStore.feedback(message2.executionId, 1, messageIndex)
5088
+ onClick: () => chatStore.feedback(message3.executionId, 1, messageIndex)
4961
5089
  }
4962
5090
  ),
4963
5091
  /* @__PURE__ */ jsx(
4964
5092
  Button,
4965
5093
  {
4966
- color: message2.feedback === 2 ? "primary" : "default",
5094
+ color: message3.feedback === 2 ? "primary" : "default",
4967
5095
  size: "small",
4968
5096
  variant: "text",
4969
5097
  icon: /* @__PURE__ */ jsx(DislikeOutlined, {}),
4970
- onClick: () => chatStore.feedback(message2.executionId, 2, messageIndex)
5098
+ onClick: () => chatStore.feedback(message3.executionId, 2, messageIndex)
4971
5099
  }
4972
5100
  ),
4973
5101
  /* @__PURE__ */ jsx(
@@ -4975,7 +5103,7 @@ var BubbleListItems_default = ({
4975
5103
  {
4976
5104
  control: agentActions,
4977
5105
  ctx: {
4978
- message: message2,
5106
+ message: message3,
4979
5107
  get dom() {
4980
5108
  return messageRefs.current[baseKey];
4981
5109
  }
@@ -4993,7 +5121,7 @@ var BubbleListItems_default = ({
4993
5121
  MessageRender_default,
4994
5122
  {
4995
5123
  role,
4996
- message: message2,
5124
+ message: message3,
4997
5125
  messageIndex,
4998
5126
  customComponents,
4999
5127
  loading: isMessageLoading,
@@ -5572,6 +5700,313 @@ var ChatSenderHeader = () => {
5572
5700
  ] });
5573
5701
  };
5574
5702
  var ChatSenderHeader_default = ChatSenderHeader;
5703
+ var MonacoEditor = ({ value = "", onChange, placeholder, height = 200, readOnly = false, style }) => {
5704
+ const handleKeyDownCapture = useCallback((e) => {
5705
+ if (e.key === " " || e.code === "Space") {
5706
+ e.stopPropagation();
5707
+ }
5708
+ }, []);
5709
+ const handleKeyUpCapture = useCallback((e) => {
5710
+ if (e.key === " " || e.code === "Space") {
5711
+ e.stopPropagation();
5712
+ }
5713
+ }, []);
5714
+ const handleScriptChange = useCallback(
5715
+ (event) => {
5716
+ onChange?.(event.target.value || "");
5717
+ },
5718
+ [onChange]
5719
+ );
5720
+ return /* @__PURE__ */ jsx("div", { style, onKeyDownCapture: handleKeyDownCapture, onKeyUpCapture: handleKeyUpCapture, children: /* @__PURE__ */ jsx(
5721
+ Input.TextArea,
5722
+ {
5723
+ value,
5724
+ onChange: handleScriptChange,
5725
+ readOnly,
5726
+ placeholder,
5727
+ autoSize: false,
5728
+ style: {
5729
+ height,
5730
+ resize: "vertical",
5731
+ fontFamily: 'Monaco, Menlo, Consolas, "Courier New", monospace',
5732
+ ...style
5733
+ }
5734
+ }
5735
+ ) });
5736
+ };
5737
+ var MonacoEditor_default = MonacoEditor;
5738
+ var { Text: Text8 } = Typography;
5739
+ var FormFileUpload = ({ value, onChange, multiple = false }) => {
5740
+ const { token } = theme.useToken();
5741
+ const fileList = Array.isArray(value) ? value : value ? [value] : [];
5742
+ const chatStore = useChatStore();
5743
+ const conversationState = useSnapshot(chatStore.conversation);
5744
+ const agentState = useSnapshot(chatStore.agent);
5745
+ const configState = useSnapshot(chatStore.config);
5746
+ const customRequest = async (options) => {
5747
+ const { file, onSuccess, onError } = options;
5748
+ try {
5749
+ const formData = new FormData();
5750
+ formData.append("file", file);
5751
+ const params = {
5752
+ workspaceType: "conversation" /* CONVERSATION */,
5753
+ agentId: agentState.agentInfo.id,
5754
+ workspaceId: conversationState.active.id
5755
+ };
5756
+ const res = await configState.services.request.chatUpload(params, formData);
5757
+ if (res.code === 200 && res.data?.length) {
5758
+ const uploadedFile = res.data[0];
5759
+ onSuccess(uploadedFile);
5760
+ if (multiple) {
5761
+ onChange?.([...fileList, uploadedFile]);
5762
+ } else {
5763
+ onChange?.([uploadedFile]);
5764
+ }
5765
+ } else {
5766
+ message.error(res.message || "\u4E0A\u4F20\u5931\u8D25");
5767
+ onError(new Error(res.message));
5768
+ }
5769
+ } catch (error) {
5770
+ onError(error);
5771
+ }
5772
+ };
5773
+ const handleRemove = (fileToRemove) => {
5774
+ const newList = fileList.filter((f) => f.id !== fileToRemove.id);
5775
+ onChange?.(newList.length > 0 ? newList : void 0);
5776
+ };
5777
+ return /* @__PURE__ */ jsxs(Flex, { vertical: true, gap: 12, style: { width: "100%" }, children: [
5778
+ !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" }) }),
5779
+ fileList.length > 0 && /* @__PURE__ */ jsx(Flex, { vertical: true, gap: 8, children: fileList.map((file) => /* @__PURE__ */ jsxs(
5780
+ Flex,
5781
+ {
5782
+ align: "center",
5783
+ justify: "space-between",
5784
+ style: {
5785
+ padding: "8px 12px",
5786
+ backgroundColor: token.colorFillAlter,
5787
+ borderRadius: token.borderRadiusLG || 8,
5788
+ border: `1px solid ${token.colorBorderSecondary}`
5789
+ },
5790
+ children: [
5791
+ /* @__PURE__ */ jsxs(Flex, { align: "center", gap: 12, style: { overflow: "hidden", flex: 1 }, children: [
5792
+ /* @__PURE__ */ jsx(
5793
+ "div",
5794
+ {
5795
+ style: {
5796
+ width: 40,
5797
+ height: 40,
5798
+ backgroundColor: "#000",
5799
+ borderRadius: token.borderRadiusSM || 4,
5800
+ display: "flex",
5801
+ alignItems: "center",
5802
+ justifyContent: "center",
5803
+ flexShrink: 0
5804
+ },
5805
+ children: getFileIcon(file.extension || getFileSuffixName(file.name), 20)
5806
+ }
5807
+ ),
5808
+ /* @__PURE__ */ jsxs("div", { style: { overflow: "hidden", display: "flex", flexDirection: "column", flex: 1 }, children: [
5809
+ /* @__PURE__ */ jsx(Text8, { ellipsis: true, style: { width: "100%", fontSize: 14, fontWeight: 500 }, children: file.name }),
5810
+ /* @__PURE__ */ jsxs(Text8, { type: "secondary", style: { fontSize: 12 }, children: [
5811
+ (file.extension || getFileSuffixName(file.name)).toUpperCase(),
5812
+ " \u2022 ",
5813
+ formatFileSize(file.size)
5814
+ ] })
5815
+ ] })
5816
+ ] }),
5817
+ /* @__PURE__ */ jsx(Button, { type: "text", icon: /* @__PURE__ */ jsx(DeleteOutlined, {}), onClick: () => handleRemove(file), style: { color: token.colorTextSecondary } })
5818
+ ]
5819
+ },
5820
+ file.id || file.uid
5821
+ )) })
5822
+ ] });
5823
+ };
5824
+ var FormMonacoEditor = ({ value, onChange }) => {
5825
+ const { token } = theme.useToken();
5826
+ 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 }) });
5827
+ };
5828
+ var UserInputPanel = () => {
5829
+ const chatStore = useChatStore();
5830
+ const agentState = useSnapshot(chatStore.agent);
5831
+ const [form] = Form.useForm();
5832
+ const [activeKey, setActiveKey] = useState(["1"]);
5833
+ const inputs = useMemo(() => {
5834
+ if (agentState.agentInfo.userInput?.length > 0) {
5835
+ return agentState.agentInfo.userInput;
5836
+ }
5837
+ }, [agentState.agentInfo.userInput]);
5838
+ useEffect(() => {
5839
+ if (inputs.length > 0) {
5840
+ const initialValues = inputs.reduce((acc, cur) => {
5841
+ let value = cur.value;
5842
+ acc[cur.name] = value;
5843
+ return acc;
5844
+ }, {});
5845
+ form.setFieldsValue(initialValues);
5846
+ }
5847
+ }, [inputs, form]);
5848
+ const handleValuesChange = (changedValues) => {
5849
+ if (agentState.agentInfo.userInput?.length > 0) {
5850
+ const newInput = agentState.agentInfo.userInput.map((v) => {
5851
+ if (v.name in changedValues) {
5852
+ const newValue = changedValues[v.name];
5853
+ return { ...v, value: newValue };
5854
+ }
5855
+ return v;
5856
+ });
5857
+ chatStore.setConversationUserInput(newInput);
5858
+ return;
5859
+ }
5860
+ };
5861
+ const handleStartChat = () => {
5862
+ form.validateFields().then(() => {
5863
+ setActiveKey([]);
5864
+ }).catch(() => {
5865
+ message.error("\u8BF7\u68C0\u67E5\u8F93\u5165\u53C2\u6570");
5866
+ });
5867
+ };
5868
+ const renderFormItem = (item) => {
5869
+ const itemStyle = { marginBottom: 0 };
5870
+ const commonProps = {
5871
+ label: item.name,
5872
+ name: item.name,
5873
+ style: itemStyle,
5874
+ rules: item.rules?.map((r) => {
5875
+ const valStr = String(r.value || "");
5876
+ if (r.type === "required") return { required: true, message: r.message };
5877
+ if (r.type === "email") return { type: "email", message: r.message };
5878
+ if (r.type === "pattern") return { pattern: new RegExp(valStr), message: r.message };
5879
+ if (r.type === "max" || r.type === "min") {
5880
+ return {
5881
+ validator: (_, val) => {
5882
+ if (val === void 0 || val === null || val === "") return Promise.resolve();
5883
+ const numVal = Number(val);
5884
+ if (isNaN(numVal)) return Promise.resolve();
5885
+ if (r.type === "max" && numVal > Number(valStr)) return Promise.reject(new Error(r.message));
5886
+ if (r.type === "min" && numVal < Number(valStr)) return Promise.reject(new Error(r.message));
5887
+ return Promise.resolve();
5888
+ }
5889
+ };
5890
+ }
5891
+ if (r.type === "length") {
5892
+ const [min, max] = valStr.split(",").map((v) => v ? Number(v) : void 0);
5893
+ return {
5894
+ validator: (_, val) => {
5895
+ if (val === void 0 || val === null || val === "") return Promise.resolve();
5896
+ const strVal = String(val);
5897
+ if (min !== void 0 && strVal.length < min) return Promise.reject(new Error(r.message));
5898
+ if (max !== void 0 && strVal.length > max) return Promise.reject(new Error(r.message));
5899
+ return Promise.resolve();
5900
+ }
5901
+ };
5902
+ }
5903
+ if (r.type === "size") {
5904
+ const [min, max] = valStr.split(",").map((v) => v ? Number(v) : void 0);
5905
+ return {
5906
+ validator: (_, val) => {
5907
+ if (val === void 0 || val === null || val === "") return Promise.resolve();
5908
+ let len = 0;
5909
+ if (Array.isArray(val)) {
5910
+ len = val.length;
5911
+ } else if (typeof val === "string") {
5912
+ try {
5913
+ const parsed = JSON.parse(val);
5914
+ if (Array.isArray(parsed)) len = parsed.length;
5915
+ else return Promise.resolve();
5916
+ } catch (e) {
5917
+ return Promise.resolve();
5918
+ }
5919
+ } else {
5920
+ return Promise.resolve();
5921
+ }
5922
+ if (min !== void 0 && len < min) return Promise.reject(new Error(r.message));
5923
+ if (max !== void 0 && len > max) return Promise.reject(new Error(r.message));
5924
+ return Promise.resolve();
5925
+ }
5926
+ };
5927
+ }
5928
+ if (r.type === "enum") {
5929
+ const options = valStr.split(",").map((s) => s.trim());
5930
+ return {
5931
+ validator: (_, val) => {
5932
+ if (val === void 0 || val === null || val === "") return Promise.resolve();
5933
+ if (options.includes(String(val))) return Promise.resolve();
5934
+ return Promise.reject(new Error(r.message));
5935
+ }
5936
+ };
5937
+ }
5938
+ return {};
5939
+ })
5940
+ };
5941
+ if (["STRING", "LONG"].includes(item.type)) {
5942
+ return /* @__PURE__ */ jsx(Form.Item, { ...commonProps, children: /* @__PURE__ */ jsx(Input, { placeholder: "\u8BF7\u8F93\u5165\u503C" }) });
5943
+ }
5944
+ if (["NUMBER"].includes(item.type)) {
5945
+ return /* @__PURE__ */ jsx(Form.Item, { ...commonProps, children: /* @__PURE__ */ jsx(InputNumber, { style: { width: "100%" }, placeholder: "\u8BF7\u8F93\u5165\u6570\u503C" }) });
5946
+ }
5947
+ if (item.type === "BOOLEAN") {
5948
+ return /* @__PURE__ */ jsx(Form.Item, { style: itemStyle, name: item.name, valuePropName: "checked", children: /* @__PURE__ */ jsxs(Flex, { justify: "space-between", align: "center", children: [
5949
+ /* @__PURE__ */ jsx("span", { children: item.name }),
5950
+ /* @__PURE__ */ jsx(Switch$1, { size: "small" })
5951
+ ] }) });
5952
+ }
5953
+ if (item.type === "FILE") {
5954
+ return /* @__PURE__ */ jsx(Form.Item, { ...commonProps, children: /* @__PURE__ */ jsx(FormFileUpload, { multiple: false }) });
5955
+ }
5956
+ if (item.type === "ARRAY_FILE") {
5957
+ return /* @__PURE__ */ jsx(Form.Item, { ...commonProps, children: /* @__PURE__ */ jsx(FormFileUpload, { multiple: true }) });
5958
+ }
5959
+ if (["OBJECT", "ARRAY", "ARRAY_STRING", "ARRAY_NUMBER", "ARRAY_DECIMAL", "ARRAY_BOOLEAN", "ARRAY_OBJECT"].includes(item.type)) {
5960
+ return /* @__PURE__ */ jsx(Form.Item, { ...commonProps, children: /* @__PURE__ */ jsx(FormMonacoEditor, {}) });
5961
+ }
5962
+ return /* @__PURE__ */ jsx(Form.Item, { ...commonProps, children: /* @__PURE__ */ jsx(Input, { placeholder: "\u8BF7\u8F93\u5165\u503C" }) });
5963
+ };
5964
+ const genExtra = () => {
5965
+ if (activeKey.includes("1")) return null;
5966
+ return /* @__PURE__ */ jsx(
5967
+ Button,
5968
+ {
5969
+ type: "text",
5970
+ size: "small",
5971
+ onClick: (e) => {
5972
+ e.stopPropagation();
5973
+ setActiveKey(["1"]);
5974
+ },
5975
+ children: "\u7F16\u8F91"
5976
+ }
5977
+ );
5978
+ };
5979
+ const items = [
5980
+ {
5981
+ key: "1",
5982
+ label: "\u53C2\u6570\u8BBE\u7F6E",
5983
+ extra: genExtra(),
5984
+ children: /* @__PURE__ */ jsxs(Fragment, { children: [
5985
+ /* @__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" }) }),
5986
+ /* @__PURE__ */ jsx(Flex, { align: "center", justify: "center", className: "m-t-16", children: /* @__PURE__ */ jsx(Button, { type: "primary", onClick: handleStartChat, children: "\u5F00\u59CB\u4F1A\u8BDD" }) })
5987
+ ] })
5988
+ }
5989
+ ];
5990
+ return /* @__PURE__ */ jsx("div", { className: styles_module_default2.userInputCollapse, children: /* @__PURE__ */ jsx(
5991
+ Collapse,
5992
+ {
5993
+ activeKey,
5994
+ onChange: (keys) => {
5995
+ const newKeys = typeof keys === "string" ? [keys] : keys;
5996
+ setActiveKey(newKeys);
5997
+ },
5998
+ items,
5999
+ className: "m-16",
6000
+ styles: {
6001
+ body: {
6002
+ paddingRight: 0,
6003
+ paddingBottom: 10
6004
+ }
6005
+ }
6006
+ }
6007
+ ) });
6008
+ };
6009
+ var UserInputPanel_default = UserInputPanel;
5575
6010
 
5576
6011
  // src/ui/layouts/components/styles.module.less
5577
6012
  var styles_module_default5 = {
@@ -5596,9 +6031,11 @@ var ChatMainPanel = memo(
5596
6031
  []
5597
6032
  );
5598
6033
  const configState = useSnapshot(chatStore.config);
6034
+ const agentState = useSnapshot(chatStore.agent);
5599
6035
  return /* @__PURE__ */ jsxs(Flex, { vertical: true, className: classNames2("height-full"), children: [
5600
6036
  /* @__PURE__ */ jsx(RenderWrapper, { control: configState.layout.chatHeader, DefaultComponent: ChatHeader_default }),
5601
6037
  /* @__PURE__ */ jsxs(Flex, { align: "center", vertical: true, gap: 24, className: classNames2("height-full", styles_module_default5.bodyWidth), children: [
6038
+ shouldRender(agentState.agentInfo.userInput && agentState.agentInfo.userInput.length > 0) && /* @__PURE__ */ jsx(RenderWrapper, { control: configState.layout.userInput, DefaultComponent: UserInputPanel_default }),
5602
6039
  shouldRender(configState.layout.messageList) && /* @__PURE__ */ jsx("div", { className: "full-scroll", style: { width: "100%" }, children: /* @__PURE__ */ jsx(RenderWrapper, { control: configState.layout.messageList, DefaultComponent: BubbleListItems_default }) }),
5603
6040
  /* @__PURE__ */ jsx(RenderWrapper, { control: configState.layout.senderHeader, DefaultComponent: /* @__PURE__ */ jsx(ChatSenderHeader_default, {}) }),
5604
6041
  /* @__PURE__ */ jsxs(Flex, { className: styles_module_default5.inputContainer, vertical: true, gap: 8, children: [
@@ -5677,7 +6114,7 @@ var index_module_default3 = {
5677
6114
  animatedSplitter: "index_module_animatedSplitter",
5678
6115
  hideSplitterBar: "index_module_hideSplitterBar"
5679
6116
  };
5680
- var layouts_default = forwardRef(({ theme: theme4, params, hooks, layout, config, services }, _ref) => {
6117
+ var layouts_default = forwardRef(({ theme: theme5, params, hooks, layout, config, services }, _ref) => {
5681
6118
  const chatStore = useMemo(() => createChatStore(), []);
5682
6119
  const senderRef = useRef(null);
5683
6120
  useImperativeHandle(
@@ -5724,6 +6161,11 @@ var layouts_default = forwardRef(({ theme: theme4, params, hooks, layout, config
5724
6161
  chatStore.setAgent({ ...agentState.agentInfo, config: config.agent.config || {} });
5725
6162
  }
5726
6163
  }, [agentState.agentInfo.id, config.agent?.config]);
6164
+ useDeepEffect(() => {
6165
+ if (agentState.agentInfo.id) {
6166
+ chatStore.setUserInput(config.agent.userInput);
6167
+ }
6168
+ }, [agentState.agentInfo.id, config.agent?.userInput]);
5727
6169
  useDeepEffect(() => {
5728
6170
  if (config?.agent?.id) {
5729
6171
  chatStore.getAgentInfo(config.agent.id);
@@ -5750,20 +6192,20 @@ var layouts_default = forwardRef(({ theme: theme4, params, hooks, layout, config
5750
6192
  }, [hasPreView]);
5751
6193
  useWebSocket({
5752
6194
  url: configState.services.websocketUrls?.[0],
5753
- onMessage: (message2) => chatStore.acceptMessage(message2.payload),
6195
+ onMessage: (message3) => chatStore.acceptMessage(message3.payload),
5754
6196
  clientHeartbeat: false,
5755
6197
  reconnectInterval: 1e4
5756
6198
  });
5757
6199
  useWebSocket({
5758
6200
  url: configState.services.websocketUrls?.[1],
5759
- onMessage: (message2) => chatStore.acceptMessage(message2.payload),
6201
+ onMessage: (message3) => chatStore.acceptMessage(message3.payload),
5760
6202
  clientHeartbeat: false,
5761
6203
  reconnectInterval: 1e4
5762
6204
  });
5763
6205
  useEffect(() => {
5764
6206
  hooks?.onBeforeInit?.();
5765
6207
  }, []);
5766
- 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: [
6208
+ 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: [
5767
6209
  /* @__PURE__ */ jsx(RenderWrapper, { control: configState.layout.globalHeader, DefaultComponent: ChatHeader_default }),
5768
6210
  /* @__PURE__ */ jsxs(Flex, { ref: containerRef, className: "full-scroll", children: [
5769
6211
  /* @__PURE__ */ jsx(RenderWrapper, { control: configState.layout.leftPanel }),