mirror of
https://github.com/openai/codex.git
synced 2026-11-13 22:47:20 +00:00
Persist realtime events in the thread timeline (#40508)
## Why Clients need a bounded view of realtime conversations that preserves the order of speech, agent work, and turn lifecycle events without loading the full thread history. ## What changed - Persist realtime session boundaries, transcript segments, and promoted agent items in paginated thread rollouts. - Add the experimental `thread/timeline/list` API to page ordinary items, realtime items, and turn boundaries in canonical rollout order. Include `activeRealtimeSessionAtPageStart` so each page can be rendered independently. - Emit typed `thread/realtime/item/started`, `thread/realtime/item/transcript/delta`, and `thread/realtime/item/completed` notifications around durable realtime items. - Keep the existing `thread/items/list` response and legacy thread history behavior unchanged. ## Testing - Cover mixed timeline pagination, realtime-session state at page boundaries, rollout replay, subagent history prefixes, transcript streaming, steering, and promoted agent artifacts. GitOrigin-RevId: faa2c420192d63e060e8fb32446e3c797422656e
This commit is contained in:
1 parent
80e871309a
commit
41ca88e95c
80 files changed
+5140
-47
No files matched your search
@@ -648,6 +648,13 @@ mod tests {
|
||||
.execute(&pool)
|
||||
.await
|
||||
.expect("insert item");
|
||||
sqlx::query(
|
||||
"INSERT INTO thread_realtime_items (thread_id, item_id, rollout_ordinal, created_at_ms, item_type, item_json) VALUES (?, 'realtime-1', 3, 1, 'realtime_session_started', '{}')",
|
||||
)
|
||||
.bind(thread_id_string.as_str())
|
||||
.execute(&pool)
|
||||
.await
|
||||
.expect("insert realtime item");
|
||||
sqlx::query(
|
||||
"INSERT INTO thread_history_projection_state (thread_id, next_rollout_byte_offset, next_rollout_ordinal) VALUES (?, 3, 3)",
|
||||
)
|
||||
@@ -668,21 +675,23 @@ mod tests {
|
||||
}
|
||||
));
|
||||
assert!(rollout_path.exists());
|
||||
let counts = sqlx::query_as::<_, (i64, i64, i64)>(
|
||||
let counts = sqlx::query_as::<_, (i64, i64, i64, i64)>(
|
||||
r#"
|
||||
SELECT
|
||||
(SELECT COUNT(*) FROM thread_turns WHERE thread_id = ?),
|
||||
(SELECT COUNT(*) FROM thread_items WHERE thread_id = ?),
|
||||
(SELECT COUNT(*) FROM thread_realtime_items WHERE thread_id = ?),
|
||||
(SELECT COUNT(*) FROM thread_history_projection_state WHERE thread_id = ?)
|
||||
"#,
|
||||
)
|
||||
.bind(thread_id_string.as_str())
|
||||
.bind(thread_id_string.as_str())
|
||||
.bind(thread_id_string.as_str())
|
||||
.bind(thread_id_string.as_str())
|
||||
.fetch_one(&pool)
|
||||
.await
|
||||
.expect("read preserved history rows");
|
||||
assert_eq!(counts, (1, 1, 1));
|
||||
assert_eq!(counts, (1, 1, 1, 1));
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
@@ -725,6 +734,13 @@ SELECT
|
||||
.execute(&pool)
|
||||
.await
|
||||
.expect("insert item");
|
||||
sqlx::query(
|
||||
"INSERT INTO thread_realtime_items (thread_id, item_id, rollout_ordinal, created_at_ms, item_type, item_json) VALUES (?, 'realtime-1', 3, 1, 'realtime_session_started', '{}')",
|
||||
)
|
||||
.bind(thread_id_string.as_str())
|
||||
.execute(&pool)
|
||||
.await
|
||||
.expect("insert realtime item");
|
||||
sqlx::query(
|
||||
"INSERT INTO thread_history_projection_state (thread_id, next_rollout_byte_offset, next_rollout_ordinal) VALUES (?, 3, 3)",
|
||||
)
|
||||
@@ -759,21 +775,23 @@ SELECT
|
||||
.expect("delete thread");
|
||||
assert!(!lock_path.exists());
|
||||
|
||||
let counts = sqlx::query_as::<_, (i64, i64, i64)>(
|
||||
let counts = sqlx::query_as::<_, (i64, i64, i64, i64)>(
|
||||
r#"
|
||||
SELECT
|
||||
(SELECT COUNT(*) FROM thread_turns WHERE thread_id = ?),
|
||||
(SELECT COUNT(*) FROM thread_items WHERE thread_id = ?),
|
||||
(SELECT COUNT(*) FROM thread_realtime_items WHERE thread_id = ?),
|
||||
(SELECT COUNT(*) FROM thread_history_projection_state WHERE thread_id = ?)
|
||||
"#,
|
||||
)
|
||||
.bind(thread_id_string.as_str())
|
||||
.bind(thread_id_string.as_str())
|
||||
.bind(thread_id_string.as_str())
|
||||
.bind(thread_id_string.as_str())
|
||||
.fetch_one(&pool)
|
||||
.await
|
||||
.expect("read remaining history rows");
|
||||
assert_eq!(counts, (0, 0, 0));
|
||||
assert_eq!(counts, (0, 0, 0, 0));
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
|
||||
Reference in new issue
Block a user