systemprompt_cli/commands/infrastructure/services/restart/
batch.rs1use crate::cli_settings::CliConfig;
2use crate::shared::CommandOutput;
3use anyhow::{Context, Result};
4use std::sync::Arc;
5use systemprompt_agent::services::registry::AgentRegistry;
6use systemprompt_logging::CliService;
7use systemprompt_mcp::services::McpOrchestrator;
8use systemprompt_runtime::AppContext;
9
10use super::super::types::RestartOutput;
11
12pub async fn execute_all_agents(
13 ctx: &Arc<AppContext>,
14 config: &CliConfig,
15) -> Result<CommandOutput> {
16 let quiet = config.is_json_output();
17
18 if !quiet {
19 CliService::section("Restarting All Agents");
20 }
21
22 let orchestrator = super::create_orchestrator(ctx).await?;
23 let agent_registry = AgentRegistry::new()?;
24 let all_agents = orchestrator.list_all().await?;
25
26 let mut restarted = 0usize;
27 let mut failed = 0usize;
28
29 for (agent_id, _status) in &all_agents {
30 let Ok(agent_config) = agent_registry.get_agent(agent_id).await else {
31 continue;
32 };
33
34 if !agent_config.enabled {
35 continue;
36 }
37
38 if !quiet {
39 CliService::info(&format!("Restarting agent: {}", agent_config.name));
40 }
41 match orchestrator.restart_agent(agent_id, None).await {
42 Ok(_) => {
43 restarted += 1;
44 if !quiet {
45 CliService::success(&format!(" {} restarted", agent_config.name));
46 }
47 },
48 Err(e) => {
49 failed += 1;
50 if !quiet {
51 CliService::error(&format!(" Failed to restart {}: {}", agent_config.name, e));
52 }
53 },
54 }
55 }
56
57 let message = super::format_batch_message("agents", restarted, failed, quiet);
58
59 let output = RestartOutput {
60 service_type: "agents".to_owned(),
61 service_name: None,
62 restarted_count: restarted,
63 failed_count: failed,
64 message,
65 };
66
67 Ok(CommandOutput::card_value("Restart All Agents", &output))
68}
69
70pub async fn execute_all_mcp(ctx: &Arc<AppContext>, config: &CliConfig) -> Result<CommandOutput> {
71 let quiet = config.is_json_output();
72
73 if !quiet {
74 CliService::section("Restarting All MCP Servers");
75 }
76
77 let mcp_manager = McpOrchestrator::new(
78 Arc::clone(ctx.db_pool()),
79 Arc::clone(ctx.app_paths_arc()),
80 ctx.mcp_registry().clone(),
81 )
82 .context("Failed to initialize MCP manager")?;
83
84 ctx.mcp_registry().validate()?;
85 let servers = ctx.mcp_registry().get_enabled_servers()?;
86
87 let mut restarted = 0usize;
88 let mut failed = 0usize;
89
90 for server in servers {
91 if !server.enabled {
92 continue;
93 }
94
95 if !quiet {
96 CliService::info(&format!("Restarting MCP server: {}", server.name));
97 }
98 match mcp_manager
99 .restart_services(Some(server.name.clone()))
100 .await
101 {
102 Ok(()) => {
103 restarted += 1;
104 if !quiet {
105 CliService::success(&format!(" {} restarted", server.name));
106 }
107 },
108 Err(e) => {
109 failed += 1;
110 if !quiet {
111 CliService::error(&format!(" Failed to restart {}: {}", server.name, e));
112 }
113 },
114 }
115 }
116
117 let message = super::format_batch_message("MCP servers", restarted, failed, quiet);
118
119 let output = RestartOutput {
120 service_type: "mcp".to_owned(),
121 service_name: None,
122 restarted_count: restarted,
123 failed_count: failed,
124 message,
125 };
126
127 Ok(CommandOutput::card_value(
128 "Restart All MCP Servers",
129 &output,
130 ))
131}
132
133pub async fn execute_failed(ctx: &Arc<AppContext>, config: &CliConfig) -> Result<CommandOutput> {
134 let quiet = config.is_json_output();
135
136 if !quiet {
137 CliService::section("Restarting Failed Services");
138 }
139
140 let mut restarted_count = 0usize;
141 let mut failed_count = 0usize;
142
143 restart_failed_agents(ctx, &mut restarted_count, &mut failed_count, quiet).await?;
144 restart_failed_mcp(ctx, &mut restarted_count, &mut failed_count, quiet).await?;
145
146 let message = if restarted_count > 0 {
147 let msg = format!("Restarted {} failed services", restarted_count);
148 if !quiet {
149 CliService::success(&msg);
150 }
151 if failed_count > 0 && !quiet {
152 CliService::warning(&format!("Failed to restart {} services", failed_count));
153 }
154 if failed_count > 0 {
155 format!("{}, {} failed to restart", msg, failed_count)
156 } else {
157 msg
158 }
159 } else {
160 let msg = "No failed services found".to_owned();
161 if !quiet {
162 CliService::info(&msg);
163 }
164 msg
165 };
166
167 let output = RestartOutput {
168 service_type: "failed".to_owned(),
169 service_name: None,
170 restarted_count,
171 failed_count,
172 message,
173 };
174
175 Ok(CommandOutput::card_value(
176 "Restart Failed Services",
177 &output,
178 ))
179}
180
181async fn restart_failed_agents(
182 ctx: &Arc<AppContext>,
183 restarted_count: &mut usize,
184 failed_count: &mut usize,
185 quiet: bool,
186) -> Result<()> {
187 let orchestrator = super::create_orchestrator(ctx).await?;
188 let agent_registry = AgentRegistry::new()?;
189
190 let all_agents = orchestrator.list_all().await?;
191 for (agent_id, status) in &all_agents {
192 let Ok(agent_config) = agent_registry.get_agent(agent_id).await else {
193 continue;
194 };
195
196 if !agent_config.enabled {
197 continue;
198 }
199
200 if let systemprompt_agent::services::agent_orchestration::AgentStatus::Failed { .. } =
201 status
202 {
203 if !quiet {
204 CliService::info(&format!("Restarting failed agent: {}", agent_config.name));
205 }
206 match orchestrator.restart_agent(agent_id, None).await {
207 Ok(_) => {
208 *restarted_count += 1;
209 if !quiet {
210 CliService::success(&format!(" {} restarted", agent_config.name));
211 }
212 },
213 Err(e) => {
214 *failed_count += 1;
215 if !quiet {
216 CliService::error(&format!(
217 " Failed to restart {}: {}",
218 agent_config.name, e
219 ));
220 }
221 },
222 }
223 }
224 }
225
226 Ok(())
227}
228
229async fn restart_failed_mcp(
230 ctx: &Arc<AppContext>,
231 restarted_count: &mut usize,
232 failed_count: &mut usize,
233 quiet: bool,
234) -> Result<()> {
235 let mcp_manager = McpOrchestrator::new(
236 Arc::clone(ctx.db_pool()),
237 Arc::clone(ctx.app_paths_arc()),
238 ctx.mcp_registry().clone(),
239 )
240 .context("Failed to initialize MCP manager")?;
241
242 ctx.mcp_registry().validate()?;
243 let servers = ctx.mcp_registry().get_enabled_servers()?;
244
245 for server in servers {
246 if !server.enabled {
247 continue;
248 }
249
250 let database = systemprompt_mcp::services::DatabaseService::new(
251 Arc::clone(ctx.db_pool()),
252 Arc::clone(ctx.app_paths_arc()),
253 ctx.mcp_registry().clone(),
254 );
255 let service_info = database.get_service_by_name(&server.name).await?;
256
257 let needs_restart = match service_info {
258 Some(info) => info.status != "running",
259 None => true,
260 };
261
262 if needs_restart {
263 if !quiet {
264 CliService::info(&format!("Restarting MCP server: {}", server.name));
265 }
266 match mcp_manager
267 .restart_services(Some(server.name.clone()))
268 .await
269 {
270 Ok(()) => {
271 *restarted_count += 1;
272 if !quiet {
273 CliService::success(&format!(" {} restarted", server.name));
274 }
275 },
276 Err(e) => {
277 *failed_count += 1;
278 if !quiet {
279 CliService::error(&format!(" Failed to restart {}: {}", server.name, e));
280 }
281 },
282 }
283 }
284 }
285
286 Ok(())
287}