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