Avoid unnecessary post-sampling token estimates (#34789)

## Why

The post-sampling trace calculated an estimated token count even when only the
always-on diagnostic and state log sinks were listening, adding unnecessary work
after every sample.

## What changed

- Move the estimate to a dedicated trace target and calculate it only when that
  event is enabled.
- Disable the target for the always-on diagnostic and state log sinks while
  keeping it available to explicitly configured subscribers.

## Testing

- Verify that the combined always-on subscribers do not enable the estimate
  event.

GitOrigin-RevId: ea572584597dda313e7719897d0ab1fdf7362745
This commit is contained in:
jif
2026-07-22 16:50:09 +00:00
committed by copyberry
parent 10cc57c95c
commit 66bd101fff
4 changed files with 42 additions and 6 deletions
+20 -5
View File
@@ -128,6 +128,8 @@ use tracing::trace;
use tracing::trace_span;
use tracing::warn;
const POST_SAMPLING_TOKEN_ESTIMATE_TARGET: &str = "codex_core::post_sampling_token_estimate";
/// Takes initial turn input and runs a loop where, at each sampling request,
/// the model replies with either:
///
@@ -306,7 +308,7 @@ pub(crate) async fn run_turn(
.await;
}
can_drain_pending_input = true;
let (has_pending_input, token_status, estimated_token_count) = async {
let (has_pending_input, token_status) = async {
let has_pending_input =
sess.input_queue.has_pending_input(&sess.active_turn).await;
let token_status = super::context_window::context_window_token_status(
@@ -314,9 +316,7 @@ pub(crate) async fn run_turn(
turn_context.as_ref(),
)
.await;
let estimated_token_count =
sess.get_estimated_token_count(turn_context.as_ref()).await;
(has_pending_input, token_status, estimated_token_count)
(has_pending_input, token_status)
}
.instrument(trace_span!("run_turn.collect_post_sampling_state"))
.await;
@@ -327,7 +327,6 @@ pub(crate) async fn run_turn(
turn_id = %turn_context.sub_id,
total_usage_tokens = token_status.active_context_tokens,
auto_compact_scope_tokens = token_status.auto_compact_scope_tokens,
estimated_token_count = ?estimated_token_count,
auto_compact_scope_limit = ?token_status.auto_compact_scope_limit,
auto_compact_limit_scope = ?turn_context.config.model_auto_compact_token_limit_scope,
auto_compact_window_prefill_tokens = ?token_status.auto_compact_window_prefill_tokens,
@@ -339,6 +338,22 @@ pub(crate) async fn run_turn(
needs_follow_up,
"post sampling token usage"
);
if tracing::event_enabled!(
target: POST_SAMPLING_TOKEN_ESTIMATE_TARGET,
tracing::Level::TRACE,
turn_id,
estimated_token_count,
message
) {
let estimated_token_count =
sess.get_estimated_token_count(turn_context.as_ref()).await;
trace!(
target: POST_SAMPLING_TOKEN_ESTIMATE_TARGET,
turn_id = %turn_context.sub_id,
estimated_token_count = ?estimated_token_count,
"post sampling token estimate"
);
}
let should_roll_over = needs_follow_up
&& (sess.take_new_context_window_request().await || token_limit_reached);
+19
View File
@@ -5,6 +5,7 @@ use codex_protocol::ResponseItemId;
use codex_protocol::items::AgentMessageContent;
use pretty_assertions::assert_eq;
use std::sync::Arc;
use tracing_subscriber::prelude::*;
struct RewriteAgentMessageContributor;
@@ -38,6 +39,24 @@ fn assistant_output_text(text: &str) -> ResponseItem {
}
}
#[test]
fn post_sampling_token_estimate_is_disabled_by_always_on_sinks() {
let feedback = codex_feedback::CodexFeedback::new();
let subscriber = tracing_subscriber::registry()
.with(feedback.logger_layer())
.with(tracing_subscriber::fmt::layer().with_filter(codex_state::log_db::default_filter()));
tracing::subscriber::with_default(subscriber, || {
assert!(!tracing::event_enabled!(
target: POST_SAMPLING_TOKEN_ESTIMATE_TARGET,
tracing::Level::TRACE,
turn_id,
estimated_token_count,
message
));
});
}
#[tokio::test]
async fn plan_mode_uses_contributed_turn_item_for_last_agent_message() {
let (mut session, turn_context) = crate::session::tests::make_session_and_context().await;
+2 -1
View File
@@ -213,7 +213,8 @@ impl CodexFeedback {
.with_filter(
Targets::new()
.with_default(Level::TRACE)
.with_target("codex_api::responses_websocket_timing", LevelFilter::OFF),
.with_target("codex_api::responses_websocket_timing", LevelFilter::OFF)
.with_target("codex_core::post_sampling_token_estimate", LevelFilter::OFF),
)
}
+1
View File
@@ -59,6 +59,7 @@ pub fn default_filter() -> Targets {
.with_target("codex_otel.trace_safe", LevelFilter::OFF)
.with_target("rmcp::service", LevelFilter::INFO)
.with_target("codex_api::responses_websocket_timing", LevelFilter::OFF)
.with_target("codex_core::post_sampling_token_estimate", LevelFilter::OFF)
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]