use std::sync::Arc; use crate::agents_md::LoadedAgentsMd; use crate::environment_selection::TurnEnvironmentSnapshot; use crate::session::McpRuntimeSnapshot; use crate::session::turn_context::TurnContext; use codex_exec_server::ExecutorCapabilityDiscoverySnapshot; use codex_exec_server::ResolvedSelectedCapabilityRoot; use codex_mcp::ToolInfo; use tokio::sync::OnceCell; /// Request-scoped state that may change between model sampling requests. #[derive(Debug)] pub(crate) struct StepContext { pub(crate) turn: Arc, pub(crate) environments: TurnEnvironmentSnapshot, /// Capability roots bound to ready environments in this exact step. pub(crate) selected_capability_roots: Vec, /// Executor-materialized capability files shared by MCP and skills in this exact step. pub(crate) executor_capability_discovery: Option>, /// The exact MCP config and manager used to advertise and execute tools for this step. pub(crate) mcp: Arc, /// The fixed MCP tool list used for this exact sampling request. mcp_tool_snapshot: OnceCell>, /// The canonical AGENTS.md value observed with this environment snapshot. pub(crate) loaded_agents_md: Option>, } impl StepContext { pub(crate) fn new( turn: Arc, environments: TurnEnvironmentSnapshot, selected_capability_roots: Vec, executor_capability_discovery: Option>, mcp: Arc, loaded_agents_md: Option>, ) -> Self { Self { turn, environments, selected_capability_roots, executor_capability_discovery, mcp, mcp_tool_snapshot: OnceCell::new(), loaded_agents_md, } } pub(crate) async fn mcp_tools(&self) -> &[ToolInfo] { self.mcp_tool_snapshot .get_or_init(|| self.mcp.manager().list_all_tools()) .await } }