fix: add Grok OAuth provider catalog support
This commit is contained in:
@@ -2,6 +2,10 @@
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
### Fixed
|
||||
|
||||
- **PR #2568** by @Michaelyklam (closes #2545) — Add the Hermes Agent `xai-oauth` provider to the WebUI's OAuth/provider catalogs so Grok OAuth accounts authenticated through the Hermes CLI appear in Settings → Providers and the model picker. The provider is treated as CLI-managed OAuth (not WebUI API-key configurable) and uses the live Hermes CLI model catalog when available with a Grok static fallback.
|
||||
|
||||
## [v0.51.91] — 2026-05-18 — Release BO (stage-384 — 5-PR full sweep batch — reasoning-replay history fix + archive-extract per-session inbox + fallback streaming warnings + sanitized custom-provider env hints + Slice 3c queue/goal adapter routing)
|
||||
|
||||
### Fixed
|
||||
|
||||
@@ -692,6 +692,7 @@ _PROVIDER_DISPLAY = {
|
||||
"anthropic": "Anthropic",
|
||||
"openai": "OpenAI",
|
||||
"openai-codex": "OpenAI Codex",
|
||||
"xai-oauth": "xAI Grok OAuth",
|
||||
"copilot": "GitHub Copilot",
|
||||
"zai": "Z.AI / GLM",
|
||||
"kimi-coding": "Kimi / Moonshot",
|
||||
@@ -1209,6 +1210,9 @@ _PROVIDER_MODELS = {
|
||||
"x-ai": [
|
||||
{"id": "grok-4.20", "label": "Grok 4.20"},
|
||||
],
|
||||
"xai-oauth": [
|
||||
{"id": "grok-4.20", "label": "Grok 4.20"},
|
||||
],
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -692,6 +692,7 @@ _OAUTH_PROVIDERS = frozenset({
|
||||
"nous",
|
||||
"openai-codex",
|
||||
"qwen-oauth",
|
||||
"xai-oauth",
|
||||
})
|
||||
|
||||
# SECTION: Helper functions
|
||||
@@ -1866,6 +1867,14 @@ def get_providers() -> dict[str, Any]:
|
||||
if live_models:
|
||||
models = live_models
|
||||
models_total = len(models)
|
||||
if pid == "xai-oauth":
|
||||
live_models = _models_from_live_provider_ids(
|
||||
pid,
|
||||
_read_live_provider_model_ids("xai-oauth"),
|
||||
)
|
||||
if live_models:
|
||||
models = live_models
|
||||
models_total = len(models)
|
||||
# Nous Portal: prefer the live catalog so the providers card matches
|
||||
# the dropdown picker (#1538). Same fallback shape as the static-only
|
||||
# case below — when hermes_cli is unavailable or its lookup raises,
|
||||
|
||||
78
tests/test_issue2545_xai_oauth_provider.py
Normal file
78
tests/test_issue2545_xai_oauth_provider.py
Normal file
@@ -0,0 +1,78 @@
|
||||
import copy
|
||||
|
||||
import api.config as config
|
||||
import api.profiles as profiles
|
||||
|
||||
|
||||
def _with_config(monkeypatch, tmp_path, cfg):
|
||||
old_cfg = copy.deepcopy(config.cfg)
|
||||
old_mtime = config._cfg_mtime
|
||||
config.cfg.clear()
|
||||
config.cfg.update(copy.deepcopy(cfg))
|
||||
config._cfg_mtime = 0.0
|
||||
config.invalidate_models_cache()
|
||||
monkeypatch.setattr(profiles, "get_active_hermes_home", lambda: tmp_path)
|
||||
|
||||
def restore():
|
||||
config.cfg.clear()
|
||||
config.cfg.update(old_cfg)
|
||||
config._cfg_mtime = old_mtime
|
||||
config.invalidate_models_cache()
|
||||
|
||||
return restore
|
||||
|
||||
|
||||
def test_xai_oauth_is_known_oauth_provider():
|
||||
from api.providers import _OAUTH_PROVIDERS
|
||||
from api.config import _PROVIDER_DISPLAY
|
||||
|
||||
assert "xai-oauth" in _OAUTH_PROVIDERS
|
||||
assert _PROVIDER_DISPLAY["xai-oauth"] == "xAI Grok OAuth"
|
||||
|
||||
|
||||
def test_xai_oauth_provider_card_uses_oauth_status_and_models(monkeypatch, tmp_path):
|
||||
restore = _with_config(
|
||||
monkeypatch,
|
||||
tmp_path,
|
||||
{
|
||||
"model": {"provider": "xai-oauth", "default": "grok-4.20"},
|
||||
"providers": {},
|
||||
},
|
||||
)
|
||||
monkeypatch.setattr(config, "_read_live_provider_model_ids", lambda pid: ["grok-4.20"] if pid == "xai-oauth" else [])
|
||||
try:
|
||||
from api.providers import get_providers
|
||||
import api.providers as providers
|
||||
|
||||
monkeypatch.setattr(providers, "_read_live_provider_model_ids", lambda pid: ["grok-4.20"] if pid == "xai-oauth" else [])
|
||||
|
||||
result = get_providers()
|
||||
grok = next(p for p in result["providers"] if p["id"] == "xai-oauth")
|
||||
assert grok["display_name"] == "xAI Grok OAuth"
|
||||
assert grok["is_oauth"] is True
|
||||
assert grok["configurable"] is False
|
||||
assert grok["key_source"] == "oauth"
|
||||
assert grok["models"] == [{"id": "grok-4.20", "label": "Grok 4.20"}]
|
||||
assert grok["models_total"] == 1
|
||||
finally:
|
||||
restore()
|
||||
|
||||
|
||||
def test_xai_oauth_model_picker_group_uses_live_catalog(monkeypatch, tmp_path):
|
||||
restore = _with_config(
|
||||
monkeypatch,
|
||||
tmp_path,
|
||||
{
|
||||
"model": {"provider": "xai-oauth", "default": "grok-4.20"},
|
||||
"providers": {"xai-oauth": {}},
|
||||
},
|
||||
)
|
||||
monkeypatch.setattr(config, "_read_live_provider_model_ids", lambda pid: ["grok-4.20"] if pid == "xai-oauth" else [])
|
||||
try:
|
||||
result = config.get_available_models()
|
||||
group = next(g for g in result["groups"] if g["provider_id"] == "xai-oauth")
|
||||
assert group["provider"] == "xAI Grok OAuth"
|
||||
assert group["models"] == [{"id": "grok-4.20", "label": "Grok 4.20"}]
|
||||
assert result["active_provider"] == "xai-oauth"
|
||||
finally:
|
||||
restore()
|
||||
Reference in New Issue
Block a user