Keep settings operations bound to their committed snapshot (#40645)

## Why

Post-commit work can overlap with another settings write. Reading the session
again afterward could make a settings operation report or use the later state
instead of the state that it committed.

## What changed

- Return the committed configuration and `ThreadSettingsSnapshot` from session
  settings updates.
- Use that commit result when creating a turn and emitting
  `ThreadSettingsApplied`, while retaining current-state snapshots for
  synthesized fork history.
- Route turn-start updates through the shared settings update path.

## Testing

Add coverage for standalone and turn-start updates that pause after committing,
restore different settings concurrently, and verify that each operation keeps
its original configuration and notification snapshot.

GitOrigin-RevId: cee5be9536d2840170893e6eb0c64cd039fb0a96
This commit is contained in:
joeflorencio-openai authored and copyberry committed 2026-08-25 17:20:37 +00:00
1 parent a95391160a
commit 4e883ce36e
10 files changed
+279 -91

No files matched your search

+11 -3
View File
@@ -249,6 +249,7 @@ use self::review::spawn_review_thread;
use self::session::AppServerClientMetadata;
use self::session::Session;
use self::session::SessionConfiguration;
use self::session::SessionSettingsCommit;
pub(crate) use self::session::SessionSettingsUpdate;
#[cfg(test)]
use self::turn::AssistantMessageStreamParsers;
@@ -1596,9 +1597,9 @@ impl Session {
pub(crate) async fn update_settings(
&self,
updates: SessionSettingsUpdate,
) -> ConstraintResult<()> {
) -> ConstraintResult<SessionSettingsCommit> {
let notify_config_contributors = !self.services.extensions.config_contributors().is_empty();
let (previous_config, new_config, permission_profile_changed, mcp_inputs_changed) = {
let (commit, previous_config, new_config, permission_profile_changed, mcp_inputs_changed) = {
let mut state = self.state.lock().await;
let updated = match self.apply_session_settings(&state.session_configuration, &updates)
{
@@ -1635,7 +1636,14 @@ impl Session {
state.session_configuration = updated;
let new_config = notify_config_contributors
.then(|| self.build_effective_session_config(&state.session_configuration));
let commit = SessionSettingsCommit {
configuration: state.session_configuration.clone(),
snapshot: state
.session_configuration
.thread_settings_snapshot(&self.services.turn_environments.selections()),
};
(
commit,
previous_config,
new_config,
permission_profile_changed,
@@ -1650,7 +1658,7 @@ impl Session {
if mcp_inputs_changed {
self.schedule_mcp_prewarm();
}
Ok(())
Ok(commit)
}
pub(crate) async fn preview_settings(