objectiveai_sdk/cli/command/mcp/
mod.rs1pub mod config;
2pub mod kill;
3pub mod spawn;
4
5#[derive(clap::Subcommand)]
6pub enum Command {
7 Config {
8 #[command(subcommand)]
9 command: config::Command,
10 },
11 Kill(kill::Command),
12 Spawn(spawn::Command),
13}
14
15#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, schemars::JsonSchema)]
16#[serde(untagged)]
17#[schemars(rename = "cli.command.mcp.Request")]
18pub enum Request {
19 #[schemars(title = "Config")]
20 Config(config::Request),
21 #[schemars(title = "Kill")]
22 Kill(kill::Request),
23 #[schemars(title = "KillRequestSchema")]
24 KillRequestSchema(kill::request_schema::Request),
25 #[schemars(title = "KillResponseSchema")]
26 KillResponseSchema(kill::response_schema::Request),
27 #[schemars(title = "Spawn")]
28 Spawn(spawn::Request),
29 #[schemars(title = "SpawnRequestSchema")]
30 SpawnRequestSchema(spawn::request_schema::Request),
31 #[schemars(title = "SpawnResponseSchema")]
32 SpawnResponseSchema(spawn::response_schema::Request),
33}
34
35#[objectiveai_sdk_macros::json_schema_ignore]
38#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, schemars::JsonSchema)]
39#[schemars(rename = "cli.command.mcp.Response")]
40#[serde(untagged)]
41pub enum Response {
42 #[schemars(title = "Config")]
43 Config(config::Response),
44 #[schemars(title = "Kill")]
45 Kill(kill::Response),
46 #[schemars(title = "KillRequestSchema")]
47 KillRequestSchema(kill::request_schema::Response),
48 #[schemars(title = "KillResponseSchema")]
49 KillResponseSchema(kill::response_schema::Response),
50 #[schemars(title = "Spawn")]
51 Spawn(spawn::Response),
52 #[schemars(title = "SpawnRequestSchema")]
53 SpawnRequestSchema(spawn::request_schema::Response),
54 #[schemars(title = "SpawnResponseSchema")]
55 SpawnResponseSchema(spawn::response_schema::Response),
56}
57
58#[cfg(feature = "mcp")]
59impl crate::cli::command::CommandResponse for Response {
60 fn into_mcp(self) -> crate::cli::command::McpResponseItem {
61 match self {
62 Response::Config(v) => v.into_mcp(),
63 Response::Kill(v) => v.into_mcp(),
64 Response::KillRequestSchema(v) => v.into_mcp(),
65 Response::KillResponseSchema(v) => v.into_mcp(),
66 Response::Spawn(v) => v.into_mcp(),
67 Response::SpawnRequestSchema(v) => v.into_mcp(),
68 Response::SpawnResponseSchema(v) => v.into_mcp(),
69 }
70 }
71}
72
73impl TryFrom<Command> for Request {
74 type Error = crate::cli::command::FromArgsError;
75 fn try_from(command: Command) -> Result<Self, Self::Error> {
76 match command {
77 Command::Config { command } =>
78 Ok(Request::Config(config::Request::try_from(command)?)),
79 Command::Kill(cmd) => match cmd.schema {
80 None => Ok(Request::Kill(kill::Request::try_from(cmd.args)?)),
81 Some(kill::Schema::RequestSchema(args)) =>
82 Ok(Request::KillRequestSchema(kill::request_schema::Request::try_from(args)?)),
83 Some(kill::Schema::ResponseSchema(args)) =>
84 Ok(Request::KillResponseSchema(kill::response_schema::Request::try_from(args)?)),
85 },
86 Command::Spawn(cmd) => match cmd.schema {
87 None => Ok(Request::Spawn(spawn::Request::try_from(cmd.args)?)),
88 Some(spawn::Schema::RequestSchema(args)) =>
89 Ok(Request::SpawnRequestSchema(spawn::request_schema::Request::try_from(args)?)),
90 Some(spawn::Schema::ResponseSchema(args)) =>
91 Ok(Request::SpawnResponseSchema(spawn::response_schema::Request::try_from(args)?)),
92 },
93 }
94 }
95}
96
97impl crate::cli::command::CommandRequest for Request {
98 fn into_command(&self) -> Vec<String> {
99 match self {
100 Request::Config(inner) => inner.into_command(),
101 Request::Kill(inner) => inner.into_command(),
102 Request::KillRequestSchema(inner) => inner.into_command(),
103 Request::KillResponseSchema(inner) => inner.into_command(),
104 Request::Spawn(inner) => inner.into_command(),
105 Request::SpawnRequestSchema(inner) => inner.into_command(),
106 Request::SpawnResponseSchema(inner) => inner.into_command(),
107 }
108 }
109
110 fn request_base(&self) -> &crate::cli::command::RequestBase {
111 match self {
112 Request::Config(inner) => inner.request_base(),
113 Request::Kill(inner) => inner.request_base(),
114 Request::KillRequestSchema(inner) => inner.request_base(),
115 Request::KillResponseSchema(inner) => inner.request_base(),
116 Request::Spawn(inner) => inner.request_base(),
117 Request::SpawnRequestSchema(inner) => inner.request_base(),
118 Request::SpawnResponseSchema(inner) => inner.request_base(),
119 }
120 }
121
122 fn request_base_mut(&mut self) -> Option<&mut crate::cli::command::RequestBase> {
123 match self {
124 Request::Config(inner) => inner.request_base_mut(),
125 Request::Kill(inner) => inner.request_base_mut(),
126 Request::KillRequestSchema(inner) => inner.request_base_mut(),
127 Request::KillResponseSchema(inner) => inner.request_base_mut(),
128 Request::Spawn(inner) => inner.request_base_mut(),
129 Request::SpawnRequestSchema(inner) => inner.request_base_mut(),
130 Request::SpawnResponseSchema(inner) => inner.request_base_mut(),
131 }
132 }
133}
134
135#[cfg(feature = "cli-executor")]
136pub async fn execute<E: crate::cli::command::CommandExecutor>(
137 executor: &E,
138 request: Request,
139
140 agent_arguments: Option<&crate::cli::command::AgentArguments>,
141 ) -> Result<
142 std::pin::Pin<Box<dyn futures::Stream<Item = Result<Response, E::Error>> + Send>>,
143 E::Error,
144> {
145 use futures::StreamExt;
146 let stream: std::pin::Pin<Box<dyn futures::Stream<Item = Result<Response, E::Error>> + Send>> =
147 match request {
148 Request::Config(req) => {
149 let inner = config::execute(executor, req, agent_arguments).await?;
150 Box::pin(inner.map(|r| r.map(Response::Config)))
151 }
152 Request::Kill(req) => {
153 let value = kill::execute(executor, req, agent_arguments).await?;
154 Box::pin(crate::cli::command::StreamOnce::new(Ok(
155 Response::Kill(value),
156 )))
157 }
158 Request::KillRequestSchema(req) => {
159 let value = kill::request_schema::execute(executor, req, agent_arguments).await?;
160 Box::pin(crate::cli::command::StreamOnce::new(Ok(
161 Response::KillRequestSchema(value),
162 )))
163 }
164 Request::KillResponseSchema(req) => {
165 let value = kill::response_schema::execute(executor, req, agent_arguments).await?;
166 Box::pin(crate::cli::command::StreamOnce::new(Ok(
167 Response::KillResponseSchema(value),
168 )))
169 }
170 Request::Spawn(req) => {
171 let value = spawn::execute(executor, req, agent_arguments).await?;
172 Box::pin(crate::cli::command::StreamOnce::new(Ok(
173 Response::Spawn(value),
174 )))
175 }
176 Request::SpawnRequestSchema(req) => {
177 let value = spawn::request_schema::execute(executor, req, agent_arguments).await?;
178 Box::pin(crate::cli::command::StreamOnce::new(Ok(
179 Response::SpawnRequestSchema(value),
180 )))
181 }
182 Request::SpawnResponseSchema(req) => {
183 let value = spawn::response_schema::execute(executor, req, agent_arguments).await?;
184 Box::pin(crate::cli::command::StreamOnce::new(Ok(
185 Response::SpawnResponseSchema(value),
186 )))
187 }
188 };
189 Ok(stream)
190}
191
192#[cfg(feature = "cli-executor")]
193pub async fn execute_transform<E: crate::cli::command::CommandExecutor>(
194 executor: &E,
195 request: Request,
196 transform: crate::cli::command::Transform,
197
198 agent_arguments: Option<&crate::cli::command::AgentArguments>,
199 ) -> Result<
200 std::pin::Pin<Box<dyn futures::Stream<Item = Result<serde_json::Value, E::Error>> + Send>>,
201 E::Error,
202> {
203 let stream: std::pin::Pin<Box<dyn futures::Stream<Item = Result<serde_json::Value, E::Error>> + Send>> =
204 match request {
205 Request::Config(req) => {
206 let inner = config::execute_transform(executor, req, transform, agent_arguments).await?;
207 Box::pin(inner)
208 }
209 Request::Kill(req) => {
210 let value = kill::execute_transform(executor, req, transform, agent_arguments).await?;
211 Box::pin(crate::cli::command::StreamOnce::new(Ok(value)))
212 }
213 Request::KillRequestSchema(req) => {
214 let value = kill::request_schema::execute_transform(executor, req, transform, agent_arguments).await?;
215 Box::pin(crate::cli::command::StreamOnce::new(Ok(value)))
216 }
217 Request::KillResponseSchema(req) => {
218 let value = kill::response_schema::execute_transform(executor, req, transform, agent_arguments).await?;
219 Box::pin(crate::cli::command::StreamOnce::new(Ok(value)))
220 }
221 Request::Spawn(req) => {
222 let value = spawn::execute_transform(executor, req, transform, agent_arguments).await?;
223 Box::pin(crate::cli::command::StreamOnce::new(Ok(value)))
224 }
225 Request::SpawnRequestSchema(req) => {
226 let value = spawn::request_schema::execute_transform(executor, req, transform, agent_arguments).await?;
227 Box::pin(crate::cli::command::StreamOnce::new(Ok(value)))
228 }
229 Request::SpawnResponseSchema(req) => {
230 let value = spawn::response_schema::execute_transform(executor, req, transform, agent_arguments).await?;
231 Box::pin(crate::cli::command::StreamOnce::new(Ok(value)))
232 }
233 };
234 Ok(stream)
235}