A2UI: Agent-to-UI Protocol
The A2UI protocol allows agents to render complex, interactive interfaces within the Chat Console (Canvas). Unlike static Markdown, A2UI supports dynamic components like forms, tables, and charts that can be updated incrementally via JSON patches.Data Flow & Rendering
The A2UI lifecycle begins with anA2uiDocument being emitted by the daemon. The frontend uses A2uiRenderer to transform this document into React components.
- Initial State: A full
A2uiDocumentis sent to the client. - Patching: Subsequent updates are sent as
PatchDocumentobjects containingPatchOperationarrays (e.g.,replace,add,remove). - Normalization: The frontend runs
normalizeA2uiDocumentto ensure the incoming JSON matches the expected TypeScript interfaces. - Rendering: The
A2uiRendereriterates throughdocument.componentsand delegates to specific sub-renderers.
A2UI Architecture
The following diagram illustrates the relationship between the A2UI TypeScript entities and the rendering logic. A2UI Entity to Code Mapping Sources: apps/web/src/a2ui/renderer.tsx#33-59, apps/web/src/a2ui/renderer.tsx#66-97, apps/web/src/a2ui/tests/renderer.snapshot.test.tsx#44-46Supported Components
| Component Type | Role | Key Props |
|---|---|---|
text | Basic text display | value, tone (e.g., info, error) |
markdown | Rich text rendering | value (sanitized) |
table | Tabular data | columns, rows |
form | Human-in-the-loop input | fields, submitLabel, title |
chart | Data visualization | series (bar charts) |
Workspace Patch Protocol
The Workspace Patch system provides a secure, fail-closed mechanism for agents to modify files within a user’s local workspace. It is defined in thepalyra-common crate and includes strict limits and redaction policies.
Implementation Details
The core logic resides inapply_workspace_patch. It follows a Plan -> Validate -> Execute flow:
- Parsing: The patch string is parsed into a series of
PatchOperation(Add, Update, Delete). - Validation: Paths are checked against
workspace_rootsto prevent directory traversal. - Limits:
WorkspacePatchLimitsenforces maximum bytes and file counts. - Execution: Changes are applied atomically. If a failure occurs, a best-effort rollback is performed.
Key Structures
WorkspacePatchLimits: Definesmax_patch_bytes(default 256KB) andmax_files_touched(default 64). crates/palyra-common/src/workspace_patch.rs#23-39WorkspacePatchFileAttestation: Metadata emitted for every modified file, including SHA256 hashes and size changes. crates/palyra-common/src/workspace_patch.rs#75-88WorkspacePatchRedactionPolicy: Patterns used to scrub secrets (e.g.,api_key,password) from theredacted_previewreturned to the agent. crates/palyra-common/src/workspace_patch.rs#45-63
Tool Input Schemas
Tools in Palyra consume JSON payloads that must strictly adhere to predefined schemas. This is enforced during thedecide_tool_call phase in the daemon.
Process Runner Input
Thepalyra.process.run tool uses the ProcessRunnerToolInput struct. It enforces deny_unknown_fields to prevent unexpected parameters from reaching the shell.
| Field | Type | Description |
|---|---|---|
command | String | The executable to run. |
args | Vec<String> | List of arguments. |
cwd | Option<String> | Working directory relative to workspace root. |
requested_egress_hosts | Vec<String> | Network hosts the process needs to access. |
Validation & Fuzzing
To ensure the robustness of JSON parsing across the monorepo, several fuzzing targets are maintained in thefuzz/ directory. These targets subject the parsers to arbitrary byte streams to detect crashes or hangs.
a2ui_json_parser: Targets the A2UI protocol normalization. fuzz/Cargo.toml#26-30workspace_patch_parser: Targets theapply_workspace_patchlogic withdry_run: true. fuzz/fuzz_targets/workspace_patch_parser.rs#21-41process_runner_input_parser: Targets theparse_process_runner_tool_inputfunction. fuzz/fuzz_targets/process_runner_input_parser.rs#8-13