@setoelkahfi / sigit / commits / 6bf9997

Add /reload command to re-sync session state in place

Logging in mid-session shouldn't require recreating the session. /reload re-applies the active backend from current credentials (picking up a fresh /login token), retries a failed startup model load, and pushes refreshed config options + available commands so the editor's UI reflects current state — all without a new session. Also: - Correct the /login message: it no longer claims sign-in "applies to your next session" (the backend swaps in-session); it now points to /models. - /logout drops back to the local backend when leaving a cloud tier. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

Seto Elkahfi committed Jun 24, 2026 at 17:22 UTC 6bf9997f89dd9ddde22b0811e175ae8d9920ea5d
1 file changed +83 -2
src/main.rs
+83 -2
index 180d265..16a2971 100644 --- a/src/main.rs +++ b/src/main.rs @@ -46,7 +46,8 @@ use onde::inference::SamplingConfig; use agent_client_protocol::schema::{ AgentCapabilities, AuthMethod, AuthMethodAgent, AuthenticateRequest, AuthenticateResponse, - AvailableCommand, AvailableCommandInput, AvailableCommandsUpdate, UnstructuredCommandInput, + AvailableCommand, AvailableCommandInput, AvailableCommandsUpdate, ConfigOptionUpdate, + UnstructuredCommandInput, CancelNotification, ContentBlock, ContentChunk, EmbeddedResourceResource, ForkSessionRequest, ForkSessionResponse, Implementation, InitializeRequest, InitializeResponse, LoadSessionRequest, LoadSessionResponse, Meta, NewSessionRequest, NewSessionResponse, PromptRequest, @@ -596,6 +597,7 @@ impl SiGitAgent { with_hint("login", "Sign in to siGit Code Cloud", "<email> <password>"), AvailableCommand::new("logout", "Sign out of siGit Code Cloud"), AvailableCommand::new("whoami", "Show the signed-in account"), + AvailableCommand::new("reload", "Re-sync sign-in and model state"), AvailableCommand::new("clear", "Wipe the conversation history"), AvailableCommand::new("status", "Show engine status"), ]; @@ -1214,6 +1216,70 @@ impl SiGitAgent { *self.backend.lock().await = local_backend; } + /// Re-attempt the lazy startup model load if the previous attempt failed. + /// Clears the one-shot guard so the next load runs; a healthy load is left + /// untouched so `/reload` doesn't needlessly reload a working model. + fn retry_startup_model_load_if_failed(&self) { + let had_error = self + .model_load_error + .lock() + .map(|guard| guard.is_some()) + .unwrap_or(false); + if had_error { + self.startup_model_load_started + .store(false, Ordering::Release); + self.start_startup_model_load_if_needed(); + } + } + + /// Re-sync session state in place — no new session needed. Re-applies the + /// active backend from current credentials (so a fresh `/login` token is + /// picked up), retries a failed model load, and pushes refreshed commands + + /// picker so the editor's UI reflects the current state. + async fn handle_reload(&self, cx: &ConnectionTo<Client>, session_id: SessionId) { + let signed_in = account::status_line().await; + + let on_cloud_tier = { + let guard = self.current_model.lock().unwrap(); + guard + .model_id + .strip_prefix("sigit-cloud:") + .map(str::to_string) + }; + + let backend_note = match on_cloud_tier { + Some(tier) => match self.switch_to_cloud_tier(&tier).await { + Some(name) => format!("Active: {name}."), + None => { + self.reset_to_local_backend().await; + "Signed out — back to on-device. Pick a model with /models.".to_string() + } + }, + None => { + self.reset_to_local_backend().await; + self.retry_startup_model_load_if_failed(); + let guard = self.current_model.lock().unwrap(); + format!("Active: {}.", guard.display_name) + } + }; + + // Push refreshed picker + commands so the editor reflects current state. + let config_options = { + let guard = self.current_model.lock().unwrap(); + build_model_config_options(&guard) + }; + self.send_tool_call_update( + cx, + session_id.clone(), + SessionUpdate::ConfigOptionUpdate(ConfigOptionUpdate::new(config_options)), + ) + .ok(); + self.advertise_commands(cx, session_id.clone()); + + self.send_assistant_message(cx, session_id, format!("Reloaded. {signed_in} {backend_note}")) + .ok(); + } + async fn handle_set_session_config_option( &self, cx: &ConnectionTo<Client>, @@ -1609,6 +1675,8 @@ enum SlashCommand { Login(Option<String>), Logout, Whoami, + /// Re-sync session state (auth, backend, picker) without a new session. + Reload, Exit, Unknown(String), } @@ -1629,6 +1697,7 @@ fn parse_slash(input: &str) -> Option<SlashCommand> { "/login" => SlashCommand::Login(argument.map(str::to_string)), "/logout" => SlashCommand::Logout, "/whoami" => SlashCommand::Whoami, + "/reload" => SlashCommand::Reload, "/exit" | "/quit" | "/q" => SlashCommand::Exit, other => SlashCommand::Unknown(other.to_string()), }) @@ -1722,6 +1791,7 @@ async fn exec_slash_acp( /login E P - sign in to siGit Code Cloud\n\ /logout - sign out\n\ /whoami - show the signed-in account\n\ + /reload - re-sync sign-in and model state\n\ /clear - wipe conversation history\n\ /status - show engine status\n\ /exit - end this turn", @@ -1858,7 +1928,7 @@ async fn exec_slash_acp( let message = match argument.as_deref().and_then(account::parse_login_args) { Some((email, password)) => match account::authenticate(&email, &password).await { Ok(email) => format!( - "Signed in as {email}. siGit Code Cloud applies to your next session." + "Signed in as {email}. Pick a siGit Code Cloud tier in /models to use it." ), Err(error) => format!("Login failed: {error}"), }, @@ -1867,13 +1937,24 @@ async fn exec_slash_acp( agent.send_assistant_message(cx, session_id, message).ok(); } SlashCommand::Logout => { + // If we're on a cloud tier, drop back to local — the token is gone. + let on_cloud = { + let guard = agent.current_model.lock().unwrap(); + guard.model_id.starts_with("sigit-cloud:") + }; let message = account::end_session().await; + if on_cloud { + agent.reset_to_local_backend().await; + } agent.send_assistant_message(cx, session_id, message).ok(); } SlashCommand::Whoami => { let message = account::status_line().await; agent.send_assistant_message(cx, session_id, message).ok(); } + SlashCommand::Reload => { + agent.handle_reload(cx, session_id).await; + } SlashCommand::Exit => { agent .send_assistant_message(