Codex Handbook
cloud-tasks-client/src/api.rs 176 lines
use chrono::DateTime;use chrono::Utc;use serde::Deserialize;use serde::Serialize;use std::future::Future;use std::pin::Pin;pub type Result<T> = std::result::Result<T, CloudTaskError>;pub type CloudBackendFuture<'a, T> = Pin<Box<dyn Future<Output = Result<T>> + Send + 'a>>;#[derive(Debug, thiserror::Error)]pub enum CloudTaskError {    #[error("unimplemented: {0}")]    Unimplemented(&'static str),    #[error("http error: {0}")]    Http(String),    #[error("io error: {0}")]    Io(String),    #[error("{0}")]    Msg(String),}#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]#[serde(transparent)]pub struct TaskId(pub String);#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]#[serde(rename_all = "kebab-case")]pub enum TaskStatus {    Pending,    Ready,    Applied,    Error,}#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]pub struct TaskSummary {    pub id: TaskId,    pub title: String,    pub status: TaskStatus,    pub updated_at: DateTime<Utc>,    /// Backend environment identifier (when available)    pub environment_id: Option<String>,    /// Human-friendly environment label (when available)    pub environment_label: Option<String>,    pub summary: DiffSummary,    /// True when the backend reports this task as a code review.    #[serde(default)]    pub is_review: bool,    /// Number of assistant attempts (best-of-N), when reported by the backend.    #[serde(default)]    pub attempt_total: Option<usize>,}#[derive(Clone, Copy, Debug, PartialEq, Eq, Default)]pub enum AttemptStatus {    Pending,    InProgress,    Completed,    Failed,    Cancelled,    #[default]    Unknown,}#[derive(Clone, Debug, PartialEq, Eq)]pub struct TurnAttempt {    pub turn_id: String,    pub attempt_placement: Option<i64>,    pub created_at: Option<DateTime<Utc>>,    pub status: AttemptStatus,    pub diff: Option<String>,    pub messages: Vec<String>,}#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]#[serde(rename_all = "lowercase")]pub enum ApplyStatus {    Success,    Partial,    Error,}#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]pub struct ApplyOutcome {    pub applied: bool,    pub status: ApplyStatus,    pub message: String,    #[serde(default)]    pub skipped_paths: Vec<String>,    #[serde(default)]    pub conflict_paths: Vec<String>,}#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]pub struct CreatedTask {    pub id: TaskId,}#[derive(Clone, Debug, PartialEq, Eq)]pub struct TaskListPage {    pub tasks: Vec<TaskSummary>,    pub cursor: Option<String>,}#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Default)]pub struct DiffSummary {    pub files_changed: usize,    pub lines_added: usize,    pub lines_removed: usize,}#[derive(Clone, Debug, PartialEq, Eq)]pub struct TaskText {    pub prompt: Option<String>,    pub messages: Vec<String>,    pub turn_id: Option<String>,    pub sibling_turn_ids: Vec<String>,    pub attempt_placement: Option<i64>,    pub attempt_status: AttemptStatus,}impl Default for TaskText {    fn default() -> Self {        Self {            prompt: None,            messages: Vec::new(),            turn_id: None,            sibling_turn_ids: Vec::new(),            attempt_placement: None,            attempt_status: AttemptStatus::Unknown,        }    }}pub trait CloudBackend: Send + Sync {    fn list_tasks<'a>(        &'a self,        env: Option<&'a str>,        limit: Option<i64>,        cursor: Option<&'a str>,    ) -> CloudBackendFuture<'a, TaskListPage>;    fn get_task_summary(&self, id: TaskId) -> CloudBackendFuture<'_, TaskSummary>;    fn get_task_diff(&self, id: TaskId) -> CloudBackendFuture<'_, Option<String>>;    /// Return assistant output messages (no diff) when available.    fn get_task_messages(&self, id: TaskId) -> CloudBackendFuture<'_, Vec<String>>;    /// Return the creating prompt and assistant messages (when available).    fn get_task_text(&self, id: TaskId) -> CloudBackendFuture<'_, TaskText>;    /// Return any sibling attempts (best-of-N) for the given assistant turn.    fn list_sibling_attempts(        &self,        task: TaskId,        turn_id: String,    ) -> CloudBackendFuture<'_, Vec<TurnAttempt>>;    /// Dry-run apply (preflight) that validates whether the patch would apply cleanly.    /// Never modifies the working tree. When `diff_override` is supplied, the provided diff is    /// used instead of re-fetching the task details so callers can apply alternate attempts.    fn apply_task_preflight(        &self,        id: TaskId,        diff_override: Option<String>,    ) -> CloudBackendFuture<'_, ApplyOutcome>;    fn apply_task(        &self,        id: TaskId,        diff_override: Option<String>,    ) -> CloudBackendFuture<'_, ApplyOutcome>;    fn create_task<'a>(        &'a self,        env_id: &'a str,        prompt: &'a str,        git_ref: &'a str,        qa_mode: bool,        best_of_n: usize,    ) -> CloudBackendFuture<'a, CreatedTask>;}