Files
codex/codex-rs/analytics/src/lib.rs
T
priyanshusingh-de b0af519c39 Add elicitation classification support to app and MCP analytics (#45649)
## What changed

Add an optional `elicitation_type` to app-used and MCP tool-call events, with `auth_or_link` and `approval` classifications and `null` for unclassified calls. Existing core app-use tracking passes `None`.

Expose an API to queue MCP classifications by thread, turn, and item before completion. Preserve them across turn completion, consume them on item completion, and clear them on thread closure. Bound pending classifications to 256 entries, evicting the oldest when full.

## Testing

Add coverage for serialization, first-classification retention during app-use deduplication, per-call classification across turn completion, pending-state eviction and cleanup, and exclusion of tool arguments from emitted events.

GitOrigin-RevId: 185a2ccb38153e123fc731231edff0259a26bce3
2026-09-15 08:28:03 +00:00

117 lines
3.6 KiB
Rust

mod accepted_lines;
#[cfg(debug_assertions)]
mod analytics_capture;
mod client;
mod events;
mod facts;
mod guardian_v2;
mod reducer;
mod thread_hint;
use std::time::SystemTime;
use std::time::UNIX_EPOCH;
pub use accepted_lines::fingerprint_hash;
pub use client::AnalyticsEventsClient;
pub use events::AppServerRpcTransport;
pub use events::GuardianAdditionalPermissions;
pub use events::GuardianApprovalRequestSource;
pub use events::GuardianReviewAnalyticsResult;
pub use events::GuardianReviewDecision;
pub use events::GuardianReviewEventParams;
pub use events::GuardianReviewFailureReason;
pub use events::GuardianReviewSessionAnalyticsParams;
pub use events::GuardianReviewSessionKind;
pub use events::GuardianReviewTerminalStatus;
pub use events::GuardianReviewTrackContext;
pub use events::GuardianReviewedAction;
pub use facts::AnalyticsJsonRpcError;
pub use facts::AppInvocation;
pub use facts::ArtifactOperation;
pub use facts::ArtifactOperationLifecycle;
pub use facts::CodeModeToolCallFact;
pub use facts::CodeModeToolCallStatus;
pub use facts::CodexCompactionEvent;
pub use facts::CodexErrKind;
pub use facts::CodexGoalEvent;
pub use facts::CodexTurnSteerEvent;
pub use facts::CompactionImplementation;
pub use facts::CompactionPhase;
pub use facts::CompactionReason;
pub use facts::CompactionStatus;
pub use facts::CompactionStrategy;
pub use facts::CompactionTrigger;
pub use facts::ControlToolCallFact;
pub use facts::ControlToolCallStatus;
pub use facts::ElicitationType;
pub use facts::ExternalAgentConfigImportCompletedInput;
pub use facts::ExternalAgentConfigImportFailureInput;
pub use facts::GoalEventKind;
pub use facts::HookRunFact;
pub use facts::ImageDetailSetting;
pub use facts::ImagePreparationFact;
pub use facts::ImagePreparationMetadata;
pub use facts::InputError;
pub use facts::InvocationType;
pub use facts::McpToolCallElicitation;
pub use facts::PluginInstallRequestSource;
pub use facts::PluginInstallRequested;
pub use facts::PluginInstallRequestedPlugin;
pub use facts::PluginInstallSource;
pub use facts::PluginMeasurementRow;
pub use facts::PluginMeasurementsInput;
pub use facts::SkillInvocation;
pub use facts::SkillInvocationLocation;
pub use facts::SubAgentThreadStartedInput;
pub use facts::ThreadInitializationMode;
pub use facts::TrackEventsContext;
pub use facts::TurnAnalyticsMetadata;
pub use facts::TurnCodexErrorFact;
pub use facts::TurnProfile;
pub use facts::TurnProfileFact;
pub use facts::TurnResolvedConfigFact;
pub use facts::TurnStatus;
pub use facts::TurnSteerRejectionReason;
pub use facts::TurnSteerRequestError;
pub use facts::TurnSteerResult;
pub use facts::TurnTokenUsageFact;
pub use facts::build_track_events_context;
pub use guardian_v2::GuardianV2Event;
pub use guardian_v2::GuardianV2EventKind;
pub use thread_hint::ThreadHintStatus;
pub use thread_hint::ThreadHintStatusEvent;
#[cfg(test)]
mod analytics_client_tests;
pub fn now_unix_seconds() -> u64 {
SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap_or_default()
.as_secs()
}
pub fn now_unix_millis() -> u64 {
u64::try_from(
SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap_or_default()
.as_millis(),
)
.unwrap_or(u64::MAX)
}
pub(crate) fn serialize_enum_as_string<T: serde::Serialize>(value: &T) -> Option<String> {
serde_json::to_value(value)
.ok()
.and_then(|value| value.as_str().map(str::to_string))
}
pub(crate) fn usize_to_u64(value: usize) -> u64 {
u64::try_from(value).unwrap_or(u64::MAX)
}
pub(crate) fn option_i64_to_u64(value: Option<i64>) -> Option<u64> {
value.and_then(|value| u64::try_from(value).ok())
}