diff --git a/codex-rs/core/src/agent/role.rs b/codex-rs/core/src/agent/role.rs index 6570baa45a..84e7642d97 100644 --- a/codex-rs/core/src/agent/role.rs +++ b/codex-rs/core/src/agent/role.rs @@ -25,7 +25,7 @@ use std::sync::LazyLock; use toml::Value as TomlValue; /// The role name used when a caller omits `agent_type`. -pub const DEFAULT_ROLE_NAME: &str = "default"; +pub(crate) const DEFAULT_ROLE_NAME: &str = "default"; const AGENT_TYPE_UNAVAILABLE_ERROR: &str = "agent type is currently not available"; /// Applies a named role layer to `config` while preserving caller-owned model selection. diff --git a/codex-rs/core/src/client.rs b/codex-rs/core/src/client.rs index d77e36870a..7bfc88f3bd 100644 --- a/codex-rs/core/src/client.rs +++ b/codex-rs/core/src/client.rs @@ -117,12 +117,12 @@ use codex_response_debug_context::extract_response_debug_context_from_api_error; use codex_response_debug_context::telemetry_api_error_message; use codex_response_debug_context::telemetry_transport_error_message; -pub const OPENAI_BETA_HEADER: &str = "OpenAI-Beta"; -pub const X_CODEX_TURN_STATE_HEADER: &str = "x-codex-turn-state"; +pub(crate) const OPENAI_BETA_HEADER: &str = "OpenAI-Beta"; +pub(crate) const X_CODEX_TURN_STATE_HEADER: &str = "x-codex-turn-state"; pub const X_CODEX_TURN_METADATA_HEADER: &str = "x-codex-turn-metadata"; -pub const X_CODEX_PARENT_THREAD_ID_HEADER: &str = "x-codex-parent-thread-id"; -pub const X_CODEX_WINDOW_ID_HEADER: &str = "x-codex-window-id"; -pub const X_OPENAI_SUBAGENT_HEADER: &str = "x-openai-subagent"; +pub(crate) const X_CODEX_PARENT_THREAD_ID_HEADER: &str = "x-codex-parent-thread-id"; +pub(crate) const X_CODEX_WINDOW_ID_HEADER: &str = "x-codex-window-id"; +pub(crate) const X_OPENAI_SUBAGENT_HEADER: &str = "x-openai-subagent"; pub const X_RESPONSESAPI_INCLUDE_TIMING_METRICS_HEADER: &str = "x-responsesapi-include-timing-metrics"; const RESPONSES_WEBSOCKETS_V2_BETA_HEADER_VALUE: &str = "responses_websockets=2026-02-06"; diff --git a/codex-rs/core/src/client_common.rs b/codex-rs/core/src/client_common.rs index cb50ccac39..6ae58aaced 100644 --- a/codex-rs/core/src/client_common.rs +++ b/codex-rs/core/src/client_common.rs @@ -18,8 +18,9 @@ use tokio::sync::mpsc; pub const REVIEW_PROMPT: &str = include_str!("../review_prompt.md"); // Centralized templates for review-related user messages -pub const REVIEW_EXIT_SUCCESS_TMPL: &str = include_str!("../templates/review/exit_success.xml"); -pub const REVIEW_EXIT_INTERRUPTED_TMPL: &str = +pub(crate) const REVIEW_EXIT_SUCCESS_TMPL: &str = + include_str!("../templates/review/exit_success.xml"); +pub(crate) const REVIEW_EXIT_INTERRUPTED_TMPL: &str = include_str!("../templates/review/exit_interrupted.xml"); /// API request payload for a single model turn diff --git a/codex-rs/core/src/codex.rs b/codex-rs/core/src/codex.rs index 4bf309c902..80d683106c 100644 --- a/codex-rs/core/src/codex.rs +++ b/codex-rs/core/src/codex.rs @@ -149,7 +149,6 @@ use rmcp::model::PaginatedRequestParams; use rmcp::model::ReadResourceRequestParams; use rmcp::model::ReadResourceResult; use rmcp::model::RequestId; -use serde_json; use serde_json::Value; use tokio::sync::Mutex; use tokio::sync::RwLock; @@ -388,7 +387,7 @@ use codex_utils_readiness::ReadinessFlag; /// The high-level interface to the Codex system. /// It operates as a queue pair where you send submissions and receive events. -pub struct Codex { +pub(crate) struct Codex { pub(crate) tx_sub: Sender, pub(crate) rx_event: Receiver, // Last known status of the agent. @@ -404,11 +403,9 @@ pub(crate) type SessionLoopTermination = Shared>; /// Wrapper returned by [`Codex::spawn`] containing the spawned [`Codex`], /// the submission id for the initial `ConfigureSession` request and the /// unique session id. -pub struct CodexSpawnOk { - pub codex: Codex, - pub thread_id: ThreadId, - #[deprecated(note = "use thread_id")] - pub conversation_id: ThreadId, +pub(crate) struct CodexSpawnOk { + pub(crate) codex: Codex, + pub(crate) thread_id: ThreadId, } pub(crate) struct CodexSpawnArgs { @@ -693,20 +690,15 @@ impl Codex { session_loop_termination: session_loop_termination_from_handle(session_loop_handle), }; - #[allow(deprecated)] - Ok(CodexSpawnOk { - codex, - thread_id, - conversation_id: thread_id, - }) + Ok(CodexSpawnOk { codex, thread_id }) } /// Submit the `op` wrapped in a `Submission` with a unique ID. - pub async fn submit(&self, op: Op) -> CodexResult { + pub(crate) async fn submit(&self, op: Op) -> CodexResult { self.submit_with_trace(op, /*trace*/ None).await } - pub async fn submit_with_trace( + pub(crate) async fn submit_with_trace( &self, op: Op, trace: Option, @@ -723,7 +715,7 @@ impl Codex { /// Use sparingly: prefer `submit()` so Codex is responsible for generating /// unique IDs for each submission. - pub async fn submit_with_id(&self, mut sub: Submission) -> CodexResult<()> { + pub(crate) async fn submit_with_id(&self, mut sub: Submission) -> CodexResult<()> { if sub.trace.is_none() { sub.trace = current_span_w3c_trace_context(); } @@ -734,7 +726,7 @@ impl Codex { Ok(()) } - pub async fn shutdown_and_wait(&self) -> CodexResult<()> { + pub(crate) async fn shutdown_and_wait(&self) -> CodexResult<()> { let session_loop_termination = self.session_loop_termination.clone(); match self.submit(Op::Shutdown).await { Ok(_) => {} @@ -745,7 +737,7 @@ impl Codex { Ok(()) } - pub async fn next_event(&self) -> CodexResult { + pub(crate) async fn next_event(&self) -> CodexResult { let event = self .rx_event .recv() @@ -754,7 +746,7 @@ impl Codex { Ok(event) } - pub async fn steer_input( + pub(crate) async fn steer_input( &self, input: Vec, expected_turn_id: Option<&str>, @@ -867,8 +859,8 @@ pub(crate) struct TurnContext { /// by the model as well as sandbox policies are resolved against this path /// instead of `std::env::current_dir()`. pub(crate) cwd: AbsolutePathBuf, - pub(crate) current_date: Option, pub(crate) timezone: Option, + pub(crate) current_date: Option, pub(crate) app_server_client_name: Option, pub(crate) developer_instructions: Option, pub(crate) compact_prompt: Option, @@ -3034,7 +3026,7 @@ impl Session { /// be used to derive the available decisions via /// [ExecApprovalRequestEvent::default_available_decisions]. #[allow(clippy::too_many_arguments)] - pub async fn request_command_approval( + pub(crate) async fn request_command_approval( &self, turn_context: &TurnContext, call_id: String, @@ -3105,7 +3097,7 @@ impl Session { rx_approve.await.unwrap_or(ReviewDecision::Abort) } - pub async fn request_patch_approval( + pub(crate) async fn request_patch_approval( &self, turn_context: &TurnContext, call_id: String, @@ -3141,7 +3133,7 @@ impl Session { rx_approve } - pub async fn request_permissions( + pub(crate) async fn request_permissions( &self, turn_context: &TurnContext, call_id: String, @@ -3196,7 +3188,7 @@ impl Session { rx_response.await.ok() } - pub async fn request_user_input( + pub(crate) async fn request_user_input( &self, turn_context: &TurnContext, call_id: String, @@ -3228,7 +3220,7 @@ impl Session { rx_response.await.ok() } - pub async fn request_mcp_server_elicitation( + pub(crate) async fn request_mcp_server_elicitation( &self, turn_context: &TurnContext, request_id: RequestId, @@ -3307,7 +3299,7 @@ impl Session { rx_response.await.ok() } - pub async fn notify_user_input_response( + pub(crate) async fn notify_user_input_response( &self, sub_id: &str, response: RequestUserInputResponse, @@ -3332,7 +3324,7 @@ impl Session { } } - pub async fn notify_request_permissions_response( + pub(crate) async fn notify_request_permissions_response( &self, call_id: &str, response: RequestPermissionsResponse, @@ -3385,7 +3377,11 @@ impl Session { state.granted_permissions() } - pub async fn notify_dynamic_tool_response(&self, call_id: &str, response: DynamicToolResponse) { + pub(crate) async fn notify_dynamic_tool_response( + &self, + call_id: &str, + response: DynamicToolResponse, + ) { let entry = { let mut active = self.active_turn.lock().await; match active.as_mut() { @@ -3406,7 +3402,7 @@ impl Session { } } - pub async fn notify_approval(&self, approval_id: &str, decision: ReviewDecision) { + pub(crate) async fn notify_approval(&self, approval_id: &str, decision: ReviewDecision) { let entry = { let mut active = self.active_turn.lock().await; match active.as_mut() { @@ -3427,7 +3423,7 @@ impl Session { } } - pub async fn resolve_elicitation( + pub(crate) async fn resolve_elicitation( &self, server_name: String, id: RequestId, @@ -3574,7 +3570,7 @@ impl Session { self.persist_rollout_items(&rollout_items).await; } - pub fn enabled(&self, feature: Feature) -> bool { + pub(crate) fn enabled(&self, feature: Feature) -> bool { self.features.enabled(feature) } @@ -3913,12 +3909,12 @@ impl Session { state.record_mcp_dependency_prompted(names); } - pub async fn dependency_env(&self) -> HashMap { + pub(crate) async fn dependency_env(&self) -> HashMap { let state = self.state.lock().await; state.dependency_env() } - pub async fn set_dependency_env(&self, values: HashMap) { + pub(crate) async fn set_dependency_env(&self, values: HashMap) { let mut state = self.state.lock().await; state.set_dependency_env(values); } @@ -4038,7 +4034,7 @@ impl Session { /// Inject additional user input into the currently active turn. /// /// Returns the active turn id when accepted. - pub async fn steer_input( + pub(crate) async fn steer_input( &self, input: Vec, expected_turn_id: Option<&str>, @@ -4087,7 +4083,7 @@ impl Session { } /// Returns the input if there was no task running to inject into. - pub async fn inject_response_items( + pub(crate) async fn inject_response_items( &self, input: Vec, ) -> Result<(), Vec> { @@ -4152,7 +4148,10 @@ impl Session { self.mailbox_rx.lock().await.has_pending_trigger_turn() } - pub async fn prepend_pending_input(&self, input: Vec) -> Result<(), ()> { + pub(crate) async fn prepend_pending_input( + &self, + input: Vec, + ) -> Result<(), ()> { let mut active = self.active_turn.lock().await; match active.as_mut() { Some(at) => { @@ -4164,7 +4163,7 @@ impl Session { } } - pub async fn get_pending_input(&self) -> Vec { + pub(crate) async fn get_pending_input(&self) -> Vec { let (pending_input, accepts_mailbox_delivery) = { let mut active = self.active_turn.lock().await; match active.as_mut() { @@ -4219,7 +4218,7 @@ impl Session { !self.idle_pending_input.lock().await.is_empty() } - pub async fn has_pending_input(&self) -> bool { + pub(crate) async fn has_pending_input(&self) -> bool { let (has_turn_pending_input, accepts_mailbox_delivery) = { let active = self.active_turn.lock().await; match active.as_ref() { @@ -4242,7 +4241,7 @@ impl Session { self.mailbox_rx.lock().await.has_pending() } - pub async fn list_resources( + pub(crate) async fn list_resources( &self, server: &str, params: Option, @@ -4255,7 +4254,7 @@ impl Session { .await } - pub async fn list_resource_templates( + pub(crate) async fn list_resource_templates( &self, server: &str, params: Option, @@ -4268,7 +4267,7 @@ impl Session { .await } - pub async fn read_resource( + pub(crate) async fn read_resource( &self, server: &str, params: ReadResourceRequestParams, @@ -4281,7 +4280,7 @@ impl Session { .await } - pub async fn call_tool( + pub(crate) async fn call_tool( &self, server: &str, tool: &str, @@ -4318,7 +4317,7 @@ impl Session { .await } - pub async fn interrupt_task(self: &Arc) { + pub(crate) async fn interrupt_task(self: &Arc) { info!("interrupt received: abort current task, if any"); let has_active_turn = { self.active_turn.lock().await.is_some() }; if has_active_turn { @@ -4805,15 +4804,15 @@ mod handlers { use tracing::info; use tracing::warn; - pub async fn interrupt(sess: &Arc) { + pub(super) async fn interrupt(sess: &Arc) { sess.interrupt_task().await; } - pub async fn clean_background_terminals(sess: &Arc) { + pub(super) async fn clean_background_terminals(sess: &Arc) { sess.close_unified_exec_processes().await; } - pub async fn override_turn_context( + pub(super) async fn override_turn_context( sess: &Session, sub_id: String, updates: SessionSettingsUpdate, @@ -4830,7 +4829,7 @@ mod handlers { } } - pub async fn user_input_or_turn(sess: &Arc, sub_id: String, op: Op) { + pub(super) async fn user_input_or_turn(sess: &Arc, sub_id: String, op: Op) { let (items, updates) = match op { Op::UserTurn { cwd, @@ -4921,7 +4920,7 @@ mod handlers { /// Records an inter-agent assistant envelope, then lets the shared pending-work scheduler /// decide whether an idle session should start a regular turn. - pub async fn inter_agent_communication( + pub(super) async fn inter_agent_communication( sess: &Arc, sub_id: String, communication: InterAgentCommunication, @@ -4934,7 +4933,11 @@ mod handlers { } } - pub async fn run_user_shell_command(sess: &Arc, sub_id: String, command: String) { + pub(super) async fn run_user_shell_command( + sess: &Arc, + sub_id: String, + command: String, + ) { if let Some((turn_context, cancellation_token)) = sess.active_turn_context_and_cancellation_token().await { @@ -4961,7 +4964,7 @@ mod handlers { .await; } - pub async fn resolve_elicitation( + pub(super) async fn resolve_elicitation( sess: &Arc, server_name: String, request_id: ProtocolRequestId, @@ -5003,7 +5006,7 @@ mod handlers { /// Propagate a user's exec approval decision to the session. /// Also optionally applies an execpolicy amendment. - pub async fn exec_approval( + pub(super) async fn exec_approval( sess: &Arc, approval_id: String, turn_id: Option, @@ -5045,7 +5048,7 @@ mod handlers { } } - pub async fn patch_approval(sess: &Arc, id: String, decision: ReviewDecision) { + pub(super) async fn patch_approval(sess: &Arc, id: String, decision: ReviewDecision) { match decision { ReviewDecision::Abort => { sess.interrupt_task().await; @@ -5054,7 +5057,7 @@ mod handlers { } } - pub async fn request_user_input_response( + pub(super) async fn request_user_input_response( sess: &Arc, id: String, response: RequestUserInputResponse, @@ -5062,7 +5065,7 @@ mod handlers { sess.notify_user_input_response(&id, response).await; } - pub async fn request_permissions_response( + pub(super) async fn request_permissions_response( sess: &Arc, id: String, response: RequestPermissionsResponse, @@ -5071,7 +5074,7 @@ mod handlers { .await; } - pub async fn dynamic_tool_response( + pub(super) async fn dynamic_tool_response( sess: &Arc, id: String, response: DynamicToolResponse, @@ -5079,7 +5082,7 @@ mod handlers { sess.notify_dynamic_tool_response(&id, response).await; } - pub async fn add_to_history(sess: &Arc, config: &Arc, text: String) { + pub(super) async fn add_to_history(sess: &Arc, config: &Arc, text: String) { let id = sess.conversation_id; let config = Arc::clone(config); tokio::spawn(async move { @@ -5089,7 +5092,7 @@ mod handlers { }); } - pub async fn get_history_entry_request( + pub(super) async fn get_history_entry_request( sess: &Arc, config: &Arc, sub_id: String, @@ -5126,16 +5129,19 @@ mod handlers { }); } - pub async fn refresh_mcp_servers(sess: &Arc, refresh_config: McpServerRefreshConfig) { + pub(super) async fn refresh_mcp_servers( + sess: &Arc, + refresh_config: McpServerRefreshConfig, + ) { let mut guard = sess.pending_mcp_server_refresh_config.lock().await; *guard = Some(refresh_config); } - pub async fn reload_user_config(sess: &Arc) { + pub(super) async fn reload_user_config(sess: &Arc) { sess.reload_user_config_layer().await; } - pub async fn list_mcp_tools(sess: &Session, config: &Arc, sub_id: String) { + pub(super) async fn list_mcp_tools(sess: &Session, config: &Arc, sub_id: String) { let mcp_connection_manager = sess.services.mcp_connection_manager.read().await; let auth = sess.services.auth_manager.auth().await; let mcp_servers = sess @@ -5155,7 +5161,7 @@ mod handlers { sess.send_event_raw(event).await; } - pub async fn list_skills( + pub(super) async fn list_skills( sess: &Session, sub_id: String, cwds: Vec, @@ -5244,13 +5250,13 @@ mod handlers { sess.send_event_raw(event).await; } - pub async fn undo(sess: &Arc, sub_id: String) { + pub(super) async fn undo(sess: &Arc, sub_id: String) { let turn_context = sess.new_default_turn_with_sub_id(sub_id).await; sess.spawn_task(turn_context, Vec::new(), UndoTask::new()) .await; } - pub async fn compact(sess: &Arc, sub_id: String) { + pub(super) async fn compact(sess: &Arc, sub_id: String) { let turn_context = sess.new_default_turn_with_sub_id(sub_id).await; sess.spawn_task( @@ -5265,7 +5271,7 @@ mod handlers { .await; } - pub async fn drop_memories(sess: &Arc, config: &Arc, sub_id: String) { + pub(super) async fn drop_memories(sess: &Arc, config: &Arc, sub_id: String) { let mut errors = Vec::new(); if let Some(state_db) = sess.services.state_db.as_deref() { @@ -5308,7 +5314,7 @@ mod handlers { .await; } - pub async fn update_memories(sess: &Arc, config: &Arc, sub_id: String) { + pub(super) async fn update_memories(sess: &Arc, config: &Arc, sub_id: String) { let session_source = { let state = sess.state.lock().await; state.session_configuration.session_source.clone() @@ -5325,7 +5331,7 @@ mod handlers { .await; } - pub async fn thread_rollback(sess: &Arc, sub_id: String, num_turns: u32) { + pub(super) async fn thread_rollback(sess: &Arc, sub_id: String, num_turns: u32) { if num_turns == 0 { sess.send_event_raw(Event { id: sub_id, @@ -5436,7 +5442,7 @@ mod handlers { /// current `thread_id`, then updates `SessionConfiguration::thread_name`. /// /// Returns an error event if the name is empty or session persistence is disabled. - pub async fn set_thread_name(sess: &Arc, sub_id: String, name: String) { + pub(super) async fn set_thread_name(sess: &Arc, sub_id: String, name: String) { let Some(name) = crate::util::normalize_thread_name(&name) else { let event = Event { id: sub_id, @@ -5495,7 +5501,7 @@ mod handlers { .await; } - pub async fn shutdown(sess: &Arc, sub_id: String) -> bool { + pub(super) async fn shutdown(sess: &Arc, sub_id: String) -> bool { sess.abort_all_tasks(TurnAbortReason::Interrupted).await; let _ = sess.conversation.shutdown().await; sess.services @@ -5544,7 +5550,7 @@ mod handlers { true } - pub async fn review( + pub(super) async fn review( sess: &Arc, config: &Arc, sub_id: String, diff --git a/codex-rs/core/src/codex_tests_guardian.rs b/codex-rs/core/src/codex_tests_guardian.rs index 4f60c2f28e..98388f29a5 100644 --- a/codex-rs/core/src/codex_tests_guardian.rs +++ b/codex-rs/core/src/codex_tests_guardian.rs @@ -282,7 +282,7 @@ async fn process_compacted_history_preserves_separate_guardian_developer_message .iter() .filter_map(|item| match item { ResponseItem::Message { role, content, .. } if role == "developer" => { - crate::content_items_to_text(content) + crate::compact::content_items_to_text(content) } _ => None, }) diff --git a/codex-rs/core/src/compact.rs b/codex-rs/core/src/compact.rs index 8300dc650c..4e0cacfe06 100644 --- a/codex-rs/core/src/compact.rs +++ b/codex-rs/core/src/compact.rs @@ -233,7 +233,7 @@ async fn run_compact_task_inner( Ok(()) } -pub fn content_items_to_text(content: &[ContentItem]) -> Option { +pub(crate) fn content_items_to_text(content: &[ContentItem]) -> Option { let mut pieces = Vec::new(); for item in content { match item { diff --git a/codex-rs/core/src/connectors.rs b/codex-rs/core/src/connectors.rs index 334e160f12..96eaff9424 100644 --- a/codex-rs/core/src/connectors.rs +++ b/codex-rs/core/src/connectors.rs @@ -613,7 +613,7 @@ pub fn merge_plugin_apps( merged } -pub fn merge_plugin_apps_with_accessible( +pub(crate) fn merge_plugin_apps_with_accessible( plugin_apps: Vec, accessible_connectors: Vec, ) -> Vec { @@ -655,7 +655,7 @@ pub fn with_app_enabled_state(mut connectors: Vec, config: &Config) -> connectors } -pub fn with_app_plugin_sources( +fn with_app_plugin_sources( mut connectors: Vec, tool_plugin_provenance: &ToolPluginProvenance, ) -> Vec { @@ -953,7 +953,8 @@ pub fn connector_install_url(name: &str, connector_id: &str) -> String { format!("https://chatgpt.com/apps/{slug}/{connector_id}") } -pub fn sanitize_name(name: &str) -> String { +#[cfg(test)] +pub(crate) fn sanitize_name(name: &str) -> String { sanitize_slug(name).replace("-", "_") } diff --git a/codex-rs/core/src/environment_context.rs b/codex-rs/core/src/environment_context.rs index df4e49cf4e..c6da02e499 100644 --- a/codex-rs/core/src/environment_context.rs +++ b/codex-rs/core/src/environment_context.rs @@ -26,7 +26,7 @@ pub(crate) struct NetworkContext { } impl EnvironmentContext { - pub fn new( + pub(crate) fn new( cwd: Option, shell: Shell, current_date: Option, @@ -47,7 +47,7 @@ impl EnvironmentContext { /// Compares two environment contexts, ignoring the shell. Useful when /// comparing turn to turn, since the initial environment_context will /// include the shell, and then it is not configurable from turn to turn. - pub fn equals_except_shell(&self, other: &EnvironmentContext) -> bool { + pub(crate) fn equals_except_shell(&self, other: &EnvironmentContext) -> bool { let EnvironmentContext { cwd, current_date, @@ -63,7 +63,7 @@ impl EnvironmentContext { && self.subagents == *subagents } - pub fn diff_from_turn_context_item( + pub(crate) fn diff_from_turn_context_item( before: &TurnContextItem, after: &TurnContext, shell: &Shell, @@ -92,7 +92,7 @@ impl EnvironmentContext { ) } - pub fn from_turn_context(turn_context: &TurnContext, shell: &Shell) -> Self { + pub(crate) fn from_turn_context(turn_context: &TurnContext, shell: &Shell) -> Self { Self::new( Some(turn_context.cwd.to_path_buf()), shell.clone(), @@ -103,7 +103,10 @@ impl EnvironmentContext { ) } - pub fn from_turn_context_item(turn_context_item: &TurnContextItem, shell: &Shell) -> Self { + pub(crate) fn from_turn_context_item( + turn_context_item: &TurnContextItem, + shell: &Shell, + ) -> Self { Self::new( Some(turn_context_item.cwd.clone()), shell.clone(), @@ -114,7 +117,7 @@ impl EnvironmentContext { ) } - pub fn with_subagents(mut self, subagents: String) -> Self { + pub(crate) fn with_subagents(mut self, subagents: String) -> Self { if !subagents.is_empty() { self.subagents = Some(subagents); } @@ -168,7 +171,7 @@ impl EnvironmentContext { /// ... /// /// ``` - pub fn serialize_to_xml(self) -> String { + pub(crate) fn serialize_to_xml(self) -> String { let mut lines = Vec::new(); if let Some(cwd) = self.cwd { lines.push(format!(" {}", cwd.to_string_lossy())); diff --git a/codex-rs/core/src/exec_policy.rs b/codex-rs/core/src/exec_policy.rs index dbfab81d32..a249970f54 100644 --- a/codex-rs/core/src/exec_policy.rs +++ b/codex-rs/core/src/exec_policy.rs @@ -174,7 +174,7 @@ pub enum ExecPolicyError { } #[derive(Debug, Error)] -pub enum ExecPolicyUpdateError { +pub(crate) enum ExecPolicyUpdateError { #[error("failed to update rules file {path}: {source}")] AppendRule { path: PathBuf, source: AmendError }, @@ -535,7 +535,7 @@ pub async fn load_exec_policy(config_stack: &ConfigLayerStack) -> Result, @@ -190,7 +190,7 @@ pub struct ThrottledWatchReceiver { impl ThrottledWatchReceiver { /// Creates a throttling wrapper around a raw watcher [`Receiver`]. - pub fn new(rx: Receiver, interval: Duration) -> Self { + pub(crate) fn new(rx: Receiver, interval: Duration) -> Self { Self { rx, interval, @@ -200,7 +200,7 @@ impl ThrottledWatchReceiver { /// Receives the next event, enforcing the configured minimum delay after /// the previous emission. - pub async fn recv(&mut self) -> Option { + pub(crate) async fn recv(&mut self) -> Option { if let Some(next_allowed) = self.next_allowed { sleep_until(next_allowed).await; } diff --git a/codex-rs/core/src/function_tool.rs b/codex-rs/core/src/function_tool.rs index 240e04361c..be64ea7012 100644 --- a/codex-rs/core/src/function_tool.rs +++ b/codex-rs/core/src/function_tool.rs @@ -1,7 +1,7 @@ use thiserror::Error; #[derive(Debug, Error, PartialEq)] -pub enum FunctionCallError { +pub(crate) enum FunctionCallError { #[error("{0}")] RespondToModel(String), #[error("LocalShellCall without call_id or id")] diff --git a/codex-rs/core/src/instructions/mod.rs b/codex-rs/core/src/instructions/mod.rs index 5af9a6e890..a1f77ba5e8 100644 --- a/codex-rs/core/src/instructions/mod.rs +++ b/codex-rs/core/src/instructions/mod.rs @@ -1,2 +1 @@ -pub use codex_instructions::USER_INSTRUCTIONS_PREFIX; pub(crate) use codex_instructions::UserInstructions; diff --git a/codex-rs/core/src/lib.rs b/codex-rs/core/src/lib.rs index d68c2b2992..6f95a6a1d7 100644 --- a/codex-rs/core/src/lib.rs +++ b/codex-rs/core/src/lib.rs @@ -10,7 +10,7 @@ mod apps; mod arc_monitor; mod client; mod client_common; -pub mod codex; +mod codex; mod realtime_context; mod realtime_conversation; pub use codex::SteerInputError; @@ -38,13 +38,12 @@ mod flags; mod git_info_tests; mod guardian; mod hook_runtime; -pub mod instructions; +mod instructions; pub mod landlock; pub mod mcp; mod mcp_skill_dependencies; mod mcp_tool_approval_templates; mod network_policy_decision; -pub mod network_proxy_loader; mod original_image_detail; pub use codex_mcp::mcp_connection_manager; pub use codex_mcp::mcp_connection_manager::MCP_SANDBOX_STATE_CAPABILITY; @@ -54,7 +53,7 @@ mod mcp_tool_call; mod memories; pub mod mention_syntax; pub mod message_history; -pub mod utils; +mod utils; pub use utils::path_utils; pub mod personality_migration; pub mod plugins; @@ -119,12 +118,11 @@ pub(crate) mod safety; pub mod seatbelt; mod session_rollout_init_error; pub mod shell; -pub mod shell_snapshot; +mod shell_snapshot; pub mod spawn; -pub mod state_db_bridge; mod thread_rollout_truncation; mod tools; -pub mod turn_diff_tracker; +mod turn_diff_tracker; mod turn_metadata; mod turn_timing; pub use rollout::ARCHIVED_SESSIONS_SUBDIR; @@ -163,7 +161,6 @@ pub use client_common::Prompt; pub use client_common::REVIEW_PROMPT; pub use client_common::ResponseEvent; pub use client_common::ResponseStream; -pub use compact::content_items_to_text; pub use event_mapping::parse_turn_item; pub use exec_policy::ExecPolicyError; pub use exec_policy::check_execpolicy_for_warnings; @@ -172,5 +169,4 @@ pub use exec_policy::load_exec_policy; pub use file_watcher::FileWatcherEvent; pub use turn_metadata::build_turn_metadata_header; pub mod compact; -pub mod memory_trace; pub mod otel_init; diff --git a/codex-rs/core/src/mcp.rs b/codex-rs/core/src/mcp.rs index d82452c54d..eec7f7e498 100644 --- a/codex-rs/core/src/mcp.rs +++ b/codex-rs/core/src/mcp.rs @@ -34,7 +34,7 @@ impl McpManager { effective_mcp_servers(&mcp_config, auth) } - pub fn tool_plugin_provenance(&self, config: &Config) -> ToolPluginProvenance { + pub(crate) fn tool_plugin_provenance(&self, config: &Config) -> ToolPluginProvenance { let mcp_config = config.to_mcp_config(self.plugins_manager.as_ref()); collect_tool_plugin_provenance(&mcp_config) } diff --git a/codex-rs/core/src/memories/citations.rs b/codex-rs/core/src/memories/citations.rs index d8642880f1..6371b3a949 100644 --- a/codex-rs/core/src/memories/citations.rs +++ b/codex-rs/core/src/memories/citations.rs @@ -3,7 +3,7 @@ use codex_protocol::memory_citation::MemoryCitation; use codex_protocol::memory_citation::MemoryCitationEntry; use std::collections::HashSet; -pub fn parse_memory_citation(citations: Vec) -> Option { +pub(crate) fn parse_memory_citation(citations: Vec) -> Option { let mut entries = Vec::new(); let mut rollout_ids = Vec::new(); let mut seen_rollout_ids = HashSet::new(); @@ -42,7 +42,7 @@ pub fn parse_memory_citation(citations: Vec) -> Option { } } -pub fn get_thread_id_from_citations(citations: Vec) -> Vec { +pub(crate) fn get_thread_id_from_citations(citations: Vec) -> Vec { let mut result = Vec::new(); if let Some(memory_citation) = parse_memory_citation(citations) { for rollout_id in memory_citation.rollout_ids { diff --git a/codex-rs/core/src/memories/mod.rs b/codex-rs/core/src/memories/mod.rs index ac49c640ca..ec4124cf20 100644 --- a/codex-rs/core/src/memories/mod.rs +++ b/codex-rs/core/src/memories/mod.rs @@ -98,7 +98,7 @@ mod metrics { use std::path::Path; use std::path::PathBuf; -pub fn memory_root(codex_home: &Path) -> PathBuf { +pub(crate) fn memory_root(codex_home: &Path) -> PathBuf { codex_home.join("memories") } diff --git a/codex-rs/core/src/memories/phase1.rs b/codex-rs/core/src/memories/phase1.rs index 37cb0e9f48..78ace917cc 100644 --- a/codex-rs/core/src/memories/phase1.rs +++ b/codex-rs/core/src/memories/phase1.rs @@ -147,7 +147,7 @@ pub(in crate::memories) async fn prune(session: &Arc, config: &Config) } /// JSON schema used to constrain phase-1 model output. -pub fn output_schema() -> Value { +pub(super) fn output_schema() -> Value { json!({ "type": "object", "properties": { diff --git a/codex-rs/core/src/otel_init.rs b/codex-rs/core/src/otel_init.rs index c732692d62..e735056006 100644 --- a/codex-rs/core/src/otel_init.rs +++ b/codex-rs/core/src/otel_init.rs @@ -91,9 +91,3 @@ pub fn build_provider( runtime_metrics, }) } - -/// Filter predicate for exporting only Codex-owned events via OTEL. -/// Keeps events that originated from codex_otel module -pub fn codex_export_filter(meta: &tracing::Metadata<'_>) -> bool { - meta.target().starts_with("codex_otel") -} diff --git a/codex-rs/core/src/plugins/manager.rs b/codex-rs/core/src/plugins/manager.rs index 1da98b85cb..b881be7357 100644 --- a/codex-rs/core/src/plugins/manager.rs +++ b/codex-rs/core/src/plugins/manager.rs @@ -80,7 +80,7 @@ const DEFAULT_SKILLS_DIR_NAME: &str = "skills"; const DEFAULT_MCP_CONFIG_FILE: &str = ".mcp.json"; const DEFAULT_APP_CONFIG_FILE: &str = ".app.json"; pub const OPENAI_CURATED_MARKETPLACE_NAME: &str = "openai-curated"; -pub const OPENAI_CURATED_MARKETPLACE_DISPLAY_NAME: &str = "OpenAI Curated"; +pub(super) const OPENAI_CURATED_MARKETPLACE_DISPLAY_NAME: &str = "OpenAI Curated"; static CURATED_REPO_SYNC_STARTED: AtomicBool = AtomicBool::new(false); const FEATURED_PLUGIN_IDS_CACHE_TTL: std::time::Duration = std::time::Duration::from_secs(60 * 60 * 3); @@ -1882,7 +1882,7 @@ fn load_apps_from_paths( connector_ids } -pub fn plugin_telemetry_metadata_from_root( +pub(crate) fn plugin_telemetry_metadata_from_root( plugin_id: &PluginId, plugin_root: &Path, ) -> PluginTelemetryMetadata { diff --git a/codex-rs/core/src/plugins/manifest.rs b/codex-rs/core/src/plugins/manifest.rs index f1253441bd..7aeb36eb12 100644 --- a/codex-rs/core/src/plugins/manifest.rs +++ b/codex-rs/core/src/plugins/manifest.rs @@ -39,7 +39,7 @@ pub(crate) struct PluginManifest { } #[derive(Debug, Clone, PartialEq, Eq)] -pub struct PluginManifestPaths { +pub(crate) struct PluginManifestPaths { pub skills: Option, pub mcp_servers: Option, pub apps: Option, diff --git a/codex-rs/core/src/plugins/marketplace.rs b/codex-rs/core/src/plugins/marketplace.rs index ee775262aa..bce50715d5 100644 --- a/codex-rs/core/src/plugins/marketplace.rs +++ b/codex-rs/core/src/plugins/marketplace.rs @@ -19,14 +19,14 @@ use tracing::warn; const MARKETPLACE_RELATIVE_PATH: &str = ".agents/plugins/marketplace.json"; #[derive(Debug, Clone, PartialEq, Eq)] -pub struct ResolvedMarketplacePlugin { +pub(super) struct ResolvedMarketplacePlugin { pub plugin_id: PluginId, pub source_path: AbsolutePathBuf, pub auth_policy: MarketplacePluginAuthPolicy, } #[derive(Debug, Clone, PartialEq, Eq)] -pub struct Marketplace { +pub(super) struct Marketplace { pub name: String, pub path: AbsolutePathBuf, pub interface: Option, @@ -40,7 +40,7 @@ pub struct MarketplaceListError { } #[derive(Debug, Clone, Default, PartialEq, Eq)] -pub struct MarketplaceListOutcome { +pub(super) struct MarketplaceListOutcome { pub marketplaces: Vec, pub errors: Vec, } @@ -51,7 +51,7 @@ pub struct MarketplaceInterface { } #[derive(Debug, Clone, PartialEq, Eq)] -pub struct MarketplacePlugin { +pub(super) struct MarketplacePlugin { pub name: String, pub source: MarketplacePluginSource, pub policy: MarketplacePluginPolicy, @@ -155,7 +155,7 @@ impl MarketplaceError { // Always read the specified marketplace file from disk so installs see the // latest marketplace.json contents without any in-memory cache invalidation. -pub fn resolve_marketplace_plugin( +pub(super) fn resolve_marketplace_plugin( marketplace_path: &AbsolutePathBuf, plugin_name: &str, restriction_product: Option, @@ -205,7 +205,7 @@ pub fn resolve_marketplace_plugin( }) } -pub fn list_marketplaces( +pub(super) fn list_marketplaces( additional_roots: &[AbsolutePathBuf], ) -> Result { list_marketplaces_with_home(additional_roots, home_dir().as_deref()) diff --git a/codex-rs/core/src/plugins/mod.rs b/codex-rs/core/src/plugins/mod.rs index a86502c28c..58c2468101 100644 --- a/codex-rs/core/src/plugins/mod.rs +++ b/codex-rs/core/src/plugins/mod.rs @@ -43,7 +43,6 @@ pub use manager::RemotePluginSyncResult; pub use manager::installed_plugin_telemetry_metadata; pub use manager::load_plugin_apps; pub use manager::load_plugin_mcp_servers; -pub use manager::plugin_telemetry_metadata_from_root; pub use manifest::PluginManifestInterface; pub(crate) use manifest::PluginManifestPaths; pub(crate) use manifest::load_plugin_manifest; diff --git a/codex-rs/core/src/plugins/store.rs b/codex-rs/core/src/plugins/store.rs index 4316f18002..59852f05e7 100644 --- a/codex-rs/core/src/plugins/store.rs +++ b/codex-rs/core/src/plugins/store.rs @@ -15,30 +15,30 @@ pub(crate) const DEFAULT_PLUGIN_VERSION: &str = "local"; pub(crate) const PLUGINS_CACHE_DIR: &str = "plugins/cache"; #[derive(Debug, Clone, PartialEq, Eq)] -pub struct PluginInstallResult { +pub(super) struct PluginInstallResult { pub plugin_id: PluginId, pub plugin_version: String, pub installed_path: AbsolutePathBuf, } #[derive(Debug, Clone)] -pub struct PluginStore { +pub(super) struct PluginStore { root: AbsolutePathBuf, } impl PluginStore { - pub fn new(codex_home: PathBuf) -> Self { + pub(super) fn new(codex_home: PathBuf) -> Self { Self { root: AbsolutePathBuf::try_from(codex_home.join(PLUGINS_CACHE_DIR)) .unwrap_or_else(|err| panic!("plugin cache root should be absolute: {err}")), } } - pub fn root(&self) -> &AbsolutePathBuf { + pub(super) fn root(&self) -> &AbsolutePathBuf { &self.root } - pub fn plugin_base_root(&self, plugin_id: &PluginId) -> AbsolutePathBuf { + pub(super) fn plugin_base_root(&self, plugin_id: &PluginId) -> AbsolutePathBuf { AbsolutePathBuf::try_from( self.root .as_path() @@ -48,7 +48,11 @@ impl PluginStore { .unwrap_or_else(|err| panic!("plugin cache path should resolve to an absolute path: {err}")) } - pub fn plugin_root(&self, plugin_id: &PluginId, plugin_version: &str) -> AbsolutePathBuf { + pub(super) fn plugin_root( + &self, + plugin_id: &PluginId, + plugin_version: &str, + ) -> AbsolutePathBuf { AbsolutePathBuf::try_from( self.plugin_base_root(plugin_id) .as_path() @@ -57,7 +61,7 @@ impl PluginStore { .unwrap_or_else(|err| panic!("plugin cache path should resolve to an absolute path: {err}")) } - pub fn active_plugin_version(&self, plugin_id: &PluginId) -> Option { + pub(super) fn active_plugin_version(&self, plugin_id: &PluginId) -> Option { let mut discovered_versions = fs::read_dir(self.plugin_base_root(plugin_id).as_path()) .ok()? .filter_map(Result::ok) @@ -80,16 +84,16 @@ impl PluginStore { } } - pub fn active_plugin_root(&self, plugin_id: &PluginId) -> Option { + pub(super) fn active_plugin_root(&self, plugin_id: &PluginId) -> Option { self.active_plugin_version(plugin_id) .map(|plugin_version| self.plugin_root(plugin_id, &plugin_version)) } - pub fn is_installed(&self, plugin_id: &PluginId) -> bool { + pub(super) fn is_installed(&self, plugin_id: &PluginId) -> bool { self.active_plugin_version(plugin_id).is_some() } - pub fn install( + pub(super) fn install( &self, source_path: AbsolutePathBuf, plugin_id: PluginId, @@ -98,7 +102,7 @@ impl PluginStore { self.install_with_version(source_path, plugin_id, plugin_version) } - pub fn install_with_version( + pub(super) fn install_with_version( &self, source_path: AbsolutePathBuf, plugin_id: PluginId, @@ -133,7 +137,7 @@ impl PluginStore { }) } - pub fn uninstall(&self, plugin_id: &PluginId) -> Result<(), PluginStoreError> { + pub(super) fn uninstall(&self, plugin_id: &PluginId) -> Result<(), PluginStoreError> { remove_existing_target(self.plugin_base_root(plugin_id).as_path()) } } diff --git a/codex-rs/core/src/project_doc.rs b/codex-rs/core/src/project_doc.rs index 1b72f64610..fa2103458f 100644 --- a/codex-rs/core/src/project_doc.rs +++ b/codex-rs/core/src/project_doc.rs @@ -34,7 +34,7 @@ pub(crate) const HIERARCHICAL_AGENTS_MESSAGE: &str = /// Default filename scanned for project-level docs. pub const DEFAULT_PROJECT_DOC_FILENAME: &str = "AGENTS.md"; /// Preferred local override for project-level docs. -pub const LOCAL_PROJECT_DOC_FILENAME: &str = "AGENTS.override.md"; +pub(crate) const LOCAL_PROJECT_DOC_FILENAME: &str = "AGENTS.override.md"; /// When both `Config::instructions` and the project doc are present, they will /// be concatenated with the following separator. @@ -125,7 +125,7 @@ pub(crate) async fn get_user_instructions(config: &Config) -> Option { /// concatenation of all discovered docs. If no documentation file is found the /// function returns `Ok(None)`. Unexpected I/O failures bubble up as `Err` so /// callers can decide how to handle them. -pub async fn read_project_docs(config: &Config) -> std::io::Result> { +pub(crate) async fn read_project_docs(config: &Config) -> std::io::Result> { let max_total = config.project_doc_max_bytes; if max_total == 0 { diff --git a/codex-rs/core/src/review_prompts.rs b/codex-rs/core/src/review_prompts.rs index 988ceff821..ab0e89e8e4 100644 --- a/codex-rs/core/src/review_prompts.rs +++ b/codex-rs/core/src/review_prompts.rs @@ -6,10 +6,10 @@ use std::path::Path; use std::sync::LazyLock; #[derive(Clone, Debug, PartialEq)] -pub struct ResolvedReviewRequest { - pub target: ReviewTarget, - pub prompt: String, - pub user_facing_hint: String, +pub(crate) struct ResolvedReviewRequest { + pub(crate) target: ReviewTarget, + pub(crate) prompt: String, + pub(crate) user_facing_hint: String, } const UNCOMMITTED_PROMPT: &str = "Review the current code changes (staged, unstaged, and untracked files) and provide prioritized findings."; @@ -36,7 +36,7 @@ static COMMIT_PROMPT_TEMPLATE: LazyLock