feat: add grsai video provider type
Some checks failed
Lint / build (20) (push) Has been cancelled
Playwright Tests / test (push) Has been cancelled

This commit is contained in:
Your Name 2026-04-23 15:20:58 +08:00
parent e58d37015e
commit 0808d1963b
7 changed files with 23 additions and 4 deletions

View File

@ -456,6 +456,7 @@ type AiProvider = {
| "local"
| "gemini"
| "grsai-gpt-image"
| "grsai-video"
| "huanke-gemini"
| "qianwen-video"
| "doubao-video"
@ -1188,6 +1189,7 @@ const PROVIDER_TYPES = [
{ value: "fal-image", label: "FAL 生图模型" },
{ value: "openai-image", label: "OpenAI 图片兼容" },
{ value: "grsai-gpt-image", label: "Grsai GPT Image" },
{ value: "grsai-video", label: "Grsai 视频模型" },
{ value: "midjourney", label: "Midjourney" },
{ value: "tripo-3d", label: "Tripo3D 模型生成" },
{ value: "worldlabs-3d", label: "World Labs 3D 世界生成" },
@ -1218,6 +1220,7 @@ const PROVIDER_DEFAULT_BASE_URL: Record<string, string> = {
"fal-image": "https://fal.run",
"openai-image": "https://api.openai.com/v1",
"grsai-gpt-image": "https://grsai.dakka.com.cn",
"grsai-video": "https://grsai.dakka.com.cn",
midjourney: "https://your-midjourney-api.example.com",
"fal-video": "https://fal.run",
"tripo-3d": "https://api.tripo3d.ai/v2/openapi",
@ -3012,6 +3015,7 @@ export function AdminSettingsClient() {
| "local"
| "gemini"
| "grsai-gpt-image"
| "grsai-video"
| "huanke-gemini"
| "qianwen-video"
| "doubao-video"
@ -8019,6 +8023,8 @@ export function AdminSettingsClient() {
"ruxa-image": "bg-emerald-500",
"fal-image": "bg-sky-500",
"openai-image": "bg-green-600",
"grsai-gpt-image": "bg-emerald-600",
"grsai-video": "bg-orange-600",
midjourney: "bg-fuchsia-600",
"tripo-3d": "bg-teal-500",
"worldlabs-3d": "bg-sky-600",

View File

@ -16,6 +16,7 @@ const providerTypes = [
"local",
"gemini",
"grsai-gpt-image",
"grsai-video",
"huanke-gemini",
"qianwen-video",
"doubao-video",
@ -71,6 +72,7 @@ const KITTYCAD_CAD_BASE_URL = "https://api.zoo.dev";
const RUNWAY_BASE_URL = "https://api.dev.runwayml.com";
const KREA_BASE_URL = "https://api.krea.ai";
const GRSAI_GPT_IMAGE_BASE_URL = "https://grsai.dakka.com.cn";
const GRSAI_VIDEO_BASE_URL = "https://grsai.dakka.com.cn";
const RUNWAY_API_KEY_PATTERN = /^key_[0-9a-f]{128}$/;
function normalizeProviderTypeForStorage(
@ -226,6 +228,8 @@ export async function POST(request: Request) {
? data.baseUrl || KREA_BASE_URL
: data.type === "grsai-gpt-image"
? data.baseUrl || GRSAI_GPT_IMAGE_BASE_URL
: data.type === "grsai-video"
? data.baseUrl || GRSAI_VIDEO_BASE_URL
: data.baseUrl,
updatedBy: session.user.id,
});

View File

@ -137,6 +137,13 @@ function getOrCreateProvider(provider: Pick<AiProvider, "id" | "type" | "baseUrl
return grsaiGptImageProvider as any;
}
case "grsai-video": {
console.warn(
`[Provider] Grsai Video provider is configured but its runtime adapter is not connected yet: ${resolvedBaseUrl}`
);
return null;
}
case "huanke-gemini": {
// 环科 Gemini 原生格式 API
// 使用 /v1beta/models/{model}:generateContent 端点

View File

@ -4,6 +4,7 @@ const PROVIDER_DEFAULT_BASE_URL: Partial<Record<AiProvider["type"], string>> = {
alibaba: "https://dashscope.aliyuncs.com/compatible-mode/v1",
openai: "https://api.openai.com/v1",
"grsai-gpt-image": "https://grsai.dakka.com.cn",
"grsai-video": "https://grsai.dakka.com.cn",
"huanke-gemini": "https://api.huandutech.com/v1",
"qianwen-video": "https://dashscope.aliyuncs.com/api/v1/services/aigc/video-generation",
"doubao-video": "https://ark.cn-beijing.volces.com/api/v3",

View File

@ -14,6 +14,7 @@ const providerBaseUrlDefaults = [
{ type: "alibaba", baseUrl: "https://dashscope.aliyuncs.com/compatible-mode/v1" },
{ type: "openai", baseUrl: "https://api.openai.com/v1" },
{ type: "grsai-gpt-image", baseUrl: "https://grsai.dakka.com.cn" },
{ type: "grsai-video", baseUrl: "https://grsai.dakka.com.cn" },
{ type: "huanke-gemini", baseUrl: "https://api.huandutech.com/v1" },
{
type: "qianwen-video",
@ -97,7 +98,7 @@ const runMigrate = async () => {
ADD CONSTRAINT "AiProvider_type_check"
CHECK (type IN (
'alibaba', 'openai', 'custom', 'local', 'gemini',
'grsai-gpt-image', 'huanke-gemini', 'qianwen-video', 'doubao-video', 'ruxa-video', 'volcano-vision', 'volcano-video', 'alibaba-image', 'bfl-image', 'ruxa-image', 'fal-image', 'openai-image', 'midjourney', 'fal-video', 'zhipu', 'tripo-3d', 'worldlabs-3d', 'kittycad-cad', 'runway', 'krea'
'grsai-gpt-image', 'grsai-video', 'huanke-gemini', 'qianwen-video', 'doubao-video', 'ruxa-video', 'volcano-vision', 'volcano-video', 'alibaba-image', 'bfl-image', 'ruxa-image', 'fal-image', 'openai-image', 'midjourney', 'fal-video', 'zhipu', 'tripo-3d', 'worldlabs-3d', 'kittycad-cad', 'runway', 'krea'
));
`);
await db.execute(sql`

View File

@ -3750,7 +3750,7 @@ export async function createAiProvider({
updatedBy,
}: {
name: string;
type: "alibaba" | "openai" | "custom" | "local" | "gemini" | "grsai-gpt-image" | "huanke-gemini" | "qianwen-video" | "doubao-video" | "ruxa-video" | "volcano-vision" | "volcano-video" | "alibaba-image" | "bfl-image" | "ruxa-image" | "fal-image" | "openai-image" | "midjourney" | "fal-video" | "zhipu" | "tripo-3d" | "worldlabs-3d" | "kittycad-cad" | "runway" | "krea";
type: "alibaba" | "openai" | "custom" | "local" | "gemini" | "grsai-gpt-image" | "grsai-video" | "huanke-gemini" | "qianwen-video" | "doubao-video" | "ruxa-video" | "volcano-vision" | "volcano-video" | "alibaba-image" | "bfl-image" | "ruxa-image" | "fal-image" | "openai-image" | "midjourney" | "fal-video" | "zhipu" | "tripo-3d" | "worldlabs-3d" | "kittycad-cad" | "runway" | "krea";
baseUrl: string;
apiKey: string;
isEnabled?: boolean;
@ -3788,7 +3788,7 @@ export async function updateAiProvider({
}: {
id: string;
name?: string;
type?: "alibaba" | "openai" | "custom" | "local" | "gemini" | "grsai-gpt-image" | "huanke-gemini" | "qianwen-video" | "doubao-video" | "ruxa-video" | "volcano-vision" | "volcano-video" | "alibaba-image" | "bfl-image" | "ruxa-image" | "fal-image" | "openai-image" | "midjourney" | "fal-video" | "zhipu" | "tripo-3d" | "worldlabs-3d" | "kittycad-cad" | "runway" | "krea";
type?: "alibaba" | "openai" | "custom" | "local" | "gemini" | "grsai-gpt-image" | "grsai-video" | "huanke-gemini" | "qianwen-video" | "doubao-video" | "ruxa-video" | "volcano-vision" | "volcano-video" | "alibaba-image" | "bfl-image" | "ruxa-image" | "fal-image" | "openai-image" | "midjourney" | "fal-video" | "zhipu" | "tripo-3d" | "worldlabs-3d" | "kittycad-cad" | "runway" | "krea";
baseUrl?: string;
apiKey?: string;
isEnabled?: boolean;

View File

@ -276,7 +276,7 @@ export type ToolConfig = InferSelectModel<typeof toolConfig>;
export const aiProvider = pgTable("AiProvider", {
id: uuid("id").primaryKey().notNull().defaultRandom(),
name: varchar("name", { length: 128 }).notNull(), // 提供商名称,如 "阿里云通义千问"
type: varchar("type", { enum: ["alibaba", "openai", "custom", "local", "gemini", "grsai-gpt-image", "huanke-gemini", "qianwen-video", "doubao-video", "ruxa-video", "volcano-vision", "volcano-video", "alibaba-image", "ruxa-image", "fal-image", "openai-image", "midjourney", "fal-video", "zhipu", "tripo-3d", "worldlabs-3d", "kittycad-cad", "runway", "krea", "bfl-image"] })
type: varchar("type", { enum: ["alibaba", "openai", "custom", "local", "gemini", "grsai-gpt-image", "grsai-video", "huanke-gemini", "qianwen-video", "doubao-video", "ruxa-video", "volcano-vision", "volcano-video", "alibaba-image", "ruxa-image", "fal-image", "openai-image", "midjourney", "fal-video", "zhipu", "tripo-3d", "worldlabs-3d", "kittycad-cad", "runway", "krea", "bfl-image"] })
.notNull()
.default("custom"), // 提供商类型
baseUrl: text("baseUrl").notNull(), // API 基础 URL