Skip to main content

systemprompt_cli/commands/infrastructure/services/
dispatch.rs

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