Persist resume metadata in compaction checkpoints (#47323)

## Why

Compaction companion records do not represent all resume state, including the last started turn and previous turn settings. The selected multi-agent runtime also needs a persisted value when no companion turn context is present.

## What changed

- Add optional `resume_metadata` to `CompactedItem`, recording the multi-agent version, last started turn ID, and previous turn settings. Preserve the distinction between absent metadata and explicitly empty values while retaining compatibility with older records.
- Capture this metadata under the settings persistence lock alongside the compaction checkpoint.
- Rewrite inherited metadata to use the child agent's runtime, and clear previous turn settings when the child must rebuild context.
- Clear pending continuation state before delivering acceptance of standalone settings updates, while holding the persistence lock.

## Testing

Add coverage for metadata round trips with empty values, legacy reader compatibility, checkpoint companion records, inherited fork metadata, and continuation invalidation while settings event delivery is blocked.

GitOrigin-RevId: f30b7feaa7e2fdb5b65fc3c53b37fd7a7fe27903
This commit is contained in:
Owen Lin
2026-09-22 16:35:30 +00:00
committed by copyberry
parent 5a11c45606
commit 286d4ecf44
23 changed files with 340 additions and 63 deletions
@@ -891,5 +891,6 @@ fn compacted(message: &str, replacement_history: Option<Vec<ResponseItem>>) -> R
window_id: None,
compaction_response_id: None,
latest_token_usage_record: None,
resume_metadata: None,
})
}
@@ -248,6 +248,7 @@ fn compacted(replacement_history: Vec<ResponseItem>) -> RolloutItem {
window_id: None,
compaction_response_id: None,
latest_token_usage_record: None,
resume_metadata: None,
})
}
@@ -1783,6 +1784,7 @@ async fn migration_compacts_subagent_prefix_and_does_not_project_it() {
window_id: None,
compaction_response_id: None,
latest_token_usage_record: None,
resume_metadata: None,
}),
RolloutItem::Compacted(CompactedItem {
message: "latest checkpoint".to_string(),
@@ -1807,6 +1809,7 @@ async fn migration_compacts_subagent_prefix_and_does_not_project_it() {
window_id: None,
compaction_response_id: None,
latest_token_usage_record: None,
resume_metadata: None,
}),
started("child-turn"),
RolloutItem::TurnContext(TurnContextItem {
@@ -674,6 +674,7 @@ mod tests {
window_id: None,
compaction_response_id: None,
latest_token_usage_record: None,
resume_metadata: None,
});
let first = sync