mirror of
https://github.com/openai/codex.git
synced 2026-11-13 06:45:07 +00:00
Retain the last selected step context for each turn (#41429)
## What changed - Store the most recently captured execution `StepContext` in the active turn state. - Keep speculative model-fallback captures from replacing that context, and update it only when the fallback is selected for remote compaction. - Preserve the retained context when a turn completes or is interrupted. ## Testing - Add coverage for completed and interrupted turns, successful primary compaction, fallback compaction, and interruption while a fallback is running. GitOrigin-RevId: c7dee36ec8e88ba2f4fb4a9c0322e5c86a0caf0e
This commit is contained in:
1 parent
2008d27e98
commit
0d22692962
7 files changed
+356
-36
No files matched your search
@@ -3305,12 +3305,28 @@ impl Session {
|
||||
Ok(world_state)
|
||||
}
|
||||
|
||||
/// Captures one request-scoped view of dynamic state.
|
||||
/// Retains the step captured for execution.
|
||||
pub(crate) async fn set_last_known_step_context(&self, step_context: &Arc<StepContext>) {
|
||||
let turn_state = {
|
||||
let active_turn = self.active_turn.lock().await;
|
||||
active_turn.as_ref().and_then(|active_turn| {
|
||||
active_turn
|
||||
.task
|
||||
.as_ref()
|
||||
.filter(|task| task.turn_context.sub_id == step_context.turn.sub_id)
|
||||
.map(|_| Arc::clone(&active_turn.turn_state))
|
||||
})
|
||||
};
|
||||
if let Some(turn_state) = turn_state {
|
||||
turn_state.lock().await.last_known_step_context = Some(Arc::clone(step_context));
|
||||
}
|
||||
}
|
||||
|
||||
/// Captures one request-scoped view of dynamic state and retains it for the active turn.
|
||||
///
|
||||
/// 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.
|
||||
#[tracing::instrument(name = "step_context.capture", level = "info", skip_all)]
|
||||
/// their own step. Use speculative capture for a step that may not execute.
|
||||
pub(crate) async fn capture_step_context(
|
||||
self: &Arc<Self>,
|
||||
turn_context: Arc<TurnContext>,
|
||||
@@ -3329,6 +3345,35 @@ impl Session {
|
||||
turn_context: Arc<TurnContext>,
|
||||
cancellation_token: &CancellationToken,
|
||||
required_servers: &[String],
|
||||
) -> CodexResult<Arc<StepContext>> {
|
||||
let step_context = self
|
||||
.capture_step_context_inner(turn_context, cancellation_token, required_servers)
|
||||
.await?;
|
||||
self.set_last_known_step_context(&step_context).await;
|
||||
Ok(step_context)
|
||||
}
|
||||
|
||||
/// Prepares a candidate step without replacing the active turn's retained context.
|
||||
/// The caller must retain it explicitly if it is selected for execution.
|
||||
async fn capture_speculative_step_context(
|
||||
self: &Arc<Self>,
|
||||
turn_context: Arc<TurnContext>,
|
||||
cancellation_token: &CancellationToken,
|
||||
) -> CodexResult<Arc<StepContext>> {
|
||||
self.capture_step_context_inner(
|
||||
turn_context,
|
||||
cancellation_token,
|
||||
/*required_servers*/ &[],
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
#[tracing::instrument(name = "step_context.capture", level = "info", skip_all)]
|
||||
async fn capture_step_context_inner(
|
||||
self: &Arc<Self>,
|
||||
turn_context: Arc<TurnContext>,
|
||||
cancellation_token: &CancellationToken,
|
||||
required_servers: &[String],
|
||||
) -> CodexResult<Arc<StepContext>> {
|
||||
// Capture once before asynchronous planning; all request consumers
|
||||
// retain this immutable settings version even if the turn is updated.
|
||||
|
||||
Reference in new issue
Block a user