use super::{ExecError, STEP_TOOLS_SUBDIR};
use serde::{Deserialize, Serialize};
use serde_json::Value;
use std::path::{Path, PathBuf};
pub const INPUT_FILE: &str = "input.json";
pub const OUTPUT_FILE: &str = "output.json";
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct ToolInputRecord {
pub id: String,
pub name: String,
pub input: Value,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct ToolOutputRecord {
pub stdout: String,
pub stderr: String,
pub exit_code: i32,
pub started_at: String,
pub ended_at: String,
}
pub(crate) fn tool_call_dir(step_dir: &Path, tool_id: &str) -> PathBuf {
step_dir.join(STEP_TOOLS_SUBDIR).join(tool_id)
}
pub(crate) fn atomic_write_json<T: Serialize>(
dir: &Path,
filename: &str,
value: &T,
) -> Result<(), ExecError> {
let bytes = serde_json::to_vec_pretty(value).expect("serializable record");
let final_path = dir.join(filename);
let tmp_path = dir.join(format!("{filename}.tmp"));
std::fs::write(&tmp_path, bytes).map_err(|source| ExecError::Io {
dir: dir.to_path_buf(),
source,
})?;
std::fs::rename(&tmp_path, &final_path).map_err(|source| ExecError::Io {
dir: dir.to_path_buf(),
source,
})?;
Ok(())
}