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