mirror of
https://github.com/openai/codex.git
synced 2026-09-15 12:08:01 +00:00
fix(context) include yolo on resume
This commit is contained in:
@@ -801,6 +801,7 @@ impl Session {
|
||||
InitialHistory::Resumed(_) | InitialHistory::Forked(_) => {
|
||||
let rollout_items = conversation_history.get_rollout_items();
|
||||
let persist = matches!(conversation_history, InitialHistory::Forked(_));
|
||||
let append_env_context = matches!(conversation_history, InitialHistory::Resumed(_));
|
||||
|
||||
// If resuming, warn when the last recorded model differs from the current one.
|
||||
if let InitialHistory::Resumed(_) = conversation_history
|
||||
@@ -845,6 +846,12 @@ impl Session {
|
||||
state.set_token_info(Some(info));
|
||||
}
|
||||
|
||||
if append_env_context {
|
||||
let env_item = self.build_environment_context_item(&turn_context);
|
||||
self.record_conversation_items(&turn_context, std::slice::from_ref(&env_item))
|
||||
.await;
|
||||
}
|
||||
|
||||
// If persisting, persist all rollout items as-is (recorder filters)
|
||||
if persist && !rollout_items.is_empty() {
|
||||
self.persist_rollout_items(&rollout_items).await;
|
||||
@@ -1333,9 +1340,18 @@ impl Session {
|
||||
}
|
||||
}
|
||||
|
||||
fn build_environment_context_item(&self, turn_context: &TurnContext) -> ResponseItem {
|
||||
let shell = self.user_shell();
|
||||
ResponseItem::from(EnvironmentContext::new(
|
||||
Some(turn_context.cwd.clone()),
|
||||
Some(turn_context.approval_policy),
|
||||
Some(turn_context.sandbox_policy.clone()),
|
||||
shell.as_ref().clone(),
|
||||
))
|
||||
}
|
||||
|
||||
pub(crate) fn build_initial_context(&self, turn_context: &TurnContext) -> Vec<ResponseItem> {
|
||||
let mut items = Vec::<ResponseItem>::with_capacity(3);
|
||||
let shell = self.user_shell();
|
||||
if let Some(developer_instructions) = turn_context.developer_instructions.as_deref() {
|
||||
items.push(DeveloperInstructions::new(developer_instructions.to_string()).into());
|
||||
}
|
||||
@@ -1348,12 +1364,7 @@ impl Session {
|
||||
.into(),
|
||||
);
|
||||
}
|
||||
items.push(ResponseItem::from(EnvironmentContext::new(
|
||||
Some(turn_context.cwd.clone()),
|
||||
Some(turn_context.approval_policy),
|
||||
Some(turn_context.sandbox_policy.clone()),
|
||||
shell.as_ref().clone(),
|
||||
)));
|
||||
items.push(self.build_environment_context_item(turn_context));
|
||||
items
|
||||
}
|
||||
|
||||
@@ -2925,6 +2936,8 @@ mod tests {
|
||||
async fn record_initial_history_reconstructs_resumed_transcript() {
|
||||
let (session, turn_context) = make_session_and_context().await;
|
||||
let (rollout_items, expected) = sample_rollout(&session, &turn_context);
|
||||
let mut expected = expected;
|
||||
expected.push(session.build_environment_context_item(&turn_context));
|
||||
|
||||
session
|
||||
.record_initial_history(InitialHistory::Resumed(ResumedHistory {
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
use anyhow::Result;
|
||||
use codex_core::config::Constrained;
|
||||
use codex_core::protocol::AskForApproval;
|
||||
use codex_core::protocol::ENVIRONMENT_CONTEXT_OPEN_TAG;
|
||||
use codex_core::protocol::EventMsg;
|
||||
use codex_core::protocol::Op;
|
||||
use codex_protocol::user_input::UserInput;
|
||||
@@ -12,6 +15,7 @@ use core_test_support::responses::start_mock_server;
|
||||
use core_test_support::skip_if_no_network;
|
||||
use core_test_support::test_codex::test_codex;
|
||||
use core_test_support::wait_for_event;
|
||||
use pretty_assertions::assert_eq;
|
||||
use std::sync::Arc;
|
||||
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
@@ -120,3 +124,78 @@ async fn resume_includes_initial_messages_from_reasoning_events() -> Result<()>
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
async fn resume_appends_environment_context_on_first_turn() -> Result<()> {
|
||||
skip_if_no_network!(Ok(()));
|
||||
|
||||
let server = start_mock_server().await;
|
||||
let mut builder = test_codex();
|
||||
let initial = builder.build(&server).await?;
|
||||
let codex = Arc::clone(&initial.codex);
|
||||
let home = initial.home.clone();
|
||||
let rollout_path = initial.session_configured.rollout_path.clone();
|
||||
|
||||
let initial_sse = sse(vec![
|
||||
ev_response_created("resp-initial"),
|
||||
ev_assistant_message("msg-1", "Completed first turn"),
|
||||
ev_completed("resp-initial"),
|
||||
]);
|
||||
mount_sse_once(&server, initial_sse).await;
|
||||
|
||||
codex
|
||||
.submit(Op::UserInput {
|
||||
items: vec![UserInput::Text {
|
||||
text: "Record some messages".into(),
|
||||
}],
|
||||
final_output_json_schema: None,
|
||||
})
|
||||
.await?;
|
||||
|
||||
wait_for_event(&codex, |event| matches!(event, EventMsg::TaskComplete(_))).await;
|
||||
|
||||
let mut resume_builder = test_codex().with_config(|config| {
|
||||
config.approval_policy = Constrained::allow_any(AskForApproval::Never);
|
||||
});
|
||||
let resumed = resume_builder.resume(&server, home, rollout_path).await?;
|
||||
|
||||
let resumed_sse = sse(vec![
|
||||
ev_response_created("resp-resume"),
|
||||
ev_assistant_message("msg-2", "Completed after resume"),
|
||||
ev_completed("resp-resume"),
|
||||
]);
|
||||
let resumed_mock = mount_sse_once(&server, resumed_sse).await;
|
||||
|
||||
resumed
|
||||
.codex
|
||||
.submit(Op::UserInput {
|
||||
items: vec![UserInput::Text {
|
||||
text: "After resume".into(),
|
||||
}],
|
||||
final_output_json_schema: None,
|
||||
})
|
||||
.await?;
|
||||
wait_for_event(&resumed.codex, |event| {
|
||||
matches!(event, EventMsg::TaskComplete(_))
|
||||
})
|
||||
.await;
|
||||
|
||||
let body = resumed_mock.single_request().body_json();
|
||||
let input = body["input"]
|
||||
.as_array()
|
||||
.expect("resume request input is an array");
|
||||
let env_texts: Vec<&str> = input
|
||||
.iter()
|
||||
.filter_map(|item| item["content"][0]["text"].as_str())
|
||||
.filter(|text| text.starts_with(ENVIRONMENT_CONTEXT_OPEN_TAG))
|
||||
.collect();
|
||||
|
||||
assert_eq!(env_texts.is_empty(), false);
|
||||
let last_env = env_texts.last().expect("environment context present");
|
||||
assert_eq!(
|
||||
last_env.contains("<approval_policy>never</approval_policy>"),
|
||||
true,
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user