完善debug调试功能

This commit is contained in:
ACT丶流星雨 2026-03-27 15:50:52 +08:00
parent 7516870104
commit 879c0439bc
13 changed files with 192 additions and 160 deletions

View File

@ -90,5 +90,10 @@
"nodemon": "^3.1.11",
"tsx": "^4.21.0",
"typescript": "^5.9.3"
},
"overrides": {
"@rmp135/sql-ts": {
"better-sqlite3": "^12.8.0"
}
}
}

View File

@ -156,6 +156,10 @@ app.whenReady().then(async () => {
windowismaximized: () => ({
maximized: mainWindow?.isMaximized() ?? false,
}),
openDevTool: () => {
mainWindow?.webContents.openDevTools();
return { ok: true };
},
};
const handler = handlers[pathname];
const responseData = handler ? handler() : { error: "未知接口" };

View File

@ -159,6 +159,10 @@ export default async (knex: Knex, forceInit: boolean = false): Promise<void> =>
key: "modelDtype",
value: "fp16",
},
{
key: "switchAiDevTool",
value: "0",
},
]);
},
},
@ -371,26 +375,10 @@ export default async (knex: Knex, forceInit: boolean = false): Promise<void> =>
{
name: "o_vendorConfig",
builder: (table) => {
table.integer("id").notNullable();
table.string("id").notNullable();
table.text("author");
table.text("description");
table.text("name");
table.text("version");
table.text("icon");
table.text("inputs"); // 输入项配置 JSON
table.text("inputValues"); // 输入项值 JSON
table.text("models"); // 模型配置 JSON
table.text("code"); // 模型配置 JSON
table.integer("createTime");
table.primary(["id"]);
table.unique(["id"]);
},
},
//供应商配置表
{
name: "o_vendorConfig",
builder: (table) => {
table.integer("id").notNullable();
table.text("name");
table.text("version");
table.text("icon");
table.text("inputs"); // 输入项配置 JSON
table.text("inputValues"); // 输入项值 JSON

View File

@ -1,4 +1,4 @@
// @routes-hash 557dfd43a824a4bd4170d0e2c9a6b45c
// @routes-hash 57463134da0d81d65d10c163ee8a2b26
import { Express } from "express";
import route1 from "./routes/agents/clearMemory";
@ -71,34 +71,37 @@ 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/agentDeploy/agentSetKey";
import route72 from "./routes/setting/agentDeploy/deployAgentModel";
import route73 from "./routes/setting/agentDeploy/getAgentDeploy";
import route74 from "./routes/setting/dbConfig/clearData";
import route75 from "./routes/setting/fileManagement/openFolder";
import route76 from "./routes/setting/getTextModel";
import route77 from "./routes/setting/loginConfig/getUser";
import route78 from "./routes/setting/loginConfig/updateUserPwd";
import route79 from "./routes/setting/memoryConfig/delAllMemory";
import route80 from "./routes/setting/memoryConfig/getMemory";
import route81 from "./routes/setting/memoryConfig/sureMemory";
import route82 from "./routes/setting/skillManagement/addSkill";
import route83 from "./routes/setting/skillManagement/deleteSkill";
import route84 from "./routes/setting/skillManagement/embeddingSkill";
import route85 from "./routes/setting/skillManagement/generateDescription";
import route86 from "./routes/setting/skillManagement/getSkillList";
import route87 from "./routes/setting/skillManagement/scanSkills";
import route88 from "./routes/setting/skillManagement/updateSkill";
import route89 from "./routes/setting/vendorConfig/addVendor";
import route90 from "./routes/setting/vendorConfig/deleteVendor";
import route91 from "./routes/setting/vendorConfig/getVendorList";
import route92 from "./routes/setting/vendorConfig/modelTest";
import route93 from "./routes/setting/vendorConfig/updateVendor";
import route94 from "./routes/task/getProject";
import route95 from "./routes/task/getTaskApi";
import route96 from "./routes/task/getTaskCategories";
import route97 from "./routes/task/taskDetails";
import route98 from "./routes/test/test";
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";
export default async (app: Express) => {
app.use("/api/agents/clearMemory", route1);
@ -171,32 +174,35 @@ export default async (app: Express) => {
app.use("/api/script/updateScript", route68);
app.use("/api/scriptAgent/getPlanData", route69);
app.use("/api/scriptAgent/setPlanData", route70);
app.use("/api/setting/agentDeploy/agentSetKey", route71);
app.use("/api/setting/agentDeploy/deployAgentModel", route72);
app.use("/api/setting/agentDeploy/getAgentDeploy", route73);
app.use("/api/setting/dbConfig/clearData", route74);
app.use("/api/setting/fileManagement/openFolder", route75);
app.use("/api/setting/getTextModel", route76);
app.use("/api/setting/loginConfig/getUser", route77);
app.use("/api/setting/loginConfig/updateUserPwd", route78);
app.use("/api/setting/memoryConfig/delAllMemory", route79);
app.use("/api/setting/memoryConfig/getMemory", route80);
app.use("/api/setting/memoryConfig/sureMemory", route81);
app.use("/api/setting/skillManagement/addSkill", route82);
app.use("/api/setting/skillManagement/deleteSkill", route83);
app.use("/api/setting/skillManagement/embeddingSkill", route84);
app.use("/api/setting/skillManagement/generateDescription", route85);
app.use("/api/setting/skillManagement/getSkillList", route86);
app.use("/api/setting/skillManagement/scanSkills", route87);
app.use("/api/setting/skillManagement/updateSkill", route88);
app.use("/api/setting/vendorConfig/addVendor", route89);
app.use("/api/setting/vendorConfig/deleteVendor", route90);
app.use("/api/setting/vendorConfig/getVendorList", route91);
app.use("/api/setting/vendorConfig/modelTest", route92);
app.use("/api/setting/vendorConfig/updateVendor", route93);
app.use("/api/task/getProject", route94);
app.use("/api/task/getTaskApi", route95);
app.use("/api/task/getTaskCategories", route96);
app.use("/api/task/taskDetails", route97);
app.use("/api/test/test", route98);
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);
}

View File

@ -0,0 +1,11 @@
import express from "express";
import { success, error } from "@/lib/responseFormat";
import u from "@/utils";
import initDB from "@/lib/initDB";
const router = express.Router();
export default router.get("/", async (req, res) => {
const switchAiDevTool = await u.db("o_setting").where("key", "switchAiDevTool").first();
res.status(200).send(success(switchAiDevTool?.value || "0"));
});

View File

@ -0,0 +1,20 @@
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({
switchAiDevTool: z.string(),
}),
async (req, res) => {
const { switchAiDevTool } = req.body;
await u.db("o_setting").where("key", "switchAiDevTool").update({
value: switchAiDevTool,
});
res.status(200).send(success("保存设置成功"));
},
);

View File

@ -8,9 +8,11 @@ import { transform } from "sucrase";
const router = express.Router();
const vendorConfigSchema = z.object({
version: z.number(),
icon: z.string().optional(),
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(),
@ -41,16 +43,19 @@ const vendorConfigSchema = z.object({
modelName: z.string(),
type: z.literal("video"),
mode: z.array(
z.enum([
"singleImage",
"multiImage",
"gridImage",
"startEndRequired",
"endFrameOptional",
"startFrameOptional",
"text",
"audioReference",
"videoReference",
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()]),
@ -87,12 +92,14 @@ export default router.post(
return res.status(400).send(error(`vendor配置校验失败: ${errorMsg}`));
}
await u.db("o_vendorConfig").insert({
id: vendor.id,
author: vendor.author,
description: vendor.description || "",
name: vendor.name,
version: vendor.version.toString(),
icon: vendor.icon || "",
inputs: JSON.stringify(vendor.inputs),
inputValues: JSON.stringify(vendor.inputValues),
models: JSON.stringify(vendor.models),
inputs: JSON.stringify(vendor.inputs ?? []),
inputValues: JSON.stringify(vendor.inputValues ?? {}),
models: JSON.stringify(vendor.models ?? []),
code: tsCode,
createTime: Date.now(),
});

View File

@ -7,7 +7,7 @@ const router = express.Router();
export default router.post(
"/",
validateFields({
id: z.number(),
id: z.string(),
}),
async (req, res) => {
const { id } = req.body;

View File

@ -11,12 +11,11 @@ export default router.post(
"/",
validateFields({
modelName: z.string(),
apiKey: z.string(),
type: z.enum(["text", "video", "image"]),
id: z.number(),
id: z.string(),
}),
async (req, res) => {
const { modelName, apiKey, type, id } = req.body;
const { modelName, type, id } = req.body;
try {
const requestFn: Record<string, { fnName: string; modelData?: any }> = {
@ -69,12 +68,16 @@ export default router.post(
});
if (type == "text") {
const resTextData = await u.Ai.Text(`${id}:${modelName}`).invoke({
const { textStream } = await u.Ai.Text(`${id}:${modelName}`).stream({
prompt: "请调用工具获取火星的天气,并回答我多少气温",
tools: { getWeatherTool },
});
res.status(200).send(success(resTextData.text));
let fullResponse = "";
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 = {
image: "Image",

View File

@ -7,9 +7,11 @@ import { transform } from "sucrase";
const router = express.Router();
const vendorConfigSchema = z.object({
version: z.number(),
icon: z.string().optional(),
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(),
@ -41,8 +43,18 @@ const vendorConfigSchema = z.object({
type: z.literal("video"),
mode: z.array(
z.union([
z.enum(["singleImage", "multiImage", "gridImage", "startEndRequired", "endFrameOptional", "startFrameOptional", "text"]),
z.array(z.enum(["audioReference", "videoReference", "textReference", "imageReference"])),
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()]),
@ -60,9 +72,8 @@ const vendorConfigSchema = z.object({
export default router.post(
"/",
validateFields({
id: z.number(),
id: z.string(),
tsCode: z.string(),
icon: z.string().optional(),
inputValues: z.record(z.string(), z.string()),
inputs: z.array(
z.object({
@ -108,11 +119,9 @@ export default router.post(
}),
]),
),
name: z.string().optional(),
version: z.string().optional(),
}),
async (req, res) => {
const { id, tsCode, name, version, models, inputs, inputValues, icon } = req.body;
const { id, tsCode, name, models, inputs, inputValues, icon } = req.body;
const jsCode = transform(tsCode, { transforms: ["typescript"] }).code;
const exports = u.vm(jsCode);
@ -158,9 +167,6 @@ export default router.post(
};
let updatedTsCode = tsCode;
updatedTsCode = replacePrimitiveValue(updatedTsCode, "name", name ?? vendor.name);
updatedTsCode = replacePrimitiveValue(updatedTsCode, "version", version ? Number(version) : vendor.version);
updatedTsCode = replacePrimitiveValue(updatedTsCode, "icon", icon ?? vendor.icon ?? "");
updatedTsCode = replaceBlockValue(updatedTsCode, "inputs", JSON.stringify(inputs ?? vendor.inputs, null, 2));
updatedTsCode = replaceBlockValue(updatedTsCode, "inputValues", JSON.stringify(inputValues ?? vendor.inputValues, null, 2));
updatedTsCode = replaceBlockValue(updatedTsCode, "models", JSON.stringify(models ?? vendor.models, null, 2));
@ -169,9 +175,6 @@ export default router.post(
.db("o_vendorConfig")
.where("id", id)
.update({
name: name ? name : vendor.name,
version: version ? version.toString() : vendor.version.toString(),
icon: icon ? icon : vendor.icon || "",
inputs: inputs ? JSON.stringify(inputs) : JSON.stringify(vendor.inputs),
inputValues: inputValues ? JSON.stringify(inputValues) : JSON.stringify(vendor.inputValues),
models: models ? JSON.stringify(models) : JSON.stringify(vendor.models),

View File

@ -1,36 +1,6 @@
// @db-hash 579a004cc745580469a24ee71f5f51c3
// @db-hash 0041ea9843a4bb46f03412c516ec323b
//该文件由脚本自动生成,请勿手动修改
export interface _o_project_old_20260326 {
'artStyle'?: string | null;
'createTime'?: number | null;
'id'?: number | null;
'intro'?: string | null;
'name'?: string | null;
'projectType'?: string | null;
'type'?: string | null;
'userId'?: number | null;
'videoRatio'?: string | null;
}
export interface _o_storyboard_old_20260325 {
'camera'?: string | null;
'createTime'?: number | null;
'description'?: string | null;
'duration'?: string | null;
'filePath'?: string | null;
'frameMode'?: string | null;
'id'?: number;
'lines'?: string | null;
'mode'?: string | null;
'model'?: string | null;
'prompt'?: string | null;
'reason'?: string | null;
'resolution'?: string | null;
'scriptId'?: number | null;
'sound'?: string | null;
'state'?: string | null;
'title'?: string | null;
}
export interface memories {
'content': string;
'createTime': number;
@ -215,15 +185,16 @@ export interface o_user {
'password'?: string | null;
}
export interface o_vendorConfig {
'author'?: string | null;
'code'?: string | null;
'createTime'?: number | null;
'description'?: string | null;
'icon'?: string | null;
'id'?: number;
'id'?: string;
'inputs'?: string | null;
'inputValues'?: string | null;
'models'?: string | null;
'name'?: string | null;
'version'?: string | null;
}
export interface o_video {
'errorReason'?: string | null;
@ -250,8 +221,6 @@ export interface o_videoConfig {
}
export interface DB {
"_o_project_old_20260326": _o_project_old_20260326;
"_o_storyboard_old_20260325": _o_storyboard_old_20260325;
"memories": memories;
"o_agentDeploy": o_agentDeploy;
"o_agentWorkData": o_agentWorkData;

View File

@ -8,7 +8,7 @@ type AiType = "scriptAgent" | "productionAgent" | "universalAgent";
type FnName = "textRequest" | "imageRequest" | "videoRequest" | "ttsRequest";
const AiTypeValues: AiType[] = ["scriptAgent", "productionAgent", "universalAgent"];
async function resolveModelName(value: AiType | `${number}:${string}`): Promise<`${number}:${string}`> {
async function resolveModelName(value: AiType | `${string}:${string}`): Promise<`${string}:${string}`> {
if (AiTypeValues.includes(value as AiType)) {
const agentDeployData = await u.db("o_agentDeploy").where("key", value).first();
if (!agentDeployData?.modelName) throw new Error(`${value}模型未配置`);
@ -17,7 +17,7 @@ async function resolveModelName(value: AiType | `${number}:${string}`): Promise<
return value as `${number}:${string}`;
}
async function getVendorTemplateFn(fnName: FnName, modelName: `${number}:${string}`) {
async function getVendorTemplateFn(fnName: FnName, modelName: `${string}:${string}`) {
const [id, name] = modelName.split(":");
const vendorConfigData = await u.db("o_vendorConfig").where("id", id).first();
if (!vendorConfigData) throw new Error(`未找到供应商配置 id=${id}`);
@ -37,7 +37,7 @@ async function withTaskRecord<T>(
describe: string,
relatedObjects: string,
projectId: number,
fn: (modelName: `${number}:${string}`) => Promise<T>,
fn: (modelName: `${string}:${string}`) => Promise<T>,
): Promise<T> {
const modelName = await resolveModelName(modelKey);
const [id, model] = modelName.split(":");
@ -59,27 +59,38 @@ async function urlToBase64(url: string): Promise<string> {
}
class AiText {
private AiType: AiType | `${number}:${string}`;
constructor(AiType: AiType | `${number}:${string}`) {
private AiType: AiType | `${string}:${string}`;
constructor(AiType: AiType | `${string}:${string}`) {
this.AiType = AiType;
}
async invoke(input: Omit<Parameters<typeof generateText>[0], "model">) {
const switchAiDevTool = await u.db("o_setting").where("key", "switchAiDevTool").first();
const modelName = await resolveModelName(this.AiType);
return generateText({
...(input.tools && { stopWhen: stepCountIs(Object.keys(input.tools).length * 50) }),
...input,
model: await getVendorTemplateFn("textRequest", modelName),
model:
switchAiDevTool?.value === "1"
? wrapLanguageModel({
model: await getVendorTemplateFn("textRequest", modelName),
middleware: devToolsMiddleware(),
})
: await getVendorTemplateFn("textRequest", modelName),
} as Parameters<typeof generateText>[0]);
}
async stream(input: Omit<Parameters<typeof streamText>[0], "model">) {
const switchAiDevTool = await u.db("o_setting").where("key", "switchAiDevTool").first();
const modelName = await resolveModelName(this.AiType);
return streamText({
...(input.tools && { stopWhen: stepCountIs(Object.keys(input.tools).length * 50) }),
...input,
model: wrapLanguageModel({
model: await getVendorTemplateFn("textRequest", modelName),
middleware: devToolsMiddleware(),
}),
model:
switchAiDevTool?.value == "1"
? wrapLanguageModel({
model: await getVendorTemplateFn("textRequest", modelName),
middleware: devToolsMiddleware(),
})
: await getVendorTemplateFn("textRequest", modelName),
} as Parameters<typeof streamText>[0]);
}
}
@ -168,7 +179,7 @@ class AiAudio {
}
export default {
Text: (AiType: AiType | `${number}:${string}`) => new AiText(AiType),
Text: (AiType: AiType | `${string}:${string}`) => new AiText(AiType),
Image: (key: `${number}:${string}`) => new AiImage(key),
Video: (key: `${number}:${string}`) => new AiVideo(key),
Audio: (key: `${number}:${string}`) => new AiAudio(key),

View File

@ -34,6 +34,7 @@ export default function runCode(code: string) {
exports,
axios,
FormData,
logger,
},
compiler: "javascript",
eval: false,
@ -44,6 +45,10 @@ export default function runCode(code: string) {
return exports as Record<string, any>;
}
export function logger(logstring: string) {
console.log("【VM】" + logstring);
}
/**
* size
*/