Centralize synchronous Guardian reviewer selection (#60784)

Share reviewer lookup and deferred configuration resolution through
`select_synchronous_reviewer` in isolated assessments and approval reviews.
Keep configuration resolution within each caller's review deadline.

GitOrigin-RevId: 77f9a77a3d7a859f5c8012e4d22b68c8def7d81b
This commit is contained in:
felixxia-oai
2026-11-11 11:01:31 +00:00
committed by copyberry
parent c1934fc99e
commit e58bf8f523
+25 -8
View File
@@ -23,6 +23,7 @@ use codex_prompts::ResolvedModelMessages;
use codex_protocol::openai_models::GuardianScope;
use codex_protocol::protocol::EventMsg;
use codex_protocol::protocol::ReviewDecision;
use std::future::Future;
use std::sync::Arc;
use std::time::Duration;
use tokio::time::Instant;
@@ -38,6 +39,7 @@ use super::ApprovalRequestReasons;
use super::GUARDIAN_REVIEW_TIMEOUT;
use super::GuardianApprovalRequest;
use super::GuardianReviewContext;
use super::GuardianReviewSessionManager;
use super::approval_request::format_guardian_action_pretty;
use super::approval_request::guardian_assessment_action;
use super::approval_request::guardian_request_target_item_id;
@@ -105,6 +107,20 @@ pub(super) struct GuardianReviewSessionConfig {
review_model: ReviewModel,
}
/// Selects the thread's reviewer and leaves configuration resolution under the caller's deadline.
fn select_synchronous_reviewer(
session: &Session,
context: &GuardianReviewContext,
) -> Option<(
Arc<GuardianReviewSessionManager>,
impl Future<Output = anyhow::Result<GuardianReviewSessionConfig>>,
)> {
Some((
session.guardian_review_session()?,
guardian_review_session_config(session, context),
))
}
pub(super) async fn guardian_review_session_config(
session: &Session,
context: &GuardianReviewContext,
@@ -201,12 +217,13 @@ impl ReviewInput {
cancellation: &CancellationToken,
) -> Result<GuardianAssessment, GuardianReviewError> {
let review = async {
let pool = self.session.guardian_review_session().ok_or_else(|| {
GuardianReviewError::session(anyhow::anyhow!("Guardian reviewer is unavailable"))
})?;
let config = guardian_review_session_config(&self.session, &self.context)
.await
.map_err(GuardianReviewError::prompt_build)?;
let (pool, config) = select_synchronous_reviewer(&self.session, &self.context)
.ok_or_else(|| {
GuardianReviewError::session(anyhow::anyhow!(
"Guardian reviewer is unavailable"
))
})?;
let config = config.await.map_err(GuardianReviewError::prompt_build)?;
let category = self.request.guardian_scope();
let params = self.into_params(
config,
@@ -258,7 +275,7 @@ async fn run_guardian_review_session_before_deadline(
reasons: ApprovalRequestReasons,
options: ReviewAttemptOptions,
) -> (GuardianReviewOutcome, GuardianReviewAnalyticsResult) {
let Some(pool) = session.guardian_review_session() else {
let Some((pool, config)) = select_synchronous_reviewer(&session, &context) else {
return (
GuardianReviewOutcome::Error(GuardianReviewError::prompt_build(anyhow::anyhow!(
"Guardian extension is not installed for this thread"
@@ -269,7 +286,7 @@ async fn run_guardian_review_session_before_deadline(
let session_config = match run_before_review_deadline(
options.deadline,
options.external_cancel.as_ref(),
guardian_review_session_config(session.as_ref(), &context),
config,
)
.await
{