modular_agent_core/
preset.rs1use serde::{Deserialize, Serialize};
2use serde_json::Value;
3
4use crate::error::AgentError;
5use crate::id::{new_id, update_ids};
6use crate::modular_agent::ModularAgent;
7use crate::spec::PresetSpec;
8use crate::{AgentSpec, ConnectionSpec};
9
10pub struct Preset {
16 id: String,
18
19 name: Option<String>,
21
22 running: bool,
24
25 spec: PresetSpec,
27}
28
29impl Preset {
30 pub fn new(mut spec: PresetSpec) -> Self {
34 let (agents, connections) = update_ids(&spec.agents, &spec.connections);
35 spec.agents = agents;
36 spec.connections = connections;
37
38 Self {
39 id: new_id(),
40 name: None,
41 running: false,
42 spec,
43 }
44 }
45
46 pub fn id(&self) -> &str {
48 &self.id
49 }
50
51 pub fn spec(&self) -> &PresetSpec {
53 &self.spec
54 }
55
56 pub fn update_spec(&mut self, value: &Value) -> Result<(), AgentError> {
61 let update_map = value
62 .as_object()
63 .ok_or_else(|| AgentError::SerializationError("Expected JSON object".to_string()))?;
64
65 for (k, v) in update_map {
66 match k.as_str() {
67 "agents" => {
68 }
70 "connections" => {
71 }
73 _ => {
74 self.spec.extensions.insert(k.clone(), v.clone());
76 }
77 }
78 }
79 Ok(())
80 }
81
82 pub fn running(&self) -> bool {
84 self.running
85 }
86
87 pub fn name(&self) -> Option<&str> {
89 self.name.as_deref()
90 }
91
92 pub fn set_name(&mut self, name: String) {
94 self.name = Some(name);
95 }
96
97 pub fn clear_name(&mut self) {
99 self.name = None;
100 }
101
102 pub fn add_agent(&mut self, agent: AgentSpec) {
104 self.spec.add_agent(agent);
105 }
106
107 pub fn remove_agent(&mut self, agent_id: &str) {
109 self.spec.remove_agent(agent_id);
110 }
111
112 pub fn add_connection(&mut self, connection: ConnectionSpec) {
114 self.spec.add_connection(connection);
115 }
116
117 pub fn remove_connection(&mut self, connection: &ConnectionSpec) -> Option<ConnectionSpec> {
119 self.spec.remove_connection(connection)
120 }
121
122 pub async fn start(&mut self, ma: &ModularAgent) -> Result<(), AgentError> {
127 if self.running {
128 return Ok(());
130 }
131 self.running = true;
132
133 for agent in self.spec.agents.iter() {
134 if agent.disabled {
135 continue;
136 }
137 ma.start_agent(&agent.id).await.unwrap_or_else(|e| {
138 log::error!("Failed to start agent {}: {}", agent.id, e);
139 });
140 }
141
142 Ok(())
143 }
144
145 pub async fn stop(&mut self, ma: &ModularAgent) -> Result<(), AgentError> {
147 for agent in self.spec.agents.iter() {
148 ma.stop_agent(&agent.id).await.unwrap_or_else(|e| {
149 log::error!("Failed to stop agent {}: {}", agent.id, e);
150 });
151 }
152 self.running = false;
153 Ok(())
154 }
155}
156
157#[derive(Clone, Debug, Serialize, Deserialize)]
162pub struct PresetInfo {
163 pub id: String,
165
166 pub name: Option<String>,
168
169 pub running: bool,
171}
172
173impl From<&Preset> for PresetInfo {
174 fn from(preset: &Preset) -> Self {
175 Self {
176 id: preset.id.clone(),
177 name: preset.name.clone(),
178 running: preset.running,
179 }
180 }
181}