@llumiverse/common
Version:
Public types, enums and options used by Llumiverse API.
519 lines • 22.3 kB
JavaScript
import { OptionType, SharedOptions } from "../types.js";
import { textOptionsFallback } from "./fallback.js";
import { buildClaudeCacheOptions, buildClaudeCacheTtlOptions, buildClaudeEffortOptions, buildClaudeIncludeThoughtsOption, buildClaudeThinkingBudgetOption, getClaudeMaxTokensLimit, } from "./shared-parsing.js";
import { hasSamplingParameterRestriction, isGeminiModelVersionGte, } from "./version-parsing.js";
export var ImagenTaskType;
(function (ImagenTaskType) {
ImagenTaskType["TEXT_IMAGE"] = "TEXT_IMAGE";
ImagenTaskType["EDIT_MODE_INPAINT_REMOVAL"] = "EDIT_MODE_INPAINT_REMOVAL";
ImagenTaskType["EDIT_MODE_INPAINT_INSERTION"] = "EDIT_MODE_INPAINT_INSERTION";
ImagenTaskType["EDIT_MODE_BGSWAP"] = "EDIT_MODE_BGSWAP";
ImagenTaskType["EDIT_MODE_OUTPAINT"] = "EDIT_MODE_OUTPAINT";
ImagenTaskType["CUSTOMIZATION_SUBJECT"] = "CUSTOMIZATION_SUBJECT";
ImagenTaskType["CUSTOMIZATION_STYLE"] = "CUSTOMIZATION_STYLE";
ImagenTaskType["CUSTOMIZATION_CONTROLLED"] = "CUSTOMIZATION_CONTROLLED";
ImagenTaskType["CUSTOMIZATION_INSTRUCT"] = "CUSTOMIZATION_INSTRUCT";
})(ImagenTaskType || (ImagenTaskType = {}));
export var ImagenMaskMode;
(function (ImagenMaskMode) {
ImagenMaskMode["MASK_MODE_USER_PROVIDED"] = "MASK_MODE_USER_PROVIDED";
ImagenMaskMode["MASK_MODE_BACKGROUND"] = "MASK_MODE_BACKGROUND";
ImagenMaskMode["MASK_MODE_FOREGROUND"] = "MASK_MODE_FOREGROUND";
ImagenMaskMode["MASK_MODE_SEMANTIC"] = "MASK_MODE_SEMANTIC";
})(ImagenMaskMode || (ImagenMaskMode = {}));
export var ThinkingLevel;
(function (ThinkingLevel) {
ThinkingLevel["HIGH"] = "HIGH";
ThinkingLevel["MEDIUM"] = "MEDIUM";
ThinkingLevel["LOW"] = "LOW";
ThinkingLevel["MINIMAL"] = "MINIMAL";
ThinkingLevel["THINKING_LEVEL_UNSPECIFIED"] = "THINKING_LEVEL_UNSPECIFIED";
})(ThinkingLevel || (ThinkingLevel = {}));
/** Models that support Flex processing (shared, cost-efficient tier). */
const FLEX_SUPPORTED_GEMINI_MODELS = [
"gemini-3.1-flash-lite-preview",
"gemini-3.1-flash-image-preview",
"gemini-3.1-pro-preview",
"gemini-3-flash-preview",
"gemini-3-pro-image-preview",
];
export function isFlexSupportedGeminiModel(model) {
const modelName = model.split('/').pop() ?? model;
return FLEX_SUPPORTED_GEMINI_MODELS.some(m => modelName.includes(m));
}
export function getVertexAiOptions(model, option) {
if (model.includes("imagen-")) {
return getImagenOptions(model, option);
}
else if (model.includes("gemini")) {
return getGeminiOptions(model, option);
}
else if (model.includes("claude")) {
return getClaudeOptions(model, option);
}
else if (model.includes("llama")) {
return getLlamaOptions(model);
}
return textOptionsFallback;
}
function getImagenOptions(model, option) {
const commonOptions = [
{
name: SharedOptions.number_of_images, type: OptionType.numeric, min: 1, max: 4, default: 1,
integer: true, description: "Number of Images to generate",
},
{
name: SharedOptions.seed, type: OptionType.numeric, min: 0, max: 4294967295, default: 12,
integer: true, description: "The seed of the generated image"
},
{
name: "person_generation", type: OptionType.enum, enum: { "Disallow the inclusion of people or faces in images": "dont_allow", "Allow generation of adults only": "allow_adult", "Allow generation of people of all ages": "allow_all" },
default: "allow_adult", description: "The safety setting for allowing the generation of people in the image"
},
{
name: "safety_setting", type: OptionType.enum, enum: { "Block very few problematic prompts and responses": "block_none", "Block only few problematic prompts and responses": "block_only_high", "Block some problematic prompts and responses": "block_medium_and_above", "Strictest filtering": "block_low_and_above" },
default: "block_medium_and_above", description: "The overall safety setting"
},
];
const outputOptions = [
{
name: "image_file_type", type: OptionType.enum, enum: { "JPEG": "image/jpeg", "PNG": "image/png" },
default: "image/png", description: "The file type of the generated image",
refresh: true,
},
];
const jpegQuality = {
name: "jpeg_compression_quality", type: OptionType.numeric, min: 0, max: 100, default: 75,
integer: true, description: "The compression quality of the JPEG image",
};
if (option?.image_file_type === "image/jpeg") {
outputOptions.push(jpegQuality);
}
if (model.includes("generate")) {
// Generate models
const modeOptions = [
{
name: "aspect_ratio", type: OptionType.enum, enum: { "1:1": "1:1", "4:3": "4:3", "3:4": "3:4", "16:9": "16:9", "9:16": "9:16" },
default: "1:1", description: "The aspect ratio of the generated image"
},
{
name: "add_watermark", type: OptionType.boolean, default: false, description: "Add an invisible watermark to the generated image, useful for detection of AI images"
},
];
const enhanceOptions = !model.includes("generate-001") ? [
{
name: "enhance_prompt", type: OptionType.boolean, default: true, description: "VertexAI automatically rewrites the prompt to better reflect the prompt's intent."
},
] : [];
return {
_option_id: "vertexai-imagen",
options: [
...commonOptions,
...modeOptions,
...outputOptions,
...enhanceOptions,
]
};
}
if (model.includes("capability")) {
// Edit models
let guidanceScaleDefault = 75;
if (option?.edit_mode === ImagenTaskType.EDIT_MODE_INPAINT_INSERTION) {
guidanceScaleDefault = 60;
}
const modeOptions = [
{
name: "edit_mode", type: OptionType.enum,
enum: {
"EDIT_MODE_INPAINT_REMOVAL": "EDIT_MODE_INPAINT_REMOVAL",
"EDIT_MODE_INPAINT_INSERTION": "EDIT_MODE_INPAINT_INSERTION",
"EDIT_MODE_BGSWAP": "EDIT_MODE_BGSWAP",
"EDIT_MODE_OUTPAINT": "EDIT_MODE_OUTPAINT",
"CUSTOMIZATION_SUBJECT": "CUSTOMIZATION_SUBJECT",
"CUSTOMIZATION_STYLE": "CUSTOMIZATION_STYLE",
"CUSTOMIZATION_CONTROLLED": "CUSTOMIZATION_CONTROLLED",
"CUSTOMIZATION_INSTRUCT": "CUSTOMIZATION_INSTRUCT",
},
description: "The editing mode. CUSTOMIZATION options use few-shot learning to generate images based on a few examples."
},
{
name: "guidance_scale", type: OptionType.numeric, min: 0, max: 500, default: guidanceScaleDefault,
integer: true, description: "How closely the generation follows the prompt"
}
];
const maskOptions = (option?.edit_mode?.includes("EDIT")) ? [
{
name: "mask_mode", type: OptionType.enum,
enum: {
"MASK_MODE_USER_PROVIDED": "MASK_MODE_USER_PROVIDED",
"MASK_MODE_BACKGROUND": "MASK_MODE_BACKGROUND",
"MASK_MODE_FOREGROUND": "MASK_MODE_FOREGROUND",
"MASK_MODE_SEMANTIC": "MASK_MODE_SEMANTIC",
},
default: "MASK_MODE_USER_PROVIDED",
description: "How should the mask for the generation be provided"
},
{
name: "mask_dilation", type: OptionType.numeric, min: 0, max: 1,
integer: true, description: "The mask dilation, grows the mask by a percentage of image width to compensate for imprecise masks."
},
] : [];
const maskClassOptions = (option?.mask_mode === ImagenMaskMode.MASK_MODE_SEMANTIC) ? [
{
name: "mask_class", type: OptionType.string_list, default: [],
description: "Input Class IDs. Create a mask based on image class, based on https://cloud.google.com/vertex-ai/generative-ai/docs/model-reference/imagen-api-customization#segment-ids"
}
] : [];
const editOptions = option?.edit_mode?.includes("EDIT") ? [
{
name: "edit_steps", type: OptionType.numeric, default: 75,
integer: true, description: "The number of steps for the base image generation, more steps means more time and better quality"
},
] : [];
const customizationOptions = option?.edit_mode === ImagenTaskType.CUSTOMIZATION_CONTROLLED
|| option?.edit_mode === ImagenTaskType.CUSTOMIZATION_SUBJECT ? [
{
name: "controlType", type: OptionType.enum, enum: { "Face Mesh": "CONTROL_TYPE_FACE_MESH", "Canny": "CONTROL_TYPE_CANNY", "Scribble": "CONTROL_TYPE_SCRIBBLE" },
default: "CONTROL_TYPE_CANNY", description: "Method used to generate the control image"
},
{
name: "controlImageComputation", type: OptionType.boolean, default: true, description: "Should the control image be computed from the input image, or is it provided"
}
] : [];
return {
_option_id: "vertexai-imagen",
options: [
...modeOptions,
...commonOptions,
...maskOptions,
...maskClassOptions,
...editOptions,
...customizationOptions,
...outputOptions,
]
};
}
return textOptionsFallback;
}
function getGeminiEffortOptions(model) {
if (model.includes("gemini-3-pro-image")) {
return { "High": "high" };
}
if (model.includes("gemini-3.1-flash-image")) {
return { "Low": "low", "High": "high" };
}
return { "Low": "low", "Medium": "medium", "High": "high" };
}
function getGeminiThinkingOptionItems(model) {
return [
{
name: "include_thoughts",
type: OptionType.boolean,
default: false,
description: "Include the model's reasoning process in the response"
},
{
name: SharedOptions.effort,
type: OptionType.enum,
enum: getGeminiEffortOptions(model),
description: "Higher thinking levels may improve quality, but increase response times and token costs"
}
];
}
function getGeminiOptions(model, option) {
// Special handling for gemini image / nano banana models
if (model.includes("image")) {
const isGemini25OrLater = isGeminiModelVersionGte(model, "2.5");
const isGemini3OrLater = isGeminiModelVersionGte(model, "3.0");
const max_tokens_limit = getGeminiMaxTokensLimit(model);
const excludeOptions = ["max_tokens", "presence_penalty", "frequency_penalty", "seed", "top_k"];
let commonOptions = textOptionsFallback.options.filter((option) => !excludeOptions.includes(option.name));
// Set max temperature to 2.0
commonOptions = commonOptions.map((option) => {
if (option.name === SharedOptions.temperature &&
option.type === OptionType.numeric) {
return {
...option,
max: 2.0,
};
}
return option;
});
const max_tokens = [{
name: SharedOptions.max_tokens,
type: OptionType.numeric,
min: 1,
max: max_tokens_limit,
integer: true,
step: 200,
description: "Maximum output tokens"
}];
const imageOptions = [];
// Aspect ratio, person generation, prominent people: 2.5+
if (isGemini25OrLater) {
imageOptions.push({
name: "image_aspect_ratio",
type: OptionType.enum,
enum: {
"1:1": "1:1",
"2:3": "2:3",
"3:2": "3:2",
"3:4": "3:4",
"4:3": "4:3",
"9:16": "9:16",
"16:9": "16:9",
"21:9": "21:9"
},
default: "1:1",
description: "Aspect ratio of the generated images"
}, {
name: "person_generation",
type: OptionType.enum,
enum: {
"Allow all people": "ALLOW_ALL",
"Allow adults only": "ALLOW_ADULT",
"Do not generate people": "ALLOW_NONE"
},
default: "ALLOW_ALL",
description: "Controls the generation of people in images"
}, {
name: "prominent_people",
type: OptionType.enum,
enum: {
"Allow prominent people": "ALLOW_PROMINENT_PEOPLE",
"Block prominent people": "BLOCK_PROMINENT_PEOPLE"
},
description: "Controls whether prominent people (celebrities) can be generated"
});
}
// Resolution settings: 3.0+
if (isGemini3OrLater) {
imageOptions.push({
name: "image_size",
type: OptionType.enum,
enum: {
"1K": "1K",
"2K": "2K",
"4K": "4K"
},
default: "1K",
description: "Size of generated images"
});
}
// Output format: all image models
imageOptions.push({
name: "output_mime_type",
type: OptionType.enum,
enum: {
"PNG": "image/png",
"JPEG": "image/jpeg",
},
default: "image/png",
description: "MIME type of the generated image",
refresh: true,
});
if (option?.output_mime_type === "image/jpeg") {
imageOptions.push({
name: "output_compression_quality",
type: OptionType.numeric,
min: 0,
max: 100,
default: 90,
integer: true,
description: "Compression quality for JPEG images (0-100)"
});
}
// Thinking options: 3.0+ (same as non-image counterparts)
const thinkingOptions = isGemini3OrLater ? getGeminiThinkingOptionItems(model) : [];
return {
_option_id: "vertexai-gemini",
options: [
...max_tokens,
...commonOptions,
...imageOptions,
...thinkingOptions,
]
};
}
const max_tokens_limit = getGeminiMaxTokensLimit(model);
const excludeOptions = ["max_tokens"];
const commonOptions = textOptionsFallback.options.filter((option) => !excludeOptions.includes(option.name));
const max_tokens = [{
name: SharedOptions.max_tokens, type: OptionType.numeric, min: 1, max: max_tokens_limit,
integer: true, step: 200, description: "The maximum number of tokens to generate"
}];
const seedOption = {
name: SharedOptions.seed, type: OptionType.numeric, integer: true, description: "The seed for the generation, useful for reproducibility"
};
if (isGeminiModelVersionGte(model, "3.0")) {
const flexOptions = isFlexSupportedGeminiModel(model) ? [{
name: "flex",
type: OptionType.boolean,
default: false,
description: "Use Flex processing tier for cost-efficient, batch-style execution with relaxed latency.",
}] : [];
return {
_option_id: "vertexai-gemini",
options: [
...max_tokens,
...commonOptions,
seedOption,
...getGeminiThinkingOptionItems(model),
...flexOptions,
]
};
}
if (model.includes("-2.5-")) {
// Gemini 2.5 thinking models
// Set budget token ranges based on model variant
let budgetMin = -1;
let budgetMax = 24576;
let budgetDescription = "";
if (model.includes("flash-lite")) {
budgetMin = -1;
budgetMax = 24576;
budgetDescription = "The target number of tokens to use for reasoning. " +
"Flash Lite default: Model does not think. " +
"Range: 512-24576 tokens. " +
"Set to 0 to disable thinking, -1 for dynamic thinking.";
}
else if (model.includes("flash")) {
budgetMin = -1;
budgetMax = 24576;
budgetDescription = "The target number of tokens to use for reasoning. " +
"Flash default: Dynamic thinking (model decides when and how much to think). " +
"Range: 0-24576 tokens. " +
"Set to 0 to disable thinking, -1 for dynamic thinking.";
}
else if (model.includes("pro")) {
budgetMin = -1;
budgetMax = 32768;
budgetDescription = "The target number of tokens to use for reasoning. " +
"Pro default: Dynamic thinking (model decides when and how much to think). " +
"Range: 128-32768 tokens. " +
"Cannot disable thinking - minimum 128 tokens. Set to -1 for dynamic thinking.";
}
const geminiThinkingOptions = [
{
name: "include_thoughts",
type: OptionType.boolean,
default: false,
description: "Include the model's reasoning process in the response"
},
{
name: "thinking_budget_tokens",
type: OptionType.numeric,
min: budgetMin,
max: budgetMax,
default: undefined,
integer: true,
step: 100,
description: budgetDescription,
}
];
return {
_option_id: "vertexai-gemini",
options: [
...max_tokens,
...commonOptions,
seedOption,
...geminiThinkingOptions,
]
};
}
return {
_option_id: "vertexai-gemini",
options: [
...max_tokens,
...commonOptions,
seedOption,
]
};
}
function getClaudeOptions(model, option) {
const max_tokens_limit = getClaudeMaxTokensLimit(model);
const excludeOptions = ["max_tokens", "presence_penalty", "frequency_penalty"];
let commonOptions = textOptionsFallback.options.filter((option) => !excludeOptions.includes(option.name));
// Opus 4.7+ models no longer support temperature, top_p, top_k (returns 400 error)
// Opus 4.6 and Sonnet 4.6 still support these parameters
const hasSamplingRestriction = hasSamplingParameterRestriction(model);
if (hasSamplingRestriction) {
commonOptions = commonOptions.filter((option) => option.name !== SharedOptions.temperature &&
option.name !== SharedOptions.top_p &&
option.name !== "top_k");
}
const max_tokens = [{
name: SharedOptions.max_tokens, type: OptionType.numeric, min: 1, max: max_tokens_limit,
integer: true, step: 200, description: "The maximum number of tokens to generate"
}];
return {
_option_id: "vertexai-claude",
options: [
...max_tokens,
...commonOptions,
...buildClaudeEffortOptions(model),
...buildClaudeThinkingBudgetOption(model),
...buildClaudeIncludeThoughtsOption(model),
...buildClaudeCacheOptions(),
...buildClaudeCacheTtlOptions(option?.cache_enabled),
],
};
}
function getLlamaOptions(model) {
const max_tokens_limit = getLlamaMaxTokensLimit(model);
const excludeOptions = ["max_tokens", "presence_penalty", "frequency_penalty", "stop_sequence"];
let commonOptions = textOptionsFallback.options.filter((option) => !excludeOptions.includes(option.name));
const max_tokens = [{
name: SharedOptions.max_tokens, type: OptionType.numeric, min: 1, max: max_tokens_limit,
integer: true, step: 200, description: "The maximum number of tokens to generate"
}];
// Set max temperature to 1.0 for Llama models
commonOptions = commonOptions.map((option) => {
if (option.name === SharedOptions.temperature &&
option.type === OptionType.numeric) {
return {
...option,
max: 1.0,
};
}
return option;
});
return {
_option_id: "text-fallback",
options: [
...max_tokens,
...commonOptions,
]
};
}
function getGeminiMaxTokensLimit(model) {
if (model.includes("image")) {
return isGeminiModelVersionGte(model, "2.5") ? 32768 : 8192;
}
if (model.includes("thinking") || isGeminiModelVersionGte(model, "2.5")) {
return 65535; // API upper bound is exclusive
}
if (model.includes("ultra") || model.includes("vision")) {
return 2048;
}
return 8192;
}
function getLlamaMaxTokensLimit(_model) {
return 8192;
}
export function getMaxTokensLimitVertexAi(model) {
if (model.includes("imagen-")) {
return 0; // Imagen models do not have a max tokens limit in the same way as text models
}
else if (model.includes("claude")) {
return getClaudeMaxTokensLimit(model);
}
else if (model.includes("gemini")) {
return getGeminiMaxTokensLimit(model);
}
else if (model.includes("llama")) {
return getLlamaMaxTokensLimit(model);
}
return 8192; // Default fallback limit
}
//# sourceMappingURL=vertexai.js.map