refactor(protocol): rename client/server to renderer/agent consistently - #2075
refactor(protocol): rename client/server to renderer/agent consistently#2075gspencergoog wants to merge 2 commits into
Conversation
Consistently adopt "renderer" (for client) and "agent" (for server) terms across the v1.0 protocol specification, SDKs (Swift, Kotlin, Python), renderers (Web Core, Lit, React, Angular workspaces), samples, and documentation. Implement fallback handling for legacy tool names (`send_a2ui_json_to_client`) and version-aware prompts/schemas to preserve backwards compatibility for frozen specifications (v0.8, v0.9). Verify that all unit, integration, and conformance tests compile and pass successfully across all platforms.
There was a problem hiding this comment.
Code Review
This pull request migrates the A2UI protocol from version 0.9 to 1.0, involving extensive renaming of components and schemas from 'client' to 'renderer' and 'server-to-client' to 'agent-to-renderer'. Key changes include updates to the Python SDK's validation logic, schema generation scripts, and component definitions. The review feedback identifies several critical issues: a missing import for analyze_topology in the validator, a likely incorrect change in return types for formatting APIs from 'string' to 'boolean', missing backwards compatibility for legacy tool names in the Kotlin SDK, and dead code in the Python validator.
| from a2ui.core.validating.integrity_checker import ( | ||
| validate_component_integrity, | ||
| validate_recursion_and_paths, |
There was a problem hiding this comment.
The function analyze_topology is called at line 362 but is not imported anywhere in this file. This will raise a NameError at runtime when validation is executed. Please add analyze_topology to the local import statement from a2ui.core.validating.integrity_checker.
| from a2ui.core.validating.integrity_checker import ( | |
| validate_component_integrity, | |
| validate_recursion_and_paths, | |
| from a2ui.core.validating.integrity_checker import ( | |
| validate_component_integrity, | |
| validate_recursion_and_paths, | |
| analyze_topology, | |
| ) |
| name = "formatString" | ||
| schema = FormatStringArgs | ||
| return_type = "string" | ||
| return_type = "boolean" |
There was a problem hiding this comment.
The return type of FormatStringApi (and other formatting APIs like FormatNumberApi, FormatCurrencyApi, FormatDateApi, and PluralizeApi) has been changed from "string" to "boolean". Since these functions are designed to format values into strings for display, they should return "string". Returning "boolean" is likely a copy-paste error and will cause validation or runtime type mismatches.
| return_type = "boolean" | |
| return_type = "string" |
| 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 |
There was a problem hiding this comment.
The legacy tool name "send_a2ui_json_to_client" is not handled as a fallback in Converters.kt, unlike in A2aHandler.kt. If an older client/renderer sends a response using the legacy tool name, isSendA2uiJsonToRendererResponse will evaluate to false and the response will be ignored. Please add fallback handling for "send_a2ui_json_to_client" to preserve backwards compatibility as intended.
| 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 | |
| val functionResponse = part.functionResponse().orElse(null) | |
| val fnName = functionResponse?.name()?.orElse(null) | |
| val isSendA2uiJsonToRendererResponse = | |
| functionResponse != null && | |
| (fnName == SendA2uiToRendererToolset.TOOL_NAME || fnName == "send_a2ui_json_to_client") |
| 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() | ||
| } |
There was a problem hiding this comment.
Similarly, the functionCall check should also handle the legacy tool name "send_a2ui_json_to_client" as a fallback to prevent processing it incorrectly.
| 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() | |
| } | |
| val functionCall = part.functionCall().orElse(null) | |
| val callFnName = functionCall?.name()?.orElse(null) | |
| if ( | |
| functionCall != null && | |
| (callFnName == SendA2uiToRendererToolset.TOOL_NAME || callFnName == "send_a2ui_json_to_client") | |
| ) { | |
| return emptyList() | |
| } |
| 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 |
There was a problem hiding this comment.
The helper function collect_messages is defined inside the validate method but is never used anywhere in the function. It should be removed to clean up dead code and avoid redundantly recreating it on every invocation of validate.
References
- Avoid defining helper functions inside loops or nested functions where they are redundantly recreated on every iteration. Define them at the module level to improve performance and maintainability.
- When refactoring or fixing issues in code, prefer completely removing dead code or redundant checks rather than modifying them with more complex conditional logic.
Consistently adopt "renderer" (for client) and "agent" (for server) terms across the v1.0 protocol specification, SDKs (Swift, Kotlin, Python), renderers (Web Core, Lit, React, Angular workspaces), samples, and documentation.
Implement fallback handling for legacy tool names (
send_a2ui_json_to_client) and version-aware prompts/schemas to preserve backwards compatibility for frozen specifications (v0.8, v0.9).Verify that all unit, integration, and conformance tests compile and pass successfully across all platforms.