feat(core): store turn_id on ResponseItem metadata (#28360)

## Description

This PR is a followup to https://github.com/openai/codex/pull/28355 and
starts assigning `internal_chat_message_metadata_passthrough.turn_id` to
durable Responses API items created during a turn.

The goal is that those items keep the `turn_id` that introduced them
when Codex resends stateless HTTP context, reconstructs history for
resume/fork paths, or reuses websocket response state.

## What changed

- Set `internal_chat_message_metadata_passthrough.turn_id` when missing
as response items enter durable history, initial/replacement history,
inter-agent communication history, and local compaction summaries.
- Preserve existing item turn IDs instead of overwriting them during
persistence, resume reconstruction, compaction, forked history, and
websocket incremental reuse.
- Keep `compaction_trigger` fieldless because it is a request control,
not a durable response item.
- Update focused history/request assertions and fixtures for stateless
requests, websocket incrementals, compaction, thread injection, prompt
debug, and related CI coverage.
This commit is contained in:
Owen Lin
2026-06-22 16:45:14 -07:00
committed by GitHub
Unverified
parent 7153affa0f
commit 4a82ecc3c9
27 changed files with 317 additions and 167 deletions
+10 -1
View File
@@ -2693,6 +2693,10 @@ impl Session {
) -> Cow<'a, [ResponseItem]> {
let mut items = Cow::Borrowed(items);
prepare_response_items(items.to_mut());
// Most response items get their passthrough turn ID at the durable history boundary.
for item in items.to_mut() {
item.set_turn_id_if_missing(&turn_context.sub_id);
}
if turn_context.config.features.enabled(Feature::ItemIds) {
Self::assign_missing_response_item_ids(items)
} else {
@@ -2784,8 +2788,9 @@ impl Session {
pub(crate) async fn record_inter_agent_communication(
&self,
turn_context: &TurnContext,
communication: InterAgentCommunication,
mut communication: InterAgentCommunication,
) {
communication.set_turn_id_if_missing(&turn_context.sub_id);
let response_item = communication.to_model_input_item();
let items = self.prepare_conversation_items_for_history(
turn_context,
@@ -3355,6 +3360,10 @@ impl Session {
{
items.push(guardian_developer_message);
}
// New context windows and compaction install these items directly into replacement history.
for item in &mut items {
item.set_turn_id_if_missing(&turn_context.sub_id);
}
items
}