feat(cli): add minimax-oauth provider with PKCE browser flow#15203
Closed
amanning3390 wants to merge 4 commits into
Closed
feat(cli): add minimax-oauth provider with PKCE browser flow#15203amanning3390 wants to merge 4 commits into
amanning3390 wants to merge 4 commits into
Conversation
Add MiniMax OAuth (minimax-oauth) as a first-class provider using a
PKCE device-code flow ported from openclaw/extensions/minimax/oauth.ts.
Changes:
- hermes_cli/auth.py:
- Add 8 MINIMAX_OAUTH_* constants (client ID, scope, grant type,
global/CN base URLs, inference URLs, refresh skew)
- Add 'minimax-oauth' ProviderConfig to PROVIDER_REGISTRY (auth_type
oauth_minimax) with global portal + inference base URLs and CN
extras in the extra dict
- Add provider aliases: minimax-portal, minimax-global, minimax_oauth
- Implement _minimax_pkce_pair(), _minimax_request_user_code(),
_minimax_poll_token(), _minimax_save_auth_state(),
_minimax_oauth_login(), _refresh_minimax_oauth_state(),
resolve_minimax_oauth_runtime_credentials(),
get_minimax_oauth_auth_status(), _login_minimax_oauth()
- Token refresh uses standard OAuth2 refresh_token grant; triggers
relogin_required on invalid_grant / refresh_token_reused
- hermes_cli/runtime_provider.py:
- Add minimax-oauth branch (after qwen-oauth) that calls
resolve_minimax_oauth_runtime_credentials() and returns
api_mode='anthropic_messages' with the OAuth Bearer token
- hermes_cli/auth_commands.py:
- Add 'minimax-oauth' to _OAUTH_CAPABLE_PROVIDERS
- Add auth_type auto-detection for oauth_minimax
- Add provider == 'minimax-oauth' branch in auth_add_command
- hermes_cli/doctor.py:
- Import get_minimax_oauth_auth_status
- Add MiniMax OAuth status check in the Auth Providers section
Wire MiniMax-M2.7 and MiniMax-M2.7-highspeed into the model catalog,
CLI model picker, and agent auxiliary/metadata subsystems.
Changes:
- hermes_cli/models.py:
- Add 'minimax-oauth' to _PROVIDER_MODELS with MiniMax-M2.7 and
MiniMax-M2.7-highspeed
- Add ProviderEntry('minimax-oauth', 'MiniMax (OAuth)', ...) to
CANONICAL_PROVIDERS near existing minimax entries
- Add aliases: minimax-portal, minimax-global, minimax_oauth in
_PROVIDER_ALIASES
- hermes_cli/main.py:
- Add 'minimax-oauth' to provider_labels dict
- Insert 'minimax-oauth' into providers list in
select_provider_and_model() near the other minimax entries
- Add 'minimax-oauth' to --provider argparse choices
- Add _model_flow_minimax_oauth() function: ensures login via
_login_minimax_oauth(), resolves runtime credentials, prompts for
model selection, saves model choice and config
- Add dispatch elif branch for selected_provider == 'minimax-oauth'
- agent/auxiliary_client.py:
- Add 'minimax-oauth': 'MiniMax-M2.7-highspeed' to
_API_KEY_PROVIDER_AUX_MODELS
- Add 'minimax-oauth' to _ANTHROPIC_COMPAT_PROVIDERS set
- agent/model_metadata.py:
- Add 'minimax-oauth' to _PROVIDER_PREFIXES frozenset
- MiniMax-M2.7 context length (200_000) already covered by the
existing 'minimax' substring match in DEFAULT_CONTEXT_LENGTHS
Add and extend tests for the minimax-oauth provider across three test
modules.
New file: tests/test_minimax_oauth.py (15 tests)
- test_pkce_pair_produces_valid_s256: verifies PKCE verifier/challenge
pair produces a valid S256 hash and correct lengths
- test_request_user_code_happy_path: mocks httpx, verifies correct
POST parameters and response parsing
- test_request_user_code_state_mismatch_raises: verifies CSRF guard
- test_request_user_code_non_200_raises: verifies HTTP error handling
- test_poll_token_pending_then_success: verifies polling loop retries
on 'pending' and returns on 'success'
- test_poll_token_error_raises: verifies 'error' status raises AuthError
- test_poll_token_timeout_raises: verifies deadline expiry raises
- test_refresh_skip_when_not_expired: verifies no HTTP call when token
is fresh
- test_refresh_updates_access_token: verifies new access/refresh tokens
stored on successful refresh
- test_refresh_reuse_triggers_relogin_required: verifies
relogin_required=True on invalid_grant/refresh_token_reused
- test_resolve_credentials_requires_login: verifies AuthError when no
stored state
- test_provider_registry_contains_minimax_oauth: PROVIDER_REGISTRY key
- test_minimax_oauth_alias_resolves: portal/global/underscore aliases
- test_get_minimax_oauth_auth_status_not_logged_in
- test_get_minimax_oauth_auth_status_logged_in
Extended: tests/hermes_cli/test_runtime_provider_resolution.py
- test_minimax_oauth_runtime_returns_anthropic_messages_mode
- test_minimax_oauth_runtime_uses_inference_base_url
Extended: tests/hermes_cli/test_api_key_providers.py
- TestMinimaxOAuthProvider class (8 tests) covering registry keys,
auth_type, endpoints, client_id, aliases, CANONICAL_PROVIDERS
listing, _PROVIDER_MODELS entries, and aux model
Add comprehensive documentation for the minimax-oauth provider.
New file: website/docs/guides/minimax-oauth.md
- Overview table (provider ID, auth type, models, endpoints)
- Quick start via 'hermes model'
- Manual login via 'hermes auth add minimax-oauth'
- --region global|cn flag reference
- The PKCE OAuth flow explained step-by-step
- hermes doctor output example
- Configuration reference (config.yaml shape, region table, aliases)
- Environment variables note: MINIMAX_API_KEY is NOT used by
minimax-oauth (OAuth path uses browser login)
- Models table with context length note
- Troubleshooting section: expired token, timeout, state mismatch,
headless/remote sessions, not logged in
- Logout command
Updated: website/docs/getting-started/quickstart.md
- Add MiniMax (OAuth) to provider picker table as the recommended
path for users who want MiniMax models without an API key
Updated: website/docs/user-guide/configuration.md
- Add 'minimax-oauth' to the auxiliary providers list
- Add MiniMax OAuth tip callout in the providers section
- Add minimax-oauth row to the provider table (auxiliary tasks)
- Add MiniMax OAuth config.yaml example in Common Setups
Updated: website/docs/reference/environment-variables.md
- Annotate MINIMAX_API_KEY, MINIMAX_BASE_URL, MINIMAX_CN_API_KEY,
MINIMAX_CN_BASE_URL as NOT used by minimax-oauth
- Add minimax-oauth to HERMES_INFERENCE_PROVIDER allowed values
teknium1
added a commit
that referenced
this pull request
Apr 29, 2026
Close integration gaps discovered by auditing qwen-oauth's file coverage. These are surfaces the original salvage missed — they all existed on main and were added in the 747 commits since PR #15203 was opened. Coverage added: - agent/credential_pool.py: seed pool from auth.json providers.minimax-oauth so `hermes auth list` reflects logged-in state and `hermes auth remove minimax-oauth <N>` works through the standard flow. - agent/credential_sources.py: register RemovalStep for minimax-oauth with suppression-aware `_clear_auth_store_provider`. - agent/models_dev.py: PROVIDER_TO_MODELS_DEV mapping (-> 'minimax' family). - hermes_cli/providers.py: HermesOverlay entry (anthropic_messages transport, oauth_external auth_type, api.minimax.io/anthropic base). - hermes_cli/model_normalize.py: add to _MATCHING_PREFIX_STRIP_PROVIDERS so `minimax-oauth/MiniMax-M2.7` in config.yaml gets correctly repaired. - hermes_cli/status.py: render MiniMax OAuth block in `hermes doctor` (logged-in / region / expires_at / error). - hermes_cli/web_server.py: register in OAUTH_PROVIDER_REGISTRY + dispatch branch in _resolve_provider_status so the dashboard auth page shows it. - website/docs/integrations/providers.md: full 'MiniMax (OAuth)' section. - website/docs/reference/cli-commands.md: --provider enum. - website/docs/user-guide/features/fallback-providers.md: fallback table row. - scripts/release.py AUTHOR_MAP: amanning3390 mapping (CI gate).
Contributor
|
Merged via PR #17524 onto current main. All 4 of your original commits were cherry-picked with your authorship preserved (rebase-merge), plus a follow-up commit closed 10 integration gaps that peer OAuth providers had but hadn't existed yet when you opened this PR (credential pool seeding, credential_sources removal step, models_dev mapping, HermesOverlay, model normalize, hermes doctor block, dashboard auth page, and 3 docs pages). Thanks for the contribution — you're credited in scripts/release.py AUTHOR_MAP and in the merged git history. |
donald131
pushed a commit
to donald131/hermes-agent
that referenced
this pull request
May 2, 2026
Close integration gaps discovered by auditing qwen-oauth's file coverage. These are surfaces the original salvage missed — they all existed on main and were added in the 747 commits since PR NousResearch#15203 was opened. Coverage added: - agent/credential_pool.py: seed pool from auth.json providers.minimax-oauth so `hermes auth list` reflects logged-in state and `hermes auth remove minimax-oauth <N>` works through the standard flow. - agent/credential_sources.py: register RemovalStep for minimax-oauth with suppression-aware `_clear_auth_store_provider`. - agent/models_dev.py: PROVIDER_TO_MODELS_DEV mapping (-> 'minimax' family). - hermes_cli/providers.py: HermesOverlay entry (anthropic_messages transport, oauth_external auth_type, api.minimax.io/anthropic base). - hermes_cli/model_normalize.py: add to _MATCHING_PREFIX_STRIP_PROVIDERS so `minimax-oauth/MiniMax-M2.7` in config.yaml gets correctly repaired. - hermes_cli/status.py: render MiniMax OAuth block in `hermes doctor` (logged-in / region / expires_at / error). - hermes_cli/web_server.py: register in OAUTH_PROVIDER_REGISTRY + dispatch branch in _resolve_provider_status so the dashboard auth page shows it. - website/docs/integrations/providers.md: full 'MiniMax (OAuth)' section. - website/docs/reference/cli-commands.md: --provider enum. - website/docs/user-guide/features/fallback-providers.md: fallback table row. - scripts/release.py AUTHOR_MAP: amanning3390 mapping (CI gate).
nickdlkk
pushed a commit
to nickdlkk/hermes-agent
that referenced
this pull request
May 11, 2026
Close integration gaps discovered by auditing qwen-oauth's file coverage. These are surfaces the original salvage missed — they all existed on main and were added in the 747 commits since PR NousResearch#15203 was opened. Coverage added: - agent/credential_pool.py: seed pool from auth.json providers.minimax-oauth so `hermes auth list` reflects logged-in state and `hermes auth remove minimax-oauth <N>` works through the standard flow. - agent/credential_sources.py: register RemovalStep for minimax-oauth with suppression-aware `_clear_auth_store_provider`. - agent/models_dev.py: PROVIDER_TO_MODELS_DEV mapping (-> 'minimax' family). - hermes_cli/providers.py: HermesOverlay entry (anthropic_messages transport, oauth_external auth_type, api.minimax.io/anthropic base). - hermes_cli/model_normalize.py: add to _MATCHING_PREFIX_STRIP_PROVIDERS so `minimax-oauth/MiniMax-M2.7` in config.yaml gets correctly repaired. - hermes_cli/status.py: render MiniMax OAuth block in `hermes doctor` (logged-in / region / expires_at / error). - hermes_cli/web_server.py: register in OAUTH_PROVIDER_REGISTRY + dispatch branch in _resolve_provider_status so the dashboard auth page shows it. - website/docs/integrations/providers.md: full 'MiniMax (OAuth)' section. - website/docs/reference/cli-commands.md: --provider enum. - website/docs/user-guide/features/fallback-providers.md: fallback table row. - scripts/release.py AUTHOR_MAP: amanning3390 mapping (CI gate).
4 tasks
02356abc
pushed a commit
to 02356abc/hermes-agent
that referenced
this pull request
May 14, 2026
Close integration gaps discovered by auditing qwen-oauth's file coverage. These are surfaces the original salvage missed — they all existed on main and were added in the 747 commits since PR NousResearch#15203 was opened. Coverage added: - agent/credential_pool.py: seed pool from auth.json providers.minimax-oauth so `hermes auth list` reflects logged-in state and `hermes auth remove minimax-oauth <N>` works through the standard flow. - agent/credential_sources.py: register RemovalStep for minimax-oauth with suppression-aware `_clear_auth_store_provider`. - agent/models_dev.py: PROVIDER_TO_MODELS_DEV mapping (-> 'minimax' family). - hermes_cli/providers.py: HermesOverlay entry (anthropic_messages transport, oauth_external auth_type, api.minimax.io/anthropic base). - hermes_cli/model_normalize.py: add to _MATCHING_PREFIX_STRIP_PROVIDERS so `minimax-oauth/MiniMax-M2.7` in config.yaml gets correctly repaired. - hermes_cli/status.py: render MiniMax OAuth block in `hermes doctor` (logged-in / region / expires_at / error). - hermes_cli/web_server.py: register in OAUTH_PROVIDER_REGISTRY + dispatch branch in _resolve_provider_status so the dashboard auth page shows it. - website/docs/integrations/providers.md: full 'MiniMax (OAuth)' section. - website/docs/reference/cli-commands.md: --provider enum. - website/docs/user-guide/features/fallback-providers.md: fallback table row. - scripts/release.py AUTHOR_MAP: amanning3390 mapping (CI gate).
jsboige
pushed a commit
to jsboige/hermes-agent
that referenced
this pull request
May 14, 2026
Close integration gaps discovered by auditing qwen-oauth's file coverage. These are surfaces the original salvage missed — they all existed on main and were added in the 747 commits since PR NousResearch#15203 was opened. Coverage added: - agent/credential_pool.py: seed pool from auth.json providers.minimax-oauth so `hermes auth list` reflects logged-in state and `hermes auth remove minimax-oauth <N>` works through the standard flow. - agent/credential_sources.py: register RemovalStep for minimax-oauth with suppression-aware `_clear_auth_store_provider`. - agent/models_dev.py: PROVIDER_TO_MODELS_DEV mapping (-> 'minimax' family). - hermes_cli/providers.py: HermesOverlay entry (anthropic_messages transport, oauth_external auth_type, api.minimax.io/anthropic base). - hermes_cli/model_normalize.py: add to _MATCHING_PREFIX_STRIP_PROVIDERS so `minimax-oauth/MiniMax-M2.7` in config.yaml gets correctly repaired. - hermes_cli/status.py: render MiniMax OAuth block in `hermes doctor` (logged-in / region / expires_at / error). - hermes_cli/web_server.py: register in OAUTH_PROVIDER_REGISTRY + dispatch branch in _resolve_provider_status so the dashboard auth page shows it. - website/docs/integrations/providers.md: full 'MiniMax (OAuth)' section. - website/docs/reference/cli-commands.md: --provider enum. - website/docs/user-guide/features/fallback-providers.md: fallback table row. - scripts/release.py AUTHOR_MAP: amanning3390 mapping (CI gate).
dannyJ848
pushed a commit
to dannyJ848/hermes-agent
that referenced
this pull request
May 17, 2026
Close integration gaps discovered by auditing qwen-oauth's file coverage. These are surfaces the original salvage missed — they all existed on main and were added in the 747 commits since PR NousResearch#15203 was opened. Coverage added: - agent/credential_pool.py: seed pool from auth.json providers.minimax-oauth so `hermes auth list` reflects logged-in state and `hermes auth remove minimax-oauth <N>` works through the standard flow. - agent/credential_sources.py: register RemovalStep for minimax-oauth with suppression-aware `_clear_auth_store_provider`. - agent/models_dev.py: PROVIDER_TO_MODELS_DEV mapping (-> 'minimax' family). - hermes_cli/providers.py: HermesOverlay entry (anthropic_messages transport, oauth_external auth_type, api.minimax.io/anthropic base). - hermes_cli/model_normalize.py: add to _MATCHING_PREFIX_STRIP_PROVIDERS so `minimax-oauth/MiniMax-M2.7` in config.yaml gets correctly repaired. - hermes_cli/status.py: render MiniMax OAuth block in `hermes doctor` (logged-in / region / expires_at / error). - hermes_cli/web_server.py: register in OAUTH_PROVIDER_REGISTRY + dispatch branch in _resolve_provider_status so the dashboard auth page shows it. - website/docs/integrations/providers.md: full 'MiniMax (OAuth)' section. - website/docs/reference/cli-commands.md: --provider enum. - website/docs/user-guide/features/fallback-providers.md: fallback table row. - scripts/release.py AUTHOR_MAP: amanning3390 mapping (CI gate).
gweeteve
pushed a commit
to gweeteve/hermes-agent
that referenced
this pull request
Jun 2, 2026
Close integration gaps discovered by auditing qwen-oauth's file coverage. These are surfaces the original salvage missed — they all existed on main and were added in the 747 commits since PR NousResearch#15203 was opened. Coverage added: - agent/credential_pool.py: seed pool from auth.json providers.minimax-oauth so `hermes auth list` reflects logged-in state and `hermes auth remove minimax-oauth <N>` works through the standard flow. - agent/credential_sources.py: register RemovalStep for minimax-oauth with suppression-aware `_clear_auth_store_provider`. - agent/models_dev.py: PROVIDER_TO_MODELS_DEV mapping (-> 'minimax' family). - hermes_cli/providers.py: HermesOverlay entry (anthropic_messages transport, oauth_external auth_type, api.minimax.io/anthropic base). - hermes_cli/model_normalize.py: add to _MATCHING_PREFIX_STRIP_PROVIDERS so `minimax-oauth/MiniMax-M2.7` in config.yaml gets correctly repaired. - hermes_cli/status.py: render MiniMax OAuth block in `hermes doctor` (logged-in / region / expires_at / error). - hermes_cli/web_server.py: register in OAUTH_PROVIDER_REGISTRY + dispatch branch in _resolve_provider_status so the dashboard auth page shows it. - website/docs/integrations/providers.md: full 'MiniMax (OAuth)' section. - website/docs/reference/cli-commands.md: --provider enum. - website/docs/user-guide/features/fallback-providers.md: fallback table row. - scripts/release.py AUTHOR_MAP: amanning3390 mapping (CI gate).
Egavasyug
pushed a commit
to Egavasyug/hermes-agent
that referenced
this pull request
Jun 10, 2026
Close integration gaps discovered by auditing qwen-oauth's file coverage. These are surfaces the original salvage missed — they all existed on main and were added in the 747 commits since PR NousResearch#15203 was opened. Coverage added: - agent/credential_pool.py: seed pool from auth.json providers.minimax-oauth so `hermes auth list` reflects logged-in state and `hermes auth remove minimax-oauth <N>` works through the standard flow. - agent/credential_sources.py: register RemovalStep for minimax-oauth with suppression-aware `_clear_auth_store_provider`. - agent/models_dev.py: PROVIDER_TO_MODELS_DEV mapping (-> 'minimax' family). - hermes_cli/providers.py: HermesOverlay entry (anthropic_messages transport, oauth_external auth_type, api.minimax.io/anthropic base). - hermes_cli/model_normalize.py: add to _MATCHING_PREFIX_STRIP_PROVIDERS so `minimax-oauth/MiniMax-M2.7` in config.yaml gets correctly repaired. - hermes_cli/status.py: render MiniMax OAuth block in `hermes doctor` (logged-in / region / expires_at / error). - hermes_cli/web_server.py: register in OAUTH_PROVIDER_REGISTRY + dispatch branch in _resolve_provider_status so the dashboard auth page shows it. - website/docs/integrations/providers.md: full 'MiniMax (OAuth)' section. - website/docs/reference/cli-commands.md: --provider enum. - website/docs/user-guide/features/fallback-providers.md: fallback table row. - scripts/release.py AUTHOR_MAP: amanning3390 mapping (CI gate).
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.
What
Adds
minimax-oauthas a first-class inference provider in Hermes Agent, alongside the existing API-keyminimax/minimax-cnproviders. Users can now log in to MiniMax via browser OAuth instead of pasting an API key.minimax-oauth(aliases:minimax-portal,minimax-global,minimax_oauth)https://api.minimax.io/oauth/codeand/oauth/tokenanthropic_messagesapi_mode againsthttps://api.minimax.io/anthropic— no new adapter, no newapi_mode, sinceagent/anthropic_adapter.pyalready supports Bearer-token authget_hermes_home()), with standard OAuth2refresh_tokengrant andrefresh_token_reused/invalid_grantdetection--region global|cnflag to select betweenapi.minimax.ioandapi.minimaxi.comMiniMax-M2.7andMiniMax-M2.7-highspeed;MiniMax-M2.7-highspeedis wired as the auxiliary modelWhy
MiniMax's platform docs describe OAuth as a supported auth method for AI coding tools, and it ships today in OpenClaw via the bundled
minimaxextension. Per the Hermes Adding Providers guide, OAuth flows warrant a first-class built-in provider so thathermes model→ MiniMax (OAuth) can drive browser login end-to-end, tokens auto-refresh, and the experience matches the existing Nous Portal / OpenAI Codex OAuth paths.The OAuth flow is ported from
openclaw/extensions/minimax/oauth.ts(PKCE S256,urn:ietf:params:oauth:grant-type:user_codegrant, state validation, poll-with-deadline).How to test
Automated
Manual smoke test
Refresh path can be exercised by manually rolling
expires_atbackwards in the auth store and issuing any request — the nextresolve_minimax_oauth_runtime_credentials()call triggers a standardgrant_type=refresh_tokenexchange.Provider-alias resolution
What platforms
Browser open is skipped automatically on remote/headless sessions (reuses the existing
_is_remote_session()helper); the user gets the verification URL + user code printed for manual paste.Related issues
inference_base_urlfrom the registry + region flag and cannot be confused by a stalemodel.base_url./v1/modelsfor MiniMax: the newget_minimax_oauth_auth_status()check used byhermes doctoronly verifies local token state (present / not expired), so it does not hit the broken endpoint. Fix for the API-key doctor path is out of scope here.minimax-cnnot shown in /model list: unrelated to the OAuth provider wiring; the newminimax-oauthentry is added to bothCANONICAL_PROVIDERSand theselect_provider_and_model()flow, so it shows up inhermes modelandhermes setupfrom day one.Scope / non-goals
minimaxorminimax-cnproviders.MINIMAX_API_KEY/MINIMAX_CN_API_KEYcontinue to work for those, and are explicitly documented as not consumed byminimax-oauth.api_mode. This is a Path A contribution per the Adding Providers guide.Checklist (per Adding Providers)
ProviderConfigadded inhermes_cli/auth.pyhermes_cli/auth.pyandhermes_cli/models.pyhermes_cli/models.py(_PROVIDER_MODELS,CANONICAL_PROVIDERS)hermes_cli/runtime_provider.pyhermes_cli/main.py(provider_labels,providerslist,--providerchoices,_model_flow_minimax_oauth, dispatch)hermes_cli/setup.py— no changes needed (delegates toselect_provider_and_model)agent/auxiliary_client.pyagent/model_metadata.py(context length resolved via existingminimaxsubstring rule at 204,800)hermes_cli/auth_commands.py—hermes auth add minimax-oauthdispatchhermes_cli/doctor.py— health check branchtests/test_minimax_oauth.py,tests/hermes_cli/test_api_key_providers.py,tests/hermes_cli/test_runtime_provider_resolution.py)website/docs/guides/minimax-oauth.md, quickstart, configuration, environment-variables)Implementation ported from OpenClaw's reference OAuth flow at
openclaw/extensions/minimax/oauth.ts. By contributing, I agree that this contribution will be licensed under the MIT License.