@nano-ui-kit/a2ui-validator
v0.0.1
Published
A2UI validation — structural schema validation, catalog-aware validation (component props, slots, enums), and optional semantic LLM-judge scoring. Framework-agnostic; pairs with @nano-ui-kit/a2ui-utils.
Maintainers
Readme
@nano-ui-kit/a2ui-validator
A2UI validation — three orthogonal layers that you compose based on how much assurance you want.
| Layer | What it checks | Cost | Determinism |
|---|---|---|---|
| Structural (./structural) | Shape, tag registration, required fields per NanoUI A2UI schema | µs | ✅ fully deterministic |
| Catalog (./catalog) | Full prop types, enum values, slot names, validation rules from per-component a2ui.json schemas | ms | ✅ fully deterministic |
| Semantic (./semantic) | Intent alignment via LLM judge (dominant pattern, required capabilities, forbidden noise) | seconds, API cost | ✱ cached per rubric+input |
Install
npm install @nano-ui-kit/a2ui-validator @nano-ui-kit/a2ui-utilsStructural validation
import { validateSchema } from '@nano-ui-kit/a2ui-validator';
const messages = [
{ type: 'updateComponents', surfaceId: 'default', components: [
{ id: 'root', component: 'Card', children: ['sec'] },
{ id: 'sec', component: 'Section', children: ['btn'] },
{ id: 'btn', component: 'Button', text: 'Hello' },
]},
];
const { valid, errors } = validateSchema(messages);Catalog-aware validation
Needs the catalog shipped in @nano-ui-kit/a2ui-corpus:
import { validateMessages } from '@nano-ui-kit/a2ui-validator/catalog';
import catalog from '@nano-ui-kit/a2ui-corpus/catalog';
const { valid, errors } = validateMessages(messages, catalog);Catches variant="fictional" on a component whose yaml only declares
[default, info, success, warning, danger], wrong slot names, missing
required props — the things structural validation is too coarse to see.
Semantic validation (optional)
import { validateSemantics } from '@nano-ui-kit/a2ui-validator/semantic';
const result = await validateSemantics({
intent: 'password reset form',
messages,
rubric: {
dominantPattern: 'forms/password-reset',
requiredCapabilities: ['email input', 'submit button'],
forbiddenNoise: ['login flow', 'signup'],
},
});
// → { verdict: 'aligned' | 'partial' | 'misaligned' | 'off-topic', score, rationale }Needs ANTHROPIC_API_KEY in the environment. Judgments are cached at
<cwd>/.a2ui-semantic-cache/ keyed by sha256(rubricVersion + intent +
messages) — the default Haiku-4.5 rubric is ~108k tokens per 100-intent
run.
Development / design notes
- Layer 1 and 2 are framework-agnostic — they validate any A2UI message set against any component registry.
- Layer 3 is opinionated: specific rubric, specific model. If you want
a different model, provide a custom
judgefunction tovalidateSemantics. - This package is Node-only today (fs-backed semantic cache). Browser builds of the structural/catalog layers work via standard ESM import.
License
MIT © Kim Granlund
