You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Currently, A2UI has an underlying data structure which is basically a set of components and a data model. But our messages are for incrementally updating each of them, just imply defining them.
Problems
There is no well-defined format to serialize the current state of a surface
Our CRUD operations are a little irregular. E.g. why updateComponents rather than updateSurface? Why not include initial components in CreateSurface etc (see createSurface that includes initial components and data model #1239). If we add more kinds of data, we need to invent new CRUD operations to represent them.
In practice, most UIs are created and never updated, so it makes sense for the format to emphasize the surface state, rather than incremental updates. Right now, we have an incremental API makes it simple to represent changes to state (a single message) but complex to represent the current state (list of message which may overwrite each other and thus be redundant).
There is no way to delete components currently, only replace them.
Recent changes in direction
Since we defined A2UI v0.8 and v0.9, some things have changed about our direction which could motivate this design change.
There is more emphasis on MCP, which is typically a "generate once" pattern, rather than a "generate and update" pattern. A2UI is kind of awkward for MCP, because they need to include a list of messages, and there is a question about which order they should be in etc (it doesn't matter).
Let's focus on defining a JSON object which represents the state of a surface including data model and components. Then, when creating new surfaces, we just send the data. To update a surface, we send a JSON patch based on the previous data to apply.
Pros and Cons
Pros
Simplify the transport format
Simplify the mental model of a Surface snapshot and incremental updates
Make it easy for us to expand the surface state representation (e.g. add something more than data model and components) without needing to rethink CRUD operations
Simplify core library implementation. Currently, we have a message processor that understands how to apply our messages to a data model. Instead, we would just have some JSON and a JSON patch library that modifies it.
Obvious way to represent surface snapshot state to LLMs. Currently, in the most simple a2ui implementations, the LLM would see the history of A2UI messages in its context. This is unnecessarily verbose. If there are many messages updating a surface, it should likely just see a snapshot of surface state. This new structure makes it obvious how to achieve this.
Ability to represent arbitrarily small updates to state, e.g. update an individual property value
Cons
Creates more churn - this is relatively big change to the spec. Though, I believe we can make this update in the core library and renderers would be unaffected.
Agents will really need full access to the accurate existing UI state in order to generate correct patches. They will probably have this anyway, though.
JSON patch is hard for humans to read
To incrementally update surfaces, developers will need an inference library to help. They won't be able to wing the JSON patch generation.
Sketch
Surface
{
"$defs": {
"Surface": {
"type": "object",
"description": "The complete state of an A2UI surface.",
"properties": {
"surfaceId": {
"type": "string",
"description": "Unique identifier for the surface."
},
"catalogId": {
"type": "string",
"description": "The URI of the catalog defining the components used."
},
"components": {
"type": "object",
"description": "A map of ComponentId to component definitions.",
"additionalProperties": {
"$ref": "catalog.json#/$defs/anyComponent"
}
},
"dataModel": {
"type": "object",
"description": "The initial data model for the surface.",
"default": {}
},
"theme": {
"$ref": "catalog.json#/$defs/theme"
},
"sendDataModel": {
"type": "boolean",
"default": false
}
},
"required": ["surfaceId", "catalogId", "components"]
}
}
}
Background
Currently, A2UI has an underlying data structure which is basically a set of components and a data model. But our messages are for incrementally updating each of them, just imply defining them.
Problems
updateComponentsrather thanupdateSurface? Why not include initial components inCreateSurfaceetc (see createSurface that includes initial components and data model #1239). If we add more kinds of data, we need to invent new CRUD operations to represent them.Recent changes in direction
Since we defined A2UI v0.8 and v0.9, some things have changed about our direction which could motivate this design change.
Proposal
Let's focus on defining a JSON object which represents the state of a surface including data model and components. Then, when creating new surfaces, we just send the data. To update a surface, we send a JSON patch based on the previous data to apply.
Pros and Cons
Pros
Cons
Sketch
Surface
Server to client