ai-chatbot/lib/ai/vip98k-runtime.ts

166 lines
4.9 KiB
TypeScript

import "server-only";
import { and, eq } from "drizzle-orm";
import {
executeVip98kExternalTask,
getVip98kExternalTaskStatus,
submitVip98kExternalTask,
} from "@/lib/ai/providers/vip98k";
import { db } from "@/lib/db";
import { getAiProvidersByType } from "@/lib/db/queries";
import { aiModel } from "@/lib/db/schema";
export type Vip98kRuntimeProvider = {
id: string;
name: string;
apiKey: string;
baseUrl: string;
};
let providerCursor = 0;
export async function getVip98kRuntimeProviders(): Promise<Vip98kRuntimeProvider[]> {
const providers = await getAiProvidersByType({
type: "vip98k",
enabledOnly: true,
});
return providers
.map((provider) => ({
id: provider.id,
name: provider.name,
apiKey: String(provider.apiKey || "").trim(),
baseUrl: String(provider.baseUrl || "").trim(),
}))
.filter((provider) => Boolean(provider.apiKey && provider.baseUrl));
}
export async function getVip98kRuntimeProvider(
preferredProviderId?: string | null,
): Promise<Vip98kRuntimeProvider> {
const providers = await getVip98kRuntimeProviders();
const preferredId = String(preferredProviderId || "").trim();
if (preferredId) {
const matched = providers.find((provider) => provider.id === preferredId);
if (matched) return matched;
}
if (providers.length === 0) {
throw new Error("VIP98K 服务商未配置或未启用");
}
const selected = providers[providerCursor % providers.length]!;
providerCursor = (providerCursor + 1) % providers.length;
return selected;
}
export async function executeConfiguredVip98kTask(params: {
modelId: string;
kind: string;
prompt?: string;
imageUrls?: string[];
videoUrls?: string[];
imageParams?: Record<string, unknown>;
videoParams?: Record<string, unknown>;
preferredProviderId?: string | null;
}) {
const provider = await getVip98kRuntimeProvider(params.preferredProviderId);
const model = await db.query.aiModel.findFirst({
where: and(
eq(aiModel.providerId, provider.id),
eq(aiModel.modelId, params.modelId),
eq(aiModel.isEnabled, true),
),
});
if (!model) {
throw new Error(`VIP98K 模型未同步或未启用:${params.modelId}`);
}
const result = await executeVip98kExternalTask({
apiKey: provider.apiKey,
baseURL: provider.baseUrl,
modelId: params.modelId,
kind: params.kind,
prompt: params.prompt,
imageUrls: params.imageUrls,
videoUrls: params.videoUrls,
imageParams: params.imageParams,
videoParams: params.videoParams,
modelConfig: {
capabilities:
model.capabilities && typeof model.capabilities === "object"
? (model.capabilities as Record<string, unknown>)
: null,
imageGenConfig:
model.imageGenConfig && typeof model.imageGenConfig === "object"
? (model.imageGenConfig as Record<string, unknown>)
: null,
},
});
return {
...result,
providerId: provider.id,
providerName: provider.name,
};
}
export async function submitConfiguredVip98kTask(params: {
modelId: string;
kind: string;
prompt?: string;
imageUrls?: string[];
videoUrls?: string[];
imageParams?: Record<string, unknown>;
videoParams?: Record<string, unknown>;
preferredProviderId?: string | null;
}) {
const provider = await getVip98kRuntimeProvider(params.preferredProviderId);
const model = await db.query.aiModel.findFirst({
where: and(
eq(aiModel.providerId, provider.id),
eq(aiModel.modelId, params.modelId),
eq(aiModel.isEnabled, true),
),
});
if (!model) {
throw new Error(`VIP98K 模型未同步或未启用:${params.modelId}`);
}
const result = await submitVip98kExternalTask({
apiKey: provider.apiKey,
baseURL: provider.baseUrl,
modelId: params.modelId,
kind: params.kind,
prompt: params.prompt,
imageUrls: params.imageUrls,
videoUrls: params.videoUrls,
imageParams: params.imageParams,
videoParams: params.videoParams,
modelConfig: {
capabilities:
model.capabilities && typeof model.capabilities === "object"
? (model.capabilities as Record<string, unknown>)
: null,
imageGenConfig:
model.imageGenConfig && typeof model.imageGenConfig === "object"
? (model.imageGenConfig as Record<string, unknown>)
: null,
},
});
return { ...result, providerId: provider.id, providerName: provider.name };
}
export async function getConfiguredVip98kTaskStatus(params: {
taskId: string;
preferredProviderId?: string | null;
resultPath?: string | null;
}) {
const provider = await getVip98kRuntimeProvider(params.preferredProviderId);
const result = await getVip98kExternalTaskStatus({
apiKey: provider.apiKey,
baseURL: provider.baseUrl,
taskId: params.taskId,
resultPath: params.resultPath,
});
return { ...result, providerId: provider.id, providerName: provider.name };
}