Skip to content

Extending A2UI with Custom Functions

A2UI functions are designed to be extensible. Third-party developers can define their own function catalogs.

This guide demonstrates how to create a custom_catalog.json that adds a string trim function and a hardware query function (getScreenResolution).

Create a JSON Schema file (e.g., custom_catalog.json) that defines your function parameters.

Use the functions property to define a map of function schemas.

{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://example.com/schemas/custom_catalog.json",
"title": "Custom Function Catalog",
"description": "Extension catalog adding string trimming and screen resolution functions.",
"functions": {
"trim": {
"type": "object",
"description": "Removes whitespace (or other characters) from the beginning and end of a string.",
"properties": {
"call": { "const": "trim" },
"args": {
"type": "object",
"properties": {
"value": {
"$ref": "common_types.json#/$defs/DynamicString",
"description": "The string to trim."
},
"chars": {
"$ref": "common_types.json#/$defs/DynamicString",
"description": "Optional. A set of characters to remove. Defaults to whitespace."
}
},
"required": ["value"],
"unevaluatedProperties": false
},
"returnType": { "const": "string" }
},
"required": ["call", "args"],
"unevaluatedProperties": false
},
"getScreenResolution": {
"type": "object",
"description": "Queries hardware for screen resolution.",
"properties": {
"call": { "const": "getScreenResolution" },
"args": {
"type": "object",
"properties": {
"screenIndex": {
"$ref": "common_types.json#/$defs/DynamicNumber",
"description": "Optional. The index of the screen to query. Defaults to 0 (primary screen)."
}
},
"unevaluatedProperties": false
},
"returnType": { "const": "array" }
},
"required": ["call", "args"],
"unevaluatedProperties": false
}
}
}

The FunctionCall definition refers to a catalog-agnostic reference. In your catalog, you simply need to define the anyFunction reference:

{
"$defs": {
"anyFunction": {
"oneOf": [
{"$ref": "#/functions/trim"},
{"$ref": "#/functions/getScreenResolution"}
]
}
}
}

If you want to incorporate functions defined in the [basic_catalog.json], those can be added too:

{
"$defs": {
"anyFunction": {
"oneOf": [
{"$ref": "#/functions/trim"},
{"$ref": "#/functions/getScreenResolution"},
{"$ref": "basic_catalog.json#/$defs/anyFunction" }
]
}
}
}

When a FunctionCall is validated:

  1. Discriminator Lookup: The validator looks at the call property of the object.
  2. Schema Matching:
    • If call is “length”, it matches Functions -> length and validates the named arguments in args against the length rules.
    • If call is “trim”, it matches CustomFunctions -> trim and validates against your custom rules.
    • If call is “unknownFunc”, validation FAILS immediately (strict mode).

This strict-by-default approach ensures typos are caught early, while the modular structure makes it easy to add new capabilities with full type safety.