From 9ff819a5fe2d877cf4dae4b29c13d10b04c5f252 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: Sat, 28 Mar 2026 00:02:48 +0800
Subject: [PATCH] =?UTF-8?q?=E9=87=8D=E5=86=99agent=E8=BF=94=E5=9B=9E?=
=?UTF-8?q?=E9=80=BB=E8=BE=91?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/agents/scriptAgent/index.ts | 45 ++++++++++++++-------------
src/agents/scriptAgent/tools.ts | 55 ++++++++++++++++-----------------
2 files changed, 50 insertions(+), 50 deletions(-)
diff --git a/src/agents/scriptAgent/index.ts b/src/agents/scriptAgent/index.ts
index 47b809a..acbe05a 100644
--- a/src/agents/scriptAgent/index.ts
+++ b/src/agents/scriptAgent/index.ts
@@ -67,7 +67,7 @@ export async function decisionAI(ctx: AgentContext) {
...skill.tools,
...memory.getTools(),
run_sub_agent: runSubAgent(ctx),
- ...useTools(ctx.resTool),
+ ...useTools({ resTool: ctx.resTool, msg: ctx.msg }),
},
});
@@ -77,45 +77,50 @@ export async function decisionAI(ctx: AgentContext) {
//====================== 执行层 ======================
export async function executionAI(ctx: AgentContext) {
- const { isolationKey, text, abortSignal, resTool } = ctx;
- const memory = new Memory("scriptAgent", isolationKey);
- const [skill, mem] = await Promise.all([useSkill("script_agent_execution.md"), memory.get(text)]);
+ const { text, abortSignal } = ctx;
+ const skill = await useSkill("script_agent_execution.md");
- const systemPrompt = buildSystemPrompt(skill.prompt, mem);
+ const subMsg = ctx.resTool.newMessage("assistant", "编剧");
+
+ const prefixSystem = `
+你可以使用如下XML格式写入工作区:
+故事骨架内容
+改编策略内容
+`;
const { textStream } = await u.Ai.Text("scriptAgent").stream({
- system: systemPrompt,
+ system: prefixSystem + skill.prompt,
messages: [{ role: "user", content: text }],
abortSignal,
tools: {
...skill.tools,
- ...memory.getTools(),
- ...useTools(ctx.resTool),
+ ...useTools({ resTool: ctx.resTool, msg: subMsg }),
},
});
- return textStream;
+ return { textStream, subMsg };
}
export async function supervisionAI(ctx: AgentContext) {
- const { isolationKey, text, abortSignal, resTool } = ctx;
+ const { text, abortSignal } = ctx;
- const memory = new Memory("scriptAgent", isolationKey);
- const [skill, mem] = await Promise.all([useSkill("script_agent_supervision.md"), memory.get(text)]);
-
- const systemPrompt = buildSystemPrompt(skill.prompt, mem);
+ const skill = await useSkill("script_agent_supervision.md");
+ const subMsg = ctx.resTool.newMessage("assistant", "编辑");
const { textStream } = await u.Ai.Text("scriptAgent").stream({
- system: systemPrompt,
+ system: skill.prompt,
messages: [{ role: "user", content: text }],
abortSignal,
tools: {
...skill.tools,
- ...useTools(ctx.resTool),
+ ...useTools({
+ resTool: ctx.resTool,
+ msg: subMsg,
+ }),
},
});
- return textStream;
+ return { textStream, subMsg };
}
//工具函数
@@ -125,17 +130,15 @@ function runSubAgent(parentCtx: AgentContext) {
description: "启动子Agent执行独立任务。可用子Agent:executionAI, decisionAI, supervisionAI",
inputSchema: z.object({
agent: z.enum(["executionAI", "supervisionAI"]).describe("子Agent名称"),
- prompt: z.string().max(100).describe("交给子Agent的任务简约描述"),
+ prompt: z.string().describe("交给子Agent的任务简约描述,100字以内"),
}),
execute: async ({ agent, prompt }) => {
const fn = [executionAI, supervisionAI][subAgentList.indexOf(agent)];
- const subMsg = parentCtx.resTool.newMessage("assistant", agent == "executionAI" ? "编剧" : "编辑");
-
// 先完成主Agent当前的消息
parentCtx.msg.complete();
// 子Agent用新消息回复
- const subTextStream = await fn({ ...parentCtx, text: prompt });
+ const { textStream: subTextStream, subMsg } = await fn({ ...parentCtx, text: prompt });
let text = subMsg.text();
let fullResponse = "";
for await (const chunk of subTextStream) {
diff --git a/src/agents/scriptAgent/tools.ts b/src/agents/scriptAgent/tools.ts
index 03cbdbe..0c312f4 100644
--- a/src/agents/scriptAgent/tools.ts
+++ b/src/agents/scriptAgent/tools.ts
@@ -29,7 +29,14 @@ const planDataKeyLabels = Object.fromEntries(
Object.entries(planData.shape).map(([key, schema]) => [key, (schema as z.ZodTypeAny).description ?? key]),
) as Record;
-export default (resTool: ResTool, toolsNames?: string[]) => {
+interface ToolConfig {
+ resTool: ResTool;
+ toolsNames?: string[];
+ msg: ReturnType;
+}
+
+export default (toolCpnfig: ToolConfig) => {
+ const { resTool, toolsNames, msg } = toolCpnfig;
const { socket } = resTool;
const tools: Record = {
get_novel_events: tool({
@@ -38,14 +45,18 @@ export default (resTool: ResTool, toolsNames?: string[]) => {
ids: z.array(z.number()).describe("章节id,注意区分"),
}),
execute: async ({ ids }) => {
- resTool.newMessage('system').text(`正在获取章节事件,章节ID:${ids.join(",")}`).complete();
console.log("[tools] get_novel_events", ids);
+ const thinking = msg.thinking("正在查询章节事件...");
const data = await u
.db("o_novel")
.where("projectId", resTool.data.projectId)
.select("id", "chapterIndex as index", "reel", "chapter", "chapterData", "event", "eventState")
.whereIn("id", ids);
+ thinking.appendText("正在查询章节ID: " + ids.join(","));
const eventString = data.map((i: any) => [`第${i.index}章,标题:${i.chapter},事件:${i.event}`].join("\n")).join("\n");
+ thinking.appendText("查询结果:\n" + eventString);
+ thinking.updateTitle("查询章节事件完成");
+ thinking.complete();
return eventString;
},
}),
@@ -55,9 +66,12 @@ export default (resTool: ResTool, toolsNames?: string[]) => {
key: keySchema.describe("数据key"),
}),
execute: async ({ key }) => {
- resTool.newMessage('system').text(`正在阅读 ${planDataKeyLabels[key]} 数据...`).complete();
console.log("[tools] get_planData", key);
+ const thinking = msg.thinking(`正在获取${planDataKeyLabels[key]}工作区数据...`);
const planData: planData = await new Promise((resolve) => socket.emit("getPlanData", { key }, (res: any) => resolve(res)));
+ thinking.appendText(`获取到${planDataKeyLabels[key]}:\n` + planData[key]);
+ thinking.updateTitle(`获取${planDataKeyLabels[key]}完成`);
+ thinking.complete();
return planData[key];
},
}),
@@ -67,42 +81,27 @@ export default (resTool: ResTool, toolsNames?: string[]) => {
id: z.string().describe("章节id"),
}),
execute: async ({ id }) => {
- console.log(id);
- return "";
- },
- }),
- set_planData_storySkeleton: tool({
- description: "保存故事骨架到工作区",
- inputSchema: z.object({ value: planData.shape.storySkeleton }),
- execute: async ({ value }) => {
- console.log("[tools] set_planData storySkeleton", value);
- resTool.newMessage('system').text("正在保存 故事骨架 数据").complete();
- socket.emit("setPlanData", { key: "storySkeleton", value });
- return true;
- },
- }),
- set_planData_adaptationStrategy: tool({
- description: "保存改编策略到工作区",
- inputSchema: z.object({ value: planData.shape.adaptationStrategy }),
- execute: async ({ value }) => {
- console.log("[tools] set_planData adaptationStrategy", value);
- resTool.newMessage('system').text("正在保存 改编策略 数据").complete();
- socket.emit("setPlanData", { key: "adaptationStrategy", value });
- return true;
+ console.log("[tools] get_novel_text", id);
+ const thinking = msg.thinking(`正在获取小说章节原文...`);
+ const data = await u.db("o_novel").where({ id }).select("chapterData").first();
+ const text = data && data?.chapterData ? data.chapterData : "";
+ thinking.appendText(`获取到原文:\n` + text);
+ thinking.updateTitle(`获取小说章节原文完成`);
+ thinking.complete();
+ return text;
},
}),
+ //======================
update_script_to_sqlite: tool({
description: "更新剧本,修改数据库对应剧本,供后续业务使用",
inputSchema: z.object({
script: ScriptSchema,
}),
execute: async ({ script }) => {
- console.log("%c Line:103 🍷 script", "background:#42b983", script);
await u.db("o_script").where({ id: script.id }).update({
name: script.name,
content: script.content,
});
-
socket.emit("setPlanData", { key: "script", value: script.id });
return true;
},
@@ -113,8 +112,6 @@ export default (resTool: ResTool, toolsNames?: string[]) => {
script: ScriptSchema.omit({ id: true }),
}),
execute: async ({ script }) => {
- console.log("%c Line:103 🍷 script", "background:#42b983", script);
-
const [scriptId] = await u.db("o_script").insert({
name: script.name,
content: script.content,