feat: keyless flag on the provider catalog — GUI contract tests exempt anonymous providers
opencode-free broke two provider-surface contract tests: 'api_key providers must expose a credential env var' and 'GUI ⊇ hermes model universe'. Both premises assume a credential exists. Add a keyless flag to HermesOverlay + ProviderDescriptor (same derived-exemption pattern as virtual providers) so any future anonymous provider is covered without hardcoded slugs. Nothing to configure = no Providers-tab card, by design; the model picker remains the selection surface.
This commit is contained in:
@@ -66,6 +66,7 @@ class ProviderDescriptor:
|
||||
base_url_env_var: str # base-URL override env var (may be "")
|
||||
signup_url: str # signup / console URL (may be "")
|
||||
order: int # CANONICAL_PROVIDERS index — mirrors `hermes model`
|
||||
keyless: bool = False # served anonymously — no credential exists to configure
|
||||
|
||||
|
||||
def tab_for_auth_type(auth_type: str) -> str:
|
||||
@@ -171,6 +172,10 @@ def provider_catalog() -> list[ProviderDescriptor]:
|
||||
base_url_env_var=base_url_var,
|
||||
signup_url=signup_url,
|
||||
order=order,
|
||||
# Keyless providers (e.g. opencode-free) are served
|
||||
# anonymously: there is no credential to configure, so the
|
||||
# GUI renders no key card and contract tests exempt them.
|
||||
keyless=bool(getattr(overlay, "keyless", False)),
|
||||
)
|
||||
)
|
||||
return out
|
||||
|
||||
@@ -41,6 +41,7 @@ class HermesOverlay:
|
||||
extra_env_vars: Tuple[str, ...] = () # env vars models.dev doesn't list
|
||||
base_url_override: str = "" # override if models.dev URL is wrong/missing
|
||||
base_url_env_var: str = "" # env var for user-custom base URL
|
||||
keyless: bool = False # served anonymously — no credential exists to configure
|
||||
|
||||
|
||||
HERMES_OVERLAYS: Dict[str, HermesOverlay] = {
|
||||
@@ -160,6 +161,7 @@ HERMES_OVERLAYS: Dict[str, HermesOverlay] = {
|
||||
transport="openai_chat",
|
||||
is_aggregator=True,
|
||||
base_url_override="https://opencode.ai/zen/v1",
|
||||
keyless=True,
|
||||
),
|
||||
"kilo": HermesOverlay(
|
||||
transport="openai_chat",
|
||||
|
||||
@@ -57,13 +57,14 @@ def test_api_key_providers_expose_a_credential_env_var():
|
||||
surface at least one env var to write the key into (otherwise the GUI can't
|
||||
configure it).
|
||||
|
||||
Exemptions: ``aws_sdk`` (bedrock — uses AWS_REGION/AWS_PROFILE) and the
|
||||
``custom`` bring-your-own-endpoint pseudo-provider, which is configured
|
||||
inline via the local-endpoint flow rather than a fixed env var.
|
||||
Exemptions: ``aws_sdk`` (bedrock — uses AWS_REGION/AWS_PROFILE), the
|
||||
``custom`` bring-your-own-endpoint pseudo-provider (configured inline via
|
||||
the local-endpoint flow), and keyless providers (``d.keyless`` — e.g.
|
||||
opencode-free, served anonymously: there is no credential to write).
|
||||
"""
|
||||
exempt = {"custom"}
|
||||
for d in provider_catalog():
|
||||
if d.auth_type == "api_key" and d.slug not in exempt:
|
||||
if d.auth_type == "api_key" and d.slug not in exempt and not d.keyless:
|
||||
assert d.api_key_env_vars, f"{d.slug} is api_key but exposes no env var"
|
||||
|
||||
|
||||
|
||||
@@ -31,7 +31,11 @@ HEADERS = {"X-Hermes-Session-Token": _SESSION_TOKEN}
|
||||
# derived from the catalog so any future virtual provider is covered without a
|
||||
# hardcoded slug.
|
||||
_VIRTUAL = {d.slug for d in provider_catalog() if d.auth_type == "virtual"}
|
||||
_EXEMPT = {"custom"} | _VIRTUAL
|
||||
# Keyless providers (opencode-free) are served anonymously: no credential
|
||||
# exists, so there is nothing to configure on either Providers tab. Derived
|
||||
# from the catalog flag so any future keyless provider is covered.
|
||||
_KEYLESS = {d.slug for d in provider_catalog() if d.keyless}
|
||||
_EXEMPT = {"custom"} | _VIRTUAL | _KEYLESS
|
||||
|
||||
# Providers that legitimately offer BOTH auth methods and so intentionally
|
||||
# appear on both desktop tabs (an API-key card AND an account sign-in card).
|
||||
|
||||
Reference in New Issue
Block a user