修复 删除视频配置 导致图片丢失,增加魔塔配置,分镜提示词添加台词(待测试)

This commit is contained in:
zhishi 2026-02-28 11:20:22 +08:00
parent 06beb62324
commit fea860e1bb
15 changed files with 185 additions and 176 deletions

View File

@ -58,7 +58,7 @@
"jsonwebtoken": "^9.0.3",
"knex": "^3.1.0",
"morgan": "^1.10.1",
"qwen-ai-provider": "^0.1.1",
"qwen-ai-provider-v5": "^2.1.0",
"serialize-error": "^13.0.1",
"sharp": "^0.34.5",
"sqlite3": "^5.1.7",

View File

@ -242,11 +242,10 @@ ${sections.join("\n\n")}
const skipped: number[] = [];
for (const item of shots) {
const resultIndex = item.segmentIndex - 1;
const exists = this.shots.some((f) => f.segmentId === resultIndex);
const exists = this.shots.some((f) => f.segmentId === item.segmentIndex);
if (exists) {
skipped.push(resultIndex);
skipped.push(item.segmentIndex);
continue;
}
// 分配独立的分镜ID
@ -254,15 +253,15 @@ ${sections.join("\n\n")}
const shotId = this.shotIdCounter;
this.shots.push({
id: shotId,
segmentId: resultIndex,
segmentId: item.segmentIndex,
title: `分镜 ${shotId}`,
x: 0,
y: 0,
cells: item.prompts.map((prompt) => ({ id: u.uuid(), prompt })),
fragmentContent: this.segments[resultIndex]?.description,
fragmentContent: this.segments[item.segmentIndex - 1]?.description,
assetsTags: item.assetsTags,
});
added.push({ id: shotId, segmentIndex: resultIndex });
added.push({ id: shotId, segmentIndex: item.segmentIndex });
}
const addedInfo = added.map((a) => `分镜${a.id}(片段${a.segmentIndex})`).join(", ");

File diff suppressed because one or more lines are too long

View File

@ -436,7 +436,7 @@ export default async (knex: Knex, forceInit: boolean = false): Promise<void> =>
type: "system",
parentCode: null,
defaultValue:
'# 角色定位\\n你是一名专业的视频分镜图片提示词设计师根据用户提供的分镜信息生成具象化的中文图片描述提示词。\\n## 核心任务\\n将分镜名称和描述转化为一条完整、具象化的中文图片提示词供后续AI图像生成使用。\\n---\\n## 描述要素(按优先级排列)\\n### 核心要素(必须包含)\\n1. **镜头语言**:镜头类型(特写/近景/中景/全景/远景)、视角(平视/俯视/仰视)、构图方式\\n2. **场景环境**:场所类型、室内外、时间段、天气、季节氛围\\n3. **人物特征**:数量、性别、年龄、外貌特点、服饰细节、发型、表情状态\\n4. **人物动作**:具体姿态、动态描述、肢体语言、互动行为\\n### 辅助要素(丰富画面)\\n5. **空间布局**:前景中景背景层次、物品摆放、景深关系\\n6. **光影色彩**:光源方向、明暗对比、主色调、情绪氛围\\n7. **道具细节**:重要道具的外观、材质、位置\\n8. **材质质感**:环境或物品的材质特征\\n---\\n## 镜头类型参考\\n- **特写**:局部细节放大,强调情绪或关键物件\\n- **近景**:胸部以上,聚焦面部表情\\n- **中景**:腰部以上,平衡角色与环境\\n- **全景**:全身入镜,展现完整动作姿态\\n- **远景**:人物与环境关系,空间感\\n- **大远景**:环境主导,史诗感或孤独感\\n## 视角参考\\n- **平视**:客观中立的观察视角\\n- **俯视**:表现渺小、脆弱、被压迫\\n- **仰视**:表现威严、力量、崇敬\\n- **斜角**:不安、紧张、失衡感\\n- **肩后视角**:增强代入感和互动感\\n---\\n## 输出规范\\n### 必须遵守\\n- 纯中文描述,一段式连贯输出\\n- 使用具象化、可视化的具体描述,避免抽象词汇\\n- 涵盖镜头语言、场景、人物、光影等关键要素\\n- 只输出提示词本身,不包含任何解释说明\\n### 严格禁止在提示词中包含\\n- 分镜编号、镜号标记(如"场景1"、"镜头5"\\n- 技术注释(如"推镜头"、"淡入淡出"\\n- 时长标记、帧数说明\\n- 任何画外解释性文字\\n- 水印、Logo相关描述\\n---\\n## 输出示例\\n用户输入分镜名称"少年奔跑",描述"主角在校园操场上奔跑"\\n输出\\n全景镜头平视角度阳光明媚的午后校园操场身穿白色运动服的少年正在向前奔跑短发随风飘动侧脸表情专注而坚定双臂有力摆动背景是清晰可见的红色教学楼翠绿草坪平整开阔银色篮球架立于画面右侧整体暖黄色调自然光从左侧照射形成柔和投影充满青春活力氛围\\n---\\n请等待用户提供分镜信息后开始生成提示词。',
'# 角色定位\\n你是一名专业的视频分镜图片提示词设计师根据用户提供的分镜信息生成具象化的中文图片描述提示词,如果剧本中包含对话要把对话加入到提示词中。\\n## 核心任务\\n将分镜名称和描述转化为一条完整、具象化的中文图片提示词供后续AI图像生成使用。\\n---\\n## 描述要素(按优先级排列)\\n### 核心要素(必须包含)\\n1. **镜头语言**:镜头类型(特写/近景/中景/全景/远景)、视角(平视/俯视/仰视)、构图方式\\n2. **场景环境**:场所类型、室内外、时间段、天气、季节氛围\\n3. **人物特征**:数量、性别、年龄、外貌特点、服饰细节、发型、表情状态\\n4. **人物动作**:具体姿态、动态描述、肢体语言、互动行为\\n### 辅助要素(丰富画面)\\n5. **空间布局**:前景中景背景层次、物品摆放、景深关系\\n6. **光影色彩**:光源方向、明暗对比、主色调、情绪氛围\\n7. **道具细节**:重要道具的外观、材质、位置\\n8. **材质质感**:环境或物品的材质特征\\n---\\n## 镜头类型参考\\n- **特写**:局部细节放大,强调情绪或关键物件\\n- **近景**:胸部以上,聚焦面部表情\\n- **中景**:腰部以上,平衡角色与环境\\n- **全景**:全身入镜,展现完整动作姿态\\n- **远景**:人物与环境关系,空间感\\n- **大远景**:环境主导,史诗感或孤独感\\n## 视角参考\\n- **平视**:客观中立的观察视角\\n- **俯视**:表现渺小、脆弱、被压迫\\n- **仰视**:表现威严、力量、崇敬\\n- **斜角**:不安、紧张、失衡感\\n- **肩后视角**:增强代入感和互动感\\n---\\n## 输出规范\\n### 必须遵守\\n- 纯中文描述,一段式连贯输出\\n- 使用具象化、可视化的具体描述,避免抽象词汇\\n- 涵盖镜头语言、场景、人物、光影等关键要素\\n- 只输出提示词本身,不包含任何解释说明\\n### 严格禁止在提示词中包含\\n- 分镜编号、镜号标记(如"场景1"、"镜头5"\\n- 技术注释(如"推镜头"、"淡入淡出"\\n- 时长标记、帧数说明\\n- 任何画外解释性文字\\n- 水印、Logo相关描述\\n---\\n## 输出示例\\n用户输入分镜名称"少年奔跑",描述"主角在校园操场上奔跑"\\n输出\\n全景镜头平视角度阳光明媚的午后校园操场身穿白色运动服的少年正在向前奔跑短发随风飘动侧脸表情专注而坚定双臂有力摆动背景是清晰可见的红色教学楼翠绿草坪平整开阔银色篮球架立于画面右侧整体暖黄色调自然光从左侧照射形成柔和投影充满青春活力氛围\\n---\\n请等待用户提供分镜信息后开始生成提示词。',
customValue: null,
},
{
@ -634,15 +634,16 @@ export default async (knex: Knex, forceInit: boolean = false): Promise<void> =>
},
initData: async (knex) => {
await knex("t_imageModel").insert([
{ id: 1, manufacturer: "volcengine", model: "doubao-seedream-4-5-251128", grid: 0, type: "ti2i" },
{ id: 2, manufacturer: "volcengine", model: "doubao-seedream-4-0-250828", grid: 0, type: "ti2i" },
{ id: 3, manufacturer: "kling", model: "kling-image-o1", grid: 0, type: "ti2i" },
{ id: 4, manufacturer: "gemini", model: "gemini-2.5-flash-image", grid: 1, type: "ti2i" },
{ id: 5, manufacturer: "gemini", model: "gemini-3-pro-image-preview", grid: 1, type: "ti2i" },
{ id: 6, manufacturer: "vidu", model: "viduq1", grid: 0, type: "i2i" },
{ id: 7, manufacturer: "vidu", model: "viduq2", grid: 0, type: "ti2i" },
{ id: 8, manufacturer: "runninghub", model: "nanobanana", grid: 1, type: "ti2i" },
{ id: 9, manufacturer: "modelScope", model: "Qwen/Qwen-Image", grid: 1, type: "ti2i" },
{ manufacturer: "volcengine", model: "doubao-seedream-5-0-260128", grid: 1, type: "ti2i" },
{ manufacturer: "volcengine", model: "doubao-seedream-4-5-251128", grid: 0, type: "ti2i" },
{ manufacturer: "volcengine", model: "doubao-seedream-4-0-250828", grid: 0, type: "ti2i" },
{ manufacturer: "kling", model: "kling-image-o1", grid: 0, type: "ti2i" },
{ manufacturer: "gemini", model: "gemini-2.5-flash-image", grid: 1, type: "ti2i" },
{ manufacturer: "gemini", model: "gemini-3-pro-image-preview", grid: 1, type: "ti2i" },
{ manufacturer: "vidu", model: "viduq1", grid: 0, type: "i2i" },
{ manufacturer: "vidu", model: "viduq2", grid: 0, type: "ti2i" },
{ manufacturer: "runninghub", model: "nanobanana", grid: 1, type: "ti2i" },
{ manufacturer: "modelScope", model: "Qwen/Qwen-Image", grid: 1, type: "ti2i" },
]);
},
},

View File

@ -1,4 +1,4 @@
// @routes-hash bf59be4347a649430bc8b6067c3cf9ef
// @routes-hash c97cf72361299980ea4b0c43549a0de8
import { Express } from "express";
import route1 from "./routes/assets/addAssets";
@ -48,38 +48,41 @@ import route44 from "./routes/script/geScriptApi";
import route45 from "./routes/setting/addModel";
import route46 from "./routes/setting/configurationModel";
import route47 from "./routes/setting/delModel";
import route48 from "./routes/setting/getAiModelMap";
import route49 from "./routes/setting/getLog";
import route50 from "./routes/setting/getSetting";
import route51 from "./routes/setting/getVideoModelList";
import route52 from "./routes/setting/updateModel";
import route53 from "./routes/setting/updeteModel";
import route54 from "./routes/storyboard/batchSuperScoreImage";
import route55 from "./routes/storyboard/chatStoryboard";
import route56 from "./routes/storyboard/delStoryboard";
import route57 from "./routes/storyboard/generateShotImage";
import route58 from "./routes/storyboard/generateStoryboardApi";
import route59 from "./routes/storyboard/generateVideoPrompt";
import route60 from "./routes/storyboard/getStoryboard";
import route61 from "./routes/storyboard/keepStoryboard";
import route62 from "./routes/storyboard/saveStoryboard";
import route63 from "./routes/storyboard/uploadImage";
import route64 from "./routes/task/getTaskApi";
import route65 from "./routes/task/taskDetails";
import route66 from "./routes/user/getUser";
import route67 from "./routes/video/addVideo";
import route68 from "./routes/video/addVideoConfig";
import route69 from "./routes/video/deleteVideoConfig";
import route70 from "./routes/video/generatePrompt";
import route71 from "./routes/video/generateVideo";
import route72 from "./routes/video/getManufacturer";
import route73 from "./routes/video/getVideo";
import route74 from "./routes/video/getVideoConfigs";
import route75 from "./routes/video/getVideoModel";
import route76 from "./routes/video/getVideoStoryboards";
import route77 from "./routes/video/reviseVideoStoryboards";
import route78 from "./routes/video/saveVideo";
import route79 from "./routes/video/upDateVideoConfig";
import route48 from "./routes/setting/getAiModelList";
import route49 from "./routes/setting/getAiModelMap";
import route50 from "./routes/setting/getLog";
import route51 from "./routes/setting/getSetting";
import route52 from "./routes/setting/getVideoModelDetail";
import route53 from "./routes/setting/getVideoModelList";
import route54 from "./routes/setting/updateModel";
import route55 from "./routes/setting/updeteModel";
import route56 from "./routes/storyboard/batchSuperScoreImage";
import route57 from "./routes/storyboard/chatStoryboard";
import route58 from "./routes/storyboard/delStoryboard";
import route59 from "./routes/storyboard/generateShotImage";
import route60 from "./routes/storyboard/generateStoryboardApi";
import route61 from "./routes/storyboard/generateVideoPrompt";
import route62 from "./routes/storyboard/getStoryboard";
import route63 from "./routes/storyboard/keepStoryboard";
import route64 from "./routes/storyboard/saveStoryboard";
import route65 from "./routes/storyboard/uploadImage";
import route66 from "./routes/task/getTaskApi";
import route67 from "./routes/task/taskDetails";
import route68 from "./routes/user/getUser";
import route69 from "./routes/user/saveUser";
import route70 from "./routes/video/addVideo";
import route71 from "./routes/video/addVideoConfig";
import route72 from "./routes/video/deleteVideoConfig";
import route73 from "./routes/video/generatePrompt";
import route74 from "./routes/video/generateVideo";
import route75 from "./routes/video/getManufacturer";
import route76 from "./routes/video/getVideo";
import route77 from "./routes/video/getVideoConfigs";
import route78 from "./routes/video/getVideoModel";
import route79 from "./routes/video/getVideoStoryboards";
import route80 from "./routes/video/reviseVideoStoryboards";
import route81 from "./routes/video/saveVideo";
import route82 from "./routes/video/upDateVideoConfig";
export default async (app: Express) => {
app.use("/assets/addAssets", route1);
@ -129,36 +132,39 @@ export default async (app: Express) => {
app.use("/setting/addModel", route45);
app.use("/setting/configurationModel", route46);
app.use("/setting/delModel", route47);
app.use("/setting/getAiModelMap", route48);
app.use("/setting/getLog", route49);
app.use("/setting/getSetting", route50);
app.use("/setting/getVideoModelList", route51);
app.use("/setting/updateModel", route52);
app.use("/setting/updeteModel", route53);
app.use("/storyboard/batchSuperScoreImage", route54);
app.use("/storyboard/chatStoryboard", route55);
app.use("/storyboard/delStoryboard", route56);
app.use("/storyboard/generateShotImage", route57);
app.use("/storyboard/generateStoryboardApi", route58);
app.use("/storyboard/generateVideoPrompt", route59);
app.use("/storyboard/getStoryboard", route60);
app.use("/storyboard/keepStoryboard", route61);
app.use("/storyboard/saveStoryboard", route62);
app.use("/storyboard/uploadImage", route63);
app.use("/task/getTaskApi", route64);
app.use("/task/taskDetails", route65);
app.use("/user/getUser", route66);
app.use("/video/addVideo", route67);
app.use("/video/addVideoConfig", route68);
app.use("/video/deleteVideoConfig", route69);
app.use("/video/generatePrompt", route70);
app.use("/video/generateVideo", route71);
app.use("/video/getManufacturer", route72);
app.use("/video/getVideo", route73);
app.use("/video/getVideoConfigs", route74);
app.use("/video/getVideoModel", route75);
app.use("/video/getVideoStoryboards", route76);
app.use("/video/reviseVideoStoryboards", route77);
app.use("/video/saveVideo", route78);
app.use("/video/upDateVideoConfig", route79);
app.use("/setting/getAiModelList", route48);
app.use("/setting/getAiModelMap", route49);
app.use("/setting/getLog", route50);
app.use("/setting/getSetting", route51);
app.use("/setting/getVideoModelDetail", route52);
app.use("/setting/getVideoModelList", route53);
app.use("/setting/updateModel", route54);
app.use("/setting/updeteModel", route55);
app.use("/storyboard/batchSuperScoreImage", route56);
app.use("/storyboard/chatStoryboard", route57);
app.use("/storyboard/delStoryboard", route58);
app.use("/storyboard/generateShotImage", route59);
app.use("/storyboard/generateStoryboardApi", route60);
app.use("/storyboard/generateVideoPrompt", route61);
app.use("/storyboard/getStoryboard", route62);
app.use("/storyboard/keepStoryboard", route63);
app.use("/storyboard/saveStoryboard", route64);
app.use("/storyboard/uploadImage", route65);
app.use("/task/getTaskApi", route66);
app.use("/task/taskDetails", route67);
app.use("/user/getUser", route68);
app.use("/user/saveUser", route69);
app.use("/video/addVideo", route70);
app.use("/video/addVideoConfig", route71);
app.use("/video/deleteVideoConfig", route72);
app.use("/video/generatePrompt", route73);
app.use("/video/generateVideo", route74);
app.use("/video/getManufacturer", route75);
app.use("/video/getVideo", route76);
app.use("/video/getVideoConfigs", route77);
app.use("/video/getVideoModel", route78);
app.use("/video/getVideoStoryboards", route79);
app.use("/video/reviseVideoStoryboards", route80);
app.use("/video/saveVideo", route81);
app.use("/video/upDateVideoConfig", route82);
}

View File

@ -48,6 +48,7 @@ export default router.post(
);
res.status(200).send(success(reply));
} catch (err) {
console.log("%c Line:51 🥟 err", "background:#e41a6a", err);
const msg = u.error(err).message;
console.error(msg);
res.status(500).send(error(msg));

View File

@ -1,7 +1,7 @@
import express from "express";
import u from "@/utils";
import { z } from "zod";
import { success } from "@/lib/responseFormat";
import { error, success } from "@/lib/responseFormat";
import { validateFields } from "@/middleware/middleware";
import { generateScript } from "@/utils/generateScript";
const router = express.Router();
@ -43,14 +43,18 @@ export default router.post(
if (novelData.length == 0) return res.status(500).send(success({ message: "原文为空" }));
const result: string = mergeNovelText(novelData);
try {
const data = await generateScript(parameter ?? "", result ?? "");
if (!data) return res.status(500).send({ message: "生成剧本失败" });
const data = await generateScript(parameter ?? "", result ?? "");
if (!data) return res.status(500).send({ message: "生成剧本失败" });
await u.db("t_script").where("id", scriptId).update({
content: data,
});
await u.db("t_script").where("id", scriptId).update({
content: data,
});
res.status(200).send(success({ message: "生成剧本成功" }));
res.status(200).send(success({ message: "生成剧本成功" }));
} catch (e) {
const errMsg = u.error(e).message || "生成剧本失败";
res.status(500).send(error(errMsg));
}
},
);

View File

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

View File

@ -33,9 +33,9 @@ export default router.post(
if (result.filePath) {
filesToDelete.push(result.filePath);
}
if (result.firstFrame) {
filesToDelete.push(result.firstFrame);
}
// if (result.firstFrame) {
// filesToDelete.push(result.firstFrame);
// }
}
// 删除文件

View File

@ -1,20 +1,6 @@
// @db-hash ab4e3e93bfba304164daa7d28c804eaf
// @db-hash 0f9789bd5ad2eebd79bd502988efcb4e
//该文件由脚本自动生成,请勿手动修改
export interface _t_video_old_20260210 {
'aiConfigId'?: number | null;
'configId'?: number | null;
'filePath'?: string | null;
'firstFrame'?: string | null;
'id'?: number;
'model'?: string | null;
'prompt'?: string | null;
'resolution'?: string | null;
'scriptId'?: number | null;
'state'?: number | null;
'storyboardImgs'?: string | null;
'time'?: number | null;
}
export interface t_aiModelMap {
'configId'?: number | null;
'id'?: number;
@ -66,13 +52,6 @@ export interface t_image {
'type'?: string | null;
'videoId'?: number | null;
}
export interface t_imageConfig {
'grid'?: number | null;
'id'?: number;
'manufacturer'?: string | null;
'model'?: string | null;
'type'?: string | null;
}
export interface t_imageModel {
'grid'?: number | null;
'id'?: number;
@ -145,15 +124,6 @@ export interface t_taskList {
'startTime'?: string | null;
'state'?: string | null;
}
export interface t_textConfig {
'id'?: number;
'image'?: number | null;
'manufacturer'?: string | null;
'model'?: string | null;
'responseFormat'?: string | null;
'think'?: number | null;
'tool'?: number | null;
}
export interface t_textModel {
'id'?: number;
'image'?: number | null;
@ -212,13 +182,11 @@ export interface t_videoModel {
}
export interface DB {
"_t_video_old_20260210": _t_video_old_20260210;
"t_aiModelMap": t_aiModelMap;
"t_assets": t_assets;
"t_chatHistory": t_chatHistory;
"t_config": t_config;
"t_image": t_image;
"t_imageConfig": t_imageConfig;
"t_imageModel": t_imageModel;
"t_novel": t_novel;
"t_outline": t_outline;
@ -228,7 +196,6 @@ export interface DB {
"t_setting": t_setting;
"t_storyline": t_storyline;
"t_taskList": t_taskList;
"t_textConfig": t_textConfig;
"t_textModel": t_textModel;
"t_user": t_user;
"t_video": t_video;

View File

@ -69,26 +69,28 @@ export default async (input: ImageConfig, config: AIConfig): Promise<string> =>
console.error(JSON.stringify(result.response, null, 2));
throw new Error("图片生成失败");
}
const mdMatch = result.text.match(/^!\[.*?\]\((.+?)\)$/);
if (mdMatch) {
const imgInfo = mdMatch[1];
const base64InMd = imgInfo.match(/data:image\/[a-z]+;base64,(.+)/);
// 匹配所有 markdown 图片 ![...](url)
const mdImgPattern = /!\[.*?\]\((.+?)\)/g;
const matches = [...result.text.matchAll(mdImgPattern)];
for (const match of matches) {
const imgInfo = match[1];
// 检查是否已是 base64
const base64InMd = imgInfo.match(/data:image\/[a-z]+;base64,.+/);
if (base64InMd) {
return imgInfo;
return imgInfo; // 已经是base64直接返回
} else {
return await urlToBase64(imgInfo);
return await urlToBase64(imgInfo); // 否则尝试转base64
}
}
// 检查纯base64字符串
const base64Match = result.text.match(/base64,([A-Za-z0-9+/=]+)/);
if (base64Match) {
return "data:image/jpeg;base64," + base64Match[1];
}
// 检查是否为图片直链 url
// 检查是否为图片直链
if (/^https?:\/\/.*\.(png|jpg|jpeg|gif|webp|bmp)$/i.test(result.text)) {
return await urlToBase64(result.text);
}
// 默认情况
return result.text;
}

View File

@ -8,18 +8,26 @@ export default async (input: ImageConfig, config: AIConfig): Promise<string> =>
const apiKey = "Bearer " + config.apiKey.replace(/Bearer\s+/g, "").trim();
const size = input.size === "1K" ? "2K" : input.size;
const sizeMap: Record<string, Record<string, string>> = {
"16:9": {
"2K": "2848x1600",
"4K": "4096x2304",
},
"9:16": {
"2K": "1600x2848",
"4K": "2304x4096",
},
};
const body: Record<string, any> = {
model: config.model,
prompt: input.prompt,
size,
size: sizeMap[input.aspectRatio][size],
response_format: "url",
sequential_image_generation: "disabled",
stream: false,
watermark: false,
...(input.imageBase64 && { image: input.imageBase64 }),
};
const url = config.baseURL ?? "https://ark.cn-beijing.volces.com/api/v3/images/generations";
try {
const { data } = await axios.post(url, body, { headers: { Authorization: apiKey } });
@ -28,4 +36,4 @@ export default async (input: ImageConfig, config: AIConfig): Promise<string> =>
const msg = u.error(error).message || "Volcengine 图片生成失败";
throw new Error(msg);
}
}
};

View File

@ -34,7 +34,6 @@ const buildOptions = async (input: AIInput<any>, config: AIConfig = {}) => {
if (!owned) owned = modelList.find((m) => m.manufacturer === manufacturer);
}
if (!owned) throw new Error("不支持的厂商");
console.log("%c Line:36 🥛 owned", "background:#6ec1c2", owned);
const modelInstance = owned.instance({ apiKey, baseURL: baseURL!, name: "xixixi" });
@ -55,8 +54,9 @@ const buildOptions = async (input: AIInput<any>, config: AIConfig = {}) => {
};
const output = input.output ? (outputBuilders[owned.responseFormat]?.(input.output) ?? null) : null;
const chatModelManufacturer = ["volcengine", "other", "openai"];
const chatModelManufacturer = ["volcengine", "other", "openai", "modelScope"];
const modelFn = chatModelManufacturer.includes(owned.manufacturer) ? (modelInstance as OpenAIProvider).chat(model!) : modelInstance(model!);
return {
config: {
model: modelFn as LanguageModel,
@ -79,7 +79,7 @@ const ai = Object.create({}) as {
ai.invoke = async (input: AIInput<any>, config: AIConfig) => {
const options = await buildOptions(input, config);
console.log("%c Line:81 🍧 options", "background:#93c0a4", options);
const result = await generateText(options.config);
if (options.responseFormat === "object" && input.output) {
const pattern = /{[^{}]*}|{(?:[^{}]*|{[^{}]*})*}/g;
@ -96,7 +96,7 @@ ai.invoke = async (input: AIInput<any>, config: AIConfig) => {
ai.stream = async (input: AIInput, config: AIConfig) => {
const options = await buildOptions(input, config);
console.log("%c Line:98 🍬 options", "background:#fca650", options);
return streamText(options.config);
};

View File

@ -1,7 +1,7 @@
import { createOpenAI, OpenAIProviderSettings } from "@ai-sdk/openai";
import { createDeepSeek } from "@ai-sdk/deepseek";
import { createZhipu } from "zhipu-ai-provider";
import { createQwen } from "qwen-ai-provider";
import { createQwen } from "qwen-ai-provider-v5";
import { createGoogleGenerativeAI } from "@ai-sdk/google";
import { createAnthropic } from "@ai-sdk/anthropic";
import { createOpenAICompatible } from "@ai-sdk/openai-compatible";

View File

@ -74,15 +74,6 @@
"@standard-schema/spec" "^1.1.0"
eventsource-parser "^3.0.6"
"@ai-sdk/provider-utils@^2.1.6":
version "2.2.8"
resolved "https://registry.npmmirror.com/@ai-sdk/provider-utils/-/provider-utils-2.2.8.tgz#ad11b92d5a1763ab34ba7b5fc42494bfe08b76d1"
integrity sha512-fqhG+4sCVv8x7nFzYnFo19ryhAa3w096Kmc3hWxMQfW/TubPOmt3A6tYZhl4mUfQWWQMsuSkLrtjlWuXBVSGQA==
dependencies:
"@ai-sdk/provider" "1.1.3"
nanoid "^3.3.8"
secure-json-parse "^2.7.0"
"@ai-sdk/provider-utils@^3.0.0":
version "3.0.20"
resolved "https://registry.npmmirror.com/@ai-sdk/provider-utils/-/provider-utils-3.0.20.tgz#61d7741065550833eae3ac6440d943e9d3d25120"
@ -92,12 +83,14 @@
"@standard-schema/spec" "^1.0.0"
eventsource-parser "^3.0.6"
"@ai-sdk/provider@1.1.3", "@ai-sdk/provider@^1.0.7":
version "1.1.3"
resolved "https://registry.npmmirror.com/@ai-sdk/provider/-/provider-1.1.3.tgz#ebdda8077b8d2b3f290dcba32c45ad19b2704681"
integrity sha512-qZMxYJ0qqX/RfnuIaab+zp8UAeJn/ygXXAffR5I4N0n1IrvA6qBsjc8hXLmBiMV2zoXlifkacF7sEFnYnjBcqg==
"@ai-sdk/provider-utils@^4.0.0":
version "4.0.15"
resolved "https://registry.npmmirror.com/@ai-sdk/provider-utils/-/provider-utils-4.0.15.tgz#d585c7c89cfdf13697a40be5768ecd907a251585"
integrity sha512-8XiKWbemmCbvNN0CLR9u3PQiet4gtEVIrX4zzLxnCj06AwsEDJwJVBbKrEI4t6qE8XRSIvU2irka0dcpziKW6w==
dependencies:
json-schema "^0.4.0"
"@ai-sdk/provider" "3.0.8"
"@standard-schema/spec" "^1.1.0"
eventsource-parser "^3.0.6"
"@ai-sdk/provider@2.0.1", "@ai-sdk/provider@^2.0.0":
version "2.0.1"
@ -113,6 +106,13 @@
dependencies:
json-schema "^0.4.0"
"@ai-sdk/provider@3.0.8", "@ai-sdk/provider@^3.0.0":
version "3.0.8"
resolved "https://registry.npmmirror.com/@ai-sdk/provider/-/provider-3.0.8.tgz#fd7fac7533c03534ac1d3fb710a6b96e2aa00263"
integrity sha512-oGMAgGoQdBXbZqNG0Ze56CHjDZ1IDYOwGYxYjO5KLSlz5HiNQ9udIXsPZ61VWaHGZ5XW/jyjmr6t2xz2jGVwbQ==
dependencies:
json-schema "^0.4.0"
"@ai-sdk/xai@^3.0.47":
version "3.0.47"
resolved "https://registry.npmmirror.com/@ai-sdk/xai/-/xai-3.0.47.tgz#a8d3e08603865c5e401e19c801c7a80c3f31b890"
@ -3160,11 +3160,6 @@ ms@^2.0.0, ms@^2.1.1, ms@^2.1.3:
resolved "https://registry.npmmirror.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2"
integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==
nanoid@^3.3.8:
version "3.3.11"
resolved "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.11.tgz#4f4f112cefbe303202f2199838128936266d185b"
integrity sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==
napi-build-utils@^2.0.0:
version "2.0.0"
resolved "https://registry.npmmirror.com/napi-build-utils/-/napi-build-utils-2.0.0.tgz#13c22c0187fcfccce1461844136372a47ddc027e"
@ -3614,13 +3609,13 @@ quick-lru@^5.1.1:
resolved "https://registry.npmmirror.com/quick-lru/-/quick-lru-5.1.1.tgz#366493e6b3e42a3a6885e2e99d18f80fb7a8c932"
integrity sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==
qwen-ai-provider@^0.1.1:
version "0.1.1"
resolved "https://registry.npmmirror.com/qwen-ai-provider/-/qwen-ai-provider-0.1.1.tgz#f854379514eed919fe01de20007f6238a8ad2b41"
integrity sha512-7dVu97U7fbOGgCYdaOunC4NQqC+7Or3/Gsbx+P16+Ny4VxST7WJxfUCogQl6D2EDxIJdHGz4akHm+5fyEulmyw==
qwen-ai-provider-v5@^2.1.0:
version "2.1.0"
resolved "https://registry.npmmirror.com/qwen-ai-provider-v5/-/qwen-ai-provider-v5-2.1.0.tgz#8672871135bb4a5fda32409c00b70d10637f8a50"
integrity sha512-I+Iv45ymrez1wieZFu0n/lc/lSkbAQMlujWBCfUWBUOf6DizYfvPKaydsojXM7CU8TcqJbYJuN3ofnaxFIwBZA==
dependencies:
"@ai-sdk/provider" "^1.0.7"
"@ai-sdk/provider-utils" "^2.1.6"
"@ai-sdk/provider" "^3.0.0"
"@ai-sdk/provider-utils" "^4.0.0"
range-parser@^1.2.1:
version "1.2.1"
@ -3846,11 +3841,6 @@ sax@^1.2.4:
resolved "https://registry.npmmirror.com/sax/-/sax-1.4.4.tgz#f29c2bba80ce5b86f4343b4c2be9f2b96627cf8b"
integrity sha512-1n3r/tGXO6b6VXMdFT54SHzT9ytu9yr7TaELowdYpMqY/Ao7EnlQGmAQ1+RatX7Tkkdm6hONI2owqNx2aZj5Sw==
secure-json-parse@^2.7.0:
version "2.7.0"
resolved "https://registry.npmmirror.com/secure-json-parse/-/secure-json-parse-2.7.0.tgz#5a5f9cd6ae47df23dba3151edd06855d47e09862"
integrity sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw==
semver-compare@^1.0.0:
version "1.0.0"
resolved "https://registry.npmmirror.com/semver-compare/-/semver-compare-1.0.0.tgz#0dee216a1c941ab37e9efb1788f6afc5ff5537fc"