@antv/dumi-theme-antv 0.7.9 → 0.8.0-alpha.3
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/builtins/Playground/index.js +1 -1
- package/dist/builtins/Playground/index.module.less +0 -1
- package/dist/common/styles/Common.js +1 -1
- package/dist/common/styles/theme.js +1 -1
- package/dist/components/AI/HomeDialog/AntVBanner/index.js +4 -0
- package/dist/components/AI/HomeDialog/AntVBanner/index.module.less +35 -0
- package/dist/components/AI/HomeDialog/ModeSelector/ModeSelectorDropdown.js +42 -0
- package/dist/components/AI/HomeDialog/ModeSelector/index.js +32 -0
- package/dist/components/AI/HomeDialog/ModeSelector/index.module.less +289 -0
- package/dist/components/AI/HomeDialog/PromptTextarea/ChooseLib/index.js +62 -0
- package/dist/components/AI/HomeDialog/PromptTextarea/ChooseLib/index.module.less +4 -0
- package/dist/components/AI/HomeDialog/PromptTextarea/DatasourceCard/index.js +25 -0
- package/dist/components/AI/HomeDialog/PromptTextarea/DatasourceCard/index.module.less +42 -0
- package/dist/components/AI/HomeDialog/PromptTextarea/SendButton.js +23 -0
- package/dist/components/AI/HomeDialog/PromptTextarea/SendButton.module.less +9 -0
- package/dist/components/AI/HomeDialog/PromptTextarea/Uploader/DataUploader.js +225 -0
- package/dist/components/AI/HomeDialog/PromptTextarea/index.js +172 -0
- package/dist/components/AI/HomeDialog/PromptTextarea/index.module.less +128 -0
- package/dist/components/AI/HomeDialog/RecommendCase/Card.js +80 -0
- package/dist/components/AI/HomeDialog/RecommendCase/card.module.less +131 -0
- package/dist/components/AI/HomeDialog/RecommendCase/index.js +130 -0
- package/dist/components/AI/HomeDialog/RecommendCase/index.module.less +45 -0
- package/dist/components/AI/HomeDialog/RecommendCase/recommend.json +66 -0
- package/dist/components/AI/HomeDialog/index.js +62 -0
- package/dist/components/AI/HomeDialog/index.module.less +3 -0
- package/dist/components/AI/constant.js +37 -0
- package/dist/components/AI/index.js +1 -0
- package/dist/components/AI/types.js +1 -0
- package/dist/components/AI/utils.js +38 -0
- package/dist/components/Login/Captcha/index.js +185 -0
- package/dist/components/Login/Captcha/index.less +91 -0
- package/dist/components/Login/CheckCode/index.js +244 -0
- package/dist/components/Login/CheckCode/index.less +137 -0
- package/dist/components/Login/CountDownButton/index.js +109 -0
- package/dist/components/Login/CountDownButton/index.less +8 -0
- package/dist/components/Login/LoginForm.js +239 -0
- package/dist/components/Login/LoginForm.less +408 -0
- package/dist/components/Login/index.js +24 -0
- package/dist/components/Login/openAuthWindow.js +54 -0
- package/dist/components/Login/types.js +5 -0
- package/dist/components/Login/utils.js +47 -0
- package/dist/hooks/useProducts.js +39 -0
- package/dist/hooks/useStreamingText.js +139 -0
- package/dist/hooks/useTypewriter.js +69 -0
- package/dist/hooks/useVisionsnapSdk.js +159 -0
- package/dist/layouts/DocLayout.js +2 -2
- package/dist/layouts/GlobalLayout/index.js +22 -0
- package/dist/locales/en.json +132 -1
- package/dist/locales/zh.json +132 -1
- package/dist/model/AIChat.js +313 -0
- package/dist/model/auth.js +147 -0
- package/dist/pages/AIPlayground/components/ConversationsMenu/index.js +176 -0
- package/dist/pages/AIPlayground/components/ConversationsMenu/index.module.less +46 -0
- package/dist/pages/AIPlayground/components/MarkdownComponent/MarkdownCodeBlock.js +97 -0
- package/dist/pages/AIPlayground/components/MarkdownComponent/MarkdownCodeBlock.module.less +13 -0
- package/dist/pages/AIPlayground/components/MarkdownComponent/index.js +50 -0
- package/dist/pages/AIPlayground/components/MsgBox/index.js +407 -0
- package/dist/pages/AIPlayground/components/MsgBox/index.module.less +43 -0
- package/dist/pages/AIPlayground/components/MsgBox/useAutoScroll.js +46 -0
- package/dist/pages/AIPlayground/components/SessionLayout/index.js +62 -0
- package/dist/pages/AIPlayground/components/SessionLayout/index.module.less +37 -0
- package/dist/pages/AIPlayground/components/TaskBox/generateCode.js +230 -0
- package/dist/pages/AIPlayground/components/TaskBox/index.js +101 -0
- package/dist/pages/AIPlayground/components/TaskBox/index.module.less +9 -0
- package/dist/pages/AIPlayground/demo.js +34 -0
- package/dist/pages/AIPlayground/index.js +12 -0
- package/dist/pages/AIPlayground/index.module.less +5 -0
- package/dist/pages/Examples/components/Accouncement/index.module.less +1 -1
- package/dist/pages/Examples/index.module.less +13 -13
- package/dist/pages/Index/components/Cases/index.module.less +9 -9
- package/dist/pages/Index/components/Companies/index.module.less +5 -4
- package/dist/pages/Index/components/Features/FeatureCard.module.less +4 -5
- package/dist/pages/Index/components/Features/index.module.less +6 -6
- package/dist/pages/Index/components/_.less +9 -9
- package/dist/pages/Index/index.js +1 -1
- package/dist/plugin/index.js +14 -6
- package/dist/slots/Banner/Notification.module.less +8 -8
- package/dist/slots/Banner/index.module.less +11 -10
- package/dist/slots/CodeEditor/Toolbar.js +23 -27
- package/dist/slots/CodeEditor/Toolbar.module.less +7 -0
- package/dist/slots/CodeEditor/index.js +67 -5
- package/dist/slots/CodeEditor/index.module.less +24 -0
- package/dist/slots/CodeEditor/utils.js +2 -1
- package/dist/slots/CodePreview/index.module.less +0 -3
- package/dist/slots/CodeRunner/index.js +24 -11
- package/dist/slots/ContentTable/index.module.less +2 -1
- package/dist/{pages/Index/components → slots}/Detail/News.js +1 -1
- package/dist/{pages/Index/components → slots}/Detail/News.module.less +9 -9
- package/dist/{pages/Index/components → slots}/Detail/index.js +13 -29
- package/dist/{pages/Index/components → slots}/Detail/index.module.less +24 -21
- package/dist/slots/ExampleSider/index.module.less +3 -4
- package/dist/slots/Footer/index.module.less +3 -3
- package/dist/slots/Header/Products/Product.module.less +3 -3
- package/dist/slots/Header/Products/getProducts.js +20 -26
- package/dist/slots/Header/Products/index.js +20 -16
- package/dist/slots/Header/Search/SearchResult.js +53 -14
- package/dist/slots/Header/Search/SearchResult.module.less +1 -0
- package/dist/slots/Header/Search/index.js +2 -1
- package/dist/slots/Header/index.js +72 -30
- package/dist/slots/Header/index.module.less +15 -7
- package/dist/slots/LiveExample/index.js +1 -1
- package/dist/slots/LiveExample/index.module.less +1 -1
- package/dist/slots/Loading/index.module.less +30 -28
- package/dist/slots/ManualContent/index.module.less +14 -17
- package/dist/slots/_.less +9 -9
- package/dist/static/user.svg +3 -0
- package/dist/typings.d.ts +11 -0
- package/dist/utils/analytics.js +16 -0
- package/dist/utils/code.js +35 -0
- package/dist/utils/env.js +63 -0
- package/dist/utils/index.js +7 -0
- package/dist/utils/request.js +42 -0
- package/package.json +33 -17
|
@@ -0,0 +1,407 @@
|
|
|
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 _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
|
|
3
|
+
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."); }
|
|
4
|
+
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); }
|
|
5
|
+
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; }
|
|
6
|
+
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; } }
|
|
7
|
+
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
8
|
+
import { BranchesOutlined, CheckOutlined, CopyOutlined, DeleteOutlined, PlusSquareOutlined, SyncOutlined, ToolOutlined } from '@ant-design/icons';
|
|
9
|
+
import { Bubble } from '@ant-design/x';
|
|
10
|
+
import { Button, Flex, Space, Tooltip } from 'antd';
|
|
11
|
+
import { useChat } from '@ai-sdk/react';
|
|
12
|
+
import { TextStreamChatTransport } from 'ai';
|
|
13
|
+
import { useIntl, useSiteData } from 'dumi';
|
|
14
|
+
import { findLast } from 'lodash-es';
|
|
15
|
+
import React, { useEffect, useState, useMemo, useRef } from 'react';
|
|
16
|
+
import { useCopyToClipboard } from 'react-use';
|
|
17
|
+
import { useSnapshot } from 'valtio';
|
|
18
|
+
import { PromptTextarea } from "../../../../components/AI/HomeDialog/PromptTextarea";
|
|
19
|
+
import { AIChatStore, branchMessage, clearEmptySession, createPureNewSession, deleteMessage, derivedState } from "../../../../model/AIChat";
|
|
20
|
+
import { getCodeFromMarkdown, isPreviewable } from "../../../../utils/code";
|
|
21
|
+
import { MarkdownComponent } from "../MarkdownComponent";
|
|
22
|
+
import styles from "./index.module.less";
|
|
23
|
+
import { useAutoScroll } from "./useAutoScroll";
|
|
24
|
+
import { getBaseURL } from "../../../../utils/env";
|
|
25
|
+
import { AIMode } from "../../../../components/AI/constant";
|
|
26
|
+
import { trackEvent } from "../../../../utils/analytics";
|
|
27
|
+
var avatar = {
|
|
28
|
+
icon: /*#__PURE__*/React.createElement("img", {
|
|
29
|
+
draggable: false,
|
|
30
|
+
src: 'https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*7svFR6wkPMoAAAAAAAAAAAAADmJ7AQ/original',
|
|
31
|
+
alt: "AntV"
|
|
32
|
+
}),
|
|
33
|
+
style: {
|
|
34
|
+
borderRadius: 0,
|
|
35
|
+
backgroundColor: 'transparent'
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
var chatScrollIntoView = function chatScrollIntoView() {
|
|
39
|
+
setTimeout(function () {
|
|
40
|
+
document.getElementById('msgBoxAnchor').scrollIntoView({
|
|
41
|
+
block: 'end'
|
|
42
|
+
});
|
|
43
|
+
}, 100);
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
// 辅助函数:将旧的 Message 格式转换为新的 UIMessage 格式
|
|
47
|
+
var convertToUIMessages = function convertToUIMessages(messages) {
|
|
48
|
+
return messages.map(function (msg) {
|
|
49
|
+
return {
|
|
50
|
+
id: msg.id,
|
|
51
|
+
role: msg.role,
|
|
52
|
+
parts: [{
|
|
53
|
+
type: 'text',
|
|
54
|
+
text: msg.content
|
|
55
|
+
}]
|
|
56
|
+
};
|
|
57
|
+
});
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
// 辅助函数:从 UIMessage 提取文本内容
|
|
61
|
+
var getTextContent = function getTextContent(message) {
|
|
62
|
+
return message.parts.filter(function (part) {
|
|
63
|
+
return part.type === 'text';
|
|
64
|
+
}).map(function (part) {
|
|
65
|
+
return part.text;
|
|
66
|
+
}).join('');
|
|
67
|
+
};
|
|
68
|
+
function MsgBox(props) {
|
|
69
|
+
var _derivedSnap$activeSe, _derivedSnap$activeSe2, _derivedSnap$activeSe4, _derivedSnap$activeSe7, _derivedSnap$activeSe8, _messages;
|
|
70
|
+
var _props$messages = props.messages,
|
|
71
|
+
initialMessages = _props$messages === void 0 ? [] : _props$messages,
|
|
72
|
+
_props$simple = props.simple,
|
|
73
|
+
simple = _props$simple === void 0 ? false : _props$simple,
|
|
74
|
+
onCodegen = props.onCodegen,
|
|
75
|
+
title = props.title;
|
|
76
|
+
var _useIntl = useIntl(),
|
|
77
|
+
formatMessage = _useIntl.formatMessage;
|
|
78
|
+
var _useState = useState(''),
|
|
79
|
+
_useState2 = _slicedToArray(_useState, 2),
|
|
80
|
+
promptText = _useState2[0],
|
|
81
|
+
setPromptText = _useState2[1];
|
|
82
|
+
var _useState3 = useState(''),
|
|
83
|
+
_useState4 = _slicedToArray(_useState3, 2),
|
|
84
|
+
fileSummary = _useState4[0],
|
|
85
|
+
setFileSummary = _useState4[1];
|
|
86
|
+
var snap = useSnapshot(AIChatStore);
|
|
87
|
+
var derivedSnap = useSnapshot(derivedState);
|
|
88
|
+
var _useCopyToClipboard = useCopyToClipboard(),
|
|
89
|
+
_useCopyToClipboard2 = _slicedToArray(_useCopyToClipboard, 2),
|
|
90
|
+
copyState = _useCopyToClipboard2[0],
|
|
91
|
+
copyToClipboard = _useCopyToClipboard2[1];
|
|
92
|
+
var latestUserMessage = findLast((_derivedSnap$activeSe = derivedSnap.activeSession) === null || _derivedSnap$activeSe === void 0 ? void 0 : _derivedSnap$activeSe.messages, function (msg) {
|
|
93
|
+
return msg.role === 'user';
|
|
94
|
+
});
|
|
95
|
+
// 使用 ref 存储动态值,避免重新创建 transport
|
|
96
|
+
var anonymousUserIdRef = useRef(snap.anonymousUserId);
|
|
97
|
+
var activeSessionIdRef = useRef((_derivedSnap$activeSe2 = derivedSnap.activeSession) === null || _derivedSnap$activeSe2 === void 0 ? void 0 : _derivedSnap$activeSe2.id);
|
|
98
|
+
var _useSiteData = useSiteData(),
|
|
99
|
+
themeConfig = _useSiteData.themeConfig;
|
|
100
|
+
useEffect(function () {
|
|
101
|
+
var _derivedSnap$activeSe3;
|
|
102
|
+
anonymousUserIdRef.current = snap.anonymousUserId;
|
|
103
|
+
activeSessionIdRef.current = (_derivedSnap$activeSe3 = derivedSnap.activeSession) === null || _derivedSnap$activeSe3 === void 0 ? void 0 : _derivedSnap$activeSe3.id;
|
|
104
|
+
}, [snap.anonymousUserId, (_derivedSnap$activeSe4 = derivedSnap.activeSession) === null || _derivedSnap$activeSe4 === void 0 ? void 0 : _derivedSnap$activeSe4.id]);
|
|
105
|
+
|
|
106
|
+
// 转换初始消息为新格式
|
|
107
|
+
var convertedInitialMessages = useMemo(function () {
|
|
108
|
+
return convertToUIMessages(initialMessages);
|
|
109
|
+
}, [initialMessages]);
|
|
110
|
+
|
|
111
|
+
// 核心:使用 useChat hook,配置 DefaultChatTransport
|
|
112
|
+
var _useChat = useChat({
|
|
113
|
+
transport: new TextStreamChatTransport({
|
|
114
|
+
api: getBaseURL() + '/api/modules/antv/ai/chat',
|
|
115
|
+
credentials: 'include',
|
|
116
|
+
headers: {
|
|
117
|
+
// xxx
|
|
118
|
+
},
|
|
119
|
+
// body 可以是函数,用于获取最新的动态值
|
|
120
|
+
body: function body() {
|
|
121
|
+
return {
|
|
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: AIChatStore.lib,
|
|
127
|
+
mode: AIChatStore.mode
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
}),
|
|
131
|
+
messages: convertedInitialMessages,
|
|
132
|
+
// 当AI响应结束时触发
|
|
133
|
+
onFinish: function onFinish(_ref) {
|
|
134
|
+
var message = _ref.message,
|
|
135
|
+
isAbort = _ref.isAbort,
|
|
136
|
+
isDisconnect = _ref.isDisconnect,
|
|
137
|
+
isError = _ref.isError;
|
|
138
|
+
if (!isAbort && !isDisconnect && !isError) {
|
|
139
|
+
var _derivedState$activeS;
|
|
140
|
+
var messageContent = getTextContent(message);
|
|
141
|
+
if (isPreviewable(messageContent)) {
|
|
142
|
+
var codeBlock = getCodeFromMarkdown(messageContent).code;
|
|
143
|
+
AIChatStore.codeBlock = codeBlock;
|
|
144
|
+
onCodegen === null || onCodegen === void 0 || onCodegen(codeBlock);
|
|
145
|
+
} else {
|
|
146
|
+
AIChatStore.codeBlock = '';
|
|
147
|
+
}
|
|
148
|
+
(_derivedState$activeS = derivedState.activeSession) === null || _derivedState$activeS === void 0 || (_derivedState$activeS = _derivedState$activeS.messages) === null || _derivedState$activeS === void 0 || _derivedState$activeS.push({
|
|
149
|
+
id: crypto.randomUUID(),
|
|
150
|
+
role: 'assistant',
|
|
151
|
+
content: messageContent,
|
|
152
|
+
createdAt: Date.now()
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
},
|
|
156
|
+
onError: function onError(error) {
|
|
157
|
+
var _derivedState$activeS2;
|
|
158
|
+
console.error('回答失败', error);
|
|
159
|
+
// 同步错误消息到 valtio
|
|
160
|
+
(_derivedState$activeS2 = derivedState.activeSession) === null || _derivedState$activeS2 === void 0 || (_derivedState$activeS2 = _derivedState$activeS2.messages) === null || _derivedState$activeS2 === void 0 || _derivedState$activeS2.push({
|
|
161
|
+
id: crypto.randomUUID(),
|
|
162
|
+
role: 'assistant',
|
|
163
|
+
content: formatMessage({
|
|
164
|
+
id: 'ai.msgbox.error.response'
|
|
165
|
+
}),
|
|
166
|
+
createdAt: Date.now()
|
|
167
|
+
// mode,
|
|
168
|
+
// lib,
|
|
169
|
+
});
|
|
170
|
+
},
|
|
171
|
+
experimental_throttle: 500
|
|
172
|
+
}),
|
|
173
|
+
messages = _useChat.messages,
|
|
174
|
+
setMessages = _useChat.setMessages,
|
|
175
|
+
sendMessage = _useChat.sendMessage,
|
|
176
|
+
regenerate = _useChat.regenerate,
|
|
177
|
+
status = _useChat.status,
|
|
178
|
+
stop = _useChat.stop;
|
|
179
|
+
|
|
180
|
+
// 处理用户提交
|
|
181
|
+
var handleSubmit = function handleSubmit() {
|
|
182
|
+
var _derivedSnap$activeSe5, _derivedState$activeS3;
|
|
183
|
+
var trimmedPrompt = promptText.trim();
|
|
184
|
+
if (!trimmedPrompt || status === 'streaming' || status === 'submitted') return;
|
|
185
|
+
if (derivedSnap.activeSession && ((_derivedSnap$activeSe5 = derivedSnap.activeSession.messages) === null || _derivedSnap$activeSe5 === void 0 ? void 0 : _derivedSnap$activeSe5.length) === 0) {
|
|
186
|
+
derivedState.activeSession.title = trimmedPrompt;
|
|
187
|
+
}
|
|
188
|
+
// 使用 sendMessage 函数发送新消息
|
|
189
|
+
// 第二个参数传递每次请求特定的额外数据
|
|
190
|
+
sendMessage({
|
|
191
|
+
text: promptText
|
|
192
|
+
}, {
|
|
193
|
+
body: {
|
|
194
|
+
// context: fileSummary,
|
|
195
|
+
// lib: snap.lib,
|
|
196
|
+
// mode: snap.mode,
|
|
197
|
+
}
|
|
198
|
+
});
|
|
199
|
+
setPromptText('');
|
|
200
|
+
(_derivedState$activeS3 = derivedState.activeSession) === null || _derivedState$activeS3 === void 0 || (_derivedState$activeS3 = _derivedState$activeS3.messages) === null || _derivedState$activeS3 === void 0 || _derivedState$activeS3.push({
|
|
201
|
+
id: crypto.randomUUID(),
|
|
202
|
+
role: 'user',
|
|
203
|
+
content: promptText,
|
|
204
|
+
createdAt: Date.now(),
|
|
205
|
+
context: fileSummary,
|
|
206
|
+
lib: snap.lib
|
|
207
|
+
});
|
|
208
|
+
chatScrollIntoView();
|
|
209
|
+
// 埋点
|
|
210
|
+
if ((typeof window === "undefined" ? "undefined" : _typeof(window)) === 'object') {
|
|
211
|
+
trackEvent('start_ai_chat', {
|
|
212
|
+
entry_point: simple ? 'Drawer' : 'MsgBox',
|
|
213
|
+
mode: AIChatStore.mode,
|
|
214
|
+
lib: AIChatStore.lib,
|
|
215
|
+
page_title: document.title,
|
|
216
|
+
location: location.href
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
};
|
|
220
|
+
|
|
221
|
+
// 同步 Valtio store -> useChat state
|
|
222
|
+
useEffect(function () {
|
|
223
|
+
if (simple) {
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
setTimeout(function () {
|
|
227
|
+
var _derivedSnap$activeSe6;
|
|
228
|
+
var sessionMessages = (_derivedSnap$activeSe6 = derivedSnap.activeSession) === null || _derivedSnap$activeSe6 === void 0 ? void 0 : _derivedSnap$activeSe6.messages;
|
|
229
|
+
if ((sessionMessages === null || sessionMessages === void 0 ? void 0 : sessionMessages.length) > 0) {
|
|
230
|
+
var converted = convertToUIMessages(sessionMessages);
|
|
231
|
+
// 避免无限循环,仅当消息数量或内容不同时更新
|
|
232
|
+
if (messages.length !== converted.length || JSON.stringify(messages) !== JSON.stringify(converted)) {
|
|
233
|
+
setMessages(converted);
|
|
234
|
+
}
|
|
235
|
+
} else {
|
|
236
|
+
setMessages([]);
|
|
237
|
+
}
|
|
238
|
+
});
|
|
239
|
+
}, [(_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]);
|
|
240
|
+
|
|
241
|
+
// 处理从外部(如demo页)发起的对话
|
|
242
|
+
useEffect(function () {
|
|
243
|
+
if (snap.tempMessage) {
|
|
244
|
+
var _derivedState$activeS4, _derivedState$activeS5;
|
|
245
|
+
sendMessage({
|
|
246
|
+
text: snap.tempMessage.content
|
|
247
|
+
});
|
|
248
|
+
(_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);
|
|
249
|
+
AIChatStore.tempMessage = null;
|
|
250
|
+
}
|
|
251
|
+
}, [snap.tempMessage]);
|
|
252
|
+
useEffect(function () {
|
|
253
|
+
chatScrollIntoView();
|
|
254
|
+
if (simple) {
|
|
255
|
+
createPureNewSession(title);
|
|
256
|
+
AIChatStore.mode = AIMode.implement;
|
|
257
|
+
if (!themeConfig.isAntVSite && themeConfig.title) {
|
|
258
|
+
AIChatStore.lib = themeConfig.title;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
return function () {
|
|
262
|
+
if (simple) {
|
|
263
|
+
clearEmptySession();
|
|
264
|
+
}
|
|
265
|
+
};
|
|
266
|
+
}, []);
|
|
267
|
+
useEffect(function () {
|
|
268
|
+
chatScrollIntoView();
|
|
269
|
+
stop();
|
|
270
|
+
AIChatStore.errorMsg = null;
|
|
271
|
+
}, [snap.activeSessionId]);
|
|
272
|
+
|
|
273
|
+
// 将 messages 数组作为依赖项。当它变化时,Hook 会运行。
|
|
274
|
+
var _useAutoScroll = useAutoScroll(messages),
|
|
275
|
+
containerRef = _useAutoScroll.containerRef,
|
|
276
|
+
anchorRef = _useAutoScroll.anchorRef;
|
|
277
|
+
var autofix = function autofix() {
|
|
278
|
+
var _derivedState$activeS6;
|
|
279
|
+
var autoFixPromptText = "".concat(formatMessage({
|
|
280
|
+
id: 'ai.msgbox.auto.fix.prompt'
|
|
281
|
+
}), " [").concat(snap.errorMsg, "]");
|
|
282
|
+
sendMessage({
|
|
283
|
+
text: autoFixPromptText
|
|
284
|
+
}, {
|
|
285
|
+
body: {
|
|
286
|
+
antvContext: snap.codeBlock
|
|
287
|
+
}
|
|
288
|
+
});
|
|
289
|
+
AIChatStore.errorMsg = null;
|
|
290
|
+
(_derivedState$activeS6 = derivedState.activeSession) === null || _derivedState$activeS6 === void 0 || (_derivedState$activeS6 = _derivedState$activeS6.messages) === null || _derivedState$activeS6 === void 0 || _derivedState$activeS6.push({
|
|
291
|
+
id: crypto.randomUUID(),
|
|
292
|
+
role: 'user',
|
|
293
|
+
content: autoFixPromptText,
|
|
294
|
+
createdAt: Date.now(),
|
|
295
|
+
context: snap.codeBlock,
|
|
296
|
+
lib: snap.lib
|
|
297
|
+
});
|
|
298
|
+
chatScrollIntoView();
|
|
299
|
+
};
|
|
300
|
+
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Flex, {
|
|
301
|
+
gap: "middle",
|
|
302
|
+
vertical: true,
|
|
303
|
+
className: styles.chatContainer,
|
|
304
|
+
ref: containerRef
|
|
305
|
+
}, messages.map(function (msg, index) {
|
|
306
|
+
var textContent = getTextContent(msg);
|
|
307
|
+
return /*#__PURE__*/React.createElement(Bubble, {
|
|
308
|
+
key: msg.id || index,
|
|
309
|
+
content: /*#__PURE__*/React.createElement(MarkdownComponent, {
|
|
310
|
+
content: textContent,
|
|
311
|
+
showRunButton: !props.simple
|
|
312
|
+
}),
|
|
313
|
+
avatar: msg.role === 'assistant' ? avatar : null,
|
|
314
|
+
footer: status === 'ready' && /*#__PURE__*/React.createElement(Space, {
|
|
315
|
+
size: "small"
|
|
316
|
+
}, msg.role === 'assistant' && index === messages.length - 1 && /*#__PURE__*/React.createElement(Tooltip, {
|
|
317
|
+
title: formatMessage({
|
|
318
|
+
id: 'ai.msgbox.retry'
|
|
319
|
+
})
|
|
320
|
+
}, /*#__PURE__*/React.createElement(Button, {
|
|
321
|
+
onClick: function onClick() {
|
|
322
|
+
regenerate();
|
|
323
|
+
derivedState.activeSession.messages.pop();
|
|
324
|
+
},
|
|
325
|
+
color: "default",
|
|
326
|
+
variant: "text",
|
|
327
|
+
size: "small",
|
|
328
|
+
icon: /*#__PURE__*/React.createElement(SyncOutlined, null)
|
|
329
|
+
})), /*#__PURE__*/React.createElement(Tooltip, {
|
|
330
|
+
title: formatMessage({
|
|
331
|
+
id: 'ai.msgbox.copy'
|
|
332
|
+
})
|
|
333
|
+
}, /*#__PURE__*/React.createElement(Button, {
|
|
334
|
+
color: "default",
|
|
335
|
+
variant: "text",
|
|
336
|
+
size: "small",
|
|
337
|
+
onClick: function onClick() {
|
|
338
|
+
return copyToClipboard(textContent);
|
|
339
|
+
},
|
|
340
|
+
icon: copyState.value === textContent ? /*#__PURE__*/React.createElement(CheckOutlined, null) : /*#__PURE__*/React.createElement(CopyOutlined, null)
|
|
341
|
+
})), /*#__PURE__*/React.createElement(Tooltip, {
|
|
342
|
+
title: formatMessage({
|
|
343
|
+
id: 'ai.msgbox.continue.from.here'
|
|
344
|
+
})
|
|
345
|
+
}, /*#__PURE__*/React.createElement(Button, {
|
|
346
|
+
color: "default",
|
|
347
|
+
variant: "text",
|
|
348
|
+
size: "small",
|
|
349
|
+
onClick: function onClick() {
|
|
350
|
+
return branchMessage(index);
|
|
351
|
+
},
|
|
352
|
+
icon: /*#__PURE__*/React.createElement(BranchesOutlined, null)
|
|
353
|
+
})), msg.role === 'assistant' && /*#__PURE__*/React.createElement(Tooltip, {
|
|
354
|
+
title: formatMessage({
|
|
355
|
+
id: 'ai.msgbox.delete'
|
|
356
|
+
})
|
|
357
|
+
}, /*#__PURE__*/React.createElement(Button, {
|
|
358
|
+
color: "default",
|
|
359
|
+
variant: "text",
|
|
360
|
+
size: "small",
|
|
361
|
+
onClick: function onClick() {
|
|
362
|
+
return deleteMessage(msg.id);
|
|
363
|
+
},
|
|
364
|
+
icon: /*#__PURE__*/React.createElement(DeleteOutlined, null)
|
|
365
|
+
}))),
|
|
366
|
+
placement: msg.role === 'user' ? 'end' : 'start'
|
|
367
|
+
});
|
|
368
|
+
}), (status === 'streaming' || status === 'submitted') && ((_messages = messages[messages.length - 1]) === null || _messages === void 0 ? void 0 : _messages.role) === 'user' && /*#__PURE__*/React.createElement(Bubble, {
|
|
369
|
+
placement: "start",
|
|
370
|
+
avatar: avatar,
|
|
371
|
+
loading: true
|
|
372
|
+
}), /*#__PURE__*/React.createElement("div", {
|
|
373
|
+
ref: anchorRef,
|
|
374
|
+
id: "msgBoxAnchor"
|
|
375
|
+
})), /*#__PURE__*/React.createElement("div", null, !props.simple && /*#__PURE__*/React.createElement("div", {
|
|
376
|
+
className: styles.newButtonContainer
|
|
377
|
+
}, /*#__PURE__*/React.createElement(Space, null, /*#__PURE__*/React.createElement("button", {
|
|
378
|
+
type: "button",
|
|
379
|
+
onClick: function onClick() {
|
|
380
|
+
return createPureNewSession();
|
|
381
|
+
},
|
|
382
|
+
className: styles.newButton
|
|
383
|
+
}, /*#__PURE__*/React.createElement(Space, null, /*#__PURE__*/React.createElement(PlusSquareOutlined, null), formatMessage({
|
|
384
|
+
id: 'ai.msgbox.start.new.chat'
|
|
385
|
+
}))), snap.errorMsg && status === 'ready' && /*#__PURE__*/React.createElement(Button, {
|
|
386
|
+
onClick: autofix,
|
|
387
|
+
color: "danger",
|
|
388
|
+
variant: "filled",
|
|
389
|
+
icon: /*#__PURE__*/React.createElement(ToolOutlined, null)
|
|
390
|
+
}, formatMessage({
|
|
391
|
+
id: 'ai.msgbox.auto.fix'
|
|
392
|
+
})))), /*#__PURE__*/React.createElement(PromptTextarea, {
|
|
393
|
+
size: "compact",
|
|
394
|
+
value: promptText,
|
|
395
|
+
onChange: setPromptText,
|
|
396
|
+
loading: status === 'streaming' || status === 'submitted',
|
|
397
|
+
onCancel: stop,
|
|
398
|
+
showAction: !props.simple,
|
|
399
|
+
style: {
|
|
400
|
+
marginBottom: 0
|
|
401
|
+
},
|
|
402
|
+
onConfirm: handleSubmit,
|
|
403
|
+
onDataSummaryChange: setFileSummary,
|
|
404
|
+
showModeSelector: true
|
|
405
|
+
})));
|
|
406
|
+
}
|
|
407
|
+
export default MsgBox;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
.msg {
|
|
2
|
+
display: flex;
|
|
3
|
+
justify-content: flex-end;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
.query {
|
|
7
|
+
background: #c9dfff;
|
|
8
|
+
box-shadow: 0 4px 10px rgba(51, 113, 242, 10%);
|
|
9
|
+
border-radius: 8px;
|
|
10
|
+
padding: 8px 16px;
|
|
11
|
+
max-width: calc(100% - 100px);
|
|
12
|
+
word-break: break-all;
|
|
13
|
+
font-size: 14px;
|
|
14
|
+
line-height: 26px;
|
|
15
|
+
font-weight: 400;
|
|
16
|
+
color: #1d2129;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
.newButton {
|
|
20
|
+
display: inline-flex;
|
|
21
|
+
align-items: center;
|
|
22
|
+
cursor: pointer;
|
|
23
|
+
border: none;
|
|
24
|
+
outline: none;
|
|
25
|
+
height: 30px;
|
|
26
|
+
padding: 0 8px;
|
|
27
|
+
color: var(--primary-color);
|
|
28
|
+
font-size: 14px;
|
|
29
|
+
background: rgba(135, 59, 244, 14.5%);
|
|
30
|
+
border-radius: 6px;
|
|
31
|
+
line-height: 22px;
|
|
32
|
+
margin: 12px auto;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.newButtonContainer {
|
|
36
|
+
display: flex;
|
|
37
|
+
justify-content: center;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
.chatContainer {
|
|
41
|
+
height: 100%;
|
|
42
|
+
overflow: auto;
|
|
43
|
+
}
|
|
@@ -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
|
+
};
|
|
@@ -0,0 +1,62 @@
|
|
|
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 classnames from 'classnames';
|
|
8
|
+
import React, { useState } from 'react';
|
|
9
|
+
import SplitPane from 'react-split-pane';
|
|
10
|
+
import { useSnapshot } from 'valtio';
|
|
11
|
+
import { AIChatStore } from "../../../../model/AIChat";
|
|
12
|
+
import { ConversationsMenu } from "../ConversationsMenu";
|
|
13
|
+
import styles from "./index.module.less";
|
|
14
|
+
function SessionLayout(props) {
|
|
15
|
+
var children = props.children;
|
|
16
|
+
var snap = useSnapshot(AIChatStore);
|
|
17
|
+
var _useState = useState(false),
|
|
18
|
+
_useState2 = _slicedToArray(_useState, 2),
|
|
19
|
+
isDragging = _useState2[0],
|
|
20
|
+
setIsDragging = _useState2[1];
|
|
21
|
+
if (!Array.isArray(children)) {
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
25
|
+
className: styles.container
|
|
26
|
+
}, /*#__PURE__*/React.createElement(ConversationsMenu, null), snap.codeBlock ?
|
|
27
|
+
/*#__PURE__*/
|
|
28
|
+
// @ts-ignore
|
|
29
|
+
React.createElement(SplitPane, {
|
|
30
|
+
split: "vertical",
|
|
31
|
+
defaultSize: '50vw',
|
|
32
|
+
onDragStarted: function onDragStarted() {
|
|
33
|
+
return setIsDragging(true);
|
|
34
|
+
},
|
|
35
|
+
onDragFinished: function onDragFinished() {
|
|
36
|
+
return setIsDragging(false);
|
|
37
|
+
},
|
|
38
|
+
primary: "second",
|
|
39
|
+
style: {
|
|
40
|
+
position: 'unset'
|
|
41
|
+
},
|
|
42
|
+
minSize: 100
|
|
43
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
44
|
+
className: classnames(styles.msgBox)
|
|
45
|
+
}, children[0]), /*#__PURE__*/React.createElement("div", {
|
|
46
|
+
className: styles.taskBox
|
|
47
|
+
}, children[1])) : /*#__PURE__*/React.createElement("div", {
|
|
48
|
+
className: classnames(styles.msgBox, styles.msgBoxFull),
|
|
49
|
+
key: snap.codeBlock
|
|
50
|
+
}, children[0]), isDragging && /*#__PURE__*/React.createElement("div", {
|
|
51
|
+
style: {
|
|
52
|
+
position: 'fixed',
|
|
53
|
+
top: 0,
|
|
54
|
+
left: 0,
|
|
55
|
+
right: 0,
|
|
56
|
+
bottom: 0,
|
|
57
|
+
zIndex: 9999,
|
|
58
|
+
cursor: 'col-resize' // 或 'row-resize' 用于水平分割
|
|
59
|
+
}
|
|
60
|
+
}));
|
|
61
|
+
}
|
|
62
|
+
export { SessionLayout };
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
.container {
|
|
2
|
+
display: flex;
|
|
3
|
+
gap: 12px;
|
|
4
|
+
background: #f6f7fb;
|
|
5
|
+
padding: 0;
|
|
6
|
+
flex-grow: 1;
|
|
7
|
+
overflow-y: auto;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
.msgBox, .taskBox{
|
|
11
|
+
box-shadow: 0 2px 7px #e0e0e080;
|
|
12
|
+
border-radius: 12px;
|
|
13
|
+
display: flex;
|
|
14
|
+
flex-direction: column;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
.msgBox {
|
|
18
|
+
height: 100%;
|
|
19
|
+
padding: 16px;
|
|
20
|
+
min-width: 400px;
|
|
21
|
+
justify-content: space-between;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.msgBoxHalf {
|
|
25
|
+
max-width: 40vw;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.msgBoxFull {
|
|
29
|
+
width: 100%;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.taskBox {
|
|
33
|
+
height: calc(100% - 32px);
|
|
34
|
+
margin: 16px;
|
|
35
|
+
flex-grow: 1;
|
|
36
|
+
background: transparent;
|
|
37
|
+
}
|