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>;