Skip to content
Kimenpre-v1
Color scheme

Guide

A2UI adapter

@kimen/adapter-a2ui is Kimen’s first protocol adapter. It translates declarative A2UI messages into the neutral UI spec and renders every surface through the guarded renderer alone. The catalog and the ki-* elements are the durable assets; the adapter is disposable by design — the exact supported A2UI version(s) live in the package’s COMPAT.md, protocol churn is absorbed there, and an unabsorbable break retires the package without touching core.

The adapter owns no rendering path of its own. It builds a neutral UiSpec and hands it to renderUiSpec from @kimen/catalog; the guardrail’s four invariants (only catalog components render, only declared actions dispatch, unknown props are rejected, no code path executes from message data) are enforced there, once. Two complementary checks prove the adapter never opens a side channel: a static module boundary (no other rendering library is importable) and a runtime guarantee that every render call arrives at the guarded renderer.

import { createA2uiAdapter } from '@kimen/adapter-a2ui';
const adapter = createA2uiAdapter({
surface: document.querySelector('#genui'),
protocolVersion: '0.9.1',
onUserAction: (event) => channelToAgent.send(event), // A2UI userAction round-trip
onDegradation: (report) => log(report), // unmapped-type gaps, as data
});
// A supported A2UI surface update renders as catalog components:
const result = adapter.apply({
surfaceUpdate: {
surfaceId: 'checkout',
root: 'card',
components: [
{ id: 'card', component: { Card: { children: { explicitList: ['confirm'] } } } },
{
id: 'confirm',
component: {
Button: { label: { literalString: 'Confirm order' }, action: { name: 'confirm-order' } },
},
},
],
},
});
result.ok; // true — or false with inert diagnostics naming each offender

An A2UI message is data, never code:

  • Unmapped component types degrade per node to a fixed fallback that never carries agent content.
  • Forbidden types reject the whole message — a type the compatibility matrix declares forbidden (e.g. raw html) is never partially rendered.
  • Unsupported protocol versions are rejected naming the supported set.
  • The action set is frozen at first render: incremental surfaceUpdate / dataModelUpdate messages revise the surface without discarding it, but no later update can bind an undeclared action.

Transport is caller-owned: the adapter consumes already-delivered A2UI messages and emits userAction events to the supplied channel. deleteSurface drops adapter state; the host owns teardown of its surface element.

The canonical package documentation, including the compatibility policy, lives in the repository: packages/adapter-a2ui.