Skip to main content

systemprompt_agent/services/shared/
config.rs

1//! Runtime configuration for agent services: connection, runtime, and service
2//! settings, plus a builder and validation for assembling them.
3
4use crate::services::shared::error::{AgentServiceError, Result};
5use serde::{Deserialize, Serialize};
6use std::time::Duration;
7use systemprompt_identifiers::AgentId;
8
9#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
10pub struct ServiceConfiguration {
11    pub enabled: bool,
12    pub timeout_seconds: u64,
13    pub retry_attempts: u32,
14    pub retry_delay_milliseconds: u64,
15    pub max_connections: usize,
16}
17
18impl ServiceConfiguration {
19    pub const fn timeout(&self) -> Duration {
20        Duration::from_secs(self.timeout_seconds)
21    }
22
23    pub const fn retry_delay(&self) -> Duration {
24        Duration::from_millis(self.retry_delay_milliseconds)
25    }
26
27    pub fn validate(&self) -> Result<()> {
28        if self.retry_attempts == 0 {
29            return Err(AgentServiceError::Configuration(
30                "ServiceConfiguration".to_owned(),
31                "retry_attempts must be at least 1".to_owned(),
32            ));
33        }
34        if self.max_connections == 0 {
35            return Err(AgentServiceError::Configuration(
36                "ServiceConfiguration".to_owned(),
37                "max_connections must be at least 1".to_owned(),
38            ));
39        }
40        Ok(())
41    }
42}
43
44impl Default for ServiceConfiguration {
45    fn default() -> Self {
46        Self {
47            enabled: true,
48            timeout_seconds: 30,
49            retry_attempts: 3,
50            retry_delay_milliseconds: 500,
51            max_connections: 10,
52        }
53    }
54}
55
56#[derive(Debug, Clone, Serialize, Deserialize)]
57pub struct RuntimeConfiguration {
58    pub agent_id: AgentId,
59    pub name: String,
60    pub port: u16,
61    pub host: String,
62    pub ssl_enabled: bool,
63    pub auth_required: bool,
64    pub system_prompt: Option<String>,
65}
66
67#[derive(Debug, Clone)]
68pub struct RuntimeConfigurationBuilder {
69    agent_id: AgentId,
70    name: String,
71    port: u16,
72    host: String,
73    ssl_enabled: bool,
74    auth_required: bool,
75    system_prompt: Option<String>,
76}
77
78impl RuntimeConfigurationBuilder {
79    pub fn new(agent_id: AgentId, name: String) -> Self {
80        Self {
81            agent_id,
82            name,
83            port: 8080,
84            host: "localhost".to_owned(),
85            ssl_enabled: false,
86            auth_required: false,
87            system_prompt: None,
88        }
89    }
90
91    pub const fn port(mut self, port: u16) -> Self {
92        self.port = port;
93        self
94    }
95
96    pub fn host(mut self, host: String) -> Self {
97        self.host = host;
98        self
99    }
100
101    pub const fn enable_ssl(mut self) -> Self {
102        self.ssl_enabled = true;
103        self
104    }
105
106    pub const fn require_auth(mut self) -> Self {
107        self.auth_required = true;
108        self
109    }
110
111    pub fn system_prompt(mut self, prompt: String) -> Self {
112        self.system_prompt = Some(prompt);
113        self
114    }
115
116    pub fn build(self) -> RuntimeConfiguration {
117        RuntimeConfiguration {
118            agent_id: self.agent_id,
119            name: self.name,
120            port: self.port,
121            host: self.host,
122            ssl_enabled: self.ssl_enabled,
123            auth_required: self.auth_required,
124            system_prompt: self.system_prompt,
125        }
126    }
127}
128
129#[derive(Debug, Clone, Serialize, Deserialize)]
130pub struct ConnectionConfiguration {
131    pub url: String,
132    pub timeout_seconds: u64,
133    pub keepalive_enabled: bool,
134    pub pool_size: usize,
135}
136
137impl ConnectionConfiguration {
138    pub const fn timeout(&self) -> Duration {
139        Duration::from_secs(self.timeout_seconds)
140    }
141}
142
143#[derive(Debug, Clone, Serialize, Deserialize)]
144pub struct AgentServiceConfig {
145    pub agent_id: AgentId,
146    pub name: String,
147    pub description: String,
148    pub version: String,
149    pub endpoint: String,
150    pub port: u16,
151    pub is_active: bool,
152}
153
154impl AgentServiceConfig {
155    pub fn validate(&self) -> Result<()> {
156        if self.agent_id.as_str().is_empty() {
157            return Err(AgentServiceError::Validation(
158                "agent_id".to_owned(),
159                "cannot be empty".to_owned(),
160            ));
161        }
162        if self.port == 0 {
163            return Err(AgentServiceError::Validation(
164                "port".to_owned(),
165                "must be greater than 0".to_owned(),
166            ));
167        }
168        if self.name.is_empty() {
169            return Err(AgentServiceError::Validation(
170                "name".to_owned(),
171                "cannot be empty".to_owned(),
172            ));
173        }
174        Ok(())
175    }
176}
177
178impl Default for AgentServiceConfig {
179    fn default() -> Self {
180        Self {
181            agent_id: AgentId::generate(),
182            name: "Default Agent".to_owned(),
183            description: "Default agent instance".to_owned(),
184            version: "0.1.0".to_owned(),
185            endpoint: "http://localhost:8080".to_owned(),
186            port: 8080,
187            is_active: true,
188        }
189    }
190}