Skip to main content

systemprompt_cli/commands/infrastructure/services/
dispatch.rs

1use anyhow::{Context, Result};
2use std::sync::Arc;
3use systemprompt_runtime::AppContext;
4
5use super::{RestartTarget, ServicesCommands, StartTarget, StopTarget, restart, start, stop};
6use crate::cli_settings::CliConfig;
7use crate::shared::render_result;
8
9pub async fn execute(command: ServicesCommands, config: &CliConfig) -> Result<()> {
10    match command {
11        ServicesCommands::Start {
12            target,
13            all,
14            api,
15            agents,
16            mcp,
17            foreground: _,
18            skip_migrate,
19            kill_port_process,
20        } => {
21            let flags = start::ServiceFlags {
22                all,
23                targets: start::ServiceTargetFlags { api, agents, mcp },
24            };
25            let options = start::StartupOptions {
26                skip_migrate,
27                kill_port_process,
28            };
29            execute_start(target, flags, options, config).await
30        },
31
32        ServicesCommands::Stop {
33            target,
34            all,
35            api,
36            agents,
37            mcp,
38            force,
39        } => {
40            let flags = start::ServiceFlags {
41                all,
42                targets: start::ServiceTargetFlags { api, agents, mcp },
43            };
44            execute_stop(target, flags, force, config).await
45        },
46
47        ServicesCommands::Restart {
48            target,
49            failed,
50            agents,
51            mcp,
52        } => execute_restart(target, failed, agents, mcp, config).await,
53
54        ServicesCommands::Status {
55            detailed,
56            json,
57            health,
58        } => {
59            let result = super::status::execute(detailed, json, health, config).await?;
60            render_result(&result);
61            Ok(())
62        },
63
64        ServicesCommands::Cleanup { yes, dry_run } => {
65            let result = super::cleanup::execute(yes, dry_run, config).await?;
66            render_result(&result);
67            Ok(())
68        },
69
70        ServicesCommands::Serve {
71            foreground,
72            kill_port_process,
73        } => super::serve::execute(foreground, kill_port_process, config).await,
74    }
75}
76
77async fn execute_start(
78    target: Option<StartTarget>,
79    flags: start::ServiceFlags,
80    options: start::StartupOptions,
81    config: &CliConfig,
82) -> Result<()> {
83    if let Some(individual) = target {
84        let ctx = Arc::new(
85            AppContext::new()
86                .await
87                .context("Failed to initialize application context")?,
88        );
89        return match individual {
90            StartTarget::Agent { agent } => {
91                start::execute_individual_agent(&ctx, &agent, config).await
92            },
93            StartTarget::Mcp { server_name } => {
94                start::execute_individual_mcp(&ctx, &server_name, config).await
95            },
96        };
97    }
98
99    let service_target = start::ServiceTarget::from_flags(flags);
100    start::execute(service_target, options, config).await
101}
102
103async fn execute_stop(
104    target: Option<StopTarget>,
105    flags: start::ServiceFlags,
106    force: bool,
107    config: &CliConfig,
108) -> Result<()> {
109    if let Some(individual) = target {
110        let ctx = Arc::new(
111            AppContext::new()
112                .await
113                .context("Failed to initialize application context")?,
114        );
115        return match individual {
116            StopTarget::Agent { agent, force } => {
117                let result = stop::execute_individual_agent(&ctx, &agent, force, config).await?;
118                render_result(&result);
119                Ok(())
120            },
121            StopTarget::Mcp { server_name, force } => {
122                let result =
123                    stop::execute_individual_mcp(&ctx, &server_name, force, config).await?;
124                render_result(&result);
125                Ok(())
126            },
127        };
128    }
129
130    let service_target = start::ServiceTarget::from_flags(flags);
131    let result = stop::execute(service_target, force, config).await?;
132    render_result(&result);
133    Ok(())
134}
135
136async fn execute_restart(
137    target: Option<RestartTarget>,
138    failed: bool,
139    agents: bool,
140    mcp: bool,
141    config: &CliConfig,
142) -> Result<()> {
143    let ctx = Arc::new(
144        AppContext::new()
145            .await
146            .context("Failed to initialize application context")?,
147    );
148
149    let result = if failed {
150        restart::execute_failed(&ctx, config).await?
151    } else if agents {
152        restart::execute_all_agents(&ctx, config).await?
153    } else if mcp {
154        restart::execute_all_mcp(&ctx, config).await?
155    } else {
156        match target {
157            Some(RestartTarget::Api) => restart::execute_api(config).await?,
158            Some(RestartTarget::Agent { agent }) => {
159                restart::execute_agent(&ctx, &agent, config).await?
160            },
161            Some(RestartTarget::Mcp { server_name, build }) => {
162                restart::execute_mcp(&ctx, &server_name, build, config).await?
163            },
164            None => {
165                return Err(anyhow::anyhow!(
166                    "Must specify target (api, agent, mcp) or use --failed/--agents/--mcp flag"
167                ));
168            },
169        }
170    };
171    render_result(&result);
172    Ok(())
173}
174
175pub fn load_service_configs(
176    _ctx: &AppContext,
177) -> Result<Vec<systemprompt_scheduler::ServiceConfig>> {
178    use systemprompt_loader::ConfigLoader;
179    use systemprompt_scheduler::{ServiceConfig, ServiceType};
180
181    let services_config = ConfigLoader::load()?;
182    let mut configs = Vec::new();
183
184    for (name, agent) in &services_config.agents {
185        configs.push(ServiceConfig {
186            name: name.clone(),
187            service_type: ServiceType::Agent,
188            port: agent.port,
189            enabled: agent.enabled,
190        });
191    }
192
193    for (name, mcp) in &services_config.mcp_servers {
194        configs.push(ServiceConfig {
195            name: name.clone(),
196            service_type: ServiceType::Mcp,
197            port: mcp.port,
198            enabled: mcp.enabled,
199        });
200    }
201
202    Ok(configs)
203}