Split compaction analytics trigger dimensions

This commit is contained in:
Roy Han
2026-04-08 17:12:14 -07:00
parent 0b2428f63d
commit 595a74a809
7 changed files with 110 additions and 35 deletions

View File

@@ -20,7 +20,9 @@ use crate::facts::AppInvocation;
use crate::facts::AppMentionedInput;
use crate::facts::AppUsedInput;
use crate::facts::CodexCompactionEvent;
use crate::facts::CompactionMode;
use crate::facts::CompactionImplementation;
use crate::facts::CompactionPhase;
use crate::facts::CompactionReason;
use crate::facts::CompactionStatus;
use crate::facts::CompactionTrigger;
use crate::facts::CustomAnalyticsFact;
@@ -266,8 +268,10 @@ fn compaction_event_serializes_expected_shape() {
event_params: crate::events::codex_compaction_event_params(CodexCompactionEvent {
thread_id: "thread-1".to_string(),
turn_id: "turn-1".to_string(),
trigger: CompactionTrigger::AutoMidTurn,
mode: CompactionMode::Remote,
trigger: CompactionTrigger::Auto,
reason: CompactionReason::TokenLimit,
implementation: CompactionImplementation::ResponsesCompact,
phase: CompactionPhase::MidTurn,
status: CompactionStatus::Completed,
error: None,
active_context_tokens_before: 120_000,
@@ -287,8 +291,10 @@ fn compaction_event_serializes_expected_shape() {
"event_params": {
"thread_id": "thread-1",
"turn_id": "turn-1",
"trigger": "auto_mid_turn",
"mode": "remote",
"trigger": "auto",
"reason": "token_limit",
"implementation": "responses_compact",
"phase": "mid_turn",
"status": "completed",
"error": null,
"active_context_tokens_before": 120000,
@@ -508,7 +514,9 @@ async fn compaction_event_ingests_custom_fact() {
thread_id: "thread-1".to_string(),
turn_id: "turn-compact".to_string(),
trigger: CompactionTrigger::Manual,
mode: CompactionMode::Local,
reason: CompactionReason::UserRequested,
implementation: CompactionImplementation::Responses,
phase: CompactionPhase::StandaloneTurn,
status: CompactionStatus::Failed,
error: Some("context limit exceeded".to_string()),
active_context_tokens_before: 131_000,
@@ -528,7 +536,9 @@ async fn compaction_event_ingests_custom_fact() {
assert_eq!(payload[0]["event_params"]["thread_id"], "thread-1");
assert_eq!(payload[0]["event_params"]["turn_id"], "turn-compact");
assert_eq!(payload[0]["event_params"]["trigger"], "manual");
assert_eq!(payload[0]["event_params"]["mode"], "local");
assert_eq!(payload[0]["event_params"]["reason"], "user_requested");
assert_eq!(payload[0]["event_params"]["implementation"], "responses");
assert_eq!(payload[0]["event_params"]["phase"], "standalone_turn");
assert_eq!(payload[0]["event_params"]["status"], "failed");
}

View File

@@ -129,7 +129,9 @@ pub(crate) struct CodexCompactionEventParams {
pub(crate) thread_id: String,
pub(crate) turn_id: String,
pub(crate) trigger: crate::facts::CompactionTrigger,
pub(crate) mode: crate::facts::CompactionMode,
pub(crate) reason: crate::facts::CompactionReason,
pub(crate) implementation: crate::facts::CompactionImplementation,
pub(crate) phase: crate::facts::CompactionPhase,
pub(crate) status: crate::facts::CompactionStatus,
pub(crate) error: Option<String>,
pub(crate) active_context_tokens_before: i64,
@@ -231,7 +233,9 @@ pub(crate) fn codex_compaction_event_params(
thread_id: input.thread_id,
turn_id: input.turn_id,
trigger: input.trigger,
mode: input.mode,
reason: input.reason,
implementation: input.implementation,
phase: input.phase,
status: input.status,
error: input.error,
active_context_tokens_before: input.active_context_tokens_before,

View File

@@ -67,16 +67,30 @@ pub struct SubAgentThreadStartedInput {
#[serde(rename_all = "snake_case")]
pub enum CompactionTrigger {
Manual,
AutoPreTurn,
AutoMidTurn,
Auto,
}
#[derive(Clone, Copy, Debug, Serialize)]
#[serde(rename_all = "snake_case")]
pub enum CompactionReason {
UserRequested,
TokenLimit,
ModelDownshift,
}
#[derive(Clone, Copy, Debug, Serialize)]
#[serde(rename_all = "snake_case")]
pub enum CompactionMode {
Local,
Remote,
pub enum CompactionImplementation {
Responses,
ResponsesCompact,
}
#[derive(Clone, Copy, Debug, Serialize)]
#[serde(rename_all = "snake_case")]
pub enum CompactionPhase {
StandaloneTurn,
PreTurn,
MidTurn,
}
#[derive(Clone, Copy, Debug, Serialize)]
@@ -92,7 +106,9 @@ pub struct CodexCompactionEvent {
pub thread_id: String,
pub turn_id: String,
pub trigger: CompactionTrigger,
pub mode: CompactionMode,
pub reason: CompactionReason,
pub implementation: CompactionImplementation,
pub phase: CompactionPhase,
pub status: CompactionStatus,
pub error: Option<String>,
pub active_context_tokens_before: i64,

View File

@@ -7,7 +7,9 @@ pub use client::AnalyticsEventsClient;
pub use events::AppServerRpcTransport;
pub use facts::AppInvocation;
pub use facts::CodexCompactionEvent;
pub use facts::CompactionMode;
pub use facts::CompactionImplementation;
pub use facts::CompactionPhase;
pub use facts::CompactionReason;
pub use facts::CompactionStatus;
pub use facts::CompactionTrigger;
pub use facts::InvocationType;

View File

@@ -50,7 +50,8 @@ use chrono::Local;
use chrono::Utc;
use codex_analytics::AnalyticsEventsClient;
use codex_analytics::AppInvocation;
use codex_analytics::CompactionTrigger;
use codex_analytics::CompactionPhase;
use codex_analytics::CompactionReason;
use codex_analytics::InvocationType;
use codex_analytics::SubAgentThreadStartedInput;
use codex_analytics::build_track_events_context;
@@ -6218,7 +6219,8 @@ pub(crate) async fn run_turn(
&sess,
&turn_context,
InitialContextInjection::BeforeLastUserMessage,
CompactionTrigger::AutoMidTurn,
CompactionReason::TokenLimit,
CompactionPhase::MidTurn,
)
.await
.is_err()
@@ -6405,7 +6407,8 @@ async fn run_pre_sampling_compact(
sess,
turn_context,
InitialContextInjection::DoNotInject,
CompactionTrigger::AutoPreTurn,
CompactionReason::TokenLimit,
CompactionPhase::PreTurn,
)
.await?;
pre_sampling_compacted = true;
@@ -6451,7 +6454,8 @@ async fn maybe_run_previous_model_inline_compact(
sess,
&previous_model_turn_context,
InitialContextInjection::DoNotInject,
CompactionTrigger::ModelDownshift,
CompactionReason::ModelDownshift,
CompactionPhase::PreTurn,
)
.await?;
return Ok(true);
@@ -6463,14 +6467,16 @@ async fn run_auto_compact(
sess: &Arc<Session>,
turn_context: &Arc<TurnContext>,
initial_context_injection: InitialContextInjection,
trigger: CompactionTrigger,
reason: CompactionReason,
phase: CompactionPhase,
) -> CodexResult<()> {
if should_use_remote_compact_task(&turn_context.provider) {
run_inline_remote_auto_compact_task(
Arc::clone(sess),
Arc::clone(turn_context),
initial_context_injection,
trigger,
reason,
phase,
)
.await?;
} else {
@@ -6478,7 +6484,8 @@ async fn run_auto_compact(
Arc::clone(sess),
Arc::clone(turn_context),
initial_context_injection,
trigger,
reason,
phase,
)
.await?;
}

View File

@@ -13,7 +13,9 @@ use crate::codex::TurnContext;
use crate::codex::get_last_assistant_message_from_turn;
use crate::util::backoff;
use codex_analytics::CodexCompactionEvent;
use codex_analytics::CompactionMode;
use codex_analytics::CompactionImplementation;
use codex_analytics::CompactionPhase;
use codex_analytics::CompactionReason;
use codex_analytics::CompactionStatus;
use codex_analytics::CompactionTrigger;
use codex_features::Feature;
@@ -63,7 +65,8 @@ pub(crate) async fn run_inline_auto_compact_task(
sess: Arc<Session>,
turn_context: Arc<TurnContext>,
initial_context_injection: InitialContextInjection,
trigger: CompactionTrigger,
reason: CompactionReason,
phase: CompactionPhase,
) -> CodexResult<()> {
let prompt = turn_context.compact_prompt().to_string();
let input = vec![UserInput::Text {
@@ -77,7 +80,9 @@ pub(crate) async fn run_inline_auto_compact_task(
turn_context,
input,
initial_context_injection,
trigger,
CompactionTrigger::Auto,
reason,
phase,
)
.await?;
Ok(())
@@ -101,6 +106,8 @@ pub(crate) async fn run_compact_task(
input,
InitialContextInjection::DoNotInject,
CompactionTrigger::Manual,
CompactionReason::UserRequested,
CompactionPhase::StandaloneTurn,
)
.await
}
@@ -111,12 +118,16 @@ async fn run_compact_task_inner(
input: Vec<UserInput>,
initial_context_injection: InitialContextInjection,
trigger: CompactionTrigger,
reason: CompactionReason,
phase: CompactionPhase,
) -> CodexResult<()> {
let attempt = CompactionAnalyticsAttempt::begin(
sess.as_ref(),
turn_context.as_ref(),
trigger,
CompactionMode::Local,
reason,
CompactionImplementation::Responses,
phase,
)
.await;
let result = run_compact_task_inner_impl(
@@ -286,7 +297,9 @@ pub(crate) struct CompactionAnalyticsAttempt {
thread_id: String,
turn_id: String,
trigger: CompactionTrigger,
mode: CompactionMode,
reason: CompactionReason,
implementation: CompactionImplementation,
phase: CompactionPhase,
active_context_tokens_before: i64,
started_at: u64,
start_instant: Instant,
@@ -297,7 +310,9 @@ impl CompactionAnalyticsAttempt {
sess: &Session,
turn_context: &TurnContext,
trigger: CompactionTrigger,
mode: CompactionMode,
reason: CompactionReason,
implementation: CompactionImplementation,
phase: CompactionPhase,
) -> Self {
let enabled = sess.enabled(Feature::GeneralAnalytics);
let active_context_tokens_before = if enabled {
@@ -310,7 +325,9 @@ impl CompactionAnalyticsAttempt {
thread_id: sess.conversation_id.to_string(),
turn_id: turn_context.sub_id.clone(),
trigger,
mode,
reason,
implementation,
phase,
active_context_tokens_before,
started_at: now_unix_seconds(),
start_instant: Instant::now(),
@@ -333,7 +350,9 @@ impl CompactionAnalyticsAttempt {
thread_id: self.thread_id,
turn_id: self.turn_id,
trigger: self.trigger,
mode: self.mode,
reason: self.reason,
implementation: self.implementation,
phase: self.phase,
status,
error,
active_context_tokens_before: self.active_context_tokens_before,

View File

@@ -13,7 +13,9 @@ use crate::context_manager::ContextManager;
use crate::context_manager::TotalTokenUsageBreakdown;
use crate::context_manager::estimate_response_item_model_visible_bytes;
use crate::context_manager::is_codex_generated_item;
use codex_analytics::CompactionMode;
use codex_analytics::CompactionImplementation;
use codex_analytics::CompactionPhase;
use codex_analytics::CompactionReason;
use codex_analytics::CompactionTrigger;
use codex_protocol::error::CodexErr;
use codex_protocol::error::Result as CodexResult;
@@ -33,9 +35,18 @@ pub(crate) async fn run_inline_remote_auto_compact_task(
sess: Arc<Session>,
turn_context: Arc<TurnContext>,
initial_context_injection: InitialContextInjection,
trigger: CompactionTrigger,
reason: CompactionReason,
phase: CompactionPhase,
) -> CodexResult<()> {
run_remote_compact_task_inner(&sess, &turn_context, initial_context_injection, trigger).await?;
run_remote_compact_task_inner(
&sess,
&turn_context,
initial_context_injection,
CompactionTrigger::Auto,
reason,
phase,
)
.await?;
Ok(())
}
@@ -56,6 +67,8 @@ pub(crate) async fn run_remote_compact_task(
&turn_context,
InitialContextInjection::DoNotInject,
CompactionTrigger::Manual,
CompactionReason::UserRequested,
CompactionPhase::StandaloneTurn,
)
.await
}
@@ -65,12 +78,16 @@ async fn run_remote_compact_task_inner(
turn_context: &Arc<TurnContext>,
initial_context_injection: InitialContextInjection,
trigger: CompactionTrigger,
reason: CompactionReason,
phase: CompactionPhase,
) -> CodexResult<()> {
let attempt = CompactionAnalyticsAttempt::begin(
sess.as_ref(),
turn_context.as_ref(),
trigger,
CompactionMode::Remote,
reason,
CompactionImplementation::ResponsesCompact,
phase,
)
.await;
let result =