Skip to content

Commit 3328a11

Browse files
committed
[codex-analytics] feature plumbing and emittance
1 parent 9f737c2 commit 3328a11

21 files changed

+1269
-43
lines changed

codex-rs/analytics/src/analytics_client_tests.rs

Lines changed: 398 additions & 0 deletions
Large diffs are not rendered by default.

codex-rs/analytics/src/client.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,13 @@ use crate::facts::SkillInvocation;
1313
use crate::facts::SkillInvokedInput;
1414
use crate::facts::SubAgentThreadStartedInput;
1515
use crate::facts::TrackEventsContext;
16+
use crate::facts::TurnResolvedConfigFact;
1617
use crate::reducer::AnalyticsReducer;
18+
use codex_app_server_protocol::ClientRequest;
1719
use codex_app_server_protocol::ClientResponse;
1820
use codex_app_server_protocol::InitializeParams;
21+
use codex_app_server_protocol::RequestId;
22+
use codex_app_server_protocol::ServerNotification;
1923
use codex_login::AuthManager;
2024
use codex_login::default_client::create_client;
2125
use codex_plugin::PluginTelemetryMetadata;
@@ -160,6 +164,14 @@ impl AnalyticsEventsClient {
160164
)));
161165
}
162166

167+
pub fn track_request(&self, connection_id: u64, request_id: RequestId, request: ClientRequest) {
168+
self.record_fact(AnalyticsFact::Request {
169+
connection_id,
170+
request_id,
171+
request: Box::new(request),
172+
});
173+
}
174+
163175
pub fn track_app_used(&self, tracking: TrackEventsContext, app: AppInvocation) {
164176
if !self.queue.should_enqueue_app_used(&tracking, &app) {
165177
return;
@@ -178,6 +190,12 @@ impl AnalyticsEventsClient {
178190
)));
179191
}
180192

193+
pub fn track_turn_resolved_config(&self, fact: TurnResolvedConfigFact) {
194+
self.record_fact(AnalyticsFact::Custom(
195+
CustomAnalyticsFact::TurnResolvedConfig(Box::new(fact)),
196+
));
197+
}
198+
181199
pub fn track_plugin_installed(&self, plugin: PluginTelemetryMetadata) {
182200
self.record_fact(AnalyticsFact::Custom(
183201
CustomAnalyticsFact::PluginStateChanged(PluginStateChangedInput {
@@ -227,6 +245,10 @@ impl AnalyticsEventsClient {
227245
response: Box::new(response),
228246
});
229247
}
248+
249+
pub fn track_notification(&self, notification: ServerNotification) {
250+
self.record_fact(AnalyticsFact::Notification(Box::new(notification)));
251+
}
230252
}
231253

232254
async fn send_track_events(

codex-rs/analytics/src/events.rs

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ use crate::facts::InvocationType;
33
use crate::facts::PluginState;
44
use crate::facts::SubAgentThreadStartedInput;
55
use crate::facts::TrackEventsContext;
6+
use crate::facts::TurnStatus;
7+
use crate::facts::TurnSubmissionType;
8+
use codex_app_server_protocol::CodexErrorInfo;
69
use codex_login::default_client::originator;
710
use codex_plugin::PluginTelemetryMetadata;
811
use codex_protocol::protocol::SessionSource;
@@ -37,6 +40,7 @@ pub(crate) enum TrackEventRequest {
3740
ThreadInitialized(ThreadInitializedEvent),
3841
AppMentioned(CodexAppMentionedEventRequest),
3942
AppUsed(CodexAppUsedEventRequest),
43+
TurnEvent(Box<CodexTurnEventRequest>),
4044
PluginUsed(CodexPluginUsedEventRequest),
4145
PluginInstalled(CodexPluginEventRequest),
4246
PluginUninstalled(CodexPluginEventRequest),
@@ -122,6 +126,47 @@ pub(crate) struct CodexAppUsedEventRequest {
122126
pub(crate) event_params: CodexAppMetadata,
123127
}
124128

129+
#[derive(Serialize)]
130+
pub(crate) struct CodexTurnEventParams {
131+
pub(crate) thread_id: String,
132+
pub(crate) turn_id: String,
133+
pub(crate) product_client_id: String,
134+
pub(crate) submission_type: Option<TurnSubmissionType>,
135+
pub(crate) model: Option<String>,
136+
pub(crate) model_provider: String,
137+
pub(crate) sandbox_policy: Option<&'static str>,
138+
pub(crate) reasoning_effort: Option<String>,
139+
pub(crate) reasoning_summary: Option<String>,
140+
pub(crate) service_tier: String,
141+
pub(crate) approval_policy: String,
142+
pub(crate) approvals_reviewer: String,
143+
pub(crate) sandbox_network_access: bool,
144+
pub(crate) collaboration_mode: Option<&'static str>,
145+
pub(crate) personality: Option<String>,
146+
pub(crate) num_input_images: usize,
147+
pub(crate) is_first_turn: bool,
148+
pub(crate) status: Option<TurnStatus>,
149+
pub(crate) turn_error: Option<CodexErrorInfo>,
150+
pub(crate) steer_count: Option<usize>,
151+
pub(crate) total_tool_call_count: Option<usize>,
152+
pub(crate) shell_command_count: Option<usize>,
153+
pub(crate) file_change_count: Option<usize>,
154+
pub(crate) mcp_tool_call_count: Option<usize>,
155+
pub(crate) dynamic_tool_call_count: Option<usize>,
156+
pub(crate) subagent_tool_call_count: Option<usize>,
157+
pub(crate) web_search_count: Option<usize>,
158+
pub(crate) image_generation_count: Option<usize>,
159+
pub(crate) duration_ms: Option<u64>,
160+
pub(crate) started_at: Option<u64>,
161+
pub(crate) completed_at: Option<u64>,
162+
}
163+
164+
#[derive(Serialize)]
165+
pub(crate) struct CodexTurnEventRequest {
166+
pub(crate) event_type: &'static str,
167+
pub(crate) event_params: CodexTurnEventParams,
168+
}
169+
125170
#[derive(Serialize)]
126171
pub(crate) struct CodexPluginMetadata {
127172
pub(crate) plugin_id: Option<String>,

codex-rs/analytics/src/facts.rs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,14 @@ use codex_app_server_protocol::InitializeParams;
66
use codex_app_server_protocol::RequestId;
77
use codex_app_server_protocol::ServerNotification;
88
use codex_plugin::PluginTelemetryMetadata;
9+
use codex_protocol::config_types::ApprovalsReviewer;
10+
use codex_protocol::config_types::ModeKind;
11+
use codex_protocol::config_types::Personality;
12+
use codex_protocol::config_types::ReasoningSummary;
13+
use codex_protocol::config_types::ServiceTier;
14+
use codex_protocol::openai_models::ReasoningEffort;
15+
use codex_protocol::protocol::AskForApproval;
16+
use codex_protocol::protocol::SandboxPolicy;
917
use codex_protocol::protocol::SkillScope;
1018
use codex_protocol::protocol::SubAgentSource;
1119
use serde::Serialize;
@@ -30,6 +38,41 @@ pub fn build_track_events_context(
3038
}
3139
}
3240

41+
#[derive(Clone)]
42+
pub struct TurnResolvedConfigFact {
43+
pub turn_id: String,
44+
pub thread_id: String,
45+
pub num_input_images: usize,
46+
pub submission_type: Option<TurnSubmissionType>,
47+
pub model: String,
48+
pub model_provider: String,
49+
pub sandbox_policy: SandboxPolicy,
50+
pub reasoning_effort: Option<ReasoningEffort>,
51+
pub reasoning_summary: Option<ReasoningSummary>,
52+
pub service_tier: Option<ServiceTier>,
53+
pub approval_policy: AskForApproval,
54+
pub approvals_reviewer: ApprovalsReviewer,
55+
pub sandbox_network_access: bool,
56+
pub collaboration_mode: ModeKind,
57+
pub personality: Option<Personality>,
58+
pub is_first_turn: bool,
59+
}
60+
61+
#[derive(Clone, Copy, Debug, Serialize)]
62+
#[serde(rename_all = "snake_case")]
63+
pub enum TurnSubmissionType {
64+
Default,
65+
Queued,
66+
}
67+
68+
#[derive(Clone, Copy, Debug, Serialize)]
69+
#[serde(rename_all = "snake_case")]
70+
pub enum TurnStatus {
71+
Completed,
72+
Failed,
73+
Interrupted,
74+
}
75+
3376
#[derive(Clone, Debug)]
3477
pub struct SkillInvocation {
3578
pub skill_name: String,
@@ -89,6 +132,7 @@ pub(crate) enum AnalyticsFact {
89132

90133
pub(crate) enum CustomAnalyticsFact {
91134
SubAgentThreadStarted(SubAgentThreadStartedInput),
135+
TurnResolvedConfig(Box<TurnResolvedConfigFact>),
92136
SkillInvoked(SkillInvokedInput),
93137
AppMentioned(AppMentionedInput),
94138
AppUsed(AppUsedInput),

codex-rs/analytics/src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ pub use facts::InvocationType;
1010
pub use facts::SkillInvocation;
1111
pub use facts::SubAgentThreadStartedInput;
1212
pub use facts::TrackEventsContext;
13+
pub use facts::TurnResolvedConfigFact;
14+
pub use facts::TurnStatus;
15+
pub use facts::TurnSubmissionType;
1316
pub use facts::build_track_events_context;
1417

1518
#[cfg(test)]

0 commit comments

Comments
 (0)