Retain client developer messages across context compaction (#38445)

## Why

Client-authored developer instructions should remain available after a context
window is compacted when `retain_client_developer_messages` is enabled.

## What changed

- Preserve annotated client-authored developer messages during remote compaction
  v2 and local token-budget context resets.
- Apply the existing retained-message token budget when carrying those messages
  into the new context window.

## Testing

- Cover enabled and disabled retention for remote compaction v2, manual
  token-budget compaction, and mid-turn automatic compaction.

GitOrigin-RevId: 4cb3782cb86ef46458413a17a3255d0016fd675f
This commit is contained in:
rka-oai authored and copyberry committed 2026-08-13 22:21:18 +00:00
1 parent 3ba52d6075
commit bff03ecce5
4 files changed
+304 -39

No files matched your search

+18
View File
@@ -3695,6 +3695,23 @@ impl Session {
world_state: Arc<WorldState>,
) -> u64 {
let turn_context = step_context.turn.as_ref();
let retained_client_developer_messages =
if self.enabled(Feature::RetainClientDeveloperMessages) {
let history = self.clone_history().await;
crate::compact_remote_v2::truncate_retained_messages_for_remote_compaction(
history
.annotated_items()
.iter()
.filter(|item| {
crate::compact_remote_v2::is_client_authored_developer_message(item)
})
.cloned()
.collect(),
crate::compact_remote_v2::RETAINED_MESSAGE_TOKEN_BUDGET,
)
} else {
Vec::new()
};
let window = {
let mut state = self.state.lock().await;
state.start_new_context_window()
@@ -3705,6 +3722,7 @@ impl Session {
.await
.into_iter()
.map(ResponseItemEnvelope::new)
.chain(retained_client_developer_messages)
.collect();
let turn_context_item = turn_context.to_turn_context_item();
self.replace_compacted_history(