tmp
This commit is contained in:
+49
-31
@@ -1,8 +1,10 @@
|
||||
import 'dotenv/config';
|
||||
import { createDeepAgent, FilesystemBackend } from "deepagents";
|
||||
import { AIMessageChunk, ToolMessage } from "langchain";
|
||||
import { SystemMessage, HumanMessage, AIMessage } from "@langchain/core/messages";
|
||||
import { HumanMessage } from "@langchain/core/messages";
|
||||
import { ChatDeepSeek } from "@langchain/deepseek";
|
||||
import config from '../../conf.json' with { type: 'json' };
|
||||
import logger from '../../utils/logger.js';
|
||||
import EscortAdminPrompts from "./prompts.js";
|
||||
import {
|
||||
getEnvTool, webFetchTool, webSearchTool, getCalendarInfoTool,
|
||||
@@ -12,10 +14,14 @@ import {
|
||||
|
||||
export default class EscortAdminAgent {
|
||||
constructor() {
|
||||
// 按用户隔离会话:userId -> { agent, messages }
|
||||
this.sessions = new Map();
|
||||
this.maxSessions = 100;
|
||||
}
|
||||
|
||||
clearMessages() {
|
||||
this.messages = [];
|
||||
clearMessages(userInfo) {
|
||||
const userId = userInfo?._id ?? 'default-session';
|
||||
this.sessions.delete(userId);
|
||||
}
|
||||
|
||||
// msg: { agent: 'escort-admin', type: 'chat', ts: "2023-08-01 10:00:00", content: "你好" }
|
||||
@@ -24,27 +30,47 @@ export default class EscortAdminAgent {
|
||||
return;
|
||||
}
|
||||
|
||||
const agent = this._genAgent(userInfo);
|
||||
const userId = userInfo?._id ?? 'default-session';
|
||||
|
||||
// LRU:按用户取会话,并更新使用顺序
|
||||
let session = this.sessions.get(userId);
|
||||
if (session) {
|
||||
this.sessions.delete(userId);
|
||||
} else {
|
||||
session = { agent: null, messages: [] };
|
||||
}
|
||||
this.sessions.set(userId, session);
|
||||
|
||||
// 超出上限时淘汰最久未使用的会话,避免内存泄漏
|
||||
if (this.sessions.size > this.maxSessions) {
|
||||
const oldest = this.sessions.keys().next().value;
|
||||
this.sessions.delete(oldest);
|
||||
}
|
||||
|
||||
msgs.forEach(msg => {
|
||||
if (msg.type === "clear") {
|
||||
this.messages = [];
|
||||
session.messages = [];
|
||||
session.agent = null;
|
||||
} else {
|
||||
this.messages.push(new HumanMessage(`${msg.ts} - ${msg.content}`));
|
||||
session.messages.push(new HumanMessage(`${msg.ts} - ${msg.content}`));
|
||||
}
|
||||
});
|
||||
|
||||
if (this.messages.length === 0) {
|
||||
if (session.messages.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const agent = session.agent ?? this._genAgent(userInfo);
|
||||
session.agent = agent;
|
||||
|
||||
const INTERESTING_NODES = new Set(["model_request", "tools"]);
|
||||
for await (const [namespace, mode, data] of await agent.stream(
|
||||
{ messages: this.messages },
|
||||
{ messages: session.messages },
|
||||
{
|
||||
recursion_limit: 50,
|
||||
streamMode: ["updates", "messages", "custom"], subgraphs: true,
|
||||
configurable: {
|
||||
thread_id: 'default-session'
|
||||
thread_id: userId
|
||||
}
|
||||
})) {
|
||||
const isSubagent = namespace.some(s => s.startsWith("tools:"));
|
||||
@@ -59,18 +85,17 @@ export default class EscortAdminAgent {
|
||||
// Subagent results returned to main agent
|
||||
for (const msg of data_.messages ?? []) {
|
||||
if (msg.type === "tool") {
|
||||
console.log(`\nSubagent complete: ${msg.name}`);
|
||||
console.log(` Result: ${String(msg.content).slice(0, 200)}...`);
|
||||
logger.info(`Subagent complete: ${msg.name}, Result: ${String(msg.content).slice(0, 200)}`);
|
||||
}
|
||||
}
|
||||
} else if (nodeName === "model_request") {
|
||||
this.messages.push(...data_.messages);
|
||||
session.messages.push(...data_.messages);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Subagent updates (non-empty namespace)
|
||||
for (const [nodeName, data_] of Object.entries(data)) {
|
||||
console.log(` [${namespace[0]}] step: ${nodeName}`);
|
||||
logger.info(`[${namespace[0]}] step: ${nodeName}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -91,29 +116,23 @@ export default class EscortAdminAgent {
|
||||
callback(source, "tool", message.text, message.id);
|
||||
}
|
||||
} else if (mode === "custom") {
|
||||
this.logger.info("custom: ", data);
|
||||
logger.info("custom: ", data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_genAgent(userInfo) {
|
||||
if (this.agent) {
|
||||
return this.agent;
|
||||
}
|
||||
|
||||
this.messages = [];
|
||||
|
||||
const rootDir = process.cwd();
|
||||
const backend = new FilesystemBackend({ rootDir });
|
||||
|
||||
this.flashModel = new ChatDeepSeek({
|
||||
model: 'deepseek-v4-flash',
|
||||
apiKey: 'sk-a58ccd82b7ba4ce3ac176a88c9381095',
|
||||
model: config.agent.deepseek.flashModel,
|
||||
apiKey: config.agent.deepseek.apiKey,
|
||||
temperature: 0.0
|
||||
});
|
||||
this.proModel = new ChatDeepSeek({
|
||||
model: 'deepseek-v4-pro',
|
||||
apiKey: 'sk-a58ccd82b7ba4ce3ac176a88c9381095',
|
||||
model: config.agent.deepseek.proModel,
|
||||
apiKey: config.agent.deepseek.apiKey,
|
||||
temperature: 0.3
|
||||
});
|
||||
|
||||
@@ -122,7 +141,7 @@ export default class EscortAdminAgent {
|
||||
description: "查询和设置陪诊预约记录",
|
||||
systemPrompt: "根据用户指令,调用工具完成查询和设置陪诊记录。",
|
||||
model: this.flashModel,
|
||||
tools: [escortRecordQueryTool],
|
||||
tools: [escortRecordQueryTool, escortRecordSetTool],
|
||||
};
|
||||
|
||||
const escortResearchSubagent = {
|
||||
@@ -133,19 +152,18 @@ export default class EscortAdminAgent {
|
||||
tools: [webFetchTool, webSearchTool],
|
||||
};
|
||||
|
||||
this.agent = createDeepAgent({
|
||||
return createDeepAgent({
|
||||
name: "deep-agent",
|
||||
model: this.flashModel,
|
||||
systemPrompt: EscortAdminPrompts.buildSystemPrompt(userInfo),
|
||||
backend,
|
||||
tools: [getEnvTool, webFetchTool, webSearchTool, getLatLngTool, httpGetTool, httpPostTool,
|
||||
getCalendarInfoTool, getLunarCalendarInfoTool, getYearHolidaysTool, getYearTermsTool,
|
||||
escortRecordQueryTool, escortRecordSetTool]
|
||||
getCalendarInfoTool, getLunarCalendarInfoTool, getYearHolidaysTool, getYearTermsTool,
|
||||
escortRecordQueryTool, escortRecordSetTool],
|
||||
subagents: [escortRecordOperSubagent, escortResearchSubagent]
|
||||
});
|
||||
|
||||
return this.agent;
|
||||
}
|
||||
}
|
||||
|
||||
const adminAgent = new EscortAdminAgent();
|
||||
export { adminAgent };
|
||||
export { adminAgent };
|
||||
|
||||
Reference in New Issue
Block a user