@cloudbase/agent-adapter-yuanqi 0.0.16 → 0.0.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +243 -9
- package/dist/index.d.mts +187 -8
- package/dist/index.d.ts +187 -8
- package/dist/index.js +476 -27
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +467 -25
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -2
package/dist/index.js
CHANGED
|
@@ -30,14 +30,23 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
30
30
|
// src/index.ts
|
|
31
31
|
var index_exports = {};
|
|
32
32
|
__export(index_exports, {
|
|
33
|
+
ChatHistoryEntity: () => ChatHistoryEntity,
|
|
33
34
|
YuanqiAgent: () => YuanqiAgent,
|
|
34
|
-
|
|
35
|
-
convertMessagesToOpenAI: () => convertMessagesToOpenAI
|
|
35
|
+
YuanqiAgentError: () => YuanqiAgentError,
|
|
36
|
+
convertMessagesToOpenAI: () => convertMessagesToOpenAI,
|
|
37
|
+
createChatHistory: () => createChatHistory,
|
|
38
|
+
describeChatHistory: () => describeChatHistory,
|
|
39
|
+
processYuanqiStream: () => processYuanqiStream,
|
|
40
|
+
queryForLLM: () => queryForLLM,
|
|
41
|
+
transDataToChatEntity: () => transDataToChatEntity,
|
|
42
|
+
updateChatHistoryByRecordId: () => updateChatHistoryByRecordId
|
|
36
43
|
});
|
|
37
44
|
module.exports = __toCommonJS(index_exports);
|
|
38
45
|
|
|
39
46
|
// src/agent.ts
|
|
40
47
|
var import_client2 = require("@ag-ui/client");
|
|
48
|
+
var import_node_sdk = __toESM(require("@cloudbase/node-sdk"));
|
|
49
|
+
var import_manager_node = __toESM(require("@cloudbase/manager-node"));
|
|
41
50
|
var import_openai = __toESM(require("openai"));
|
|
42
51
|
var import_crypto = require("crypto");
|
|
43
52
|
|
|
@@ -62,6 +71,14 @@ function camelToSnakeKeys(obj) {
|
|
|
62
71
|
}
|
|
63
72
|
return obj;
|
|
64
73
|
}
|
|
74
|
+
function genRandomStr(length) {
|
|
75
|
+
const chars = "abcdefghijklmnopqrstuvwxyz0123456789";
|
|
76
|
+
let result = "";
|
|
77
|
+
for (let i = 0; i < length; i++) {
|
|
78
|
+
result += chars.charAt(Math.floor(Math.random() * chars.length));
|
|
79
|
+
}
|
|
80
|
+
return result;
|
|
81
|
+
}
|
|
65
82
|
|
|
66
83
|
// src/stream.ts
|
|
67
84
|
var import_client = require("@ag-ui/client");
|
|
@@ -80,6 +97,28 @@ async function* processYuanqiStream(stream, context) {
|
|
|
80
97
|
for await (const chunk of stream) {
|
|
81
98
|
const delta = chunk.choices[0]?.delta;
|
|
82
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
|
+
}
|
|
83
122
|
if (delta.content) {
|
|
84
123
|
if (reasoningState.hasStarted) {
|
|
85
124
|
reasoningState.hasStarted = false;
|
|
@@ -152,6 +191,15 @@ async function* processYuanqiStream(stream, context) {
|
|
|
152
191
|
toolCallId,
|
|
153
192
|
toolCallName: toolCall.function.name
|
|
154
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
|
+
}
|
|
155
203
|
state.toolCallsMap.set(toolCallId, {
|
|
156
204
|
name: toolCall.function.name,
|
|
157
205
|
args: toolCall.function.arguments || ""
|
|
@@ -180,6 +228,20 @@ async function* processYuanqiStream(stream, context) {
|
|
|
180
228
|
messageId
|
|
181
229
|
};
|
|
182
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
|
+
}
|
|
183
245
|
for (const [toolCallId] of state.toolCallsMap) {
|
|
184
246
|
yield {
|
|
185
247
|
type: import_client.EventType.TOOL_CALL_END,
|
|
@@ -188,24 +250,217 @@ async function* processYuanqiStream(stream, context) {
|
|
|
188
250
|
toolCallId
|
|
189
251
|
};
|
|
190
252
|
}
|
|
191
|
-
yield {
|
|
192
|
-
type: import_client.EventType.RUN_FINISHED,
|
|
193
|
-
threadId,
|
|
194
|
-
runId
|
|
195
|
-
};
|
|
196
253
|
}
|
|
197
254
|
|
|
198
255
|
// src/agent.ts
|
|
199
256
|
var import_rxjs = require("rxjs");
|
|
257
|
+
|
|
258
|
+
// src/constant.ts
|
|
259
|
+
var CHAT_HISTORY_DATA_SOURCE = "ai_bot_chat_history_5hobd2b";
|
|
260
|
+
|
|
261
|
+
// src/chat_history.ts
|
|
262
|
+
function genRecordId() {
|
|
263
|
+
return "record-" + genRandomStr(8);
|
|
264
|
+
}
|
|
265
|
+
async function createChatHistory({
|
|
266
|
+
tcbClient,
|
|
267
|
+
chatHistoryEntity
|
|
268
|
+
}) {
|
|
269
|
+
try {
|
|
270
|
+
const recordId = chatHistoryEntity.recordId || genRecordId();
|
|
271
|
+
const data = {
|
|
272
|
+
record_id: recordId,
|
|
273
|
+
bot_id: chatHistoryEntity.botId,
|
|
274
|
+
role: chatHistoryEntity.role,
|
|
275
|
+
content: chatHistoryEntity.content,
|
|
276
|
+
sender: chatHistoryEntity.sender,
|
|
277
|
+
conversation: chatHistoryEntity.conversation,
|
|
278
|
+
type: chatHistoryEntity.type,
|
|
279
|
+
image: chatHistoryEntity.image,
|
|
280
|
+
trigger_src: chatHistoryEntity.triggerSrc,
|
|
281
|
+
origin_msg: chatHistoryEntity.originMsg,
|
|
282
|
+
reply_to: chatHistoryEntity.replyTo,
|
|
283
|
+
reply: chatHistoryEntity.reply,
|
|
284
|
+
trace_id: chatHistoryEntity.traceId,
|
|
285
|
+
need_async_reply: chatHistoryEntity.needAsyncReply,
|
|
286
|
+
async_reply: chatHistoryEntity.asyncReply,
|
|
287
|
+
createdAt: Date.now(),
|
|
288
|
+
updatedAt: Date.now()
|
|
289
|
+
};
|
|
290
|
+
const db = tcbClient.database();
|
|
291
|
+
const collection = db.collection(CHAT_HISTORY_DATA_SOURCE);
|
|
292
|
+
const result = await collection.add(data);
|
|
293
|
+
return recordId;
|
|
294
|
+
} catch (error) {
|
|
295
|
+
console.error("Failed to create chat history record, error:", error);
|
|
296
|
+
return void 0;
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
async function updateChatHistoryByRecordId({
|
|
300
|
+
tcbClient,
|
|
301
|
+
recordId,
|
|
302
|
+
chatHistoryEntity
|
|
303
|
+
}) {
|
|
304
|
+
try {
|
|
305
|
+
const db = tcbClient.database();
|
|
306
|
+
const _ = db.command;
|
|
307
|
+
const collection = db.collection(CHAT_HISTORY_DATA_SOURCE);
|
|
308
|
+
const result = await collection.where({ record_id: _.eq(recordId) }).update({
|
|
309
|
+
content: chatHistoryEntity.content,
|
|
310
|
+
image: chatHistoryEntity.image,
|
|
311
|
+
async_reply: chatHistoryEntity.asyncReply,
|
|
312
|
+
recommend_questions: chatHistoryEntity.recommendQuestions,
|
|
313
|
+
status: chatHistoryEntity.status,
|
|
314
|
+
origin_msg: chatHistoryEntity.originMsg,
|
|
315
|
+
updatedAt: Date.now()
|
|
316
|
+
});
|
|
317
|
+
return chatHistoryEntity.recordId;
|
|
318
|
+
} catch (error) {
|
|
319
|
+
console.error("Failed to update chat history, error:", error);
|
|
320
|
+
return void 0;
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
async function describeChatHistory({
|
|
324
|
+
tcbClient,
|
|
325
|
+
botId,
|
|
326
|
+
sort,
|
|
327
|
+
pageSize = 10,
|
|
328
|
+
pageNumber = 1,
|
|
329
|
+
conversation,
|
|
330
|
+
startCreatedAt,
|
|
331
|
+
triggerSrc
|
|
332
|
+
}) {
|
|
333
|
+
if (!sort || sort.length === 0) {
|
|
334
|
+
sort = "desc";
|
|
335
|
+
}
|
|
336
|
+
try {
|
|
337
|
+
const db = tcbClient.database();
|
|
338
|
+
const _ = db.command;
|
|
339
|
+
const collection = db.collection(CHAT_HISTORY_DATA_SOURCE);
|
|
340
|
+
const whereConditions = {
|
|
341
|
+
bot_id: _.eq(botId)
|
|
342
|
+
};
|
|
343
|
+
if (conversation) {
|
|
344
|
+
whereConditions.conversation = _.eq(conversation);
|
|
345
|
+
}
|
|
346
|
+
if (startCreatedAt !== void 0) {
|
|
347
|
+
whereConditions.createdAt = _.gt(startCreatedAt);
|
|
348
|
+
}
|
|
349
|
+
if (triggerSrc) {
|
|
350
|
+
whereConditions.trigger_src = _.eq(triggerSrc);
|
|
351
|
+
}
|
|
352
|
+
const skip = (pageNumber - 1) * pageSize;
|
|
353
|
+
const result = await collection.where(whereConditions).orderBy("createdAt", sort).skip(skip).limit(pageSize).get();
|
|
354
|
+
const countResult = await collection.where(whereConditions).count();
|
|
355
|
+
const total = countResult.total || 0;
|
|
356
|
+
const records = result?.data || [];
|
|
357
|
+
const entityList = records.map(
|
|
358
|
+
(item) => transDataToChatEntity(item)
|
|
359
|
+
);
|
|
360
|
+
return [entityList, total];
|
|
361
|
+
} catch (error) {
|
|
362
|
+
console.error("Failed to query chat history, error:", error);
|
|
363
|
+
return [[], 0];
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
function transDataToChatEntity(item) {
|
|
367
|
+
if (!item) {
|
|
368
|
+
return new ChatHistoryEntity();
|
|
369
|
+
}
|
|
370
|
+
const chatEntity = new ChatHistoryEntity();
|
|
371
|
+
chatEntity.botId = item.bot_id;
|
|
372
|
+
chatEntity.recordId = item.record_id;
|
|
373
|
+
chatEntity.role = item.role;
|
|
374
|
+
chatEntity.status = item.status;
|
|
375
|
+
chatEntity.content = item.content;
|
|
376
|
+
chatEntity.sender = item.sender;
|
|
377
|
+
chatEntity.conversation = item.conversation;
|
|
378
|
+
chatEntity.type = item.type;
|
|
379
|
+
chatEntity.triggerSrc = item.trigger_src;
|
|
380
|
+
chatEntity.originMsg = item.origin_msg;
|
|
381
|
+
chatEntity.replyTo = item.reply_to;
|
|
382
|
+
chatEntity.reply = item.reply;
|
|
383
|
+
chatEntity.traceId = item.trace_id;
|
|
384
|
+
chatEntity.needAsyncReply = item.need_async_reply;
|
|
385
|
+
chatEntity.asyncReply = item.async_reply;
|
|
386
|
+
chatEntity.createdAt = item.createdAt;
|
|
387
|
+
chatEntity.updatedAt = item.updatedAt;
|
|
388
|
+
return chatEntity;
|
|
389
|
+
}
|
|
390
|
+
async function queryForLLM({
|
|
391
|
+
tcbClient,
|
|
392
|
+
botId,
|
|
393
|
+
pageSize = 10,
|
|
394
|
+
startCreatedAt,
|
|
395
|
+
triggerSrc
|
|
396
|
+
}) {
|
|
397
|
+
if (startCreatedAt === void 0) {
|
|
398
|
+
startCreatedAt = Date.now() - 24 * 60 * 60 * 1e3;
|
|
399
|
+
}
|
|
400
|
+
const recordEntityList = [];
|
|
401
|
+
const [recordList] = await describeChatHistory({
|
|
402
|
+
tcbClient,
|
|
403
|
+
botId,
|
|
404
|
+
sort: "desc",
|
|
405
|
+
pageSize,
|
|
406
|
+
startCreatedAt,
|
|
407
|
+
triggerSrc
|
|
408
|
+
});
|
|
409
|
+
recordEntityList.push(...recordList.reverse());
|
|
410
|
+
const entityMap = /* @__PURE__ */ new Map();
|
|
411
|
+
recordEntityList.filter((item) => {
|
|
412
|
+
if (item.needAsyncReply === true) {
|
|
413
|
+
return !!item.asyncReply;
|
|
414
|
+
} else {
|
|
415
|
+
return !!item.content;
|
|
416
|
+
}
|
|
417
|
+
}).forEach((item) => {
|
|
418
|
+
entityMap.set(item.recordId, item);
|
|
419
|
+
});
|
|
420
|
+
const result = [];
|
|
421
|
+
recordEntityList.forEach((item) => {
|
|
422
|
+
const { role, content, reply } = item;
|
|
423
|
+
if (role === "user" && content?.length !== 0) {
|
|
424
|
+
if (entityMap.has(reply)) {
|
|
425
|
+
result.push({ role, content });
|
|
426
|
+
result.push({
|
|
427
|
+
role: entityMap.get(reply).role,
|
|
428
|
+
content: entityMap.get(reply).content
|
|
429
|
+
});
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
});
|
|
433
|
+
if (result.length % 2 === 1) {
|
|
434
|
+
result.splice(-1, 1);
|
|
435
|
+
}
|
|
436
|
+
return result;
|
|
437
|
+
}
|
|
438
|
+
var ChatHistoryEntity = class {
|
|
439
|
+
};
|
|
440
|
+
|
|
441
|
+
// src/agent.ts
|
|
442
|
+
var YuanqiAgentError = class extends Error {
|
|
443
|
+
constructor(message, code) {
|
|
444
|
+
super(message);
|
|
445
|
+
this.name = "YuanqiAgentError";
|
|
446
|
+
if (code) this.code = code;
|
|
447
|
+
}
|
|
448
|
+
};
|
|
200
449
|
var YuanqiAgent = class extends import_client2.AbstractAgent {
|
|
201
450
|
constructor(config) {
|
|
202
451
|
super(config);
|
|
452
|
+
this.finalCloudCredential = {};
|
|
203
453
|
this.yuanqiConfig = config.yuanqiConfig;
|
|
204
454
|
this.model = new import_openai.default({
|
|
205
455
|
apiKey: "",
|
|
206
456
|
baseURL: this.yuanqiConfig.request?.baseUrl || "https://yuanqi.tencent.com/openapi/v1/agent"
|
|
207
457
|
});
|
|
208
458
|
this.finalAppId = this.yuanqiConfig.appId || this.yuanqiConfig.request?.body?.assistantId || process.env.YUANQI_APP_ID || "";
|
|
459
|
+
this.finalCloudCredential = {
|
|
460
|
+
secretId: this.yuanqiConfig.credential?.secretId || process.env.TENCENTCLOUD_SECRETID,
|
|
461
|
+
secretKey: this.yuanqiConfig.credential?.secretKey || process.env.TENCENTCLOUD_SECRETKEY,
|
|
462
|
+
token: this.yuanqiConfig.credential?.token || process.env.TENCENTCLOUD_SESSIONTOKEN
|
|
463
|
+
};
|
|
209
464
|
}
|
|
210
465
|
generateRequestBody({
|
|
211
466
|
messages,
|
|
@@ -229,27 +484,49 @@ var YuanqiAgent = class extends import_client2.AbstractAgent {
|
|
|
229
484
|
}
|
|
230
485
|
async _run(subscriber, input) {
|
|
231
486
|
try {
|
|
232
|
-
const { messages, runId
|
|
233
|
-
const
|
|
487
|
+
const { messages, runId } = input;
|
|
488
|
+
const openai = this.model;
|
|
489
|
+
const threadId = input.threadId || (0, import_crypto.randomUUID)();
|
|
234
490
|
subscriber.next({
|
|
235
491
|
type: import_client2.EventType.RUN_STARTED,
|
|
236
492
|
threadId,
|
|
237
493
|
runId
|
|
238
494
|
});
|
|
239
495
|
if (!this.finalAppId) {
|
|
240
|
-
throw new
|
|
241
|
-
"YUANQI_APP_ID is required, check your env variables or config passed with the adapter"
|
|
496
|
+
throw new YuanqiAgentError(
|
|
497
|
+
"YUANQI_APP_ID is required, check your env variables or config passed with the adapter",
|
|
498
|
+
"MISSING_YUANQI_APP_ID"
|
|
242
499
|
);
|
|
243
500
|
}
|
|
244
501
|
if (!this.yuanqiConfig.appKey && !process.env.YUANQI_APP_KEY) {
|
|
245
|
-
throw new
|
|
246
|
-
"YUANQI_APP_KEY is required, check your env variables or config passed with the adapter"
|
|
502
|
+
throw new YuanqiAgentError(
|
|
503
|
+
"YUANQI_APP_KEY is required, check your env variables or config passed with the adapter",
|
|
504
|
+
"MISSING_YUANQI_APP_KEY"
|
|
247
505
|
);
|
|
248
506
|
}
|
|
249
|
-
const
|
|
250
|
-
|
|
507
|
+
const trimmedCount = messages.length - 1;
|
|
508
|
+
if (trimmedCount > 0) {
|
|
509
|
+
subscriber.next({
|
|
510
|
+
type: import_client2.EventType.RAW,
|
|
511
|
+
rawEvent: {
|
|
512
|
+
message: `Yuanqi handles message history itself, so that a total of ${trimmedCount} messages before the last user message will be trimmed.`,
|
|
513
|
+
type: "warn"
|
|
514
|
+
}
|
|
515
|
+
});
|
|
516
|
+
}
|
|
517
|
+
const latestUserMessage = messages.filter((m) => m.role === "user").pop();
|
|
518
|
+
if (!latestUserMessage) {
|
|
519
|
+
throw new YuanqiAgentError(
|
|
520
|
+
"No user message found, please send a message first.",
|
|
521
|
+
"MESSAGE_FORMAT_ERROR"
|
|
522
|
+
);
|
|
523
|
+
}
|
|
524
|
+
const allMessages = await this.getChatHistory(
|
|
525
|
+
subscriber,
|
|
526
|
+
latestUserMessage
|
|
527
|
+
);
|
|
251
528
|
const body = this.generateRequestBody({
|
|
252
|
-
messages:
|
|
529
|
+
messages: allMessages,
|
|
253
530
|
input
|
|
254
531
|
});
|
|
255
532
|
const stream = await openai.chat.completions.create(
|
|
@@ -266,27 +543,192 @@ var YuanqiAgent = class extends import_client2.AbstractAgent {
|
|
|
266
543
|
}
|
|
267
544
|
}
|
|
268
545
|
);
|
|
269
|
-
const
|
|
270
|
-
const
|
|
546
|
+
const userRecordId = `record-${(0, import_crypto.randomUUID)().slice(0, 8)}`;
|
|
547
|
+
const assistantRecordId = `record-${(0, import_crypto.randomUUID)().slice(0, 8)}`;
|
|
548
|
+
const context = { threadId, runId, messageId: userRecordId };
|
|
549
|
+
let fullAssistantContent = "";
|
|
271
550
|
for await (const event of processYuanqiStream(stream, context)) {
|
|
272
551
|
subscriber.next(event);
|
|
552
|
+
if (event.type === import_client2.EventType.TEXT_MESSAGE_CONTENT && event.delta) {
|
|
553
|
+
fullAssistantContent += event.delta;
|
|
554
|
+
}
|
|
273
555
|
}
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
556
|
+
const userContent = typeof latestUserMessage?.content === "string" ? latestUserMessage.content : latestUserMessage?.content?.filter((c) => c.type === "text").map((c) => c.text).join("") || "";
|
|
557
|
+
await this.saveChatHistory(
|
|
558
|
+
subscriber,
|
|
559
|
+
input,
|
|
560
|
+
userRecordId,
|
|
561
|
+
assistantRecordId,
|
|
562
|
+
userContent,
|
|
563
|
+
fullAssistantContent
|
|
564
|
+
);
|
|
565
|
+
subscriber.next({
|
|
566
|
+
type: import_client2.EventType.RUN_FINISHED,
|
|
567
|
+
threadId,
|
|
568
|
+
runId
|
|
569
|
+
});
|
|
570
|
+
} catch (e) {
|
|
571
|
+
console.error("[ERROR] Uncaught error: ", JSON.stringify(e));
|
|
572
|
+
let code = "UNKNOWN_ERROR";
|
|
573
|
+
let message = JSON.stringify(e);
|
|
574
|
+
if (e instanceof YuanqiAgentError) {
|
|
575
|
+
code = e.code || "AGENT_ERROR";
|
|
576
|
+
message = e.message;
|
|
577
|
+
} else if (e instanceof Error) {
|
|
578
|
+
code = e.name || "ERROR";
|
|
579
|
+
message = e.message;
|
|
279
580
|
}
|
|
280
581
|
subscriber.next({
|
|
281
582
|
type: import_client2.EventType.RUN_ERROR,
|
|
282
|
-
|
|
283
|
-
|
|
583
|
+
code,
|
|
584
|
+
message: `Sorry, an error occurred while running the agent: Error code ${code}, ${message}`
|
|
284
585
|
});
|
|
285
586
|
} finally {
|
|
286
587
|
subscriber.complete();
|
|
287
588
|
}
|
|
288
589
|
}
|
|
590
|
+
// Can be override by subclasses
|
|
591
|
+
async getChatHistory(subscriber, latestUserMessage) {
|
|
592
|
+
const botId = `bot-yuanqi-${this.finalAppId}`;
|
|
593
|
+
const tcbClient = this.getTcbClient();
|
|
594
|
+
const isDBReady = await this.checkIsDatabaseReady();
|
|
595
|
+
if (!isDBReady) {
|
|
596
|
+
subscriber.next({
|
|
597
|
+
type: import_client2.EventType.RAW,
|
|
598
|
+
rawEvent: {
|
|
599
|
+
message: `Chat history database is not ready, skip history loading.`,
|
|
600
|
+
type: "warn"
|
|
601
|
+
}
|
|
602
|
+
});
|
|
603
|
+
return convertMessagesToOpenAI([latestUserMessage]);
|
|
604
|
+
}
|
|
605
|
+
let historyMessages = [];
|
|
606
|
+
const historyCount = this.yuanqiConfig.historyCount ?? 10;
|
|
607
|
+
const historyRecords = await queryForLLM({
|
|
608
|
+
tcbClient,
|
|
609
|
+
botId,
|
|
610
|
+
pageSize: historyCount
|
|
611
|
+
});
|
|
612
|
+
historyMessages = historyRecords.map((record) => ({
|
|
613
|
+
role: record.role,
|
|
614
|
+
content: [{ type: "text", text: record.content }]
|
|
615
|
+
}));
|
|
616
|
+
const allMessages = historyMessages.concat(
|
|
617
|
+
convertMessagesToOpenAI([latestUserMessage])
|
|
618
|
+
);
|
|
619
|
+
return allMessages;
|
|
620
|
+
}
|
|
621
|
+
// Can be override by subclasses
|
|
622
|
+
async saveChatHistory(subscriber, input, userRecordId, assistantRecordId, userContent, assistantContent) {
|
|
623
|
+
const botId = `bot-yuanqi-${this.finalAppId}`;
|
|
624
|
+
const { threadId, runId } = input;
|
|
625
|
+
const tcbClient = this.getTcbClient();
|
|
626
|
+
const isDBReady = await this.checkIsDatabaseReady();
|
|
627
|
+
if (!isDBReady) {
|
|
628
|
+
subscriber.next({
|
|
629
|
+
type: import_client2.EventType.RAW,
|
|
630
|
+
rawEvent: {
|
|
631
|
+
message: `Chat history database is not ready, skip history saving.`,
|
|
632
|
+
type: "warn"
|
|
633
|
+
}
|
|
634
|
+
});
|
|
635
|
+
return;
|
|
636
|
+
}
|
|
637
|
+
const userEntity = new ChatHistoryEntity();
|
|
638
|
+
userEntity.recordId = userRecordId;
|
|
639
|
+
userEntity.botId = botId;
|
|
640
|
+
userEntity.role = "user";
|
|
641
|
+
userEntity.content = userContent;
|
|
642
|
+
userEntity.conversation = threadId;
|
|
643
|
+
userEntity.reply = assistantRecordId;
|
|
644
|
+
userEntity.triggerSrc = "";
|
|
645
|
+
userEntity.traceId = (0, import_crypto.randomUUID)();
|
|
646
|
+
await createChatHistory({ tcbClient, chatHistoryEntity: userEntity });
|
|
647
|
+
const assistantEntity = new ChatHistoryEntity();
|
|
648
|
+
assistantEntity.recordId = assistantRecordId;
|
|
649
|
+
assistantEntity.botId = botId;
|
|
650
|
+
assistantEntity.role = "assistant";
|
|
651
|
+
assistantEntity.content = assistantContent;
|
|
652
|
+
assistantEntity.conversation = threadId;
|
|
653
|
+
assistantEntity.replyTo = userRecordId;
|
|
654
|
+
assistantEntity.triggerSrc = "";
|
|
655
|
+
assistantEntity.traceId = runId;
|
|
656
|
+
assistantEntity.status = "done";
|
|
657
|
+
await createChatHistory({
|
|
658
|
+
tcbClient,
|
|
659
|
+
chatHistoryEntity: assistantEntity
|
|
660
|
+
});
|
|
661
|
+
}
|
|
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) {
|
|
676
|
+
throw new YuanqiAgentError(
|
|
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"
|
|
679
|
+
);
|
|
680
|
+
}
|
|
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
|
+
}
|
|
694
|
+
}
|
|
695
|
+
const managedTcbClient = import_manager_node.default.init({
|
|
696
|
+
envId,
|
|
697
|
+
secretId: this.finalCloudCredential.secretId,
|
|
698
|
+
secretKey: this.finalCloudCredential.secretKey,
|
|
699
|
+
token: this.finalCloudCredential.token
|
|
700
|
+
});
|
|
701
|
+
const checkDBRes = await managedTcbClient.database.checkCollectionExists(
|
|
702
|
+
CHAT_HISTORY_DATA_SOURCE
|
|
703
|
+
);
|
|
704
|
+
if (checkDBRes && checkDBRes.Exists) {
|
|
705
|
+
return true;
|
|
706
|
+
} else if (checkDBRes && !checkDBRes.Exists) {
|
|
707
|
+
await managedTcbClient.database.createCollection(
|
|
708
|
+
CHAT_HISTORY_DATA_SOURCE
|
|
709
|
+
);
|
|
710
|
+
return true;
|
|
711
|
+
} else {
|
|
712
|
+
throw new Error("Check database exists failed");
|
|
713
|
+
}
|
|
714
|
+
} catch (dbError) {
|
|
715
|
+
console.error(
|
|
716
|
+
"[ERROR] Failed to check/create chat history collection:",
|
|
717
|
+
JSON.stringify(dbError)
|
|
718
|
+
);
|
|
719
|
+
return false;
|
|
720
|
+
}
|
|
721
|
+
}
|
|
289
722
|
};
|
|
723
|
+
function getCloudbaseEnvId() {
|
|
724
|
+
if (process.env.CBR_ENV_ID) {
|
|
725
|
+
return process.env.CBR_ENV_ID;
|
|
726
|
+
} else if (process.env.SCF_NAMESPACE) {
|
|
727
|
+
return process.env.SCF_NAMESPACE;
|
|
728
|
+
} else {
|
|
729
|
+
return process.env.CLOUDBASE_ENV_ID || "";
|
|
730
|
+
}
|
|
731
|
+
}
|
|
290
732
|
function convertMessagesToOpenAI(messages, systemPrompt) {
|
|
291
733
|
const openaiMessages = [];
|
|
292
734
|
if (systemPrompt) {
|
|
@@ -335,8 +777,15 @@ function convertMessagesToOpenAI(messages, systemPrompt) {
|
|
|
335
777
|
}
|
|
336
778
|
// Annotate the CommonJS export names for ESM import in node:
|
|
337
779
|
0 && (module.exports = {
|
|
780
|
+
ChatHistoryEntity,
|
|
338
781
|
YuanqiAgent,
|
|
339
|
-
|
|
340
|
-
convertMessagesToOpenAI
|
|
782
|
+
YuanqiAgentError,
|
|
783
|
+
convertMessagesToOpenAI,
|
|
784
|
+
createChatHistory,
|
|
785
|
+
describeChatHistory,
|
|
786
|
+
processYuanqiStream,
|
|
787
|
+
queryForLLM,
|
|
788
|
+
transDataToChatEntity,
|
|
789
|
+
updateChatHistoryByRecordId
|
|
341
790
|
});
|
|
342
791
|
//# sourceMappingURL=index.js.map
|