Skip to main content

objectiveai_sdk/cli/command/agents/instances/
mod.rs

1//! `agents instances` — caller-side handles that didn't earn their
2//! own top-level home under `agents`. Two leaves today:
3//!
4//! - `get` — per-agent aggregates for the exact resolved targets.
5//! - `list` — the direct children of the resolved targets.
6//!
7//! Historically this tier also owned `spawn`, `message`, and `read`;
8//! those moved up to `agents spawn`, `agents message`, and
9//! `agents logs read` respectively.
10
11use crate::cli::command::CommandRequest;
12
13pub mod get;
14pub mod list;
15
16#[derive(clap::Subcommand)]
17pub enum Command {
18    /// Per-agent aggregates for the exact resolved targets.
19    Get(get::Command),
20    /// List the direct children of the resolved targets.
21    List(list::Command),
22}
23
24#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, schemars::JsonSchema)]
25#[serde(untagged)]
26#[schemars(rename = "cli.command.agents.instances.Request")]
27pub enum Request {
28    #[schemars(title = "Get")]
29    Get(get::Request),
30    #[schemars(title = "GetRequestSchema")]
31    GetRequestSchema(get::request_schema::Request),
32    #[schemars(title = "GetResponseSchema")]
33    GetResponseSchema(get::response_schema::Request),
34    #[schemars(title = "List")]
35    List(list::Request),
36    #[schemars(title = "ListRequestSchema")]
37    ListRequestSchema(list::request_schema::Request),
38    #[schemars(title = "ListResponseSchema")]
39    ListResponseSchema(list::response_schema::Request),
40}
41
42// Exempt from json-schema coverage: tier aggregate (see the root
43// `ResponseItem` in command.rs - TS7056).
44#[objectiveai_sdk_macros::json_schema_ignore]
45#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, schemars::JsonSchema)]
46#[schemars(rename = "cli.command.agents.instances.ResponseItem")]
47#[serde(untagged)]
48pub enum ResponseItem {
49    #[schemars(title = "Get")]
50    Get(get::ResponseItem),
51    #[schemars(title = "GetRequestSchema")]
52    GetRequestSchema(get::request_schema::Response),
53    #[schemars(title = "GetResponseSchema")]
54    GetResponseSchema(get::response_schema::Response),
55    #[schemars(title = "List")]
56    List(list::ResponseItem),
57    #[schemars(title = "ListRequestSchema")]
58    ListRequestSchema(list::request_schema::Response),
59    #[schemars(title = "ListResponseSchema")]
60    ListResponseSchema(list::response_schema::Response),
61}
62
63#[cfg(feature = "mcp")]
64impl crate::cli::command::CommandResponse for ResponseItem {
65    fn into_mcp(self) -> crate::cli::command::McpResponseItem {
66        match self {
67            ResponseItem::Get(v) => v.into_mcp(),
68            ResponseItem::GetRequestSchema(v) => v.into_mcp(),
69            ResponseItem::GetResponseSchema(v) => v.into_mcp(),
70            ResponseItem::List(v) => v.into_mcp(),
71            ResponseItem::ListRequestSchema(v) => v.into_mcp(),
72            ResponseItem::ListResponseSchema(v) => v.into_mcp(),
73        }
74    }
75}
76
77impl TryFrom<Command> for Request {
78    type Error = crate::cli::command::FromArgsError;
79    fn try_from(command: Command) -> Result<Self, Self::Error> {
80        match command {
81            Command::Get(cmd) => match cmd.schema {
82                None => Ok(Request::Get(get::Request::try_from(cmd.args)?)),
83                Some(get::Schema::RequestSchema(args)) =>
84                    Ok(Request::GetRequestSchema(get::request_schema::Request::try_from(args)?)),
85                Some(get::Schema::ResponseSchema(args)) =>
86                    Ok(Request::GetResponseSchema(get::response_schema::Request::try_from(args)?)),
87            },
88            Command::List(cmd) => match cmd.schema {
89                None => Ok(Request::List(list::Request::try_from(cmd.args)?)),
90                Some(list::Schema::RequestSchema(args)) =>
91                    Ok(Request::ListRequestSchema(list::request_schema::Request::try_from(args)?)),
92                Some(list::Schema::ResponseSchema(args)) =>
93                    Ok(Request::ListResponseSchema(list::response_schema::Request::try_from(args)?)),
94            },
95        }
96    }
97}
98
99impl CommandRequest for Request {
100    fn into_command(&self) -> Vec<String> {
101        match self {
102            Request::Get(inner) => inner.into_command(),
103            Request::GetRequestSchema(inner) => inner.into_command(),
104            Request::GetResponseSchema(inner) => inner.into_command(),
105            Request::List(inner) => inner.into_command(),
106            Request::ListRequestSchema(inner) => inner.into_command(),
107            Request::ListResponseSchema(inner) => inner.into_command(),
108        }
109    }
110
111    fn request_base(&self) -> &crate::cli::command::RequestBase {
112        match self {
113            Request::Get(inner) => inner.request_base(),
114            Request::GetRequestSchema(inner) => inner.request_base(),
115            Request::GetResponseSchema(inner) => inner.request_base(),
116            Request::List(inner) => inner.request_base(),
117            Request::ListRequestSchema(inner) => inner.request_base(),
118            Request::ListResponseSchema(inner) => inner.request_base(),
119        }
120    }
121
122    fn request_base_mut(&mut self) -> Option<&mut crate::cli::command::RequestBase> {
123        match self {
124            Request::Get(inner) => inner.request_base_mut(),
125            Request::GetRequestSchema(inner) => inner.request_base_mut(),
126            Request::GetResponseSchema(inner) => inner.request_base_mut(),
127            Request::List(inner) => inner.request_base_mut(),
128            Request::ListRequestSchema(inner) => inner.request_base_mut(),
129            Request::ListResponseSchema(inner) => inner.request_base_mut(),
130        }
131    }
132}
133
134#[cfg(feature = "cli-executor")]
135pub async fn execute<E: crate::cli::command::CommandExecutor>(
136    executor: &E,
137    request: Request,
138    agent_arguments: Option<&crate::cli::command::AgentArguments>,
139) -> Result<
140    std::pin::Pin<Box<dyn futures::Stream<Item = Result<ResponseItem, E::Error>> + Send>>,
141    E::Error,
142> {
143    use futures::StreamExt;
144    let stream: std::pin::Pin<
145        Box<dyn futures::Stream<Item = Result<ResponseItem, E::Error>> + Send>,
146    > = match request {
147        Request::Get(req) => {
148            let inner = get::execute(executor, req, agent_arguments).await?;
149            Box::pin(inner.map(|r| r.map(ResponseItem::Get)))
150        }
151        Request::GetRequestSchema(req) => {
152            let value = get::request_schema::execute(executor, req, agent_arguments).await?;
153            Box::pin(crate::cli::command::StreamOnce::new(Ok(
154                ResponseItem::GetRequestSchema(value),
155            )))
156        }
157        Request::GetResponseSchema(req) => {
158            let value = get::response_schema::execute(executor, req, agent_arguments).await?;
159            Box::pin(crate::cli::command::StreamOnce::new(Ok(
160                ResponseItem::GetResponseSchema(value),
161            )))
162        }
163        Request::List(req) => {
164            let inner = list::execute(executor, req, agent_arguments).await?;
165            Box::pin(inner.map(|r| r.map(ResponseItem::List)))
166        }
167        Request::ListRequestSchema(req) => {
168            let value = list::request_schema::execute(executor, req, agent_arguments).await?;
169            Box::pin(crate::cli::command::StreamOnce::new(Ok(
170                ResponseItem::ListRequestSchema(value),
171            )))
172        }
173        Request::ListResponseSchema(req) => {
174            let value = list::response_schema::execute(executor, req, agent_arguments).await?;
175            Box::pin(crate::cli::command::StreamOnce::new(Ok(
176                ResponseItem::ListResponseSchema(value),
177            )))
178        }
179    };
180    Ok(stream)
181}
182
183#[cfg(feature = "cli-executor")]
184pub async fn execute_transform<E: crate::cli::command::CommandExecutor>(
185    executor: &E,
186    request: Request,
187    transform: crate::cli::command::Transform,
188    agent_arguments: Option<&crate::cli::command::AgentArguments>,
189) -> Result<
190    std::pin::Pin<Box<dyn futures::Stream<Item = Result<serde_json::Value, E::Error>> + Send>>,
191    E::Error,
192> {
193    let stream: std::pin::Pin<
194        Box<dyn futures::Stream<Item = Result<serde_json::Value, E::Error>> + Send>,
195    > = match request {
196        Request::Get(req) => {
197            let inner = get::execute_transform(executor, req, transform, agent_arguments).await?;
198            Box::pin(inner)
199        }
200        Request::GetRequestSchema(req) => {
201            let value =
202                get::request_schema::execute_transform(executor, req, transform, agent_arguments).await?;
203            Box::pin(crate::cli::command::StreamOnce::new(Ok(value)))
204        }
205        Request::GetResponseSchema(req) => {
206            let value =
207                get::response_schema::execute_transform(executor, req, transform, agent_arguments).await?;
208            Box::pin(crate::cli::command::StreamOnce::new(Ok(value)))
209        }
210        Request::List(req) => {
211            let inner = list::execute_transform(executor, req, transform, agent_arguments).await?;
212            Box::pin(inner)
213        }
214        Request::ListRequestSchema(req) => {
215            let value =
216                list::request_schema::execute_transform(executor, req, transform, agent_arguments).await?;
217            Box::pin(crate::cli::command::StreamOnce::new(Ok(value)))
218        }
219        Request::ListResponseSchema(req) => {
220            let value =
221                list::response_schema::execute_transform(executor, req, transform, agent_arguments).await?;
222            Box::pin(crate::cli::command::StreamOnce::new(Ok(value)))
223        }
224    };
225    Ok(stream)
226}