Skip to main content

codex/
output_schema_file.rs

1use std::path::{Path, PathBuf};
2
3use serde_json::Value;
4use tempfile::{Builder, TempDir};
5
6use crate::errors::{Error, Result};
7
8/// Temporary on-disk output schema file passed to `codex --output-schema`.
9///
10/// The underlying temporary directory is kept alive by this struct and cleaned
11/// up automatically when dropped.
12pub struct OutputSchemaFile {
13    _dir: TempDir,
14    path: PathBuf,
15}
16
17impl OutputSchemaFile {
18    /// Returns the filesystem path of the generated schema file.
19    ///
20    /// # Example
21    ///
22    /// ```rust
23    /// use codex::output_schema_file::create_output_schema_file;
24    /// use serde_json::json;
25    ///
26    /// let file = create_output_schema_file(Some(&json!({"type":"object"})))?
27    ///     .expect("schema file should exist");
28    /// assert!(file.path().exists());
29    /// # Ok::<(), codex::Error>(())
30    /// ```
31    pub fn path(&self) -> &Path {
32        &self.path
33    }
34}
35
36/// Creates a temporary JSON schema file for structured output turns.
37///
38/// Returns `Ok(None)` when no schema is provided.
39///
40/// # Example
41///
42/// ```rust
43/// use codex::output_schema_file::create_output_schema_file;
44/// use serde_json::json;
45///
46/// let file = create_output_schema_file(Some(&json!({"type":"object"})))?;
47/// assert!(file.is_some());
48///
49/// let absent = create_output_schema_file(None)?;
50/// assert!(absent.is_none());
51/// # Ok::<(), codex::Error>(())
52/// ```
53pub fn create_output_schema_file(schema: Option<&Value>) -> Result<Option<OutputSchemaFile>> {
54    let Some(schema) = schema else {
55        return Ok(None);
56    };
57
58    if !schema.is_object() {
59        return Err(Error::InvalidOutputSchema(
60            "output_schema must be a plain JSON object".to_string(),
61        ));
62    }
63
64    let dir = Builder::new().prefix("codex-output-schema-").tempdir()?;
65    let schema_path = dir.path().join("schema.json");
66    std::fs::write(&schema_path, serde_json::to_vec(schema)?)?;
67
68    Ok(Some(OutputSchemaFile {
69        _dir: dir,
70        path: schema_path,
71    }))
72}