@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.cjs.js CHANGED
@@ -72,7 +72,7 @@ var styles_module_default = {
72
72
  chatAttachments: "styles_module_chatAttachments",
73
73
  chatSender: "styles_module_chatSender"};
74
74
  var Attachments_default = React10.forwardRef(({ fileUpload, fileUploadConfig, fileList = [], onChange, extraParams }, ref) => {
75
- const { message: message2 } = antd.App.useApp();
75
+ const { message: message3 } = antd.App.useApp();
76
76
  const chatStore = useChatStore();
77
77
  valtio.useSnapshot(chatStore.agent);
78
78
  const fileListRef = React10.useRef([]);
@@ -100,7 +100,7 @@ var Attachments_default = React10.forwardRef(({ fileUpload, fileUploadConfig, fi
100
100
  onChange(files);
101
101
  }, [attachedFiles]);
102
102
  const onErrorTip = common.useDebounce((errorMsg) => {
103
- message2.error(errorMsg);
103
+ message3.error(errorMsg);
104
104
  }, 300);
105
105
  const findConfig = (file) => {
106
106
  return fileUploadConfig?.allowedTypes?.find((type) => type === common.getFileSuffixName(file.name)) || "";
@@ -294,6 +294,41 @@ var classifyTime = (timestamp) => {
294
294
  return "\u66F4\u65E9";
295
295
  }
296
296
  };
297
+ var variablesToObject = (variables) => {
298
+ if (!common.isArray(variables)) return {};
299
+ const jsonTypes = ["OBJECT", "ARRAY", "ARRAY_STRING", "ARRAY_NUMBER", "ARRAY_DECIMAL", "ARRAY_BOOLEAN", "ARRAY_OBJECT"];
300
+ return variables.reduce(
301
+ (acc, cur) => {
302
+ if (cur.type === "BOOLEAN") {
303
+ if (common.isDef(cur.value) && !common.isNull(cur.value)) {
304
+ acc[cur.name] = cur.value;
305
+ }
306
+ } else if (jsonTypes.includes(cur.type)) {
307
+ if (common.isDef(cur.value) && !common.isNull(cur.value)) {
308
+ if (typeof cur.value === "string") {
309
+ if (cur.value === "") {
310
+ acc[cur.name] = cur.type === "OBJECT" ? {} : [];
311
+ } else {
312
+ try {
313
+ acc[cur.name] = JSON.parse(cur.value);
314
+ } catch (e) {
315
+ acc[cur.name] = cur.type === "OBJECT" ? {} : [];
316
+ }
317
+ }
318
+ } else {
319
+ acc[cur.name] = cur.value;
320
+ }
321
+ }
322
+ } else {
323
+ if (common.isDef(cur.value) && !common.isNull(cur.value) && cur.value !== "") {
324
+ acc[cur.name] = cur.value;
325
+ }
326
+ }
327
+ return acc;
328
+ },
329
+ {}
330
+ );
331
+ };
297
332
  var getChatSocketUrl = (baseURL, params) => {
298
333
  return common.buildUrlParams(params, common.getWebSocketUrl(`${baseURL}/ws`), "comma");
299
334
  };
@@ -331,6 +366,15 @@ var getFileUrl = (params, baseUrl, url) => {
331
366
  };
332
367
  return common.buildUrlParams(data, url || `${baseUrl}/files/access`);
333
368
  };
369
+ var formatFileSize = (size = 0) => {
370
+ if (size < 1024) return `${size} B`;
371
+ const kb = size / 1024;
372
+ if (kb < 1024) return `${kb.toFixed(2)} KB`;
373
+ const mb = kb / 1024;
374
+ if (mb < 1024) return `${mb.toFixed(2)} MB`;
375
+ const gb = mb / 1024;
376
+ return `${gb.toFixed(2)} GB`;
377
+ };
334
378
  function GroupPicker({
335
379
  groups,
336
380
  selectedIndex,
@@ -401,6 +445,13 @@ function formatResourceName(resourceName) {
401
445
  if (name.length <= 6) return `${name}${extension}`;
402
446
  return `${name.slice(0, 3)}***${name.slice(-3)}${extension}`;
403
447
  }
448
+ function ReadonlyResourceTag({ resource }) {
449
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: index_module_default.resourceTag, children: /* @__PURE__ */ jsxRuntime.jsxs(antd.Tag, { color: "blue", children: [
450
+ resource.resourceLabel,
451
+ "\uFF1A",
452
+ formatResourceName(resource.resourceName)
453
+ ] }) });
454
+ }
404
455
  function ResourceTag({ resource }) {
405
456
  const [editor] = LexicalComposerContext.useLexicalComposerContext();
406
457
  const handleClose = (event) => {
@@ -488,7 +539,7 @@ var VariableNode = class _VariableNode extends lexical.DecoratorNode {
488
539
  * 生成节点的纯文本表达,便于发送、存储和重新初始化编辑器内容。
489
540
  */
490
541
  getTextContent() {
491
- return `${this.__resourceType}://${this.__resourceId}?name=${this.__resourceName}&label=${this.__resourceLabel}`;
542
+ return ` ${this.__resourceType}://${this.__resourceId}?name=${this.__resourceName}&label=${this.__resourceLabel} `;
492
543
  }
493
544
  /**
494
545
  * 将变量节点渲染为可交互的资源标签组件。
@@ -556,6 +607,7 @@ function VariablePickerPlugin({ commandConfig = {} }) {
556
607
  React10.useEffect(() => {
557
608
  setCommandDataSource(commandConfig);
558
609
  }, [commandConfig]);
610
+ const commandKeys = React10.useMemo(() => Object.keys(commandConfig), [commandConfig]);
559
611
  const commandKey = queryString?.[0] || "";
560
612
  const searchKeyword = queryString?.slice(commandKey.length).trim().toLocaleLowerCase() || "";
561
613
  const categoryConfig = React10.useMemo(
@@ -668,15 +720,15 @@ function VariablePickerPlugin({ commandConfig = {} }) {
668
720
  onQueryChange: (query) => setQueryString(query),
669
721
  onSelectOption,
670
722
  triggerFn: (text) => {
671
- const match = new RegExp(
672
- `(?:${Object.keys(commandConfig).map((key) => key.replace(/[.*+?^${}()|[\\]\\]/g, "\\$&")).join("|")})([^\\s]*)$`
673
- ).exec(text);
723
+ if (!commandKeys.length) return null;
724
+ const match = new RegExp(`(?:${commandKeys.map((key) => key.replace(/[.*+?^${}()|[\\]\\]/g, "\\$&")).join("|")})([^\\s]*)$`).exec(text);
674
725
  if (!match) return null;
675
726
  return { leadOffset: match.index, matchingString: match[0], replaceableString: match[0] };
676
727
  },
677
728
  options: commandOptions,
678
729
  menuRenderFn: (anchorElementRef, { selectedIndex, setHighlightedIndex, selectOptionAndCleanUp }) => {
679
- if (!isEditorFocused || !anchorElementRef.current || searchKeyword && !commandGroups.length) return null;
730
+ if (!isEditorFocused || !anchorElementRef.current || !commandKeys.length || !commandGroups.length && !searchKeyword) return null;
731
+ if (searchKeyword && !commandGroups.length) return null;
680
732
  return ReactDOM__namespace.createPortal(
681
733
  /* @__PURE__ */ jsxRuntime.jsx(ResourcePickerMenu, { anchorElementRef, children: /* @__PURE__ */ jsxRuntime.jsx(
682
734
  GroupPicker,
@@ -854,8 +906,8 @@ var ChatSender_default = React10.forwardRef(
854
906
  const isFocusedRef = React10.useRef(false);
855
907
  const commandConfigRef = React10.useRef(commandConfig);
856
908
  commandConfigRef.current = commandConfig;
857
- const inputComponent = React10.useCallback(
858
- (inputProps) => /* @__PURE__ */ jsxRuntime.jsx(ChatInput_default, { ...inputProps, commandConfig: commandConfigRef.current }),
909
+ const inputComponent = React10.useMemo(
910
+ () => React10.forwardRef((inputProps, ref2) => /* @__PURE__ */ jsxRuntime.jsx(ChatInput_default, { ...inputProps, ref: ref2, commandConfig: commandConfigRef.current })),
859
911
  []
860
912
  );
861
913
  React10.useEffect(() => {
@@ -1006,7 +1058,8 @@ var defaultLayout = {
1006
1058
  messageList: true,
1007
1059
  senderHeader: false,
1008
1060
  senderFooter: false,
1009
- disclaimerNotice: true
1061
+ disclaimerNotice: true,
1062
+ userInput: false
1010
1063
  };
1011
1064
  function createChatStore() {
1012
1065
  const config = valtio.proxy({
@@ -1119,6 +1172,17 @@ function createChatStore() {
1119
1172
  agent.model = { ...agent.model, ...model };
1120
1173
  config.hooks?.onAfterSwitchModel?.(model);
1121
1174
  };
1175
+ const getUserInput = async (agentId) => {
1176
+ agent.loading = true;
1177
+ try {
1178
+ const { data } = await config.services.request.getAgentUserInput(agentId);
1179
+ if (data?.inputs && !agent.agentInfo.userInput?.length) {
1180
+ agent.agentInfo.userInput = data.inputs.filter((item) => item.enableEdit);
1181
+ }
1182
+ } finally {
1183
+ agent.loading = false;
1184
+ }
1185
+ };
1122
1186
  const setAgent = (agentInfo) => {
1123
1187
  agent.agentInfo = agentInfo;
1124
1188
  if (agentInfo.agentType === 2 /* AUTONOMOUS */) {
@@ -1126,6 +1190,13 @@ function createChatStore() {
1126
1190
  modelName: agent.agentInfo.spec?.model?.modelName || "",
1127
1191
  providerName: agent.agentInfo.spec?.model?.providerName || ""
1128
1192
  });
1193
+ } else if (config.layout.userInput) {
1194
+ getUserInput(agent.agentInfo.id);
1195
+ }
1196
+ };
1197
+ const setUserInput = (userInput) => {
1198
+ if (agent.agentInfo.agentType === 1 /* FLOW */) {
1199
+ agent.agentInfo.userInput = userInput;
1129
1200
  }
1130
1201
  };
1131
1202
  const getAgentInfo = async (id) => {
@@ -1252,7 +1323,8 @@ function createChatStore() {
1252
1323
  /** 当前激活的会话信息 */
1253
1324
  active: {
1254
1325
  id: "",
1255
- spec: {}
1326
+ spec: {},
1327
+ userInput: []
1256
1328
  },
1257
1329
  /** 每个会话的消息存储,以会话ID为键 */
1258
1330
  messages: {},
@@ -1287,6 +1359,9 @@ function createChatStore() {
1287
1359
  Object.assign(conversation.active.spec, spec);
1288
1360
  }
1289
1361
  };
1362
+ const setConversationUserInput = (userInput) => {
1363
+ conversation.active.userInput = userInput;
1364
+ };
1290
1365
  const feedback = async (executionId, feedback2, index) => {
1291
1366
  try {
1292
1367
  conversation.feedback.loading = true;
@@ -1671,9 +1746,9 @@ function createChatStore() {
1671
1746
  }
1672
1747
  }
1673
1748
  }
1674
- function processMessageContent(message2) {
1749
+ function processMessageContent(message3) {
1675
1750
  const newMessage = {
1676
- ...message2,
1751
+ ...message3,
1677
1752
  agentId: agent.agentInfo.id
1678
1753
  };
1679
1754
  const contentList = Array.isArray(newMessage.content) ? newMessage.content : [];
@@ -1721,14 +1796,14 @@ function createChatStore() {
1721
1796
  }
1722
1797
  processMessageContent(newMessage);
1723
1798
  };
1724
- const sendMessage = async (message2, msgFiles = [], params) => {
1799
+ const sendMessage = async (message3, msgFiles = [], params) => {
1725
1800
  const conversationId = conversation.active.id;
1726
1801
  if (conversation.messages[conversationId].loading) return;
1727
1802
  let msgContent = "", files;
1728
1803
  const references = conversation.messages[conversationId].references;
1729
- if (message2) {
1730
- msgContent = message2;
1731
- files = msgFiles;
1804
+ if (message3) {
1805
+ msgContent = message3;
1806
+ files = [...msgFiles, ...conversation.messages[conversationId].files || []];
1732
1807
  } else {
1733
1808
  if (references?.type === 1 && references?.content?.msgContent) {
1734
1809
  msgContent = references.content.msgContent + "\n\n";
@@ -1739,6 +1814,22 @@ function createChatStore() {
1739
1814
  if (!msgContent) return;
1740
1815
  const canProceed = await config.hooks?.onBeforeSend?.(msgContent, files || []);
1741
1816
  if (canProceed === false) return;
1817
+ if (conversation.active.userInput?.length) {
1818
+ const invalid = conversation.active.userInput.some((item) => {
1819
+ const isRequired = item.rules?.some((r) => r.type === "required");
1820
+ if (isRequired) {
1821
+ if (item.type === "BOOLEAN") {
1822
+ return common.isNullOrUnDef(item.value);
1823
+ }
1824
+ return common.isNullOrUnDef(item.value) || item.value === "";
1825
+ }
1826
+ return false;
1827
+ });
1828
+ if (invalid) {
1829
+ antd.message.error("\u8BF7\u68C0\u67E5\u8F93\u5165\u53C2\u6570");
1830
+ return;
1831
+ }
1832
+ }
1742
1833
  conversation.messages[conversationId].loading = true;
1743
1834
  const idx = conversations.list.items.findIndex((item) => item.id === conversationId);
1744
1835
  if (idx !== -1 && !conversations.list.items[idx].label) {
@@ -1757,15 +1848,16 @@ function createChatStore() {
1757
1848
  responseMode: 2
1758
1849
  };
1759
1850
  const extraParams = common.deepCopy(config.params?.params || {});
1760
- Object.assign(extraParams, message2 ? {} : { ...references?.params }, params);
1851
+ const userInputParams = variablesToObject(conversation.active.userInput || []);
1852
+ Object.assign(extraParams, message3 ? {} : { ...references?.params }, params, userInputParams);
1761
1853
  sendParams.params = extraParams;
1762
- if (!message2) {
1854
+ if (!message3) {
1763
1855
  setContent("");
1764
1856
  setContentParams();
1765
- setFileList([]);
1766
1857
  setReferences();
1767
- setHeaderOpen(false);
1768
1858
  }
1859
+ setFileList([]);
1860
+ setHeaderOpen(false);
1769
1861
  try {
1770
1862
  const dealedParams = await config.hooks?.onHandleSendParams?.(sendParams);
1771
1863
  await config.services.request.sendMessageStream(dealedParams || sendParams, agent.agentInfo?.id || "");
@@ -1823,7 +1915,7 @@ function createChatStore() {
1823
1915
  /** 设置智能体 */
1824
1916
  setAgent,
1825
1917
  /** 设置智能体用户输入 */
1826
- // setUserInput,
1918
+ setUserInput,
1827
1919
  /** 设置会话配置 */
1828
1920
  setConversationSpec,
1829
1921
  /** 历史会话状态 */
@@ -1857,9 +1949,11 @@ function createChatStore() {
1857
1949
  /** 接收消息 */
1858
1950
  acceptMessage,
1859
1951
  /** 获取智能体用户输入 */
1860
- // getUserInput,
1952
+ getUserInput,
1861
1953
  /** 消息反馈 */
1862
- feedback
1954
+ feedback,
1955
+ /** 设置会话用户输入 */
1956
+ setConversationUserInput
1863
1957
  };
1864
1958
  }
1865
1959
  var AuthImage = ({ path, size, shape = "square" }) => {
@@ -1953,6 +2047,7 @@ var styles_module_default2 = {
1953
2047
  chatWelcome: "styles_module_chatWelcome",
1954
2048
  promptItem: "styles_module_promptItem",
1955
2049
  bubbleList: "styles_module_bubbleList",
2050
+ userInputCollapse: "styles_module_userInputCollapse",
1956
2051
  logoArea: "styles_module_logoArea",
1957
2052
  logoContainer: "styles_module_logoContainer",
1958
2053
  staticHalo: "styles_module_staticHalo",
@@ -2686,12 +2781,12 @@ var DocDrawer_default = ({ title, open, onClose, paramsStr }) => {
2686
2781
  }, [paramsStr]);
2687
2782
  return /* @__PURE__ */ jsxRuntime.jsx(antd.Drawer, { title, push: false, size: "100%", open, onClose, children: /* @__PURE__ */ jsxRuntime.jsx(antd.Spin, { spinning: loading, children: content ? /* @__PURE__ */ jsxRuntime.jsx(XMarkdown__default.default, { content }) : /* @__PURE__ */ jsxRuntime.jsx(antd.Empty, { className: "m-t-32" }) }) });
2688
2783
  };
2689
- var IndexQuote_default = ({ data, loading, message: message2 }) => {
2784
+ var IndexQuote_default = ({ data, loading, message: message3 }) => {
2690
2785
  const [open, setOpen] = React10.useState(false);
2691
2786
  const citation = React10.useMemo(() => {
2692
- const citations = message2.content?.find((item) => item.type === "citation")?.citations ?? [];
2787
+ const citations = message3.content?.find((item) => item.type === "citation")?.citations ?? [];
2693
2788
  return citations?.find((item) => String(item.citationId) === String(data.citationId));
2694
- }, [data.citationId, message2.content]);
2789
+ }, [data.citationId, message3.content]);
2695
2790
  const onClick = () => {
2696
2791
  if (!citation?.citationUrl) return;
2697
2792
  if (common.isExternal(citation.citationUrl)) {
@@ -2706,7 +2801,7 @@ var IndexQuote_default = ({ data, loading, message: message2 }) => {
2706
2801
  open && /* @__PURE__ */ jsxRuntime.jsx(DocDrawer_default, { paramsStr: citation?.citationUrl, title: citation?.citationName, open, onClose: () => setOpen(false) })
2707
2802
  ] });
2708
2803
  };
2709
- var MarkImg_default = ({ data, loading, message: message2, ...rest }) => {
2804
+ var MarkImg_default = ({ data, loading, message: message3, ...rest }) => {
2710
2805
  const getPreviewFileUrl = (src) => {
2711
2806
  return common.buildUrlParams({ [TOKEN_KEY]: tokenManager.get() || "" }, src);
2712
2807
  };
@@ -2733,7 +2828,7 @@ var MdEdit_default = ({ data, loading }) => {
2733
2828
  !loading && /* @__PURE__ */ jsxRuntime.jsx(antd.Flex, { justify: "end", className: "m-t-16", children: /* @__PURE__ */ jsxRuntime.jsx(antd.Button, { color: "primary", variant: "outlined", onClick: onOk, children: btnText }) })
2734
2829
  ] });
2735
2830
  };
2736
- var PreviewLink_default = ({ data, loading, message: message2, ...rest }) => {
2831
+ var PreviewLink_default = ({ data, loading, message: message3, ...rest }) => {
2737
2832
  const chatStore = useChatStore();
2738
2833
  const getLinkFileName = (href) => {
2739
2834
  const url = new URL(href, window.location.origin);
@@ -2766,7 +2861,7 @@ var PreviewLink_default = ({ data, loading, message: message2, ...rest }) => {
2766
2861
  chatStore.setPreview({
2767
2862
  fileUrl: chatStore.config.services.request.getPreviewUrl({
2768
2863
  path: href,
2769
- workspaceId: message2.conversationId
2864
+ workspaceId: message3.conversationId
2770
2865
  }),
2771
2866
  fileName,
2772
2867
  suffix
@@ -2873,7 +2968,7 @@ var adaptMarkdownComponent = (Component, payloadMapRef, messageRef) => {
2873
2968
  return WrappedComponent;
2874
2969
  };
2875
2970
  var adaptMarkdownComponents = (components, payloadMapRef, messageRef) => Object.fromEntries(Object.entries(components ?? {}).map(([key, Component]) => [key, adaptMarkdownComponent(Component, payloadMapRef, messageRef)]));
2876
- var XMarkdown_default = React10.memo(({ message: message2, components = {}, content = "", ...rest }) => {
2971
+ var XMarkdown_default = React10.memo(({ message: message3, components = {}, content = "", ...rest }) => {
2877
2972
  const config = React10.useMemo(() => getMarkdownConfig(), []);
2878
2973
  const formattedContent = React10.useMemo(() => formatMixedContent(content), [content]);
2879
2974
  const newComponents = React10.useMemo(
@@ -2899,9 +2994,9 @@ var XMarkdown_default = React10.memo(({ message: message2, components = {}, cont
2899
2994
  [formattedContent, payloadTagPattern]
2900
2995
  );
2901
2996
  const payloadMapRef = React10.useRef(payloadMap);
2902
- const messageRef = React10.useRef(message2);
2997
+ const messageRef = React10.useRef(message3);
2903
2998
  payloadMapRef.current = payloadMap;
2904
- messageRef.current = message2;
2999
+ messageRef.current = message3;
2905
3000
  const markdownComponents = React10.useMemo(() => adaptMarkdownComponents(newComponents, payloadMapRef, messageRef), [payloadTagPattern]);
2906
3001
  return /* @__PURE__ */ jsxRuntime.jsx(
2907
3002
  XMarkdown__default.default,
@@ -3354,9 +3449,9 @@ function splitA2uiTextSegments(text) {
3354
3449
  }
3355
3450
  return segments.length ? segments : [];
3356
3451
  }
3357
- function extractInlineSurfaceIdsFromMessage(message2) {
3452
+ function extractInlineSurfaceIdsFromMessage(message3) {
3358
3453
  const surfaceIds = /* @__PURE__ */ new Set();
3359
- const items = Array.isArray(message2?.content) ? message2.content : [];
3454
+ const items = Array.isArray(message3?.content) ? message3.content : [];
3360
3455
  for (const item of items) {
3361
3456
  if (item?.type !== "text") continue;
3362
3457
  const text = item.messageContent || item.text || "";
@@ -3375,10 +3470,10 @@ function extractDismissedSurfaceIdsFromMessages(messages) {
3375
3470
  const lastCreateIndexBySurface = /* @__PURE__ */ new Map();
3376
3471
  const lastActionIndexBySurface = /* @__PURE__ */ new Map();
3377
3472
  for (let messageIndex = 0; messageIndex < messages.length; messageIndex++) {
3378
- const message2 = messages[messageIndex];
3379
- const items = Array.isArray(message2?.content) ? message2.content : [];
3473
+ const message3 = messages[messageIndex];
3474
+ const items = Array.isArray(message3?.content) ? message3.content : [];
3380
3475
  for (const item of items) {
3381
- if (message2?.role !== 1) {
3476
+ if (message3?.role !== 1) {
3382
3477
  if (item?.type === "a2uiCommand" && item.command) {
3383
3478
  const surfaceId = String(item.command?.createSurface?.surfaceId || "").trim();
3384
3479
  if (surfaceId) lastCreateIndexBySurface.set(surfaceId, messageIndex);
@@ -3396,7 +3491,7 @@ function extractDismissedSurfaceIdsFromMessages(messages) {
3396
3491
  }
3397
3492
  }
3398
3493
  }
3399
- if (message2?.role === 1 && item?.type === "text") {
3494
+ if (message3?.role === 1 && item?.type === "text") {
3400
3495
  const text = item.messageContent || item.text || "";
3401
3496
  if (typeof text !== "string" || !text.includes("a2ui_action.v1")) continue;
3402
3497
  try {
@@ -3909,6 +4004,15 @@ function extractSurfaceId2(command) {
3909
4004
  function getA2uiRuntimeCommands(state) {
3910
4005
  return [...state.serverCommands, ...state.localCommands];
3911
4006
  }
4007
+ function sanitizeA2uiCommands(commands) {
4008
+ return commands.map((cmd) => {
4009
+ if (!cmd || typeof cmd !== "object" || !cmd.updateDataModel) return cmd;
4010
+ const { path } = cmd.updateDataModel;
4011
+ if (typeof path === "string" && path.trim()) return cmd;
4012
+ const { updateDataModel: _, ...rest } = cmd;
4013
+ return rest;
4014
+ });
4015
+ }
3912
4016
  function diffConversationMessages(messages, prevCursors) {
3913
4017
  if (messages.length < prevCursors.length) {
3914
4018
  return { shouldReplayAll: true, nextCursors: [], pendingItems: [] };
@@ -3916,9 +4020,9 @@ function diffConversationMessages(messages, prevCursors) {
3916
4020
  const nextCursors = [];
3917
4021
  const pendingItems = [];
3918
4022
  for (let messageIndex = 0; messageIndex < messages.length; messageIndex += 1) {
3919
- const message2 = messages[messageIndex];
3920
- const messageId = String(message2?.messageId ?? messageIndex);
3921
- const items = Array.isArray(message2?.content) ? message2.content : [];
4023
+ const message3 = messages[messageIndex];
4024
+ const messageId = String(message3?.messageId ?? messageIndex);
4025
+ const items = Array.isArray(message3?.content) ? message3.content : [];
3922
4026
  const prevCursor = prevCursors[messageIndex];
3923
4027
  const startIndex = prevCursor ? prevCursor.contentLength : 0;
3924
4028
  if (prevCursor && (prevCursor.messageId !== messageId || items.length < prevCursor.contentLength)) {
@@ -3980,9 +4084,9 @@ function scanA2uiTagsFromMessages(messages, processedTagIds) {
3980
4084
  const newTags = [];
3981
4085
  const newTagIds = [];
3982
4086
  for (let messageIndex = 0; messageIndex < messages.length; messageIndex += 1) {
3983
- const message2 = messages[messageIndex];
3984
- const messageId = String(message2?.messageId ?? messageIndex);
3985
- const items = Array.isArray(message2?.content) ? message2.content : [];
4087
+ const message3 = messages[messageIndex];
4088
+ const messageId = String(message3?.messageId ?? messageIndex);
4089
+ const items = Array.isArray(message3?.content) ? message3.content : [];
3986
4090
  for (const item of items) {
3987
4091
  if (item?.type !== "text") continue;
3988
4092
  const text = item.messageContent || item.text || "";
@@ -4000,9 +4104,9 @@ function scanA2uiTagsFromMessages(messages, processedTagIds) {
4000
4104
  }
4001
4105
  function reduceA2uiRuntimeMessages(state, messages) {
4002
4106
  const { shouldReplayAll, pendingItems, nextCursors } = diffConversationMessages(messages || [], state.processedMessageCursors);
4003
- const itemsToProcess = shouldReplayAll ? messages.flatMap((message2, messageIndex) => {
4004
- const messageId = String(message2?.messageId ?? messageIndex);
4005
- const items = Array.isArray(message2?.content) ? message2.content : [];
4107
+ const itemsToProcess = shouldReplayAll ? messages.flatMap((message3, messageIndex) => {
4108
+ const messageId = String(message3?.messageId ?? messageIndex);
4109
+ const items = Array.isArray(message3?.content) ? message3.content : [];
4006
4110
  return items.map((item) => ({ messageIndex, messageId, item }));
4007
4111
  }) : pendingItems;
4008
4112
  const tagProcessedSet = new Set(shouldReplayAll ? [] : state.processedTagIds);
@@ -4044,9 +4148,9 @@ function reduceA2uiRuntimeMessages(state, messages) {
4044
4148
  processA2uiCommand(cmd, messageIndex, messageId, nextState, effects, deletedSurfaceIds, nextWizardSteps);
4045
4149
  }
4046
4150
  });
4047
- nextState.processedMessageCursors = shouldReplayAll ? messages.map((message2, messageIndex) => ({
4048
- messageId: String(message2?.messageId ?? messageIndex),
4049
- contentLength: Array.isArray(message2?.content) ? message2.content.length : 0
4151
+ nextState.processedMessageCursors = shouldReplayAll ? messages.map((message3, messageIndex) => ({
4152
+ messageId: String(message3?.messageId ?? messageIndex),
4153
+ contentLength: Array.isArray(message3?.content) ? message3.content.length : 0
4050
4154
  })) : nextCursors;
4051
4155
  nextState.wizardStepBySurface = { ...nextState.wizardStepBySurface, ...nextWizardSteps };
4052
4156
  if (deletedSurfaceIds.size) {
@@ -4106,7 +4210,7 @@ function selectA2uiRuntimeView(state, dismissedSurfaceIds) {
4106
4210
  const mergedDismissedSurfaceIds = Array.from(
4107
4211
  new Set([...dismissedSurfaceIds || [], ...state.optimisticallyDismissedSurfaceIds].filter((surfaceId) => surfaceId?.trim?.()))
4108
4212
  );
4109
- const commands = getA2uiRuntimeCommands(state);
4213
+ const commands = sanitizeA2uiCommands(getA2uiRuntimeCommands(state));
4110
4214
  const visibleSurfaceIds = resolveVisibleSurfaceIds(commands, mergedDismissedSurfaceIds);
4111
4215
  const anchoredSurfaceIdsByMessageIndex = {};
4112
4216
  visibleSurfaceIds.forEach((surfaceId) => {
@@ -4195,10 +4299,10 @@ var A2uiRuntimeContext = React10__namespace.default.createContext({
4195
4299
  function useA2uiRuntimeView() {
4196
4300
  return React10__namespace.default.useContext(A2uiRuntimeContext);
4197
4301
  }
4198
- function A2uiMessageCards({ messageIndex, message: message2 }) {
4302
+ function A2uiMessageCards({ messageIndex, message: message3 }) {
4199
4303
  const { surfaceIdsByMessageIndex } = useA2uiRuntimeView();
4200
4304
  const allSurfaceIds = surfaceIdsByMessageIndex[messageIndex] || [];
4201
- const inlineSurfaceIds = message2 ? extractInlineSurfaceIdsFromMessage(message2) : /* @__PURE__ */ new Set();
4305
+ const inlineSurfaceIds = message3 ? extractInlineSurfaceIdsFromMessage(message3) : /* @__PURE__ */ new Set();
4202
4306
  const surfaceIds = allSurfaceIds.filter((id) => !inlineSurfaceIds.has(id));
4203
4307
  if (!surfaceIds.length) return null;
4204
4308
  return /* @__PURE__ */ jsxRuntime.jsx("div", { children: surfaceIds.map((surfaceId) => /* @__PURE__ */ jsxRuntime.jsx(XCard.Card, { id: surfaceId }, surfaceId)) });
@@ -4396,8 +4500,8 @@ function readContextModelPath(context) {
4396
4500
  function buildLatestCommandIndexBySurface(messages) {
4397
4501
  const indexBySurface = {};
4398
4502
  let commandIndex = -1;
4399
- for (const message2 of messages) {
4400
- const items = Array.isArray(message2?.content) ? message2.content : [];
4503
+ for (const message3 of messages) {
4504
+ const items = Array.isArray(message3?.content) ? message3.content : [];
4401
4505
  for (const item of items) {
4402
4506
  if (item?.type === "a2uiCommand" && item.command) {
4403
4507
  commandIndex += 1;
@@ -4553,6 +4657,8 @@ var RunStartedNode = React10__namespace.default.memo(({ loading }) => {
4553
4657
  if (!loading) return null;
4554
4658
  return /* @__PURE__ */ jsxRuntime.jsx(antd.Flex, { gap: 8, align: "center", className: style_module_default2.runStartedNode, children: /* @__PURE__ */ jsxRuntime.jsx(icons.LoadingOutlined, { style: { color: "#1677ff" } }) });
4555
4659
  });
4660
+ var RESOURCE_MARKDOWN_TAG = "resourcetag";
4661
+ var RESOURCE_TOKEN_REGEX = /(\w+):\/\/([^?\s]+)\?name=([^&\s]+)&label=([^\s]+)/g;
4556
4662
  function QuestionSummary({ content }) {
4557
4663
  const answer = content.replace(/^Question:\s*/, "").trim() || "\u5DF2\u56DE\u7B54";
4558
4664
  return /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { display: "inline-flex", flexDirection: "column", gap: 4 }, children: [
@@ -4560,17 +4666,37 @@ function QuestionSummary({ content }) {
4560
4666
  /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: 13, color: "#262626", lineHeight: 1.6, whiteSpace: "pre-wrap" }, children: answer })
4561
4667
  ] });
4562
4668
  }
4669
+ function MessageResourceTag({ data }) {
4670
+ const resource = data;
4671
+ if (!resource) return null;
4672
+ return /* @__PURE__ */ jsxRuntime.jsx(ReadonlyResourceTag, { resource });
4673
+ }
4674
+ function transformResourceText(content) {
4675
+ return content.replace(RESOURCE_TOKEN_REGEX, (_, resourceType, resourceId, resourceName, resourceLabel) => {
4676
+ const resource = {
4677
+ resourceType: decodeURIComponent(resourceType),
4678
+ resourceId: decodeURIComponent(resourceId),
4679
+ resourceName: decodeURIComponent(resourceName),
4680
+ resourceLabel: decodeURIComponent(resourceLabel)
4681
+ };
4682
+ return `<${RESOURCE_MARKDOWN_TAG}>${JSON.stringify(resource)}</${RESOURCE_MARKDOWN_TAG}>`;
4683
+ });
4684
+ }
4563
4685
  var TextNode2 = React10__namespace.default.memo(
4564
4686
  ({
4565
4687
  item,
4566
4688
  role,
4567
4689
  customComponents,
4568
- message: message2,
4690
+ message: message3,
4569
4691
  messageIndex = -1
4570
4692
  }) => {
4571
4693
  const { surfaceIdsByMessageIndex } = useA2uiRuntimeView();
4572
4694
  const rawContent = toA2uiDisplayText(role, item?.messageContent);
4573
4695
  const segments = splitA2uiTextSegments(rawContent);
4696
+ const markdownComponents = {
4697
+ [RESOURCE_MARKDOWN_TAG]: MessageResourceTag,
4698
+ ...customComponents
4699
+ };
4574
4700
  const visibleSurfaceIds = messageIndex >= 0 ? new Set(surfaceIdsByMessageIndex[messageIndex] || []) : null;
4575
4701
  const firstSeg = segments[0];
4576
4702
  const isPureText = segments.length === 0 || segments.length === 1 && firstSeg.type === "text";
@@ -4579,16 +4705,18 @@ var TextNode2 = React10__namespace.default.memo(
4579
4705
  if (typeof content === "string" && content.startsWith("Question:")) {
4580
4706
  return /* @__PURE__ */ jsxRuntime.jsx(QuestionSummary, { content });
4581
4707
  }
4708
+ const markdownContent = typeof content === "string" ? transformResourceText(content) : content;
4582
4709
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
4583
4710
  !!item.reasoningContent && /* @__PURE__ */ jsxRuntime.jsx(xV2.Think, { title: "\u6DF1\u5EA6\u601D\u8003", children: item.reasoningContent }),
4584
- !!content && /* @__PURE__ */ jsxRuntime.jsx(XMarkdown_default, { message: message2, components: customComponents, content })
4711
+ !!markdownContent && /* @__PURE__ */ jsxRuntime.jsx(XMarkdown_default, { message: message3, components: markdownComponents, content: markdownContent })
4585
4712
  ] });
4586
4713
  }
4587
4714
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
4588
4715
  !!item.reasoningContent && /* @__PURE__ */ jsxRuntime.jsx(xV2.Think, { title: "\u6DF1\u5EA6\u601D\u8003", children: item.reasoningContent }),
4589
4716
  segments.map((seg, i) => {
4590
4717
  if (seg.type === "text") {
4591
- return seg.content.trim() ? /* @__PURE__ */ jsxRuntime.jsx(XMarkdown_default, { message: message2, components: customComponents, content: seg.content }, `text-${i}`) : null;
4718
+ const markdownContent = transformResourceText(seg.content);
4719
+ return seg.content.trim() ? /* @__PURE__ */ jsxRuntime.jsx(XMarkdown_default, { message: message3, components: markdownComponents, content: markdownContent }, `text-${i}`) : null;
4592
4720
  }
4593
4721
  return seg.surfaceIds.filter((sid) => !visibleSurfaceIds || visibleSurfaceIds.has(sid)).map((sid) => /* @__PURE__ */ jsxRuntime.jsx(XCard.Card, { id: sid }, `a2ui-${i}-${sid}`));
4594
4722
  })
@@ -4807,9 +4935,9 @@ var ToolCallItem = ({ item }) => {
4807
4935
  };
4808
4936
  var tool_call_item_default = ToolCallItem;
4809
4937
  var RENDERABLE_MESSAGE_TYPES = ["runStarted", "toolCall", "toolResult", "text", "stepError", "files", "plan"];
4810
- var MessageRender_default = React10__namespace.default.memo(({ role, message: message2, messageIndex = -1, loading, containerRef, customComponents }) => {
4938
+ var MessageRender_default = React10__namespace.default.memo(({ role, message: message3, messageIndex = -1, loading, containerRef, customComponents }) => {
4811
4939
  const content = React10.useMemo(() => {
4812
- return (message2.content || []).filter((item) => {
4940
+ return (message3.content || []).filter((item) => {
4813
4941
  if (!RENDERABLE_MESSAGE_TYPES.includes(item.type)) {
4814
4942
  return false;
4815
4943
  }
@@ -4827,12 +4955,12 @@ var MessageRender_default = React10__namespace.default.memo(({ role, message: me
4827
4955
  }
4828
4956
  return true;
4829
4957
  });
4830
- }, [loading, message2.content]);
4958
+ }, [loading, message3.content]);
4831
4959
  const quoteMsg = React10.useMemo(() => {
4832
4960
  const quoteMsg2 = {};
4833
- if (message2.params) {
4961
+ if (message3.params) {
4834
4962
  try {
4835
- const citation = JSON.parse(message2.params).citation;
4963
+ const citation = JSON.parse(message3.params).citation;
4836
4964
  if (citation) {
4837
4965
  quoteMsg2.messageContent = citation;
4838
4966
  }
@@ -4840,7 +4968,7 @@ var MessageRender_default = React10__namespace.default.memo(({ role, message: me
4840
4968
  }
4841
4969
  }
4842
4970
  return common.isEmptyObj(quoteMsg2) ? null : quoteMsg2;
4843
- }, [message2.params, message2.quoteMsg]);
4971
+ }, [message3.params, message3.quoteMsg]);
4844
4972
  if (content.length === 0) return null;
4845
4973
  return /* @__PURE__ */ jsxRuntime.jsxs(antd.Flex, { ref: containerRef, vertical: true, gap: 8, children: [
4846
4974
  content.map((item, index) => {
@@ -4853,8 +4981,8 @@ var MessageRender_default = React10__namespace.default.memo(({ role, message: me
4853
4981
  content: /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
4854
4982
  item.type === "runStarted" && /* @__PURE__ */ jsxRuntime.jsx(RunStartedNode, { loading }, `flow-start-${index}`),
4855
4983
  (item.type === "toolCall" || item.type === "toolResult") && /* @__PURE__ */ jsxRuntime.jsx(tool_call_item_default, { item }, `tool-call-${item.toolCallId || index}`),
4856
- item.type === "text" && /* @__PURE__ */ jsxRuntime.jsx(TextNode2, { item, role: message2.role, customComponents, message: message2, messageIndex }, `message-${index}`),
4857
- item.type === "stepError" && (item.errorMessage ? /* @__PURE__ */ jsxRuntime.jsx(XMarkdown_default, { message: message2, components: customComponents, content: item.errorMessage }) : null),
4984
+ item.type === "text" && /* @__PURE__ */ jsxRuntime.jsx(TextNode2, { item, role: message3.role, customComponents, message: message3, messageIndex }, `message-${index}`),
4985
+ item.type === "stepError" && (item.errorMessage ? /* @__PURE__ */ jsxRuntime.jsx(XMarkdown_default, { message: message3, components: customComponents, content: item.errorMessage }) : null),
4858
4986
  item.type === "files" && /* @__PURE__ */ jsxRuntime.jsx(FilesNode, { item }, `files-${index}`),
4859
4987
  item.type === "plan" && /* @__PURE__ */ jsxRuntime.jsx(A2uiPlanNode, { item }, `plan-${index}`)
4860
4988
  ] })
@@ -4863,7 +4991,7 @@ var MessageRender_default = React10__namespace.default.memo(({ role, message: me
4863
4991
  );
4864
4992
  }),
4865
4993
  quoteMsg && /* @__PURE__ */ jsxRuntime.jsx(QuoteMsgNode, { quoteMsg, role }),
4866
- messageIndex >= 0 ? /* @__PURE__ */ jsxRuntime.jsx(A2uiMessageCards, { messageIndex, message: message2 }) : null
4994
+ messageIndex >= 0 ? /* @__PURE__ */ jsxRuntime.jsx(A2uiMessageCards, { messageIndex, message: message3 }) : null
4867
4995
  ] });
4868
4996
  });
4869
4997
  var WelcomeItem_default = ({ icon = true, title = true, description = true, prompts = true }) => {
@@ -4956,13 +5084,13 @@ var BubbleListItems_default = ({
4956
5084
  const messageRefs = React10.useRef({});
4957
5085
  const chatRecords = React10.useMemo(() => {
4958
5086
  const chatRecords2 = [];
4959
- conversationMessages.forEach((message2, messageIndex) => {
4960
- const role = getRole(message2.role);
5087
+ conversationMessages.forEach((message3, messageIndex) => {
5088
+ const role = getRole(message3.role);
4961
5089
  const isLeftBubble = role.user === "agent";
4962
- const isMessageLoading = !!message2.generating;
4963
- const baseKey = `${message2.executionId}-${messageIndex}`;
5090
+ const isMessageLoading = !!message3.generating;
5091
+ const baseKey = `${message3.executionId}-${messageIndex}`;
4964
5092
  const footerNode = !isMessageLoading ? /* @__PURE__ */ jsxRuntime.jsxs(antd.Flex, { align: "center", gap: 8, children: [
4965
- message2.stopFlag && isLeftBubble && /* @__PURE__ */ jsxRuntime.jsx(Text3, { type: "secondary", style: { flex: "none" }, children: "\u5DF2\u505C\u6B62" }),
5093
+ message3.stopFlag && isLeftBubble && /* @__PURE__ */ jsxRuntime.jsx(Text3, { type: "secondary", style: { flex: "none" }, children: "\u5DF2\u505C\u6B62" }),
4966
5094
  /* @__PURE__ */ jsxRuntime.jsx(antd.Flex, { align: "center", gap: 4, children: role.user === "agent" && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
4967
5095
  /* @__PURE__ */ jsxRuntime.jsx(
4968
5096
  antd.Button,
@@ -4982,21 +5110,21 @@ var BubbleListItems_default = ({
4982
5110
  /* @__PURE__ */ jsxRuntime.jsx(
4983
5111
  antd.Button,
4984
5112
  {
4985
- color: message2.feedback === 1 ? "primary" : "default",
5113
+ color: message3.feedback === 1 ? "primary" : "default",
4986
5114
  size: "small",
4987
5115
  variant: "text",
4988
5116
  icon: /* @__PURE__ */ jsxRuntime.jsx(icons.LikeOutlined, {}),
4989
- onClick: () => chatStore.feedback(message2.executionId, 1, messageIndex)
5117
+ onClick: () => chatStore.feedback(message3.executionId, 1, messageIndex)
4990
5118
  }
4991
5119
  ),
4992
5120
  /* @__PURE__ */ jsxRuntime.jsx(
4993
5121
  antd.Button,
4994
5122
  {
4995
- color: message2.feedback === 2 ? "primary" : "default",
5123
+ color: message3.feedback === 2 ? "primary" : "default",
4996
5124
  size: "small",
4997
5125
  variant: "text",
4998
5126
  icon: /* @__PURE__ */ jsxRuntime.jsx(icons.DislikeOutlined, {}),
4999
- onClick: () => chatStore.feedback(message2.executionId, 2, messageIndex)
5127
+ onClick: () => chatStore.feedback(message3.executionId, 2, messageIndex)
5000
5128
  }
5001
5129
  ),
5002
5130
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -5004,7 +5132,7 @@ var BubbleListItems_default = ({
5004
5132
  {
5005
5133
  control: agentActions,
5006
5134
  ctx: {
5007
- message: message2,
5135
+ message: message3,
5008
5136
  get dom() {
5009
5137
  return messageRefs.current[baseKey];
5010
5138
  }
@@ -5022,7 +5150,7 @@ var BubbleListItems_default = ({
5022
5150
  MessageRender_default,
5023
5151
  {
5024
5152
  role,
5025
- message: message2,
5153
+ message: message3,
5026
5154
  messageIndex,
5027
5155
  customComponents,
5028
5156
  loading: isMessageLoading,
@@ -5601,6 +5729,313 @@ var ChatSenderHeader = () => {
5601
5729
  ] });
5602
5730
  };
5603
5731
  var ChatSenderHeader_default = ChatSenderHeader;
5732
+ var MonacoEditor = ({ value = "", onChange, placeholder, height = 200, readOnly = false, style }) => {
5733
+ const handleKeyDownCapture = React10.useCallback((e) => {
5734
+ if (e.key === " " || e.code === "Space") {
5735
+ e.stopPropagation();
5736
+ }
5737
+ }, []);
5738
+ const handleKeyUpCapture = React10.useCallback((e) => {
5739
+ if (e.key === " " || e.code === "Space") {
5740
+ e.stopPropagation();
5741
+ }
5742
+ }, []);
5743
+ const handleScriptChange = React10.useCallback(
5744
+ (event) => {
5745
+ onChange?.(event.target.value || "");
5746
+ },
5747
+ [onChange]
5748
+ );
5749
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { style, onKeyDownCapture: handleKeyDownCapture, onKeyUpCapture: handleKeyUpCapture, children: /* @__PURE__ */ jsxRuntime.jsx(
5750
+ antd.Input.TextArea,
5751
+ {
5752
+ value,
5753
+ onChange: handleScriptChange,
5754
+ readOnly,
5755
+ placeholder,
5756
+ autoSize: false,
5757
+ style: {
5758
+ height,
5759
+ resize: "vertical",
5760
+ fontFamily: 'Monaco, Menlo, Consolas, "Courier New", monospace',
5761
+ ...style
5762
+ }
5763
+ }
5764
+ ) });
5765
+ };
5766
+ var MonacoEditor_default = MonacoEditor;
5767
+ var { Text: Text8 } = antd.Typography;
5768
+ var FormFileUpload = ({ value, onChange, multiple = false }) => {
5769
+ const { token } = antd.theme.useToken();
5770
+ const fileList = Array.isArray(value) ? value : value ? [value] : [];
5771
+ const chatStore = useChatStore();
5772
+ const conversationState = valtio.useSnapshot(chatStore.conversation);
5773
+ const agentState = valtio.useSnapshot(chatStore.agent);
5774
+ const configState = valtio.useSnapshot(chatStore.config);
5775
+ const customRequest = async (options) => {
5776
+ const { file, onSuccess, onError } = options;
5777
+ try {
5778
+ const formData = new FormData();
5779
+ formData.append("file", file);
5780
+ const params = {
5781
+ workspaceType: "conversation" /* CONVERSATION */,
5782
+ agentId: agentState.agentInfo.id,
5783
+ workspaceId: conversationState.active.id
5784
+ };
5785
+ const res = await configState.services.request.chatUpload(params, formData);
5786
+ if (res.code === 200 && res.data?.length) {
5787
+ const uploadedFile = res.data[0];
5788
+ onSuccess(uploadedFile);
5789
+ if (multiple) {
5790
+ onChange?.([...fileList, uploadedFile]);
5791
+ } else {
5792
+ onChange?.([uploadedFile]);
5793
+ }
5794
+ } else {
5795
+ antd.message.error(res.message || "\u4E0A\u4F20\u5931\u8D25");
5796
+ onError(new Error(res.message));
5797
+ }
5798
+ } catch (error) {
5799
+ onError(error);
5800
+ }
5801
+ };
5802
+ const handleRemove = (fileToRemove) => {
5803
+ const newList = fileList.filter((f) => f.id !== fileToRemove.id);
5804
+ onChange?.(newList.length > 0 ? newList : void 0);
5805
+ };
5806
+ return /* @__PURE__ */ jsxRuntime.jsxs(antd.Flex, { vertical: true, gap: 12, style: { width: "100%" }, children: [
5807
+ !multiple && fileList.length >= 1 ? null : /* @__PURE__ */ jsxRuntime.jsx(antd.Upload, { multiple, customRequest, showUploadList: false, children: /* @__PURE__ */ jsxRuntime.jsx(antd.Button, { icon: /* @__PURE__ */ jsxRuntime.jsx(icons.CloudUploadOutlined, {}), children: "\u4ECE\u672C\u5730\u4E0A\u4F20" }) }),
5808
+ fileList.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(antd.Flex, { vertical: true, gap: 8, children: fileList.map((file) => /* @__PURE__ */ jsxRuntime.jsxs(
5809
+ antd.Flex,
5810
+ {
5811
+ align: "center",
5812
+ justify: "space-between",
5813
+ style: {
5814
+ padding: "8px 12px",
5815
+ backgroundColor: token.colorFillAlter,
5816
+ borderRadius: token.borderRadiusLG || 8,
5817
+ border: `1px solid ${token.colorBorderSecondary}`
5818
+ },
5819
+ children: [
5820
+ /* @__PURE__ */ jsxRuntime.jsxs(antd.Flex, { align: "center", gap: 12, style: { overflow: "hidden", flex: 1 }, children: [
5821
+ /* @__PURE__ */ jsxRuntime.jsx(
5822
+ "div",
5823
+ {
5824
+ style: {
5825
+ width: 40,
5826
+ height: 40,
5827
+ backgroundColor: "#000",
5828
+ borderRadius: token.borderRadiusSM || 4,
5829
+ display: "flex",
5830
+ alignItems: "center",
5831
+ justifyContent: "center",
5832
+ flexShrink: 0
5833
+ },
5834
+ children: getFileIcon(file.extension || common.getFileSuffixName(file.name), 20)
5835
+ }
5836
+ ),
5837
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { overflow: "hidden", display: "flex", flexDirection: "column", flex: 1 }, children: [
5838
+ /* @__PURE__ */ jsxRuntime.jsx(Text8, { ellipsis: true, style: { width: "100%", fontSize: 14, fontWeight: 500 }, children: file.name }),
5839
+ /* @__PURE__ */ jsxRuntime.jsxs(Text8, { type: "secondary", style: { fontSize: 12 }, children: [
5840
+ (file.extension || common.getFileSuffixName(file.name)).toUpperCase(),
5841
+ " \u2022 ",
5842
+ formatFileSize(file.size)
5843
+ ] })
5844
+ ] })
5845
+ ] }),
5846
+ /* @__PURE__ */ jsxRuntime.jsx(antd.Button, { type: "text", icon: /* @__PURE__ */ jsxRuntime.jsx(icons.DeleteOutlined, {}), onClick: () => handleRemove(file), style: { color: token.colorTextSecondary } })
5847
+ ]
5848
+ },
5849
+ file.id || file.uid
5850
+ )) })
5851
+ ] });
5852
+ };
5853
+ var FormMonacoEditor = ({ value, onChange }) => {
5854
+ const { token } = antd.theme.useToken();
5855
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { style: { backgroundColor: token.colorFillAlter, padding: 8, borderRadius: token.borderRadius }, children: /* @__PURE__ */ jsxRuntime.jsx(MonacoEditor_default, { language: "json", placeholder: "\u8BF7\u8F93\u5165\u503C...", height: 80, value, onChange }) });
5856
+ };
5857
+ var UserInputPanel = () => {
5858
+ const chatStore = useChatStore();
5859
+ const agentState = valtio.useSnapshot(chatStore.agent);
5860
+ const [form] = antd.Form.useForm();
5861
+ const [activeKey, setActiveKey] = React10.useState(["1"]);
5862
+ const inputs = React10.useMemo(() => {
5863
+ if (agentState.agentInfo.userInput?.length > 0) {
5864
+ return agentState.agentInfo.userInput;
5865
+ }
5866
+ }, [agentState.agentInfo.userInput]);
5867
+ React10.useEffect(() => {
5868
+ if (inputs.length > 0) {
5869
+ const initialValues = inputs.reduce((acc, cur) => {
5870
+ let value = cur.value;
5871
+ acc[cur.name] = value;
5872
+ return acc;
5873
+ }, {});
5874
+ form.setFieldsValue(initialValues);
5875
+ }
5876
+ }, [inputs, form]);
5877
+ const handleValuesChange = (changedValues) => {
5878
+ if (agentState.agentInfo.userInput?.length > 0) {
5879
+ const newInput = agentState.agentInfo.userInput.map((v) => {
5880
+ if (v.name in changedValues) {
5881
+ const newValue = changedValues[v.name];
5882
+ return { ...v, value: newValue };
5883
+ }
5884
+ return v;
5885
+ });
5886
+ chatStore.setConversationUserInput(newInput);
5887
+ return;
5888
+ }
5889
+ };
5890
+ const handleStartChat = () => {
5891
+ form.validateFields().then(() => {
5892
+ setActiveKey([]);
5893
+ }).catch(() => {
5894
+ antd.message.error("\u8BF7\u68C0\u67E5\u8F93\u5165\u53C2\u6570");
5895
+ });
5896
+ };
5897
+ const renderFormItem = (item) => {
5898
+ const itemStyle = { marginBottom: 0 };
5899
+ const commonProps = {
5900
+ label: item.name,
5901
+ name: item.name,
5902
+ style: itemStyle,
5903
+ rules: item.rules?.map((r) => {
5904
+ const valStr = String(r.value || "");
5905
+ if (r.type === "required") return { required: true, message: r.message };
5906
+ if (r.type === "email") return { type: "email", message: r.message };
5907
+ if (r.type === "pattern") return { pattern: new RegExp(valStr), message: r.message };
5908
+ if (r.type === "max" || r.type === "min") {
5909
+ return {
5910
+ validator: (_, val) => {
5911
+ if (val === void 0 || val === null || val === "") return Promise.resolve();
5912
+ const numVal = Number(val);
5913
+ if (isNaN(numVal)) return Promise.resolve();
5914
+ if (r.type === "max" && numVal > Number(valStr)) return Promise.reject(new Error(r.message));
5915
+ if (r.type === "min" && numVal < Number(valStr)) return Promise.reject(new Error(r.message));
5916
+ return Promise.resolve();
5917
+ }
5918
+ };
5919
+ }
5920
+ if (r.type === "length") {
5921
+ const [min, max] = valStr.split(",").map((v) => v ? Number(v) : void 0);
5922
+ return {
5923
+ validator: (_, val) => {
5924
+ if (val === void 0 || val === null || val === "") return Promise.resolve();
5925
+ const strVal = String(val);
5926
+ if (min !== void 0 && strVal.length < min) return Promise.reject(new Error(r.message));
5927
+ if (max !== void 0 && strVal.length > max) return Promise.reject(new Error(r.message));
5928
+ return Promise.resolve();
5929
+ }
5930
+ };
5931
+ }
5932
+ if (r.type === "size") {
5933
+ const [min, max] = valStr.split(",").map((v) => v ? Number(v) : void 0);
5934
+ return {
5935
+ validator: (_, val) => {
5936
+ if (val === void 0 || val === null || val === "") return Promise.resolve();
5937
+ let len = 0;
5938
+ if (Array.isArray(val)) {
5939
+ len = val.length;
5940
+ } else if (typeof val === "string") {
5941
+ try {
5942
+ const parsed = JSON.parse(val);
5943
+ if (Array.isArray(parsed)) len = parsed.length;
5944
+ else return Promise.resolve();
5945
+ } catch (e) {
5946
+ return Promise.resolve();
5947
+ }
5948
+ } else {
5949
+ return Promise.resolve();
5950
+ }
5951
+ if (min !== void 0 && len < min) return Promise.reject(new Error(r.message));
5952
+ if (max !== void 0 && len > max) return Promise.reject(new Error(r.message));
5953
+ return Promise.resolve();
5954
+ }
5955
+ };
5956
+ }
5957
+ if (r.type === "enum") {
5958
+ const options = valStr.split(",").map((s) => s.trim());
5959
+ return {
5960
+ validator: (_, val) => {
5961
+ if (val === void 0 || val === null || val === "") return Promise.resolve();
5962
+ if (options.includes(String(val))) return Promise.resolve();
5963
+ return Promise.reject(new Error(r.message));
5964
+ }
5965
+ };
5966
+ }
5967
+ return {};
5968
+ })
5969
+ };
5970
+ if (["STRING", "LONG"].includes(item.type)) {
5971
+ return /* @__PURE__ */ jsxRuntime.jsx(antd.Form.Item, { ...commonProps, children: /* @__PURE__ */ jsxRuntime.jsx(antd.Input, { placeholder: "\u8BF7\u8F93\u5165\u503C" }) });
5972
+ }
5973
+ if (["NUMBER"].includes(item.type)) {
5974
+ return /* @__PURE__ */ jsxRuntime.jsx(antd.Form.Item, { ...commonProps, children: /* @__PURE__ */ jsxRuntime.jsx(antd.InputNumber, { style: { width: "100%" }, placeholder: "\u8BF7\u8F93\u5165\u6570\u503C" }) });
5975
+ }
5976
+ if (item.type === "BOOLEAN") {
5977
+ return /* @__PURE__ */ jsxRuntime.jsx(antd.Form.Item, { style: itemStyle, name: item.name, valuePropName: "checked", children: /* @__PURE__ */ jsxRuntime.jsxs(antd.Flex, { justify: "space-between", align: "center", children: [
5978
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: item.name }),
5979
+ /* @__PURE__ */ jsxRuntime.jsx(antd.Switch, { size: "small" })
5980
+ ] }) });
5981
+ }
5982
+ if (item.type === "FILE") {
5983
+ return /* @__PURE__ */ jsxRuntime.jsx(antd.Form.Item, { ...commonProps, children: /* @__PURE__ */ jsxRuntime.jsx(FormFileUpload, { multiple: false }) });
5984
+ }
5985
+ if (item.type === "ARRAY_FILE") {
5986
+ return /* @__PURE__ */ jsxRuntime.jsx(antd.Form.Item, { ...commonProps, children: /* @__PURE__ */ jsxRuntime.jsx(FormFileUpload, { multiple: true }) });
5987
+ }
5988
+ if (["OBJECT", "ARRAY", "ARRAY_STRING", "ARRAY_NUMBER", "ARRAY_DECIMAL", "ARRAY_BOOLEAN", "ARRAY_OBJECT"].includes(item.type)) {
5989
+ return /* @__PURE__ */ jsxRuntime.jsx(antd.Form.Item, { ...commonProps, children: /* @__PURE__ */ jsxRuntime.jsx(FormMonacoEditor, {}) });
5990
+ }
5991
+ return /* @__PURE__ */ jsxRuntime.jsx(antd.Form.Item, { ...commonProps, children: /* @__PURE__ */ jsxRuntime.jsx(antd.Input, { placeholder: "\u8BF7\u8F93\u5165\u503C" }) });
5992
+ };
5993
+ const genExtra = () => {
5994
+ if (activeKey.includes("1")) return null;
5995
+ return /* @__PURE__ */ jsxRuntime.jsx(
5996
+ antd.Button,
5997
+ {
5998
+ type: "text",
5999
+ size: "small",
6000
+ onClick: (e) => {
6001
+ e.stopPropagation();
6002
+ setActiveKey(["1"]);
6003
+ },
6004
+ children: "\u7F16\u8F91"
6005
+ }
6006
+ );
6007
+ };
6008
+ const items = [
6009
+ {
6010
+ key: "1",
6011
+ label: "\u53C2\u6570\u8BBE\u7F6E",
6012
+ extra: genExtra(),
6013
+ children: /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
6014
+ /* @__PURE__ */ jsxRuntime.jsx(antd.Form, { form, layout: "vertical", onValuesChange: handleValuesChange, style: { maxHeight: 500, overflow: "auto", paddingRight: 16 }, children: inputs.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(antd.Flex, { vertical: true, gap: 12, children: inputs.map((item) => /* @__PURE__ */ jsxRuntime.jsx(React10__namespace.default.Fragment, { children: renderFormItem(item) }, item.name)) }) : /* @__PURE__ */ jsxRuntime.jsx("div", { style: { padding: "10px", color: "#999", textAlign: "center" }, children: "\u6682\u65E0\u7528\u6237\u8F93\u5165\u5B57\u6BB5" }) }),
6015
+ /* @__PURE__ */ jsxRuntime.jsx(antd.Flex, { align: "center", justify: "center", className: "m-t-16", children: /* @__PURE__ */ jsxRuntime.jsx(antd.Button, { type: "primary", onClick: handleStartChat, children: "\u5F00\u59CB\u4F1A\u8BDD" }) })
6016
+ ] })
6017
+ }
6018
+ ];
6019
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: styles_module_default2.userInputCollapse, children: /* @__PURE__ */ jsxRuntime.jsx(
6020
+ antd.Collapse,
6021
+ {
6022
+ activeKey,
6023
+ onChange: (keys) => {
6024
+ const newKeys = typeof keys === "string" ? [keys] : keys;
6025
+ setActiveKey(newKeys);
6026
+ },
6027
+ items,
6028
+ className: "m-16",
6029
+ styles: {
6030
+ body: {
6031
+ paddingRight: 0,
6032
+ paddingBottom: 10
6033
+ }
6034
+ }
6035
+ }
6036
+ ) });
6037
+ };
6038
+ var UserInputPanel_default = UserInputPanel;
5604
6039
 
5605
6040
  // src/ui/layouts/components/styles.module.less
5606
6041
  var styles_module_default5 = {
@@ -5625,9 +6060,11 @@ var ChatMainPanel = React10.memo(
5625
6060
  []
5626
6061
  );
5627
6062
  const configState = valtio.useSnapshot(chatStore.config);
6063
+ const agentState = valtio.useSnapshot(chatStore.agent);
5628
6064
  return /* @__PURE__ */ jsxRuntime.jsxs(antd.Flex, { vertical: true, className: classNames2__default.default("height-full"), children: [
5629
6065
  /* @__PURE__ */ jsxRuntime.jsx(common.RenderWrapper, { control: configState.layout.chatHeader, DefaultComponent: ChatHeader_default }),
5630
6066
  /* @__PURE__ */ jsxRuntime.jsxs(antd.Flex, { align: "center", vertical: true, gap: 24, className: classNames2__default.default("height-full", styles_module_default5.bodyWidth), children: [
6067
+ common.shouldRender(agentState.agentInfo.userInput && agentState.agentInfo.userInput.length > 0) && /* @__PURE__ */ jsxRuntime.jsx(common.RenderWrapper, { control: configState.layout.userInput, DefaultComponent: UserInputPanel_default }),
5631
6068
  common.shouldRender(configState.layout.messageList) && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "full-scroll", style: { width: "100%" }, children: /* @__PURE__ */ jsxRuntime.jsx(common.RenderWrapper, { control: configState.layout.messageList, DefaultComponent: BubbleListItems_default }) }),
5632
6069
  /* @__PURE__ */ jsxRuntime.jsx(common.RenderWrapper, { control: configState.layout.senderHeader, DefaultComponent: /* @__PURE__ */ jsxRuntime.jsx(ChatSenderHeader_default, {}) }),
5633
6070
  /* @__PURE__ */ jsxRuntime.jsxs(antd.Flex, { className: styles_module_default5.inputContainer, vertical: true, gap: 8, children: [
@@ -5706,7 +6143,7 @@ var index_module_default3 = {
5706
6143
  animatedSplitter: "index_module_animatedSplitter",
5707
6144
  hideSplitterBar: "index_module_hideSplitterBar"
5708
6145
  };
5709
- var layouts_default = React10.forwardRef(({ theme: theme4, params, hooks, layout, config, services }, _ref) => {
6146
+ var layouts_default = React10.forwardRef(({ theme: theme5, params, hooks, layout, config, services }, _ref) => {
5710
6147
  const chatStore = React10.useMemo(() => createChatStore(), []);
5711
6148
  const senderRef = React10.useRef(null);
5712
6149
  React10.useImperativeHandle(
@@ -5753,6 +6190,11 @@ var layouts_default = React10.forwardRef(({ theme: theme4, params, hooks, layout
5753
6190
  chatStore.setAgent({ ...agentState.agentInfo, config: config.agent.config || {} });
5754
6191
  }
5755
6192
  }, [agentState.agentInfo.id, config.agent?.config]);
6193
+ common.useDeepEffect(() => {
6194
+ if (agentState.agentInfo.id) {
6195
+ chatStore.setUserInput(config.agent.userInput);
6196
+ }
6197
+ }, [agentState.agentInfo.id, config.agent?.userInput]);
5756
6198
  common.useDeepEffect(() => {
5757
6199
  if (config?.agent?.id) {
5758
6200
  chatStore.getAgentInfo(config.agent.id);
@@ -5779,20 +6221,20 @@ var layouts_default = React10.forwardRef(({ theme: theme4, params, hooks, layout
5779
6221
  }, [hasPreView]);
5780
6222
  common.useWebSocket({
5781
6223
  url: configState.services.websocketUrls?.[0],
5782
- onMessage: (message2) => chatStore.acceptMessage(message2.payload),
6224
+ onMessage: (message3) => chatStore.acceptMessage(message3.payload),
5783
6225
  clientHeartbeat: false,
5784
6226
  reconnectInterval: 1e4
5785
6227
  });
5786
6228
  common.useWebSocket({
5787
6229
  url: configState.services.websocketUrls?.[1],
5788
- onMessage: (message2) => chatStore.acceptMessage(message2.payload),
6230
+ onMessage: (message3) => chatStore.acceptMessage(message3.payload),
5789
6231
  clientHeartbeat: false,
5790
6232
  reconnectInterval: 1e4
5791
6233
  });
5792
6234
  React10.useEffect(() => {
5793
6235
  hooks?.onBeforeInit?.();
5794
6236
  }, []);
5795
- return /* @__PURE__ */ jsxRuntime.jsx(xV2.XProvider, { theme: { cssVar: {}, ...theme4 }, children: /* @__PURE__ */ jsxRuntime.jsx(ChatProvider, { store: chatStore, children: /* @__PURE__ */ jsxRuntime.jsx(antd.Spin, { spinning: configState.loading, classNames: { root: "full-spin" }, children: /* @__PURE__ */ jsxRuntime.jsxs(antd.Flex, { vertical: true, className: classNames2__default.default(index_module_default3.chatLayout, "zero-chat-layout", "height-full"), children: [
6237
+ return /* @__PURE__ */ jsxRuntime.jsx(xV2.XProvider, { theme: { cssVar: {}, ...theme5 }, children: /* @__PURE__ */ jsxRuntime.jsx(ChatProvider, { store: chatStore, children: /* @__PURE__ */ jsxRuntime.jsx(antd.Spin, { spinning: configState.loading, classNames: { root: "full-spin" }, children: /* @__PURE__ */ jsxRuntime.jsxs(antd.Flex, { vertical: true, className: classNames2__default.default(index_module_default3.chatLayout, "zero-chat-layout", "height-full"), children: [
5796
6238
  /* @__PURE__ */ jsxRuntime.jsx(common.RenderWrapper, { control: configState.layout.globalHeader, DefaultComponent: ChatHeader_default }),
5797
6239
  /* @__PURE__ */ jsxRuntime.jsxs(antd.Flex, { ref: containerRef, className: "full-scroll", children: [
5798
6240
  /* @__PURE__ */ jsxRuntime.jsx(common.RenderWrapper, { control: configState.layout.leftPanel }),