1#[derive(clap::Parser)]
6#[command(name = "objectiveai")]
7pub enum Command {
8 Agents {
9 #[command(subcommand)]
10 command: super::agents::Command,
11 },
12 Config {
13 #[command(subcommand)]
14 command: super::config::Command,
15 },
16 Functions {
17 #[command(subcommand)]
18 command: super::functions::Command,
19 },
20 Logs {
21 #[command(subcommand)]
22 command: super::logs::Command,
23 },
24 Mcp {
25 #[command(subcommand)]
26 command: super::mcp::Command,
27 },
28 Plugins {
29 #[command(subcommand)]
30 command: super::plugins::Command,
31 },
32 Swarms {
33 #[command(subcommand)]
34 command: super::swarms::Command,
35 },
36 Tools {
37 #[command(subcommand)]
38 command: super::tools::Command,
39 },
40 Update(super::update::Command),
41 Viewer {
42 #[command(subcommand)]
43 command: super::viewer::Command,
44 },
45}
46
47#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, schemars::JsonSchema)]
48#[serde(untagged)]
49#[schemars(rename = "cli.command.Request")]
50pub enum Request {
51 #[schemars(title = "Agents")]
52 Agents(super::agents::Request),
53 #[schemars(title = "Config")]
54 Config(super::config::Request),
55 #[schemars(title = "Functions")]
56 Functions(super::functions::Request),
57 #[schemars(title = "Logs")]
58 Logs(super::logs::Request),
59 #[schemars(title = "Mcp")]
60 Mcp(super::mcp::Request),
61 #[schemars(title = "Plugins")]
62 Plugins(super::plugins::Request),
63 #[schemars(title = "Swarms")]
64 Swarms(super::swarms::Request),
65 #[schemars(title = "Tools")]
66 Tools(super::tools::Request),
67 #[schemars(title = "Update")]
68 Update(super::update::Request),
69 #[schemars(title = "UpdateRequestSchema")]
70 UpdateRequestSchema(super::update::request_schema::Request),
71 #[schemars(title = "UpdateResponseSchema")]
72 UpdateResponseSchema(super::update::response_schema::Request),
73 #[schemars(title = "Viewer")]
74 Viewer(super::viewer::Request),
75}
76
77#[objectiveai_sdk_macros::json_schema_ignore]
83#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, schemars::JsonSchema)]
84#[schemars(rename = "cli.command.ResponseItem")]
85#[serde(untagged)]
86pub enum ResponseItem {
87 #[schemars(title = "Agents")]
88 Agents(super::agents::ResponseItem),
89 #[schemars(title = "Config")]
90 Config(super::config::ResponseItem),
91 #[schemars(title = "Functions")]
92 Functions(super::functions::ResponseItem),
93 #[schemars(title = "Logs")]
94 Logs(super::logs::ResponseItem),
95 #[schemars(title = "Mcp")]
96 Mcp(super::mcp::Response),
97 #[schemars(title = "Plugins")]
98 Plugins(super::plugins::ResponseItem),
99 #[schemars(title = "Swarms")]
100 Swarms(super::swarms::ResponseItem),
101 #[schemars(title = "Tools")]
102 Tools(super::tools::ResponseItem),
103 #[schemars(title = "Update")]
104 Update(super::update::ResponseItem),
105 #[schemars(title = "UpdateRequestSchema")]
106 UpdateRequestSchema(super::update::request_schema::Response),
107 #[schemars(title = "UpdateResponseSchema")]
108 UpdateResponseSchema(super::update::response_schema::Response),
109 #[schemars(title = "Viewer")]
110 Viewer(super::viewer::Response),
111}
112
113#[cfg(feature = "mcp")]
114impl super::CommandResponse for ResponseItem {
115 fn into_mcp(self) -> super::McpResponseItem {
116 match self {
117 ResponseItem::Agents(v) => v.into_mcp(),
118 ResponseItem::Config(v) => v.into_mcp(),
119 ResponseItem::Functions(v) => v.into_mcp(),
120 ResponseItem::Logs(v) => v.into_mcp(),
121 ResponseItem::Mcp(v) => v.into_mcp(),
122 ResponseItem::Plugins(v) => v.into_mcp(),
123 ResponseItem::Swarms(v) => v.into_mcp(),
124 ResponseItem::Tools(v) => v.into_mcp(),
125 ResponseItem::Update(v) => v.into_mcp(),
126 ResponseItem::UpdateRequestSchema(v) => v.into_mcp(),
127 ResponseItem::UpdateResponseSchema(v) => v.into_mcp(),
128 ResponseItem::Viewer(v) => v.into_mcp(),
129 }
130 }
131}
132
133impl TryFrom<Command> for Request {
134 type Error = super::FromArgsError;
135 fn try_from(command: Command) -> Result<Self, Self::Error> {
136 match command {
137 Command::Agents { command } =>
138 Ok(Request::Agents(super::agents::Request::try_from(command)?)),
139 Command::Config { command } =>
140 Ok(Request::Config(super::config::Request::try_from(command)?)),
141 Command::Functions { command } =>
142 Ok(Request::Functions(super::functions::Request::try_from(command)?)),
143 Command::Logs { command } =>
144 Ok(Request::Logs(super::logs::Request::try_from(command)?)),
145 Command::Mcp { command } =>
146 Ok(Request::Mcp(super::mcp::Request::try_from(command)?)),
147 Command::Plugins { command } =>
148 Ok(Request::Plugins(super::plugins::Request::try_from(command)?)),
149 Command::Swarms { command } =>
150 Ok(Request::Swarms(super::swarms::Request::try_from(command)?)),
151 Command::Tools { command } =>
152 Ok(Request::Tools(super::tools::Request::try_from(command)?)),
153 Command::Update(cmd) => match cmd.schema {
154 None => Ok(Request::Update(super::update::Request::try_from(cmd.args)?)),
155 Some(super::update::Schema::RequestSchema(args)) =>
156 Ok(Request::UpdateRequestSchema(super::update::request_schema::Request::try_from(args)?)),
157 Some(super::update::Schema::ResponseSchema(args)) =>
158 Ok(Request::UpdateResponseSchema(super::update::response_schema::Request::try_from(args)?)),
159 },
160 Command::Viewer { command } =>
161 Ok(Request::Viewer(super::viewer::Request::try_from(command)?)),
162 }
163 }
164}
165
166impl super::CommandRequest for Request {
167 fn into_command(&self) -> Vec<String> {
168 match self {
169 Request::Agents(inner) => inner.into_command(),
170 Request::Config(inner) => inner.into_command(),
171 Request::Functions(inner) => inner.into_command(),
172 Request::Logs(inner) => inner.into_command(),
173 Request::Mcp(inner) => inner.into_command(),
174 Request::Plugins(inner) => inner.into_command(),
175 Request::Swarms(inner) => inner.into_command(),
176 Request::Tools(inner) => inner.into_command(),
177 Request::Update(inner) => inner.into_command(),
178 Request::UpdateRequestSchema(inner) => inner.into_command(),
179 Request::UpdateResponseSchema(inner) => inner.into_command(),
180 Request::Viewer(inner) => inner.into_command(),
181 }
182 }
183}
184
185#[cfg(feature = "cli-executor")]
186pub async fn execute<E: super::CommandExecutor>(
187 executor: &E,
188 request: Request,
189
190 agent_arguments: Option<&crate::cli::command::AgentArguments>,
191 ) -> Result<
192 std::pin::Pin<Box<dyn futures::Stream<Item = Result<ResponseItem, E::Error>> + Send>>,
193 E::Error,
194> {
195 use futures::StreamExt;
196 let stream: std::pin::Pin<Box<dyn futures::Stream<Item = Result<ResponseItem, E::Error>> + Send>> =
197 match request {
198 Request::Agents(req) => {
199 let inner = super::agents::execute(executor, req, agent_arguments).await?;
200 Box::pin(inner.map(|r| r.map(ResponseItem::Agents)))
201 }
202 Request::Config(req) => {
203 let inner = super::config::execute(executor, req, agent_arguments).await?;
204 Box::pin(inner.map(|r| r.map(ResponseItem::Config)))
205 }
206 Request::Functions(req) => {
207 let inner = super::functions::execute(executor, req, agent_arguments).await?;
208 Box::pin(inner.map(|r| r.map(ResponseItem::Functions)))
209 }
210 Request::Logs(req) => {
211 let inner = super::logs::execute(executor, req, agent_arguments).await?;
212 Box::pin(inner.map(|r| r.map(ResponseItem::Logs)))
213 }
214 Request::Mcp(req) => {
215 let inner = super::mcp::execute(executor, req, agent_arguments).await?;
216 Box::pin(inner.map(|r| r.map(ResponseItem::Mcp)))
217 }
218 Request::Plugins(req) => {
219 let inner = super::plugins::execute(executor, req, agent_arguments).await?;
220 Box::pin(inner.map(|r| r.map(ResponseItem::Plugins)))
221 }
222 Request::Swarms(req) => {
223 let inner = super::swarms::execute(executor, req, agent_arguments).await?;
224 Box::pin(inner.map(|r| r.map(ResponseItem::Swarms)))
225 }
226 Request::Tools(req) => {
227 let inner = super::tools::execute(executor, req, agent_arguments).await?;
228 Box::pin(inner.map(|r| r.map(ResponseItem::Tools)))
229 }
230 Request::Update(req) => {
231 let inner = super::update::execute(executor, req, agent_arguments).await?;
232 Box::pin(inner.map(|r| r.map(ResponseItem::Update)))
233 }
234 Request::UpdateRequestSchema(req) => {
235 let value = super::update::request_schema::execute(executor, req, agent_arguments).await?;
236 Box::pin(super::StreamOnce::new(Ok(ResponseItem::UpdateRequestSchema(value))))
237 }
238 Request::UpdateResponseSchema(req) => {
239 let value = super::update::response_schema::execute(executor, req, agent_arguments).await?;
240 Box::pin(super::StreamOnce::new(Ok(ResponseItem::UpdateResponseSchema(value))))
241 }
242 Request::Viewer(req) => {
243 let inner = super::viewer::execute(executor, req, agent_arguments).await?;
244 Box::pin(inner.map(|r| r.map(ResponseItem::Viewer)))
245 }
246 };
247 Ok(stream)
248}
249
250#[cfg(feature = "cli-executor")]
251pub async fn execute_jq<E: super::CommandExecutor>(
252 executor: &E,
253 request: Request,
254 jq: String,
255
256 agent_arguments: Option<&crate::cli::command::AgentArguments>,
257 ) -> Result<
258 std::pin::Pin<Box<dyn futures::Stream<Item = Result<serde_json::Value, E::Error>> + Send>>,
259 E::Error,
260> {
261 let stream: std::pin::Pin<Box<dyn futures::Stream<Item = Result<serde_json::Value, E::Error>> + Send>> =
262 match request {
263 Request::Agents(req) => {
264 let inner = super::agents::execute_jq(executor, req, jq, agent_arguments).await?;
265 Box::pin(inner)
266 }
267 Request::Config(req) => {
268 let inner = super::config::execute_jq(executor, req, jq, agent_arguments).await?;
269 Box::pin(inner)
270 }
271 Request::Functions(req) => {
272 let inner = super::functions::execute_jq(executor, req, jq, agent_arguments).await?;
273 Box::pin(inner)
274 }
275 Request::Logs(req) => {
276 let inner = super::logs::execute_jq(executor, req, jq, agent_arguments).await?;
277 Box::pin(inner)
278 }
279 Request::Mcp(req) => {
280 let inner = super::mcp::execute_jq(executor, req, jq, agent_arguments).await?;
281 Box::pin(inner)
282 }
283 Request::Plugins(req) => {
284 let inner = super::plugins::execute_jq(executor, req, jq, agent_arguments).await?;
285 Box::pin(inner)
286 }
287 Request::Swarms(req) => {
288 let inner = super::swarms::execute_jq(executor, req, jq, agent_arguments).await?;
289 Box::pin(inner)
290 }
291 Request::Tools(req) => {
292 let inner = super::tools::execute_jq(executor, req, jq, agent_arguments).await?;
293 Box::pin(inner)
294 }
295 Request::Update(req) => {
296 let inner = super::update::execute_jq(executor, req, jq, agent_arguments).await?;
297 Box::pin(inner)
298 }
299 Request::UpdateRequestSchema(req) => {
300 let value = super::update::request_schema::execute_jq(executor, req, jq, agent_arguments).await?;
301 Box::pin(super::StreamOnce::new(Ok(value)))
302 }
303 Request::UpdateResponseSchema(req) => {
304 let value = super::update::response_schema::execute_jq(executor, req, jq, agent_arguments).await?;
305 Box::pin(super::StreamOnce::new(Ok(value)))
306 }
307 Request::Viewer(req) => {
308 let inner = super::viewer::execute_jq(executor, req, jq, agent_arguments).await?;
309 Box::pin(inner)
310 }
311 };
312 Ok(stream)
313}
314
315pub fn parse_request(args: &[String]) -> Result<Request, ParseError> {
330 let command = if args.first().map(String::as_str) == Some("objectiveai") {
331 <Command as clap::Parser>::try_parse_from(args)?
332 } else {
333 let argv = std::iter::once("objectiveai".to_string())
334 .chain(args.iter().cloned());
335 <Command as clap::Parser>::try_parse_from(argv)?
336 };
337 Ok(Request::try_from(command)?)
338}
339
340#[derive(Debug)]
346pub enum ParseError {
347 Clap(clap::Error),
348 FromArgs(super::FromArgsError),
349}
350
351impl std::fmt::Display for ParseError {
352 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
353 match self {
354 ParseError::Clap(e) => write!(f, "{e}"),
355 ParseError::FromArgs(e) => write!(f, "{e}"),
356 }
357 }
358}
359
360impl std::error::Error for ParseError {}
361
362impl From<clap::Error> for ParseError {
363 fn from(e: clap::Error) -> Self {
364 ParseError::Clap(e)
365 }
366}
367
368impl From<super::FromArgsError> for ParseError {
369 fn from(e: super::FromArgsError) -> Self {
370 ParseError::FromArgs(e)
371 }
372}