Skip to main content

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

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