Skip to content
Draft
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
8dc92bf
Add resources discussion
jacobsimionato Mar 5, 2026
c5a8eb3
Improve functions design
jacobsimionato Mar 5, 2026
5df86c2
Add comments about unsubscribing
jacobsimionato Mar 5, 2026
07077b2
Add catalog API proposal doc v1
jacobsimionato Mar 5, 2026
6ae4b24
Update catalog proposal
jacobsimionato Mar 6, 2026
0e75794
Improve catalog API proposal
jacobsimionato Mar 6, 2026
2f52cad
Update renderer guide
jacobsimionato Mar 6, 2026
d9f328f
Add improvements to the renderer guide
jacobsimionato Mar 6, 2026
a4b2b61
Delete catalog proposal
jacobsimionato Mar 6, 2026
f8c147c
remove dumb
jacobsimionato Mar 10, 2026
2a74434
Address feedback
jacobsimionato Mar 10, 2026
46a1504
Improve explanation of scope
jacobsimionato Mar 10, 2026
a17edea
Respond to a few more commments
jacobsimionato Mar 10, 2026
7d73d59
Add initial react renderer
jacobsimionato Mar 10, 2026
1daad96
Update react renderer to fix reactivity
jacobsimionato Mar 11, 2026
a1fa3ec
improve react renderer
jacobsimionato Mar 11, 2026
dc958a6
Improvemeents to react renderer
jacobsimionato Mar 11, 2026
1ceb3f1
More react improvements
jacobsimionato Mar 11, 2026
e773e0f
Add deep generic binder etc
jacobsimionato Mar 12, 2026
f07b00d
MOve react to react_prototype
jacobsimionato Mar 12, 2026
1eebf0d
clean up react renderer
jacobsimionato Mar 12, 2026
b95ab1d
Merge branch 'main' into react-1
jacobsimionato Mar 12, 2026
4168208
Add more samples
jacobsimionato Mar 12, 2026
110f87e
refactor(react): automatically infer component props from Zod schema
jacobsimionato Mar 12, 2026
11399ee
feat(react): implement basic catalog and integrate with gallery app
jacobsimionato Mar 12, 2026
6c113ff
fix(react): robust zod schema matching for generic binder
jacobsimionato Mar 12, 2026
88378d9
refactor(core): move generic binder from react prototype to web core
jacobsimionato Mar 12, 2026
587cdd6
set function invoker properly
jacobsimionato Mar 12, 2026
7a4b788
feat(react): improve generic binder ergonomics for two-way binding
jacobsimionato Mar 13, 2026
99e7095
feat(react): strictly typed setter generation in generic binder
jacobsimionato Mar 13, 2026
502520d
fix(react): remove optional chaining from strictly typed generated se…
jacobsimionato Mar 13, 2026
d2d6069
Improements to binder and add copyright headers
jacobsimionato Mar 13, 2026
64ff985
Improve return type of FunctionInvoker
jacobsimionato Mar 13, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions renderers/react/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*

node_modules
dist
dist-ssr
*.local

# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
34 changes: 34 additions & 0 deletions renderers/react/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# @a2ui/react

A2UI Renderer for React. This library provides components and adapters for rendering A2UI (Agent to User Interface) surfaces in React applications.

## Installation

```bash
npm install @a2ui/react @a2ui/web_core react react-dom zod rxjs
```

## Key Components

- `A2uiSurface`: The main component for rendering an A2UI surface.
- `createReactComponent`: An adapter for creating React-specific A2UI components.
- `minimalCatalog`: A pre-configured catalog for the minimal set of A2UI components.

## Development

To build the library:

```bash
npm run build
```

To run tests:

```bash
npm test
```

## Related Projects

- `@a2ui/web_core`: The core agnostic logic for A2UI.
- `samples/client/react`: A gallery application for testing and debugging this renderer.
72 changes: 72 additions & 0 deletions renderers/react/design.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# A2UI React Renderer Design Document

## 1. Overview
This document outlines the architecture and implementation plan for the React renderer of the A2UI (Agent to UI) protocol v0.9. The implementation follows the guidelines specified in the `renderer_guide.md`.

## 2. Key Dependency Decisions
* **Schema Library**: `zod` (provided by `@a2ui/web_core`). We will use TypeScript for defining schemas and intersection types to enforce component API compliance.
* **Observable/Reactive Library**: `rxjs` (provided by `@a2ui/web_core`). React 18+ provides `useSyncExternalStore`, which is the ideal hook for subscribing to external state (like RxJS Observables or our internal `EventEmitter` implementations in the Data Layer).
* **Native UI Framework**: React (v18+).

## 3. Core Model Layer
We will strictly leverage `@a2ui/web_core` for the framework-agnostic Data Layer. This includes:
* `MessageProcessor`
* `SurfaceGroupModel`, `SurfaceModel`, `SurfaceComponentsModel`, `ComponentModel`
* `DataModel`, `DataContext`, `ComponentContext`
* `Catalog`, `ComponentApi`, `FunctionImplementation`

Our React renderer will act as the "View" layer that consumes these models.

## 4. Framework-Specific Layer (The React Bridge)

We will build an adapter layer that bridges the `web_core` data layer to React components.

### 4.1. Generic Binder Factory (`GenericBinder`)
Since TypeScript/JavaScript are dynamic, we will implement a generic binder that inspects the component's Zod schema. It will automatically traverse the component properties, resolving `DynamicValue` fields (like `DynamicString`, `DynamicBoolean`) into reactive streams using `context.dataContext.subscribeDynamicValue()`.

The `GenericBinder` will produce a single stateful stream of `ResolvedProps` which can be consumed by React. Structural properties (like `child` or `children`) will be passed through as metadata objects (e.g., `{ id, basePath }` or `Array<{id, basePath}>`) so the React adapter can recursively build children.

### 4.2. React Component Adapter (`createReactComponent`)
We will provide a Higher-Order Component (HOC) or factory function, `createReactComponent(binder, RenderComponent)`.
* It takes a `ComponentContext`.
* It utilizes the `GenericBinder` to subscribe to the data model.
* It uses `useSyncExternalStore` to connect the `GenericBinder`'s reactive stream to React's rendering cycle.
* It manages the cleanup (`dispose()`) of the binding when the React component unmounts.
* It passes the fully resolved props (data props as native JS types, structural props as IDs) and a `buildChild(id, basePath)` helper to the stateless `RenderComponent`.

### 4.3. Surface Renderer (`A2uiSurface`)
We will create a root React component, `<A2uiSurface surface={surfaceModel} />`, which:
* Locates the component with `id="root"`.
* Recursively renders the tree using a component registry mapping component types (e.g., "Text", "Button") to their wrapped React implementations.

## 5. Minimal Catalog Implementation
For our initial milestone, we will target the `minimal_catalog.json` specification.

### 5.1. Core Library (Binder & APIs)
We will define the component APIs (Schemas) using Zod for the following components:
* `Text`
* `Row`
* `Column`
* `Button`
* `TextField`

We will implement the `capitalize` function.

### 5.2. Framework Library (React UI Widgets)
We will build stateless, styled React components for the minimal catalog, wrapped using `createReactComponent`.
* `ReactText`
* `ReactRow`
* `ReactColumn`
* `ReactButton`
* `ReactTextField`

### 5.3. Catalog Assembly
We will bundle these definitions and implementations into a `Catalog` instance that the `MessageProcessor` can use.

## 6. Milestone: Demo Application
Once the minimal catalog is complete, we will build a local demo application:
* A standalone React app (`npm run dev` in Vite).
* Loads JSON arrays from `minimal_catalog/examples/`.
* Feeds them into a `MessageProcessor`.
* Renders the resulting `SurfaceGroupModel` using `<A2uiSurface />`.
* Includes a test for delayed `updateDataModel` messages to verify reactive updates and progressive rendering.
23 changes: 23 additions & 0 deletions renderers/react/eslint.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import js from '@eslint/js'
import globals from 'globals'
import reactHooks from 'eslint-plugin-react-hooks'
import reactRefresh from 'eslint-plugin-react-refresh'
import tseslint from 'typescript-eslint'
import { defineConfig, globalIgnores } from 'eslint/config'

export default defineConfig([
globalIgnores(['dist']),
{
files: ['**/*.{ts,tsx}'],
extends: [
js.configs.recommended,
tseslint.configs.recommended,
reactHooks.configs.flat.recommended,
reactRefresh.configs.vite,
],
languageOptions: {
ecmaVersion: 2020,
globals: globals.browser,
},
},
])
Loading