inline model instructions in initial context

This commit is contained in:
pakrym-oai
2026-06-20 23:29:49 -07:00
parent aaf737fa59
commit f6f0b8efca
67 changed files with 654 additions and 257 deletions
+38 -5
View File
@@ -58,8 +58,34 @@ pub fn format_request_input_snapshot(
request: &ResponsesRequest,
options: &ContextSnapshotOptions,
) -> String {
let items = request.input();
format_response_items_snapshot(items.as_slice(), options)
let mut items = request.input();
let has_top_level_instructions = request
.body_json()
.get("instructions")
.and_then(Value::as_str)
.is_some();
// Inline model instructions can be large and vary by model. Keep their position visible while
// normalizing the text to a stable, compact placeholder.
if !has_top_level_instructions
&& let Some(text) = items
.iter_mut()
.find(|item| {
item.get("type").and_then(Value::as_str) == Some("message")
&& item.get("role").and_then(Value::as_str) == Some("developer")
})
.and_then(|item| item.get_mut("content"))
.and_then(Value::as_array_mut)
.and_then(|content| content.first_mut())
.and_then(|entry| entry.get_mut("text"))
{
*text = Value::String("<MODEL_INSTRUCTIONS>".to_string());
}
let input = format_response_items_snapshot(items.as_slice(), options);
if has_top_level_instructions {
format!("instructions:<MODEL_INSTRUCTIONS>\n{input}")
} else {
input
}
}
pub fn format_response_items_snapshot(items: &[Value], options: &ContextSnapshotOptions) -> String {
@@ -422,7 +448,7 @@ fn canonicalize_snapshot_text(text: &str) -> String {
{
return format!("<COMPACTION_SUMMARY>\n{summary}");
}
normalize_dynamic_snapshot_paths(text)
normalize_dynamic_snapshot_text(text)
}
fn is_capability_instruction_text(text: &str) -> bool {
@@ -431,14 +457,21 @@ fn is_capability_instruction_text(text: &str) -> bool {
|| text.starts_with(PLUGINS_INSTRUCTIONS_OPEN_TAG)
}
fn normalize_dynamic_snapshot_paths(text: &str) -> String {
fn normalize_dynamic_snapshot_text(text: &str) -> String {
static SYSTEM_SKILL_PATH_RE: OnceLock<Regex> = OnceLock::new();
static WALL_TIME_RE: OnceLock<Regex> = OnceLock::new();
let system_skill_path_re = SYSTEM_SKILL_PATH_RE.get_or_init(|| {
Regex::new(r"/[^)\n]*/skills/\.system/([^/\n]+)/SKILL\.md")
.expect("system skill path regex should compile")
});
system_skill_path_re
let text = system_skill_path_re
.replace_all(text, "<SYSTEM_SKILLS_ROOT>/$1/SKILL.md")
.into_owned();
let wall_time_re = WALL_TIME_RE.get_or_init(|| {
Regex::new(r"Wall time: [0-9.]+ seconds").expect("wall time regex should compile")
});
wall_time_re
.replace_all(&text, "Wall time: <DURATION>")
.into_owned()
}
+3 -3
View File
@@ -201,9 +201,9 @@ async fn remote_model_override_uses_catalog_model_for_strict_auto_review() -> Re
.into_iter()
.find(|request| {
request.body_contains_text("auto-review-model-override.txt")
&& request
.instructions_text()
.starts_with("You are judging one planned coding-agent action.")
&& request.message_input_texts("developer").iter().any(|text| {
text.starts_with("You are judging one planned coding-agent action.")
})
})
.expect("expected Guardian request for apply_patch");
assert_eq!(
+3 -13
View File
@@ -344,14 +344,9 @@ async fn exec_cli_applies_model_instructions_file() {
assert!(output.status.success());
// Inspect the captured request and verify our custom base instructions were
// included in the `instructions` field.
// included in developer input.
let request = resp_mock.single_request();
let body = request.body_json();
let instructions = body
.get("instructions")
.and_then(|v| v.as_str())
.unwrap_or_default()
.to_string();
let instructions = request.message_input_texts("developer").join("\n\n");
assert!(
instructions.contains(marker),
"instructions did not contain custom marker; got: {instructions}"
@@ -414,12 +409,7 @@ async fn exec_cli_profile_applies_model_instructions_file() {
assert!(output.status.success());
let request = resp_mock.single_request();
let body = request.body_json();
let instructions = body
.get("instructions")
.and_then(|v| v.as_str())
.unwrap_or_default()
.to_string();
let instructions = request.message_input_texts("developer").join("\n\n");
assert!(
instructions.contains(marker),
"instructions did not contain profile marker; got: {instructions}"
+19 -24
View File
@@ -1199,7 +1199,7 @@ async fn send_provider_auth_request(server: &MockServer, auth: ModelProviderAuth
}
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn includes_base_instructions_override_in_request() {
async fn inlines_base_instructions_override_in_request() {
skip_if_no_network!();
// Mock server
let server = MockServer::start().await;
@@ -1238,12 +1238,14 @@ async fn includes_base_instructions_override_in_request() {
let request = resp_mock.single_request();
let request_body = request.body_json();
let developer_messages = request.message_input_texts("developer");
assert!(request_body.get("instructions").is_none());
assert!(
request_body["instructions"]
.as_str()
.unwrap()
.contains("test instructions")
developer_messages
.iter()
.any(|text| text.contains("test instructions")),
"expected base instructions in developer input, got {developer_messages:?}"
);
}
@@ -1464,16 +1466,13 @@ async fn includes_user_instructions_message_in_request() {
let request = resp_mock.single_request();
let request_body = request.body_json();
assert!(
!request_body["instructions"]
.as_str()
.unwrap()
.contains("be nice")
);
assert!(request_body.get("instructions").is_none());
assert_message_role(&request_body["input"][0], "developer");
let permissions_text = request_body["input"][0]["content"][0]["text"]
.as_str()
.expect("invalid permissions message content");
let developer_texts = request.message_input_texts("developer");
let permissions_text = developer_texts
.iter()
.find(|text| text.contains("`sandbox_mode`"))
.expect("permissions message content");
assert!(
permissions_text.contains("`sandbox_mode`"),
"expected permissions message to mention sandbox_mode, got {permissions_text:?}"
@@ -2650,17 +2649,13 @@ async fn includes_developer_instructions_message_in_request() {
let request = resp_mock.single_request();
let request_body = request.body_json();
let permissions_text = request_body["input"][0]["content"][0]["text"]
.as_str()
.expect("invalid permissions message content");
assert!(
!request_body["instructions"]
.as_str()
.unwrap()
.contains("be nice")
);
assert!(request_body.get("instructions").is_none());
assert_message_role(&request_body["input"][0], "developer");
let developer_texts = request.message_input_texts("developer");
let permissions_text = developer_texts
.iter()
.find(|text| text.contains("`sandbox_mode`"))
.expect("permissions message content");
assert!(
permissions_text.contains("`sandbox_mode`"),
"expected permissions message to mention sandbox_mode, got {permissions_text:?}"
@@ -2081,9 +2081,9 @@ fn prompt_with_input(input: Vec<ResponseItem>) -> Prompt {
fn prompt_with_input_and_instructions(input: Vec<ResponseItem>, instructions: &str) -> Prompt {
let mut prompt = prompt_with_input(input);
prompt.base_instructions = BaseInstructions {
prompt.base_instructions = Some(BaseInstructions {
text: instructions.to_string(),
};
});
prompt
}
+24 -25
View File
@@ -547,11 +547,13 @@ async fn summarize_context_three_requests_and_instructions() {
let body3 = requests[2].body_json();
// Manual compact should keep the baseline developer instructions.
let instr1 = body1.get("instructions").and_then(|v| v.as_str()).unwrap();
let instr2 = body2.get("instructions").and_then(|v| v.as_str()).unwrap();
assert_eq!(
instr1, instr2,
"manual compact should keep the standard developer instructions"
assert!(body1.get("instructions").is_none());
assert!(body2.get("instructions").is_none());
let developer_texts1 = requests[0].message_input_texts("developer");
let developer_texts2 = requests[1].message_input_texts("developer");
assert!(
developer_texts2.starts_with(&developer_texts1),
"manual compact should keep the standard developer instructions: {developer_texts2:?}"
);
// The summarization request should include the injected user input marker.
@@ -1206,18 +1208,20 @@ async fn multiple_auto_compact_per_task_runs_after_token_limit_hit() {
return None;
}
let text = value
.get("content")
.and_then(|content| content.as_array())
.and_then(|content| content.first())
.and_then(|item| item.get("text"))
.and_then(|text| text.as_str());
// Ignore cached prefix messages (project docs + permissions) since they are not
// relevant to compaction behavior and can change as bundled prompts evolve.
let role = value.get("role").and_then(|role| role.as_str());
if role == Some("developer")
&& text.is_some_and(|text| text.contains("`sandbox_mode`"))
&& value
.get("content")
.and_then(|content| content.as_array())
.is_some_and(|content| {
content.iter().any(|item| {
item.get("text")
.and_then(|text| text.as_str())
.is_some_and(|text| text.contains("`sandbox_mode`"))
})
})
{
return None;
}
@@ -1713,18 +1717,13 @@ async fn auto_compact_runs_after_token_limit_hit() {
let body_first = requests[0].body_json();
let body_auto = requests[auto_compact_index].body_json();
let body_follow_up = requests[follow_up_index].body_json();
let instructions = body_auto
.get("instructions")
.and_then(|v| v.as_str())
.unwrap_or_default();
let baseline_instructions = body_first
.get("instructions")
.and_then(|v| v.as_str())
.unwrap_or_default()
.to_string();
assert_eq!(
instructions, baseline_instructions,
"auto compact should keep the standard developer instructions",
assert!(body_first.get("instructions").is_none());
assert!(body_auto.get("instructions").is_none());
let baseline_developer_texts = requests[0].message_input_texts("developer");
let auto_developer_texts = requests[auto_compact_index].message_input_texts("developer");
assert!(
auto_developer_texts.starts_with(&baseline_developer_texts),
"auto compact should keep the standard developer instructions: {auto_developer_texts:?}",
);
let input_auto = body_auto.get("input").and_then(|v| v.as_array()).unwrap();
+33 -9
View File
@@ -61,8 +61,12 @@ fn estimate_compact_input_tokens(request: &responses::ResponsesRequest) -> i64 {
}
fn estimate_compact_payload_tokens(request: &responses::ResponsesRequest) -> i64 {
estimate_compact_input_tokens(request)
.saturating_add(approx_token_count(&request.instructions_text()))
let body = request.body_json();
let instructions = body
.get("instructions")
.and_then(Value::as_str)
.unwrap_or_default();
estimate_compact_input_tokens(request).saturating_add(approx_token_count(instructions))
}
fn assert_tools_payload_does_not_defer(body: &Value) {
@@ -1986,7 +1990,17 @@ async fn remote_compact_trim_estimate_uses_session_base_instructions() -> Result
}),
)
.await?;
let baseline_codex = baseline_harness.test().codex.clone();
let baseline_test = baseline_harness.test();
let baseline_base_instructions = baseline_test
.thread_manager
.get_models_manager()
.get_model_info(
&baseline_test.session_configured.model,
&baseline_test.config.to_models_manager_config(),
)
.await
.base_instructions;
let baseline_codex = baseline_test.codex.clone();
responses::mount_sse_sequence(
baseline_harness.server(),
@@ -2071,12 +2085,13 @@ async fn remote_compact_trim_estimate_uses_session_base_instructions() -> Result
let override_base_instructions = format!(
"{}\nREMOTE_BASE_INSTRUCTIONS_OVERRIDE {}",
baseline_compact_request.instructions_text(),
baseline_base_instructions,
"x".repeat(8_000)
);
let override_context_window = baseline_payload_tokens.saturating_add(500);
let pretrim_override_estimate =
baseline_input_tokens.saturating_add(approx_token_count(&override_base_instructions));
let pretrim_override_estimate = baseline_input_tokens
.saturating_sub(approx_token_count(&baseline_base_instructions))
.saturating_add(approx_token_count(&override_base_instructions));
assert!(
pretrim_override_estimate > override_context_window,
"expected override instructions to push pre-trim estimate past the context window"
@@ -2165,9 +2180,18 @@ async fn remote_compact_trim_estimate_uses_session_base_instructions() -> Result
.await;
let override_compact_request = override_compact_mock.single_request();
assert_eq!(
override_compact_request.instructions_text(),
override_base_instructions
assert!(
override_compact_request
.body_json()
.get("instructions")
.is_none()
);
let override_developer_texts = override_compact_request.message_input_texts("developer");
assert!(
override_developer_texts
.iter()
.any(|text| text.contains(&override_base_instructions)),
"expected override instructions in developer input, got {override_developer_texts:?}"
);
assert!(
override_compact_request.has_function_call(override_retained_call_id),
@@ -317,8 +317,9 @@ async fn apps_default_prompt_with_auto_review_routes_actual_mcp_approval_to_guar
.into_iter()
.find(|request| {
request
.instructions_text()
.starts_with("You are judging one planned coding-agent action.")
.message_input_texts("developer")
.iter()
.any(|text| text.starts_with("You are judging one planned coding-agent action."))
})
.expect("expected a Guardian request for the app MCP approval");
assert!(guardian_request.body_contains_text("calendar_create_event"));
@@ -6,9 +6,12 @@ use anyhow::Result;
use codex_config::types::Personality;
use codex_features::Feature;
use codex_protocol::models::PermissionProfile;
use codex_protocol::models::ResponseItem;
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::PathBufExt;
use core_test_support::context_snapshot;
@@ -374,6 +377,40 @@ async fn snapshot_model_visible_layout_resume_with_personality_change() -> Resul
wait_for_event(&codex, |event| matches!(event, EventMsg::TurnComplete(_))).await;
let initial_request = initial_mock.single_request();
// Rewrite the seed turn into the legacy representation: no persisted compatibility flag and
// no model instructions in history. The resumed request should therefore use the top-level
// `instructions` field.
let mut removed_inline_instructions = false;
let mut found_turn_context = false;
let legacy_rollout = fs::read_to_string(&rollout_path)?
.lines()
.map(|line| -> Result<String> {
let mut line: RolloutLine = serde_json::from_str(line)?;
match &mut line.item {
RolloutItem::TurnContext(turn_context) => {
turn_context.inline_instructions = false;
found_turn_context = true;
}
RolloutItem::ResponseItem(ResponseItem::Message { role, content, .. })
if role == "developer" && !removed_inline_instructions =>
{
assert!(!content.is_empty(), "developer message should have content");
content.remove(0);
removed_inline_instructions = true;
}
_ => {}
}
Ok(serde_json::to_string(&line)?)
})
.collect::<Result<Vec<_>>>()?
.join("\n");
assert!(found_turn_context, "rollout should contain a turn context");
assert!(
removed_inline_instructions,
"rollout should contain inline model instructions"
);
fs::write(&rollout_path, format!("{legacy_rollout}\n"))?;
let resumed_mock = mount_sse_once(
&server,
sse(vec![
@@ -437,7 +474,7 @@ async fn snapshot_model_visible_layout_resume_with_personality_change() -> Resul
insta::assert_snapshot!(
"model_visible_layout_resume_with_personality_change",
format_labeled_requests_snapshot(
"First post-resume turn where resumed config model differs from rollout and personality changes.",
"First post-legacy-resume turn where resumed config model differs from rollout and personality changes.",
&[
("Last Request Before Resume", &initial_request),
("First Request After Resume", &resumed_request),
+4 -4
View File
@@ -194,7 +194,7 @@ async fn config_personality_some_sets_instructions_template() -> anyhow::Result<
wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await;
let request = resp_mock.single_request();
let instructions_text = request.instructions_text();
let instructions_text = request.message_input_texts("developer").join("\n\n");
assert!(
instructions_text.contains(LOCAL_FRIENDLY_TEMPLATE),
@@ -241,7 +241,7 @@ async fn config_personality_none_sends_no_personality() -> anyhow::Result<()> {
wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await;
let request = resp_mock.single_request();
let instructions_text = request.instructions_text();
let instructions_text = request.message_input_texts("developer").join("\n\n");
assert!(
!instructions_text.contains(LOCAL_FRIENDLY_TEMPLATE),
"expected no friendly personality template, got: {instructions_text:?}"
@@ -294,7 +294,7 @@ async fn default_personality_is_pragmatic_without_config_toml() -> anyhow::Resul
wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await;
let request = resp_mock.single_request();
let instructions_text = request.instructions_text();
let instructions_text = request.message_input_texts("developer").join("\n\n");
assert!(
instructions_text.contains(LOCAL_PRAGMATIC_TEMPLATE),
"expected default friendly template, got: {instructions_text:?}"
@@ -636,7 +636,7 @@ async fn remote_model_friendly_personality_instructions_with_feature() -> anyhow
wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await;
let request = resp_mock.single_request();
let instructions_text = request.instructions_text();
let instructions_text = request.message_input_texts("developer").join("\n\n");
assert!(
instructions_text.contains(friendly_personality_message),
+31 -24
View File
@@ -110,7 +110,6 @@ fn normalize_newlines(text: &str) -> String {
#[tokio::test(flavor = "multi_thread", worker_threads = 4)]
async fn prompt_tools_are_consistent_across_requests() -> anyhow::Result<()> {
skip_if_no_network!(Ok(()));
use pretty_assertions::assert_eq;
let server = start_mock_server().await;
let req1 = mount_sse_once(
@@ -198,7 +197,8 @@ async fn prompt_tools_are_consistent_across_requests() -> anyhow::Result<()> {
"tool_search",
"web_search",
]);
let body0 = req1.single_request().body_json();
let request0 = req1.single_request();
let body0 = request0.body_json();
let expected_instructions = if expected_tools_names.contains(&"apply_patch") {
base_instructions
@@ -206,16 +206,25 @@ async fn prompt_tools_are_consistent_across_requests() -> anyhow::Result<()> {
[base_instructions, APPLY_PATCH_TOOL_INSTRUCTIONS.to_string()].join("\n")
};
assert_eq!(
body0["instructions"],
serde_json::json!(expected_instructions),
assert!(body0.get("instructions").is_none());
let developer_texts0 = request0.message_input_texts("developer");
assert!(
developer_texts0
.iter()
.any(|text| text.starts_with(&expected_instructions)),
"expected model instructions in developer input, got {developer_texts0:?}"
);
assert_tool_names(&body0, &expected_tools_names);
let body1 = req2.single_request().body_json();
assert_eq!(
body1["instructions"],
serde_json::json!(expected_instructions),
let request1 = req2.single_request();
let body1 = request1.body_json();
assert!(body1.get("instructions").is_none());
let developer_texts1 = request1.message_input_texts("developer");
assert!(
developer_texts1
.iter()
.any(|text| text.starts_with(&expected_instructions)),
"expected model instructions in developer input, got {developer_texts1:?}"
);
assert_tool_names(&body1, &expected_tools_names);
@@ -280,19 +289,19 @@ async fn gpt_5_tools_without_apply_patch_append_apply_patch_instructions() -> an
wait_for_event(&codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await;
let body0 = req1.single_request().body_json();
let instructions0 = body0["instructions"]
.as_str()
.expect("instructions should be a string");
let request0 = req1.single_request();
assert!(request0.body_json().get("instructions").is_none());
let developer_texts0 = request0.message_input_texts("developer");
let instructions0 = developer_texts0.first().expect("developer instructions");
assert!(
instructions0.contains("You are"),
"expected non-empty instructions"
);
let body1 = req2.single_request().body_json();
let instructions1 = body1["instructions"]
.as_str()
.expect("instructions should be a string");
let request1 = req2.single_request();
assert!(request1.body_json().get("instructions").is_none());
let developer_texts1 = request1.message_input_texts("developer");
let instructions1 = developer_texts1.first().expect("developer instructions");
assert_eq!(
normalize_newlines(instructions1),
normalize_newlines(instructions0)
@@ -647,15 +656,13 @@ async fn override_before_first_turn_emits_environment_context() -> anyhow::Resul
let permissions_texts: Vec<&str> = input
.iter()
.filter_map(|msg| {
let role = msg["role"].as_str()?;
if role != "developer" {
return None;
}
.filter(|msg| msg["role"].as_str() == Some("developer"))
.flat_map(|msg| {
msg["content"]
.as_array()
.and_then(|content| content.first())
.and_then(|item| item["text"].as_str())
.into_iter()
.flatten()
.filter_map(|item| item["text"].as_str())
})
.collect();
assert!(
+9 -3
View File
@@ -826,9 +826,15 @@ async fn remote_models_apply_remote_base_instructions() -> Result<()> {
let base_model_info = models_manager
.get_model_info("gpt-5.2", &config.to_models_manager_config())
.await;
let body = response_mock.single_request().body_json();
let instructions = body["instructions"].as_str().unwrap();
assert_eq!(instructions, base_model_info.base_instructions);
let request = response_mock.single_request();
assert!(request.body_json().get("instructions").is_none());
let developer_texts = request.message_input_texts("developer");
assert!(
developer_texts
.iter()
.any(|text| text.contains(&base_model_info.base_instructions)),
"expected model instructions in developer input, got {developer_texts:?}"
);
Ok(())
}
+7 -8
View File
@@ -274,12 +274,9 @@ async fn resume_switches_models_preserves_base_instructions() -> Result<()> {
.await?;
wait_for_event(&codex, |event| matches!(event, EventMsg::TurnComplete(_))).await;
let initial_body = initial_mock.single_request().body_json();
let initial_instructions = initial_body
.get("instructions")
.and_then(|v| v.as_str())
.unwrap_or_default()
.to_string();
let initial_request = initial_mock.single_request();
assert!(initial_request.body_json().get("instructions").is_none());
let initial_developer_texts = initial_request.message_input_texts("developer");
let resumed_mock = mount_sse_sequence(
&server,
@@ -342,8 +339,9 @@ async fn resume_switches_models_preserves_base_instructions() -> Result<()> {
assert_eq!(requests.len(), 2, "expected two resumed requests");
let first_resumed = &requests[0];
assert_eq!(first_resumed.instructions_text(), initial_instructions);
assert!(first_resumed.body_json().get("instructions").is_none());
let first_developer_texts = first_resumed.message_input_texts("developer");
assert!(first_developer_texts.starts_with(&initial_developer_texts));
let first_model_switch_count = first_developer_texts
.iter()
.filter(|text| text.contains("<model_switch>"))
@@ -354,8 +352,9 @@ async fn resume_switches_models_preserves_base_instructions() -> Result<()> {
);
let second_resumed = &requests[1];
assert_eq!(second_resumed.instructions_text(), initial_instructions);
assert!(second_resumed.body_json().get("instructions").is_none());
let second_developer_texts = second_resumed.message_input_texts("developer");
assert!(second_developer_texts.starts_with(&initial_developer_texts));
let second_model_switch_count = second_developer_texts
.iter()
.filter(|text| text.contains("<model_switch>"))
@@ -27,6 +27,7 @@ fn resume_history(
let turn_id = "resume-warning-seed-turn".to_string();
let turn_ctx = TurnContextItem {
turn_id: Some(turn_id.clone()),
inline_instructions: false,
cwd: config.cwd.clone(),
workspace_roots: None,
current_date: None,
+9 -3
View File
@@ -627,9 +627,15 @@ async fn review_input_isolated_from_parent_history() {
"user message should only contain the raw review prompt"
);
// Ensure the REVIEW_PROMPT rubric is sent via instructions.
let instructions = body["instructions"].as_str().expect("instructions string");
assert_eq!(instructions, REVIEW_PROMPT);
// Ensure the REVIEW_PROMPT rubric is sent via developer input.
assert!(body.get("instructions").is_none());
let developer_texts = request.message_input_texts("developer");
assert!(
developer_texts
.iter()
.any(|text| text.contains(REVIEW_PROMPT)),
"expected review instructions in developer input, got {developer_texts:?}"
);
// Also verify that a user interruption note was recorded in the rollout.
let path = codex.rollout_path().expect("rollout path");
@@ -1,11 +1,13 @@
---
source: core/tests/suite/additional_context.rs
expression: "context_snapshot::format_labeled_requests_snapshot(\"additional context is inserted before the user turn input.\",\n&[(\"Request\", &request)], &additional_context_snapshot_options(),)"
expression: "context_snapshot::format_labeled_requests_snapshot(\"additional context is inserted before the user turn input.\",\n&[(\"Request\", &request)],\n&ContextSnapshotOptions::default().strip_capability_instructions().render_mode(ContextSnapshotRenderMode::KindWithTextPrefix\n{ max_chars: 160 }),)"
---
Scenario: additional context is inserted before the user turn input.
## Request
00:message/developer:<PERMISSIONS_INSTRUCTIONS>
00:message/developer[2]:
[01] <MODEL_INSTRUCTIONS>
[02] <PERMISSIONS_INSTRUCTIONS>
01:message/developer:<automation_info>run one</automation_info>
02:message/user:<external_browser_info>tab one</external_browser_info>
03:message/user:inspect the active tab
@@ -5,7 +5,9 @@ expression: "format_labeled_requests_snapshot(\"Manual /compact with prior user
Scenario: Manual /compact with prior user history compacts existing history and the follow-up turn includes the compact summary plus new user message.
## Local Compaction Request
00:message/developer:<PERMISSIONS_INSTRUCTIONS>
00:message/developer[2]:
[01] <MODEL_INSTRUCTIONS>
[02] <PERMISSIONS_INSTRUCTIONS>
01:message/user:<ENVIRONMENT_CONTEXT:cwd=<CWD>>
02:message/user:first manual turn
03:message/assistant:FIRST_REPLY
@@ -14,6 +16,8 @@ Scenario: Manual /compact with prior user history compacts existing history and
## Local Post-Compaction History Layout
00:message/user:first manual turn
01:message/user:<COMPACTION_SUMMARY>\nFIRST_MANUAL_SUMMARY
02:message/developer:<PERMISSIONS_INSTRUCTIONS>
02:message/developer[2]:
[01] <MODEL_INSTRUCTIONS>
[02] <PERMISSIONS_INSTRUCTIONS>
03:message/user:<ENVIRONMENT_CONTEXT:cwd=<CWD>>
04:message/user:second manual turn
@@ -9,6 +9,8 @@ Scenario: Manual /compact with no prior user turn currently still issues a compa
## Local Post-Compaction History Layout
00:message/user:<COMPACTION_SUMMARY>\nMANUAL_EMPTY_SUMMARY
01:message/developer:<PERMISSIONS_INSTRUCTIONS>
01:message/developer[2]:
[01] <MODEL_INSTRUCTIONS>
[02] <PERMISSIONS_INSTRUCTIONS>
02:message/user:<ENVIRONMENT_CONTEXT:cwd=<CWD>>
03:message/user:AFTER_MANUAL_EMPTY_COMPACT
@@ -5,7 +5,9 @@ expression: "format_labeled_requests_snapshot(\"True mid-turn continuation compa
Scenario: True mid-turn continuation compaction after tool output: compact request includes tool artifacts, and the continuation request includes the summary in the same turn.
## Local Compaction Request
00:message/developer:<PERMISSIONS_INSTRUCTIONS>
00:message/developer[2]:
[01] <MODEL_INSTRUCTIONS>
[02] <PERMISSIONS_INSTRUCTIONS>
01:message/user:<ENVIRONMENT_CONTEXT:cwd=<CWD>>
02:message/user:function call limit push
03:function_call/test_tool
@@ -13,7 +15,9 @@ Scenario: True mid-turn continuation compaction after tool output: compact reque
05:message/user:<SUMMARIZATION_PROMPT>
## Local Post-Compaction History Layout
00:message/developer:<PERMISSIONS_INSTRUCTIONS>
00:message/developer[2]:
[01] <MODEL_INSTRUCTIONS>
[02] <PERMISSIONS_INSTRUCTIONS>
01:message/user:<ENVIRONMENT_CONTEXT:cwd=<CWD>>
02:message/user:function call limit push
03:message/user:<COMPACTION_SUMMARY>\nAUTO_SUMMARY
@@ -5,12 +5,16 @@ expression: "format_labeled_requests_snapshot(\"Pre-sampling compaction on model
Scenario: Pre-sampling compaction on model switch to a smaller context window: current behavior compacts using prior-turn history only (incoming user message excluded), and the follow-up request carries compacted history plus the new user message.
## Initial Request (Previous Model)
00:message/developer:<PERMISSIONS_INSTRUCTIONS>
00:message/developer[2]:
[01] <MODEL_INSTRUCTIONS>
[02] <PERMISSIONS_INSTRUCTIONS>
01:message/user:<ENVIRONMENT_CONTEXT:cwd=<CWD>>
02:message/user:before switch
## Pre-sampling Compaction Request
00:message/developer:<PERMISSIONS_INSTRUCTIONS>
00:message/developer[2]:
[01] <MODEL_INSTRUCTIONS>
[02] <PERMISSIONS_INSTRUCTIONS>
01:message/user:<ENVIRONMENT_CONTEXT:cwd=<CWD>>
02:message/user:before switch
03:message/assistant:before switch
@@ -19,8 +23,9 @@ Scenario: Pre-sampling compaction on model switch to a smaller context window: c
## Post-Compaction Follow-up Request (Next Model)
00:message/user:before switch
01:message/user:<COMPACTION_SUMMARY>\nPRE_SAMPLING_SUMMARY
02:message/developer[2]:
[01] <model_switch>\nThe user was previously using a different model....
[02] <PERMISSIONS_INSTRUCTIONS>
02:message/developer[3]:
[01] <MODEL_INSTRUCTIONS>
[02] <model_switch>\nThe user was previously using a different model....
[03] <PERMISSIONS_INSTRUCTIONS>
03:message/user:<ENVIRONMENT_CONTEXT:cwd=<CWD>>
04:message/user:after switch
@@ -5,7 +5,9 @@ expression: "format_labeled_requests_snapshot(\"Pre-turn auto-compaction context
Scenario: Pre-turn auto-compaction context-window failure: compaction request excludes the incoming user message and the turn errors.
## Local Compaction Request (Incoming User Excluded)
00:message/developer:<PERMISSIONS_INSTRUCTIONS>
00:message/developer[2]:
[01] <MODEL_INSTRUCTIONS>
[02] <PERMISSIONS_INSTRUCTIONS>
01:message/user:<ENVIRONMENT_CONTEXT:cwd=<CWD>>
02:message/user:USER_ONE
03:message/assistant:FIRST_REPLY
@@ -5,7 +5,9 @@ expression: "format_labeled_requests_snapshot(\"Pre-turn auto-compaction with a
Scenario: Pre-turn auto-compaction with a context override emits the context diff in the compact request while the incoming user message is still excluded.
## Local Compaction Request
00:message/developer:<PERMISSIONS_INSTRUCTIONS>
00:message/developer[2]:
[01] <MODEL_INSTRUCTIONS>
[02] <PERMISSIONS_INSTRUCTIONS>
01:message/user:<ENVIRONMENT_CONTEXT:cwd=<CWD>>
02:message/user:USER_ONE
03:message/assistant:FIRST_REPLY
@@ -17,7 +19,9 @@ Scenario: Pre-turn auto-compaction with a context override emits the context dif
00:message/user:USER_ONE
01:message/user:USER_TWO
02:message/user:<COMPACTION_SUMMARY>\nPRE_TURN_SUMMARY
03:message/developer:<PERMISSIONS_INSTRUCTIONS>
03:message/developer[2]:
[01] <MODEL_INSTRUCTIONS>
[02] <PERMISSIONS_INSTRUCTIONS>
04:message/user:<ENVIRONMENT_CONTEXT:cwd=PRETURN_CONTEXT_DIFF_CWD>
05:message/user[2]:
[01] <input_image:detail,image_url>
@@ -5,12 +5,16 @@ expression: "format_labeled_requests_snapshot(\"Pre-turn compaction during model
Scenario: Pre-turn compaction during model switch (without pre-sampling model-switch compaction): current behavior strips incoming <model_switch> from the compact request and restores it in the post-compaction follow-up request.
## Initial Request (Previous Model)
00:message/developer:<PERMISSIONS_INSTRUCTIONS>
00:message/developer[2]:
[01] <MODEL_INSTRUCTIONS>
[02] <PERMISSIONS_INSTRUCTIONS>
01:message/user:<ENVIRONMENT_CONTEXT:cwd=<CWD>>
02:message/user:BEFORE_SWITCH_USER
## Local Compaction Request
00:message/developer:<PERMISSIONS_INSTRUCTIONS>
00:message/developer[2]:
[01] <MODEL_INSTRUCTIONS>
[02] <PERMISSIONS_INSTRUCTIONS>
01:message/user:<ENVIRONMENT_CONTEXT:cwd=<CWD>>
02:message/user:BEFORE_SWITCH_USER
03:message/assistant:BEFORE_SWITCH_REPLY
@@ -19,9 +23,10 @@ Scenario: Pre-turn compaction during model switch (without pre-sampling model-sw
## Local Post-Compaction History Layout
00:message/user:BEFORE_SWITCH_USER
01:message/user:<COMPACTION_SUMMARY>\nPRETURN_SWITCH_SUMMARY
02:message/developer[3]:
[01] <model_switch>\nThe user was previously using a different model....
[02] <PERMISSIONS_INSTRUCTIONS>
[03] <personality_spec> The user has requested a new communication st...
02:message/developer[4]:
[01] <MODEL_INSTRUCTIONS>
[02] <model_switch>\nThe user was previously using a different model....
[03] <PERMISSIONS_INSTRUCTIONS>
[04] <personality_spec> The user has requested a new communication st...
03:message/user:<ENVIRONMENT_CONTEXT:cwd=<CWD>>
04:message/user:AFTER_SWITCH_USER
@@ -5,17 +5,19 @@ expression: "format_labeled_requests_snapshot(\"After remote manual /compact and
Scenario: After remote manual /compact and resume, the first resumed turn rebuilds history from the compaction item and restates realtime-end instructions from reconstructed previous-turn settings.
## Remote Compaction Request
00:message/developer[2]:
[01] <PERMISSIONS_INSTRUCTIONS>
[02] <realtime_conversation>\nRealtime conversation started.\n\nYou a...
00:message/developer[3]:
[01] <MODEL_INSTRUCTIONS>
[02] <PERMISSIONS_INSTRUCTIONS>
[03] <realtime_conversation>\nRealtime conversation started.\n\nYou a...
01:message/user:<ENVIRONMENT_CONTEXT:cwd=<CWD>>
02:message/user:USER_ONE
03:message/assistant:REMOTE_FIRST_REPLY
## Remote Post-Resume History Layout
00:compaction:encrypted=true
01:message/developer[2]:
[01] <PERMISSIONS_INSTRUCTIONS>
[02] <realtime_conversation>\nRealtime conversation ended.\n\nSubsequ...
01:message/developer[3]:
[01] <MODEL_INSTRUCTIONS>
[02] <PERMISSIONS_INSTRUCTIONS>
[03] <realtime_conversation>\nRealtime conversation ended.\n\nSubsequ...
02:message/user:<ENVIRONMENT_CONTEXT:cwd=<CWD>>
03:message/user:USER_TWO
@@ -5,17 +5,19 @@ expression: "format_labeled_requests_snapshot(\"Remote manual /compact while rea
Scenario: Remote manual /compact while realtime remains active: the next regular turn restates realtime-start instructions after compaction clears the baseline.
## Remote Compaction Request
00:message/developer[2]:
[01] <PERMISSIONS_INSTRUCTIONS>
[02] <realtime_conversation>\nRealtime conversation started.\n\nYou a...
00:message/developer[3]:
[01] <MODEL_INSTRUCTIONS>
[02] <PERMISSIONS_INSTRUCTIONS>
[03] <realtime_conversation>\nRealtime conversation started.\n\nYou a...
01:message/user:<ENVIRONMENT_CONTEXT:cwd=<CWD>>
02:message/user:USER_ONE
03:message/assistant:REMOTE_FIRST_REPLY
## Remote Post-Compaction History Layout
00:compaction:encrypted=true
01:message/developer[2]:
[01] <PERMISSIONS_INSTRUCTIONS>
[02] <realtime_conversation>\nRealtime conversation started.\n\nYou a...
01:message/developer[3]:
[01] <MODEL_INSTRUCTIONS>
[02] <PERMISSIONS_INSTRUCTIONS>
[03] <realtime_conversation>\nRealtime conversation started.\n\nYou a...
02:message/user:<ENVIRONMENT_CONTEXT:cwd=<CWD>>
03:message/user:USER_TWO
@@ -5,13 +5,17 @@ expression: "format_labeled_requests_snapshot(\"Remote manual /compact where rem
Scenario: Remote manual /compact where remote compact output is compaction-only: follow-up layout uses the returned compaction item plus new user message.
## Remote Compaction Request
00:message/developer:<PERMISSIONS_INSTRUCTIONS>
00:message/developer[2]:
[01] <MODEL_INSTRUCTIONS>
[02] <PERMISSIONS_INSTRUCTIONS>
01:message/user:<ENVIRONMENT_CONTEXT:cwd=<CWD>>
02:message/user:hello remote compact
03:message/assistant:FIRST_REMOTE_REPLY
## Remote Post-Compaction History Layout
00:compaction:encrypted=true
01:message/developer:<PERMISSIONS_INSTRUCTIONS>
01:message/developer[2]:
[01] <MODEL_INSTRUCTIONS>
[02] <PERMISSIONS_INSTRUCTIONS>
02:message/user:<ENVIRONMENT_CONTEXT:cwd=<CWD>>
03:message/user:after compact
@@ -5,6 +5,8 @@ expression: "format_labeled_requests_snapshot(\"Remote manual /compact with no p
Scenario: Remote manual /compact with no prior user turn skips the remote compact request; the follow-up turn carries canonical context and new user message.
## Remote Post-Compaction History Layout
00:message/developer:<PERMISSIONS_INSTRUCTIONS>
00:message/developer[2]:
[01] <MODEL_INSTRUCTIONS>
[02] <PERMISSIONS_INSTRUCTIONS>
01:message/user:<ENVIRONMENT_CONTEXT:cwd=<CWD>>
02:message/user:USER_ONE
@@ -5,9 +5,10 @@ expression: "format_labeled_requests_snapshot(\"Remote mid-turn continuation com
Scenario: Remote mid-turn continuation compaction after realtime was closed before the turn: the initial second-turn request emits realtime-end instructions, but the continuation request does not restate them after compaction because the current turn already established the inactive baseline.
## Second Turn Initial Request
00:message/developer[2]:
[01] <PERMISSIONS_INSTRUCTIONS>
[02] <realtime_conversation>\nRealtime conversation started.\n\nYou a...
00:message/developer[3]:
[01] <MODEL_INSTRUCTIONS>
[02] <PERMISSIONS_INSTRUCTIONS>
[03] <realtime_conversation>\nRealtime conversation started.\n\nYou a...
01:message/user:<ENVIRONMENT_CONTEXT:cwd=<CWD>>
02:message/user:SETUP_USER
03:message/assistant:REMOTE_SETUP_REPLY
@@ -15,9 +16,10 @@ Scenario: Remote mid-turn continuation compaction after realtime was closed befo
05:message/user:USER_TWO
## Remote Compaction Request
00:message/developer[2]:
[01] <PERMISSIONS_INSTRUCTIONS>
[02] <realtime_conversation>\nRealtime conversation started.\n\nYou a...
00:message/developer[3]:
[01] <MODEL_INSTRUCTIONS>
[02] <PERMISSIONS_INSTRUCTIONS>
[03] <realtime_conversation>\nRealtime conversation started.\n\nYou a...
01:message/user:<ENVIRONMENT_CONTEXT:cwd=<CWD>>
02:message/user:SETUP_USER
03:message/assistant:REMOTE_SETUP_REPLY
@@ -27,6 +29,8 @@ Scenario: Remote mid-turn continuation compaction after realtime was closed befo
07:function_call_output:unsupported call: test_tool
## Remote Post-Compaction History Layout
00:message/developer:<PERMISSIONS_INSTRUCTIONS>
00:message/developer[2]:
[01] <MODEL_INSTRUCTIONS>
[02] <PERMISSIONS_INSTRUCTIONS>
01:message/user:<ENVIRONMENT_CONTEXT:cwd=<CWD>>
02:compaction:encrypted=true
@@ -7,10 +7,19 @@ Scenario: After a prior manual /compact produced an older remote compaction item
## Remote Compaction Request
00:message/user:USER_ONE
01:compaction:encrypted=true
02:message/developer[2]:
[01] <MODEL_INSTRUCTIONS>
[02] <PERMISSIONS_INSTRUCTIONS>
03:message/user:<ENVIRONMENT_CONTEXT:cwd=<CWD>>
04:message/user:USER_TWO
05:function_call/shell_command
06:function_call_output:Exit code: 0\nWall time: <DURATION>\nOutput:\nmulti-summary\n
## Second Turn Request (After Compaction)
00:message/user:USER_ONE
01:compaction:encrypted=true
02:message/developer:<PERMISSIONS_INSTRUCTIONS>
02:message/developer[2]:
[01] <MODEL_INSTRUCTIONS>
[02] <PERMISSIONS_INSTRUCTIONS>
03:message/user:<ENVIRONMENT_CONTEXT:cwd=<CWD>>
04:message/user:USER_TWO
@@ -5,14 +5,18 @@ expression: "format_labeled_requests_snapshot(\"Remote mid-turn continuation com
Scenario: Remote mid-turn continuation compaction after tool output: compact request includes tool artifacts and the follow-up request includes the returned compaction item.
## Remote Compaction Request
00:message/developer:<PERMISSIONS_INSTRUCTIONS>
00:message/developer[2]:
[01] <MODEL_INSTRUCTIONS>
[02] <PERMISSIONS_INSTRUCTIONS>
01:message/user:<ENVIRONMENT_CONTEXT:cwd=<CWD>>
02:message/user:USER_ONE
03:function_call/test_tool
04:function_call_output:unsupported call: test_tool
## Remote Post-Compaction History Layout
00:message/developer:<PERMISSIONS_INSTRUCTIONS>
00:message/developer[2]:
[01] <MODEL_INSTRUCTIONS>
[02] <PERMISSIONS_INSTRUCTIONS>
01:message/user:<ENVIRONMENT_CONTEXT:cwd=<CWD>>
02:message/user:USER_ONE
03:compaction:encrypted=true
@@ -5,13 +5,17 @@ expression: "format_labeled_requests_snapshot(\"Remote mid-turn compaction where
Scenario: Remote mid-turn compaction where compact output has only a compaction item: continuation layout reinjects context before that compaction item.
## Remote Compaction Request
00:message/developer:<PERMISSIONS_INSTRUCTIONS>
00:message/developer[2]:
[01] <MODEL_INSTRUCTIONS>
[02] <PERMISSIONS_INSTRUCTIONS>
01:message/user:<ENVIRONMENT_CONTEXT:cwd=<CWD>>
02:message/user:USER_ONE
03:function_call/test_tool
04:function_call_output:unsupported call: test_tool
## Remote Post-Compaction History Layout
00:message/developer:<PERMISSIONS_INSTRUCTIONS>
00:message/developer[2]:
[01] <MODEL_INSTRUCTIONS>
[02] <PERMISSIONS_INSTRUCTIONS>
01:message/user:<ENVIRONMENT_CONTEXT:cwd=<CWD>>
02:compaction:encrypted=true
@@ -5,7 +5,9 @@ expression: "format_labeled_requests_snapshot(\"Remote pre-turn auto-compaction
Scenario: Remote pre-turn auto-compaction context-window failure: compaction request excludes the incoming user message and the turn errors.
## Remote Compaction Request (Incoming User Excluded)
00:message/developer:<PERMISSIONS_INSTRUCTIONS>
00:message/developer[2]:
[01] <MODEL_INSTRUCTIONS>
[02] <PERMISSIONS_INSTRUCTIONS>
01:message/user:<ENVIRONMENT_CONTEXT:cwd=<CWD>>
02:message/user:USER_ONE
03:message/assistant:REMOTE_FIRST_REPLY
@@ -5,7 +5,9 @@ expression: "format_labeled_requests_snapshot(\"Remote pre-turn auto-compaction
Scenario: Remote pre-turn auto-compaction parse failure: compaction request excludes the incoming user message and the turn stops.
## Remote Compaction Request (Incoming User Excluded)
00:message/developer:<PERMISSIONS_INSTRUCTIONS>
00:message/developer[2]:
[01] <MODEL_INSTRUCTIONS>
[02] <PERMISSIONS_INSTRUCTIONS>
01:message/user:<ENVIRONMENT_CONTEXT:cwd=<CWD>>
02:message/user:turn that exceeds token threshold
03:message/assistant:initial turn complete
@@ -5,7 +5,9 @@ expression: "format_labeled_requests_snapshot(\"Remote pre-turn auto-compaction
Scenario: Remote pre-turn auto-compaction with a context override emits the context diff in the compact request while excluding the incoming user message.
## Remote Compaction Request
00:message/developer:<PERMISSIONS_INSTRUCTIONS>
00:message/developer[2]:
[01] <MODEL_INSTRUCTIONS>
[02] <PERMISSIONS_INSTRUCTIONS>
01:message/user:<ENVIRONMENT_CONTEXT:cwd=<CWD>>
02:message/user:USER_ONE
03:message/assistant:REMOTE_FIRST_REPLY
@@ -16,6 +18,8 @@ Scenario: Remote pre-turn auto-compaction with a context override emits the cont
00:message/user:USER_ONE
01:message/user:USER_TWO
02:compaction:encrypted=true
03:message/developer:<PERMISSIONS_INSTRUCTIONS>
03:message/developer[2]:
[01] <MODEL_INSTRUCTIONS>
[02] <PERMISSIONS_INSTRUCTIONS>
04:message/user:<ENVIRONMENT_CONTEXT:cwd=PRETURN_CONTEXT_DIFF_CWD>
05:message/user:USER_THREE
@@ -5,17 +5,19 @@ expression: "format_labeled_requests_snapshot(\"Remote pre-turn auto-compaction
Scenario: Remote pre-turn auto-compaction after realtime was closed between turns: the follow-up request emits realtime-end instructions from previous-turn settings even though compaction cleared the reference baseline.
## Remote Compaction Request
00:message/developer[2]:
[01] <PERMISSIONS_INSTRUCTIONS>
[02] <realtime_conversation>\nRealtime conversation started.\n\nYou a...
00:message/developer[3]:
[01] <MODEL_INSTRUCTIONS>
[02] <PERMISSIONS_INSTRUCTIONS>
[03] <realtime_conversation>\nRealtime conversation started.\n\nYou a...
01:message/user:<ENVIRONMENT_CONTEXT:cwd=<CWD>>
02:message/user:USER_ONE
03:message/assistant:REMOTE_FIRST_REPLY
## Remote Post-Compaction History Layout
00:compaction:encrypted=true
01:message/developer[2]:
[01] <PERMISSIONS_INSTRUCTIONS>
[02] <realtime_conversation>\nRealtime conversation ended.\n\nSubsequ...
01:message/developer[3]:
[01] <MODEL_INSTRUCTIONS>
[02] <PERMISSIONS_INSTRUCTIONS>
[03] <realtime_conversation>\nRealtime conversation ended.\n\nSubsequ...
02:message/user:<ENVIRONMENT_CONTEXT:cwd=<CWD>>
03:message/user:USER_TWO
@@ -5,17 +5,19 @@ expression: "format_labeled_requests_snapshot(\"Remote pre-turn auto-compaction
Scenario: Remote pre-turn auto-compaction while realtime remains active: compaction clears the reference baseline, so the follow-up request restates realtime-start instructions.
## Remote Compaction Request
00:message/developer[2]:
[01] <PERMISSIONS_INSTRUCTIONS>
[02] <realtime_conversation>\nRealtime conversation started.\n\nYou a...
00:message/developer[3]:
[01] <MODEL_INSTRUCTIONS>
[02] <PERMISSIONS_INSTRUCTIONS>
[03] <realtime_conversation>\nRealtime conversation started.\n\nYou a...
01:message/user:<ENVIRONMENT_CONTEXT:cwd=<CWD>>
02:message/user:USER_ONE
03:message/assistant:REMOTE_FIRST_REPLY
## Remote Post-Compaction History Layout
00:compaction:encrypted=true
01:message/developer[2]:
[01] <PERMISSIONS_INSTRUCTIONS>
[02] <realtime_conversation>\nRealtime conversation started.\n\nYou a...
01:message/developer[3]:
[01] <MODEL_INSTRUCTIONS>
[02] <PERMISSIONS_INSTRUCTIONS>
[03] <realtime_conversation>\nRealtime conversation started.\n\nYou a...
02:message/user:<ENVIRONMENT_CONTEXT:cwd=<CWD>>
03:message/user:USER_TWO
@@ -5,12 +5,16 @@ expression: "format_labeled_requests_snapshot(\"Remote pre-turn compaction durin
Scenario: Remote pre-turn compaction during model switch currently excludes incoming user input, strips incoming <model_switch> from the compact request payload, and restores it in the post-compaction follow-up request.
## Initial Request (Previous Model)
00:message/developer:<PERMISSIONS_INSTRUCTIONS>
00:message/developer[2]:
[01] <MODEL_INSTRUCTIONS>
[02] <PERMISSIONS_INSTRUCTIONS>
01:message/user:<ENVIRONMENT_CONTEXT:cwd=<CWD>>
02:message/user:BEFORE_SWITCH_USER
## Remote Compaction Request
00:message/developer:<PERMISSIONS_INSTRUCTIONS>
00:message/developer[2]:
[01] <MODEL_INSTRUCTIONS>
[02] <PERMISSIONS_INSTRUCTIONS>
01:message/user:<ENVIRONMENT_CONTEXT:cwd=<CWD>>
02:message/user:BEFORE_SWITCH_USER
03:message/assistant:BEFORE_SWITCH_REPLY
@@ -18,9 +22,10 @@ Scenario: Remote pre-turn compaction during model switch currently excludes inco
## Remote Post-Compaction History Layout
00:message/user:BEFORE_SWITCH_USER
01:compaction:encrypted=true
02:message/developer[3]:
[01] <model_switch>\nThe user was previously using a different model....
[02] <PERMISSIONS_INSTRUCTIONS>
[03] <personality_spec> The user has requested a new communication st...
02:message/developer[4]:
[01] <MODEL_INSTRUCTIONS>
[02] <model_switch>\nThe user was previously using a different model....
[03] <PERMISSIONS_INSTRUCTIONS>
[04] <personality_spec> The user has requested a new communication st...
03:message/user:<ENVIRONMENT_CONTEXT:cwd=<CWD>>
04:message/user:AFTER_SWITCH_USER
@@ -5,7 +5,9 @@ expression: "context_snapshot::format_labeled_requests_snapshot(\"rollback trims
Scenario: rollback trims pre-turn override context updates before the follow-up request
## rolled-back turn request
00:message/developer:<PERMISSIONS_INSTRUCTIONS>
00:message/developer[2]:
[01] <MODEL_INSTRUCTIONS>
[02] <PERMISSIONS_INSTRUCTIONS>
01:message/user:<ENVIRONMENT_CONTEXT:cwd=<CWD>>
02:message/user:turn 1 user
03:message/assistant:turn 1 assistant
@@ -14,7 +16,9 @@ Scenario: rollback trims pre-turn override context updates before the follow-up
06:message/user:turn 2 user
## follow-up request after rollback
00:message/developer:<PERMISSIONS_INSTRUCTIONS>
00:message/developer[2]:
[01] <MODEL_INSTRUCTIONS>
[02] <PERMISSIONS_INSTRUCTIONS>
01:message/user:<ENVIRONMENT_CONTEXT:cwd=<CWD>>
02:message/user:turn 1 user
03:message/assistant:turn 1 assistant
@@ -5,7 +5,9 @@ expression: "context_snapshot::format_labeled_requests_snapshot(\"rollback past
Scenario: rollback past compaction replay after rollback
## compaction request
00:message/developer:<PERMISSIONS_INSTRUCTIONS>
00:message/developer[2]:
[01] <MODEL_INSTRUCTIONS>
[02] <PERMISSIONS_INSTRUCTIONS>
01:message/user:<ENVIRONMENT_CONTEXT:cwd=<CWD>>
02:message/user:hello world
03:message/assistant:FIRST_REPLY
@@ -14,13 +16,17 @@ Scenario: rollback past compaction replay after rollback
## before rollback
00:message/user:hello world
01:message/user:<COMPACTION_SUMMARY>\nSUMMARY_ONLY_CONTEXT
02:message/developer:<PERMISSIONS_INSTRUCTIONS>
02:message/developer[2]:
[01] <MODEL_INSTRUCTIONS>
[02] <PERMISSIONS_INSTRUCTIONS>
03:message/user:<ENVIRONMENT_CONTEXT:cwd=<CWD>>
04:message/user:EDITED_AFTER_COMPACT
## after rollback
00:message/user:hello world
01:message/user:<COMPACTION_SUMMARY>\nSUMMARY_ONLY_CONTEXT
02:message/developer:<PERMISSIONS_INSTRUCTIONS>
02:message/developer[2]:
[01] <MODEL_INSTRUCTIONS>
[02] <PERMISSIONS_INSTRUCTIONS>
03:message/user:<ENVIRONMENT_CONTEXT:cwd=<CWD>>
04:message/user:AFTER_ROLLBACK
@@ -5,16 +5,18 @@ expression: "format_labeled_requests_snapshot(\"Second turn changes cwd to a dir
Scenario: Second turn changes cwd to a directory with different AGENTS.md; current behavior does not emit refreshed AGENTS instructions.
## First Request (agents_one)
00:message/developer[2]:
[01] <PERMISSIONS_INSTRUCTIONS>
[02] <SKILLS_INSTRUCTIONS>
00:message/developer[3]:
[01] <MODEL_INSTRUCTIONS>
[02] <PERMISSIONS_INSTRUCTIONS>
[03] <SKILLS_INSTRUCTIONS>
01:message/user:<ENVIRONMENT_CONTEXT:cwd=<CWD>>
02:message/user:first turn in agents_one
## Second Request (agents_two cwd)
00:message/developer[2]:
[01] <PERMISSIONS_INSTRUCTIONS>
[02] <SKILLS_INSTRUCTIONS>
00:message/developer[3]:
[01] <MODEL_INSTRUCTIONS>
[02] <PERMISSIONS_INSTRUCTIONS>
[03] <SKILLS_INSTRUCTIONS>
01:message/user:<ENVIRONMENT_CONTEXT:cwd=<CWD>>
02:message/user:first turn in agents_one
03:message/assistant:turn one complete
@@ -5,16 +5,18 @@ expression: "format_labeled_requests_snapshot(\"First post-resume turn where pre
Scenario: First post-resume turn where pre-turn override sets model to rollout model; no model-switch update should appear.
## Last Request Before Resume
00:message/developer[2]:
[01] <PERMISSIONS_INSTRUCTIONS>
[02] <SKILLS_INSTRUCTIONS>
00:message/developer[3]:
[01] <MODEL_INSTRUCTIONS>
[02] <PERMISSIONS_INSTRUCTIONS>
[03] <SKILLS_INSTRUCTIONS>
01:message/user:<ENVIRONMENT_CONTEXT:cwd=<CWD>>
02:message/user:seed resume history
## First Request After Resume + Override
00:message/developer[2]:
[01] <PERMISSIONS_INSTRUCTIONS>
[02] <SKILLS_INSTRUCTIONS>
00:message/developer[3]:
[01] <MODEL_INSTRUCTIONS>
[02] <PERMISSIONS_INSTRUCTIONS>
[03] <SKILLS_INSTRUCTIONS>
01:message/user:<ENVIRONMENT_CONTEXT:cwd=<CWD>>
02:message/user:seed resume history
03:message/assistant:recorded before resume
@@ -1,17 +1,19 @@
---
source: core/tests/suite/model_visible_layout.rs
expression: "format_labeled_requests_snapshot(\"First post-resume turn where resumed config model differs from rollout and personality changes.\",\n&[(\"Last Request Before Resume\", &initial_request),\n(\"First Request After Resume\", &resumed_request),])"
expression: "format_labeled_requests_snapshot(\"First post-legacy-resume turn where resumed config model differs from rollout and personality changes.\",\n&[(\"Last Request Before Resume\", &initial_request),\n(\"First Request After Resume\", &resumed_request),])"
---
Scenario: First post-resume turn where resumed config model differs from rollout and personality changes.
Scenario: First post-legacy-resume turn where resumed config model differs from rollout and personality changes.
## Last Request Before Resume
00:message/developer[2]:
[01] <PERMISSIONS_INSTRUCTIONS>
[02] <SKILLS_INSTRUCTIONS>
00:message/developer[3]:
[01] <MODEL_INSTRUCTIONS>
[02] <PERMISSIONS_INSTRUCTIONS>
[03] <SKILLS_INSTRUCTIONS>
01:message/user:<ENVIRONMENT_CONTEXT:cwd=<CWD>>
02:message/user:seed resume history
## First Request After Resume
instructions:<MODEL_INSTRUCTIONS>
00:message/developer[2]:
[01] <PERMISSIONS_INSTRUCTIONS>
[02] <SKILLS_INSTRUCTIONS>
@@ -5,16 +5,18 @@ expression: "format_labeled_requests_snapshot(\"Second turn changes cwd, approva
Scenario: Second turn changes cwd, approval policy, and personality while keeping model constant.
## First Request (Baseline)
00:message/developer[2]:
[01] <PERMISSIONS_INSTRUCTIONS>
[02] <SKILLS_INSTRUCTIONS>
00:message/developer[3]:
[01] <MODEL_INSTRUCTIONS>
[02] <PERMISSIONS_INSTRUCTIONS>
[03] <SKILLS_INSTRUCTIONS>
01:message/user:<ENVIRONMENT_CONTEXT:cwd=<CWD>>
02:message/user:first turn
## Second Request (Turn Overrides)
00:message/developer[2]:
[01] <PERMISSIONS_INSTRUCTIONS>
[02] <SKILLS_INSTRUCTIONS>
00:message/developer[3]:
[01] <MODEL_INSTRUCTIONS>
[02] <PERMISSIONS_INSTRUCTIONS>
[03] <SKILLS_INSTRUCTIONS>
01:message/user:<ENVIRONMENT_CONTEXT:cwd=<CWD>>
02:message/user:first turn
03:message/assistant:turn one complete