@ai-group/chat-sdk 3.6.10 → 3.6.11

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 (64) hide show
  1. package/dist/cjs/client/base.d.ts +1 -2
  2. package/dist/cjs/client/base.js.map +1 -1
  3. package/dist/cjs/components/XAdkChatbot/components/ThinkRender/index.d.ts +1 -1
  4. package/dist/cjs/components/XAdkChatbot/components/ThinkRender/index.js.map +1 -1
  5. package/dist/cjs/components/XAdkProvider/compound/Sender.js +2 -2
  6. package/dist/cjs/components/XAdkProvider/compound/Sender.js.map +2 -2
  7. package/dist/cjs/components/XAdkProvider/compound/Sidebar.js.map +1 -1
  8. package/dist/cjs/components/XAdkProvider/context/ChatSenderStateContext.d.ts +12 -0
  9. package/dist/cjs/components/XAdkProvider/context/ChatSenderStateContext.js +40 -0
  10. package/dist/cjs/components/XAdkProvider/context/ChatSenderStateContext.js.map +7 -0
  11. package/dist/cjs/components/XAdkProvider/context/index.d.ts +1 -0
  12. package/dist/cjs/components/XAdkProvider/context/index.js +3 -1
  13. package/dist/cjs/components/XAdkProvider/context/index.js.map +2 -2
  14. package/dist/cjs/components/XAdkProvider/index.js +10 -2
  15. package/dist/cjs/components/XAdkProvider/index.js.map +2 -2
  16. package/dist/cjs/components/XAiChatbot/index.js.map +1 -1
  17. package/dist/cjs/components/XAiProvider/index.js.map +1 -1
  18. package/dist/cjs/components/XAiSender/index.js.map +1 -1
  19. package/dist/cjs/hooks/useADKChat.js +9 -2
  20. package/dist/cjs/hooks/useADKChat.js.map +2 -2
  21. package/dist/cjs/types/XAiChatbot.d.ts +1 -1
  22. package/dist/cjs/types/XAiChatbot.js.map +1 -1
  23. package/dist/cjs/types/XAiConversations.d.ts +1 -1
  24. package/dist/cjs/types/XAiConversations.js.map +1 -1
  25. package/dist/cjs/types/XAiMessage.d.ts +1 -1
  26. package/dist/cjs/types/XAiMessage.js.map +1 -1
  27. package/dist/cjs/types/XAiSender.d.ts +1 -2
  28. package/dist/cjs/types/XAiSender.js.map +1 -1
  29. package/dist/cjs/types/antdx.d.ts +146 -0
  30. package/dist/cjs/types/antdx.js +18 -0
  31. package/dist/cjs/types/antdx.js.map +7 -0
  32. package/dist/esm/client/base.d.ts +1 -2
  33. package/dist/esm/client/base.js.map +1 -1
  34. package/dist/esm/components/XAdkChatbot/components/ThinkRender/index.d.ts +1 -1
  35. package/dist/esm/components/XAdkChatbot/components/ThinkRender/index.js.map +1 -1
  36. package/dist/esm/components/XAdkProvider/compound/Sender.js +4 -4
  37. package/dist/esm/components/XAdkProvider/compound/Sender.js.map +1 -1
  38. package/dist/esm/components/XAdkProvider/compound/Sidebar.js.map +1 -1
  39. package/dist/esm/components/XAdkProvider/context/ChatSenderStateContext.d.ts +12 -0
  40. package/dist/esm/components/XAdkProvider/context/ChatSenderStateContext.js +16 -0
  41. package/dist/esm/components/XAdkProvider/context/ChatSenderStateContext.js.map +1 -0
  42. package/dist/esm/components/XAdkProvider/context/index.d.ts +1 -0
  43. package/dist/esm/components/XAdkProvider/context/index.js +1 -0
  44. package/dist/esm/components/XAdkProvider/context/index.js.map +1 -1
  45. package/dist/esm/components/XAdkProvider/index.js +20 -8
  46. package/dist/esm/components/XAdkProvider/index.js.map +1 -1
  47. package/dist/esm/components/XAiChatbot/index.js.map +1 -1
  48. package/dist/esm/components/XAiProvider/index.js.map +1 -1
  49. package/dist/esm/components/XAiSender/index.js.map +1 -1
  50. package/dist/esm/hooks/useADKChat.js +12 -3
  51. package/dist/esm/hooks/useADKChat.js.map +1 -1
  52. package/dist/esm/types/XAiChatbot.d.ts +1 -1
  53. package/dist/esm/types/XAiChatbot.js.map +1 -1
  54. package/dist/esm/types/XAiConversations.d.ts +1 -1
  55. package/dist/esm/types/XAiConversations.js.map +1 -1
  56. package/dist/esm/types/XAiMessage.d.ts +1 -1
  57. package/dist/esm/types/XAiMessage.js.map +1 -1
  58. package/dist/esm/types/XAiSender.d.ts +1 -2
  59. package/dist/esm/types/XAiSender.js.map +1 -1
  60. package/dist/esm/types/antdx.d.ts +146 -0
  61. package/dist/esm/types/antdx.js +2 -0
  62. package/dist/esm/types/antdx.js.map +1 -0
  63. package/dist/umd/chat-sdk.min.js +1 -1
  64. package/package.json +1 -1
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/components/XAiSender/index.tsx"],
4
- "sourcesContent": ["import React, {\n useRef,\n useState,\n} from 'react';\nimport {\n Attachments,\n Sender,\n} from '@ant-design/x';\nimport {\n Button,\n GetRef,\n Popover,\n Space,\n Flex,\n Tooltip,\n} from 'antd';\nimport {\n ArrowUpOutlined,\n ClearOutlined,\n PlusCircleOutlined,\n} from '@ant-design/icons';\nimport clsx from 'clsx';\nimport { AttachmentsRef } from '@ant-design/x/es/attachments';\nimport {\n XAiSenderProps,\n} from '@/types';\nimport { useChatbotContext } from '@/hooks/useProviderContext';\nimport { useStyles } from './styles';\n\nconst XAiSender: React.FC<XAiSenderProps> = (props) => {\n // 使用新的 Hook 来处理 Provider 上下文\n const { mergedProps } = useChatbotContext(props);\n const {\n footerTips,\n clearBtnShow,\n value,\n onChange,\n onClear,\n onStop,\n onSubmit,\n files,\n enableUpload,\n onChangeFiles,\n uploadRequest,\n loading: propLoading = false,\n disabled,\n ...resetProps\n } = mergedProps as XAiSenderProps;\n const senderRef = useRef<GetRef<typeof Sender>>(null);\n const attachmentsRef = useRef<AttachmentsRef>(null);\n\n // 如果在 Provider 中,使用 Provider 的状态\n const loading = mergedProps.loading || propLoading;\n const [clearPopoverVisible, setClearPopoverVisible] = useState(false); // 气泡卡片显隐藏\n const styles = useStyles();\n\n // 触发发送\n const handleSend = () => {\n if (value && value.trim()) {\n // 直接使用合并后的 onSend,自动处理 Provider 和独立模式\n onSubmit?.({\n text: value,\n files: files || [],\n });\n }\n };\n\n // 文件上传按钮引用\n const fileInputRef = useRef<HTMLInputElement>(null);\n\n // 点击清除按钮\n const handleClear = () => {\n setClearPopoverVisible(true);\n };\n\n // 取消清除\n const cancelClear = () => {\n setClearPopoverVisible(false);\n };\n\n // 确认清除\n const confirmClear = () => {\n onClear?.();\n setClearPopoverVisible(false);\n };\n\n // 清空按钮提示文案\n const clearConfirmContent = (\n <div className={styles.p('2px')}>\n <p className={clsx(styles.mb(14), styles.mt(0))}>确认清除所有聊天记录并重置会话!</p>\n <div className={styles.popoverFooter}>\n <Button size=\"small\" onClick={cancelClear}>\n 取消\n </Button>\n <Button size=\"small\" type=\"primary\" danger onClick={confirmClear}>\n 确认\n </Button>\n </div>\n </div>\n );\n\n // 自定义上传按钮\n const uploadButton = (\n <div className={styles.flexCenterGap2}>\n <Tooltip\n placement=\"top\"\n title=\"支持图片、文档等上传\"\n >\n <Button\n color=\"default\"\n variant=\"text\"\n shape=\"circle\"\n size=\"small\"\n icon={<PlusCircleOutlined style={{ fontSize: 20, color: '#949494' }} />}\n onClick={() => {\n if (fileInputRef.current) {\n fileInputRef.current?.click();\n }\n }}\n />\n <input\n type=\"file\"\n ref={fileInputRef}\n multiple\n onChange={(e) => {\n const fileList = e.target.files || [];\n if (!fileList.length) return;\n for (let i = 0; i < fileList.length; i++) {\n const file = fileList[i];\n attachmentsRef.current?.upload(file);\n }\n e.target.value = '';\n }}\n style={{ display: 'none' }}\n accept=\"*/*\"\n />\n </Tooltip>\n </div>\n );\n\n return (\n <>\n <div className={styles.chatFooter}>\n <div className={clsx(styles.flex, styles.gap(8))}>\n {/* 普通文本输入 */}\n <Sender\n {...resetProps}\n value={value}\n className={styles.sendWrapper}\n placeholder=\"继续对话...\"\n disabled={disabled}\n loading={loading}\n ref={senderRef}\n header={enableUpload && (\n <Sender.Header\n closable={false}\n forceRender\n open={!!files?.length}\n styles={{\n content: { padding: 0 },\n }}\n >\n <Attachments\n ref={attachmentsRef}\n customRequest={uploadRequest}\n multiple\n items={files}\n // imageProps={{\n // preview: {\n // mask: true,\n // },\n // }}\n onChange={({ fileList }) => {\n onChangeFiles?.(fileList);\n }}\n getDropContainer={() => senderRef.current?.nativeElement}\n />\n </Sender.Header>\n )}\n suffix={false}\n footer={(_, info) => {\n const { SendButton, LoadingButton } = info.components;\n return (\n <Flex justify=\"space-between\">\n <div>\n {/* 清空按钮 */}\n {clearBtnShow && (\n <Popover\n content={clearConfirmContent}\n title=\"确认清空对话\"\n trigger=\"click\"\n open={clearPopoverVisible}\n onOpenChange={setClearPopoverVisible}\n >\n <div\n className={styles.clearBtn}\n onClick={handleClear}\n >\n <ClearOutlined className={styles.text(12)} />\n </div>\n </Popover>\n )}\n </div>\n <Space size=\"small\" style={{ display: 'flex', alignItems: 'center'}}>\n {enableUpload && (\n <>\n {uploadButton}\n <div className={styles.divider} />\n </>\n )}\n {loading\n ? (\n <LoadingButton onClick={() => onStop?.()} className={styles.stopButton} />\n )\n : (\n <SendButton\n className={styles.sendButton}\n type=\"primary\"\n icon={<ArrowUpOutlined className={styles.text(20)} />}\n disabled={disabled}\n />\n )}\n </Space>\n </Flex>\n );\n }}\n onChange={(v) => {\n onChange?.(v);\n }}\n onSubmit={handleSend}\n onCancel={() => {\n onStop?.();\n }}\n />\n </div>\n </div>\n { footerTips && <div className={styles.footerTips}>{footerTips}</div>}\n </>\n );\n};\n\nexport default XAiSender;\n"],
4
+ "sourcesContent": ["import React, {\n useRef,\n useState,\n} from 'react';\nimport {\n Attachments,\n Sender,\n} from '@ant-design/x';\nimport {\n Button,\n GetRef,\n Popover,\n Space,\n Flex,\n Tooltip,\n} from 'antd';\nimport {\n ArrowUpOutlined,\n ClearOutlined,\n PlusCircleOutlined,\n} from '@ant-design/icons';\nimport clsx from 'clsx';\nimport type { AttachmentsRef } from '@/types/antdx';\nimport {\n XAiSenderProps,\n} from '@/types';\nimport { useChatbotContext } from '@/hooks/useProviderContext';\nimport { useStyles } from './styles';\n\nconst XAiSender: React.FC<XAiSenderProps> = (props) => {\n // 使用新的 Hook 来处理 Provider 上下文\n const { mergedProps } = useChatbotContext(props);\n const {\n footerTips,\n clearBtnShow,\n value,\n onChange,\n onClear,\n onStop,\n onSubmit,\n files,\n enableUpload,\n onChangeFiles,\n uploadRequest,\n loading: propLoading = false,\n disabled,\n ...resetProps\n } = mergedProps as XAiSenderProps;\n const senderRef = useRef<GetRef<typeof Sender>>(null);\n const attachmentsRef = useRef<AttachmentsRef>(null);\n\n // 如果在 Provider 中,使用 Provider 的状态\n const loading = mergedProps.loading || propLoading;\n const [clearPopoverVisible, setClearPopoverVisible] = useState(false); // 气泡卡片显隐藏\n const styles = useStyles();\n\n // 触发发送\n const handleSend = () => {\n if (value && value.trim()) {\n // 直接使用合并后的 onSend,自动处理 Provider 和独立模式\n onSubmit?.({\n text: value,\n files: files || [],\n });\n }\n };\n\n // 文件上传按钮引用\n const fileInputRef = useRef<HTMLInputElement>(null);\n\n // 点击清除按钮\n const handleClear = () => {\n setClearPopoverVisible(true);\n };\n\n // 取消清除\n const cancelClear = () => {\n setClearPopoverVisible(false);\n };\n\n // 确认清除\n const confirmClear = () => {\n onClear?.();\n setClearPopoverVisible(false);\n };\n\n // 清空按钮提示文案\n const clearConfirmContent = (\n <div className={styles.p('2px')}>\n <p className={clsx(styles.mb(14), styles.mt(0))}>确认清除所有聊天记录并重置会话!</p>\n <div className={styles.popoverFooter}>\n <Button size=\"small\" onClick={cancelClear}>\n 取消\n </Button>\n <Button size=\"small\" type=\"primary\" danger onClick={confirmClear}>\n 确认\n </Button>\n </div>\n </div>\n );\n\n // 自定义上传按钮\n const uploadButton = (\n <div className={styles.flexCenterGap2}>\n <Tooltip\n placement=\"top\"\n title=\"支持图片、文档等上传\"\n >\n <Button\n color=\"default\"\n variant=\"text\"\n shape=\"circle\"\n size=\"small\"\n icon={<PlusCircleOutlined style={{ fontSize: 20, color: '#949494' }} />}\n onClick={() => {\n if (fileInputRef.current) {\n fileInputRef.current?.click();\n }\n }}\n />\n <input\n type=\"file\"\n ref={fileInputRef}\n multiple\n onChange={(e) => {\n const fileList = e.target.files || [];\n if (!fileList.length) return;\n for (let i = 0; i < fileList.length; i++) {\n const file = fileList[i];\n attachmentsRef.current?.upload(file);\n }\n e.target.value = '';\n }}\n style={{ display: 'none' }}\n accept=\"*/*\"\n />\n </Tooltip>\n </div>\n );\n\n return (\n <>\n <div className={styles.chatFooter}>\n <div className={clsx(styles.flex, styles.gap(8))}>\n {/* 普通文本输入 */}\n <Sender\n {...resetProps}\n value={value}\n className={styles.sendWrapper}\n placeholder=\"继续对话...\"\n disabled={disabled}\n loading={loading}\n ref={senderRef}\n header={enableUpload && (\n <Sender.Header\n closable={false}\n forceRender\n open={!!files?.length}\n styles={{\n content: { padding: 0 },\n }}\n >\n <Attachments\n ref={attachmentsRef}\n customRequest={uploadRequest}\n multiple\n items={files}\n // imageProps={{\n // preview: {\n // mask: true,\n // },\n // }}\n onChange={({ fileList }) => {\n onChangeFiles?.(fileList);\n }}\n getDropContainer={() => senderRef.current?.nativeElement}\n />\n </Sender.Header>\n )}\n suffix={false}\n footer={(_, info) => {\n const { SendButton, LoadingButton } = info.components;\n return (\n <Flex justify=\"space-between\">\n <div>\n {/* 清空按钮 */}\n {clearBtnShow && (\n <Popover\n content={clearConfirmContent}\n title=\"确认清空对话\"\n trigger=\"click\"\n open={clearPopoverVisible}\n onOpenChange={setClearPopoverVisible}\n >\n <div\n className={styles.clearBtn}\n onClick={handleClear}\n >\n <ClearOutlined className={styles.text(12)} />\n </div>\n </Popover>\n )}\n </div>\n <Space size=\"small\" style={{ display: 'flex', alignItems: 'center'}}>\n {enableUpload && (\n <>\n {uploadButton}\n <div className={styles.divider} />\n </>\n )}\n {loading\n ? (\n <LoadingButton onClick={() => onStop?.()} className={styles.stopButton} />\n )\n : (\n <SendButton\n className={styles.sendButton}\n type=\"primary\"\n icon={<ArrowUpOutlined className={styles.text(20)} />}\n disabled={disabled}\n />\n )}\n </Space>\n </Flex>\n );\n }}\n onChange={(v) => {\n onChange?.(v);\n }}\n onSubmit={handleSend}\n onCancel={() => {\n onStop?.();\n }}\n />\n </div>\n </div>\n { footerTips && <div className={styles.footerTips}>{footerTips}</div>}\n </>\n );\n};\n\nexport default XAiSender;\n"],
5
5
  "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAGO;AACP,eAGO;AACP,kBAOO;AACP,mBAIO;AACP,kBAAiB;AAKjB,gCAAkC;AAClC,oBAA0B;AA8DpB;AA5DN,IAAM,YAAsC,CAAC,UAAU;AAErD,QAAM,EAAE,YAAY,QAAI,6CAAkB,KAAK;AAC/C,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,SAAS,cAAc;AAAA,IACvB;AAAA,IACA,GAAG;AAAA,EACL,IAAI;AACJ,QAAM,gBAAY,qBAA8B,IAAI;AACpD,QAAM,qBAAiB,qBAAuB,IAAI;AAGlD,QAAM,UAAU,YAAY,WAAW;AACvC,QAAM,CAAC,qBAAqB,sBAAsB,QAAI,uBAAS,KAAK;AACpE,QAAM,aAAS,yBAAU;AAGzB,QAAM,aAAa,MAAM;AACvB,QAAI,SAAS,MAAM,KAAK,GAAG;AAEzB,2CAAW;AAAA,QACT,MAAM;AAAA,QACN,OAAO,SAAS,CAAC;AAAA,MACnB;AAAA,IACF;AAAA,EACF;AAGA,QAAM,mBAAe,qBAAyB,IAAI;AAGlD,QAAM,cAAc,MAAM;AACxB,2BAAuB,IAAI;AAAA,EAC7B;AAGA,QAAM,cAAc,MAAM;AACxB,2BAAuB,KAAK;AAAA,EAC9B;AAGA,QAAM,eAAe,MAAM;AACzB;AACA,2BAAuB,KAAK;AAAA,EAC9B;AAGA,QAAM,sBACJ,6CAAC,SAAI,WAAW,OAAO,EAAE,KAAK,GAC5B;AAAA,gDAAC,OAAE,eAAW,YAAAA,SAAK,OAAO,GAAG,EAAE,GAAG,OAAO,GAAG,CAAC,CAAC,GAAG,8BAAgB;AAAA,IACjE,6CAAC,SAAI,WAAW,OAAO,eACrB;AAAA,kDAAC,sBAAO,MAAK,SAAQ,SAAS,aAAa,gBAE3C;AAAA,MACA,4CAAC,sBAAO,MAAK,SAAQ,MAAK,WAAU,QAAM,MAAC,SAAS,cAAc,gBAElE;AAAA,OACF;AAAA,KACF;AAIF,QAAM,eACJ,4CAAC,SAAI,WAAW,OAAO,gBACrB;AAAA,IAAC;AAAA;AAAA,MACC,WAAU;AAAA,MACV,OAAM;AAAA,MAEN;AAAA;AAAA,UAAC;AAAA;AAAA,YACC,OAAM;AAAA,YACN,SAAQ;AAAA,YACR,OAAM;AAAA,YACN,MAAK;AAAA,YACL,MAAM,4CAAC,mCAAmB,OAAO,EAAE,UAAU,IAAI,OAAO,UAAU,GAAG;AAAA,YACrE,SAAS,MAAM;AAlHzB;AAmHY,kBAAI,aAAa,SAAS;AACxB,mCAAa,YAAb,mBAAsB;AAAA,cACxB;AAAA,YACF;AAAA;AAAA,QACF;AAAA,QACA;AAAA,UAAC;AAAA;AAAA,YACC,MAAK;AAAA,YACL,KAAK;AAAA,YACL,UAAQ;AAAA,YACR,UAAU,CAAC,MAAM;AA5H3B;AA6HY,oBAAM,WAAW,EAAE,OAAO,SAAS,CAAC;AACpC,kBAAI,CAAC,SAAS;AAAQ;AACtB,uBAAS,IAAI,GAAG,IAAI,SAAS,QAAQ,KAAK;AACxC,sBAAM,OAAO,SAAS,CAAC;AACvB,qCAAe,YAAf,mBAAwB,OAAO;AAAA,cACjC;AACA,gBAAE,OAAO,QAAQ;AAAA,YACnB;AAAA,YACA,OAAO,EAAE,SAAS,OAAO;AAAA,YACzB,QAAO;AAAA;AAAA,QACT;AAAA;AAAA;AAAA,EACF,GACF;AAGF,SACE,4EACE;AAAA,gDAAC,SAAI,WAAW,OAAO,YACrB,sDAAC,SAAI,eAAW,YAAAA,SAAK,OAAO,MAAM,OAAO,IAAI,CAAC,CAAC,GAE7C;AAAA,MAAC;AAAA;AAAA,QACE,GAAG;AAAA,QACJ;AAAA,QACA,WAAW,OAAO;AAAA,QAClB,aAAY;AAAA,QACZ;AAAA,QACA;AAAA,QACA,KAAK;AAAA,QACL,QAAQ,gBACN;AAAA,UAAC,gBAAO;AAAA,UAAP;AAAA,YACC,UAAU;AAAA,YACV,aAAW;AAAA,YACX,MAAM,CAAC,EAAC,+BAAO;AAAA,YACf,QAAQ;AAAA,cACN,SAAS,EAAE,SAAS,EAAE;AAAA,YACxB;AAAA,YAEA;AAAA,cAAC;AAAA;AAAA,gBACC,KAAK;AAAA,gBACL,eAAe;AAAA,gBACf,UAAQ;AAAA,gBACR,OAAO;AAAA,gBAMP,UAAU,CAAC,EAAE,SAAS,MAAM;AAC1B,iEAAgB;AAAA,gBAClB;AAAA,gBACA,kBAAkB,MAAG;AA/KvC;AA+K0C,yCAAU,YAAV,mBAAmB;AAAA;AAAA;AAAA,YAC7C;AAAA;AAAA,QACF;AAAA,QAEF,QAAQ;AAAA,QACR,QAAQ,CAAC,GAAG,SAAS;AACnB,gBAAM,EAAE,YAAY,cAAc,IAAI,KAAK;AAC3C,iBACE,6CAAC,oBAAK,SAAQ,iBACZ;AAAA,wDAAC,SAEE,0BACC;AAAA,cAAC;AAAA;AAAA,gBACC,SAAS;AAAA,gBACT,OAAM;AAAA,gBACN,SAAQ;AAAA,gBACR,MAAM;AAAA,gBACN,cAAc;AAAA,gBAEd;AAAA,kBAAC;AAAA;AAAA,oBACC,WAAW,OAAO;AAAA,oBAClB,SAAS;AAAA,oBAET,sDAAC,8BAAc,WAAW,OAAO,KAAK,EAAE,GAAG;AAAA;AAAA,gBAC7C;AAAA;AAAA,YACF,GAEJ;AAAA,YACA,6CAAC,qBAAM,MAAK,SAAQ,OAAO,EAAE,SAAS,QAAQ,YAAY,SAAQ,GAC/D;AAAA,8BACC,4EACG;AAAA;AAAA,gBACD,4CAAC,SAAI,WAAW,OAAO,SAAS;AAAA,iBAClC;AAAA,cAED,UAEG,4CAAC,iBAAc,SAAS,MAAM,oCAAY,WAAW,OAAO,YAAY,IAGxE;AAAA,gBAAC;AAAA;AAAA,kBACC,WAAW,OAAO;AAAA,kBAClB,MAAK;AAAA,kBACL,MAAM,4CAAC,gCAAgB,WAAW,OAAO,KAAK,EAAE,GAAG;AAAA,kBACnD;AAAA;AAAA,cACF;AAAA,eAEN;AAAA,aACF;AAAA,QAEJ;AAAA,QACA,UAAU,CAAC,MAAM;AACf,+CAAW;AAAA,QACb;AAAA,QACA,UAAU;AAAA,QACV,UAAU,MAAM;AACd;AAAA,QACF;AAAA;AAAA,IACF,GACF,GACF;AAAA,IACE,cAAc,4CAAC,SAAI,WAAW,OAAO,YAAa,sBAAW;AAAA,KACjE;AAEJ;AAEA,IAAO,oBAAQ;",
6
6
  "names": ["clsx"]
7
7
  }
@@ -764,6 +764,7 @@ function useADKChat({
764
764
  if (bg) {
765
765
  bg.loading = false;
766
766
  bg.textMsgRef = null;
767
+ bg.ctrl.abort();
767
768
  }
768
769
  if (!backgroundRef.current.has(targetSessionId) && currentSessionIdRef.current === targetSessionId) {
769
770
  setLoading(false);
@@ -776,6 +777,7 @@ function useADKChat({
776
777
  }
777
778
  textMsgRef.current = null;
778
779
  ctrl.current = null;
780
+ newCtrl.abort();
779
781
  }
780
782
  resolve();
781
783
  },
@@ -783,8 +785,10 @@ function useADKChat({
783
785
  const isBackground = currentSessionIdRef.current !== targetSessionId;
784
786
  if (isBackground) {
785
787
  const bg = backgroundRef.current.get(targetSessionId);
786
- if (bg)
788
+ if (bg) {
787
789
  bg.loading = false;
790
+ bg.ctrl.abort();
791
+ }
788
792
  if (!backgroundRef.current.has(targetSessionId) && currentSessionIdRef.current === targetSessionId) {
789
793
  setLoading(false);
790
794
  ctrl.current = null;
@@ -792,6 +796,7 @@ function useADKChat({
792
796
  } else {
793
797
  setLoading(false);
794
798
  ctrl.current = null;
799
+ newCtrl.abort();
795
800
  }
796
801
  resolve();
797
802
  console.error("EventSource failed:", error);
@@ -990,8 +995,10 @@ function useADKChat({
990
995
  textMsgRef.current = null;
991
996
  setLoading(false);
992
997
  } else if (messagesRef.current.length > 0) {
998
+ const dummyCtrl = new AbortController();
999
+ dummyCtrl.abort();
993
1000
  backgroundRef.current.set(prevSessionId, {
994
- ctrl: new AbortController(),
1001
+ ctrl: dummyCtrl,
995
1002
  messages: [...messagesRef.current],
996
1003
  loading: false,
997
1004
  textMsgRef: null
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/hooks/useADKChat.ts"],
4
- "sourcesContent": ["import { useEffect, useCallback, useMemo, useRef, useState } from \"react\";\nimport {\n fetchEventSource,\n EventStreamContentType,\n} from \"@microsoft/fetch-event-source\";\nimport { message } from \"antd\";\nimport { v4 } from \"uuid\";\nimport { SESSION_PAGE_SIZE, API_SUCCESS_CODE } from \"@/constants\";\nimport {\n SuccessCode,\n ErrorCode,\n DebugOptions,\n FunctionCall,\n SendContent,\n SessionData,\n AgentRunRequest,\n Event,\n FunctionResponse,\n IMessage,\n Part,\n} from \"@/types\";\nimport {\n fetchAppConfig,\n fetchSessionList,\n fetchSessionDetail,\n closeSession,\n updateSessionTitle,\n addFeedback,\n type ChatConfig,\n} from \"@/services/api\";\nimport { safeJsonParse } from \"@/utils\";\n\nconst combineTextParts = (parts: Part[]) => {\n const result: Part[] = [];\n let combinedTextPart: Part | undefined;\n\n // eslint-disable-next-line no-restricted-syntax\n for (const part of parts) {\n // 纯文本 part(没有 fileData 等其他字段)才合并\n const isPureText = part.text && !part.fileData;\n if (isPureText) {\n // 如果没有 combined 或 combined 思考类型跟当前 part 不同,则创建新的合并引用\n if (!combinedTextPart || combinedTextPart.thought !== part.thought) {\n combinedTextPart = { ...part };\n result.push(combinedTextPart);\n } else {\n combinedTextPart.text =\n (combinedTextPart.text || \"\") + (part.text || \"\");\n }\n } else {\n combinedTextPart = undefined;\n result.push(part);\n }\n }\n return result;\n};\n\nconst DEFAULT_SESSION_EVENTS_POLLING_INTERVAL = 10000;\n\n/**\n * 从 event + part 构建非文本 IMessage(functionCall / functionResponse / executableCode 等)。\n */\nconst buildNonTextMessage = (\n event: Event,\n part: Part,\n role: \"user\" | \"bot\" = \"bot\",\n): IMessage => {\n const msg: IMessage = {\n id: v4(),\n author: event.author,\n invocationId: event.invocationId,\n eventId: event.id,\n timestamp: event.timestamp,\n isLike: event.isLike || 0,\n role,\n modelCode: event.modelCode,\n usageMetadata: event.usageMetadata,\n finishReason: event.finishReason,\n raw: event,\n };\n\n if (part.inlineData) {\n msg.inlineData = {\n displayName: part.inlineData.displayName,\n data: part.inlineData.data,\n mimeType: part.inlineData.mimeType,\n };\n } else if (part.fileData) {\n msg.fileData = [part.fileData];\n } else if (part.functionCall) {\n msg.functionCall = part.functionCall;\n } else if (part.functionResponse) {\n msg.functionResponse = part.functionResponse;\n } else if (part.executableCode) {\n msg.executableCode = part.executableCode;\n } else if (part.codeExecutionResult) {\n msg.codeExecutionResult = part.codeExecutionResult;\n } else if (part.text) {\n msg.text = part.text;\n msg.thought = part.thought;\n }\n\n return msg;\n};\n\nconst getMessageEventId = (messageItem: IMessage) =>\n messageItem.eventId || messageItem.raw?.id;\n\nconst deduplicateMessages = (messageItems: IMessage[]) => {\n const seenMessageIds = new Set<string>();\n let hasDuplicate = false;\n\n const uniqueIdMessages = messageItems.filter((messageItem) => {\n if (seenMessageIds.has(messageItem.id)) {\n hasDuplicate = true;\n return false;\n }\n seenMessageIds.add(messageItem.id);\n return true;\n });\n\n // 机器人文本消息去重:同一 invocationId + 思考类型的文本消息,\n // 如果文本内容存在包含关系,保留最长的(sessionDetails 完整消息),去掉被包含的短文本(SSE 流式增量)。\n // 使用 invocationId 分组,同一轮对话的 invocationId 始终一致, SSE 后续 chunk 的 首个id 与 sessionDetails 的 id 相同,其余不同,\n const botTextGroups = new Map<\n string,\n Array<{ messageItem: IMessage; normalizedText: string }>\n >();\n uniqueIdMessages.forEach((messageItem) => {\n if (\n messageItem.role !== \"bot\" ||\n !messageItem.invocationId ||\n typeof messageItem.text !== \"string\"\n )\n return;\n\n const normalizedText = messageItem.text.replace(/\\s+/g, \" \").trim();\n if (!normalizedText) return;\n\n const fileKey = (messageItem.fileData || [])\n .map((file) => file.fileUri)\n .join(\"|\");\n const groupKey = `${messageItem.invocationId}\\u0000${Boolean(\n messageItem.thought,\n )}\\u0000${fileKey}`;\n const group = botTextGroups.get(groupKey) || [];\n group.push({ messageItem, normalizedText });\n botTextGroups.set(groupKey, group);\n });\n\n const redundantMessageIds = new Set<string>();\n botTextGroups.forEach((group) => {\n if (group.length <= 1) return;\n const completeTexts: string[] = [];\n [...group]\n .sort((a, b) => b.normalizedText.length - a.normalizedText.length)\n .forEach(({ messageItem, normalizedText }) => {\n if (\n completeTexts.some((completeText) =>\n completeText.includes(normalizedText),\n )\n ) {\n redundantMessageIds.add(messageItem.id);\n hasDuplicate = true;\n return;\n }\n completeTexts.push(normalizedText);\n });\n });\n\n return hasDuplicate\n ? uniqueIdMessages.filter(\n (messageItem) => !redundantMessageIds.has(messageItem.id),\n )\n : messageItems;\n};\n\nconst mapSessionMessages = (sessionEvents: any[]): IMessage[] => {\n const mapped: IMessage[] = [];\n sessionEvents.forEach((item) => {\n if (!item || !item.content || !Array.isArray(item.content.parts)) return;\n // 后端为异步任务插入的用户事件仅用于关联任务,不在页面展示。\n if (\n item.author === \"user\" &&\n item.content.parts.some((part: any) => part.task)\n )\n return;\n // functionResponse 的 user 事件仅用于配对 functionCall,不作为独立消息展示\n if (\n item.content.role === \"user\" &&\n item.content.parts.every((part: any) => !part || part.functionResponse)\n )\n return;\n\n const role =\n (item.content.role || \"\").toLowerCase() === \"user\" ? \"user\" : \"bot\";\n const parts = item.content.parts.filter((part: any) => {\n if (!part) return false;\n return Boolean(\n part.text ||\n part.inlineData ||\n part.functionCall ||\n part.functionResponse ||\n part.fileData ||\n part.executableCode ||\n part.codeExecutionResult ||\n part.errorMessage,\n );\n });\n if (parts.length === 0) return;\n\n const textParts = parts.filter(\n (part: any) => part.text || part.errorMessage || part.inlineData,\n );\n const fileDataParts = parts.filter((part: any) => part.fileData);\n const otherParts = parts.filter(\n (part: any) =>\n !part.text && !part.errorMessage && !part.inlineData && !part.fileData,\n );\n\n // 使用确定性 ID:同一服务端事件 + 同一 part 类型始终生成相同 ID,\n // 确保多次 mapSessionMessages 调用产生的消息可以被 id 去重正确识别。\n let partCounter = 0;\n\n if (textParts.length > 0 || fileDataParts.length > 0) {\n const messageItem: IMessage = {\n id: `session-event:${item.id}:${partCounter++}`,\n author: item.author,\n invocationId: item.invocationId,\n eventId: item.id,\n timestamp: item.timestamp,\n isLike: item.isLike,\n role,\n modelCode: item.modelCode,\n usageMetadata: item.usageMetadata,\n finishReason: item.finishReason,\n raw: item,\n };\n\n textParts.forEach((part: any) => {\n if (part.inlineData) {\n messageItem.inlineData = {\n displayName: part.inlineData.displayName,\n data: part.inlineData.data,\n mimeType: part.inlineData.mimeType,\n };\n }\n if (part.text) {\n messageItem.text =\n (messageItem.text ? `${messageItem.text}\\n` : \"\") + part.text;\n if (typeof part.thought !== \"undefined\")\n messageItem.thought = part.thought;\n }\n if (part.errorMessage) {\n messageItem.text =\n (messageItem.text ? `${messageItem.text}\\n` : \"\") +\n part.errorMessage;\n }\n });\n\n if (fileDataParts.length > 0) {\n messageItem.fileData = fileDataParts.map((part: any) => ({\n displayName: part.fileData.displayName || \"\",\n fileUri: part.fileData.fileUri,\n mimeType: part.fileData.mimeType,\n }));\n }\n mapped.push(messageItem);\n }\n\n otherParts.forEach((part: any) => {\n const messageItem: IMessage = {\n id: `session-event:${item.id}:${partCounter++}`,\n author: item.author,\n invocationId: item.invocationId,\n eventId: item.id,\n timestamp: item.timestamp,\n isLike: item.isLike,\n role,\n modelCode: item.modelCode,\n usageMetadata: item.usageMetadata,\n finishReason: item.finishReason,\n raw: item,\n };\n\n if (part.functionCall) messageItem.functionCall = part.functionCall;\n if (part.executableCode) messageItem.executableCode = part.executableCode;\n if (part.codeExecutionResult)\n messageItem.codeExecutionResult = part.codeExecutionResult;\n if (part.functionResponse) {\n const functionCallMessage = mapped.find(\n (currentMessage) =>\n currentMessage.functionCall?.id === part.functionResponse?.id,\n );\n if (functionCallMessage) {\n functionCallMessage.functionResponse = part.functionResponse;\n }\n return;\n }\n mapped.push(messageItem);\n });\n });\n return mapped;\n};\n\nconst insertMissingSessionEvents = (\n currentMessages: IMessage[],\n sessionEvents: any[],\n removedInvocationIds?: Set<string>,\n) => {\n const renderedEventIds = new Set(\n currentMessages.map(getMessageEventId).filter(Boolean),\n );\n\n // 从所有 sessionEvents 中提取 functionResponse,配对到 currentMessages 中缺少响应的 functionCall\n // (functionResponse 事件的 role 为 user,不应作为独立消息展示,仅用于补齐工具调用状态)\n let nextMessages = [...currentMessages];\n const fnResMap = new Map<string, any>();\n sessionEvents.forEach((event) => {\n if (event.content?.role !== \"user\" || !Array.isArray(event.content?.parts))\n return;\n event.content.parts.forEach((p: any) => {\n if (p.functionResponse?.id) {\n fnResMap.set(p.functionResponse.id, p.functionResponse);\n }\n });\n });\n if (fnResMap.size > 0) {\n let paired = false;\n nextMessages = nextMessages.map((msg) => {\n if (msg.functionCall && !msg.functionResponse) {\n const callId = msg.functionCall.id;\n if (callId && fnResMap.has(callId)) {\n paired = true;\n return { ...msg, functionResponse: fnResMap.get(callId) };\n }\n }\n return msg;\n });\n if (!paired) nextMessages = currentMessages;\n }\n\n const missingEvents = sessionEvents.filter((event) => {\n const parts = event.content?.parts;\n const canRender =\n Boolean(event.id) &&\n event.content?.role === \"model\" &&\n Array.isArray(parts) &&\n parts.length > 0;\n if (!canRender || renderedEventIds.has(event.id)) return false;\n\n // reChat 截断后,忽略被删除的 invocationId 对应的旧 bot 消息\n if (\n removedInvocationIds &&\n removedInvocationIds.size > 0 &&\n event.invocationId &&\n removedInvocationIds.has(event.invocationId)\n ) {\n return false;\n }\n\n return true;\n });\n if (missingEvents.length === 0) return nextMessages;\n\n const missingMessages = mapSessionMessages(missingEvents);\n if (missingMessages.length === 0) return nextMessages;\n\n const eventOrder = new Map(\n sessionEvents.map((event, index) => [event.id, index]),\n );\n const getMessageOrder = (messageItem: IMessage) => {\n const eventId = getMessageEventId(messageItem);\n if (eventId && eventOrder.has(eventId)) return eventOrder.get(eventId)!;\n\n const timestamp = messageItem.timestamp ?? messageItem.raw?.timestamp;\n if (timestamp !== undefined) {\n const nextEventIndex = sessionEvents.findIndex(\n (event) => (event.timestamp || 0) > timestamp,\n );\n return nextEventIndex < 0\n ? sessionEvents.length + 0.5\n : nextEventIndex - 0.5;\n }\n return Number.POSITIVE_INFINITY;\n };\n\n // nextMessages 已在上方 functionResponse 配对阶段创建,此处直接复用\n missingMessages.forEach((messageItem) => {\n const targetOrder = getMessageOrder(messageItem);\n let insertIndex = nextMessages.findIndex((currentMessage) => {\n const currentOrder = getMessageOrder(currentMessage);\n return Number.isFinite(currentOrder) && currentOrder > targetOrder;\n });\n if (insertIndex < 0) insertIndex = nextMessages.length;\n nextMessages.splice(insertIndex, 0, messageItem);\n });\n return nextMessages;\n};\n\n// 后台会话连接状态\ninterface BackgroundSession {\n ctrl: AbortController;\n messages: IMessage[];\n loading: boolean;\n textMsgRef: IMessage | null;\n}\n\nfunction useADKChat({\n url = window.location.origin,\n token,\n config = {},\n type: _type = \"agentDebug\",\n enabled = true, // ← 新增: 是否启用 Hook\n strategies,\n onError,\n onMessage,\n onSuccess,\n onStream,\n}: DebugOptions) {\n const [loading, setLoadingState] = useState(false);\n const loadingRef = useRef(false);\n const setLoading = useCallback((nextLoading: boolean) => {\n loadingRef.current = nextLoading;\n setLoadingState(nextLoading);\n }, []);\n const [sessionLoading, setSessionLoading] = useState(false);\n const sendingRef = useRef(false); // 同步锁,防止快速重复点击\n const ctrl = useRef<AbortController | null>(null);\n const tokenRef = useRef(token);\n tokenRef.current = token;\n // 应用配置\n const { appNo, showFirstSession } = config || {};\n const pollSessionEvents = config?.session?.pollSessionEvents ?? true;\n const sessionEventsPollingInterval = Math.max(\n config?.session?.sessionEventsPollingInterval ??\n DEFAULT_SESSION_EVENTS_POLLING_INTERVAL,\n 1000,\n );\n const [appInfo, setAppInfo] = useState<ChatConfig | null>(null);\n // 初始化完成\n const [initialized, setInitialized] = useState(false);\n // 会话记录\n const [sessionList, setSessionList] = useState<SessionData[]>([]);\n // 当前会话\n const [currentSessionId, setCurrentSessionId] = useState<string>(() => v4());\n // 会话分页设置\n const [sessionPagination, setSessionPagination] = useState({\n total: 0,\n pageNum: 1,\n pageSize: SESSION_PAGE_SIZE,\n });\n // 开场白\n const [prologue, setPrologue] = useState<string>(\"\");\n // 建议问题\n const [suggestedQuestions, setSuggestedQuestions] = useState<string[]>([]);\n const [messages, setMessages] = useState<IMessage[]>([]);\n const pendingSessionEventsRef = useRef<{\n sessionId: string;\n events: any[];\n } | null>(null);\n // 记录上次同步的事件数量,若接口返回长度未变化则跳过后续遍历处理\n const lastSyncedEventsLengthRef = useRef<number>(0);\n const sessionDetailLoadingRef = useRef(false);\n // 用户自定义业务参数 (stateDelta),每次发送请求时携带\n const stateDeltaRef = useRef<Record<string, any> | undefined>(undefined);\n // reChat 截断消息时记录被删除的 invocationId,防止轮询把旧 bot 回复补回\n const reChatRemovedInvocationIdsRef = useRef<Set<string>>(new Set());\n\n // ===== 多会话后台连接管理 =====\n const backgroundRef = useRef<Map<string, BackgroundSession>>(new Map());\n const messagesRef = useRef<IMessage[]>(messages);\n messagesRef.current = messages;\n const currentSessionIdRef = useRef<string>(currentSessionId);\n currentSessionIdRef.current = currentSessionId;\n // 合并消息\n const mergedMessages = useMemo(() => {\n const fnResMap: Record<string, FunctionResponse> = {};\n const uniqueMessages = deduplicateMessages(messages);\n uniqueMessages.forEach((msg) => {\n if (msg.functionResponse) {\n fnResMap[msg?.functionResponse?.id || \"\"] = msg.functionResponse;\n }\n });\n return uniqueMessages.map((msg) => {\n if (msg.functionCall) {\n return {\n ...msg,\n functionResponse: fnResMap[msg?.functionCall?.id || \"\"],\n };\n }\n return msg;\n });\n }, [messages]);\n const textMsgRef = useRef<IMessage>(null);\n const eventDataRef = useRef<Map<string, any>>(new Map());\n const flushPendingSessionEvents = useCallback(() => {\n const pending = pendingSessionEventsRef.current;\n // 仅在用户正在发送或流式文本拼接时跳过 flush,\n // loading 状态不应阻塞轮询补入(异步任务完成的消息需要在 loading 期间也能补入)\n const replyInProgress = sendingRef.current || textMsgRef.current !== null;\n if (\n !pending ||\n replyInProgress ||\n pending.sessionId !== currentSessionIdRef.current\n )\n return;\n\n pendingSessionEventsRef.current = null;\n\n // 使用 functional update 在同一个 setMessages 回调中完成 diff + 写入,\n // 避免双重调用和 loading 闪烁。仅在有实际新消息时才触发 loading 状态。\n setMessages((prev) => {\n const nextMessages = insertMissingSessionEvents(\n prev,\n pending.events,\n reChatRemovedInvocationIdsRef.current,\n );\n if (nextMessages === prev) return prev; // 无变化,不触发 re-render\n messagesRef.current = nextMessages;\n return nextMessages;\n });\n }, []);\n\n // ===== 多会话轮询事件同步 =====\n const syncSessionEvents = useCallback(\n (events: any[], targetSessionId: string) => {\n if (targetSessionId !== currentSessionIdRef.current) return;\n // 接口返回的事件数量与上次一致,说明列表未发生变化,跳过后续遍历处理\n if (events.length === lastSyncedEventsLengthRef.current) return;\n lastSyncedEventsLengthRef.current = events.length;\n pendingSessionEventsRef.current = {\n sessionId: targetSessionId,\n events,\n };\n flushPendingSessionEvents();\n },\n [flushPendingSessionEvents],\n );\n\n useEffect(() => {\n pendingSessionEventsRef.current = null;\n lastSyncedEventsLengthRef.current = 0;\n }, [currentSessionId]);\n\n useEffect(() => {\n if (!loading) flushPendingSessionEvents();\n }, [flushPendingSessionEvents, loading]);\n\n // 插入消息\n const insertMessage = useCallback((msg: IMessage) => {\n setMessages((prev) => {\n const lastMessage = prev[prev.length - 1];\n if (lastMessage?.isLoading) {\n return [...prev.slice(0, -1), msg, lastMessage];\n }\n return [...prev, msg];\n });\n }, []);\n\n // 初始化开场白预设置问题\n const insertSuggestedQuestions = useCallback(\n (suggested_questions: string[] = []) => {\n if (!suggested_questions?.length) return;\n // 无消息内容 且 有建议问题时\n setSuggestedQuestions((prev) =>\n messages.length === 0 ? suggested_questions : prev,\n );\n },\n [messages.length],\n );\n\n // 初始化开场白\n const insertPrologue = useCallback((prologueText: string) => {\n if (prologueText) {\n setPrologue(prologueText);\n }\n }, []);\n\n // 更新消息\n const updateMessage = useCallback((msg: IMessage) => {\n setMessages((prev) => {\n return prev.map((m) => {\n if (m.id === msg.id) {\n return msg;\n }\n return m;\n });\n });\n }, []);\n\n const withEventMeta = useCallback((msg: IMessage, event: Event): IMessage => {\n return {\n ...msg,\n modelCode: event.modelCode ?? msg.modelCode,\n usageMetadata: event.usageMetadata ?? msg.usageMetadata,\n finishReason: event.finishReason ?? msg.finishReason,\n raw: {\n ...(msg.raw || {}),\n ...event,\n },\n };\n }, []);\n\n const updateLastBotEventMeta = useCallback(\n (event: Event) => {\n if (!event.modelCode && !event.usageMetadata && !event.finishReason)\n return;\n\n setMessages((prev) => {\n const next = [...prev];\n const index = next.findLastIndex((msg) => msg.role === \"bot\");\n if (index < 0) return prev;\n\n next[index] = withEventMeta(next[index], event);\n return next;\n });\n },\n [withEventMeta],\n );\n\n // 存储事件\n const storeEvents = useCallback((part: Part | null, event: any) => {\n let title = \"\";\n\n if (part == null && event.actions?.artifactDelta) {\n title += \"eventAction: artifact\";\n } else if (part) {\n if (part.text) {\n title += `text:${part.text}`;\n } else if (part.functionCall) {\n title += `functionCall:${part.functionCall.name}`;\n } else if (part.functionResponse) {\n title += `functionResponse:${part.functionResponse.name}`;\n } else if (part.executableCode) {\n title += `executableCode:${part.executableCode.code?.slice(0, 10)}`;\n } else if (part.codeExecutionResult) {\n title += `codeExecutionResult:${part.codeExecutionResult.outcome}`;\n } else if (part.errorMessage) {\n title += `errorMessage:${part.errorMessage}`;\n }\n }\n\n const updatedEvent = { ...event, title };\n\n const newEventData = new Map(eventDataRef.current);\n newEventData.set(event.id, updatedEvent);\n eventDataRef.current = newEventData;\n }, []);\n\n // 存储消息\n const storeMessage = useCallback(\n (part: Part | null, event: Event, role: \"user\" | \"bot\") => {\n if (!part || Object.keys(part).length === 0) return;\n\n const msg = buildNonTextMessage(event, part, role);\n\n // groundingMetadata 仅在前台 SSE 场景需要\n if (\n part.text &&\n event?.groundingMetadata?.searchEntryPoint?.renderedContent\n ) {\n msg.renderedContent =\n event.groundingMetadata.searchEntryPoint.renderedContent;\n }\n\n insertMessage(msg);\n },\n [insertMessage],\n );\n\n // 处理消息部分(关键更新)\n const processPart = useCallback(\n (event: Event, part: Part, ignore: boolean = false) => {\n const renderedContent =\n event.groundingMetadata?.searchEntryPoint?.renderedContent;\n if (part.text) {\n if (ignore) return;\n const newChunk = part.text;\n\n if (\n !textMsgRef.current ||\n textMsgRef.current.thought !== part.thought\n ) {\n const newMessage: IMessage = {\n id: v4(),\n author: event.author,\n invocationId: event.invocationId,\n eventId: event.id,\n timestamp: event.timestamp,\n role: \"bot\",\n text: newChunk,\n isLike: event.isLike || 0,\n thought: part.thought,\n modelCode: event.modelCode,\n usageMetadata: event.usageMetadata,\n finishReason: event.finishReason,\n raw: event,\n };\n\n if (renderedContent) {\n newMessage.renderedContent = renderedContent;\n }\n\n textMsgRef.current = newMessage;\n // 存储原数据\n storeEvents(part, event);\n // 插入消息\n insertMessage(newMessage);\n } else {\n if (renderedContent) {\n textMsgRef.current = {\n ...textMsgRef.current,\n renderedContent,\n };\n }\n textMsgRef.current = {\n ...withEventMeta(textMsgRef.current, event),\n text: (textMsgRef.current.text || \"\") + newChunk,\n };\n updateMessage(textMsgRef.current);\n if (event.partial === false) {\n storeEvents(part, event);\n textMsgRef.current = null;\n }\n }\n } else {\n textMsgRef.current = null;\n storeEvents(part, event);\n storeMessage(part, event, \"bot\");\n }\n },\n [storeEvents, storeMessage, insertMessage, updateMessage, withEventMeta],\n );\n\n // 处理建议类消息\n const processFollowupPart = useCallback(\n (event: Event) => {\n // 获取建议类消息的文本内容\n const part = event?.content?.parts?.[0] || null;\n const text = part?.text || \"\";\n storeEvents(part, event);\n if (text) {\n setSuggestedQuestions((prev) => [...prev, text]);\n }\n },\n [storeEvents],\n );\n\n // 处理错误消息\n const processErrorMessage = useCallback(\n (chunkJson: any) => {\n storeEvents(null, chunkJson);\n insertMessage({\n id: v4(),\n text: chunkJson.errorMessage,\n role: \"bot\",\n });\n },\n [storeEvents, insertMessage],\n );\n\n // 处理动作和制品\n const processActionArtifact = useCallback(\n (event: any) => {\n if (event.actions && event.actions.artifactDelta) {\n storeEvents(null, event);\n storeMessage(null, event, \"bot\");\n }\n },\n [storeEvents, storeMessage],\n );\n\n // 发送消息请求\n const sendMessageRequest = useCallback(\n (values: AgentRunRequest) => {\n return new Promise<void>((resolve) => {\n const targetSessionId = values.sessionId || currentSessionIdRef.current;\n\n // 只 abort 同一 session 的旧连接\n if (targetSessionId === currentSessionIdRef.current && ctrl.current) {\n ctrl.current.abort();\n }\n const newCtrl = new AbortController();\n if (targetSessionId === currentSessionIdRef.current) {\n setLoading(true);\n ctrl.current = newCtrl;\n }\n\n // 当 signal 被外部 abort(stopChat)时,确保外层 Promise 被 resolve\n // 否则 startChat 中的 await 会永远挂起,sendingRef 无法重置为 false\n newCtrl.signal.addEventListener(\n \"abort\",\n () => {\n resolve();\n },\n { once: true },\n );\n\n const requestUrl = `${url}/api/gateway-web/openApi/v1/aizt/app/${appNo}/sendMsgStreaming`;\n\n // 后台流式文本拼接\n let bgTextMsg: IMessage | null = null;\n\n fetchEventSource(requestUrl, {\n method: \"POST\",\n signal: newCtrl.signal,\n body: JSON.stringify(values),\n openWhenHidden: true,\n headers: {\n \"Content-Type\": \"application/json\",\n \"Cache-Control\": \"no-cache\",\n stream: \"true\",\n Authorization: `Bearer ${tokenRef.current}`,\n },\n async onopen(response) {\n if (\n response.ok &&\n response.headers.get(\"content-type\") === EventStreamContentType\n ) {\n // everything's good\n } else if (response.status === 401 || response.status === 403) {\n setLoading(false);\n onError?.({\n code: ErrorCode.AUTH_ERROR,\n message:\n response.status === 401\n ? \"认证失败,token 无效或已过期\"\n : \"无权限访问该资源\",\n });\n resolve();\n } else if (\n response.status >= 400 &&\n response.status < 500 &&\n response.status !== 429\n ) {\n resolve();\n } else {\n resolve();\n }\n },\n onmessage: (event) => {\n const rawData = safeJsonParse(event.data, {});\n\n // 处理新的数据格式: { data: {...}, result: {...} }\n let chunkJson: Event = rawData;\n if (rawData.data && rawData.result) {\n // 转换为旧格式\n chunkJson = {\n ...rawData.data,\n content: rawData.data,\n invocationId: rawData.result.invocationId,\n sessionId: rawData.result.sessionId,\n id:\n rawData.data.id ||\n rawData.result.id ||\n rawData.result.eventId ||\n rawData.result.invocationId,\n };\n }\n\n if (chunkJson.error) {\n message.warning(chunkJson.error);\n return;\n }\n\n // 判断是否为后台 session\n const isBackground =\n currentSessionIdRef.current !== targetSessionId;\n\n if (isBackground) {\n // 后台 session:更新 backgroundRef 中的消息\n const bg = backgroundRef.current.get(targetSessionId);\n if (!bg) return;\n\n if (chunkJson.content) {\n if (chunkJson.content.role === \"followup\") return;\n for (const part of combineTextParts(chunkJson.content.parts)) {\n const isPureText = part.text && !part.fileData;\n if (isPureText) {\n if (chunkJson?.partial === false) continue;\n const newChunk = part.text || \"\";\n if (!bgTextMsg || bgTextMsg?.thought !== part.thought) {\n const newMessage: IMessage = {\n id: v4(),\n author: chunkJson.author,\n invocationId: chunkJson.invocationId,\n eventId: chunkJson.id,\n timestamp: chunkJson.timestamp,\n role: \"bot\",\n text: newChunk,\n thought: part.thought,\n };\n bgTextMsg = newMessage;\n bg.messages = [...bg.messages, newMessage];\n } else {\n bgTextMsg = {\n ...bgTextMsg,\n text: (bgTextMsg.text || \"\") + newChunk,\n };\n bg.messages = bg.messages.map((m) =>\n m.id === bgTextMsg!.id ? bgTextMsg! : m,\n );\n if (chunkJson.finishReason === \"stop\") {\n bgTextMsg = null;\n }\n }\n } else {\n bgTextMsg = null;\n bg.messages = [\n ...bg.messages,\n buildNonTextMessage(chunkJson, part),\n ];\n }\n }\n } else if (chunkJson.errorMessage) {\n bg.messages = [\n ...bg.messages,\n { id: v4(), text: chunkJson.errorMessage, role: \"bot\" },\n ];\n }\n bg.textMsgRef = bgTextMsg;\n return;\n }\n\n // 前台 session:正常处理\n onStream?.(chunkJson);\n updateLastBotEventMeta(chunkJson);\n if (chunkJson.content) {\n // 建议类消息单独处理\n if (chunkJson.content.role === \"followup\") {\n processFollowupPart(chunkJson);\n return;\n }\n // eslint-disable-next-line no-restricted-syntax\n for (const part of combineTextParts(chunkJson.content.parts)) {\n // partial为 false 时忽略该条消息文本\n processPart(chunkJson, part, chunkJson?.partial === false);\n }\n } else if (chunkJson.errorMessage) {\n processErrorMessage(chunkJson);\n } else if (chunkJson.actions) {\n processActionArtifact(chunkJson);\n }\n },\n onclose: () => {\n const isBackground =\n currentSessionIdRef.current !== targetSessionId;\n if (isBackground) {\n const bg = backgroundRef.current.get(targetSessionId);\n if (bg) {\n bg.loading = false;\n bg.textMsgRef = null;\n }\n // 如果该后台会话已被恢复到前台(backgroundRef 中已删除),\n // 需要更新前台 loading 状态\n if (\n !backgroundRef.current.has(targetSessionId) &&\n currentSessionIdRef.current === targetSessionId\n ) {\n setLoading(false);\n textMsgRef.current = null;\n }\n } else {\n setLoading(false);\n if (textMsgRef.current) {\n onMessage?.(textMsgRef.current?.text || \"\", textMsgRef.current);\n }\n textMsgRef.current = null;\n ctrl.current = null;\n }\n resolve();\n },\n onerror: (error) => {\n const isBackground =\n currentSessionIdRef.current !== targetSessionId;\n if (isBackground) {\n const bg = backgroundRef.current.get(targetSessionId);\n if (bg) bg.loading = false;\n // 同上:后台会话已恢复到前台时同步 loading 状态\n if (\n !backgroundRef.current.has(targetSessionId) &&\n currentSessionIdRef.current === targetSessionId\n ) {\n setLoading(false);\n ctrl.current = null;\n }\n } else {\n setLoading(false);\n ctrl.current = null;\n }\n resolve();\n console.error(\"EventSource failed:\", error);\n throw error;\n },\n });\n });\n },\n [\n processActionArtifact,\n processErrorMessage,\n processPart,\n updateLastBotEventMeta,\n ],\n );\n\n // 发送会话\n const startChat = async ({\n text = \"\",\n files = [],\n functionResponse,\n }: SendContent) => {\n if (loadingRef.current || sendingRef.current) return;\n if (!text.trim() && !files?.length && !functionResponse) return;\n sendingRef.current = true;\n // 清空建议问题\n setSuggestedQuestions([]);\n // 正常发送时重置 reChat 删除标记\n reChatRemovedInvocationIdsRef.current = new Set();\n // 发送消息\n setMessages((prev) => {\n let temp = [...prev];\n // 如果 text 存在\n if (text.trim()) {\n temp.push({\n id: v4(),\n role: \"user\",\n text,\n });\n }\n // 如果file 存在\n if (files.length > 0) {\n temp.push({\n id: v4(),\n role: \"user\",\n fileData: files.map((file) => ({\n displayName: file.fileName || file.name,\n mimeType: file.mimeType || file.response?.mimeType,\n fileUri:\n file.tempUrl || file.response?.fileUrl || file.response?.tempUrl,\n })),\n });\n }\n // 如果 functionResponse 存在\n if (functionResponse) {\n temp.push({\n id: v4(),\n role: \"user\",\n functionResponse,\n });\n }\n return temp;\n });\n try {\n await sendMessageRequest({\n stream: true,\n sessionId: currentSessionId,\n content: {\n role: \"user\",\n parts: functionResponse ? [{ functionResponse }] : [{ text }],\n },\n files: files.map((file) => ({\n fileName: file.fileName || file.response?.fileName,\n fileId: file.fileId || file.response?.fileId,\n tempUrl:\n file.tempUrl || file.response?.fileUrl || file.response?.tempUrl,\n type: file.type || file.response?.fileType,\n mimeType: file.mimeType || file.response?.mimeType,\n })),\n ...(stateDeltaRef.current !== undefined && {\n stateDelta: stateDeltaRef.current,\n }),\n });\n } finally {\n sendingRef.current = false;\n }\n // 获取聊天记录\n initAppConversations();\n };\n\n // 重新发送会话\n const reChat = async () => {\n if (loadingRef.current || sendingRef.current) return;\n if (messages.length === 0) return;\n sendingRef.current = true;\n // 清空建议问题\n setSuggestedQuestions([]);\n\n // 找到最后一条用户消息的索引,删除其后所有 bot 消息\n const lastUserIndex = messages.findLastIndex(\n (msg) => msg.role === \"user\" && !msg.functionResponse,\n );\n if (lastUserIndex === -1) {\n sendingRef.current = false;\n return;\n }\n\n const newMessages = messages.slice(0, lastUserIndex + 1);\n setMessages(newMessages);\n\n // 收集被截断的 bot 消息的 invocationId,轮询时忽略这些旧回复\n const removedInvocationIds = new Set<string>();\n for (let i = lastUserIndex + 1; i < messages.length; i++) {\n const msg = messages[i];\n if (msg.invocationId) removedInvocationIds.add(msg.invocationId);\n }\n reChatRemovedInvocationIdsRef.current = removedInvocationIds;\n\n const lastUserMessage = newMessages[lastUserIndex];\n const { text = \"\", fileData = [] } = lastUserMessage;\n\n try {\n await sendMessageRequest({\n stream: true,\n sessionId: currentSessionId,\n content: {\n role: \"user\",\n parts: [{ text }],\n },\n files: fileData?.map((file) => ({\n fileName: file.displayName,\n tempUrl: file.fileUri,\n mimeType: file.mimeType,\n })),\n ...(stateDeltaRef.current !== undefined && {\n stateDelta: stateDeltaRef.current,\n }),\n });\n } finally {\n sendingRef.current = false;\n }\n };\n\n // 确认函数调用\n const confirmFnCall = (fnCall: FunctionCall, confirmed: boolean) => {\n const functionResponse = strategies?.createFunctionResponse?.(\n fnCall,\n confirmed,\n ) ?? {\n id: fnCall.id,\n name: fnCall.name,\n response: { confirmed },\n };\n startChat({ functionResponse });\n };\n\n // 使用建议问题\n const suggestChat = (text: string) => {\n if (loadingRef.current) return;\n if (!text.trim()) return;\n setSuggestedQuestions([]);\n startChat({ text });\n };\n\n // 停止会话(只中断前台连接)\n const stopChat = useCallback(() => {\n pendingSessionEventsRef.current = null;\n ctrl.current?.abort();\n ctrl.current = null;\n setLoading(false);\n textMsgRef.current = null;\n }, [setLoading]);\n\n // 清除/重置会话\n const clearChat = () => {\n const newSessionId = v4();\n setCurrentSessionId(newSessionId);\n // 清除 reChat 删除标记\n reChatRemovedInvocationIdsRef.current = new Set();\n // 重置聊天内容\n stopChat();\n setPrologue(appInfo?.onboardingInfo?.prologue || \"\");\n setMessages([]);\n setSuggestedQuestions(appInfo?.onboardingInfo?.suggested_questions || []);\n };\n\n // 格式化会话记录\n const formatMessages = useCallback(\n (sessionEvents: any[], isReplace = false) => {\n const mapped = mapSessionMessages(sessionEvents);\n setMessages((prev) => (isReplace ? mapped : [...prev, ...mapped]));\n },\n [],\n );\n\n // 设置当前会话详情\n const setCurrentSession = async (sessionId: string) => {\n if (sessionId) {\n if (sessionId === currentSessionId) {\n return;\n }\n\n pendingSessionEventsRef.current = null;\n // 切换会话时重置 reChat 删除标记\n reChatRemovedInvocationIdsRef.current = new Set();\n\n // 1. 将当前会话挂起到后台(不中断 SSE 连接)\n const prevSessionId = currentSessionId;\n if (ctrl.current) {\n // 有活跃流式连接,保存到后台\n backgroundRef.current.set(prevSessionId, {\n ctrl: ctrl.current,\n messages: [...messagesRef.current],\n loading: true,\n textMsgRef: textMsgRef.current,\n });\n ctrl.current = null;\n textMsgRef.current = null;\n setLoading(false);\n } else if (messagesRef.current.length > 0) {\n // 无活跃连接但有消息,缓存用于切回\n backgroundRef.current.set(prevSessionId, {\n ctrl: new AbortController(),\n messages: [...messagesRef.current],\n loading: false,\n textMsgRef: null,\n });\n }\n\n // 2. 尝试从后台恢复目标会话\n const bg = backgroundRef.current.get(sessionId);\n if (bg) {\n setMessages(bg.messages);\n messagesRef.current = bg.messages;\n textMsgRef.current = bg.textMsgRef;\n // 仅当 SSE 连接还在运行时才恢复 loading 状态,\n // 避免 SSE 已关闭但 bg 快照中 loading 仍为 true 导致 sender 永久卡住\n const isSseStillActive = bg.loading && !bg.ctrl.signal.aborted;\n setLoading(isSseStillActive);\n ctrl.current = isSseStillActive ? bg.ctrl : null;\n setCurrentSessionId(sessionId);\n setInitialized(true);\n backgroundRef.current.delete(sessionId);\n return;\n }\n\n // 3. 后台没有目标 session,走 API 加载(原有逻辑)\n setInitialized(false);\n setCurrentSessionId(sessionId);\n sessionDetailLoadingRef.current = true;\n try {\n const { data, result } = await fetchSessionDetail({\n url,\n appNo,\n sessionId,\n token: tokenRef.current,\n });\n\n if (result?.code === API_SUCCESS_CODE) {\n setPrologue(appInfo?.onboardingInfo?.prologue || \"\");\n if (Array.isArray(data) && data.length > 0) {\n formatMessages(data, true);\n } else {\n setSuggestedQuestions(\n appInfo?.onboardingInfo?.suggested_questions || [],\n );\n }\n }\n } finally {\n sessionDetailLoadingRef.current = false;\n setInitialized(true);\n }\n } else {\n setCurrentSessionId(v4());\n }\n };\n\n // 获取聊天记录\n const initAppConversations = async (fetchDetail = false) => {\n try {\n setSessionLoading(true);\n\n const {\n data = [],\n pagination,\n result,\n } = await fetchSessionList({\n url,\n appNo,\n token: tokenRef.current,\n pageSize: sessionPagination.pageSize,\n });\n\n if (result?.code === API_SUCCESS_CODE) {\n if (data.length > 0) {\n const formatSessions = data.map((item) => {\n return {\n key: item.sessionId,\n label: item.title || \"新对话\",\n timestamp: new Date(item.startTime).getTime(),\n messages: [],\n meta: {\n ...item,\n },\n };\n });\n\n setSessionList(formatSessions);\n // 设置分页信息\n setSessionPagination({\n pageNum: sessionPagination.pageNum,\n pageSize: sessionPagination.pageSize,\n total: pagination?.total || 0,\n });\n const { sessionId } = data?.[0];\n if (showFirstSession) {\n setCurrentSession(sessionId);\n } else {\n fetchDetail && setPrologue(appInfo?.onboardingInfo?.prologue || \"\");\n fetchDetail &&\n setSuggestedQuestions(\n appInfo?.onboardingInfo?.suggested_questions || [],\n );\n }\n // 成功回调\n if (!initialized) {\n onSuccess?.({\n code: SuccessCode.APP_MESSAGES_INIT_SUCCESS,\n message: \"初始化聊天记录成功\",\n data: {\n sessionId,\n },\n });\n setInitialized(true);\n }\n } else {\n // 无会话记录时,初始化会话详情\n clearChat();\n }\n } else {\n // 服务端业务错误,透传原始 code + message 给接入方自行处理\n onError?.({\n code: result?.code || \"UNKNOWN_ERROR\",\n message: result?.message || \"获取会话列表失败\",\n raw: result,\n });\n setSessionList([]);\n setCurrentSessionId(v4());\n setPrologue(\"\");\n setSuggestedQuestions([]);\n }\n } catch {\n onError?.({\n code: ErrorCode.NETWORK_ERROR,\n message: \"获取会话列表失败\",\n });\n } finally {\n setSessionLoading(false);\n }\n };\n\n // 删除会话\n const deleteSession = async (sessionId: string) => {\n if (!sessionId) return;\n const { result } = await closeSession({\n url,\n appNo,\n sessionId,\n token: tokenRef.current,\n });\n if (result?.code === API_SUCCESS_CODE) {\n // 删除成功后,重新获取会话列表\n initAppConversations(true);\n // 如果删除的是当前会话,则创建新的会话\n if (sessionId === currentSessionId) {\n clearChat();\n }\n } else {\n message.error(\"删除会话失败\");\n }\n };\n\n // 点赞/点踩\n const likeMessage = async (\n invocationId: string,\n isLike: 1 | -1,\n feedbackData?: { feedbackTags?: string; feedbackDescription?: string },\n ) => {\n if (!appNo || !invocationId) return false;\n const { result } = await addFeedback({\n url,\n appNo,\n token: tokenRef.current,\n requestId: invocationId,\n isLike,\n ...feedbackData,\n });\n if (result?.code === API_SUCCESS_CODE) {\n setMessages((prev) =>\n prev.map((m) =>\n m.invocationId === invocationId ? { ...m, isLike } : m,\n ),\n );\n return true;\n }\n return false;\n };\n\n // 更新会话名称\n const updateSession = async (sessionId: string, title: string) => {\n if (!sessionId || !title) return;\n const { result } = await updateSessionTitle({\n url,\n appNo,\n title,\n sessionId,\n token: tokenRef.current,\n });\n if (result?.code === API_SUCCESS_CODE) {\n // 编辑成功后,重新获取会话列表\n initAppConversations();\n } else {\n message.error(\"更新会话失败\");\n }\n };\n\n // 初始化应用\n const initConfig = async () => {\n try {\n setSessionLoading(true);\n const { data, result } = await fetchAppConfig({ url, appNo });\n if (result.code === API_SUCCESS_CODE) {\n setAppInfo(data);\n // 成功回调\n onSuccess?.({\n code: SuccessCode.APP_CONFIG_INIT_SUCCESS,\n message: \"初始化配置成功\",\n });\n } else {\n // 服务端业务错误,透传原始 code + message\n onError?.({\n code: result.code || \"UNKNOWN_ERROR\",\n message: result.message || \"获取应用配置失败\",\n raw: result,\n });\n }\n } catch (error) {\n onError?.({\n code: ErrorCode.NETWORK_ERROR,\n message: \"获取应用配置失败\",\n });\n } finally {\n setSessionLoading(false);\n }\n };\n\n // 初始化—获取配置 (仅在启用时)\n useEffect(() => {\n if (enabled && url && appNo) {\n initConfig();\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [enabled, url, appNo]);\n\n // 初始化-聊天记录\n useEffect(() => {\n if (appInfo) {\n initAppConversations(true);\n }\n }, [appInfo]);\n\n // 轮询当前会话详情,空闲时补入后端异步任务产生的模型消息。\n useEffect(() => {\n if (\n !enabled ||\n !initialized ||\n !pollSessionEvents ||\n !appNo ||\n !currentSessionId\n )\n return;\n\n let disposed = false;\n let requesting = false;\n const pollingSessionId = currentSessionId;\n\n const poll = async () => {\n if (disposed || requesting || sessionDetailLoadingRef.current) return;\n requesting = true;\n try {\n const { data, result } = await fetchSessionDetail({\n url,\n appNo,\n sessionId: pollingSessionId,\n token: tokenRef.current,\n });\n if (\n !disposed &&\n result?.code === API_SUCCESS_CODE &&\n Array.isArray(data)\n ) {\n syncSessionEvents(data, pollingSessionId);\n }\n } catch {\n // 新会话尚未落库或短暂网络异常时等待下一轮,不打断当前聊天。\n } finally {\n requesting = false;\n }\n };\n\n // 不立即执行首次 poll,避免与 initAppConversations / setCurrentSession / fetchSessionDetail 竞争。首次数据由初始化流程加载,轮询仅负责后续增量同步。\n const timer = window.setInterval(poll, sessionEventsPollingInterval);\n return () => {\n disposed = true;\n window.clearInterval(timer);\n };\n }, [\n appNo,\n currentSessionId,\n enabled,\n initialized,\n pollSessionEvents,\n sessionEventsPollingInterval,\n syncSessionEvents,\n url,\n ]);\n\n // 组件卸载时清理所有连接(前台 + 后台)\n useEffect(() => {\n return () => {\n ctrl.current?.abort();\n backgroundRef.current.forEach((bg) => bg.ctrl?.abort());\n backgroundRef.current.clear();\n };\n }, []);\n\n return {\n appInfo,\n startChat,\n reChat,\n stopChat,\n clearChat,\n suggestChat,\n confirmFnCall,\n initialized,\n currentSessionId,\n sessionList,\n sessionPagination,\n prologue,\n suggestions: suggestedQuestions,\n loading,\n sessionLoading,\n messages: mergedMessages,\n insertSuggestedQuestions,\n insertPrologue,\n deleteSession,\n updateSession,\n setSuggestedQuestions,\n setCurrentSession,\n setMessages,\n storeEvents,\n storeMessage,\n likeMessage,\n setStateDelta: (delta: Record<string, any> | undefined) => {\n stateDeltaRef.current = delta;\n },\n };\n}\n\nexport default useADKChat;\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { useEffect, useCallback, useMemo, useRef, useState } from \"react\";\nimport {\n fetchEventSource,\n EventStreamContentType,\n} from \"@microsoft/fetch-event-source\";\nimport { message } from \"antd\";\nimport { v4 } from \"uuid\";\nimport { SESSION_PAGE_SIZE, API_SUCCESS_CODE } from \"@/constants\";\nimport {\n SuccessCode,\n ErrorCode,\n DebugOptions,\n FunctionCall,\n SendContent,\n SessionData,\n AgentRunRequest,\n Event,\n FunctionResponse,\n IMessage,\n Part,\n} from \"@/types\";\nimport {\n fetchAppConfig,\n fetchSessionList,\n fetchSessionDetail,\n closeSession,\n updateSessionTitle,\n addFeedback,\n type ChatConfig,\n} from \"@/services/api\";\nimport { safeJsonParse } from \"@/utils\";\n\nconst combineTextParts = (parts: Part[]) => {\n const result: Part[] = [];\n let combinedTextPart: Part | undefined;\n\n // eslint-disable-next-line no-restricted-syntax\n for (const part of parts) {\n // 纯文本 part(没有 fileData 等其他字段)才合并\n const isPureText = part.text && !part.fileData;\n if (isPureText) {\n // 如果没有 combined 或 combined 思考类型跟当前 part 不同,则创建新的合并引用\n if (!combinedTextPart || combinedTextPart.thought !== part.thought) {\n combinedTextPart = { ...part };\n result.push(combinedTextPart);\n } else {\n combinedTextPart.text =\n (combinedTextPart.text || \"\") + (part.text || \"\");\n }\n } else {\n combinedTextPart = undefined;\n result.push(part);\n }\n }\n return result;\n};\n\nconst DEFAULT_SESSION_EVENTS_POLLING_INTERVAL = 10000;\n\n/**\n * 从 event + part 构建非文本 IMessage(functionCall / functionResponse / executableCode 等)。\n */\nconst buildNonTextMessage = (\n event: Event,\n part: Part,\n role: \"user\" | \"bot\" = \"bot\",\n): IMessage => {\n const msg: IMessage = {\n id: v4(),\n author: event.author,\n invocationId: event.invocationId,\n eventId: event.id,\n timestamp: event.timestamp,\n isLike: event.isLike || 0,\n role,\n modelCode: event.modelCode,\n usageMetadata: event.usageMetadata,\n finishReason: event.finishReason,\n raw: event,\n };\n\n if (part.inlineData) {\n msg.inlineData = {\n displayName: part.inlineData.displayName,\n data: part.inlineData.data,\n mimeType: part.inlineData.mimeType,\n };\n } else if (part.fileData) {\n msg.fileData = [part.fileData];\n } else if (part.functionCall) {\n msg.functionCall = part.functionCall;\n } else if (part.functionResponse) {\n msg.functionResponse = part.functionResponse;\n } else if (part.executableCode) {\n msg.executableCode = part.executableCode;\n } else if (part.codeExecutionResult) {\n msg.codeExecutionResult = part.codeExecutionResult;\n } else if (part.text) {\n msg.text = part.text;\n msg.thought = part.thought;\n }\n\n return msg;\n};\n\nconst getMessageEventId = (messageItem: IMessage) =>\n messageItem.eventId || messageItem.raw?.id;\n\nconst deduplicateMessages = (messageItems: IMessage[]) => {\n const seenMessageIds = new Set<string>();\n let hasDuplicate = false;\n\n const uniqueIdMessages = messageItems.filter((messageItem) => {\n if (seenMessageIds.has(messageItem.id)) {\n hasDuplicate = true;\n return false;\n }\n seenMessageIds.add(messageItem.id);\n return true;\n });\n\n // 机器人文本消息去重:同一 invocationId + 思考类型的文本消息,\n // 如果文本内容存在包含关系,保留最长的(sessionDetails 完整消息),去掉被包含的短文本(SSE 流式增量)。\n // 使用 invocationId 分组,同一轮对话的 invocationId 始终一致, SSE 后续 chunk 的 首个id 与 sessionDetails 的 id 相同,其余不同,\n const botTextGroups = new Map<\n string,\n Array<{ messageItem: IMessage; normalizedText: string }>\n >();\n uniqueIdMessages.forEach((messageItem) => {\n if (\n messageItem.role !== \"bot\" ||\n !messageItem.invocationId ||\n typeof messageItem.text !== \"string\"\n )\n return;\n\n const normalizedText = messageItem.text.replace(/\\s+/g, \" \").trim();\n if (!normalizedText) return;\n\n const fileKey = (messageItem.fileData || [])\n .map((file) => file.fileUri)\n .join(\"|\");\n const groupKey = `${messageItem.invocationId}\\u0000${Boolean(\n messageItem.thought,\n )}\\u0000${fileKey}`;\n const group = botTextGroups.get(groupKey) || [];\n group.push({ messageItem, normalizedText });\n botTextGroups.set(groupKey, group);\n });\n\n const redundantMessageIds = new Set<string>();\n botTextGroups.forEach((group) => {\n if (group.length <= 1) return;\n const completeTexts: string[] = [];\n [...group]\n .sort((a, b) => b.normalizedText.length - a.normalizedText.length)\n .forEach(({ messageItem, normalizedText }) => {\n if (\n completeTexts.some((completeText) =>\n completeText.includes(normalizedText),\n )\n ) {\n redundantMessageIds.add(messageItem.id);\n hasDuplicate = true;\n return;\n }\n completeTexts.push(normalizedText);\n });\n });\n\n return hasDuplicate\n ? uniqueIdMessages.filter(\n (messageItem) => !redundantMessageIds.has(messageItem.id),\n )\n : messageItems;\n};\n\nconst mapSessionMessages = (sessionEvents: any[]): IMessage[] => {\n const mapped: IMessage[] = [];\n sessionEvents.forEach((item) => {\n if (!item || !item.content || !Array.isArray(item.content.parts)) return;\n // 后端为异步任务插入的用户事件仅用于关联任务,不在页面展示。\n if (\n item.author === \"user\" &&\n item.content.parts.some((part: any) => part.task)\n )\n return;\n // functionResponse 的 user 事件仅用于配对 functionCall,不作为独立消息展示\n if (\n item.content.role === \"user\" &&\n item.content.parts.every((part: any) => !part || part.functionResponse)\n )\n return;\n\n const role =\n (item.content.role || \"\").toLowerCase() === \"user\" ? \"user\" : \"bot\";\n const parts = item.content.parts.filter((part: any) => {\n if (!part) return false;\n return Boolean(\n part.text ||\n part.inlineData ||\n part.functionCall ||\n part.functionResponse ||\n part.fileData ||\n part.executableCode ||\n part.codeExecutionResult ||\n part.errorMessage,\n );\n });\n if (parts.length === 0) return;\n\n const textParts = parts.filter(\n (part: any) => part.text || part.errorMessage || part.inlineData,\n );\n const fileDataParts = parts.filter((part: any) => part.fileData);\n const otherParts = parts.filter(\n (part: any) =>\n !part.text && !part.errorMessage && !part.inlineData && !part.fileData,\n );\n\n // 使用确定性 ID:同一服务端事件 + 同一 part 类型始终生成相同 ID,\n // 确保多次 mapSessionMessages 调用产生的消息可以被 id 去重正确识别。\n let partCounter = 0;\n\n if (textParts.length > 0 || fileDataParts.length > 0) {\n const messageItem: IMessage = {\n id: `session-event:${item.id}:${partCounter++}`,\n author: item.author,\n invocationId: item.invocationId,\n eventId: item.id,\n timestamp: item.timestamp,\n isLike: item.isLike,\n role,\n modelCode: item.modelCode,\n usageMetadata: item.usageMetadata,\n finishReason: item.finishReason,\n raw: item,\n };\n\n textParts.forEach((part: any) => {\n if (part.inlineData) {\n messageItem.inlineData = {\n displayName: part.inlineData.displayName,\n data: part.inlineData.data,\n mimeType: part.inlineData.mimeType,\n };\n }\n if (part.text) {\n messageItem.text =\n (messageItem.text ? `${messageItem.text}\\n` : \"\") + part.text;\n if (typeof part.thought !== \"undefined\")\n messageItem.thought = part.thought;\n }\n if (part.errorMessage) {\n messageItem.text =\n (messageItem.text ? `${messageItem.text}\\n` : \"\") +\n part.errorMessage;\n }\n });\n\n if (fileDataParts.length > 0) {\n messageItem.fileData = fileDataParts.map((part: any) => ({\n displayName: part.fileData.displayName || \"\",\n fileUri: part.fileData.fileUri,\n mimeType: part.fileData.mimeType,\n }));\n }\n mapped.push(messageItem);\n }\n\n otherParts.forEach((part: any) => {\n const messageItem: IMessage = {\n id: `session-event:${item.id}:${partCounter++}`,\n author: item.author,\n invocationId: item.invocationId,\n eventId: item.id,\n timestamp: item.timestamp,\n isLike: item.isLike,\n role,\n modelCode: item.modelCode,\n usageMetadata: item.usageMetadata,\n finishReason: item.finishReason,\n raw: item,\n };\n\n if (part.functionCall) messageItem.functionCall = part.functionCall;\n if (part.executableCode) messageItem.executableCode = part.executableCode;\n if (part.codeExecutionResult)\n messageItem.codeExecutionResult = part.codeExecutionResult;\n if (part.functionResponse) {\n const functionCallMessage = mapped.find(\n (currentMessage) =>\n currentMessage.functionCall?.id === part.functionResponse?.id,\n );\n if (functionCallMessage) {\n functionCallMessage.functionResponse = part.functionResponse;\n }\n return;\n }\n mapped.push(messageItem);\n });\n });\n return mapped;\n};\n\nconst insertMissingSessionEvents = (\n currentMessages: IMessage[],\n sessionEvents: any[],\n removedInvocationIds?: Set<string>,\n) => {\n const renderedEventIds = new Set(\n currentMessages.map(getMessageEventId).filter(Boolean),\n );\n\n // 从所有 sessionEvents 中提取 functionResponse,配对到 currentMessages 中缺少响应的 functionCall\n // (functionResponse 事件的 role 为 user,不应作为独立消息展示,仅用于补齐工具调用状态)\n let nextMessages = [...currentMessages];\n const fnResMap = new Map<string, any>();\n sessionEvents.forEach((event) => {\n if (event.content?.role !== \"user\" || !Array.isArray(event.content?.parts))\n return;\n event.content.parts.forEach((p: any) => {\n if (p.functionResponse?.id) {\n fnResMap.set(p.functionResponse.id, p.functionResponse);\n }\n });\n });\n if (fnResMap.size > 0) {\n let paired = false;\n nextMessages = nextMessages.map((msg) => {\n if (msg.functionCall && !msg.functionResponse) {\n const callId = msg.functionCall.id;\n if (callId && fnResMap.has(callId)) {\n paired = true;\n return { ...msg, functionResponse: fnResMap.get(callId) };\n }\n }\n return msg;\n });\n if (!paired) nextMessages = currentMessages;\n }\n\n const missingEvents = sessionEvents.filter((event) => {\n const parts = event.content?.parts;\n const canRender =\n Boolean(event.id) &&\n event.content?.role === \"model\" &&\n Array.isArray(parts) &&\n parts.length > 0;\n if (!canRender || renderedEventIds.has(event.id)) return false;\n\n // reChat 截断后,忽略被删除的 invocationId 对应的旧 bot 消息\n if (\n removedInvocationIds &&\n removedInvocationIds.size > 0 &&\n event.invocationId &&\n removedInvocationIds.has(event.invocationId)\n ) {\n return false;\n }\n\n return true;\n });\n if (missingEvents.length === 0) return nextMessages;\n\n const missingMessages = mapSessionMessages(missingEvents);\n if (missingMessages.length === 0) return nextMessages;\n\n const eventOrder = new Map(\n sessionEvents.map((event, index) => [event.id, index]),\n );\n const getMessageOrder = (messageItem: IMessage) => {\n const eventId = getMessageEventId(messageItem);\n if (eventId && eventOrder.has(eventId)) return eventOrder.get(eventId)!;\n\n const timestamp = messageItem.timestamp ?? messageItem.raw?.timestamp;\n if (timestamp !== undefined) {\n const nextEventIndex = sessionEvents.findIndex(\n (event) => (event.timestamp || 0) > timestamp,\n );\n return nextEventIndex < 0\n ? sessionEvents.length + 0.5\n : nextEventIndex - 0.5;\n }\n return Number.POSITIVE_INFINITY;\n };\n\n // nextMessages 已在上方 functionResponse 配对阶段创建,此处直接复用\n missingMessages.forEach((messageItem) => {\n const targetOrder = getMessageOrder(messageItem);\n let insertIndex = nextMessages.findIndex((currentMessage) => {\n const currentOrder = getMessageOrder(currentMessage);\n return Number.isFinite(currentOrder) && currentOrder > targetOrder;\n });\n if (insertIndex < 0) insertIndex = nextMessages.length;\n nextMessages.splice(insertIndex, 0, messageItem);\n });\n return nextMessages;\n};\n\n// 后台会话连接状态\ninterface BackgroundSession {\n ctrl: AbortController;\n messages: IMessage[];\n loading: boolean;\n textMsgRef: IMessage | null;\n}\n\nfunction useADKChat({\n url = window.location.origin,\n token,\n config = {},\n type: _type = \"agentDebug\",\n enabled = true, // ← 新增: 是否启用 Hook\n strategies,\n onError,\n onMessage,\n onSuccess,\n onStream,\n}: DebugOptions) {\n const [loading, setLoadingState] = useState(false);\n const loadingRef = useRef(false);\n const setLoading = useCallback((nextLoading: boolean) => {\n loadingRef.current = nextLoading;\n setLoadingState(nextLoading);\n }, []);\n const [sessionLoading, setSessionLoading] = useState(false);\n const sendingRef = useRef(false); // 同步锁,防止快速重复点击\n const ctrl = useRef<AbortController | null>(null);\n const tokenRef = useRef(token);\n tokenRef.current = token;\n // 应用配置\n const { appNo, showFirstSession } = config || {};\n const pollSessionEvents = config?.session?.pollSessionEvents ?? true;\n const sessionEventsPollingInterval = Math.max(\n config?.session?.sessionEventsPollingInterval ??\n DEFAULT_SESSION_EVENTS_POLLING_INTERVAL,\n 1000,\n );\n const [appInfo, setAppInfo] = useState<ChatConfig | null>(null);\n // 初始化完成\n const [initialized, setInitialized] = useState(false);\n // 会话记录\n const [sessionList, setSessionList] = useState<SessionData[]>([]);\n // 当前会话\n const [currentSessionId, setCurrentSessionId] = useState<string>(() => v4());\n // 会话分页设置\n const [sessionPagination, setSessionPagination] = useState({\n total: 0,\n pageNum: 1,\n pageSize: SESSION_PAGE_SIZE,\n });\n // 开场白\n const [prologue, setPrologue] = useState<string>(\"\");\n // 建议问题\n const [suggestedQuestions, setSuggestedQuestions] = useState<string[]>([]);\n const [messages, setMessages] = useState<IMessage[]>([]);\n const pendingSessionEventsRef = useRef<{\n sessionId: string;\n events: any[];\n } | null>(null);\n // 记录上次同步的事件数量,若接口返回长度未变化则跳过后续遍历处理\n const lastSyncedEventsLengthRef = useRef<number>(0);\n const sessionDetailLoadingRef = useRef(false);\n // 用户自定义业务参数 (stateDelta),每次发送请求时携带\n const stateDeltaRef = useRef<Record<string, any> | undefined>(undefined);\n // reChat 截断消息时记录被删除的 invocationId,防止轮询把旧 bot 回复补回\n const reChatRemovedInvocationIdsRef = useRef<Set<string>>(new Set());\n\n // ===== 多会话后台连接管理 =====\n const backgroundRef = useRef<Map<string, BackgroundSession>>(new Map());\n const messagesRef = useRef<IMessage[]>(messages);\n messagesRef.current = messages;\n const currentSessionIdRef = useRef<string>(currentSessionId);\n currentSessionIdRef.current = currentSessionId;\n // 合并消息\n const mergedMessages = useMemo(() => {\n const fnResMap: Record<string, FunctionResponse> = {};\n const uniqueMessages = deduplicateMessages(messages);\n uniqueMessages.forEach((msg) => {\n if (msg.functionResponse) {\n fnResMap[msg?.functionResponse?.id || \"\"] = msg.functionResponse;\n }\n });\n return uniqueMessages.map((msg) => {\n if (msg.functionCall) {\n return {\n ...msg,\n functionResponse: fnResMap[msg?.functionCall?.id || \"\"],\n };\n }\n return msg;\n });\n }, [messages]);\n const textMsgRef = useRef<IMessage>(null);\n const eventDataRef = useRef<Map<string, any>>(new Map());\n const flushPendingSessionEvents = useCallback(() => {\n const pending = pendingSessionEventsRef.current;\n // 仅在用户正在发送或流式文本拼接时跳过 flush,\n // loading 状态不应阻塞轮询补入(异步任务完成的消息需要在 loading 期间也能补入)\n const replyInProgress = sendingRef.current || textMsgRef.current !== null;\n if (\n !pending ||\n replyInProgress ||\n pending.sessionId !== currentSessionIdRef.current\n )\n return;\n\n pendingSessionEventsRef.current = null;\n\n // 使用 functional update 在同一个 setMessages 回调中完成 diff + 写入,\n // 避免双重调用和 loading 闪烁。仅在有实际新消息时才触发 loading 状态。\n setMessages((prev) => {\n const nextMessages = insertMissingSessionEvents(\n prev,\n pending.events,\n reChatRemovedInvocationIdsRef.current,\n );\n if (nextMessages === prev) return prev; // 无变化,不触发 re-render\n messagesRef.current = nextMessages;\n return nextMessages;\n });\n }, []);\n\n // ===== 多会话轮询事件同步 =====\n const syncSessionEvents = useCallback(\n (events: any[], targetSessionId: string) => {\n if (targetSessionId !== currentSessionIdRef.current) return;\n // 接口返回的事件数量与上次一致,说明列表未发生变化,跳过后续遍历处理\n if (events.length === lastSyncedEventsLengthRef.current) return;\n lastSyncedEventsLengthRef.current = events.length;\n pendingSessionEventsRef.current = {\n sessionId: targetSessionId,\n events,\n };\n flushPendingSessionEvents();\n },\n [flushPendingSessionEvents],\n );\n\n useEffect(() => {\n pendingSessionEventsRef.current = null;\n lastSyncedEventsLengthRef.current = 0;\n }, [currentSessionId]);\n\n useEffect(() => {\n if (!loading) flushPendingSessionEvents();\n }, [flushPendingSessionEvents, loading]);\n\n // 插入消息\n const insertMessage = useCallback((msg: IMessage) => {\n setMessages((prev) => {\n const lastMessage = prev[prev.length - 1];\n if (lastMessage?.isLoading) {\n return [...prev.slice(0, -1), msg, lastMessage];\n }\n return [...prev, msg];\n });\n }, []);\n\n // 初始化开场白预设置问题\n const insertSuggestedQuestions = useCallback(\n (suggested_questions: string[] = []) => {\n if (!suggested_questions?.length) return;\n // 无消息内容 且 有建议问题时\n setSuggestedQuestions((prev) =>\n messages.length === 0 ? suggested_questions : prev,\n );\n },\n [messages.length],\n );\n\n // 初始化开场白\n const insertPrologue = useCallback((prologueText: string) => {\n if (prologueText) {\n setPrologue(prologueText);\n }\n }, []);\n\n // 更新消息\n const updateMessage = useCallback((msg: IMessage) => {\n setMessages((prev) => {\n return prev.map((m) => {\n if (m.id === msg.id) {\n return msg;\n }\n return m;\n });\n });\n }, []);\n\n const withEventMeta = useCallback((msg: IMessage, event: Event): IMessage => {\n return {\n ...msg,\n modelCode: event.modelCode ?? msg.modelCode,\n usageMetadata: event.usageMetadata ?? msg.usageMetadata,\n finishReason: event.finishReason ?? msg.finishReason,\n raw: {\n ...(msg.raw || {}),\n ...event,\n },\n };\n }, []);\n\n const updateLastBotEventMeta = useCallback(\n (event: Event) => {\n if (!event.modelCode && !event.usageMetadata && !event.finishReason)\n return;\n\n setMessages((prev) => {\n const next = [...prev];\n const index = next.findLastIndex((msg) => msg.role === \"bot\");\n if (index < 0) return prev;\n\n next[index] = withEventMeta(next[index], event);\n return next;\n });\n },\n [withEventMeta],\n );\n\n // 存储事件\n const storeEvents = useCallback((part: Part | null, event: any) => {\n let title = \"\";\n\n if (part == null && event.actions?.artifactDelta) {\n title += \"eventAction: artifact\";\n } else if (part) {\n if (part.text) {\n title += `text:${part.text}`;\n } else if (part.functionCall) {\n title += `functionCall:${part.functionCall.name}`;\n } else if (part.functionResponse) {\n title += `functionResponse:${part.functionResponse.name}`;\n } else if (part.executableCode) {\n title += `executableCode:${part.executableCode.code?.slice(0, 10)}`;\n } else if (part.codeExecutionResult) {\n title += `codeExecutionResult:${part.codeExecutionResult.outcome}`;\n } else if (part.errorMessage) {\n title += `errorMessage:${part.errorMessage}`;\n }\n }\n\n const updatedEvent = { ...event, title };\n\n const newEventData = new Map(eventDataRef.current);\n newEventData.set(event.id, updatedEvent);\n eventDataRef.current = newEventData;\n }, []);\n\n // 存储消息\n const storeMessage = useCallback(\n (part: Part | null, event: Event, role: \"user\" | \"bot\") => {\n if (!part || Object.keys(part).length === 0) return;\n\n const msg = buildNonTextMessage(event, part, role);\n\n // groundingMetadata 仅在前台 SSE 场景需要\n if (\n part.text &&\n event?.groundingMetadata?.searchEntryPoint?.renderedContent\n ) {\n msg.renderedContent =\n event.groundingMetadata.searchEntryPoint.renderedContent;\n }\n\n insertMessage(msg);\n },\n [insertMessage],\n );\n\n // 处理消息部分(关键更新)\n const processPart = useCallback(\n (event: Event, part: Part, ignore: boolean = false) => {\n const renderedContent =\n event.groundingMetadata?.searchEntryPoint?.renderedContent;\n if (part.text) {\n if (ignore) return;\n const newChunk = part.text;\n\n if (\n !textMsgRef.current ||\n textMsgRef.current.thought !== part.thought\n ) {\n const newMessage: IMessage = {\n id: v4(),\n author: event.author,\n invocationId: event.invocationId,\n eventId: event.id,\n timestamp: event.timestamp,\n role: \"bot\",\n text: newChunk,\n isLike: event.isLike || 0,\n thought: part.thought,\n modelCode: event.modelCode,\n usageMetadata: event.usageMetadata,\n finishReason: event.finishReason,\n raw: event,\n };\n\n if (renderedContent) {\n newMessage.renderedContent = renderedContent;\n }\n\n textMsgRef.current = newMessage;\n // 存储原数据\n storeEvents(part, event);\n // 插入消息\n insertMessage(newMessage);\n } else {\n if (renderedContent) {\n textMsgRef.current = {\n ...textMsgRef.current,\n renderedContent,\n };\n }\n textMsgRef.current = {\n ...withEventMeta(textMsgRef.current, event),\n text: (textMsgRef.current.text || \"\") + newChunk,\n };\n updateMessage(textMsgRef.current);\n if (event.partial === false) {\n storeEvents(part, event);\n textMsgRef.current = null;\n }\n }\n } else {\n textMsgRef.current = null;\n storeEvents(part, event);\n storeMessage(part, event, \"bot\");\n }\n },\n [storeEvents, storeMessage, insertMessage, updateMessage, withEventMeta],\n );\n\n // 处理建议类消息\n const processFollowupPart = useCallback(\n (event: Event) => {\n // 获取建议类消息的文本内容\n const part = event?.content?.parts?.[0] || null;\n const text = part?.text || \"\";\n storeEvents(part, event);\n if (text) {\n setSuggestedQuestions((prev) => [...prev, text]);\n }\n },\n [storeEvents],\n );\n\n // 处理错误消息\n const processErrorMessage = useCallback(\n (chunkJson: any) => {\n storeEvents(null, chunkJson);\n insertMessage({\n id: v4(),\n text: chunkJson.errorMessage,\n role: \"bot\",\n });\n },\n [storeEvents, insertMessage],\n );\n\n // 处理动作和制品\n const processActionArtifact = useCallback(\n (event: any) => {\n if (event.actions && event.actions.artifactDelta) {\n storeEvents(null, event);\n storeMessage(null, event, \"bot\");\n }\n },\n [storeEvents, storeMessage],\n );\n\n // 发送消息请求\n const sendMessageRequest = useCallback(\n (values: AgentRunRequest) => {\n return new Promise<void>((resolve) => {\n const targetSessionId = values.sessionId || currentSessionIdRef.current;\n\n // 只 abort 同一 session 的旧连接\n if (targetSessionId === currentSessionIdRef.current && ctrl.current) {\n ctrl.current.abort();\n }\n const newCtrl = new AbortController();\n if (targetSessionId === currentSessionIdRef.current) {\n setLoading(true);\n ctrl.current = newCtrl;\n }\n\n // 当 signal 被外部 abort(stopChat)时,确保外层 Promise 被 resolve\n // 否则 startChat 中的 await 会永远挂起,sendingRef 无法重置为 false\n newCtrl.signal.addEventListener(\n \"abort\",\n () => {\n resolve();\n },\n { once: true },\n );\n\n const requestUrl = `${url}/api/gateway-web/openApi/v1/aizt/app/${appNo}/sendMsgStreaming`;\n\n // 后台流式文本拼接\n let bgTextMsg: IMessage | null = null;\n\n fetchEventSource(requestUrl, {\n method: \"POST\",\n signal: newCtrl.signal,\n body: JSON.stringify(values),\n openWhenHidden: true,\n headers: {\n \"Content-Type\": \"application/json\",\n \"Cache-Control\": \"no-cache\",\n stream: \"true\",\n Authorization: `Bearer ${tokenRef.current}`,\n },\n async onopen(response) {\n if (\n response.ok &&\n response.headers.get(\"content-type\") === EventStreamContentType\n ) {\n // everything's good\n } else if (response.status === 401 || response.status === 403) {\n setLoading(false);\n onError?.({\n code: ErrorCode.AUTH_ERROR,\n message:\n response.status === 401\n ? \"认证失败,token 无效或已过期\"\n : \"无权限访问该资源\",\n });\n resolve();\n } else if (\n response.status >= 400 &&\n response.status < 500 &&\n response.status !== 429\n ) {\n resolve();\n } else {\n resolve();\n }\n },\n onmessage: (event) => {\n const rawData = safeJsonParse(event.data, {});\n\n // 处理新的数据格式: { data: {...}, result: {...} }\n let chunkJson: Event = rawData;\n if (rawData.data && rawData.result) {\n // 转换为旧格式\n chunkJson = {\n ...rawData.data,\n content: rawData.data,\n invocationId: rawData.result.invocationId,\n sessionId: rawData.result.sessionId,\n id:\n rawData.data.id ||\n rawData.result.id ||\n rawData.result.eventId ||\n rawData.result.invocationId,\n };\n }\n\n if (chunkJson.error) {\n message.warning(chunkJson.error);\n return;\n }\n\n // 判断是否为后台 session\n const isBackground =\n currentSessionIdRef.current !== targetSessionId;\n\n if (isBackground) {\n // 后台 session:更新 backgroundRef 中的消息\n const bg = backgroundRef.current.get(targetSessionId);\n if (!bg) return;\n\n if (chunkJson.content) {\n if (chunkJson.content.role === \"followup\") return;\n for (const part of combineTextParts(chunkJson.content.parts)) {\n const isPureText = part.text && !part.fileData;\n if (isPureText) {\n if (chunkJson?.partial === false) continue;\n const newChunk = part.text || \"\";\n if (!bgTextMsg || bgTextMsg?.thought !== part.thought) {\n const newMessage: IMessage = {\n id: v4(),\n author: chunkJson.author,\n invocationId: chunkJson.invocationId,\n eventId: chunkJson.id,\n timestamp: chunkJson.timestamp,\n role: \"bot\",\n text: newChunk,\n thought: part.thought,\n };\n bgTextMsg = newMessage;\n bg.messages = [...bg.messages, newMessage];\n } else {\n bgTextMsg = {\n ...bgTextMsg,\n text: (bgTextMsg.text || \"\") + newChunk,\n };\n bg.messages = bg.messages.map((m) =>\n m.id === bgTextMsg!.id ? bgTextMsg! : m,\n );\n if (chunkJson.finishReason === \"stop\") {\n bgTextMsg = null;\n }\n }\n } else {\n bgTextMsg = null;\n bg.messages = [\n ...bg.messages,\n buildNonTextMessage(chunkJson, part),\n ];\n }\n }\n } else if (chunkJson.errorMessage) {\n bg.messages = [\n ...bg.messages,\n { id: v4(), text: chunkJson.errorMessage, role: \"bot\" },\n ];\n }\n bg.textMsgRef = bgTextMsg;\n return;\n }\n\n // 前台 session:正常处理\n onStream?.(chunkJson);\n updateLastBotEventMeta(chunkJson);\n if (chunkJson.content) {\n // 建议类消息单独处理\n if (chunkJson.content.role === \"followup\") {\n processFollowupPart(chunkJson);\n return;\n }\n // eslint-disable-next-line no-restricted-syntax\n for (const part of combineTextParts(chunkJson.content.parts)) {\n // partial为 false 时忽略该条消息文本\n processPart(chunkJson, part, chunkJson?.partial === false);\n }\n } else if (chunkJson.errorMessage) {\n processErrorMessage(chunkJson);\n } else if (chunkJson.actions) {\n processActionArtifact(chunkJson);\n }\n },\n onclose: () => {\n const isBackground =\n currentSessionIdRef.current !== targetSessionId;\n if (isBackground) {\n const bg = backgroundRef.current.get(targetSessionId);\n if (bg) {\n bg.loading = false;\n bg.textMsgRef = null;\n // 标记 SSE 已完成,使恢复时 signal.aborted 能正确判断\n bg.ctrl.abort();\n }\n // 如果该后台会话已被恢复到前台(backgroundRef 中已删除),\n // 需要更新前台 loading 状态\n if (\n !backgroundRef.current.has(targetSessionId) &&\n currentSessionIdRef.current === targetSessionId\n ) {\n setLoading(false);\n textMsgRef.current = null;\n }\n } else {\n setLoading(false);\n if (textMsgRef.current) {\n onMessage?.(textMsgRef.current?.text || \"\", textMsgRef.current);\n }\n textMsgRef.current = null;\n ctrl.current = null;\n newCtrl.abort();\n }\n resolve();\n },\n onerror: (error) => {\n const isBackground =\n currentSessionIdRef.current !== targetSessionId;\n if (isBackground) {\n const bg = backgroundRef.current.get(targetSessionId);\n if (bg) {\n bg.loading = false;\n bg.ctrl.abort();\n }\n // 同上:后台会话已恢复到前台时同步 loading 状态\n if (\n !backgroundRef.current.has(targetSessionId) &&\n currentSessionIdRef.current === targetSessionId\n ) {\n setLoading(false);\n ctrl.current = null;\n }\n } else {\n setLoading(false);\n ctrl.current = null;\n newCtrl.abort();\n }\n resolve();\n console.error(\"EventSource failed:\", error);\n throw error;\n },\n });\n });\n },\n [\n processActionArtifact,\n processErrorMessage,\n processPart,\n updateLastBotEventMeta,\n ],\n );\n\n // 发送会话\n const startChat = async ({\n text = \"\",\n files = [],\n functionResponse,\n }: SendContent) => {\n if (loadingRef.current || sendingRef.current) return;\n if (!text.trim() && !files?.length && !functionResponse) return;\n sendingRef.current = true;\n // 清空建议问题\n setSuggestedQuestions([]);\n // 正常发送时重置 reChat 删除标记\n reChatRemovedInvocationIdsRef.current = new Set();\n // 发送消息\n setMessages((prev) => {\n let temp = [...prev];\n // 如果 text 存在\n if (text.trim()) {\n temp.push({\n id: v4(),\n role: \"user\",\n text,\n });\n }\n // 如果file 存在\n if (files.length > 0) {\n temp.push({\n id: v4(),\n role: \"user\",\n fileData: files.map((file) => ({\n displayName: file.fileName || file.name,\n mimeType: file.mimeType || file.response?.mimeType,\n fileUri:\n file.tempUrl || file.response?.fileUrl || file.response?.tempUrl,\n })),\n });\n }\n // 如果 functionResponse 存在\n if (functionResponse) {\n temp.push({\n id: v4(),\n role: \"user\",\n functionResponse,\n });\n }\n return temp;\n });\n try {\n await sendMessageRequest({\n stream: true,\n sessionId: currentSessionId,\n content: {\n role: \"user\",\n parts: functionResponse ? [{ functionResponse }] : [{ text }],\n },\n files: files.map((file) => ({\n fileName: file.fileName || file.response?.fileName,\n fileId: file.fileId || file.response?.fileId,\n tempUrl:\n file.tempUrl || file.response?.fileUrl || file.response?.tempUrl,\n type: file.type || file.response?.fileType,\n mimeType: file.mimeType || file.response?.mimeType,\n })),\n ...(stateDeltaRef.current !== undefined && {\n stateDelta: stateDeltaRef.current,\n }),\n });\n } finally {\n sendingRef.current = false;\n }\n // 获取聊天记录\n initAppConversations();\n };\n\n // 重新发送会话\n const reChat = async () => {\n if (loadingRef.current || sendingRef.current) return;\n if (messages.length === 0) return;\n sendingRef.current = true;\n // 清空建议问题\n setSuggestedQuestions([]);\n\n // 找到最后一条用户消息的索引,删除其后所有 bot 消息\n const lastUserIndex = messages.findLastIndex(\n (msg) => msg.role === \"user\" && !msg.functionResponse,\n );\n if (lastUserIndex === -1) {\n sendingRef.current = false;\n return;\n }\n\n const newMessages = messages.slice(0, lastUserIndex + 1);\n setMessages(newMessages);\n\n // 收集被截断的 bot 消息的 invocationId,轮询时忽略这些旧回复\n const removedInvocationIds = new Set<string>();\n for (let i = lastUserIndex + 1; i < messages.length; i++) {\n const msg = messages[i];\n if (msg.invocationId) removedInvocationIds.add(msg.invocationId);\n }\n reChatRemovedInvocationIdsRef.current = removedInvocationIds;\n\n const lastUserMessage = newMessages[lastUserIndex];\n const { text = \"\", fileData = [] } = lastUserMessage;\n\n try {\n await sendMessageRequest({\n stream: true,\n sessionId: currentSessionId,\n content: {\n role: \"user\",\n parts: [{ text }],\n },\n files: fileData?.map((file) => ({\n fileName: file.displayName,\n tempUrl: file.fileUri,\n mimeType: file.mimeType,\n })),\n ...(stateDeltaRef.current !== undefined && {\n stateDelta: stateDeltaRef.current,\n }),\n });\n } finally {\n sendingRef.current = false;\n }\n };\n\n // 确认函数调用\n const confirmFnCall = (fnCall: FunctionCall, confirmed: boolean) => {\n const functionResponse = strategies?.createFunctionResponse?.(\n fnCall,\n confirmed,\n ) ?? {\n id: fnCall.id,\n name: fnCall.name,\n response: { confirmed },\n };\n startChat({ functionResponse });\n };\n\n // 使用建议问题\n const suggestChat = (text: string) => {\n if (loadingRef.current) return;\n if (!text.trim()) return;\n setSuggestedQuestions([]);\n startChat({ text });\n };\n\n // 停止会话(只中断前台连接)\n const stopChat = useCallback(() => {\n pendingSessionEventsRef.current = null;\n ctrl.current?.abort();\n ctrl.current = null;\n setLoading(false);\n textMsgRef.current = null;\n }, [setLoading]);\n\n // 清除/重置会话\n const clearChat = () => {\n const newSessionId = v4();\n setCurrentSessionId(newSessionId);\n // 清除 reChat 删除标记\n reChatRemovedInvocationIdsRef.current = new Set();\n // 重置聊天内容\n stopChat();\n setPrologue(appInfo?.onboardingInfo?.prologue || \"\");\n setMessages([]);\n setSuggestedQuestions(appInfo?.onboardingInfo?.suggested_questions || []);\n };\n\n // 格式化会话记录\n const formatMessages = useCallback(\n (sessionEvents: any[], isReplace = false) => {\n const mapped = mapSessionMessages(sessionEvents);\n setMessages((prev) => (isReplace ? mapped : [...prev, ...mapped]));\n },\n [],\n );\n\n // 设置当前会话详情\n const setCurrentSession = async (sessionId: string) => {\n if (sessionId) {\n if (sessionId === currentSessionId) {\n return;\n }\n\n pendingSessionEventsRef.current = null;\n // 切换会话时重置 reChat 删除标记\n reChatRemovedInvocationIdsRef.current = new Set();\n\n // 1. 将当前会话挂起到后台(不中断 SSE 连接)\n const prevSessionId = currentSessionId;\n if (ctrl.current) {\n // 有活跃流式连接,保存到后台\n backgroundRef.current.set(prevSessionId, {\n ctrl: ctrl.current,\n messages: [...messagesRef.current],\n loading: true,\n textMsgRef: textMsgRef.current,\n });\n ctrl.current = null;\n textMsgRef.current = null;\n setLoading(false);\n } else if (messagesRef.current.length > 0) {\n // 无活跃连接但有消息,缓存用于切回\n const dummyCtrl = new AbortController();\n dummyCtrl.abort(); // 标记为已完成\n backgroundRef.current.set(prevSessionId, {\n ctrl: dummyCtrl,\n messages: [...messagesRef.current],\n loading: false,\n textMsgRef: null,\n });\n }\n\n // 2. 尝试从后台恢复目标会话\n const bg = backgroundRef.current.get(sessionId);\n if (bg) {\n setMessages(bg.messages);\n messagesRef.current = bg.messages;\n textMsgRef.current = bg.textMsgRef;\n // 仅当 SSE 连接还在运行时才恢复 loading 状态,\n // 避免 SSE 已关闭但 bg 快照中 loading 仍为 true 导致 sender 永久卡住\n const isSseStillActive = bg.loading && !bg.ctrl.signal.aborted;\n setLoading(isSseStillActive);\n ctrl.current = isSseStillActive ? bg.ctrl : null;\n setCurrentSessionId(sessionId);\n setInitialized(true);\n backgroundRef.current.delete(sessionId);\n return;\n }\n\n // 3. 后台没有目标 session,走 API 加载(原有逻辑)\n setInitialized(false);\n setCurrentSessionId(sessionId);\n sessionDetailLoadingRef.current = true;\n try {\n const { data, result } = await fetchSessionDetail({\n url,\n appNo,\n sessionId,\n token: tokenRef.current,\n });\n\n if (result?.code === API_SUCCESS_CODE) {\n setPrologue(appInfo?.onboardingInfo?.prologue || \"\");\n if (Array.isArray(data) && data.length > 0) {\n formatMessages(data, true);\n } else {\n setSuggestedQuestions(\n appInfo?.onboardingInfo?.suggested_questions || [],\n );\n }\n }\n } finally {\n sessionDetailLoadingRef.current = false;\n setInitialized(true);\n }\n } else {\n setCurrentSessionId(v4());\n }\n };\n\n // 获取聊天记录\n const initAppConversations = async (fetchDetail = false) => {\n try {\n setSessionLoading(true);\n\n const {\n data = [],\n pagination,\n result,\n } = await fetchSessionList({\n url,\n appNo,\n token: tokenRef.current,\n pageSize: sessionPagination.pageSize,\n });\n\n if (result?.code === API_SUCCESS_CODE) {\n if (data.length > 0) {\n const formatSessions = data.map((item) => {\n return {\n key: item.sessionId,\n label: item.title || \"新对话\",\n timestamp: new Date(item.startTime).getTime(),\n messages: [],\n meta: {\n ...item,\n },\n };\n });\n\n setSessionList(formatSessions);\n // 设置分页信息\n setSessionPagination({\n pageNum: sessionPagination.pageNum,\n pageSize: sessionPagination.pageSize,\n total: pagination?.total || 0,\n });\n const { sessionId } = data?.[0];\n if (showFirstSession) {\n setCurrentSession(sessionId);\n } else {\n fetchDetail && setPrologue(appInfo?.onboardingInfo?.prologue || \"\");\n fetchDetail &&\n setSuggestedQuestions(\n appInfo?.onboardingInfo?.suggested_questions || [],\n );\n }\n // 成功回调\n if (!initialized) {\n onSuccess?.({\n code: SuccessCode.APP_MESSAGES_INIT_SUCCESS,\n message: \"初始化聊天记录成功\",\n data: {\n sessionId,\n },\n });\n setInitialized(true);\n }\n } else {\n // 无会话记录时,初始化会话详情\n clearChat();\n }\n } else {\n // 服务端业务错误,透传原始 code + message 给接入方自行处理\n onError?.({\n code: result?.code || \"UNKNOWN_ERROR\",\n message: result?.message || \"获取会话列表失败\",\n raw: result,\n });\n setSessionList([]);\n setCurrentSessionId(v4());\n setPrologue(\"\");\n setSuggestedQuestions([]);\n }\n } catch {\n onError?.({\n code: ErrorCode.NETWORK_ERROR,\n message: \"获取会话列表失败\",\n });\n } finally {\n setSessionLoading(false);\n }\n };\n\n // 删除会话\n const deleteSession = async (sessionId: string) => {\n if (!sessionId) return;\n const { result } = await closeSession({\n url,\n appNo,\n sessionId,\n token: tokenRef.current,\n });\n if (result?.code === API_SUCCESS_CODE) {\n // 删除成功后,重新获取会话列表\n initAppConversations(true);\n // 如果删除的是当前会话,则创建新的会话\n if (sessionId === currentSessionId) {\n clearChat();\n }\n } else {\n message.error(\"删除会话失败\");\n }\n };\n\n // 点赞/点踩\n const likeMessage = async (\n invocationId: string,\n isLike: 1 | -1,\n feedbackData?: { feedbackTags?: string; feedbackDescription?: string },\n ) => {\n if (!appNo || !invocationId) return false;\n const { result } = await addFeedback({\n url,\n appNo,\n token: tokenRef.current,\n requestId: invocationId,\n isLike,\n ...feedbackData,\n });\n if (result?.code === API_SUCCESS_CODE) {\n setMessages((prev) =>\n prev.map((m) =>\n m.invocationId === invocationId ? { ...m, isLike } : m,\n ),\n );\n return true;\n }\n return false;\n };\n\n // 更新会话名称\n const updateSession = async (sessionId: string, title: string) => {\n if (!sessionId || !title) return;\n const { result } = await updateSessionTitle({\n url,\n appNo,\n title,\n sessionId,\n token: tokenRef.current,\n });\n if (result?.code === API_SUCCESS_CODE) {\n // 编辑成功后,重新获取会话列表\n initAppConversations();\n } else {\n message.error(\"更新会话失败\");\n }\n };\n\n // 初始化应用\n const initConfig = async () => {\n try {\n setSessionLoading(true);\n const { data, result } = await fetchAppConfig({ url, appNo });\n if (result.code === API_SUCCESS_CODE) {\n setAppInfo(data);\n // 成功回调\n onSuccess?.({\n code: SuccessCode.APP_CONFIG_INIT_SUCCESS,\n message: \"初始化配置成功\",\n });\n } else {\n // 服务端业务错误,透传原始 code + message\n onError?.({\n code: result.code || \"UNKNOWN_ERROR\",\n message: result.message || \"获取应用配置失败\",\n raw: result,\n });\n }\n } catch (error) {\n onError?.({\n code: ErrorCode.NETWORK_ERROR,\n message: \"获取应用配置失败\",\n });\n } finally {\n setSessionLoading(false);\n }\n };\n\n // 初始化—获取配置 (仅在启用时)\n useEffect(() => {\n if (enabled && url && appNo) {\n initConfig();\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [enabled, url, appNo]);\n\n // 初始化-聊天记录\n useEffect(() => {\n if (appInfo) {\n initAppConversations(true);\n }\n }, [appInfo]);\n\n // 轮询当前会话详情,空闲时补入后端异步任务产生的模型消息。\n useEffect(() => {\n if (\n !enabled ||\n !initialized ||\n !pollSessionEvents ||\n !appNo ||\n !currentSessionId\n )\n return;\n\n let disposed = false;\n let requesting = false;\n const pollingSessionId = currentSessionId;\n\n const poll = async () => {\n if (disposed || requesting || sessionDetailLoadingRef.current) return;\n requesting = true;\n try {\n const { data, result } = await fetchSessionDetail({\n url,\n appNo,\n sessionId: pollingSessionId,\n token: tokenRef.current,\n });\n if (\n !disposed &&\n result?.code === API_SUCCESS_CODE &&\n Array.isArray(data)\n ) {\n syncSessionEvents(data, pollingSessionId);\n }\n } catch {\n // 新会话尚未落库或短暂网络异常时等待下一轮,不打断当前聊天。\n } finally {\n requesting = false;\n }\n };\n\n // 不立即执行首次 poll,避免与 initAppConversations / setCurrentSession / fetchSessionDetail 竞争。首次数据由初始化流程加载,轮询仅负责后续增量同步。\n const timer = window.setInterval(poll, sessionEventsPollingInterval);\n return () => {\n disposed = true;\n window.clearInterval(timer);\n };\n }, [\n appNo,\n currentSessionId,\n enabled,\n initialized,\n pollSessionEvents,\n sessionEventsPollingInterval,\n syncSessionEvents,\n url,\n ]);\n\n // 组件卸载时清理所有连接(前台 + 后台)\n useEffect(() => {\n return () => {\n ctrl.current?.abort();\n backgroundRef.current.forEach((bg) => bg.ctrl?.abort());\n backgroundRef.current.clear();\n };\n }, []);\n\n return {\n appInfo,\n startChat,\n reChat,\n stopChat,\n clearChat,\n suggestChat,\n confirmFnCall,\n initialized,\n currentSessionId,\n sessionList,\n sessionPagination,\n prologue,\n suggestions: suggestedQuestions,\n loading,\n sessionLoading,\n messages: mergedMessages,\n insertSuggestedQuestions,\n insertPrologue,\n deleteSession,\n updateSession,\n setSuggestedQuestions,\n setCurrentSession,\n setMessages,\n storeEvents,\n storeMessage,\n likeMessage,\n setStateDelta: (delta: Record<string, any> | undefined) => {\n stateDeltaRef.current = delta;\n },\n };\n}\n\nexport default useADKChat;\n"],
5
+ "mappings": "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",
6
6
  "names": ["_a", "_b"]
7
7
  }
@@ -1,5 +1,5 @@
1
1
  import React, { ReactNode, RefObject, MouseEvent, ReactElement } from 'react';
2
- import type { PromptsItemType } from '@ant-design/x';
2
+ import type { PromptsItemType } from './antdx';
3
3
  import type { MessageType } from '../client/base';
4
4
  import type { UploadProps } from 'antd';
5
5
  import type { Messages } from './XAiMessage';
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/types/XAiChatbot.ts"],
4
- "sourcesContent": ["import React, { ReactNode, RefObject, MouseEvent, ReactElement } from 'react';\nimport type { PromptsItemType } from '@ant-design/x';\nimport type { MessageType } from '../client/base';\nimport type { UploadProps } from 'antd';\nimport type { Messages } from './XAiMessage';\nimport type { SendContent } from './XAiSender';\n\n// 类型定义\nexport interface User {\n id: string;\n name: string;\n avatar?: string;\n }\n\nexport interface MessageProps {\n _id: string;\n type: string;\n content: Record<string, any>;\n createdAt: number;\n user: User;\n position?: 'left' | 'right' | 'center' | 'pop';\n hasTime?: boolean;\n status?: 'pending' | 'sent' | 'fail';\n }\n\nexport interface QuickReplyItemProps {\n name: string;\n code: string;\n icon?: string;\n img?: string;\n isNew?: boolean;\n isHighlight?: boolean;\n }\n\nexport interface ComposerHandle {\n setText: (text: string) => void;\n }\n\nexport interface ScrollToEndOptions {\n animated?: boolean;\n force?: boolean;\n }\n\nexport interface MessageContainerHandle {\n scrollToEnd: (options?: ScrollToEndOptions) => void;\n }\n\nexport interface NavbarProps {\n title?: string;\n subtitle?: string;\n avatar?: string;\n}\n\nexport interface ToolbarItemProps {\n id: string;\n icon: string;\n label: string;\n disabled?: boolean;\n }\n\nexport interface IconButtonProps {\n icon: string;\n onClick: () => void;\n disabled?: boolean;\n }\n\nexport interface RecorderProps {\n onStart?: () => void;\n onStop?: (audioBlob: Blob) => void;\n onError?: (error: Error) => void;\n }\n\nexport type InputType = 'text' | 'voice';\n\n// chatbot 会话字段\nexport interface ChatbotMessageFields {\n messages?: MessageType[];\n setMessages?: React.Dispatch<React.SetStateAction<MessageType[]>>;\n /** 发送消息回调 */\n onSend?: (content: SendContent) => void;\n /** 清空消息回调 */\n onClear?: () => void;\n /** 停止生成回调 */\n onStop?: () => void;\n}\n\nexport interface ActionItem {\n key?: string;\n icon?: React.ReactNode;\n render?: (index: number, msg: any) => React.ReactNode;\n tooltip?: string;\n}\n\n/**\n * AI 聊天机器人组件\n */\nexport interface XAiChatbotProps extends ChatbotMessageFields {\n /** 宽屏断点 */\n wideBreakpoint?: string;\n /** 导航栏展示 */\n navbarShow?: boolean;\n /** 导航栏配置 */\n navbar?: NavbarProps;\n /** 导航栏渲染函数,会覆盖 navbar */\n renderNavbar?: () => ReactNode;\n /** 是否加载中 */\n loading?: boolean;\n /** 加载更多文案 */\n loadMoreText?: string;\n /** 在消息列表上面的渲染函数 */\n renderBeforeMessageList?: () => ReactNode;\n /** 消息列表 ref */\n messagesRef?: RefObject<MessageContainerHandle>;\n /** 下拉加载回调 */\n onRefresh?: () => Promise<any>;\n /** 滚动消息列表回调 */\n onScroll?: (event: React.UIEvent<HTMLDivElement, UIEvent>) => void;\n /** 消息内容渲染函数 */\n renderMessageContent?: (message: MessageProps) => ReactNode;\n /** 快捷短语列表 */\n quickReplies?: QuickReplyItemProps[];\n /** 快捷短语是否可见 */\n quickRepliesVisible?: boolean;\n // /** 点击快速回复回调 */\n // onQuickReplyClick?: (item: QuickReplyItemProps, index: number) => void;\n // /** 快捷短语的滚动回调 */\n // onQuickReplyScroll?: () => void;\n // /** 快捷短语渲染函数,会覆盖 quickReplies */\n // renderQuickReplies?: () => ReactNode;\n /** 输入框初始内容 */\n text?: string;\n /** 空状态渲染插槽 */\n empty?: ReactElement;\n /** 空状态图片 */\n emptyStateImage?: string;\n /** 空状态文案 */\n emptyStateText?: string;\n /** 输入框占位符 */\n placeholder?: string;\n /** 输入方式 */\n inputType?: InputType;\n // /** 输入方式切换回调 */\n // onInputTypeChange?: (inputType: InputType) => void;\n /** 语音输入配置 */\n recorder?: RecorderProps;\n /** 工具栏配置 */\n toolbar?: ToolbarItemProps[];\n /** AI头像 */\n avatar?: ReactNode;\n /** 用户头像 */\n userAvatar?: ReactNode;\n /** 发送按钮 */\n sendBtn?: ReactNode;\n /** 是否展示清空按钮 */\n clearBtnShow? : boolean;\n /** 工具栏点击回调 */\n onToolbarClick?: (item: ToolbarItemProps, event: MouseEvent) => void;\n /** 工具栏打开/关闭回调 */\n onAccessoryToggle?: (isAccessoryOpen: boolean) => void;\n /** 输入框右边图标按钮配置 */\n rightAction?: IconButtonProps;\n /** 底部文案 */\n footerTips?: string;\n /** 帮助消息点击回调 */\n onSuggestMessageClick?: (item: PromptsItemType, id: string) => void;\n /** 消息左下角展示字段 */\n messageTooltip?: (msg: Messages) => React.ReactNode;\n /** 消息右下角功能区 */\n messageActions?: ActionItem[];\n /** 消息右下角功能区点击回调 */\n onMessagesActionsCallback?: (index: number, data: Messages) => void; // 点击回调\n /** 输入组件 */\n Composer?: React.ElementType;\n /** 是否展示输入框 */\n inputShow?: boolean;\n /** 多个chatbot唯一键 */\n providerId?: string;\n /** 消息顶部 */\n messageTop?: ReactNode;\n enableUpload?: boolean;\n uploadRequest?: UploadProps['customRequest'];\n }\n"],
4
+ "sourcesContent": ["import React, { ReactNode, RefObject, MouseEvent, ReactElement } from 'react';\nimport type { PromptsItemType } from './antdx';\nimport type { MessageType } from '../client/base';\nimport type { UploadProps } from 'antd';\nimport type { Messages } from './XAiMessage';\nimport type { SendContent } from './XAiSender';\n\n// 类型定义\nexport interface User {\n id: string;\n name: string;\n avatar?: string;\n }\n\nexport interface MessageProps {\n _id: string;\n type: string;\n content: Record<string, any>;\n createdAt: number;\n user: User;\n position?: 'left' | 'right' | 'center' | 'pop';\n hasTime?: boolean;\n status?: 'pending' | 'sent' | 'fail';\n }\n\nexport interface QuickReplyItemProps {\n name: string;\n code: string;\n icon?: string;\n img?: string;\n isNew?: boolean;\n isHighlight?: boolean;\n }\n\nexport interface ComposerHandle {\n setText: (text: string) => void;\n }\n\nexport interface ScrollToEndOptions {\n animated?: boolean;\n force?: boolean;\n }\n\nexport interface MessageContainerHandle {\n scrollToEnd: (options?: ScrollToEndOptions) => void;\n }\n\nexport interface NavbarProps {\n title?: string;\n subtitle?: string;\n avatar?: string;\n}\n\nexport interface ToolbarItemProps {\n id: string;\n icon: string;\n label: string;\n disabled?: boolean;\n }\n\nexport interface IconButtonProps {\n icon: string;\n onClick: () => void;\n disabled?: boolean;\n }\n\nexport interface RecorderProps {\n onStart?: () => void;\n onStop?: (audioBlob: Blob) => void;\n onError?: (error: Error) => void;\n }\n\nexport type InputType = 'text' | 'voice';\n\n// chatbot 会话字段\nexport interface ChatbotMessageFields {\n messages?: MessageType[];\n setMessages?: React.Dispatch<React.SetStateAction<MessageType[]>>;\n /** 发送消息回调 */\n onSend?: (content: SendContent) => void;\n /** 清空消息回调 */\n onClear?: () => void;\n /** 停止生成回调 */\n onStop?: () => void;\n}\n\nexport interface ActionItem {\n key?: string;\n icon?: React.ReactNode;\n render?: (index: number, msg: any) => React.ReactNode;\n tooltip?: string;\n}\n\n/**\n * AI 聊天机器人组件\n */\nexport interface XAiChatbotProps extends ChatbotMessageFields {\n /** 宽屏断点 */\n wideBreakpoint?: string;\n /** 导航栏展示 */\n navbarShow?: boolean;\n /** 导航栏配置 */\n navbar?: NavbarProps;\n /** 导航栏渲染函数,会覆盖 navbar */\n renderNavbar?: () => ReactNode;\n /** 是否加载中 */\n loading?: boolean;\n /** 加载更多文案 */\n loadMoreText?: string;\n /** 在消息列表上面的渲染函数 */\n renderBeforeMessageList?: () => ReactNode;\n /** 消息列表 ref */\n messagesRef?: RefObject<MessageContainerHandle>;\n /** 下拉加载回调 */\n onRefresh?: () => Promise<any>;\n /** 滚动消息列表回调 */\n onScroll?: (event: React.UIEvent<HTMLDivElement, UIEvent>) => void;\n /** 消息内容渲染函数 */\n renderMessageContent?: (message: MessageProps) => ReactNode;\n /** 快捷短语列表 */\n quickReplies?: QuickReplyItemProps[];\n /** 快捷短语是否可见 */\n quickRepliesVisible?: boolean;\n // /** 点击快速回复回调 */\n // onQuickReplyClick?: (item: QuickReplyItemProps, index: number) => void;\n // /** 快捷短语的滚动回调 */\n // onQuickReplyScroll?: () => void;\n // /** 快捷短语渲染函数,会覆盖 quickReplies */\n // renderQuickReplies?: () => ReactNode;\n /** 输入框初始内容 */\n text?: string;\n /** 空状态渲染插槽 */\n empty?: ReactElement;\n /** 空状态图片 */\n emptyStateImage?: string;\n /** 空状态文案 */\n emptyStateText?: string;\n /** 输入框占位符 */\n placeholder?: string;\n /** 输入方式 */\n inputType?: InputType;\n // /** 输入方式切换回调 */\n // onInputTypeChange?: (inputType: InputType) => void;\n /** 语音输入配置 */\n recorder?: RecorderProps;\n /** 工具栏配置 */\n toolbar?: ToolbarItemProps[];\n /** AI头像 */\n avatar?: ReactNode;\n /** 用户头像 */\n userAvatar?: ReactNode;\n /** 发送按钮 */\n sendBtn?: ReactNode;\n /** 是否展示清空按钮 */\n clearBtnShow? : boolean;\n /** 工具栏点击回调 */\n onToolbarClick?: (item: ToolbarItemProps, event: MouseEvent) => void;\n /** 工具栏打开/关闭回调 */\n onAccessoryToggle?: (isAccessoryOpen: boolean) => void;\n /** 输入框右边图标按钮配置 */\n rightAction?: IconButtonProps;\n /** 底部文案 */\n footerTips?: string;\n /** 帮助消息点击回调 */\n onSuggestMessageClick?: (item: PromptsItemType, id: string) => void;\n /** 消息左下角展示字段 */\n messageTooltip?: (msg: Messages) => React.ReactNode;\n /** 消息右下角功能区 */\n messageActions?: ActionItem[];\n /** 消息右下角功能区点击回调 */\n onMessagesActionsCallback?: (index: number, data: Messages) => void; // 点击回调\n /** 输入组件 */\n Composer?: React.ElementType;\n /** 是否展示输入框 */\n inputShow?: boolean;\n /** 多个chatbot唯一键 */\n providerId?: string;\n /** 消息顶部 */\n messageTop?: ReactNode;\n enableUpload?: boolean;\n uploadRequest?: UploadProps['customRequest'];\n }\n"],
5
5
  "mappings": ";;;;;;;;;;;;;;;AAAA;AAAA;",
6
6
  "names": []
7
7
  }
@@ -1,4 +1,4 @@
1
- import { type ConversationsProps, type ConversationItemType } from "@ant-design/x";
1
+ import { type ConversationsProps, type ConversationItemType } from "./antdx";
2
2
  import React from "react";
3
3
  type OmitItems = Omit<ConversationsProps, "items" | "style">;
4
4
  export interface SessionData extends ConversationItemType {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/types/XAiConversations.ts"],
4
- "sourcesContent": ["import {\n type ConversationsProps,\n type ConversationItemType,\n} from \"@ant-design/x\";\nimport React from \"react\";\n\ntype OmitItems = Omit<ConversationsProps, \"items\" | \"style\">;\n\nexport interface SessionData extends ConversationItemType {\n meta?: any;\n}\n\nexport interface XAiConversationsProps extends OmitItems {\n /** 配色 */\n color?: string;\n /** 侧边栏展示形式,若为 true 则为抽屉式展示 */\n isNarrow?: boolean;\n /** 会话列表,替换原来的 items 字段 */\n sessionList?: SessionData[];\n /** session总数,当设置该值时,会增加自动加载逻辑 */\n sessionTotal?: number;\n /** 加载更多函数 */\n loadMoreSession?: () => void;\n /** 点击生成新对话回调 */\n onNewChat?: () => void;\n style?: React.CSSProperties;\n}\n"],
4
+ "sourcesContent": ["import {\n type ConversationsProps,\n type ConversationItemType,\n} from \"./antdx\";\nimport React from \"react\";\n\ntype OmitItems = Omit<ConversationsProps, \"items\" | \"style\">;\n\nexport interface SessionData extends ConversationItemType {\n meta?: any;\n}\n\nexport interface XAiConversationsProps extends OmitItems {\n /** 配色 */\n color?: string;\n /** 侧边栏展示形式,若为 true 则为抽屉式展示 */\n isNarrow?: boolean;\n /** 会话列表,替换原来的 items 字段 */\n sessionList?: SessionData[];\n /** session总数,当设置该值时,会增加自动加载逻辑 */\n sessionTotal?: number;\n /** 加载更多函数 */\n loadMoreSession?: () => void;\n /** 点击生成新对话回调 */\n onNewChat?: () => void;\n style?: React.CSSProperties;\n}\n"],
5
5
  "mappings": ";;;;;;;;;;;;;;;AAAA;AAAA;",
6
6
  "names": []
7
7
  }
@@ -1,4 +1,4 @@
1
- import type { PromptsProps } from '@ant-design/x';
1
+ import type { PromptsProps } from './antdx';
2
2
  export type MessageType = 'TextMessage' | 'ActionExecutionMessage' | 'ResultMessage' | 'AgentStateMessage' | 'SuggestionMessage';
3
3
  export declare enum MessageRole {
4
4
  user = "user",// 用户
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/types/XAiMessage.ts"],
4
- "sourcesContent": ["import type { PromptsProps } from '@ant-design/x';\n\nexport type MessageType =\n| 'TextMessage'\n| 'ActionExecutionMessage'\n| 'ResultMessage'\n| 'AgentStateMessage'\n| 'SuggestionMessage';\n\nexport enum MessageRole {\n user = 'user', // 用户\n assistant = 'assistant', // AI助手\n suggestion = 'suggestion', // 建议\n system = 'system', // 工具\n}\n\nexport enum MessageStatus {\n init = 'init',\n pending = 'pending', // 生成中/接收中\n done = 'done', // 已完成\n failed = 'failed', // 失败\n recalled = 'recalled', // 已撤回\n deleted = 'deleted', // 已删除\n}\n\n/**\n * 阶段性回答内容\n */\nexport interface Steps {\n id: string; // 阶段性回答ID\n content: any; // 文本内容\n}\n\n/**\n* 所有消息的基础结构\n*/\nexport interface BaseMessage {\n id: string; // 消息唯一ID\n type: MessageType; // 消息类型\n createdAt: Date; // 创建时间\n status?: MessageStatus; // 内容是否生成中\n execute?: ActionExecutionMessage[]; // 智能体执行过程\n stepContent?: Steps[]; // 阶段性回答内容\n thinks?: string ; // 思考过程\n extra?: any; // 额外消息\n isLike?: 0 | 1 | -1; // 是否喜欢\n raw?: any; // 原始消息\n}\n\nexport interface FileMessage {\n fileId?: string | number; // 文件ID\n fileName?: string; // 文件名\n fileSize?: number | string; // 文件大小(字节)\n fileType?: string; // 文件类型(MIME类型)\n fileUrl?: string; // 文件URL(可选,用于展示/下载)\n}\n\n/**\n* 文本消息\n*/\nexport interface TextMessage extends BaseMessage {\n type: 'TextMessage';\n role: MessageRole; // 发送者角色\n content: {\n text?: string; // 文本内容\n files?: FileMessage[]; // 文件列表\n };\n parentMessageId?: string; // 父消息ID(可选)\n}\n\n/**\n* 工具/动作执行消息\n*/\nexport interface ActionExecutionMessage extends BaseMessage {\n type: 'ActionExecutionMessage';\n name: string; // 动作/工具名称\n arguments?: Record<string, any>; // 执行参数\n parentMessageId?: string;\n extra?: any; // 额外信息\n}\n\n/**\n* 工具/动作执行结果消息\n*/\nexport interface ResultMessage extends BaseMessage {\n type: 'ResultMessage';\n actionExecutionId: string; // 执行ID\n actionName: string; // 动作/工具名称\n result: string; // 执行结果\n}\n\n/**\n* 智能体状态消息\n*/\nexport interface AgentStateMessage extends BaseMessage {\n type: 'AgentStateMessage';\n threadId: string; // 线程ID\n agentName: string; // agent名称\n nodeName: string; // 节点名称\n runId: string; // 运行ID\n active: boolean; // 是否激活\n role: MessageRole; // 角色\n state: any; // 状态内容\n running: boolean; // 是否运行中\n}\n\n/**\n * 提示消息\n */\nexport interface SuggestionMessage extends BaseMessage {\n type: 'SuggestionMessage';\n content: PromptsProps['items'];\n role: MessageRole;\n}\n\n/**\n* 消息输入类型(用于前端输入/组装)\n* 可选地包含不同类型的消息体\n*/\nexport interface MessageInput extends BaseMessage {\n textMessage?: Omit<TextMessage, 'id' | 'createdAt' | 'type'>;\n actionExecutionMessage?: Omit<ActionExecutionMessage, 'id' | 'createdAt' | 'type'>;\n resultMessage?: Omit<ResultMessage, 'id' | 'createdAt' | 'type'>;\n agentStateMessage?: Omit<AgentStateMessage, 'id' | 'createdAt' | 'type'>;\n}\n\n/**\n* 消息列表中消息格式\n*/\nexport type Messages = TextMessage | SuggestionMessage;\n\nexport enum ActionAvailability {\n disabled = 'disabled', // 不可用\n enabled = 'enabled', // 可用\n remote = 'remote', // 远程可用\n}\n\n/**\n* 工具/动作定义\n*/\nexport interface Action {\n name: string; // 名称\n description: string; // 描述\n jsonSchema: string; // 参数JSON Schema\n available?: ActionAvailability; // 可用性\n}\n"],
4
+ "sourcesContent": ["import type { PromptsProps } from './antdx';\n\nexport type MessageType =\n| 'TextMessage'\n| 'ActionExecutionMessage'\n| 'ResultMessage'\n| 'AgentStateMessage'\n| 'SuggestionMessage';\n\nexport enum MessageRole {\n user = 'user', // 用户\n assistant = 'assistant', // AI助手\n suggestion = 'suggestion', // 建议\n system = 'system', // 工具\n}\n\nexport enum MessageStatus {\n init = 'init',\n pending = 'pending', // 生成中/接收中\n done = 'done', // 已完成\n failed = 'failed', // 失败\n recalled = 'recalled', // 已撤回\n deleted = 'deleted', // 已删除\n}\n\n/**\n * 阶段性回答内容\n */\nexport interface Steps {\n id: string; // 阶段性回答ID\n content: any; // 文本内容\n}\n\n/**\n* 所有消息的基础结构\n*/\nexport interface BaseMessage {\n id: string; // 消息唯一ID\n type: MessageType; // 消息类型\n createdAt: Date; // 创建时间\n status?: MessageStatus; // 内容是否生成中\n execute?: ActionExecutionMessage[]; // 智能体执行过程\n stepContent?: Steps[]; // 阶段性回答内容\n thinks?: string ; // 思考过程\n extra?: any; // 额外消息\n isLike?: 0 | 1 | -1; // 是否喜欢\n raw?: any; // 原始消息\n}\n\nexport interface FileMessage {\n fileId?: string | number; // 文件ID\n fileName?: string; // 文件名\n fileSize?: number | string; // 文件大小(字节)\n fileType?: string; // 文件类型(MIME类型)\n fileUrl?: string; // 文件URL(可选,用于展示/下载)\n}\n\n/**\n* 文本消息\n*/\nexport interface TextMessage extends BaseMessage {\n type: 'TextMessage';\n role: MessageRole; // 发送者角色\n content: {\n text?: string; // 文本内容\n files?: FileMessage[]; // 文件列表\n };\n parentMessageId?: string; // 父消息ID(可选)\n}\n\n/**\n* 工具/动作执行消息\n*/\nexport interface ActionExecutionMessage extends BaseMessage {\n type: 'ActionExecutionMessage';\n name: string; // 动作/工具名称\n arguments?: Record<string, any>; // 执行参数\n parentMessageId?: string;\n extra?: any; // 额外信息\n}\n\n/**\n* 工具/动作执行结果消息\n*/\nexport interface ResultMessage extends BaseMessage {\n type: 'ResultMessage';\n actionExecutionId: string; // 执行ID\n actionName: string; // 动作/工具名称\n result: string; // 执行结果\n}\n\n/**\n* 智能体状态消息\n*/\nexport interface AgentStateMessage extends BaseMessage {\n type: 'AgentStateMessage';\n threadId: string; // 线程ID\n agentName: string; // agent名称\n nodeName: string; // 节点名称\n runId: string; // 运行ID\n active: boolean; // 是否激活\n role: MessageRole; // 角色\n state: any; // 状态内容\n running: boolean; // 是否运行中\n}\n\n/**\n * 提示消息\n */\nexport interface SuggestionMessage extends BaseMessage {\n type: 'SuggestionMessage';\n content: PromptsProps['items'];\n role: MessageRole;\n}\n\n/**\n* 消息输入类型(用于前端输入/组装)\n* 可选地包含不同类型的消息体\n*/\nexport interface MessageInput extends BaseMessage {\n textMessage?: Omit<TextMessage, 'id' | 'createdAt' | 'type'>;\n actionExecutionMessage?: Omit<ActionExecutionMessage, 'id' | 'createdAt' | 'type'>;\n resultMessage?: Omit<ResultMessage, 'id' | 'createdAt' | 'type'>;\n agentStateMessage?: Omit<AgentStateMessage, 'id' | 'createdAt' | 'type'>;\n}\n\n/**\n* 消息列表中消息格式\n*/\nexport type Messages = TextMessage | SuggestionMessage;\n\nexport enum ActionAvailability {\n disabled = 'disabled', // 不可用\n enabled = 'enabled', // 可用\n remote = 'remote', // 远程可用\n}\n\n/**\n* 工具/动作定义\n*/\nexport interface Action {\n name: string; // 名称\n description: string; // 描述\n jsonSchema: string; // 参数JSON Schema\n available?: ActionAvailability; // 可用性\n}\n"],
5
5
  "mappings": ";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AASO,IAAK,cAAL,kBAAKA,iBAAL;AACL,EAAAA,aAAA,UAAO;AACP,EAAAA,aAAA,eAAY;AACZ,EAAAA,aAAA,gBAAa;AACb,EAAAA,aAAA,YAAS;AAJC,SAAAA;AAAA,GAAA;AAOL,IAAK,gBAAL,kBAAKC,mBAAL;AACL,EAAAA,eAAA,UAAO;AACP,EAAAA,eAAA,aAAU;AACV,EAAAA,eAAA,UAAO;AACP,EAAAA,eAAA,YAAS;AACT,EAAAA,eAAA,cAAW;AACX,EAAAA,eAAA,aAAU;AANA,SAAAA;AAAA,GAAA;AAmHL,IAAK,qBAAL,kBAAKC,wBAAL;AACL,EAAAA,oBAAA,cAAW;AACX,EAAAA,oBAAA,aAAU;AACV,EAAAA,oBAAA,YAAS;AAHC,SAAAA;AAAA,GAAA;",
6
6
  "names": ["MessageRole", "MessageStatus", "ActionAvailability"]
7
7
  }
@@ -1,5 +1,4 @@
1
- import type { SenderProps } from '@ant-design/x';
2
- import type { Attachment } from '@ant-design/x/es/attachments';
1
+ import type { SenderProps, Attachment } from './antdx';
3
2
  import { UploadProps } from 'antd';
4
3
  import { FunctionResponse } from './XAdkChatbot';
5
4
  export interface SendContent {