1use serde::{Deserialize, Deserializer, Serialize};
2use std::collections::HashMap;
3
4fn null_to_default<'de, D, T>(deserializer: D) -> Result<T, D::Error>
12where
13 D: Deserializer<'de>,
14 T: Default + Deserialize<'de>,
15{
16 let opt = Option::<T>::deserialize(deserializer)?;
17 Ok(opt.unwrap_or_default())
18}
19
20#[derive(Debug, Serialize, Deserialize, Clone)]
21pub struct MediaContent {
22 pub id: String,
23 pub r#type: String,
24 #[serde(skip_serializing_if = "Option::is_none")]
25 pub url: Option<String>,
26 #[serde(skip_serializing_if = "Option::is_none")]
27 pub base64: Option<String>,
28}
29
30#[derive(Debug, Serialize, Deserialize, Clone)]
31pub struct ClientRequest {
32 pub query: String,
33 pub user_token: String,
34 #[serde(skip_serializing_if = "Option::is_none")]
35 pub client_id: Option<String>,
36 pub request_type: String,
37 #[serde(default)]
38 pub context: HashMap<String, serde_json::Value>,
39 #[serde(skip_serializing_if = "Option::is_none")]
40 pub media: Option<Vec<MediaContent>>,
41}
42
43#[must_use]
44#[derive(Debug, Serialize, Deserialize, Clone)]
45pub struct ClientResponse {
46 pub success: bool,
47 #[serde(skip_serializing_if = "Option::is_none")]
48 pub data: Option<serde_json::Value>,
49 #[serde(skip_serializing_if = "Option::is_none")]
50 pub result: Option<String>,
51 #[serde(skip_serializing_if = "Option::is_none")]
52 pub plan_id: Option<String>,
53 #[serde(skip_serializing_if = "Option::is_none")]
54 pub request_id: Option<String>,
55 #[serde(skip_serializing_if = "Option::is_none")]
56 pub metadata: Option<HashMap<String, serde_json::Value>>,
57 #[serde(skip_serializing_if = "Option::is_none")]
58 pub error: Option<String>,
59 #[serde(default)]
60 pub blocked: bool,
61 #[serde(skip_serializing_if = "Option::is_none")]
62 pub block_reason: Option<String>,
63 #[serde(skip_serializing_if = "Option::is_none")]
64 pub policy_info: Option<PolicyEvaluationInfo>,
65 #[serde(skip_serializing_if = "Option::is_none")]
66 pub budget_info: Option<BudgetInfo>,
67}
68
69impl ClientResponse {
70 pub fn fail_open(error: crate::error::AxonFlowError) -> Self {
71 Self {
72 success: true,
73 data: None,
74 result: None,
75 plan_id: None,
76 request_id: None,
77 metadata: None,
78 error: Some(format!("AxonFlow unavailable (fail-open): {}", error)),
79 blocked: false,
80 block_reason: None,
81 policy_info: None,
82 budget_info: None,
83 }
84 }
85}
86
87#[derive(Debug, Serialize, Deserialize, Clone)]
88pub struct BudgetInfo {
89 #[serde(skip_serializing_if = "Option::is_none")]
90 pub budget_id: Option<String>,
91 #[serde(skip_serializing_if = "Option::is_none")]
92 pub budget_name: Option<String>,
93 pub used_usd: f64,
94 pub limit_usd: f64,
95 pub percentage: f64,
96 pub exceeded: bool,
97 #[serde(skip_serializing_if = "Option::is_none")]
98 pub action: Option<String>,
99}
100
101#[derive(Debug, Serialize, Deserialize, Clone, Default)]
102#[serde(default)]
103pub struct PolicyEvaluationInfo {
104 #[serde(deserialize_with = "null_to_default")]
105 pub policies_evaluated: Vec<String>,
106 #[serde(deserialize_with = "null_to_default")]
107 pub static_checks: Vec<String>,
108 pub processing_time: String,
109 pub tenant_id: String,
110 #[serde(skip_serializing_if = "Option::is_none")]
111 pub code_artifact: Option<CodeArtifact>,
112}
113
114#[derive(Debug, Serialize, Deserialize, Clone, Default)]
115pub struct TokenUsage {
116 pub prompt_tokens: usize,
117 pub completion_tokens: usize,
118 pub total_tokens: usize,
119}
120
121#[derive(Debug, Clone)]
122pub struct AuditRequest {
123 pub context_id: String,
124 pub response_summary: String,
125 pub provider: String,
126 pub model: String,
127 pub token_usage: TokenUsage,
128 pub latency_ms: i64,
129 pub metadata: Option<HashMap<String, serde_json::Value>>,
130}
131
132#[derive(Debug, Serialize, Deserialize, Clone, Default)]
133#[serde(default)]
134pub struct AuditResult {
135 pub success: bool,
136 pub audit_id: String,
137}
138
139#[derive(Debug, Serialize, Deserialize, Clone, Default)]
140#[serde(default)]
141pub struct ConnectorMetadata {
142 pub id: String,
143 pub name: String,
144 #[serde(rename = "type")]
145 pub r#type: String,
146 pub version: String,
147 pub description: String,
148 pub category: String,
149 pub icon: String,
150 #[serde(deserialize_with = "null_to_default")]
151 pub tags: Vec<String>,
152 #[serde(deserialize_with = "null_to_default")]
153 pub capabilities: Vec<String>,
154 #[serde(deserialize_with = "null_to_default")]
155 pub config_schema: HashMap<String, serde_json::Value>,
156 pub installed: bool,
157 #[serde(skip_serializing_if = "Option::is_none")]
158 pub instance_name: Option<String>,
159 #[serde(skip_serializing_if = "Option::is_none")]
160 pub healthy: Option<bool>,
161 #[serde(skip_serializing_if = "Option::is_none")]
162 pub last_check: Option<String>,
163}
164
165#[derive(Debug, Serialize, Deserialize, Clone, Default)]
166#[serde(default)]
167pub struct ConnectorHealthStatus {
168 pub healthy: bool,
169 pub latency: i64,
170 #[serde(deserialize_with = "null_to_default")]
171 pub details: HashMap<String, String>,
172 pub timestamp: String,
173 #[serde(skip_serializing_if = "Option::is_none")]
174 pub error: Option<String>,
175}
176
177#[derive(Debug, Serialize, Deserialize, Clone)]
178pub struct ConnectorInstallRequest {
179 pub connector_id: String,
180 pub name: String,
181 pub tenant_id: String,
182 pub options: HashMap<String, serde_json::Value>,
183 pub credentials: HashMap<String, String>,
184}
185
186#[must_use]
187#[derive(Debug, Serialize, Deserialize, Clone)]
188pub struct ConnectorResponse {
189 pub success: bool,
190 pub data: serde_json::Value,
191 #[serde(skip_serializing_if = "Option::is_none")]
192 pub error: Option<String>,
193 #[serde(skip_serializing_if = "Option::is_none")]
194 pub meta: Option<HashMap<String, serde_json::Value>>,
195 #[serde(default)]
196 pub redacted: bool,
197 #[serde(default, deserialize_with = "null_to_default")]
198 pub redacted_fields: Vec<String>,
199 #[serde(skip_serializing_if = "Option::is_none")]
200 pub policy_info: Option<PolicyInfo>,
201}
202
203#[derive(Debug, Serialize, Deserialize, Clone)]
204pub struct PolicyInfo {
205 pub policies_evaluated: usize,
206 pub blocked: bool,
207 #[serde(skip_serializing_if = "Option::is_none")]
208 pub block_reason: Option<String>,
209 pub redactions_applied: usize,
210 pub processing_time_ms: i64,
211 #[serde(default, deserialize_with = "null_to_default")]
212 pub matched_policies: Vec<PolicyMatchInfo>,
213}
214
215#[derive(Debug, Serialize, Deserialize, Clone)]
216pub struct PolicyMatchInfo {
217 pub policy_id: String,
218 pub policy_name: String,
219 pub category: String,
220 pub severity: String,
221 pub action: String,
222}
223
224#[derive(Debug, Serialize, Deserialize, Clone, Default)]
225pub struct PlanStep {
226 #[serde(default)]
227 pub id: String,
228 #[serde(default)]
229 pub name: String,
230 #[serde(default, rename = "type")]
231 pub r#type: String,
232 #[serde(default)]
233 pub description: String,
234 #[serde(default, deserialize_with = "null_to_default")]
235 pub dependencies: Vec<String>,
236 #[serde(default)]
237 pub agent: String,
238 #[serde(default, deserialize_with = "null_to_default")]
239 pub parameters: HashMap<String, serde_json::Value>,
240 #[serde(default)]
241 pub estimated_time: String,
242}
243
244#[must_use]
245#[derive(Debug, Serialize, Deserialize, Clone, Default)]
246#[serde(default)]
247pub struct PlanResponse {
248 pub plan_id: String,
249 pub status: String,
250 #[serde(deserialize_with = "null_to_default")]
251 pub steps: Vec<PlanStep>,
252 pub domain: String,
253 pub complexity: i32,
254 pub parallel: bool,
255 pub estimated_duration: String,
256 #[serde(deserialize_with = "null_to_default")]
257 pub metadata: HashMap<String, serde_json::Value>,
258 pub success: bool,
259 pub version: i32,
260 #[serde(skip_serializing_if = "Option::is_none")]
261 pub result: Option<serde_json::Value>,
262 #[serde(skip_serializing_if = "Option::is_none")]
263 pub error: Option<String>,
264}
265
266#[derive(Debug, Serialize, Deserialize, Clone, Default)]
267#[serde(default)]
268pub struct StepResult {
269 pub step_id: String,
270 pub step_name: String,
271 pub status: String,
272 #[serde(skip_serializing_if = "Option::is_none")]
273 pub result: Option<serde_json::Value>,
274 #[serde(skip_serializing_if = "Option::is_none")]
275 pub error: Option<String>,
276 pub duration: String,
277}
278
279#[must_use]
280#[derive(Debug, Serialize, Deserialize, Clone, Default)]
281#[serde(default)]
282pub struct PlanExecutionResponse {
283 pub plan_id: String,
284 pub status: String,
285 #[serde(skip_serializing_if = "Option::is_none")]
286 pub workflow_id: Option<String>,
287 #[serde(skip_serializing_if = "Option::is_none")]
288 pub result: Option<String>,
289 #[serde(deserialize_with = "null_to_default")]
290 pub step_results: Vec<StepResult>,
291 #[serde(skip_serializing_if = "Option::is_none")]
292 pub error: Option<String>,
293 pub duration: String,
294 pub completed_steps: i32,
295 pub total_steps: i32,
296}
297
298#[derive(Debug, Serialize, Deserialize, Clone, Default)]
299#[serde(default)]
300pub struct CancelPlanResponse {
301 pub plan_id: String,
302 pub status: String,
303 pub success: bool,
304}
305
306#[derive(Debug, Serialize, Deserialize, Clone)]
307pub struct CodeArtifact {
308 pub is_code_output: bool,
309 pub language: String,
310 pub code_type: String,
311 pub size_bytes: usize,
312 pub line_count: usize,
313 pub secrets_detected: usize,
314 pub unsafe_patterns: usize,
315 #[serde(default, deserialize_with = "null_to_default")]
316 pub policies_checked: Vec<String>,
317}