mirror of
https://github.com/openai/codex.git
synced 2026-05-04 13:21:54 +03:00
[codex-analytics] denormalize thread metadata onto turn events
This commit is contained in:
@@ -8,7 +8,6 @@ use crate::events::CodexPluginUsedEventRequest;
|
||||
use crate::events::CodexRuntimeMetadata;
|
||||
use crate::events::CodexTurnEventRequest;
|
||||
use crate::events::CodexTurnSteerEventRequest;
|
||||
use crate::events::ThreadInitializationMode;
|
||||
use crate::events::ThreadInitializedEvent;
|
||||
use crate::events::ThreadInitializedEventParams;
|
||||
use crate::events::TrackEventRequest;
|
||||
@@ -30,6 +29,7 @@ use crate::facts::PluginUsedInput;
|
||||
use crate::facts::SkillInvocation;
|
||||
use crate::facts::SkillInvokedInput;
|
||||
use crate::facts::SubAgentThreadStartedInput;
|
||||
use crate::facts::ThreadInitializationMode;
|
||||
use crate::facts::TrackEventsContext;
|
||||
use crate::facts::TurnResolvedConfigFact;
|
||||
use crate::facts::TurnStatus;
|
||||
@@ -75,6 +75,7 @@ use codex_protocol::config_types::ApprovalsReviewer;
|
||||
use codex_protocol::config_types::ModeKind;
|
||||
use codex_protocol::protocol::AskForApproval;
|
||||
use codex_protocol::protocol::SandboxPolicy;
|
||||
use codex_protocol::protocol::SessionSource;
|
||||
use codex_protocol::protocol::SubAgentSource;
|
||||
use pretty_assertions::assert_eq;
|
||||
use serde_json::json;
|
||||
@@ -248,6 +249,9 @@ fn sample_turn_resolved_config(turn_id: &str) -> TurnResolvedConfigFact {
|
||||
thread_id: "thread-2".to_string(),
|
||||
num_input_images: 1,
|
||||
submission_type: Some(TurnSubmissionType::Default),
|
||||
ephemeral: false,
|
||||
session_source: SessionSource::Exec,
|
||||
initialization_mode: ThreadInitializationMode::New,
|
||||
model: "gpt-5".to_string(),
|
||||
model_provider: "openai".to_string(),
|
||||
sandbox_policy: SandboxPolicy::new_read_only_policy(),
|
||||
@@ -266,8 +270,8 @@ fn sample_turn_resolved_config(turn_id: &str) -> TurnResolvedConfigFact {
|
||||
fn sample_app_server_client_metadata() -> CodexAppServerClientMetadata {
|
||||
CodexAppServerClientMetadata {
|
||||
product_client_id: "codex-tui".to_string(),
|
||||
client_name: Some("codex-tui".to_string()),
|
||||
client_version: Some("1.0.0".to_string()),
|
||||
client_name: "codex-tui".to_string(),
|
||||
client_version: "1.0.0".to_string(),
|
||||
rpc_transport: AppServerRpcTransport::Stdio,
|
||||
experimental_api_enabled: None,
|
||||
}
|
||||
@@ -549,8 +553,8 @@ fn thread_initialized_event_serializes_expected_shape() {
|
||||
thread_id: "thread-0".to_string(),
|
||||
app_server_client: CodexAppServerClientMetadata {
|
||||
product_client_id: DEFAULT_ORIGINATOR.to_string(),
|
||||
client_name: Some("codex-tui".to_string()),
|
||||
client_version: Some("1.0.0".to_string()),
|
||||
client_name: "codex-tui".to_string(),
|
||||
client_version: "1.0.0".to_string(),
|
||||
rpc_transport: AppServerRpcTransport::Stdio,
|
||||
experimental_api_enabled: Some(true),
|
||||
},
|
||||
@@ -1087,8 +1091,14 @@ fn turn_event_serializes_expected_shape() {
|
||||
event_params: crate::events::CodexTurnEventParams {
|
||||
thread_id: "thread-2".to_string(),
|
||||
turn_id: "turn-2".to_string(),
|
||||
product_client_id: "codex-tui".to_string(),
|
||||
app_server_client: sample_app_server_client_metadata(),
|
||||
runtime: sample_runtime_metadata(),
|
||||
submission_type: Some(TurnSubmissionType::Default),
|
||||
ephemeral: false,
|
||||
thread_source: Some("user".to_string()),
|
||||
initialization_mode: ThreadInitializationMode::New,
|
||||
subagent_source: None,
|
||||
parent_thread_id: None,
|
||||
model: Some("gpt-5".to_string()),
|
||||
model_provider: "openai".to_string(),
|
||||
sandbox_policy: Some("read_only"),
|
||||
@@ -1125,51 +1135,97 @@ fn turn_event_serializes_expected_shape() {
|
||||
}));
|
||||
|
||||
let payload = serde_json::to_value(&event).expect("serialize turn event");
|
||||
|
||||
assert_eq!(payload["event_type"], json!("codex_turn_event"));
|
||||
assert_eq!(payload["event_params"]["thread_id"], json!("thread-2"));
|
||||
assert_eq!(payload["event_params"]["turn_id"], json!("turn-2"));
|
||||
assert_eq!(
|
||||
payload,
|
||||
payload["event_params"]["app_server_client"],
|
||||
json!({
|
||||
"event_type": "codex_turn_event",
|
||||
"event_params": {
|
||||
"thread_id": "thread-2",
|
||||
"turn_id": "turn-2",
|
||||
"product_client_id": "codex-tui",
|
||||
"submission_type": "default",
|
||||
"model": "gpt-5",
|
||||
"model_provider": "openai",
|
||||
"sandbox_policy": "read_only",
|
||||
"reasoning_effort": "high",
|
||||
"reasoning_summary": "detailed",
|
||||
"service_tier": "flex",
|
||||
"approval_policy": "on-request",
|
||||
"approvals_reviewer": "guardian_subagent",
|
||||
"sandbox_network_access": true,
|
||||
"collaboration_mode": "plan",
|
||||
"personality": "pragmatic",
|
||||
"num_input_images": 2,
|
||||
"is_first_turn": true,
|
||||
"status": "completed",
|
||||
"turn_error": null,
|
||||
"steer_count": 0,
|
||||
"total_tool_call_count": null,
|
||||
"shell_command_count": null,
|
||||
"file_change_count": null,
|
||||
"mcp_tool_call_count": null,
|
||||
"dynamic_tool_call_count": null,
|
||||
"subagent_tool_call_count": null,
|
||||
"web_search_count": null,
|
||||
"image_generation_count": null,
|
||||
"input_tokens": null,
|
||||
"cached_input_tokens": null,
|
||||
"output_tokens": null,
|
||||
"reasoning_output_tokens": null,
|
||||
"total_tokens": null,
|
||||
"duration_ms": 1234,
|
||||
"started_at": 455,
|
||||
"completed_at": 456
|
||||
}
|
||||
"product_client_id": "codex-tui",
|
||||
"client_name": "codex-tui",
|
||||
"client_version": "1.0.0",
|
||||
"rpc_transport": "stdio",
|
||||
"experimental_api_enabled": null,
|
||||
})
|
||||
);
|
||||
assert_eq!(
|
||||
payload["event_params"]["runtime"],
|
||||
json!({
|
||||
"codex_rs_version": "0.1.0",
|
||||
"runtime_os": "macos",
|
||||
"runtime_os_version": "15.3.1",
|
||||
"runtime_arch": "aarch64",
|
||||
})
|
||||
);
|
||||
assert!(payload["event_params"].get("product_client_id").is_none());
|
||||
assert_eq!(payload["event_params"]["submission_type"], json!("default"));
|
||||
assert_eq!(payload["event_params"]["ephemeral"], json!(false));
|
||||
assert_eq!(payload["event_params"]["thread_source"], json!("user"));
|
||||
assert_eq!(payload["event_params"]["initialization_mode"], json!("new"));
|
||||
assert_eq!(payload["event_params"]["subagent_source"], json!(null));
|
||||
assert_eq!(payload["event_params"]["parent_thread_id"], json!(null));
|
||||
assert_eq!(payload["event_params"]["model"], json!("gpt-5"));
|
||||
assert_eq!(payload["event_params"]["model_provider"], json!("openai"));
|
||||
assert_eq!(
|
||||
payload["event_params"]["sandbox_policy"],
|
||||
json!("read_only")
|
||||
);
|
||||
assert_eq!(payload["event_params"]["reasoning_effort"], json!("high"));
|
||||
assert_eq!(
|
||||
payload["event_params"]["reasoning_summary"],
|
||||
json!("detailed")
|
||||
);
|
||||
assert_eq!(payload["event_params"]["service_tier"], json!("flex"));
|
||||
assert_eq!(
|
||||
payload["event_params"]["approval_policy"],
|
||||
json!("on-request")
|
||||
);
|
||||
assert_eq!(
|
||||
payload["event_params"]["approvals_reviewer"],
|
||||
json!("guardian_subagent")
|
||||
);
|
||||
assert_eq!(
|
||||
payload["event_params"]["sandbox_network_access"],
|
||||
json!(true)
|
||||
);
|
||||
assert_eq!(payload["event_params"]["collaboration_mode"], json!("plan"));
|
||||
assert_eq!(payload["event_params"]["personality"], json!("pragmatic"));
|
||||
assert_eq!(payload["event_params"]["num_input_images"], json!(2));
|
||||
assert_eq!(payload["event_params"]["is_first_turn"], json!(true));
|
||||
assert_eq!(payload["event_params"]["status"], json!("completed"));
|
||||
assert_eq!(payload["event_params"]["turn_error"], json!(null));
|
||||
assert_eq!(payload["event_params"]["steer_count"], json!(0));
|
||||
assert_eq!(
|
||||
payload["event_params"]["total_tool_call_count"],
|
||||
json!(null)
|
||||
);
|
||||
assert_eq!(payload["event_params"]["shell_command_count"], json!(null));
|
||||
assert_eq!(payload["event_params"]["file_change_count"], json!(null));
|
||||
assert_eq!(payload["event_params"]["mcp_tool_call_count"], json!(null));
|
||||
assert_eq!(
|
||||
payload["event_params"]["dynamic_tool_call_count"],
|
||||
json!(null)
|
||||
);
|
||||
assert_eq!(
|
||||
payload["event_params"]["subagent_tool_call_count"],
|
||||
json!(null)
|
||||
);
|
||||
assert_eq!(payload["event_params"]["web_search_count"], json!(null));
|
||||
assert_eq!(
|
||||
payload["event_params"]["image_generation_count"],
|
||||
json!(null)
|
||||
);
|
||||
assert_eq!(payload["event_params"]["input_tokens"], json!(null));
|
||||
assert_eq!(payload["event_params"]["cached_input_tokens"], json!(null));
|
||||
assert_eq!(payload["event_params"]["output_tokens"], json!(null));
|
||||
assert_eq!(
|
||||
payload["event_params"]["reasoning_output_tokens"],
|
||||
json!(null)
|
||||
);
|
||||
assert_eq!(payload["event_params"]["total_tokens"], json!(null));
|
||||
assert_eq!(payload["event_params"]["duration_ms"], json!(1234));
|
||||
assert_eq!(payload["event_params"]["started_at"], json!(455));
|
||||
assert_eq!(payload["event_params"]["completed_at"], json!(456));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -1478,9 +1534,30 @@ async fn turn_lifecycle_emits_turn_event() {
|
||||
assert_eq!(payload["event_params"]["thread_id"], json!("thread-2"));
|
||||
assert_eq!(payload["event_params"]["turn_id"], json!("turn-2"));
|
||||
assert_eq!(
|
||||
payload["event_params"]["product_client_id"],
|
||||
json!("codex-tui")
|
||||
payload["event_params"]["app_server_client"],
|
||||
json!({
|
||||
"product_client_id": "codex-tui",
|
||||
"client_name": "codex-tui",
|
||||
"client_version": "1.0.0",
|
||||
"rpc_transport": "stdio",
|
||||
"experimental_api_enabled": null,
|
||||
})
|
||||
);
|
||||
assert_eq!(
|
||||
payload["event_params"]["runtime"],
|
||||
json!({
|
||||
"codex_rs_version": "0.1.0",
|
||||
"runtime_os": "macos",
|
||||
"runtime_os_version": "15.3.1",
|
||||
"runtime_arch": "aarch64",
|
||||
})
|
||||
);
|
||||
assert!(payload["event_params"].get("product_client_id").is_none());
|
||||
assert_eq!(payload["event_params"]["ephemeral"], json!(false));
|
||||
assert_eq!(payload["event_params"]["thread_source"], json!("user"));
|
||||
assert_eq!(payload["event_params"]["initialization_mode"], json!("new"));
|
||||
assert_eq!(payload["event_params"]["subagent_source"], json!(null));
|
||||
assert_eq!(payload["event_params"]["parent_thread_id"], json!(null));
|
||||
assert_eq!(payload["event_params"]["num_input_images"], json!(1));
|
||||
assert_eq!(payload["event_params"]["status"], json!("completed"));
|
||||
assert_eq!(payload["event_params"]["steer_count"], json!(0));
|
||||
@@ -1678,6 +1755,73 @@ async fn queued_submission_type_emits_queued_turn_event() {
|
||||
assert_eq!(payload["event_params"]["submission_type"], json!("queued"));
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn turn_event_includes_subagent_thread_metadata() {
|
||||
let mut reducer = AnalyticsReducer::default();
|
||||
let mut out = Vec::new();
|
||||
|
||||
ingest_turn_prerequisites(
|
||||
&mut reducer,
|
||||
&mut out,
|
||||
/*include_initialize*/ true,
|
||||
/*include_resolved_config*/ false,
|
||||
/*include_started*/ true,
|
||||
/*include_token_usage*/ false,
|
||||
)
|
||||
.await;
|
||||
|
||||
let mut resolved_config = sample_turn_resolved_config("turn-2");
|
||||
resolved_config.ephemeral = true;
|
||||
let parent_thread_id =
|
||||
codex_protocol::ThreadId::from_string("11111111-1111-1111-1111-111111111111")
|
||||
.expect("valid thread id");
|
||||
resolved_config.session_source = SessionSource::SubAgent(SubAgentSource::ThreadSpawn {
|
||||
parent_thread_id,
|
||||
depth: 1,
|
||||
agent_path: None,
|
||||
agent_nickname: Some("worker".to_string()),
|
||||
agent_role: None,
|
||||
});
|
||||
resolved_config.initialization_mode = ThreadInitializationMode::Forked;
|
||||
|
||||
reducer
|
||||
.ingest(
|
||||
AnalyticsFact::Custom(CustomAnalyticsFact::TurnResolvedConfig(Box::new(
|
||||
resolved_config,
|
||||
))),
|
||||
&mut out,
|
||||
)
|
||||
.await;
|
||||
reducer
|
||||
.ingest(
|
||||
AnalyticsFact::Notification(Box::new(sample_turn_completed_notification(
|
||||
"thread-2",
|
||||
"turn-2",
|
||||
AppServerTurnStatus::Completed,
|
||||
/*codex_error_info*/ None,
|
||||
))),
|
||||
&mut out,
|
||||
)
|
||||
.await;
|
||||
|
||||
assert_eq!(out.len(), 1);
|
||||
let payload = serde_json::to_value(&out[0]).expect("serialize turn event");
|
||||
assert_eq!(payload["event_params"]["ephemeral"], json!(true));
|
||||
assert_eq!(payload["event_params"]["thread_source"], json!("subagent"));
|
||||
assert_eq!(
|
||||
payload["event_params"]["initialization_mode"],
|
||||
json!("forked")
|
||||
);
|
||||
assert_eq!(
|
||||
payload["event_params"]["subagent_source"],
|
||||
json!("thread_spawn")
|
||||
);
|
||||
assert_eq!(
|
||||
payload["event_params"]["parent_thread_id"],
|
||||
json!("11111111-1111-1111-1111-111111111111")
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn turn_does_not_emit_without_required_prerequisites() {
|
||||
let mut reducer = AnalyticsReducer::default();
|
||||
@@ -1703,12 +1847,7 @@ async fn turn_does_not_emit_without_required_prerequisites() {
|
||||
&mut out,
|
||||
)
|
||||
.await;
|
||||
assert_eq!(out.len(), 1);
|
||||
let payload = serde_json::to_value(&out[0]).expect("serialize turn event");
|
||||
assert_eq!(
|
||||
payload["event_params"]["product_client_id"],
|
||||
json!(originator().value)
|
||||
);
|
||||
assert!(out.is_empty());
|
||||
|
||||
let mut reducer = AnalyticsReducer::default();
|
||||
let mut out = Vec::new();
|
||||
|
||||
@@ -3,6 +3,7 @@ use crate::facts::CodexTurnSteerEvent;
|
||||
use crate::facts::InvocationType;
|
||||
use crate::facts::PluginState;
|
||||
use crate::facts::SubAgentThreadStartedInput;
|
||||
use crate::facts::ThreadInitializationMode;
|
||||
use crate::facts::TrackEventsContext;
|
||||
use crate::facts::TurnStatus;
|
||||
use crate::facts::TurnSteerRejectionReason;
|
||||
@@ -23,14 +24,6 @@ pub enum AppServerRpcTransport {
|
||||
InProcess,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Serialize)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub(crate) enum ThreadInitializationMode {
|
||||
New,
|
||||
Forked,
|
||||
Resumed,
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub(crate) struct TrackEventsRequest {
|
||||
pub(crate) events: Vec<TrackEventRequest>,
|
||||
@@ -73,8 +66,8 @@ pub(crate) struct SkillInvocationEventParams {
|
||||
#[derive(Clone, Serialize)]
|
||||
pub(crate) struct CodexAppServerClientMetadata {
|
||||
pub(crate) product_client_id: String,
|
||||
pub(crate) client_name: Option<String>,
|
||||
pub(crate) client_version: Option<String>,
|
||||
pub(crate) client_name: String,
|
||||
pub(crate) client_version: String,
|
||||
pub(crate) rpc_transport: AppServerRpcTransport,
|
||||
pub(crate) experimental_api_enabled: Option<bool>,
|
||||
}
|
||||
@@ -134,8 +127,14 @@ pub(crate) struct CodexAppUsedEventRequest {
|
||||
pub(crate) struct CodexTurnEventParams {
|
||||
pub(crate) thread_id: String,
|
||||
pub(crate) turn_id: String,
|
||||
pub(crate) product_client_id: String,
|
||||
pub(crate) app_server_client: CodexAppServerClientMetadata,
|
||||
pub(crate) runtime: CodexRuntimeMetadata,
|
||||
pub(crate) submission_type: Option<TurnSubmissionType>,
|
||||
pub(crate) ephemeral: bool,
|
||||
pub(crate) thread_source: Option<String>,
|
||||
pub(crate) initialization_mode: ThreadInitializationMode,
|
||||
pub(crate) subagent_source: Option<String>,
|
||||
pub(crate) parent_thread_id: Option<String>,
|
||||
pub(crate) model: Option<String>,
|
||||
pub(crate) model_provider: String,
|
||||
pub(crate) sandbox_policy: Option<&'static str>,
|
||||
@@ -330,8 +329,8 @@ pub(crate) fn subagent_thread_started_event_request(
|
||||
thread_id: input.thread_id,
|
||||
app_server_client: CodexAppServerClientMetadata {
|
||||
product_client_id: input.product_client_id,
|
||||
client_name: Some(input.client_name),
|
||||
client_version: Some(input.client_version),
|
||||
client_name: input.client_name,
|
||||
client_version: input.client_version,
|
||||
rpc_transport: AppServerRpcTransport::InProcess,
|
||||
experimental_api_enabled: None,
|
||||
},
|
||||
@@ -368,3 +367,27 @@ fn subagent_parent_thread_id(subagent_source: &SubAgentSource) -> Option<String>
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn turn_subagent_source_name(thread_source: &SessionSource) -> Option<String> {
|
||||
match thread_source {
|
||||
SessionSource::SubAgent(subagent_source) => Some(subagent_source_name(subagent_source)),
|
||||
SessionSource::Cli
|
||||
| SessionSource::VSCode
|
||||
| SessionSource::Exec
|
||||
| SessionSource::Mcp
|
||||
| SessionSource::Custom(_)
|
||||
| SessionSource::Unknown => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn turn_parent_thread_id(thread_source: &SessionSource) -> Option<String> {
|
||||
match thread_source {
|
||||
SessionSource::SubAgent(subagent_source) => subagent_parent_thread_id(subagent_source),
|
||||
SessionSource::Cli
|
||||
| SessionSource::VSCode
|
||||
| SessionSource::Exec
|
||||
| SessionSource::Mcp
|
||||
| SessionSource::Custom(_)
|
||||
| SessionSource::Unknown => None,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ use codex_protocol::config_types::ServiceTier;
|
||||
use codex_protocol::openai_models::ReasoningEffort;
|
||||
use codex_protocol::protocol::AskForApproval;
|
||||
use codex_protocol::protocol::SandboxPolicy;
|
||||
use codex_protocol::protocol::SessionSource;
|
||||
use codex_protocol::protocol::SkillScope;
|
||||
use codex_protocol::protocol::SubAgentSource;
|
||||
use serde::Serialize;
|
||||
@@ -44,6 +45,9 @@ pub struct TurnResolvedConfigFact {
|
||||
pub thread_id: String,
|
||||
pub num_input_images: usize,
|
||||
pub submission_type: Option<TurnSubmissionType>,
|
||||
pub ephemeral: bool,
|
||||
pub session_source: SessionSource,
|
||||
pub initialization_mode: ThreadInitializationMode,
|
||||
pub model: String,
|
||||
pub model_provider: String,
|
||||
pub sandbox_policy: SandboxPolicy,
|
||||
@@ -65,6 +69,14 @@ pub enum TurnSubmissionType {
|
||||
Queued,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Serialize)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum ThreadInitializationMode {
|
||||
New,
|
||||
Forked,
|
||||
Resumed,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Serialize)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum TurnStatus {
|
||||
|
||||
@@ -10,6 +10,7 @@ pub use facts::CodexTurnSteerEvent;
|
||||
pub use facts::InvocationType;
|
||||
pub use facts::SkillInvocation;
|
||||
pub use facts::SubAgentThreadStartedInput;
|
||||
pub use facts::ThreadInitializationMode;
|
||||
pub use facts::TrackEventsContext;
|
||||
pub use facts::TurnResolvedConfigFact;
|
||||
pub use facts::TurnStatus;
|
||||
|
||||
@@ -10,7 +10,6 @@ use crate::events::CodexTurnEventRequest;
|
||||
use crate::events::CodexTurnSteerEventRequest;
|
||||
use crate::events::SkillInvocationEventParams;
|
||||
use crate::events::SkillInvocationEventRequest;
|
||||
use crate::events::ThreadInitializationMode;
|
||||
use crate::events::ThreadInitializedEvent;
|
||||
use crate::events::ThreadInitializedEventParams;
|
||||
use crate::events::TrackEventRequest;
|
||||
@@ -21,6 +20,8 @@ use crate::events::codex_turn_steer_event_params;
|
||||
use crate::events::plugin_state_event_type;
|
||||
use crate::events::subagent_thread_started_event_request;
|
||||
use crate::events::thread_source_name;
|
||||
use crate::events::turn_parent_thread_id;
|
||||
use crate::events::turn_subagent_source_name;
|
||||
use crate::facts::AnalyticsFact;
|
||||
use crate::facts::AppMentionedInput;
|
||||
use crate::facts::AppUsedInput;
|
||||
@@ -31,6 +32,7 @@ use crate::facts::PluginStateChangedInput;
|
||||
use crate::facts::PluginUsedInput;
|
||||
use crate::facts::SkillInvokedInput;
|
||||
use crate::facts::SubAgentThreadStartedInput;
|
||||
use crate::facts::ThreadInitializationMode;
|
||||
use crate::facts::TrackEventsContext;
|
||||
use crate::facts::TurnResolvedConfigFact;
|
||||
use crate::facts::TurnStatus;
|
||||
@@ -174,8 +176,8 @@ impl AnalyticsReducer {
|
||||
ConnectionState {
|
||||
app_server_client: CodexAppServerClientMetadata {
|
||||
product_client_id,
|
||||
client_name: Some(params.client_info.name),
|
||||
client_version: Some(params.client_info.version),
|
||||
client_name: params.client_info.name,
|
||||
client_version: params.client_info.version,
|
||||
rpc_transport,
|
||||
experimental_api_enabled: params
|
||||
.capabilities
|
||||
@@ -572,16 +574,24 @@ impl AnalyticsReducer {
|
||||
{
|
||||
return;
|
||||
}
|
||||
let product_client_id = turn_state
|
||||
let connection_metadata = turn_state
|
||||
.connection_id
|
||||
.and_then(|connection_id| self.connections.get(&connection_id))
|
||||
.map(|connection_state| connection_state.app_server_client.product_client_id.clone())
|
||||
.unwrap_or_else(|| originator().value);
|
||||
.map(|connection_state| {
|
||||
(
|
||||
connection_state.app_server_client.clone(),
|
||||
connection_state.runtime.clone(),
|
||||
)
|
||||
});
|
||||
let Some((app_server_client, runtime)) = connection_metadata else {
|
||||
return;
|
||||
};
|
||||
out.push(TrackEventRequest::TurnEvent(Box::new(
|
||||
CodexTurnEventRequest {
|
||||
event_type: "codex_turn_event",
|
||||
event_params: codex_turn_event_params(
|
||||
product_client_id,
|
||||
app_server_client,
|
||||
runtime,
|
||||
turn_id.to_string(),
|
||||
turn_state,
|
||||
),
|
||||
@@ -592,7 +602,8 @@ impl AnalyticsReducer {
|
||||
}
|
||||
|
||||
fn codex_turn_event_params(
|
||||
product_client_id: String,
|
||||
app_server_client: CodexAppServerClientMetadata,
|
||||
runtime: CodexRuntimeMetadata,
|
||||
turn_id: String,
|
||||
turn_state: &TurnState,
|
||||
) -> CodexTurnEventParams {
|
||||
@@ -610,6 +621,9 @@ fn codex_turn_event_params(
|
||||
thread_id: _resolved_thread_id,
|
||||
num_input_images: _resolved_num_input_images,
|
||||
submission_type,
|
||||
ephemeral,
|
||||
session_source,
|
||||
initialization_mode,
|
||||
model,
|
||||
model_provider,
|
||||
sandbox_policy,
|
||||
@@ -627,8 +641,14 @@ fn codex_turn_event_params(
|
||||
CodexTurnEventParams {
|
||||
thread_id,
|
||||
turn_id,
|
||||
product_client_id,
|
||||
app_server_client,
|
||||
runtime,
|
||||
submission_type,
|
||||
ephemeral,
|
||||
thread_source: thread_source_name(&session_source).map(str::to_string),
|
||||
initialization_mode,
|
||||
subagent_source: turn_subagent_source_name(&session_source),
|
||||
parent_thread_id: turn_parent_thread_id(&session_source),
|
||||
model: Some(model),
|
||||
model_provider,
|
||||
sandbox_policy: Some(sandbox_policy_mode(&sandbox_policy)),
|
||||
|
||||
Reference in New Issue
Block a user