mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
core: make AGENTS.md react to environment changes (#29810)
## Why With deferred executors, a turn can begin before a remote environment attaches. AGENTS.md discovery previously ran only during session setup, so instructions from a later environment never reached the model or the session instruction sources. WorldState persistence has now landed, so this uses the durable model-visible baseline directly instead of carrying a temporary resume/fork compatibility path. ## What - Add an `AgentsMdManager` in `SessionServices` to own host instructions, loaded state, and refresh caching. - When `DeferredExecutor` is enabled, refresh AGENTS.md when attached environment selections change and freeze the result in the corresponding `StepContext`. - Represent AGENTS.md as a persisted WorldState section for every session, with bounded initial, replacement, and removal updates. - Remove duplicate AGENTS.md state and rendering from `SessionConfiguration` and `TurnContext`. - Build initial context, per-request updates, and compaction context from the same step-scoped value. - On resume and fork, compare current instructions with the restored WorldState baseline and inject a replacement exactly once when they differ. Builds on #29833, #29835, and #29837. ## Tests - Covers a remote environment becoming ready mid-turn, with AGENTS.md appearing on the next request exactly once and updating canonical instruction sources. - Covers full, unchanged, replaced, and removed AGENTS.md WorldState rendering. - Covers changed instructions across cold resume and fork without duplicate reinjection. - Covers remote-v2 compaction retaining creation-time instructions in the live session and cold resume appending one replacement when the source changed. - Ran focused `codex-core` AGENTS.md, WorldState, and context-update test suites.
This commit is contained in:
committed by
GitHub
Unverified
parent
51864b0b4b
commit
f2f80ef442
@@ -14,7 +14,6 @@ use crate::agent::AgentControl;
|
||||
use crate::agent::AgentStatus;
|
||||
use crate::agent::agent_status_from_event;
|
||||
use crate::agent::status::is_final;
|
||||
use crate::agents_md::LoadedAgentsMd;
|
||||
use crate::attestation::AttestationProvider;
|
||||
use crate::build_available_skills;
|
||||
use crate::compact;
|
||||
@@ -248,7 +247,6 @@ use self::turn::collect_explicit_app_ids_from_skill_items;
|
||||
use self::turn::realtime_text_for_event;
|
||||
use self::turn_context::TurnContext;
|
||||
use self::turn_context::TurnSkillsContext;
|
||||
use self::world_state::build_world_state_from_environment_snapshot;
|
||||
#[cfg(test)]
|
||||
mod rollout_reconstruction_tests;
|
||||
|
||||
@@ -308,7 +306,6 @@ pub(crate) struct PreviousTurnSettings {
|
||||
#[cfg(test)]
|
||||
use crate::SkillMetadata;
|
||||
use crate::SkillsService;
|
||||
use crate::agents_md::load_project_instructions;
|
||||
use crate::exec_policy::ExecPolicyUpdateError;
|
||||
use crate::guardian::GuardianReviewSessionManager;
|
||||
use crate::mcp::McpManager;
|
||||
@@ -627,7 +624,6 @@ impl Codex {
|
||||
model_reasoning_summary: config.model_reasoning_summary,
|
||||
service_tier,
|
||||
developer_instructions: config.developer_instructions.clone(),
|
||||
loaded_agents_md: None,
|
||||
personality: config.personality,
|
||||
base_instructions,
|
||||
compact_prompt: config.compact_prompt.clone(),
|
||||
@@ -842,10 +838,11 @@ impl Codex {
|
||||
}
|
||||
|
||||
pub(crate) async fn instruction_sources(&self) -> Vec<PathUri> {
|
||||
let state = self.session.state.lock().await;
|
||||
state
|
||||
.session_configuration
|
||||
.loaded_agents_md
|
||||
self.session
|
||||
.services
|
||||
.agents_md_manager
|
||||
.get_loaded()
|
||||
.await
|
||||
.as_ref()
|
||||
.map_or_else(Vec::new, |instructions| instructions.sources().collect())
|
||||
}
|
||||
@@ -1542,13 +1539,7 @@ impl Session {
|
||||
}
|
||||
|
||||
pub(crate) async fn user_instructions(&self) -> Option<codex_extension_api::UserInstructions> {
|
||||
let state = self.state.lock().await;
|
||||
state
|
||||
.session_configuration
|
||||
.loaded_agents_md
|
||||
.as_ref()
|
||||
.and_then(LoadedAgentsMd::user_instructions)
|
||||
.cloned()
|
||||
self.services.agents_md_manager.user_instructions()
|
||||
}
|
||||
|
||||
pub(crate) async fn provider(&self) -> ModelProviderInfo {
|
||||
@@ -2776,17 +2767,14 @@ impl Session {
|
||||
self.send_raw_response_items(turn_context, items).await;
|
||||
}
|
||||
|
||||
pub(crate) async fn record_step_environment_context_if_changed(
|
||||
pub(crate) async fn record_step_world_state_if_changed(
|
||||
&self,
|
||||
previous_world_state: &Arc<WorldState>,
|
||||
step_context: &step_context::StepContext,
|
||||
) -> Arc<WorldState> {
|
||||
let turn_context = step_context.turn.as_ref();
|
||||
// Render model-visible state from the same step used to build and run tools.
|
||||
let world_state = Arc::new(
|
||||
self.build_world_state_for_environments(turn_context, &step_context.environments)
|
||||
.await,
|
||||
);
|
||||
let world_state = Arc::new(self.build_world_state_for_step(step_context).await);
|
||||
// Derive the model update and persisted patch from the same two snapshots.
|
||||
let previous_snapshot = previous_world_state.snapshot();
|
||||
let world_state_snapshot = world_state.snapshot();
|
||||
@@ -2814,21 +2802,37 @@ impl Session {
|
||||
world_state
|
||||
}
|
||||
|
||||
/// Captures one request-scoped view of dynamic state.
|
||||
///
|
||||
/// This may refresh filesystem-derived state. Normal turns should call it only from
|
||||
/// `run_turn` and pass the result down; standalone request or history boundaries may capture
|
||||
/// their own step.
|
||||
pub(crate) async fn capture_step_context(
|
||||
&self,
|
||||
turn_context: Arc<TurnContext>,
|
||||
) -> Arc<StepContext> {
|
||||
// Keep the old turn-frozen view unless deferred executors are explicitly enabled.
|
||||
let environments = if turn_context
|
||||
let deferred_executor_enabled = turn_context
|
||||
.config
|
||||
.features
|
||||
.enabled(Feature::DeferredExecutor)
|
||||
{
|
||||
.enabled(Feature::DeferredExecutor);
|
||||
// Keep the old turn-frozen environment view unless deferred executors are enabled.
|
||||
let environments = if deferred_executor_enabled {
|
||||
self.services.turn_environments.snapshot().await
|
||||
} else {
|
||||
turn_context.environments.clone()
|
||||
};
|
||||
Arc::new(StepContext::new(turn_context, environments))
|
||||
if deferred_executor_enabled {
|
||||
self.services
|
||||
.agents_md_manager
|
||||
.refresh(&turn_context.config, &environments)
|
||||
.await;
|
||||
}
|
||||
let loaded_agents_md = self.services.agents_md_manager.get_loaded().await;
|
||||
Arc::new(StepContext::new(
|
||||
turn_context,
|
||||
environments,
|
||||
loaded_agents_md,
|
||||
))
|
||||
}
|
||||
|
||||
pub(crate) async fn record_inter_agent_communication(
|
||||
@@ -3088,26 +3092,6 @@ impl Session {
|
||||
items
|
||||
}
|
||||
|
||||
pub(crate) async fn build_world_state_for_environments(
|
||||
&self,
|
||||
turn_context: &TurnContext,
|
||||
environments: &TurnEnvironmentSnapshot,
|
||||
) -> WorldState {
|
||||
let environment_subagents = if turn_context.config.include_environment_context {
|
||||
self.services
|
||||
.agent_control
|
||||
.format_environment_context_subagents(self.thread_id)
|
||||
.await
|
||||
} else {
|
||||
String::new()
|
||||
};
|
||||
build_world_state_from_environment_snapshot(
|
||||
turn_context,
|
||||
environments,
|
||||
&environment_subagents,
|
||||
)
|
||||
}
|
||||
|
||||
pub(crate) async fn build_initial_context_with_world_state(
|
||||
&self,
|
||||
turn_context: &TurnContext,
|
||||
@@ -3311,9 +3295,6 @@ impl Session {
|
||||
);
|
||||
}
|
||||
}
|
||||
if let Some(user_instructions) = turn_context.user_instructions.as_deref() {
|
||||
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.config.features.enabled(Feature::TokenBudget)
|
||||
&& turn_context.model_context_window().is_some()
|
||||
@@ -3519,8 +3500,9 @@ impl Session {
|
||||
#[instrument(level = "trace", skip_all)]
|
||||
pub(crate) async fn record_context_updates_and_set_reference_context_item(
|
||||
&self,
|
||||
turn_context: &TurnContext,
|
||||
step_context: &StepContext,
|
||||
) -> Arc<WorldState> {
|
||||
let turn_context = step_context.turn.as_ref();
|
||||
let reference_context_item = {
|
||||
let state = self.state.lock().await;
|
||||
state.reference_context_item()
|
||||
@@ -3528,10 +3510,7 @@ impl Session {
|
||||
let turn_context_item = turn_context.to_turn_context_item();
|
||||
let turn_context_changed = reference_context_item.as_ref() != Some(&turn_context_item);
|
||||
let should_inject_full_context = reference_context_item.is_none();
|
||||
let world_state = Arc::new(
|
||||
self.build_world_state_for_environments(turn_context, &turn_context.environments)
|
||||
.await,
|
||||
);
|
||||
let world_state = Arc::new(self.build_world_state_for_step(step_context).await);
|
||||
// Full initial context resets the baseline; later turns persist only its changes.
|
||||
let (mut context_items, world_state_item) = if should_inject_full_context {
|
||||
let context_items = self
|
||||
|
||||
@@ -126,7 +126,6 @@ pub(super) async fn spawn_review_thread(
|
||||
timezone: parent_turn_context.timezone.clone(),
|
||||
app_server_client_name: parent_turn_context.app_server_client_name.clone(),
|
||||
developer_instructions: None,
|
||||
user_instructions: None,
|
||||
collaboration_mode: parent_turn_context.collaboration_mode.clone(),
|
||||
multi_agent_version: MultiAgentVersion::Disabled,
|
||||
personality: parent_turn_context.personality,
|
||||
|
||||
@@ -135,6 +135,7 @@ async fn record_initial_history_reconstructs_typed_inter_agent_message() {
|
||||
#[tokio::test]
|
||||
async fn record_initial_history_restores_world_state_baseline() {
|
||||
let (session, turn_context) = make_session_and_context().await;
|
||||
let turn_context = Arc::new(turn_context);
|
||||
let world_state = build_world_state_from_turn_context(&session, &turn_context).await;
|
||||
let rollout_items = completed_user_turn_rollout(
|
||||
turn_context.to_turn_context_item(),
|
||||
@@ -150,8 +151,9 @@ async fn record_initial_history_restores_world_state_baseline() {
|
||||
rollout_path: Some(PathBuf::from("/tmp/resume.jsonl")),
|
||||
}))
|
||||
.await;
|
||||
let step_context = StepContext::for_test(Arc::clone(&turn_context));
|
||||
session
|
||||
.record_context_updates_and_set_reference_context_item(&turn_context)
|
||||
.record_context_updates_and_set_reference_context_item(&step_context)
|
||||
.await;
|
||||
|
||||
assert_eq!(session.clone_history().await.raw_items(), &[]);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use super::input_queue::InputQueue;
|
||||
use super::*;
|
||||
use crate::agents_md::LoadedAgentsMd;
|
||||
use crate::agents_md_manager::AgentsMdManager;
|
||||
use crate::config::ConstraintError;
|
||||
use crate::environment_selection::ThreadEnvironments;
|
||||
use crate::environment_selection::TurnEnvironmentSnapshot;
|
||||
@@ -16,7 +16,6 @@ use codex_protocol::permissions::FileSystemPath;
|
||||
use codex_protocol::permissions::FileSystemSpecialPath;
|
||||
use codex_protocol::protocol::MultiAgentVersion;
|
||||
use codex_protocol::protocol::ThreadSource;
|
||||
use codex_protocol::protocol::TurnEnvironmentSelection;
|
||||
use codex_protocol::protocol::TurnEnvironmentSelections;
|
||||
use std::sync::OnceLock;
|
||||
use tokio::sync::Semaphore;
|
||||
@@ -59,10 +58,6 @@ pub(crate) struct SessionConfiguration {
|
||||
/// Developer instructions that supplement the base instructions.
|
||||
pub(super) developer_instructions: Option<String>,
|
||||
|
||||
/// Model instructions assembled from provider instructions and discovered
|
||||
/// AGENTS.md files.
|
||||
pub(super) loaded_agents_md: Option<LoadedAgentsMd>,
|
||||
|
||||
/// Personality preference for the model.
|
||||
pub(super) personality: Option<Personality>,
|
||||
|
||||
@@ -863,12 +858,10 @@ impl Session {
|
||||
));
|
||||
turn_environments.update_selections(session_configuration.environment_selections());
|
||||
let resolved_environments = turn_environments.snapshot().await;
|
||||
session_configuration.loaded_agents_md = load_project_instructions(
|
||||
config.as_ref(),
|
||||
user_instructions,
|
||||
&resolved_environments,
|
||||
)
|
||||
.await;
|
||||
let agents_md_manager = Arc::new(AgentsMdManager::new(user_instructions));
|
||||
agents_md_manager
|
||||
.refresh(config.as_ref(), &resolved_environments)
|
||||
.await;
|
||||
let plugin_skill_errors = warm_plugins_and_skills_for_session_init(
|
||||
Arc::clone(&config),
|
||||
Arc::clone(&plugins_manager),
|
||||
@@ -1036,6 +1029,7 @@ impl Session {
|
||||
guardian_rejection_circuit_breaker: Mutex::new(Default::default()),
|
||||
runtime_handle: tokio::runtime::Handle::current(),
|
||||
skills_service,
|
||||
agents_md_manager,
|
||||
plugins_manager: Arc::clone(&plugins_manager),
|
||||
mcp_manager: Arc::clone(&mcp_manager),
|
||||
extensions,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::agents_md::LoadedAgentsMd;
|
||||
use crate::environment_selection::TurnEnvironmentSnapshot;
|
||||
use crate::session::turn_context::TurnContext;
|
||||
|
||||
@@ -8,10 +9,20 @@ use crate::session::turn_context::TurnContext;
|
||||
pub(crate) struct StepContext {
|
||||
pub(crate) turn: Arc<TurnContext>,
|
||||
pub(crate) environments: TurnEnvironmentSnapshot,
|
||||
/// The canonical AGENTS.md value observed with this environment snapshot.
|
||||
pub(crate) loaded_agents_md: Option<Arc<LoadedAgentsMd>>,
|
||||
}
|
||||
|
||||
impl StepContext {
|
||||
pub(crate) fn new(turn: Arc<TurnContext>, environments: TurnEnvironmentSnapshot) -> Self {
|
||||
Self { turn, environments }
|
||||
pub(crate) fn new(
|
||||
turn: Arc<TurnContext>,
|
||||
environments: TurnEnvironmentSnapshot,
|
||||
loaded_agents_md: Option<Arc<LoadedAgentsMd>>,
|
||||
) -> Self {
|
||||
Self {
|
||||
turn,
|
||||
environments,
|
||||
loaded_agents_md,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
use super::turn_context::TurnEnvironment;
|
||||
use super::*;
|
||||
use crate::agents_md_manager::AgentsMdManager;
|
||||
use crate::codex_thread::TryStartTurnIfIdleRejectionReason;
|
||||
use crate::config::ConfigBuilder;
|
||||
use crate::config::ConfigOverrides;
|
||||
@@ -186,7 +187,11 @@ use std::time::Duration as StdDuration;
|
||||
impl StepContext {
|
||||
pub(crate) fn for_test(turn: Arc<TurnContext>) -> Arc<Self> {
|
||||
let environments = turn.environments.clone();
|
||||
Arc::new(Self::new(turn, environments))
|
||||
Arc::new(Self::new(
|
||||
turn,
|
||||
environments,
|
||||
/*loaded_agents_md*/ None,
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2082,6 +2087,7 @@ fn session_meta_item(
|
||||
#[tokio::test]
|
||||
async fn resumed_history_injects_initial_context_on_first_context_update_only() {
|
||||
let (session, turn_context) = make_session_and_context().await;
|
||||
let turn_context = Arc::new(turn_context);
|
||||
let (rollout_items, mut expected) = sample_rollout(&session, &turn_context).await;
|
||||
|
||||
session
|
||||
@@ -2095,8 +2101,9 @@ async fn resumed_history_injects_initial_context_on_first_context_update_only()
|
||||
let history_before_seed = session.state.lock().await.clone_history();
|
||||
assert_eq!(expected, history_before_seed.raw_items());
|
||||
|
||||
let step_context = StepContext::for_test(Arc::clone(&turn_context));
|
||||
session
|
||||
.record_context_updates_and_set_reference_context_item(&turn_context)
|
||||
.record_context_updates_and_set_reference_context_item(&step_context)
|
||||
.await;
|
||||
let initial_context = build_initial_context(&session, &turn_context).await;
|
||||
expected.extend(initial_context);
|
||||
@@ -2104,7 +2111,7 @@ async fn resumed_history_injects_initial_context_on_first_context_update_only()
|
||||
assert_eq!(expected, history_after_seed.raw_items());
|
||||
|
||||
session
|
||||
.record_context_updates_and_set_reference_context_item(&turn_context)
|
||||
.record_context_updates_and_set_reference_context_item(&step_context)
|
||||
.await;
|
||||
let history_after_second_seed = session.clone_history().await;
|
||||
assert_eq!(
|
||||
@@ -2715,9 +2722,8 @@ async fn start_new_context_window_assigns_and_persists_item_ids() {
|
||||
.await;
|
||||
let rollout_path =
|
||||
attach_thread_persistence(Arc::get_mut(&mut session).expect("unique session")).await;
|
||||
let world_state = Arc::new(
|
||||
build_world_state_from_turn_context(session.as_ref(), turn_context.as_ref()).await,
|
||||
);
|
||||
let world_state =
|
||||
Arc::new(build_world_state_from_turn_context(session.as_ref(), &turn_context).await);
|
||||
|
||||
session
|
||||
.start_new_context_window(turn_context.as_ref(), world_state)
|
||||
@@ -3091,7 +3097,7 @@ async fn thread_rollback_drops_last_turn_from_history() {
|
||||
)
|
||||
.await;
|
||||
|
||||
let initial_context = build_initial_context(&sess, tc.as_ref()).await;
|
||||
let initial_context = build_initial_context(&sess, &tc).await;
|
||||
let turn_1 = vec![
|
||||
user_message("turn 1 user"),
|
||||
assistant_message("turn 1 assistant"),
|
||||
@@ -3159,7 +3165,7 @@ async fn thread_rollback_clears_history_when_num_turns_exceeds_existing_turns()
|
||||
)
|
||||
.await;
|
||||
|
||||
let initial_context = build_initial_context(&sess, tc.as_ref()).await;
|
||||
let initial_context = build_initial_context(&sess, &tc).await;
|
||||
let turn_1 = vec![user_message("turn 1 user")];
|
||||
let mut full_history = Vec::new();
|
||||
full_history.extend(initial_context.clone());
|
||||
@@ -3185,7 +3191,7 @@ async fn thread_rollback_clears_history_when_num_turns_exceeds_existing_turns()
|
||||
async fn thread_rollback_fails_without_persisted_thread_history() {
|
||||
let (sess, tc, rx) = make_session_and_context_with_rx().await;
|
||||
|
||||
let initial_context = build_initial_context(&sess, tc.as_ref()).await;
|
||||
let initial_context = build_initial_context(&sess, &tc).await;
|
||||
sess.record_conversation_items(tc.as_ref(), &initial_context)
|
||||
.await;
|
||||
|
||||
@@ -3595,7 +3601,7 @@ async fn thread_rollback_persists_marker_and_replays_cumulatively() {
|
||||
async fn thread_rollback_fails_when_turn_in_progress() {
|
||||
let (sess, tc, rx) = make_session_and_context_with_rx().await;
|
||||
|
||||
let initial_context = build_initial_context(&sess, tc.as_ref()).await;
|
||||
let initial_context = build_initial_context(&sess, &tc).await;
|
||||
sess.record_conversation_items(tc.as_ref(), &initial_context)
|
||||
.await;
|
||||
|
||||
@@ -3616,7 +3622,7 @@ async fn thread_rollback_fails_when_turn_in_progress() {
|
||||
async fn thread_rollback_fails_when_num_turns_is_zero() {
|
||||
let (sess, tc, rx) = make_session_and_context_with_rx().await;
|
||||
|
||||
let initial_context = build_initial_context(&sess, tc.as_ref()).await;
|
||||
let initial_context = build_initial_context(&sess, &tc).await;
|
||||
sess.record_conversation_items(tc.as_ref(), &initial_context)
|
||||
.await;
|
||||
|
||||
@@ -3655,7 +3661,6 @@ async fn set_rate_limits_retains_previous_credits() {
|
||||
collaboration_mode,
|
||||
model_reasoning_summary: config.model_reasoning_summary,
|
||||
developer_instructions: config.developer_instructions.clone(),
|
||||
loaded_agents_md: None,
|
||||
service_tier: None,
|
||||
personality: config.personality,
|
||||
base_instructions: config
|
||||
@@ -3762,7 +3767,6 @@ async fn set_rate_limits_updates_plan_type_when_present() {
|
||||
collaboration_mode,
|
||||
model_reasoning_summary: config.model_reasoning_summary,
|
||||
developer_instructions: config.developer_instructions.clone(),
|
||||
loaded_agents_md: None,
|
||||
service_tier: None,
|
||||
personality: config.personality,
|
||||
base_instructions: config
|
||||
@@ -4293,7 +4297,6 @@ pub(crate) async fn make_session_configuration_for_tests() -> SessionConfigurati
|
||||
collaboration_mode,
|
||||
model_reasoning_summary: config.model_reasoning_summary,
|
||||
developer_instructions: config.developer_instructions.clone(),
|
||||
loaded_agents_md: None,
|
||||
service_tier: None,
|
||||
personality: config.personality,
|
||||
base_instructions: config
|
||||
@@ -5164,7 +5167,6 @@ async fn session_new_fails_when_zsh_fork_enabled_without_packaged_zsh() {
|
||||
collaboration_mode,
|
||||
model_reasoning_summary: config.model_reasoning_summary,
|
||||
developer_instructions: config.developer_instructions.clone(),
|
||||
loaded_agents_md: None,
|
||||
service_tier: None,
|
||||
personality: config.personality,
|
||||
base_instructions: config
|
||||
@@ -5243,20 +5245,22 @@ async fn session_new_fails_when_zsh_fork_enabled_without_packaged_zsh() {
|
||||
assert!(msg.contains("zsh fork feature enabled, but no packaged zsh fork is available"));
|
||||
}
|
||||
|
||||
async fn build_initial_context(session: &Session, turn_context: &TurnContext) -> Vec<ResponseItem> {
|
||||
async fn build_initial_context(
|
||||
session: &Session,
|
||||
turn_context: &Arc<TurnContext>,
|
||||
) -> Vec<ResponseItem> {
|
||||
let world_state = build_world_state_from_turn_context(session, turn_context).await;
|
||||
session
|
||||
.build_initial_context_with_world_state(turn_context, &world_state)
|
||||
.build_initial_context_with_world_state(turn_context.as_ref(), &world_state)
|
||||
.await
|
||||
}
|
||||
|
||||
pub(crate) async fn build_world_state_from_turn_context(
|
||||
session: &Session,
|
||||
turn_context: &TurnContext,
|
||||
turn_context: &Arc<TurnContext>,
|
||||
) -> WorldState {
|
||||
session
|
||||
.build_world_state_for_environments(turn_context, &turn_context.environments)
|
||||
.await
|
||||
let step_context = StepContext::for_test(Arc::clone(turn_context));
|
||||
session.build_world_state_for_step(&step_context).await
|
||||
}
|
||||
|
||||
// todo: use online model info
|
||||
@@ -5293,7 +5297,6 @@ pub(crate) async fn make_session_and_context() -> (Session, TurnContext) {
|
||||
collaboration_mode,
|
||||
model_reasoning_summary: config.model_reasoning_summary,
|
||||
developer_instructions: config.developer_instructions.clone(),
|
||||
loaded_agents_md: None,
|
||||
service_tier: None,
|
||||
personality: config.personality,
|
||||
base_instructions: config
|
||||
@@ -5393,6 +5396,7 @@ pub(crate) async fn make_session_and_context() -> (Session, TurnContext) {
|
||||
guardian_rejection_circuit_breaker: Mutex::new(Default::default()),
|
||||
runtime_handle: tokio::runtime::Handle::current(),
|
||||
skills_service,
|
||||
agents_md_manager: Arc::new(AgentsMdManager::new(/*user_instructions*/ None)),
|
||||
plugins_manager,
|
||||
mcp_manager,
|
||||
extensions: Arc::new(codex_extension_api::ExtensionRegistryBuilder::new().build()),
|
||||
@@ -5471,7 +5475,6 @@ pub(crate) async fn make_session_and_context() -> (Session, TurnContext) {
|
||||
"turn_id".to_string(),
|
||||
skills_snapshot,
|
||||
);
|
||||
|
||||
let session = Session {
|
||||
thread_id,
|
||||
installation_id: "11111111-1111-4111-8111-111111111111".to_string(),
|
||||
@@ -5541,7 +5544,6 @@ async fn make_session_with_config_and_rx(
|
||||
collaboration_mode,
|
||||
model_reasoning_summary: config.model_reasoning_summary,
|
||||
developer_instructions: config.developer_instructions.clone(),
|
||||
loaded_agents_md: None,
|
||||
service_tier: None,
|
||||
personality: config.personality,
|
||||
base_instructions: config
|
||||
@@ -5648,7 +5650,6 @@ async fn make_session_with_history_source_and_agent_control_and_rx(
|
||||
collaboration_mode,
|
||||
model_reasoning_summary: config.model_reasoning_summary,
|
||||
developer_instructions: config.developer_instructions.clone(),
|
||||
loaded_agents_md: None,
|
||||
service_tier: None,
|
||||
personality: config.personality,
|
||||
base_instructions: config
|
||||
@@ -7372,7 +7373,6 @@ where
|
||||
collaboration_mode,
|
||||
model_reasoning_summary: config.model_reasoning_summary,
|
||||
developer_instructions: config.developer_instructions.clone(),
|
||||
loaded_agents_md: None,
|
||||
service_tier: None,
|
||||
personality: config.personality,
|
||||
base_instructions: config
|
||||
@@ -7471,6 +7471,7 @@ where
|
||||
guardian_rejection_circuit_breaker: Mutex::new(Default::default()),
|
||||
runtime_handle: tokio::runtime::Handle::current(),
|
||||
skills_service,
|
||||
agents_md_manager: Arc::new(AgentsMdManager::new(/*user_instructions*/ None)),
|
||||
plugins_manager,
|
||||
mcp_manager,
|
||||
extensions: Arc::new(codex_extension_api::ExtensionRegistryBuilder::new().build()),
|
||||
@@ -7549,7 +7550,6 @@ where
|
||||
"turn_id".to_string(),
|
||||
skills_snapshot,
|
||||
));
|
||||
|
||||
let session = Arc::new(Session {
|
||||
thread_id,
|
||||
installation_id: "11111111-1111-4111-8111-111111111111".to_string(),
|
||||
@@ -7718,7 +7718,7 @@ async fn record_context_updates_emits_environment_item_for_network_changes() {
|
||||
current_context.config = Arc::new(config);
|
||||
|
||||
let update_items =
|
||||
record_context_update_items(&session, &previous_context, ¤t_context).await;
|
||||
record_context_update_items(&session, previous_context, current_context).await;
|
||||
|
||||
let environment_update = user_input_texts(&update_items)
|
||||
.into_iter()
|
||||
@@ -7749,7 +7749,7 @@ async fn record_context_updates_emits_environment_item_for_cwd_changes() {
|
||||
);
|
||||
|
||||
let update_items =
|
||||
record_context_update_items(&session, &previous_context, ¤t_context).await;
|
||||
record_context_update_items(&session, previous_context, current_context).await;
|
||||
|
||||
let environment_update = user_input_texts(&update_items)
|
||||
.into_iter()
|
||||
@@ -7776,7 +7776,7 @@ async fn record_context_updates_emits_environment_item_for_time_changes() {
|
||||
current_context.timezone = Some("Europe/Berlin".to_string());
|
||||
|
||||
let update_items =
|
||||
record_context_update_items(&session, &previous_context, ¤t_context).await;
|
||||
record_context_update_items(&session, previous_context, current_context).await;
|
||||
|
||||
let environment_update = user_input_texts(&update_items)
|
||||
.into_iter()
|
||||
@@ -7808,7 +7808,7 @@ async fn record_context_updates_omits_environment_item_when_disabled() {
|
||||
);
|
||||
|
||||
let update_items =
|
||||
record_context_update_items(&session, &previous_context, ¤t_context).await;
|
||||
record_context_update_items(&session, previous_context, current_context).await;
|
||||
|
||||
let user_texts = user_input_texts(&update_items);
|
||||
assert!(
|
||||
@@ -7821,16 +7821,18 @@ async fn record_context_updates_omits_environment_item_when_disabled() {
|
||||
|
||||
async fn record_context_update_items(
|
||||
session: &Session,
|
||||
previous_context: &TurnContext,
|
||||
current_context: &TurnContext,
|
||||
previous_context: Arc<TurnContext>,
|
||||
current_context: TurnContext,
|
||||
) -> Vec<ResponseItem> {
|
||||
let previous_step = StepContext::for_test(previous_context);
|
||||
session
|
||||
.record_context_updates_and_set_reference_context_item(previous_context)
|
||||
.record_context_updates_and_set_reference_context_item(&previous_step)
|
||||
.await;
|
||||
let previous_len = session.clone_history().await.raw_items().len();
|
||||
|
||||
let current_step = StepContext::for_test(Arc::new(current_context));
|
||||
session
|
||||
.record_context_updates_and_set_reference_context_item(current_context)
|
||||
.record_context_updates_and_set_reference_context_item(¤t_step)
|
||||
.await;
|
||||
let history = session.clone_history().await;
|
||||
history.raw_items()[previous_len..].to_vec()
|
||||
@@ -7930,6 +7932,7 @@ async fn build_settings_update_items_uses_previous_turn_settings_for_realtime_en
|
||||
async fn build_initial_context_uses_previous_realtime_state() {
|
||||
let (session, mut turn_context) = make_session_and_context().await;
|
||||
turn_context.realtime_active = true;
|
||||
let turn_context = Arc::new(turn_context);
|
||||
|
||||
let initial_context = build_initial_context(&session, &turn_context).await;
|
||||
let developer_texts = developer_input_texts(&initial_context);
|
||||
@@ -8043,6 +8046,7 @@ async fn build_initial_context_includes_prompt_fragments_from_extensions() {
|
||||
.services
|
||||
.thread_extension_data
|
||||
.insert(PromptExtensionTestState);
|
||||
let turn_context = Arc::new(turn_context);
|
||||
|
||||
let initial_context = build_initial_context(&session, &turn_context).await;
|
||||
let developer_messages = developer_message_texts(&initial_context);
|
||||
@@ -8069,6 +8073,7 @@ async fn build_initial_context_includes_turn_context_fragments_from_extensions()
|
||||
.insert(TurnContextExtensionTestState {
|
||||
expected_model_context_window: Some(50),
|
||||
});
|
||||
let turn_context = Arc::new(turn_context);
|
||||
|
||||
let initial_context = build_initial_context(&session, &turn_context).await;
|
||||
let developer_messages = developer_message_texts(&initial_context);
|
||||
@@ -8097,6 +8102,7 @@ async fn record_context_updates_includes_turn_context_fragments_on_steady_state_
|
||||
});
|
||||
let mut previous_context_item = turn_context.to_turn_context_item();
|
||||
previous_context_item.turn_id = Some("previous-turn-id".to_string());
|
||||
let turn_context = Arc::new(turn_context);
|
||||
let world_state = build_world_state_from_turn_context(&session, &turn_context).await;
|
||||
{
|
||||
let mut state = session.state.lock().await;
|
||||
@@ -8106,8 +8112,9 @@ async fn record_context_updates_includes_turn_context_fragments_on_steady_state_
|
||||
.set_world_state_baseline(world_state.snapshot());
|
||||
}
|
||||
|
||||
let step_context = StepContext::for_test(Arc::clone(&turn_context));
|
||||
session
|
||||
.record_context_updates_and_set_reference_context_item(&turn_context)
|
||||
.record_context_updates_and_set_reference_context_item(&step_context)
|
||||
.await;
|
||||
|
||||
let history = session.clone_history().await;
|
||||
@@ -8125,6 +8132,7 @@ async fn record_context_updates_includes_turn_context_fragments_on_steady_state_
|
||||
async fn build_initial_context_omits_prompt_fragments_without_extension_state() {
|
||||
let (mut session, turn_context) = make_session_and_context().await;
|
||||
session.services.extensions = prompt_extension_test_registry();
|
||||
let turn_context = Arc::new(turn_context);
|
||||
|
||||
let initial_context = build_initial_context(&session, &turn_context).await;
|
||||
let developer_messages = developer_message_texts(&initial_context);
|
||||
@@ -8143,7 +8151,7 @@ async fn build_initial_context_adds_multi_agent_v2_root_usage_hint_as_developer_
|
||||
let (session, turn_context) =
|
||||
make_multi_agent_v2_usage_hint_test_session(/*enable_multi_agent_v2*/ true).await;
|
||||
|
||||
let initial_context = build_initial_context(&session, turn_context.as_ref()).await;
|
||||
let initial_context = build_initial_context(&session, &turn_context).await;
|
||||
|
||||
let developer_messages = developer_message_texts(&initial_context);
|
||||
assert!(
|
||||
@@ -8181,7 +8189,7 @@ async fn build_initial_context_adds_multi_agent_v2_subagent_usage_hint_as_develo
|
||||
.expect("thread settings should not be shared")
|
||||
.session_source = session_source;
|
||||
|
||||
let initial_context = build_initial_context(&session, turn_context.as_ref()).await;
|
||||
let initial_context = build_initial_context(&session, &turn_context).await;
|
||||
|
||||
let developer_messages = developer_message_texts(&initial_context);
|
||||
assert!(
|
||||
@@ -8203,7 +8211,7 @@ async fn build_initial_context_omits_multi_agent_v2_usage_hints_when_feature_dis
|
||||
let (session, turn_context) =
|
||||
make_multi_agent_v2_usage_hint_test_session(/*enable_multi_agent_v2*/ false).await;
|
||||
|
||||
let initial_context = build_initial_context(&session, turn_context.as_ref()).await;
|
||||
let initial_context = build_initial_context(&session, &turn_context).await;
|
||||
|
||||
let developer_messages = developer_message_texts(&initial_context);
|
||||
assert!(
|
||||
@@ -8230,7 +8238,7 @@ async fn build_initial_context_omits_multi_agent_v2_usage_hints_when_hint_is_emp
|
||||
)
|
||||
.await;
|
||||
|
||||
let initial_context = build_initial_context(&session, turn_context.as_ref()).await;
|
||||
let initial_context = build_initial_context(&session, &turn_context).await;
|
||||
|
||||
let developer_messages = developer_message_texts(&initial_context);
|
||||
assert!(
|
||||
@@ -8259,6 +8267,7 @@ async fn build_initial_context_omits_default_image_save_location_with_image_hist
|
||||
/*reference_context_item*/ None,
|
||||
)
|
||||
.await;
|
||||
let turn_context = Arc::new(turn_context);
|
||||
|
||||
let initial_context = build_initial_context(&session, &turn_context).await;
|
||||
let developer_texts = developer_input_texts(&initial_context);
|
||||
@@ -8273,6 +8282,7 @@ async fn build_initial_context_omits_default_image_save_location_with_image_hist
|
||||
#[tokio::test]
|
||||
async fn build_initial_context_omits_default_image_save_location_without_image_history() {
|
||||
let (session, turn_context) = make_session_and_context().await;
|
||||
let turn_context = Arc::new(turn_context);
|
||||
|
||||
let initial_context = build_initial_context(&session, &turn_context).await;
|
||||
let developer_texts = developer_input_texts(&initial_context);
|
||||
@@ -8315,6 +8325,7 @@ async fn build_initial_context_trims_skill_metadata_from_context_window_budget()
|
||||
];
|
||||
turn_context.model_info.context_window = Some(100);
|
||||
turn_context.turn_skills = TurnSkillsContext::new(HostSkillsSnapshot::new(Arc::new(outcome)));
|
||||
let turn_context = Arc::new(turn_context);
|
||||
|
||||
let initial_context = build_initial_context(&session, &turn_context).await;
|
||||
let developer_texts = developer_input_texts(&initial_context);
|
||||
@@ -8466,6 +8477,7 @@ async fn build_initial_context_emits_thread_start_skill_warning_on_repeated_buil
|
||||
];
|
||||
turn_context.model_info.context_window = Some(100);
|
||||
turn_context.turn_skills = TurnSkillsContext::new(HostSkillsSnapshot::new(Arc::new(outcome)));
|
||||
let turn_context = Arc::new(turn_context);
|
||||
|
||||
let _ = build_initial_context(&session, &turn_context).await;
|
||||
let warning_event = timeout(Duration::from_secs(1), rx.recv())
|
||||
@@ -8598,6 +8610,7 @@ async fn build_initial_context_uses_previous_turn_settings_for_realtime_end() {
|
||||
session
|
||||
.set_previous_turn_settings(Some(previous_turn_settings))
|
||||
.await;
|
||||
let turn_context = Arc::new(turn_context);
|
||||
let initial_context = build_initial_context(&session, &turn_context).await;
|
||||
let developer_texts = developer_input_texts(&initial_context);
|
||||
assert!(
|
||||
@@ -8621,6 +8634,7 @@ async fn build_initial_context_restates_realtime_start_when_reference_context_is
|
||||
session
|
||||
.set_previous_turn_settings(Some(previous_turn_settings))
|
||||
.await;
|
||||
let turn_context = Arc::new(turn_context);
|
||||
let initial_context = build_initial_context(&session, &turn_context).await;
|
||||
let developer_texts = developer_input_texts(&initial_context);
|
||||
assert!(
|
||||
@@ -8704,8 +8718,10 @@ async fn turn_context_item_stores_split_file_system_sandbox_policy_when_differen
|
||||
async fn record_context_updates_and_set_reference_context_item_injects_full_context_when_baseline_missing()
|
||||
{
|
||||
let (session, turn_context) = make_session_and_context().await;
|
||||
let turn_context = Arc::new(turn_context);
|
||||
let step_context = StepContext::for_test(Arc::clone(&turn_context));
|
||||
session
|
||||
.record_context_updates_and_set_reference_context_item(&turn_context)
|
||||
.record_context_updates_and_set_reference_context_item(&step_context)
|
||||
.await;
|
||||
let history = session.clone_history().await;
|
||||
let initial_context = build_initial_context(&session, &turn_context).await;
|
||||
@@ -8723,6 +8739,8 @@ async fn record_context_updates_and_set_reference_context_item_injects_full_cont
|
||||
async fn record_context_updates_and_set_reference_context_item_reinjects_full_context_after_clear()
|
||||
{
|
||||
let (session, turn_context) = make_session_and_context().await;
|
||||
let turn_context = Arc::new(turn_context);
|
||||
let step_context = StepContext::for_test(Arc::clone(&turn_context));
|
||||
let compacted_summary = ResponseItem::Message {
|
||||
id: None,
|
||||
role: "user".to_string(),
|
||||
@@ -8736,7 +8754,7 @@ async fn record_context_updates_and_set_reference_context_item_reinjects_full_co
|
||||
.record_conversation_items(&turn_context, std::slice::from_ref(&compacted_summary))
|
||||
.await;
|
||||
session
|
||||
.record_context_updates_and_set_reference_context_item(&turn_context)
|
||||
.record_context_updates_and_set_reference_context_item(&step_context)
|
||||
.await;
|
||||
{
|
||||
let mut state = session.state.lock().await;
|
||||
@@ -8750,7 +8768,7 @@ async fn record_context_updates_and_set_reference_context_item_reinjects_full_co
|
||||
.await;
|
||||
|
||||
session
|
||||
.record_context_updates_and_set_reference_context_item(&turn_context)
|
||||
.record_context_updates_and_set_reference_context_item(&step_context)
|
||||
.await;
|
||||
|
||||
let history = session.clone_history().await;
|
||||
@@ -8773,6 +8791,7 @@ async fn record_context_updates_and_set_reference_context_item_persists_baseline
|
||||
.with_model(next_model.to_string(), &session.services.models_manager)
|
||||
.await;
|
||||
let previous_context_item = previous_context.to_turn_context_item();
|
||||
let previous_context = Arc::new(previous_context);
|
||||
let world_state = build_world_state_from_turn_context(&session, &previous_context).await;
|
||||
{
|
||||
let mut state = session.state.lock().await;
|
||||
@@ -8788,8 +8807,10 @@ async fn record_context_updates_and_set_reference_context_item_persists_baseline
|
||||
.await;
|
||||
assert_eq!(update_items, Vec::new());
|
||||
|
||||
let turn_context = Arc::new(turn_context);
|
||||
let step_context = StepContext::for_test(Arc::clone(&turn_context));
|
||||
session
|
||||
.record_context_updates_and_set_reference_context_item(&turn_context)
|
||||
.record_context_updates_and_set_reference_context_item(&step_context)
|
||||
.await;
|
||||
|
||||
assert_eq!(
|
||||
@@ -8835,8 +8856,10 @@ async fn record_context_updates_and_set_reference_context_item_persists_split_fi
|
||||
);
|
||||
let rollout_path = attach_thread_persistence(&mut session).await;
|
||||
|
||||
let turn_context = Arc::new(turn_context);
|
||||
let step_context = StepContext::for_test(Arc::clone(&turn_context));
|
||||
session
|
||||
.record_context_updates_and_set_reference_context_item(&turn_context)
|
||||
.record_context_updates_and_set_reference_context_item(&step_context)
|
||||
.await;
|
||||
session.ensure_rollout_materialized().await;
|
||||
session.flush_rollout().await.expect("rollout should flush");
|
||||
@@ -8869,6 +8892,7 @@ async fn build_initial_context_prepends_model_switch_message() {
|
||||
session
|
||||
.set_previous_turn_settings(Some(previous_turn_settings))
|
||||
.await;
|
||||
let turn_context = Arc::new(turn_context);
|
||||
let initial_context = build_initial_context(&session, &turn_context).await;
|
||||
|
||||
let ResponseItem::Message { role, content, .. } = &initial_context[0] else {
|
||||
@@ -8919,8 +8943,10 @@ async fn record_context_updates_and_set_reference_context_item_persists_full_rei
|
||||
realtime_active: Some(previous_context.realtime_active),
|
||||
}))
|
||||
.await;
|
||||
let turn_context = Arc::new(turn_context);
|
||||
let step_context = StepContext::for_test(Arc::clone(&turn_context));
|
||||
session
|
||||
.record_context_updates_and_set_reference_context_item(&turn_context)
|
||||
.record_context_updates_and_set_reference_context_item(&step_context)
|
||||
.await;
|
||||
session.ensure_rollout_materialized().await;
|
||||
session.flush_rollout().await.expect("rollout should flush");
|
||||
@@ -10195,7 +10221,7 @@ async fn sample_rollout(
|
||||
// Use the same turn_context source as record_initial_history so model_info (and thus
|
||||
// personality_spec) matches reconstruction.
|
||||
let reconstruction_turn = session.new_default_turn().await;
|
||||
let mut initial_context = build_initial_context(session, reconstruction_turn.as_ref()).await;
|
||||
let mut initial_context = build_initial_context(session, &reconstruction_turn).await;
|
||||
// Ensure personality_spec is present when Personality is enabled, so expected matches
|
||||
// what reconstruction produces (build_initial_context may omit it when baked into model).
|
||||
if !initial_context.iter().any(|m| {
|
||||
|
||||
@@ -530,6 +530,7 @@ async fn process_compacted_history_preserves_separate_guardian_developer_message
|
||||
}
|
||||
turn_context.session_source = guardian_source;
|
||||
turn_context.developer_instructions = Some(guardian_policy.clone());
|
||||
let turn_context = Arc::new(turn_context);
|
||||
let world_state = Arc::new(build_world_state_from_turn_context(&session, &turn_context).await);
|
||||
let initial_context_injection = InitialContextInjection::BeforeLastUserMessage(world_state);
|
||||
|
||||
|
||||
@@ -164,9 +164,11 @@ pub(crate) async fn run_turn(
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
// run_turn owns the step used to seed context and make the first sampling request.
|
||||
let first_step_context = sess.capture_step_context(Arc::clone(&turn_context)).await;
|
||||
// Keep the exact model-visible state used by this turn and its inline compactions.
|
||||
let mut world_state = sess
|
||||
.record_context_updates_and_set_reference_context_item(turn_context.as_ref())
|
||||
.record_context_updates_and_set_reference_context_item(first_step_context.as_ref())
|
||||
.await;
|
||||
|
||||
let Some((injection_items, explicitly_enabled_connectors)) =
|
||||
@@ -214,6 +216,7 @@ pub(crate) async fn run_turn(
|
||||
// 1. At the start of a turn, so the fresh turn input in `input` gets sampled first.
|
||||
// 2. After auto-compact, when model/tool continuation needs to resume before any steer.
|
||||
|
||||
let mut next_step_context = Some(first_step_context);
|
||||
loop {
|
||||
// Note that pending_input would be something like a message the user
|
||||
// submitted through the UI while the model was running. Though the UI
|
||||
@@ -237,7 +240,10 @@ pub(crate) async fn run_turn(
|
||||
.await;
|
||||
|
||||
// Capture once so context, advertised tools, and tool calls share one request view.
|
||||
let step_context = sess.capture_step_context(Arc::clone(&turn_context)).await;
|
||||
let step_context = match next_step_context.take() {
|
||||
Some(step_context) => step_context,
|
||||
None => sess.capture_step_context(Arc::clone(&turn_context)).await,
|
||||
};
|
||||
let sampling_request_result: CodexResult<_> = async {
|
||||
super::time_reminder::maybe_record_current_time_reminder(
|
||||
sess.as_ref(),
|
||||
@@ -252,7 +258,7 @@ pub(crate) async fn run_turn(
|
||||
.enabled(Feature::DeferredExecutor)
|
||||
{
|
||||
world_state = sess
|
||||
.record_step_environment_context_if_changed(&world_state, step_context.as_ref())
|
||||
.record_step_world_state_if_changed(&world_state, step_context.as_ref())
|
||||
.await;
|
||||
}
|
||||
|
||||
@@ -796,6 +802,7 @@ async fn run_pre_sampling_compact(
|
||||
.await;
|
||||
// Compact if the configured auto-compaction budget or usable context window is exhausted.
|
||||
if token_status.token_limit_reached {
|
||||
// Pre-turn compaction runs before run_turn creates the normal sampling step.
|
||||
let step_context = sess.capture_step_context(Arc::clone(turn_context)).await;
|
||||
run_auto_compact(
|
||||
sess,
|
||||
@@ -841,6 +848,7 @@ async fn maybe_run_previous_model_inline_compact(
|
||||
);
|
||||
|
||||
if should_compact_for_comp_hash_change {
|
||||
// This pre-turn request needs a step built from the previous model's turn context.
|
||||
let step_context = sess
|
||||
.capture_step_context(Arc::clone(&previous_model_turn_context))
|
||||
.await;
|
||||
@@ -881,6 +889,7 @@ async fn maybe_run_previous_model_inline_compact(
|
||||
&& previous_model_turn_context.model_info.slug != turn_context.model_info.slug
|
||||
&& old_context_window > new_context_window;
|
||||
if should_run {
|
||||
// This pre-turn request needs a step built from the previous model's turn context.
|
||||
let step_context = sess
|
||||
.capture_step_context(Arc::clone(&previous_model_turn_context))
|
||||
.await;
|
||||
@@ -916,7 +925,7 @@ async fn run_auto_compact(
|
||||
// instead of consuming a pending `new_context` tool request.
|
||||
crate::compact_token_budget::run_inline_auto_compact_task(
|
||||
Arc::clone(sess),
|
||||
Arc::clone(turn_context),
|
||||
step_context,
|
||||
initial_context_injection,
|
||||
)
|
||||
.await?;
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
use super::*;
|
||||
use crate::agents_md::LoadedAgentsMd;
|
||||
use crate::environment_selection::TurnEnvironmentSnapshot;
|
||||
use crate::shell_snapshot::ShellSnapshotFile;
|
||||
use codex_core_skills::HostSkillsSnapshot;
|
||||
@@ -124,7 +123,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) user_instructions: Option<String>,
|
||||
pub(crate) collaboration_mode: CollaborationMode,
|
||||
pub(crate) multi_agent_version: MultiAgentVersion,
|
||||
pub(crate) personality: Option<Personality>,
|
||||
@@ -273,7 +271,6 @@ impl TurnContext {
|
||||
timezone: self.timezone.clone(),
|
||||
app_server_client_name: self.app_server_client_name.clone(),
|
||||
developer_instructions: self.developer_instructions.clone(),
|
||||
user_instructions: self.user_instructions.clone(),
|
||||
collaboration_mode,
|
||||
multi_agent_version: self.multi_agent_version,
|
||||
personality: self.personality,
|
||||
@@ -552,10 +549,6 @@ impl Session {
|
||||
timezone: Some(timezone),
|
||||
app_server_client_name: session_configuration.app_server_client_name.clone(),
|
||||
developer_instructions: session_configuration.developer_instructions.clone(),
|
||||
user_instructions: session_configuration
|
||||
.loaded_agents_md
|
||||
.as_ref()
|
||||
.map(LoadedAgentsMd::render),
|
||||
collaboration_mode: session_configuration.collaboration_mode.clone(),
|
||||
multi_agent_version,
|
||||
personality: session_configuration.personality,
|
||||
|
||||
@@ -1,19 +1,35 @@
|
||||
use super::turn_context::TurnContext;
|
||||
use super::session::Session;
|
||||
use super::step_context::StepContext;
|
||||
use crate::context::world_state::AgentsMdState;
|
||||
use crate::context::world_state::EnvironmentsState;
|
||||
use crate::context::world_state::WorldState;
|
||||
use crate::environment_selection::TurnEnvironmentSnapshot;
|
||||
|
||||
pub(super) fn build_world_state_from_environment_snapshot(
|
||||
turn_context: &TurnContext,
|
||||
environments: &TurnEnvironmentSnapshot,
|
||||
environment_subagents: &str,
|
||||
) -> WorldState {
|
||||
let mut world_state = WorldState::default();
|
||||
if turn_context.config.include_environment_context {
|
||||
world_state.add_section(
|
||||
EnvironmentsState::from_turn_context_with_environments(turn_context, environments)
|
||||
.with_subagents(environment_subagents.to_string()),
|
||||
);
|
||||
impl Session {
|
||||
pub(crate) async fn build_world_state_for_step(
|
||||
&self,
|
||||
step_context: &StepContext,
|
||||
) -> WorldState {
|
||||
let turn_context = step_context.turn.as_ref();
|
||||
let environment_subagents = if turn_context.config.include_environment_context {
|
||||
self.services
|
||||
.agent_control
|
||||
.format_environment_context_subagents(self.thread_id)
|
||||
.await
|
||||
} else {
|
||||
String::new()
|
||||
};
|
||||
|
||||
let mut world_state = WorldState::default();
|
||||
world_state.add_section(AgentsMdState::new(step_context.loaded_agents_md.as_deref()));
|
||||
if turn_context.config.include_environment_context {
|
||||
world_state.add_section(
|
||||
EnvironmentsState::from_turn_context_with_environments(
|
||||
turn_context,
|
||||
&step_context.environments,
|
||||
)
|
||||
.with_subagents(environment_subagents),
|
||||
);
|
||||
}
|
||||
world_state
|
||||
}
|
||||
world_state
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user