mirror of
https://github.com/openai/codex.git
synced 2026-10-27 18:48:37 +00:00
[codex-analytics] denormalize thread metadata onto turn events
This commit is contained in:
@@ -254,15 +254,6 @@ fn sample_turn_resolved_config(turn_id: &str) -> TurnResolvedConfigFact {
|
||||
}
|
||||
}
|
||||
|
||||
fn sample_runtime_metadata() -> CodexRuntimeMetadata {
|
||||
CodexRuntimeMetadata {
|
||||
codex_rs_version: "0.1.0".to_string(),
|
||||
runtime_os: "macos".to_string(),
|
||||
runtime_os_version: "15.3.1".to_string(),
|
||||
runtime_arch: "aarch64".to_string(),
|
||||
}
|
||||
}
|
||||
|
||||
fn sample_app_server_client_metadata() -> CodexAppServerClientMetadata {
|
||||
CodexAppServerClientMetadata {
|
||||
product_client_id: "codex-tui".to_string(),
|
||||
@@ -273,6 +264,15 @@ fn sample_app_server_client_metadata() -> CodexAppServerClientMetadata {
|
||||
}
|
||||
}
|
||||
|
||||
fn sample_runtime_metadata() -> CodexRuntimeMetadata {
|
||||
CodexRuntimeMetadata {
|
||||
codex_rs_version: "0.1.0".to_string(),
|
||||
runtime_os: "macos".to_string(),
|
||||
runtime_os_version: "15.3.1".to_string(),
|
||||
runtime_arch: "aarch64".to_string(),
|
||||
}
|
||||
}
|
||||
|
||||
fn sample_turn_steer_request(
|
||||
thread_id: &str,
|
||||
expected_turn_id: &str,
|
||||
@@ -1222,7 +1222,6 @@ 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: None,
|
||||
@@ -1273,7 +1272,6 @@ fn turn_event_serializes_expected_shape() {
|
||||
"event_params": {
|
||||
"thread_id": "thread-2",
|
||||
"turn_id": "turn-2",
|
||||
"product_client_id": "codex-tui",
|
||||
"submission_type": null,
|
||||
"app_server_client": {
|
||||
"product_client_id": "codex-tui",
|
||||
@@ -1603,10 +1601,7 @@ async fn turn_lifecycle_emits_turn_event() {
|
||||
"runtime_arch": "aarch64",
|
||||
})
|
||||
);
|
||||
assert_eq!(
|
||||
payload["event_params"]["product_client_id"],
|
||||
json!("codex-tui")
|
||||
);
|
||||
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"));
|
||||
|
||||
@@ -127,7 +127,6 @@ 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) submission_type: Option<TurnSubmissionType>,
|
||||
pub(crate) app_server_client: CodexAppServerClientMetadata,
|
||||
pub(crate) runtime: CodexRuntimeMetadata,
|
||||
@@ -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,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,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::AnalyticsJsonRpcError;
|
||||
use crate::facts::AppMentionedInput;
|
||||
@@ -740,15 +742,14 @@ fn codex_turn_event_params(
|
||||
CodexTurnEventParams {
|
||||
thread_id,
|
||||
turn_id,
|
||||
product_client_id: app_server_client.product_client_id.clone(),
|
||||
app_server_client,
|
||||
runtime,
|
||||
submission_type,
|
||||
ephemeral,
|
||||
thread_source: thread_source_name(&session_source).map(str::to_string),
|
||||
initialization_mode,
|
||||
subagent_source: None,
|
||||
parent_thread_id: None,
|
||||
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)),
|
||||
|
||||
@@ -299,12 +299,23 @@ async fn turn_start_tracks_turn_event_analytics() -> Result<()> {
|
||||
assert_eq!(event["event_params"]["thread_id"], thread.id);
|
||||
assert_eq!(event["event_params"]["turn_id"], turn.id);
|
||||
assert_eq!(
|
||||
event["event_params"]["product_client_id"],
|
||||
event["event_params"]["app_server_client"]["product_client_id"],
|
||||
DEFAULT_CLIENT_NAME
|
||||
);
|
||||
assert_eq!(event["event_params"]["model"], "mock-model");
|
||||
assert_eq!(event["event_params"]["model_provider"], "mock_provider");
|
||||
assert_eq!(event["event_params"]["sandbox_policy"], "read_only");
|
||||
assert_eq!(event["event_params"]["ephemeral"], false);
|
||||
assert_eq!(event["event_params"]["thread_source"], "user");
|
||||
assert_eq!(event["event_params"]["initialization_mode"], "new");
|
||||
assert_eq!(
|
||||
event["event_params"]["subagent_source"],
|
||||
serde_json::Value::Null
|
||||
);
|
||||
assert_eq!(
|
||||
event["event_params"]["parent_thread_id"],
|
||||
serde_json::Value::Null
|
||||
);
|
||||
assert_eq!(event["event_params"]["num_input_images"], 1);
|
||||
assert_eq!(event["event_params"]["status"], "completed");
|
||||
assert!(event["event_params"]["started_at"].as_u64().is_some());
|
||||
|
||||
@@ -1077,6 +1077,14 @@ impl TurnContext {
|
||||
}
|
||||
}
|
||||
|
||||
fn thread_initialization_mode(initial_history: &InitialHistory) -> ThreadInitializationMode {
|
||||
match initial_history {
|
||||
InitialHistory::New => ThreadInitializationMode::New,
|
||||
InitialHistory::Forked(_) => ThreadInitializationMode::Forked,
|
||||
InitialHistory::Resumed(_) => ThreadInitializationMode::Resumed,
|
||||
}
|
||||
}
|
||||
|
||||
fn local_time_context() -> (String, String) {
|
||||
match iana_time_zone::get_timezone() {
|
||||
Ok(timezone) => (Local::now().format("%Y-%m-%d").to_string(), timezone),
|
||||
@@ -1537,6 +1545,8 @@ impl Session {
|
||||
session_configuration.collaboration_mode.model(),
|
||||
session_configuration.provider
|
||||
);
|
||||
session_configuration.thread_initialization_mode =
|
||||
thread_initialization_mode(&initial_history);
|
||||
let forked_from_id = initial_history.forked_from_id();
|
||||
|
||||
let (conversation_id, rollout_params) = match &initial_history {
|
||||
|
||||
@@ -13,6 +13,7 @@ use crate::function_tool::FunctionCallError;
|
||||
use crate::shell::default_user_shell;
|
||||
use crate::tools::format_exec_output_str;
|
||||
|
||||
use codex_analytics::ThreadInitializationMode;
|
||||
use codex_features::Features;
|
||||
use codex_login::CodexAuth;
|
||||
use codex_mcp::ToolInfo;
|
||||
@@ -1872,6 +1873,7 @@ async fn set_rate_limits_retains_previous_credits() {
|
||||
app_server_client_name: None,
|
||||
app_server_client_version: None,
|
||||
session_source: SessionSource::Exec,
|
||||
thread_initialization_mode: ThreadInitializationMode::New,
|
||||
dynamic_tools: Vec::new(),
|
||||
persist_extended_history: false,
|
||||
inherited_shell_snapshot: None,
|
||||
@@ -1974,6 +1976,7 @@ async fn set_rate_limits_updates_plan_type_when_present() {
|
||||
app_server_client_name: None,
|
||||
app_server_client_version: None,
|
||||
session_source: SessionSource::Exec,
|
||||
thread_initialization_mode: ThreadInitializationMode::New,
|
||||
dynamic_tools: Vec::new(),
|
||||
persist_extended_history: false,
|
||||
inherited_shell_snapshot: None,
|
||||
@@ -2323,6 +2326,7 @@ pub(crate) async fn make_session_configuration_for_tests() -> SessionConfigurati
|
||||
app_server_client_name: None,
|
||||
app_server_client_version: None,
|
||||
session_source: SessionSource::Exec,
|
||||
thread_initialization_mode: ThreadInitializationMode::New,
|
||||
dynamic_tools: Vec::new(),
|
||||
persist_extended_history: false,
|
||||
inherited_shell_snapshot: None,
|
||||
@@ -2586,6 +2590,7 @@ async fn session_new_fails_when_zsh_fork_enabled_without_zsh_path() {
|
||||
app_server_client_name: None,
|
||||
app_server_client_version: None,
|
||||
session_source: SessionSource::Exec,
|
||||
thread_initialization_mode: ThreadInitializationMode::New,
|
||||
dynamic_tools: Vec::new(),
|
||||
persist_extended_history: false,
|
||||
inherited_shell_snapshot: None,
|
||||
@@ -2690,6 +2695,7 @@ pub(crate) async fn make_session_and_context() -> (Session, TurnContext) {
|
||||
app_server_client_name: None,
|
||||
app_server_client_version: None,
|
||||
session_source: SessionSource::Exec,
|
||||
thread_initialization_mode: ThreadInitializationMode::New,
|
||||
dynamic_tools: Vec::new(),
|
||||
persist_extended_history: false,
|
||||
inherited_shell_snapshot: None,
|
||||
@@ -3531,6 +3537,7 @@ pub(crate) async fn make_session_and_context_with_dynamic_tools_and_rx(
|
||||
app_server_client_name: None,
|
||||
app_server_client_version: None,
|
||||
session_source: SessionSource::Exec,
|
||||
thread_initialization_mode: ThreadInitializationMode::New,
|
||||
dynamic_tools,
|
||||
persist_extended_history: false,
|
||||
inherited_shell_snapshot: None,
|
||||
|
||||
Reference in New Issue
Block a user