Specification
contract rules · generated prompts
EBNF grammar, 15 stable error codes and an extension protocol. The specification comes before the code and resolves differences between implementations.
1.1 Your JSON. Your contract. Your .mini. →
Provide JSON samples from your domain. mini-format builds your contract, prompt and tools to recover validated JSON from compact AI responses. Detect errors and apply safe repairs with a verifiable report.
Install mini-format 1.1.0
pip install https://mini-format.pmoluna.com/downloads/mini_format-1.1.0-py3-none-any.whl
npm install ./mini-format-core-1.1.0.tgz
Python 3.9+ · dependency-free core · MIT open source. The ZIP includes the Python package, TypeScript, examples and documentation.
Build my first .mini →194 records · Public test data
Output tokens relative to .mini · lower is better. o200k_base
208 records · Public test data
Output tokens relative to .mini · lower is better. o200k_base
500 records · Public test data
Output tokens relative to .mini · lower is better. o200k_base
1,000 records · Real observations
Output tokens relative to .mini · lower is better. o200k_base
For your application
mini validate and parse() fit into an existing Python or Node project. Keep your model provider and your framework.
contract rules · generated prompts
EBNF grammar, 15 stable error codes and an extension protocol. The specification comes before the code and resolves differences between implementations.
parsing · validation · diagnostics
Python and TypeScript, written independently from the same specification. Parser, serializer, lenient mode, prompt block and streaming reader.
build · convert · validate
Build your toolkit, validate, diagnose, convert both ways, generate prompts, count tokens and check families.
shared expectations across implementations
303 language-independent cases, with expectations derived from the specification rather than calculated by the code. Python and TypeScript pass 303/303.
One minute with mini-format
Define, instruct, call, validate, repair and use with the same toolkit. Each step is a real command; output is abbreviated. Pick a step or watch.
One build per domain
Gather the JSON your application needs. One command creates a .mini directory to reuse in your workflow.
mini build phones.json more.json --prefix phone --out .miniRecording of this demonstration. Real commands; abbreviated output.
Integration
Load the family registry, request the prompt block with spec_block(), call your provider as usual and pass the response to parse().
from minifmt import Registry, parse, spec_block
reg = Registry.load() # descubre forks/*/contract.json
c = reg.get("a")
def generar_items(tema):
respuesta = cliente.completar(sistema=spec_block(c, lang="es"), usuario=tema)
doc = parse(respuesta, c, strict=False) # tolerante: acumula errores
return doc.records, doc.errors # válidos tipados, rechazados con códigoJSON repeats every field name in every object. mini-format declares it once in the contract. Field-name cost grows as O(W·N) in JSON and O(W) here.
narrow record
typical business record
wide record
Savings versus compact JSON · linear scale from 0%, maximum 50% · 1,000 records · o200k_base · median of 5 documents per cell · deterministic synthetic data (seed 20260915). The curve levels off near 32 fields. reproduce →
1,902 records from four public datasets. 35.64% fewer tokens than compact JSON and 9.65% fewer than flat TOON across the measured total.
| Dataset | N | .mini | TOON flat | Saved vs TOON | Saved vs CSV | .mini prompt |
|---|---|---|---|---|---|---|
| DummyJSON products | 194 | 64,090 | 68,260 | 6.11 % | 4.42 % | 1,206 |
| DummyJSON users | 208 | 43,268 | 60,926 | 28.98 % | 27.92 % | 1,796 |
| JSONPlaceholder comments | 500 | 30,268 | 31,022 | 2.43 % | -1.35 % | 477 |
| USGS earthquake observations | 1,000 | 164,137 | 173,803 | 5.56 % | 4.11 % | 1,336 |
USGS: 1,000 real observations. DummyJSON and JSONPlaceholder: 902 synthetic test records, never duplicated to inflate the batch. Exact JSON round-trips for all eight formats. Official TOON 4.1.1; the smaller of two reversible flattening variants is selected. Savings describe output tokens; the .mini prompt is shown separately. CSV remains smaller for comments. This measures serialization, not LLM generation accuracy. Method and reproduction → · JSON
Separators tokenize differently across vocabularies. Same 14 domains, batches of 10, versus compact JSON.
50k vocabulary
95% CI [26.8 % · 31.5 %] · k=14
100k vocabulary
95% CI [29.1 % · 33.5 %] · k=14
200k vocabulary
95% CI [31.5 % · 35.5 %] · k=14
Linear scale from 0%, maximum 36%: a 3.9-point difference between the oldest and newest vocabulary. All three are tiktoken vocabularies. reproduce →
Interface
from minifmt import Registry, parse, dumps, spec_block, roundtrip_ok
reg = Registry.load() # descubre forks/*/contract.json
c = reg.get("log")
instruccion = spec_block(c, lang="es") # bloque para el prompt de sistema
doc = parse(respuesta, c, strict=False) # tolerante: no lanza, acumula
doc.records # registros válidos, ya tipados
for e in doc.errors: # MiniError: code, line, field, message
print(e)
texto = dumps(doc.to_canonical(), c) # canónico -> .mini
assert roundtrip_ok(doc.to_canonical(), c)import { Registry, parse, dumps, specBlock } from '@mini-format/core';
const reg = Registry.load(); // descubre ../forks/*/contract.json
const c = reg.get('log');
const lenient = parse(texto, c, { strict: false });
lenient.records; // registros válidos
lenient.errors; // MiniError[] con code, line, field, message
lenient.invalidLines(); // líneas rechazadas: las que hay que regenerar
lenient.missingRecords; // n − líneas recibidas
lenient.diagnostics(); // mismas claves que la referencia Pythonimport { createReader } from '@mini-format/core';
const reader = createReader(c, { // strict: false por defecto
onRecord: ({ record, line, index }) => mostrar(record),
onError: (e) => console.warn(String(e)),
});
for await (const token of respuestaDelModelo) reader.push(token);
const res = reader.end();
res.missing; // registros que faltan respecto de n
res.truncated; // se cortó: incompleto o menos líneas que n
res.terminated; // el flujo terminó en salto de líneamini forks # lista las familias
mini validate respuesta.mini # estricto: sale con 1 si hay errores
mini diagnose respuesta.mini # tolerante: informe JSON con líneas a regenerar
mini to-json respuesta.mini | jq . # .mini -> JSON canónico
mini from-json datos.json -p log # JSON canónico -> .mini
mini prompt log --lang es # bloque de especificación para el modelo
mini tokens respuesta.mini --enc o200k_base # tokens y bytes, con el tokenizador declarado
mini check-forks # invariantes + fixtures de ida y vuelta
mini new-fork quiz2 --from a --add "nivel:enum{facil|dificil}"$ python conformance/run_python.py
303 casos · 303 pasan · 0 fallan
$ cd ts && npm test
conformance.test.ts · 303/303
# las expectativas salen de la norma y de los fixtures publicados,
# nunca se calculan ejecutando la implementación$ mini new-fork quiz2 --from a --add "feedback:str" "level:enum{easy|hard}"
$ mini check-forks
# cinco invariantes mantienen toda familia analizable por construcción:
# I1 una línea = un registro I4 campos nuevos solo al final
# I2 prefijo y n obligatorios I5 los fixtures hacen ida y vuelta
# I3 el núcleo heredado no cambia (cambio incompatible => prefijo nuevo)Each family preserves its core, appends fields at the end and follows five verifiable invariants. A family is a data file, not code.
aassessment items: multiple choice, Bloom, IRT 3PL, CAT
qformative quizzes: extends a with feedback, hints and objectives
cardspaced-repetition flashcards
summicro-lesson summary segments
mapconcept-map edges
ranalytic rubric criteria
sLikert survey items
codeprogramming exercises with tests
tcsoftware test cases
ususer stories with acceptance criteria
logservice events and incidents
nernamed-entity annotations
catproduct catalog records
clsmulti-label text classification
Playground
Runs entirely in your browser with the reference JavaScript port. No server or account required.
Open the playgroundComparison
| Capability | mini-format | JSON | CSV | TOON |
|---|---|---|---|---|
| Fewer tokens than compact JSON | ✓ | — | ✓ | ✓ |
| Contract-declared types | ✓ | partial | ✗ | partial |
| Errors with code, line and field | ✓ | partial | ✗ | ✗ |
| Stable specification error codes | 15 | ✗ | ✗ | ✗ |
| Truncation recovery | ✓ | ✗ | ✓ | partial |
| Selective per-line repair | ✓ | ✗ | ✗ | ✗ |
| Record-by-record streaming | ✓ | partial | ✓ | ✗ |
| Published conformance suite | 303 | ✓ | ✗ | ✗ |
| Two independent implementations | ✓ | ✓ | ✓ | partial |
| Lists with a selected item | ✓ | ✗ | ✗ | ✗ |
| Declared forward compatibility | ✓ | ✗ | ✗ | ✗ |
| Arbitrary nesting | ✗ | ✓ | ✗ | ✓ |
| Reading without a contract | partial | ✓ | ✓ | ✓ |
| Native provider API support | ✗ | ✓ | ✗ | ✗ |
Forward compatibility preserves known fields when the same prefix declares a higher version. The base profile uses flat records; the generated toolkit reconstructs your domain's JSON structure. The model needs the prompt; the reader needs the contract.
Download the toolkit, gather JSON samples and build your application's contract.
mini build phones.json --prefix phone --out .miniDocumentation · Specification 1.0 · Error index · Playground