fix(cli): allow oauth login to set main provider
This commit is contained in:
@@ -1744,6 +1744,11 @@ _PROVIDER_DISPLAY: dict[str, str] = {
|
|||||||
"github_copilot": "GitHub Copilot",
|
"github_copilot": "GitHub Copilot",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_OAUTH_PROVIDER_DEFAULT_MODELS: dict[str, str] = {
|
||||||
|
"openai_codex": "openai-codex/gpt-5.1-codex",
|
||||||
|
"github_copilot": "github-copilot/gpt-4.1",
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
def _register_login(name: str):
|
def _register_login(name: str):
|
||||||
"""Register an OAuth login handler."""
|
"""Register an OAuth login handler."""
|
||||||
@@ -1775,9 +1780,51 @@ def _resolve_oauth_provider(provider: str):
|
|||||||
return spec
|
return spec
|
||||||
|
|
||||||
|
|
||||||
|
def _set_oauth_provider_as_main(
|
||||||
|
provider_name: str,
|
||||||
|
*,
|
||||||
|
model: str | None = None,
|
||||||
|
config_path: str | None = None,
|
||||||
|
) -> None:
|
||||||
|
"""Persist an OAuth provider as the active agent provider."""
|
||||||
|
from nanobot.config.loader import get_config_path, load_config, save_config, set_config_path
|
||||||
|
|
||||||
|
resolved_config_path = Path(config_path).expanduser().resolve() if config_path else None
|
||||||
|
if resolved_config_path is not None:
|
||||||
|
set_config_path(resolved_config_path)
|
||||||
|
console.print(f"[dim]Using config: {resolved_config_path}[/dim]")
|
||||||
|
|
||||||
|
config = load_config(resolved_config_path)
|
||||||
|
selected_model = (model or "").strip() or _OAUTH_PROVIDER_DEFAULT_MODELS[provider_name]
|
||||||
|
config.agents.defaults.model_preset = None
|
||||||
|
config.agents.defaults.provider = provider_name
|
||||||
|
config.agents.defaults.model = selected_model
|
||||||
|
save_config(config, resolved_config_path)
|
||||||
|
|
||||||
|
saved_path = resolved_config_path or get_config_path()
|
||||||
|
console.print(
|
||||||
|
f"[green]✓ Set {provider_name.replace('_', '-')} as the main provider[/green] "
|
||||||
|
f"[dim]{selected_model}[/dim]"
|
||||||
|
)
|
||||||
|
console.print(f"[dim]Saved: {saved_path}[/dim]")
|
||||||
|
|
||||||
|
|
||||||
@provider_app.command("login")
|
@provider_app.command("login")
|
||||||
def provider_login(
|
def provider_login(
|
||||||
provider: str = typer.Argument(..., help="OAuth provider (e.g. 'openai-codex', 'github-copilot')"),
|
provider: str = typer.Argument(..., help="OAuth provider (e.g. 'openai-codex', 'github-copilot')"),
|
||||||
|
set_main: bool = typer.Option(
|
||||||
|
False,
|
||||||
|
"--set-main",
|
||||||
|
"--main",
|
||||||
|
help="Set this OAuth provider as the active agent provider after login",
|
||||||
|
),
|
||||||
|
model: str | None = typer.Option(
|
||||||
|
None,
|
||||||
|
"--model",
|
||||||
|
"-m",
|
||||||
|
help="Model to use when setting this provider as the active provider",
|
||||||
|
),
|
||||||
|
config: str | None = typer.Option(None, "--config", "-c", help="Path to config file"),
|
||||||
):
|
):
|
||||||
"""Authenticate with an OAuth provider."""
|
"""Authenticate with an OAuth provider."""
|
||||||
spec = _resolve_oauth_provider(provider)
|
spec = _resolve_oauth_provider(provider)
|
||||||
@@ -1789,6 +1836,8 @@ def provider_login(
|
|||||||
|
|
||||||
console.print(f"{__logo__} OAuth Login - {spec.label}\n")
|
console.print(f"{__logo__} OAuth Login - {spec.label}\n")
|
||||||
handler()
|
handler()
|
||||||
|
if set_main or model:
|
||||||
|
_set_oauth_provider_as_main(spec.name, model=model, config_path=config)
|
||||||
|
|
||||||
|
|
||||||
@provider_app.command("logout")
|
@provider_app.command("logout")
|
||||||
|
|||||||
@@ -435,6 +435,71 @@ def test_provider_login_rejects_unknown_provider():
|
|||||||
assert "Unknown OAuth provider" in result.stdout
|
assert "Unknown OAuth provider" in result.stdout
|
||||||
|
|
||||||
|
|
||||||
|
def test_provider_login_can_set_openai_codex_as_main_provider(tmp_path):
|
||||||
|
config_path = tmp_path / "config.json"
|
||||||
|
called = False
|
||||||
|
original = cli_commands._LOGIN_HANDLERS["openai_codex"]
|
||||||
|
|
||||||
|
def fake_login() -> None:
|
||||||
|
nonlocal called
|
||||||
|
called = True
|
||||||
|
|
||||||
|
cli_commands._LOGIN_HANDLERS["openai_codex"] = fake_login
|
||||||
|
try:
|
||||||
|
result = runner.invoke(
|
||||||
|
app,
|
||||||
|
[
|
||||||
|
"provider",
|
||||||
|
"login",
|
||||||
|
"openai-codex",
|
||||||
|
"--set-main",
|
||||||
|
"--config",
|
||||||
|
str(config_path),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
finally:
|
||||||
|
cli_commands._LOGIN_HANDLERS["openai_codex"] = original
|
||||||
|
|
||||||
|
assert result.exit_code == 0
|
||||||
|
assert called is True
|
||||||
|
assert "Set openai-codex as the main provider" in result.stdout
|
||||||
|
|
||||||
|
saved = Config.model_validate(json.loads(config_path.read_text(encoding="utf-8")))
|
||||||
|
assert saved.agents.defaults.provider == "openai_codex"
|
||||||
|
assert saved.agents.defaults.model == "openai-codex/gpt-5.1-codex"
|
||||||
|
assert saved.agents.defaults.model_preset is None
|
||||||
|
assert make_provider(saved).__class__.__name__ == "OpenAICodexProvider"
|
||||||
|
|
||||||
|
|
||||||
|
def test_provider_login_model_implies_set_main_provider(tmp_path):
|
||||||
|
config_path = tmp_path / "config.json"
|
||||||
|
original = cli_commands._LOGIN_HANDLERS["github_copilot"]
|
||||||
|
cli_commands._LOGIN_HANDLERS["github_copilot"] = lambda: None
|
||||||
|
try:
|
||||||
|
result = runner.invoke(
|
||||||
|
app,
|
||||||
|
[
|
||||||
|
"provider",
|
||||||
|
"login",
|
||||||
|
"github-copilot",
|
||||||
|
"--model",
|
||||||
|
"github-copilot/gpt-5.4-mini",
|
||||||
|
"--config",
|
||||||
|
str(config_path),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
finally:
|
||||||
|
cli_commands._LOGIN_HANDLERS["github_copilot"] = original
|
||||||
|
|
||||||
|
assert result.exit_code == 0
|
||||||
|
assert "Set github-copilot as the main provider" in result.stdout
|
||||||
|
|
||||||
|
saved = Config.model_validate(json.loads(config_path.read_text(encoding="utf-8")))
|
||||||
|
assert saved.agents.defaults.provider == "github_copilot"
|
||||||
|
assert saved.agents.defaults.model == "github-copilot/gpt-5.4-mini"
|
||||||
|
assert make_provider(saved).__class__.__name__ == "GitHubCopilotProvider"
|
||||||
|
|
||||||
|
|
||||||
def test_provider_login_openai_codex_passes_configured_proxy(monkeypatch):
|
def test_provider_login_openai_codex_passes_configured_proxy(monkeypatch):
|
||||||
proxy = "http://127.0.0.1:23458"
|
proxy = "http://127.0.0.1:23458"
|
||||||
monkeypatch.setattr(
|
monkeypatch.setattr(
|
||||||
|
|||||||
Reference in New Issue
Block a user