fix: prioritize bfl input image editing
This commit is contained in:
parent
449dd19d5f
commit
2b6342bc7f
@ -154,6 +154,12 @@ function toImagePromptValue(imageUrl: string) {
|
|||||||
return trimmed;
|
return trimmed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getBflImageFieldCandidates() {
|
||||||
|
// BFL's current FLUX/Kontext editing APIs use `input_image` as the canonical field.
|
||||||
|
// Keep `image_prompt` only as a legacy fallback in case an older compatible endpoint is used.
|
||||||
|
return ["input_image", "image_prompt"] as const;
|
||||||
|
}
|
||||||
|
|
||||||
type SubmitTaskResult = {
|
type SubmitTaskResult = {
|
||||||
taskId: string;
|
taskId: string;
|
||||||
pollingUrl: string;
|
pollingUrl: string;
|
||||||
@ -367,13 +373,9 @@ export async function POST(request: Request) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const preferredImageField =
|
const imageFieldCandidates = getBflImageFieldCandidates();
|
||||||
model.toLowerCase().includes("kontext") || model.toLowerCase().includes("edit")
|
|
||||||
? "input_image"
|
|
||||||
: "image_prompt";
|
|
||||||
const imageFieldCandidates = [preferredImageField, preferredImageField === "input_image" ? "image_prompt" : "input_image"];
|
|
||||||
|
|
||||||
let selectedImageField = imageFieldCandidates[0];
|
let selectedImageField: "input_image" | "image_prompt" = imageFieldCandidates[0];
|
||||||
let submitResult: SubmitTaskResult | null = null;
|
let submitResult: SubmitTaskResult | null = null;
|
||||||
let fallbackWarning = "";
|
let fallbackWarning = "";
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,9 @@
|
|||||||
|
import sharp from "sharp";
|
||||||
|
|
||||||
const DEFAULT_BFL_BASE_URL = "https://api.bfl.ai";
|
const DEFAULT_BFL_BASE_URL = "https://api.bfl.ai";
|
||||||
const DEFAULT_BFL_MODEL_ID = "flux-2-klein-4b";
|
const DEFAULT_BFL_MODEL_ID = "flux-2-klein-4b";
|
||||||
const DEFAULT_TIMEOUT_MS = 15_000;
|
const DEFAULT_TIMEOUT_MS = 15_000;
|
||||||
|
const PROBE_IMAGE_SIZE = 64;
|
||||||
|
|
||||||
export type BflCapabilityCode =
|
export type BflCapabilityCode =
|
||||||
| "SUPPORTED"
|
| "SUPPORTED"
|
||||||
@ -68,6 +71,28 @@ function hasTaskIdentity(payload: any) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let cachedProbeImageBase64: string | null = null;
|
||||||
|
|
||||||
|
async function getProbeImageBase64() {
|
||||||
|
if (cachedProbeImageBase64) {
|
||||||
|
return cachedProbeImageBase64;
|
||||||
|
}
|
||||||
|
|
||||||
|
const buffer = await sharp({
|
||||||
|
create: {
|
||||||
|
width: PROBE_IMAGE_SIZE,
|
||||||
|
height: PROBE_IMAGE_SIZE,
|
||||||
|
channels: 3,
|
||||||
|
background: { r: 255, g: 255, b: 255 },
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.png()
|
||||||
|
.toBuffer();
|
||||||
|
|
||||||
|
cachedProbeImageBase64 = buffer.toString("base64");
|
||||||
|
return cachedProbeImageBase64;
|
||||||
|
}
|
||||||
|
|
||||||
export async function probeBflModelSupport(params: BflProbeParams): Promise<BflModelProbeResult> {
|
export async function probeBflModelSupport(params: BflProbeParams): Promise<BflModelProbeResult> {
|
||||||
const apiKey = String(params.apiKey || "").trim();
|
const apiKey = String(params.apiKey || "").trim();
|
||||||
const modelId = String(params.modelId || DEFAULT_BFL_MODEL_ID).trim() || DEFAULT_BFL_MODEL_ID;
|
const modelId = String(params.modelId || DEFAULT_BFL_MODEL_ID).trim() || DEFAULT_BFL_MODEL_ID;
|
||||||
@ -87,6 +112,7 @@ export async function probeBflModelSupport(params: BflProbeParams): Promise<BflM
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const endpoint = `${baseUrl}/v1/${encodeModelPath(modelId)}`;
|
const endpoint = `${baseUrl}/v1/${encodeModelPath(modelId)}`;
|
||||||
|
const inputImage = await getProbeImageBase64();
|
||||||
const response = await fetch(endpoint, {
|
const response = await fetch(endpoint, {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: {
|
headers: {
|
||||||
@ -95,9 +121,10 @@ export async function probeBflModelSupport(params: BflProbeParams): Promise<BflM
|
|||||||
Accept: "application/json",
|
Accept: "application/json",
|
||||||
},
|
},
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
prompt: "probe image generation capability",
|
prompt: "probe image editing capability; preserve the input image composition",
|
||||||
width: 512,
|
input_image: inputImage,
|
||||||
height: 512,
|
width: PROBE_IMAGE_SIZE,
|
||||||
|
height: PROBE_IMAGE_SIZE,
|
||||||
safety_tolerance: 2,
|
safety_tolerance: 2,
|
||||||
}),
|
}),
|
||||||
cache: "no-store",
|
cache: "no-store",
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user