mirror of
https://github.com/Nezumi-2711/9router.git
synced 2026-09-22 13:38:31 +00:00
feat(antigravity): native image generation support
Add image generation for Antigravity provider via gemini-3.1-flash-image and gemini-3-pro-image, exposed through Text to Image UI and /v1/images/generations. - registry: serviceKinds ['llm','image'] + image model entries - executor: image model detection + image_gen request envelope - chatCore: force stream=false for image models (generateContent) - nonStreamingHandler: parse inlineData -> markdown image - imageGenerationCore: useExecutor fast-path for executor delegation - imageProviders/antigravity: image adapter with image input support - usage/google: image models in quota whitelist Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
committed by
decolua
co-authored by
Cursor
parent
b4d2754d32
commit
5306bd904e
@@ -50,6 +50,47 @@ export async function handleImageGenerationCore({
|
||||
);
|
||||
}
|
||||
|
||||
// Executor-delegating adapters: skip manual URL/headers/body, use the proven executor flow
|
||||
if (adapter.useExecutor && adapter.executeViaExecutor) {
|
||||
try {
|
||||
log?.debug?.("IMAGE", `${provider.toUpperCase()} | ${model} | prompt="${body.prompt.slice(0, 50)}..." (executor)`);
|
||||
const responseBody = await adapter.executeViaExecutor(model, body, credentials, log);
|
||||
if (onRequestSuccess) await onRequestSuccess();
|
||||
const normalized = adapter.normalize(responseBody, body.prompt);
|
||||
const finalBody = (normalized.created && Array.isArray(normalized.data)) ? normalized : responseBody;
|
||||
|
||||
if (binaryOutput) {
|
||||
const first = finalBody.data?.[0];
|
||||
let b64 = first?.b64_json;
|
||||
if (!b64 && first?.url) {
|
||||
try { b64 = await urlToBase64(first.url); } catch {}
|
||||
}
|
||||
if (b64) {
|
||||
const buf = Buffer.from(b64, "base64");
|
||||
const fmt = (body.output_format || "png").toLowerCase();
|
||||
const mime = fmt === "jpeg" || fmt === "jpg" ? "image/jpeg" : fmt === "webp" ? "image/webp" : "image/png";
|
||||
return {
|
||||
success: true,
|
||||
response: new Response(buf, {
|
||||
headers: { "Content-Type": mime, "Content-Disposition": `inline; filename="image.${fmt === "jpeg" ? "jpg" : fmt}"`, "Access-Control-Allow-Origin": "*" },
|
||||
}),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
response: new Response(JSON.stringify(finalBody), {
|
||||
headers: { "Content-Type": "application/json", "Access-Control-Allow-Origin": "*" },
|
||||
}),
|
||||
};
|
||||
} catch (error) {
|
||||
const errMsg = formatProviderError(error, provider, model, HTTP_STATUS.BAD_GATEWAY);
|
||||
log?.debug?.("IMAGE", `Executor error: ${errMsg}`);
|
||||
return createErrorResult(HTTP_STATUS.BAD_GATEWAY, errMsg);
|
||||
}
|
||||
}
|
||||
|
||||
let url;
|
||||
let headers;
|
||||
let requestBody;
|
||||
|
||||
Reference in New Issue
Block a user