@ai-group/chat-sdk 3.6.10 → 3.6.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/client/base.d.ts +1 -2
- package/dist/cjs/client/base.js.map +1 -1
- package/dist/cjs/components/XAdkChatbot/components/ThinkRender/index.d.ts +1 -1
- package/dist/cjs/components/XAdkChatbot/components/ThinkRender/index.js.map +1 -1
- package/dist/cjs/components/XAdkChatbot/index.js +25 -13
- package/dist/cjs/components/XAdkChatbot/index.js.map +2 -2
- package/dist/cjs/components/XAdkProvider/compound/Sender.d.ts +2 -2
- package/dist/cjs/components/XAdkProvider/compound/Sender.js +21 -18
- package/dist/cjs/components/XAdkProvider/compound/Sender.js.map +2 -2
- package/dist/cjs/components/XAdkProvider/compound/Sidebar.js +6 -2
- package/dist/cjs/components/XAdkProvider/compound/Sidebar.js.map +2 -2
- package/dist/cjs/components/XAdkProvider/context/ChatSenderStateContext.d.ts +16 -0
- package/dist/cjs/components/XAdkProvider/context/ChatSenderStateContext.js +40 -0
- package/dist/cjs/components/XAdkProvider/context/ChatSenderStateContext.js.map +7 -0
- package/dist/cjs/components/XAdkProvider/context/index.d.ts +1 -0
- package/dist/cjs/components/XAdkProvider/context/index.js +3 -1
- package/dist/cjs/components/XAdkProvider/context/index.js.map +2 -2
- package/dist/cjs/components/XAdkProvider/index.js +13 -2
- package/dist/cjs/components/XAdkProvider/index.js.map +2 -2
- package/dist/cjs/components/XAdkSender/index.js +502 -496
- package/dist/cjs/components/XAdkSender/index.js.map +2 -2
- package/dist/cjs/components/XAdkSender/styles.js +0 -13
- package/dist/cjs/components/XAdkSender/styles.js.map +2 -2
- package/dist/cjs/components/XAiChatbot/index.js.map +1 -1
- package/dist/cjs/components/XAiProvider/index.js.map +1 -1
- package/dist/cjs/components/XAiSender/index.js.map +1 -1
- package/dist/cjs/hooks/useADKChat.js +10 -2
- package/dist/cjs/hooks/useADKChat.js.map +2 -2
- package/dist/cjs/types/XAdkSender.d.ts +0 -2
- package/dist/cjs/types/XAdkSender.js.map +1 -1
- package/dist/cjs/types/XAiChatbot.d.ts +1 -1
- package/dist/cjs/types/XAiChatbot.js.map +1 -1
- package/dist/cjs/types/XAiConversations.d.ts +1 -1
- package/dist/cjs/types/XAiConversations.js.map +1 -1
- package/dist/cjs/types/XAiMessage.d.ts +1 -1
- package/dist/cjs/types/XAiMessage.js.map +1 -1
- package/dist/cjs/types/XAiSender.d.ts +1 -2
- package/dist/cjs/types/XAiSender.js.map +1 -1
- package/dist/cjs/types/antdx.d.ts +146 -0
- package/dist/cjs/types/antdx.js +18 -0
- package/dist/cjs/types/antdx.js.map +7 -0
- package/dist/esm/client/base.d.ts +1 -2
- package/dist/esm/client/base.js.map +1 -1
- package/dist/esm/components/XAdkChatbot/components/ThinkRender/index.d.ts +1 -1
- package/dist/esm/components/XAdkChatbot/components/ThinkRender/index.js.map +1 -1
- package/dist/esm/components/XAdkChatbot/index.js.map +1 -1
- package/dist/esm/components/XAdkProvider/compound/Sender.d.ts +2 -2
- package/dist/esm/components/XAdkProvider/compound/Sender.js +10 -7
- package/dist/esm/components/XAdkProvider/compound/Sender.js.map +1 -1
- package/dist/esm/components/XAdkProvider/compound/Sidebar.js +7 -2
- package/dist/esm/components/XAdkProvider/compound/Sidebar.js.map +1 -1
- package/dist/esm/components/XAdkProvider/context/ChatSenderStateContext.d.ts +16 -0
- package/dist/esm/components/XAdkProvider/context/ChatSenderStateContext.js +16 -0
- package/dist/esm/components/XAdkProvider/context/ChatSenderStateContext.js.map +1 -0
- package/dist/esm/components/XAdkProvider/context/index.d.ts +1 -0
- package/dist/esm/components/XAdkProvider/context/index.js +1 -0
- package/dist/esm/components/XAdkProvider/context/index.js.map +1 -1
- package/dist/esm/components/XAdkProvider/index.js +30 -9
- package/dist/esm/components/XAdkProvider/index.js.map +1 -1
- package/dist/esm/components/XAdkSender/index.js +2 -5
- package/dist/esm/components/XAdkSender/index.js.map +1 -1
- package/dist/esm/components/XAdkSender/styles.js +1 -1
- package/dist/esm/components/XAdkSender/styles.js.map +1 -1
- package/dist/esm/components/XAiChatbot/index.js.map +1 -1
- package/dist/esm/components/XAiProvider/index.js.map +1 -1
- package/dist/esm/components/XAiSender/index.js.map +1 -1
- package/dist/esm/hooks/useADKChat.js +14 -4
- package/dist/esm/hooks/useADKChat.js.map +1 -1
- package/dist/esm/types/XAdkSender.d.ts +0 -2
- package/dist/esm/types/XAdkSender.js.map +1 -1
- package/dist/esm/types/XAiChatbot.d.ts +1 -1
- package/dist/esm/types/XAiChatbot.js.map +1 -1
- package/dist/esm/types/XAiConversations.d.ts +1 -1
- package/dist/esm/types/XAiConversations.js.map +1 -1
- package/dist/esm/types/XAiMessage.d.ts +1 -1
- package/dist/esm/types/XAiMessage.js.map +1 -1
- package/dist/esm/types/XAiSender.d.ts +1 -2
- package/dist/esm/types/XAiSender.js.map +1 -1
- package/dist/esm/types/antdx.d.ts +146 -0
- package/dist/esm/types/antdx.js +2 -0
- package/dist/esm/types/antdx.js.map +1 -0
- package/dist/umd/chat-sdk.min.js +1 -1
- package/package.json +1 -1
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import BubbleDataType from "@ant-design/x/es/bubble/BubbleList";
|
|
2
1
|
export interface AiClient {
|
|
3
2
|
appName: string;
|
|
4
3
|
icon: string;
|
|
@@ -6,4 +5,4 @@ export interface AiClient {
|
|
|
6
5
|
stream?(message: string, onMessage: (msg: any) => void): void;
|
|
7
6
|
close?(): void;
|
|
8
7
|
}
|
|
9
|
-
export type MessageType =
|
|
8
|
+
export type MessageType = any;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/client/base.ts"],
|
|
4
|
-
"sourcesContent": ["// baseClient.ts\
|
|
4
|
+
"sourcesContent": ["// baseClient.ts\n\nexport interface AiClient {\n appName: string;\n icon: string;\n send(message: string): Promise<any>;\n stream?(message: string, onMessage: (msg: any) => void): void;\n close?(): void;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type MessageType = any;\n"],
|
|
5
5
|
"mappings": ";;;;;;;;;;;;;;;AAAA;AAAA;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../../src/components/XAdkChatbot/components/ThinkRender/index.tsx"],
|
|
4
|
-
"sourcesContent": ["import { Think } from '@ant-design/x';\nimport type { ThinkProps } from '
|
|
4
|
+
"sourcesContent": ["import { Think } from '@ant-design/x';\nimport type { ThinkProps } from '@/types/antdx';\nimport React, { useEffect, useState } from 'react';\nimport type { IMessage } from '@/types';\n\nexport interface ThinkRenderProps extends Omit<ThinkProps, 'children'> {\n msg: IMessage;\n}\n\nconst ThinkRender: React.FC<ThinkRenderProps> = ({\n msg,\n loading,\n title,\n expanded,\n onExpand,\n defaultExpanded,\n ...rest\n}) => {\n const isControlled = expanded !== undefined;\n const [innerExpand, setInnerExpand] = useState(defaultExpanded ?? false);\n\n useEffect(() => {\n if (isControlled) return;\n setInnerExpand(!!loading);\n }, [loading, isControlled]);\n\n const expandValue = isControlled ? expanded : innerExpand;\n\n const handleExpand = (val: boolean) => {\n if (!isControlled) {\n setInnerExpand(val);\n }\n onExpand?.(val);\n };\n\n return (\n <Think\n title={title ?? (loading ? '思考中...' : '深度思考')}\n loading={loading}\n expanded={expandValue}\n onExpand={handleExpand}\n {...rest}\n >\n {msg.text}\n </Think>\n );\n};\n\nexport default ThinkRender;\n"],
|
|
5
5
|
"mappings": ";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,eAAsB;AAEtB,mBAA2C;AAkCvC;AA3BJ,IAAM,cAA0C,CAAC;AAAA,EAC/C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,MAAM;AACJ,QAAM,eAAe,aAAa;AAClC,QAAM,CAAC,aAAa,cAAc,QAAI,uBAAS,mBAAmB,KAAK;AAEvE,8BAAU,MAAM;AACd,QAAI;AAAc;AAClB,mBAAe,CAAC,CAAC,OAAO;AAAA,EAC1B,GAAG,CAAC,SAAS,YAAY,CAAC;AAE1B,QAAM,cAAc,eAAe,WAAW;AAE9C,QAAM,eAAe,CAAC,QAAiB;AACrC,QAAI,CAAC,cAAc;AACjB,qBAAe,GAAG;AAAA,IACpB;AACA,yCAAW;AAAA,EACb;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,OAAO,UAAU,UAAU,WAAW;AAAA,MACtC;AAAA,MACA,UAAU;AAAA,MACV,UAAU;AAAA,MACT,GAAG;AAAA,MAEH,cAAI;AAAA;AAAA,EACP;AAEJ;AAEA,IAAO,sBAAQ;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -86,13 +86,10 @@ var XAdkChatbot = (0, import_react.forwardRef)(
|
|
|
86
86
|
const messagesEndRef = (0, import_react.useRef)(null);
|
|
87
87
|
const prevInitializedRef = (0, import_react.useRef)(false);
|
|
88
88
|
const prevSessionIdRef = (0, import_react.useRef)(sessionId);
|
|
89
|
-
const scrollToBottom = (0, import_react.useCallback)(
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
},
|
|
94
|
-
[]
|
|
95
|
-
);
|
|
89
|
+
const scrollToBottom = (0, import_react.useCallback)((behavior = "auto") => {
|
|
90
|
+
var _a;
|
|
91
|
+
(_a = messagesEndRef.current) == null ? void 0 : _a.scrollIntoView({ behavior });
|
|
92
|
+
}, []);
|
|
96
93
|
(0, import_react.useImperativeHandle)(ref, () => ({ scrollToBottom }), [scrollToBottom]);
|
|
97
94
|
const mergedStrategies = (0, import_react.useMemo)(
|
|
98
95
|
() => (0, import_xGroupAdk.mergeChatStrategies)(preset, strategies),
|
|
@@ -126,7 +123,11 @@ var XAdkChatbot = (0, import_react.forwardRef)(
|
|
|
126
123
|
clearTimeout(stableTimer);
|
|
127
124
|
stableTimer = setTimeout(doScroll, 80);
|
|
128
125
|
});
|
|
129
|
-
observer.observe(el, {
|
|
126
|
+
observer.observe(el, {
|
|
127
|
+
childList: true,
|
|
128
|
+
subtree: true,
|
|
129
|
+
characterData: true
|
|
130
|
+
});
|
|
130
131
|
doScroll();
|
|
131
132
|
const maxTimer = setTimeout(() => {
|
|
132
133
|
observer.disconnect();
|
|
@@ -381,9 +382,7 @@ var XAdkChatbot = (0, import_react.forwardRef)(
|
|
|
381
382
|
const isGroupLoading = loading && isLastGroup;
|
|
382
383
|
const actionProps = { message: group, isLastBotMsg: isLastGroup };
|
|
383
384
|
const actionExtraNode = actionsExtra == null ? void 0 : actionsExtra(actionProps);
|
|
384
|
-
const lastProcessIdx = nodes.findLastIndex(
|
|
385
|
-
(n) => n.type === "process"
|
|
386
|
-
);
|
|
385
|
+
const lastProcessIdx = nodes.findLastIndex((n) => n.type === "process");
|
|
387
386
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: styles.botMsg, children: [
|
|
388
387
|
nodes.map((node, idx) => {
|
|
389
388
|
if (node.type === "process") {
|
|
@@ -404,7 +403,13 @@ var XAdkChatbot = (0, import_react.forwardRef)(
|
|
|
404
403
|
node.key
|
|
405
404
|
);
|
|
406
405
|
}
|
|
407
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
406
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
407
|
+
import_MarkdownRender.default,
|
|
408
|
+
{
|
|
409
|
+
text: node.content,
|
|
410
|
+
onFileClick
|
|
411
|
+
}
|
|
412
|
+
) }, node.key);
|
|
408
413
|
}),
|
|
409
414
|
allFiles.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: styles.fileSection, children: [
|
|
410
415
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: styles.fileHeader, children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { children: [
|
|
@@ -412,7 +417,14 @@ var XAdkChatbot = (0, import_react.forwardRef)(
|
|
|
412
417
|
allFiles.length,
|
|
413
418
|
")"
|
|
414
419
|
] }) }),
|
|
415
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { display: "flex", flexWrap: "wrap", gap: "8px" }, children: allFiles.map((file, index) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
420
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { display: "flex", flexWrap: "wrap", gap: "8px" }, children: allFiles.map((file, index) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
421
|
+
import_FileGallery.default,
|
|
422
|
+
{
|
|
423
|
+
file,
|
|
424
|
+
onClick: onFileClick
|
|
425
|
+
},
|
|
426
|
+
index
|
|
427
|
+
)) })
|
|
416
428
|
] }),
|
|
417
429
|
!isGroupLoading && (actions || showRetry || showCopy || showLog || actionExtraNode) && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: styles.metaFooter, children: [
|
|
418
430
|
actions ? actions(actionProps) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_antd.Flex, { gap: 16, className: styles.actionIcons, children: [
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/components/XAdkChatbot/index.tsx"],
|
|
4
|
-
"sourcesContent": ["import React, {\n useMemo,\n useCallback,\n useEffect,\n useRef,\n useImperativeHandle,\n forwardRef,\n} from \"react\";\nimport { Button, Flex, Tooltip, message as antdMessage } from \"antd\";\nimport clsx from \"clsx\";\nimport {\n SwapRightOutlined,\n ReloadOutlined,\n CopyOutlined,\n InfoCircleOutlined,\n CheckCircleFilled,\n} from \"@ant-design/icons\";\nimport copy from \"copy-to-clipboard\";\nimport { useStyles } from \"./styles\";\nimport MarkdownRender from \"./components/MarkdownRender\";\nimport FunctionCallRender from \"./components/FunctionCallRender\";\nimport FileGallery from \"../FileGallery\";\nimport XAdkThoughtChain from \"@/components/XAdkThoughtChain\";\nimport { parseAgentMessage } from \"@/utils\";\nimport { mergeChatStrategies } from \"@/presets/xGroupAdk\";\nimport type {\n IMessage,\n XAdkChatbotProps,\n XAdkChatbotHandle,\n ChatGroup,\n} from \"@/types\";\nimport type { ThoughtChainItemType } from \"@/types/XAdkThoughtChain\";\nimport { defaultToolKindResolver } from \"@/types/FunctionCallRender\";\n\nconst scrollThreshold = 10;\n\n/**\n * XAdkChatbot - 增强版聊天组件\n *\n * 新增功能:\n * - ✅ 自动消息分组 (enableGrouping)\n * - ✅ 自动解析思维链 (enableProcessParsing)\n * - ✅ 文件展示 (FileGallery)\n * - ✅ 操作栏 (重试/复制/日志)\n * - ✅ 欢迎页面 (agentName/agentIcon/description)\n */\nconst XAdkChatbot = forwardRef<XAdkChatbotHandle, XAdkChatbotProps>(\n (\n {\n loading = false,\n prologue,\n suggestions,\n messages,\n showFnCallDetail,\n onConfirm,\n onSuggest,\n showRetry,\n showCopy,\n showLog,\n onRetry,\n onCopy,\n onShowLog,\n actions,\n actionsExtra,\n className,\n style,\n // welcome = null,\n enableGrouping = true,\n enableProcessParsing = true,\n parseOptions,\n initialized = true,\n sessionId,\n onFileClick,\n renderFunctionCall,\n toolKindResolver,\n strategies,\n preset,\n empty,\n },\n ref,\n ) => {\n const styles = useStyles();\n const listRef = useRef<HTMLDivElement>(null);\n const lastScrollTopRef = useRef(0);\n const userHasScrolledRef = useRef(false);\n const messagesEndRef = useRef<HTMLDivElement>(null);\n const prevInitializedRef = useRef(false);\n const prevSessionIdRef = useRef(sessionId);\n\n // 暴露命令式 API\n const scrollToBottom = useCallback(\n (behavior: ScrollBehavior = \"auto\") => {\n messagesEndRef.current?.scrollIntoView({ behavior });\n },\n [],\n );\n useImperativeHandle(ref, () => ({ scrollToBottom }), [scrollToBottom]);\n const mergedStrategies = useMemo(\n () => mergeChatStrategies(preset, strategies),\n [preset, strategies],\n );\n const resolveToolKind = useCallback(\n (name?: string, msg?: IMessage) =>\n toolKindResolver?.(name) ??\n mergedStrategies.resolveToolKind?.({ name, msg }) ??\n defaultToolKindResolver(name),\n [toolKindResolver, mergedStrategies],\n );\n const parseProcessMessage =\n mergedStrategies.parseProcessMessage ?? parseAgentMessage;\n\n // 初始化完成时滚动到底部\n useEffect(() => {\n if (!initialized) return;\n if (!messages.length) return;\n if (prevInitializedRef.current) return;\n prevInitializedRef.current = true;\n\n const el = listRef.current;\n if (!el) return;\n\n // 用 MutationObserver 监听 DOM 子树变化,等内容渲染稳定后置底\n // 每次 DOM 变化都重新计时,确保所有异步渲染(Markdown、代码高亮、思维链等)完成后再滚动\n let stableTimer: ReturnType<typeof setTimeout>;\n const doScroll = () => {\n messagesEndRef.current?.scrollIntoView({ behavior: \"auto\" });\n };\n\n const observer = new MutationObserver(() => {\n clearTimeout(stableTimer);\n stableTimer = setTimeout(doScroll, 80);\n });\n\n observer.observe(el, { childList: true, subtree: true, characterData: true });\n\n // 立即执行一次,处理内容已经就绪的情况\n doScroll();\n // 兜底:最多等 500ms 后强制滚动并断开观察\n const maxTimer = setTimeout(() => {\n observer.disconnect();\n doScroll();\n }, 500);\n\n return () => {\n clearTimeout(stableTimer);\n clearTimeout(maxTimer);\n observer.disconnect();\n };\n }, [initialized, messages]);\n\n // 会话切换时重置滚动状态,允许重新触发初始化置底\n useEffect(() => {\n if (sessionId === undefined) return; // 未传 sessionId 不处理\n if (prevSessionIdRef.current === sessionId) return; // 同一会话不处理\n prevSessionIdRef.current = sessionId;\n prevInitializedRef.current = false;\n userHasScrolledRef.current = false;\n }, [sessionId]);\n\n // 消息变化时自动滚动到底部(用户未手动上滚时)\n useEffect(() => {\n if (userHasScrolledRef.current) return;\n if (!messages.length) return;\n const el = listRef.current;\n if (el) {\n el.scrollTop = el.scrollHeight;\n }\n }, [loading, messages]);\n\n // loading 结束时(流式输出完成),操作栏(metaFooter)会渲染出来增加高度,\n // 需要延迟滚动到底部,确保操作栏可见\n const prevLoadingRef = useRef(loading);\n useEffect(() => {\n const wasLoading = prevLoadingRef.current;\n prevLoadingRef.current = loading;\n\n if (!wasLoading || loading) return; // 只在 loading true → false 时触发\n if (userHasScrolledRef.current) return;\n if (!messages.length) return;\n\n // 延迟等待操作栏 DOM 渲染完成后再滚动\n const timer = setTimeout(() => {\n const el = listRef.current;\n if (el) {\n el.scrollTop = el.scrollHeight;\n }\n }, 50);\n return () => clearTimeout(timer);\n }, [loading, messages]);\n\n // 处理滚动事件\n const handleScroll = useCallback(() => {\n const el = listRef.current;\n if (!el) return;\n const currentTop = el.scrollTop;\n\n if (currentTop < lastScrollTopRef.current) {\n userHasScrolledRef.current = true;\n }\n\n const isAtBottom =\n Math.abs(el.scrollHeight - currentTop - el.clientHeight) <=\n scrollThreshold;\n if (isAtBottom) {\n userHasScrolledRef.current = false;\n }\n\n lastScrollTopRef.current = currentTop;\n }, []);\n\n useEffect(() => {\n const listElement = listRef.current;\n if (!listElement) return;\n\n listElement.addEventListener(\"scroll\", handleScroll);\n return () => {\n listElement.removeEventListener(\"scroll\", handleScroll);\n };\n }, [handleScroll]);\n\n // ========== 消息分组逻辑 ==========\n const chatGroups = useMemo(() => {\n if (!enableGrouping) {\n // 不分组,每条消息独立\n return messages.map((msg) => ({\n id: msg.id,\n role: msg.role,\n msgs: [msg],\n invocationId: msg.invocationId,\n allFiles: msg.fileData || [],\n isLike: msg.isLike ?? 0,\n }));\n }\n\n const groups: ChatGroup[] = [];\n messages.forEach((msg) => {\n // 过滤 followup 消息\n if ((msg as any).role === \"followup\") return;\n\n const isRealUserQuery =\n msg.role === \"user\" && !msg.functionResponse && !msg.functionCall;\n const lastGroup = groups[groups.length - 1];\n const isLastGroupAgent = lastGroup?.role === \"bot\";\n\n if (isLastGroupAgent && !isRealUserQuery) {\n // 合并到上一个 bot 分组\n lastGroup.msgs.push(msg);\n if (msg.invocationId) lastGroup.invocationId = msg.invocationId;\n // 更新 isLike: 取最新的非0值,或保持当前值\n if (msg.isLike && msg.isLike !== 0) {\n lastGroup.isLike = msg.isLike;\n }\n } else {\n // 创建新分组\n groups.push({\n id: msg.id || `group-${groups.length}`,\n role: isRealUserQuery ? \"user\" : \"bot\",\n msgs: [msg],\n invocationId: msg.invocationId,\n allFiles: [],\n isLike: msg.isLike ?? 0,\n });\n }\n });\n\n // 合并文件\n groups.forEach((g) => {\n g.allFiles = g.msgs.reduce(\n (acc, m) => [...acc, ...(m.fileData || [])],\n [] as any[],\n );\n });\n\n return groups;\n }, [messages, enableGrouping]);\n\n // ========== 渲染 Bot 消息组 ==========\n const renderBotGroup = useCallback(\n (\n group: ChatGroup,\n isLastGroup: boolean,\n renderFunctionCall?: XAdkChatbotProps[\"renderFunctionCall\"],\n ) => {\n const { msgs, allFiles } = group;\n\n if (!enableProcessParsing) {\n // 不解析 process,简单渲染\n return (\n <div key={group.id} className={styles.botMsg}>\n {msgs.map((msg, i) => {\n if (msg.text) {\n return (\n <MarkdownRender\n key={`${msg.id}-${i}`}\n text={msg.text}\n onFileClick={onFileClick}\n />\n );\n }\n if (msg.functionCall) {\n return (\n renderFunctionCall?.(msg) ?? (\n <FunctionCallRender\n key={`${msg.id}-${i}`}\n msg={msg}\n showDetail={showFnCallDetail}\n onConfirm={onConfirm}\n kind={resolveToolKind(msg.functionCall?.name, msg)}\n renderApproval={mergedStrategies.renderApproval}\n renderHandoff={mergedStrategies.renderHandoff}\n />\n )\n );\n }\n return null;\n })}\n </div>\n );\n }\n\n // ========== 解析 Process 内容 ==========\n\n // 1. 合并工具调用\n const mergedToolMap = new Map<string, IMessage>();\n msgs.forEach((msg) => {\n if (msg.functionCall) {\n const callId = msg.functionCall.id || \"\";\n if (!mergedToolMap.has(callId)) {\n mergedToolMap.set(callId, { ...msg });\n } else {\n mergedToolMap.set(callId, {\n ...(mergedToolMap.get(callId) ?? {}),\n ...msg,\n });\n }\n } else if (msg.functionResponse) {\n const callId = msg.functionResponse.id || \"\";\n if (mergedToolMap.has(callId)) {\n const tool = mergedToolMap.get(callId);\n if (tool) tool.functionResponse = msg.functionResponse;\n } else {\n mergedToolMap.set(callId, {\n ...msg,\n functionCall: {\n id: callId,\n name: msg.functionResponse.name || \"Unknown\",\n args: {},\n },\n });\n }\n }\n });\n\n // 2. 解析文本消息中的 process 内容\n type RenderNode =\n | { type: \"text\"; content: string; key: string }\n | { type: \"process\"; items: ThoughtChainItemType[]; key: string };\n\n const nodes: RenderNode[] = [];\n let currentProcessItems: ThoughtChainItemType[] = [];\n const processedToolIds = new Set<string>();\n\n const flushProcessItems = () => {\n if (currentProcessItems.length > 0) {\n nodes.push({\n type: \"process\",\n items: [...currentProcessItems],\n key: `process-${nodes.length}`,\n });\n currentProcessItems = [];\n }\n };\n\n msgs.forEach((msg) => {\n // 处理工具调用\n if (msg.functionCall) {\n const callId = msg.functionCall.id || \"\";\n if (!processedToolIds.has(callId)) {\n const mergedMsg = mergedToolMap.get(callId);\n if (mergedMsg) {\n currentProcessItems.push({\n type: \"tool\",\n key: `tool-${callId}`,\n content: \"\",\n msg: mergedMsg,\n });\n processedToolIds.add(callId);\n }\n }\n }\n // 处理文本消息\n else if (msg.text && !msg.functionResponse) {\n const parts = parseProcessMessage(msg.text, parseOptions as any);\n\n parts.forEach((part, partIdx) => {\n // process 内容放入 currentProcessItems\n if (\n [\n \"planning\",\n \"replanning\",\n \"reasoning\",\n \"action_log\",\n \"process_text\",\n ].includes(part.type)\n ) {\n const titleMap: Record<string, string> = {\n planning: \"任务规划\",\n replanning: \"重新规划\",\n reasoning: \"推理分析\",\n action_log: \"行动记录\",\n process_text: \"过程分析\",\n };\n\n currentProcessItems.push({\n type: \"text\",\n key: `${msg.id}-${partIdx}`,\n content: part.content,\n title: titleMap[part.type] || \"分析\",\n });\n }\n // 普通文本内容\n else {\n flushProcessItems();\n if (part.content.trim()) {\n const lastNode = nodes[nodes.length - 1];\n if (lastNode?.type === \"text\") {\n // 合并到上一个文本节点\n lastNode.content += \"\\n\\n\" + part.content;\n } else {\n nodes.push({\n type: \"text\",\n content: part.content,\n key: `text-${msg.id}-${partIdx}`,\n });\n }\n }\n }\n });\n }\n });\n\n // 最后flush一次\n flushProcessItems();\n\n // 3. 准备操作栏数据\n const fullTextToCopy = msgs\n .filter((m) => !m.functionCall && !m.functionResponse)\n .map((m) => m.text || \"\")\n .join(\"\");\n\n const lastBotMsg = msgs[msgs.length - 1];\n const hasProcess = nodes.some((n) => n.type === \"process\");\n const isGroupLoading = loading && isLastGroup;\n const actionProps = { message: group, isLastBotMsg: isLastGroup };\n const actionExtraNode = actionsExtra?.(actionProps);\n\n // 4. 渲染\n const lastProcessIdx = nodes.findLastIndex(\n (n) => n.type === \"process\",\n );\n return (\n <div key={group.id} className={styles.botMsg}>\n {nodes.map((node, idx) => {\n if (node.type === \"process\") {\n // 只有最后一个 process node 跟随 loading 状态,已完成的思维链不应显示 loading\n const isLastProcess = idx === lastProcessIdx;\n return (\n <XAdkThoughtChain\n key={node.key}\n loading={isLastProcess && isGroupLoading}\n title=\"思维链已完成\"\n items={node.items}\n showFnCallDetail={showFnCallDetail}\n onConfirm={onConfirm}\n defaultOpen={isLastProcess && isGroupLoading}\n renderFunctionCall={renderFunctionCall}\n toolKindResolver={(name) => resolveToolKind(name)}\n strategies={mergedStrategies}\n />\n );\n }\n\n // 文本节点\n // const showBadge =\n // hasProcess && nodes.findIndex((n) => n.type === \"text\") === idx;\n return (\n <div key={node.key}>\n {/* {showBadge && (\n <div className={styles.successBadge}>\n <CheckCircleFilled /> 已完成所有规划任务\n </div>\n )} */}\n <MarkdownRender text={node.content} onFileClick={onFileClick} />\n </div>\n );\n })}\n\n {/* 文件展示 */}\n {allFiles.length > 0 && (\n <div className={styles.fileSection}>\n <div className={styles.fileHeader}>\n <span>生成文件 ({allFiles.length})</span>\n </div>\n <div style={{ display: \"flex\", flexWrap: \"wrap\", gap: \"8px\" }}>\n {allFiles.map((file, index) => (\n <FileGallery key={index} file={file} onClick={onFileClick} />\n ))}\n </div>\n </div>\n )}\n\n {/* 操作栏 */}\n {!isGroupLoading &&\n (actions ||\n showRetry ||\n showCopy ||\n showLog ||\n actionExtraNode) && (\n <div className={styles.metaFooter}>\n {actions ? (\n actions(actionProps)\n ) : (\n <Flex gap={16} className={styles.actionIcons}>\n {showRetry && isLastGroup && (\n <Tooltip title=\"重新生成\">\n <ReloadOutlined onClick={onRetry} />\n </Tooltip>\n )}\n {showCopy && (\n <Tooltip title=\"复制内容\">\n <CopyOutlined\n onClick={() => {\n copy(fullTextToCopy);\n antdMessage.success(\"复制成功\");\n onCopy?.(fullTextToCopy);\n }}\n />\n </Tooltip>\n )}\n {showLog && lastBotMsg?.invocationId && (\n <Tooltip title=\"查看日志\">\n <InfoCircleOutlined\n onClick={() =>\n onShowLog?.(\n lastBotMsg.invocationId!,\n lastBotMsg.timestamp,\n )\n }\n />\n </Tooltip>\n )}\n </Flex>\n )}\n {actionExtraNode}\n </div>\n )}\n </div>\n );\n },\n [\n enableProcessParsing,\n parseOptions,\n parseProcessMessage,\n showFnCallDetail,\n onConfirm,\n loading,\n showRetry,\n showCopy,\n showLog,\n onRetry,\n onCopy,\n onShowLog,\n actions,\n actionsExtra,\n onFileClick,\n styles,\n resolveToolKind,\n mergedStrategies,\n ],\n );\n\n // ========== 渲染用户消息组 ==========\n const renderUserGroup = useCallback(\n (group: ChatGroup) => {\n return (\n <div key={group.id} className={styles.userMsg}>\n {group.msgs.map((m, i) => (\n <div key={m.id || i} className={styles.userContainer}>\n {/* 文件展示 */}\n {m.fileData && m.fileData.length > 0 && (\n <>\n {m.fileData.map((file, index) => (\n <FileGallery\n key={index}\n file={file}\n align=\"left\"\n style={{ marginBottom: \"16px\" }}\n onClick={onFileClick}\n />\n ))}\n </>\n )}\n {/* 文本展示 */}\n {m.text && <div className={styles.card}>{m.text}</div>}\n </div>\n ))}\n </div>\n );\n },\n [styles, onFileClick],\n );\n\n // ========== 空状态 ==========\n\n // ========== 渲染建议问题 ==========\n const renderSuggestions = () => {\n if (!suggestions || suggestions.length === 0) return null;\n\n return (\n <div className={styles.suggestionWrapper}>\n {suggestions.map((item) => (\n <div key={item} className={styles.suggestion}>\n <div className={styles.suggestContent}>\n <Button\n type=\"text\"\n icon={<SwapRightOutlined />}\n iconPosition=\"end\"\n onClick={() => {\n if (!item) return;\n onSuggest?.(item);\n }}\n style={{\n whiteSpace: \"normal\",\n height: \"auto\",\n wordWrap: \"break-word\",\n textAlign: \"left\",\n padding: \"4px 15px\",\n lineHeight: \"1.5\",\n }}\n >\n {item}\n </Button>\n </div>\n </div>\n ))}\n </div>\n );\n };\n\n // 空状态判断\n const isEmpty = messages.length === 0 && !prologue && (!suggestions || suggestions.length === 0);\n\n return (\n <div className={clsx(styles.wrapper, className)} style={style}>\n <div className={styles.list} ref={listRef}>\n {/* 空状态 */}\n {isEmpty && empty && (\n <div className={styles.emptyWrapper}>\n {typeof empty === \"function\" ? empty() : empty}\n </div>\n )}\n\n {/* 开场白 */}\n {prologue && (\n <div className={styles.prologue}>\n <MarkdownRender text={prologue} onFileClick={onFileClick} />\n </div>\n )}\n\n {/* 消息列表 */}\n {chatGroups.map((group, idx) =>\n group.role === \"user\"\n ? renderUserGroup(group)\n : renderBotGroup(\n group,\n idx === chatGroups.length - 1,\n renderFunctionCall,\n ),\n )}\n\n {/* 建议问题 */}\n {renderSuggestions()}\n\n <div ref={messagesEndRef} />\n </div>\n </div>\n );\n },\n);\n\nXAdkChatbot.displayName = \"XAdkChatbot\";\n\nexport default XAdkChatbot;\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["import React, {\n useMemo,\n useCallback,\n useEffect,\n useRef,\n useImperativeHandle,\n forwardRef,\n} from \"react\";\nimport { Button, Flex, Tooltip, message as antdMessage } from \"antd\";\nimport clsx from \"clsx\";\nimport {\n SwapRightOutlined,\n ReloadOutlined,\n CopyOutlined,\n InfoCircleOutlined,\n CheckCircleFilled,\n} from \"@ant-design/icons\";\nimport copy from \"copy-to-clipboard\";\nimport { useStyles } from \"./styles\";\nimport MarkdownRender from \"./components/MarkdownRender\";\nimport FunctionCallRender from \"./components/FunctionCallRender\";\nimport FileGallery from \"../FileGallery\";\nimport XAdkThoughtChain from \"@/components/XAdkThoughtChain\";\nimport { parseAgentMessage } from \"@/utils\";\nimport { mergeChatStrategies } from \"@/presets/xGroupAdk\";\nimport type {\n IMessage,\n XAdkChatbotProps,\n XAdkChatbotHandle,\n ChatGroup,\n} from \"@/types\";\nimport type { ThoughtChainItemType } from \"@/types/XAdkThoughtChain\";\nimport { defaultToolKindResolver } from \"@/types/FunctionCallRender\";\n\nconst scrollThreshold = 10;\n\n/**\n * XAdkChatbot - 增强版聊天组件\n *\n * 新增功能:\n * - ✅ 自动消息分组 (enableGrouping)\n * - ✅ 自动解析思维链 (enableProcessParsing)\n * - ✅ 文件展示 (FileGallery)\n * - ✅ 操作栏 (重试/复制/日志)\n * - ✅ 欢迎页面 (agentName/agentIcon/description)\n */\nconst XAdkChatbot = forwardRef<XAdkChatbotHandle, XAdkChatbotProps>(\n (\n {\n loading = false,\n prologue,\n suggestions,\n messages,\n showFnCallDetail,\n onConfirm,\n onSuggest,\n showRetry,\n showCopy,\n showLog,\n onRetry,\n onCopy,\n onShowLog,\n actions,\n actionsExtra,\n className,\n style,\n // welcome = null,\n enableGrouping = true,\n enableProcessParsing = true,\n parseOptions,\n initialized = true,\n sessionId,\n onFileClick,\n renderFunctionCall,\n toolKindResolver,\n strategies,\n preset,\n empty,\n },\n ref,\n ) => {\n const styles = useStyles();\n const listRef = useRef<HTMLDivElement>(null);\n const lastScrollTopRef = useRef(0);\n const userHasScrolledRef = useRef(false);\n const messagesEndRef = useRef<HTMLDivElement>(null);\n const prevInitializedRef = useRef(false);\n const prevSessionIdRef = useRef(sessionId);\n\n // 暴露命令式 API\n const scrollToBottom = useCallback((behavior: ScrollBehavior = \"auto\") => {\n messagesEndRef.current?.scrollIntoView({ behavior });\n }, []);\n useImperativeHandle(ref, () => ({ scrollToBottom }), [scrollToBottom]);\n const mergedStrategies = useMemo(\n () => mergeChatStrategies(preset, strategies),\n [preset, strategies],\n );\n const resolveToolKind = useCallback(\n (name?: string, msg?: IMessage) =>\n toolKindResolver?.(name) ??\n mergedStrategies.resolveToolKind?.({ name, msg }) ??\n defaultToolKindResolver(name),\n [toolKindResolver, mergedStrategies],\n );\n const parseProcessMessage =\n mergedStrategies.parseProcessMessage ?? parseAgentMessage;\n\n // 初始化完成时滚动到底部\n useEffect(() => {\n if (!initialized) return;\n if (!messages.length) return;\n if (prevInitializedRef.current) return;\n prevInitializedRef.current = true;\n\n const el = listRef.current;\n if (!el) return;\n\n // 用 MutationObserver 监听 DOM 子树变化,等内容渲染稳定后置底\n // 每次 DOM 变化都重新计时,确保所有异步渲染(Markdown、代码高亮、思维链等)完成后再滚动\n let stableTimer: ReturnType<typeof setTimeout>;\n const doScroll = () => {\n messagesEndRef.current?.scrollIntoView({ behavior: \"auto\" });\n };\n\n const observer = new MutationObserver(() => {\n clearTimeout(stableTimer);\n stableTimer = setTimeout(doScroll, 80);\n });\n\n observer.observe(el, {\n childList: true,\n subtree: true,\n characterData: true,\n });\n\n // 立即执行一次,处理内容已经就绪的情况\n doScroll();\n // 兜底:最多等 500ms 后强制滚动并断开观察\n const maxTimer = setTimeout(() => {\n observer.disconnect();\n doScroll();\n }, 500);\n\n return () => {\n clearTimeout(stableTimer);\n clearTimeout(maxTimer);\n observer.disconnect();\n };\n }, [initialized, messages]);\n\n // 会话切换时重置滚动状态,允许重新触发初始化置底\n useEffect(() => {\n if (sessionId === undefined) return; // 未传 sessionId 不处理\n if (prevSessionIdRef.current === sessionId) return; // 同一会话不处理\n prevSessionIdRef.current = sessionId;\n prevInitializedRef.current = false;\n userHasScrolledRef.current = false;\n }, [sessionId]);\n\n // 消息变化时自动滚动到底部(用户未手动上滚时)\n useEffect(() => {\n if (userHasScrolledRef.current) return;\n if (!messages.length) return;\n const el = listRef.current;\n if (el) {\n el.scrollTop = el.scrollHeight;\n }\n }, [loading, messages]);\n\n // loading 结束时(流式输出完成),操作栏(metaFooter)会渲染出来增加高度,\n // 需要延迟滚动到底部,确保操作栏可见\n const prevLoadingRef = useRef(loading);\n useEffect(() => {\n const wasLoading = prevLoadingRef.current;\n prevLoadingRef.current = loading;\n\n if (!wasLoading || loading) return; // 只在 loading true → false 时触发\n if (userHasScrolledRef.current) return;\n if (!messages.length) return;\n\n // 延迟等待操作栏 DOM 渲染完成后再滚动\n const timer = setTimeout(() => {\n const el = listRef.current;\n if (el) {\n el.scrollTop = el.scrollHeight;\n }\n }, 50);\n return () => clearTimeout(timer);\n }, [loading, messages]);\n\n // 处理滚动事件\n const handleScroll = useCallback(() => {\n const el = listRef.current;\n if (!el) return;\n const currentTop = el.scrollTop;\n\n if (currentTop < lastScrollTopRef.current) {\n userHasScrolledRef.current = true;\n }\n\n const isAtBottom =\n Math.abs(el.scrollHeight - currentTop - el.clientHeight) <=\n scrollThreshold;\n if (isAtBottom) {\n userHasScrolledRef.current = false;\n }\n\n lastScrollTopRef.current = currentTop;\n }, []);\n\n useEffect(() => {\n const listElement = listRef.current;\n if (!listElement) return;\n\n listElement.addEventListener(\"scroll\", handleScroll);\n return () => {\n listElement.removeEventListener(\"scroll\", handleScroll);\n };\n }, [handleScroll]);\n\n // ========== 消息分组逻辑 ==========\n const chatGroups = useMemo(() => {\n if (!enableGrouping) {\n // 不分组,每条消息独立\n return messages.map((msg) => ({\n id: msg.id,\n role: msg.role,\n msgs: [msg],\n invocationId: msg.invocationId,\n allFiles: msg.fileData || [],\n isLike: msg.isLike ?? 0,\n }));\n }\n\n const groups: ChatGroup[] = [];\n messages.forEach((msg) => {\n // 过滤 followup 消息\n if ((msg as any).role === \"followup\") return;\n\n const isRealUserQuery =\n msg.role === \"user\" && !msg.functionResponse && !msg.functionCall;\n const lastGroup = groups[groups.length - 1];\n const isLastGroupAgent = lastGroup?.role === \"bot\";\n\n if (isLastGroupAgent && !isRealUserQuery) {\n // 合并到上一个 bot 分组\n lastGroup.msgs.push(msg);\n if (msg.invocationId) lastGroup.invocationId = msg.invocationId;\n // 更新 isLike: 取最新的非0值,或保持当前值\n if (msg.isLike && msg.isLike !== 0) {\n lastGroup.isLike = msg.isLike;\n }\n } else {\n // 创建新分组\n groups.push({\n id: msg.id || `group-${groups.length}`,\n role: isRealUserQuery ? \"user\" : \"bot\",\n msgs: [msg],\n invocationId: msg.invocationId,\n allFiles: [],\n isLike: msg.isLike ?? 0,\n });\n }\n });\n\n // 合并文件\n groups.forEach((g) => {\n g.allFiles = g.msgs.reduce(\n (acc, m) => [...acc, ...(m.fileData || [])],\n [] as any[],\n );\n });\n\n return groups;\n }, [messages, enableGrouping]);\n\n // ========== 渲染 Bot 消息组 ==========\n const renderBotGroup = useCallback(\n (\n group: ChatGroup,\n isLastGroup: boolean,\n renderFunctionCall?: XAdkChatbotProps[\"renderFunctionCall\"],\n ) => {\n const { msgs, allFiles } = group;\n\n if (!enableProcessParsing) {\n // 不解析 process,简单渲染\n return (\n <div key={group.id} className={styles.botMsg}>\n {msgs.map((msg, i) => {\n if (msg.text) {\n return (\n <MarkdownRender\n key={`${msg.id}-${i}`}\n text={msg.text}\n onFileClick={onFileClick}\n />\n );\n }\n if (msg.functionCall) {\n return (\n renderFunctionCall?.(msg) ?? (\n <FunctionCallRender\n key={`${msg.id}-${i}`}\n msg={msg}\n showDetail={showFnCallDetail}\n onConfirm={onConfirm}\n kind={resolveToolKind(msg.functionCall?.name, msg)}\n renderApproval={mergedStrategies.renderApproval}\n renderHandoff={mergedStrategies.renderHandoff}\n />\n )\n );\n }\n return null;\n })}\n </div>\n );\n }\n\n // ========== 解析 Process 内容 ==========\n\n // 1. 合并工具调用\n const mergedToolMap = new Map<string, IMessage>();\n msgs.forEach((msg) => {\n if (msg.functionCall) {\n const callId = msg.functionCall.id || \"\";\n if (!mergedToolMap.has(callId)) {\n mergedToolMap.set(callId, { ...msg });\n } else {\n mergedToolMap.set(callId, {\n ...(mergedToolMap.get(callId) ?? {}),\n ...msg,\n });\n }\n } else if (msg.functionResponse) {\n const callId = msg.functionResponse.id || \"\";\n if (mergedToolMap.has(callId)) {\n const tool = mergedToolMap.get(callId);\n if (tool) tool.functionResponse = msg.functionResponse;\n } else {\n mergedToolMap.set(callId, {\n ...msg,\n functionCall: {\n id: callId,\n name: msg.functionResponse.name || \"Unknown\",\n args: {},\n },\n });\n }\n }\n });\n\n // 2. 解析文本消息中的 process 内容\n type RenderNode =\n | { type: \"text\"; content: string; key: string }\n | { type: \"process\"; items: ThoughtChainItemType[]; key: string };\n\n const nodes: RenderNode[] = [];\n let currentProcessItems: ThoughtChainItemType[] = [];\n const processedToolIds = new Set<string>();\n\n const flushProcessItems = () => {\n if (currentProcessItems.length > 0) {\n nodes.push({\n type: \"process\",\n items: [...currentProcessItems],\n key: `process-${nodes.length}`,\n });\n currentProcessItems = [];\n }\n };\n\n msgs.forEach((msg) => {\n // 处理工具调用\n if (msg.functionCall) {\n const callId = msg.functionCall.id || \"\";\n if (!processedToolIds.has(callId)) {\n const mergedMsg = mergedToolMap.get(callId);\n if (mergedMsg) {\n currentProcessItems.push({\n type: \"tool\",\n key: `tool-${callId}`,\n content: \"\",\n msg: mergedMsg,\n });\n processedToolIds.add(callId);\n }\n }\n }\n // 处理文本消息\n else if (msg.text && !msg.functionResponse) {\n const parts = parseProcessMessage(msg.text, parseOptions as any);\n\n parts.forEach((part, partIdx) => {\n // process 内容放入 currentProcessItems\n if (\n [\n \"planning\",\n \"replanning\",\n \"reasoning\",\n \"action_log\",\n \"process_text\",\n ].includes(part.type)\n ) {\n const titleMap: Record<string, string> = {\n planning: \"任务规划\",\n replanning: \"重新规划\",\n reasoning: \"推理分析\",\n action_log: \"行动记录\",\n process_text: \"过程分析\",\n };\n\n currentProcessItems.push({\n type: \"text\",\n key: `${msg.id}-${partIdx}`,\n content: part.content,\n title: titleMap[part.type] || \"分析\",\n });\n }\n // 普通文本内容\n else {\n flushProcessItems();\n if (part.content.trim()) {\n const lastNode = nodes[nodes.length - 1];\n if (lastNode?.type === \"text\") {\n // 合并到上一个文本节点\n lastNode.content += \"\\n\\n\" + part.content;\n } else {\n nodes.push({\n type: \"text\",\n content: part.content,\n key: `text-${msg.id}-${partIdx}`,\n });\n }\n }\n }\n });\n }\n });\n\n // 最后flush一次\n flushProcessItems();\n\n // 3. 准备操作栏数据\n const fullTextToCopy = msgs\n .filter((m) => !m.functionCall && !m.functionResponse)\n .map((m) => m.text || \"\")\n .join(\"\");\n\n const lastBotMsg = msgs[msgs.length - 1];\n const hasProcess = nodes.some((n) => n.type === \"process\");\n const isGroupLoading = loading && isLastGroup;\n const actionProps = { message: group, isLastBotMsg: isLastGroup };\n const actionExtraNode = actionsExtra?.(actionProps);\n\n // 4. 渲染\n const lastProcessIdx = nodes.findLastIndex((n) => n.type === \"process\");\n return (\n <div key={group.id} className={styles.botMsg}>\n {nodes.map((node, idx) => {\n if (node.type === \"process\") {\n // 只有最后一个 process node 跟随 loading 状态,已完成的思维链不应显示 loading\n const isLastProcess = idx === lastProcessIdx;\n return (\n <XAdkThoughtChain\n key={node.key}\n loading={isLastProcess && isGroupLoading}\n title=\"思维链已完成\"\n items={node.items}\n showFnCallDetail={showFnCallDetail}\n onConfirm={onConfirm}\n defaultOpen={isLastProcess && isGroupLoading}\n renderFunctionCall={renderFunctionCall}\n toolKindResolver={(name) => resolveToolKind(name)}\n strategies={mergedStrategies}\n />\n );\n }\n\n // 文本节点\n // const showBadge =\n // hasProcess && nodes.findIndex((n) => n.type === \"text\") === idx;\n return (\n <div key={node.key}>\n {/* {showBadge && (\n <div className={styles.successBadge}>\n <CheckCircleFilled /> 已完成所有规划任务\n </div>\n )} */}\n <MarkdownRender\n text={node.content}\n onFileClick={onFileClick}\n />\n </div>\n );\n })}\n\n {/* 文件展示 */}\n {allFiles.length > 0 && (\n <div className={styles.fileSection}>\n <div className={styles.fileHeader}>\n <span>生成文件 ({allFiles.length})</span>\n </div>\n <div style={{ display: \"flex\", flexWrap: \"wrap\", gap: \"8px\" }}>\n {allFiles.map((file, index) => (\n <FileGallery\n key={index}\n file={file}\n onClick={onFileClick}\n />\n ))}\n </div>\n </div>\n )}\n\n {/* 操作栏 */}\n {!isGroupLoading &&\n (actions ||\n showRetry ||\n showCopy ||\n showLog ||\n actionExtraNode) && (\n <div className={styles.metaFooter}>\n {actions ? (\n actions(actionProps)\n ) : (\n <Flex gap={16} className={styles.actionIcons}>\n {showRetry && isLastGroup && (\n <Tooltip title=\"重新生成\">\n <ReloadOutlined onClick={onRetry} />\n </Tooltip>\n )}\n {showCopy && (\n <Tooltip title=\"复制内容\">\n <CopyOutlined\n onClick={() => {\n copy(fullTextToCopy);\n antdMessage.success(\"复制成功\");\n onCopy?.(fullTextToCopy);\n }}\n />\n </Tooltip>\n )}\n {showLog && lastBotMsg?.invocationId && (\n <Tooltip title=\"查看日志\">\n <InfoCircleOutlined\n onClick={() =>\n onShowLog?.(\n lastBotMsg.invocationId!,\n lastBotMsg.timestamp,\n )\n }\n />\n </Tooltip>\n )}\n </Flex>\n )}\n {actionExtraNode}\n </div>\n )}\n </div>\n );\n },\n [\n enableProcessParsing,\n parseOptions,\n parseProcessMessage,\n showFnCallDetail,\n onConfirm,\n loading,\n showRetry,\n showCopy,\n showLog,\n onRetry,\n onCopy,\n onShowLog,\n actions,\n actionsExtra,\n onFileClick,\n styles,\n resolveToolKind,\n mergedStrategies,\n ],\n );\n\n // ========== 渲染用户消息组 ==========\n const renderUserGroup = useCallback(\n (group: ChatGroup) => {\n return (\n <div key={group.id} className={styles.userMsg}>\n {group.msgs.map((m, i) => (\n <div key={m.id || i} className={styles.userContainer}>\n {/* 文件展示 */}\n {m.fileData && m.fileData.length > 0 && (\n <>\n {m.fileData.map((file, index) => (\n <FileGallery\n key={index}\n file={file}\n align=\"left\"\n style={{ marginBottom: \"16px\" }}\n onClick={onFileClick}\n />\n ))}\n </>\n )}\n {/* 文本展示 */}\n {m.text && <div className={styles.card}>{m.text}</div>}\n </div>\n ))}\n </div>\n );\n },\n [styles, onFileClick],\n );\n\n // ========== 空状态 ==========\n\n // ========== 渲染建议问题 ==========\n const renderSuggestions = () => {\n if (!suggestions || suggestions.length === 0) return null;\n\n return (\n <div className={styles.suggestionWrapper}>\n {suggestions.map((item) => (\n <div key={item} className={styles.suggestion}>\n <div className={styles.suggestContent}>\n <Button\n type=\"text\"\n icon={<SwapRightOutlined />}\n iconPosition=\"end\"\n onClick={() => {\n if (!item) return;\n onSuggest?.(item);\n }}\n style={{\n whiteSpace: \"normal\",\n height: \"auto\",\n wordWrap: \"break-word\",\n textAlign: \"left\",\n padding: \"4px 15px\",\n lineHeight: \"1.5\",\n }}\n >\n {item}\n </Button>\n </div>\n </div>\n ))}\n </div>\n );\n };\n\n // 空状态判断\n const isEmpty =\n messages.length === 0 &&\n !prologue &&\n (!suggestions || suggestions.length === 0);\n\n return (\n <div className={clsx(styles.wrapper, className)} style={style}>\n <div className={styles.list} ref={listRef}>\n {/* 空状态 */}\n {isEmpty && empty && (\n <div className={styles.emptyWrapper}>\n {typeof empty === \"function\" ? empty() : empty}\n </div>\n )}\n\n {/* 开场白 */}\n {prologue && (\n <div className={styles.prologue}>\n <MarkdownRender text={prologue} onFileClick={onFileClick} />\n </div>\n )}\n\n {/* 消息列表 */}\n {chatGroups.map((group, idx) =>\n group.role === \"user\"\n ? renderUserGroup(group)\n : renderBotGroup(\n group,\n idx === chatGroups.length - 1,\n renderFunctionCall,\n ),\n )}\n\n {/* 建议问题 */}\n {renderSuggestions()}\n\n <div ref={messagesEndRef} />\n </div>\n </div>\n );\n },\n);\n\nXAdkChatbot.displayName = \"XAdkChatbot\";\n\nexport default XAdkChatbot;\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAOO;AACP,kBAA8D;AAC9D,kBAAiB;AACjB,mBAMO;AACP,+BAAiB;AACjB,oBAA0B;AAC1B,4BAA2B;AAC3B,gCAA+B;AAC/B,yBAAwB;AACxB,8BAA6B;AAC7B,mBAAkC;AAClC,uBAAoC;AAQpC,IAAAA,6BAAwC;AAqQpB;AAnQpB,IAAM,kBAAkB;AAYxB,IAAM,kBAAc;AAAA,EAClB,CACE;AAAA,IACE,UAAU;AAAA,IACV;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAAA,IAEA,iBAAiB;AAAA,IACjB,uBAAuB;AAAA,IACvB;AAAA,IACA,cAAc;AAAA,IACd;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,GACA,QACG;AACH,UAAM,aAAS,yBAAU;AACzB,UAAM,cAAU,qBAAuB,IAAI;AAC3C,UAAM,uBAAmB,qBAAO,CAAC;AACjC,UAAM,yBAAqB,qBAAO,KAAK;AACvC,UAAM,qBAAiB,qBAAuB,IAAI;AAClD,UAAM,yBAAqB,qBAAO,KAAK;AACvC,UAAM,uBAAmB,qBAAO,SAAS;AAGzC,UAAM,qBAAiB,0BAAY,CAAC,WAA2B,WAAW;AA1F9E;AA2FM,2BAAe,YAAf,mBAAwB,eAAe,EAAE,SAAS;AAAA,IACpD,GAAG,CAAC,CAAC;AACL,0CAAoB,KAAK,OAAO,EAAE,eAAe,IAAI,CAAC,cAAc,CAAC;AACrE,UAAM,uBAAmB;AAAA,MACvB,UAAM,sCAAoB,QAAQ,UAAU;AAAA,MAC5C,CAAC,QAAQ,UAAU;AAAA,IACrB;AACA,UAAM,sBAAkB;AAAA,MACtB,CAAC,MAAe,QAAgB;AAnGtC;AAoGQ,qEAAmB,YACnB,sBAAiB,oBAAjB,0CAAmC,EAAE,MAAM,IAAI,WAC/C,oDAAwB,IAAI;AAAA;AAAA,MAC9B,CAAC,kBAAkB,gBAAgB;AAAA,IACrC;AACA,UAAM,sBACJ,iBAAiB,uBAAuB;AAG1C,gCAAU,MAAM;AACd,UAAI,CAAC;AAAa;AAClB,UAAI,CAAC,SAAS;AAAQ;AACtB,UAAI,mBAAmB;AAAS;AAChC,yBAAmB,UAAU;AAE7B,YAAM,KAAK,QAAQ;AACnB,UAAI,CAAC;AAAI;AAIT,UAAI;AACJ,YAAM,WAAW,MAAM;AAzH7B;AA0HQ,6BAAe,YAAf,mBAAwB,eAAe,EAAE,UAAU,OAAO;AAAA,MAC5D;AAEA,YAAM,WAAW,IAAI,iBAAiB,MAAM;AAC1C,qBAAa,WAAW;AACxB,sBAAc,WAAW,UAAU,EAAE;AAAA,MACvC,CAAC;AAED,eAAS,QAAQ,IAAI;AAAA,QACnB,WAAW;AAAA,QACX,SAAS;AAAA,QACT,eAAe;AAAA,MACjB,CAAC;AAGD,eAAS;AAET,YAAM,WAAW,WAAW,MAAM;AAChC,iBAAS,WAAW;AACpB,iBAAS;AAAA,MACX,GAAG,GAAG;AAEN,aAAO,MAAM;AACX,qBAAa,WAAW;AACxB,qBAAa,QAAQ;AACrB,iBAAS,WAAW;AAAA,MACtB;AAAA,IACF,GAAG,CAAC,aAAa,QAAQ,CAAC;AAG1B,gCAAU,MAAM;AACd,UAAI,cAAc;AAAW;AAC7B,UAAI,iBAAiB,YAAY;AAAW;AAC5C,uBAAiB,UAAU;AAC3B,yBAAmB,UAAU;AAC7B,yBAAmB,UAAU;AAAA,IAC/B,GAAG,CAAC,SAAS,CAAC;AAGd,gCAAU,MAAM;AACd,UAAI,mBAAmB;AAAS;AAChC,UAAI,CAAC,SAAS;AAAQ;AACtB,YAAM,KAAK,QAAQ;AACnB,UAAI,IAAI;AACN,WAAG,YAAY,GAAG;AAAA,MACpB;AAAA,IACF,GAAG,CAAC,SAAS,QAAQ,CAAC;AAItB,UAAM,qBAAiB,qBAAO,OAAO;AACrC,gCAAU,MAAM;AACd,YAAM,aAAa,eAAe;AAClC,qBAAe,UAAU;AAEzB,UAAI,CAAC,cAAc;AAAS;AAC5B,UAAI,mBAAmB;AAAS;AAChC,UAAI,CAAC,SAAS;AAAQ;AAGtB,YAAM,QAAQ,WAAW,MAAM;AAC7B,cAAM,KAAK,QAAQ;AACnB,YAAI,IAAI;AACN,aAAG,YAAY,GAAG;AAAA,QACpB;AAAA,MACF,GAAG,EAAE;AACL,aAAO,MAAM,aAAa,KAAK;AAAA,IACjC,GAAG,CAAC,SAAS,QAAQ,CAAC;AAGtB,UAAM,mBAAe,0BAAY,MAAM;AACrC,YAAM,KAAK,QAAQ;AACnB,UAAI,CAAC;AAAI;AACT,YAAM,aAAa,GAAG;AAEtB,UAAI,aAAa,iBAAiB,SAAS;AACzC,2BAAmB,UAAU;AAAA,MAC/B;AAEA,YAAM,aACJ,KAAK,IAAI,GAAG,eAAe,aAAa,GAAG,YAAY,KACvD;AACF,UAAI,YAAY;AACd,2BAAmB,UAAU;AAAA,MAC/B;AAEA,uBAAiB,UAAU;AAAA,IAC7B,GAAG,CAAC,CAAC;AAEL,gCAAU,MAAM;AACd,YAAM,cAAc,QAAQ;AAC5B,UAAI,CAAC;AAAa;AAElB,kBAAY,iBAAiB,UAAU,YAAY;AACnD,aAAO,MAAM;AACX,oBAAY,oBAAoB,UAAU,YAAY;AAAA,MACxD;AAAA,IACF,GAAG,CAAC,YAAY,CAAC;AAGjB,UAAM,iBAAa,sBAAQ,MAAM;AAC/B,UAAI,CAAC,gBAAgB;AAEnB,eAAO,SAAS,IAAI,CAAC,SAAS;AAAA,UAC5B,IAAI,IAAI;AAAA,UACR,MAAM,IAAI;AAAA,UACV,MAAM,CAAC,GAAG;AAAA,UACV,cAAc,IAAI;AAAA,UAClB,UAAU,IAAI,YAAY,CAAC;AAAA,UAC3B,QAAQ,IAAI,UAAU;AAAA,QACxB,EAAE;AAAA,MACJ;AAEA,YAAM,SAAsB,CAAC;AAC7B,eAAS,QAAQ,CAAC,QAAQ;AAExB,YAAK,IAAY,SAAS;AAAY;AAEtC,cAAM,kBACJ,IAAI,SAAS,UAAU,CAAC,IAAI,oBAAoB,CAAC,IAAI;AACvD,cAAM,YAAY,OAAO,OAAO,SAAS,CAAC;AAC1C,cAAM,oBAAmB,uCAAW,UAAS;AAE7C,YAAI,oBAAoB,CAAC,iBAAiB;AAExC,oBAAU,KAAK,KAAK,GAAG;AACvB,cAAI,IAAI;AAAc,sBAAU,eAAe,IAAI;AAEnD,cAAI,IAAI,UAAU,IAAI,WAAW,GAAG;AAClC,sBAAU,SAAS,IAAI;AAAA,UACzB;AAAA,QACF,OAAO;AAEL,iBAAO,KAAK;AAAA,YACV,IAAI,IAAI,MAAM,SAAS,OAAO;AAAA,YAC9B,MAAM,kBAAkB,SAAS;AAAA,YACjC,MAAM,CAAC,GAAG;AAAA,YACV,cAAc,IAAI;AAAA,YAClB,UAAU,CAAC;AAAA,YACX,QAAQ,IAAI,UAAU;AAAA,UACxB,CAAC;AAAA,QACH;AAAA,MACF,CAAC;AAGD,aAAO,QAAQ,CAAC,MAAM;AACpB,UAAE,WAAW,EAAE,KAAK;AAAA,UAClB,CAAC,KAAK,MAAM,CAAC,GAAG,KAAK,GAAI,EAAE,YAAY,CAAC,CAAE;AAAA,UAC1C,CAAC;AAAA,QACH;AAAA,MACF,CAAC;AAED,aAAO;AAAA,IACT,GAAG,CAAC,UAAU,cAAc,CAAC;AAG7B,UAAM,qBAAiB;AAAA,MACrB,CACE,OACA,aACAC,wBACG;AACH,cAAM,EAAE,MAAM,SAAS,IAAI;AAE3B,YAAI,CAAC,sBAAsB;AAEzB,iBACE,4CAAC,SAAmB,WAAW,OAAO,QACnC,eAAK,IAAI,CAAC,KAAK,MAAM;AAlSpC;AAmSgB,gBAAI,IAAI,MAAM;AACZ,qBACE;AAAA,gBAAC,sBAAAC;AAAA,gBAAA;AAAA,kBAEC,MAAM,IAAI;AAAA,kBACV;AAAA;AAAA,gBAFK,GAAG,IAAI,MAAM;AAAA,cAGpB;AAAA,YAEJ;AACA,gBAAI,IAAI,cAAc;AACpB,sBACED,uBAAA,gBAAAA,oBAAqB,SACnB;AAAA,gBAAC,0BAAAE;AAAA,gBAAA;AAAA,kBAEC;AAAA,kBACA,YAAY;AAAA,kBACZ;AAAA,kBACA,MAAM,iBAAgB,SAAI,iBAAJ,mBAAkB,MAAM,GAAG;AAAA,kBACjD,gBAAgB,iBAAiB;AAAA,kBACjC,eAAe,iBAAiB;AAAA;AAAA,gBAN3B,GAAG,IAAI,MAAM;AAAA,cAOpB;AAAA,YAGN;AACA,mBAAO;AAAA,UACT,CAAC,KA3BO,MAAM,EA4BhB;AAAA,QAEJ;AAKA,cAAM,gBAAgB,oBAAI,IAAsB;AAChD,aAAK,QAAQ,CAAC,QAAQ;AACpB,cAAI,IAAI,cAAc;AACpB,kBAAM,SAAS,IAAI,aAAa,MAAM;AACtC,gBAAI,CAAC,cAAc,IAAI,MAAM,GAAG;AAC9B,4BAAc,IAAI,QAAQ,EAAE,GAAG,IAAI,CAAC;AAAA,YACtC,OAAO;AACL,4BAAc,IAAI,QAAQ;AAAA,gBACxB,GAAI,cAAc,IAAI,MAAM,KAAK,CAAC;AAAA,gBAClC,GAAG;AAAA,cACL,CAAC;AAAA,YACH;AAAA,UACF,WAAW,IAAI,kBAAkB;AAC/B,kBAAM,SAAS,IAAI,iBAAiB,MAAM;AAC1C,gBAAI,cAAc,IAAI,MAAM,GAAG;AAC7B,oBAAM,OAAO,cAAc,IAAI,MAAM;AACrC,kBAAI;AAAM,qBAAK,mBAAmB,IAAI;AAAA,YACxC,OAAO;AACL,4BAAc,IAAI,QAAQ;AAAA,gBACxB,GAAG;AAAA,gBACH,cAAc;AAAA,kBACZ,IAAI;AAAA,kBACJ,MAAM,IAAI,iBAAiB,QAAQ;AAAA,kBACnC,MAAM,CAAC;AAAA,gBACT;AAAA,cACF,CAAC;AAAA,YACH;AAAA,UACF;AAAA,QACF,CAAC;AAOD,cAAM,QAAsB,CAAC;AAC7B,YAAI,sBAA8C,CAAC;AACnD,cAAM,mBAAmB,oBAAI,IAAY;AAEzC,cAAM,oBAAoB,MAAM;AAC9B,cAAI,oBAAoB,SAAS,GAAG;AAClC,kBAAM,KAAK;AAAA,cACT,MAAM;AAAA,cACN,OAAO,CAAC,GAAG,mBAAmB;AAAA,cAC9B,KAAK,WAAW,MAAM;AAAA,YACxB,CAAC;AACD,kCAAsB,CAAC;AAAA,UACzB;AAAA,QACF;AAEA,aAAK,QAAQ,CAAC,QAAQ;AAEpB,cAAI,IAAI,cAAc;AACpB,kBAAM,SAAS,IAAI,aAAa,MAAM;AACtC,gBAAI,CAAC,iBAAiB,IAAI,MAAM,GAAG;AACjC,oBAAM,YAAY,cAAc,IAAI,MAAM;AAC1C,kBAAI,WAAW;AACb,oCAAoB,KAAK;AAAA,kBACvB,MAAM;AAAA,kBACN,KAAK,QAAQ;AAAA,kBACb,SAAS;AAAA,kBACT,KAAK;AAAA,gBACP,CAAC;AACD,iCAAiB,IAAI,MAAM;AAAA,cAC7B;AAAA,YACF;AAAA,UACF,WAES,IAAI,QAAQ,CAAC,IAAI,kBAAkB;AAC1C,kBAAM,QAAQ,oBAAoB,IAAI,MAAM,YAAmB;AAE/D,kBAAM,QAAQ,CAAC,MAAM,YAAY;AAE/B,kBACE;AAAA,gBACE;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA,cACF,EAAE,SAAS,KAAK,IAAI,GACpB;AACA,sBAAM,WAAmC;AAAA,kBACvC,UAAU;AAAA,kBACV,YAAY;AAAA,kBACZ,WAAW;AAAA,kBACX,YAAY;AAAA,kBACZ,cAAc;AAAA,gBAChB;AAEA,oCAAoB,KAAK;AAAA,kBACvB,MAAM;AAAA,kBACN,KAAK,GAAG,IAAI,MAAM;AAAA,kBAClB,SAAS,KAAK;AAAA,kBACd,OAAO,SAAS,KAAK,IAAI,KAAK;AAAA,gBAChC,CAAC;AAAA,cACH,OAEK;AACH,kCAAkB;AAClB,oBAAI,KAAK,QAAQ,KAAK,GAAG;AACvB,wBAAM,WAAW,MAAM,MAAM,SAAS,CAAC;AACvC,uBAAI,qCAAU,UAAS,QAAQ;AAE7B,6BAAS,WAAW,SAAS,KAAK;AAAA,kBACpC,OAAO;AACL,0BAAM,KAAK;AAAA,sBACT,MAAM;AAAA,sBACN,SAAS,KAAK;AAAA,sBACd,KAAK,QAAQ,IAAI,MAAM;AAAA,oBACzB,CAAC;AAAA,kBACH;AAAA,gBACF;AAAA,cACF;AAAA,YACF,CAAC;AAAA,UACH;AAAA,QACF,CAAC;AAGD,0BAAkB;AAGlB,cAAM,iBAAiB,KACpB,OAAO,CAAC,MAAM,CAAC,EAAE,gBAAgB,CAAC,EAAE,gBAAgB,EACpD,IAAI,CAAC,MAAM,EAAE,QAAQ,EAAE,EACvB,KAAK,EAAE;AAEV,cAAM,aAAa,KAAK,KAAK,SAAS,CAAC;AACvC,cAAM,aAAa,MAAM,KAAK,CAAC,MAAM,EAAE,SAAS,SAAS;AACzD,cAAM,iBAAiB,WAAW;AAClC,cAAM,cAAc,EAAE,SAAS,OAAO,cAAc,YAAY;AAChE,cAAM,kBAAkB,6CAAe;AAGvC,cAAM,iBAAiB,MAAM,cAAc,CAAC,MAAM,EAAE,SAAS,SAAS;AACtE,eACE,6CAAC,SAAmB,WAAW,OAAO,QACnC;AAAA,gBAAM,IAAI,CAAC,MAAM,QAAQ;AACxB,gBAAI,KAAK,SAAS,WAAW;AAE3B,oBAAM,gBAAgB,QAAQ;AAC9B,qBACE;AAAA,gBAAC,wBAAAC;AAAA,gBAAA;AAAA,kBAEC,SAAS,iBAAiB;AAAA,kBAC1B,OAAM;AAAA,kBACN,OAAO,KAAK;AAAA,kBACZ;AAAA,kBACA;AAAA,kBACA,aAAa,iBAAiB;AAAA,kBAC9B,oBAAoBH;AAAA,kBACpB,kBAAkB,CAAC,SAAS,gBAAgB,IAAI;AAAA,kBAChD,YAAY;AAAA;AAAA,gBATP,KAAK;AAAA,cAUZ;AAAA,YAEJ;AAKA,mBACE,4CAAC,SAMC;AAAA,cAAC,sBAAAC;AAAA,cAAA;AAAA,gBACC,MAAM,KAAK;AAAA,gBACX;AAAA;AAAA,YACF,KATQ,KAAK,GAUf;AAAA,UAEJ,CAAC;AAAA,UAGA,SAAS,SAAS,KACjB,6CAAC,SAAI,WAAW,OAAO,aACrB;AAAA,wDAAC,SAAI,WAAW,OAAO,YACrB,uDAAC,UAAK;AAAA;AAAA,cAAO,SAAS;AAAA,cAAO;AAAA,eAAC,GAChC;AAAA,YACA,4CAAC,SAAI,OAAO,EAAE,SAAS,QAAQ,UAAU,QAAQ,KAAK,MAAM,GACzD,mBAAS,IAAI,CAAC,MAAM,UACnB;AAAA,cAAC,mBAAAG;AAAA,cAAA;AAAA,gBAEC;AAAA,gBACA,SAAS;AAAA;AAAA,cAFJ;AAAA,YAGP,CACD,GACH;AAAA,aACF;AAAA,UAID,CAAC,mBACC,WACC,aACA,YACA,WACA,oBACA,6CAAC,SAAI,WAAW,OAAO,YACpB;AAAA,sBACC,QAAQ,WAAW,IAEnB,6CAAC,oBAAK,KAAK,IAAI,WAAW,OAAO,aAC9B;AAAA,2BAAa,eACZ,4CAAC,uBAAQ,OAAM,QACb,sDAAC,+BAAe,SAAS,SAAS,GACpC;AAAA,cAED,YACC,4CAAC,uBAAQ,OAAM,QACb;AAAA,gBAAC;AAAA;AAAA,kBACC,SAAS,MAAM;AACb,iDAAAC,SAAK,cAAc;AACnB,gCAAAC,QAAY,QAAQ,MAAM;AAC1B,qDAAS;AAAA,kBACX;AAAA;AAAA,cACF,GACF;AAAA,cAED,YAAW,yCAAY,iBACtB,4CAAC,uBAAQ,OAAM,QACb;AAAA,gBAAC;AAAA;AAAA,kBACC,SAAS,MACP;AAAA,oBACE,WAAW;AAAA,oBACX,WAAW;AAAA;AAAA;AAAA,cAGjB,GACF;AAAA,eAEJ;AAAA,YAED;AAAA,aACH;AAAA,aApGI,MAAM,EAsGhB;AAAA,MAEJ;AAAA,MACA;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAGA,UAAM,sBAAkB;AAAA,MACtB,CAAC,UAAqB;AACpB,eACE,4CAAC,SAAmB,WAAW,OAAO,SACnC,gBAAM,KAAK,IAAI,CAAC,GAAG,MAClB,6CAAC,SAAoB,WAAW,OAAO,eAEpC;AAAA,YAAE,YAAY,EAAE,SAAS,SAAS,KACjC,2EACG,YAAE,SAAS,IAAI,CAAC,MAAM,UACrB;AAAA,YAAC,mBAAAF;AAAA,YAAA;AAAA,cAEC;AAAA,cACA,OAAM;AAAA,cACN,OAAO,EAAE,cAAc,OAAO;AAAA,cAC9B,SAAS;AAAA;AAAA,YAJJ;AAAA,UAKP,CACD,GACH;AAAA,UAGD,EAAE,QAAQ,4CAAC,SAAI,WAAW,OAAO,MAAO,YAAE,MAAK;AAAA,aAhBxC,EAAE,MAAM,CAiBlB,CACD,KApBO,MAAM,EAqBhB;AAAA,MAEJ;AAAA,MACA,CAAC,QAAQ,WAAW;AAAA,IACtB;AAKA,UAAM,oBAAoB,MAAM;AAC9B,UAAI,CAAC,eAAe,YAAY,WAAW;AAAG,eAAO;AAErD,aACE,4CAAC,SAAI,WAAW,OAAO,mBACpB,sBAAY,IAAI,CAAC,SAChB,4CAAC,SAAe,WAAW,OAAO,YAChC,sDAAC,SAAI,WAAW,OAAO,gBACrB;AAAA,QAAC;AAAA;AAAA,UACC,MAAK;AAAA,UACL,MAAM,4CAAC,kCAAkB;AAAA,UACzB,cAAa;AAAA,UACb,SAAS,MAAM;AACb,gBAAI,CAAC;AAAM;AACX,mDAAY;AAAA,UACd;AAAA,UACA,OAAO;AAAA,YACL,YAAY;AAAA,YACZ,QAAQ;AAAA,YACR,UAAU;AAAA,YACV,WAAW;AAAA,YACX,SAAS;AAAA,YACT,YAAY;AAAA,UACd;AAAA,UAEC;AAAA;AAAA,MACH,GACF,KArBQ,IAsBV,CACD,GACH;AAAA,IAEJ;AAGA,UAAM,UACJ,SAAS,WAAW,KACpB,CAAC,aACA,CAAC,eAAe,YAAY,WAAW;AAE1C,WACE,4CAAC,SAAI,eAAW,YAAAG,SAAK,OAAO,SAAS,SAAS,GAAG,OAC/C,uDAAC,SAAI,WAAW,OAAO,MAAM,KAAK,SAE/B;AAAA,iBAAW,SACV,4CAAC,SAAI,WAAW,OAAO,cACpB,iBAAO,UAAU,aAAa,MAAM,IAAI,OAC3C;AAAA,MAID,YACC,4CAAC,SAAI,WAAW,OAAO,UACrB,sDAAC,sBAAAN,SAAA,EAAe,MAAM,UAAU,aAA0B,GAC5D;AAAA,MAID,WAAW;AAAA,QAAI,CAAC,OAAO,QACtB,MAAM,SAAS,SACX,gBAAgB,KAAK,IACrB;AAAA,UACE;AAAA,UACA,QAAQ,WAAW,SAAS;AAAA,UAC5B;AAAA,QACF;AAAA,MACN;AAAA,MAGC,kBAAkB;AAAA,MAEnB,4CAAC,SAAI,KAAK,gBAAgB;AAAA,OAC5B,GACF;AAAA,EAEJ;AACF;AAEA,YAAY,cAAc;AAE1B,IAAO,sBAAQ;",
|
|
6
6
|
"names": ["import_FunctionCallRender", "renderFunctionCall", "MarkdownRender", "FunctionCallRender", "XAdkThoughtChain", "FileGallery", "copy", "antdMessage", "clsx"]
|
|
7
7
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React from
|
|
1
|
+
import React from "react";
|
|
2
2
|
import type { XAdkSenderProps, XAdkSenderHandle } from "../../../types";
|
|
3
3
|
/**
|
|
4
4
|
* XAdkProvider.Sender - 输入框组件
|
|
@@ -17,7 +17,7 @@ import type { XAdkSenderProps, XAdkSenderHandle } from "../../../types";
|
|
|
17
17
|
* </XAdkProvider>
|
|
18
18
|
* ```
|
|
19
19
|
*/
|
|
20
|
-
export interface XAdkSenderCompoundProps extends Partial<Omit<XAdkSenderProps,
|
|
20
|
+
export interface XAdkSenderCompoundProps extends Partial<Omit<XAdkSenderProps, "loading" | "onSubmit" | "onStop" | "onClear">> {
|
|
21
21
|
/** 额外的样式 */
|
|
22
22
|
style?: React.CSSProperties;
|
|
23
23
|
/** 额外的类名 */
|
|
@@ -34,26 +34,29 @@ __export(Sender_exports, {
|
|
|
34
34
|
module.exports = __toCommonJS(Sender_exports);
|
|
35
35
|
var import_react = require("react");
|
|
36
36
|
var import_XAdkSender = __toESM(require("../../XAdkSender"));
|
|
37
|
-
var
|
|
37
|
+
var import_ChatSenderStateContext = require("../context/ChatSenderStateContext");
|
|
38
38
|
var import_ChatActionContext = require("../context/ChatActionContext");
|
|
39
39
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
40
|
-
var Sender = (0, import_react.forwardRef)(
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
}
|
|
40
|
+
var Sender = (0, import_react.forwardRef)(
|
|
41
|
+
(props, ref) => {
|
|
42
|
+
const { loading, uploadRequest, senderValue, setSenderValue } = (0, import_ChatSenderStateContext.useChatSenderState)();
|
|
43
|
+
const { chat, stopChat, clearChat } = (0, import_ChatActionContext.useChatActions)();
|
|
44
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
45
|
+
import_XAdkSender.default,
|
|
46
|
+
{
|
|
47
|
+
ref,
|
|
48
|
+
...props,
|
|
49
|
+
loading,
|
|
50
|
+
value: senderValue,
|
|
51
|
+
onChange: setSenderValue,
|
|
52
|
+
onSubmit: chat,
|
|
53
|
+
onStop: stopChat,
|
|
54
|
+
onClear: clearChat,
|
|
55
|
+
uploadRequest
|
|
56
|
+
}
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
);
|
|
57
60
|
Sender.displayName = "XAdkProvider.Sender";
|
|
58
61
|
var Sender_default = Sender;
|
|
59
62
|
//# sourceMappingURL=Sender.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/components/XAdkProvider/compound/Sender.tsx"],
|
|
4
|
-
"sourcesContent": ["import React, { forwardRef } from
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAAkC;AAClC,wBAAuB;AACvB,
|
|
4
|
+
"sourcesContent": ["import React, { forwardRef } from \"react\";\nimport XAdkSender from \"@/components/XAdkSender\";\nimport { useChatSenderState } from \"../context/ChatSenderStateContext\";\nimport { useChatActions } from \"../context/ChatActionContext\";\nimport type { XAdkSenderProps, XAdkSenderHandle } from \"@/types\";\n\n/**\n * XAdkProvider.Sender - 输入框组件\n *\n * 从 Context 获取聊天动作并提供输入界面\n * 基于 XAdkSender 组件实现\n *\n * @example\n * ```tsx\n * <XAdkProvider url=\"...\" token=\"...\">\n * <XAdkProvider.Sender\n * allowUpload={true}\n * clearBtnShow={true}\n * uploadRequest={myUploadHandler}\n * />\n * </XAdkProvider>\n * ```\n */\nexport interface XAdkSenderCompoundProps extends Partial<\n Omit<XAdkSenderProps, \"loading\" | \"onSubmit\" | \"onStop\" | \"onClear\">\n> {\n /** 额外的样式 */\n style?: React.CSSProperties;\n /** 额外的类名 */\n className?: string;\n}\n\nconst Sender = forwardRef<XAdkSenderHandle, XAdkSenderCompoundProps>(\n (props, ref) => {\n const { loading, uploadRequest, senderValue, setSenderValue } = useChatSenderState();\n const { chat, stopChat, clearChat } = useChatActions();\n\n return (\n <XAdkSender\n ref={ref}\n {...props}\n loading={loading}\n value={senderValue}\n onChange={setSenderValue}\n onSubmit={chat}\n onStop={stopChat}\n onClear={clearChat}\n uploadRequest={uploadRequest}\n />\n );\n },\n);\n\nSender.displayName = \"XAdkProvider.Sender\";\n\nexport default Sender;\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAAkC;AAClC,wBAAuB;AACvB,oCAAmC;AACnC,+BAA+B;AAmCzB;AANN,IAAM,aAAS;AAAA,EACb,CAAC,OAAO,QAAQ;AACd,UAAM,EAAE,SAAS,eAAe,aAAa,eAAe,QAAI,kDAAmB;AACnF,UAAM,EAAE,MAAM,UAAU,UAAU,QAAI,yCAAe;AAErD,WACE;AAAA,MAAC,kBAAAA;AAAA,MAAA;AAAA,QACC;AAAA,QACC,GAAG;AAAA,QACJ;AAAA,QACA,OAAO;AAAA,QACP,UAAU;AAAA,QACV,UAAU;AAAA,QACV,QAAQ;AAAA,QACR,SAAS;AAAA,QACT;AAAA;AAAA,IACF;AAAA,EAEJ;AACF;AAEA,OAAO,cAAc;AAErB,IAAO,iBAAQ;",
|
|
6
6
|
"names": ["XAdkSender"]
|
|
7
7
|
}
|
|
@@ -39,6 +39,7 @@ var import_XAiConversations = __toESM(require("../../XAiConversations"));
|
|
|
39
39
|
var import_ChatStateContext = require("../context/ChatStateContext");
|
|
40
40
|
var import_ChatActionContext = require("../context/ChatActionContext");
|
|
41
41
|
var import_SessionContext = require("../context/SessionContext");
|
|
42
|
+
var import_ChatSenderStateContext = require("../context/ChatSenderStateContext");
|
|
42
43
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
43
44
|
var { confirm } = import_antd.Modal;
|
|
44
45
|
var Sidebar = ({
|
|
@@ -49,12 +50,15 @@ var Sidebar = ({
|
|
|
49
50
|
const { currentSessionId } = (0, import_ChatStateContext.useChatState)();
|
|
50
51
|
const { clearChat } = (0, import_ChatActionContext.useChatActions)();
|
|
51
52
|
const { sessionList, deleteSession, updateSession, setCurrentSession } = (0, import_SessionContext.useSession)();
|
|
53
|
+
const { setSenderValue } = (0, import_ChatSenderStateContext.useChatSenderState)();
|
|
52
54
|
const handleActiveChange = (0, import_react.useCallback)((key) => {
|
|
53
55
|
setCurrentSession(key);
|
|
54
|
-
|
|
56
|
+
setSenderValue("");
|
|
57
|
+
}, [setCurrentSession, setSenderValue]);
|
|
55
58
|
const handleNewChat = (0, import_react.useCallback)(() => {
|
|
56
59
|
clearChat();
|
|
57
|
-
|
|
60
|
+
setSenderValue("");
|
|
61
|
+
}, [clearChat, setSenderValue]);
|
|
58
62
|
const defaultMenuConfig = (0, import_react.useCallback)((conversation) => ({
|
|
59
63
|
items: [
|
|
60
64
|
{
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/components/XAdkProvider/compound/Sidebar.tsx"],
|
|
4
|
-
"sourcesContent": ["import React, { useCallback } from 'react';\nimport { message, Modal, Input } from 'antd';\nimport { ExclamationCircleFilled } from '@ant-design/icons';\nimport type { ConversationsProps } from '
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAAmC;AACnC,kBAAsC;AACtC,mBAAwC;AAExC,8BAA6B;AAC7B,8BAA6B;AAC7B,+BAA+B;AAC/B,4BAA2B;
|
|
4
|
+
"sourcesContent": ["import React, { useCallback } from 'react';\nimport { message, Modal, Input } from 'antd';\nimport { ExclamationCircleFilled } from '@ant-design/icons';\nimport type { ConversationsProps } from '@/types/antdx';\nimport XAiConversations from '@/components/XAiConversations';\nimport { useChatState } from '../context/ChatStateContext';\nimport { useChatActions } from '../context/ChatActionContext';\nimport { useSession } from '../context/SessionContext';\nimport { useChatSenderState } from '../context/ChatSenderStateContext';\n\nconst { confirm } = Modal;\n\n/**\n * XAdkProvider.Sidebar - 会话列表侧边栏组件\n *\n * 从 Context 获取会话数据并提供会话管理界面\n * 基于 XAiConversations 组件实现(带展开/收起功能)\n *\n * @example\n * ```tsx\n * <XAdkProvider url=\"...\" token=\"...\">\n * <XAdkProvider.Sidebar isNarrow={false} />\n * </XAdkProvider>\n * ```\n */\nexport interface XAdkSidebarProps {\n /** 额外的样式 */\n style?: React.CSSProperties;\n /** 额外的类名 */\n className?: string;\n /** 是否为窄屏模式 */\n isNarrow?: boolean;\n}\n\nconst Sidebar: React.FC<XAdkSidebarProps> = ({\n isNarrow = false,\n style,\n className,\n}) => {\n const { currentSessionId } = useChatState();\n const { clearChat } = useChatActions();\n const { sessionList, deleteSession, updateSession, setCurrentSession } = useSession();\n const { setSenderValue } = useChatSenderState();\n\n // 切换会话\n const handleActiveChange = useCallback((key: string) => {\n setCurrentSession(key);\n setSenderValue('');\n }, [setCurrentSession, setSenderValue]);\n\n // 新建对话\n const handleNewChat = useCallback(() => {\n clearChat();\n setSenderValue('');\n }, [clearChat, setSenderValue]);\n\n // 默认会话菜单配置\n const defaultMenuConfig: ConversationsProps['menu'] = useCallback((conversation: any) => ({\n items: [\n {\n label: '重命名',\n key: 'edit',\n },\n {\n label: '删除',\n key: 'delete',\n danger: true,\n },\n ],\n onClick: (menuInfo: any) => {\n menuInfo.domEvent.stopPropagation();\n const { key } = menuInfo;\n switch (key) {\n case 'edit': {\n let inputValue = (conversation.label as string) || '';\n confirm({\n title: '编辑对话名称',\n icon: null,\n content: (\n <Input\n defaultValue={inputValue}\n autoFocus\n style={{ width: '100%' }}\n onChange={(e) => {\n inputValue = e.target.value;\n }}\n />\n ),\n okText: '确认',\n cancelText: '取消',\n okButtonProps: {\n style: {\n background: '#000',\n borderColor: '#000',\n color: '#fff',\n },\n },\n onOk: () => {\n if (!inputValue.trim()) {\n message.error('对话名称不能为空');\n return Promise.reject();\n }\n updateSession(conversation.key, inputValue);\n },\n onCancel: () => {\n // 静默处理\n },\n });\n break;\n }\n case 'delete':\n confirm({\n title: '确认删除?',\n icon: <ExclamationCircleFilled />,\n content: '该对话内容将被删除无法恢复。',\n okText: '确认删除',\n okType: 'danger',\n cancelText: '取消',\n okButtonProps: {\n style: {\n background: '#ff4d4f',\n borderColor: '#ff4d4f',\n color: '#fff',\n },\n },\n onOk() {\n deleteSession(conversation.key);\n },\n onCancel() {\n //\n },\n });\n break;\n }\n },\n }), [deleteSession, updateSession]);\n\n return (\n <XAiConversations\n isNarrow={isNarrow}\n sessionList={sessionList}\n activeKey={currentSessionId}\n onActiveChange={handleActiveChange}\n onNewChat={handleNewChat}\n menu={defaultMenuConfig}\n style={style}\n />\n );\n};\n\nSidebar.displayName = 'XAdkProvider.Sidebar';\n\nexport default Sidebar;\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["XAiConversations"]
|
|
7
7
|
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import type { UploadRequestFn } from "../../../types";
|
|
3
|
+
/**
|
|
4
|
+
* Sender 专用状态 Context
|
|
5
|
+
* 仅包含 Sender 需要的字段,避免 messages 变化导致 Sender 重渲染和焦点丢失
|
|
6
|
+
*/
|
|
7
|
+
export interface ChatSenderStateContextType {
|
|
8
|
+
loading: boolean;
|
|
9
|
+
uploadRequest?: UploadRequestFn;
|
|
10
|
+
/** Sender 输入框受控值 */
|
|
11
|
+
senderValue: string;
|
|
12
|
+
/** 更新 Sender 输入框值 */
|
|
13
|
+
setSenderValue: React.Dispatch<React.SetStateAction<string>>;
|
|
14
|
+
}
|
|
15
|
+
export declare const ChatSenderStateContext: React.Context<ChatSenderStateContextType | null>;
|
|
16
|
+
export declare const useChatSenderState: () => ChatSenderStateContextType;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
var __export = (target, all) => {
|
|
6
|
+
for (var name in all)
|
|
7
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
8
|
+
};
|
|
9
|
+
var __copyProps = (to, from, except, desc) => {
|
|
10
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
11
|
+
for (let key of __getOwnPropNames(from))
|
|
12
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
13
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
14
|
+
}
|
|
15
|
+
return to;
|
|
16
|
+
};
|
|
17
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
18
|
+
|
|
19
|
+
// src/components/XAdkProvider/context/ChatSenderStateContext.tsx
|
|
20
|
+
var ChatSenderStateContext_exports = {};
|
|
21
|
+
__export(ChatSenderStateContext_exports, {
|
|
22
|
+
ChatSenderStateContext: () => ChatSenderStateContext,
|
|
23
|
+
useChatSenderState: () => useChatSenderState
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(ChatSenderStateContext_exports);
|
|
26
|
+
var import_react = require("react");
|
|
27
|
+
var ChatSenderStateContext = (0, import_react.createContext)(null);
|
|
28
|
+
var useChatSenderState = () => {
|
|
29
|
+
const context = (0, import_react.useContext)(ChatSenderStateContext);
|
|
30
|
+
if (!context) {
|
|
31
|
+
throw new Error("useChatSenderState must be used within XAdkProvider");
|
|
32
|
+
}
|
|
33
|
+
return context;
|
|
34
|
+
};
|
|
35
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
36
|
+
0 && (module.exports = {
|
|
37
|
+
ChatSenderStateContext,
|
|
38
|
+
useChatSenderState
|
|
39
|
+
});
|
|
40
|
+
//# sourceMappingURL=ChatSenderStateContext.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../src/components/XAdkProvider/context/ChatSenderStateContext.tsx"],
|
|
4
|
+
"sourcesContent": ["import React, { createContext, useContext } from \"react\";\nimport type { UploadRequestFn } from \"@/types\";\n\n/**\n * Sender 专用状态 Context\n * 仅包含 Sender 需要的字段,避免 messages 变化导致 Sender 重渲染和焦点丢失\n */\nexport interface ChatSenderStateContextType {\n loading: boolean;\n uploadRequest?: UploadRequestFn;\n /** Sender 输入框受控值 */\n senderValue: string;\n /** 更新 Sender 输入框值 */\n setSenderValue: React.Dispatch<React.SetStateAction<string>>;\n}\n\nexport const ChatSenderStateContext = createContext<ChatSenderStateContextType | null>(null);\n\nexport const useChatSenderState = () => {\n const context = useContext(ChatSenderStateContext);\n if (!context) {\n throw new Error(\"useChatSenderState must be used within XAdkProvider\");\n }\n return context;\n};\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAAiD;AAgB1C,IAAM,6BAAyB,4BAAiD,IAAI;AAEpF,IAAM,qBAAqB,MAAM;AACtC,QAAM,cAAU,yBAAW,sBAAsB;AACjD,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI,MAAM,qDAAqD;AAAA,EACvE;AACA,SAAO;AACT;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -19,10 +19,12 @@ module.exports = __toCommonJS(context_exports);
|
|
|
19
19
|
__reExport(context_exports, require("./ChatStateContext"), module.exports);
|
|
20
20
|
__reExport(context_exports, require("./ChatActionContext"), module.exports);
|
|
21
21
|
__reExport(context_exports, require("./SessionContext"), module.exports);
|
|
22
|
+
__reExport(context_exports, require("./ChatSenderStateContext"), module.exports);
|
|
22
23
|
// Annotate the CommonJS export names for ESM import in node:
|
|
23
24
|
0 && (module.exports = {
|
|
24
25
|
...require("./ChatStateContext"),
|
|
25
26
|
...require("./ChatActionContext"),
|
|
26
|
-
...require("./SessionContext")
|
|
27
|
+
...require("./SessionContext"),
|
|
28
|
+
...require("./ChatSenderStateContext")
|
|
27
29
|
});
|
|
28
30
|
//# sourceMappingURL=index.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/components/XAdkProvider/context/index.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * XAdkProvider Context 导出\n * 提供拆分的 Context 和对应的 Hooks\n */\n\nexport * from './ChatStateContext';\nexport * from './ChatActionContext';\nexport * from './SessionContext';\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;AAAA;AAAA;AAKA,4BAAc,+BALd;AAMA,4BAAc,gCANd;AAOA,4BAAc,6BAPd;",
|
|
4
|
+
"sourcesContent": ["/**\n * XAdkProvider Context 导出\n * 提供拆分的 Context 和对应的 Hooks\n */\n\nexport * from './ChatStateContext';\nexport * from './ChatActionContext';\nexport * from './SessionContext';\nexport * from './ChatSenderStateContext';\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;AAAA;AAAA;AAKA,4BAAc,+BALd;AAMA,4BAAc,gCANd;AAOA,4BAAc,6BAPd;AAQA,4BAAc,qCARd;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -38,6 +38,7 @@ var import_x = require("@ant-design/x");
|
|
|
38
38
|
var import_ChatStateContext = require("./context/ChatStateContext");
|
|
39
39
|
var import_ChatActionContext = require("./context/ChatActionContext");
|
|
40
40
|
var import_SessionContext = require("./context/SessionContext");
|
|
41
|
+
var import_ChatSenderStateContext = require("./context/ChatSenderStateContext");
|
|
41
42
|
var import_useADKChat = __toESM(require("../../hooks/useADKChat"));
|
|
42
43
|
var import_common = require("../../styles/common");
|
|
43
44
|
var import_tokens = require("../../styles/tokens");
|
|
@@ -229,6 +230,16 @@ var XAdkProviderComponent = (0, import_react.forwardRef)(
|
|
|
229
230
|
setCurrentSession
|
|
230
231
|
]
|
|
231
232
|
);
|
|
233
|
+
const [senderValue, setSenderValue] = (0, import_react.useState)("");
|
|
234
|
+
const senderStateValue = (0, import_react.useMemo)(
|
|
235
|
+
() => ({
|
|
236
|
+
loading,
|
|
237
|
+
uploadRequest,
|
|
238
|
+
senderValue,
|
|
239
|
+
setSenderValue
|
|
240
|
+
}),
|
|
241
|
+
[loading, uploadRequest, senderValue]
|
|
242
|
+
);
|
|
232
243
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
233
244
|
import_antd.ConfigProvider,
|
|
234
245
|
{
|
|
@@ -237,7 +248,7 @@ var XAdkProviderComponent = (0, import_react.forwardRef)(
|
|
|
237
248
|
colorPrimary: (appInfo == null ? void 0 : appInfo.appTheme) || import_common.primaryBlue
|
|
238
249
|
}
|
|
239
250
|
},
|
|
240
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_x.XProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_ChatStateContext.ChatStateContext.Provider, { value: chatStateValue, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_ChatActionContext.ChatActionContext.Provider, { value: chatActionValue, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_SessionContext.SessionContext.Provider, { value: sessionValue, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
251
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_x.XProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_ChatStateContext.ChatStateContext.Provider, { value: chatStateValue, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_ChatActionContext.ChatActionContext.Provider, { value: chatActionValue, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_SessionContext.SessionContext.Provider, { value: sessionValue, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_ChatSenderStateContext.ChatSenderStateContext.Provider, { value: senderStateValue, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
241
252
|
"div",
|
|
242
253
|
{
|
|
243
254
|
style: {
|
|
@@ -249,7 +260,7 @@ var XAdkProviderComponent = (0, import_react.forwardRef)(
|
|
|
249
260
|
},
|
|
250
261
|
children
|
|
251
262
|
}
|
|
252
|
-
) }) }) }) })
|
|
263
|
+
) }) }) }) }) })
|
|
253
264
|
}
|
|
254
265
|
);
|
|
255
266
|
}
|