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 vgl
from vgl.dialects.thales import Generate

scene = 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))

Edit from images

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

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

scene = vgl.modify(EditImages(prompt="make it night", images=[room]))
scene = 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 vgl.dialects.thales import EditImageWithMask

mask = Image.open("mask.png")  # white is the area to change; same size as the image
scene = 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 = vgl.create(Generate(prompt="a cosy living room"))
image = ...  # generate the image from `scene` with FIBO
night = vgl.modify(EditImages(prompt="make it night", images=[image], input_image_vgl=scene))

Runnable versions are in examples/.

Options

vgl.create(payload, llm="vertex_ai/gemini-3.5-flash-lite", seed=7, style_preset_prompt="Muted film colours, soft grain.")
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.
  • 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 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.

vgl logs under the vgl logger hierarchy (vgl.gateway, vgl.prompting, …). Configure it the standard way — e.g. logging.getLogger("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 vgl raises inherits from vgl.exceptions.VGLError, except a bad payload, which raises pydantic.ValidationError before any LLM call. The classes below all live in 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.2.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.2.0
File Size Uploaded
bria_vgl-0.2.0.tar.gz 32.1 kB Details

Built distribution (wheel)

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

Total release size: 90.5 kB

Release files / bria_vgl-0.2.0.tar.gz

Download URL bria_vgl-0.2.0.tar.gz
Size 32.1 kB
Tags Source
SHA-256 checksum
How to use checksums
e09b5b00f7351faa569146f86a8aeb4a3c4b72e86b6d79755189d3a73c071914
BLAKE2b-256 checksum
How to use checksums
d5ddaad0b6925cb889ae3e4d6eeed64f3f9c5dd404b225df0a9b3a6a8f370e38
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.13.0 {"installer":{"name":"uv","version":"0.13.0","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.2.0-py3-none-any.whl

Download URL bria_vgl-0.2.0-py3-none-any.whl
Size 58.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
0b8f4b023348220f398212ab06dabd3ba473321029c758d552e709a544289eaf
BLAKE2b-256 checksum
How to use checksums
b684bc7af1eecac6bfec80f21e8afe7a311feb0cb8ceb528d584d77a17bf231b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.13.0 {"installer":{"name":"uv","version":"0.13.0","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 history Release notifications | RSS feed

This release

0.2.0 This release

2 release files

0.1.0

2 release files

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