@cloudbase/agent-adapter-adp 1.0.1-alpha.23 → 1.0.1-alpha.25
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 +3 -2
- package/dist/index.d.mts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +137 -124
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +137 -124
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -168,8 +168,8 @@ const observable = agent.run({
|
|
|
168
168
|
|
|
169
169
|
**Supported file types:**
|
|
170
170
|
|
|
171
|
-
- **Images**: `image/png`, `image/jpeg`, `image/
|
|
172
|
-
- **Documents**: `application/pdf`, `application/msword`, `application/vnd.openxmlformats-officedocument.wordprocessingml.document`, `
|
|
171
|
+
- **Images**: `image/png`, `image/jpeg`, `image/bmp`
|
|
172
|
+
- **Documents**: `application/pdf`, `application/msword`, `application/vnd.openxmlformats-officedocument.wordprocessingml.document`, `application/vnd.ms-powerpoint`, `application/vnd.openxmlformats-officedocument.presentationml.presentation`, `text/plain`
|
|
173
173
|
|
|
174
174
|
## API Reference
|
|
175
175
|
|
|
@@ -200,6 +200,7 @@ interface AdpConfig {
|
|
|
200
200
|
request?: {
|
|
201
201
|
baseUrl?: string; // Base URL for ADP API (default: https://wss.lke.cloud.tencent.com)
|
|
202
202
|
endpoint?: string; // API endpoint (default: /v1/qbot/chat/sse)
|
|
203
|
+
docParseEndpoint?: string; // Document parse API endpoint (default: /v1/qbot/chat/docParse)
|
|
203
204
|
body?: Partial<AdpChatRequest>; // Additional request body options
|
|
204
205
|
};
|
|
205
206
|
}
|
package/dist/index.d.mts
CHANGED
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -171,9 +171,11 @@ var AdpAgent = class extends import_client.AbstractAgent {
|
|
|
171
171
|
});
|
|
172
172
|
}
|
|
173
173
|
async _run(subscriber, input) {
|
|
174
|
+
let thinkingMessageSet = /* @__PURE__ */ new Set();
|
|
175
|
+
let thinkFinishedMessageSet = /* @__PURE__ */ new Set();
|
|
174
176
|
try {
|
|
175
|
-
const { runId
|
|
176
|
-
const threadId =
|
|
177
|
+
const { runId } = input;
|
|
178
|
+
const threadId = input.threadId || (0, import_crypto.randomUUID)();
|
|
177
179
|
subscriber.next({
|
|
178
180
|
type: import_client.EventType.RUN_STARTED,
|
|
179
181
|
runId,
|
|
@@ -185,19 +187,26 @@ var AdpAgent = class extends import_client.AbstractAgent {
|
|
|
185
187
|
"MISSING_APP_KEY"
|
|
186
188
|
);
|
|
187
189
|
}
|
|
188
|
-
const
|
|
189
|
-
|
|
190
|
+
const latestUserMessage = input.messages.filter((m) => m.role === "user").pop();
|
|
191
|
+
if (!latestUserMessage) {
|
|
192
|
+
throw new AdpAgentError(
|
|
193
|
+
"Message content format error, or empty content",
|
|
194
|
+
"INVALID_MESSAGE_FORMAT"
|
|
195
|
+
);
|
|
196
|
+
}
|
|
197
|
+
const { message: docExtractedMessage, fileInfos } = await this.extractDocuments(latestUserMessage, threadId, subscriber);
|
|
198
|
+
const message = await this.convertAGUIMessagesToAdpMessages(docExtractedMessage);
|
|
190
199
|
if (!message) {
|
|
191
200
|
throw new AdpAgentError(
|
|
192
201
|
"Message content format error, or empty content",
|
|
193
202
|
"INVALID_MESSAGE_FORMAT"
|
|
194
203
|
);
|
|
195
204
|
}
|
|
196
|
-
if (
|
|
205
|
+
if (input.messages.length > 1) {
|
|
197
206
|
subscriber.next({
|
|
198
207
|
type: import_client.EventType.RAW,
|
|
199
208
|
rawEvent: {
|
|
200
|
-
message: `ADP handles message history itself, so that a total of ${
|
|
209
|
+
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.`,
|
|
201
210
|
type: "warn"
|
|
202
211
|
}
|
|
203
212
|
});
|
|
@@ -216,7 +225,6 @@ var AdpAgent = class extends import_client.AbstractAgent {
|
|
|
216
225
|
let buffer = "";
|
|
217
226
|
let interruptRequested = false;
|
|
218
227
|
let thinkingStart = false;
|
|
219
|
-
let thinkingMessageSet = /* @__PURE__ */ new Set();
|
|
220
228
|
for await (const chunk of sseStream) {
|
|
221
229
|
buffer += chunk.toString();
|
|
222
230
|
const parts = buffer.split("\n\n");
|
|
@@ -243,6 +251,22 @@ var AdpAgent = class extends import_client.AbstractAgent {
|
|
|
243
251
|
}
|
|
244
252
|
switch (data.type) {
|
|
245
253
|
case "reply": {
|
|
254
|
+
const messageId = data.payload.record_id;
|
|
255
|
+
const isFinal = data.payload.is_final;
|
|
256
|
+
if (thinkingStart) {
|
|
257
|
+
thinkingStart = false;
|
|
258
|
+
for (const index of thinkingMessageSet) {
|
|
259
|
+
subscriber.next({
|
|
260
|
+
type: import_client.EventType.THINKING_TEXT_MESSAGE_END,
|
|
261
|
+
messageId: `${messageId}-think-${index}`
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
thinkingMessageSet.clear();
|
|
265
|
+
subscriber.next({
|
|
266
|
+
type: import_client.EventType.THINKING_END,
|
|
267
|
+
messageId
|
|
268
|
+
});
|
|
269
|
+
}
|
|
246
270
|
if (data.payload.is_from_self) {
|
|
247
271
|
if (data.payload.is_evil) {
|
|
248
272
|
throw new AdpAgentError(
|
|
@@ -253,8 +277,6 @@ var AdpAgent = class extends import_client.AbstractAgent {
|
|
|
253
277
|
continue;
|
|
254
278
|
}
|
|
255
279
|
}
|
|
256
|
-
const messageId = data.payload.record_id;
|
|
257
|
-
const isFinal = data.payload.is_final;
|
|
258
280
|
data.payload.content = data.payload.content.replace(
|
|
259
281
|
/\\n/g,
|
|
260
282
|
"\n\n"
|
|
@@ -334,51 +356,47 @@ var AdpAgent = class extends import_client.AbstractAgent {
|
|
|
334
356
|
});
|
|
335
357
|
}
|
|
336
358
|
data.payload.procedures.forEach((procedure) => {
|
|
337
|
-
|
|
338
|
-
|
|
359
|
+
const index = procedure.index.toString();
|
|
360
|
+
if (!thinkingMessageSet.has(index) && !thinkFinishedMessageSet.has(index)) {
|
|
361
|
+
thinkingMessageSet.add(index);
|
|
339
362
|
subscriber.next({
|
|
340
363
|
type: import_client.EventType.THINKING_TEXT_MESSAGE_START,
|
|
341
|
-
messageId
|
|
364
|
+
messageId: `${messageId}-think-${index}`,
|
|
342
365
|
delta: procedure.debugging.content
|
|
343
366
|
});
|
|
344
367
|
} else {
|
|
345
368
|
if (procedure.status === "processing") {
|
|
346
369
|
subscriber.next({
|
|
347
370
|
type: import_client.EventType.THINKING_TEXT_MESSAGE_CONTENT,
|
|
348
|
-
messageId
|
|
371
|
+
messageId: `${messageId}-think-${index}`,
|
|
349
372
|
delta: procedure.debugging.content
|
|
350
373
|
});
|
|
351
374
|
} else {
|
|
352
|
-
thinkingMessageSet.delete(
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
375
|
+
thinkingMessageSet.delete(index);
|
|
376
|
+
if (!thinkFinishedMessageSet.has(index)) {
|
|
377
|
+
thinkFinishedMessageSet.add(index);
|
|
378
|
+
subscriber.next({
|
|
379
|
+
type: import_client.EventType.THINKING_TEXT_MESSAGE_END,
|
|
380
|
+
messageId: `${messageId}-think-${index}`
|
|
381
|
+
});
|
|
382
|
+
}
|
|
357
383
|
}
|
|
358
384
|
}
|
|
359
385
|
});
|
|
360
|
-
const allFinished = data.payload.procedures.every(
|
|
361
|
-
(procedure) => procedure.status !== "processing"
|
|
362
|
-
);
|
|
363
|
-
if (allFinished) {
|
|
364
|
-
thinkingStart = false;
|
|
365
|
-
thinkingMessageSet.clear();
|
|
366
|
-
subscriber.next({
|
|
367
|
-
type: import_client.EventType.THINKING_END,
|
|
368
|
-
messageId
|
|
369
|
-
});
|
|
370
|
-
}
|
|
371
386
|
break;
|
|
372
387
|
}
|
|
373
388
|
case "error": {
|
|
374
|
-
console.error(
|
|
389
|
+
console.error(
|
|
390
|
+
"[ERROR] ADP throws error: ",
|
|
391
|
+
JSON.stringify(data)
|
|
392
|
+
);
|
|
375
393
|
throw new AdpAgentError(
|
|
376
394
|
data.error.message,
|
|
377
395
|
data.error.code ? `ADP_ERROR_${data.error.code}` : "ADP_ERROR_-1"
|
|
378
396
|
);
|
|
379
397
|
}
|
|
380
398
|
case "token_stat": {
|
|
381
|
-
console.debug(JSON.stringify(data));
|
|
399
|
+
console.debug("[DEBUG] ADP token stat: ", JSON.stringify(data));
|
|
382
400
|
break;
|
|
383
401
|
}
|
|
384
402
|
case "reference": {
|
|
@@ -408,7 +426,7 @@ var AdpAgent = class extends import_client.AbstractAgent {
|
|
|
408
426
|
}
|
|
409
427
|
subscriber.complete();
|
|
410
428
|
} catch (e) {
|
|
411
|
-
console.error(JSON.stringify(e));
|
|
429
|
+
console.error("[ERROR] Uncaught error: ", JSON.stringify(e));
|
|
412
430
|
let code = "UNKNOWN_ERROR";
|
|
413
431
|
let message = JSON.stringify(e);
|
|
414
432
|
if (e instanceof import_axios.AxiosError) {
|
|
@@ -424,111 +442,105 @@ var AdpAgent = class extends import_client.AbstractAgent {
|
|
|
424
442
|
message: `Sorry, an error occurred while running the agent: Error code ${code}, ${message}`
|
|
425
443
|
});
|
|
426
444
|
subscriber.complete();
|
|
445
|
+
} finally {
|
|
446
|
+
thinkingMessageSet.clear();
|
|
447
|
+
thinkFinishedMessageSet.clear();
|
|
427
448
|
}
|
|
428
449
|
}
|
|
429
|
-
async convertAGUIMessagesToAdpMessages(
|
|
450
|
+
async convertAGUIMessagesToAdpMessages(message) {
|
|
430
451
|
let result = "";
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
if (message.
|
|
434
|
-
|
|
435
|
-
}
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
452
|
+
if (message.role === "user") {
|
|
453
|
+
let content = "";
|
|
454
|
+
if (typeof message.content === "string") {
|
|
455
|
+
content = message.content;
|
|
456
|
+
} else {
|
|
457
|
+
if (this.adpConfig.enableUpload) {
|
|
458
|
+
if (!this.finalCloudCredential.token) {
|
|
459
|
+
if (!this.finalCloudCredential.secretId) {
|
|
460
|
+
throw new AdpAgentError(
|
|
461
|
+
"TENCENTCLOUD_SECRETID is required, check your env variables or config passed with the adapter",
|
|
462
|
+
"MISSING_SECRET_ID"
|
|
463
|
+
);
|
|
464
|
+
}
|
|
465
|
+
if (!this.finalCloudCredential.secretKey) {
|
|
466
|
+
throw new AdpAgentError(
|
|
467
|
+
"TENCENTCLOUD_SECRETKEY is required, check your env variables or config passed with the adapter",
|
|
468
|
+
"MISSING_SECRET_KEY"
|
|
469
|
+
);
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
const imageMap = /* @__PURE__ */ new Map();
|
|
473
|
+
const imagesToUpload = [];
|
|
474
|
+
message.content.forEach((item) => {
|
|
475
|
+
if (item.type === "binary") {
|
|
476
|
+
if (Object.keys(IMAGE_MIME_TYPES).includes(item.mimeType)) {
|
|
477
|
+
imagesToUpload.push(item);
|
|
449
478
|
}
|
|
450
|
-
|
|
479
|
+
}
|
|
480
|
+
});
|
|
481
|
+
if (imagesToUpload.length) {
|
|
482
|
+
await this.uploadToCos(
|
|
483
|
+
imagesToUpload,
|
|
484
|
+
(data, _, file) => {
|
|
485
|
+
imageMap.set(
|
|
486
|
+
file.id || file.filename,
|
|
487
|
+
`https://${data.Location}`
|
|
488
|
+
);
|
|
489
|
+
},
|
|
490
|
+
(fileName, error) => {
|
|
451
491
|
throw new AdpAgentError(
|
|
452
|
-
|
|
453
|
-
"
|
|
492
|
+
`Upload image ${fileName} failed: ${error}`,
|
|
493
|
+
"UPLOAD_IMAGE_FAILED"
|
|
454
494
|
);
|
|
455
495
|
}
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
await this.uploadToCos(
|
|
468
|
-
imagesToUpload,
|
|
469
|
-
(data, _, file) => {
|
|
470
|
-
imageMap.set(
|
|
471
|
-
file.id || file.filename,
|
|
472
|
-
`https://${data.Location}`
|
|
473
|
-
);
|
|
474
|
-
},
|
|
475
|
-
(fileName, error) => {
|
|
476
|
-
throw new AdpAgentError(
|
|
477
|
-
`Upload image ${fileName} failed: ${error}`,
|
|
478
|
-
"UPLOAD_IMAGE_FAILED"
|
|
479
|
-
);
|
|
496
|
+
);
|
|
497
|
+
}
|
|
498
|
+
content = message.content.reduce((acc, cur) => {
|
|
499
|
+
if (cur.type === "text") {
|
|
500
|
+
return acc + `${cur.text} `;
|
|
501
|
+
} else if (cur.type === "binary") {
|
|
502
|
+
if (Object.keys(IMAGE_MIME_TYPES).includes(cur.mimeType)) {
|
|
503
|
+
if (imageMap.has(cur.id || cur.filename)) {
|
|
504
|
+
return acc + `}) `;
|
|
505
|
+
} else {
|
|
506
|
+
return acc;
|
|
480
507
|
}
|
|
481
|
-
|
|
508
|
+
} else return acc;
|
|
509
|
+
} else {
|
|
510
|
+
return acc;
|
|
482
511
|
}
|
|
483
|
-
|
|
484
|
-
if (cur.type === "text") {
|
|
485
|
-
return acc + `${cur.text} `;
|
|
486
|
-
} else if (cur.type === "binary") {
|
|
487
|
-
if (Object.keys(IMAGE_MIME_TYPES).includes(cur.mimeType)) {
|
|
488
|
-
if (imageMap.has(cur.id || cur.filename)) {
|
|
489
|
-
return acc + `}) `;
|
|
490
|
-
} else {
|
|
491
|
-
return acc;
|
|
492
|
-
}
|
|
493
|
-
} else return acc;
|
|
494
|
-
} else {
|
|
495
|
-
return acc;
|
|
496
|
-
}
|
|
497
|
-
}, "").trim();
|
|
498
|
-
}
|
|
512
|
+
}, "").trim();
|
|
499
513
|
}
|
|
500
|
-
|
|
514
|
+
}
|
|
515
|
+
result = `${message.role}: ${content}
|
|
501
516
|
${result}`;
|
|
502
|
-
|
|
503
|
-
|
|
517
|
+
} else {
|
|
518
|
+
result = `${message.role}: ${message.content}
|
|
504
519
|
${result}`;
|
|
505
|
-
}
|
|
506
520
|
}
|
|
507
|
-
return
|
|
521
|
+
return result.trim();
|
|
508
522
|
}
|
|
509
|
-
async extractDocuments(
|
|
510
|
-
const { messages, runId, threadId } = input;
|
|
523
|
+
async extractDocuments(message, threadId, subscriber) {
|
|
511
524
|
const documentFiles = [];
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
525
|
+
let newMessage;
|
|
526
|
+
if (message.role === "user" && Array.isArray(message.content)) {
|
|
527
|
+
let newContent = [];
|
|
528
|
+
message.content.forEach((item) => {
|
|
529
|
+
if (item.type === "text") {
|
|
530
|
+
newContent.push(item);
|
|
531
|
+
} else if (item.type === "binary") {
|
|
532
|
+
if (Object.keys(DOCUMENT_MIME_TYPES).includes(item.mimeType)) {
|
|
533
|
+
documentFiles.push(item);
|
|
534
|
+
} else {
|
|
517
535
|
newContent.push(item);
|
|
518
|
-
} else if (item.type === "binary") {
|
|
519
|
-
if (Object.keys(DOCUMENT_MIME_TYPES).includes(item.mimeType)) {
|
|
520
|
-
documentFiles.push(item);
|
|
521
|
-
} else {
|
|
522
|
-
newContent.push(item);
|
|
523
|
-
}
|
|
524
536
|
}
|
|
525
|
-
}
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
}
|
|
531
|
-
}
|
|
537
|
+
}
|
|
538
|
+
});
|
|
539
|
+
newMessage = {
|
|
540
|
+
...message,
|
|
541
|
+
content: newContent
|
|
542
|
+
};
|
|
543
|
+
} else newMessage = message;
|
|
532
544
|
const fileInfos = [];
|
|
533
545
|
const successedFiles = [];
|
|
534
546
|
const failedFiles = [];
|
|
@@ -559,10 +571,11 @@ ${result}`;
|
|
|
559
571
|
}
|
|
560
572
|
);
|
|
561
573
|
} catch (e) {
|
|
574
|
+
console.error("Document upload failed: ", JSON.stringify(e));
|
|
562
575
|
}
|
|
563
576
|
}
|
|
564
577
|
if (successedFiles.length) {
|
|
565
|
-
|
|
578
|
+
for (const { data: cosData, cosParams, file } of successedFiles) {
|
|
566
579
|
const extName = MIME_TYPES[file.mimeType];
|
|
567
580
|
const requestBody = {
|
|
568
581
|
sessionId: threadId,
|
|
@@ -577,7 +590,7 @@ ${result}`;
|
|
|
577
590
|
size: file.data?.length.toString() || "0"
|
|
578
591
|
};
|
|
579
592
|
const response = await this.reqAppClient.post(
|
|
580
|
-
this.adpConfig.request?.
|
|
593
|
+
this.adpConfig.request?.docParseEndpoint || "/v1/qbot/chat/docParse",
|
|
581
594
|
camelToSnakeKeys(requestBody),
|
|
582
595
|
{ responseType: "stream" }
|
|
583
596
|
);
|
|
@@ -645,11 +658,11 @@ ${result}`;
|
|
|
645
658
|
}
|
|
646
659
|
}
|
|
647
660
|
}
|
|
648
|
-
}
|
|
661
|
+
}
|
|
649
662
|
}
|
|
650
663
|
}
|
|
651
664
|
return {
|
|
652
|
-
|
|
665
|
+
message: newMessage,
|
|
653
666
|
fileInfos,
|
|
654
667
|
failedFiles
|
|
655
668
|
};
|