@antv/dumi-theme-antv 0.8.0-beta.13 → 0.8.0-beta.15

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.
@@ -9,7 +9,7 @@ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len
9
9
  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
10
  function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
11
11
  import { Spin } from 'antd';
12
- import React, { useCallback, useEffect, useState } from 'react';
12
+ import React, { useEffect, useState } from 'react';
13
13
  import { Card } from "./Card";
14
14
  import styles from "./index.module.less";
15
15
  import { ReloadOutlined } from "@ant-design/icons";
@@ -27,54 +27,60 @@ export var RecommendCase = function RecommendCase(props) {
27
27
  setLoading = _useState2[1];
28
28
  var _useSiteData = useSiteData(),
29
29
  themeConfig = _useSiteData.themeConfig;
30
- var _useState3 = useState(RecommendJson),
30
+ var _useState3 = useState([]),
31
31
  _useState4 = _slicedToArray(_useState3, 2),
32
32
  list = _useState4[0],
33
33
  setList = _useState4[1];
34
34
  var _useLibrary = useLibrary(),
35
35
  _useLibrary$data = _useLibrary.data,
36
36
  library = _useLibrary$data === void 0 ? [] : _useLibrary$data;
37
- var fetchList = useCallback( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee() {
38
- var _themeConfig$ai, data, url;
39
- return _regeneratorRuntime().wrap(function _callee$(_context) {
40
- while (1) switch (_context.prev = _context.next) {
41
- case 0:
42
- _context.prev = 0;
43
- setLoading(true);
44
- data = [];
45
- url = themeConfig.isAntVSite ? "".concat(getBaseSiteDataUrl(), "/").concat(sample(library).toLowerCase(), "/recommend.json") : (themeConfig === null || themeConfig === void 0 || (_themeConfig$ai = themeConfig.ai) === null || _themeConfig$ai === void 0 ? void 0 : _themeConfig$ai.recommend) || "".concat(getBaseSiteDataUrl(), "/").concat(themeConfig.title, "/recommend.json");
46
- if (!url) {
47
- _context.next = 10;
37
+ var fetchList = /*#__PURE__*/function () {
38
+ var _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee() {
39
+ var _themeConfig$ai, data, url;
40
+ return _regeneratorRuntime().wrap(function _callee$(_context) {
41
+ while (1) switch (_context.prev = _context.next) {
42
+ case 0:
43
+ _context.prev = 0;
44
+ setLoading(true);
45
+ data = [];
46
+ url = themeConfig.isAntVSite && library.length ? "".concat(getBaseSiteDataUrl(), "/").concat(sample(library).toLowerCase(), "/recommend.json") : (themeConfig === null || themeConfig === void 0 || (_themeConfig$ai = themeConfig.ai) === null || _themeConfig$ai === void 0 ? void 0 : _themeConfig$ai.recommend) || "".concat(getBaseSiteDataUrl(), "/").concat(themeConfig.title, "/recommend.json");
47
+ if (!url) {
48
+ _context.next = 10;
49
+ break;
50
+ }
51
+ _context.next = 7;
52
+ return fetch(url).then(function (res) {
53
+ return res.json();
54
+ });
55
+ case 7:
56
+ data = _context.sent;
57
+ _context.next = 11;
48
58
  break;
49
- }
50
- _context.next = 7;
51
- return fetch(url).then(function (res) {
52
- return res.json();
53
- });
54
- case 7:
55
- data = _context.sent;
56
- _context.next = 11;
57
- break;
58
- case 10:
59
- data = RecommendJson;
60
- case 11:
61
- setList(sampleSize(data, 4));
62
- _context.next = 17;
63
- break;
64
- case 14:
65
- _context.prev = 14;
66
- _context.t0 = _context["catch"](0);
67
- console.log(_context.t0);
68
- case 17:
69
- _context.prev = 17;
70
- setLoading(false);
71
- return _context.finish(17);
72
- case 20:
73
- case "end":
74
- return _context.stop();
75
- }
76
- }, _callee, null, [[0, 14, 17, 20]]);
77
- })), [list]);
59
+ case 10:
60
+ data = RecommendJson;
61
+ case 11:
62
+ setList(sampleSize(data, 4));
63
+ _context.next = 18;
64
+ break;
65
+ case 14:
66
+ _context.prev = 14;
67
+ _context.t0 = _context["catch"](0);
68
+ setList(RecommendJson);
69
+ console.log(_context.t0);
70
+ case 18:
71
+ _context.prev = 18;
72
+ setLoading(false);
73
+ return _context.finish(18);
74
+ case 21:
75
+ case "end":
76
+ return _context.stop();
77
+ }
78
+ }, _callee, null, [[0, 14, 18, 21]]);
79
+ }));
80
+ return function fetchList() {
81
+ return _ref.apply(this, arguments);
82
+ };
83
+ }();
78
84
  useEffect(function () {
79
85
  fetchList();
80
86
  }, []);
@@ -45,7 +45,8 @@ export function HomeDialog(props) {
45
45
  mode: snap.mode,
46
46
  jump: true,
47
47
  context: fileSummary,
48
- lang: locale.id
48
+ lang: locale.id,
49
+ entry_point: 'home'
49
50
  });
50
51
  },
51
52
  style: props.promptTextareaStyle,
@@ -207,6 +207,7 @@
207
207
  "ai.msgbox.start.new.chat": "Start New Chat",
208
208
  "ai.msgbox.send.tip": "Please enter content before sending",
209
209
  "ai.msgbox.error.response": "Sorry, I couldn't successfully process your request, please try again later",
210
+ "ai.msgbox.continue.from.here": "Continue from here",
210
211
  "ai.recommend.title": "Featured Cases",
211
212
  "ai.recommend.refresh": "Refresh",
212
213
  "ai.recommend.card.caseName": "Case Name",
@@ -229,12 +230,16 @@
229
230
  "ai.conversations.pin": "Pin",
230
231
  "ai.conversations.delete": "Delete",
231
232
  "ai.conversations.edit.title": "Edit Conversation Name",
233
+ "ai.conversations.ok": "OK",
234
+ "ai.conversations.cancel": "Cancel",
235
+ "ai.msgbox.delete": "Delete",
236
+ "ai.msgbox.auto.fix": "Auto Fix",
237
+ "ai.msgbox.auto.fix.prompt": "This code encountered a problem during execution. Here is the exact error message it threw.",
232
238
  "ai.chooseLib.placeholder": "Choose Technology Stack",
233
239
  "ai.search.try": "Try",
234
240
  "ai.search.visualization": "Q&A",
235
241
  "ai.assistant.editor.intro": "I am AntV AI Assistant. You can ask me questions at any time to:\n1. Interpret the code configuration of the current chart.\n2. Generate new code based on the current case through natural language dialogue to customize the chart.",
236
242
  "ai.placeholder.whatis": "What is {title}?",
237
- "header.ai.code": "AI Code Generation",
238
243
  "header.user.history": "History",
239
244
  "header.user.logout": "Logout",
240
245
  "header.user.deleteAccount": "Delete Account",
@@ -222,18 +222,23 @@
222
222
  "ai.toolbar.clear.conversation": "清空对话",
223
223
  "ai.conversations.expand": "展开",
224
224
  "ai.conversations.collapse": "收起",
225
+ "ai.msgbox.continue.from.here": "从这里继续",
225
226
  "ai.conversations.new": "开始新对话",
226
227
  "ai.conversations.history": "历史对话",
227
228
  "ai.conversations.rename": "重命名",
228
229
  "ai.conversations.pin": "置顶",
229
230
  "ai.conversations.delete": "删除",
230
231
  "ai.conversations.edit.title": "编辑对话名称",
232
+ "ai.conversations.ok": "确定",
233
+ "ai.conversations.cancel": "取消",
234
+ "ai.msgbox.delete": "删除",
235
+ "ai.msgbox.auto.fix": "自动修复",
236
+ "ai.msgbox.auto.fix.prompt": "这个代码在执行时遇到了问题。下面是它抛出的确切错误信息。",
231
237
  "ai.chooseLib.placeholder": "选择技术栈",
232
238
  "ai.search.try": "试试",
233
239
  "ai.search.visualization": "可视化答疑",
234
240
  "ai.assistant.editor.intro": "我是AntV AI助手。您可以随时向我提问,让我为您:\n\n1、解读当前图表的代码配置。\n2、通过自然语言对话,基于当前案例生成新代码以定制图表。",
235
241
  "ai.placeholder.whatis": "{title}是什么?",
236
- "header.ai.code": "AI生码",
237
242
  "header.user.history": "历史会话",
238
243
  "header.user.logout": "退出登录",
239
244
  "header.user.deleteAccount": "注销账号",
@@ -15,6 +15,7 @@ import FingerprintJS from '@fingerprintjs/fingerprintjs';
15
15
  import { history } from "dumi";
16
16
  import { message } from "antd";
17
17
  import { AIMode } from "../components/AI/constant";
18
+ import { trackEvent } from "../utils/analytics";
18
19
 
19
20
  // --- 配置 ---
20
21
  // 定义需要持久化的 state key
@@ -30,7 +31,8 @@ var initialState = {
30
31
  tempMessage: null,
31
32
  codeBlock: null,
32
33
  lib: null,
33
- mode: AIMode.implement
34
+ mode: AIMode.implement,
35
+ errorMsg: null
34
36
  };
35
37
 
36
38
  // --- valtio Store 创建 ---
@@ -205,9 +207,11 @@ subscribeKey(AIChatStore, 'activeSessionId', function () {
205
207
  });
206
208
  export var createPureNewSession = function createPureNewSession(title) {
207
209
  var newConversationName = 'New Conversation';
208
- if (AIChatStore.sessions.some(function (s) {
210
+ var existNewSession = AIChatStore.sessions.find(function (s) {
209
211
  return s.title === newConversationName && s.messages.length === 0;
210
- })) {
212
+ });
213
+ if (existNewSession) {
214
+ AIChatStore.activeSessionId = existNewSession.id;
211
215
  return;
212
216
  }
213
217
  var newSessionId = crypto.randomUUID();
@@ -220,7 +224,6 @@ export var createPureNewSession = function createPureNewSession(title) {
220
224
  AIChatStore.activeSessionId = newSessionId;
221
225
  };
222
226
  export var createNewSession = function createNewSession(config) {
223
- // todo 埋点
224
227
  // 1. 创建一个新的会话
225
228
  createPureNewSession(config.promptText);
226
229
 
@@ -238,6 +241,16 @@ export var createNewSession = function createNewSession(config) {
238
241
  var _config$lang;
239
242
  history.push("/".concat((_config$lang = config.lang) !== null && _config$lang !== void 0 ? _config$lang : 'zh', "/ai-playground"));
240
243
  }
244
+ // 埋点
245
+ if ((typeof window === "undefined" ? "undefined" : _typeof(window)) === 'object') {
246
+ trackEvent('start_ai_chat', {
247
+ entry_point: config.entry_point,
248
+ mode: AIChatStore.mode,
249
+ lib: AIChatStore.lib,
250
+ page_title: document.title,
251
+ location: location.href
252
+ });
253
+ }
241
254
  };
242
255
 
243
256
  /**
@@ -287,4 +300,14 @@ export var clearAllChatData = /*#__PURE__*/function () {
287
300
  return function clearAllChatData() {
288
301
  return _ref2.apply(this, arguments);
289
302
  };
290
- }();
303
+ }();
304
+ export function deleteMessage(msgId) {
305
+ derivedState.activeSession.messages = derivedState.activeSession.messages.filter(function (m) {
306
+ return m.id !== msgId;
307
+ });
308
+ }
309
+ export function branchMessage(index) {
310
+ var messages = derivedState.activeSession.messages.slice(0, index + 1);
311
+ createPureNewSession(messages[0].content);
312
+ AIChatStore.sessions[0].messages = messages;
313
+ }
@@ -156,7 +156,13 @@ export var ConversationsMenu = function ConversationsMenu() {
156
156
  },
157
157
  okButtonProps: {
158
158
  disabled: !state.rename
159
- }
159
+ },
160
+ okText: formatMessage({
161
+ id: 'ai.conversations.ok'
162
+ }),
163
+ cancelText: formatMessage({
164
+ id: 'ai.conversations.cancel'
165
+ })
160
166
  }, /*#__PURE__*/React.createElement(Input, {
161
167
  showCount: true,
162
168
  maxLength: 100,
@@ -1,10 +1,11 @@
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); }
1
2
  function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
2
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."); }
3
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); }
4
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; }
5
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; } }
6
7
  function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
7
- import { CheckOutlined, CopyOutlined, PlusSquareOutlined, SyncOutlined } from '@ant-design/icons';
8
+ import { BranchesOutlined, CheckOutlined, CopyOutlined, DeleteOutlined, PlusSquareOutlined, SyncOutlined, ToolOutlined } from '@ant-design/icons';
8
9
  import { Bubble } from '@ant-design/x';
9
10
  import { Button, Flex, Space, Tooltip } from 'antd';
10
11
  import { useChat } from '@ai-sdk/react';
@@ -15,13 +16,14 @@ import React, { useEffect, useState, useMemo, useRef } from 'react';
15
16
  import { useCopyToClipboard } from 'react-use';
16
17
  import { useSnapshot } from 'valtio';
17
18
  import { PromptTextarea } from "../../../../components/AI/HomeDialog/PromptTextarea";
18
- import { AIChatStore, clearEmptySession, createPureNewSession, derivedState } from "../../../../model/AIChat";
19
+ import { AIChatStore, branchMessage, clearEmptySession, createPureNewSession, deleteMessage, derivedState } from "../../../../model/AIChat";
19
20
  import { getCodeFromMarkdown, isPreviewable } from "../../../../utils/code";
20
21
  import { MarkdownComponent } from "../MarkdownComponent";
21
22
  import styles from "./index.module.less";
22
23
  import { useAutoScroll } from "./useAutoScroll";
23
24
  import { getBaseURL } from "../../../../utils/env";
24
25
  import { AIMode } from "../../../../components/AI/constant";
26
+ import { trackEvent } from "../../../../utils/analytics";
25
27
  var avatar = {
26
28
  icon: /*#__PURE__*/React.createElement("img", {
27
29
  draggable: false,
@@ -188,9 +190,9 @@ function MsgBox(props) {
188
190
  text: promptText
189
191
  }, {
190
192
  body: {
191
- context: fileSummary,
192
- lib: snap.lib,
193
- mode: snap.mode
193
+ // context: fileSummary,
194
+ // lib: snap.lib,
195
+ // mode: snap.mode,
194
196
  }
195
197
  });
196
198
  setPromptText('');
@@ -203,6 +205,16 @@ function MsgBox(props) {
203
205
  lib: snap.lib
204
206
  });
205
207
  chatScrollIntoView();
208
+ // 埋点
209
+ if ((typeof window === "undefined" ? "undefined" : _typeof(window)) === 'object') {
210
+ trackEvent('start_ai_chat', {
211
+ entry_point: simple ? 'Drawer' : 'MsgBox',
212
+ mode: AIChatStore.mode,
213
+ lib: AIChatStore.lib,
214
+ page_title: document.title,
215
+ location: location.href
216
+ });
217
+ }
206
218
  };
207
219
 
208
220
  // 同步 Valtio store -> useChat state
@@ -254,12 +266,36 @@ function MsgBox(props) {
254
266
  useEffect(function () {
255
267
  chatScrollIntoView();
256
268
  stop();
269
+ AIChatStore.errorMsg = null;
257
270
  }, [snap.activeSessionId]);
258
271
 
259
272
  // 将 messages 数组作为依赖项。当它变化时,Hook 会运行。
260
273
  var _useAutoScroll = useAutoScroll(messages),
261
274
  containerRef = _useAutoScroll.containerRef,
262
275
  anchorRef = _useAutoScroll.anchorRef;
276
+ var autofix = function autofix() {
277
+ var _derivedState$activeS6;
278
+ var autoFixPromptText = "".concat(formatMessage({
279
+ id: 'ai.msgbox.auto.fix.prompt'
280
+ }), ": [").concat(snap.errorMsg, "]");
281
+ sendMessage({
282
+ text: autoFixPromptText
283
+ }, {
284
+ body: {
285
+ antvContext: snap.codeBlock
286
+ }
287
+ });
288
+ AIChatStore.errorMsg = null;
289
+ (_derivedState$activeS6 = derivedState.activeSession) === null || _derivedState$activeS6 === void 0 || (_derivedState$activeS6 = _derivedState$activeS6.messages) === null || _derivedState$activeS6 === void 0 || _derivedState$activeS6.push({
290
+ id: crypto.randomUUID(),
291
+ role: 'user',
292
+ content: autoFixPromptText,
293
+ createdAt: Date.now(),
294
+ context: snap.codeBlock,
295
+ lib: snap.lib
296
+ });
297
+ chatScrollIntoView();
298
+ };
263
299
  return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Flex, {
264
300
  gap: "middle",
265
301
  vertical: true,
@@ -274,9 +310,9 @@ function MsgBox(props) {
274
310
  showRunButton: !props.simple
275
311
  }),
276
312
  avatar: msg.role === 'assistant' ? avatar : null,
277
- footer: msg.role === 'assistant' && index > 0 && index === messages.length - 1 && status === 'ready' ? /*#__PURE__*/React.createElement(Space, {
313
+ footer: status === 'ready' && /*#__PURE__*/React.createElement(Space, {
278
314
  size: "small"
279
- }, /*#__PURE__*/React.createElement(Tooltip, {
315
+ }, msg.role === 'assistant' && index === messages.length - 1 && /*#__PURE__*/React.createElement(Tooltip, {
280
316
  title: formatMessage({
281
317
  id: 'ai.msgbox.retry'
282
318
  })
@@ -301,7 +337,31 @@ function MsgBox(props) {
301
337
  return copyToClipboard(textContent);
302
338
  },
303
339
  icon: copyState.value === textContent ? /*#__PURE__*/React.createElement(CheckOutlined, null) : /*#__PURE__*/React.createElement(CopyOutlined, null)
304
- }))) : null,
340
+ })), /*#__PURE__*/React.createElement(Tooltip, {
341
+ title: formatMessage({
342
+ id: 'ai.msgbox.continue.from.here'
343
+ })
344
+ }, /*#__PURE__*/React.createElement(Button, {
345
+ color: "default",
346
+ variant: "text",
347
+ size: "small",
348
+ onClick: function onClick() {
349
+ return branchMessage(index);
350
+ },
351
+ icon: /*#__PURE__*/React.createElement(BranchesOutlined, null)
352
+ })), msg.role === 'assistant' && /*#__PURE__*/React.createElement(Tooltip, {
353
+ title: formatMessage({
354
+ id: 'ai.msgbox.delete'
355
+ })
356
+ }, /*#__PURE__*/React.createElement(Button, {
357
+ color: "default",
358
+ variant: "text",
359
+ size: "small",
360
+ onClick: function onClick() {
361
+ return deleteMessage(msg.id);
362
+ },
363
+ icon: /*#__PURE__*/React.createElement(DeleteOutlined, null)
364
+ }))),
305
365
  placement: msg.role === 'user' ? 'end' : 'start'
306
366
  });
307
367
  }), (status === 'streaming' || status === 'submitted') && ((_messages = messages[messages.length - 1]) === null || _messages === void 0 ? void 0 : _messages.role) === 'user' && /*#__PURE__*/React.createElement(Bubble, {
@@ -321,7 +381,14 @@ function MsgBox(props) {
321
381
  className: styles.newButton
322
382
  }, /*#__PURE__*/React.createElement(Space, null, /*#__PURE__*/React.createElement(PlusSquareOutlined, null), formatMessage({
323
383
  id: 'ai.msgbox.start.new.chat'
324
- }))))), /*#__PURE__*/React.createElement(PromptTextarea, {
384
+ }))), snap.errorMsg && status === 'ready' && /*#__PURE__*/React.createElement(Button, {
385
+ onClick: autofix,
386
+ color: "danger",
387
+ variant: "filled",
388
+ icon: /*#__PURE__*/React.createElement(ToolOutlined, null)
389
+ }, formatMessage({
390
+ id: 'ai.msgbox.auto.fix'
391
+ })))), /*#__PURE__*/React.createElement(PromptTextarea, {
325
392
  size: "compact",
326
393
  value: promptText,
327
394
  onChange: setPromptText,
@@ -38,7 +38,8 @@ function SessionLayout(props) {
38
38
  primary: "second",
39
39
  style: {
40
40
  position: 'unset'
41
- }
41
+ },
42
+ minSize: 100
42
43
  }, /*#__PURE__*/React.createElement("div", {
43
44
  className: classnames(styles.msgBox)
44
45
  }, children[0]), /*#__PURE__*/React.createElement("div", {
@@ -2,8 +2,9 @@
2
2
  display: flex;
3
3
  gap: 12px;
4
4
  background: #f6f7fb;
5
- height: calc(100vh - 64px);
6
5
  padding: 0;
6
+ flex-grow: 1;
7
+ overflow-y: auto;
7
8
  }
8
9
 
9
10
  .msgBox, .taskBox{
@@ -1,3 +1,7 @@
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); }
1
5
  function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
2
6
  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); }
3
7
  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; }
@@ -75,25 +79,99 @@ export function generateDependencies(codeString) {
75
79
  }
76
80
  return dependencies;
77
81
  }
82
+
83
+ /**
84
+ * 基于代码内容,启发式地判断其最合适的文件扩展名。
85
+ * @param {string} code - 要分析的前端代码字符串。
86
+ * @returns {'tsx' | 'jsx' | 'ts' | 'js'} - 推断出的文件扩展名(不含点)。
87
+ */
88
+ export function getLanguageExtension(code) {
89
+ // --- 特征检测函数 ---
90
+
91
+ /**
92
+ * 检查代码是否包含 JSX 语法。
93
+ * 这是一个启发式检查,它查找类似HTML标签的模式。
94
+ * - 匹配 <div...>, <MyComponent...>, </tag>, <Component/>, <>
95
+ */
96
+ var containsJsx = function containsJsx(text) {
97
+ // 1. 查找开/闭标签 <...> 或自闭合标签 <.../>
98
+ // 2. 忽略可能误判的比较操作,如 `i < j`
99
+ // 这个正则查找一个'<'符号,后面不能是'!' (注释)或'=' (小于等于),
100
+ // 并且后面跟着一个合法的标签名(字母开头)或闭合标签'/'。
101
+ // 这比简单的 /<...>/ 更可靠。
102
+ var jsxRegex = /<(?![\s!=])([a-zA-Z][a-zA-Z0-9-]*|\/|)/;
103
+ return jsxRegex.test(text);
104
+ };
105
+
106
+ /**
107
+ * 检查代码是否包含 TypeScript 语法。
108
+ * 这是一个启发式检查,查找TS独有的关键字和语法模式。
109
+ */
110
+ var containsTypeScript = function containsTypeScript(text) {
111
+ // 检查点 1: 类型/接口定义(非常明确的信号)
112
+ // 匹配 `type MyType = ...` 或 `interface MyInterface { ... }`
113
+ var typeDefinitionRegex = /\b(interface|type)\s+[A-Z][a-zA-Z0-9]*\b/;
114
+ if (typeDefinitionRegex.test(text)) {
115
+ return true;
116
+ }
117
+
118
+ // 检查点 2: 变量或参数的类型注解(强信号)
119
+ // 匹配 `: string`, `: number`, `: MyType` 等
120
+ // 这个正则查找一个冒号,后面跟着一个类型(通常大写字母开头或ts内置类型)
121
+ var typeAnnotationRegex = /:\s*([A-Z][a-zA-Z0-9<>.]*|string|number|boolean|any\[?\]?)/;
122
+ if (typeAnnotationRegex.test(text)) {
123
+ return true;
124
+ }
125
+
126
+ // 检查点 3: 其他TS关键字
127
+ // 匹配 `as someType`, `implements`, `private`, `public`, `protected` 等
128
+ var tsKeywordsRegex = /\b(as|implements|private|public|protected|readonly)\s+[a-zA-Z]/;
129
+ if (tsKeywordsRegex.test(text)) {
130
+ return true;
131
+ }
132
+ return false;
133
+ };
134
+
135
+ // --- 决策逻辑 ---
136
+
137
+ if (containsJsx(code)) {
138
+ if (containsTypeScript(code)) {
139
+ return 'tsx';
140
+ }
141
+ return 'jsx';
142
+ } else {
143
+ if (containsTypeScript(code)) {
144
+ return 'ts';
145
+ }
146
+ return 'js';
147
+ }
148
+ }
78
149
  export function wrap2VisionSnap() {
79
150
  var codeBlock = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
151
+ var ext = getLanguageExtension(codeBlock);
152
+ var mainFile = "/src/index.".concat(ext);
153
+ var appFile = "/src/App.".concat(ext);
80
154
  var dependencies = generateDependencies(codeBlock);
81
155
  var rootElementType = dependencies['@antv/f2'] ? 'canvas' : 'div';
156
+ var dependenciesJSON = {
157
+ "name": "AntV-adapted-project",
158
+ "version": "1.0.0",
159
+ "main": mainFile,
160
+ "dependencies": dependencies
161
+ };
82
162
  return {
83
- modules: {
163
+ modules: _defineProperty(_defineProperty({
84
164
  '/package.json': {
85
165
  fpath: '/package.json',
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}")
87
- },
88
- '/src/index.jsx': {
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',
94
- code: codeBlock
166
+ code: JSON.stringify(dependenciesJSON, null, 2)
95
167
  }
96
- }
168
+ }, mainFile, {
169
+ fpath: mainFile,
170
+ 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.").concat(ext, "');\n\n}\n ")
171
+ }), appFile, {
172
+ fpath: [appFile],
173
+ code: codeBlock
174
+ })
97
175
  };
98
176
  }
99
177
  export function wrap2Sandpack() {
@@ -48,7 +48,15 @@ function TaskBox() {
48
48
  if (loading) {
49
49
  return /*#__PURE__*/React.createElement(Loading, null);
50
50
  }
51
- if (themeConfig.isAntVSite || ((_themeConfig$ai = themeConfig.ai) === null || _themeConfig$ai === void 0 ? void 0 : _themeConfig$ai.codeRunner) === "VisionSnap" || !((_themeConfig$ai2 = themeConfig.ai) !== null && _themeConfig$ai2 !== void 0 && _themeConfig$ai2.codeRunner) || snap.lib !== 'F2') {
51
+ var wrappedVisionSnapCode = wrap2VisionSnap(snap.codeBlock);
52
+ var handleEsmLoadFailed = function handleEsmLoadFailed(err) {
53
+ // F2的异常没法修,VisionSnap的异常信息不准确
54
+ if (!wrappedVisionSnapCode.modules["/package.json"].code.includes("@antv/f2")) {
55
+ var _err$data;
56
+ AIChatStore.errorMsg = ((_err$data = err.data) === null || _err$data === void 0 || (_err$data = _err$data.error) === null || _err$data === void 0 || (_err$data = _err$data.split('\n')) === null || _err$data === void 0 ? void 0 : _err$data[1]) || JSON.stringify(err) || err.message;
57
+ }
58
+ };
59
+ if (themeConfig.isAntVSite || ((_themeConfig$ai = themeConfig.ai) === null || _themeConfig$ai === void 0 ? void 0 : _themeConfig$ai.codeRunner) === "VisionSnap" || !((_themeConfig$ai2 = themeConfig.ai) !== null && _themeConfig$ai2 !== void 0 && _themeConfig$ai2.codeRunner) || !wrappedVisionSnapCode.modules["/package.json"].code.includes("@antv/f2")) {
52
60
  return /*#__PURE__*/React.createElement(ErrorBoundary, {
53
61
  FallbackComponent: ErrorFallback
54
62
  }, /*#__PURE__*/React.createElement(sdk.VisionPreview, {
@@ -61,13 +69,14 @@ function TaskBox() {
61
69
  displayMode: "code-and-preview",
62
70
  initialView: "preview",
63
71
  theme: "light",
64
- code: wrap2VisionSnap(snap.codeBlock),
72
+ code: wrappedVisionSnapCode,
65
73
  requestProxy: requestProxy,
66
74
  isStreaming: false,
67
75
  proxyOptions: {
68
76
  isWAN: true
69
77
  },
70
- src: "https://www.weavefox.cn/_visionsnap_render/index.html?version=3.2.15&enableInspector=1"
78
+ src: "https://www.weavefox.cn/_visionsnap_render/index.html?version=3.2.15&enableInspector=1",
79
+ onEsmLoadFailed: handleEsmLoadFailed
71
80
  }));
72
81
  } else {
73
82
  return /*#__PURE__*/React.createElement(CodeRunner, {
@@ -3,7 +3,10 @@ import { SessionLayout } from "./components/SessionLayout";
3
3
  import MsgBox from "./components/MsgBox";
4
4
  import TaskBox from "./components/TaskBox";
5
5
  import Header from "dumi/theme/slots/Header";
6
+ import styles from "./index.module.less";
6
7
  function AIPlayground() {
7
- return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Header, null), /*#__PURE__*/React.createElement(SessionLayout, null, /*#__PURE__*/React.createElement(MsgBox, null), /*#__PURE__*/React.createElement(TaskBox, null)));
8
+ return /*#__PURE__*/React.createElement("div", {
9
+ className: styles.aiPlayground
10
+ }, /*#__PURE__*/React.createElement(Header, null), /*#__PURE__*/React.createElement(SessionLayout, null, /*#__PURE__*/React.createElement(MsgBox, null), /*#__PURE__*/React.createElement(TaskBox, null)));
8
11
  }
9
12
  export default AIPlayground;
@@ -0,0 +1,5 @@
1
+ .aiPlayground {
2
+ display: flex;
3
+ flex-direction: column;
4
+ height: 100vh;
5
+ }
@@ -2,7 +2,7 @@ import { useIntl, useSiteData } from 'dumi';
2
2
  import React from 'react';
3
3
  import styles from "./SearchResult.module.less";
4
4
  import classnames from "classnames";
5
- import { createNewSession } from "../../../model/AIChat";
5
+ import { AIChatStore, createNewSession } from "../../../model/AIChat";
6
6
  import { authStore, showLoginModal } from "../../../model/auth";
7
7
  import { useSnapshot } from "valtio";
8
8
  var getHighlightInfo = function getHighlightInfo(textSegments) {
@@ -25,12 +25,14 @@ export var SearchResult = function SearchResult(_ref) {
25
25
  var intl = useIntl();
26
26
  var authSnap = useSnapshot(authStore);
27
27
  function pureSearch() {
28
+ AIChatStore.mode = 'solve';
28
29
  createNewSession({
29
30
  promptText: keywords,
30
31
  mode: 'solve',
31
32
  lib: !themeConfig.isAntVSite ? themeConfig.title : undefined,
32
33
  jump: true,
33
- lang: intl.locale === 'zh' ? 'zh' : 'en'
34
+ lang: intl.locale === 'zh' ? 'zh' : 'en',
35
+ entry_point: 'SearchResult'
34
36
  });
35
37
  }
36
38
  return /*#__PURE__*/React.createElement("div", {
@@ -18,7 +18,7 @@ import { Alert, Button, Dropdown, Menu, Modal, Popover } from 'antd';
18
18
  import cx from 'classnames';
19
19
  import { FormattedMessage, Link, useLocale, useSiteData, useIntl, history } from 'dumi';
20
20
  import { get, map, size } from 'lodash-es';
21
- import React, { useEffect, useMemo, useState } from 'react';
21
+ import React, { useEffect, useState } from 'react';
22
22
  import { useMedia } from 'react-use';
23
23
  import { getPurePathname } from "../../utils/location";
24
24
  import { ic, icWithLocale } from "../hooks";
@@ -57,9 +57,6 @@ var HeaderComponent = function HeaderComponent(_ref) {
57
57
  showAntVProductsCard = _ref$showAntVProducts === void 0 ? true : _ref$showAntVProducts,
58
58
  _ref$showLanguageSwit = _ref.showLanguageSwitcher,
59
59
  showLanguageSwitcher = _ref$showLanguageSwit === void 0 ? true : _ref$showLanguageSwit,
60
- _ref$showWeavefox = _ref.showWeavefox,
61
- showWeavefox = _ref$showWeavefox === void 0 ? {} : _ref$showWeavefox,
62
- isInternalUser = _ref.isInternalUser,
63
60
  logo = _ref.logo,
64
61
  onLanguageChange = _ref.onLanguageChange,
65
62
  _ref$showWxQrcode = _ref.showWxQrcode,
@@ -154,8 +151,7 @@ var HeaderComponent = function HeaderComponent(_ref) {
154
151
  }),
155
152
  link: ''
156
153
  }, logo),
157
- img = _img$link$logo.img,
158
- link = _img$link$logo.link;
154
+ img = _img$link$logo.img;
159
155
  var _useLocation = useLocation(),
160
156
  pathname = _useLocation.pathname;
161
157
  useEffect(function () {
@@ -190,27 +186,13 @@ var HeaderComponent = function HeaderComponent(_ref) {
190
186
  var handleSwitchLanguage = function handleSwitchLanguage() {
191
187
  onLanguageChange === null || onLanguageChange === void 0 || onLanguageChange(lang);
192
188
  };
193
- var weavefox = useMemo(function () {
194
- var configKey = isInternalUser ? 'internal' : 'public';
195
- var configValue = showWeavefox[configKey];
196
- if (!configValue) return /*#__PURE__*/React.createElement(React.Fragment, null);
197
- var defaultLink = isInternalUser ? 'https://weavefox.antgroup-inc.cn/agent/@huiyu.zjt/AntV' : 'https://weavefox.alipay.com/agent/@ufox-b8tydq-0758/202505AP7vfl00422922';
198
- var href = typeof configValue === 'string' ? configValue : defaultLink;
199
- return /*#__PURE__*/React.createElement("li", null, /*#__PURE__*/React.createElement("a", {
200
- href: href,
201
- target: "_blank",
202
- rel: "noreferrer"
203
- }, /*#__PURE__*/React.createElement(FormattedMessage, {
204
- id: "header.ai.code"
205
- })));
206
- }, [isInternalUser, showWeavefox]);
207
189
  var menu = /*#__PURE__*/React.createElement("ul", {
208
190
  className: cx(styles.menu, _defineProperty(_defineProperty({}, styles.popup, !isWide), styles.popupHidden, !popupMenuVisible))
209
191
  }, /** 最左侧的菜单,一般是 教程、API、示例,或者其他自定义,有配置文件中的 `navs` 决定 */
210
192
  size(navs) ? /*#__PURE__*/React.createElement(Navs, {
211
193
  navs: navs,
212
194
  path: pathname
213
- }) : null, weavefox, /** 生态产品 */
195
+ }) : null, /** 生态产品 */
214
196
  size(ecosystems) ? /*#__PURE__*/React.createElement("li", null, /*#__PURE__*/React.createElement(Dropdown, {
215
197
  className: styles.ecoSystems,
216
198
  overlay: /*#__PURE__*/React.createElement(Menu, null, map(ecosystems, function (_ref2) {
@@ -0,0 +1,16 @@
1
+ /**
2
+ * 统一的事件跟踪函数
3
+ * @param {string} eventName - 事件名称,如 'button_click'
4
+ * @param {object} params - 事件相关的参数
5
+ */
6
+ export var trackEvent = function trackEvent(eventName) {
7
+ var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
8
+ if (typeof window === 'undefined') {
9
+ return false;
10
+ }
11
+ if (window.gtag) {
12
+ window.gtag('event', eventName, params);
13
+ } else {
14
+ console.warn('[Analytics] gtag is not available.');
15
+ }
16
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@antv/dumi-theme-antv",
3
- "version": "0.8.0-beta.13",
3
+ "version": "0.8.0-beta.15",
4
4
  "description": "AntV website theme based on dumi2.",
5
5
  "keywords": [
6
6
  "dumi",