Persist agent messages as response items (#29829)

## Why

Inter-agent messages are recorded in live history as
`ResponseItem::AgentMessage`, but rollouts stored
`InterAgentCommunication` and rebuilt the response item during resume.
This made the rollout differ from the actual Responses history.

## What changed

- store the prepared `agent_message` response item directly
- keep `trigger_turn` in a small local metadata record for fork
truncation
- keep reading older `inter_agent_communication` rollout items
This commit is contained in:
jif
2026-06-24 15:43:10 +01:00
committed by GitHub
Unverified
parent f959e7fc98
commit b4f0f3eff1
19 changed files with 144 additions and 17 deletions
+28 -6
View File
@@ -1766,6 +1766,29 @@ async fn record_inter_agent_communication_sets_turn_id_in_rollout_and_resume() {
else {
panic!("expected resumed rollout history");
};
let persisted_items = resumed
.history
.iter()
.filter(|item| {
matches!(
item,
RolloutItem::ResponseItem(_)
| RolloutItem::InterAgentCommunication(_)
| RolloutItem::InterAgentCommunicationMetadata { .. }
)
})
.cloned()
.collect::<Vec<_>>();
let expected_persisted_items = vec![
RolloutItem::InterAgentCommunicationMetadata {
trigger_turn: false,
},
RolloutItem::ResponseItem(expected_item.clone()),
];
assert_eq!(
serde_json::to_value(persisted_items).unwrap(),
serde_json::to_value(expected_persisted_items).unwrap()
);
let (resumed_session, _resumed_turn_context) = make_session_and_context().await;
resumed_session
@@ -1818,14 +1841,11 @@ async fn record_inter_agent_communication_preserves_item_id_in_rollout_and_resum
else {
panic!("expected resumed rollout history");
};
let persisted_communication = resumed.history.iter().find_map(|item| match item {
RolloutItem::InterAgentCommunication(communication) => Some(communication),
let persisted_item_id = resumed.history.iter().find_map(|item| match item {
RolloutItem::ResponseItem(item @ ResponseItem::AgentMessage { .. }) => item.id(),
_ => None,
});
assert_eq!(
persisted_communication.and_then(|communication| communication.id.as_deref()),
Some(live_item_id.as_str())
);
assert_eq!(persisted_item_id, Some(live_item_id.as_str()));
let (resumed_session, _resumed_turn_context, _rx) =
make_session_and_context_with_auth_and_config_and_rx(
@@ -2727,6 +2747,7 @@ async fn start_new_context_window_assigns_and_persists_item_ids() {
RolloutItem::SessionMeta(_)
| RolloutItem::ResponseItem(_)
| RolloutItem::InterAgentCommunication(_)
| RolloutItem::InterAgentCommunicationMetadata { .. }
| RolloutItem::TurnContext(_)
| RolloutItem::EventMsg(_) => None,
});
@@ -2783,6 +2804,7 @@ async fn record_initial_history_assigns_and_persists_id_for_forked_response_item
RolloutItem::ResponseItem(response_item) => response_item.id(),
RolloutItem::SessionMeta(_)
| RolloutItem::InterAgentCommunication(_)
| RolloutItem::InterAgentCommunicationMetadata { .. }
| RolloutItem::Compacted(_)
| RolloutItem::TurnContext(_)
| RolloutItem::EventMsg(_) => None,