diff --git a/specification/v1_0/catalogs/basic/catalog.json b/specification/v1_0/catalogs/basic/catalog.json index 8a93af75d2..9b6b962411 100644 --- a/specification/v1_0/catalogs/basic/catalog.json +++ b/specification/v1_0/catalogs/basic/catalog.json @@ -1366,21 +1366,6 @@ } }, "$defs": { - "surfaceProperties": { - "type": "object", - "properties": { - "iconUrl": { - "type": "string", - "format": "uri", - "description": "A URL for an image that identifies the agent or tool associated with the surface." - }, - "agentDisplayName": { - "type": "string", - "description": "Text to be displayed next to the surface to identify the agent or tool that created it." - } - }, - "additionalProperties": true - }, "anyComponent": { "oneOf": [ { diff --git a/specification/v1_0/docs/a2ui_protocol.md b/specification/v1_0/docs/a2ui_protocol.md index 375d72b1d7..2bd72623f3 100644 --- a/specification/v1_0/docs/a2ui_protocol.md +++ b/specification/v1_0/docs/a2ui_protocol.md @@ -36,7 +36,7 @@ The major differences between version 1.0 and 0.9 (including 0.9.1) are: - **Bidirectional RPC Messaging**: Supports synchronous agent responses to renderer actions (`actionResponse`) and remote agent-initiated function execution (`callFunction` / `functionResponse`) verified against runtime catalog definitions. - **Single-Message UI Instantiation**: Allows initial component trees and data models to be embedded directly within `createSurface`, enabling complete UI composition in a single payload. -- **Decoupled Branding**: Replaces rigid theme properties with extensible `surfaceProperties` (removing hardcoded brand colors) to defer visual styling entirely to the target framework's native theme. +- **Decoupled Branding**: Removes rigid theme properties (removing hardcoded brand colors) to defer visual styling entirely to the target framework's native theme. - **Enhanced Catalog Schemas**: Refactors function definitions into object maps for direct O(1) lookups and supports standard JSON Schema metadata fields (`$schema`, `$id`) on inline catalogs. - **Strict Identifier & Context Standards**: Enforces Unicode (UAX #31) naming rules across all catalog entities and reserves the `@` namespace for universal system context evaluations (such as `@index`). @@ -138,11 +138,11 @@ The [`agent_to_renderer.json`] schema is the top-level entry point. Every messag ### The Basic Catalog -The [`catalogs/basic/catalog.json`] schema contains the definitions for all specific UI components (e.g., `Text`, `Button`, `Row`), functions (e.g., `required`, `email`), and the `surfaceProperties` schema. +The [`catalogs/basic/catalog.json`] schema contains the definitions for all specific UI components (e.g., `Text`, `Button`, `Row`) and functions (e.g., `required`, `email`). **Swappable Catalogs & Validation:** -The [`agent_to_renderer.json`] envelope schema is designed to be catalog-agnostic. It references components and surfaceProperties using a placeholder filename: `catalog.json` (specifically `$ref: "catalog.json#/$defs/anyComponent"` and `$ref: "catalog.json#/$defs/surfaceProperties"`). +The [`agent_to_renderer.json`] envelope schema is designed to be catalog-agnostic. It references components using a placeholder filename: `catalog.json` (specifically `$ref: "catalog.json#/$defs/anyComponent"`). To validate A2UI messages: @@ -182,8 +182,6 @@ One of the components in one of the component lists MUST have an `id` of `root` - `surfaceId` (string, required): The unique identifier for the UI surface to be rendered. This must be globally unique for the renderer's lifetime. - `catalogId` (string, optional): A string that uniquely identifies the default catalog (components and functions) used for this surface. Note that `catalogId` is a string identifier, not a resolvable URI; while it is conventionally formatted as a URI (e.g., `https://mycompany.com/1.0/somecatalog`) to avoid naming collisions across organizations, it does not need to point to any deployed resource or downloadable file. Components and function calls on this surface that do not explicitly specify their own `catalogId` will use this surface-level default `catalogId`. - -- `surfaceProperties` (object, optional): A JSON object containing surface properties (e.g., `agentDisplayName`) defined in the catalog's surfaceProperties schema. - `sendDataModel` (boolean, optional): If true, the renderer will send the full data model of this surface in the metadata of every message sent to the agent (via the Transport's metadata mechanism). This ensures the surface owner receives the full current state of the UI alongside the user's action or query. Defaults to false. - `components` (array, optional): A list containing UI components for the surface, allowing the renderer to build and populate the UI tree immediately on surface creation. Conforms to the `ComponentsList` schema. - `dataModel` (object, optional): A plain JSON object representing the initial root state of the data model. @@ -196,9 +194,6 @@ One of the components in one of the component lists MUST have an `id` of `root` "createSurface": { "surfaceId": "user_profile_card", "catalogId": "https://a2ui.org/specification/v1_0/catalogs/basic/catalog.json", - "surfaceProperties": { - "agentDisplayName": "Weather Bot" - }, "sendDataModel": true, "components": [ { @@ -459,7 +454,6 @@ Every catalog follows the standard `Catalog` object definition: - **instructions** (string, optional): Markdown-formatted design principles, rules, or developer guidelines specific to this catalog. These rules guide LLMs when generating UI layouts under this catalog. - **components** (object, optional): A map of supported UI components, where each key is the component type (e.g., `Text`) and its value is its JSON Schema definition. All keys MUST conform to the UAX #31 entity naming rules defined below. - **functions** (object, optional): A map of renderer-side validation or utility functions supported by the catalog, where each key is the function name and its value is its definition. All function names MUST conform to the UAX #31 entity naming rules defined below. The renderer determines a function's execution boundary (e.g., rendererOnly status) at runtime by reading its configuration from the active catalog definition. -- **surfaceProperties** (object, optional): A schema defining the catalog's customizable visual properties. #### Catalog Entity Naming Rules @@ -490,12 +484,11 @@ To ensure catalog schemas can be translated reliably into alternative, LLM-frien 1. **Strict Top-Level vs. `$defs` Boundary:** - **Top-Level components and functions:** All component and function schemas MUST be declared directly under the top-level keys `"components"` and `"functions"` respectively. - **External References inside `$defs`:** Any definition referenced externally (e.g., from the envelope schema `agent_to_renderer.json` or `common_types.json`) MUST reside inside the `"$defs"` object at the catalog root. This strictly includes: - - `surfaceProperties`: Referenced as `catalog.json#/$defs/surfaceProperties`. - `anyComponent`: Referenced as `catalog.json#/$defs/anyComponent`. - `anyFunction`: Referenced as `catalog.json#/$defs/anyFunction`. 2. **No Custom `$defs` or Helpers:** - To prevent unconstrained branching, custom definitions or shared helper schemas inside a catalog are strictly prohibited under `"$defs"`. - - The only allowed keys within the catalog's `"$defs"` object are `anyComponent`, `anyFunction`, and `surfaceProperties`. + - The only allowed keys within the catalog's `"$defs"` object are `anyComponent` and `anyFunction`. - All helper properties (such as common properties factored out of catalog items) MUST be inlined directly inside the properties block of each supporting component schema rather than referenced from a shared helper. 3. **Restricted `$ref` Targets:** - Local `$ref` targets are restricted to referencing the catalog's top-level components or functions (e.g., `#/components/Text`, `#/functions/required`). @@ -554,7 +547,7 @@ Below is an annotated, fully compliant `catalog.json` schema template (written i ```jsonc { - // Rule 7: Strict Top-Level Schema Keys + // Strict Top-Level Schema Keys "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://a2ui.org/specification/v1_0/catalogs/basic/catalog.json", "protocolVersion": "1.0", @@ -563,20 +556,20 @@ Below is an annotated, fully compliant `catalog.json` schema template (written i "catalogId": "https://example.com/catalogs/custom-v1", "instructions": "Design instructions for LLMs when generating layouts under this catalog.", - // Rule 1: Top-level components declared under top-level "components" map. + // Top-level components declared under top-level "components" map. "components": { "Text": { "type": "object", - // Rule 5: Components must combine ComponentCommon and local properties using "allOf". + // Components must combine ComponentCommon and local properties using "allOf". "allOf": [ { - // Rule 3: External references must reference standard types in common_types.json. + // External references must reference standard types in common_types.json. "$ref": "https://a2ui.org/specification/v1_0/common_types.json#/$defs/ComponentCommon", }, { "type": "object", "properties": { - // Rule 4: Required "component" property must be a constant matching the component key. + // Required "component" property must be a constant matching the component key. "component": { "const": "Text", }, @@ -593,16 +586,16 @@ Below is an annotated, fully compliant `catalog.json` schema template (written i }, }, - // Rule 1: Top-level functions declared under top-level "functions" map. + // Top-level functions declared under top-level "functions" map. "functions": { "required": { "type": "object", "description": "Checks that the value is not null, undefined, or empty.", - // Rule 6: Strict function metadata defined outside the properties block. + // Strict function metadata defined outside the properties block. "returnType": "boolean", "callableFrom": "rendererOnly", "properties": { - // Rule 6: Function call schema requires constant with function's name. + // Function call schema requires constant with function's name. "call": { "const": "required", }, @@ -622,21 +615,13 @@ Below is an annotated, fully compliant `catalog.json` schema template (written i }, }, - // Rule 1 & Rule 2: $defs is restricted strictly to surfaceProperties, anyComponent, and anyFunction. + // $defs is restricted strictly to anyComponent and anyFunction. // Custom definitions or helpers inside a catalog are strictly prohibited under $defs. "$defs": { - "surfaceProperties": { - "type": "object", - "properties": { - "agentDisplayName": { - "type": "string", - }, - }, - }, "anyComponent": { "oneOf": [ { - // Rule 3: Local refs restricted to top-level components map. + // Local refs restricted to top-level components map. "$ref": "#/components/Text", }, ], @@ -647,7 +632,7 @@ Below is an annotated, fully compliant `catalog.json` schema template (written i "anyFunction": { "oneOf": [ { - // Rule 3: Local refs restricted to top-level functions map. + // Local refs restricted to top-level functions map. "$ref": "#/functions/required", }, ], @@ -1058,21 +1043,6 @@ The [`catalogs/basic/catalog.json`] provides the baseline set of components and | **or** | Logical OR operation on a list of boolean values. | | **not** | Logical NOT operation on a boolean value. | -### Surface Properties - -The basic catalog defines the following surface properties that can be set in the `createSurface` message: - -| Property | Type | Description | -| :------------------- | :----- | :----------------------------------------------------------------------------------------------------------- | -| **iconUrl** | URI | A URL for an image (e.g., logo or avatar) that identifies the agent or tool associated with the surface. | -| **agentDisplayName** | String | Text to be displayed next to the surface to identify the agent or tool that created it (e.g. "Weather Bot"). | - -#### Identity and attribution - -The `iconUrl` and `agentDisplayName` fields are used to provide attribution to the user, identifying which sub-agent or tool is responsible for a particular UI surface. - -In multi-agent systems or orchestrators, the orchestrator is responsible for setting or validating these fields. This ensures that the identity displayed to the user matches the actual agent being contacted, preventing malicious agents from impersonating trusted services. For example, an orchestrator might overwrite these fields with the verified identity of the sub-agent before forwarding the `createSurface` message to the renderer. - ### The `formatString` function The `formatString` function supports embedding dynamic expressions directly within string properties. This allows for mixing static text with data model values and function results. diff --git a/specification/v1_0/docs/evolution_guide.md b/specification/v1_0/docs/evolution_guide.md index 231e5b4999..c63b9675dc 100644 --- a/specification/v1_0/docs/evolution_guide.md +++ b/specification/v1_0/docs/evolution_guide.md @@ -12,7 +12,7 @@ Version 1.0 differs from 0.9 in the following ways: - Added an optional `catalogId` property to `ComponentCommon` and `FunctionCall` to allow individual components and function calls to explicitly declare their source catalog. - Retained `catalogId` on `createSurface` as an optional parameter that defines the default catalog for that surface. - Defined explicit component and function call resolution logic: the renderer checks the component-level (or function call-level) `catalogId` first, then falls back to the surface default `catalogId`. If neither is defined, the renderer errors out and does not render the component (or rejects the function call). There is no fallback to catalogs declared in capabilities. Available catalogs for a surface include both `supportedCatalogIds` and any negotiated `inlineCatalogs`, and all mixed catalogs must use the same A2UI specification version. -- The `theme` property in the catalog and surface creation message is replaced by `surfaceProperties`, and `primaryColor` is removed to separate layout from branding. +- The `theme` property in the catalog and surface creation message is removed, along with `primaryColor`, to separate layout from branding. - Components and initial data model states can be defined directly within the `createSurface` parameters. This allows for the creation of entire UIs in a single message, rather than a create followed by separate updates. - The `functions` field in a Catalog is now defined as a map of function name to its definition, instead of a list. - Standard JSON Schema metadata fields (`$schema`, `$id`, `title`, and `description`) are supported in catalogs, preventing validation failures on inline catalogs with strict property checks. @@ -24,7 +24,7 @@ Version 1.0 differs from 0.9 in the following ways: ### 2.1. Catalog definition schema -- Renamed the `$defs/theme` schema to `$defs/surfaceProperties` in the Catalog schema, and removed the `primaryColor` property. +- Removed the `$defs/theme` schema and the `primaryColor` property from the Catalog schema. - Changed the `functions` property in the Catalog schema from a list to a map object, keyed by function name. - Added `callableFrom` (enum: `rendererOnly`, `agentOnly`, `rendererOrAgent`) to `FunctionDefinition` to restrict where a function can be invoked. - Added an optional `instructions` field to the `Catalog` schema to embed design guidelines and component usage rules directly in the catalog, replacing the external `rules.txt` file. @@ -38,13 +38,13 @@ Version 1.0 differs from 0.9 in the following ways: - Added `placeholder` prop to the `TextField` component schema. - Added a `steps` property to the `Slider` component schema to snap values to discrete intervals. - Added an optional `instructions` field to the `Catalog` schema (`catalogs/basic/catalog.json`) to embed Markdown guidelines/rules directly, replacing the external `rules.txt` file. -- Renamed `$defs/theme` to `$defs/surfaceProperties` in the basic catalog. +- Removed `$defs/theme` from the basic catalog. ### 2.3. Agent-to-renderer messages - Added `actionResponse` message structure (`ActionResponseMessage`) to allow the agent to respond to a specific action call using a unique `actionId` with a `value` or `error`. - Added `callFunction` message structure (`CallFunctionMessage`) to support agent-initiated function execution. Removed `callableFrom` and `returnType` properties from the wire payload, relying on runtime catalog verification. -- Updated the `createSurface` message (`CreateSurfaceMessage`) to rename the `theme` field to `surfaceProperties`, allowed passing initial `components` and `dataModel` directly inside the payload, and made `catalogId` an optional parameter that acts as the surface's default catalog. +- Updated the `createSurface` message (`CreateSurfaceMessage`) to remove the `theme` field, allowed passing initial `components` and `dataModel` directly inside the payload, and made `catalogId` an optional parameter that acts as the surface's default catalog. - Added an optional `catalogId` property to `ComponentCommon` and `FunctionCall` in `common_types.json` to enable mixing catalogs and explicitly designating the catalog on individual components or function calls. - Updated all protocol version references and envelopes from `v0.9` or `v0.9.1` to `v1.0`. @@ -58,7 +58,7 @@ Version 1.0 differs from 0.9 in the following ways: ### 2.5. Catalog definition schema - Added an optional `instructions` field to the `Catalog` object definition (`catalog_definition.json`) as a plain Markdown string to embed design guidelines directly. -- Renamed `theme` capability block to `surfaceProperties` within the Catalog definition in `catalog_definition.json`. +- Removed `theme` capability block from the Catalog definition in `catalog_definition.json`. - Added static `callableFrom` and `returnType` metadata properties to `FunctionDefinition` inside `catalog_definition.json` to advertise execution boundaries and return types to the agent. ### 2.6. Agent card and transport metadata @@ -102,10 +102,10 @@ This section outlines the steps required to migrate existing applications and co - Set the `version` field in all streamed JSON envelopes to `"v1.0"`. - Change the MIME type of A2UI payloads in transport layers from `application/json+a2ui` to `application/a2ui+json`. -- Rename the `theme` field in `createSurface` messages to `surfaceProperties` and remove `primaryColor`. You can pass initial `components` and `dataModel` directly in the `createSurface` payload, and `catalogId` is now optional (acting as the default catalog for that surface). +- Remove the `theme` field from `createSurface` messages. You can pass initial `components` and `dataModel` directly in the `createSurface` payload, and `catalogId` is now optional (acting as the default catalog for that surface). - When mixing components from multiple catalogs, specify the optional `catalogId` on individual components or function calls. - Convert the `functions` property in catalog definitions from an array to a JSON object map keyed by function name. -- Rename the `$defs/theme` catalog definition to `$defs/surfaceProperties` and remove the `primaryColor` field. +- Remove the `$defs/theme` catalog definition and the `primaryColor` field. - Ensure all generated catalog entity names conform to UAX #31 identifier rules. - Do not include `callableFrom` or `returnType` properties in wire-level `FunctionCall` payloads. Set static `callableFrom` and `returnType` metadata in catalog function definitions where needed. - Update `Video`, `TextField`, and `Slider` components to support optional `posterUrl`, `placeholder`, and `steps` properties. diff --git a/specification/v1_0/eval/src/types.ts b/specification/v1_0/eval/src/types.ts index 308272e187..05d2a186fb 100644 --- a/specification/v1_0/eval/src/types.ts +++ b/specification/v1_0/eval/src/types.ts @@ -68,7 +68,6 @@ export interface CatalogSchema { instructions?: string; components?: Record; functions?: Record; - surfaceProperties?: Record; [key: string]: unknown; } diff --git a/specification/v1_0/eval/src/validator.ts b/specification/v1_0/eval/src/validator.ts index 630269a512..e747d9de57 100644 --- a/specification/v1_0/eval/src/validator.ts +++ b/specification/v1_0/eval/src/validator.ts @@ -401,14 +401,7 @@ export class Validator { if (data.catalogId === undefined) { errors.push("createSurface must have a 'catalogId' property."); } - const allowed = [ - 'surfaceId', - 'catalogId', - 'surfaceProperties', - 'sendDataModel', - 'components', - 'dataModel', - ]; + const allowed = ['surfaceId', 'catalogId', 'sendDataModel', 'components', 'dataModel']; for (const key in data) { if (!allowed.includes(key)) { errors.push(`createSurface has unexpected property: ${key}`); diff --git a/specification/v1_0/json/agent_to_renderer.json b/specification/v1_0/json/agent_to_renderer.json index 09d867f9db..77300391dc 100644 --- a/specification/v1_0/json/agent_to_renderer.json +++ b/specification/v1_0/json/agent_to_renderer.json @@ -31,10 +31,6 @@ "description": "A string that uniquely identifies the default catalog for this surface. It is recommended to prefix this with an internet domain that you own, to avoid conflicts e.g. 'mycompany.com:somecatalog'. Components and function calls that do not explicitly specify a catalogId will use this surface-level default catalogId.", "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 renderer will send the full data model of this surface in the metadata of every A2A message sent to the agent that created the surface. Defaults to false." diff --git a/specification/v1_0/json/catalog_definition.json b/specification/v1_0/json/catalog_definition.json index 8c4555dd33..03b5ed07f1 100644 --- a/specification/v1_0/json/catalog_definition.json +++ b/specification/v1_0/json/catalog_definition.json @@ -17,11 +17,6 @@ "type": "object", "description": "Standardized schema definitions referenced from outside the catalog file.", "properties": { - "surfaceProperties": { - "title": "A2UI Surface Properties Schema", - "description": "A JSON Schema that defines the catalog's surface properties.", - "$ref": "https://json-schema.org/draft/2020-12/schema" - }, "anyComponent": { "title": "A2UI Any Component Schema", "description": "Unified validation schema for all components.", diff --git a/specification/v1_0/test/cases/surface_properties_validation.json b/specification/v1_0/test/cases/surface_properties_validation.json deleted file mode 100644 index 12f15acb58..0000000000 --- a/specification/v1_0/test/cases/surface_properties_validation.json +++ /dev/null @@ -1,63 +0,0 @@ -{ - "schema": "agent_to_renderer.json", - "tests": [ - { - "description": "Valid surfaceProperties in createSurface", - "valid": true, - "data": { - "version": "v1.0", - "createSurface": { - "surfaceId": "test_surface", - "catalogId": "https://a2ui.org/specification/v1_0/catalogs/basic/catalog.json", - "surfaceProperties": { - "agentDisplayName": "Test Agent", - "iconUrl": "https://example.com/icon.png" - } - } - } - }, - { - "description": "Invalid surfaceProperties property (wrong type for agentDisplayName)", - "valid": false, - "data": { - "version": "v1.0", - "createSurface": { - "surfaceId": "test_surface", - "catalogId": "https://a2ui.org/specification/v1_0/catalogs/basic/catalog.json", - "surfaceProperties": { - "agentDisplayName": 123 - } - } - } - }, - { - "description": "Invalid surfaceProperties property (invalid uri for iconUrl)", - "valid": false, - "data": { - "version": "v1.0", - "createSurface": { - "surfaceId": "test_surface", - "catalogId": "https://a2ui.org/specification/v1_0/catalogs/basic/catalog.json", - "surfaceProperties": { - "iconUrl": "not-a-uri" - } - } - } - }, - { - "description": "Additional surfaceProperties properties are allowed", - "valid": true, - "data": { - "version": "v1.0", - "createSurface": { - "surfaceId": "test_surface", - "catalogId": "https://a2ui.org/specification/v1_0/catalogs/basic/catalog.json", - "surfaceProperties": { - "agentDisplayName": "Test Agent", - "customProperty": "customValue" - } - } - } - } - ] -} diff --git a/specification/v1_0/test/testing_catalog.json b/specification/v1_0/test/testing_catalog.json index f9db83e1d3..33fdd3600d 100644 --- a/specification/v1_0/test/testing_catalog.json +++ b/specification/v1_0/test/testing_catalog.json @@ -78,21 +78,6 @@ } }, "$defs": { - "surfaceProperties": { - "type": "object", - "properties": { - "iconUrl": { - "type": "string", - "format": "uri", - "description": "A URL for an image that identifies the agent or tool associated with the surface." - }, - "agentDisplayName": { - "type": "string", - "description": "Text to be displayed next to the surface to identify the agent or tool that created it." - } - }, - "additionalProperties": true - }, "anyComponent": { "oneOf": [{"$ref": "#/components/Text"}], "discriminator": {