更新minimax与火山引擎代码
This commit is contained in:
parent
79226b80c5
commit
9912f90377
7
data/vendor/minimax.ts
vendored
7
data/vendor/minimax.ts
vendored
@ -134,7 +134,7 @@ declare const exports: {
|
||||
|
||||
const vendor: VendorConfig = {
|
||||
id: "minimax",
|
||||
version: "2.0",
|
||||
version: "2.1",
|
||||
author: "Toonflow",
|
||||
name: "MiniMax(海螺AI)",
|
||||
description: "MiniMax官方接口适配,支持M系列推理文本模型、文生图/图生图、视频生成(文生视频、图生视频、首尾帧生成)能力 \n [前往平台](https://minimaxi.com/)",
|
||||
@ -228,11 +228,8 @@ const extractBase64WithHead = (ref: ReferenceList): string => {
|
||||
const textRequest = (model: TextModel, think: boolean, thinkLevel: 0 | 1 | 2 | 3) => {
|
||||
if (!vendor.inputValues.apiKey) throw new Error("缺少API Key");
|
||||
const apiKey = vendor.inputValues.apiKey.replace(/^Bearer\s+/i, "");
|
||||
const baseUrl = getBaseUrl();
|
||||
|
||||
const openaiBaseUrl = `${baseUrl}/v1`;
|
||||
const extraBody = model.think ? { reasoning_split: true } : {};
|
||||
return createOpenAI({ baseURL: openaiBaseUrl, apiKey, extraBody }).chat(model.modelName);
|
||||
return createOpenAI({ baseURL: getBaseUrl(), apiKey, extraBody }).chat(model.modelName);
|
||||
};
|
||||
|
||||
const uploadReference = async (base64: string, fileType: "image" | "audio" | "video"): Promise<ReferenceList> => {
|
||||
|
||||
133
data/vendor/volcengine.ts
vendored
133
data/vendor/volcengine.ts
vendored
@ -133,7 +133,7 @@ declare const exports: {
|
||||
|
||||
const vendor: VendorConfig = {
|
||||
id: "volcengine",
|
||||
version: "2.0",
|
||||
version: "2.1",
|
||||
author: "leeqi",
|
||||
name: "火山引擎(豆包)",
|
||||
description:
|
||||
@ -326,43 +326,120 @@ const imageRequest = async (config: ImageConfig, model: ImageModel): Promise<str
|
||||
const baseUrl = getBaseUrl();
|
||||
const headers = getHeaders();
|
||||
|
||||
const content: any[] = [];
|
||||
const body: any = {
|
||||
model: model.modelName,
|
||||
prompt: config.prompt || "",
|
||||
response_format: "url",
|
||||
watermark: false,
|
||||
};
|
||||
|
||||
if (config.prompt) {
|
||||
content.push({ type: "text", text: config.prompt });
|
||||
const isOldModel = model.modelName.includes("seedream-3-0");
|
||||
const is5Lite = model.modelName.includes("seedream-5-0-lite");
|
||||
|
||||
// sequential_image_generation 仅 seedream 5.0-lite/4.5/4.0 支持
|
||||
if (!isOldModel) {
|
||||
body.sequential_image_generation = "disabled";
|
||||
}
|
||||
|
||||
if (config.referenceList && config.referenceList.length > 0) {
|
||||
for (const ref of config.referenceList) {
|
||||
content.push({
|
||||
type: "image_url",
|
||||
image_url: { url: ref.base64 },
|
||||
});
|
||||
// 参考图片:单图为 string,多图为 array(seedream-3.0-t2i 不支持 image 参数)
|
||||
if (!isOldModel && config.referenceList && config.referenceList.length > 0) {
|
||||
const images = config.referenceList.map((ref) => ref.base64);
|
||||
body.image = images.length === 1 ? images[0] : images;
|
||||
}
|
||||
|
||||
// 尺寸处理:优先使用推荐像素值,未匹配则直接传分辨率字符串让模型自行决定
|
||||
const [w, h] = config.aspectRatio.split(":").map(Number);
|
||||
const sizeTable: Record<string, Record<string, string>> = {
|
||||
"1K": {
|
||||
"1:1": "1024x1024",
|
||||
"4:3": "1152x864",
|
||||
"3:4": "864x1152",
|
||||
"16:9": "1280x720",
|
||||
"9:16": "720x1280",
|
||||
"3:2": "1248x832",
|
||||
"2:3": "832x1248",
|
||||
"21:9": "1512x648",
|
||||
},
|
||||
"2K": {
|
||||
"1:1": "2048x2048",
|
||||
"4:3": "2304x1728",
|
||||
"3:4": "1728x2304",
|
||||
"16:9": "2848x1600",
|
||||
"9:16": "1600x2848",
|
||||
"3:2": "2496x1664",
|
||||
"2:3": "1664x2496",
|
||||
"21:9": "3136x1344",
|
||||
},
|
||||
"4K": {
|
||||
"1:1": "4096x4096",
|
||||
"4:3": "4704x3520",
|
||||
"3:4": "3520x4704",
|
||||
"16:9": "5504x3040",
|
||||
"9:16": "3040x5504",
|
||||
"3:2": "4992x3328",
|
||||
"2:3": "3328x4992",
|
||||
"21:9": "6240x2656",
|
||||
},
|
||||
};
|
||||
|
||||
const sizeKey = config.size || "2K";
|
||||
const ratioKey = config.aspectRatio;
|
||||
const table = sizeTable[sizeKey];
|
||||
|
||||
if (table && table[ratioKey]) {
|
||||
// 推荐像素值匹配到了,但需要检查是否满足模型最低像素要求
|
||||
const [pw, ph] = table[ratioKey].split("x").map(Number);
|
||||
const totalPixels = pw * ph;
|
||||
if (isOldModel) {
|
||||
// seedream-3.0-t2i: 像素范围 [512x512, 2048x2048]
|
||||
body.size = table[ratioKey];
|
||||
} else if (totalPixels < 3686400) {
|
||||
// 1K 像素值不满足新模型最低要求,直接传 "2K" 让模型自行决定
|
||||
body.size = "2K";
|
||||
} else if (is5Lite && totalPixels > 10404496) {
|
||||
// seedream-5.0-lite 最高 10404496,4K 超限,回退传 "2K"
|
||||
body.size = "2K";
|
||||
} else {
|
||||
body.size = table[ratioKey];
|
||||
}
|
||||
} else if (isOldModel) {
|
||||
// seedream-3.0-t2i: 像素范围 [512x512, 2048x2048],直接按比例计算
|
||||
const base = sizeKey === "1K" ? 1024 : 2048;
|
||||
const calcW = Math.min(2048, Math.round(base * Math.sqrt(w / h)));
|
||||
const calcH = Math.min(2048, Math.round(base * Math.sqrt(h / w)));
|
||||
body.size = `${Math.max(512, calcW)}x${Math.max(512, calcH)}`;
|
||||
} else {
|
||||
// 新模型未匹配推荐值时,直接传分辨率字符串(方式1),由模型根据 prompt 自行决定尺寸
|
||||
// seedream 5.0-lite 支持 "2K"/"3K",seedream 4.5 支持 "2K"/"4K",seedream 4.0 支持 "1K"/"2K"/"4K"
|
||||
if (is5Lite) {
|
||||
body.size = sizeKey === "4K" ? "3K" : sizeKey === "1K" ? "2K" : sizeKey;
|
||||
} else {
|
||||
body.size = sizeKey === "1K" ? "2K" : sizeKey;
|
||||
}
|
||||
}
|
||||
|
||||
const [w, h] = config.aspectRatio.split(":").map(Number);
|
||||
const sizeMap: Record<string, { width: number; height: number }> = {
|
||||
"1K": { width: 1024, height: Math.round(1024 * (h / w)) },
|
||||
"2K": { width: 2048, height: Math.round(2048 * (h / w)) },
|
||||
"4K": { width: 4096, height: Math.round(4096 * (h / w)) },
|
||||
};
|
||||
const size = sizeMap[config.size] || sizeMap["1K"];
|
||||
|
||||
const body = {
|
||||
model: model.modelName,
|
||||
content,
|
||||
size: `${size.width}x${size.height}`,
|
||||
response_format: "url",
|
||||
};
|
||||
|
||||
logger(`[图片生成] 请求模型: ${model.modelName}`);
|
||||
logger(`[图片生成] 请求模型: ${model.modelName}, 尺寸: ${body.size}`);
|
||||
|
||||
const response = await axios.post(`${baseUrl}/images/generations`, body, { headers });
|
||||
const data = response.data;
|
||||
|
||||
if (data?.data?.[0]?.url) {
|
||||
return await urlToBase64(data.data[0].url);
|
||||
if (data?.error) {
|
||||
throw new Error(`图片生成失败:${data.error.message || data.error.code}`);
|
||||
}
|
||||
|
||||
// 从 data 数组中提取第一张成功的图片
|
||||
if (data?.data && data.data.length > 0) {
|
||||
for (const item of data.data) {
|
||||
if (item.url) {
|
||||
return await urlToBase64(item.url);
|
||||
}
|
||||
if (item.b64_json) {
|
||||
return item.b64_json;
|
||||
}
|
||||
if (item.error) {
|
||||
throw new Error(`图片生成失败:${item.error.message || item.error.code}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
throw new Error("图片生成失败:未返回有效结果");
|
||||
|
||||
@ -31,7 +31,8 @@
|
||||
"dist:mac": "yarn build && electron-builder --mac",
|
||||
"dist:linux": "yarn build && electron-builder --linux",
|
||||
"debug:ai": "npx @ai-sdk/devtools",
|
||||
"license": "bun run scripts/license.ts"
|
||||
"license": "node scripts/license.ts",
|
||||
"vendor2json": "node scripts/vendor2json.ts"
|
||||
},
|
||||
"dependencies": {
|
||||
"@ai-sdk/anthropic": "^3.0.35",
|
||||
@ -98,4 +99,4 @@
|
||||
"better-sqlite3": "^12.8.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
11
scripts/vendor2json.ts
Normal file
11
scripts/vendor2json.ts
Normal file
@ -0,0 +1,11 @@
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
|
||||
const vendorDir = path.join("data", "vendor");
|
||||
const files = fs.readdirSync(vendorDir).filter((f) => f.endsWith(".ts"));
|
||||
const result: Record<string, string> = {};
|
||||
for (const file of files) {
|
||||
result[file] = fs.readFileSync(path.join(vendorDir, file), "utf-8");
|
||||
}
|
||||
fs.writeFileSync(path.join(vendorDir, "vendor.json"), JSON.stringify(result, null, 2), "utf-8");
|
||||
console.log("Done, saved vendor.json");
|
||||
@ -1,234 +0,0 @@
|
||||
import { Socket } from "socket.io";
|
||||
import { tool } from "ai";
|
||||
import { z } from "zod";
|
||||
import u from "@/utils";
|
||||
import Memory from "@/utils/agent/memory";
|
||||
import { createSkillTools, parseFrontmatter, scanSkills, useSkill } from "@/utils/agent/skillsTools";
|
||||
import useTools from "@/agents/productionAgent/tools";
|
||||
import ResTool from "@/socket/resTool";
|
||||
import * as fs from "fs";
|
||||
import path from "path";
|
||||
|
||||
export interface AgentContext {
|
||||
socket: Socket;
|
||||
isolationKey: string;
|
||||
text: string;
|
||||
userMessageTime?: number;
|
||||
abortSignal?: AbortSignal;
|
||||
resTool: ResTool;
|
||||
msg: ReturnType<ResTool["newMessage"]>;
|
||||
}
|
||||
|
||||
function buildMemPrompt(mem: Awaited<ReturnType<Memory["get"]>>): string {
|
||||
let memoryContext = "";
|
||||
if (mem.rag.length) {
|
||||
memoryContext += `[相关记忆]\n${mem.rag.map((r) => r.content).join("\n")}`;
|
||||
}
|
||||
if (mem.summaries.length) {
|
||||
if (memoryContext) memoryContext += "\n\n";
|
||||
memoryContext += `[历史摘要]\n${mem.summaries.map((s, i) => `${i + 1}. ${s.content}`).join("\n")}`;
|
||||
}
|
||||
if (mem.shortTerm.length) {
|
||||
if (memoryContext) memoryContext += "\n\n";
|
||||
memoryContext += `[近期对话]\n${mem.shortTerm.map((m) => `${m.role}: ${m.content}`).join("\n")}`;
|
||||
}
|
||||
return `## Memory\n以下是你对用户的记忆,可作为参考但不要主动提及:\n${memoryContext}`;
|
||||
}
|
||||
|
||||
export async function decisionAI(ctx: AgentContext) {
|
||||
const { isolationKey, text, abortSignal } = ctx;
|
||||
const memory = new Memory("productionAgent", isolationKey);
|
||||
await memory.add("user", text);
|
||||
|
||||
const skill = path.join(u.getPath("skills"), "production_agent_decision.md");
|
||||
const prompt = await fs.promises.readFile(skill, "utf-8");
|
||||
|
||||
const projectInfo = await u.db("o_project").where("id", ctx.resTool.data.projectId).first();
|
||||
if (!projectInfo) throw new Error(`项目不存在,ID: ${ctx.resTool.data.projectId}`);
|
||||
const [_, imageModelName] = projectInfo.imageModel!.split(":");
|
||||
const [id, videoModelName] = projectInfo.videoModel!.split(":");
|
||||
const data = await u.db("o_vendorConfig").where("id", id).select("models").first();
|
||||
const models = JSON.parse(data!.models!);
|
||||
const findData = models.find((i: any) => i.modelName == videoModelName);
|
||||
const isRef = findData.mode.every((i: any) => Array.isArray(i));
|
||||
const modelInfo = `项目使用的模型如下:\n图像模型:${imageModelName}\n视频模型:${videoModelName}\n多参:${isRef ? "是" : "否"}`;
|
||||
|
||||
const mem = buildMemPrompt(await memory.get(text));
|
||||
|
||||
const { textStream } = await u.Ai.Text("productionAgent").stream({
|
||||
messages: [
|
||||
{ role: "system", content: prompt },
|
||||
{ role: "assistant", content: mem + "\n" + modelInfo },
|
||||
{ role: "user", content: text },
|
||||
],
|
||||
abortSignal,
|
||||
tools: {
|
||||
...memory.getTools(),
|
||||
...useTools({ resTool: ctx.resTool, msg: ctx.msg }),
|
||||
...createSubAgent(ctx),
|
||||
},
|
||||
onFinish: async (completion) => {
|
||||
await memory.add("assistant:decision", removeAllXmlTags(completion.text));
|
||||
},
|
||||
});
|
||||
|
||||
return textStream;
|
||||
}
|
||||
|
||||
function createSubAgent(parentCtx: AgentContext) {
|
||||
const { resTool, abortSignal } = parentCtx;
|
||||
const memory = new Memory("productionAgent", parentCtx.isolationKey);
|
||||
async function runAgent({
|
||||
prompt,
|
||||
system,
|
||||
name,
|
||||
memoryKey,
|
||||
tools: extraTools,
|
||||
messages,
|
||||
}: {
|
||||
prompt: string;
|
||||
system: string;
|
||||
name: string;
|
||||
memoryKey: string;
|
||||
tools?: Record<string, any>;
|
||||
messages?: { role: "user" | "assistant" | "system"; content: string }[];
|
||||
}) {
|
||||
parentCtx.msg.complete();
|
||||
const subMsg = resTool.newMessage("assistant", name);
|
||||
const text = subMsg.text();
|
||||
let fullResponse = "";
|
||||
|
||||
const { textStream } = await u.Ai.Text("scriptAgent").stream({
|
||||
system,
|
||||
messages: messages ?? [{ role: "user", content: prompt }],
|
||||
abortSignal,
|
||||
tools: { ...extraTools, ...useTools({ resTool, msg: subMsg }) },
|
||||
});
|
||||
|
||||
try {
|
||||
for await (const chunk of textStream) {
|
||||
await new Promise<void>((resolve) => setTimeout(() => resolve(), 1));
|
||||
text.append(chunk);
|
||||
fullResponse += chunk;
|
||||
}
|
||||
text.complete();
|
||||
subMsg.complete();
|
||||
} catch (err: any) {
|
||||
text.complete();
|
||||
subMsg.stop();
|
||||
throw err;
|
||||
}
|
||||
|
||||
if (fullResponse.trim()) {
|
||||
await memory.add(memoryKey, removeAllXmlTags(fullResponse), {
|
||||
name,
|
||||
createTime: new Date(subMsg.datetime).getTime(),
|
||||
});
|
||||
}
|
||||
|
||||
parentCtx.msg = resTool.newMessage("assistant", "视频策划");
|
||||
return fullResponse;
|
||||
}
|
||||
|
||||
const promptInput = z.object({
|
||||
prompt: z.string().describe("交给子Agent的任务简约描述,100字以内"),
|
||||
});
|
||||
|
||||
const run_sub_agent_execution = tool({
|
||||
description: "执行层子Agent,负责衍生资产、",
|
||||
inputSchema: promptInput,
|
||||
execute: async ({ prompt }) => {
|
||||
const skill = path.join(u.getPath("skills"), "production_agent_execution.md");
|
||||
const systemPrompt = await fs.promises.readFile(skill, "utf-8");
|
||||
const addPrompt =
|
||||
"\n" +
|
||||
[
|
||||
"你必须使用如下XML格式写入工作区:\n```",
|
||||
"拍摄计划:<scriptPlan>内容</scriptPlan>",
|
||||
"分镜表:<storyboardTable>内容</storyboardTable>",
|
||||
"分镜面板:<storyboardItem videoDesc='视频描述' prompt=提示词内容 track='分组' duration='视频推荐时间' associateAssetsIds='[该分镜所需的资产ID列表]'></storyboardItem>",
|
||||
"```",
|
||||
].join("\n");
|
||||
|
||||
const projectInfo = await u.db("o_project").where("id", resTool.data.projectId).first();
|
||||
if (!projectInfo) throw new Error(`项目不存在,ID: ${resTool.data.projectId}`);
|
||||
const artSkills = await createArtSkills(projectInfo?.artStyle!, projectInfo?.directorManual!);
|
||||
|
||||
const [_, imageModelName] = projectInfo.imageModel!.split(":");
|
||||
const [id, videoModelName] = projectInfo.videoModel!.split(":");
|
||||
const data = await u.db("o_vendorConfig").where("id", id).select("models").first();
|
||||
const models = JSON.parse(data!.models!);
|
||||
const findData = models.find((i: any) => i.modelName == videoModelName);
|
||||
const isRef = findData.mode.every((i: any) => Array.isArray(i));
|
||||
const modelInfo = `项目使用的模型如下:\n图像模型:${imageModelName}\n视频模型:${videoModelName}\n多参:${isRef ? "是" : "否"}`;
|
||||
|
||||
return runAgent({
|
||||
prompt,
|
||||
system: systemPrompt + addPrompt,
|
||||
name: "执行导演",
|
||||
memoryKey: "assistant:execution",
|
||||
messages: [
|
||||
{ role: "assistant", content: artSkills.prompt + `\n${modelInfo}` },
|
||||
{ role: "user", content: prompt + addPrompt },
|
||||
],
|
||||
tools: { ...artSkills.tools },
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
const run_sub_agent_supervision = tool({
|
||||
description: "监制层子Agent,负责审核执行结果",
|
||||
inputSchema: promptInput,
|
||||
execute: async ({ prompt }) => {
|
||||
const skill = path.join(u.getPath("skills"), "production_agent_supervision.md");
|
||||
const systemPrompt = await fs.promises.readFile(skill, "utf-8");
|
||||
return runAgent({
|
||||
prompt,
|
||||
system: systemPrompt,
|
||||
name: "监制",
|
||||
memoryKey: "assistant:supervision",
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
return { run_sub_agent_execution, run_sub_agent_supervision };
|
||||
}
|
||||
|
||||
async function createArtSkills(artName: string, storyName: string) {
|
||||
const artWorkerPath = u.getPath(["skills", "art_skills", artName, "driector_skills"]);
|
||||
const storyWorkerPath = u.getPath(["skills", "story_skills", storyName, "driector_skills"]);
|
||||
const skillList = [...(await scanSkills(artWorkerPath + "/*.md")), ...(await scanSkills(storyWorkerPath + "/*.md"))];
|
||||
const mainSkills: { path: string; name: string; description: string }[] = [];
|
||||
for (const skillPath of skillList) {
|
||||
if (!fs.existsSync(skillPath)) throw new Error(`主技能文件不存在: ${skillPath}`);
|
||||
const content = await fs.promises.readFile(skillPath, "utf-8");
|
||||
const parsed = parseFrontmatter(content);
|
||||
mainSkills.push({ path: skillPath, ...parsed });
|
||||
}
|
||||
const res = {
|
||||
prompt: `## Skills
|
||||
以下技能提供了专业任务的专用指令。
|
||||
当任务与某个技能的描述匹配时,调用 activate_skill 工具并传入技能名称来加载完整指令。
|
||||
加载后遵循技能指令执行任务,需要时调用 read_skill_file 读取资源文件内容。
|
||||
${buildSkillPrompt(mainSkills)}`,
|
||||
tools: createSkillTools(mainSkills, { mainSkill: mainSkills, secondarySkills: [], tertiarySkills: [] }),
|
||||
};
|
||||
return res;
|
||||
}
|
||||
|
||||
function removeAllXmlTags(text: string): string {
|
||||
text = text.replace(/<([a-zA-Z][\w-]*)(\s+[^>]*)?>([\s\S]*?)<\/\1>/g, "");
|
||||
text = text.replace(/<([a-zA-Z][\w-]*)(\s+[^>]*)?\/>/g, "");
|
||||
text = text.replace(/<\/?[a-zA-Z][\w-]*(\s+[^>]*)?>/g, "");
|
||||
return text.trim();
|
||||
}
|
||||
|
||||
export function buildSkillPrompt(skills: { name: string; description: string }[]): string {
|
||||
const skillEntries = skills
|
||||
.map((s) => ` <skill>\n <name>${s.name}</name>\n <description>${s.description}</description>\n </skill>`)
|
||||
.join("\n");
|
||||
return `
|
||||
<available_skills>
|
||||
${skillEntries}
|
||||
</available_skills>`;
|
||||
}
|
||||
@ -47,8 +47,8 @@ export async function decisionAI(ctx: AgentContext) {
|
||||
if (!projectInfo) throw new Error(`项目不存在,ID: ${ctx.resTool.data.projectId}`);
|
||||
const [_, imageModelName] = projectInfo.imageModel!.split(":");
|
||||
const [id, videoModelName] = projectInfo.videoModel!.split(":");
|
||||
const data = await u.db("o_vendorConfig").where("id", id).select("models").first();
|
||||
const models = JSON.parse(data!.models!);
|
||||
const models = await u.vendor.getModelList(id);
|
||||
if(!models.length) throw new Error(`项目使用的模型不存在,ID: ${projectInfo.videoModel}`);
|
||||
const findData = models.find((i: any) => i.modelName == videoModelName);
|
||||
const isRef = findData.mode.every((i: any) => Array.isArray(i));
|
||||
const modelInfo = `项目使用的模型如下:\n图像模型:${imageModelName}\n视频模型:${videoModelName}\n多参:${isRef ? "是" : "否"}`;
|
||||
@ -140,8 +140,8 @@ async function createSubAgent(parentCtx: AgentContext) {
|
||||
|
||||
const [_, imageModelName] = projectInfo.imageModel!.split(":");
|
||||
const [id, videoModelName] = projectInfo.videoModel!.split(":");
|
||||
const data = await u.db("o_vendorConfig").where("id", id).select("models").first();
|
||||
const models = JSON.parse(data!.models!);
|
||||
const models = await u.vendor.getModelList(id);
|
||||
if(!models.length) throw new Error(`项目使用的模型不存在,ID: ${projectInfo.videoModel}`);
|
||||
const findData = models.find((i: any) => i.modelName == videoModelName);
|
||||
const isRef = findData.mode.every((i: any) => Array.isArray(i));
|
||||
const modelInfo = `项目使用的模型如下:\n图像模型:${imageModelName}\n视频模型:${videoModelName}\n多参:${isRef ? "是" : "否"}`;
|
||||
|
||||
@ -93,7 +93,7 @@ export default (toolCpnfig: ToolConfig) => {
|
||||
const thinking = msg.thinking(`正在获取脚本内容...`);
|
||||
const data = await u.db("o_script").whereIn("id", ids).select("content", "name");
|
||||
const text = data && data.length ? data.map((d) => `<scriptItem name="${d.name}">${d.content}</scriptItem>`).join("\n") : "";
|
||||
thinking.appendText(`获取到脚本内容:\n` + text);
|
||||
thinking.appendText(`获取到脚本内容:\n` + JSON.stringify(data, null, 2));
|
||||
thinking.updateTitle(`获取脚本内容完成`);
|
||||
thinking.complete();
|
||||
return text ?? "无数据";
|
||||
|
||||
File diff suppressed because one or more lines are too long
@ -85,7 +85,6 @@ export default router.post(
|
||||
.db("o_vendorConfig")
|
||||
.where("id", id)
|
||||
.update({
|
||||
inputValues: JSON.stringify(vendor.inputValues ?? {}),
|
||||
models: JSON.stringify(vendor.models ?? []),
|
||||
});
|
||||
u.vendor.writeCode(id, tsCode);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user