116 lines
6.2 KiB
TypeScript
116 lines
6.2 KiB
TypeScript
/**
|
|
* Default A2UI generation and design guideline prompts.
|
|
*
|
|
* These are the canonical prompt fragments that instruct an LLM how to call
|
|
* the render_a2ui tool, how to bind data, and how to style surfaces.
|
|
*/
|
|
|
|
/**
|
|
* Generation guidelines — protocol rules, tool arguments, path rules,
|
|
* data model format, and form/two-way-binding instructions.
|
|
*/
|
|
export const A2UI_DEFAULT_GENERATION_GUIDELINES = `\
|
|
Generate A2UI v0.9 JSON.
|
|
|
|
## A2UI Protocol Instructions
|
|
|
|
A2UI (Agent to UI) is a protocol for rendering rich UI surfaces from agent responses.
|
|
|
|
CRITICAL: You MUST call the render_a2ui tool with ALL of these arguments:
|
|
- surfaceId: A unique ID for the surface (e.g. "product-comparison")
|
|
- components: REQUIRED — the A2UI component array. NEVER omit this. Only use
|
|
components listed in the Available Components schema provided as context.
|
|
- data: OPTIONAL — a JSON object written to the root of the surface data model.
|
|
Use for pre-filling form values or providing data for path-bound components.
|
|
- every component must have the "component" field specifying the component type.
|
|
ONLY use component names from the Available Components schema — do NOT invent
|
|
component names or use names not in the schema.
|
|
|
|
COMPONENT ID RULES:
|
|
- Exactly one component MUST have id="root". This is the surface's entry
|
|
point — the renderer begins at "root" and walks the child/children tree
|
|
from there. Every other component must be reachable from "root". If no
|
|
component has id="root", the surface renders an empty loading placeholder
|
|
and none of your components will be shown.
|
|
- Every component ID must be unique within the surface.
|
|
- A component MUST NOT reference itself as child/children. This causes a
|
|
circular dependency error. For example, if a component has id="avatar",
|
|
its child must be a DIFFERENT id (e.g. "avatar-img"), never "avatar".
|
|
- The child/children tree must be a DAG — no cycles allowed.
|
|
|
|
REPEATING CONTENT (TEMPLATES):
|
|
To repeat a component for each item in an array, use the structural children format:
|
|
children: { componentId: "card-id", path: "/items" }
|
|
This tells the renderer to create one instance of "card-id" per item in the "/items" array.
|
|
|
|
PATH RULES FOR TEMPLATES:
|
|
Components inside a repeating template use RELATIVE paths (no leading slash).
|
|
The path is resolved relative to each array item automatically.
|
|
If a container has children: { componentId: "card", path: "/items" } and each item
|
|
has a key "name", use { "path": "name" } (NO leading slash — relative to item).
|
|
CRITICAL: Do NOT use "/name" (absolute) inside templates — use "name" (relative).
|
|
The container's path ("/items") uses a leading slash (absolute), but all
|
|
components INSIDE the template use paths WITHOUT leading slash.
|
|
|
|
COMPONENT VALUES — DEFAULT RULE:
|
|
Use inline literal values for ALL component properties. Pass strings, numbers,
|
|
arrays, and objects directly on the component. Do NOT use { "path": "..." }
|
|
objects unless the property's schema explicitly allows it (see exception below).
|
|
CRITICAL: USING { "path": "..." } ON A PROPERTY THAT DOES NOT DECLARE PATH
|
|
SUPPORT IN ITS SCHEMA WILL CAUSE A RUNTIME CRASH AND BREAK THE ENTIRE UI.
|
|
ALWAYS CHECK THE COMPONENT SCHEMA FIRST — IF THE PROPERTY ONLY ACCEPTS A
|
|
PLAIN TYPE, YOU MUST USE A LITERAL VALUE.
|
|
VERY IMPORTANT: THE APPLICATION WILL BREAK IF YOU DO NOT FOLLOW THIS RULE!
|
|
|
|
For example, a chart's "data" must always be an inline array:
|
|
"data": [{"label": "Jan", "value": 100}, {"label": "Feb", "value": 200}]
|
|
A metric's "value" must always be an inline string:
|
|
"value": "$1,200"
|
|
|
|
PATH BINDING EXCEPTION — SCHEMA-DRIVEN:
|
|
A few properties accept { "path": "/some/path" } as an alternative to a literal
|
|
value. You can identify these in the Available Components schema: the property
|
|
will list BOTH a literal type AND an object-with-path option. If a property only
|
|
shows a single type (string, number, array, etc.), it does NOT support path
|
|
binding — use a literal value only.
|
|
|
|
Path binding is typically used for editable form inputs so the client can write
|
|
user input back to the data model. When building forms:
|
|
- Bind input "value" to a data model path: "value": { "path": "/form/name" }
|
|
- Pre-fill via the "data" tool argument: "data": { "form": { "name": "Alice" } }
|
|
- Capture values on submit via button action context:
|
|
"action": { "event": { "name": "submit", "context": { "name": { "path": "/form/name" } } } }
|
|
|
|
REPEATING CONTENT uses a structural children format (not the same as value binding):
|
|
children: { componentId: "card-id", path: "/items" }
|
|
Components inside templates use RELATIVE paths (no leading slash): { "path": "name" }.`;
|
|
|
|
/**
|
|
* Design guidelines — visual design rules, component hierarchy tips,
|
|
* and action handler patterns.
|
|
*/
|
|
export const A2UI_DEFAULT_DESIGN_GUIDELINES = `\
|
|
Create polished, visually appealing interfaces. ONLY use components listed in the
|
|
Available Components schema — do NOT use component names that are not in the schema.
|
|
|
|
Design principles:
|
|
- Create clear visual hierarchy within cards and layouts.
|
|
- Keep cards clean — avoid clutter. Whitespace is good.
|
|
- Use consistent surfaceIds (lowercase, hyphenated).
|
|
- NEVER use the same ID for a component and its child — this creates a
|
|
circular dependency. E.g. if id="avatar", child must NOT be "avatar".
|
|
- For side-by-side comparisons, use a container with structural children
|
|
(children: { componentId, path }) to repeat a card template per data item.
|
|
- Include images when relevant (logos, icons, product photos):
|
|
- Prefer company logos via Google favicons: https://www.google.com/s2/favicons?domain=example.com&sz=128
|
|
- Do NOT invent Unsplash photo-IDs — they will 404. Only use real, known URLs.
|
|
- For buttons: action MUST use this exact nested format:
|
|
"action": { "event": { "name": "myAction", "context": { "key": "value" } } }
|
|
The "event" key holds an OBJECT with "name" (required) and "context" (optional).
|
|
Do NOT use a flat format like {"event": "name"} — "event" must be an object.
|
|
- For forms: check the component schema — if an input's "value" property
|
|
supports path binding, use it for editable fields. The submit button's
|
|
action context should reference the same paths to capture user input.
|
|
|
|
Use the SAME surfaceId as the main surface. Match action names to button action event names.`;
|