Skip to content

feat(cli): add minimax-oauth provider with PKCE browser flow + full OAuth integration (salvage #15203)#17524

Merged
teknium1 merged 5 commits into
mainfrom
hermes/hermes-a68d743e
Apr 29, 2026
Merged

feat(cli): add minimax-oauth provider with PKCE browser flow + full OAuth integration (salvage #15203)#17524
teknium1 merged 5 commits into
mainfrom
hermes/hermes-a68d743e

Conversation

@teknium1

Copy link
Copy Markdown
Contributor

Salvages #15203 onto current main (747 commits behind at time of open) and closes integration gaps against peer OAuth providers.

Adds minimax-oauth as a first-class provider with a PKCE browser OAuth flow against MiniMax's portal (api.minimax.io/oauth/code + /oauth/token). Reuses the existing anthropic_messages api_mode against /anthropic — no new adapter, no new api_mode — since agent/anthropic_adapter.py already supports Bearer-token auth for MiniMax endpoints.

Changes (vs. #15203)

  • 4 original commits cherry-picked unchanged with @amanning3390 authorship preserved
  • Rebased onto current main (Apr 29), resolving conflicts in hermes_cli/main.py (argparse choices → runtime validation), tests/hermes_cli/test_runtime_provider_resolution.py (Azure Foundry / tencent-tokenhub additions), and 3 docs files (GMI Cloud entry, custom provider enum, azure-foundry auxiliary entry)
  • NEW feat(minimax-oauth): full integration with peer OAuth providers — closes 10 integration gaps the original PR didn't know about (they were added to main after feat(cli): add minimax-oauth provider with PKCE browser flow #15203 was opened):
File Purpose
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 via the standard flow
agent/credential_sources.py Register RemovalStep for minimax-oauth (suppression-aware)
agent/models_dev.py PROVIDER_TO_MODELS_DEV mapping → minimax family
hermes_cli/providers.py HermesOverlay (anthropic_messages / oauth_external / api.minimax.io/anthropic)
hermes_cli/model_normalize.py _MATCHING_PREFIX_STRIP_PROVIDERS — repairs minimax-oauth/MiniMax-M2.7MiniMax-M2.7
hermes_cli/status.py hermes doctor renders MiniMax OAuth block (logged-in / region / expires / error)
hermes_cli/web_server.py Dashboard auth page: _OAUTH_PROVIDER_CATALOG registration + _resolve_provider_status dispatch
website/docs/integrations/providers.md Full "MiniMax (OAuth)" section + fallback table row
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)

Validation

Targeted tests: 278/279 passed in 6.32s (1 pre-existing copilot/GITHUB_TOKEN unrelated failure — verified against clean origin/main, not introduced by this PR).

  • tests/test_minimax_oauth.py — 15 OAuth flow / refresh / token store tests
  • tests/hermes_cli/test_api_key_providers.py — provider registry + aliases
  • tests/hermes_cli/test_runtime_provider_resolution.py — runtime branches (incl. 2 new minimax-oauth tests)

E2E verified with isolated HERMES_HOME + mock auth state:

  • resolve_runtime_provider(requested="minimax-oauth")api_mode=anthropic_messages, base_url=https://api.minimax.io/anthropic, source=oauth
  • All 3 aliases (minimax-portal, minimax-global, minimax_oauth) route to minimax-oauth
  • credential_pool.load_pool("minimax-oauth") reflects logged-in token from auth.json
  • Not-logged-in raises AuthError with guidance: Run \hermes model` and select MiniMax (OAuth).`
  • hermes doctor block: MiniMax OAuth ✗ not logged in (run: hermes auth add minimax-oauth)
  • Dashboard /api/providers/oauth exposes {id: "minimax-oauth", flow: "pkce", source_label: "MiniMax (global)"}
  • credential_sources.find_removal_step("minimax-oauth", "oauth") resolves to registered step
  • model_normalize.normalize_model_for_provider("minimax-oauth/MiniMax-M2.7", "minimax-oauth")MiniMax-M2.7

Attribution

Original PR #15203 by @amanning3390. All 4 original commits cherry-picked onto current main with @amanning3390's authorship preserved via rebase-merge. Follow-up integration commit (feat(minimax-oauth): full integration with peer OAuth providers) by @teknium1.

Closes #15203.

amanning3390 and others added 5 commits April 29, 2026 08:17
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
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).
Comment thread hermes_cli/main.py Dismissed
Comment thread hermes_cli/status.py Dismissed
Comment thread hermes_cli/status.py Dismissed
Comment thread hermes_cli/status.py
if minimax_exp:
print(f" Access exp: {minimax_exp}")
if minimax_status.get("error") and not minimax_logged_in:
print(f" Error: {minimax_status.get('error')}")
@alt-glitch alt-glitch added type/feature New feature or request P3 Low — cosmetic, nice to have comp/cli CLI entry point, hermes_cli/, setup wizard area/auth Authentication, OAuth, credential pools provider/minimax MiniMax (Anthropic transport) labels Apr 29, 2026
@teknium1 teknium1 merged commit 40a98fb into main Apr 29, 2026
11 of 13 checks passed
@teknium1 teknium1 deleted the hermes/hermes-a68d743e branch April 29, 2026 16:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/auth Authentication, OAuth, credential pools comp/cli CLI entry point, hermes_cli/, setup wizard P3 Low — cosmetic, nice to have provider/minimax MiniMax (Anthropic transport) type/feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants