mirror of
https://github.com/openai/codex.git
synced 2026-10-19 17:28:46 +00:00
Add Guardian v2 approval review metrics (#39224)
## What changed - Pass metrics bound to the active turn's model to approval-review contributors. - Add counter support to `ExtensionMetrics` while preserving host session attribution. - Record Guardian v2 tool-call score lag and count stale-score fallbacks with the `score_lag` reason. ## Testing - Cover counter forwarding and session metadata tags. - Verify Guardian v2 metric samples for current and stale scores. GitOrigin-RevId: 0ec34736d29d2e37ed217a27e773b4f6230ae38a
This commit is contained in:
@@ -330,6 +330,9 @@ async fn run_guardian_review(
|
||||
&session.services.session_extension_data,
|
||||
&session.services.thread_extension_data,
|
||||
&action.to_string(),
|
||||
Some(crate::session::extension_metrics::from_session_telemetry(
|
||||
turn.session_telemetry.clone(),
|
||||
)),
|
||||
)
|
||||
.await
|
||||
{
|
||||
|
||||
@@ -2999,6 +2999,7 @@ async fn escalated_retry_bypasses_extension_approval_and_runs_guardian() -> anyh
|
||||
_session_store: &'a codex_extension_api::ExtensionData,
|
||||
_thread_store: &'a codex_extension_api::ExtensionData,
|
||||
_prompt: &'a str,
|
||||
_extension_metrics: Option<Arc<dyn codex_extension_api::ExtensionMetrics>>,
|
||||
) -> codex_extension_api::ExtensionFuture<'a, Option<ReviewDecision>> {
|
||||
Box::pin(async move { Some(ReviewDecision::Approved) })
|
||||
}
|
||||
|
||||
@@ -8,12 +8,16 @@ struct SessionTelemetryExtensionMetrics {
|
||||
}
|
||||
|
||||
impl ExtensionMetrics for SessionTelemetryExtensionMetrics {
|
||||
fn counter(&self, name: &str, inc: i64, tags: &[(&str, &str)]) {
|
||||
self.session_telemetry.counter(name, inc, tags);
|
||||
}
|
||||
|
||||
fn histogram(&self, name: &str, value: i64, tags: &[(&str, &str)]) {
|
||||
self.session_telemetry.histogram(name, value, tags);
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn from_session_telemetry(
|
||||
pub(crate) fn from_session_telemetry(
|
||||
session_telemetry: SessionTelemetry,
|
||||
) -> Arc<dyn ExtensionMetrics> {
|
||||
Arc::new(SessionTelemetryExtensionMetrics { session_telemetry })
|
||||
|
||||
@@ -204,7 +204,7 @@ use codex_protocol::exec_output::StreamOutput;
|
||||
mod code_mode_warning;
|
||||
pub(crate) mod context_window;
|
||||
mod environment;
|
||||
mod extension_metrics;
|
||||
pub(crate) mod extension_metrics;
|
||||
mod handlers;
|
||||
mod inject;
|
||||
mod input_queue;
|
||||
|
||||
@@ -402,8 +402,31 @@ fn extension_metrics_preserve_session_metadata_tags() {
|
||||
],
|
||||
);
|
||||
|
||||
extension_metrics.counter(
|
||||
"codex.test.extension.counter",
|
||||
/*inc*/ 2,
|
||||
&[("component", "skills"), ("model", "extension-model")],
|
||||
);
|
||||
|
||||
let snapshot = metrics.snapshot().expect("metrics snapshot");
|
||||
let attributes = single_histogram_attributes(&snapshot, "codex.test.extension");
|
||||
let counter = find_metric(&snapshot, "codex.test.extension.counter");
|
||||
let AggregatedMetrics::U64(MetricData::Sum(sum)) = counter.data() else {
|
||||
panic!("expected counter");
|
||||
};
|
||||
let points = sum.data_points().collect::<Vec<_>>();
|
||||
assert_eq!(points.len(), 1);
|
||||
assert_eq!(points[0].value(), 2);
|
||||
assert_eq!(
|
||||
points[0]
|
||||
.attributes()
|
||||
.map(|attribute| (
|
||||
attribute.key.as_str().to_string(),
|
||||
attribute.value.as_str().to_string(),
|
||||
))
|
||||
.collect::<BTreeMap<_, _>>(),
|
||||
attributes,
|
||||
);
|
||||
assert_eq!(
|
||||
attributes,
|
||||
BTreeMap::from([
|
||||
|
||||
@@ -6,6 +6,7 @@ use anyhow::Result;
|
||||
use codex_extension_api::ApprovalReviewContributor;
|
||||
use codex_extension_api::ExtensionData;
|
||||
use codex_extension_api::ExtensionFuture;
|
||||
use codex_extension_api::ExtensionMetrics;
|
||||
use codex_extension_api::ExtensionRegistryBuilder;
|
||||
use codex_features::Feature;
|
||||
use codex_login::CodexAuth;
|
||||
@@ -64,8 +65,10 @@ impl ApprovalReviewContributor for ApprovedReviewContributor {
|
||||
_session_store: &'a ExtensionData,
|
||||
_thread_store: &'a ExtensionData,
|
||||
prompt: &'a str,
|
||||
extension_metrics: Option<Arc<dyn ExtensionMetrics>>,
|
||||
) -> ExtensionFuture<'a, Option<ReviewDecision>> {
|
||||
Box::pin(async move {
|
||||
assert!(extension_metrics.is_some());
|
||||
assert!(prompt.contains("\"tool\":\"request_permissions\""));
|
||||
Some(ReviewDecision::Approved)
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user