Skip to main content

systemprompt_cli/commands/infrastructure/services/
dispatch.rs

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