feat(ruxa-image): add provider defaults and request compatibility
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-03-06 01:26:37 +08:00
parent 610317f824
commit ddefba63b6
3 changed files with 26 additions and 19 deletions

View File

@ -435,7 +435,7 @@ const AVAILABLE_TOOLS = [
const PROVIDER_TYPES = [
{ value: "alibaba", label: "阿里云通义千问" },
{ value: "alibaba-image", label: "阿里生图模型" }, // 🆕 千问图片生成/编辑
{ value: "ruxa-image", label: "RUXA 生图模型" },
{ value: "ruxa-image", label: "RUXA生图" },
{ value: "fal-image", label: "FAL 生图模型" },
{ value: "tripo-3d", label: "Tripo3D 模型生成" },
{ value: "zhipu", label: "智普官方 4.7" },

View File

@ -53,6 +53,7 @@ const ZHIPU_BASE_URL = "https://open.bigmodel.cn/api/paas/v4";
const VOLCANO_MULTIMODAL_BASE_URL = "https://ark.cn-beijing.volces.com/api/v3";
const DOUBAO_VIDEO_BASE_URL = "https://ark.cn-beijing.volces.com/api/v3";
const RUXA_VIDEO_BASE_URL = "https://api.ruxa.ai";
const RUXA_IMAGE_BASE_URL = "https://api.ruxa.ai";
const TRIPO_3D_BASE_URL = "https://api.tripo3d.ai/v2/openapi";
function normalizeProviderTypeForStorage(
@ -162,6 +163,8 @@ export async function POST(request: Request) {
? data.baseUrl || DOUBAO_VIDEO_BASE_URL
: data.type === "ruxa-video"
? data.baseUrl || RUXA_VIDEO_BASE_URL
: data.type === "ruxa-image"
? data.baseUrl || RUXA_IMAGE_BASE_URL
: data.type === "tripo-3d"
? data.baseUrl || TRIPO_3D_BASE_URL
: data.baseUrl,

View File

@ -20,7 +20,7 @@ interface UploadedImage {
original: string;
}
const DEFAULT_ASPECT_RATIO = "auto";
const DEFAULT_SIZE = "1:1";
const DEFAULT_RESOLUTION = "1k";
const DEFAULT_OUTPUT_FORMAT = "png";
const POLL_INTERVAL_MS = 2000;
@ -50,14 +50,14 @@ function joinApiPath(baseURL: string, path: string) {
}
function normalizeAspectRatio(aspectRatio?: string) {
if (!aspectRatio) return DEFAULT_ASPECT_RATIO;
if (!aspectRatio) return DEFAULT_SIZE;
const normalized = aspectRatio.trim().toLowerCase();
if (normalized === "auto") return "auto";
if (normalized === "auto") return DEFAULT_SIZE;
const ratio = aspectRatio.trim();
if (["1:1", "2:3", "3:2", "3:4", "4:3", "4:5", "5:4", "9:16", "16:9", "21:9"].includes(ratio)) {
if (["1:1", "16:9", "9:16", "4:3", "3:4", "2:3", "3:2"].includes(ratio)) {
return ratio;
}
return DEFAULT_ASPECT_RATIO;
return DEFAULT_SIZE;
}
function normalizeResolution(imageSize?: string) {
@ -67,10 +67,11 @@ function normalizeResolution(imageSize?: string) {
return DEFAULT_RESOLUTION;
}
function normalizeOutputFormat(outputFormat?: string): "png" | "jpg" {
function normalizeOutputFormat(outputFormat?: string): "png" | "jpg" | "webp" {
if (!outputFormat) return DEFAULT_OUTPUT_FORMAT;
const normalized = outputFormat.trim().toLowerCase();
if (normalized === "jpg" || normalized === "jpeg") return "jpg";
if (normalized === "webp") return "webp";
return "png";
}
@ -168,10 +169,6 @@ function extractPromptAndImages(messages: Array<{ role: string; content: any }>)
throw new Error("No prompt found in user message");
}
if (imageUrls.length === 0) {
throw new Error("RUXA 图片编辑模型需要至少 1 张输入图片");
}
return { prompt, imageUrls };
}
@ -361,18 +358,25 @@ export function createRuxaImage({ apiKey, baseURL }: RuxaImageConfig) {
const aspectRatio = normalizeAspectRatio(options.imageParams?.aspectRatio);
const resolution = normalizeResolution(options.imageParams?.imageSize);
const outputFormat = normalizeOutputFormat(options.imageParams?.outputFormat);
const activeModelId = options.overrideModelId || modelId;
const activeModelId = options.overrideModelId || modelId || "gpt-image-1.5";
const createEndpoint = joinApiPath(baseURL, "/api/v1/tasks/create");
const callbackUrl = process.env.RUXA_CALLBACK_URL?.trim();
const input: Record<string, unknown> = {
prompt,
size: aspectRatio,
aspect_ratio: aspectRatio,
resolution,
output_format: outputFormat,
};
if (imageUrls[0]) {
input.image = imageUrls[0];
}
if (imageUrls.length > 1) {
input.image_input = imageUrls;
}
const requestBody = {
input: {
prompt,
image_input: imageUrls,
aspect_ratio: aspectRatio,
resolution,
output_format: outputFormat,
},
input,
model: activeModelId,
...(callbackUrl ? { callBackUrl: callbackUrl } : {}),
};