This commit is contained in:
lik
2026-09-02 22:39:04 +08:00
parent c95a9c4c95
commit f81f6906f0
24 changed files with 389 additions and 1024 deletions
+26 -23
View File
@@ -5,6 +5,10 @@ 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';
// 密钥由 conf.json 统一提供;百度地图 skill 通过 env_get 读环境变量,此处桥接
process.env.TAVILY_API_KEY ??= config.agent.tavily?.apiKey;
process.env.BAIDU_MAP_AUTH_TOKEN ??= config.agent.baiduMap?.authToken;
import EscortAdminPrompts from "./prompts.js";
import {
getEnvTool, webFetchTool, webSearchTool, getCalendarInfoTool,
@@ -20,8 +24,7 @@ export default class EscortAdminAgent {
}
clearMessages(userInfo) {
const userId = userInfo?._id ?? 'default-session';
this.sessions.delete(userId);
this.sessions.delete(userInfo._id);
}
// msg: { agent: 'escort-admin', type: 'chat', ts: "2023-08-01 10:00:00", content: "你好" }
@@ -30,7 +33,7 @@ export default class EscortAdminAgent {
return;
}
const userId = userInfo?._id ?? 'default-session';
const userId = userInfo._id;
// LRU:按用户取会话,并更新使用顺序
let session = this.sessions.get(userId);
@@ -76,27 +79,27 @@ export default class EscortAdminAgent {
const isSubagent = namespace.some(s => s.startsWith("tools:"));
const source = isSubagent ? "subagent" : "main";
if (mode === "updates") {
for (const nodeName of Object.keys(data)) {
if (!INTERESTING_NODES.has(nodeName)) continue;
// Main agent updates (empty namespace)
if (namespace.length === 0) {
for (const [nodeName, data_] of Object.entries(data)) {
if (nodeName === "tools") {
// Subagent results returned to main agent
for (const msg of data_.messages ?? []) {
if (msg.type === "tool") {
logger.info(`Subagent complete: ${msg.name}, Result: ${String(msg.content).slice(0, 200)}`);
}
// Main agent updates (empty namespace)
if (namespace.length === 0) {
for (const [nodeName, data_] of Object.entries(data)) {
if (!INTERESTING_NODES.has(nodeName)) continue;
if (nodeName === "tools") {
// 工具结果必须并入历史,否则下一轮会出现 tool_calls 缺少对应 tool 结果的断链
for (const msg of data_.messages ?? []) {
if (msg.type === "tool") {
session.messages.push(msg);
logger.info(`Tool complete: ${msg.name}, Result: ${String(msg.content).slice(0, 200)}`);
}
} else if (nodeName === "model_request") {
session.messages.push(...data_.messages);
}
} else if (nodeName === "model_request") {
session.messages.push(...data_.messages);
}
} else {
// Subagent updates (non-empty namespace)
for (const [nodeName, data_] of Object.entries(data)) {
logger.info(`[${namespace[0]}] step: ${nodeName}`);
}
}
} else {
// Subagent updates (non-empty namespace)
for (const nodeName of Object.keys(data)) {
if (!INTERESTING_NODES.has(nodeName)) continue;
logger.info(`[${namespace[0]}] step: ${nodeName}`);
}
}
} else if (mode === "messages") {
@@ -105,10 +108,10 @@ export default class EscortAdminAgent {
continue;
}
if (AIMessageChunk.isInstance(message)) {
if (message.text && !message.tool_call_chunks?.length) {
if (message.text) {
callback(source, "ai", message.text, message.id);
}
if (message.additional_kwargs.reasoning_content && !message.tool_call_chunks?.length) {
if (message.additional_kwargs.reasoning_content) {
callback(source, "reasoning", message.additional_kwargs.reasoning_content, message.id);
}
}