fix(providers): extract minimax image-gen helpers to fix complexity ratchet

check:complexity-ratchets regressed 2056 -> 2058 (handleMinimaxImageGeneration:
complexity 25, max-lines-per-function 97). Split logging, upstream-error,
no-images, success and fetch-error branches into small named helpers so the
handler stays within the cyclomatic-complexity (15) and max-lines-per-function
(80) ratchets. No behavior change; existing minimax-image-provider-2482 and
minimax-media-servicekinds unit tests still pass.
This commit is contained in:
Diego Rodrigues de Sa e Souza
2026-07-15 09:48:52 -03:00
parent 33d4e057ef
commit 483080bfc8

View File

@@ -19,6 +19,16 @@ interface MinimaxImageGenArgs {
} | null;
}
interface MinimaxCallLogParams {
status: number;
model: string;
provider: string;
duration: number;
error?: string;
requestBody?: unknown;
responseBody?: unknown;
}
const MINIMAX_ASPECT_RATIOS = new Set(["1:1", "16:9", "9:16", "4:3", "3:4", "3:2", "2:3"]);
function mapMinimaxAspectRatio(size?: string): string {
@@ -26,6 +36,113 @@ function mapMinimaxAspectRatio(size?: string): string {
return "1:1";
}
/** Fire-and-forget usage log for a MiniMax image-generation call. */
function logMinimaxCall(params: MinimaxCallLogParams): void {
saveCallLog({
method: "POST",
path: "/v1/images/generations",
...params,
}).catch(() => {});
}
/** Builds the upstream MiniMax request body from the OpenAI-shaped input body. */
function buildMinimaxUpstreamBody(model: string, prompt: string, body: MinimaxImageGenArgs["body"]) {
return {
model: model || "image-01",
prompt,
aspect_ratio: mapMinimaxAspectRatio(body.size),
n: body.n ?? 1,
response_format: "url",
};
}
/** Handles a non-2xx MiniMax response: logs, records the call, and shapes the error result. */
async function handleMinimaxUpstreamError(
response: Response,
ctx: { provider: string; model: string; startTime: number; upstreamBody: unknown; log?: MinimaxImageGenArgs["log"] }
) {
const errorText = await response.text();
ctx.log?.error?.("IMAGE", `${ctx.provider} error ${response.status}: ${errorText.slice(0, 200)}`);
logMinimaxCall({
status: response.status,
model: `${ctx.provider}/${ctx.model}`,
provider: ctx.provider,
duration: Date.now() - ctx.startTime,
error: errorText.slice(0, 500),
requestBody: ctx.upstreamBody,
});
return { success: false as const, status: response.status, error: errorText };
}
/** Extracts and validates the `image_urls` array from a MiniMax response payload. */
function extractMinimaxImageUrls(data: unknown): unknown[] {
const record = data as { data?: { image_urls?: unknown } } | undefined;
return Array.isArray(record?.data?.image_urls) ? (record?.data?.image_urls as unknown[]) : [];
}
interface MinimaxResultCtx {
provider: string;
model: string;
startTime: number;
}
/** MiniMax returned 2xx but no images — logs and shapes the empty-result error. */
function buildMinimaxNoImagesResult(data: unknown, ctx: MinimaxResultCtx) {
const record = data as { base_resp?: { status_msg?: string } } | undefined;
const errorMsg = record?.base_resp?.status_msg || "No images returned from MiniMax";
logMinimaxCall({
status: 502,
model: `${ctx.provider}/${ctx.model}`,
provider: ctx.provider,
duration: Date.now() - ctx.startTime,
error: errorMsg,
});
return { success: false as const, status: 502, error: errorMsg };
}
/** MiniMax returned images — logs and shapes the OpenAI-compatible success result. */
function buildMinimaxSuccessResult(imageUrls: unknown[], prompt: string, ctx: MinimaxResultCtx) {
const images = imageUrls.map((url) => ({ url, revised_prompt: prompt }));
logMinimaxCall({
status: 200,
model: `${ctx.provider}/${ctx.model}`,
provider: ctx.provider,
duration: Date.now() - ctx.startTime,
responseBody: { images_count: images.length },
});
return {
success: true as const,
data: { created: Math.floor(Date.now() / 1000), data: images },
};
}
/** Network/parse failure reaching MiniMax — logs and shapes the sanitized error result. */
function buildMinimaxFetchErrorResult(
err: unknown,
ctx: MinimaxResultCtx & { log?: MinimaxImageGenArgs["log"] }
) {
const errMsg = err instanceof Error ? err.message : String(err);
ctx.log?.error?.("IMAGE", `${ctx.provider} fetch error: ${errMsg}`);
logMinimaxCall({
status: 502,
model: `${ctx.provider}/${ctx.model}`,
provider: ctx.provider,
duration: Date.now() - ctx.startTime,
error: errMsg,
});
return {
success: false as const,
status: 502,
error: `Image provider error: ${sanitizeErrorMessage(errMsg)}`,
};
}
export async function handleMinimaxImageGeneration({
model,
provider,
@@ -37,22 +154,12 @@ export async function handleMinimaxImageGeneration({
const startTime = Date.now();
const token = credentials?.apiKey || credentials?.accessToken || "";
const prompt = typeof body.prompt === "string" ? body.prompt : String(body.prompt ?? "");
const aspectRatio = mapMinimaxAspectRatio(body.size);
const upstreamBody = buildMinimaxUpstreamBody(model, prompt, body);
const upstreamBody = {
model: model || "image-01",
prompt,
aspect_ratio: aspectRatio,
n: body.n ?? 1,
response_format: "url",
};
if (log) {
log.info?.(
"IMAGE",
`${provider}/${model} (minimax-image) | prompt: "${prompt.slice(0, 60)}..." | aspect_ratio: ${aspectRatio}`
);
}
log?.info?.(
"IMAGE",
`${provider}/${model} (minimax-image) | prompt: "${prompt.slice(0, 60)}..." | aspect_ratio: ${upstreamBody.aspect_ratio}`
);
try {
const response = await fetch(providerConfig.baseUrl, {
@@ -65,74 +172,19 @@ export async function handleMinimaxImageGeneration({
});
if (!response.ok) {
const errorText = await response.text();
if (log) log.error?.("IMAGE", `${provider} error ${response.status}: ${errorText.slice(0, 200)}`);
saveCallLog({
method: "POST",
path: "/v1/images/generations",
status: response.status,
model: `${provider}/${model}`,
provider,
duration: Date.now() - startTime,
error: errorText.slice(0, 500),
requestBody: upstreamBody,
}).catch(() => {});
return { success: false, status: response.status, error: errorText };
return handleMinimaxUpstreamError(response, { provider, model, startTime, upstreamBody, log });
}
const data = await response.json();
const imageUrls: unknown[] = Array.isArray(data?.data?.image_urls) ? data.data.image_urls : [];
const imageUrls = extractMinimaxImageUrls(data);
const ctx: MinimaxResultCtx = { provider, model, startTime };
if (imageUrls.length === 0) {
const errorMsg = data?.base_resp?.status_msg || "No images returned from MiniMax";
saveCallLog({
method: "POST",
path: "/v1/images/generations",
status: 502,
model: `${provider}/${model}`,
provider,
duration: Date.now() - startTime,
error: errorMsg,
}).catch(() => {});
return { success: false, status: 502, error: errorMsg };
return buildMinimaxNoImagesResult(data, ctx);
}
const images = imageUrls.map((url) => ({ url, revised_prompt: prompt }));
saveCallLog({
method: "POST",
path: "/v1/images/generations",
status: 200,
model: `${provider}/${model}`,
provider,
duration: Date.now() - startTime,
responseBody: { images_count: images.length },
}).catch(() => {});
return {
success: true,
data: { created: Math.floor(Date.now() / 1000), data: images },
};
return buildMinimaxSuccessResult(imageUrls, prompt, ctx);
} catch (err: unknown) {
const errMsg = err instanceof Error ? err.message : String(err);
if (log) log.error?.("IMAGE", `${provider} fetch error: ${errMsg}`);
saveCallLog({
method: "POST",
path: "/v1/images/generations",
status: 502,
model: `${provider}/${model}`,
provider,
duration: Date.now() - startTime,
error: errMsg,
}).catch(() => {});
return {
success: false,
status: 502,
error: `Image provider error: ${sanitizeErrorMessage(errMsg)}`,
};
return buildMinimaxFetchErrorResult(err, { provider, model, startTime, log });
}
}