1use async_trait::async_trait;
2use serde::{Deserialize, Serialize};
3use std::collections::HashMap;
4use std::sync::Arc;
5
6use crate::{AuthMetadata, Tool};
7
8#[derive(Debug, Clone, Serialize, Deserialize)]
10pub struct OAuthProviderConfig {
11 pub provider: String,
12 pub client_id: Option<String>,
13 pub client_secret: Option<String>,
14 pub authorization_url: String,
15 pub token_url: String,
16 pub refresh_url: Option<String>,
17 pub scopes: Vec<String>,
18 pub redirect_uri: Option<String>,
19}
20
21#[derive(Debug, Clone, Serialize, Deserialize)]
23pub struct SecretProviderConfig {
24 pub provider: String,
25 pub key_name: String,
26 pub location: Option<String>, pub description: Option<String>,
28}
29
30#[derive(Debug, Clone, Serialize, Deserialize)]
32#[serde(tag = "type")]
33pub enum AuthProviderConfig {
34 #[serde(rename = "oauth")]
35 OAuth(OAuthProviderConfig),
36 #[serde(rename = "secret")]
37 Secret(SecretProviderConfig),
38}
39
40#[async_trait]
43pub trait Integration: Send + Sync + std::fmt::Debug {
44 fn get_name(&self) -> String;
46
47 fn get_description(&self) -> String;
49
50 fn get_version(&self) -> String {
52 "1.0.0".to_string()
53 }
54
55 fn get_auth_metadata(&self) -> Option<Box<dyn AuthMetadata>> {
57 None
58 }
59
60 fn get_tools(&self) -> Vec<Arc<dyn Tool>>;
62
63 fn get_callbacks(&self) -> HashMap<String, serde_json::Value> {
65 HashMap::new() }
67
68 fn get_notifications(&self) -> Vec<String> {
70 vec![] }
72
73 fn get_metadata(&self) -> HashMap<String, serde_json::Value> {
75 HashMap::new()
76 }
77
78 async fn initialize(&self) -> Result<(), anyhow::Error> {
80 Ok(()) }
82
83 async fn shutdown(&self) -> Result<(), anyhow::Error> {
85 Ok(()) }
87}
88
89#[derive(Debug)]
92pub struct IntegrationTool {
93 tool: Arc<dyn Tool>,
95 integration_name: String,
97}
98
99impl IntegrationTool {
100 pub fn new(tool: Arc<dyn Tool>, integration_name: String) -> Self {
102 Self {
103 tool,
104 integration_name,
105 }
106 }
107
108 pub fn get_integration_name(&self) -> &str {
110 &self.integration_name
111 }
112
113 pub fn get_tool(&self) -> &Arc<dyn Tool> {
115 &self.tool
116 }
117}
118
119#[async_trait]
120impl Tool for IntegrationTool {
121 fn get_name(&self) -> String {
122 self.tool.get_name()
123 }
124
125 fn get_parameters(&self) -> serde_json::Value {
126 self.tool.get_parameters()
127 }
128
129 fn get_description(&self) -> String {
130 self.tool.get_description()
131 }
132
133 fn is_external(&self) -> bool {
134 self.tool.is_external()
135 }
136
137 fn is_mcp(&self) -> bool {
138 self.tool.is_mcp()
139 }
140
141 fn is_sync(&self) -> bool {
142 self.tool.is_sync()
143 }
144
145 fn is_final(&self) -> bool {
146 self.tool.is_final()
147 }
148
149 fn needs_executor_context(&self) -> bool {
150 self.tool.needs_executor_context()
151 }
152
153 fn get_auth_metadata(&self) -> Option<Box<dyn AuthMetadata>> {
155 self.tool.get_auth_metadata()
158 }
159
160 fn get_plugin_name(&self) -> Option<String> {
162 Some(self.integration_name.clone())
163 }
164
165 async fn execute(
166 &self,
167 tool_call: crate::ToolCall,
168 context: Arc<crate::ToolContext>,
169 ) -> Result<Vec<crate::Part>, anyhow::Error> {
170 self.tool.execute(tool_call, context).await
171 }
172
173 fn execute_sync(
174 &self,
175 tool_call: crate::ToolCall,
176 context: Arc<crate::ToolContext>,
177 ) -> Result<Vec<crate::Part>, anyhow::Error> {
178 self.tool.execute_sync(tool_call, context)
179 }
180}
181
182#[derive(Debug, Clone, Serialize, Deserialize)]
184pub struct IntegrationInfo {
185 pub name: String,
186 pub description: String,
187 pub version: String,
188 pub tools: Vec<String>, pub callbacks: HashMap<String, serde_json::Value>,
190 pub notifications: Vec<String>,
191 pub requires_auth: bool,
192 pub auth_entity: Option<String>,
193 pub metadata: HashMap<String, serde_json::Value>,
194}
195
196#[derive(Debug, Clone, Serialize, Deserialize)]
198pub struct PluginData {
199 #[serde(default)]
200 pub package_name: String,
201 pub integrations: Vec<IntegrationData>,
202}
203
204#[derive(Debug, Clone, Serialize, Deserialize)]
206pub struct IntegrationToolDefinition {
207 pub name: String,
208 pub description: String,
209 pub version: Option<String>,
210 #[serde(default)]
211 pub parameters: serde_json::Value,
212 #[serde(default, skip_serializing_if = "Option::is_none", rename = "auth")]
213 pub auth: Option<crate::AuthRequirement>,
214}
215
216#[derive(Debug, Clone, Serialize, Deserialize)]
218pub struct IntegrationData {
219 #[serde(default)]
220 pub name: String,
221
222 pub description: String,
223 pub version: String,
224 #[serde(default)]
225 pub tools: Vec<IntegrationToolDefinition>,
226 #[serde(default)]
227 pub callbacks: HashMap<String, serde_json::Value>,
228 #[serde(default, skip_serializing_if = "Option::is_none", rename = "auth")]
229 pub auth: Option<crate::AuthRequirement>,
230 #[serde(default)]
231 pub notifications: Vec<String>,
232 #[serde(default)]
233 pub metadata: HashMap<String, serde_json::Value>,
234}
235
236impl IntegrationInfo {
237 pub fn from_integration(integration: &dyn Integration) -> Self {
238 let auth_metadata = integration.get_auth_metadata();
239 let (requires_auth, auth_entity) = if let Some(auth) = auth_metadata.as_ref() {
240 (auth.requires_auth(), Some(auth.get_auth_entity()))
241 } else {
242 (false, None)
243 };
244
245 Self {
246 name: integration.get_name(),
247 description: integration.get_description(),
248 version: integration.get_version(),
249 tools: integration
250 .get_tools()
251 .iter()
252 .map(|t| t.get_name())
253 .collect(),
254 callbacks: integration.get_callbacks(),
255 notifications: integration.get_notifications(),
256 requires_auth,
257 auth_entity,
258 metadata: integration.get_metadata(),
259 }
260 }
261}