Skip to main content

objectiveai_sdk/cli/command/mcp/
mod.rs

1pub mod kill;
2pub mod spawn;
3
4#[derive(clap::Subcommand)]
5pub enum Command {
6    Kill(kill::Command),
7    Spawn(spawn::Command),
8}
9
10#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, schemars::JsonSchema)]
11#[serde(untagged)]
12#[schemars(rename = "cli.command.mcp.Request")]
13pub enum Request {
14    #[schemars(title = "Kill")]
15    Kill(kill::Request),
16    #[schemars(title = "KillRequestSchema")]
17    KillRequestSchema(kill::request_schema::Request),
18    #[schemars(title = "KillResponseSchema")]
19    KillResponseSchema(kill::response_schema::Request),
20    #[schemars(title = "Spawn")]
21    Spawn(spawn::Request),
22    #[schemars(title = "SpawnRequestSchema")]
23    SpawnRequestSchema(spawn::request_schema::Request),
24    #[schemars(title = "SpawnResponseSchema")]
25    SpawnResponseSchema(spawn::response_schema::Request),
26}
27
28// Exempt from json-schema coverage: tier aggregate (see the root
29// `ResponseItem` in command.rs - TS7056).
30#[objectiveai_sdk_macros::json_schema_ignore]
31#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, schemars::JsonSchema)]
32#[schemars(rename = "cli.command.mcp.Response")]
33#[serde(untagged)]
34pub enum Response {
35    #[schemars(title = "Kill")]
36    Kill(kill::Response),
37    #[schemars(title = "KillRequestSchema")]
38    KillRequestSchema(kill::request_schema::Response),
39    #[schemars(title = "KillResponseSchema")]
40    KillResponseSchema(kill::response_schema::Response),
41    #[schemars(title = "Spawn")]
42    Spawn(spawn::Response),
43    #[schemars(title = "SpawnRequestSchema")]
44    SpawnRequestSchema(spawn::request_schema::Response),
45    #[schemars(title = "SpawnResponseSchema")]
46    SpawnResponseSchema(spawn::response_schema::Response),
47}
48
49#[cfg(feature = "mcp")]
50impl crate::cli::command::CommandResponse for Response {
51    fn into_mcp(self) -> crate::cli::command::McpResponseItem {
52        match self {
53            Response::Kill(v) => v.into_mcp(),
54            Response::KillRequestSchema(v) => v.into_mcp(),
55            Response::KillResponseSchema(v) => v.into_mcp(),
56            Response::Spawn(v) => v.into_mcp(),
57            Response::SpawnRequestSchema(v) => v.into_mcp(),
58            Response::SpawnResponseSchema(v) => v.into_mcp(),
59        }
60    }
61}
62
63impl TryFrom<Command> for Request {
64    type Error = crate::cli::command::FromArgsError;
65    fn try_from(command: Command) -> Result<Self, Self::Error> {
66        match command {
67            Command::Kill(cmd) => match cmd.schema {
68                None => Ok(Request::Kill(kill::Request::try_from(cmd.args)?)),
69                Some(kill::Schema::RequestSchema(args)) =>
70                    Ok(Request::KillRequestSchema(kill::request_schema::Request::try_from(args)?)),
71                Some(kill::Schema::ResponseSchema(args)) =>
72                    Ok(Request::KillResponseSchema(kill::response_schema::Request::try_from(args)?)),
73            },
74            Command::Spawn(cmd) => match cmd.schema {
75                None => Ok(Request::Spawn(spawn::Request::try_from(cmd.args)?)),
76                Some(spawn::Schema::RequestSchema(args)) =>
77                    Ok(Request::SpawnRequestSchema(spawn::request_schema::Request::try_from(args)?)),
78                Some(spawn::Schema::ResponseSchema(args)) =>
79                    Ok(Request::SpawnResponseSchema(spawn::response_schema::Request::try_from(args)?)),
80            },
81        }
82    }
83}
84
85impl crate::cli::command::CommandRequest for Request {
86    fn into_command(&self) -> Vec<String> {
87        match self {
88            Request::Kill(inner) => inner.into_command(),
89            Request::KillRequestSchema(inner) => inner.into_command(),
90            Request::KillResponseSchema(inner) => inner.into_command(),
91            Request::Spawn(inner) => inner.into_command(),
92            Request::SpawnRequestSchema(inner) => inner.into_command(),
93            Request::SpawnResponseSchema(inner) => inner.into_command(),
94        }
95    }
96}
97
98#[cfg(feature = "cli-executor")]
99pub async fn execute<E: crate::cli::command::CommandExecutor>(
100    executor: &E,
101    request: Request,
102
103        agent_arguments: Option<&crate::cli::command::AgentArguments>,
104    ) -> Result<
105    std::pin::Pin<Box<dyn futures::Stream<Item = Result<Response, E::Error>> + Send>>,
106    E::Error,
107> {
108    use futures::StreamExt;
109    let stream: std::pin::Pin<Box<dyn futures::Stream<Item = Result<Response, E::Error>> + Send>> =
110        match request {
111            Request::Kill(req) => {
112                let value = kill::execute(executor, req, agent_arguments).await?;
113                Box::pin(crate::cli::command::StreamOnce::new(Ok(
114                    Response::Kill(value),
115                )))
116            }
117            Request::KillRequestSchema(req) => {
118                let value = kill::request_schema::execute(executor, req, agent_arguments).await?;
119                Box::pin(crate::cli::command::StreamOnce::new(Ok(
120                    Response::KillRequestSchema(value),
121                )))
122            }
123            Request::KillResponseSchema(req) => {
124                let value = kill::response_schema::execute(executor, req, agent_arguments).await?;
125                Box::pin(crate::cli::command::StreamOnce::new(Ok(
126                    Response::KillResponseSchema(value),
127                )))
128            }
129            Request::Spawn(req) => {
130                let value = spawn::execute(executor, req, agent_arguments).await?;
131                Box::pin(crate::cli::command::StreamOnce::new(Ok(
132                    Response::Spawn(value),
133                )))
134            }
135            Request::SpawnRequestSchema(req) => {
136                let value = spawn::request_schema::execute(executor, req, agent_arguments).await?;
137                Box::pin(crate::cli::command::StreamOnce::new(Ok(
138                    Response::SpawnRequestSchema(value),
139                )))
140            }
141            Request::SpawnResponseSchema(req) => {
142                let value = spawn::response_schema::execute(executor, req, agent_arguments).await?;
143                Box::pin(crate::cli::command::StreamOnce::new(Ok(
144                    Response::SpawnResponseSchema(value),
145                )))
146            }
147        };
148    Ok(stream)
149}
150
151#[cfg(feature = "cli-executor")]
152pub async fn execute_jq<E: crate::cli::command::CommandExecutor>(
153    executor: &E,
154    request: Request,
155    jq: String,
156
157        agent_arguments: Option<&crate::cli::command::AgentArguments>,
158    ) -> Result<
159    std::pin::Pin<Box<dyn futures::Stream<Item = Result<serde_json::Value, E::Error>> + Send>>,
160    E::Error,
161> {
162    let stream: std::pin::Pin<Box<dyn futures::Stream<Item = Result<serde_json::Value, E::Error>> + Send>> =
163        match request {
164            Request::Kill(req) => {
165                let value = kill::execute_jq(executor, req, jq, agent_arguments).await?;
166                Box::pin(crate::cli::command::StreamOnce::new(Ok(value)))
167            }
168            Request::KillRequestSchema(req) => {
169                let value = kill::request_schema::execute_jq(executor, req, jq, agent_arguments).await?;
170                Box::pin(crate::cli::command::StreamOnce::new(Ok(value)))
171            }
172            Request::KillResponseSchema(req) => {
173                let value = kill::response_schema::execute_jq(executor, req, jq, agent_arguments).await?;
174                Box::pin(crate::cli::command::StreamOnce::new(Ok(value)))
175            }
176            Request::Spawn(req) => {
177                let value = spawn::execute_jq(executor, req, jq, agent_arguments).await?;
178                Box::pin(crate::cli::command::StreamOnce::new(Ok(value)))
179            }
180            Request::SpawnRequestSchema(req) => {
181                let value = spawn::request_schema::execute_jq(executor, req, jq, agent_arguments).await?;
182                Box::pin(crate::cli::command::StreamOnce::new(Ok(value)))
183            }
184            Request::SpawnResponseSchema(req) => {
185                let value = spawn::response_schema::execute_jq(executor, req, jq, agent_arguments).await?;
186                Box::pin(crate::cli::command::StreamOnce::new(Ok(value)))
187            }
188        };
189    Ok(stream)
190}