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 into_command(&self) -> Vec<String> {
148 match self {
149 Request::Config(inner) => inner.into_command(),
150 Request::Kill(inner) => inner.into_command(),
151 Request::KillRequestSchema(inner) => inner.into_command(),
152 Request::KillResponseSchema(inner) => inner.into_command(),
153 Request::Query(inner) => inner.into_command(),
154 Request::QueryRequestSchema(inner) => inner.into_command(),
155 Request::QueryResponseSchema(inner) => inner.into_command(),
156 Request::Spawn(inner) => inner.into_command(),
157 Request::SpawnRequestSchema(inner) => inner.into_command(),
158 Request::SpawnResponseSchema(inner) => inner.into_command(),
159 }
160 }
161
162 fn request_base(&self) -> &crate::cli::command::RequestBase {
163 match self {
164 Request::Config(inner) => inner.request_base(),
165 Request::Kill(inner) => inner.request_base(),
166 Request::KillRequestSchema(inner) => inner.request_base(),
167 Request::KillResponseSchema(inner) => inner.request_base(),
168 Request::Query(inner) => inner.request_base(),
169 Request::QueryRequestSchema(inner) => inner.request_base(),
170 Request::QueryResponseSchema(inner) => inner.request_base(),
171 Request::Spawn(inner) => inner.request_base(),
172 Request::SpawnRequestSchema(inner) => inner.request_base(),
173 Request::SpawnResponseSchema(inner) => inner.request_base(),
174 }
175 }
176
177 fn request_base_mut(&mut self) -> Option<&mut crate::cli::command::RequestBase> {
178 match self {
179 Request::Config(inner) => inner.request_base_mut(),
180 Request::Kill(inner) => inner.request_base_mut(),
181 Request::KillRequestSchema(inner) => inner.request_base_mut(),
182 Request::KillResponseSchema(inner) => inner.request_base_mut(),
183 Request::Query(inner) => inner.request_base_mut(),
184 Request::QueryRequestSchema(inner) => inner.request_base_mut(),
185 Request::QueryResponseSchema(inner) => inner.request_base_mut(),
186 Request::Spawn(inner) => inner.request_base_mut(),
187 Request::SpawnRequestSchema(inner) => inner.request_base_mut(),
188 Request::SpawnResponseSchema(inner) => inner.request_base_mut(),
189 }
190 }
191}
192
193#[cfg(feature = "cli-executor")]
194pub async fn execute<E: crate::cli::command::CommandExecutor>(
195 executor: &E,
196 request: Request,
197 agent_arguments: Option<&crate::cli::command::AgentArguments>,
198) -> Result<
199 std::pin::Pin<Box<dyn futures::Stream<Item = Result<ResponseItem, E::Error>> + Send>>,
200 E::Error,
201> {
202 use futures::StreamExt;
203 let stream: std::pin::Pin<
204 Box<dyn futures::Stream<Item = Result<ResponseItem, E::Error>> + Send>,
205 > = match request {
206 Request::Config(req) => {
207 let inner = config::execute(executor, req, agent_arguments).await?;
208 Box::pin(inner.map(|r| r.map(ResponseItem::Config)))
209 }
210 Request::Kill(req) => {
211 let value = kill::execute(executor, req, agent_arguments).await?;
212 Box::pin(crate::cli::command::StreamOnce::new(Ok(
213 ResponseItem::Kill(value),
214 )))
215 }
216 Request::KillRequestSchema(req) => {
217 let value = kill::request_schema::execute(executor, req, agent_arguments).await?;
218 Box::pin(crate::cli::command::StreamOnce::new(Ok(
219 ResponseItem::KillRequestSchema(value),
220 )))
221 }
222 Request::KillResponseSchema(req) => {
223 let value = kill::response_schema::execute(executor, req, agent_arguments).await?;
224 Box::pin(crate::cli::command::StreamOnce::new(Ok(
225 ResponseItem::KillResponseSchema(value),
226 )))
227 }
228 Request::Query(req) => {
229 let value = query::execute(executor, req, agent_arguments).await?;
230 Box::pin(crate::cli::command::StreamOnce::new(Ok(
231 ResponseItem::Query(value),
232 )))
233 }
234 Request::QueryRequestSchema(req) => {
235 let value = query::request_schema::execute(executor, req, agent_arguments).await?;
236 Box::pin(crate::cli::command::StreamOnce::new(Ok(
237 ResponseItem::QueryRequestSchema(value),
238 )))
239 }
240 Request::QueryResponseSchema(req) => {
241 let value = query::response_schema::execute(executor, req, agent_arguments).await?;
242 Box::pin(crate::cli::command::StreamOnce::new(Ok(
243 ResponseItem::QueryResponseSchema(value),
244 )))
245 }
246 Request::Spawn(req) => {
247 let value = spawn::execute(executor, req, agent_arguments).await?;
248 Box::pin(crate::cli::command::StreamOnce::new(Ok(
249 ResponseItem::Spawn(value),
250 )))
251 }
252 Request::SpawnRequestSchema(req) => {
253 let value = spawn::request_schema::execute(executor, req, agent_arguments).await?;
254 Box::pin(crate::cli::command::StreamOnce::new(Ok(
255 ResponseItem::SpawnRequestSchema(value),
256 )))
257 }
258 Request::SpawnResponseSchema(req) => {
259 let value = spawn::response_schema::execute(executor, req, agent_arguments).await?;
260 Box::pin(crate::cli::command::StreamOnce::new(Ok(
261 ResponseItem::SpawnResponseSchema(value),
262 )))
263 }
264 };
265 Ok(stream)
266}
267
268#[cfg(feature = "cli-executor")]
269pub async fn execute_transform<E: crate::cli::command::CommandExecutor>(
270 executor: &E,
271 request: Request,
272 transform: crate::cli::command::Transform,
273 agent_arguments: Option<&crate::cli::command::AgentArguments>,
274) -> Result<
275 std::pin::Pin<Box<dyn futures::Stream<Item = Result<serde_json::Value, E::Error>> + Send>>,
276 E::Error,
277> {
278 let stream: std::pin::Pin<
279 Box<dyn futures::Stream<Item = Result<serde_json::Value, E::Error>> + Send>,
280 > = match request {
281 Request::Config(req) => {
282 let inner = config::execute_transform(executor, req, transform, agent_arguments).await?;
283 Box::pin(inner)
284 }
285 Request::Kill(req) => {
286 let value = kill::execute_transform(executor, req, transform, agent_arguments).await?;
287 Box::pin(crate::cli::command::StreamOnce::new(Ok(value)))
288 }
289 Request::KillRequestSchema(req) => {
290 let value =
291 kill::request_schema::execute_transform(executor, req, transform, agent_arguments).await?;
292 Box::pin(crate::cli::command::StreamOnce::new(Ok(value)))
293 }
294 Request::KillResponseSchema(req) => {
295 let value =
296 kill::response_schema::execute_transform(executor, req, transform, agent_arguments).await?;
297 Box::pin(crate::cli::command::StreamOnce::new(Ok(value)))
298 }
299 Request::Query(req) => {
300 let value = query::execute_transform(executor, req, transform, agent_arguments).await?;
301 Box::pin(crate::cli::command::StreamOnce::new(Ok(value)))
302 }
303 Request::QueryRequestSchema(req) => {
304 let value =
305 query::request_schema::execute_transform(executor, req, transform, agent_arguments).await?;
306 Box::pin(crate::cli::command::StreamOnce::new(Ok(value)))
307 }
308 Request::QueryResponseSchema(req) => {
309 let value =
310 query::response_schema::execute_transform(executor, req, transform, agent_arguments).await?;
311 Box::pin(crate::cli::command::StreamOnce::new(Ok(value)))
312 }
313 Request::Spawn(req) => {
314 let value = spawn::execute_transform(executor, req, transform, agent_arguments).await?;
315 Box::pin(crate::cli::command::StreamOnce::new(Ok(value)))
316 }
317 Request::SpawnRequestSchema(req) => {
318 let value =
319 spawn::request_schema::execute_transform(executor, req, transform, agent_arguments).await?;
320 Box::pin(crate::cli::command::StreamOnce::new(Ok(value)))
321 }
322 Request::SpawnResponseSchema(req) => {
323 let value =
324 spawn::response_schema::execute_transform(executor, req, transform, agent_arguments).await?;
325 Box::pin(crate::cli::command::StreamOnce::new(Ok(value)))
326 }
327 };
328 Ok(stream)
329}