Merge branch '108' of https://github.com/HBAI-Ltd/Toonflow-app into 108
# Conflicts: # src/types/database.d.ts
This commit is contained in:
commit
b099017862
8307
package-lock.json
generated
8307
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -52,6 +52,7 @@
|
||||
"cors": "^2.8.5",
|
||||
"custom-electron-titlebar": "^4.2.8",
|
||||
"dotenv": "^17.2.3",
|
||||
"electron-rebuild": "^3.2.9",
|
||||
"express": "^5.2.1",
|
||||
"express-ws": "^5.0.2",
|
||||
"fast-glob": "^3.3.3",
|
||||
|
||||
@ -153,6 +153,14 @@ app.whenReady().then(async () => {
|
||||
app.exit(0);
|
||||
return { ok: true };
|
||||
},
|
||||
apprestart: () => {
|
||||
// 延迟执行,让响应先返回给前端
|
||||
setTimeout(() => {
|
||||
app.relaunch();
|
||||
app.exit(0);
|
||||
}, 500);
|
||||
return { ok: true, message: "应用即将重启" };
|
||||
},
|
||||
windowismaximized: () => ({
|
||||
maximized: mainWindow?.isMaximized() ?? false,
|
||||
}),
|
||||
|
||||
@ -78,7 +78,7 @@ export default async (knex: Knex, forceInit: boolean = false): Promise<void> =>
|
||||
modelName: "",
|
||||
vendorId: null,
|
||||
key: "scriptAgent",
|
||||
name: "剧本Agent",
|
||||
name: "剧本AI",
|
||||
desc: "用于读取原文生成故事骨架、改编策略,建议使用具备强大文本理解和生成能力的模型",
|
||||
disabled: false,
|
||||
},
|
||||
@ -87,7 +87,7 @@ export default async (knex: Knex, forceInit: boolean = false): Promise<void> =>
|
||||
modelName: "",
|
||||
vendorId: null,
|
||||
key: "productionAgent",
|
||||
name: "生产Agent",
|
||||
name: "生产AI",
|
||||
desc: "对工作流进行调度和管理,建议使用具备较强的逻辑推理和任务管理能力的模型",
|
||||
disabled: false,
|
||||
},
|
||||
@ -96,7 +96,7 @@ export default async (knex: Knex, forceInit: boolean = false): Promise<void> =>
|
||||
modelName: "",
|
||||
vendorId: null,
|
||||
key: "universalAgent",
|
||||
name: "通用Agent",
|
||||
name: "通用AI",
|
||||
desc: "用于小说事件提取、资产提示词生成、台词提取等边缘功能,建议使用具备较强文本处理能力的模型",
|
||||
disabled: false,
|
||||
},
|
||||
@ -184,6 +184,18 @@ export default async (knex: Knex, forceInit: boolean = false): Promise<void> =>
|
||||
},
|
||||
initData: async (knex) => {},
|
||||
},
|
||||
//提示词表
|
||||
{
|
||||
name: "o_prompt",
|
||||
builder: (table) => {
|
||||
table.integer("id").notNullable();
|
||||
table.string("name");
|
||||
table.text("rompt");
|
||||
table.primary(["id"]);
|
||||
table.unique(["id"]);
|
||||
},
|
||||
initData: async (knex) => {},
|
||||
},
|
||||
//小说原文表
|
||||
{
|
||||
name: "o_novel",
|
||||
@ -276,6 +288,7 @@ export default async (knex: Knex, forceInit: boolean = false): Promise<void> =>
|
||||
table.integer("assetsId");
|
||||
table.integer("projectId");
|
||||
table.integer("startTime");
|
||||
table.string("promptState");
|
||||
table.primary(["id"]);
|
||||
table.unique(["id"]);
|
||||
},
|
||||
|
||||
360
src/router.ts
360
src/router.ts
@ -1,4 +1,4 @@
|
||||
// @routes-hash 57463134da0d81d65d10c163ee8a2b26
|
||||
// @routes-hash 63d067de9d3f97b0602ef91a69334bc8
|
||||
import { Express } from "express";
|
||||
|
||||
import route1 from "./routes/agents/clearMemory";
|
||||
@ -14,94 +14,97 @@ import route10 from "./routes/assets/delAssets";
|
||||
import route11 from "./routes/assets/getAssetsApi";
|
||||
import route12 from "./routes/assets/getImage";
|
||||
import route13 from "./routes/assets/getMaterialData";
|
||||
import route14 from "./routes/assets/saveAssets";
|
||||
import route15 from "./routes/assets/updateAssets";
|
||||
import route16 from "./routes/assets/uploadClip";
|
||||
import route17 from "./routes/assetsGenerate/generateAssets";
|
||||
import route18 from "./routes/assetsGenerate/polishAssetsPrompt";
|
||||
import route19 from "./routes/cornerScape/getAllAssets";
|
||||
import route20 from "./routes/general/generalStatistics";
|
||||
import route21 from "./routes/general/getSingleProject";
|
||||
import route22 from "./routes/general/updateProject";
|
||||
import route23 from "./routes/login/login";
|
||||
import route24 from "./routes/migrate/migrateData";
|
||||
import route25 from "./routes/modelSelect/getModelDetail";
|
||||
import route26 from "./routes/modelSelect/getModelList";
|
||||
import route27 from "./routes/novel/addNovel";
|
||||
import route28 from "./routes/novel/batchDeleteNovel";
|
||||
import route29 from "./routes/novel/delNovel";
|
||||
import route30 from "./routes/novel/event/batchDeleteEvent";
|
||||
import route31 from "./routes/novel/event/deletEvent";
|
||||
import route32 from "./routes/novel/event/generateEvents";
|
||||
import route33 from "./routes/novel/event/getEvent";
|
||||
import route34 from "./routes/novel/getNovel";
|
||||
import route35 from "./routes/novel/getNovelEventState";
|
||||
import route36 from "./routes/novel/getNovelIndex";
|
||||
import route37 from "./routes/novel/updateNovel";
|
||||
import route38 from "./routes/other/deleteAllData";
|
||||
import route39 from "./routes/other/getVersion";
|
||||
import route40 from "./routes/production/assets/getAssetsData";
|
||||
import route41 from "./routes/production/editImage/generateFlowImage";
|
||||
import route42 from "./routes/production/editImage/getImageFlow";
|
||||
import route43 from "./routes/production/editImage/saveImageFlow";
|
||||
import route44 from "./routes/production/editImage/updateImageFlow";
|
||||
import route45 from "./routes/production/exportImage";
|
||||
import route46 from "./routes/production/getFlowData";
|
||||
import route47 from "./routes/production/getProductionData";
|
||||
import route48 from "./routes/production/getStoryboardData";
|
||||
import route49 from "./routes/production/saveFlowData";
|
||||
import route50 from "./routes/production/storyboard/downPreviewImage";
|
||||
import route51 from "./routes/production/storyboard/getStoryboardData";
|
||||
import route52 from "./routes/production/storyboard/previewImage";
|
||||
import route53 from "./routes/production/workbench/confirmSelection";
|
||||
import route54 from "./routes/production/workbench/delVideo";
|
||||
import route55 from "./routes/production/workbench/generateVideo";
|
||||
import route56 from "./routes/production/workbench/getChatLines";
|
||||
import route57 from "./routes/production/workbench/getVideoModelDetail";
|
||||
import route58 from "./routes/production/workbench/videoPolling";
|
||||
import route59 from "./routes/project/addProject";
|
||||
import route60 from "./routes/project/delProject";
|
||||
import route61 from "./routes/project/editProject";
|
||||
import route62 from "./routes/project/getProject";
|
||||
import route63 from "./routes/script/addScript";
|
||||
import route64 from "./routes/script/delScript";
|
||||
import route65 from "./routes/script/exportScript";
|
||||
import route66 from "./routes/script/extractAssets";
|
||||
import route67 from "./routes/script/getScrptApi";
|
||||
import route68 from "./routes/script/updateScript";
|
||||
import route69 from "./routes/scriptAgent/getPlanData";
|
||||
import route70 from "./routes/scriptAgent/setPlanData";
|
||||
import route71 from "./routes/setting/about/checkUpdate";
|
||||
import route72 from "./routes/setting/agentDeploy/agentSetKey";
|
||||
import route73 from "./routes/setting/agentDeploy/deployAgentModel";
|
||||
import route74 from "./routes/setting/agentDeploy/getAgentDeploy";
|
||||
import route75 from "./routes/setting/dbConfig/clearData";
|
||||
import route76 from "./routes/setting/dev/getSwitchAiDevTool";
|
||||
import route77 from "./routes/setting/dev/updateSwitchAiDevTool";
|
||||
import route78 from "./routes/setting/fileManagement/openFolder";
|
||||
import route79 from "./routes/setting/getTextModel";
|
||||
import route80 from "./routes/setting/loginConfig/getUser";
|
||||
import route81 from "./routes/setting/loginConfig/updateUserPwd";
|
||||
import route82 from "./routes/setting/memoryConfig/delAllMemory";
|
||||
import route83 from "./routes/setting/memoryConfig/getMemory";
|
||||
import route84 from "./routes/setting/memoryConfig/sureMemory";
|
||||
import route85 from "./routes/setting/skillManagement/addSkill";
|
||||
import route86 from "./routes/setting/skillManagement/deleteSkill";
|
||||
import route87 from "./routes/setting/skillManagement/embeddingSkill";
|
||||
import route88 from "./routes/setting/skillManagement/generateDescription";
|
||||
import route89 from "./routes/setting/skillManagement/getSkillList";
|
||||
import route90 from "./routes/setting/skillManagement/scanSkills";
|
||||
import route91 from "./routes/setting/skillManagement/updateSkill";
|
||||
import route92 from "./routes/setting/vendorConfig/addVendor";
|
||||
import route93 from "./routes/setting/vendorConfig/deleteVendor";
|
||||
import route94 from "./routes/setting/vendorConfig/getVendorList";
|
||||
import route95 from "./routes/setting/vendorConfig/modelTest";
|
||||
import route96 from "./routes/setting/vendorConfig/updateVendor";
|
||||
import route97 from "./routes/task/getProject";
|
||||
import route98 from "./routes/task/getTaskApi";
|
||||
import route99 from "./routes/task/getTaskCategories";
|
||||
import route100 from "./routes/task/taskDetails";
|
||||
import route101 from "./routes/test/test";
|
||||
import route14 from "./routes/assets/pollingImageAssets";
|
||||
import route15 from "./routes/assets/pollingPromptAssets";
|
||||
import route16 from "./routes/assets/saveAssets";
|
||||
import route17 from "./routes/assets/updateAssets";
|
||||
import route18 from "./routes/assets/uploadClip";
|
||||
import route19 from "./routes/assetsGenerate/generateAssets";
|
||||
import route20 from "./routes/assetsGenerate/polishAssetsPrompt";
|
||||
import route21 from "./routes/cornerScape/getAllAssets";
|
||||
import route22 from "./routes/general/generalStatistics";
|
||||
import route23 from "./routes/general/getSingleProject";
|
||||
import route24 from "./routes/general/updateProject";
|
||||
import route25 from "./routes/login/login";
|
||||
import route26 from "./routes/migrate/migrateData";
|
||||
import route27 from "./routes/modelSelect/getModelDetail";
|
||||
import route28 from "./routes/modelSelect/getModelList";
|
||||
import route29 from "./routes/novel/addNovel";
|
||||
import route30 from "./routes/novel/batchDeleteNovel";
|
||||
import route31 from "./routes/novel/delNovel";
|
||||
import route32 from "./routes/novel/event/batchDeleteEvent";
|
||||
import route33 from "./routes/novel/event/deletEvent";
|
||||
import route34 from "./routes/novel/event/generateEvents";
|
||||
import route35 from "./routes/novel/event/getEvent";
|
||||
import route36 from "./routes/novel/getNovel";
|
||||
import route37 from "./routes/novel/getNovelEventState";
|
||||
import route38 from "./routes/novel/getNovelIndex";
|
||||
import route39 from "./routes/novel/updateNovel";
|
||||
import route40 from "./routes/other/deleteAllData";
|
||||
import route41 from "./routes/other/getVersion";
|
||||
import route42 from "./routes/production/assets/getAssetsData";
|
||||
import route43 from "./routes/production/editImage/generateFlowImage";
|
||||
import route44 from "./routes/production/editImage/getImageFlow";
|
||||
import route45 from "./routes/production/editImage/saveImageFlow";
|
||||
import route46 from "./routes/production/editImage/updateImageFlow";
|
||||
import route47 from "./routes/production/exportImage";
|
||||
import route48 from "./routes/production/getFlowData";
|
||||
import route49 from "./routes/production/getProductionData";
|
||||
import route50 from "./routes/production/getStoryboardData";
|
||||
import route51 from "./routes/production/saveFlowData";
|
||||
import route52 from "./routes/production/storyboard/downPreviewImage";
|
||||
import route53 from "./routes/production/storyboard/getStoryboardData";
|
||||
import route54 from "./routes/production/storyboard/previewImage";
|
||||
import route55 from "./routes/production/workbench/confirmSelection";
|
||||
import route56 from "./routes/production/workbench/delVideo";
|
||||
import route57 from "./routes/production/workbench/generateVideo";
|
||||
import route58 from "./routes/production/workbench/getChatLines";
|
||||
import route59 from "./routes/production/workbench/getVideoModelDetail";
|
||||
import route60 from "./routes/production/workbench/videoPolling";
|
||||
import route61 from "./routes/project/addProject";
|
||||
import route62 from "./routes/project/delProject";
|
||||
import route63 from "./routes/project/editProject";
|
||||
import route64 from "./routes/project/getProject";
|
||||
import route65 from "./routes/script/addScript";
|
||||
import route66 from "./routes/script/delScript";
|
||||
import route67 from "./routes/script/exportScript";
|
||||
import route68 from "./routes/script/extractAssets";
|
||||
import route69 from "./routes/script/getScrptApi";
|
||||
import route70 from "./routes/script/updateScript";
|
||||
import route71 from "./routes/scriptAgent/getPlanData";
|
||||
import route72 from "./routes/scriptAgent/setPlanData";
|
||||
import route73 from "./routes/setting/about/checkUpdate";
|
||||
import route74 from "./routes/setting/agentDeploy/agentSetKey";
|
||||
import route75 from "./routes/setting/agentDeploy/deployAgentModel";
|
||||
import route76 from "./routes/setting/agentDeploy/getAgentDeploy";
|
||||
import route77 from "./routes/setting/dbConfig/clearData";
|
||||
import route78 from "./routes/setting/dev/getSwitchAiDevTool";
|
||||
import route79 from "./routes/setting/dev/updateSwitchAiDevTool";
|
||||
import route80 from "./routes/setting/fileManagement/openFolder";
|
||||
import route81 from "./routes/setting/getTextModel";
|
||||
import route82 from "./routes/setting/loginConfig/getUser";
|
||||
import route83 from "./routes/setting/loginConfig/updateUserPwd";
|
||||
import route84 from "./routes/setting/memoryConfig/delAllMemory";
|
||||
import route85 from "./routes/setting/memoryConfig/getMemory";
|
||||
import route86 from "./routes/setting/memoryConfig/sureMemory";
|
||||
import route87 from "./routes/setting/skillManagement/addSkill";
|
||||
import route88 from "./routes/setting/skillManagement/deleteSkill";
|
||||
import route89 from "./routes/setting/skillManagement/embeddingSkill";
|
||||
import route90 from "./routes/setting/skillManagement/generateDescription";
|
||||
import route91 from "./routes/setting/skillManagement/getSkillList";
|
||||
import route92 from "./routes/setting/skillManagement/scanSkills";
|
||||
import route93 from "./routes/setting/skillManagement/updateSkill";
|
||||
import route94 from "./routes/setting/vendorConfig/addVendor";
|
||||
import route95 from "./routes/setting/vendorConfig/deleteVendor";
|
||||
import route96 from "./routes/setting/vendorConfig/getVendorList";
|
||||
import route97 from "./routes/setting/vendorConfig/modelTest";
|
||||
import route98 from "./routes/setting/vendorConfig/updateCode";
|
||||
import route99 from "./routes/setting/vendorConfig/updateVendor";
|
||||
import route100 from "./routes/task/getProject";
|
||||
import route101 from "./routes/task/getTaskApi";
|
||||
import route102 from "./routes/task/getTaskCategories";
|
||||
import route103 from "./routes/task/taskDetails";
|
||||
import route104 from "./routes/test/test";
|
||||
|
||||
export default async (app: Express) => {
|
||||
app.use("/api/agents/clearMemory", route1);
|
||||
@ -117,92 +120,95 @@ export default async (app: Express) => {
|
||||
app.use("/api/assets/getAssetsApi", route11);
|
||||
app.use("/api/assets/getImage", route12);
|
||||
app.use("/api/assets/getMaterialData", route13);
|
||||
app.use("/api/assets/saveAssets", route14);
|
||||
app.use("/api/assets/updateAssets", route15);
|
||||
app.use("/api/assets/uploadClip", route16);
|
||||
app.use("/api/assetsGenerate/generateAssets", route17);
|
||||
app.use("/api/assetsGenerate/polishAssetsPrompt", route18);
|
||||
app.use("/api/cornerScape/getAllAssets", route19);
|
||||
app.use("/api/general/generalStatistics", route20);
|
||||
app.use("/api/general/getSingleProject", route21);
|
||||
app.use("/api/general/updateProject", route22);
|
||||
app.use("/api/login/login", route23);
|
||||
app.use("/api/migrate/migrateData", route24);
|
||||
app.use("/api/modelSelect/getModelDetail", route25);
|
||||
app.use("/api/modelSelect/getModelList", route26);
|
||||
app.use("/api/novel/addNovel", route27);
|
||||
app.use("/api/novel/batchDeleteNovel", route28);
|
||||
app.use("/api/novel/delNovel", route29);
|
||||
app.use("/api/novel/event/batchDeleteEvent", route30);
|
||||
app.use("/api/novel/event/deletEvent", route31);
|
||||
app.use("/api/novel/event/generateEvents", route32);
|
||||
app.use("/api/novel/event/getEvent", route33);
|
||||
app.use("/api/novel/getNovel", route34);
|
||||
app.use("/api/novel/getNovelEventState", route35);
|
||||
app.use("/api/novel/getNovelIndex", route36);
|
||||
app.use("/api/novel/updateNovel", route37);
|
||||
app.use("/api/other/deleteAllData", route38);
|
||||
app.use("/api/other/getVersion", route39);
|
||||
app.use("/api/production/assets/getAssetsData", route40);
|
||||
app.use("/api/production/editImage/generateFlowImage", route41);
|
||||
app.use("/api/production/editImage/getImageFlow", route42);
|
||||
app.use("/api/production/editImage/saveImageFlow", route43);
|
||||
app.use("/api/production/editImage/updateImageFlow", route44);
|
||||
app.use("/api/production/exportImage", route45);
|
||||
app.use("/api/production/getFlowData", route46);
|
||||
app.use("/api/production/getProductionData", route47);
|
||||
app.use("/api/production/getStoryboardData", route48);
|
||||
app.use("/api/production/saveFlowData", route49);
|
||||
app.use("/api/production/storyboard/downPreviewImage", route50);
|
||||
app.use("/api/production/storyboard/getStoryboardData", route51);
|
||||
app.use("/api/production/storyboard/previewImage", route52);
|
||||
app.use("/api/production/workbench/confirmSelection", route53);
|
||||
app.use("/api/production/workbench/delVideo", route54);
|
||||
app.use("/api/production/workbench/generateVideo", route55);
|
||||
app.use("/api/production/workbench/getChatLines", route56);
|
||||
app.use("/api/production/workbench/getVideoModelDetail", route57);
|
||||
app.use("/api/production/workbench/videoPolling", route58);
|
||||
app.use("/api/project/addProject", route59);
|
||||
app.use("/api/project/delProject", route60);
|
||||
app.use("/api/project/editProject", route61);
|
||||
app.use("/api/project/getProject", route62);
|
||||
app.use("/api/script/addScript", route63);
|
||||
app.use("/api/script/delScript", route64);
|
||||
app.use("/api/script/exportScript", route65);
|
||||
app.use("/api/script/extractAssets", route66);
|
||||
app.use("/api/script/getScrptApi", route67);
|
||||
app.use("/api/script/updateScript", route68);
|
||||
app.use("/api/scriptAgent/getPlanData", route69);
|
||||
app.use("/api/scriptAgent/setPlanData", route70);
|
||||
app.use("/api/setting/about/checkUpdate", route71);
|
||||
app.use("/api/setting/agentDeploy/agentSetKey", route72);
|
||||
app.use("/api/setting/agentDeploy/deployAgentModel", route73);
|
||||
app.use("/api/setting/agentDeploy/getAgentDeploy", route74);
|
||||
app.use("/api/setting/dbConfig/clearData", route75);
|
||||
app.use("/api/setting/dev/getSwitchAiDevTool", route76);
|
||||
app.use("/api/setting/dev/updateSwitchAiDevTool", route77);
|
||||
app.use("/api/setting/fileManagement/openFolder", route78);
|
||||
app.use("/api/setting/getTextModel", route79);
|
||||
app.use("/api/setting/loginConfig/getUser", route80);
|
||||
app.use("/api/setting/loginConfig/updateUserPwd", route81);
|
||||
app.use("/api/setting/memoryConfig/delAllMemory", route82);
|
||||
app.use("/api/setting/memoryConfig/getMemory", route83);
|
||||
app.use("/api/setting/memoryConfig/sureMemory", route84);
|
||||
app.use("/api/setting/skillManagement/addSkill", route85);
|
||||
app.use("/api/setting/skillManagement/deleteSkill", route86);
|
||||
app.use("/api/setting/skillManagement/embeddingSkill", route87);
|
||||
app.use("/api/setting/skillManagement/generateDescription", route88);
|
||||
app.use("/api/setting/skillManagement/getSkillList", route89);
|
||||
app.use("/api/setting/skillManagement/scanSkills", route90);
|
||||
app.use("/api/setting/skillManagement/updateSkill", route91);
|
||||
app.use("/api/setting/vendorConfig/addVendor", route92);
|
||||
app.use("/api/setting/vendorConfig/deleteVendor", route93);
|
||||
app.use("/api/setting/vendorConfig/getVendorList", route94);
|
||||
app.use("/api/setting/vendorConfig/modelTest", route95);
|
||||
app.use("/api/setting/vendorConfig/updateVendor", route96);
|
||||
app.use("/api/task/getProject", route97);
|
||||
app.use("/api/task/getTaskApi", route98);
|
||||
app.use("/api/task/getTaskCategories", route99);
|
||||
app.use("/api/task/taskDetails", route100);
|
||||
app.use("/api/test/test", route101);
|
||||
app.use("/api/assets/pollingImageAssets", route14);
|
||||
app.use("/api/assets/pollingPromptAssets", route15);
|
||||
app.use("/api/assets/saveAssets", route16);
|
||||
app.use("/api/assets/updateAssets", route17);
|
||||
app.use("/api/assets/uploadClip", route18);
|
||||
app.use("/api/assetsGenerate/generateAssets", route19);
|
||||
app.use("/api/assetsGenerate/polishAssetsPrompt", route20);
|
||||
app.use("/api/cornerScape/getAllAssets", route21);
|
||||
app.use("/api/general/generalStatistics", route22);
|
||||
app.use("/api/general/getSingleProject", route23);
|
||||
app.use("/api/general/updateProject", route24);
|
||||
app.use("/api/login/login", route25);
|
||||
app.use("/api/migrate/migrateData", route26);
|
||||
app.use("/api/modelSelect/getModelDetail", route27);
|
||||
app.use("/api/modelSelect/getModelList", route28);
|
||||
app.use("/api/novel/addNovel", route29);
|
||||
app.use("/api/novel/batchDeleteNovel", route30);
|
||||
app.use("/api/novel/delNovel", route31);
|
||||
app.use("/api/novel/event/batchDeleteEvent", route32);
|
||||
app.use("/api/novel/event/deletEvent", route33);
|
||||
app.use("/api/novel/event/generateEvents", route34);
|
||||
app.use("/api/novel/event/getEvent", route35);
|
||||
app.use("/api/novel/getNovel", route36);
|
||||
app.use("/api/novel/getNovelEventState", route37);
|
||||
app.use("/api/novel/getNovelIndex", route38);
|
||||
app.use("/api/novel/updateNovel", route39);
|
||||
app.use("/api/other/deleteAllData", route40);
|
||||
app.use("/api/other/getVersion", route41);
|
||||
app.use("/api/production/assets/getAssetsData", route42);
|
||||
app.use("/api/production/editImage/generateFlowImage", route43);
|
||||
app.use("/api/production/editImage/getImageFlow", route44);
|
||||
app.use("/api/production/editImage/saveImageFlow", route45);
|
||||
app.use("/api/production/editImage/updateImageFlow", route46);
|
||||
app.use("/api/production/exportImage", route47);
|
||||
app.use("/api/production/getFlowData", route48);
|
||||
app.use("/api/production/getProductionData", route49);
|
||||
app.use("/api/production/getStoryboardData", route50);
|
||||
app.use("/api/production/saveFlowData", route51);
|
||||
app.use("/api/production/storyboard/downPreviewImage", route52);
|
||||
app.use("/api/production/storyboard/getStoryboardData", route53);
|
||||
app.use("/api/production/storyboard/previewImage", route54);
|
||||
app.use("/api/production/workbench/confirmSelection", route55);
|
||||
app.use("/api/production/workbench/delVideo", route56);
|
||||
app.use("/api/production/workbench/generateVideo", route57);
|
||||
app.use("/api/production/workbench/getChatLines", route58);
|
||||
app.use("/api/production/workbench/getVideoModelDetail", route59);
|
||||
app.use("/api/production/workbench/videoPolling", route60);
|
||||
app.use("/api/project/addProject", route61);
|
||||
app.use("/api/project/delProject", route62);
|
||||
app.use("/api/project/editProject", route63);
|
||||
app.use("/api/project/getProject", route64);
|
||||
app.use("/api/script/addScript", route65);
|
||||
app.use("/api/script/delScript", route66);
|
||||
app.use("/api/script/exportScript", route67);
|
||||
app.use("/api/script/extractAssets", route68);
|
||||
app.use("/api/script/getScrptApi", route69);
|
||||
app.use("/api/script/updateScript", route70);
|
||||
app.use("/api/scriptAgent/getPlanData", route71);
|
||||
app.use("/api/scriptAgent/setPlanData", route72);
|
||||
app.use("/api/setting/about/checkUpdate", route73);
|
||||
app.use("/api/setting/agentDeploy/agentSetKey", route74);
|
||||
app.use("/api/setting/agentDeploy/deployAgentModel", route75);
|
||||
app.use("/api/setting/agentDeploy/getAgentDeploy", route76);
|
||||
app.use("/api/setting/dbConfig/clearData", route77);
|
||||
app.use("/api/setting/dev/getSwitchAiDevTool", route78);
|
||||
app.use("/api/setting/dev/updateSwitchAiDevTool", route79);
|
||||
app.use("/api/setting/fileManagement/openFolder", route80);
|
||||
app.use("/api/setting/getTextModel", route81);
|
||||
app.use("/api/setting/loginConfig/getUser", route82);
|
||||
app.use("/api/setting/loginConfig/updateUserPwd", route83);
|
||||
app.use("/api/setting/memoryConfig/delAllMemory", route84);
|
||||
app.use("/api/setting/memoryConfig/getMemory", route85);
|
||||
app.use("/api/setting/memoryConfig/sureMemory", route86);
|
||||
app.use("/api/setting/skillManagement/addSkill", route87);
|
||||
app.use("/api/setting/skillManagement/deleteSkill", route88);
|
||||
app.use("/api/setting/skillManagement/embeddingSkill", route89);
|
||||
app.use("/api/setting/skillManagement/generateDescription", route90);
|
||||
app.use("/api/setting/skillManagement/getSkillList", route91);
|
||||
app.use("/api/setting/skillManagement/scanSkills", route92);
|
||||
app.use("/api/setting/skillManagement/updateSkill", route93);
|
||||
app.use("/api/setting/vendorConfig/addVendor", route94);
|
||||
app.use("/api/setting/vendorConfig/deleteVendor", route95);
|
||||
app.use("/api/setting/vendorConfig/getVendorList", route96);
|
||||
app.use("/api/setting/vendorConfig/modelTest", route97);
|
||||
app.use("/api/setting/vendorConfig/updateCode", route98);
|
||||
app.use("/api/setting/vendorConfig/updateVendor", route99);
|
||||
app.use("/api/task/getProject", route100);
|
||||
app.use("/api/task/getTaskApi", route101);
|
||||
app.use("/api/task/getTaskCategories", route102);
|
||||
app.use("/api/task/taskDetails", route103);
|
||||
app.use("/api/test/test", route104);
|
||||
}
|
||||
|
||||
@ -21,7 +21,7 @@ export default router.post(
|
||||
let query = u
|
||||
.db("o_assets")
|
||||
.leftJoin("o_image", "o_assets.imageId", "o_image.id")
|
||||
.select("o_assets.*", "o_image.filePath")
|
||||
.select("o_assets.*", "o_image.filePath", "o_image.state")
|
||||
.where("o_assets.projectId", projectId)
|
||||
.andWhere("o_assets.type", type);
|
||||
if (name) {
|
||||
@ -34,7 +34,7 @@ export default router.post(
|
||||
let childQuery = u
|
||||
.db("o_assets")
|
||||
.leftJoin("o_image", "o_assets.imageId", "o_image.id")
|
||||
.select("o_assets.*", "o_image.filePath")
|
||||
.select("o_assets.*", "o_image.filePath", "o_image.state")
|
||||
.where("o_assets.projectId", projectId)
|
||||
.andWhere("o_assets.type", type)
|
||||
.whereNotNull("o_assets.assetsId");
|
||||
|
||||
28
src/routes/assets/pollingImageAssets.ts
Normal file
28
src/routes/assets/pollingImageAssets.ts
Normal file
@ -0,0 +1,28 @@
|
||||
import express from "express";
|
||||
import u from "@/utils";
|
||||
import { z } from "zod";
|
||||
import { success } from "@/lib/responseFormat";
|
||||
import { validateFields } from "@/middleware/middleware";
|
||||
const router = express.Router();
|
||||
|
||||
export default router.post(
|
||||
"/",
|
||||
validateFields({
|
||||
ids: z.array(z.number()),
|
||||
}),
|
||||
async (req, res) => {
|
||||
const { ids } = req.body;
|
||||
const data = await u
|
||||
.db("o_assets")
|
||||
.leftJoin("o_image", "o_assets.id", "o_image.assetsId")
|
||||
.whereIn("o_assets.id", ids)
|
||||
.select("o_image.state", "o_assets.id", "o_image.filePath");
|
||||
const result = await Promise.all(
|
||||
data.map(async (item: any) => ({
|
||||
...item,
|
||||
filePath: item.filePath ? await u.oss.getFileUrl(item.filePath) : null,
|
||||
})),
|
||||
);
|
||||
res.status(200).send(success(result));
|
||||
},
|
||||
);
|
||||
18
src/routes/assets/pollingPromptAssets.ts
Normal file
18
src/routes/assets/pollingPromptAssets.ts
Normal file
@ -0,0 +1,18 @@
|
||||
import express from "express";
|
||||
import u from "@/utils";
|
||||
import { z } from "zod";
|
||||
import { success } from "@/lib/responseFormat";
|
||||
import { validateFields } from "@/middleware/middleware";
|
||||
const router = express.Router();
|
||||
|
||||
export default router.post(
|
||||
"/",
|
||||
validateFields({
|
||||
ids: z.array(z.number()),
|
||||
}),
|
||||
async (req, res) => {
|
||||
const { ids } = req.body;
|
||||
const data = await u.db("o_assets").whereIn("id", ids).select("*");
|
||||
res.status(200).send(success(data));
|
||||
},
|
||||
);
|
||||
@ -33,7 +33,7 @@ export default router.post(
|
||||
assetsId: id,
|
||||
filePath: savePath,
|
||||
type: type,
|
||||
state: "生成成功",
|
||||
state: "已完成",
|
||||
});
|
||||
// 更新资产表图片为新图片
|
||||
await u
|
||||
|
||||
@ -50,7 +50,7 @@ export default router.post(
|
||||
filePath: savePath,
|
||||
type,
|
||||
assetsId: id,
|
||||
state: "1",
|
||||
state: '已完成',
|
||||
});
|
||||
await u.db("o_assets").where("id", id).update({
|
||||
imageId: imageId,
|
||||
|
||||
@ -87,6 +87,7 @@ export default router.post("/", validateFields(requestSchema), async (req, res)
|
||||
state: "生成中",
|
||||
assetsId: id,
|
||||
});
|
||||
await u.db("o_assets").where("id", id).update({ imageId });
|
||||
|
||||
// 3. 准备生成参数
|
||||
const imagePath = `/${projectId}/${cfg.dir}/${uuidv4()}.jpg`;
|
||||
@ -106,7 +107,7 @@ export default router.post("/", validateFields(requestSchema), async (req, res)
|
||||
describe,
|
||||
projectId,
|
||||
relatedObjects: JSON.stringify(relatedObjects),
|
||||
});
|
||||
})
|
||||
aiImage.save(imagePath);
|
||||
|
||||
// 5. 更新记录 & 返回结果
|
||||
@ -114,7 +115,7 @@ export default router.post("/", validateFields(requestSchema), async (req, res)
|
||||
if (!imageData) return res.status(500).send("资产已被删除");
|
||||
|
||||
await u.db("o_image").where("id", imageId).update({
|
||||
state: "生成成功",
|
||||
state: "已完成",
|
||||
filePath: imagePath,
|
||||
type,
|
||||
model: model.split(":")[1],
|
||||
|
||||
@ -61,6 +61,7 @@ export default router.post(
|
||||
if (!project) return res.status(500).send(success({ message: "项目为空" }));
|
||||
|
||||
const allOutlineDataList: { data: string }[] = await u.db("o_outline").where("projectId", projectId).select("data");
|
||||
await u.db("o_assets").where("id", assetsId).update({ promptState: "生成中" });
|
||||
|
||||
const itemMap: Record<string, ResultItem> = {};
|
||||
|
||||
@ -124,7 +125,7 @@ export default router.post(
|
||||
})) as any;
|
||||
|
||||
if (!_output) return res.status(500).send("失败");
|
||||
await u.db("o_assets").where("id", assetsId).update({ prompt: _output });
|
||||
await u.db("o_assets").where("id", assetsId).update({ prompt: _output, promptState: "已完成" });
|
||||
|
||||
res.status(200).send(success({ prompt: _output, assetsId }));
|
||||
} catch (e: any) {
|
||||
|
||||
@ -12,32 +12,24 @@ export default router.post(
|
||||
}),
|
||||
async (req, res) => {
|
||||
const { type } = req.body;
|
||||
const data = await u.db("o_vendorConfig").select("id", "models", "name").first();
|
||||
if (!data) {
|
||||
const dataList = await u.db("o_vendorConfig").select("id", "models", "name");
|
||||
if (!dataList || dataList.length === 0) {
|
||||
return res.status(404).send({ error: "模型未找到" });
|
||||
}
|
||||
const models = JSON.parse(data.models!);
|
||||
if (type === "all") {
|
||||
const allData = models
|
||||
.filter((item: { type: string }) => item.type !== "video")
|
||||
.map((item: { name: string; modelName: string; type: string }) => ({
|
||||
id: data.id,
|
||||
label: item.name,
|
||||
value: item.modelName,
|
||||
type: item.type,
|
||||
name: data.name,
|
||||
}));
|
||||
return res.status(200).send(success(allData));
|
||||
}
|
||||
const filteredData = models
|
||||
.filter((item: { type: string }) => item.type === type)
|
||||
.map((item: { name: string; modelName: string; type: string }) => ({
|
||||
const result = dataList.flatMap((data) => {
|
||||
const models = JSON.parse(data.models!);
|
||||
const filtered =
|
||||
type === "all"
|
||||
? models.filter((item: { type: string }) => item.type !== "video")
|
||||
: models.filter((item: { type: string }) => item.type === type);
|
||||
return filtered.map((item: { name: string; modelName: string; type: string }) => ({
|
||||
id: data.id,
|
||||
label: item.name,
|
||||
value: item.modelName,
|
||||
type: item.type,
|
||||
name: data.name,
|
||||
}));
|
||||
res.status(200).send(success(filteredData));
|
||||
});
|
||||
res.status(200).send(success(result));
|
||||
},
|
||||
);
|
||||
|
||||
@ -2,10 +2,10 @@ import express from "express";
|
||||
import u from "@/utils";
|
||||
import { z } from "zod";
|
||||
import { error, success } from "@/lib/responseFormat";
|
||||
import compressing from "compressing";
|
||||
import { validateFields } from "@/middleware/middleware";
|
||||
import { useSkill } from "@/utils/agent/skillsTools";
|
||||
import { Output, tool } from "ai";
|
||||
import { tool } from "ai";
|
||||
import { o_script } from "@/types/database";
|
||||
|
||||
const router = express.Router();
|
||||
export const AssetSchema = z.object({
|
||||
@ -14,79 +14,166 @@ export const AssetSchema = z.object({
|
||||
desc: z.string().describe("资产描述"),
|
||||
type: z.enum(["role", "tool", "scene"]).describe("资产类型"),
|
||||
});
|
||||
|
||||
type Asset = z.infer<typeof AssetSchema>;
|
||||
|
||||
/** 控制并发的辅助函数 */
|
||||
async function pMap<T, R>(items: T[], fn: (item: T) => Promise<R>, concurrency: number): Promise<R[]> {
|
||||
const results: R[] = [];
|
||||
let index = 0;
|
||||
async function worker() {
|
||||
while (index < items.length) {
|
||||
const i = index++;
|
||||
results[i] = await fn(items[i]);
|
||||
}
|
||||
}
|
||||
await Promise.all(Array.from({ length: Math.min(concurrency, items.length) }, () => worker()));
|
||||
return results;
|
||||
}
|
||||
|
||||
export default router.post(
|
||||
"/",
|
||||
validateFields({
|
||||
scriptIds: z.array(z.number()),
|
||||
projectId: z.number(),
|
||||
concurrency: z.number().min(1).max(20).optional(),
|
||||
}),
|
||||
async (req, res) => {
|
||||
const { scriptIds, projectId } = req.body;
|
||||
const { scriptIds, projectId, concurrency = 3 } = req.body;
|
||||
if (!scriptIds.length) return res.status(400).send(error("请先选择剧本"));
|
||||
const scripts = await u.db("o_script").whereIn("id", scriptIds);
|
||||
const intansce = u.Ai.Text("universalAgent");
|
||||
const novelData = await u.db("o_novel").where("projectId", projectId).select("chapterData");
|
||||
if (!novelData || novelData.length === 0) return res.status(400).send(error("请先上传小说"));
|
||||
|
||||
async function getAssets() {
|
||||
return await u.db("o_assets").where("projectId", projectId).select("id", "name");
|
||||
}
|
||||
for (const scriptId of scriptIds) {
|
||||
const resultTool = tool({
|
||||
description: "返回结果时必须调用这个工具,",
|
||||
inputSchema: z.object({
|
||||
assetsList: z.array(AssetSchema).describe("剧本所使用资产列表,注意不要包含剧本内容,仅为所使用到的 道具、人物、场景、素材"),
|
||||
}),
|
||||
execute: async ({ assetsList }) => {
|
||||
console.log("[tools] set_flowData script", assetsList);
|
||||
if (assetsList && assetsList.length) {
|
||||
const assetId = [];
|
||||
const existingAssets = await getAssets();
|
||||
for (const i of assetsList) {
|
||||
if (existingAssets.length) {
|
||||
const exist = existingAssets.find((j) => j.name === i.name);
|
||||
if (exist) {
|
||||
assetId.push(exist.id);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
const [id] = await u.db("o_assets").insert({
|
||||
name: i.name,
|
||||
prompt: i.prompt,
|
||||
type: i.type,
|
||||
describe: i.desc,
|
||||
projectId: projectId,
|
||||
startTime: Date.now(),
|
||||
});
|
||||
assetId.push(id);
|
||||
}
|
||||
// 每个 scriptId 对应提取出的资产列表
|
||||
const scriptAssetsMap = new Map<number, Asset[]>();
|
||||
|
||||
await u.db("o_scriptAssets").insert(assetId.map((i) => ({ scriptId: scriptId, assetId: i })));
|
||||
}
|
||||
return true;
|
||||
},
|
||||
});
|
||||
try {
|
||||
const skill = await useSkill("universal_agent.md");
|
||||
const resData = await intansce.invoke({
|
||||
messages: [
|
||||
{
|
||||
role: "system",
|
||||
content:
|
||||
skill.prompt +
|
||||
"\n\n提取剧本中涉及的资产(角色、场景、道具),参考技能 script_assets_extract 规范,结果必须通过 resultTool 工具返回。",
|
||||
},
|
||||
{
|
||||
role: "user",
|
||||
content: `请根据以下剧本提取对应的剧本资产(角色、场景、道具、素材片段):\n\n${scripts.map((i) => i.content).join("\n\n---\n\n")}`,
|
||||
},
|
||||
],
|
||||
tools: { ...skill.tools, resultTool },
|
||||
// 构建 scriptId -> script 内容的映射
|
||||
const scriptMap = new Map(scripts.map((s: o_script) => [s.id, s]));
|
||||
|
||||
const errors: { scriptId: number; error: string }[] = [];
|
||||
|
||||
// 并发提取所有剧本的资产,每个剧本单独跑一次 AI
|
||||
await pMap(
|
||||
scriptIds,
|
||||
async (scriptId: number) => {
|
||||
const script = scriptMap.get(scriptId);
|
||||
if (!script) {
|
||||
errors.push({ scriptId, error: "未找到对应剧本" });
|
||||
return;
|
||||
}
|
||||
|
||||
// 用闭包收集当前 scriptId 的资产
|
||||
let collected: Asset[] = [];
|
||||
|
||||
const resultTool = tool({
|
||||
description: "返回结果时必须调用这个工具,",
|
||||
inputSchema: z.object({
|
||||
assetsList: z.array(AssetSchema).describe("剧本所使用资产列表,注意不要包含剧本内容,仅为所使用到的 道具、人物、场景、素材"),
|
||||
}),
|
||||
execute: async ({ assetsList }) => {
|
||||
console.log("[tools] set_flowData script", assetsList);
|
||||
if (assetsList && assetsList.length) {
|
||||
collected = assetsList;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
});
|
||||
console.log("%c Line:47 🥝 resData", "background:#2eafb0", resData);
|
||||
} catch (e) {
|
||||
console.log("%c Line:52 🍢 e", "background:#42b983", e);
|
||||
|
||||
try {
|
||||
const skill = await useSkill("universal_agent.md");
|
||||
await intansce.invoke({
|
||||
messages: [
|
||||
{
|
||||
role: "system",
|
||||
content:
|
||||
skill.prompt +
|
||||
"\n\n提取剧本中涉及的资产(角色、场景、道具),参考技能 script_assets_extract 规范,结果必须通过 resultTool 工具返回。",
|
||||
},
|
||||
{
|
||||
role: "user",
|
||||
content: `请根据以下剧本提取对应的剧本资产(角色、场景、道具、素材片段):\n\n${script.content}`,
|
||||
},
|
||||
],
|
||||
tools: { ...skill.tools, resultTool },
|
||||
});
|
||||
} catch (e: any) {
|
||||
const msg = e?.message || String(e);
|
||||
console.error(`[extractAssets] scriptId=${scriptId} name=${script.name} 提取失败:`, msg);
|
||||
errors.push({ scriptId, error: script.name + ":" + u.error(e).message });
|
||||
return;
|
||||
}
|
||||
|
||||
if (!collected.length) {
|
||||
errors.push({ scriptId, error: "AI 未返回任何资产" });
|
||||
return;
|
||||
}
|
||||
|
||||
scriptAssetsMap.set(scriptId, collected);
|
||||
},
|
||||
concurrency,
|
||||
);
|
||||
|
||||
// 如果全部失败,直接返回错误
|
||||
if (!scriptAssetsMap.size) {
|
||||
return res.status(500).send(error("所有剧本资产提取均失败", errors));
|
||||
}
|
||||
|
||||
// 按 name 合并所有资产,同名资产只保留第一个
|
||||
const mergedAssetsMap = new Map<string, Asset>();
|
||||
// 同时记录每个资产名称关联的 scriptId 列表
|
||||
const assetScriptIds = new Map<string, number[]>();
|
||||
|
||||
for (const [scriptId, assets] of scriptAssetsMap) {
|
||||
for (const asset of assets) {
|
||||
if (!mergedAssetsMap.has(asset.name)) {
|
||||
mergedAssetsMap.set(asset.name, asset);
|
||||
}
|
||||
const ids = assetScriptIds.get(asset.name) || [];
|
||||
ids.push(scriptId);
|
||||
assetScriptIds.set(asset.name, ids);
|
||||
}
|
||||
}
|
||||
|
||||
// 一次性查询数据库中已有的资产
|
||||
const existingAssets = await u.db("o_assets").where("projectId", projectId).select("id", "name");
|
||||
const existingMap = new Map(existingAssets.map((a) => [a.name!, a.id!]));
|
||||
|
||||
// 批量插入不存在的资产
|
||||
const toInsert = [...mergedAssetsMap.values()].filter((asset) => !existingMap.has(asset.name));
|
||||
if (toInsert.length) {
|
||||
await u.db("o_assets").insert(
|
||||
toInsert.map((asset) => ({
|
||||
name: asset.name,
|
||||
prompt: asset.prompt,
|
||||
type: asset.type,
|
||||
describe: asset.desc,
|
||||
projectId: projectId,
|
||||
startTime: Date.now(),
|
||||
})),
|
||||
);
|
||||
}
|
||||
|
||||
// 重新查询所有资产,获取完整的 name -> id 映射
|
||||
const allAssets = await u.db("o_assets").where("projectId", projectId).select("id", "name");
|
||||
const nameToId = new Map(allAssets.map((a) => [a.name, a.id]));
|
||||
|
||||
// 批量建立 scriptId <-> assetId 的关联
|
||||
const scriptAssetRows: { scriptId: number; assetId: number }[] = [];
|
||||
for (const [name, sIds] of assetScriptIds) {
|
||||
const assetId = nameToId.get(name);
|
||||
if (assetId) {
|
||||
for (const sid of sIds) {
|
||||
scriptAssetRows.push({ scriptId: sid, assetId });
|
||||
}
|
||||
}
|
||||
}
|
||||
await u.db("o_scriptAssets").whereIn("scriptId", scriptIds).delete();
|
||||
if (scriptAssetRows.length) {
|
||||
await u.db("o_scriptAssets").insert(scriptAssetRows);
|
||||
}
|
||||
|
||||
return res.send(success(errors.length ? `部分剧本资产提取失败\n${errors.map((i) => i.error).join("\n")}` : "资产提取完成"));
|
||||
},
|
||||
);
|
||||
|
||||
@ -23,11 +23,11 @@ export default router.post("/", async (req, res) => {
|
||||
const currentVersionList = APP_VERSION.split(".").map(Number);
|
||||
//对比Major
|
||||
if (taggerList[0] > currentVersionList[0]) {
|
||||
return res.status(200).send(success({ needUpdate: true, latestVersion: tagger, reinstall: true }));
|
||||
return res.status(200).send(success({ needUpdate: true, latestVersion: tagger, reinstall: false }));
|
||||
}
|
||||
//对比Minor
|
||||
if (taggerList[1] > currentVersionList[1]) {
|
||||
return res.status(200).send(success({ needUpdate: true, latestVersion: tagger, reinstall: true }));
|
||||
return res.status(200).send(success({ needUpdate: true, latestVersion: tagger, reinstall: false }));
|
||||
}
|
||||
//Patch
|
||||
if (taggerList[2] > currentVersionList[2]) {
|
||||
|
||||
@ -14,7 +14,7 @@ export default router.post(
|
||||
const { id } = req.body;
|
||||
await u.db("o_agentDeploy").whereIn("id", id).where("disabled", "<>", 1).update({
|
||||
model: "gpt-4.1",
|
||||
modelName: "1:gpt-4.1",
|
||||
modelName: "toonflow:gpt-4.1",
|
||||
vendorId: 1,
|
||||
});
|
||||
res.status(200).send(success("配置成功"));
|
||||
|
||||
@ -5,15 +5,19 @@ import { z } from "zod";
|
||||
import { validateFields } from "@/middleware/middleware";
|
||||
const router = express.Router();
|
||||
|
||||
export default router.post("/", validateFields({
|
||||
export default router.post(
|
||||
"/",
|
||||
validateFields({
|
||||
id: z.number(),
|
||||
name: z.string(),
|
||||
model: z.string(),
|
||||
modelName: z.string(),
|
||||
vendorId: z.number().nullable(),
|
||||
desc: z.string(),
|
||||
}), async (req, res) => {
|
||||
}),
|
||||
async (req, res) => {
|
||||
const { id, name, model, modelName, vendorId, desc } = req.body;
|
||||
await u.db("o_agentDeploy").where({ id }).update({ id, name, model, modelName, vendorId, desc });
|
||||
res.status(200).send(success("配置成功"));
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
@ -76,7 +76,6 @@ export default router.post(
|
||||
for await (const chunk of textStream) {
|
||||
fullResponse += chunk;
|
||||
}
|
||||
console.log("%c Line:78 🥝 fullResponse", "background:#ea7e5c", fullResponse);
|
||||
res.status(200).send(success(fullResponse));
|
||||
} else {
|
||||
const aiTypeFn = {
|
||||
|
||||
115
src/routes/setting/vendorConfig/updateCode.ts
Normal file
115
src/routes/setting/vendorConfig/updateCode.ts
Normal file
@ -0,0 +1,115 @@
|
||||
import express from "express";
|
||||
import { serializeError } from "serialize-error";
|
||||
import { success, error } from "@/lib/responseFormat";
|
||||
import { validateFields } from "@/middleware/middleware";
|
||||
import u from "@/utils";
|
||||
import { z } from "zod";
|
||||
import { transform } from "sucrase";
|
||||
const router = express.Router();
|
||||
|
||||
const vendorConfigSchema = z.object({
|
||||
id: z.string(),
|
||||
author: z.string(),
|
||||
description: z.string().optional(),
|
||||
name: z.string(),
|
||||
icon: z.string().optional(),
|
||||
inputs: z.array(
|
||||
z.object({
|
||||
key: z.string(),
|
||||
label: z.string(),
|
||||
type: z.enum(["text", "password", "url"]),
|
||||
required: z.boolean(),
|
||||
placeholder: z.string().optional(),
|
||||
}),
|
||||
),
|
||||
inputValues: z.record(z.string(), z.string()),
|
||||
models: z.array(
|
||||
z.discriminatedUnion("type", [
|
||||
z.object({
|
||||
name: z.string(),
|
||||
modelName: z.string(),
|
||||
type: z.literal("text"),
|
||||
multimodal: z.boolean(),
|
||||
tool: z.boolean(),
|
||||
}),
|
||||
z.object({
|
||||
name: z.string(),
|
||||
modelName: z.string(),
|
||||
type: z.literal("image"),
|
||||
mode: z.array(z.enum(["text", "singleImage", "multiReference"])),
|
||||
}),
|
||||
z.object({
|
||||
name: z.string(),
|
||||
modelName: z.string(),
|
||||
type: z.literal("video"),
|
||||
mode: z.array(
|
||||
z.union([
|
||||
z.enum([
|
||||
"singleImage",
|
||||
"multiImage",
|
||||
"gridImage",
|
||||
"startEndRequired",
|
||||
"endFrameOptional",
|
||||
"startFrameOptional",
|
||||
"text",
|
||||
"audioReference",
|
||||
"videoReference",
|
||||
]),
|
||||
z.array(z.enum(["video", "image", "audio", "text"])),
|
||||
]),
|
||||
),
|
||||
audio: z.union([z.literal("optional"), z.boolean()]),
|
||||
durationResolutionMap: z.array(
|
||||
z.object({
|
||||
duration: z.array(z.number()),
|
||||
resolution: z.array(z.string()),
|
||||
}),
|
||||
),
|
||||
}),
|
||||
]),
|
||||
),
|
||||
});
|
||||
|
||||
export default router.post(
|
||||
"/",
|
||||
validateFields({
|
||||
id: z.string(),
|
||||
tsCode: z.string(),
|
||||
}),
|
||||
async (req, res) => {
|
||||
try {
|
||||
const { tsCode, id } = req.body;
|
||||
const jsCode = transform(tsCode, { transforms: ["typescript"] }).code;
|
||||
const exports = u.vm(jsCode);
|
||||
if (!exports) return res.status(400).send(success("脚本文件必须导出对象"));
|
||||
if (!exports.textRequest) return res.status(400).send(success("脚本文件必须导出文本请求对象"));
|
||||
if (!exports.imageRequest) return res.status(400).send(success("脚本文件必须导出图像请求对象"));
|
||||
if (!exports.videoRequest) return res.status(400).send(success("脚本文件必须导出视频请求对象"));
|
||||
if (!exports.vendor) return res.status(400).send(success("脚本文件必须导出vendor对象"));
|
||||
const vendor = exports.vendor;
|
||||
const result = vendorConfigSchema.safeParse(vendor);
|
||||
if (!result.success) {
|
||||
const errorMsg = result.error.issues.map((e) => `${e.path.join(".")}: ${e.message}`).join("; ");
|
||||
return res.status(400).send(error(`vendor配置校验失败: ${errorMsg}`));
|
||||
}
|
||||
await u
|
||||
.db("o_vendorConfig")
|
||||
.where("id", id)
|
||||
.update({
|
||||
author: vendor.author,
|
||||
description: vendor.description || "",
|
||||
name: vendor.name,
|
||||
icon: vendor.icon || "",
|
||||
inputs: JSON.stringify(vendor.inputs ?? []),
|
||||
inputValues: JSON.stringify(vendor.inputValues ?? {}),
|
||||
models: JSON.stringify(vendor.models ?? []),
|
||||
code: tsCode,
|
||||
createTime: Date.now(),
|
||||
});
|
||||
res.status(200).send(success(result.data));
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
res.status(400).send(error(serializeError(err).message || "未知错误"));
|
||||
}
|
||||
},
|
||||
);
|
||||
@ -158,14 +158,6 @@ export default router.post(
|
||||
return code.slice(0, valueStart) + newValue + code.slice(valueEnd + 1);
|
||||
};
|
||||
|
||||
// 替换 tsCode 中指定 key 的字符串/数字值(如 name: "xxx" 或 version: 1)
|
||||
const replacePrimitiveValue = (code: string, key: string, newValue: string | number): string => {
|
||||
return code.replace(
|
||||
new RegExp(`(\\b${key}\\s*:\\s*)(?:"[^"]*"|'[^']*'|\\d+)`),
|
||||
(_, prefix) => `${prefix}${typeof newValue === "string" ? JSON.stringify(newValue) : newValue}`,
|
||||
);
|
||||
};
|
||||
|
||||
let updatedTsCode = tsCode;
|
||||
updatedTsCode = replaceBlockValue(updatedTsCode, "inputs", JSON.stringify(inputs ?? vendor.inputs, null, 2));
|
||||
updatedTsCode = replaceBlockValue(updatedTsCode, "inputValues", JSON.stringify(inputValues ?? vendor.inputValues, null, 2));
|
||||
|
||||
8
src/types/database.d.ts
vendored
8
src/types/database.d.ts
vendored
@ -1,4 +1,4 @@
|
||||
// @db-hash e933f0aef750ba14e50c72aab5b6eeb7
|
||||
// @db-hash 8e5f2b7a28d4494b291d802b055b6399
|
||||
//该文件由脚本自动生成,请勿手动修改
|
||||
|
||||
export interface memories {
|
||||
@ -118,6 +118,11 @@ export interface o_project {
|
||||
'videoModel'?: string | null;
|
||||
'videoRatio'?: string | null;
|
||||
}
|
||||
export interface o_prompt {
|
||||
'id'?: number;
|
||||
'name'?: string | null;
|
||||
'rompt'?: string | null;
|
||||
}
|
||||
export interface o_script {
|
||||
'content'?: string | null;
|
||||
'createTime'?: number | null;
|
||||
@ -236,6 +241,7 @@ export interface DB {
|
||||
"o_outline": o_outline;
|
||||
"o_outlineNovel": o_outlineNovel;
|
||||
"o_project": o_project;
|
||||
"o_prompt": o_prompt;
|
||||
"o_script": o_script;
|
||||
"o_scriptAssets": o_scriptAssets;
|
||||
"o_setting": o_setting;
|
||||
|
||||
@ -8,6 +8,7 @@ import getPath from "@/utils/getPath";
|
||||
import vm from "@/utils/vm";
|
||||
import task from "@/utils/taskRecord";
|
||||
import Ai from "@/utils/ai";
|
||||
import { getPrompts } from "@/utils/getPrompts";
|
||||
|
||||
export default {
|
||||
db,
|
||||
@ -20,4 +21,5 @@ export default {
|
||||
getPath,
|
||||
Ai,
|
||||
task,
|
||||
getPrompts,
|
||||
};
|
||||
|
||||
@ -26,21 +26,25 @@ class CleanNovel {
|
||||
|
||||
private async processChapter(novel: o_novel, intansce: ReturnType<typeof u.Ai.Text>): Promise<EventType | null> {
|
||||
try {
|
||||
const skill = await useSkill("universal_agent.md");
|
||||
|
||||
const prompt = await u.getPrompts("event");
|
||||
const resData = await intansce.invoke({
|
||||
system: skill.prompt,
|
||||
system: prompt,
|
||||
messages: [
|
||||
{
|
||||
role: "user",
|
||||
content: "请根据以下小说章节生成事件摘要:\n" + novel.chapterData!,
|
||||
content:
|
||||
"请根据以下小说章节数:" +
|
||||
novel.chapterIndex +
|
||||
"小说章节券:" +
|
||||
novel.reel +
|
||||
"小说章节名称:" +
|
||||
novel.chapter +
|
||||
"、小说章节内容生成事件摘要:\n" +
|
||||
novel.chapterData!,
|
||||
},
|
||||
],
|
||||
tools: skill.tools,
|
||||
});
|
||||
|
||||
const preData = resData.text;
|
||||
|
||||
this.emitter.emit("item", { id: novel.id, event: preData });
|
||||
return { id: novel.id!, event: preData };
|
||||
} catch (e) {
|
||||
@ -71,10 +75,7 @@ class CleanNovel {
|
||||
};
|
||||
|
||||
// 启动最多 concurrency 个并发任务
|
||||
const workers = Array.from(
|
||||
{ length: Math.min(this.concurrency, allChapters.length) },
|
||||
() => runNext()
|
||||
);
|
||||
const workers = Array.from({ length: Math.min(this.concurrency, allChapters.length) }, () => runNext());
|
||||
|
||||
await Promise.all(workers);
|
||||
|
||||
|
||||
59
src/utils/getPrompts.ts
Normal file
59
src/utils/getPrompts.ts
Normal file
@ -0,0 +1,59 @@
|
||||
export async function getPrompts(type: string) {
|
||||
if (type == "event") {
|
||||
return `
|
||||
# 事件提取指令
|
||||
|
||||
你是小说文本分析助手。用户每次提供一个章节的原文,你提取该章的结构化事件信息。
|
||||
|
||||
## ⚠️ 输出约束(最高优先级,违反任何一条即为失败)
|
||||
|
||||
1. 你的**完整回复**只有一行,以 \`|\` 开头、以 \`|\` 结尾,恰好 7 个字段
|
||||
2. 回复的**第一个字符**必须是 \`|\`,**最后一个字符**必须是 \`|\`
|
||||
3. \`|\` 之前不许有任何字符——没有引导语、没有解释、没有"根据……"、没有"以下是……"
|
||||
4. \`|\` 之后不许有任何字符——没有总结、没有提取说明、没有改编建议
|
||||
5. 不输出表头行、分隔线、Markdown 标题、emoji、代码块标记
|
||||
|
||||
## 输出格式
|
||||
|
||||
\`\`\`
|
||||
| 第X章 {章节标题} | {涉及角色} | {核心事件} | {主线关系} | {信息密度} | {预估集长} | {情绪强度} |
|
||||
\`\`\`
|
||||
|
||||
### 字段规范
|
||||
|
||||
| 字段 | 格式要求 | 示例 |
|
||||
|------|----------|------|
|
||||
| 章节 | \`第X章 {章节标题}\` | \`第1章 职业危机与许愿\` |
|
||||
| 涉及角色 | 有实际戏份的角色,顿号分隔 | \`林逸、白有容\` |
|
||||
| 核心事件 | 30-60字,必须含动作+结果 | \`林逸因解密风潮事业崩塌,颓废中许愿触发魔法系统绑定\` |
|
||||
| 主线关系 | **必须**为 \`强/中/弱(3-8字理由)\` | \`强(动机建立+系统激活)\` |
|
||||
| 信息密度 | \`高\` / \`中\` / \`低\` | \`高\` |
|
||||
| 预估集长 | **必须**为 \`X秒\`,禁止用分钟 | \`50秒\` |
|
||||
| 情绪强度 | 文字标签,\`+\` 连接,禁止星级/数字 | \`转折+悬疑\` |
|
||||
|
||||
**主线关系判定**:强=直接推动主角弧线;中=补充世界观/人物关系/伏笔;弱=过渡/气氛。
|
||||
|
||||
**预估集长参考**:高密度+高情绪→45-60秒;中→35-45秒;低→25-35秒。
|
||||
|
||||
**可用情绪标签**:\`冲突\`、\`恐怖\`、\`情感\`、\`转折\`、\`高潮\`、\`平铺\`、\`喜剧\`、\`悬疑\`、\`情感崩溃\`。
|
||||
|
||||
## 输出示例
|
||||
|
||||
以下两个示例展示的是**完整回复**——除这一行外没有任何其他内容:
|
||||
|
||||
\`\`\`
|
||||
| 第1章 职业危机与许愿 | 林逸 | 职业魔术师林逸因解密打假风潮导致事业崩塌,颓废中感慨"如果会魔法就好了",意外触发神奇魔法系统绑定 | 强(主角动机建立+系统激活) | 高 | 50秒 | 转折+悬疑 |
|
||||
\`\`\`
|
||||
\`\`\`
|
||||
| 第12章 山间小憩 | 凌玄、苏晚卿 | 凌玄与苏晚卿在山间歇脚,苏晚卿回忆幼时往事,两人关系略有缓和但未实质推进 | 弱(气氛过渡) | 低 | 25秒 | 平铺+情感 |
|
||||
\`\`\`
|
||||
|
||||
## 提取规则
|
||||
|
||||
- 忠于原文,不推测、不脑补、不加入原文未出现的情节
|
||||
- 角色使用文中主要称呼,保持一致
|
||||
- 多条平行事件线时,选对主角影响最大的一条,其余简要带过
|
||||
- 对话密集章节,关注对话推动了什么结果,而非复述对话内容
|
||||
`;
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user