Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions specification/v0_10/docs/a2ui_protocol.md
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,22 @@ To execute a local function, use the `functionCall` property within the `action`
}
```

```json
{
"component": "Button",
"text": "Copy Invite Code",
"action": {
"functionCall": {
"call": "copyToClipboard",
"args": {
"text": "INVITE-1234"
},
"returnType": "void"
}
}
}
```

## Data model representation: binding, scope

This section describes how UI components **represent** and reference data from the Data Model. A2UI relies on a strictly defined relationship between the UI structure (Components) and the state (Data Model), defining the mechanics of path resolution, variable scope during iteration.
Expand Down Expand Up @@ -687,6 +703,7 @@ The [`standard_catalog.json`] provides the baseline set of components and functi
| **formatDate** | Formats a date/time using a pattern. |
| **pluralize** | Selects a localized string based on a numeric count. |
| **openUrl** | Opens a URL in a browser. |
| **copyToClipboard**| Copies text to the system clipboard. |
| **and** | Logical AND operation on a list of boolean values. |
| **or** | Logical OR operation on a list of boolean values. |
| **not** | Logical NOT operation on a boolean value. |
Expand Down
7 changes: 7 additions & 0 deletions specification/v0_10/eval/src/prompts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,13 @@ Each activity in the inner lists should be a 'Row' containing a 'CheckBox' (to m
Include a 'Button' labeled "Visit Website".
The button's action should be a client-side function call to 'openUrl' with the argument 'url': 'https://a2ui.org'.`,
},
{
name: "copyToClipboardAction",
description: "A button that copies text to clipboard.",
promptText: `Create a 'createSurface' and 'updateComponents' message. Surface ID 'main'.
Include a 'Button' labeled "Copy Code".
The button's action should be a client-side function call to 'copyToClipboard' with the argument 'text': 'SAVE20'.`,
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The prompt text for the LLM is a bit ambiguous about returnType. Given the subtleties of the schema validation where returnType defaults to "boolean", it would be more robust to explicitly ask the LLM to include "returnType": "void" in the function call. This will lead to more reliable JSON generation.

    The button's action should be a client-side function call to 'copyToClipboard' with the argument 'text': 'SAVE20' and a 'returnType' of 'void'.

},
{
name: "nestedLayoutRecursive",
description: "A deeply nested layout to test component recursion.",
Expand Down
26 changes: 26 additions & 0 deletions specification/v0_10/json/standard_catalog.json
Original file line number Diff line number Diff line change
Expand Up @@ -981,6 +981,31 @@
"required": ["call", "args"],
"unevaluatedProperties": false
},
"copyToClipboard": {
"type": "object",
"description": "Copies text to the system clipboard. This function has no return value.",
"properties": {
"call": {
"const": "copyToClipboard"
},
"args": {
"type": "object",
"properties": {
"text": {
"$ref": "common_types.json#/$defs/DynamicString",
"description": "The text to copy."
}
},
"required": ["text"],
"additionalProperties": false
},
"returnType": {
"const": "void"
}
},
"required": ["call", "args"],
"unevaluatedProperties": false
},
"and": {
"type": "object",
"description": "Performs a logical AND operation on a list of boolean values.",
Expand Down Expand Up @@ -1129,6 +1154,7 @@
{ "$ref": "#/functions/formatDate" },
{ "$ref": "#/functions/pluralize" },
{ "$ref": "#/functions/openUrl" },
{ "$ref": "#/functions/copyToClipboard" },
{ "$ref": "#/functions/and" },
{ "$ref": "#/functions/or" },
{ "$ref": "#/functions/not" }
Expand Down
100 changes: 100 additions & 0 deletions specification/v0_10/test/cases/function_catalog_validation.json
Original file line number Diff line number Diff line change
Expand Up @@ -472,6 +472,106 @@
}
}
},
{
"description": "copyToClipboard: Valid call in Action",
"valid": true,
"data": {
"version": "v0.10",
"updateComponents": {
"surfaceId": "test",
"components": [
{
"id": "btn1",
"component": "Button",
"child": "txt1",
"action": {
"functionCall": {
"call": "copyToClipboard",
"args": { "text": "ABC-123" },
"returnType": "void"
}
}
},
{ "id": "txt1", "component": "Text", "text": "Copy" }
]
}
}
},
{
"description": "copyToClipboard: Invalid args (string instead of object)",
"valid": false,
"data": {
"version": "v0.10",
"updateComponents": {
"surfaceId": "test",
"components": [
{
"id": "btn1",
"component": "Button",
"child": "txt1",
"action": {
"functionCall": {
"call": "copyToClipboard",
"args": "ABC-123",
"returnType": "void"
}
}
},
{ "id": "txt1", "component": "Text", "text": "Copy" }
]
}
}
},
{
"description": "copyToClipboard: Invalid returnType",
"valid": false,
"data": {
"version": "v0.10",
"updateComponents": {
"surfaceId": "test",
"components": [
{
"id": "btn1",
"component": "Button",
"child": "txt1",
"action": {
"functionCall": {
"call": "copyToClipboard",
"args": { "text": "ABC-123" },
"returnType": "string"
}
}
},
{ "id": "txt1", "component": "Text", "text": "Copy" }
]
}
}
},
{
"description": "copyToClipboard: Invalid text type (number)",
"valid": false,
"data": {
"version": "v0.10",
"updateComponents": {
"surfaceId": "test",
"components": [
{
"id": "btn1",
"component": "Button",
"child": "txt1",
"action": {
"functionCall": {
"call": "copyToClipboard",
"args": { "text": 12345 },
"returnType": "void"
}
}
},
{ "id": "txt1", "component": "Text", "text": "Copy" }
]
}
}
},
{
"description": "length: Invalid min type (string)",
"valid": false,
Expand Down