Skip to main content
How Mavri keeps generated content on-brand and on-budget — versioning kits immutably, compositing real assets over generated imagery, auto-repairing weak output, and grounding generations in retrieved exemplars.

1. Immutable & versioned Brand Kit lifecycle

Mavri ingests brand materials, runs structured extraction via forced LLM tool calls, and version-controls the resulting Brand Kit.
1

Normalize inputs

Multi-source inputs (files and URLs) are normalized into a single ingestion stream.
2

Structured extraction

Extraction runs via Anthropic Claude or OpenAI models; the result is stored as a draft version.
3

Human activation

On activation, a partial database index (uq_brandkit_one_active where status = 'active') guarantees any existing active kit is archived first.
Reference: src/mavri/domain/versioning.py defines the kit lifecycle and the single-active guard.

2. Deterministic image compositing (Pillow)

Diffusion models render exact text and logos poorly. Mavri sidesteps this by splitting image generation into two stages:

Generate clean backgrounds

The generation prompt requests clean compositions with defined negative space in the lower-left and bottom — no model-rendered text or logos.

Composite real assets

Pillow overlays a translucent, brand-tinted plate, scales the brand’s real logo, wraps text, and renders the headline and CTA.
The uncomposited base image is stored separately, so the image-to-image exemplar flywheel can reuse it without feedback loops.
Reference: src/mavri/services/generation/compositor.py handles coordinates, text wrapping, dynamic scaling, and color contrast.

3. Closed-loop critique & repair

Low-quality or non-compliant generations are auto-revised before they’re ever returned.
Output is checked against the brand’s banned_words using word-boundary regexes. On a violation, a correction instruction is appended and the copy is regenerated, up to a set limit.
Reference: src/mavri/services/generation/copy_generator.py (regex checks and repair loop); src/mavri/services/generation/critic.py (vision scoring).

4. Local vector indexing without pgvector

Mavri embeds and retrieves segments of the active brand kit and approved prior exemplars for context grounding — without a database extension. Chunks are extracted from the active kit and their embeddings inserted as raw JSON float lists. Retrieval loads those rows for the active brand and computes cosine similarity in Python with basic math operations — efficient for the small document count and free of a pgvector install.
Reference: src/mavri/services/ingestion/indexer.py handles chunking, dedup via SHA-256 content hashes, and cosine similarity.

The hardest problem

Preventing logo and text collisions in AI-generated imagery. The two-part rendering pipeline solves it: the diffusion model is prompted to reserve negative space in specific zones (lower-left and bottom), then a deterministic, code-driven Pillow compositor overlays the real assets in non-overlapping layout grids. A zero-temperature vision critic verifies the composition constraints were met.

Performance & DX

AST-enforced decoupling

AST-parsing test guards (test_architecture.py) verify that no core service file imports a vendor SDK directly, preserving clean architectural separation.

Transaction-safe budget caps

Adapter spend is calculated and logged on every API call; a budget-breach exception is thrown before invoking downstream generation if caps are exceeded.

Primary entry points

Last modified on June 22, 2026