Track model and personality in world state (#35530)

## What changed

- Add model and personality sections to the persisted world-state snapshot.
- Generate model-switch and personality instructions through world-state diffs, including when prior state must be inferred during replay.
- Keep those instruction fragments in standalone developer messages instead of merging them with adjacent context updates.

## Testing

- Cover initial, unchanged, and changed model and personality states.
- Verify that model changes are recorded in rollout world-state items.

GitOrigin-RevId: 497e29cf38cac08e992e546df900f6f8b01120f9
This commit is contained in:
sayan-oai
2026-07-26 23:36:33 +00:00
committed by copyberry
parent 0896bf6fc0
commit 18f50c9e62
13 changed files with 421 additions and 148 deletions
@@ -20,6 +20,8 @@ use codex_protocol::openai_models::default_input_modalities;
use codex_protocol::protocol::AskForApproval;
use codex_protocol::protocol::EventMsg;
use codex_protocol::protocol::Op;
use codex_protocol::protocol::RolloutItem;
use codex_protocol::protocol::RolloutLine;
use codex_protocol::user_input::UserInput;
use core_test_support::responses::ev_completed_with_tokens;
use core_test_support::responses::ev_image_generation_call;
@@ -179,6 +181,31 @@ async fn model_change_appends_model_instructions_developer_message() -> Result<(
"expected model switch preamble, got: {model_switch_text:?}"
);
test.codex.ensure_rollout_materialized().await;
test.codex.flush_rollout().await?;
let rollout_path = test.codex.rollout_path().expect("rollout path");
let model_states = std::fs::read_to_string(rollout_path)?
.lines()
.map(serde_json::from_str::<RolloutLine>)
.collect::<serde_json::Result<Vec<_>>>()?
.into_iter()
.filter_map(|line| match line.item {
RolloutItem::WorldState(item) => item
.state
.get("model")
.and_then(serde_json::Value::as_str)
.map(str::to_string),
_ => None,
})
.collect::<Vec<_>>();
assert_eq!(
model_states,
vec![
test.session_configured.model.clone(),
next_model.to_string()
]
);
Ok(())
}