ares/types/mod.rs
1//! Core types used throughout the A.R.E.S server.
2//!
3//! This module contains all the common data structures used for:
4//! - API requests and responses
5//! - Agent configuration and context
6//! - Memory and user preferences
7//! - Tool definitions and calls
8//! - RAG (Retrieval Augmented Generation)
9//! - Authentication
10//! - Error handling
11
12use chrono::{DateTime, Utc};
13use serde::{Deserialize, Serialize};
14use utoipa::ToSchema;
15
16/// Default datetime for serde deserialization
17fn default_datetime() -> DateTime<Utc> {
18 Utc::now()
19}
20
21// ============= API Request/Response Types =============
22
23/// Request payload for chat endpoints.
24#[derive(Debug, Serialize, Deserialize, ToSchema)]
25pub struct ChatRequest {
26 /// The user's message to send to the agent.
27 pub message: String,
28 /// Optional agent type to handle the request. Defaults to router.
29 #[serde(skip_serializing_if = "Option::is_none")]
30 pub agent_type: Option<AgentType>,
31 /// Optional context ID for conversation continuity.
32 #[serde(skip_serializing_if = "Option::is_none")]
33 pub context_id: Option<String>,
34}
35
36/// Response from chat endpoints.
37#[derive(Debug, Serialize, Deserialize, ToSchema)]
38pub struct ChatResponse {
39 /// The agent's response text.
40 pub response: String,
41 /// The name of the agent that handled the request.
42 pub agent: String,
43 /// Context ID for continuing this conversation.
44 pub context_id: String,
45 /// Optional sources used to generate the response.
46 pub sources: Option<Vec<Source>>,
47}
48
49/// A source reference used in responses.
50#[derive(Debug, Serialize, Deserialize, ToSchema, Clone)]
51pub struct Source {
52 /// Title of the source document or webpage.
53 pub title: String,
54 /// URL of the source, if available.
55 pub url: Option<String>,
56 /// Relevance score (0.0 to 1.0) indicating how relevant this source is.
57 pub relevance_score: f32,
58}
59
60/// Request payload for deep research endpoints.
61#[derive(Debug, Serialize, Deserialize, ToSchema)]
62pub struct ResearchRequest {
63 /// The research query or question.
64 pub query: String,
65 /// Optional maximum depth for recursive research (default: 3).
66 pub depth: Option<u8>,
67 /// Optional maximum iterations across all agents (default: 10).
68 pub max_iterations: Option<u8>,
69}
70
71/// Response from deep research endpoints.
72#[derive(Debug, Serialize, Deserialize, ToSchema)]
73pub struct ResearchResponse {
74 /// The compiled research findings.
75 pub findings: String,
76 /// Sources discovered during research.
77 pub sources: Vec<Source>,
78 /// Time taken for the research in milliseconds.
79 pub duration_ms: u64,
80}
81
82// ============= RAG API Types =============
83
84/// Request to ingest a document into the RAG system.
85#[derive(Debug, Serialize, Deserialize, ToSchema)]
86pub struct RagIngestRequest {
87 /// Collection name to ingest into.
88 pub collection: String,
89 /// The text content to ingest.
90 pub content: String,
91 /// Optional document title.
92 pub title: Option<String>,
93 /// Optional source URL or path.
94 pub source: Option<String>,
95 /// Optional tags for categorization.
96 #[serde(default)]
97 pub tags: Vec<String>,
98 /// Chunking strategy to use.
99 #[serde(default)]
100 pub chunking_strategy: Option<String>,
101}
102
103/// Response from document ingestion.
104#[derive(Debug, Serialize, Deserialize, ToSchema)]
105pub struct RagIngestResponse {
106 /// Number of chunks created.
107 pub chunks_created: usize,
108 /// Document IDs created.
109 pub document_ids: Vec<String>,
110 /// Collection name.
111 pub collection: String,
112}
113
114/// Request to search the RAG system.
115#[derive(Debug, Serialize, Deserialize, ToSchema)]
116pub struct RagSearchRequest {
117 /// Collection to search.
118 pub collection: String,
119 /// The search query.
120 pub query: String,
121 /// Maximum results to return (default: 10).
122 #[serde(default = "default_search_limit")]
123 pub limit: usize,
124 /// Search strategy to use: semantic, bm25, fuzzy, hybrid.
125 #[serde(default)]
126 pub strategy: Option<String>,
127 /// Minimum similarity threshold (0.0 to 1.0).
128 #[serde(default = "default_search_threshold")]
129 pub threshold: f32,
130 /// Whether to enable reranking.
131 #[serde(default)]
132 pub rerank: bool,
133 /// Reranker model to use if reranking.
134 #[serde(default)]
135 pub reranker_model: Option<String>,
136}
137
138fn default_search_limit() -> usize {
139 10
140}
141
142fn default_search_threshold() -> f32 {
143 0.0
144}
145
146/// Single search result.
147#[derive(Debug, Serialize, Deserialize, ToSchema)]
148pub struct RagSearchResult {
149 /// Document ID.
150 pub id: String,
151 /// Matching text content.
152 pub content: String,
153 /// Relevance score.
154 pub score: f32,
155 /// Document metadata.
156 pub metadata: DocumentMetadata,
157}
158
159/// Response from RAG search.
160#[derive(Debug, Serialize, Deserialize, ToSchema)]
161pub struct RagSearchResponse {
162 /// Search results.
163 pub results: Vec<RagSearchResult>,
164 /// Total number of results before limit.
165 pub total: usize,
166 /// Search strategy used.
167 pub strategy: String,
168 /// Whether reranking was applied.
169 pub reranked: bool,
170 /// Query processing time in milliseconds.
171 pub duration_ms: u64,
172}
173
174/// Request to delete a collection.
175#[derive(Debug, Serialize, Deserialize, ToSchema)]
176pub struct RagDeleteCollectionRequest {
177 /// Collection name to delete.
178 pub collection: String,
179}
180
181/// Response from collection deletion.
182#[derive(Debug, Serialize, Deserialize, ToSchema)]
183pub struct RagDeleteCollectionResponse {
184 /// Whether deletion was successful.
185 pub success: bool,
186 /// Collection that was deleted.
187 pub collection: String,
188 /// Number of documents deleted.
189 pub documents_deleted: usize,
190}
191
192// ============= Workflow Types =============
193
194/// Request payload for workflow execution endpoints.
195#[derive(Debug, Serialize, Deserialize, ToSchema)]
196pub struct WorkflowRequest {
197 /// The query to process through the workflow.
198 pub query: String,
199 /// Additional context data as key-value pairs.
200 #[serde(default)]
201 pub context: std::collections::HashMap<String, serde_json::Value>,
202}
203
204// ============= Agent Types =============
205
206/// Available agent types in the system.
207#[derive(Debug, Serialize, Deserialize, ToSchema, Clone, Copy, PartialEq, Eq)]
208#[serde(rename_all = "lowercase")]
209pub enum AgentType {
210 /// Routes requests to appropriate specialized agents.
211 Router,
212 /// Orchestrates complex multi-step tasks.
213 Orchestrator,
214 /// Handles product-related queries.
215 Product,
216 /// Handles invoice and billing queries.
217 Invoice,
218 /// Handles sales-related queries.
219 Sales,
220 /// Handles financial queries and analysis.
221 Finance,
222 /// Handles HR and employee-related queries.
223 HR,
224}
225
226/// Context passed to agents during request processing.
227#[derive(Debug, Clone)]
228pub struct AgentContext {
229 /// Unique identifier for the user making the request.
230 pub user_id: String,
231 /// Session identifier for conversation tracking.
232 pub session_id: String,
233 /// Previous messages in the conversation.
234 pub conversation_history: Vec<Message>,
235 /// User's stored memory and preferences.
236 pub user_memory: Option<UserMemory>,
237}
238
239/// A single message in a conversation.
240#[derive(Debug, Clone, Serialize, Deserialize)]
241pub struct Message {
242 /// The role of the message sender.
243 pub role: MessageRole,
244 /// The message content.
245 pub content: String,
246 /// When the message was sent.
247 pub timestamp: DateTime<Utc>,
248}
249
250/// Role of a message sender in a conversation.
251#[derive(Debug, Clone, Serialize, Deserialize)]
252#[serde(rename_all = "lowercase")]
253pub enum MessageRole {
254 /// System instructions to the model.
255 System,
256 /// Message from the user.
257 User,
258 /// Response from the assistant/agent.
259 Assistant,
260}
261
262// ============= Memory Types =============
263
264/// User memory containing preferences and learned facts.
265#[derive(Debug, Clone, Serialize, Deserialize)]
266pub struct UserMemory {
267 /// The user's unique identifier.
268 pub user_id: String,
269 /// List of user preferences.
270 pub preferences: Vec<Preference>,
271 /// List of facts learned about the user.
272 pub facts: Vec<MemoryFact>,
273}
274
275/// A user preference entry.
276#[derive(Debug, Clone, Serialize, Deserialize)]
277pub struct Preference {
278 /// Category of the preference (e.g., "communication", "output").
279 pub category: String,
280 /// Key identifying the specific preference.
281 pub key: String,
282 /// The preference value.
283 pub value: String,
284 /// Confidence score (0.0 to 1.0) for this preference.
285 pub confidence: f32,
286}
287
288/// A fact learned about a user.
289#[derive(Debug, Clone, Serialize, Deserialize)]
290pub struct MemoryFact {
291 /// Unique identifier for this fact.
292 pub id: String,
293 /// The user this fact belongs to.
294 pub user_id: String,
295 /// Category of the fact (e.g., "personal", "work").
296 pub category: String,
297 /// Key identifying the specific fact.
298 pub fact_key: String,
299 /// The fact value.
300 pub fact_value: String,
301 /// Confidence score (0.0 to 1.0) for this fact.
302 pub confidence: f32,
303 /// When this fact was first recorded.
304 pub created_at: DateTime<Utc>,
305 /// When this fact was last updated.
306 pub updated_at: DateTime<Utc>,
307}
308
309// ============= Tool Types =============
310
311/// Definition of a tool that can be called by an LLM.
312#[derive(Debug, Serialize, Deserialize, Clone)]
313pub struct ToolDefinition {
314 /// Unique name of the tool.
315 pub name: String,
316 /// Human-readable description of what the tool does.
317 pub description: String,
318 /// JSON Schema defining the tool's parameters.
319 pub parameters: serde_json::Value,
320}
321
322/// A request to call a tool.
323#[derive(Debug, Serialize, Deserialize, Clone)]
324pub struct ToolCall {
325 /// Unique identifier for this tool call.
326 pub id: String,
327 /// Name of the tool to call.
328 pub name: String,
329 /// Arguments to pass to the tool.
330 pub arguments: serde_json::Value,
331}
332
333/// Result from executing a tool.
334#[derive(Debug, Serialize, Deserialize)]
335pub struct ToolResult {
336 /// ID of the tool call this result corresponds to.
337 pub tool_call_id: String,
338 /// The result data from the tool execution.
339 pub result: serde_json::Value,
340}
341
342// ============= RAG Types =============
343
344/// A document in the RAG knowledge base.
345#[derive(Debug, Clone, Serialize, Deserialize)]
346pub struct Document {
347 /// Unique identifier for the document.
348 pub id: String,
349 /// The document's text content.
350 pub content: String,
351 /// Metadata about the document.
352 pub metadata: DocumentMetadata,
353 /// Optional embedding vector for semantic search.
354 pub embedding: Option<Vec<f32>>,
355}
356
357/// Metadata associated with a document.
358#[derive(Debug, Clone, Default, Serialize, Deserialize, ToSchema)]
359pub struct DocumentMetadata {
360 /// Title of the document.
361 #[serde(default)]
362 pub title: String,
363 /// Source of the document (e.g., URL, file path).
364 #[serde(default)]
365 pub source: String,
366 /// When the document was created or ingested.
367 #[serde(default = "default_datetime")]
368 pub created_at: DateTime<Utc>,
369 /// Tags for categorization and filtering.
370 #[serde(default)]
371 pub tags: Vec<String>,
372}
373
374/// Query parameters for semantic search.
375#[derive(Debug, Clone)]
376pub struct SearchQuery {
377 /// The search query text.
378 pub query: String,
379 /// Maximum number of results to return.
380 pub limit: usize,
381 /// Minimum similarity threshold (0.0 to 1.0).
382 pub threshold: f32,
383 /// Optional filters to apply to results.
384 pub filters: Option<Vec<SearchFilter>>,
385}
386
387/// A filter to apply during search.
388#[derive(Debug, Clone)]
389pub struct SearchFilter {
390 /// Field name to filter on.
391 pub field: String,
392 /// Value to filter by.
393 pub value: String,
394}
395
396/// A single search result with relevance score.
397#[derive(Debug, Clone)]
398pub struct SearchResult {
399 /// The matching document.
400 pub document: Document,
401 /// Similarity score (0.0 to 1.0).
402 pub score: f32,
403}
404
405// ============= Authentication Types =============
406
407/// Request payload for user login.
408#[derive(Debug, Serialize, Deserialize, ToSchema)]
409pub struct LoginRequest {
410 /// User's email address.
411 pub email: String,
412 /// User's password.
413 pub password: String,
414}
415
416/// Request payload for user registration.
417#[derive(Debug, Serialize, Deserialize, ToSchema)]
418pub struct RegisterRequest {
419 /// Email address for the new account.
420 pub email: String,
421 /// Password for the new account.
422 pub password: String,
423 /// Display name for the user.
424 pub name: String,
425}
426
427/// Response containing authentication tokens.
428#[derive(Debug, Serialize, Deserialize, ToSchema)]
429pub struct TokenResponse {
430 /// JWT access token for API authentication.
431 pub access_token: String,
432 /// Refresh token for obtaining new access tokens.
433 pub refresh_token: String,
434 /// Time in seconds until the access token expires.
435 pub expires_in: i64,
436}
437
438/// JWT claims embedded in access tokens.
439#[derive(Debug, Serialize, Deserialize, Clone)]
440pub struct Claims {
441 /// Subject (user ID).
442 pub sub: String,
443 /// User's email address.
444 pub email: String,
445 /// Expiration time (Unix timestamp).
446 pub exp: usize,
447 /// Issued at time (Unix timestamp).
448 pub iat: usize,
449}
450
451// ============= Error Types =============
452
453/// Application-wide error type.
454#[derive(Debug, thiserror::Error)]
455pub enum AppError {
456 /// Database operation failed.
457 #[error("Database error: {0}")]
458 Database(String),
459
460 /// LLM operation failed.
461 #[error("LLM error: {0}")]
462 LLM(String),
463
464 /// Authentication or authorization failed.
465 #[error("Authentication error: {0}")]
466 Auth(String),
467
468 /// Requested resource was not found.
469 #[error("Not found: {0}")]
470 NotFound(String),
471
472 /// Input validation failed.
473 #[error("Invalid input: {0}")]
474 InvalidInput(String),
475
476 /// Configuration error.
477 #[error("Configuration error: {0}")]
478 Configuration(String),
479
480 /// External service call failed.
481 #[error("External service error: {0}")]
482 External(String),
483
484 /// Internal server error.
485 #[error("Internal error: {0}")]
486 Internal(String),
487}
488
489impl axum::response::IntoResponse for AppError {
490 fn into_response(self) -> axum::response::Response {
491 let (status, message) = match self {
492 AppError::Database(msg) => (axum::http::StatusCode::INTERNAL_SERVER_ERROR, msg),
493 AppError::LLM(msg) => (axum::http::StatusCode::INTERNAL_SERVER_ERROR, msg),
494 AppError::Auth(msg) => (axum::http::StatusCode::UNAUTHORIZED, msg),
495 AppError::NotFound(msg) => (axum::http::StatusCode::NOT_FOUND, msg),
496 AppError::InvalidInput(msg) => (axum::http::StatusCode::BAD_REQUEST, msg),
497 AppError::Configuration(msg) => (axum::http::StatusCode::INTERNAL_SERVER_ERROR, msg),
498 AppError::External(msg) => (axum::http::StatusCode::BAD_GATEWAY, msg),
499 AppError::Internal(msg) => (axum::http::StatusCode::INTERNAL_SERVER_ERROR, msg),
500 };
501
502 let body = serde_json::json!({
503 "error": message
504 });
505
506 (status, axum::Json(body)).into_response()
507 }
508}
509
510/// A specialized Result type for A.R.E.S operations.
511pub type Result<T> = std::result::Result<T, AppError>;