ai-chatbot/lib/ai/reference-image-capability.ts

73 lines
2.1 KiB
TypeScript

type ModelDescriptor = {
modelId?: unknown;
supportsVision?: boolean | null;
capabilities?: unknown;
defaultParams?: unknown;
};
type ProviderDescriptor = {
type?: unknown;
};
const BFL_REFERENCE_IMAGE_MODEL_REGEX =
/^(?:bfl\/)?(?:flux-2-(?:max|flex|pro(?:-preview)?|klein-(?:4b|9b)(?:-preview)?)|flux-kontext-(?:pro|max))$/i;
function readStringField(source: unknown, key: string) {
if (!source || typeof source !== "object" || !(key in source)) return "";
return String((source as Record<string, unknown>)[key] || "").trim();
}
function normalizeBflModelId(value: unknown) {
const trimmed = String(value || "").trim();
if (!trimmed) return "";
return trimmed
.replace(/^https?:\/\/[^/]+/i, "")
.replace(/^\/?(?:bfl\/)?v1\//i, "")
.replace(/^\/+/, "")
.replace(/[?#].*$/, "");
}
export function isKnownReferenceImageModel(
model: ModelDescriptor | null | undefined,
provider?: ProviderDescriptor | null
) {
const providerType = String(provider?.type || "").trim();
if (providerType !== "bfl-image") return false;
const candidates = [
model?.modelId,
readStringField(model?.defaultParams, "endpoint"),
readStringField(model?.defaultParams, "submitEndpoint"),
readStringField(model?.capabilities, "endpoint"),
];
const capabilitiesEndpoints =
model?.capabilities &&
typeof model.capabilities === "object" &&
"endpoints" in model.capabilities
? (model.capabilities as { endpoints?: unknown }).endpoints
: undefined;
candidates.push(readStringField(capabilitiesEndpoints, "submit"));
return candidates
.map(normalizeBflModelId)
.some((modelId) => BFL_REFERENCE_IMAGE_MODEL_REGEX.test(modelId));
}
export function modelLacksReferenceImageInputSupport(
model: ModelDescriptor | null | undefined,
provider?: ProviderDescriptor | null
) {
if (isKnownReferenceImageModel(model, provider)) return false;
return model?.supportsVision === false;
}
export function modelSupportsReferenceImageInput(
model: ModelDescriptor | null | undefined,
provider?: ProviderDescriptor | null
) {
return !modelLacksReferenceImageInputSupport(model, provider);
}