@cloudbase/agent-adapter-yuanqi 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 CHANGED
@@ -238,17 +238,53 @@ Entity class for chat history records stored in CloudBase.
238
238
  class ChatHistoryEntity {
239
239
  id: number;
240
240
  botId: string;
241
- recordId: string;
242
- role: string;
241
+ recordId: string; // Unique conversation ID
242
+ role: string; // "user" or "assistant"
243
243
  content: string;
244
- status: string;
244
+ recommendQuestions: string[];
245
+ sender: string;
245
246
  conversation: string;
247
+ type: string;
248
+ status: string; // Message status: pending, done, error, cancel
249
+ image: string;
250
+ triggerSrc: string;
251
+ originMsg: string;
246
252
  replyTo: string;
247
253
  reply: string;
248
254
  traceId: string;
255
+ needAsyncReply: boolean;
256
+ asyncReply: string;
257
+ createTime: string;
258
+ updateTime: string;
259
+ createdAt: number;
260
+ updatedAt: number;
261
+ event: string;
262
+ }
263
+ ```
264
+
265
+ ### ChatHistoryData
266
+
267
+ Interface for raw chat history data from CloudBase database.
268
+
269
+ ```typescript
270
+ interface ChatHistoryData {
271
+ bot_id: string;
272
+ record_id: string;
273
+ role: string;
274
+ status: string;
275
+ content: string;
276
+ sender: string;
277
+ conversation: string;
278
+ type: string;
279
+ trigger_src: string;
280
+ origin_msg: string;
281
+ reply_to: string;
282
+ reply: string;
283
+ trace_id: string;
284
+ need_async_reply: boolean;
285
+ async_reply: string;
249
286
  createdAt: number;
250
287
  updatedAt: number;
251
- // ... additional fields
252
288
  }
253
289
  ```
254
290
 
@@ -263,6 +299,28 @@ function createChatHistory(params: {
263
299
  chatHistoryEntity: ChatHistoryEntity;
264
300
  }): Promise<string | undefined>
265
301
 
302
+ // Update chat history by record ID
303
+ function updateChatHistoryByRecordId(params: {
304
+ tcbClient: tcb.CloudBase;
305
+ recordId: string;
306
+ chatHistoryEntity: ChatHistoryEntity;
307
+ }): Promise<string | undefined>
308
+
309
+ // Query chat history from database (paginated)
310
+ function describeChatHistory(params: {
311
+ tcbClient: tcb.CloudBase;
312
+ botId: string;
313
+ sort: "asc" | "desc";
314
+ pageSize?: number;
315
+ pageNumber?: number;
316
+ conversation?: string;
317
+ startCreatedAt?: number;
318
+ triggerSrc?: string;
319
+ }): Promise<[ChatHistoryEntity[], number]>
320
+
321
+ // Transform raw database data to ChatHistoryEntity
322
+ function transDataToChatEntity(item: ChatHistoryData): ChatHistoryEntity
323
+
266
324
  // Query chat history for LLM context
267
325
  function queryForLLM(params: {
268
326
  tcbClient: tcb.CloudBase;
@@ -273,6 +331,16 @@ function queryForLLM(params: {
273
331
  }): Promise<{ role: string; content: string }[]>
274
332
  ```
275
333
 
334
+ ### Message Conversion Utility
335
+
336
+ ```typescript
337
+ // Convert AG-UI messages to OpenAI chat completion format
338
+ function convertMessagesToOpenAI(
339
+ messages: Message[],
340
+ systemPrompt?: string
341
+ ): ChatMessage[]
342
+ ```
343
+
276
344
  ### Supported Events
277
345
 
278
346
  The adapter emits the following AG-UI events:
package/dist/index.d.mts CHANGED
@@ -51,12 +51,13 @@ declare class YuanqiAgent extends AbstractAgent {
51
51
  private _run;
52
52
  protected getChatHistory(subscriber: Subscriber<BaseEvent>, latestUserMessage: Message): Promise<OpenAI.Chat.Completions.ChatCompletionMessageParam[]>;
53
53
  protected saveChatHistory(subscriber: Subscriber<BaseEvent>, input: RunAgentInput, userRecordId: string, assistantRecordId: string, userContent: string, assistantContent: string): Promise<void>;
54
+ private getTcbClient;
54
55
  private checkIsDatabaseReady;
55
56
  }
56
57
  /**
57
58
  * Convert AGUI messages to OpenAI chat completion format
58
59
  */
59
- declare function convertMessagesToOpenAI(messages: Message[], systemPrompt?: string): OpenAI.Chat.ChatCompletionMessageParam[];
60
+ declare function convertMessagesToOpenAI(messages: Message[], systemPrompt?: string): ChatMessage[];
60
61
 
61
62
  interface StreamContext {
62
63
  threadId: string;
@@ -78,10 +79,31 @@ declare function processYuanqiStream(stream: AsyncIterable<OpenAI.Chat.Completio
78
79
  type: EventType;
79
80
  threadId: string;
80
81
  runId: string;
81
- messageId: string;
82
+ toolCallId: any;
83
+ content?: undefined;
84
+ messageId?: undefined;
85
+ role?: undefined;
86
+ delta?: undefined;
87
+ toolCallName?: undefined;
88
+ } | {
89
+ type: EventType;
90
+ threadId: string;
91
+ runId: string;
92
+ toolCallId: any;
93
+ content: string;
94
+ messageId?: undefined;
82
95
  role?: undefined;
83
96
  delta?: undefined;
97
+ toolCallName?: undefined;
98
+ } | {
99
+ type: EventType;
100
+ threadId: string;
101
+ runId: string;
102
+ messageId: string;
84
103
  toolCallId?: undefined;
104
+ content?: undefined;
105
+ role?: undefined;
106
+ delta?: undefined;
85
107
  toolCallName?: undefined;
86
108
  } | {
87
109
  type: EventType;
@@ -89,8 +111,9 @@ declare function processYuanqiStream(stream: AsyncIterable<OpenAI.Chat.Completio
89
111
  runId: string;
90
112
  messageId: string;
91
113
  role: string;
92
- delta?: undefined;
93
114
  toolCallId?: undefined;
115
+ content?: undefined;
116
+ delta?: undefined;
94
117
  toolCallName?: undefined;
95
118
  } | {
96
119
  type: EventType;
@@ -98,8 +121,9 @@ declare function processYuanqiStream(stream: AsyncIterable<OpenAI.Chat.Completio
98
121
  runId: string;
99
122
  messageId: string;
100
123
  delta: string;
101
- role?: undefined;
102
124
  toolCallId?: undefined;
125
+ content?: undefined;
126
+ role?: undefined;
103
127
  toolCallName?: undefined;
104
128
  } | {
105
129
  type: EventType;
@@ -107,6 +131,7 @@ declare function processYuanqiStream(stream: AsyncIterable<OpenAI.Chat.Completio
107
131
  runId: string;
108
132
  toolCallId: string;
109
133
  toolCallName: string;
134
+ content?: undefined;
110
135
  messageId?: undefined;
111
136
  role?: undefined;
112
137
  delta?: undefined;
@@ -116,18 +141,10 @@ declare function processYuanqiStream(stream: AsyncIterable<OpenAI.Chat.Completio
116
141
  runId: string;
117
142
  toolCallId: string;
118
143
  delta: string;
144
+ content?: undefined;
119
145
  messageId?: undefined;
120
146
  role?: undefined;
121
147
  toolCallName?: undefined;
122
- } | {
123
- type: EventType;
124
- threadId: string;
125
- runId: string;
126
- toolCallId: string;
127
- messageId?: undefined;
128
- role?: undefined;
129
- delta?: undefined;
130
- toolCallName?: undefined;
131
148
  }, void, unknown>;
132
149
 
133
150
  declare function createChatHistory({ tcbClient, chatHistoryEntity, }: {
@@ -190,7 +207,7 @@ declare class ChatHistoryEntity {
190
207
  conversation: string;
191
208
  type: string;
192
209
  /**
193
- * 消息状态,pending donw error cancel
210
+ * 消息状态,pending done error cancel
194
211
  */
195
212
  status: string;
196
213
  image: string;
package/dist/index.d.ts CHANGED
@@ -51,12 +51,13 @@ declare class YuanqiAgent extends AbstractAgent {
51
51
  private _run;
52
52
  protected getChatHistory(subscriber: Subscriber<BaseEvent>, latestUserMessage: Message): Promise<OpenAI.Chat.Completions.ChatCompletionMessageParam[]>;
53
53
  protected saveChatHistory(subscriber: Subscriber<BaseEvent>, input: RunAgentInput, userRecordId: string, assistantRecordId: string, userContent: string, assistantContent: string): Promise<void>;
54
+ private getTcbClient;
54
55
  private checkIsDatabaseReady;
55
56
  }
56
57
  /**
57
58
  * Convert AGUI messages to OpenAI chat completion format
58
59
  */
59
- declare function convertMessagesToOpenAI(messages: Message[], systemPrompt?: string): OpenAI.Chat.ChatCompletionMessageParam[];
60
+ declare function convertMessagesToOpenAI(messages: Message[], systemPrompt?: string): ChatMessage[];
60
61
 
61
62
  interface StreamContext {
62
63
  threadId: string;
@@ -78,10 +79,31 @@ declare function processYuanqiStream(stream: AsyncIterable<OpenAI.Chat.Completio
78
79
  type: EventType;
79
80
  threadId: string;
80
81
  runId: string;
81
- messageId: string;
82
+ toolCallId: any;
83
+ content?: undefined;
84
+ messageId?: undefined;
85
+ role?: undefined;
86
+ delta?: undefined;
87
+ toolCallName?: undefined;
88
+ } | {
89
+ type: EventType;
90
+ threadId: string;
91
+ runId: string;
92
+ toolCallId: any;
93
+ content: string;
94
+ messageId?: undefined;
82
95
  role?: undefined;
83
96
  delta?: undefined;
97
+ toolCallName?: undefined;
98
+ } | {
99
+ type: EventType;
100
+ threadId: string;
101
+ runId: string;
102
+ messageId: string;
84
103
  toolCallId?: undefined;
104
+ content?: undefined;
105
+ role?: undefined;
106
+ delta?: undefined;
85
107
  toolCallName?: undefined;
86
108
  } | {
87
109
  type: EventType;
@@ -89,8 +111,9 @@ declare function processYuanqiStream(stream: AsyncIterable<OpenAI.Chat.Completio
89
111
  runId: string;
90
112
  messageId: string;
91
113
  role: string;
92
- delta?: undefined;
93
114
  toolCallId?: undefined;
115
+ content?: undefined;
116
+ delta?: undefined;
94
117
  toolCallName?: undefined;
95
118
  } | {
96
119
  type: EventType;
@@ -98,8 +121,9 @@ declare function processYuanqiStream(stream: AsyncIterable<OpenAI.Chat.Completio
98
121
  runId: string;
99
122
  messageId: string;
100
123
  delta: string;
101
- role?: undefined;
102
124
  toolCallId?: undefined;
125
+ content?: undefined;
126
+ role?: undefined;
103
127
  toolCallName?: undefined;
104
128
  } | {
105
129
  type: EventType;
@@ -107,6 +131,7 @@ declare function processYuanqiStream(stream: AsyncIterable<OpenAI.Chat.Completio
107
131
  runId: string;
108
132
  toolCallId: string;
109
133
  toolCallName: string;
134
+ content?: undefined;
110
135
  messageId?: undefined;
111
136
  role?: undefined;
112
137
  delta?: undefined;
@@ -116,18 +141,10 @@ declare function processYuanqiStream(stream: AsyncIterable<OpenAI.Chat.Completio
116
141
  runId: string;
117
142
  toolCallId: string;
118
143
  delta: string;
144
+ content?: undefined;
119
145
  messageId?: undefined;
120
146
  role?: undefined;
121
147
  toolCallName?: undefined;
122
- } | {
123
- type: EventType;
124
- threadId: string;
125
- runId: string;
126
- toolCallId: string;
127
- messageId?: undefined;
128
- role?: undefined;
129
- delta?: undefined;
130
- toolCallName?: undefined;
131
148
  }, void, unknown>;
132
149
 
133
150
  declare function createChatHistory({ tcbClient, chatHistoryEntity, }: {
@@ -190,7 +207,7 @@ declare class ChatHistoryEntity {
190
207
  conversation: string;
191
208
  type: string;
192
209
  /**
193
- * 消息状态,pending donw error cancel
210
+ * 消息状态,pending done error cancel
194
211
  */
195
212
  status: string;
196
213
  image: string;
package/dist/index.js CHANGED
@@ -97,6 +97,28 @@ async function* processYuanqiStream(stream, context) {
97
97
  for await (const chunk of stream) {
98
98
  const delta = chunk.choices[0]?.delta;
99
99
  if (!delta) continue;
100
+ if (delta.role === "tool") {
101
+ const toolCallId = delta.tool_call_id;
102
+ if (toolCallId) {
103
+ if (state.toolCallsMap.has(toolCallId)) {
104
+ yield {
105
+ type: import_client.EventType.TOOL_CALL_END,
106
+ threadId,
107
+ runId,
108
+ toolCallId
109
+ };
110
+ state.toolCallsMap.delete(toolCallId);
111
+ }
112
+ yield {
113
+ type: import_client.EventType.TOOL_CALL_RESULT,
114
+ threadId,
115
+ runId,
116
+ toolCallId,
117
+ content: delta.content || ""
118
+ };
119
+ }
120
+ continue;
121
+ }
100
122
  if (delta.content) {
101
123
  if (reasoningState.hasStarted) {
102
124
  reasoningState.hasStarted = false;
@@ -169,6 +191,15 @@ async function* processYuanqiStream(stream, context) {
169
191
  toolCallId,
170
192
  toolCallName: toolCall.function.name
171
193
  };
194
+ if (toolCall.function.arguments) {
195
+ yield {
196
+ type: import_client.EventType.TOOL_CALL_ARGS,
197
+ threadId,
198
+ runId,
199
+ toolCallId,
200
+ delta: toolCall.function.arguments
201
+ };
202
+ }
172
203
  state.toolCallsMap.set(toolCallId, {
173
204
  name: toolCall.function.name,
174
205
  args: toolCall.function.arguments || ""
@@ -197,6 +228,20 @@ async function* processYuanqiStream(stream, context) {
197
228
  messageId
198
229
  };
199
230
  }
231
+ if (reasoningState.hasStarted) {
232
+ yield {
233
+ type: import_client.EventType.THINKING_TEXT_MESSAGE_END,
234
+ threadId,
235
+ runId,
236
+ messageId
237
+ };
238
+ yield {
239
+ type: import_client.EventType.THINKING_END,
240
+ threadId,
241
+ runId,
242
+ messageId
243
+ };
244
+ }
200
245
  for (const [toolCallId] of state.toolCallsMap) {
201
246
  yield {
202
247
  type: import_client.EventType.TOOL_CALL_END,
@@ -439,9 +484,9 @@ var YuanqiAgent = class extends import_client2.AbstractAgent {
439
484
  }
440
485
  async _run(subscriber, input) {
441
486
  try {
442
- const { messages, runId, threadId: _threadId } = input;
487
+ const { messages, runId } = input;
443
488
  const openai = this.model;
444
- const threadId = _threadId || (0, import_crypto.randomUUID)();
489
+ const threadId = input.threadId || (0, import_crypto.randomUUID)();
445
490
  subscriber.next({
446
491
  type: import_client2.EventType.RUN_STARTED,
447
492
  threadId,
@@ -523,7 +568,7 @@ var YuanqiAgent = class extends import_client2.AbstractAgent {
523
568
  runId
524
569
  });
525
570
  } catch (e) {
526
- console.error(JSON.stringify(e));
571
+ console.error("[ERROR] Uncaught error: ", JSON.stringify(e));
527
572
  let code = "UNKNOWN_ERROR";
528
573
  let message = JSON.stringify(e);
529
574
  if (e instanceof YuanqiAgentError) {
@@ -544,9 +589,9 @@ var YuanqiAgent = class extends import_client2.AbstractAgent {
544
589
  }
545
590
  // Can be override by subclasses
546
591
  async getChatHistory(subscriber, latestUserMessage) {
547
- const envId = this.yuanqiConfig.envId || getCloudbaseEnvId();
548
592
  const botId = `bot-yuanqi-${this.finalAppId}`;
549
- const isDBReady = await this.checkIsDatabaseReady(envId);
593
+ const tcbClient = this.getTcbClient();
594
+ const isDBReady = await this.checkIsDatabaseReady();
550
595
  if (!isDBReady) {
551
596
  subscriber.next({
552
597
  type: import_client2.EventType.RAW,
@@ -557,12 +602,6 @@ var YuanqiAgent = class extends import_client2.AbstractAgent {
557
602
  });
558
603
  return convertMessagesToOpenAI([latestUserMessage]);
559
604
  }
560
- const tcbClient = import_node_sdk.default.init({
561
- env: envId,
562
- secretId: this.finalCloudCredential.secretId,
563
- secretKey: this.finalCloudCredential.secretKey,
564
- sessionToken: this.finalCloudCredential.token
565
- });
566
605
  let historyMessages = [];
567
606
  const historyCount = this.yuanqiConfig.historyCount ?? 10;
568
607
  const historyRecords = await queryForLLM({
@@ -581,10 +620,10 @@ var YuanqiAgent = class extends import_client2.AbstractAgent {
581
620
  }
582
621
  // Can be override by subclasses
583
622
  async saveChatHistory(subscriber, input, userRecordId, assistantRecordId, userContent, assistantContent) {
584
- const envId = this.yuanqiConfig.envId || getCloudbaseEnvId();
585
623
  const botId = `bot-yuanqi-${this.finalAppId}`;
586
624
  const { threadId, runId } = input;
587
- const isDBReady = await this.checkIsDatabaseReady(envId);
625
+ const tcbClient = this.getTcbClient();
626
+ const isDBReady = await this.checkIsDatabaseReady();
588
627
  if (!isDBReady) {
589
628
  subscriber.next({
590
629
  type: import_client2.EventType.RAW,
@@ -595,12 +634,6 @@ var YuanqiAgent = class extends import_client2.AbstractAgent {
595
634
  });
596
635
  return;
597
636
  }
598
- const tcbClient = import_node_sdk.default.init({
599
- env: envId,
600
- secretId: this.finalCloudCredential.secretId,
601
- secretKey: this.finalCloudCredential.secretKey,
602
- sessionToken: this.finalCloudCredential.token
603
- });
604
637
  const userEntity = new ChatHistoryEntity();
605
638
  userEntity.recordId = userRecordId;
606
639
  userEntity.botId = botId;
@@ -626,28 +659,39 @@ var YuanqiAgent = class extends import_client2.AbstractAgent {
626
659
  chatHistoryEntity: assistantEntity
627
660
  });
628
661
  }
629
- async checkIsDatabaseReady(envId) {
630
- if (!envId) {
631
- throw new YuanqiAgentError(
632
- "CLOUDBASE_ENV_ID is required, check your env variables or config passed with the adapter",
633
- "MISSING_CLOUDBASE_ENV_ID"
634
- );
635
- }
636
- if (!this.finalCloudCredential.token) {
637
- if (!this.finalCloudCredential.secretId) {
662
+ getTcbClient() {
663
+ const envId = this.yuanqiConfig.envId || getCloudbaseEnvId();
664
+ const tcbClient = import_node_sdk.default.init({
665
+ env: envId,
666
+ secretId: this.finalCloudCredential.secretId,
667
+ secretKey: this.finalCloudCredential.secretKey,
668
+ sessionToken: this.finalCloudCredential.token
669
+ });
670
+ return tcbClient;
671
+ }
672
+ async checkIsDatabaseReady() {
673
+ try {
674
+ const envId = this.yuanqiConfig.envId || getCloudbaseEnvId();
675
+ if (!envId) {
638
676
  throw new YuanqiAgentError(
639
- "TENCENTCLOUD_SECRETID is required, check your env variables or config passed with the adapter",
640
- "MISSING_SECRET_ID"
677
+ "When saving chat history to CloudBase, CLOUDBASE_ENV_ID is required, check your env variables or config passed with the adapter",
678
+ "MISSING_CLOUDBASE_ENV_ID"
641
679
  );
642
680
  }
643
- if (!this.finalCloudCredential.secretKey) {
644
- throw new YuanqiAgentError(
645
- "TENCENTCLOUD_SECRETKEY is required, check your env variables or config passed with the adapter",
646
- "MISSING_SECRET_KEY"
647
- );
681
+ if (!this.finalCloudCredential.token) {
682
+ if (!this.finalCloudCredential.secretId) {
683
+ throw new YuanqiAgentError(
684
+ "When saving chat history to CloudBase, TENCENTCLOUD_SECRETID is required, check your env variables or config passed with the adapter",
685
+ "MISSING_SECRET_ID"
686
+ );
687
+ }
688
+ if (!this.finalCloudCredential.secretKey) {
689
+ throw new YuanqiAgentError(
690
+ "When saving chat history to CloudBase, TENCENTCLOUD_SECRETKEY is required, check your env variables or config passed with the adapter",
691
+ "MISSING_SECRET_KEY"
692
+ );
693
+ }
648
694
  }
649
- }
650
- try {
651
695
  const managedTcbClient = import_manager_node.default.init({
652
696
  envId,
653
697
  secretId: this.finalCloudCredential.secretId,
@@ -664,10 +708,12 @@ var YuanqiAgent = class extends import_client2.AbstractAgent {
664
708
  CHAT_HISTORY_DATA_SOURCE
665
709
  );
666
710
  return true;
711
+ } else {
712
+ throw new Error("Check database exists failed");
667
713
  }
668
714
  } catch (dbError) {
669
715
  console.error(
670
- "Failed to check/create chat history collection:",
716
+ "[ERROR] Failed to check/create chat history collection:",
671
717
  JSON.stringify(dbError)
672
718
  );
673
719
  return false;
@@ -675,9 +721,9 @@ var YuanqiAgent = class extends import_client2.AbstractAgent {
675
721
  }
676
722
  };
677
723
  function getCloudbaseEnvId() {
678
- if (!!process.env.CBR_ENV_ID) {
724
+ if (process.env.CBR_ENV_ID) {
679
725
  return process.env.CBR_ENV_ID;
680
- } else if (!!process.env.SCF_NAMESPACE) {
726
+ } else if (process.env.SCF_NAMESPACE) {
681
727
  return process.env.SCF_NAMESPACE;
682
728
  } else {
683
729
  return process.env.CLOUDBASE_ENV_ID || "";
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/agent.ts","../src/utils.ts","../src/stream.ts","../src/constant.ts","../src/chat_history.ts"],"sourcesContent":["export * from \"./agent\";\n\nexport * from \"./types\";\n\nexport * from \"./stream\";\n\nexport * from \"./chat_history\";\n","import {\n RunAgentInput,\n Message,\n AbstractAgent,\n AgentConfig,\n BaseEvent,\n EventType,\n} from \"@ag-ui/client\";\nimport tcb from \"@cloudbase/node-sdk\";\nimport managedTcb from \"@cloudbase/manager-node\";\nimport OpenAI from \"openai\";\nimport { randomUUID } from \"crypto\";\nimport { camelToSnakeKeys } from \"./utils\";\nimport { processYuanqiStream } from \"./stream\";\nimport { Observable, Subscriber } from \"rxjs\";\nimport {\n createChatHistory,\n queryForLLM,\n ChatHistoryEntity,\n} from \"./chat_history\";\nimport { CHAT_HISTORY_DATA_SOURCE } from \"./constant\";\nimport { YuanqiConfig, ChatMessage, YuanqiChatRequest } from \"./types\";\n\nexport class YuanqiAgentError extends Error {\n code?: string;\n constructor(message: string, code?: string) {\n super(message);\n this.name = \"YuanqiAgentError\";\n if (code) this.code = code;\n }\n}\n\nexport class YuanqiAgent extends AbstractAgent {\n protected yuanqiConfig: YuanqiConfig;\n private finalAppId: string;\n private finalCloudCredential: {\n secretId?: string;\n secretKey?: string;\n token?: string;\n } = {};\n private model: OpenAI;\n constructor(config: AgentConfig & { yuanqiConfig: YuanqiConfig }) {\n super(config);\n this.yuanqiConfig = config.yuanqiConfig;\n this.model = new OpenAI({\n apiKey: \"\",\n baseURL:\n this.yuanqiConfig.request?.baseUrl ||\n \"https://yuanqi.tencent.com/openapi/v1/agent\",\n });\n this.finalAppId =\n this.yuanqiConfig.appId ||\n this.yuanqiConfig.request?.body?.assistantId ||\n process.env.YUANQI_APP_ID ||\n \"\";\n this.finalCloudCredential = {\n secretId:\n this.yuanqiConfig.credential?.secretId ||\n process.env.TENCENTCLOUD_SECRETID,\n secretKey:\n this.yuanqiConfig.credential?.secretKey ||\n process.env.TENCENTCLOUD_SECRETKEY,\n token:\n this.yuanqiConfig.credential?.token ||\n process.env.TENCENTCLOUD_SESSIONTOKEN,\n };\n }\n\n generateRequestBody({\n messages,\n input,\n }: {\n messages: ChatMessage[];\n input: RunAgentInput;\n }): YuanqiChatRequest {\n const { state, forwardedProps } = input;\n const requestBody: YuanqiChatRequest = {\n stream: true,\n ...(this.yuanqiConfig.request?.body || {}),\n ...(forwardedProps || {}),\n\n assistantId: this.finalAppId,\n userId:\n state?.__request_context__?.id ||\n forwardedProps?.userId ||\n randomUUID(),\n messages,\n };\n return requestBody;\n }\n\n run(input: RunAgentInput): Observable<BaseEvent> {\n return new Observable<BaseEvent>((subscriber) => {\n this._run(subscriber, input);\n });\n }\n\n private async _run(subscriber: any, input: RunAgentInput): Promise<void> {\n try {\n const { messages, runId, threadId: _threadId } = input;\n\n const openai = this.model as OpenAI;\n const threadId = _threadId || randomUUID();\n\n subscriber.next({\n type: EventType.RUN_STARTED,\n threadId,\n runId,\n });\n\n if (!this.finalAppId) {\n throw new YuanqiAgentError(\n \"YUANQI_APP_ID is required, check your env variables or config passed with the adapter\",\n \"MISSING_YUANQI_APP_ID\"\n );\n }\n if (!this.yuanqiConfig.appKey && !process.env.YUANQI_APP_KEY) {\n throw new YuanqiAgentError(\n \"YUANQI_APP_KEY is required, check your env variables or config passed with the adapter\",\n \"MISSING_YUANQI_APP_KEY\"\n );\n }\n\n // Warn user if messages are being trimmed (only using latest user message)\n const trimmedCount = messages.length - 1;\n if (trimmedCount > 0) {\n subscriber.next({\n type: EventType.RAW,\n rawEvent: {\n message: `Yuanqi handles message history itself, so that a total of ${trimmedCount} messages before the last user message will be trimmed.`,\n type: \"warn\",\n },\n });\n }\n\n // Get the latest user message for saving to history\n const latestUserMessage = messages.filter((m) => m.role === \"user\").pop();\n if (!latestUserMessage) {\n throw new YuanqiAgentError(\n \"No user message found, please send a message first.\",\n \"MESSAGE_FORMAT_ERROR\"\n );\n }\n\n const allMessages = await this.getChatHistory(\n subscriber,\n latestUserMessage\n );\n\n const body = this.generateRequestBody({\n messages: allMessages,\n input,\n });\n\n const stream = await openai.chat.completions.create(\n {\n stream: true,\n messages: [],\n model: \"\",\n },\n {\n body: camelToSnakeKeys(body),\n headers: {\n ...this.yuanqiConfig.request?.headers,\n Authorization: `Bearer ${\n this.yuanqiConfig.appKey || process.env.YUANQI_APP_KEY\n }`,\n },\n }\n );\n\n // Process stream and emit AGUI events, collect full response\n const userRecordId = `record-${randomUUID().slice(0, 8)}`;\n const assistantRecordId = `record-${randomUUID().slice(0, 8)}`;\n const context = { threadId, runId, messageId: userRecordId };\n\n let fullAssistantContent = \"\";\n\n for await (const event of processYuanqiStream(stream, context)) {\n subscriber.next(event);\n // Collect assistant content from TEXT_MESSAGE_CONTENT events\n if (\n event.type === EventType.TEXT_MESSAGE_CONTENT &&\n (event as any).delta\n ) {\n fullAssistantContent += (event as any).delta;\n }\n }\n\n const userContent =\n typeof latestUserMessage?.content === \"string\"\n ? latestUserMessage.content\n : latestUserMessage?.content\n ?.filter((c) => c.type === \"text\")\n .map((c) => (c as any).text)\n .join(\"\") || \"\";\n\n await this.saveChatHistory(\n subscriber,\n input,\n userRecordId,\n assistantRecordId,\n userContent,\n fullAssistantContent\n );\n\n subscriber.next({\n type: EventType.RUN_FINISHED,\n threadId,\n runId,\n } as any);\n } catch (e: unknown) {\n console.error(JSON.stringify(e));\n let code = \"UNKNOWN_ERROR\";\n let message = JSON.stringify(e);\n if (e instanceof YuanqiAgentError) {\n code = e.code || \"AGENT_ERROR\";\n message = e.message;\n } else if (e instanceof Error) {\n code = e.name || \"ERROR\";\n message = e.message;\n }\n subscriber.next({\n type: EventType.RUN_ERROR,\n code,\n message: `Sorry, an error occurred while running the agent: Error code ${code}, ${message}`,\n } as any);\n } finally {\n subscriber.complete();\n }\n }\n\n // Can be override by subclasses\n protected async getChatHistory(\n subscriber: Subscriber<BaseEvent>,\n latestUserMessage: Message\n ) {\n const envId = this.yuanqiConfig.envId || getCloudbaseEnvId();\n const botId = `bot-yuanqi-${this.finalAppId}`;\n\n const isDBReady = await this.checkIsDatabaseReady(envId);\n if (!isDBReady) {\n subscriber.next({\n type: EventType.RAW,\n rawEvent: {\n message: `Chat history database is not ready, skip history loading.`,\n type: \"warn\",\n },\n });\n return convertMessagesToOpenAI([latestUserMessage]);\n }\n\n const tcbClient = tcb.init({\n env: envId,\n secretId: this.finalCloudCredential.secretId,\n secretKey: this.finalCloudCredential.secretKey,\n sessionToken: this.finalCloudCredential.token,\n });\n\n // Fetch chat history from database using queryForLLM\n let historyMessages: ChatMessage[] = [];\n\n const historyCount = this.yuanqiConfig.historyCount ?? 10;\n const historyRecords = await queryForLLM({\n tcbClient,\n botId,\n pageSize: historyCount,\n });\n\n // Convert queryForLLM result to ChatMessage format\n historyMessages = historyRecords.map((record) => ({\n role: record.role as \"user\" | \"assistant\",\n content: [{ type: \"text\" as const, text: record.content }],\n }));\n\n // Combine history messages with current messages\n const allMessages = historyMessages.concat(\n convertMessagesToOpenAI([latestUserMessage])\n );\n return allMessages;\n }\n\n // Can be override by subclasses\n protected async saveChatHistory(\n subscriber: Subscriber<BaseEvent>,\n input: RunAgentInput,\n userRecordId: string,\n assistantRecordId: string,\n userContent: string,\n assistantContent: string\n ) {\n const envId = this.yuanqiConfig.envId || getCloudbaseEnvId();\n const botId = `bot-yuanqi-${this.finalAppId}`;\n\n const { threadId, runId } = input;\n\n const isDBReady = await this.checkIsDatabaseReady(envId);\n if (!isDBReady) {\n subscriber.next({\n type: EventType.RAW,\n rawEvent: {\n message: `Chat history database is not ready, skip history saving.`,\n type: \"warn\",\n },\n });\n return;\n }\n\n const tcbClient = tcb.init({\n env: envId,\n secretId: this.finalCloudCredential.secretId,\n secretKey: this.finalCloudCredential.secretKey,\n sessionToken: this.finalCloudCredential.token,\n });\n\n // Save message pair to history\n const userEntity = new ChatHistoryEntity();\n userEntity.recordId = userRecordId;\n userEntity.botId = botId;\n userEntity.role = \"user\";\n userEntity.content = userContent;\n userEntity.conversation = threadId;\n userEntity.reply = assistantRecordId;\n userEntity.triggerSrc = \"\";\n userEntity.traceId = randomUUID();\n\n await createChatHistory({ tcbClient, chatHistoryEntity: userEntity });\n\n const assistantEntity = new ChatHistoryEntity();\n assistantEntity.recordId = assistantRecordId;\n assistantEntity.botId = botId;\n assistantEntity.role = \"assistant\";\n assistantEntity.content = assistantContent;\n assistantEntity.conversation = threadId;\n assistantEntity.replyTo = userRecordId;\n assistantEntity.triggerSrc = \"\";\n assistantEntity.traceId = runId;\n assistantEntity.status = \"done\";\n\n await createChatHistory({\n tcbClient,\n chatHistoryEntity: assistantEntity,\n });\n }\n\n private async checkIsDatabaseReady(envId: string) {\n if (!envId) {\n throw new YuanqiAgentError(\n \"CLOUDBASE_ENV_ID is required, check your env variables or config passed with the adapter\",\n \"MISSING_CLOUDBASE_ENV_ID\"\n );\n }\n if (!this.finalCloudCredential.token) {\n if (!this.finalCloudCredential.secretId) {\n throw new YuanqiAgentError(\n \"TENCENTCLOUD_SECRETID is required, check your env variables or config passed with the adapter\",\n \"MISSING_SECRET_ID\"\n );\n }\n if (!this.finalCloudCredential.secretKey) {\n throw new YuanqiAgentError(\n \"TENCENTCLOUD_SECRETKEY is required, check your env variables or config passed with the adapter\",\n \"MISSING_SECRET_KEY\"\n );\n }\n }\n\n try {\n const managedTcbClient = managedTcb.init({\n envId,\n secretId: this.finalCloudCredential.secretId,\n secretKey: this.finalCloudCredential.secretKey,\n token: this.finalCloudCredential.token,\n });\n\n const checkDBRes = await managedTcbClient.database.checkCollectionExists(\n CHAT_HISTORY_DATA_SOURCE\n );\n if (checkDBRes && checkDBRes.Exists) {\n return true;\n } else if (checkDBRes && !checkDBRes.Exists) {\n await managedTcbClient.database.createCollection(\n CHAT_HISTORY_DATA_SOURCE\n );\n return true;\n }\n } catch (dbError) {\n console.error(\n \"Failed to check/create chat history collection:\",\n JSON.stringify(dbError)\n );\n return false;\n }\n }\n}\n\nfunction getCloudbaseEnvId() {\n if (!!process.env.CBR_ENV_ID) {\n return process.env.CBR_ENV_ID;\n } else if (!!process.env.SCF_NAMESPACE) {\n return process.env.SCF_NAMESPACE;\n } else {\n return process.env.CLOUDBASE_ENV_ID || \"\";\n }\n}\n\n/**\n * Convert AGUI messages to OpenAI chat completion format\n */\nexport function convertMessagesToOpenAI(\n messages: Message[],\n systemPrompt?: string\n): OpenAI.Chat.ChatCompletionMessageParam[] {\n const openaiMessages: OpenAI.Chat.ChatCompletionMessageParam[] = [];\n\n // Add system prompt if provided\n if (systemPrompt) {\n openaiMessages.push({\n role: \"system\",\n content: systemPrompt,\n });\n }\n\n // Convert messages\n for (const msg of messages) {\n if (msg.role === \"user\") {\n openaiMessages.push({\n role: \"user\",\n content:\n typeof msg.content === \"string\"\n ? [{ type: \"text\", text: msg.content }]\n : msg.content.map((item) => {\n if (item.type === \"text\") {\n return { type: \"text\", text: item.text };\n } else {\n return {\n type: \"image_url\",\n image_url: { url: item.url || \"\" },\n };\n }\n }),\n });\n } else if (msg.role === \"assistant\") {\n openaiMessages.push({\n role: \"assistant\",\n content: msg.content ? [{ type: \"text\", text: msg.content }] : [],\n tool_calls: msg.toolCalls?.map((tc: any) => ({\n id: tc.id,\n type: \"function\" as const,\n function: {\n name: tc.function.name,\n arguments: tc.function.arguments,\n },\n })),\n });\n } else if (msg.role === \"tool\") {\n openaiMessages.push({\n role: \"tool\",\n tool_call_id: msg.toolCallId!,\n content: msg.content ? [{ type: \"text\", text: msg.content }] : [],\n });\n }\n }\n\n return openaiMessages;\n}\n","/**\n * 将小驼峰字符串转换为下划线格式\n * 例如: \"userName\" -> \"user_name\"\n */\nfunction camelToSnake(str: string): string {\n return str.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`);\n}\n\n/**\n * 递归地将对象的所有小驼峰属性名转换为下划线格式\n */\nexport function camelToSnakeKeys<T>(obj: T): T {\n if (obj === null || obj === undefined) {\n return obj;\n }\n\n if (Array.isArray(obj)) {\n return obj.map((item) => camelToSnakeKeys(item)) as T;\n }\n\n if (typeof obj === \"object\") {\n const result: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(obj)) {\n const snakeKey = camelToSnake(key);\n result[snakeKey] = camelToSnakeKeys(value);\n }\n return result as T;\n }\n\n return obj;\n}\n\nexport function genRandomStr(length: number): string {\n const chars = \"abcdefghijklmnopqrstuvwxyz0123456789\";\n let result = \"\";\n for (let i = 0; i < length; i++) {\n result += chars.charAt(Math.floor(Math.random() * chars.length));\n }\n return result;\n}\n","import OpenAI from \"openai\";\nimport { EventType } from \"@ag-ui/client\";\n\nexport interface StreamContext {\n threadId: string;\n runId: string;\n messageId: string;\n}\n\nexport interface StreamState {\n hasStarted: boolean;\n fullContent: string;\n toolCallsMap: Map<string, { name: string; args: string }>;\n}\n\nexport type Delta =\n OpenAI.Chat.Completions.ChatCompletionChunk[\"choices\"][number][\"delta\"] & {\n reasoning_content?: string;\n };\n\nexport async function* processYuanqiStream(\n stream: AsyncIterable<OpenAI.Chat.Completions.ChatCompletionChunk>,\n context: StreamContext\n) {\n const { threadId, runId, messageId } = context;\n const state: StreamState = {\n hasStarted: false,\n fullContent: \"\",\n toolCallsMap: new Map(),\n };\n const reasoningState: StreamState = {\n hasStarted: false,\n fullContent: \"\",\n toolCallsMap: new Map(),\n };\n\n for await (const chunk of stream) {\n const delta = chunk.choices[0]?.delta as Delta;\n if (!delta) continue;\n\n // Handle text content\n if (delta.content) {\n // End reasoning message if it was started\n if (reasoningState.hasStarted) {\n reasoningState.hasStarted = false;\n yield {\n type: EventType.THINKING_TEXT_MESSAGE_END,\n threadId,\n runId,\n messageId,\n };\n yield {\n type: EventType.THINKING_END,\n threadId,\n runId,\n messageId,\n };\n }\n\n if (!state.hasStarted) {\n yield {\n type: EventType.TEXT_MESSAGE_START,\n threadId,\n runId,\n messageId,\n role: \"assistant\",\n };\n state.hasStarted = true;\n }\n\n state.fullContent += delta.content;\n yield {\n type: EventType.TEXT_MESSAGE_CONTENT,\n threadId,\n runId,\n messageId,\n delta: delta.content,\n };\n }\n\n // Handle reasoning content\n if (delta.reasoning_content) {\n if (!reasoningState.hasStarted) {\n yield {\n type: EventType.THINKING_START,\n threadId,\n runId,\n messageId,\n };\n yield {\n type: EventType.THINKING_TEXT_MESSAGE_START,\n threadId,\n runId,\n messageId,\n role: \"assistant\",\n };\n reasoningState.hasStarted = true;\n }\n\n reasoningState.fullContent += delta.reasoning_content;\n yield {\n type: EventType.THINKING_TEXT_MESSAGE_CONTENT,\n threadId,\n runId,\n messageId,\n delta: delta.reasoning_content,\n };\n }\n\n // Handle tool calls\n if (delta.tool_calls) {\n for (const toolCall of delta.tool_calls) {\n const toolCallId = toolCall.id || `tool_${toolCall.index}`;\n\n if (toolCall.function?.name) {\n // Tool call start\n yield {\n type: EventType.TOOL_CALL_START,\n threadId,\n runId,\n toolCallId,\n toolCallName: toolCall.function.name,\n };\n\n state.toolCallsMap.set(toolCallId, {\n name: toolCall.function.name,\n args: toolCall.function.arguments || \"\",\n });\n } else if (toolCall.function?.arguments) {\n // Tool call arguments delta\n const existing = state.toolCallsMap.get(toolCallId);\n if (existing) {\n existing.args += toolCall.function.arguments;\n\n yield {\n type: EventType.TOOL_CALL_ARGS,\n threadId,\n runId,\n toolCallId,\n delta: toolCall.function.arguments,\n };\n }\n }\n }\n }\n }\n\n // Emit TEXT_MESSAGE_END if we had text content\n if (state.hasStarted) {\n yield {\n type: EventType.TEXT_MESSAGE_END,\n threadId,\n runId,\n messageId,\n };\n }\n\n // Emit TOOL_CALL_END for all tool calls\n for (const [toolCallId] of state.toolCallsMap) {\n yield {\n type: EventType.TOOL_CALL_END,\n threadId,\n runId,\n toolCallId,\n };\n }\n}\n","// 对话数据模型\nexport const CHAT_HISTORY_DATA_SOURCE = \"ai_bot_chat_history_5hobd2b\";\n","import tcb from \"@cloudbase/node-sdk\";\nimport { CHAT_HISTORY_DATA_SOURCE } from \"./constant\";\nimport { genRandomStr } from \"./utils\";\n\nfunction genRecordId(): string {\n return \"record-\" + genRandomStr(8);\n}\n\n// Create a new chat history record\nexport async function createChatHistory({\n tcbClient,\n chatHistoryEntity,\n}: {\n tcbClient: tcb.CloudBase;\n chatHistoryEntity: ChatHistoryEntity;\n}): Promise<string | undefined> {\n try {\n const recordId = chatHistoryEntity.recordId || genRecordId();\n const data = {\n record_id: recordId,\n bot_id: chatHistoryEntity.botId,\n role: chatHistoryEntity.role,\n content: chatHistoryEntity.content,\n sender: chatHistoryEntity.sender,\n conversation: chatHistoryEntity.conversation,\n type: chatHistoryEntity.type,\n image: chatHistoryEntity.image,\n trigger_src: chatHistoryEntity.triggerSrc,\n origin_msg: chatHistoryEntity.originMsg,\n reply_to: chatHistoryEntity.replyTo,\n reply: chatHistoryEntity.reply,\n trace_id: chatHistoryEntity.traceId,\n need_async_reply: chatHistoryEntity.needAsyncReply,\n async_reply: chatHistoryEntity.asyncReply,\n createdAt: Date.now(),\n updatedAt: Date.now(),\n };\n\n const db = tcbClient.database();\n const collection = db.collection(CHAT_HISTORY_DATA_SOURCE);\n const result = await collection.add(data);\n\n // console.log(\n // `Create record: chatHistoryEntity:${JSON.stringify(\n // chatHistoryEntity\n // )}, result: ${JSON.stringify(result)}`\n // );\n return recordId;\n } catch (error) {\n console.error(\"Failed to create chat history record, error:\", error);\n return undefined;\n }\n}\n\n// Update chat history by record ID\nexport async function updateChatHistoryByRecordId({\n tcbClient,\n recordId,\n chatHistoryEntity,\n}: {\n tcbClient: tcb.CloudBase;\n recordId: string;\n chatHistoryEntity: ChatHistoryEntity;\n}): Promise<string | undefined> {\n try {\n const db = tcbClient.database();\n const _ = db.command;\n const collection = db.collection(CHAT_HISTORY_DATA_SOURCE);\n\n const result = await collection\n .where({ record_id: _.eq(recordId) })\n .update({\n content: chatHistoryEntity.content,\n image: chatHistoryEntity.image,\n async_reply: chatHistoryEntity.asyncReply,\n recommend_questions: chatHistoryEntity.recommendQuestions,\n status: chatHistoryEntity.status,\n origin_msg: chatHistoryEntity.originMsg,\n updatedAt: Date.now(),\n });\n\n // console.log(\n // `Update record: recordId: ${recordId}, chatHistoryEntity:${JSON.stringify(\n // chatHistoryEntity\n // )}, result: ${JSON.stringify(result)}`\n // );\n return chatHistoryEntity.recordId;\n } catch (error) {\n console.error(\"Failed to update chat history, error:\", error);\n return undefined;\n }\n}\n\n// Query chat history from database\nexport async function describeChatHistory({\n tcbClient,\n botId,\n sort,\n pageSize = 10,\n pageNumber = 1,\n conversation,\n startCreatedAt,\n triggerSrc,\n}: {\n tcbClient: tcb.CloudBase;\n botId: string;\n sort: \"asc\" | \"desc\";\n pageSize?: number;\n pageNumber?: number;\n conversation?: string;\n startCreatedAt?: number;\n triggerSrc?: string;\n}): Promise<[ChatHistoryEntity[], number]> {\n if (!sort || sort.length === 0) {\n sort = \"desc\";\n }\n\n try {\n const db = tcbClient.database();\n const _ = db.command;\n const collection = db.collection(CHAT_HISTORY_DATA_SOURCE);\n\n // Build where conditions\n const whereConditions: Record<string, unknown> = {\n bot_id: _.eq(botId),\n };\n\n // Add optional filters\n if (conversation) {\n whereConditions.conversation = _.eq(conversation);\n }\n\n if (startCreatedAt !== undefined) {\n whereConditions.createdAt = _.gt(startCreatedAt);\n }\n\n if (triggerSrc) {\n whereConditions.trigger_src = _.eq(triggerSrc);\n }\n\n // Calculate skip for pagination\n const skip = (pageNumber - 1) * pageSize;\n\n // Query records\n const result = await collection\n .where(whereConditions)\n .orderBy(\"createdAt\", sort)\n .skip(skip)\n .limit(pageSize)\n .get();\n\n // Get total count\n const countResult = await collection.where(whereConditions).count();\n const total = countResult.total || 0;\n\n const records = result?.data || [];\n\n const entityList: ChatHistoryEntity[] = records.map(\n (item: ChatHistoryData) => transDataToChatEntity(item)\n );\n\n return [entityList, total];\n } catch (error) {\n console.error(\"Failed to query chat history, error:\", error);\n return [[], 0];\n }\n}\n\n// Transform data to ChatHistoryEntity structure\nexport function transDataToChatEntity(\n item: ChatHistoryData\n): ChatHistoryEntity {\n if (!item) {\n return new ChatHistoryEntity();\n }\n const chatEntity: ChatHistoryEntity = new ChatHistoryEntity();\n chatEntity.botId = item.bot_id;\n chatEntity.recordId = item.record_id;\n chatEntity.role = item.role;\n chatEntity.status = item.status;\n chatEntity.content = item.content;\n chatEntity.sender = item.sender;\n chatEntity.conversation = item.conversation;\n chatEntity.type = item.type;\n chatEntity.triggerSrc = item.trigger_src;\n chatEntity.originMsg = item.origin_msg;\n chatEntity.replyTo = item.reply_to;\n chatEntity.reply = item.reply;\n chatEntity.traceId = item.trace_id;\n chatEntity.needAsyncReply = item.need_async_reply;\n chatEntity.asyncReply = item.async_reply;\n chatEntity.createdAt = item.createdAt;\n chatEntity.updatedAt = item.updatedAt;\n return chatEntity;\n}\n\n// Query history records for LLM, get the most recent 10 conversation pairs (20 records)\nexport async function queryForLLM({\n tcbClient,\n botId,\n pageSize = 10,\n startCreatedAt,\n triggerSrc,\n}: {\n tcbClient: tcb.CloudBase;\n botId: string;\n pageSize?: number;\n startCreatedAt?: number;\n triggerSrc?: string;\n}): Promise<{ role: string; content: string }[]> {\n if (startCreatedAt === undefined) {\n startCreatedAt = Date.now() - 24 * 60 * 60 * 1000;\n }\n const recordEntityList: ChatHistoryEntity[] = [];\n\n const [recordList] = await describeChatHistory({\n tcbClient,\n botId,\n sort: \"desc\",\n pageSize,\n startCreatedAt,\n triggerSrc,\n });\n recordEntityList.push(...recordList.reverse());\n\n const entityMap = new Map<string, ChatHistoryEntity>();\n recordEntityList\n .filter((item) => {\n if (item.needAsyncReply === true) {\n return !!item.asyncReply;\n } else {\n return !!item.content;\n }\n })\n .forEach((item) => {\n entityMap.set(item.recordId, item);\n });\n\n const result: { role: string; content: string }[] = [];\n /*\n 1. Strongly depends on database history data, model history data has role order requirements\n 2. Need to ensure that no matter what bug occurs, always get a complete and usable user + assistant pair, otherwise the request will fail\n */\n recordEntityList.forEach((item) => {\n const { role, content, reply } = item;\n // When calling LLM, empty content will cause failure, so filter out conversations with empty content\n if (role === \"user\" && content?.length !== 0) {\n if (entityMap.has(reply)) {\n result.push({ role, content });\n result.push({\n role: entityMap.get(reply)!.role,\n content: entityMap.get(reply)!.content,\n });\n }\n }\n });\n if (result.length % 2 === 1) {\n result.splice(-1, 1);\n }\n return result;\n}\n\nexport interface ChatHistoryData {\n bot_id: string;\n record_id: string;\n role: string;\n status: string;\n content: string;\n sender: string;\n conversation: string;\n type: string;\n trigger_src: string;\n origin_msg: string;\n reply_to: string;\n reply: string;\n trace_id: string;\n need_async_reply: boolean;\n async_reply: string;\n createdAt: number;\n updatedAt: number;\n}\n\nexport class ChatHistoryEntity {\n id: number;\n botId: string;\n // 对话唯一id\n recordId: string;\n role: string;\n content: string;\n recommendQuestions: string[];\n sender: string;\n conversation: string;\n type: string;\n /**\n * 消息状态,pending donw error cancel\n */\n status: string;\n image: string;\n triggerSrc: string;\n originMsg: string;\n replyTo: string;\n reply: string;\n traceId: string;\n needAsyncReply: boolean;\n asyncReply: string;\n createTime: string;\n updateTime: string;\n createdAt: number;\n updatedAt: number;\n event: string;\n}\n"],"mappings":"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","names":["import_client","OpenAI","tcb","managedTcb"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/agent.ts","../src/utils.ts","../src/stream.ts","../src/constant.ts","../src/chat_history.ts"],"sourcesContent":["export * from \"./agent\";\n\nexport * from \"./types\";\n\nexport * from \"./stream\";\n\nexport * from \"./chat_history\";\n","import {\n RunAgentInput,\n Message,\n AbstractAgent,\n AgentConfig,\n BaseEvent,\n EventType,\n RunStartedEvent,\n RunFinishedEvent,\n RunErrorEvent,\n TextMessageContentEvent,\n ToolCall,\n} from \"@ag-ui/client\";\nimport tcb from \"@cloudbase/node-sdk\";\nimport managedTcb from \"@cloudbase/manager-node\";\nimport OpenAI from \"openai\";\nimport { randomUUID } from \"crypto\";\nimport { camelToSnakeKeys } from \"./utils\";\nimport { processYuanqiStream } from \"./stream\";\nimport { Observable, Subscriber } from \"rxjs\";\nimport {\n createChatHistory,\n queryForLLM,\n ChatHistoryEntity,\n} from \"./chat_history\";\nimport { CHAT_HISTORY_DATA_SOURCE } from \"./constant\";\nimport { YuanqiConfig, ChatMessage, YuanqiChatRequest } from \"./types\";\n\nexport class YuanqiAgentError extends Error {\n code?: string;\n constructor(message: string, code?: string) {\n super(message);\n this.name = \"YuanqiAgentError\";\n if (code) this.code = code;\n }\n}\n\nexport class YuanqiAgent extends AbstractAgent {\n protected yuanqiConfig: YuanqiConfig;\n private finalAppId: string;\n private finalCloudCredential: {\n secretId?: string;\n secretKey?: string;\n token?: string;\n } = {};\n private model: OpenAI;\n constructor(config: AgentConfig & { yuanqiConfig: YuanqiConfig }) {\n super(config);\n this.yuanqiConfig = config.yuanqiConfig;\n this.model = new OpenAI({\n apiKey: \"\",\n baseURL:\n this.yuanqiConfig.request?.baseUrl ||\n \"https://yuanqi.tencent.com/openapi/v1/agent\",\n });\n this.finalAppId =\n this.yuanqiConfig.appId ||\n this.yuanqiConfig.request?.body?.assistantId ||\n process.env.YUANQI_APP_ID ||\n \"\";\n this.finalCloudCredential = {\n secretId:\n this.yuanqiConfig.credential?.secretId ||\n process.env.TENCENTCLOUD_SECRETID,\n secretKey:\n this.yuanqiConfig.credential?.secretKey ||\n process.env.TENCENTCLOUD_SECRETKEY,\n token:\n this.yuanqiConfig.credential?.token ||\n process.env.TENCENTCLOUD_SESSIONTOKEN,\n };\n }\n\n generateRequestBody({\n messages,\n input,\n }: {\n messages: ChatMessage[];\n input: RunAgentInput;\n }): YuanqiChatRequest {\n const { state, forwardedProps } = input;\n const requestBody: YuanqiChatRequest = {\n stream: true,\n ...(this.yuanqiConfig.request?.body || {}),\n ...(forwardedProps || {}),\n\n assistantId: this.finalAppId,\n userId:\n state?.__request_context__?.id ||\n forwardedProps?.userId ||\n randomUUID(),\n messages,\n };\n return requestBody;\n }\n\n run(input: RunAgentInput): Observable<BaseEvent> {\n return new Observable<BaseEvent>((subscriber) => {\n this._run(subscriber, input);\n });\n }\n\n private async _run(\n subscriber: Subscriber<BaseEvent>,\n input: RunAgentInput\n ): Promise<void> {\n try {\n const { messages, runId } = input;\n\n const openai = this.model as OpenAI;\n const threadId = input.threadId || randomUUID();\n\n subscriber.next({\n type: EventType.RUN_STARTED,\n threadId,\n runId,\n } as RunStartedEvent);\n\n if (!this.finalAppId) {\n throw new YuanqiAgentError(\n \"YUANQI_APP_ID is required, check your env variables or config passed with the adapter\",\n \"MISSING_YUANQI_APP_ID\"\n );\n }\n if (!this.yuanqiConfig.appKey && !process.env.YUANQI_APP_KEY) {\n throw new YuanqiAgentError(\n \"YUANQI_APP_KEY is required, check your env variables or config passed with the adapter\",\n \"MISSING_YUANQI_APP_KEY\"\n );\n }\n\n // Warn user if messages are being trimmed (only using latest user message)\n const trimmedCount = messages.length - 1;\n if (trimmedCount > 0) {\n subscriber.next({\n type: EventType.RAW,\n rawEvent: {\n message: `Yuanqi handles message history itself, so that a total of ${trimmedCount} messages before the last user message will be trimmed.`,\n type: \"warn\",\n },\n });\n }\n\n // Get the latest user message for saving to history\n const latestUserMessage = messages.filter((m) => m.role === \"user\").pop();\n if (!latestUserMessage) {\n throw new YuanqiAgentError(\n \"No user message found, please send a message first.\",\n \"MESSAGE_FORMAT_ERROR\"\n );\n }\n\n const allMessages = await this.getChatHistory(\n subscriber,\n latestUserMessage\n );\n\n const body = this.generateRequestBody({\n messages: allMessages,\n input,\n });\n\n const stream = await openai.chat.completions.create(\n {\n stream: true,\n messages: [],\n model: \"\",\n },\n {\n body: camelToSnakeKeys(body),\n headers: {\n ...this.yuanqiConfig.request?.headers,\n Authorization: `Bearer ${\n this.yuanqiConfig.appKey || process.env.YUANQI_APP_KEY\n }`,\n },\n }\n );\n\n // Process stream and emit AGUI events, collect full response\n const userRecordId = `record-${randomUUID().slice(0, 8)}`;\n const assistantRecordId = `record-${randomUUID().slice(0, 8)}`;\n const context = { threadId, runId, messageId: userRecordId };\n\n let fullAssistantContent = \"\";\n\n for await (const event of processYuanqiStream(stream, context)) {\n subscriber.next(event);\n // Collect assistant content from TEXT_MESSAGE_CONTENT events\n if (\n event.type === EventType.TEXT_MESSAGE_CONTENT &&\n (event as TextMessageContentEvent).delta\n ) {\n fullAssistantContent += (event as TextMessageContentEvent).delta;\n }\n }\n\n const userContent =\n typeof latestUserMessage?.content === \"string\"\n ? latestUserMessage.content\n : latestUserMessage?.content\n ?.filter((c) => c.type === \"text\")\n .map((c) => c.text)\n .join(\"\") || \"\";\n\n await this.saveChatHistory(\n subscriber,\n input,\n userRecordId,\n assistantRecordId,\n userContent,\n fullAssistantContent\n );\n\n subscriber.next({\n type: EventType.RUN_FINISHED,\n threadId,\n runId,\n } as RunFinishedEvent);\n } catch (e: unknown) {\n console.error(\"[ERROR] Uncaught error: \", JSON.stringify(e));\n let code = \"UNKNOWN_ERROR\";\n let message = JSON.stringify(e);\n if (e instanceof YuanqiAgentError) {\n code = e.code || \"AGENT_ERROR\";\n message = e.message;\n } else if (e instanceof Error) {\n code = e.name || \"ERROR\";\n message = e.message;\n }\n subscriber.next({\n type: EventType.RUN_ERROR,\n code,\n message: `Sorry, an error occurred while running the agent: Error code ${code}, ${message}`,\n } as RunErrorEvent);\n } finally {\n subscriber.complete();\n }\n }\n\n // Can be override by subclasses\n protected async getChatHistory(\n subscriber: Subscriber<BaseEvent>,\n latestUserMessage: Message\n ) {\n const botId = `bot-yuanqi-${this.finalAppId}`;\n\n const tcbClient = this.getTcbClient();\n\n const isDBReady = await this.checkIsDatabaseReady();\n if (!isDBReady) {\n subscriber.next({\n type: EventType.RAW,\n rawEvent: {\n message: `Chat history database is not ready, skip history loading.`,\n type: \"warn\",\n },\n });\n return convertMessagesToOpenAI([latestUserMessage]);\n }\n\n // Fetch chat history from database using queryForLLM\n let historyMessages: ChatMessage[] = [];\n\n const historyCount = this.yuanqiConfig.historyCount ?? 10;\n const historyRecords = await queryForLLM({\n tcbClient,\n botId,\n pageSize: historyCount,\n });\n\n // Convert queryForLLM result to ChatMessage format\n historyMessages = historyRecords.map((record) => ({\n role: record.role as \"user\" | \"assistant\",\n content: [{ type: \"text\" as const, text: record.content }],\n }));\n\n // Combine history messages with current messages\n const allMessages = historyMessages.concat(\n convertMessagesToOpenAI([latestUserMessage])\n );\n return allMessages;\n }\n\n // Can be override by subclasses\n protected async saveChatHistory(\n subscriber: Subscriber<BaseEvent>,\n input: RunAgentInput,\n userRecordId: string,\n assistantRecordId: string,\n userContent: string,\n assistantContent: string\n ) {\n const botId = `bot-yuanqi-${this.finalAppId}`;\n\n const { threadId, runId } = input;\n\n const tcbClient = this.getTcbClient();\n\n const isDBReady = await this.checkIsDatabaseReady();\n if (!isDBReady) {\n subscriber.next({\n type: EventType.RAW,\n rawEvent: {\n message: `Chat history database is not ready, skip history saving.`,\n type: \"warn\",\n },\n });\n return;\n }\n\n // Save message pair to history\n const userEntity = new ChatHistoryEntity();\n userEntity.recordId = userRecordId;\n userEntity.botId = botId;\n userEntity.role = \"user\";\n userEntity.content = userContent;\n userEntity.conversation = threadId;\n userEntity.reply = assistantRecordId;\n userEntity.triggerSrc = \"\";\n userEntity.traceId = randomUUID();\n\n await createChatHistory({ tcbClient, chatHistoryEntity: userEntity });\n\n const assistantEntity = new ChatHistoryEntity();\n assistantEntity.recordId = assistantRecordId;\n assistantEntity.botId = botId;\n assistantEntity.role = \"assistant\";\n assistantEntity.content = assistantContent;\n assistantEntity.conversation = threadId;\n assistantEntity.replyTo = userRecordId;\n assistantEntity.triggerSrc = \"\";\n assistantEntity.traceId = runId;\n assistantEntity.status = \"done\";\n\n await createChatHistory({\n tcbClient,\n chatHistoryEntity: assistantEntity,\n });\n }\n\n private getTcbClient() {\n const envId = this.yuanqiConfig.envId || getCloudbaseEnvId();\n\n const tcbClient = tcb.init({\n env: envId,\n secretId: this.finalCloudCredential.secretId,\n secretKey: this.finalCloudCredential.secretKey,\n sessionToken: this.finalCloudCredential.token,\n });\n return tcbClient;\n }\n\n private async checkIsDatabaseReady() {\n try {\n const envId = this.yuanqiConfig.envId || getCloudbaseEnvId();\n if (!envId) {\n throw new YuanqiAgentError(\n \"When saving chat history to CloudBase, CLOUDBASE_ENV_ID is required, check your env variables or config passed with the adapter\",\n \"MISSING_CLOUDBASE_ENV_ID\"\n );\n }\n if (!this.finalCloudCredential.token) {\n if (!this.finalCloudCredential.secretId) {\n throw new YuanqiAgentError(\n \"When saving chat history to CloudBase, TENCENTCLOUD_SECRETID is required, check your env variables or config passed with the adapter\",\n \"MISSING_SECRET_ID\"\n );\n }\n if (!this.finalCloudCredential.secretKey) {\n throw new YuanqiAgentError(\n \"When saving chat history to CloudBase, TENCENTCLOUD_SECRETKEY is required, check your env variables or config passed with the adapter\",\n \"MISSING_SECRET_KEY\"\n );\n }\n }\n const managedTcbClient = managedTcb.init({\n envId,\n secretId: this.finalCloudCredential.secretId,\n secretKey: this.finalCloudCredential.secretKey,\n token: this.finalCloudCredential.token,\n });\n\n const checkDBRes = await managedTcbClient.database.checkCollectionExists(\n CHAT_HISTORY_DATA_SOURCE\n );\n if (checkDBRes && checkDBRes.Exists) {\n return true;\n } else if (checkDBRes && !checkDBRes.Exists) {\n await managedTcbClient.database.createCollection(\n CHAT_HISTORY_DATA_SOURCE\n );\n return true;\n } else {\n throw new Error(\"Check database exists failed\");\n }\n } catch (dbError) {\n console.error(\n \"[ERROR] Failed to check/create chat history collection:\",\n JSON.stringify(dbError)\n );\n return false;\n }\n }\n}\n\nfunction getCloudbaseEnvId() {\n if (process.env.CBR_ENV_ID) {\n return process.env.CBR_ENV_ID;\n } else if (process.env.SCF_NAMESPACE) {\n return process.env.SCF_NAMESPACE;\n } else {\n return process.env.CLOUDBASE_ENV_ID || \"\";\n }\n}\n\n/**\n * Convert AGUI messages to OpenAI chat completion format\n */\nexport function convertMessagesToOpenAI(\n messages: Message[],\n systemPrompt?: string\n): ChatMessage[] {\n const openaiMessages: ChatMessage[] = [];\n\n // Add system prompt if provided\n if (systemPrompt) {\n openaiMessages.push({\n role: \"system\",\n content: systemPrompt,\n });\n }\n\n // Convert messages\n for (const msg of messages) {\n if (msg.role === \"user\") {\n openaiMessages.push({\n role: \"user\",\n content:\n typeof msg.content === \"string\"\n ? [{ type: \"text\", text: msg.content }]\n : msg.content.map((item) => {\n if (item.type === \"text\") {\n return { type: \"text\", text: item.text };\n } else {\n return {\n type: \"image_url\",\n image_url: { url: item.url || \"\" },\n };\n }\n }),\n });\n } else if (msg.role === \"assistant\") {\n openaiMessages.push({\n role: \"assistant\",\n content: msg.content ? [{ type: \"text\", text: msg.content }] : [],\n tool_calls: msg.toolCalls?.map((tc: ToolCall) => ({\n id: tc.id,\n type: \"function\" as const,\n function: {\n name: tc.function.name,\n arguments: tc.function.arguments,\n },\n })),\n });\n } else if (msg.role === \"tool\") {\n openaiMessages.push({\n role: \"tool\",\n tool_call_id: msg.toolCallId,\n content: msg.content ? [{ type: \"text\", text: msg.content }] : [],\n });\n }\n }\n\n return openaiMessages;\n}\n","/**\n * 将小驼峰字符串转换为下划线格式\n * 例如: \"userName\" -> \"user_name\"\n */\nfunction camelToSnake(str: string): string {\n return str.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`);\n}\n\n/**\n * 递归地将对象的所有小驼峰属性名转换为下划线格式\n */\nexport function camelToSnakeKeys<T>(obj: T): T {\n if (obj === null || obj === undefined) {\n return obj;\n }\n\n if (Array.isArray(obj)) {\n return obj.map((item) => camelToSnakeKeys(item)) as T;\n }\n\n if (typeof obj === \"object\") {\n const result: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(obj)) {\n const snakeKey = camelToSnake(key);\n result[snakeKey] = camelToSnakeKeys(value);\n }\n return result as T;\n }\n\n return obj;\n}\n\nexport function genRandomStr(length: number): string {\n const chars = \"abcdefghijklmnopqrstuvwxyz0123456789\";\n let result = \"\";\n for (let i = 0; i < length; i++) {\n result += chars.charAt(Math.floor(Math.random() * chars.length));\n }\n return result;\n}\n","import OpenAI from \"openai\";\nimport { EventType } from \"@ag-ui/client\";\n\nexport interface StreamContext {\n threadId: string;\n runId: string;\n messageId: string;\n}\n\nexport interface StreamState {\n hasStarted: boolean;\n fullContent: string;\n toolCallsMap: Map<string, { name: string; args: string }>;\n}\n\nexport type Delta =\n OpenAI.Chat.Completions.ChatCompletionChunk[\"choices\"][number][\"delta\"] & {\n reasoning_content?: string;\n };\n\nexport async function* processYuanqiStream(\n stream: AsyncIterable<OpenAI.Chat.Completions.ChatCompletionChunk>,\n context: StreamContext\n) {\n const { threadId, runId, messageId } = context;\n const state: StreamState = {\n hasStarted: false,\n fullContent: \"\",\n toolCallsMap: new Map(),\n };\n const reasoningState: StreamState = {\n hasStarted: false,\n fullContent: \"\",\n toolCallsMap: new Map(),\n };\n\n for await (const chunk of stream) {\n const delta = chunk.choices[0]?.delta as Delta;\n if (!delta) continue;\n\n if (delta.role === \"tool\") {\n const toolCallId = (delta as any).tool_call_id;\n if (toolCallId) {\n if (state.toolCallsMap.has(toolCallId)) {\n yield {\n type: EventType.TOOL_CALL_END,\n threadId,\n runId,\n toolCallId,\n };\n state.toolCallsMap.delete(toolCallId);\n }\n yield {\n type: EventType.TOOL_CALL_RESULT,\n threadId,\n runId,\n toolCallId,\n content: delta.content || \"\",\n };\n }\n continue;\n }\n\n // Handle text content\n if (delta.content) {\n // End reasoning message if it was started\n if (reasoningState.hasStarted) {\n reasoningState.hasStarted = false;\n yield {\n type: EventType.THINKING_TEXT_MESSAGE_END,\n threadId,\n runId,\n messageId,\n };\n yield {\n type: EventType.THINKING_END,\n threadId,\n runId,\n messageId,\n };\n }\n\n if (!state.hasStarted) {\n yield {\n type: EventType.TEXT_MESSAGE_START,\n threadId,\n runId,\n messageId,\n role: \"assistant\",\n };\n state.hasStarted = true;\n }\n\n state.fullContent += delta.content;\n yield {\n type: EventType.TEXT_MESSAGE_CONTENT,\n threadId,\n runId,\n messageId,\n delta: delta.content,\n };\n }\n\n // Handle reasoning content\n if (delta.reasoning_content) {\n if (!reasoningState.hasStarted) {\n yield {\n type: EventType.THINKING_START,\n threadId,\n runId,\n messageId,\n };\n yield {\n type: EventType.THINKING_TEXT_MESSAGE_START,\n threadId,\n runId,\n messageId,\n role: \"assistant\",\n };\n reasoningState.hasStarted = true;\n }\n\n reasoningState.fullContent += delta.reasoning_content;\n yield {\n type: EventType.THINKING_TEXT_MESSAGE_CONTENT,\n threadId,\n runId,\n messageId,\n delta: delta.reasoning_content,\n };\n }\n\n // Handle tool calls\n if (delta.tool_calls) {\n for (const toolCall of delta.tool_calls) {\n const toolCallId = toolCall.id || `tool_${toolCall.index}`;\n\n if (toolCall.function?.name) {\n // Tool call start\n yield {\n type: EventType.TOOL_CALL_START,\n threadId,\n runId,\n toolCallId,\n toolCallName: toolCall.function.name,\n };\n\n // If first chunk contains arguments, emit TOOL_CALL_ARGS event\n if (toolCall.function.arguments) {\n yield {\n type: EventType.TOOL_CALL_ARGS,\n threadId,\n runId,\n toolCallId,\n delta: toolCall.function.arguments,\n };\n }\n\n state.toolCallsMap.set(toolCallId, {\n name: toolCall.function.name,\n args: toolCall.function.arguments || \"\",\n });\n } else if (toolCall.function?.arguments) {\n // Tool call arguments delta\n const existing = state.toolCallsMap.get(toolCallId);\n if (existing) {\n existing.args += toolCall.function.arguments;\n\n yield {\n type: EventType.TOOL_CALL_ARGS,\n threadId,\n runId,\n toolCallId,\n delta: toolCall.function.arguments,\n };\n }\n }\n }\n }\n }\n\n // Emit TEXT_MESSAGE_END if we had text content\n if (state.hasStarted) {\n yield {\n type: EventType.TEXT_MESSAGE_END,\n threadId,\n runId,\n messageId,\n };\n }\n\n if (reasoningState.hasStarted) {\n yield {\n type: EventType.THINKING_TEXT_MESSAGE_END,\n threadId,\n runId,\n messageId,\n };\n yield {\n type: EventType.THINKING_END,\n threadId,\n runId,\n messageId,\n };\n }\n\n // Emit TOOL_CALL_END for all tool calls\n for (const [toolCallId] of state.toolCallsMap) {\n yield {\n type: EventType.TOOL_CALL_END,\n threadId,\n runId,\n toolCallId,\n };\n }\n}\n","// 对话数据模型\nexport const CHAT_HISTORY_DATA_SOURCE = \"ai_bot_chat_history_5hobd2b\";\n","import tcb from \"@cloudbase/node-sdk\";\nimport { CHAT_HISTORY_DATA_SOURCE } from \"./constant\";\nimport { genRandomStr } from \"./utils\";\n\nfunction genRecordId(): string {\n return \"record-\" + genRandomStr(8);\n}\n\n// Create a new chat history record\nexport async function createChatHistory({\n tcbClient,\n chatHistoryEntity,\n}: {\n tcbClient: tcb.CloudBase;\n chatHistoryEntity: ChatHistoryEntity;\n}): Promise<string | undefined> {\n try {\n const recordId = chatHistoryEntity.recordId || genRecordId();\n const data = {\n record_id: recordId,\n bot_id: chatHistoryEntity.botId,\n role: chatHistoryEntity.role,\n content: chatHistoryEntity.content,\n sender: chatHistoryEntity.sender,\n conversation: chatHistoryEntity.conversation,\n type: chatHistoryEntity.type,\n image: chatHistoryEntity.image,\n trigger_src: chatHistoryEntity.triggerSrc,\n origin_msg: chatHistoryEntity.originMsg,\n reply_to: chatHistoryEntity.replyTo,\n reply: chatHistoryEntity.reply,\n trace_id: chatHistoryEntity.traceId,\n need_async_reply: chatHistoryEntity.needAsyncReply,\n async_reply: chatHistoryEntity.asyncReply,\n createdAt: Date.now(),\n updatedAt: Date.now(),\n };\n\n const db = tcbClient.database();\n const collection = db.collection(CHAT_HISTORY_DATA_SOURCE);\n const result = await collection.add(data);\n\n // console.log(\n // `Create record: chatHistoryEntity:${JSON.stringify(\n // chatHistoryEntity\n // )}, result: ${JSON.stringify(result)}`\n // );\n return recordId;\n } catch (error) {\n console.error(\"Failed to create chat history record, error:\", error);\n return undefined;\n }\n}\n\n// Update chat history by record ID\nexport async function updateChatHistoryByRecordId({\n tcbClient,\n recordId,\n chatHistoryEntity,\n}: {\n tcbClient: tcb.CloudBase;\n recordId: string;\n chatHistoryEntity: ChatHistoryEntity;\n}): Promise<string | undefined> {\n try {\n const db = tcbClient.database();\n const _ = db.command;\n const collection = db.collection(CHAT_HISTORY_DATA_SOURCE);\n\n const result = await collection\n .where({ record_id: _.eq(recordId) })\n .update({\n content: chatHistoryEntity.content,\n image: chatHistoryEntity.image,\n async_reply: chatHistoryEntity.asyncReply,\n recommend_questions: chatHistoryEntity.recommendQuestions,\n status: chatHistoryEntity.status,\n origin_msg: chatHistoryEntity.originMsg,\n updatedAt: Date.now(),\n });\n\n // console.log(\n // `Update record: recordId: ${recordId}, chatHistoryEntity:${JSON.stringify(\n // chatHistoryEntity\n // )}, result: ${JSON.stringify(result)}`\n // );\n return chatHistoryEntity.recordId;\n } catch (error) {\n console.error(\"Failed to update chat history, error:\", error);\n return undefined;\n }\n}\n\n// Query chat history from database\nexport async function describeChatHistory({\n tcbClient,\n botId,\n sort,\n pageSize = 10,\n pageNumber = 1,\n conversation,\n startCreatedAt,\n triggerSrc,\n}: {\n tcbClient: tcb.CloudBase;\n botId: string;\n sort: \"asc\" | \"desc\";\n pageSize?: number;\n pageNumber?: number;\n conversation?: string;\n startCreatedAt?: number;\n triggerSrc?: string;\n}): Promise<[ChatHistoryEntity[], number]> {\n if (!sort || sort.length === 0) {\n sort = \"desc\";\n }\n\n try {\n const db = tcbClient.database();\n const _ = db.command;\n const collection = db.collection(CHAT_HISTORY_DATA_SOURCE);\n\n // Build where conditions\n const whereConditions: Record<string, unknown> = {\n bot_id: _.eq(botId),\n };\n\n // Add optional filters\n if (conversation) {\n whereConditions.conversation = _.eq(conversation);\n }\n\n if (startCreatedAt !== undefined) {\n whereConditions.createdAt = _.gt(startCreatedAt);\n }\n\n if (triggerSrc) {\n whereConditions.trigger_src = _.eq(triggerSrc);\n }\n\n // Calculate skip for pagination\n const skip = (pageNumber - 1) * pageSize;\n\n // Query records\n const result = await collection\n .where(whereConditions)\n .orderBy(\"createdAt\", sort)\n .skip(skip)\n .limit(pageSize)\n .get();\n\n // Get total count\n const countResult = await collection.where(whereConditions).count();\n const total = countResult.total || 0;\n\n const records = result?.data || [];\n\n const entityList: ChatHistoryEntity[] = records.map(\n (item: ChatHistoryData) => transDataToChatEntity(item)\n );\n\n return [entityList, total];\n } catch (error) {\n console.error(\"Failed to query chat history, error:\", error);\n return [[], 0];\n }\n}\n\n// Transform data to ChatHistoryEntity structure\nexport function transDataToChatEntity(\n item: ChatHistoryData\n): ChatHistoryEntity {\n if (!item) {\n return new ChatHistoryEntity();\n }\n const chatEntity: ChatHistoryEntity = new ChatHistoryEntity();\n chatEntity.botId = item.bot_id;\n chatEntity.recordId = item.record_id;\n chatEntity.role = item.role;\n chatEntity.status = item.status;\n chatEntity.content = item.content;\n chatEntity.sender = item.sender;\n chatEntity.conversation = item.conversation;\n chatEntity.type = item.type;\n chatEntity.triggerSrc = item.trigger_src;\n chatEntity.originMsg = item.origin_msg;\n chatEntity.replyTo = item.reply_to;\n chatEntity.reply = item.reply;\n chatEntity.traceId = item.trace_id;\n chatEntity.needAsyncReply = item.need_async_reply;\n chatEntity.asyncReply = item.async_reply;\n chatEntity.createdAt = item.createdAt;\n chatEntity.updatedAt = item.updatedAt;\n return chatEntity;\n}\n\n// Query history records for LLM, get the most recent 10 conversation pairs (20 records)\nexport async function queryForLLM({\n tcbClient,\n botId,\n pageSize = 10,\n startCreatedAt,\n triggerSrc,\n}: {\n tcbClient: tcb.CloudBase;\n botId: string;\n pageSize?: number;\n startCreatedAt?: number;\n triggerSrc?: string;\n}): Promise<{ role: string; content: string }[]> {\n if (startCreatedAt === undefined) {\n startCreatedAt = Date.now() - 24 * 60 * 60 * 1000;\n }\n const recordEntityList: ChatHistoryEntity[] = [];\n\n const [recordList] = await describeChatHistory({\n tcbClient,\n botId,\n sort: \"desc\",\n pageSize,\n startCreatedAt,\n triggerSrc,\n });\n recordEntityList.push(...recordList.reverse());\n\n const entityMap = new Map<string, ChatHistoryEntity>();\n recordEntityList\n .filter((item) => {\n if (item.needAsyncReply === true) {\n return !!item.asyncReply;\n } else {\n return !!item.content;\n }\n })\n .forEach((item) => {\n entityMap.set(item.recordId, item);\n });\n\n const result: { role: string; content: string }[] = [];\n /*\n 1. Strongly depends on database history data, model history data has role order requirements\n 2. Need to ensure that no matter what bug occurs, always get a complete and usable user + assistant pair, otherwise the request will fail\n */\n recordEntityList.forEach((item) => {\n const { role, content, reply } = item;\n // When calling LLM, empty content will cause failure, so filter out conversations with empty content\n if (role === \"user\" && content?.length !== 0) {\n if (entityMap.has(reply)) {\n result.push({ role, content });\n result.push({\n role: entityMap.get(reply)!.role,\n content: entityMap.get(reply)!.content,\n });\n }\n }\n });\n if (result.length % 2 === 1) {\n result.splice(-1, 1);\n }\n return result;\n}\n\nexport interface ChatHistoryData {\n bot_id: string;\n record_id: string;\n role: string;\n status: string;\n content: string;\n sender: string;\n conversation: string;\n type: string;\n trigger_src: string;\n origin_msg: string;\n reply_to: string;\n reply: string;\n trace_id: string;\n need_async_reply: boolean;\n async_reply: string;\n createdAt: number;\n updatedAt: number;\n}\n\nexport class ChatHistoryEntity {\n id: number;\n botId: string;\n // 对话唯一id\n recordId: string;\n role: string;\n content: string;\n recommendQuestions: string[];\n sender: string;\n conversation: string;\n type: string;\n /**\n * 消息状态,pending done error cancel\n */\n status: string;\n image: string;\n triggerSrc: string;\n originMsg: string;\n replyTo: string;\n reply: string;\n traceId: string;\n needAsyncReply: boolean;\n asyncReply: string;\n createTime: string;\n updateTime: string;\n createdAt: number;\n updatedAt: number;\n event: string;\n}\n"],"mappings":"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","names":["import_client","OpenAI","tcb","managedTcb"]}
package/dist/index.mjs CHANGED
@@ -55,6 +55,28 @@ async function* processYuanqiStream(stream, context) {
55
55
  for await (const chunk of stream) {
56
56
  const delta = chunk.choices[0]?.delta;
57
57
  if (!delta) continue;
58
+ if (delta.role === "tool") {
59
+ const toolCallId = delta.tool_call_id;
60
+ if (toolCallId) {
61
+ if (state.toolCallsMap.has(toolCallId)) {
62
+ yield {
63
+ type: EventType.TOOL_CALL_END,
64
+ threadId,
65
+ runId,
66
+ toolCallId
67
+ };
68
+ state.toolCallsMap.delete(toolCallId);
69
+ }
70
+ yield {
71
+ type: EventType.TOOL_CALL_RESULT,
72
+ threadId,
73
+ runId,
74
+ toolCallId,
75
+ content: delta.content || ""
76
+ };
77
+ }
78
+ continue;
79
+ }
58
80
  if (delta.content) {
59
81
  if (reasoningState.hasStarted) {
60
82
  reasoningState.hasStarted = false;
@@ -127,6 +149,15 @@ async function* processYuanqiStream(stream, context) {
127
149
  toolCallId,
128
150
  toolCallName: toolCall.function.name
129
151
  };
152
+ if (toolCall.function.arguments) {
153
+ yield {
154
+ type: EventType.TOOL_CALL_ARGS,
155
+ threadId,
156
+ runId,
157
+ toolCallId,
158
+ delta: toolCall.function.arguments
159
+ };
160
+ }
130
161
  state.toolCallsMap.set(toolCallId, {
131
162
  name: toolCall.function.name,
132
163
  args: toolCall.function.arguments || ""
@@ -155,6 +186,20 @@ async function* processYuanqiStream(stream, context) {
155
186
  messageId
156
187
  };
157
188
  }
189
+ if (reasoningState.hasStarted) {
190
+ yield {
191
+ type: EventType.THINKING_TEXT_MESSAGE_END,
192
+ threadId,
193
+ runId,
194
+ messageId
195
+ };
196
+ yield {
197
+ type: EventType.THINKING_END,
198
+ threadId,
199
+ runId,
200
+ messageId
201
+ };
202
+ }
158
203
  for (const [toolCallId] of state.toolCallsMap) {
159
204
  yield {
160
205
  type: EventType.TOOL_CALL_END,
@@ -397,9 +442,9 @@ var YuanqiAgent = class extends AbstractAgent {
397
442
  }
398
443
  async _run(subscriber, input) {
399
444
  try {
400
- const { messages, runId, threadId: _threadId } = input;
445
+ const { messages, runId } = input;
401
446
  const openai = this.model;
402
- const threadId = _threadId || randomUUID();
447
+ const threadId = input.threadId || randomUUID();
403
448
  subscriber.next({
404
449
  type: EventType2.RUN_STARTED,
405
450
  threadId,
@@ -481,7 +526,7 @@ var YuanqiAgent = class extends AbstractAgent {
481
526
  runId
482
527
  });
483
528
  } catch (e) {
484
- console.error(JSON.stringify(e));
529
+ console.error("[ERROR] Uncaught error: ", JSON.stringify(e));
485
530
  let code = "UNKNOWN_ERROR";
486
531
  let message = JSON.stringify(e);
487
532
  if (e instanceof YuanqiAgentError) {
@@ -502,9 +547,9 @@ var YuanqiAgent = class extends AbstractAgent {
502
547
  }
503
548
  // Can be override by subclasses
504
549
  async getChatHistory(subscriber, latestUserMessage) {
505
- const envId = this.yuanqiConfig.envId || getCloudbaseEnvId();
506
550
  const botId = `bot-yuanqi-${this.finalAppId}`;
507
- const isDBReady = await this.checkIsDatabaseReady(envId);
551
+ const tcbClient = this.getTcbClient();
552
+ const isDBReady = await this.checkIsDatabaseReady();
508
553
  if (!isDBReady) {
509
554
  subscriber.next({
510
555
  type: EventType2.RAW,
@@ -515,12 +560,6 @@ var YuanqiAgent = class extends AbstractAgent {
515
560
  });
516
561
  return convertMessagesToOpenAI([latestUserMessage]);
517
562
  }
518
- const tcbClient = tcb.init({
519
- env: envId,
520
- secretId: this.finalCloudCredential.secretId,
521
- secretKey: this.finalCloudCredential.secretKey,
522
- sessionToken: this.finalCloudCredential.token
523
- });
524
563
  let historyMessages = [];
525
564
  const historyCount = this.yuanqiConfig.historyCount ?? 10;
526
565
  const historyRecords = await queryForLLM({
@@ -539,10 +578,10 @@ var YuanqiAgent = class extends AbstractAgent {
539
578
  }
540
579
  // Can be override by subclasses
541
580
  async saveChatHistory(subscriber, input, userRecordId, assistantRecordId, userContent, assistantContent) {
542
- const envId = this.yuanqiConfig.envId || getCloudbaseEnvId();
543
581
  const botId = `bot-yuanqi-${this.finalAppId}`;
544
582
  const { threadId, runId } = input;
545
- const isDBReady = await this.checkIsDatabaseReady(envId);
583
+ const tcbClient = this.getTcbClient();
584
+ const isDBReady = await this.checkIsDatabaseReady();
546
585
  if (!isDBReady) {
547
586
  subscriber.next({
548
587
  type: EventType2.RAW,
@@ -553,12 +592,6 @@ var YuanqiAgent = class extends AbstractAgent {
553
592
  });
554
593
  return;
555
594
  }
556
- const tcbClient = tcb.init({
557
- env: envId,
558
- secretId: this.finalCloudCredential.secretId,
559
- secretKey: this.finalCloudCredential.secretKey,
560
- sessionToken: this.finalCloudCredential.token
561
- });
562
595
  const userEntity = new ChatHistoryEntity();
563
596
  userEntity.recordId = userRecordId;
564
597
  userEntity.botId = botId;
@@ -584,28 +617,39 @@ var YuanqiAgent = class extends AbstractAgent {
584
617
  chatHistoryEntity: assistantEntity
585
618
  });
586
619
  }
587
- async checkIsDatabaseReady(envId) {
588
- if (!envId) {
589
- throw new YuanqiAgentError(
590
- "CLOUDBASE_ENV_ID is required, check your env variables or config passed with the adapter",
591
- "MISSING_CLOUDBASE_ENV_ID"
592
- );
593
- }
594
- if (!this.finalCloudCredential.token) {
595
- if (!this.finalCloudCredential.secretId) {
620
+ getTcbClient() {
621
+ const envId = this.yuanqiConfig.envId || getCloudbaseEnvId();
622
+ const tcbClient = tcb.init({
623
+ env: envId,
624
+ secretId: this.finalCloudCredential.secretId,
625
+ secretKey: this.finalCloudCredential.secretKey,
626
+ sessionToken: this.finalCloudCredential.token
627
+ });
628
+ return tcbClient;
629
+ }
630
+ async checkIsDatabaseReady() {
631
+ try {
632
+ const envId = this.yuanqiConfig.envId || getCloudbaseEnvId();
633
+ if (!envId) {
596
634
  throw new YuanqiAgentError(
597
- "TENCENTCLOUD_SECRETID is required, check your env variables or config passed with the adapter",
598
- "MISSING_SECRET_ID"
635
+ "When saving chat history to CloudBase, CLOUDBASE_ENV_ID is required, check your env variables or config passed with the adapter",
636
+ "MISSING_CLOUDBASE_ENV_ID"
599
637
  );
600
638
  }
601
- if (!this.finalCloudCredential.secretKey) {
602
- throw new YuanqiAgentError(
603
- "TENCENTCLOUD_SECRETKEY is required, check your env variables or config passed with the adapter",
604
- "MISSING_SECRET_KEY"
605
- );
639
+ if (!this.finalCloudCredential.token) {
640
+ if (!this.finalCloudCredential.secretId) {
641
+ throw new YuanqiAgentError(
642
+ "When saving chat history to CloudBase, TENCENTCLOUD_SECRETID is required, check your env variables or config passed with the adapter",
643
+ "MISSING_SECRET_ID"
644
+ );
645
+ }
646
+ if (!this.finalCloudCredential.secretKey) {
647
+ throw new YuanqiAgentError(
648
+ "When saving chat history to CloudBase, TENCENTCLOUD_SECRETKEY is required, check your env variables or config passed with the adapter",
649
+ "MISSING_SECRET_KEY"
650
+ );
651
+ }
606
652
  }
607
- }
608
- try {
609
653
  const managedTcbClient = managedTcb.init({
610
654
  envId,
611
655
  secretId: this.finalCloudCredential.secretId,
@@ -622,10 +666,12 @@ var YuanqiAgent = class extends AbstractAgent {
622
666
  CHAT_HISTORY_DATA_SOURCE
623
667
  );
624
668
  return true;
669
+ } else {
670
+ throw new Error("Check database exists failed");
625
671
  }
626
672
  } catch (dbError) {
627
673
  console.error(
628
- "Failed to check/create chat history collection:",
674
+ "[ERROR] Failed to check/create chat history collection:",
629
675
  JSON.stringify(dbError)
630
676
  );
631
677
  return false;
@@ -633,9 +679,9 @@ var YuanqiAgent = class extends AbstractAgent {
633
679
  }
634
680
  };
635
681
  function getCloudbaseEnvId() {
636
- if (!!process.env.CBR_ENV_ID) {
682
+ if (process.env.CBR_ENV_ID) {
637
683
  return process.env.CBR_ENV_ID;
638
- } else if (!!process.env.SCF_NAMESPACE) {
684
+ } else if (process.env.SCF_NAMESPACE) {
639
685
  return process.env.SCF_NAMESPACE;
640
686
  } else {
641
687
  return process.env.CLOUDBASE_ENV_ID || "";
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/agent.ts","../src/utils.ts","../src/stream.ts","../src/constant.ts","../src/chat_history.ts"],"sourcesContent":["import {\n RunAgentInput,\n Message,\n AbstractAgent,\n AgentConfig,\n BaseEvent,\n EventType,\n} from \"@ag-ui/client\";\nimport tcb from \"@cloudbase/node-sdk\";\nimport managedTcb from \"@cloudbase/manager-node\";\nimport OpenAI from \"openai\";\nimport { randomUUID } from \"crypto\";\nimport { camelToSnakeKeys } from \"./utils\";\nimport { processYuanqiStream } from \"./stream\";\nimport { Observable, Subscriber } from \"rxjs\";\nimport {\n createChatHistory,\n queryForLLM,\n ChatHistoryEntity,\n} from \"./chat_history\";\nimport { CHAT_HISTORY_DATA_SOURCE } from \"./constant\";\nimport { YuanqiConfig, ChatMessage, YuanqiChatRequest } from \"./types\";\n\nexport class YuanqiAgentError extends Error {\n code?: string;\n constructor(message: string, code?: string) {\n super(message);\n this.name = \"YuanqiAgentError\";\n if (code) this.code = code;\n }\n}\n\nexport class YuanqiAgent extends AbstractAgent {\n protected yuanqiConfig: YuanqiConfig;\n private finalAppId: string;\n private finalCloudCredential: {\n secretId?: string;\n secretKey?: string;\n token?: string;\n } = {};\n private model: OpenAI;\n constructor(config: AgentConfig & { yuanqiConfig: YuanqiConfig }) {\n super(config);\n this.yuanqiConfig = config.yuanqiConfig;\n this.model = new OpenAI({\n apiKey: \"\",\n baseURL:\n this.yuanqiConfig.request?.baseUrl ||\n \"https://yuanqi.tencent.com/openapi/v1/agent\",\n });\n this.finalAppId =\n this.yuanqiConfig.appId ||\n this.yuanqiConfig.request?.body?.assistantId ||\n process.env.YUANQI_APP_ID ||\n \"\";\n this.finalCloudCredential = {\n secretId:\n this.yuanqiConfig.credential?.secretId ||\n process.env.TENCENTCLOUD_SECRETID,\n secretKey:\n this.yuanqiConfig.credential?.secretKey ||\n process.env.TENCENTCLOUD_SECRETKEY,\n token:\n this.yuanqiConfig.credential?.token ||\n process.env.TENCENTCLOUD_SESSIONTOKEN,\n };\n }\n\n generateRequestBody({\n messages,\n input,\n }: {\n messages: ChatMessage[];\n input: RunAgentInput;\n }): YuanqiChatRequest {\n const { state, forwardedProps } = input;\n const requestBody: YuanqiChatRequest = {\n stream: true,\n ...(this.yuanqiConfig.request?.body || {}),\n ...(forwardedProps || {}),\n\n assistantId: this.finalAppId,\n userId:\n state?.__request_context__?.id ||\n forwardedProps?.userId ||\n randomUUID(),\n messages,\n };\n return requestBody;\n }\n\n run(input: RunAgentInput): Observable<BaseEvent> {\n return new Observable<BaseEvent>((subscriber) => {\n this._run(subscriber, input);\n });\n }\n\n private async _run(subscriber: any, input: RunAgentInput): Promise<void> {\n try {\n const { messages, runId, threadId: _threadId } = input;\n\n const openai = this.model as OpenAI;\n const threadId = _threadId || randomUUID();\n\n subscriber.next({\n type: EventType.RUN_STARTED,\n threadId,\n runId,\n });\n\n if (!this.finalAppId) {\n throw new YuanqiAgentError(\n \"YUANQI_APP_ID is required, check your env variables or config passed with the adapter\",\n \"MISSING_YUANQI_APP_ID\"\n );\n }\n if (!this.yuanqiConfig.appKey && !process.env.YUANQI_APP_KEY) {\n throw new YuanqiAgentError(\n \"YUANQI_APP_KEY is required, check your env variables or config passed with the adapter\",\n \"MISSING_YUANQI_APP_KEY\"\n );\n }\n\n // Warn user if messages are being trimmed (only using latest user message)\n const trimmedCount = messages.length - 1;\n if (trimmedCount > 0) {\n subscriber.next({\n type: EventType.RAW,\n rawEvent: {\n message: `Yuanqi handles message history itself, so that a total of ${trimmedCount} messages before the last user message will be trimmed.`,\n type: \"warn\",\n },\n });\n }\n\n // Get the latest user message for saving to history\n const latestUserMessage = messages.filter((m) => m.role === \"user\").pop();\n if (!latestUserMessage) {\n throw new YuanqiAgentError(\n \"No user message found, please send a message first.\",\n \"MESSAGE_FORMAT_ERROR\"\n );\n }\n\n const allMessages = await this.getChatHistory(\n subscriber,\n latestUserMessage\n );\n\n const body = this.generateRequestBody({\n messages: allMessages,\n input,\n });\n\n const stream = await openai.chat.completions.create(\n {\n stream: true,\n messages: [],\n model: \"\",\n },\n {\n body: camelToSnakeKeys(body),\n headers: {\n ...this.yuanqiConfig.request?.headers,\n Authorization: `Bearer ${\n this.yuanqiConfig.appKey || process.env.YUANQI_APP_KEY\n }`,\n },\n }\n );\n\n // Process stream and emit AGUI events, collect full response\n const userRecordId = `record-${randomUUID().slice(0, 8)}`;\n const assistantRecordId = `record-${randomUUID().slice(0, 8)}`;\n const context = { threadId, runId, messageId: userRecordId };\n\n let fullAssistantContent = \"\";\n\n for await (const event of processYuanqiStream(stream, context)) {\n subscriber.next(event);\n // Collect assistant content from TEXT_MESSAGE_CONTENT events\n if (\n event.type === EventType.TEXT_MESSAGE_CONTENT &&\n (event as any).delta\n ) {\n fullAssistantContent += (event as any).delta;\n }\n }\n\n const userContent =\n typeof latestUserMessage?.content === \"string\"\n ? latestUserMessage.content\n : latestUserMessage?.content\n ?.filter((c) => c.type === \"text\")\n .map((c) => (c as any).text)\n .join(\"\") || \"\";\n\n await this.saveChatHistory(\n subscriber,\n input,\n userRecordId,\n assistantRecordId,\n userContent,\n fullAssistantContent\n );\n\n subscriber.next({\n type: EventType.RUN_FINISHED,\n threadId,\n runId,\n } as any);\n } catch (e: unknown) {\n console.error(JSON.stringify(e));\n let code = \"UNKNOWN_ERROR\";\n let message = JSON.stringify(e);\n if (e instanceof YuanqiAgentError) {\n code = e.code || \"AGENT_ERROR\";\n message = e.message;\n } else if (e instanceof Error) {\n code = e.name || \"ERROR\";\n message = e.message;\n }\n subscriber.next({\n type: EventType.RUN_ERROR,\n code,\n message: `Sorry, an error occurred while running the agent: Error code ${code}, ${message}`,\n } as any);\n } finally {\n subscriber.complete();\n }\n }\n\n // Can be override by subclasses\n protected async getChatHistory(\n subscriber: Subscriber<BaseEvent>,\n latestUserMessage: Message\n ) {\n const envId = this.yuanqiConfig.envId || getCloudbaseEnvId();\n const botId = `bot-yuanqi-${this.finalAppId}`;\n\n const isDBReady = await this.checkIsDatabaseReady(envId);\n if (!isDBReady) {\n subscriber.next({\n type: EventType.RAW,\n rawEvent: {\n message: `Chat history database is not ready, skip history loading.`,\n type: \"warn\",\n },\n });\n return convertMessagesToOpenAI([latestUserMessage]);\n }\n\n const tcbClient = tcb.init({\n env: envId,\n secretId: this.finalCloudCredential.secretId,\n secretKey: this.finalCloudCredential.secretKey,\n sessionToken: this.finalCloudCredential.token,\n });\n\n // Fetch chat history from database using queryForLLM\n let historyMessages: ChatMessage[] = [];\n\n const historyCount = this.yuanqiConfig.historyCount ?? 10;\n const historyRecords = await queryForLLM({\n tcbClient,\n botId,\n pageSize: historyCount,\n });\n\n // Convert queryForLLM result to ChatMessage format\n historyMessages = historyRecords.map((record) => ({\n role: record.role as \"user\" | \"assistant\",\n content: [{ type: \"text\" as const, text: record.content }],\n }));\n\n // Combine history messages with current messages\n const allMessages = historyMessages.concat(\n convertMessagesToOpenAI([latestUserMessage])\n );\n return allMessages;\n }\n\n // Can be override by subclasses\n protected async saveChatHistory(\n subscriber: Subscriber<BaseEvent>,\n input: RunAgentInput,\n userRecordId: string,\n assistantRecordId: string,\n userContent: string,\n assistantContent: string\n ) {\n const envId = this.yuanqiConfig.envId || getCloudbaseEnvId();\n const botId = `bot-yuanqi-${this.finalAppId}`;\n\n const { threadId, runId } = input;\n\n const isDBReady = await this.checkIsDatabaseReady(envId);\n if (!isDBReady) {\n subscriber.next({\n type: EventType.RAW,\n rawEvent: {\n message: `Chat history database is not ready, skip history saving.`,\n type: \"warn\",\n },\n });\n return;\n }\n\n const tcbClient = tcb.init({\n env: envId,\n secretId: this.finalCloudCredential.secretId,\n secretKey: this.finalCloudCredential.secretKey,\n sessionToken: this.finalCloudCredential.token,\n });\n\n // Save message pair to history\n const userEntity = new ChatHistoryEntity();\n userEntity.recordId = userRecordId;\n userEntity.botId = botId;\n userEntity.role = \"user\";\n userEntity.content = userContent;\n userEntity.conversation = threadId;\n userEntity.reply = assistantRecordId;\n userEntity.triggerSrc = \"\";\n userEntity.traceId = randomUUID();\n\n await createChatHistory({ tcbClient, chatHistoryEntity: userEntity });\n\n const assistantEntity = new ChatHistoryEntity();\n assistantEntity.recordId = assistantRecordId;\n assistantEntity.botId = botId;\n assistantEntity.role = \"assistant\";\n assistantEntity.content = assistantContent;\n assistantEntity.conversation = threadId;\n assistantEntity.replyTo = userRecordId;\n assistantEntity.triggerSrc = \"\";\n assistantEntity.traceId = runId;\n assistantEntity.status = \"done\";\n\n await createChatHistory({\n tcbClient,\n chatHistoryEntity: assistantEntity,\n });\n }\n\n private async checkIsDatabaseReady(envId: string) {\n if (!envId) {\n throw new YuanqiAgentError(\n \"CLOUDBASE_ENV_ID is required, check your env variables or config passed with the adapter\",\n \"MISSING_CLOUDBASE_ENV_ID\"\n );\n }\n if (!this.finalCloudCredential.token) {\n if (!this.finalCloudCredential.secretId) {\n throw new YuanqiAgentError(\n \"TENCENTCLOUD_SECRETID is required, check your env variables or config passed with the adapter\",\n \"MISSING_SECRET_ID\"\n );\n }\n if (!this.finalCloudCredential.secretKey) {\n throw new YuanqiAgentError(\n \"TENCENTCLOUD_SECRETKEY is required, check your env variables or config passed with the adapter\",\n \"MISSING_SECRET_KEY\"\n );\n }\n }\n\n try {\n const managedTcbClient = managedTcb.init({\n envId,\n secretId: this.finalCloudCredential.secretId,\n secretKey: this.finalCloudCredential.secretKey,\n token: this.finalCloudCredential.token,\n });\n\n const checkDBRes = await managedTcbClient.database.checkCollectionExists(\n CHAT_HISTORY_DATA_SOURCE\n );\n if (checkDBRes && checkDBRes.Exists) {\n return true;\n } else if (checkDBRes && !checkDBRes.Exists) {\n await managedTcbClient.database.createCollection(\n CHAT_HISTORY_DATA_SOURCE\n );\n return true;\n }\n } catch (dbError) {\n console.error(\n \"Failed to check/create chat history collection:\",\n JSON.stringify(dbError)\n );\n return false;\n }\n }\n}\n\nfunction getCloudbaseEnvId() {\n if (!!process.env.CBR_ENV_ID) {\n return process.env.CBR_ENV_ID;\n } else if (!!process.env.SCF_NAMESPACE) {\n return process.env.SCF_NAMESPACE;\n } else {\n return process.env.CLOUDBASE_ENV_ID || \"\";\n }\n}\n\n/**\n * Convert AGUI messages to OpenAI chat completion format\n */\nexport function convertMessagesToOpenAI(\n messages: Message[],\n systemPrompt?: string\n): OpenAI.Chat.ChatCompletionMessageParam[] {\n const openaiMessages: OpenAI.Chat.ChatCompletionMessageParam[] = [];\n\n // Add system prompt if provided\n if (systemPrompt) {\n openaiMessages.push({\n role: \"system\",\n content: systemPrompt,\n });\n }\n\n // Convert messages\n for (const msg of messages) {\n if (msg.role === \"user\") {\n openaiMessages.push({\n role: \"user\",\n content:\n typeof msg.content === \"string\"\n ? [{ type: \"text\", text: msg.content }]\n : msg.content.map((item) => {\n if (item.type === \"text\") {\n return { type: \"text\", text: item.text };\n } else {\n return {\n type: \"image_url\",\n image_url: { url: item.url || \"\" },\n };\n }\n }),\n });\n } else if (msg.role === \"assistant\") {\n openaiMessages.push({\n role: \"assistant\",\n content: msg.content ? [{ type: \"text\", text: msg.content }] : [],\n tool_calls: msg.toolCalls?.map((tc: any) => ({\n id: tc.id,\n type: \"function\" as const,\n function: {\n name: tc.function.name,\n arguments: tc.function.arguments,\n },\n })),\n });\n } else if (msg.role === \"tool\") {\n openaiMessages.push({\n role: \"tool\",\n tool_call_id: msg.toolCallId!,\n content: msg.content ? [{ type: \"text\", text: msg.content }] : [],\n });\n }\n }\n\n return openaiMessages;\n}\n","/**\n * 将小驼峰字符串转换为下划线格式\n * 例如: \"userName\" -> \"user_name\"\n */\nfunction camelToSnake(str: string): string {\n return str.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`);\n}\n\n/**\n * 递归地将对象的所有小驼峰属性名转换为下划线格式\n */\nexport function camelToSnakeKeys<T>(obj: T): T {\n if (obj === null || obj === undefined) {\n return obj;\n }\n\n if (Array.isArray(obj)) {\n return obj.map((item) => camelToSnakeKeys(item)) as T;\n }\n\n if (typeof obj === \"object\") {\n const result: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(obj)) {\n const snakeKey = camelToSnake(key);\n result[snakeKey] = camelToSnakeKeys(value);\n }\n return result as T;\n }\n\n return obj;\n}\n\nexport function genRandomStr(length: number): string {\n const chars = \"abcdefghijklmnopqrstuvwxyz0123456789\";\n let result = \"\";\n for (let i = 0; i < length; i++) {\n result += chars.charAt(Math.floor(Math.random() * chars.length));\n }\n return result;\n}\n","import OpenAI from \"openai\";\nimport { EventType } from \"@ag-ui/client\";\n\nexport interface StreamContext {\n threadId: string;\n runId: string;\n messageId: string;\n}\n\nexport interface StreamState {\n hasStarted: boolean;\n fullContent: string;\n toolCallsMap: Map<string, { name: string; args: string }>;\n}\n\nexport type Delta =\n OpenAI.Chat.Completions.ChatCompletionChunk[\"choices\"][number][\"delta\"] & {\n reasoning_content?: string;\n };\n\nexport async function* processYuanqiStream(\n stream: AsyncIterable<OpenAI.Chat.Completions.ChatCompletionChunk>,\n context: StreamContext\n) {\n const { threadId, runId, messageId } = context;\n const state: StreamState = {\n hasStarted: false,\n fullContent: \"\",\n toolCallsMap: new Map(),\n };\n const reasoningState: StreamState = {\n hasStarted: false,\n fullContent: \"\",\n toolCallsMap: new Map(),\n };\n\n for await (const chunk of stream) {\n const delta = chunk.choices[0]?.delta as Delta;\n if (!delta) continue;\n\n // Handle text content\n if (delta.content) {\n // End reasoning message if it was started\n if (reasoningState.hasStarted) {\n reasoningState.hasStarted = false;\n yield {\n type: EventType.THINKING_TEXT_MESSAGE_END,\n threadId,\n runId,\n messageId,\n };\n yield {\n type: EventType.THINKING_END,\n threadId,\n runId,\n messageId,\n };\n }\n\n if (!state.hasStarted) {\n yield {\n type: EventType.TEXT_MESSAGE_START,\n threadId,\n runId,\n messageId,\n role: \"assistant\",\n };\n state.hasStarted = true;\n }\n\n state.fullContent += delta.content;\n yield {\n type: EventType.TEXT_MESSAGE_CONTENT,\n threadId,\n runId,\n messageId,\n delta: delta.content,\n };\n }\n\n // Handle reasoning content\n if (delta.reasoning_content) {\n if (!reasoningState.hasStarted) {\n yield {\n type: EventType.THINKING_START,\n threadId,\n runId,\n messageId,\n };\n yield {\n type: EventType.THINKING_TEXT_MESSAGE_START,\n threadId,\n runId,\n messageId,\n role: \"assistant\",\n };\n reasoningState.hasStarted = true;\n }\n\n reasoningState.fullContent += delta.reasoning_content;\n yield {\n type: EventType.THINKING_TEXT_MESSAGE_CONTENT,\n threadId,\n runId,\n messageId,\n delta: delta.reasoning_content,\n };\n }\n\n // Handle tool calls\n if (delta.tool_calls) {\n for (const toolCall of delta.tool_calls) {\n const toolCallId = toolCall.id || `tool_${toolCall.index}`;\n\n if (toolCall.function?.name) {\n // Tool call start\n yield {\n type: EventType.TOOL_CALL_START,\n threadId,\n runId,\n toolCallId,\n toolCallName: toolCall.function.name,\n };\n\n state.toolCallsMap.set(toolCallId, {\n name: toolCall.function.name,\n args: toolCall.function.arguments || \"\",\n });\n } else if (toolCall.function?.arguments) {\n // Tool call arguments delta\n const existing = state.toolCallsMap.get(toolCallId);\n if (existing) {\n existing.args += toolCall.function.arguments;\n\n yield {\n type: EventType.TOOL_CALL_ARGS,\n threadId,\n runId,\n toolCallId,\n delta: toolCall.function.arguments,\n };\n }\n }\n }\n }\n }\n\n // Emit TEXT_MESSAGE_END if we had text content\n if (state.hasStarted) {\n yield {\n type: EventType.TEXT_MESSAGE_END,\n threadId,\n runId,\n messageId,\n };\n }\n\n // Emit TOOL_CALL_END for all tool calls\n for (const [toolCallId] of state.toolCallsMap) {\n yield {\n type: EventType.TOOL_CALL_END,\n threadId,\n runId,\n toolCallId,\n };\n }\n}\n","// 对话数据模型\nexport const CHAT_HISTORY_DATA_SOURCE = \"ai_bot_chat_history_5hobd2b\";\n","import tcb from \"@cloudbase/node-sdk\";\nimport { CHAT_HISTORY_DATA_SOURCE } from \"./constant\";\nimport { genRandomStr } from \"./utils\";\n\nfunction genRecordId(): string {\n return \"record-\" + genRandomStr(8);\n}\n\n// Create a new chat history record\nexport async function createChatHistory({\n tcbClient,\n chatHistoryEntity,\n}: {\n tcbClient: tcb.CloudBase;\n chatHistoryEntity: ChatHistoryEntity;\n}): Promise<string | undefined> {\n try {\n const recordId = chatHistoryEntity.recordId || genRecordId();\n const data = {\n record_id: recordId,\n bot_id: chatHistoryEntity.botId,\n role: chatHistoryEntity.role,\n content: chatHistoryEntity.content,\n sender: chatHistoryEntity.sender,\n conversation: chatHistoryEntity.conversation,\n type: chatHistoryEntity.type,\n image: chatHistoryEntity.image,\n trigger_src: chatHistoryEntity.triggerSrc,\n origin_msg: chatHistoryEntity.originMsg,\n reply_to: chatHistoryEntity.replyTo,\n reply: chatHistoryEntity.reply,\n trace_id: chatHistoryEntity.traceId,\n need_async_reply: chatHistoryEntity.needAsyncReply,\n async_reply: chatHistoryEntity.asyncReply,\n createdAt: Date.now(),\n updatedAt: Date.now(),\n };\n\n const db = tcbClient.database();\n const collection = db.collection(CHAT_HISTORY_DATA_SOURCE);\n const result = await collection.add(data);\n\n // console.log(\n // `Create record: chatHistoryEntity:${JSON.stringify(\n // chatHistoryEntity\n // )}, result: ${JSON.stringify(result)}`\n // );\n return recordId;\n } catch (error) {\n console.error(\"Failed to create chat history record, error:\", error);\n return undefined;\n }\n}\n\n// Update chat history by record ID\nexport async function updateChatHistoryByRecordId({\n tcbClient,\n recordId,\n chatHistoryEntity,\n}: {\n tcbClient: tcb.CloudBase;\n recordId: string;\n chatHistoryEntity: ChatHistoryEntity;\n}): Promise<string | undefined> {\n try {\n const db = tcbClient.database();\n const _ = db.command;\n const collection = db.collection(CHAT_HISTORY_DATA_SOURCE);\n\n const result = await collection\n .where({ record_id: _.eq(recordId) })\n .update({\n content: chatHistoryEntity.content,\n image: chatHistoryEntity.image,\n async_reply: chatHistoryEntity.asyncReply,\n recommend_questions: chatHistoryEntity.recommendQuestions,\n status: chatHistoryEntity.status,\n origin_msg: chatHistoryEntity.originMsg,\n updatedAt: Date.now(),\n });\n\n // console.log(\n // `Update record: recordId: ${recordId}, chatHistoryEntity:${JSON.stringify(\n // chatHistoryEntity\n // )}, result: ${JSON.stringify(result)}`\n // );\n return chatHistoryEntity.recordId;\n } catch (error) {\n console.error(\"Failed to update chat history, error:\", error);\n return undefined;\n }\n}\n\n// Query chat history from database\nexport async function describeChatHistory({\n tcbClient,\n botId,\n sort,\n pageSize = 10,\n pageNumber = 1,\n conversation,\n startCreatedAt,\n triggerSrc,\n}: {\n tcbClient: tcb.CloudBase;\n botId: string;\n sort: \"asc\" | \"desc\";\n pageSize?: number;\n pageNumber?: number;\n conversation?: string;\n startCreatedAt?: number;\n triggerSrc?: string;\n}): Promise<[ChatHistoryEntity[], number]> {\n if (!sort || sort.length === 0) {\n sort = \"desc\";\n }\n\n try {\n const db = tcbClient.database();\n const _ = db.command;\n const collection = db.collection(CHAT_HISTORY_DATA_SOURCE);\n\n // Build where conditions\n const whereConditions: Record<string, unknown> = {\n bot_id: _.eq(botId),\n };\n\n // Add optional filters\n if (conversation) {\n whereConditions.conversation = _.eq(conversation);\n }\n\n if (startCreatedAt !== undefined) {\n whereConditions.createdAt = _.gt(startCreatedAt);\n }\n\n if (triggerSrc) {\n whereConditions.trigger_src = _.eq(triggerSrc);\n }\n\n // Calculate skip for pagination\n const skip = (pageNumber - 1) * pageSize;\n\n // Query records\n const result = await collection\n .where(whereConditions)\n .orderBy(\"createdAt\", sort)\n .skip(skip)\n .limit(pageSize)\n .get();\n\n // Get total count\n const countResult = await collection.where(whereConditions).count();\n const total = countResult.total || 0;\n\n const records = result?.data || [];\n\n const entityList: ChatHistoryEntity[] = records.map(\n (item: ChatHistoryData) => transDataToChatEntity(item)\n );\n\n return [entityList, total];\n } catch (error) {\n console.error(\"Failed to query chat history, error:\", error);\n return [[], 0];\n }\n}\n\n// Transform data to ChatHistoryEntity structure\nexport function transDataToChatEntity(\n item: ChatHistoryData\n): ChatHistoryEntity {\n if (!item) {\n return new ChatHistoryEntity();\n }\n const chatEntity: ChatHistoryEntity = new ChatHistoryEntity();\n chatEntity.botId = item.bot_id;\n chatEntity.recordId = item.record_id;\n chatEntity.role = item.role;\n chatEntity.status = item.status;\n chatEntity.content = item.content;\n chatEntity.sender = item.sender;\n chatEntity.conversation = item.conversation;\n chatEntity.type = item.type;\n chatEntity.triggerSrc = item.trigger_src;\n chatEntity.originMsg = item.origin_msg;\n chatEntity.replyTo = item.reply_to;\n chatEntity.reply = item.reply;\n chatEntity.traceId = item.trace_id;\n chatEntity.needAsyncReply = item.need_async_reply;\n chatEntity.asyncReply = item.async_reply;\n chatEntity.createdAt = item.createdAt;\n chatEntity.updatedAt = item.updatedAt;\n return chatEntity;\n}\n\n// Query history records for LLM, get the most recent 10 conversation pairs (20 records)\nexport async function queryForLLM({\n tcbClient,\n botId,\n pageSize = 10,\n startCreatedAt,\n triggerSrc,\n}: {\n tcbClient: tcb.CloudBase;\n botId: string;\n pageSize?: number;\n startCreatedAt?: number;\n triggerSrc?: string;\n}): Promise<{ role: string; content: string }[]> {\n if (startCreatedAt === undefined) {\n startCreatedAt = Date.now() - 24 * 60 * 60 * 1000;\n }\n const recordEntityList: ChatHistoryEntity[] = [];\n\n const [recordList] = await describeChatHistory({\n tcbClient,\n botId,\n sort: \"desc\",\n pageSize,\n startCreatedAt,\n triggerSrc,\n });\n recordEntityList.push(...recordList.reverse());\n\n const entityMap = new Map<string, ChatHistoryEntity>();\n recordEntityList\n .filter((item) => {\n if (item.needAsyncReply === true) {\n return !!item.asyncReply;\n } else {\n return !!item.content;\n }\n })\n .forEach((item) => {\n entityMap.set(item.recordId, item);\n });\n\n const result: { role: string; content: string }[] = [];\n /*\n 1. Strongly depends on database history data, model history data has role order requirements\n 2. Need to ensure that no matter what bug occurs, always get a complete and usable user + assistant pair, otherwise the request will fail\n */\n recordEntityList.forEach((item) => {\n const { role, content, reply } = item;\n // When calling LLM, empty content will cause failure, so filter out conversations with empty content\n if (role === \"user\" && content?.length !== 0) {\n if (entityMap.has(reply)) {\n result.push({ role, content });\n result.push({\n role: entityMap.get(reply)!.role,\n content: entityMap.get(reply)!.content,\n });\n }\n }\n });\n if (result.length % 2 === 1) {\n result.splice(-1, 1);\n }\n return result;\n}\n\nexport interface ChatHistoryData {\n bot_id: string;\n record_id: string;\n role: string;\n status: string;\n content: string;\n sender: string;\n conversation: string;\n type: string;\n trigger_src: string;\n origin_msg: string;\n reply_to: string;\n reply: string;\n trace_id: string;\n need_async_reply: boolean;\n async_reply: string;\n createdAt: number;\n updatedAt: number;\n}\n\nexport class ChatHistoryEntity {\n id: number;\n botId: string;\n // 对话唯一id\n recordId: string;\n role: string;\n content: string;\n recommendQuestions: string[];\n sender: string;\n conversation: string;\n type: string;\n /**\n * 消息状态,pending donw error cancel\n */\n status: string;\n image: string;\n triggerSrc: string;\n originMsg: string;\n replyTo: string;\n reply: string;\n traceId: string;\n needAsyncReply: boolean;\n asyncReply: string;\n createTime: string;\n updateTime: string;\n createdAt: number;\n updatedAt: number;\n event: string;\n}\n"],"mappings":"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","names":["EventType","EventType"]}
1
+ {"version":3,"sources":["../src/agent.ts","../src/utils.ts","../src/stream.ts","../src/constant.ts","../src/chat_history.ts"],"sourcesContent":["import {\n RunAgentInput,\n Message,\n AbstractAgent,\n AgentConfig,\n BaseEvent,\n EventType,\n RunStartedEvent,\n RunFinishedEvent,\n RunErrorEvent,\n TextMessageContentEvent,\n ToolCall,\n} from \"@ag-ui/client\";\nimport tcb from \"@cloudbase/node-sdk\";\nimport managedTcb from \"@cloudbase/manager-node\";\nimport OpenAI from \"openai\";\nimport { randomUUID } from \"crypto\";\nimport { camelToSnakeKeys } from \"./utils\";\nimport { processYuanqiStream } from \"./stream\";\nimport { Observable, Subscriber } from \"rxjs\";\nimport {\n createChatHistory,\n queryForLLM,\n ChatHistoryEntity,\n} from \"./chat_history\";\nimport { CHAT_HISTORY_DATA_SOURCE } from \"./constant\";\nimport { YuanqiConfig, ChatMessage, YuanqiChatRequest } from \"./types\";\n\nexport class YuanqiAgentError extends Error {\n code?: string;\n constructor(message: string, code?: string) {\n super(message);\n this.name = \"YuanqiAgentError\";\n if (code) this.code = code;\n }\n}\n\nexport class YuanqiAgent extends AbstractAgent {\n protected yuanqiConfig: YuanqiConfig;\n private finalAppId: string;\n private finalCloudCredential: {\n secretId?: string;\n secretKey?: string;\n token?: string;\n } = {};\n private model: OpenAI;\n constructor(config: AgentConfig & { yuanqiConfig: YuanqiConfig }) {\n super(config);\n this.yuanqiConfig = config.yuanqiConfig;\n this.model = new OpenAI({\n apiKey: \"\",\n baseURL:\n this.yuanqiConfig.request?.baseUrl ||\n \"https://yuanqi.tencent.com/openapi/v1/agent\",\n });\n this.finalAppId =\n this.yuanqiConfig.appId ||\n this.yuanqiConfig.request?.body?.assistantId ||\n process.env.YUANQI_APP_ID ||\n \"\";\n this.finalCloudCredential = {\n secretId:\n this.yuanqiConfig.credential?.secretId ||\n process.env.TENCENTCLOUD_SECRETID,\n secretKey:\n this.yuanqiConfig.credential?.secretKey ||\n process.env.TENCENTCLOUD_SECRETKEY,\n token:\n this.yuanqiConfig.credential?.token ||\n process.env.TENCENTCLOUD_SESSIONTOKEN,\n };\n }\n\n generateRequestBody({\n messages,\n input,\n }: {\n messages: ChatMessage[];\n input: RunAgentInput;\n }): YuanqiChatRequest {\n const { state, forwardedProps } = input;\n const requestBody: YuanqiChatRequest = {\n stream: true,\n ...(this.yuanqiConfig.request?.body || {}),\n ...(forwardedProps || {}),\n\n assistantId: this.finalAppId,\n userId:\n state?.__request_context__?.id ||\n forwardedProps?.userId ||\n randomUUID(),\n messages,\n };\n return requestBody;\n }\n\n run(input: RunAgentInput): Observable<BaseEvent> {\n return new Observable<BaseEvent>((subscriber) => {\n this._run(subscriber, input);\n });\n }\n\n private async _run(\n subscriber: Subscriber<BaseEvent>,\n input: RunAgentInput\n ): Promise<void> {\n try {\n const { messages, runId } = input;\n\n const openai = this.model as OpenAI;\n const threadId = input.threadId || randomUUID();\n\n subscriber.next({\n type: EventType.RUN_STARTED,\n threadId,\n runId,\n } as RunStartedEvent);\n\n if (!this.finalAppId) {\n throw new YuanqiAgentError(\n \"YUANQI_APP_ID is required, check your env variables or config passed with the adapter\",\n \"MISSING_YUANQI_APP_ID\"\n );\n }\n if (!this.yuanqiConfig.appKey && !process.env.YUANQI_APP_KEY) {\n throw new YuanqiAgentError(\n \"YUANQI_APP_KEY is required, check your env variables or config passed with the adapter\",\n \"MISSING_YUANQI_APP_KEY\"\n );\n }\n\n // Warn user if messages are being trimmed (only using latest user message)\n const trimmedCount = messages.length - 1;\n if (trimmedCount > 0) {\n subscriber.next({\n type: EventType.RAW,\n rawEvent: {\n message: `Yuanqi handles message history itself, so that a total of ${trimmedCount} messages before the last user message will be trimmed.`,\n type: \"warn\",\n },\n });\n }\n\n // Get the latest user message for saving to history\n const latestUserMessage = messages.filter((m) => m.role === \"user\").pop();\n if (!latestUserMessage) {\n throw new YuanqiAgentError(\n \"No user message found, please send a message first.\",\n \"MESSAGE_FORMAT_ERROR\"\n );\n }\n\n const allMessages = await this.getChatHistory(\n subscriber,\n latestUserMessage\n );\n\n const body = this.generateRequestBody({\n messages: allMessages,\n input,\n });\n\n const stream = await openai.chat.completions.create(\n {\n stream: true,\n messages: [],\n model: \"\",\n },\n {\n body: camelToSnakeKeys(body),\n headers: {\n ...this.yuanqiConfig.request?.headers,\n Authorization: `Bearer ${\n this.yuanqiConfig.appKey || process.env.YUANQI_APP_KEY\n }`,\n },\n }\n );\n\n // Process stream and emit AGUI events, collect full response\n const userRecordId = `record-${randomUUID().slice(0, 8)}`;\n const assistantRecordId = `record-${randomUUID().slice(0, 8)}`;\n const context = { threadId, runId, messageId: userRecordId };\n\n let fullAssistantContent = \"\";\n\n for await (const event of processYuanqiStream(stream, context)) {\n subscriber.next(event);\n // Collect assistant content from TEXT_MESSAGE_CONTENT events\n if (\n event.type === EventType.TEXT_MESSAGE_CONTENT &&\n (event as TextMessageContentEvent).delta\n ) {\n fullAssistantContent += (event as TextMessageContentEvent).delta;\n }\n }\n\n const userContent =\n typeof latestUserMessage?.content === \"string\"\n ? latestUserMessage.content\n : latestUserMessage?.content\n ?.filter((c) => c.type === \"text\")\n .map((c) => c.text)\n .join(\"\") || \"\";\n\n await this.saveChatHistory(\n subscriber,\n input,\n userRecordId,\n assistantRecordId,\n userContent,\n fullAssistantContent\n );\n\n subscriber.next({\n type: EventType.RUN_FINISHED,\n threadId,\n runId,\n } as RunFinishedEvent);\n } catch (e: unknown) {\n console.error(\"[ERROR] Uncaught error: \", JSON.stringify(e));\n let code = \"UNKNOWN_ERROR\";\n let message = JSON.stringify(e);\n if (e instanceof YuanqiAgentError) {\n code = e.code || \"AGENT_ERROR\";\n message = e.message;\n } else if (e instanceof Error) {\n code = e.name || \"ERROR\";\n message = e.message;\n }\n subscriber.next({\n type: EventType.RUN_ERROR,\n code,\n message: `Sorry, an error occurred while running the agent: Error code ${code}, ${message}`,\n } as RunErrorEvent);\n } finally {\n subscriber.complete();\n }\n }\n\n // Can be override by subclasses\n protected async getChatHistory(\n subscriber: Subscriber<BaseEvent>,\n latestUserMessage: Message\n ) {\n const botId = `bot-yuanqi-${this.finalAppId}`;\n\n const tcbClient = this.getTcbClient();\n\n const isDBReady = await this.checkIsDatabaseReady();\n if (!isDBReady) {\n subscriber.next({\n type: EventType.RAW,\n rawEvent: {\n message: `Chat history database is not ready, skip history loading.`,\n type: \"warn\",\n },\n });\n return convertMessagesToOpenAI([latestUserMessage]);\n }\n\n // Fetch chat history from database using queryForLLM\n let historyMessages: ChatMessage[] = [];\n\n const historyCount = this.yuanqiConfig.historyCount ?? 10;\n const historyRecords = await queryForLLM({\n tcbClient,\n botId,\n pageSize: historyCount,\n });\n\n // Convert queryForLLM result to ChatMessage format\n historyMessages = historyRecords.map((record) => ({\n role: record.role as \"user\" | \"assistant\",\n content: [{ type: \"text\" as const, text: record.content }],\n }));\n\n // Combine history messages with current messages\n const allMessages = historyMessages.concat(\n convertMessagesToOpenAI([latestUserMessage])\n );\n return allMessages;\n }\n\n // Can be override by subclasses\n protected async saveChatHistory(\n subscriber: Subscriber<BaseEvent>,\n input: RunAgentInput,\n userRecordId: string,\n assistantRecordId: string,\n userContent: string,\n assistantContent: string\n ) {\n const botId = `bot-yuanqi-${this.finalAppId}`;\n\n const { threadId, runId } = input;\n\n const tcbClient = this.getTcbClient();\n\n const isDBReady = await this.checkIsDatabaseReady();\n if (!isDBReady) {\n subscriber.next({\n type: EventType.RAW,\n rawEvent: {\n message: `Chat history database is not ready, skip history saving.`,\n type: \"warn\",\n },\n });\n return;\n }\n\n // Save message pair to history\n const userEntity = new ChatHistoryEntity();\n userEntity.recordId = userRecordId;\n userEntity.botId = botId;\n userEntity.role = \"user\";\n userEntity.content = userContent;\n userEntity.conversation = threadId;\n userEntity.reply = assistantRecordId;\n userEntity.triggerSrc = \"\";\n userEntity.traceId = randomUUID();\n\n await createChatHistory({ tcbClient, chatHistoryEntity: userEntity });\n\n const assistantEntity = new ChatHistoryEntity();\n assistantEntity.recordId = assistantRecordId;\n assistantEntity.botId = botId;\n assistantEntity.role = \"assistant\";\n assistantEntity.content = assistantContent;\n assistantEntity.conversation = threadId;\n assistantEntity.replyTo = userRecordId;\n assistantEntity.triggerSrc = \"\";\n assistantEntity.traceId = runId;\n assistantEntity.status = \"done\";\n\n await createChatHistory({\n tcbClient,\n chatHistoryEntity: assistantEntity,\n });\n }\n\n private getTcbClient() {\n const envId = this.yuanqiConfig.envId || getCloudbaseEnvId();\n\n const tcbClient = tcb.init({\n env: envId,\n secretId: this.finalCloudCredential.secretId,\n secretKey: this.finalCloudCredential.secretKey,\n sessionToken: this.finalCloudCredential.token,\n });\n return tcbClient;\n }\n\n private async checkIsDatabaseReady() {\n try {\n const envId = this.yuanqiConfig.envId || getCloudbaseEnvId();\n if (!envId) {\n throw new YuanqiAgentError(\n \"When saving chat history to CloudBase, CLOUDBASE_ENV_ID is required, check your env variables or config passed with the adapter\",\n \"MISSING_CLOUDBASE_ENV_ID\"\n );\n }\n if (!this.finalCloudCredential.token) {\n if (!this.finalCloudCredential.secretId) {\n throw new YuanqiAgentError(\n \"When saving chat history to CloudBase, TENCENTCLOUD_SECRETID is required, check your env variables or config passed with the adapter\",\n \"MISSING_SECRET_ID\"\n );\n }\n if (!this.finalCloudCredential.secretKey) {\n throw new YuanqiAgentError(\n \"When saving chat history to CloudBase, TENCENTCLOUD_SECRETKEY is required, check your env variables or config passed with the adapter\",\n \"MISSING_SECRET_KEY\"\n );\n }\n }\n const managedTcbClient = managedTcb.init({\n envId,\n secretId: this.finalCloudCredential.secretId,\n secretKey: this.finalCloudCredential.secretKey,\n token: this.finalCloudCredential.token,\n });\n\n const checkDBRes = await managedTcbClient.database.checkCollectionExists(\n CHAT_HISTORY_DATA_SOURCE\n );\n if (checkDBRes && checkDBRes.Exists) {\n return true;\n } else if (checkDBRes && !checkDBRes.Exists) {\n await managedTcbClient.database.createCollection(\n CHAT_HISTORY_DATA_SOURCE\n );\n return true;\n } else {\n throw new Error(\"Check database exists failed\");\n }\n } catch (dbError) {\n console.error(\n \"[ERROR] Failed to check/create chat history collection:\",\n JSON.stringify(dbError)\n );\n return false;\n }\n }\n}\n\nfunction getCloudbaseEnvId() {\n if (process.env.CBR_ENV_ID) {\n return process.env.CBR_ENV_ID;\n } else if (process.env.SCF_NAMESPACE) {\n return process.env.SCF_NAMESPACE;\n } else {\n return process.env.CLOUDBASE_ENV_ID || \"\";\n }\n}\n\n/**\n * Convert AGUI messages to OpenAI chat completion format\n */\nexport function convertMessagesToOpenAI(\n messages: Message[],\n systemPrompt?: string\n): ChatMessage[] {\n const openaiMessages: ChatMessage[] = [];\n\n // Add system prompt if provided\n if (systemPrompt) {\n openaiMessages.push({\n role: \"system\",\n content: systemPrompt,\n });\n }\n\n // Convert messages\n for (const msg of messages) {\n if (msg.role === \"user\") {\n openaiMessages.push({\n role: \"user\",\n content:\n typeof msg.content === \"string\"\n ? [{ type: \"text\", text: msg.content }]\n : msg.content.map((item) => {\n if (item.type === \"text\") {\n return { type: \"text\", text: item.text };\n } else {\n return {\n type: \"image_url\",\n image_url: { url: item.url || \"\" },\n };\n }\n }),\n });\n } else if (msg.role === \"assistant\") {\n openaiMessages.push({\n role: \"assistant\",\n content: msg.content ? [{ type: \"text\", text: msg.content }] : [],\n tool_calls: msg.toolCalls?.map((tc: ToolCall) => ({\n id: tc.id,\n type: \"function\" as const,\n function: {\n name: tc.function.name,\n arguments: tc.function.arguments,\n },\n })),\n });\n } else if (msg.role === \"tool\") {\n openaiMessages.push({\n role: \"tool\",\n tool_call_id: msg.toolCallId,\n content: msg.content ? [{ type: \"text\", text: msg.content }] : [],\n });\n }\n }\n\n return openaiMessages;\n}\n","/**\n * 将小驼峰字符串转换为下划线格式\n * 例如: \"userName\" -> \"user_name\"\n */\nfunction camelToSnake(str: string): string {\n return str.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`);\n}\n\n/**\n * 递归地将对象的所有小驼峰属性名转换为下划线格式\n */\nexport function camelToSnakeKeys<T>(obj: T): T {\n if (obj === null || obj === undefined) {\n return obj;\n }\n\n if (Array.isArray(obj)) {\n return obj.map((item) => camelToSnakeKeys(item)) as T;\n }\n\n if (typeof obj === \"object\") {\n const result: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(obj)) {\n const snakeKey = camelToSnake(key);\n result[snakeKey] = camelToSnakeKeys(value);\n }\n return result as T;\n }\n\n return obj;\n}\n\nexport function genRandomStr(length: number): string {\n const chars = \"abcdefghijklmnopqrstuvwxyz0123456789\";\n let result = \"\";\n for (let i = 0; i < length; i++) {\n result += chars.charAt(Math.floor(Math.random() * chars.length));\n }\n return result;\n}\n","import OpenAI from \"openai\";\nimport { EventType } from \"@ag-ui/client\";\n\nexport interface StreamContext {\n threadId: string;\n runId: string;\n messageId: string;\n}\n\nexport interface StreamState {\n hasStarted: boolean;\n fullContent: string;\n toolCallsMap: Map<string, { name: string; args: string }>;\n}\n\nexport type Delta =\n OpenAI.Chat.Completions.ChatCompletionChunk[\"choices\"][number][\"delta\"] & {\n reasoning_content?: string;\n };\n\nexport async function* processYuanqiStream(\n stream: AsyncIterable<OpenAI.Chat.Completions.ChatCompletionChunk>,\n context: StreamContext\n) {\n const { threadId, runId, messageId } = context;\n const state: StreamState = {\n hasStarted: false,\n fullContent: \"\",\n toolCallsMap: new Map(),\n };\n const reasoningState: StreamState = {\n hasStarted: false,\n fullContent: \"\",\n toolCallsMap: new Map(),\n };\n\n for await (const chunk of stream) {\n const delta = chunk.choices[0]?.delta as Delta;\n if (!delta) continue;\n\n if (delta.role === \"tool\") {\n const toolCallId = (delta as any).tool_call_id;\n if (toolCallId) {\n if (state.toolCallsMap.has(toolCallId)) {\n yield {\n type: EventType.TOOL_CALL_END,\n threadId,\n runId,\n toolCallId,\n };\n state.toolCallsMap.delete(toolCallId);\n }\n yield {\n type: EventType.TOOL_CALL_RESULT,\n threadId,\n runId,\n toolCallId,\n content: delta.content || \"\",\n };\n }\n continue;\n }\n\n // Handle text content\n if (delta.content) {\n // End reasoning message if it was started\n if (reasoningState.hasStarted) {\n reasoningState.hasStarted = false;\n yield {\n type: EventType.THINKING_TEXT_MESSAGE_END,\n threadId,\n runId,\n messageId,\n };\n yield {\n type: EventType.THINKING_END,\n threadId,\n runId,\n messageId,\n };\n }\n\n if (!state.hasStarted) {\n yield {\n type: EventType.TEXT_MESSAGE_START,\n threadId,\n runId,\n messageId,\n role: \"assistant\",\n };\n state.hasStarted = true;\n }\n\n state.fullContent += delta.content;\n yield {\n type: EventType.TEXT_MESSAGE_CONTENT,\n threadId,\n runId,\n messageId,\n delta: delta.content,\n };\n }\n\n // Handle reasoning content\n if (delta.reasoning_content) {\n if (!reasoningState.hasStarted) {\n yield {\n type: EventType.THINKING_START,\n threadId,\n runId,\n messageId,\n };\n yield {\n type: EventType.THINKING_TEXT_MESSAGE_START,\n threadId,\n runId,\n messageId,\n role: \"assistant\",\n };\n reasoningState.hasStarted = true;\n }\n\n reasoningState.fullContent += delta.reasoning_content;\n yield {\n type: EventType.THINKING_TEXT_MESSAGE_CONTENT,\n threadId,\n runId,\n messageId,\n delta: delta.reasoning_content,\n };\n }\n\n // Handle tool calls\n if (delta.tool_calls) {\n for (const toolCall of delta.tool_calls) {\n const toolCallId = toolCall.id || `tool_${toolCall.index}`;\n\n if (toolCall.function?.name) {\n // Tool call start\n yield {\n type: EventType.TOOL_CALL_START,\n threadId,\n runId,\n toolCallId,\n toolCallName: toolCall.function.name,\n };\n\n // If first chunk contains arguments, emit TOOL_CALL_ARGS event\n if (toolCall.function.arguments) {\n yield {\n type: EventType.TOOL_CALL_ARGS,\n threadId,\n runId,\n toolCallId,\n delta: toolCall.function.arguments,\n };\n }\n\n state.toolCallsMap.set(toolCallId, {\n name: toolCall.function.name,\n args: toolCall.function.arguments || \"\",\n });\n } else if (toolCall.function?.arguments) {\n // Tool call arguments delta\n const existing = state.toolCallsMap.get(toolCallId);\n if (existing) {\n existing.args += toolCall.function.arguments;\n\n yield {\n type: EventType.TOOL_CALL_ARGS,\n threadId,\n runId,\n toolCallId,\n delta: toolCall.function.arguments,\n };\n }\n }\n }\n }\n }\n\n // Emit TEXT_MESSAGE_END if we had text content\n if (state.hasStarted) {\n yield {\n type: EventType.TEXT_MESSAGE_END,\n threadId,\n runId,\n messageId,\n };\n }\n\n if (reasoningState.hasStarted) {\n yield {\n type: EventType.THINKING_TEXT_MESSAGE_END,\n threadId,\n runId,\n messageId,\n };\n yield {\n type: EventType.THINKING_END,\n threadId,\n runId,\n messageId,\n };\n }\n\n // Emit TOOL_CALL_END for all tool calls\n for (const [toolCallId] of state.toolCallsMap) {\n yield {\n type: EventType.TOOL_CALL_END,\n threadId,\n runId,\n toolCallId,\n };\n }\n}\n","// 对话数据模型\nexport const CHAT_HISTORY_DATA_SOURCE = \"ai_bot_chat_history_5hobd2b\";\n","import tcb from \"@cloudbase/node-sdk\";\nimport { CHAT_HISTORY_DATA_SOURCE } from \"./constant\";\nimport { genRandomStr } from \"./utils\";\n\nfunction genRecordId(): string {\n return \"record-\" + genRandomStr(8);\n}\n\n// Create a new chat history record\nexport async function createChatHistory({\n tcbClient,\n chatHistoryEntity,\n}: {\n tcbClient: tcb.CloudBase;\n chatHistoryEntity: ChatHistoryEntity;\n}): Promise<string | undefined> {\n try {\n const recordId = chatHistoryEntity.recordId || genRecordId();\n const data = {\n record_id: recordId,\n bot_id: chatHistoryEntity.botId,\n role: chatHistoryEntity.role,\n content: chatHistoryEntity.content,\n sender: chatHistoryEntity.sender,\n conversation: chatHistoryEntity.conversation,\n type: chatHistoryEntity.type,\n image: chatHistoryEntity.image,\n trigger_src: chatHistoryEntity.triggerSrc,\n origin_msg: chatHistoryEntity.originMsg,\n reply_to: chatHistoryEntity.replyTo,\n reply: chatHistoryEntity.reply,\n trace_id: chatHistoryEntity.traceId,\n need_async_reply: chatHistoryEntity.needAsyncReply,\n async_reply: chatHistoryEntity.asyncReply,\n createdAt: Date.now(),\n updatedAt: Date.now(),\n };\n\n const db = tcbClient.database();\n const collection = db.collection(CHAT_HISTORY_DATA_SOURCE);\n const result = await collection.add(data);\n\n // console.log(\n // `Create record: chatHistoryEntity:${JSON.stringify(\n // chatHistoryEntity\n // )}, result: ${JSON.stringify(result)}`\n // );\n return recordId;\n } catch (error) {\n console.error(\"Failed to create chat history record, error:\", error);\n return undefined;\n }\n}\n\n// Update chat history by record ID\nexport async function updateChatHistoryByRecordId({\n tcbClient,\n recordId,\n chatHistoryEntity,\n}: {\n tcbClient: tcb.CloudBase;\n recordId: string;\n chatHistoryEntity: ChatHistoryEntity;\n}): Promise<string | undefined> {\n try {\n const db = tcbClient.database();\n const _ = db.command;\n const collection = db.collection(CHAT_HISTORY_DATA_SOURCE);\n\n const result = await collection\n .where({ record_id: _.eq(recordId) })\n .update({\n content: chatHistoryEntity.content,\n image: chatHistoryEntity.image,\n async_reply: chatHistoryEntity.asyncReply,\n recommend_questions: chatHistoryEntity.recommendQuestions,\n status: chatHistoryEntity.status,\n origin_msg: chatHistoryEntity.originMsg,\n updatedAt: Date.now(),\n });\n\n // console.log(\n // `Update record: recordId: ${recordId}, chatHistoryEntity:${JSON.stringify(\n // chatHistoryEntity\n // )}, result: ${JSON.stringify(result)}`\n // );\n return chatHistoryEntity.recordId;\n } catch (error) {\n console.error(\"Failed to update chat history, error:\", error);\n return undefined;\n }\n}\n\n// Query chat history from database\nexport async function describeChatHistory({\n tcbClient,\n botId,\n sort,\n pageSize = 10,\n pageNumber = 1,\n conversation,\n startCreatedAt,\n triggerSrc,\n}: {\n tcbClient: tcb.CloudBase;\n botId: string;\n sort: \"asc\" | \"desc\";\n pageSize?: number;\n pageNumber?: number;\n conversation?: string;\n startCreatedAt?: number;\n triggerSrc?: string;\n}): Promise<[ChatHistoryEntity[], number]> {\n if (!sort || sort.length === 0) {\n sort = \"desc\";\n }\n\n try {\n const db = tcbClient.database();\n const _ = db.command;\n const collection = db.collection(CHAT_HISTORY_DATA_SOURCE);\n\n // Build where conditions\n const whereConditions: Record<string, unknown> = {\n bot_id: _.eq(botId),\n };\n\n // Add optional filters\n if (conversation) {\n whereConditions.conversation = _.eq(conversation);\n }\n\n if (startCreatedAt !== undefined) {\n whereConditions.createdAt = _.gt(startCreatedAt);\n }\n\n if (triggerSrc) {\n whereConditions.trigger_src = _.eq(triggerSrc);\n }\n\n // Calculate skip for pagination\n const skip = (pageNumber - 1) * pageSize;\n\n // Query records\n const result = await collection\n .where(whereConditions)\n .orderBy(\"createdAt\", sort)\n .skip(skip)\n .limit(pageSize)\n .get();\n\n // Get total count\n const countResult = await collection.where(whereConditions).count();\n const total = countResult.total || 0;\n\n const records = result?.data || [];\n\n const entityList: ChatHistoryEntity[] = records.map(\n (item: ChatHistoryData) => transDataToChatEntity(item)\n );\n\n return [entityList, total];\n } catch (error) {\n console.error(\"Failed to query chat history, error:\", error);\n return [[], 0];\n }\n}\n\n// Transform data to ChatHistoryEntity structure\nexport function transDataToChatEntity(\n item: ChatHistoryData\n): ChatHistoryEntity {\n if (!item) {\n return new ChatHistoryEntity();\n }\n const chatEntity: ChatHistoryEntity = new ChatHistoryEntity();\n chatEntity.botId = item.bot_id;\n chatEntity.recordId = item.record_id;\n chatEntity.role = item.role;\n chatEntity.status = item.status;\n chatEntity.content = item.content;\n chatEntity.sender = item.sender;\n chatEntity.conversation = item.conversation;\n chatEntity.type = item.type;\n chatEntity.triggerSrc = item.trigger_src;\n chatEntity.originMsg = item.origin_msg;\n chatEntity.replyTo = item.reply_to;\n chatEntity.reply = item.reply;\n chatEntity.traceId = item.trace_id;\n chatEntity.needAsyncReply = item.need_async_reply;\n chatEntity.asyncReply = item.async_reply;\n chatEntity.createdAt = item.createdAt;\n chatEntity.updatedAt = item.updatedAt;\n return chatEntity;\n}\n\n// Query history records for LLM, get the most recent 10 conversation pairs (20 records)\nexport async function queryForLLM({\n tcbClient,\n botId,\n pageSize = 10,\n startCreatedAt,\n triggerSrc,\n}: {\n tcbClient: tcb.CloudBase;\n botId: string;\n pageSize?: number;\n startCreatedAt?: number;\n triggerSrc?: string;\n}): Promise<{ role: string; content: string }[]> {\n if (startCreatedAt === undefined) {\n startCreatedAt = Date.now() - 24 * 60 * 60 * 1000;\n }\n const recordEntityList: ChatHistoryEntity[] = [];\n\n const [recordList] = await describeChatHistory({\n tcbClient,\n botId,\n sort: \"desc\",\n pageSize,\n startCreatedAt,\n triggerSrc,\n });\n recordEntityList.push(...recordList.reverse());\n\n const entityMap = new Map<string, ChatHistoryEntity>();\n recordEntityList\n .filter((item) => {\n if (item.needAsyncReply === true) {\n return !!item.asyncReply;\n } else {\n return !!item.content;\n }\n })\n .forEach((item) => {\n entityMap.set(item.recordId, item);\n });\n\n const result: { role: string; content: string }[] = [];\n /*\n 1. Strongly depends on database history data, model history data has role order requirements\n 2. Need to ensure that no matter what bug occurs, always get a complete and usable user + assistant pair, otherwise the request will fail\n */\n recordEntityList.forEach((item) => {\n const { role, content, reply } = item;\n // When calling LLM, empty content will cause failure, so filter out conversations with empty content\n if (role === \"user\" && content?.length !== 0) {\n if (entityMap.has(reply)) {\n result.push({ role, content });\n result.push({\n role: entityMap.get(reply)!.role,\n content: entityMap.get(reply)!.content,\n });\n }\n }\n });\n if (result.length % 2 === 1) {\n result.splice(-1, 1);\n }\n return result;\n}\n\nexport interface ChatHistoryData {\n bot_id: string;\n record_id: string;\n role: string;\n status: string;\n content: string;\n sender: string;\n conversation: string;\n type: string;\n trigger_src: string;\n origin_msg: string;\n reply_to: string;\n reply: string;\n trace_id: string;\n need_async_reply: boolean;\n async_reply: string;\n createdAt: number;\n updatedAt: number;\n}\n\nexport class ChatHistoryEntity {\n id: number;\n botId: string;\n // 对话唯一id\n recordId: string;\n role: string;\n content: string;\n recommendQuestions: string[];\n sender: string;\n conversation: string;\n type: string;\n /**\n * 消息状态,pending done error cancel\n */\n status: string;\n image: string;\n triggerSrc: string;\n originMsg: string;\n replyTo: string;\n reply: string;\n traceId: string;\n needAsyncReply: boolean;\n asyncReply: string;\n createTime: string;\n updateTime: string;\n createdAt: number;\n updatedAt: number;\n event: string;\n}\n"],"mappings":"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","names":["EventType","EventType"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cloudbase/agent-adapter-yuanqi",
3
- "version": "1.0.1-alpha.23",
3
+ "version": "1.0.1-alpha.25",
4
4
  "description": "Tencent Yuanqi adapter for AG-Kit agents",
5
5
  "files": [
6
6
  "dist/",