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