Codex Handbook
core/src/tasks/lifecycle.rs 92 lines
use codex_extension_api::ExtensionData;use codex_protocol::protocol::CodexErrorInfo;use codex_protocol::protocol::TokenUsage;use codex_protocol::protocol::TurnAbortReason;use crate::session::session::Session;use crate::session::turn_context::TurnContext;impl Session {    pub(super) async fn emit_turn_start_lifecycle(        &self,        turn_context: &TurnContext,        token_usage_at_turn_start: &TokenUsage,    ) {        for contributor in self.services.extensions.turn_lifecycle_contributors() {            contributor                .on_turn_start(codex_extension_api::TurnStartInput {                    turn_id: turn_context.sub_id.as_str(),                    collaboration_mode: &turn_context.collaboration_mode,                    token_usage_at_turn_start,                    session_store: &self.services.session_extension_data,                    thread_store: &self.services.thread_extension_data,                    turn_store: turn_context.extension_data.as_ref(),                })                .await;        }    }    pub(super) async fn emit_turn_stop_lifecycle(&self, turn_store: &ExtensionData) {        for contributor in self.services.extensions.turn_lifecycle_contributors() {            contributor                .on_turn_stop(codex_extension_api::TurnStopInput {                    session_store: &self.services.session_extension_data,                    thread_store: &self.services.thread_extension_data,                    turn_store,                })                .await;        }    }    pub(crate) async fn emit_thread_idle_lifecycle_if_idle(&self) {        if self.active_turn.lock().await.is_some()            || self.input_queue.has_trigger_turn_mailbox_items().await        {            return;        }        for contributor in self.services.extensions.thread_lifecycle_contributors() {            contributor                .on_thread_idle(codex_extension_api::ThreadIdleInput {                    session_store: &self.services.session_extension_data,                    thread_store: &self.services.thread_extension_data,                })                .await;        }    }    pub(super) async fn emit_turn_abort_lifecycle(        &self,        reason: TurnAbortReason,        turn_store: &ExtensionData,    ) {        for contributor in self.services.extensions.turn_lifecycle_contributors() {            contributor                .on_turn_abort(codex_extension_api::TurnAbortInput {                    reason: reason.clone(),                    session_store: &self.services.session_extension_data,                    thread_store: &self.services.thread_extension_data,                    turn_store,                })                .await;        }    }    pub(crate) async fn emit_turn_error_lifecycle(        &self,        turn_context: &TurnContext,        error: CodexErrorInfo,    ) {        for contributor in self.services.extensions.turn_lifecycle_contributors() {            contributor                .on_turn_error(codex_extension_api::TurnErrorInput {                    turn_id: turn_context.sub_id.as_str(),                    error: error.clone(),                    session_store: &self.services.session_extension_data,                    thread_store: &self.services.thread_extension_data,                    turn_store: turn_context.extension_data.as_ref(),                })                .await;        }    }}