1use crate::cli::command::CommandRequest;
12
13pub mod config;
14pub mod kill;
15pub mod query;
16pub mod spawn;
17
18#[derive(clap::Subcommand)]
19pub enum Command {
20 Config {
21 #[command(subcommand)]
22 command: config::Command,
23 },
24 Kill(kill::Command),
27 Query(query::Command),
30 Spawn(spawn::Command),
34}
35
36#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, schemars::JsonSchema)]
37#[serde(untagged)]
38#[schemars(rename = "cli.command.db.Request")]
39pub enum Request {
40 #[schemars(title = "Config")]
41 Config(config::Request),
42 #[schemars(title = "Kill")]
43 Kill(kill::Request),
44 #[schemars(title = "KillRequestSchema")]
45 KillRequestSchema(kill::request_schema::Request),
46 #[schemars(title = "KillResponseSchema")]
47 KillResponseSchema(kill::response_schema::Request),
48 #[schemars(title = "Query")]
49 Query(query::Request),
50 #[schemars(title = "QueryRequestSchema")]
51 QueryRequestSchema(query::request_schema::Request),
52 #[schemars(title = "QueryResponseSchema")]
53 QueryResponseSchema(query::response_schema::Request),
54 #[schemars(title = "Spawn")]
55 Spawn(spawn::Request),
56 #[schemars(title = "SpawnRequestSchema")]
57 SpawnRequestSchema(spawn::request_schema::Request),
58 #[schemars(title = "SpawnResponseSchema")]
59 SpawnResponseSchema(spawn::response_schema::Request),
60}
61
62#[objectiveai_sdk_macros::json_schema_ignore]
65#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, schemars::JsonSchema)]
66#[schemars(rename = "cli.command.db.ResponseItem")]
67#[serde(untagged)]
68pub enum ResponseItem {
69 #[schemars(title = "Config")]
70 Config(config::Response),
71 #[schemars(title = "Kill")]
72 Kill(kill::Response),
73 #[schemars(title = "KillRequestSchema")]
74 KillRequestSchema(kill::request_schema::Response),
75 #[schemars(title = "KillResponseSchema")]
76 KillResponseSchema(kill::response_schema::Response),
77 #[schemars(title = "Query")]
78 Query(query::Response),
79 #[schemars(title = "QueryRequestSchema")]
80 QueryRequestSchema(query::request_schema::Response),
81 #[schemars(title = "QueryResponseSchema")]
82 QueryResponseSchema(query::response_schema::Response),
83 #[schemars(title = "Spawn")]
84 Spawn(spawn::Response),
85 #[schemars(title = "SpawnRequestSchema")]
86 SpawnRequestSchema(spawn::request_schema::Response),
87 #[schemars(title = "SpawnResponseSchema")]
88 SpawnResponseSchema(spawn::response_schema::Response),
89}
90
91#[cfg(feature = "mcp")]
92impl crate::cli::command::CommandResponse for ResponseItem {
93 fn into_mcp(self) -> crate::cli::command::McpResponseItem {
94 match self {
95 ResponseItem::Config(v) => v.into_mcp(),
96 ResponseItem::Kill(v) => v.into_mcp(),
97 ResponseItem::KillRequestSchema(v) => v.into_mcp(),
98 ResponseItem::KillResponseSchema(v) => v.into_mcp(),
99 ResponseItem::Query(v) => v.into_mcp(),
100 ResponseItem::QueryRequestSchema(v) => v.into_mcp(),
101 ResponseItem::QueryResponseSchema(v) => v.into_mcp(),
102 ResponseItem::Spawn(v) => v.into_mcp(),
103 ResponseItem::SpawnRequestSchema(v) => v.into_mcp(),
104 ResponseItem::SpawnResponseSchema(v) => v.into_mcp(),
105 }
106 }
107}
108
109impl TryFrom<Command> for Request {
110 type Error = crate::cli::command::FromArgsError;
111 fn try_from(command: Command) -> Result<Self, Self::Error> {
112 match command {
113 Command::Config { command } =>
114 Ok(Request::Config(config::Request::try_from(command)?)),
115 Command::Kill(cmd) => match cmd.schema {
116 None => Ok(Request::Kill(kill::Request::try_from(cmd.args)?)),
117 Some(kill::Schema::RequestSchema(args)) => Ok(
118 Request::KillRequestSchema(kill::request_schema::Request::try_from(args)?),
119 ),
120 Some(kill::Schema::ResponseSchema(args)) => Ok(
121 Request::KillResponseSchema(kill::response_schema::Request::try_from(args)?),
122 ),
123 },
124 Command::Query(cmd) => match cmd.schema {
125 None => Ok(Request::Query(query::Request::try_from(cmd.args)?)),
126 Some(query::Schema::RequestSchema(args)) => Ok(
127 Request::QueryRequestSchema(query::request_schema::Request::try_from(args)?),
128 ),
129 Some(query::Schema::ResponseSchema(args)) => Ok(
130 Request::QueryResponseSchema(query::response_schema::Request::try_from(args)?),
131 ),
132 },
133 Command::Spawn(cmd) => match cmd.schema {
134 None => Ok(Request::Spawn(spawn::Request::try_from(cmd.args)?)),
135 Some(spawn::Schema::RequestSchema(args)) => Ok(
136 Request::SpawnRequestSchema(spawn::request_schema::Request::try_from(args)?),
137 ),
138 Some(spawn::Schema::ResponseSchema(args)) => Ok(
139 Request::SpawnResponseSchema(spawn::response_schema::Request::try_from(args)?),
140 ),
141 },
142 }
143 }
144}
145
146impl CommandRequest for Request {
147 fn request_base(&self) -> &crate::cli::command::RequestBase {
148 match self {
149 Request::Config(inner) => inner.request_base(),
150 Request::Kill(inner) => inner.request_base(),
151 Request::KillRequestSchema(inner) => inner.request_base(),
152 Request::KillResponseSchema(inner) => inner.request_base(),
153 Request::Query(inner) => inner.request_base(),
154 Request::QueryRequestSchema(inner) => inner.request_base(),
155 Request::QueryResponseSchema(inner) => inner.request_base(),
156 Request::Spawn(inner) => inner.request_base(),
157 Request::SpawnRequestSchema(inner) => inner.request_base(),
158 Request::SpawnResponseSchema(inner) => inner.request_base(),
159 }
160 }
161
162 fn request_base_mut(&mut self) -> Option<&mut crate::cli::command::RequestBase> {
163 match self {
164 Request::Config(inner) => inner.request_base_mut(),
165 Request::Kill(inner) => inner.request_base_mut(),
166 Request::KillRequestSchema(inner) => inner.request_base_mut(),
167 Request::KillResponseSchema(inner) => inner.request_base_mut(),
168 Request::Query(inner) => inner.request_base_mut(),
169 Request::QueryRequestSchema(inner) => inner.request_base_mut(),
170 Request::QueryResponseSchema(inner) => inner.request_base_mut(),
171 Request::Spawn(inner) => inner.request_base_mut(),
172 Request::SpawnRequestSchema(inner) => inner.request_base_mut(),
173 Request::SpawnResponseSchema(inner) => inner.request_base_mut(),
174 }
175 }
176}
177
178#[cfg(feature = "cli-executor")]
179pub async fn execute<E: crate::cli::command::CommandExecutor>(
180 executor: &E,
181 request: Request,
182 agent_arguments: Option<&crate::cli::command::AgentArguments>,
183) -> Result<
184 std::pin::Pin<Box<dyn futures::Stream<Item = Result<ResponseItem, E::Error>> + Send>>,
185 E::Error,
186> {
187 use futures::StreamExt;
188 let stream: std::pin::Pin<
189 Box<dyn futures::Stream<Item = Result<ResponseItem, E::Error>> + Send>,
190 > = match request {
191 Request::Config(req) => {
192 let inner = config::execute(executor, req, agent_arguments).await?;
193 Box::pin(inner.map(|r| r.map(ResponseItem::Config)))
194 }
195 Request::Kill(req) => {
196 let value = kill::execute(executor, req, agent_arguments).await?;
197 Box::pin(crate::cli::command::StreamOnce::new(Ok(
198 ResponseItem::Kill(value),
199 )))
200 }
201 Request::KillRequestSchema(req) => {
202 let value = kill::request_schema::execute(executor, req, agent_arguments).await?;
203 Box::pin(crate::cli::command::StreamOnce::new(Ok(
204 ResponseItem::KillRequestSchema(value),
205 )))
206 }
207 Request::KillResponseSchema(req) => {
208 let value = kill::response_schema::execute(executor, req, agent_arguments).await?;
209 Box::pin(crate::cli::command::StreamOnce::new(Ok(
210 ResponseItem::KillResponseSchema(value),
211 )))
212 }
213 Request::Query(req) => {
214 let value = query::execute(executor, req, agent_arguments).await?;
215 Box::pin(crate::cli::command::StreamOnce::new(Ok(
216 ResponseItem::Query(value),
217 )))
218 }
219 Request::QueryRequestSchema(req) => {
220 let value = query::request_schema::execute(executor, req, agent_arguments).await?;
221 Box::pin(crate::cli::command::StreamOnce::new(Ok(
222 ResponseItem::QueryRequestSchema(value),
223 )))
224 }
225 Request::QueryResponseSchema(req) => {
226 let value = query::response_schema::execute(executor, req, agent_arguments).await?;
227 Box::pin(crate::cli::command::StreamOnce::new(Ok(
228 ResponseItem::QueryResponseSchema(value),
229 )))
230 }
231 Request::Spawn(req) => {
232 let value = spawn::execute(executor, req, agent_arguments).await?;
233 Box::pin(crate::cli::command::StreamOnce::new(Ok(
234 ResponseItem::Spawn(value),
235 )))
236 }
237 Request::SpawnRequestSchema(req) => {
238 let value = spawn::request_schema::execute(executor, req, agent_arguments).await?;
239 Box::pin(crate::cli::command::StreamOnce::new(Ok(
240 ResponseItem::SpawnRequestSchema(value),
241 )))
242 }
243 Request::SpawnResponseSchema(req) => {
244 let value = spawn::response_schema::execute(executor, req, agent_arguments).await?;
245 Box::pin(crate::cli::command::StreamOnce::new(Ok(
246 ResponseItem::SpawnResponseSchema(value),
247 )))
248 }
249 };
250 Ok(stream)
251}
252
253#[cfg(feature = "cli-executor")]
254pub async fn execute_transform<E: crate::cli::command::CommandExecutor>(
255 executor: &E,
256 request: Request,
257 transform: crate::cli::command::Transform,
258 agent_arguments: Option<&crate::cli::command::AgentArguments>,
259) -> Result<
260 std::pin::Pin<Box<dyn futures::Stream<Item = Result<serde_json::Value, E::Error>> + Send>>,
261 E::Error,
262> {
263 let stream: std::pin::Pin<
264 Box<dyn futures::Stream<Item = Result<serde_json::Value, E::Error>> + Send>,
265 > = match request {
266 Request::Config(req) => {
267 let inner = config::execute_transform(executor, req, transform, agent_arguments).await?;
268 Box::pin(inner)
269 }
270 Request::Kill(req) => {
271 let value = kill::execute_transform(executor, req, transform, agent_arguments).await?;
272 Box::pin(crate::cli::command::StreamOnce::new(Ok(value)))
273 }
274 Request::KillRequestSchema(req) => {
275 let value =
276 kill::request_schema::execute_transform(executor, req, transform, agent_arguments).await?;
277 Box::pin(crate::cli::command::StreamOnce::new(Ok(value)))
278 }
279 Request::KillResponseSchema(req) => {
280 let value =
281 kill::response_schema::execute_transform(executor, req, transform, agent_arguments).await?;
282 Box::pin(crate::cli::command::StreamOnce::new(Ok(value)))
283 }
284 Request::Query(req) => {
285 let value = query::execute_transform(executor, req, transform, agent_arguments).await?;
286 Box::pin(crate::cli::command::StreamOnce::new(Ok(value)))
287 }
288 Request::QueryRequestSchema(req) => {
289 let value =
290 query::request_schema::execute_transform(executor, req, transform, agent_arguments).await?;
291 Box::pin(crate::cli::command::StreamOnce::new(Ok(value)))
292 }
293 Request::QueryResponseSchema(req) => {
294 let value =
295 query::response_schema::execute_transform(executor, req, transform, agent_arguments).await?;
296 Box::pin(crate::cli::command::StreamOnce::new(Ok(value)))
297 }
298 Request::Spawn(req) => {
299 let value = spawn::execute_transform(executor, req, transform, agent_arguments).await?;
300 Box::pin(crate::cli::command::StreamOnce::new(Ok(value)))
301 }
302 Request::SpawnRequestSchema(req) => {
303 let value =
304 spawn::request_schema::execute_transform(executor, req, transform, agent_arguments).await?;
305 Box::pin(crate::cli::command::StreamOnce::new(Ok(value)))
306 }
307 Request::SpawnResponseSchema(req) => {
308 let value =
309 spawn::response_schema::execute_transform(executor, req, transform, agent_arguments).await?;
310 Box::pin(crate::cli::command::StreamOnce::new(Ok(value)))
311 }
312 };
313 Ok(stream)
314}