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
+22
View File
@@ -412,6 +412,7 @@ mod job {
Some(communication.to_model_input_item())
}
RolloutItem::SessionMeta(_)
| RolloutItem::InterAgentCommunicationMetadata { .. }
| RolloutItem::Compacted(_)
| RolloutItem::TurnContext(_)
| RolloutItem::EventMsg(_) => None,
@@ -790,6 +791,27 @@ mod tests {
assert_eq!(parsed, expected);
}
#[test]
fn serializes_agent_message_response_items_for_memory() {
let communication = InterAgentCommunication::new(
AgentPath::root(),
AgentPath::root().join("worker").expect("agent path"),
Vec::new(),
"delegated task".to_string(),
/*trigger_turn*/ true,
);
let response_item = communication.to_model_input_item();
let serialized = job::serialize_filtered_rollout_response_items(&[
RolloutItem::InterAgentCommunicationMetadata { trigger_turn: true },
RolloutItem::ResponseItem(response_item.clone()),
])
.expect("serialize");
let parsed: Vec<ResponseItem> = serde_json::from_str(&serialized).expect("parse");
assert_eq!(parsed, vec![response_item]);
}
#[test]
fn count_outcomes_sums_token_usage_across_all_jobs() {
let counts = aggregate_stats(vec![