mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
feat: route guardian review model selection through providers (#22258)
## Why Guardian review selection was hard-coded in `core`, which worked for the default OpenAI path but did not give provider implementations a way to choose backend-specific reviewer model IDs. That matters for Amazon Bedrock: guardian review should run through the Bedrock/Mantle provider using Bedrock's `openai.gpt-5.4` model ID, instead of accidentally selecting a reviewer model that implies the OpenAI backend. ## What Changed - Added provider-owned approval review model selection via `ModelProvider::approval_review_model_selection`. - Moved the existing default selection policy into the provider abstraction: prefer the requested reviewer model when it is available, otherwise fall back to the active turn model, preferring `Low` reasoning when supported. - Added an Amazon Bedrock override that pins guardian review to `openai.gpt-5.4` with `Low` reasoning.
This commit is contained in:
committed by
GitHub
Unverified
parent
51bfb5f3b1
commit
e2eb7c30fe
@@ -40,7 +40,6 @@ pub(crate) use review::routes_approval_to_guardian;
|
||||
pub(crate) use review::spawn_approval_request_review;
|
||||
pub(crate) use review_session::GuardianReviewSessionManager;
|
||||
|
||||
const GUARDIAN_PREFERRED_MODEL: &str = "codex-auto-review";
|
||||
pub(crate) const GUARDIAN_REVIEW_TIMEOUT: Duration = Duration::from_secs(90);
|
||||
pub(crate) const GUARDIAN_REVIEWER_NAME: &str = "guardian";
|
||||
pub(crate) const MAX_CONSECUTIVE_GUARDIAN_DENIALS_PER_TURN: u32 = 3;
|
||||
|
||||
@@ -659,9 +659,10 @@ pub(super) async fn run_guardian_review_session(
|
||||
fallback
|
||||
}
|
||||
};
|
||||
let preferred_model_id = turn.provider.approval_review_preferred_model();
|
||||
let preferred_model = available_models
|
||||
.iter()
|
||||
.find(|preset| preset.model == super::GUARDIAN_PREFERRED_MODEL);
|
||||
.find(|preset| preset.model == preferred_model_id);
|
||||
let (guardian_model, guardian_reasoning_effort) = if let Some(preset) = preferred_model {
|
||||
let reasoning_effort = preferred_reasoning_effort(
|
||||
preset
|
||||
@@ -670,10 +671,7 @@ pub(super) async fn run_guardian_review_session(
|
||||
.any(|effort| effort.effort == codex_protocol::openai_models::ReasoningEffort::Low),
|
||||
Some(preset.default_reasoning_effort),
|
||||
);
|
||||
(
|
||||
super::GUARDIAN_PREFERRED_MODEL.to_string(),
|
||||
reasoning_effort,
|
||||
)
|
||||
(preferred_model_id.to_string(), reasoning_effort)
|
||||
} else {
|
||||
let reasoning_effort = preferred_reasoning_effort(
|
||||
turn.model_info
|
||||
|
||||
@@ -22,6 +22,9 @@ use codex_config::types::McpServerConfig;
|
||||
use codex_exec_server::LOCAL_FS;
|
||||
use codex_features::Feature;
|
||||
use codex_model_provider::create_model_provider;
|
||||
use codex_model_provider_info::AMAZON_BEDROCK_GPT_5_4_MODEL_ID;
|
||||
use codex_model_provider_info::AMAZON_BEDROCK_PROVIDER_ID;
|
||||
use codex_model_provider_info::ModelProviderInfo;
|
||||
use codex_network_proxy::NetworkProxyConfig;
|
||||
use codex_protocol::ThreadId;
|
||||
use codex_protocol::approvals::NetworkApprovalProtocol;
|
||||
@@ -29,6 +32,7 @@ use codex_protocol::config_types::ApprovalsReviewer;
|
||||
use codex_protocol::models::ContentItem;
|
||||
use codex_protocol::models::PermissionProfile;
|
||||
use codex_protocol::models::ResponseItem;
|
||||
use codex_protocol::openai_models::ReasoningEffort;
|
||||
use codex_protocol::protocol::AskForApproval;
|
||||
use codex_protocol::protocol::Event;
|
||||
use codex_protocol::protocol::EventMsg;
|
||||
@@ -2336,6 +2340,35 @@ async fn guardian_review_session_config_uses_parent_active_model_instead_of_hard
|
||||
assert_eq!(guardian_config.model, Some("active-model".to_string()));
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn guardian_review_session_config_keeps_bedrock_provider_for_bedrock_gpt_5_4() {
|
||||
let mut parent_config = test_config().await;
|
||||
parent_config.model_provider_id = AMAZON_BEDROCK_PROVIDER_ID.to_string();
|
||||
parent_config.model_provider =
|
||||
ModelProviderInfo::create_amazon_bedrock_provider(/*aws*/ None);
|
||||
|
||||
let guardian_config = build_guardian_review_session_config_for_test(
|
||||
&parent_config,
|
||||
/*live_network_config*/ None,
|
||||
AMAZON_BEDROCK_GPT_5_4_MODEL_ID,
|
||||
Some(ReasoningEffort::Low),
|
||||
)
|
||||
.expect("guardian config");
|
||||
|
||||
assert_eq!(
|
||||
(
|
||||
guardian_config.model,
|
||||
guardian_config.model_provider_id,
|
||||
guardian_config.model_provider,
|
||||
),
|
||||
(
|
||||
Some(AMAZON_BEDROCK_GPT_5_4_MODEL_ID.to_string()),
|
||||
AMAZON_BEDROCK_PROVIDER_ID.to_string(),
|
||||
ModelProviderInfo::create_amazon_bedrock_provider(/*aws*/ None),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn guardian_review_session_config_uses_requirements_guardian_policy_config() {
|
||||
let codex_home = tempfile::tempdir().expect("create temp dir");
|
||||
|
||||
Reference in New Issue
Block a user