mirror of
https://github.com/openai/codex.git
synced 2026-10-26 18:38:47 +00:00
Separate TUI preferences from server configuration (#42202)
## Why TUI preferences and persistence paths belong to the local client, while thread configuration and account requirements may come from the active app server. Keeping both in the same resolved `Config` can replace live local preferences when a thread is resumed, forked, reconnected, or switched. ## What changed - Add `LocalSettings` as the TUI-owned source for UI, history, notice, and local persistence settings, and preserve it across session lifecycle transitions. - Write preference changes to the selected user config file and reload local settings from disk when changing roots. - Use the app server's account response for authentication-dependent onboarding and status UI instead of the local model-provider configuration. - Retain platform family and OS metadata reported by remote app servers. ## Testing - Cover local setting defaults, overrides, persistence destinations, reloads, and preservation across widget replacement and root switching. - Cover remote platform metadata and server-controlled authentication UI. GitOrigin-RevId: dbc2965fb1d6cbecb3f973f6133f3dcd4467b753
This commit is contained in:
@@ -201,6 +201,7 @@ impl AppServerSession {
|
||||
turn_cursor: Option<String>,
|
||||
item_cursor: Option<String>,
|
||||
config: Option<&Config>,
|
||||
local_settings: Option<&crate::local_settings::LocalSettings>,
|
||||
scope: HistoryHydrationScope,
|
||||
) -> Result<()> {
|
||||
let thread_id = ThreadId::from_string(&thread.id)
|
||||
@@ -226,8 +227,8 @@ impl AppServerSession {
|
||||
let width = crossterm::terminal::size()
|
||||
.map(|(width, _)| width.max(/*other*/ 1))
|
||||
.unwrap_or(/*default*/ 80);
|
||||
let row_budget =
|
||||
config.and_then(|config| resize_reflow_max_rows(config.terminal_resize_reflow));
|
||||
let row_budget = local_settings
|
||||
.and_then(|settings| resize_reflow_max_rows(settings.terminal_resize_reflow()));
|
||||
let item_budget = match (scope, config, row_budget) {
|
||||
(HistoryHydrationScope::Complete, _, _)
|
||||
| (HistoryHydrationScope::Initial, Some(_), None) => None,
|
||||
@@ -268,9 +269,16 @@ impl AppServerSession {
|
||||
let items = self
|
||||
.merge_thread_item_page(thread_id, page, &mut state, &mut thread.turns)
|
||||
.await?;
|
||||
if let Some(config) = config {
|
||||
rendered_rows =
|
||||
rendered_history_rows(thread_id, thread, items, config, width, rendered_rows);
|
||||
if let Some((config, local_settings)) = config.zip(local_settings) {
|
||||
rendered_rows = rendered_history_rows(
|
||||
thread_id,
|
||||
thread,
|
||||
items,
|
||||
config,
|
||||
local_settings,
|
||||
width,
|
||||
rendered_rows,
|
||||
);
|
||||
} else {
|
||||
rendered_rows = rendered_rows.saturating_add(items.len());
|
||||
}
|
||||
@@ -290,6 +298,7 @@ fn rendered_history_rows(
|
||||
thread: &Thread,
|
||||
items: Vec<ThreadItem>,
|
||||
config: &Config,
|
||||
local_settings: &crate::local_settings::LocalSettings,
|
||||
width: u16,
|
||||
rendered_rows: usize,
|
||||
) -> usize {
|
||||
@@ -298,7 +307,7 @@ fn rendered_history_rows(
|
||||
} else {
|
||||
RawReasoningVisibility::Hidden
|
||||
};
|
||||
let mode = if config.tui_raw_output_mode {
|
||||
let mode = if local_settings.tui.raw_output_mode {
|
||||
HistoryRenderMode::Raw
|
||||
} else {
|
||||
HistoryRenderMode::Rich
|
||||
|
||||
@@ -50,6 +50,7 @@ impl AppServerSession {
|
||||
|
||||
pub(crate) async fn resume_thread(
|
||||
&mut self,
|
||||
local_settings: &crate::local_settings::LocalSettings,
|
||||
config: Config,
|
||||
thread_id: ThreadId,
|
||||
model_settings: ResumeModelSettings,
|
||||
@@ -138,6 +139,7 @@ impl AppServerSession {
|
||||
response.turns_backwards_cursor.clone(),
|
||||
response.items_backwards_cursor.clone(),
|
||||
Some(&config),
|
||||
Some(local_settings),
|
||||
HistoryHydrationScope::Initial,
|
||||
)
|
||||
.await?;
|
||||
|
||||
@@ -44,7 +44,12 @@ async fn legacy_resume_preserves_history_mode_after_picker_server_replacement()
|
||||
app_server.remember_thread_history_mode(thread_id, history_mode);
|
||||
let next_request_id = app_server.next_request_id;
|
||||
let resumed = app_server
|
||||
.resume_thread(config, thread_id, ResumeModelSettings::RestoreFromThread)
|
||||
.resume_thread(
|
||||
&crate::local_settings::LocalSettings::from(&config),
|
||||
config,
|
||||
thread_id,
|
||||
ResumeModelSettings::RestoreFromThread,
|
||||
)
|
||||
.await?;
|
||||
|
||||
assert_eq!(app_server.next_request_id, next_request_id + 2);
|
||||
@@ -95,6 +100,7 @@ async fn background_migration_disables_cached_legacy_resume_shortcut() -> Result
|
||||
let next_request_id = app_server.next_request_id;
|
||||
let legacy = app_server
|
||||
.resume_thread(
|
||||
&crate::local_settings::LocalSettings::from(resume_config),
|
||||
resume_config.clone(),
|
||||
legacy_thread_id,
|
||||
ResumeModelSettings::RestoreFromThread,
|
||||
@@ -108,6 +114,7 @@ async fn background_migration_disables_cached_legacy_resume_shortcut() -> Result
|
||||
|
||||
let resumed = app_server
|
||||
.resume_thread(
|
||||
&crate::local_settings::LocalSettings::from(resume_config),
|
||||
resume_config.clone(),
|
||||
thread_id,
|
||||
ResumeModelSettings::RestoreFromThread,
|
||||
@@ -152,7 +159,12 @@ async fn rollout_maintenance_contention_disables_cached_legacy_resume_shortcut()
|
||||
let next_request_id = app_server.next_request_id;
|
||||
|
||||
let resumed = app_server
|
||||
.resume_thread(config, thread_id, ResumeModelSettings::RestoreFromThread)
|
||||
.resume_thread(
|
||||
&crate::local_settings::LocalSettings::from(&config),
|
||||
config,
|
||||
thread_id,
|
||||
ResumeModelSettings::RestoreFromThread,
|
||||
)
|
||||
.await?;
|
||||
|
||||
assert_eq!(app_server.next_request_id, next_request_id + 3);
|
||||
@@ -190,6 +202,7 @@ async fn stale_legacy_history_mode_is_revalidated_before_resume() -> Result<()>
|
||||
|
||||
let resumed = app_server
|
||||
.resume_thread(
|
||||
&crate::local_settings::LocalSettings::from(&config),
|
||||
config.clone(),
|
||||
thread_id,
|
||||
ResumeModelSettings::RestoreFromThread,
|
||||
@@ -211,6 +224,7 @@ async fn stale_legacy_history_mode_is_revalidated_before_resume() -> Result<()>
|
||||
assert!(
|
||||
app_server
|
||||
.resume_thread(
|
||||
&crate::local_settings::LocalSettings::from(&config),
|
||||
config,
|
||||
missing_thread_id,
|
||||
ResumeModelSettings::RestoreFromThread
|
||||
|
||||
Reference in New Issue
Block a user