diff --git a/src/agents/productionAgent/tools.ts b/src/agents/productionAgent/tools.ts index 64f6b8f..d50679d 100644 --- a/src/agents/productionAgent/tools.ts +++ b/src/agents/productionAgent/tools.ts @@ -488,7 +488,6 @@ export default (resTool: ResTool, toolsNames?: string[]) => { return `错误:检测到循环依赖,涉及分镜id: ${cyclicIds.join(", ")}`; } - console.log("%c Line:496 🌶", "background:#ea7e5c"); resTool.systemMessage(`图片生成调度计划:共 ${levels.length} 层,${images.length} 张图片`); // --- 准备公共数据 --- diff --git a/src/routes/assetsGenerate/generateAssets.ts b/src/routes/assetsGenerate/generateAssets.ts index 3e1001f..977a876 100644 --- a/src/routes/assetsGenerate/generateAssets.ts +++ b/src/routes/assetsGenerate/generateAssets.ts @@ -4,160 +4,129 @@ import { z } from "zod"; import { v4 as uuidv4 } from "uuid"; import { error, success } from "@/lib/responseFormat"; import { validateFields } from "@/middleware/middleware"; + const router = express.Router(); -// 生成资产图片 -export default router.post( - "/", - validateFields({ - id: z.number(), - type: z.enum(["role", "scene", "tool", "storyboard"]), - projectId: z.number(), - name: z.string(), - base64: z.string().optional().nullable(), - prompt: z.string(), - model: z.string(), - resolution: z.string(), - }), - async (req, res) => { - const { id, type, projectId, base64, prompt, name, model, resolution } = req.body; - //获取风格 - const project = await u.db("o_project").where("id", projectId).select("artStyle", "type", "intro").first(); - if (!project) return res.status(500).send(success({ message: "项目为空" })); - const role = (await u.getPrompts("role-generateImage")) ?? ""; - const scene = (await u.getPrompts("scene-generateImage")) ?? ""; - const tool = (await u.getPrompts("tool-generateImage")) ?? ""; - let systemPrompt = ""; - let userPrompt = ""; - if (type == "role") { - systemPrompt = role; - userPrompt = ` - 请根据以下参数生成角色标准四视图: +type AssetType = "role" | "scene" | "tool"; - **基础参数:** - - 画风风格: ${project?.artStyle || "未指定"} +interface AssetTypeConfig { + label: string; + taskClass: string; + dir: string; + promptTitle: string; + promptEnd: string; +} - **角色设定:** - - 名称:${name}, - - 提示词:${prompt}, - - 请严格按照系统规范生成人物角色四视图。 - `; - } - if (type == "scene") { - systemPrompt = scene; - userPrompt = ` - 请根据以下参数生成标准场景图: - - **基础参数:** - - 画风风格: ${project?.artStyle || "未指定"} - - **场景设定:** - - 名称:${name}, - - 提示词:${prompt}, - - 请严格按照系统规范生成标准场景图。 - `; - } - if (type == "tool") { - systemPrompt = tool; - userPrompt = ` - 请根据以下参数生成标准道具图: - - **基础参数:** - - 画风风格: ${project?.artStyle || "未指定"} - - **道具设定:** - - 名称:${name}, - - 提示词:${prompt}, - - 请严格按照系统规范生成标准道具图。 - `; - } - const [imageId] = await u.db("o_image").insert({ - type: type, - state: "生成中", - assetsId: id, - }); - let taskClass = ""; - if (type == "role") taskClass = "角色图生成"; - if (type == "scene") taskClass = "场景图生成"; - if (type == "tool") taskClass = "道具图生成"; - - try { - let imagePath; - let insertType; - let describe; - let relatedObjects = {}; - - if (type == "role") { - insertType = "role"; - imagePath = `/${projectId}/role/${uuidv4()}.jpg`; - describe = `生成角色图,名称:${name},提示词:${prompt}`; - relatedObjects = { - id: id, - projectId, - type: "角色", - }; - } - if (type == "scene") { - insertType = "scene"; - imagePath = `/${projectId}/scene/${uuidv4()}.jpg`; - describe = `生成场景图,名称:${name},提示词:${prompt}`; - relatedObjects = { - id: id, - projectId, - type: "场景", - }; - } - if (type == "tool") { - insertType = "tool"; - imagePath = `/${projectId}/props/${uuidv4()}.jpg`; - describe = `生成道具图,名称:${name},提示词:${prompt}`; - relatedObjects = { - id: id, - projectId, - type: "道具", - }; - } - - const aiImage = u.Ai.Image(model); - await aiImage.run({ - systemPrompt, - prompt: userPrompt, - imageBase64: base64 ? [base64] : [], - size: resolution, - aspectRatio: "16:9", - taskClass, - describe: describe ?? "", // 描述 - projectId, - relatedObjects: JSON.stringify(relatedObjects), // 相关对象信息,便于后续分析和追踪 - }); - aiImage.save(imagePath!); - const imageData = await u.db("o_image").where("id", imageId).select("*").first(); - const modelData = model.split(":")[1]; - if (imageData) { - await u.db("o_image").where("id", imageId).update({ - state: "生成成功", - filePath: imagePath, - type: insertType, - model: modelData, - resolution: resolution, - }); - const path = await u.oss.getFileUrl(imagePath!); - await u.db("o_assets").where("id", id).update({ - imageId: imageId, - }); - return res.status(200).send(success({ path, assetsId: id })); - } else { - return res.status(500).send("资产已被删除"); - } - } catch (e) { - await u.db("o_image").where("id", imageId).update({ - state: "生成失败", - }); - const msg = u.error(e).message || "图片生成失败"; - return res.status(400).send(error(msg)); - } +const assetTypeConfig: Record = { + role: { + label: "角色", + taskClass: "角色图生成", + dir: "role", + promptTitle: "角色标准四视图", + promptEnd: "人物角色四视图", }, -); + scene: { + label: "场景", + taskClass: "场景图生成", + dir: "scene", + promptTitle: "标准场景图", + promptEnd: "标准场景图", + }, + tool: { + label: "道具", + taskClass: "道具图生成", + dir: "props", + promptTitle: "标准道具图", + promptEnd: "标准道具图", + }, +}; + +// ─── 构建生成提示词 ────────────────────────────────────────── + +function buildPrompt(cfg: AssetTypeConfig, artStyle: string, name: string, prompt: string): string { + return ` + 请根据以下参数生成${cfg.promptTitle}: + + **基础参数:** + - 画风风格: ${artStyle || "未指定"} + + **${cfg.label}设定:** + - 名称:${name}, + - 提示词:${prompt}, + + 请严格按照系统规范生成${cfg.promptEnd}。 + `; +} + +// ─── 生成资产图片 ──────────────────────────────────────────── + +const requestSchema = { + id: z.number(), + type: z.enum(["role", "scene", "tool", "storyboard"]), + projectId: z.number(), + name: z.string(), + base64: z.string().optional().nullable(), + prompt: z.string(), + model: z.string(), + resolution: z.string(), +}; + +export default router.post("/", validateFields(requestSchema), async (req, res) => { + const { id, type, projectId, base64, prompt, name, model, resolution } = req.body; + + // 1. 查询项目 & 获取类型配置 + const project = await u.db("o_project").where("id", projectId).select("artStyle", "type", "intro").first(); + if (!project) return res.status(500).send(success({ message: "项目为空" })); + + const cfg = assetTypeConfig[type as AssetType]; + if (!cfg) return res.status(400).send(error("不支持的类型")); + + // 2. 创建图片占位记录 + const [imageId] = await u.db("o_image").insert({ + type, + state: "生成中", + assetsId: id, + }); + + // 3. 准备生成参数 + const imagePath = `/${projectId}/${cfg.dir}/${uuidv4()}.jpg`; + const userPrompt = buildPrompt(cfg, project.artStyle!, name, prompt); + const describe = `生成${cfg.label}图,名称:${name},提示词:${prompt}`; + const relatedObjects = { id, projectId, type: cfg.label }; + + try { + // 4. 调用 AI 生成图片 + const aiImage = u.Ai.Image(model); + await aiImage.run({ + prompt: userPrompt, + imageBase64: base64 ? [base64] : [], + size: resolution, + aspectRatio: "16:9", + taskClass: cfg.taskClass, + describe, + projectId, + relatedObjects: JSON.stringify(relatedObjects), + }); + aiImage.save(imagePath); + + // 5. 更新记录 & 返回结果 + const imageData = await u.db("o_image").where("id", imageId).select("*").first(); + if (!imageData) return res.status(500).send("资产已被删除"); + + await u.db("o_image").where("id", imageId).update({ + state: "生成成功", + filePath: imagePath, + type, + model: model.split(":")[1], + resolution, + }); + + const path = await u.oss.getFileUrl(imagePath); + await u.db("o_assets").where("id", id).update({ imageId }); + + return res.status(200).send(success({ path, assetsId: id })); + } catch (e) { + await u.db("o_image").where("id", imageId).update({ state: "生成失败" }); + return res.status(400).send(error(u.error(e).message || "图片生成失败")); + } +}); diff --git a/src/utils.ts b/src/utils.ts index 1a4adda..98eb57a 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,13 +1,11 @@ import db from "@/utils/db"; import oss from "@/utils/oss"; -// import * as ai from "@/utils/ai"; import getConfig from "./utils/getConfig"; import { v4 as uuid } from "uuid"; import error from "@/utils/error"; import cleanNovel from "./utils/cleanNovel"; import getPath from "@/utils/getPath"; import vm from "@/utils/vm"; -import { getPrompts } from "@/utils/getPrompts"; import task from "@/utils/taskRecord"; import Ai from "@/utils/ai"; @@ -21,6 +19,5 @@ export default { vm, getPath, Ai, - getPrompts, task, }; diff --git a/src/utils/agent/skillsTools.ts b/src/utils/agent/skillsTools.ts index 16bc5ba..6361c15 100644 --- a/src/utils/agent/skillsTools.ts +++ b/src/utils/agent/skillsTools.ts @@ -123,8 +123,6 @@ function createSkillTools(skill: SkillRecord, mainSkillName: string) { .where("o_skillList.state", 1) .andWhere("o_skillAttribution.attribution", mainSkillName); - console.log("%c Line:120 🌮 resources", "background:#b03734", resources); - activated.add(name); console.log(`[Skill] 📖 已激活:${name}(${body.length} 字符,${resources.length} 资源)`); let content = ""; @@ -144,7 +142,6 @@ function createSkillTools(skill: SkillRecord, mainSkillName: string) { content += "- discover_skill_docs:当上方资源不足以完成任务时,使用关键词检索更多相关文档。传入与当前任务相关的关键词列表即可获取推荐。\n"; content += "\n"; content += ""; - console.log("%c Line:133 🍊 content", "background:#2eafb0", content); return { content }; }, }), diff --git a/src/utils/ai.ts b/src/utils/ai.ts index f900ab4..7a94a8e 100644 --- a/src/utils/ai.ts +++ b/src/utils/ai.ts @@ -85,7 +85,6 @@ class AiText { } interface ImageConfig { - systemPrompt?: string; // 系统提示词 prompt: string; //图片提示词 imageBase64: string[]; //输入的图片提示词 size: "1K" | "2K" | "4K"; // 图片尺寸 diff --git a/src/utils/getPrompts.ts b/src/utils/getPrompts.ts deleted file mode 100644 index 746e963..0000000 --- a/src/utils/getPrompts.ts +++ /dev/null @@ -1,20 +0,0 @@ -export function getPrompts(type: string) { - if (type == "role-polish") { - return "帮我升深入描述一下这个角色,包括他的外貌、性格、背景故事等方面,要求生动有趣,能够让人印象深刻。" - } - if (type == "scene-polish") { - return "帮我升深入描述一下这个场景,包括它的环境、氛围、视觉效果等方面,要求生动有趣,能够让人印象深刻。" - } - if (type == "tool-polish") { - return "帮我升深入描述一下这个道具,包括它的外观、功能、使用方法等方面,要求生动有趣,能够让人印象深刻。" - } - if (type == "role-generateImage") { - return "你是一个资深的角色设计师,擅长根据提示词创作出符合要求的角色设计图。请根据用户提供的提示词,结合你的专业知识和创意,生成一套角色设计图,包括正面、侧面、背面和动态四视图。请确保设计图风格统一,细节丰富,能够清晰地展示角色的外貌特征、服装设计和个性特点。" - } - if (type == "scene-generateImage") { - return "你是一个资深的场景设计师,擅长根据提示词创作出符合要求的场景设计图。请根据用户提供的提示词,结合你的专业知识和创意,生成一套场景设计图,包括全景图、局部特写图和动态效果图。请确保设计图风格统一,细节丰富,能够清晰地展示场景的环境氛围、视觉效果和叙事功能。" - } - if (type == "tool-generateImage") { - return "你是一个资深的道具设计师,擅长根据提示词创作出符合要求的道具设计图。请根据用户提供的提示词,结合你的专业知识和创意,生成一套道具设计图,包括正面、侧面、背面和动态四视图。请确保设计图风格统一,细节丰富,能够清晰地展示道具的外观特征、功能设计和使用方法。" - } -} \ No newline at end of file