@cloudbase/agent-adapter-adp 0.0.16 → 0.0.18
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/README.md +53 -0
- package/dist/index.d.mts +3 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +211 -164
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +211 -164
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -8
package/dist/index.mjs
CHANGED
|
@@ -93,18 +93,20 @@ var AdpAgent = class extends AbstractAgent {
|
|
|
93
93
|
constructor(config) {
|
|
94
94
|
super(config);
|
|
95
95
|
this.finalAppKey = "";
|
|
96
|
+
this.finalCloudCredential = {};
|
|
96
97
|
this.adpConfig = config.adpConfig;
|
|
97
98
|
this.finalAppKey = this.adpConfig.appKey || this.adpConfig.request?.body?.botAppKey || process.env.ADP_APP_KEY || "";
|
|
98
99
|
this.reqAppClient = axios.create({
|
|
99
100
|
baseURL: this.adpConfig.request?.baseUrl || "https://wss.lke.cloud.tencent.com"
|
|
100
101
|
});
|
|
101
102
|
const LkeClient = lke.v20231130.Client;
|
|
103
|
+
this.finalCloudCredential = {
|
|
104
|
+
secretId: this.adpConfig.credential?.secretId || process.env.TENCENTCLOUD_SECRETID,
|
|
105
|
+
secretKey: this.adpConfig.credential?.secretKey || process.env.TENCENTCLOUD_SECRETKEY,
|
|
106
|
+
token: this.adpConfig.credential?.token || process.env.TENCENTCLOUD_SESSIONTOKEN
|
|
107
|
+
};
|
|
102
108
|
this.reqLkeClient = new LkeClient({
|
|
103
|
-
credential:
|
|
104
|
-
secretId: this.adpConfig.credential?.secretId || process.env.TENCENTCLOUD_SECRETID,
|
|
105
|
-
secretKey: this.adpConfig.credential?.secretKey || process.env.TENCENTCLOUD_SECRETKEY,
|
|
106
|
-
token: this.adpConfig.credential?.token || process.env.TENCENTCLOUD_SESSIONTOKEN
|
|
107
|
-
}
|
|
109
|
+
credential: this.finalCloudCredential
|
|
108
110
|
});
|
|
109
111
|
}
|
|
110
112
|
generateRequestBody({
|
|
@@ -133,9 +135,11 @@ var AdpAgent = class extends AbstractAgent {
|
|
|
133
135
|
});
|
|
134
136
|
}
|
|
135
137
|
async _run(subscriber, input) {
|
|
138
|
+
let thinkingMessageSet = /* @__PURE__ */ new Set();
|
|
139
|
+
let thinkFinishedMessageSet = /* @__PURE__ */ new Set();
|
|
136
140
|
try {
|
|
137
|
-
const { runId
|
|
138
|
-
const threadId =
|
|
141
|
+
const { runId } = input;
|
|
142
|
+
const threadId = input.threadId || randomUUID();
|
|
139
143
|
subscriber.next({
|
|
140
144
|
type: EventType.RUN_STARTED,
|
|
141
145
|
runId,
|
|
@@ -147,19 +151,26 @@ var AdpAgent = class extends AbstractAgent {
|
|
|
147
151
|
"MISSING_APP_KEY"
|
|
148
152
|
);
|
|
149
153
|
}
|
|
150
|
-
const
|
|
151
|
-
|
|
154
|
+
const latestUserMessage = input.messages.filter((m) => m.role === "user").pop();
|
|
155
|
+
if (!latestUserMessage) {
|
|
156
|
+
throw new AdpAgentError(
|
|
157
|
+
"Message content format error, or empty content",
|
|
158
|
+
"INVALID_MESSAGE_FORMAT"
|
|
159
|
+
);
|
|
160
|
+
}
|
|
161
|
+
const { message: docExtractedMessage, fileInfos } = await this.extractDocuments(latestUserMessage, threadId, subscriber);
|
|
162
|
+
const message = await this.convertAGUIMessagesToAdpMessages(docExtractedMessage);
|
|
152
163
|
if (!message) {
|
|
153
164
|
throw new AdpAgentError(
|
|
154
165
|
"Message content format error, or empty content",
|
|
155
166
|
"INVALID_MESSAGE_FORMAT"
|
|
156
167
|
);
|
|
157
168
|
}
|
|
158
|
-
if (
|
|
169
|
+
if (input.messages.length > 1) {
|
|
159
170
|
subscriber.next({
|
|
160
171
|
type: EventType.RAW,
|
|
161
172
|
rawEvent: {
|
|
162
|
-
message: `ADP handles message history itself, so that a total of ${
|
|
173
|
+
message: `ADP handles message history itself, so that a total of ${input.messages.length - 1} messages before and including last assistant message will be trimmed.`,
|
|
163
174
|
type: "warn"
|
|
164
175
|
}
|
|
165
176
|
});
|
|
@@ -178,7 +189,6 @@ var AdpAgent = class extends AbstractAgent {
|
|
|
178
189
|
let buffer = "";
|
|
179
190
|
let interruptRequested = false;
|
|
180
191
|
let thinkingStart = false;
|
|
181
|
-
let thinkingMessageSet = /* @__PURE__ */ new Set();
|
|
182
192
|
for await (const chunk of sseStream) {
|
|
183
193
|
buffer += chunk.toString();
|
|
184
194
|
const parts = buffer.split("\n\n");
|
|
@@ -205,6 +215,22 @@ var AdpAgent = class extends AbstractAgent {
|
|
|
205
215
|
}
|
|
206
216
|
switch (data.type) {
|
|
207
217
|
case "reply": {
|
|
218
|
+
const messageId = data.payload.record_id;
|
|
219
|
+
const isFinal = data.payload.is_final;
|
|
220
|
+
if (thinkingStart) {
|
|
221
|
+
thinkingStart = false;
|
|
222
|
+
for (const index of thinkingMessageSet) {
|
|
223
|
+
subscriber.next({
|
|
224
|
+
type: EventType.THINKING_TEXT_MESSAGE_END,
|
|
225
|
+
messageId: `${messageId}-think-${index}`
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
thinkingMessageSet.clear();
|
|
229
|
+
subscriber.next({
|
|
230
|
+
type: EventType.THINKING_END,
|
|
231
|
+
messageId
|
|
232
|
+
});
|
|
233
|
+
}
|
|
208
234
|
if (data.payload.is_from_self) {
|
|
209
235
|
if (data.payload.is_evil) {
|
|
210
236
|
throw new AdpAgentError(
|
|
@@ -215,8 +241,6 @@ var AdpAgent = class extends AbstractAgent {
|
|
|
215
241
|
continue;
|
|
216
242
|
}
|
|
217
243
|
}
|
|
218
|
-
const messageId = data.payload.record_id;
|
|
219
|
-
const isFinal = data.payload.is_final;
|
|
220
244
|
data.payload.content = data.payload.content.replace(
|
|
221
245
|
/\\n/g,
|
|
222
246
|
"\n\n"
|
|
@@ -296,51 +320,47 @@ var AdpAgent = class extends AbstractAgent {
|
|
|
296
320
|
});
|
|
297
321
|
}
|
|
298
322
|
data.payload.procedures.forEach((procedure) => {
|
|
299
|
-
|
|
300
|
-
|
|
323
|
+
const index = procedure.index.toString();
|
|
324
|
+
if (!thinkingMessageSet.has(index) && !thinkFinishedMessageSet.has(index)) {
|
|
325
|
+
thinkingMessageSet.add(index);
|
|
301
326
|
subscriber.next({
|
|
302
327
|
type: EventType.THINKING_TEXT_MESSAGE_START,
|
|
303
|
-
messageId
|
|
328
|
+
messageId: `${messageId}-think-${index}`,
|
|
304
329
|
delta: procedure.debugging.content
|
|
305
330
|
});
|
|
306
331
|
} else {
|
|
307
332
|
if (procedure.status === "processing") {
|
|
308
333
|
subscriber.next({
|
|
309
334
|
type: EventType.THINKING_TEXT_MESSAGE_CONTENT,
|
|
310
|
-
messageId
|
|
335
|
+
messageId: `${messageId}-think-${index}`,
|
|
311
336
|
delta: procedure.debugging.content
|
|
312
337
|
});
|
|
313
338
|
} else {
|
|
314
|
-
thinkingMessageSet.delete(
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
339
|
+
thinkingMessageSet.delete(index);
|
|
340
|
+
if (!thinkFinishedMessageSet.has(index)) {
|
|
341
|
+
thinkFinishedMessageSet.add(index);
|
|
342
|
+
subscriber.next({
|
|
343
|
+
type: EventType.THINKING_TEXT_MESSAGE_END,
|
|
344
|
+
messageId: `${messageId}-think-${index}`
|
|
345
|
+
});
|
|
346
|
+
}
|
|
319
347
|
}
|
|
320
348
|
}
|
|
321
349
|
});
|
|
322
|
-
const allFinished = data.payload.procedures.every(
|
|
323
|
-
(procedure) => procedure.status !== "processing"
|
|
324
|
-
);
|
|
325
|
-
if (allFinished) {
|
|
326
|
-
thinkingStart = false;
|
|
327
|
-
thinkingMessageSet.clear();
|
|
328
|
-
subscriber.next({
|
|
329
|
-
type: EventType.THINKING_END,
|
|
330
|
-
messageId
|
|
331
|
-
});
|
|
332
|
-
}
|
|
333
350
|
break;
|
|
334
351
|
}
|
|
335
352
|
case "error": {
|
|
336
|
-
console.error(
|
|
353
|
+
console.error(
|
|
354
|
+
"[ERROR] ADP throws error: ",
|
|
355
|
+
JSON.stringify(data)
|
|
356
|
+
);
|
|
337
357
|
throw new AdpAgentError(
|
|
338
358
|
data.error.message,
|
|
339
359
|
data.error.code ? `ADP_ERROR_${data.error.code}` : "ADP_ERROR_-1"
|
|
340
360
|
);
|
|
341
361
|
}
|
|
342
362
|
case "token_stat": {
|
|
343
|
-
console.debug(JSON.stringify(data));
|
|
363
|
+
console.debug("[DEBUG] ADP token stat: ", JSON.stringify(data));
|
|
344
364
|
break;
|
|
345
365
|
}
|
|
346
366
|
case "reference": {
|
|
@@ -370,7 +390,7 @@ var AdpAgent = class extends AbstractAgent {
|
|
|
370
390
|
}
|
|
371
391
|
subscriber.complete();
|
|
372
392
|
} catch (e) {
|
|
373
|
-
console.error(JSON.stringify(e));
|
|
393
|
+
console.error("[ERROR] Uncaught error: ", JSON.stringify(e));
|
|
374
394
|
let code = "UNKNOWN_ERROR";
|
|
375
395
|
let message = JSON.stringify(e);
|
|
376
396
|
if (e instanceof AxiosError) {
|
|
@@ -386,21 +406,33 @@ var AdpAgent = class extends AbstractAgent {
|
|
|
386
406
|
message: `Sorry, an error occurred while running the agent: Error code ${code}, ${message}`
|
|
387
407
|
});
|
|
388
408
|
subscriber.complete();
|
|
409
|
+
} finally {
|
|
410
|
+
thinkingMessageSet.clear();
|
|
411
|
+
thinkFinishedMessageSet.clear();
|
|
389
412
|
}
|
|
390
413
|
}
|
|
391
|
-
async convertAGUIMessagesToAdpMessages(
|
|
414
|
+
async convertAGUIMessagesToAdpMessages(message) {
|
|
392
415
|
let result = "";
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
if (message.
|
|
396
|
-
|
|
397
|
-
}
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
416
|
+
if (message.role === "user") {
|
|
417
|
+
let content = "";
|
|
418
|
+
if (typeof message.content === "string") {
|
|
419
|
+
content = message.content;
|
|
420
|
+
} else {
|
|
421
|
+
if (this.adpConfig.enableUpload) {
|
|
422
|
+
if (!this.finalCloudCredential.token) {
|
|
423
|
+
if (!this.finalCloudCredential.secretId) {
|
|
424
|
+
throw new AdpAgentError(
|
|
425
|
+
"TENCENTCLOUD_SECRETID is required, check your env variables or config passed with the adapter",
|
|
426
|
+
"MISSING_SECRET_ID"
|
|
427
|
+
);
|
|
428
|
+
}
|
|
429
|
+
if (!this.finalCloudCredential.secretKey) {
|
|
430
|
+
throw new AdpAgentError(
|
|
431
|
+
"TENCENTCLOUD_SECRETKEY is required, check your env variables or config passed with the adapter",
|
|
432
|
+
"MISSING_SECRET_KEY"
|
|
433
|
+
);
|
|
434
|
+
}
|
|
435
|
+
}
|
|
404
436
|
const imageMap = /* @__PURE__ */ new Map();
|
|
405
437
|
const imagesToUpload = [];
|
|
406
438
|
message.content.forEach((item) => {
|
|
@@ -443,143 +475,158 @@ var AdpAgent = class extends AbstractAgent {
|
|
|
443
475
|
}
|
|
444
476
|
}, "").trim();
|
|
445
477
|
}
|
|
446
|
-
|
|
478
|
+
}
|
|
479
|
+
result = `${message.role}: ${content}
|
|
447
480
|
${result}`;
|
|
448
|
-
|
|
449
|
-
|
|
481
|
+
} else {
|
|
482
|
+
result = `${message.role}: ${message.content}
|
|
450
483
|
${result}`;
|
|
451
|
-
}
|
|
452
484
|
}
|
|
453
|
-
return
|
|
485
|
+
return result.trim();
|
|
454
486
|
}
|
|
455
|
-
async extractDocuments(
|
|
456
|
-
const { messages, runId, threadId } = input;
|
|
487
|
+
async extractDocuments(message, threadId, subscriber) {
|
|
457
488
|
const documentFiles = [];
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
489
|
+
let newMessage;
|
|
490
|
+
if (message.role === "user" && Array.isArray(message.content)) {
|
|
491
|
+
let newContent = [];
|
|
492
|
+
message.content.forEach((item) => {
|
|
493
|
+
if (item.type === "text") {
|
|
494
|
+
newContent.push(item);
|
|
495
|
+
} else if (item.type === "binary") {
|
|
496
|
+
if (Object.keys(DOCUMENT_MIME_TYPES).includes(item.mimeType)) {
|
|
497
|
+
documentFiles.push(item);
|
|
498
|
+
} else {
|
|
463
499
|
newContent.push(item);
|
|
464
|
-
} else if (item.type === "binary") {
|
|
465
|
-
if (Object.keys(DOCUMENT_MIME_TYPES).includes(item.mimeType)) {
|
|
466
|
-
documentFiles.push(item);
|
|
467
|
-
} else {
|
|
468
|
-
newContent.push(item);
|
|
469
|
-
}
|
|
470
500
|
}
|
|
471
|
-
}
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
}
|
|
477
|
-
}
|
|
501
|
+
}
|
|
502
|
+
});
|
|
503
|
+
newMessage = {
|
|
504
|
+
...message,
|
|
505
|
+
content: newContent
|
|
506
|
+
};
|
|
507
|
+
} else newMessage = message;
|
|
478
508
|
const fileInfos = [];
|
|
479
509
|
const successedFiles = [];
|
|
480
510
|
const failedFiles = [];
|
|
481
|
-
if (
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
511
|
+
if (this.adpConfig.enableUpload) {
|
|
512
|
+
if (!this.finalCloudCredential.token) {
|
|
513
|
+
if (!this.finalCloudCredential.secretId) {
|
|
514
|
+
throw new AdpAgentError(
|
|
515
|
+
"TENCENTCLOUD_SECRETID is required, check your env variables or config passed with the adapter",
|
|
516
|
+
"MISSING_SECRET_ID"
|
|
517
|
+
);
|
|
518
|
+
}
|
|
519
|
+
if (!this.finalCloudCredential.secretKey) {
|
|
520
|
+
throw new AdpAgentError(
|
|
521
|
+
"TENCENTCLOUD_SECRETKEY is required, check your env variables or config passed with the adapter",
|
|
522
|
+
"MISSING_SECRET_KEY"
|
|
523
|
+
);
|
|
524
|
+
}
|
|
493
525
|
}
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
fileType: extName,
|
|
504
|
-
fileName: file.filename,
|
|
505
|
-
cosUrl: cosParams.UploadPath,
|
|
506
|
-
cosHash: cosData.headers?.["x-cos-hash-crc64ecma"] || "",
|
|
507
|
-
eTag: cosData.ETag,
|
|
508
|
-
size: file.data?.length.toString() || "0"
|
|
509
|
-
};
|
|
510
|
-
const response = await this.reqAppClient.post(
|
|
511
|
-
this.adpConfig.request?.endpoint || "/v1/qbot/chat/docParse",
|
|
512
|
-
camelToSnakeKeys(requestBody),
|
|
513
|
-
{ responseType: "stream" }
|
|
514
|
-
);
|
|
515
|
-
const sseStream = response.data;
|
|
516
|
-
let buffer = "";
|
|
517
|
-
for await (const chunk of sseStream) {
|
|
518
|
-
buffer += chunk.toString();
|
|
519
|
-
const parts = buffer.split("\n\n");
|
|
520
|
-
buffer = parts.pop() || "";
|
|
521
|
-
for (const part of parts) {
|
|
522
|
-
if (!part.trim()) continue;
|
|
523
|
-
const event = { data: "", event: "" };
|
|
524
|
-
for (const line of part.split("\n")) {
|
|
525
|
-
if (line.startsWith("data:")) {
|
|
526
|
-
event.data += line.slice(5);
|
|
527
|
-
} else if (line.startsWith("event:")) {
|
|
528
|
-
event.event = line.slice(6);
|
|
529
|
-
}
|
|
526
|
+
if (documentFiles.length) {
|
|
527
|
+
try {
|
|
528
|
+
await this.uploadToCos(
|
|
529
|
+
documentFiles,
|
|
530
|
+
(data, cosParams, file) => {
|
|
531
|
+
successedFiles.push({ data, cosParams, file });
|
|
532
|
+
},
|
|
533
|
+
(fileName, error) => {
|
|
534
|
+
failedFiles.push({ fileName, error });
|
|
530
535
|
}
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
536
|
+
);
|
|
537
|
+
} catch (e) {
|
|
538
|
+
console.error("Document upload failed: ", JSON.stringify(e));
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
if (successedFiles.length) {
|
|
542
|
+
for (const { data: cosData, cosParams, file } of successedFiles) {
|
|
543
|
+
const extName = MIME_TYPES[file.mimeType];
|
|
544
|
+
const requestBody = {
|
|
545
|
+
sessionId: threadId,
|
|
546
|
+
botAppKey: this.finalAppKey,
|
|
547
|
+
requestId: randomUUID(),
|
|
548
|
+
cosBucket: cosParams.Bucket,
|
|
549
|
+
fileType: extName,
|
|
550
|
+
fileName: file.filename,
|
|
551
|
+
cosUrl: cosParams.UploadPath,
|
|
552
|
+
cosHash: cosData.headers?.["x-cos-hash-crc64ecma"] || "",
|
|
553
|
+
eTag: cosData.ETag,
|
|
554
|
+
size: file.data?.length.toString() || "0"
|
|
555
|
+
};
|
|
556
|
+
const response = await this.reqAppClient.post(
|
|
557
|
+
this.adpConfig.request?.docParseEndpoint || "/v1/qbot/chat/docParse",
|
|
558
|
+
camelToSnakeKeys(requestBody),
|
|
559
|
+
{ responseType: "stream" }
|
|
560
|
+
);
|
|
561
|
+
const sseStream = response.data;
|
|
562
|
+
let buffer = "";
|
|
563
|
+
for await (const chunk of sseStream) {
|
|
564
|
+
buffer += chunk.toString();
|
|
565
|
+
const parts = buffer.split("\n\n");
|
|
566
|
+
buffer = parts.pop() || "";
|
|
567
|
+
for (const part of parts) {
|
|
568
|
+
if (!part.trim()) continue;
|
|
569
|
+
const event = { data: "", event: "" };
|
|
570
|
+
for (const line of part.split("\n")) {
|
|
571
|
+
if (line.startsWith("data:")) {
|
|
572
|
+
event.data += line.slice(5);
|
|
573
|
+
} else if (line.startsWith("event:")) {
|
|
574
|
+
event.event = line.slice(6);
|
|
575
|
+
}
|
|
540
576
|
}
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
}
|
|
559
|
-
}
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
577
|
+
if (event.data) {
|
|
578
|
+
let data;
|
|
579
|
+
try {
|
|
580
|
+
data = JSON.parse(event.data);
|
|
581
|
+
} catch (e) {
|
|
582
|
+
throw new AdpAgentError(
|
|
583
|
+
`ADP returned invalid data: ${event.data}`,
|
|
584
|
+
"INVALID_DATA"
|
|
585
|
+
);
|
|
586
|
+
}
|
|
587
|
+
switch (data.type) {
|
|
588
|
+
case "parsing": {
|
|
589
|
+
subscriber.next({
|
|
590
|
+
type: EventType.RAW,
|
|
591
|
+
rawEvent: {
|
|
592
|
+
message: `Parsing document ${file.filename}: ${data.payload.process}%`,
|
|
593
|
+
type: "info"
|
|
594
|
+
}
|
|
595
|
+
});
|
|
596
|
+
if (data.payload.is_final) {
|
|
597
|
+
if (data.payload.error_message) {
|
|
598
|
+
subscriber.next({
|
|
599
|
+
type: EventType.RAW,
|
|
600
|
+
rawEvent: {
|
|
601
|
+
message: `Parsing document ${file.filename} failed: ${data.payload.error_message}`,
|
|
602
|
+
type: "error"
|
|
603
|
+
}
|
|
604
|
+
});
|
|
605
|
+
} else {
|
|
606
|
+
const fileNameNoExt = file.filename.split(".").splice(0, -1).join(".");
|
|
607
|
+
fileInfos.push({
|
|
608
|
+
docId: data.payload.doc_id,
|
|
609
|
+
fileName: fileNameNoExt,
|
|
610
|
+
fileType: extName,
|
|
611
|
+
fileSize: file.data?.length.toString() || "0",
|
|
612
|
+
fileUrl: `https://${cosData.Location}`
|
|
613
|
+
});
|
|
614
|
+
}
|
|
568
615
|
}
|
|
616
|
+
break;
|
|
617
|
+
}
|
|
618
|
+
default: {
|
|
619
|
+
break;
|
|
569
620
|
}
|
|
570
|
-
break;
|
|
571
|
-
}
|
|
572
|
-
default: {
|
|
573
|
-
break;
|
|
574
621
|
}
|
|
575
622
|
}
|
|
576
623
|
}
|
|
577
624
|
}
|
|
578
625
|
}
|
|
579
|
-
}
|
|
626
|
+
}
|
|
580
627
|
}
|
|
581
628
|
return {
|
|
582
|
-
|
|
629
|
+
message: newMessage,
|
|
583
630
|
fileInfos,
|
|
584
631
|
failedFiles
|
|
585
632
|
};
|