import type { Model } from "./models.js"; /** Wire-format options shape returned by /v1/models. */ export interface Schema { /** * Per-field constraints, keyed by canonical request field name * (matching the JSON keys on Image/Video/Speech/Embed/Transcribe * params). A field absent from this map is NOT accepted by the * model. */ inputs?: Record; /** Cross-field rules. */ constraints?: Constraint[]; /** Rich content (TTS voices, emotions). */ catalog?: Catalog; } export interface FieldSchema { type: "string" | "int" | "float" | "bool" | "url" | "url[]" | "string[]" | "file"; /** Default when omitted is "optional". */ presence?: "required" | "optional" | "forbidden"; min?: number; max?: number; default?: unknown; enum?: unknown[]; max_items?: number; /** Lower-bound counterpart of max_items. Applies to array types * AND `repeatable` object groups. Nil = no minimum. */ min_items?: number; /** Semantic hint for media-input fields. */ role?: "source" | "reference" | "motion"; /** When present, this field is a structured sub-object. The wire * value is `{: , ...}` matching this inner * schema; renderers recurse into it. With `repeatable: true` the * wire value becomes an array of such objects (e.g. multi-utterance * TTS "+ add another group"). */ fields?: Record; /** Pairs with `fields`: array-of-objects rather than a single * nested object. Ignored when `fields` is absent. */ repeatable?: boolean; /** Human-readable display label. Falls back to the field name. */ label?: string; /** One-sentence tooltip / sub-text explainer. */ help?: string; /** * Widget override hint: * "textarea" — large multi-line string * "slider" — numeric with min/max * "radio" — small enum * "voice_picker" — string with values from catalog.voices * "code" — long string with syntax highlighting * "segmented" — pill-shaped row of enum values (compact, * horizontal). Best for short ordered enums * like the resolution tier (512P / 1K / 2K / * 4K) in image generation. Renders as a single * line; selected option has solid background. * "tile" — grid of square cards, each carrying a small * visual proxy for the value (aspect-ratio * shape icon, or fit-brackets for the * "adaptive" sentinel). Used for aspect_ratio * in image generation. When the enum includes * "adaptive" or "auto", that entry is * promoted to a row-spanning anchor block. * "tabs" — horizontal tab strip. Same data contract as * "radio" but a different visual. Drives * `ui.show_when` on sibling fields. * "card_group" — bordered card containing the field's nested * `fields`. With `repeatable: true` the card * becomes a "+ add another"-able stack. * Unknown values fall back to the type default (forward-compat). */ widget?: string; /** * Nested presentational hints: * "group" (string) — sectional grouping ("main"/"advanced"/"output"). * "order" (int) — display order within the group; lower first. * "card_label" (string) — title above a card_group; "{{i}}" is * substituted with the card index for * repeatable groups. * "show_when" ({field, equals}) * — purely-visual conditional: hide this * field unless a sibling's value matches. * Validator ignores it; server still * accepts conditionally-hidden fields. */ ui?: { group?: string; order?: number; card_label?: string; show_when?: { field: string; equals: unknown; }; [k: string]: unknown; }; } export type ConstraintKind = "any_of_required" | "mutually_exclusive" | "group_mutex" | "requires_all" | "pixel_bounds"; export interface Group { /** Stable id; also the value the discriminator field * (`Constraint.name`) takes when this group is active. */ name?: string; /** Tab strip display label. Falls back to `name`. */ label?: string; fields: string[]; } export interface Constraint { kind: ConstraintKind; fields?: string[]; /** * On a `group_mutex` constraint, names the discriminator field * selecting which group is active. The renderer auto-injects a * `tabs` input with this name (enum = group names) and gives * every group member an implicit `show_when` pointing at it. * When omitted, the constraint behaves as legacy anonymous-group * mutex — all members render flat, mutex enforced at submit. */ name?: string; /** * Human-readable title for the synthesized tab widget (e.g. * "Animation mode"). Falls back to `name` when omitted. */ label?: string; /** * Used by `group_mutex`. Wire shape is either the legacy * `string[][]` (each `[a,b,...]` reads as an anonymous * `{fields:[a,b,...]}` Group) or the new `Group[]`. Consumers * should normalize via `normalizeGroups()` before reading. */ groups?: Group[] | string[][]; when?: string; then?: string[]; min?: number; max?: number; } /** * Normalize either legacy `string[][]` or new `Group[]` into a * uniform `Group[]`. Mirror of sdk-go's `Group.UnmarshalJSON`. */ export declare function normalizeGroups(g: Constraint["groups"]): Group[]; export interface Catalog { voices?: Array>; emotions?: string[]; } /** * Parse the model's wire-format `options` blob into the typed Schema. * Returns null when the model has no options or the blob can't be * structurally decoded — callers fall back to whatever default * behaviour they had pre-schema. */ export declare function getOptionsSchema(model: Model): Schema | null; /** * True iff the model declares an Inputs entry for `name` with * presence != "forbidden". Use for "should I show this UI chip" * decisions. */ export declare function acceptsField(model: Model, name: string): boolean; /** * True iff the schema marks `name` as presence: "required". Use for * red-star UI marks and submit-button gating. */ export declare function requiresField(model: Model, name: string): boolean; /** * Discrete enum for the named field, or null if no enum constraint. * Use to populate dropdown options on the client. */ export declare function allowedValuesFor(model: Model, name: string): unknown[] | null; //# sourceMappingURL=model_options.d.ts.map