修复生产Agent记忆错乱问退

This commit is contained in:
ACT丶流星雨 2026-03-30 22:13:38 +08:00
parent 0fe8001d2f
commit ffdc6854c0
6 changed files with 87 additions and 40 deletions

View File

@ -98,14 +98,19 @@ function createSubAgent(parentCtx: AgentContext) {
tools: { ...extraTools, ...useTools({ resTool, msg: subMsg }) },
});
for await (const chunk of textStream) {
text.append(chunk);
fullResponse += chunk;
try {
for await (const chunk of textStream) {
text.append(chunk);
fullResponse += chunk;
}
text.complete();
subMsg.complete();
} catch (err: any) {
text.complete();
subMsg.stop();
throw err;
}
text.complete();
subMsg.complete();
if (fullResponse.trim()) {
await memory.add(memoryKey, fullResponse, {
name,

View File

@ -108,14 +108,19 @@ function createSubAgent(parentCtx: AgentContext) {
tools: { ...extraTools, ...useTools({ resTool, msg: subMsg }) },
});
for await (const chunk of textStream) {
text.append(chunk);
fullResponse += chunk;
try {
for await (const chunk of textStream) {
text.append(chunk);
fullResponse += chunk;
}
text.complete();
subMsg.complete();
} catch (err: any) {
text.complete();
subMsg.stop();
throw err;
}
text.complete();
subMsg.complete();
if (fullResponse.trim()) {
await memory.add(memoryKey, fullResponse, {
name,

View File

@ -2,25 +2,35 @@ import express from "express";
const router = express.Router();
import u from "@/utils";
import fs from "fs";
import { useSkill } from "@/utils/agent/skillsTools";
import Memory from "@/utils/agent/memory";
function buildMemPrompt(mem: Awaited<ReturnType<Memory["get"]>>): string {
let memoryContext = "";
if (mem.rag.length) {
memoryContext += `[相关记忆]\n${mem.rag.map((r) => r.content).join("\n")}`;
}
if (mem.summaries.length) {
if (memoryContext) memoryContext += "\n\n";
memoryContext += `[历史摘要]\n${mem.summaries.map((s, i) => `${i + 1}. ${s.content}`).join("\n")}`;
}
if (mem.shortTerm.length) {
if (memoryContext) memoryContext += "\n\n";
memoryContext += `[近期对话]\n${mem.shortTerm.map((m) => `${m.role}: ${m.content}`).join("\n")}`;
}
return `## Memory\n以下是你对用户的记忆可作为参考但不要主动提及\n${memoryContext}`;
}
export default router.get("/", async (req, res) => {
const skill = await useSkill(
{
mainSkill: "production_agent_execution",
workspace: ["production_agent_skills/execution"],
attachedSkills: ["art_prompts/chinese_sweet_romance/driector_skills"],
},
);
const test = await u.Ai.Text("scriptAgent").invoke({
system: skill.prompt,
messages: [
{ role: "user", content: "渐进式激活skill技能->资源1->资源2...一直渐进到最深处,并输出你的阅读路线,同级目录你只用读取一个无需全部读取" },
],
tools: skill.tools,
});
const isolationKey = "test";
const input = "你好"
console.log("%c Line:21 🌽 text", "background:#ea7e5c", test.text);
res.send(test.text);
const memory = new Memory("productionAgent", isolationKey);
await memory.add("user", input);
const mem = buildMemPrompt(await memory.get(input));
res.send(mem);
});

View File

@ -36,12 +36,22 @@ export default (nsp: Namespace) => {
console.log("[productionAgent] 已连接:", socket.id);
const resTool = new ResTool(socket, {
let resTool = new ResTool(socket, {
projectId: socket.handshake.auth.projectId,
scriptId: socket.handshake.auth.scriptId,
});
let abortController: AbortController | null = null;
socket.on("updateContext", (data: { isolationKey: string; projectId: number; scriptId: number }, callback) => {
isolationKey = data.isolationKey;
resTool = new ResTool(socket, {
projectId: data.projectId,
scriptId: data.scriptId,
});
console.log("[productionAgent] 上下文已更新:", isolationKey);
callback?.({ success: true });
});
socket.on("chat", async (data: { content: string }) => {
const { content } = data;
abortController?.abort();
@ -84,6 +94,7 @@ export default (nsp: Namespace) => {
text = currentMsg.text();
};
let aborted = false;
try {
for await (const chunk of textStream) {
await syncCurrentMessage();
@ -91,11 +102,21 @@ export default (nsp: Namespace) => {
currentContent += chunk;
}
} catch (err: any) {
if (err.name !== "AbortError") throw err;
if (err.name === "AbortError" || currentController.signal.aborted) {
aborted = true;
} else {
throw err;
}
} finally {
await syncCurrentMessage();
text.complete();
currentMsg.complete();
if (aborted) {
text.append("[已停止]");
text.complete();
currentMsg.stop();
} else {
text.complete();
currentMsg.complete();
}
await persistCurrentMessage();
if (abortController === currentController) {
abortController = null;

View File

@ -83,6 +83,7 @@ export default (nsp: Namespace) => {
text = currentMsg.text();
};
let aborted = false;
try {
for await (const chunk of textStream) {
await syncCurrentMessage();
@ -90,11 +91,20 @@ export default (nsp: Namespace) => {
currentContent += chunk;
}
} catch (err: any) {
if (err.name !== "AbortError") throw err;
if (err.name === "AbortError" || currentController.signal.aborted) {
aborted = true;
} else {
throw err;
}
} finally {
await syncCurrentMessage();
text.complete();
currentMsg.complete();
if (aborted) {
text.complete();
currentMsg.stop();
} else {
text.complete();
currentMsg.complete();
}
await persistCurrentMessage();
if (abortController === currentController) {
abortController = null;

View File

@ -1,8 +1,4 @@
<<<<<<< HEAD
// @db-hash 93b2462070c45c2b449e9a18c4e88763
=======
// @db-hash 24748d4ef971381a79c720c846f83847
>>>>>>> 796947cef173e7fe2f96e21fa8aeae23ff0fdf4a
//该文件由脚本自动生成,请勿手动修改
export interface memories {