mirror of
https://github.com/openai/codex.git
synced 2026-10-22 17:58:46 +00:00
## What changed - Add `environments` to `TurnSettingsUpdate` to replace the selection for subsequent steps without changing future turns. - Capture model settings and environments together so combined updates apply or reject atomically, while existing steps retain their captured selection. - Validate environment IDs, working directories, configuration ownership, and permission requirements against the running turn's selections. - Preserve executor startup behavior when switching environments and use the step's local working directory for tool hooks. ## Testing Add coverage for workspace switching and restoration on the next turn, atomic model and environment updates, permission validation, executor connection waits, and replacement of pending environment selections. GitOrigin-RevId: 02b5c57a78fd594b2aed84fc09d9e99eb97be28c
67 lines
2.4 KiB
Rust
67 lines
2.4 KiB
Rust
//! Task completion preserves a queued notification's budget alongside real user input.
|
|
|
|
use super::*;
|
|
use pretty_assertions::assert_eq;
|
|
|
|
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
|
async fn task_finish_preserves_notification_budget_and_queued_user_input() {
|
|
let (session, turn, _rx) = make_session_and_context_with_rx().await;
|
|
session
|
|
.spawn_task(
|
|
Arc::clone(&turn),
|
|
Vec::new(),
|
|
NeverEndingTask {
|
|
kind: TaskKind::Regular,
|
|
listen_to_cancellation_token: false,
|
|
},
|
|
)
|
|
.await;
|
|
let text = "notification diagnostic line\n".repeat(500);
|
|
let notification = |text| ResponseItem::CustomToolCallOutput {
|
|
id: None,
|
|
call_id: "call-a".to_string(),
|
|
name: Some("exec".to_string()),
|
|
output: FunctionCallOutputPayload::from_text(text),
|
|
internal_chat_message_metadata_passthrough: None,
|
|
};
|
|
session
|
|
.inject_if_running(vec![ResponseItemEnvelope {
|
|
item: notification(text.clone()),
|
|
metadata: Some(CodexHarnessMetadata {
|
|
history_truncation_token_limit: Some(120),
|
|
..Default::default()
|
|
}),
|
|
}])
|
|
.await
|
|
.unwrap();
|
|
let user_input = vec![UserInput::Text {
|
|
text: "keep this queued user input".to_string(),
|
|
text_elements: Vec::new(),
|
|
}];
|
|
assert!(matches!(
|
|
submit_steer_only(&session, user_input.clone(), &turn.sub_id).await,
|
|
TurnInputSubmission::Steered { .. }
|
|
));
|
|
let mut current = turn.initial_settings.as_ref().clone();
|
|
Arc::make_mut(&mut current.model_info).truncation_policy =
|
|
codex_protocol::openai_models::TruncationPolicyConfig::tokens(/*limit*/ 400);
|
|
turn.next_step_settings.store(Arc::new(current));
|
|
|
|
session
|
|
.on_task_finished(Arc::clone(&turn), /*task_result*/ Ok(None))
|
|
.await;
|
|
|
|
let expected = vec![
|
|
notification(codex_utils_output_truncation::truncate_text(
|
|
&text,
|
|
codex_utils_output_truncation::TruncationPolicy::Tokens(120),
|
|
)),
|
|
session.response_item_from_user_input(user_input),
|
|
];
|
|
let history = session.clone_history().await;
|
|
assert_eq!(
|
|
strip_response_item_ids(&strip_metadata_from_items(&raw_history_items(&history))),
|
|
strip_response_item_ids(&strip_metadata_from_items(&expected)),
|
|
);
|
|
}
|