This commit is contained in:
lik
2026-09-09 17:36:45 +08:00
parent d6efb180dd
commit 223e0ed2ee
25 changed files with 933 additions and 59 deletions
+17 -10
View File
@@ -6,18 +6,20 @@ import { ChatOpenAI } from "@langchain/openai";
import { AIMessageChunk, ToolMessage } from "langchain";
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 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 Prompts from "./prompts.js";
import { createRestrictedBackend } from "../../infra/restricted_fs_backend.js";
import { createHospitalInfoSubagent } from "../../subagent/hospital_info.js";
import {
getEnvTool, webFetchTool, webSearchTool, getCalendarInfoTool,
getLunarCalendarInfoTool, getYearHolidaysTool, getYearTermsTool, getLatLngTool,
httpGetTool, httpPostTool, createEscortRecordQueryTool
} from "./tools/index.js";
} from "../../infra/tools/index.js";
export default class EscortAgent {
// 历史消息字符数上限,超出时从头部丢弃完整轮次
@@ -144,8 +146,10 @@ export default class EscortAgent {
_genAgent(userInfo) {
const rootDir = process.cwd();
// 外部数据(用户记忆等)存储目录,由 conf.json agent.dataDir 配置
const dataDir = path.resolve(rootDir, config.agent.dataDir ?? "data");
const memoryFile = userInfo
? path.join(rootDir, "data", userInfo._id, "memories", "user_memory.txt")
? path.join(dataDir, "users", userInfo._id, "memory.txt")
: null;
// 会话中记忆文件被更新后重建 agent,使 systemPrompt 中的用户记忆保持最新
@@ -156,15 +160,17 @@ export default class EscortAgent {
return this.agent;
}
let backend = new FilesystemBackend({ rootDir });
// 受限后端:锁定沙箱根并禁止读取 conf.json/.env/logs 及用户数据目录
let backend = createRestrictedBackend({ rootDir, dataDir });
if (userInfo) {
const userMemoryPath = path.join(rootDir, "data", userInfo._id, "memories");
// 挂载根为用户数据目录:/memories/memory.txt ↔ data/users/{userId}/memory.txt
const userMemoryRoot = path.join(dataDir, "users", userInfo._id);
backend = new CompositeBackend(
new FilesystemBackend({ rootDir }),
createRestrictedBackend({ rootDir, dataDir }),
{
"/memories/": new FilesystemBackend({
rootDir: userMemoryPath,
rootDir: userMemoryRoot,
virtualMode: true
})
},
@@ -183,12 +189,13 @@ export default class EscortAgent {
name: "deep-agent",
model: this.flashModel,
systemPrompt: Prompts.buildSystemPrompt(userInfo),
memory: ["./agent/escort/AGENTS.md"],
memory: ["./agent/bots/bot-escort/AGENTS.md"],
backend,
tools: [getEnvTool, webFetchTool, webSearchTool, getLatLngTool, httpGetTool, httpPostTool,
getCalendarInfoTool, getLunarCalendarInfoTool, getYearHolidaysTool, getYearTermsTool,
createEscortRecordQueryTool(userInfo)],
skills: ["./agent/escort/skills/"],
subagents: [createHospitalInfoSubagent(this.flashModel)],
skills: ["./agent/infra/skills/"],
});
return this.agent;