Skip to main content

objectiveai_sdk/cli/command/daemon/
mod.rs

1pub mod kill;
2pub mod spawn;
3
4#[derive(clap::Subcommand)]
5pub enum Command {
6    Spawn(spawn::Command),
7    Kill(kill::Command),
8}
9
10#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, schemars::JsonSchema)]
11#[serde(untagged)]
12#[schemars(rename = "cli.command.daemon.Request")]
13pub enum Request {
14    #[schemars(title = "Spawn")]
15    Spawn(spawn::Request),
16    #[schemars(title = "SpawnRequestSchema")]
17    SpawnRequestSchema(spawn::request_schema::Request),
18    #[schemars(title = "SpawnResponseSchema")]
19    SpawnResponseSchema(spawn::response_schema::Request),
20    #[schemars(title = "Kill")]
21    Kill(kill::Request),
22    #[schemars(title = "KillRequestSchema")]
23    KillRequestSchema(kill::request_schema::Request),
24    #[schemars(title = "KillResponseSchema")]
25    KillResponseSchema(kill::response_schema::Request),
26}
27
28// Exempt from json-schema coverage: tier aggregate (see the root
29// `ResponseItem` in command.rs - TS7056).
30#[objectiveai_sdk_macros::json_schema_ignore]
31#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, schemars::JsonSchema)]
32#[schemars(rename = "cli.command.daemon.ResponseItem")]
33#[serde(untagged)]
34pub enum ResponseItem {
35    #[schemars(title = "Spawn")]
36    Spawn(spawn::ResponseItem),
37    #[schemars(title = "SpawnRequestSchema")]
38    SpawnRequestSchema(spawn::request_schema::Response),
39    #[schemars(title = "SpawnResponseSchema")]
40    SpawnResponseSchema(spawn::response_schema::Response),
41    #[schemars(title = "Kill")]
42    Kill(kill::Response),
43    #[schemars(title = "KillRequestSchema")]
44    KillRequestSchema(kill::request_schema::Response),
45    #[schemars(title = "KillResponseSchema")]
46    KillResponseSchema(kill::response_schema::Response),
47}
48
49#[cfg(feature = "mcp")]
50impl crate::cli::command::CommandResponse for ResponseItem {
51    fn into_mcp(self) -> crate::cli::command::McpResponseItem {
52        match self {
53            ResponseItem::Spawn(v) => v.into_mcp(),
54            ResponseItem::SpawnRequestSchema(v) => v.into_mcp(),
55            ResponseItem::SpawnResponseSchema(v) => v.into_mcp(),
56            ResponseItem::Kill(v) => v.into_mcp(),
57            ResponseItem::KillRequestSchema(v) => v.into_mcp(),
58            ResponseItem::KillResponseSchema(v) => v.into_mcp(),
59        }
60    }
61}
62
63impl TryFrom<Command> for Request {
64    type Error = crate::cli::command::FromArgsError;
65    fn try_from(command: Command) -> Result<Self, Self::Error> {
66        match command {
67            Command::Spawn(cmd) => match cmd.schema {
68                None => Ok(Request::Spawn(spawn::Request::try_from(cmd.args)?)),
69                Some(spawn::Schema::RequestSchema(args)) =>
70                    Ok(Request::SpawnRequestSchema(spawn::request_schema::Request::try_from(args)?)),
71                Some(spawn::Schema::ResponseSchema(args)) =>
72                    Ok(Request::SpawnResponseSchema(spawn::response_schema::Request::try_from(args)?)),
73            },
74            Command::Kill(cmd) => match cmd.schema {
75                None => Ok(Request::Kill(kill::Request::try_from(cmd.args)?)),
76                Some(kill::Schema::RequestSchema(args)) =>
77                    Ok(Request::KillRequestSchema(kill::request_schema::Request::try_from(args)?)),
78                Some(kill::Schema::ResponseSchema(args)) =>
79                    Ok(Request::KillResponseSchema(kill::response_schema::Request::try_from(args)?)),
80            },
81        }
82    }
83}
84
85impl crate::cli::command::CommandRequest for Request {
86    fn request_base(&self) -> &crate::cli::command::RequestBase {
87        match self {
88            Request::Spawn(inner) => inner.request_base(),
89            Request::SpawnRequestSchema(inner) => inner.request_base(),
90            Request::SpawnResponseSchema(inner) => inner.request_base(),
91            Request::Kill(inner) => inner.request_base(),
92            Request::KillRequestSchema(inner) => inner.request_base(),
93            Request::KillResponseSchema(inner) => inner.request_base(),
94        }
95    }
96
97    fn request_base_mut(&mut self) -> Option<&mut crate::cli::command::RequestBase> {
98        match self {
99            Request::Spawn(inner) => inner.request_base_mut(),
100            Request::SpawnRequestSchema(inner) => inner.request_base_mut(),
101            Request::SpawnResponseSchema(inner) => inner.request_base_mut(),
102            Request::Kill(inner) => inner.request_base_mut(),
103            Request::KillRequestSchema(inner) => inner.request_base_mut(),
104            Request::KillResponseSchema(inner) => inner.request_base_mut(),
105        }
106    }
107}
108
109#[cfg(feature = "cli-executor")]
110pub async fn execute<E: crate::cli::command::CommandExecutor>(
111    executor: &E,
112    request: Request,
113    agent_arguments: Option<&crate::cli::command::AgentArguments>,
114) -> Result<
115    std::pin::Pin<Box<dyn futures::Stream<Item = Result<ResponseItem, E::Error>> + Send>>,
116    E::Error,
117> {
118    use futures::StreamExt;
119    let stream: std::pin::Pin<Box<dyn futures::Stream<Item = Result<ResponseItem, E::Error>> + Send>> =
120        match request {
121            Request::Spawn(req) => {
122                let inner = spawn::execute(executor, req, agent_arguments).await?;
123                Box::pin(inner.map(|r| r.map(ResponseItem::Spawn)))
124            }
125            Request::SpawnRequestSchema(req) => {
126                let value = spawn::request_schema::execute(executor, req, agent_arguments).await?;
127                Box::pin(crate::cli::command::StreamOnce::new(Ok(
128                    ResponseItem::SpawnRequestSchema(value),
129                )))
130            }
131            Request::SpawnResponseSchema(req) => {
132                let value = spawn::response_schema::execute(executor, req, agent_arguments).await?;
133                Box::pin(crate::cli::command::StreamOnce::new(Ok(
134                    ResponseItem::SpawnResponseSchema(value),
135                )))
136            }
137            Request::Kill(req) => {
138                let value = kill::execute(executor, req, agent_arguments).await?;
139                Box::pin(crate::cli::command::StreamOnce::new(Ok(
140                    ResponseItem::Kill(value),
141                )))
142            }
143            Request::KillRequestSchema(req) => {
144                let value = kill::request_schema::execute(executor, req, agent_arguments).await?;
145                Box::pin(crate::cli::command::StreamOnce::new(Ok(
146                    ResponseItem::KillRequestSchema(value),
147                )))
148            }
149            Request::KillResponseSchema(req) => {
150                let value = kill::response_schema::execute(executor, req, agent_arguments).await?;
151                Box::pin(crate::cli::command::StreamOnce::new(Ok(
152                    ResponseItem::KillResponseSchema(value),
153                )))
154            }
155        };
156    Ok(stream)
157}
158
159#[cfg(feature = "cli-executor")]
160pub async fn execute_transform<E: crate::cli::command::CommandExecutor>(
161    executor: &E,
162    request: Request,
163    transform: crate::cli::command::Transform,
164    agent_arguments: Option<&crate::cli::command::AgentArguments>,
165) -> Result<
166    std::pin::Pin<Box<dyn futures::Stream<Item = Result<serde_json::Value, E::Error>> + Send>>,
167    E::Error,
168> {
169    let stream: std::pin::Pin<Box<dyn futures::Stream<Item = Result<serde_json::Value, E::Error>> + Send>> =
170        match request {
171            Request::Spawn(req) => {
172                let inner = spawn::execute_transform(executor, req, transform, agent_arguments).await?;
173                Box::pin(inner)
174            }
175            Request::SpawnRequestSchema(req) => {
176                let value = spawn::request_schema::execute_transform(executor, req, transform, agent_arguments).await?;
177                Box::pin(crate::cli::command::StreamOnce::new(Ok(value)))
178            }
179            Request::SpawnResponseSchema(req) => {
180                let value = spawn::response_schema::execute_transform(executor, req, transform, agent_arguments).await?;
181                Box::pin(crate::cli::command::StreamOnce::new(Ok(value)))
182            }
183            Request::Kill(req) => {
184                let value = kill::execute_transform(executor, req, transform, agent_arguments).await?;
185                Box::pin(crate::cli::command::StreamOnce::new(Ok(value)))
186            }
187            Request::KillRequestSchema(req) => {
188                let value = kill::request_schema::execute_transform(executor, req, transform, agent_arguments).await?;
189                Box::pin(crate::cli::command::StreamOnce::new(Ok(value)))
190            }
191            Request::KillResponseSchema(req) => {
192                let value = kill::response_schema::execute_transform(executor, req, transform, agent_arguments).await?;
193                Box::pin(crate::cli::command::StreamOnce::new(Ok(value)))
194            }
195        };
196    Ok(stream)
197}