mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
core: remove redundant TurnContext and Prompt fields (#28638)
## Why `TurnContext` had accumulated dead fields and cached projections of values already owned by its per-turn `Config` or `ModelInfo`. Keeping both copies made ownership unclear and allowed artificial split-brain states, such as a compatibility hash differing from the model metadata it came from. `Prompt` similarly carried a write-only personality after personality selection had already been materialized into its base instructions. This makes the canonical owner explicit: configuration-backed values come from `config`, model-derived values come from `model_info`, and prompts contain only data consumed by request construction. ## What changed - Remove the unused `ghost_snapshot`, `codex_self_exe`, and `thread_source` fields. - Remove duplicate `comp_hash`, `truncation_policy`, `features`, `shell_environment_policy`, `codex_linux_sandbox_exe`, `compact_prompt`, and `tool_mode` fields. - Read those values directly from `TurnContext::config` or `TurnContext::model_info` at their consumers. - Remove the write-only `Prompt::personality` field and its constructor assignments. - Preserve review-turn inheritance of the parent turn's shell policy, Linux sandbox executable, and compact prompt through the review config. ## Testing - `cargo check -p codex-core --tests`
This commit is contained in:
committed by
GitHub
Unverified
parent
cb15c64760
commit
172b2218a5
@@ -1,5 +1,4 @@
|
||||
pub use codex_api::ResponseEvent;
|
||||
use codex_config::types::Personality;
|
||||
use codex_protocol::error::Result;
|
||||
use codex_protocol::models::BaseInstructions;
|
||||
use codex_protocol::models::ContentItem;
|
||||
@@ -29,9 +28,6 @@ pub struct Prompt {
|
||||
|
||||
pub base_instructions: BaseInstructions,
|
||||
|
||||
/// Optionally specify the personality of the model.
|
||||
pub personality: Option<Personality>,
|
||||
|
||||
/// Optional the output schema for the model's response.
|
||||
pub output_schema: Option<Value>,
|
||||
|
||||
@@ -46,7 +42,6 @@ impl Default for Prompt {
|
||||
tools: Vec::new(),
|
||||
parallel_tool_calls: false,
|
||||
base_instructions: BaseInstructions::default(),
|
||||
personality: None,
|
||||
output_schema: None,
|
||||
output_schema_strict: true,
|
||||
}
|
||||
|
||||
@@ -77,7 +77,12 @@ pub(crate) async fn run_inline_auto_compact_task(
|
||||
reason: CompactionReason,
|
||||
phase: CompactionPhase,
|
||||
) -> CodexResult<()> {
|
||||
let prompt = turn_context.compact_prompt().to_string();
|
||||
let prompt = turn_context
|
||||
.config
|
||||
.compact_prompt
|
||||
.as_deref()
|
||||
.unwrap_or(SUMMARIZATION_PROMPT)
|
||||
.to_string();
|
||||
let input = vec![UserInput::Text {
|
||||
text: prompt,
|
||||
// Compaction prompt is synthesized; no UI element ranges to preserve.
|
||||
@@ -209,7 +214,7 @@ async fn run_compact_task_inner_impl(
|
||||
let mut history = sess.clone_history().await;
|
||||
history.record_items(
|
||||
&[initial_input_for_turn.into()],
|
||||
turn_context.truncation_policy,
|
||||
turn_context.model_info.truncation_policy.into(),
|
||||
);
|
||||
|
||||
let max_retries = turn_context.provider.info().stream_max_retries();
|
||||
@@ -234,7 +239,6 @@ async fn run_compact_task_inner_impl(
|
||||
let prompt = Prompt {
|
||||
input: turn_input,
|
||||
base_instructions: sess.get_base_instructions().await,
|
||||
personality: turn_context.personality,
|
||||
..Default::default()
|
||||
};
|
||||
let attempt_result = drain_to_completed(
|
||||
|
||||
@@ -228,7 +228,6 @@ async fn run_remote_compact_task_inner_impl(
|
||||
tools: tool_router.model_visible_specs(),
|
||||
parallel_tool_calls: turn_context.model_info.supports_parallel_tool_calls,
|
||||
base_instructions,
|
||||
personality: turn_context.personality,
|
||||
output_schema: None,
|
||||
output_schema_strict: true,
|
||||
};
|
||||
|
||||
@@ -237,7 +237,6 @@ async fn run_remote_compact_task_inner_impl(
|
||||
tools: tool_router.model_visible_specs(),
|
||||
parallel_tool_calls: turn_context.model_info.supports_parallel_tool_calls,
|
||||
base_instructions,
|
||||
personality: turn_context.personality,
|
||||
output_schema: None,
|
||||
output_schema_strict: true,
|
||||
};
|
||||
|
||||
@@ -63,8 +63,12 @@ fn build_permissions_update_item(
|
||||
exec_policy,
|
||||
#[allow(deprecated)]
|
||||
&next.cwd,
|
||||
next.features.enabled(Feature::ExecPermissionApprovals),
|
||||
next.features.enabled(Feature::RequestPermissionsTool),
|
||||
next.config
|
||||
.features
|
||||
.enabled(Feature::ExecPermissionApprovals),
|
||||
next.config
|
||||
.features
|
||||
.enabled(Feature::RequestPermissionsTool),
|
||||
)
|
||||
.render(),
|
||||
)
|
||||
|
||||
@@ -626,7 +626,11 @@ async fn maybe_request_codex_apps_auth_elicitation(
|
||||
return result;
|
||||
}
|
||||
|
||||
if !turn_context.features.enabled(Feature::AuthElicitation) {
|
||||
if !turn_context
|
||||
.config
|
||||
.features
|
||||
.enabled(Feature::AuthElicitation)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -723,10 +727,10 @@ async fn augment_mcp_tool_request_meta_with_sandbox_state(
|
||||
let sandbox_state = serde_json::to_value(SandboxState {
|
||||
permission_profile: Some(turn_context.permission_profile()),
|
||||
sandbox_policy: turn_context.sandbox_policy(),
|
||||
codex_linux_sandbox_exe: turn_context.codex_linux_sandbox_exe.clone(),
|
||||
codex_linux_sandbox_exe: turn_context.config.codex_linux_sandbox_exe.clone(),
|
||||
#[allow(deprecated)]
|
||||
sandbox_cwd: turn_context.cwd.to_path_buf(),
|
||||
use_legacy_landlock: turn_context.features.use_legacy_landlock(),
|
||||
use_legacy_landlock: turn_context.config.features.use_legacy_landlock(),
|
||||
})?;
|
||||
|
||||
match meta.as_mut() {
|
||||
|
||||
@@ -1316,15 +1316,14 @@ async fn codex_apps_auth_elicitation_non_host_owned_server_returns_original_resu
|
||||
let (session, mut turn_context, rx_event) = make_session_and_context_with_rx().await;
|
||||
let mut features = Features::with_defaults();
|
||||
features.enable(Feature::AuthElicitation);
|
||||
Arc::get_mut(&mut turn_context)
|
||||
.expect("single turn context ref")
|
||||
.features = ManagedFeatures::from(features);
|
||||
let turn_context = Arc::get_mut(&mut turn_context).expect("single turn context ref");
|
||||
Arc::make_mut(&mut turn_context.config).features = ManagedFeatures::from(features);
|
||||
let result = codex_apps_auth_failure_result();
|
||||
let metadata = codex_apps_auth_failure_metadata();
|
||||
|
||||
let returned = maybe_request_codex_apps_auth_elicitation(
|
||||
&session,
|
||||
&turn_context,
|
||||
turn_context,
|
||||
"call_123",
|
||||
CODEX_APPS_MCP_SERVER_NAME,
|
||||
Some(&metadata),
|
||||
@@ -1343,7 +1342,7 @@ async fn codex_apps_auth_elicitation_disallowed_by_policy_returns_original_resul
|
||||
let mut features = Features::with_defaults();
|
||||
features.enable(Feature::AuthElicitation);
|
||||
let turn_context = Arc::get_mut(&mut turn_context).expect("single turn context ref");
|
||||
turn_context.features = ManagedFeatures::from(features);
|
||||
Arc::make_mut(&mut turn_context.config).features = ManagedFeatures::from(features);
|
||||
turn_context
|
||||
.approval_policy
|
||||
.set(AskForApproval::Never)
|
||||
@@ -1372,7 +1371,7 @@ async fn codex_apps_auth_elicitation_granular_mcp_disabled_returns_original_resu
|
||||
let mut features = Features::with_defaults();
|
||||
features.enable(Feature::AuthElicitation);
|
||||
let turn_context = Arc::get_mut(&mut turn_context).expect("single turn context ref");
|
||||
turn_context.features = ManagedFeatures::from(features);
|
||||
Arc::make_mut(&mut turn_context.config).features = ManagedFeatures::from(features);
|
||||
turn_context
|
||||
.approval_policy
|
||||
.set(AskForApproval::Granular(GranularApprovalConfig {
|
||||
@@ -1407,9 +1406,10 @@ async fn codex_apps_auth_elicitation_feature_enabled_requests_elicitation() {
|
||||
*session.active_turn.lock().await = Some(ActiveTurn::default());
|
||||
let mut features = Features::with_defaults();
|
||||
features.enable(Feature::AuthElicitation);
|
||||
Arc::get_mut(&mut turn_context)
|
||||
.expect("single turn context ref")
|
||||
.features = ManagedFeatures::from(features);
|
||||
{
|
||||
let turn_context = Arc::get_mut(&mut turn_context).expect("single turn context ref");
|
||||
Arc::make_mut(&mut turn_context.config).features = ManagedFeatures::from(features);
|
||||
}
|
||||
let result = codex_apps_auth_failure_result();
|
||||
let metadata = codex_apps_auth_failure_metadata();
|
||||
|
||||
|
||||
@@ -149,7 +149,6 @@ use codex_thread_store::ReadThreadParams;
|
||||
use codex_thread_store::ResumeThreadParams;
|
||||
use codex_thread_store::ThreadPersistenceMetadata;
|
||||
use codex_thread_store::ThreadStore;
|
||||
use codex_utils_output_truncation::TruncationPolicy;
|
||||
use codex_utils_path_uri::PathUri;
|
||||
use futures::future::BoxFuture;
|
||||
use futures::future::Shared;
|
||||
@@ -198,7 +197,6 @@ use codex_config::ConfigLayerSource;
|
||||
use codex_config::ConfigLayerStackOrdering;
|
||||
use codex_config::types::McpServerConfig;
|
||||
use codex_model_provider_info::ModelProviderInfo;
|
||||
use codex_protocol::config_types::ShellEnvironmentPolicy;
|
||||
use codex_protocol::error::CodexErr;
|
||||
use codex_protocol::error::Result as CodexResult;
|
||||
#[cfg(test)]
|
||||
@@ -1330,7 +1328,11 @@ impl Session {
|
||||
} = self
|
||||
.reconstruct_history_from_rollout(turn_context, rollout_items)
|
||||
.await;
|
||||
if turn_context.features.enabled(Feature::ResizeAllImages) {
|
||||
if turn_context
|
||||
.config
|
||||
.features
|
||||
.enabled(Feature::ResizeAllImages)
|
||||
{
|
||||
// Keep the recorded rollout unchanged. Prepare its reconstructed history before
|
||||
// installing it, so legacy images are processed once for this resume or fork and
|
||||
// will be processed again if the rollout is reconstructed in a future session.
|
||||
@@ -2630,7 +2632,11 @@ impl Session {
|
||||
turn_context: &TurnContext,
|
||||
items: &'a [ResponseItem],
|
||||
) -> Cow<'a, [ResponseItem]> {
|
||||
if !turn_context.features.enabled(Feature::ResizeAllImages) {
|
||||
if !turn_context
|
||||
.config
|
||||
.features
|
||||
.enabled(Feature::ResizeAllImages)
|
||||
{
|
||||
return Cow::Borrowed(items);
|
||||
}
|
||||
|
||||
@@ -2644,7 +2650,11 @@ impl Session {
|
||||
turn_context: &TurnContext,
|
||||
input: Vec<UserInput>,
|
||||
) -> ResponseItem {
|
||||
let local_image_preparation = if turn_context.features.enabled(Feature::ResizeAllImages) {
|
||||
let local_image_preparation = if turn_context
|
||||
.config
|
||||
.features
|
||||
.enabled(Feature::ResizeAllImages)
|
||||
{
|
||||
LocalImagePreparation::Defer
|
||||
} else {
|
||||
LocalImagePreparation::Process
|
||||
@@ -2664,7 +2674,10 @@ impl Session {
|
||||
let items = items.as_ref();
|
||||
{
|
||||
let mut state = self.state.lock().await;
|
||||
state.record_items(items.iter(), turn_context.truncation_policy);
|
||||
state.record_items(
|
||||
items.iter(),
|
||||
turn_context.model_info.truncation_policy.into(),
|
||||
);
|
||||
}
|
||||
self.persist_rollout_response_items(items).await;
|
||||
self.send_raw_response_items(turn_context, items).await;
|
||||
@@ -2683,7 +2696,10 @@ impl Session {
|
||||
let items = items.as_ref();
|
||||
{
|
||||
let mut state = self.state.lock().await;
|
||||
state.record_items(items.iter(), turn_context.truncation_policy);
|
||||
state.record_items(
|
||||
items.iter(),
|
||||
turn_context.model_info.truncation_policy.into(),
|
||||
);
|
||||
}
|
||||
self.persist_rollout_items(&[RolloutItem::InterAgentCommunication(communication)])
|
||||
.await;
|
||||
@@ -2885,9 +2901,11 @@ impl Session {
|
||||
#[allow(deprecated)]
|
||||
&turn_context.cwd,
|
||||
turn_context
|
||||
.config
|
||||
.features
|
||||
.enabled(Feature::ExecPermissionApprovals),
|
||||
turn_context
|
||||
.config
|
||||
.features
|
||||
.enabled(Feature::RequestPermissionsTool),
|
||||
)
|
||||
@@ -3031,7 +3049,7 @@ impl Session {
|
||||
contextual_user_sections.push(user_instructions.to_string());
|
||||
}
|
||||
// This is full-context metadata. Steady-state context diffs should not re-emit it.
|
||||
if turn_context.features.enabled(Feature::TokenBudget)
|
||||
if turn_context.config.features.enabled(Feature::TokenBudget)
|
||||
&& let Some(model_context_window) = turn_context.model_context_window()
|
||||
{
|
||||
developer_sections.push(
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
use super::*;
|
||||
use codex_core_skills::HostLoadedSkills;
|
||||
use codex_protocol::openai_models::ToolMode;
|
||||
use std::sync::atomic::AtomicBool;
|
||||
|
||||
/// Spawn a review thread using the given prompt.
|
||||
@@ -47,15 +46,14 @@ pub(super) async fn spawn_review_thread(
|
||||
let mut per_turn_config = (*config).clone();
|
||||
per_turn_config.model = Some(model.clone());
|
||||
per_turn_config.features = review_features.clone();
|
||||
let tool_mode = model_info.tool_mode.unwrap_or_else(|| {
|
||||
if per_turn_config.features.enabled(Feature::CodeModeOnly) {
|
||||
ToolMode::CodeModeOnly
|
||||
} else if per_turn_config.features.enabled(Feature::CodeMode) {
|
||||
ToolMode::CodeMode
|
||||
} else {
|
||||
ToolMode::Direct
|
||||
}
|
||||
});
|
||||
per_turn_config.permissions.shell_environment_policy = parent_turn_context
|
||||
.config
|
||||
.permissions
|
||||
.shell_environment_policy
|
||||
.clone();
|
||||
per_turn_config.codex_linux_sandbox_exe =
|
||||
parent_turn_context.config.codex_linux_sandbox_exe.clone();
|
||||
per_turn_config.compact_prompt = parent_turn_context.config.compact_prompt.clone();
|
||||
if let Err(err) = per_turn_config.web_search_mode.set(review_web_search_mode) {
|
||||
let fallback_value = per_turn_config.web_search_mode.value();
|
||||
tracing::warn!(
|
||||
@@ -113,26 +111,20 @@ pub(super) async fn spawn_review_thread(
|
||||
config: per_turn_config,
|
||||
auth_manager: auth_manager_for_context,
|
||||
model_info: model_info.clone(),
|
||||
comp_hash: model_info.comp_hash.clone(),
|
||||
tool_mode,
|
||||
session_telemetry: session_telemetry_for_context,
|
||||
provider: provider_for_context,
|
||||
reasoning_effort,
|
||||
reasoning_summary,
|
||||
session_source,
|
||||
parent_thread_id: parent_turn_context.parent_thread_id,
|
||||
thread_source: parent_turn_context.thread_source.clone(),
|
||||
environments: parent_turn_context.environments.clone(),
|
||||
available_models,
|
||||
unified_exec_shell_mode,
|
||||
features: review_features,
|
||||
ghost_snapshot: parent_turn_context.ghost_snapshot.clone(),
|
||||
current_date: parent_turn_context.current_date.clone(),
|
||||
timezone: parent_turn_context.timezone.clone(),
|
||||
app_server_client_name: parent_turn_context.app_server_client_name.clone(),
|
||||
developer_instructions: None,
|
||||
user_instructions: None,
|
||||
compact_prompt: parent_turn_context.compact_prompt.clone(),
|
||||
collaboration_mode: parent_turn_context.collaboration_mode.clone(),
|
||||
multi_agent_version: MultiAgentVersion::Disabled,
|
||||
personality: parent_turn_context.personality,
|
||||
@@ -140,14 +132,10 @@ pub(super) async fn spawn_review_thread(
|
||||
permission_profile: parent_turn_context.permission_profile(),
|
||||
network: parent_turn_context.network.clone(),
|
||||
windows_sandbox_level: parent_turn_context.windows_sandbox_level,
|
||||
shell_environment_policy: parent_turn_context.shell_environment_policy.clone(),
|
||||
#[allow(deprecated)]
|
||||
cwd: parent_turn_context.cwd.clone(),
|
||||
final_output_json_schema: None,
|
||||
codex_self_exe: parent_turn_context.codex_self_exe.clone(),
|
||||
codex_linux_sandbox_exe: parent_turn_context.codex_linux_sandbox_exe.clone(),
|
||||
dynamic_tools: parent_turn_context.dynamic_tools.clone(),
|
||||
truncation_policy: model_info.truncation_policy.into(),
|
||||
turn_metadata_state,
|
||||
extension_data,
|
||||
turn_skills: TurnSkillsContext::new(parent_turn_context.turn_skills.outcome.clone()),
|
||||
|
||||
@@ -271,14 +271,14 @@ impl Session {
|
||||
RolloutItem::ResponseItem(response_item) => {
|
||||
history.record_items(
|
||||
std::iter::once(response_item),
|
||||
turn_context.truncation_policy,
|
||||
turn_context.model_info.truncation_policy.into(),
|
||||
);
|
||||
}
|
||||
RolloutItem::InterAgentCommunication(communication) => {
|
||||
let response_item = communication.to_model_input_item();
|
||||
history.record_items(
|
||||
std::iter::once(&response_item),
|
||||
turn_context.truncation_policy,
|
||||
turn_context.model_info.truncation_policy.into(),
|
||||
);
|
||||
}
|
||||
RolloutItem::Compacted(compacted) => {
|
||||
|
||||
@@ -3530,7 +3530,7 @@ async fn includes_timed_out_message() {
|
||||
};
|
||||
let (_, turn_context) = make_session_and_context().await;
|
||||
|
||||
let out = format_exec_output_str(&exec, turn_context.truncation_policy);
|
||||
let out = format_exec_output_str(&exec, turn_context.model_info.truncation_policy.into());
|
||||
|
||||
assert_eq!(
|
||||
out,
|
||||
@@ -3569,10 +3569,6 @@ async fn turn_context_with_model_updates_model_fields() {
|
||||
updated.config.model_reasoning_effort,
|
||||
Some(ReasoningEffortConfig::Medium)
|
||||
);
|
||||
assert_eq!(
|
||||
updated.truncation_policy,
|
||||
expected_model_info.truncation_policy.into()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -8118,18 +8114,6 @@ fn file_system_policy_with_unreadable_glob(turn_context: &TurnContext) -> FileSy
|
||||
policy
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn turn_context_item_uses_turn_context_comp_hash_snapshot() {
|
||||
let (_session, mut turn_context) = make_session_and_context().await;
|
||||
turn_context.comp_hash = Some("turn-context-hash".to_string());
|
||||
turn_context.model_info.comp_hash = Some("model-info-hash".to_string());
|
||||
|
||||
assert_eq!(
|
||||
turn_context.to_turn_context_item().comp_hash.as_deref(),
|
||||
Some("turn-context-hash")
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn turn_context_item_stores_local_cwd() {
|
||||
let (_session, mut turn_context) = make_session_and_context().await;
|
||||
@@ -9706,7 +9690,7 @@ async fn sample_rollout(
|
||||
}
|
||||
live_history.record_items(
|
||||
initial_context.iter(),
|
||||
reconstruction_turn.truncation_policy,
|
||||
reconstruction_turn.model_info.truncation_policy.into(),
|
||||
);
|
||||
|
||||
let user1 = ResponseItem::Message {
|
||||
@@ -9720,7 +9704,7 @@ async fn sample_rollout(
|
||||
};
|
||||
live_history.record_items(
|
||||
std::iter::once(&user1),
|
||||
reconstruction_turn.truncation_policy,
|
||||
reconstruction_turn.model_info.truncation_policy.into(),
|
||||
);
|
||||
rollout_items.push(RolloutItem::ResponseItem(user1.clone()));
|
||||
|
||||
@@ -9735,7 +9719,7 @@ async fn sample_rollout(
|
||||
};
|
||||
live_history.record_items(
|
||||
std::iter::once(&assistant1),
|
||||
reconstruction_turn.truncation_policy,
|
||||
reconstruction_turn.model_info.truncation_policy.into(),
|
||||
);
|
||||
rollout_items.push(RolloutItem::ResponseItem(assistant1.clone()));
|
||||
|
||||
@@ -9763,7 +9747,7 @@ async fn sample_rollout(
|
||||
};
|
||||
live_history.record_items(
|
||||
std::iter::once(&user2),
|
||||
reconstruction_turn.truncation_policy,
|
||||
reconstruction_turn.model_info.truncation_policy.into(),
|
||||
);
|
||||
rollout_items.push(RolloutItem::ResponseItem(user2.clone()));
|
||||
|
||||
@@ -9778,7 +9762,7 @@ async fn sample_rollout(
|
||||
};
|
||||
live_history.record_items(
|
||||
std::iter::once(&assistant2),
|
||||
reconstruction_turn.truncation_policy,
|
||||
reconstruction_turn.model_info.truncation_policy.into(),
|
||||
);
|
||||
rollout_items.push(RolloutItem::ResponseItem(assistant2.clone()));
|
||||
|
||||
@@ -9806,7 +9790,7 @@ async fn sample_rollout(
|
||||
};
|
||||
live_history.record_items(
|
||||
std::iter::once(&user3),
|
||||
reconstruction_turn.truncation_policy,
|
||||
reconstruction_turn.model_info.truncation_policy.into(),
|
||||
);
|
||||
rollout_items.push(RolloutItem::ResponseItem(user3));
|
||||
|
||||
@@ -9821,7 +9805,7 @@ async fn sample_rollout(
|
||||
};
|
||||
live_history.record_items(
|
||||
std::iter::once(&assistant3),
|
||||
reconstruction_turn.truncation_policy,
|
||||
reconstruction_turn.model_info.truncation_policy.into(),
|
||||
);
|
||||
rollout_items.push(RolloutItem::ResponseItem(assistant3));
|
||||
|
||||
|
||||
@@ -95,11 +95,11 @@ async fn request_permissions_routes_to_guardian_when_reviewer_is_enabled() {
|
||||
.approval_policy
|
||||
.set(AskForApproval::OnRequest)
|
||||
.expect("test setup should allow updating approval policy");
|
||||
turn_context_raw
|
||||
let mut config = (*turn_context_raw.config).clone();
|
||||
config
|
||||
.features
|
||||
.enable(Feature::GuardianApproval)
|
||||
.expect("test setup should allow enabling guardian approvals");
|
||||
let mut config = (*turn_context_raw.config).clone();
|
||||
config.approvals_reviewer = ApprovalsReviewer::AutoReview;
|
||||
config.model_provider.base_url = Some(format!("{}/v1", server.uri()));
|
||||
let config = Arc::new(config);
|
||||
@@ -183,11 +183,11 @@ async fn request_permissions_guardian_review_stops_when_cancelled() {
|
||||
.approval_policy
|
||||
.set(AskForApproval::OnRequest)
|
||||
.expect("test setup should allow updating approval policy");
|
||||
turn_context_raw
|
||||
let mut config = (*turn_context_raw.config).clone();
|
||||
config
|
||||
.features
|
||||
.enable(Feature::GuardianApproval)
|
||||
.expect("test setup should allow enabling guardian approvals");
|
||||
let mut config = (*turn_context_raw.config).clone();
|
||||
config.approvals_reviewer = ApprovalsReviewer::AutoReview;
|
||||
config.model_provider.base_url = Some(format!("{}/v1", server.uri()));
|
||||
let config = Arc::new(config);
|
||||
@@ -292,21 +292,21 @@ async fn guardian_allows_shell_command_additional_permissions_requests_past_poli
|
||||
.await;
|
||||
|
||||
let (mut session, mut turn_context_raw) = make_session_and_context().await;
|
||||
turn_context_raw.codex_linux_sandbox_exe = codex_linux_sandbox_exe_or_skip!();
|
||||
turn_context_raw
|
||||
.approval_policy
|
||||
.set(AskForApproval::OnRequest)
|
||||
.expect("test setup should allow updating approval policy");
|
||||
turn_context_raw
|
||||
.features
|
||||
.enable(Feature::GuardianApproval)
|
||||
.expect("test setup should allow enabling guardian approvals");
|
||||
session
|
||||
.features
|
||||
.enable(Feature::ExecPermissionApprovals)
|
||||
.expect("test setup should allow enabling request permissions");
|
||||
turn_context_raw.permission_profile = codex_protocol::models::PermissionProfile::Disabled;
|
||||
let mut config = (*turn_context_raw.config).clone();
|
||||
config.codex_linux_sandbox_exe = codex_linux_sandbox_exe_or_skip!();
|
||||
config
|
||||
.features
|
||||
.enable(Feature::GuardianApproval)
|
||||
.expect("test setup should allow enabling guardian approvals");
|
||||
config.model_provider.base_url = Some(format!("{}/v1", server.uri()));
|
||||
let config = Arc::new(config);
|
||||
let models_manager = models_manager_with_provider(
|
||||
@@ -467,7 +467,7 @@ async fn guardian_allows_unified_exec_additional_permissions_requests_past_polic
|
||||
.approval_policy
|
||||
.set(AskForApproval::OnRequest)
|
||||
.expect("test setup should allow updating approval policy");
|
||||
turn_context_raw
|
||||
Arc::make_mut(&mut turn_context_raw.config)
|
||||
.features
|
||||
.enable(Feature::GuardianApproval)
|
||||
.expect("test setup should allow enabling guardian approvals");
|
||||
|
||||
@@ -11,7 +11,7 @@ pub(super) async fn maybe_record_token_budget_remaining_context(
|
||||
tokens_before_sampling: i64,
|
||||
tokens_after_sampling: i64,
|
||||
) {
|
||||
if !turn_context.features.enabled(Feature::TokenBudget) {
|
||||
if !turn_context.config.features.enabled(Feature::TokenBudget) {
|
||||
return;
|
||||
}
|
||||
let Some(model_context_window) = turn_context.model_context_window() else {
|
||||
|
||||
@@ -177,7 +177,7 @@ pub(crate) async fn run_turn(
|
||||
.await;
|
||||
sess.set_previous_turn_settings(Some(PreviousTurnSettings {
|
||||
model: turn_context.model_info.slug.clone(),
|
||||
comp_hash: turn_context.comp_hash.clone(),
|
||||
comp_hash: turn_context.model_info.comp_hash.clone(),
|
||||
realtime_active: Some(turn_context.realtime_active),
|
||||
}))
|
||||
.await;
|
||||
@@ -840,7 +840,7 @@ async fn maybe_run_previous_model_inline_compact(
|
||||
};
|
||||
let should_compact_for_comp_hash_change = comp_hash_changed(
|
||||
previous_turn_settings.comp_hash.as_deref(),
|
||||
turn_context.comp_hash.as_deref(),
|
||||
turn_context.model_info.comp_hash.as_deref(),
|
||||
);
|
||||
let previous_model_turn_context = Arc::new(
|
||||
turn_context
|
||||
@@ -913,7 +913,11 @@ async fn run_auto_compact(
|
||||
phase: CompactionPhase,
|
||||
) -> CodexResult<()> {
|
||||
if should_use_remote_compact_task(turn_context.provider.info()) {
|
||||
if turn_context.features.enabled(Feature::RemoteCompactionV2) {
|
||||
if turn_context
|
||||
.config
|
||||
.features
|
||||
.enabled(Feature::RemoteCompactionV2)
|
||||
{
|
||||
emit_compact_metric(
|
||||
&sess.services.session_telemetry,
|
||||
"remote_v2",
|
||||
@@ -1025,7 +1029,6 @@ pub(crate) fn build_prompt(
|
||||
tools: router.model_visible_specs(),
|
||||
parallel_tool_calls: turn_context.model_info.supports_parallel_tool_calls,
|
||||
base_instructions,
|
||||
personality: turn_context.personality,
|
||||
output_schema: turn_context.final_output_json_schema.clone(),
|
||||
output_schema_strict: !crate::guardian::is_guardian_reviewer_source(
|
||||
&turn_context.session_source,
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
use super::*;
|
||||
use crate::SkillLoadOutcome;
|
||||
use crate::agents_md::LoadedAgentsMd;
|
||||
use crate::config::GhostSnapshotConfig;
|
||||
use crate::environment_selection::TurnEnvironmentSnapshot;
|
||||
use crate::shell_snapshot::ShellSnapshotFile;
|
||||
use codex_core_skills::HostLoadedSkills;
|
||||
@@ -12,9 +11,7 @@ use codex_protocol::SessionId;
|
||||
use codex_protocol::ThreadId;
|
||||
use codex_protocol::models::AdditionalPermissionProfile;
|
||||
use codex_protocol::openai_models::ModelInfo;
|
||||
use codex_protocol::openai_models::ToolMode;
|
||||
use codex_protocol::protocol::MultiAgentVersion;
|
||||
use codex_protocol::protocol::ThreadSource;
|
||||
use codex_protocol::protocol::TurnEnvironmentSelection;
|
||||
use codex_sandboxing::compatibility_sandbox_policy_for_permission_profile;
|
||||
use codex_sandboxing::policy_transforms::effective_file_system_sandbox_policy;
|
||||
@@ -111,15 +108,12 @@ pub struct TurnContext {
|
||||
pub config: Arc<Config>,
|
||||
pub(crate) auth_manager: Option<Arc<AuthManager>>,
|
||||
pub(crate) model_info: ModelInfo,
|
||||
pub(crate) comp_hash: Option<String>,
|
||||
pub(crate) tool_mode: ToolMode,
|
||||
pub(crate) session_telemetry: SessionTelemetry,
|
||||
pub(crate) provider: SharedModelProvider,
|
||||
pub(crate) reasoning_effort: Option<ReasoningEffortConfig>,
|
||||
pub(crate) reasoning_summary: ReasoningSummaryConfig,
|
||||
pub(crate) session_source: SessionSource,
|
||||
pub(crate) parent_thread_id: Option<ThreadId>,
|
||||
pub(crate) thread_source: Option<ThreadSource>,
|
||||
pub(crate) environments: TurnEnvironmentSnapshot,
|
||||
/// The session's absolute working directory. All relative paths provided
|
||||
/// by the model as well as sandbox policies are resolved against this path
|
||||
@@ -130,7 +124,6 @@ pub struct TurnContext {
|
||||
pub(crate) timezone: Option<String>,
|
||||
pub(crate) app_server_client_name: Option<String>,
|
||||
pub(crate) developer_instructions: Option<String>,
|
||||
pub(crate) compact_prompt: Option<String>,
|
||||
pub(crate) user_instructions: Option<String>,
|
||||
pub(crate) collaboration_mode: CollaborationMode,
|
||||
pub(crate) multi_agent_version: MultiAgentVersion,
|
||||
@@ -139,15 +132,9 @@ pub struct TurnContext {
|
||||
pub(crate) permission_profile: PermissionProfile,
|
||||
pub(crate) network: Option<NetworkProxy>,
|
||||
pub(crate) windows_sandbox_level: WindowsSandboxLevel,
|
||||
pub(crate) shell_environment_policy: ShellEnvironmentPolicy,
|
||||
pub(crate) available_models: Vec<ModelPreset>,
|
||||
pub(crate) unified_exec_shell_mode: UnifiedExecShellMode,
|
||||
pub features: ManagedFeatures,
|
||||
pub(crate) ghost_snapshot: GhostSnapshotConfig,
|
||||
pub(crate) final_output_json_schema: Option<Value>,
|
||||
pub(crate) codex_self_exe: Option<PathBuf>,
|
||||
pub(crate) codex_linux_sandbox_exe: Option<PathBuf>,
|
||||
pub(crate) truncation_policy: TruncationPolicy,
|
||||
pub(crate) dynamic_tools: Vec<DynamicToolSpec>,
|
||||
pub(crate) turn_metadata_state: Arc<TurnMetadataState>,
|
||||
pub(crate) extension_data: Arc<codex_extension_api::ExtensionData>,
|
||||
@@ -214,7 +201,9 @@ impl TurnContext {
|
||||
.auth_manager
|
||||
.as_deref()
|
||||
.is_some_and(AuthManager::current_auth_uses_codex_backend);
|
||||
self.features.apps_enabled_for_auth(uses_codex_backend)
|
||||
self.config
|
||||
.features
|
||||
.apps_enabled_for_auth(uses_codex_backend)
|
||||
}
|
||||
|
||||
pub(crate) fn tool_environment_mode(&self) -> ToolEnvironmentMode {
|
||||
@@ -231,16 +220,6 @@ impl TurnContext {
|
||||
let model_info = models_manager
|
||||
.get_model_info(model.as_str(), &config.to_models_manager_config())
|
||||
.await;
|
||||
let tool_mode = model_info.tool_mode.unwrap_or_else(|| {
|
||||
if config.features.enabled(Feature::CodeModeOnly) {
|
||||
ToolMode::CodeModeOnly
|
||||
} else if config.features.enabled(Feature::CodeMode) {
|
||||
ToolMode::CodeMode
|
||||
} else {
|
||||
ToolMode::Direct
|
||||
}
|
||||
});
|
||||
let truncation_policy = model_info.truncation_policy.into();
|
||||
let supported_reasoning_levels = model_info
|
||||
.supported_reasoning_levels
|
||||
.iter()
|
||||
@@ -269,7 +248,6 @@ impl TurnContext {
|
||||
Some(reasoning_effort.clone()),
|
||||
/*developer_instructions*/ None,
|
||||
);
|
||||
let features = self.features.clone();
|
||||
let available_models = models_manager
|
||||
.list_models(RefreshStrategy::OnlineIfUncached)
|
||||
.await;
|
||||
@@ -281,8 +259,6 @@ impl TurnContext {
|
||||
config: Arc::new(config),
|
||||
auth_manager: self.auth_manager.clone(),
|
||||
model_info: model_info.clone(),
|
||||
comp_hash: model_info.comp_hash.clone(),
|
||||
tool_mode,
|
||||
session_telemetry: self
|
||||
.session_telemetry
|
||||
.clone()
|
||||
@@ -292,7 +268,6 @@ impl TurnContext {
|
||||
reasoning_summary: self.reasoning_summary,
|
||||
session_source: self.session_source.clone(),
|
||||
parent_thread_id: self.parent_thread_id,
|
||||
thread_source: self.thread_source.clone(),
|
||||
environments: self.environments.clone(),
|
||||
#[allow(deprecated)]
|
||||
cwd: self.cwd.clone(),
|
||||
@@ -300,7 +275,6 @@ impl TurnContext {
|
||||
timezone: self.timezone.clone(),
|
||||
app_server_client_name: self.app_server_client_name.clone(),
|
||||
developer_instructions: self.developer_instructions.clone(),
|
||||
compact_prompt: self.compact_prompt.clone(),
|
||||
user_instructions: self.user_instructions.clone(),
|
||||
collaboration_mode,
|
||||
multi_agent_version: self.multi_agent_version,
|
||||
@@ -309,15 +283,9 @@ impl TurnContext {
|
||||
permission_profile: self.permission_profile.clone(),
|
||||
network: self.network.clone(),
|
||||
windows_sandbox_level: self.windows_sandbox_level,
|
||||
shell_environment_policy: self.shell_environment_policy.clone(),
|
||||
available_models,
|
||||
unified_exec_shell_mode: self.unified_exec_shell_mode.clone(),
|
||||
features,
|
||||
ghost_snapshot: self.ghost_snapshot.clone(),
|
||||
final_output_json_schema: self.final_output_json_schema.clone(),
|
||||
codex_self_exe: self.codex_self_exe.clone(),
|
||||
codex_linux_sandbox_exe: self.codex_linux_sandbox_exe.clone(),
|
||||
truncation_policy,
|
||||
dynamic_tools: self.dynamic_tools.clone(),
|
||||
turn_metadata_state: self.turn_metadata_state.clone(),
|
||||
extension_data: Arc::clone(&self.extension_data),
|
||||
@@ -368,7 +336,7 @@ impl TurnContext {
|
||||
.config
|
||||
.permissions
|
||||
.windows_sandbox_private_desktop,
|
||||
use_legacy_landlock: self.features.use_legacy_landlock(),
|
||||
use_legacy_landlock: self.config.features.use_legacy_landlock(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -388,12 +356,6 @@ impl TurnContext {
|
||||
.then_some(file_system_sandbox_policy)
|
||||
}
|
||||
|
||||
pub(crate) fn compact_prompt(&self) -> &str {
|
||||
self.compact_prompt
|
||||
.as_deref()
|
||||
.unwrap_or(compact::SUMMARIZATION_PROMPT)
|
||||
}
|
||||
|
||||
pub(crate) fn to_turn_context_item(&self) -> TurnContextItem {
|
||||
let workspace_roots = self.config.effective_workspace_roots();
|
||||
#[allow(deprecated)]
|
||||
@@ -410,7 +372,7 @@ impl TurnContext {
|
||||
network: self.turn_context_network_item(),
|
||||
file_system_sandbox_policy: self.non_legacy_file_system_sandbox_policy(),
|
||||
model: self.model_info.slug.clone(),
|
||||
comp_hash: self.comp_hash.clone(),
|
||||
comp_hash: self.model_info.comp_hash.clone(),
|
||||
personality: self.personality,
|
||||
collaboration_mode: Some(self.collaboration_mode.clone()),
|
||||
multi_agent_version: Some(self.multi_agent_version),
|
||||
@@ -549,15 +511,6 @@ impl Session {
|
||||
);
|
||||
|
||||
let mut per_turn_config = per_turn_config;
|
||||
let tool_mode = model_info.tool_mode.unwrap_or_else(|| {
|
||||
if per_turn_config.features.enabled(Feature::CodeModeOnly) {
|
||||
ToolMode::CodeModeOnly
|
||||
} else if per_turn_config.features.enabled(Feature::CodeMode) {
|
||||
ToolMode::CodeMode
|
||||
} else {
|
||||
ToolMode::Direct
|
||||
}
|
||||
});
|
||||
per_turn_config.service_tier = get_service_tier(
|
||||
per_turn_config.service_tier,
|
||||
per_turn_config.features.enabled(Feature::FastMode),
|
||||
@@ -583,18 +536,15 @@ impl Session {
|
||||
sub_id,
|
||||
trace_id: current_span_trace_id(),
|
||||
realtime_active: false,
|
||||
config: per_turn_config.clone(),
|
||||
config: per_turn_config,
|
||||
auth_manager: auth_manager_for_context,
|
||||
model_info: model_info.clone(),
|
||||
comp_hash: model_info.comp_hash.clone(),
|
||||
tool_mode,
|
||||
model_info,
|
||||
session_telemetry: session_telemetry_for_context,
|
||||
provider: provider_for_context,
|
||||
reasoning_effort,
|
||||
reasoning_summary,
|
||||
session_source,
|
||||
parent_thread_id: session_configuration.parent_thread_id,
|
||||
thread_source: session_configuration.thread_source.clone(),
|
||||
environments,
|
||||
#[allow(deprecated)]
|
||||
cwd,
|
||||
@@ -602,7 +552,6 @@ impl Session {
|
||||
timezone: Some(timezone),
|
||||
app_server_client_name: session_configuration.app_server_client_name.clone(),
|
||||
developer_instructions: session_configuration.developer_instructions.clone(),
|
||||
compact_prompt: session_configuration.compact_prompt.clone(),
|
||||
user_instructions: session_configuration
|
||||
.loaded_agents_md
|
||||
.as_ref()
|
||||
@@ -614,15 +563,9 @@ impl Session {
|
||||
permission_profile: session_configuration.permission_profile(),
|
||||
network,
|
||||
windows_sandbox_level: session_configuration.windows_sandbox_level,
|
||||
shell_environment_policy: per_turn_config.permissions.shell_environment_policy.clone(),
|
||||
available_models,
|
||||
unified_exec_shell_mode,
|
||||
features: per_turn_config.features.clone(),
|
||||
ghost_snapshot: per_turn_config.ghost_snapshot.clone(),
|
||||
final_output_json_schema: None,
|
||||
codex_self_exe: per_turn_config.codex_self_exe.clone(),
|
||||
codex_linux_sandbox_exe: per_turn_config.codex_linux_sandbox_exe.clone(),
|
||||
truncation_policy: model_info.truncation_policy.into(),
|
||||
dynamic_tools: session_configuration.dynamic_tools.clone(),
|
||||
turn_metadata_state,
|
||||
extension_data,
|
||||
|
||||
@@ -31,6 +31,7 @@ impl SessionTask for CompactTask {
|
||||
let session = session.clone_session();
|
||||
let _ = if crate::compact::should_use_remote_compact_task(ctx.provider.info()) {
|
||||
if ctx
|
||||
.config
|
||||
.features
|
||||
.enabled(codex_features::Feature::RemoteCompactionV2)
|
||||
{
|
||||
@@ -55,7 +56,12 @@ impl SessionTask for CompactTask {
|
||||
/*manual*/ true,
|
||||
);
|
||||
let input = vec![UserInput::Text {
|
||||
text: ctx.compact_prompt().to_string(),
|
||||
text: ctx
|
||||
.config
|
||||
.compact_prompt
|
||||
.as_deref()
|
||||
.unwrap_or(crate::compact::SUMMARIZATION_PROMPT)
|
||||
.to_string(),
|
||||
// Compaction prompt is synthesized; no UI element ranges to preserve.
|
||||
text_elements: Vec::new(),
|
||||
}];
|
||||
|
||||
@@ -722,7 +722,7 @@ impl Session {
|
||||
}
|
||||
emit_turn_memory_metric(
|
||||
&self.services.session_telemetry,
|
||||
turn_context.features.enabled(Feature::MemoryTool),
|
||||
turn_context.config.features.enabled(Feature::MemoryTool),
|
||||
turn_context.config.memories.use_memories,
|
||||
turn_had_memory_citation,
|
||||
);
|
||||
|
||||
@@ -157,7 +157,7 @@ pub(crate) async fn execute_user_shell_command(
|
||||
};
|
||||
let shell_snapshot_location = turn_environment.shell_snapshot(&cwd);
|
||||
let mut exec_env_map = create_env(
|
||||
&turn_context.shell_environment_policy,
|
||||
&turn_context.config.permissions.shell_environment_policy,
|
||||
Some(session.thread_id),
|
||||
);
|
||||
if exec_env_map.contains_key(PROXY_ACTIVE_ENV_KEY) {
|
||||
@@ -167,7 +167,11 @@ pub(crate) async fn execute_user_shell_command(
|
||||
&display_command,
|
||||
environment_shell,
|
||||
shell_snapshot_location.as_ref(),
|
||||
&turn_context.shell_environment_policy.r#set,
|
||||
&turn_context
|
||||
.config
|
||||
.permissions
|
||||
.shell_environment_policy
|
||||
.r#set,
|
||||
&mut exec_env_map,
|
||||
);
|
||||
|
||||
@@ -294,7 +298,7 @@ pub(crate) async fn execute_user_shell_command(
|
||||
duration: output.duration,
|
||||
formatted_output: format_exec_output_str(
|
||||
&output,
|
||||
turn_context.truncation_policy,
|
||||
turn_context.model_info.truncation_policy.into(),
|
||||
),
|
||||
status: if output.exit_code == 0 {
|
||||
ExecCommandStatus::Completed
|
||||
@@ -339,7 +343,7 @@ pub(crate) async fn execute_user_shell_command(
|
||||
duration: exec_output.duration,
|
||||
formatted_output: format_exec_output_str(
|
||||
&exec_output,
|
||||
turn_context.truncation_policy,
|
||||
turn_context.model_info.truncation_policy.into(),
|
||||
),
|
||||
status: ExecCommandStatus::Failed,
|
||||
}),
|
||||
|
||||
@@ -26,6 +26,7 @@ use crate::tools::ToolRouter;
|
||||
use crate::tools::context::FunctionToolOutput;
|
||||
use crate::tools::context::SharedTurnDiffTracker;
|
||||
use crate::tools::context::ToolPayload;
|
||||
use crate::tools::effective_tool_mode;
|
||||
use crate::tools::parallel::ToolCallRuntime;
|
||||
use crate::tools::router::ToolCall;
|
||||
use crate::tools::router::ToolCallSource;
|
||||
@@ -116,7 +117,8 @@ impl CodeModeService {
|
||||
router: Arc<ToolRouter>,
|
||||
tracker: SharedTurnDiffTracker,
|
||||
) -> Option<CodeModeDispatchWorker> {
|
||||
if !matches!(turn.tool_mode, ToolMode::CodeMode | ToolMode::CodeModeOnly)
|
||||
let tool_mode = effective_tool_mode(turn);
|
||||
if !matches!(tool_mode, ToolMode::CodeMode | ToolMode::CodeModeOnly)
|
||||
|| self.session.is_none()
|
||||
{
|
||||
return None;
|
||||
|
||||
@@ -346,7 +346,7 @@ impl ToolEmitter {
|
||||
output: &ExecToolCallOutput,
|
||||
ctx: ToolEventCtx<'_>,
|
||||
) -> String {
|
||||
super::format_exec_output_for_model(output, ctx.turn.truncation_policy)
|
||||
super::format_exec_output_for_model(output, ctx.turn.model_info.truncation_policy.into())
|
||||
}
|
||||
|
||||
pub async fn finish(
|
||||
@@ -495,7 +495,10 @@ async fn emit_exec_stage(
|
||||
aggregated_output: output.aggregated_output.text.clone(),
|
||||
exit_code: output.exit_code,
|
||||
duration: output.duration,
|
||||
formatted_output: format_exec_output_str(&output, ctx.turn.truncation_policy),
|
||||
formatted_output: format_exec_output_str(
|
||||
&output,
|
||||
ctx.turn.model_info.truncation_policy.into(),
|
||||
),
|
||||
status: if output.exit_code == 0 {
|
||||
ExecCommandStatus::Completed
|
||||
} else {
|
||||
|
||||
@@ -82,7 +82,11 @@ impl ToolArgumentDiffConsumer for ApplyPatchArgumentDiffConsumer {
|
||||
call_id: String,
|
||||
diff: &str,
|
||||
) -> Option<EventMsg> {
|
||||
if !turn.features.enabled(Feature::ApplyPatchStreamingEvents) {
|
||||
if !turn
|
||||
.config
|
||||
.features
|
||||
.enabled(Feature::ApplyPatchStreamingEvents)
|
||||
{
|
||||
return None;
|
||||
}
|
||||
|
||||
|
||||
@@ -143,7 +143,7 @@ async fn to_extension_call(invocation: &ToolInvocation) -> ExtensionToolCall {
|
||||
call_id: invocation.call_id.clone(),
|
||||
tool_name: invocation.tool_name.clone(),
|
||||
model: invocation.turn.model_info.slug.clone(),
|
||||
truncation_policy: invocation.turn.truncation_policy,
|
||||
truncation_policy: invocation.turn.model_info.truncation_policy.into(),
|
||||
conversation_history,
|
||||
turn_item_emitter: Arc::new(CoreTurnItemEmitter {
|
||||
session: Arc::downgrade(&invocation.session),
|
||||
@@ -315,7 +315,7 @@ mod tests {
|
||||
let weak_turn = Arc::downgrade(&turn);
|
||||
let turn_id = turn.sub_id.clone();
|
||||
let model = turn.model_info.slug.clone();
|
||||
let truncation_policy = turn.truncation_policy;
|
||||
let truncation_policy = turn.model_info.truncation_policy.into();
|
||||
let expected_sandbox_cwds = turn
|
||||
.environments
|
||||
.turn_environments
|
||||
|
||||
@@ -156,7 +156,7 @@ impl McpHandler {
|
||||
tool_input: result.tool_input,
|
||||
wall_time: started.elapsed(),
|
||||
original_image_detail_supported: can_request_original_image_detail(&turn.model_info),
|
||||
truncation_policy: turn.truncation_policy,
|
||||
truncation_policy: turn.model_info.truncation_policy.into(),
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,9 +115,10 @@ impl ListMcpResourceTemplatesHandler {
|
||||
}
|
||||
}
|
||||
.await;
|
||||
let truncation_policy = turn.model_info.truncation_policy.into();
|
||||
|
||||
match payload_result {
|
||||
Ok(payload) => match serialize_function_output(payload, turn.truncation_policy) {
|
||||
Ok(payload) => match serialize_function_output(payload, truncation_policy) {
|
||||
Ok(output) => {
|
||||
let content = function_call_output_content_items_to_text(&output.body)
|
||||
.unwrap_or_default();
|
||||
|
||||
@@ -113,9 +113,10 @@ impl ListMcpResourcesHandler {
|
||||
}
|
||||
}
|
||||
.await;
|
||||
let truncation_policy = turn.model_info.truncation_policy.into();
|
||||
|
||||
match payload_result {
|
||||
Ok(payload) => match serialize_function_output(payload, turn.truncation_policy) {
|
||||
Ok(payload) => match serialize_function_output(payload, truncation_policy) {
|
||||
Ok(output) => {
|
||||
let content = function_call_output_content_items_to_text(&output.body)
|
||||
.unwrap_or_default();
|
||||
|
||||
@@ -96,9 +96,10 @@ impl ReadMcpResourceHandler {
|
||||
})
|
||||
}
|
||||
.await;
|
||||
let truncation_policy = turn.model_info.truncation_policy.into();
|
||||
|
||||
match payload_result {
|
||||
Ok(payload) => match serialize_function_output(payload, turn.truncation_policy) {
|
||||
Ok(payload) => match serialize_function_output(payload, truncation_policy) {
|
||||
Ok(output) => {
|
||||
let content = function_call_output_content_items_to_text(&output.body)
|
||||
.unwrap_or_default();
|
||||
|
||||
@@ -228,7 +228,6 @@ fn build_agent_shared_config(turn: &TurnContext) -> Result<Config, FunctionCallE
|
||||
.or_else(|| turn.model_info.default_reasoning_level.clone());
|
||||
config.model_reasoning_summary = Some(turn.reasoning_summary);
|
||||
config.developer_instructions = turn.developer_instructions.clone();
|
||||
config.compact_prompt = turn.compact_prompt.clone();
|
||||
apply_spawn_agent_runtime_overrides(&mut config, turn)?;
|
||||
|
||||
Ok(config)
|
||||
@@ -263,8 +262,6 @@ pub(crate) fn apply_spawn_agent_runtime_overrides(
|
||||
FunctionCallError::RespondToModel(format!("approval_policy is invalid: {err}"))
|
||||
})?;
|
||||
config.approvals_reviewer = turn.config.approvals_reviewer;
|
||||
config.permissions.shell_environment_policy = turn.shell_environment_policy.clone();
|
||||
config.codex_linux_sandbox_exe = turn.codex_linux_sandbox_exe.clone();
|
||||
#[allow(deprecated)]
|
||||
let turn_cwd = turn.cwd.clone();
|
||||
config.cwd = turn_cwd;
|
||||
|
||||
@@ -4467,17 +4467,19 @@ async fn build_agent_spawn_config_uses_turn_context_values() {
|
||||
text: "base".to_string(),
|
||||
};
|
||||
turn.developer_instructions = Some("dev".to_string());
|
||||
turn.compact_prompt = Some("compact".to_string());
|
||||
turn.shell_environment_policy = ShellEnvironmentPolicy {
|
||||
let mut config = (*turn.config).clone();
|
||||
config.compact_prompt = Some("compact".to_string());
|
||||
config.permissions.shell_environment_policy = ShellEnvironmentPolicy {
|
||||
use_profile: true,
|
||||
..ShellEnvironmentPolicy::default()
|
||||
};
|
||||
config.codex_linux_sandbox_exe = Some(PathBuf::from("/bin/echo"));
|
||||
turn.config = Arc::new(config);
|
||||
let temp_dir = tempfile::tempdir().expect("temp dir");
|
||||
#[allow(deprecated)]
|
||||
{
|
||||
turn.cwd = temp_dir.abs();
|
||||
}
|
||||
turn.codex_linux_sandbox_exe = Some(PathBuf::from("/bin/echo"));
|
||||
#[allow(deprecated)]
|
||||
let turn_cwd = turn.cwd.clone();
|
||||
let sandbox_policy = pick_allowed_sandbox_policy(
|
||||
@@ -4506,9 +4508,6 @@ async fn build_agent_spawn_config_uses_turn_context_values() {
|
||||
expected.model_reasoning_effort = turn.reasoning_effort.clone();
|
||||
expected.model_reasoning_summary = Some(turn.reasoning_summary);
|
||||
expected.developer_instructions = turn.developer_instructions.clone();
|
||||
expected.compact_prompt = turn.compact_prompt.clone();
|
||||
expected.permissions.shell_environment_policy = turn.shell_environment_policy.clone();
|
||||
expected.codex_linux_sandbox_exe = turn.codex_linux_sandbox_exe.clone();
|
||||
#[allow(deprecated)]
|
||||
{
|
||||
expected.cwd = turn.cwd.clone();
|
||||
@@ -4544,9 +4543,6 @@ async fn build_agent_resume_config_clears_base_instructions() {
|
||||
expected.model_reasoning_effort = turn.reasoning_effort.clone();
|
||||
expected.model_reasoning_summary = Some(turn.reasoning_summary);
|
||||
expected.developer_instructions = turn.developer_instructions.clone();
|
||||
expected.compact_prompt = turn.compact_prompt.clone();
|
||||
expected.permissions.shell_environment_policy = turn.shell_environment_policy.clone();
|
||||
expected.codex_linux_sandbox_exe = turn.codex_linux_sandbox_exe.clone();
|
||||
#[allow(deprecated)]
|
||||
{
|
||||
expected.cwd = turn.cwd.clone();
|
||||
|
||||
@@ -80,7 +80,12 @@ async fn run_exec_like(args: RunExecLikeArgs) -> Result<FunctionToolOutput, Func
|
||||
};
|
||||
let fs = turn_environment.environment.get_filesystem();
|
||||
|
||||
let explicit_env_overrides = turn.shell_environment_policy.r#set.clone();
|
||||
let explicit_env_overrides = turn
|
||||
.config
|
||||
.permissions
|
||||
.shell_environment_policy
|
||||
.r#set
|
||||
.clone();
|
||||
let exec_permission_approvals_enabled =
|
||||
session.features().enabled(Feature::ExecPermissionApprovals);
|
||||
let requested_additional_permissions = additional_permissions.clone();
|
||||
@@ -223,7 +228,9 @@ async fn run_exec_like(args: RunExecLikeArgs) -> Result<FunctionToolOutput, Func
|
||||
let post_tool_use_response = out
|
||||
.as_ref()
|
||||
.ok()
|
||||
.map(|output| crate::tools::format_exec_output_str(output, turn.truncation_policy))
|
||||
.map(|output| {
|
||||
crate::tools::format_exec_output_str(output, turn.model_info.truncation_policy.into())
|
||||
})
|
||||
.map(JsonValue::String);
|
||||
let content = emitter
|
||||
.finish(event_ctx, out, /*applied_patch_delta*/ None)
|
||||
|
||||
@@ -100,7 +100,10 @@ impl ShellCommandHandler {
|
||||
cwd,
|
||||
expiration: params.timeout_ms.into(),
|
||||
capture_policy: ExecCapturePolicy::ShellTool,
|
||||
env: create_env(&turn_context.shell_environment_policy, Some(thread_id)),
|
||||
env: create_env(
|
||||
&turn_context.config.permissions.shell_environment_policy,
|
||||
Some(thread_id),
|
||||
),
|
||||
network: turn_context.network.clone(),
|
||||
sandbox_permissions: params.sandbox_permissions.unwrap_or_default(),
|
||||
windows_sandbox_level: turn_context.windows_sandbox_level,
|
||||
|
||||
@@ -83,7 +83,7 @@ async fn shell_command_handler_to_exec_params_uses_session_shell_and_turn_contex
|
||||
#[allow(deprecated)]
|
||||
let expected_cwd = turn_context.resolve_path(workdir.clone());
|
||||
let expected_env = create_env(
|
||||
&turn_context.shell_environment_policy,
|
||||
&turn_context.config.permissions.shell_environment_policy,
|
||||
Some(session.thread_id),
|
||||
);
|
||||
|
||||
|
||||
@@ -265,7 +265,7 @@ impl ExecCommandHandler {
|
||||
chunk_id: String::new(),
|
||||
wall_time: std::time::Duration::ZERO,
|
||||
raw_output: output.into_text().into_bytes(),
|
||||
truncation_policy: turn.truncation_policy,
|
||||
truncation_policy: turn.model_info.truncation_policy.into(),
|
||||
max_output_tokens,
|
||||
process_id: None,
|
||||
exit_code: None,
|
||||
@@ -310,7 +310,7 @@ impl ExecCommandHandler {
|
||||
chunk_id: generate_chunk_id(),
|
||||
wall_time: output.duration,
|
||||
raw_output: output_text.into_bytes(),
|
||||
truncation_policy: turn.truncation_policy,
|
||||
truncation_policy: turn.model_info.truncation_policy.into(),
|
||||
max_output_tokens,
|
||||
// Sandbox denial is terminal, so there is no live
|
||||
// process for write_stdin to resume.
|
||||
|
||||
@@ -75,7 +75,7 @@ impl WriteStdinHandler {
|
||||
input: &args.chars,
|
||||
yield_time_ms: args.yield_time_ms,
|
||||
max_output_tokens: args.max_output_tokens,
|
||||
truncation_policy: turn.truncation_policy,
|
||||
truncation_policy: turn.model_info.truncation_policy.into(),
|
||||
})
|
||||
.await
|
||||
.map_err(|err| {
|
||||
|
||||
@@ -195,7 +195,7 @@ impl ViewImageHandler {
|
||||
DEFAULT_IMAGE_DETAIL
|
||||
};
|
||||
|
||||
let image_url = if turn.features.enabled(Feature::ResizeAllImages) {
|
||||
let image_url = if turn.config.features.enabled(Feature::ResizeAllImages) {
|
||||
// The history insertion path owns image decoding and resizing when this is enabled.
|
||||
data_url_from_bytes("application/octet-stream", &file_bytes)
|
||||
} else {
|
||||
|
||||
@@ -17,7 +17,10 @@ pub(crate) mod tool_dispatch_trace;
|
||||
|
||||
use std::borrow::Cow;
|
||||
|
||||
use crate::session::turn_context::TurnContext;
|
||||
use codex_features::Feature;
|
||||
use codex_protocol::exec_output::ExecToolCallOutput;
|
||||
use codex_protocol::openai_models::ToolMode;
|
||||
use codex_tools::ToolName;
|
||||
use codex_utils_output_truncation::TruncationPolicy;
|
||||
use codex_utils_output_truncation::formatted_truncate_text;
|
||||
@@ -57,6 +60,18 @@ pub(crate) fn tool_user_shell_type(
|
||||
}
|
||||
}
|
||||
|
||||
fn effective_tool_mode(turn_context: &TurnContext) -> ToolMode {
|
||||
turn_context.model_info.tool_mode.unwrap_or_else(|| {
|
||||
if turn_context.config.features.enabled(Feature::CodeModeOnly) {
|
||||
ToolMode::CodeModeOnly
|
||||
} else if turn_context.config.features.enabled(Feature::CodeMode) {
|
||||
ToolMode::CodeMode
|
||||
} else {
|
||||
ToolMode::Direct
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// Format the combined exec output for sending back to the model.
|
||||
/// Includes exit code and duration metadata; truncates large bodies safely.
|
||||
pub fn format_exec_output_for_model(
|
||||
|
||||
@@ -237,7 +237,7 @@ impl ToolOrchestrator {
|
||||
};
|
||||
|
||||
// Platform-specific flag gating is handled by SandboxManager::select_initial.
|
||||
let use_legacy_landlock = turn_ctx.features.use_legacy_landlock();
|
||||
let use_legacy_landlock = turn_ctx.config.features.use_legacy_landlock();
|
||||
#[allow(deprecated)]
|
||||
let sandbox_cwd = tool.sandbox_cwd(req).unwrap_or(&turn_ctx.cwd);
|
||||
let sandbox_policy_cwd = PathUri::from_abs_path(sandbox_cwd);
|
||||
@@ -249,7 +249,7 @@ impl ToolOrchestrator {
|
||||
manager: &self.sandbox,
|
||||
sandbox_cwd: &sandbox_policy_cwd,
|
||||
workspace_roots: workspace_roots.as_slice(),
|
||||
codex_linux_sandbox_exe: turn_ctx.codex_linux_sandbox_exe.as_ref(),
|
||||
codex_linux_sandbox_exe: turn_ctx.config.codex_linux_sandbox_exe.as_ref(),
|
||||
use_legacy_landlock,
|
||||
windows_sandbox_level: turn_ctx.windows_sandbox_level,
|
||||
windows_sandbox_private_desktop: turn_ctx
|
||||
@@ -413,7 +413,7 @@ impl ToolOrchestrator {
|
||||
let retry_codex_linux_sandbox_exe = if unsandboxed_allowed {
|
||||
None
|
||||
} else {
|
||||
turn_ctx.codex_linux_sandbox_exe.as_ref()
|
||||
turn_ctx.config.codex_linux_sandbox_exe.as_ref()
|
||||
};
|
||||
let retry_attempt = SandboxAttempt {
|
||||
sandbox: retry_sandbox,
|
||||
|
||||
@@ -185,8 +185,8 @@ pub(super) async fn try_run_zsh_fork(
|
||||
arg0,
|
||||
sandbox_policy_cwd,
|
||||
windows_sandbox_workspace_roots,
|
||||
codex_linux_sandbox_exe: ctx.turn.codex_linux_sandbox_exe.clone(),
|
||||
use_legacy_landlock: ctx.turn.features.use_legacy_landlock(),
|
||||
codex_linux_sandbox_exe: ctx.turn.config.codex_linux_sandbox_exe.clone(),
|
||||
use_legacy_landlock: ctx.turn.config.features.use_legacy_landlock(),
|
||||
};
|
||||
let main_execve_wrapper_exe = ctx
|
||||
.session
|
||||
@@ -286,8 +286,8 @@ pub(crate) async fn prepare_unified_exec_zsh_fork(
|
||||
arg0: exec_request.arg0.clone(),
|
||||
sandbox_policy_cwd: exec_request.windows_sandbox_policy_cwd.clone(),
|
||||
windows_sandbox_workspace_roots: exec_request.windows_sandbox_workspace_roots.clone(),
|
||||
codex_linux_sandbox_exe: ctx.turn.codex_linux_sandbox_exe.clone(),
|
||||
use_legacy_landlock: ctx.turn.features.use_legacy_landlock(),
|
||||
codex_linux_sandbox_exe: ctx.turn.config.codex_linux_sandbox_exe.clone(),
|
||||
use_legacy_landlock: ctx.turn.config.features.use_legacy_landlock(),
|
||||
};
|
||||
let escalation_policy = CoreShellActionProvider {
|
||||
policy: Arc::clone(&exec_policy),
|
||||
|
||||
@@ -3,6 +3,7 @@ use crate::agent::next_thread_spawn_depth;
|
||||
use crate::session::turn_context::TurnContext;
|
||||
use crate::tools::code_mode::execute_spec::create_code_mode_tool;
|
||||
use crate::tools::context::ToolInvocation;
|
||||
use crate::tools::effective_tool_mode;
|
||||
use crate::tools::handlers::ApplyPatchHandler;
|
||||
use crate::tools::handlers::CodeModeExecuteHandler;
|
||||
use crate::tools::handlers::CodeModeWaitHandler;
|
||||
@@ -243,10 +244,9 @@ fn spec_for_model_request(
|
||||
tool_name: &ToolName,
|
||||
spec: ToolSpec,
|
||||
) -> ToolSpec {
|
||||
if matches!(
|
||||
turn_context.tool_mode,
|
||||
ToolMode::CodeMode | ToolMode::CodeModeOnly
|
||||
) && exposure != ToolExposure::DirectModelOnly
|
||||
let tool_mode = effective_tool_mode(turn_context);
|
||||
if matches!(tool_mode, ToolMode::CodeMode | ToolMode::CodeModeOnly)
|
||||
&& exposure != ToolExposure::DirectModelOnly
|
||||
&& !is_excluded_from_code_mode(turn_context, tool_name)
|
||||
&& codex_code_mode::is_code_mode_nested_tool(spec.name())
|
||||
{
|
||||
@@ -298,7 +298,7 @@ pub(crate) fn search_tool_enabled(turn_context: &TurnContext) -> bool {
|
||||
}
|
||||
|
||||
pub(crate) fn tool_suggest_enabled(turn_context: &TurnContext) -> bool {
|
||||
let features = turn_context.features.get();
|
||||
let features = turn_context.config.features.get();
|
||||
features.enabled(Feature::ToolSuggest)
|
||||
&& features.enabled(Feature::Apps)
|
||||
&& features.enabled(Feature::Plugins)
|
||||
@@ -324,7 +324,12 @@ fn collab_tools_enabled(turn_context: &TurnContext) -> bool {
|
||||
}
|
||||
|
||||
fn agent_jobs_tools_enabled(turn_context: &TurnContext) -> bool {
|
||||
turn_context.features.get().enabled(Feature::SpawnCsv) && collab_tools_enabled(turn_context)
|
||||
turn_context
|
||||
.config
|
||||
.features
|
||||
.get()
|
||||
.enabled(Feature::SpawnCsv)
|
||||
&& collab_tools_enabled(turn_context)
|
||||
}
|
||||
|
||||
fn agent_jobs_worker_tools_enabled(turn_context: &TurnContext) -> bool {
|
||||
@@ -339,6 +344,7 @@ fn agent_jobs_worker_tools_enabled(turn_context: &TurnContext) -> bool {
|
||||
fn image_generation_tool_enabled(turn_context: &TurnContext) -> bool {
|
||||
image_generation_runtime_enabled(turn_context)
|
||||
&& turn_context
|
||||
.config
|
||||
.features
|
||||
.get()
|
||||
.enabled(Feature::ImageGeneration)
|
||||
@@ -365,7 +371,11 @@ fn standalone_image_generation_model_visible(turn_context: &TurnContext) -> bool
|
||||
return true;
|
||||
}
|
||||
|
||||
turn_context.features.get().enabled(Feature::ImageGenExt)
|
||||
turn_context
|
||||
.config
|
||||
.features
|
||||
.get()
|
||||
.enabled(Feature::ImageGenExt)
|
||||
}
|
||||
|
||||
fn standalone_image_generation_available(
|
||||
@@ -412,7 +422,8 @@ fn is_hidden_by_code_mode_only(
|
||||
tool_name: &ToolName,
|
||||
exposure: ToolExposure,
|
||||
) -> bool {
|
||||
turn_context.tool_mode == ToolMode::CodeModeOnly
|
||||
let tool_mode = effective_tool_mode(turn_context);
|
||||
tool_mode == ToolMode::CodeModeOnly
|
||||
&& exposure != ToolExposure::DirectModelOnly
|
||||
&& codex_code_mode::is_code_mode_nested_tool(&codex_tools::code_mode_name_for_tool_name(
|
||||
tool_name,
|
||||
@@ -433,10 +444,8 @@ fn build_code_mode_executors(
|
||||
turn_context: &TurnContext,
|
||||
executors: &[Arc<dyn CoreToolRuntime>],
|
||||
) -> Vec<Arc<dyn CoreToolRuntime>> {
|
||||
if !matches!(
|
||||
turn_context.tool_mode,
|
||||
ToolMode::CodeMode | ToolMode::CodeModeOnly
|
||||
) {
|
||||
let tool_mode = effective_tool_mode(turn_context);
|
||||
if !matches!(tool_mode, ToolMode::CodeMode | ToolMode::CodeModeOnly) {
|
||||
return vec![];
|
||||
}
|
||||
|
||||
@@ -482,7 +491,7 @@ fn build_code_mode_executors(
|
||||
create_code_mode_tool(
|
||||
&enabled_tools,
|
||||
&namespace_descriptions,
|
||||
turn_context.tool_mode == ToolMode::CodeModeOnly,
|
||||
tool_mode == ToolMode::CodeModeOnly,
|
||||
deferred_tools_available,
|
||||
),
|
||||
code_mode_nested_tool_specs,
|
||||
@@ -577,6 +586,7 @@ fn standalone_web_search_enabled(turn_context: &TurnContext) -> bool {
|
||||
namespace_tools_enabled(turn_context)
|
||||
&& (turn_context.model_info.use_responses_lite
|
||||
|| turn_context
|
||||
.config
|
||||
.features
|
||||
.get()
|
||||
.enabled(Feature::StandaloneWebSearch))
|
||||
@@ -584,7 +594,7 @@ fn standalone_web_search_enabled(turn_context: &TurnContext) -> bool {
|
||||
|
||||
fn add_shell_tools(context: &CoreToolPlanContext<'_>, planned_tools: &mut PlannedTools) {
|
||||
let turn_context = context.turn_context;
|
||||
let features = turn_context.features.get();
|
||||
let features = turn_context.config.features.get();
|
||||
let environment_mode = turn_context.tool_environment_mode();
|
||||
if !environment_mode.has_environment() {
|
||||
return;
|
||||
@@ -643,7 +653,7 @@ fn add_mcp_resource_tools(context: &CoreToolPlanContext<'_>, planned_tools: &mut
|
||||
|
||||
fn add_core_utility_tools(context: &CoreToolPlanContext<'_>, planned_tools: &mut PlannedTools) {
|
||||
let turn_context = context.turn_context;
|
||||
let features = turn_context.features.get();
|
||||
let features = turn_context.config.features.get();
|
||||
let environment_mode = turn_context.tool_environment_mode();
|
||||
|
||||
planned_tools.add(PlanHandler);
|
||||
@@ -915,10 +925,8 @@ fn append_extension_tool_executors(
|
||||
.iter()
|
||||
.map(|executor| executor.tool_name())
|
||||
.collect::<HashSet<_>>();
|
||||
if matches!(
|
||||
turn_context.tool_mode,
|
||||
ToolMode::CodeMode | ToolMode::CodeModeOnly
|
||||
) {
|
||||
let tool_mode = effective_tool_mode(turn_context);
|
||||
if matches!(tool_mode, ToolMode::CodeMode | ToolMode::CodeModeOnly) {
|
||||
reserved_tool_names.insert(ToolName::plain(codex_code_mode::PUBLIC_TOOL_NAME));
|
||||
reserved_tool_names.insert(ToolName::plain(codex_code_mode::WAIT_TOOL_NAME));
|
||||
}
|
||||
|
||||
@@ -197,16 +197,6 @@ async fn probe(configure_turn: impl FnOnce(&mut TurnContext)) -> ToolPlanProbe {
|
||||
}
|
||||
|
||||
fn set_feature(turn: &mut TurnContext, feature: Feature, enabled: bool) {
|
||||
if enabled {
|
||||
turn.features
|
||||
.enable(feature)
|
||||
.expect("test feature should be enableable");
|
||||
} else {
|
||||
turn.features
|
||||
.disable(feature)
|
||||
.expect("test feature should be disableable");
|
||||
}
|
||||
|
||||
let mut config = (*turn.config).clone();
|
||||
if enabled {
|
||||
config
|
||||
@@ -221,15 +211,6 @@ fn set_feature(turn: &mut TurnContext, feature: Feature, enabled: bool) {
|
||||
}
|
||||
turn.multi_agent_version = config.multi_agent_version_from_features();
|
||||
turn.config = Arc::new(config);
|
||||
turn.tool_mode = turn.model_info.tool_mode.unwrap_or_else(|| {
|
||||
if turn.config.features.enabled(Feature::CodeModeOnly) {
|
||||
ToolMode::CodeModeOnly
|
||||
} else if turn.config.features.enabled(Feature::CodeMode) {
|
||||
ToolMode::CodeMode
|
||||
} else {
|
||||
ToolMode::Direct
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
fn set_features(turn: &mut TurnContext, features: &[Feature]) {
|
||||
@@ -1196,7 +1177,6 @@ async fn tool_mode_selector_overrides_feature_flags() {
|
||||
let direct = probe(|turn| {
|
||||
set_features(turn, &[Feature::CodeMode, Feature::CodeModeOnly]);
|
||||
turn.model_info.tool_mode = Some(ToolMode::Direct);
|
||||
turn.tool_mode = ToolMode::Direct;
|
||||
})
|
||||
.await;
|
||||
direct.assert_visible_lacks(&[
|
||||
|
||||
@@ -190,7 +190,7 @@ async fn exec_command_with_tty(
|
||||
chunk_id: generate_chunk_id(),
|
||||
wall_time,
|
||||
raw_output: collected,
|
||||
truncation_policy: turn.truncation_policy,
|
||||
truncation_policy: turn.model_info.truncation_policy.into(),
|
||||
max_output_tokens: None,
|
||||
process_id: response_process_id,
|
||||
exit_code,
|
||||
|
||||
@@ -602,7 +602,7 @@ impl UnifiedExecProcessManager {
|
||||
chunk_id,
|
||||
wall_time,
|
||||
raw_output: collected,
|
||||
truncation_policy: context.turn.truncation_policy,
|
||||
truncation_policy: context.turn.model_info.truncation_policy.into(),
|
||||
max_output_tokens: request.max_output_tokens,
|
||||
process_id: response_process_id,
|
||||
exit_code,
|
||||
@@ -1030,7 +1030,7 @@ impl UnifiedExecProcessManager {
|
||||
context: &UnifiedExecContext,
|
||||
) -> Result<(UnifiedExecProcess, Option<DeferredNetworkApproval>), UnifiedExecError> {
|
||||
let local_policy_env = create_env(
|
||||
&context.turn.shell_environment_policy,
|
||||
&context.turn.config.permissions.shell_environment_policy,
|
||||
/*thread_id*/ None,
|
||||
);
|
||||
let mut env = local_policy_env.clone();
|
||||
@@ -1040,7 +1040,9 @@ impl UnifiedExecProcessManager {
|
||||
);
|
||||
let env = apply_unified_exec_env(env);
|
||||
let exec_server_env_config = ExecServerEnvConfig {
|
||||
policy: exec_env_policy_from_shell_policy(&context.turn.shell_environment_policy),
|
||||
policy: exec_env_policy_from_shell_policy(
|
||||
&context.turn.config.permissions.shell_environment_policy,
|
||||
),
|
||||
local_policy_env,
|
||||
};
|
||||
let mut orchestrator = ToolOrchestrator::new();
|
||||
@@ -1072,7 +1074,13 @@ impl UnifiedExecProcessManager {
|
||||
turn_environment: request.turn_environment.clone(),
|
||||
env,
|
||||
exec_server_env_config: Some(exec_server_env_config),
|
||||
explicit_env_overrides: context.turn.shell_environment_policy.r#set.clone(),
|
||||
explicit_env_overrides: context
|
||||
.turn
|
||||
.config
|
||||
.permissions
|
||||
.shell_environment_policy
|
||||
.r#set
|
||||
.clone(),
|
||||
network: request.network.clone(),
|
||||
tty: request.tty,
|
||||
sandbox_permissions: request.sandbox_permissions,
|
||||
|
||||
@@ -11,7 +11,10 @@ fn user_shell_command_fragment(
|
||||
exec_output: &ExecToolCallOutput,
|
||||
turn_context: &TurnContext,
|
||||
) -> UserShellCommand {
|
||||
let output = format_exec_output_str(exec_output, turn_context.truncation_policy);
|
||||
let output = format_exec_output_str(
|
||||
exec_output,
|
||||
turn_context.model_info.truncation_policy.into(),
|
||||
);
|
||||
UserShellCommand::new(command, exec_output.exit_code, exec_output.duration, output)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user