Skip to main content

adk_ui/a2ui/
capabilities.rs

1use serde::{Deserialize, Serialize};
2use serde_json::Value;
3
4use super::{A2UI_BASIC_CATALOG_ID, A2UI_BASIC_CATALOG_ID_V1};
5
6fn is_false(value: &bool) -> bool {
7    !*value
8}
9
10/// Catalog support advertised by an A2UI renderer.
11#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq)]
12#[serde(rename_all = "camelCase")]
13pub struct A2uiRendererCapabilitySet {
14    pub supported_catalog_ids: Vec<String>,
15    #[serde(skip_serializing_if = "Option::is_none")]
16    pub inline_catalogs: Option<Vec<Value>>,
17}
18
19/// Versioned A2UI renderer capabilities. The upstream schemas intentionally
20/// keep the family key (`v0.9`) for the production v0.9.1 patch release.
21#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq)]
22pub struct A2uiRendererCapabilities {
23    #[serde(rename = "v0.9", skip_serializing_if = "Option::is_none")]
24    pub v0_9: Option<A2uiRendererCapabilitySet>,
25    #[serde(rename = "v1.0", skip_serializing_if = "Option::is_none")]
26    pub v1_0: Option<A2uiRendererCapabilitySet>,
27}
28
29/// Catalog support advertised by an A2UI agent.
30#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq, Eq)]
31#[serde(rename_all = "camelCase")]
32pub struct A2uiAgentCapabilitySet {
33    pub supported_catalog_ids: Vec<String>,
34    #[serde(default, skip_serializing_if = "is_false")]
35    pub accepts_inline_catalogs: bool,
36}
37
38/// Versioned A2UI agent capabilities for production and candidate renderers.
39#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq, Eq)]
40pub struct A2uiAgentCapabilities {
41    #[serde(rename = "v0.9", skip_serializing_if = "Option::is_none")]
42    pub v0_9: Option<A2uiAgentCapabilitySet>,
43    #[serde(rename = "v1.0", skip_serializing_if = "Option::is_none")]
44    pub v1_0: Option<A2uiAgentCapabilitySet>,
45}
46
47pub fn default_a2ui_renderer_capabilities() -> A2uiRendererCapabilities {
48    A2uiRendererCapabilities {
49        v0_9: Some(A2uiRendererCapabilitySet {
50            supported_catalog_ids: vec![A2UI_BASIC_CATALOG_ID.to_string()],
51            inline_catalogs: None,
52        }),
53        v1_0: Some(A2uiRendererCapabilitySet {
54            supported_catalog_ids: vec![A2UI_BASIC_CATALOG_ID_V1.to_string()],
55            inline_catalogs: None,
56        }),
57    }
58}
59
60pub fn default_a2ui_agent_capabilities() -> A2uiAgentCapabilities {
61    A2uiAgentCapabilities {
62        v0_9: Some(A2uiAgentCapabilitySet {
63            supported_catalog_ids: vec![A2UI_BASIC_CATALOG_ID.to_string()],
64            accepts_inline_catalogs: false,
65        }),
66        v1_0: Some(A2uiAgentCapabilitySet {
67            supported_catalog_ids: vec![A2UI_BASIC_CATALOG_ID_V1.to_string()],
68            accepts_inline_catalogs: false,
69        }),
70    }
71}
72
73#[cfg(test)]
74mod tests {
75    use super::*;
76
77    #[test]
78    fn capabilities_use_upstream_version_family_keys() {
79        let renderer = serde_json::to_value(default_a2ui_renderer_capabilities()).unwrap();
80        let agent = serde_json::to_value(default_a2ui_agent_capabilities()).unwrap();
81
82        assert_eq!(
83            renderer["v0.9"]["supportedCatalogIds"][0],
84            A2UI_BASIC_CATALOG_ID
85        );
86        assert_eq!(
87            renderer["v1.0"]["supportedCatalogIds"][0],
88            A2UI_BASIC_CATALOG_ID_V1
89        );
90        assert_eq!(agent["v1.0"]["acceptsInlineCatalogs"], Value::Null);
91    }
92}