For agents
A building language a model can write, drawings it can look at, and a judgement loop it cannot flatter — the three moves that make an agent produce buildings instead of pictures of buildings.
An agent that draws buildings fails in one of three places: it does arithmetic it should not be trusted with, it never looks at what it made, or it grades its own work. bimtex is designed against all three, and the design is three moves.
Move one — declare, never draft
The model's job is to declare intent. The compiler's job is arithmetic. The validator's job is to return repairable contradictions.
NDJSON entities → compile → solids → derive plans · elevations · sections · 3D
└──────→ validate → diagnostics, addressed to the writerA wall is a side of a footprint, not four coordinates; a roof is a form
and a pitch, not a mesh. Every drawing is derived from one model, so the
drawings cannot disagree with each other — and coordinates, ridge heights,
areas and travel distances leave the model's working memory entirely. Bind
the wire format as a tool schema (bimtex/ai exports the definitions) rather
than describing it in prose: in the benchmark, one response spelled t as
type on every line, and that single spelling produced 96 findings.
One consequence agents get wrong constantly: diagnostics come in two
populations, and only one is work. blocking means the drawings contradict
each other — geometry that cannot be built — and fails ok. Everything else
(advisory, numeric thresholds, presentation lint) is an indicator: the
model is unusual, not impossible, and an agent that spends repair turns on
indicators loops forever on a model that was already releasable.
Move two — look at the drawing
Text diagnostics cannot say "the roof reads as a lid" or "half the frame is
tarmac". The second half of the design is that the same inspect() that
compiles and validates will also print the drawings:
import { inspect } from 'bimtex/ai';
const report = inspect(source, { review: true, split: true });
// report.diagnostics — the checker's findings, as text
// report.review.sheets — labelled SVGs, one per view, ready to rasterisebimtex supplies the compiler, the diagnostics and the labelled sheet; the agent harness supplies the eyes — rasterise the SVG, hand the pixels to a vision model, and treat what it sees as findings the same way checker output is findings. A model that writes without looking ships buildings that pass every rule and read as nothing.
Move three — judge with different eyes than drew
The most expensive failure mode is self-assessment: measured on this repository's own artifacts, nineteen consecutive self-scores came back as compliments, and the same rubric given to a judge that had not drawn the model came back honest. So judgement is structurally separated from authorship:
- the drafter must state a scheme before writing — what the building is, its organising idea, what each view must show — and is later held to it;
evaluaterefuses a verdict on a drawing the drafter has not looked at since its last change, and cannot overrule the checker;- an independent crit — a second model call with no drafting history — reviews a fixed sheet set the drafter does not get to curate, and grades likeness against the scheme's own rubric;
- the pass bar is never told to the model. A model that knows the bar clears it by writing a bigger number.
Two ways in
bimtex/ai — the primitives. getSyntax(), getVocabulary(),
validateNdjson(), inspect(), the tool schemas. Build your own loop; this
is the layer everything else stands on.
bimtex/drafter — the shipped loop. The full harness the studio runs:
session, seven tools with their refusal gates, drawing rounds, the
independent crit and the likeness score. It is host-agnostic — a browser tab
and a server run the same code and differ only in the services they inject.
Requires the optional peer dependencies ai, zod and
@openrouter/ai-sdk-provider.
The drafter loop
The shipped harness: sessions, hosts, rounds, the crit, and what each gate exists to prevent.
Prompting a model
What the checker structurally cannot see, and the practices that cover it.
Tool schemas
The model and edit contracts, and when to declare less schema on purpose.
Editing
Four atomic operations and the semantic diff that checks them.
Benchmark
Where the current system actually succeeds and fails.