@antv/dumi-theme-antv 0.8.0-beta.0 → 0.8.0-beta.2
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/components/AI/HomeDialog/ModeSelector/index.js +4 -1
- package/dist/components/AI/HomeDialog/PromptTextarea/ChooseLib/index.js +5 -2
- package/dist/components/AI/HomeDialog/PromptTextarea/Uploader/DataUploader.js +225 -0
- package/dist/components/AI/HomeDialog/PromptTextarea/index.js +62 -24
- package/dist/components/AI/HomeDialog/PromptTextarea/index.module.less +1 -0
- package/dist/components/AI/HomeDialog/RecommendCase/Card.js +10 -3
- package/dist/components/AI/HomeDialog/RecommendCase/index.js +8 -3
- package/dist/components/AI/HomeDialog/index.js +12 -3
- package/dist/components/AI/constant.js +2 -2
- package/dist/hooks/useStreamingText.js +38 -18
- package/dist/hooks/useTypewriter.js +69 -0
- package/dist/locales/en.json +91 -1
- package/dist/locales/zh.json +91 -1
- package/dist/model/AIChat.js +20 -8
- package/dist/pages/AIPlayground/components/ConversationsMenu/index.js +29 -7
- package/dist/pages/AIPlayground/components/MarkdownComponent/MarkdownCodeBlock.js +41 -18
- package/dist/pages/AIPlayground/components/MarkdownComponent/MarkdownCodeBlock.module.less +14 -0
- package/dist/pages/AIPlayground/components/MarkdownComponent/index.js +1 -1
- package/dist/pages/AIPlayground/components/MsgBox/index.js +149 -47
- package/dist/pages/AIPlayground/components/SessionLayout/index.js +18 -10
- package/dist/pages/AIPlayground/components/SessionLayout/index.module.less +3 -0
- package/dist/pages/AIPlayground/components/TaskBox/generateCode.js +3 -4
- package/dist/pages/AIPlayground/components/TaskBox/index.js +1 -0
- package/dist/plugin/index.js +2 -2
- package/dist/slots/CodeEditor/Toolbar.js +17 -7
- package/dist/slots/CodeEditor/Toolbar.module.less +1 -0
- package/dist/slots/CodeEditor/index.js +18 -4
- package/dist/slots/CodeRunner/index.js +2 -1
- package/dist/slots/Header/Search/SearchResult.js +9 -3
- package/dist/slots/Header/index.js +24 -8
- package/dist/static/SearchAiIcon.svg +14 -0
- package/dist/utils/code.js +35 -0
- package/package.json +1 -1
|
@@ -6,6 +6,7 @@ import classnames from 'classnames';
|
|
|
6
6
|
import React from 'react';
|
|
7
7
|
import styles from "./index.module.less";
|
|
8
8
|
import { AIMode, AIModeMeta } from "../../constant";
|
|
9
|
+
import { FormattedMessage } from 'dumi';
|
|
9
10
|
export var ModeSelector = function ModeSelector(_ref) {
|
|
10
11
|
var value = _ref.value,
|
|
11
12
|
size = _ref.size,
|
|
@@ -24,6 +25,8 @@ export var ModeSelector = function ModeSelector(_ref) {
|
|
|
24
25
|
onChange(mode);
|
|
25
26
|
}
|
|
26
27
|
}
|
|
27
|
-
}, meta.icon, /*#__PURE__*/React.createElement(
|
|
28
|
+
}, meta.icon, /*#__PURE__*/React.createElement(FormattedMessage, {
|
|
29
|
+
id: meta.name
|
|
30
|
+
}));
|
|
28
31
|
})));
|
|
29
32
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { Dropdown } from "antd";
|
|
3
3
|
import { useProducts } from "../../../../../hooks/useProducts";
|
|
4
|
-
import { useLocale } from "dumi";
|
|
4
|
+
import { useLocale, useIntl, FormattedMessage } from "dumi";
|
|
5
5
|
import styles from "./index.module.less";
|
|
6
6
|
export function ChooseLib(props) {
|
|
7
7
|
var _data$find;
|
|
@@ -35,6 +35,7 @@ export function ChooseLib(props) {
|
|
|
35
35
|
}
|
|
36
36
|
};
|
|
37
37
|
});
|
|
38
|
+
var intl = useIntl();
|
|
38
39
|
return /*#__PURE__*/React.createElement(Dropdown, {
|
|
39
40
|
menu: {
|
|
40
41
|
items: items
|
|
@@ -47,5 +48,7 @@ export function ChooseLib(props) {
|
|
|
47
48
|
return item.title === value;
|
|
48
49
|
})) === null || _data$find === void 0 ? void 0 : _data$find.icon) || "https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*7svFR6wkPMoAAAAAAAAAAAAADmJ7AQ/original",
|
|
49
50
|
alt: "AntV"
|
|
50
|
-
}), value || !isCompact &&
|
|
51
|
+
}), value || !isCompact && /*#__PURE__*/React.createElement(FormattedMessage, {
|
|
52
|
+
id: "ai.chooseLib.placeholder"
|
|
53
|
+
})));
|
|
51
54
|
}
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
function _regeneratorRuntime() { "use strict"; /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */ _regeneratorRuntime = function _regeneratorRuntime() { return e; }; var t, e = {}, r = Object.prototype, n = r.hasOwnProperty, o = Object.defineProperty || function (t, e, r) { t[e] = r.value; }, i = "function" == typeof Symbol ? Symbol : {}, a = i.iterator || "@@iterator", c = i.asyncIterator || "@@asyncIterator", u = i.toStringTag || "@@toStringTag"; function define(t, e, r) { return Object.defineProperty(t, e, { value: r, enumerable: !0, configurable: !0, writable: !0 }), t[e]; } try { define({}, ""); } catch (t) { define = function define(t, e, r) { return t[e] = r; }; } function wrap(t, e, r, n) { var i = e && e.prototype instanceof Generator ? e : Generator, a = Object.create(i.prototype), c = new Context(n || []); return o(a, "_invoke", { value: makeInvokeMethod(t, r, c) }), a; } function tryCatch(t, e, r) { try { return { type: "normal", arg: t.call(e, r) }; } catch (t) { return { type: "throw", arg: t }; } } e.wrap = wrap; var h = "suspendedStart", l = "suspendedYield", f = "executing", s = "completed", y = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} var p = {}; define(p, a, function () { return this; }); var d = Object.getPrototypeOf, v = d && d(d(values([]))); v && v !== r && n.call(v, a) && (p = v); var g = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(p); function defineIteratorMethods(t) { ["next", "throw", "return"].forEach(function (e) { define(t, e, function (t) { return this._invoke(e, t); }); }); } function AsyncIterator(t, e) { function invoke(r, o, i, a) { var c = tryCatch(t[r], t, o); if ("throw" !== c.type) { var u = c.arg, h = u.value; return h && "object" == _typeof(h) && n.call(h, "__await") ? e.resolve(h.__await).then(function (t) { invoke("next", t, i, a); }, function (t) { invoke("throw", t, i, a); }) : e.resolve(h).then(function (t) { u.value = t, i(u); }, function (t) { return invoke("throw", t, i, a); }); } a(c.arg); } var r; o(this, "_invoke", { value: function value(t, n) { function callInvokeWithMethodAndArg() { return new e(function (e, r) { invoke(t, n, e, r); }); } return r = r ? r.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg(); } }); } function makeInvokeMethod(e, r, n) { var o = h; return function (i, a) { if (o === f) throw new Error("Generator is already running"); if (o === s) { if ("throw" === i) throw a; return { value: t, done: !0 }; } for (n.method = i, n.arg = a;;) { var c = n.delegate; if (c) { var u = maybeInvokeDelegate(c, n); if (u) { if (u === y) continue; return u; } } if ("next" === n.method) n.sent = n._sent = n.arg;else if ("throw" === n.method) { if (o === h) throw o = s, n.arg; n.dispatchException(n.arg); } else "return" === n.method && n.abrupt("return", n.arg); o = f; var p = tryCatch(e, r, n); if ("normal" === p.type) { if (o = n.done ? s : l, p.arg === y) continue; return { value: p.arg, done: n.done }; } "throw" === p.type && (o = s, n.method = "throw", n.arg = p.arg); } }; } function maybeInvokeDelegate(e, r) { var n = r.method, o = e.iterator[n]; if (o === t) return r.delegate = null, "throw" === n && e.iterator.return && (r.method = "return", r.arg = t, maybeInvokeDelegate(e, r), "throw" === r.method) || "return" !== n && (r.method = "throw", r.arg = new TypeError("The iterator does not provide a '" + n + "' method")), y; var i = tryCatch(o, e.iterator, r.arg); if ("throw" === i.type) return r.method = "throw", r.arg = i.arg, r.delegate = null, y; var a = i.arg; return a ? a.done ? (r[e.resultName] = a.value, r.next = e.nextLoc, "return" !== r.method && (r.method = "next", r.arg = t), r.delegate = null, y) : a : (r.method = "throw", r.arg = new TypeError("iterator result is not an object"), r.delegate = null, y); } function pushTryEntry(t) { var e = { tryLoc: t[0] }; 1 in t && (e.catchLoc = t[1]), 2 in t && (e.finallyLoc = t[2], e.afterLoc = t[3]), this.tryEntries.push(e); } function resetTryEntry(t) { var e = t.completion || {}; e.type = "normal", delete e.arg, t.completion = e; } function Context(t) { this.tryEntries = [{ tryLoc: "root" }], t.forEach(pushTryEntry, this), this.reset(!0); } function values(e) { if (e || "" === e) { var r = e[a]; if (r) return r.call(e); if ("function" == typeof e.next) return e; if (!isNaN(e.length)) { var o = -1, i = function next() { for (; ++o < e.length;) if (n.call(e, o)) return next.value = e[o], next.done = !1, next; return next.value = t, next.done = !0, next; }; return i.next = i; } } throw new TypeError(_typeof(e) + " is not iterable"); } return GeneratorFunction.prototype = GeneratorFunctionPrototype, o(g, "constructor", { value: GeneratorFunctionPrototype, configurable: !0 }), o(GeneratorFunctionPrototype, "constructor", { value: GeneratorFunction, configurable: !0 }), GeneratorFunction.displayName = define(GeneratorFunctionPrototype, u, "GeneratorFunction"), e.isGeneratorFunction = function (t) { var e = "function" == typeof t && t.constructor; return !!e && (e === GeneratorFunction || "GeneratorFunction" === (e.displayName || e.name)); }, e.mark = function (t) { return Object.setPrototypeOf ? Object.setPrototypeOf(t, GeneratorFunctionPrototype) : (t.__proto__ = GeneratorFunctionPrototype, define(t, u, "GeneratorFunction")), t.prototype = Object.create(g), t; }, e.awrap = function (t) { return { __await: t }; }, defineIteratorMethods(AsyncIterator.prototype), define(AsyncIterator.prototype, c, function () { return this; }), e.AsyncIterator = AsyncIterator, e.async = function (t, r, n, o, i) { void 0 === i && (i = Promise); var a = new AsyncIterator(wrap(t, r, n, o), i); return e.isGeneratorFunction(r) ? a : a.next().then(function (t) { return t.done ? t.value : a.next(); }); }, defineIteratorMethods(g), define(g, u, "Generator"), define(g, a, function () { return this; }), define(g, "toString", function () { return "[object Generator]"; }), e.keys = function (t) { var e = Object(t), r = []; for (var n in e) r.push(n); return r.reverse(), function next() { for (; r.length;) { var t = r.pop(); if (t in e) return next.value = t, next.done = !1, next; } return next.done = !0, next; }; }, e.values = values, Context.prototype = { constructor: Context, reset: function reset(e) { if (this.prev = 0, this.next = 0, this.sent = this._sent = t, this.done = !1, this.delegate = null, this.method = "next", this.arg = t, this.tryEntries.forEach(resetTryEntry), !e) for (var r in this) "t" === r.charAt(0) && n.call(this, r) && !isNaN(+r.slice(1)) && (this[r] = t); }, stop: function stop() { this.done = !0; var t = this.tryEntries[0].completion; if ("throw" === t.type) throw t.arg; return this.rval; }, dispatchException: function dispatchException(e) { if (this.done) throw e; var r = this; function handle(n, o) { return a.type = "throw", a.arg = e, r.next = n, o && (r.method = "next", r.arg = t), !!o; } for (var o = this.tryEntries.length - 1; o >= 0; --o) { var i = this.tryEntries[o], a = i.completion; if ("root" === i.tryLoc) return handle("end"); if (i.tryLoc <= this.prev) { var c = n.call(i, "catchLoc"), u = n.call(i, "finallyLoc"); if (c && u) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } else if (c) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); } else { if (!u) throw new Error("try statement without catch or finally"); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } } } }, abrupt: function abrupt(t, e) { for (var r = this.tryEntries.length - 1; r >= 0; --r) { var o = this.tryEntries[r]; if (o.tryLoc <= this.prev && n.call(o, "finallyLoc") && this.prev < o.finallyLoc) { var i = o; break; } } i && ("break" === t || "continue" === t) && i.tryLoc <= e && e <= i.finallyLoc && (i = null); var a = i ? i.completion : {}; return a.type = t, a.arg = e, i ? (this.method = "next", this.next = i.finallyLoc, y) : this.complete(a); }, complete: function complete(t, e) { if ("throw" === t.type) throw t.arg; return "break" === t.type || "continue" === t.type ? this.next = t.arg : "return" === t.type ? (this.rval = this.arg = t.arg, this.method = "return", this.next = "end") : "normal" === t.type && e && (this.next = e), y; }, finish: function finish(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.finallyLoc === t) return this.complete(r.completion, r.afterLoc), resetTryEntry(r), y; } }, catch: function _catch(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.tryLoc === t) { var n = r.completion; if ("throw" === n.type) { var o = n.arg; resetTryEntry(r); } return o; } } throw new Error("illegal catch attempt"); }, delegateYield: function delegateYield(e, r, n) { return this.delegate = { iterator: values(e), resultName: r, nextLoc: n }, "next" === this.method && (this.arg = t), y; } }, e; }
|
|
2
|
+
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
|
|
3
|
+
function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
|
|
4
|
+
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); }
|
|
5
|
+
// src/components/DataUploader.tsx
|
|
6
|
+
import React from 'react';
|
|
7
|
+
import { Upload, message, Tooltip } from 'antd';
|
|
8
|
+
import { useRequest } from 'ahooks';
|
|
9
|
+
import { useIntl } from 'dumi';
|
|
10
|
+
import { FileIcons } from "../../../constant";
|
|
11
|
+
|
|
12
|
+
// 定义文件元信息类型,与父组件保持一致
|
|
13
|
+
|
|
14
|
+
// 定义回调函数返回的完整数据类型
|
|
15
|
+
|
|
16
|
+
// 定义组件Props
|
|
17
|
+
|
|
18
|
+
// 新增:直接发送给AI的原始内容最大字符数阈值
|
|
19
|
+
var DIRECT_FEED_CHAR_THRESHOLD = 4000; // 约1k tokens,这是一个比较保守和经济的阈值
|
|
20
|
+
var MAX_FILE_SIZE_MB = 5;
|
|
21
|
+
var MAX_CONTEXT_CHARS = 5000;
|
|
22
|
+
var ALLOWED_FILE_TYPES = ['csv', 'json', 'tsv', 'txt'];
|
|
23
|
+
var MAX_LINES = 10;
|
|
24
|
+
|
|
25
|
+
// --- 辅助函数(与之前相同) ---
|
|
26
|
+
var formatBytes = function formatBytes(bytes) {
|
|
27
|
+
var decimals = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 2;
|
|
28
|
+
if (bytes === 0) return '0 Bytes';
|
|
29
|
+
var k = 1024;
|
|
30
|
+
var dm = decimals < 0 ? 0 : decimals;
|
|
31
|
+
var sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];
|
|
32
|
+
var i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
33
|
+
return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
// 这些函数负责将文件内容转换成给AI看的摘要
|
|
37
|
+
function getTableSummary(content, fileType, intl) {
|
|
38
|
+
var lines = content.replace(/\r\n/g, '\n').split('\n');
|
|
39
|
+
if (lines.length === 0) return intl.formatMessage({
|
|
40
|
+
id: 'ai.upload.file.empty'
|
|
41
|
+
});
|
|
42
|
+
var delimiter = fileType === 'csv' ? ',' : '\t';
|
|
43
|
+
var header = lines[0];
|
|
44
|
+
// 取前MAX_LINES行有效数据作为样本
|
|
45
|
+
var sampleRows = lines.slice(1).filter(function (line) {
|
|
46
|
+
return line.trim() !== '';
|
|
47
|
+
}).slice(0, MAX_LINES).join('\n');
|
|
48
|
+
var columnCount = header.split(delimiter).length;
|
|
49
|
+
var rowCount = lines.filter(function (line) {
|
|
50
|
+
return line.trim() !== '';
|
|
51
|
+
}).length;
|
|
52
|
+
return intl.formatMessage({
|
|
53
|
+
id: 'ai.upload.file.table.summary'
|
|
54
|
+
}, {
|
|
55
|
+
rowCount: rowCount,
|
|
56
|
+
columnCount: columnCount,
|
|
57
|
+
header: header,
|
|
58
|
+
maxLines: MAX_LINES,
|
|
59
|
+
sampleRows: sampleRows
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
function getJsonSummary(data, intl) {
|
|
63
|
+
if (Array.isArray(data) && data.length > 0 && _typeof(data[0]) === 'object') {
|
|
64
|
+
var keys = Object.keys(data[0]);
|
|
65
|
+
var sampleData = data.slice(0, MAX_LINES).map(function (item) {
|
|
66
|
+
return JSON.stringify(item);
|
|
67
|
+
}).join('\n');
|
|
68
|
+
return intl.formatMessage({
|
|
69
|
+
id: 'ai.upload.file.json.array.summary'
|
|
70
|
+
}, {
|
|
71
|
+
dataLength: data.length,
|
|
72
|
+
keys: keys.join(', '),
|
|
73
|
+
maxLines: MAX_LINES,
|
|
74
|
+
sampleData: sampleData
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
return intl.formatMessage({
|
|
78
|
+
id: 'ai.upload.file.json.object.summary'
|
|
79
|
+
}) + '\n' + JSON.stringify(data, null, 2);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// --- 文件解析服务函数 ---
|
|
83
|
+
function parseFile(_x, _x2) {
|
|
84
|
+
return _parseFile.apply(this, arguments);
|
|
85
|
+
}
|
|
86
|
+
function _parseFile() {
|
|
87
|
+
_parseFile = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(file, intl) {
|
|
88
|
+
return _regeneratorRuntime().wrap(function _callee$(_context) {
|
|
89
|
+
while (1) switch (_context.prev = _context.next) {
|
|
90
|
+
case 0:
|
|
91
|
+
return _context.abrupt("return", new Promise(function (resolve, reject) {
|
|
92
|
+
var reader = new FileReader();
|
|
93
|
+
reader.onload = function (event) {
|
|
94
|
+
try {
|
|
95
|
+
var _event$target;
|
|
96
|
+
var fileContent = (_event$target = event.target) === null || _event$target === void 0 ? void 0 : _event$target.result;
|
|
97
|
+
var dataSummary;
|
|
98
|
+
|
|
99
|
+
// --- 智能策略判断 ---
|
|
100
|
+
if (fileContent.length <= DIRECT_FEED_CHAR_THRESHOLD) {
|
|
101
|
+
// 策略1:文件内容足够小,直接作为上下文
|
|
102
|
+
dataSummary = intl.formatMessage({
|
|
103
|
+
id: 'ai.upload.file.full.content'
|
|
104
|
+
}, {
|
|
105
|
+
fileContent: fileContent
|
|
106
|
+
});
|
|
107
|
+
} else {
|
|
108
|
+
var _file$name$split$pop2;
|
|
109
|
+
// 策略2:文件内容过大,执行摘要算法
|
|
110
|
+
var fileType = ((_file$name$split$pop2 = file.name.split('.').pop()) === null || _file$name$split$pop2 === void 0 ? void 0 : _file$name$split$pop2.toLowerCase()) || '';
|
|
111
|
+
if (fileType === 'json') {
|
|
112
|
+
var jsonData = JSON.parse(fileContent);
|
|
113
|
+
dataSummary = getJsonSummary(jsonData, intl);
|
|
114
|
+
} else if (['csv', 'tsv', 'txt'].includes(fileType)) {
|
|
115
|
+
dataSummary = getTableSummary(fileContent, fileType, intl);
|
|
116
|
+
} else {
|
|
117
|
+
reject(new Error(intl.formatMessage({
|
|
118
|
+
id: 'ai.upload.file.parse.type.error'
|
|
119
|
+
})));
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
if (dataSummary.length > MAX_CONTEXT_CHARS) {
|
|
123
|
+
dataSummary = dataSummary.substring(0, MAX_CONTEXT_CHARS) + "\n" + intl.formatMessage({
|
|
124
|
+
id: 'ai.upload.file.summary.truncated'
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
resolve({
|
|
129
|
+
dataSummary: dataSummary,
|
|
130
|
+
fileMeta: {
|
|
131
|
+
type: 'FILE',
|
|
132
|
+
fileName: file.name,
|
|
133
|
+
fileSize: formatBytes(file.size)
|
|
134
|
+
}
|
|
135
|
+
});
|
|
136
|
+
} catch (e) {
|
|
137
|
+
reject(new Error(intl.formatMessage({
|
|
138
|
+
id: 'ai.upload.file.parse.error'
|
|
139
|
+
})));
|
|
140
|
+
}
|
|
141
|
+
};
|
|
142
|
+
reader.onerror = function () {
|
|
143
|
+
return reject(new Error(intl.formatMessage({
|
|
144
|
+
id: 'ai.upload.file.read.error'
|
|
145
|
+
})));
|
|
146
|
+
};
|
|
147
|
+
reader.readAsText(file);
|
|
148
|
+
}));
|
|
149
|
+
case 1:
|
|
150
|
+
case "end":
|
|
151
|
+
return _context.stop();
|
|
152
|
+
}
|
|
153
|
+
}, _callee);
|
|
154
|
+
}));
|
|
155
|
+
return _parseFile.apply(this, arguments);
|
|
156
|
+
}
|
|
157
|
+
export var DataUploader = function DataUploader(_ref) {
|
|
158
|
+
var onDataAnalyzed = _ref.onDataAnalyzed,
|
|
159
|
+
isCompact = _ref.isCompact,
|
|
160
|
+
tooltipText = _ref.tooltipText;
|
|
161
|
+
var intl = useIntl();
|
|
162
|
+
var _useRequest = useRequest(function (file) {
|
|
163
|
+
return parseFile(file, intl);
|
|
164
|
+
}, {
|
|
165
|
+
manual: true,
|
|
166
|
+
onSuccess: function onSuccess(result) {
|
|
167
|
+
// message.success(`${result.fileMeta?.fileName} 分析成功!`);
|
|
168
|
+
onDataAnalyzed(result);
|
|
169
|
+
},
|
|
170
|
+
onError: function onError(e) {
|
|
171
|
+
message.error(e.message);
|
|
172
|
+
// 如果解析失败,也需要通知父组件清空数据
|
|
173
|
+
onDataAnalyzed({
|
|
174
|
+
fileMeta: null,
|
|
175
|
+
dataSummary: ''
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
}),
|
|
179
|
+
runParse = _useRequest.run,
|
|
180
|
+
loading = _useRequest.loading;
|
|
181
|
+
var uploadProps = {
|
|
182
|
+
showUploadList: false,
|
|
183
|
+
// 我们用自己的DatasourceCard来回显,所以隐藏默认列表
|
|
184
|
+
accept: ALLOWED_FILE_TYPES.map(function (ext) {
|
|
185
|
+
return ".".concat(ext);
|
|
186
|
+
}).join(','),
|
|
187
|
+
beforeUpload: function beforeUpload(file) {
|
|
188
|
+
var _file$name$split$pop;
|
|
189
|
+
var fileExtension = ((_file$name$split$pop = file.name.split('.').pop()) === null || _file$name$split$pop === void 0 ? void 0 : _file$name$split$pop.toLowerCase()) || '';
|
|
190
|
+
if (!ALLOWED_FILE_TYPES.includes(fileExtension)) {
|
|
191
|
+
message.error(intl.formatMessage({
|
|
192
|
+
id: 'ai.upload.file.type.error'
|
|
193
|
+
}, {
|
|
194
|
+
types: ALLOWED_FILE_TYPES.join(', ')
|
|
195
|
+
}));
|
|
196
|
+
return Upload.LIST_IGNORE;
|
|
197
|
+
}
|
|
198
|
+
if (file.size / 1024 / 1024 > MAX_FILE_SIZE_MB) {
|
|
199
|
+
message.error(intl.formatMessage({
|
|
200
|
+
id: 'ai.upload.file.size.error'
|
|
201
|
+
}, {
|
|
202
|
+
size: MAX_FILE_SIZE_MB
|
|
203
|
+
}));
|
|
204
|
+
return Upload.LIST_IGNORE;
|
|
205
|
+
}
|
|
206
|
+
runParse(file);
|
|
207
|
+
return false; // 总是返回 false 来手动控制
|
|
208
|
+
}
|
|
209
|
+
};
|
|
210
|
+
return /*#__PURE__*/React.createElement(Tooltip, {
|
|
211
|
+
title: isCompact ? "".concat(intl.formatMessage({
|
|
212
|
+
id: 'ai.upload.data'
|
|
213
|
+
}), "\u3002").concat(tooltipText) : tooltipText
|
|
214
|
+
}, /*#__PURE__*/React.createElement(Upload, uploadProps, /*#__PURE__*/React.createElement("button", {
|
|
215
|
+
type: "button",
|
|
216
|
+
disabled: loading
|
|
217
|
+
}, loading ? intl.formatMessage({
|
|
218
|
+
id: 'ai.upload.analyzing'
|
|
219
|
+
}) : /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("img", {
|
|
220
|
+
src: FileIcons.FILE,
|
|
221
|
+
alt: "file-icon"
|
|
222
|
+
}), " ", !isCompact && intl.formatMessage({
|
|
223
|
+
id: 'ai.upload.data'
|
|
224
|
+
})))));
|
|
225
|
+
};
|
|
@@ -10,7 +10,7 @@ function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" !=
|
|
|
10
10
|
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
11
11
|
import { DatasourceCard } from "./DatasourceCard";
|
|
12
12
|
import { useEventListener } from 'ahooks';
|
|
13
|
-
import {
|
|
13
|
+
import { Tooltip, Upload } from 'antd';
|
|
14
14
|
import classnames from 'classnames';
|
|
15
15
|
import _ from 'lodash';
|
|
16
16
|
import React, { useState } from 'react';
|
|
@@ -18,29 +18,37 @@ import styles from "./index.module.less";
|
|
|
18
18
|
import { SendButton } from "./SendButton";
|
|
19
19
|
import { AIMode, FileIcons } from "../../constant";
|
|
20
20
|
import { ChooseLib } from "./ChooseLib";
|
|
21
|
-
import { useSiteData } from 'dumi';
|
|
21
|
+
import { useSiteData, useIntl } from 'dumi';
|
|
22
22
|
import { ic } from "../../../../slots/hooks";
|
|
23
|
+
import { useTypewriter } from "../../../../hooks/useTypewriter";
|
|
24
|
+
import { DataUploader } from "./Uploader/DataUploader";
|
|
23
25
|
var PLACEHOLDER = {
|
|
24
|
-
implement: '
|
|
25
|
-
solve: '
|
|
26
|
+
implement: 'ai.placeholder.implement',
|
|
27
|
+
solve: 'ai.placeholder.solve'
|
|
26
28
|
};
|
|
27
29
|
function PromptTextarea(props) {
|
|
28
30
|
var value = props.value,
|
|
29
31
|
size = props.size,
|
|
30
32
|
_onChange = props.onChange,
|
|
33
|
+
onDataSummaryChange = props.onDataSummaryChange,
|
|
31
34
|
onConfirm = props.onConfirm,
|
|
32
35
|
onCancel = props.onCancel,
|
|
33
36
|
loading = props.loading,
|
|
34
|
-
fileMeta = props.fileMeta,
|
|
35
37
|
mode = props.mode,
|
|
36
38
|
lib = props.lib,
|
|
37
39
|
onLibChange = props.onLibChange,
|
|
38
40
|
_props$showAction = props.showAction,
|
|
39
41
|
showAction = _props$showAction === void 0 ? true : _props$showAction;
|
|
40
|
-
var
|
|
42
|
+
var _useIntl = useIntl(),
|
|
43
|
+
formatMessage = _useIntl.formatMessage;
|
|
44
|
+
|
|
45
|
+
// 将fileMeta状态移到组件内部管理
|
|
46
|
+
var _useState = useState(null),
|
|
41
47
|
_useState2 = _slicedToArray(_useState, 2),
|
|
42
|
-
|
|
43
|
-
|
|
48
|
+
fileMeta = _useState2[0],
|
|
49
|
+
setFileMeta = _useState2[1];
|
|
50
|
+
|
|
51
|
+
// ... 其他状态和hooks保持不变
|
|
44
52
|
var _useState3 = useState(false),
|
|
45
53
|
_useState4 = _slicedToArray(_useState3, 2),
|
|
46
54
|
focus = _useState4[0],
|
|
@@ -48,12 +56,35 @@ function PromptTextarea(props) {
|
|
|
48
56
|
var isCompact = size === 'compact';
|
|
49
57
|
var _useSiteData = useSiteData(),
|
|
50
58
|
themeConfig = _useSiteData.themeConfig;
|
|
59
|
+
var typedPlaceholder = useTypewriter({
|
|
60
|
+
texts: [formatMessage({
|
|
61
|
+
id: 'ai.placeholder.whatis'
|
|
62
|
+
}, {
|
|
63
|
+
title: themeConfig.title
|
|
64
|
+
}), ic(themeConfig.metas.description)]
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
// 处理DataUploader的回调
|
|
68
|
+
var handleDataAnalyzed = function handleDataAnalyzed(analyzedData) {
|
|
69
|
+
setFileMeta(analyzedData.fileMeta);
|
|
70
|
+
if (onDataSummaryChange) {
|
|
71
|
+
onDataSummaryChange(analyzedData.dataSummary);
|
|
72
|
+
}
|
|
73
|
+
};
|
|
51
74
|
function renderDatasourceCard() {
|
|
52
75
|
if (((fileMeta === null || fileMeta === void 0 ? void 0 : fileMeta.type) === 'FILE' || (fileMeta === null || fileMeta === void 0 ? void 0 : fileMeta.type) === 'IMAGE') && fileMeta !== null && fileMeta !== void 0 && fileMeta.fileName) {
|
|
76
|
+
// 当点击DatasourceCard的关闭按钮时,应该清空状态
|
|
77
|
+
var handleClose = function handleClose() {
|
|
78
|
+
setFileMeta(null);
|
|
79
|
+
if (onDataSummaryChange) {
|
|
80
|
+
onDataSummaryChange('');
|
|
81
|
+
}
|
|
82
|
+
};
|
|
53
83
|
return /*#__PURE__*/React.createElement(DatasourceCard, {
|
|
54
84
|
type: fileMeta.type,
|
|
55
85
|
title: fileMeta.fileName,
|
|
56
|
-
desc: fileMeta.fileSize
|
|
86
|
+
desc: fileMeta.fileSize,
|
|
87
|
+
onDelete: handleClose
|
|
57
88
|
});
|
|
58
89
|
} else {
|
|
59
90
|
return null;
|
|
@@ -62,10 +93,7 @@ function PromptTextarea(props) {
|
|
|
62
93
|
var datasourceNode = renderDatasourceCard();
|
|
63
94
|
var promptTextValid = Boolean(value);
|
|
64
95
|
var send = function send() {
|
|
65
|
-
if (
|
|
66
|
-
message.warning('请输入指令');
|
|
67
|
-
} else {
|
|
68
|
-
setShowError(false);
|
|
96
|
+
if (promptTextValid) {
|
|
69
97
|
onConfirm === null || onConfirm === void 0 || onConfirm();
|
|
70
98
|
}
|
|
71
99
|
};
|
|
@@ -92,7 +120,11 @@ function PromptTextarea(props) {
|
|
|
92
120
|
},
|
|
93
121
|
id: "prompt-textarea",
|
|
94
122
|
className: classnames(styles.promptTextarea),
|
|
95
|
-
placeholder:
|
|
123
|
+
placeholder:
|
|
124
|
+
// (!isCompact && !themeConfig.isAntVSite && ic(themeConfig.metas.description)) ||
|
|
125
|
+
!isCompact && !themeConfig.isAntVSite ? typedPlaceholder : formatMessage({
|
|
126
|
+
id: _.get(PLACEHOLDER, mode, 'ai.placeholder.implement')
|
|
127
|
+
}),
|
|
96
128
|
value: value,
|
|
97
129
|
onChange: function onChange(evt) {
|
|
98
130
|
_onChange(evt.target.value);
|
|
@@ -105,19 +137,23 @@ function PromptTextarea(props) {
|
|
|
105
137
|
value: lib,
|
|
106
138
|
onChange: onLibChange,
|
|
107
139
|
size: size
|
|
108
|
-
}), mode === AIMode.implement && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
}),
|
|
115
|
-
title: isCompact
|
|
140
|
+
}), mode === AIMode.implement && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(DataUploader, {
|
|
141
|
+
onDataAnalyzed: handleDataAnalyzed,
|
|
142
|
+
isCompact: isCompact,
|
|
143
|
+
tooltipText: formatMessage({
|
|
144
|
+
id: 'ai.upload.tooltip'
|
|
145
|
+
})
|
|
146
|
+
}), /*#__PURE__*/React.createElement(Tooltip, {
|
|
147
|
+
title: isCompact ? formatMessage({
|
|
148
|
+
id: 'ai.upload.image'
|
|
149
|
+
}) : undefined
|
|
116
150
|
}, /*#__PURE__*/React.createElement(Upload, null, /*#__PURE__*/React.createElement("button", {
|
|
117
151
|
type: "button"
|
|
118
152
|
}, /*#__PURE__*/React.createElement("img", {
|
|
119
153
|
src: FileIcons.IMAGE
|
|
120
|
-
}), " ", !isCompact &&
|
|
154
|
+
}), " ", !isCompact && formatMessage({
|
|
155
|
+
id: 'ai.upload.image'
|
|
156
|
+
}))))))), /*#__PURE__*/React.createElement("div", {
|
|
121
157
|
className: styles.actions
|
|
122
158
|
}, loading ? /*#__PURE__*/React.createElement("img", {
|
|
123
159
|
className: styles.actionBtn,
|
|
@@ -126,7 +162,9 @@ function PromptTextarea(props) {
|
|
|
126
162
|
}) : /*#__PURE__*/React.createElement(SendButton, {
|
|
127
163
|
onClick: send,
|
|
128
164
|
disabled: !promptTextValid,
|
|
129
|
-
tip: !promptTextValid ?
|
|
165
|
+
tip: !promptTextValid ? formatMessage({
|
|
166
|
+
id: 'ai.msgbox.send.tip'
|
|
167
|
+
}) : undefined
|
|
130
168
|
}))));
|
|
131
169
|
}
|
|
132
170
|
export { PromptTextarea };
|
|
@@ -3,6 +3,7 @@ import React from 'react';
|
|
|
3
3
|
import styles from "./card.module.less";
|
|
4
4
|
import { BarChartOutlined, QuestionCircleOutlined } from "@ant-design/icons";
|
|
5
5
|
import { AIMode, AIModeMeta, COLORS } from "../../constant";
|
|
6
|
+
import { FormattedMessage } from 'dumi';
|
|
6
7
|
export var Card = function Card(_ref) {
|
|
7
8
|
var _AIModeMeta$tag;
|
|
8
9
|
var item = _ref.item,
|
|
@@ -26,13 +27,17 @@ export var Card = function Card(_ref) {
|
|
|
26
27
|
className: styles.popoverItem
|
|
27
28
|
}, /*#__PURE__*/React.createElement("div", {
|
|
28
29
|
className: styles.popoverLabel
|
|
29
|
-
},
|
|
30
|
+
}, /*#__PURE__*/React.createElement(FormattedMessage, {
|
|
31
|
+
id: "ai.recommend.card.caseName"
|
|
32
|
+
})), /*#__PURE__*/React.createElement("div", {
|
|
30
33
|
className: styles.popoverValue
|
|
31
34
|
}, query)), /*#__PURE__*/React.createElement("div", {
|
|
32
35
|
className: styles.popoverItem
|
|
33
36
|
}, /*#__PURE__*/React.createElement("div", {
|
|
34
37
|
className: styles.popoverLabel
|
|
35
|
-
},
|
|
38
|
+
}, /*#__PURE__*/React.createElement(FormattedMessage, {
|
|
39
|
+
id: "ai.recommend.card.description"
|
|
40
|
+
})), /*#__PURE__*/React.createElement("div", {
|
|
36
41
|
className: styles.popoverValue
|
|
37
42
|
}, description)));
|
|
38
43
|
return /*#__PURE__*/React.createElement(Popover, {
|
|
@@ -54,7 +59,9 @@ export var Card = function Card(_ref) {
|
|
|
54
59
|
className: styles.typeIcon
|
|
55
60
|
}), /*#__PURE__*/React.createElement("span", {
|
|
56
61
|
className: styles.typeText
|
|
57
|
-
},
|
|
62
|
+
}, /*#__PURE__*/React.createElement(FormattedMessage, {
|
|
63
|
+
id: ((_AIModeMeta$tag = AIModeMeta[tag]) === null || _AIModeMeta$tag === void 0 ? void 0 : _AIModeMeta$tag.name) || tag
|
|
64
|
+
}))), /*#__PURE__*/React.createElement("div", {
|
|
58
65
|
className: styles.title
|
|
59
66
|
}, query), /*#__PURE__*/React.createElement("div", {
|
|
60
67
|
className: styles.imageContainer
|
|
@@ -12,9 +12,10 @@ import { Spin } from 'antd';
|
|
|
12
12
|
import React, { useCallback, useEffect, useState } from 'react';
|
|
13
13
|
import { Card } from "./Card";
|
|
14
14
|
import styles from "./index.module.less";
|
|
15
|
-
import {
|
|
15
|
+
import { ReloadOutlined } from "@ant-design/icons";
|
|
16
16
|
import RecommendJson from "./recommend.json";
|
|
17
17
|
import classnames from "classnames";
|
|
18
|
+
import { FormattedMessage } from 'dumi';
|
|
18
19
|
export var RecommendCase = function RecommendCase(props) {
|
|
19
20
|
var _useState = useState(false),
|
|
20
21
|
_useState2 = _slicedToArray(_useState, 2),
|
|
@@ -56,12 +57,16 @@ export var RecommendCase = function RecommendCase(props) {
|
|
|
56
57
|
className: styles.title
|
|
57
58
|
}, /*#__PURE__*/React.createElement("span", {
|
|
58
59
|
className: styles.quickStart
|
|
59
|
-
},
|
|
60
|
+
}, /*#__PURE__*/React.createElement(FormattedMessage, {
|
|
61
|
+
id: "ai.recommend.title"
|
|
62
|
+
})), /*#__PURE__*/React.createElement("span", {
|
|
60
63
|
className: styles.refresh,
|
|
61
64
|
onClick: function onClick() {
|
|
62
65
|
return fetchList();
|
|
63
66
|
}
|
|
64
|
-
}, /*#__PURE__*/React.createElement(
|
|
67
|
+
}, /*#__PURE__*/React.createElement(ReloadOutlined, null), /*#__PURE__*/React.createElement(FormattedMessage, {
|
|
68
|
+
id: "ai.recommend.refresh"
|
|
69
|
+
}))), /*#__PURE__*/React.createElement(Spin, {
|
|
65
70
|
spinning: loading,
|
|
66
71
|
wrapperClassName: classnames(styles.listContainer, props.className)
|
|
67
72
|
}, /*#__PURE__*/React.createElement("div", {
|
|
@@ -13,9 +13,10 @@ import { ModeSelector } from "./ModeSelector";
|
|
|
13
13
|
import { useLocalStorageState } from 'ahooks';
|
|
14
14
|
import { AIMode } from "../constant";
|
|
15
15
|
import classnames from 'classnames';
|
|
16
|
-
import { useSiteData } from 'dumi';
|
|
16
|
+
import { useSiteData, useLocale } from 'dumi';
|
|
17
17
|
import { createNewSession } from "../../../model/AIChat";
|
|
18
18
|
export function HomeDialog(props) {
|
|
19
|
+
var locale = useLocale();
|
|
19
20
|
var _useSiteData = useSiteData(),
|
|
20
21
|
themeConfig = _useSiteData.themeConfig;
|
|
21
22
|
var _useState = useState(!themeConfig.isAntVSite ? themeConfig.title : undefined),
|
|
@@ -32,6 +33,10 @@ export function HomeDialog(props) {
|
|
|
32
33
|
_useState4 = _slicedToArray(_useState3, 2),
|
|
33
34
|
promptText = _useState4[0],
|
|
34
35
|
setPromptText = _useState4[1];
|
|
36
|
+
var _useState5 = useState(''),
|
|
37
|
+
_useState6 = _slicedToArray(_useState5, 2),
|
|
38
|
+
fileSummary = _useState6[0],
|
|
39
|
+
setFileSummary = _useState6[1];
|
|
35
40
|
return /*#__PURE__*/React.createElement("div", {
|
|
36
41
|
className: classnames(styles.content, props.className),
|
|
37
42
|
style: props.style
|
|
@@ -55,10 +60,14 @@ export function HomeDialog(props) {
|
|
|
55
60
|
createNewSession({
|
|
56
61
|
promptText: promptText,
|
|
57
62
|
mode: mode,
|
|
58
|
-
lib: lib
|
|
63
|
+
lib: lib,
|
|
64
|
+
jump: true,
|
|
65
|
+
context: fileSummary,
|
|
66
|
+
lang: locale.id
|
|
59
67
|
});
|
|
60
68
|
},
|
|
61
|
-
style: props.promptTextareaStyle
|
|
69
|
+
style: props.promptTextareaStyle,
|
|
70
|
+
onDataSummaryChange: setFileSummary
|
|
62
71
|
}), /*#__PURE__*/React.createElement(RecommendCase, {
|
|
63
72
|
className: props.recommendCaseClassName
|
|
64
73
|
}));
|
|
@@ -6,11 +6,11 @@ export var AIMode = {
|
|
|
6
6
|
};
|
|
7
7
|
export var AIModeMeta = {
|
|
8
8
|
implement: {
|
|
9
|
-
name: '
|
|
9
|
+
name: 'ai.mode.implement',
|
|
10
10
|
icon: /*#__PURE__*/React.createElement(BarChartOutlined, null)
|
|
11
11
|
},
|
|
12
12
|
solve: {
|
|
13
|
-
name: '
|
|
13
|
+
name: 'ai.mode.solve',
|
|
14
14
|
icon: /*#__PURE__*/React.createElement(QuestionCircleOutlined, null)
|
|
15
15
|
}
|
|
16
16
|
};
|