@ai-group/chat-sdk 3.7.5 → 3.8.0-alpha.2

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 (117) hide show
  1. package/README.md +36 -0
  2. package/dist/cjs/components/DislikeFeedback.js.map +2 -2
  3. package/dist/cjs/components/FileGallery/index.js +2 -1
  4. package/dist/cjs/components/FileGallery/index.js.map +3 -3
  5. package/dist/cjs/components/FolderTree/DirectoryTree.js.map +2 -2
  6. package/dist/cjs/components/Sources/components/CarouselCard.js.map +2 -2
  7. package/dist/cjs/components/XAdkChatbot/index.js +307 -59
  8. package/dist/cjs/components/XAdkChatbot/index.js.map +3 -3
  9. package/dist/cjs/components/XAdkChatbot/styles.d.ts +4 -0
  10. package/dist/cjs/components/XAdkChatbot/styles.js +59 -2
  11. package/dist/cjs/components/XAdkChatbot/styles.js.map +2 -2
  12. package/dist/cjs/components/XAdkChatbot/utils.d.ts +14 -0
  13. package/dist/cjs/components/XAdkChatbot/utils.js +79 -0
  14. package/dist/cjs/components/XAdkChatbot/utils.js.map +7 -0
  15. package/dist/cjs/components/XAdkProvider/compound/DislikeFeedBack.js.map +2 -2
  16. package/dist/cjs/components/XAdkProvider/compound/Messages.d.ts +7 -1
  17. package/dist/cjs/components/XAdkProvider/compound/Messages.js +12 -0
  18. package/dist/cjs/components/XAdkProvider/compound/Messages.js.map +2 -2
  19. package/dist/cjs/components/XAdkProvider/compound/Sidebar.js.map +2 -2
  20. package/dist/cjs/components/XAdkProvider/context/ChatStateContext.d.ts +2 -0
  21. package/dist/cjs/components/XAdkProvider/context/ChatStateContext.js.map +2 -2
  22. package/dist/cjs/components/XAdkProvider/index.js +3 -0
  23. package/dist/cjs/components/XAdkProvider/index.js.map +2 -2
  24. package/dist/cjs/components/XAdkSender/InputTags.js.map +2 -2
  25. package/dist/cjs/components/XAdkSender/index.js +53 -5
  26. package/dist/cjs/components/XAdkSender/index.js.map +3 -3
  27. package/dist/cjs/components/XAdkThoughtChain/index.js +27 -28
  28. package/dist/cjs/components/XAdkThoughtChain/index.js.map +2 -2
  29. package/dist/cjs/components/XAdkThoughtChain/styles.d.ts +3 -1
  30. package/dist/cjs/components/XAdkThoughtChain/styles.js +66 -39
  31. package/dist/cjs/components/XAdkThoughtChain/styles.js.map +2 -2
  32. package/dist/cjs/components/XAiChatbot/index.js.map +2 -2
  33. package/dist/cjs/components/XAiConversations/index.js +2 -1
  34. package/dist/cjs/components/XAiConversations/index.js.map +3 -3
  35. package/dist/cjs/components/XAiProvider/index.js.map +2 -2
  36. package/dist/cjs/components/XAiSender/index.js.map +2 -2
  37. package/dist/cjs/hooks/useADKChat.d.ts +6 -1
  38. package/dist/cjs/hooks/useADKChat.js +15 -1
  39. package/dist/cjs/hooks/useADKChat.js.map +2 -2
  40. package/dist/cjs/hooks/useADKMessageQueue.d.ts +24 -0
  41. package/dist/cjs/hooks/useADKMessageQueue.js +107 -0
  42. package/dist/cjs/hooks/useADKMessageQueue.js.map +7 -0
  43. package/dist/cjs/index.d.ts +3 -1
  44. package/dist/cjs/index.js +3 -0
  45. package/dist/cjs/index.js.map +2 -2
  46. package/dist/cjs/react/index.d.ts +2 -0
  47. package/dist/cjs/react/index.js +3 -0
  48. package/dist/cjs/react/index.js.map +2 -2
  49. package/dist/cjs/types/XAdkChatbot.d.ts +49 -0
  50. package/dist/cjs/types/XAdkChatbot.js.map +1 -1
  51. package/dist/cjs/types/XAdkProvider.d.ts +7 -0
  52. package/dist/cjs/types/XAdkProvider.js.map +2 -2
  53. package/dist/cjs/types/XAdkSender.d.ts +8 -1
  54. package/dist/cjs/types/XAdkSender.js.map +1 -1
  55. package/dist/cjs/types/XAdkThoughtChain.d.ts +2 -0
  56. package/dist/cjs/types/XAdkThoughtChain.js.map +1 -1
  57. package/dist/cjs/types/antdx.d.ts +6 -3
  58. package/dist/cjs/types/antdx.js.map +1 -1
  59. package/dist/esm/components/DislikeFeedback.js.map +1 -1
  60. package/dist/esm/components/FileGallery/index.js +2 -1
  61. package/dist/esm/components/FileGallery/index.js.map +1 -1
  62. package/dist/esm/components/FolderTree/DirectoryTree.js.map +1 -1
  63. package/dist/esm/components/Sources/components/CarouselCard.js.map +1 -1
  64. package/dist/esm/components/XAdkChatbot/index.js +277 -25
  65. package/dist/esm/components/XAdkChatbot/index.js.map +1 -1
  66. package/dist/esm/components/XAdkChatbot/styles.d.ts +4 -0
  67. package/dist/esm/components/XAdkChatbot/styles.js +30 -26
  68. package/dist/esm/components/XAdkChatbot/styles.js.map +1 -1
  69. package/dist/esm/components/XAdkChatbot/utils.d.ts +14 -0
  70. package/dist/esm/components/XAdkChatbot/utils.js +66 -0
  71. package/dist/esm/components/XAdkChatbot/utils.js.map +1 -0
  72. package/dist/esm/components/XAdkProvider/compound/DislikeFeedBack.js.map +1 -1
  73. package/dist/esm/components/XAdkProvider/compound/Messages.d.ts +7 -1
  74. package/dist/esm/components/XAdkProvider/compound/Messages.js +16 -2
  75. package/dist/esm/components/XAdkProvider/compound/Messages.js.map +1 -1
  76. package/dist/esm/components/XAdkProvider/compound/Sidebar.js.map +1 -1
  77. package/dist/esm/components/XAdkProvider/context/ChatStateContext.d.ts +2 -0
  78. package/dist/esm/components/XAdkProvider/context/ChatStateContext.js.map +1 -1
  79. package/dist/esm/components/XAdkProvider/index.js +4 -2
  80. package/dist/esm/components/XAdkProvider/index.js.map +1 -1
  81. package/dist/esm/components/XAdkSender/InputTags.js.map +1 -1
  82. package/dist/esm/components/XAdkSender/index.js +80 -16
  83. package/dist/esm/components/XAdkSender/index.js.map +1 -1
  84. package/dist/esm/components/XAdkThoughtChain/index.js +52 -78
  85. package/dist/esm/components/XAdkThoughtChain/index.js.map +1 -1
  86. package/dist/esm/components/XAdkThoughtChain/styles.d.ts +3 -1
  87. package/dist/esm/components/XAdkThoughtChain/styles.js +29 -27
  88. package/dist/esm/components/XAdkThoughtChain/styles.js.map +1 -1
  89. package/dist/esm/components/XAiChatbot/index.js.map +1 -1
  90. package/dist/esm/components/XAiConversations/index.js +2 -1
  91. package/dist/esm/components/XAiConversations/index.js.map +1 -1
  92. package/dist/esm/components/XAiProvider/index.js.map +1 -1
  93. package/dist/esm/components/XAiSender/index.js.map +1 -1
  94. package/dist/esm/hooks/useADKChat.d.ts +6 -1
  95. package/dist/esm/hooks/useADKChat.js +18 -1
  96. package/dist/esm/hooks/useADKChat.js.map +1 -1
  97. package/dist/esm/hooks/useADKMessageQueue.d.ts +24 -0
  98. package/dist/esm/hooks/useADKMessageQueue.js +159 -0
  99. package/dist/esm/hooks/useADKMessageQueue.js.map +1 -0
  100. package/dist/esm/index.d.ts +3 -1
  101. package/dist/esm/index.js +2 -1
  102. package/dist/esm/index.js.map +1 -1
  103. package/dist/esm/react/index.d.ts +2 -0
  104. package/dist/esm/react/index.js +1 -0
  105. package/dist/esm/react/index.js.map +1 -1
  106. package/dist/esm/types/XAdkChatbot.d.ts +49 -0
  107. package/dist/esm/types/XAdkChatbot.js.map +1 -1
  108. package/dist/esm/types/XAdkProvider.d.ts +7 -0
  109. package/dist/esm/types/XAdkProvider.js.map +1 -1
  110. package/dist/esm/types/XAdkSender.d.ts +8 -1
  111. package/dist/esm/types/XAdkSender.js.map +1 -1
  112. package/dist/esm/types/XAdkThoughtChain.d.ts +2 -0
  113. package/dist/esm/types/XAdkThoughtChain.js.map +1 -1
  114. package/dist/esm/types/antdx.d.ts +6 -3
  115. package/dist/esm/types/antdx.js.map +1 -1
  116. package/dist/umd/chat-sdk.min.js +1 -1
  117. package/package.json +1 -1
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/components/XAdkChatbot/index.tsx"],
4
- "sourcesContent": ["import {\n useMemo,\n useCallback,\n useEffect,\n useRef,\n useImperativeHandle,\n forwardRef,\n} from \"react\";\nimport { Button, Flex, Tooltip, message as antdMessage } from \"antd\";\nimport clsx from \"clsx\";\nimport {\n SwapRightOutlined,\n ReloadOutlined,\n CopyOutlined,\n InfoCircleOutlined,\n} from \"@ant-design/icons\";\nimport copy from \"copy-to-clipboard\";\nimport { useStyles } from \"./styles\";\nimport MarkdownRender from \"./components/MarkdownRender\";\nimport FunctionCallRender from \"./components/FunctionCallRender\";\nimport FileGallery from \"../FileGallery\";\nimport XAdkThoughtChain from \"@/components/XAdkThoughtChain\";\nimport { parseAgentMessage } from \"@/utils\";\nimport {\n mergeChatStrategies,\n resolvePresetMarkdownExtensions,\n} from \"@/presets/runtime\";\nimport type {\n IMessage,\n XAdkChatbotProps,\n XAdkChatbotHandle,\n ChatGroup,\n} from \"@/types\";\nimport type { ThoughtChainItemType } from \"@/types/XAdkThoughtChain\";\nimport { defaultToolKindResolver } from \"@/types/FunctionCallRender\";\n\nconst scrollThreshold = 10;\n\n/**\n * XAdkChatbot - 增强版聊天组件\n *\n * 新增功能:\n * - ✅ 自动消息分组 (enableGrouping)\n * - ✅ 自动解析思维链 (enableProcessParsing)\n * - ✅ 文件展示 (FileGallery)\n * - ✅ 操作栏 (重试/复制/日志)\n * - ✅ 欢迎页面 (agentName/agentIcon/description)\n */\nconst XAdkChatbot = forwardRef<XAdkChatbotHandle, XAdkChatbotProps>(\n (\n {\n loading = false,\n prologue,\n suggestions,\n messages,\n showFnCallDetail,\n onConfirm,\n onSuggest,\n showRetry,\n showCopy,\n showLog,\n onRetry,\n onCopy,\n onShowLog,\n actions,\n actionsExtra,\n className,\n style,\n // welcome = null,\n enableGrouping = true,\n enableProcessParsing = true,\n parseOptions,\n initialized = true,\n sessionId,\n onFileClick,\n onResourceLinkClick,\n renderResourceLink,\n markdownExtensions,\n renderFunctionCall,\n toolKindResolver,\n strategies,\n preset,\n empty,\n },\n ref,\n ) => {\n const styles = useStyles();\n const listRef = useRef<HTMLDivElement>(null);\n const lastScrollTopRef = useRef(0);\n const userHasScrolledRef = useRef(false);\n const messagesEndRef = useRef<HTMLDivElement>(null);\n const prevInitializedRef = useRef(false);\n const prevSessionIdRef = useRef(sessionId);\n const previousMessageCountRef = useRef(messages.length);\n\n // 暴露命令式 API\n const scrollToBottom = useCallback((behavior: ScrollBehavior = \"auto\") => {\n messagesEndRef.current?.scrollIntoView({ behavior });\n }, []);\n useImperativeHandle(ref, () => ({ scrollToBottom }), [scrollToBottom]);\n const mergedStrategies = useMemo(\n () => mergeChatStrategies(preset, strategies),\n [preset, strategies],\n );\n const mergedMarkdownExtensions = useMemo(\n () => resolvePresetMarkdownExtensions(preset, markdownExtensions),\n [markdownExtensions, preset],\n );\n const resolveToolKind = useCallback(\n (name?: string, msg?: IMessage) =>\n toolKindResolver?.(name) ??\n mergedStrategies.resolveToolKind?.({ name, msg }) ??\n defaultToolKindResolver(name),\n [toolKindResolver, mergedStrategies],\n );\n const parseProcessMessage =\n mergedStrategies.parseProcessMessage ?? parseAgentMessage;\n const resourceLinkSchemes = mergedStrategies.markdownResourceLinkSchemes;\n\n // 初始化完成时滚动到底部\n useEffect(() => {\n if (!initialized) return;\n if (!messages.length) return;\n if (prevInitializedRef.current) return;\n prevInitializedRef.current = true;\n\n const el = listRef.current;\n if (!el) return;\n\n // 用 MutationObserver 监听 DOM 子树变化,等内容渲染稳定后置底\n // 每次 DOM 变化都重新计时,确保所有异步渲染(Markdown、代码高亮、思维链等)完成后再滚动\n let stableTimer: ReturnType<typeof setTimeout>;\n const doScroll = () => {\n messagesEndRef.current?.scrollIntoView({ behavior: \"auto\" });\n };\n\n const observer = new MutationObserver(() => {\n clearTimeout(stableTimer);\n stableTimer = setTimeout(doScroll, 80);\n });\n\n observer.observe(el, {\n childList: true,\n subtree: true,\n characterData: true,\n });\n\n // 立即执行一次,处理内容已经就绪的情况\n doScroll();\n // 兜底:最多等 500ms 后强制滚动并断开观察\n const maxTimer = setTimeout(() => {\n observer.disconnect();\n doScroll();\n }, 500);\n\n return () => {\n clearTimeout(stableTimer);\n clearTimeout(maxTimer);\n observer.disconnect();\n };\n }, [initialized, messages]);\n\n // 会话切换时重置滚动状态,允许重新触发初始化置底\n useEffect(() => {\n if (sessionId === undefined) return; // 未传 sessionId 不处理\n if (prevSessionIdRef.current === sessionId) return; // 同一会话不处理\n prevSessionIdRef.current = sessionId;\n prevInitializedRef.current = false;\n userHasScrolledRef.current = false;\n }, [sessionId]);\n\n // 新增用户消息代表一次主动发送,应无条件恢复跟随并置底。\n // 之后的流式回复继续沿用“用户未主动上滚时跟随”的规则。\n useEffect(() => {\n const previousCount = previousMessageCountRef.current;\n previousMessageCountRef.current = messages.length;\n const hasNewUserMessage = messages\n .slice(previousCount)\n .some((message) => message.role === \"user\");\n if (hasNewUserMessage) {\n userHasScrolledRef.current = false;\n }\n if (userHasScrolledRef.current) return;\n if (!messages.length) return;\n const el = listRef.current;\n if (el) {\n el.scrollTop = el.scrollHeight;\n }\n }, [loading, messages]);\n\n // loading 结束时(流式输出完成),操作栏(metaFooter)会渲染出来增加高度,\n // 需要延迟滚动到底部,确保操作栏可见\n const prevLoadingRef = useRef(loading);\n useEffect(() => {\n const wasLoading = prevLoadingRef.current;\n prevLoadingRef.current = loading;\n\n if (!wasLoading || loading) return; // 只在 loading true → false 时触发\n if (userHasScrolledRef.current) return;\n if (!messages.length) return;\n\n // 延迟等待操作栏 DOM 渲染完成后再滚动\n const timer = setTimeout(() => {\n const el = listRef.current;\n if (el) {\n el.scrollTop = el.scrollHeight;\n }\n }, 50);\n return () => clearTimeout(timer);\n }, [loading, messages]);\n\n // 处理滚动事件\n const handleScroll = useCallback(() => {\n const el = listRef.current;\n if (!el) return;\n const currentTop = el.scrollTop;\n\n if (currentTop < lastScrollTopRef.current) {\n userHasScrolledRef.current = true;\n }\n\n const isAtBottom =\n Math.abs(el.scrollHeight - currentTop - el.clientHeight) <=\n scrollThreshold;\n if (isAtBottom) {\n userHasScrolledRef.current = false;\n }\n\n lastScrollTopRef.current = currentTop;\n }, []);\n\n useEffect(() => {\n const listElement = listRef.current;\n if (!listElement) return;\n\n listElement.addEventListener(\"scroll\", handleScroll);\n return () => {\n listElement.removeEventListener(\"scroll\", handleScroll);\n };\n }, [handleScroll]);\n\n // ========== 消息分组逻辑 ==========\n const chatGroups = useMemo(() => {\n if (!enableGrouping) {\n // 不分组,每条消息独立\n return messages.map((msg) => ({\n id: msg.id,\n role: msg.role,\n msgs: [msg],\n invocationId: msg.invocationId,\n allFiles: msg.fileData || [],\n isLike: msg.isLike ?? 0,\n }));\n }\n\n const groups: ChatGroup[] = [];\n messages.forEach((msg) => {\n // 过滤 followup 消息\n if ((msg as any).role === \"followup\") return;\n\n const isRealUserQuery =\n msg.role === \"user\" && !msg.functionResponse && !msg.functionCall;\n const lastGroup = groups[groups.length - 1];\n const isLastGroupAgent = lastGroup?.role === \"bot\";\n\n if (isLastGroupAgent && !isRealUserQuery) {\n // 合并到上一个 bot 分组\n lastGroup.msgs.push(msg);\n if (msg.invocationId) lastGroup.invocationId = msg.invocationId;\n // 更新 isLike: 取最新的非0值,或保持当前值\n if (msg.isLike && msg.isLike !== 0) {\n lastGroup.isLike = msg.isLike;\n }\n } else {\n // 创建新分组\n groups.push({\n id: msg.id || `group-${groups.length}`,\n role: isRealUserQuery ? \"user\" : \"bot\",\n msgs: [msg],\n invocationId: msg.invocationId,\n allFiles: [],\n isLike: msg.isLike ?? 0,\n });\n }\n });\n\n // 合并文件\n groups.forEach((g) => {\n g.allFiles = g.msgs.reduce(\n (acc, m) => [...acc, ...(m.fileData || [])],\n [] as any[],\n );\n });\n\n return groups;\n }, [messages, enableGrouping]);\n\n // ========== 渲染 Bot 消息组 ==========\n const renderBotGroup = useCallback(\n (\n group: ChatGroup,\n isLastGroup: boolean,\n renderFunctionCall?: XAdkChatbotProps[\"renderFunctionCall\"],\n ) => {\n const { msgs, allFiles } = group;\n\n if (!enableProcessParsing) {\n // 不解析 process,简单渲染\n return (\n <div key={group.id} className={styles.botMsg}>\n {msgs.map((msg, i) => {\n if (msg.text) {\n return (\n <MarkdownRender\n key={`${msg.id}-${i}`}\n text={msg.text}\n resourceLinkSchemes={resourceLinkSchemes}\n onFileClick={onFileClick}\n onResourceLinkClick={onResourceLinkClick}\n renderResourceLink={renderResourceLink}\n markdownExtensions={mergedMarkdownExtensions}\n />\n );\n }\n if (msg.functionCall) {\n return (\n renderFunctionCall?.(msg) ?? (\n <FunctionCallRender\n key={`${msg.id}-${i}`}\n msg={msg}\n showDetail={showFnCallDetail}\n onConfirm={onConfirm}\n kind={resolveToolKind(msg.functionCall?.name, msg)}\n renderApproval={mergedStrategies.renderApproval}\n renderHandoff={mergedStrategies.renderHandoff}\n />\n )\n );\n }\n return null;\n })}\n </div>\n );\n }\n\n // ========== 解析 Process 内容 ==========\n\n // 1. 合并工具调用\n const mergedToolMap = new Map<string, IMessage>();\n msgs.forEach((msg) => {\n if (msg.functionCall) {\n const callId = msg.functionCall.id || \"\";\n if (!mergedToolMap.has(callId)) {\n mergedToolMap.set(callId, { ...msg });\n } else {\n mergedToolMap.set(callId, {\n ...(mergedToolMap.get(callId) ?? {}),\n ...msg,\n });\n }\n } else if (msg.functionResponse) {\n const callId = msg.functionResponse.id || \"\";\n if (mergedToolMap.has(callId)) {\n const tool = mergedToolMap.get(callId);\n if (tool) tool.functionResponse = msg.functionResponse;\n } else {\n mergedToolMap.set(callId, {\n ...msg,\n functionCall: {\n id: callId,\n name: msg.functionResponse.name || \"Unknown\",\n args: {},\n },\n });\n }\n }\n });\n\n // 2. 解析文本消息中的 process 内容\n type RenderNode =\n | { type: \"text\"; content: string; key: string }\n | { type: \"process\"; items: ThoughtChainItemType[]; key: string };\n\n const nodes: RenderNode[] = [];\n let currentProcessItems: ThoughtChainItemType[] = [];\n const processedToolIds = new Set<string>();\n\n const flushProcessItems = () => {\n if (currentProcessItems.length > 0) {\n nodes.push({\n type: \"process\",\n items: [...currentProcessItems],\n key: `process-${nodes.length}`,\n });\n currentProcessItems = [];\n }\n };\n\n msgs.forEach((msg) => {\n // 处理工具调用\n if (msg.functionCall) {\n const callId = msg.functionCall.id || \"\";\n if (!processedToolIds.has(callId)) {\n const mergedMsg = mergedToolMap.get(callId);\n if (mergedMsg) {\n currentProcessItems.push({\n type: \"tool\",\n key: `tool-${callId}`,\n content: \"\",\n msg: mergedMsg,\n });\n processedToolIds.add(callId);\n }\n }\n }\n // 处理文本消息\n else if (msg.text && !msg.functionResponse) {\n const parts = parseProcessMessage(msg.text, parseOptions as any);\n\n parts.forEach((part, partIdx) => {\n // process 内容放入 currentProcessItems\n if (\n [\n \"planning\",\n \"replanning\",\n \"reasoning\",\n \"action_log\",\n \"process_text\",\n ].includes(part.type)\n ) {\n const titleMap: Record<string, string> = {\n planning: \"任务规划\",\n replanning: \"重新规划\",\n reasoning: \"推理分析\",\n action_log: \"行动记录\",\n process_text: \"过程分析\",\n };\n\n currentProcessItems.push({\n type: \"text\",\n key: `${msg.id}-${partIdx}`,\n content: part.content,\n title: titleMap[part.type] || \"分析\",\n });\n }\n // 普通文本内容\n else {\n flushProcessItems();\n if (part.content.trim()) {\n const lastNode = nodes[nodes.length - 1];\n if (lastNode?.type === \"text\") {\n // 合并到上一个文本节点\n lastNode.content += \"\\n\\n\" + part.content;\n } else {\n nodes.push({\n type: \"text\",\n content: part.content,\n key: `text-${msg.id}-${partIdx}`,\n });\n }\n }\n }\n });\n }\n });\n\n // 最后flush一次\n flushProcessItems();\n\n // 3. 准备操作栏数据\n const fullTextToCopy = msgs\n .filter((m) => !m.functionCall && !m.functionResponse)\n .map((m) => m.text || \"\")\n .join(\"\");\n\n const lastBotMsg = msgs[msgs.length - 1];\n const hasProcess = nodes.some((n) => n.type === \"process\");\n const isGroupLoading = loading && isLastGroup;\n const actionProps = { message: group, isLastBotMsg: isLastGroup };\n const actionExtraNode = actionsExtra?.(actionProps);\n\n // 4. 渲染\n const lastProcessIdx = nodes.findLastIndex((n) => n.type === \"process\");\n return (\n <div key={group.id} className={styles.botMsg}>\n {nodes.map((node, idx) => {\n if (node.type === \"process\") {\n // 只有最后一个 process node 跟随 loading 状态,已完成的思维链不应显示 loading\n const isLastProcess = idx === lastProcessIdx;\n return (\n <XAdkThoughtChain\n key={node.key}\n loading={isLastProcess && isGroupLoading}\n title=\"思维链已完成\"\n items={node.items}\n showFnCallDetail={showFnCallDetail}\n onConfirm={onConfirm}\n defaultOpen={isLastProcess && isGroupLoading}\n renderFunctionCall={renderFunctionCall}\n toolKindResolver={(name) => resolveToolKind(name)}\n strategies={mergedStrategies}\n />\n );\n }\n\n // 文本节点\n // const showBadge =\n // hasProcess && nodes.findIndex((n) => n.type === \"text\") === idx;\n return (\n <div key={node.key}>\n {/* {showBadge && (\n <div className={styles.successBadge}>\n <CheckCircleFilled /> 已完成所有规划任务\n </div>\n )} */}\n <MarkdownRender\n text={node.content}\n resourceLinkSchemes={resourceLinkSchemes}\n onFileClick={onFileClick}\n onResourceLinkClick={onResourceLinkClick}\n renderResourceLink={renderResourceLink}\n markdownExtensions={mergedMarkdownExtensions}\n />\n </div>\n );\n })}\n\n {/* 文件展示 */}\n {allFiles.length > 0 && (\n <div className={styles.fileSection}>\n <div className={styles.fileHeader}>\n <span>生成文件 ({allFiles.length})</span>\n </div>\n <div style={{ display: \"flex\", flexWrap: \"wrap\", gap: \"8px\" }}>\n {allFiles.map((file, index) => (\n <FileGallery\n key={index}\n file={file}\n onClick={onFileClick}\n />\n ))}\n </div>\n </div>\n )}\n\n {/* 操作栏 */}\n {!isGroupLoading &&\n (actions ||\n showRetry ||\n showCopy ||\n showLog ||\n actionExtraNode) && (\n <div className={styles.metaFooter}>\n {actions ? (\n actions(actionProps)\n ) : (\n <Flex gap={16} className={styles.actionIcons}>\n {showRetry && isLastGroup && (\n <Tooltip title=\"重新生成\">\n <ReloadOutlined onClick={onRetry} />\n </Tooltip>\n )}\n {showCopy && (\n <Tooltip title=\"复制内容\">\n <CopyOutlined\n onClick={() => {\n copy(fullTextToCopy);\n antdMessage.success(\"复制成功\");\n onCopy?.(fullTextToCopy);\n }}\n />\n </Tooltip>\n )}\n {showLog && lastBotMsg?.invocationId && (\n <Tooltip title=\"查看日志\">\n <InfoCircleOutlined\n onClick={() =>\n onShowLog?.(\n lastBotMsg.invocationId!,\n lastBotMsg.timestamp,\n )\n }\n />\n </Tooltip>\n )}\n </Flex>\n )}\n {actionExtraNode}\n </div>\n )}\n </div>\n );\n },\n [\n enableProcessParsing,\n parseOptions,\n parseProcessMessage,\n showFnCallDetail,\n onConfirm,\n loading,\n showRetry,\n showCopy,\n showLog,\n onRetry,\n onCopy,\n onShowLog,\n actions,\n actionsExtra,\n onFileClick,\n onResourceLinkClick,\n renderResourceLink,\n mergedMarkdownExtensions,\n resourceLinkSchemes,\n styles,\n resolveToolKind,\n mergedStrategies,\n ],\n );\n\n // ========== 渲染用户消息组 ==========\n const renderUserGroup = useCallback(\n (group: ChatGroup) => {\n return (\n <div key={group.id} className={styles.userMsg}>\n {group.msgs.map((m, i) => (\n <div key={m.id || i} className={styles.userContainer}>\n {/* 文件展示 */}\n {m.fileData && m.fileData.length > 0 && (\n <>\n {m.fileData.map((file, index) => (\n <FileGallery\n key={index}\n file={file}\n align=\"left\"\n style={{ marginBottom: \"16px\" }}\n onClick={onFileClick}\n />\n ))}\n </>\n )}\n {/* 文本展示 */}\n {m.text && (\n <div\n className={styles.card}\n onCopy={(event) => {\n // 富文本标签的可见文案不含协议;复制用户消息时保留原始 Markdown,\n // 使内容粘贴回 XAdkSender 后能重新还原成 Mention。\n event.preventDefault();\n event.clipboardData.setData(\"text/plain\", m.text || \"\");\n }}\n >\n <MarkdownRender\n text={m.text}\n compact\n bareUrlAsText\n highlightPlainMentions\n resourceLinkSchemes={resourceLinkSchemes}\n onFileClick={onFileClick}\n onResourceLinkClick={onResourceLinkClick}\n renderResourceLink={renderResourceLink}\n markdownExtensions={mergedMarkdownExtensions}\n />\n </div>\n )}\n </div>\n ))}\n </div>\n );\n },\n [\n styles,\n onFileClick,\n onResourceLinkClick,\n renderResourceLink,\n mergedMarkdownExtensions,\n resourceLinkSchemes,\n ],\n );\n\n // ========== 空状态 ==========\n\n // ========== 渲染建议问题 ==========\n const renderSuggestions = () => {\n if (!suggestions || suggestions.length === 0) return null;\n\n return (\n <div className={styles.suggestionWrapper}>\n {suggestions.map((item) => (\n <div key={item} className={styles.suggestion}>\n <div className={styles.suggestContent}>\n <Button\n type=\"text\"\n icon={<SwapRightOutlined />}\n iconPlacement=\"end\"\n onClick={() => {\n if (!item) return;\n onSuggest?.(item);\n }}\n style={{\n whiteSpace: \"normal\",\n height: \"auto\",\n wordWrap: \"break-word\",\n textAlign: \"left\",\n padding: \"4px 15px\",\n lineHeight: \"1.5\",\n }}\n >\n {item}\n </Button>\n </div>\n </div>\n ))}\n </div>\n );\n };\n\n // 空状态判断\n const isEmpty =\n messages.length === 0 &&\n !prologue &&\n (!suggestions || suggestions.length === 0);\n\n return (\n <div className={clsx(styles.wrapper, className)} style={style}>\n {/* 空状态 */}\n {isEmpty && empty && (\n <div className={styles.emptyWrapper}>\n {typeof empty === \"function\" ? empty() : empty}\n </div>\n )}\n\n <div\n className={styles.list}\n ref={listRef}\n style={isEmpty ? { flex: 0 } : undefined}\n >\n {/* 开场白 */}\n {prologue && (\n <div className={styles.prologue}>\n <MarkdownRender\n text={prologue}\n resourceLinkSchemes={resourceLinkSchemes}\n onFileClick={onFileClick}\n onResourceLinkClick={onResourceLinkClick}\n renderResourceLink={renderResourceLink}\n markdownExtensions={mergedMarkdownExtensions}\n />\n </div>\n )}\n\n {/* 消息列表 */}\n {chatGroups.map((group, idx) =>\n group.role === \"user\"\n ? renderUserGroup(group)\n : renderBotGroup(\n group,\n idx === chatGroups.length - 1,\n renderFunctionCall,\n ),\n )}\n\n {/* 建议问题 */}\n {renderSuggestions()}\n\n <div ref={messagesEndRef} />\n </div>\n </div>\n );\n },\n);\n\nXAdkChatbot.displayName = \"XAdkChatbot\";\n\nexport default XAdkChatbot;\n"],
5
- "mappings": "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",
6
- "names": ["import_FunctionCallRender", "renderFunctionCall", "MarkdownRender", "FunctionCallRender", "XAdkThoughtChain", "FileGallery", "copy", "antdMessage", "clsx"]
4
+ "sourcesContent": ["import {\n useMemo,\n useCallback,\n useEffect,\n useLayoutEffect,\n useRef,\n useImperativeHandle,\n forwardRef,\n Fragment,\n} from \"react\";\nimport { Button, Flex, Tooltip, message as antdMessage } from \"antd\";\nimport clsx from \"clsx\";\nimport {\n SwapRightOutlined,\n ReloadOutlined,\n CopyOutlined,\n InfoCircleOutlined,\n} from \"@ant-design/icons\";\nimport copy from \"copy-to-clipboard\";\nimport { useStyles } from \"./styles\";\nimport { formatTimestamp, getSelectionText } from \"./utils\";\nimport MarkdownRender from \"./components/MarkdownRender\";\nimport FunctionCallRender from \"./components/FunctionCallRender\";\nimport FileGallery from \"../FileGallery\";\nimport XAdkThoughtChain from \"@/components/XAdkThoughtChain\";\nimport { parseAgentMessage } from \"@/utils\";\nimport {\n mergeChatStrategies,\n resolvePresetMarkdownExtensions,\n} from \"@/presets/runtime\";\nimport type {\n IMessage,\n XAdkChatbotProps,\n XAdkChatbotHandle,\n ChatGroup,\n} from \"@/types\";\nimport type { ThoughtChainItemType } from \"@/types/XAdkThoughtChain\";\nimport { defaultToolKindResolver } from \"@/types/FunctionCallRender\";\n\nconst scrollThreshold = 10;\n\n/**\n * XAdkChatbot - 增强版聊天组件\n *\n * 新增功能:\n * - ✅ 自动消息分组 (enableGrouping)\n * - ✅ 自动解析思维链 (enableProcessParsing)\n * - ✅ 文件展示 (FileGallery)\n * - ✅ 操作栏 (重试/复制/日志)\n * - ✅ 欢迎页面 (agentName/agentIcon/description)\n */\nconst XAdkChatbot = forwardRef<XAdkChatbotHandle, XAdkChatbotProps>(\n (\n {\n loading = false,\n prologue,\n suggestions,\n messages,\n renderBeforeGroup,\n renderAfterGroup,\n renderGroup,\n history,\n showFnCallDetail,\n onConfirm,\n onSuggest,\n showRetry,\n showCopy,\n showLog,\n onRetry,\n onCopy,\n onShowLog,\n actions,\n actionsExtra,\n className,\n style,\n // welcome = null,\n enableGrouping = true,\n enableProcessParsing = true,\n parseOptions,\n initialized = true,\n sessionId,\n onFileClick,\n onResourceLinkClick,\n renderResourceLink,\n markdownExtensions,\n renderFunctionCall,\n toolKindResolver,\n strategies,\n preset,\n empty,\n showUserActions,\n userActions,\n },\n ref,\n ) => {\n const styles = useStyles();\n const listRef = useRef<HTMLDivElement>(null);\n const lastScrollTopRef = useRef(0);\n const userHasScrolledRef = useRef(false);\n const messagesEndRef = useRef<HTMLDivElement>(null);\n const prevInitializedRef = useRef(false);\n const prevSessionIdRef = useRef(sessionId);\n const previousMessageCountRef = useRef(messages.length);\n const historyRef = useRef(history);\n historyRef.current = history;\n const messagesRef = useRef(messages);\n messagesRef.current = messages;\n const historyRequestRef = useRef(false);\n const historyRequestIdRef = useRef(0);\n const historyRequestControllerRef = useRef<AbortController | null>(null);\n const historyRefreshRef = useRef(false);\n const historyRefreshIdRef = useRef(0);\n const historyRefreshControllerRef = useRef<AbortController | null>(null);\n const prependAnchorRef = useRef<{\n sessionId?: string;\n firstMessageId?: string;\n messageCount: number;\n scrollTop: number;\n scrollHeight: number;\n } | null>(null);\n const skipNextAutoScrollRef = useRef(false);\n const prependExpiryRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n const loadMoreHistory = useCallback(() => {\n const pagination = historyRef.current;\n const el = listRef.current;\n if (!pagination?.hasMore || pagination.loading || historyRequestRef.current || !el) return;\n\n const direction = pagination.direction ?? \"top\";\n if (direction === \"top\") {\n if (prependExpiryRef.current) clearTimeout(prependExpiryRef.current);\n const currentMessages = messagesRef.current;\n prependAnchorRef.current = {\n sessionId: prevSessionIdRef.current,\n firstMessageId: currentMessages[0]?.id,\n messageCount: currentMessages.length,\n scrollTop: el.scrollTop,\n scrollHeight: el.scrollHeight,\n };\n }\n\n historyRequestRef.current = true;\n const requestId = ++historyRequestIdRef.current;\n const controller = new AbortController();\n historyRequestControllerRef.current = controller;\n void Promise.resolve()\n .then(() => pagination.onLoadMore({ signal: controller.signal }))\n .catch(() => {\n if (requestId !== historyRequestIdRef.current || controller.signal.aborted) return;\n prependAnchorRef.current = null;\n antdMessage.error(\"加载历史消息失败,请重试\");\n })\n .finally(() => {\n if (requestId === historyRequestIdRef.current) {\n historyRequestRef.current = false;\n historyRequestControllerRef.current = null;\n // 没有新页时解除滚动锚点,避免后续正常消息被误认为 prepend。\n prependExpiryRef.current = setTimeout(() => {\n prependAnchorRef.current = null;\n prependExpiryRef.current = null;\n }, 500);\n }\n });\n }, []);\n\n const refreshHistory = useCallback(() => {\n const pagination = historyRef.current;\n if (!pagination?.onRefresh || pagination.refreshing || historyRefreshRef.current) return;\n historyRefreshRef.current = true;\n const requestId = ++historyRefreshIdRef.current;\n const controller = new AbortController();\n historyRefreshControllerRef.current = controller;\n void Promise.resolve()\n .then(() => pagination.onRefresh?.({ signal: controller.signal }))\n .catch(() => {\n if (!controller.signal.aborted) antdMessage.error(\"刷新历史消息失败,请重试\");\n })\n .finally(() => {\n if (requestId === historyRefreshIdRef.current) {\n historyRefreshRef.current = false;\n historyRefreshControllerRef.current = null;\n }\n });\n }, []);\n\n useLayoutEffect(() => {\n const anchor = prependAnchorRef.current;\n const el = listRef.current;\n if (!anchor || !el) return;\n if (anchor.sessionId !== sessionId) {\n prependAnchorRef.current = null;\n return;\n }\n if (messages.length <= anchor.messageCount || messages[0]?.id === anchor.firstMessageId) return;\n\n el.scrollTop = anchor.scrollTop + el.scrollHeight - anchor.scrollHeight;\n skipNextAutoScrollRef.current = true;\n prependAnchorRef.current = null;\n if (prependExpiryRef.current) clearTimeout(prependExpiryRef.current);\n prependExpiryRef.current = null;\n }, [messages, sessionId]);\n\n // 暴露命令式 API\n const scrollToBottom = useCallback((behavior: ScrollBehavior = \"auto\") => {\n messagesEndRef.current?.scrollIntoView({ behavior });\n }, []);\n const getScrollContainer = useCallback(() => listRef.current, []);\n const getMessagePosition = useCallback((messageId: string) => {\n const list = listRef.current;\n if (!list) return null;\n const group = Array.from(list.children).find(\n (element) =>\n element instanceof HTMLElement && element.dataset.messageId === messageId,\n );\n if (!group) return null;\n return group.getBoundingClientRect().top - list.getBoundingClientRect().top + list.scrollTop;\n }, []);\n const scrollToMessage = useCallback(\n (messageId: string, behavior: ScrollBehavior = \"smooth\") => {\n const list = listRef.current;\n const top = getMessagePosition(messageId);\n if (list && top !== null) list.scrollTo({ top, behavior });\n },\n [getMessagePosition],\n );\n useImperativeHandle(\n ref,\n () => ({ scrollToBottom, getScrollContainer, getMessagePosition, scrollToMessage }),\n [scrollToBottom, getScrollContainer, getMessagePosition, scrollToMessage],\n );\n const mergedStrategies = useMemo(\n () => mergeChatStrategies(preset, strategies),\n [preset, strategies],\n );\n const mergedMarkdownExtensions = useMemo(\n () => resolvePresetMarkdownExtensions(preset, markdownExtensions),\n [markdownExtensions, preset],\n );\n const resolveToolKind = useCallback(\n (name?: string, msg?: IMessage) =>\n toolKindResolver?.(name) ??\n mergedStrategies.resolveToolKind?.({ name, msg }) ??\n defaultToolKindResolver(name),\n [toolKindResolver, mergedStrategies],\n );\n const parseProcessMessage =\n mergedStrategies.parseProcessMessage ?? parseAgentMessage;\n const resourceLinkSchemes = mergedStrategies.markdownResourceLinkSchemes;\n\n // 初始化完成时滚动到底部\n useEffect(() => {\n if (!initialized) return;\n if (!messages.length) return;\n if (prevInitializedRef.current) return;\n prevInitializedRef.current = true;\n\n const el = listRef.current;\n if (!el) return;\n\n // 用 MutationObserver 监听 DOM 子树变化,等内容渲染稳定后置底\n // 每次 DOM 变化都重新计时,确保所有异步渲染(Markdown、代码高亮、思维链等)完成后再滚动\n let stableTimer: ReturnType<typeof setTimeout>;\n const doScroll = () => {\n messagesEndRef.current?.scrollIntoView({ behavior: \"auto\" });\n };\n\n const observer = new MutationObserver(() => {\n clearTimeout(stableTimer);\n stableTimer = setTimeout(doScroll, 80);\n });\n\n observer.observe(el, {\n childList: true,\n subtree: true,\n characterData: true,\n });\n\n // 立即执行一次,处理内容已经就绪的情况\n doScroll();\n // 兜底:最多等 500ms 后强制滚动并断开观察\n const maxTimer = setTimeout(() => {\n observer.disconnect();\n doScroll();\n }, 500);\n\n return () => {\n clearTimeout(stableTimer);\n clearTimeout(maxTimer);\n observer.disconnect();\n };\n }, [initialized, messages]);\n\n // 会话切换时重置滚动状态,允许重新触发初始化置底\n useEffect(() => {\n if (sessionId === undefined) return; // 未传 sessionId 不处理\n if (prevSessionIdRef.current === sessionId) return; // 同一会话不处理\n prevSessionIdRef.current = sessionId;\n prevInitializedRef.current = false;\n userHasScrolledRef.current = false;\n historyRequestControllerRef.current?.abort();\n historyRefreshControllerRef.current?.abort();\n prependAnchorRef.current = null;\n historyRequestRef.current = false;\n historyRequestIdRef.current += 1;\n historyRefreshRef.current = false;\n historyRefreshIdRef.current += 1;\n if (prependExpiryRef.current) clearTimeout(prependExpiryRef.current);\n prependExpiryRef.current = null;\n }, [sessionId]);\n\n useEffect(() => () => {\n historyRequestControllerRef.current?.abort();\n historyRefreshControllerRef.current?.abort();\n if (prependExpiryRef.current) clearTimeout(prependExpiryRef.current);\n }, []);\n\n // 新增用户消息代表一次主动发送,应无条件恢复跟随并置底。\n // 之后的流式回复继续沿用“用户未主动上滚时跟随”的规则。\n useEffect(() => {\n const previousCount = previousMessageCountRef.current;\n previousMessageCountRef.current = messages.length;\n if (skipNextAutoScrollRef.current || prependAnchorRef.current) {\n skipNextAutoScrollRef.current = false;\n return;\n }\n const hasNewUserMessage = messages\n .slice(previousCount)\n .some((message) => message.role === \"user\");\n if (hasNewUserMessage) {\n userHasScrolledRef.current = false;\n }\n if (userHasScrolledRef.current) return;\n if (!messages.length) return;\n const el = listRef.current;\n if (el) {\n el.scrollTop = el.scrollHeight;\n }\n }, [loading, messages]);\n\n // loading 结束时(流式输出完成),操作栏(metaFooter)会渲染出来增加高度,\n // 需要延迟滚动到底部,确保操作栏可见\n const prevLoadingRef = useRef(loading);\n useEffect(() => {\n const wasLoading = prevLoadingRef.current;\n prevLoadingRef.current = loading;\n\n if (!wasLoading || loading) return; // 只在 loading true → false 时触发\n if (userHasScrolledRef.current) return;\n if (!messages.length) return;\n\n // 延迟等待操作栏 DOM 渲染完成后再滚动\n const timer = setTimeout(() => {\n const el = listRef.current;\n if (el) {\n el.scrollTop = el.scrollHeight;\n }\n }, 50);\n return () => clearTimeout(timer);\n }, [loading, messages]);\n\n // 处理滚动事件\n const handleScroll = useCallback(() => {\n const el = listRef.current;\n if (!el) return;\n const currentTop = el.scrollTop;\n\n if (currentTop < lastScrollTopRef.current) {\n userHasScrolledRef.current = true;\n }\n\n const isAtBottom =\n Math.abs(el.scrollHeight - currentTop - el.clientHeight) <=\n scrollThreshold;\n if (isAtBottom) {\n userHasScrolledRef.current = false;\n }\n\n const pagination = historyRef.current;\n if (pagination?.hasMore) {\n const threshold = pagination.threshold ?? 80;\n const atLoadEdge =\n (pagination.direction ?? \"top\") === \"top\"\n ? currentTop <= threshold\n : el.scrollHeight - currentTop - el.clientHeight <= threshold;\n if (atLoadEdge) loadMoreHistory();\n }\n\n lastScrollTopRef.current = currentTop;\n }, [loadMoreHistory]);\n\n useEffect(() => {\n const listElement = listRef.current;\n if (!listElement) return;\n\n listElement.addEventListener(\"scroll\", handleScroll);\n return () => {\n listElement.removeEventListener(\"scroll\", handleScroll);\n };\n }, [handleScroll]);\n\n // 首屏内容不足一屏时没有滚动事件,继续按需加载直到内容可滚动或数据耗尽。\n useEffect(() => {\n if (!initialized || !history?.hasMore || history.loading) return;\n const el = listRef.current;\n if (el && el.scrollHeight <= el.clientHeight + 1) loadMoreHistory();\n }, [history?.hasMore, history?.loading, initialized, loadMoreHistory, messages]);\n\n // ========== 消息分组逻辑 ==========\n const chatGroups = useMemo(() => {\n if (!enableGrouping) {\n // 不分组,每条消息独立\n return messages.map((msg) => ({\n id: msg.id,\n role: msg.role,\n msgs: [msg],\n invocationId: msg.invocationId,\n allFiles: msg.fileData || [],\n isLike: msg.isLike ?? 0,\n }));\n }\n\n const groups: ChatGroup[] = [];\n messages.forEach((msg) => {\n // 过滤 followup 消息\n if ((msg as any).role === \"followup\") return;\n\n const isRealUserQuery =\n msg.role === \"user\" && !msg.functionResponse && !msg.functionCall;\n const lastGroup = groups[groups.length - 1];\n const isLastGroupAgent = lastGroup?.role === \"bot\";\n\n if (isLastGroupAgent && !isRealUserQuery) {\n // 合并到上一个 bot 分组\n lastGroup.msgs.push(msg);\n if (msg.invocationId) lastGroup.invocationId = msg.invocationId;\n // 更新 isLike: 取最新的非0值,或保持当前值\n if (msg.isLike && msg.isLike !== 0) {\n lastGroup.isLike = msg.isLike;\n }\n } else {\n // 创建新分组\n groups.push({\n id: msg.id || `group-${groups.length}`,\n role: isRealUserQuery ? \"user\" : \"bot\",\n msgs: [msg],\n invocationId: msg.invocationId,\n allFiles: [],\n isLike: msg.isLike ?? 0,\n });\n }\n });\n\n // 合并文件\n groups.forEach((g) => {\n g.allFiles = g.msgs.reduce(\n (acc, m) => [...acc, ...(m.fileData || [])],\n [] as any[],\n );\n });\n\n return groups;\n }, [messages, enableGrouping]);\n\n // ========== 渲染 Bot 消息组 ==========\n const renderBotGroup = useCallback(\n (\n group: ChatGroup,\n isLastGroup: boolean,\n renderFunctionCall?: XAdkChatbotProps[\"renderFunctionCall\"],\n ) => {\n const { msgs, allFiles } = group;\n\n if (!enableProcessParsing) {\n // 不解析 process,简单渲染\n return (\n <div key={group.id} className={styles.botMsg} data-message-id={group.id}>\n {msgs.map((msg, i) => {\n if (msg.text) {\n return (\n <MarkdownRender\n key={`${msg.id}-${i}`}\n text={msg.text}\n resourceLinkSchemes={resourceLinkSchemes}\n onFileClick={onFileClick}\n onResourceLinkClick={onResourceLinkClick}\n renderResourceLink={renderResourceLink}\n markdownExtensions={mergedMarkdownExtensions}\n />\n );\n }\n if (msg.functionCall) {\n return (\n renderFunctionCall?.(msg) ?? (\n <FunctionCallRender\n key={`${msg.id}-${i}`}\n msg={msg}\n showDetail={showFnCallDetail}\n onConfirm={onConfirm}\n kind={resolveToolKind(msg.functionCall?.name, msg)}\n renderApproval={mergedStrategies.renderApproval}\n renderHandoff={mergedStrategies.renderHandoff}\n />\n )\n );\n }\n return null;\n })}\n </div>\n );\n }\n\n // ========== 解析 Process 内容 ==========\n\n // 1. 合并工具调用\n const mergedToolMap = new Map<string, IMessage>();\n msgs.forEach((msg) => {\n if (msg.functionCall) {\n const callId = msg.functionCall.id || \"\";\n if (!mergedToolMap.has(callId)) {\n mergedToolMap.set(callId, { ...msg });\n } else {\n mergedToolMap.set(callId, {\n ...(mergedToolMap.get(callId) ?? {}),\n ...msg,\n });\n }\n } else if (msg.functionResponse) {\n const callId = msg.functionResponse.id || \"\";\n if (mergedToolMap.has(callId)) {\n const tool = mergedToolMap.get(callId);\n if (tool) tool.functionResponse = msg.functionResponse;\n } else {\n mergedToolMap.set(callId, {\n ...msg,\n functionCall: {\n id: callId,\n name: msg.functionResponse.name || \"Unknown\",\n args: {},\n },\n });\n }\n }\n });\n\n // 2. 解析文本消息中的 process 内容\n type RenderNode =\n | { type: \"text\"; content: string; key: string }\n | { type: \"process\"; items: ThoughtChainItemType[]; key: string };\n\n const nodes: RenderNode[] = [];\n let currentProcessItems: ThoughtChainItemType[] = [];\n const processedToolIds = new Set<string>();\n\n const flushProcessItems = () => {\n if (currentProcessItems.length > 0) {\n nodes.push({\n type: \"process\",\n items: [...currentProcessItems],\n key: `process-${nodes.length}`,\n });\n currentProcessItems = [];\n }\n };\n\n msgs.forEach((msg) => {\n // 处理工具调用\n if (msg.functionCall) {\n const callId = msg.functionCall.id || \"\";\n if (!processedToolIds.has(callId)) {\n const mergedMsg = mergedToolMap.get(callId);\n if (mergedMsg) {\n currentProcessItems.push({\n type: \"tool\",\n key: `tool-${callId}`,\n content: \"\",\n msg: mergedMsg,\n });\n processedToolIds.add(callId);\n }\n }\n }\n // 处理文本消息\n else if (msg.text && !msg.functionResponse) {\n const parts = parseProcessMessage(msg.text, parseOptions as any);\n\n parts.forEach((part, partIdx) => {\n // process 内容放入 currentProcessItems\n if (\n [\n \"planning\",\n \"replanning\",\n \"reasoning\",\n \"action_log\",\n \"process_text\",\n ].includes(part.type)\n ) {\n const titleMap: Record<string, string> = {\n planning: \"任务规划\",\n replanning: \"重新规划\",\n reasoning: \"推理分析\",\n action_log: \"行动记录\",\n process_text: \"过程分析\",\n };\n\n currentProcessItems.push({\n type: \"text\",\n key: `${msg.id}-${partIdx}`,\n content: part.content,\n title: titleMap[part.type] || \"分析\",\n });\n }\n // 普通文本内容\n else {\n flushProcessItems();\n if (part.content.trim()) {\n const lastNode = nodes[nodes.length - 1];\n if (lastNode?.type === \"text\") {\n // 合并到上一个文本节点\n lastNode.content += \"\\n\\n\" + part.content;\n } else {\n nodes.push({\n type: \"text\",\n content: part.content,\n key: `text-${msg.id}-${partIdx}`,\n });\n }\n }\n }\n });\n }\n });\n\n // 最后flush一次\n flushProcessItems();\n\n // 3. 准备操作栏数据\n const fullTextToCopy = msgs\n .filter((m) => !m.functionCall && !m.functionResponse)\n .map((m) => m.text || \"\")\n .join(\"\");\n\n const lastBotMsg = msgs[msgs.length - 1];\n // const hasProcess = nodes.some((n) => n.type === \"process\");\n const isGroupLoading = loading && isLastGroup;\n const actionProps = { message: group, isLastBotMsg: isLastGroup };\n const actionExtraNode = actionsExtra?.(actionProps);\n\n // 4. 渲染\n // 确认 [规划, 工具调用, 中途说明, 工具调用, 最终回答]\n const firstProcessIdx = nodes.findIndex((n) => n.type === \"process\");\n const lastProcessIdx = nodes.findLastIndex((n) => n.type === \"process\");\n const processItems: ThoughtChainItemType[] = nodes\n .slice(firstProcessIdx, lastProcessIdx + 1)\n .flatMap((node) =>\n node.type === \"process\"\n ? node.items\n : [\n {\n type: \"text\",\n key: node.key,\n title: \"过程分析\",\n content: node.content,\n },\n ],\n );\n const activeItem = processItems[processItems.length - 1];\n const activeStep =\n activeItem?.type === \"tool\"\n ? String(\n activeItem.msg?.functionCall?.args?.agentName ||\n activeItem.msg?.functionCall?.args?.componentName ||\n activeItem.msg?.functionCall?.name ||\n \"\",\n )\n : typeof activeItem?.title === \"string\"\n ? activeItem.title\n : \"\";\n return (\n <div key={group.id} className={styles.botMsg} data-message-id={group.id}>\n {nodes.map((node, idx) => {\n if (\n node.type === \"text\" &&\n idx > firstProcessIdx &&\n idx < lastProcessIdx\n ) {\n return null;\n }\n if (node.type === \"process\") {\n // 同一轮回复中的过程节点共用一个容器,保留节点自身的执行顺序。\n if (idx !== firstProcessIdx) {\n return null;\n }\n return (\n <XAdkThoughtChain\n key={node.key}\n collapsible\n loading={isGroupLoading}\n title=\"已完成\"\n activeStep={activeStep}\n items={processItems}\n showFnCallDetail={showFnCallDetail}\n onConfirm={onConfirm}\n defaultOpen={isGroupLoading}\n renderFunctionCall={renderFunctionCall}\n toolKindResolver={(name) => resolveToolKind(name)}\n strategies={mergedStrategies}\n />\n );\n }\n\n // 文本节点\n // const showBadge =\n // hasProcess && nodes.findIndex((n) => n.type === \"text\") === idx;\n return (\n <div key={node.key}>\n {/* {showBadge && (\n <div className={styles.successBadge}>\n <CheckCircleFilled /> 已完成所有规划任务\n </div>\n )} */}\n <MarkdownRender\n text={node.content}\n resourceLinkSchemes={resourceLinkSchemes}\n onFileClick={onFileClick}\n onResourceLinkClick={onResourceLinkClick}\n renderResourceLink={renderResourceLink}\n markdownExtensions={mergedMarkdownExtensions}\n />\n </div>\n );\n })}\n\n {/* 文件展示 */}\n {allFiles.length > 0 && (\n <div className={styles.fileSection}>\n <div className={styles.fileHeader}>\n <span>生成文件 ({allFiles.length})</span>\n </div>\n <div style={{ display: \"flex\", flexWrap: \"wrap\", gap: \"8px\" }}>\n {allFiles.map((file, index) => (\n <FileGallery\n key={index}\n file={file}\n onClick={onFileClick}\n />\n ))}\n </div>\n </div>\n )}\n\n {/* 操作栏 */}\n {!isGroupLoading &&\n (actions ||\n showRetry ||\n showCopy ||\n showLog ||\n actionExtraNode) && (\n <div className={styles.metaFooter}>\n {actions ? (\n actions(actionProps)\n ) : (\n <Flex gap={16} className={styles.actionIcons}>\n {showRetry && isLastGroup && (\n <Tooltip title=\"重新生成\">\n <ReloadOutlined onClick={onRetry} />\n </Tooltip>\n )}\n {showCopy && (\n <Tooltip title=\"复制内容\">\n <CopyOutlined\n onClick={() => {\n copy(fullTextToCopy);\n antdMessage.success(\"复制成功\");\n onCopy?.(fullTextToCopy);\n }}\n />\n </Tooltip>\n )}\n {showLog && lastBotMsg?.invocationId && (\n <Tooltip title=\"查看日志\">\n <InfoCircleOutlined\n onClick={() =>\n onShowLog?.(\n lastBotMsg.invocationId!,\n lastBotMsg.timestamp,\n )\n }\n />\n </Tooltip>\n )}\n </Flex>\n )}\n {actionExtraNode}\n </div>\n )}\n </div>\n );\n },\n [\n enableProcessParsing,\n parseOptions,\n parseProcessMessage,\n showFnCallDetail,\n onConfirm,\n loading,\n showRetry,\n showCopy,\n showLog,\n onRetry,\n onCopy,\n onShowLog,\n actions,\n actionsExtra,\n onFileClick,\n onResourceLinkClick,\n renderResourceLink,\n mergedMarkdownExtensions,\n resourceLinkSchemes,\n styles,\n resolveToolKind,\n mergedStrategies,\n ],\n );\n\n // ========== 渲染用户消息组 ==========\n const renderUserGroup = useCallback(\n (group: ChatGroup, nextGroup?: ChatGroup) => {\n const compactWithNextText =\n group.msgs.some((message) => Boolean(message.fileData?.length)) &&\n group.msgs.every((message) => !message.text?.trim()) &&\n nextGroup?.role === \"user\" &&\n nextGroup.msgs.some((message) => Boolean(message.text?.trim()));\n return (\n <div\n key={group.id}\n className={styles.userMsg}\n data-message-id={group.id}\n style={compactWithNextText ? { marginBottom: 8 } : undefined}\n >\n {group.msgs.map((m, i) => (\n <div key={m.id || i} className={styles.userContainer}>\n {/* 文件展示 */}\n {m.fileData && m.fileData.length > 0 && (\n <>\n {m.fileData.map((file, index) => (\n <FileGallery\n key={index}\n file={file}\n align=\"left\"\n style={{\n marginBottom:\n compactWithNextText &&\n i === group.msgs.length - 1 &&\n index === m.fileData!.length - 1\n ? 0\n : 16,\n }}\n onClick={onFileClick}\n />\n ))}\n </>\n )}\n {/* 文本展示 */}\n {m.text && (\n <div\n className={styles.card}\n data-xadk-user-card\n onCopy={(event) => {\n // 富文本标签的可见文案不含协议;复制用户消息时保留原始 Markdown,\n // 使内容粘贴回 XAdkSender 后能重新还原成 Mention。\n // 若有选区则只复制选区内容(变量模块取完整文案),否则复制全量。\n event.preventDefault();\n const selected = getSelectionText(event.currentTarget);\n event.clipboardData.setData(\n \"text/plain\",\n selected || m.text || \"\",\n );\n }}\n >\n <MarkdownRender\n text={m.text}\n compact\n bareUrlAsText\n highlightPlainMentions\n resourceLinkSchemes={resourceLinkSchemes}\n onFileClick={onFileClick}\n onResourceLinkClick={onResourceLinkClick}\n renderResourceLink={renderResourceLink}\n markdownExtensions={mergedMarkdownExtensions}\n />\n </div>\n )}\n </div>\n ))}\n {/* 一轮用户消息可能拆成文件和文本多个片段,操作栏只放在整组末尾。 */}\n {showUserActions && group.msgs.some((message) => Boolean(message.text?.trim())) && (\n <div className={`x-user-actions ${styles.userActions}`}>\n {userActions?.({ message: group }) ?? (\n <>\n <span className={styles.userTime}>\n {formatTimestamp(group.msgs[group.msgs.length - 1]?.timestamp)}\n </span>\n <Tooltip title=\"复制内容\">\n <CopyOutlined\n className={styles.userActionIcon}\n onClick={() => {\n const container = document.querySelector(\n `[data-message-id=\"${group.id}\"]`,\n );\n const selected = getSelectionText(container as HTMLElement | null);\n const fullText = group.msgs.map((message) => message.text || \"\").join(\"\");\n copy(selected || fullText);\n antdMessage.success(\"复制成功\");\n }}\n />\n </Tooltip>\n </>\n )}\n </div>\n )}\n </div>\n );\n },\n [\n styles,\n onFileClick,\n onResourceLinkClick,\n renderResourceLink,\n mergedMarkdownExtensions,\n resourceLinkSchemes,\n showUserActions,\n userActions,\n ],\n );\n\n // ========== 空状态 ==========\n\n // ========== 渲染建议问题 ==========\n const renderSuggestions = () => {\n if (!suggestions || suggestions.length === 0) return null;\n\n return (\n <div className={styles.suggestionWrapper}>\n {suggestions.map((item) => (\n <div key={item} className={styles.suggestion}>\n <div className={styles.suggestContent}>\n <Button\n type=\"text\"\n icon={<SwapRightOutlined />}\n iconPlacement=\"end\"\n onClick={() => {\n if (!item) return;\n onSuggest?.(item);\n }}\n style={{\n whiteSpace: \"normal\",\n height: \"auto\",\n wordWrap: \"break-word\",\n textAlign: \"left\",\n padding: \"4px 15px\",\n lineHeight: \"1.5\",\n }}\n >\n {item}\n </Button>\n </div>\n </div>\n ))}\n </div>\n );\n };\n\n // 空状态判断\n const isEmpty =\n messages.length === 0 &&\n !prologue &&\n (!suggestions || suggestions.length === 0);\n\n const historyControls = history && (history.hasMore || history.loading || history.onRefresh) && (\n <div className={styles.historyControls}>\n {history.onRefresh && (\n <button type=\"button\" onClick={refreshHistory} disabled={history.refreshing}>\n {history.refreshing ? \"正在刷新...\" : \"刷新\"}\n </button>\n )}\n {(history.hasMore || history.loading) && (\n <button type=\"button\" onClick={loadMoreHistory} disabled={history.loading}>\n {history.loading ? \"正在加载...\" : \"加载更多\"}\n </button>\n )}\n </div>\n );\n\n return (\n <div className={clsx(styles.wrapper, className)} style={style}>\n {/* 空状态 */}\n {isEmpty && empty && (\n <div className={styles.emptyWrapper}>\n {typeof empty === \"function\" ? empty() : empty}\n </div>\n )}\n\n <div\n className={styles.list}\n ref={listRef}\n style={isEmpty ? { flex: 0 } : undefined}\n >\n {(history?.direction ?? \"top\") === \"top\" && historyControls}\n {/* 开场白 */}\n {prologue && (\n <div className={styles.prologue}>\n <MarkdownRender\n text={prologue}\n resourceLinkSchemes={resourceLinkSchemes}\n onFileClick={onFileClick}\n onResourceLinkClick={onResourceLinkClick}\n renderResourceLink={renderResourceLink}\n markdownExtensions={mergedMarkdownExtensions}\n />\n </div>\n )}\n\n {/* 消息列表 */}\n {chatGroups.map((group, idx) => {\n const context = {\n group,\n index: idx,\n previousGroup: chatGroups[idx - 1],\n nextGroup: chatGroups[idx + 1],\n };\n const defaultNode =\n group.role === \"user\"\n ? renderUserGroup(group, chatGroups[idx + 1])\n : renderBotGroup(group, idx === chatGroups.length - 1, renderFunctionCall);\n const customNode = renderGroup?.({ ...context, defaultNode });\n return (\n <Fragment key={group.id}>\n {renderBeforeGroup?.(context)}\n {customNode === undefined ? defaultNode : customNode}\n {renderAfterGroup?.(context)}\n </Fragment>\n );\n })}\n\n {history?.direction === \"bottom\" && historyControls}\n\n {/* 建议问题 */}\n {renderSuggestions()}\n\n <div ref={messagesEndRef} />\n </div>\n </div>\n );\n },\n);\n\nXAdkChatbot.displayName = \"XAdkChatbot\";\n\nexport default XAdkChatbot;\n"],
5
+ "mappings": "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",
6
+ "names": ["import_utils", "import_FunctionCallRender", "antdMessage", "renderFunctionCall", "_a", "MarkdownRender", "FunctionCallRender", "XAdkThoughtChain", "FileGallery", "copy", "clsx"]
7
7
  }
@@ -1,11 +1,15 @@
1
1
  export declare const useStyles: () => {
2
2
  wrapper: string;
3
3
  list: string;
4
+ historyControls: string;
4
5
  prologue: string;
5
6
  suggestion: string;
6
7
  suggestContent: string;
7
8
  userMsg: string;
8
9
  userContainer: string;
10
+ userActions: string;
11
+ userTime: string;
12
+ userActionIcon: string;
9
13
  card: string;
10
14
  botMsg: string;
11
15
  emptyWrapper: string;
@@ -71,6 +71,32 @@ var useStyles = (0, import_common.withBasicStyles)(() => ({
71
71
  /* IE 10+ */
72
72
  -ms-overflow-style: none;
73
73
  `,
74
+ historyControls: import_css.css`
75
+ display: flex;
76
+ justify-content: center;
77
+ gap: 12px;
78
+ padding: 8px 0;
79
+ color: #7b8494;
80
+ font-size: 12px;
81
+
82
+ button {
83
+ border: 0;
84
+ background: transparent;
85
+ color: inherit;
86
+ cursor: pointer;
87
+ padding: 4px 8px;
88
+ border-radius: 4px;
89
+ }
90
+
91
+ button:hover:not(:disabled) {
92
+ background: #f3f5f9;
93
+ }
94
+
95
+ button:disabled {
96
+ cursor: default;
97
+ opacity: 0.7;
98
+ }
99
+ `,
74
100
  prologue: import_css.css`
75
101
  margin-bottom: 12px;
76
102
  `,
@@ -84,10 +110,16 @@ var useStyles = (0, import_common.withBasicStyles)(() => ({
84
110
  `,
85
111
  userMsg: import_css.css`
86
112
  display: flex;
87
- justify-content: flex-end;
113
+ flex-direction: column;
114
+ align-items: flex-end;
88
115
  width: 100%;
89
116
  min-width: 0;
90
- margin-bottom: 24px;
117
+ margin-bottom: 12px;
118
+
119
+ &:hover .x-user-actions {
120
+ opacity: 1;
121
+ pointer-events: auto;
122
+ }
91
123
  `,
92
124
  userContainer: import_css.css`
93
125
  display: flex;
@@ -96,6 +128,31 @@ var useStyles = (0, import_common.withBasicStyles)(() => ({
96
128
  align-items: flex-end;
97
129
  min-width: 0;
98
130
  max-width: 100%;
131
+
132
+ `,
133
+ userActions: import_css.css`
134
+ &.x-user-actions {
135
+ display: flex;
136
+ align-items: center;
137
+ gap: 8px;
138
+ padding: 4px 0;
139
+ opacity: 0;
140
+ transition: opacity 0.2s;
141
+ pointer-events: none;
142
+ }
143
+ `,
144
+ userTime: import_css.css`
145
+ font-size: 12px;
146
+ color: rgba(0, 0, 0, 0.45);
147
+ `,
148
+ userActionIcon: import_css.css`
149
+ cursor: pointer;
150
+ color: rgba(0, 0, 0, 0.45);
151
+ transition: color 0.2s;
152
+
153
+ &:hover {
154
+ color: #1890ff;
155
+ }
99
156
  `,
100
157
  card: import_css.css`
101
158
  display: inline-block;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/components/XAdkChatbot/styles.tsx"],
4
- "sourcesContent": ["import { css } from \"@emotion/css\";\nimport { withBasicStyles } from \"@/styles/common\";\n\nexport const useStyles = withBasicStyles(() => ({\n wrapper: css`\n padding: 0 16px;\n /* 作为 flex 子项时必须允许收缩,消息滚动由内部 list 承担。 */\n min-height: 0;\n height: 100%;\n box-sizing: border-box;\n overflow: hidden;\n border-radius: 8px;\n display: flex;\n flex-direction: column;\n\n .x-markdown {\n --margin-ul-ol: 0 0 1em 1em;\n\n code {\n background: rgba(150, 150, 150, 0.2);\n border-radius: 3px;\n }\n\n .ant-highlightCode-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n color: var(--ant-highlight-code-color-text-title);\n background: var(--ant-highlight-code-color-bg-title);\n padding: var(--ant-padding-sm);\n border-top-left-radius: var(--ant-border-radius);\n border-top-right-radius: var(--ant-border-radius);\n }\n }\n `,\n\n list: css`\n flex: 1;\n min-height: 0;\n margin-top: 16px;\n overflow-y: auto;\n /* Chrome, Safari, Edge, Opera */\n &::-webkit-scrollbar {\n display: none;\n }\n /* Firefox */\n scrollbar-width: none;\n /* IE 10+ */\n -ms-overflow-style: none;\n `,\n\n prologue: css`\n margin-bottom: 12px;\n `,\n\n suggestion: css`\n margin-bottom: 12px;\n `,\n\n suggestContent: css`\n display: inline-flex;\n border: 2px solid #e7e7e7;\n border-radius: 8px;\n `,\n\n userMsg: css`\n display: flex;\n justify-content: flex-end;\n width: 100%;\n min-width: 0;\n margin-bottom: 24px;\n `,\n\n userContainer: css`\n display: flex;\n flex-direction: column;\n justify-content: flex-end;\n align-items: flex-end;\n min-width: 0;\n max-width: 100%;\n `,\n\n card: css`\n display: inline-block;\n box-sizing: border-box;\n min-width: 0;\n padding: 12px 16px;\n background: #d5e3ff;\n border-radius: 12px;\n max-width: 100%;\n white-space: pre-line;\n overflow-wrap: anywhere;\n word-break: break-word;\n `,\n\n botMsg: css`\n margin-bottom: 12px;\n `,\n\n emptyWrapper: css`\n display: flex;\n align-items: center;\n justify-content: center;\n flex: 1;\n min-height: 200px;\n `,\n\n // 新增样式\n welcomeWrapper: css`\n display: flex;\n flex-direction: column;\n align-items: center;\n padding: 40px 20px;\n text-align: center;\n `,\n\n welcomeIcon: css`\n width: 64px;\n height: 64px;\n border-radius: 12px;\n margin-bottom: 16px;\n `,\n\n welcomeTitle: css`\n font-size: 24px;\n font-weight: 600;\n color: rgba(0, 0, 0, 0.88);\n margin-bottom: 8px;\n `,\n\n welcomeDesc: css`\n font-size: 14px;\n color: rgba(0, 0, 0, 0.65);\n margin-bottom: 24px;\n `,\n\n suggestionWrapper: css`\n margin-top: 16px;\n `,\n\n successBadge: css`\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 4px 12px;\n background: #f6ffed;\n border: 1px solid #b7eb8f;\n border-radius: 4px;\n color: #52c41a;\n font-size: 13px;\n margin-bottom: 12px;\n `,\n\n fileSection: css`\n margin: 12px 0;\n `,\n\n fileHeader: css`\n font-size: 13px;\n color: rgba(0, 0, 0, 0.65);\n margin-bottom: 8px;\n `,\n\n metaFooter: css`\n display: flex;\n align-items: center;\n flex-wrap: wrap;\n gap: 16px;\n margin-top: 12px;\n padding-top: 12px;\n border-top: 1px solid #f0f0f0;\n `,\n\n actionIcons: css`\n color: rgba(0, 0, 0, 0.45);\n\n & > span {\n cursor: pointer;\n transition: color 0.2s;\n\n &:hover {\n color: #1890ff;\n }\n }\n `,\n\n fnCall: css`\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 11px;\n border-radius: 24px;\n line-height: 16px;\n border: 1px solid #e7e7e7;\n cursor: pointer;\n `,\n\n confirm: css`\n padding: 12px;\n border-radius: 12px;\n border: 1px solid #e7e7e7;\n `,\n\n footer: css`\n /* senderWrap and tip moved to top-level keys so they are\n accessible as styles.senderWrap and styles.tip in the component */\n `,\n\n sender: css`\n width: 100%;\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 8px 8px 12px;\n border: 1px solid #e7e7e7;\n border-radius: 24px;\n\n /* .input moved to top-level key so component can use styles.input */\n `,\n\n senderWrap: css`\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n `,\n\n tip: css`\n padding: 4px;\n font-size: 12px;\n text-align: center;\n color: rgba(0, 0, 0, 0.4);\n `,\n\n input: css`\n padding: 0;\n margin: 5px 0;\n line-height: 22px;\n font-size: 15px;\n border-radius: 0;\n border: none;\n\n &:focus {\n box-shadow: none;\n }\n `,\n}));\n\nexport default useStyles;\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,iBAAoB;AACpB,oBAAgC;AAEzB,IAAM,gBAAY,+BAAgB,OAAO;AAAA,EAC9C,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgCT,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeN,UAAU;AAAA;AAAA;AAAA,EAIV,YAAY;AAAA;AAAA;AAAA,EAIZ,gBAAgB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMhB,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQT,eAAe;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASf,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaN,QAAQ;AAAA;AAAA;AAAA,EAIR,cAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASd,gBAAgB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQhB,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOb,cAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOd,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA,EAMb,mBAAmB;AAAA;AAAA;AAAA,EAInB,cAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAad,aAAa;AAAA;AAAA;AAAA,EAIb,YAAY;AAAA;AAAA;AAAA;AAAA;AAAA,EAMZ,YAAY;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUZ,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAab,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWR,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA,EAMT,QAAQ;AAAA;AAAA;AAAA;AAAA,EAKR,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYR,YAAY;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOZ,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOL,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAYT,EAAE;AAEF,IAAO,iBAAQ;",
4
+ "sourcesContent": ["import { css } from \"@emotion/css\";\nimport { withBasicStyles } from \"@/styles/common\";\n\nexport const useStyles = withBasicStyles(() => ({\n wrapper: css`\n padding: 0 16px;\n /* 作为 flex 子项时必须允许收缩,消息滚动由内部 list 承担。 */\n min-height: 0;\n height: 100%;\n box-sizing: border-box;\n overflow: hidden;\n border-radius: 8px;\n display: flex;\n flex-direction: column;\n\n .x-markdown {\n --margin-ul-ol: 0 0 1em 1em;\n\n code {\n background: rgba(150, 150, 150, 0.2);\n border-radius: 3px;\n }\n\n .ant-highlightCode-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n color: var(--ant-highlight-code-color-text-title);\n background: var(--ant-highlight-code-color-bg-title);\n padding: var(--ant-padding-sm);\n border-top-left-radius: var(--ant-border-radius);\n border-top-right-radius: var(--ant-border-radius);\n }\n }\n `,\n\n list: css`\n flex: 1;\n min-height: 0;\n margin-top: 16px;\n overflow-y: auto;\n /* Chrome, Safari, Edge, Opera */\n &::-webkit-scrollbar {\n display: none;\n }\n /* Firefox */\n scrollbar-width: none;\n /* IE 10+ */\n -ms-overflow-style: none;\n `,\n\n historyControls: css`\n display: flex;\n justify-content: center;\n gap: 12px;\n padding: 8px 0;\n color: #7b8494;\n font-size: 12px;\n\n button {\n border: 0;\n background: transparent;\n color: inherit;\n cursor: pointer;\n padding: 4px 8px;\n border-radius: 4px;\n }\n\n button:hover:not(:disabled) {\n background: #f3f5f9;\n }\n\n button:disabled {\n cursor: default;\n opacity: 0.7;\n }\n `,\n\n prologue: css`\n margin-bottom: 12px;\n `,\n\n suggestion: css`\n margin-bottom: 12px;\n `,\n\n suggestContent: css`\n display: inline-flex;\n border: 2px solid #e7e7e7;\n border-radius: 8px;\n `,\n\n userMsg: css`\n display: flex;\n flex-direction: column;\n align-items: flex-end;\n width: 100%;\n min-width: 0;\n margin-bottom: 12px;\n\n &:hover .x-user-actions {\n opacity: 1;\n pointer-events: auto;\n }\n `,\n\n userContainer: css`\n display: flex;\n flex-direction: column;\n justify-content: flex-end;\n align-items: flex-end;\n min-width: 0;\n max-width: 100%;\n\n `,\n\n userActions: css`\n &.x-user-actions {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 4px 0;\n opacity: 0;\n transition: opacity 0.2s;\n pointer-events: none;\n }\n `,\n\n userTime: css`\n font-size: 12px;\n color: rgba(0, 0, 0, 0.45);\n `,\n\n userActionIcon: css`\n cursor: pointer;\n color: rgba(0, 0, 0, 0.45);\n transition: color 0.2s;\n\n &:hover {\n color: #1890ff;\n }\n `,\n\n card: css`\n display: inline-block;\n box-sizing: border-box;\n min-width: 0;\n padding: 12px 16px;\n background: #d5e3ff;\n border-radius: 12px;\n max-width: 100%;\n white-space: pre-line;\n overflow-wrap: anywhere;\n word-break: break-word;\n `,\n\n botMsg: css`\n margin-bottom: 12px;\n `,\n\n emptyWrapper: css`\n display: flex;\n align-items: center;\n justify-content: center;\n flex: 1;\n min-height: 200px;\n `,\n\n // 新增样式\n welcomeWrapper: css`\n display: flex;\n flex-direction: column;\n align-items: center;\n padding: 40px 20px;\n text-align: center;\n `,\n\n welcomeIcon: css`\n width: 64px;\n height: 64px;\n border-radius: 12px;\n margin-bottom: 16px;\n `,\n\n welcomeTitle: css`\n font-size: 24px;\n font-weight: 600;\n color: rgba(0, 0, 0, 0.88);\n margin-bottom: 8px;\n `,\n\n welcomeDesc: css`\n font-size: 14px;\n color: rgba(0, 0, 0, 0.65);\n margin-bottom: 24px;\n `,\n\n suggestionWrapper: css`\n margin-top: 16px;\n `,\n\n successBadge: css`\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 4px 12px;\n background: #f6ffed;\n border: 1px solid #b7eb8f;\n border-radius: 4px;\n color: #52c41a;\n font-size: 13px;\n margin-bottom: 12px;\n `,\n\n fileSection: css`\n margin: 12px 0;\n `,\n\n fileHeader: css`\n font-size: 13px;\n color: rgba(0, 0, 0, 0.65);\n margin-bottom: 8px;\n `,\n\n metaFooter: css`\n display: flex;\n align-items: center;\n flex-wrap: wrap;\n gap: 16px;\n margin-top: 12px;\n padding-top: 12px;\n border-top: 1px solid #f0f0f0;\n `,\n\n actionIcons: css`\n color: rgba(0, 0, 0, 0.45);\n\n & > span {\n cursor: pointer;\n transition: color 0.2s;\n\n &:hover {\n color: #1890ff;\n }\n }\n `,\n\n fnCall: css`\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 11px;\n border-radius: 24px;\n line-height: 16px;\n border: 1px solid #e7e7e7;\n cursor: pointer;\n `,\n\n confirm: css`\n padding: 12px;\n border-radius: 12px;\n border: 1px solid #e7e7e7;\n `,\n\n footer: css`\n /* senderWrap and tip moved to top-level keys so they are\n accessible as styles.senderWrap and styles.tip in the component */\n `,\n\n sender: css`\n width: 100%;\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 8px 8px 12px;\n border: 1px solid #e7e7e7;\n border-radius: 24px;\n\n /* .input moved to top-level key so component can use styles.input */\n `,\n\n senderWrap: css`\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n `,\n\n tip: css`\n padding: 4px;\n font-size: 12px;\n text-align: center;\n color: rgba(0, 0, 0, 0.4);\n `,\n\n input: css`\n padding: 0;\n margin: 5px 0;\n line-height: 22px;\n font-size: 15px;\n border-radius: 0;\n border: none;\n\n &:focus {\n box-shadow: none;\n }\n `,\n}));\n\nexport default useStyles;\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,iBAAoB;AACpB,oBAAgC;AAEzB,IAAM,gBAAY,+BAAgB,OAAO;AAAA,EAC9C,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgCT,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeN,iBAAiB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA2BjB,UAAU;AAAA;AAAA;AAAA,EAIV,YAAY;AAAA;AAAA;AAAA,EAIZ,gBAAgB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMhB,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcT,eAAe;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUf,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYb,UAAU;AAAA;AAAA;AAAA;AAAA,EAKV,gBAAgB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUhB,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaN,QAAQ;AAAA;AAAA;AAAA,EAIR,cAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASd,gBAAgB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQhB,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOb,cAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOd,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA,EAMb,mBAAmB;AAAA;AAAA;AAAA,EAInB,cAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAad,aAAa;AAAA;AAAA;AAAA,EAIb,YAAY;AAAA;AAAA;AAAA;AAAA;AAAA,EAMZ,YAAY;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUZ,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAab,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWR,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA,EAMT,QAAQ;AAAA;AAAA;AAAA;AAAA,EAKR,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYR,YAAY;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOZ,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOL,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAYT,EAAE;AAEF,IAAO,iBAAQ;",
6
6
  "names": []
7
7
  }
@@ -0,0 +1,14 @@
1
+ /**
2
+ * 将时间戳格式化为 "x月y日 mm:ss" 格式
3
+ *
4
+ * @param ts 毫秒级时间戳
5
+ * @returns 如 "10月14日 09:30",无时间戳时返回 null
6
+ */
7
+ export declare function formatTimestamp(ts?: number): string | null;
8
+ /**
9
+ * 从当前 DOM 选区提取文本,遇到变量模块(带 data-resource-markdown 或
10
+ * data-xadk-resource-link 的元素)时保留完整模块文案,而非只取选中的片段。
11
+ *
12
+ * 无选区或选区不在 container 内时返回 null。
13
+ */
14
+ export declare function getSelectionText(container?: HTMLElement | null): string | null;
@@ -0,0 +1,79 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __export = (target, all) => {
6
+ for (var name in all)
7
+ __defProp(target, name, { get: all[name], enumerable: true });
8
+ };
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") {
11
+ for (let key of __getOwnPropNames(from))
12
+ if (!__hasOwnProp.call(to, key) && key !== except)
13
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
+ }
15
+ return to;
16
+ };
17
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
18
+
19
+ // src/components/XAdkChatbot/utils.ts
20
+ var utils_exports = {};
21
+ __export(utils_exports, {
22
+ formatTimestamp: () => formatTimestamp,
23
+ getSelectionText: () => getSelectionText
24
+ });
25
+ module.exports = __toCommonJS(utils_exports);
26
+ function formatTimestamp(ts) {
27
+ if (!ts)
28
+ return null;
29
+ const d = new Date(ts);
30
+ const month = d.getMonth() + 1;
31
+ const day = d.getDate();
32
+ const mm = String(d.getMinutes()).padStart(2, "0");
33
+ const ss = String(d.getSeconds()).padStart(2, "0");
34
+ return `${month}月${day}日 ${mm}:${ss}`;
35
+ }
36
+ function getSelectionText(container) {
37
+ const sel = window.getSelection();
38
+ if (!sel || sel.isCollapsed || sel.rangeCount === 0)
39
+ return null;
40
+ const range = sel.getRangeAt(0);
41
+ if (container && !container.contains(range.commonAncestorContainer)) {
42
+ return null;
43
+ }
44
+ const fragment = range.cloneContents();
45
+ let result = "";
46
+ fragment.childNodes.forEach((node) => {
47
+ result += extractNodeText(node);
48
+ });
49
+ return result || null;
50
+ }
51
+ function extractNodeText(node) {
52
+ var _a, _b;
53
+ if (node.nodeType === Node.TEXT_NODE) {
54
+ return node.textContent || "";
55
+ }
56
+ if (node.nodeType === Node.ELEMENT_NODE) {
57
+ const el = node;
58
+ const md = (_a = el.getAttribute) == null ? void 0 : _a.call(el, "data-resource-markdown");
59
+ if (md)
60
+ return md;
61
+ if ((_b = el.getAttribute) == null ? void 0 : _b.call(el, "data-xadk-resource-link")) {
62
+ const label = el.getAttribute("aria-label");
63
+ if (label)
64
+ return `@${label}`;
65
+ }
66
+ let text = "";
67
+ el.childNodes.forEach((child) => {
68
+ text += extractNodeText(child);
69
+ });
70
+ return text;
71
+ }
72
+ return "";
73
+ }
74
+ // Annotate the CommonJS export names for ESM import in node:
75
+ 0 && (module.exports = {
76
+ formatTimestamp,
77
+ getSelectionText
78
+ });
79
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/components/XAdkChatbot/utils.ts"],
4
+ "sourcesContent": ["/**\n * 将时间戳格式化为 \"x月y日 mm:ss\" 格式\n *\n * @param ts 毫秒级时间戳\n * @returns 如 \"10月14日 09:30\",无时间戳时返回 null\n */\nexport function formatTimestamp(ts?: number): string | null {\n if (!ts) return null;\n const d = new Date(ts);\n const month = d.getMonth() + 1;\n const day = d.getDate();\n const mm = String(d.getMinutes()).padStart(2, \"0\");\n const ss = String(d.getSeconds()).padStart(2, \"0\");\n return `${month}月${day}日 ${mm}:${ss}`;\n}\n\n/**\n * 从当前 DOM 选区提取文本,遇到变量模块(带 data-resource-markdown 或\n * data-xadk-resource-link 的元素)时保留完整模块文案,而非只取选中的片段。\n *\n * 无选区或选区不在 container 内时返回 null。\n */\nexport function getSelectionText(container?: HTMLElement | null): string | null {\n const sel = window.getSelection();\n if (!sel || sel.isCollapsed || sel.rangeCount === 0) return null;\n\n const range = sel.getRangeAt(0);\n // 选区不在容器内时忽略\n if (container && !container.contains(range.commonAncestorContainer)) {\n return null;\n }\n\n const fragment = range.cloneContents();\n let result = \"\";\n\n fragment.childNodes.forEach((node) => {\n result += extractNodeText(node);\n });\n\n return result || null;\n}\n\n/** 递归提取节点文本,变量模块取完整文案 */\nfunction extractNodeText(node: Node): string {\n if (node.nodeType === Node.TEXT_NODE) {\n return node.textContent || \"\";\n }\n\n if (node.nodeType === Node.ELEMENT_NODE) {\n const el = node as HTMLElement;\n // 优先用 data-resource-markdown(带协议的完整 markdown)\n const md = el.getAttribute?.(\"data-resource-markdown\");\n if (md) return md;\n\n // 变量模块(plain-mention 等):取 aria-label 或完整文本\n if (el.getAttribute?.(\"data-xadk-resource-link\")) {\n const label = el.getAttribute(\"aria-label\");\n if (label) return `@${label}`;\n }\n\n // 递归子节点\n let text = \"\";\n el.childNodes.forEach((child) => {\n text += extractNodeText(child);\n });\n return text;\n }\n\n return \"\";\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAMO,SAAS,gBAAgB,IAA4B;AAC1D,MAAI,CAAC;AAAI,WAAO;AAChB,QAAM,IAAI,IAAI,KAAK,EAAE;AACrB,QAAM,QAAQ,EAAE,SAAS,IAAI;AAC7B,QAAM,MAAM,EAAE,QAAQ;AACtB,QAAM,KAAK,OAAO,EAAE,WAAW,CAAC,EAAE,SAAS,GAAG,GAAG;AACjD,QAAM,KAAK,OAAO,EAAE,WAAW,CAAC,EAAE,SAAS,GAAG,GAAG;AACjD,SAAO,GAAG,SAAS,QAAQ,MAAM;AACnC;AAQO,SAAS,iBAAiB,WAA+C;AAC9E,QAAM,MAAM,OAAO,aAAa;AAChC,MAAI,CAAC,OAAO,IAAI,eAAe,IAAI,eAAe;AAAG,WAAO;AAE5D,QAAM,QAAQ,IAAI,WAAW,CAAC;AAE9B,MAAI,aAAa,CAAC,UAAU,SAAS,MAAM,uBAAuB,GAAG;AACnE,WAAO;AAAA,EACT;AAEA,QAAM,WAAW,MAAM,cAAc;AACrC,MAAI,SAAS;AAEb,WAAS,WAAW,QAAQ,CAAC,SAAS;AACpC,cAAU,gBAAgB,IAAI;AAAA,EAChC,CAAC;AAED,SAAO,UAAU;AACnB;AAGA,SAAS,gBAAgB,MAAoB;AA3C7C;AA4CE,MAAI,KAAK,aAAa,KAAK,WAAW;AACpC,WAAO,KAAK,eAAe;AAAA,EAC7B;AAEA,MAAI,KAAK,aAAa,KAAK,cAAc;AACvC,UAAM,KAAK;AAEX,UAAM,MAAK,QAAG,iBAAH,4BAAkB;AAC7B,QAAI;AAAI,aAAO;AAGf,SAAI,QAAG,iBAAH,4BAAkB,4BAA4B;AAChD,YAAM,QAAQ,GAAG,aAAa,YAAY;AAC1C,UAAI;AAAO,eAAO,IAAI;AAAA,IACxB;AAGA,QAAI,OAAO;AACX,OAAG,WAAW,QAAQ,CAAC,UAAU;AAC/B,cAAQ,gBAAgB,KAAK;AAAA,IAC/B,CAAC;AACD,WAAO;AAAA,EACT;AAEA,SAAO;AACT;",
6
+ "names": []
7
+ }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/components/XAdkProvider/compound/DislikeFeedBack.tsx"],
4
- "sourcesContent": ["import { Button, Form, Input, message, Popover } from \"antd\";\nimport React, { useState } from \"react\";\nimport { DislikeFilled, DislikeOutlined } from \"@ant-design/icons\";\nimport FeedbackTags from \"./FeedbackTags\";\n\nexport interface DislikeFeedbackProps {\n msg: any;\n activeColor: string;\n onSubmit: (v: any) => Promise<boolean>;\n}\n\nexport const DislikeFeedback: React.FC<DislikeFeedbackProps> = ({\n msg,\n activeColor,\n onSubmit,\n}) => {\n const [form] = Form.useForm();\n const [showFeedback, setShowFeedback] = useState(false);\n\n // msg 是 ChatGroup 对象,isLike 在同层\n const currentIsLike = msg.isLike ?? 0;\n\n return (\n <Popover\n trigger={[\"click\"]}\n open={showFeedback}\n onOpenChange={(v) => {\n if (v && currentIsLike !== 0) {\n message.warning(\"已收到您的反馈,无需重复提交\");\n return;\n }\n if (v) {\n form.resetFields();\n }\n setShowFeedback(v);\n }}\n title={\n <div>\n <div>抱歉,未能满足您的需求</div>\n <div\n style={{ color: \"#999\", fontWeight: \"normal\", marginBottom: 12 }}\n >\n 为提升您的使用体验,请告诉我们不足的方向\n </div>\n </div>\n }\n content={\n <div>\n <Form form={form}>\n <Form.Item name=\"feedbackTags\" style={{ marginBottom: 12 }}>\n <FeedbackTags />\n </Form.Item>\n <Form.Item name=\"feedbackDescription\" style={{ marginBottom: 12 }}>\n <Input.TextArea rows={4} placeholder=\"欢迎说说你的想法\" />\n </Form.Item>\n <Form.Item\n dependencies={[\"feedbackTags\", \"feedbackDescription\"]}\n noStyle\n >\n {({ getFieldValue }) => {\n const feedbackTags = getFieldValue(\"feedbackTags\") || [];\n const feedbackDescription = getFieldValue(\n \"feedbackDescription\",\n );\n const disabled = !feedbackTags.length && !feedbackDescription;\n return (\n <Button\n type=\"primary\"\n block\n disabled={disabled}\n onClick={async () => {\n const formData = await form.validateFields();\n const res = await onSubmit(formData);\n if (res) {\n setShowFeedback(false);\n }\n }}\n >\n 提交反馈\n </Button>\n );\n }}\n </Form.Item>\n </Form>\n </div>\n }\n >\n {currentIsLike === -1 ? (\n <DislikeFilled style={{ color: activeColor, cursor: \"pointer\" }} />\n ) : (\n <DislikeOutlined style={{ color: \"#81858c\", cursor: \"pointer\" }} />\n )}\n </Popover>\n );\n};\n\nexport default DislikeFeedback;\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kBAAsD;AACtD,mBAAgC;AAChC,mBAA+C;AAC/C,0BAAyB;AAkCjB;AA1BD,IAAM,kBAAkD,CAAC;AAAA,EAC9D;AAAA,EACA;AAAA,EACA;AACF,MAAM;AACJ,QAAM,CAAC,IAAI,IAAI,iBAAK,QAAQ;AAC5B,QAAM,CAAC,cAAc,eAAe,QAAI,uBAAS,KAAK;AAGtD,QAAM,gBAAgB,IAAI,UAAU;AAEpC,SACE;AAAA,IAAC;AAAA;AAAA,MACC,SAAS,CAAC,OAAO;AAAA,MACjB,MAAM;AAAA,MACN,cAAc,CAAC,MAAM;AACnB,YAAI,KAAK,kBAAkB,GAAG;AAC5B,8BAAQ,QAAQ,gBAAgB;AAChC;AAAA,QACF;AACA,YAAI,GAAG;AACL,eAAK,YAAY;AAAA,QACnB;AACA,wBAAgB,CAAC;AAAA,MACnB;AAAA,MACA,OACE,6CAAC,SACC;AAAA,oDAAC,SAAI,yBAAW;AAAA,QAChB;AAAA,UAAC;AAAA;AAAA,YACC,OAAO,EAAE,OAAO,QAAQ,YAAY,UAAU,cAAc,GAAG;AAAA,YAChE;AAAA;AAAA,QAED;AAAA,SACF;AAAA,MAEF,SACE,4CAAC,SACC,uDAAC,oBAAK,MACJ;AAAA,oDAAC,iBAAK,MAAL,EAAU,MAAK,gBAAe,OAAO,EAAE,cAAc,GAAG,GACvD,sDAAC,oBAAAA,SAAA,EAAa,GAChB;AAAA,QACA,4CAAC,iBAAK,MAAL,EAAU,MAAK,uBAAsB,OAAO,EAAE,cAAc,GAAG,GAC9D,sDAAC,kBAAM,UAAN,EAAe,MAAM,GAAG,aAAY,YAAW,GAClD;AAAA,QACA;AAAA,UAAC,iBAAK;AAAA,UAAL;AAAA,YACC,cAAc,CAAC,gBAAgB,qBAAqB;AAAA,YACpD,SAAO;AAAA,YAEN,WAAC,EAAE,cAAc,MAAM;AACtB,oBAAM,eAAe,cAAc,cAAc,KAAK,CAAC;AACvD,oBAAM,sBAAsB;AAAA,gBAC1B;AAAA,cACF;AACA,oBAAM,WAAW,CAAC,aAAa,UAAU,CAAC;AAC1C,qBACE;AAAA,gBAAC;AAAA;AAAA,kBACC,MAAK;AAAA,kBACL,OAAK;AAAA,kBACL;AAAA,kBACA,SAAS,YAAY;AACnB,0BAAM,WAAW,MAAM,KAAK,eAAe;AAC3C,0BAAM,MAAM,MAAM,SAAS,QAAQ;AACnC,wBAAI,KAAK;AACP,sCAAgB,KAAK;AAAA,oBACvB;AAAA,kBACF;AAAA,kBACD;AAAA;AAAA,cAED;AAAA,YAEJ;AAAA;AAAA,QACF;AAAA,SACF,GACF;AAAA,MAGD,4BAAkB,KACjB,4CAAC,8BAAc,OAAO,EAAE,OAAO,aAAa,QAAQ,UAAU,GAAG,IAEjE,4CAAC,gCAAgB,OAAO,EAAE,OAAO,WAAW,QAAQ,UAAU,GAAG;AAAA;AAAA,EAErE;AAEJ;AAEA,IAAO,0BAAQ;",
4
+ "sourcesContent": ["import { Button, Form, Input, message, Popover } from \"antd\";\nimport React, { useState } from \"react\";\nimport { DislikeFilled, DislikeOutlined } from \"@ant-design/icons\";\nimport FeedbackTags from \"./FeedbackTags\";\n\nexport interface DislikeFeedbackProps {\n msg: any;\n activeColor: string;\n onSubmit: (v: any) => Promise<boolean>;\n}\n\nexport const DislikeFeedback: React.FC<DislikeFeedbackProps> = ({\n msg,\n activeColor,\n onSubmit,\n}) => {\n const [form] = Form.useForm();\n const [showFeedback, setShowFeedback] = useState(false);\n\n // msg 是 ChatGroup 对象,isLike 在同层\n const currentIsLike = msg.isLike ?? 0;\n\n return (\n <Popover\n trigger={[\"click\"]}\n open={showFeedback}\n onOpenChange={(v: boolean) => {\n if (v && currentIsLike !== 0) {\n message.warning(\"已收到您的反馈,无需重复提交\");\n return;\n }\n if (v) {\n form.resetFields();\n }\n setShowFeedback(v);\n }}\n title={\n <div>\n <div>抱歉,未能满足您的需求</div>\n <div\n style={{ color: \"#999\", fontWeight: \"normal\", marginBottom: 12 }}\n >\n 为提升您的使用体验,请告诉我们不足的方向\n </div>\n </div>\n }\n content={\n <div>\n <Form form={form}>\n <Form.Item name=\"feedbackTags\" style={{ marginBottom: 12 }}>\n <FeedbackTags />\n </Form.Item>\n <Form.Item name=\"feedbackDescription\" style={{ marginBottom: 12 }}>\n <Input.TextArea rows={4} placeholder=\"欢迎说说你的想法\" />\n </Form.Item>\n <Form.Item\n dependencies={[\"feedbackTags\", \"feedbackDescription\"]}\n noStyle\n >\n {({ getFieldValue }: { getFieldValue: (name: string) => any }) => {\n const feedbackTags = getFieldValue(\"feedbackTags\") || [];\n const feedbackDescription = getFieldValue(\n \"feedbackDescription\",\n );\n const disabled = !feedbackTags.length && !feedbackDescription;\n return (\n <Button\n type=\"primary\"\n block\n disabled={disabled}\n onClick={async () => {\n const formData = await form.validateFields();\n const res = await onSubmit(formData);\n if (res) {\n setShowFeedback(false);\n }\n }}\n >\n 提交反馈\n </Button>\n );\n }}\n </Form.Item>\n </Form>\n </div>\n }\n >\n {currentIsLike === -1 ? (\n <DislikeFilled style={{ color: activeColor, cursor: \"pointer\" }} />\n ) : (\n <DislikeOutlined style={{ color: \"#81858c\", cursor: \"pointer\" }} />\n )}\n </Popover>\n );\n};\n\nexport default DislikeFeedback;\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kBAAsD;AACtD,mBAAgC;AAChC,mBAA+C;AAC/C,0BAAyB;AAkCjB;AA1BD,IAAM,kBAAkD,CAAC;AAAA,EAC9D;AAAA,EACA;AAAA,EACA;AACF,MAAM;AACJ,QAAM,CAAC,IAAI,IAAI,iBAAK,QAAQ;AAC5B,QAAM,CAAC,cAAc,eAAe,QAAI,uBAAS,KAAK;AAGtD,QAAM,gBAAgB,IAAI,UAAU;AAEpC,SACE;AAAA,IAAC;AAAA;AAAA,MACC,SAAS,CAAC,OAAO;AAAA,MACjB,MAAM;AAAA,MACN,cAAc,CAAC,MAAe;AAC5B,YAAI,KAAK,kBAAkB,GAAG;AAC5B,8BAAQ,QAAQ,gBAAgB;AAChC;AAAA,QACF;AACA,YAAI,GAAG;AACL,eAAK,YAAY;AAAA,QACnB;AACA,wBAAgB,CAAC;AAAA,MACnB;AAAA,MACA,OACE,6CAAC,SACC;AAAA,oDAAC,SAAI,yBAAW;AAAA,QAChB;AAAA,UAAC;AAAA;AAAA,YACC,OAAO,EAAE,OAAO,QAAQ,YAAY,UAAU,cAAc,GAAG;AAAA,YAChE;AAAA;AAAA,QAED;AAAA,SACF;AAAA,MAEF,SACE,4CAAC,SACC,uDAAC,oBAAK,MACJ;AAAA,oDAAC,iBAAK,MAAL,EAAU,MAAK,gBAAe,OAAO,EAAE,cAAc,GAAG,GACvD,sDAAC,oBAAAA,SAAA,EAAa,GAChB;AAAA,QACA,4CAAC,iBAAK,MAAL,EAAU,MAAK,uBAAsB,OAAO,EAAE,cAAc,GAAG,GAC9D,sDAAC,kBAAM,UAAN,EAAe,MAAM,GAAG,aAAY,YAAW,GAClD;AAAA,QACA;AAAA,UAAC,iBAAK;AAAA,UAAL;AAAA,YACC,cAAc,CAAC,gBAAgB,qBAAqB;AAAA,YACpD,SAAO;AAAA,YAEN,WAAC,EAAE,cAAc,MAAgD;AAChE,oBAAM,eAAe,cAAc,cAAc,KAAK,CAAC;AACvD,oBAAM,sBAAsB;AAAA,gBAC1B;AAAA,cACF;AACA,oBAAM,WAAW,CAAC,aAAa,UAAU,CAAC;AAC1C,qBACE;AAAA,gBAAC;AAAA;AAAA,kBACC,MAAK;AAAA,kBACL,OAAK;AAAA,kBACL;AAAA,kBACA,SAAS,YAAY;AACnB,0BAAM,WAAW,MAAM,KAAK,eAAe;AAC3C,0BAAM,MAAM,MAAM,SAAS,QAAQ;AACnC,wBAAI,KAAK;AACP,sCAAgB,KAAK;AAAA,oBACvB;AAAA,kBACF;AAAA,kBACD;AAAA;AAAA,cAED;AAAA,YAEJ;AAAA;AAAA,QACF;AAAA,SACF,GACF;AAAA,MAGD,4BAAkB,KACjB,4CAAC,8BAAc,OAAO,EAAE,OAAO,aAAa,QAAQ,UAAU,GAAG,IAEjE,4CAAC,gCAAgB,OAAO,EAAE,OAAO,WAAW,QAAQ,UAAU,GAAG;AAAA;AAAA,EAErE;AAEJ;AAEA,IAAO,0BAAQ;",
6
6
  "names": ["FeedbackTags"]
7
7
  }
@@ -1,11 +1,17 @@
1
1
  import React from "react";
2
- import type { ActionExtraProps, ActionProps } from "../../../types";
2
+ import type { ActionExtraProps, ActionProps, XAdkChatbotProps } from "../../../types";
3
3
  import type { ChatStrategies } from "../../../types";
4
4
  export interface XAdkMessagesProps {
5
5
  /** 自定义操作栏渲染 */
6
6
  actions?: ActionProps;
7
7
  /** 追加在操作栏之后的内容 */
8
8
  actionsExtra?: ActionExtraProps;
9
+ /** 消息流中的业务模块与整组自定义展示。 */
10
+ renderBeforeGroup?: XAdkChatbotProps["renderBeforeGroup"];
11
+ renderAfterGroup?: XAdkChatbotProps["renderAfterGroup"];
12
+ renderGroup?: XAdkChatbotProps["renderGroup"];
13
+ /** 受控历史消息分页;可通过 useChatActions().setMessages 合并新页。 */
14
+ history?: XAdkChatbotProps["history"];
9
15
  /** 类名 */
10
16
  className?: string;
11
17
  /** 样式 */
@@ -44,6 +44,10 @@ var import_jsx_runtime = require("react/jsx-runtime");
44
44
  var Messages = ({
45
45
  actions,
46
46
  actionsExtra,
47
+ renderBeforeGroup,
48
+ renderAfterGroup,
49
+ renderGroup,
50
+ history,
47
51
  className,
48
52
  style,
49
53
  showFnCallDetail,
@@ -56,7 +60,9 @@ var Messages = ({
56
60
  prologue,
57
61
  suggestions,
58
62
  initialized,
63
+ currentSessionId,
59
64
  showFeedback,
65
+ showUserActions,
60
66
  appInfo,
61
67
  onFileClick,
62
68
  strategies
@@ -143,6 +149,11 @@ var Messages = ({
143
149
  onConfirm: confirmFnCall,
144
150
  actions: actions ?? defaultActions,
145
151
  actionsExtra,
152
+ renderBeforeGroup,
153
+ renderAfterGroup,
154
+ renderGroup,
155
+ history,
156
+ sessionId: currentSessionId,
146
157
  enableGrouping: true,
147
158
  enableProcessParsing: true,
148
159
  initialized,
@@ -151,6 +162,7 @@ var Messages = ({
151
162
  className,
152
163
  style,
153
164
  renderFunctionCall,
165
+ showUserActions,
154
166
  strategies: { ...strategies, ...strategiesProp }
155
167
  }
156
168
  );