mirror of
https://github.com/decolua/9router.git
synced 2026-05-08 12:01:28 +00:00
Add codex to image providers
This commit is contained in:
@@ -37,9 +37,9 @@ export const PROVIDER_MODELS = {
|
||||
{ id: "gpt-5-codex", name: "GPT 5 Codex" },
|
||||
{ id: "gpt-5-codex-mini", name: "GPT 5 Codex Mini" },
|
||||
// Image models (uses image_generation tool, requires Plus/Pro plan)
|
||||
{ id: "gpt-5.4-image", name: "GPT 5.4 Image", type: "image", capabilities: ["text2img", "edit"] },
|
||||
{ id: "gpt-5.3-image", name: "GPT 5.3 Image", type: "image", capabilities: ["text2img", "edit"] },
|
||||
{ id: "gpt-5.2-image", name: "GPT 5.2 Image", type: "image", capabilities: ["text2img", "edit"] },
|
||||
{ id: "gpt-5.4-image", name: "GPT 5.4 Image", type: "image", capabilities: ["text2img", "edit"], params: ["size", "quality", "background", "image_detail", "output_format"] },
|
||||
{ id: "gpt-5.3-image", name: "GPT 5.3 Image", type: "image", capabilities: ["text2img", "edit"], params: ["size", "quality", "background", "image_detail", "output_format"] },
|
||||
{ id: "gpt-5.2-image", name: "GPT 5.2 Image", type: "image", capabilities: ["text2img", "edit"], params: ["size", "quality", "background", "image_detail", "output_format"] },
|
||||
],
|
||||
gc: [ // Gemini CLI
|
||||
{ id: "gemini-3-flash-preview", name: "Gemini 3 Flash Preview" },
|
||||
@@ -345,14 +345,13 @@ export const PROVIDER_MODELS = {
|
||||
{ id: "DeepSeek-V3.2", name: "DeepSeek-V3.2" },
|
||||
],
|
||||
byteplus: [
|
||||
{ id: "doubao-seed-2.0-pro", name: "Doubao Seed 2.0 Pro" },
|
||||
{ id: "doubao-seed-2.0-code", name: "Doubao Seed 2.0 Code" },
|
||||
{ id: "doubao-seed-2.0-lite", name: "Doubao Seed 2.0 Lite" },
|
||||
{ id: "doubao-seed-code", name: "Doubao Seed Code" },
|
||||
{ id: "glm-5.1", name: "GLM-5.1" },
|
||||
{ id: "glm-4.7", name: "GLM-4.7" },
|
||||
{ id: "kimi-k2.5", name: "Kimi-K2.5" },
|
||||
{ id: "gpt-oss-120b", name: "GPT-OSS-120B" },
|
||||
{ id: "seed-2-0-pro-260328", name: "Seed 2.0 Pro" },
|
||||
{ id: "seed-2-0-code-preview-260328", name: "Seed 2.0 Code Preview" },
|
||||
{ id: "seed-2-0-mini-260215", name: "Seed 2.0 Mini" },
|
||||
{ id: "seed-2-0-lite-260228", name: "Seed 2.0 Lite" },
|
||||
{ id: "kimi-k2-thinking-251104", name: "Kimi K2 Thinking" },
|
||||
{ id: "glm-4-7-251222", name: "GLM 4.7" },
|
||||
{ id: "gpt-oss-120b-250805", name: "GPT-OSS-120B" },
|
||||
],
|
||||
deepseek: [
|
||||
{ id: "deepseek-v4-flash", name: "DeepSeek V4 Flash" },
|
||||
|
||||
@@ -83,11 +83,11 @@ function toCodexDataUrl(input) {
|
||||
}
|
||||
|
||||
// Build content array with optional reference images, mirroring codex-imagen tagging
|
||||
function buildCodexContent(prompt, refs) {
|
||||
function buildCodexContent(prompt, refs, detail = CODEX_REF_DETAIL) {
|
||||
const content = [];
|
||||
refs.forEach((url, index) => {
|
||||
content.push({ type: "input_text", text: `<image name=image${index + 1}>` });
|
||||
content.push({ type: "input_image", image_url: url, detail: CODEX_REF_DETAIL });
|
||||
content.push({ type: "input_image", image_url: url, detail });
|
||||
content.push({ type: "input_text", text: "</image>" });
|
||||
});
|
||||
content.push({ type: "input_text", text: prompt });
|
||||
@@ -280,11 +280,16 @@ function buildImageBody(provider, model, body) {
|
||||
if (Array.isArray(images)) images.forEach((i) => { const u = toCodexDataUrl(i); if (u) refs.push(u); });
|
||||
const single = toCodexDataUrl(image);
|
||||
if (single) refs.push(single);
|
||||
const detail = body.image_detail || CODEX_REF_DETAIL;
|
||||
const imgTool = { type: "image_generation", output_format: (body.output_format || "png").toLowerCase() };
|
||||
if (body.size && body.size !== "") imgTool.size = body.size;
|
||||
if (body.quality && body.quality !== "") imgTool.quality = body.quality;
|
||||
if (body.background && body.background !== "") imgTool.background = body.background;
|
||||
return {
|
||||
model: stripCodexImageModel(model),
|
||||
instructions: "",
|
||||
input: [{ type: "message", role: "user", content: buildCodexContent(prompt, refs) }],
|
||||
tools: [{ type: "image_generation", output_format: "png" }],
|
||||
input: [{ type: "message", role: "user", content: buildCodexContent(prompt, refs, detail) }],
|
||||
tools: [imgTool],
|
||||
tool_choice: "auto",
|
||||
parallel_tool_calls: false,
|
||||
prompt_cache_key: randomUUID(),
|
||||
@@ -404,6 +409,7 @@ export async function handleImageGenerationCore({
|
||||
credentials,
|
||||
log,
|
||||
streamToClient = false,
|
||||
binaryOutput = false,
|
||||
onCredentialsRefreshed,
|
||||
onRequestSuccess,
|
||||
}) {
|
||||
@@ -524,7 +530,26 @@ export async function handleImageGenerationCore({
|
||||
|
||||
const normalized = normalizeImageResponse(responseBody, provider, body.prompt);
|
||||
|
||||
log?.debug?.("IMAGE", `Success | images=${normalized.data?.length || 0}`);
|
||||
// Binary output: decode first b64_json into raw bytes
|
||||
if (binaryOutput) {
|
||||
const first = normalized.data?.[0];
|
||||
const b64 = first?.b64_json;
|
||||
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,
|
||||
|
||||
Reference in New Issue
Block a user