Skip to main content

VGL — Visual Generation Language

VGL turns a text prompt, or images plus a prompt, into a structured JSON description of a scene: objects, background, lighting, aesthetics, camera, and text. The result is a typed Pydantic model that an image model like FIBO takes as its prompt.

Install

pip install bria-vgl

The default LLM is Gemini through Google AI Studio. For other providers, install the extra:

pip install 'bria-vgl[vertex]'     # Gemini on Vertex AI
pip install 'bria-vgl[bedrock]'    # Claude on AWS Bedrock

Authenticate

Provider llm= Set
Google AI Studio (default) gemini/gemini-3.5-flash-lite GEMINI_API_KEY (get one)
Vertex AI vertex_ai/gemini-3.5-flash-lite VERTEXAI_PROJECT, VERTEXAI_LOCATION, GOOGLE_APPLICATION_CREDENTIALS (a service account JSON)
AWS Bedrock e.g. bedrock/us.anthropic.claude-sonnet-4-5-20250929-v1:0 the usual AWS credentials and AWS_REGION_NAME

llm takes any litellm model id, but the prompts are tuned for Gemini.

Quickstart

Create a scene from a prompt

import bria_vgl
from bria_vgl.dialects.thales import Generate

scene = bria_vgl.create(Generate(prompt="a red fox in snow at dusk"))
print(scene.short_description)
print(scene.model_dump_json(indent=2, exclude_none=True))

Create a scene inspired by an image

The image is a visual reference only. The VGL describes the scene the prompt asks for, not the image.

import bria_vgl
from bria_vgl.dialects.thales import Inspire

scene = bria_vgl.create(Inspire(prompt="the same fox, at the beach", image=fox))

Describe an image

No prompt: the VGL describes the image itself.

from bria_vgl.dialects.thales import Caption

scene = bria_vgl.create(Caption(image=fox))

Refine a VGL

No image: the prompt changes an existing VGL, and the fields it doesn't affect are kept.

from bria_vgl.dialects.thales import Generate, Refine

scene = bria_vgl.create(Generate(prompt="a cosy living room"))
night = bria_vgl.modify(Refine(prompt="make it night", input_vgl=scene))

Edit from images

from PIL import Image
from bria_vgl.dialects.thales import EditImages

room = Image.open("room.jpg")
lamp = Image.open("lamp.jpg")

scene = bria_vgl.modify(EditImages(prompt="make it night", images=[room]))
scene = bria_vgl.modify(EditImages(prompt="put the lamp from <image_2> in <image_1>", images=[room, lamp]))
print(scene.edit_instruction)

Up to 4 images. The prompt refers to them as <image_1> to <image_4>, in list order.

Edit a masked area

from bria_vgl.dialects.thales import EditImageWithMask

mask = Image.open("mask.png")  # white is the area to change; same size as the image
scene = bria_vgl.modify(EditImageWithMask(prompt="replace it with a cat", image=room, mask=mask))

Edit with the image's VGL

If you have the VGL that an image was generated from, pass it as input_image_vgl. The edit then keeps everything the prompt doesn't change, rather than re-describing the image from scratch. vgl doesn't check that it matches the image.

scene = bria_vgl.create(Generate(prompt="a cosy living room"))
image = ...  # generate the image from `scene` with FIBO
night = bria_vgl.modify(EditImages(prompt="make it night", images=[image], input_image_vgl=scene))

Runnable versions are in examples/.

Options

bria_vgl.create(payload, llm="vertex_ai/gemini-3.5-flash-lite", seed=7, style_preset_prompt="Muted film colours, soft grain.")
bria_vgl.modify(payload, llm=..., seed=...)
  • llm: the litellm model id; see Authenticate.
  • seed: makes a call repeatable, on models that accept one.
  • style_preset_prompt: style guidelines added to the system prompt. Applies to create only; modify ignores it.

create also takes overrides for the payload's defaults. Each is optional, and leaving it out keeps the default:

  • system_prompt: replaces the system prompt. {llm_input_schema} and {style_preset_block} in it are still filled.
  • final_prompt: replaces the final (user) prompt. Its placeholders, such as {user_prompt}, are still filled.
  • input_schema: the field guide filled into {llm_input_schema}.
  • response_schema: the JSON schema the model must follow, in Gemini's format. Extra keys in the reply are dropped from the VGL.
  • thinking_level: a bria_vgl.ThinkingLevel or its string, "minimal", "low", "medium" or "high", on Gemini 3+. Anything else, or a level on an older Gemini, raises ValueError before the call. By default thinking is as low as the model allows.
  • temperature and max_output_tokens: thinking tokens count against max_output_tokens, so raise it with a high thinking level.

bria-vgl logs under the bria_vgl logger hierarchy (bria_vgl.gateway, bria_vgl.prompting, …). Configure it the standard way — e.g. logging.getLogger("bria_vgl").setLevel(logging.INFO) and attach your own handler; add a logging.Filter if you need to inject contextual fields.

A Gemini call that keeps failing (3 attempts) or hits a rate limit (429, not retried) moves to gemini-3.1-flash-lite on the same provider.

Errors

Everything bria-vgl raises inherits from bria_vgl.exceptions.VGLError, except a bad payload, which raises pydantic.ValidationError before any LLM call. The classes below all live in bria_vgl.exceptions.

Error Means
AuthenticationError the provider rejected your credentials, e.g. a missing or wrong API key
RateLimitError the provider returned 429 (quota exhausted), on the Gemini fallback too
LLMError any other provider failure, after retries and the fallback
InvalidResponseError the model's reply isn't a valid VGL
MaxTokensError the model ran out of output tokens mid-reply
PromptNotFoundError a bundled prompt is missing; a packaging fault, please report it

Dialects

A dialect is a small variant of VGL, with its own model, payloads, and prompts. The payload you import decides the dialect. vgl ships the Thales dialect: no aesthetic scores, and every edit states its change in edit_instruction.

More

Metadata

Release files for bria-vgl 0.7.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for bria-vgl 0.7.0
File Size Uploaded Provenance
bria_vgl-0.7.0.tar.gz 34.4 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for bria-vgl 0.7.0
File Interpreter ABI Platform
bria_vgl-0.7.0-py3-none-any.whl Python 3 none any Details

Total release size: 100.9 kB

Release files / bria_vgl-0.7.0.tar.gz

Download URL bria_vgl-0.7.0.tar.gz
Size 34.4 kB
Tags Source
SHA-256 checksum
How to use checksums
71c00ff0c9a63d14ed1d18c92db4eb03f43c988e3a80f264646b696a31f2f983
BLAKE2b-256 checksum
How to use checksums
3822f999ea2b1d48d839347208762ff3ed92eb79bc7eeacc65b46fd0ac49ae81
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.13.3 {"installer":{"name":"uv","version":"0.13.3","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / bria_vgl-0.7.0-py3-none-any.whl

Download URL bria_vgl-0.7.0-py3-none-any.whl
Size 66.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
f89e0fe35ed1d8733ea84b0fa80c6d6d7138d48cf278af617b4afc0daf713d7c
BLAKE2b-256 checksum
How to use checksums
e80a5e3e0982bfb8f2700153db162a6dec889e9313e350e004473c5105e7e795
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.13.3 {"installer":{"name":"uv","version":"0.13.3","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Security for bria-vgl 0.7.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page