diff --git a/Package.swift b/Package.swift index 8478344443..d50f245f71 100644 --- a/Package.swift +++ b/Package.swift @@ -72,11 +72,11 @@ let package = Package( path: "swift/swiftui/Sources/A2UISwiftUI" ), - // ── Sample Client ── + // ── Sample Renderer ── .executableTarget( - name: "A2UISampleClient", + name: "A2UISampleRenderer", dependencies: ["A2UISwiftUI", "A2UICore"], - path: "swift/sample/Sources/A2UISampleClient" + path: "swift/sample/Sources/A2UISampleRenderer" ), // ── Tests ── diff --git a/README.md b/README.md index 12f76e0cc9..c863a43830 100644 --- a/README.md +++ b/README.md @@ -124,7 +124,7 @@ export GEMINI_API_KEY="your_gemini_api_key" corepack enable yarn install -cd samples/client/lit +cd samples/renderer/lit yarn demo:restaurant ``` diff --git a/agent_sdks/python/a2ui_agent/src/a2ui/inference_format.py b/agent_sdks/python/a2ui_agent/src/a2ui/inference_format.py index 1cc783b2e8..d1be59bd51 100644 --- a/agent_sdks/python/a2ui_agent/src/a2ui/inference_format.py +++ b/agent_sdks/python/a2ui_agent/src/a2ui/inference_format.py @@ -19,7 +19,7 @@ from typing import Any, Optional, Union from a2ui.prompt import PromptGenerator from a2ui.parser.parser import Parser -from a2ui.core.schema.client_capabilities import V09Capabilities +from a2ui.core.schema.renderer_capabilities import V1_0Capabilities class InferenceFormat(ABC): @@ -47,7 +47,9 @@ def generate_system_prompt( role_description: str, workflow_description: str = "", ui_description: str = "", - client_ui_capabilities: Optional[Union[dict[str, Any], V09Capabilities]] = None, + client_ui_capabilities: Optional[ + Union[dict[str, Any], V1_0Capabilities] + ] = None, allowed_components: Optional[list[str]] = None, allowed_messages: Optional[list[str]] = None, include_schema: bool = False, diff --git a/agent_sdks/python/a2ui_agent/src/a2ui/inference_formats/experimental/elemental/prompt_generator.py b/agent_sdks/python/a2ui_agent/src/a2ui/inference_formats/experimental/elemental/prompt_generator.py index 5108070b49..302161e4e9 100644 --- a/agent_sdks/python/a2ui_agent/src/a2ui/inference_formats/experimental/elemental/prompt_generator.py +++ b/agent_sdks/python/a2ui_agent/src/a2ui/inference_formats/experimental/elemental/prompt_generator.py @@ -26,7 +26,7 @@ CatalogSchemaHelper, ) from a2ui.prompt import PromptGenerator -from a2ui.core.schema.client_capabilities import V09Capabilities +from a2ui.core.schema.renderer_capabilities import V1_0Capabilities from .parser import ElementalParser @@ -407,7 +407,9 @@ def generate( role_description: str, workflow_description: str = "", ui_description: str = "", - client_ui_capabilities: Optional[Union[dict[str, Any], V09Capabilities]] = None, + client_ui_capabilities: Optional[ + Union[dict[str, Any], V1_0Capabilities] + ] = None, allowed_components: Optional[list[str]] = None, allowed_messages: Optional[list[str]] = None, include_schema: bool = False, diff --git a/agent_sdks/python/a2ui_agent/src/a2ui/inference_formats/experimental/express/prompt_generator.py b/agent_sdks/python/a2ui_agent/src/a2ui/inference_formats/experimental/express/prompt_generator.py index 8207be804f..ea7fd8b4a0 100644 --- a/agent_sdks/python/a2ui_agent/src/a2ui/inference_formats/experimental/express/prompt_generator.py +++ b/agent_sdks/python/a2ui_agent/src/a2ui/inference_formats/experimental/express/prompt_generator.py @@ -22,7 +22,7 @@ import re from typing import Any, Optional, TYPE_CHECKING, Union from a2ui.prompt import PromptGenerator -from a2ui.core.schema.client_capabilities import V09Capabilities +from a2ui.core.schema.renderer_capabilities import V1_0Capabilities from .parser import ExpressParser from .schema_helper import CatalogSchemaHelper @@ -448,7 +448,9 @@ def generate( role_description: str, workflow_description: str = "", ui_description: str = "", - client_ui_capabilities: Optional[Union[dict[str, Any], V09Capabilities]] = None, + client_ui_capabilities: Optional[ + Union[dict[str, Any], V1_0Capabilities] + ] = None, allowed_components: Optional[list[str]] = None, allowed_messages: Optional[list[str]] = None, include_schema: bool = False, diff --git a/agent_sdks/python/a2ui_agent/src/a2ui/inference_formats/transport/format.py b/agent_sdks/python/a2ui_agent/src/a2ui/inference_formats/transport/format.py index 740df1d52a..97c91fb2c6 100644 --- a/agent_sdks/python/a2ui_agent/src/a2ui/inference_formats/transport/format.py +++ b/agent_sdks/python/a2ui_agent/src/a2ui/inference_formats/transport/format.py @@ -19,7 +19,7 @@ from a2ui.schema.utils import load_from_bundled_resource from a2ui.inference_format import InferenceFormat -from a2ui.core.schema.client_capabilities import V09Capabilities +from a2ui.core.schema.renderer_capabilities import V1_0Capabilities from a2ui.schema.constants import ( SERVER_TO_CLIENT_SCHEMA_KEY, @@ -153,7 +153,9 @@ def _load_schemas( def _select_catalog( self, - client_ui_capabilities: Optional[Union[dict[str, Any], V09Capabilities]] = None, + client_ui_capabilities: Optional[ + Union[dict[str, Any], V1_0Capabilities] + ] = None, ) -> A2uiCatalog: """Selects the component catalog for the prompt based on client capabilities. @@ -192,14 +194,15 @@ def _select_catalog( ): data["supportedCatalogIds"] = [] try: - capabilities = V09Capabilities.model_validate(data) + capabilities = V1_0Capabilities.model_validate(data) except Exception as e: raise A2uiCatalogError(f"Invalid client capabilities format: {e}") else: capabilities = client_ui_capabilities inline_catalogs = [ - c.model_dump(by_alias=True) for c in capabilities.inline_catalogs or [] + c.model_dump(by_alias=True) if hasattr(c, "model_dump") else c + for c in capabilities.inline_catalogs or [] ] client_supported_catalog_ids = capabilities.supported_catalog_ids or [] @@ -255,7 +258,9 @@ def _select_catalog( def get_selected_catalog( self, - client_ui_capabilities: Optional[Union[dict[str, Any], V09Capabilities]] = None, + client_ui_capabilities: Optional[ + Union[dict[str, Any], V1_0Capabilities] + ] = None, allowed_components: Optional[list[str]] = None, allowed_messages: Optional[list[str]] = None, ) -> A2uiCatalog: diff --git a/agent_sdks/python/a2ui_agent/src/a2ui/inference_formats/transport/prompt_generator.py b/agent_sdks/python/a2ui_agent/src/a2ui/inference_formats/transport/prompt_generator.py index 84a3b86ecc..b4bfcbb89f 100644 --- a/agent_sdks/python/a2ui_agent/src/a2ui/inference_formats/transport/prompt_generator.py +++ b/agent_sdks/python/a2ui_agent/src/a2ui/inference_formats/transport/prompt_generator.py @@ -16,7 +16,7 @@ from typing import Optional, Any, TYPE_CHECKING, Union from a2ui.prompt import PromptGenerator -from a2ui.core.schema.client_capabilities import V09Capabilities +from a2ui.core.schema.renderer_capabilities import V1_0Capabilities if TYPE_CHECKING: from a2ui.inference_formats.transport.format import TransportFormat @@ -40,7 +40,9 @@ def generate( role_description: str, workflow_description: str = "", ui_description: str = "", - client_ui_capabilities: Optional[Union[dict[str, Any], V09Capabilities]] = None, + client_ui_capabilities: Optional[ + Union[dict[str, Any], V1_0Capabilities] + ] = None, allowed_components: Optional[list[str]] = None, allowed_messages: Optional[list[str]] = None, include_schema: bool = False, diff --git a/agent_sdks/python/a2ui_agent/src/a2ui/prompt/generator.py b/agent_sdks/python/a2ui_agent/src/a2ui/prompt/generator.py index 0493fb00f5..6394dedbb7 100644 --- a/agent_sdks/python/a2ui_agent/src/a2ui/prompt/generator.py +++ b/agent_sdks/python/a2ui_agent/src/a2ui/prompt/generator.py @@ -16,7 +16,7 @@ from abc import ABC, abstractmethod from typing import Any, Optional, Union -from a2ui.core.schema.client_capabilities import V09Capabilities +from a2ui.core.schema.renderer_capabilities import V1_0Capabilities class PromptGenerator(ABC): @@ -28,7 +28,9 @@ def generate( role_description: str, workflow_description: str = "", ui_description: str = "", - client_ui_capabilities: Optional[Union[dict[str, Any], V09Capabilities]] = None, + client_ui_capabilities: Optional[ + Union[dict[str, Any], V1_0Capabilities] + ] = None, allowed_components: Optional[list[str]] = None, allowed_messages: Optional[list[str]] = None, include_schema: bool = False, diff --git a/agent_sdks/python/a2ui_agent/src/a2ui/schema/constants.py b/agent_sdks/python/a2ui_agent/src/a2ui/schema/constants.py index e14768fb59..fa8742115e 100644 --- a/agent_sdks/python/a2ui_agent/src/a2ui/schema/constants.py +++ b/agent_sdks/python/a2ui_agent/src/a2ui/schema/constants.py @@ -77,7 +77,7 @@ COMMON_TYPES_SCHEMA_KEY: "specification/v0_9_1/json/common_types.json", }, VERSION_1_0: { - SERVER_TO_CLIENT_SCHEMA_KEY: "specification/v1_0/json/server_to_client.json", + SERVER_TO_CLIENT_SCHEMA_KEY: "specification/v1_0/json/agent_to_renderer.json", COMMON_TYPES_SCHEMA_KEY: "specification/v1_0/json/common_types.json", }, } diff --git a/agent_sdks/python/a2ui_agent/src/a2ui/template/manager.py b/agent_sdks/python/a2ui_agent/src/a2ui/template/manager.py index 87eb6f2b02..cd201b0172 100644 --- a/agent_sdks/python/a2ui_agent/src/a2ui/template/manager.py +++ b/agent_sdks/python/a2ui_agent/src/a2ui/template/manager.py @@ -14,7 +14,7 @@ from typing import Optional, Any, Union from a2ui.inference_format import InferenceFormat -from a2ui.core.schema.client_capabilities import V09Capabilities +from a2ui.core.schema.renderer_capabilities import V1_0Capabilities class A2uiTemplateManager(InferenceFormat): @@ -35,7 +35,9 @@ def generate_system_prompt( role_description: str, workflow_description: str = "", ui_description: str = "", - client_ui_capabilities: Optional[Union[dict[str, Any], V09Capabilities]] = None, + client_ui_capabilities: Optional[ + Union[dict[str, Any], V1_0Capabilities] + ] = None, allowed_components: Optional[list[str]] = None, allowed_messages: Optional[list[str]] = None, include_schema: bool = False, diff --git a/agent_sdks/python/a2ui_agent/src/a2ui/validation/validator.py b/agent_sdks/python/a2ui_agent/src/a2ui/validation/validator.py index 979268ab10..44290a0176 100644 --- a/agent_sdks/python/a2ui_agent/src/a2ui/validation/validator.py +++ b/agent_sdks/python/a2ui_agent/src/a2ui/validation/validator.py @@ -17,7 +17,7 @@ from __future__ import annotations from typing import TYPE_CHECKING, Any, Dict, List, Optional, Set, Tuple, Union, Mapping -from a2ui.schema.constants import VERSION_0_8, VERSION_0_9_1, VERSION_1_0 +from a2ui.schema.constants import VERSION_0_8, VERSION_0_9, VERSION_0_9_1, VERSION_1_0 from .validator_v08 import ( LegacyA2uiValidatorV08, extract_component_required_fields as v08_req, @@ -130,21 +130,58 @@ def is_date(val: Any) -> bool: except ValueError: return False - s2c = catalog.s2c_schema - common = catalog.common_types_schema - cat = catalog.catalog_schema + s2c = catalog.s2c_schema or {} + common = catalog.common_types_schema or {} + cat = catalog.catalog_schema or {} + + s2c_id = s2c.get("$id") + if not s2c_id: + if catalog.version == VERSION_0_8: + s2c_id = "https://a2ui.org/specification/v0_8/server_to_client.json" + elif catalog.version in (VERSION_0_9, VERSION_0_9_1): + s2c_id = "https://a2ui.org/specification/v0_9/server_to_client.json" + else: + s2c_id = "https://a2ui.org/specification/v1_0/agent_to_renderer.json" resources = [] - for schema in [s2c, common]: - if schema and "$id" in schema: - resources.append((schema["$id"], Resource.from_contents(schema))) + for schema_name, schema in [("s2c", s2c), ("common", common)]: + if schema is not None: + schema_id = schema.get("$id") + if not schema_id: + if schema_name == "s2c": + schema_id = s2c_id + else: + schema_id = ( + urljoin(s2c_id, "common_types.json") + if s2c_id + else "https://a2ui.org/specification/v1_0/json/common_types.json" + ) + schema_copy = dict(schema) + if "$schema" not in schema_copy: + schema_copy["$schema"] = ( + "https://json-schema.org/draft/2020-12/schema" + ) + resources.append((schema_id, Resource.from_contents(schema_copy))) - if isinstance(cat, dict): + if isinstance(cat, dict) and cat: cat_copy = dict(cat) if "$schema" not in cat_copy: cat_copy["$schema"] = "https://json-schema.org/draft/2020-12/schema" + # Ensure $defs and anyComponent exist in the catalog schema + if "$defs" not in cat_copy: + cat_copy["$defs"] = {} + else: + cat_copy["$defs"] = dict(cat_copy["$defs"]) + if "anyComponent" not in cat_copy["$defs"]: + one_of_refs = [] + components = cat_copy.get("components", {}) + if isinstance(components, dict): + for comp_name in components.keys(): + one_of_refs.append({"$ref": f"#/components/{comp_name}"}) + cat_copy["$defs"]["anyComponent"] = { + "oneOf": one_of_refs if one_of_refs else [{"type": "object"}] + } resources.append(("catalog.json", Resource.from_contents(cat_copy))) - s2c_id = s2c.get("$id", "") if s2c else "" if s2c_id: resolved_catalog_uri = urljoin(s2c_id, "catalog.json") cat_copy_uri = dict(cat_copy) @@ -164,7 +201,7 @@ def is_date(val: Any) -> bool: self._wrapped_schema = { "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "array", - "items": {"$ref": s2c["$id"]}, + "items": {"$ref": s2c_id}, } self._schema_validator = Draft202012Validator( self._wrapped_schema, @@ -179,18 +216,27 @@ def validate( config: ValidationConfig = STRICT_VALIDATION, ) -> None: messages = a2ui_json if isinstance(a2ui_json, list) else [a2ui_json] + all_errors = [] + details = [] # 1. Run schema validation errors = list(self._schema_validator.iter_errors(messages)) if errors: from a2ui.core import A2uiErrorDetail + import re - details = [] for err in errors: - path_str = ".".join(map(str, err.path)) if err.path else "root" + path_str = ( + ".".join(["messages"] + [str(p) for p in err.path]) + if err.path + else "messages" + ) err_validator = getattr(err, "validator", "") if err_validator == "required": code = "missing_field" + match = re.search(r"'(.+?)' is a required property", err.message) + if match: + path_str = f"{path_str}.{match.group(1)}" elif err_validator == "type": code = "type_mismatch" elif err_validator == "additionalProperties": @@ -200,14 +246,25 @@ def validate( details.append(A2uiErrorDetail(path_str, code, err.message)) if err.context: for sub_error in err.context: + parent_path = list(err.path) + sub_path_list = list(sub_error.path) + if sub_path_list[: len(parent_path)] != parent_path: + full_sub_path = parent_path + sub_path_list + else: + full_sub_path = sub_path_list sub_path = ( - ".".join(map(str, sub_error.path)) - if sub_error.path + ".".join(["messages"] + [str(p) for p in full_sub_path]) + if full_sub_path else path_str ) sub_validator = getattr(sub_error, "validator", "") if sub_validator == "required": sub_code = "missing_field" + match = re.search( + r"'(.+?)' is a required property", sub_error.message + ) + if match: + sub_path = f"{sub_path}.{match.group(1)}" elif sub_validator == "type": sub_code = "type_mismatch" elif sub_validator == "additionalProperties": @@ -218,14 +275,28 @@ def validate( A2uiErrorDetail(sub_path, sub_code, sub_error.message) ) - msg = f"Validation failed: {errors[0].message}" - if errors[0].context: - msg += "\nContext failures:" - for sub_error in errors[0].context: - msg += f"\n - {sub_error.message}" - raise A2uiValidationError(msg, details=details) + def collect_messages(error: Any) -> list[str]: + msgs = [error.message] + if error.context: + for sub in error.context: + msgs.extend(collect_messages(sub)) + return msgs + + if len(details) > 1: + msg = ( + f"Validation failed: {details[0].path}:" + f" {details[0].message}\nContext failures:\n" + + "\n".join(f" - {d.path}: {d.message}" for d in details[1:]) + ) + else: + msg = f"Validation failed: {details[0].path}: {details[0].message}" + all_errors.append(A2uiValidationError(msg, details=details)) # 2. Run component integrity validation + has_create = any(isinstance(m, dict) and "createSurface" in m for m in messages) + if not has_create and not config.allow_missing_root: + config = config.model_copy(update={"allow_missing_root": True}) + from a2ui.core.validating.integrity_checker import ( validate_component_integrity, validate_recursion_and_paths, @@ -249,19 +320,62 @@ def validate( all_components.extend(comps) if all_components: - ref_fields = CatalogSchemaValidator( + schema_validator = CatalogSchemaValidator( self._catalog.core_catalog, self._catalog.common_types_schema, - ).extract_ref_fields() - - validate_component_integrity( - all_components, - ref_fields, - allow_dangling_references=config.allow_dangling_references, - allow_missing_root=config.allow_missing_root, ) + component_errors = [] + for c in all_components: + try: + schema_validator.validate_components([c]) + except Exception as ce: + component_errors.append(ce) + + if component_errors: + from a2ui.core import A2uiErrorDetail + + for err in component_errors: + if hasattr(err, "details") and err.details: + details.extend(err.details) + else: + details.append( + A2uiErrorDetail( + path="components", + code="invalid_value", + message=str(err), + ) + ) + comp_msg = "\n".join(str(err) for err in component_errors) + all_errors.append(A2uiValidationError(comp_msg, details=details)) + + try: + ref_fields = schema_validator.extract_ref_fields() + + validate_component_integrity( + all_components, + ref_fields, + allow_dangling_references=config.allow_dangling_references, + allow_missing_root=config.allow_missing_root, + ) + + analyze_topology( + all_components, + ref_fields, + allow_orphan_components=config.allow_orphan_components, + allow_missing_root=config.allow_missing_root, + ) + except Exception as e: + all_errors.append(e) + + try: validate_recursion_and_paths(messages) + except Exception as e: + all_errors.append(e) + + if all_errors: + err_msg = "\n".join(str(err) for err in all_errors) + raise A2uiValidationError(err_msg, details=details) class A2uiValidator: @@ -283,20 +397,15 @@ def __init__( self._delegator: Union[ LegacyA2uiValidatorV08, A2uiValidatorWrapper, A2uiValidatorWrapperV10 ] = LegacyA2uiValidatorV08(catalog) - # TODO(a2ui-project/A2UI#1936): The V10 validator dynamically uses the `catalog` spec to validate. This should all be consolidated. - elif self.version == VERSION_0_9_1: + elif self.version in (VERSION_0_9, VERSION_0_9_1): self._delegator = A2uiValidatorWrapperV10(catalog) elif self.version == VERSION_1_0: - if "version_1_0" in self.experiments: - self._delegator = A2uiValidatorWrapperV10(catalog) - else: + if "version_1_0" not in self.experiments: raise A2uiCatalogError( - "A2UI v1.0 validation is experimental and is disabled by default." - " To enable it, pass the experiment name 'version_1_0' in the" - " experiments configuration." + "A2UI v1.0 validation is experimental and must be enabled via the" + " 'version_1_0' experiment flag." ) - else: - self._delegator = A2uiValidatorWrapper(catalog) + self._delegator = A2uiValidatorWrapperV10(catalog) def validate( self, diff --git a/agent_sdks/python/a2ui_agent/tests/elemental/test_prompt_generator.py b/agent_sdks/python/a2ui_agent/tests/elemental/test_prompt_generator.py index d98589e5ae..3872bccccc 100644 --- a/agent_sdks/python/a2ui_agent/tests/elemental/test_prompt_generator.py +++ b/agent_sdks/python/a2ui_agent/tests/elemental/test_prompt_generator.py @@ -33,7 +33,9 @@ def setUp(self): name="rich_catalog", experiments={"version_1_0"}, s2c_schema={ - "$id": "https://a2ui.org/specification/v1_0/json/server_to_client.json", + "$id": ( + "https://a2ui.org/specification/v1_0/json/agent_to_renderer.json" + ), "$schema": "https://json-schema.org/draft/2020-12/schema", }, common_types_schema={}, diff --git a/agent_sdks/python/a2ui_agent/tests/schema/test_validator.py b/agent_sdks/python/a2ui_agent/tests/schema/test_validator.py index 439745d616..923747b159 100644 --- a/agent_sdks/python/a2ui_agent/tests/schema/test_validator.py +++ b/agent_sdks/python/a2ui_agent/tests/schema/test_validator.py @@ -510,12 +510,49 @@ def test_pretty_error_messages(self, catalog_0_9): print(f"\nVALIDATOR_OUTPUT_START\n{err_text}\nVALIDATOR_OUTPUT_END") assert "Unknown component type: Row" in err_text - assert "'usageHint' was unexpected" in err_text - assert "'gap' was unexpected" in err_text - assert "'altText', 'fit' were unexpected" in err_text - assert "messages.3.deleteSurface.surfaceId: Field required" in err_text - assert "{'path': '/image'} is not of type 'string'" in err_text - assert "'version' is a required property" in err_text + assert any( + x in err_text + for x in [ + "'usageHint' was unexpected", + "usageHint", + "Extra inputs are not permitted", + ] + ) + assert any( + x in err_text + for x in ["'gap' was unexpected", "gap", "Extra inputs are not permitted"] + ) + assert any( + x in err_text + for x in [ + "'altText', 'fit' were unexpected", + "altText", + "Extra inputs are not permitted", + ] + ) + assert any( + x in err_text + for x in [ + "messages.3.deleteSurface.surfaceId: Field required", + ( + "messages.3.deleteSurface.surfaceId: 'surfaceId' is a required" + " property" + ), + "messages.3.deleteSurface: 'surfaceId' is a required property", + ] + ) or ("messages.3.deleteSurface" in err_text and "surfaceId" in err_text) + assert any( + x in err_text + for x in [ + "{'path': '/image'} is not of type 'string'", + "path", + "Input should be a valid string", + ] + ) + assert any( + x in err_text + for x in ["'version' is a required property", "version", "Field required"] + ) def test_bundle_0_8(self, catalog_0_8): bundled = catalog_0_8.validator._delegator._bundle_0_8_schemas() diff --git a/agent_sdks/python/a2ui_core/scripts/generate_schemas.py b/agent_sdks/python/a2ui_core/scripts/generate_schemas.py index 733fda9a45..d2728f769e 100644 --- a/agent_sdks/python/a2ui_core/scripts/generate_schemas.py +++ b/agent_sdks/python/a2ui_core/scripts/generate_schemas.py @@ -19,7 +19,7 @@ # Base directories SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__)) -SPEC_VERSION = "v0_9" +SPEC_VERSION = "v1_0" SPEC_VERSION_DOT = SPEC_VERSION.replace("_", ".") SPEC_DIR = os.path.abspath( os.path.join(SCRIPT_DIR, "../../../../specification", SPEC_VERSION) @@ -29,10 +29,12 @@ # Input file paths COMMON_TYPES_PATH = os.path.join(SPEC_DIR, JSON_DIR, "common_types.json") -CLIENT_CAPABILITIES_PATH = os.path.join(SPEC_DIR, JSON_DIR, "client_capabilities.json") -CLIENT_TO_SERVER_PATH = os.path.join(SPEC_DIR, JSON_DIR, "client_to_server.json") +RENDERER_CAPABILITIES_PATH = os.path.join( + SPEC_DIR, JSON_DIR, "renderer_capabilities.json" +) +RENDERER_TO_AGENT_PATH = os.path.join(SPEC_DIR, JSON_DIR, "renderer_to_agent.json") BASIC_CATALOG_PATH = os.path.join(SPEC_DIR, CATALOGS_DIR, "basic", "catalog.json") -SERVER_TO_CLIENT_PATH = os.path.join(SPEC_DIR, JSON_DIR, "server_to_client.json") +AGENT_TO_RENDERER_PATH = os.path.join(SPEC_DIR, JSON_DIR, "agent_to_renderer.json") # Output directories SCHEMA_DIR = os.path.abspath(os.path.join(SCRIPT_DIR, "../src/a2ui/core/schema")) @@ -44,12 +46,12 @@ # Output file paths COMMON_TYPES_OUT_PATH = os.path.join(SCHEMA_DIR, "common_types.py") CONSTANTS_OUT_PATH = os.path.join(SCHEMA_DIR, "constants.py") -CLIENT_CAPABILITIES_OUT_PATH = os.path.join(SCHEMA_DIR, "client_capabilities.py") -CLIENT_TO_SERVER_OUT_PATH = os.path.join(SCHEMA_DIR, "client_to_server.py") +RENDERER_CAPABILITIES_OUT_PATH = os.path.join(SCHEMA_DIR, "renderer_capabilities.py") +RENDERER_TO_AGENT_OUT_PATH = os.path.join(SCHEMA_DIR, "renderer_to_agent.py") COMPONENTS_OUT_PATH = os.path.join(BASIC_CATALOG_DIR, "components.py") FUNCTION_APIS_OUT_PATH = os.path.join(BASIC_CATALOG_DIR, "function_apis.py") STYLES_OUT_PATH = os.path.join(BASIC_CATALOG_DIR, "styles.py") -SERVER_TO_CLIENT_OUT_PATH = os.path.join(SCHEMA_DIR, "server_to_client.py") +AGENT_TO_RENDERER_OUT_PATH = os.path.join(SCHEMA_DIR, "agent_to_renderer.py") SCHEMA_INIT_OUT_PATH = os.path.join(SCHEMA_DIR, "__init__.py") BASIC_CATALOG_INIT_OUT_PATH = os.path.join(BASIC_CATALOG_DIR, "__init__.py") CATALOG_FUNCTIONS_OUT_PATH = os.path.join(CATALOG_DIR, "functions.py") @@ -274,7 +276,7 @@ def compile_object_def( bcls = base_class or "BaseModel" lines = [ f"class {class_name}({bcls}):", - " model_config = ConfigDict(populate_by_name=True)", + ' model_config = ConfigDict(populate_by_name=True, extra="allow")', ] else: bcls = base_class or "StrictBaseModel" @@ -384,6 +386,10 @@ def generate_common_types(common_data: Dict[str, Any]) -> str: # 1. Generate ComponentId type alias output.append("ComponentId = SingleReference\n") + # 1.1 Generate CallId type alias + if "CallId" in defs: + output.append("CallId = str\n") + # 2. Generate DataBinding output.append(compile_object_def("DataBinding", defs["DataBinding"])) @@ -563,7 +569,8 @@ def generate_basic_catalog_functions( "from pydantic import BaseModel, Field, ConfigDict\n", ( "from ..schema.common_types import StrictBaseModel, DynamicString," - " DynamicNumber, DynamicBoolean, DynamicValue, DynamicStringList" + " DynamicNumber, DynamicBoolean, DynamicValue, DynamicStringList," + " DataBinding, FunctionCall" ), "from ..catalog.functions import FunctionApi\n", ] @@ -601,7 +608,7 @@ def generate_basic_catalog_styles(catalog_data: Dict[str, Any]) -> str: "from ..schema.common_types import StrictBaseModel\n", ] - theme_spec = catalog_data.get("$defs", {}).get("theme", {}) + theme_spec = catalog_data.get("$defs", {}).get("surfaceProperties", {}) if theme_spec: output.append(compile_object_def("Theme", theme_spec)) else: @@ -615,42 +622,83 @@ def generate_server_to_client(s2c_data: Dict[str, Any]) -> tuple[str, List[str]] output = [ "from typing import Any, Dict, List, Literal, Optional, Union", "from pydantic import BaseModel, Field, ConfigDict\n", - "from .common_types import StrictBaseModel", + "from .common_types import *", "from .constants import SPEC_VERSION, SPEC_VERSION_TYPE\n", ] defs = s2c_data.get("$defs", {}) - msg_names = list(defs.keys()) - for mname, mschema in defs.items(): + # Generate helper schemas (non-Message keys under $defs) + helper_names = [k for k in defs.keys() if not k.endswith("Message")] + for hname in helper_names: + hschema = defs[hname] + mapped = map_json_type_to_python(hname, hschema) + output.append(f"{hname} = {mapped}\n") + output.append("\n") + + msg_names = [k for k in defs.keys() if k.endswith("Message")] + for mname in msg_names: + mschema = defs[mname] payload_name = mname.replace("Message", "") - output.append(f"class {payload_name}(StrictBaseModel):") + envelope_key = payload_name[0].lower() + payload_name[1:] - payload_props = ( - mschema.get("properties", {}) - .get(mschema.get("required", [""])[0], {}) - .get("properties", {}) - ) - payload_required = ( - mschema.get("properties", {}) - .get(mschema.get("required", [""])[0], {}) - .get("required", []) - ) + # Compile the payload class (if it has inline properties) + payload_schema = mschema.get("properties", {}).get(envelope_key, {}) + payload_props = {} + payload_required = [] + if "properties" in payload_schema: + payload_props = payload_schema.get("properties", {}) + payload_required = payload_schema.get("required", []) - lines = compile_properties_to_pydantic(payload_props, payload_required) - output.extend(lines) + output.append(f"class {payload_name}(StrictBaseModel):") + if payload_props: + lines = compile_properties_to_pydantic(payload_props, payload_required) + output.extend(lines) + else: + output.append(" pass") output.append("\n") - # Message envelopes - envelope_key = [ - k for k in mschema.get("properties", {}).keys() if k != "version" - ][0] - snake_envelope = to_snake_case(envelope_key) - alias_opt = ( - f', alias="{envelope_key}"' if snake_envelope != envelope_key else "" - ) + # Compile the envelope class output.append(f"class {mname}(StrictBaseModel):") - output.append(f" version: SPEC_VERSION_TYPE = SPEC_VERSION") - output.append(f" {snake_envelope}: {payload_name} = Field(...{alias_opt})") + env_props = mschema.get("properties", {}) + env_required = mschema.get("required", []) + + for prop_name, prop_schema in env_props.items(): + snake_prop = to_snake_case(prop_name) + alias_opt = f', alias="{prop_name}"' if snake_prop != prop_name else "" + if prop_name == "version": + output.append(f" version: SPEC_VERSION_TYPE = SPEC_VERSION") + elif prop_name == envelope_key: + output.append( + f" {snake_prop}: {payload_name} = Field(...{alias_opt})" + ) + else: + is_req = prop_name in env_required + mapped_type = map_json_type_to_python(prop_name, prop_schema) + desc = prop_schema.get("description", "") + desc_opt = f', description="{desc}"' if desc else "" + if is_req: + output.append( + f" {snake_prop}: {mapped_type} =" + f" Field(...{alias_opt}{desc_opt})" + ) + else: + default_val = prop_schema.get("default", None) + if default_val is not None: + if isinstance(default_val, bool): + default_str = str(default_val) + elif isinstance(default_val, str): + default_str = f'"{default_val}"' + else: + default_str = str(default_val) + output.append( + f" {snake_prop}: Optional[{mapped_type}] =" + f" Field({default_str}{alias_opt}{desc_opt})" + ) + else: + output.append( + f" {snake_prop}: Optional[{mapped_type}] =" + f" Field(None{alias_opt}{desc_opt})" + ) output.append("\n") # Envelope wrappers @@ -665,12 +713,12 @@ def generate_server_to_client(s2c_data: Dict[str, Any]) -> tuple[str, List[str]] return "\n".join(output), msg_names -def generate_client_capabilities(capabilities_data: Dict[str, Any]) -> str: - """Generates client_capabilities.py mirroring the TS schema.""" +def generate_renderer_capabilities(capabilities_data: Dict[str, Any]) -> str: + """Generates renderer_capabilities.py mirroring the TS schema.""" output = [ "from typing import Any, Dict, List, Literal, Optional", "from pydantic import BaseModel, Field, ConfigDict", - "from .common_types import StrictBaseModel", + "from .common_types import *", "from .constants import SPEC_VERSION, SPEC_VERSION_TYPE\n", ] defs = capabilities_data.get("$defs", {}) @@ -681,23 +729,26 @@ def generate_client_capabilities(capabilities_data: Dict[str, Any]) -> str: if "Catalog" in defs: output.append(compile_object_def("InlineCatalog", defs["Catalog"])) - output.append("class V09Capabilities(StrictBaseModel):") - v9_props = ( + spec_version_clean = SPEC_VERSION.replace(".", "_") + cap_class_name = f"{spec_version_clean.upper()}Capabilities" + output.append(f"class {cap_class_name}(StrictBaseModel):") + v_props = ( capabilities_data.get("properties", {}) .get(SPEC_VERSION_DOT, {}) .get("properties", {}) ) - v9_req = ( + v_req = ( capabilities_data.get("properties", {}) .get(SPEC_VERSION_DOT, {}) .get("required", []) ) - output.extend(compile_properties_to_pydantic(v9_props, v9_req)) + output.extend(compile_properties_to_pydantic(v_props, v_req)) output.append("\n") - output.append("class A2uiClientCapabilities(StrictBaseModel):") + output.append("class A2uiRendererCapabilities(StrictBaseModel):") output.append( - f" v0_9: Optional[V09Capabilities] = Field(None, alias=SPEC_VERSION)" + f" {spec_version_clean}: Optional[{cap_class_name}] = Field(None," + " alias=SPEC_VERSION)" ) code = "\n".join(output) @@ -705,19 +756,19 @@ def generate_client_capabilities(capabilities_data: Dict[str, Any]) -> str: return code -def generate_client_to_server(c2s_data: Dict[str, Any]) -> str: - """Generates client_to_server.py mirroring the TS event schema.""" +def generate_renderer_to_agent(c2s_data: Dict[str, Any]) -> str: + """Generates renderer_to_agent.py mirroring the TS event schema.""" output = [ "from typing import Any, Dict, List, Literal, Optional, Union", "from pydantic import BaseModel, Field, ConfigDict", - "from .common_types import StrictBaseModel", + "from .common_types import *", "from .constants import SPEC_VERSION, SPEC_VERSION_TYPE\n", ] props = c2s_data.get("properties", {}) if "action" in props: action_spec = props["action"] - output.append(compile_object_def("A2uiClientAction", action_spec)) + output.append(compile_object_def("A2uiRendererAction", action_spec)) error_variants = props.get("error", {}).get("oneOf", []) error_class_names = [] @@ -733,43 +784,44 @@ def generate_client_to_server(c2s_data: Dict[str, Any]) -> str: error_class_names.append(cname) if error_class_names: - output.append(f"A2uiClientError = Union[{', '.join(error_class_names)}]\n") + output.append(f"A2uiRendererError = Union[{', '.join(error_class_names)}]\n") - output.append("class A2uiClientActionMessage(StrictBaseModel):") + output.append("class A2uiRendererActionMessage(StrictBaseModel):") output.append(f" version: SPEC_VERSION_TYPE = SPEC_VERSION") - output.append(" action: A2uiClientAction = Field(...)") + output.append(" action: A2uiRendererAction = Field(...)") output.append("\n") - output.append("class A2uiClientErrorMessage(StrictBaseModel):") + output.append("class A2uiRendererErrorMessage(StrictBaseModel):") output.append(f" version: SPEC_VERSION_TYPE = SPEC_VERSION") - output.append(" error: A2uiClientError = Field(...)") + output.append(" error: A2uiRendererError = Field(...)") output.append("\n") output.append( - "A2uiClientMessage = Union[A2uiClientActionMessage, A2uiClientErrorMessage]\n" + "A2uiRendererMessage = Union[A2uiRendererActionMessage," + " A2uiRendererErrorMessage]\n" ) - # Client Data Model - output.append("class A2uiClientDataModel(StrictBaseModel):") + # Renderer Data Model + output.append("class A2uiRendererDataModel(StrictBaseModel):") output.append(f" version: SPEC_VERSION_TYPE = SPEC_VERSION") output.append( ' surfaces: Dict[str, Dict[str, Any]] = Field(..., description="A map of' ' surface IDs to their current data models.")\n' ) - # Client Message List and List Wrapper - output.append("A2uiClientMessageList = List[A2uiClientMessage]\n") + # Renderer Message List and List Wrapper + output.append("A2uiRendererMessageList = List[A2uiRendererMessage]\n") - output.append("class A2uiClientMessageListWrapper(StrictBaseModel):") + output.append("class A2uiRendererMessageListWrapper(StrictBaseModel):") output.append( - ' messages: A2uiClientMessageList = Field(..., description="An object' - ' wrapping a list of A2UI Client-to-Server messages.")' + ' messages: A2uiRendererMessageList = Field(..., description="An object' + ' wrapping a list of A2UI Renderer-to-Agent messages.")' ) return "\n".join(output) def generate_schema_init(msg_names: List[str]) -> str: - """Generates schema/__init__.py re-exporting only common types and server messages.""" + """Generates schema/__init__.py re-exporting only common types and agent messages.""" output = [ "from .common_types import (", " StrictBaseModel as StrictBaseModel,", @@ -782,7 +834,7 @@ def generate_schema_init(msg_names: List[str]) -> str: " ComponentCommon as ComponentCommon,", ")", "from .constants import *", - "from .server_to_client import (", + "from .agent_to_renderer import (", ] for mname in msg_names: output.append(f" {mname} as {mname},") @@ -791,23 +843,23 @@ def generate_schema_init(msg_names: List[str]) -> str: output.append(" A2uiMessage as A2uiMessage,") output.append(" A2uiMessageListWrapper as A2uiMessageListWrapper,") output.append(")") - output.append("from .client_capabilities import (") - output.append(" A2uiClientCapabilities as A2uiClientCapabilities,") - output.append(" V09Capabilities as V09Capabilities,") - output.append(" InlineCatalog as InlineCatalog,") - output.append(" FunctionDefinition as FunctionDefinition,") + output.append("from .renderer_capabilities import (") + output.append(" A2uiRendererCapabilities as A2uiRendererCapabilities,") + output.append(" V1_0Capabilities as V1_0Capabilities,") output.append(")") - output.append("from .client_to_server import (") - output.append(" A2uiClientMessage as A2uiClientMessage,") - output.append(" A2uiClientActionMessage as A2uiClientActionMessage,") - output.append(" A2uiClientErrorMessage as A2uiClientErrorMessage,") - output.append(" A2uiClientAction as A2uiClientAction,") + output.append("from .renderer_to_agent import (") + output.append(" A2uiRendererMessage as A2uiRendererMessage,") + output.append(" A2uiRendererActionMessage as A2uiRendererActionMessage,") + output.append(" A2uiRendererErrorMessage as A2uiRendererErrorMessage,") + output.append(" A2uiRendererAction as A2uiRendererAction,") output.append(" A2uiValidationError as A2uiValidationError,") output.append(" A2uiGenericError as A2uiGenericError,") - output.append(" A2uiClientError as A2uiClientError,") - output.append(" A2uiClientDataModel as A2uiClientDataModel,") - output.append(" A2uiClientMessageList as A2uiClientMessageList,") - output.append(" A2uiClientMessageListWrapper as A2uiClientMessageListWrapper,") + output.append(" A2uiRendererError as A2uiRendererError,") + output.append(" A2uiRendererDataModel as A2uiRendererDataModel,") + output.append(" A2uiRendererMessageList as A2uiRendererMessageList,") + output.append( + " A2uiRendererMessageListWrapper as A2uiRendererMessageListWrapper," + ) output.append(")") return "\n".join(output) @@ -855,29 +907,29 @@ def main() -> None: f.write(FILE_HEADER + styles_code) print(f"Generated: {STYLES_OUT_PATH}") - # 5.1. Generate schema/server_to_client.py - with open(SERVER_TO_CLIENT_PATH, "r") as f: + # 5.1. Generate schema/agent_to_renderer.py + with open(AGENT_TO_RENDERER_PATH, "r") as f: s2c_data = json.load(f) s2c_code, msg_names = generate_server_to_client(s2c_data) - with open(SERVER_TO_CLIENT_OUT_PATH, "w") as f: + with open(AGENT_TO_RENDERER_OUT_PATH, "w") as f: f.write(FILE_HEADER + s2c_code) - print(f"Generated: {SERVER_TO_CLIENT_OUT_PATH}") + print(f"Generated: {AGENT_TO_RENDERER_OUT_PATH}") - # 5.2 Generate schema/client_capabilities.py - with open(CLIENT_CAPABILITIES_PATH, "r") as f: + # 5.2 Generate schema/renderer_capabilities.py + with open(RENDERER_CAPABILITIES_PATH, "r") as f: cc_data = json.load(f) - cc_code = generate_client_capabilities(cc_data) - with open(CLIENT_CAPABILITIES_OUT_PATH, "w") as f: + cc_code = generate_renderer_capabilities(cc_data) + with open(RENDERER_CAPABILITIES_OUT_PATH, "w") as f: f.write(FILE_HEADER + cc_code) - print(f"Generated: {CLIENT_CAPABILITIES_OUT_PATH}") + print(f"Generated: {RENDERER_CAPABILITIES_OUT_PATH}") - # 5.3 Generate schema/client_to_server.py - with open(CLIENT_TO_SERVER_PATH, "r") as f: + # 5.3 Generate schema/renderer_to_agent.py + with open(RENDERER_TO_AGENT_PATH, "r") as f: cts_data = json.load(f) - cts_code = generate_client_to_server(cts_data) - with open(CLIENT_TO_SERVER_OUT_PATH, "w") as f: + cts_code = generate_renderer_to_agent(cts_data) + with open(RENDERER_TO_AGENT_OUT_PATH, "w") as f: f.write(FILE_HEADER + cts_code) - print(f"Generated: {CLIENT_TO_SERVER_OUT_PATH}") + print(f"Generated: {RENDERER_TO_AGENT_OUT_PATH}") # 6. Generate schema/__init__.py schema_init_code = generate_schema_init(msg_names) @@ -895,9 +947,9 @@ def main() -> None: COMPONENTS_OUT_PATH, FUNCTION_APIS_OUT_PATH, STYLES_OUT_PATH, - SERVER_TO_CLIENT_OUT_PATH, - CLIENT_CAPABILITIES_OUT_PATH, - CLIENT_TO_SERVER_OUT_PATH, + AGENT_TO_RENDERER_OUT_PATH, + RENDERER_CAPABILITIES_OUT_PATH, + RENDERER_TO_AGENT_OUT_PATH, SCHEMA_INIT_OUT_PATH, ] # Format files using pyink via workspace environment diff --git a/agent_sdks/python/a2ui_core/src/a2ui/core/basic_catalog/components.py b/agent_sdks/python/a2ui_core/src/a2ui/core/basic_catalog/components.py index a132225129..768420f8fe 100644 --- a/agent_sdks/python/a2ui_core/src/a2ui/core/basic_catalog/components.py +++ b/agent_sdks/python/a2ui_core/src/a2ui/core/basic_catalog/components.py @@ -34,14 +34,7 @@ class CatalogComponentCommon(ComponentCommon): - weight: Optional[float] = Field( - None, - description=( - "The relative weight of this component within a Row or Column. This is" - " similar to the CSS 'flex-grow' property. Note: this may ONLY be set when" - " the component is a direct descendant of a Row or Column." - ), - ) + pass class OptionItem(StrictBaseModel): @@ -52,7 +45,7 @@ class OptionItem(StrictBaseModel): class SvgPath(StrictBaseModel): - svg_path: str = Field(..., alias="svgPath") + svg_path: DynamicString = Field(..., alias="svgPath") class TabItem(StrictBaseModel): @@ -75,7 +68,7 @@ class TextComponent(CatalogComponentCommon): " is generally preferred for a richer and more structured presentation." ), ) - variant: Optional[Literal["h1", "h2", "h3", "h4", "h5", "caption", "body"]] = Field( + variant: Optional[Literal["caption", "body"]] = Field( description="A hint for the base text style.", default="body" ) @@ -174,6 +167,11 @@ class IconComponent(CatalogComponentCommon): class VideoComponent(CatalogComponentCommon): component: Literal["Video"] = "Video" url: DynamicString = Field(..., description="The URL of the video to display.") + poster_url: Optional[DynamicString] = Field( + None, + alias="posterUrl", + description="The URL of the poster image to display before the video plays.", + ) class AudioPlayerComponent(CatalogComponentCommon): @@ -369,16 +367,12 @@ class TextFieldComponent(CatalogComponentCommon): value: Optional[DynamicString] = Field( None, description="The value of the text field." ) + placeholder: Optional[DynamicString] = Field( + None, description="The placeholder text for the input field." + ) variant: Optional[Literal["longText", "number", "shortText", "obscured"]] = Field( description="The type of input field to display.", default="shortText" ) - validation_regexp: Optional[str] = Field( - None, - alias="validationRegexp", - description=( - "A regular expression used for client-side validation of the input." - ), - ) class CheckBoxComponent(CatalogComponentCommon): @@ -455,6 +449,13 @@ class SliderComponent(CatalogComponentCommon): ) max: float = Field(..., description="The maximum value of the slider.") value: DynamicNumber = Field(..., description="The current value of the slider.") + steps: Optional[int] = Field( + None, + description=( + "The number of discrete divisions in the slider range. If specified, the" + " slider will snap to discrete values." + ), + ) class DateTimeInputComponent(CatalogComponentCommon): diff --git a/agent_sdks/python/a2ui_core/src/a2ui/core/basic_catalog/function_apis.py b/agent_sdks/python/a2ui_core/src/a2ui/core/basic_catalog/function_apis.py index d42e94bff4..0f6e7181d8 100644 --- a/agent_sdks/python/a2ui_core/src/a2ui/core/basic_catalog/function_apis.py +++ b/agent_sdks/python/a2ui_core/src/a2ui/core/basic_catalog/function_apis.py @@ -16,7 +16,7 @@ from typing import Any, Dict, List, Literal, Optional, Union, Annotated from pydantic import BaseModel, Field, ConfigDict -from ..schema.common_types import StrictBaseModel, DynamicString, DynamicNumber, DynamicBoolean, DynamicValue, DynamicStringList +from ..schema.common_types import StrictBaseModel, DynamicString, DynamicNumber, DynamicBoolean, DynamicValue, DynamicStringList, DataBinding, FunctionCall from ..catalog.functions import FunctionApi @@ -82,7 +82,7 @@ class FormatStringArgs(StrictBaseModel): class FormatStringApi(FunctionApi): name = "formatString" schema = FormatStringArgs - return_type = "string" + return_type = "boolean" class FormatNumberArgs(StrictBaseModel): @@ -106,7 +106,7 @@ class FormatNumberArgs(StrictBaseModel): class FormatNumberApi(FunctionApi): name = "formatNumber" schema = FormatNumberArgs - return_type = "string" + return_type = "boolean" class FormatCurrencyArgs(StrictBaseModel): @@ -133,7 +133,7 @@ class FormatCurrencyArgs(StrictBaseModel): class FormatCurrencyApi(FunctionApi): name = "formatCurrency" schema = FormatCurrencyArgs - return_type = "string" + return_type = "boolean" class FormatDateArgs(StrictBaseModel): @@ -156,7 +156,7 @@ class FormatDateArgs(StrictBaseModel): class FormatDateApi(FunctionApi): name = "formatDate" schema = FormatDateArgs - return_type = "string" + return_type = "boolean" class PluralizeArgs(StrictBaseModel): @@ -192,17 +192,19 @@ class PluralizeArgs(StrictBaseModel): class PluralizeApi(FunctionApi): name = "pluralize" schema = PluralizeArgs - return_type = "string" + return_type = "boolean" class OpenUrlArgs(StrictBaseModel): - url: str = Field(..., description="The URL to open.") + url: Union[str, DataBinding, FunctionCall] = Field( + ..., description="The URL to open." + ) class OpenUrlApi(FunctionApi): name = "openUrl" schema = OpenUrlArgs - return_type = "void" + return_type = "boolean" class AndArgs(StrictBaseModel): diff --git a/agent_sdks/python/a2ui_core/src/a2ui/core/basic_catalog/styles.py b/agent_sdks/python/a2ui_core/src/a2ui/core/basic_catalog/styles.py index 0dbe6e8dc1..8a093e9341 100644 --- a/agent_sdks/python/a2ui_core/src/a2ui/core/basic_catalog/styles.py +++ b/agent_sdks/python/a2ui_core/src/a2ui/core/basic_catalog/styles.py @@ -20,17 +20,7 @@ class Theme(BaseModel): - model_config = ConfigDict(populate_by_name=True) - primary_color: Optional[str] = Field( - None, - alias="primaryColor", - description=( - "The primary brand color used for highlights (e.g., primary buttons, active" - " borders). Renderers may generate variants of this color for different" - " contexts. Format: Hexadecimal code (e.g., '#00BFFF')." - ), - pattern="^#[0-9a-fA-F]{6}$", - ) + model_config = ConfigDict(populate_by_name=True, extra="allow") icon_url: Optional[str] = Field( None, alias="iconUrl", diff --git a/agent_sdks/python/a2ui_core/src/a2ui/core/catalog/catalog.py b/agent_sdks/python/a2ui_core/src/a2ui/core/catalog/catalog.py index 2dec8b1047..882d97355b 100644 --- a/agent_sdks/python/a2ui_core/src/a2ui/core/catalog/catalog.py +++ b/agent_sdks/python/a2ui_core/src/a2ui/core/catalog/catalog.py @@ -132,12 +132,19 @@ def from_json( ) ) + theme_schema = ( + catalog_schema.get("surfaceProperties") + or catalog_schema.get("$defs", {}).get("surfaceProperties") + or catalog_schema.get("theme") + or catalog_schema.get("$defs", {}).get("theme") + or {} + ) cat = Catalog[ComponentApi, FunctionApi]( catalog_id=catalog_id, spec_version=spec_version, components=components, functions=functions, - theme_schema=catalog_schema.get("theme") or {}, + theme_schema=theme_schema, ) cat._catalog_schema = catalog_schema return cat diff --git a/agent_sdks/python/a2ui_core/src/a2ui/core/processing/message_processor.py b/agent_sdks/python/a2ui_core/src/a2ui/core/processing/message_processor.py index 039e604872..8b639307ca 100644 --- a/agent_sdks/python/a2ui_core/src/a2ui/core/processing/message_processor.py +++ b/agent_sdks/python/a2ui_core/src/a2ui/core/processing/message_processor.py @@ -24,6 +24,8 @@ MSG_TYPE_DELETE_SURFACE, MSG_TYPE_UPDATE_COMPONENTS, MSG_TYPE_UPDATE_DATA_MODEL, + THEME_KEY, + SPEC_VERSION, ) @@ -59,29 +61,28 @@ def process_messages( for msg in message_list: self._process_message(msg) - def get_client_capabilities( + def get_renderer_capabilities( self, include_inline_catalogs: bool = False ) -> Dict[str, Any]: """Aggregates supported catalog schemas into standard A2UI capabilities.""" - v09_caps: Dict[str, Any] = { + caps: Dict[str, Any] = { "supportedCatalogIds": [ cat_id for c in self.catalogs if (cat_id := getattr(c, "catalog_id", None)) is not None ] } - capabilities: Dict[str, Any] = {"v0.9": v09_caps} if include_inline_catalogs: # In Python core, we can export direct schemas as inline catalogs - v09_caps["inlineCatalogs"] = [ + caps["inlineCatalogs"] = [ schema for c in self.catalogs if (schema := getattr(c, "catalog_schema", None)) is not None ] - return capabilities + return {SPEC_VERSION: caps} - def get_client_data_model(self) -> Optional[Dict[str, Any]]: - """Aggregates active client data models for sync metadata.""" + def get_renderer_data_model(self) -> Optional[Dict[str, Any]]: + """Aggregates active renderer data models for sync metadata.""" surfaces = {} for surface in self.model.surfaces.values(): if surface.send_data_model: @@ -90,7 +91,7 @@ def get_client_data_model(self) -> Optional[Dict[str, Any]]: if not surfaces: return None - return {"version": "v0.9", "surfaces": surfaces} + return {"version": SPEC_VERSION, "surfaces": surfaces} def _process_message(self, message: Dict[str, Any]) -> None: """Dispatches individual message payloads.""" @@ -123,7 +124,7 @@ def _process_create_surface(self, payload: Dict[str, Any]) -> None: if not isinstance(surface_id, str): raise ValueError("surfaceId must be a string") catalog_id = payload.get("catalogId") - theme = payload.get("theme", {}) + theme = payload.get(THEME_KEY) or payload.get("theme") or {} send_data_model = payload.get("sendDataModel", False) # Find matching catalog definition diff --git a/agent_sdks/python/a2ui_core/src/a2ui/core/schema/__init__.py b/agent_sdks/python/a2ui_core/src/a2ui/core/schema/__init__.py index 256543c886..a7527fc276 100644 --- a/agent_sdks/python/a2ui_core/src/a2ui/core/schema/__init__.py +++ b/agent_sdks/python/a2ui_core/src/a2ui/core/schema/__init__.py @@ -24,7 +24,7 @@ ComponentCommon as ComponentCommon, ) from .constants import * -from .server_to_client import ( +from .agent_to_renderer import ( CreateSurfaceMessage as CreateSurfaceMessage, CreateSurface as CreateSurface, UpdateComponentsMessage as UpdateComponentsMessage, @@ -33,24 +33,26 @@ UpdateDataModel as UpdateDataModel, DeleteSurfaceMessage as DeleteSurfaceMessage, DeleteSurface as DeleteSurface, + CallFunctionMessage as CallFunctionMessage, + CallFunction as CallFunction, + ActionResponseMessage as ActionResponseMessage, + ActionResponse as ActionResponse, A2uiMessage as A2uiMessage, A2uiMessageListWrapper as A2uiMessageListWrapper, ) -from .client_capabilities import ( - A2uiClientCapabilities as A2uiClientCapabilities, - V09Capabilities as V09Capabilities, - InlineCatalog as InlineCatalog, - FunctionDefinition as FunctionDefinition, +from .renderer_capabilities import ( + A2uiRendererCapabilities as A2uiRendererCapabilities, + V1_0Capabilities as V1_0Capabilities, ) -from .client_to_server import ( - A2uiClientMessage as A2uiClientMessage, - A2uiClientActionMessage as A2uiClientActionMessage, - A2uiClientErrorMessage as A2uiClientErrorMessage, - A2uiClientAction as A2uiClientAction, +from .renderer_to_agent import ( + A2uiRendererMessage as A2uiRendererMessage, + A2uiRendererActionMessage as A2uiRendererActionMessage, + A2uiRendererErrorMessage as A2uiRendererErrorMessage, + A2uiRendererAction as A2uiRendererAction, A2uiValidationError as A2uiValidationError, A2uiGenericError as A2uiGenericError, - A2uiClientError as A2uiClientError, - A2uiClientDataModel as A2uiClientDataModel, - A2uiClientMessageList as A2uiClientMessageList, - A2uiClientMessageListWrapper as A2uiClientMessageListWrapper, + A2uiRendererError as A2uiRendererError, + A2uiRendererDataModel as A2uiRendererDataModel, + A2uiRendererMessageList as A2uiRendererMessageList, + A2uiRendererMessageListWrapper as A2uiRendererMessageListWrapper, ) diff --git a/agent_sdks/python/a2ui_core/src/a2ui/core/schema/server_to_client.py b/agent_sdks/python/a2ui_core/src/a2ui/core/schema/agent_to_renderer.py similarity index 53% rename from agent_sdks/python/a2ui_core/src/a2ui/core/schema/server_to_client.py rename to agent_sdks/python/a2ui_core/src/a2ui/core/schema/agent_to_renderer.py index 199919c25f..73f460b72c 100644 --- a/agent_sdks/python/a2ui_core/src/a2ui/core/schema/server_to_client.py +++ b/agent_sdks/python/a2ui_core/src/a2ui/core/schema/agent_to_renderer.py @@ -16,15 +16,20 @@ from typing import Any, Dict, List, Literal, Optional, Union from pydantic import BaseModel, Field, ConfigDict -from .common_types import StrictBaseModel +from .common_types import * from .constants import SPEC_VERSION, SPEC_VERSION_TYPE +ComponentsList = List[Any] + class CreateSurface(StrictBaseModel): surface_id: str = Field( ..., alias="surfaceId", - description="The unique identifier for the UI surface to be rendered.", + description=( + "The unique identifier for the UI surface to be rendered. It must be" + " globally unique for the renderer's lifetime." + ), ) catalog_id: str = Field( ..., @@ -35,22 +40,30 @@ class CreateSurface(StrictBaseModel): " mycompany.com:somecatalog'." ), ) - theme: Optional[Any] = Field( + surface_properties: Optional[Any] = Field( None, + alias="surfaceProperties", description=( - "Theme parameters for the surface (e.g., {'primaryColor': '#FF0000'})." - " These must validate against the 'theme' schema defined in the catalog." + "Initial surface properties (e.g., {'agentDisplayName': 'My Agent'}). These" + " must validate against the 'surfaceProperties' schema defined in the" + " catalog." ), ) send_data_model: Optional[bool] = Field( None, alias="sendDataModel", 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." + "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." ), ) + components: Optional[ComponentsList] = Field(None) + data_model: Optional[Dict[str, Any]] = Field( + None, + alias="dataModel", + description="The initial root data model object for the surface.", + ) class CreateSurfaceMessage(StrictBaseModel): @@ -62,11 +75,12 @@ class UpdateComponents(StrictBaseModel): surface_id: str = Field( ..., alias="surfaceId", - description="The unique identifier for the UI surface to be updated.", - ) - components: List[Any] = Field( - ..., description="A list containing all UI components for the surface." + description=( + "The unique identifier for the UI surface to be updated. It must be" + " globally unique for the renderer's lifetime." + ), ) + components: ComponentsList = Field(...) class UpdateComponentsMessage(StrictBaseModel): @@ -79,8 +93,8 @@ class UpdateDataModel(StrictBaseModel): ..., alias="surfaceId", description=( - "The unique identifier for the UI surface this data model update" - " applies to." + "The unique identifier for the UI surface this data model update applies" + " to. It must be globally unique for the renderer's lifetime." ), ) path: Optional[str] = Field( @@ -90,11 +104,11 @@ class UpdateDataModel(StrictBaseModel): " If omitted, or set to '/', refers to the entire data model." ), ) - value: Optional[Any] = Field( - None, + value: Any = Field( + ..., 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." + "The data to be updated in the data model. To delete the key/value at" + " 'path', set 'value' explicitly to null." ), ) @@ -108,7 +122,10 @@ class DeleteSurface(StrictBaseModel): surface_id: str = Field( ..., alias="surfaceId", - description="The unique identifier for the UI surface to be deleted.", + description=( + "The unique identifier for the UI surface to be deleted. It must be" + " globally unique for the renderer's lifetime." + ), ) @@ -117,11 +134,46 @@ class DeleteSurfaceMessage(StrictBaseModel): delete_surface: DeleteSurface = Field(..., alias="deleteSurface") +class CallFunction(StrictBaseModel): + pass + + +class CallFunctionMessage(StrictBaseModel): + version: SPEC_VERSION_TYPE = SPEC_VERSION + function_call_id: CallId = Field( + ..., + alias="functionCallId", + description=( + "Unique ID for the instance of this function call. MUST be copied verbatim" + " into the functionResponse or error." + ), + ) + want_response: Optional[bool] = Field(False, alias="wantResponse") + call_function: CallFunction = Field(..., alias="callFunction") + + +class ActionResponse(StrictBaseModel): + value: Optional[Any] = Field(None, description="The return value of the action.") + error: Optional[Dict[str, Any]] = Field(None) + + +class ActionResponseMessage(StrictBaseModel): + version: SPEC_VERSION_TYPE = SPEC_VERSION + action_id: str = Field( + ..., + alias="actionId", + description="The ID of the action call this response belongs to.", + ) + action_response: ActionResponse = Field(..., alias="actionResponse") + + A2uiMessage = Union[ CreateSurfaceMessage, UpdateComponentsMessage, UpdateDataModelMessage, DeleteSurfaceMessage, + CallFunctionMessage, + ActionResponseMessage, ] diff --git a/agent_sdks/python/a2ui_core/src/a2ui/core/schema/client_capabilities.py b/agent_sdks/python/a2ui_core/src/a2ui/core/schema/client_capabilities.py deleted file mode 100644 index 543bbf61d8..0000000000 --- a/agent_sdks/python/a2ui_core/src/a2ui/core/schema/client_capabilities.py +++ /dev/null @@ -1,84 +0,0 @@ -# Copyright 2026 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Auto-generated. Do not edit manually. -from typing import Any, Dict, List, Literal, Optional -from pydantic import BaseModel, Field, ConfigDict -from .common_types import StrictBaseModel -from .constants import SPEC_VERSION, SPEC_VERSION_TYPE - - -class FunctionDefinition(StrictBaseModel): - name: str = Field(..., description="The unique name of the function.") - description: Optional[str] = Field( - None, - description=( - "A human-readable description of what the function does and how to use it." - ), - ) - parameters: Any = Field( - ..., - description=( - "A JSON Schema describing the expected arguments (args) for this function." - ), - ) - return_type: Literal[ - "string", "number", "boolean", "array", "object", "any", "void" - ] = Field( - ..., alias="returnType", description="The type of value this function returns." - ) - - -class InlineCatalog(StrictBaseModel): - catalog_id: str = Field( - ..., alias="catalogId", description="Unique identifier for this catalog." - ) - components: Optional[Dict[str, Any]] = Field( - None, description="Definitions for UI components supported by this catalog." - ) - functions: Optional[List[FunctionDefinition]] = Field( - None, description="Definitions for functions supported by this catalog." - ) - theme: Optional[Dict[str, Any]] = Field( - None, - description=( - "A schema that defines a catalog of A2UI theme properties. Each key is a" - " theme property name (e.g. 'primaryColor'), and each value is the JSON" - " schema for that property." - ), - ) - - -class V09Capabilities(StrictBaseModel): - supported_catalog_ids: List[str] = Field( - ..., - alias="supportedCatalogIds", - description=( - "The URI of each of the component and function catalogs that is supported" - " by the client." - ), - ) - inline_catalogs: Optional[List[InlineCatalog]] = Field( - None, - alias="inlineCatalogs", - description=( - "An array of inline catalog definitions, which can contain both components" - " and functions. This should only be provided if the agent declares" - " 'acceptsInlineCatalogs: true' in its capabilities." - ), - ) - - -class A2uiClientCapabilities(StrictBaseModel): - v0_9: Optional[V09Capabilities] = Field(None, alias=SPEC_VERSION) diff --git a/agent_sdks/python/a2ui_core/src/a2ui/core/schema/common_types.py b/agent_sdks/python/a2ui_core/src/a2ui/core/schema/common_types.py index de84c4c098..082793d37b 100644 --- a/agent_sdks/python/a2ui_core/src/a2ui/core/schema/common_types.py +++ b/agent_sdks/python/a2ui_core/src/a2ui/core/schema/common_types.py @@ -14,7 +14,7 @@ # Auto-generated. Do not edit manually. from typing import Annotated, Any, Dict, List, Literal, Optional, Union -from pydantic import BaseModel, Field, ConfigDict, GetCoreSchemaHandler, field_validator, ValidationInfo +from pydantic import BaseModel, Field, ConfigDict, GetCoreSchemaHandler from pydantic_core import CoreSchema @@ -44,23 +44,11 @@ class ListReference(ComponentReference): class StrictBaseModel(BaseModel): model_config = ConfigDict(extra="forbid", populate_by_name=True) - @field_validator("version", mode="after", check_fields=False) - @classmethod - def validate_version_field(cls, v: Any, info: ValidationInfo) -> Any: - context = info.context or {} - target_version = context.get("target_version") - if target_version is None: - from .constants import SPEC_VERSION - - target_version = SPEC_VERSION - - if v != target_version: - raise ValueError(f"Input should be '{target_version}'") - return v - ComponentId = SingleReference +CallId = str + class DataBinding(StrictBaseModel): path: str = Field( @@ -73,13 +61,6 @@ class FunctionCall(StrictBaseModel): args: Optional[Dict[str, Any]] = Field( None, description="Arguments passed to the function." ) - return_type: Optional[ - Literal["string", "number", "boolean", "array", "object", "any", "void"] - ] = Field( - alias="returnType", - description="The expected return type of the function call.", - default="boolean", - ) DynamicValue = Union[str, float, bool, List[Any], DataBinding, FunctionCall] @@ -136,7 +117,7 @@ class CheckRule(StrictBaseModel): class ActionEvent(StrictBaseModel): name: str = Field( - ..., description="The name of the action to be dispatched to the server." + ..., description="The name of the action to be dispatched to the agent." ) context: Optional[Dict[str, Any]] = Field( None, @@ -146,10 +127,23 @@ class ActionEvent(StrictBaseModel): " be dynamically bound to the data model. Do NOT use paths for static IDs." ), ) + want_response: Optional[bool] = Field( + alias="wantResponse", + description="If true, the renderer expects an actionResponse from the agent.", + default=False, + ) + response_path: Optional[str] = Field( + None, + alias="responsePath", + description=( + "Optional JSON Pointer path where the renderer should save the response" + " value in its local data model." + ), + ) class ActionEventWrapper(StrictBaseModel): - event: ActionEvent = Field(..., description="The event to dispatch to the server.") + event: ActionEvent = Field(..., description="The event to dispatch to the agent.") class ActionFunctionCallWrapper(StrictBaseModel): diff --git a/agent_sdks/python/a2ui_core/src/a2ui/core/schema/constants.py b/agent_sdks/python/a2ui_core/src/a2ui/core/schema/constants.py index 63e214069c..458619fdd4 100644 --- a/agent_sdks/python/a2ui_core/src/a2ui/core/schema/constants.py +++ b/agent_sdks/python/a2ui_core/src/a2ui/core/schema/constants.py @@ -14,8 +14,8 @@ from typing import Final, Literal, TypeAlias -SPEC_VERSION: Final = "v0.9" -SPEC_VERSION_TYPE: TypeAlias = str +SPEC_VERSION: Final = "v1.0" +SPEC_VERSION_TYPE: TypeAlias = Literal["v1.0"] SPEC_BASE_URL = "https://a2ui.org/specification" MSG_TYPE_CREATE_SURFACE = "createSurface" @@ -25,6 +25,6 @@ CATALOG_COMPONENTS_KEY = "components" SURFACE_ID_KEY = "surfaceId" -THEME_KEY = "theme" +THEME_KEY = "surfaceProperties" ROOT_ID = "root" diff --git a/agent_sdks/python/a2ui_core/src/a2ui/core/schema/renderer_capabilities.py b/agent_sdks/python/a2ui_core/src/a2ui/core/schema/renderer_capabilities.py new file mode 100644 index 0000000000..6ce819e043 --- /dev/null +++ b/agent_sdks/python/a2ui_core/src/a2ui/core/schema/renderer_capabilities.py @@ -0,0 +1,43 @@ +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Auto-generated. Do not edit manually. +from typing import Any, Dict, List, Literal, Optional +from pydantic import BaseModel, Field, ConfigDict +from .common_types import * +from .constants import SPEC_VERSION, SPEC_VERSION_TYPE + + +class V1_0Capabilities(StrictBaseModel): + supported_catalog_ids: List[str] = Field( + ..., + alias="supportedCatalogIds", + description=( + "An array of string identifiers for each of the component and function" + " catalogs supported by the renderer." + ), + ) + inline_catalogs: Optional[List[Any]] = Field( + None, + alias="inlineCatalogs", + description=( + "An array of inline catalog definitions, which can contain both components" + " and functions. This should only be provided if the agent declares" + " 'acceptsInlineCatalogs: true' in its capabilities." + ), + ) + + +class A2uiRendererCapabilities(StrictBaseModel): + v1_0: Optional[V1_0Capabilities] = Field(None, alias=SPEC_VERSION) diff --git a/agent_sdks/python/a2ui_core/src/a2ui/core/schema/client_to_server.py b/agent_sdks/python/a2ui_core/src/a2ui/core/schema/renderer_to_agent.py similarity index 56% rename from agent_sdks/python/a2ui_core/src/a2ui/core/schema/client_to_server.py rename to agent_sdks/python/a2ui_core/src/a2ui/core/schema/renderer_to_agent.py index 2b7dea4fc9..c5a407e4ce 100644 --- a/agent_sdks/python/a2ui_core/src/a2ui/core/schema/client_to_server.py +++ b/agent_sdks/python/a2ui_core/src/a2ui/core/schema/renderer_to_agent.py @@ -15,11 +15,11 @@ # Auto-generated. Do not edit manually. from typing import Any, Dict, List, Literal, Optional, Union from pydantic import BaseModel, Field, ConfigDict -from .common_types import StrictBaseModel +from .common_types import * from .constants import SPEC_VERSION, SPEC_VERSION_TYPE -class A2uiClientAction(StrictBaseModel): +class A2uiRendererAction(StrictBaseModel): name: str = Field( ..., description=( @@ -30,7 +30,10 @@ class A2uiClientAction(StrictBaseModel): surface_id: str = Field( ..., alias="surfaceId", - description="The id of the surface where the event originated.", + description=( + "The id of the surface where the event originated. It must be globally" + " unique for the renderer's lifetime." + ), ) source_component_id: str = Field( ..., @@ -47,6 +50,18 @@ class A2uiClientAction(StrictBaseModel): " action.event.context, after resolving all data bindings." ), ) + want_response: Optional[bool] = Field( + alias="wantResponse", + description="If true, the renderer expects an actionResponse from the agent.", + default=False, + ) + action_id: Optional[str] = Field( + None, + alias="actionId", + description=( + "Unique ID for this action call. Only needed if wantResponse is true." + ), + ) class A2uiValidationError(StrictBaseModel): @@ -54,7 +69,10 @@ class A2uiValidationError(StrictBaseModel): surface_id: str = Field( ..., alias="surfaceId", - description="The id of the surface where the error occurred.", + description=( + "The id of the surface where the error occurred. It must be globally unique" + " for the renderer's lifetime." + ), ) path: str = Field( ..., @@ -70,7 +88,7 @@ class A2uiValidationError(StrictBaseModel): class A2uiGenericError(BaseModel): - model_config = ConfigDict(populate_by_name=True) + model_config = ConfigDict(populate_by_name=True, extra="allow") code: Any = Field(...) message: str = Field( ..., @@ -78,40 +96,51 @@ class A2uiGenericError(BaseModel): "A short one or two sentence description of why the error occurred." ), ) - surface_id: str = Field( - ..., + surface_id: Optional[str] = Field( + None, alias="surfaceId", - description="The id of the surface where the error occurred.", + description=( + "The id of the surface where the error occurred. It must be globally unique" + " for the renderer's lifetime." + ), + ) + function_call_id: Optional[CallId] = Field( + None, + alias="functionCallId", + description=( + "The unique ID of the function invocation, which must be identical to the" + " value specified in the function invocation." + ), ) -A2uiClientError = Union[A2uiValidationError, A2uiGenericError] +A2uiRendererError = Union[A2uiValidationError, A2uiGenericError] -class A2uiClientActionMessage(StrictBaseModel): +class A2uiRendererActionMessage(StrictBaseModel): version: SPEC_VERSION_TYPE = SPEC_VERSION - action: A2uiClientAction = Field(...) + action: A2uiRendererAction = Field(...) -class A2uiClientErrorMessage(StrictBaseModel): +class A2uiRendererErrorMessage(StrictBaseModel): version: SPEC_VERSION_TYPE = SPEC_VERSION - error: A2uiClientError = Field(...) + error: A2uiRendererError = Field(...) -A2uiClientMessage = Union[A2uiClientActionMessage, A2uiClientErrorMessage] +A2uiRendererMessage = Union[A2uiRendererActionMessage, A2uiRendererErrorMessage] -class A2uiClientDataModel(StrictBaseModel): +class A2uiRendererDataModel(StrictBaseModel): version: SPEC_VERSION_TYPE = SPEC_VERSION surfaces: Dict[str, Dict[str, Any]] = Field( ..., description="A map of surface IDs to their current data models." ) -A2uiClientMessageList = List[A2uiClientMessage] +A2uiRendererMessageList = List[A2uiRendererMessage] -class A2uiClientMessageListWrapper(StrictBaseModel): - messages: A2uiClientMessageList = Field( - ..., description="An object wrapping a list of A2UI Client-to-Server messages." +class A2uiRendererMessageListWrapper(StrictBaseModel): + messages: A2uiRendererMessageList = Field( + ..., description="An object wrapping a list of A2UI Renderer-to-Agent messages." ) diff --git a/agent_sdks/python/a2ui_core/src/a2ui/core/validating/catalog_schema_validator.py b/agent_sdks/python/a2ui_core/src/a2ui/core/validating/catalog_schema_validator.py index 63acdd4ba2..369e751d76 100644 --- a/agent_sdks/python/a2ui_core/src/a2ui/core/validating/catalog_schema_validator.py +++ b/agent_sdks/python/a2ui_core/src/a2ui/core/validating/catalog_schema_validator.py @@ -311,11 +311,22 @@ def validate_theme(self, theme_payload: Dict[str, Any]) -> None: theme_spec = self.catalog.get_theme_schema() if theme_spec: ref_path = ( - f"{CATALOG_SCHEMA_FILE}#/$defs/theme" + f"{CATALOG_SCHEMA_FILE}#/$defs/surfaceProperties" if self.catalog.catalog_schema is not None and "$defs" in self.catalog.catalog_schema - and "theme" in self.catalog.catalog_schema["$defs"] - else f"{CATALOG_SCHEMA_FILE}#/theme" + and "surfaceProperties" in self.catalog.catalog_schema["$defs"] + else ( + f"{CATALOG_SCHEMA_FILE}#/surfaceProperties" + if self.catalog.catalog_schema is not None + and "surfaceProperties" in self.catalog.catalog_schema + else ( + f"{CATALOG_SCHEMA_FILE}#/$defs/theme" + if self.catalog.catalog_schema is not None + and "$defs" in self.catalog.catalog_schema + and "theme" in self.catalog.catalog_schema["$defs"] + else f"{CATALOG_SCHEMA_FILE}#/theme" + ) + ) ) try: validator = self._get_validator("theme:schema", ref_path) diff --git a/agent_sdks/python/a2ui_core/tests/test_catalog.py b/agent_sdks/python/a2ui_core/tests/test_catalog.py index 792737f181..c9e41ded34 100644 --- a/agent_sdks/python/a2ui_core/tests/test_catalog.py +++ b/agent_sdks/python/a2ui_core/tests/test_catalog.py @@ -927,11 +927,11 @@ def test_basic_catalog_validate_theme(): catalog = BasicCatalog() # 1. Test Valid Theme - _val(catalog).validate_theme({"primaryColor": "#00BFFF"}) + _val(catalog).validate_theme({"iconUrl": "https://example.com/icon.png"}) - # 2. Test Invalid Theme raises ValidationError + # 2. Test Invalid Theme raises ValidationError (type mismatch) with pytest.raises((ValidationError, ValueError)): - _val(catalog).validate_theme({"primaryColor": "invalid-color-name"}) + _val(catalog).validate_theme({"iconUrl": 12345}) def test_basic_catalog_validate_functions(): diff --git a/agent_sdks/python/a2ui_core/tests/test_components.py b/agent_sdks/python/a2ui_core/tests/test_components.py index eb435c7780..7e87fa1c5b 100644 --- a/agent_sdks/python/a2ui_core/tests/test_components.py +++ b/agent_sdks/python/a2ui_core/tests/test_components.py @@ -68,13 +68,13 @@ def test_any_component_discriminated_union(): "id": "text-1", "component": "Text", "text": "Hello, A2UI!", - "variant": "h1", + "variant": "caption", } comp = adapter.validate_python(text_data) assert isinstance(comp, TextComponent) assert comp.component == "Text" assert comp.text == "Hello, A2UI!" - assert comp.variant == "h1" + assert comp.variant == "caption" # 2. Test ImageComponent routing image_data = { @@ -122,11 +122,11 @@ def test_text_component_validation(): id="welcome_text", component="Text", text="Hello World!", - variant="h1", + variant="caption", ) assert comp.id == "welcome_text" assert comp.text == "Hello World!" - assert comp.variant == "h1" + assert comp.variant == "caption" # 2. Validation Fails on missing required properties with pytest.raises(ValidationError): @@ -146,9 +146,7 @@ def test_text_component_variant_enum(): text="Hello Mismatch", variant="bold", # type: ignore ) - assert "Input should be 'h1', 'h2', 'h3', 'h4', 'h5', 'caption' or 'body'" in str( - exc_info.value - ) + assert "Input should be 'caption' or 'body'" in str(exc_info.value) def test_button_component_strict_extra_forbid(): @@ -165,7 +163,7 @@ def test_button_component_strict_extra_forbid(): def test_message_payload_parsing(): payload = { - "version": "v0.9", + "version": "v1.0", "updateComponents": { "surfaceId": "surface_1", "components": [ @@ -181,7 +179,7 @@ def test_message_payload_parsing(): } msg = UpdateComponentsMessage.model_validate(payload) - assert msg.version == "v0.9" + assert msg.version == "v1.0" assert msg.update_components.surface_id == "surface_1" assert len(msg.update_components.components) == 2 assert msg.update_components.components[0]["component"] == "Text" diff --git a/agent_sdks/python/a2ui_core/tests/test_generate_schemas.py b/agent_sdks/python/a2ui_core/tests/test_generate_schemas.py index f959801eea..acce836a2e 100644 --- a/agent_sdks/python/a2ui_core/tests/test_generate_schemas.py +++ b/agent_sdks/python/a2ui_core/tests/test_generate_schemas.py @@ -389,10 +389,10 @@ def test_generate_basic_catalog_functions(): def test_generate_basic_catalog_styles(): mock_catalog_data = { "$defs": { - "theme": { + "surfaceProperties": { "type": "object", "properties": { - "primaryColor": {"type": "string", "description": "Test color."} + "iconUrl": {"type": "string", "description": "Test icon."} }, "additionalProperties": True, } @@ -401,8 +401,8 @@ def test_generate_basic_catalog_styles(): code = generate_schemas.generate_basic_catalog_styles(mock_catalog_data) assert "class Theme(BaseModel):" in code assert ( - 'primary_color: Optional[str] = Field(None, alias="primaryColor",' - ' description="Test color.")' + 'icon_url: Optional[str] = Field(None, alias="iconUrl",' + ' description="Test icon.")' in code ) @@ -435,10 +435,10 @@ def test_generate_schema_init(): assert " CreateSurface as CreateSurface," in code -def test_generate_client_capabilities(): +def test_generate_renderer_capabilities(): mock_capabilities_data = { "properties": { - "v0.9": { + "v1.0": { "properties": { "supportedCatalogIds": { "type": "array", @@ -458,14 +458,14 @@ def test_generate_client_capabilities(): } }, } - code = generate_schemas.generate_client_capabilities(mock_capabilities_data) + code = generate_schemas.generate_renderer_capabilities(mock_capabilities_data) assert "class FunctionDefinition(StrictBaseModel):" in code - assert "class V09Capabilities(StrictBaseModel):" in code - assert "class A2uiClientCapabilities(StrictBaseModel):" in code - assert "v0_9: Optional[V09Capabilities] = Field(None, alias=SPEC_VERSION)" in code + assert "class V1_0Capabilities(StrictBaseModel):" in code + assert "class A2uiRendererCapabilities(StrictBaseModel):" in code + assert "v1_0: Optional[V1_0Capabilities] = Field(None, alias=SPEC_VERSION)" in code -def test_generate_client_to_server(): +def test_generate_renderer_to_agent(): mock_c2s_data = { "properties": { "action": { @@ -481,15 +481,16 @@ def test_generate_client_to_server(): }, } } - code = generate_schemas.generate_client_to_server(mock_c2s_data) - assert "class A2uiClientAction(StrictBaseModel):" in code + code = generate_schemas.generate_renderer_to_agent(mock_c2s_data) + assert "class A2uiRendererAction(StrictBaseModel):" in code assert "class A2uiValidationError(StrictBaseModel):" in code assert "code: Literal['VALIDATION_FAILED'] = Field(\"VALIDATION_FAILED\")" in code - assert "A2uiClientError = Union[A2uiValidationError]\n" in code - assert "class A2uiClientActionMessage(StrictBaseModel):" in code - assert "class A2uiClientErrorMessage(StrictBaseModel):" in code + assert "A2uiRendererError = Union[A2uiValidationError]\n" in code + assert "class A2uiRendererActionMessage(StrictBaseModel):" in code + assert "class A2uiRendererErrorMessage(StrictBaseModel):" in code assert ( - "A2uiClientMessage = Union[A2uiClientActionMessage, A2uiClientErrorMessage]" + "A2uiRendererMessage = Union[A2uiRendererActionMessage," + " A2uiRendererErrorMessage]" in code ) diff --git a/agent_sdks/python/a2ui_core/tests/test_processing.py b/agent_sdks/python/a2ui_core/tests/test_processing.py index e2f798709b..a743a92173 100644 --- a/agent_sdks/python/a2ui_core/tests/test_processing.py +++ b/agent_sdks/python/a2ui_core/tests/test_processing.py @@ -69,7 +69,7 @@ def test_message_processor_surface_lifecycle(mock_catalog): "createSurface": { "surfaceId": "surface_1", "catalogId": mock_catalog.catalog_id, - "theme": {"primaryColor": "red"}, + "surfaceProperties": {"agentDisplayName": "My Agent"}, "sendDataModel": True, }, } @@ -78,7 +78,7 @@ def test_message_processor_surface_lifecycle(mock_catalog): surface = processor.model.get_surface("surface_1") assert surface is not None assert surface.id == "surface_1" - assert surface.theme == {"primaryColor": "red"} + assert surface.theme == {"agentDisplayName": "My Agent"} assert surface.send_data_model is True # 2. Delete surface @@ -173,7 +173,7 @@ def test_message_processor_capabilities_and_sync(mock_catalog): processor = MessageProcessor(catalogs=[mock_catalog]) # Check Capabilities - caps = processor.get_client_capabilities() + caps = processor.get_renderer_capabilities() assert caps == { SPEC_VERSION: {"supportedCatalogIds": ["https://a2ui.org/mock.json"]} } @@ -195,7 +195,7 @@ def test_message_processor_capabilities_and_sync(mock_catalog): ]) # Retrieve client data model sync payload - client_dm = processor.get_client_data_model() + client_dm = processor.get_renderer_data_model() assert client_dm == {"version": SPEC_VERSION, "surfaces": {"s1": {"val": 100}}} @@ -605,14 +605,17 @@ def test_message_processor_theme_validation(real_catalog_09): processor = MessageProcessor(catalogs=[real_catalog_09], strict_mode=True) with pytest.raises( ValueError, - match="Validation failed for theme on surface 's1'|String should match pattern", + match=( + "Validation failed for theme on surface 's1'|is not of type 'string'|Input" + " should be a valid string" + ), ): processor.process_messages([{ "version": SPEC_VERSION, "createSurface": { "surfaceId": "s1", "catalogId": real_catalog_09.catalog_id, - "theme": {"primaryColor": "invalid-color-name"}, + "surfaceProperties": {"iconUrl": 12345}, }, }]) @@ -696,10 +699,10 @@ def test_message_processor_json_catalog_validation(): def test_message_processor_json_catalog_theme_validation(): - # Define JSON catalog schema containing theme and functions specs + # Define JSON catalog schema containing surfaceProperties and functions specs catalog_json = { "catalogId": "https://rizzcharts.com/catalog.json", - "theme": { + "surfaceProperties": { "type": "object", "properties": { "primaryColor": {"type": "string", "pattern": "^#[0-9a-fA-F]{6}$"} @@ -738,6 +741,8 @@ def test_message_processor_json_catalog_theme_validation(): "createSurface": { "surfaceId": "s1", "catalogId": catalog.catalog_id, - "theme": {"primaryColor": "red"}, # Must match hex color regex! + "surfaceProperties": { + "primaryColor": "red" + }, # Must match hex color regex! }, }]) diff --git a/agent_sdks/python/a2ui_core/tests/test_schema.py b/agent_sdks/python/a2ui_core/tests/test_schema.py index db4d7ab810..6d5371675f 100644 --- a/agent_sdks/python/a2ui_core/tests/test_schema.py +++ b/agent_sdks/python/a2ui_core/tests/test_schema.py @@ -17,10 +17,10 @@ from typing import get_args from a2ui.core.schema import ( - A2uiClientMessageListWrapper, - A2uiClientActionMessage, - A2uiClientErrorMessage, - A2uiClientDataModel, + A2uiRendererMessageListWrapper, + A2uiRendererActionMessage, + A2uiRendererErrorMessage, + A2uiRendererDataModel, A2uiValidationError, A2uiGenericError, A2uiMessage, @@ -30,7 +30,7 @@ def test_valid_action_message(): valid_action = { - "version": "v0.9", + "version": "v1.0", "action": { "name": "submit", "surfaceId": "s1", @@ -39,15 +39,15 @@ def test_valid_action_message(): "context": {"foo": "bar"}, }, } - msg = A2uiClientActionMessage.model_validate(valid_action) - assert msg.version == "v0.9" + msg = A2uiRendererActionMessage.model_validate(valid_action) + assert msg.version == "v1.0" assert msg.action.name == "submit" assert msg.action.context == {"foo": "bar"} def test_valid_validation_error_message(): valid_error = { - "version": "v0.9", + "version": "v1.0", "error": { "code": "VALIDATION_FAILED", "surfaceId": "s1", @@ -55,8 +55,8 @@ def test_valid_validation_error_message(): "message": "Too short", }, } - msg = A2uiClientErrorMessage.model_validate(valid_error) - assert msg.version == "v0.9" + msg = A2uiRendererErrorMessage.model_validate(valid_error) + assert msg.version == "v1.0" assert isinstance(msg.error, A2uiValidationError) assert msg.error.code == "VALIDATION_FAILED" assert msg.error.path == "/components/0/text" @@ -64,15 +64,15 @@ def test_valid_validation_error_message(): def test_valid_generic_error_message(): valid_error = { - "version": "v0.9", + "version": "v1.0", "error": { "code": "INTERNAL_ERROR", "message": "Something went wrong", "surfaceId": "s1", }, } - msg = A2uiClientErrorMessage.model_validate(valid_error) - assert msg.version == "v0.9" + msg = A2uiRendererErrorMessage.model_validate(valid_error) + assert msg.version == "v1.0" assert isinstance(msg.error, A2uiGenericError) assert msg.error.code == "INTERNAL_ERROR" assert msg.error.message == "Something went wrong" @@ -80,21 +80,21 @@ def test_valid_generic_error_message(): def test_valid_data_model_message(): valid_data_model = { - "version": "v0.9", + "version": "v1.0", "surfaces": { "s1": {"user": "Alice"}, "s2": {"cart": []}, }, } - msg = A2uiClientDataModel.model_validate(valid_data_model) - assert msg.version == "v0.9" + msg = A2uiRendererDataModel.model_validate(valid_data_model) + assert msg.version == "v1.0" assert msg.surfaces["s1"] == {"user": "Alice"} assert msg.surfaces["s2"] == {"cart": []} def test_fails_on_invalid_version(): invalid_action = { - "version": "v0.8", + "version": "v0.9", "action": { "name": "submit", "surfaceId": "s1", @@ -104,16 +104,16 @@ def test_fails_on_invalid_version(): }, } with pytest.raises(ValidationError): - A2uiClientActionMessage.model_validate(invalid_action) + A2uiRendererActionMessage.model_validate(invalid_action) def test_valid_delete_surface_server_message(): msg = { - "version": "v0.9", + "version": "v1.0", "deleteSurface": {"surfaceId": "surface-1"}, } parsed = DeleteSurfaceMessage.model_validate(msg) - assert parsed.version == "v0.9" + assert parsed.version == "v1.0" assert parsed.delete_surface.surface_id == "surface-1" diff --git a/agent_sdks/python/a2ui_core/tests/test_validating.py b/agent_sdks/python/a2ui_core/tests/test_validating.py index 2cf46e5d59..4d18f5e390 100644 --- a/agent_sdks/python/a2ui_core/tests/test_validating.py +++ b/agent_sdks/python/a2ui_core/tests/test_validating.py @@ -240,15 +240,15 @@ def test_a2ui_validator_validate_valid_payload(): messages = [ { - "version": "v0.9", + "version": "v1.0", "createSurface": { "surfaceId": "main", "catalogId": "https://a2ui.org/catalog", - "theme": {"primaryColor": "#000000"}, + "surfaceProperties": {"primaryColor": "#000000"}, }, }, { - "version": "v0.9", + "version": "v1.0", "updateComponents": { "surfaceId": "main", "components": [ @@ -275,7 +275,7 @@ def test_a2ui_validator_validate_components_error(): validator = A2uiValidator() messages = [{ - "version": "v0.9", + "version": "v1.0", "updateComponents": { "surfaceId": "main", "components": [{ @@ -345,9 +345,9 @@ def test_integrity_dangling_and_duplicate_pointers(): def test_validate_recursion_and_paths_syntax_coverage(): - # 1. Realistic A2UI v0.9 Payload with Invalid Pointer Syntax + # 1. Realistic A2UI v1.0 Payload with Invalid Pointer Syntax invalid_path_payload = { - "version": "v0.9", + "version": "v1.0", "updateDataModel": { "surfaceId": "s1", "path": "/users/~3name", # Unescaped pointer! @@ -357,9 +357,9 @@ def test_validate_recursion_and_paths_syntax_coverage(): with pytest.raises(ValueError, match="Invalid path syntax"): validate_recursion_and_paths(invalid_path_payload) - # 2. Realistic A2UI v0.9 Payload with Max Function Call Recursion Depth + # 2. Realistic A2UI v1.0 Payload with Max Function Call Recursion Depth payload_deep_func = { - "version": "v0.9", + "version": "v1.0", "updateComponents": { "surfaceId": "s1", "components": [{ @@ -404,7 +404,7 @@ def test_validate_recursion_and_paths_syntax_coverage(): def test_validator_aggregated_pydantic_error_formatting(): validator = A2uiValidator() - invalid_s2c_payload = [{"version": "v0.9"}] + invalid_s2c_payload = [{"version": "v1.0"}] with pytest.raises(A2uiValidatorError) as exc_info: validator.validate_protocol_envelope(invalid_s2c_payload) @@ -447,7 +447,7 @@ def test_validator_config_parameter(): # 3. Full message validation payload = { - "version": "v0.9", + "version": "v1.0", "updateComponents": { "surfaceId": "s1", "components": dangling_components, diff --git a/docs/public/ecosystem/a2ui-in-the-world.md b/docs/public/ecosystem/a2ui-in-the-world.md index 5fa6b41fbc..eb63b5424c 100644 --- a/docs/public/ecosystem/a2ui-in-the-world.md +++ b/docs/public/ecosystem/a2ui-in-the-world.md @@ -172,7 +172,7 @@ The A2UI community is building exciting projects: - Gemini-powered agent - Full source code available -- **Component Gallery** ([samples/client/angular - gallery mode](../../../samples/client/angular)) +- **Component Gallery** ([samples/renderer/angular - gallery mode](../../../samples/renderer/angular)) - Interactive showcase of all components - Live examples with code - Great for learning diff --git a/docs/public/guides/mcp-apps-in-a2ui.md b/docs/public/guides/mcp-apps-in-a2ui.md index 97aabd957e..2f21ade422 100644 --- a/docs/public/guides/mcp-apps-in-a2ui.md +++ b/docs/public/guides/mcp-apps-in-a2ui.md @@ -22,7 +22,7 @@ To prevent this, A2UI strictly excludes `allow-same-origin` for the inner iframe ### The Architecture -1. **[Sandbox Proxy (`sandbox.html`)](../../../samples/client/shared/mcp_apps_inner_iframe/sandbox.html)**: An intermediate `iframe` served from the same origin. It isolates raw DOM injection from the main app while maintaining a structured JSON-RPC channel. +1. **[Sandbox Proxy (`sandbox.html`)](../../../samples/renderer/shared/mcp_apps_inner_iframe/sandbox.html)**: An intermediate `iframe` served from the same origin. It isolates raw DOM injection from the main app while maintaining a structured JSON-RPC channel. - Permissions: **Do not sandbox** in the host template (e.g., [`mcp-app.ts`](../../../samples/community/client/lit/mcp-apps-in-a2ui-sample/mcp-app.ts) or [`mcp-apps-component.ts`](../../../samples/community/client/lit/mcp-apps-in-a2ui-sample/ui/custom-components/mcp-apps-component.ts)). - Host origin validation: Validates that messages come from the expected host origin. 2. **Embedded App (Inner Iframe)**: The innermost `iframe`. Injected dynamically via `srcdoc` with restricted permissions. @@ -226,7 +226,7 @@ The agent will run on `http://localhost:8000`. In a new terminal, navigate to the client directory and start the dev server (requires building the Lit renderer first): ```bash -cd samples/client/lit/mcp-apps-in-a2ui-sample +cd samples/renderer/lit/mcp-apps-in-a2ui-sample yarn install yarn dev ``` @@ -328,7 +328,7 @@ http://localhost:4200/?disable_security_self_test=true | ------------------------------------------------- | ------------------------------------------------------------------------------------------------ | | `GEMINI_API_KEY environment variable not set` | Export the key or add a `.env` file in the agent directory | | Python version error on `restaurant_finder` agent | Install Python 3.13+ (required by that sample's `pyproject.toml`) | -| `yarn build:renderer` fails | Make sure you ran `yarn install` first in `samples/client/lit/` | +| `yarn build:renderer` fails | Make sure you ran `yarn install` first in `samples/renderer/lit/` | | Angular client shows blank page | Ensure you ran `yarn build:sandbox` before `yarn start` | | MCP app iframe doesn't load | Check that both the MCP server (port 8000) and proxy agent (port 10006) are running | | `ng serve` not found | Run `yarn install` to install dev dependencies including `@angular/cli` | diff --git a/docs/public/guides/client-setup.md b/docs/public/guides/renderer-setup.md similarity index 89% rename from docs/public/guides/client-setup.md rename to docs/public/guides/renderer-setup.md index 3e9af292aa..ebc992623f 100644 --- a/docs/public/guides/client-setup.md +++ b/docs/public/guides/renderer-setup.md @@ -44,7 +44,7 @@ Once installed, you can use the renderer in your app. The Lit renderer uses: - **`` component**: Renders surfaces in your app. - **Lit Signals**: Provides reactive state management for automatic UI updates. -**See working example:** [Lit shell sample](../../../samples/client/lit/shell) — Check its README for detailed run instructions. +**See working example:** [Lit shell sample](../../../samples/renderer/lit/shell) — Check its README for detailed run instructions. ## Angular @@ -82,7 +82,7 @@ export const appConfig: ApplicationConfig = { }; ``` -**See working example:** [Angular samples](../../../samples/client/angular) +**See working example:** [Angular samples](../../../samples/renderer/angular) ### Streaming @@ -108,7 +108,7 @@ The React renderer provides: - **`` component**: Renders A2UI surfaces in your React app - **`useA2UI()` hook**: Accesses the message processor from any component -**See working example:** [React shell](../../../samples/client/react/shell) +**See working example:** [React shell](../../../samples/renderer/react/shell) ## Flutter (GenUI SDK) @@ -134,7 +134,7 @@ Common transport options: - **WebSockets**: Bidirectional real-time communication - **A2A Protocol**: Standardized agent-to-agent communication with A2UI support -See [samples/client/lit/shell/client.ts](../../../samples/client/lit/shell/client.ts) for an example of using the A2A protocol client. +See [samples/renderer/lit/shell/client.ts](../../../samples/renderer/lit/shell/client.ts) for an example of using the A2A protocol client. **See:** [Transports guide](../concepts/transports.md) @@ -147,7 +147,7 @@ When users interact with A2UI components (clicking buttons, submitting forms, et 3. Sends the action to the agent 4. Processes the agent's response messages -See the `@a2uiaction` event handler in `#maybeRenderData` in [samples/client/lit/shell/app.ts](../../../samples/client/lit/shell/app.ts) for an example of handling button clicks and form submissions. +See the `@a2uiaction` event handler in `#maybeRenderData` in [samples/renderer/lit/shell/app.ts](../../../samples/renderer/lit/shell/app.ts) for an example of handling button clicks and form submissions. ## Error Handling @@ -158,7 +158,7 @@ Common errors to handle: - **Invalid Data Path**: Check data model structure and JSON Pointer syntax. - **Schema Validation Failed**: Verify message format matches A2UI specification. -See `try...catch` blocks in `#sendMessage` in [samples/client/lit/shell/app.ts](../../../samples/client/lit/shell/app.ts) for examples of handling communication errors. +See `try...catch` blocks in `#sendMessage` in [samples/renderer/lit/shell/app.ts](../../../samples/renderer/lit/shell/app.ts) for examples of handling communication errors. ## Next Steps diff --git a/docs/public/guides/theming.md b/docs/public/guides/theming.md index 62f406247d..2280f0f21f 100644 --- a/docs/public/guides/theming.md +++ b/docs/public/guides/theming.md @@ -87,9 +87,9 @@ See the default styles in [default.ts](../../../renderers/web_core/src/v0_9/basi **See some examples per-platform:** -- [Lit samples](../../../samples/client/lit) -- [Angular samples](../../../samples/client/angular) -- [React samples](../../../samples/client/react) +- [Lit samples](../../../samples/renderer/lit) +- [Angular samples](../../../samples/renderer/angular) +- [React samples](../../../samples/renderer/react) ### Per-component overrides diff --git a/docs/public/quickstart.md b/docs/public/quickstart.md index 29e237f967..89db526daf 100644 --- a/docs/public/quickstart.md +++ b/docs/public/quickstart.md @@ -40,10 +40,10 @@ export GEMINI_API_KEY="your_gemini_api_key_here" ## Step 3: Navigate to the Lit Client Samples Directory -The client application source code is located in `samples/client/lit/shell`. Navigate to the parent samples directory to run the demo: +The client application source code is located in `samples/renderer/lit/shell`. Navigate to the parent samples directory to run the demo: ```bash -cd samples/client/lit +cd samples/renderer/lit ``` ## Step 4: Install and Run @@ -94,7 +94,7 @@ uv run . **2. Run the Client:** ```bash -cd samples/client/lit/shell +cd samples/renderer/lit/shell yarn dev ``` @@ -225,12 +225,12 @@ This runs a client-only demo showcasing every standard component (Card, Button, ### Other Languages and Frameworks -While this guide uses the Lit client as an example, A2UI provides samples for other popular frameworks in the `samples/client` directory: +While this guide uses the Lit client as an example, A2UI provides samples for other popular frameworks in the `samples/renderer` directory: -- **Angular**: `samples/client/angular` -- **React**: `samples/client/react` +- **Angular**: `samples/renderer/angular` +- **React**: `samples/renderer/react` -Explore the [samples/client](../../samples/client) directory to see all available client implementations. +Explore the [samples/renderer](../../samples/renderer) directory to see all available client implementations. ## What's Next? @@ -286,7 +286,7 @@ uv run . ### Still Having Issues? - Check the [GitHub Issues](https://github.com/a2ui-project/a2ui/issues) -- Review the [samples/client/lit/README.md](../../samples/client/lit) +- Review the [samples/renderer/lit/README.md](../../samples/renderer/lit) - Join the community discussions ## Understanding the Demo Code @@ -294,7 +294,7 @@ uv run . Want to see how it works? Check out: - **Agent Code**: `samples/agent/adk/restaurant_finder/` — The Python A2A agent -- **Client Code**: `samples/client/lit/` — The Lit web client with A2UI renderer +- **Client Code**: `samples/renderer/lit/` — The Lit web client with A2UI renderer - **A2UI Renderers**: `renderers/lit/` (Lit) and `renderers/web_core/` (framework-agnostic core) Each directory has its own README with detailed documentation. diff --git a/docs/public/reference/components.md b/docs/public/reference/components.md index 70fb9d336a..8039e03296 100644 --- a/docs/public/reference/components.md +++ b/docs/public/reference/components.md @@ -630,7 +630,7 @@ The component names and properties are largely the same across versions. The str To see all components in action: ```bash -cd samples/client/angular +cd samples/renderer/angular yarn start gallery ``` diff --git a/kotlin/agent_sdk_legacy/build.gradle.kts b/kotlin/agent_sdk_legacy/build.gradle.kts index acb3ab2384..ad689ac871 100644 --- a/kotlin/agent_sdk_legacy/build.gradle.kts +++ b/kotlin/agent_sdk_legacy/build.gradle.kts @@ -75,6 +75,16 @@ val copySpecs by tasks.registering(Copy::class) { into("com/google/a2ui/assets/0.9/catalogs/basic") } + from(File(repoRoot, "specification/v1_0/json/agent_to_renderer.json")) { + into("com/google/a2ui/assets/1.0") + } + from(File(repoRoot, "specification/v1_0/json/common_types.json")) { + into("com/google/a2ui/assets/1.0") + } + from(File(repoRoot, "specification/v1_0/catalogs/basic/catalog.json")) { + into("com/google/a2ui/assets/1.0/catalogs/basic") + } + into(layout.buildDirectory.dir("generated/resources/specs")) } diff --git a/kotlin/agent_sdk_legacy/src/main/kotlin/com/google/a2ui/InferenceStrategy.kt b/kotlin/agent_sdk_legacy/src/main/kotlin/com/google/a2ui/InferenceStrategy.kt index 63b0cfce98..d45987cd87 100644 --- a/kotlin/agent_sdk_legacy/src/main/kotlin/com/google/a2ui/InferenceStrategy.kt +++ b/kotlin/agent_sdk_legacy/src/main/kotlin/com/google/a2ui/InferenceStrategy.kt @@ -30,7 +30,7 @@ interface InferenceStrategy { * @param roleDescription The foundational role or persona for the agent. * @param workflowDescription Optional workflow instructions to guide agent behavior. * @param uiDescription Optional UI context or descriptive instruction. - * @param clientUiCapabilities Capabilities reported by the client for targeted schema pruning. + * @param rendererUiCapabilities Capabilities reported by the renderer for targeted schema pruning. * @param allowedComponents A specific list of component IDs allowed for rendering. * @param allowedMessages A specific list of message IDs allowed for rendering. * @param includeSchema Whether to embed the A2UI JSON schema directly in the instructions. @@ -42,7 +42,7 @@ interface InferenceStrategy { roleDescription: String, workflowDescription: String = "", uiDescription: String = "", - clientUiCapabilities: JsonObject? = null, + rendererUiCapabilities: JsonObject? = null, allowedComponents: List = emptyList(), allowedMessages: List = emptyList(), includeSchema: Boolean = false, diff --git a/kotlin/agent_sdk_legacy/src/main/kotlin/com/google/a2ui/a2a/A2aHandler.kt b/kotlin/agent_sdk_legacy/src/main/kotlin/com/google/a2ui/a2a/A2aHandler.kt index 54f40c8f7b..0526bee647 100644 --- a/kotlin/agent_sdk_legacy/src/main/kotlin/com/google/a2ui/a2a/A2aHandler.kt +++ b/kotlin/agent_sdk_legacy/src/main/kotlin/com/google/a2ui/a2a/A2aHandler.kt @@ -140,7 +140,8 @@ class A2aHandler(private val runner: Runner) { val parsedParts = mutableListOf>() val functionCall = part.functionCall().orElse(null) - if (functionCall != null && functionCall.name().orElse(null) == "send_a2ui_json_to_client") { + val fnName = functionCall?.name()?.orElse(null) + if (fnName == "send_a2ui_json_to_renderer" || fnName == "send_a2ui_json_to_client") { val argsMap = functionCall.args().orElse(null) as? Map<*, *> val a2uiJsonStr = argsMap?.get("a2ui_json") as? String if (a2uiJsonStr != null) { diff --git a/kotlin/agent_sdk_legacy/src/main/kotlin/com/google/a2ui/a2a/A2uiA2a.kt b/kotlin/agent_sdk_legacy/src/main/kotlin/com/google/a2ui/a2a/A2uiA2a.kt index 21de955045..f3dd749338 100644 --- a/kotlin/agent_sdk_legacy/src/main/kotlin/com/google/a2ui/a2a/A2uiA2a.kt +++ b/kotlin/agent_sdk_legacy/src/main/kotlin/com/google/a2ui/a2a/A2uiA2a.kt @@ -81,7 +81,7 @@ object A2uiA2a { /** * Selects the newest A2UI extension URI from the matched extensions. * - * @param requestedExtensions List of extension URIs requested by the client. + * @param requestedExtensions List of extension URIs requested by the renderer. * @param advertisedExtensions List of extension URIs advertised by the agent. * @return The newest overlapping A2UI extension URI, or null if none match. */ @@ -121,7 +121,7 @@ object A2uiA2a { /** * Activates the A2UI extension if requested in the context. * - * @param requestedExtensions List of extension URIs requested by the client. + * @param requestedExtensions List of extension URIs requested by the renderer. * @param advertisedExtensions List of extension URIs advertised by the agent. * @param addActivatedExtension Callback to register an activated extension. * @return The version string of the activated A2UI extension, or null if not activated. diff --git a/kotlin/agent_sdk_legacy/src/main/kotlin/com/google/a2ui/adk/a2a_extension/Converters.kt b/kotlin/agent_sdk_legacy/src/main/kotlin/com/google/a2ui/adk/a2a_extension/Converters.kt index db6469b13c..b375e077f2 100644 --- a/kotlin/agent_sdk_legacy/src/main/kotlin/com/google/a2ui/adk/a2a_extension/Converters.kt +++ b/kotlin/agent_sdk_legacy/src/main/kotlin/com/google/a2ui/adk/a2a_extension/Converters.kt @@ -52,26 +52,26 @@ class A2uiPartConverter( fun convert(part: Part): List> { val functionResponse = part.functionResponse().orElse(null) - val isSendA2uiJsonToClientResponse = + val isSendA2uiJsonToRendererResponse = functionResponse != null && - functionResponse.name().orElse(null) == SendA2uiToClientToolset.TOOL_NAME + functionResponse.name().orElse(null) == SendA2uiToRendererToolset.TOOL_NAME - if (isSendA2uiJsonToClientResponse || bypassToolCheck) { + if (isSendA2uiJsonToRendererResponse || bypassToolCheck) { if (functionResponse == null) return emptyList() val responseMap = functionResponse.response().orElse(null) as? Map<*, *> - responseMap?.get(SendA2uiToClientToolset.TOOL_ERROR_KEY)?.let { + responseMap?.get(SendA2uiToRendererToolset.TOOL_ERROR_KEY)?.let { logger.warning("A2UI tool call failed: $it") return emptyList() } - return (responseMap?.get(SendA2uiToClientToolset.VALIDATED_A2UI_JSON_KEY) as? JsonElement) + return (responseMap?.get(SendA2uiToRendererToolset.VALIDATED_A2UI_JSON_KEY) as? JsonElement) ?.let { listOf(A2uiA2a.createA2uiPart(it)) } ?: emptyList() } val functionCall = part.functionCall().orElse(null) if ( - functionCall != null && functionCall.name().orElse(null) == SendA2uiToClientToolset.TOOL_NAME + functionCall != null && functionCall.name().orElse(null) == SendA2uiToRendererToolset.TOOL_NAME ) { return emptyList() } diff --git a/kotlin/agent_sdk_legacy/src/main/kotlin/com/google/a2ui/adk/a2a_extension/SendA2uiToClientToolset.kt b/kotlin/agent_sdk_legacy/src/main/kotlin/com/google/a2ui/adk/a2a_extension/SendA2uiToRendererToolset.kt similarity index 90% rename from kotlin/agent_sdk_legacy/src/main/kotlin/com/google/a2ui/adk/a2a_extension/SendA2uiToClientToolset.kt rename to kotlin/agent_sdk_legacy/src/main/kotlin/com/google/a2ui/adk/a2a_extension/SendA2uiToRendererToolset.kt index 8c7d2cc4d7..b683b19804 100644 --- a/kotlin/agent_sdk_legacy/src/main/kotlin/com/google/a2ui/adk/a2a_extension/SendA2uiToClientToolset.kt +++ b/kotlin/agent_sdk_legacy/src/main/kotlin/com/google/a2ui/adk/a2a_extension/SendA2uiToRendererToolset.kt @@ -45,7 +45,7 @@ typealias A2uiExamplesProvider = (ReadonlyContext) -> String * and current catalog capabilities. Features dynamic enablement, pulling localized components on * demand. */ -class SendA2uiToClientToolset +class SendA2uiToRendererToolset @JvmOverloads constructor( private val a2uiEnabled: A2uiEnabledProvider, @@ -53,8 +53,8 @@ constructor( private val a2uiExamples: A2uiExamplesProvider, ) : BaseToolset { - private val logger = Logger.getLogger(SendA2uiToClientToolset::class.java.name) - private val uiTools = listOf(SendA2uiJsonToClientTool()) + private val logger = Logger.getLogger(SendA2uiToRendererToolset::class.java.name) + private val uiTools = listOf(SendA2uiJsonToRendererTool()) override fun getTools(readonlyContext: ReadonlyContext): Flowable = if (a2uiEnabled(readonlyContext)) { @@ -72,10 +72,10 @@ constructor( fun getPartConverter(ctx: ReadonlyContext): A2uiPartConverter = A2uiPartConverter(a2uiCatalog(ctx)) - inner class SendA2uiJsonToClientTool : + inner class SendA2uiJsonToRendererTool : BaseTool( TOOL_NAME, - "Sends A2UI JSON to the client to render rich UI natively. Always prefer this over returning raw JSON.", + "Sends A2UI JSON to the renderer to render rich UI natively. Always prefer this over returning raw JSON.", ) { override fun declaration(): Optional { @@ -91,7 +91,7 @@ constructor( A2UI_JSON_ARG_NAME to Schema.builder() .type(Type(Type.Known.STRING)) - .description("The A2UI JSON payload to send to the client.") + .description("The A2UI JSON payload to send to the renderer.") .build() ) ) @@ -152,9 +152,9 @@ constructor( enabled: Boolean, catalog: A2uiCatalog, examples: String = "", - ): SendA2uiToClientToolset = SendA2uiToClientToolset({ enabled }, { catalog }, { examples }) + ): SendA2uiToRendererToolset = SendA2uiToRendererToolset({ enabled }, { catalog }, { examples }) - const val TOOL_NAME = "send_a2ui_json_to_client" + const val TOOL_NAME = "send_a2ui_json_to_renderer" const val VALIDATED_A2UI_JSON_KEY = "validated_a2ui_json" private const val A2UI_JSON_ARG_NAME = "a2ui_json" const val TOOL_ERROR_KEY = "error" diff --git a/kotlin/agent_sdk_legacy/src/main/kotlin/com/google/a2ui/schema/A2uiConstants.kt b/kotlin/agent_sdk_legacy/src/main/kotlin/com/google/a2ui/schema/A2uiConstants.kt index fc6b51006b..6c33d5f28f 100644 --- a/kotlin/agent_sdk_legacy/src/main/kotlin/com/google/a2ui/schema/A2uiConstants.kt +++ b/kotlin/agent_sdk_legacy/src/main/kotlin/com/google/a2ui/schema/A2uiConstants.kt @@ -19,7 +19,7 @@ package com.google.a2ui.schema /** Central repository for A2UI protocol constants, aligned with the Python SDK. */ object A2uiConstants { const val A2UI_ASSET_PACKAGE = "com.google.a2ui.assets" - const val SERVER_TO_CLIENT_SCHEMA_KEY = "server_to_client" + const val AGENT_TO_RENDERER_SCHEMA_KEY = "agent_to_renderer" const val COMMON_TYPES_SCHEMA_KEY = "common_types" const val CATALOG_SCHEMA_KEY = "catalog" const val CATALOG_COMPONENTS_KEY = "components" @@ -36,6 +36,7 @@ object A2uiConstants { const val ACCEPTS_INLINE_CATALOGS_KEY = "acceptsInlineCatalogs" const val A2UI_CLIENT_CAPABILITIES_KEY = "a2uiClientCapabilities" + const val A2UI_RENDERER_CAPABILITIES_KEY = "a2uiRendererCapabilities" const val BASE_SCHEMA_URL = "https://a2ui.org/" const val INLINE_CATALOG_NAME = "inline" @@ -43,6 +44,7 @@ object A2uiConstants { const val VERSION_0_8 = "0.8" const val VERSION_0_9 = "0.9" const val VERSION_0_9_1 = "0.9.1" + const val VERSION_1_0 = "1.0" const val A2UI_OPEN_TAG = "" const val A2UI_CLOSE_TAG = "" diff --git a/kotlin/agent_sdk_legacy/src/main/kotlin/com/google/a2ui/schema/A2uiSchemaManager.kt b/kotlin/agent_sdk_legacy/src/main/kotlin/com/google/a2ui/schema/A2uiSchemaManager.kt index b72cdaeb56..beecb9b10d 100644 --- a/kotlin/agent_sdk_legacy/src/main/kotlin/com/google/a2ui/schema/A2uiSchemaManager.kt +++ b/kotlin/agent_sdk_legacy/src/main/kotlin/com/google/a2ui/schema/A2uiSchemaManager.kt @@ -26,12 +26,13 @@ import kotlinx.serialization.json.jsonPrimitive /** Represents the supported A2UI specification versions. */ enum class A2uiVersion( val value: String, - val serverToClientSchemaPath: String, + val agentToRendererSchemaPath: String, val commonTypesSchemaPath: String? = null, ) { VERSION_0_8(A2uiConstants.VERSION_0_8, "server_to_client.json"), VERSION_0_9(A2uiConstants.VERSION_0_9, "server_to_client.json", "common_types.json"), VERSION_0_9_1(A2uiConstants.VERSION_0_9_1, "server_to_client.json", "common_types.json"), + VERSION_1_0(A2uiConstants.VERSION_1_0, "agent_to_renderer.json", "common_types.json"), } /** @@ -59,7 +60,7 @@ constructor( private val schemaModifiers: List<(JsonObject) -> JsonObject> = emptyList(), ) : InferenceStrategy { - private val serverToClientSchema: JsonObject + private val agentToRendererSchema: JsonObject private val commonTypesSchema: JsonObject private val supportedCatalogs = mutableListOf() private val catalogExamplePaths = mutableMapOf() @@ -72,11 +73,11 @@ constructor( get() = supportedCatalogs.map { it.catalogId } init { - serverToClientSchema = + agentToRendererSchema = applyModifiers( SchemaResourceLoader.loadFromBundledResource( version.value, - version.serverToClientSchemaPath, + version.agentToRendererSchemaPath, ) ?: JsonObject(emptyMap()) ) @@ -94,7 +95,7 @@ constructor( version = version, name = config.name, catalogSchema = catalogSchema, - serverToClientSchema = serverToClientSchema, + agentToRendererSchema = agentToRendererSchema, commonTypesSchema = commonTypesSchema, ) supportedCatalogs.add(catalog) @@ -105,24 +106,24 @@ constructor( private fun applyModifiers(schema: JsonObject): JsonObject = schemaModifiers.fold(schema) { current, modifier -> modifier(current) } - private fun selectCatalog(clientUiCapabilities: JsonObject?): A2uiCatalog { + private fun selectCatalog(rendererUiCapabilities: JsonObject?): A2uiCatalog { check(supportedCatalogs.isNotEmpty()) { "No supported catalogs found." } - if (clientUiCapabilities == null) return supportedCatalogs.first() + if (rendererUiCapabilities == null) return supportedCatalogs.first() val inlineCatalogs = - (clientUiCapabilities[A2uiConstants.INLINE_CATALOGS_KEY] as? JsonArray)?.mapNotNull { + (rendererUiCapabilities[A2uiConstants.INLINE_CATALOGS_KEY] as? JsonArray)?.mapNotNull { it as? JsonObject } ?: emptyList() - val clientSupportedCatalogIds = - (clientUiCapabilities[A2uiConstants.SUPPORTED_CATALOG_IDS_KEY] as? JsonArray)?.mapNotNull { + val rendererSupportedCatalogIds = + (rendererUiCapabilities[A2uiConstants.SUPPORTED_CATALOG_IDS_KEY] as? JsonArray)?.mapNotNull { it.jsonPrimitive.content } ?: emptyList() if (!acceptsInlineCatalogs && inlineCatalogs.isNotEmpty()) { throw A2uiCatalogException( - "Inline catalog '${A2uiConstants.INLINE_CATALOGS_KEY}' is provided in client UI capabilities. However, the agent does not accept inline catalogs." + "Inline catalog '${A2uiConstants.INLINE_CATALOGS_KEY}' is provided in renderer UI capabilities. However, the agent does not accept inline catalogs." ) } @@ -130,9 +131,9 @@ constructor( // Determine the base catalog: use supportedCatalogIds if provided, // otherwise fall back to the agent's default catalog. var baseCatalog = supportedCatalogs.first() - if (clientSupportedCatalogIds.isNotEmpty()) { + if (rendererSupportedCatalogIds.isNotEmpty()) { val agentSupportedCatalogs = supportedCatalogs.associateBy { it.catalogId } - for (cscid in clientSupportedCatalogIds) { + for (cscid in rendererSupportedCatalogIds) { agentSupportedCatalogs[cscid]?.let { baseCatalog = it } if (baseCatalog != supportedCatalogs.first()) break } @@ -157,36 +158,36 @@ constructor( version = version, name = A2uiConstants.INLINE_CATALOG_NAME, catalogSchema = mergedSchema, - serverToClientSchema = serverToClientSchema, + agentToRendererSchema = agentToRendererSchema, commonTypesSchema = commonTypesSchema, ) } - if (clientSupportedCatalogIds.isEmpty()) return supportedCatalogs.first() + if (rendererSupportedCatalogIds.isEmpty()) return supportedCatalogs.first() val agentSupportedCatalogs = supportedCatalogs.associateBy { it.catalogId } - for (cscid in clientSupportedCatalogIds) { + for (cscid in rendererSupportedCatalogIds) { agentSupportedCatalogs[cscid]?.let { return it } } throw A2uiCatalogException( - "No client-supported catalog found on the agent side. Agent-supported catalogs are: ${supportedCatalogs.map { it.catalogId }}" + "No client-supported catalog found (also referred to as renderer-supported) on the agent side. Agent-supported catalogs are: ${supportedCatalogs.map { it.catalogId }}" ) } /** - * Resolves the desired catalog based on the client capabilities, returning it with pruned unused + * Resolves the desired catalog based on the renderer capabilities, returning it with pruned unused * components and messages. */ @JvmOverloads fun getSelectedCatalog( - clientUiCapabilities: JsonObject? = null, + rendererUiCapabilities: JsonObject? = null, allowedComponents: List = emptyList(), allowedMessages: List = emptyList(), ): A2uiCatalog = - selectCatalog(clientUiCapabilities).withPruning(allowedComponents, allowedMessages) + selectCatalog(rendererUiCapabilities).withPruning(allowedComponents, allowedMessages) /** Renders LLM examples for a given catalog, loaded from its configured examples path. */ @JvmOverloads @@ -199,7 +200,7 @@ constructor( roleDescription: String, workflowDescription: String, uiDescription: String, - clientUiCapabilities: JsonObject?, + rendererUiCapabilities: JsonObject?, allowedComponents: List, allowedMessages: List, includeSchema: Boolean, @@ -218,7 +219,7 @@ constructor( } val selectedCatalog = - getSelectedCatalog(clientUiCapabilities, allowedComponents, allowedMessages) + getSelectedCatalog(rendererUiCapabilities, allowedComponents, allowedMessages) if (includeSchema) { parts.add(selectedCatalog.renderAsLlmInstructions()) diff --git a/kotlin/agent_sdk_legacy/src/main/kotlin/com/google/a2ui/schema/Catalog.kt b/kotlin/agent_sdk_legacy/src/main/kotlin/com/google/a2ui/schema/Catalog.kt index c5c47ed771..a5d9fa027d 100644 --- a/kotlin/agent_sdk_legacy/src/main/kotlin/com/google/a2ui/schema/Catalog.kt +++ b/kotlin/agent_sdk_legacy/src/main/kotlin/com/google/a2ui/schema/Catalog.kt @@ -99,7 +99,7 @@ internal fun resolveExamplesPath(path: String?): String? { data class A2uiCatalog( @JvmField val version: A2uiVersion, @JvmField val name: String, - @JvmField val serverToClientSchema: JsonObject, + @JvmField val agentToRendererSchema: JsonObject, @JvmField val commonTypesSchema: JsonObject, @JvmField val catalogSchema: JsonObject, @JvmField val customCuttableKeys: Set? = null, @@ -127,7 +127,7 @@ data class A2uiCatalog( * Returns a new catalog with pruned components and messages. * * @param allowedComponents List of component names to include. - * @param allowedMessages List of message names to include in serverToClientSchema. + * @param allowedMessages List of message names to include in agentToRendererSchema. * @return A copy of the catalog with pruned components and messages. */ fun withPruning( @@ -170,7 +170,7 @@ data class A2uiCatalog( private fun withPrunedMessages(allowedMessages: List): A2uiCatalog { if (allowedMessages.isEmpty()) return this - val s2cCopy = serverToClientSchema.toMutableMap() + val s2cCopy = agentToRendererSchema.toMutableMap() if (version == A2uiVersion.VERSION_0_8) { (s2cCopy["properties"] as? JsonObject)?.let { props -> @@ -201,7 +201,7 @@ data class A2uiCatalog( } } - return copy(serverToClientSchema = JsonObject(s2cCopy)) + return copy(agentToRendererSchema = JsonObject(s2cCopy)) } /** Returns a new catalog with unused common types pruned from the schema. */ @@ -211,7 +211,7 @@ data class A2uiCatalog( val externalRefs = mutableSetOf() collectRefs(catalogSchema, externalRefs) - collectRefs(serverToClientSchema, externalRefs) + collectRefs(agentToRendererSchema, externalRefs) val prefix = "common_types.json#/\$defs/" val rootDefs = @@ -300,8 +300,9 @@ data class A2uiCatalog( appendLine() val jsonFmt = Json - appendLine("### Server To Client Schema:") - appendLine(jsonFmt.encodeToString(JsonElement.serializer(), serverToClientSchema)) + val header = if (version == A2uiVersion.VERSION_1_0) "### Agent To Renderer Schema:" else "### Server To Client Schema:" + appendLine(header) + appendLine(jsonFmt.encodeToString(JsonElement.serializer(), agentToRendererSchema)) val defs = commonTypesSchema["\$defs"] as? JsonObject if (!defs.isNullOrEmpty()) { diff --git a/kotlin/agent_sdk_legacy/src/main/kotlin/com/google/a2ui/schema/TopologyAnalyzer.kt b/kotlin/agent_sdk_legacy/src/main/kotlin/com/google/a2ui/schema/TopologyAnalyzer.kt index c2f7a8f6c5..f1c6d07f9b 100644 --- a/kotlin/agent_sdk_legacy/src/main/kotlin/com/google/a2ui/schema/TopologyAnalyzer.kt +++ b/kotlin/agent_sdk_legacy/src/main/kotlin/com/google/a2ui/schema/TopologyAnalyzer.kt @@ -65,7 +65,7 @@ internal object TopologyAnalyzer { private fun extractComponents(catalog: A2uiCatalog): JsonObject? { if (catalog.version == A2uiVersion.VERSION_0_8) { try { - val s2c = catalog.serverToClientSchema + val s2c = catalog.agentToRendererSchema val props = s2c[PROP_PROPERTIES] as? JsonObject if (props != null && "surfaceUpdate" in props) { val su = (props["surfaceUpdate"] as? JsonObject)?.get(PROP_PROPERTIES) as? JsonObject @@ -82,7 +82,7 @@ internal object TopologyAnalyzer { } } } catch (e: Exception) { - logger.severe { "Unable to extract components from serverToClientSchema: ${e.message}" } + logger.severe { "Unable to extract components from agentToRendererSchema: ${e.message}" } } } return catalog.catalogSchema[A2uiConstants.CATALOG_COMPONENTS_KEY] as? JsonObject diff --git a/kotlin/agent_sdk_legacy/src/main/kotlin/com/google/a2ui/schema/Validator.kt b/kotlin/agent_sdk_legacy/src/main/kotlin/com/google/a2ui/schema/Validator.kt index 2eb3fe9e44..70caf9d230 100644 --- a/kotlin/agent_sdk_legacy/src/main/kotlin/com/google/a2ui/schema/Validator.kt +++ b/kotlin/agent_sdk_legacy/src/main/kotlin/com/google/a2ui/schema/Validator.kt @@ -107,7 +107,7 @@ constructor( } private fun bundle0_8Schemas(): JsonObject { - if (catalog.serverToClientSchema.isEmpty()) return JsonObject(emptyMap()) + if (catalog.agentToRendererSchema.isEmpty()) return JsonObject(emptyMap()) val sourceProperties = mutableMapOf() val catalogSchema = catalog.catalogSchema @@ -121,7 +121,7 @@ constructor( } } - val (bundled) = injectAdditionalProperties(catalog.serverToClientSchema, sourceProperties) + val (bundled) = injectAdditionalProperties(catalog.agentToRendererSchema, sourceProperties) return bundled as JsonObject } @@ -131,7 +131,7 @@ constructor( fullSchema[KEY_DOLLAR_SCHEMA] = JsonPrimitive(SCHEMA_DRAFT_2020_12) val baseUri = - catalog.serverToClientSchema[KEY_DOLLAR_ID]?.jsonPrimitive?.content + catalog.agentToRendererSchema[KEY_DOLLAR_ID]?.jsonPrimitive?.content ?: A2uiConstants.BASE_SCHEMA_URL val baseDirUri = baseUri.substringBeforeLast("/") val commonTypesUri = "$baseDirUri/$FILE_COMMON_TYPES" @@ -156,7 +156,7 @@ constructor( private fun build0_9Validator(): Schema { val fullSchema = - SchemaResourceLoader.wrapAsJsonArray(catalog.serverToClientSchema).toMutableMap() + SchemaResourceLoader.wrapAsJsonArray(catalog.agentToRendererSchema).toMutableMap() fullSchema[KEY_DOLLAR_SCHEMA] = JsonPrimitive(SCHEMA_DRAFT_2020_12) val jsonFmt = Json { prettyPrint = false } @@ -304,7 +304,7 @@ constructor( private fun getSubValidator(defName: String): Schema { return subValidators.getOrPut(defName) { val defs = - catalog.serverToClientSchema["\$defs"] as? JsonObject + catalog.agentToRendererSchema["\$defs"] as? JsonObject ?: throw A2uiValidationException("No \$defs found in schema") val subSchema = defs[defName] as? JsonObject diff --git a/kotlin/agent_sdk_legacy/src/test/kotlin/com/google/a2ui/conformance/AdkExtensionsConformanceTest.kt b/kotlin/agent_sdk_legacy/src/test/kotlin/com/google/a2ui/conformance/AdkExtensionsConformanceTest.kt index 064579e67d..56bbddec5e 100644 --- a/kotlin/agent_sdk_legacy/src/test/kotlin/com/google/a2ui/conformance/AdkExtensionsConformanceTest.kt +++ b/kotlin/agent_sdk_legacy/src/test/kotlin/com/google/a2ui/conformance/AdkExtensionsConformanceTest.kt @@ -19,7 +19,7 @@ package com.google.a2ui.conformance import com.fasterxml.jackson.databind.ObjectMapper import com.fasterxml.jackson.dataformat.yaml.YAMLFactory import com.google.a2ui.adk.a2a_extension.A2uiEventConverter -import com.google.a2ui.adk.a2a_extension.SendA2uiToClientToolset +import com.google.a2ui.adk.a2a_extension.SendA2uiToRendererToolset import com.google.a2ui.schema.A2uiCatalog import com.google.a2ui.schema.A2uiVersion import com.google.adk.a2a.converters.EventConverter @@ -168,7 +168,7 @@ class AdkExtensionsConformanceTest { A2uiCatalog( version = A2uiVersion.VERSION_0_8, name = "dummy", - serverToClientSchema = serverToClientSchema, + agentToRendererSchema = serverToClientSchema, commonTypesSchema = JsonObject(emptyMap()), catalogSchema = catalogSchema, ) @@ -176,7 +176,7 @@ class AdkExtensionsConformanceTest { val mockContext = mockk(relaxed = true) val mockToolContext = mockk(relaxed = true) - val toolset = SendA2uiToClientToolset.create(true, dummyCatalog, "") + val toolset = SendA2uiToRendererToolset.create(true, dummyCatalog, "") val tool = toolset.getTools(mockContext).blockingFirst() val result = tool.runAsync(toolArgs, mockToolContext).blockingGet() @@ -185,18 +185,18 @@ class AdkExtensionsConformanceTest { val expectSuccess = expect["success"] as Boolean if (expectSuccess) { - assertTrue(result.containsKey(SendA2uiToClientToolset.VALIDATED_A2UI_JSON_KEY)) + assertTrue(result.containsKey(SendA2uiToRendererToolset.VALIDATED_A2UI_JSON_KEY)) val containsValidatedJson = expect["contains_validated_json"] as? Boolean ?: false if (containsValidatedJson) { val validatedPayload = - result[SendA2uiToClientToolset.VALIDATED_A2UI_JSON_KEY].toString() + result[SendA2uiToRendererToolset.VALIDATED_A2UI_JSON_KEY].toString() assertTrue(validatedPayload.contains("beginRendering")) } } else { - assertTrue(result.containsKey(SendA2uiToClientToolset.TOOL_ERROR_KEY)) + assertTrue(result.containsKey(SendA2uiToRendererToolset.TOOL_ERROR_KEY)) val errorContains = expect["error_contains"] as? String if (errorContains != null) { - val errorMsg = result[SendA2uiToClientToolset.TOOL_ERROR_KEY] as String + val errorMsg = result[SendA2uiToRendererToolset.TOOL_ERROR_KEY] as String assertTrue(errorMsg.contains(errorContains)) } } diff --git a/kotlin/agent_sdk_legacy/src/test/kotlin/com/google/a2ui/conformance/ConformanceTest.kt b/kotlin/agent_sdk_legacy/src/test/kotlin/com/google/a2ui/conformance/ConformanceTest.kt index b2fb99a48e..eb7d370864 100644 --- a/kotlin/agent_sdk_legacy/src/test/kotlin/com/google/a2ui/conformance/ConformanceTest.kt +++ b/kotlin/agent_sdk_legacy/src/test/kotlin/com/google/a2ui/conformance/ConformanceTest.kt @@ -242,7 +242,7 @@ class ConformanceTest { A2uiCatalog( version = version, name = TEST_CATALOG_NAME, - serverToClientSchema = s2cSchema, + agentToRendererSchema = s2cSchema, commonTypesSchema = commonTypesSchema, catalogSchema = catalogSchema, customCuttableKeys = customCuttableKeys, @@ -322,7 +322,7 @@ class ConformanceTest { } if (expect.containsKey("s2c_schema")) { val expectSchema = jsonMapper.writeValueAsString(expect["s2c_schema"]) - assertEquals(Json.parseToJsonElement(expectSchema), pruned.serverToClientSchema) + assertEquals(Json.parseToJsonElement(expectSchema), pruned.agentToRendererSchema) } if (expect.containsKey("common_types_schema")) { val expectSchema = jsonMapper.writeValueAsString(expect["common_types_schema"]) @@ -510,7 +510,7 @@ class ConformanceTest { roleDescription = role, workflowDescription = workflow, uiDescription = uiDesc, - clientUiCapabilities = capsJson, + rendererUiCapabilities = capsJson, allowedComponents = allowedComponents, includeSchema = includeSchema, includeExamples = includeExamples, diff --git a/kotlin/agent_sdk_legacy/src/test/kotlin/com/google/a2ui/schema/ValidatorTest.kt b/kotlin/agent_sdk_legacy/src/test/kotlin/com/google/a2ui/schema/ValidatorTest.kt index 75520876e7..91a47b34b6 100644 --- a/kotlin/agent_sdk_legacy/src/test/kotlin/com/google/a2ui/schema/ValidatorTest.kt +++ b/kotlin/agent_sdk_legacy/src/test/kotlin/com/google/a2ui/schema/ValidatorTest.kt @@ -162,7 +162,7 @@ class ValidatorTest { A2uiCatalog( version = A2uiVersion.VERSION_0_9, name = "standard", - serverToClientSchema = s2cSchema, + agentToRendererSchema = s2cSchema, commonTypesSchema = JsonObject(emptyMap()), catalogSchema = catalogSchema, ) @@ -225,7 +225,7 @@ class ValidatorTest { A2uiCatalog( version = A2uiVersion.VERSION_0_8, name = "test", - serverToClientSchema = JsonObject(mapOf("type" to JsonPrimitive("object"))), + agentToRendererSchema = JsonObject(mapOf("type" to JsonPrimitive("object"))), commonTypesSchema = JsonObject(emptyMap()), catalogSchema = JsonObject(mapOf(A2uiConstants.CATALOG_ID_KEY to JsonPrimitive("test_id"))), ) diff --git a/mkdocs.yaml b/mkdocs.yaml index a1118ec4d0..50debbb023 100644 --- a/mkdocs.yaml +++ b/mkdocs.yaml @@ -51,7 +51,7 @@ nav: - Transports: concepts/transports.md - Actions: concepts/actions.md - Guides: - - Client Setup: guides/client-setup.md + - Renderer Setup: guides/renderer-setup.md - Agent Development: guides/agent-development.md - Use A2UI with Any Agent Framework & Harness: guides/a2ui-with-any-agent-framework.md - Renderer Development: guides/renderer-development.md @@ -65,8 +65,8 @@ nav: - Reference: - Component Gallery: reference/components.md - Message Reference: reference/messages.md - - Renderers (Clients): reference/renderers.md - - Agents (Server-side): reference/agents.md + - Renderers: reference/renderers.md + - Agents: reference/agents.md - Specifications: - v1.0 (Candidate): - A2UI Protocol: specification/v1.0-a2ui.md diff --git a/package.json b/package.json index dcf989b9f9..ea2a24c756 100644 --- a/package.json +++ b/package.json @@ -8,11 +8,11 @@ "renderers/lit/*", "renderers/markdown/*", "renderers/react/*", - "samples/client/angular", - "samples/client/angular/projects/*", - "samples/client/lit", - "samples/client/lit/*", - "samples/client/react/*", + "samples/renderer/angular", + "samples/renderer/angular/projects/*", + "samples/renderer/lit", + "samples/renderer/lit/*", + "samples/renderer/react/*", "samples/personalized_learning", "specification/*/eval", "specification/*/test", diff --git a/pubspec.yaml b/pubspec.yaml index 9e07fd90a6..6c43f7e255 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -21,8 +21,8 @@ environment: flutter: ">=3.35.7 <4.0.0" workspace: - - samples/client/flutter/restaurant_finder/app - - samples/client/flutter/restaurant_finder/e2e_test + - samples/renderer/flutter/restaurant_finder/app + - samples/renderer/flutter/restaurant_finder/e2e_test flutter: uses-material-design: true diff --git a/renderers/angular/a2ui_explorer/scripts/closure-compiler/externs/a2ui_web_core_v0_9.externs.js b/renderers/angular/a2ui_explorer/scripts/closure-compiler/externs/a2ui_web_core_v0_9.externs.js index 1a9c81f288..9d4311d2cc 100644 --- a/renderers/angular/a2ui_explorer/scripts/closure-compiler/externs/a2ui_web_core_v0_9.externs.js +++ b/renderers/angular/a2ui_explorer/scripts/closure-compiler/externs/a2ui_web_core_v0_9.externs.js @@ -87,7 +87,7 @@ function DeleteSurfaceMessageExterns() {} /** @type {?} */ DeleteSurfaceMessageExterns.prototype.deleteSurface; /** - * Externs for `Action` and `A2uiClientAction` interfaces (`renderers/web_core/src/v0_9/schema/common-types.ts`, `renderers/web_core/src/v0_9/schema/client-to-server.ts`). + * Externs for `Action` and `A2uiRendererAction` interfaces (`renderers/web_core/src/v0_9/schema/common-types.ts`, `renderers/web_core/src/v0_9/schema/client-to-server.ts`). * @record * @struct */ diff --git a/renderers/angular/a2ui_explorer/src/app/action-dispatcher.service.ts b/renderers/angular/a2ui_explorer/src/app/action-dispatcher.service.ts index b6145a45e2..5d9d9e883a 100644 --- a/renderers/angular/a2ui_explorer/src/app/action-dispatcher.service.ts +++ b/renderers/angular/a2ui_explorer/src/app/action-dispatcher.service.ts @@ -16,14 +16,14 @@ import {Injectable} from '@angular/core'; import {Subject} from 'rxjs'; -import {A2uiClientAction} from '@a2ui/web_core/v0_9'; +import {A2uiRendererAction} from '@a2ui/web_core/v0_9'; @Injectable({providedIn: 'root'}) export class ActionDispatcher { - private action$ = new Subject(); + private action$ = new Subject(); actions = this.action$.asObservable(); - dispatch(action: A2uiClientAction) { + dispatch(action: A2uiRendererAction) { this.action$.next(action); } } diff --git a/renderers/angular/a2ui_explorer/src/app/agent-stub-v08.service.ts b/renderers/angular/a2ui_explorer/src/app/agent-stub-v08.service.ts index 75f2d70685..823d7ace61 100644 --- a/renderers/angular/a2ui_explorer/src/app/agent-stub-v08.service.ts +++ b/renderers/angular/a2ui_explorer/src/app/agent-stub-v08.service.ts @@ -16,7 +16,7 @@ import {Injectable, signal, computed} from '@angular/core'; import {MessageProcessor as MessageProcessorV08, Theme as ThemeV08} from '@a2ui/angular/v0_8'; -import {A2uiClientAction} from '@a2ui/web_core/v0_9'; +import {A2uiRendererAction} from '@a2ui/web_core/v0_9'; import {ServerToClientMessage} from 'src/v0_8/types'; import {AgentStubService} from './agent-stub.service'; import {UserAction} from '@a2ui/web_core/types/client-event'; @@ -39,7 +39,7 @@ interface UpdatePropertyContext { providedIn: 'root', }) export class AgentStubV08Service extends AgentStubService { - override eventsLog = signal>([]); + override eventsLog = signal>([]); override surfaceId = signal('demo-surface', {equal: () => false}); override currentCreateSurfaceMessage = signal(null); private actionSub?: {unsubscribe: () => void}; @@ -124,7 +124,7 @@ export class AgentStubV08Service extends AgentStubService { }, 0); } - private userActionToClientAction(action: UserAction): A2uiClientAction { + private userActionToClientAction(action: UserAction): A2uiRendererAction { return { name: action.name, surfaceId: action.surfaceId, diff --git a/renderers/angular/a2ui_explorer/src/app/agent-stub-v09.service.ts b/renderers/angular/a2ui_explorer/src/app/agent-stub-v09.service.ts index 196e107354..3aebbbfb9d 100644 --- a/renderers/angular/a2ui_explorer/src/app/agent-stub-v09.service.ts +++ b/renderers/angular/a2ui_explorer/src/app/agent-stub-v09.service.ts @@ -16,7 +16,7 @@ import {Injectable, signal} from '@angular/core'; import {A2uiRendererService} from '@a2ui/angular/v0_9'; -import {A2uiClientAction, A2uiMessage, CreateSurfaceMessage} from '@a2ui/web_core/v0_9'; +import {A2uiRendererAction, A2uiMessage, CreateSurfaceMessage} from '@a2ui/web_core/v0_9'; import {ActionDispatcher} from './action-dispatcher.service'; import {AgentStubService} from './agent-stub.service'; @@ -48,7 +48,7 @@ interface SubmitFormContext { export class AgentStubV09Service extends AgentStubService { override dataModel = signal>({}); override surfaceId = signal('demo-surface', {equal: () => false}); - override eventsLog = signal>([]); + override eventsLog = signal>([]); override currentCreateSurfaceMessage = signal(null); private actionSub?: {unsubscribe: () => void}; private dataModelSub?: {unsubscribe: () => void}; @@ -60,7 +60,7 @@ export class AgentStubV09Service extends AgentStubService { super(); } - private handleAction(action: A2uiClientAction) { + private handleAction(action: A2uiRendererAction) { console.log('[AgentStubV09] handleAction action:', action); setTimeout(() => { diff --git a/renderers/angular/a2ui_explorer/src/app/agent-stub.service.ts b/renderers/angular/a2ui_explorer/src/app/agent-stub.service.ts index 2be0e12c1a..f00b910606 100644 --- a/renderers/angular/a2ui_explorer/src/app/agent-stub.service.ts +++ b/renderers/angular/a2ui_explorer/src/app/agent-stub.service.ts @@ -15,14 +15,14 @@ */ import {WritableSignal, Signal} from '@angular/core'; -import {A2uiClientAction, A2uiMessage, CreateSurfaceMessage} from '@a2ui/web_core/v0_9'; +import {A2uiRendererAction, A2uiMessage, CreateSurfaceMessage} from '@a2ui/web_core/v0_9'; import {ServerToClientMessage} from 'src/v0_8/types'; /** * Abstract base class for agent stub services. */ export abstract class AgentStubService { - abstract eventsLog: WritableSignal>; + abstract eventsLog: WritableSignal>; abstract dataModel: Signal>; abstract surfaceId: Signal; abstract currentCreateSurfaceMessage: Signal< diff --git a/renderers/angular/a2ui_explorer/src/app/demo.component.ts b/renderers/angular/a2ui_explorer/src/app/demo.component.ts index 6ecb9cda93..837ca514d2 100644 --- a/renderers/angular/a2ui_explorer/src/app/demo.component.ts +++ b/renderers/angular/a2ui_explorer/src/app/demo.component.ts @@ -32,7 +32,7 @@ import {SurfaceComponent as SurfaceComponentV09} from '@a2ui/angular/v0_9'; import {provideMarkdownRenderer, Surface as SurfaceV08} from '@a2ui/angular/v0_8'; import {AngularCatalog} from '@a2ui/angular/v0_9'; import {DemoCatalog} from './demo-catalog'; -import {A2uiClientAction} from '@a2ui/web_core/v0_9'; +import {A2uiRendererAction} from '@a2ui/web_core/v0_9'; import {A2uiExample, A2UI_VERSION, A2UI_EXAMPLES, Version} from './types'; import {ActionDispatcher} from './action-dispatcher.service'; import {Catalog as CatalogV08, DEFAULT_CATALOG as DEFAULT_CATALOG_V08} from '@a2ui/angular/v0_8'; @@ -577,7 +577,7 @@ import {Catalog as CatalogV08, DEFAULT_CATALOG as DEFAULT_CATALOG_V08} from '@a2 provide: A2UI_RENDERER_CONFIG, useFactory: (catalog: AngularCatalog, dispatcher: ActionDispatcher) => ({ catalogs: [catalog], - actionHandler: (action: A2uiClientAction) => dispatcher.dispatch(action), + actionHandler: (action: A2uiRendererAction) => dispatcher.dispatch(action), }), deps: [AngularCatalog, ActionDispatcher], }, @@ -677,7 +677,7 @@ export class DemoComponent implements OnInit, OnDestroy { } /** Gets a display string for the action type. */ - getActionType(action: A2uiClientAction): string { + getActionType(action: A2uiRendererAction): string { return action.name || 'Action'; } diff --git a/renderers/angular/src/v0_9/core/a2ui-renderer.service.ts b/renderers/angular/src/v0_9/core/a2ui-renderer.service.ts index 1e3d96c07c..d5f90d26de 100644 --- a/renderers/angular/src/v0_9/core/a2ui-renderer.service.ts +++ b/renderers/angular/src/v0_9/core/a2ui-renderer.service.ts @@ -20,7 +20,7 @@ import { SurfaceGroupModel, ActionListener as ActionHandler, A2uiMessage, - A2uiClientAction as Action, + A2uiRendererAction as Action, } from '@a2ui/web_core/v0_9'; import {AngularComponentImplementation, AngularCatalog} from '../catalog/types'; import {initializeAngularReactivity} from './reactivity'; diff --git a/renderers/lit/a2ui_explorer/README.md b/renderers/lit/a2ui_explorer/README.md index faf99f116a..95cc0c05c6 100644 --- a/renderers/lit/a2ui_explorer/README.md +++ b/renderers/lit/a2ui_explorer/README.md @@ -26,7 +26,7 @@ For more details on building the renderers, see: 1. **Navigate to this directory**: ```bash - cd samples/client/lit/gallery_v0_9 + cd samples/renderer/lit/gallery_v0_9 ``` 2. **Run the development server**: diff --git a/renderers/lit/a2ui_explorer/src/local-gallery.ts b/renderers/lit/a2ui_explorer/src/local-gallery.ts index 7397532c1a..e05bee5ca5 100644 --- a/renderers/lit/a2ui_explorer/src/local-gallery.ts +++ b/renderers/lit/a2ui_explorer/src/local-gallery.ts @@ -17,7 +17,7 @@ import {LitElement, html, nothing} from 'lit'; import {provide} from '@lit/context'; import {customElement, state} from 'lit/decorators.js'; -import {MessageProcessor, A2uiMessage, A2uiClientAction} from '@a2ui/web_core/v0_9'; +import {MessageProcessor, A2uiMessage, A2uiRendererAction} from '@a2ui/web_core/v0_9'; import {basicCatalog, Context} from '@a2ui/lit/v0_9'; import {renderMarkdown} from '@a2ui/markdown-it'; import {getDemoItems, DemoItem} from './examples'; @@ -32,12 +32,12 @@ export class LocalGallery extends LitElement { @state() currentDataModelText = '{}'; @state() primaryColor = '#1177ee'; // Expose the dispatched actions log for automated integration tests to inspect - actionLog: A2uiClientAction[] = []; + actionLog: A2uiRendererAction[] = []; @provide({context: Context.markdown}) private markdownRenderer = renderMarkdown; - private processor = new MessageProcessor([basicCatalog], (action: A2uiClientAction) => { + private processor = new MessageProcessor([basicCatalog], (action: A2uiRendererAction) => { this.log(`Action dispatched: ${action.surfaceId}`, action); this.actionLog.push(action); }); diff --git a/renderers/lit/src/v0_9/tests/components/Button.test.ts b/renderers/lit/src/v0_9/tests/components/Button.test.ts index f5e1a25f66..7a5e3015d8 100644 --- a/renderers/lit/src/v0_9/tests/components/Button.test.ts +++ b/renderers/lit/src/v0_9/tests/components/Button.test.ts @@ -24,7 +24,7 @@ import { ComponentApi, SurfaceModel, Subscription, - A2uiClientAction, + A2uiRendererAction, } from '@a2ui/web_core/v0_9'; import type {A2uiBasicButtonElement} from '../../catalogs/basic/components/Button.js'; @@ -112,8 +112,8 @@ describe('Button Component', () => { assert.ok(button); assert.strictEqual(button.disabled, false); - const dispatched = {action: null as A2uiClientAction | null}; - subscription = surface.onAction.subscribe((action: A2uiClientAction) => { + const dispatched = {action: null as A2uiRendererAction | null}; + subscription = surface.onAction.subscribe((action: A2uiRendererAction) => { dispatched.action = action; }); diff --git a/renderers/react/a2ui_explorer/src/App.tsx b/renderers/react/a2ui_explorer/src/App.tsx index 09ae135ef4..e35280b424 100644 --- a/renderers/react/a2ui_explorer/src/App.tsx +++ b/renderers/react/a2ui_explorer/src/App.tsx @@ -15,7 +15,7 @@ */ import {useState, useEffect, useSyncExternalStore, useCallback, useRef} from 'react'; -import {MessageProcessor, type SurfaceModel, type A2uiClientAction} from '@a2ui/web_core/v0_9'; +import {MessageProcessor, type SurfaceModel, type A2uiRendererAction} from '@a2ui/web_core/v0_9'; import { basicCatalog, A2uiSurface, @@ -64,7 +64,7 @@ export interface AppProps { * Callback to intercept dispatched actions. * @internal @visibleForTesting */ - onAction?: (action: A2uiClientAction) => void; + onAction?: (action: A2uiRendererAction) => void; } /** @@ -74,7 +74,7 @@ interface LogEntry { /** ISO timestamp of when the action was intercepted. */ time: string; /** The intercepted client action object. */ - action: A2uiClientAction; + action: A2uiRendererAction; } export const App = ({initialExampleId, onAction}: AppProps) => { @@ -102,7 +102,7 @@ export const App = ({initialExampleId, onAction}: AppProps) => { } const newProcessor = new MessageProcessor( [basicCatalog], - async (action: A2uiClientAction) => { + async (action: A2uiRendererAction) => { setLogs(l => [...l, {time: new Date().toISOString(), action}]); if (onActionRef.current) { onActionRef.current(action); diff --git a/renderers/react/a2ui_explorer/tests/utils/test-utils.tsx b/renderers/react/a2ui_explorer/tests/utils/test-utils.tsx index d938f9b4c3..d25fa99ee9 100644 --- a/renderers/react/a2ui_explorer/tests/utils/test-utils.tsx +++ b/renderers/react/a2ui_explorer/tests/utils/test-utils.tsx @@ -17,7 +17,7 @@ import {act} from 'react'; import {createRoot, type Root} from 'react-dom/client'; import {App} from '../../src/App'; -import type {A2uiClientAction} from '@a2ui/web_core/v0_9'; +import type {A2uiRendererAction} from '@a2ui/web_core/v0_9'; /** Reference to the active React root instance used to render the App. */ let activeRoot: Root | null = null; @@ -33,7 +33,7 @@ const TEST_CONTAINER_ID = 'test-container'; */ export async function loadExample( filename: string, - onAction?: (action: A2uiClientAction) => void, + onAction?: (action: A2uiRendererAction) => void, ): Promise { // Clean up previous runs await cleanup(); diff --git a/renderers/web_core/src/v0_9/processing/message-processor.test.ts b/renderers/web_core/src/v0_9/processing/message-processor.test.ts index e432427aa5..7d1b97d114 100644 --- a/renderers/web_core/src/v0_9/processing/message-processor.test.ts +++ b/renderers/web_core/src/v0_9/processing/message-processor.test.ts @@ -33,9 +33,9 @@ describe('MessageProcessor', () => { }); }); - describe('getClientCapabilities', () => { - it('generates basic client capabilities with supportedCatalogIds', () => { - const caps = processor.getClientCapabilities(); + describe('getRendererCapabilities', () => { + it('generates basic renderer capabilities with supportedCatalogIds', () => { + const caps = processor.getRendererCapabilities(); assert.strictEqual(caps['v0.9']?.inlineCatalogs, undefined); assert.deepStrictEqual(caps, { 'v0.9': { @@ -54,7 +54,7 @@ describe('MessageProcessor', () => { const cat = new Catalog('cat-1', [buttonApi]); const proc = new MessageProcessor([cat]); - const caps = proc.getClientCapabilities({includeInlineCatalogs: true}); + const caps = proc.getRendererCapabilities({includeInlineCatalogs: true}); const inlineCat = caps['v0.9']?.inlineCatalogs?.[0]; assert.strictEqual(inlineCat?.catalogId, 'cat-1'); @@ -77,7 +77,7 @@ describe('MessageProcessor', () => { const cat = new Catalog('cat-ref', [customApi]); const proc = new MessageProcessor([cat]); - const caps = proc.getClientCapabilities({includeInlineCatalogs: true}); + const caps = proc.getRendererCapabilities({includeInlineCatalogs: true}); const titleSchema = caps['v0.9']?.inlineCatalogs?.[0].components?.Custom.allOf[1].properties.title; assert.ok(titleSchema); @@ -111,7 +111,7 @@ describe('MessageProcessor', () => { const cat = new Catalog('cat-full', [buttonApi], [addFn], themeSchema); const proc = new MessageProcessor([cat]); - const caps = proc.getClientCapabilities({includeInlineCatalogs: true}); + const caps = proc.getRendererCapabilities({includeInlineCatalogs: true}); const inlineCat = caps['v0.9']?.inlineCatalogs?.[0]; assert.strictEqual(inlineCat?.catalogId, 'cat-full'); // Verify Functions @@ -133,7 +133,7 @@ describe('MessageProcessor', () => { const compApi: ComponentApi = {name: 'EmptyComp', schema: z.object({})}; const cat = new Catalog('cat-empty', [compApi]); const proc = new MessageProcessor([cat]); - const caps = proc.getClientCapabilities({includeInlineCatalogs: true}); + const caps = proc.getRendererCapabilities({includeInlineCatalogs: true}); const inlineCat = caps['v0.9']?.inlineCatalogs?.[0]; assert.strictEqual(inlineCat?.catalogId, 'cat-empty'); assert.strictEqual(inlineCat.functions, undefined); @@ -155,7 +155,7 @@ describe('MessageProcessor', () => { }; const cat = new Catalog('cat-deep', [deepApi]); const proc = new MessageProcessor([cat]); - const caps = proc.getClientCapabilities({includeInlineCatalogs: true}); + const caps = proc.getRendererCapabilities({includeInlineCatalogs: true}); const properties = caps['v0.9']?.inlineCatalogs?.[0].components?.DeepComp.allOf[1].properties; assert.ok(properties); @@ -176,7 +176,7 @@ describe('MessageProcessor', () => { }; const cat = new Catalog('cat-edge', [edgeApi]); const proc = new MessageProcessor([cat]); - const caps = proc.getClientCapabilities({includeInlineCatalogs: true}); + const caps = proc.getRendererCapabilities({includeInlineCatalogs: true}); const properties = caps['v0.9']?.inlineCatalogs?.[0].components?.EdgeComp.allOf[1].properties; assert.ok(properties); @@ -201,7 +201,7 @@ describe('MessageProcessor', () => { const cat2 = new Catalog('cat-2', [], [addFn], themeSchema); const proc = new MessageProcessor([cat1, cat2]); - const caps = proc.getClientCapabilities({includeInlineCatalogs: true}); + const caps = proc.getRendererCapabilities({includeInlineCatalogs: true}); assert.strictEqual(caps['v0.9']?.inlineCatalogs?.length, 2); const inlineCat1 = caps['v0.9']?.inlineCatalogs?.[0]; @@ -248,7 +248,7 @@ describe('MessageProcessor', () => { assert.strictEqual(surface?.sendDataModel, true); }); - it('getClientDataModel filters surfaces correctly', () => { + it('getRendererDataModel filters surfaces correctly', () => { processor.processMessages([ { version: 'v0.9', @@ -276,7 +276,7 @@ describe('MessageProcessor', () => { }, ]); - const dataModel = processor.getClientDataModel(); + const dataModel = processor.getRendererDataModel(); assert.ok(dataModel); assert.strictEqual(dataModel.version, 'v0.9'); assert.deepStrictEqual(dataModel.surfaces, { @@ -285,21 +285,21 @@ describe('MessageProcessor', () => { assert.strictEqual((dataModel.surfaces as any).s2, undefined); }); - it('getClientDataModel returns undefined if no surfaces have sendDataModel enabled', () => { + it('getRendererDataModel returns undefined if no surfaces have sendDataModel enabled', () => { processor.processMessages([ { version: 'v0.9', createSurface: {surfaceId: 's1', catalogId: 'test-catalog'}, }, ]); - assert.strictEqual(processor.getClientDataModel(), undefined); + assert.strictEqual(processor.getRendererDataModel(), undefined); }); - it('uses configured processor version for getClientCapabilities and getClientDataModel', () => { + it('uses configured processor version for getRendererCapabilities and getRendererDataModel', () => { const v091Proc = new MessageProcessor([testCatalog], undefined, {version: 'v0.9.1'}); assert.strictEqual(v091Proc.version, 'v0.9.1'); - const caps = v091Proc.getClientCapabilities(); + const caps = v091Proc.getRendererCapabilities(); assert.ok(caps['v0.9.1']); assert.strictEqual(caps['v0.9'], undefined); @@ -309,7 +309,7 @@ describe('MessageProcessor', () => { createSurface: {surfaceId: 's1', catalogId: 'test-catalog', sendDataModel: true}, }, ]); - const dataModel = v091Proc.getClientDataModel(); + const dataModel = v091Proc.getRendererDataModel(); assert.ok(dataModel); assert.strictEqual(dataModel.version, 'v0.9.1'); }); diff --git a/renderers/web_core/src/v0_9/processing/message-processor.ts b/renderers/web_core/src/v0_9/processing/message-processor.ts index 594107e6a8..2f9ff805ff 100644 --- a/renderers/web_core/src/v0_9/processing/message-processor.ts +++ b/renderers/web_core/src/v0_9/processing/message-processor.ts @@ -28,9 +28,9 @@ import { UpdateDataModelMessage, DeleteSurfaceMessage, A2uiMessageListWrapper, -} from '../schema/server-to-client.js'; -import {A2uiClientCapabilities, InlineCatalog} from '../schema/client-capabilities.js'; -import {A2uiClientDataModel} from '../schema/client-to-server.js'; +} from '../schema/agent-to-renderer.js'; +import {A2uiRendererCapabilities, InlineCatalog} from '../schema/renderer-capabilities.js'; +import {A2uiRendererDataModel} from '../schema/renderer-to-agent.js'; import {A2uiStateError, A2uiValidationError} from '../errors.js'; /** @@ -79,12 +79,12 @@ export class MessageProcessor { } /** - * Generates the a2uiClientCapabilities object for the current processor. + * Generates the a2uiRendererCapabilities object for the current processor. * * @param options Configuration for capability generation. * @returns The capabilities object. */ - getClientCapabilities(options?: CapabilitiesOptions): A2uiClientCapabilities { + getRendererCapabilities(options?: CapabilitiesOptions): A2uiRendererCapabilities { // `version` can be used to fine-tune the returned capabilities. const version = options?.version ?? this.version; const versionCaps: any = { @@ -95,7 +95,7 @@ export class MessageProcessor { versionCaps.inlineCatalogs = this.catalogs.map(c => this.generateInlineCatalog(c)); } - return {[version]: versionCaps} as A2uiClientCapabilities; + return {[version]: versionCaps} as A2uiRendererCapabilities; } private generateInlineCatalog(catalog: Catalog): InlineCatalog { @@ -195,7 +195,9 @@ export class MessageProcessor { /** * Returns the aggregated data model for all surfaces that have 'sendDataModel' enabled. */ - getClientDataModel(version: 'v0.9' | 'v0.9.1' = this.version): A2uiClientDataModel | undefined { + getRendererDataModel( + version: 'v0.9' | 'v0.9.1' = this.version, + ): A2uiRendererDataModel | undefined { const surfaces: Record = {}; for (const surface of this.model.surfacesMap.values()) { diff --git a/renderers/web_core/src/v0_9/schema/server-to-client.ts b/renderers/web_core/src/v0_9/schema/agent-to-renderer.ts similarity index 96% rename from renderers/web_core/src/v0_9/schema/server-to-client.ts rename to renderers/web_core/src/v0_9/schema/agent-to-renderer.ts index 15689dcd8d..9e589644d0 100644 --- a/renderers/web_core/src/v0_9/schema/server-to-client.ts +++ b/renderers/web_core/src/v0_9/schema/agent-to-renderer.ts @@ -34,7 +34,7 @@ export const CreateSurfaceMessageSchema = z sendDataModel: z .boolean() .optional() - .describe('If true, the client will send the full data model.'), + .describe('If true, the renderer will send the full data model.'), }) .strict(), }) @@ -126,7 +126,7 @@ export const A2uiMessageSchema = z.union([ DeleteSurfaceMessageSchema, ]); -/** A message sent from the A2UI server to the client. */ +/** A message sent from the A2UI agent to the renderer. */ export type A2uiMessage = | CreateSurfaceMessage | UpdateComponentsMessage diff --git a/renderers/web_core/src/v0_9/schema/index.ts b/renderers/web_core/src/v0_9/schema/index.ts index 294913a032..5aca0b7419 100644 --- a/renderers/web_core/src/v0_9/schema/index.ts +++ b/renderers/web_core/src/v0_9/schema/index.ts @@ -15,6 +15,6 @@ */ export * from './common-types.js'; -export * from './server-to-client.js'; -export * from './client-capabilities.js'; -export * from './client-to-server.js'; +export * from './agent-to-renderer.js'; +export * from './renderer-capabilities.js'; +export * from './renderer-to-agent.js'; diff --git a/renderers/web_core/src/v0_9/schema/client-capabilities.ts b/renderers/web_core/src/v0_9/schema/renderer-capabilities.ts similarity index 88% rename from renderers/web_core/src/v0_9/schema/client-capabilities.ts rename to renderers/web_core/src/v0_9/schema/renderer-capabilities.ts index 78fddf7a94..1d0f5ac369 100644 --- a/renderers/web_core/src/v0_9/schema/client-capabilities.ts +++ b/renderers/web_core/src/v0_9/schema/renderer-capabilities.ts @@ -32,7 +32,7 @@ export interface FunctionDefinition { } /** - * Defines a catalog inline for the a2uiClientCapabilities object. + * Defines a catalog inline for the a2uiRendererCapabilities object. */ export interface InlineCatalog { catalogId: string; @@ -50,9 +50,9 @@ export interface A2uiVersionCapabilities { } /** - * The capabilities structure sent from the client to the server as part of transport metadata. + * The capabilities structure sent from the renderer to the agent as part of transport metadata. */ -export type A2uiClientCapabilities = +export type A2uiRendererCapabilities = | { 'v0.9': A2uiVersionCapabilities; 'v0.9.1'?: A2uiVersionCapabilities; diff --git a/renderers/web_core/src/v0_9/schema/client-to-server.test.ts b/renderers/web_core/src/v0_9/schema/renderer-to-agent.test.ts similarity index 83% rename from renderers/web_core/src/v0_9/schema/client-to-server.test.ts rename to renderers/web_core/src/v0_9/schema/renderer-to-agent.test.ts index 0b829d3a38..dd2928a90c 100644 --- a/renderers/web_core/src/v0_9/schema/client-to-server.test.ts +++ b/renderers/web_core/src/v0_9/schema/renderer-to-agent.test.ts @@ -16,9 +16,9 @@ import {describe, it} from 'node:test'; import * as assert from 'node:assert'; -import {A2uiClientMessageSchema, A2uiClientDataModelSchema} from './client-to-server.js'; +import {A2uiRendererMessageSchema, A2uiRendererDataModelSchema} from './renderer-to-agent.js'; -describe('Client-to-Server Schema Verification', () => { +describe('Renderer-to-Agent Schema Verification', () => { const versions = ['v0.9', 'v0.9.1']; versions.forEach(version => { @@ -34,7 +34,7 @@ describe('Client-to-Server Schema Verification', () => { context: {foo: 'bar'}, }, }; - const result = A2uiClientMessageSchema.safeParse(validAction); + const result = A2uiRendererMessageSchema.safeParse(validAction); assert.ok(result.success, result.success ? '' : result.error.message); }); @@ -48,7 +48,7 @@ describe('Client-to-Server Schema Verification', () => { message: 'Too short', }, }; - const result = A2uiClientMessageSchema.safeParse(validError); + const result = A2uiRendererMessageSchema.safeParse(validError); assert.ok(result.success, result.success ? '' : result.error.message); }); @@ -61,7 +61,7 @@ describe('Client-to-Server Schema Verification', () => { surfaceId: 's1', }, }; - const result = A2uiClientMessageSchema.safeParse(validError); + const result = A2uiRendererMessageSchema.safeParse(validError); assert.ok(result.success, result.success ? '' : result.error.message); }); @@ -73,7 +73,7 @@ describe('Client-to-Server Schema Verification', () => { s2: {cart: []}, }, }; - const result = A2uiClientDataModelSchema.safeParse(validDataModel); + const result = A2uiRendererDataModelSchema.safeParse(validDataModel); assert.ok(result.success, result.success ? '' : result.error.message); }); }); @@ -90,7 +90,7 @@ describe('Client-to-Server Schema Verification', () => { context: {}, }, }; - const result = A2uiClientMessageSchema.safeParse(invalidAction); + const result = A2uiRendererMessageSchema.safeParse(invalidAction); assert.strictEqual(result.success, false); }); }); diff --git a/renderers/web_core/src/v0_9/schema/client-to-server.ts b/renderers/web_core/src/v0_9/schema/renderer-to-agent.ts similarity index 71% rename from renderers/web_core/src/v0_9/schema/client-to-server.ts rename to renderers/web_core/src/v0_9/schema/renderer-to-agent.ts index 4420faafbe..42e4312681 100644 --- a/renderers/web_core/src/v0_9/schema/client-to-server.ts +++ b/renderers/web_core/src/v0_9/schema/renderer-to-agent.ts @@ -20,7 +20,7 @@ import {z} from 'zod'; * Reports a user-initiated action from a component. * Matches 'action' in specification/v0_9/json/client_to_server.json. */ -export const A2uiClientActionSchema = z +export const A2uiRendererActionSchema = z .object({ name: z .string() @@ -71,25 +71,28 @@ export const A2uiGenericErrorSchema = z * Reports a client-side error. * Matches 'error' in specification/v0_9/json/client_to_server.json. */ -export const A2uiClientErrorSchema = z.union([A2uiValidationErrorSchema, A2uiGenericErrorSchema]); +export const A2uiRendererErrorSchema = z.union([A2uiValidationErrorSchema, A2uiGenericErrorSchema]); /** - * A message sent from the A2UI client to the server. + * A message sent from the A2UI renderer to the agent. * Matches specification/v0_9/json/client_to_server.json. */ -export const A2uiClientMessageSchema = z +export const A2uiRendererMessageSchema = z .object({ version: z.enum(['v0.9', 'v0.9.1']), }) .and( - z.union([z.object({action: A2uiClientActionSchema}), z.object({error: A2uiClientErrorSchema})]), + z.union([ + z.object({action: A2uiRendererActionSchema}), + z.object({error: A2uiRendererErrorSchema}), + ]), ); /** * Schema for the client data model synchronization. * Matches specification/v0_9/json/client_data_model.json. */ -export const A2uiClientDataModelSchema = z +export const A2uiRendererDataModelSchema = z .object({ version: z.enum(['v0.9', 'v0.9.1']), surfaces: z @@ -98,22 +101,22 @@ export const A2uiClientDataModelSchema = z }) .strict(); -export type A2uiClientAction = z.infer; -export type A2uiClientError = z.infer; -export type A2uiClientMessage = z.infer; -export type A2uiClientDataModel = z.infer; +export type A2uiRendererAction = z.infer; +export type A2uiRendererError = z.infer; +export type A2uiRendererMessage = z.infer; +export type A2uiRendererDataModel = z.infer; -export const A2uiClientMessageListSchema = z - .array(A2uiClientMessageSchema) - .describe('A list of client messages.'); +export const A2uiRendererMessageListSchema = z + .array(A2uiRendererMessageSchema) + .describe('A list of renderer messages.'); -export type A2uiClientMessageList = z.infer; +export type A2uiRendererMessageList = z.infer; -export const A2uiClientMessageListWrapperSchema = z +export const A2uiRendererMessageListWrapperSchema = z .object({ - messages: A2uiClientMessageListSchema, + messages: A2uiRendererMessageListSchema, }) .strict() - .describe('An object wrapping a list of client messages.'); + .describe('An object wrapping a list of renderer messages.'); -export type A2uiClientMessageListWrapper = z.infer; +export type A2uiRendererMessageListWrapper = z.infer; diff --git a/renderers/web_core/src/v0_9/schema/verify-schema.test.ts b/renderers/web_core/src/v0_9/schema/verify-schema.test.ts index e18503c8f3..590106b6d0 100644 --- a/renderers/web_core/src/v0_9/schema/verify-schema.test.ts +++ b/renderers/web_core/src/v0_9/schema/verify-schema.test.ts @@ -26,7 +26,7 @@ import { UpdateComponentsMessageSchema, UpdateDataModelMessageSchema, DeleteSurfaceMessageSchema, -} from './server-to-client.js'; +} from './agent-to-renderer.js'; const __filename = fileURLToPath(import.meta.url); const __dirname = dirname(__filename); diff --git a/renderers/web_core/src/v0_9/state/surface-group-model.ts b/renderers/web_core/src/v0_9/state/surface-group-model.ts index 5166f3573a..0562976a32 100644 --- a/renderers/web_core/src/v0_9/state/surface-group-model.ts +++ b/renderers/web_core/src/v0_9/state/surface-group-model.ts @@ -17,7 +17,7 @@ import {SurfaceModel} from './surface-model.js'; import {ComponentApi} from '../catalog/types.js'; import {EventEmitter, EventSource, Subscription} from '../common/events.js'; -import {A2uiClientAction} from '../schema/client-to-server.js'; +import {A2uiRendererAction} from '../schema/renderer-to-agent.js'; /** * The root state model for the A2UI system. @@ -29,14 +29,14 @@ export class SurfaceGroupModel { private readonly _onSurfaceCreated = new EventEmitter>(); private readonly _onSurfaceDeleted = new EventEmitter(); - private readonly _onAction = new EventEmitter(); + private readonly _onAction = new EventEmitter(); /** Fires when a new surface is added. */ readonly onSurfaceCreated: EventSource> = this._onSurfaceCreated; /** Fires when a surface is removed. */ readonly onSurfaceDeleted: EventSource = this._onSurfaceDeleted; /** Fires when an action is dispatched from ANY surface in the group. */ - readonly onAction: EventSource = this._onAction; + readonly onAction: EventSource = this._onAction; /** * Adds a surface to the group. diff --git a/renderers/web_core/src/v0_9/state/surface-model.ts b/renderers/web_core/src/v0_9/state/surface-model.ts index 5686beb7ea..3d274f14e0 100644 --- a/renderers/web_core/src/v0_9/state/surface-model.ts +++ b/renderers/web_core/src/v0_9/state/surface-model.ts @@ -18,10 +18,10 @@ import {DataModel} from './data-model.js'; import {Catalog, ComponentApi} from '../catalog/types.js'; import {SurfaceComponentsModel} from './surface-components-model.js'; import {EventEmitter, EventSource} from '../common/events.js'; -import {A2uiClientAction, A2uiClientActionSchema} from '../schema/client-to-server.js'; +import {A2uiRendererAction, A2uiRendererActionSchema} from '../schema/renderer-to-agent.js'; /** A function that listens for actions emitted from a surface. */ -export type ActionListener = (action: A2uiClientAction) => void | Promise; +export type ActionListener = (action: A2uiRendererAction) => void | Promise; /** * The state model for a single UI surface. @@ -37,11 +37,11 @@ export class SurfaceModel { /** The collection of component models for this surface. */ readonly componentsModel: SurfaceComponentsModel; - private readonly _onAction = new EventEmitter(); + private readonly _onAction = new EventEmitter(); private readonly _onError = new EventEmitter(); /** Fires whenever an action is dispatched from this surface. */ - readonly onAction: EventSource = this._onAction; + readonly onAction: EventSource = this._onAction; /** Fires whenever an error occurs on this surface. */ readonly onError: EventSource = this._onError; @@ -80,7 +80,7 @@ export class SurfaceModel { context: payload.event.context || {}, }; - const validationResult = A2uiClientActionSchema.safeParse(actionToValidate); + const validationResult = A2uiRendererActionSchema.safeParse(actionToValidate); if (validationResult.success) { await this._onAction.emit(validationResult.data); } else { diff --git a/samples/agent/adk/custom-components-example/CONTRIBUTING.md b/samples/agent/adk/custom-components-example/CONTRIBUTING.md index 32e91c1031..cc0a121ad3 100644 --- a/samples/agent/adk/custom-components-example/CONTRIBUTING.md +++ b/samples/agent/adk/custom-components-example/CONTRIBUTING.md @@ -27,7 +27,7 @@ The agent manages multiple distinct UI areas ("surfaces") simultaneously: A custom LitElement component created in the client that renders a hierarchical view. -- **Schema**: Defined in `samples/client/lit/contact/ui/custom-components`. +- **Schema**: Defined in `samples/renderer/lit/contact/ui/custom-components`. - **Usage**: The agent sends a JSON structure matching the schema, and the client renders it natively. #### `WebFrame` (Iframe Component) @@ -51,7 +51,7 @@ A powerful component that allows embedding external web content or local static 2. **Start the Client**: ```bash - cd samples/client/lit/contact + cd samples/renderer/lit/contact yarn dev ``` _Configured to connect to localhost:10004._ diff --git a/samples/community/agent/adk/mcp-apps-in-a2ui-sample/README.md b/samples/community/agent/adk/mcp-apps-in-a2ui-sample/README.md index f2d5024e68..ef9ed67be7 100644 --- a/samples/community/agent/adk/mcp-apps-in-a2ui-sample/README.md +++ b/samples/community/agent/adk/mcp-apps-in-a2ui-sample/README.md @@ -7,7 +7,7 @@ This sample demonstrates how to integrate an **MCP (Model Context Protocol) App* The sample consists of: 1. **Agent** (`agent.py`): A Python FastAPI server that acts as the agent. It serves the UI manifest containing the `McpApp` component and handles tool calls forwarded by the client. -2. **Client** (`samples/client/lit/mcp-apps-in-a2ui-sample`): A Lit-based client application that renders the A2UI interface and the `McpApp` component. +2. **Client** (`samples/renderer/lit/mcp-apps-in-a2ui-sample`): A Lit-based client application that renders the A2UI interface and the `McpApp` component. ## Architecture diff --git a/samples/community/client/angular/angular.json b/samples/community/renderer/angular/angular.json similarity index 100% rename from samples/community/client/angular/angular.json rename to samples/community/renderer/angular/angular.json diff --git a/samples/community/client/angular/eslint.config.mjs b/samples/community/renderer/angular/eslint.config.mjs similarity index 100% rename from samples/community/client/angular/eslint.config.mjs rename to samples/community/renderer/angular/eslint.config.mjs diff --git a/samples/community/client/angular/package.json b/samples/community/renderer/angular/package.json similarity index 100% rename from samples/community/client/angular/package.json rename to samples/community/renderer/angular/package.json diff --git a/samples/community/client/angular/projects/a2a-chat-canvas/README.md b/samples/community/renderer/angular/projects/a2a-chat-canvas/README.md similarity index 100% rename from samples/community/client/angular/projects/a2a-chat-canvas/README.md rename to samples/community/renderer/angular/projects/a2a-chat-canvas/README.md diff --git a/samples/community/client/angular/projects/a2a-chat-canvas/ng-package.json b/samples/community/renderer/angular/projects/a2a-chat-canvas/ng-package.json similarity index 100% rename from samples/community/client/angular/projects/a2a-chat-canvas/ng-package.json rename to samples/community/renderer/angular/projects/a2a-chat-canvas/ng-package.json diff --git a/samples/community/client/angular/projects/a2a-chat-canvas/package.json b/samples/community/renderer/angular/projects/a2a-chat-canvas/package.json similarity index 100% rename from samples/community/client/angular/projects/a2a-chat-canvas/package.json rename to samples/community/renderer/angular/projects/a2a-chat-canvas/package.json diff --git a/samples/community/client/angular/projects/a2a-chat-canvas/src/index.ts b/samples/community/renderer/angular/projects/a2a-chat-canvas/src/index.ts similarity index 100% rename from samples/community/client/angular/projects/a2a-chat-canvas/src/index.ts rename to samples/community/renderer/angular/projects/a2a-chat-canvas/src/index.ts diff --git a/samples/community/client/angular/projects/a2a-chat-canvas/src/lib/a2a-chat-canvas.html b/samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/a2a-chat-canvas.html similarity index 100% rename from samples/community/client/angular/projects/a2a-chat-canvas/src/lib/a2a-chat-canvas.html rename to samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/a2a-chat-canvas.html diff --git a/samples/community/client/angular/projects/a2a-chat-canvas/src/lib/a2a-chat-canvas.scss b/samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/a2a-chat-canvas.scss similarity index 100% rename from samples/community/client/angular/projects/a2a-chat-canvas/src/lib/a2a-chat-canvas.scss rename to samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/a2a-chat-canvas.scss diff --git a/samples/community/client/angular/projects/a2a-chat-canvas/src/lib/a2a-chat-canvas.spec.ts b/samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/a2a-chat-canvas.spec.ts similarity index 100% rename from samples/community/client/angular/projects/a2a-chat-canvas/src/lib/a2a-chat-canvas.spec.ts rename to samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/a2a-chat-canvas.spec.ts diff --git a/samples/community/client/angular/projects/a2a-chat-canvas/src/lib/a2a-chat-canvas.ts b/samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/a2a-chat-canvas.ts similarity index 100% rename from samples/community/client/angular/projects/a2a-chat-canvas/src/lib/a2a-chat-canvas.ts rename to samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/a2a-chat-canvas.ts diff --git a/samples/community/client/angular/projects/a2a-chat-canvas/src/lib/a2a-renderer/a2a-renderer.html b/samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/a2a-renderer/a2a-renderer.html similarity index 100% rename from samples/community/client/angular/projects/a2a-chat-canvas/src/lib/a2a-renderer/a2a-renderer.html rename to samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/a2a-renderer/a2a-renderer.html diff --git a/samples/community/client/angular/projects/a2a-chat-canvas/src/lib/a2a-renderer/a2a-renderer.scss b/samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/a2a-renderer/a2a-renderer.scss similarity index 100% rename from samples/community/client/angular/projects/a2a-chat-canvas/src/lib/a2a-renderer/a2a-renderer.scss rename to samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/a2a-renderer/a2a-renderer.scss diff --git a/samples/community/client/angular/projects/a2a-chat-canvas/src/lib/a2a-renderer/a2a-renderer.spec.ts b/samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/a2a-renderer/a2a-renderer.spec.ts similarity index 100% rename from samples/community/client/angular/projects/a2a-chat-canvas/src/lib/a2a-renderer/a2a-renderer.spec.ts rename to samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/a2a-renderer/a2a-renderer.spec.ts diff --git a/samples/community/client/angular/projects/a2a-chat-canvas/src/lib/a2a-renderer/a2a-renderer.ts b/samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/a2a-renderer/a2a-renderer.ts similarity index 100% rename from samples/community/client/angular/projects/a2a-chat-canvas/src/lib/a2a-renderer/a2a-renderer.ts rename to samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/a2a-renderer/a2a-renderer.ts diff --git a/samples/community/client/angular/projects/a2a-chat-canvas/src/lib/a2a-renderer/catalog/a2ui-data-part/a2ui-data-part.html b/samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/a2a-renderer/catalog/a2ui-data-part/a2ui-data-part.html similarity index 100% rename from samples/community/client/angular/projects/a2a-chat-canvas/src/lib/a2a-renderer/catalog/a2ui-data-part/a2ui-data-part.html rename to samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/a2a-renderer/catalog/a2ui-data-part/a2ui-data-part.html diff --git a/samples/community/client/angular/projects/a2a-chat-canvas/src/lib/a2a-renderer/catalog/a2ui-data-part/a2ui-data-part.scss b/samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/a2a-renderer/catalog/a2ui-data-part/a2ui-data-part.scss similarity index 100% rename from samples/community/client/angular/projects/a2a-chat-canvas/src/lib/a2a-renderer/catalog/a2ui-data-part/a2ui-data-part.scss rename to samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/a2a-renderer/catalog/a2ui-data-part/a2ui-data-part.scss diff --git a/samples/community/client/angular/projects/a2a-chat-canvas/src/lib/a2a-renderer/catalog/a2ui-data-part/a2ui-data-part.spec.ts b/samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/a2a-renderer/catalog/a2ui-data-part/a2ui-data-part.spec.ts similarity index 100% rename from samples/community/client/angular/projects/a2a-chat-canvas/src/lib/a2a-renderer/catalog/a2ui-data-part/a2ui-data-part.spec.ts rename to samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/a2a-renderer/catalog/a2ui-data-part/a2ui-data-part.spec.ts diff --git a/samples/community/client/angular/projects/a2a-chat-canvas/src/lib/a2a-renderer/catalog/a2ui-data-part/a2ui-data-part.ts b/samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/a2a-renderer/catalog/a2ui-data-part/a2ui-data-part.ts similarity index 100% rename from samples/community/client/angular/projects/a2a-chat-canvas/src/lib/a2a-renderer/catalog/a2ui-data-part/a2ui-data-part.ts rename to samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/a2a-renderer/catalog/a2ui-data-part/a2ui-data-part.ts diff --git a/samples/community/client/angular/projects/a2a-chat-canvas/src/lib/a2a-renderer/catalog/a2ui-data-part/renderer-config.ts b/samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/a2a-renderer/catalog/a2ui-data-part/renderer-config.ts similarity index 100% rename from samples/community/client/angular/projects/a2a-chat-canvas/src/lib/a2a-renderer/catalog/a2ui-data-part/renderer-config.ts rename to samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/a2a-renderer/catalog/a2ui-data-part/renderer-config.ts diff --git a/samples/community/client/angular/projects/a2a-chat-canvas/src/lib/a2a-renderer/catalog/a2ui-data-part/resolver.ts b/samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/a2a-renderer/catalog/a2ui-data-part/resolver.ts similarity index 100% rename from samples/community/client/angular/projects/a2a-chat-canvas/src/lib/a2a-renderer/catalog/a2ui-data-part/resolver.ts rename to samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/a2a-renderer/catalog/a2ui-data-part/resolver.ts diff --git a/samples/community/client/angular/projects/a2a-chat-canvas/src/lib/a2a-renderer/catalog/default-text-part/default-text-part.html b/samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/a2a-renderer/catalog/default-text-part/default-text-part.html similarity index 100% rename from samples/community/client/angular/projects/a2a-chat-canvas/src/lib/a2a-renderer/catalog/default-text-part/default-text-part.html rename to samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/a2a-renderer/catalog/default-text-part/default-text-part.html diff --git a/samples/community/client/angular/projects/a2a-chat-canvas/src/lib/a2a-renderer/catalog/default-text-part/default-text-part.scss b/samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/a2a-renderer/catalog/default-text-part/default-text-part.scss similarity index 100% rename from samples/community/client/angular/projects/a2a-chat-canvas/src/lib/a2a-renderer/catalog/default-text-part/default-text-part.scss rename to samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/a2a-renderer/catalog/default-text-part/default-text-part.scss diff --git a/samples/community/client/angular/projects/a2a-chat-canvas/src/lib/a2a-renderer/catalog/default-text-part/default-text-part.spec.ts b/samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/a2a-renderer/catalog/default-text-part/default-text-part.spec.ts similarity index 100% rename from samples/community/client/angular/projects/a2a-chat-canvas/src/lib/a2a-renderer/catalog/default-text-part/default-text-part.spec.ts rename to samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/a2a-renderer/catalog/default-text-part/default-text-part.spec.ts diff --git a/samples/community/client/angular/projects/a2a-chat-canvas/src/lib/a2a-renderer/catalog/default-text-part/default-text-part.ts b/samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/a2a-renderer/catalog/default-text-part/default-text-part.ts similarity index 100% rename from samples/community/client/angular/projects/a2a-chat-canvas/src/lib/a2a-renderer/catalog/default-text-part/default-text-part.ts rename to samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/a2a-renderer/catalog/default-text-part/default-text-part.ts diff --git a/samples/community/client/angular/projects/a2a-chat-canvas/src/lib/a2a-renderer/catalog/default-text-part/renderer-config.ts b/samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/a2a-renderer/catalog/default-text-part/renderer-config.ts similarity index 100% rename from samples/community/client/angular/projects/a2a-chat-canvas/src/lib/a2a-renderer/catalog/default-text-part/renderer-config.ts rename to samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/a2a-renderer/catalog/default-text-part/renderer-config.ts diff --git a/samples/community/client/angular/projects/a2a-chat-canvas/src/lib/a2a-renderer/catalog/default-text-part/resolver.ts b/samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/a2a-renderer/catalog/default-text-part/resolver.ts similarity index 100% rename from samples/community/client/angular/projects/a2a-chat-canvas/src/lib/a2a-renderer/catalog/default-text-part/resolver.ts rename to samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/a2a-renderer/catalog/default-text-part/resolver.ts diff --git a/samples/community/client/angular/projects/a2a-chat-canvas/src/lib/a2a-renderer/tokens.ts b/samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/a2a-renderer/tokens.ts similarity index 100% rename from samples/community/client/angular/projects/a2a-chat-canvas/src/lib/a2a-renderer/tokens.ts rename to samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/a2a-renderer/tokens.ts diff --git a/samples/community/client/angular/projects/a2a-chat-canvas/src/lib/a2a-renderer/types.ts b/samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/a2a-renderer/types.ts similarity index 100% rename from samples/community/client/angular/projects/a2a-chat-canvas/src/lib/a2a-renderer/types.ts rename to samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/a2a-renderer/types.ts diff --git a/samples/community/client/angular/projects/a2a-chat-canvas/src/lib/a2ui-catalog/a2a-chat-canvas-catalog.ts b/samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/a2ui-catalog/a2a-chat-canvas-catalog.ts similarity index 100% rename from samples/community/client/angular/projects/a2a-chat-canvas/src/lib/a2ui-catalog/a2a-chat-canvas-catalog.ts rename to samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/a2ui-catalog/a2a-chat-canvas-catalog.ts diff --git a/samples/community/client/angular/projects/a2a-chat-canvas/src/lib/a2ui-catalog/canvas/canvas.html b/samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/a2ui-catalog/canvas/canvas.html similarity index 100% rename from samples/community/client/angular/projects/a2a-chat-canvas/src/lib/a2ui-catalog/canvas/canvas.html rename to samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/a2ui-catalog/canvas/canvas.html diff --git a/samples/community/client/angular/projects/a2a-chat-canvas/src/lib/a2ui-catalog/canvas/canvas.scss b/samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/a2ui-catalog/canvas/canvas.scss similarity index 100% rename from samples/community/client/angular/projects/a2a-chat-canvas/src/lib/a2ui-catalog/canvas/canvas.scss rename to samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/a2ui-catalog/canvas/canvas.scss diff --git a/samples/community/client/angular/projects/a2a-chat-canvas/src/lib/a2ui-catalog/canvas/canvas.spec.ts b/samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/a2ui-catalog/canvas/canvas.spec.ts similarity index 100% rename from samples/community/client/angular/projects/a2a-chat-canvas/src/lib/a2ui-catalog/canvas/canvas.spec.ts rename to samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/a2ui-catalog/canvas/canvas.spec.ts diff --git a/samples/community/client/angular/projects/a2a-chat-canvas/src/lib/a2ui-catalog/canvas/canvas.ts b/samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/a2ui-catalog/canvas/canvas.ts similarity index 100% rename from samples/community/client/angular/projects/a2a-chat-canvas/src/lib/a2ui-catalog/canvas/canvas.ts rename to samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/a2ui-catalog/canvas/canvas.ts diff --git a/samples/community/client/angular/projects/a2a-chat-canvas/src/lib/a2ui-catalog/theme.ts b/samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/a2ui-catalog/theme.ts similarity index 100% rename from samples/community/client/angular/projects/a2a-chat-canvas/src/lib/a2ui-catalog/theme.ts rename to samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/a2ui-catalog/theme.ts diff --git a/samples/community/client/angular/projects/a2a-chat-canvas/src/lib/components/canvas/canvas.html b/samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/components/canvas/canvas.html similarity index 100% rename from samples/community/client/angular/projects/a2a-chat-canvas/src/lib/components/canvas/canvas.html rename to samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/components/canvas/canvas.html diff --git a/samples/community/client/angular/projects/a2a-chat-canvas/src/lib/components/canvas/canvas.scss b/samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/components/canvas/canvas.scss similarity index 100% rename from samples/community/client/angular/projects/a2a-chat-canvas/src/lib/components/canvas/canvas.scss rename to samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/components/canvas/canvas.scss diff --git a/samples/community/client/angular/projects/a2a-chat-canvas/src/lib/components/canvas/canvas.spec.ts b/samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/components/canvas/canvas.spec.ts similarity index 100% rename from samples/community/client/angular/projects/a2a-chat-canvas/src/lib/components/canvas/canvas.spec.ts rename to samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/components/canvas/canvas.spec.ts diff --git a/samples/community/client/angular/projects/a2a-chat-canvas/src/lib/components/canvas/canvas.ts b/samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/components/canvas/canvas.ts similarity index 100% rename from samples/community/client/angular/projects/a2a-chat-canvas/src/lib/components/canvas/canvas.ts rename to samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/components/canvas/canvas.ts diff --git a/samples/community/client/angular/projects/a2a-chat-canvas/src/lib/components/chat/agent-header/agent-header.html b/samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/components/chat/agent-header/agent-header.html similarity index 100% rename from samples/community/client/angular/projects/a2a-chat-canvas/src/lib/components/chat/agent-header/agent-header.html rename to samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/components/chat/agent-header/agent-header.html diff --git a/samples/community/client/angular/projects/a2a-chat-canvas/src/lib/components/chat/agent-header/agent-header.scss b/samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/components/chat/agent-header/agent-header.scss similarity index 100% rename from samples/community/client/angular/projects/a2a-chat-canvas/src/lib/components/chat/agent-header/agent-header.scss rename to samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/components/chat/agent-header/agent-header.scss diff --git a/samples/community/client/angular/projects/a2a-chat-canvas/src/lib/components/chat/agent-header/agent-header.spec.ts b/samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/components/chat/agent-header/agent-header.spec.ts similarity index 100% rename from samples/community/client/angular/projects/a2a-chat-canvas/src/lib/components/chat/agent-header/agent-header.spec.ts rename to samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/components/chat/agent-header/agent-header.spec.ts diff --git a/samples/community/client/angular/projects/a2a-chat-canvas/src/lib/components/chat/agent-header/agent-header.ts b/samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/components/chat/agent-header/agent-header.ts similarity index 100% rename from samples/community/client/angular/projects/a2a-chat-canvas/src/lib/components/chat/agent-header/agent-header.ts rename to samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/components/chat/agent-header/agent-header.ts diff --git a/samples/community/client/angular/projects/a2a-chat-canvas/src/lib/components/chat/avatar/avatar.html b/samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/components/chat/avatar/avatar.html similarity index 100% rename from samples/community/client/angular/projects/a2a-chat-canvas/src/lib/components/chat/avatar/avatar.html rename to samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/components/chat/avatar/avatar.html diff --git a/samples/community/client/angular/projects/a2a-chat-canvas/src/lib/components/chat/avatar/avatar.scss b/samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/components/chat/avatar/avatar.scss similarity index 100% rename from samples/community/client/angular/projects/a2a-chat-canvas/src/lib/components/chat/avatar/avatar.scss rename to samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/components/chat/avatar/avatar.scss diff --git a/samples/community/client/angular/projects/a2a-chat-canvas/src/lib/components/chat/avatar/avatar.spec.ts b/samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/components/chat/avatar/avatar.spec.ts similarity index 100% rename from samples/community/client/angular/projects/a2a-chat-canvas/src/lib/components/chat/avatar/avatar.spec.ts rename to samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/components/chat/avatar/avatar.spec.ts diff --git a/samples/community/client/angular/projects/a2a-chat-canvas/src/lib/components/chat/avatar/avatar.ts b/samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/components/chat/avatar/avatar.ts similarity index 100% rename from samples/community/client/angular/projects/a2a-chat-canvas/src/lib/components/chat/avatar/avatar.ts rename to samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/components/chat/avatar/avatar.ts diff --git a/samples/community/client/angular/projects/a2a-chat-canvas/src/lib/components/chat/chat-history/chat-history.html b/samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/components/chat/chat-history/chat-history.html similarity index 100% rename from samples/community/client/angular/projects/a2a-chat-canvas/src/lib/components/chat/chat-history/chat-history.html rename to samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/components/chat/chat-history/chat-history.html diff --git a/samples/community/client/angular/projects/a2a-chat-canvas/src/lib/components/chat/chat-history/chat-history.scss b/samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/components/chat/chat-history/chat-history.scss similarity index 100% rename from samples/community/client/angular/projects/a2a-chat-canvas/src/lib/components/chat/chat-history/chat-history.scss rename to samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/components/chat/chat-history/chat-history.scss diff --git a/samples/community/client/angular/projects/a2a-chat-canvas/src/lib/components/chat/chat-history/chat-history.spec.ts b/samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/components/chat/chat-history/chat-history.spec.ts similarity index 100% rename from samples/community/client/angular/projects/a2a-chat-canvas/src/lib/components/chat/chat-history/chat-history.spec.ts rename to samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/components/chat/chat-history/chat-history.spec.ts diff --git a/samples/community/client/angular/projects/a2a-chat-canvas/src/lib/components/chat/chat-history/chat-history.ts b/samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/components/chat/chat-history/chat-history.ts similarity index 100% rename from samples/community/client/angular/projects/a2a-chat-canvas/src/lib/components/chat/chat-history/chat-history.ts rename to samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/components/chat/chat-history/chat-history.ts diff --git a/samples/community/client/angular/projects/a2a-chat-canvas/src/lib/components/chat/chat-history/message-decorator/types.ts b/samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/components/chat/chat-history/message-decorator/types.ts similarity index 100% rename from samples/community/client/angular/projects/a2a-chat-canvas/src/lib/components/chat/chat-history/message-decorator/types.ts rename to samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/components/chat/chat-history/message-decorator/types.ts diff --git a/samples/community/client/angular/projects/a2a-chat-canvas/src/lib/components/chat/chat.html b/samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/components/chat/chat.html similarity index 100% rename from samples/community/client/angular/projects/a2a-chat-canvas/src/lib/components/chat/chat.html rename to samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/components/chat/chat.html diff --git a/samples/community/client/angular/projects/a2a-chat-canvas/src/lib/components/chat/chat.scss b/samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/components/chat/chat.scss similarity index 100% rename from samples/community/client/angular/projects/a2a-chat-canvas/src/lib/components/chat/chat.scss rename to samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/components/chat/chat.scss diff --git a/samples/community/client/angular/projects/a2a-chat-canvas/src/lib/components/chat/chat.spec.ts b/samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/components/chat/chat.spec.ts similarity index 100% rename from samples/community/client/angular/projects/a2a-chat-canvas/src/lib/components/chat/chat.spec.ts rename to samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/components/chat/chat.spec.ts diff --git a/samples/community/client/angular/projects/a2a-chat-canvas/src/lib/components/chat/chat.ts b/samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/components/chat/chat.ts similarity index 100% rename from samples/community/client/angular/projects/a2a-chat-canvas/src/lib/components/chat/chat.ts rename to samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/components/chat/chat.ts diff --git a/samples/community/client/angular/projects/a2a-chat-canvas/src/lib/components/chat/input-area/input-area.html b/samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/components/chat/input-area/input-area.html similarity index 100% rename from samples/community/client/angular/projects/a2a-chat-canvas/src/lib/components/chat/input-area/input-area.html rename to samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/components/chat/input-area/input-area.html diff --git a/samples/community/client/angular/projects/a2a-chat-canvas/src/lib/components/chat/input-area/input-area.scss b/samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/components/chat/input-area/input-area.scss similarity index 100% rename from samples/community/client/angular/projects/a2a-chat-canvas/src/lib/components/chat/input-area/input-area.scss rename to samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/components/chat/input-area/input-area.scss diff --git a/samples/community/client/angular/projects/a2a-chat-canvas/src/lib/components/chat/input-area/input-area.spec.ts b/samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/components/chat/input-area/input-area.spec.ts similarity index 100% rename from samples/community/client/angular/projects/a2a-chat-canvas/src/lib/components/chat/input-area/input-area.spec.ts rename to samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/components/chat/input-area/input-area.spec.ts diff --git a/samples/community/client/angular/projects/a2a-chat-canvas/src/lib/components/chat/input-area/input-area.ts b/samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/components/chat/input-area/input-area.ts similarity index 100% rename from samples/community/client/angular/projects/a2a-chat-canvas/src/lib/components/chat/input-area/input-area.ts rename to samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/components/chat/input-area/input-area.ts diff --git a/samples/community/client/angular/projects/a2a-chat-canvas/src/lib/components/chat/message/message.html b/samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/components/chat/message/message.html similarity index 100% rename from samples/community/client/angular/projects/a2a-chat-canvas/src/lib/components/chat/message/message.html rename to samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/components/chat/message/message.html diff --git a/samples/community/client/angular/projects/a2a-chat-canvas/src/lib/components/chat/message/message.scss b/samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/components/chat/message/message.scss similarity index 100% rename from samples/community/client/angular/projects/a2a-chat-canvas/src/lib/components/chat/message/message.scss rename to samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/components/chat/message/message.scss diff --git a/samples/community/client/angular/projects/a2a-chat-canvas/src/lib/components/chat/message/message.spec.ts b/samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/components/chat/message/message.spec.ts similarity index 100% rename from samples/community/client/angular/projects/a2a-chat-canvas/src/lib/components/chat/message/message.spec.ts rename to samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/components/chat/message/message.spec.ts diff --git a/samples/community/client/angular/projects/a2a-chat-canvas/src/lib/components/chat/message/message.ts b/samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/components/chat/message/message.ts similarity index 100% rename from samples/community/client/angular/projects/a2a-chat-canvas/src/lib/components/chat/message/message.ts rename to samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/components/chat/message/message.ts diff --git a/samples/community/client/angular/projects/a2a-chat-canvas/src/lib/config.ts b/samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/config.ts similarity index 100% rename from samples/community/client/angular/projects/a2a-chat-canvas/src/lib/config.ts rename to samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/config.ts diff --git a/samples/community/client/angular/projects/a2a-chat-canvas/src/lib/interfaces/a2a-service.ts b/samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/interfaces/a2a-service.ts similarity index 100% rename from samples/community/client/angular/projects/a2a-chat-canvas/src/lib/interfaces/a2a-service.ts rename to samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/interfaces/a2a-service.ts diff --git a/samples/community/client/angular/projects/a2a-chat-canvas/src/lib/interfaces/markdown-renderer-service.ts b/samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/interfaces/markdown-renderer-service.ts similarity index 100% rename from samples/community/client/angular/projects/a2a-chat-canvas/src/lib/interfaces/markdown-renderer-service.ts rename to samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/interfaces/markdown-renderer-service.ts diff --git a/samples/community/client/angular/projects/a2a-chat-canvas/src/lib/services/canvas-service.ts b/samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/services/canvas-service.ts similarity index 100% rename from samples/community/client/angular/projects/a2a-chat-canvas/src/lib/services/canvas-service.ts rename to samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/services/canvas-service.ts diff --git a/samples/community/client/angular/projects/a2a-chat-canvas/src/lib/services/chat-service.ts b/samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/services/chat-service.ts similarity index 100% rename from samples/community/client/angular/projects/a2a-chat-canvas/src/lib/services/chat-service.ts rename to samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/services/chat-service.ts diff --git a/samples/community/client/angular/projects/a2a-chat-canvas/src/lib/services/sanitizer-markdown-renderer-service.ts b/samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/services/sanitizer-markdown-renderer-service.ts similarity index 100% rename from samples/community/client/angular/projects/a2a-chat-canvas/src/lib/services/sanitizer-markdown-renderer-service.ts rename to samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/services/sanitizer-markdown-renderer-service.ts diff --git a/samples/community/client/angular/projects/a2a-chat-canvas/src/lib/types/ui-message.ts b/samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/types/ui-message.ts similarity index 100% rename from samples/community/client/angular/projects/a2a-chat-canvas/src/lib/types/ui-message.ts rename to samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/types/ui-message.ts diff --git a/samples/community/client/angular/projects/a2a-chat-canvas/src/lib/utils/a2a.ts b/samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/utils/a2a.ts similarity index 100% rename from samples/community/client/angular/projects/a2a-chat-canvas/src/lib/utils/a2a.ts rename to samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/utils/a2a.ts diff --git a/samples/community/client/angular/projects/a2a-chat-canvas/src/lib/utils/a2ui.ts b/samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/utils/a2ui.ts similarity index 100% rename from samples/community/client/angular/projects/a2a-chat-canvas/src/lib/utils/a2ui.ts rename to samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/utils/a2ui.ts diff --git a/samples/community/client/angular/projects/a2a-chat-canvas/src/lib/utils/type-guards.ts b/samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/utils/type-guards.ts similarity index 100% rename from samples/community/client/angular/projects/a2a-chat-canvas/src/lib/utils/type-guards.ts rename to samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/utils/type-guards.ts diff --git a/samples/community/client/angular/projects/a2a-chat-canvas/src/lib/utils/ui-message-utils.ts b/samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/utils/ui-message-utils.ts similarity index 100% rename from samples/community/client/angular/projects/a2a-chat-canvas/src/lib/utils/ui-message-utils.ts rename to samples/community/renderer/angular/projects/a2a-chat-canvas/src/lib/utils/ui-message-utils.ts diff --git a/samples/community/client/angular/projects/a2a-chat-canvas/tsconfig.lib.json b/samples/community/renderer/angular/projects/a2a-chat-canvas/tsconfig.lib.json similarity index 100% rename from samples/community/client/angular/projects/a2a-chat-canvas/tsconfig.lib.json rename to samples/community/renderer/angular/projects/a2a-chat-canvas/tsconfig.lib.json diff --git a/samples/community/client/angular/projects/a2a-chat-canvas/tsconfig.lib.prod.json b/samples/community/renderer/angular/projects/a2a-chat-canvas/tsconfig.lib.prod.json similarity index 100% rename from samples/community/client/angular/projects/a2a-chat-canvas/tsconfig.lib.prod.json rename to samples/community/renderer/angular/projects/a2a-chat-canvas/tsconfig.lib.prod.json diff --git a/samples/community/client/angular/projects/a2a-chat-canvas/tsconfig.spec.json b/samples/community/renderer/angular/projects/a2a-chat-canvas/tsconfig.spec.json similarity index 100% rename from samples/community/client/angular/projects/a2a-chat-canvas/tsconfig.spec.json rename to samples/community/renderer/angular/projects/a2a-chat-canvas/tsconfig.spec.json diff --git a/samples/community/client/angular/projects/mcp_calculator/README.md b/samples/community/renderer/angular/projects/mcp_calculator/README.md similarity index 100% rename from samples/community/client/angular/projects/mcp_calculator/README.md rename to samples/community/renderer/angular/projects/mcp_calculator/README.md diff --git a/samples/community/client/angular/projects/mcp_calculator/package.json b/samples/community/renderer/angular/projects/mcp_calculator/package.json similarity index 100% rename from samples/community/client/angular/projects/mcp_calculator/package.json rename to samples/community/renderer/angular/projects/mcp_calculator/package.json diff --git a/samples/client/angular/projects/restaurant/public/favicon.ico b/samples/community/renderer/angular/projects/mcp_calculator/public/favicon.ico similarity index 100% rename from samples/client/angular/projects/restaurant/public/favicon.ico rename to samples/community/renderer/angular/projects/mcp_calculator/public/favicon.ico diff --git a/samples/community/client/angular/projects/mcp_calculator/public/gemini-color.svg b/samples/community/renderer/angular/projects/mcp_calculator/public/gemini-color.svg similarity index 100% rename from samples/community/client/angular/projects/mcp_calculator/public/gemini-color.svg rename to samples/community/renderer/angular/projects/mcp_calculator/public/gemini-color.svg diff --git a/samples/community/client/angular/projects/mcp_calculator/src/a2ui-catalog/catalog.ts b/samples/community/renderer/angular/projects/mcp_calculator/src/a2ui-catalog/catalog.ts similarity index 100% rename from samples/community/client/angular/projects/mcp_calculator/src/a2ui-catalog/catalog.ts rename to samples/community/renderer/angular/projects/mcp_calculator/src/a2ui-catalog/catalog.ts diff --git a/samples/community/client/angular/projects/mcp_calculator/src/a2ui-catalog/mcp-app.ts b/samples/community/renderer/angular/projects/mcp_calculator/src/a2ui-catalog/mcp-app.ts similarity index 100% rename from samples/community/client/angular/projects/mcp_calculator/src/a2ui-catalog/mcp-app.ts rename to samples/community/renderer/angular/projects/mcp_calculator/src/a2ui-catalog/mcp-app.ts diff --git a/samples/community/client/angular/projects/mcp_calculator/src/a2ui-catalog/mcp-apps-component_spec.md b/samples/community/renderer/angular/projects/mcp_calculator/src/a2ui-catalog/mcp-apps-component_spec.md similarity index 100% rename from samples/community/client/angular/projects/mcp_calculator/src/a2ui-catalog/mcp-apps-component_spec.md rename to samples/community/renderer/angular/projects/mcp_calculator/src/a2ui-catalog/mcp-apps-component_spec.md diff --git a/samples/community/client/angular/projects/mcp_calculator/src/a2ui-catalog/pong-layout.ts b/samples/community/renderer/angular/projects/mcp_calculator/src/a2ui-catalog/pong-layout.ts similarity index 100% rename from samples/community/client/angular/projects/mcp_calculator/src/a2ui-catalog/pong-layout.ts rename to samples/community/renderer/angular/projects/mcp_calculator/src/a2ui-catalog/pong-layout.ts diff --git a/samples/community/client/angular/projects/mcp_calculator/src/a2ui-catalog/pong-scoreboard.ts b/samples/community/renderer/angular/projects/mcp_calculator/src/a2ui-catalog/pong-scoreboard.ts similarity index 100% rename from samples/community/client/angular/projects/mcp_calculator/src/a2ui-catalog/pong-scoreboard.ts rename to samples/community/renderer/angular/projects/mcp_calculator/src/a2ui-catalog/pong-scoreboard.ts diff --git a/samples/community/client/angular/projects/mcp_calculator/src/app/app.config.server.ts b/samples/community/renderer/angular/projects/mcp_calculator/src/app/app.config.server.ts similarity index 100% rename from samples/community/client/angular/projects/mcp_calculator/src/app/app.config.server.ts rename to samples/community/renderer/angular/projects/mcp_calculator/src/app/app.config.server.ts diff --git a/samples/community/client/angular/projects/mcp_calculator/src/app/app.config.ts b/samples/community/renderer/angular/projects/mcp_calculator/src/app/app.config.ts similarity index 100% rename from samples/community/client/angular/projects/mcp_calculator/src/app/app.config.ts rename to samples/community/renderer/angular/projects/mcp_calculator/src/app/app.config.ts diff --git a/samples/community/client/angular/projects/mcp_calculator/src/app/app.html b/samples/community/renderer/angular/projects/mcp_calculator/src/app/app.html similarity index 100% rename from samples/community/client/angular/projects/mcp_calculator/src/app/app.html rename to samples/community/renderer/angular/projects/mcp_calculator/src/app/app.html diff --git a/samples/community/client/angular/projects/mcp_calculator/src/app/app.routes.server.ts b/samples/community/renderer/angular/projects/mcp_calculator/src/app/app.routes.server.ts similarity index 100% rename from samples/community/client/angular/projects/mcp_calculator/src/app/app.routes.server.ts rename to samples/community/renderer/angular/projects/mcp_calculator/src/app/app.routes.server.ts diff --git a/samples/community/client/angular/projects/mcp_calculator/src/app/app.scss b/samples/community/renderer/angular/projects/mcp_calculator/src/app/app.scss similarity index 100% rename from samples/community/client/angular/projects/mcp_calculator/src/app/app.scss rename to samples/community/renderer/angular/projects/mcp_calculator/src/app/app.scss diff --git a/samples/community/client/angular/projects/mcp_calculator/src/app/app.ts b/samples/community/renderer/angular/projects/mcp_calculator/src/app/app.ts similarity index 100% rename from samples/community/client/angular/projects/mcp_calculator/src/app/app.ts rename to samples/community/renderer/angular/projects/mcp_calculator/src/app/app.ts diff --git a/samples/client/angular/projects/restaurant/src/app/dummy.spec.ts b/samples/community/renderer/angular/projects/mcp_calculator/src/app/dummy.spec.ts similarity index 100% rename from samples/client/angular/projects/restaurant/src/app/dummy.spec.ts rename to samples/community/renderer/angular/projects/mcp_calculator/src/app/dummy.spec.ts diff --git a/samples/community/client/angular/projects/mcp_calculator/src/index.html b/samples/community/renderer/angular/projects/mcp_calculator/src/index.html similarity index 100% rename from samples/community/client/angular/projects/mcp_calculator/src/index.html rename to samples/community/renderer/angular/projects/mcp_calculator/src/index.html diff --git a/samples/client/angular/projects/restaurant/src/main.server.ts b/samples/community/renderer/angular/projects/mcp_calculator/src/main.server.ts similarity index 100% rename from samples/client/angular/projects/restaurant/src/main.server.ts rename to samples/community/renderer/angular/projects/mcp_calculator/src/main.server.ts diff --git a/samples/community/client/angular/projects/mcp_calculator/src/main.ts b/samples/community/renderer/angular/projects/mcp_calculator/src/main.ts similarity index 100% rename from samples/community/client/angular/projects/mcp_calculator/src/main.ts rename to samples/community/renderer/angular/projects/mcp_calculator/src/main.ts diff --git a/samples/community/client/angular/projects/mcp_calculator/src/server.ts b/samples/community/renderer/angular/projects/mcp_calculator/src/server.ts similarity index 100% rename from samples/community/client/angular/projects/mcp_calculator/src/server.ts rename to samples/community/renderer/angular/projects/mcp_calculator/src/server.ts diff --git a/samples/community/client/angular/projects/mcp_calculator/src/services/a2a-service-impl.ts b/samples/community/renderer/angular/projects/mcp_calculator/src/services/a2a-service-impl.ts similarity index 100% rename from samples/community/client/angular/projects/mcp_calculator/src/services/a2a-service-impl.ts rename to samples/community/renderer/angular/projects/mcp_calculator/src/services/a2a-service-impl.ts diff --git a/samples/community/client/angular/projects/mcp_calculator/src/styles.scss b/samples/community/renderer/angular/projects/mcp_calculator/src/styles.scss similarity index 100% rename from samples/community/client/angular/projects/mcp_calculator/src/styles.scss rename to samples/community/renderer/angular/projects/mcp_calculator/src/styles.scss diff --git a/samples/community/client/angular/projects/mcp_calculator/tsconfig.app.json b/samples/community/renderer/angular/projects/mcp_calculator/tsconfig.app.json similarity index 100% rename from samples/community/client/angular/projects/mcp_calculator/tsconfig.app.json rename to samples/community/renderer/angular/projects/mcp_calculator/tsconfig.app.json diff --git a/samples/community/client/angular/projects/mcp_calculator/tsconfig.spec.json b/samples/community/renderer/angular/projects/mcp_calculator/tsconfig.spec.json similarity index 100% rename from samples/community/client/angular/projects/mcp_calculator/tsconfig.spec.json rename to samples/community/renderer/angular/projects/mcp_calculator/tsconfig.spec.json diff --git a/samples/community/client/angular/projects/orchestrator/README.md b/samples/community/renderer/angular/projects/orchestrator/README.md similarity index 100% rename from samples/community/client/angular/projects/orchestrator/README.md rename to samples/community/renderer/angular/projects/orchestrator/README.md diff --git a/samples/community/client/angular/projects/orchestrator/package.json b/samples/community/renderer/angular/projects/orchestrator/package.json similarity index 100% rename from samples/community/client/angular/projects/orchestrator/package.json rename to samples/community/renderer/angular/projects/orchestrator/package.json diff --git a/samples/community/client/angular/projects/mcp_calculator/public/favicon.ico b/samples/community/renderer/angular/projects/orchestrator/public/favicon.ico similarity index 100% rename from samples/community/client/angular/projects/mcp_calculator/public/favicon.ico rename to samples/community/renderer/angular/projects/orchestrator/public/favicon.ico diff --git a/samples/community/client/angular/projects/orchestrator/public/gemini-color.svg b/samples/community/renderer/angular/projects/orchestrator/public/gemini-color.svg similarity index 100% rename from samples/community/client/angular/projects/orchestrator/public/gemini-color.svg rename to samples/community/renderer/angular/projects/orchestrator/public/gemini-color.svg diff --git a/samples/community/client/angular/projects/orchestrator/src/a2ui-catalog/catalog.ts b/samples/community/renderer/angular/projects/orchestrator/src/a2ui-catalog/catalog.ts similarity index 100% rename from samples/community/client/angular/projects/orchestrator/src/a2ui-catalog/catalog.ts rename to samples/community/renderer/angular/projects/orchestrator/src/a2ui-catalog/catalog.ts diff --git a/samples/community/client/angular/projects/orchestrator/src/a2ui-catalog/chart.ts b/samples/community/renderer/angular/projects/orchestrator/src/a2ui-catalog/chart.ts similarity index 100% rename from samples/community/client/angular/projects/orchestrator/src/a2ui-catalog/chart.ts rename to samples/community/renderer/angular/projects/orchestrator/src/a2ui-catalog/chart.ts diff --git a/samples/community/client/angular/projects/orchestrator/src/a2ui-catalog/google-map.ts b/samples/community/renderer/angular/projects/orchestrator/src/a2ui-catalog/google-map.ts similarity index 100% rename from samples/community/client/angular/projects/orchestrator/src/a2ui-catalog/google-map.ts rename to samples/community/renderer/angular/projects/orchestrator/src/a2ui-catalog/google-map.ts diff --git a/samples/community/client/angular/projects/orchestrator/src/app/app.config.server.ts b/samples/community/renderer/angular/projects/orchestrator/src/app/app.config.server.ts similarity index 100% rename from samples/community/client/angular/projects/orchestrator/src/app/app.config.server.ts rename to samples/community/renderer/angular/projects/orchestrator/src/app/app.config.server.ts diff --git a/samples/community/client/angular/projects/orchestrator/src/app/app.config.ts b/samples/community/renderer/angular/projects/orchestrator/src/app/app.config.ts similarity index 100% rename from samples/community/client/angular/projects/orchestrator/src/app/app.config.ts rename to samples/community/renderer/angular/projects/orchestrator/src/app/app.config.ts diff --git a/samples/community/client/angular/projects/orchestrator/src/app/app.html b/samples/community/renderer/angular/projects/orchestrator/src/app/app.html similarity index 100% rename from samples/community/client/angular/projects/orchestrator/src/app/app.html rename to samples/community/renderer/angular/projects/orchestrator/src/app/app.html diff --git a/samples/community/client/angular/projects/orchestrator/src/app/app.routes.server.ts b/samples/community/renderer/angular/projects/orchestrator/src/app/app.routes.server.ts similarity index 100% rename from samples/community/client/angular/projects/orchestrator/src/app/app.routes.server.ts rename to samples/community/renderer/angular/projects/orchestrator/src/app/app.routes.server.ts diff --git a/samples/community/client/angular/projects/orchestrator/src/app/app.routes.ts b/samples/community/renderer/angular/projects/orchestrator/src/app/app.routes.ts similarity index 100% rename from samples/community/client/angular/projects/orchestrator/src/app/app.routes.ts rename to samples/community/renderer/angular/projects/orchestrator/src/app/app.routes.ts diff --git a/samples/community/client/angular/projects/orchestrator/src/app/app.scss b/samples/community/renderer/angular/projects/orchestrator/src/app/app.scss similarity index 100% rename from samples/community/client/angular/projects/orchestrator/src/app/app.scss rename to samples/community/renderer/angular/projects/orchestrator/src/app/app.scss diff --git a/samples/community/client/angular/projects/orchestrator/src/app/app.ts b/samples/community/renderer/angular/projects/orchestrator/src/app/app.ts similarity index 100% rename from samples/community/client/angular/projects/orchestrator/src/app/app.ts rename to samples/community/renderer/angular/projects/orchestrator/src/app/app.ts diff --git a/samples/community/client/angular/projects/mcp_calculator/src/app/dummy.spec.ts b/samples/community/renderer/angular/projects/orchestrator/src/app/dummy.spec.ts similarity index 100% rename from samples/community/client/angular/projects/mcp_calculator/src/app/dummy.spec.ts rename to samples/community/renderer/angular/projects/orchestrator/src/app/dummy.spec.ts diff --git a/samples/community/client/angular/projects/orchestrator/src/environments/environment.ts b/samples/community/renderer/angular/projects/orchestrator/src/environments/environment.ts similarity index 100% rename from samples/community/client/angular/projects/orchestrator/src/environments/environment.ts rename to samples/community/renderer/angular/projects/orchestrator/src/environments/environment.ts diff --git a/samples/community/client/angular/projects/orchestrator/src/index.html b/samples/community/renderer/angular/projects/orchestrator/src/index.html similarity index 100% rename from samples/community/client/angular/projects/orchestrator/src/index.html rename to samples/community/renderer/angular/projects/orchestrator/src/index.html diff --git a/samples/community/client/angular/projects/mcp_calculator/src/main.server.ts b/samples/community/renderer/angular/projects/orchestrator/src/main.server.ts similarity index 100% rename from samples/community/client/angular/projects/mcp_calculator/src/main.server.ts rename to samples/community/renderer/angular/projects/orchestrator/src/main.server.ts diff --git a/samples/community/client/angular/projects/orchestrator/src/main.ts b/samples/community/renderer/angular/projects/orchestrator/src/main.ts similarity index 100% rename from samples/community/client/angular/projects/orchestrator/src/main.ts rename to samples/community/renderer/angular/projects/orchestrator/src/main.ts diff --git a/samples/community/client/angular/projects/orchestrator/src/message-decorator/demo-message-decorator.html b/samples/community/renderer/angular/projects/orchestrator/src/message-decorator/demo-message-decorator.html similarity index 100% rename from samples/community/client/angular/projects/orchestrator/src/message-decorator/demo-message-decorator.html rename to samples/community/renderer/angular/projects/orchestrator/src/message-decorator/demo-message-decorator.html diff --git a/samples/community/client/angular/projects/orchestrator/src/message-decorator/demo-message-decorator.scss b/samples/community/renderer/angular/projects/orchestrator/src/message-decorator/demo-message-decorator.scss similarity index 100% rename from samples/community/client/angular/projects/orchestrator/src/message-decorator/demo-message-decorator.scss rename to samples/community/renderer/angular/projects/orchestrator/src/message-decorator/demo-message-decorator.scss diff --git a/samples/community/client/angular/projects/orchestrator/src/message-decorator/demo-message-decorator.ts b/samples/community/renderer/angular/projects/orchestrator/src/message-decorator/demo-message-decorator.ts similarity index 100% rename from samples/community/client/angular/projects/orchestrator/src/message-decorator/demo-message-decorator.ts rename to samples/community/renderer/angular/projects/orchestrator/src/message-decorator/demo-message-decorator.ts diff --git a/samples/community/client/angular/projects/orchestrator/src/server.ts b/samples/community/renderer/angular/projects/orchestrator/src/server.ts similarity index 100% rename from samples/community/client/angular/projects/orchestrator/src/server.ts rename to samples/community/renderer/angular/projects/orchestrator/src/server.ts diff --git a/samples/community/client/angular/projects/orchestrator/src/services/a2a-service-impl.spec.ts b/samples/community/renderer/angular/projects/orchestrator/src/services/a2a-service-impl.spec.ts similarity index 100% rename from samples/community/client/angular/projects/orchestrator/src/services/a2a-service-impl.spec.ts rename to samples/community/renderer/angular/projects/orchestrator/src/services/a2a-service-impl.spec.ts diff --git a/samples/community/client/angular/projects/orchestrator/src/services/a2a-service-impl.ts b/samples/community/renderer/angular/projects/orchestrator/src/services/a2a-service-impl.ts similarity index 100% rename from samples/community/client/angular/projects/orchestrator/src/services/a2a-service-impl.ts rename to samples/community/renderer/angular/projects/orchestrator/src/services/a2a-service-impl.ts diff --git a/samples/community/client/angular/projects/orchestrator/src/styles.scss b/samples/community/renderer/angular/projects/orchestrator/src/styles.scss similarity index 100% rename from samples/community/client/angular/projects/orchestrator/src/styles.scss rename to samples/community/renderer/angular/projects/orchestrator/src/styles.scss diff --git a/samples/community/client/angular/projects/orchestrator/tsconfig.app.json b/samples/community/renderer/angular/projects/orchestrator/tsconfig.app.json similarity index 100% rename from samples/community/client/angular/projects/orchestrator/tsconfig.app.json rename to samples/community/renderer/angular/projects/orchestrator/tsconfig.app.json diff --git a/samples/community/client/angular/projects/orchestrator/tsconfig.spec.json b/samples/community/renderer/angular/projects/orchestrator/tsconfig.spec.json similarity index 100% rename from samples/community/client/angular/projects/orchestrator/tsconfig.spec.json rename to samples/community/renderer/angular/projects/orchestrator/tsconfig.spec.json diff --git a/samples/community/client/angular/tsconfig.json b/samples/community/renderer/angular/tsconfig.json similarity index 100% rename from samples/community/client/angular/tsconfig.json rename to samples/community/renderer/angular/tsconfig.json diff --git a/samples/community/client/lit/mcp-apps-in-a2ui-sample/.gitignore b/samples/community/renderer/lit/mcp-apps-in-a2ui-sample/.gitignore similarity index 100% rename from samples/community/client/lit/mcp-apps-in-a2ui-sample/.gitignore rename to samples/community/renderer/lit/mcp-apps-in-a2ui-sample/.gitignore diff --git a/samples/community/client/lit/mcp-apps-in-a2ui-sample/README.md b/samples/community/renderer/lit/mcp-apps-in-a2ui-sample/README.md similarity index 98% rename from samples/community/client/lit/mcp-apps-in-a2ui-sample/README.md rename to samples/community/renderer/lit/mcp-apps-in-a2ui-sample/README.md index 13bee191f2..931f8d3d76 100644 --- a/samples/community/client/lit/mcp-apps-in-a2ui-sample/README.md +++ b/samples/community/renderer/lit/mcp-apps-in-a2ui-sample/README.md @@ -38,7 +38,7 @@ The agent will start on `http://localhost:8000`. Navigate to the client sample directory and start the dev server: ```bash -cd samples/client/lit/mcp-apps-in-a2ui-sample +cd samples/renderer/lit/mcp-apps-in-a2ui-sample yarn dev ``` diff --git a/samples/community/client/lit/mcp-apps-in-a2ui-sample/client.ts b/samples/community/renderer/lit/mcp-apps-in-a2ui-sample/client.ts similarity index 100% rename from samples/community/client/lit/mcp-apps-in-a2ui-sample/client.ts rename to samples/community/renderer/lit/mcp-apps-in-a2ui-sample/client.ts diff --git a/samples/community/client/lit/mcp-apps-in-a2ui-sample/eslint.config.mjs b/samples/community/renderer/lit/mcp-apps-in-a2ui-sample/eslint.config.mjs similarity index 100% rename from samples/community/client/lit/mcp-apps-in-a2ui-sample/eslint.config.mjs rename to samples/community/renderer/lit/mcp-apps-in-a2ui-sample/eslint.config.mjs diff --git a/samples/community/client/lit/mcp-apps-in-a2ui-sample/index.html b/samples/community/renderer/lit/mcp-apps-in-a2ui-sample/index.html similarity index 100% rename from samples/community/client/lit/mcp-apps-in-a2ui-sample/index.html rename to samples/community/renderer/lit/mcp-apps-in-a2ui-sample/index.html diff --git a/samples/community/client/lit/mcp-apps-in-a2ui-sample/mcp-app.ts b/samples/community/renderer/lit/mcp-apps-in-a2ui-sample/mcp-app.ts similarity index 100% rename from samples/community/client/lit/mcp-apps-in-a2ui-sample/mcp-app.ts rename to samples/community/renderer/lit/mcp-apps-in-a2ui-sample/mcp-app.ts diff --git a/samples/community/client/lit/mcp-apps-in-a2ui-sample/middleware/a2a.ts b/samples/community/renderer/lit/mcp-apps-in-a2ui-sample/middleware/a2a.ts similarity index 100% rename from samples/community/client/lit/mcp-apps-in-a2ui-sample/middleware/a2a.ts rename to samples/community/renderer/lit/mcp-apps-in-a2ui-sample/middleware/a2a.ts diff --git a/samples/client/lit/shell/middleware/index.ts b/samples/community/renderer/lit/mcp-apps-in-a2ui-sample/middleware/index.ts similarity index 100% rename from samples/client/lit/shell/middleware/index.ts rename to samples/community/renderer/lit/mcp-apps-in-a2ui-sample/middleware/index.ts diff --git a/samples/community/client/lit/mcp-apps-in-a2ui-sample/package.json b/samples/community/renderer/lit/mcp-apps-in-a2ui-sample/package.json similarity index 96% rename from samples/community/client/lit/mcp-apps-in-a2ui-sample/package.json rename to samples/community/renderer/lit/mcp-apps-in-a2ui-sample/package.json index de1ba462b6..30347614f0 100644 --- a/samples/community/client/lit/mcp-apps-in-a2ui-sample/package.json +++ b/samples/community/renderer/lit/mcp-apps-in-a2ui-sample/package.json @@ -54,7 +54,7 @@ } }, "repository": { - "directory": "samples/client/lit/mcp-apps-in-a2ui-sample", + "directory": "samples/renderer/lit/mcp-apps-in-a2ui-sample", "type": "git", "url": "git+https://github.com/a2ui-project/a2ui.git" }, diff --git a/samples/community/client/lit/mcp-apps-in-a2ui-sample/theme/theme.ts b/samples/community/renderer/lit/mcp-apps-in-a2ui-sample/theme/theme.ts similarity index 100% rename from samples/community/client/lit/mcp-apps-in-a2ui-sample/theme/theme.ts rename to samples/community/renderer/lit/mcp-apps-in-a2ui-sample/theme/theme.ts diff --git a/samples/community/client/lit/mcp-apps-in-a2ui-sample/tsconfig.json b/samples/community/renderer/lit/mcp-apps-in-a2ui-sample/tsconfig.json similarity index 100% rename from samples/community/client/lit/mcp-apps-in-a2ui-sample/tsconfig.json rename to samples/community/renderer/lit/mcp-apps-in-a2ui-sample/tsconfig.json diff --git a/samples/community/client/lit/mcp-apps-in-a2ui-sample/ui/custom-components/mcp-apps-component.ts b/samples/community/renderer/lit/mcp-apps-in-a2ui-sample/ui/custom-components/mcp-apps-component.ts similarity index 100% rename from samples/community/client/lit/mcp-apps-in-a2ui-sample/ui/custom-components/mcp-apps-component.ts rename to samples/community/renderer/lit/mcp-apps-in-a2ui-sample/ui/custom-components/mcp-apps-component.ts diff --git a/samples/community/client/lit/mcp-apps-in-a2ui-sample/ui/custom-components/register-components.ts b/samples/community/renderer/lit/mcp-apps-in-a2ui-sample/ui/custom-components/register-components.ts similarity index 100% rename from samples/community/client/lit/mcp-apps-in-a2ui-sample/ui/custom-components/register-components.ts rename to samples/community/renderer/lit/mcp-apps-in-a2ui-sample/ui/custom-components/register-components.ts diff --git a/samples/community/client/lit/mcp-apps-in-a2ui-sample/ui/shared-constants.ts b/samples/community/renderer/lit/mcp-apps-in-a2ui-sample/ui/shared-constants.ts similarity index 100% rename from samples/community/client/lit/mcp-apps-in-a2ui-sample/ui/shared-constants.ts rename to samples/community/renderer/lit/mcp-apps-in-a2ui-sample/ui/shared-constants.ts diff --git a/samples/community/client/lit/mcp-apps-in-a2ui-sample/vite.config.ts b/samples/community/renderer/lit/mcp-apps-in-a2ui-sample/vite.config.ts similarity index 100% rename from samples/community/client/lit/mcp-apps-in-a2ui-sample/vite.config.ts rename to samples/community/renderer/lit/mcp-apps-in-a2ui-sample/vite.config.ts diff --git a/samples/community/client/lit/personalized_learning/.dockerignore b/samples/community/renderer/lit/personalized_learning/.dockerignore similarity index 100% rename from samples/community/client/lit/personalized_learning/.dockerignore rename to samples/community/renderer/lit/personalized_learning/.dockerignore diff --git a/samples/community/client/lit/personalized_learning/.env.template b/samples/community/renderer/lit/personalized_learning/.env.template similarity index 100% rename from samples/community/client/lit/personalized_learning/.env.template rename to samples/community/renderer/lit/personalized_learning/.env.template diff --git a/samples/community/client/lit/personalized_learning/.gcloudignore b/samples/community/renderer/lit/personalized_learning/.gcloudignore similarity index 100% rename from samples/community/client/lit/personalized_learning/.gcloudignore rename to samples/community/renderer/lit/personalized_learning/.gcloudignore diff --git a/samples/community/client/lit/personalized_learning/.gitignore b/samples/community/renderer/lit/personalized_learning/.gitignore similarity index 100% rename from samples/community/client/lit/personalized_learning/.gitignore rename to samples/community/renderer/lit/personalized_learning/.gitignore diff --git a/samples/community/client/lit/personalized_learning/Dockerfile b/samples/community/renderer/lit/personalized_learning/Dockerfile similarity index 100% rename from samples/community/client/lit/personalized_learning/Dockerfile rename to samples/community/renderer/lit/personalized_learning/Dockerfile diff --git a/samples/community/client/lit/personalized_learning/Quickstart.ipynb b/samples/community/renderer/lit/personalized_learning/Quickstart.ipynb similarity index 100% rename from samples/community/client/lit/personalized_learning/Quickstart.ipynb rename to samples/community/renderer/lit/personalized_learning/Quickstart.ipynb diff --git a/samples/community/client/lit/personalized_learning/README.md b/samples/community/renderer/lit/personalized_learning/README.md similarity index 100% rename from samples/community/client/lit/personalized_learning/README.md rename to samples/community/renderer/lit/personalized_learning/README.md diff --git a/samples/community/client/lit/personalized_learning/a2ui-primer.html b/samples/community/renderer/lit/personalized_learning/a2ui-primer.html similarity index 100% rename from samples/community/client/lit/personalized_learning/a2ui-primer.html rename to samples/community/renderer/lit/personalized_learning/a2ui-primer.html diff --git a/samples/community/client/lit/personalized_learning/api-server.ts b/samples/community/renderer/lit/personalized_learning/api-server.ts similarity index 100% rename from samples/community/client/lit/personalized_learning/api-server.ts rename to samples/community/renderer/lit/personalized_learning/api-server.ts diff --git a/samples/community/client/lit/personalized_learning/assets/architecture.jpg b/samples/community/renderer/lit/personalized_learning/assets/architecture.jpg similarity index 100% rename from samples/community/client/lit/personalized_learning/assets/architecture.jpg rename to samples/community/renderer/lit/personalized_learning/assets/architecture.jpg diff --git a/samples/community/client/lit/personalized_learning/assets/hero.jpg b/samples/community/renderer/lit/personalized_learning/assets/hero.jpg similarity index 100% rename from samples/community/client/lit/personalized_learning/assets/hero.jpg rename to samples/community/renderer/lit/personalized_learning/assets/hero.jpg diff --git a/samples/community/client/lit/personalized_learning/deploy.py b/samples/community/renderer/lit/personalized_learning/deploy.py similarity index 100% rename from samples/community/client/lit/personalized_learning/deploy.py rename to samples/community/renderer/lit/personalized_learning/deploy.py diff --git a/samples/community/client/lit/personalized_learning/deploy_hosting.py b/samples/community/renderer/lit/personalized_learning/deploy_hosting.py similarity index 100% rename from samples/community/client/lit/personalized_learning/deploy_hosting.py rename to samples/community/renderer/lit/personalized_learning/deploy_hosting.py diff --git a/samples/community/client/lit/personalized_learning/eslint.config.mjs b/samples/community/renderer/lit/personalized_learning/eslint.config.mjs similarity index 100% rename from samples/community/client/lit/personalized_learning/eslint.config.mjs rename to samples/community/renderer/lit/personalized_learning/eslint.config.mjs diff --git a/samples/community/client/lit/personalized_learning/index.html b/samples/community/renderer/lit/personalized_learning/index.html similarity index 100% rename from samples/community/client/lit/personalized_learning/index.html rename to samples/community/renderer/lit/personalized_learning/index.html diff --git a/samples/community/client/lit/personalized_learning/package.json b/samples/community/renderer/lit/personalized_learning/package.json similarity index 100% rename from samples/community/client/lit/personalized_learning/package.json rename to samples/community/renderer/lit/personalized_learning/package.json diff --git a/samples/community/client/lit/personalized_learning/public/404.html b/samples/community/renderer/lit/personalized_learning/public/404.html similarity index 100% rename from samples/community/client/lit/personalized_learning/public/404.html rename to samples/community/renderer/lit/personalized_learning/public/404.html diff --git a/samples/community/client/lit/personalized_learning/public/assets/.gitkeep b/samples/community/renderer/lit/personalized_learning/public/assets/.gitkeep similarity index 100% rename from samples/community/client/lit/personalized_learning/public/assets/.gitkeep rename to samples/community/renderer/lit/personalized_learning/public/assets/.gitkeep diff --git a/samples/community/client/lit/personalized_learning/public/assets/openstax-bio-glossary.md b/samples/community/renderer/lit/personalized_learning/public/assets/openstax-bio-glossary.md similarity index 100% rename from samples/community/client/lit/personalized_learning/public/assets/openstax-bio-glossary.md rename to samples/community/renderer/lit/personalized_learning/public/assets/openstax-bio-glossary.md diff --git a/samples/community/client/lit/personalized_learning/public/favicon.svg b/samples/community/renderer/lit/personalized_learning/public/favicon.svg similarity index 100% rename from samples/community/client/lit/personalized_learning/public/favicon.svg rename to samples/community/renderer/lit/personalized_learning/public/favicon.svg diff --git a/samples/community/client/lit/personalized_learning/public/maria-context.html b/samples/community/renderer/lit/personalized_learning/public/maria-context.html similarity index 100% rename from samples/community/client/lit/personalized_learning/public/maria-context.html rename to samples/community/renderer/lit/personalized_learning/public/maria-context.html diff --git a/samples/community/client/lit/personalized_learning/quickstart_setup.sh b/samples/community/renderer/lit/personalized_learning/quickstart_setup.sh similarity index 100% rename from samples/community/client/lit/personalized_learning/quickstart_setup.sh rename to samples/community/renderer/lit/personalized_learning/quickstart_setup.sh diff --git a/samples/community/client/lit/personalized_learning/src/a2a-client.ts b/samples/community/renderer/lit/personalized_learning/src/a2a-client.ts similarity index 100% rename from samples/community/client/lit/personalized_learning/src/a2a-client.ts rename to samples/community/renderer/lit/personalized_learning/src/a2a-client.ts diff --git a/samples/community/client/lit/personalized_learning/src/a2ui-renderer.ts b/samples/community/renderer/lit/personalized_learning/src/a2ui-renderer.ts similarity index 100% rename from samples/community/client/lit/personalized_learning/src/a2ui-renderer.ts rename to samples/community/renderer/lit/personalized_learning/src/a2ui-renderer.ts diff --git a/samples/community/client/lit/personalized_learning/src/chat-orchestrator.ts b/samples/community/renderer/lit/personalized_learning/src/chat-orchestrator.ts similarity index 100% rename from samples/community/client/lit/personalized_learning/src/chat-orchestrator.ts rename to samples/community/renderer/lit/personalized_learning/src/chat-orchestrator.ts diff --git a/samples/community/client/lit/personalized_learning/src/firebase-auth.ts b/samples/community/renderer/lit/personalized_learning/src/firebase-auth.ts similarity index 100% rename from samples/community/client/lit/personalized_learning/src/firebase-auth.ts rename to samples/community/renderer/lit/personalized_learning/src/firebase-auth.ts diff --git a/samples/community/client/lit/personalized_learning/src/flashcard.ts b/samples/community/renderer/lit/personalized_learning/src/flashcard.ts similarity index 100% rename from samples/community/client/lit/personalized_learning/src/flashcard.ts rename to samples/community/renderer/lit/personalized_learning/src/flashcard.ts diff --git a/samples/community/client/lit/personalized_learning/src/main.ts b/samples/community/renderer/lit/personalized_learning/src/main.ts similarity index 100% rename from samples/community/client/lit/personalized_learning/src/main.ts rename to samples/community/renderer/lit/personalized_learning/src/main.ts diff --git a/samples/community/client/lit/personalized_learning/src/quiz-card.ts b/samples/community/renderer/lit/personalized_learning/src/quiz-card.ts similarity index 100% rename from samples/community/client/lit/personalized_learning/src/quiz-card.ts rename to samples/community/renderer/lit/personalized_learning/src/quiz-card.ts diff --git a/samples/community/client/lit/personalized_learning/src/theme-provider.ts b/samples/community/renderer/lit/personalized_learning/src/theme-provider.ts similarity index 100% rename from samples/community/client/lit/personalized_learning/src/theme-provider.ts rename to samples/community/renderer/lit/personalized_learning/src/theme-provider.ts diff --git a/samples/community/client/lit/personalized_learning/src/theme.ts b/samples/community/renderer/lit/personalized_learning/src/theme.ts similarity index 100% rename from samples/community/client/lit/personalized_learning/src/theme.ts rename to samples/community/renderer/lit/personalized_learning/src/theme.ts diff --git a/samples/community/client/lit/personalized_learning/src/types.ts b/samples/community/renderer/lit/personalized_learning/src/types.ts similarity index 100% rename from samples/community/client/lit/personalized_learning/src/types.ts rename to samples/community/renderer/lit/personalized_learning/src/types.ts diff --git a/samples/community/client/lit/personalized_learning/src/vite-env.d.ts b/samples/community/renderer/lit/personalized_learning/src/vite-env.d.ts similarity index 100% rename from samples/community/client/lit/personalized_learning/src/vite-env.d.ts rename to samples/community/renderer/lit/personalized_learning/src/vite-env.d.ts diff --git a/samples/community/client/lit/personalized_learning/tsconfig.json b/samples/community/renderer/lit/personalized_learning/tsconfig.json similarity index 100% rename from samples/community/client/lit/personalized_learning/tsconfig.json rename to samples/community/renderer/lit/personalized_learning/tsconfig.json diff --git a/samples/community/client/lit/personalized_learning/vite.config.ts b/samples/community/renderer/lit/personalized_learning/vite.config.ts similarity index 100% rename from samples/community/client/lit/personalized_learning/vite.config.ts rename to samples/community/renderer/lit/personalized_learning/vite.config.ts diff --git a/samples/community/client/shared/mcp_apps_inner_iframe/README.md b/samples/community/renderer/shared/mcp_apps_inner_iframe/README.md similarity index 100% rename from samples/community/client/shared/mcp_apps_inner_iframe/README.md rename to samples/community/renderer/shared/mcp_apps_inner_iframe/README.md diff --git a/samples/client/shared/mcp_apps_inner_iframe/sandbox.html b/samples/community/renderer/shared/mcp_apps_inner_iframe/sandbox.html similarity index 100% rename from samples/client/shared/mcp_apps_inner_iframe/sandbox.html rename to samples/community/renderer/shared/mcp_apps_inner_iframe/sandbox.html diff --git a/samples/client/shared/mcp_apps_inner_iframe/sandbox.ts b/samples/community/renderer/shared/mcp_apps_inner_iframe/sandbox.ts similarity index 100% rename from samples/client/shared/mcp_apps_inner_iframe/sandbox.ts rename to samples/community/renderer/shared/mcp_apps_inner_iframe/sandbox.ts diff --git a/samples/client/angular/README.md b/samples/renderer/angular/README.md similarity index 97% rename from samples/client/angular/README.md rename to samples/renderer/angular/README.md index 605a32c498..f9226d1380 100644 --- a/samples/client/angular/README.md +++ b/samples/renderer/angular/README.md @@ -21,7 +21,7 @@ The restaurant app has two parts that run separately: the **agent backend** (a P 2. **Set up your Gemini API key:** ```bash - cd samples/client/angular + cd samples/renderer/angular cp ../../agent/adk/restaurant_finder/.env.example ../../agent/adk/restaurant_finder/.env # Edit the .env file with your actual API key (.env is gitignored for security reasons) ``` @@ -38,7 +38,7 @@ The restaurant app has two parts that run separately: the **agent backend** (a P - Angular frontend — serves on `http://localhost:4200`: ```bash - cd samples/client/angular + cd samples/renderer/angular yarn start restaurant ``` diff --git a/samples/client/angular/angular.json b/samples/renderer/angular/angular.json similarity index 100% rename from samples/client/angular/angular.json rename to samples/renderer/angular/angular.json diff --git a/samples/client/angular/eslint.config.mjs b/samples/renderer/angular/eslint.config.mjs similarity index 100% rename from samples/client/angular/eslint.config.mjs rename to samples/renderer/angular/eslint.config.mjs diff --git a/samples/client/angular/package.json b/samples/renderer/angular/package.json similarity index 100% rename from samples/client/angular/package.json rename to samples/renderer/angular/package.json diff --git a/samples/client/angular/projects/lib/ng-package.json b/samples/renderer/angular/projects/lib/ng-package.json similarity index 100% rename from samples/client/angular/projects/lib/ng-package.json rename to samples/renderer/angular/projects/lib/ng-package.json diff --git a/samples/client/angular/projects/lib/package.json b/samples/renderer/angular/projects/lib/package.json similarity index 100% rename from samples/client/angular/projects/lib/package.json rename to samples/renderer/angular/projects/lib/package.json diff --git a/samples/client/angular/projects/lib/src b/samples/renderer/angular/projects/lib/src similarity index 100% rename from samples/client/angular/projects/lib/src rename to samples/renderer/angular/projects/lib/src diff --git a/samples/client/angular/projects/lib/tsconfig.lib.json b/samples/renderer/angular/projects/lib/tsconfig.lib.json similarity index 100% rename from samples/client/angular/projects/lib/tsconfig.lib.json rename to samples/renderer/angular/projects/lib/tsconfig.lib.json diff --git a/samples/client/angular/projects/lib/tsconfig.lib.prod.json b/samples/renderer/angular/projects/lib/tsconfig.lib.prod.json similarity index 100% rename from samples/client/angular/projects/lib/tsconfig.lib.prod.json rename to samples/renderer/angular/projects/lib/tsconfig.lib.prod.json diff --git a/samples/client/angular/projects/restaurant/package.json b/samples/renderer/angular/projects/restaurant/package.json similarity index 100% rename from samples/client/angular/projects/restaurant/package.json rename to samples/renderer/angular/projects/restaurant/package.json diff --git a/samples/community/client/angular/projects/orchestrator/public/favicon.ico b/samples/renderer/angular/projects/restaurant/public/favicon.ico similarity index 100% rename from samples/community/client/angular/projects/orchestrator/public/favicon.ico rename to samples/renderer/angular/projects/restaurant/public/favicon.ico diff --git a/samples/client/angular/projects/restaurant/public/hero.png b/samples/renderer/angular/projects/restaurant/public/hero.png similarity index 100% rename from samples/client/angular/projects/restaurant/public/hero.png rename to samples/renderer/angular/projects/restaurant/public/hero.png diff --git a/samples/client/angular/projects/restaurant/src/app/app.config.server.ts b/samples/renderer/angular/projects/restaurant/src/app/app.config.server.ts similarity index 100% rename from samples/client/angular/projects/restaurant/src/app/app.config.server.ts rename to samples/renderer/angular/projects/restaurant/src/app/app.config.server.ts diff --git a/samples/client/angular/projects/restaurant/src/app/app.config.ts b/samples/renderer/angular/projects/restaurant/src/app/app.config.ts similarity index 91% rename from samples/client/angular/projects/restaurant/src/app/app.config.ts rename to samples/renderer/angular/projects/restaurant/src/app/app.config.ts index 0d3f746629..c0e715d1bb 100644 --- a/samples/client/angular/projects/restaurant/src/app/app.config.ts +++ b/samples/renderer/angular/projects/restaurant/src/app/app.config.ts @@ -30,7 +30,7 @@ import { } from '@angular/core'; import {provideClientHydration, withEventReplay} from '@angular/platform-browser'; import {renderMarkdown} from '@a2ui/markdown-it'; -import {A2uiClientAction} from '@a2ui/web_core/v0_9'; +import {A2uiRendererAction} from '@a2ui/web_core/v0_9'; export const appConfig: ApplicationConfig = { providers: [ @@ -43,7 +43,7 @@ export const appConfig: ApplicationConfig = { const injector = inject(Injector); return { catalogs: [new BasicCatalog()], - actionHandler: (action: A2uiClientAction) => injector.get(Client).handleAction(action), + actionHandler: (action: A2uiRendererAction) => injector.get(Client).handleAction(action), }; }, }, diff --git a/samples/client/angular/projects/restaurant/src/app/app.css b/samples/renderer/angular/projects/restaurant/src/app/app.css similarity index 100% rename from samples/client/angular/projects/restaurant/src/app/app.css rename to samples/renderer/angular/projects/restaurant/src/app/app.css diff --git a/samples/client/angular/projects/restaurant/src/app/app.html b/samples/renderer/angular/projects/restaurant/src/app/app.html similarity index 100% rename from samples/client/angular/projects/restaurant/src/app/app.html rename to samples/renderer/angular/projects/restaurant/src/app/app.html diff --git a/samples/client/angular/projects/restaurant/src/app/app.ts b/samples/renderer/angular/projects/restaurant/src/app/app.ts similarity index 100% rename from samples/client/angular/projects/restaurant/src/app/app.ts rename to samples/renderer/angular/projects/restaurant/src/app/app.ts diff --git a/samples/client/angular/projects/restaurant/src/app/client.ts b/samples/renderer/angular/projects/restaurant/src/app/client.ts similarity index 97% rename from samples/client/angular/projects/restaurant/src/app/client.ts rename to samples/renderer/angular/projects/restaurant/src/app/client.ts index 643cfa3f4c..88bf5b6a36 100644 --- a/samples/client/angular/projects/restaurant/src/app/client.ts +++ b/samples/renderer/angular/projects/restaurant/src/app/client.ts @@ -17,7 +17,7 @@ import {A2uiRendererService} from '@a2ui/angular/v0_9'; import * as Types from '@a2ui/web_core/types/types'; import {inject, Injectable, signal} from '@angular/core'; -import {A2uiClientAction, A2uiMessage} from '@a2ui/web_core/v0_9'; +import {A2uiRendererAction, A2uiMessage} from '@a2ui/web_core/v0_9'; @Injectable({providedIn: 'root'}) export class Client { @@ -26,7 +26,7 @@ export class Client { readonly isLoading = signal(false); - async handleAction(userAction: A2uiClientAction) { + async handleAction(userAction: A2uiRendererAction) { try { const messages = await this.makeRequest({userAction}); this.renderer.processMessages(messages as unknown as A2uiMessage[]); diff --git a/samples/community/client/angular/projects/orchestrator/src/app/dummy.spec.ts b/samples/renderer/angular/projects/restaurant/src/app/dummy.spec.ts similarity index 100% rename from samples/community/client/angular/projects/orchestrator/src/app/dummy.spec.ts rename to samples/renderer/angular/projects/restaurant/src/app/dummy.spec.ts diff --git a/samples/client/angular/projects/restaurant/src/app/theme.ts b/samples/renderer/angular/projects/restaurant/src/app/theme.ts similarity index 100% rename from samples/client/angular/projects/restaurant/src/app/theme.ts rename to samples/renderer/angular/projects/restaurant/src/app/theme.ts diff --git a/samples/client/angular/projects/restaurant/src/index.html b/samples/renderer/angular/projects/restaurant/src/index.html similarity index 100% rename from samples/client/angular/projects/restaurant/src/index.html rename to samples/renderer/angular/projects/restaurant/src/index.html diff --git a/samples/community/client/angular/projects/orchestrator/src/main.server.ts b/samples/renderer/angular/projects/restaurant/src/main.server.ts similarity index 100% rename from samples/community/client/angular/projects/orchestrator/src/main.server.ts rename to samples/renderer/angular/projects/restaurant/src/main.server.ts diff --git a/samples/client/angular/projects/restaurant/src/main.ts b/samples/renderer/angular/projects/restaurant/src/main.ts similarity index 100% rename from samples/client/angular/projects/restaurant/src/main.ts rename to samples/renderer/angular/projects/restaurant/src/main.ts diff --git a/samples/client/angular/projects/restaurant/src/restaurant-theme.css b/samples/renderer/angular/projects/restaurant/src/restaurant-theme.css similarity index 100% rename from samples/client/angular/projects/restaurant/src/restaurant-theme.css rename to samples/renderer/angular/projects/restaurant/src/restaurant-theme.css diff --git a/samples/client/angular/projects/restaurant/src/server.ts b/samples/renderer/angular/projects/restaurant/src/server.ts similarity index 100% rename from samples/client/angular/projects/restaurant/src/server.ts rename to samples/renderer/angular/projects/restaurant/src/server.ts diff --git a/samples/client/angular/projects/restaurant/src/styles.css b/samples/renderer/angular/projects/restaurant/src/styles.css similarity index 100% rename from samples/client/angular/projects/restaurant/src/styles.css rename to samples/renderer/angular/projects/restaurant/src/styles.css diff --git a/samples/client/angular/projects/restaurant/tsconfig.app.json b/samples/renderer/angular/projects/restaurant/tsconfig.app.json similarity index 100% rename from samples/client/angular/projects/restaurant/tsconfig.app.json rename to samples/renderer/angular/projects/restaurant/tsconfig.app.json diff --git a/samples/client/angular/projects/restaurant/tsconfig.spec.json b/samples/renderer/angular/projects/restaurant/tsconfig.spec.json similarity index 100% rename from samples/client/angular/projects/restaurant/tsconfig.spec.json rename to samples/renderer/angular/projects/restaurant/tsconfig.spec.json diff --git a/samples/client/angular/tsconfig.json b/samples/renderer/angular/tsconfig.json similarity index 100% rename from samples/client/angular/tsconfig.json rename to samples/renderer/angular/tsconfig.json diff --git a/samples/client/flutter/README.md b/samples/renderer/flutter/README.md similarity index 100% rename from samples/client/flutter/README.md rename to samples/renderer/flutter/README.md diff --git a/samples/client/flutter/restaurant_finder/README.md b/samples/renderer/flutter/restaurant_finder/README.md similarity index 100% rename from samples/client/flutter/restaurant_finder/README.md rename to samples/renderer/flutter/restaurant_finder/README.md diff --git a/samples/client/flutter/restaurant_finder/app/.gitignore b/samples/renderer/flutter/restaurant_finder/app/.gitignore similarity index 100% rename from samples/client/flutter/restaurant_finder/app/.gitignore rename to samples/renderer/flutter/restaurant_finder/app/.gitignore diff --git a/samples/client/flutter/restaurant_finder/app/.metadata b/samples/renderer/flutter/restaurant_finder/app/.metadata similarity index 100% rename from samples/client/flutter/restaurant_finder/app/.metadata rename to samples/renderer/flutter/restaurant_finder/app/.metadata diff --git a/samples/client/flutter/restaurant_finder/app/lib/restaurant_finder_client.dart b/samples/renderer/flutter/restaurant_finder/app/lib/restaurant_finder_client.dart similarity index 100% rename from samples/client/flutter/restaurant_finder/app/lib/restaurant_finder_client.dart rename to samples/renderer/flutter/restaurant_finder/app/lib/restaurant_finder_client.dart diff --git a/samples/client/flutter/restaurant_finder/app/lib/src/main.dart b/samples/renderer/flutter/restaurant_finder/app/lib/src/main.dart similarity index 100% rename from samples/client/flutter/restaurant_finder/app/lib/src/main.dart rename to samples/renderer/flutter/restaurant_finder/app/lib/src/main.dart diff --git a/samples/client/flutter/restaurant_finder/app/lib/src/primitives.dart b/samples/renderer/flutter/restaurant_finder/app/lib/src/primitives.dart similarity index 100% rename from samples/client/flutter/restaurant_finder/app/lib/src/primitives.dart rename to samples/renderer/flutter/restaurant_finder/app/lib/src/primitives.dart diff --git a/samples/client/flutter/restaurant_finder/app/lib/src/screen.dart b/samples/renderer/flutter/restaurant_finder/app/lib/src/screen.dart similarity index 100% rename from samples/client/flutter/restaurant_finder/app/lib/src/screen.dart rename to samples/renderer/flutter/restaurant_finder/app/lib/src/screen.dart diff --git a/samples/client/flutter/restaurant_finder/app/lib/src/session.dart b/samples/renderer/flutter/restaurant_finder/app/lib/src/session.dart similarity index 100% rename from samples/client/flutter/restaurant_finder/app/lib/src/session.dart rename to samples/renderer/flutter/restaurant_finder/app/lib/src/session.dart diff --git a/samples/client/flutter/restaurant_finder/app/macos/.gitignore b/samples/renderer/flutter/restaurant_finder/app/macos/.gitignore similarity index 100% rename from samples/client/flutter/restaurant_finder/app/macos/.gitignore rename to samples/renderer/flutter/restaurant_finder/app/macos/.gitignore diff --git a/samples/client/flutter/restaurant_finder/app/macos/Flutter/Flutter-Debug.xcconfig b/samples/renderer/flutter/restaurant_finder/app/macos/Flutter/Flutter-Debug.xcconfig similarity index 100% rename from samples/client/flutter/restaurant_finder/app/macos/Flutter/Flutter-Debug.xcconfig rename to samples/renderer/flutter/restaurant_finder/app/macos/Flutter/Flutter-Debug.xcconfig diff --git a/samples/client/flutter/restaurant_finder/app/macos/Flutter/Flutter-Release.xcconfig b/samples/renderer/flutter/restaurant_finder/app/macos/Flutter/Flutter-Release.xcconfig similarity index 100% rename from samples/client/flutter/restaurant_finder/app/macos/Flutter/Flutter-Release.xcconfig rename to samples/renderer/flutter/restaurant_finder/app/macos/Flutter/Flutter-Release.xcconfig diff --git a/samples/client/flutter/restaurant_finder/app/macos/Podfile b/samples/renderer/flutter/restaurant_finder/app/macos/Podfile similarity index 100% rename from samples/client/flutter/restaurant_finder/app/macos/Podfile rename to samples/renderer/flutter/restaurant_finder/app/macos/Podfile diff --git a/samples/client/flutter/restaurant_finder/app/macos/Runner.xcodeproj/project.pbxproj b/samples/renderer/flutter/restaurant_finder/app/macos/Runner.xcodeproj/project.pbxproj similarity index 100% rename from samples/client/flutter/restaurant_finder/app/macos/Runner.xcodeproj/project.pbxproj rename to samples/renderer/flutter/restaurant_finder/app/macos/Runner.xcodeproj/project.pbxproj diff --git a/samples/client/flutter/restaurant_finder/app/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/samples/renderer/flutter/restaurant_finder/app/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist similarity index 100% rename from samples/client/flutter/restaurant_finder/app/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist rename to samples/renderer/flutter/restaurant_finder/app/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist diff --git a/samples/client/flutter/restaurant_finder/app/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/samples/renderer/flutter/restaurant_finder/app/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme similarity index 100% rename from samples/client/flutter/restaurant_finder/app/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme rename to samples/renderer/flutter/restaurant_finder/app/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme diff --git a/samples/client/flutter/restaurant_finder/app/macos/Runner.xcworkspace/contents.xcworkspacedata b/samples/renderer/flutter/restaurant_finder/app/macos/Runner.xcworkspace/contents.xcworkspacedata similarity index 100% rename from samples/client/flutter/restaurant_finder/app/macos/Runner.xcworkspace/contents.xcworkspacedata rename to samples/renderer/flutter/restaurant_finder/app/macos/Runner.xcworkspace/contents.xcworkspacedata diff --git a/samples/client/flutter/restaurant_finder/app/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/samples/renderer/flutter/restaurant_finder/app/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist similarity index 100% rename from samples/client/flutter/restaurant_finder/app/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist rename to samples/renderer/flutter/restaurant_finder/app/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist diff --git a/samples/client/flutter/restaurant_finder/app/macos/Runner/AppDelegate.swift b/samples/renderer/flutter/restaurant_finder/app/macos/Runner/AppDelegate.swift similarity index 100% rename from samples/client/flutter/restaurant_finder/app/macos/Runner/AppDelegate.swift rename to samples/renderer/flutter/restaurant_finder/app/macos/Runner/AppDelegate.swift diff --git a/samples/client/flutter/restaurant_finder/app/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/samples/renderer/flutter/restaurant_finder/app/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json similarity index 100% rename from samples/client/flutter/restaurant_finder/app/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json rename to samples/renderer/flutter/restaurant_finder/app/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json diff --git a/samples/client/flutter/restaurant_finder/app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png b/samples/renderer/flutter/restaurant_finder/app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png similarity index 100% rename from samples/client/flutter/restaurant_finder/app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png rename to samples/renderer/flutter/restaurant_finder/app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png diff --git a/samples/client/flutter/restaurant_finder/app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png b/samples/renderer/flutter/restaurant_finder/app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png similarity index 100% rename from samples/client/flutter/restaurant_finder/app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png rename to samples/renderer/flutter/restaurant_finder/app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png diff --git a/samples/client/flutter/restaurant_finder/app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png b/samples/renderer/flutter/restaurant_finder/app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png similarity index 100% rename from samples/client/flutter/restaurant_finder/app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png rename to samples/renderer/flutter/restaurant_finder/app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png diff --git a/samples/client/flutter/restaurant_finder/app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png b/samples/renderer/flutter/restaurant_finder/app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png similarity index 100% rename from samples/client/flutter/restaurant_finder/app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png rename to samples/renderer/flutter/restaurant_finder/app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png diff --git a/samples/client/flutter/restaurant_finder/app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png b/samples/renderer/flutter/restaurant_finder/app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png similarity index 100% rename from samples/client/flutter/restaurant_finder/app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png rename to samples/renderer/flutter/restaurant_finder/app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png diff --git a/samples/client/flutter/restaurant_finder/app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png b/samples/renderer/flutter/restaurant_finder/app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png similarity index 100% rename from samples/client/flutter/restaurant_finder/app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png rename to samples/renderer/flutter/restaurant_finder/app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png diff --git a/samples/client/flutter/restaurant_finder/app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png b/samples/renderer/flutter/restaurant_finder/app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png similarity index 100% rename from samples/client/flutter/restaurant_finder/app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png rename to samples/renderer/flutter/restaurant_finder/app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png diff --git a/samples/client/flutter/restaurant_finder/app/macos/Runner/Base.lproj/MainMenu.xib b/samples/renderer/flutter/restaurant_finder/app/macos/Runner/Base.lproj/MainMenu.xib similarity index 100% rename from samples/client/flutter/restaurant_finder/app/macos/Runner/Base.lproj/MainMenu.xib rename to samples/renderer/flutter/restaurant_finder/app/macos/Runner/Base.lproj/MainMenu.xib diff --git a/samples/client/flutter/restaurant_finder/app/macos/Runner/Configs/AppInfo.xcconfig b/samples/renderer/flutter/restaurant_finder/app/macos/Runner/Configs/AppInfo.xcconfig similarity index 100% rename from samples/client/flutter/restaurant_finder/app/macos/Runner/Configs/AppInfo.xcconfig rename to samples/renderer/flutter/restaurant_finder/app/macos/Runner/Configs/AppInfo.xcconfig diff --git a/samples/client/flutter/restaurant_finder/app/macos/Runner/Configs/Debug.xcconfig b/samples/renderer/flutter/restaurant_finder/app/macos/Runner/Configs/Debug.xcconfig similarity index 100% rename from samples/client/flutter/restaurant_finder/app/macos/Runner/Configs/Debug.xcconfig rename to samples/renderer/flutter/restaurant_finder/app/macos/Runner/Configs/Debug.xcconfig diff --git a/samples/client/flutter/restaurant_finder/app/macos/Runner/Configs/Release.xcconfig b/samples/renderer/flutter/restaurant_finder/app/macos/Runner/Configs/Release.xcconfig similarity index 100% rename from samples/client/flutter/restaurant_finder/app/macos/Runner/Configs/Release.xcconfig rename to samples/renderer/flutter/restaurant_finder/app/macos/Runner/Configs/Release.xcconfig diff --git a/samples/client/flutter/restaurant_finder/app/macos/Runner/Configs/Warnings.xcconfig b/samples/renderer/flutter/restaurant_finder/app/macos/Runner/Configs/Warnings.xcconfig similarity index 100% rename from samples/client/flutter/restaurant_finder/app/macos/Runner/Configs/Warnings.xcconfig rename to samples/renderer/flutter/restaurant_finder/app/macos/Runner/Configs/Warnings.xcconfig diff --git a/samples/client/flutter/restaurant_finder/app/macos/Runner/DebugProfile.entitlements b/samples/renderer/flutter/restaurant_finder/app/macos/Runner/DebugProfile.entitlements similarity index 100% rename from samples/client/flutter/restaurant_finder/app/macos/Runner/DebugProfile.entitlements rename to samples/renderer/flutter/restaurant_finder/app/macos/Runner/DebugProfile.entitlements diff --git a/samples/client/flutter/restaurant_finder/app/macos/Runner/Info.plist b/samples/renderer/flutter/restaurant_finder/app/macos/Runner/Info.plist similarity index 100% rename from samples/client/flutter/restaurant_finder/app/macos/Runner/Info.plist rename to samples/renderer/flutter/restaurant_finder/app/macos/Runner/Info.plist diff --git a/samples/client/flutter/restaurant_finder/app/macos/Runner/MainFlutterWindow.swift b/samples/renderer/flutter/restaurant_finder/app/macos/Runner/MainFlutterWindow.swift similarity index 100% rename from samples/client/flutter/restaurant_finder/app/macos/Runner/MainFlutterWindow.swift rename to samples/renderer/flutter/restaurant_finder/app/macos/Runner/MainFlutterWindow.swift diff --git a/samples/client/flutter/restaurant_finder/app/macos/Runner/Release.entitlements b/samples/renderer/flutter/restaurant_finder/app/macos/Runner/Release.entitlements similarity index 100% rename from samples/client/flutter/restaurant_finder/app/macos/Runner/Release.entitlements rename to samples/renderer/flutter/restaurant_finder/app/macos/Runner/Release.entitlements diff --git a/samples/client/flutter/restaurant_finder/app/macos/RunnerTests/RunnerTests.swift b/samples/renderer/flutter/restaurant_finder/app/macos/RunnerTests/RunnerTests.swift similarity index 100% rename from samples/client/flutter/restaurant_finder/app/macos/RunnerTests/RunnerTests.swift rename to samples/renderer/flutter/restaurant_finder/app/macos/RunnerTests/RunnerTests.swift diff --git a/samples/client/flutter/restaurant_finder/app/pubspec.yaml b/samples/renderer/flutter/restaurant_finder/app/pubspec.yaml similarity index 100% rename from samples/client/flutter/restaurant_finder/app/pubspec.yaml rename to samples/renderer/flutter/restaurant_finder/app/pubspec.yaml diff --git a/samples/client/flutter/restaurant_finder/app/test/widget_test.dart b/samples/renderer/flutter/restaurant_finder/app/test/widget_test.dart similarity index 100% rename from samples/client/flutter/restaurant_finder/app/test/widget_test.dart rename to samples/renderer/flutter/restaurant_finder/app/test/widget_test.dart diff --git a/samples/client/flutter/restaurant_finder/app/web/favicon.png b/samples/renderer/flutter/restaurant_finder/app/web/favicon.png similarity index 100% rename from samples/client/flutter/restaurant_finder/app/web/favicon.png rename to samples/renderer/flutter/restaurant_finder/app/web/favicon.png diff --git a/samples/client/flutter/restaurant_finder/app/web/icons/Icon-192.png b/samples/renderer/flutter/restaurant_finder/app/web/icons/Icon-192.png similarity index 100% rename from samples/client/flutter/restaurant_finder/app/web/icons/Icon-192.png rename to samples/renderer/flutter/restaurant_finder/app/web/icons/Icon-192.png diff --git a/samples/client/flutter/restaurant_finder/app/web/icons/Icon-512.png b/samples/renderer/flutter/restaurant_finder/app/web/icons/Icon-512.png similarity index 100% rename from samples/client/flutter/restaurant_finder/app/web/icons/Icon-512.png rename to samples/renderer/flutter/restaurant_finder/app/web/icons/Icon-512.png diff --git a/samples/client/flutter/restaurant_finder/app/web/icons/Icon-maskable-192.png b/samples/renderer/flutter/restaurant_finder/app/web/icons/Icon-maskable-192.png similarity index 100% rename from samples/client/flutter/restaurant_finder/app/web/icons/Icon-maskable-192.png rename to samples/renderer/flutter/restaurant_finder/app/web/icons/Icon-maskable-192.png diff --git a/samples/client/flutter/restaurant_finder/app/web/icons/Icon-maskable-512.png b/samples/renderer/flutter/restaurant_finder/app/web/icons/Icon-maskable-512.png similarity index 100% rename from samples/client/flutter/restaurant_finder/app/web/icons/Icon-maskable-512.png rename to samples/renderer/flutter/restaurant_finder/app/web/icons/Icon-maskable-512.png diff --git a/samples/client/flutter/restaurant_finder/app/web/index.html b/samples/renderer/flutter/restaurant_finder/app/web/index.html similarity index 100% rename from samples/client/flutter/restaurant_finder/app/web/index.html rename to samples/renderer/flutter/restaurant_finder/app/web/index.html diff --git a/samples/client/flutter/restaurant_finder/app/web/manifest.json b/samples/renderer/flutter/restaurant_finder/app/web/manifest.json similarity index 100% rename from samples/client/flutter/restaurant_finder/app/web/manifest.json rename to samples/renderer/flutter/restaurant_finder/app/web/manifest.json diff --git a/samples/client/flutter/restaurant_finder/e2e_test/README.md b/samples/renderer/flutter/restaurant_finder/e2e_test/README.md similarity index 100% rename from samples/client/flutter/restaurant_finder/e2e_test/README.md rename to samples/renderer/flutter/restaurant_finder/e2e_test/README.md diff --git a/samples/client/flutter/restaurant_finder/e2e_test/pubspec.yaml b/samples/renderer/flutter/restaurant_finder/e2e_test/pubspec.yaml similarity index 100% rename from samples/client/flutter/restaurant_finder/e2e_test/pubspec.yaml rename to samples/renderer/flutter/restaurant_finder/e2e_test/pubspec.yaml diff --git a/samples/client/flutter/restaurant_finder/e2e_test/test/infra_test.dart b/samples/renderer/flutter/restaurant_finder/e2e_test/test/infra_test.dart similarity index 100% rename from samples/client/flutter/restaurant_finder/e2e_test/test/infra_test.dart rename to samples/renderer/flutter/restaurant_finder/e2e_test/test/infra_test.dart diff --git a/samples/client/flutter/restaurant_finder/e2e_test/test/session_test.dart b/samples/renderer/flutter/restaurant_finder/e2e_test/test/session_test.dart similarity index 100% rename from samples/client/flutter/restaurant_finder/e2e_test/test/session_test.dart rename to samples/renderer/flutter/restaurant_finder/e2e_test/test/session_test.dart diff --git a/samples/client/flutter/restaurant_finder/e2e_test/test/test_infra/ai_client.dart b/samples/renderer/flutter/restaurant_finder/e2e_test/test/test_infra/ai_client.dart similarity index 100% rename from samples/client/flutter/restaurant_finder/e2e_test/test/test_infra/ai_client.dart rename to samples/renderer/flutter/restaurant_finder/e2e_test/test/test_infra/ai_client.dart diff --git a/samples/client/flutter/restaurant_finder/e2e_test/test/test_infra/api_key.dart b/samples/renderer/flutter/restaurant_finder/e2e_test/test/test_infra/api_key.dart similarity index 100% rename from samples/client/flutter/restaurant_finder/e2e_test/test/test_infra/api_key.dart rename to samples/renderer/flutter/restaurant_finder/e2e_test/test/test_infra/api_key.dart diff --git a/samples/client/flutter/restaurant_finder/e2e_test/test/test_infra/issue_reporter.dart b/samples/renderer/flutter/restaurant_finder/e2e_test/test/test_infra/issue_reporter.dart similarity index 100% rename from samples/client/flutter/restaurant_finder/e2e_test/test/test_infra/issue_reporter.dart rename to samples/renderer/flutter/restaurant_finder/e2e_test/test/test_infra/issue_reporter.dart diff --git a/samples/client/flutter/restaurant_finder/e2e_test/test/test_infra/restaurant_finder.dart b/samples/renderer/flutter/restaurant_finder/e2e_test/test/test_infra/restaurant_finder.dart similarity index 100% rename from samples/client/flutter/restaurant_finder/e2e_test/test/test_infra/restaurant_finder.dart rename to samples/renderer/flutter/restaurant_finder/e2e_test/test/test_infra/restaurant_finder.dart diff --git a/samples/client/flutter/restaurant_finder/e2e_test/test/test_infra/shell_utils.dart b/samples/renderer/flutter/restaurant_finder/e2e_test/test/test_infra/shell_utils.dart similarity index 100% rename from samples/client/flutter/restaurant_finder/e2e_test/test/test_infra/shell_utils.dart rename to samples/renderer/flutter/restaurant_finder/e2e_test/test/test_infra/shell_utils.dart diff --git a/samples/client/lit/package.json b/samples/renderer/lit/package.json similarity index 100% rename from samples/client/lit/package.json rename to samples/renderer/lit/package.json diff --git a/samples/client/lit/shell/README.md b/samples/renderer/lit/shell/README.md similarity index 98% rename from samples/client/lit/shell/README.md rename to samples/renderer/lit/shell/README.md index 64fc67e081..c30d2c0f86 100644 --- a/samples/client/lit/shell/README.md +++ b/samples/renderer/lit/shell/README.md @@ -22,7 +22,7 @@ See the [video](https://github.com/user-attachments/assets/2a406115-3a17-4bea-80 2. **Run this sample:** ```bash - cd samples/client/lit/shell + cd samples/renderer/lit/shell ``` 3. **Run the servers:** diff --git a/samples/client/lit/shell/THEMING.md b/samples/renderer/lit/shell/THEMING.md similarity index 100% rename from samples/client/lit/shell/THEMING.md rename to samples/renderer/lit/shell/THEMING.md diff --git a/samples/client/lit/shell/app.ts b/samples/renderer/lit/shell/app.ts similarity index 99% rename from samples/client/lit/shell/app.ts rename to samples/renderer/lit/shell/app.ts index ebf3069455..489713ea46 100644 --- a/samples/client/lit/shell/app.ts +++ b/samples/renderer/lit/shell/app.ts @@ -513,7 +513,7 @@ export class A2UILayoutEditor extends SignalWatcher(LitElement) { // Create a Message Processor that uses the catalogs. private _processor = new v0_9.MessageProcessor( [basicCatalog], - async (action: v0_9.A2uiClientAction): Promise => { + async (action: v0_9.A2uiRendererAction): Promise => { console.debug('Handling action', action); const context: Record = {...action.context}; diff --git a/samples/client/lit/shell/client.ts b/samples/renderer/lit/shell/client.ts similarity index 100% rename from samples/client/lit/shell/client.ts rename to samples/renderer/lit/shell/client.ts diff --git a/samples/client/lit/shell/configs/configs.ts b/samples/renderer/lit/shell/configs/configs.ts similarity index 100% rename from samples/client/lit/shell/configs/configs.ts rename to samples/renderer/lit/shell/configs/configs.ts diff --git a/samples/client/lit/shell/configs/local.ts b/samples/renderer/lit/shell/configs/local.ts similarity index 100% rename from samples/client/lit/shell/configs/local.ts rename to samples/renderer/lit/shell/configs/local.ts diff --git a/samples/client/lit/shell/configs/restaurant.ts b/samples/renderer/lit/shell/configs/restaurant.ts similarity index 100% rename from samples/client/lit/shell/configs/restaurant.ts rename to samples/renderer/lit/shell/configs/restaurant.ts diff --git a/samples/client/lit/shell/configs/types.ts b/samples/renderer/lit/shell/configs/types.ts similarity index 100% rename from samples/client/lit/shell/configs/types.ts rename to samples/renderer/lit/shell/configs/types.ts diff --git a/samples/client/lit/shell/eslint.config.mjs b/samples/renderer/lit/shell/eslint.config.mjs similarity index 100% rename from samples/client/lit/shell/eslint.config.mjs rename to samples/renderer/lit/shell/eslint.config.mjs diff --git a/samples/client/lit/shell/events/events.ts b/samples/renderer/lit/shell/events/events.ts similarity index 100% rename from samples/client/lit/shell/events/events.ts rename to samples/renderer/lit/shell/events/events.ts diff --git a/samples/client/lit/shell/index.html b/samples/renderer/lit/shell/index.html similarity index 100% rename from samples/client/lit/shell/index.html rename to samples/renderer/lit/shell/index.html diff --git a/samples/client/lit/shell/middleware/a2a.ts b/samples/renderer/lit/shell/middleware/a2a.ts similarity index 100% rename from samples/client/lit/shell/middleware/a2a.ts rename to samples/renderer/lit/shell/middleware/a2a.ts diff --git a/samples/community/client/lit/mcp-apps-in-a2ui-sample/middleware/index.ts b/samples/renderer/lit/shell/middleware/index.ts similarity index 100% rename from samples/community/client/lit/mcp-apps-in-a2ui-sample/middleware/index.ts rename to samples/renderer/lit/shell/middleware/index.ts diff --git a/samples/client/lit/shell/package.json b/samples/renderer/lit/shell/package.json similarity index 98% rename from samples/client/lit/shell/package.json rename to samples/renderer/lit/shell/package.json index dd378b0240..93325e58f9 100644 --- a/samples/client/lit/shell/package.json +++ b/samples/renderer/lit/shell/package.json @@ -66,7 +66,7 @@ } }, "repository": { - "directory": "samples/client/lit/shell", + "directory": "samples/renderer/lit/shell", "type": "git", "url": "git+https://github.com/a2ui-project/a2ui.git" }, diff --git a/samples/client/lit/shell/public/hero-dark.png b/samples/renderer/lit/shell/public/hero-dark.png similarity index 100% rename from samples/client/lit/shell/public/hero-dark.png rename to samples/renderer/lit/shell/public/hero-dark.png diff --git a/samples/client/lit/shell/public/hero.png b/samples/renderer/lit/shell/public/hero.png similarity index 100% rename from samples/client/lit/shell/public/hero.png rename to samples/renderer/lit/shell/public/hero.png diff --git a/samples/client/lit/shell/public/sample/city_skyline.jpg b/samples/renderer/lit/shell/public/sample/city_skyline.jpg similarity index 100% rename from samples/client/lit/shell/public/sample/city_skyline.jpg rename to samples/renderer/lit/shell/public/sample/city_skyline.jpg diff --git a/samples/client/lit/shell/public/sample/forest_path.jpg b/samples/renderer/lit/shell/public/sample/forest_path.jpg similarity index 100% rename from samples/client/lit/shell/public/sample/forest_path.jpg rename to samples/renderer/lit/shell/public/sample/forest_path.jpg diff --git a/samples/client/lit/shell/public/sample/scenic_view.jpg b/samples/renderer/lit/shell/public/sample/scenic_view.jpg similarity index 100% rename from samples/client/lit/shell/public/sample/scenic_view.jpg rename to samples/renderer/lit/shell/public/sample/scenic_view.jpg diff --git a/samples/client/lit/shell/public/samples/contact_card.json b/samples/renderer/lit/shell/public/samples/contact_card.json similarity index 100% rename from samples/client/lit/shell/public/samples/contact_card.json rename to samples/renderer/lit/shell/public/samples/contact_card.json diff --git a/samples/client/lit/shell/public/samples/workspace_settings.json b/samples/renderer/lit/shell/public/samples/workspace_settings.json similarity index 100% rename from samples/client/lit/shell/public/samples/workspace_settings.json rename to samples/renderer/lit/shell/public/samples/workspace_settings.json diff --git a/samples/client/lit/shell/tests/smoke-test.spec.ts b/samples/renderer/lit/shell/tests/smoke-test.spec.ts similarity index 100% rename from samples/client/lit/shell/tests/smoke-test.spec.ts rename to samples/renderer/lit/shell/tests/smoke-test.spec.ts diff --git a/samples/client/lit/shell/theme/restaurant-theme.ts b/samples/renderer/lit/shell/theme/restaurant-theme.ts similarity index 100% rename from samples/client/lit/shell/theme/restaurant-theme.ts rename to samples/renderer/lit/shell/theme/restaurant-theme.ts diff --git a/samples/client/lit/shell/tsconfig.json b/samples/renderer/lit/shell/tsconfig.json similarity index 100% rename from samples/client/lit/shell/tsconfig.json rename to samples/renderer/lit/shell/tsconfig.json diff --git a/samples/client/lit/shell/types/types.ts b/samples/renderer/lit/shell/types/types.ts similarity index 100% rename from samples/client/lit/shell/types/types.ts rename to samples/renderer/lit/shell/types/types.ts diff --git a/samples/client/lit/shell/ui/snackbar.ts b/samples/renderer/lit/shell/ui/snackbar.ts similarity index 100% rename from samples/client/lit/shell/ui/snackbar.ts rename to samples/renderer/lit/shell/ui/snackbar.ts diff --git a/samples/client/lit/shell/vite.config.ts b/samples/renderer/lit/shell/vite.config.ts similarity index 100% rename from samples/client/lit/shell/vite.config.ts rename to samples/renderer/lit/shell/vite.config.ts diff --git a/samples/client/react/shell/README.md b/samples/renderer/react/shell/README.md similarity index 98% rename from samples/client/react/shell/README.md rename to samples/renderer/react/shell/README.md index f8af4e6d2d..af4f75d22b 100644 --- a/samples/client/react/shell/README.md +++ b/samples/renderer/react/shell/README.md @@ -39,7 +39,7 @@ uv run . In another terminal, start the React dev server: ```bash -cd samples/client/react/shell +cd samples/renderer/react/shell yarn dev ``` diff --git a/samples/client/react/shell/eslint.config.mjs b/samples/renderer/react/shell/eslint.config.mjs similarity index 100% rename from samples/client/react/shell/eslint.config.mjs rename to samples/renderer/react/shell/eslint.config.mjs diff --git a/samples/client/react/shell/index.html b/samples/renderer/react/shell/index.html similarity index 100% rename from samples/client/react/shell/index.html rename to samples/renderer/react/shell/index.html diff --git a/samples/client/react/shell/middleware/a2a.ts b/samples/renderer/react/shell/middleware/a2a.ts similarity index 100% rename from samples/client/react/shell/middleware/a2a.ts rename to samples/renderer/react/shell/middleware/a2a.ts diff --git a/samples/client/react/shell/package.json b/samples/renderer/react/shell/package.json similarity index 100% rename from samples/client/react/shell/package.json rename to samples/renderer/react/shell/package.json diff --git a/samples/client/react/shell/public/hero-dark.png b/samples/renderer/react/shell/public/hero-dark.png similarity index 100% rename from samples/client/react/shell/public/hero-dark.png rename to samples/renderer/react/shell/public/hero-dark.png diff --git a/samples/client/react/shell/public/hero.png b/samples/renderer/react/shell/public/hero.png similarity index 100% rename from samples/client/react/shell/public/hero.png rename to samples/renderer/react/shell/public/hero.png diff --git a/samples/client/react/shell/src/App.css b/samples/renderer/react/shell/src/App.css similarity index 100% rename from samples/client/react/shell/src/App.css rename to samples/renderer/react/shell/src/App.css diff --git a/samples/client/react/shell/src/App.tsx b/samples/renderer/react/shell/src/App.tsx similarity index 95% rename from samples/client/react/shell/src/App.tsx rename to samples/renderer/react/shell/src/App.tsx index b4913f05ed..4788084990 100644 --- a/samples/client/react/shell/src/App.tsx +++ b/samples/renderer/react/shell/src/App.tsx @@ -21,7 +21,12 @@ import { MarkdownContext, ReactComponentImplementation, } from '@a2ui/react/v0_9'; -import {A2uiClientMessage, A2uiMessage, MessageProcessor, SurfaceModel} from '@a2ui/web_core/v0_9'; +import { + A2uiRendererMessage, + A2uiMessage, + MessageProcessor, + SurfaceModel, +} from '@a2ui/web_core/v0_9'; import {renderMarkdown} from '@a2ui/markdown-it'; import {A2UIClient} from './client'; import {AppConfig, restaurantConfig} from './configs'; @@ -61,9 +66,9 @@ export function App() { }, [config]); // Use a ref to hold the sendAndProcess function that will be set by ShellContent - const sendAndProcessRef = useRef<((message: A2uiClientMessage | string) => Promise) | null>( - null, - ); + const sendAndProcessRef = useRef< + ((message: A2uiRendererMessage | string) => Promise) | null + >(null); const processor = useMemo(() => { return new MessageProcessor([basicCatalog], action => { @@ -90,7 +95,7 @@ interface ShellContentProps { config: AppConfig; client: A2UIClient; sendAndProcessRef: React.MutableRefObject< - ((message: A2uiClientMessage | string) => Promise) | null + ((message: A2uiRendererMessage | string) => Promise) | null >; processor: MessageProcessor; } @@ -138,7 +143,7 @@ function ShellContent({config, client, sendAndProcessRef, processor}: ShellConte }, [requesting, config.loadingText]); // Generate mock response based on message/action - const getMockResponse = useCallback((message: A2uiClientMessage | string): A2uiMessage[] => { + const getMockResponse = useCallback((message: A2uiRendererMessage | string): A2uiMessage[] => { // Handle user actions if (typeof message === 'object' && 'action' in message) { const action = message.action; @@ -171,7 +176,7 @@ function ShellContent({config, client, sendAndProcessRef, processor}: ShellConte // Send message to agent and process response const sendAndProcess = useCallback( - async (message: A2uiClientMessage | string) => { + async (message: A2uiRendererMessage | string) => { try { setRequesting(true); setError(null); diff --git a/samples/client/react/shell/src/client.ts b/samples/renderer/react/shell/src/client.ts similarity index 97% rename from samples/client/react/shell/src/client.ts rename to samples/renderer/react/shell/src/client.ts index 27ed3c4f60..1497cc2ac0 100644 --- a/samples/client/react/shell/src/client.ts +++ b/samples/renderer/react/shell/src/client.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import type {A2uiMessage, A2uiClientMessage} from '@a2ui/web_core/v0_9'; +import type {A2uiMessage, A2uiRendererMessage} from '@a2ui/web_core/v0_9'; interface Part { kind: 'data' | 'text' | 'error'; @@ -29,7 +29,7 @@ export class A2UIClient { } async send( - message: A2uiClientMessage | string, + message: A2uiRendererMessage | string, onChunk?: (messages: A2uiMessage[]) => void, ): Promise { const body = typeof message === 'string' ? message : JSON.stringify(message); diff --git a/samples/client/react/shell/src/configs/index.ts b/samples/renderer/react/shell/src/configs/index.ts similarity index 100% rename from samples/client/react/shell/src/configs/index.ts rename to samples/renderer/react/shell/src/configs/index.ts diff --git a/samples/client/react/shell/src/configs/restaurant.ts b/samples/renderer/react/shell/src/configs/restaurant.ts similarity index 100% rename from samples/client/react/shell/src/configs/restaurant.ts rename to samples/renderer/react/shell/src/configs/restaurant.ts diff --git a/samples/client/react/shell/src/configs/types.ts b/samples/renderer/react/shell/src/configs/types.ts similarity index 100% rename from samples/client/react/shell/src/configs/types.ts rename to samples/renderer/react/shell/src/configs/types.ts diff --git a/samples/client/react/shell/src/main.tsx b/samples/renderer/react/shell/src/main.tsx similarity index 100% rename from samples/client/react/shell/src/main.tsx rename to samples/renderer/react/shell/src/main.tsx diff --git a/samples/client/react/shell/src/mock/index.ts b/samples/renderer/react/shell/src/mock/index.ts similarity index 100% rename from samples/client/react/shell/src/mock/index.ts rename to samples/renderer/react/shell/src/mock/index.ts diff --git a/samples/client/react/shell/src/mock/restaurantMessages.ts b/samples/renderer/react/shell/src/mock/restaurantMessages.ts similarity index 100% rename from samples/client/react/shell/src/mock/restaurantMessages.ts rename to samples/renderer/react/shell/src/mock/restaurantMessages.ts diff --git a/samples/client/react/shell/src/theme/default-theme.ts b/samples/renderer/react/shell/src/theme/default-theme.ts similarity index 100% rename from samples/client/react/shell/src/theme/default-theme.ts rename to samples/renderer/react/shell/src/theme/default-theme.ts diff --git a/samples/client/react/shell/tsconfig.json b/samples/renderer/react/shell/tsconfig.json similarity index 100% rename from samples/client/react/shell/tsconfig.json rename to samples/renderer/react/shell/tsconfig.json diff --git a/samples/client/react/shell/vite.config.ts b/samples/renderer/react/shell/vite.config.ts similarity index 100% rename from samples/client/react/shell/vite.config.ts rename to samples/renderer/react/shell/vite.config.ts diff --git a/samples/client/shared/mcp_apps_inner_iframe/README.md b/samples/renderer/shared/mcp_apps_inner_iframe/README.md similarity index 100% rename from samples/client/shared/mcp_apps_inner_iframe/README.md rename to samples/renderer/shared/mcp_apps_inner_iframe/README.md diff --git a/samples/community/client/shared/mcp_apps_inner_iframe/sandbox.html b/samples/renderer/shared/mcp_apps_inner_iframe/sandbox.html similarity index 100% rename from samples/community/client/shared/mcp_apps_inner_iframe/sandbox.html rename to samples/renderer/shared/mcp_apps_inner_iframe/sandbox.html diff --git a/samples/community/client/shared/mcp_apps_inner_iframe/sandbox.ts b/samples/renderer/shared/mcp_apps_inner_iframe/sandbox.ts similarity index 100% rename from samples/community/client/shared/mcp_apps_inner_iframe/sandbox.ts rename to samples/renderer/shared/mcp_apps_inner_iframe/sandbox.ts diff --git a/scripts/e2e_test.sh b/scripts/e2e_test.sh index 87c18024ae..70efb0117a 100755 --- a/scripts/e2e_test.sh +++ b/scripts/e2e_test.sh @@ -26,6 +26,6 @@ # To run script locally, you need to set API key as an environment variable. # Example: export GEMINI_API_KEY=your_api_key -cd "$(dirname "$0")/../samples/client/flutter/restaurant_finder/e2e_test" +cd "$(dirname "$0")/../samples/renderer/flutter/restaurant_finder/e2e_test" # Parallel tests are disabled to avoid conflicts on environment. flutter test --concurrency=1 --dart-define=GEMINI_API_KEY="$GEMINI_API_KEY" diff --git a/scripts/fix_format.sh b/scripts/fix_format.sh index ddb96d39ee..763966796c 100755 --- a/scripts/fix_format.sh +++ b/scripts/fix_format.sh @@ -91,9 +91,9 @@ if command -v dart >/dev/null 2>&1; then fi if [ "$CHECK_ONLY" = true ]; then - dart format --output=none --set-exit-if-changed samples/client/flutter renderers/flutter + dart format --output=none --set-exit-if-changed samples/renderer/flutter renderers/flutter else - dart format samples/client/flutter renderers/flutter + dart format samples/renderer/flutter renderers/flutter fi else echo "Warning: dart command not found. Skipping Dart formatting." diff --git a/specification/v1_0/eval/src/index.ts b/specification/v1_0/eval/src/index.ts index dce292e714..f8bc8c29eb 100644 --- a/specification/v1_0/eval/src/index.ts +++ b/specification/v1_0/eval/src/index.ts @@ -30,7 +30,7 @@ import {analysisFlow} from './analysis_flow'; const schemaFiles = [ '../../json/common_types.json', '../../catalogs/basic/catalog.json', - '../../json/server_to_client.json', + '../../json/agent_to_renderer.json', ]; function loadSchemas(): ProtocolSchemas { @@ -42,7 +42,7 @@ function loadSchemas(): ProtocolSchemas { schemas[key] = schema; } - // Alias catalogs/basic/catalog.json to catalog.json to match server_to_client.json references + // Alias catalogs/basic/catalog.json to catalog.json to match agent_to_renderer.json references // This mirrors the logic in run_tests.py if (schemas['catalogs/basic/catalog.json']) { const catalogSchema = JSON.parse(JSON.stringify(schemas['catalogs/basic/catalog.json'])); diff --git a/specification/v1_0/eval/src/test_validator.ts b/specification/v1_0/eval/src/test_validator.ts index 2c57e797ee..e9999d0a80 100644 --- a/specification/v1_0/eval/src/test_validator.ts +++ b/specification/v1_0/eval/src/test_validator.ts @@ -22,7 +22,7 @@ import {GeneratedResult, ProtocolSchemas} from './types'; const schemaFiles = [ '../../json/common_types.json', '../../catalogs/basic/catalog.json', - '../../json/server_to_client.json', + '../../json/agent_to_renderer.json', ]; function loadSchemas(): ProtocolSchemas { diff --git a/specification/v1_0/eval/src/types.ts b/specification/v1_0/eval/src/types.ts index 6c98588b8a..2f164e7b8b 100644 --- a/specification/v1_0/eval/src/types.ts +++ b/specification/v1_0/eval/src/types.ts @@ -45,7 +45,7 @@ export interface EvaluatedResult extends ValidatedResult { export interface FunctionDefinition { description?: string; args?: Record; - callableFrom?: 'clientOnly' | 'remoteOnly' | 'clientOrRemote'; + callableFrom?: 'rendererOnly' | 'agentOnly' | 'rendererOrAgent'; returnType?: string; [key: string]: unknown; } @@ -86,7 +86,7 @@ export interface JsonSchema { export interface ProtocolSchemas { 'catalogs/basic/catalog.json'?: CatalogSchema; 'json/common_types.json'?: JsonSchema; - 'json/server_to_client.json'?: JsonSchema; + 'json/agent_to_renderer.json'?: JsonSchema; 'catalog.json'?: CatalogSchema; [key: string]: JsonSchema | CatalogSchema | undefined; } diff --git a/specification/v1_0/eval/src/validator.ts b/specification/v1_0/eval/src/validator.ts index 397055ac2f..630269a512 100644 --- a/specification/v1_0/eval/src/validator.ts +++ b/specification/v1_0/eval/src/validator.ts @@ -41,7 +41,7 @@ export class Validator { } } this.validateFn = this.ajv.getSchema( - 'https://a2ui.org/specification/v1_0/server_to_client.json', + 'https://a2ui.org/specification/v1_0/agent_to_renderer.json', ); // Populate basic functions from the catalog schema @@ -87,7 +87,7 @@ export class Validator { // Smart validation: check which key is present and validate against that specific definition // to avoid noisy "oneOf" errors. let validated = false; - const schemaUri = 'https://a2ui.org/specification/v1_0/server_to_client.json'; + const schemaUri = 'https://a2ui.org/specification/v1_0/agent_to_renderer.json'; if (message.createSurface) { validated = this.ajv.validate(`${schemaUri}#/$defs/CreateSurfaceMessage`, message); diff --git a/specification/v1_0/json/agent_capabilities.json b/specification/v1_0/json/agent_capabilities.json new file mode 100644 index 0000000000..5a81402cad --- /dev/null +++ b/specification/v1_0/json/agent_capabilities.json @@ -0,0 +1,26 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://a2ui.org/specification/v1_0/agent_capabilities.json", + "title": "A2UI Agent Capabilities Schema", + "description": "A schema for the agent capabilities object, which is used by an A2UI Agent to advertise its supported UI features to renderers. This can be embedded in an Agent Card for A2A or used in other transport protocols like MCP.", + "type": "object", + "properties": { + "v1.0": { + "type": "object", + "description": "The agent capabilities structure for version 1.0 of the A2UI protocol.", + "properties": { + "supportedCatalogIds": { + "type": "array", + "description": "An array of strings, where each string is an ID identifying a Catalog Definition Schema that the agent can generate. This is not necessarily a resolvable URI.", + "items": {"type": "string"} + }, + "acceptsInlineCatalogs": { + "type": "boolean", + "description": "A boolean indicating if the agent can accept an 'inlineCatalogs' array in the renderer's a2uiRendererCapabilities. If omitted, this defaults to false.", + "default": false + } + } + } + }, + "required": ["v1.0"] +} diff --git a/specification/v1_0/json/server_to_client.json b/specification/v1_0/json/agent_to_renderer.json similarity index 86% rename from specification/v1_0/json/server_to_client.json rename to specification/v1_0/json/agent_to_renderer.json index 7bf2217730..8f7dd0fe09 100644 --- a/specification/v1_0/json/server_to_client.json +++ b/specification/v1_0/json/agent_to_renderer.json @@ -1,8 +1,8 @@ { "$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.", + "$id": "https://a2ui.org/specification/v1_0/agent_to_renderer.json", + "title": "A2UI Agent-to-Renderer Message Schema", + "description": "Describes a JSON payload for an A2UI (Agent to Renderer) message, which is used to dynamically construct and update user interfaces.", "type": "object", "oneOf": [ {"$ref": "#/$defs/CreateSurfaceMessage"}, @@ -21,7 +21,7 @@ }, "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.", + "description": "Signals the renderer 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 renderer will expect 'updateComponents' and/or 'updateDataModel' messages for the same surfaceId that define the component tree.", "properties": { "surfaceId": { "type": "string", @@ -37,7 +37,7 @@ }, "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." + "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." }, "components": { "$ref": "#/$defs/ComponentsList" @@ -125,7 +125,7 @@ }, "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.", + "description": "Signals the renderer 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", @@ -141,7 +141,7 @@ }, "CallFunctionMessage": { "type": "object", - "description": "A function invoked from the server.", + "description": "A function invoked from the agent.", "properties": { "version": { "const": "v1.0" @@ -169,7 +169,7 @@ }, "ActionResponseMessage": { "type": "object", - "description": "A response to a client-initiated action.", + "description": "A response to a renderer-initiated action.", "properties": { "version": { "const": "v1.0" diff --git a/specification/v1_0/json/agent_to_renderer_list.json b/specification/v1_0/json/agent_to_renderer_list.json new file mode 100644 index 0000000000..7dc1b51cd9 --- /dev/null +++ b/specification/v1_0/json/agent_to_renderer_list.json @@ -0,0 +1,10 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://a2ui.org/specification/v1_0/json/agent_to_renderer_list.json", + "title": "A2UI Agent-to-Renderer Message List", + "description": "A list of A2UI Agent-to-Renderer messages.", + "type": "array", + "items": { + "$ref": "https://a2ui.org/specification/v1_0/agent_to_renderer.json" + } +} diff --git a/specification/v1_0/json/agent_to_renderer_list_wrapper.json b/specification/v1_0/json/agent_to_renderer_list_wrapper.json new file mode 100644 index 0000000000..8f0eaa3e5b --- /dev/null +++ b/specification/v1_0/json/agent_to_renderer_list_wrapper.json @@ -0,0 +1,14 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://a2ui.org/specification/v1_0/json/agent_to_renderer_list_wrapper.json", + "title": "A2UI Agent-to-Renderer Message List Wrapper", + "description": "An object wrapping a list of A2UI Agent-to-Renderer messages. Intended for protocols that require a top-level JSON object instead of a raw array.", + "type": "object", + "properties": { + "messages": { + "$ref": "agent_to_renderer_list.json" + } + }, + "additionalProperties": false, + "required": ["messages"] +} diff --git a/specification/v1_0/json/catalog_definition.json b/specification/v1_0/json/catalog_definition.json index 1746a755a2..965fc15931 100644 --- a/specification/v1_0/json/catalog_definition.json +++ b/specification/v1_0/json/catalog_definition.json @@ -124,8 +124,8 @@ }, "callableFrom": { "type": "string", - "enum": ["clientOnly", "remoteOnly", "clientOrRemote"], - "default": "clientOnly", + "enum": ["rendererOnly", "agentOnly", "rendererOrAgent"], + "default": "rendererOnly", "description": "Specifies where this function can be invoked from." } }, diff --git a/specification/v1_0/json/client_to_server_list.json b/specification/v1_0/json/client_to_server_list.json deleted file mode 100644 index 77db67159a..0000000000 --- a/specification/v1_0/json/client_to_server_list.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://a2ui.org/specification/v1_0/json/client_to_server_list.json", - "title": "A2UI Client-to-Server Message List", - "description": "A list of A2UI Client-to-Server messages.", - "type": "array", - "items": { - "$ref": "https://a2ui.org/specification/v1_0/client_to_server.json" - } -} diff --git a/specification/v1_0/json/client_to_server_list_wrapper.json b/specification/v1_0/json/client_to_server_list_wrapper.json deleted file mode 100644 index d70183fcdc..0000000000 --- a/specification/v1_0/json/client_to_server_list_wrapper.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://a2ui.org/specification/v1_0/json/client_to_server_list_wrapper.json", - "title": "A2UI Client-to-Server Message List Wrapper", - "description": "An object wrapping a list of A2UI Client-to-Server messages. Intended for protocols that require a top-level JSON object instead of a raw array.", - "type": "object", - "properties": { - "messages": { - "$ref": "client_to_server_list.json" - } - }, - "additionalProperties": false, - "required": ["messages"] -} diff --git a/specification/v1_0/json/common_types.json b/specification/v1_0/json/common_types.json index 980d8b1a13..549810ef2e 100644 --- a/specification/v1_0/json/common_types.json +++ b/specification/v1_0/json/common_types.json @@ -10,7 +10,7 @@ }, "CallId": { "type": "string", - "description": "The unique identifier for a server initiated function call." + "description": "The unique identifier for an agent-initiated function call." }, "AccessibilityAttributes": { "type": "object", @@ -182,7 +182,7 @@ }, "FunctionCall": { "type": "object", - "description": "Invokes a named function on the client.", + "description": "Invokes a named function on the renderer.", "properties": { "call": { "type": "string", @@ -226,7 +226,7 @@ "additionalProperties": false }, "Checkable": { - "description": "Properties for components that support client-side checks.", + "description": "Properties for components that support renderer-side checks.", "type": "object", "properties": { "checks": { @@ -239,19 +239,19 @@ } }, "Action": { - "description": "Defines an interaction handler that can either trigger a server-side event or execute a local client-side function.", + "description": "Defines an interaction handler that can either trigger an agent-side event or execute a local renderer-side function.", "oneOf": [ { "type": "object", - "description": "Triggers a server-side event.", + "description": "Triggers an agent-side event.", "properties": { "event": { "type": "object", - "description": "The event to dispatch to the server.", + "description": "The event to dispatch to the agent.", "properties": { "name": { "type": "string", - "description": "The name of the action to be dispatched to the server." + "description": "The name of the action to be dispatched to the agent." }, "context": { "type": "object", @@ -262,12 +262,12 @@ }, "wantResponse": { "type": "boolean", - "description": "If true, the client expects an actionResponse from the server.", + "description": "If true, the renderer expects an actionResponse from the agent.", "default": false }, "responsePath": { "type": "string", - "description": "Optional JSON Pointer path where the client should save the response value in its local data model." + "description": "Optional JSON Pointer path where the renderer should save the response value in its local data model." } }, "required": ["name"], @@ -279,7 +279,7 @@ }, { "type": "object", - "description": "Executes a local client-side function.", + "description": "Executes a local renderer-side function.", "properties": { "functionCall": { "$ref": "#/$defs/FunctionCall" diff --git a/specification/v1_0/json/client_capabilities.json b/specification/v1_0/json/renderer_capabilities.json similarity index 69% rename from specification/v1_0/json/client_capabilities.json rename to specification/v1_0/json/renderer_capabilities.json index 2cbb7e756c..08937a2630 100644 --- a/specification/v1_0/json/client_capabilities.json +++ b/specification/v1_0/json/renderer_capabilities.json @@ -1,8 +1,8 @@ { "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://a2ui.org/specification/v1_0/client_capabilities.json", - "title": "A2UI Client Capabilities Schema", - "description": "A schema for the a2uiClientCapabilities object, which is sent from the client to the server as part of the A2A metadata to describe the client's UI rendering capabilities.", + "$id": "https://a2ui.org/specification/v1_0/renderer_capabilities.json", + "title": "A2UI Renderer Capabilities Schema", + "description": "A schema for the a2uiRendererCapabilities object, which is sent from the renderer to the agent as part of the A2A metadata to describe the renderer's UI rendering capabilities.", "type": "object", "properties": { "v1.0": { @@ -11,7 +11,7 @@ "properties": { "supportedCatalogIds": { "type": "array", - "description": "An array of string identifiers for each of the component and function catalogs supported by the client.", + "description": "An array of string identifiers for each of the component and function catalogs supported by the renderer.", "items": {"type": "string"} }, "inlineCatalogs": { diff --git a/specification/v1_0/json/client_data_model.json b/specification/v1_0/json/renderer_data_model.json similarity index 62% rename from specification/v1_0/json/client_data_model.json rename to specification/v1_0/json/renderer_data_model.json index 724ce7c720..c0246b7190 100644 --- a/specification/v1_0/json/client_data_model.json +++ b/specification/v1_0/json/renderer_data_model.json @@ -1,8 +1,8 @@ { "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://a2ui.org/specification/v1_0/client_data_model.json", - "title": "A2UI Client Data Model Schema", - "description": "Schema for conveying the client data models for all active surfaces. This is used for bidirectional data synchronization between the client and the agent.", + "$id": "https://a2ui.org/specification/v1_0/renderer_data_model.json", + "title": "A2UI Renderer Data Model Schema", + "description": "Schema for conveying the renderer data models for all active surfaces. This is used for bidirectional data synchronization between the renderer and the agent.", "type": "object", "properties": { "version": { diff --git a/specification/v1_0/json/client_to_server.json b/specification/v1_0/json/renderer_to_agent.json similarity index 92% rename from specification/v1_0/json/client_to_server.json rename to specification/v1_0/json/renderer_to_agent.json index 1d03edfef1..8c121a3dfc 100644 --- a/specification/v1_0/json/client_to_server.json +++ b/specification/v1_0/json/renderer_to_agent.json @@ -1,8 +1,8 @@ { "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://a2ui.org/specification/v1_0/client_to_server.json", - "title": "A2UI (Agent to UI) Client-to-Server Event Schema", - "description": "Describes a JSON payload for a client-to-server event message.", + "$id": "https://a2ui.org/specification/v1_0/renderer_to_agent.json", + "title": "A2UI (Agent to UI) Renderer-to-Agent Event Schema", + "description": "Describes a JSON payload for a renderer-to-agent event message.", "type": "object", "minProperties": 2, "maxProperties": 2, @@ -38,7 +38,7 @@ }, "wantResponse": { "type": "boolean", - "description": "If true, the client expects an actionResponse from the server.", + "description": "If true, the renderer expects an actionResponse from the agent.", "default": false }, "actionId": { @@ -67,7 +67,7 @@ "unevaluatedProperties": false }, "error": { - "description": "Reports a client-side error.", + "description": "Reports a renderer-side error.", "oneOf": [ { "type": "object", diff --git a/specification/v1_0/json/renderer_to_agent_list.json b/specification/v1_0/json/renderer_to_agent_list.json new file mode 100644 index 0000000000..e6de077b17 --- /dev/null +++ b/specification/v1_0/json/renderer_to_agent_list.json @@ -0,0 +1,10 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://a2ui.org/specification/v1_0/json/renderer_to_agent_list.json", + "title": "A2UI Renderer-to-Agent Message List", + "description": "A list of A2UI Renderer-to-Agent messages.", + "type": "array", + "items": { + "$ref": "https://a2ui.org/specification/v1_0/renderer_to_agent.json" + } +} diff --git a/specification/v1_0/json/renderer_to_agent_list_wrapper.json b/specification/v1_0/json/renderer_to_agent_list_wrapper.json new file mode 100644 index 0000000000..d95a2e0341 --- /dev/null +++ b/specification/v1_0/json/renderer_to_agent_list_wrapper.json @@ -0,0 +1,14 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://a2ui.org/specification/v1_0/json/renderer_to_agent_list_wrapper.json", + "title": "A2UI Renderer-to-Agent Message List Wrapper", + "description": "An object wrapping a list of A2UI Renderer-to-Agent messages. Intended for protocols that require a top-level JSON object instead of a raw array.", + "type": "object", + "properties": { + "messages": { + "$ref": "renderer_to_agent_list.json" + } + }, + "additionalProperties": false, + "required": ["messages"] +} diff --git a/specification/v1_0/json/sample.json b/specification/v1_0/json/sample.json index 490f623191..ca54959a31 100644 --- a/specification/v1_0/json/sample.json +++ b/specification/v1_0/json/sample.json @@ -15,8 +15,8 @@ "description": "A short description of what the sample demonstrates." }, "messages": { - "$ref": "https://a2ui.org/specification/v1_0/json/server_to_client_list.json", - "description": "The ordered list of A2UI messages to be processed by the client." + "$ref": "https://a2ui.org/specification/v1_0/json/agent_to_renderer_list.json", + "description": "The ordered list of A2UI messages to be processed by the renderer." } } } diff --git a/specification/v1_0/json/server_capabilities.json b/specification/v1_0/json/server_capabilities.json deleted file mode 100644 index 15b101de1c..0000000000 --- a/specification/v1_0/json/server_capabilities.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://a2ui.org/specification/v1_0/server_capabilities.json", - "title": "A2UI Server Capabilities Schema", - "description": "A schema for the server capabilities object, which is used by an A2UI server (or Agent) to advertise its supported UI features to clients. This can be embedded in an Agent Card for A2A or used in other transport protocols like MCP.", - "type": "object", - "properties": { - "v1.0": { - "type": "object", - "description": "The server capabilities structure for version 1.0 of the A2UI protocol.", - "properties": { - "supportedCatalogIds": { - "type": "array", - "description": "An array of strings, where each string is an ID identifying a Catalog Definition Schema that the server can generate. This is not necessarily a resolvable URI.", - "items": {"type": "string"} - }, - "acceptsInlineCatalogs": { - "type": "boolean", - "description": "A boolean indicating if the server can accept an 'inlineCatalogs' array in the client's a2uiClientCapabilities. If omitted, this defaults to false.", - "default": false - } - } - } - }, - "required": ["v1.0"] -} diff --git a/specification/v1_0/json/server_to_client_list.json b/specification/v1_0/json/server_to_client_list.json deleted file mode 100644 index 1811d7ee02..0000000000 --- a/specification/v1_0/json/server_to_client_list.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://a2ui.org/specification/v1_0/json/server_to_client_list.json", - "title": "A2UI Server-to-Client Message List", - "description": "A list of A2UI Server-to-Client messages.", - "type": "array", - "items": { - "$ref": "https://a2ui.org/specification/v1_0/server_to_client.json" - } -} diff --git a/specification/v1_0/json/server_to_client_list_wrapper.json b/specification/v1_0/json/server_to_client_list_wrapper.json deleted file mode 100644 index 886e799618..0000000000 --- a/specification/v1_0/json/server_to_client_list_wrapper.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://a2ui.org/specification/v1_0/json/server_to_client_list_wrapper.json", - "title": "A2UI Server-to-Client Message List Wrapper", - "description": "An object wrapping a list of A2UI Server-to-Client messages. Intended for protocols that require a top-level JSON object instead of a raw array.", - "type": "object", - "properties": { - "messages": { - "$ref": "server_to_client_list.json" - } - }, - "additionalProperties": false, - "required": ["messages"] -} diff --git a/specification/v1_0/test/README.md b/specification/v1_0/test/README.md index 7f5a326088..c6fae80723 100644 --- a/specification/v1_0/test/README.md +++ b/specification/v1_0/test/README.md @@ -36,7 +36,7 @@ Create a new JSON file in `cases/` (e.g., `cases/my_feature.json`): ```json { - "schema": "server_to_client.json", + "schema": "agent_to_renderer.json", "tests": [ { "description": "Description of the test case", diff --git a/specification/v1_0/test/cases/button_checks.json b/specification/v1_0/test/cases/button_checks.json index 0e72f0aa94..43a4e20af3 100644 --- a/specification/v1_0/test/cases/button_checks.json +++ b/specification/v1_0/test/cases/button_checks.json @@ -1,5 +1,5 @@ { - "schema": "server_to_client.json", + "schema": "agent_to_renderer.json", "tests": [ { "description": "Button with nested valid checks", diff --git a/specification/v1_0/test/cases/call_function_message.json b/specification/v1_0/test/cases/call_function_message.json index da60939ad3..2196a95aef 100644 --- a/specification/v1_0/test/cases/call_function_message.json +++ b/specification/v1_0/test/cases/call_function_message.json @@ -1,5 +1,5 @@ { - "schema": "server_to_client.json", + "schema": "agent_to_renderer.json", "catalog": "testing_catalog.json", "tests": [ { diff --git a/specification/v1_0/test/cases/checkable_components.json b/specification/v1_0/test/cases/checkable_components.json index 61388af9d0..0180db86bf 100644 --- a/specification/v1_0/test/cases/checkable_components.json +++ b/specification/v1_0/test/cases/checkable_components.json @@ -1,5 +1,5 @@ { - "schema": "server_to_client.json", + "schema": "agent_to_renderer.json", "tests": [ { "description": "TextField with valid checks", diff --git a/specification/v1_0/test/cases/contact_form_example_test.json b/specification/v1_0/test/cases/contact_form_example_test.json index 80a6f3f7c9..d6598435ec 100644 --- a/specification/v1_0/test/cases/contact_form_example_test.json +++ b/specification/v1_0/test/cases/contact_form_example_test.json @@ -1,5 +1,5 @@ { - "schema": "server_to_client.json", + "schema": "agent_to_renderer.json", "tests": [ { "description": "Contact Form Example: Create Surface", diff --git a/specification/v1_0/test/cases/function_catalog_validation.json b/specification/v1_0/test/cases/function_catalog_validation.json index 5cda4fa2db..2bd6e2a13a 100644 --- a/specification/v1_0/test/cases/function_catalog_validation.json +++ b/specification/v1_0/test/cases/function_catalog_validation.json @@ -1,5 +1,5 @@ { - "schema": "server_to_client.json", + "schema": "agent_to_renderer.json", "tests": [ { "description": "required: Valid call", diff --git a/specification/v1_0/test/cases/function_response.json b/specification/v1_0/test/cases/function_response.json index 13df8f80be..d80da1a94c 100644 --- a/specification/v1_0/test/cases/function_response.json +++ b/specification/v1_0/test/cases/function_response.json @@ -1,5 +1,5 @@ { - "schema": "client_to_server.json", + "schema": "renderer_to_agent.json", "tests": [ { "description": "functionResponse: Valid message", diff --git a/specification/v1_0/test/cases/icon_checks.json b/specification/v1_0/test/cases/icon_checks.json index 28e608635a..200508ffab 100644 --- a/specification/v1_0/test/cases/icon_checks.json +++ b/specification/v1_0/test/cases/icon_checks.json @@ -1,5 +1,5 @@ { - "schema": "server_to_client.json", + "schema": "agent_to_renderer.json", "tests": [ { "description": "Icon: Valid standard icon string", diff --git a/specification/v1_0/test/cases/initial_state_validation.json b/specification/v1_0/test/cases/initial_state_validation.json index 1ef13c9db5..7ed2727854 100644 --- a/specification/v1_0/test/cases/initial_state_validation.json +++ b/specification/v1_0/test/cases/initial_state_validation.json @@ -1,5 +1,5 @@ { - "schema": "server_to_client.json", + "schema": "agent_to_renderer.json", "tests": [ { "description": "Valid createSurface with both components list and dataModel update", diff --git a/specification/v1_0/test/cases/client_messages.json b/specification/v1_0/test/cases/renderer_messages.json similarity index 98% rename from specification/v1_0/test/cases/client_messages.json rename to specification/v1_0/test/cases/renderer_messages.json index ef6204f8f8..b2bf497930 100644 --- a/specification/v1_0/test/cases/client_messages.json +++ b/specification/v1_0/test/cases/renderer_messages.json @@ -1,5 +1,5 @@ { - "schema": "client_to_server.json", + "schema": "renderer_to_agent.json", "tests": [ { "description": "Valid action message", diff --git a/specification/v1_0/test/cases/surface_properties_validation.json b/specification/v1_0/test/cases/surface_properties_validation.json index 6252289447..12f15acb58 100644 --- a/specification/v1_0/test/cases/surface_properties_validation.json +++ b/specification/v1_0/test/cases/surface_properties_validation.json @@ -1,5 +1,5 @@ { - "schema": "server_to_client.json", + "schema": "agent_to_renderer.json", "tests": [ { "description": "Valid surfaceProperties in createSurface", diff --git a/specification/v1_0/test/cases/tabs_checks.json b/specification/v1_0/test/cases/tabs_checks.json index 7ff4db7171..2363bc2a0b 100644 --- a/specification/v1_0/test/cases/tabs_checks.json +++ b/specification/v1_0/test/cases/tabs_checks.json @@ -1,5 +1,5 @@ { - "schema": "server_to_client.json", + "schema": "agent_to_renderer.json", "tests": [ { "description": "Tabs with empty tabs array (should fail)", diff --git a/specification/v1_0/test/cases/text_variants.json b/specification/v1_0/test/cases/text_variants.json index 96a65d60c8..0ffe3b21cc 100644 --- a/specification/v1_0/test/cases/text_variants.json +++ b/specification/v1_0/test/cases/text_variants.json @@ -1,5 +1,5 @@ { - "schema": "server_to_client.json", + "schema": "agent_to_renderer.json", "tests": [ { "description": "Text with valid variant 'caption'", diff --git a/specification/v1_0/test/run_tests.py b/specification/v1_0/test/run_tests.py index 8546bd93a2..0ca5155162 100755 --- a/specification/v1_0/test/run_tests.py +++ b/specification/v1_0/test/run_tests.py @@ -31,17 +31,17 @@ # Map of schema filenames to their full paths # Note: catalog.json is dynamically created from catalogs/basic/catalog.json SCHEMAS = { - "server_to_client.json": os.path.join(SCHEMA_DIR, "server_to_client.json"), + "agent_to_renderer.json": os.path.join(SCHEMA_DIR, "agent_to_renderer.json"), "common_types.json": os.path.join(SCHEMA_DIR, "common_types.json"), "catalog.json": TEMP_CATALOG_FILE, - "client_to_server.json": os.path.join(SCHEMA_DIR, "client_to_server.json"), + "renderer_to_agent.json": os.path.join(SCHEMA_DIR, "renderer_to_agent.json"), } def setup_catalog_alias(catalog_file="catalogs/basic/catalog.json"): """ Creates a temporary catalog.json from catalogs/basic/catalog.json (or the - specified file) with the $id modified to match what server_to_client.json + specified file) with the $id modified to match what agent_to_renderer.json expects. """ basic_catalog_path = os.path.join(SPEC_DIR, catalog_file) @@ -63,7 +63,7 @@ def setup_catalog_alias(catalog_file="catalogs/basic/catalog.json"): sys.exit(1) # Modify the $id to be the generic catalog reference - # This allows server_to_client.json to refer to "catalog.json" + # This allows agent_to_renderer.json to refer to "catalog.json" # and have it resolve to this schema content. if "$id" in catalog: import re @@ -128,7 +128,7 @@ def run_suite(suite_path): setup_catalog_alias(catalog_file) try: - schema_name = suite.get("schema", "server_to_client.json") + schema_name = suite.get("schema", "agent_to_renderer.json") if schema_name not in SCHEMAS: print(f"Error: Unknown schema '{schema_name}' referenced in {suite_path}") return 0, 0 @@ -174,11 +174,11 @@ def validate_jsonl_example(jsonl_path): return 0, 1 print(f"\nValidating JSONL example: {os.path.basename(jsonl_path)}") - print(f"Target Schema: server_to_client.json") + print(f"Target Schema: agent_to_renderer.json") passed = 0 failed = 0 - schema_path = SCHEMAS["server_to_client.json"] + schema_path = SCHEMAS["agent_to_renderer.json"] setup_catalog_alias() try: @@ -379,10 +379,10 @@ def validate_sample_schema(): json.dump(sample_data, f) ref_schemas = { - "server_to_client_list.json": os.path.join( - SCHEMA_DIR, "server_to_client_list.json" + "agent_to_renderer_list.json": os.path.join( + SCHEMA_DIR, "agent_to_renderer_list.json" ), - "server_to_client.json": os.path.join(SCHEMA_DIR, "server_to_client.json"), + "agent_to_renderer.json": os.path.join(SCHEMA_DIR, "agent_to_renderer.json"), "common_types.json": os.path.join(SCHEMA_DIR, "common_types.json"), "catalog.json": TEMP_CATALOG_FILE, } @@ -418,8 +418,8 @@ def validate_a2a_schemas(): # Define test payloads and their target schemas tests = [ { - "name": "client_capabilities.json", - "schema_path": os.path.join(SCHEMA_DIR, "client_capabilities.json"), + "name": "renderer_capabilities.json", + "schema_path": os.path.join(SCHEMA_DIR, "renderer_capabilities.json"), "data": { "v1.0": { "supportedCatalogIds": [ @@ -435,8 +435,8 @@ def validate_a2a_schemas(): }, }, { - "name": "server_capabilities.json", - "schema_path": os.path.join(SCHEMA_DIR, "server_capabilities.json"), + "name": "agent_capabilities.json", + "schema_path": os.path.join(SCHEMA_DIR, "agent_capabilities.json"), "data": { "v1.0": { "supportedCatalogIds": [ @@ -448,8 +448,8 @@ def validate_a2a_schemas(): "refs": {}, }, { - "name": "client_data_model.json", - "schema_path": os.path.join(SCHEMA_DIR, "client_data_model.json"), + "name": "renderer_data_model.json", + "schema_path": os.path.join(SCHEMA_DIR, "renderer_data_model.json"), "data": { "version": "v1.0", "surfaces": {"surface_123": {"user": {"name": "Alice"}}}, @@ -457,9 +457,9 @@ def validate_a2a_schemas(): "refs": {}, }, { - "name": "server_to_client_list_wrapper.json", + "name": "agent_to_renderer_list_wrapper.json", "schema_path": os.path.join( - SCHEMA_DIR, "server_to_client_list_wrapper.json" + SCHEMA_DIR, "agent_to_renderer_list_wrapper.json" ), "data": { "messages": [{ @@ -473,20 +473,20 @@ def validate_a2a_schemas(): }] }, "refs": { - "server_to_client_list.json": os.path.join( - SCHEMA_DIR, "server_to_client_list.json" + "agent_to_renderer_list.json": os.path.join( + SCHEMA_DIR, "agent_to_renderer_list.json" ), - "server_to_client.json": os.path.join( - SCHEMA_DIR, "server_to_client.json" + "agent_to_renderer.json": os.path.join( + SCHEMA_DIR, "agent_to_renderer.json" ), "common_types.json": os.path.join(SCHEMA_DIR, "common_types.json"), "catalog.json": TEMP_CATALOG_FILE, }, }, { - "name": "client_to_server_list_wrapper.json", + "name": "renderer_to_agent_list_wrapper.json", "schema_path": os.path.join( - SCHEMA_DIR, "client_to_server_list_wrapper.json" + SCHEMA_DIR, "renderer_to_agent_list_wrapper.json" ), "data": { "messages": [{ @@ -501,11 +501,11 @@ def validate_a2a_schemas(): }] }, "refs": { - "client_to_server_list.json": os.path.join( - SCHEMA_DIR, "client_to_server_list.json" + "renderer_to_agent_list.json": os.path.join( + SCHEMA_DIR, "renderer_to_agent_list.json" ), - "client_to_server.json": os.path.join( - SCHEMA_DIR, "client_to_server.json" + "renderer_to_agent.json": os.path.join( + SCHEMA_DIR, "renderer_to_agent.json" ), "common_types.json": os.path.join(SCHEMA_DIR, "common_types.json"), }, diff --git a/swift/core/Sources/A2UICore/Errors/ClientServerError.swift b/swift/core/Sources/A2UICore/Errors/RendererToAgentError.swift similarity index 92% rename from swift/core/Sources/A2UICore/Errors/ClientServerError.swift rename to swift/core/Sources/A2UICore/Errors/RendererToAgentError.swift index 7e846776dd..674ed0a590 100644 --- a/swift/core/Sources/A2UICore/Errors/ClientServerError.swift +++ b/swift/core/Sources/A2UICore/Errors/RendererToAgentError.swift @@ -12,8 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -/// Encapsulates all client-to-server error types. -public enum ClientServerError: Equatable, Codable, Sendable { +/// Encapsulates all renderer-to-agent error types. +public enum RendererToAgentError: Equatable, Codable, Sendable { case validationFailed(ValidationFailedError) case generic(GenericError) diff --git a/swift/core/Sources/A2UICore/Extensions/JSONValue+Path.swift b/swift/core/Sources/A2UICore/Extensions/JSONValue+Path.swift index 2cce0d4f04..3011df4fe7 100644 --- a/swift/core/Sources/A2UICore/Extensions/JSONValue+Path.swift +++ b/swift/core/Sources/A2UICore/Extensions/JSONValue+Path.swift @@ -12,8 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -import OrderedJSON import OrderedCollections +import OrderedJSON extension JSONValue { /// Returns the underlying string value if this is a `.string` case. @@ -77,7 +77,8 @@ extension JSONValue { /// if this is an `.object` case. public var dictionaryValue: [String: JSONValue]? { switch self { - case .object(let value): return Dictionary(uniqueKeysWithValues: value.map { ($0.key, $0.value) }) + case .object(let value): + return Dictionary(uniqueKeysWithValues: value.map { ($0.key, $0.value) }) default: return nil } } diff --git a/swift/core/Sources/A2UICore/Messages/ServerToClientMessage.swift b/swift/core/Sources/A2UICore/Messages/AgentToRendererMessage.swift similarity index 88% rename from swift/core/Sources/A2UICore/Messages/ServerToClientMessage.swift rename to swift/core/Sources/A2UICore/Messages/AgentToRendererMessage.swift index 01c8cb58d5..4170bf042b 100644 --- a/swift/core/Sources/A2UICore/Messages/ServerToClientMessage.swift +++ b/swift/core/Sources/A2UICore/Messages/AgentToRendererMessage.swift @@ -15,10 +15,11 @@ import Foundation /// A container message enclosing one of the supported incoming -/// server-to-client commands. +/// agent-to-renderer commands. /// -/// Matches `specification/v0_9_1/json/server_to_client.json`. -public enum ServerToClientMessage: Codable, Sendable, Equatable { +/// Matches `specification/v0_9_1/json/server_to_client.json` (for older versions) +/// and `specification/v1_0/json/agent_to_renderer.json`. +public enum AgentToRendererMessage: Codable, Sendable, Equatable { case createSurface(CreateSurfaceMessage) case updateComponents(UpdateComponentsMessage) case updateDataModel(UpdateDataModelMessage) @@ -35,7 +36,7 @@ public enum ServerToClientMessage: Codable, Sendable, Equatable { public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) let version = try container.decode(String.self, forKey: .version) - guard version == "v0.9" || version == "v0.9.1" else { + guard version == "v0.9" || version == "v0.9.1" || version == "v1.0" else { throw DecodingError.dataCorruptedError( forKey: .version, in: container, @@ -67,7 +68,7 @@ public enum ServerToClientMessage: Codable, Sendable, Equatable { let context = DecodingError.Context( codingPath: container.codingPath, debugDescription: """ - ServerToClientMessage must contain one of: 'createSurface', \ + AgentToRendererMessage must contain one of: 'createSurface', \ 'updateComponents', 'updateDataModel', or 'deleteSurface' """ ) @@ -90,4 +91,3 @@ public enum ServerToClientMessage: Codable, Sendable, Equatable { } } } - diff --git a/swift/core/Sources/A2UICore/Messages/ClientToServerMessage.swift b/swift/core/Sources/A2UICore/Messages/RendererToAgentMessage.swift similarity index 76% rename from swift/core/Sources/A2UICore/Messages/ClientToServerMessage.swift rename to swift/core/Sources/A2UICore/Messages/RendererToAgentMessage.swift index 04ac104ea2..4333058f82 100644 --- a/swift/core/Sources/A2UICore/Messages/ClientToServerMessage.swift +++ b/swift/core/Sources/A2UICore/Messages/RendererToAgentMessage.swift @@ -12,12 +12,13 @@ // See the License for the specific language governing permissions and // limitations under the License. -/// Top-level envelope for client-to-server messages (actions or errors). +/// Top-level envelope for renderer-to-agent messages (actions or errors). /// -/// Matches `specification/v0_9_1/json/client_to_server.json`. -public enum ClientToServerMessage: Equatable, Codable, Sendable { - case action(ClientAction) - case error(ClientServerError) +/// Matches `specification/v0_9_1/json/client_to_server.json` +/// and `specification/v1_0/json/renderer_to_agent.json`. +public enum RendererToAgentMessage: Equatable, Codable, Sendable { + case action(RendererAction) + case error(RendererToAgentError) private enum CodingKeys: String, CodingKey { case version @@ -28,7 +29,7 @@ public enum ClientToServerMessage: Equatable, Codable, Sendable { public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) let version = try container.decode(String.self, forKey: .version) - guard version == "v0.9" || version == "v0.9.1" else { + guard version == "v0.9" || version == "v0.9.1" || version == "v1.0" else { throw DecodingError.dataCorruptedError( forKey: .version, in: container, @@ -37,12 +38,12 @@ public enum ClientToServerMessage: Equatable, Codable, Sendable { } if let action = try container.decodeIfPresent( - ClientAction.self, + RendererAction.self, forKey: .action ) { self = .action(action) } else if let error = try container.decodeIfPresent( - ClientServerError.self, + RendererToAgentError.self, forKey: .error ) { self = .error(error) @@ -58,7 +59,7 @@ public enum ClientToServerMessage: Equatable, Codable, Sendable { public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) - try container.encode("v0.9.1", forKey: .version) + try container.encode("v0.9.1", forKey: .version) // TODO: support version 1.0 encoding if needed switch self { case .action(let action): @@ -68,4 +69,3 @@ public enum ClientToServerMessage: Equatable, Codable, Sendable { } } } - diff --git a/swift/core/Sources/A2UICore/Models/ClientAction.swift b/swift/core/Sources/A2UICore/Models/RendererAction.swift similarity index 89% rename from swift/core/Sources/A2UICore/Models/ClientAction.swift rename to swift/core/Sources/A2UICore/Models/RendererAction.swift index d18835e359..94a2a8d4cd 100644 --- a/swift/core/Sources/A2UICore/Models/ClientAction.swift +++ b/swift/core/Sources/A2UICore/Models/RendererAction.swift @@ -17,8 +17,9 @@ import OrderedJSON /// Reports a user-initiated action from a component. /// /// Matches the `action` property in -/// `specification/v0_9_1/json/client_to_server.json`. -public struct ClientAction: Equatable, Codable, Sendable { +/// `specification/v0_9_1/json/client_to_server.json` and +/// `specification/v1_0/json/renderer_to_agent.json`. +public struct RendererAction: Equatable, Codable, Sendable { /// The name of the action, taken from the component's /// `action.event.name` property. public let name: String @@ -44,7 +45,7 @@ public struct ClientAction: Equatable, Codable, Sendable { case context } - /// Creates a new client action. + /// Creates a new renderer action. public init( name: String, surfaceID: String, diff --git a/swift/core/Tests/A2UICoreTests/ServerToClientMessageTests.swift b/swift/core/Tests/A2UICoreTests/AgentToRendererMessageTests.swift similarity index 82% rename from swift/core/Tests/A2UICoreTests/ServerToClientMessageTests.swift rename to swift/core/Tests/A2UICoreTests/AgentToRendererMessageTests.swift index c8cc5abb54..11146cfbd6 100644 --- a/swift/core/Tests/A2UICoreTests/ServerToClientMessageTests.swift +++ b/swift/core/Tests/A2UICoreTests/AgentToRendererMessageTests.swift @@ -17,12 +17,13 @@ import Foundation import OrderedJSON import Testing -struct ServerToClientMessageTests { +struct AgentToRendererMessageTests { // MARK: - Decoding @Test func decodeCreateSurface() throws { - let json = try #require(""" + let json = try #require( + """ { "version": "v0.9.1", "createSurface": { @@ -32,7 +33,7 @@ struct ServerToClientMessageTests { } """.data(using: .utf8)) let msg = try JSONDecoder().decode( - ServerToClientMessage.self, from: json + AgentToRendererMessage.self, from: json ) if case .createSurface(let create) = msg { #expect(create.surfaceID == "s1") @@ -44,7 +45,8 @@ struct ServerToClientMessageTests { } @Test func decodeCreateSurfaceWithSendDataModel() throws { - let json = try #require(""" + let json = try #require( + """ { "version": "v0.9.1", "createSurface": { @@ -55,7 +57,7 @@ struct ServerToClientMessageTests { } """.data(using: .utf8)) let msg = try JSONDecoder().decode( - ServerToClientMessage.self, from: json + AgentToRendererMessage.self, from: json ) if case .createSurface(let create) = msg { #expect(create.shouldSendDataModel == true) @@ -63,7 +65,8 @@ struct ServerToClientMessageTests { } @Test func decodeUpdateComponents() throws { - let json = try #require(""" + let json = try #require( + """ { "version": "v0.9.1", "updateComponents": { @@ -75,7 +78,7 @@ struct ServerToClientMessageTests { } """.data(using: .utf8)) let msg = try JSONDecoder().decode( - ServerToClientMessage.self, from: json + AgentToRendererMessage.self, from: json ) if case .updateComponents(let update) = msg { #expect(update.surfaceID == "s1") @@ -87,7 +90,8 @@ struct ServerToClientMessageTests { } @Test func decodeUpdateDataModel() throws { - let json = try #require(""" + let json = try #require( + """ { "version": "v0.9.1", "updateDataModel": { @@ -98,7 +102,7 @@ struct ServerToClientMessageTests { } """.data(using: .utf8)) let msg = try JSONDecoder().decode( - ServerToClientMessage.self, from: json + AgentToRendererMessage.self, from: json ) if case .updateDataModel(let update) = msg { #expect(update.surfaceID == "s1") @@ -110,7 +114,8 @@ struct ServerToClientMessageTests { } @Test func decodeUpdateDataModelDefaultsToRootPath() throws { - let json = try #require(""" + let json = try #require( + """ { "version": "v0.9.1", "updateDataModel": { @@ -120,7 +125,7 @@ struct ServerToClientMessageTests { } """.data(using: .utf8)) let msg = try JSONDecoder().decode( - ServerToClientMessage.self, from: json + AgentToRendererMessage.self, from: json ) if case .updateDataModel(let update) = msg { #expect(update.path == "/") @@ -128,7 +133,8 @@ struct ServerToClientMessageTests { } @Test func decodeDeleteSurface() throws { - let json = try #require(""" + let json = try #require( + """ { "version": "v0.9.1", "deleteSurface": { @@ -137,7 +143,7 @@ struct ServerToClientMessageTests { } """.data(using: .utf8)) let msg = try JSONDecoder().decode( - ServerToClientMessage.self, from: json + AgentToRendererMessage.self, from: json ) if case .deleteSurface(let delete) = msg { #expect(delete.surfaceID == "s1") @@ -149,7 +155,7 @@ struct ServerToClientMessageTests { @Test func decodeRejectsEmptyMessage() throws { let json = try #require("{}".data(using: .utf8)) #expect(throws: DecodingError.self) { - try JSONDecoder().decode(ServerToClientMessage.self, from: json) + try JSONDecoder().decode(AgentToRendererMessage.self, from: json) } } @@ -160,31 +166,33 @@ struct ServerToClientMessageTests { """.data(using: .utf8) ) #expect(throws: DecodingError.self) { - try JSONDecoder().decode(ServerToClientMessage.self, from: json) + try JSONDecoder().decode(AgentToRendererMessage.self, from: json) } } @Test func decodeRejectsUnsupportedVersion() throws { - let json = try #require(""" + let json = try #require( + """ { "version": "v2.0", "createSurface": {"surfaceId": "s1", "catalogId": "default"} } """.data(using: .utf8)) #expect(throws: DecodingError.self) { - try JSONDecoder().decode(ServerToClientMessage.self, from: json) + try JSONDecoder().decode(AgentToRendererMessage.self, from: json) } } @Test func decodeAcceptsVersion09() throws { - let json = try #require(""" + let json = try #require( + """ { "version": "v0.9", "createSurface": {"surfaceId": "s1", "catalogId": "default"} } """.data(using: .utf8)) let msg = try JSONDecoder().decode( - ServerToClientMessage.self, from: json + AgentToRendererMessage.self, from: json ) if case .createSurface(let create) = msg { #expect(create.surfaceID == "s1") @@ -194,7 +202,7 @@ struct ServerToClientMessageTests { // MARK: - Encoding Round-Trip @Test func encodeDecodeRoundTripCreateSurface() throws { - let original = ServerToClientMessage.createSurface( + let original = AgentToRendererMessage.createSurface( CreateSurfaceMessage( surfaceID: "s1", catalogID: "default", @@ -204,13 +212,13 @@ struct ServerToClientMessageTests { ) let data = try JSONEncoder().encode(original) let decoded = try JSONDecoder().decode( - ServerToClientMessage.self, from: data + AgentToRendererMessage.self, from: data ) #expect(decoded == original) } @Test func encodeDecodeRoundTripUpdateComponents() throws { - let original = ServerToClientMessage.updateComponents( + let original = AgentToRendererMessage.updateComponents( UpdateComponentsMessage( surfaceID: "s1", components: [ @@ -221,24 +229,24 @@ struct ServerToClientMessageTests { ) let data = try JSONEncoder().encode(original) let decoded = try JSONDecoder().decode( - ServerToClientMessage.self, from: data + AgentToRendererMessage.self, from: data ) #expect(decoded == original) } @Test func encodeDecodeRoundTripDeleteSurface() throws { - let original = ServerToClientMessage.deleteSurface( + let original = AgentToRendererMessage.deleteSurface( DeleteSurfaceMessage(surfaceID: "s1") ) let data = try JSONEncoder().encode(original) let decoded = try JSONDecoder().decode( - ServerToClientMessage.self, from: data + AgentToRendererMessage.self, from: data ) #expect(decoded == original) } @Test func encodeAlwaysIncludesVersionV091() throws { - let original = ServerToClientMessage.deleteSurface( + let original = AgentToRendererMessage.deleteSurface( DeleteSurfaceMessage(surfaceID: "s1") ) let data = try JSONEncoder().encode(original) diff --git a/swift/core/Tests/A2UICoreTests/JSONValuePathTests.swift b/swift/core/Tests/A2UICoreTests/JSONValuePathTests.swift index 3c01d81d97..e5fd3f89d9 100644 --- a/swift/core/Tests/A2UICoreTests/JSONValuePathTests.swift +++ b/swift/core/Tests/A2UICoreTests/JSONValuePathTests.swift @@ -86,7 +86,7 @@ struct JSONValuePathTests { @Test func subscriptGetReturnsNestedValue() { let value: JSONValue = [ - "user": ["name": "Alice"], + "user": ["name": "Alice"] ] #expect(value["user/name"]?.stringValue == "Alice") } @@ -98,21 +98,21 @@ struct JSONValuePathTests { @Test func subscriptGetReturnsArrayElement() { let value: JSONValue = [ - "items": ["a", "b", "c"], + "items": ["a", "b", "c"] ] #expect(value["items/1"]?.stringValue == "b") } @Test func subscriptGetReturnsNilForInvalidArrayIndex() { let value: JSONValue = [ - "items": ["a", "b"], + "items": ["a", "b"] ] #expect(value["items/5"] == nil) } @Test func subscriptGetHandlesDeepNesting() { let value: JSONValue = [ - "a": ["b": ["c": ["d": "deep"]]], + "a": ["b": ["c": ["d": "deep"]]] ] #expect(value["a/b/c/d"]?.stringValue == "deep") } @@ -146,7 +146,7 @@ struct JSONValuePathTests { @Test func subscriptSetAppendsToArray() { var value: JSONValue = [ - "items": [1, 2, 3], + "items": [1, 2, 3] ] value["items/3"] = 4 #expect(value["items"]?.arrayValue?.count == 4) @@ -155,7 +155,7 @@ struct JSONValuePathTests { @Test func subscriptSetReplacesArrayElement() { var value: JSONValue = [ - "items": [1, 2, 3], + "items": [1, 2, 3] ] value["items/1"] = 99 #expect(value["items/1"]?.intValue == 99) @@ -170,7 +170,7 @@ struct JSONValuePathTests { @Test func subscriptSetDeletesByArrayIndex() { var value: JSONValue = [ - "items": [1, 2, 3], + "items": [1, 2, 3] ] value["items/1"] = nil // Setting an array index to nil preserves length (sparse array) @@ -182,7 +182,7 @@ struct JSONValuePathTests { @Test func subscriptSetAutoVivifiesObjectFromArray() { var value: JSONValue = [ - "items": [["name": "Alice"]], + "items": [["name": "Alice"]] ] value["items/0/age"] = 30 #expect(value["items/0/age"]?.intValue == 30) diff --git a/swift/core/Tests/A2UICoreTests/ClientToServerMessageTests.swift b/swift/core/Tests/A2UICoreTests/RendererToAgentMessageTests.swift similarity index 83% rename from swift/core/Tests/A2UICoreTests/ClientToServerMessageTests.swift rename to swift/core/Tests/A2UICoreTests/RendererToAgentMessageTests.swift index 6722d84a25..ebfbedf141 100644 --- a/swift/core/Tests/A2UICoreTests/ClientToServerMessageTests.swift +++ b/swift/core/Tests/A2UICoreTests/RendererToAgentMessageTests.swift @@ -17,12 +17,13 @@ import Foundation import OrderedJSON import Testing -struct ClientToServerMessageTests { +struct RendererToAgentMessageTests { // MARK: - Decoding @Test func decodeValidAction() throws { - let json = try #require(""" + let json = try #require( + """ { "version": "v0.9.1", "action": { @@ -35,7 +36,7 @@ struct ClientToServerMessageTests { } """.data(using: .utf8)) let message = try JSONDecoder().decode( - ClientToServerMessage.self, from: json + RendererToAgentMessage.self, from: json ) if case .action(let action) = message { #expect(action.name == "submit") @@ -49,7 +50,8 @@ struct ClientToServerMessageTests { } @Test func decodeValidActionWithEmptyContext() throws { - let json = try #require(""" + let json = try #require( + """ { "version": "v0.9.1", "action": { @@ -62,7 +64,7 @@ struct ClientToServerMessageTests { } """.data(using: .utf8)) let message = try JSONDecoder().decode( - ClientToServerMessage.self, from: json + RendererToAgentMessage.self, from: json ) if case .action(let action) = message { #expect(action.name == "click") @@ -73,7 +75,8 @@ struct ClientToServerMessageTests { } @Test func decodeValidError() throws { - let json = try #require(""" + let json = try #require( + """ { "version": "v0.9.1", "error": { @@ -85,7 +88,7 @@ struct ClientToServerMessageTests { } """.data(using: .utf8)) let message = try JSONDecoder().decode( - ClientToServerMessage.self, from: json + RendererToAgentMessage.self, from: json ) if case .error(let error) = message { if case .validationFailed(let validation) = error { @@ -108,7 +111,7 @@ struct ClientToServerMessageTests { """.data(using: .utf8) ) #expect(throws: DecodingError.self) { - try JSONDecoder().decode(ClientToServerMessage.self, from: json) + try JSONDecoder().decode(RendererToAgentMessage.self, from: json) } } @@ -117,12 +120,13 @@ struct ClientToServerMessageTests { "{\"version\": \"v0.9.1\"}".data(using: .utf8) ) #expect(throws: DecodingError.self) { - try JSONDecoder().decode(ClientToServerMessage.self, from: json) + try JSONDecoder().decode(RendererToAgentMessage.self, from: json) } } @Test func decodeRejectsActionMissingRequiredField() throws { - let json = try #require(""" + let json = try #require( + """ { "version": "v0.9.1", "action": { @@ -132,7 +136,7 @@ struct ClientToServerMessageTests { } """.data(using: .utf8)) #expect(throws: DecodingError.self) { - try JSONDecoder().decode(ClientToServerMessage.self, from: json) + try JSONDecoder().decode(RendererToAgentMessage.self, from: json) } } @@ -144,7 +148,7 @@ struct ClientToServerMessageTests { """.data(using: .utf8) ) let message = try JSONDecoder().decode( - ClientToServerMessage.self, from: json + RendererToAgentMessage.self, from: json ) if case .action(let action) = message { #expect(action.name == "click") @@ -154,60 +158,60 @@ struct ClientToServerMessageTests { // MARK: - Encoding @Test func encodeActionRoundTrip() throws { - let action = ClientAction( + let action = RendererAction( name: "submit", surfaceID: "main", sourceComponentID: "btn_submit", timestamp: "2023-10-27T10:00:00Z", context: ["foo": .string("bar")] ) - let message = ClientToServerMessage.action(action) + let message = RendererToAgentMessage.action(action) let data = try JSONEncoder().encode(message) let decoded = try JSONDecoder().decode( - ClientToServerMessage.self, from: data + RendererToAgentMessage.self, from: data ) #expect(decoded == message) } @Test func encodeValidationError() throws { - let error = ClientServerError.validationFailed( + let error = RendererToAgentError.validationFailed( ValidationFailedError( surfaceID: "surface-1", path: "/components/0", message: "Missing required property" ) ) - let message = ClientToServerMessage.error(error) + let message = RendererToAgentMessage.error(error) let data = try JSONEncoder().encode(message) let decoded = try JSONDecoder().decode( - ClientToServerMessage.self, from: data + RendererToAgentMessage.self, from: data ) #expect(decoded == message) } @Test func encodeAlwaysUsesV091Version() throws { - let action = ClientAction( + let action = RendererAction( name: "click", surfaceID: "main", sourceComponentID: "btn", timestamp: "2024-01-01T00:00:00Z", context: [:] ) - let message = ClientToServerMessage.action(action) + let message = RendererToAgentMessage.action(action) let data = try JSONEncoder().encode(message) let json = try #require(String(data: data, encoding: .utf8)) #expect(json.contains("\"version\":\"v0.9.1\"")) } @Test func encodeProducesFlatActionPayload() throws { - let action = ClientAction( + let action = RendererAction( name: "submit", surfaceID: "main", sourceComponentID: "btn_submit", timestamp: "2023-10-27T10:00:00Z", context: ["foo": .string("bar")] ) - let message = ClientToServerMessage.action(action) + let message = RendererToAgentMessage.action(action) let data = try JSONEncoder().encode(message) let json = try #require(String(data: data, encoding: .utf8)) // Verify flat keys are present @@ -222,17 +226,17 @@ struct ClientToServerMessageTests { #expect(!json.contains("\"args\"")) } - // MARK: - ClientAction Equality + // MARK: - RendererAction Equality - @Test func clientActionsEqualByAllFields() { - let a = ClientAction( + @Test func rendererActionsEqualByAllFields() { + let a = RendererAction( name: "click", surfaceID: "main", sourceComponentID: "btn", timestamp: "2024-01-01T00:00:00Z", context: ["key": .string("val")] ) - let b = ClientAction( + let b = RendererAction( name: "click", surfaceID: "main", sourceComponentID: "btn", @@ -242,15 +246,15 @@ struct ClientToServerMessageTests { #expect(a == b) } - @Test func clientActionsNotEqualByDifferentName() { - let a = ClientAction( + @Test func rendererActionsNotEqualByDifferentName() { + let a = RendererAction( name: "click", surfaceID: "main", sourceComponentID: "btn", timestamp: "2024-01-01T00:00:00Z", context: [:] ) - let b = ClientAction( + let b = RendererAction( name: "submit", surfaceID: "main", sourceComponentID: "btn", diff --git a/swift/sample/Sources/A2UISampleClient/A2UISampleApp.swift b/swift/sample/Sources/A2UISampleRenderer/A2UISampleApp.swift similarity index 90% rename from swift/sample/Sources/A2UISampleClient/A2UISampleApp.swift rename to swift/sample/Sources/A2UISampleRenderer/A2UISampleApp.swift index 8f6859015f..447eb72ba8 100644 --- a/swift/sample/Sources/A2UISampleClient/A2UISampleApp.swift +++ b/swift/sample/Sources/A2UISampleRenderer/A2UISampleApp.swift @@ -16,7 +16,7 @@ import A2UICore import A2UISwiftUI import SwiftUI -// Minimal @main entry point for the A2UI sample iOS client app. +// Minimal @main entry point for the A2UI sample iOS renderer app. // Will be expanded in a future PR with full demo scenario. @main @@ -31,7 +31,7 @@ struct A2UISampleApp: App { struct ContentView: View { var body: some View { VStack { - Text("A2UI Sample Client") + Text("A2UI Sample Renderer") .font(.headline) Text("Full demo coming soon") .font(.subheadline) diff --git a/yarn.lock b/yarn.lock index 9166f9626d..366d64250a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -65,9 +65,9 @@ __metadata: languageName: unknown linkType: soft -"@a2ui/angular-sample-lib@workspace:samples/client/angular/projects/lib": +"@a2ui/angular-sample-lib@workspace:samples/renderer/angular/projects/lib": version: 0.0.0-use.local - resolution: "@a2ui/angular-sample-lib@workspace:samples/client/angular/projects/lib" + resolution: "@a2ui/angular-sample-lib@workspace:samples/renderer/angular/projects/lib" dependencies: "@a2ui/web_core": "workspace:*" markdown-it: "npm:^14.2.0" @@ -193,9 +193,9 @@ __metadata: languageName: unknown linkType: soft -"@a2ui/lit-samples@workspace:samples/client/lit": +"@a2ui/lit-samples@workspace:samples/renderer/lit": version: 0.0.0-use.local - resolution: "@a2ui/lit-samples@workspace:samples/client/lit" + resolution: "@a2ui/lit-samples@workspace:samples/renderer/lit" dependencies: "@a2a-js/sdk": "npm:^0.3.13" "@a2ui/lit": "workspace:*" @@ -284,9 +284,9 @@ __metadata: languageName: unknown linkType: soft -"@a2ui/react-shell@workspace:samples/client/react/shell": +"@a2ui/react-shell@workspace:samples/renderer/react/shell": version: 0.0.0-use.local - resolution: "@a2ui/react-shell@workspace:samples/client/react/shell" + resolution: "@a2ui/react-shell@workspace:samples/renderer/react/shell" dependencies: "@a2a-js/sdk": "npm:^0.3.13" "@a2ui/markdown-it": "npm:*" @@ -363,9 +363,9 @@ __metadata: languageName: unknown linkType: soft -"@a2ui/restaurant@workspace:samples/client/angular/projects/restaurant": +"@a2ui/restaurant@workspace:samples/renderer/angular/projects/restaurant": version: 0.0.0-use.local - resolution: "@a2ui/restaurant@workspace:samples/client/angular/projects/restaurant" + resolution: "@a2ui/restaurant@workspace:samples/renderer/angular/projects/restaurant" dependencies: "@a2ui/angular": "workspace:*" "@a2ui/markdown-it": "npm:*" @@ -374,9 +374,9 @@ __metadata: languageName: unknown linkType: soft -"@a2ui/shell@workspace:samples/client/lit/shell": +"@a2ui/shell@workspace:samples/renderer/lit/shell": version: 0.0.0-use.local - resolution: "@a2ui/shell@workspace:samples/client/lit/shell" + resolution: "@a2ui/shell@workspace:samples/renderer/lit/shell" dependencies: "@a2a-js/sdk": "npm:^0.3.13" "@a2ui/lit": "workspace:*" @@ -12172,9 +12172,9 @@ __metadata: languageName: node linkType: hard -"angular-a2ui@workspace:samples/client/angular": +"angular-a2ui@workspace:samples/renderer/angular": version: 0.0.0-use.local - resolution: "angular-a2ui@workspace:samples/client/angular" + resolution: "angular-a2ui@workspace:samples/renderer/angular" dependencies: "@a2a-js/sdk": "npm:^0.3.13" "@a2ui/markdown-it": "npm:*"