1use std::sync::Arc;
4use std::time::Duration;
5
6use rskit_hook::HookRegistry;
7use rskit_resilience::Policy;
8use rskit_tool::Registry;
9
10use crate::types::ContextStrategy;
11
12pub struct AgentConfig {
14 pub tools: Option<Arc<Registry>>,
16 pub hooks: Option<Arc<HookRegistry>>,
18 pub system_prompt: String,
20 pub max_turns: u32,
22 pub max_tokens: usize,
24 pub wall_clock: Duration,
26 pub max_tool_calls: u32,
28 pub tool_concurrency: usize,
30 pub tool_timeout: Duration,
32 pub policy: Option<Policy>,
34 pub context_strategy: Option<Box<dyn ContextStrategy>>,
36 pub model: String,
38}
39
40impl AgentConfig {
41 #[must_use]
43 pub fn budget(&self) -> rskit_ai::Budget {
44 rskit_ai::Budget {
45 max_tokens: Some(self.max_tokens as u64),
46 max_calls: Some(u64::from(self.max_tool_calls)),
47 max_cost: None,
48 wall_clock: Some(self.wall_clock.as_secs()),
49 }
50 }
51}
52
53impl Default for AgentConfig {
54 fn default() -> Self {
55 Self {
56 tools: None,
57 hooks: None,
58 system_prompt: String::new(),
59 max_turns: 10,
60 max_tokens: 100_000,
61 wall_clock: Duration::from_mins(1),
62 max_tool_calls: 50,
63 tool_concurrency: 4,
64 tool_timeout: Duration::from_secs(30),
65 policy: None,
66 context_strategy: None,
67 model: String::new(),
68 }
69 }
70}
71
72#[cfg(test)]
73mod tests {
74 use super::*;
75
76 #[test]
77 fn budget_maps_config_limits_to_shared_genai_vocabulary() {
78 let config = AgentConfig {
79 max_tokens: 4_096,
80 max_tool_calls: 7,
81 wall_clock: Duration::from_secs(45),
82 ..AgentConfig::default()
83 };
84
85 let budget = config.budget();
86
87 assert_eq!(budget.max_tokens, Some(4_096));
88 assert_eq!(budget.max_calls, Some(7));
89 assert_eq!(budget.wall_clock, Some(45));
90 assert_eq!(budget.max_cost, None);
92 }
93}