Merge branch '108' of https://github.com/HBAI-Ltd/Toonflow-app into 108
This commit is contained in:
commit
a947ce5824
@ -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格式写入工作区:
|
||||
<storySkeleton>故事骨架内容</storySkeleton>
|
||||
<adaptationStrategy>改编策略内容</adaptationStrategy>
|
||||
`;
|
||||
|
||||
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) {
|
||||
|
||||
@ -29,7 +29,14 @@ const planDataKeyLabels = Object.fromEntries(
|
||||
Object.entries(planData.shape).map(([key, schema]) => [key, (schema as z.ZodTypeAny).description ?? key]),
|
||||
) as Record<keyof planData, string>;
|
||||
|
||||
export default (resTool: ResTool, toolsNames?: string[]) => {
|
||||
interface ToolConfig {
|
||||
resTool: ResTool;
|
||||
toolsNames?: string[];
|
||||
msg: ReturnType<ResTool["newMessage"]>;
|
||||
}
|
||||
|
||||
export default (toolCpnfig: ToolConfig) => {
|
||||
const { resTool, toolsNames, msg } = toolCpnfig;
|
||||
const { socket } = resTool;
|
||||
const tools: Record<string, Tool> = {
|
||||
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,43 +81,27 @@ export default (resTool: ResTool, toolsNames?: string[]) => {
|
||||
id: z.string().describe("章节id"),
|
||||
}),
|
||||
execute: async ({ id }) => {
|
||||
console.log("[tools] get_novel_text", id);
|
||||
console.log("[tools] get_novel_text", "[tools] get_novel_text", id);
|
||||
const thinking = msg.thinking(`正在获取小说章节原文...`);
|
||||
const data = await u.db("o_novel").where({ id }).select("chapterData").first();
|
||||
return data && data?.chapterData ? data.chapterData : "";
|
||||
},
|
||||
}),
|
||||
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;
|
||||
const text = data && data?.chapterData ? data.chapterData : "";
|
||||
thinking.appendText(`获取到原文:\n` + text);
|
||||
thinking.updateTitle(`获取小说章节原文完成`);
|
||||
thinking.complete();
|
||||
return data && data?.chapterData ? data.chapterData : 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;
|
||||
},
|
||||
@ -114,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,
|
||||
|
||||
8
src/types/database.d.ts
vendored
8
src/types/database.d.ts
vendored
@ -1,4 +1,4 @@
|
||||
// @db-hash 05ecfd675f848d88631c1a546996caea
|
||||
// @db-hash 8e5f2b7a28d4494b291d802b055b6399
|
||||
//该文件由脚本自动生成,请勿手动修改
|
||||
|
||||
export interface memories {
|
||||
@ -7,6 +7,7 @@ export interface memories {
|
||||
'embedding'?: string | null;
|
||||
'id'?: string;
|
||||
'isolationKey': string;
|
||||
'name'?: string | null;
|
||||
'relatedMessageIds'?: string | null;
|
||||
'role'?: string | null;
|
||||
'summarized'?: number | null;
|
||||
@ -46,7 +47,6 @@ export interface o_assets {
|
||||
'name'?: string | null;
|
||||
'projectId'?: number | null;
|
||||
'prompt'?: string | null;
|
||||
'promptState'?: string | null;
|
||||
'remark'?: string | null;
|
||||
'scriptId'?: number | null;
|
||||
'startTime'?: number | null;
|
||||
@ -121,13 +121,11 @@ export interface o_project {
|
||||
export interface o_prompt {
|
||||
'id'?: number;
|
||||
'name'?: string | null;
|
||||
'prompt'?: string | null;
|
||||
'rompt'?: string | null;
|
||||
}
|
||||
export interface o_script {
|
||||
'content'?: string | null;
|
||||
'createTime'?: number | null;
|
||||
'errorReason'?: string | null;
|
||||
'extractState'?: number | null;
|
||||
'id'?: number;
|
||||
'name'?: string | null;
|
||||
'projectId'?: number | null;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user