mirror of
https://github.com/openai/codex.git
synced 2026-11-04 00:24:43 +00:00
adding parent_thread_id in guardian (#17249)
## Summary This PR adds the parent conversation/session id to the subagent-start analytics event for Guardian subagents. Previously, Guardian sessions were emitted as subagent thread-initialized events, but their `parent_thread_id` was serialized as `null`. After this change, the `codex_thread_initialized` analytics event for a Guardian child session includes the parent user conversation id.
This commit is contained in:
1 parent
26a28afc6d
commit
4e910bf151
7 files changed
+39
-1
No files matched your search
@@ -454,6 +454,7 @@ fn subagent_thread_started_review_serializes_expected_shape() {
|
|||||||
let event = TrackEventRequest::ThreadInitialized(subagent_thread_started_event_request(
|
let event = TrackEventRequest::ThreadInitialized(subagent_thread_started_event_request(
|
||||||
SubAgentThreadStartedInput {
|
SubAgentThreadStartedInput {
|
||||||
thread_id: "thread-review".to_string(),
|
thread_id: "thread-review".to_string(),
|
||||||
|
parent_thread_id: None,
|
||||||
product_client_id: "codex-tui".to_string(),
|
product_client_id: "codex-tui".to_string(),
|
||||||
client_name: "codex-tui".to_string(),
|
client_name: "codex-tui".to_string(),
|
||||||
client_version: "1.0.0".to_string(),
|
client_version: "1.0.0".to_string(),
|
||||||
@@ -496,6 +497,7 @@ fn subagent_thread_started_thread_spawn_serializes_parent_thread_id() {
|
|||||||
let event = TrackEventRequest::ThreadInitialized(subagent_thread_started_event_request(
|
let event = TrackEventRequest::ThreadInitialized(subagent_thread_started_event_request(
|
||||||
SubAgentThreadStartedInput {
|
SubAgentThreadStartedInput {
|
||||||
thread_id: "thread-spawn".to_string(),
|
thread_id: "thread-spawn".to_string(),
|
||||||
|
parent_thread_id: None,
|
||||||
product_client_id: "codex-tui".to_string(),
|
product_client_id: "codex-tui".to_string(),
|
||||||
client_name: "codex-tui".to_string(),
|
client_name: "codex-tui".to_string(),
|
||||||
client_version: "1.0.0".to_string(),
|
client_version: "1.0.0".to_string(),
|
||||||
@@ -526,6 +528,7 @@ fn subagent_thread_started_memory_consolidation_serializes_expected_shape() {
|
|||||||
let event = TrackEventRequest::ThreadInitialized(subagent_thread_started_event_request(
|
let event = TrackEventRequest::ThreadInitialized(subagent_thread_started_event_request(
|
||||||
SubAgentThreadStartedInput {
|
SubAgentThreadStartedInput {
|
||||||
thread_id: "thread-memory".to_string(),
|
thread_id: "thread-memory".to_string(),
|
||||||
|
parent_thread_id: None,
|
||||||
product_client_id: "codex-tui".to_string(),
|
product_client_id: "codex-tui".to_string(),
|
||||||
client_name: "codex-tui".to_string(),
|
client_name: "codex-tui".to_string(),
|
||||||
client_version: "1.0.0".to_string(),
|
client_version: "1.0.0".to_string(),
|
||||||
@@ -550,6 +553,7 @@ fn subagent_thread_started_other_serializes_expected_shape() {
|
|||||||
let event = TrackEventRequest::ThreadInitialized(subagent_thread_started_event_request(
|
let event = TrackEventRequest::ThreadInitialized(subagent_thread_started_event_request(
|
||||||
SubAgentThreadStartedInput {
|
SubAgentThreadStartedInput {
|
||||||
thread_id: "thread-guardian".to_string(),
|
thread_id: "thread-guardian".to_string(),
|
||||||
|
parent_thread_id: None,
|
||||||
product_client_id: "codex-tui".to_string(),
|
product_client_id: "codex-tui".to_string(),
|
||||||
client_name: "codex-tui".to_string(),
|
client_name: "codex-tui".to_string(),
|
||||||
client_version: "1.0.0".to_string(),
|
client_version: "1.0.0".to_string(),
|
||||||
@@ -562,6 +566,31 @@ fn subagent_thread_started_other_serializes_expected_shape() {
|
|||||||
|
|
||||||
let payload = serde_json::to_value(&event).expect("serialize other subagent event");
|
let payload = serde_json::to_value(&event).expect("serialize other subagent event");
|
||||||
assert_eq!(payload["event_params"]["subagent_source"], "guardian");
|
assert_eq!(payload["event_params"]["subagent_source"], "guardian");
|
||||||
|
assert_eq!(payload["event_params"]["parent_thread_id"], json!(null));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn subagent_thread_started_other_serializes_explicit_parent_thread_id() {
|
||||||
|
let event = TrackEventRequest::ThreadInitialized(subagent_thread_started_event_request(
|
||||||
|
SubAgentThreadStartedInput {
|
||||||
|
thread_id: "thread-guardian".to_string(),
|
||||||
|
parent_thread_id: Some("parent-thread-guardian".to_string()),
|
||||||
|
product_client_id: "codex-tui".to_string(),
|
||||||
|
client_name: "codex-tui".to_string(),
|
||||||
|
client_version: "1.0.0".to_string(),
|
||||||
|
model: "gpt-5".to_string(),
|
||||||
|
ephemeral: false,
|
||||||
|
subagent_source: SubAgentSource::Other("guardian".to_string()),
|
||||||
|
created_at: 126,
|
||||||
|
},
|
||||||
|
));
|
||||||
|
|
||||||
|
let payload = serde_json::to_value(&event).expect("serialize guardian subagent event");
|
||||||
|
assert_eq!(payload["event_params"]["subagent_source"], "guardian");
|
||||||
|
assert_eq!(
|
||||||
|
payload["event_params"]["parent_thread_id"],
|
||||||
|
"parent-thread-guardian"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
@@ -574,6 +603,7 @@ async fn subagent_thread_started_publishes_without_initialize() {
|
|||||||
AnalyticsFact::Custom(CustomAnalyticsFact::SubAgentThreadStarted(
|
AnalyticsFact::Custom(CustomAnalyticsFact::SubAgentThreadStarted(
|
||||||
SubAgentThreadStartedInput {
|
SubAgentThreadStartedInput {
|
||||||
thread_id: "thread-review".to_string(),
|
thread_id: "thread-review".to_string(),
|
||||||
|
parent_thread_id: None,
|
||||||
product_client_id: "codex-tui".to_string(),
|
product_client_id: "codex-tui".to_string(),
|
||||||
client_name: "codex-tui".to_string(),
|
client_name: "codex-tui".to_string(),
|
||||||
client_version: "1.0.0".to_string(),
|
client_version: "1.0.0".to_string(),
|
||||||
|
|||||||
@@ -249,7 +249,9 @@ pub(crate) fn subagent_thread_started_event_request(
|
|||||||
thread_source: Some("subagent"),
|
thread_source: Some("subagent"),
|
||||||
initialization_mode: ThreadInitializationMode::New,
|
initialization_mode: ThreadInitializationMode::New,
|
||||||
subagent_source: Some(subagent_source_name(&input.subagent_source)),
|
subagent_source: Some(subagent_source_name(&input.subagent_source)),
|
||||||
parent_thread_id: subagent_parent_thread_id(&input.subagent_source),
|
parent_thread_id: input
|
||||||
|
.parent_thread_id
|
||||||
|
.or_else(|| subagent_parent_thread_id(&input.subagent_source)),
|
||||||
created_at: input.created_at,
|
created_at: input.created_at,
|
||||||
};
|
};
|
||||||
ThreadInitializedEvent {
|
ThreadInitializedEvent {
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ pub struct AppInvocation {
|
|||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct SubAgentThreadStartedInput {
|
pub struct SubAgentThreadStartedInput {
|
||||||
pub thread_id: String,
|
pub thread_id: String,
|
||||||
|
pub parent_thread_id: Option<String>,
|
||||||
pub product_client_id: String,
|
pub product_client_id: String,
|
||||||
pub client_name: String,
|
pub client_name: String,
|
||||||
pub client_version: String,
|
pub client_version: String,
|
||||||
|
|||||||
@@ -283,6 +283,7 @@ impl AgentControl {
|
|||||||
.analytics_events_client,
|
.analytics_events_client,
|
||||||
client_metadata,
|
client_metadata,
|
||||||
new_thread.thread_id,
|
new_thread.thread_id,
|
||||||
|
/*parent_thread_id*/ None,
|
||||||
thread_config,
|
thread_config,
|
||||||
subagent_source.clone(),
|
subagent_source.clone(),
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -4582,6 +4582,7 @@ pub(crate) fn emit_subagent_session_started(
|
|||||||
analytics_events_client: &AnalyticsEventsClient,
|
analytics_events_client: &AnalyticsEventsClient,
|
||||||
client_metadata: AppServerClientMetadata,
|
client_metadata: AppServerClientMetadata,
|
||||||
thread_id: ThreadId,
|
thread_id: ThreadId,
|
||||||
|
parent_thread_id: Option<ThreadId>,
|
||||||
thread_config: ThreadConfigSnapshot,
|
thread_config: ThreadConfigSnapshot,
|
||||||
subagent_source: SubAgentSource,
|
subagent_source: SubAgentSource,
|
||||||
) {
|
) {
|
||||||
@@ -4599,6 +4600,7 @@ pub(crate) fn emit_subagent_session_started(
|
|||||||
.as_secs();
|
.as_secs();
|
||||||
analytics_events_client.track_subagent_thread_started(SubAgentThreadStartedInput {
|
analytics_events_client.track_subagent_thread_started(SubAgentThreadStartedInput {
|
||||||
thread_id: thread_id.to_string(),
|
thread_id: thread_id.to_string(),
|
||||||
|
parent_thread_id: parent_thread_id.map(|thread_id| thread_id.to_string()),
|
||||||
product_client_id: client_name.clone(),
|
product_client_id: client_name.clone(),
|
||||||
client_name,
|
client_name,
|
||||||
client_version,
|
client_version,
|
||||||
|
|||||||
@@ -104,6 +104,7 @@ pub(crate) async fn run_codex_thread_interactive(
|
|||||||
&parent_session.services.analytics_events_client,
|
&parent_session.services.analytics_events_client,
|
||||||
client_metadata,
|
client_metadata,
|
||||||
codex.session.conversation_id,
|
codex.session.conversation_id,
|
||||||
|
Some(parent_session.conversation_id),
|
||||||
thread_config,
|
thread_config,
|
||||||
subagent_source,
|
subagent_source,
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -156,6 +156,7 @@ pub(super) async fn run(session: &Arc<Session>, config: Arc<Config>) {
|
|||||||
&session.services.analytics_events_client,
|
&session.services.analytics_events_client,
|
||||||
client_metadata,
|
client_metadata,
|
||||||
thread_id,
|
thread_id,
|
||||||
|
/*parent_thread_id*/ None,
|
||||||
thread_config,
|
thread_config,
|
||||||
SubAgentSource::MemoryConsolidation,
|
SubAgentSource::MemoryConsolidation,
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in new issue
Block a user