Skip to main content

objectiveai_sdk/cli/command/functions/inventions/recursive/create/remote/
mod.rs

1//! `functions inventions recursive create remote` — async handler stub.
2
3use crate::cli::command::CommandRequest;
4use crate::cli::command::agents::spawn::AgentSpec;
5use crate::functions::inventions::state::ParamsState;
6
7#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, schemars::JsonSchema)]
8#[schemars(rename = "cli.command.functions.inventions.recursive.create.remote.Request")]
9pub struct Request {
10    pub path_type: Path,
11    pub state: RequestState,
12    pub agent: AgentSpec,
13    pub continuation: Option<String>,
14    pub seed: Option<i64>,
15    pub dangerous_advanced: Option<RequestDangerousAdvanced>,
16    pub jq: Option<String>,
17}
18
19#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize, schemars::JsonSchema)]
20#[schemars(rename = "cli.command.functions.inventions.recursive.create.remote.Path")]
21pub enum Path {
22    #[serde(rename = "functions/inventions/recursive/create/remote")]
23    FunctionsInventionsRecursiveCreateRemote,
24}
25
26#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, schemars::JsonSchema)]
27#[schemars(rename = "cli.command.functions.inventions.recursive.create.remote.RequestState")]
28pub enum RequestState {
29    #[schemars(title = "Inline")]
30    Inline(ParamsState),
31    #[schemars(title = "Ref")]
32    Ref(String),
33}
34
35impl RequestState {
36    fn push_flags(&self, out: &mut Vec<String>) {
37        match self {
38            RequestState::Inline(v) => {
39                out.push("--state-inline".to_string());
40                out.push(serde_json::to_string(v).expect("state serializes"));
41            }
42            RequestState::Ref(r) => {
43                out.push("--state".to_string());
44                out.push(r.clone());
45            }
46        }
47    }
48}
49
50impl CommandRequest for Request {
51    fn into_command(&self) -> Vec<String> {
52        let mut argv = vec![
53            "functions".to_string(),
54            "inventions".to_string(),
55            "recursive".to_string(),
56            "create".to_string(),
57            "remote".to_string(),
58        ];
59        self.state.push_flags(&mut argv);
60        argv.push("--agent-inline".to_string());
61        argv.push(serde_json::to_string(&self.agent).expect("agent serializes"));
62        if let Some(c) = &self.continuation {
63            argv.push("--continuation".to_string());
64            argv.push(c.clone());
65        }
66        if let Some(seed) = self.seed {
67            argv.push("--seed".to_string());
68            argv.push(seed.to_string());
69        }
70        if let Some(advanced) = &self.dangerous_advanced {
71            argv.push("--dangerous-advanced".to_string());
72            argv.push(
73                serde_json::to_string(advanced)
74                    .expect("RequestDangerousAdvanced serializes"),
75            );
76        }
77        if let Some(jq) = &self.jq {
78            argv.push("--jq".to_string());
79            argv.push(jq.clone());
80        }
81        argv
82    }
83}
84
85#[derive(Debug, Clone, Default, PartialEq, Eq, serde::Serialize, serde::Deserialize, schemars::JsonSchema)]
86#[schemars(rename = "cli.command.functions.inventions.recursive.create.remote.RequestDangerousAdvanced")]
87pub struct RequestDangerousAdvanced {
88    #[serde(default, skip_serializing_if = "Option::is_none")]
89    #[schemars(extend("omitempty" = true))]
90    pub stream: Option<bool>,
91}
92
93#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, schemars::JsonSchema)]
94#[serde(untagged)]
95#[schemars(rename = "cli.command.functions.inventions.recursive.create.remote.ResponseItem")]
96pub enum ResponseItem {
97    #[schemars(title = "Chunk")]
98    Chunk(crate::functions::inventions::recursive::response::streaming::FunctionInventionRecursiveChunk),
99    #[schemars(title = "Id")]
100    Id(String),
101}
102
103/// Non-chunk variant of [`ResponseItem`]. Returned by the unary `execute`
104/// path (with `dangerous_advanced.stream` cleared) when the cli emits a
105/// single bare id string.
106pub type Response = String;
107
108#[derive(clap::Args)]
109#[group(id = "state", required = true, multiple = false)]
110pub struct Args {
111    /// State reference.
112    #[arg(long, group = "state")]
113    pub state: Option<String>,
114    /// Inline JSON state.
115    #[arg(long, group = "state")]
116    pub state_inline: Option<String>,
117    /// Inline JSON agent definition.
118    #[arg(long)]
119    pub agent_inline: String,
120    /// Continuation token from a previous response.
121    #[arg(long)]
122    pub continuation: Option<String>,
123    /// Seed for deterministic mock responses.
124    #[arg(long)]
125    pub seed: Option<i64>,
126    /// Advanced opt-in flags as inline JSON.
127    #[arg(long)]
128    pub dangerous_advanced: Option<String>,
129    /// jq filter applied to the JSON output.
130    #[arg(long)]
131    pub jq: Option<String>,
132}
133
134#[derive(clap::Args)]
135#[command(args_conflicts_with_subcommands = true)]
136pub struct Command {
137    #[command(flatten)]
138    pub args: Args,
139    #[command(subcommand)]
140    pub schema: Option<Schema>,
141}
142
143#[derive(clap::Subcommand)]
144pub enum Schema {
145    /// Emit the JSON Schema for this leaf's `Request` type and exit.
146    RequestSchema(request_schema::Args),
147    /// Emit the JSON Schema for this leaf's `Response` type and exit.
148    ResponseSchema(response_schema::Args),
149}
150
151impl TryFrom<Args> for Request {
152    type Error = crate::cli::command::FromArgsError;
153    fn try_from(args: Args) -> Result<Self, Self::Error> {
154        let state = if let Some(s) = args.state_inline {
155            let mut de = serde_json::Deserializer::from_str(&s);
156            let v = serde_path_to_error::deserialize(&mut de).map_err(|source| {
157                crate::cli::command::FromArgsError {
158                    field: "state_inline",
159                    source: source.into(),
160                }
161            })?;
162            RequestState::Inline(v)
163        } else {
164            RequestState::Ref(args.state.unwrap())
165        };
166        let agent = {
167            let mut de = serde_json::Deserializer::from_str(&args.agent_inline);
168            serde_path_to_error::deserialize(&mut de).map_err(|source| {
169                crate::cli::command::FromArgsError {
170                    field: "agent_inline",
171                    source: source.into(),
172                }
173            })?
174        };
175        let dangerous_advanced = if let Some(s) = args.dangerous_advanced {
176            let mut de = serde_json::Deserializer::from_str(&s);
177            let v = serde_path_to_error::deserialize(&mut de).map_err(|source| {
178                crate::cli::command::FromArgsError {
179                    field: "dangerous_advanced",
180                    source: source.into(),
181                }
182            })?;
183            Some(v)
184        } else {
185            None
186        };
187        Ok(Self { path_type: Path::FunctionsInventionsRecursiveCreateRemote,
188            state,
189            agent,
190            continuation: args.continuation,
191            seed: args.seed,
192            dangerous_advanced,
193            jq: args.jq,
194        })
195    }
196}
197
198#[cfg(feature = "cli-executor")]
199pub async fn execute_streaming<E: crate::cli::command::CommandExecutor>(
200    executor: &E,
201    mut request: Request,
202
203        agent_arguments: Option<&crate::cli::command::AgentArguments>,
204    ) -> Result<E::Stream<ResponseItem>, E::Error> {
205    request.jq = None;
206    let mut advanced = request.dangerous_advanced.unwrap_or_default();
207    advanced.stream = Some(true);
208    request.dangerous_advanced = Some(advanced);
209    executor.execute(request, agent_arguments).await
210}
211
212#[cfg(feature = "cli-executor")]
213pub async fn execute_streaming_jq<E: crate::cli::command::CommandExecutor>(
214    executor: &E,
215    mut request: Request,
216    jq: String,
217
218        agent_arguments: Option<&crate::cli::command::AgentArguments>,
219    ) -> Result<E::Stream<serde_json::Value>, E::Error> {
220    request.jq = Some(jq);
221    let mut advanced = request.dangerous_advanced.unwrap_or_default();
222    advanced.stream = Some(true);
223    request.dangerous_advanced = Some(advanced);
224    executor.execute(request, agent_arguments).await
225}
226
227#[cfg(feature = "cli-executor")]
228pub async fn execute<E: crate::cli::command::CommandExecutor>(
229    executor: &E,
230    mut request: Request,
231
232        agent_arguments: Option<&crate::cli::command::AgentArguments>,
233    ) -> Result<Response, E::Error> {
234    request.jq = None;
235    if let Some(advanced) = request.dangerous_advanced.as_mut() {
236        advanced.stream = None;
237    }
238    executor.execute_one(request, agent_arguments).await
239}
240
241#[cfg(feature = "cli-executor")]
242pub async fn execute_jq<E: crate::cli::command::CommandExecutor>(
243    executor: &E,
244    mut request: Request,
245    jq: String,
246
247        agent_arguments: Option<&crate::cli::command::AgentArguments>,
248    ) -> Result<serde_json::Value, E::Error> {
249    request.jq = Some(jq);
250    if let Some(advanced) = request.dangerous_advanced.as_mut() {
251        advanced.stream = None;
252    }
253    executor.execute_one(request, agent_arguments).await
254}
255
256#[cfg(feature = "mcp")]
257impl crate::cli::command::CommandResponse for ResponseItem {
258    fn into_mcp(self) -> crate::cli::command::McpResponseItem {
259        crate::cli::command::McpResponseItem::JSONL(serde_json::to_value(self).unwrap())
260    }
261}
262
263pub mod request_schema;
264
265
266pub mod response_schema;