diff --git a/hermes_cli/auth.py b/hermes_cli/auth.py index 7bde989ff3797..ce1cb08e10844 100644 --- a/hermes_cli/auth.py +++ b/hermes_cli/auth.py @@ -1926,6 +1926,26 @@ def _read_qwen_cli_tokens() -> Dict[str, Any]: return data +def _save_qwen_oauth_provider_state(creds: Dict[str, Any]) -> None: + """Set active_provider to qwen-oauth in auth.json. + + Qwen OAuth tokens live in the Qwen CLI credential file managed by + _save_qwen_cli_tokens / resolve_qwen_runtime_credentials; this call only + records the provider-state singleton and sets active_provider so + get_active_provider() and _model_section_has_credentials() detect the + provider (setup wizard, status checks). + """ + with _auth_store_lock(): + auth_store = _load_auth_store() + state = _load_provider_state(auth_store, "qwen-oauth") or {} + if creds.get("base_url"): + state["base_url"] = creds["base_url"] + if creds.get("auth_file"): + state["auth_file"] = creds["auth_file"] + _save_provider_state(auth_store, "qwen-oauth", state) + _save_auth_store(auth_store) + + def _save_qwen_cli_tokens(tokens: Dict[str, Any]) -> Path: auth_path = _qwen_cli_auth_path() auth_path.parent.mkdir(parents=True, exist_ok=True) diff --git a/hermes_cli/auth_commands.py b/hermes_cli/auth_commands.py index 0ca5627627557..1c3ece13ddcc7 100644 --- a/hermes_cli/auth_commands.py +++ b/hermes_cli/auth_commands.py @@ -372,6 +372,7 @@ def auth_add_command(args) -> None: if provider == "qwen-oauth": creds = auth_mod.resolve_qwen_runtime_credentials(refresh_if_expiring=False) + auth_mod._save_qwen_oauth_provider_state(creds) label = (getattr(args, "label", None) or "").strip() or label_from_token( creds["api_key"], _oauth_default_label(provider, len(pool.entries()) + 1), diff --git a/tests/hermes_cli/test_auth_commands.py b/tests/hermes_cli/test_auth_commands.py index f6fc408a083fb..a533aaeefb219 100644 --- a/tests/hermes_cli/test_auth_commands.py +++ b/tests/hermes_cli/test_auth_commands.py @@ -97,6 +97,39 @@ class _Args: assert entry["expires_at_ms"] == 1711234567000 +def test_auth_add_qwen_oauth_sets_active_provider(tmp_path, monkeypatch): + """hermes auth add qwen-oauth must set active_provider in auth.json.""" + monkeypatch.setenv("HERMES_HOME", str(tmp_path / "hermes")) + _write_auth_store(tmp_path, {"version": 1, "providers": {}}) + monkeypatch.setattr( + "hermes_cli.auth.resolve_qwen_runtime_credentials", + lambda **kwargs: { + "api_key": "qwen-test-token", + "base_url": "https://portal.qwen.ai/v1", + "source": "qwen-cli", + "auth_file": "/home/user/.qwen/oauth_creds.json", + }, + ) + + from hermes_cli.auth_commands import auth_add_command + + class _Args: + provider = "qwen-oauth" + auth_type = "oauth" + api_key = None + label = None + + auth_add_command(_Args()) + + payload = json.loads((tmp_path / "hermes" / "auth.json").read_text()) + assert payload["active_provider"] == "qwen-oauth" + assert payload["providers"]["qwen-oauth"]["base_url"] == "https://portal.qwen.ai/v1" + entries = payload["credential_pool"]["qwen-oauth"] + entry = next(item for item in entries if item["source"] == "manual:qwen_cli") + assert entry["source"] == "manual:qwen_cli" + assert entry["access_token"] == "qwen-test-token" + + def test_auth_add_nous_oauth_persists_pool_entry(tmp_path, monkeypatch): monkeypatch.setenv("HERMES_HOME", str(tmp_path / "hermes")) _write_auth_store(tmp_path, {"version": 1, "providers": {}})