objectiveai_sdk/cli/command/agents/spawn/
mod.rs1use crate::cli::command::CommandRequest;
4use crate::cli::command::agents::message::RequestMessage;
5use crate::cli::command::agents::selector::AgentSelector;
6
7#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, schemars::JsonSchema)]
8#[schemars(rename = "cli.command.agents.spawn.Request")]
9pub struct Request {
10 pub path_type: Path,
11 pub message: RequestMessage,
17 pub agent: AgentSelector,
25 pub dangerous_advanced: Option<RequestDangerousAdvanced>,
26 #[serde(flatten)]
27 pub base: crate::cli::command::RequestBase,
28}
29
30#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize, schemars::JsonSchema)]
31#[schemars(rename = "cli.command.agents.spawn.Path")]
32pub enum Path {
33 #[serde(rename = "agents/spawn")]
34 AgentsSpawn,
35}
36
37impl CommandRequest for Request {
38 fn into_command(&self) -> Vec<String> {
39 let mut argv = vec!["agents".to_string(), "spawn".to_string()];
40 self.message.push_flags(&mut argv);
43 self.agent.push_flags(&mut argv);
44 if let Some(advanced) = &self.dangerous_advanced {
45 argv.push("--dangerous-advanced".to_string());
46 argv.push(
47 serde_json::to_string(advanced)
48 .expect("RequestDangerousAdvanced serializes"),
49 );
50 }
51 self.base.push_flags(&mut argv);
52 argv
53 }
54
55 fn request_base(&self) -> &crate::cli::command::RequestBase {
56 &self.base
57 }
58
59 fn request_base_mut(&mut self) -> Option<&mut crate::cli::command::RequestBase> {
60 Some(&mut self.base)
61 }
62}
63
64#[derive(Debug, Clone, Default, PartialEq, Eq, serde::Serialize, serde::Deserialize, schemars::JsonSchema)]
65#[schemars(rename = "cli.command.agents.spawn.RequestDangerousAdvanced")]
66pub struct RequestDangerousAdvanced {
67 #[serde(default, skip_serializing_if = "Option::is_none")]
68 #[schemars(extend("omitempty" = true))]
69 pub stream: Option<bool>,
70 #[serde(default, skip_serializing_if = "Option::is_none")]
75 #[schemars(extend("omitempty" = true))]
76 pub seed: Option<i64>,
77 #[serde(default, skip_serializing_if = "Option::is_none")]
84 #[schemars(extend("omitempty" = true))]
85 pub skip_lock: Option<bool>,
86}
87
88#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, schemars::JsonSchema)]
89#[serde(untagged)]
90#[schemars(rename = "cli.command.agents.spawn.ResponseItem")]
91pub enum ResponseItem {
92 #[schemars(title = "Chunk")]
93 Chunk(crate::agent::completions::response::streaming::AgentCompletionChunk),
94 #[schemars(title = "Id")]
95 Id(String),
96}
97
98pub type Response = String;
102
103#[derive(clap::Args)]
104pub struct Args {
105 #[command(flatten)]
106 pub message: MessageArgs,
107 #[command(flatten)]
108 pub agent: crate::cli::command::agents::selector::AgentSelectorArgs,
109 #[arg(long)]
112 pub dangerous_advanced: Option<String>,
113 #[command(flatten)]
114 pub base: crate::cli::command::RequestBaseArgs,
115}
116
117#[derive(clap::Args)]
120#[group(required = true, multiple = false)]
121pub struct MessageArgs {
122 #[arg(long)]
124 pub simple: Option<String>,
125 #[arg(long)]
127 pub inline: Option<String>,
128 #[arg(long)]
130 pub file: Option<std::path::PathBuf>,
131 #[arg(long)]
133 pub python_inline: Option<String>,
134 #[arg(long)]
136 pub python_file: Option<std::path::PathBuf>,
137}
138
139#[derive(clap::Args)]
140#[command(args_conflicts_with_subcommands = true)]
141pub struct Command {
142 #[command(flatten)]
143 pub args: Args,
144 #[command(subcommand)]
145 pub schema: Option<Schema>,
146}
147
148#[derive(clap::Subcommand)]
149pub enum Schema {
150 RequestSchema(request_schema::Args),
152 ResponseSchema(response_schema::Args),
154}
155
156impl TryFrom<Args> for Request {
157 type Error = crate::cli::command::FromArgsError;
158 fn try_from(args: Args) -> Result<Self, Self::Error> {
159 let message = if let Some(s) = args.message.simple {
160 RequestMessage::Simple(s)
161 } else if let Some(s) = args.message.inline {
162 let mut de = serde_json::Deserializer::from_str(&s);
163 let v = serde_path_to_error::deserialize(&mut de).map_err(|source| {
164 crate::cli::command::FromArgsError {
165 field: "inline",
166 source: source.into(),
167 }
168 })?;
169 RequestMessage::Inline(v)
170 } else if let Some(p) = args.message.file {
171 RequestMessage::File(p)
172 } else if let Some(s) = args.message.python_inline {
173 RequestMessage::PythonInline(s)
174 } else {
175 RequestMessage::PythonFile(args.message.python_file.unwrap())
178 };
179 let agent = AgentSelector::try_from(args.agent)?;
180 let dangerous_advanced: Option<RequestDangerousAdvanced> =
181 if let Some(s) = args.dangerous_advanced {
182 let mut de = serde_json::Deserializer::from_str(&s);
183 let v = serde_path_to_error::deserialize(&mut de).map_err(|source| {
184 crate::cli::command::FromArgsError {
185 field: "dangerous_advanced",
186 source: source.into(),
187 }
188 })?;
189 Some(v)
190 } else {
191 None
192 };
193 Ok(Self { path_type: Path::AgentsSpawn,
194 message,
195 agent,
196 dangerous_advanced,
197 base: args.base.into(),
198 })
199 }
200}
201
202#[cfg(feature = "cli-executor")]
203pub async fn execute_streaming<E: crate::cli::command::CommandExecutor>(
204 executor: &E,
205 mut request: Request,
206
207 agent_arguments: Option<&crate::cli::command::AgentArguments>,
208 ) -> Result<E::Stream<ResponseItem>, E::Error> {
209 request.base.clear_transform();
210 let mut advanced = request.dangerous_advanced.unwrap_or_default();
211 advanced.stream = Some(true);
212 request.dangerous_advanced = Some(advanced);
213 executor.execute(request, agent_arguments).await
214}
215
216#[cfg(feature = "cli-executor")]
217pub async fn execute_streaming_transform<E: crate::cli::command::CommandExecutor>(
218 executor: &E,
219 mut request: Request,
220 transform: crate::cli::command::Transform,
221
222 agent_arguments: Option<&crate::cli::command::AgentArguments>,
223 ) -> Result<E::Stream<serde_json::Value>, E::Error> {
224 request.base.set_transform(transform);
225 let mut advanced = request.dangerous_advanced.unwrap_or_default();
226 advanced.stream = Some(true);
227 request.dangerous_advanced = Some(advanced);
228 executor.execute(request, agent_arguments).await
229}
230
231#[cfg(feature = "cli-executor")]
232pub async fn execute<E: crate::cli::command::CommandExecutor>(
233 executor: &E,
234 mut request: Request,
235
236 agent_arguments: Option<&crate::cli::command::AgentArguments>,
237 ) -> Result<Response, E::Error> {
238 request.base.clear_transform();
239 if let Some(advanced) = request.dangerous_advanced.as_mut() {
240 advanced.stream = None;
241 }
242 executor.execute_one(request, agent_arguments).await
243}
244
245#[cfg(feature = "cli-executor")]
246pub async fn execute_transform<E: crate::cli::command::CommandExecutor>(
247 executor: &E,
248 mut request: Request,
249 transform: crate::cli::command::Transform,
250
251 agent_arguments: Option<&crate::cli::command::AgentArguments>,
252 ) -> Result<serde_json::Value, E::Error> {
253 request.base.set_transform(transform);
254 if let Some(advanced) = request.dangerous_advanced.as_mut() {
255 advanced.stream = None;
256 }
257 executor.execute_one(request, agent_arguments).await
258}
259
260#[cfg(feature = "mcp")]
261impl crate::cli::command::CommandResponse for ResponseItem {
262 fn into_mcp(self) -> crate::cli::command::McpResponseItem {
263 crate::cli::command::McpResponseItem::JSONL(serde_json::to_value(self).unwrap())
264 }
265}
266
267pub mod request_schema;
268
269
270pub mod response_schema;