Skip to content

Commit 3ef01bb

Browse files
committed
fix: match A2uiMessage.a2uiMessageSchema to v0.9 server to client JSON schema
According to A2UI v0.9 specification: https://a2ui.org/reference/messages/#v09_1 https://a2ui.org/specification/v0_9/server_to_client.json
1 parent bba8a70 commit 3ef01bb

11 files changed

+481
-244
lines changed

packages/genui/lib/src/model/a2ui_message.dart

Lines changed: 28 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -89,36 +89,44 @@ sealed class A2uiMessage {
8989
/// Returns the JSON schema for an A2UI message.
9090
static Schema a2uiMessageSchema(Catalog catalog) {
9191
return S.combined(
92-
allOf: [
92+
title: 'A2UI Message Schema',
93+
description:
94+
'Describes a JSON payload for an A2UI (Agent to UI) message, '
95+
'which is used to dynamically construct and update user interfaces.',
96+
oneOf: [
9397
S.object(
94-
title: 'A2UI Message Schema',
95-
description:
96-
'Describes a JSON payload for an A2UI (Agent to UI) message. '
97-
'A message MUST contain exactly ONE of the action properties.',
9898
properties: {
9999
'version': S.string(constValue: 'v0.9'),
100100
'createSurface': A2uiSchemas.createSurfaceSchema(),
101+
},
102+
required: ['version', 'createSurface'],
103+
additionalProperties: false,
104+
),
105+
S.object(
106+
properties: {
107+
'version': S.string(constValue: 'v0.9'),
101108
'updateComponents': A2uiSchemas.updateComponentsSchema(catalog),
109+
},
110+
required: ['version', 'updateComponents'],
111+
additionalProperties: false,
112+
),
113+
S.object(
114+
properties: {
115+
'version': S.string(constValue: 'v0.9'),
102116
'updateDataModel': A2uiSchemas.updateDataModelSchema(),
117+
},
118+
required: ['version', 'updateDataModel'],
119+
additionalProperties: false,
120+
),
121+
S.object(
122+
properties: {
123+
'version': S.string(constValue: 'v0.9'),
103124
'deleteSurface': A2uiSchemas.deleteSurfaceSchema(),
104125
},
105-
required: ['version'],
126+
required: ['version', 'deleteSurface'],
127+
additionalProperties: false,
106128
),
107129
],
108-
anyOf: [
109-
{
110-
'required': ['createSurface'],
111-
},
112-
{
113-
'required': ['updateComponents'],
114-
},
115-
{
116-
'required': ['updateDataModel'],
117-
},
118-
{
119-
'required': ['deleteSurface'],
120-
},
121-
],
122130
);
123131
}
124132
}

packages/genui/lib/src/model/a2ui_schemas.dart

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,11 @@ abstract final class A2uiSchemas {
398398

399399
/// Schema for a createSurface message.
400400
static Schema createSurfaceSchema() => S.object(
401+
description:
402+
'Signals the client to create a new surface and begin rendering it. '
403+
"When this message is sent, the client will expect 'updateComponents' "
404+
"and/or 'updateDataModel' messages for the same surfaceId that define "
405+
'the component tree.',
401406
properties: {
402407
surfaceIdKey: S.string(description: 'The unique ID for the surface.'),
403408
'catalogId': S.string(description: 'The URI of the component catalog.'),
@@ -414,12 +419,21 @@ abstract final class A2uiSchemas {
414419

415420
/// Schema for a deleteSurface message.
416421
static Schema deleteSurfaceSchema() => S.object(
422+
description:
423+
"Signals the client to delete the surface identified by 'surfaceId'. "
424+
'The createSurface message MUST have been previously sent with the '
425+
"'catalogId' that is in this message.",
417426
properties: {surfaceIdKey: S.string()},
418427
required: [surfaceIdKey],
419428
);
420429

421430
/// Schema for a updateDataModel message.
422431
static Schema updateDataModelSchema() => S.object(
432+
description:
433+
'Updates the data model for an existing surface. This message can be '
434+
'sent multiple times to update the data model. The createSurface '
435+
"message MUST have been previously sent with the 'catalogId' that is "
436+
'in this message.',
423437
properties: {
424438
surfaceIdKey: S.string(),
425439
'path': S.combined(type: JsonType.string, defaultValue: '/'),
@@ -445,6 +459,13 @@ abstract final class A2uiSchemas {
445459
.toList();
446460

447461
return S.object(
462+
description:
463+
'Updates a surface with a new set of components. This message can '
464+
'be sent multiple times to update the component tree of an existing '
465+
'surface. One of the components in one of the components lists MUST '
466+
"have an 'id' of 'root' to serve as the root of the component tree. "
467+
'The createSurface message MUST have been previously sent with the '
468+
"'catalogId' that is in this message.",
448469
properties: {
449470
surfaceIdKey: S.string(
450471
description: 'The unique identifier for the UI surface.',

packages/genui/test/facade/prompt_builder_test.golden/all_operations_with_dataModel_false.txt

Lines changed: 52 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -127,18 +127,19 @@ When constructing UI, you must output a VALID A2UI JSON object representing one
127127

128128
-----A2UI_JSON_SCHEMA_START-----
129129
{
130-
"allOf": [
130+
"title": "A2UI Message Schema",
131+
"description": "Describes a JSON payload for an A2UI (Agent to UI) message, which is used to dynamically construct and update user interfaces.",
132+
"oneOf": [
131133
{
132134
"type": "object",
133-
"title": "A2UI Message Schema",
134-
"description": "Describes a JSON payload for an A2UI (Agent to UI) message. A message MUST contain exactly ONE of the action properties.",
135135
"properties": {
136136
"version": {
137137
"type": "string",
138138
"const": "v0.9"
139139
},
140140
"createSurface": {
141141
"type": "object",
142+
"description": "Signals the client to create a new surface and begin rendering it. When this message is sent, the client will expect 'updateComponents' and/or 'updateDataModel' messages for the same surfaceId that define the component tree.",
142143
"properties": {
143144
"surfaceId": {
144145
"type": "string",
@@ -162,9 +163,24 @@ When constructing UI, you must output a VALID A2UI JSON object representing one
162163
"surfaceId",
163164
"catalogId"
164165
]
166+
}
167+
},
168+
"required": [
169+
"version",
170+
"createSurface"
171+
],
172+
"additionalProperties": false
173+
},
174+
{
175+
"type": "object",
176+
"properties": {
177+
"version": {
178+
"type": "string",
179+
"const": "v0.9"
165180
},
166181
"updateComponents": {
167182
"type": "object",
183+
"description": "Updates a surface with a new set of components. This message can be sent multiple times to update the component tree of an existing surface. One of the components in one of the components lists MUST have an 'id' of 'root' to serve as the root of the component tree. The createSurface message MUST have been previously sent with the 'catalogId' that is in this message.",
168184
"properties": {
169185
"surfaceId": {
170186
"type": "string",
@@ -253,9 +269,24 @@ When constructing UI, you must output a VALID A2UI JSON object representing one
253269
"surfaceId",
254270
"components"
255271
]
272+
}
273+
},
274+
"required": [
275+
"version",
276+
"updateComponents"
277+
],
278+
"additionalProperties": false
279+
},
280+
{
281+
"type": "object",
282+
"properties": {
283+
"version": {
284+
"type": "string",
285+
"const": "v0.9"
256286
},
257287
"updateDataModel": {
258288
"type": "object",
289+
"description": "Updates the data model for an existing surface. This message can be sent multiple times to update the data model. The createSurface message MUST have been previously sent with the 'catalogId' that is in this message.",
259290
"properties": {
260291
"surfaceId": {
261292
"type": "string"
@@ -271,9 +302,24 @@ When constructing UI, you must output a VALID A2UI JSON object representing one
271302
"required": [
272303
"surfaceId"
273304
]
305+
}
306+
},
307+
"required": [
308+
"version",
309+
"updateDataModel"
310+
],
311+
"additionalProperties": false
312+
},
313+
{
314+
"type": "object",
315+
"properties": {
316+
"version": {
317+
"type": "string",
318+
"const": "v0.9"
274319
},
275320
"deleteSurface": {
276321
"type": "object",
322+
"description": "Signals the client to delete the surface identified by 'surfaceId'. The createSurface message MUST have been previously sent with the 'catalogId' that is in this message.",
277323
"properties": {
278324
"surfaceId": {
279325
"type": "string"
@@ -285,30 +331,10 @@ When constructing UI, you must output a VALID A2UI JSON object representing one
285331
}
286332
},
287333
"required": [
288-
"version"
289-
]
290-
}
291-
],
292-
"anyOf": [
293-
{
294-
"required": [
295-
"createSurface"
296-
]
297-
},
298-
{
299-
"required": [
300-
"updateComponents"
301-
]
302-
},
303-
{
304-
"required": [
305-
"updateDataModel"
306-
]
307-
},
308-
{
309-
"required": [
334+
"version",
310335
"deleteSurface"
311-
]
336+
],
337+
"additionalProperties": false
312338
}
313339
]
314340
}

packages/genui/test/facade/prompt_builder_test.golden/all_operations_with_dataModel_true.txt

Lines changed: 52 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -129,18 +129,19 @@ When constructing UI, you must output a VALID A2UI JSON object representing one
129129

130130
-----A2UI_JSON_SCHEMA_START-----
131131
{
132-
"allOf": [
132+
"title": "A2UI Message Schema",
133+
"description": "Describes a JSON payload for an A2UI (Agent to UI) message, which is used to dynamically construct and update user interfaces.",
134+
"oneOf": [
133135
{
134136
"type": "object",
135-
"title": "A2UI Message Schema",
136-
"description": "Describes a JSON payload for an A2UI (Agent to UI) message. A message MUST contain exactly ONE of the action properties.",
137137
"properties": {
138138
"version": {
139139
"type": "string",
140140
"const": "v0.9"
141141
},
142142
"createSurface": {
143143
"type": "object",
144+
"description": "Signals the client to create a new surface and begin rendering it. When this message is sent, the client will expect 'updateComponents' and/or 'updateDataModel' messages for the same surfaceId that define the component tree.",
144145
"properties": {
145146
"surfaceId": {
146147
"type": "string",
@@ -164,9 +165,24 @@ When constructing UI, you must output a VALID A2UI JSON object representing one
164165
"surfaceId",
165166
"catalogId"
166167
]
168+
}
169+
},
170+
"required": [
171+
"version",
172+
"createSurface"
173+
],
174+
"additionalProperties": false
175+
},
176+
{
177+
"type": "object",
178+
"properties": {
179+
"version": {
180+
"type": "string",
181+
"const": "v0.9"
167182
},
168183
"updateComponents": {
169184
"type": "object",
185+
"description": "Updates a surface with a new set of components. This message can be sent multiple times to update the component tree of an existing surface. One of the components in one of the components lists MUST have an 'id' of 'root' to serve as the root of the component tree. The createSurface message MUST have been previously sent with the 'catalogId' that is in this message.",
170186
"properties": {
171187
"surfaceId": {
172188
"type": "string",
@@ -255,9 +271,24 @@ When constructing UI, you must output a VALID A2UI JSON object representing one
255271
"surfaceId",
256272
"components"
257273
]
274+
}
275+
},
276+
"required": [
277+
"version",
278+
"updateComponents"
279+
],
280+
"additionalProperties": false
281+
},
282+
{
283+
"type": "object",
284+
"properties": {
285+
"version": {
286+
"type": "string",
287+
"const": "v0.9"
258288
},
259289
"updateDataModel": {
260290
"type": "object",
291+
"description": "Updates the data model for an existing surface. This message can be sent multiple times to update the data model. The createSurface message MUST have been previously sent with the 'catalogId' that is in this message.",
261292
"properties": {
262293
"surfaceId": {
263294
"type": "string"
@@ -273,9 +304,24 @@ When constructing UI, you must output a VALID A2UI JSON object representing one
273304
"required": [
274305
"surfaceId"
275306
]
307+
}
308+
},
309+
"required": [
310+
"version",
311+
"updateDataModel"
312+
],
313+
"additionalProperties": false
314+
},
315+
{
316+
"type": "object",
317+
"properties": {
318+
"version": {
319+
"type": "string",
320+
"const": "v0.9"
276321
},
277322
"deleteSurface": {
278323
"type": "object",
324+
"description": "Signals the client to delete the surface identified by 'surfaceId'. The createSurface message MUST have been previously sent with the 'catalogId' that is in this message.",
279325
"properties": {
280326
"surfaceId": {
281327
"type": "string"
@@ -287,30 +333,10 @@ When constructing UI, you must output a VALID A2UI JSON object representing one
287333
}
288334
},
289335
"required": [
290-
"version"
291-
]
292-
}
293-
],
294-
"anyOf": [
295-
{
296-
"required": [
297-
"createSurface"
298-
]
299-
},
300-
{
301-
"required": [
302-
"updateComponents"
303-
]
304-
},
305-
{
306-
"required": [
307-
"updateDataModel"
308-
]
309-
},
310-
{
311-
"required": [
336+
"version",
312337
"deleteSurface"
313-
]
338+
],
339+
"additionalProperties": false
314340
}
315341
]
316342
}

0 commit comments

Comments
 (0)