@ai-group/chat-sdk 3.0.1-alpha.2 → 3.0.1-alpha.4
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/components/XAdkChatbot/components/MarkdownRender/index.d.ts +1 -1
- package/dist/cjs/components/XAdkChatbot/components/MarkdownRender/index.js +6 -3
- package/dist/cjs/components/XAdkChatbot/components/MarkdownRender/index.js.map +2 -2
- package/dist/cjs/components/XAdkChatbot/components/MarkdownRender/styles.js +60 -2
- package/dist/cjs/components/XAdkChatbot/components/MarkdownRender/styles.js.map +2 -2
- package/dist/cjs/components/XAdkChatbot/index.js +1 -1
- package/dist/cjs/components/XAdkChatbot/index.js.map +2 -2
- package/dist/cjs/components/XAdkProvider/XAdkProvider.stories.js +3 -3
- package/dist/cjs/components/XAdkProvider/XAdkProvider.stories.js.map +1 -1
- package/dist/cjs/components/XAdkProvider/compound/DefaultLayout.js +1 -1
- package/dist/cjs/components/XAdkProvider/compound/DefaultLayout.js.map +2 -2
- package/dist/cjs/components/XAiChatbot/XAiChatbot.stories.d.ts +2 -2
- package/dist/cjs/components/XAiChatbot/XAiChatbot.stories.js +277 -131
- package/dist/cjs/components/XAiChatbot/XAiChatbot.stories.js.map +2 -2
- package/dist/cjs/components/XAiProvider/XAiProvider.stories.d.ts +2 -2
- package/dist/cjs/components/XAiProvider/XAiProvider.stories.js +14 -2
- package/dist/cjs/components/XAiProvider/XAiProvider.stories.js.map +2 -2
- package/dist/cjs/components/XAiSender/XAiSender.stories.d.ts +2 -2
- package/dist/cjs/components/XAiSender/XAiSender.stories.js +1 -1
- package/dist/cjs/components/XAiSender/XAiSender.stories.js.map +1 -1
- package/dist/cjs/hooks/useADKChat.js +4 -4
- package/dist/cjs/hooks/useADKChat.js.map +2 -2
- package/dist/cjs/types/XAiConversations.d.ts +1 -1
- package/dist/cjs/types/XAiConversations.js.map +1 -1
- package/dist/esm/components/XAdkChatbot/components/MarkdownRender/index.d.ts +1 -1
- package/dist/esm/components/XAdkChatbot/components/MarkdownRender/index.js +16 -16
- package/dist/esm/components/XAdkChatbot/components/MarkdownRender/index.js.map +1 -1
- package/dist/esm/components/XAdkChatbot/components/MarkdownRender/styles.js +2 -2
- package/dist/esm/components/XAdkChatbot/components/MarkdownRender/styles.js.map +1 -1
- package/dist/esm/components/XAdkChatbot/index.js +1 -1
- package/dist/esm/components/XAdkChatbot/index.js.map +1 -1
- package/dist/esm/components/XAdkProvider/XAdkProvider.stories.js +3 -3
- package/dist/esm/components/XAdkProvider/XAdkProvider.stories.js.map +1 -1
- package/dist/esm/components/XAdkProvider/compound/DefaultLayout.js +0 -2
- package/dist/esm/components/XAdkProvider/compound/DefaultLayout.js.map +1 -1
- package/dist/esm/components/XAiChatbot/XAiChatbot.stories.d.ts +2 -2
- package/dist/esm/components/XAiChatbot/XAiChatbot.stories.js +123 -123
- package/dist/esm/components/XAiChatbot/XAiChatbot.stories.js.map +1 -1
- package/dist/esm/components/XAiProvider/XAiProvider.stories.d.ts +2 -2
- package/dist/esm/components/XAiProvider/XAiProvider.stories.js +53 -53
- package/dist/esm/components/XAiProvider/XAiProvider.stories.js.map +1 -1
- package/dist/esm/components/XAiSender/XAiSender.stories.d.ts +2 -2
- package/dist/esm/components/XAiSender/XAiSender.stories.js +9 -9
- package/dist/esm/components/XAiSender/XAiSender.stories.js.map +1 -1
- package/dist/esm/hooks/useADKChat.js +4 -4
- package/dist/esm/hooks/useADKChat.js.map +1 -1
- package/dist/esm/types/XAiConversations.d.ts +1 -1
- package/dist/esm/types/XAiConversations.js.map +1 -1
- package/dist/umd/chat-sdk.min.js +1 -1
- package/package.json +1 -1
|
@@ -43,7 +43,7 @@ var import_jsx_runtime = require("react/jsx-runtime");
|
|
|
43
43
|
var CodeComponent = (props) => {
|
|
44
44
|
var _a;
|
|
45
45
|
const { className, children } = props;
|
|
46
|
-
const lang = ((_a = className == null ? void 0 : className.match(/language-(\
|
|
46
|
+
const lang = ((_a = className == null ? void 0 : className.match(/language-(\S+)/)) == null ? void 0 : _a[1]) || "";
|
|
47
47
|
if (typeof children !== "string")
|
|
48
48
|
return null;
|
|
49
49
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_x.CodeHighlighter, { lang, children });
|
|
@@ -66,12 +66,15 @@ var ThinkComponent = import_react.default.memo((props) => {
|
|
|
66
66
|
};
|
|
67
67
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_antd.Flex, { align: "center", gap: 8, style: { color: "#888", margin: "4px 0" }, children: [
|
|
68
68
|
type in titleMap && iconMap[type],
|
|
69
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: titleMap[type] })
|
|
69
|
+
titleMap[type] && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: titleMap[type] })
|
|
70
70
|
] });
|
|
71
71
|
});
|
|
72
72
|
var MarkdownRender = ({ text }) => {
|
|
73
73
|
const styles = (0, import_styles.useStyles)();
|
|
74
|
-
const markdown = text.replaceAll(/\/\*\s*PLANNING\s*\*\//g, '<tag type="planning"></tag>').replaceAll(/\/\*\s*REPLANNING\s*\*\//g, '<tag type="replanning"></tag>').replaceAll(/\/\*\s*REASONING\s*\*\//g, '<tag type="reasoning"></tag>').replaceAll(/\/\*\s*ACTION\s*\*\//g, '<tag type="action"></tag>').replaceAll(
|
|
74
|
+
const markdown = text.replaceAll(/\/\*\s*PLANNING\s*\*\//g, '<tag type="planning"></tag>').replaceAll(/\/\*\s*REPLANNING\s*\*\//g, '<tag type="replanning"></tag>').replaceAll(/\/\*\s*REASONING\s*\*\//g, '<tag type="reasoning"></tag>').replaceAll(/\/\*\s*ACTION\s*\*\//g, '<tag type="action"></tag>').replaceAll(
|
|
75
|
+
/\/\*\s*FINAL_ANSWER\s*\*\//g,
|
|
76
|
+
'<tag type="final_answer"></tag>'
|
|
77
|
+
);
|
|
75
78
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: styles.markdownWrapper, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: styles.markdownHost, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
76
79
|
import_x_markdown.default,
|
|
77
80
|
{
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../../src/components/XAdkChatbot/components/MarkdownRender/index.tsx"],
|
|
4
|
-
"sourcesContent": ["import React from
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAAkB;AAClB,wBAA+C;AAC/C,eAAgC;AAChC,kBAAqB;AACrB,mBAAkB;AAClB,oBAA0B;AAC1B,
|
|
4
|
+
"sourcesContent": ["import React from \"react\";\nimport XMarkdown, { type ComponentProps } from \"@ant-design/x-markdown\";\nimport { CodeHighlighter } from \"@ant-design/x\";\nimport { Flex } from \"antd\";\nimport Latex from \"@ant-design/x-markdown/plugins/Latex\";\nimport { useStyles } from \"./styles\";\nimport {\n BarsOutlined,\n BulbOutlined,\n ThunderboltOutlined,\n CheckCircleOutlined,\n} from \"@ant-design/icons\";\n\nconst CodeComponent: React.FC<ComponentProps> = (props) => {\n const { className, children } = props;\n const lang = className?.match(/language-(\\S+)/)?.[1] || \"\";\n\n if (typeof children !== \"string\") return null;\n return <CodeHighlighter lang={lang}>{children}</CodeHighlighter>;\n};\n\nexport interface MarkdownRenderProps {\n text: string;\n}\n\nconst ThinkComponent = React.memo((props: ComponentProps) => {\n const type = (props.type || \"\") as string;\n const titleMap: Record<string, string> = {\n planning: \"规划\",\n replanning: \"重新规划\",\n reasoning: \"推理\",\n action: \"行动\",\n final_answer: \"最终答案\",\n };\n const iconMap = {\n planning: <BarsOutlined />,\n replanning: <BarsOutlined />,\n reasoning: <BulbOutlined />,\n action: <ThunderboltOutlined />,\n final_answer: <CheckCircleOutlined />,\n };\n\n return (\n <Flex align=\"center\" gap={8} style={{ color: \"#888\", margin: \"4px 0\" }}>\n {type in titleMap && iconMap[type as keyof typeof iconMap]}\n {titleMap[type] && <span>{titleMap[type]}</span>}\n </Flex>\n );\n});\n\nconst MarkdownRender: React.FC<MarkdownRenderProps> = ({ text }) => {\n const styles = useStyles();\n const markdown = text\n .replaceAll(/\\/\\*\\s*PLANNING\\s*\\*\\//g, '<tag type=\"planning\"></tag>')\n .replaceAll(/\\/\\*\\s*REPLANNING\\s*\\*\\//g, '<tag type=\"replanning\"></tag>')\n .replaceAll(/\\/\\*\\s*REASONING\\s*\\*\\//g, '<tag type=\"reasoning\"></tag>')\n .replaceAll(/\\/\\*\\s*ACTION\\s*\\*\\//g, '<tag type=\"action\"></tag>')\n .replaceAll(\n /\\/\\*\\s*FINAL_ANSWER\\s*\\*\\//g,\n '<tag type=\"final_answer\"></tag>',\n );\n\n return (\n <div className={styles.markdownWrapper}>\n <div className={styles.markdownHost}>\n <XMarkdown\n content={markdown}\n paragraphTag=\"div\"\n config={{\n extensions: Latex(),\n }}\n components={{\n tag: ThinkComponent,\n code: CodeComponent,\n }}\n streaming={{\n enableAnimation: true,\n animationConfig: {\n fadeDuration: 400,\n },\n }}\n />\n </div>\n </div>\n );\n};\n\nexport default MarkdownRender;\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAAkB;AAClB,wBAA+C;AAC/C,eAAgC;AAChC,kBAAqB;AACrB,mBAAkB;AAClB,oBAA0B;AAC1B,mBAKO;AAOE;AALT,IAAM,gBAA0C,CAAC,UAAU;AAb3D;AAcE,QAAM,EAAE,WAAW,SAAS,IAAI;AAChC,QAAM,SAAO,4CAAW,MAAM,sBAAjB,mBAAqC,OAAM;AAExD,MAAI,OAAO,aAAa;AAAU,WAAO;AACzC,SAAO,4CAAC,4BAAgB,MAAa,UAAS;AAChD;AAMA,IAAM,iBAAiB,aAAAA,QAAM,KAAK,CAAC,UAA0B;AAC3D,QAAM,OAAQ,MAAM,QAAQ;AAC5B,QAAM,WAAmC;AAAA,IACvC,UAAU;AAAA,IACV,YAAY;AAAA,IACZ,WAAW;AAAA,IACX,QAAQ;AAAA,IACR,cAAc;AAAA,EAChB;AACA,QAAM,UAAU;AAAA,IACd,UAAU,4CAAC,6BAAa;AAAA,IACxB,YAAY,4CAAC,6BAAa;AAAA,IAC1B,WAAW,4CAAC,6BAAa;AAAA,IACzB,QAAQ,4CAAC,oCAAoB;AAAA,IAC7B,cAAc,4CAAC,oCAAoB;AAAA,EACrC;AAEA,SACE,6CAAC,oBAAK,OAAM,UAAS,KAAK,GAAG,OAAO,EAAE,OAAO,QAAQ,QAAQ,QAAQ,GAClE;AAAA,YAAQ,YAAY,QAAQ,IAA4B;AAAA,IACxD,SAAS,IAAI,KAAK,4CAAC,UAAM,mBAAS,IAAI,GAAE;AAAA,KAC3C;AAEJ,CAAC;AAED,IAAM,iBAAgD,CAAC,EAAE,KAAK,MAAM;AAClE,QAAM,aAAS,yBAAU;AACzB,QAAM,WAAW,KACd,WAAW,2BAA2B,6BAA6B,EACnE,WAAW,6BAA6B,+BAA+B,EACvE,WAAW,4BAA4B,8BAA8B,EACrE,WAAW,yBAAyB,2BAA2B,EAC/D;AAAA,IACC;AAAA,IACA;AAAA,EACF;AAEF,SACE,4CAAC,SAAI,WAAW,OAAO,iBACrB,sDAAC,SAAI,WAAW,OAAO,cACrB;AAAA,IAAC,kBAAAC;AAAA,IAAA;AAAA,MACC,SAAS;AAAA,MACT,cAAa;AAAA,MACb,QAAQ;AAAA,QACN,gBAAY,aAAAC,SAAM;AAAA,MACpB;AAAA,MACA,YAAY;AAAA,QACV,KAAK;AAAA,QACL,MAAM;AAAA,MACR;AAAA,MACA,WAAW;AAAA,QACT,iBAAiB;AAAA,QACjB,iBAAiB;AAAA,UACf,cAAc;AAAA,QAChB;AAAA,MACF;AAAA;AAAA,EACF,GACF,GACF;AAEJ;AAEA,IAAO,yBAAQ;",
|
|
6
6
|
"names": ["React", "XMarkdown", "Latex"]
|
|
7
7
|
}
|
|
@@ -33,14 +33,72 @@ var useStyles = (0, import_common.withBasicStyles)(() => ({
|
|
|
33
33
|
margin: 0 auto;
|
|
34
34
|
`,
|
|
35
35
|
markdownHost: import_css.css`
|
|
36
|
-
container-type: inline-size;
|
|
36
|
+
container-type: inline-size;
|
|
37
37
|
width: 100%;
|
|
38
38
|
overflow: auto;
|
|
39
39
|
|
|
40
|
+
/* ===== Markdown 基础排版 ===== */
|
|
41
|
+
|
|
42
|
+
p {
|
|
43
|
+
margin: 8px 0;
|
|
44
|
+
line-height: 1.6;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
ul,
|
|
48
|
+
ol {
|
|
49
|
+
padding-left: 20px;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
li {
|
|
53
|
+
margin: 4px 0;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/* ===== Table 样式 ===== */
|
|
57
|
+
|
|
58
|
+
table {
|
|
59
|
+
border-collapse: collapse;
|
|
60
|
+
width: 100%;
|
|
61
|
+
max-width: 100%;
|
|
62
|
+
margin: 12px 0;
|
|
63
|
+
font-size: 14px;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
thead {
|
|
67
|
+
background: #fafafa;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
th,
|
|
71
|
+
td {
|
|
72
|
+
border: 1px solid #e5e6eb;
|
|
73
|
+
padding: 8px 12px;
|
|
74
|
+
text-align: left;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
th {
|
|
78
|
+
font-weight: 600;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
tbody tr:hover {
|
|
82
|
+
background: #fafafa;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/* ===== Code ===== */
|
|
86
|
+
|
|
87
|
+
pre {
|
|
88
|
+
margin: 12px 0;
|
|
89
|
+
}
|
|
90
|
+
|
|
40
91
|
ant-highlightCode {
|
|
41
|
-
max-width: min(100%, 80ch);
|
|
92
|
+
max-width: min(100%, 80ch);
|
|
42
93
|
overflow-x: auto;
|
|
43
94
|
}
|
|
95
|
+
|
|
96
|
+
/* ===== 图片 ===== */
|
|
97
|
+
|
|
98
|
+
img {
|
|
99
|
+
max-width: 100%;
|
|
100
|
+
border-radius: 6px;
|
|
101
|
+
}
|
|
44
102
|
`
|
|
45
103
|
}));
|
|
46
104
|
var styles_default = useStyles;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../../src/components/XAdkChatbot/components/MarkdownRender/styles.tsx"],
|
|
4
|
-
"sourcesContent": ["import { css } from
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,iBAAoB;AACpB,oBAAgC;AAEzB,IAAM,gBAAY,+BAAgB,OAAO;AAAA,EAC9C,iBAAiB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,
|
|
4
|
+
"sourcesContent": ["import { css } from \"@emotion/css\";\nimport { withBasicStyles } from \"@/styles/common\";\n\nexport const useStyles = withBasicStyles(() => ({\n markdownWrapper: css`\n display: grid;\n grid-template-columns: minmax(0, 1fr); /* 关键:允许内容收缩 */\n max-width: 100%; /* 自定义最大宽度 */\n margin: 0 auto;\n `,\n\n markdownHost: css`\n container-type: inline-size;\n width: 100%;\n overflow: auto;\n\n /* ===== Markdown 基础排版 ===== */\n\n p {\n margin: 8px 0;\n line-height: 1.6;\n }\n\n ul,\n ol {\n padding-left: 20px;\n }\n\n li {\n margin: 4px 0;\n }\n\n /* ===== Table 样式 ===== */\n\n table {\n border-collapse: collapse;\n width: 100%;\n max-width: 100%;\n margin: 12px 0;\n font-size: 14px;\n }\n\n thead {\n background: #fafafa;\n }\n\n th,\n td {\n border: 1px solid #e5e6eb;\n padding: 8px 12px;\n text-align: left;\n }\n\n th {\n font-weight: 600;\n }\n\n tbody tr:hover {\n background: #fafafa;\n }\n\n /* ===== Code ===== */\n\n pre {\n margin: 12px 0;\n }\n\n ant-highlightCode {\n max-width: min(100%, 80ch);\n overflow-x: auto;\n }\n\n /* ===== 图片 ===== */\n\n img {\n max-width: 100%;\n border-radius: 6px;\n }\n `,\n}));\n\nexport default useStyles;\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,iBAAoB;AACpB,oBAAgC;AAEzB,IAAM,gBAAY,+BAAgB,OAAO;AAAA,EAC9C,iBAAiB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOjB,cAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAoEhB,EAAE;AAEF,IAAO,iBAAQ;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -307,7 +307,7 @@ var XAdkChatbot = ({
|
|
|
307
307
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_FileGallery.default, { files: allFiles, align: "left" })
|
|
308
308
|
] }),
|
|
309
309
|
!isGroupLoading && (actions ? actions({ message: group, isLastBotMsg: isLastGroup }) : (showRetry || showCopy || showLog) && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: styles.metaFooter, children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_antd.Flex, { gap: 16, className: styles.actionIcons, children: [
|
|
310
|
-
showRetry && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_antd.Tooltip, { title: "重新生成", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_icons.ReloadOutlined, { onClick: onRetry }) }),
|
|
310
|
+
showRetry && isLastGroup && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_antd.Tooltip, { title: "重新生成", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_icons.ReloadOutlined, { onClick: onRetry }) }),
|
|
311
311
|
showCopy && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_antd.Tooltip, { title: "复制内容", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
312
312
|
import_icons.CopyOutlined,
|
|
313
313
|
{
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/components/XAdkChatbot/index.tsx"],
|
|
4
|
-
"sourcesContent": ["import React, { useMemo, useCallback, useEffect, useRef } 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 \"./components/FileGallery\";\nimport XAiThoughtChain from \"@/components/XAiThoughtChain\";\nimport { parseAgentMessage, hasProcessContent, getPlainText } from \"@/utils\";\nimport type {\n IMessage,\n XAdkChatbotProps,\n ChatGroup,\n FunctionCall,\n} from \"@/types\";\nimport type { ThoughtChainItemType } from \"@/types/XAiThoughtChain\";\n\nconst scrollThreshold = 10;\n\n/**\n * XAdkChatbot - 增强版聊天组件\n *\n * 新增功能:\n * - ✅ 自动消息分组 (enableGrouping)\n * - ✅ 自动解析思维链 (enableProcessParsing)\n * - ✅ 文件展示 (FileGallery)\n * - ✅ 操作栏 (重试/复制/日志)\n * - ✅ 欢迎页面 (agentName/agentIcon/description)\n */\nconst XAdkChatbot: React.FC<XAdkChatbotProps> = ({\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 className,\n style,\n // welcome = null,\n enableGrouping = true,\n enableProcessParsing = true,\n parseOptions,\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\n // 滚动到底部\n useEffect(() => {\n if (!loading) return;\n if (userHasScrolledRef.current) return;\n messagesEndRef.current?.scrollIntoView({ behavior: \"smooth\" });\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 (group: ChatGroup, isLastGroup: boolean) => {\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 key={`${msg.id}-${i}`} text={msg.text} />\n );\n }\n if (msg.functionCall) {\n return (\n <FunctionCallRender\n key={`${msg.id}-${i}`}\n msg={msg}\n showDetail={showFnCallDetail}\n onConfirm={onConfirm}\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 = parseAgentMessage(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\n // 4. 渲染\n return (\n <div key={group.id} className={styles.botMsg}>\n {nodes.map((node, idx) => {\n if (node.type === \"process\") {\n return (\n <XAiThoughtChain\n key={node.key}\n loading={isGroupLoading}\n title=\"思维链已完成\"\n items={node.items}\n showFnCallDetail={showFnCallDetail}\n onConfirm={onConfirm}\n defaultOpen={isGroupLoading}\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} />\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 <FileGallery files={allFiles} align=\"left\" />\n </div>\n )}\n\n {/* 操作栏 */}\n {!isGroupLoading &&\n (actions\n ? actions({ message: group, isLastBotMsg: isLastGroup })\n : (showRetry || showCopy || showLog) && (\n <div className={styles.metaFooter}>\n <Flex gap={16} className={styles.actionIcons}>\n {showRetry && (\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 </div>\n ))}\n </div>\n );\n },\n [\n enableProcessParsing,\n parseOptions,\n showFnCallDetail,\n onConfirm,\n loading,\n showRetry,\n showCopy,\n showLog,\n onRetry,\n onCopy,\n onShowLog,\n styles,\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}>\n {/* 文件展示 */}\n {m.fileData && m.fileData.length > 0 && (\n <FileGallery files={m.fileData} align=\"right\" />\n )}\n {/* 文本展示 */}\n {m.text && <div className={styles.card}>{m.text}</div>}\n </div>\n ))}\n </div>\n );\n },\n [styles],\n );\n\n // ========== 欢迎页面 ==========\n // const isEmpty =\n // messages.length === 0 &&\n // !prologue &&\n // (!suggestions || suggestions.length === 0);\n\n // const renderWelcome = () => {\n // if (!isEmpty) return null;\n\n // return (\n // <>\n // {welcome ?? (\n // <div className={styles.welcomeWrapper}>\n // {agentIcon && (\n // <img src={agentIcon} alt=\"icon\" className={styles.welcomeIcon} />\n // )}\n // {agentName && (\n // <div className={styles.welcomeTitle}>{agentName}</div>\n // )}\n // {description && (\n // <div className={styles.welcomeDesc}>{description}</div>\n // )}\n // </div>\n // )}\n // </>\n // );\n // };\n\n // ========== 渲染建议问题 ==========\n const renderSuggestions = () => {\n if (!suggestions || suggestions.length === 0) return null;\n\n return (\n <div className={styles.suggestionWrapper}>\n {suggestions.map((item) => (\n <div key={item} className={styles.suggestion}>\n <div className={styles.suggestContent}>\n <Button\n type=\"text\"\n icon={<SwapRightOutlined />}\n 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 return (\n <div className={clsx(styles.wrapper, className)} style={style}>\n <div className={styles.list} ref={listRef}>\n {/* 开场白 */}\n {prologue && (\n <div className={styles.prologue}>\n <MarkdownRender text={prologue} />\n </div>\n )}\n\n {/* 欢迎页面 */}\n {/* {renderWelcome()} */}\n\n {/* 消息列表 */}\n {chatGroups.map((group, idx) =>\n group.role === \"user\"\n ? renderUserGroup(group)\n : renderBotGroup(group, idx === chatGroups.length - 1),\n )}\n\n {/* 建议问题 */}\n {renderSuggestions()}\n\n <div ref={messagesEndRef} />\n </div>\n </div>\n );\n};\n\nexport default XAdkChatbot;\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAA+D;AAC/D,kBAA8D;AAC9D,kBAAiB;AACjB,mBAMO;AACP,+BAAiB;AACjB,oBAA0B;AAC1B,4BAA2B;AAC3B,gCAA+B;AAC/B,yBAAwB;AACxB,6BAA4B;AAC5B,
|
|
4
|
+
"sourcesContent": ["import React, { useMemo, useCallback, useEffect, useRef } 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 \"./components/FileGallery\";\nimport XAiThoughtChain from \"@/components/XAiThoughtChain\";\nimport { parseAgentMessage } from \"@/utils\";\nimport type { IMessage, XAdkChatbotProps, ChatGroup } from \"@/types\";\nimport type { ThoughtChainItemType } from \"@/types/XAiThoughtChain\";\n\nconst scrollThreshold = 10;\n\n/**\n * XAdkChatbot - 增强版聊天组件\n *\n * 新增功能:\n * - ✅ 自动消息分组 (enableGrouping)\n * - ✅ 自动解析思维链 (enableProcessParsing)\n * - ✅ 文件展示 (FileGallery)\n * - ✅ 操作栏 (重试/复制/日志)\n * - ✅ 欢迎页面 (agentName/agentIcon/description)\n */\nconst XAdkChatbot: React.FC<XAdkChatbotProps> = ({\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 className,\n style,\n // welcome = null,\n enableGrouping = true,\n enableProcessParsing = true,\n parseOptions,\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\n // 滚动到底部\n useEffect(() => {\n if (!loading) return;\n if (userHasScrolledRef.current) return;\n messagesEndRef.current?.scrollIntoView({ behavior: \"smooth\" });\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 (group: ChatGroup, isLastGroup: boolean) => {\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 key={`${msg.id}-${i}`} text={msg.text} />\n );\n }\n if (msg.functionCall) {\n return (\n <FunctionCallRender\n key={`${msg.id}-${i}`}\n msg={msg}\n showDetail={showFnCallDetail}\n onConfirm={onConfirm}\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 = parseAgentMessage(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\n // 4. 渲染\n return (\n <div key={group.id} className={styles.botMsg}>\n {nodes.map((node, idx) => {\n if (node.type === \"process\") {\n return (\n <XAiThoughtChain\n key={node.key}\n loading={isGroupLoading}\n title=\"思维链已完成\"\n items={node.items}\n showFnCallDetail={showFnCallDetail}\n onConfirm={onConfirm}\n defaultOpen={isGroupLoading}\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} />\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 <FileGallery files={allFiles} align=\"left\" />\n </div>\n )}\n\n {/* 操作栏 */}\n {!isGroupLoading &&\n (actions\n ? actions({ message: group, isLastBotMsg: isLastGroup })\n : (showRetry || showCopy || showLog) && (\n <div className={styles.metaFooter}>\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 </div>\n ))}\n </div>\n );\n },\n [\n enableProcessParsing,\n parseOptions,\n showFnCallDetail,\n onConfirm,\n loading,\n showRetry,\n showCopy,\n showLog,\n onRetry,\n onCopy,\n onShowLog,\n styles,\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}>\n {/* 文件展示 */}\n {m.fileData && m.fileData.length > 0 && (\n <FileGallery files={m.fileData} align=\"right\" />\n )}\n {/* 文本展示 */}\n {m.text && <div className={styles.card}>{m.text}</div>}\n </div>\n ))}\n </div>\n );\n },\n [styles],\n );\n\n // ========== 欢迎页面 ==========\n // const isEmpty =\n // messages.length === 0 &&\n // !prologue &&\n // (!suggestions || suggestions.length === 0);\n\n // const renderWelcome = () => {\n // if (!isEmpty) return null;\n\n // return (\n // <>\n // {welcome ?? (\n // <div className={styles.welcomeWrapper}>\n // {agentIcon && (\n // <img src={agentIcon} alt=\"icon\" className={styles.welcomeIcon} />\n // )}\n // {agentName && (\n // <div className={styles.welcomeTitle}>{agentName}</div>\n // )}\n // {description && (\n // <div className={styles.welcomeDesc}>{description}</div>\n // )}\n // </div>\n // )}\n // </>\n // );\n // };\n\n // ========== 渲染建议问题 ==========\n const renderSuggestions = () => {\n if (!suggestions || suggestions.length === 0) return null;\n\n return (\n <div className={styles.suggestionWrapper}>\n {suggestions.map((item) => (\n <div key={item} className={styles.suggestion}>\n <div className={styles.suggestContent}>\n <Button\n type=\"text\"\n icon={<SwapRightOutlined />}\n 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 return (\n <div className={clsx(styles.wrapper, className)} style={style}>\n <div className={styles.list} ref={listRef}>\n {/* 开场白 */}\n {prologue && (\n <div className={styles.prologue}>\n <MarkdownRender text={prologue} />\n </div>\n )}\n\n {/* 欢迎页面 */}\n {/* {renderWelcome()} */}\n\n {/* 消息列表 */}\n {chatGroups.map((group, idx) =>\n group.role === \"user\"\n ? renderUserGroup(group)\n : renderBotGroup(group, idx === chatGroups.length - 1),\n )}\n\n {/* 建议问题 */}\n {renderSuggestions()}\n\n <div ref={messagesEndRef} />\n </div>\n </div>\n );\n};\n\nexport default XAdkChatbot;\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["MarkdownRender", "FunctionCallRender", "XAiThoughtChain", "FileGallery", "copy", "antdMessage", "clsx"]
|
|
7
7
|
}
|
|
@@ -183,9 +183,9 @@ var 带会话列表 = {
|
|
|
183
183
|
},
|
|
184
184
|
args: {
|
|
185
185
|
url: "https://m-poc-dev.zaxline.com",
|
|
186
|
-
token: "eyJhbGciOiJSUzI1NiJ9.
|
|
186
|
+
token: "eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJNRlg1VHhsaGVJS2Jla1pIS29lT1ZObG8iLCJhdWQiOiJNRlg1VHhsaGVJS2Jla1pIS29lT1ZObG8iLCJuYmYiOjE3NzMyODI3NzMsInVzZXJfaWQiOiJWNFNPSG1KbzNaZWE0Uk51ZzdYWDJBPT0iLCJzY29wZSI6WyJNRlg1VHhsaGVJS2Jla1pIS29lT1ZObG8iXSwiaXNzIjoiaHR0cDovL2htLWF1dGgtc2VydmVyLnhsaW5lLWRldi50ZXN0LnhpbmtlLmJpeiIsImV4cCI6MTc3MzI4OTk3MywiaWF0IjoxNzczMjgyNzczLCJqdGkiOiIwYmM4NmIzNS0xYzcxLTQ2NTAtYmU1Zi01Y2E2NDI0NDgxNTEiLCJjbGllbnRfaWQiOiJNRlg1VHhsaGVJS2Jla1pIS29lT1ZObG8ifQ.WRUgp7RTNcGH-vh8eoOwvgwbWwdFCrxCcDOZiJ6t0vdhAothDkl2N8r1NgqpvC3jwMTjCMYbPY4ARlCBmvHq5dv65VYjA1nyEytzicVTMi2KHLigRlHq90CVYP8-c33Bv8ZTYsvzGwHhQjmVYHW9NCAUiVvCP-yMDNPeli6ts4sDUVzdZE5t8kpKG3DAhnWnaWl28UtdyduVy5j3K0BgTes-bzV-Ka2otwCljM4fvc2dVAtYNb20PTiX-dz-7SLAmwUNMb81g-CejWYUiKWS5MTRsnRfOOmPW_a2TSoRbHlvdAGGBVCdzK5b6CLmR7178RdVMU07nk7vD_szctMAcQ",
|
|
187
187
|
config: {
|
|
188
|
-
appNo: "
|
|
188
|
+
appNo: "MFX5TxlheIKbekZHKoeOVNlo"
|
|
189
189
|
}
|
|
190
190
|
}
|
|
191
191
|
};
|
|
@@ -219,7 +219,7 @@ var 自定义布局 = {
|
|
|
219
219
|
},
|
|
220
220
|
args: {
|
|
221
221
|
url: "https://m-poc-dev.zaxline.com",
|
|
222
|
-
token: "eyJhbGciOiJSUzI1NiJ9.
|
|
222
|
+
token: "eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiIzanQyWWJEamV3Vm4yUEhSS2FEZkpFZ08iLCJhdWQiOiIzanQyWWJEamV3Vm4yUEhSS2FEZkpFZ08iLCJuYmYiOjE3NzMwNjI5MjUsInVzZXJfaWQiOiJWNFNPSG1KbzNaZWE0Uk51ZzdYWDJBPT0iLCJzY29wZSI6WyIzanQyWWJEamV3Vm4yUEhSS2FEZkpFZ08iXSwiaXNzIjoiaHR0cDovL2htLWF1dGgtc2VydmVyLnhsaW5lLWRldi50ZXN0LnhpbmtlLmJpeiIsImV4cCI6MTc3MzA3MDEyNSwiaWF0IjoxNzczMDYyOTI1LCJqdGkiOiI0YmY3MjcxOS03NzNkLTRkZGYtOGYzNC01YjAwNjA5MWE3Y2IiLCJjbGllbnRfaWQiOiIzanQyWWJEamV3Vm4yUEhSS2FEZkpFZ08ifQ.AcWWnsWZVHvvpbT9IG64oo6mNNUFDKuaTMSCRMUvgiRyfn8f4Y64GBF_VR_XhgvNgNczXx5pXlU5AEXlvwA3RXv5Voy5Vl1dvyrLOtjZivnRJVeDVzn8Af57cXKE9QBZAS94bUMAtfmZmvqer4Lw6wuFNSg6G32BCpQH6ifR8zei3scf1Gcs0QXr00KcT3dFROmAzJscJC_KnXxGx_729BlQqupdJ05KEGHDIokqJNy5Ev_40IPmW-ZDJprXpEdReHfHnPuaUgGQRAJEW2yTf2OsyNenOwA9l0iKYK1ENDnBpsr08VUgMhJBKq-quzP5AE3eLIn-3KR0O-yT4lyBiQ",
|
|
223
223
|
config: {
|
|
224
224
|
appNo: "3jt2YbDjewVn2PHRKaDfJEgO"
|
|
225
225
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/components/XAdkProvider/XAdkProvider.stories.tsx"],
|
|
4
|
-
"sourcesContent": ["import type { Meta, StoryObj } from \"@storybook/react-vite\";\nimport { Button, Space } from \"antd\";\nimport XAdkProvider from \"./index\";\nimport { useChatState, useChatActions } from \"./context\";\n\nconst meta: Meta<typeof XAdkProvider> = {\n title: \"AI组件/XAdkProvider 对话容器\",\n component: XAdkProvider,\n parameters: {\n layout: \"fullscreen\",\n docs: {\n description: {\n component: `\n# XAdkProvider - 新一代 Compound Components 架构\n\n基于 Compound Components 模式的 AI 聊天 SDK,提供完全可组合的聊天界面。\n\n## 核心特性\n\n- 🧩 **完全可组合**: 自由组合子组件,构建任意布局\n- 🪝 **Hooks 访问**: 通过 Hooks 轻松访问状态和方法\n- ⚡ **性能优化**: Context 三层分离,避免不必要的 rerender\n- 🔙 **向后兼容**: 旧 API 完全保留,平滑升级\n- 📘 **TypeScript**: 完整的类型支持\n\n## 可用组件\n\n- \\`XAdkProvider.DefaultLayout\\` - 默认布局 (类似 ChatGPT/DeepSeek)\n- \\`XAdkProvider.Chatbot\\` - 完整的聊天界面 (Messages + Sender)\n- \\`XAdkProvider.Messages\\` - 消息列表\n- \\`XAdkProvider.Sender\\` - 输入框\n- \\`XAdkProvider.Sidebar\\` - 会话列表\n- \\`XAdkProvider.Header\\` - 可选头部\n\n## 可用 Hooks\n\n- \\`useChatState()\\` - 访问聊天状态\n- \\`useChatActions()\\` - 访问聊天方法\n- \\`useSession()\\` - 访问会话管理\n\n## 配置说明\n\n请在使用前配置:\n- \\`url\\`: AI 服务地址 (默认: window.location.origin)\n- \\`token\\`: 认证令牌 (必填)\n- \\`config.appNo\\`: 应用编号 (必填)\n `,\n },\n },\n },\n tags: [\"autodocs\"],\n argTypes: {\n url: {\n description: \"AI 服务地址\",\n control: \"text\",\n },\n token: {\n description: \"认证令牌\",\n control: \"text\",\n },\n },\n};\n\nexport default meta;\ntype Story = StoryObj<typeof meta>;\n\n// ============================================\n// 示例 1: 默认布局 (类似 ChatGPT)\n// ============================================\nexport const 默认布局: Story = {\n render: (args) => (\n <div style={{ height: \"100vh\" }}>\n <XAdkProvider url={args.url} token={args.token} config={args.config}>\n <XAdkProvider.DefaultLayout\n showSessionList={false}\n allowUpload={true}\n clearBtnShow={true}\n />\n </XAdkProvider>\n </div>\n ),\n parameters: {\n docs: {\n description: {\n story: `\n默认布局,类似 ChatGPT 的界面风格。\n\n\\`\\`\\`tsx\n<XAdkProvider url=\"...\" token=\"...\" config={{ appNo: 'xxx' }}>\n <XAdkProvider.DefaultLayout\n showSessionList={false}\n allowUpload={true}\n clearBtnShow={true}\n />\n</XAdkProvider>\n\\`\\`\\`\n `,\n },\n },\n },\n args: {\n url: \"https://m-poc-dev.zaxline.com\",\n token:\n \"eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJ3VFhIOE5SZUQ2TkloV0tWZkJRQ3hXdlMiLCJhdWQiOiJ3VFhIOE5SZUQ2TkloV0tWZkJRQ3hXdlMiLCJuYmYiOjE3NzI3ODU3OTMsInVzZXJfaWQiOiJWNFNPSG1KbzNaZWE0Uk51ZzdYWDJBPT0iLCJzY29wZSI6WyJ3VFhIOE5SZUQ2TkloV0tWZkJRQ3hXdlMiXSwiaXNzIjoiaHR0cDovL2htLWF1dGgtc2VydmVyLnhsaW5lLWRldi50ZXN0LnhpbmtlLmJpeiIsImV4cCI6MTc3Mjc5Mjk5MywiaWF0IjoxNzcyNzg1NzkzLCJqdGkiOiI4MmFjMGZmZS1lZDBlLTRiMjMtYWE3NS04NmUzZjA1OTQ2NmEiLCJjbGllbnRfaWQiOiJ3VFhIOE5SZUQ2TkloV0tWZkJRQ3hXdlMifQ.bBipIkOwu4BQqtH_ijT1V12yw5SnDpu7HAZhWrzjRSF7NUlqXr3m25f1VU_jiE9wyHO0Pj0VMMox1xVrE90JT9zgFL2sa4IDLpoHl6B2sr-3pY8WsvTLnk9PBSyTfOjmuSRwNDZyQYx0p4xJKd0yhf5Acfh5vuvH8pW7ksGpEXKvCLqc9tpeLytE1qZm_eSWt_rjTxDzvwMv33RAWO_fEigezoXfOe8ALtWpIDXEoza6cI--2buVM6-ZAFJHwe0CA_rx5E5H7QpmonUlZZhu9JVEL7HCc76MWLnuRP9TlNuicsR3JrYvkZ8nkG4oiBSWaHAgOVizGXaf2Elr7edTNA\",\n config: {\n appNo: \"wTXH8NReD6NIhWKVfBQCxWvS\",\n },\n },\n};\n\n// ============================================\n// 示例 2: 带会话列表 (类似 DeepSeek)\n// ============================================\nexport const 带会话列表: Story = {\n render: (args) => (\n <div style={{ height: \"100vh\" }}>\n <XAdkProvider url={args.url} token={args.token} config={args.config}>\n <XAdkProvider.DefaultLayout\n header={<></>}\n showSessionList={true}\n allowUpload={true}\n clearBtnShow={false}\n showFnCallDetail={true}\n />\n </XAdkProvider>\n </div>\n ),\n parameters: {\n docs: {\n description: {\n story: `\n带会话列表的布局,类似 DeepSeek/元宝 的界面风格。\n\n左侧显示历史会话列表,右侧显示聊天区域。\n\n特点:\n- ✅ 左右布局: 左侧 280px 宽的会话列表,右侧聊天区域\n- ✅ 会话管理: 支持新建、切换、重命名、删除会话\n- ✅ 自动加载: 会话列表自动加载历史记录\n- ✅ 响应式: 窄屏自动切换到侧边栏模式\n\n\\`\\`\\`tsx\n<XAdkProvider\n url=\"...\"\n token=\"...\"\n config={{\n appNo: 'xxx',\n session: {\n showSessionList: true,\n }\n }}\n>\n <XAdkProvider.DefaultLayout\n showSessionList={true}\n allowUpload={true}\n />\n</XAdkProvider>\n\\`\\`\\`\n `,\n },\n },\n },\n args: {\n url: \"https://m-poc-dev.zaxline.com\",\n token:\n \"eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJwSFFPWVdjSjMzT0Y3RzdDOFdjR21IR2kiLCJhdWQiOiJwSFFPWVdjSjMzT0Y3RzdDOFdjR21IR2kiLCJuYmYiOjE3NzMwNDM0MjIsInVzZXJfaWQiOiJWNFNPSG1KbzNaZWE0Uk51ZzdYWDJBPT0iLCJzY29wZSI6WyJwSFFPWVdjSjMzT0Y3RzdDOFdjR21IR2kiXSwiaXNzIjoiaHR0cDovL2htLWF1dGgtc2VydmVyLnhsaW5lLWRldi50ZXN0LnhpbmtlLmJpeiIsImV4cCI6MTc3MzA1MDYyMiwiaWF0IjoxNzczMDQzNDIyLCJqdGkiOiJhODRmM2I5Ni1mNDIyLTRjOTgtOTA4Yi1lYzFiYmY0Y2JlNDciLCJjbGllbnRfaWQiOiJwSFFPWVdjSjMzT0Y3RzdDOFdjR21IR2kifQ.PDpY6X-fO2QkOB_30rkDsFFBNObsNJXtK0DoGKb7euOg0R7nHrXimCKR28LbVk-gRa-7C8uwJbVvCX-gJZivYaVwpeUijiBq2lY59bXU695iCyZNpkCAsRNnPfIX75hnTDDTY2-Qr2CXN0lgPZ8KO5Kt-CItu3cq8SiLYM8YlUVjqsCbNQdaqkhPLVnUzjyQseM-5mldNW2_j_UvQ0wtjcybPVHpmHrKT_N6jdqZDtwYUuM4vk6DL-K4O8m66gXImXbolQB62Ad04hFVrI2sJjHOt7U4ZwRWxxIm8JY7nk-03uUiUmhGsDSVaqHIc-YlDbxGVR0dhx59w6EaIYAX9A\",\n config: {\n appNo: \"pHQOYWcJ33OF7G7C8WcGmHGi\",\n },\n },\n};\n\n// ============================================\n// 示例 3: 自定义布局\n// ============================================\nexport const 自定义布局: Story = {\n render: (args) => (\n <div style={{ height: \"100vh\" }}>\n <XAdkProvider url={args.url} token={args.token} config={args.config}>\n <div style={{ display: \"flex\", height: \"100%\" }}>\n {/* 左侧会话列表 */}\n {/* <div\n style={{\n width: 300,\n borderRight: \"1px solid #f0f0f0\",\n background: \"#fafafa\",\n }}\n >\n <XAdkProvider.Sidebar />\n </div> */}\n\n {/* 右侧聊天区 */}\n <div style={{ flex: 1, display: \"flex\", flexDirection: \"column\" }}>\n {/* 自定义头部 */}\n <div\n style={{\n padding: \"16px 24px\",\n background: \"linear-gradient(135deg, #667eea 0%, #764ba2 100%)\",\n color: \"white\",\n borderBottom: \"1px solid rgba(255,255,255,0.1)\",\n }}\n >\n <h2 style={{ margin: 0, fontSize: \"18px\" }}>🤖 AI 智能助手</h2>\n </div>\n\n {/* 消息区 */}\n <div style={{ flex: 1, overflow: \"hidden\", background: \"#f9fafb\" }}>\n <XAdkProvider.Messages />\n </div>\n\n {/* 输入区 */}\n <XAdkProvider.Sender allowUpload={true} clearBtnShow={true} />\n </div>\n </div>\n </XAdkProvider>\n </div>\n ),\n parameters: {\n docs: {\n description: {\n story: `\n完全自定义的布局,展示 Compound Components 的灵活性。\n\n可以任意组合 Sidebar、Messages、Sender 等组件。\n `,\n },\n },\n },\n args: {\n url: \"https://m-poc-dev.zaxline.com\",\n token:\n \"eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJwSFFPWVdjSjMzT0Y3RzdDOFdjR21IR2kiLCJhdWQiOiJwSFFPWVdjSjMzT0Y3RzdDOFdjR21IR2kiLCJuYmYiOjE3NzMwNDM0MjIsInVzZXJfaWQiOiJWNFNPSG1KbzNaZWE0Uk51ZzdYWDJBPT0iLCJzY29wZSI6WyJwSFFPWVdjSjMzT0Y3RzdDOFdjR21IR2kiXSwiaXNzIjoiaHR0cDovL2htLWF1dGgtc2VydmVyLnhsaW5lLWRldi50ZXN0LnhpbmtlLmJpeiIsImV4cCI6MTc3MzA1MDYyMiwiaWF0IjoxNzczMDQzNDIyLCJqdGkiOiJhODRmM2I5Ni1mNDIyLTRjOTgtOTA4Yi1lYzFiYmY0Y2JlNDciLCJjbGllbnRfaWQiOiJwSFFPWVdjSjMzT0Y3RzdDOFdjR21IR2kifQ.PDpY6X-fO2QkOB_30rkDsFFBNObsNJXtK0DoGKb7euOg0R7nHrXimCKR28LbVk-gRa-7C8uwJbVvCX-gJZivYaVwpeUijiBq2lY59bXU695iCyZNpkCAsRNnPfIX75hnTDDTY2-Qr2CXN0lgPZ8KO5Kt-CItu3cq8SiLYM8YlUVjqsCbNQdaqkhPLVnUzjyQseM-5mldNW2_j_UvQ0wtjcybPVHpmHrKT_N6jdqZDtwYUuM4vk6DL-K4O8m66gXImXbolQB62Ad04hFVrI2sJjHOt7U4ZwRWxxIm8JY7nk-03uUiUmhGsDSVaqHIc-YlDbxGVR0dhx59w6EaIYAX9A\",\n config: {\n appNo: \"3jt2YbDjewVn2PHRKaDfJEgO\",\n },\n },\n};\n\n// ============================================\n// 示例 4: 使用 Hooks\n// ============================================\nconst CustomStatsBar = () => {\n const { messages, loading, appInfo } = useChatState();\n const { chat } = useChatActions();\n\n const quickQuestions = [\"介绍一下你自己\", \"你能帮我做什么?\", \"如何开始使用?\"];\n\n return (\n <div\n style={{\n padding: \"16px 20px\",\n background: \"white\",\n borderBottom: \"1px solid #f0f0f0\",\n }}\n >\n <div\n style={{\n display: \"flex\",\n justifyContent: \"space-between\",\n alignItems: \"center\",\n marginBottom: \"12px\",\n }}\n >\n <Space>\n <span style={{ fontSize: \"12px\", color: \"#999\" }}>\n 💬 消息数: <strong>{messages.length}</strong>\n </span>\n <span style={{ fontSize: \"12px\", color: \"#999\" }}>\n 🤖 {appInfo?.appName || \"加载中...\"}\n </span>\n </Space>\n <span\n style={{ fontSize: \"12px\", color: loading ? \"#1890ff\" : \"#52c41a\" }}\n >\n {loading ? \"● 生成中...\" : \"● 就绪\"}\n </span>\n </div>\n <div style={{ fontSize: \"12px\", color: \"#666\", marginBottom: \"8px\" }}>\n 💡 快捷问题:\n </div>\n <Space wrap>\n {quickQuestions.map((q, i) => (\n <Button\n key={i}\n size=\"small\"\n onClick={() => chat({ text: q })}\n disabled={loading}\n >\n {q}\n </Button>\n ))}\n </Space>\n </div>\n );\n};\n\nexport const 使用Hooks: Story = {\n render: (args) => (\n <div style={{ height: \"100vh\" }}>\n <XAdkProvider url={args.url} token={args.token} config={args.config}>\n <div\n style={{ display: \"flex\", flexDirection: \"column\", height: \"100%\" }}\n >\n <CustomStatsBar />\n <div style={{ flex: 1 }}>\n <XAdkProvider.Chatbot />\n </div>\n </div>\n </XAdkProvider>\n </div>\n ),\n parameters: {\n docs: {\n description: {\n story: `\n使用 \\`useChatState\\` 和 \\`useChatActions\\` Hooks 访问状态和方法。\n\n可以在任意子组件中使用这些 Hooks 来访问聊天数据和操作。\n\n\\`\\`\\`tsx\nfunction CustomStatsBar() {\n const { messages, loading } = useChatState();\n const { chat } = useChatActions();\n\n return (\n <div>\n <p>消息数: {messages.length}</p>\n <button onClick={() => chat({ text: 'Hello' })}>\n 发送\n </button>\n </div>\n );\n}\n\\`\\`\\`\n `,\n },\n },\n },\n args: {\n url: \"https://m-poc-dev.zaxline.com\",\n token:\n \"eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiIzanQyWWJEamV3Vm4yUEhSS2FEZkpFZ08iLCJhdWQiOiIzanQyWWJEamV3Vm4yUEhSS2FEZkpFZ08iLCJuYmYiOjE3NzI3NjE1OTQsInVzZXJfaWQiOiJWNFNPSG1KbzNaZWE0Uk51ZzdYWDJBPT0iLCJzY29wZSI6WyIzanQyWWJEamV3Vm4yUEhSS2FEZkpFZ08iXSwiaXNzIjoiaHR0cDovL2htLWF1dGgtc2VydmVyLnhsaW5lLWRldi50ZXN0LnhpbmtlLmJpeiIsImV4cCI6MTc3Mjc2ODc5NCwiaWF0IjoxNzcyNzYxNTk0LCJqdGkiOiI2M2IyMjRkNC1iODY3LTQzNjYtYTM5ZC1hZjNmOWQ0M2YyZmMiLCJjbGllbnRfaWQiOiIzanQyWWJEamV3Vm4yUEhSS2FEZkpFZ08ifQ.QNI4bD6MjIIvv-_SFxYEOiNv9304Ps5WF3b8_qmi3YIrqJQiaJ-iT1_fENpe9dD25RXcpgIv2Xnz9cI3Lz3gHfPKwoefijhrD7_Ye-9C5ztM2OI5pfoUurc1xPvjS7FGrTMZHNbpIFXyPoDAxtzGt-hLoQAEhBhLib8lLAbAQACmBOYy3KGwJg4sSFvbLkGWgqkH2aqC8MdH50ce35leybbEJu7ImithH3rj4E2oF6EqTb3vK181DFooEJ9E_LaC_hrw8zqGh9PSJah1rO3nxUDOPnz946RLKUi0xLOtz42l6qY2nUFsd9axYunGnk2ds5gg-PcBZN_X_aa-w7SLnw\",\n config: {\n appNo: \"3jt2YbDjewVn2PHRKaDfJEgO\",\n },\n },\n};\n\n// ============================================\n// 示例 5: 简化的 Chatbot\n// ============================================\nexport const 简化界面: Story = {\n render: (args) => (\n <div\n style={{\n height: \"100vh\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n background: \"#f5f5f5\",\n padding: \"40px\",\n }}\n >\n <div\n style={{\n width: \"100%\",\n maxWidth: \"900px\",\n height: \"700px\",\n background: \"white\",\n borderRadius: \"12px\",\n overflow: \"hidden\",\n boxShadow: \"0 8px 24px rgba(0,0,0,0.12)\",\n }}\n >\n <XAdkProvider url={args.url} token={args.token} config={args.config}>\n <XAdkProvider.Chatbot />\n </XAdkProvider>\n </div>\n </div>\n ),\n parameters: {\n docs: {\n description: {\n story: `\n最简化的聊天界面,只包含消息列表和输入框。\n\n适合嵌入到其他页面或作为对话窗口使用。\n\n\\`\\`\\`tsx\n<XAdkProvider url=\"...\" token=\"...\" config={{ appNo: 'xxx' }}>\n <XAdkProvider.Chatbot />\n</XAdkProvider>\n\\`\\`\\`\n `,\n },\n },\n },\n args: {\n url: \"https://m-poc-dev.zaxline.com\",\n token:\n \"eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiIzanQyWWJEamV3Vm4yUEhSS2FEZkpFZ08iLCJhdWQiOiIzanQyWWJEamV3Vm4yUEhSS2FEZkpFZ08iLCJuYmYiOjE3NzI3NjE1OTQsInVzZXJfaWQiOiJWNFNPSG1KbzNaZWE0Uk51ZzdYWDJBPT0iLCJzY29wZSI6WyIzanQyWWJEamV3Vm4yUEhSS2FEZkpFZ08iXSwiaXNzIjoiaHR0cDovL2htLWF1dGgtc2VydmVyLnhsaW5lLWRldi50ZXN0LnhpbmtlLmJpeiIsImV4cCI6MTc3Mjc2ODc5NCwiaWF0IjoxNzcyNzYxNTk0LCJqdGkiOiI2M2IyMjRkNC1iODY3LTQzNjYtYTM5ZC1hZjNmOWQ0M2YyZmMiLCJjbGllbnRfaWQiOiIzanQyWWJEamV3Vm4yUEhSS2FEZkpFZ08ifQ.QNI4bD6MjIIvv-_SFxYEOiNv9304Ps5WF3b8_qmi3YIrqJQiaJ-iT1_fENpe9dD25RXcpgIv2Xnz9cI3Lz3gHfPKwoefijhrD7_Ye-9C5ztM2OI5pfoUurc1xPvjS7FGrTMZHNbpIFXyPoDAxtzGt-hLoQAEhBhLib8lLAbAQACmBOYy3KGwJg4sSFvbLkGWgqkH2aqC8MdH50ce35leybbEJu7ImithH3rj4E2oF6EqTb3vK181DFooEJ9E_LaC_hrw8zqGh9PSJah1rO3nxUDOPnz946RLKUi0xLOtz42l6qY2nUFsd9axYunGnk2ds5gg-PcBZN_X_aa-w7SLnw\",\n config: {\n appNo: \"3jt2YbDjewVn2PHRKaDfJEgO\",\n },\n },\n};\n"],
|
|
4
|
+
"sourcesContent": ["import type { Meta, StoryObj } from \"@storybook/react-vite\";\nimport { Button, Space } from \"antd\";\nimport XAdkProvider from \"./index\";\nimport { useChatState, useChatActions } from \"./context\";\n\nconst meta: Meta<typeof XAdkProvider> = {\n title: \"AI组件/XAdkProvider 对话容器\",\n component: XAdkProvider,\n parameters: {\n layout: \"fullscreen\",\n docs: {\n description: {\n component: `\n# XAdkProvider - 新一代 Compound Components 架构\n\n基于 Compound Components 模式的 AI 聊天 SDK,提供完全可组合的聊天界面。\n\n## 核心特性\n\n- 🧩 **完全可组合**: 自由组合子组件,构建任意布局\n- 🪝 **Hooks 访问**: 通过 Hooks 轻松访问状态和方法\n- ⚡ **性能优化**: Context 三层分离,避免不必要的 rerender\n- 🔙 **向后兼容**: 旧 API 完全保留,平滑升级\n- 📘 **TypeScript**: 完整的类型支持\n\n## 可用组件\n\n- \\`XAdkProvider.DefaultLayout\\` - 默认布局 (类似 ChatGPT/DeepSeek)\n- \\`XAdkProvider.Chatbot\\` - 完整的聊天界面 (Messages + Sender)\n- \\`XAdkProvider.Messages\\` - 消息列表\n- \\`XAdkProvider.Sender\\` - 输入框\n- \\`XAdkProvider.Sidebar\\` - 会话列表\n- \\`XAdkProvider.Header\\` - 可选头部\n\n## 可用 Hooks\n\n- \\`useChatState()\\` - 访问聊天状态\n- \\`useChatActions()\\` - 访问聊天方法\n- \\`useSession()\\` - 访问会话管理\n\n## 配置说明\n\n请在使用前配置:\n- \\`url\\`: AI 服务地址 (默认: window.location.origin)\n- \\`token\\`: 认证令牌 (必填)\n- \\`config.appNo\\`: 应用编号 (必填)\n `,\n },\n },\n },\n tags: [\"autodocs\"],\n argTypes: {\n url: {\n description: \"AI 服务地址\",\n control: \"text\",\n },\n token: {\n description: \"认证令牌\",\n control: \"text\",\n },\n },\n};\n\nexport default meta;\ntype Story = StoryObj<typeof meta>;\n\n// ============================================\n// 示例 1: 默认布局 (类似 ChatGPT)\n// ============================================\nexport const 默认布局: Story = {\n render: (args) => (\n <div style={{ height: \"100vh\" }}>\n <XAdkProvider url={args.url} token={args.token} config={args.config}>\n <XAdkProvider.DefaultLayout\n showSessionList={false}\n allowUpload={true}\n clearBtnShow={true}\n />\n </XAdkProvider>\n </div>\n ),\n parameters: {\n docs: {\n description: {\n story: `\n默认布局,类似 ChatGPT 的界面风格。\n\n\\`\\`\\`tsx\n<XAdkProvider url=\"...\" token=\"...\" config={{ appNo: 'xxx' }}>\n <XAdkProvider.DefaultLayout\n showSessionList={false}\n allowUpload={true}\n clearBtnShow={true}\n />\n</XAdkProvider>\n\\`\\`\\`\n `,\n },\n },\n },\n args: {\n url: \"https://m-poc-dev.zaxline.com\",\n token:\n \"eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJ3VFhIOE5SZUQ2TkloV0tWZkJRQ3hXdlMiLCJhdWQiOiJ3VFhIOE5SZUQ2TkloV0tWZkJRQ3hXdlMiLCJuYmYiOjE3NzI3ODU3OTMsInVzZXJfaWQiOiJWNFNPSG1KbzNaZWE0Uk51ZzdYWDJBPT0iLCJzY29wZSI6WyJ3VFhIOE5SZUQ2TkloV0tWZkJRQ3hXdlMiXSwiaXNzIjoiaHR0cDovL2htLWF1dGgtc2VydmVyLnhsaW5lLWRldi50ZXN0LnhpbmtlLmJpeiIsImV4cCI6MTc3Mjc5Mjk5MywiaWF0IjoxNzcyNzg1NzkzLCJqdGkiOiI4MmFjMGZmZS1lZDBlLTRiMjMtYWE3NS04NmUzZjA1OTQ2NmEiLCJjbGllbnRfaWQiOiJ3VFhIOE5SZUQ2TkloV0tWZkJRQ3hXdlMifQ.bBipIkOwu4BQqtH_ijT1V12yw5SnDpu7HAZhWrzjRSF7NUlqXr3m25f1VU_jiE9wyHO0Pj0VMMox1xVrE90JT9zgFL2sa4IDLpoHl6B2sr-3pY8WsvTLnk9PBSyTfOjmuSRwNDZyQYx0p4xJKd0yhf5Acfh5vuvH8pW7ksGpEXKvCLqc9tpeLytE1qZm_eSWt_rjTxDzvwMv33RAWO_fEigezoXfOe8ALtWpIDXEoza6cI--2buVM6-ZAFJHwe0CA_rx5E5H7QpmonUlZZhu9JVEL7HCc76MWLnuRP9TlNuicsR3JrYvkZ8nkG4oiBSWaHAgOVizGXaf2Elr7edTNA\",\n config: {\n appNo: \"wTXH8NReD6NIhWKVfBQCxWvS\",\n },\n },\n};\n\n// ============================================\n// 示例 2: 带会话列表 (类似 DeepSeek)\n// ============================================\nexport const 带会话列表: Story = {\n render: (args) => (\n <div style={{ height: \"100vh\" }}>\n <XAdkProvider url={args.url} token={args.token} config={args.config}>\n <XAdkProvider.DefaultLayout\n header={<></>}\n showSessionList={true}\n allowUpload={true}\n clearBtnShow={false}\n showFnCallDetail={true}\n />\n </XAdkProvider>\n </div>\n ),\n parameters: {\n docs: {\n description: {\n story: `\n带会话列表的布局,类似 DeepSeek/元宝 的界面风格。\n\n左侧显示历史会话列表,右侧显示聊天区域。\n\n特点:\n- ✅ 左右布局: 左侧 280px 宽的会话列表,右侧聊天区域\n- ✅ 会话管理: 支持新建、切换、重命名、删除会话\n- ✅ 自动加载: 会话列表自动加载历史记录\n- ✅ 响应式: 窄屏自动切换到侧边栏模式\n\n\\`\\`\\`tsx\n<XAdkProvider\n url=\"...\"\n token=\"...\"\n config={{\n appNo: 'xxx',\n session: {\n showSessionList: true,\n }\n }}\n>\n <XAdkProvider.DefaultLayout\n showSessionList={true}\n allowUpload={true}\n />\n</XAdkProvider>\n\\`\\`\\`\n `,\n },\n },\n },\n args: {\n url: \"https://m-poc-dev.zaxline.com\",\n token:\n \"eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJNRlg1VHhsaGVJS2Jla1pIS29lT1ZObG8iLCJhdWQiOiJNRlg1VHhsaGVJS2Jla1pIS29lT1ZObG8iLCJuYmYiOjE3NzMyODI3NzMsInVzZXJfaWQiOiJWNFNPSG1KbzNaZWE0Uk51ZzdYWDJBPT0iLCJzY29wZSI6WyJNRlg1VHhsaGVJS2Jla1pIS29lT1ZObG8iXSwiaXNzIjoiaHR0cDovL2htLWF1dGgtc2VydmVyLnhsaW5lLWRldi50ZXN0LnhpbmtlLmJpeiIsImV4cCI6MTc3MzI4OTk3MywiaWF0IjoxNzczMjgyNzczLCJqdGkiOiIwYmM4NmIzNS0xYzcxLTQ2NTAtYmU1Zi01Y2E2NDI0NDgxNTEiLCJjbGllbnRfaWQiOiJNRlg1VHhsaGVJS2Jla1pIS29lT1ZObG8ifQ.WRUgp7RTNcGH-vh8eoOwvgwbWwdFCrxCcDOZiJ6t0vdhAothDkl2N8r1NgqpvC3jwMTjCMYbPY4ARlCBmvHq5dv65VYjA1nyEytzicVTMi2KHLigRlHq90CVYP8-c33Bv8ZTYsvzGwHhQjmVYHW9NCAUiVvCP-yMDNPeli6ts4sDUVzdZE5t8kpKG3DAhnWnaWl28UtdyduVy5j3K0BgTes-bzV-Ka2otwCljM4fvc2dVAtYNb20PTiX-dz-7SLAmwUNMb81g-CejWYUiKWS5MTRsnRfOOmPW_a2TSoRbHlvdAGGBVCdzK5b6CLmR7178RdVMU07nk7vD_szctMAcQ\",\n config: {\n appNo: \"MFX5TxlheIKbekZHKoeOVNlo\",\n },\n },\n};\n\n// ============================================\n// 示例 3: 自定义布局\n// ============================================\nexport const 自定义布局: Story = {\n render: (args) => (\n <div style={{ height: \"100vh\" }}>\n <XAdkProvider url={args.url} token={args.token} config={args.config}>\n <div style={{ display: \"flex\", height: \"100%\" }}>\n {/* 左侧会话列表 */}\n {/* <div\n style={{\n width: 300,\n borderRight: \"1px solid #f0f0f0\",\n background: \"#fafafa\",\n }}\n >\n <XAdkProvider.Sidebar />\n </div> */}\n\n {/* 右侧聊天区 */}\n <div style={{ flex: 1, display: \"flex\", flexDirection: \"column\" }}>\n {/* 自定义头部 */}\n <div\n style={{\n padding: \"16px 24px\",\n background: \"linear-gradient(135deg, #667eea 0%, #764ba2 100%)\",\n color: \"white\",\n borderBottom: \"1px solid rgba(255,255,255,0.1)\",\n }}\n >\n <h2 style={{ margin: 0, fontSize: \"18px\" }}>🤖 AI 智能助手</h2>\n </div>\n\n {/* 消息区 */}\n <div style={{ flex: 1, overflow: \"hidden\", background: \"#f9fafb\" }}>\n <XAdkProvider.Messages />\n </div>\n\n {/* 输入区 */}\n <XAdkProvider.Sender allowUpload={true} clearBtnShow={true} />\n </div>\n </div>\n </XAdkProvider>\n </div>\n ),\n parameters: {\n docs: {\n description: {\n story: `\n完全自定义的布局,展示 Compound Components 的灵活性。\n\n可以任意组合 Sidebar、Messages、Sender 等组件。\n `,\n },\n },\n },\n args: {\n url: \"https://m-poc-dev.zaxline.com\",\n token:\n \"eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiIzanQyWWJEamV3Vm4yUEhSS2FEZkpFZ08iLCJhdWQiOiIzanQyWWJEamV3Vm4yUEhSS2FEZkpFZ08iLCJuYmYiOjE3NzMwNjI5MjUsInVzZXJfaWQiOiJWNFNPSG1KbzNaZWE0Uk51ZzdYWDJBPT0iLCJzY29wZSI6WyIzanQyWWJEamV3Vm4yUEhSS2FEZkpFZ08iXSwiaXNzIjoiaHR0cDovL2htLWF1dGgtc2VydmVyLnhsaW5lLWRldi50ZXN0LnhpbmtlLmJpeiIsImV4cCI6MTc3MzA3MDEyNSwiaWF0IjoxNzczMDYyOTI1LCJqdGkiOiI0YmY3MjcxOS03NzNkLTRkZGYtOGYzNC01YjAwNjA5MWE3Y2IiLCJjbGllbnRfaWQiOiIzanQyWWJEamV3Vm4yUEhSS2FEZkpFZ08ifQ.AcWWnsWZVHvvpbT9IG64oo6mNNUFDKuaTMSCRMUvgiRyfn8f4Y64GBF_VR_XhgvNgNczXx5pXlU5AEXlvwA3RXv5Voy5Vl1dvyrLOtjZivnRJVeDVzn8Af57cXKE9QBZAS94bUMAtfmZmvqer4Lw6wuFNSg6G32BCpQH6ifR8zei3scf1Gcs0QXr00KcT3dFROmAzJscJC_KnXxGx_729BlQqupdJ05KEGHDIokqJNy5Ev_40IPmW-ZDJprXpEdReHfHnPuaUgGQRAJEW2yTf2OsyNenOwA9l0iKYK1ENDnBpsr08VUgMhJBKq-quzP5AE3eLIn-3KR0O-yT4lyBiQ\",\n config: {\n appNo: \"3jt2YbDjewVn2PHRKaDfJEgO\",\n },\n },\n};\n\n// ============================================\n// 示例 4: 使用 Hooks\n// ============================================\nconst CustomStatsBar = () => {\n const { messages, loading, appInfo } = useChatState();\n const { chat } = useChatActions();\n\n const quickQuestions = [\"介绍一下你自己\", \"你能帮我做什么?\", \"如何开始使用?\"];\n\n return (\n <div\n style={{\n padding: \"16px 20px\",\n background: \"white\",\n borderBottom: \"1px solid #f0f0f0\",\n }}\n >\n <div\n style={{\n display: \"flex\",\n justifyContent: \"space-between\",\n alignItems: \"center\",\n marginBottom: \"12px\",\n }}\n >\n <Space>\n <span style={{ fontSize: \"12px\", color: \"#999\" }}>\n 💬 消息数: <strong>{messages.length}</strong>\n </span>\n <span style={{ fontSize: \"12px\", color: \"#999\" }}>\n 🤖 {appInfo?.appName || \"加载中...\"}\n </span>\n </Space>\n <span\n style={{ fontSize: \"12px\", color: loading ? \"#1890ff\" : \"#52c41a\" }}\n >\n {loading ? \"● 生成中...\" : \"● 就绪\"}\n </span>\n </div>\n <div style={{ fontSize: \"12px\", color: \"#666\", marginBottom: \"8px\" }}>\n 💡 快捷问题:\n </div>\n <Space wrap>\n {quickQuestions.map((q, i) => (\n <Button\n key={i}\n size=\"small\"\n onClick={() => chat({ text: q })}\n disabled={loading}\n >\n {q}\n </Button>\n ))}\n </Space>\n </div>\n );\n};\n\nexport const 使用Hooks: Story = {\n render: (args) => (\n <div style={{ height: \"100vh\" }}>\n <XAdkProvider url={args.url} token={args.token} config={args.config}>\n <div\n style={{ display: \"flex\", flexDirection: \"column\", height: \"100%\" }}\n >\n <CustomStatsBar />\n <div style={{ flex: 1 }}>\n <XAdkProvider.Chatbot />\n </div>\n </div>\n </XAdkProvider>\n </div>\n ),\n parameters: {\n docs: {\n description: {\n story: `\n使用 \\`useChatState\\` 和 \\`useChatActions\\` Hooks 访问状态和方法。\n\n可以在任意子组件中使用这些 Hooks 来访问聊天数据和操作。\n\n\\`\\`\\`tsx\nfunction CustomStatsBar() {\n const { messages, loading } = useChatState();\n const { chat } = useChatActions();\n\n return (\n <div>\n <p>消息数: {messages.length}</p>\n <button onClick={() => chat({ text: 'Hello' })}>\n 发送\n </button>\n </div>\n );\n}\n\\`\\`\\`\n `,\n },\n },\n },\n args: {\n url: \"https://m-poc-dev.zaxline.com\",\n token:\n \"eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiIzanQyWWJEamV3Vm4yUEhSS2FEZkpFZ08iLCJhdWQiOiIzanQyWWJEamV3Vm4yUEhSS2FEZkpFZ08iLCJuYmYiOjE3NzI3NjE1OTQsInVzZXJfaWQiOiJWNFNPSG1KbzNaZWE0Uk51ZzdYWDJBPT0iLCJzY29wZSI6WyIzanQyWWJEamV3Vm4yUEhSS2FEZkpFZ08iXSwiaXNzIjoiaHR0cDovL2htLWF1dGgtc2VydmVyLnhsaW5lLWRldi50ZXN0LnhpbmtlLmJpeiIsImV4cCI6MTc3Mjc2ODc5NCwiaWF0IjoxNzcyNzYxNTk0LCJqdGkiOiI2M2IyMjRkNC1iODY3LTQzNjYtYTM5ZC1hZjNmOWQ0M2YyZmMiLCJjbGllbnRfaWQiOiIzanQyWWJEamV3Vm4yUEhSS2FEZkpFZ08ifQ.QNI4bD6MjIIvv-_SFxYEOiNv9304Ps5WF3b8_qmi3YIrqJQiaJ-iT1_fENpe9dD25RXcpgIv2Xnz9cI3Lz3gHfPKwoefijhrD7_Ye-9C5ztM2OI5pfoUurc1xPvjS7FGrTMZHNbpIFXyPoDAxtzGt-hLoQAEhBhLib8lLAbAQACmBOYy3KGwJg4sSFvbLkGWgqkH2aqC8MdH50ce35leybbEJu7ImithH3rj4E2oF6EqTb3vK181DFooEJ9E_LaC_hrw8zqGh9PSJah1rO3nxUDOPnz946RLKUi0xLOtz42l6qY2nUFsd9axYunGnk2ds5gg-PcBZN_X_aa-w7SLnw\",\n config: {\n appNo: \"3jt2YbDjewVn2PHRKaDfJEgO\",\n },\n },\n};\n\n// ============================================\n// 示例 5: 简化的 Chatbot\n// ============================================\nexport const 简化界面: Story = {\n render: (args) => (\n <div\n style={{\n height: \"100vh\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n background: \"#f5f5f5\",\n padding: \"40px\",\n }}\n >\n <div\n style={{\n width: \"100%\",\n maxWidth: \"900px\",\n height: \"700px\",\n background: \"white\",\n borderRadius: \"12px\",\n overflow: \"hidden\",\n boxShadow: \"0 8px 24px rgba(0,0,0,0.12)\",\n }}\n >\n <XAdkProvider url={args.url} token={args.token} config={args.config}>\n <XAdkProvider.Chatbot />\n </XAdkProvider>\n </div>\n </div>\n ),\n parameters: {\n docs: {\n description: {\n story: `\n最简化的聊天界面,只包含消息列表和输入框。\n\n适合嵌入到其他页面或作为对话窗口使用。\n\n\\`\\`\\`tsx\n<XAdkProvider url=\"...\" token=\"...\" config={{ appNo: 'xxx' }}>\n <XAdkProvider.Chatbot />\n</XAdkProvider>\n\\`\\`\\`\n `,\n },\n },\n },\n args: {\n url: \"https://m-poc-dev.zaxline.com\",\n token:\n \"eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiIzanQyWWJEamV3Vm4yUEhSS2FEZkpFZ08iLCJhdWQiOiIzanQyWWJEamV3Vm4yUEhSS2FEZkpFZ08iLCJuYmYiOjE3NzI3NjE1OTQsInVzZXJfaWQiOiJWNFNPSG1KbzNaZWE0Uk51ZzdYWDJBPT0iLCJzY29wZSI6WyIzanQyWWJEamV3Vm4yUEhSS2FEZkpFZ08iXSwiaXNzIjoiaHR0cDovL2htLWF1dGgtc2VydmVyLnhsaW5lLWRldi50ZXN0LnhpbmtlLmJpeiIsImV4cCI6MTc3Mjc2ODc5NCwiaWF0IjoxNzcyNzYxNTk0LCJqdGkiOiI2M2IyMjRkNC1iODY3LTQzNjYtYTM5ZC1hZjNmOWQ0M2YyZmMiLCJjbGllbnRfaWQiOiIzanQyWWJEamV3Vm4yUEhSS2FEZkpFZ08ifQ.QNI4bD6MjIIvv-_SFxYEOiNv9304Ps5WF3b8_qmi3YIrqJQiaJ-iT1_fENpe9dD25RXcpgIv2Xnz9cI3Lz3gHfPKwoefijhrD7_Ye-9C5ztM2OI5pfoUurc1xPvjS7FGrTMZHNbpIFXyPoDAxtzGt-hLoQAEhBhLib8lLAbAQACmBOYy3KGwJg4sSFvbLkGWgqkH2aqC8MdH50ce35leybbEJu7ImithH3rj4E2oF6EqTb3vK181DFooEJ9E_LaC_hrw8zqGh9PSJah1rO3nxUDOPnz946RLKUi0xLOtz42l6qY2nUFsd9axYunGnk2ds5gg-PcBZN_X_aa-w7SLnw\",\n config: {\n appNo: \"3jt2YbDjewVn2PHRKaDfJEgO\",\n },\n },\n};\n"],
|
|
5
5
|
"mappings": "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",
|
|
6
6
|
"names": ["XAdkProvider"]
|
|
7
7
|
}
|
|
@@ -44,7 +44,7 @@ var DefaultLayout = ({
|
|
|
44
44
|
footer,
|
|
45
45
|
allowUpload = false,
|
|
46
46
|
clearBtnShow = true,
|
|
47
|
-
showFnCallDetail = false,
|
|
47
|
+
// showFnCallDetail = false,
|
|
48
48
|
messagesFooter
|
|
49
49
|
}) => {
|
|
50
50
|
const { appInfo, messages, prologue, suggestions } = (0, import_ChatStateContext.useChatState)();
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/components/XAdkProvider/compound/DefaultLayout.tsx"],
|
|
4
|
-
"sourcesContent": ["import React from \"react\";\nimport { useChatState } from \"../context/ChatStateContext\";\nimport Sidebar from \"./Sidebar\";\nimport Messages from \"./Messages\";\nimport Welcome from \"./Welcome\";\nimport Sender from \"./Sender\";\n\n/**\n * XAdkProvider 默认布局\n *\n * 提供类似 ChatGPT/DeepSeek 的默认布局:\n * - 左侧: 会话列表侧边栏 (可选,支持展开/收起)\n * - 右侧: 聊天区域 (标题 + 消息 + 输入框,居中显示,最大宽度800px)\n */\nexport interface DefaultLayoutProps {\n /** 是否显示会话列表 */\n showSessionList?: boolean;\n /** 自定义头部 */\n header?: React.ReactNode;\n /** 自定义底部 (替代默认 Sender) */\n footer?: React.ReactNode;\n /** 是否允许上传文件 */\n allowUpload?: boolean;\n /** 是否显示清空按钮 */\n clearBtnShow?: boolean;\n /** 是否显示函数调用详情 */\n showFnCallDetail?: boolean;\n /** 自定义消息 Footer */\n messagesFooter?: (msg: any) => React.ReactNode;\n}\n\nconst DefaultLayout: React.FC<DefaultLayoutProps> = ({\n showSessionList = false,\n header,\n footer,\n allowUpload = false,\n clearBtnShow = true,\n showFnCallDetail = false,\n messagesFooter,\n}) => {\n const { appInfo, messages, prologue, suggestions } = useChatState();\n\n // 判断是否为空状态(展示Welcome)\n const isEmpty =\n messages.length === 0 &&\n !prologue &&\n (!suggestions || suggestions.length === 0);\n\n return (\n <div\n style={{\n display: \"flex\",\n height: \"100%\",\n width: \"100%\",\n position: \"relative\",\n overflow: \"hidden\",\n }}\n >\n {/* 左侧会话列表 - XAiConversations 组件会处理展开/收起 */}\n {showSessionList && <Sidebar isNarrow={false} />}\n\n {/* 右侧聊天区域 - 使用 flex: 1 自动占据剩余空间 */}\n <div\n style={{\n flex: 1,\n display: \"flex\",\n justifyContent: \"center\",\n alignItems: \"center\",\n flexDirection: \"column\",\n overflow: \"hidden\",\n }}\n >\n {/* 居中容器 - 最大宽度 800px */}\n <div\n style={{\n width: \"100%\",\n maxWidth: \"800px\",\n height: \"100%\",\n display: \"flex\",\n flexDirection: \"column\",\n }}\n >\n {/* 头部 */}\n {header ||\n (appInfo && (\n <div\n style={{\n padding: \"16px 24px\",\n display: \"flex\",\n justifyContent: \"center\",\n background: \"white\",\n }}\n >\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: \"12px\",\n }}\n >\n {/* {appInfo.icon && (\n <img\n src={appInfo.icon}\n alt=\"应用图标\"\n style={{\n width: 32,\n height: 32,\n borderRadius: \"6px\",\n }}\n />\n )} */}\n {appInfo.appName && (\n <div>\n <div\n style={{\n fontSize: \"16px\",\n fontWeight: 500,\n color: \"#000\",\n }}\n >\n {appInfo.appName}\n </div>\n {/* {appInfo.description && (\n <div\n style={{\n fontSize: \"12px\",\n color: \"#999\",\n marginTop: \"2px\",\n }}\n >\n {appInfo.description}\n </div>\n )} */}\n </div>\n )}\n </div>\n </div>\n ))}\n\n {/* 消息区域或Welcome区域 */}\n <div\n style={{\n flex: 1,\n overflow: \"hidden\",\n display: \"flex\",\n flexDirection: \"column\",\n }}\n >\n {/* 上方弹性占位 - Welcome状态时占据空间 */}\n <div\n style={{\n flex: isEmpty ? 1 : 0,\n transition: \"flex 0.4s cubic-bezier(0.4, 0, 0.2, 1)\",\n }}\n />\n\n {/* Welcome 组件 - 只在空状态显示 */}\n {isEmpty && (\n <div\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n padding: \"0 24px\",\n marginBottom: \"24px\",\n }}\n >\n <Welcome />\n </div>\n )}\n\n {/* Messages 组件 - 只在非空状态显示 */}\n {!isEmpty && (\n <div\n style={{\n flex: 1,\n overflow: \"hidden\",\n }}\n >\n <Messages\n // footer={messagesFooter}\n />\n </div>\n )}\n\n {/* 输入区域 - 始终存在,通过样式控制位置 */}\n <div\n style={{\n width: \"100%\",\n maxWidth: isEmpty ? \"600px\" : \"100%\",\n alignSelf: \"center\",\n padding: isEmpty ? \"0 24px\" : \"0\",\n transition: \"all 0.4s cubic-bezier(0.4, 0, 0.2, 1)\",\n }}\n >\n {footer || (\n <Sender allowUpload={allowUpload} clearBtnShow={clearBtnShow} />\n )}\n </div>\n\n {/* 下方弹性占位 - Welcome状态时占据更多空间,让内容偏上 */}\n <div\n style={{\n flex: isEmpty ? 1.5 : 0,\n transition: \"flex 0.4s cubic-bezier(0.4, 0, 0.2, 1)\",\n }}\n />\n </div>\n </div>\n </div>\n </div>\n );\n};\n\nDefaultLayout.displayName = \"XAdkProvider.DefaultLayout\";\n\nexport default DefaultLayout;\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,8BAA6B;AAC7B,qBAAoB;AACpB,sBAAqB;AACrB,qBAAoB;AACpB,oBAAmB;AAsDO;AA5B1B,IAAM,gBAA8C,CAAC;AAAA,EACnD,kBAAkB;AAAA,EAClB;AAAA,EACA;AAAA,EACA,cAAc;AAAA,EACd,eAAe;AAAA
|
|
4
|
+
"sourcesContent": ["import React from \"react\";\nimport { useChatState } from \"../context/ChatStateContext\";\nimport Sidebar from \"./Sidebar\";\nimport Messages from \"./Messages\";\nimport Welcome from \"./Welcome\";\nimport Sender from \"./Sender\";\n\n/**\n * XAdkProvider 默认布局\n *\n * 提供类似 ChatGPT/DeepSeek 的默认布局:\n * - 左侧: 会话列表侧边栏 (可选,支持展开/收起)\n * - 右侧: 聊天区域 (标题 + 消息 + 输入框,居中显示,最大宽度800px)\n */\nexport interface DefaultLayoutProps {\n /** 是否显示会话列表 */\n showSessionList?: boolean;\n /** 自定义头部 */\n header?: React.ReactNode;\n /** 自定义底部 (替代默认 Sender) */\n footer?: React.ReactNode;\n /** 是否允许上传文件 */\n allowUpload?: boolean;\n /** 是否显示清空按钮 */\n clearBtnShow?: boolean;\n /** 是否显示函数调用详情 */\n showFnCallDetail?: boolean;\n /** 自定义消息 Footer */\n messagesFooter?: (msg: any) => React.ReactNode;\n}\n\nconst DefaultLayout: React.FC<DefaultLayoutProps> = ({\n showSessionList = false,\n header,\n footer,\n allowUpload = false,\n clearBtnShow = true,\n // showFnCallDetail = false,\n messagesFooter,\n}) => {\n const { appInfo, messages, prologue, suggestions } = useChatState();\n\n // 判断是否为空状态(展示Welcome)\n const isEmpty =\n messages.length === 0 &&\n !prologue &&\n (!suggestions || suggestions.length === 0);\n\n return (\n <div\n style={{\n display: \"flex\",\n height: \"100%\",\n width: \"100%\",\n position: \"relative\",\n overflow: \"hidden\",\n }}\n >\n {/* 左侧会话列表 - XAiConversations 组件会处理展开/收起 */}\n {showSessionList && <Sidebar isNarrow={false} />}\n\n {/* 右侧聊天区域 - 使用 flex: 1 自动占据剩余空间 */}\n <div\n style={{\n flex: 1,\n display: \"flex\",\n justifyContent: \"center\",\n alignItems: \"center\",\n flexDirection: \"column\",\n overflow: \"hidden\",\n }}\n >\n {/* 居中容器 - 最大宽度 800px */}\n <div\n style={{\n width: \"100%\",\n maxWidth: \"800px\",\n height: \"100%\",\n display: \"flex\",\n flexDirection: \"column\",\n }}\n >\n {/* 头部 */}\n {header ||\n (appInfo && (\n <div\n style={{\n padding: \"16px 24px\",\n display: \"flex\",\n justifyContent: \"center\",\n background: \"white\",\n }}\n >\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: \"12px\",\n }}\n >\n {/* {appInfo.icon && (\n <img\n src={appInfo.icon}\n alt=\"应用图标\"\n style={{\n width: 32,\n height: 32,\n borderRadius: \"6px\",\n }}\n />\n )} */}\n {appInfo.appName && (\n <div>\n <div\n style={{\n fontSize: \"16px\",\n fontWeight: 500,\n color: \"#000\",\n }}\n >\n {appInfo.appName}\n </div>\n {/* {appInfo.description && (\n <div\n style={{\n fontSize: \"12px\",\n color: \"#999\",\n marginTop: \"2px\",\n }}\n >\n {appInfo.description}\n </div>\n )} */}\n </div>\n )}\n </div>\n </div>\n ))}\n\n {/* 消息区域或Welcome区域 */}\n <div\n style={{\n flex: 1,\n overflow: \"hidden\",\n display: \"flex\",\n flexDirection: \"column\",\n }}\n >\n {/* 上方弹性占位 - Welcome状态时占据空间 */}\n <div\n style={{\n flex: isEmpty ? 1 : 0,\n transition: \"flex 0.4s cubic-bezier(0.4, 0, 0.2, 1)\",\n }}\n />\n\n {/* Welcome 组件 - 只在空状态显示 */}\n {isEmpty && (\n <div\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n padding: \"0 24px\",\n marginBottom: \"24px\",\n }}\n >\n <Welcome />\n </div>\n )}\n\n {/* Messages 组件 - 只在非空状态显示 */}\n {!isEmpty && (\n <div\n style={{\n flex: 1,\n overflow: \"hidden\",\n }}\n >\n <Messages\n // footer={messagesFooter}\n />\n </div>\n )}\n\n {/* 输入区域 - 始终存在,通过样式控制位置 */}\n <div\n style={{\n width: \"100%\",\n maxWidth: isEmpty ? \"600px\" : \"100%\",\n alignSelf: \"center\",\n padding: isEmpty ? \"0 24px\" : \"0\",\n transition: \"all 0.4s cubic-bezier(0.4, 0, 0.2, 1)\",\n }}\n >\n {footer || (\n <Sender allowUpload={allowUpload} clearBtnShow={clearBtnShow} />\n )}\n </div>\n\n {/* 下方弹性占位 - Welcome状态时占据更多空间,让内容偏上 */}\n <div\n style={{\n flex: isEmpty ? 1.5 : 0,\n transition: \"flex 0.4s cubic-bezier(0.4, 0, 0.2, 1)\",\n }}\n />\n </div>\n </div>\n </div>\n </div>\n );\n};\n\nDefaultLayout.displayName = \"XAdkProvider.DefaultLayout\";\n\nexport default DefaultLayout;\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["Sidebar", "Welcome", "Messages", "Sender"]
|
|
7
7
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { Meta, StoryObj } from
|
|
2
|
-
import XAiChatbot from
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react-vite";
|
|
2
|
+
import XAiChatbot from ".";
|
|
3
3
|
declare const meta: Meta<typeof XAiChatbot>;
|
|
4
4
|
export default meta;
|
|
5
5
|
type Story = StoryObj<typeof meta>;
|