Skip to main content

a2ui_base/protocol/
server_to_client.rs

1//! A2UI v1.0 Server-to-Client Messages
2//!
3//! Mirrors the JSON Schema `server_to_client.json`.
4
5use serde::{Deserialize, Serialize};
6
7use super::common_types::FunctionCall;
8
9// ---------------------------------------------------------------------------
10// Top-level envelope
11// ---------------------------------------------------------------------------
12
13/// A single A2UI message from the server.
14#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
15pub struct A2uiMessage {
16    pub version: String,
17    #[serde(flatten)]
18    pub payload: A2uiPayload,
19}
20
21/// The typed payload of a server-to-client message.
22#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
23#[serde(untagged)]
24pub enum A2uiPayload {
25    CreateSurface(CreateSurfacePayload),
26    UpdateComponents(UpdateComponentsPayload),
27    UpdateDataModel(UpdateDataModelPayload),
28    DeleteSurface(DeleteSurfacePayload),
29    CallFunction(CallFunctionPayload),
30    ActionResponse(ActionResponsePayload),
31}
32
33// ---------------------------------------------------------------------------
34// createSurface
35// ---------------------------------------------------------------------------
36
37#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
38#[serde(rename_all = "camelCase")]
39pub struct CreateSurfacePayload {
40    pub create_surface: CreateSurfaceData,
41}
42
43#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
44#[serde(rename_all = "camelCase")]
45pub struct CreateSurfaceData {
46    pub surface_id: String,
47    pub catalog_id: String,
48    #[serde(default, skip_serializing_if = "Option::is_none")]
49    pub surface_properties: Option<serde_json::Value>,
50    #[serde(default)]
51    pub send_data_model: bool,
52    #[serde(default, skip_serializing_if = "Option::is_none")]
53    pub components: Option<Vec<serde_json::Value>>,
54    #[serde(default, skip_serializing_if = "Option::is_none")]
55    pub data_model: Option<serde_json::Value>,
56}
57
58// ---------------------------------------------------------------------------
59// updateComponents
60// ---------------------------------------------------------------------------
61
62#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
63#[serde(rename_all = "camelCase")]
64pub struct UpdateComponentsPayload {
65    pub update_components: UpdateComponentsData,
66}
67
68#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
69#[serde(rename_all = "camelCase")]
70pub struct UpdateComponentsData {
71    pub surface_id: String,
72    pub components: Vec<serde_json::Value>,
73}
74
75// ---------------------------------------------------------------------------
76// updateDataModel
77// ---------------------------------------------------------------------------
78
79#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
80#[serde(rename_all = "camelCase")]
81pub struct UpdateDataModelPayload {
82    pub update_data_model: UpdateDataModelData,
83}
84
85#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
86#[serde(rename_all = "camelCase")]
87pub struct UpdateDataModelData {
88    pub surface_id: String,
89    #[serde(default, skip_serializing_if = "Option::is_none")]
90    pub path: Option<String>,
91    #[serde(default, skip_serializing_if = "Option::is_none")]
92    pub value: Option<serde_json::Value>,
93}
94
95// ---------------------------------------------------------------------------
96// deleteSurface
97// ---------------------------------------------------------------------------
98
99#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
100#[serde(rename_all = "camelCase")]
101pub struct DeleteSurfacePayload {
102    pub delete_surface: DeleteSurfaceData,
103}
104
105#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
106#[serde(rename_all = "camelCase")]
107pub struct DeleteSurfaceData {
108    pub surface_id: String,
109}
110
111// ---------------------------------------------------------------------------
112// callFunction
113// ---------------------------------------------------------------------------
114
115#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
116#[serde(rename_all = "camelCase")]
117pub struct CallFunctionPayload {
118    pub call_function: FunctionCall,
119    pub function_call_id: String,
120    #[serde(default)]
121    pub want_response: bool,
122}
123
124// ---------------------------------------------------------------------------
125// actionResponse
126// ---------------------------------------------------------------------------
127
128#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
129#[serde(rename_all = "camelCase")]
130pub struct ActionResponsePayload {
131    pub action_response: ActionResponseData,
132    pub action_id: String,
133}
134
135#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
136#[serde(rename_all = "camelCase")]
137pub struct ActionResponseData {
138    #[serde(default, skip_serializing_if = "Option::is_none")]
139    pub value: Option<serde_json::Value>,
140    #[serde(default, skip_serializing_if = "Option::is_none")]
141    pub error: Option<ActionResponseError>,
142}
143
144#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
145pub struct ActionResponseError {
146    pub code: String,
147    pub message: String,
148}