mirror of
https://github.com/openai/codex.git
synced 2026-11-09 08:40:33 +00:00
Track parent turns for nested Codex requests (#35835)
## What changed - Propagate the initiating turn ID through agent spawns, follow-up tasks, reviews, and delegated Codex sessions. - Add `parent_turn_id` to Responses client and turn metadata while keeping it out of external MCP metadata. - Preserve parent-turn provenance across queued agent messages when their triggering parent is unambiguous. ## Testing - Cover spawned, resumed, nested, reviewed, delegated, and WebSocket request metadata. - Verify queued messages do not claim ambiguous or queue-only parent turns. GitOrigin-RevId: 481fdebbe7df2031880fe259509273cce50b20a8
This commit is contained in:
1 parent
12b3e88028
commit
1def0a8925
34 files changed
+635
-165
No files matched your search
@@ -69,6 +69,11 @@ const TASK_COMPACT_METRIC: &str = "codex.task.compact";
|
||||
|
||||
pub(crate) type SessionTaskResult = CodexResult<Option<String>>;
|
||||
|
||||
pub(crate) enum MailboxParentProvenance {
|
||||
Ignore,
|
||||
Attribute,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub(crate) enum InterruptedTurnHistoryMarker {
|
||||
Disabled,
|
||||
@@ -319,7 +324,8 @@ impl Session {
|
||||
) {
|
||||
self.abort_all_tasks(TurnAbortReason::Replaced).await;
|
||||
self.clear_connector_selection().await;
|
||||
self.start_task(turn_context, input, task).await;
|
||||
self.start_task(turn_context, input, task, MailboxParentProvenance::Ignore)
|
||||
.await;
|
||||
}
|
||||
|
||||
pub(crate) async fn start_task<T: SessionTask>(
|
||||
@@ -327,6 +333,7 @@ impl Session {
|
||||
turn_context: Arc<TurnContext>,
|
||||
input: Vec<TurnInput>,
|
||||
task: T,
|
||||
mailbox_parent_provenance: MailboxParentProvenance,
|
||||
) {
|
||||
let task: Arc<dyn AnySessionTask> = Arc::new(task);
|
||||
let task_kind = task.kind();
|
||||
@@ -350,7 +357,13 @@ impl Session {
|
||||
.await
|
||||
.clear_turn(&turn_context.sub_id);
|
||||
|
||||
let pending_items = self.input_queue.get_pending_input(&self.active_turn).await;
|
||||
let (pending_items, parent_turn_id) =
|
||||
self.input_queue.get_pending_input(&self.active_turn).await;
|
||||
if let (MailboxParentProvenance::Attribute, Some(id)) =
|
||||
(mailbox_parent_provenance, parent_turn_id)
|
||||
{
|
||||
turn_context.turn_metadata_state.set_parent_turn_id(id);
|
||||
}
|
||||
let turn_state = {
|
||||
let mut active = self.active_turn.lock().await;
|
||||
let turn = active.get_or_insert_with(ActiveTurn::default);
|
||||
@@ -502,8 +515,13 @@ impl Session {
|
||||
let turn_context = self.new_default_turn_with_sub_id(sub_id).await;
|
||||
self.maybe_emit_model_warnings_for_turn(turn_context.as_ref())
|
||||
.await;
|
||||
self.start_task(turn_context, Vec::new(), RegularTask::new())
|
||||
.await;
|
||||
self.start_task(
|
||||
turn_context,
|
||||
Vec::new(),
|
||||
RegularTask::new(),
|
||||
MailboxParentProvenance::Attribute,
|
||||
)
|
||||
.await;
|
||||
}
|
||||
|
||||
pub async fn abort_all_tasks(self: &Arc<Self>, reason: TurnAbortReason) {
|
||||
|
||||
Reference in new issue
Block a user