Skip to content

refactor: Refactor FunctionCall wire schema and align protocol specification#1518

Open
gspencergoog wants to merge 18 commits into
a2ui-project:mainfrom
gspencergoog:refactor-function-call
Open

refactor: Refactor FunctionCall wire schema and align protocol specification#1518
gspencergoog wants to merge 18 commits into
a2ui-project:mainfrom
gspencergoog:refactor-function-call

Conversation

@gspencergoog
Copy link
Copy Markdown
Collaborator

@gspencergoog gspencergoog commented Jun 2, 2026

Description

This pull request refactors the FunctionCall schema definition in the A2UI v0.10 specification to completely remove the redundant callableFrom and returnType properties from the wire-level payload. Enforcements and validations (such as execution boundaries and return type correctness) are moved entirely to client-side runtime verification against catalog registries rather than being validated on the wire.

Additionally, this pull request adds support for static callableFrom and returnType metadata inside the client capabilities catalog definition schema, aligns the official protocol documentation (a2ui_protocol.md) with all updated schemas, and comprehensively updates all test cases, JSONL streams, and basic catalog examples to remove these obsolete wire-level fields.

Detailed changes

Schemas

  • common_types.json:
    • Removed the callableFrom and returnType properties from the core FunctionCall schema definition.
    • Removed static returnType constraints from DynamicString, DynamicNumber, DynamicBoolean, and DynamicStringList schema unions so they accept any FunctionCall on the wire and rely on client-side runtime type checking.
  • server_to_client.json: Simplified the CallFunctionMessage payload's callFunction property, removing both callableFrom and returnType overrides and required constraints.
  • testing_catalog.json & catalogs/minimal/catalog.json & catalogs/basic/catalog.json: Removed the callableFrom and returnType property definitions from catalog function schemas, keeping them strictly as validators for wire payloads.
  • client_capabilities.json: Declared static callableFrom and returnType properties inside the $defs/FunctionDefinition catalog schema. This allows clients to statically advertise their custom functions' boundaries and return types to the server as metadata, separate from the wire payload.

Test cases and Examples

  • Test Suites (cases/*.json, cases/*.jsonl): Performed an automated smart cleanup of positive and unrelated test payloads across all test cases (e.g., checkable_components.json, button_checks.json, call_function_message.json, function_catalog_validation.json) to strip returnType and callableFrom fields, while preserving their values in dedicated negative tests checking for schema rejection of unknown properties.
  • Catalog Examples (catalogs/basic/examples/*.json): Cleaned up all 36 basic catalog examples to strip the obsolete wire-level returnType field from their function call declarations.

Documentation (a2ui_protocol.md)

  • callFunction specifications: Aligned the callFunction property documentation and examples to remove wire-level returnType properties and updated the JSONL stream example.
  • Server-to-client envelopes: Aligned the introductory list under ## Envelope message structure to include the callFunction key. Added a new section detailing the callFunction message, its properties, and payload examples. Clarified how the client runtime extracts the callableFrom configuration from catalog definitions/annotations (defaulting to "clientOnly").
  • Client-to-server event messages: Restructured and expanded the documentation for client events. Fully detailed the property lists, mutual exclusion rules, and JSON examples for action events (including wantResponse and actionId), functionResponse execution results, and client error messages.
  • Capabilities and metadata: Promoted transport-level capability and data model exchanges to a dedicated section. Aligned the documented properties of server_capabilities.json, client_capabilities.json, and client_data_model.json to correctly describe version-wrapped objects ("v0.10") and the required "version" property. Documented that custom inline catalog function definitions support static callableFrom and returnType metadata to advertise function execution details.

Verification results

All 107 test cases in the A2UI v0.10 schema validation suite pass successfully. The automated tests validated the modified JSON schemas against the updated test files under /specification/v0_10/test/cases/.

Fixes #718

gemini-code-assist[bot]

This comment was marked as resolved.

@gspencergoog gspencergoog force-pushed the refactor-function-call branch 3 times, most recently from b9c150b to 1e47d05 Compare June 2, 2026 22:47
@gspencergoog gspencergoog enabled auto-merge (squash) June 2, 2026 23:36
The formatting script now uses Flutter, so the workflow requires the Flutter SDK instead of just the Dart SDK. Also updated formatting in infra_test.dart to keep it consistent.
…re schema

- Removes the wire-level `callableFrom` property from the `FunctionCall` definition in `common_types.json`.
- Simplifies the `CallFunctionMessage` payload in `server_to_client.json` to directly reference `FunctionCall` without `callableFrom` overrides or requirements.
- Removes the property from `testing_catalog.json` and all validation cases in `call_function_message.json`.
- Enforces boundary validation strictly as a client-side runtime check against local catalog registry definitions.
- Formally documents the `CallFunctionMessage` payload structure and its properties in `a2ui_protocol.md`.
- Outlines execution boundary check rules and security constraints for client-side runtime verification.
- Provides concrete JSON communication examples for server-initiated execution, client responses, and error handling.
…col spec

- Aligns `server_to_client` envelope list intro with the schema by including the new `callFunction` message type.
- Restructures and fully documents the `client_to_server` event envelope messages (`action` updates, `functionResponse`, and `error`).
- Provides detailed property descriptions, JSON examples, and layout rules for client events, execution responses, and mutual exclusions.
- Promotes `Capabilities and metadata` to its own top-level section to distinguish transport metadata from first-class A2UI envelope streams.
…emas

- Aligns the properties of `server_capabilities` and `client_capabilities` by properly nesting them under their required `"v0.10"` version wrapper objects in the protocol documentation.
- Adds the required top-level `"version"` property to the documented properties of the `a2uiClientDataModel` metadata object.
- Resolves the remaining discrepancies between the A2UI JSON schemas and `a2ui_protocol.md`.
…itions

- Adds `callableFrom` as an optional property inside the static `FunctionDefinition` schema within `client_capabilities.json`.
- Defaults the execution boundary configuration for registered catalog functions to `"clientOnly"`.
- Updates the client capability documentation in `a2ui_protocol.md` to specify how inline catalogs can statically declare execution boundaries.
- Adds a parenthetical note to the `callFunction` lookup rules in `a2ui_protocol.md`.
- Clarifies that the client runtime inspects `callableFrom` metadata or schema annotations from the catalog to determine execution boundaries, defaulting to `"clientOnly"`.
- Updates the ReturnType description under `callFunction` to use precise and standard terminology ("Must be one of" instead of "Snaps to one of").
The formatting script now uses Flutter, so the workflow requires the Flutter SDK instead of just the Dart SDK. Also updated formatting in infra_test.dart to keep it consistent.
@gspencergoog gspencergoog force-pushed the refactor-function-call branch from 279a614 to c069127 Compare June 3, 2026 00:44
},
"callableFrom": {
"type": "string",
"enum": ["clientOnly", "remoteOnly", "clientOrRemote"],
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't this also be called from either server or client? Add clientOrRemote?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't this also be called from either server or client? Add clientOrRemote?

"clientOnly" means it can only be called on the client. "remoteOnly" means it can only be called on the server, and "clientOrRemote" means it is available on both.

I'm not sure I understand your comment, though. clientOrRemote is already available.

Comment thread specification/v0_10/catalogs/basic/catalog.json
@@ -46,6 +46,12 @@
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This declares a function definition, but looking closer, it seems like this schema is actually not validated anywhere.

The basic catalog is supposed to conform to the Catalog schema below which includes this, but it seems like we don't actually validate that anywhere, because I see returnType is required here, yet it's not declared in the basic catalog JSON document.

I think probably what we really need is for each FunctionDefinition object to include a FunctionCall schema (referenced from common_types) inside which contains the name and args, and also extra metadata like ReturnType and CallableFrom that is used by the client for validation and the LLM to understand the call signature. Then, anyFunction etc in basic_catalog needs to combine together the inner FunctionCall schemas, rather than the outer FunctionDefinitions.

Hmmm maybe we're hitting the edge of what JSON schema validation can get us...

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, good point. Okay, I've modified the schema so it is suitable to use for validation and added validation tests for the basic and minimal catalogs to make sure that they pass validation against Catalog.

When we implement this for the core libraries, do you think we should add automatic validation for advertised catalogs?

I think JSON validation still good enough, or at least a part of a functional solution, but you're right, we're getting close to needing more.

Comment thread tmp/evaluation_v0_10_features.md Outdated
…ype metadata

- Changed functions from an array of definitions to an object (map) of schemas inside client_capabilities.json.
- Redefined FunctionDefinition to inherit from Draft 2020-12 schema, housing metadata like returnType and callableFrom at the root level of the schema.
- Added returnType metadata directly to basic catalog, minimal catalog, and testing catalog function definitions.
- Aligned custom functions documentation with the new structure.
- Removed obsolete tmp/evaluation_v0_10_features.md file.
…tion

Define a separate $defs/FunctionCallValidationSchema to explicitly validate client/server function calls on the wire, and compose it in $defs/FunctionDefinition alongside returnType/callableFrom metadata using allOf. This allows reusing validation constraints without leaking metadata parameters onto the wire protocol.
Update the Catalog definition schema in client_capabilities.json to allow standard JSON schema properties ($schema, $id, title, description, $defs). Add a new test step to run_tests.py that automatically validates the basic, minimal, and testing catalogs against this Catalog schema definition.
@gspencergoog gspencergoog force-pushed the refactor-function-call branch from 03de8a6 to 14e6d60 Compare June 3, 2026 17:46
gspencergoog and others added 2 commits June 3, 2026 13:06
…ect#1464)

* docs: Replace agent-and-renderer.png by a Mermaid diagram.
* docs: Add Glossary menu entry under Concepts
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Consider simplifying function "call sites" at the transport level or in inference formats

3 participants