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