{
    "$schema": "https://json-schema.org/draft/2020-12/schema",
    "$id": "https://a2ui.org/specification/v1_0/server_to_client.json",
    "title": "A2UI Message Schema",
    "description": "Describes a JSON payload for an A2UI (Agent to UI) message, which is used to dynamically construct and update user interfaces.",
    "type": "object",
    "oneOf": [
        { "$ref": "#/$defs/CreateSurfaceMessage" },
        { "$ref": "#/$defs/UpdateComponentsMessage" },
        { "$ref": "#/$defs/UpdateDataModelMessage" },
        { "$ref": "#/$defs/DeleteSurfaceMessage" },
        { "$ref": "#/$defs/CallFunctionMessage" },
        { "$ref": "#/$defs/ActionResponseMessage" }
    ],
    "$defs": {
        "CreateSurfaceMessage": {
            "type": "object",
            "properties": {
                "version": {
                    "const": "v1.0"
                },
                "createSurface": {
                    "type": "object",
                    "description": "Signals the client to create a new surface and begin rendering it. It is an error to try to create a surface with the same ID twice without first deleting it; surfaceId MUST be globally unique for the renderer's lifetime. When this message is sent, the client will expect 'updateComponents' and/or 'updateDataModel' messages for the same surfaceId that define the component tree.",
                    "properties": {
                        "surfaceId": {
                            "type": "string",
                            "description": "The unique identifier for the UI surface to be rendered. It must be globally unique for the renderer's lifetime."
                        },
                        "catalogId": {
                            "description": "A string that uniquely identifies this catalog. It is recommended to prefix this with an internet domain that you own, to avoid conflicts e.g. mycompany.com:somecatalog'.",
                            "type": "string"
                        },
                        "surfaceProperties": {
                            "$ref": "catalog.json#/$defs/surfaceProperties",
                            "description": "Initial surface properties (e.g., {'agentDisplayName': 'My Agent'}). These must validate against the 'surfaceProperties' schema defined in the catalog."
                        },
                        "sendDataModel": {
                            "type": "boolean",
                            "description": "If true, the client will send the full data model of this surface in the metadata of every A2A message sent to the server that created the surface. Defaults to false."
                        },
                        "components": {
                            "$ref": "#/$defs/ComponentsList"
                        },
                        "dataModel": {
                            "type": "object",
                            "description": "The initial root data model object for the surface.",
                            "additionalProperties": true
                        }
                    },
                    "required": ["surfaceId", "catalogId"],
                    "additionalProperties": false
                }
            },
            "required": ["createSurface", "version"],
            "additionalProperties": false
        },
        "ComponentsList": {
            "type": "array",
            "description": "A list containing UI components for the surface.",
            "minItems": 1,
            "items": {
                "$ref": "catalog.json#/$defs/anyComponent"
            }
        },
        "UpdateComponentsMessage": {
            "type": "object",
            "properties": {
                "version": {
                    "const": "v1.0"
                },
                "updateComponents": {
                    "type": "object",
                    "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.",
                    "properties": {
                        "surfaceId": {
                            "type": "string",
                            "description": "The unique identifier for the UI surface to be updated. It must be globally unique for the renderer's lifetime."
                        },
                        "components": {
                            "$ref": "#/$defs/ComponentsList"
                        }
                    },
                    "required": ["surfaceId", "components"],
                    "additionalProperties": false
                }
            },
            "required": ["updateComponents", "version"],
            "additionalProperties": false
        },
        "UpdateDataModelMessage": {
            "type": "object",
            "properties": {
                "version": {
                    "const": "v1.0"
                },
                "updateDataModel": {
                    "type": "object",
                    "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.",
                    "properties": {
                        "surfaceId": {
                            "type": "string",
                            "description": "The unique identifier for the UI surface this data model update applies to. It must be globally unique for the renderer's lifetime."
                        },
                        "path": {
                            "type": "string",
                            "description": "An optional path to a location within the data model (e.g., '/user/name'). If omitted, or set to '/', refers to the entire data model."
                        },
                        "value": {
                            "description": "The data to be updated in the data model. If present, the value at 'path' is replaced (or created). If omitted, the key at 'path' is removed.",
                            "additionalProperties": true
                        }
                    },
                    "required": ["surfaceId"],
                    "additionalProperties": false
                }
            },
            "required": ["updateDataModel", "version"],
            "additionalProperties": false
        },
        "DeleteSurfaceMessage": {
            "type": "object",
            "properties": {
                "version": {
                    "const": "v1.0"
                },
                "deleteSurface": {
                    "type": "object",
                    "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.",
                    "properties": {
                        "surfaceId": {
                            "type": "string",
                            "description": "The unique identifier for the UI surface to be deleted. It must be globally unique for the renderer's lifetime."
                        }
                    },
                    "required": ["surfaceId"],
                    "additionalProperties": false
                }
            },
            "required": ["deleteSurface", "version"],
            "additionalProperties": false
        },
        "CallFunctionMessage": {
            "type": "object",
            "description": "A function invoked from the server.",
            "properties": {
                "version": {
                    "const": "v1.0"
                },
                "functionCallId": {
                    "$ref": "common_types.json#/$defs/CallId",
                    "description": "Unique ID for the instance of this function call. MUST be copied verbatim into the functionResponse or error."
                },
                "wantResponse": {
                    "type": "boolean",
                    "default": false
                },
                "callFunction": {
                    "allOf": [
                        {
                            "$ref": "common_types.json#/$defs/FunctionCall"
                        }
                    ],
                    "required": ["call"],
                    "unevaluatedProperties": false
                }
            },
            "required": ["version", "callFunction", "functionCallId"],
            "additionalProperties": false
        },
        "ActionResponseMessage": {
            "type": "object",
            "description": "A response to a client-initiated action.",
            "properties": {
                "version": {
                    "const": "v1.0"
                },
                "actionId": {
                    "type": "string",
                    "description": "The ID of the action call this response belongs to."
                },
                "actionResponse": {
                    "type": "object",
                    "properties": {
                        "value": {
                            "description": "The return value of the action.",
                            "type": ["string", "number", "boolean", "array", "object", "null"]
                        },
                        "error": {
                            "type": "object",
                            "properties": {
                                "code": { "type": "string" },
                                "message": { "type": "string" }
                            },
                            "required": ["code", "message"],
                            "additionalProperties": false
                        }
                    },
                    "oneOf": [{ "required": ["value"] }, { "required": ["error"] }],
                    "additionalProperties": false
                }
            },
            "required": ["version", "actionResponse", "actionId"],
            "additionalProperties": false
        }
    }
}
