mirror of
https://github.com/openai/codex.git
synced 2026-10-25 18:28:38 +00:00
pivot to consuming from app-event stream
This commit is contained in:
@@ -5,8 +5,6 @@ use std::path::Path;
|
||||
use std::path::PathBuf;
|
||||
use std::sync::Arc;
|
||||
use std::sync::atomic::AtomicU64;
|
||||
use std::time::SystemTime;
|
||||
use std::time::UNIX_EPOCH;
|
||||
|
||||
use crate::AuthManager;
|
||||
use crate::CodexAuth;
|
||||
@@ -350,9 +348,6 @@ use crate::util::backoff;
|
||||
use crate::windows_sandbox::WindowsSandboxLevelExt;
|
||||
use codex_analytics::AnalyticsEventsClient;
|
||||
use codex_analytics::AppInvocation;
|
||||
use codex_analytics::CodexThreadContext;
|
||||
use codex_analytics::CodexThreadInitializedInput;
|
||||
use codex_analytics::InitializationMode;
|
||||
use codex_analytics::InvocationType;
|
||||
use codex_analytics::build_track_events_context;
|
||||
use codex_async_utils::OrCancelExt;
|
||||
@@ -637,12 +632,6 @@ impl Codex {
|
||||
user_shell_override,
|
||||
};
|
||||
|
||||
let initialization_mode = initialization_mode(&conversation_history);
|
||||
let thread_session_source = session_configuration.session_source.clone();
|
||||
let subagent_source = session_source_subagent_source(&thread_session_source);
|
||||
let parent_thread_id = session_source_parent_thread_id(&thread_session_source);
|
||||
let thread_initialized_configuration = session_configuration.clone();
|
||||
|
||||
// Generate a unique ID for the lifetime of this Codex session.
|
||||
let session_source_clone = session_configuration.session_source.clone();
|
||||
let (agent_status_tx, agent_status_rx) = watch::channel(AgentStatus::PendingInit);
|
||||
@@ -670,31 +659,6 @@ impl Codex {
|
||||
})?;
|
||||
let thread_id = session.conversation_id;
|
||||
|
||||
session
|
||||
.services
|
||||
.analytics_events_client
|
||||
.track_thread_initialized(CodexThreadInitializedInput {
|
||||
thread_id: thread_id.to_string(),
|
||||
model: thread_initialized_configuration
|
||||
.collaboration_mode
|
||||
.model()
|
||||
.to_string(),
|
||||
product_client_id: crate::default_client::originator().value,
|
||||
created_at: SystemTime::now()
|
||||
.duration_since(UNIX_EPOCH)
|
||||
.unwrap_or_default()
|
||||
.as_secs(),
|
||||
thread_context: CodexThreadContext {
|
||||
ephemeral: thread_initialized_configuration
|
||||
.original_config_do_not_use
|
||||
.ephemeral,
|
||||
session_source: thread_session_source,
|
||||
initialization_mode,
|
||||
subagent_source,
|
||||
parent_thread_id,
|
||||
},
|
||||
});
|
||||
|
||||
// This task will run until Op::Shutdown is received.
|
||||
let session_for_loop = Arc::clone(&session);
|
||||
let session_loop_handle = tokio::spawn(async move {
|
||||
@@ -809,30 +773,6 @@ impl Codex {
|
||||
}
|
||||
}
|
||||
|
||||
fn initialization_mode(conversation_history: &InitialHistory) -> InitializationMode {
|
||||
match conversation_history {
|
||||
InitialHistory::New => InitializationMode::New,
|
||||
InitialHistory::Forked(_) => InitializationMode::Forked,
|
||||
InitialHistory::Resumed(_) => InitializationMode::Resumed,
|
||||
}
|
||||
}
|
||||
|
||||
fn session_source_subagent_source(session_source: &SessionSource) -> Option<SubAgentSource> {
|
||||
match session_source {
|
||||
SessionSource::SubAgent(subagent_source) => Some(subagent_source.clone()),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn session_source_parent_thread_id(session_source: &SessionSource) -> Option<String> {
|
||||
match session_source {
|
||||
SessionSource::SubAgent(SubAgentSource::ThreadSpawn {
|
||||
parent_thread_id, ..
|
||||
}) => Some(parent_thread_id.to_string()),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
pub(crate) fn completed_session_loop_termination() -> SessionLoopTermination {
|
||||
futures::future::ready(()).boxed().shared()
|
||||
|
||||
@@ -136,6 +136,8 @@ pub type CodexConversation = CodexThread;
|
||||
pub use auth::AuthManager;
|
||||
pub use auth::CodexAuth;
|
||||
pub use codex_analytics::AnalyticsEventsClient;
|
||||
pub use codex_analytics::InitializeInput;
|
||||
pub use codex_analytics::ThreadInitializeInput;
|
||||
mod default_client_forwarding;
|
||||
|
||||
/// Default Codex HTTP client headers and reqwest construction.
|
||||
|
||||
@@ -1,78 +0,0 @@
|
||||
use anyhow::Result;
|
||||
use codex_core::CodexAuth;
|
||||
use codex_core::config::Constrained;
|
||||
use core_test_support::responses::start_mock_server;
|
||||
use core_test_support::test_codex::test_codex;
|
||||
use std::time::Duration;
|
||||
use std::time::Instant;
|
||||
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
async fn thread_initialization_tracks_thread_initialized_analytics() -> Result<()> {
|
||||
let server = start_mock_server().await;
|
||||
let chatgpt_base_url = server.uri();
|
||||
|
||||
let test = test_codex()
|
||||
.with_auth(CodexAuth::create_dummy_chatgpt_auth_for_testing())
|
||||
.with_config(move |config| {
|
||||
config.chatgpt_base_url = chatgpt_base_url;
|
||||
config.model = Some("gpt-5".to_string());
|
||||
config.permissions.sandbox_policy = Constrained::allow_any(
|
||||
codex_protocol::protocol::SandboxPolicy::new_workspace_write_policy(),
|
||||
);
|
||||
config.ephemeral = true;
|
||||
})
|
||||
.build(&server)
|
||||
.await?;
|
||||
|
||||
let deadline = Instant::now() + Duration::from_secs(10);
|
||||
let analytics_request = loop {
|
||||
let requests = server.received_requests().await.unwrap_or_default();
|
||||
if let Some(request) = requests
|
||||
.into_iter()
|
||||
.find(|request| request.url.path() == "/codex/analytics-events/events")
|
||||
{
|
||||
break request;
|
||||
}
|
||||
if Instant::now() >= deadline {
|
||||
panic!("timed out waiting for thread analytics request");
|
||||
}
|
||||
tokio::time::sleep(Duration::from_millis(50)).await;
|
||||
};
|
||||
|
||||
let payload: serde_json::Value =
|
||||
serde_json::from_slice(&analytics_request.body).expect("analytics payload");
|
||||
let event = payload["events"]
|
||||
.as_array()
|
||||
.expect("events array")
|
||||
.iter()
|
||||
.find(|event| event["event_type"] == "codex_thread_initialized")
|
||||
.expect("codex_thread_initialized event should be present");
|
||||
|
||||
assert_eq!(
|
||||
event["event_params"]["thread_id"],
|
||||
serde_json::json!(test.session_configured.session_id.to_string())
|
||||
);
|
||||
assert_eq!(
|
||||
event["event_params"]["product_client_id"],
|
||||
serde_json::json!(codex_core::default_client::originator().value)
|
||||
);
|
||||
assert_eq!(event["event_params"]["model"], "gpt-5");
|
||||
assert_eq!(event["event_params"]["ephemeral"], true);
|
||||
assert_eq!(event["event_params"]["session_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!(
|
||||
event["event_params"]["created_at"]
|
||||
.as_u64()
|
||||
.is_some_and(|timestamp| timestamp > 0)
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -58,7 +58,6 @@ pub static CODEX_ALIASES_TEMP_DIR: TestCodexAliasesGuard = unsafe {
|
||||
mod abort_tasks;
|
||||
mod agent_jobs;
|
||||
mod agent_websocket;
|
||||
mod analytics;
|
||||
mod apply_patch_cli;
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
mod approvals;
|
||||
|
||||
Reference in New Issue
Block a user