Skip to main content

systemprompt_cli/commands/infrastructure/services/restart/
single.rs

1use 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}