Skip to content

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

Merged
gspencergoog merged 23 commits into
a2ui-project:mainfrom
gspencergoog:refactor-function-call
Jun 5, 2026
Merged

refactor: Refactor FunctionCall wire schema and align protocol specification#1518
gspencergoog merged 23 commits into
a2ui-project:mainfrom
gspencergoog:refactor-function-call

Conversation

@gspencergoog

@gspencergoog gspencergoog commented Jun 2, 2026

Copy link
Copy Markdown
Collaborator

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.

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.

Ummm, I don't know what I was thinking here. I guess I just didn't read it properly??

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
gspencergoog force-pushed the refactor-function-call branch from 00b0f0e to 0d18b66 Compare June 3, 2026 22:20
Comment thread specification/v0_10/catalogs/minimal/catalog.json
},
"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.

Ummm, I don't know what I was thinking here. I guess I just didn't read it properly??

@@ -159,17 +159,9 @@
"allOf": [

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.

I think allOf now only has one child, so you can move the reference to FunctionCall a step higher.

"description": "Describes a function's validation schema and interface metadata.",
"allOf": [
{
"$ref": "#/$defs/FunctionCallValidationSchema"

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.

Actually, how about just inlining FunctionCallValidationSchema into FunctionDefinition rather than having it separate.

I think I suggested this structure, but I was confused before. I hadn't realised that FunctionCallValidationSchema and FunctionCall are different things, because the first one is for a function declaration (e.g. the types of arguments) and the second is for a function call.

Comment thread tmp/refactor_function_call_pr_description.md
@gspencergoog
gspencergoog merged commit ecda497 into a2ui-project:main Jun 5, 2026
25 checks passed
@github-project-automation github-project-automation Bot moved this from Todo to Done in A2UI Jun 5, 2026
gspencergoog added a commit to gspencergoog/A2UI that referenced this pull request Jun 5, 2026
…ication (a2ui-project#1518)

# 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 a2ui-project#718
@gspencergoog
gspencergoog deleted the refactor-function-call branch June 25, 2026 21:08
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