my-ai-chat-framework 1.0.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/LICENSE +21 -0
- package/README.md +305 -0
- package/README_ZH.md +401 -0
- package/dist/my-ai-chat-framework.browser.es.js +2630 -0
- package/dist/my-ai-chat-framework.browser.es.js.map +1 -0
- package/dist/my-ai-chat-framework.browser.umd.js +2634 -0
- package/dist/my-ai-chat-framework.browser.umd.js.map +1 -0
- package/dist/my-ai-chat-framework.cjs.js +2630 -0
- package/dist/my-ai-chat-framework.cjs.js.map +1 -0
- package/dist/my-ai-chat-framework.es.js +2630 -0
- package/dist/my-ai-chat-framework.es.js.map +1 -0
- package/dist/my-ai-chat-framework.node.cjs.js +1381 -0
- package/dist/my-ai-chat-framework.node.cjs.js.map +1 -0
- package/dist/my-ai-chat-framework.umd.js +2634 -0
- package/dist/my-ai-chat-framework.umd.js.map +1 -0
- package/package.json +54 -0
- package/src/core/ApiClient.js +288 -0
- package/src/core/EventEmitter.js +126 -0
- package/src/core/MessageFormatter.js +126 -0
- package/src/core/Messages.js +562 -0
- package/src/core/RequestBuilder.js +96 -0
- package/src/core/ToolManager.js +175 -0
- package/src/index.js +419 -0
- package/src/utils/index.js +21 -0
|
@@ -0,0 +1,2634 @@
|
|
|
1
|
+
(function(global, factory) {
|
|
2
|
+
typeof exports === "object" && typeof module !== "undefined" ? factory(exports) : typeof define === "function" && define.amd ? define(["exports"], factory) : (global = typeof globalThis !== "undefined" ? globalThis : global || self, factory(global.AIChatFramework = {}));
|
|
3
|
+
})(this, (function(exports2) {
|
|
4
|
+
"use strict";
|
|
5
|
+
class MessageFormatter {
|
|
6
|
+
/**
|
|
7
|
+
* 将消息转换为标准格式(过滤掉自定义元数据)
|
|
8
|
+
*/
|
|
9
|
+
static toStandardFormat(message) {
|
|
10
|
+
const { role, content } = message;
|
|
11
|
+
const standardMessage = { role, content };
|
|
12
|
+
if (message.reasoning_content) {
|
|
13
|
+
standardMessage.reasoning_content = message.reasoning_content;
|
|
14
|
+
}
|
|
15
|
+
if (message.tool_calls) {
|
|
16
|
+
standardMessage.tool_calls = message.tool_calls;
|
|
17
|
+
}
|
|
18
|
+
if (message.tool_call_id) {
|
|
19
|
+
standardMessage.tool_call_id = message.tool_call_id;
|
|
20
|
+
}
|
|
21
|
+
return standardMessage;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* 批量转换消息为标准格式
|
|
25
|
+
*/
|
|
26
|
+
static batchToStandardFormat(messages) {
|
|
27
|
+
return messages.map((msg) => this.toStandardFormat(msg));
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* 从Messages实例获取格式化后的消息数组
|
|
31
|
+
*/
|
|
32
|
+
static formatMessages(messagesInstance, baseRounds, cycleRounds) {
|
|
33
|
+
const systems = messagesInstance.getEnabledSystemPrompts();
|
|
34
|
+
const hintSystem = {
|
|
35
|
+
role: "system",
|
|
36
|
+
content: `你的名字||标题是:${messagesInstance.getName() || "未知"}`
|
|
37
|
+
};
|
|
38
|
+
systems.unshift(hintSystem);
|
|
39
|
+
const recentMessages = messagesInstance.getRecentMessages(baseRounds, cycleRounds);
|
|
40
|
+
return [...systems, ...recentMessages];
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* 构造工具参数
|
|
44
|
+
*/
|
|
45
|
+
static constructParameters(array) {
|
|
46
|
+
let paramsArray = [];
|
|
47
|
+
if (Array.isArray(array)) {
|
|
48
|
+
paramsArray = array;
|
|
49
|
+
} else if (typeof array === "object" && array !== null) {
|
|
50
|
+
paramsArray = [array];
|
|
51
|
+
} else {
|
|
52
|
+
throw new Error("[系统提示异常] 检测到无效的参数格式");
|
|
53
|
+
}
|
|
54
|
+
const parameters = {};
|
|
55
|
+
for (let i = 0; i < paramsArray.length; i++) {
|
|
56
|
+
const param = paramsArray[i];
|
|
57
|
+
if (!param?.name?.trim()) {
|
|
58
|
+
throw new Error(`[系统提示异常] 检测到空参数名称 位置: 第 ${i + 1} 个参数`);
|
|
59
|
+
}
|
|
60
|
+
if (!param?.type?.trim()) {
|
|
61
|
+
throw new Error(`[系统提示异常] 检测到空参数类型 位置: 参数 "${param.name}"`);
|
|
62
|
+
}
|
|
63
|
+
if (!param?.description?.trim()) {
|
|
64
|
+
throw new Error(`[系统提示异常] 检测到空参数描述 位置: 参数 "${param.name}"`);
|
|
65
|
+
}
|
|
66
|
+
parameters[param.name] = {
|
|
67
|
+
type: param.type,
|
|
68
|
+
description: param.description
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
return {
|
|
72
|
+
type: "object",
|
|
73
|
+
properties: parameters,
|
|
74
|
+
required: Object.keys(parameters)
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* 构造工具定义
|
|
79
|
+
*/
|
|
80
|
+
static constructTool({ name, description, parameters }) {
|
|
81
|
+
if (!name?.trim()) {
|
|
82
|
+
throw new Error("[系统提示异常] 检测到空工具名称");
|
|
83
|
+
}
|
|
84
|
+
if (!description?.trim()) {
|
|
85
|
+
throw new Error("[系统提示异常] 检测到空工具描述");
|
|
86
|
+
}
|
|
87
|
+
let processedParameters;
|
|
88
|
+
try {
|
|
89
|
+
processedParameters = this.constructParameters(parameters);
|
|
90
|
+
} catch (error) {
|
|
91
|
+
throw new Error(`[系统提示异常] 工具参数验证失败 工具名称: ${name} 错误详情: ${error.message}`);
|
|
92
|
+
}
|
|
93
|
+
return {
|
|
94
|
+
type: "function",
|
|
95
|
+
function: {
|
|
96
|
+
name,
|
|
97
|
+
description,
|
|
98
|
+
parameters: processedParameters
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
class Messages {
|
|
104
|
+
constructor() {
|
|
105
|
+
this.messages = [];
|
|
106
|
+
this.systemPrompts = [];
|
|
107
|
+
this.tools = [];
|
|
108
|
+
this.metadata = {
|
|
109
|
+
name: "",
|
|
110
|
+
createdAt: /* @__PURE__ */ new Date(),
|
|
111
|
+
lastModified: /* @__PURE__ */ new Date()
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
// ========== 核心消息方法 ==========
|
|
115
|
+
/**
|
|
116
|
+
* 添加消息(通用方法)
|
|
117
|
+
* @param {string} role - 角色:user/assistant/system/tool
|
|
118
|
+
* @param {string} content - 消息内容
|
|
119
|
+
* @param {object} metadata - 额外元数据
|
|
120
|
+
* @returns {number} 新消息的索引
|
|
121
|
+
*/
|
|
122
|
+
addMessage(role, content, metadata = {}) {
|
|
123
|
+
const validRoles = ["user", "assistant", "system", "tool"];
|
|
124
|
+
if (!validRoles.includes(role)) {
|
|
125
|
+
throw new Error(`无效的角色: ${role},有效值: ${validRoles.join(", ")}`);
|
|
126
|
+
}
|
|
127
|
+
if (role === "tool") {
|
|
128
|
+
if (!metadata.tool_call_id) {
|
|
129
|
+
throw new Error("tool消息必须包含tool_call_id");
|
|
130
|
+
}
|
|
131
|
+
} else {
|
|
132
|
+
if (typeof content !== "string") {
|
|
133
|
+
throw new Error("消息内容必须是字符串");
|
|
134
|
+
}
|
|
135
|
+
if (content === void 0 || content === null) {
|
|
136
|
+
throw new Error("消息内容不能为undefined或null");
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
const message = {
|
|
140
|
+
role,
|
|
141
|
+
content: content ? content.trim() : "",
|
|
142
|
+
// 允许空字符串
|
|
143
|
+
timestamp: /* @__PURE__ */ new Date()
|
|
144
|
+
};
|
|
145
|
+
if (metadata && typeof metadata === "object") {
|
|
146
|
+
for (const [key, value] of Object.entries(metadata)) {
|
|
147
|
+
if (value !== void 0 && value !== null) {
|
|
148
|
+
message[key] = value;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
return this.messages.push(message) - 1;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* 添加用户消息(便捷方法)
|
|
156
|
+
*/
|
|
157
|
+
addUserMessage(content, metadata = {}) {
|
|
158
|
+
return this.addMessage("user", content, metadata);
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* 添加助手消息(便捷方法)
|
|
162
|
+
*/
|
|
163
|
+
addAssistantMessage(content, metadata = {}) {
|
|
164
|
+
return this.addMessage("assistant", content, metadata);
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* 添加系统消息(便捷方法)
|
|
168
|
+
*/
|
|
169
|
+
addSystemMessage(content, metadata = {}) {
|
|
170
|
+
return this.addMessage("system", content, metadata);
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* 添加工具消息(便捷方法)
|
|
174
|
+
*/
|
|
175
|
+
addToolMessage(content, toolCallId, metadata = {}) {
|
|
176
|
+
if (!toolCallId || typeof toolCallId !== "string") {
|
|
177
|
+
throw new Error("tool_call_id不能为空");
|
|
178
|
+
}
|
|
179
|
+
return this.addMessage("tool", content, {
|
|
180
|
+
tool_call_id: toolCallId,
|
|
181
|
+
...metadata
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* 批量添加消息
|
|
186
|
+
*/
|
|
187
|
+
addMessages(messagesArray) {
|
|
188
|
+
if (!Array.isArray(messagesArray)) {
|
|
189
|
+
throw new Error("参数必须是数组");
|
|
190
|
+
}
|
|
191
|
+
const indices = [];
|
|
192
|
+
for (const msg of messagesArray) {
|
|
193
|
+
if (!msg.role || !msg.content) {
|
|
194
|
+
throw new Error("消息必须包含role和content属性");
|
|
195
|
+
}
|
|
196
|
+
const { role, content, ...metadata } = msg;
|
|
197
|
+
const index2 = this.addMessage(role, content, metadata);
|
|
198
|
+
indices.push(index2);
|
|
199
|
+
}
|
|
200
|
+
return indices;
|
|
201
|
+
}
|
|
202
|
+
// ========== 消息查询 ==========
|
|
203
|
+
/**
|
|
204
|
+
* 获取所有消息
|
|
205
|
+
*/
|
|
206
|
+
getMessages() {
|
|
207
|
+
return [...this.messages];
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* 按角色获取消息
|
|
211
|
+
*/
|
|
212
|
+
getMessagesByRole(role) {
|
|
213
|
+
const validRoles = ["user", "assistant", "system", "tool"];
|
|
214
|
+
if (!validRoles.includes(role)) {
|
|
215
|
+
throw new Error(`无效的角色: ${role}`);
|
|
216
|
+
}
|
|
217
|
+
return this.messages.filter((msg) => msg.role === role);
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* 获取最后一条消息
|
|
221
|
+
*/
|
|
222
|
+
getLastMessage() {
|
|
223
|
+
return this.messages.length > 0 ? { ...this.messages[this.messages.length - 1] } : null;
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* 获取最后一条用户消息
|
|
227
|
+
*/
|
|
228
|
+
getLastUserMessage() {
|
|
229
|
+
for (let i = this.messages.length - 1; i >= 0; i--) {
|
|
230
|
+
if (this.messages[i].role === "user") {
|
|
231
|
+
return { ...this.messages[i] };
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
return null;
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* 获取最后一条助手消息
|
|
238
|
+
*/
|
|
239
|
+
getLastAssistantMessage() {
|
|
240
|
+
for (let i = this.messages.length - 1; i >= 0; i--) {
|
|
241
|
+
if (this.messages[i].role === "assistant") {
|
|
242
|
+
return { ...this.messages[i] };
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
return null;
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* 获取消息数量
|
|
249
|
+
*/
|
|
250
|
+
getMessageCount() {
|
|
251
|
+
return this.messages.length;
|
|
252
|
+
}
|
|
253
|
+
// ========== 消息修改 ==========
|
|
254
|
+
/**
|
|
255
|
+
* 更新消息内容
|
|
256
|
+
*/
|
|
257
|
+
updateMessage(index2, content) {
|
|
258
|
+
if (!Number.isInteger(index2) || index2 < 0 || index2 >= this.messages.length) {
|
|
259
|
+
throw new Error(`无效的消息索引: ${index2}`);
|
|
260
|
+
}
|
|
261
|
+
if (typeof content !== "string" || !content.trim()) {
|
|
262
|
+
throw new Error("消息内容不能为空");
|
|
263
|
+
}
|
|
264
|
+
this.messages[index2].content = content.trim();
|
|
265
|
+
this.messages[index2].lastModified = /* @__PURE__ */ new Date();
|
|
266
|
+
return this;
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* 更新最后一条消息
|
|
270
|
+
*/
|
|
271
|
+
updateLastMessage(content) {
|
|
272
|
+
if (this.messages.length === 0) {
|
|
273
|
+
throw new Error("没有消息可以修改");
|
|
274
|
+
}
|
|
275
|
+
return this.updateMessage(this.messages.length - 1, content);
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* 设置消息字段
|
|
279
|
+
*/
|
|
280
|
+
setMessageField(index2, field, value) {
|
|
281
|
+
if (!Number.isInteger(index2) || index2 < 0 || index2 >= this.messages.length) {
|
|
282
|
+
throw new Error(`无效的消息索引: ${index2}`);
|
|
283
|
+
}
|
|
284
|
+
this.messages[index2][field] = value;
|
|
285
|
+
this.messages[index2].lastModified = /* @__PURE__ */ new Date();
|
|
286
|
+
return this;
|
|
287
|
+
}
|
|
288
|
+
// ========== 消息删除 ==========
|
|
289
|
+
/**
|
|
290
|
+
* 删除消息
|
|
291
|
+
*/
|
|
292
|
+
removeMessage(index2) {
|
|
293
|
+
if (!Number.isInteger(index2) || index2 < 0 || index2 >= this.messages.length) {
|
|
294
|
+
throw new Error(`无效的消息索引: ${index2}`);
|
|
295
|
+
}
|
|
296
|
+
return this.messages.splice(index2, 1)[0];
|
|
297
|
+
}
|
|
298
|
+
/**
|
|
299
|
+
* 删除最后一条消息
|
|
300
|
+
*/
|
|
301
|
+
removeLastMessage() {
|
|
302
|
+
if (this.messages.length === 0) {
|
|
303
|
+
throw new Error("没有消息可以删除");
|
|
304
|
+
}
|
|
305
|
+
return this.removeMessage(this.messages.length - 1);
|
|
306
|
+
}
|
|
307
|
+
/**
|
|
308
|
+
* 撤回到上一条助手消息
|
|
309
|
+
*/
|
|
310
|
+
undoToAssistant() {
|
|
311
|
+
if (this.messages.length === 0) {
|
|
312
|
+
return [];
|
|
313
|
+
}
|
|
314
|
+
let lastAssistantIndex = -1;
|
|
315
|
+
for (let i = this.messages.length - 1; i >= 0; i--) {
|
|
316
|
+
if (this.messages[i].role === "assistant") {
|
|
317
|
+
lastAssistantIndex = i;
|
|
318
|
+
break;
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
if (lastAssistantIndex >= 0) {
|
|
322
|
+
return this.messages.splice(lastAssistantIndex + 1);
|
|
323
|
+
} else {
|
|
324
|
+
const removed = [...this.messages];
|
|
325
|
+
this.messages = [];
|
|
326
|
+
return removed;
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
/**
|
|
330
|
+
* 是否可以撤回
|
|
331
|
+
*/
|
|
332
|
+
canUndo() {
|
|
333
|
+
return this.messages.some((msg) => msg.role === "assistant");
|
|
334
|
+
}
|
|
335
|
+
/**
|
|
336
|
+
* 清空所有消息
|
|
337
|
+
*/
|
|
338
|
+
clearMessages() {
|
|
339
|
+
const removed = [...this.messages];
|
|
340
|
+
this.messages = [];
|
|
341
|
+
this.metadata.lastModified = /* @__PURE__ */ new Date();
|
|
342
|
+
return removed;
|
|
343
|
+
}
|
|
344
|
+
// ========== 系统提示管理 ==========
|
|
345
|
+
/**
|
|
346
|
+
* 添加系统提示
|
|
347
|
+
*/
|
|
348
|
+
addSystemPrompt(content, enabled = true) {
|
|
349
|
+
if (typeof content !== "string" || !content.trim()) {
|
|
350
|
+
throw new Error("系统提示内容不能为空");
|
|
351
|
+
}
|
|
352
|
+
const prompt = {
|
|
353
|
+
role: "system",
|
|
354
|
+
content: content.trim(),
|
|
355
|
+
enabled: Boolean(enabled),
|
|
356
|
+
createdAt: /* @__PURE__ */ new Date()
|
|
357
|
+
};
|
|
358
|
+
return this.systemPrompts.push(prompt) - 1;
|
|
359
|
+
}
|
|
360
|
+
/**
|
|
361
|
+
* 获取启用的系统提示
|
|
362
|
+
*/
|
|
363
|
+
getEnabledSystemPrompts() {
|
|
364
|
+
return this.systemPrompts.filter((prompt) => prompt.enabled).map((prompt) => ({ role: prompt.role, content: prompt.content }));
|
|
365
|
+
}
|
|
366
|
+
/**
|
|
367
|
+
* 切换系统提示状态
|
|
368
|
+
*/
|
|
369
|
+
toggleSystemPrompt(index2) {
|
|
370
|
+
if (!Number.isInteger(index2) || index2 < 0 || index2 >= this.systemPrompts.length) {
|
|
371
|
+
throw new Error(`无效的系统提示索引: ${index2}`);
|
|
372
|
+
}
|
|
373
|
+
this.systemPrompts[index2].enabled = !this.systemPrompts[index2].enabled;
|
|
374
|
+
return this;
|
|
375
|
+
}
|
|
376
|
+
/**
|
|
377
|
+
* 更新系统提示内容
|
|
378
|
+
*/
|
|
379
|
+
updateSystemPrompt(index2, content) {
|
|
380
|
+
if (!Number.isInteger(index2) || index2 < 0 || index2 >= this.systemPrompts.length) {
|
|
381
|
+
throw new Error(`无效的系统提示索引: ${index2}`);
|
|
382
|
+
}
|
|
383
|
+
if (typeof content !== "string" || !content.trim()) {
|
|
384
|
+
throw new Error("系统提示内容不能为空");
|
|
385
|
+
}
|
|
386
|
+
this.systemPrompts[index2].content = content.trim();
|
|
387
|
+
this.systemPrompts[index2].lastModified = /* @__PURE__ */ new Date();
|
|
388
|
+
return this;
|
|
389
|
+
}
|
|
390
|
+
/**
|
|
391
|
+
* 删除系统提示
|
|
392
|
+
*/
|
|
393
|
+
removeSystemPrompt(index2) {
|
|
394
|
+
if (!Number.isInteger(index2) || index2 < 0 || index2 >= this.systemPrompts.length) {
|
|
395
|
+
throw new Error(`无效的系统提示索引: ${index2}`);
|
|
396
|
+
}
|
|
397
|
+
return this.systemPrompts.splice(index2, 1)[0];
|
|
398
|
+
}
|
|
399
|
+
// ========== 工具管理 ==========
|
|
400
|
+
/**
|
|
401
|
+
* 添加工具
|
|
402
|
+
*/
|
|
403
|
+
addTool(toolDefinition) {
|
|
404
|
+
if (typeof toolDefinition === "object" && toolDefinition !== null) {
|
|
405
|
+
if (!toolDefinition.type || toolDefinition.type !== "function") {
|
|
406
|
+
throw new Error(`无效的工具类型,期望: 'function',实际: '${toolDefinition.type || "undefined"}'`);
|
|
407
|
+
}
|
|
408
|
+
if (!toolDefinition.function?.name?.trim()) {
|
|
409
|
+
throw new Error("工具名称不能为空");
|
|
410
|
+
}
|
|
411
|
+
return this.tools.push(toolDefinition) - 1;
|
|
412
|
+
}
|
|
413
|
+
if (toolDefinition.name && toolDefinition.description && toolDefinition.parameters) {
|
|
414
|
+
const constructedTool = MessageFormatter.constructTool(toolDefinition);
|
|
415
|
+
return this.tools.push(constructedTool) - 1;
|
|
416
|
+
}
|
|
417
|
+
throw new Error("无效的工具格式");
|
|
418
|
+
}
|
|
419
|
+
/**
|
|
420
|
+
* 从定义添加工具
|
|
421
|
+
*/
|
|
422
|
+
addToolFromDefinition(name, description, parameters) {
|
|
423
|
+
const tool = MessageFormatter.constructTool({ name, description, parameters });
|
|
424
|
+
return this.tools.push(tool) - 1;
|
|
425
|
+
}
|
|
426
|
+
/**
|
|
427
|
+
* 获取所有工具
|
|
428
|
+
*/
|
|
429
|
+
getTools() {
|
|
430
|
+
return [...this.tools];
|
|
431
|
+
}
|
|
432
|
+
/**
|
|
433
|
+
* 删除工具
|
|
434
|
+
*/
|
|
435
|
+
removeTool(index2) {
|
|
436
|
+
if (!Number.isInteger(index2) || index2 < 0 || index2 >= this.tools.length) {
|
|
437
|
+
throw new Error(`无效的工具索引: ${index2}`);
|
|
438
|
+
}
|
|
439
|
+
return this.tools.splice(index2, 1)[0];
|
|
440
|
+
}
|
|
441
|
+
/**
|
|
442
|
+
* 清空所有工具
|
|
443
|
+
*/
|
|
444
|
+
clearTools() {
|
|
445
|
+
const removed = [...this.tools];
|
|
446
|
+
this.tools = [];
|
|
447
|
+
return removed;
|
|
448
|
+
}
|
|
449
|
+
// ========== 元数据管理 ==========
|
|
450
|
+
setName(name) {
|
|
451
|
+
if (typeof name !== "string" || !name.trim()) {
|
|
452
|
+
throw new Error("名称不能为空");
|
|
453
|
+
}
|
|
454
|
+
this.metadata.name = name.trim();
|
|
455
|
+
this.metadata.lastModified = /* @__PURE__ */ new Date();
|
|
456
|
+
return this;
|
|
457
|
+
}
|
|
458
|
+
getName() {
|
|
459
|
+
return this.metadata.name;
|
|
460
|
+
}
|
|
461
|
+
// ========== 兼容性方法 ==========
|
|
462
|
+
/**
|
|
463
|
+
* 获取最近的消息(兼容旧方法)
|
|
464
|
+
*/
|
|
465
|
+
getRecentMessages(baseRounds, cycleRounds) {
|
|
466
|
+
const messages = this.messages.map((item) => {
|
|
467
|
+
return MessageFormatter.toStandardFormat(item);
|
|
468
|
+
});
|
|
469
|
+
const msgTotal = messages.length;
|
|
470
|
+
const totalRounds = msgTotal / 2;
|
|
471
|
+
if (!baseRounds || isNaN(baseRounds) || baseRounds <= 0) {
|
|
472
|
+
return messages;
|
|
473
|
+
}
|
|
474
|
+
const maxCycleRoundMultiple = cycleRounds > 0 ? Math.floor(totalRounds / cycleRounds) * cycleRounds : 0;
|
|
475
|
+
const actualRounds = baseRounds + (totalRounds - maxCycleRoundMultiple);
|
|
476
|
+
const actualMsgCount = actualRounds * 2;
|
|
477
|
+
const n = Math.max(msgTotal - actualMsgCount, 0);
|
|
478
|
+
return messages.slice(n);
|
|
479
|
+
}
|
|
480
|
+
/**
|
|
481
|
+
* 获取所有格式化消息(兼容旧方法)
|
|
482
|
+
*/
|
|
483
|
+
getMessagesFormatted(baseRounds, cycleRounds) {
|
|
484
|
+
const systems = this.getEnabledSystemPrompts();
|
|
485
|
+
const hintSystem = {
|
|
486
|
+
role: "system",
|
|
487
|
+
content: `你的名字||标题是:${this.metadata.name || "未知"}`
|
|
488
|
+
};
|
|
489
|
+
systems.unshift(hintSystem);
|
|
490
|
+
const recentMessages = this.getRecentMessages(baseRounds, cycleRounds);
|
|
491
|
+
return [...systems, ...recentMessages];
|
|
492
|
+
}
|
|
493
|
+
// ========== 导入导出 ==========
|
|
494
|
+
export() {
|
|
495
|
+
return {
|
|
496
|
+
__format_version: 2,
|
|
497
|
+
exportedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
498
|
+
metadata: { ...this.metadata },
|
|
499
|
+
payload: {
|
|
500
|
+
messages: JSON.parse(JSON.stringify(this.messages)),
|
|
501
|
+
systemPrompts: JSON.parse(JSON.stringify(this.systemPrompts)),
|
|
502
|
+
tools: JSON.parse(JSON.stringify(this.tools))
|
|
503
|
+
}
|
|
504
|
+
};
|
|
505
|
+
}
|
|
506
|
+
import(data) {
|
|
507
|
+
const obj = typeof data === "string" ? JSON.parse(data) : data;
|
|
508
|
+
const parsed = Messages.parseCompatible(obj);
|
|
509
|
+
this.messages = parsed.messages || [];
|
|
510
|
+
this.systemPrompts = parsed.systemPrompts || [];
|
|
511
|
+
this.tools = parsed.tools || [];
|
|
512
|
+
this.metadata = parsed.metadata || {
|
|
513
|
+
name: "",
|
|
514
|
+
createdAt: /* @__PURE__ */ new Date(),
|
|
515
|
+
lastModified: /* @__PURE__ */ new Date()
|
|
516
|
+
};
|
|
517
|
+
this.metadata.lastModified = /* @__PURE__ */ new Date();
|
|
518
|
+
return this;
|
|
519
|
+
}
|
|
520
|
+
static parseCompatible(obj) {
|
|
521
|
+
if (obj?.__format_version === 2 && obj.payload) {
|
|
522
|
+
return {
|
|
523
|
+
messages: obj.payload.messages || [],
|
|
524
|
+
systemPrompts: obj.payload.systemPrompts || [],
|
|
525
|
+
tools: obj.payload.tools || [],
|
|
526
|
+
metadata: obj.metadata || {
|
|
527
|
+
name: "",
|
|
528
|
+
createdAt: /* @__PURE__ */ new Date(),
|
|
529
|
+
lastModified: /* @__PURE__ */ new Date()
|
|
530
|
+
}
|
|
531
|
+
};
|
|
532
|
+
}
|
|
533
|
+
if (obj?.__format_version === 1 && obj.payload) {
|
|
534
|
+
return {
|
|
535
|
+
messages: obj.payload.messages || [],
|
|
536
|
+
systemPrompts: obj.payload.systems || [],
|
|
537
|
+
tools: obj.payload.tools || [],
|
|
538
|
+
metadata: {
|
|
539
|
+
name: obj.payload.hintData?.name || "",
|
|
540
|
+
createdAt: /* @__PURE__ */ new Date(),
|
|
541
|
+
lastModified: /* @__PURE__ */ new Date()
|
|
542
|
+
}
|
|
543
|
+
};
|
|
544
|
+
}
|
|
545
|
+
if (obj?.messages && Array.isArray(obj.messages)) {
|
|
546
|
+
return {
|
|
547
|
+
messages: obj.messages || [],
|
|
548
|
+
systemPrompts: obj.systems || [],
|
|
549
|
+
tools: obj.tools || [],
|
|
550
|
+
metadata: {
|
|
551
|
+
name: obj.hintData?.name || "",
|
|
552
|
+
createdAt: /* @__PURE__ */ new Date(),
|
|
553
|
+
lastModified: /* @__PURE__ */ new Date()
|
|
554
|
+
}
|
|
555
|
+
};
|
|
556
|
+
}
|
|
557
|
+
throw new Error("无法识别的聊天数据格式");
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
class EventEmitter {
|
|
561
|
+
constructor() {
|
|
562
|
+
this.events = {};
|
|
563
|
+
}
|
|
564
|
+
/**
|
|
565
|
+
* 监听事件
|
|
566
|
+
* @param {string} eventName - 要注册的事件名称
|
|
567
|
+
* @param {Function} callback - 事件触发时执行的回调函数
|
|
568
|
+
*/
|
|
569
|
+
//实现一个监听事件的方法
|
|
570
|
+
on(eventName, callback) {
|
|
571
|
+
if (!this.events[eventName]) {
|
|
572
|
+
this.events[eventName] = [];
|
|
573
|
+
}
|
|
574
|
+
this.events[eventName].push(callback);
|
|
575
|
+
return () => this.off(eventName, callback);
|
|
576
|
+
}
|
|
577
|
+
/**
|
|
578
|
+
* 触发事件
|
|
579
|
+
* @param {string} eventName --要触发的事件名称
|
|
580
|
+
* @param {any} data --传递给回调函数的数据
|
|
581
|
+
*/
|
|
582
|
+
emit(eventName, data) {
|
|
583
|
+
const callbacks = this.events[eventName];
|
|
584
|
+
if (!callbacks) return;
|
|
585
|
+
const callbakesCopy = callbacks.slice();
|
|
586
|
+
for (let i = 0; i < callbakesCopy.length; i++) {
|
|
587
|
+
try {
|
|
588
|
+
callbakesCopy[i](data);
|
|
589
|
+
} catch (error) {
|
|
590
|
+
console.error(`事件 ${eventName} 的回调函数执行出错:`, error);
|
|
591
|
+
}
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
/**
|
|
595
|
+
* 取消监听事件
|
|
596
|
+
* @param {string} eventName --要取消的事件名称
|
|
597
|
+
* @param {Function} callback --要移除的回调函数
|
|
598
|
+
*/
|
|
599
|
+
off(eventName, callback) {
|
|
600
|
+
const callbacks = this.events[eventName];
|
|
601
|
+
if (!callbacks) return;
|
|
602
|
+
this.events[eventName] = callbacks.filter((item) => item !== callback);
|
|
603
|
+
if (this.events[eventName].length === 0) {
|
|
604
|
+
delete this.events[eventName];
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
/**
|
|
608
|
+
* 只监听一次事件(触发后自动取消)
|
|
609
|
+
* @param {string} eventName - 事件名称
|
|
610
|
+
* @param {Function} callback - 回调函数
|
|
611
|
+
*/
|
|
612
|
+
once(evenName, callback) {
|
|
613
|
+
const onceCallback = (data) => {
|
|
614
|
+
this.off(evenName, onceCallback);
|
|
615
|
+
callback(data);
|
|
616
|
+
};
|
|
617
|
+
this.on(evenName, onceCallback);
|
|
618
|
+
return () => this.off(evenName, onceCallback);
|
|
619
|
+
}
|
|
620
|
+
/**
|
|
621
|
+
* 移除某个事件的所有监听器
|
|
622
|
+
* @param {string} eventName - 事件名称
|
|
623
|
+
*/
|
|
624
|
+
removeAllListeners(eventName) {
|
|
625
|
+
if (eventName) {
|
|
626
|
+
delete this.events[eventName];
|
|
627
|
+
} else {
|
|
628
|
+
this.events = {};
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
/**
|
|
632
|
+
* 获取某个事件的所有监听器数量
|
|
633
|
+
* @param {string} eventName - 事件名称
|
|
634
|
+
* @returns {number} 监听器数量
|
|
635
|
+
*/
|
|
636
|
+
listenerCount(eventName) {
|
|
637
|
+
const callbacks = this.events[eventName];
|
|
638
|
+
return callbacks ? callbacks.length : 0;
|
|
639
|
+
}
|
|
640
|
+
}
|
|
641
|
+
class ToolManager extends EventEmitter {
|
|
642
|
+
constructor() {
|
|
643
|
+
super();
|
|
644
|
+
this.tools = /* @__PURE__ */ new Map();
|
|
645
|
+
}
|
|
646
|
+
/**
|
|
647
|
+
* 注册工具
|
|
648
|
+
* @param {string} name - 工具名称
|
|
649
|
+
* @param {object} toolDefinition - 工具定义(包含描述和参数信息)
|
|
650
|
+
* @param {Function} executor - 工具执行函数,接受参数对象并返回结果
|
|
651
|
+
*/
|
|
652
|
+
registerTool(name, toolDefinition, executor) {
|
|
653
|
+
if (this.tools.has(name)) {
|
|
654
|
+
throw new Error(`[系统提示异常] 工具 "${name}" 已经注册过了`);
|
|
655
|
+
}
|
|
656
|
+
this.tools.set(name, {
|
|
657
|
+
definition: toolDefinition,
|
|
658
|
+
executor
|
|
659
|
+
});
|
|
660
|
+
this.emit("tool-registered", { name, definition: toolDefinition });
|
|
661
|
+
return this;
|
|
662
|
+
}
|
|
663
|
+
/**
|
|
664
|
+
* 执行工具调用
|
|
665
|
+
* @param {object} toolCall - 工具调用信息,包含工具名称和参数
|
|
666
|
+
* @returns {Promise<any>} - 工具执行结果
|
|
667
|
+
*/
|
|
668
|
+
async executeToolCall(toolCall) {
|
|
669
|
+
const { id, function: func } = toolCall;
|
|
670
|
+
const { name, arguments: argsStr } = func;
|
|
671
|
+
if (!this.tools.has(name)) {
|
|
672
|
+
throw new Error(`未找到工具: ${name}`);
|
|
673
|
+
}
|
|
674
|
+
const tool = this.tools.get(name);
|
|
675
|
+
try {
|
|
676
|
+
const args = JSON.parse(argsStr);
|
|
677
|
+
this.emit("tool-execute-start", { name, args });
|
|
678
|
+
const result = await tool.executor(args);
|
|
679
|
+
this.emit("tool-execute-success", { name, args, result });
|
|
680
|
+
return {
|
|
681
|
+
tool_call_id: id,
|
|
682
|
+
// 必须包含tool_call_id
|
|
683
|
+
name,
|
|
684
|
+
result: JSON.stringify(result),
|
|
685
|
+
success: true
|
|
686
|
+
};
|
|
687
|
+
} catch (error) {
|
|
688
|
+
this.emit("tool-execute-error", { name, error });
|
|
689
|
+
return {
|
|
690
|
+
tool_call_id: id,
|
|
691
|
+
name,
|
|
692
|
+
error: error.message,
|
|
693
|
+
success: false
|
|
694
|
+
};
|
|
695
|
+
}
|
|
696
|
+
}
|
|
697
|
+
/**
|
|
698
|
+
* 获取所有工具定义(用于发送给AI)
|
|
699
|
+
*/
|
|
700
|
+
getToolDefinitions() {
|
|
701
|
+
const definitions = [];
|
|
702
|
+
for (const [name, tool] of this.tools) {
|
|
703
|
+
definitions.push(tool.definition);
|
|
704
|
+
}
|
|
705
|
+
return definitions;
|
|
706
|
+
}
|
|
707
|
+
/**
|
|
708
|
+
* 检查是否有工具
|
|
709
|
+
*/
|
|
710
|
+
hasTools() {
|
|
711
|
+
return this.tools.size > 0;
|
|
712
|
+
}
|
|
713
|
+
/**
|
|
714
|
+
* 批量执行工具调用
|
|
715
|
+
* @param {Array} toolCalls - 工具调用数组
|
|
716
|
+
* @returns {Promise<Array>} - 所有工具的执行结果
|
|
717
|
+
*/
|
|
718
|
+
async executeToolCalls(toolCalls) {
|
|
719
|
+
if (!Array.isArray(toolCalls)) {
|
|
720
|
+
throw new Error("toolCalls必须是数组");
|
|
721
|
+
}
|
|
722
|
+
const results = [];
|
|
723
|
+
const promises = toolCalls.map(async (toolCall) => {
|
|
724
|
+
try {
|
|
725
|
+
const result = await this.executeToolCall(toolCall);
|
|
726
|
+
return result;
|
|
727
|
+
} catch (error) {
|
|
728
|
+
return {
|
|
729
|
+
tool_call_id: toolCall.id,
|
|
730
|
+
name: toolCall.function.name,
|
|
731
|
+
error: error.message,
|
|
732
|
+
success: false
|
|
733
|
+
};
|
|
734
|
+
}
|
|
735
|
+
});
|
|
736
|
+
const settledResults = await Promise.allSettled(promises);
|
|
737
|
+
for (const settled of settledResults) {
|
|
738
|
+
if (settled.status === "fulfilled") {
|
|
739
|
+
results.push(settled.value);
|
|
740
|
+
} else {
|
|
741
|
+
results.push({
|
|
742
|
+
error: settled.reason.message,
|
|
743
|
+
success: false
|
|
744
|
+
});
|
|
745
|
+
}
|
|
746
|
+
}
|
|
747
|
+
return results;
|
|
748
|
+
}
|
|
749
|
+
/**
|
|
750
|
+
* 串行执行工具调用(如果需要顺序执行)
|
|
751
|
+
*/
|
|
752
|
+
async executeToolCallsSequentially(toolCalls) {
|
|
753
|
+
const results = [];
|
|
754
|
+
for (const toolCall of toolCalls) {
|
|
755
|
+
try {
|
|
756
|
+
const result = await this.executeToolCall(toolCall);
|
|
757
|
+
results.push(result);
|
|
758
|
+
} catch (error) {
|
|
759
|
+
results.push({
|
|
760
|
+
tool_call_id: toolCall.id,
|
|
761
|
+
name: toolCall.function.name,
|
|
762
|
+
error: error.message,
|
|
763
|
+
success: false
|
|
764
|
+
});
|
|
765
|
+
}
|
|
766
|
+
}
|
|
767
|
+
return results;
|
|
768
|
+
}
|
|
769
|
+
}
|
|
770
|
+
class RequestBuilder {
|
|
771
|
+
constructor(model, messagesInstance, config = {}) {
|
|
772
|
+
this.model = model;
|
|
773
|
+
this.messages = messagesInstance;
|
|
774
|
+
this.config = {
|
|
775
|
+
// temperature: 0.7,
|
|
776
|
+
// max_tokens: 2000,
|
|
777
|
+
// stream: false, // 默认关闭流式传输
|
|
778
|
+
...config
|
|
779
|
+
};
|
|
780
|
+
this.toolManager = null;
|
|
781
|
+
}
|
|
782
|
+
/**
|
|
783
|
+
* 设置ToolManager引用
|
|
784
|
+
*/
|
|
785
|
+
setToolManager(toolManager) {
|
|
786
|
+
this.toolManager = toolManager;
|
|
787
|
+
return this;
|
|
788
|
+
}
|
|
789
|
+
/**
|
|
790
|
+
* 构建OpenAI兼容格式的请求体
|
|
791
|
+
*/
|
|
792
|
+
buildOpenAIFormat(baseRounds, cycleRounds) {
|
|
793
|
+
const formattedMessages = MessageFormatter.formatMessages(
|
|
794
|
+
this.messages,
|
|
795
|
+
baseRounds,
|
|
796
|
+
cycleRounds
|
|
797
|
+
);
|
|
798
|
+
const request = {
|
|
799
|
+
model: this.model,
|
|
800
|
+
messages: formattedMessages,
|
|
801
|
+
...this.config
|
|
802
|
+
};
|
|
803
|
+
let tools = [];
|
|
804
|
+
if (this.toolManager && this.toolManager.hasTools()) {
|
|
805
|
+
tools = this.toolManager.getToolDefinitions();
|
|
806
|
+
} else {
|
|
807
|
+
tools = this.messages.getTools();
|
|
808
|
+
}
|
|
809
|
+
if (tools && tools.length > 0) {
|
|
810
|
+
request.tools = tools;
|
|
811
|
+
request.tool_choice = "auto";
|
|
812
|
+
}
|
|
813
|
+
return request;
|
|
814
|
+
}
|
|
815
|
+
/**
|
|
816
|
+
* 构建请求体并返回JSON字符串
|
|
817
|
+
*/
|
|
818
|
+
toJSON(baseRounds, cycleRounds) {
|
|
819
|
+
const request = this.buildOpenAIFormat(baseRounds, cycleRounds);
|
|
820
|
+
return JSON.stringify(request);
|
|
821
|
+
}
|
|
822
|
+
/**
|
|
823
|
+
* 构建请求体并返回对象
|
|
824
|
+
*/
|
|
825
|
+
toObject(baseRounds, cycleRounds) {
|
|
826
|
+
return this.buildOpenAIFormat(baseRounds, cycleRounds);
|
|
827
|
+
}
|
|
828
|
+
/**
|
|
829
|
+
* 设置配置项
|
|
830
|
+
*/
|
|
831
|
+
setConfig(key, value) {
|
|
832
|
+
this.config[key] = value;
|
|
833
|
+
return this;
|
|
834
|
+
}
|
|
835
|
+
/**
|
|
836
|
+
* 批量设置配置项
|
|
837
|
+
*/
|
|
838
|
+
setConfigs(configs) {
|
|
839
|
+
Object.assign(this.config, configs);
|
|
840
|
+
return this;
|
|
841
|
+
}
|
|
842
|
+
}
|
|
843
|
+
function getDefaultExportFromCjs(x) {
|
|
844
|
+
return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, "default") ? x["default"] : x;
|
|
845
|
+
}
|
|
846
|
+
var axios$2 = { exports: {} };
|
|
847
|
+
var bind;
|
|
848
|
+
var hasRequiredBind;
|
|
849
|
+
function requireBind() {
|
|
850
|
+
if (hasRequiredBind) return bind;
|
|
851
|
+
hasRequiredBind = 1;
|
|
852
|
+
bind = function bind2(fn, thisArg) {
|
|
853
|
+
return function wrap() {
|
|
854
|
+
var args = new Array(arguments.length);
|
|
855
|
+
for (var i = 0; i < args.length; i++) {
|
|
856
|
+
args[i] = arguments[i];
|
|
857
|
+
}
|
|
858
|
+
return fn.apply(thisArg, args);
|
|
859
|
+
};
|
|
860
|
+
};
|
|
861
|
+
return bind;
|
|
862
|
+
}
|
|
863
|
+
var utils;
|
|
864
|
+
var hasRequiredUtils;
|
|
865
|
+
function requireUtils() {
|
|
866
|
+
if (hasRequiredUtils) return utils;
|
|
867
|
+
hasRequiredUtils = 1;
|
|
868
|
+
var bind2 = requireBind();
|
|
869
|
+
var toString = Object.prototype.toString;
|
|
870
|
+
function isArray(val) {
|
|
871
|
+
return toString.call(val) === "[object Array]";
|
|
872
|
+
}
|
|
873
|
+
function isUndefined(val) {
|
|
874
|
+
return typeof val === "undefined";
|
|
875
|
+
}
|
|
876
|
+
function isBuffer(val) {
|
|
877
|
+
return val !== null && !isUndefined(val) && val.constructor !== null && !isUndefined(val.constructor) && typeof val.constructor.isBuffer === "function" && val.constructor.isBuffer(val);
|
|
878
|
+
}
|
|
879
|
+
function isArrayBuffer(val) {
|
|
880
|
+
return toString.call(val) === "[object ArrayBuffer]";
|
|
881
|
+
}
|
|
882
|
+
function isFormData(val) {
|
|
883
|
+
return typeof FormData !== "undefined" && val instanceof FormData;
|
|
884
|
+
}
|
|
885
|
+
function isArrayBufferView(val) {
|
|
886
|
+
var result;
|
|
887
|
+
if (typeof ArrayBuffer !== "undefined" && ArrayBuffer.isView) {
|
|
888
|
+
result = ArrayBuffer.isView(val);
|
|
889
|
+
} else {
|
|
890
|
+
result = val && val.buffer && val.buffer instanceof ArrayBuffer;
|
|
891
|
+
}
|
|
892
|
+
return result;
|
|
893
|
+
}
|
|
894
|
+
function isString(val) {
|
|
895
|
+
return typeof val === "string";
|
|
896
|
+
}
|
|
897
|
+
function isNumber(val) {
|
|
898
|
+
return typeof val === "number";
|
|
899
|
+
}
|
|
900
|
+
function isObject(val) {
|
|
901
|
+
return val !== null && typeof val === "object";
|
|
902
|
+
}
|
|
903
|
+
function isPlainObject(val) {
|
|
904
|
+
if (toString.call(val) !== "[object Object]") {
|
|
905
|
+
return false;
|
|
906
|
+
}
|
|
907
|
+
var prototype = Object.getPrototypeOf(val);
|
|
908
|
+
return prototype === null || prototype === Object.prototype;
|
|
909
|
+
}
|
|
910
|
+
function isDate(val) {
|
|
911
|
+
return toString.call(val) === "[object Date]";
|
|
912
|
+
}
|
|
913
|
+
function isFile(val) {
|
|
914
|
+
return toString.call(val) === "[object File]";
|
|
915
|
+
}
|
|
916
|
+
function isBlob(val) {
|
|
917
|
+
return toString.call(val) === "[object Blob]";
|
|
918
|
+
}
|
|
919
|
+
function isFunction(val) {
|
|
920
|
+
return toString.call(val) === "[object Function]";
|
|
921
|
+
}
|
|
922
|
+
function isStream(val) {
|
|
923
|
+
return isObject(val) && isFunction(val.pipe);
|
|
924
|
+
}
|
|
925
|
+
function isURLSearchParams(val) {
|
|
926
|
+
return typeof URLSearchParams !== "undefined" && val instanceof URLSearchParams;
|
|
927
|
+
}
|
|
928
|
+
function trim(str) {
|
|
929
|
+
return str.trim ? str.trim() : str.replace(/^\s+|\s+$/g, "");
|
|
930
|
+
}
|
|
931
|
+
function isStandardBrowserEnv() {
|
|
932
|
+
if (typeof navigator !== "undefined" && (navigator.product === "ReactNative" || navigator.product === "NativeScript" || navigator.product === "NS")) {
|
|
933
|
+
return false;
|
|
934
|
+
}
|
|
935
|
+
return typeof window !== "undefined" && typeof document !== "undefined";
|
|
936
|
+
}
|
|
937
|
+
function forEach(obj, fn) {
|
|
938
|
+
if (obj === null || typeof obj === "undefined") {
|
|
939
|
+
return;
|
|
940
|
+
}
|
|
941
|
+
if (typeof obj !== "object") {
|
|
942
|
+
obj = [obj];
|
|
943
|
+
}
|
|
944
|
+
if (isArray(obj)) {
|
|
945
|
+
for (var i = 0, l = obj.length; i < l; i++) {
|
|
946
|
+
fn.call(null, obj[i], i, obj);
|
|
947
|
+
}
|
|
948
|
+
} else {
|
|
949
|
+
for (var key in obj) {
|
|
950
|
+
if (Object.prototype.hasOwnProperty.call(obj, key)) {
|
|
951
|
+
fn.call(null, obj[key], key, obj);
|
|
952
|
+
}
|
|
953
|
+
}
|
|
954
|
+
}
|
|
955
|
+
}
|
|
956
|
+
function merge() {
|
|
957
|
+
var result = {};
|
|
958
|
+
function assignValue(val, key) {
|
|
959
|
+
if (isPlainObject(result[key]) && isPlainObject(val)) {
|
|
960
|
+
result[key] = merge(result[key], val);
|
|
961
|
+
} else if (isPlainObject(val)) {
|
|
962
|
+
result[key] = merge({}, val);
|
|
963
|
+
} else if (isArray(val)) {
|
|
964
|
+
result[key] = val.slice();
|
|
965
|
+
} else {
|
|
966
|
+
result[key] = val;
|
|
967
|
+
}
|
|
968
|
+
}
|
|
969
|
+
for (var i = 0, l = arguments.length; i < l; i++) {
|
|
970
|
+
forEach(arguments[i], assignValue);
|
|
971
|
+
}
|
|
972
|
+
return result;
|
|
973
|
+
}
|
|
974
|
+
function extend(a, b, thisArg) {
|
|
975
|
+
forEach(b, function assignValue(val, key) {
|
|
976
|
+
if (thisArg && typeof val === "function") {
|
|
977
|
+
a[key] = bind2(val, thisArg);
|
|
978
|
+
} else {
|
|
979
|
+
a[key] = val;
|
|
980
|
+
}
|
|
981
|
+
});
|
|
982
|
+
return a;
|
|
983
|
+
}
|
|
984
|
+
function stripBOM(content) {
|
|
985
|
+
if (content.charCodeAt(0) === 65279) {
|
|
986
|
+
content = content.slice(1);
|
|
987
|
+
}
|
|
988
|
+
return content;
|
|
989
|
+
}
|
|
990
|
+
utils = {
|
|
991
|
+
isArray,
|
|
992
|
+
isArrayBuffer,
|
|
993
|
+
isBuffer,
|
|
994
|
+
isFormData,
|
|
995
|
+
isArrayBufferView,
|
|
996
|
+
isString,
|
|
997
|
+
isNumber,
|
|
998
|
+
isObject,
|
|
999
|
+
isPlainObject,
|
|
1000
|
+
isUndefined,
|
|
1001
|
+
isDate,
|
|
1002
|
+
isFile,
|
|
1003
|
+
isBlob,
|
|
1004
|
+
isFunction,
|
|
1005
|
+
isStream,
|
|
1006
|
+
isURLSearchParams,
|
|
1007
|
+
isStandardBrowserEnv,
|
|
1008
|
+
forEach,
|
|
1009
|
+
merge,
|
|
1010
|
+
extend,
|
|
1011
|
+
trim,
|
|
1012
|
+
stripBOM
|
|
1013
|
+
};
|
|
1014
|
+
return utils;
|
|
1015
|
+
}
|
|
1016
|
+
var buildURL;
|
|
1017
|
+
var hasRequiredBuildURL;
|
|
1018
|
+
function requireBuildURL() {
|
|
1019
|
+
if (hasRequiredBuildURL) return buildURL;
|
|
1020
|
+
hasRequiredBuildURL = 1;
|
|
1021
|
+
var utils2 = requireUtils();
|
|
1022
|
+
function encode(val) {
|
|
1023
|
+
return encodeURIComponent(val).replace(/%3A/gi, ":").replace(/%24/g, "$").replace(/%2C/gi, ",").replace(/%20/g, "+").replace(/%5B/gi, "[").replace(/%5D/gi, "]");
|
|
1024
|
+
}
|
|
1025
|
+
buildURL = function buildURL2(url, params, paramsSerializer) {
|
|
1026
|
+
if (!params) {
|
|
1027
|
+
return url;
|
|
1028
|
+
}
|
|
1029
|
+
var serializedParams;
|
|
1030
|
+
if (paramsSerializer) {
|
|
1031
|
+
serializedParams = paramsSerializer(params);
|
|
1032
|
+
} else if (utils2.isURLSearchParams(params)) {
|
|
1033
|
+
serializedParams = params.toString();
|
|
1034
|
+
} else {
|
|
1035
|
+
var parts = [];
|
|
1036
|
+
utils2.forEach(params, function serialize(val, key) {
|
|
1037
|
+
if (val === null || typeof val === "undefined") {
|
|
1038
|
+
return;
|
|
1039
|
+
}
|
|
1040
|
+
if (utils2.isArray(val)) {
|
|
1041
|
+
key = key + "[]";
|
|
1042
|
+
} else {
|
|
1043
|
+
val = [val];
|
|
1044
|
+
}
|
|
1045
|
+
utils2.forEach(val, function parseValue(v) {
|
|
1046
|
+
if (utils2.isDate(v)) {
|
|
1047
|
+
v = v.toISOString();
|
|
1048
|
+
} else if (utils2.isObject(v)) {
|
|
1049
|
+
v = JSON.stringify(v);
|
|
1050
|
+
}
|
|
1051
|
+
parts.push(encode(key) + "=" + encode(v));
|
|
1052
|
+
});
|
|
1053
|
+
});
|
|
1054
|
+
serializedParams = parts.join("&");
|
|
1055
|
+
}
|
|
1056
|
+
if (serializedParams) {
|
|
1057
|
+
var hashmarkIndex = url.indexOf("#");
|
|
1058
|
+
if (hashmarkIndex !== -1) {
|
|
1059
|
+
url = url.slice(0, hashmarkIndex);
|
|
1060
|
+
}
|
|
1061
|
+
url += (url.indexOf("?") === -1 ? "?" : "&") + serializedParams;
|
|
1062
|
+
}
|
|
1063
|
+
return url;
|
|
1064
|
+
};
|
|
1065
|
+
return buildURL;
|
|
1066
|
+
}
|
|
1067
|
+
var InterceptorManager_1;
|
|
1068
|
+
var hasRequiredInterceptorManager;
|
|
1069
|
+
function requireInterceptorManager() {
|
|
1070
|
+
if (hasRequiredInterceptorManager) return InterceptorManager_1;
|
|
1071
|
+
hasRequiredInterceptorManager = 1;
|
|
1072
|
+
var utils2 = requireUtils();
|
|
1073
|
+
function InterceptorManager() {
|
|
1074
|
+
this.handlers = [];
|
|
1075
|
+
}
|
|
1076
|
+
InterceptorManager.prototype.use = function use(fulfilled, rejected, options) {
|
|
1077
|
+
this.handlers.push({
|
|
1078
|
+
fulfilled,
|
|
1079
|
+
rejected,
|
|
1080
|
+
synchronous: options ? options.synchronous : false,
|
|
1081
|
+
runWhen: options ? options.runWhen : null
|
|
1082
|
+
});
|
|
1083
|
+
return this.handlers.length - 1;
|
|
1084
|
+
};
|
|
1085
|
+
InterceptorManager.prototype.eject = function eject(id) {
|
|
1086
|
+
if (this.handlers[id]) {
|
|
1087
|
+
this.handlers[id] = null;
|
|
1088
|
+
}
|
|
1089
|
+
};
|
|
1090
|
+
InterceptorManager.prototype.forEach = function forEach(fn) {
|
|
1091
|
+
utils2.forEach(this.handlers, function forEachHandler(h) {
|
|
1092
|
+
if (h !== null) {
|
|
1093
|
+
fn(h);
|
|
1094
|
+
}
|
|
1095
|
+
});
|
|
1096
|
+
};
|
|
1097
|
+
InterceptorManager_1 = InterceptorManager;
|
|
1098
|
+
return InterceptorManager_1;
|
|
1099
|
+
}
|
|
1100
|
+
var normalizeHeaderName;
|
|
1101
|
+
var hasRequiredNormalizeHeaderName;
|
|
1102
|
+
function requireNormalizeHeaderName() {
|
|
1103
|
+
if (hasRequiredNormalizeHeaderName) return normalizeHeaderName;
|
|
1104
|
+
hasRequiredNormalizeHeaderName = 1;
|
|
1105
|
+
var utils2 = requireUtils();
|
|
1106
|
+
normalizeHeaderName = function normalizeHeaderName2(headers, normalizedName) {
|
|
1107
|
+
utils2.forEach(headers, function processHeader(value, name) {
|
|
1108
|
+
if (name !== normalizedName && name.toUpperCase() === normalizedName.toUpperCase()) {
|
|
1109
|
+
headers[normalizedName] = value;
|
|
1110
|
+
delete headers[name];
|
|
1111
|
+
}
|
|
1112
|
+
});
|
|
1113
|
+
};
|
|
1114
|
+
return normalizeHeaderName;
|
|
1115
|
+
}
|
|
1116
|
+
var enhanceError;
|
|
1117
|
+
var hasRequiredEnhanceError;
|
|
1118
|
+
function requireEnhanceError() {
|
|
1119
|
+
if (hasRequiredEnhanceError) return enhanceError;
|
|
1120
|
+
hasRequiredEnhanceError = 1;
|
|
1121
|
+
enhanceError = function enhanceError2(error, config, code, request, response) {
|
|
1122
|
+
error.config = config;
|
|
1123
|
+
if (code) {
|
|
1124
|
+
error.code = code;
|
|
1125
|
+
}
|
|
1126
|
+
error.request = request;
|
|
1127
|
+
error.response = response;
|
|
1128
|
+
error.isAxiosError = true;
|
|
1129
|
+
error.toJSON = function toJSON() {
|
|
1130
|
+
return {
|
|
1131
|
+
// Standard
|
|
1132
|
+
message: this.message,
|
|
1133
|
+
name: this.name,
|
|
1134
|
+
// Microsoft
|
|
1135
|
+
description: this.description,
|
|
1136
|
+
number: this.number,
|
|
1137
|
+
// Mozilla
|
|
1138
|
+
fileName: this.fileName,
|
|
1139
|
+
lineNumber: this.lineNumber,
|
|
1140
|
+
columnNumber: this.columnNumber,
|
|
1141
|
+
stack: this.stack,
|
|
1142
|
+
// Axios
|
|
1143
|
+
config: this.config,
|
|
1144
|
+
code: this.code
|
|
1145
|
+
};
|
|
1146
|
+
};
|
|
1147
|
+
return error;
|
|
1148
|
+
};
|
|
1149
|
+
return enhanceError;
|
|
1150
|
+
}
|
|
1151
|
+
var createError;
|
|
1152
|
+
var hasRequiredCreateError;
|
|
1153
|
+
function requireCreateError() {
|
|
1154
|
+
if (hasRequiredCreateError) return createError;
|
|
1155
|
+
hasRequiredCreateError = 1;
|
|
1156
|
+
var enhanceError2 = requireEnhanceError();
|
|
1157
|
+
createError = function createError2(message, config, code, request, response) {
|
|
1158
|
+
var error = new Error(message);
|
|
1159
|
+
return enhanceError2(error, config, code, request, response);
|
|
1160
|
+
};
|
|
1161
|
+
return createError;
|
|
1162
|
+
}
|
|
1163
|
+
var settle;
|
|
1164
|
+
var hasRequiredSettle;
|
|
1165
|
+
function requireSettle() {
|
|
1166
|
+
if (hasRequiredSettle) return settle;
|
|
1167
|
+
hasRequiredSettle = 1;
|
|
1168
|
+
var createError2 = requireCreateError();
|
|
1169
|
+
settle = function settle2(resolve, reject, response) {
|
|
1170
|
+
var validateStatus = response.config.validateStatus;
|
|
1171
|
+
if (!response.status || !validateStatus || validateStatus(response.status)) {
|
|
1172
|
+
resolve(response);
|
|
1173
|
+
} else {
|
|
1174
|
+
reject(createError2(
|
|
1175
|
+
"Request failed with status code " + response.status,
|
|
1176
|
+
response.config,
|
|
1177
|
+
null,
|
|
1178
|
+
response.request,
|
|
1179
|
+
response
|
|
1180
|
+
));
|
|
1181
|
+
}
|
|
1182
|
+
};
|
|
1183
|
+
return settle;
|
|
1184
|
+
}
|
|
1185
|
+
var cookies;
|
|
1186
|
+
var hasRequiredCookies;
|
|
1187
|
+
function requireCookies() {
|
|
1188
|
+
if (hasRequiredCookies) return cookies;
|
|
1189
|
+
hasRequiredCookies = 1;
|
|
1190
|
+
var utils2 = requireUtils();
|
|
1191
|
+
cookies = utils2.isStandardBrowserEnv() ? (
|
|
1192
|
+
// Standard browser envs support document.cookie
|
|
1193
|
+
/* @__PURE__ */ (function standardBrowserEnv() {
|
|
1194
|
+
return {
|
|
1195
|
+
write: function write(name, value, expires, path, domain, secure) {
|
|
1196
|
+
var cookie = [];
|
|
1197
|
+
cookie.push(name + "=" + encodeURIComponent(value));
|
|
1198
|
+
if (utils2.isNumber(expires)) {
|
|
1199
|
+
cookie.push("expires=" + new Date(expires).toGMTString());
|
|
1200
|
+
}
|
|
1201
|
+
if (utils2.isString(path)) {
|
|
1202
|
+
cookie.push("path=" + path);
|
|
1203
|
+
}
|
|
1204
|
+
if (utils2.isString(domain)) {
|
|
1205
|
+
cookie.push("domain=" + domain);
|
|
1206
|
+
}
|
|
1207
|
+
if (secure === true) {
|
|
1208
|
+
cookie.push("secure");
|
|
1209
|
+
}
|
|
1210
|
+
document.cookie = cookie.join("; ");
|
|
1211
|
+
},
|
|
1212
|
+
read: function read(name) {
|
|
1213
|
+
var match = document.cookie.match(new RegExp("(^|;\\s*)(" + name + ")=([^;]*)"));
|
|
1214
|
+
return match ? decodeURIComponent(match[3]) : null;
|
|
1215
|
+
},
|
|
1216
|
+
remove: function remove(name) {
|
|
1217
|
+
this.write(name, "", Date.now() - 864e5);
|
|
1218
|
+
}
|
|
1219
|
+
};
|
|
1220
|
+
})()
|
|
1221
|
+
) : (
|
|
1222
|
+
// Non standard browser env (web workers, react-native) lack needed support.
|
|
1223
|
+
/* @__PURE__ */ (function nonStandardBrowserEnv() {
|
|
1224
|
+
return {
|
|
1225
|
+
write: function write() {
|
|
1226
|
+
},
|
|
1227
|
+
read: function read() {
|
|
1228
|
+
return null;
|
|
1229
|
+
},
|
|
1230
|
+
remove: function remove() {
|
|
1231
|
+
}
|
|
1232
|
+
};
|
|
1233
|
+
})()
|
|
1234
|
+
);
|
|
1235
|
+
return cookies;
|
|
1236
|
+
}
|
|
1237
|
+
var isAbsoluteURL;
|
|
1238
|
+
var hasRequiredIsAbsoluteURL;
|
|
1239
|
+
function requireIsAbsoluteURL() {
|
|
1240
|
+
if (hasRequiredIsAbsoluteURL) return isAbsoluteURL;
|
|
1241
|
+
hasRequiredIsAbsoluteURL = 1;
|
|
1242
|
+
isAbsoluteURL = function isAbsoluteURL2(url) {
|
|
1243
|
+
return /^([a-z][a-z\d\+\-\.]*:)?\/\//i.test(url);
|
|
1244
|
+
};
|
|
1245
|
+
return isAbsoluteURL;
|
|
1246
|
+
}
|
|
1247
|
+
var combineURLs;
|
|
1248
|
+
var hasRequiredCombineURLs;
|
|
1249
|
+
function requireCombineURLs() {
|
|
1250
|
+
if (hasRequiredCombineURLs) return combineURLs;
|
|
1251
|
+
hasRequiredCombineURLs = 1;
|
|
1252
|
+
combineURLs = function combineURLs2(baseURL, relativeURL) {
|
|
1253
|
+
return relativeURL ? baseURL.replace(/\/+$/, "") + "/" + relativeURL.replace(/^\/+/, "") : baseURL;
|
|
1254
|
+
};
|
|
1255
|
+
return combineURLs;
|
|
1256
|
+
}
|
|
1257
|
+
var buildFullPath;
|
|
1258
|
+
var hasRequiredBuildFullPath;
|
|
1259
|
+
function requireBuildFullPath() {
|
|
1260
|
+
if (hasRequiredBuildFullPath) return buildFullPath;
|
|
1261
|
+
hasRequiredBuildFullPath = 1;
|
|
1262
|
+
var isAbsoluteURL2 = requireIsAbsoluteURL();
|
|
1263
|
+
var combineURLs2 = requireCombineURLs();
|
|
1264
|
+
buildFullPath = function buildFullPath2(baseURL, requestedURL) {
|
|
1265
|
+
if (baseURL && !isAbsoluteURL2(requestedURL)) {
|
|
1266
|
+
return combineURLs2(baseURL, requestedURL);
|
|
1267
|
+
}
|
|
1268
|
+
return requestedURL;
|
|
1269
|
+
};
|
|
1270
|
+
return buildFullPath;
|
|
1271
|
+
}
|
|
1272
|
+
var parseHeaders;
|
|
1273
|
+
var hasRequiredParseHeaders;
|
|
1274
|
+
function requireParseHeaders() {
|
|
1275
|
+
if (hasRequiredParseHeaders) return parseHeaders;
|
|
1276
|
+
hasRequiredParseHeaders = 1;
|
|
1277
|
+
var utils2 = requireUtils();
|
|
1278
|
+
var ignoreDuplicateOf = [
|
|
1279
|
+
"age",
|
|
1280
|
+
"authorization",
|
|
1281
|
+
"content-length",
|
|
1282
|
+
"content-type",
|
|
1283
|
+
"etag",
|
|
1284
|
+
"expires",
|
|
1285
|
+
"from",
|
|
1286
|
+
"host",
|
|
1287
|
+
"if-modified-since",
|
|
1288
|
+
"if-unmodified-since",
|
|
1289
|
+
"last-modified",
|
|
1290
|
+
"location",
|
|
1291
|
+
"max-forwards",
|
|
1292
|
+
"proxy-authorization",
|
|
1293
|
+
"referer",
|
|
1294
|
+
"retry-after",
|
|
1295
|
+
"user-agent"
|
|
1296
|
+
];
|
|
1297
|
+
parseHeaders = function parseHeaders2(headers) {
|
|
1298
|
+
var parsed = {};
|
|
1299
|
+
var key;
|
|
1300
|
+
var val;
|
|
1301
|
+
var i;
|
|
1302
|
+
if (!headers) {
|
|
1303
|
+
return parsed;
|
|
1304
|
+
}
|
|
1305
|
+
utils2.forEach(headers.split("\n"), function parser(line) {
|
|
1306
|
+
i = line.indexOf(":");
|
|
1307
|
+
key = utils2.trim(line.substr(0, i)).toLowerCase();
|
|
1308
|
+
val = utils2.trim(line.substr(i + 1));
|
|
1309
|
+
if (key) {
|
|
1310
|
+
if (parsed[key] && ignoreDuplicateOf.indexOf(key) >= 0) {
|
|
1311
|
+
return;
|
|
1312
|
+
}
|
|
1313
|
+
if (key === "set-cookie") {
|
|
1314
|
+
parsed[key] = (parsed[key] ? parsed[key] : []).concat([val]);
|
|
1315
|
+
} else {
|
|
1316
|
+
parsed[key] = parsed[key] ? parsed[key] + ", " + val : val;
|
|
1317
|
+
}
|
|
1318
|
+
}
|
|
1319
|
+
});
|
|
1320
|
+
return parsed;
|
|
1321
|
+
};
|
|
1322
|
+
return parseHeaders;
|
|
1323
|
+
}
|
|
1324
|
+
var isURLSameOrigin;
|
|
1325
|
+
var hasRequiredIsURLSameOrigin;
|
|
1326
|
+
function requireIsURLSameOrigin() {
|
|
1327
|
+
if (hasRequiredIsURLSameOrigin) return isURLSameOrigin;
|
|
1328
|
+
hasRequiredIsURLSameOrigin = 1;
|
|
1329
|
+
var utils2 = requireUtils();
|
|
1330
|
+
isURLSameOrigin = utils2.isStandardBrowserEnv() ? (
|
|
1331
|
+
// Standard browser envs have full support of the APIs needed to test
|
|
1332
|
+
// whether the request URL is of the same origin as current location.
|
|
1333
|
+
(function standardBrowserEnv() {
|
|
1334
|
+
var msie = /(msie|trident)/i.test(navigator.userAgent);
|
|
1335
|
+
var urlParsingNode = document.createElement("a");
|
|
1336
|
+
var originURL;
|
|
1337
|
+
function resolveURL(url) {
|
|
1338
|
+
var href = url;
|
|
1339
|
+
if (msie) {
|
|
1340
|
+
urlParsingNode.setAttribute("href", href);
|
|
1341
|
+
href = urlParsingNode.href;
|
|
1342
|
+
}
|
|
1343
|
+
urlParsingNode.setAttribute("href", href);
|
|
1344
|
+
return {
|
|
1345
|
+
href: urlParsingNode.href,
|
|
1346
|
+
protocol: urlParsingNode.protocol ? urlParsingNode.protocol.replace(/:$/, "") : "",
|
|
1347
|
+
host: urlParsingNode.host,
|
|
1348
|
+
search: urlParsingNode.search ? urlParsingNode.search.replace(/^\?/, "") : "",
|
|
1349
|
+
hash: urlParsingNode.hash ? urlParsingNode.hash.replace(/^#/, "") : "",
|
|
1350
|
+
hostname: urlParsingNode.hostname,
|
|
1351
|
+
port: urlParsingNode.port,
|
|
1352
|
+
pathname: urlParsingNode.pathname.charAt(0) === "/" ? urlParsingNode.pathname : "/" + urlParsingNode.pathname
|
|
1353
|
+
};
|
|
1354
|
+
}
|
|
1355
|
+
originURL = resolveURL(window.location.href);
|
|
1356
|
+
return function isURLSameOrigin2(requestURL) {
|
|
1357
|
+
var parsed = utils2.isString(requestURL) ? resolveURL(requestURL) : requestURL;
|
|
1358
|
+
return parsed.protocol === originURL.protocol && parsed.host === originURL.host;
|
|
1359
|
+
};
|
|
1360
|
+
})()
|
|
1361
|
+
) : (
|
|
1362
|
+
// Non standard browser envs (web workers, react-native) lack needed support.
|
|
1363
|
+
/* @__PURE__ */ (function nonStandardBrowserEnv() {
|
|
1364
|
+
return function isURLSameOrigin2() {
|
|
1365
|
+
return true;
|
|
1366
|
+
};
|
|
1367
|
+
})()
|
|
1368
|
+
);
|
|
1369
|
+
return isURLSameOrigin;
|
|
1370
|
+
}
|
|
1371
|
+
var xhr;
|
|
1372
|
+
var hasRequiredXhr;
|
|
1373
|
+
function requireXhr() {
|
|
1374
|
+
if (hasRequiredXhr) return xhr;
|
|
1375
|
+
hasRequiredXhr = 1;
|
|
1376
|
+
var utils2 = requireUtils();
|
|
1377
|
+
var settle2 = requireSettle();
|
|
1378
|
+
var cookies2 = requireCookies();
|
|
1379
|
+
var buildURL2 = requireBuildURL();
|
|
1380
|
+
var buildFullPath2 = requireBuildFullPath();
|
|
1381
|
+
var parseHeaders2 = requireParseHeaders();
|
|
1382
|
+
var isURLSameOrigin2 = requireIsURLSameOrigin();
|
|
1383
|
+
var createError2 = requireCreateError();
|
|
1384
|
+
xhr = function xhrAdapter(config) {
|
|
1385
|
+
return new Promise(function dispatchXhrRequest(resolve, reject) {
|
|
1386
|
+
var requestData = config.data;
|
|
1387
|
+
var requestHeaders = config.headers;
|
|
1388
|
+
var responseType = config.responseType;
|
|
1389
|
+
if (utils2.isFormData(requestData)) {
|
|
1390
|
+
delete requestHeaders["Content-Type"];
|
|
1391
|
+
}
|
|
1392
|
+
var request = new XMLHttpRequest();
|
|
1393
|
+
if (config.auth) {
|
|
1394
|
+
var username = config.auth.username || "";
|
|
1395
|
+
var password = config.auth.password ? unescape(encodeURIComponent(config.auth.password)) : "";
|
|
1396
|
+
requestHeaders.Authorization = "Basic " + btoa(username + ":" + password);
|
|
1397
|
+
}
|
|
1398
|
+
var fullPath = buildFullPath2(config.baseURL, config.url);
|
|
1399
|
+
request.open(config.method.toUpperCase(), buildURL2(fullPath, config.params, config.paramsSerializer), true);
|
|
1400
|
+
request.timeout = config.timeout;
|
|
1401
|
+
function onloadend() {
|
|
1402
|
+
if (!request) {
|
|
1403
|
+
return;
|
|
1404
|
+
}
|
|
1405
|
+
var responseHeaders = "getAllResponseHeaders" in request ? parseHeaders2(request.getAllResponseHeaders()) : null;
|
|
1406
|
+
var responseData = !responseType || responseType === "text" || responseType === "json" ? request.responseText : request.response;
|
|
1407
|
+
var response = {
|
|
1408
|
+
data: responseData,
|
|
1409
|
+
status: request.status,
|
|
1410
|
+
statusText: request.statusText,
|
|
1411
|
+
headers: responseHeaders,
|
|
1412
|
+
config,
|
|
1413
|
+
request
|
|
1414
|
+
};
|
|
1415
|
+
settle2(resolve, reject, response);
|
|
1416
|
+
request = null;
|
|
1417
|
+
}
|
|
1418
|
+
if ("onloadend" in request) {
|
|
1419
|
+
request.onloadend = onloadend;
|
|
1420
|
+
} else {
|
|
1421
|
+
request.onreadystatechange = function handleLoad() {
|
|
1422
|
+
if (!request || request.readyState !== 4) {
|
|
1423
|
+
return;
|
|
1424
|
+
}
|
|
1425
|
+
if (request.status === 0 && !(request.responseURL && request.responseURL.indexOf("file:") === 0)) {
|
|
1426
|
+
return;
|
|
1427
|
+
}
|
|
1428
|
+
setTimeout(onloadend);
|
|
1429
|
+
};
|
|
1430
|
+
}
|
|
1431
|
+
request.onabort = function handleAbort() {
|
|
1432
|
+
if (!request) {
|
|
1433
|
+
return;
|
|
1434
|
+
}
|
|
1435
|
+
reject(createError2("Request aborted", config, "ECONNABORTED", request));
|
|
1436
|
+
request = null;
|
|
1437
|
+
};
|
|
1438
|
+
request.onerror = function handleError() {
|
|
1439
|
+
reject(createError2("Network Error", config, null, request));
|
|
1440
|
+
request = null;
|
|
1441
|
+
};
|
|
1442
|
+
request.ontimeout = function handleTimeout() {
|
|
1443
|
+
var timeoutErrorMessage = "timeout of " + config.timeout + "ms exceeded";
|
|
1444
|
+
if (config.timeoutErrorMessage) {
|
|
1445
|
+
timeoutErrorMessage = config.timeoutErrorMessage;
|
|
1446
|
+
}
|
|
1447
|
+
reject(createError2(
|
|
1448
|
+
timeoutErrorMessage,
|
|
1449
|
+
config,
|
|
1450
|
+
config.transitional && config.transitional.clarifyTimeoutError ? "ETIMEDOUT" : "ECONNABORTED",
|
|
1451
|
+
request
|
|
1452
|
+
));
|
|
1453
|
+
request = null;
|
|
1454
|
+
};
|
|
1455
|
+
if (utils2.isStandardBrowserEnv()) {
|
|
1456
|
+
var xsrfValue = (config.withCredentials || isURLSameOrigin2(fullPath)) && config.xsrfCookieName ? cookies2.read(config.xsrfCookieName) : void 0;
|
|
1457
|
+
if (xsrfValue) {
|
|
1458
|
+
requestHeaders[config.xsrfHeaderName] = xsrfValue;
|
|
1459
|
+
}
|
|
1460
|
+
}
|
|
1461
|
+
if ("setRequestHeader" in request) {
|
|
1462
|
+
utils2.forEach(requestHeaders, function setRequestHeader(val, key) {
|
|
1463
|
+
if (typeof requestData === "undefined" && key.toLowerCase() === "content-type") {
|
|
1464
|
+
delete requestHeaders[key];
|
|
1465
|
+
} else {
|
|
1466
|
+
request.setRequestHeader(key, val);
|
|
1467
|
+
}
|
|
1468
|
+
});
|
|
1469
|
+
}
|
|
1470
|
+
if (!utils2.isUndefined(config.withCredentials)) {
|
|
1471
|
+
request.withCredentials = !!config.withCredentials;
|
|
1472
|
+
}
|
|
1473
|
+
if (responseType && responseType !== "json") {
|
|
1474
|
+
request.responseType = config.responseType;
|
|
1475
|
+
}
|
|
1476
|
+
if (typeof config.onDownloadProgress === "function") {
|
|
1477
|
+
request.addEventListener("progress", config.onDownloadProgress);
|
|
1478
|
+
}
|
|
1479
|
+
if (typeof config.onUploadProgress === "function" && request.upload) {
|
|
1480
|
+
request.upload.addEventListener("progress", config.onUploadProgress);
|
|
1481
|
+
}
|
|
1482
|
+
if (config.cancelToken) {
|
|
1483
|
+
config.cancelToken.promise.then(function onCanceled(cancel) {
|
|
1484
|
+
if (!request) {
|
|
1485
|
+
return;
|
|
1486
|
+
}
|
|
1487
|
+
request.abort();
|
|
1488
|
+
reject(cancel);
|
|
1489
|
+
request = null;
|
|
1490
|
+
});
|
|
1491
|
+
}
|
|
1492
|
+
if (!requestData) {
|
|
1493
|
+
requestData = null;
|
|
1494
|
+
}
|
|
1495
|
+
request.send(requestData);
|
|
1496
|
+
});
|
|
1497
|
+
};
|
|
1498
|
+
return xhr;
|
|
1499
|
+
}
|
|
1500
|
+
var defaults_1;
|
|
1501
|
+
var hasRequiredDefaults;
|
|
1502
|
+
function requireDefaults() {
|
|
1503
|
+
if (hasRequiredDefaults) return defaults_1;
|
|
1504
|
+
hasRequiredDefaults = 1;
|
|
1505
|
+
var utils2 = requireUtils();
|
|
1506
|
+
var normalizeHeaderName2 = requireNormalizeHeaderName();
|
|
1507
|
+
var enhanceError2 = requireEnhanceError();
|
|
1508
|
+
var DEFAULT_CONTENT_TYPE = {
|
|
1509
|
+
"Content-Type": "application/x-www-form-urlencoded"
|
|
1510
|
+
};
|
|
1511
|
+
function setContentTypeIfUnset(headers, value) {
|
|
1512
|
+
if (!utils2.isUndefined(headers) && utils2.isUndefined(headers["Content-Type"])) {
|
|
1513
|
+
headers["Content-Type"] = value;
|
|
1514
|
+
}
|
|
1515
|
+
}
|
|
1516
|
+
function getDefaultAdapter() {
|
|
1517
|
+
var adapter;
|
|
1518
|
+
if (typeof XMLHttpRequest !== "undefined") {
|
|
1519
|
+
adapter = requireXhr();
|
|
1520
|
+
} else if (typeof process !== "undefined" && Object.prototype.toString.call(process) === "[object process]") {
|
|
1521
|
+
adapter = requireXhr();
|
|
1522
|
+
}
|
|
1523
|
+
return adapter;
|
|
1524
|
+
}
|
|
1525
|
+
function stringifySafely(rawValue, parser, encoder) {
|
|
1526
|
+
if (utils2.isString(rawValue)) {
|
|
1527
|
+
try {
|
|
1528
|
+
(parser || JSON.parse)(rawValue);
|
|
1529
|
+
return utils2.trim(rawValue);
|
|
1530
|
+
} catch (e) {
|
|
1531
|
+
if (e.name !== "SyntaxError") {
|
|
1532
|
+
throw e;
|
|
1533
|
+
}
|
|
1534
|
+
}
|
|
1535
|
+
}
|
|
1536
|
+
return (encoder || JSON.stringify)(rawValue);
|
|
1537
|
+
}
|
|
1538
|
+
var defaults = {
|
|
1539
|
+
transitional: {
|
|
1540
|
+
silentJSONParsing: true,
|
|
1541
|
+
forcedJSONParsing: true,
|
|
1542
|
+
clarifyTimeoutError: false
|
|
1543
|
+
},
|
|
1544
|
+
adapter: getDefaultAdapter(),
|
|
1545
|
+
transformRequest: [function transformRequest(data, headers) {
|
|
1546
|
+
normalizeHeaderName2(headers, "Accept");
|
|
1547
|
+
normalizeHeaderName2(headers, "Content-Type");
|
|
1548
|
+
if (utils2.isFormData(data) || utils2.isArrayBuffer(data) || utils2.isBuffer(data) || utils2.isStream(data) || utils2.isFile(data) || utils2.isBlob(data)) {
|
|
1549
|
+
return data;
|
|
1550
|
+
}
|
|
1551
|
+
if (utils2.isArrayBufferView(data)) {
|
|
1552
|
+
return data.buffer;
|
|
1553
|
+
}
|
|
1554
|
+
if (utils2.isURLSearchParams(data)) {
|
|
1555
|
+
setContentTypeIfUnset(headers, "application/x-www-form-urlencoded;charset=utf-8");
|
|
1556
|
+
return data.toString();
|
|
1557
|
+
}
|
|
1558
|
+
if (utils2.isObject(data) || headers && headers["Content-Type"] === "application/json") {
|
|
1559
|
+
setContentTypeIfUnset(headers, "application/json");
|
|
1560
|
+
return stringifySafely(data);
|
|
1561
|
+
}
|
|
1562
|
+
return data;
|
|
1563
|
+
}],
|
|
1564
|
+
transformResponse: [function transformResponse(data) {
|
|
1565
|
+
var transitional = this.transitional;
|
|
1566
|
+
var silentJSONParsing = transitional && transitional.silentJSONParsing;
|
|
1567
|
+
var forcedJSONParsing = transitional && transitional.forcedJSONParsing;
|
|
1568
|
+
var strictJSONParsing = !silentJSONParsing && this.responseType === "json";
|
|
1569
|
+
if (strictJSONParsing || forcedJSONParsing && utils2.isString(data) && data.length) {
|
|
1570
|
+
try {
|
|
1571
|
+
return JSON.parse(data);
|
|
1572
|
+
} catch (e) {
|
|
1573
|
+
if (strictJSONParsing) {
|
|
1574
|
+
if (e.name === "SyntaxError") {
|
|
1575
|
+
throw enhanceError2(e, this, "E_JSON_PARSE");
|
|
1576
|
+
}
|
|
1577
|
+
throw e;
|
|
1578
|
+
}
|
|
1579
|
+
}
|
|
1580
|
+
}
|
|
1581
|
+
return data;
|
|
1582
|
+
}],
|
|
1583
|
+
/**
|
|
1584
|
+
* A timeout in milliseconds to abort a request. If set to 0 (default) a
|
|
1585
|
+
* timeout is not created.
|
|
1586
|
+
*/
|
|
1587
|
+
timeout: 0,
|
|
1588
|
+
xsrfCookieName: "XSRF-TOKEN",
|
|
1589
|
+
xsrfHeaderName: "X-XSRF-TOKEN",
|
|
1590
|
+
maxContentLength: -1,
|
|
1591
|
+
maxBodyLength: -1,
|
|
1592
|
+
validateStatus: function validateStatus(status) {
|
|
1593
|
+
return status >= 200 && status < 300;
|
|
1594
|
+
}
|
|
1595
|
+
};
|
|
1596
|
+
defaults.headers = {
|
|
1597
|
+
common: {
|
|
1598
|
+
"Accept": "application/json, text/plain, */*"
|
|
1599
|
+
}
|
|
1600
|
+
};
|
|
1601
|
+
utils2.forEach(["delete", "get", "head"], function forEachMethodNoData(method) {
|
|
1602
|
+
defaults.headers[method] = {};
|
|
1603
|
+
});
|
|
1604
|
+
utils2.forEach(["post", "put", "patch"], function forEachMethodWithData(method) {
|
|
1605
|
+
defaults.headers[method] = utils2.merge(DEFAULT_CONTENT_TYPE);
|
|
1606
|
+
});
|
|
1607
|
+
defaults_1 = defaults;
|
|
1608
|
+
return defaults_1;
|
|
1609
|
+
}
|
|
1610
|
+
var transformData;
|
|
1611
|
+
var hasRequiredTransformData;
|
|
1612
|
+
function requireTransformData() {
|
|
1613
|
+
if (hasRequiredTransformData) return transformData;
|
|
1614
|
+
hasRequiredTransformData = 1;
|
|
1615
|
+
var utils2 = requireUtils();
|
|
1616
|
+
var defaults = requireDefaults();
|
|
1617
|
+
transformData = function transformData2(data, headers, fns) {
|
|
1618
|
+
var context = this || defaults;
|
|
1619
|
+
utils2.forEach(fns, function transform(fn) {
|
|
1620
|
+
data = fn.call(context, data, headers);
|
|
1621
|
+
});
|
|
1622
|
+
return data;
|
|
1623
|
+
};
|
|
1624
|
+
return transformData;
|
|
1625
|
+
}
|
|
1626
|
+
var isCancel;
|
|
1627
|
+
var hasRequiredIsCancel;
|
|
1628
|
+
function requireIsCancel() {
|
|
1629
|
+
if (hasRequiredIsCancel) return isCancel;
|
|
1630
|
+
hasRequiredIsCancel = 1;
|
|
1631
|
+
isCancel = function isCancel2(value) {
|
|
1632
|
+
return !!(value && value.__CANCEL__);
|
|
1633
|
+
};
|
|
1634
|
+
return isCancel;
|
|
1635
|
+
}
|
|
1636
|
+
var dispatchRequest;
|
|
1637
|
+
var hasRequiredDispatchRequest;
|
|
1638
|
+
function requireDispatchRequest() {
|
|
1639
|
+
if (hasRequiredDispatchRequest) return dispatchRequest;
|
|
1640
|
+
hasRequiredDispatchRequest = 1;
|
|
1641
|
+
var utils2 = requireUtils();
|
|
1642
|
+
var transformData2 = requireTransformData();
|
|
1643
|
+
var isCancel2 = requireIsCancel();
|
|
1644
|
+
var defaults = requireDefaults();
|
|
1645
|
+
function throwIfCancellationRequested(config) {
|
|
1646
|
+
if (config.cancelToken) {
|
|
1647
|
+
config.cancelToken.throwIfRequested();
|
|
1648
|
+
}
|
|
1649
|
+
}
|
|
1650
|
+
dispatchRequest = function dispatchRequest2(config) {
|
|
1651
|
+
throwIfCancellationRequested(config);
|
|
1652
|
+
config.headers = config.headers || {};
|
|
1653
|
+
config.data = transformData2.call(
|
|
1654
|
+
config,
|
|
1655
|
+
config.data,
|
|
1656
|
+
config.headers,
|
|
1657
|
+
config.transformRequest
|
|
1658
|
+
);
|
|
1659
|
+
config.headers = utils2.merge(
|
|
1660
|
+
config.headers.common || {},
|
|
1661
|
+
config.headers[config.method] || {},
|
|
1662
|
+
config.headers
|
|
1663
|
+
);
|
|
1664
|
+
utils2.forEach(
|
|
1665
|
+
["delete", "get", "head", "post", "put", "patch", "common"],
|
|
1666
|
+
function cleanHeaderConfig(method) {
|
|
1667
|
+
delete config.headers[method];
|
|
1668
|
+
}
|
|
1669
|
+
);
|
|
1670
|
+
var adapter = config.adapter || defaults.adapter;
|
|
1671
|
+
return adapter(config).then(function onAdapterResolution(response) {
|
|
1672
|
+
throwIfCancellationRequested(config);
|
|
1673
|
+
response.data = transformData2.call(
|
|
1674
|
+
config,
|
|
1675
|
+
response.data,
|
|
1676
|
+
response.headers,
|
|
1677
|
+
config.transformResponse
|
|
1678
|
+
);
|
|
1679
|
+
return response;
|
|
1680
|
+
}, function onAdapterRejection(reason) {
|
|
1681
|
+
if (!isCancel2(reason)) {
|
|
1682
|
+
throwIfCancellationRequested(config);
|
|
1683
|
+
if (reason && reason.response) {
|
|
1684
|
+
reason.response.data = transformData2.call(
|
|
1685
|
+
config,
|
|
1686
|
+
reason.response.data,
|
|
1687
|
+
reason.response.headers,
|
|
1688
|
+
config.transformResponse
|
|
1689
|
+
);
|
|
1690
|
+
}
|
|
1691
|
+
}
|
|
1692
|
+
return Promise.reject(reason);
|
|
1693
|
+
});
|
|
1694
|
+
};
|
|
1695
|
+
return dispatchRequest;
|
|
1696
|
+
}
|
|
1697
|
+
var mergeConfig;
|
|
1698
|
+
var hasRequiredMergeConfig;
|
|
1699
|
+
function requireMergeConfig() {
|
|
1700
|
+
if (hasRequiredMergeConfig) return mergeConfig;
|
|
1701
|
+
hasRequiredMergeConfig = 1;
|
|
1702
|
+
var utils2 = requireUtils();
|
|
1703
|
+
mergeConfig = function mergeConfig2(config1, config2) {
|
|
1704
|
+
config2 = config2 || {};
|
|
1705
|
+
var config = {};
|
|
1706
|
+
var valueFromConfig2Keys = ["url", "method", "data"];
|
|
1707
|
+
var mergeDeepPropertiesKeys = ["headers", "auth", "proxy", "params"];
|
|
1708
|
+
var defaultToConfig2Keys = [
|
|
1709
|
+
"baseURL",
|
|
1710
|
+
"transformRequest",
|
|
1711
|
+
"transformResponse",
|
|
1712
|
+
"paramsSerializer",
|
|
1713
|
+
"timeout",
|
|
1714
|
+
"timeoutMessage",
|
|
1715
|
+
"withCredentials",
|
|
1716
|
+
"adapter",
|
|
1717
|
+
"responseType",
|
|
1718
|
+
"xsrfCookieName",
|
|
1719
|
+
"xsrfHeaderName",
|
|
1720
|
+
"onUploadProgress",
|
|
1721
|
+
"onDownloadProgress",
|
|
1722
|
+
"decompress",
|
|
1723
|
+
"maxContentLength",
|
|
1724
|
+
"maxBodyLength",
|
|
1725
|
+
"maxRedirects",
|
|
1726
|
+
"transport",
|
|
1727
|
+
"httpAgent",
|
|
1728
|
+
"httpsAgent",
|
|
1729
|
+
"cancelToken",
|
|
1730
|
+
"socketPath",
|
|
1731
|
+
"responseEncoding"
|
|
1732
|
+
];
|
|
1733
|
+
var directMergeKeys = ["validateStatus"];
|
|
1734
|
+
function getMergedValue(target, source) {
|
|
1735
|
+
if (utils2.isPlainObject(target) && utils2.isPlainObject(source)) {
|
|
1736
|
+
return utils2.merge(target, source);
|
|
1737
|
+
} else if (utils2.isPlainObject(source)) {
|
|
1738
|
+
return utils2.merge({}, source);
|
|
1739
|
+
} else if (utils2.isArray(source)) {
|
|
1740
|
+
return source.slice();
|
|
1741
|
+
}
|
|
1742
|
+
return source;
|
|
1743
|
+
}
|
|
1744
|
+
function mergeDeepProperties(prop) {
|
|
1745
|
+
if (!utils2.isUndefined(config2[prop])) {
|
|
1746
|
+
config[prop] = getMergedValue(config1[prop], config2[prop]);
|
|
1747
|
+
} else if (!utils2.isUndefined(config1[prop])) {
|
|
1748
|
+
config[prop] = getMergedValue(void 0, config1[prop]);
|
|
1749
|
+
}
|
|
1750
|
+
}
|
|
1751
|
+
utils2.forEach(valueFromConfig2Keys, function valueFromConfig2(prop) {
|
|
1752
|
+
if (!utils2.isUndefined(config2[prop])) {
|
|
1753
|
+
config[prop] = getMergedValue(void 0, config2[prop]);
|
|
1754
|
+
}
|
|
1755
|
+
});
|
|
1756
|
+
utils2.forEach(mergeDeepPropertiesKeys, mergeDeepProperties);
|
|
1757
|
+
utils2.forEach(defaultToConfig2Keys, function defaultToConfig2(prop) {
|
|
1758
|
+
if (!utils2.isUndefined(config2[prop])) {
|
|
1759
|
+
config[prop] = getMergedValue(void 0, config2[prop]);
|
|
1760
|
+
} else if (!utils2.isUndefined(config1[prop])) {
|
|
1761
|
+
config[prop] = getMergedValue(void 0, config1[prop]);
|
|
1762
|
+
}
|
|
1763
|
+
});
|
|
1764
|
+
utils2.forEach(directMergeKeys, function merge(prop) {
|
|
1765
|
+
if (prop in config2) {
|
|
1766
|
+
config[prop] = getMergedValue(config1[prop], config2[prop]);
|
|
1767
|
+
} else if (prop in config1) {
|
|
1768
|
+
config[prop] = getMergedValue(void 0, config1[prop]);
|
|
1769
|
+
}
|
|
1770
|
+
});
|
|
1771
|
+
var axiosKeys = valueFromConfig2Keys.concat(mergeDeepPropertiesKeys).concat(defaultToConfig2Keys).concat(directMergeKeys);
|
|
1772
|
+
var otherKeys = Object.keys(config1).concat(Object.keys(config2)).filter(function filterAxiosKeys(key) {
|
|
1773
|
+
return axiosKeys.indexOf(key) === -1;
|
|
1774
|
+
});
|
|
1775
|
+
utils2.forEach(otherKeys, mergeDeepProperties);
|
|
1776
|
+
return config;
|
|
1777
|
+
};
|
|
1778
|
+
return mergeConfig;
|
|
1779
|
+
}
|
|
1780
|
+
const version = "0.21.4";
|
|
1781
|
+
const require$$0 = {
|
|
1782
|
+
version
|
|
1783
|
+
};
|
|
1784
|
+
var validator;
|
|
1785
|
+
var hasRequiredValidator;
|
|
1786
|
+
function requireValidator() {
|
|
1787
|
+
if (hasRequiredValidator) return validator;
|
|
1788
|
+
hasRequiredValidator = 1;
|
|
1789
|
+
var pkg = require$$0;
|
|
1790
|
+
var validators = {};
|
|
1791
|
+
["object", "boolean", "number", "function", "string", "symbol"].forEach(function(type, i) {
|
|
1792
|
+
validators[type] = function validator2(thing) {
|
|
1793
|
+
return typeof thing === type || "a" + (i < 1 ? "n " : " ") + type;
|
|
1794
|
+
};
|
|
1795
|
+
});
|
|
1796
|
+
var deprecatedWarnings = {};
|
|
1797
|
+
var currentVerArr = pkg.version.split(".");
|
|
1798
|
+
function isOlderVersion(version2, thanVersion) {
|
|
1799
|
+
var pkgVersionArr = thanVersion ? thanVersion.split(".") : currentVerArr;
|
|
1800
|
+
var destVer = version2.split(".");
|
|
1801
|
+
for (var i = 0; i < 3; i++) {
|
|
1802
|
+
if (pkgVersionArr[i] > destVer[i]) {
|
|
1803
|
+
return true;
|
|
1804
|
+
} else if (pkgVersionArr[i] < destVer[i]) {
|
|
1805
|
+
return false;
|
|
1806
|
+
}
|
|
1807
|
+
}
|
|
1808
|
+
return false;
|
|
1809
|
+
}
|
|
1810
|
+
validators.transitional = function transitional(validator2, version2, message) {
|
|
1811
|
+
var isDeprecated = version2 && isOlderVersion(version2);
|
|
1812
|
+
function formatMessage(opt, desc) {
|
|
1813
|
+
return "[Axios v" + pkg.version + "] Transitional option '" + opt + "'" + desc + (message ? ". " + message : "");
|
|
1814
|
+
}
|
|
1815
|
+
return function(value, opt, opts) {
|
|
1816
|
+
if (validator2 === false) {
|
|
1817
|
+
throw new Error(formatMessage(opt, " has been removed in " + version2));
|
|
1818
|
+
}
|
|
1819
|
+
if (isDeprecated && !deprecatedWarnings[opt]) {
|
|
1820
|
+
deprecatedWarnings[opt] = true;
|
|
1821
|
+
console.warn(
|
|
1822
|
+
formatMessage(
|
|
1823
|
+
opt,
|
|
1824
|
+
" has been deprecated since v" + version2 + " and will be removed in the near future"
|
|
1825
|
+
)
|
|
1826
|
+
);
|
|
1827
|
+
}
|
|
1828
|
+
return validator2 ? validator2(value, opt, opts) : true;
|
|
1829
|
+
};
|
|
1830
|
+
};
|
|
1831
|
+
function assertOptions(options, schema, allowUnknown) {
|
|
1832
|
+
if (typeof options !== "object") {
|
|
1833
|
+
throw new TypeError("options must be an object");
|
|
1834
|
+
}
|
|
1835
|
+
var keys = Object.keys(options);
|
|
1836
|
+
var i = keys.length;
|
|
1837
|
+
while (i-- > 0) {
|
|
1838
|
+
var opt = keys[i];
|
|
1839
|
+
var validator2 = schema[opt];
|
|
1840
|
+
if (validator2) {
|
|
1841
|
+
var value = options[opt];
|
|
1842
|
+
var result = value === void 0 || validator2(value, opt, options);
|
|
1843
|
+
if (result !== true) {
|
|
1844
|
+
throw new TypeError("option " + opt + " must be " + result);
|
|
1845
|
+
}
|
|
1846
|
+
continue;
|
|
1847
|
+
}
|
|
1848
|
+
if (allowUnknown !== true) {
|
|
1849
|
+
throw Error("Unknown option " + opt);
|
|
1850
|
+
}
|
|
1851
|
+
}
|
|
1852
|
+
}
|
|
1853
|
+
validator = {
|
|
1854
|
+
isOlderVersion,
|
|
1855
|
+
assertOptions,
|
|
1856
|
+
validators
|
|
1857
|
+
};
|
|
1858
|
+
return validator;
|
|
1859
|
+
}
|
|
1860
|
+
var Axios_1;
|
|
1861
|
+
var hasRequiredAxios$2;
|
|
1862
|
+
function requireAxios$2() {
|
|
1863
|
+
if (hasRequiredAxios$2) return Axios_1;
|
|
1864
|
+
hasRequiredAxios$2 = 1;
|
|
1865
|
+
var utils2 = requireUtils();
|
|
1866
|
+
var buildURL2 = requireBuildURL();
|
|
1867
|
+
var InterceptorManager = requireInterceptorManager();
|
|
1868
|
+
var dispatchRequest2 = requireDispatchRequest();
|
|
1869
|
+
var mergeConfig2 = requireMergeConfig();
|
|
1870
|
+
var validator2 = requireValidator();
|
|
1871
|
+
var validators = validator2.validators;
|
|
1872
|
+
function Axios(instanceConfig) {
|
|
1873
|
+
this.defaults = instanceConfig;
|
|
1874
|
+
this.interceptors = {
|
|
1875
|
+
request: new InterceptorManager(),
|
|
1876
|
+
response: new InterceptorManager()
|
|
1877
|
+
};
|
|
1878
|
+
}
|
|
1879
|
+
Axios.prototype.request = function request(config) {
|
|
1880
|
+
if (typeof config === "string") {
|
|
1881
|
+
config = arguments[1] || {};
|
|
1882
|
+
config.url = arguments[0];
|
|
1883
|
+
} else {
|
|
1884
|
+
config = config || {};
|
|
1885
|
+
}
|
|
1886
|
+
config = mergeConfig2(this.defaults, config);
|
|
1887
|
+
if (config.method) {
|
|
1888
|
+
config.method = config.method.toLowerCase();
|
|
1889
|
+
} else if (this.defaults.method) {
|
|
1890
|
+
config.method = this.defaults.method.toLowerCase();
|
|
1891
|
+
} else {
|
|
1892
|
+
config.method = "get";
|
|
1893
|
+
}
|
|
1894
|
+
var transitional = config.transitional;
|
|
1895
|
+
if (transitional !== void 0) {
|
|
1896
|
+
validator2.assertOptions(transitional, {
|
|
1897
|
+
silentJSONParsing: validators.transitional(validators.boolean, "1.0.0"),
|
|
1898
|
+
forcedJSONParsing: validators.transitional(validators.boolean, "1.0.0"),
|
|
1899
|
+
clarifyTimeoutError: validators.transitional(validators.boolean, "1.0.0")
|
|
1900
|
+
}, false);
|
|
1901
|
+
}
|
|
1902
|
+
var requestInterceptorChain = [];
|
|
1903
|
+
var synchronousRequestInterceptors = true;
|
|
1904
|
+
this.interceptors.request.forEach(function unshiftRequestInterceptors(interceptor) {
|
|
1905
|
+
if (typeof interceptor.runWhen === "function" && interceptor.runWhen(config) === false) {
|
|
1906
|
+
return;
|
|
1907
|
+
}
|
|
1908
|
+
synchronousRequestInterceptors = synchronousRequestInterceptors && interceptor.synchronous;
|
|
1909
|
+
requestInterceptorChain.unshift(interceptor.fulfilled, interceptor.rejected);
|
|
1910
|
+
});
|
|
1911
|
+
var responseInterceptorChain = [];
|
|
1912
|
+
this.interceptors.response.forEach(function pushResponseInterceptors(interceptor) {
|
|
1913
|
+
responseInterceptorChain.push(interceptor.fulfilled, interceptor.rejected);
|
|
1914
|
+
});
|
|
1915
|
+
var promise;
|
|
1916
|
+
if (!synchronousRequestInterceptors) {
|
|
1917
|
+
var chain = [dispatchRequest2, void 0];
|
|
1918
|
+
Array.prototype.unshift.apply(chain, requestInterceptorChain);
|
|
1919
|
+
chain = chain.concat(responseInterceptorChain);
|
|
1920
|
+
promise = Promise.resolve(config);
|
|
1921
|
+
while (chain.length) {
|
|
1922
|
+
promise = promise.then(chain.shift(), chain.shift());
|
|
1923
|
+
}
|
|
1924
|
+
return promise;
|
|
1925
|
+
}
|
|
1926
|
+
var newConfig = config;
|
|
1927
|
+
while (requestInterceptorChain.length) {
|
|
1928
|
+
var onFulfilled = requestInterceptorChain.shift();
|
|
1929
|
+
var onRejected = requestInterceptorChain.shift();
|
|
1930
|
+
try {
|
|
1931
|
+
newConfig = onFulfilled(newConfig);
|
|
1932
|
+
} catch (error) {
|
|
1933
|
+
onRejected(error);
|
|
1934
|
+
break;
|
|
1935
|
+
}
|
|
1936
|
+
}
|
|
1937
|
+
try {
|
|
1938
|
+
promise = dispatchRequest2(newConfig);
|
|
1939
|
+
} catch (error) {
|
|
1940
|
+
return Promise.reject(error);
|
|
1941
|
+
}
|
|
1942
|
+
while (responseInterceptorChain.length) {
|
|
1943
|
+
promise = promise.then(responseInterceptorChain.shift(), responseInterceptorChain.shift());
|
|
1944
|
+
}
|
|
1945
|
+
return promise;
|
|
1946
|
+
};
|
|
1947
|
+
Axios.prototype.getUri = function getUri(config) {
|
|
1948
|
+
config = mergeConfig2(this.defaults, config);
|
|
1949
|
+
return buildURL2(config.url, config.params, config.paramsSerializer).replace(/^\?/, "");
|
|
1950
|
+
};
|
|
1951
|
+
utils2.forEach(["delete", "get", "head", "options"], function forEachMethodNoData(method) {
|
|
1952
|
+
Axios.prototype[method] = function(url, config) {
|
|
1953
|
+
return this.request(mergeConfig2(config || {}, {
|
|
1954
|
+
method,
|
|
1955
|
+
url,
|
|
1956
|
+
data: (config || {}).data
|
|
1957
|
+
}));
|
|
1958
|
+
};
|
|
1959
|
+
});
|
|
1960
|
+
utils2.forEach(["post", "put", "patch"], function forEachMethodWithData(method) {
|
|
1961
|
+
Axios.prototype[method] = function(url, data, config) {
|
|
1962
|
+
return this.request(mergeConfig2(config || {}, {
|
|
1963
|
+
method,
|
|
1964
|
+
url,
|
|
1965
|
+
data
|
|
1966
|
+
}));
|
|
1967
|
+
};
|
|
1968
|
+
});
|
|
1969
|
+
Axios_1 = Axios;
|
|
1970
|
+
return Axios_1;
|
|
1971
|
+
}
|
|
1972
|
+
var Cancel_1;
|
|
1973
|
+
var hasRequiredCancel;
|
|
1974
|
+
function requireCancel() {
|
|
1975
|
+
if (hasRequiredCancel) return Cancel_1;
|
|
1976
|
+
hasRequiredCancel = 1;
|
|
1977
|
+
function Cancel(message) {
|
|
1978
|
+
this.message = message;
|
|
1979
|
+
}
|
|
1980
|
+
Cancel.prototype.toString = function toString() {
|
|
1981
|
+
return "Cancel" + (this.message ? ": " + this.message : "");
|
|
1982
|
+
};
|
|
1983
|
+
Cancel.prototype.__CANCEL__ = true;
|
|
1984
|
+
Cancel_1 = Cancel;
|
|
1985
|
+
return Cancel_1;
|
|
1986
|
+
}
|
|
1987
|
+
var CancelToken_1;
|
|
1988
|
+
var hasRequiredCancelToken;
|
|
1989
|
+
function requireCancelToken() {
|
|
1990
|
+
if (hasRequiredCancelToken) return CancelToken_1;
|
|
1991
|
+
hasRequiredCancelToken = 1;
|
|
1992
|
+
var Cancel = requireCancel();
|
|
1993
|
+
function CancelToken(executor) {
|
|
1994
|
+
if (typeof executor !== "function") {
|
|
1995
|
+
throw new TypeError("executor must be a function.");
|
|
1996
|
+
}
|
|
1997
|
+
var resolvePromise;
|
|
1998
|
+
this.promise = new Promise(function promiseExecutor(resolve) {
|
|
1999
|
+
resolvePromise = resolve;
|
|
2000
|
+
});
|
|
2001
|
+
var token = this;
|
|
2002
|
+
executor(function cancel(message) {
|
|
2003
|
+
if (token.reason) {
|
|
2004
|
+
return;
|
|
2005
|
+
}
|
|
2006
|
+
token.reason = new Cancel(message);
|
|
2007
|
+
resolvePromise(token.reason);
|
|
2008
|
+
});
|
|
2009
|
+
}
|
|
2010
|
+
CancelToken.prototype.throwIfRequested = function throwIfRequested() {
|
|
2011
|
+
if (this.reason) {
|
|
2012
|
+
throw this.reason;
|
|
2013
|
+
}
|
|
2014
|
+
};
|
|
2015
|
+
CancelToken.source = function source() {
|
|
2016
|
+
var cancel;
|
|
2017
|
+
var token = new CancelToken(function executor(c) {
|
|
2018
|
+
cancel = c;
|
|
2019
|
+
});
|
|
2020
|
+
return {
|
|
2021
|
+
token,
|
|
2022
|
+
cancel
|
|
2023
|
+
};
|
|
2024
|
+
};
|
|
2025
|
+
CancelToken_1 = CancelToken;
|
|
2026
|
+
return CancelToken_1;
|
|
2027
|
+
}
|
|
2028
|
+
var spread;
|
|
2029
|
+
var hasRequiredSpread;
|
|
2030
|
+
function requireSpread() {
|
|
2031
|
+
if (hasRequiredSpread) return spread;
|
|
2032
|
+
hasRequiredSpread = 1;
|
|
2033
|
+
spread = function spread2(callback) {
|
|
2034
|
+
return function wrap(arr) {
|
|
2035
|
+
return callback.apply(null, arr);
|
|
2036
|
+
};
|
|
2037
|
+
};
|
|
2038
|
+
return spread;
|
|
2039
|
+
}
|
|
2040
|
+
var isAxiosError;
|
|
2041
|
+
var hasRequiredIsAxiosError;
|
|
2042
|
+
function requireIsAxiosError() {
|
|
2043
|
+
if (hasRequiredIsAxiosError) return isAxiosError;
|
|
2044
|
+
hasRequiredIsAxiosError = 1;
|
|
2045
|
+
isAxiosError = function isAxiosError2(payload) {
|
|
2046
|
+
return typeof payload === "object" && payload.isAxiosError === true;
|
|
2047
|
+
};
|
|
2048
|
+
return isAxiosError;
|
|
2049
|
+
}
|
|
2050
|
+
var hasRequiredAxios$1;
|
|
2051
|
+
function requireAxios$1() {
|
|
2052
|
+
if (hasRequiredAxios$1) return axios$2.exports;
|
|
2053
|
+
hasRequiredAxios$1 = 1;
|
|
2054
|
+
var utils2 = requireUtils();
|
|
2055
|
+
var bind2 = requireBind();
|
|
2056
|
+
var Axios = requireAxios$2();
|
|
2057
|
+
var mergeConfig2 = requireMergeConfig();
|
|
2058
|
+
var defaults = requireDefaults();
|
|
2059
|
+
function createInstance(defaultConfig) {
|
|
2060
|
+
var context = new Axios(defaultConfig);
|
|
2061
|
+
var instance = bind2(Axios.prototype.request, context);
|
|
2062
|
+
utils2.extend(instance, Axios.prototype, context);
|
|
2063
|
+
utils2.extend(instance, context);
|
|
2064
|
+
return instance;
|
|
2065
|
+
}
|
|
2066
|
+
var axios2 = createInstance(defaults);
|
|
2067
|
+
axios2.Axios = Axios;
|
|
2068
|
+
axios2.create = function create(instanceConfig) {
|
|
2069
|
+
return createInstance(mergeConfig2(axios2.defaults, instanceConfig));
|
|
2070
|
+
};
|
|
2071
|
+
axios2.Cancel = requireCancel();
|
|
2072
|
+
axios2.CancelToken = requireCancelToken();
|
|
2073
|
+
axios2.isCancel = requireIsCancel();
|
|
2074
|
+
axios2.all = function all(promises) {
|
|
2075
|
+
return Promise.all(promises);
|
|
2076
|
+
};
|
|
2077
|
+
axios2.spread = requireSpread();
|
|
2078
|
+
axios2.isAxiosError = requireIsAxiosError();
|
|
2079
|
+
axios$2.exports = axios2;
|
|
2080
|
+
axios$2.exports.default = axios2;
|
|
2081
|
+
return axios$2.exports;
|
|
2082
|
+
}
|
|
2083
|
+
var axios$1;
|
|
2084
|
+
var hasRequiredAxios;
|
|
2085
|
+
function requireAxios() {
|
|
2086
|
+
if (hasRequiredAxios) return axios$1;
|
|
2087
|
+
hasRequiredAxios = 1;
|
|
2088
|
+
axios$1 = requireAxios$1();
|
|
2089
|
+
return axios$1;
|
|
2090
|
+
}
|
|
2091
|
+
var axiosExports = requireAxios();
|
|
2092
|
+
const axios = /* @__PURE__ */ getDefaultExportFromCjs(axiosExports);
|
|
2093
|
+
class ApiClient extends EventEmitter {
|
|
2094
|
+
constructor(apiKey, apiUrl = "https://api.deepseek.com/v1/chat/completions") {
|
|
2095
|
+
super();
|
|
2096
|
+
this.apiKey = apiKey;
|
|
2097
|
+
this.url = apiUrl;
|
|
2098
|
+
this.isGenerating = false;
|
|
2099
|
+
this.cancelTokenSource = null;
|
|
2100
|
+
this.axiosInstance = axios.create({
|
|
2101
|
+
baseURL: apiUrl,
|
|
2102
|
+
headers: {
|
|
2103
|
+
"Authorization": `Bearer ${apiKey}`,
|
|
2104
|
+
"Content-Type": "application/json"
|
|
2105
|
+
},
|
|
2106
|
+
timeout: 3e4
|
|
2107
|
+
// 30秒超时
|
|
2108
|
+
});
|
|
2109
|
+
}
|
|
2110
|
+
setApiKey(apiKey) {
|
|
2111
|
+
if (!apiKey || typeof apiKey !== "string") {
|
|
2112
|
+
throw new Error("无效的API Key");
|
|
2113
|
+
}
|
|
2114
|
+
this.apiKey = apiKey;
|
|
2115
|
+
this.axiosInstance.defaults.headers["Authorization"] = `Bearer ${apiKey}`;
|
|
2116
|
+
}
|
|
2117
|
+
setApiUrl(apiUrl) {
|
|
2118
|
+
if (!apiUrl || typeof apiUrl !== "string") {
|
|
2119
|
+
throw new Error("无效的API URL");
|
|
2120
|
+
}
|
|
2121
|
+
this.url = apiUrl;
|
|
2122
|
+
this.axiosInstance.defaults.baseURL = apiUrl;
|
|
2123
|
+
}
|
|
2124
|
+
async send(body) {
|
|
2125
|
+
this.isGenerating = true;
|
|
2126
|
+
this.cancelTokenSource = axios.CancelToken.source();
|
|
2127
|
+
try {
|
|
2128
|
+
this.emit("request-start", { body });
|
|
2129
|
+
const requestBody = this._buildRequestBody(body);
|
|
2130
|
+
const response = await this.axiosInstance.post("", requestBody, {
|
|
2131
|
+
cancelToken: this.cancelTokenSource.token
|
|
2132
|
+
});
|
|
2133
|
+
this.emit("request-success", { response: response.data });
|
|
2134
|
+
return response.data;
|
|
2135
|
+
} catch (error) {
|
|
2136
|
+
if (axios.isCancel(error)) {
|
|
2137
|
+
const cancelError = new Error("请求被中断");
|
|
2138
|
+
cancelError.name = "CancelError";
|
|
2139
|
+
this.emit("request-cancel", { error: cancelError });
|
|
2140
|
+
throw cancelError;
|
|
2141
|
+
}
|
|
2142
|
+
this.emit("request-error", { error });
|
|
2143
|
+
throw this._handleAxiosError(error);
|
|
2144
|
+
} finally {
|
|
2145
|
+
this.isGenerating = false;
|
|
2146
|
+
this.cancelTokenSource = null;
|
|
2147
|
+
}
|
|
2148
|
+
}
|
|
2149
|
+
async strSend(body, onProgress = () => {
|
|
2150
|
+
}, onDone = () => {
|
|
2151
|
+
}) {
|
|
2152
|
+
this.isGenerating = true;
|
|
2153
|
+
this.cancelTokenSource = axios.CancelToken.source();
|
|
2154
|
+
try {
|
|
2155
|
+
this.emit("stream-start", { body });
|
|
2156
|
+
const requestBody = this._buildRequestBody(body);
|
|
2157
|
+
const response = await fetch(this.url, {
|
|
2158
|
+
method: "POST",
|
|
2159
|
+
headers: {
|
|
2160
|
+
"Content-Type": "application/json",
|
|
2161
|
+
"Authorization": `Bearer ${this.apiKey}`,
|
|
2162
|
+
"Accept": "text/event-stream"
|
|
2163
|
+
},
|
|
2164
|
+
body: requestBody,
|
|
2165
|
+
signal: this.cancelTokenSource.token ? new AbortController().signal : void 0
|
|
2166
|
+
});
|
|
2167
|
+
if (!response.ok) {
|
|
2168
|
+
throw new Error(`HTTP错误: ${response.status}`);
|
|
2169
|
+
}
|
|
2170
|
+
const reader = response.body.getReader();
|
|
2171
|
+
const decoder = new TextDecoder();
|
|
2172
|
+
let buffer = "";
|
|
2173
|
+
const message = {
|
|
2174
|
+
content: "",
|
|
2175
|
+
reasoning_content: "",
|
|
2176
|
+
tool_calls: []
|
|
2177
|
+
// 新增:收集工具调用
|
|
2178
|
+
};
|
|
2179
|
+
while (true) {
|
|
2180
|
+
const { done, value } = await reader.read();
|
|
2181
|
+
if (done) break;
|
|
2182
|
+
buffer += decoder.decode(value, { stream: true });
|
|
2183
|
+
let lines = buffer.split(/(\r?\n){2,}/);
|
|
2184
|
+
buffer = lines.pop() || "";
|
|
2185
|
+
for (let rawChunk of lines) {
|
|
2186
|
+
const cleanChunk = rawChunk.trim().replace(/^data: /, "");
|
|
2187
|
+
if (!cleanChunk) continue;
|
|
2188
|
+
if (cleanChunk === "[DONE]") {
|
|
2189
|
+
this.emit("stream-done", { message });
|
|
2190
|
+
onDone({ ...message });
|
|
2191
|
+
return;
|
|
2192
|
+
}
|
|
2193
|
+
try {
|
|
2194
|
+
const obj = JSON.parse(cleanChunk);
|
|
2195
|
+
console.log("🔍 收到流式chunk:", obj);
|
|
2196
|
+
if (obj.choices?.[0]?.delta?.content) {
|
|
2197
|
+
message.content += obj.choices[0].delta.content;
|
|
2198
|
+
}
|
|
2199
|
+
if (obj.choices?.[0]?.delta?.reasoning_content) {
|
|
2200
|
+
message.reasoning_content += obj.choices[0].delta.reasoning_content;
|
|
2201
|
+
}
|
|
2202
|
+
if (obj.choices?.[0]?.delta?.tool_calls) {
|
|
2203
|
+
const deltaToolCalls = obj.choices[0].delta.tool_calls;
|
|
2204
|
+
deltaToolCalls.forEach((toolCall) => {
|
|
2205
|
+
const index2 = toolCall.index || 0;
|
|
2206
|
+
if (!message.tool_calls) message.tool_calls = [];
|
|
2207
|
+
if (!message.tool_calls[index2]) {
|
|
2208
|
+
message.tool_calls[index2] = {
|
|
2209
|
+
id: "",
|
|
2210
|
+
type: "function",
|
|
2211
|
+
function: { name: "", arguments: "" }
|
|
2212
|
+
};
|
|
2213
|
+
}
|
|
2214
|
+
if (toolCall.id) message.tool_calls[index2].id = toolCall.id;
|
|
2215
|
+
if (toolCall.type) message.tool_calls[index2].type = toolCall.type;
|
|
2216
|
+
if (toolCall.function?.name) {
|
|
2217
|
+
message.tool_calls[index2].function.name += toolCall.function.name;
|
|
2218
|
+
}
|
|
2219
|
+
if (toolCall.function?.arguments) {
|
|
2220
|
+
message.tool_calls[index2].function.arguments += toolCall.function.arguments;
|
|
2221
|
+
}
|
|
2222
|
+
});
|
|
2223
|
+
}
|
|
2224
|
+
this.emit("stream-chunk", { chunk: obj, message });
|
|
2225
|
+
onProgress({ ...message });
|
|
2226
|
+
} catch (e) {
|
|
2227
|
+
console.error("🔍 解析chunk错误:", e, "原始数据:", cleanChunk);
|
|
2228
|
+
}
|
|
2229
|
+
}
|
|
2230
|
+
if (!this.isGenerating) {
|
|
2231
|
+
break;
|
|
2232
|
+
}
|
|
2233
|
+
}
|
|
2234
|
+
this.emit("stream-done", { message });
|
|
2235
|
+
onDone({ ...message });
|
|
2236
|
+
} catch (error) {
|
|
2237
|
+
if (error.name === "AbortError" || axios.isCancel(error)) {
|
|
2238
|
+
const cancelError = new Error("请求被中断");
|
|
2239
|
+
cancelError.name = "CancelError";
|
|
2240
|
+
this.emit("stream-cancel", { error: cancelError });
|
|
2241
|
+
throw cancelError;
|
|
2242
|
+
}
|
|
2243
|
+
this.emit("stream-error", { error });
|
|
2244
|
+
throw error;
|
|
2245
|
+
} finally {
|
|
2246
|
+
this.isGenerating = false;
|
|
2247
|
+
this.cancelTokenSource = null;
|
|
2248
|
+
}
|
|
2249
|
+
}
|
|
2250
|
+
interrupt() {
|
|
2251
|
+
if (this.isGenerating && this.cancelTokenSource) {
|
|
2252
|
+
this.cancelTokenSource.cancel("用户中断请求");
|
|
2253
|
+
this.isGenerating = false;
|
|
2254
|
+
}
|
|
2255
|
+
}
|
|
2256
|
+
_buildRequestBody(body) {
|
|
2257
|
+
if (typeof body?.toJSON === "function") {
|
|
2258
|
+
return body.toJSON();
|
|
2259
|
+
} else if (typeof body === "object" && body !== null) {
|
|
2260
|
+
return JSON.stringify(body);
|
|
2261
|
+
} else if (typeof body === "string") {
|
|
2262
|
+
try {
|
|
2263
|
+
JSON.parse(body);
|
|
2264
|
+
return body;
|
|
2265
|
+
} catch {
|
|
2266
|
+
throw new Error("字符串不是有效的JSON格式");
|
|
2267
|
+
}
|
|
2268
|
+
} else {
|
|
2269
|
+
throw new Error("无效的请求体类型,应传入对象或JSON字符串");
|
|
2270
|
+
}
|
|
2271
|
+
}
|
|
2272
|
+
_handleAxiosError(error) {
|
|
2273
|
+
if (error.response) {
|
|
2274
|
+
const status = error.response.status;
|
|
2275
|
+
const data = error.response.data;
|
|
2276
|
+
let message = `API错误 ${status}`;
|
|
2277
|
+
if (data?.error?.message) {
|
|
2278
|
+
message += `: ${data.error.message}`;
|
|
2279
|
+
}
|
|
2280
|
+
return new Error(message);
|
|
2281
|
+
} else if (error.request) {
|
|
2282
|
+
return new Error("网络错误:无法连接到API服务器");
|
|
2283
|
+
} else {
|
|
2284
|
+
return error;
|
|
2285
|
+
}
|
|
2286
|
+
}
|
|
2287
|
+
static parseCompatible(obj) {
|
|
2288
|
+
if (obj?.__format_version === 1 && obj.payload) {
|
|
2289
|
+
return {
|
|
2290
|
+
messages: obj.payload.messages || [],
|
|
2291
|
+
systems: obj.payload.systems || [],
|
|
2292
|
+
hintData: obj.payload.hintData || {
|
|
2293
|
+
name: "",
|
|
2294
|
+
toolState: {
|
|
2295
|
+
currentTime: "同步失败",
|
|
2296
|
+
currentTime_TS: 0
|
|
2297
|
+
}
|
|
2298
|
+
},
|
|
2299
|
+
tools: obj.payload.tools || []
|
|
2300
|
+
};
|
|
2301
|
+
}
|
|
2302
|
+
if (obj?.messages && Array.isArray(obj.messages)) {
|
|
2303
|
+
return {
|
|
2304
|
+
messages: obj.messages || [],
|
|
2305
|
+
systems: obj.systems || [],
|
|
2306
|
+
hintData: obj.hintData || {
|
|
2307
|
+
name: "",
|
|
2308
|
+
toolState: {
|
|
2309
|
+
currentTime: "同步失败",
|
|
2310
|
+
currentTime_TS: 0
|
|
2311
|
+
}
|
|
2312
|
+
},
|
|
2313
|
+
tools: obj.tools || []
|
|
2314
|
+
};
|
|
2315
|
+
}
|
|
2316
|
+
throw new Error("无法识别的聊天数据格式");
|
|
2317
|
+
}
|
|
2318
|
+
}
|
|
2319
|
+
class ChatService extends EventEmitter {
|
|
2320
|
+
constructor(apiKey, model = "deepseek-chat", config = {}) {
|
|
2321
|
+
super();
|
|
2322
|
+
this.messages = new Messages();
|
|
2323
|
+
this.apiClient = new ApiClient(apiKey);
|
|
2324
|
+
this.requestBuilder = new RequestBuilder(model, this.messages, config);
|
|
2325
|
+
this.toolManager = new ToolManager();
|
|
2326
|
+
this._setupDefaultListeners();
|
|
2327
|
+
}
|
|
2328
|
+
_setupDefaultListeners() {
|
|
2329
|
+
this.apiClient.on("request-start", (data) => {
|
|
2330
|
+
this.emit("request-start", data);
|
|
2331
|
+
});
|
|
2332
|
+
this.apiClient.on("request-success", (data) => {
|
|
2333
|
+
this.emit("request-success", data);
|
|
2334
|
+
});
|
|
2335
|
+
this.apiClient.on("request-error", (data) => {
|
|
2336
|
+
this.emit("request-error", data);
|
|
2337
|
+
});
|
|
2338
|
+
this.apiClient.on("stream-chunk", (data) => {
|
|
2339
|
+
this.emit("stream-chunk", data);
|
|
2340
|
+
});
|
|
2341
|
+
this.toolManager.on("tool-execute-start", (data) => {
|
|
2342
|
+
this.emit("tool-execute-start", data);
|
|
2343
|
+
});
|
|
2344
|
+
this.toolManager.on("tool-execute-success", (data) => {
|
|
2345
|
+
this.emit("tool-execute-success", data);
|
|
2346
|
+
});
|
|
2347
|
+
this.toolManager.on("tool-execute-error", (data) => {
|
|
2348
|
+
this.emit("tool-execute-error", data);
|
|
2349
|
+
});
|
|
2350
|
+
}
|
|
2351
|
+
/**
|
|
2352
|
+
* 注册工具
|
|
2353
|
+
*/
|
|
2354
|
+
registerTool(name, definition, executor) {
|
|
2355
|
+
this.toolManager.registerTool(name, definition, executor);
|
|
2356
|
+
this.messages.addTool(definition);
|
|
2357
|
+
return this;
|
|
2358
|
+
}
|
|
2359
|
+
/**
|
|
2360
|
+
* 发送消息(支持工具调用)
|
|
2361
|
+
*/
|
|
2362
|
+
async send(userMessage, options = {}) {
|
|
2363
|
+
try {
|
|
2364
|
+
this.emit("sending", {
|
|
2365
|
+
role: "user",
|
|
2366
|
+
content: userMessage,
|
|
2367
|
+
timestamp: /* @__PURE__ */ new Date()
|
|
2368
|
+
});
|
|
2369
|
+
this.messages.addUserMessage(userMessage);
|
|
2370
|
+
const requestBody = this.requestBuilder.toJSON(
|
|
2371
|
+
options.baseRounds,
|
|
2372
|
+
options.cycleRounds
|
|
2373
|
+
);
|
|
2374
|
+
const response = await this.apiClient.send(requestBody);
|
|
2375
|
+
const aiMessage = response.choices[0].message;
|
|
2376
|
+
if (aiMessage.tool_calls && aiMessage.tool_calls.length > 0) {
|
|
2377
|
+
return await this._handleToolCalls(aiMessage);
|
|
2378
|
+
} else {
|
|
2379
|
+
return await this._handleNormalResponse(aiMessage);
|
|
2380
|
+
}
|
|
2381
|
+
} catch (error) {
|
|
2382
|
+
this.emit("error", {
|
|
2383
|
+
error,
|
|
2384
|
+
message: userMessage,
|
|
2385
|
+
timestamp: /* @__PURE__ */ new Date()
|
|
2386
|
+
});
|
|
2387
|
+
throw error;
|
|
2388
|
+
}
|
|
2389
|
+
}
|
|
2390
|
+
/**
|
|
2391
|
+
* 处理工具调用(支持循环调用)
|
|
2392
|
+
*/
|
|
2393
|
+
async _handleToolCalls(aiMessage, maxIterations = 5) {
|
|
2394
|
+
console.log("🔍 处理工具调用,aiMessage:", aiMessage);
|
|
2395
|
+
let iteration = 0;
|
|
2396
|
+
let currentMessage = aiMessage;
|
|
2397
|
+
while (iteration < maxIterations) {
|
|
2398
|
+
iteration++;
|
|
2399
|
+
console.log(`🔄 工具调用迭代 ${iteration}/${maxIterations}`);
|
|
2400
|
+
this.messages.addAssistantMessage(currentMessage.content || "", {
|
|
2401
|
+
tool_calls: currentMessage.tool_calls,
|
|
2402
|
+
reasoning_content: currentMessage.reasoning_content || ""
|
|
2403
|
+
// ✅ 新增:保存思考内容
|
|
2404
|
+
});
|
|
2405
|
+
this.emit("tool-call-requested", {
|
|
2406
|
+
tool_calls: currentMessage.tool_calls,
|
|
2407
|
+
reasoning_content: currentMessage.reasoning_content,
|
|
2408
|
+
// ✅ 新增:包含思考内容
|
|
2409
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
2410
|
+
iteration
|
|
2411
|
+
});
|
|
2412
|
+
const toolResults = await this.toolManager.executeToolCalls(currentMessage.tool_calls);
|
|
2413
|
+
console.log("🔍 工具执行结果:", toolResults);
|
|
2414
|
+
for (const result of toolResults) {
|
|
2415
|
+
console.log("🔍 添加工具消息,result:", result);
|
|
2416
|
+
this.messages.addToolMessage(
|
|
2417
|
+
result.result || result.error || "",
|
|
2418
|
+
result.tool_call_id
|
|
2419
|
+
);
|
|
2420
|
+
}
|
|
2421
|
+
console.log("🔍 当前所有消息:", this.messages.getMessages());
|
|
2422
|
+
const requestBody = this.requestBuilder.toJSON();
|
|
2423
|
+
console.log("🔍 第", iteration, "次请求体:", requestBody);
|
|
2424
|
+
const response = await this.apiClient.send(requestBody);
|
|
2425
|
+
currentMessage = response.choices[0].message;
|
|
2426
|
+
if (!currentMessage.tool_calls || currentMessage.tool_calls.length === 0) {
|
|
2427
|
+
console.log("✅ 工具调用完成,AI给出最终回复");
|
|
2428
|
+
break;
|
|
2429
|
+
}
|
|
2430
|
+
console.log("🔄 AI请求了新的工具调用,继续处理...");
|
|
2431
|
+
}
|
|
2432
|
+
this.messages.addAssistantMessage(currentMessage.content || "", {
|
|
2433
|
+
reasoning_content: currentMessage.reasoning_content || ""
|
|
2434
|
+
// ✅ 新增:保存最终思考内容
|
|
2435
|
+
});
|
|
2436
|
+
this.emit("message", {
|
|
2437
|
+
role: "assistant",
|
|
2438
|
+
content: currentMessage.content,
|
|
2439
|
+
reasoning_content: currentMessage.reasoning_content,
|
|
2440
|
+
// ✅ 新增:包含思考内容
|
|
2441
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
2442
|
+
response: { choices: [{ message: currentMessage }] },
|
|
2443
|
+
toolIterations: iteration
|
|
2444
|
+
});
|
|
2445
|
+
return currentMessage.content;
|
|
2446
|
+
}
|
|
2447
|
+
/**
|
|
2448
|
+
* 处理普通回复
|
|
2449
|
+
*/
|
|
2450
|
+
async _handleNormalResponse(aiMessage) {
|
|
2451
|
+
this.messages.addAssistantMessage(aiMessage.content || "", {
|
|
2452
|
+
reasoning_content: aiMessage.reasoning_content
|
|
2453
|
+
});
|
|
2454
|
+
this.emit("message", {
|
|
2455
|
+
role: "assistant",
|
|
2456
|
+
content: aiMessage.content,
|
|
2457
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
2458
|
+
response: { choices: [{ message: aiMessage }] }
|
|
2459
|
+
});
|
|
2460
|
+
return aiMessage.content;
|
|
2461
|
+
}
|
|
2462
|
+
/**
|
|
2463
|
+
* 流式发送消息(支持工具调用)
|
|
2464
|
+
*/
|
|
2465
|
+
async stream(userMessage, onProgress, onDone, options = {}) {
|
|
2466
|
+
try {
|
|
2467
|
+
this.emit("sending", {
|
|
2468
|
+
role: "user",
|
|
2469
|
+
content: userMessage,
|
|
2470
|
+
timestamp: /* @__PURE__ */ new Date()
|
|
2471
|
+
});
|
|
2472
|
+
this.messages.addUserMessage(userMessage);
|
|
2473
|
+
const requestBuilder = new RequestBuilder(this.requestBuilder.model, this.messages, {
|
|
2474
|
+
...this.requestBuilder.config,
|
|
2475
|
+
stream: true
|
|
2476
|
+
// ✅ 必须设置为true!
|
|
2477
|
+
});
|
|
2478
|
+
const requestBody = requestBuilder.toJSON(
|
|
2479
|
+
options.baseRounds,
|
|
2480
|
+
options.cycleRounds
|
|
2481
|
+
);
|
|
2482
|
+
const response = await this.apiClient.strSend(
|
|
2483
|
+
requestBody,
|
|
2484
|
+
(chunk) => {
|
|
2485
|
+
this.emit("stream-progress", chunk);
|
|
2486
|
+
onProgress(chunk);
|
|
2487
|
+
},
|
|
2488
|
+
async (finalMessage) => {
|
|
2489
|
+
if (finalMessage.tool_calls && finalMessage.tool_calls.length > 0) {
|
|
2490
|
+
await this._handleStreamToolCalls(finalMessage, onProgress, onDone);
|
|
2491
|
+
} else {
|
|
2492
|
+
this.messages.addAssistantMessage(finalMessage.content || "", {
|
|
2493
|
+
reasoning_content: finalMessage.reasoning_content
|
|
2494
|
+
});
|
|
2495
|
+
this.emit("stream-done", { message: finalMessage });
|
|
2496
|
+
onDone(finalMessage);
|
|
2497
|
+
}
|
|
2498
|
+
}
|
|
2499
|
+
);
|
|
2500
|
+
return response;
|
|
2501
|
+
} catch (error) {
|
|
2502
|
+
this.emit("error", {
|
|
2503
|
+
error,
|
|
2504
|
+
message: userMessage,
|
|
2505
|
+
timestamp: /* @__PURE__ */ new Date()
|
|
2506
|
+
});
|
|
2507
|
+
throw error;
|
|
2508
|
+
}
|
|
2509
|
+
}
|
|
2510
|
+
/**
|
|
2511
|
+
* 处理流式传输中的工具调用(支持循环调用)
|
|
2512
|
+
*/
|
|
2513
|
+
async _handleStreamToolCalls(aiMessage, onProgress, onDone, maxIterations = 5) {
|
|
2514
|
+
let iteration = 0;
|
|
2515
|
+
let currentMessage = aiMessage;
|
|
2516
|
+
while (iteration < maxIterations) {
|
|
2517
|
+
iteration++;
|
|
2518
|
+
this.messages.addAssistantMessage(currentMessage.content || "", {
|
|
2519
|
+
tool_calls: currentMessage.tool_calls,
|
|
2520
|
+
reasoning_content: currentMessage.reasoning_content || ""
|
|
2521
|
+
// ✅ 新增:保存思考内容
|
|
2522
|
+
});
|
|
2523
|
+
this.emit("tool-call-requested", {
|
|
2524
|
+
tool_calls: currentMessage.tool_calls,
|
|
2525
|
+
reasoning_content: currentMessage.reasoning_content,
|
|
2526
|
+
// ✅ 新增:包含思考内容
|
|
2527
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
2528
|
+
iteration
|
|
2529
|
+
});
|
|
2530
|
+
const toolResults = await this.toolManager.executeToolCalls(currentMessage.tool_calls);
|
|
2531
|
+
for (const result of toolResults) {
|
|
2532
|
+
this.messages.addToolMessage(result.result || result.error, result.tool_call_id);
|
|
2533
|
+
}
|
|
2534
|
+
const requestBody = this.requestBuilder.toJSON();
|
|
2535
|
+
await new Promise((resolve, reject) => {
|
|
2536
|
+
this.apiClient.strSend(
|
|
2537
|
+
requestBody,
|
|
2538
|
+
(chunk) => {
|
|
2539
|
+
this.emit("stream-progress", chunk);
|
|
2540
|
+
onProgress(chunk);
|
|
2541
|
+
},
|
|
2542
|
+
(finalMessage) => {
|
|
2543
|
+
currentMessage = finalMessage;
|
|
2544
|
+
if (!currentMessage.tool_calls || currentMessage.tool_calls.length === 0) {
|
|
2545
|
+
resolve();
|
|
2546
|
+
} else {
|
|
2547
|
+
resolve();
|
|
2548
|
+
}
|
|
2549
|
+
}
|
|
2550
|
+
).catch(reject);
|
|
2551
|
+
});
|
|
2552
|
+
if (!currentMessage.tool_calls || currentMessage.tool_calls.length === 0) {
|
|
2553
|
+
break;
|
|
2554
|
+
}
|
|
2555
|
+
}
|
|
2556
|
+
this.messages.addAssistantMessage(currentMessage.content, {
|
|
2557
|
+
reasoning_content: currentMessage.reasoning_content || ""
|
|
2558
|
+
// ✅ 新增:保存最终思考内容
|
|
2559
|
+
});
|
|
2560
|
+
this.emit("stream-done", {
|
|
2561
|
+
message: currentMessage,
|
|
2562
|
+
reasoning_content: currentMessage.reasoning_content,
|
|
2563
|
+
// ✅ 新增:包含思考内容
|
|
2564
|
+
toolIterations: iteration
|
|
2565
|
+
});
|
|
2566
|
+
onDone(currentMessage);
|
|
2567
|
+
}
|
|
2568
|
+
/**
|
|
2569
|
+
* 撤回消息
|
|
2570
|
+
*/
|
|
2571
|
+
undo() {
|
|
2572
|
+
const removed = this.messages.undoToAssistant();
|
|
2573
|
+
if (removed.length > 0) {
|
|
2574
|
+
this.emit("undo", {
|
|
2575
|
+
removedMessages: removed,
|
|
2576
|
+
timestamp: /* @__PURE__ */ new Date()
|
|
2577
|
+
});
|
|
2578
|
+
}
|
|
2579
|
+
return removed;
|
|
2580
|
+
}
|
|
2581
|
+
/**
|
|
2582
|
+
* 清空消息
|
|
2583
|
+
*/
|
|
2584
|
+
clear() {
|
|
2585
|
+
const removed = this.messages.clearMessages();
|
|
2586
|
+
this.emit("clear", {
|
|
2587
|
+
removedMessages: removed,
|
|
2588
|
+
timestamp: /* @__PURE__ */ new Date()
|
|
2589
|
+
});
|
|
2590
|
+
return removed;
|
|
2591
|
+
}
|
|
2592
|
+
/**
|
|
2593
|
+
* 导出对话数据
|
|
2594
|
+
*/
|
|
2595
|
+
export() {
|
|
2596
|
+
const data = this.messages.export();
|
|
2597
|
+
this.emit("export", {
|
|
2598
|
+
data,
|
|
2599
|
+
timestamp: /* @__PURE__ */ new Date()
|
|
2600
|
+
});
|
|
2601
|
+
return data;
|
|
2602
|
+
}
|
|
2603
|
+
/**
|
|
2604
|
+
* 导入对话数据
|
|
2605
|
+
*/
|
|
2606
|
+
import(data) {
|
|
2607
|
+
this.messages.import(data);
|
|
2608
|
+
this.emit("import", {
|
|
2609
|
+
data,
|
|
2610
|
+
timestamp: /* @__PURE__ */ new Date()
|
|
2611
|
+
});
|
|
2612
|
+
return this;
|
|
2613
|
+
}
|
|
2614
|
+
}
|
|
2615
|
+
const index = {
|
|
2616
|
+
Messages,
|
|
2617
|
+
RequestBuilder,
|
|
2618
|
+
ApiClient,
|
|
2619
|
+
EventEmitter,
|
|
2620
|
+
MessageFormatter,
|
|
2621
|
+
ToolManager,
|
|
2622
|
+
ChatService
|
|
2623
|
+
};
|
|
2624
|
+
exports2.ApiClient = ApiClient;
|
|
2625
|
+
exports2.ChatService = ChatService;
|
|
2626
|
+
exports2.EventEmitter = EventEmitter;
|
|
2627
|
+
exports2.MessageFormatter = MessageFormatter;
|
|
2628
|
+
exports2.Messages = Messages;
|
|
2629
|
+
exports2.RequestBuilder = RequestBuilder;
|
|
2630
|
+
exports2.ToolManager = ToolManager;
|
|
2631
|
+
exports2.default = index;
|
|
2632
|
+
Object.defineProperties(exports2, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
|
|
2633
|
+
}));
|
|
2634
|
+
//# sourceMappingURL=my-ai-chat-framework.browser.umd.js.map
|