@ai-group/chat-sdk 3.5.13 → 3.6.0

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 (38) hide show
  1. package/dist/cjs/components/FileGallery/index.js +1 -1
  2. package/dist/cjs/components/FileGallery/index.js.map +1 -1
  3. package/dist/cjs/components/FolderTree/styles.js +4 -1
  4. package/dist/cjs/components/FolderTree/styles.js.map +2 -2
  5. package/dist/cjs/components/XAdkProvider/index.js +2 -0
  6. package/dist/cjs/components/XAdkProvider/index.js.map +2 -2
  7. package/dist/cjs/components/XAdkThoughtChain/index.js +75 -39
  8. package/dist/cjs/components/XAdkThoughtChain/index.js.map +2 -2
  9. package/dist/cjs/components/XAdkThoughtChain/styles.js +27 -26
  10. package/dist/cjs/components/XAdkThoughtChain/styles.js.map +2 -2
  11. package/dist/cjs/index.d.ts +2 -1
  12. package/dist/cjs/index.js +9 -0
  13. package/dist/cjs/index.js.map +2 -2
  14. package/dist/cjs/styles/tokens.d.ts +27 -0
  15. package/dist/cjs/styles/tokens.js +72 -0
  16. package/dist/cjs/styles/tokens.js.map +7 -0
  17. package/dist/cjs/types/XAdkThoughtChain.d.ts +13 -0
  18. package/dist/cjs/types/XAdkThoughtChain.js.map +1 -1
  19. package/dist/esm/components/FileGallery/index.js +1 -1
  20. package/dist/esm/components/FileGallery/index.js.map +1 -1
  21. package/dist/esm/components/FolderTree/styles.js +2 -2
  22. package/dist/esm/components/FolderTree/styles.js.map +1 -1
  23. package/dist/esm/components/XAdkProvider/index.js +3 -2
  24. package/dist/esm/components/XAdkProvider/index.js.map +1 -1
  25. package/dist/esm/components/XAdkThoughtChain/index.js +100 -50
  26. package/dist/esm/components/XAdkThoughtChain/index.js.map +1 -1
  27. package/dist/esm/components/XAdkThoughtChain/styles.js +20 -19
  28. package/dist/esm/components/XAdkThoughtChain/styles.js.map +1 -1
  29. package/dist/esm/index.d.ts +2 -1
  30. package/dist/esm/index.js +3 -0
  31. package/dist/esm/index.js.map +1 -1
  32. package/dist/esm/styles/tokens.d.ts +27 -0
  33. package/dist/esm/styles/tokens.js +42 -0
  34. package/dist/esm/styles/tokens.js.map +1 -0
  35. package/dist/esm/types/XAdkThoughtChain.d.ts +13 -0
  36. package/dist/esm/types/XAdkThoughtChain.js.map +1 -1
  37. package/dist/umd/chat-sdk.min.js +1 -1
  38. package/package.json +1 -1
@@ -163,7 +163,7 @@ var FileGallery = ({
163
163
  {
164
164
  src: url,
165
165
  alt: fileName,
166
- fallback: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mN8/5+hHgAHggJ/PchI7wAAAABJRU5ErkJggg==",
166
+ fallback: "data:image/png;base64,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",
167
167
  preview: onClick ? false : { src: url }
168
168
  }
169
169
  ),
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/components/FileGallery/index.tsx"],
4
- "sourcesContent": ["import React, { useState, useEffect } from \"react\";\nimport { Image, Tooltip, Progress } from \"antd\";\nimport {\n FileOutlined,\n FilePdfOutlined,\n FileWordOutlined,\n FileExcelOutlined,\n FilePptOutlined,\n FileImageOutlined,\n CloseOutlined,\n AudioOutlined,\n FileZipOutlined,\n VideoCameraOutlined,\n FileMarkdownOutlined,\n} from \"@ant-design/icons\";\nimport { FileItem, FileGalleryProps } from \"@/types\";\nimport { useStyles } from \"./styles\";\n\n// ==================== 工具函数 ====================\n\n/**\n * 获取文件名\n */\nconst getFileName = (file: FileItem): string => {\n return file.displayName || file.name || \"\";\n};\n\n/**\n * 获取文件大小\n */\nconst getFileSize = (file: FileItem): number => {\n return file.size || 0;\n};\n\n/**\n * 获取文件 MIME 类型\n */\nconst getMimeType = (file: FileItem): string => {\n return file.mimeType || file.type || \"\";\n};\n\n/**\n * 获取文件 URL\n */\nconst getFileUrl = (file: FileItem): string => {\n return (\n file.fileUri ||\n file.response?.fileUrl ||\n file.response?.tempUrl ||\n file.tempUrl ||\n \"\"\n );\n};\n\n/**\n * 获取文件唯一标识\n */\nconst getFileId = (file: FileItem): string => {\n return file.id || file.uid || \"\";\n};\n\n/**\n * 判断是否是图片文件\n */\nconst isImageFile = (file: FileItem): boolean => {\n const mimeType = getMimeType(file);\n if (mimeType && mimeType.startsWith(\"image/\")) return true;\n\n const fileName = getFileName(file);\n if (fileName && fileName.match(/\\.(jpg|jpeg|png|gif|webp|bmp|svg)$/i))\n return true;\n\n const url = getFileUrl(file);\n if (url && url.match(/\\.(jpg|jpeg|png|gif|webp|bmp|svg)(\\?.*)?$/i))\n return true;\n\n return false;\n};\n\n/**\n * 判断是否是音频文件\n */\nconst isAudioFile = (file: FileItem): boolean => {\n const mimeType = getMimeType(file);\n if (mimeType && mimeType.startsWith(\"audio/\")) return true;\n\n const fileName = getFileName(file);\n return !!fileName?.match(/\\.(mp3|wav|m4a|aac|ogg|flac)$/i);\n};\n\n/**\n * 判断是否是视频文件\n */\nconst isVideoFile = (file: FileItem): boolean => {\n const mimeType = getMimeType(file);\n if (mimeType && mimeType.startsWith(\"video/\")) return true;\n\n const fileName = getFileName(file);\n return !!fileName?.match(/\\.(mp4|mov|webm|mkv|avi)$/i);\n};\n\n/**\n * 判断是否是压缩包文件\n */\nconst isZipFile = (file: FileItem): boolean => {\n const fileName = getFileName(file);\n return !!fileName?.match(/\\.(zip|rar|7z|tar|gz|bz2|xz|tgz)$/i);\n};\n\n/**\n * 判断是否是 Markdown 文件\n */\nconst isMarkdownFile = (file: FileItem): boolean => {\n const fileName = getFileName(file);\n return !!fileName?.match(/\\.(md|markdown)$/i);\n};\n\n/**\n * 获取文件扩展名\n */\nconst getFileExtension = (filename: string): string => {\n const ext = filename.split(\".\").pop();\n return ext ? ext.toLowerCase() : \"\";\n};\n\n/**\n * 获取文件图标和颜色\n */\nconst getFileIcon = (\n file: FileItem,\n): { icon: React.ReactNode; color: string } => {\n const ext = getFileExtension(getFileName(file));\n\n // PDF\n if (ext === \"pdf\") {\n return { icon: <FilePdfOutlined />, color: \"#ff4d4f\" };\n }\n\n // Word\n if ([\"doc\", \"docx\"].includes(ext)) {\n return { icon: <FileWordOutlined />, color: \"#1677ff\" };\n }\n\n // Excel\n if ([\"xls\", \"xlsx\", \"csv\"].includes(ext)) {\n return { icon: <FileExcelOutlined />, color: \"#22b35e\" };\n }\n\n // PPT\n if ([\"ppt\", \"pptx\"].includes(ext)) {\n return { icon: <FilePptOutlined />, color: \"#ff6e31\" };\n }\n\n // Audio\n if ([\"mp3\", \"wav\", \"m4a\", \"aac\", \"ogg\", \"flac\"].includes(ext)) {\n return { icon: <AudioOutlined />, color: \"#722ed1\" };\n }\n\n // Video\n if ([\"mp4\", \"mov\", \"webm\", \"mkv\", \"avi\"].includes(ext)) {\n return { icon: <VideoCameraOutlined />, color: \"#fa8c16\" };\n }\n\n // 压缩包\n if ([\"zip\", \"rar\", \"7z\", \"tar\", \"gz\", \"bz2\", \"xz\", \"tgz\"].includes(ext)) {\n return { icon: <FileZipOutlined />, color: \"#eb2f96\" };\n }\n\n // Markdown\n if ([\"md\", \"markdown\"].includes(ext)) {\n return { icon: <FileMarkdownOutlined />, color: \"#13c2c2\" };\n }\n\n // 图片\n if (isImageFile(file)) {\n return { icon: <FileImageOutlined />, color: \"#8c8c8c\" };\n }\n\n // 默认\n return { icon: <FileOutlined />, color: \"#8c8c8c\" };\n};\n\n/**\n * 格式化文件大小\n */\nconst formatFileSize = (bytes: number): string => {\n if (bytes < 1024) return bytes + \" B\";\n if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(1) + \" KB\";\n return (bytes / (1024 * 1024)).toFixed(1) + \" MB\";\n};\n\nconst styles = useStyles();\n\n/**\n * FileGallery - 单文件展示组件\n *\n * 功能特性:\n * - 📁 支持多种文件类型展示 (图片、音频、视频、文档等)\n * - 🖼️ 图片支持预览和缩略图\n * - 🎵 音频文件支持内联播放\n * - 🎬 视频文件支持内联播放\n * - 📊 显示文件大小、类型图标\n * - 🗑️ 支持删除操作\n * - 📤 支持上传进度显示\n * - 🎨 支持卡片内部布局控制(align:图标和信息的排列方式)\n *\n * @example\n * // XAdkSender 场景 - 可删除的本地文件\n * {files.map(file => (\n * <FileGallery\n * key={file.id}\n * file={file}\n * removable\n * onRemove={handleRemove}\n * />\n * ))}\n *\n * @example\n * // XadkChatbot 场景 - 只读的远程文件\n * {files.map(file => (\n * <FileGallery key={file.id} file={file} />\n * ))}\n */\nconst FileGallery: React.FC<FileGalleryProps> = ({\n file,\n align = \"left\",\n removable = false,\n onRemove = () => {},\n className,\n style,\n onClick,\n}) => {\n const [objectUrl, setObjectUrl] = useState(\"\");\n\n useEffect(() => {\n if (!file?.file) return;\n\n const url = URL.createObjectURL(file.file);\n setObjectUrl(url);\n\n return () => URL.revokeObjectURL(url);\n }, [file?.file]);\n\n if (!file) return null;\n\n const isImage = isImageFile(file);\n const isAudio = isAudioFile(file);\n const isVideo = isVideoFile(file);\n const isZip = isZipFile(file);\n const isMarkdown = isMarkdownFile(file);\n const fileName = getFileName(file);\n const fileSize = getFileSize(file);\n const fileId = getFileId(file);\n const url = getFileUrl(file) || objectUrl;\n\n // 图片文件\n if (isImage) {\n return (\n <div\n className={`${styles.fileCard} ${align === \"right\" ? \"align-right\" : \"\"} ${className || \"\"}`}\n style={{ ...style, cursor: onClick ? \"pointer\" : undefined }}\n onClick={() => onClick?.(file)}\n >\n {/* 图片缩略图 */}\n <div className={styles.imageThumbnail}>\n <Image\n src={url}\n alt={fileName}\n fallback=\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mN8/5+hHgAHggJ/PchI7wAAAABJRU5ErkJggg==\"\n preview={onClick ? false : { src: url }}\n />\n\n {/* 上传进度遮罩 */}\n {file.status === \"uploading\" && (\n <div className={styles.imageOverlay}>\n <Progress\n type=\"circle\"\n percent={file.progress}\n size={30}\n strokeColor=\"#1677ff\"\n />\n </div>\n )}\n </div>\n\n {/* 文件信息 */}\n <div className={styles.fileInfo}>\n <Tooltip title={fileName}>\n <div className={styles.fileName}>\n {fileName.length > 15\n ? `${fileName.substring(0, 15)}...`\n : fileName}\n </div>\n </Tooltip>\n {Number(file?.size) > 0 && (\n <div className={styles.fileSize}>{formatFileSize(fileSize)}</div>\n )}\n </div>\n\n {/* 删除按钮 */}\n {removable && (\n <button\n className={styles.fileRemoveBtn}\n onClick={() => onRemove(fileId)}\n disabled={file.status === \"uploading\"}\n aria-label=\"删除文件\"\n >\n <CloseOutlined />\n </button>\n )}\n </div>\n );\n }\n\n // 音频文件\n if (isAudio) {\n return (\n <div\n className={`${styles.fileCard} ${align === \"right\" ? \"align-right\" : \"\"} ${className || \"\"}`}\n style={style}\n >\n <div className={styles.fileIcon} style={{ color: \"#722ed1\" }}>\n <AudioOutlined />\n </div>\n\n <div className={styles.fileInfo}>\n <Tooltip title={fileName}>\n <div className={styles.fileName}>{fileName}</div>\n </Tooltip>\n\n <audio\n src={url}\n controls\n className={styles.mediaWrapper}\n style={{ width: \"100%\", height: 28 }}\n />\n </div>\n\n {removable && (\n <button\n className={styles.fileRemoveBtn}\n onClick={() => onRemove(fileId)}\n disabled={file.status === \"uploading\"}\n aria-label=\"删除文件\"\n >\n <CloseOutlined />\n </button>\n )}\n </div>\n );\n }\n\n // 视频文件\n if (isVideo) {\n return (\n <div\n className={`${styles.fileCard} ${align === \"right\" ? \"align-right\" : \"\"} ${className || \"\"}`}\n style={style}\n >\n <div className={styles.fileIcon} style={{ color: \"#fa8c16\" }}>\n <VideoCameraOutlined />\n </div>\n\n <div className={styles.fileInfo}>\n <Tooltip title={fileName}>\n <div className={styles.fileName}>{fileName}</div>\n </Tooltip>\n\n <video\n src={url}\n controls\n className={styles.mediaWrapper}\n style={{ width: \"100%\", height: 40 }}\n />\n </div>\n\n {removable && (\n <button\n className={styles.fileRemoveBtn}\n onClick={() => onRemove(fileId)}\n disabled={file.status === \"uploading\"}\n aria-label=\"删除文件\"\n >\n <CloseOutlined />\n </button>\n )}\n </div>\n );\n }\n\n // 其他文件\n const { icon, color } = getFileIcon(file);\n const isExternalUrl = url && url.startsWith(\"http\");\n\n return (\n <div\n className={`${styles.fileCard} ${align === \"right\" ? \"align-right\" : \"\"} ${className || \"\"}`}\n style={{ ...style, cursor: onClick ? \"pointer\" : undefined }}\n onClick={() => onClick?.(file)}\n >\n <div className={styles.fileIcon} style={{ color }}>\n {icon}\n </div>\n\n <div className={styles.fileInfo}>\n {isExternalUrl && !onClick ? (\n <a\n href={url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className={styles.fileLink}\n >\n <Tooltip title={fileName}>\n <div className={styles.fileName}>\n {fileName.length > 15\n ? `${fileName.substring(0, 15)}...`\n : fileName}\n </div>\n </Tooltip>\n </a>\n ) : (\n <Tooltip title={fileName}>\n <div className={styles.fileName}>\n {fileName.length > 15\n ? `${fileName.substring(0, 15)}...`\n : fileName}\n </div>\n </Tooltip>\n )}\n\n {file.status === \"uploading\" ? (\n <Progress\n percent={file.progress}\n size=\"small\"\n showInfo={false}\n strokeColor=\"#1677ff\"\n className={styles.progress}\n />\n ) : (\n fileSize > 0 && (\n <div className={styles.fileSize}>{formatFileSize(fileSize)}</div>\n )\n )}\n\n {file.status === \"error\" && file.errorMessage && (\n <div\n style={{\n fontSize: \"11px\",\n color: \"#ff4d4f\",\n marginTop: \"2px\",\n }}\n >\n {file.errorMessage}\n </div>\n )}\n </div>\n\n {removable && (\n <button\n className={styles.fileRemoveBtn}\n onClick={() => onRemove(fileId)}\n disabled={file.status === \"uploading\"}\n aria-label=\"删除文件\"\n >\n <CloseOutlined />\n </button>\n )}\n </div>\n );\n};\n\nexport default FileGallery;\n"],
4
+ "sourcesContent": ["import React, { useState, useEffect } from \"react\";\nimport { Image, Tooltip, Progress } from \"antd\";\nimport {\n FileOutlined,\n FilePdfOutlined,\n FileWordOutlined,\n FileExcelOutlined,\n FilePptOutlined,\n FileImageOutlined,\n CloseOutlined,\n AudioOutlined,\n FileZipOutlined,\n VideoCameraOutlined,\n FileMarkdownOutlined,\n} from \"@ant-design/icons\";\nimport { FileItem, FileGalleryProps } from \"@/types\";\nimport { useStyles } from \"./styles\";\n\n// ==================== 工具函数 ====================\n\n/**\n * 获取文件名\n */\nconst getFileName = (file: FileItem): string => {\n return file.displayName || file.name || \"\";\n};\n\n/**\n * 获取文件大小\n */\nconst getFileSize = (file: FileItem): number => {\n return file.size || 0;\n};\n\n/**\n * 获取文件 MIME 类型\n */\nconst getMimeType = (file: FileItem): string => {\n return file.mimeType || file.type || \"\";\n};\n\n/**\n * 获取文件 URL\n */\nconst getFileUrl = (file: FileItem): string => {\n return (\n file.fileUri ||\n file.response?.fileUrl ||\n file.response?.tempUrl ||\n file.tempUrl ||\n \"\"\n );\n};\n\n/**\n * 获取文件唯一标识\n */\nconst getFileId = (file: FileItem): string => {\n return file.id || file.uid || \"\";\n};\n\n/**\n * 判断是否是图片文件\n */\nconst isImageFile = (file: FileItem): boolean => {\n const mimeType = getMimeType(file);\n if (mimeType && mimeType.startsWith(\"image/\")) return true;\n\n const fileName = getFileName(file);\n if (fileName && fileName.match(/\\.(jpg|jpeg|png|gif|webp|bmp|svg)$/i))\n return true;\n\n const url = getFileUrl(file);\n if (url && url.match(/\\.(jpg|jpeg|png|gif|webp|bmp|svg)(\\?.*)?$/i))\n return true;\n\n return false;\n};\n\n/**\n * 判断是否是音频文件\n */\nconst isAudioFile = (file: FileItem): boolean => {\n const mimeType = getMimeType(file);\n if (mimeType && mimeType.startsWith(\"audio/\")) return true;\n\n const fileName = getFileName(file);\n return !!fileName?.match(/\\.(mp3|wav|m4a|aac|ogg|flac)$/i);\n};\n\n/**\n * 判断是否是视频文件\n */\nconst isVideoFile = (file: FileItem): boolean => {\n const mimeType = getMimeType(file);\n if (mimeType && mimeType.startsWith(\"video/\")) return true;\n\n const fileName = getFileName(file);\n return !!fileName?.match(/\\.(mp4|mov|webm|mkv|avi)$/i);\n};\n\n/**\n * 判断是否是压缩包文件\n */\nconst isZipFile = (file: FileItem): boolean => {\n const fileName = getFileName(file);\n return !!fileName?.match(/\\.(zip|rar|7z|tar|gz|bz2|xz|tgz)$/i);\n};\n\n/**\n * 判断是否是 Markdown 文件\n */\nconst isMarkdownFile = (file: FileItem): boolean => {\n const fileName = getFileName(file);\n return !!fileName?.match(/\\.(md|markdown)$/i);\n};\n\n/**\n * 获取文件扩展名\n */\nconst getFileExtension = (filename: string): string => {\n const ext = filename.split(\".\").pop();\n return ext ? ext.toLowerCase() : \"\";\n};\n\n/**\n * 获取文件图标和颜色\n */\nconst getFileIcon = (\n file: FileItem,\n): { icon: React.ReactNode; color: string } => {\n const ext = getFileExtension(getFileName(file));\n\n // PDF\n if (ext === \"pdf\") {\n return { icon: <FilePdfOutlined />, color: \"#ff4d4f\" };\n }\n\n // Word\n if ([\"doc\", \"docx\"].includes(ext)) {\n return { icon: <FileWordOutlined />, color: \"#1677ff\" };\n }\n\n // Excel\n if ([\"xls\", \"xlsx\", \"csv\"].includes(ext)) {\n return { icon: <FileExcelOutlined />, color: \"#22b35e\" };\n }\n\n // PPT\n if ([\"ppt\", \"pptx\"].includes(ext)) {\n return { icon: <FilePptOutlined />, color: \"#ff6e31\" };\n }\n\n // Audio\n if ([\"mp3\", \"wav\", \"m4a\", \"aac\", \"ogg\", \"flac\"].includes(ext)) {\n return { icon: <AudioOutlined />, color: \"#722ed1\" };\n }\n\n // Video\n if ([\"mp4\", \"mov\", \"webm\", \"mkv\", \"avi\"].includes(ext)) {\n return { icon: <VideoCameraOutlined />, color: \"#fa8c16\" };\n }\n\n // 压缩包\n if ([\"zip\", \"rar\", \"7z\", \"tar\", \"gz\", \"bz2\", \"xz\", \"tgz\"].includes(ext)) {\n return { icon: <FileZipOutlined />, color: \"#eb2f96\" };\n }\n\n // Markdown\n if ([\"md\", \"markdown\"].includes(ext)) {\n return { icon: <FileMarkdownOutlined />, color: \"#13c2c2\" };\n }\n\n // 图片\n if (isImageFile(file)) {\n return { icon: <FileImageOutlined />, color: \"#8c8c8c\" };\n }\n\n // 默认\n return { icon: <FileOutlined />, color: \"#8c8c8c\" };\n};\n\n/**\n * 格式化文件大小\n */\nconst formatFileSize = (bytes: number): string => {\n if (bytes < 1024) return bytes + \" B\";\n if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(1) + \" KB\";\n return (bytes / (1024 * 1024)).toFixed(1) + \" MB\";\n};\n\nconst styles = useStyles();\n\n/**\n * FileGallery - 单文件展示组件\n *\n * 功能特性:\n * - 📁 支持多种文件类型展示 (图片、音频、视频、文档等)\n * - 🖼️ 图片支持预览和缩略图\n * - 🎵 音频文件支持内联播放\n * - 🎬 视频文件支持内联播放\n * - 📊 显示文件大小、类型图标\n * - 🗑️ 支持删除操作\n * - 📤 支持上传进度显示\n * - 🎨 支持卡片内部布局控制(align:图标和信息的排列方式)\n *\n * @example\n * // XAdkSender 场景 - 可删除的本地文件\n * {files.map(file => (\n * <FileGallery\n * key={file.id}\n * file={file}\n * removable\n * onRemove={handleRemove}\n * />\n * ))}\n *\n * @example\n * // XadkChatbot 场景 - 只读的远程文件\n * {files.map(file => (\n * <FileGallery key={file.id} file={file} />\n * ))}\n */\nconst FileGallery: React.FC<FileGalleryProps> = ({\n file,\n align = \"left\",\n removable = false,\n onRemove = () => {},\n className,\n style,\n onClick,\n}) => {\n const [objectUrl, setObjectUrl] = useState(\"\");\n\n useEffect(() => {\n if (!file?.file) return;\n\n const url = URL.createObjectURL(file.file);\n setObjectUrl(url);\n\n return () => URL.revokeObjectURL(url);\n }, [file?.file]);\n\n if (!file) return null;\n\n const isImage = isImageFile(file);\n const isAudio = isAudioFile(file);\n const isVideo = isVideoFile(file);\n const isZip = isZipFile(file);\n const isMarkdown = isMarkdownFile(file);\n const fileName = getFileName(file);\n const fileSize = getFileSize(file);\n const fileId = getFileId(file);\n const url = getFileUrl(file) || objectUrl;\n\n // 图片文件\n if (isImage) {\n return (\n <div\n className={`${styles.fileCard} ${align === \"right\" ? \"align-right\" : \"\"} ${className || \"\"}`}\n style={{ ...style, cursor: onClick ? \"pointer\" : undefined }}\n onClick={() => onClick?.(file)}\n >\n {/* 图片缩略图 */}\n <div className={styles.imageThumbnail}>\n <Image\n src={url}\n alt={fileName}\n fallback=\"data:image/png;base64,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\"\n preview={onClick ? false : { src: url }}\n />\n\n {/* 上传进度遮罩 */}\n {file.status === \"uploading\" && (\n <div className={styles.imageOverlay}>\n <Progress\n type=\"circle\"\n percent={file.progress}\n size={30}\n strokeColor=\"#1677ff\"\n />\n </div>\n )}\n </div>\n\n {/* 文件信息 */}\n <div className={styles.fileInfo}>\n <Tooltip title={fileName}>\n <div className={styles.fileName}>\n {fileName.length > 15\n ? `${fileName.substring(0, 15)}...`\n : fileName}\n </div>\n </Tooltip>\n {Number(file?.size) > 0 && (\n <div className={styles.fileSize}>{formatFileSize(fileSize)}</div>\n )}\n </div>\n\n {/* 删除按钮 */}\n {removable && (\n <button\n className={styles.fileRemoveBtn}\n onClick={() => onRemove(fileId)}\n disabled={file.status === \"uploading\"}\n aria-label=\"删除文件\"\n >\n <CloseOutlined />\n </button>\n )}\n </div>\n );\n }\n\n // 音频文件\n if (isAudio) {\n return (\n <div\n className={`${styles.fileCard} ${align === \"right\" ? \"align-right\" : \"\"} ${className || \"\"}`}\n style={style}\n >\n <div className={styles.fileIcon} style={{ color: \"#722ed1\" }}>\n <AudioOutlined />\n </div>\n\n <div className={styles.fileInfo}>\n <Tooltip title={fileName}>\n <div className={styles.fileName}>{fileName}</div>\n </Tooltip>\n\n <audio\n src={url}\n controls\n className={styles.mediaWrapper}\n style={{ width: \"100%\", height: 28 }}\n />\n </div>\n\n {removable && (\n <button\n className={styles.fileRemoveBtn}\n onClick={() => onRemove(fileId)}\n disabled={file.status === \"uploading\"}\n aria-label=\"删除文件\"\n >\n <CloseOutlined />\n </button>\n )}\n </div>\n );\n }\n\n // 视频文件\n if (isVideo) {\n return (\n <div\n className={`${styles.fileCard} ${align === \"right\" ? \"align-right\" : \"\"} ${className || \"\"}`}\n style={style}\n >\n <div className={styles.fileIcon} style={{ color: \"#fa8c16\" }}>\n <VideoCameraOutlined />\n </div>\n\n <div className={styles.fileInfo}>\n <Tooltip title={fileName}>\n <div className={styles.fileName}>{fileName}</div>\n </Tooltip>\n\n <video\n src={url}\n controls\n className={styles.mediaWrapper}\n style={{ width: \"100%\", height: 40 }}\n />\n </div>\n\n {removable && (\n <button\n className={styles.fileRemoveBtn}\n onClick={() => onRemove(fileId)}\n disabled={file.status === \"uploading\"}\n aria-label=\"删除文件\"\n >\n <CloseOutlined />\n </button>\n )}\n </div>\n );\n }\n\n // 其他文件\n const { icon, color } = getFileIcon(file);\n const isExternalUrl = url && url.startsWith(\"http\");\n\n return (\n <div\n className={`${styles.fileCard} ${align === \"right\" ? \"align-right\" : \"\"} ${className || \"\"}`}\n style={{ ...style, cursor: onClick ? \"pointer\" : undefined }}\n onClick={() => onClick?.(file)}\n >\n <div className={styles.fileIcon} style={{ color }}>\n {icon}\n </div>\n\n <div className={styles.fileInfo}>\n {isExternalUrl && !onClick ? (\n <a\n href={url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className={styles.fileLink}\n >\n <Tooltip title={fileName}>\n <div className={styles.fileName}>\n {fileName.length > 15\n ? `${fileName.substring(0, 15)}...`\n : fileName}\n </div>\n </Tooltip>\n </a>\n ) : (\n <Tooltip title={fileName}>\n <div className={styles.fileName}>\n {fileName.length > 15\n ? `${fileName.substring(0, 15)}...`\n : fileName}\n </div>\n </Tooltip>\n )}\n\n {file.status === \"uploading\" ? (\n <Progress\n percent={file.progress}\n size=\"small\"\n showInfo={false}\n strokeColor=\"#1677ff\"\n className={styles.progress}\n />\n ) : (\n fileSize > 0 && (\n <div className={styles.fileSize}>{formatFileSize(fileSize)}</div>\n )\n )}\n\n {file.status === \"error\" && file.errorMessage && (\n <div\n style={{\n fontSize: \"11px\",\n color: \"#ff4d4f\",\n marginTop: \"2px\",\n }}\n >\n {file.errorMessage}\n </div>\n )}\n </div>\n\n {removable && (\n <button\n className={styles.fileRemoveBtn}\n onClick={() => onRemove(fileId)}\n disabled={file.status === \"uploading\"}\n aria-label=\"删除文件\"\n >\n <CloseOutlined />\n </button>\n )}\n </div>\n );\n};\n\nexport default FileGallery;\n"],
5
5
  "mappings": "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",
6
6
  "names": ["url"]
7
7
  }
@@ -125,7 +125,7 @@ var useStyles = (0, import_common.withBasicStyles)(() => ({
125
125
  z-index: 10;
126
126
  pointer-events: none;
127
127
  }
128
- `,
128
+ `,
129
129
  /** 自定义拖拽 - 节点可拖拽样式 */
130
130
  dragNodeHandle: import_css.css`
131
131
  cursor: grab;
@@ -199,7 +199,10 @@ var useStyles = (0, import_common.withBasicStyles)(() => ({
199
199
  margin: 2px;
200
200
  color: #999;
201
201
  font-size: 12px;
202
+ line-height: 20px;
202
203
  transition: all 0.2s;
204
+ height: 20px;
205
+ box-sizing: border-box;
203
206
 
204
207
  &:hover {
205
208
  border-radius: 50%;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/components/FolderTree/styles.tsx"],
4
- "sourcesContent": ["import { css } from \"@emotion/css\";\nimport { withBasicStyles } from \"@/styles/common\";\n\nexport const useStyles = withBasicStyles(() => ({\n container: css`\n display: flex;\n width: 100%;\n height: 500px;\n border: 1px solid #e8e8e8;\n border-radius: 8px;\n overflow: hidden;\n background: #fff;\n `,\n containerNoPreview: css`\n height: auto;\n border: none;\n border-radius: 0;\n & > *:first-child {\n border-right: none;\n }\n `,\n directoryPanel: css`\n display: flex;\n flex-direction: column;\n height: 100%;\n overflow: auto;\n border-right: 1px solid #e8e8e8;\n background: var(--folder-tree-directory-bg, #fafafa);\n `,\n directoryTitle: css`\n padding: 12px 16px;\n font-weight: 600;\n font-size: 14px;\n border-bottom: 1px solid #e8e8e8;\n color: #333;\n `,\n directoryTreeContent: css`\n padding: 4px 8px;\n flex: 1;\n\n .ant-tree {\n background: transparent;\n height: 100%;\n }\n .ant-tree-switcher {\n margin-right: 0;\n }\n .ant-tree .ant-tree-node-content-wrapper {\n display: inline-flex;\n align-items: center;\n flex: 1;\n min-width: 0;\n padding-left: 0;\n overflow: hidden;\n }\n .ant-tree .ant-tree-title {\n flex: 1;\n min-width: 0;\n overflow: hidden;\n }\n .ant-tree-directory .ant-tree-treenode {\n position: relative;\n &::before {\n border-radius: 4px;\n }\n }\n /* 自定义拖拽样式 — 基于 ant-tree-treenode 定位,覆盖整行 */\n .ant-tree-treenode.folder-tree-drop-before::after {\n content: \"\";\n position: absolute;\n top: -2px;\n left: 0;\n right: 0;\n height: 2px;\n background: transparent;\n border-top: 2px dashed #1677ff;\n z-index: 10;\n pointer-events: none;\n }\n .ant-tree-treenode.folder-tree-drop-inside::after {\n content: \"\";\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n border: 2px dashed #1677ff;\n border-radius: 4px;\n background: rgba(22, 119, 255, 0.04);\n z-index: 10;\n pointer-events: none;\n }\n .ant-tree-treenode.folder-tree-drop-after::after {\n content: \"\";\n position: absolute;\n bottom: -2px;\n left: 0;\n right: 0;\n height: 2px;\n background: transparent;\n border-bottom: 2px dashed #1677ff;\n z-index: 10;\n pointer-events: none;\n }\n `,\n\n /** 自定义拖拽 - 节点可拖拽样式 */\n dragNodeHandle: css`\n cursor: grab;\n user-select: none;\n\n &:active {\n cursor: grabbing;\n }\n `,\n /** 树节点容器,用于相对定位 drop indicator */\n treeNodeWrapper: css`\n position: relative;\n min-width: 0;\n overflow: hidden;\n `,\n previewPanel: css`\n flex: 1;\n height: 100%;\n overflow: auto;\n display: flex;\n flex-direction: column;\n `,\n previewTitle: css`\n padding: 10px 16px;\n font-size: 13px;\n font-weight: 500;\n border-bottom: 1px solid #e8e8e8;\n display: flex;\n align-items: center;\n justify-content: space-between;\n color: #333;\n background: #fff;\n `,\n previewContent: css`\n flex: 1;\n overflow: auto;\n padding: 16px;\n font-size: 13px;\n line-height: 1.6;\n `,\n emptyContainer: css`\n display: flex;\n align-items: center;\n justify-content: center;\n height: 100%;\n `,\n loadingContainer: css`\n display: flex;\n align-items: center;\n justify-content: center;\n height: 100%;\n `,\n treeNodeTitle: css`\n display: flex;\n align-items: center;\n justify-content: space-between;\n min-width: 0;\n overflow: hidden;\n padding-right: 4px;\n\n > span:first-child {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n `,\n moreIcon: css`\n opacity: 0;\n cursor: pointer;\n padding: 0 4px;\n margin: 2px;\n color: #999;\n font-size: 12px;\n transition: all 0.2s;\n\n &:hover {\n border-radius: 50%;\n color: #333;\n background: rgba(0, 0, 0, 0.04);\n }\n `,\n treeNodeTitleHover: css`\n &:hover .folder-tree-more-icon {\n opacity: 1;\n }\n `,\n inlineInput: css`\n width: 100%;\n .ant-input {\n height: 22px;\n font-size: 13px;\n padding: 0 6px;\n border-radius: 4px;\n }\n `,\n copyBtn: css`\n cursor: pointer;\n color: #999;\n font-size: 14px;\n &:hover {\n color: #1677ff;\n }\n `,\n}));\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,iBAAoB;AACpB,oBAAgC;AAEzB,IAAM,gBAAY,+BAAgB,OAAO;AAAA,EAC9C,WAAW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASX,oBAAoB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQpB,gBAAgB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQhB,gBAAgB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOhB,sBAAsB;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;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;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAuEtB,gBAAgB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAShB,iBAAiB;AAAA;AAAA;AAAA;AAAA;AAAA,EAKjB,cAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOd,cAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWd,gBAAgB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOhB,gBAAgB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMhB,kBAAkB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMlB,eAAe;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcf,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeV,oBAAoB;AAAA;AAAA;AAAA;AAAA;AAAA,EAKpB,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASb,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAQX,EAAE;",
4
+ "sourcesContent": ["import { css } from \"@emotion/css\";\nimport { withBasicStyles } from \"@/styles/common\";\n\nexport const useStyles = withBasicStyles(() => ({\n container: css`\n display: flex;\n width: 100%;\n height: 500px;\n border: 1px solid #e8e8e8;\n border-radius: 8px;\n overflow: hidden;\n background: #fff;\n `,\n containerNoPreview: css`\n height: auto;\n border: none;\n border-radius: 0;\n & > *:first-child {\n border-right: none;\n }\n `,\n directoryPanel: css`\n display: flex;\n flex-direction: column;\n height: 100%;\n overflow: auto;\n border-right: 1px solid #e8e8e8;\n background: var(--folder-tree-directory-bg, #fafafa);\n `,\n directoryTitle: css`\n padding: 12px 16px;\n font-weight: 600;\n font-size: 14px;\n border-bottom: 1px solid #e8e8e8;\n color: #333;\n `,\n directoryTreeContent: css`\n padding: 4px 8px;\n flex: 1;\n\n .ant-tree {\n background: transparent;\n height: 100%;\n }\n .ant-tree-switcher {\n margin-right: 0;\n }\n .ant-tree .ant-tree-node-content-wrapper {\n display: inline-flex;\n align-items: center;\n flex: 1;\n min-width: 0;\n padding-left: 0;\n overflow: hidden;\n }\n .ant-tree .ant-tree-title {\n flex: 1;\n min-width: 0;\n overflow: hidden;\n }\n .ant-tree-directory .ant-tree-treenode {\n position: relative;\n &::before {\n border-radius: 4px;\n }\n }\n /* 自定义拖拽样式 — 基于 ant-tree-treenode 定位,覆盖整行 */\n .ant-tree-treenode.folder-tree-drop-before::after {\n content: \"\";\n position: absolute;\n top: -2px;\n left: 0;\n right: 0;\n height: 2px;\n background: transparent;\n border-top: 2px dashed #1677ff;\n z-index: 10;\n pointer-events: none;\n }\n .ant-tree-treenode.folder-tree-drop-inside::after {\n content: \"\";\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n border: 2px dashed #1677ff;\n border-radius: 4px;\n background: rgba(22, 119, 255, 0.04);\n z-index: 10;\n pointer-events: none;\n }\n .ant-tree-treenode.folder-tree-drop-after::after {\n content: \"\";\n position: absolute;\n bottom: -2px;\n left: 0;\n right: 0;\n height: 2px;\n background: transparent;\n border-bottom: 2px dashed #1677ff;\n z-index: 10;\n pointer-events: none;\n }\n `,\n\n /** 自定义拖拽 - 节点可拖拽样式 */\n dragNodeHandle: css`\n cursor: grab;\n user-select: none;\n\n &:active {\n cursor: grabbing;\n }\n `,\n /** 树节点容器,用于相对定位 drop indicator */\n treeNodeWrapper: css`\n position: relative;\n min-width: 0;\n overflow: hidden;\n `,\n previewPanel: css`\n flex: 1;\n height: 100%;\n overflow: auto;\n display: flex;\n flex-direction: column;\n `,\n previewTitle: css`\n padding: 10px 16px;\n font-size: 13px;\n font-weight: 500;\n border-bottom: 1px solid #e8e8e8;\n display: flex;\n align-items: center;\n justify-content: space-between;\n color: #333;\n background: #fff;\n `,\n previewContent: css`\n flex: 1;\n overflow: auto;\n padding: 16px;\n font-size: 13px;\n line-height: 1.6;\n `,\n emptyContainer: css`\n display: flex;\n align-items: center;\n justify-content: center;\n height: 100%;\n `,\n loadingContainer: css`\n display: flex;\n align-items: center;\n justify-content: center;\n height: 100%;\n `,\n treeNodeTitle: css`\n display: flex;\n align-items: center;\n justify-content: space-between;\n min-width: 0;\n overflow: hidden;\n padding-right: 4px;\n\n > span:first-child {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n `,\n moreIcon: css`\n opacity: 0;\n cursor: pointer;\n padding: 0 4px;\n margin: 2px;\n color: #999;\n font-size: 12px;\n line-height: 20px;\n transition: all 0.2s;\n height: 20px;\n box-sizing: border-box;\n\n &:hover {\n border-radius: 50%;\n color: #333;\n background: rgba(0, 0, 0, 0.04);\n }\n `,\n treeNodeTitleHover: css`\n &:hover .folder-tree-more-icon {\n opacity: 1;\n }\n `,\n inlineInput: css`\n width: 100%;\n .ant-input {\n height: 22px;\n font-size: 13px;\n padding: 0 6px;\n border-radius: 4px;\n }\n `,\n copyBtn: css`\n cursor: pointer;\n color: #999;\n font-size: 14px;\n &:hover {\n color: #1677ff;\n }\n `,\n}));\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,iBAAoB;AACpB,oBAAgC;AAEzB,IAAM,gBAAY,+BAAgB,OAAO;AAAA,EAC9C,WAAW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASX,oBAAoB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQpB,gBAAgB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQhB,gBAAgB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOhB,sBAAsB;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;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;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAuEtB,gBAAgB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAShB,iBAAiB;AAAA;AAAA;AAAA;AAAA;AAAA,EAKjB,cAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOd,cAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWd,gBAAgB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOhB,gBAAgB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMhB,kBAAkB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMlB,eAAe;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcf,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAkBV,oBAAoB;AAAA;AAAA;AAAA;AAAA;AAAA,EAKpB,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASb,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAQX,EAAE;",
6
6
  "names": []
7
7
  }
@@ -40,6 +40,7 @@ var import_ChatActionContext = require("./context/ChatActionContext");
40
40
  var import_SessionContext = require("./context/SessionContext");
41
41
  var import_useADKChat = __toESM(require("../../hooks/useADKChat"));
42
42
  var import_common = require("../../styles/common");
43
+ var import_tokens = require("../../styles/tokens");
43
44
  var import_xGroupAdk = require("../../presets/xGroupAdk");
44
45
  var import_Header = __toESM(require("./compound/Header"));
45
46
  var import_Sidebar = __toESM(require("./compound/Sidebar"));
@@ -238,6 +239,7 @@ var XAdkProviderComponent = (0, import_react.forwardRef)(
238
239
  "div",
239
240
  {
240
241
  style: {
242
+ ...import_tokens.cssVarStyle,
241
243
  display: "flex",
242
244
  height: "100%",
243
245
  width: "100%",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/components/XAdkProvider/index.tsx"],
4
- "sourcesContent": ["import React, { forwardRef, useImperativeHandle, useMemo } from \"react\";\nimport { ConfigProvider } from \"antd\";\nimport { XProvider } from \"@ant-design/x\";\nimport { ChatStateContext } from \"./context/ChatStateContext\";\nimport { ChatActionContext } from \"./context/ChatActionContext\";\nimport { SessionContext } from \"./context/SessionContext\";\nimport useADKChat from \"@/hooks/useADKChat\";\nimport { primaryBlue } from \"@/styles/common\";\nimport type {\n XAdkProviderProps,\n XAdkProviderHandle,\n XAdkProviderConfig,\n} from \"@/types/XAdkProvider\";\nimport type { ChatHookResult } from \"@/types/ChatHook\";\nimport {\n mergeChatStrategies,\n resolvePresetUploadRequest,\n} from \"@/presets/xGroupAdk\";\n\n/**\n * XAdkProvider Props (扩展版)\n *\n * 支持两种使用方式:\n * 1. 标准协议: 提供 url/token/config,使用内置 useADKChat\n * 2. 自定义协议: 提供 chatData,使用自己的 Hook\n */\nexport interface XAdkProviderPropsExtended extends Omit<\n XAdkProviderProps,\n \"url\" | \"token\" | \"config\"\n> {\n /**\n * 选项 A: 使用标准协议 (内置 useADKChat)\n */\n url?: string;\n token: string;\n config?: XAdkProviderConfig;\n\n /**\n * 选项 B: 使用自定义 Hook 数据\n * 如果提供此参数,将忽略 url/token/config\n *\n * @example\n * // GraphQL 协议\n * const chatData = useMyGraphQLChat({ endpoint: '...' });\n * <XAdkProvider chatData={chatData}>\n * <XAdkProvider.DefaultLayout />\n * </XAdkProvider>\n *\n * @example\n * // WebSocket 协议\n * const chatData = useWebSocketChat({ url: 'ws://...' });\n * <XAdkProvider chatData={chatData}>\n * <XAdkProvider.DefaultLayout />\n * </XAdkProvider>\n */\n chatData?: ChatHookResult;\n\n children: React.ReactNode;\n}\n\n/**\n * XAdkProvider - AI 聊天 SDK 核心 Provider\n *\n * 采用 Compound Components 架构:\n * - 只负责数据和状态管理\n * - 不包含 UI 布局\n * - 通过 Context 向子组件提供数据\n * - 支持完全自定义的组件组合\n * - 支持协议解耦,可使用自定义 Hook\n *\n * @example\n * // 基础用法 - 标准协议\n * <XAdkProvider url=\"...\" token=\"...\" config={...}>\n * <XAdkProvider.Chatbot />\n * </XAdkProvider>\n *\n * @example\n * // 自定义协议 - GraphQL\n * function App() {\n * const chatData = useMyGraphQLChat({ endpoint: '...' });\n * return (\n * <XAdkProvider chatData={chatData}>\n * <XAdkProvider.DefaultLayout />\n * </XAdkProvider>\n * );\n * }\n *\n * @example\n * // 自定义布局\n * <XAdkProvider url=\"...\" token=\"...\">\n * <div style={{ display: 'flex' }}>\n * <XAdkProvider.Sidebar />\n * <div>\n * <XAdkProvider.Messages />\n * <XAdkProvider.Sender />\n * </div>\n * </div>\n * </XAdkProvider>\n */\nconst XAdkProviderComponent = forwardRef<\n XAdkProviderHandle,\n XAdkProviderPropsExtended\n>(\n (\n {\n url = window.location.origin,\n token,\n config,\n preset,\n strategies,\n chatData, // 自定义 Hook 数据\n providerId = \"defaultId\",\n onSuccess,\n onError,\n onMessage,\n onStream,\n children,\n },\n ref,\n ) => {\n const mergedStrategies = useMemo(\n () =>\n mergeChatStrategies(\n preset ?? config?.preset,\n {\n ...config?.strategies,\n ...strategies,\n },\n ),\n [preset, strategies, config?.preset, config?.strategies],\n );\n\n // 内置 Hook 数据 (仅在没有提供 chatData 时调用)\n const internalData = useADKChat({\n url,\n token: token || \"\",\n config: config || {},\n strategies: mergedStrategies,\n onError,\n onSuccess,\n onMessage,\n onStream,\n // 仅在提供了 url 和 token 时才初始化\n enabled: !chatData && !!url && !!token,\n });\n\n // 使用外部数据或内部数据\n const data = chatData || internalData;\n\n // 解构数据\n const {\n appInfo,\n startChat,\n stopChat,\n reChat,\n clearChat,\n suggestChat,\n confirmFnCall,\n deleteSession,\n updateSession,\n currentSessionId,\n sessionPagination,\n sessionList,\n messages,\n loading,\n prologue,\n suggestions,\n initialized,\n setCurrentSession,\n setMessages,\n likeMessage = async () => false,\n setStateDelta = () => {},\n } = data;\n\n const showFeedback = config?.showFeedback ?? true;\n const onFileClick = config?.onFileClick;\n const presetUploadRequest = useMemo(\n () =>\n resolvePresetUploadRequest(preset ?? config?.preset, {\n url,\n token,\n appNo: config?.appNo,\n }),\n [preset, config?.preset, url, token, config?.appNo],\n );\n const uploadRequest = config?.uploadRequest ?? presetUploadRequest;\n\n // 暴露 API 给 ref\n useImperativeHandle(\n ref,\n () => ({\n startChat,\n stopChat,\n reChat,\n clearChat,\n suggestChat,\n deleteSession,\n updateSession,\n getAppInfo: () => appInfo,\n getMessages: () => messages,\n getSessions: () => sessionList,\n setMessages,\n setCurrentSession,\n setStateDelta,\n }),\n [\n appInfo,\n messages,\n sessionList,\n startChat,\n stopChat,\n reChat,\n clearChat,\n suggestChat,\n deleteSession,\n updateSession,\n setMessages,\n setCurrentSession,\n setStateDelta,\n ],\n );\n\n // 状态 Context Value - 使用 useMemo 避免不必要的 rerender\n const chatStateValue = useMemo(\n () => ({\n messages,\n loading,\n currentSessionId,\n prologue,\n suggestions,\n appInfo,\n initialized,\n url,\n token,\n showFeedback,\n onFileClick,\n uploadRequest,\n strategies: mergedStrategies,\n }),\n [\n messages,\n loading,\n currentSessionId,\n prologue,\n suggestions,\n appInfo,\n initialized,\n showFeedback,\n onFileClick,\n uploadRequest,\n mergedStrategies,\n ],\n );\n\n // 动作 Context Value - 函数引用稳定,不需要每次都创建新对象\n const chatActionValue = useMemo(\n () => ({\n chat: startChat,\n stopChat,\n clearChat,\n reChat,\n suggestChat,\n confirmFnCall,\n setMessages,\n likeMessage,\n setStateDelta,\n }),\n [\n startChat,\n stopChat,\n clearChat,\n reChat,\n suggestChat,\n confirmFnCall,\n setMessages,\n likeMessage,\n setStateDelta,\n ],\n );\n\n // 会话 Context Value\n const sessionValue = useMemo(\n () => ({\n sessionList,\n sessionPagination,\n deleteSession,\n updateSession,\n setCurrentSession,\n }),\n [\n sessionList,\n sessionPagination,\n deleteSession,\n updateSession,\n setCurrentSession,\n ],\n );\n\n return (\n <ConfigProvider\n theme={{\n token: {\n colorPrimary: appInfo?.appTheme || primaryBlue,\n },\n }}\n >\n <XProvider>\n <ChatStateContext.Provider value={chatStateValue}>\n <ChatActionContext.Provider value={chatActionValue}>\n <SessionContext.Provider value={sessionValue}>\n <div\n style={{\n display: \"flex\",\n height: \"100%\",\n width: \"100%\",\n position: \"relative\",\n }}\n >\n {children}\n </div>\n </SessionContext.Provider>\n </ChatActionContext.Provider>\n </ChatStateContext.Provider>\n </XProvider>\n </ConfigProvider>\n );\n },\n);\n\nXAdkProviderComponent.displayName = \"XAdkProvider\";\n\n// 导入 Compound Components\nimport Header from \"./compound/Header\";\nimport Sidebar from \"./compound/Sidebar\";\nimport Messages from \"./compound/Messages\";\nimport Sender from \"./compound/Sender\";\nimport Chatbot from \"./compound/Chatbot\";\nimport Welcome from \"./compound/Welcome\";\nimport DefaultLayout from \"./compound/DefaultLayout\";\n\n// 导出时会挂载 Compound Components\nconst XAdkProvider = XAdkProviderComponent as typeof XAdkProviderComponent & {\n Header: typeof Header;\n Sidebar: typeof Sidebar;\n Messages: typeof Messages;\n Sender: typeof Sender;\n Chatbot: typeof Chatbot;\n Welcome: typeof Welcome;\n DefaultLayout: typeof DefaultLayout;\n};\n\n// 挂载 Compound Components\nXAdkProvider.Header = Header;\nXAdkProvider.Sidebar = Sidebar;\nXAdkProvider.Messages = Messages;\nXAdkProvider.Sender = Sender;\nXAdkProvider.Chatbot = Chatbot;\nXAdkProvider.DefaultLayout = DefaultLayout;\nXAdkProvider.Welcome = Welcome;\n\nexport default XAdkProvider;\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import React, { forwardRef, useImperativeHandle, useMemo } from \"react\";\nimport { ConfigProvider } from \"antd\";\nimport { XProvider } from \"@ant-design/x\";\nimport { ChatStateContext } from \"./context/ChatStateContext\";\nimport { ChatActionContext } from \"./context/ChatActionContext\";\nimport { SessionContext } from \"./context/SessionContext\";\nimport useADKChat from \"@/hooks/useADKChat\";\nimport { primaryBlue } from \"@/styles/common\";\nimport { cssVarStyle } from \"@/styles/tokens\";\nimport type {\n XAdkProviderProps,\n XAdkProviderHandle,\n XAdkProviderConfig,\n} from \"@/types/XAdkProvider\";\nimport type { ChatHookResult } from \"@/types/ChatHook\";\nimport {\n mergeChatStrategies,\n resolvePresetUploadRequest,\n} from \"@/presets/xGroupAdk\";\n\n/**\n * XAdkProvider Props (扩展版)\n *\n * 支持两种使用方式:\n * 1. 标准协议: 提供 url/token/config,使用内置 useADKChat\n * 2. 自定义协议: 提供 chatData,使用自己的 Hook\n */\nexport interface XAdkProviderPropsExtended extends Omit<\n XAdkProviderProps,\n \"url\" | \"token\" | \"config\"\n> {\n /**\n * 选项 A: 使用标准协议 (内置 useADKChat)\n */\n url?: string;\n token: string;\n config?: XAdkProviderConfig;\n\n /**\n * 选项 B: 使用自定义 Hook 数据\n * 如果提供此参数,将忽略 url/token/config\n *\n * @example\n * // GraphQL 协议\n * const chatData = useMyGraphQLChat({ endpoint: '...' });\n * <XAdkProvider chatData={chatData}>\n * <XAdkProvider.DefaultLayout />\n * </XAdkProvider>\n *\n * @example\n * // WebSocket 协议\n * const chatData = useWebSocketChat({ url: 'ws://...' });\n * <XAdkProvider chatData={chatData}>\n * <XAdkProvider.DefaultLayout />\n * </XAdkProvider>\n */\n chatData?: ChatHookResult;\n\n children: React.ReactNode;\n}\n\n/**\n * XAdkProvider - AI 聊天 SDK 核心 Provider\n *\n * 采用 Compound Components 架构:\n * - 只负责数据和状态管理\n * - 不包含 UI 布局\n * - 通过 Context 向子组件提供数据\n * - 支持完全自定义的组件组合\n * - 支持协议解耦,可使用自定义 Hook\n *\n * @example\n * // 基础用法 - 标准协议\n * <XAdkProvider url=\"...\" token=\"...\" config={...}>\n * <XAdkProvider.Chatbot />\n * </XAdkProvider>\n *\n * @example\n * // 自定义协议 - GraphQL\n * function App() {\n * const chatData = useMyGraphQLChat({ endpoint: '...' });\n * return (\n * <XAdkProvider chatData={chatData}>\n * <XAdkProvider.DefaultLayout />\n * </XAdkProvider>\n * );\n * }\n *\n * @example\n * // 自定义布局\n * <XAdkProvider url=\"...\" token=\"...\">\n * <div style={{ display: 'flex' }}>\n * <XAdkProvider.Sidebar />\n * <div>\n * <XAdkProvider.Messages />\n * <XAdkProvider.Sender />\n * </div>\n * </div>\n * </XAdkProvider>\n */\nconst XAdkProviderComponent = forwardRef<\n XAdkProviderHandle,\n XAdkProviderPropsExtended\n>(\n (\n {\n url = window.location.origin,\n token,\n config,\n preset,\n strategies,\n chatData, // 自定义 Hook 数据\n providerId = \"defaultId\",\n onSuccess,\n onError,\n onMessage,\n onStream,\n children,\n },\n ref,\n ) => {\n const mergedStrategies = useMemo(\n () =>\n mergeChatStrategies(\n preset ?? config?.preset,\n {\n ...config?.strategies,\n ...strategies,\n },\n ),\n [preset, strategies, config?.preset, config?.strategies],\n );\n\n // 内置 Hook 数据 (仅在没有提供 chatData 时调用)\n const internalData = useADKChat({\n url,\n token: token || \"\",\n config: config || {},\n strategies: mergedStrategies,\n onError,\n onSuccess,\n onMessage,\n onStream,\n // 仅在提供了 url 和 token 时才初始化\n enabled: !chatData && !!url && !!token,\n });\n\n // 使用外部数据或内部数据\n const data = chatData || internalData;\n\n // 解构数据\n const {\n appInfo,\n startChat,\n stopChat,\n reChat,\n clearChat,\n suggestChat,\n confirmFnCall,\n deleteSession,\n updateSession,\n currentSessionId,\n sessionPagination,\n sessionList,\n messages,\n loading,\n prologue,\n suggestions,\n initialized,\n setCurrentSession,\n setMessages,\n likeMessage = async () => false,\n setStateDelta = () => {},\n } = data;\n\n const showFeedback = config?.showFeedback ?? true;\n const onFileClick = config?.onFileClick;\n const presetUploadRequest = useMemo(\n () =>\n resolvePresetUploadRequest(preset ?? config?.preset, {\n url,\n token,\n appNo: config?.appNo,\n }),\n [preset, config?.preset, url, token, config?.appNo],\n );\n const uploadRequest = config?.uploadRequest ?? presetUploadRequest;\n\n // 暴露 API 给 ref\n useImperativeHandle(\n ref,\n () => ({\n startChat,\n stopChat,\n reChat,\n clearChat,\n suggestChat,\n deleteSession,\n updateSession,\n getAppInfo: () => appInfo,\n getMessages: () => messages,\n getSessions: () => sessionList,\n setMessages,\n setCurrentSession,\n setStateDelta,\n }),\n [\n appInfo,\n messages,\n sessionList,\n startChat,\n stopChat,\n reChat,\n clearChat,\n suggestChat,\n deleteSession,\n updateSession,\n setMessages,\n setCurrentSession,\n setStateDelta,\n ],\n );\n\n // 状态 Context Value - 使用 useMemo 避免不必要的 rerender\n const chatStateValue = useMemo(\n () => ({\n messages,\n loading,\n currentSessionId,\n prologue,\n suggestions,\n appInfo,\n initialized,\n url,\n token,\n showFeedback,\n onFileClick,\n uploadRequest,\n strategies: mergedStrategies,\n }),\n [\n messages,\n loading,\n currentSessionId,\n prologue,\n suggestions,\n appInfo,\n initialized,\n showFeedback,\n onFileClick,\n uploadRequest,\n mergedStrategies,\n ],\n );\n\n // 动作 Context Value - 函数引用稳定,不需要每次都创建新对象\n const chatActionValue = useMemo(\n () => ({\n chat: startChat,\n stopChat,\n clearChat,\n reChat,\n suggestChat,\n confirmFnCall,\n setMessages,\n likeMessage,\n setStateDelta,\n }),\n [\n startChat,\n stopChat,\n clearChat,\n reChat,\n suggestChat,\n confirmFnCall,\n setMessages,\n likeMessage,\n setStateDelta,\n ],\n );\n\n // 会话 Context Value\n const sessionValue = useMemo(\n () => ({\n sessionList,\n sessionPagination,\n deleteSession,\n updateSession,\n setCurrentSession,\n }),\n [\n sessionList,\n sessionPagination,\n deleteSession,\n updateSession,\n setCurrentSession,\n ],\n );\n\n return (\n <ConfigProvider\n theme={{\n token: {\n colorPrimary: appInfo?.appTheme || primaryBlue,\n },\n }}\n >\n <XProvider>\n <ChatStateContext.Provider value={chatStateValue}>\n <ChatActionContext.Provider value={chatActionValue}>\n <SessionContext.Provider value={sessionValue}>\n <div\n style={{\n ...cssVarStyle,\n display: \"flex\",\n height: \"100%\",\n width: \"100%\",\n position: \"relative\",\n } as React.CSSProperties}\n >\n {children}\n </div>\n </SessionContext.Provider>\n </ChatActionContext.Provider>\n </ChatStateContext.Provider>\n </XProvider>\n </ConfigProvider>\n );\n },\n);\n\nXAdkProviderComponent.displayName = \"XAdkProvider\";\n\n// 导入 Compound Components\nimport Header from \"./compound/Header\";\nimport Sidebar from \"./compound/Sidebar\";\nimport Messages from \"./compound/Messages\";\nimport Sender from \"./compound/Sender\";\nimport Chatbot from \"./compound/Chatbot\";\nimport Welcome from \"./compound/Welcome\";\nimport DefaultLayout from \"./compound/DefaultLayout\";\n\n// 导出时会挂载 Compound Components\nconst XAdkProvider = XAdkProviderComponent as typeof XAdkProviderComponent & {\n Header: typeof Header;\n Sidebar: typeof Sidebar;\n Messages: typeof Messages;\n Sender: typeof Sender;\n Chatbot: typeof Chatbot;\n Welcome: typeof Welcome;\n DefaultLayout: typeof DefaultLayout;\n};\n\n// 挂载 Compound Components\nXAdkProvider.Header = Header;\nXAdkProvider.Sidebar = Sidebar;\nXAdkProvider.Messages = Messages;\nXAdkProvider.Sender = Sender;\nXAdkProvider.Chatbot = Chatbot;\nXAdkProvider.DefaultLayout = DefaultLayout;\nXAdkProvider.Welcome = Welcome;\n\nexport default XAdkProvider;\n"],
5
+ "mappings": "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",
6
6
  "names": ["useADKChat", "Header", "Sidebar", "Messages", "Sender", "Chatbot", "DefaultLayout", "Welcome"]
7
7
  }
@@ -129,7 +129,23 @@ var TimelineToolItem = ({
129
129
  }
130
130
  );
131
131
  };
132
+ var StatusIcon = ({ status }) => {
133
+ switch (status) {
134
+ case "loading":
135
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_icons.SyncOutlined, { spin: true, style: { color: "#1677ff" } });
136
+ case "success":
137
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_icons.CheckCircleFilled, { style: { color: "#52c41a" } });
138
+ case "error":
139
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_icons.CloseCircleFilled, { style: { color: "#ff4d4f" } });
140
+ case "pending":
141
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_icons.ClockCircleOutlined, { style: { color: "#8c8c8c" } });
142
+ }
143
+ };
132
144
  var XAdkThoughtChain = ({
145
+ collapsible: showCollapsibleHeader = false,
146
+ status,
147
+ className,
148
+ style,
133
149
  defaultOpen = false,
134
150
  showFnCallDetail = false,
135
151
  title = "思维链已完成",
@@ -142,48 +158,68 @@ var XAdkThoughtChain = ({
142
158
  strategies
143
159
  }) => {
144
160
  const styles = (0, import_styles.useStyles)();
161
+ const effectiveStatus = status ?? (loading ? "loading" : "success");
162
+ const isLoading = effectiveStatus === "loading";
145
163
  const [isOpen, setIsOpen] = (0, import_react.useState)(defaultOpen);
146
164
  (0, import_react.useEffect)(() => {
147
- if (loading)
165
+ if (isLoading)
148
166
  Promise.resolve().then(() => setIsOpen(true));
149
- }, [loading]);
150
- const shouldBlink = blink && loading;
151
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: styles.thoughtChainBlock, children: [
152
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: styles.thoughtHeader, onClick: () => setIsOpen(!isOpen), children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: styles.headerLeft, children: [
153
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: styles.statusIcon, children: loading ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_icons.SyncOutlined, { spin: true, style: { color: "#1677ff" } }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_icons.CheckCircleFilled, { style: { color: "#52c41a" } }) }),
154
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
155
- "span",
156
- {
157
- className: `${styles.headerTitle}${shouldBlink ? ` ${styles.blink}` : ""}`,
158
- children: loading ? "深度思考与执行中..." : title
159
- }
160
- ),
161
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: `${styles.caret} ${isOpen ? "open" : ""}`, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_icons.RightOutlined, {}) })
162
- ] }) }),
163
- isOpen && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: styles.thinkingBody, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: styles.timeline, children: items.map(
164
- (item, i) => item.type === "text" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
165
- TimelineTextItem,
166
- {
167
- item,
168
- blink: shouldBlink
169
- },
170
- item.key || i
171
- ) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
172
- TimelineToolItem,
173
- {
174
- msg: item.msg,
175
- collapsible: item.collapsible,
176
- showFnCallDetail,
177
- onConfirm,
178
- blink: shouldBlink,
179
- renderFunctionCall,
180
- toolKindResolver,
181
- strategies
182
- },
183
- `tool-${item.key || i}`
184
- )
185
- ) }) })
186
- ] });
167
+ }, [isLoading]);
168
+ const shouldBlink = blink && isLoading;
169
+ const renderTimeline = () => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: styles.timeline, children: items.map(
170
+ (item, i) => item.type === "text" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
171
+ TimelineTextItem,
172
+ {
173
+ item,
174
+ blink: shouldBlink
175
+ },
176
+ item.key || i
177
+ ) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
178
+ TimelineToolItem,
179
+ {
180
+ msg: item.msg,
181
+ collapsible: item.collapsible,
182
+ showFnCallDetail,
183
+ onConfirm,
184
+ blink: shouldBlink,
185
+ renderFunctionCall,
186
+ toolKindResolver,
187
+ strategies
188
+ },
189
+ `tool-${item.key || i}`
190
+ )
191
+ ) });
192
+ if (!showCollapsibleHeader) {
193
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
194
+ "div",
195
+ {
196
+ className: `${styles.thoughtChainBlock}${className ? ` ${className}` : ""}`,
197
+ style,
198
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: styles.thinkingBody, children: renderTimeline() })
199
+ }
200
+ );
201
+ }
202
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
203
+ "div",
204
+ {
205
+ className: `${styles.thoughtChainBlock}${className ? ` ${className}` : ""}`,
206
+ style,
207
+ children: [
208
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: styles.thoughtHeader, onClick: () => setIsOpen(!isOpen), children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: styles.headerLeft, children: [
209
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: styles.statusIcon, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(StatusIcon, { status: effectiveStatus }) }),
210
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
211
+ "span",
212
+ {
213
+ className: `${styles.headerTitle}${shouldBlink ? ` ${styles.blink}` : ""}`,
214
+ children: isLoading ? "深度思考与执行中..." : title
215
+ }
216
+ ),
217
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: `${styles.caret} ${isOpen ? "open" : ""}`, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_icons.RightOutlined, {}) })
218
+ ] }) }),
219
+ isOpen && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: styles.thinkingBody, children: renderTimeline() })
220
+ ]
221
+ }
222
+ );
187
223
  };
188
224
  var XAdkThoughtChain_default = XAdkThoughtChain;
189
225
  //# sourceMappingURL=index.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/components/XAdkThoughtChain/index.tsx"],
4
- "sourcesContent": ["import React, { useState, useEffect } from \"react\";\nimport {\n CheckCircleFilled,\n SyncOutlined,\n ThunderboltOutlined,\n PartitionOutlined,\n RightOutlined,\n DownOutlined,\n} from \"@ant-design/icons\";\nimport MarkdownRender from \"@/components/XAdkChatbot/components/MarkdownRender\";\nimport FunctionCallRender from \"@/components/XAdkChatbot/components/FunctionCallRender\";\nimport { useStyles } from \"./styles\";\nimport {\n XAdkThoughtChainProps,\n ThoughtChainItemType,\n TimelineItemProps,\n FunctionCall,\n IMessage,\n RenderFunctionCall,\n ToolRenderKind,\n} from \"@/types\";\nimport { defaultToolKindResolver } from \"@/types/FunctionCallRender\";\nimport { cleanProcessText } from \"@/utils\";\n\nconst TimelineItem = ({\n icon,\n title,\n children,\n collapsible = true,\n defaultOpen = true,\n blink,\n}: TimelineItemProps) => {\n const [isOpen, setIsOpen] = useState(defaultOpen);\n const styles = useStyles();\n\n return (\n <div className={styles.timelineItem}>\n <div className={styles.timelineLeft}>\n {icon}\n <div className={styles.timelineConnector} />\n </div>\n <div className={styles.timelineRight}>\n <div\n className={styles.collapsibleHeader}\n onClick={() => (collapsible ? setIsOpen(!isOpen) : undefined)}\n >\n <div className={blink ? styles.blink : undefined}>{title}</div>\n {collapsible && (\n <span className={styles.arrowIcon}>\n {isOpen ? <DownOutlined /> : <RightOutlined />}\n </span>\n )}\n </div>\n\n {isOpen && <div className={styles.stepContent}>{children}</div>}\n </div>\n </div>\n );\n};\n\nconst TimelineTextItem: React.FC<{\n item: ThoughtChainItemType;\n blink?: boolean;\n}> = ({ item, blink }) => {\n return (\n <TimelineItem\n icon={\n <span className={useStyles().timelineIcon}>\n <PartitionOutlined />\n </span>\n }\n title={<span className={useStyles().titleText}>{item.title}</span>}\n blink={blink}\n >\n <MarkdownRender text={cleanProcessText(item.content)} />\n </TimelineItem>\n );\n};\n\nconst TimelineToolItem: React.FC<{\n msg: IMessage;\n collapsible?: boolean;\n showFnCallDetail: boolean;\n onConfirm?: (fnCall: FunctionCall, confirmed: boolean) => void;\n blink?: boolean;\n renderFunctionCall?: RenderFunctionCall;\n toolKindResolver: (name: string | undefined) => ToolRenderKind;\n strategies?: XAdkThoughtChainProps[\"strategies\"];\n}> = ({\n msg,\n collapsible,\n onConfirm,\n showFnCallDetail,\n blink,\n renderFunctionCall,\n toolKindResolver,\n strategies,\n}) => {\n const styles = useStyles();\n const fnName = msg.functionCall?.name;\n const kind = toolKindResolver(fnName);\n const needsConfirm = msg.functionCall && !msg.functionResponse;\n const isDone = !!msg.functionResponse;\n\n const toolName =\n msg.functionCall?.args?.componentName ||\n msg.functionCall?.name ||\n \"组件执行\";\n\n const statusInfo =\n msg.functionResponse?.response?.processData ||\n msg.functionResponse?.response?.output;\n\n const titleNode = (\n <div className={styles.toolTitleGroup}>\n <span className={styles.toolName}>{toolName}</span>\n {isDone && <span className={styles.toolStatusTag}>执行成功</span>}\n </div>\n );\n\n return (\n <TimelineItem\n icon={\n <span className={styles.timelineIconTool}>\n <ThunderboltOutlined />\n </span>\n }\n title={titleNode}\n collapsible={collapsible}\n defaultOpen={needsConfirm}\n blink={blink}\n >\n {statusInfo && typeof statusInfo === \"string\" && (\n <div className={styles.statusInfo}>{statusInfo}</div>\n )}\n {renderFunctionCall?.(msg) ?? (\n <FunctionCallRender\n msg={msg}\n showDetail={showFnCallDetail}\n onConfirm={onConfirm}\n kind={kind}\n renderApproval={strategies?.renderApproval}\n renderHandoff={strategies?.renderHandoff}\n />\n )}\n </TimelineItem>\n );\n};\n\nconst XAdkThoughtChain: React.FC<XAdkThoughtChainProps> = ({\n defaultOpen = false,\n showFnCallDetail = false,\n title = \"思维链已完成\",\n items = [],\n loading,\n blink = false,\n onConfirm,\n renderFunctionCall,\n toolKindResolver = defaultToolKindResolver,\n strategies,\n}) => {\n const styles = useStyles();\n const [isOpen, setIsOpen] = useState(defaultOpen);\n useEffect(() => {\n if (loading) Promise.resolve().then(() => setIsOpen(true));\n }, [loading]);\n\n const shouldBlink = blink && loading;\n\n return (\n <div className={styles.thoughtChainBlock}>\n <div className={styles.thoughtHeader} onClick={() => setIsOpen(!isOpen)}>\n <div className={styles.headerLeft}>\n <div className={styles.statusIcon}>\n {loading ? (\n <SyncOutlined spin style={{ color: \"#1677ff\" }} />\n ) : (\n <CheckCircleFilled style={{ color: \"#52c41a\" }} />\n )}\n </div>\n <span\n className={`${styles.headerTitle}${shouldBlink ? ` ${styles.blink}` : \"\"}`}\n >\n {loading ? \"深度思考与执行中...\" : title}\n </span>\n <div className={`${styles.caret} ${isOpen ? \"open\" : \"\"}`}>\n <RightOutlined />\n </div>\n </div>\n </div>\n {isOpen && (\n <div className={styles.thinkingBody}>\n <div className={styles.timeline}>\n {items.map((item, i) =>\n item.type === \"text\" ? (\n <TimelineTextItem\n key={item.key || i}\n item={item}\n blink={shouldBlink}\n />\n ) : (\n <TimelineToolItem\n key={`tool-${item.key || i}`}\n msg={item.msg!}\n collapsible={item.collapsible}\n showFnCallDetail={showFnCallDetail}\n onConfirm={onConfirm}\n blink={shouldBlink}\n renderFunctionCall={renderFunctionCall}\n toolKindResolver={toolKindResolver}\n strategies={strategies}\n />\n ),\n )}\n </div>\n </div>\n )}\n </div>\n );\n};\n\nexport default XAdkThoughtChain;\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import React, { useState, useEffect } from \"react\";\nimport {\n CheckCircleFilled,\n CloseCircleFilled,\n ClockCircleOutlined,\n SyncOutlined,\n ThunderboltOutlined,\n PartitionOutlined,\n RightOutlined,\n DownOutlined,\n} from \"@ant-design/icons\";\nimport MarkdownRender from \"@/components/XAdkChatbot/components/MarkdownRender\";\nimport FunctionCallRender from \"@/components/XAdkChatbot/components/FunctionCallRender\";\nimport { useStyles } from \"./styles\";\nimport {\n XAdkThoughtChainProps,\n ThoughtChainItemType,\n ThoughtChainStatus,\n TimelineItemProps,\n FunctionCall,\n IMessage,\n RenderFunctionCall,\n ToolRenderKind,\n} from \"@/types\";\nimport { defaultToolKindResolver } from \"@/types/FunctionCallRender\";\nimport { cleanProcessText } from \"@/utils\";\n\nconst TimelineItem = ({\n icon,\n title,\n children,\n collapsible = true,\n defaultOpen = true,\n blink,\n}: TimelineItemProps) => {\n const [isOpen, setIsOpen] = useState(defaultOpen);\n const styles = useStyles();\n\n return (\n <div className={styles.timelineItem}>\n <div className={styles.timelineLeft}>\n {icon}\n <div className={styles.timelineConnector} />\n </div>\n <div className={styles.timelineRight}>\n <div\n className={styles.collapsibleHeader}\n onClick={() => (collapsible ? setIsOpen(!isOpen) : undefined)}\n >\n <div className={blink ? styles.blink : undefined}>{title}</div>\n {collapsible && (\n <span className={styles.arrowIcon}>\n {isOpen ? <DownOutlined /> : <RightOutlined />}\n </span>\n )}\n </div>\n\n {isOpen && <div className={styles.stepContent}>{children}</div>}\n </div>\n </div>\n );\n};\n\nconst TimelineTextItem: React.FC<{\n item: ThoughtChainItemType;\n blink?: boolean;\n}> = ({ item, blink }) => {\n return (\n <TimelineItem\n icon={\n <span className={useStyles().timelineIcon}>\n <PartitionOutlined />\n </span>\n }\n title={<span className={useStyles().titleText}>{item.title}</span>}\n blink={blink}\n >\n <MarkdownRender text={cleanProcessText(item.content)} />\n </TimelineItem>\n );\n};\n\nconst TimelineToolItem: React.FC<{\n msg: IMessage;\n collapsible?: boolean;\n showFnCallDetail: boolean;\n onConfirm?: (fnCall: FunctionCall, confirmed: boolean) => void;\n blink?: boolean;\n renderFunctionCall?: RenderFunctionCall;\n toolKindResolver: (name: string | undefined) => ToolRenderKind;\n strategies?: XAdkThoughtChainProps[\"strategies\"];\n}> = ({\n msg,\n collapsible,\n onConfirm,\n showFnCallDetail,\n blink,\n renderFunctionCall,\n toolKindResolver,\n strategies,\n}) => {\n const styles = useStyles();\n const fnName = msg.functionCall?.name;\n const kind = toolKindResolver(fnName);\n const needsConfirm = msg.functionCall && !msg.functionResponse;\n const isDone = !!msg.functionResponse;\n\n const toolName =\n msg.functionCall?.args?.componentName ||\n msg.functionCall?.name ||\n \"组件执行\";\n\n const statusInfo =\n msg.functionResponse?.response?.processData ||\n msg.functionResponse?.response?.output;\n\n const titleNode = (\n <div className={styles.toolTitleGroup}>\n <span className={styles.toolName}>{toolName}</span>\n {isDone && <span className={styles.toolStatusTag}>执行成功</span>}\n </div>\n );\n\n return (\n <TimelineItem\n icon={\n <span className={styles.timelineIconTool}>\n <ThunderboltOutlined />\n </span>\n }\n title={titleNode}\n collapsible={collapsible}\n defaultOpen={needsConfirm}\n blink={blink}\n >\n {statusInfo && typeof statusInfo === \"string\" && (\n <div className={styles.statusInfo}>{statusInfo}</div>\n )}\n {renderFunctionCall?.(msg) ?? (\n <FunctionCallRender\n msg={msg}\n showDetail={showFnCallDetail}\n onConfirm={onConfirm}\n kind={kind}\n renderApproval={strategies?.renderApproval}\n renderHandoff={strategies?.renderHandoff}\n />\n )}\n </TimelineItem>\n );\n};\n\nconst StatusIcon: React.FC<{ status: ThoughtChainStatus }> = ({ status }) => {\n switch (status) {\n case \"loading\":\n return <SyncOutlined spin style={{ color: \"#1677ff\" }} />;\n case \"success\":\n return <CheckCircleFilled style={{ color: \"#52c41a\" }} />;\n case \"error\":\n return <CloseCircleFilled style={{ color: \"#ff4d4f\" }} />;\n case \"pending\":\n return <ClockCircleOutlined style={{ color: \"#8c8c8c\" }} />;\n }\n};\n\nconst XAdkThoughtChain: React.FC<XAdkThoughtChainProps> = ({\n collapsible: showCollapsibleHeader = false,\n status,\n className,\n style,\n defaultOpen = false,\n showFnCallDetail = false,\n title = \"思维链已完成\",\n items = [],\n loading,\n blink = false,\n onConfirm,\n renderFunctionCall,\n toolKindResolver = defaultToolKindResolver,\n strategies,\n}) => {\n const styles = useStyles();\n\n // status 优先,loading 向后兼容\n const effectiveStatus: ThoughtChainStatus =\n status ?? (loading ? \"loading\" : \"success\");\n const isLoading = effectiveStatus === \"loading\";\n\n const [isOpen, setIsOpen] = useState(defaultOpen);\n useEffect(() => {\n if (isLoading) Promise.resolve().then(() => setIsOpen(true));\n }, [isLoading]);\n\n const shouldBlink = blink && isLoading;\n\n const renderTimeline = () => (\n <div className={styles.timeline}>\n {items.map((item, i) =>\n item.type === \"text\" ? (\n <TimelineTextItem\n key={item.key || i}\n item={item}\n blink={shouldBlink}\n />\n ) : (\n <TimelineToolItem\n key={`tool-${item.key || i}`}\n msg={item.msg!}\n collapsible={item.collapsible}\n showFnCallDetail={showFnCallDetail}\n onConfirm={onConfirm}\n blink={shouldBlink}\n renderFunctionCall={renderFunctionCall}\n toolKindResolver={toolKindResolver}\n strategies={strategies}\n />\n ),\n )}\n </div>\n );\n\n // 不显示外层 header,直接渲染 timeline\n if (!showCollapsibleHeader) {\n return (\n <div\n className={`${styles.thoughtChainBlock}${className ? ` ${className}` : \"\"}`}\n style={style}\n >\n <div className={styles.thinkingBody}>{renderTimeline()}</div>\n </div>\n );\n }\n\n // 显示可折叠 header\n return (\n <div\n className={`${styles.thoughtChainBlock}${className ? ` ${className}` : \"\"}`}\n style={style}\n >\n <div className={styles.thoughtHeader} onClick={() => setIsOpen(!isOpen)}>\n <div className={styles.headerLeft}>\n <div className={styles.statusIcon}>\n <StatusIcon status={effectiveStatus} />\n </div>\n <span\n className={`${styles.headerTitle}${shouldBlink ? ` ${styles.blink}` : \"\"}`}\n >\n {isLoading ? \"深度思考与执行中...\" : title}\n </span>\n <div className={`${styles.caret} ${isOpen ? \"open\" : \"\"}`}>\n <RightOutlined />\n </div>\n </div>\n </div>\n {isOpen && (\n <div className={styles.thinkingBody}>{renderTimeline()}</div>\n )}\n </div>\n );\n};\n\nexport default XAdkThoughtChain;\n"],
5
+ "mappings": "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",
6
6
  "names": ["import_FunctionCallRender", "MarkdownRender", "FunctionCallRender"]
7
7
  }
@@ -24,6 +24,7 @@ __export(styles_exports, {
24
24
  module.exports = __toCommonJS(styles_exports);
25
25
  var import_css = require("@emotion/css");
26
26
  var import_common = require("../../styles/common");
27
+ var import_tokens = require("../../styles/tokens");
27
28
  var blinkAnimation = import_css.keyframes`
28
29
  0% { background-position-x: -200%; background-position-y: 100%; }
29
30
  25% { background-position-x: -100%; background-position-y: 100%; }
@@ -34,8 +35,8 @@ var blinkAnimation = import_css.keyframes`
34
35
  var useStyles = (0, import_common.withBasicStyles)(() => ({
35
36
  /* --- ThoughtChain --- */
36
37
  thoughtChainBlock: import_css.css`
37
- margin-bottom: 16px;
38
- border-radius: 8px;
38
+ margin-bottom: ${(0, import_tokens.token)(import_tokens.tokens.spacingMd)};
39
+ border-radius: ${(0, import_tokens.token)(import_tokens.tokens.borderRadius)};
39
40
  overflow: hidden;
40
41
  `,
41
42
  thoughtHeader: import_css.css`
@@ -46,18 +47,18 @@ var useStyles = (0, import_common.withBasicStyles)(() => ({
46
47
  user-select: none;
47
48
  transition: background 0.2s;
48
49
  &:hover {
49
- background: #f0f0f0;
50
+ background: ${(0, import_tokens.token)(import_tokens.tokens.colorBgHover)};
50
51
  border-color: #ccc;
51
52
  }
52
53
  `,
53
54
  headerLeft: import_css.css`
54
55
  display: flex;
55
56
  align-items: center;
56
- gap: 8px;
57
+ gap: ${(0, import_tokens.token)(import_tokens.tokens.spacingSm)};
57
58
  `,
58
59
  caret: import_css.css`
59
- font-size: 12px;
60
- color: #8194ad;
60
+ font-size: ${(0, import_tokens.token)(import_tokens.tokens.fontSizeSm)};
61
+ color: ${(0, import_tokens.token)(import_tokens.tokens.colorTextSecondary)};
61
62
  transition: transform 0.2s;
62
63
  &.open {
63
64
  transform: rotate(90deg);
@@ -69,13 +70,13 @@ var useStyles = (0, import_common.withBasicStyles)(() => ({
69
70
  align-items: center;
70
71
  `,
71
72
  headerTitle: import_css.css`
72
- font-size: 13px;
73
- color: #8194ad;
73
+ font-size: ${(0, import_tokens.token)(import_tokens.tokens.fontSizeBase)};
74
+ color: ${(0, import_tokens.token)(import_tokens.tokens.colorTextSecondary)};
74
75
  font-weight: 500;
75
76
  `,
76
77
  headerRight: import_css.css``,
77
78
  thinkingBody: import_css.css`
78
- padding: 0 16px;
79
+ padding: 0 ${(0, import_tokens.token)(import_tokens.tokens.spacingMd)};
79
80
  animation: fadeIn 0.2s ease-in-out;
80
81
  `,
81
82
  /* --- Timeline --- */
@@ -95,19 +96,19 @@ var useStyles = (0, import_common.withBasicStyles)(() => ({
95
96
  flex-shrink: 0;
96
97
  `,
97
98
  timelineIcon: import_css.css`
98
- color: #8194ad;
99
+ color: ${(0, import_tokens.token)(import_tokens.tokens.colorTextSecondary)};
99
100
  font-size: 16px;
100
101
  margin-top: 6px;
101
102
  `,
102
103
  timelineIconTool: import_css.css`
103
- color: #faad14;
104
+ color: ${(0, import_tokens.token)(import_tokens.tokens.colorWarning)};
104
105
  font-size: 16px;
105
106
  margin-top: 6px;
106
107
  `,
107
108
  timelineConnector: import_css.css`
108
109
  flex: 1;
109
110
  width: 1px;
110
- background-color: #e5e5e5;
111
+ background-color: ${(0, import_tokens.token)(import_tokens.tokens.colorBorder)};
111
112
  margin: 4px 0;
112
113
  min-height: 12px;
113
114
  `,
@@ -117,7 +118,7 @@ var useStyles = (0, import_common.withBasicStyles)(() => ({
117
118
  `,
118
119
  timelineRight: import_css.css`
119
120
  flex: 1;
120
- padding-bottom: 8px;
121
+ padding-bottom: ${(0, import_tokens.token)(import_tokens.tokens.spacingSm)};
121
122
  min-width: 0;
122
123
  `,
123
124
  collapsibleHeader: import_css.css`
@@ -132,31 +133,31 @@ var useStyles = (0, import_common.withBasicStyles)(() => ({
132
133
  user-select: none;
133
134
 
134
135
  &:hover {
135
- background: #f5f5f5;
136
+ background: ${(0, import_tokens.token)(import_tokens.tokens.colorBgHover)};
136
137
  }
137
138
  `,
138
139
  titleText: import_css.css`
139
- font-size: 13px;
140
+ font-size: ${(0, import_tokens.token)(import_tokens.tokens.fontSizeBase)};
140
141
  font-weight: 600;
141
- color: #8194ad;
142
+ color: ${(0, import_tokens.token)(import_tokens.tokens.colorTextSecondary)};
142
143
  `,
143
144
  toolTitleGroup: import_css.css`
144
145
  display: flex;
145
146
  align-items: center;
146
- gap: 8px;
147
+ gap: ${(0, import_tokens.token)(import_tokens.tokens.spacingSm)};
147
148
  overflow: hidden;
148
149
  `,
149
150
  toolName: import_css.css`
150
- font-size: 13px;
151
+ font-size: ${(0, import_tokens.token)(import_tokens.tokens.fontSizeBase)};
151
152
  font-weight: 600;
152
- color: #8194ad;
153
+ color: ${(0, import_tokens.token)(import_tokens.tokens.colorTextSecondary)};
153
154
  white-space: nowrap;
154
155
  overflow: hidden;
155
156
  text-overflow: ellipsis;
156
157
  `,
157
158
  toolStatusTag: import_css.css`
158
159
  font-size: 11px;
159
- color: #52c41a;
160
+ color: ${(0, import_tokens.token)(import_tokens.tokens.colorSuccess)};
160
161
  background: #f6ffed;
161
162
  border: 1px solid #b7eb8f;
162
163
  padding: 0 6px;
@@ -166,22 +167,22 @@ var useStyles = (0, import_common.withBasicStyles)(() => ({
166
167
  arrowIcon: import_css.css`
167
168
  font-size: 10px;
168
169
  color: #bbb;
169
- margin-left: 8px;
170
+ margin-left: ${(0, import_tokens.token)(import_tokens.tokens.spacingSm)};
170
171
  `,
171
172
  stepContent: import_css.css`
172
- font-size: 13px;
173
- color: #8194ad;
173
+ font-size: ${(0, import_tokens.token)(import_tokens.tokens.fontSizeBase)};
174
+ color: ${(0, import_tokens.token)(import_tokens.tokens.colorTextSecondary)};
174
175
  line-height: 1.6;
175
176
  padding-left: 4px;
176
177
  `,
177
178
  statusInfo: import_css.css`
178
- font-size: 12px;
179
- color: #8194ad;
179
+ font-size: ${(0, import_tokens.token)(import_tokens.tokens.fontSizeSm)};
180
+ color: ${(0, import_tokens.token)(import_tokens.tokens.colorTextSecondary)};
180
181
  margin-bottom: 4px;
181
182
  font-style: italic;
182
183
  `,
183
184
  blink: import_css.css`
184
- color: #8194ad;
185
+ color: ${(0, import_tokens.token)(import_tokens.tokens.colorTextSecondary)};
185
186
  background-image: linear-gradient(
186
187
  90deg,
187
188
  transparent,