A reactive rendering engine that bridges the A2UI Protocol with the native AWS Cloudscape Design System. Feed it strict JSON event payloads — get production-grade, enterprise-quality UI components in return.
Edit A2UI JSON payloads in real time and watch them render as native Cloudscape components:
Human-in-the-loop form interactions powered by ACTION_REQUIRED events:
| Feature | Description |
|---|---|
| ProtocolBridge | Routes A2UI_RENDER, ACTION_REQUIRED, STATE_DELTA, TOOL_CALL_START, and DATA_MODEL_UPDATE events to their matching presentation layers |
| A2UIRenderer | Recursive dictionary parser targeting the A2UI v0.9 Basic Catalog — maps 15+ layout & primitive components 1:1 to Cloudscape |
| A2UITableRenderer | Auto-generates columns, paginated sorting, and converts status strings (e.g. "Success", "Failed") to native <StatusIndicator> icons |
| SurfaceRenderer | Bidirectional HITL form engine with field-level validation (regex, min/max length, required) and USER_RESPONSE event emission |
| A2UIPropertyRedact | Click-to-reveal security wrapper that protects sensitive tokens from shoulder surfing |
| Multi-Surface Routing | Events can target main, tools, or navigation surfaces via the surface property |
| Reactive Data Binding | $/path/to/value expressions in component text resolve live from DATA_MODEL_UPDATE events |
| Protocol Playground | Dual-panel dev tool at /playground — edit JSON payloads and see all 18 mapped A2UI components render instantly |
# Install dependencies
npm install
# Start the dev server
npm run devOpen your browser:
| Route | What it does |
|---|---|
http://localhost:5173/ |
Live agent demo — simulates real-time HITL interaction with temporal delays |
http://localhost:5173/playground |
Interactive JSON playground — test any A2UI payload against the renderer |
Send this JSON payload through the event stream and the renderer produces a native Cloudscape card with live-updating text:
{
"type": "A2UI_RENDER",
"payload": {
"surface": "main",
"rootId": "statusCard",
"components": {
"statusCard": { "component": "Card", "child": "col" },
"col": { "component": "Column", "children": ["heading", "status"] },
"heading": { "component": "Text", "variant": "h2", "text": "Deployment Status" },
"status": { "component": "Text", "text": "$/deployment/message" }
}
}
}The $/deployment/message expression binds reactively — when a DATA_MODEL_UPDATE event arrives with { "deployment": { "message": "Complete" } }, the text updates in place without a re-render of the tree.
Row · Column · List · Card · Tabs · Modal
Text · Image · Icon · Button · Divider
TextField · CheckBox · ChoicePicker · DateTimeInput
Table (auto-columns, status indicators) · PropertyRedact (sensitive data)
flowchart TD
A["AG-UI Event Stream\n(WebSocket / SSE / Mock)"] --> B["ProtocolBridge\nRoutes events by type"]
B --> C["A2UIRenderer\nRecursive catalog tree"]
B --> D["SurfaceRenderer\nHITL forms + validation"]
B --> E["A2UITableRenderer\nAuto-columns + status icons"]
B --> F["TraceSidebar\nTool-call trace"]
C --> G["Cloudscape Design System"]
D --> G
E --> G
style A fill:#232f3e,color:#ff9900,stroke:#ff9900
style B fill:#232f3e,color:#fff,stroke:#527fff
style G fill:#232f3e,color:#ff9900,stroke:#ff9900
Built with Vite, React 19, TypeScript 5.9, and @cloudscape-design/components.
| File | Role |
|---|---|
src/types/agui.ts |
Strictly typed AG-UI event and A2UI catalog interfaces |
src/hooks/useAgUiEvents.ts |
Mock event stream (see inline docs for real integration guide) |
src/components/ProtocolBridge.tsx |
Central event router |
src/components/A2UIRenderer.tsx |
Recursive catalog renderer |
src/pages/Playground.tsx |
Interactive dev playground |
# Lint
npm run lint
# Run tests
npx vitest run
# Run tests in watch mode
npx vitest --watch
# Type check
npx tsc --noEmit
# Production build
npm run buildThe mock hook (useAgUiEvents.ts) documents a complete SSE integration example in its JSDoc header. The ProtocolBridge component is transport-agnostic — it accepts:
interface ProtocolBridgeProps {
events: AgUiEvent[];
emitEvent: (event: OutboundClientEvent) => Promise<void>;
}Swap the event source, keep the renderer.
Contributions are welcome! See CONTRIBUTING.md for guidelines on filing issues, submitting PRs, and coding conventions.
MIT © Vishal Gole

