fix: switch active provider on /login and /logout#59
Merged
Conversation
When /login succeeds for a different provider than the current one, the REPL now switches to that provider (swaps the thinker, updates the displayed provider name, model, and auth status). When /logout removes credentials for the current provider, the REPL falls back to another authenticated provider if one exists. Adds StateChange::Provider variant and build_provider_by_id() for runtime provider switching. Closes #58
There was a problem hiding this comment.
Pull request overview
This PR fixes REPL provider state not updating when authenticating/logging out across multiple providers, ensuring commands like /model operate against the currently active authenticated provider.
Changes:
- Added
StateChange::Provider(String)to allow commands to request a provider switch. - Introduced
build_provider_by_id()for rebuilding the active provider/thinker using provider defaults when switching at runtime. - Updated
/loginand/logoutflows plus the REPL handler to switch providers appropriately; added tests for the new behavior.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/login_test.rs | Adds tests for build_provider_by_id behavior and auth/model resolution expectations. |
| src/provider.rs | Adds build_provider_by_id() helper for runtime provider switching using default model. |
| src/main.rs | Handles StateChange::Provider by rebuilding provider setup and swapping the engine thinker + display state. |
| src/commands/mod.rs | Adds StateChange::Provider and a registry dispatch test to ensure the payload is carried through. |
| src/commands/logout.rs | Adds fallback logic to switch to another provider after logout if credentials exist. |
| src/commands/login.rs | Updates /login to switch active provider when logging into a different provider. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
…oviders Banner now lists auth status for every provider (marking the active one). /model fetches and displays models from all authenticated providers, grouped by provider. Selecting a model from a different provider automatically switches the active provider. StateChange::Provider now carries an optional model override. build_provider_by_id accepts an optional model parameter. New helpers: all_provider_statuses(), is_authenticated().
- Remove unnecessary env var save/restore from build_provider_by_id tests (no auth_status assertions, avoids parallel test races) - Logout fallback now checks env vars too, not just stored credentials - Login derives auth status from storage instead of hard-coding 'OAuth ✓' - Add provider_auth_status() public helper with tests - Persist model preference to config DB on provider switch
The auth label and continuation lines now use the same 10-char label column as the rest of the banner (provider, shell, workdir, etc.).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
When logged into both Anthropic and Google,
/modelalways queries the Anthropic provider regardless of which provider was last authenticated via/login. After/logoutfrom the current provider,/modelstill tries the old provider even when another is authenticated. The startup banner only showed the active provider's auth status, with no visibility into other authenticated providers.Fixes #58
Root Cause
/loginto a different provider returnedCommandResult::Handled(no-op) instead of switching the active provider. The REPL's thinker was never swapped./modelonly queried the single active provider.Changes
1. Provider switching on
/loginand/logoutStateChange::Provider(String, Option<String>)— new variant that tells the REPL to switch provider, with an optional model override.build_provider_by_id(id, db_path, model, debug)— builds aProviderSetupfrom a string id. Used for runtime provider switches./login— when login succeeds for a different provider, returnsStateChange::Providerto switch to it. Auth status is derived from storage (not hard-coded)./logout— after logging out from the current provider, falls back to another authenticated provider if one exists (checks both stored credentials and env vars).REPL handler — handles
StateChange::Providerby callingbuild_provider_by_id(), swapping the engine's thinker, updating all display state, and persisting the new model preference to the config DB.2. Banner shows all providers
all_provider_statuses(db_path)— returns auth status for every configurable provider.The startup banner now lists every provider with its auth status, marking the active one:
3.
/modelshows models from all authenticated providers/modelnow fetches models from all authenticated providers (not just the active one), displays them grouped by provider, and allows switching provider + model in one step:Selecting a model from a different provider automatically switches the active provider via
StateChange::Provider(id, Some(model)).4. Review feedback addressed
build_provider_by_idtests (avoids parallel test races)provider_auth_status()instead of hard-coding"OAuth ✓"New public API
build_provider_by_id()all_provider_statuses()provider_auth_status()is_authenticated()Testing
23 new tests covering:
build_provider_by_id— known/unknown providers, auth detection, default model, model overridefind_authenticated_provider— fallback logic (empty, excluded, found)StateChange::Provider— variant dispatchall_provider_statuses/is_authenticated/provider_auth_status— status helpersfind_other_authenticated_providers— empty dbprovider_display_name— known and unknown ids