Skip to content
Merged
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
6 changes: 5 additions & 1 deletion codex-rs/core/src/guardian/review.rs
Original file line number Diff line number Diff line change
Expand Up @@ -730,13 +730,17 @@ pub(super) async fn guardian_review_session_config(
&turn.config.to_models_manager_config(),
)
.await;
let spawn_config = build_guardian_review_session_config(
let mut spawn_config = build_guardian_review_session_config(
turn.config.as_ref(),
live_network_config,
guardian_model.as_str(),
guardian_reasoning_effort.clone(),
guardian_model_info.model_messages.as_ref(),
)?;
if guardian_model != turn.model_info.slug {
spawn_config.model_context_window = None;
spawn_config.model_auto_compact_token_limit = None;
}
Ok(GuardianReviewSessionConfig {
spawn_config,
model: guardian_model,
Expand Down
64 changes: 64 additions & 0 deletions codex-rs/core/src/guardian/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use crate::guardian::approval_request::guardian_request_target_item_id;
use crate::guardian::prompt::BUNDLED_GUARDIAN_POLICY;
use crate::guardian::prompt::BUNDLED_GUARDIAN_POLICY_TEMPLATE;
use crate::guardian::prompt::guardian_policy_prompt_with_config_and_template;
use crate::guardian::review::guardian_review_session_config;
use crate::session::session::Session;
use crate::session::turn_context::TurnContext;
use crate::test_support;
Expand Down Expand Up @@ -2932,6 +2933,69 @@ async fn guardian_review_session_config_preserves_parent_network_proxy() {
);
}

#[tokio::test]
async fn guardian_review_session_config_clears_context_overrides_for_distinct_effective_model() {
let server = start_mock_server().await;
let (session, mut turn) = guardian_test_session_and_turn(&server).await;
let mut config = (*turn.config).clone();
config.model = Some("codex-auto-review".to_string());
config.model_context_window = Some(900_000);
config.model_auto_compact_token_limit = Some(600_000);
Arc::get_mut(&mut turn)
.expect("turn should be unique")
.config = Arc::new(config);

let guardian_config = guardian_review_session_config(session.as_ref(), turn.as_ref())
.await
.expect("guardian config")
.spawn_config;

assert_eq!(
(
guardian_config.model_context_window,
guardian_config.model_auto_compact_token_limit,
),
(None, None)
);
}

#[tokio::test]
async fn guardian_review_session_config_preserves_context_overrides_for_same_effective_model() {
let server = start_mock_server().await;
let (mut session, mut turn) = guardian_test_session_and_turn(&server).await;
let parent_model = turn.model_info.clone();
let auth_manager = Arc::clone(&session.services.auth_manager);
Arc::get_mut(&mut session)
.expect("session should be unique")
.services
.models_manager = Arc::new(StaticModelsManager::new(
Some(auth_manager),
ModelsResponse {
models: vec![parent_model],
},
));
let mut config = (*turn.config).clone();
config.model = Some("stale-parent-model".to_string());
config.model_context_window = Some(128_000);
config.model_auto_compact_token_limit = Some(100_000);
Arc::get_mut(&mut turn)
.expect("turn should be unique")
.config = Arc::new(config);

let guardian_config = guardian_review_session_config(session.as_ref(), turn.as_ref())
.await
.expect("guardian config")
.spawn_config;

assert_eq!(
(
guardian_config.model_context_window,
guardian_config.model_auto_compact_token_limit,
),
(Some(128_000), Some(100_000))
);
}

#[tokio::test]
async fn guardian_review_session_config_clears_parent_developer_instructions() {
let mut parent_config = test_config().await;
Expand Down
30 changes: 30 additions & 0 deletions codex-rs/core/tests/suite/guardian_review.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ use codex_protocol::openai_models::ModelsResponse;
use codex_protocol::protocol::AskForApproval;
use codex_protocol::protocol::EventMsg;
use codex_protocol::protocol::Op;
use codex_protocol::protocol::RolloutItem;
use codex_protocol::protocol::RolloutLine;
use codex_protocol::protocol::SandboxPolicy;
use codex_protocol::user_input::UserInput;
use core_test_support::fs_wait;
Expand Down Expand Up @@ -69,6 +71,16 @@ async fn guardian_session_prewarms_and_is_reused_for_first_review() -> Result<()
]],
vec![vec![
ev_response_created("guardian-review"),
ev_assistant_message(
"guardian-assessment",
&json!({
"risk_level": "low",
"user_authorization": "high",
"outcome": "allow",
"rationale": "The command is safe to execute.",
})
.to_string(),
),
ev_completed("guardian-review"),
]],
])
Expand All @@ -77,6 +89,8 @@ async fn guardian_session_prewarms_and_is_reused_for_first_review() -> Result<()
config.model_catalog = Some(ModelsResponse {
models: vec![review_model],
});
config.model_context_window = Some(900_000);
config.model_auto_compact_token_limit = Some(600_000);
config.permissions.approval_policy = Constrained::allow_any(AskForApproval::OnRequest);
config.approvals_reviewer = ApprovalsReviewer::AutoReview;
});
Expand Down Expand Up @@ -133,7 +147,23 @@ async fn guardian_session_prewarms_and_is_reused_for_first_review() -> Result<()
);
assert_eq!(guardian_review.get("generate"), None);

let guardian_rollout_path = test
.codex
.guardian_trunk_rollout_path()
.await
.expect("guardian trunk rollout path");
test.codex.shutdown_and_wait().await?;
let guardian_context_windows = fs::read_to_string(guardian_rollout_path)?
.lines()
.map(serde_json::from_str::<RolloutLine>)
.collect::<serde_json::Result<Vec<_>>>()?
.into_iter()
.filter_map(|line| match line.item {
RolloutItem::EventMsg(EventMsg::TurnStarted(event)) => Some(event.model_context_window),
_ => None,
})
.collect::<Vec<_>>();
assert_eq!(guardian_context_windows, vec![Some(258_400)]);
server.shutdown().await;
Ok(())
}
Expand Down
Loading