mirror of
https://github.com/openai/codex.git
synced 2026-11-14 21:40:39 +00:00
Use serving assessments for adaptive Guardian review (#58075)
## What changed - Match final serving assessments to their response and output item, then retain them with tool invocations and code cells across waits. - Use matching assessments instead of asynchronous scoring for adaptive review: low-risk actions can skip synchronous review, while elevated-risk actions require it. - Revalidate captured authorization and policy before approval. Require fresh review for stale or incomplete authorization, preserve explicit review requirements, and discard assessments when hooks rewrite tool input. - Keep asynchronous scoring as the fallback when an assessment is missing or does not match. ## Testing Add integration coverage for direct and nested tool calls, hook rewrites, explicit escalation, interrupted responses, catalog-driven policy, incomplete authorization, and assessment retention across code-cell yields and waits. GitOrigin-RevId: 4346a227204137f018c03c34b302d6f1e9592c96
This commit is contained in:
@@ -41,6 +41,11 @@ pub(crate) async fn notify_tool_start(
|
||||
for contributor in contributors {
|
||||
contributor
|
||||
.on_tool_start(ToolStartInput {
|
||||
serving_assessment: invocation
|
||||
.step_context
|
||||
.serving_assessment
|
||||
.as_ref()
|
||||
.map(|value| value.requires_review),
|
||||
session_store: &invocation.session.services.session_extension_data,
|
||||
thread_store,
|
||||
turn_store: invocation.turn.extension_data.as_ref(),
|
||||
|
||||
@@ -49,7 +49,7 @@ struct ToolCallTimingGuard {
|
||||
pub(crate) struct ToolCallRuntime {
|
||||
session: Arc<Session>,
|
||||
// Tool calls may run later, so retain the step whose tool list advertised them.
|
||||
step_context: Arc<StepContext>,
|
||||
pub(crate) step_context: Arc<StepContext>,
|
||||
tracker: SharedTurnDiffTracker,
|
||||
parallel_execution: Arc<RwLock<()>>,
|
||||
timing: Option<DirectToolTiming>,
|
||||
|
||||
@@ -887,7 +887,11 @@ impl ToolRegistry {
|
||||
PreToolUseHookResult::Continue {
|
||||
updated_input: Some(updated_input),
|
||||
} => match tool.with_updated_hook_input(invocation.clone(), updated_input) {
|
||||
Ok(updated_invocation) => {
|
||||
Ok(mut updated_invocation) => {
|
||||
if updated_invocation.payload != invocation.payload {
|
||||
Arc::make_mut(&mut updated_invocation.step_context)
|
||||
.serving_assessment = None;
|
||||
}
|
||||
invocation = updated_invocation;
|
||||
}
|
||||
Err(err) => return Err(fail_before_execution(&invocation, err).await),
|
||||
@@ -898,6 +902,16 @@ impl ToolRegistry {
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(assessment) = &invocation.step_context.serving_assessment {
|
||||
let mut assessment = assessment.as_ref().clone();
|
||||
match crate::guardian::tool_permission_context(&invocation) {
|
||||
Ok(permissions) => assessment.authorization.permissions = permissions,
|
||||
Err(_) => assessment.requires_review = true,
|
||||
}
|
||||
Arc::make_mut(&mut invocation.step_context).serving_assessment =
|
||||
Some(Arc::new(assessment));
|
||||
}
|
||||
|
||||
if registered_tool.native_review == NativeReview::Required
|
||||
&& let Err(err) = super::review_native_tool_call(&invocation).await
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user