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 request_base(&self) -> &crate::cli::command::RequestBase {
101        match self {
102            Request::Get(inner) => inner.request_base(),
103            Request::GetRequestSchema(inner) => inner.request_base(),
104            Request::GetResponseSchema(inner) => inner.request_base(),
105            Request::List(inner) => inner.request_base(),
106            Request::ListRequestSchema(inner) => inner.request_base(),
107            Request::ListResponseSchema(inner) => inner.request_base(),
108        }
109    }
110
111    fn request_base_mut(&mut self) -> Option<&mut crate::cli::command::RequestBase> {
112        match self {
113            Request::Get(inner) => inner.request_base_mut(),
114            Request::GetRequestSchema(inner) => inner.request_base_mut(),
115            Request::GetResponseSchema(inner) => inner.request_base_mut(),
116            Request::List(inner) => inner.request_base_mut(),
117            Request::ListRequestSchema(inner) => inner.request_base_mut(),
118            Request::ListResponseSchema(inner) => inner.request_base_mut(),
119        }
120    }
121}
122
123#[cfg(feature = "cli-executor")]
124pub async fn execute<E: crate::cli::command::CommandExecutor>(
125    executor: &E,
126    request: Request,
127    agent_arguments: Option<&crate::cli::command::AgentArguments>,
128) -> Result<
129    std::pin::Pin<Box<dyn futures::Stream<Item = Result<ResponseItem, E::Error>> + Send>>,
130    E::Error,
131> {
132    use futures::StreamExt;
133    let stream: std::pin::Pin<
134        Box<dyn futures::Stream<Item = Result<ResponseItem, E::Error>> + Send>,
135    > = match request {
136        Request::Get(req) => {
137            let inner = get::execute(executor, req, agent_arguments).await?;
138            Box::pin(inner.map(|r| r.map(ResponseItem::Get)))
139        }
140        Request::GetRequestSchema(req) => {
141            let value = get::request_schema::execute(executor, req, agent_arguments).await?;
142            Box::pin(crate::cli::command::StreamOnce::new(Ok(
143                ResponseItem::GetRequestSchema(value),
144            )))
145        }
146        Request::GetResponseSchema(req) => {
147            let value = get::response_schema::execute(executor, req, agent_arguments).await?;
148            Box::pin(crate::cli::command::StreamOnce::new(Ok(
149                ResponseItem::GetResponseSchema(value),
150            )))
151        }
152        Request::List(req) => {
153            let inner = list::execute(executor, req, agent_arguments).await?;
154            Box::pin(inner.map(|r| r.map(ResponseItem::List)))
155        }
156        Request::ListRequestSchema(req) => {
157            let value = list::request_schema::execute(executor, req, agent_arguments).await?;
158            Box::pin(crate::cli::command::StreamOnce::new(Ok(
159                ResponseItem::ListRequestSchema(value),
160            )))
161        }
162        Request::ListResponseSchema(req) => {
163            let value = list::response_schema::execute(executor, req, agent_arguments).await?;
164            Box::pin(crate::cli::command::StreamOnce::new(Ok(
165                ResponseItem::ListResponseSchema(value),
166            )))
167        }
168    };
169    Ok(stream)
170}
171
172#[cfg(feature = "cli-executor")]
173pub async fn execute_transform<E: crate::cli::command::CommandExecutor>(
174    executor: &E,
175    request: Request,
176    transform: crate::cli::command::Transform,
177    agent_arguments: Option<&crate::cli::command::AgentArguments>,
178) -> Result<
179    std::pin::Pin<Box<dyn futures::Stream<Item = Result<serde_json::Value, E::Error>> + Send>>,
180    E::Error,
181> {
182    let stream: std::pin::Pin<
183        Box<dyn futures::Stream<Item = Result<serde_json::Value, E::Error>> + Send>,
184    > = match request {
185        Request::Get(req) => {
186            let inner = get::execute_transform(executor, req, transform, agent_arguments).await?;
187            Box::pin(inner)
188        }
189        Request::GetRequestSchema(req) => {
190            let value =
191                get::request_schema::execute_transform(executor, req, transform, agent_arguments).await?;
192            Box::pin(crate::cli::command::StreamOnce::new(Ok(value)))
193        }
194        Request::GetResponseSchema(req) => {
195            let value =
196                get::response_schema::execute_transform(executor, req, transform, agent_arguments).await?;
197            Box::pin(crate::cli::command::StreamOnce::new(Ok(value)))
198        }
199        Request::List(req) => {
200            let inner = list::execute_transform(executor, req, transform, agent_arguments).await?;
201            Box::pin(inner)
202        }
203        Request::ListRequestSchema(req) => {
204            let value =
205                list::request_schema::execute_transform(executor, req, transform, agent_arguments).await?;
206            Box::pin(crate::cli::command::StreamOnce::new(Ok(value)))
207        }
208        Request::ListResponseSchema(req) => {
209            let value =
210                list::response_schema::execute_transform(executor, req, transform, agent_arguments).await?;
211            Box::pin(crate::cli::command::StreamOnce::new(Ok(value)))
212        }
213    };
214    Ok(stream)
215}