@agentscope-ai/chat 1.1.61 → 1.1.62
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/components/AgentScopeRuntimeWebUI/core/Chat/hooks/useChatController.tsx +4 -0
- package/components/AgentScopeRuntimeWebUI/core/Chat/hooks/useChatRequest.tsx +19 -1
- package/components/Markdown/core/components/CodeBlock.tsx +16 -6
- package/components/Stream/index.ts +39 -12
- package/lib/AgentScopeRuntimeWebUI/core/Chat/hooks/useChatController.js +10 -5
- package/lib/AgentScopeRuntimeWebUI/core/Chat/hooks/useChatRequest.js +60 -44
- package/lib/Markdown/core/components/CodeBlock.js +44 -12
- package/lib/Stream/index.d.ts +5 -0
- package/lib/Stream/index.js +38 -18
- package/package.json +1 -1
- package/bin/starter_webui/README.md +0 -75
- package/bin/starter_webui/eslint.config.js +0 -28
- package/bin/starter_webui/index.html +0 -12
- package/bin/starter_webui/package.json +0 -34
- package/bin/starter_webui/src/App.tsx +0 -20
- package/bin/starter_webui/src/components/Chat/OptionsPanel/FormItem.tsx +0 -37
- package/bin/starter_webui/src/components/Chat/OptionsPanel/OptionsEditor.tsx +0 -160
- package/bin/starter_webui/src/components/Chat/OptionsPanel/defaultConfig.ts +0 -41
- package/bin/starter_webui/src/components/Chat/OptionsPanel/index.tsx +0 -27
- package/bin/starter_webui/src/components/Chat/index.tsx +0 -45
- package/bin/starter_webui/src/components/Chat/sessionApi/index.ts +0 -53
- package/bin/starter_webui/src/main.tsx +0 -9
- package/bin/starter_webui/src/vite-env.d.ts +0 -4
- package/bin/starter_webui/tsconfig.app.json +0 -24
- package/bin/starter_webui/tsconfig.json +0 -7
- package/bin/starter_webui/tsconfig.node.json +0 -22
- package/bin/starter_webui/vite.config.ts +0 -11
|
@@ -99,9 +99,13 @@ export default function useChatController() {
|
|
|
99
99
|
|
|
100
100
|
/**
|
|
101
101
|
* 处理取消
|
|
102
|
+
* 1. 标记 interrupted 并重置 UI(finishResponse)
|
|
103
|
+
* 2. abort SSE 连接 —— Stream 内部的 Promise.race 会立即 reject AbortError,
|
|
104
|
+
* processSSEResponse 的 catch 会检测 interrupted 状态并调用 cancel API
|
|
102
105
|
*/
|
|
103
106
|
const handleCancel = useCallback(() => {
|
|
104
107
|
finishResponse('interrupted');
|
|
108
|
+
currentQARef.current.abortController?.abort();
|
|
105
109
|
}, [finishResponse]);
|
|
106
110
|
|
|
107
111
|
/**
|
|
@@ -92,9 +92,12 @@ export default function useChatRequest(options: UseChatRequestOptions) {
|
|
|
92
92
|
return;
|
|
93
93
|
}
|
|
94
94
|
|
|
95
|
+
const abortSignal = currentQARef.current.abortController?.signal;
|
|
96
|
+
|
|
95
97
|
try {
|
|
96
98
|
for await (const chunk of Stream({
|
|
97
99
|
readableStream: response.body,
|
|
100
|
+
signal: abortSignal,
|
|
98
101
|
})) {
|
|
99
102
|
if (currentQARef.current.response?.msgStatus === 'interrupted') {
|
|
100
103
|
currentQARef.current.abortController?.abort();
|
|
@@ -137,7 +140,22 @@ export default function useChatRequest(options: UseChatRequestOptions) {
|
|
|
137
140
|
}
|
|
138
141
|
}
|
|
139
142
|
} catch (error) {
|
|
140
|
-
|
|
143
|
+
if (currentQARef.current.response?.msgStatus === 'interrupted') {
|
|
144
|
+
if (currentApiOptions.cancel) {
|
|
145
|
+
currentApiOptions.cancel({
|
|
146
|
+
session_id: getCurrentSessionId(),
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
currentQARef.current.response.cards = [
|
|
150
|
+
{
|
|
151
|
+
code: 'AgentScopeRuntimeResponseCard',
|
|
152
|
+
data: agentScopeRuntimeResponseBuilder.cancel(),
|
|
153
|
+
}
|
|
154
|
+
];
|
|
155
|
+
updateMessage(currentQARef.current.response);
|
|
156
|
+
} else {
|
|
157
|
+
console.error(error);
|
|
158
|
+
}
|
|
141
159
|
}
|
|
142
160
|
}, [getCurrentSessionId, currentQARef, updateMessage, onFinish]);
|
|
143
161
|
|
|
@@ -41,14 +41,24 @@ function CodeHeader({ lang, content }: { lang: string, content: string }) {
|
|
|
41
41
|
URL.revokeObjectURL(url);
|
|
42
42
|
}, [lang, content]);
|
|
43
43
|
|
|
44
|
-
const handleCopy = useCallback(() => {
|
|
45
|
-
|
|
46
|
-
|
|
44
|
+
const handleCopy = useCallback(async () => {
|
|
45
|
+
try {
|
|
46
|
+
if (window.isSecureContext && navigator.clipboard) {
|
|
47
|
+
await navigator.clipboard.writeText(content);
|
|
48
|
+
} else {
|
|
49
|
+
const textarea = document.createElement('textarea');
|
|
50
|
+
textarea.value = content;
|
|
51
|
+
textarea.style.cssText = 'position:fixed;left:-9999px';
|
|
52
|
+
document.body.appendChild(textarea);
|
|
53
|
+
textarea.select();
|
|
54
|
+
document.execCommand('copy');
|
|
55
|
+
document.body.removeChild(textarea);
|
|
56
|
+
}
|
|
47
57
|
setCopied(true);
|
|
48
|
-
|
|
49
|
-
}
|
|
58
|
+
setTimeout(() => setCopied(false), 1000);
|
|
59
|
+
} catch {
|
|
50
60
|
console.warn('Copy failed');
|
|
51
|
-
}
|
|
61
|
+
}
|
|
52
62
|
}, [content]);
|
|
53
63
|
|
|
54
64
|
return <div className={prefixCls}>
|
|
@@ -137,6 +137,12 @@ export interface StreamOptions<Output> {
|
|
|
137
137
|
* @link https://developer.mozilla.org/en-US/docs/Web/API/TransformStream
|
|
138
138
|
*/
|
|
139
139
|
transformStream?: TransformStream<string, Output>;
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* @description 用于中断流读取的 AbortSignal
|
|
143
|
+
* @descriptionEn AbortSignal to cancel stream reading
|
|
144
|
+
*/
|
|
145
|
+
signal?: AbortSignal;
|
|
140
146
|
}
|
|
141
147
|
|
|
142
148
|
type XReadableStream<R = SSEOutput> = ReadableStream<R> & AsyncGenerator<R>;
|
|
@@ -151,7 +157,7 @@ function Stream<Output = SSEOutput>(
|
|
|
151
157
|
openaiCompatible?: boolean;
|
|
152
158
|
},
|
|
153
159
|
) {
|
|
154
|
-
const { readableStream, transformStream } = options;
|
|
160
|
+
const { readableStream, transformStream, signal } = options;
|
|
155
161
|
|
|
156
162
|
if (!(readableStream instanceof ReadableStream)) {
|
|
157
163
|
throw new Error(
|
|
@@ -181,19 +187,40 @@ function Stream<Output = SSEOutput>(
|
|
|
181
187
|
stream[Symbol.asyncIterator] = async function* () {
|
|
182
188
|
const reader = this.getReader();
|
|
183
189
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
190
|
+
try {
|
|
191
|
+
while (true) {
|
|
192
|
+
let readPromise: Promise<ReadableStreamReadResult<Output>> = reader.read();
|
|
193
|
+
|
|
194
|
+
if (signal) {
|
|
195
|
+
readPromise = Promise.race([
|
|
196
|
+
readPromise,
|
|
197
|
+
new Promise<never>((_, reject) => {
|
|
198
|
+
if (signal.aborted) {
|
|
199
|
+
reject(new DOMException('The operation was aborted.', 'AbortError'));
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
202
|
+
signal.addEventListener('abort', () => {
|
|
203
|
+
reject(new DOMException('The operation was aborted.', 'AbortError'));
|
|
204
|
+
}, { once: true });
|
|
205
|
+
}),
|
|
206
|
+
]);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
const { done, value } = await readPromise;
|
|
210
|
+
if (done) break;
|
|
187
211
|
|
|
188
|
-
|
|
212
|
+
if (!value) continue;
|
|
189
213
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
214
|
+
// Transformed data through all transform pipes
|
|
215
|
+
yield config?.openaiCompatible
|
|
216
|
+
? {
|
|
217
|
+
...value,
|
|
218
|
+
data: (value as any).data.slice(1),
|
|
219
|
+
}
|
|
220
|
+
: value;
|
|
221
|
+
}
|
|
222
|
+
} finally {
|
|
223
|
+
reader.releaseLock();
|
|
197
224
|
}
|
|
198
225
|
};
|
|
199
226
|
|
|
@@ -139,9 +139,14 @@ export default function useChatController() {
|
|
|
139
139
|
|
|
140
140
|
/**
|
|
141
141
|
* 处理取消
|
|
142
|
+
* 1. 标记 interrupted 并重置 UI(finishResponse)
|
|
143
|
+
* 2. abort SSE 连接 —— Stream 内部的 Promise.race 会立即 reject AbortError,
|
|
144
|
+
* processSSEResponse 的 catch 会检测 interrupted 状态并调用 cancel API
|
|
142
145
|
*/
|
|
143
146
|
var handleCancel = useCallback(function () {
|
|
147
|
+
var _currentQARef$current;
|
|
144
148
|
finishResponse('interrupted');
|
|
149
|
+
(_currentQARef$current = currentQARef.current.abortController) === null || _currentQARef$current === void 0 || _currentQARef$current.abort();
|
|
145
150
|
}, [finishResponse]);
|
|
146
151
|
|
|
147
152
|
/**
|
|
@@ -184,8 +189,8 @@ export default function useChatController() {
|
|
|
184
189
|
*/
|
|
185
190
|
var handleReconnect = useCallback( /*#__PURE__*/function () {
|
|
186
191
|
var _ref5 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee4(sessionId) {
|
|
187
|
-
var _currentQARef$current;
|
|
188
192
|
var _currentQARef$current2;
|
|
193
|
+
var _currentQARef$current3;
|
|
189
194
|
return _regeneratorRuntime().wrap(function _callee4$(_context4) {
|
|
190
195
|
while (1) switch (_context4.prev = _context4.next) {
|
|
191
196
|
case 0:
|
|
@@ -200,9 +205,9 @@ export default function useChatController() {
|
|
|
200
205
|
// Treat as idle: remove the empty placeholder and reset loading.
|
|
201
206
|
// HTTP errors and normal SSE completions both call onFinish() → msgStatus becomes 'finished',
|
|
202
207
|
// so they are correctly excluded from this cleanup.
|
|
203
|
-
if (((_currentQARef$
|
|
208
|
+
if (((_currentQARef$current2 = currentQARef.current.response) === null || _currentQARef$current2 === void 0 ? void 0 : _currentQARef$current2.msgStatus) === 'generating') {
|
|
204
209
|
setLoading(false);
|
|
205
|
-
if ((_currentQARef$
|
|
210
|
+
if ((_currentQARef$current3 = currentQARef.current.response) !== null && _currentQARef$current3 !== void 0 && _currentQARef$current3.id) {
|
|
206
211
|
messageHandler.removeMessageById(currentQARef.current.response.id);
|
|
207
212
|
}
|
|
208
213
|
currentQARef.current.response = undefined;
|
|
@@ -220,8 +225,8 @@ export default function useChatController() {
|
|
|
220
225
|
|
|
221
226
|
// 监听会话切换,断开当前 SSE 连接(不通知后端取消)并重置状态
|
|
222
227
|
useEffect(function () {
|
|
223
|
-
var _currentQARef$
|
|
224
|
-
(_currentQARef$
|
|
228
|
+
var _currentQARef$current4;
|
|
229
|
+
(_currentQARef$current4 = currentQARef.current.abortController) === null || _currentQARef$current4 === void 0 || _currentQARef$current4.abort();
|
|
225
230
|
currentQARef.current = {
|
|
226
231
|
request: undefined,
|
|
227
232
|
response: undefined,
|
|
@@ -102,7 +102,8 @@ export default function useChatRequest(options) {
|
|
|
102
102
|
}(), []);
|
|
103
103
|
var processSSEResponse = useCallback( /*#__PURE__*/function () {
|
|
104
104
|
var _ref2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee2(response) {
|
|
105
|
-
var
|
|
105
|
+
var _currentQARef$current;
|
|
106
|
+
var currentApiOptions, agentScopeRuntimeResponseBuilder, data, res, abortSignal, _iteratorAbruptCompletion2, _didIteratorError2, _iteratorError2, _iterator2, _step2, chunk, _currentQARef$current2, _res$output, _currentQARef$current3, responseParser, chunkData, _res, _currentQARef$current4;
|
|
106
107
|
return _regeneratorRuntime().wrap(function _callee2$(_context2) {
|
|
107
108
|
while (1) switch (_context2.prev = _context2.next) {
|
|
108
109
|
case 0:
|
|
@@ -144,27 +145,29 @@ export default function useChatRequest(options) {
|
|
|
144
145
|
onFinish();
|
|
145
146
|
return _context2.abrupt("return");
|
|
146
147
|
case 15:
|
|
147
|
-
|
|
148
|
+
abortSignal = (_currentQARef$current = currentQARef.current.abortController) === null || _currentQARef$current === void 0 ? void 0 : _currentQARef$current.signal;
|
|
149
|
+
_context2.prev = 16;
|
|
148
150
|
_iteratorAbruptCompletion2 = false;
|
|
149
151
|
_didIteratorError2 = false;
|
|
150
|
-
_context2.prev =
|
|
152
|
+
_context2.prev = 19;
|
|
151
153
|
_iterator2 = _asyncIterator(Stream({
|
|
152
|
-
readableStream: response.body
|
|
154
|
+
readableStream: response.body,
|
|
155
|
+
signal: abortSignal
|
|
153
156
|
}));
|
|
154
|
-
case
|
|
155
|
-
_context2.next =
|
|
157
|
+
case 21:
|
|
158
|
+
_context2.next = 23;
|
|
156
159
|
return _iterator2.next();
|
|
157
|
-
case
|
|
160
|
+
case 23:
|
|
158
161
|
if (!(_iteratorAbruptCompletion2 = !(_step2 = _context2.sent).done)) {
|
|
159
|
-
_context2.next =
|
|
162
|
+
_context2.next = 40;
|
|
160
163
|
break;
|
|
161
164
|
}
|
|
162
165
|
chunk = _step2.value;
|
|
163
|
-
if (!(((_currentQARef$
|
|
164
|
-
_context2.next =
|
|
166
|
+
if (!(((_currentQARef$current2 = currentQARef.current.response) === null || _currentQARef$current2 === void 0 ? void 0 : _currentQARef$current2.msgStatus) === 'interrupted')) {
|
|
167
|
+
_context2.next = 31;
|
|
165
168
|
break;
|
|
166
169
|
}
|
|
167
|
-
(_currentQARef$
|
|
170
|
+
(_currentQARef$current3 = currentQARef.current.abortController) === null || _currentQARef$current3 === void 0 || _currentQARef$current3.abort();
|
|
168
171
|
if (currentApiOptions.cancel) {
|
|
169
172
|
currentApiOptions.cancel({
|
|
170
173
|
session_id: getCurrentSessionId()
|
|
@@ -175,17 +178,17 @@ export default function useChatRequest(options) {
|
|
|
175
178
|
data: agentScopeRuntimeResponseBuilder.cancel()
|
|
176
179
|
}];
|
|
177
180
|
updateMessage(currentQARef.current.response);
|
|
178
|
-
return _context2.abrupt("break",
|
|
179
|
-
case
|
|
181
|
+
return _context2.abrupt("break", 40);
|
|
182
|
+
case 31:
|
|
180
183
|
responseParser = apiOptionsRef.current.responseParser || JSON.parse;
|
|
181
184
|
chunkData = responseParser(chunk.data);
|
|
182
185
|
_res = agentScopeRuntimeResponseBuilder.handle(chunkData);
|
|
183
186
|
if (!(_res.status !== AgentScopeRuntimeRunStatus.Failed && !((_res$output = _res.output) !== null && _res$output !== void 0 && (_res$output = _res$output[0]) !== null && _res$output !== void 0 && (_res$output = _res$output.content) !== null && _res$output !== void 0 && _res$output.length))) {
|
|
184
|
-
_context2.next =
|
|
187
|
+
_context2.next = 36;
|
|
185
188
|
break;
|
|
186
189
|
}
|
|
187
|
-
return _context2.abrupt("continue",
|
|
188
|
-
case
|
|
190
|
+
return _context2.abrupt("continue", 37);
|
|
191
|
+
case 36:
|
|
189
192
|
if (currentQARef.current.response) {
|
|
190
193
|
currentQARef.current.response.cards = [{
|
|
191
194
|
code: 'AgentScopeRuntimeResponseCard',
|
|
@@ -197,50 +200,63 @@ export default function useChatRequest(options) {
|
|
|
197
200
|
updateMessage(currentQARef.current.response);
|
|
198
201
|
}
|
|
199
202
|
}
|
|
200
|
-
case
|
|
203
|
+
case 37:
|
|
201
204
|
_iteratorAbruptCompletion2 = false;
|
|
202
|
-
_context2.next =
|
|
205
|
+
_context2.next = 21;
|
|
203
206
|
break;
|
|
204
|
-
case
|
|
205
|
-
_context2.next =
|
|
207
|
+
case 40:
|
|
208
|
+
_context2.next = 46;
|
|
206
209
|
break;
|
|
207
|
-
case
|
|
208
|
-
_context2.prev =
|
|
209
|
-
_context2.t1 = _context2["catch"](
|
|
210
|
+
case 42:
|
|
211
|
+
_context2.prev = 42;
|
|
212
|
+
_context2.t1 = _context2["catch"](19);
|
|
210
213
|
_didIteratorError2 = true;
|
|
211
214
|
_iteratorError2 = _context2.t1;
|
|
212
|
-
case
|
|
213
|
-
_context2.prev = 45;
|
|
215
|
+
case 46:
|
|
214
216
|
_context2.prev = 46;
|
|
217
|
+
_context2.prev = 47;
|
|
215
218
|
if (!(_iteratorAbruptCompletion2 && _iterator2.return != null)) {
|
|
216
|
-
_context2.next =
|
|
219
|
+
_context2.next = 51;
|
|
217
220
|
break;
|
|
218
221
|
}
|
|
219
|
-
_context2.next =
|
|
222
|
+
_context2.next = 51;
|
|
220
223
|
return _iterator2.return();
|
|
221
|
-
case
|
|
222
|
-
_context2.prev =
|
|
224
|
+
case 51:
|
|
225
|
+
_context2.prev = 51;
|
|
223
226
|
if (!_didIteratorError2) {
|
|
224
|
-
_context2.next =
|
|
227
|
+
_context2.next = 54;
|
|
225
228
|
break;
|
|
226
229
|
}
|
|
227
230
|
throw _iteratorError2;
|
|
228
|
-
case 53:
|
|
229
|
-
return _context2.finish(50);
|
|
230
231
|
case 54:
|
|
231
|
-
return _context2.finish(
|
|
232
|
+
return _context2.finish(51);
|
|
232
233
|
case 55:
|
|
233
|
-
_context2.
|
|
234
|
+
return _context2.finish(46);
|
|
235
|
+
case 56:
|
|
236
|
+
_context2.next = 61;
|
|
234
237
|
break;
|
|
235
|
-
case
|
|
236
|
-
_context2.prev =
|
|
237
|
-
_context2.t2 = _context2["catch"](
|
|
238
|
-
|
|
239
|
-
|
|
238
|
+
case 58:
|
|
239
|
+
_context2.prev = 58;
|
|
240
|
+
_context2.t2 = _context2["catch"](16);
|
|
241
|
+
if (((_currentQARef$current4 = currentQARef.current.response) === null || _currentQARef$current4 === void 0 ? void 0 : _currentQARef$current4.msgStatus) === 'interrupted') {
|
|
242
|
+
if (currentApiOptions.cancel) {
|
|
243
|
+
currentApiOptions.cancel({
|
|
244
|
+
session_id: getCurrentSessionId()
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
currentQARef.current.response.cards = [{
|
|
248
|
+
code: 'AgentScopeRuntimeResponseCard',
|
|
249
|
+
data: agentScopeRuntimeResponseBuilder.cancel()
|
|
250
|
+
}];
|
|
251
|
+
updateMessage(currentQARef.current.response);
|
|
252
|
+
} else {
|
|
253
|
+
console.error(_context2.t2);
|
|
254
|
+
}
|
|
255
|
+
case 61:
|
|
240
256
|
case "end":
|
|
241
257
|
return _context2.stop();
|
|
242
258
|
}
|
|
243
|
-
}, _callee2, null, [[3, 11], [
|
|
259
|
+
}, _callee2, null, [[3, 11], [16, 58], [19, 42, 46, 56], [47,, 51, 55]]);
|
|
244
260
|
}));
|
|
245
261
|
return function (_x2) {
|
|
246
262
|
return _ref2.apply(this, arguments);
|
|
@@ -248,14 +264,14 @@ export default function useChatRequest(options) {
|
|
|
248
264
|
}(), [getCurrentSessionId, currentQARef, updateMessage, onFinish]);
|
|
249
265
|
var request = useCallback( /*#__PURE__*/function () {
|
|
250
266
|
var _ref3 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee3(historyMessages, biz_params) {
|
|
251
|
-
var _currentQARef$
|
|
267
|
+
var _currentQARef$current5;
|
|
252
268
|
var currentApiOptions, _currentApiOptions$en, enableHistoryMessages, abortSignal, response;
|
|
253
269
|
return _regeneratorRuntime().wrap(function _callee3$(_context3) {
|
|
254
270
|
while (1) switch (_context3.prev = _context3.next) {
|
|
255
271
|
case 0:
|
|
256
272
|
currentApiOptions = apiOptionsRef.current;
|
|
257
273
|
_currentApiOptions$en = currentApiOptions.enableHistoryMessages, enableHistoryMessages = _currentApiOptions$en === void 0 ? false : _currentApiOptions$en;
|
|
258
|
-
abortSignal = (_currentQARef$
|
|
274
|
+
abortSignal = (_currentQARef$current5 = currentQARef.current.abortController) === null || _currentQARef$current5 === void 0 ? void 0 : _currentQARef$current5.signal;
|
|
259
275
|
_context3.prev = 3;
|
|
260
276
|
if (!currentApiOptions.fetch) {
|
|
261
277
|
_context3.next = 10;
|
|
@@ -315,7 +331,7 @@ export default function useChatRequest(options) {
|
|
|
315
331
|
}(), [getCurrentSessionId, currentQARef, processSSEResponse]);
|
|
316
332
|
var reconnect = useCallback( /*#__PURE__*/function () {
|
|
317
333
|
var _ref4 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee4(sessionId) {
|
|
318
|
-
var _currentQARef$
|
|
334
|
+
var _currentQARef$current6;
|
|
319
335
|
var currentApiOptions, abortSignal, response;
|
|
320
336
|
return _regeneratorRuntime().wrap(function _callee4$(_context4) {
|
|
321
337
|
while (1) switch (_context4.prev = _context4.next) {
|
|
@@ -327,7 +343,7 @@ export default function useChatRequest(options) {
|
|
|
327
343
|
}
|
|
328
344
|
return _context4.abrupt("return");
|
|
329
345
|
case 3:
|
|
330
|
-
abortSignal = (_currentQARef$
|
|
346
|
+
abortSignal = (_currentQARef$current6 = currentQARef.current.abortController) === null || _currentQARef$current6 === void 0 ? void 0 : _currentQARef$current6.signal;
|
|
331
347
|
_context4.prev = 4;
|
|
332
348
|
_context4.next = 7;
|
|
333
349
|
return currentApiOptions.reconnect({
|
|
@@ -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 _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; }
|
|
3
|
+
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); } }
|
|
4
|
+
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); }); }; }
|
|
1
5
|
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
|
|
2
6
|
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
7
|
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
|
|
@@ -8,7 +12,6 @@ import { CodeHighlighter, Mermaid } from '@ant-design/x';
|
|
|
8
12
|
import { useProviderContext } from "../../..";
|
|
9
13
|
import { useCallback, useRef, useState } from 'react';
|
|
10
14
|
import { SparkCopyLine, SparkDownloadLine, SparkTrueLine } from '@agentscope-ai/icons';
|
|
11
|
-
import { copy } from "../../../Util/copy";
|
|
12
15
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
13
16
|
import { jsxs as _jsxs } from "react/jsx-runtime";
|
|
14
17
|
var LANG_EXT_MAP = {
|
|
@@ -75,17 +78,46 @@ function CodeHeader(_ref) {
|
|
|
75
78
|
a.click();
|
|
76
79
|
URL.revokeObjectURL(url);
|
|
77
80
|
}, [lang, content]);
|
|
78
|
-
var handleCopy = useCallback(function () {
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
81
|
+
var handleCopy = useCallback( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee() {
|
|
82
|
+
var textarea;
|
|
83
|
+
return _regeneratorRuntime().wrap(function _callee$(_context) {
|
|
84
|
+
while (1) switch (_context.prev = _context.next) {
|
|
85
|
+
case 0:
|
|
86
|
+
_context.prev = 0;
|
|
87
|
+
if (!(window.isSecureContext && navigator.clipboard)) {
|
|
88
|
+
_context.next = 6;
|
|
89
|
+
break;
|
|
90
|
+
}
|
|
91
|
+
_context.next = 4;
|
|
92
|
+
return navigator.clipboard.writeText(content);
|
|
93
|
+
case 4:
|
|
94
|
+
_context.next = 13;
|
|
95
|
+
break;
|
|
96
|
+
case 6:
|
|
97
|
+
textarea = document.createElement('textarea');
|
|
98
|
+
textarea.value = content;
|
|
99
|
+
textarea.style.cssText = 'position:fixed;left:-9999px';
|
|
100
|
+
document.body.appendChild(textarea);
|
|
101
|
+
textarea.select();
|
|
102
|
+
document.execCommand('copy');
|
|
103
|
+
document.body.removeChild(textarea);
|
|
104
|
+
case 13:
|
|
105
|
+
setCopied(true);
|
|
106
|
+
setTimeout(function () {
|
|
107
|
+
return setCopied(false);
|
|
108
|
+
}, 1000);
|
|
109
|
+
_context.next = 20;
|
|
110
|
+
break;
|
|
111
|
+
case 17:
|
|
112
|
+
_context.prev = 17;
|
|
113
|
+
_context.t0 = _context["catch"](0);
|
|
114
|
+
console.warn('Copy failed');
|
|
115
|
+
case 20:
|
|
116
|
+
case "end":
|
|
117
|
+
return _context.stop();
|
|
118
|
+
}
|
|
119
|
+
}, _callee, null, [[0, 17]]);
|
|
120
|
+
})), [content]);
|
|
89
121
|
return /*#__PURE__*/_jsxs("div", {
|
|
90
122
|
className: prefixCls,
|
|
91
123
|
children: [/*#__PURE__*/_jsx("div", {
|
package/lib/Stream/index.d.ts
CHANGED
|
@@ -24,6 +24,11 @@ export interface StreamOptions<Output> {
|
|
|
24
24
|
* @link https://developer.mozilla.org/en-US/docs/Web/API/TransformStream
|
|
25
25
|
*/
|
|
26
26
|
transformStream?: TransformStream<string, Output>;
|
|
27
|
+
/**
|
|
28
|
+
* @description 用于中断流读取的 AbortSignal
|
|
29
|
+
* @descriptionEn AbortSignal to cancel stream reading
|
|
30
|
+
*/
|
|
31
|
+
signal?: AbortSignal;
|
|
27
32
|
}
|
|
28
33
|
type XReadableStream<R = SSEOutput> = ReadableStream<R> & AsyncGenerator<R>;
|
|
29
34
|
/**
|
package/lib/Stream/index.js
CHANGED
|
@@ -132,7 +132,8 @@ function splitPart() {
|
|
|
132
132
|
*/
|
|
133
133
|
function Stream(options, config) {
|
|
134
134
|
var readableStream = options.readableStream,
|
|
135
|
-
transformStream = options.transformStream
|
|
135
|
+
transformStream = options.transformStream,
|
|
136
|
+
signal = options.signal;
|
|
136
137
|
if (!(readableStream instanceof ReadableStream)) {
|
|
137
138
|
throw new Error('The options.readableStream must be an instance of ReadableStream.');
|
|
138
139
|
}
|
|
@@ -151,46 +152,65 @@ function Stream(options, config) {
|
|
|
151
152
|
|
|
152
153
|
/** support async iterator */
|
|
153
154
|
stream[Symbol.asyncIterator] = /*#__PURE__*/_wrapAsyncGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee() {
|
|
154
|
-
var reader, _yield$_awaitAsyncGen, done, value;
|
|
155
|
+
var reader, readPromise, _yield$_awaitAsyncGen, done, value;
|
|
155
156
|
return _regeneratorRuntime().wrap(function _callee$(_context) {
|
|
156
157
|
while (1) switch (_context.prev = _context.next) {
|
|
157
158
|
case 0:
|
|
158
159
|
reader = this.getReader();
|
|
159
|
-
|
|
160
|
+
_context.prev = 1;
|
|
161
|
+
case 2:
|
|
160
162
|
if (!true) {
|
|
161
|
-
_context.next =
|
|
163
|
+
_context.next = 18;
|
|
162
164
|
break;
|
|
163
165
|
}
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
166
|
+
readPromise = reader.read();
|
|
167
|
+
if (signal) {
|
|
168
|
+
readPromise = Promise.race([readPromise, new Promise(function (_, reject) {
|
|
169
|
+
if (signal.aborted) {
|
|
170
|
+
reject(new DOMException('The operation was aborted.', 'AbortError'));
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
signal.addEventListener('abort', function () {
|
|
174
|
+
reject(new DOMException('The operation was aborted.', 'AbortError'));
|
|
175
|
+
}, {
|
|
176
|
+
once: true
|
|
177
|
+
});
|
|
178
|
+
})]);
|
|
179
|
+
}
|
|
180
|
+
_context.next = 7;
|
|
181
|
+
return _awaitAsyncGenerator(readPromise);
|
|
182
|
+
case 7:
|
|
167
183
|
_yield$_awaitAsyncGen = _context.sent;
|
|
168
184
|
done = _yield$_awaitAsyncGen.done;
|
|
169
185
|
value = _yield$_awaitAsyncGen.value;
|
|
170
186
|
if (!done) {
|
|
171
|
-
_context.next =
|
|
187
|
+
_context.next = 12;
|
|
172
188
|
break;
|
|
173
189
|
}
|
|
174
|
-
return _context.abrupt("break",
|
|
175
|
-
case
|
|
190
|
+
return _context.abrupt("break", 18);
|
|
191
|
+
case 12:
|
|
176
192
|
if (value) {
|
|
177
|
-
_context.next =
|
|
193
|
+
_context.next = 14;
|
|
178
194
|
break;
|
|
179
195
|
}
|
|
180
|
-
return _context.abrupt("continue",
|
|
181
|
-
case
|
|
182
|
-
_context.next =
|
|
196
|
+
return _context.abrupt("continue", 2);
|
|
197
|
+
case 14:
|
|
198
|
+
_context.next = 16;
|
|
183
199
|
return config !== null && config !== void 0 && config.openaiCompatible ? _objectSpread(_objectSpread({}, value), {}, {
|
|
184
200
|
data: value.data.slice(1)
|
|
185
201
|
}) : value;
|
|
186
|
-
case
|
|
187
|
-
_context.next =
|
|
202
|
+
case 16:
|
|
203
|
+
_context.next = 2;
|
|
188
204
|
break;
|
|
189
|
-
case
|
|
205
|
+
case 18:
|
|
206
|
+
_context.prev = 18;
|
|
207
|
+
reader.releaseLock();
|
|
208
|
+
return _context.finish(18);
|
|
209
|
+
case 21:
|
|
190
210
|
case "end":
|
|
191
211
|
return _context.stop();
|
|
192
212
|
}
|
|
193
|
-
}, _callee, this);
|
|
213
|
+
}, _callee, this, [[1,, 18, 21]]);
|
|
194
214
|
}));
|
|
195
215
|
return stream;
|
|
196
216
|
}
|
package/package.json
CHANGED
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
# agentscope-runtime-starter-webui
|
|
2
|
-
|
|
3
|
-
## node version
|
|
4
|
-
|
|
5
|
-
> =22
|
|
6
|
-
|
|
7
|
-
## install
|
|
8
|
-
|
|
9
|
-
```
|
|
10
|
-
$ npm run install
|
|
11
|
-
```
|
|
12
|
-
|
|
13
|
-
## dev
|
|
14
|
-
|
|
15
|
-
```
|
|
16
|
-
$ npm run dev
|
|
17
|
-
```
|
|
18
|
-
|
|
19
|
-
## build
|
|
20
|
-
|
|
21
|
-
```
|
|
22
|
-
$ npm run build
|
|
23
|
-
```
|
|
24
|
-
|
|
25
|
-
## Core Code
|
|
26
|
-
```tsx
|
|
27
|
-
import { AgentScopeRuntimeWebUI } from '@agentscope-ai/chat';
|
|
28
|
-
|
|
29
|
-
const options = {
|
|
30
|
-
theme: {
|
|
31
|
-
colorPrimary: '#615CED',
|
|
32
|
-
darkMode: true,
|
|
33
|
-
prefix: 'agentscope-runtime-webui',
|
|
34
|
-
leftHeader: {
|
|
35
|
-
logo: 'https://img.alicdn.com/imgextra/i2/O1CN01lmoGYn1kjoXATy4PX_!!6000000004720-2-tps-200-200.png',
|
|
36
|
-
title: 'Runtime WebUI',
|
|
37
|
-
},
|
|
38
|
-
},
|
|
39
|
-
sender: {
|
|
40
|
-
maxLength: 10000,
|
|
41
|
-
disclaimer:
|
|
42
|
-
'AI can also make mistakes, so please check carefully and use it with caution',
|
|
43
|
-
},
|
|
44
|
-
|
|
45
|
-
welcome: {
|
|
46
|
-
greeting: 'Hello, how can I help you today?',
|
|
47
|
-
description:
|
|
48
|
-
'I am a helpful assistant that can help you with your questions.',
|
|
49
|
-
avatar:
|
|
50
|
-
'https://img.alicdn.com/imgextra/i2/O1CN01lmoGYn1kjoXATy4PX_!!6000000004720-2-tps-200-200.png',
|
|
51
|
-
prompts: [
|
|
52
|
-
{
|
|
53
|
-
value: 'Hello',
|
|
54
|
-
},
|
|
55
|
-
{
|
|
56
|
-
value: 'How are you?',
|
|
57
|
-
},
|
|
58
|
-
{
|
|
59
|
-
value: 'What can you do?',
|
|
60
|
-
},
|
|
61
|
-
],
|
|
62
|
-
},
|
|
63
|
-
api: {
|
|
64
|
-
baseURL: 'YOUR_API_URL',
|
|
65
|
-
token: 'YOUR_API_TOKEN', // is not required
|
|
66
|
-
},
|
|
67
|
-
};
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
<AgentScopeRuntimeWebUI
|
|
71
|
-
options={options}
|
|
72
|
-
/>
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
```
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import js from '@eslint/js'
|
|
2
|
-
import globals from 'globals'
|
|
3
|
-
import reactHooks from 'eslint-plugin-react-hooks'
|
|
4
|
-
import reactRefresh from 'eslint-plugin-react-refresh'
|
|
5
|
-
import tseslint from 'typescript-eslint'
|
|
6
|
-
|
|
7
|
-
export default tseslint.config(
|
|
8
|
-
{ ignores: ['dist'] },
|
|
9
|
-
{
|
|
10
|
-
extends: [js.configs.recommended, ...tseslint.configs.recommended],
|
|
11
|
-
files: ['**/*.{ts,tsx}'],
|
|
12
|
-
languageOptions: {
|
|
13
|
-
ecmaVersion: 2020,
|
|
14
|
-
globals: globals.browser,
|
|
15
|
-
},
|
|
16
|
-
plugins: {
|
|
17
|
-
'react-hooks': reactHooks,
|
|
18
|
-
'react-refresh': reactRefresh,
|
|
19
|
-
},
|
|
20
|
-
rules: {
|
|
21
|
-
...reactHooks.configs.recommended.rules,
|
|
22
|
-
'react-refresh/only-export-components': [
|
|
23
|
-
'warn',
|
|
24
|
-
{ allowConstantExport: true },
|
|
25
|
-
],
|
|
26
|
-
},
|
|
27
|
-
},
|
|
28
|
-
)
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
<!doctype html>
|
|
2
|
-
<html lang="en">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="UTF-8" />
|
|
5
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
-
<title>AgentScope Runtime Starter WebUI</title>
|
|
7
|
-
</head>
|
|
8
|
-
<body>
|
|
9
|
-
<div id="root"></div>
|
|
10
|
-
<script type="module" src="/src/main.tsx"></script>
|
|
11
|
-
</body>
|
|
12
|
-
</html>
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "agentscope-runtime-starter-webui",
|
|
3
|
-
"private": true,
|
|
4
|
-
"version": "0.0.0",
|
|
5
|
-
"type": "module",
|
|
6
|
-
"scripts": {
|
|
7
|
-
"dev": "vite --host",
|
|
8
|
-
"build": "tsc -b && vite build",
|
|
9
|
-
"lint": "eslint .",
|
|
10
|
-
"preview": "vite preview"
|
|
11
|
-
},
|
|
12
|
-
"dependencies": {
|
|
13
|
-
"@agentscope-ai/icons": "^1.0.46",
|
|
14
|
-
"@agentscope-ai/chat": "^1.1.44",
|
|
15
|
-
"@agentscope-ai/design": "^1.0.19",
|
|
16
|
-
"antd": "^5.29.1",
|
|
17
|
-
"antd-style": "^3.7.1",
|
|
18
|
-
"react": "^18",
|
|
19
|
-
"react-dom": "^18"
|
|
20
|
-
},
|
|
21
|
-
"devDependencies": {
|
|
22
|
-
"@eslint/js": "^9.25.0",
|
|
23
|
-
"@types/react": "^18",
|
|
24
|
-
"@types/react-dom": "^18",
|
|
25
|
-
"@vitejs/plugin-react": "^4.4.1",
|
|
26
|
-
"eslint": "^9.25.0",
|
|
27
|
-
"eslint-plugin-react-hooks": "^5.2.0",
|
|
28
|
-
"eslint-plugin-react-refresh": "^0.4.19",
|
|
29
|
-
"globals": "^16.0.0",
|
|
30
|
-
"typescript": "~5.8.3",
|
|
31
|
-
"typescript-eslint": "^8.30.1",
|
|
32
|
-
"vite": "^6.3.5"
|
|
33
|
-
}
|
|
34
|
-
}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import Chat from './components/Chat';
|
|
2
|
-
|
|
3
|
-
import { createGlobalStyle } from 'antd-style';
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
const GlobalStyle = createGlobalStyle`
|
|
7
|
-
* {
|
|
8
|
-
margin: 0;
|
|
9
|
-
box-sizing: border-box;
|
|
10
|
-
}
|
|
11
|
-
`;
|
|
12
|
-
|
|
13
|
-
function App() {
|
|
14
|
-
return <>
|
|
15
|
-
<GlobalStyle />
|
|
16
|
-
<Chat />
|
|
17
|
-
</>
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export default App
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import { Form } from 'antd';
|
|
2
|
-
import { createStyles } from 'antd-style';
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
interface FormItemProps {
|
|
6
|
-
name: string | string[];
|
|
7
|
-
label: string;
|
|
8
|
-
isList?: boolean;
|
|
9
|
-
children: any;
|
|
10
|
-
normalize?: (value: any) => any;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
const useStyles = createStyles(({ token }) => ({
|
|
15
|
-
label: {
|
|
16
|
-
marginBottom: 6,
|
|
17
|
-
fontSize: 12,
|
|
18
|
-
color: token.colorTextSecondary,
|
|
19
|
-
},
|
|
20
|
-
|
|
21
|
-
}));
|
|
22
|
-
|
|
23
|
-
export default function FormItem(props: FormItemProps) {
|
|
24
|
-
const { styles } = useStyles();
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
const node = props.isList ?
|
|
28
|
-
<Form.List name={props.name}>{props.children}</Form.List> :
|
|
29
|
-
<Form.Item name={props.name} normalize={props.normalize}>{props.children}</Form.Item>;
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
return <div>
|
|
33
|
-
{props.label && <div className={styles.label}>{props.label}</div>}
|
|
34
|
-
{node}
|
|
35
|
-
</div>
|
|
36
|
-
|
|
37
|
-
}
|
|
@@ -1,160 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { Form, Input, ColorPicker, Flex, Divider, InputNumber } from 'antd';
|
|
3
|
-
import { createStyles } from 'antd-style';
|
|
4
|
-
import { Button, IconButton, Switch } from '@agentscope-ai/design'
|
|
5
|
-
import { SparkDeleteLine, SparkPlusLine } from '@agentscope-ai/icons';
|
|
6
|
-
import FormItem from './FormItem';
|
|
7
|
-
import defaultConfig from './defaultConfig';
|
|
8
|
-
|
|
9
|
-
const useStyles = createStyles(({ token }) => ({
|
|
10
|
-
container: {
|
|
11
|
-
height: '100%',
|
|
12
|
-
display: 'flex',
|
|
13
|
-
flexDirection: 'column',
|
|
14
|
-
},
|
|
15
|
-
|
|
16
|
-
form: {
|
|
17
|
-
height: 0,
|
|
18
|
-
flex: 1,
|
|
19
|
-
padding: '8px 16px 16px 16px',
|
|
20
|
-
overflow: 'auto',
|
|
21
|
-
},
|
|
22
|
-
actions: {
|
|
23
|
-
padding: 16,
|
|
24
|
-
display: 'flex',
|
|
25
|
-
borderTop: `1px solid ${token.colorBorderSecondary}`,
|
|
26
|
-
justifyContent: 'flex-end',
|
|
27
|
-
gap: 16,
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
}));
|
|
31
|
-
|
|
32
|
-
interface OptionsEditorProps {
|
|
33
|
-
value?: any;
|
|
34
|
-
onChange?: any;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
const OptionsEditor: React.FC<OptionsEditorProps> = ({
|
|
38
|
-
value,
|
|
39
|
-
onChange,
|
|
40
|
-
}) => {
|
|
41
|
-
const { styles } = useStyles();
|
|
42
|
-
const [form] = Form.useForm();
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
const handleSave = () => {
|
|
46
|
-
form.validateFields().then((values) => {
|
|
47
|
-
onChange(values);
|
|
48
|
-
});
|
|
49
|
-
};
|
|
50
|
-
|
|
51
|
-
const handleReset = () => {
|
|
52
|
-
form.setFieldsValue(defaultConfig);
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
return (
|
|
56
|
-
<div className={styles.container}>
|
|
57
|
-
<Form
|
|
58
|
-
className={styles.form}
|
|
59
|
-
form={form}
|
|
60
|
-
layout="vertical"
|
|
61
|
-
initialValues={value}
|
|
62
|
-
>
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
<Divider orientation="left">Theme</Divider>
|
|
66
|
-
|
|
67
|
-
<FormItem name={['theme', 'colorPrimary']} label="colorPrimary" normalize={value => value.toHexString()}>
|
|
68
|
-
<ColorPicker />
|
|
69
|
-
</FormItem>
|
|
70
|
-
|
|
71
|
-
<FormItem name={['theme', 'colorBgBase']} label="colorBgBase" normalize={value => value.toHexString()}>
|
|
72
|
-
<ColorPicker />
|
|
73
|
-
</FormItem>
|
|
74
|
-
|
|
75
|
-
<FormItem name={['theme', 'colorTextBase']} label="colorTextBase" normalize={value => value.toHexString()}>
|
|
76
|
-
<ColorPicker />
|
|
77
|
-
</FormItem>
|
|
78
|
-
|
|
79
|
-
<FormItem name={['theme', 'darkMode']} label="darkMode" >
|
|
80
|
-
<Switch />
|
|
81
|
-
</FormItem>
|
|
82
|
-
|
|
83
|
-
<FormItem name={['theme', 'leftHeader', 'logo']} label="leftHeader.logo" >
|
|
84
|
-
<Input />
|
|
85
|
-
</FormItem>
|
|
86
|
-
|
|
87
|
-
<FormItem name={['theme', 'leftHeader', 'title']} label="leftHeader.title" >
|
|
88
|
-
<Input />
|
|
89
|
-
</FormItem>
|
|
90
|
-
|
|
91
|
-
<Divider orientation="left">Sender</Divider>
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
<FormItem name={['sender', 'disclaimer']} label="disclaimer" >
|
|
95
|
-
<Input />
|
|
96
|
-
</FormItem>
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
<FormItem name={['sender', 'maxLength']} label="maxLength" >
|
|
102
|
-
<InputNumber min={1000} />
|
|
103
|
-
</FormItem>
|
|
104
|
-
|
|
105
|
-
<Divider orientation="left">Welcome</Divider>
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
<FormItem name={['welcome', 'greeting']} label="greeting" >
|
|
109
|
-
<Input />
|
|
110
|
-
</FormItem>
|
|
111
|
-
|
|
112
|
-
<FormItem name={['welcome', 'description']} label="description" >
|
|
113
|
-
<Input />
|
|
114
|
-
</FormItem>
|
|
115
|
-
|
|
116
|
-
<FormItem name={['welcome', 'avatar']} label="avatar" >
|
|
117
|
-
<Input />
|
|
118
|
-
</FormItem>
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
<FormItem name={['welcome', 'prompts']} isList label="prompts" >
|
|
122
|
-
{(fields: { key: string, name: string }[], { add, remove }: { add: (item: any) => void, remove: (name: string) => void }) => {
|
|
123
|
-
return <div>
|
|
124
|
-
{fields.map(field => {
|
|
125
|
-
return <Flex key={field.key} gap={6}>
|
|
126
|
-
<Form.Item style={{ flex: 1 }} key={field.key} name={[field.name, 'value']}>
|
|
127
|
-
<Input />
|
|
128
|
-
</Form.Item>
|
|
129
|
-
<IconButton icon={<SparkPlusLine />} onClick={() => add({})}></IconButton>
|
|
130
|
-
<IconButton icon={<SparkDeleteLine />} onClick={() => remove(field.name)}></IconButton>
|
|
131
|
-
</Flex>
|
|
132
|
-
})}
|
|
133
|
-
</div>
|
|
134
|
-
}}
|
|
135
|
-
</FormItem>
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
<Divider orientation="left">API</Divider>
|
|
139
|
-
|
|
140
|
-
<FormItem name={['api', 'baseURL']} label="baseURL" >
|
|
141
|
-
<Input />
|
|
142
|
-
</FormItem>
|
|
143
|
-
|
|
144
|
-
<FormItem name={['api', 'token']} label="token" >
|
|
145
|
-
<Input />
|
|
146
|
-
</FormItem>
|
|
147
|
-
</Form>
|
|
148
|
-
|
|
149
|
-
<div className={styles.actions}>
|
|
150
|
-
<Button onClick={handleReset}>Reset</Button>
|
|
151
|
-
<Button type="primary" onClick={handleSave}>
|
|
152
|
-
Save & Copy
|
|
153
|
-
</Button>
|
|
154
|
-
</div>
|
|
155
|
-
</div>
|
|
156
|
-
);
|
|
157
|
-
};
|
|
158
|
-
|
|
159
|
-
export default OptionsEditor;
|
|
160
|
-
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
export default {
|
|
2
|
-
theme: {
|
|
3
|
-
colorPrimary: '#615CED',
|
|
4
|
-
darkMode: true,
|
|
5
|
-
prefix: 'agentscope-runtime-webui',
|
|
6
|
-
leftHeader: {
|
|
7
|
-
logo: 'https://img.alicdn.com/imgextra/i2/O1CN01lmoGYn1kjoXATy4PX_!!6000000004720-2-tps-200-200.png',
|
|
8
|
-
title: 'Runtime WebUI',
|
|
9
|
-
},
|
|
10
|
-
},
|
|
11
|
-
sender: {
|
|
12
|
-
attachments: false,
|
|
13
|
-
maxLength: 10000,
|
|
14
|
-
disclaimer:
|
|
15
|
-
'AI can also make mistakes, so please check carefully and use it with caution',
|
|
16
|
-
},
|
|
17
|
-
|
|
18
|
-
welcome: {
|
|
19
|
-
greeting: 'Hello, how can I help you today?',
|
|
20
|
-
description:
|
|
21
|
-
'I am a helpful assistant that can help you with your questions.',
|
|
22
|
-
avatar:
|
|
23
|
-
'https://img.alicdn.com/imgextra/i2/O1CN01lmoGYn1kjoXATy4PX_!!6000000004720-2-tps-200-200.png',
|
|
24
|
-
prompts: [
|
|
25
|
-
{
|
|
26
|
-
value: 'Hello',
|
|
27
|
-
},
|
|
28
|
-
{
|
|
29
|
-
value: 'How are you?',
|
|
30
|
-
},
|
|
31
|
-
{
|
|
32
|
-
value: 'What can you do?',
|
|
33
|
-
},
|
|
34
|
-
],
|
|
35
|
-
},
|
|
36
|
-
api: {
|
|
37
|
-
baseURL: BASE_URL,
|
|
38
|
-
token: TOKEN,
|
|
39
|
-
},
|
|
40
|
-
};
|
|
41
|
-
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import { SparkSettingLine } from "@agentscope-ai/icons";
|
|
2
|
-
import { IconButton, Drawer } from "@agentscope-ai/design";
|
|
3
|
-
import { useState } from "react";
|
|
4
|
-
import OptionsEditor from "./OptionsEditor";
|
|
5
|
-
|
|
6
|
-
interface OptionsPanelProps {
|
|
7
|
-
value?: any;
|
|
8
|
-
onChange?: any;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export default function OptionsPanel(props: OptionsPanelProps) {
|
|
12
|
-
const [open, setOpen] = useState(false);
|
|
13
|
-
|
|
14
|
-
return <>
|
|
15
|
-
<IconButton onClick={() => setOpen(true)} icon={<SparkSettingLine />} bordered={false} />
|
|
16
|
-
<Drawer
|
|
17
|
-
destroyOnHidden
|
|
18
|
-
open={open}
|
|
19
|
-
onClose={() => setOpen(false)}
|
|
20
|
-
styles={{ body: { padding: 0 }, header: { padding: 8 } }}>
|
|
21
|
-
<OptionsEditor value={props.value} onChange={(v: typeof props.value) => {
|
|
22
|
-
setOpen(false);
|
|
23
|
-
props.onChange(v);
|
|
24
|
-
}} />
|
|
25
|
-
</Drawer>
|
|
26
|
-
</>
|
|
27
|
-
}
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import { AgentScopeRuntimeWebUI, IAgentScopeRuntimeWebUIOptions } from '@agentscope-ai/chat';
|
|
2
|
-
import OptionsPanel from './OptionsPanel';
|
|
3
|
-
import { useMemo } from 'react';
|
|
4
|
-
import sessionApi from './sessionApi';
|
|
5
|
-
import { useLocalStorageState } from 'ahooks';
|
|
6
|
-
import defaultConfig from './OptionsPanel/defaultConfig';
|
|
7
|
-
|
|
8
|
-
export default function () {
|
|
9
|
-
const [optionsConfig, setOptionsConfig] = useLocalStorageState('agent-scope-runtime-webui-options', {
|
|
10
|
-
defaultValue: defaultConfig,
|
|
11
|
-
listenStorageChange: true,
|
|
12
|
-
});
|
|
13
|
-
|
|
14
|
-
const options = useMemo(() => {
|
|
15
|
-
const rightHeader = <OptionsPanel value={optionsConfig} onChange={(v: typeof optionsConfig) => {
|
|
16
|
-
setOptionsConfig(prev => ({
|
|
17
|
-
...prev,
|
|
18
|
-
...v,
|
|
19
|
-
}));
|
|
20
|
-
}} />;
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
return {
|
|
25
|
-
...optionsConfig,
|
|
26
|
-
session: {
|
|
27
|
-
multiple: true,
|
|
28
|
-
api: sessionApi,
|
|
29
|
-
},
|
|
30
|
-
theme: {
|
|
31
|
-
...optionsConfig.theme,
|
|
32
|
-
rightHeader,
|
|
33
|
-
},
|
|
34
|
-
};
|
|
35
|
-
}, [optionsConfig]);
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
return <div style={{ height: '100vh' }}>
|
|
41
|
-
<AgentScopeRuntimeWebUI
|
|
42
|
-
options={options as unknown as IAgentScopeRuntimeWebUIOptions}
|
|
43
|
-
/>
|
|
44
|
-
</div>;
|
|
45
|
-
}
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
IAgentScopeRuntimeWebUISession,
|
|
3
|
-
IAgentScopeRuntimeWebUISessionAPI,
|
|
4
|
-
} from '@agentscope-ai/chat';
|
|
5
|
-
|
|
6
|
-
class SessionApi implements IAgentScopeRuntimeWebUISessionAPI {
|
|
7
|
-
private lsKey: string;
|
|
8
|
-
private sessionList: IAgentScopeRuntimeWebUISession[];
|
|
9
|
-
|
|
10
|
-
constructor() {
|
|
11
|
-
this.lsKey = 'agent-scope-runtime-webui-sessions';
|
|
12
|
-
this.sessionList = [];
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
async getSessionList() {
|
|
16
|
-
this.sessionList = JSON.parse(localStorage.getItem(this.lsKey) || '[]');
|
|
17
|
-
return [...this.sessionList];
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
async getSession(sessionId: string) {
|
|
21
|
-
return this.sessionList.find((session) => session.id === sessionId) as IAgentScopeRuntimeWebUISession;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
async updateSession(session: Partial<IAgentScopeRuntimeWebUISession>) {
|
|
25
|
-
const index = this.sessionList.findIndex((item) => item.id === session.id);
|
|
26
|
-
if (index > -1) {
|
|
27
|
-
this.sessionList[index] = {
|
|
28
|
-
...this.sessionList[index],
|
|
29
|
-
...session,
|
|
30
|
-
};
|
|
31
|
-
localStorage.setItem(this.lsKey, JSON.stringify(this.sessionList));
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
return [...this.sessionList];
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
async createSession(session: Partial<IAgentScopeRuntimeWebUISession>) {
|
|
38
|
-
session.id = Date.now().toString();
|
|
39
|
-
this.sessionList.unshift(session as IAgentScopeRuntimeWebUISession);
|
|
40
|
-
localStorage.setItem(this.lsKey, JSON.stringify(this.sessionList));
|
|
41
|
-
return [...this.sessionList];
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
async removeSession(session: Partial<IAgentScopeRuntimeWebUISession>) {
|
|
45
|
-
this.sessionList = this.sessionList.filter(
|
|
46
|
-
(item) => item.id !== session.id,
|
|
47
|
-
);
|
|
48
|
-
localStorage.setItem(this.lsKey, JSON.stringify(this.sessionList));
|
|
49
|
-
return [...this.sessionList];
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
export default new SessionApi();
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
|
|
4
|
-
"target": "ES2020",
|
|
5
|
-
"useDefineForClassFields": true,
|
|
6
|
-
"lib": ["ES2020", "DOM", "DOM.Iterable"],
|
|
7
|
-
"module": "ESNext",
|
|
8
|
-
"skipLibCheck": true,
|
|
9
|
-
|
|
10
|
-
"moduleResolution": "bundler",
|
|
11
|
-
"allowImportingTsExtensions": true,
|
|
12
|
-
"moduleDetection": "force",
|
|
13
|
-
"noEmit": true,
|
|
14
|
-
"jsx": "react-jsx",
|
|
15
|
-
|
|
16
|
-
"strict": true,
|
|
17
|
-
"noUnusedLocals": true,
|
|
18
|
-
"noUnusedParameters": true,
|
|
19
|
-
"erasableSyntaxOnly": true,
|
|
20
|
-
"noFallthroughCasesInSwitch": true,
|
|
21
|
-
"noUncheckedSideEffectImports": true
|
|
22
|
-
},
|
|
23
|
-
"include": ["src"]
|
|
24
|
-
}
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
|
|
4
|
-
"target": "ES2022",
|
|
5
|
-
"lib": ["ES2023"],
|
|
6
|
-
"module": "ESNext",
|
|
7
|
-
"skipLibCheck": true,
|
|
8
|
-
|
|
9
|
-
"moduleResolution": "bundler",
|
|
10
|
-
"allowImportingTsExtensions": true,
|
|
11
|
-
"moduleDetection": "force",
|
|
12
|
-
"noEmit": true,
|
|
13
|
-
|
|
14
|
-
"strict": true,
|
|
15
|
-
"noUnusedLocals": true,
|
|
16
|
-
"noUnusedParameters": true,
|
|
17
|
-
"erasableSyntaxOnly": true,
|
|
18
|
-
"noFallthroughCasesInSwitch": true,
|
|
19
|
-
"noUncheckedSideEffectImports": true
|
|
20
|
-
},
|
|
21
|
-
"include": ["vite.config.ts"]
|
|
22
|
-
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { defineConfig } from 'vite'
|
|
2
|
-
import react from '@vitejs/plugin-react'
|
|
3
|
-
|
|
4
|
-
export default defineConfig({
|
|
5
|
-
define: {
|
|
6
|
-
BASE_URL: JSON.stringify(process.env.BASE_URL || ''),
|
|
7
|
-
TOKEN: JSON.stringify(process.env.TOKEN || ''),
|
|
8
|
-
MOBILE: false,
|
|
9
|
-
},
|
|
10
|
-
plugins: [react()],
|
|
11
|
-
})
|