1#[derive(clap::Subcommand)]
6pub enum Subcommand {
7 Agents {
8 #[command(subcommand)]
9 command: super::agents::Command,
10 },
11 Api {
12 #[command(subcommand)]
13 command: super::api::Command,
14 },
15 Daemon {
16 #[command(subcommand)]
17 command: super::daemon::Command,
18 },
19 Db {
20 #[command(subcommand)]
21 command: super::db::Command,
22 },
23 Functions {
24 #[command(subcommand)]
25 command: super::functions::Command,
26 },
27 KillAll(super::kill_all::Command),
30 Mcp {
31 #[command(subcommand)]
32 command: super::mcp::Command,
33 },
34 Plugins {
35 #[command(subcommand)]
36 command: super::plugins::Command,
37 },
38 Python(super::python::Command),
40 Swarms {
41 #[command(subcommand)]
42 command: super::swarms::Command,
43 },
44 Tools {
45 #[command(subcommand)]
46 command: super::tools::Command,
47 },
48 Update(super::update::Command),
49 Viewer {
50 #[command(subcommand)]
51 command: super::viewer::Command,
52 },
53}
54
55#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, schemars::JsonSchema)]
56#[serde(untagged)]
57#[schemars(rename = "cli.command.Request")]
58pub enum Request {
59 #[schemars(title = "Agents")]
60 Agents(super::agents::Request),
61 #[schemars(title = "Api")]
62 Api(super::api::Request),
63 #[schemars(title = "Daemon")]
64 Daemon(super::daemon::Request),
65 #[schemars(title = "Db")]
66 Db(super::db::Request),
67 #[schemars(title = "Functions")]
68 Functions(super::functions::Request),
69 #[schemars(title = "KillAll")]
70 KillAll(super::kill_all::Request),
71 #[schemars(title = "KillAllRequestSchema")]
72 KillAllRequestSchema(super::kill_all::request_schema::Request),
73 #[schemars(title = "KillAllResponseSchema")]
74 KillAllResponseSchema(super::kill_all::response_schema::Request),
75 #[schemars(title = "Mcp")]
76 Mcp(super::mcp::Request),
77 #[schemars(title = "Plugins")]
78 Plugins(super::plugins::Request),
79 #[schemars(title = "Python")]
80 Python(super::python::Request),
81 #[schemars(title = "PythonRequestSchema")]
82 PythonRequestSchema(super::python::request_schema::Request),
83 #[schemars(title = "PythonResponseSchema")]
84 PythonResponseSchema(super::python::response_schema::Request),
85 #[schemars(title = "Swarms")]
86 Swarms(super::swarms::Request),
87 #[schemars(title = "Tools")]
88 Tools(super::tools::Request),
89 #[schemars(title = "Update")]
90 Update(super::update::Request),
91 #[schemars(title = "UpdateRequestSchema")]
92 UpdateRequestSchema(super::update::request_schema::Request),
93 #[schemars(title = "UpdateResponseSchema")]
94 UpdateResponseSchema(super::update::response_schema::Request),
95 #[schemars(title = "Viewer")]
96 Viewer(super::viewer::Request),
97}
98
99#[objectiveai_sdk_macros::json_schema_ignore]
105#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, schemars::JsonSchema)]
106#[schemars(rename = "cli.command.ResponseItem")]
107#[serde(untagged)]
108pub enum ResponseItem {
109 #[schemars(title = "Agents")]
110 Agents(super::agents::ResponseItem),
111 #[schemars(title = "Api")]
112 Api(super::api::Response),
113 #[schemars(title = "Daemon")]
114 Daemon(super::daemon::ResponseItem),
115 #[schemars(title = "Db")]
116 Db(super::db::ResponseItem),
117 #[schemars(title = "Functions")]
118 Functions(super::functions::ResponseItem),
119 #[schemars(title = "KillAll")]
120 KillAll(super::kill_all::Response),
121 #[schemars(title = "KillAllRequestSchema")]
122 KillAllRequestSchema(super::kill_all::request_schema::Response),
123 #[schemars(title = "KillAllResponseSchema")]
124 KillAllResponseSchema(super::kill_all::response_schema::Response),
125 #[schemars(title = "Mcp")]
126 Mcp(super::mcp::Response),
127 #[schemars(title = "Plugins")]
128 Plugins(super::plugins::ResponseItem),
129 #[schemars(title = "Python")]
130 Python(serde_json::Value),
131 #[schemars(title = "PythonRequestSchema")]
132 PythonRequestSchema(super::python::request_schema::Response),
133 #[schemars(title = "PythonResponseSchema")]
134 PythonResponseSchema(super::python::response_schema::Response),
135 #[schemars(title = "Swarms")]
136 Swarms(super::swarms::ResponseItem),
137 #[schemars(title = "Tools")]
138 Tools(super::tools::ResponseItem),
139 #[schemars(title = "Update")]
140 Update(super::update::ResponseItem),
141 #[schemars(title = "UpdateRequestSchema")]
142 UpdateRequestSchema(super::update::request_schema::Response),
143 #[schemars(title = "UpdateResponseSchema")]
144 UpdateResponseSchema(super::update::response_schema::Response),
145 #[schemars(title = "Viewer")]
146 Viewer(super::viewer::Response),
147}
148
149#[cfg(feature = "mcp")]
150impl super::CommandResponse for ResponseItem {
151 fn into_mcp(self) -> super::McpResponseItem {
152 match self {
153 ResponseItem::Agents(v) => v.into_mcp(),
154 ResponseItem::Api(v) => v.into_mcp(),
155 ResponseItem::Daemon(v) => v.into_mcp(),
156 ResponseItem::Db(v) => v.into_mcp(),
157 ResponseItem::Functions(v) => v.into_mcp(),
158 ResponseItem::KillAll(v) => v.into_mcp(),
159 ResponseItem::KillAllRequestSchema(v) => v.into_mcp(),
160 ResponseItem::KillAllResponseSchema(v) => v.into_mcp(),
161 ResponseItem::Mcp(v) => v.into_mcp(),
162 ResponseItem::Plugins(v) => v.into_mcp(),
163 ResponseItem::Python(v) => v.into_mcp(),
164 ResponseItem::PythonRequestSchema(v) => v.into_mcp(),
165 ResponseItem::PythonResponseSchema(v) => v.into_mcp(),
166 ResponseItem::Swarms(v) => v.into_mcp(),
167 ResponseItem::Tools(v) => v.into_mcp(),
168 ResponseItem::Update(v) => v.into_mcp(),
169 ResponseItem::UpdateRequestSchema(v) => v.into_mcp(),
170 ResponseItem::UpdateResponseSchema(v) => v.into_mcp(),
171 ResponseItem::Viewer(v) => v.into_mcp(),
172 }
173 }
174}
175
176impl TryFrom<Subcommand> for Request {
177 type Error = super::FromArgsError;
178 fn try_from(command: Subcommand) -> Result<Self, Self::Error> {
179 match command {
180 Subcommand::Agents { command } =>
181 Ok(Request::Agents(super::agents::Request::try_from(command)?)),
182 Subcommand::Api { command } =>
183 Ok(Request::Api(super::api::Request::try_from(command)?)),
184 Subcommand::Daemon { command } =>
185 Ok(Request::Daemon(super::daemon::Request::try_from(command)?)),
186 Subcommand::Db { command } =>
187 Ok(Request::Db(super::db::Request::try_from(command)?)),
188 Subcommand::Functions { command } =>
189 Ok(Request::Functions(super::functions::Request::try_from(command)?)),
190 Subcommand::KillAll(cmd) => match cmd.schema {
191 None => Ok(Request::KillAll(super::kill_all::Request::try_from(cmd.args)?)),
192 Some(super::kill_all::Schema::RequestSchema(args)) =>
193 Ok(Request::KillAllRequestSchema(super::kill_all::request_schema::Request::try_from(args)?)),
194 Some(super::kill_all::Schema::ResponseSchema(args)) =>
195 Ok(Request::KillAllResponseSchema(super::kill_all::response_schema::Request::try_from(args)?)),
196 },
197 Subcommand::Mcp { command } =>
198 Ok(Request::Mcp(super::mcp::Request::try_from(command)?)),
199 Subcommand::Plugins { command } =>
200 Ok(Request::Plugins(super::plugins::Request::try_from(command)?)),
201 Subcommand::Python(cmd) => match cmd.schema {
202 None => Ok(Request::Python(super::python::Request::try_from(cmd.args)?)),
203 Some(super::python::Schema::RequestSchema(args)) =>
204 Ok(Request::PythonRequestSchema(super::python::request_schema::Request::try_from(args)?)),
205 Some(super::python::Schema::ResponseSchema(args)) =>
206 Ok(Request::PythonResponseSchema(super::python::response_schema::Request::try_from(args)?)),
207 },
208 Subcommand::Swarms { command } =>
209 Ok(Request::Swarms(super::swarms::Request::try_from(command)?)),
210 Subcommand::Tools { command } =>
211 Ok(Request::Tools(super::tools::Request::try_from(command)?)),
212 Subcommand::Update(cmd) => match cmd.schema {
213 None => Ok(Request::Update(super::update::Request::try_from(cmd.args)?)),
214 Some(super::update::Schema::RequestSchema(args)) =>
215 Ok(Request::UpdateRequestSchema(super::update::request_schema::Request::try_from(args)?)),
216 Some(super::update::Schema::ResponseSchema(args)) =>
217 Ok(Request::UpdateResponseSchema(super::update::response_schema::Request::try_from(args)?)),
218 },
219 Subcommand::Viewer { command } =>
220 Ok(Request::Viewer(super::viewer::Request::try_from(command)?)),
221 }
222 }
223}
224
225impl TryFrom<Command> for Request {
226 type Error = super::FromArgsError;
227 fn try_from(command: Command) -> Result<Self, Self::Error> {
228 match (command.request, command.command) {
229 (Some(json), _) => {
234 let de = &mut serde_json::Deserializer::from_str(&json);
235 serde_path_to_error::deserialize(de)
236 .map_err(|e| super::FromArgsError::json("request", e))
237 }
238 (None, Some(subcommand)) => Request::try_from(subcommand),
239 (None, None) => Err(super::FromArgsError::path_parse(
242 "command",
243 "a command path or --request is required".to_string(),
244 )),
245 }
246 }
247}
248
249impl super::CommandRequest for Request {
250 fn request_base(&self) -> &crate::cli::command::RequestBase {
251 match self {
252 Request::Agents(inner) => inner.request_base(),
253 Request::Api(inner) => inner.request_base(),
254 Request::Daemon(inner) => inner.request_base(),
255 Request::Db(inner) => inner.request_base(),
256 Request::Functions(inner) => inner.request_base(),
257 Request::KillAll(inner) => inner.request_base(),
258 Request::KillAllRequestSchema(inner) => inner.request_base(),
259 Request::KillAllResponseSchema(inner) => inner.request_base(),
260 Request::Mcp(inner) => inner.request_base(),
261 Request::Plugins(inner) => inner.request_base(),
262 Request::Python(inner) => inner.request_base(),
263 Request::PythonRequestSchema(inner) => inner.request_base(),
264 Request::PythonResponseSchema(inner) => inner.request_base(),
265 Request::Swarms(inner) => inner.request_base(),
266 Request::Tools(inner) => inner.request_base(),
267 Request::Update(inner) => inner.request_base(),
268 Request::UpdateRequestSchema(inner) => inner.request_base(),
269 Request::UpdateResponseSchema(inner) => inner.request_base(),
270 Request::Viewer(inner) => inner.request_base(),
271 }
272 }
273
274 fn request_base_mut(&mut self) -> Option<&mut crate::cli::command::RequestBase> {
275 match self {
276 Request::Agents(inner) => inner.request_base_mut(),
277 Request::Api(inner) => inner.request_base_mut(),
278 Request::Daemon(inner) => inner.request_base_mut(),
279 Request::Db(inner) => inner.request_base_mut(),
280 Request::Functions(inner) => inner.request_base_mut(),
281 Request::KillAll(inner) => inner.request_base_mut(),
282 Request::KillAllRequestSchema(inner) => inner.request_base_mut(),
283 Request::KillAllResponseSchema(inner) => inner.request_base_mut(),
284 Request::Mcp(inner) => inner.request_base_mut(),
285 Request::Plugins(inner) => inner.request_base_mut(),
286 Request::Python(inner) => inner.request_base_mut(),
287 Request::PythonRequestSchema(inner) => inner.request_base_mut(),
288 Request::PythonResponseSchema(inner) => inner.request_base_mut(),
289 Request::Swarms(inner) => inner.request_base_mut(),
290 Request::Tools(inner) => inner.request_base_mut(),
291 Request::Update(inner) => inner.request_base_mut(),
292 Request::UpdateRequestSchema(inner) => inner.request_base_mut(),
293 Request::UpdateResponseSchema(inner) => inner.request_base_mut(),
294 Request::Viewer(inner) => inner.request_base_mut(),
295 }
296 }
297}
298
299#[cfg(feature = "cli-executor")]
300pub async fn execute<E: super::CommandExecutor>(
301 executor: &E,
302 request: Request,
303
304 agent_arguments: Option<&crate::cli::command::AgentArguments>,
305 ) -> Result<
306 std::pin::Pin<Box<dyn futures::Stream<Item = Result<ResponseItem, E::Error>> + Send>>,
307 E::Error,
308> {
309 use futures::StreamExt;
310 let stream: std::pin::Pin<Box<dyn futures::Stream<Item = Result<ResponseItem, E::Error>> + Send>> =
311 match request {
312 Request::Agents(req) => {
313 let inner = super::agents::execute(executor, req, agent_arguments).await?;
314 Box::pin(inner.map(|r| r.map(ResponseItem::Agents)))
315 }
316 Request::Api(req) => {
317 let inner = super::api::execute(executor, req, agent_arguments).await?;
318 Box::pin(inner.map(|r| r.map(ResponseItem::Api)))
319 }
320 Request::Daemon(req) => {
321 let inner = super::daemon::execute(executor, req, agent_arguments).await?;
322 Box::pin(inner.map(|r| r.map(ResponseItem::Daemon)))
323 }
324 Request::Db(req) => {
325 let inner = super::db::execute(executor, req, agent_arguments).await?;
326 Box::pin(inner.map(|r| r.map(ResponseItem::Db)))
327 }
328 Request::Functions(req) => {
329 let inner = super::functions::execute(executor, req, agent_arguments).await?;
330 Box::pin(inner.map(|r| r.map(ResponseItem::Functions)))
331 }
332 Request::KillAll(req) => {
333 let value = super::kill_all::execute(executor, req, agent_arguments).await?;
334 Box::pin(super::StreamOnce::new(Ok(ResponseItem::KillAll(value))))
335 }
336 Request::KillAllRequestSchema(req) => {
337 let value = super::kill_all::request_schema::execute(executor, req, agent_arguments).await?;
338 Box::pin(super::StreamOnce::new(Ok(ResponseItem::KillAllRequestSchema(value))))
339 }
340 Request::KillAllResponseSchema(req) => {
341 let value = super::kill_all::response_schema::execute(executor, req, agent_arguments).await?;
342 Box::pin(super::StreamOnce::new(Ok(ResponseItem::KillAllResponseSchema(value))))
343 }
344 Request::Mcp(req) => {
345 let inner = super::mcp::execute(executor, req, agent_arguments).await?;
346 Box::pin(inner.map(|r| r.map(ResponseItem::Mcp)))
347 }
348 Request::Plugins(req) => {
349 let inner = super::plugins::execute(executor, req, agent_arguments).await?;
350 Box::pin(inner.map(|r| r.map(ResponseItem::Plugins)))
351 }
352 Request::Python(req) => {
353 let value = super::python::execute(executor, req, agent_arguments).await?;
354 Box::pin(super::StreamOnce::new(Ok(ResponseItem::Python(value))))
355 }
356 Request::PythonRequestSchema(req) => {
357 let value = super::python::request_schema::execute(executor, req, agent_arguments).await?;
358 Box::pin(super::StreamOnce::new(Ok(ResponseItem::PythonRequestSchema(value))))
359 }
360 Request::PythonResponseSchema(req) => {
361 let value = super::python::response_schema::execute(executor, req, agent_arguments).await?;
362 Box::pin(super::StreamOnce::new(Ok(ResponseItem::PythonResponseSchema(value))))
363 }
364 Request::Swarms(req) => {
365 let inner = super::swarms::execute(executor, req, agent_arguments).await?;
366 Box::pin(inner.map(|r| r.map(ResponseItem::Swarms)))
367 }
368 Request::Tools(req) => {
369 let inner = super::tools::execute(executor, req, agent_arguments).await?;
370 Box::pin(inner.map(|r| r.map(ResponseItem::Tools)))
371 }
372 Request::Update(req) => {
373 let inner = super::update::execute(executor, req, agent_arguments).await?;
374 Box::pin(inner.map(|r| r.map(ResponseItem::Update)))
375 }
376 Request::UpdateRequestSchema(req) => {
377 let value = super::update::request_schema::execute(executor, req, agent_arguments).await?;
378 Box::pin(super::StreamOnce::new(Ok(ResponseItem::UpdateRequestSchema(value))))
379 }
380 Request::UpdateResponseSchema(req) => {
381 let value = super::update::response_schema::execute(executor, req, agent_arguments).await?;
382 Box::pin(super::StreamOnce::new(Ok(ResponseItem::UpdateResponseSchema(value))))
383 }
384 Request::Viewer(req) => {
385 let inner = super::viewer::execute(executor, req, agent_arguments).await?;
386 Box::pin(inner.map(|r| r.map(ResponseItem::Viewer)))
387 }
388 };
389 Ok(stream)
390}
391
392#[cfg(feature = "cli-executor")]
393pub async fn execute_transform<E: super::CommandExecutor>(
394 executor: &E,
395 request: Request,
396 transform: crate::cli::command::Transform,
397
398 agent_arguments: Option<&crate::cli::command::AgentArguments>,
399 ) -> Result<
400 std::pin::Pin<Box<dyn futures::Stream<Item = Result<serde_json::Value, E::Error>> + Send>>,
401 E::Error,
402> {
403 let stream: std::pin::Pin<Box<dyn futures::Stream<Item = Result<serde_json::Value, E::Error>> + Send>> =
404 match request {
405 Request::Agents(req) => {
406 let inner = super::agents::execute_transform(executor, req, transform, agent_arguments).await?;
407 Box::pin(inner)
408 }
409 Request::Api(req) => {
410 let inner = super::api::execute_transform(executor, req, transform, agent_arguments).await?;
411 Box::pin(inner)
412 }
413 Request::Daemon(req) => {
414 let inner = super::daemon::execute_transform(executor, req, transform, agent_arguments).await?;
415 Box::pin(inner)
416 }
417 Request::Db(req) => {
418 let inner = super::db::execute_transform(executor, req, transform, agent_arguments).await?;
419 Box::pin(inner)
420 }
421 Request::Functions(req) => {
422 let inner = super::functions::execute_transform(executor, req, transform, agent_arguments).await?;
423 Box::pin(inner)
424 }
425 Request::KillAll(req) => {
426 let value = super::kill_all::execute_transform(executor, req, transform, agent_arguments).await?;
427 Box::pin(super::StreamOnce::new(Ok(value)))
428 }
429 Request::KillAllRequestSchema(req) => {
430 let value = super::kill_all::request_schema::execute_transform(executor, req, transform, agent_arguments).await?;
431 Box::pin(super::StreamOnce::new(Ok(value)))
432 }
433 Request::KillAllResponseSchema(req) => {
434 let value = super::kill_all::response_schema::execute_transform(executor, req, transform, agent_arguments).await?;
435 Box::pin(super::StreamOnce::new(Ok(value)))
436 }
437 Request::Mcp(req) => {
438 let inner = super::mcp::execute_transform(executor, req, transform, agent_arguments).await?;
439 Box::pin(inner)
440 }
441 Request::Plugins(req) => {
442 let inner = super::plugins::execute_transform(executor, req, transform, agent_arguments).await?;
443 Box::pin(inner)
444 }
445 Request::Python(req) => {
446 let value = super::python::execute_transform(executor, req, transform, agent_arguments).await?;
447 Box::pin(super::StreamOnce::new(Ok(value)))
448 }
449 Request::PythonRequestSchema(req) => {
450 let value = super::python::request_schema::execute_transform(executor, req, transform, agent_arguments).await?;
451 Box::pin(super::StreamOnce::new(Ok(value)))
452 }
453 Request::PythonResponseSchema(req) => {
454 let value = super::python::response_schema::execute_transform(executor, req, transform, agent_arguments).await?;
455 Box::pin(super::StreamOnce::new(Ok(value)))
456 }
457 Request::Swarms(req) => {
458 let inner = super::swarms::execute_transform(executor, req, transform, agent_arguments).await?;
459 Box::pin(inner)
460 }
461 Request::Tools(req) => {
462 let inner = super::tools::execute_transform(executor, req, transform, agent_arguments).await?;
463 Box::pin(inner)
464 }
465 Request::Update(req) => {
466 let inner = super::update::execute_transform(executor, req, transform, agent_arguments).await?;
467 Box::pin(inner)
468 }
469 Request::UpdateRequestSchema(req) => {
470 let value = super::update::request_schema::execute_transform(executor, req, transform, agent_arguments).await?;
471 Box::pin(super::StreamOnce::new(Ok(value)))
472 }
473 Request::UpdateResponseSchema(req) => {
474 let value = super::update::response_schema::execute_transform(executor, req, transform, agent_arguments).await?;
475 Box::pin(super::StreamOnce::new(Ok(value)))
476 }
477 Request::Viewer(req) => {
478 let inner = super::viewer::execute_transform(executor, req, transform, agent_arguments).await?;
479 Box::pin(inner)
480 }
481 };
482 Ok(stream)
483}
484
485pub fn parse_request(args: &[String]) -> Result<Request, ParseError> {
500 let command = if args.first().map(String::as_str) == Some("objectiveai") {
501 <Command as clap::Parser>::try_parse_from(args)?
502 } else {
503 let argv = std::iter::once("objectiveai".to_string())
504 .chain(args.iter().cloned());
505 <Command as clap::Parser>::try_parse_from(argv)?
506 };
507 Ok(Request::try_from(command)?)
508}
509
510#[derive(clap::Parser)]
516#[command(
517 name = "objectiveai",
518 args_conflicts_with_subcommands = true,
519 arg_required_else_help = true
520)]
521pub struct Command {
522 #[arg(long, value_name = "JSON")]
525 pub request: Option<String>,
526 #[command(subcommand)]
527 pub command: Option<Subcommand>,
528}
529
530#[derive(Debug)]
536pub enum ParseError {
537 Clap(clap::Error),
538 FromArgs(super::FromArgsError),
539}
540
541impl std::fmt::Display for ParseError {
542 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
543 match self {
544 ParseError::Clap(e) => write!(f, "{e}"),
545 ParseError::FromArgs(e) => write!(f, "{e}"),
546 }
547 }
548}
549
550impl std::error::Error for ParseError {}
551
552impl From<clap::Error> for ParseError {
553 fn from(e: clap::Error) -> Self {
554 ParseError::Clap(e)
555 }
556}
557
558impl From<super::FromArgsError> for ParseError {
559 fn from(e: super::FromArgsError) -> Self {
560 ParseError::FromArgs(e)
561 }
562}