Use refreshed turn context for network approvals

Co-authored-by: Codex <noreply@openai.com>
This commit is contained in:
Charles Cunningham
2026-03-05 15:19:19 -08:00
co-authored by Codex
parent 2fc485dd28
commit 1f50631422
2 changed files with 71 additions and 6 deletions
+1 -1
View File
@@ -2761,7 +2761,7 @@ impl Session {
})
}
async fn current_active_turn_context(&self) -> Option<Arc<TurnContext>> {
pub(crate) async fn current_active_turn_context(&self) -> Option<Arc<TurnContext>> {
let active = self.active_turn.lock().await;
let turn = active.as_ref()?;
turn.current_turn_context.clone().or_else(|| {
+70 -5
View File
@@ -249,11 +249,7 @@ impl NetworkApprovalService {
}
async fn active_turn_context(session: &Session) -> Option<Arc<crate::codex::TurnContext>> {
let active_turn = session.active_turn.lock().await;
active_turn
.as_ref()
.and_then(|turn| turn.tasks.first())
.map(|(_, task)| Arc::clone(&task.turn_context))
session.current_active_turn_context().await
}
fn format_network_target(protocol: &str, host: &str, port: u16) -> String {
@@ -555,9 +551,39 @@ pub(crate) async fn finish_deferred_network_approval(
#[cfg(test)]
mod tests {
use super::*;
use crate::codex::make_session_and_context_with_rx;
use crate::state::ActiveTurn;
use crate::state::RunningTask;
use crate::state::TaskKind;
use crate::tasks::SessionTask;
use crate::tasks::SessionTaskContext;
use codex_network_proxy::BlockedRequestArgs;
use codex_protocol::protocol::AskForApproval;
use codex_protocol::user_input::UserInput;
use pretty_assertions::assert_eq;
use tokio::sync::Notify;
use tokio_util::sync::CancellationToken;
use tokio_util::task::AbortOnDropHandle;
#[derive(Clone, Copy)]
struct NoopTask;
#[async_trait::async_trait]
impl SessionTask for NoopTask {
fn kind(&self) -> TaskKind {
TaskKind::Regular
}
async fn run(
self: Arc<Self>,
_session: Arc<SessionTaskContext>,
_ctx: Arc<crate::codex::TurnContext>,
_input: Vec<UserInput>,
_cancellation_token: CancellationToken,
) -> Option<String> {
None
}
}
#[tokio::test]
async fn pending_approvals_are_deduped_per_host_protocol_and_port() {
@@ -697,4 +723,43 @@ mod tests {
assert_eq!(service.take_call_outcome("registration-1").await, None);
assert_eq!(service.take_call_outcome("registration-2").await, None);
}
#[tokio::test]
async fn active_turn_context_prefers_refreshed_current_turn_context_over_task_snapshot() {
let (session, original_turn_context, _rx) = make_session_and_context_with_rx().await;
let next_model = if original_turn_context.model_info.slug == "gpt-5.1" {
"gpt-5"
} else {
"gpt-5.1"
};
let refreshed_turn_context = Arc::new(
original_turn_context
.with_model(next_model.to_string(), &session.services.models_manager)
.await,
);
let handle = tokio::spawn(async {});
*session.active_turn.lock().await = Some(ActiveTurn {
current_turn_context: Some(Arc::clone(&refreshed_turn_context)),
tasks: IndexMap::from([(
original_turn_context.sub_id.clone(),
RunningTask {
done: Arc::new(Notify::new()),
kind: TaskKind::Regular,
task: Arc::new(NoopTask),
cancellation_token: CancellationToken::new(),
handle: Arc::new(AbortOnDropHandle::new(handle)),
turn_context: Arc::clone(&original_turn_context),
_timer: None,
},
)]),
..Default::default()
});
let active_turn_context = NetworkApprovalService::active_turn_context(&session)
.await
.expect("active turn context");
assert!(Arc::ptr_eq(&active_turn_context, &refreshed_turn_context));
}
}