diff --git a/agent/auxiliary_client.py b/agent/auxiliary_client.py index 7192dfd5d..3ce0308ce 100644 --- a/agent/auxiliary_client.py +++ b/agent/auxiliary_client.py @@ -121,6 +121,11 @@ logger = logging.getLogger(__name__) # them independently. _LOGGED_UNKNOWN_PROVIDER_KEYS: set = set() _LOGGED_UNHANDLED_AUTHTYPE_KEYS: set = set() +# Same treatment for the two "registered provider, unsupported sub-branch" +# routing dead-ends — external-process and OAuth providers that fall through +# with no matching handler. Keyed by provider name. +_LOGGED_UNSUPPORTED_EXTPROC_KEYS: set = set() +_LOGGED_UNSUPPORTED_OAUTH_KEYS: set = set() def _openai_http_client_kwargs( @@ -4495,8 +4500,10 @@ def resolve_provider_client( logger.debug("resolve_provider_client: %s (%s)", provider, final_model) return (_to_async_client(client, final_model, is_vision=is_vision) if async_mode else (client, final_model)) - logger.warning("resolve_provider_client: external-process provider %s not " - "directly supported", provider) + if provider not in _LOGGED_UNSUPPORTED_EXTPROC_KEYS: + _LOGGED_UNSUPPORTED_EXTPROC_KEYS.add(provider) + logger.debug("resolve_provider_client: external-process provider %s not " + "directly supported", provider) return None, None elif pconfig.auth_type == "aws_sdk": @@ -4541,8 +4548,10 @@ def resolve_provider_client( if provider == "xai-oauth": return resolve_provider_client("xai-oauth", model, async_mode) # Other OAuth providers not directly supported - logger.warning("resolve_provider_client: OAuth provider %s not " - "directly supported, try 'auto'", provider) + if provider not in _LOGGED_UNSUPPORTED_OAUTH_KEYS: + _LOGGED_UNSUPPORTED_OAUTH_KEYS.add(provider) + logger.debug("resolve_provider_client: OAuth provider %s not " + "directly supported, try 'auto'", provider) return None, None # Demoted from logger.warning to debug; dedup keyed on (auth_type, diff --git a/tests/agent/test_auxiliary_client_resolve_dedup.py b/tests/agent/test_auxiliary_client_resolve_dedup.py index 56f3115db..1bb7bbd94 100644 --- a/tests/agent/test_auxiliary_client_resolve_dedup.py +++ b/tests/agent/test_auxiliary_client_resolve_dedup.py @@ -50,3 +50,69 @@ class TestUnknownProviderDedup: if "unknown provider" in r.getMessage() ] assert len(recs) == 2 + + +class TestUnhandledAuthTypeDedup: + def setup_method(self): + ac._LOGGED_UNHANDLED_AUTHTYPE_KEYS.clear() + + def test_unhandled_auth_type_logs_debug_once_not_warning(self, caplog, monkeypatch): + import hermes_cli.auth as auth + from hermes_cli.auth import ProviderConfig + + # A registered provider whose auth_type matches no handled branch → + # the terminal "unhandled auth_type" fall-through. + bogus = ProviderConfig( + id="bogus_authtype", + name="Bogus", + auth_type="totally_unhandled_scheme", + ) + patched = dict(auth.PROVIDER_REGISTRY) + patched["bogus_authtype"] = bogus + monkeypatch.setattr(auth, "PROVIDER_REGISTRY", patched) + + with caplog.at_level(logging.DEBUG, logger="agent.auxiliary_client"): + client, model = resolve_provider_client("bogus_authtype", "") + resolve_provider_client("bogus_authtype", "") # repeat → suppressed + + assert (client, model) == (None, None) + recs = [ + r for r in caplog.records + if "unhandled auth_type" in r.getMessage() + ] + # Two calls, one DEBUG record, never WARNING. + assert len(recs) == 1 + assert recs[0].levelno == logging.DEBUG + assert not any(r.levelno >= logging.WARNING for r in recs) + + +class TestUnsupportedOAuthDedup: + def setup_method(self): + ac._LOGGED_UNSUPPORTED_OAUTH_KEYS.clear() + + def test_unsupported_oauth_provider_logs_debug_once(self, caplog, monkeypatch): + import hermes_cli.auth as auth + from hermes_cli.auth import ProviderConfig + + # A registered oauth_* provider that is not one of the directly-handled + # names (nous / openai-codex / xai-oauth) → the OAuth dead-end branch. + bogus = ProviderConfig( + id="bogus_oauth", + name="BogusOAuth", + auth_type="oauth_device_code", + ) + patched = dict(auth.PROVIDER_REGISTRY) + patched["bogus_oauth"] = bogus + monkeypatch.setattr(auth, "PROVIDER_REGISTRY", patched) + + with caplog.at_level(logging.DEBUG, logger="agent.auxiliary_client"): + resolve_provider_client("bogus_oauth", "") + resolve_provider_client("bogus_oauth", "") + + recs = [ + r for r in caplog.records + if "OAuth provider" in r.getMessage() and "not " in r.getMessage() + ] + assert len(recs) == 1 + assert recs[0].levelno == logging.DEBUG + assert not any(r.levelno >= logging.WARNING for r in recs)