Add a turn-scoped service tier override (#40616)

## What changed

- Add `serviceTierForTurn` to `turn/start` so a newly started turn can override the service tier without changing the thread's saved tier.
- Treat `"default"` as standard speed and omitted or `null` values as inheriting the thread tier.
- Keep `serviceTier` authoritative for subsequent turns when both fields are supplied, and ignore the turn-scoped override when steering an active turn.

## Testing

- Extend the app-server turn-start test to verify both the one-turn `"default"` override and inheritance on the following turn.

GitOrigin-RevId: 4c2c4db21d8d31617a7a6e6df65bf54834e72383
This commit is contained in:
chess
2026-08-25 14:04:32 +00:00
committed by copyberry
parent d7510aa4b4
commit ed42068c45
21 changed files with 86 additions and 3 deletions
+1
View File
@@ -602,6 +602,7 @@ pub(crate) struct SessionSettingsUpdate {
pub(crate) collaboration_mode: Option<CollaborationMode>,
pub(crate) reasoning_summary: Option<ReasoningSummaryConfig>,
pub(crate) service_tier: Option<Option<String>>,
pub(crate) service_tier_for_turn: Option<String>,
pub(crate) final_output_json_schema: Option<Option<Value>>,
pub(crate) personality: Option<Personality>,
pub(crate) app_server_client_name: Option<String>,
+5 -1
View File
@@ -788,7 +788,7 @@ impl Session {
};
let (
session_configuration,
mut session_configuration,
mcp_inputs_changed,
permission_profile_changed,
previous_config,
@@ -817,6 +817,10 @@ impl Session {
self.refresh_managed_network_proxy_for_current_permission_profile()
.await;
}
// Apply the override only to the turn's copy, after persisting thread settings.
if let Some(service_tier) = updates.service_tier_for_turn {
session_configuration.service_tier = Some(service_tier);
}
Ok(self
.new_turn_from_configuration(
sub_id,
+2
View File
@@ -98,12 +98,14 @@ impl PreparedTurnInputSettings {
) -> CodexResult<Arc<TurnContext>> {
let TurnStartOptions {
final_output_json_schema,
service_tier,
parent_turn_id,
root_turn_id,
} = self.start_options;
let emit_thread_settings_applied = self.thread_settings_update.is_some();
let mut updates = self.thread_settings_update.unwrap_or_default();
updates.final_output_json_schema = Some(final_output_json_schema);
updates.service_tier_for_turn = service_tier;
// new_turn_with_sub_id already emits an error event when settings are invalid.
let turn_context = session