Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
5 changes: 5 additions & 0 deletions apps/website/content/docs/render/a2ui/catalog.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,7 @@ A single-line text input with optional label and placeholder.
| `label` | `string` | Input label |
| `value` | `string` | Current value (bind via `_bindings`) |
| `placeholder` | `string` | Placeholder text |
| `validationResult` | `A2uiValidationResult` | Validation state — shows errors below input when invalid |
| `_bindings` | `Record<string, string>` | Bind `value` to a data model path |
| `emit` | injected | Event emitter provided by the render engine |

Expand All @@ -210,6 +211,7 @@ A labeled checkbox with two-way binding for its checked state.
|------|------|-------------|
| `label` | `string` | Checkbox label |
| `checked` | `boolean` | Current checked state (bind via `_bindings`) |
| `validationResult` | `A2uiValidationResult` | Validation state — shows errors below checkbox when invalid |
| `_bindings` | `Record<string, string>` | Bind `checked` to a data model path |
| `emit` | injected | Event emitter provided by the render engine |

Expand All @@ -226,6 +228,7 @@ A dropdown select control with a list of string options.
| `label` | `string` | Select label |
| `options` | `string[]` | List of available options |
| `selected` | `string` | Currently selected value (bind via `_bindings`) |
| `validationResult` | `A2uiValidationResult` | Validation state — shows errors below dropdown when invalid |
| `_bindings` | `Record<string, string>` | Bind `selected` to a data model path |
| `emit` | injected | Event emitter provided by the render engine |

Expand All @@ -244,6 +247,7 @@ A date, time, or datetime input with two-way binding.
| `inputType` | `'date' \| 'time' \| 'datetime-local'` | HTML input type. Defaults to `'date'` |
| `min` | `string` | Minimum allowed value |
| `max` | `string` | Maximum allowed value |
| `validationResult` | `A2uiValidationResult` | Validation state — shows errors below input when invalid |
| `_bindings` | `Record<string, string>` | Bind `value` to a data model path |
| `emit` | injected | Event emitter provided by the render engine |

Expand Down Expand Up @@ -273,6 +277,7 @@ A range slider input with two-way binding.
| `min` | `number` | Minimum value |
| `max` | `number` | Maximum value |
| `step` | `number` | Step increment |
| `validationResult` | `A2uiValidationResult` | Validation state — shows errors below slider when invalid |
| `_bindings` | `Record<string, string>` | Bind `value` to a data model path |
| `emit` | injected | Event emitter provided by the render engine |

Expand Down
36 changes: 36 additions & 0 deletions apps/website/content/docs/render/a2ui/overview.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -394,6 +394,42 @@ The data model is only sent with event actions — there are no passive change n
/>
```

## Data Model Bindings

When the agent sets component properties using path references (`{ "path": "/name" }`), the surface component
tracks these as **bindings** — a mapping from prop name to JSON Pointer path. These bindings are passed to
catalog components as the `_bindings` prop.

### How Bindings Work

1. **Agent sends components** with path references: `{ "value": { "path": "/form/name" } }`
2. **`surfaceToSpec`** resolves the path to a current value AND records the binding in `_bindings`
3. **Catalog component** reads the resolved value normally. When the user changes the value, it emits an `a2ui:datamodel` event via the `emit` callback
4. **The event format** is `a2ui:datamodel:{path}:{value}`

### Using `emitBinding`

Custom catalog components can use the `emitBinding` utility for consistent binding emission:

```typescript
import { emitBinding } from '@cacheplane/chat';

// In your component's change handler:
onInput(event: Event): void {
const val = (event.target as HTMLInputElement).value;
emitBinding(this.emit(), this._bindings(), 'value', val);
}
```

### Known Limitations

The current binding mechanism is client-side only — the `a2ui:datamodel` events are emitted
but do not yet flow through the render lib's `StateStore`. Data model updates from user input
are not reflected back to other components in real time. Full `StateStore` integration is planned
for a future release.

Data model state is refreshed when the agent sends an `updateDataModel` message.

## What's Next

<CardGroup cols={2}>
Expand Down
Loading
Loading