Skip to main content

adk_ui/
compat.rs

1//! Compatibility layer providing standalone versions of types from `adk-core`.
2//!
3//! When the `adk-core` feature is enabled, these re-export from the real crate.
4//! Otherwise, minimal local definitions are used so `adk-ui` compiles independently.
5
6#[cfg(feature = "adk-core")]
7pub use adk_core::{
8    AdkError, Artifacts, CallbackContext, Content, EventActions, MemoryEntry, Part,
9    ReadonlyContext, Result, Tool, ToolContext, Toolset,
10};
11
12#[cfg(feature = "adk-core")]
13pub fn inline_data_part(mime_type: impl Into<String>, data: Vec<u8>) -> Part {
14    Part::InlineData {
15        mime_type: mime_type.into(),
16        data,
17        uri: None,
18        annotations: None,
19    }
20}
21
22#[cfg(not(feature = "adk-core"))]
23mod standalone {
24    use async_trait::async_trait;
25    use serde::{Deserialize, Serialize};
26    use serde_json::Value;
27    use std::collections::HashMap;
28    use std::fmt;
29    use std::sync::Arc;
30
31    // ── Error ──────────────────────────────────────────────────────────
32
33    #[derive(Debug, Clone)]
34    pub enum AdkError {
35        Tool(String),
36        Other(String),
37    }
38
39    impl AdkError {
40        pub fn tool(msg: impl Into<String>) -> Self {
41            AdkError::Tool(msg.into())
42        }
43    }
44
45    impl fmt::Display for AdkError {
46        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
47            match self {
48                AdkError::Tool(msg) => write!(f, "Tool error: {}", msg),
49                AdkError::Other(msg) => write!(f, "{}", msg),
50            }
51        }
52    }
53
54    impl std::error::Error for AdkError {}
55
56    pub type Result<T> = std::result::Result<T, AdkError>;
57
58    // ── Content / Part ─────────────────────────────────────────────────
59
60    #[derive(Debug, Clone, Serialize, Deserialize)]
61    pub struct Content {
62        pub role: String,
63        pub parts: Vec<Part>,
64    }
65
66    impl Content {
67        pub fn new(role: &str) -> Self {
68            Self {
69                role: role.to_string(),
70                parts: Vec::new(),
71            }
72        }
73
74        pub fn with_text(mut self, text: impl Into<String>) -> Self {
75            self.parts.push(Part::Text { text: text.into() });
76            self
77        }
78    }
79
80    #[derive(Debug, Clone, Serialize, Deserialize)]
81    #[serde(untagged)]
82    pub enum Part {
83        Text {
84            text: String,
85        },
86        InlineData {
87            mime_type: String,
88            data: Vec<u8>,
89            #[serde(default, skip_serializing_if = "Option::is_none")]
90            uri: Option<String>,
91            #[serde(default, skip_serializing_if = "Option::is_none")]
92            annotations: Option<Value>,
93        },
94    }
95
96    // ── Traits ─────────────────────────────────────────────────────────
97
98    #[async_trait]
99    pub trait Tool: Send + Sync {
100        fn name(&self) -> &str;
101        fn description(&self) -> &str;
102        fn parameters_schema(&self) -> Option<Value> {
103            None
104        }
105        async fn execute(&self, ctx: Arc<dyn ToolContext>, args: Value) -> Result<Value>;
106    }
107
108    pub trait ReadonlyContext: Send + Sync {
109        fn invocation_id(&self) -> &str {
110            ""
111        }
112        fn agent_name(&self) -> &str {
113            ""
114        }
115        fn user_id(&self) -> &str {
116            ""
117        }
118        fn app_name(&self) -> &str {
119            ""
120        }
121        fn session_id(&self) -> &str {
122            ""
123        }
124        fn branch(&self) -> &str {
125            ""
126        }
127        fn user_content(&self) -> &Content;
128        fn state(&self) -> Option<Value> {
129            None
130        }
131    }
132
133    #[async_trait]
134    pub trait ToolContext: ReadonlyContext + Send + Sync {
135        fn function_call_id(&self) -> &str {
136            ""
137        }
138        fn actions(&self) -> EventActions {
139            EventActions::default()
140        }
141        fn set_actions(&self, actions: EventActions);
142        async fn search_memory(&self, query: &str) -> Result<Vec<MemoryEntry>>;
143        async fn emit_progress(&self, _stream: &str, _chunk: &str) {}
144    }
145
146    #[async_trait]
147    pub trait Toolset: Send + Sync {
148        fn name(&self) -> &str;
149        async fn tools(&self, ctx: Arc<dyn ReadonlyContext>) -> Result<Vec<Arc<dyn Tool>>>;
150    }
151
152    pub trait CallbackContext: Send + Sync {
153        fn artifacts(&self) -> Option<Arc<dyn Artifacts>>;
154    }
155
156    pub trait Artifacts: Send + Sync {}
157
158    // ── Supporting types ───────────────────────────────────────────────
159
160    #[derive(Debug, Clone, Default, Serialize, Deserialize)]
161    pub struct EventActions {
162        #[serde(default)]
163        pub state_delta: HashMap<String, Value>,
164        #[serde(default)]
165        pub artifact_delta: HashMap<String, i64>,
166        #[serde(default)]
167        pub skip_summarization: bool,
168        #[serde(default)]
169        pub transfer_to_agent: Option<String>,
170        #[serde(default)]
171        pub escalate: bool,
172        #[serde(default, skip_serializing_if = "Option::is_none")]
173        pub route: Option<Vec<String>>,
174    }
175
176    #[derive(Debug, Clone, Serialize, Deserialize)]
177    pub struct MemoryEntry {
178        pub content: String,
179        #[serde(default)]
180        pub metadata: Option<Value>,
181    }
182}
183
184#[cfg(not(feature = "adk-core"))]
185pub use standalone::*;
186
187#[cfg(not(feature = "adk-core"))]
188pub fn inline_data_part(mime_type: impl Into<String>, data: Vec<u8>) -> Part {
189    Part::InlineData {
190        mime_type: mime_type.into(),
191        data,
192        uri: None,
193        annotations: None,
194    }
195}