mirror of
https://github.com/openai/codex.git
synced 2026-10-24 18:18:41 +00:00
Overlap plugin and model discovery during startup
This commit is contained in:
@@ -16,6 +16,7 @@ use crate::app_event::RealtimeAudioDeviceKind;
|
||||
#[cfg(target_os = "windows")]
|
||||
use crate::app_event::WindowsSandboxEnableMode;
|
||||
use crate::app_event_sender::AppEventSender;
|
||||
use crate::app_server_session::AppServerBootstrap;
|
||||
use crate::app_server_session::AppServerSession;
|
||||
use crate::app_server_session::AppServerStartedThread;
|
||||
use crate::app_server_session::TurnPermissionsOverride;
|
||||
@@ -727,6 +728,8 @@ impl App {
|
||||
app_server_target: AppServerTarget,
|
||||
state_db: Option<StateDbHandle>,
|
||||
environment_manager: Arc<EnvironmentManager>,
|
||||
startup_elapsed_before_app: Duration,
|
||||
startup_bootstrap: Option<AppServerBootstrap>,
|
||||
startup_hooks_browser: Option<HooksListEntry>,
|
||||
) -> Result<AppExitInfo> {
|
||||
use tokio_stream::StreamExt;
|
||||
@@ -774,9 +777,11 @@ impl App {
|
||||
});
|
||||
}
|
||||
};
|
||||
let bootstrap_started_at = Instant::now();
|
||||
let bootstrap = app_server.bootstrap(&config).await?;
|
||||
let bootstrap_ms = bootstrap_started_at.elapsed().as_millis();
|
||||
let bootstrap = match startup_bootstrap {
|
||||
Some(bootstrap) => bootstrap,
|
||||
None => app_server.bootstrap(&config).await?,
|
||||
};
|
||||
let bootstrap_ms = bootstrap.duration.as_millis();
|
||||
let mut model = bootstrap.default_model;
|
||||
let available_models = bootstrap.available_models;
|
||||
let remote_connection = crate::status::remote_connection::remote_connection_status_value(
|
||||
@@ -1085,7 +1090,7 @@ See the Codex keymap documentation for supported actions and examples."
|
||||
|
||||
tui.frame_requester().schedule_frame();
|
||||
tracing::info!(
|
||||
duration_ms = %startup_started_at.elapsed().as_millis(),
|
||||
duration_ms = %(startup_elapsed_before_app + startup_started_at.elapsed()).as_millis(),
|
||||
bootstrap_ms = %bootstrap_ms,
|
||||
runtime_model_provider_ms = %runtime_model_provider_ms,
|
||||
thread_and_widget_ms = %thread_and_widget_ms,
|
||||
|
||||
@@ -127,6 +127,8 @@ use color_eyre::eyre::Result;
|
||||
use color_eyre::eyre::WrapErr;
|
||||
use std::collections::HashMap;
|
||||
use std::path::PathBuf;
|
||||
use std::time::Duration;
|
||||
use std::time::Instant;
|
||||
use uuid::Uuid;
|
||||
|
||||
const JSONRPC_INVALID_REQUEST: i64 = -32600;
|
||||
@@ -150,6 +152,7 @@ fn is_thread_settings_update_unsupported(source: &JSONRPCErrorError) -> bool {
|
||||
/// fetched asynchronously after bootstrap returns so that the TUI can render
|
||||
/// its first frame without waiting for the rate-limit round-trip.
|
||||
pub(crate) struct AppServerBootstrap {
|
||||
pub(crate) duration: Duration,
|
||||
pub(crate) account_email: Option<String>,
|
||||
pub(crate) auth_mode: Option<TelemetryAuthMode>,
|
||||
pub(crate) status_account_display: Option<StatusAccountDisplay>,
|
||||
@@ -239,6 +242,7 @@ impl AppServerSession {
|
||||
}
|
||||
|
||||
pub(crate) async fn bootstrap(&mut self, config: &Config) -> Result<AppServerBootstrap> {
|
||||
let started_at = Instant::now();
|
||||
let account = self.read_account().await?;
|
||||
let model_request_id = self.next_request_id();
|
||||
let models: ModelListResponse = self
|
||||
@@ -314,6 +318,7 @@ impl AppServerSession {
|
||||
None => (None, None, None, None, FeedbackAudience::External, false),
|
||||
};
|
||||
Ok(AppServerBootstrap {
|
||||
duration: started_at.elapsed(),
|
||||
account_email,
|
||||
auth_mode,
|
||||
status_account_display,
|
||||
|
||||
@@ -25,7 +25,7 @@ pub(crate) enum ExternalAgentConfigMigrationStartupOutcome {
|
||||
ExitRequested,
|
||||
}
|
||||
|
||||
fn should_show_external_agent_config_migration_prompt(
|
||||
pub(crate) fn should_show_external_agent_config_migration_prompt(
|
||||
config: &Config,
|
||||
entered_trust_nux: bool,
|
||||
) -> bool {
|
||||
|
||||
@@ -71,6 +71,7 @@ use std::fs::OpenOptions;
|
||||
use std::path::Path;
|
||||
use std::path::PathBuf;
|
||||
use std::sync::Arc;
|
||||
use std::time::Instant;
|
||||
pub use token_usage::TokenUsage;
|
||||
use tracing::Level;
|
||||
use tracing::error;
|
||||
@@ -276,6 +277,7 @@ pub(crate) mod test_support;
|
||||
use crate::onboarding::onboarding_screen::OnboardingScreenArgs;
|
||||
use crate::onboarding::onboarding_screen::run_onboarding_app;
|
||||
use crate::startup_hooks_review::StartupHooksReviewOutcome;
|
||||
use crate::startup_hooks_review::load_startup_hooks_review_entry;
|
||||
use crate::startup_hooks_review::maybe_run_startup_hooks_review;
|
||||
use crate::tui::Tui;
|
||||
pub use cli::Cli;
|
||||
@@ -1781,11 +1783,33 @@ async fn run_ratatui_app(
|
||||
resume_picker::SessionSelection::Resume(_)
|
||||
);
|
||||
let bypass_hook_trust_for_startup_review = config.bypass_hook_trust && !is_persistent_resume;
|
||||
let hooks_request_handle = app_server.request_handle();
|
||||
let hooks_cwd = config.cwd.to_path_buf();
|
||||
let startup_prefetch_started_at = Instant::now();
|
||||
let should_defer_bootstrap =
|
||||
external_agent_config_migration_startup::should_show_external_agent_config_migration_prompt(
|
||||
&config,
|
||||
should_show_trust_screen_flag,
|
||||
);
|
||||
let (startup_bootstrap, startup_hooks_entry) = if should_defer_bootstrap {
|
||||
(
|
||||
None,
|
||||
load_startup_hooks_review_entry(hooks_request_handle, hooks_cwd).await,
|
||||
)
|
||||
} else {
|
||||
let (bootstrap, entry) = tokio::join!(
|
||||
app_server.bootstrap(&config),
|
||||
load_startup_hooks_review_entry(hooks_request_handle, hooks_cwd),
|
||||
);
|
||||
(Some(bootstrap?), entry)
|
||||
};
|
||||
let startup_elapsed_before_app = startup_prefetch_started_at.elapsed();
|
||||
let startup_hooks_browser = match maybe_run_startup_hooks_review(
|
||||
&mut app_server,
|
||||
&mut tui,
|
||||
&config,
|
||||
bypass_hook_trust_for_startup_review,
|
||||
startup_hooks_entry,
|
||||
)
|
||||
.await?
|
||||
{
|
||||
@@ -1810,6 +1834,8 @@ async fn run_ratatui_app(
|
||||
app_server_target,
|
||||
state_db,
|
||||
environment_manager,
|
||||
startup_elapsed_before_app,
|
||||
startup_bootstrap,
|
||||
startup_hooks_browser,
|
||||
)
|
||||
.await;
|
||||
|
||||
@@ -28,7 +28,9 @@ use crate::render::renderable::ColumnRenderable;
|
||||
use crate::render::renderable::Renderable;
|
||||
use crate::tui::Tui;
|
||||
use crate::tui::TuiEvent;
|
||||
use codex_app_server_client::AppServerRequestHandle;
|
||||
use codex_app_server_protocol::HooksListEntry;
|
||||
use std::path::PathBuf;
|
||||
|
||||
pub(crate) enum StartupHooksReviewOutcome {
|
||||
Continue,
|
||||
@@ -42,21 +44,32 @@ enum StartupHooksReviewSelection {
|
||||
ContinueWithoutTrusting,
|
||||
}
|
||||
|
||||
pub(crate) async fn load_startup_hooks_review_entry(
|
||||
request_handle: AppServerRequestHandle,
|
||||
cwd: PathBuf,
|
||||
) -> HooksListEntry {
|
||||
let response = match fetch_hooks_list(request_handle, cwd.clone()).await {
|
||||
Ok(response) => response,
|
||||
Err(err) => {
|
||||
tracing::warn!("failed to load startup hook review state: {err:#}");
|
||||
return HooksListEntry {
|
||||
cwd,
|
||||
hooks: Vec::new(),
|
||||
warnings: Vec::new(),
|
||||
errors: Vec::new(),
|
||||
};
|
||||
}
|
||||
};
|
||||
hooks_list_entry_for_cwd(response, &cwd)
|
||||
}
|
||||
|
||||
pub(crate) async fn maybe_run_startup_hooks_review(
|
||||
app_server: &mut AppServerSession,
|
||||
tui: &mut Tui,
|
||||
config: &Config,
|
||||
bypass_hook_trust: bool,
|
||||
entry: HooksListEntry,
|
||||
) -> Result<StartupHooksReviewOutcome> {
|
||||
let cwd = config.cwd.to_path_buf();
|
||||
let response = match fetch_hooks_list(app_server.request_handle(), cwd.clone()).await {
|
||||
Ok(response) => response,
|
||||
Err(err) => {
|
||||
tracing::warn!("failed to load startup hook review state: {err:#}");
|
||||
return Ok(StartupHooksReviewOutcome::Continue);
|
||||
}
|
||||
};
|
||||
let entry = hooks_list_entry_for_cwd(response, &cwd);
|
||||
if !review_is_needed(bypass_hook_trust, &entry) {
|
||||
return Ok(StartupHooksReviewOutcome::Continue);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user