Skip to main content

codex_runtime/ergonomic/
oneshot.rs

1use crate::runtime::{
2    Client, ClientError, PromptRunError, PromptRunResult, RunProfile, RuntimeError,
3};
4use thiserror::Error;
5
6/// Error model for one-shot convenience calls.
7/// Side effects are explicit: run errors can carry shutdown errors.
8#[derive(Debug, Error, PartialEq, Eq)]
9pub enum QuickRunError {
10    #[error("failed to connect codex runtime: {0}")]
11    Connect(#[from] ClientError),
12    #[error("prompt run failed: {run}; shutdown_error={shutdown:?}")]
13    Run {
14        run: PromptRunError,
15        shutdown: Option<RuntimeError>,
16    },
17    #[error("runtime shutdown failed after successful run: {0}")]
18    Shutdown(#[from] RuntimeError),
19}
20
21/// One-shot convenience:
22/// connect -> run(default profile) -> shutdown
23pub async fn quick_run(
24    cwd: impl Into<String>,
25    prompt: impl Into<String>,
26) -> Result<PromptRunResult, QuickRunError> {
27    quick_run_impl(cwd.into(), prompt.into(), None).await
28}
29
30/// One-shot convenience with explicit profile:
31/// connect -> run(profile) -> shutdown
32pub async fn quick_run_with_profile(
33    cwd: impl Into<String>,
34    prompt: impl Into<String>,
35    profile: RunProfile,
36) -> Result<PromptRunResult, QuickRunError> {
37    quick_run_impl(cwd.into(), prompt.into(), Some(profile)).await
38}
39
40async fn quick_run_impl(
41    cwd: String,
42    prompt: String,
43    profile: Option<RunProfile>,
44) -> Result<PromptRunResult, QuickRunError> {
45    let client = Client::connect_default().await?;
46    let run_result = match profile {
47        Some(profile) => client.run_with_profile(cwd, prompt, profile).await,
48        None => client.run(cwd, prompt).await,
49    };
50    let shutdown_result = client.shutdown().await;
51    fold_quick_run(run_result, shutdown_result)
52}
53
54pub(crate) fn fold_quick_run(
55    run_result: Result<PromptRunResult, PromptRunError>,
56    shutdown_result: Result<(), RuntimeError>,
57) -> Result<PromptRunResult, QuickRunError> {
58    match (run_result, shutdown_result) {
59        (Ok(output), Ok(())) => Ok(output),
60        (Ok(_), Err(shutdown)) => Err(QuickRunError::Shutdown(shutdown)),
61        (Err(run), Ok(())) => Err(QuickRunError::Run {
62            run,
63            shutdown: None,
64        }),
65        (Err(run), Err(shutdown)) => Err(QuickRunError::Run {
66            run,
67            shutdown: Some(shutdown),
68        }),
69    }
70}