systemprompt_cli/commands/infrastructure/services/
dispatch.rs1use 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}