no message

This commit is contained in:
ACT丶流星雨 2026-02-03 18:27:09 +08:00
parent 07d209d1fe
commit e57728b1c5
13 changed files with 871 additions and 76 deletions

View File

@ -260,12 +260,6 @@ pm2 monit # 监控面板
yarn dev #端口60000 yarn dev #端口60000
``` ```
- 使用 Bun 快速运行开发服务:
```bash
yarn bun:dev #端口60000
```
4. **项目打包** 4. **项目打包**
- 编译并生成 TypeScript 文件: - 编译并生成 TypeScript 文件:

View File

@ -22,13 +22,19 @@
"license": "bun run scripts/license.ts" "license": "bun run scripts/license.ts"
}, },
"dependencies": { "dependencies": {
"@ai-sdk/anthropic": "^3.0.35",
"@ai-sdk/deepseek": "^2.0.17",
"@ai-sdk/google": "^3.0.20",
"@ai-sdk/openai": "^3.0.25",
"@aigne/core": "^1.72.0", "@aigne/core": "^1.72.0",
"@aigne/openai": "^0.16.16", "@aigne/openai": "^0.16.16",
"@langchain/core": "^1.1.15", "@langchain/core": "^1.1.15",
"@langchain/openai": "^1.2.1", "@langchain/openai": "^1.2.1",
"@rmp135/sql-ts": "^2.2.0", "@rmp135/sql-ts": "^2.2.0",
"ai": "^6.0.67",
"axios": "^1.13.2", "axios": "^1.13.2",
"axios-retry": "^4.5.0", "axios-retry": "^4.5.0",
"best-effort-json-parser": "^1.2.1",
"better-sqlite3": "^12.6.2", "better-sqlite3": "^12.6.2",
"cors": "^2.8.5", "cors": "^2.8.5",
"dotenv": "^17.2.3", "dotenv": "^17.2.3",
@ -42,8 +48,10 @@
"knex": "^3.1.0", "knex": "^3.1.0",
"langchain": "^1.2.10", "langchain": "^1.2.10",
"morgan": "^1.10.1", "morgan": "^1.10.1",
"qwen-ai-provider": "^0.1.1",
"sharp": "^0.34.5", "sharp": "^0.34.5",
"sqlite3": "^5.1.7", "sqlite3": "^5.1.7",
"zhipu-ai-provider": "^0.2.2",
"zod": "^4.3.5" "zod": "^4.3.5"
}, },
"devDependencies": { "devDependencies": {

View File

@ -115,19 +115,91 @@ async function mergeImages(imagePaths: string[]): Promise<Buffer> {
return compressImage(mergedImage); return compressImage(mergedImage);
} }
// 处理图片列表确保不超过10张且每张不超过3MB // 进一步压缩单张图片到指定大小
async function compressToSize(buffer: Buffer, targetSize: number): Promise<Buffer> {
if (buffer.length <= targetSize) {
return buffer;
}
const metadata = await sharp(buffer).metadata();
let quality = 80;
let scale = 1.0;
let compressedBuffer = buffer;
// 先尝试降低质量
while (compressedBuffer.length > targetSize && quality > 10) {
compressedBuffer = await sharp(buffer).jpeg({ quality }).toBuffer();
quality -= 10;
}
// 如果还是太大,缩小尺寸
while (compressedBuffer.length > targetSize && scale > 0.2) {
scale -= 0.1;
const newWidth = Math.round((metadata.width || 1000) * scale);
const newHeight = Math.round((metadata.height || 1000) * scale);
compressedBuffer = await sharp(buffer)
.resize(newWidth, newHeight, { fit: "inside" })
.jpeg({ quality: Math.max(quality, 20) })
.toBuffer();
}
return compressedBuffer;
}
// 确保图片列表总大小不超过指定限制
async function ensureTotalSizeLimit(buffers: Buffer[], maxTotalBytes: number = 10 * 1024 * 1024): Promise<Buffer[]> {
let totalSize = buffers.reduce((sum, buf) => sum + buf.length, 0);
if (totalSize <= maxTotalBytes) {
return buffers;
}
// 计算每张图片的平均目标大小
const avgTargetSize = Math.floor(maxTotalBytes / buffers.length);
// 按大小降序排列,优先压缩大图片
const indexedBuffers = buffers.map((buf, idx) => ({ buf, idx, size: buf.length }));
indexedBuffers.sort((a, b) => b.size - a.size);
const result = [...buffers];
for (const item of indexedBuffers) {
totalSize = result.reduce((sum, buf) => sum + buf.length, 0);
if (totalSize <= maxTotalBytes) {
break;
}
// 计算这张图片需要压缩到的目标大小
const excessSize = totalSize - maxTotalBytes;
const targetSize = Math.max(item.buf.length - excessSize, avgTargetSize, 100 * 1024); // 最小100KB
if (item.buf.length > targetSize) {
result[item.idx] = await compressToSize(item.buf, targetSize);
}
}
return result;
}
// 处理图片列表确保不超过10张且每张不超过3MB总大小不超过10MB
async function processImages(images: ImageInfo[]): Promise<Buffer[]> { async function processImages(images: ImageInfo[]): Promise<Buffer[]> {
const maxImages = 10; const maxImages = 10;
let processedBuffers: Buffer[];
if (images.length <= maxImages) { if (images.length <= maxImages) {
const buffers = await Promise.all(images.map((img) => u.oss.getFile(img.filePath))); const buffers = await Promise.all(images.map((img) => u.oss.getFile(img.filePath)));
return Promise.all(buffers.map((buffer) => compressImage(buffer))); processedBuffers = await Promise.all(buffers.map((buffer) => compressImage(buffer)));
} } else {
const mergeStartIndex = maxImages - 1; const mergeStartIndex = maxImages - 1;
const firstBuffers = await Promise.all(images.slice(0, mergeStartIndex).map((img) => u.oss.getFile(img.filePath))); const firstBuffers = await Promise.all(images.slice(0, mergeStartIndex).map((img) => u.oss.getFile(img.filePath)));
const compressedFirstImages = await Promise.all(firstBuffers.map((buffer) => compressImage(buffer))); const compressedFirstImages = await Promise.all(firstBuffers.map((buffer) => compressImage(buffer)));
const imagesToMergeList = images.slice(mergeStartIndex).map((img) => img.filePath); const imagesToMergeList = images.slice(mergeStartIndex).map((img) => img.filePath);
const mergedImage = await mergeImages(imagesToMergeList); const mergedImage = await mergeImages(imagesToMergeList);
return [...compressedFirstImages, mergedImage]; processedBuffers = [...compressedFirstImages, mergedImage];
}
// 确保总大小不超过10MB
return ensureTotalSizeLimit(processedBuffers);
} }
// 使用 AI 过滤与分镜相关的资产 // 使用 AI 过滤与分镜相关的资产

View File

@ -1,13 +1,17 @@
import { Knex } from "knex"; import { Knex } from "knex";
export default async (knex: Knex): Promise<void> => { export default async (knex: Knex): Promise<void> => {
const hasTime = await knex.schema.hasColumn("t_video", "time"); const videoHasTime = await knex.schema.hasColumn("t_video", "time");
if (!hasTime) { if (!videoHasTime) {
await knex.schema.alterTable("t_video", (table) => { await knex.schema.alterTable("t_video", (table) => {
table.integer("time"); table.integer("time");
}); });
console.log("字段 'time' 已添加到 t_video 表"); }
} else {
console.log("t_video 表已存在 'time' 字段"); const configHasIndex = await knex.schema.hasColumn("t_config", "index");
if (configHasIndex) {
await knex.schema.alterTable("t_config", (table) => {
table.dropColumn("index");
});
} }
}; };

View File

@ -1,12 +1,14 @@
import express from "express"; import express from "express";
import { success, error } from "@/lib/responseFormat"; import { success, error } from "@/lib/responseFormat";
import { createAgent } from "langchain";
import { openAI } from "@/agents/models";
import { OpenAIChatModel, type OpenAIChatModelOptions } from "@aigne/openai";
import { validateFields } from "@/middleware/middleware"; import { validateFields } from "@/middleware/middleware";
import u from "@/utils";
import { z } from "zod"; import { z } from "zod";
import { generateText, Output, tool, stepCountIs } from "ai";
const router = express.Router(); const router = express.Router();
import { createOpenAI } from "@ai-sdk/openai";
import { createDeepSeek } from "@ai-sdk/deepseek";
// 检查语言模型 // 检查语言模型
export default router.post( export default router.post(
"/", "/",
@ -17,24 +19,42 @@ export default router.post(
}), }),
async (req, res) => { async (req, res) => {
const { modelName, apiKey, baseURL } = req.body; const { modelName, apiKey, baseURL } = req.body;
const ai = new OpenAIChatModel({
apiKey: apiKey, const getWeatherTool = tool({
baseURL: baseURL, // strict: true,
model: modelName, description: "Get the weather in a location",
modelOptions: { temperature: 0.7 }, inputSchema: z.object({
location: z.string().describe("The location to get the weather for"),
}),
execute: async ({ location }) => {
return {
location,
temperature: 72 + Math.floor(Math.random() * 21) - 10,
};
},
}); });
try { try {
const data = await ai.invoke({ const { reply } = await u.ai.text.invoke(
messages: [
{ {
role: "user", prompt: "请调用工具获取北京的天气,并回答我多少气温",
content: "hello", tools: { getWeatherTool },
output: {
reply: z.string().describe("回复内容"),
}, },
], },
}); {
res.status(200).send(success(data)); model: modelName,
} catch (err: any) { apiKey,
res.status(500).send(error(err.error.message || "模型调用失败")); baseURL,
},
);
console.log("%c Line:52 🍐 reply", "background:#ffdd4d", reply);
res.status(200).send(success(reply));
} catch (err) {
console.log(err);
if (typeof err === "string") return res.status(500).send(error(err));
const msg = err instanceof Error ? err.message : (err as any)?.error?.message;
return res.status(500).send(error(msg || "未知错误"));
} }
}, },
); );

View File

@ -1,9 +1,6 @@
import express from "express"; import express from "express";
import { success, error } from "@/lib/responseFormat"; import { success, error } from "@/lib/responseFormat";
import u from "@/utils"; import u from "@/utils";
import { createAgent } from "langchain";
import { openAI } from "@/agents/models";
import { OpenAIChatModel, type OpenAIChatModelOptions } from "@aigne/openai";
import { validateFields } from "@/middleware/middleware"; import { validateFields } from "@/middleware/middleware";
import { z } from "zod"; import { z } from "zod";
const router = express.Router(); const router = express.Router();

View File

@ -15,7 +15,7 @@ export default router.post(
const settingData = await u.db("t_setting").select("*"); const settingData = await u.db("t_setting").select("*");
const configData = await u.db("t_config").where("userId", userId).select("*").orderBy("index", "asc"); const configData = await u.db("t_config").where("userId", userId).select("*") ;
const parsedData = settingData.map((item) => ({ const parsedData = settingData.map((item) => ({
...item, ...item,

View File

@ -1,16 +1,20 @@
import db from "@/utils/db"; import db from "@/utils/db";
import oss from "@/utils/oss"; import oss from "@/utils/oss";
import * as ai from "@/utils/ai"; // import * as ai from "@/utils/ai";
import editImage from "@/utils/editImage"; import editImage from "@/utils/editImage";
import number2Chinese from "@/utils/number2Chinese"; import number2Chinese from "@/utils/number2Chinese";
import deleteOutline from "@/utils/deleteOutline"; import deleteOutline from "@/utils/deleteOutline";
import getConfig from "./utils/getConfig"; import getConfig from "./utils/getConfig";
import { v4 as uuid } from "uuid"; import { v4 as uuid } from "uuid";
import AIText from "@/utils/ai/text";
export default { export default {
db, db,
oss, oss,
ai, ai: {
text: AIText,
},
editImage, editImage,
number2Chinese, number2Chinese,
deleteOutline, deleteOutline,

414
src/utils/ai/modelList.ts Normal file
View File

@ -0,0 +1,414 @@
import { createOpenAI } from "@ai-sdk/openai";
import { createDeepSeek } from "@ai-sdk/deepseek";
import { createZhipu } from "zhipu-ai-provider";
import { createQwen } from "qwen-ai-provider";
import { createGoogleGenerativeAI } from "@ai-sdk/google";
import { createAnthropic } from "@ai-sdk/anthropic";
interface Owned {
manufacturer: string;
model: string;
responseFormat: "schema" | "object";
image: boolean;
think: boolean;
tool: boolean;
instance:
| typeof createOpenAI
| typeof createDeepSeek
| typeof createZhipu
| typeof createQwen
| typeof createGoogleGenerativeAI
| typeof createAnthropic;
}
const modelList: Owned[] = [
// DeepSeek
{
manufacturer: "deepseek",
model: "deepseek-chat",
responseFormat: "schema",
image: false,
think: false,
instance: createDeepSeek,
tool: true,
},
{
manufacturer: "deepseek",
model: "deepseek-reasoner",
responseFormat: "schema",
image: false,
think: true,
instance: createDeepSeek,
tool: true,
},
// 豆包
{
manufacturer: "doubao",
model: "doubao-seed-1-8",
responseFormat: "schema",
image: true,
think: true,
instance: createOpenAI,
tool: true,
},
{
manufacturer: "doubao",
model: "doubao-seed-1-6",
responseFormat: "schema",
image: true,
think: true,
instance: createOpenAI,
tool: true,
},
{
manufacturer: "doubao",
model: "doubao-seed-1-6-lite",
responseFormat: "schema",
image: true,
think: true,
instance: createOpenAI,
tool: true,
},
{
manufacturer: "doubao",
model: "doubao-seed-1-6-flash",
responseFormat: "schema",
image: true,
think: true,
instance: createOpenAI,
tool: true,
},
// GLM
{
manufacturer: "zhipu",
model: "glm-4.7",
responseFormat: "object",
image: false,
think: false,
instance: createZhipu,
tool: true,
},
{
manufacturer: "zhipu",
model: "glm-4.7-flashx",
responseFormat: "object",
image: false,
think: false,
instance: createZhipu,
tool: true,
},
{
manufacturer: "zhipu",
model: "glm-4.6",
responseFormat: "object",
image: false,
think: false,
instance: createZhipu,
tool: true,
},
{
manufacturer: "zhipu",
model: "glm-4.5-air",
responseFormat: "object",
image: false,
think: false,
instance: createZhipu,
tool: true,
},
{
manufacturer: "zhipu",
model: "glm-4.5-airx",
responseFormat: "object",
image: false,
think: false,
instance: createZhipu,
tool: true,
},
{
manufacturer: "zhipu",
model: "glm-4-long",
responseFormat: "object",
image: false,
think: false,
instance: createZhipu,
tool: true,
},
{
manufacturer: "zhipu",
model: "glm-4-flashx-250414",
responseFormat: "object",
image: false,
think: false,
instance: createZhipu,
tool: true,
},
{
manufacturer: "zhipu",
model: "glm-4.7-flash",
responseFormat: "object",
image: false,
think: false,
instance: createZhipu,
tool: true,
},
{
manufacturer: "zhipu",
model: "glm-4.5-flash",
responseFormat: "object",
image: false,
think: true,
instance: createZhipu,
tool: true,
},
{
manufacturer: "zhipu",
model: "glm-4-flash-250414",
responseFormat: "object",
image: false,
think: false,
instance: createZhipu,
tool: true,
},
{
manufacturer: "zhipu",
model: "glm-4.6v",
responseFormat: "object",
image: true,
think: true,
instance: createZhipu,
tool: true,
},
// Qwen
{
manufacturer: "qwen",
model: "qwen-vl-max",
responseFormat: "schema",
image: true,
think: false,
instance: createQwen,
tool: true,
},
{
manufacturer: "qwen",
model: "qwen-plus-latest",
responseFormat: "schema",
image: false,
think: false,
instance: createQwen,
tool: true,
},
{
manufacturer: "qwen",
model: "qwen-max",
responseFormat: "schema",
image: false,
think: false,
instance: createQwen,
tool: true,
},
{
manufacturer: "qwen",
model: "qwen2.5-72b-instruct",
responseFormat: "schema",
image: false,
think: false,
instance: createQwen,
tool: true,
},
{
manufacturer: "qwen",
model: "qwen2.5-14b-instruct-1m",
responseFormat: "schema",
image: false,
think: false,
instance: createQwen,
tool: true,
},
{
manufacturer: "qwen",
model: "qwen2.5-vl-72b-instruct",
responseFormat: "schema",
image: true,
think: false,
instance: createQwen,
tool: true,
},
// OpenAI
{
manufacturer: "openai",
model: "gpt-4o",
responseFormat: "schema",
image: true,
think: false,
instance: createOpenAI,
tool: true,
},
{
manufacturer: "openai",
model: "gpt-4o-mini",
responseFormat: "schema",
image: true,
think: false,
instance: createOpenAI,
tool: true,
},
{
manufacturer: "openai",
model: "gpt-4.1",
responseFormat: "schema",
image: true,
think: false,
instance: createOpenAI,
tool: true,
},
{
manufacturer: "openai",
model: "gpt-5.1",
responseFormat: "schema",
image: true,
think: false,
instance: createOpenAI,
tool: true,
},
{
manufacturer: "openai",
model: "gpt-5.2",
responseFormat: "schema",
image: true,
think: false,
instance: createOpenAI,
tool: true,
},
// Gemini
{
manufacturer: "google",
model: "gemini-2.5-pro",
responseFormat: "schema",
image: true,
think: true,
instance: createGoogleGenerativeAI,
tool: true,
},
{
manufacturer: "google",
model: "gemini-2.5-flash",
responseFormat: "schema",
image: true,
think: true,
instance: createGoogleGenerativeAI,
tool: true,
},
{
manufacturer: "google",
model: "gemini-2.0-flash",
responseFormat: "schema",
image: true,
think: false,
instance: createGoogleGenerativeAI,
tool: true,
},
{
manufacturer: "google",
model: "gemini-2.0-flash-lite",
responseFormat: "schema",
image: true,
think: false,
instance: createGoogleGenerativeAI,
tool: true,
},
{
manufacturer: "google",
model: "gemini-1.5-pro",
responseFormat: "schema",
image: true,
think: false,
instance: createGoogleGenerativeAI,
tool: true,
},
{
manufacturer: "google",
model: "gemini-1.5-flash",
responseFormat: "schema",
image: true,
think: false,
instance: createGoogleGenerativeAI,
tool: true,
},
// Anthropic (Claude)
{
manufacturer: "anthropic",
model: "claude-opus-4-5",
responseFormat: "schema",
image: true,
think: false,
instance: createAnthropic,
tool: true,
},
{
manufacturer: "anthropic",
model: "claude-haiku-4-5",
responseFormat: "schema",
image: true,
think: false,
instance: createAnthropic,
tool: true,
},
{
manufacturer: "anthropic",
model: "claude-sonnet-4-5",
responseFormat: "schema",
image: true,
think: false,
instance: createAnthropic,
tool: true,
},
{
manufacturer: "anthropic",
model: "claude-opus-4-1",
responseFormat: "schema",
image: true,
think: false,
instance: createAnthropic,
tool: true,
},
{
manufacturer: "anthropic",
model: "claude-opus-4-0",
responseFormat: "schema",
image: true,
think: false,
instance: createAnthropic,
tool: true,
},
{
manufacturer: "anthropic",
model: "claude-sonnet-4-0",
responseFormat: "schema",
image: true,
think: false,
instance: createAnthropic,
tool: true,
},
{
manufacturer: "anthropic",
model: "claude-3-7-sonnet-latest",
responseFormat: "schema",
image: true,
think: false,
instance: createAnthropic,
tool: true,
},
{
manufacturer: "anthropic",
model: "claude-3-5-haiku-latest",
responseFormat: "schema",
image: true,
think: false,
instance: createAnthropic,
tool: true,
},
];
export default modelList;

88
src/utils/ai/text.ts Normal file
View File

@ -0,0 +1,88 @@
import u from "@/utils";
import { generateText, streamText, Output, stepCountIs, ModelMessage, LanguageModel, Tool, GenerateTextResult } from "ai";
import { parse } from "best-effort-json-parser";
import modelList from "./modelList";
import { z } from "zod";
interface AIInput<T extends Record<string, z.ZodTypeAny> | undefined = undefined> {
system?: string;
tools?: Record<string, Tool>;
maxStep?: number;
output?: T;
prompt?: string;
messages?: Array<ModelMessage>;
}
interface AIConfig {
model?: string;
apiKey?: string;
baseURL?: string;
}
const buildOptions = async (input: AIInput<any>, config: AIConfig) => {
const sqlTextModelConfig = await u.getConfig("text");
const { model, apiKey, baseURL } = { ...sqlTextModelConfig, ...config };
const owned = modelList.find((m) => m.model === model);
if (!owned) throw new Error("不支持的模型或厂商");
const modelInstance = owned.instance({ apiKey, baseURL });
const maxStep = input.maxStep ?? (input.tools ? Object.keys(input.tools).length * 5 : undefined);
const outputBuilders: Record<string, (schema: any) => any> = {
schema: (s) => Output.object({ schema: z.object(s) }),
object: () => {
const jsonSchemaPrompt = `\n请按照以下 JSON Schema 格式返回结果:\n${JSON.stringify(
z.toJSONSchema(z.object(input.output)),
null,
2,
)}\n只返回结果Schema返回`;
input.system = (input.system ?? "") + jsonSchemaPrompt;
// return Output.json();
},
};
const output = input.output ? outputBuilders[owned.responseFormat]?.(input.output) ?? null : null;
return {
config: {
model: modelInstance(model) as LanguageModel,
...(input.system && { system: input.system }),
...(input.prompt ? { prompt: input.prompt } : { messages: input.messages! }),
...(input.tools && owned.tool && { tools: input.tools }),
...(maxStep && { stopWhen: stepCountIs(maxStep) }),
...(output && { output }),
},
responseFormat: owned.responseFormat,
};
};
type InferOutput<T> = T extends Record<string, z.ZodTypeAny> ? z.infer<z.ZodObject<T>> : GenerateTextResult<Record<string, Tool>, never>;
const ai = Object.create({}) as {
invoke<T extends Record<string, z.ZodTypeAny> | undefined = undefined>(input: AIInput<T>, config?: AIConfig): Promise<InferOutput<T>>;
stream(input: AIInput, config?: AIConfig): Promise<ReturnType<typeof streamText>>;
};
ai.invoke = async (input: AIInput<any>, config: AIConfig = {}) => {
const options = await buildOptions(input, config);
const result = await generateText(options.config);
if (options.responseFormat === "object" && input.output) {
const pattern = /{[^{}]*}|{(?:[^{}]*|{[^{}]*})*}/g;
const jsonLikeTexts = Array.from(result.text.matchAll(pattern), (m) => m[0]);
const res = jsonLikeTexts.map((jsonText) => parse(jsonText));
return res[0];
}
if (options.responseFormat === "schema" && input.output) {
return JSON.parse(result.text);
}
return result;
};
ai.stream = async (input: AIInput, config: AIConfig = {}) => {
const options = await buildOptions(input, config);
return streamText(options.config);
};
export default ai;

View File

@ -0,0 +1,43 @@
import u from "@/utils";
// 只包含 t_setting 表里实际存在的字段
const modelFields = {
image: "imageModel",
language: "languageModel",
} as const;
interface resData {
model: string;
apiKey: string;
baseURL: string;
manufacturer: "openAi" | "volcengine" | "runninghub" | "gemini" | "apimart";
}
type ModelType = keyof typeof modelFields;
// 定义返回类型映射
type ReturnType<T extends string> = T extends "video" ? resData[] : resData;
// 主方法
export default async function getConfig<T extends ModelType | "video">(type: T, manufacturer?: string): Promise<ReturnType<T>> {
if (type === "video") {
// 查询 t_config 表,返回数组
const configList = await u.db("t_config").where("manufacturer", manufacturer).orderBy("index", "asc");
return configList.map((i) => {
return {
...i,
baseURL: i.baseUrl,
};
}) as ReturnType<T>;
}
// 只查询当前需要的字段
const modelName = modelFields[type as ModelType];
const data: Record<string, any> | undefined = await u.db("t_setting").where({ id: 1 }).select([modelName]).first();
if (!data) throw new Error("设置数据不存在");
// 字段值为 JSON 字符串,解析
return JSON.parse(data[modelName] || "{}") as ReturnType<T>;
}

View File

@ -1,44 +1,55 @@
import u from "@/utils"; import u from "@/utils";
// 只包含 t_setting 表里实际存在的字段 type AIType = "text" | "image" | "video";
const modelFields = {
image: "imageModel",
language: "languageModel",
doubao: "doubaoModel",
} as const;
interface resData { interface BaseConfig {
model: string; model: string;
apiKey: string; apiKey: string;
manufacturer: string;
}
interface TextResData extends BaseConfig {
baseURL: string; baseURL: string;
manufacturer: "openAi" | "volcengine" | "runninghub" | "gemini" | "apimart"; manufacturer: "deepseek" | "openAi" | "doubao";
} }
type ModelType = keyof typeof modelFields; interface ImageResData extends BaseConfig {
manufacturer: "openAi" | "gemini" | "volcengine" | "runninghub" | "apimart";
}
// 定义返回类型映射 interface VideoResData extends BaseConfig {
type ReturnType<T extends string> = T extends "video" ? resData[] : resData; baseURL: string;
manufacturer: "openAi" | "volcengine" | "runninghub" | "apimart" | "confyUI";
}
// 主方法 type ResDataMap = {
export default async function getConfig<T extends ModelType | "video">(type: T, manufacturer?: string): Promise<ReturnType<T>> { text: TextResData;
if (type === "video") { image: ImageResData;
// 查询 t_config 表,返回数组 video: VideoResData;
const configList = await u.db("t_config").where("manufacturer", manufacturer).orderBy("index", "asc");
return configList.map((i) => {
return {
...i,
baseURL: i.baseUrl,
}; };
}) as ReturnType<T>;
const errorMessages: Record<AIType, string> = {
text: "文本模型配置不存在",
image: "图像模型配置不存在",
video: "视频模型配置不存在",
};
const needBaseURL: AIType[] = ["text", "video"];
export default async function getConfig<T extends AIType>(aiType: T): Promise<ResDataMap[T]> {
const config = await u.db("t_config").where("type", aiType).first();
if (!config) throw new Error(errorMessages[aiType]);
const result: BaseConfig = {
model: config?.model ?? "",
apiKey: config?.apiKey ?? "",
manufacturer: config?.manufacturer ?? "",
};
if (needBaseURL.includes(aiType)) {
return { ...result, baseURL: config.baseUrl } as ResDataMap[T];
} }
// 只查询当前需要的字段 return result as ResDataMap[T];
const modelName = modelFields[type as ModelType];
const data: Record<string, any> | undefined = await u.db("t_setting").where({ id: 1 }).select([modelName]).first();
if (!data) throw new Error("设置数据不存在");
// 字段值为 JSON 字符串,解析
return JSON.parse(data[modelName] || "{}") as ReturnType<T>;
} }

144
yarn.lock
View File

@ -7,6 +7,95 @@
resolved "https://registry.npmmirror.com/7zip-bin/-/7zip-bin-5.2.0.tgz#7a03314684dd6572b7dfa89e68ce31d60286854d" resolved "https://registry.npmmirror.com/7zip-bin/-/7zip-bin-5.2.0.tgz#7a03314684dd6572b7dfa89e68ce31d60286854d"
integrity sha512-ukTPVhqG4jNzMro2qA9HSCSSVJN3aN7tlb+hfqYCt3ER0yWroeA2VR38MNrOHLQ/cVj+DaIMad0kFCtWWowh/A== integrity sha512-ukTPVhqG4jNzMro2qA9HSCSSVJN3aN7tlb+hfqYCt3ER0yWroeA2VR38MNrOHLQ/cVj+DaIMad0kFCtWWowh/A==
"@ai-sdk/anthropic@^3.0.35":
version "3.0.35"
resolved "https://registry.npmmirror.com/@ai-sdk/anthropic/-/anthropic-3.0.35.tgz#334bf3f5415ebab77cf23d52f197b8027087821e"
integrity sha512-Y3g/5uVj621XSB9lGF7WrD7qR+orhV5xpaYkRF8kfj2j4W7e7BBGIvxcdsCf85FjJbc6tKQdNTZ84ZEqT3Y5TQ==
dependencies:
"@ai-sdk/provider" "3.0.7"
"@ai-sdk/provider-utils" "4.0.13"
"@ai-sdk/deepseek@^2.0.17":
version "2.0.17"
resolved "https://registry.npmmirror.com/@ai-sdk/deepseek/-/deepseek-2.0.17.tgz#14a8460d141d36fda08040074b887b2fab06948e"
integrity sha512-rkZiasQ24UyOMiZd8Mb7R+OF3Yt90bRQyfyzIkrb0zKZj7kU2h2z2nu1CO6j0X8poE+SZhEEaHOBFhRcp6hKVg==
dependencies:
"@ai-sdk/provider" "3.0.7"
"@ai-sdk/provider-utils" "4.0.13"
"@ai-sdk/gateway@3.0.32":
version "3.0.32"
resolved "https://registry.npmmirror.com/@ai-sdk/gateway/-/gateway-3.0.32.tgz#4738f75fc2eba7f245f77fd0dc139225a08c9c47"
integrity sha512-7clZRr07P9rpur39t1RrbIe7x8jmwnwUWI8tZs+BvAfX3NFgdSVGGIaT7bTz2pb08jmLXzTSDbrOTqAQ7uBkBQ==
dependencies:
"@ai-sdk/provider" "3.0.7"
"@ai-sdk/provider-utils" "4.0.13"
"@vercel/oidc" "3.1.0"
"@ai-sdk/google@^3.0.20":
version "3.0.20"
resolved "https://registry.npmmirror.com/@ai-sdk/google/-/google-3.0.20.tgz#608ec12a13371439a6a06992fb7e7d1d4d029432"
integrity sha512-bVGsulEr6JiipAFlclo9bjL5WaUV0iCSiiekLt+PY6pwmtJeuU2GaD9DoE3OqR8LN2W779mU13IhVEzlTupf8g==
dependencies:
"@ai-sdk/provider" "3.0.7"
"@ai-sdk/provider-utils" "4.0.13"
"@ai-sdk/openai@^3.0.25":
version "3.0.25"
resolved "https://registry.npmmirror.com/@ai-sdk/openai/-/openai-3.0.25.tgz#452c8f8ed597468048569ec9476a0b5641888d2a"
integrity sha512-DsaN46R98+D1W3lU3fKuPU3ofacboLaHlkAwxJPgJ8eup1AJHmPK1N1y10eJJbJcF6iby8Tf/vanoZxc9JPUfw==
dependencies:
"@ai-sdk/provider" "3.0.7"
"@ai-sdk/provider-utils" "4.0.13"
"@ai-sdk/provider-utils@4.0.13":
version "4.0.13"
resolved "https://registry.npmmirror.com/@ai-sdk/provider-utils/-/provider-utils-4.0.13.tgz#d2240b0c4d701eef8a4273ade71585a691e34e04"
integrity sha512-HHG72BN4d+OWTcq2NwTxOm/2qvk1duYsnhCDtsbYwn/h/4zeqURu1S0+Cn0nY2Ysq9a9HGKvrYuMn9bgFhR2Og==
dependencies:
"@ai-sdk/provider" "3.0.7"
"@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"
integrity sha512-iXHVe0apM2zUEzauqJwqmpC37A5rihrStAih5Ks+JE32iTe4LZ58y17UGBjpQQTCRw9YxMeo2UFLxLpBluyvLQ==
dependencies:
"@ai-sdk/provider" "2.0.1"
"@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==
dependencies:
json-schema "^0.4.0"
"@ai-sdk/provider@2.0.1", "@ai-sdk/provider@^2.0.0":
version "2.0.1"
resolved "https://registry.npmmirror.com/@ai-sdk/provider/-/provider-2.0.1.tgz#4aba415f1815da33a7a81e5f41a0219af53278c0"
integrity sha512-KCUwswvsC5VsW2PWFqF8eJgSCu5Ysj7m1TxiHTVA6g7k360bk0RNQENT8KTMAYEs+8fWPD3Uu4dEmzGHc+jGng==
dependencies:
json-schema "^0.4.0"
"@ai-sdk/provider@3.0.7":
version "3.0.7"
resolved "https://registry.npmmirror.com/@ai-sdk/provider/-/provider-3.0.7.tgz#470bb8f9e46ec9d8d62b07b4c1f5737b991ebe83"
integrity sha512-VkPLrutM6VdA924/mG8OS+5frbVTcu6e046D2bgDo00tehBANR1QBJ/mPcZ9tXMFOsVcm6SQArOregxePzTFPw==
dependencies:
json-schema "^0.4.0"
"@aigne/afs-history@^1.2.0": "@aigne/afs-history@^1.2.0":
version "1.2.0" version "1.2.0"
resolved "https://registry.npmmirror.com/@aigne/afs-history/-/afs-history-1.2.0.tgz#42086667ee83f2bbe181b247d6987cd05793d96f" resolved "https://registry.npmmirror.com/@aigne/afs-history/-/afs-history-1.2.0.tgz#42086667ee83f2bbe181b247d6987cd05793d96f"
@ -969,7 +1058,7 @@
dependencies: dependencies:
"@opentelemetry/api" "^1.3.0" "@opentelemetry/api" "^1.3.0"
"@opentelemetry/api@^1.3.0", "@opentelemetry/api@^1.9.0": "@opentelemetry/api@1.9.0", "@opentelemetry/api@^1.3.0", "@opentelemetry/api@^1.9.0":
version "1.9.0" version "1.9.0"
resolved "https://registry.npmmirror.com/@opentelemetry/api/-/api-1.9.0.tgz#d03eba68273dc0f7509e2a3d5cba21eae10379fe" resolved "https://registry.npmmirror.com/@opentelemetry/api/-/api-1.9.0.tgz#d03eba68273dc0f7509e2a3d5cba21eae10379fe"
integrity sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg== integrity sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==
@ -1348,7 +1437,7 @@
resolved "https://registry.npmmirror.com/@sqlite.org/sqlite-wasm/-/sqlite-wasm-3.50.1-build1.tgz#67dd9944b0e37ddb0ef2c8b195baa74ece838e44" resolved "https://registry.npmmirror.com/@sqlite.org/sqlite-wasm/-/sqlite-wasm-3.50.1-build1.tgz#67dd9944b0e37ddb0ef2c8b195baa74ece838e44"
integrity sha512-yH4M/SHN98NibniIwTVk6rwTJjy7n39l7zwWY3u+qsfZBGTi4lC1uEl2NDvIlkzsFtfCBvHBJJFJ1iuU3UzzEQ== integrity sha512-yH4M/SHN98NibniIwTVk6rwTJjy7n39l7zwWY3u+qsfZBGTi4lC1uEl2NDvIlkzsFtfCBvHBJJFJ1iuU3UzzEQ==
"@standard-schema/spec@1.1.0": "@standard-schema/spec@1.1.0", "@standard-schema/spec@^1.0.0", "@standard-schema/spec@^1.1.0":
version "1.1.0" version "1.1.0"
resolved "https://registry.npmmirror.com/@standard-schema/spec/-/spec-1.1.0.tgz#a79b55dbaf8604812f52d140b2c9ab41bc150bb8" resolved "https://registry.npmmirror.com/@standard-schema/spec/-/spec-1.1.0.tgz#a79b55dbaf8604812f52d140b2c9ab41bc150bb8"
integrity sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w== integrity sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==
@ -1574,6 +1663,11 @@
resolved "https://registry.npmmirror.com/@ungap/with-resolvers/-/with-resolvers-0.1.0.tgz#63a07b13bbf10ffff074a36498cce8d82aeeecc4" resolved "https://registry.npmmirror.com/@ungap/with-resolvers/-/with-resolvers-0.1.0.tgz#63a07b13bbf10ffff074a36498cce8d82aeeecc4"
integrity sha512-g7f0IkJdPW2xhY7H4iE72DAsIyfuwEFc6JWc2tYFwKDMWWAF699vGjrM348cwQuOXgHpe1gWFe+Eiyjx/ewvvw== integrity sha512-g7f0IkJdPW2xhY7H4iE72DAsIyfuwEFc6JWc2tYFwKDMWWAF699vGjrM348cwQuOXgHpe1gWFe+Eiyjx/ewvvw==
"@vercel/oidc@3.1.0":
version "3.1.0"
resolved "https://registry.npmmirror.com/@vercel/oidc/-/oidc-3.1.0.tgz#066caee449b84079f33c7445fc862464fe10ec32"
integrity sha512-Fw28YZpRnA3cAHHDlkt7xQHiJ0fcL+NRcIqsocZQUSmbzeIKRpwttJjik5ZGanXP+vlA4SbTg+AbA3bP363l+w==
"@xmldom/xmldom@^0.8.8": "@xmldom/xmldom@^0.8.8":
version "0.8.11" version "0.8.11"
resolved "https://registry.npmmirror.com/@xmldom/xmldom/-/xmldom-0.8.11.tgz#b79de2d67389734c57c52595f7a7305e30c2d608" resolved "https://registry.npmmirror.com/@xmldom/xmldom/-/xmldom-0.8.11.tgz#b79de2d67389734c57c52595f7a7305e30c2d608"
@ -1651,6 +1745,16 @@ aggregate-error@^3.0.0:
clean-stack "^2.0.0" clean-stack "^2.0.0"
indent-string "^4.0.0" indent-string "^4.0.0"
ai@^6.0.67:
version "6.0.67"
resolved "https://registry.npmmirror.com/ai/-/ai-6.0.67.tgz#eb808301e0196915b9fe097ac7de47ce8131c2a9"
integrity sha512-xBnTcByHCj3OcG6V8G1s6zvSEqK0Bdiu+IEXYcpGrve1iGFFRgcrKeZtr/WAW/7gupnSvBbDF24BEv1OOfqi1g==
dependencies:
"@ai-sdk/gateway" "3.0.32"
"@ai-sdk/provider" "3.0.7"
"@ai-sdk/provider-utils" "4.0.13"
"@opentelemetry/api" "1.9.0"
ajv-formats@^3.0.1: ajv-formats@^3.0.1:
version "3.0.1" version "3.0.1"
resolved "https://registry.npmmirror.com/ajv-formats/-/ajv-formats-3.0.1.tgz#3d5dc762bca17679c3c2ea7e90ad6b7532309578" resolved "https://registry.npmmirror.com/ajv-formats/-/ajv-formats-3.0.1.tgz#3d5dc762bca17679c3c2ea7e90ad6b7532309578"
@ -1911,6 +2015,11 @@ basic-auth@~2.0.1:
dependencies: dependencies:
safe-buffer "5.1.2" safe-buffer "5.1.2"
best-effort-json-parser@^1.2.1:
version "1.2.1"
resolved "https://registry.npmmirror.com/best-effort-json-parser/-/best-effort-json-parser-1.2.1.tgz#e8d0b8355a0c268d918681faa0e3cf6aa192ea00"
integrity sha512-UICSLibQdzS1f+PBsi3u2YE3SsdXcWicHUg3IMvfuaePS2AYnZJdJeKhGv5OM8/mqJwPt79aDrEJ1oa84tELvw==
better-sqlite3@^12.6.2: better-sqlite3@^12.6.2:
version "12.6.2" version "12.6.2"
resolved "https://registry.npmmirror.com/better-sqlite3/-/better-sqlite3-12.6.2.tgz#770649f28a62e543a360f3dfa1afe4cc944b1937" resolved "https://registry.npmmirror.com/better-sqlite3/-/better-sqlite3-12.6.2.tgz#770649f28a62e543a360f3dfa1afe4cc944b1937"
@ -3779,6 +3888,11 @@ json-schema-typed@^8.0.2:
resolved "https://registry.npmmirror.com/json-schema-typed/-/json-schema-typed-8.0.2.tgz#e98ee7b1899ff4a184534d1f167c288c66bbeff4" resolved "https://registry.npmmirror.com/json-schema-typed/-/json-schema-typed-8.0.2.tgz#e98ee7b1899ff4a184534d1f167c288c66bbeff4"
integrity sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA== integrity sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA==
json-schema@^0.4.0:
version "0.4.0"
resolved "https://registry.npmmirror.com/json-schema/-/json-schema-0.4.0.tgz#f7de4cf6efab838ebaeb3236474cbba5a1930ab5"
integrity sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==
json-stringify-safe@^5.0.1: json-stringify-safe@^5.0.1:
version "5.0.1" version "5.0.1"
resolved "https://registry.npmmirror.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" resolved "https://registry.npmmirror.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb"
@ -4327,6 +4441,11 @@ mute-stream@^2.0.0:
resolved "https://registry.npmmirror.com/mute-stream/-/mute-stream-2.0.0.tgz#a5446fc0c512b71c83c44d908d5c7b7b4c493b2b" resolved "https://registry.npmmirror.com/mute-stream/-/mute-stream-2.0.0.tgz#a5446fc0c512b71c83c44d908d5c7b7b4c493b2b"
integrity sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA== integrity sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==
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: napi-build-utils@^2.0.0:
version "2.0.0" version "2.0.0"
resolved "https://registry.npmmirror.com/napi-build-utils/-/napi-build-utils-2.0.0.tgz#13c22c0187fcfccce1461844136372a47ddc027e" resolved "https://registry.npmmirror.com/napi-build-utils/-/napi-build-utils-2.0.0.tgz#13c22c0187fcfccce1461844136372a47ddc027e"
@ -4887,6 +5006,14 @@ quick-lru@^5.1.1:
resolved "https://registry.npmmirror.com/quick-lru/-/quick-lru-5.1.1.tgz#366493e6b3e42a3a6885e2e99d18f80fb7a8c932" resolved "https://registry.npmmirror.com/quick-lru/-/quick-lru-5.1.1.tgz#366493e6b3e42a3a6885e2e99d18f80fb7a8c932"
integrity sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA== 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==
dependencies:
"@ai-sdk/provider" "^1.0.7"
"@ai-sdk/provider-utils" "^2.1.6"
radix3@^1.1.2: radix3@^1.1.2:
version "1.1.2" version "1.1.2"
resolved "https://registry.npmmirror.com/radix3/-/radix3-1.1.2.tgz#fd27d2af3896c6bf4bcdfab6427c69c2afc69ec0" resolved "https://registry.npmmirror.com/radix3/-/radix3-1.1.2.tgz#fd27d2af3896c6bf4bcdfab6427c69c2afc69ec0"
@ -5161,6 +5288,11 @@ sax@^1.2.4:
resolved "https://registry.npmmirror.com/sax/-/sax-1.4.4.tgz#f29c2bba80ce5b86f4343b4c2be9f2b96627cf8b" resolved "https://registry.npmmirror.com/sax/-/sax-1.4.4.tgz#f29c2bba80ce5b86f4343b4c2be9f2b96627cf8b"
integrity sha512-1n3r/tGXO6b6VXMdFT54SHzT9ytu9yr7TaELowdYpMqY/Ao7EnlQGmAQ1+RatX7Tkkdm6hONI2owqNx2aZj5Sw== 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: semver-compare@^1.0.0:
version "1.0.0" version "1.0.0"
resolved "https://registry.npmmirror.com/semver-compare/-/semver-compare-1.0.0.tgz#0dee216a1c941ab37e9efb1788f6afc5ff5537fc" resolved "https://registry.npmmirror.com/semver-compare/-/semver-compare-1.0.0.tgz#0dee216a1c941ab37e9efb1788f6afc5ff5537fc"
@ -6106,6 +6238,14 @@ yoctocolors-cjs@^2.1.3:
resolved "https://registry.npmmirror.com/yoctocolors-cjs/-/yoctocolors-cjs-2.1.3.tgz#7e4964ea8ec422b7a40ac917d3a344cfd2304baa" resolved "https://registry.npmmirror.com/yoctocolors-cjs/-/yoctocolors-cjs-2.1.3.tgz#7e4964ea8ec422b7a40ac917d3a344cfd2304baa"
integrity sha512-U/PBtDf35ff0D8X8D0jfdzHYEPFxAI7jJlxZXwCSez5M3190m+QobIfh+sWDWSHMCWWJN2AWamkegn6vr6YBTw== integrity sha512-U/PBtDf35ff0D8X8D0jfdzHYEPFxAI7jJlxZXwCSez5M3190m+QobIfh+sWDWSHMCWWJN2AWamkegn6vr6YBTw==
zhipu-ai-provider@^0.2.2:
version "0.2.2"
resolved "https://registry.npmmirror.com/zhipu-ai-provider/-/zhipu-ai-provider-0.2.2.tgz#cbee428475b1c2fca446f273ac09006ef86f6f00"
integrity sha512-UjX1ho4DI9ICUv/mrpAnzmrRe5/LXrGkS5hF6h4WDY2aup5GketWWopFzWYCqsbArXAM5wbzzdH9QzZusgGiBg==
dependencies:
"@ai-sdk/provider" "^2.0.0"
"@ai-sdk/provider-utils" "^3.0.0"
zip-stream@^6.0.1: zip-stream@^6.0.1:
version "6.0.1" version "6.0.1"
resolved "https://registry.npmmirror.com/zip-stream/-/zip-stream-6.0.1.tgz#e141b930ed60ccaf5d7fa9c8260e0d1748a2bbfb" resolved "https://registry.npmmirror.com/zip-stream/-/zip-stream-6.0.1.tgz#e141b930ed60ccaf5d7fa9c8260e0d1748a2bbfb"