mirror of
https://github.com/openai/codex.git
synced 2026-11-13 22:47:20 +00:00
Preserve root turn attribution in turn-start events (#44611)
## Why Persisted turn-start events lack the originating root turn ID, so they cannot directly associate child turns with the root turn that initiated them. ## What changed - Add optional `root_turn_id` to `TurnStartedEvent`. Use the inherited root turn ID when available, otherwise the turn's own ID. - Centralize turn-start emission for regular turns, shell commands, and manual compaction so they record attribution consistently. - Carry attribution into `ThreadHistoryTurnChange` when processing turn-start events and retain it through completion in the history builder. - Keep older records compatible by defaulting missing attribution to `None`. ## Testing Add coverage for root and child turn attribution, persistence when tool collisions fail a turn before sampling, history change propagation, and deserialization of older turn-start records. GitOrigin-RevId: 54a80b828ca7d1c4c19f13d468c01d052e1b9130
This commit is contained in:
1 parent
242c5ce01c
commit
196964ef10
40 files changed
+252
-55
No files matched your search
@@ -1102,6 +1102,7 @@ async fn thread_fork_can_cut_before_unfinished_stored_turn() -> Result<()> {
|
||||
&source_path,
|
||||
&RolloutItem::EventMsg(EventMsg::TurnStarted(TurnStartedEvent {
|
||||
turn_id: unfinished_turn_id.to_string(),
|
||||
root_turn_id: None,
|
||||
trace_id: None,
|
||||
started_at: None,
|
||||
model_context_window: None,
|
||||
@@ -1376,6 +1377,7 @@ async fn thread_fork_creates_reference_backed_paginated_thread() -> Result<()> {
|
||||
for item in [
|
||||
RolloutItem::EventMsg(EventMsg::TurnStarted(TurnStartedEvent {
|
||||
turn_id: "turn-1".to_string(),
|
||||
root_turn_id: None,
|
||||
trace_id: None,
|
||||
started_at: Some(10),
|
||||
model_context_window: None,
|
||||
@@ -1705,6 +1707,7 @@ async fn assert_thread_fork_freezes_active_paginated_turn_as_interrupted(
|
||||
source_path.as_path(),
|
||||
&RolloutItem::EventMsg(EventMsg::TurnStarted(TurnStartedEvent {
|
||||
turn_id: "active-turn".to_string(),
|
||||
root_turn_id: None,
|
||||
trace_id: None,
|
||||
started_at: Some(10),
|
||||
model_context_window: None,
|
||||
|
||||
@@ -2222,6 +2222,7 @@ async fn read_items_page(
|
||||
fn paginated_turn_started(turn_id: &str) -> RolloutItem {
|
||||
RolloutItem::EventMsg(EventMsg::TurnStarted(TurnStartedEvent {
|
||||
turn_id: turn_id.to_string(),
|
||||
root_turn_id: None,
|
||||
trace_id: None,
|
||||
started_at: Some(10),
|
||||
model_context_window: None,
|
||||
|
||||
@@ -3866,6 +3866,7 @@ async fn cold_paginated_resume_restores_usage_without_loading_turns() -> Result<
|
||||
&path,
|
||||
&RolloutItem::EventMsg(EventMsg::TurnStarted(TurnStartedEvent {
|
||||
turn_id: canonical_turn_id.to_string(),
|
||||
root_turn_id: None,
|
||||
trace_id: None,
|
||||
started_at: None,
|
||||
model_context_window: None,
|
||||
@@ -3977,6 +3978,7 @@ async fn cold_paginated_resume_omits_usage_when_its_turn_is_ambiguous() -> Resul
|
||||
&path,
|
||||
&RolloutItem::EventMsg(EventMsg::TurnStarted(TurnStartedEvent {
|
||||
turn_id: interrupted_turn_id.to_string(),
|
||||
root_turn_id: None,
|
||||
trace_id: None,
|
||||
started_at: None,
|
||||
model_context_window: None,
|
||||
@@ -4119,6 +4121,7 @@ async fn thread_resume_token_usage_replay_ignores_stale_interrupted_tail_turn()
|
||||
"type": "event_msg",
|
||||
"payload": serde_json::to_value(EventMsg::TurnStarted(TurnStartedEvent {
|
||||
turn_id: stale_turn_id.to_string(),
|
||||
root_turn_id: None,
|
||||
trace_id: None,
|
||||
started_at: None,
|
||||
model_context_window: None,
|
||||
@@ -4207,6 +4210,7 @@ async fn thread_resume_token_usage_replay_can_belong_to_interrupted_turn() -> Re
|
||||
"type": "event_msg",
|
||||
"payload": serde_json::to_value(EventMsg::TurnStarted(TurnStartedEvent {
|
||||
turn_id: interrupted_turn_id.to_string(),
|
||||
root_turn_id: None,
|
||||
trace_id: None,
|
||||
started_at: None,
|
||||
model_context_window: None,
|
||||
@@ -4520,6 +4524,7 @@ async fn thread_resume_and_read_interrupt_incomplete_rollout_turn_when_thread_is
|
||||
"type": "event_msg",
|
||||
"payload": serde_json::to_value(EventMsg::TurnStarted(TurnStartedEvent {
|
||||
turn_id: turn_id.to_string(),
|
||||
root_turn_id: None,
|
||||
trace_id: None,
|
||||
started_at: None,
|
||||
model_context_window: None,
|
||||
|
||||
@@ -97,6 +97,7 @@ async fn timeline_pages_mix_items_and_resolve_the_opening_realtime_session() ->
|
||||
}),
|
||||
RolloutItem::EventMsg(EventMsg::TurnStarted(TurnStartedEvent {
|
||||
turn_id: "turn-1".to_string(),
|
||||
root_turn_id: None,
|
||||
trace_id: None,
|
||||
started_at: Some(10),
|
||||
model_context_window: None,
|
||||
|
||||
Reference in new issue
Block a user