systemprompt_cli/commands/infrastructure/services/restart/
single.rs1use crate::cli_settings::CliConfig;
2use crate::interactive::Prompter;
3use crate::shared::CommandOutput;
4use anyhow::Result;
5use std::sync::Arc;
6use systemprompt_logging::CliService;
7use systemprompt_runtime::AppContext;
8use systemprompt_scheduler::ProcessCleanup;
9
10use super::super::lifecycle;
11use super::super::types::RestartOutput;
12
13pub async fn execute_api(prompter: &dyn Prompter, config: &CliConfig) -> Result<CommandOutput> {
14 let quiet = config.is_json_output();
15
16 if !quiet {
17 CliService::section("Restarting API Server");
18 }
19
20 let port = super::get_api_port();
21 let Some(pid) = ProcessCleanup::check_port(port) else {
22 if !quiet {
23 CliService::warning("API server is not running");
24 CliService::info("Starting API server...");
25 }
26 super::super::serve::execute(prompter, true, false, config).await?;
27 let output = RestartOutput {
28 service_type: "api".to_owned(),
29 service_name: None,
30 restarted_count: 1,
31 failed_count: 0,
32 message: "API server started (was not running)".to_owned(),
33 };
34 return Ok(CommandOutput::card_value("Restart API Server", &output));
35 };
36
37 if !quiet {
38 CliService::info(&format!("Stopping API server (PID: {})...", pid));
39 }
40
41 ProcessCleanup::terminate_gracefully(pid, 100).await;
42 ProcessCleanup::kill_port(port, pid);
43
44 ProcessCleanup::wait_for_port_free(port, 5, 500).await?;
45
46 if !quiet {
47 CliService::success("API server stopped");
48 CliService::info("Starting API server...");
49 }
50
51 super::super::serve::execute(prompter, true, false, config).await?;
52
53 let message = "API server restarted successfully".to_owned();
54 if !quiet {
55 CliService::success(&message);
56 }
57
58 let output = RestartOutput {
59 service_type: "api".to_owned(),
60 service_name: None,
61 restarted_count: 1,
62 failed_count: 0,
63 message,
64 };
65
66 Ok(CommandOutput::card_value("Restart API Server", &output))
67}
68
69pub async fn execute_agent(
70 ctx: &Arc<AppContext>,
71 agent: &str,
72 config: &CliConfig,
73) -> Result<CommandOutput> {
74 let quiet = config.is_json_output();
75
76 if !quiet {
77 CliService::section(&format!("Restarting Agent: {}", agent));
78 }
79
80 let orchestrator = lifecycle::agent_orchestrator(ctx).await?;
81 let name = lifecycle::resolve_agent_name(agent).await?;
82 let service_id = orchestrator.restart_agent(&name, None).await?;
83
84 let message = format!(
85 "Agent {} restarted successfully (service ID: {})",
86 agent, service_id
87 );
88 if !quiet {
89 CliService::success(&message);
90 }
91
92 let output = RestartOutput {
93 service_type: "agent".to_owned(),
94 service_name: Some(agent.to_owned()),
95 restarted_count: 1,
96 failed_count: 0,
97 message,
98 };
99
100 Ok(CommandOutput::card_value("Restart Agent", &output))
101}
102
103pub async fn execute_mcp(
104 ctx: &Arc<AppContext>,
105 server_name: &str,
106 build: bool,
107 config: &CliConfig,
108) -> Result<CommandOutput> {
109 let quiet = config.is_json_output();
110 let action = if build {
111 "Building and restarting"
112 } else {
113 "Restarting"
114 };
115
116 if !quiet {
117 CliService::section(&format!("{} MCP Server: {}", action, server_name));
118 }
119
120 let manager = lifecycle::mcp_orchestrator(ctx)?;
121
122 if build {
123 manager
124 .build_and_restart_services(Some(server_name.to_owned()))
125 .await?;
126 } else {
127 manager
128 .restart_services_sync(Some(server_name.to_owned()))
129 .await?;
130 }
131
132 let message = format!("MCP server {} restarted successfully", server_name);
133 if !quiet {
134 CliService::success(&message);
135 }
136
137 let output = RestartOutput {
138 service_type: "mcp".to_owned(),
139 service_name: Some(server_name.to_owned()),
140 restarted_count: 1,
141 failed_count: 0,
142 message,
143 };
144
145 Ok(CommandOutput::card_value("Restart MCP Server", &output))
146}