@ai-group/chat-sdk 3.7.1-alpha5 → 3.7.1-alpha7

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.
Files changed (61) hide show
  1. package/dist/cjs/components/XAdkChatbot/components/MarkdownRender/index.d.ts +8 -0
  2. package/dist/cjs/components/XAdkChatbot/components/MarkdownRender/index.js +66 -11
  3. package/dist/cjs/components/XAdkChatbot/components/MarkdownRender/index.js.map +2 -2
  4. package/dist/cjs/components/XAdkChatbot/components/MarkdownRender/styles.js +21 -0
  5. package/dist/cjs/components/XAdkChatbot/components/MarkdownRender/styles.js.map +2 -2
  6. package/dist/cjs/components/XAdkChatbot/index.js +29 -10
  7. package/dist/cjs/components/XAdkChatbot/index.js.map +2 -2
  8. package/dist/cjs/components/XAdkProvider/compound/DefaultLayout.d.ts +6 -2
  9. package/dist/cjs/components/XAdkProvider/compound/DefaultLayout.js +59 -15
  10. package/dist/cjs/components/XAdkProvider/compound/DefaultLayout.js.map +2 -2
  11. package/dist/cjs/components/XAdkProvider/compound/Sender.d.ts +2 -1
  12. package/dist/cjs/components/XAdkProvider/compound/Sender.js.map +2 -2
  13. package/dist/cjs/components/XAdkProvider/compound/styles.d.ts +1 -0
  14. package/dist/cjs/components/XAdkProvider/compound/styles.js +16 -0
  15. package/dist/cjs/components/XAdkProvider/compound/styles.js.map +2 -2
  16. package/dist/cjs/components/XAdkSender/InlineTagInput.js +132 -2
  17. package/dist/cjs/components/XAdkSender/InlineTagInput.js.map +2 -2
  18. package/dist/cjs/components/XAdkSender/index.js +21 -55
  19. package/dist/cjs/components/XAdkSender/index.js.map +2 -2
  20. package/dist/cjs/hooks/useADKChat.js +5 -1
  21. package/dist/cjs/hooks/useADKChat.js.map +2 -2
  22. package/dist/cjs/index.d.ts +2 -2
  23. package/dist/cjs/index.js +4 -0
  24. package/dist/cjs/index.js.map +2 -2
  25. package/dist/cjs/types/XAdkSender.d.ts +10 -3
  26. package/dist/cjs/types/XAdkSender.js.map +1 -1
  27. package/dist/cjs/utils/markdownResource.d.ts +4 -1
  28. package/dist/cjs/utils/markdownResource.js +46 -0
  29. package/dist/cjs/utils/markdownResource.js.map +2 -2
  30. package/dist/esm/components/XAdkChatbot/components/MarkdownRender/index.d.ts +8 -0
  31. package/dist/esm/components/XAdkChatbot/components/MarkdownRender/index.js +67 -11
  32. package/dist/esm/components/XAdkChatbot/components/MarkdownRender/index.js.map +1 -1
  33. package/dist/esm/components/XAdkChatbot/components/MarkdownRender/styles.js +1 -1
  34. package/dist/esm/components/XAdkChatbot/components/MarkdownRender/styles.js.map +1 -1
  35. package/dist/esm/components/XAdkChatbot/index.js +20 -2
  36. package/dist/esm/components/XAdkChatbot/index.js.map +1 -1
  37. package/dist/esm/components/XAdkProvider/compound/DefaultLayout.d.ts +6 -2
  38. package/dist/esm/components/XAdkProvider/compound/DefaultLayout.js +55 -12
  39. package/dist/esm/components/XAdkProvider/compound/DefaultLayout.js.map +1 -1
  40. package/dist/esm/components/XAdkProvider/compound/Sender.d.ts +2 -1
  41. package/dist/esm/components/XAdkProvider/compound/Sender.js +2 -1
  42. package/dist/esm/components/XAdkProvider/compound/Sender.js.map +1 -1
  43. package/dist/esm/components/XAdkProvider/compound/styles.d.ts +1 -0
  44. package/dist/esm/components/XAdkProvider/compound/styles.js +3 -2
  45. package/dist/esm/components/XAdkProvider/compound/styles.js.map +1 -1
  46. package/dist/esm/components/XAdkSender/InlineTagInput.js +154 -4
  47. package/dist/esm/components/XAdkSender/InlineTagInput.js.map +1 -1
  48. package/dist/esm/components/XAdkSender/index.js +25 -58
  49. package/dist/esm/components/XAdkSender/index.js.map +1 -1
  50. package/dist/esm/hooks/useADKChat.js +8 -2
  51. package/dist/esm/hooks/useADKChat.js.map +1 -1
  52. package/dist/esm/index.d.ts +2 -2
  53. package/dist/esm/index.js +2 -2
  54. package/dist/esm/index.js.map +1 -1
  55. package/dist/esm/types/XAdkSender.d.ts +10 -3
  56. package/dist/esm/types/XAdkSender.js.map +1 -1
  57. package/dist/esm/utils/markdownResource.d.ts +4 -1
  58. package/dist/esm/utils/markdownResource.js +59 -0
  59. package/dist/esm/utils/markdownResource.js.map +1 -1
  60. package/dist/umd/chat-sdk.min.js +1 -1
  61. package/package.json +1 -1
@@ -21,7 +21,9 @@ var markdownResource_exports = {};
21
21
  __export(markdownResource_exports, {
22
22
  MARKDOWN_RESOURCE_LINK_SCHEMES: () => MARKDOWN_RESOURCE_LINK_SCHEMES,
23
23
  formatMarkdownResourceLinksAsText: () => formatMarkdownResourceLinksAsText,
24
+ getMarkdownResourceDisplayLabel: () => getMarkdownResourceDisplayLabel,
24
25
  parseMarkdownResourceHref: () => parseMarkdownResourceHref,
26
+ parseMarkdownResourceLinksAsParts: () => parseMarkdownResourceLinksAsParts,
25
27
  replaceMarkdownResourceLinks: () => replaceMarkdownResourceLinks
26
28
  });
27
29
  module.exports = __toCommonJS(markdownResource_exports);
@@ -36,6 +38,48 @@ var MARKDOWN_RESOURCE_LINK_SCHEMES = [
36
38
  var getResourceLinkSchemeSet = (options) => new Set((options == null ? void 0 : options.schemes) || MARKDOWN_RESOURCE_LINK_SCHEMES);
37
39
  var RESOURCE_LINK_REGEX = /\[([^\]\n]+)\]\(([a-z][a-z0-9+.-]*:\/{2,3}[^)\s]+)\)/gi;
38
40
  var stripTriggerPrefix = (label) => label.replace(/^[@/#$]+/, "");
41
+ var getMarkdownResourceDisplayLabel = (label) => stripTriggerPrefix(label).trim();
42
+ var parseMarkdownResourceLinksAsParts = (text, options) => {
43
+ var _a;
44
+ if (!text)
45
+ return [];
46
+ const parts = [];
47
+ let lastIndex = 0;
48
+ let mentionIndex = 0;
49
+ const regex = new RegExp(RESOURCE_LINK_REGEX.source, RESOURCE_LINK_REGEX.flags);
50
+ let match;
51
+ while ((match = regex.exec(text)) !== null) {
52
+ const source = match[0];
53
+ const label = match[1] || "";
54
+ const href = match[2] || "";
55
+ const start = match.index ?? 0;
56
+ const link = parseMarkdownResourceHref(href, label, options);
57
+ if (!link)
58
+ continue;
59
+ if (start > lastIndex) {
60
+ parts.push({ type: "text", text: text.slice(lastIndex, start) });
61
+ }
62
+ const displayName = getMarkdownResourceDisplayLabel(link.label || link.value);
63
+ const mention = {
64
+ id: `pasted-${link.type}-${mentionIndex}-${Date.now().toString(36)}`,
65
+ label: displayName,
66
+ displayName,
67
+ type: link.type,
68
+ uri: link.href,
69
+ targetId: link.value,
70
+ value: link.value,
71
+ trigger: (_a = label.match(/^[@/#$]+/)) == null ? void 0 : _a[0],
72
+ data: { uri: link.href, value: link.value }
73
+ };
74
+ parts.push({ type: "mention", mention });
75
+ mentionIndex += 1;
76
+ lastIndex = start + source.length;
77
+ }
78
+ if (lastIndex < text.length) {
79
+ parts.push({ type: "text", text: text.slice(lastIndex) });
80
+ }
81
+ return parts.length > 0 ? parts : [{ type: "text", text }];
82
+ };
39
83
  var parseMarkdownResourceHref = (href, label = "", options) => {
40
84
  const match = href.match(/^([a-z][a-z0-9+.-]*):\/{2,3}(.+)$/i);
41
85
  if (!match)
@@ -73,7 +117,9 @@ var formatMarkdownResourceLinksAsText = (text, options) => replaceMarkdownResour
73
117
  0 && (module.exports = {
74
118
  MARKDOWN_RESOURCE_LINK_SCHEMES,
75
119
  formatMarkdownResourceLinksAsText,
120
+ getMarkdownResourceDisplayLabel,
76
121
  parseMarkdownResourceHref,
122
+ parseMarkdownResourceLinksAsParts,
77
123
  replaceMarkdownResourceLinks
78
124
  });
79
125
  //# sourceMappingURL=markdownResource.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/utils/markdownResource.ts"],
4
- "sourcesContent": ["import type { MarkdownResourceLink } from \"@/types\";\n\nexport const MARKDOWN_RESOURCE_LINK_SCHEMES = [\n \"skill\",\n \"plugin\",\n \"tool\",\n \"knowledge\",\n \"agent\",\n \"model\",\n] as const;\n\nexport type MarkdownResourceLinkScheme =\n | (typeof MARKDOWN_RESOURCE_LINK_SCHEMES)[number]\n | (string & {});\n\nexport interface MarkdownResourceLinkOptions {\n schemes?: readonly MarkdownResourceLinkScheme[];\n}\n\nconst getResourceLinkSchemeSet = (options?: MarkdownResourceLinkOptions) =>\n new Set<string>(options?.schemes || MARKDOWN_RESOURCE_LINK_SCHEMES);\n\nconst RESOURCE_LINK_REGEX =\n /\\[([^\\]\\n]+)\\]\\(([a-z][a-z0-9+.-]*:\\/{2,3}[^)\\s]+)\\)/gi;\n\nconst stripTriggerPrefix = (label: string) => label.replace(/^[@/#$]+/, \"\");\n\nexport const parseMarkdownResourceHref = (\n href: string,\n label = \"\",\n options?: MarkdownResourceLinkOptions,\n): MarkdownResourceLink | null => {\n const match = href.match(/^([a-z][a-z0-9+.-]*):\\/{2,3}(.+)$/i);\n if (!match) return null;\n\n const type = match[1].toLowerCase();\n if (!getResourceLinkSchemeSet(options).has(type)) return null;\n\n return {\n href,\n label: label || href,\n type,\n value: decodeURIComponent(match[2]),\n };\n};\n\nexport const replaceMarkdownResourceLinks = (\n text: string,\n replacer: (link: MarkdownResourceLink) => string,\n options?: MarkdownResourceLinkOptions,\n) => {\n if (!text) return \"\";\n return text.replace(\n RESOURCE_LINK_REGEX,\n (source, label: string, href: string) => {\n const link = parseMarkdownResourceHref(href, label, options);\n return link ? replacer(link) : source;\n },\n );\n};\n\nexport const formatMarkdownResourceLinksAsText = (\n text: string,\n options?: MarkdownResourceLinkOptions & { stripTrigger?: boolean },\n) =>\n replaceMarkdownResourceLinks(\n text,\n (link) => {\n const label = link.label || link.value;\n return options?.stripTrigger === false\n ? label\n : stripTriggerPrefix(label);\n },\n options,\n );\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEO,IAAM,iCAAiC;AAAA,EAC5C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAUA,IAAM,2BAA2B,CAAC,YAChC,IAAI,KAAY,mCAAS,YAAW,8BAA8B;AAEpE,IAAM,sBACJ;AAEF,IAAM,qBAAqB,CAAC,UAAkB,MAAM,QAAQ,YAAY,EAAE;AAEnE,IAAM,4BAA4B,CACvC,MACA,QAAQ,IACR,YACgC;AAChC,QAAM,QAAQ,KAAK,MAAM,oCAAoC;AAC7D,MAAI,CAAC;AAAO,WAAO;AAEnB,QAAM,OAAO,MAAM,CAAC,EAAE,YAAY;AAClC,MAAI,CAAC,yBAAyB,OAAO,EAAE,IAAI,IAAI;AAAG,WAAO;AAEzD,SAAO;AAAA,IACL;AAAA,IACA,OAAO,SAAS;AAAA,IAChB;AAAA,IACA,OAAO,mBAAmB,MAAM,CAAC,CAAC;AAAA,EACpC;AACF;AAEO,IAAM,+BAA+B,CAC1C,MACA,UACA,YACG;AACH,MAAI,CAAC;AAAM,WAAO;AAClB,SAAO,KAAK;AAAA,IACV;AAAA,IACA,CAAC,QAAQ,OAAe,SAAiB;AACvC,YAAM,OAAO,0BAA0B,MAAM,OAAO,OAAO;AAC3D,aAAO,OAAO,SAAS,IAAI,IAAI;AAAA,IACjC;AAAA,EACF;AACF;AAEO,IAAM,oCAAoC,CAC/C,MACA,YAEA;AAAA,EACE;AAAA,EACA,CAAC,SAAS;AACR,UAAM,QAAQ,KAAK,SAAS,KAAK;AACjC,YAAO,mCAAS,kBAAiB,QAC7B,QACA,mBAAmB,KAAK;AAAA,EAC9B;AAAA,EACA;AACF;",
4
+ "sourcesContent": ["import type {\n MarkdownResourceLink,\n MentionTag,\n XAdkSenderSubmitPart,\n} from \"@/types\";\n\nexport const MARKDOWN_RESOURCE_LINK_SCHEMES = [\n \"skill\",\n \"plugin\",\n \"tool\",\n \"knowledge\",\n \"agent\",\n \"model\",\n] as const;\n\nexport type MarkdownResourceLinkScheme =\n | (typeof MARKDOWN_RESOURCE_LINK_SCHEMES)[number]\n | (string & {});\n\nexport interface MarkdownResourceLinkOptions {\n schemes?: readonly MarkdownResourceLinkScheme[];\n}\n\nconst getResourceLinkSchemeSet = (options?: MarkdownResourceLinkOptions) =>\n new Set<string>(options?.schemes || MARKDOWN_RESOURCE_LINK_SCHEMES);\n\nconst RESOURCE_LINK_REGEX =\n /\\[([^\\]\\n]+)\\]\\(([a-z][a-z0-9+.-]*:\\/{2,3}[^)\\s]+)\\)/gi;\n\nconst stripTriggerPrefix = (label: string) => label.replace(/^[@/#$]+/, \"\");\n\nexport const getMarkdownResourceDisplayLabel = (label: string) =>\n stripTriggerPrefix(label).trim();\n\n/** 将包含资源链接的 Markdown 还原成 Sender 可编辑的有序片段。 */\nexport const parseMarkdownResourceLinksAsParts = (\n text: string,\n options?: MarkdownResourceLinkOptions,\n): XAdkSenderSubmitPart[] => {\n if (!text) return [];\n\n const parts: XAdkSenderSubmitPart[] = [];\n let lastIndex = 0;\n let mentionIndex = 0;\n const regex = new RegExp(RESOURCE_LINK_REGEX.source, RESOURCE_LINK_REGEX.flags);\n\n let match: RegExpExecArray | null;\n while ((match = regex.exec(text)) !== null) {\n const source = match[0];\n const label = match[1] || \"\";\n const href = match[2] || \"\";\n const start = match.index ?? 0;\n const link = parseMarkdownResourceHref(href, label, options);\n if (!link) continue;\n\n if (start > lastIndex) {\n parts.push({ type: \"text\", text: text.slice(lastIndex, start) });\n }\n\n const displayName = getMarkdownResourceDisplayLabel(link.label || link.value);\n const mention: MentionTag = {\n id: `pasted-${link.type}-${mentionIndex}-${Date.now().toString(36)}`,\n label: displayName,\n displayName,\n type: link.type,\n uri: link.href,\n targetId: link.value,\n value: link.value,\n trigger: label.match(/^[@/#$]+/)?.[0],\n data: { uri: link.href, value: link.value },\n };\n parts.push({ type: \"mention\", mention });\n mentionIndex += 1;\n lastIndex = start + source.length;\n }\n\n if (lastIndex < text.length) {\n parts.push({ type: \"text\", text: text.slice(lastIndex) });\n }\n return parts.length > 0 ? parts : [{ type: \"text\", text }];\n};\n\nexport const parseMarkdownResourceHref = (\n href: string,\n label = \"\",\n options?: MarkdownResourceLinkOptions,\n): MarkdownResourceLink | null => {\n const match = href.match(/^([a-z][a-z0-9+.-]*):\\/{2,3}(.+)$/i);\n if (!match) return null;\n\n const type = match[1].toLowerCase();\n if (!getResourceLinkSchemeSet(options).has(type)) return null;\n\n return {\n href,\n label: label || href,\n type,\n value: decodeURIComponent(match[2]),\n };\n};\n\nexport const replaceMarkdownResourceLinks = (\n text: string,\n replacer: (link: MarkdownResourceLink) => string,\n options?: MarkdownResourceLinkOptions,\n) => {\n if (!text) return \"\";\n return text.replace(\n RESOURCE_LINK_REGEX,\n (source, label: string, href: string) => {\n const link = parseMarkdownResourceHref(href, label, options);\n return link ? replacer(link) : source;\n },\n );\n};\n\nexport const formatMarkdownResourceLinksAsText = (\n text: string,\n options?: MarkdownResourceLinkOptions & { stripTrigger?: boolean },\n) =>\n replaceMarkdownResourceLinks(\n text,\n (link) => {\n const label = link.label || link.value;\n return options?.stripTrigger === false\n ? label\n : stripTriggerPrefix(label);\n },\n options,\n );\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -13,6 +13,14 @@ export interface MarkdownRenderProps {
13
13
  onResourceLinkClick?: (link: MarkdownResourceLink) => void;
14
14
  /** 自定义资源链接渲染,返回 null 时使用默认标签样式 */
15
15
  renderResourceLink?: RenderMarkdownResourceLink;
16
+ /**
17
+ * 将命中文件扩展名的裸 URL 当作纯文本展示,不升级为 FileGallery。
18
+ * 用户消息应如实展示输入文本,除资源链接等业务扩展外不做额外富化。
19
+ * 默认 false,保留 Agent 消息现有行为。
20
+ */
21
+ bareUrlAsText?: boolean;
22
+ /** 将已经丢失资源 URI 的 @name 兼容渲染成只读高亮标签。 */
23
+ highlightPlainMentions?: boolean;
16
24
  }
17
25
  declare const MarkdownRender: React.FC<MarkdownRenderProps>;
18
26
  export default MarkdownRender;
@@ -7,7 +7,7 @@ import Latex from "@ant-design/x-markdown/plugins/Latex";
7
7
  import { useStyles } from "./styles";
8
8
  import { BarsOutlined, BulbOutlined, ThunderboltOutlined, CheckCircleOutlined } from "@ant-design/icons";
9
9
  import FileGallery from "../../../FileGallery";
10
- import { parseMarkdownResourceHref, replaceMarkdownResourceLinks } from "../../../../utils/markdownResource";
10
+ import { parseMarkdownResourceHref, getMarkdownResourceDisplayLabel, replaceMarkdownResourceLinks } from "../../../../utils/markdownResource";
11
11
 
12
12
  // 支持识别的文件扩展名
13
13
  import { jsx as _jsx } from "react/jsx-runtime";
@@ -64,6 +64,13 @@ var escapeHtml = function escapeHtml(value) {
64
64
  var escapeAttr = function escapeAttr(value) {
65
65
  return escapeHtml(value).replace(/"/g, "&quot;").replace(/'/g, "&#39;");
66
66
  };
67
+ var escapeMarkdownLabel = function escapeMarkdownLabel(value) {
68
+ return value.replace(/\\/g, "\\\\").replace(/\]/g, "\\]");
69
+ };
70
+
71
+ // 使用标准 https 链接作为 Markdown AST 的内部载体,避免自定义 HTML 标签被解析器降级成纯文本。
72
+ var RESOURCE_LINK_SENTINEL = "https://xadk.local/resource";
73
+ var PLAIN_MENTION_SENTINEL = "https://xadk.local/mention";
67
74
  var CodeComponent = function CodeComponent(props) {
68
75
  var _className$match;
69
76
  var className = props.className,
@@ -121,11 +128,18 @@ var MarkdownRender = function MarkdownRender(_ref) {
121
128
  resourceLinkSchemes = _ref.resourceLinkSchemes,
122
129
  onFileClick = _ref.onFileClick,
123
130
  onResourceLinkClick = _ref.onResourceLinkClick,
124
- renderResourceLink = _ref.renderResourceLink;
131
+ renderResourceLink = _ref.renderResourceLink,
132
+ _ref$bareUrlAsText = _ref.bareUrlAsText,
133
+ bareUrlAsText = _ref$bareUrlAsText === void 0 ? false : _ref$bareUrlAsText,
134
+ _ref$highlightPlainMe = _ref.highlightPlainMentions,
135
+ highlightPlainMentions = _ref$highlightPlainMe === void 0 ? false : _ref$highlightPlainMe;
125
136
  var styles = useStyles();
126
- var markdown = replaceMarkdownResourceLinks(text, function (link) {
127
- // 非 http(s) 协议容易被 Markdown 引擎清洗成普通文本,先转为内部自定义标签再交给 XMarkdown。
128
- return "<resource-link href=\"".concat(escapeAttr(link.href), "\" label=\"").concat(escapeAttr(link.label), "\" type=\"").concat(escapeAttr(link.type), "\" value=\"").concat(escapeAttr(link.value), "\">").concat(escapeHtml(link.label), "</resource-link>");
137
+ var displayText = highlightPlainMentions ? text.replace(/(^|[^\[a-z0-9_])@([a-z0-9][a-z0-9._-]*)/gi, function (_source, prefix, label) {
138
+ return "".concat(prefix, "[").concat(escapeMarkdownLabel(label), "](").concat(PLAIN_MENTION_SENTINEL, "?label=").concat(encodeURIComponent(label), ")");
139
+ }) : text;
140
+ var markdown = replaceMarkdownResourceLinks(displayText, function (link) {
141
+ // 非 http(s) 协议会被 Markdown 引擎清洗,先编码到内部标准链接中交给 a renderer 恢复。
142
+ return "[".concat(escapeMarkdownLabel(link.label), "](").concat(RESOURCE_LINK_SENTINEL, "?href=").concat(encodeURIComponent(link.href), "&label=").concat(encodeURIComponent(link.label), ")");
129
143
  }, {
130
144
  schemes: resourceLinkSchemes
131
145
  }).replaceAll(/\/\*\s*PLANNING\s*\*\//g, '<tag type="planning"></tag>').replaceAll(/\/\*\s*REPLANNING\s*\*\//g, '<tag type="replanning"></tag>').replaceAll(/\/\*\s*REASONING\s*\*\//g, '<tag type="reasoning"></tag>').replaceAll(/\/\*\s*ACTION\s*\*\//g, '<tag type="action"></tag>').replaceAll(/\/\*\s*FINAL_ANSWER\s*\*\//g, '<tag type="final_answer"></tag>');
@@ -138,6 +152,7 @@ var MarkdownRender = function MarkdownRender(_ref) {
138
152
  if (!resourceLink) return /*#__PURE__*/_jsx(_Fragment, {
139
153
  children: props.children
140
154
  });
155
+ var displayLabel = getMarkdownResourceDisplayLabel(resourceLink.label);
141
156
  var customNode = renderResourceLink === null || renderResourceLink === void 0 ? void 0 : renderResourceLink(resourceLink);
142
157
  if (customNode) return customNode;
143
158
  return /*#__PURE__*/_jsx("button", {
@@ -146,20 +161,52 @@ var MarkdownRender = function MarkdownRender(_ref) {
146
161
  onClick: function onClick() {
147
162
  return onResourceLinkClick === null || onResourceLinkClick === void 0 ? void 0 : onResourceLinkClick(resourceLink);
148
163
  },
149
- "aria-label": resourceLink.label,
150
- children: resourceLink.label
164
+ "aria-label": displayLabel,
165
+ "data-xadk-resource-link": "true",
166
+ "data-resource-markdown": "[".concat(resourceLink.label, "](").concat(resourceLink.href, ")"),
167
+ children: displayLabel
151
168
  });
152
169
  }, [onResourceLinkClick, renderResourceLink, resourceLinkSchemes, styles.resourceLink]);
170
+ var PlainMentionComponent = React.useCallback(function (props) {
171
+ var label = String(props.label || "") || extractText(props.children);
172
+ return /*#__PURE__*/_jsx("span", {
173
+ className: styles.resourceLink,
174
+ "aria-label": label,
175
+ "data-xadk-resource-link": "true",
176
+ children: label
177
+ });
178
+ }, [styles.resourceLink]);
153
179
 
154
180
  // 自定义 a 标签渲染:资源协议渲染为标签,文件链接渲染为 FileGallery,其余保持普通链接。
155
181
  var LinkComponent = React.useCallback(function (props) {
156
182
  var href = String(props.href || "");
157
183
  // 用递归提取纯文本,避免 children 是 React node 时 String() 得到 "[object Object]"
158
184
  var linkText = extractText(props.children);
159
- var resourceLink = parseMarkdownResourceHref(href, linkText, {
185
+ var resolvedHref = href;
186
+ var resolvedLabel = linkText;
187
+ try {
188
+ var internalUrl = new URL(href);
189
+ if (internalUrl.origin + internalUrl.pathname === PLAIN_MENTION_SENTINEL) {
190
+ var label = internalUrl.searchParams.get("label") || linkText;
191
+ return /*#__PURE__*/_jsx("span", {
192
+ className: styles.resourceLink,
193
+ "aria-label": label,
194
+ "data-xadk-resource-link": "true",
195
+ children: label
196
+ });
197
+ }
198
+ if (internalUrl.origin + internalUrl.pathname === RESOURCE_LINK_SENTINEL) {
199
+ resolvedHref = internalUrl.searchParams.get("href") || "";
200
+ resolvedLabel = internalUrl.searchParams.get("label") || linkText;
201
+ }
202
+ } catch (_unused) {
203
+ // 相对链接及非标准 URL 继续走原有解析逻辑。
204
+ }
205
+ var resourceLink = parseMarkdownResourceHref(resolvedHref, resolvedLabel, {
160
206
  schemes: resourceLinkSchemes
161
207
  });
162
208
  if (resourceLink) {
209
+ var displayLabel = getMarkdownResourceDisplayLabel(resourceLink.label);
163
210
  var customNode = renderResourceLink === null || renderResourceLink === void 0 ? void 0 : renderResourceLink(resourceLink);
164
211
  if (customNode) return customNode;
165
212
  return /*#__PURE__*/_jsx("button", {
@@ -168,8 +215,10 @@ var MarkdownRender = function MarkdownRender(_ref) {
168
215
  onClick: function onClick() {
169
216
  return onResourceLinkClick === null || onResourceLinkClick === void 0 ? void 0 : onResourceLinkClick(resourceLink);
170
217
  },
171
- "aria-label": resourceLink.label,
172
- children: resourceLink.label
218
+ "aria-label": displayLabel,
219
+ "data-xadk-resource-link": "true",
220
+ "data-resource-markdown": "[".concat(resourceLink.label, "](").concat(resourceLink.href, ")"),
221
+ children: displayLabel
173
222
  });
174
223
  }
175
224
 
@@ -178,6 +227,12 @@ var MarkdownRender = function MarkdownRender(_ref) {
178
227
  if (ext) {
179
228
  // href 为空说明链接还在流式截断中,不渲染,避免显示出错误文字
180
229
  if (!href) return null;
230
+ // 用户消息场景:裸 URL 不富化,直接展示为纯文本字符串
231
+ if (bareUrlAsText) {
232
+ return /*#__PURE__*/_jsx(_Fragment, {
233
+ children: linkText || href
234
+ });
235
+ }
181
236
  var mimeType = MIME_MAP[ext] || "";
182
237
  var fileItem = {
183
238
  displayName: linkText || href,
@@ -197,7 +252,7 @@ var MarkdownRender = function MarkdownRender(_ref) {
197
252
  rel: "noopener noreferrer",
198
253
  children: props.children
199
254
  });
200
- }, [onFileClick, onResourceLinkClick, renderResourceLink, resourceLinkSchemes, styles.resourceLink]);
255
+ }, [onFileClick, onResourceLinkClick, renderResourceLink, resourceLinkSchemes, styles.resourceLink, bareUrlAsText]);
201
256
  return /*#__PURE__*/_jsx("div", {
202
257
  className: "".concat(styles.markdownWrapper).concat(compact ? " ".concat(styles.markdownWrapperCompact) : ""),
203
258
  children: /*#__PURE__*/_jsx("div", {
@@ -212,6 +267,7 @@ var MarkdownRender = function MarkdownRender(_ref) {
212
267
  components: {
213
268
  tag: ThinkComponent,
214
269
  "resource-link": ResourceLinkComponent,
270
+ "plain-mention": PlainMentionComponent,
215
271
  code: CodeComponent,
216
272
  a: LinkComponent
217
273
  },
@@ -1 +1 @@
1
- {"version":3,"names":["React","XMarkdown","CodeHighlighter","Flex","Latex","useStyles","BarsOutlined","BulbOutlined","ThunderboltOutlined","CheckCircleOutlined","FileGallery","parseMarkdownResourceHref","replaceMarkdownResourceLinks","jsx","_jsx","jsxs","_jsxs","Fragment","_Fragment","FILE_EXT_REGEX","MIME_MAP","pdf","doc","docx","xls","xlsx","csv","ppt","pptx","zip","rar","txt","md","json","xml","mp3","wav","m4a","aac","ogg","flac","mp4","mov","webm","mkv","avi","png","jpg","jpeg","gif","webp","bmp","svg","extractExt","str","match","toLowerCase","escapeHtml","value","replace","escapeAttr","CodeComponent","props","_className$match","className","children","lang","ThinkComponent","memo","type","titleMap","planning","replanning","reasoning","action","final_answer","iconMap","align","gap","style","color","margin","extractText","String","Array","isArray","map","join","isValidElement","MarkdownRender","_ref","text","_ref$compact","compact","resourceLinkSchemes","onFileClick","onResourceLinkClick","renderResourceLink","styles","markdown","link","concat","href","label","schemes","replaceAll","ResourceLinkComponent","useCallback","linkText","resourceLink","customNode","onClick","LinkComponent","ext","mimeType","fileItem","displayName","fileUri","file","undefined","target","rel","markdownWrapper","markdownWrapperCompact","markdownHost","markdownHostCompact","content","paragraphTag","config","extensions","components","tag","code","a","streaming","enableAnimation","animationConfig","fadeDuration"],"sources":["../../../../../../src/components/XAdkChatbot/components/MarkdownRender/index.tsx"],"sourcesContent":["import React from \"react\";\nimport XMarkdown, { type ComponentProps } from \"@ant-design/x-markdown\";\nimport \"@ant-design/x-markdown/themes/light.css\";\nimport { CodeHighlighter } from \"@ant-design/x\";\nimport { Flex } from \"antd\";\nimport Latex from \"@ant-design/x-markdown/plugins/Latex\";\nimport { useStyles } from \"./styles\";\nimport {\n BarsOutlined,\n BulbOutlined,\n ThunderboltOutlined,\n CheckCircleOutlined,\n} from \"@ant-design/icons\";\nimport FileGallery from \"@/components/FileGallery\";\nimport type {\n FileItem,\n MarkdownResourceLink,\n RenderMarkdownResourceLink,\n} from \"@/types\";\nimport {\n parseMarkdownResourceHref,\n replaceMarkdownResourceLinks,\n} from \"@/utils/markdownResource\";\n\n// 支持识别的文件扩展名\nconst FILE_EXT_REGEX =\n /\\.(pdf|doc|docx|xls|xlsx|csv|ppt|pptx|zip|rar|7z|txt|md|json|xml|mp3|wav|m4a|aac|ogg|flac|mp4|mov|webm|mkv|avi|png|jpg|jpeg|gif|webp|bmp|svg)(\\?.*)?$/i;\n\nconst MIME_MAP: Record<string, string> = {\n pdf: \"application/pdf\",\n doc: \"application/msword\",\n docx: \"application/vnd.openxmlformats-officedocument.wordprocessingml.document\",\n xls: \"application/vnd.ms-excel\",\n xlsx: \"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\",\n csv: \"text/csv\",\n ppt: \"application/vnd.ms-powerpoint\",\n pptx: \"application/vnd.openxmlformats-officedocument.presentationml.presentation\",\n zip: \"application/zip\",\n rar: \"application/x-rar-compressed\",\n \"7z\": \"application/x-7z-compressed\",\n txt: \"text/plain\",\n md: \"text/markdown\",\n json: \"application/json\",\n xml: \"application/xml\",\n mp3: \"audio/mpeg\",\n wav: \"audio/wav\",\n m4a: \"audio/mp4\",\n aac: \"audio/aac\",\n ogg: \"audio/ogg\",\n flac: \"audio/flac\",\n mp4: \"video/mp4\",\n mov: \"video/quicktime\",\n webm: \"video/webm\",\n mkv: \"video/x-matroska\",\n avi: \"video/x-msvideo\",\n png: \"image/png\",\n jpg: \"image/jpeg\",\n jpeg: \"image/jpeg\",\n gif: \"image/gif\",\n webp: \"image/webp\",\n bmp: \"image/bmp\",\n svg: \"image/svg+xml\",\n};\n\n/**\n * 从字符串中提取文件扩展名(小写,不含点和查询参数)\n */\nconst extractExt = (str: string): string => {\n const match = str.match(FILE_EXT_REGEX);\n if (!match) return \"\";\n return match[1].toLowerCase();\n};\n\nconst escapeHtml = (value: string) =>\n value.replace(/&/g, \"&amp;\").replace(/</g, \"&lt;\").replace(/>/g, \"&gt;\");\n\nconst escapeAttr = (value: string) =>\n escapeHtml(value).replace(/\"/g, \"&quot;\").replace(/'/g, \"&#39;\");\n\nconst CodeComponent: React.FC<ComponentProps> = (props) => {\n const { className, children } = props;\n const lang = className?.match(/language-(\\S+)/)?.[1] || \"\";\n\n if (typeof children !== \"string\") return null;\n return <CodeHighlighter lang={lang}>{children}</CodeHighlighter>;\n};\n\nexport interface MarkdownRenderProps {\n text: string;\n /** 紧凑布局,适合用户消息气泡等内联场景 */\n compact?: boolean;\n /** Markdown 资源链接协议白名单,未命中的协议保持普通 Markdown 行为 */\n resourceLinkSchemes?: readonly string[];\n /** 点击 Markdown 中识别到的文件链接的回调 */\n onFileClick?: (file: FileItem) => void;\n /** 点击 Markdown 中识别到的资源链接标签,如 [@skill](skill://xxx) */\n onResourceLinkClick?: (link: MarkdownResourceLink) => void;\n /** 自定义资源链接渲染,返回 null 时使用默认标签样式 */\n renderResourceLink?: RenderMarkdownResourceLink;\n}\n\nconst ThinkComponent = React.memo((props: ComponentProps) => {\n const type = (props.type || \"\") as string;\n const titleMap: Record<string, string> = {\n planning: \"规划\",\n replanning: \"重新规划\",\n reasoning: \"推理\",\n action: \"行动\",\n final_answer: \"最终答案\",\n };\n const iconMap = {\n planning: <BarsOutlined />,\n replanning: <BarsOutlined />,\n reasoning: <BulbOutlined />,\n action: <ThunderboltOutlined />,\n final_answer: <CheckCircleOutlined />,\n };\n\n return (\n <Flex align=\"center\" gap={8} style={{ color: \"#888\", margin: \"4px 0\" }}>\n {type in titleMap && iconMap[type as keyof typeof iconMap]}\n {titleMap[type] && <span>{titleMap[type]}</span>}\n </Flex>\n );\n});\n\n/**\n * 递归从 React children 中提取纯文本\n */\nconst extractText = (children: React.ReactNode): string => {\n if (typeof children === \"string\") return children;\n if (typeof children === \"number\") return String(children);\n if (Array.isArray(children)) return children.map(extractText).join(\"\");\n if (React.isValidElement(children))\n return extractText((children.props as any).children);\n return \"\";\n};\n\nconst MarkdownRender: React.FC<MarkdownRenderProps> = ({\n text,\n compact = false,\n resourceLinkSchemes,\n onFileClick,\n onResourceLinkClick,\n renderResourceLink,\n}) => {\n const styles = useStyles();\n const markdown = replaceMarkdownResourceLinks(\n text,\n (link) => {\n // 非 http(s) 协议容易被 Markdown 引擎清洗成普通文本,先转为内部自定义标签再交给 XMarkdown。\n return `<resource-link href=\"${escapeAttr(link.href)}\" label=\"${escapeAttr(link.label)}\" type=\"${escapeAttr(link.type)}\" value=\"${escapeAttr(link.value)}\">${escapeHtml(link.label)}</resource-link>`;\n },\n { schemes: resourceLinkSchemes },\n )\n .replaceAll(/\\/\\*\\s*PLANNING\\s*\\*\\//g, '<tag type=\"planning\"></tag>')\n .replaceAll(/\\/\\*\\s*REPLANNING\\s*\\*\\//g, '<tag type=\"replanning\"></tag>')\n .replaceAll(/\\/\\*\\s*REASONING\\s*\\*\\//g, '<tag type=\"reasoning\"></tag>')\n .replaceAll(/\\/\\*\\s*ACTION\\s*\\*\\//g, '<tag type=\"action\"></tag>')\n .replaceAll(\n /\\/\\*\\s*FINAL_ANSWER\\s*\\*\\//g,\n '<tag type=\"final_answer\"></tag>',\n );\n\n const ResourceLinkComponent = React.useCallback(\n (props: ComponentProps) => {\n const href = String((props.href as string) || \"\");\n const linkText =\n String((props.label as string) || \"\") || extractText(props.children);\n const resourceLink = parseMarkdownResourceHref(href, linkText, {\n schemes: resourceLinkSchemes,\n });\n if (!resourceLink) return <>{props.children as React.ReactNode}</>;\n\n const customNode = renderResourceLink?.(resourceLink);\n if (customNode) return customNode;\n\n return (\n <button\n type=\"button\"\n className={styles.resourceLink}\n onClick={() => onResourceLinkClick?.(resourceLink)}\n aria-label={resourceLink.label}\n >\n {resourceLink.label}\n </button>\n );\n },\n [\n onResourceLinkClick,\n renderResourceLink,\n resourceLinkSchemes,\n styles.resourceLink,\n ],\n );\n\n // 自定义 a 标签渲染:资源协议渲染为标签,文件链接渲染为 FileGallery,其余保持普通链接。\n const LinkComponent = React.useCallback(\n (props: ComponentProps) => {\n const href = String((props.href as string) || \"\");\n // 用递归提取纯文本,避免 children 是 React node 时 String() 得到 \"[object Object]\"\n const linkText = extractText(props.children);\n const resourceLink = parseMarkdownResourceHref(href, linkText, {\n schemes: resourceLinkSchemes,\n });\n\n if (resourceLink) {\n const customNode = renderResourceLink?.(resourceLink);\n if (customNode) return customNode;\n\n return (\n <button\n type=\"button\"\n className={styles.resourceLink}\n onClick={() => onResourceLinkClick?.(resourceLink)}\n aria-label={resourceLink.label}\n >\n {resourceLink.label}\n </button>\n );\n }\n\n // 先识别 name(链接文字),再识别 url(href)\n const ext = extractExt(linkText) || extractExt(href);\n\n if (ext) {\n // href 为空说明链接还在流式截断中,不渲染,避免显示出错误文字\n if (!href) return null;\n const mimeType = MIME_MAP[ext] || \"\";\n const fileItem: FileItem = {\n displayName: linkText || href,\n mimeType,\n fileUri: href,\n };\n return (\n <FileGallery\n file={fileItem}\n onClick={onFileClick ? () => onFileClick(fileItem) : undefined}\n />\n );\n }\n\n return (\n <a href={href} target=\"_blank\" rel=\"noopener noreferrer\">\n {props.children as React.ReactNode}\n </a>\n );\n },\n [\n onFileClick,\n onResourceLinkClick,\n renderResourceLink,\n resourceLinkSchemes,\n styles.resourceLink,\n ],\n );\n\n return (\n <div\n className={`${styles.markdownWrapper}${compact ? ` ${styles.markdownWrapperCompact}` : \"\"}`}\n >\n <div\n className={`${styles.markdownHost}${compact ? ` ${styles.markdownHostCompact}` : \"\"}`}\n >\n <XMarkdown\n content={markdown}\n className=\"x-markdown-light\"\n paragraphTag=\"div\"\n config={{\n extensions: Latex(),\n }}\n components={{\n tag: ThinkComponent,\n \"resource-link\": ResourceLinkComponent,\n code: CodeComponent,\n a: LinkComponent,\n }}\n streaming={{\n enableAnimation: true,\n animationConfig: {\n fadeDuration: 400,\n },\n }}\n />\n </div>\n </div>\n );\n};\n\nexport default MarkdownRender;\n"],"mappings":"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"}
1
+ {"version":3,"names":["React","XMarkdown","CodeHighlighter","Flex","Latex","useStyles","BarsOutlined","BulbOutlined","ThunderboltOutlined","CheckCircleOutlined","FileGallery","parseMarkdownResourceHref","getMarkdownResourceDisplayLabel","replaceMarkdownResourceLinks","jsx","_jsx","jsxs","_jsxs","Fragment","_Fragment","FILE_EXT_REGEX","MIME_MAP","pdf","doc","docx","xls","xlsx","csv","ppt","pptx","zip","rar","txt","md","json","xml","mp3","wav","m4a","aac","ogg","flac","mp4","mov","webm","mkv","avi","png","jpg","jpeg","gif","webp","bmp","svg","extractExt","str","match","toLowerCase","escapeHtml","value","replace","escapeAttr","escapeMarkdownLabel","RESOURCE_LINK_SENTINEL","PLAIN_MENTION_SENTINEL","CodeComponent","props","_className$match","className","children","lang","ThinkComponent","memo","type","titleMap","planning","replanning","reasoning","action","final_answer","iconMap","align","gap","style","color","margin","extractText","String","Array","isArray","map","join","isValidElement","MarkdownRender","_ref","text","_ref$compact","compact","resourceLinkSchemes","onFileClick","onResourceLinkClick","renderResourceLink","_ref$bareUrlAsText","bareUrlAsText","_ref$highlightPlainMe","highlightPlainMentions","styles","displayText","_source","prefix","label","concat","encodeURIComponent","markdown","link","href","schemes","replaceAll","ResourceLinkComponent","useCallback","linkText","resourceLink","displayLabel","customNode","onClick","PlainMentionComponent","LinkComponent","resolvedHref","resolvedLabel","internalUrl","URL","origin","pathname","searchParams","get","_unused","ext","mimeType","fileItem","displayName","fileUri","file","undefined","target","rel","markdownWrapper","markdownWrapperCompact","markdownHost","markdownHostCompact","content","paragraphTag","config","extensions","components","tag","code","a","streaming","enableAnimation","animationConfig","fadeDuration"],"sources":["../../../../../../src/components/XAdkChatbot/components/MarkdownRender/index.tsx"],"sourcesContent":["import React from \"react\";\nimport XMarkdown, { type ComponentProps } from \"@ant-design/x-markdown\";\nimport \"@ant-design/x-markdown/themes/light.css\";\nimport { CodeHighlighter } from \"@ant-design/x\";\nimport { Flex } from \"antd\";\nimport Latex from \"@ant-design/x-markdown/plugins/Latex\";\nimport { useStyles } from \"./styles\";\nimport {\n BarsOutlined,\n BulbOutlined,\n ThunderboltOutlined,\n CheckCircleOutlined,\n} from \"@ant-design/icons\";\nimport FileGallery from \"@/components/FileGallery\";\nimport type {\n FileItem,\n MarkdownResourceLink,\n RenderMarkdownResourceLink,\n} from \"@/types\";\nimport {\n parseMarkdownResourceHref,\n getMarkdownResourceDisplayLabel,\n replaceMarkdownResourceLinks,\n} from \"@/utils/markdownResource\";\n\n// 支持识别的文件扩展名\nconst FILE_EXT_REGEX =\n /\\.(pdf|doc|docx|xls|xlsx|csv|ppt|pptx|zip|rar|7z|txt|md|json|xml|mp3|wav|m4a|aac|ogg|flac|mp4|mov|webm|mkv|avi|png|jpg|jpeg|gif|webp|bmp|svg)(\\?.*)?$/i;\n\nconst MIME_MAP: Record<string, string> = {\n pdf: \"application/pdf\",\n doc: \"application/msword\",\n docx: \"application/vnd.openxmlformats-officedocument.wordprocessingml.document\",\n xls: \"application/vnd.ms-excel\",\n xlsx: \"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\",\n csv: \"text/csv\",\n ppt: \"application/vnd.ms-powerpoint\",\n pptx: \"application/vnd.openxmlformats-officedocument.presentationml.presentation\",\n zip: \"application/zip\",\n rar: \"application/x-rar-compressed\",\n \"7z\": \"application/x-7z-compressed\",\n txt: \"text/plain\",\n md: \"text/markdown\",\n json: \"application/json\",\n xml: \"application/xml\",\n mp3: \"audio/mpeg\",\n wav: \"audio/wav\",\n m4a: \"audio/mp4\",\n aac: \"audio/aac\",\n ogg: \"audio/ogg\",\n flac: \"audio/flac\",\n mp4: \"video/mp4\",\n mov: \"video/quicktime\",\n webm: \"video/webm\",\n mkv: \"video/x-matroska\",\n avi: \"video/x-msvideo\",\n png: \"image/png\",\n jpg: \"image/jpeg\",\n jpeg: \"image/jpeg\",\n gif: \"image/gif\",\n webp: \"image/webp\",\n bmp: \"image/bmp\",\n svg: \"image/svg+xml\",\n};\n\n/**\n * 从字符串中提取文件扩展名(小写,不含点和查询参数)\n */\nconst extractExt = (str: string): string => {\n const match = str.match(FILE_EXT_REGEX);\n if (!match) return \"\";\n return match[1].toLowerCase();\n};\n\nconst escapeHtml = (value: string) =>\n value.replace(/&/g, \"&amp;\").replace(/</g, \"&lt;\").replace(/>/g, \"&gt;\");\n\nconst escapeAttr = (value: string) =>\n escapeHtml(value).replace(/\"/g, \"&quot;\").replace(/'/g, \"&#39;\");\n\nconst escapeMarkdownLabel = (value: string) =>\n value.replace(/\\\\/g, \"\\\\\\\\\").replace(/\\]/g, \"\\\\]\");\n\n// 使用标准 https 链接作为 Markdown AST 的内部载体,避免自定义 HTML 标签被解析器降级成纯文本。\nconst RESOURCE_LINK_SENTINEL = \"https://xadk.local/resource\";\nconst PLAIN_MENTION_SENTINEL = \"https://xadk.local/mention\";\n\nconst CodeComponent: React.FC<ComponentProps> = (props) => {\n const { className, children } = props;\n const lang = className?.match(/language-(\\S+)/)?.[1] || \"\";\n\n if (typeof children !== \"string\") return null;\n return <CodeHighlighter lang={lang}>{children}</CodeHighlighter>;\n};\n\nexport interface MarkdownRenderProps {\n text: string;\n /** 紧凑布局,适合用户消息气泡等内联场景 */\n compact?: boolean;\n /** Markdown 资源链接协议白名单,未命中的协议保持普通 Markdown 行为 */\n resourceLinkSchemes?: readonly string[];\n /** 点击 Markdown 中识别到的文件链接的回调 */\n onFileClick?: (file: FileItem) => void;\n /** 点击 Markdown 中识别到的资源链接标签,如 [@skill](skill://xxx) */\n onResourceLinkClick?: (link: MarkdownResourceLink) => void;\n /** 自定义资源链接渲染,返回 null 时使用默认标签样式 */\n renderResourceLink?: RenderMarkdownResourceLink;\n /**\n * 将命中文件扩展名的裸 URL 当作纯文本展示,不升级为 FileGallery。\n * 用户消息应如实展示输入文本,除资源链接等业务扩展外不做额外富化。\n * 默认 false,保留 Agent 消息现有行为。\n */\n bareUrlAsText?: boolean;\n /** 将已经丢失资源 URI 的 @name 兼容渲染成只读高亮标签。 */\n highlightPlainMentions?: boolean;\n}\n\nconst ThinkComponent = React.memo((props: ComponentProps) => {\n const type = (props.type || \"\") as string;\n const titleMap: Record<string, string> = {\n planning: \"规划\",\n replanning: \"重新规划\",\n reasoning: \"推理\",\n action: \"行动\",\n final_answer: \"最终答案\",\n };\n const iconMap = {\n planning: <BarsOutlined />,\n replanning: <BarsOutlined />,\n reasoning: <BulbOutlined />,\n action: <ThunderboltOutlined />,\n final_answer: <CheckCircleOutlined />,\n };\n\n return (\n <Flex align=\"center\" gap={8} style={{ color: \"#888\", margin: \"4px 0\" }}>\n {type in titleMap && iconMap[type as keyof typeof iconMap]}\n {titleMap[type] && <span>{titleMap[type]}</span>}\n </Flex>\n );\n});\n\n/**\n * 递归从 React children 中提取纯文本\n */\nconst extractText = (children: React.ReactNode): string => {\n if (typeof children === \"string\") return children;\n if (typeof children === \"number\") return String(children);\n if (Array.isArray(children)) return children.map(extractText).join(\"\");\n if (React.isValidElement(children))\n return extractText((children.props as any).children);\n return \"\";\n};\n\nconst MarkdownRender: React.FC<MarkdownRenderProps> = ({\n text,\n compact = false,\n resourceLinkSchemes,\n onFileClick,\n onResourceLinkClick,\n renderResourceLink,\n bareUrlAsText = false,\n highlightPlainMentions = false,\n}) => {\n const styles = useStyles();\n const displayText = highlightPlainMentions\n ? text.replace(\n /(^|[^\\[a-z0-9_])@([a-z0-9][a-z0-9._-]*)/gi,\n (_source, prefix: string, label: string) =>\n `${prefix}[${escapeMarkdownLabel(label)}](${PLAIN_MENTION_SENTINEL}?label=${encodeURIComponent(label)})`,\n )\n : text;\n const markdown = replaceMarkdownResourceLinks(\n displayText,\n (link) => {\n // 非 http(s) 协议会被 Markdown 引擎清洗,先编码到内部标准链接中交给 a renderer 恢复。\n return `[${escapeMarkdownLabel(link.label)}](${RESOURCE_LINK_SENTINEL}?href=${encodeURIComponent(link.href)}&label=${encodeURIComponent(link.label)})`;\n },\n { schemes: resourceLinkSchemes },\n )\n .replaceAll(/\\/\\*\\s*PLANNING\\s*\\*\\//g, '<tag type=\"planning\"></tag>')\n .replaceAll(/\\/\\*\\s*REPLANNING\\s*\\*\\//g, '<tag type=\"replanning\"></tag>')\n .replaceAll(/\\/\\*\\s*REASONING\\s*\\*\\//g, '<tag type=\"reasoning\"></tag>')\n .replaceAll(/\\/\\*\\s*ACTION\\s*\\*\\//g, '<tag type=\"action\"></tag>')\n .replaceAll(\n /\\/\\*\\s*FINAL_ANSWER\\s*\\*\\//g,\n '<tag type=\"final_answer\"></tag>',\n );\n\n const ResourceLinkComponent = React.useCallback(\n (props: ComponentProps) => {\n const href = String((props.href as string) || \"\");\n const linkText =\n String((props.label as string) || \"\") || extractText(props.children);\n const resourceLink = parseMarkdownResourceHref(href, linkText, {\n schemes: resourceLinkSchemes,\n });\n if (!resourceLink) return <>{props.children as React.ReactNode}</>;\n const displayLabel = getMarkdownResourceDisplayLabel(resourceLink.label);\n\n const customNode = renderResourceLink?.(resourceLink);\n if (customNode) return customNode;\n\n return (\n <button\n type=\"button\"\n className={styles.resourceLink}\n onClick={() => onResourceLinkClick?.(resourceLink)}\n aria-label={displayLabel}\n data-xadk-resource-link=\"true\"\n data-resource-markdown={`[${resourceLink.label}](${resourceLink.href})`}\n >\n {displayLabel}\n </button>\n );\n },\n [\n onResourceLinkClick,\n renderResourceLink,\n resourceLinkSchemes,\n styles.resourceLink,\n ],\n );\n\n const PlainMentionComponent = React.useCallback(\n (props: ComponentProps) => {\n const label = String((props.label as string) || \"\") || extractText(props.children);\n return (\n <span\n className={styles.resourceLink}\n aria-label={label}\n data-xadk-resource-link=\"true\"\n >\n {label}\n </span>\n );\n },\n [styles.resourceLink],\n );\n\n // 自定义 a 标签渲染:资源协议渲染为标签,文件链接渲染为 FileGallery,其余保持普通链接。\n const LinkComponent = React.useCallback(\n (props: ComponentProps) => {\n const href = String((props.href as string) || \"\");\n // 用递归提取纯文本,避免 children 是 React node 时 String() 得到 \"[object Object]\"\n const linkText = extractText(props.children);\n let resolvedHref = href;\n let resolvedLabel = linkText;\n try {\n const internalUrl = new URL(href);\n if (internalUrl.origin + internalUrl.pathname === PLAIN_MENTION_SENTINEL) {\n const label = internalUrl.searchParams.get(\"label\") || linkText;\n return (\n <span\n className={styles.resourceLink}\n aria-label={label}\n data-xadk-resource-link=\"true\"\n >\n {label}\n </span>\n );\n }\n if (internalUrl.origin + internalUrl.pathname === RESOURCE_LINK_SENTINEL) {\n resolvedHref = internalUrl.searchParams.get(\"href\") || \"\";\n resolvedLabel = internalUrl.searchParams.get(\"label\") || linkText;\n }\n } catch {\n // 相对链接及非标准 URL 继续走原有解析逻辑。\n }\n const resourceLink = parseMarkdownResourceHref(resolvedHref, resolvedLabel, {\n schemes: resourceLinkSchemes,\n });\n\n if (resourceLink) {\n const displayLabel = getMarkdownResourceDisplayLabel(resourceLink.label);\n const customNode = renderResourceLink?.(resourceLink);\n if (customNode) return customNode;\n\n return (\n <button\n type=\"button\"\n className={styles.resourceLink}\n onClick={() => onResourceLinkClick?.(resourceLink)}\n aria-label={displayLabel}\n data-xadk-resource-link=\"true\"\n data-resource-markdown={`[${resourceLink.label}](${resourceLink.href})`}\n >\n {displayLabel}\n </button>\n );\n }\n\n // 先识别 name(链接文字),再识别 url(href)\n const ext = extractExt(linkText) || extractExt(href);\n\n if (ext) {\n // href 为空说明链接还在流式截断中,不渲染,避免显示出错误文字\n if (!href) return null;\n // 用户消息场景:裸 URL 不富化,直接展示为纯文本字符串\n if (bareUrlAsText) {\n return <>{linkText || href}</>;\n }\n const mimeType = MIME_MAP[ext] || \"\";\n const fileItem: FileItem = {\n displayName: linkText || href,\n mimeType,\n fileUri: href,\n };\n return (\n <FileGallery\n file={fileItem}\n onClick={onFileClick ? () => onFileClick(fileItem) : undefined}\n />\n );\n }\n\n return (\n <a href={href} target=\"_blank\" rel=\"noopener noreferrer\">\n {props.children as React.ReactNode}\n </a>\n );\n },\n [\n onFileClick,\n onResourceLinkClick,\n renderResourceLink,\n resourceLinkSchemes,\n styles.resourceLink,\n bareUrlAsText,\n ],\n );\n\n return (\n <div\n className={`${styles.markdownWrapper}${compact ? ` ${styles.markdownWrapperCompact}` : \"\"}`}\n >\n <div\n className={`${styles.markdownHost}${compact ? ` ${styles.markdownHostCompact}` : \"\"}`}\n >\n <XMarkdown\n content={markdown}\n className=\"x-markdown-light\"\n paragraphTag=\"div\"\n config={{\n extensions: Latex(),\n }}\n components={{\n tag: ThinkComponent,\n \"resource-link\": ResourceLinkComponent,\n \"plain-mention\": PlainMentionComponent,\n code: CodeComponent,\n a: LinkComponent,\n }}\n streaming={{\n enableAnimation: true,\n animationConfig: {\n fadeDuration: 400,\n },\n }}\n />\n </div>\n </div>\n );\n};\n\nexport default MarkdownRender;\n"],"mappings":"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"}
@@ -7,7 +7,7 @@ export var useStyles = withBasicStyles(function () {
7
7
  markdownWrapper: css(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n display: grid;\n grid-template-columns: minmax(0, 1fr); /* \u5173\u952E\uFF1A\u5141\u8BB8\u5185\u5BB9\u6536\u7F29 */\n max-width: 100%; /* \u81EA\u5B9A\u4E49\u6700\u5927\u5BBD\u5EA6 */\n margin: 0 auto;\n "]))),
8
8
  markdownWrapperCompact: css(_templateObject2 || (_templateObject2 = _taggedTemplateLiteral(["\n display: inline;\n margin: 0;\n max-width: none;\n "]))),
9
9
  markdownHost: css(_templateObject3 || (_templateObject3 = _taggedTemplateLiteral(["\n container-type: inline-size;\n width: 100%;\n overflow: auto;\n\n /* ===== Markdown \u57FA\u7840\u6392\u7248 ===== */\n\n p {\n margin: 8px 0;\n line-height: 1.6;\n }\n\n ul,\n ol {\n padding-left: 20px;\n margin-top: 0;\n margin-bottom: 8px;\n }\n\n li {\n margin: 0 0 4px 0 !important;\n }\n\n u {\n text-decoration: underline;\n }\n\n em {\n font-style: italic;\n }\n\n /* ===== Table \u6837\u5F0F ===== */\n\n table {\n border-collapse: collapse;\n width: 100%;\n max-width: 100%;\n margin: 12px 0;\n font-size: 14px;\n }\n\n thead {\n background: #fafafa;\n }\n\n th,\n td {\n border: 1px solid #e5e6eb;\n padding: 8px 12px;\n text-align: left;\n }\n\n th {\n font-weight: 600;\n }\n\n tbody tr:hover {\n background: #fafafa;\n }\n\n /* ===== Code ===== */\n\n pre {\n margin: 12px 0;\n }\n\n ant-highlightCode {\n max-width: min(100%, 80ch);\n overflow-x: auto;\n }\n\n /* ===== \u56FE\u7247 ===== */\n\n img {\n max-width: 100%;\n border-radius: 6px;\n }\n "]))),
10
- markdownHostCompact: css(_templateObject4 || (_templateObject4 = _taggedTemplateLiteral(["\n display: inline;\n width: auto;\n overflow: visible;\n\n .x-markdown-light,\n p,\n div {\n display: inline;\n margin: 0;\n line-height: inherit;\n }\n "]))),
10
+ markdownHostCompact: css(_templateObject4 || (_templateObject4 = _taggedTemplateLiteral(["\n display: inline;\n width: auto;\n overflow: visible;\n\n .x-markdown-light,\n p,\n div {\n display: inline;\n margin: 0;\n line-height: inherit;\n }\n\n /* \u7528\u6237\u6D88\u606F\u91CC\u7684\u8D44\u6E90\u5F15\u7528\u91C7\u7528 Codex \u98CE\u683C\uFF1A\u84DD\u8272\u6587\u5B57\u9AD8\u4EAE\uFF0C\u4E0D\u989D\u5916\u5957\u6807\u7B7E\u5E95\u8272\u6216\u56FE\u6807\u3002 */\n [data-xadk-resource-link] {\n height: auto;\n margin: 0 4px;\n padding: 0;\n border: 0;\n border-radius: 0;\n background: transparent;\n color: #1677ff;\n font-size: inherit;\n font-weight: 500;\n line-height: inherit;\n cursor: default;\n\n &:hover {\n border-color: transparent;\n background: transparent;\n color: #1677ff;\n }\n }\n "]))),
11
11
  resourceLink: css(_templateObject5 || (_templateObject5 = _taggedTemplateLiteral(["\n display: inline-flex;\n align-items: center;\n max-width: 100%;\n height: 22px;\n margin: 0 2px;\n padding: 0 8px;\n border: 1px solid #d9e8ff;\n border-radius: 6px;\n background: #f5f9ff;\n color: #1f1f1f;\n font-size: 13px;\n line-height: 20px;\n vertical-align: baseline;\n cursor: pointer;\n\n &:hover {\n border-color: #91caff;\n background: #eaf3ff;\n }\n "])))
12
12
  };
13
13
  });
@@ -1 +1 @@
1
- {"version":3,"names":["css","withBasicStyles","useStyles","markdownWrapper","_templateObject","_taggedTemplateLiteral","markdownWrapperCompact","_templateObject2","markdownHost","_templateObject3","markdownHostCompact","_templateObject4","resourceLink","_templateObject5"],"sources":["../../../../../../src/components/XAdkChatbot/components/MarkdownRender/styles.tsx"],"sourcesContent":["import { css } from \"@emotion/css\";\nimport { withBasicStyles } from \"@/styles/common\";\n\nexport const useStyles = withBasicStyles(() => ({\n markdownWrapper: css`\n display: grid;\n grid-template-columns: minmax(0, 1fr); /* 关键:允许内容收缩 */\n max-width: 100%; /* 自定义最大宽度 */\n margin: 0 auto;\n `,\n\n markdownWrapperCompact: css`\n display: inline;\n margin: 0;\n max-width: none;\n `,\n\n markdownHost: css`\n container-type: inline-size;\n width: 100%;\n overflow: auto;\n\n /* ===== Markdown 基础排版 ===== */\n\n p {\n margin: 8px 0;\n line-height: 1.6;\n }\n\n ul,\n ol {\n padding-left: 20px;\n margin-top: 0;\n margin-bottom: 8px;\n }\n\n li {\n margin: 0 0 4px 0 !important;\n }\n\n u {\n text-decoration: underline;\n }\n\n em {\n font-style: italic;\n }\n\n /* ===== Table 样式 ===== */\n\n table {\n border-collapse: collapse;\n width: 100%;\n max-width: 100%;\n margin: 12px 0;\n font-size: 14px;\n }\n\n thead {\n background: #fafafa;\n }\n\n th,\n td {\n border: 1px solid #e5e6eb;\n padding: 8px 12px;\n text-align: left;\n }\n\n th {\n font-weight: 600;\n }\n\n tbody tr:hover {\n background: #fafafa;\n }\n\n /* ===== Code ===== */\n\n pre {\n margin: 12px 0;\n }\n\n ant-highlightCode {\n max-width: min(100%, 80ch);\n overflow-x: auto;\n }\n\n /* ===== 图片 ===== */\n\n img {\n max-width: 100%;\n border-radius: 6px;\n }\n `,\n\n markdownHostCompact: css`\n display: inline;\n width: auto;\n overflow: visible;\n\n .x-markdown-light,\n p,\n div {\n display: inline;\n margin: 0;\n line-height: inherit;\n }\n `,\n\n resourceLink: css`\n display: inline-flex;\n align-items: center;\n max-width: 100%;\n height: 22px;\n margin: 0 2px;\n padding: 0 8px;\n border: 1px solid #d9e8ff;\n border-radius: 6px;\n background: #f5f9ff;\n color: #1f1f1f;\n font-size: 13px;\n line-height: 20px;\n vertical-align: baseline;\n cursor: pointer;\n\n &:hover {\n border-color: #91caff;\n background: #eaf3ff;\n }\n `,\n}));\n\nexport default useStyles;\n"],"mappings":";;AAAA,SAASA,GAAG,QAAQ,cAAc;AAClC,SAASC,eAAe;AAExB,OAAO,IAAMC,SAAS,GAAGD,eAAe,CAAC;EAAA,OAAO;IAC9CE,eAAe,EAAEH,GAAG,CAAAI,eAAA,KAAAA,eAAA,GAAAC,sBAAA,qOAKnB;IAEDC,sBAAsB,EAAEN,GAAG,CAAAO,gBAAA,KAAAA,gBAAA,GAAAF,sBAAA,wEAI1B;IAEDG,YAAY,EAAER,GAAG,CAAAS,gBAAA,KAAAA,gBAAA,GAAAJ,sBAAA,irCA6EhB;IAEDK,mBAAmB,EAAEV,GAAG,CAAAW,gBAAA,KAAAA,gBAAA,GAAAN,sBAAA,uMAYvB;IAEDO,YAAY,EAAEZ,GAAG,CAAAa,gBAAA,KAAAA,gBAAA,GAAAR,sBAAA;EAqBnB,CAAC;AAAA,CAAC,CAAC;AAEH,eAAeH,SAAS"}
1
+ {"version":3,"names":["css","withBasicStyles","useStyles","markdownWrapper","_templateObject","_taggedTemplateLiteral","markdownWrapperCompact","_templateObject2","markdownHost","_templateObject3","markdownHostCompact","_templateObject4","resourceLink","_templateObject5"],"sources":["../../../../../../src/components/XAdkChatbot/components/MarkdownRender/styles.tsx"],"sourcesContent":["import { css } from \"@emotion/css\";\nimport { withBasicStyles } from \"@/styles/common\";\n\nexport const useStyles = withBasicStyles(() => ({\n markdownWrapper: css`\n display: grid;\n grid-template-columns: minmax(0, 1fr); /* 关键:允许内容收缩 */\n max-width: 100%; /* 自定义最大宽度 */\n margin: 0 auto;\n `,\n\n markdownWrapperCompact: css`\n display: inline;\n margin: 0;\n max-width: none;\n `,\n\n markdownHost: css`\n container-type: inline-size;\n width: 100%;\n overflow: auto;\n\n /* ===== Markdown 基础排版 ===== */\n\n p {\n margin: 8px 0;\n line-height: 1.6;\n }\n\n ul,\n ol {\n padding-left: 20px;\n margin-top: 0;\n margin-bottom: 8px;\n }\n\n li {\n margin: 0 0 4px 0 !important;\n }\n\n u {\n text-decoration: underline;\n }\n\n em {\n font-style: italic;\n }\n\n /* ===== Table 样式 ===== */\n\n table {\n border-collapse: collapse;\n width: 100%;\n max-width: 100%;\n margin: 12px 0;\n font-size: 14px;\n }\n\n thead {\n background: #fafafa;\n }\n\n th,\n td {\n border: 1px solid #e5e6eb;\n padding: 8px 12px;\n text-align: left;\n }\n\n th {\n font-weight: 600;\n }\n\n tbody tr:hover {\n background: #fafafa;\n }\n\n /* ===== Code ===== */\n\n pre {\n margin: 12px 0;\n }\n\n ant-highlightCode {\n max-width: min(100%, 80ch);\n overflow-x: auto;\n }\n\n /* ===== 图片 ===== */\n\n img {\n max-width: 100%;\n border-radius: 6px;\n }\n `,\n\n markdownHostCompact: css`\n display: inline;\n width: auto;\n overflow: visible;\n\n .x-markdown-light,\n p,\n div {\n display: inline;\n margin: 0;\n line-height: inherit;\n }\n\n /* 用户消息里的资源引用采用 Codex 风格:蓝色文字高亮,不额外套标签底色或图标。 */\n [data-xadk-resource-link] {\n height: auto;\n margin: 0 4px;\n padding: 0;\n border: 0;\n border-radius: 0;\n background: transparent;\n color: #1677ff;\n font-size: inherit;\n font-weight: 500;\n line-height: inherit;\n cursor: default;\n\n &:hover {\n border-color: transparent;\n background: transparent;\n color: #1677ff;\n }\n }\n `,\n\n resourceLink: css`\n display: inline-flex;\n align-items: center;\n max-width: 100%;\n height: 22px;\n margin: 0 2px;\n padding: 0 8px;\n border: 1px solid #d9e8ff;\n border-radius: 6px;\n background: #f5f9ff;\n color: #1f1f1f;\n font-size: 13px;\n line-height: 20px;\n vertical-align: baseline;\n cursor: pointer;\n\n &:hover {\n border-color: #91caff;\n background: #eaf3ff;\n }\n `,\n}));\n\nexport default useStyles;\n"],"mappings":";;AAAA,SAASA,GAAG,QAAQ,cAAc;AAClC,SAASC,eAAe;AAExB,OAAO,IAAMC,SAAS,GAAGD,eAAe,CAAC;EAAA,OAAO;IAC9CE,eAAe,EAAEH,GAAG,CAAAI,eAAA,KAAAA,eAAA,GAAAC,sBAAA,qOAKnB;IAEDC,sBAAsB,EAAEN,GAAG,CAAAO,gBAAA,KAAAA,gBAAA,GAAAF,sBAAA,wEAI1B;IAEDG,YAAY,EAAER,GAAG,CAAAS,gBAAA,KAAAA,gBAAA,GAAAJ,sBAAA,irCA6EhB;IAEDK,mBAAmB,EAAEV,GAAG,CAAAW,gBAAA,KAAAA,gBAAA,GAAAN,sBAAA,o1BAiCvB;IAEDO,YAAY,EAAEZ,GAAG,CAAAa,gBAAA,KAAAA,gBAAA,GAAAR,sBAAA;EAqBnB,CAAC;AAAA,CAAC,CAAC;AAEH,eAAeH,SAAS"}
@@ -71,6 +71,7 @@ var XAdkChatbot = /*#__PURE__*/forwardRef(function (_ref, ref) {
71
71
  var messagesEndRef = useRef(null);
72
72
  var prevInitializedRef = useRef(false);
73
73
  var prevSessionIdRef = useRef(sessionId);
74
+ var previousMessageCountRef = useRef(messages.length);
74
75
 
75
76
  // 暴露命令式 API
76
77
  var scrollToBottom = useCallback(function () {
@@ -149,8 +150,17 @@ var XAdkChatbot = /*#__PURE__*/forwardRef(function (_ref, ref) {
149
150
  userHasScrolledRef.current = false;
150
151
  }, [sessionId]);
151
152
 
152
- // 消息变化时自动滚动到底部(用户未手动上滚时)
153
+ // 新增用户消息代表一次主动发送,应无条件恢复跟随并置底。
154
+ // 之后的流式回复继续沿用“用户未主动上滚时跟随”的规则。
153
155
  useEffect(function () {
156
+ var previousCount = previousMessageCountRef.current;
157
+ previousMessageCountRef.current = messages.length;
158
+ var hasNewUserMessage = messages.slice(previousCount).some(function (message) {
159
+ return message.role === "user";
160
+ });
161
+ if (hasNewUserMessage) {
162
+ userHasScrolledRef.current = false;
163
+ }
154
164
  if (userHasScrolledRef.current) return;
155
165
  if (!messages.length) return;
156
166
  var el = listRef.current;
@@ -524,9 +534,17 @@ var XAdkChatbot = /*#__PURE__*/forwardRef(function (_ref, ref) {
524
534
  })
525
535
  }), m.text && /*#__PURE__*/_jsx("div", {
526
536
  className: styles.card,
537
+ onCopy: function onCopy(event) {
538
+ // 富文本标签的可见文案不含协议;复制用户消息时保留原始 Markdown,
539
+ // 使内容粘贴回 XAdkSender 后能重新还原成 Mention。
540
+ event.preventDefault();
541
+ event.clipboardData.setData("text/plain", m.text || "");
542
+ },
527
543
  children: /*#__PURE__*/_jsx(MarkdownRender, {
528
544
  text: m.text,
529
545
  compact: true,
546
+ bareUrlAsText: true,
547
+ highlightPlainMentions: true,
530
548
  resourceLinkSchemes: resourceLinkSchemes,
531
549
  onFileClick: onFileClick,
532
550
  onResourceLinkClick: onResourceLinkClick,
@@ -553,7 +571,7 @@ var XAdkChatbot = /*#__PURE__*/forwardRef(function (_ref, ref) {
553
571
  children: /*#__PURE__*/_jsx(Button, {
554
572
  type: "text",
555
573
  icon: /*#__PURE__*/_jsx(SwapRightOutlined, {}),
556
- iconPosition: "end",
574
+ iconPlacement: "end",
557
575
  onClick: function onClick() {
558
576
  if (!item) return;
559
577
  onSuggest === null || onSuggest === void 0 || onSuggest(item);