From ffdc6854c0192fd01e4195fbb21090450d2b71f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?ACT=E4=B8=B6=E6=B5=81=E6=98=9F=E9=9B=A8?= <1340145680@qq.com> Date: Mon, 30 Mar 2026 22:13:38 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E7=94=9F=E4=BA=A7Agent?= =?UTF-8?q?=E8=AE=B0=E5=BF=86=E9=94=99=E4=B9=B1=E9=97=AE=E9=80=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/agents/productionAgent/index.ts | 17 +++++++---- src/agents/scriptAgent/index.ts | 17 +++++++---- src/routes/test/test.ts | 44 +++++++++++++++++----------- src/socket/routes/productionAgent.ts | 29 +++++++++++++++--- src/socket/routes/scriptAgent.ts | 16 ++++++++-- src/types/database.d.ts | 4 --- 6 files changed, 87 insertions(+), 40 deletions(-) diff --git a/src/agents/productionAgent/index.ts b/src/agents/productionAgent/index.ts index 431f91a..e683aec 100644 --- a/src/agents/productionAgent/index.ts +++ b/src/agents/productionAgent/index.ts @@ -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, diff --git a/src/agents/scriptAgent/index.ts b/src/agents/scriptAgent/index.ts index ea57518..5542f77 100644 --- a/src/agents/scriptAgent/index.ts +++ b/src/agents/scriptAgent/index.ts @@ -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, diff --git a/src/routes/test/test.ts b/src/routes/test/test.ts index ed40deb..21d4b99 100644 --- a/src/routes/test/test.ts +++ b/src/routes/test/test.ts @@ -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>): 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); }); diff --git a/src/socket/routes/productionAgent.ts b/src/socket/routes/productionAgent.ts index 04abc35..367f7b8 100644 --- a/src/socket/routes/productionAgent.ts +++ b/src/socket/routes/productionAgent.ts @@ -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; diff --git a/src/socket/routes/scriptAgent.ts b/src/socket/routes/scriptAgent.ts index 5867c79..0da1c56 100644 --- a/src/socket/routes/scriptAgent.ts +++ b/src/socket/routes/scriptAgent.ts @@ -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; diff --git a/src/types/database.d.ts b/src/types/database.d.ts index 9b42b68..2a3bc57 100644 --- a/src/types/database.d.ts +++ b/src/types/database.d.ts @@ -1,8 +1,4 @@ -<<<<<<< HEAD // @db-hash 93b2462070c45c2b449e9a18c4e88763 -======= -// @db-hash 24748d4ef971381a79c720c846f83847 ->>>>>>> 796947cef173e7fe2f96e21fa8aeae23ff0fdf4a //该文件由脚本自动生成,请勿手动修改 export interface memories { From 44fa7d1b46744207ab9291c27646dc2ac1a36639 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?ACT=E4=B8=B6=E6=B5=81=E6=98=9F=E9=9B=A8?= <1340145680@qq.com> Date: Mon, 30 Mar 2026 22:14:25 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=AE=9A=E8=AF=AD?= =?UTF-8?q?=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/agents/productionAgent/index.ts | 4 ++-- src/agents/scriptAgent/index.ts | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/agents/productionAgent/index.ts b/src/agents/productionAgent/index.ts index e683aec..d64fa90 100644 --- a/src/agents/productionAgent/index.ts +++ b/src/agents/productionAgent/index.ts @@ -135,7 +135,7 @@ function createSubAgent(parentCtx: AgentContext) { const addPrompt = "\n" + [ - "你可以使用如下XML格式写入工作区:\n```", + "你必须使用如下XML格式写入工作区:\n```", "拍摄计划:内容", "分镜表:内容", "```", @@ -168,7 +168,7 @@ function createSubAgent(parentCtx: AgentContext) { const systemPrompt = await fs.promises.readFile(skill, "utf-8"); return runAgent({ prompt, - system: systemPrompt + "你可以使用如下XML格式写入工作区:\n故事骨架内容", + system: systemPrompt + "你必须使用如下XML格式写入工作区:\n故事骨架内容", name: "监制", memoryKey: "assistant:supervision", }); diff --git a/src/agents/scriptAgent/index.ts b/src/agents/scriptAgent/index.ts index 5542f77..88cf8fc 100644 --- a/src/agents/scriptAgent/index.ts +++ b/src/agents/scriptAgent/index.ts @@ -144,7 +144,7 @@ function createSubAgent(parentCtx: AgentContext) { const systemPrompt = await fs.promises.readFile(skill, "utf-8"); return runAgent({ prompt, - system: systemPrompt + "\n你可以使用如下XML格式写入工作区:\n故事骨架内容", + system: systemPrompt + "\n你必须使用如下XML格式写入工作区:\n故事骨架内容", name: "编剧", memoryKey: "assistant:execution:storySkeleton", }); @@ -159,7 +159,7 @@ function createSubAgent(parentCtx: AgentContext) { const systemPrompt = await fs.promises.readFile(skill, "utf-8"); return runAgent({ prompt, - system: systemPrompt + "\n你可以使用如下XML格式写入工作区:\n改编策略内容", + system: systemPrompt + "\n你必须使用如下XML格式写入工作区:\n改编策略内容", name: "编剧", memoryKey: "assistant:execution:adaptationStrategy", }); @@ -176,7 +176,7 @@ function createSubAgent(parentCtx: AgentContext) { prompt, system: systemPrompt + - `\n你可以使用如下XML格式写入工作区:\nXML不得添加任何额外标签`, + `\n你必须使用如下XML格式写入工作区:\nXML不得添加任何额外标签`, name: "编剧", memoryKey: "assistant:execution:script", });