feat(providers): add GMI Cloud as first-class API-key provider#16663
Merged
Conversation
) Add GMI Cloud (api.gmi-serving.com) as a full first-class API-key provider with built-in auth, aliases, model catalog, CLI entry points, auxiliary client routing, context length resolution, doctor checks, env var tracking, and docs. - auth.py: ProviderConfig for 'gmi' (api_key, GMI_API_KEY / GMI_BASE_URL) - providers.py: HermesOverlay with extra_env_vars for models.dev detection - models.py: curated slash-form model catalog; live /v1/models fetch - main.py: 'gmi' in _named_custom_provider_map and --provider choices - model_metadata.py: _URL_TO_PROVIDER, _PROVIDER_PREFIXES, dedicated context-length probe block (GMI's /models has authoritative data) - auxiliary_client.py: alias entries; _compat_model fix for slash-form models on cached aggregator-style clients; gmi aux default model - doctor.py: GMI in provider connectivity checks - config.py: GMI_API_KEY / GMI_BASE_URL in OPTIONAL_ENV_VARS - conftest.py: explicit GMI_BASE_URL clearing (not caught by _API_KEY suffix) - docs: providers.md, environment-variables.md, fallback-providers.md, configuration.md, quickstart.md (expands provider table) Co-authored-by: Isaac Huang <isaachuang@Isaacs-MacBook-Pro.local>
3 tasks
35e6a01 to
384411d
Compare
- config.py: remove dead ENV_VARS_BY_VERSION[17] entry (current _config_version
is 22, so all users are past version 17 and would never be prompted for
GMI_API_KEY on upgrade — consistent with how arcee was added)
- auxiliary_client.py: use google/gemini-3.1-flash-lite-preview as GMI aux
model instead of anthropic/claude-opus-4.6 (matches cheap fast-model pattern
used by all other providers: zai→glm-4.5-flash, kimi→kimi-k2-turbo-preview,
stepfun→step-3.5-flash, kilocode→google/gemini-3-flash-preview)
- test_gmi_provider.py: fix malformed write_text() call in doctor test
(was: write_text("GMI_API_KEY=*** encoding="utf-8") → missing closing quote,
wrote literal string 'GMI_API_KEY=*** encoding=' to .env file)
- test_gmi_provider.py + test_auxiliary_client.py: update aux model assertions
to match new cheaper default
- docs/integrations/providers.md: add 'gmi' to inline 'Supported providers'
fallback list (was only in the table, not the inline list at line ~1181)
- docs/reference/cli-commands.md: add 'gmi' to --provider choices list
384411d to
db3d75c
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Salvage of #11955 (GMI Cloud first-class provider) by @isaachuangGMICLOUD, cherry-picked onto current
mainwith conflict resolution and review fixes applied in a follow-up commit.What this adds
GMI Cloud (
api.gmi-serving.com) as a full first-class API-key provider — on par witharcee,kilocode,xiaomi, etc.:hermes_cli/auth.py—ProviderConfig(id="gmi",auth_type="api_key",GMI_API_KEY/GMI_BASE_URL)hermes_cli/providers.py—HermesOverlaywithextra_env_vars=("GMI_API_KEY",)(needed for models.dev detection since GMI isn't in models.dev yet)hermes_cli/models.py— curated vendor/model catalog (slash-form, GMI is a multi-vendor aggregator); live/v1/modelsfetch with static fallback;CANONICAL_PROVIDERSentryhermes_cli/main.py—"gmi"in both_named_custom_provider_maptuple and--providerargparse choices; dispatches to_model_flow_api_key_providergenericallyagent/model_metadata.py—_URL_TO_PROVIDER["api.gmi-serving.com"] = "gmi";_PROVIDER_PREFIXESentries; dedicated context-length probe block (GMI's/modelsendpoint has authoritativecontext_lengthdata, and it's a known URL so the generic custom-endpoint probe skips it)agent/auxiliary_client.py— provider aliases;_compat_modelfix to preserve slash-form model IDs on cached aggregator-style clients;gmiaux model entryhermes_cli/doctor.py— GMI in provider connectivity checkshermes_cli/config.py—GMI_API_KEY/GMI_BASE_URLinOPTIONAL_ENV_VARStests/conftest.py— explicitGMI_BASE_URLclearing (not caught by_API_KEYsuffix pattern)providers.md,environment-variables.md,cli-commands.md,fallback-providers.md,configuration.md,quickstart.md(expands provider table)Aliases
gmi,gmi-cloud,gmicloudall resolve to canonicalgmi.Provider flow coverage (verified against
arceepattern)auth.pyProviderConfigproviders.pyHermesOverlaymodels.py_PROVIDER_MODELS+CANONICAL_PROVIDERS+_PROVIDER_LABELS+_PROVIDER_ALIASESmodels.pyprovider_model_ids()live fetchmain.py_named_custom_provider_map+--providerchoices +_model_flow_api_key_providerdispatchmodel_metadata.py_URL_TO_PROVIDER+_PROVIDER_PREFIXES+ context-length probeauxiliary_client.pyaliases +_API_KEY_PROVIDER_AUX_MODELSdoctor.pyconnectivity checkconfig.pyOPTIONAL_ENV_VARSruntime_provider.pyresolve_api_key_provider_credentialspath, no changes needed)setup.pymain.pydispatch)status.pyresolve_provider()+provider_label())fallback_providers.mdtableproviders.mdinline fallback listenvironment-variables.mdcli-commands.md--providerlistconftest.pyhermetic envChanges from original PR (follow-up commit)
ENV_VARS_BY_VERSION[17]is dead code — current_config_versionis 22, so no existing user would ever be promptedarceewas added (no version entry)_API_KEY_PROVIDER_AUX_MODELS["gmi"] = "anthropic/claude-opus-4.6"— most expensive model, inconsistent with other providers (all use cheap flash/turbo variants)google/gemini-3.1-flash-lite-preview(already in GMI's curated catalog)write_text("GMI_API_KEY=*** encoding="utf-8")— mismatched quote, writes literal"GMI_API_KEY=*** encoding="to.envfilewrite_text("GMI_API_KEY=***\n", encoding="utf-8")providers.mdinline "Supported providers" fallback list (line ~1181) missinggmicli-commands.md--providerchoices list missinggmitest_auxiliary_client.pyleft stale assertions (fresh-agent-key,fresh_base) intest_try_nous_uses_pool_entry; also introduced a duplicatetest_try_nous_pool_entrywith wrong expected modelTest plan
tests/hermes_cli/test_gmi_provider.py— 35 focused GMI tests: 35/35 passedtests/hermes_cli/test_api_key_providers.py— full provider registry regression: 135/135 passedtests/agent/test_auxiliary_client.py— aux client tests incl. pool + GMI cache tests: 97/97 passedCloses #11955 — original contributor's commits preserved with authorship via rebase merge.