Skip to main content

atomr_agents_agent/
spec.rs

1use std::sync::Arc;
2use std::time::Duration;
3
4use atomr_agents_core::{AgentId, IterationBudget, MoneyBudget, TimeBudget, TokenBudget};
5use atomr_agents_instruction::InstructionStrategy;
6use atomr_agents_observability::EventBus;
7use atomr_agents_strategy::{MemoryStrategy, SkillStrategy, ToolStrategy};
8use serde::{Deserialize, Serialize};
9
10use crate::boxed::BoxedAgent;
11use crate::inference::InferenceClient;
12use crate::r#trait::AgentRef;
13
14/// Static, serializable description of an agent. Used by the
15/// registry and Python config; [`AgentSpec::into_agent`]
16/// materializes a runnable [`AgentRef`]. Strategies and inference
17/// client are passed in (typically constructed from a registry
18/// lookup keyed off the spec's `id` / `model`).
19#[derive(Debug, Clone, Serialize, Deserialize)]
20pub struct AgentSpec {
21    pub id: AgentId,
22    pub model: String,
23    pub max_iterations: u32,
24    pub token_budget: u32,
25    pub time_budget_ms: u64,
26    pub money_budget_usd: f64,
27}
28
29impl AgentSpec {
30    pub fn default_budgets(&self) -> (TokenBudget, TimeBudget, MoneyBudget, IterationBudget) {
31        (
32            TokenBudget::new(self.token_budget),
33            TimeBudget::new(Duration::from_millis(self.time_budget_ms)),
34            MoneyBudget::from_usd(self.money_budget_usd),
35            IterationBudget::new(self.max_iterations),
36        )
37    }
38
39    /// Materialize a runnable [`AgentRef`] from this static spec
40    /// plus a set of object-erased strategies and an inference
41    /// client. Typically the strategies are constructed from a
42    /// registry lookup keyed off the spec's `id` / `model`.
43    pub fn into_agent(
44        self,
45        instructions: Box<dyn InstructionStrategy>,
46        tools: Box<dyn ToolStrategy>,
47        memory: Box<dyn MemoryStrategy>,
48        skills: Box<dyn SkillStrategy>,
49        inference: Arc<dyn InferenceClient>,
50    ) -> AgentRef {
51        let id = self.id.clone();
52        let boxed = BoxedAgent {
53            id: self.id,
54            model: self.model,
55            instructions,
56            tools,
57            memory,
58            skills,
59            inference,
60            bus: EventBus::new(),
61            max_tool_iterations: self.max_iterations,
62        };
63        AgentRef::new(id, Arc::new(boxed))
64    }
65}