@cloudbase/agent-adapter-adp 0.0.16 → 0.0.19

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 CHANGED
@@ -15,6 +15,7 @@ npm install @cloudbase/agent-agents @cloudbase/agent-adapter-adp
15
15
  - **Thinking Events**: Support for thinking/reasoning process events from the model
16
16
  - **Workflow Integration**: Support for ADP workflows with tool call events
17
17
  - **Custom Variables**: Pass custom parameters to workflows and knowledge base
18
+ - **File Upload**: Upload images and documents to COS for multimodal conversations (**requires `enableUpload: true`**)
18
19
 
19
20
  ## Environment Variables
20
21
 
@@ -121,6 +122,55 @@ observable.subscribe({
121
122
  });
122
123
  ```
123
124
 
125
+ ### With File Upload (Images and Documents)
126
+
127
+ When `enableUpload` is **set to `true`**, you can send images and documents in messages. Files are automatically uploaded to Tencent Cloud COS and processed by ADP.
128
+
129
+ **Note:** File upload requires Tencent Cloud credentials (`TENCENTCLOUD_SECRETID` and `TENCENTCLOUD_SECRETKEY`).
130
+
131
+ ```typescript
132
+ import { AdpAgent } from "@cloudbase/agent-adapter-adp";
133
+ import { randomUUID } from "crypto";
134
+ import * as fs from "fs";
135
+
136
+ const agent = new AdpAgent({
137
+ name: "my-adp-agent",
138
+ adpConfig: {
139
+ appKey: "your-app-key",
140
+ enableUpload: true, // Enable file upload
141
+ credential: {
142
+ secretId: "your-secret-id",
143
+ secretKey: "your-secret-key",
144
+ },
145
+ },
146
+ });
147
+
148
+ const observable = agent.run({
149
+ runId: randomUUID(),
150
+ threadId: randomUUID(),
151
+ messages: [
152
+ {
153
+ id: randomUUID(),
154
+ role: "user",
155
+ content: [
156
+ { type: "text", text: "What's in this image?" },
157
+ {
158
+ type: "binary",
159
+ mimeType: "image/png",
160
+ filename: "screenshot.png",
161
+ data: fs.readFileSync("./screenshot.png"),
162
+ },
163
+ ],
164
+ },
165
+ ],
166
+ });
167
+ ```
168
+
169
+ **Supported file types:**
170
+
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
+
124
174
  ## API Reference
125
175
 
126
176
  ### AdpAgent
@@ -146,9 +196,11 @@ interface AdpConfig {
146
196
  token?: string; // Session token (optional if TENCENTCLOUD_SESSIONTOKEN env is set)
147
197
  };
148
198
  historyCount?: number; // Number of history messages to retrieve (reserved)
199
+ enableUpload?: boolean; // Enable file upload for images and documents (default: false)
149
200
  request?: {
150
201
  baseUrl?: string; // Base URL for ADP API (default: https://wss.lke.cloud.tencent.com)
151
202
  endpoint?: string; // API endpoint (default: /v1/qbot/chat/sse)
203
+ docParseEndpoint?: string; // Document parse API endpoint (default: /v1/qbot/chat/docParse)
152
204
  body?: Partial<AdpChatRequest>; // Additional request body options
153
205
  };
154
206
  }
@@ -187,6 +239,7 @@ The adapter emits the following AG-UI events:
187
239
  - `axios`: HTTP client for API requests
188
240
  - `rxjs`: Reactive extensions for JavaScript
189
241
  - `tencentcloud-sdk-nodejs-lke`: Tencent Cloud LKE SDK
242
+ - `cos-nodejs-sdk-v5`: Tencent Cloud COS SDK (for file upload)
190
243
 
191
244
  ## Related Resources
192
245
 
package/dist/index.d.mts CHANGED
@@ -59,8 +59,10 @@ type AdpConfig = {
59
59
  baseUrl?: string;
60
60
  endpoint?: string;
61
61
  body?: Partial<AdpChatRequest>;
62
+ docParseEndpoint?: string;
62
63
  };
63
64
  historyCount?: number;
65
+ enableUpload?: boolean;
64
66
  appKey?: string;
65
67
  credential?: {
66
68
  secretId?: string;
@@ -282,6 +284,7 @@ declare class AdpAgent extends AbstractAgent {
282
284
  private reqLkeClient;
283
285
  protected adpConfig: AdpConfig;
284
286
  private finalAppKey;
287
+ private finalCloudCredential;
285
288
  constructor(config: AgentConfig & {
286
289
  adpConfig: AdpConfig;
287
290
  });
package/dist/index.d.ts CHANGED
@@ -59,8 +59,10 @@ type AdpConfig = {
59
59
  baseUrl?: string;
60
60
  endpoint?: string;
61
61
  body?: Partial<AdpChatRequest>;
62
+ docParseEndpoint?: string;
62
63
  };
63
64
  historyCount?: number;
65
+ enableUpload?: boolean;
64
66
  appKey?: string;
65
67
  credential?: {
66
68
  secretId?: string;
@@ -282,6 +284,7 @@ declare class AdpAgent extends AbstractAgent {
282
284
  private reqLkeClient;
283
285
  protected adpConfig: AdpConfig;
284
286
  private finalAppKey;
287
+ private finalCloudCredential;
285
288
  constructor(config: AgentConfig & {
286
289
  adpConfig: AdpConfig;
287
290
  });
package/dist/index.js CHANGED
@@ -129,18 +129,20 @@ var AdpAgent = class extends import_client.AbstractAgent {
129
129
  constructor(config) {
130
130
  super(config);
131
131
  this.finalAppKey = "";
132
+ this.finalCloudCredential = {};
132
133
  this.adpConfig = config.adpConfig;
133
134
  this.finalAppKey = this.adpConfig.appKey || this.adpConfig.request?.body?.botAppKey || process.env.ADP_APP_KEY || "";
134
135
  this.reqAppClient = import_axios.default.create({
135
136
  baseURL: this.adpConfig.request?.baseUrl || "https://wss.lke.cloud.tencent.com"
136
137
  });
137
138
  const LkeClient = import_tencentcloud_sdk_nodejs_lke.lke.v20231130.Client;
139
+ this.finalCloudCredential = {
140
+ secretId: this.adpConfig.credential?.secretId || process.env.TENCENTCLOUD_SECRETID,
141
+ secretKey: this.adpConfig.credential?.secretKey || process.env.TENCENTCLOUD_SECRETKEY,
142
+ token: this.adpConfig.credential?.token || process.env.TENCENTCLOUD_SESSIONTOKEN
143
+ };
138
144
  this.reqLkeClient = new LkeClient({
139
- credential: {
140
- secretId: this.adpConfig.credential?.secretId || process.env.TENCENTCLOUD_SECRETID,
141
- secretKey: this.adpConfig.credential?.secretKey || process.env.TENCENTCLOUD_SECRETKEY,
142
- token: this.adpConfig.credential?.token || process.env.TENCENTCLOUD_SESSIONTOKEN
143
- }
145
+ credential: this.finalCloudCredential
144
146
  });
145
147
  }
146
148
  generateRequestBody({
@@ -169,9 +171,11 @@ var AdpAgent = class extends import_client.AbstractAgent {
169
171
  });
170
172
  }
171
173
  async _run(subscriber, input) {
174
+ let thinkingMessageSet = /* @__PURE__ */ new Set();
175
+ let thinkFinishedMessageSet = /* @__PURE__ */ new Set();
172
176
  try {
173
- const { runId, threadId: _threadId } = input;
174
- const threadId = _threadId || (0, import_crypto.randomUUID)();
177
+ const { runId } = input;
178
+ const threadId = input.threadId || (0, import_crypto.randomUUID)();
175
179
  subscriber.next({
176
180
  type: import_client.EventType.RUN_STARTED,
177
181
  runId,
@@ -183,19 +187,26 @@ var AdpAgent = class extends import_client.AbstractAgent {
183
187
  "MISSING_APP_KEY"
184
188
  );
185
189
  }
186
- const { messages: docExtractedMessages, fileInfos } = await this.extractDocuments(input, subscriber);
187
- const { message, trimmed } = await this.convertAGUIMessagesToAdpMessages(docExtractedMessages);
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);
188
199
  if (!message) {
189
200
  throw new AdpAgentError(
190
201
  "Message content format error, or empty content",
191
202
  "INVALID_MESSAGE_FORMAT"
192
203
  );
193
204
  }
194
- if (trimmed > 0) {
205
+ if (input.messages.length > 1) {
195
206
  subscriber.next({
196
207
  type: import_client.EventType.RAW,
197
208
  rawEvent: {
198
- message: `ADP handles message history itself, so that a total of ${trimmed} messages before and including last assistant message will be trimmed.`,
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.`,
199
210
  type: "warn"
200
211
  }
201
212
  });
@@ -214,7 +225,6 @@ var AdpAgent = class extends import_client.AbstractAgent {
214
225
  let buffer = "";
215
226
  let interruptRequested = false;
216
227
  let thinkingStart = false;
217
- let thinkingMessageSet = /* @__PURE__ */ new Set();
218
228
  for await (const chunk of sseStream) {
219
229
  buffer += chunk.toString();
220
230
  const parts = buffer.split("\n\n");
@@ -241,6 +251,22 @@ var AdpAgent = class extends import_client.AbstractAgent {
241
251
  }
242
252
  switch (data.type) {
243
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
+ }
244
270
  if (data.payload.is_from_self) {
245
271
  if (data.payload.is_evil) {
246
272
  throw new AdpAgentError(
@@ -251,8 +277,6 @@ var AdpAgent = class extends import_client.AbstractAgent {
251
277
  continue;
252
278
  }
253
279
  }
254
- const messageId = data.payload.record_id;
255
- const isFinal = data.payload.is_final;
256
280
  data.payload.content = data.payload.content.replace(
257
281
  /\\n/g,
258
282
  "\n\n"
@@ -332,51 +356,47 @@ var AdpAgent = class extends import_client.AbstractAgent {
332
356
  });
333
357
  }
334
358
  data.payload.procedures.forEach((procedure) => {
335
- if (!thinkingMessageSet.has(messageId)) {
336
- thinkingMessageSet.add(messageId);
359
+ const index = procedure.index.toString();
360
+ if (!thinkingMessageSet.has(index) && !thinkFinishedMessageSet.has(index)) {
361
+ thinkingMessageSet.add(index);
337
362
  subscriber.next({
338
363
  type: import_client.EventType.THINKING_TEXT_MESSAGE_START,
339
- messageId,
364
+ messageId: `${messageId}-think-${index}`,
340
365
  delta: procedure.debugging.content
341
366
  });
342
367
  } else {
343
368
  if (procedure.status === "processing") {
344
369
  subscriber.next({
345
370
  type: import_client.EventType.THINKING_TEXT_MESSAGE_CONTENT,
346
- messageId,
371
+ messageId: `${messageId}-think-${index}`,
347
372
  delta: procedure.debugging.content
348
373
  });
349
374
  } else {
350
- thinkingMessageSet.delete(messageId);
351
- subscriber.next({
352
- type: import_client.EventType.THINKING_TEXT_MESSAGE_END,
353
- messageId
354
- });
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
+ }
355
383
  }
356
384
  }
357
385
  });
358
- const allFinished = data.payload.procedures.every(
359
- (procedure) => procedure.status !== "processing"
360
- );
361
- if (allFinished) {
362
- thinkingStart = false;
363
- thinkingMessageSet.clear();
364
- subscriber.next({
365
- type: import_client.EventType.THINKING_END,
366
- messageId
367
- });
368
- }
369
386
  break;
370
387
  }
371
388
  case "error": {
372
- console.error(JSON.stringify(data));
389
+ console.error(
390
+ "[ERROR] ADP throws error: ",
391
+ JSON.stringify(data)
392
+ );
373
393
  throw new AdpAgentError(
374
394
  data.error.message,
375
395
  data.error.code ? `ADP_ERROR_${data.error.code}` : "ADP_ERROR_-1"
376
396
  );
377
397
  }
378
398
  case "token_stat": {
379
- console.debug(JSON.stringify(data));
399
+ console.debug("[DEBUG] ADP token stat: ", JSON.stringify(data));
380
400
  break;
381
401
  }
382
402
  case "reference": {
@@ -406,7 +426,7 @@ var AdpAgent = class extends import_client.AbstractAgent {
406
426
  }
407
427
  subscriber.complete();
408
428
  } catch (e) {
409
- console.error(JSON.stringify(e));
429
+ console.error("[ERROR] Uncaught error: ", JSON.stringify(e));
410
430
  let code = "UNKNOWN_ERROR";
411
431
  let message = JSON.stringify(e);
412
432
  if (e instanceof import_axios.AxiosError) {
@@ -422,21 +442,33 @@ var AdpAgent = class extends import_client.AbstractAgent {
422
442
  message: `Sorry, an error occurred while running the agent: Error code ${code}, ${message}`
423
443
  });
424
444
  subscriber.complete();
445
+ } finally {
446
+ thinkingMessageSet.clear();
447
+ thinkFinishedMessageSet.clear();
425
448
  }
426
449
  }
427
- async convertAGUIMessagesToAdpMessages(messages) {
450
+ async convertAGUIMessagesToAdpMessages(message) {
428
451
  let result = "";
429
- let trimmed = messages.length;
430
- for (const message of messages.reverse()) {
431
- if (message.role === "assistant") {
432
- break;
433
- }
434
- if (message.role === "user") {
435
- trimmed--;
436
- let content = "";
437
- if (typeof message.content === "string") {
438
- content = message.content;
439
- } else {
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
+ }
440
472
  const imageMap = /* @__PURE__ */ new Map();
441
473
  const imagesToUpload = [];
442
474
  message.content.forEach((item) => {
@@ -479,143 +511,158 @@ var AdpAgent = class extends import_client.AbstractAgent {
479
511
  }
480
512
  }, "").trim();
481
513
  }
482
- result = `${message.role}: ${content}
514
+ }
515
+ result = `${message.role}: ${content}
483
516
  ${result}`;
484
- } else {
485
- result = `${message.role}: ${message.content}
517
+ } else {
518
+ result = `${message.role}: ${message.content}
486
519
  ${result}`;
487
- }
488
520
  }
489
- return { message: result.trim(), trimmed };
521
+ return result.trim();
490
522
  }
491
- async extractDocuments(input, subscriber) {
492
- const { messages, runId, threadId } = input;
523
+ async extractDocuments(message, threadId, subscriber) {
493
524
  const documentFiles = [];
494
- const newMessages = messages.map((msg) => {
495
- if (msg.role === "user" && Array.isArray(msg.content)) {
496
- let newContent = [];
497
- msg.content.forEach((item) => {
498
- if (item.type === "text") {
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 {
499
535
  newContent.push(item);
500
- } else if (item.type === "binary") {
501
- if (Object.keys(DOCUMENT_MIME_TYPES).includes(item.mimeType)) {
502
- documentFiles.push(item);
503
- } else {
504
- newContent.push(item);
505
- }
506
536
  }
507
- });
508
- return {
509
- ...msg,
510
- content: newContent
511
- };
512
- } else return msg;
513
- });
537
+ }
538
+ });
539
+ newMessage = {
540
+ ...message,
541
+ content: newContent
542
+ };
543
+ } else newMessage = message;
514
544
  const fileInfos = [];
515
545
  const successedFiles = [];
516
546
  const failedFiles = [];
517
- if (documentFiles.length) {
518
- try {
519
- await this.uploadToCos(
520
- documentFiles,
521
- (data, cosParams, file) => {
522
- successedFiles.push({ data, cosParams, file });
523
- },
524
- (fileName, error) => {
525
- failedFiles.push({ fileName, error });
526
- }
527
- );
528
- } catch (e) {
547
+ if (this.adpConfig.enableUpload) {
548
+ if (!this.finalCloudCredential.token) {
549
+ if (!this.finalCloudCredential.secretId) {
550
+ throw new AdpAgentError(
551
+ "TENCENTCLOUD_SECRETID is required, check your env variables or config passed with the adapter",
552
+ "MISSING_SECRET_ID"
553
+ );
554
+ }
555
+ if (!this.finalCloudCredential.secretKey) {
556
+ throw new AdpAgentError(
557
+ "TENCENTCLOUD_SECRETKEY is required, check your env variables or config passed with the adapter",
558
+ "MISSING_SECRET_KEY"
559
+ );
560
+ }
529
561
  }
530
- }
531
- if (successedFiles.length) {
532
- successedFiles.forEach(async ({ data: cosData, cosParams, file }) => {
533
- const extName = MIME_TYPES[file.mimeType];
534
- const requestBody = {
535
- sessionId: threadId,
536
- botAppKey: this.finalAppKey,
537
- requestId: (0, import_crypto.randomUUID)(),
538
- cosBucket: cosParams.Bucket,
539
- fileType: extName,
540
- fileName: file.filename,
541
- cosUrl: cosParams.UploadPath,
542
- cosHash: cosData.headers?.["x-cos-hash-crc64ecma"] || "",
543
- eTag: cosData.ETag,
544
- size: file.data?.length.toString() || "0"
545
- };
546
- const response = await this.reqAppClient.post(
547
- this.adpConfig.request?.endpoint || "/v1/qbot/chat/docParse",
548
- camelToSnakeKeys(requestBody),
549
- { responseType: "stream" }
550
- );
551
- const sseStream = response.data;
552
- let buffer = "";
553
- for await (const chunk of sseStream) {
554
- buffer += chunk.toString();
555
- const parts = buffer.split("\n\n");
556
- buffer = parts.pop() || "";
557
- for (const part of parts) {
558
- if (!part.trim()) continue;
559
- const event = { data: "", event: "" };
560
- for (const line of part.split("\n")) {
561
- if (line.startsWith("data:")) {
562
- event.data += line.slice(5);
563
- } else if (line.startsWith("event:")) {
564
- event.event = line.slice(6);
565
- }
562
+ if (documentFiles.length) {
563
+ try {
564
+ await this.uploadToCos(
565
+ documentFiles,
566
+ (data, cosParams, file) => {
567
+ successedFiles.push({ data, cosParams, file });
568
+ },
569
+ (fileName, error) => {
570
+ failedFiles.push({ fileName, error });
566
571
  }
567
- if (event.data) {
568
- let data;
569
- try {
570
- data = JSON.parse(event.data);
571
- } catch (e) {
572
- throw new AdpAgentError(
573
- `ADP returned invalid data: ${event.data}`,
574
- "INVALID_DATA"
575
- );
572
+ );
573
+ } catch (e) {
574
+ console.error("Document upload failed: ", JSON.stringify(e));
575
+ }
576
+ }
577
+ if (successedFiles.length) {
578
+ for (const { data: cosData, cosParams, file } of successedFiles) {
579
+ const extName = MIME_TYPES[file.mimeType];
580
+ const requestBody = {
581
+ sessionId: threadId,
582
+ botAppKey: this.finalAppKey,
583
+ requestId: (0, import_crypto.randomUUID)(),
584
+ cosBucket: cosParams.Bucket,
585
+ fileType: extName,
586
+ fileName: file.filename,
587
+ cosUrl: cosParams.UploadPath,
588
+ cosHash: cosData.headers?.["x-cos-hash-crc64ecma"] || "",
589
+ eTag: cosData.ETag,
590
+ size: file.data?.length.toString() || "0"
591
+ };
592
+ const response = await this.reqAppClient.post(
593
+ this.adpConfig.request?.docParseEndpoint || "/v1/qbot/chat/docParse",
594
+ camelToSnakeKeys(requestBody),
595
+ { responseType: "stream" }
596
+ );
597
+ const sseStream = response.data;
598
+ let buffer = "";
599
+ for await (const chunk of sseStream) {
600
+ buffer += chunk.toString();
601
+ const parts = buffer.split("\n\n");
602
+ buffer = parts.pop() || "";
603
+ for (const part of parts) {
604
+ if (!part.trim()) continue;
605
+ const event = { data: "", event: "" };
606
+ for (const line of part.split("\n")) {
607
+ if (line.startsWith("data:")) {
608
+ event.data += line.slice(5);
609
+ } else if (line.startsWith("event:")) {
610
+ event.event = line.slice(6);
611
+ }
576
612
  }
577
- switch (data.type) {
578
- case "parsing": {
579
- subscriber.next({
580
- type: import_client.EventType.RAW,
581
- rawEvent: {
582
- message: `Parsing document ${file.filename}: ${data.payload.process}%`,
583
- type: "info"
584
- }
585
- });
586
- if (data.payload.is_final) {
587
- if (data.payload.error_message) {
588
- subscriber.next({
589
- type: import_client.EventType.RAW,
590
- rawEvent: {
591
- message: `Parsing document ${file.filename} failed: ${data.payload.error_message}`,
592
- type: "error"
593
- }
594
- });
595
- } else {
596
- const fileNameNoExt = file.filename.split(".").splice(0, -1).join(".");
597
- fileInfos.push({
598
- docId: data.payload.doc_id,
599
- fileName: fileNameNoExt,
600
- fileType: extName,
601
- fileSize: file.data?.length.toString() || "0",
602
- fileUrl: `https://${cosData.Location}`
603
- });
613
+ if (event.data) {
614
+ let data;
615
+ try {
616
+ data = JSON.parse(event.data);
617
+ } catch (e) {
618
+ throw new AdpAgentError(
619
+ `ADP returned invalid data: ${event.data}`,
620
+ "INVALID_DATA"
621
+ );
622
+ }
623
+ switch (data.type) {
624
+ case "parsing": {
625
+ subscriber.next({
626
+ type: import_client.EventType.RAW,
627
+ rawEvent: {
628
+ message: `Parsing document ${file.filename}: ${data.payload.process}%`,
629
+ type: "info"
630
+ }
631
+ });
632
+ if (data.payload.is_final) {
633
+ if (data.payload.error_message) {
634
+ subscriber.next({
635
+ type: import_client.EventType.RAW,
636
+ rawEvent: {
637
+ message: `Parsing document ${file.filename} failed: ${data.payload.error_message}`,
638
+ type: "error"
639
+ }
640
+ });
641
+ } else {
642
+ const fileNameNoExt = file.filename.split(".").splice(0, -1).join(".");
643
+ fileInfos.push({
644
+ docId: data.payload.doc_id,
645
+ fileName: fileNameNoExt,
646
+ fileType: extName,
647
+ fileSize: file.data?.length.toString() || "0",
648
+ fileUrl: `https://${cosData.Location}`
649
+ });
650
+ }
604
651
  }
652
+ break;
653
+ }
654
+ default: {
655
+ break;
605
656
  }
606
- break;
607
- }
608
- default: {
609
- break;
610
657
  }
611
658
  }
612
659
  }
613
660
  }
614
661
  }
615
- });
662
+ }
616
663
  }
617
664
  return {
618
- messages: newMessages,
665
+ message: newMessage,
619
666
  fileInfos,
620
667
  failedFiles
621
668
  };