Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 67 additions & 3 deletions codex-rs/core/src/session/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1009,7 +1009,8 @@ impl Session {
return;
}
};
let spec = match spec.with_credentialed_routes(&self.services.credentialed_routes) {
let credentialed_routes = self.services.credentialed_routes.read().await.clone();
let spec = match spec.with_credentialed_routes(&credentialed_routes) {
Ok(spec) => spec,
Err(err) => {
warn!(
Expand All @@ -1033,6 +1034,63 @@ impl Session {
}
}

async fn refresh_credentialed_routes_for_managed_proxy(&self) {
let Some(started_proxy) = self.services.network_proxy.as_ref() else {
return;
};
let (chatgpt_base_url, permission_profile, spec) = {
let state = self.state.lock().await;
let session_configuration = &state.session_configuration;
let Some(spec) = session_configuration
.original_config_do_not_use
.permissions
.network
.as_ref()
else {
return;
};
(
session_configuration
.original_config_do_not_use
.chatgpt_base_url
.clone(),
session_configuration.permission_profile(),
spec.clone(),
)
};
let auth = self.services.auth_manager.auth().await;
let credentialed_routes =
crate::credentialed_routes::load_for_session(&chatgpt_base_url, auth.as_ref()).await;
let previous_routes = self.services.credentialed_routes.read().await.clone();
if credentialed_routes.routes == previous_routes.routes
&& credentialed_routes.proxy_url == previous_routes.proxy_url
{
return;
}

let Ok(_refresh_guard) = self.managed_network_proxy_refresh_lock.acquire().await else {
error!("managed network proxy refresh semaphore closed");
return;
};
let current_exec_policy = self.services.exec_policy.current();
let spec = match spec
.recompute_for_permission_profile(&permission_profile)
.and_then(|spec| spec.with_credentialed_routes(&credentialed_routes))
.and_then(|spec| spec.with_exec_policy_network_rules(current_exec_policy.as_ref()))
{
Ok(spec) => spec,
Err(err) => {
warn!("failed to rebuild managed network proxy for credentialed routes: {err}");
return;
}
};
if let Err(err) = spec.apply_to_started_proxy(started_proxy).await {
warn!("failed to refresh managed network proxy for credentialed routes: {err}");
return;
}
*self.services.credentialed_routes.write().await = credentialed_routes;
}

#[cfg(test)]
pub(crate) async fn codex_home(&self) -> AbsolutePathBuf {
let state = self.state.lock().await;
Expand Down Expand Up @@ -1471,6 +1529,8 @@ impl Session {
) {
self.services.hooks.store(Arc::new(hooks));
}
drop(state);
self.refresh_credentialed_routes_for_managed_proxy().await;
}

fn emit_config_changed_contributors(
Expand Down Expand Up @@ -2665,8 +2725,12 @@ impl Session {
.render(),
);
}
if let Some(credentialed_routes_instructions) =
self.services.credentialed_routes.developer_instructions()
if let Some(credentialed_routes_instructions) = self
.services
.credentialed_routes
.read()
.await
.developer_instructions()
{
developer_sections.push(credentialed_routes_instructions);
}
Expand Down
2 changes: 1 addition & 1 deletion codex-rs/core/src/session/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -871,7 +871,7 @@ impl Session {
thread_extension_data,
agent_control,
network_proxy,
credentialed_routes,
credentialed_routes: RwLock::new(credentialed_routes),
network_approval: Arc::clone(&network_approval),
state_db: state_db_ctx.clone(),
live_thread: live_thread_init.as_ref().cloned(),
Expand Down
8 changes: 6 additions & 2 deletions codex-rs/core/src/session/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4132,7 +4132,9 @@ pub(crate) async fn make_session_and_context() -> (Session, TurnContext) {
thread_extension_data: codex_extension_api::ExtensionData::new(thread_id.to_string()),
agent_control,
network_proxy: None,
credentialed_routes: crate::credentialed_routes::CredentialedRoutesSessionConfig::default(),
credentialed_routes: RwLock::new(
crate::credentialed_routes::CredentialedRoutesSessionConfig::default(),
),
network_approval: Arc::clone(&network_approval),
state_db: None,
live_thread: None,
Expand Down Expand Up @@ -5985,7 +5987,9 @@ where
thread_extension_data: codex_extension_api::ExtensionData::new(thread_id.to_string()),
agent_control,
network_proxy: None,
credentialed_routes: crate::credentialed_routes::CredentialedRoutesSessionConfig::default(),
credentialed_routes: RwLock::new(
crate::credentialed_routes::CredentialedRoutesSessionConfig::default(),
),
network_approval: Arc::clone(&network_approval),
state_db: state_db.clone(),
live_thread: None,
Expand Down
1 change: 1 addition & 0 deletions codex-rs/core/src/session/turn_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -757,6 +757,7 @@ impl Session {
mcp_connection_manager
.set_permission_profile(session_configuration.permission_profile());
}
self.refresh_credentialed_routes_for_managed_proxy().await;

let model_info = self
.services
Expand Down
3 changes: 2 additions & 1 deletion codex-rs/core/src/state/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,8 @@ pub(crate) struct SessionServices {
pub(crate) thread_extension_data: ExtensionData,
pub(crate) agent_control: AgentControl,
pub(crate) network_proxy: Option<StartedNetworkProxy>,
pub(crate) credentialed_routes: crate::credentialed_routes::CredentialedRoutesSessionConfig,
pub(crate) credentialed_routes:
RwLock<crate::credentialed_routes::CredentialedRoutesSessionConfig>,
pub(crate) network_approval: Arc<NetworkApprovalService>,
pub(crate) state_db: Option<StateDbHandle>,
pub(crate) live_thread: Option<LiveThread>,
Expand Down
Loading