Skip to main content

objectiveai_sdk/cli/command/agents/
mod.rs

1pub mod get;
2pub mod list;
3pub mod me;
4pub mod message;
5pub mod publish;
6pub mod read;
7pub mod spawn;
8
9#[derive(clap::Subcommand)]
10pub enum Command {
11    /// Get an agent by remote path or favorite name.
12    Get(get::Command),
13    /// List agents — `active` (direct children of the calling agent) or
14    /// `available` (remote agents by source).
15    List {
16        #[command(subcommand)]
17        command: list::Command,
18    },
19    /// Return the configured self agent id.
20    Me(me::Command),
21    /// Deliver a message to a running spawned agent (or resume its most
22    /// recent completion via continuation if it's dormant).
23    Message(message::Command),
24    /// Publish an agent to the local filesystem.
25    Publish(publish::Command),
26    /// Read queue items.
27    Read {
28        #[command(subcommand)]
29        command: read::Command,
30    },
31    /// Spawn an agent completion (open a streaming run as a child of this caller).
32    Spawn(spawn::Command),
33}
34
35#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, schemars::JsonSchema)]
36#[serde(untagged)]
37#[schemars(rename = "cli.command.agents.Request")]
38pub enum Request {
39    #[schemars(title = "Get")]
40    Get(get::Request),
41    #[schemars(title = "GetRequestSchema")]
42    GetRequestSchema(get::request_schema::Request),
43    #[schemars(title = "GetResponseSchema")]
44    GetResponseSchema(get::response_schema::Request),
45    #[schemars(title = "List")]
46    List(list::Request),
47    #[schemars(title = "Me")]
48    Me(me::Request),
49    #[schemars(title = "MeRequestSchema")]
50    MeRequestSchema(me::request_schema::Request),
51    #[schemars(title = "MeResponseSchema")]
52    MeResponseSchema(me::response_schema::Request),
53    #[schemars(title = "Message")]
54    Message(message::Request),
55    #[schemars(title = "MessageRequestSchema")]
56    MessageRequestSchema(message::request_schema::Request),
57    #[schemars(title = "MessageResponseSchema")]
58    MessageResponseSchema(message::response_schema::Request),
59    #[schemars(title = "Publish")]
60    Publish(publish::Request),
61    #[schemars(title = "PublishRequestSchema")]
62    PublishRequestSchema(publish::request_schema::Request),
63    #[schemars(title = "PublishResponseSchema")]
64    PublishResponseSchema(publish::response_schema::Request),
65    #[schemars(title = "Read")]
66    Read(read::Request),
67    #[schemars(title = "Spawn")]
68    Spawn(spawn::Request),
69    #[schemars(title = "SpawnRequestSchema")]
70    SpawnRequestSchema(spawn::request_schema::Request),
71    #[schemars(title = "SpawnResponseSchema")]
72    SpawnResponseSchema(spawn::response_schema::Request),
73}
74
75// Exempt from json-schema coverage: tier aggregate (see the root
76// `ResponseItem` in command.rs - TS7056).
77#[objectiveai_sdk_macros::json_schema_ignore]
78#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, schemars::JsonSchema)]
79#[schemars(rename = "cli.command.agents.ResponseItem")]
80#[serde(untagged)]
81pub enum ResponseItem {
82    #[schemars(title = "Get")]
83    Get(get::Response),
84    #[schemars(title = "GetRequestSchema")]
85    GetRequestSchema(get::request_schema::Response),
86    #[schemars(title = "GetResponseSchema")]
87    GetResponseSchema(get::response_schema::Response),
88    #[schemars(title = "List")]
89    List(list::ResponseItem),
90    #[schemars(title = "Me")]
91    Me(me::Response),
92    #[schemars(title = "MeRequestSchema")]
93    MeRequestSchema(me::request_schema::Response),
94    #[schemars(title = "MeResponseSchema")]
95    MeResponseSchema(me::response_schema::Response),
96    #[schemars(title = "Message")]
97    Message(message::Response),
98    #[schemars(title = "MessageRequestSchema")]
99    MessageRequestSchema(message::request_schema::Response),
100    #[schemars(title = "MessageResponseSchema")]
101    MessageResponseSchema(message::response_schema::Response),
102    #[schemars(title = "Publish")]
103    Publish(publish::Response),
104    #[schemars(title = "PublishRequestSchema")]
105    PublishRequestSchema(publish::request_schema::Response),
106    #[schemars(title = "PublishResponseSchema")]
107    PublishResponseSchema(publish::response_schema::Response),
108    #[schemars(title = "Read")]
109    Read(read::ResponseItem),
110    #[schemars(title = "Spawn")]
111    Spawn(spawn::ResponseItem),
112    #[schemars(title = "SpawnRequestSchema")]
113    SpawnRequestSchema(spawn::request_schema::Response),
114    #[schemars(title = "SpawnResponseSchema")]
115    SpawnResponseSchema(spawn::response_schema::Response),
116}
117
118#[cfg(feature = "mcp")]
119impl crate::cli::command::CommandResponse for ResponseItem {
120    fn into_mcp(self) -> crate::cli::command::McpResponseItem {
121        match self {
122            ResponseItem::Get(v) => v.into_mcp(),
123            ResponseItem::GetRequestSchema(v) => v.into_mcp(),
124            ResponseItem::GetResponseSchema(v) => v.into_mcp(),
125            ResponseItem::List(v) => v.into_mcp(),
126            ResponseItem::Me(v) => v.into_mcp(),
127            ResponseItem::MeRequestSchema(v) => v.into_mcp(),
128            ResponseItem::MeResponseSchema(v) => v.into_mcp(),
129            ResponseItem::Message(v) => v.into_mcp(),
130            ResponseItem::MessageRequestSchema(v) => v.into_mcp(),
131            ResponseItem::MessageResponseSchema(v) => v.into_mcp(),
132            ResponseItem::Publish(v) => v.into_mcp(),
133            ResponseItem::PublishRequestSchema(v) => v.into_mcp(),
134            ResponseItem::PublishResponseSchema(v) => v.into_mcp(),
135            ResponseItem::Read(v) => v.into_mcp(),
136            ResponseItem::Spawn(v) => v.into_mcp(),
137            ResponseItem::SpawnRequestSchema(v) => v.into_mcp(),
138            ResponseItem::SpawnResponseSchema(v) => v.into_mcp(),
139        }
140    }
141}
142
143impl TryFrom<Command> for Request {
144    type Error = crate::cli::command::FromArgsError;
145    fn try_from(command: Command) -> Result<Self, Self::Error> {
146        match command {
147            Command::Get(cmd) => match cmd.schema {
148                None => Ok(Request::Get(get::Request::try_from(cmd.args)?)),
149                Some(get::Schema::RequestSchema(args)) =>
150                    Ok(Request::GetRequestSchema(get::request_schema::Request::try_from(args)?)),
151                Some(get::Schema::ResponseSchema(args)) =>
152                    Ok(Request::GetResponseSchema(get::response_schema::Request::try_from(args)?)),
153            },
154            Command::List { command } =>
155                Ok(Request::List(list::Request::try_from(command)?)),
156            Command::Me(cmd) => match cmd.schema {
157                None => Ok(Request::Me(me::Request::try_from(cmd.args)?)),
158                Some(me::Schema::RequestSchema(args)) =>
159                    Ok(Request::MeRequestSchema(me::request_schema::Request::try_from(args)?)),
160                Some(me::Schema::ResponseSchema(args)) =>
161                    Ok(Request::MeResponseSchema(me::response_schema::Request::try_from(args)?)),
162            },
163            Command::Message(cmd) => match cmd.schema {
164                None => Ok(Request::Message(message::Request::try_from(cmd.args)?)),
165                Some(message::Schema::RequestSchema(args)) =>
166                    Ok(Request::MessageRequestSchema(message::request_schema::Request::try_from(args)?)),
167                Some(message::Schema::ResponseSchema(args)) =>
168                    Ok(Request::MessageResponseSchema(message::response_schema::Request::try_from(args)?)),
169            },
170            Command::Publish(cmd) => match cmd.schema {
171                None => Ok(Request::Publish(publish::Request::try_from(cmd.args)?)),
172                Some(publish::Schema::RequestSchema(args)) =>
173                    Ok(Request::PublishRequestSchema(publish::request_schema::Request::try_from(args)?)),
174                Some(publish::Schema::ResponseSchema(args)) =>
175                    Ok(Request::PublishResponseSchema(publish::response_schema::Request::try_from(args)?)),
176            },
177            Command::Read { command } =>
178                Ok(Request::Read(read::Request::try_from(command)?)),
179            Command::Spawn(cmd) => match cmd.schema {
180                None => Ok(Request::Spawn(spawn::Request::try_from(cmd.args)?)),
181                Some(spawn::Schema::RequestSchema(args)) =>
182                    Ok(Request::SpawnRequestSchema(spawn::request_schema::Request::try_from(args)?)),
183                Some(spawn::Schema::ResponseSchema(args)) =>
184                    Ok(Request::SpawnResponseSchema(spawn::response_schema::Request::try_from(args)?)),
185            },
186        }
187    }
188}
189
190impl crate::cli::command::CommandRequest for Request {
191    fn into_command(&self) -> Vec<String> {
192        match self {
193            Request::Get(inner) => inner.into_command(),
194            Request::GetRequestSchema(inner) => inner.into_command(),
195            Request::GetResponseSchema(inner) => inner.into_command(),
196            Request::List(inner) => inner.into_command(),
197            Request::Me(inner) => inner.into_command(),
198            Request::MeRequestSchema(inner) => inner.into_command(),
199            Request::MeResponseSchema(inner) => inner.into_command(),
200            Request::Message(inner) => inner.into_command(),
201            Request::MessageRequestSchema(inner) => inner.into_command(),
202            Request::MessageResponseSchema(inner) => inner.into_command(),
203            Request::Publish(inner) => inner.into_command(),
204            Request::PublishRequestSchema(inner) => inner.into_command(),
205            Request::PublishResponseSchema(inner) => inner.into_command(),
206            Request::Read(inner) => inner.into_command(),
207            Request::Spawn(inner) => inner.into_command(),
208            Request::SpawnRequestSchema(inner) => inner.into_command(),
209            Request::SpawnResponseSchema(inner) => inner.into_command(),
210        }
211    }
212}
213
214#[cfg(feature = "cli-executor")]
215pub async fn execute<E: crate::cli::command::CommandExecutor>(
216    executor: &E,
217    request: Request,
218
219        agent_arguments: Option<&crate::cli::command::AgentArguments>,
220    ) -> Result<
221    std::pin::Pin<Box<dyn futures::Stream<Item = Result<ResponseItem, E::Error>> + Send>>,
222    E::Error,
223> {
224    use futures::StreamExt;
225    let stream: std::pin::Pin<Box<dyn futures::Stream<Item = Result<ResponseItem, E::Error>> + Send>> =
226        match request {
227            Request::Get(req) => {
228                let value = get::execute(executor, req, agent_arguments).await?;
229                Box::pin(crate::cli::command::StreamOnce::new(Ok(
230                    ResponseItem::Get(value),
231                )))
232            }
233            Request::GetRequestSchema(req) => {
234                let value = get::request_schema::execute(executor, req, agent_arguments).await?;
235                Box::pin(crate::cli::command::StreamOnce::new(Ok(
236                    ResponseItem::GetRequestSchema(value),
237                )))
238            }
239            Request::GetResponseSchema(req) => {
240                let value = get::response_schema::execute(executor, req, agent_arguments).await?;
241                Box::pin(crate::cli::command::StreamOnce::new(Ok(
242                    ResponseItem::GetResponseSchema(value),
243                )))
244            }
245            Request::List(req) => {
246                let inner = list::execute(executor, req, agent_arguments).await?;
247                Box::pin(inner.map(|r| r.map(ResponseItem::List)))
248            }
249            Request::Me(req) => {
250                let value = me::execute(executor, req, agent_arguments).await?;
251                Box::pin(crate::cli::command::StreamOnce::new(Ok(
252                    ResponseItem::Me(value),
253                )))
254            }
255            Request::MeRequestSchema(req) => {
256                let value = me::request_schema::execute(executor, req, agent_arguments).await?;
257                Box::pin(crate::cli::command::StreamOnce::new(Ok(
258                    ResponseItem::MeRequestSchema(value),
259                )))
260            }
261            Request::MeResponseSchema(req) => {
262                let value = me::response_schema::execute(executor, req, agent_arguments).await?;
263                Box::pin(crate::cli::command::StreamOnce::new(Ok(
264                    ResponseItem::MeResponseSchema(value),
265                )))
266            }
267            Request::Message(req) => {
268                let value = message::execute(executor, req, agent_arguments).await?;
269                Box::pin(crate::cli::command::StreamOnce::new(Ok(
270                    ResponseItem::Message(value),
271                )))
272            }
273            Request::MessageRequestSchema(req) => {
274                let value = message::request_schema::execute(executor, req, agent_arguments).await?;
275                Box::pin(crate::cli::command::StreamOnce::new(Ok(
276                    ResponseItem::MessageRequestSchema(value),
277                )))
278            }
279            Request::MessageResponseSchema(req) => {
280                let value = message::response_schema::execute(executor, req, agent_arguments).await?;
281                Box::pin(crate::cli::command::StreamOnce::new(Ok(
282                    ResponseItem::MessageResponseSchema(value),
283                )))
284            }
285            Request::Publish(req) => {
286                let value = publish::execute(executor, req, agent_arguments).await?;
287                Box::pin(crate::cli::command::StreamOnce::new(Ok(
288                    ResponseItem::Publish(value),
289                )))
290            }
291            Request::PublishRequestSchema(req) => {
292                let value = publish::request_schema::execute(executor, req, agent_arguments).await?;
293                Box::pin(crate::cli::command::StreamOnce::new(Ok(
294                    ResponseItem::PublishRequestSchema(value),
295                )))
296            }
297            Request::PublishResponseSchema(req) => {
298                let value = publish::response_schema::execute(executor, req, agent_arguments).await?;
299                Box::pin(crate::cli::command::StreamOnce::new(Ok(
300                    ResponseItem::PublishResponseSchema(value),
301                )))
302            }
303            Request::Read(req) => {
304                let inner = read::execute(executor, req, agent_arguments).await?;
305                Box::pin(inner.map(|r| r.map(ResponseItem::Read)))
306            }
307            Request::Spawn(req) => {
308                let want_streaming = req
309                    .dangerous_advanced
310                    .as_ref()
311                    .and_then(|a| a.stream)
312                    .unwrap_or(false);
313                if want_streaming {
314                    let inner = spawn::execute_streaming(executor, req, agent_arguments).await?;
315                    Box::pin(inner.map(|r| r.map(ResponseItem::Spawn)))
316                } else {
317                    let value = spawn::execute(executor, req, agent_arguments).await?;
318                    Box::pin(crate::cli::command::StreamOnce::new(Ok(
319                        ResponseItem::Spawn(spawn::ResponseItem::Id(value)),
320                    )))
321                }
322            }
323            Request::SpawnRequestSchema(req) => {
324                let value = spawn::request_schema::execute(executor, req, agent_arguments).await?;
325                Box::pin(crate::cli::command::StreamOnce::new(Ok(
326                    ResponseItem::SpawnRequestSchema(value),
327                )))
328            }
329            Request::SpawnResponseSchema(req) => {
330                let value = spawn::response_schema::execute(executor, req, agent_arguments).await?;
331                Box::pin(crate::cli::command::StreamOnce::new(Ok(
332                    ResponseItem::SpawnResponseSchema(value),
333                )))
334            }
335        };
336    Ok(stream)
337}
338
339#[cfg(feature = "cli-executor")]
340pub async fn execute_jq<E: crate::cli::command::CommandExecutor>(
341    executor: &E,
342    request: Request,
343    jq: String,
344
345        agent_arguments: Option<&crate::cli::command::AgentArguments>,
346    ) -> Result<
347    std::pin::Pin<Box<dyn futures::Stream<Item = Result<serde_json::Value, E::Error>> + Send>>,
348    E::Error,
349> {
350    let stream: std::pin::Pin<Box<dyn futures::Stream<Item = Result<serde_json::Value, E::Error>> + Send>> =
351        match request {
352            Request::Get(req) => {
353                let value = get::execute_jq(executor, req, jq, agent_arguments).await?;
354                Box::pin(crate::cli::command::StreamOnce::new(Ok(value)))
355            }
356            Request::GetRequestSchema(req) => {
357                let value = get::request_schema::execute_jq(executor, req, jq, agent_arguments).await?;
358                Box::pin(crate::cli::command::StreamOnce::new(Ok(value)))
359            }
360            Request::GetResponseSchema(req) => {
361                let value = get::response_schema::execute_jq(executor, req, jq, agent_arguments).await?;
362                Box::pin(crate::cli::command::StreamOnce::new(Ok(value)))
363            }
364            Request::List(req) => {
365                let inner = list::execute_jq(executor, req, jq, agent_arguments).await?;
366                Box::pin(inner)
367            }
368            Request::Me(req) => {
369                let value = me::execute_jq(executor, req, jq, agent_arguments).await?;
370                Box::pin(crate::cli::command::StreamOnce::new(Ok(value)))
371            }
372            Request::MeRequestSchema(req) => {
373                let value = me::request_schema::execute_jq(executor, req, jq, agent_arguments).await?;
374                Box::pin(crate::cli::command::StreamOnce::new(Ok(value)))
375            }
376            Request::MeResponseSchema(req) => {
377                let value = me::response_schema::execute_jq(executor, req, jq, agent_arguments).await?;
378                Box::pin(crate::cli::command::StreamOnce::new(Ok(value)))
379            }
380            Request::Message(req) => {
381                let value = message::execute_jq(executor, req, jq, agent_arguments).await?;
382                Box::pin(crate::cli::command::StreamOnce::new(Ok(value)))
383            }
384            Request::MessageRequestSchema(req) => {
385                let value = message::request_schema::execute_jq(executor, req, jq, agent_arguments).await?;
386                Box::pin(crate::cli::command::StreamOnce::new(Ok(value)))
387            }
388            Request::MessageResponseSchema(req) => {
389                let value = message::response_schema::execute_jq(executor, req, jq, agent_arguments).await?;
390                Box::pin(crate::cli::command::StreamOnce::new(Ok(value)))
391            }
392            Request::Publish(req) => {
393                let value = publish::execute_jq(executor, req, jq, agent_arguments).await?;
394                Box::pin(crate::cli::command::StreamOnce::new(Ok(value)))
395            }
396            Request::PublishRequestSchema(req) => {
397                let value = publish::request_schema::execute_jq(executor, req, jq, agent_arguments).await?;
398                Box::pin(crate::cli::command::StreamOnce::new(Ok(value)))
399            }
400            Request::PublishResponseSchema(req) => {
401                let value = publish::response_schema::execute_jq(executor, req, jq, agent_arguments).await?;
402                Box::pin(crate::cli::command::StreamOnce::new(Ok(value)))
403            }
404            Request::Read(req) => {
405                let inner = read::execute_jq(executor, req, jq, agent_arguments).await?;
406                Box::pin(inner)
407            }
408            Request::Spawn(req) => {
409                let want_streaming = req
410                    .dangerous_advanced
411                    .as_ref()
412                    .and_then(|a| a.stream)
413                    .unwrap_or(false);
414                if want_streaming {
415                    let inner = spawn::execute_streaming_jq(executor, req, jq, agent_arguments).await?;
416                    Box::pin(inner)
417                } else {
418                    let value = spawn::execute_jq(executor, req, jq, agent_arguments).await?;
419                    Box::pin(crate::cli::command::StreamOnce::new(Ok(value)))
420                }
421            }
422            Request::SpawnRequestSchema(req) => {
423                let value = spawn::request_schema::execute_jq(executor, req, jq, agent_arguments).await?;
424                Box::pin(crate::cli::command::StreamOnce::new(Ok(value)))
425            }
426            Request::SpawnResponseSchema(req) => {
427                let value = spawn::response_schema::execute_jq(executor, req, jq, agent_arguments).await?;
428                Box::pin(crate::cli::command::StreamOnce::new(Ok(value)))
429            }
430        };
431    Ok(stream)
432}