ag_ui_a2ui/constants.rs
1//! Wire-contract constants shared across every A2UI toolkit.
2//!
3//! # These values are a cross-language wire contract
4//!
5//! Every shipping A2UI toolkit (TypeScript, .NET, Python) hard-codes the same
6//! strings, and the .NET constants file declares them a "cross-language wire
7//! contract" that "must not diverge". A renderer written against the TypeScript
8//! toolkit will silently fail to see this crate's output if any of them change.
9//!
10//! **Do not change these to match a newer spec revision on its own.** The A2UI
11//! specification is at v1.0, but the interoperable toolkits still stamp
12//! [`PROTOCOL_VERSION`] `"v0.9"` — so this crate does too. Changing a value here
13//! is a breaking protocol change that has to land in every language at once.
14
15/// Envelope key carrying a batch of A2UI operations over the transport.
16///
17/// The frontend detects an A2UI payload by looking for exactly this key, so it
18/// doubles as the content sniff.
19pub const A2UI_OPERATIONS_KEY: &str = "a2ui_operations";
20
21/// `catalogId` for the standard basic component catalog.
22///
23/// Note that the upstream specification repository serves the same catalog
24/// document under `.../v0_9/catalogs/basic/catalog.json`, and the document's own
25/// `catalogId` field carries that longer URI. The value below is what the
26/// shipping toolkits negotiate with, and a `catalogId` is an opaque identifier
27/// rather than a resolvable URL, so this is the one that matters on the wire.
28pub const BASIC_CATALOG_ID: &str = "https://a2ui.org/specification/v0_9/basic_catalog.json";
29
30/// `surfaceId` used when the caller does not supply one.
31pub const DEFAULT_SURFACE_ID: &str = "dynamic-surface";
32
33/// Value stamped into the `version` field of every message this crate emits.
34pub const PROTOCOL_VERSION: &str = "v0.9";
35
36/// Planner-facing tool name: "build me a surface for this request".
37pub const GENERATE_A2UI_TOOL_NAME: &str = "generate_a2ui";
38
39/// Inner structured-output tool name the generating model calls to emit a surface.
40pub const RENDER_A2UI_TOOL_NAME: &str = "render_a2ui";
41
42/// Total generation attempts before the recovery loop gives up.
43pub const MAX_A2UI_ATTEMPTS: u32 = 3;
44
45/// Activity type used to report recovery-loop progress to the caller.
46pub const A2UI_RECOVERY_ACTIVITY_TYPE: &str = "a2ui_recovery";
47
48/// MIME type for a standalone A2UI payload (A2A parts, MCP resources, HTTP bodies).
49pub const MIME_TYPE: &str = "application/a2ui+json";
50
51/// The `id` the root of a surface's component tree must have.
52///
53/// Fixed by the specification: "One of the components in one of the component
54/// lists MUST have an `id` of `root`".
55pub const ROOT_ID: &str = "root";
56
57/// Opening tag an LLM wraps a raw A2UI JSON block in.
58pub const A2UI_OPEN_TAG: &str = "<a2ui-json>";
59
60/// Closing tag an LLM wraps a raw A2UI JSON block in.
61pub const A2UI_CLOSE_TAG: &str = "</a2ui-json>";
62
63/// Component type name reserved for the implicit surface container.
64///
65/// `createSurface` instantiates it with `child: "root"`; it can never appear in
66/// an `updateComponents` list. It is meaningful in composition constraints:
67/// `allowedParents: ["Surface"]` restricts a component to being the root.
68pub const SURFACE_COMPONENT: &str = "Surface";