feat(web-core): implement client capabilities API in MessageProcessor#826
feat(web-core): implement client capabilities API in MessageProcessor#826jacobsimionato wants to merge 18 commits intogoogle:mainfrom
Conversation
- Enhanced the Standard Observer Pattern details with clear Unsubscribe Pattern notes and Payload Support specifics. - Added clarification that the instantiating system is responsible for extracting functions from the Catalog. - Replaced the brief overview with a highly detailed section on 'Generating Client Capabilities and Schema Types'. - Inserted a new rationale detailing observability consistency and function categorizations. - Replaced the brief 'Demo Application' outline with the full, detailed 'The Gallery App' documentation.
…ers, Typed Catalogs, and Custom Catalogs
* Moves zod-to-json-schema to dependencies for runtime schema generation. * Adds getClientCapabilities to MessageProcessor to report supported catalogs. * Implements generateInlineCatalog to dynamically export component schemas. * Implements processRefs to transform REF: tags into standard JSON Schema pointers. * Adds comprehensive test suite for capability generation and schema transformation.
There was a problem hiding this comment.
Code Review
This pull request introduces a getClientCapabilities API to the MessageProcessor, enabling the client to advertise its rendering capabilities to the server. The implementation includes generating JSON schemas from Zod definitions and handling custom $ref transformations. The changes are well-tested and include significant updates to the renderer guide documentation. My feedback focuses on improving type safety by replacing any types with specific interfaces and suggesting a refactor for clarity in the recursive schema processing logic. I've also noted an opportunity to enhance the updated documentation by restoring some explanatory comments.
# Conflicts: # specification/v0_9/docs/renderer_guide.md
| * Options for generating client capabilities. | ||
| */ | ||
| export interface CapabilitiesOptions { | ||
| /** If true, the full definition of all catalogs will be included. */ |
There was a problem hiding this comment.
I thought the idea for this option was to allow inline catalogs, not to include the full definition of all of them.
There was a problem hiding this comment.
Well, for now this API just turns on sending the full capabilities for every catalog. In the future, we might want some more fine-grained API to say "just send full inline catalogs for these three schemas", but I figure this is a simple starting point? WDYT?
There was a problem hiding this comment.
Yeah, I guess start here and we can get more complicated/refined as time goes on. I was just thinking about how it is including these with every message and thinking it was a lot.
| return; | ||
| } | ||
|
|
||
| // If not a REF target, recurse into its children. |
There was a problem hiding this comment.
What if an expanded $ref has a REF: in it? Or is that not possible? Or is this just an incorrect comment?
There was a problem hiding this comment.
What this is doing is kind of the inverse of refs actually. It's taking fully expanded Zod schemas and then refactoring them to include references to common_types when they are detected. If this happens, e.g. it sees a DynamicString and replaces it with a reference, there is no more work to do. If not, then it needs to keep exploring, looking for internal refs further into the tree of properties.
| "@preact/signals-core": "^1.13.0", | ||
| "zod": "^3.25.76" | ||
| "zod": "^3.25.76", | ||
| "zod-to-json-schema": "^3.25.1" |
There was a problem hiding this comment.
This might be bloating the front end, though. I was tempted to add this in the past too, but decided against it in order to keep the front end lean. If you think it's worth it, we should quantify the size hit.
There was a problem hiding this comment.
Well, we have decided to use Zod to represent schemas, and the A2UI specification supports inline catalogs, requiring those Zod schemas to be converted to JSON. So I think our choices are:
A. Add the dep
B. Write our own more lightweight version of the same conversion
C. Not support inlineCatalogs at all
D. Support inlineCatalogs through an additional package we provide.
I vote we do A for now, then switch to D if people complain. WDYT?
There was a problem hiding this comment.
Yeah, let's add the dep for now. If it's too bloated, we can evalutate B.
- Resolved conflicts in renderers/web_core/package.json and package-lock.json. - Aligned common-types.ts with specification/v0_9/json/common_types.json. - Renamed LogicExpressionSchema to DynamicBooleanSchema to match spec. - Updated CheckRuleSchema to use 'condition' and 'message' per spec. - Updated GenericBinder tests to use correct CheckRule format. - Removed obsolete LogicExpression tests from verify-schema.test.ts. - Verified all 232 web_core tests pass.
Description
Updates the
getClientCapabilitiesimplementation in the web core renderer to fully support functions and theme schemas, aligning with the A2UI specification. Restructures the TypeScript definitions for the capabilities payload to live natively within theschemalayer, and adds comprehensive guidelines for managing protocol serialization boundaries across all renderers.Changes
InlineCatalog,FunctionDefinition,JsonSchema,A2uiClientCapabilities) out ofmessage-processor.tsand into a dedicatedschema/client-capabilities.tsfile, establishing strong deep typings corresponding to theclient_capabilities.jsonschema.themeSchemaproperty to theCatalogclass and updated its constructor.MessageProcessor.generateInlineCatalogto successfully serializefunctionsandthemeSchemainto the client capabilities object. AppliedprocessRefsto these schemas to ensure correct JSON Schema references.REF:tags to shared schemas incommon-types.ts(e.g.,DataBinding,FunctionCall,DynamicValue,ChildList,Action,Checkable) to enable automatic$refnode generation during capability exchange.message-processor.test.tscovering edge cases forREF:tags, multiple catalogs, nested references, and empty schema states.renderer_guide.md):A2uiMessageorA2uiClientCapabilities) that handle serialization/validation before passing objects into theMessageProcessor.