Files
codex/codex-rs/ext/extension-api/src/contributors/turn_lifecycle.rs
T
Anthony Tafoya d26406987e Add explicit cloud catalog refresh before turn admission (#61449)
## Why

Hosts need to refresh cloud plugin and skill catalogs without starting a turn or waiting for step preparation.

## What changed

- Add `CodexThread::refresh_cloud_plugins()` and a turn-independent extension callback that bypass cached catalog reuse and failure cooldowns.
- Run catalog contributors concurrently while serializing publication with step snapshot capture. Invalidate MCP resource caches before explicit discovery and schedule MCP reconciliation afterward.
- Accept complete and partial catalogs, report discovery errors, and keep failed or cancelled refreshes retryable.
- Allow hosts to gate cloud plugin discovery through effective configuration.

## Testing

Add coverage for discovery before turn admission, catalog replacement and reuse, immediate retry after failure, concurrent contributors, and cancellation-safe publication and invalidation.

GitOrigin-RevId: 83e847fcab6562581af2c9e831b1d2a310f2b270
2026-11-14 02:45:51 +00:00

98 lines
3.4 KiB
Rust

//! Turn lifecycle inputs and scheduling phases for host-owned contributors.
use codex_protocol::config_types::CollaborationMode;
use codex_protocol::error::CodexErrorDetails;
use codex_protocol::protocol::CodexErrorInfo;
use codex_protocol::protocol::TokenUsage;
use codex_protocol::protocol::TurnAbortReason;
use crate::ExtensionData;
/// Runs before task registration or during cancellable regular-task startup.
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum TurnStartPhase {
BeforeTaskRegistration,
RegularTaskStart,
}
/// Input supplied when the host starts a turn.
pub struct TurnStartInput<'a> {
/// Stable host-owned turn identifier.
pub turn_id: &'a str,
/// Effective collaboration mode for this turn.
pub collaboration_mode: &'a CollaborationMode,
/// Total token usage snapshot captured when the turn started.
/// Present before task registration; absent during regular-task preparation.
/// Token-accounting contributors must remain in `BeforeTaskRegistration`.
pub token_usage_at_turn_start: Option<&'a TokenUsage>,
/// Store scoped to the host session runtime.
pub session_store: &'a ExtensionData,
/// Store scoped to this thread runtime.
pub thread_store: &'a ExtensionData,
/// Store scoped to this turn runtime.
pub turn_store: &'a ExtensionData,
}
/// Inputs for refreshing catalogs before a model step.
#[derive(Clone, Copy)]
pub struct CatalogRefreshInput<'a> {
pub turn_id: &'a str,
pub session_store: &'a ExtensionData,
pub thread_store: &'a ExtensionData,
pub turn_store: &'a ExtensionData,
}
/// Inputs for explicit cloud discovery, including before a thread has any turns.
#[derive(Clone, Copy)]
pub struct CloudCatalogRefreshInput<'a> {
pub session_store: &'a ExtensionData,
pub thread_store: &'a ExtensionData,
}
impl<'a> From<CatalogRefreshInput<'a>> for CloudCatalogRefreshInput<'a> {
fn from(input: CatalogRefreshInput<'a>) -> Self {
Self {
session_store: input.session_store,
thread_store: input.thread_store,
}
}
}
/// Input supplied when the host completes a turn.
pub struct TurnStopInput<'a> {
/// Store scoped to the host session runtime.
pub session_store: &'a ExtensionData,
/// Store scoped to this thread runtime.
pub thread_store: &'a ExtensionData,
/// Store scoped to this turn runtime.
pub turn_store: &'a ExtensionData,
}
/// Input supplied when the host aborts a turn.
pub struct TurnAbortInput<'a> {
/// Reason the host aborted the turn.
pub reason: TurnAbortReason,
/// Store scoped to the host session runtime.
pub session_store: &'a ExtensionData,
/// Store scoped to this thread runtime.
pub thread_store: &'a ExtensionData,
/// Store scoped to this turn runtime.
pub turn_store: &'a ExtensionData,
}
/// Input supplied when the host observes an error for a turn.
pub struct TurnErrorInput<'a> {
/// Stable host-owned turn identifier.
pub turn_id: &'a str,
/// Error surfaced by the host for this turn.
pub error: CodexErrorInfo,
/// Original error details, including backend metadata omitted from the public category.
pub error_details: &'a CodexErrorDetails,
/// Store scoped to the host session runtime.
pub session_store: &'a ExtensionData,
/// Store scoped to this thread runtime.
pub thread_store: &'a ExtensionData,
/// Store scoped to this turn runtime.
pub turn_store: &'a ExtensionData,
}