fix(code): highlight just-installed provider on /auth reopen (#4311)

Fixed the `/auth` manager so that after installing a provider it reopens
with the just-installed provider highlighted instead of resetting to the
top of the list.

Made by [Open
SWE](https://openswe.vercel.app/agents/d1b42eb9-0efa-0224-dcc2-c71ad53093cd)

---------

Co-authored-by: open-swe[bot] <open-swe@users.noreply.github.com>
This commit is contained in:
Mason Daugherty
2026-06-26 17:50:40 -04:00
committed by GitHub
parent 54aae4beab
commit 85e47b532b
4 changed files with 140 additions and 22 deletions
+25 -6
View File
@@ -10162,12 +10162,17 @@ class DeepAgentsApp(App):
)
self.push_screen(screen, handle_result)
async def _show_auth_manager(self) -> None:
async def _show_auth_manager(self, *, initial_provider: str | None = None) -> None:
"""Show the `/auth` credential manager modal.
State changes persist via `auth_store`; the manager refreshes its
own option labels after each save/delete, so this caller only needs
to refocus the chat input on close.
Args:
initial_provider: Provider to start highlighted set when
reopening after an install-on-select so the cursor lands on
the just-installed provider instead of the top of the list.
"""
from deepagents_code.widgets.auth import AuthManagerScreen
@@ -10182,13 +10187,17 @@ class DeepAgentsApp(App):
from functools import partial
self.call_later(
partial(self._install_provider_then_reopen_auth, extra),
partial(
self._install_provider_then_reopen_auth,
extra,
provider=screen.pending_install_provider,
),
)
return
task = asyncio.create_task(self._resume_server_after_auth_change())
task.add_done_callback(_log_task_exception)
screen = AuthManagerScreen()
screen = AuthManagerScreen(initial_provider=initial_provider)
self.push_screen(screen, handle_result)
def on_auth_manager_screen_credential_saved(self, event: Message) -> None:
@@ -10258,14 +10267,18 @@ class DeepAgentsApp(App):
await self._retry_startup_with_model(model_spec, extra_kwargs=extra_kwargs)
return True
async def _install_provider_then_reopen_auth(self, extra: str) -> None:
async def _install_provider_then_reopen_auth(
self, extra: str, *, provider: str | None = None
) -> None:
"""Install a provider's extra from `/auth`, then reopen the manager.
Args:
extra: The extra that installs the selected provider's integration.
provider: The provider being installed, highlighted in the
reopened manager so the cursor lands on it ready for a key.
"""
if await self._install_extra(extra, auto_restart=True):
await self._show_auth_manager()
await self._show_auth_manager(initial_provider=provider)
return
# `_install_extra` returns `False` both when the install genuinely
# failed (it already surfaced the reason) and when the package landed
@@ -10277,7 +10290,7 @@ class DeepAgentsApp(App):
from deepagents_code.model_config import clear_caches
clear_caches()
await self._show_auth_manager()
await self._show_auth_manager(initial_provider=provider)
return
if ready is None:
# Introspection couldn't confirm the state (rare). Don't dead-end
@@ -10288,6 +10301,12 @@ class DeepAgentsApp(App):
"Reopen `/auth` to add a key once it has.",
),
)
return
# `ready is False`: the extra genuinely didn't install. `_install_extra`
# has already surfaced the reason to the user, so stay in chat rather
# than reopen — but log it so an "install button did nothing" report is
# debuggable without relying on that sibling method's invariant.
logger.debug("Provider extra %r not importable after install attempt", extra)
def _switch_agent(self, agent_name: str) -> None:
"""Switch to a different agent and hot-restart the backing server.
+36 -6
View File
@@ -31,7 +31,7 @@ from textual.message import Message
from textual.screen import ModalScreen
from textual.style import Style as TStyle
from textual.widgets import Input, OptionList, Static
from textual.widgets.option_list import Option
from textual.widgets.option_list import Option, OptionDoesNotExist
if TYPE_CHECKING:
from textual.app import ComposeResult
@@ -1148,16 +1148,26 @@ class AuthManagerScreen(ModalScreen[None]):
}
"""
def __init__(self) -> None:
"""Initialize the manager with an empty install-on-select registry."""
def __init__(self, *, initial_provider: str | None = None) -> None:
"""Initialize the manager with an empty install-on-select registry.
Args:
initial_provider: Provider whose row should start highlighted —
set when reopening after an install-on-select so the cursor
lands on the just-installed provider ready for a key, rather
than resetting to the top of the list.
"""
super().__init__()
# Uninstalled known providers mapped to the extra that installs them,
# populated each time the option list is built. Selecting one routes
# to the install confirmation instead of the key prompt.
self._install_extras: dict[str, str] = {}
# Set when the user confirms installing a provider's extra; the app
# reads this off the screen after dismissal to install then reopen.
# reads these off the screen after dismissal to install then reopen
# the manager with the just-installed provider highlighted.
self.pending_install_extra: str | None = None
self.pending_install_provider: str | None = None
self._initial_provider = initial_provider
def compose(self) -> ComposeResult:
"""Compose the manager.
@@ -1213,11 +1223,29 @@ class AuthManagerScreen(ModalScreen[None]):
)
def on_mount(self) -> None:
"""Apply ASCII border when needed."""
"""Apply ASCII border and highlight the initial provider when set."""
if is_ascii_mode():
container = self.query_one(Vertical)
colors = theme.get_theme_colors(self)
container.styles.border = ("ascii", colors.success)
self._highlight_initial_provider()
def _highlight_initial_provider(self) -> None:
"""Move the cursor to `initial_provider`'s row if it is listed.
Used when the manager reopens after an install-on-select so the cursor
lands on the just-installed provider (ready for a key) instead of
resetting to the top of the list.
"""
if self._initial_provider is None:
return
option_list = self.query_one("#auth-manager-options", OptionList)
try:
index = option_list.get_option_index(self._initial_provider)
except OptionDoesNotExist:
return
option_list.highlighted = index
option_list.scroll_to_highlight()
def on_click(self, event: Click) -> None: # noqa: PLR6301 - Textual handler
"""Open style-embedded hyperlinks (the title `Docs` link)."""
@@ -1285,11 +1313,13 @@ class AuthManagerScreen(ModalScreen[None]):
def _on_confirm(proceed: bool | None) -> None:
if proceed:
self.pending_install_extra = extra
self.pending_install_provider = provider
self.dismiss(None)
else:
# Declined or dismissed: clear any pending extra so a reused
# Declined or dismissed: clear any pending request so a reused
# screen never carries a stale install request, and stay put.
self.pending_install_extra = None
self.pending_install_provider = None
self.app.push_screen(
InstallProviderConfirmScreen(provider, extra),
+29 -8
View File
@@ -7826,10 +7826,25 @@ class TestDefaultAgentNameDrift:
class TestInstallExtraAuthContinuation:
"""Test `/auth` reopening after installing provider extras."""
async def test_reopens_auth_with_provider_highlighted_after_install(self) -> None:
"""A successful install reopens the manager on the just-installed provider."""
app = DeepAgentsApp()
app._install_extra = AsyncMock(return_value=True) # ty: ignore
app._show_auth_manager = AsyncMock() # ty: ignore
await app._install_provider_then_reopen_auth("baseten", provider="baseten")
app._install_extra.assert_awaited_once_with("baseten", auto_restart=True) # ty: ignore
app._show_auth_manager.assert_awaited_once_with(initial_provider="baseten") # ty: ignore
async def test_reopens_auth_after_installed_extra_even_when_restart_fails(
self,
) -> None:
"""`/auth` only needs the install to land before reopening the manager."""
"""`/auth` only needs the install to land before reopening the manager.
Even on the restart-failed path the just-installed provider is threaded
through so the reopened manager lands the cursor on its row.
"""
app = DeepAgentsApp()
app._install_extra = AsyncMock(return_value=False) # ty: ignore
app._show_auth_manager = AsyncMock() # ty: ignore
@@ -7838,23 +7853,29 @@ class TestInstallExtraAuthContinuation:
patch("deepagents_code.app._extra_is_ready", return_value=True),
patch("deepagents_code.model_config.clear_caches") as clear_caches,
):
await app._install_provider_then_reopen_auth("baseten")
await app._install_provider_then_reopen_auth("baseten", provider="baseten")
app._install_extra.assert_awaited_once_with("baseten", auto_restart=True) # ty: ignore
clear_caches.assert_called_once_with()
app._show_auth_manager.assert_awaited_once() # ty: ignore
app._show_auth_manager.assert_awaited_once_with(initial_provider="baseten") # ty: ignore
async def test_does_not_reopen_auth_when_install_failed(self) -> None:
"""A failed install still leaves the user in chat with the surfaced error."""
async def test_does_not_reopen_auth_when_install_failed(
self, caplog: pytest.LogCaptureFixture
) -> None:
"""A failed install leaves the user in chat and logs the dead-end at DEBUG."""
app = DeepAgentsApp()
app._install_extra = AsyncMock(return_value=False) # ty: ignore
app._show_auth_manager = AsyncMock() # ty: ignore
with patch("deepagents_code.app._extra_is_ready", return_value=False):
await app._install_provider_then_reopen_auth("baseten")
with (
patch("deepagents_code.app._extra_is_ready", return_value=False),
caplog.at_level(logging.DEBUG, logger="deepagents_code.app"),
):
await app._install_provider_then_reopen_auth("baseten", provider="baseten")
app._install_extra.assert_awaited_once_with("baseten", auto_restart=True) # ty: ignore
app._show_auth_manager.assert_not_awaited() # ty: ignore
assert any("baseten" in record.message for record in caplog.records)
async def test_surfaces_hint_when_install_state_unverifiable(self) -> None:
"""An unknown post-install state points the user back to `/auth`.
@@ -7869,7 +7890,7 @@ class TestInstallExtraAuthContinuation:
app._mount_message = AsyncMock() # ty: ignore
with patch("deepagents_code.app._extra_is_ready", return_value=None):
await app._install_provider_then_reopen_auth("baseten")
await app._install_provider_then_reopen_auth("baseten", provider="baseten")
app._show_auth_manager.assert_not_awaited() # ty: ignore
app._mount_message.assert_awaited_once() # ty: ignore
@@ -93,9 +93,9 @@ class _AuthHostApp(App[None]):
handle,
)
def show_manager(self) -> None:
def show_manager(self, *, initial_provider: str | None = None) -> None:
"""Push the manager screen."""
self.push_screen(AuthManagerScreen())
self.push_screen(AuthManagerScreen(initial_provider=initial_provider))
def on_auth_manager_screen_credential_saved(
self, _event: AuthManagerScreen.CredentialSaved
@@ -1680,6 +1680,53 @@ api_key_env = "MY_GATEWAY_API_KEY"
await pilot.press("enter")
await pilot.pause()
assert screen.pending_install_extra == "groq"
assert screen.pending_install_provider == "groq"
async def test_reopening_manager_highlights_initial_provider(
self, monkeypatch: pytest.MonkeyPatch
) -> None:
"""Reopening after an install highlights the just-installed provider.
Simulates the post-install reopen: `groq` is now installed and listed,
and passing it as `initial_provider` lands the cursor on its row rather
than resetting to index 0.
"""
monkeypatch.setattr(
"deepagents_code.widgets.auth.get_available_models",
lambda: {"openai": ["gpt-5.4"], "groq": ["llama-3"]},
)
monkeypatch.setattr(
"deepagents_code.config_manifest.is_provider_package_installed",
lambda provider: provider in {"openai", "groq"},
)
app = _AuthHostApp()
async with app.run_test() as pilot:
app.show_manager(initial_provider="groq")
await pilot.pause()
screen = cast("AuthManagerScreen", app.screen)
options = screen.query_one("#auth-manager-options", OptionList)
assert options.highlighted is not None
assert options.get_option_at_index(options.highlighted).id == "groq"
async def test_reopening_manager_ignores_unknown_initial_provider(
self, monkeypatch: pytest.MonkeyPatch
) -> None:
"""An initial provider absent from the list leaves the cursor at the top."""
monkeypatch.setattr(
"deepagents_code.widgets.auth.get_available_models",
lambda: {"openai": ["gpt-5.4"]},
)
monkeypatch.setattr(
"deepagents_code.config_manifest.is_provider_package_installed",
lambda provider: provider == "openai",
)
app = _AuthHostApp()
async with app.run_test() as pilot:
app.show_manager(initial_provider="not-a-real-provider")
await pilot.pause()
screen = cast("AuthManagerScreen", app.screen)
options = screen.query_one("#auth-manager-options", OptionList)
assert options.highlighted == 0
async def test_cancelling_install_leaves_manager_without_pending_extra(
self, monkeypatch: pytest.MonkeyPatch
@@ -1703,6 +1750,7 @@ api_key_env = "MY_GATEWAY_API_KEY"
await pilot.press("escape")
await pilot.pause()
assert screen.pending_install_extra is None
assert screen.pending_install_provider is None
assert isinstance(app.screen, AuthManagerScreen)
async def test_disabled_known_provider_not_offered_for_install(