@antv/dumi-theme-antv 0.8.0-beta.1 → 0.8.0-beta.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. package/dist/builtins/Playground/index.module.less +0 -1
  2. package/dist/components/AI/HomeDialog/AntVBanner/index.module.less +2 -2
  3. package/dist/components/AI/HomeDialog/ModeSelector/index.js +4 -1
  4. package/dist/components/AI/HomeDialog/ModeSelector/index.module.less +39 -22
  5. package/dist/components/AI/HomeDialog/PromptTextarea/ChooseLib/index.js +5 -2
  6. package/dist/components/AI/HomeDialog/PromptTextarea/ChooseLib/index.module.less +0 -1
  7. package/dist/components/AI/HomeDialog/PromptTextarea/DatasourceCard/index.module.less +3 -3
  8. package/dist/components/AI/HomeDialog/PromptTextarea/Uploader/DataUploader.js +225 -0
  9. package/dist/components/AI/HomeDialog/PromptTextarea/index.js +61 -36
  10. package/dist/components/AI/HomeDialog/PromptTextarea/index.module.less +9 -8
  11. package/dist/components/AI/HomeDialog/RecommendCase/Card.js +13 -8
  12. package/dist/components/AI/HomeDialog/RecommendCase/card.module.less +1 -1
  13. package/dist/components/AI/HomeDialog/RecommendCase/index.js +45 -13
  14. package/dist/components/AI/HomeDialog/RecommendCase/index.module.less +3 -2
  15. package/dist/components/AI/HomeDialog/index.js +17 -4
  16. package/dist/components/AI/constant.js +2 -2
  17. package/dist/components/Login/Captcha/index.js +185 -0
  18. package/dist/components/Login/Captcha/index.less +91 -0
  19. package/dist/components/Login/CheckCode/index.js +244 -0
  20. package/dist/components/Login/CheckCode/index.less +137 -0
  21. package/dist/components/Login/CountDownButton/index.js +109 -0
  22. package/dist/components/Login/CountDownButton/index.less +8 -0
  23. package/dist/components/Login/LoginForm.js +239 -0
  24. package/dist/components/Login/LoginForm.less +409 -0
  25. package/dist/components/Login/index.js +24 -0
  26. package/dist/components/Login/openAuthWindow.js +54 -0
  27. package/dist/components/Login/types.js +5 -0
  28. package/dist/components/Login/utils.js +47 -0
  29. package/dist/layouts/DocLayout.js +2 -1
  30. package/dist/layouts/GlobalLayout/index.js +10 -4
  31. package/dist/locales/en.json +121 -1
  32. package/dist/locales/zh.json +121 -1
  33. package/dist/model/AIChat.js +65 -7
  34. package/dist/model/auth.js +133 -0
  35. package/dist/pages/AIPlayground/components/ConversationsMenu/index.js +28 -10
  36. package/dist/pages/AIPlayground/components/ConversationsMenu/index.module.less +2 -0
  37. package/dist/pages/AIPlayground/components/MarkdownComponent/MarkdownCodeBlock.js +25 -11
  38. package/dist/pages/AIPlayground/components/MarkdownComponent/MarkdownCodeBlock.module.less +1 -2
  39. package/dist/pages/AIPlayground/components/MarkdownComponent/index.js +5 -2
  40. package/dist/pages/AIPlayground/components/MsgBox/index.js +198 -136
  41. package/dist/pages/AIPlayground/components/MsgBox/index.module.less +3 -2
  42. package/dist/pages/AIPlayground/components/MsgBox/useAutoScroll.js +46 -0
  43. package/dist/pages/AIPlayground/components/SessionLayout/index.js +18 -10
  44. package/dist/pages/AIPlayground/components/SessionLayout/index.module.less +3 -1
  45. package/dist/pages/AIPlayground/components/TaskBox/generateCode.js +7 -1
  46. package/dist/pages/AIPlayground/components/TaskBox/index.js +79 -55
  47. package/dist/pages/AIPlayground/components/TaskBox/index.module.less +1 -0
  48. package/dist/pages/Examples/components/Accouncement/index.module.less +1 -1
  49. package/dist/pages/Examples/index.module.less +11 -11
  50. package/dist/pages/Index/components/Cases/index.module.less +8 -8
  51. package/dist/pages/Index/components/Companies/index.module.less +4 -3
  52. package/dist/pages/Index/components/Features/FeatureCard.module.less +4 -5
  53. package/dist/pages/Index/components/Features/index.module.less +5 -5
  54. package/dist/pages/Index/components/_.less +9 -9
  55. package/dist/plugin/index.js +2 -2
  56. package/dist/slots/Banner/Notification.module.less +8 -8
  57. package/dist/slots/Banner/index.module.less +10 -9
  58. package/dist/slots/CodeEditor/Toolbar.js +15 -9
  59. package/dist/slots/CodeEditor/index.js +19 -10
  60. package/dist/slots/CodeEditor/index.module.less +3 -0
  61. package/dist/slots/CodePreview/index.module.less +0 -3
  62. package/dist/slots/CodeRunner/index.js +5 -2
  63. package/dist/slots/ContentTable/index.module.less +2 -1
  64. package/dist/slots/Detail/News.module.less +9 -9
  65. package/dist/slots/Detail/index.module.less +11 -14
  66. package/dist/slots/ExampleSider/index.module.less +3 -4
  67. package/dist/slots/Footer/index.module.less +2 -2
  68. package/dist/slots/Header/Products/Product.module.less +2 -2
  69. package/dist/slots/Header/Search/SearchResult.js +23 -8
  70. package/dist/slots/Header/Search/SearchResult.module.less +1 -0
  71. package/dist/slots/Header/index.js +56 -11
  72. package/dist/slots/Header/index.module.less +13 -5
  73. package/dist/slots/LiveExample/index.module.less +1 -1
  74. package/dist/slots/Loading/index.module.less +30 -28
  75. package/dist/slots/ManualContent/index.module.less +14 -17
  76. package/dist/slots/_.less +9 -9
  77. package/dist/static/user.svg +3 -0
  78. package/dist/utils/env.js +37 -0
  79. package/dist/utils/request.js +42 -0
  80. package/package.json +7 -2
@@ -1,27 +1,26 @@
1
- function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
2
- function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
3
- function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }
4
- function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
5
1
  function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
6
2
  function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
7
3
  function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
8
4
  function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
9
5
  function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
10
6
  function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
11
- import { CheckOutlined, CopyOutlined, DislikeOutlined, LikeOutlined, PlusSquareOutlined, SyncOutlined } from '@ant-design/icons';
7
+ import { CheckOutlined, CopyOutlined, PlusSquareOutlined, SyncOutlined } from '@ant-design/icons';
12
8
  import { Bubble } from '@ant-design/x';
13
9
  import { Button, Flex, Space, Tooltip } from 'antd';
14
- import { history, useSiteData } from 'dumi';
10
+ import { useChat } from '@ai-sdk/react';
11
+ import { TextStreamChatTransport } from 'ai';
12
+ import { useIntl, useSiteData } from 'dumi';
15
13
  import { findLast } from 'lodash-es';
16
- import React, { useEffect, useState } from 'react';
14
+ import React, { useEffect, useState, useMemo, useRef } from 'react';
17
15
  import { useCopyToClipboard } from 'react-use';
18
16
  import { useSnapshot } from 'valtio';
19
17
  import { PromptTextarea } from "../../../../components/AI/HomeDialog/PromptTextarea";
20
- import { useStreamingText } from "../../../../hooks/useStreamingText";
21
- import { AIChatStore, clearEmptySession, createPureNewSession, derivedState } from "../../../../model/AIChat";
18
+ import { AIChatStore, createPureNewSession, derivedState } from "../../../../model/AIChat";
22
19
  import { getCodeFromMarkdown, isPreviewable } from "../../../../utils/code";
23
20
  import { MarkdownComponent } from "../MarkdownComponent";
24
21
  import styles from "./index.module.less";
22
+ import { useAutoScroll } from "./useAutoScroll";
23
+ import { getBaseURL } from "../../../../utils/env";
25
24
  var avatar = {
26
25
  icon: /*#__PURE__*/React.createElement("img", {
27
26
  draggable: false,
@@ -35,24 +34,46 @@ var avatar = {
35
34
  };
36
35
  var chatScrollIntoView = function chatScrollIntoView() {
37
36
  setTimeout(function () {
38
- var nodeList = document.querySelectorAll('.ant-bubble');
39
- nodeList[nodeList.length - 1].scrollIntoView({
40
- behavior: 'smooth'
37
+ document.getElementById('msgBoxAnchor').scrollIntoView({
38
+ block: 'end'
41
39
  });
40
+ }, 100);
41
+ };
42
+
43
+ // 辅助函数:将旧的 Message 格式转换为新的 UIMessage 格式
44
+ var convertToUIMessages = function convertToUIMessages(messages) {
45
+ return messages.map(function (msg) {
46
+ return {
47
+ id: msg.id,
48
+ role: msg.role,
49
+ parts: [{
50
+ type: 'text',
51
+ text: msg.content
52
+ }]
53
+ };
42
54
  });
43
55
  };
56
+
57
+ // 辅助函数:从 UIMessage 提取文本内容
58
+ var getTextContent = function getTextContent(message) {
59
+ return message.parts.filter(function (part) {
60
+ return part.type === 'text';
61
+ }).map(function (part) {
62
+ return part.text;
63
+ }).join('');
64
+ };
44
65
  function MsgBox(props) {
45
- var _derivedSnap$activeSe, _derivedSnap$activeSe2, _derivedSnap$activeSe3;
66
+ var _derivedSnap$activeSe, _derivedSnap$activeSe2, _derivedSnap$activeSe4, _derivedSnap$activeSe7, _derivedSnap$activeSe8, _messages;
46
67
  var _props$messages = props.messages,
47
- messages = _props$messages === void 0 ? [] : _props$messages,
68
+ initialMessages = _props$messages === void 0 ? [] : _props$messages,
48
69
  _props$simple = props.simple,
49
70
  simple = _props$simple === void 0 ? false : _props$simple,
50
- _props$context = props.context,
51
- context = _props$context === void 0 ? '' : _props$context,
52
71
  onCodegen = props.onCodegen,
53
72
  title = props.title;
54
73
  var _useSiteData = useSiteData(),
55
74
  themeConfig = _useSiteData.themeConfig;
75
+ var _useIntl = useIntl(),
76
+ formatMessage = _useIntl.formatMessage;
56
77
  var _useState = useState(!themeConfig.isAntVSite ? themeConfig.title : undefined),
57
78
  _useState2 = _slicedToArray(_useState, 2),
58
79
  lib = _useState2[0],
@@ -61,14 +82,10 @@ function MsgBox(props) {
61
82
  _useState4 = _slicedToArray(_useState3, 2),
62
83
  promptText = _useState4[0],
63
84
  setPromptText = _useState4[1];
64
- var _useState5 = useState(false),
85
+ var _useState5 = useState(''),
65
86
  _useState6 = _slicedToArray(_useState5, 2),
66
- isStreaming = _useState6[0],
67
- setIsStreaming = _useState6[1]; // trigger
68
- var _useState7 = useState(false),
69
- _useState8 = _slicedToArray(_useState7, 2),
70
- loading = _useState8[0],
71
- setLoading = _useState8[1];
87
+ fileSummary = _useState6[0],
88
+ setFileSummary = _useState6[1];
72
89
  var snap = useSnapshot(AIChatStore);
73
90
  var derivedSnap = useSnapshot(derivedState);
74
91
  var _useCopyToClipboard = useCopyToClipboard(),
@@ -78,192 +95,237 @@ function MsgBox(props) {
78
95
  var latestUserMessage = findLast((_derivedSnap$activeSe = derivedSnap.activeSession) === null || _derivedSnap$activeSe === void 0 ? void 0 : _derivedSnap$activeSe.messages, function (msg) {
79
96
  return msg.role === 'user';
80
97
  });
81
- var streamingText = useStreamingText({
82
- url: 'https://webgw-pre.alipay.com/visqaservice/external/chat',
83
- method: 'POST',
84
- body: {
85
- gptConversationId: (_derivedSnap$activeSe2 = derivedSnap.activeSession) === null || _derivedSnap$activeSe2 === void 0 ? void 0 : _derivedSnap$activeSe2.id,
86
- query: latestUserMessage === null || latestUserMessage === void 0 ? void 0 : latestUserMessage.content,
87
- library: (latestUserMessage === null || latestUserMessage === void 0 ? void 0 : latestUserMessage.lib) || lib,
88
- mode: latestUserMessage === null || latestUserMessage === void 0 ? void 0 : latestUserMessage.mode,
89
- anonymousUserId: snap.anonymousUserId,
90
- context: (latestUserMessage === null || latestUserMessage === void 0 ? void 0 : latestUserMessage.context) || context,
91
- mountId: "container"
92
- },
93
- trigger: isStreaming,
94
- // 将 isStreaming 状态作为 trigger
95
- headers: {
96
- 'Content-Type': 'application/json',
97
- 'x-webgw-version': '2.0',
98
- 'x-webgw-appid': '180020010001210065'
99
- },
100
- beforeStart: function beforeStart() {
101
- setLoading(true);
102
- },
103
- onFinish: function onFinish(finalText) {
104
- try {
105
- var _derivedState$activeS;
106
- var finalJSON = JSON.parse(finalText);
107
- (_derivedState$activeS = derivedState.activeSession) === null || _derivedState$activeS === void 0 || (_derivedState$activeS = _derivedState$activeS.messages) === null || _derivedState$activeS === void 0 || _derivedState$activeS.push({
98
+ // 使用 ref 存储动态值,避免重新创建 transport
99
+ var anonymousUserIdRef = useRef(snap.anonymousUserId);
100
+ var activeSessionIdRef = useRef((_derivedSnap$activeSe2 = derivedSnap.activeSession) === null || _derivedSnap$activeSe2 === void 0 ? void 0 : _derivedSnap$activeSe2.id);
101
+ useEffect(function () {
102
+ var _derivedSnap$activeSe3;
103
+ anonymousUserIdRef.current = snap.anonymousUserId;
104
+ activeSessionIdRef.current = (_derivedSnap$activeSe3 = derivedSnap.activeSession) === null || _derivedSnap$activeSe3 === void 0 ? void 0 : _derivedSnap$activeSe3.id;
105
+ }, [snap.anonymousUserId, (_derivedSnap$activeSe4 = derivedSnap.activeSession) === null || _derivedSnap$activeSe4 === void 0 ? void 0 : _derivedSnap$activeSe4.id]);
106
+
107
+ // 转换初始消息为新格式
108
+ var convertedInitialMessages = useMemo(function () {
109
+ return convertToUIMessages(initialMessages);
110
+ }, [initialMessages]);
111
+
112
+ // 核心:使用 useChat hook,配置 DefaultChatTransport
113
+ var _useChat = useChat({
114
+ transport: new TextStreamChatTransport({
115
+ api: getBaseURL() + '/api/modules/antv/ai/chat',
116
+ credentials: 'include',
117
+ headers: {
118
+ // xxx
119
+ },
120
+ // body 可以是函数,用于获取最新的动态值
121
+ body: {
122
+ gptConversationId: activeSessionIdRef.current,
123
+ anonymousUserId: anonymousUserIdRef.current,
124
+ mountId: 'container',
125
+ antvContext: (latestUserMessage === null || latestUserMessage === void 0 ? void 0 : latestUserMessage.context) || props.context,
126
+ library: (latestUserMessage === null || latestUserMessage === void 0 ? void 0 : latestUserMessage.lib) || lib,
127
+ mode: latestUserMessage === null || latestUserMessage === void 0 ? void 0 : latestUserMessage.mode
128
+ }
129
+ }),
130
+ messages: convertedInitialMessages,
131
+ // 当AI响应结束时触发
132
+ onFinish: function onFinish(_ref) {
133
+ var message = _ref.message,
134
+ isAbort = _ref.isAbort,
135
+ isDisconnect = _ref.isDisconnect,
136
+ isError = _ref.isError;
137
+ if (!isAbort && !isDisconnect && !isError) {
138
+ var _derivedState$activeS;
139
+ var messageContent = getTextContent(message);
140
+ if (isPreviewable(messageContent)) {
141
+ var codeBlock = getCodeFromMarkdown(messageContent).code;
142
+ AIChatStore.codeBlock = codeBlock;
143
+ onCodegen === null || onCodegen === void 0 || onCodegen(codeBlock);
144
+ }
145
+ (_derivedState$activeS = derivedState.activeSession) === null || _derivedState$activeS === void 0 || (_derivedState$activeS = _derivedState$activeS.messages) === null || _derivedState$activeS === void 0 || _derivedState$activeS.push({
146
+ id: crypto.randomUUID(),
147
+ role: 'assistant',
148
+ content: messageContent,
149
+ createdAt: Date.now()
150
+ });
151
+ }
152
+ },
153
+ onError: function onError(error) {
154
+ var _derivedState$activeS2;
155
+ console.error('回答失败', error);
156
+ // 同步错误消息到 valtio
157
+ (_derivedState$activeS2 = derivedState.activeSession) === null || _derivedState$activeS2 === void 0 || (_derivedState$activeS2 = _derivedState$activeS2.messages) === null || _derivedState$activeS2 === void 0 || _derivedState$activeS2.push({
108
158
  id: crypto.randomUUID(),
109
159
  role: 'assistant',
110
- content: finalJSON.content,
160
+ content: formatMessage({
161
+ id: 'ai.msgbox.error.response'
162
+ }),
111
163
  createdAt: Date.now()
112
164
  // mode,
113
165
  // lib,
114
166
  });
115
- if (isPreviewable(finalJSON.content)) {
116
- var codeBlock = getCodeFromMarkdown(finalJSON.content).code;
117
- AIChatStore.codeBlock = codeBlock;
118
- onCodegen === null || onCodegen === void 0 || onCodegen(codeBlock);
119
- }
120
- } catch (e) {
121
- // 说明不是JSON格式
122
- } finally {
123
- // 当流结束时,更新最后一条消息并重置 trigger
124
- setIsStreaming(false); // **关键:流结束后,关闭 trigger**
125
- setLoading(false);
126
- chatScrollIntoView();
127
167
  }
128
- },
129
- onError: function onError(error) {
130
- var _derivedState$activeS2;
131
- console.log('回答失败', error);
132
- // 处理错误
133
- (_derivedState$activeS2 = derivedState.activeSession) === null || _derivedState$activeS2 === void 0 || (_derivedState$activeS2 = _derivedState$activeS2.messages) === null || _derivedState$activeS2 === void 0 || _derivedState$activeS2.push({
134
- id: crypto.randomUUID(),
135
- role: 'assistant',
136
- content: "\u62B1\u6B49\uFF0C\u6211\u6CA1\u80FD\u6210\u529F\u5904\u7406\u60A8\u7684\u8BF7\u6C42\uFF0C\u8BF7\u7A0D\u540E\u518D\u6B21\u63D0\u95EE",
137
- createdAt: Date.now()
138
- // mode,
139
- // lib,
140
- });
141
- setIsStreaming(false);
142
- setLoading(false);
143
- }
144
- });
168
+ }),
169
+ messages = _useChat.messages,
170
+ setMessages = _useChat.setMessages,
171
+ sendMessage = _useChat.sendMessage,
172
+ regenerate = _useChat.regenerate,
173
+ status = _useChat.status,
174
+ stop = _useChat.stop;
145
175
 
146
- // 3. 处理用户提交
176
+ // 处理用户提交
147
177
  var handleSubmit = function handleSubmit() {
148
- var _derivedState$activeS3;
149
- if (!promptText.trim() || isStreaming) return; // 如果正在流式输出,则不允许发送
178
+ var _derivedSnap$activeSe5, _derivedState$activeS3;
179
+ var trimmedPrompt = promptText.trim();
180
+ if (!trimmedPrompt || status === 'streaming' || status === 'submitted') return;
181
+ if (derivedSnap.activeSession && ((_derivedSnap$activeSe5 = derivedSnap.activeSession.messages) === null || _derivedSnap$activeSe5 === void 0 ? void 0 : _derivedSnap$activeSe5.length) === 0) {
182
+ derivedState.activeSession.title = trimmedPrompt;
183
+ }
184
+ // 使用 sendMessage 函数发送新消息
185
+ // 第二个参数传递每次请求特定的额外数据
186
+ sendMessage({
187
+ text: promptText
188
+ }, {
189
+ body: {
190
+ context: fileSummary,
191
+ lib: lib,
192
+ mode: 'implement'
193
+ }
194
+ });
150
195
  setPromptText('');
151
196
  (_derivedState$activeS3 = derivedState.activeSession) === null || _derivedState$activeS3 === void 0 || (_derivedState$activeS3 = _derivedState$activeS3.messages) === null || _derivedState$activeS3 === void 0 || _derivedState$activeS3.push({
152
197
  id: crypto.randomUUID(),
153
198
  role: 'user',
154
199
  content: promptText,
155
200
  createdAt: Date.now(),
201
+ context: fileSummary,
156
202
  lib: lib
157
203
  });
158
- // **关键:开启 trigger,开始请求**
159
- setIsStreaming(true);
160
204
  chatScrollIntoView();
161
205
  };
206
+
207
+ // 同步 Valtio store -> useChat state
162
208
  useEffect(function () {
163
- // 检查是否存在临时消息
164
- if (snap.tempMessage) {
165
- var activeSession = derivedState.activeSession;
166
- if (activeSession) {
167
- // 1. 将临时消息正式添加到当前会话中
168
- activeSession.messages.push(snap.tempMessage);
169
- setIsStreaming(true);
170
- AIChatStore.tempMessage = null;
209
+ if (simple) {
210
+ return;
211
+ }
212
+ setTimeout(function () {
213
+ var _derivedSnap$activeSe6;
214
+ var sessionMessages = (_derivedSnap$activeSe6 = derivedSnap.activeSession) === null || _derivedSnap$activeSe6 === void 0 ? void 0 : _derivedSnap$activeSe6.messages;
215
+ if ((sessionMessages === null || sessionMessages === void 0 ? void 0 : sessionMessages.length) > 0) {
216
+ var converted = convertToUIMessages(sessionMessages);
217
+ // 避免无限循环,仅当消息数量或内容不同时更新
218
+ if (messages.length !== converted.length || JSON.stringify(messages) !== JSON.stringify(converted)) {
219
+ setMessages(converted);
220
+ }
221
+ } else {
222
+ setMessages([]);
171
223
  }
224
+ });
225
+ }, [(_derivedSnap$activeSe7 = derivedSnap.activeSession) === null || _derivedSnap$activeSe7 === void 0 ? void 0 : _derivedSnap$activeSe7.id, (_derivedSnap$activeSe8 = derivedSnap.activeSession) === null || _derivedSnap$activeSe8 === void 0 || (_derivedSnap$activeSe8 = _derivedSnap$activeSe8.messages) === null || _derivedSnap$activeSe8 === void 0 ? void 0 : _derivedSnap$activeSe8.length]);
226
+
227
+ // 处理从外部(如demo页)发起的对话
228
+ useEffect(function () {
229
+ if (snap.tempMessage) {
230
+ var _derivedState$activeS4, _derivedState$activeS5;
231
+ sendMessage({
232
+ text: snap.tempMessage.content
233
+ });
234
+ (_derivedState$activeS4 = derivedState.activeSession) === null || _derivedState$activeS4 === void 0 || (_derivedState$activeS4 = _derivedState$activeS4.messages) === null || _derivedState$activeS4 === void 0 || (_derivedState$activeS5 = _derivedState$activeS4.push) === null || _derivedState$activeS5 === void 0 || _derivedState$activeS5.call(_derivedState$activeS4, snap.tempMessage);
235
+ AIChatStore.tempMessage = null;
172
236
  }
237
+ }, [snap.tempMessage]);
238
+ useEffect(function () {
239
+ chatScrollIntoView();
173
240
  if (simple) {
174
241
  createPureNewSession(title);
175
242
  }
176
- return function () {
177
- clearEmptySession();
178
- };
179
243
  }, []);
180
244
  useEffect(function () {
181
- if (derivedState.activeSession && Date.now() - derivedState.activeSession.createdAt > 5000) {
182
- setLoading(false);
183
- setIsStreaming(false);
184
- }
245
+ chatScrollIntoView();
246
+ stop();
185
247
  }, [snap.activeSessionId]);
186
- var showMessages = [].concat(_toConsumableArray(messages), _toConsumableArray((_derivedSnap$activeSe3 = derivedSnap.activeSession) === null || _derivedSnap$activeSe3 === void 0 ? void 0 : _derivedSnap$activeSe3.messages));
248
+
249
+ // 将 messages 数组作为依赖项。当它变化时,Hook 会运行。
250
+ var _useAutoScroll = useAutoScroll(messages),
251
+ containerRef = _useAutoScroll.containerRef,
252
+ anchorRef = _useAutoScroll.anchorRef;
187
253
  return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Flex, {
188
254
  gap: "middle",
189
255
  vertical: true,
190
- className: styles.chatContainer
191
- }, showMessages === null || showMessages === void 0 ? void 0 : showMessages.map(function (msg, index) {
256
+ className: styles.chatContainer,
257
+ ref: containerRef
258
+ }, messages.map(function (msg, index) {
259
+ var textContent = getTextContent(msg);
192
260
  return /*#__PURE__*/React.createElement(Bubble, {
193
- key: index,
261
+ key: msg.id || index,
194
262
  content: /*#__PURE__*/React.createElement(MarkdownComponent, {
195
- content: msg.content
263
+ content: textContent,
264
+ showRunButton: !props.simple
196
265
  }),
197
266
  avatar: msg.role === 'assistant' ? avatar : null,
198
- footer: msg.role === 'assistant' && index > 0 ? /*#__PURE__*/React.createElement(Space, {
267
+ footer: msg.role === 'assistant' && index > 0 && index === messages.length - 1 && status === 'ready' ? /*#__PURE__*/React.createElement(Space, {
199
268
  size: "small"
200
269
  }, /*#__PURE__*/React.createElement(Tooltip, {
201
- title: "\u70B9\u8D5E"
202
- }, /*#__PURE__*/React.createElement(Button, {
203
- color: "default",
204
- variant: "text",
205
- size: "small",
206
- icon: /*#__PURE__*/React.createElement(LikeOutlined, null)
207
- })), /*#__PURE__*/React.createElement(Tooltip, {
208
- title: "\u70B9\u8E29"
209
- }, /*#__PURE__*/React.createElement(Button, {
210
- color: "default",
211
- variant: "text",
212
- size: "small",
213
- icon: /*#__PURE__*/React.createElement(DislikeOutlined, null)
214
- })), index === showMessages.length - 1 && /*#__PURE__*/React.createElement(Tooltip, {
215
- title: "\u518D\u6765\u4E00\u6B21"
270
+ title: formatMessage({
271
+ id: 'ai.msgbox.retry'
272
+ })
216
273
  }, /*#__PURE__*/React.createElement(Button, {
217
274
  onClick: function onClick() {
275
+ regenerate();
218
276
  derivedState.activeSession.messages.pop();
219
- setIsStreaming(true);
220
277
  },
221
278
  color: "default",
222
279
  variant: "text",
223
280
  size: "small",
224
281
  icon: /*#__PURE__*/React.createElement(SyncOutlined, null)
225
282
  })), /*#__PURE__*/React.createElement(Tooltip, {
226
- title: "\u590D\u5236"
283
+ title: formatMessage({
284
+ id: 'ai.msgbox.copy'
285
+ })
227
286
  }, /*#__PURE__*/React.createElement(Button, {
228
287
  color: "default",
229
288
  variant: "text",
230
289
  size: "small",
231
290
  onClick: function onClick() {
232
- return copyToClipboard(msg.content);
291
+ return copyToClipboard(textContent);
233
292
  },
234
- icon: copyState.value === msg.content ? /*#__PURE__*/React.createElement(CheckOutlined, null) : /*#__PURE__*/React.createElement(CopyOutlined, null)
293
+ icon: copyState.value === textContent ? /*#__PURE__*/React.createElement(CheckOutlined, null) : /*#__PURE__*/React.createElement(CopyOutlined, null)
235
294
  }))) : null,
236
295
  placement: msg.role === 'user' ? 'end' : 'start'
237
296
  });
238
- }), loading && /*#__PURE__*/React.createElement(Bubble, {
297
+ }), (status === 'streaming' || status === 'submitted') && ((_messages = messages[messages.length - 1]) === null || _messages === void 0 ? void 0 : _messages.role) === 'user' && /*#__PURE__*/React.createElement(Bubble, {
239
298
  placement: "start",
240
299
  avatar: avatar,
241
- loading: loading
300
+ loading: true
301
+ }), /*#__PURE__*/React.createElement("div", {
302
+ ref: anchorRef,
303
+ id: "msgBoxAnchor"
242
304
  })), /*#__PURE__*/React.createElement("div", null, !props.simple && /*#__PURE__*/React.createElement("div", {
243
305
  className: styles.newButtonContainer
244
- }, /*#__PURE__*/React.createElement("button", {
306
+ }, /*#__PURE__*/React.createElement(Space, null, /*#__PURE__*/React.createElement("button", {
245
307
  type: "button",
246
308
  onClick: function onClick() {
247
- return history.push('/');
309
+ return createPureNewSession();
248
310
  },
249
311
  className: styles.newButton
250
- }, /*#__PURE__*/React.createElement(Space, null, /*#__PURE__*/React.createElement(PlusSquareOutlined, null), "\u5F00\u59CB\u65B0\u5BF9\u8BDD"))), /*#__PURE__*/React.createElement(PromptTextarea, {
312
+ }, /*#__PURE__*/React.createElement(Space, null, /*#__PURE__*/React.createElement(PlusSquareOutlined, null), formatMessage({
313
+ id: 'ai.msgbox.start.new.chat'
314
+ }))))), /*#__PURE__*/React.createElement(PromptTextarea, {
251
315
  size: "compact",
252
316
  mode: "implement",
253
317
  value: promptText,
254
318
  onChange: setPromptText,
255
- loading: loading,
256
- onCancel: function onCancel() {
257
- setIsStreaming(false);
258
- setLoading(false);
259
- },
319
+ loading: status === 'streaming' || status === 'submitted',
320
+ onCancel: stop,
260
321
  showAction: !props.simple,
261
322
  style: {
262
323
  marginBottom: 0
263
324
  },
264
325
  onConfirm: handleSubmit,
265
326
  lib: lib,
266
- onLibChange: setLib
327
+ onLibChange: setLib,
328
+ onDataSummaryChange: setFileSummary
267
329
  })));
268
330
  }
269
331
  export default MsgBox;
@@ -5,7 +5,7 @@
5
5
 
6
6
  .query {
7
7
  background: #c9dfff;
8
- box-shadow: 0 4px 10px rgba(51, 113, 242, .1);
8
+ box-shadow: 0 4px 10px rgba(51, 113, 242, 10%);
9
9
  border-radius: 8px;
10
10
  padding: 8px 16px;
11
11
  max-width: calc(100% - 100px);
@@ -26,7 +26,7 @@
26
26
  padding: 0 8px;
27
27
  color: var(--primary-color);
28
28
  font-size: 14px;
29
- background: rgba(135, 59, 244, .145);
29
+ background: rgba(135, 59, 244, 14.5%);
30
30
  border-radius: 6px;
31
31
  line-height: 22px;
32
32
  margin: 12px auto;
@@ -34,6 +34,7 @@
34
34
 
35
35
  .newButtonContainer {
36
36
  display: flex;
37
+ justify-content: center;
37
38
  }
38
39
 
39
40
  .chatContainer {
@@ -0,0 +1,46 @@
1
+ function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
2
+ function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
3
+ function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
4
+ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
5
+ function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
6
+ function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
7
+ import { useRef, useLayoutEffect, useState } from 'react';
8
+
9
+ // threshold: 容差值,表示离底部多远以内都算“在底部”
10
+ export var useAutoScroll = function useAutoScroll(dependencies) {
11
+ var threshold = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 100;
12
+ // 指向滚动容器
13
+ var containerRef = useRef(null);
14
+ // 指向一个永远在列表末尾的空div,作为滚动的目标
15
+ var anchorRef = useRef(null);
16
+ var _useState = useState(false),
17
+ _useState2 = _slicedToArray(_useState, 2),
18
+ showScrollDownButton = _useState2[0],
19
+ setShowScrollDownButton = _useState2[1];
20
+ useLayoutEffect(function () {
21
+ var container = containerRef.current;
22
+ if (!container) return;
23
+
24
+ // scrollTop: 滚动条距离顶部的距离
25
+ // scrollHeight: 整个可滚动内容的总高度
26
+ // clientHeight: 容器可视区域的高度
27
+ var isAtBottom = container.scrollHeight - container.scrollTop <= container.clientHeight + threshold + 200;
28
+
29
+ // 只有当用户已经在底部时,才执行自动滚动
30
+ if (isAtBottom) {
31
+ var _anchorRef$current;
32
+ (_anchorRef$current = anchorRef.current) === null || _anchorRef$current === void 0 || _anchorRef$current.scrollIntoView({
33
+ block: 'end' // 滚动到元素的末尾
34
+ });
35
+ setShowScrollDownButton(false);
36
+ } else {
37
+ setShowScrollDownButton(true);
38
+ }
39
+ }, [dependencies, threshold]); // 依赖项改变时(比如新消息来了),触发此 effect
40
+
41
+ return {
42
+ containerRef: containerRef,
43
+ anchorRef: anchorRef,
44
+ showScrollDownButton: showScrollDownButton
45
+ };
46
+ };
@@ -1,13 +1,10 @@
1
- function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
2
- function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
3
- function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
4
- function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
5
1
  import React from 'react';
6
2
  import styles from "./index.module.less";
7
3
  import { ConversationsMenu } from "../ConversationsMenu";
8
4
  import { AIChatStore } from "../../../../model/AIChat";
9
- import { useSnapshot } from "valtio";
10
- import classnames from "classnames";
5
+ import { useSnapshot } from 'valtio';
6
+ import classnames from 'classnames';
7
+ import SplitPane from 'react-split-pane';
11
8
  function SessionLayout(props) {
12
9
  var children = props.children;
13
10
  var snap = useSnapshot(AIChatStore);
@@ -16,10 +13,21 @@ function SessionLayout(props) {
16
13
  }
17
14
  return /*#__PURE__*/React.createElement("div", {
18
15
  className: styles.container
19
- }, /*#__PURE__*/React.createElement(ConversationsMenu, null), /*#__PURE__*/React.createElement("div", {
20
- className: classnames(styles.msgBox, _defineProperty(_defineProperty({}, styles.msgBoxHalf, snap.codeBlock), styles.msgBoxFull, !snap.codeBlock))
21
- }, children[0]), snap.codeBlock && /*#__PURE__*/React.createElement("div", {
16
+ }, /*#__PURE__*/React.createElement(ConversationsMenu, null),
17
+ // @ts-ignore
18
+ snap.codeBlock ? /*#__PURE__*/React.createElement(SplitPane, {
19
+ split: "vertical",
20
+ defaultSize: "50vw",
21
+ primary: "second",
22
+ style: {
23
+ position: "unset"
24
+ }
25
+ }, /*#__PURE__*/React.createElement("div", {
26
+ className: classnames(styles.msgBox)
27
+ }, children[0]), /*#__PURE__*/React.createElement("div", {
22
28
  className: styles.taskBox
23
- }, children[1]));
29
+ }, children[1])) : /*#__PURE__*/React.createElement("div", {
30
+ className: classnames(styles.msgBox, styles.msgBoxFull)
31
+ }, children[0]));
24
32
  }
25
33
  export { SessionLayout };
@@ -14,6 +14,7 @@
14
14
  }
15
15
 
16
16
  .msgBox {
17
+ height: 100%;
17
18
  padding: 16px;
18
19
  min-width: 400px;
19
20
  justify-content: space-between;
@@ -28,7 +29,8 @@
28
29
  }
29
30
 
30
31
  .taskBox {
32
+ height: calc(100% - 32px);
31
33
  margin: 16px;
32
34
  flex-grow: 1;
33
- background: #ffffff;
35
+ background: #fff;
34
36
  }
@@ -77,14 +77,20 @@ export function generateDependencies(codeString) {
77
77
  }
78
78
  export function wrap2VisionSnap() {
79
79
  var codeBlock = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
80
+ var dependencies = generateDependencies(codeBlock);
81
+ var rootElementType = dependencies['@antv/f2'] ? 'canvas' : 'div';
80
82
  return {
81
83
  modules: {
82
84
  '/package.json': {
83
85
  fpath: '/package.json',
84
- code: "{\n \"name\": \"AntV-master\",\n \"version\": \"1.0.0\",\n \"main\": \"/src/index.jsx\",\n \"dependencies\": ".concat(JSON.stringify(generateDependencies(codeBlock), null, 2), "\n}")
86
+ code: "{\n \"name\": \"AntV-adapted-project\",\n \"version\": \"1.0.0\",\n \"main\": \"/src/index.jsx\",\n \"dependencies\": ".concat(JSON.stringify(dependencies, null, 2), "\n}")
85
87
  },
86
88
  '/src/index.jsx': {
87
89
  fpath: '/src/index.jsx',
90
+ code: "\n// --- Adapter Script ---\n\n// 1. \u627E\u5230\u7F16\u8F91\u5668\u73AF\u5883\u63D0\u4F9B\u7684\u6839\u8282\u70B9 #root\nconst rootElement = document.getElementById('root');\n\nif (rootElement) {\n // 2. \u5728 #root \u5185\u90E8\u521B\u5EFA\u4E00\u4E2A ".concat(rootElementType, "\n const containerElement = document.createElement('").concat(rootElementType, "');\n\n // 3. \u5C06\u8FD9\u4E2A div \u7684 id \u8BBE\u7F6E\u4E3A 'container'\uFF0C\u4EE5\u6EE1\u8DB3\u7528\u6237\u4EE3\u7801\u7684\u9700\u6C42\n containerElement.id = 'container';\n\n // 4. \u5C06\u5B83\u6DFB\u52A0\u5230 #root \u4E2D\n rootElement.appendChild(containerElement);\n\n // 5. \u73B0\u5728 DOM \u4E2D\u5DF2\u7ECF\u5B58\u5728 #container\uFF0C\u5B89\u5168\u5730\u5BFC\u5165\u5E76\u6267\u884C\u7528\u6237\u7684\u4EE3\u7801\n import('./App.jsx');\n\n}\n ")
91
+ },
92
+ '/src/App.jsx': {
93
+ fpath: '/src/App.jsx',
88
94
  code: codeBlock
89
95
  }
90
96
  }