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 {
11 id: String,
12
13 name: Option<String>,
14
15 running: bool,
16
17 spec: PresetSpec,
18}
19
20impl Preset {
21 pub fn new(mut spec: PresetSpec) -> Self {
25 let (agents, connections) = update_ids(&spec.agents, &spec.connections);
26 spec.agents = agents;
27 spec.connections = connections;
28
29 Self {
30 id: new_id(),
31 name: None,
32 running: false,
33 spec,
34 }
35 }
36
37 pub fn id(&self) -> &str {
38 &self.id
39 }
40
41 pub fn spec(&self) -> &PresetSpec {
42 &self.spec
43 }
44
45 pub fn update_spec(&mut self, value: &Value) -> Result<(), AgentError> {
46 let update_map = value
47 .as_object()
48 .ok_or_else(|| AgentError::SerializationError("Expected JSON object".to_string()))?;
49
50 for (k, v) in update_map {
51 match k.as_str() {
52 "agents" => {
53 }
55 "connections" => {
56 }
58 _ => {
59 self.spec.extensions.insert(k.clone(), v.clone());
61 }
62 }
63 }
64 Ok(())
65 }
66
67 pub fn running(&self) -> bool {
68 self.running
69 }
70
71 pub fn name(&self) -> Option<&str> {
72 self.name.as_deref()
73 }
74
75 pub fn set_name(&mut self, name: String) {
76 self.name = Some(name);
77 }
78
79 pub fn clear_name(&mut self) {
80 self.name = None;
81 }
82
83 pub fn add_agent(&mut self, agent: AgentSpec) {
84 self.spec.add_agent(agent);
85 }
86
87 pub fn remove_agent(&mut self, agent_id: &str) {
88 self.spec.remove_agent(agent_id);
89 }
90
91 pub fn add_connection(&mut self, connection: ConnectionSpec) {
92 self.spec.add_connection(connection);
93 }
94
95 pub fn remove_connection(&mut self, connection: &ConnectionSpec) -> Option<ConnectionSpec> {
96 self.spec.remove_connection(connection)
97 }
98
99 pub async fn start(&mut self, ma: &ModularAgent) -> Result<(), AgentError> {
100 if self.running {
101 return Ok(());
103 }
104 self.running = true;
105
106 for agent in self.spec.agents.iter() {
107 if agent.disabled {
108 continue;
109 }
110 ma.start_agent(&agent.id).await.unwrap_or_else(|e| {
111 log::error!("Failed to start agent {}: {}", agent.id, e);
112 });
113 }
114
115 Ok(())
116 }
117
118 pub async fn stop(&mut self, ma: &ModularAgent) -> Result<(), AgentError> {
119 for agent in self.spec.agents.iter() {
120 ma.stop_agent(&agent.id).await.unwrap_or_else(|e| {
121 log::error!("Failed to stop agent {}: {}", agent.id, e);
122 });
123 }
124 self.running = false;
125 Ok(())
126 }
127}
128
129#[derive(Clone, Debug, Serialize, Deserialize)]
130pub struct PresetInfo {
131 pub id: String,
132 pub name: Option<String>,
133 pub running: bool,
134}
135
136impl From<&Preset> for PresetInfo {
137 fn from(preset: &Preset) -> Self {
138 Self {
139 id: preset.id.clone(),
140 name: preset.name.clone(),
141 running: preset.running,
142 }
143 }
144}