docs(auth): replace stale 'hermes login' references with 'hermes auth add'

'hermes login' was removed (the command now just prints a deprecation
message and exits). The bundled hermes-agent SKILL.md, in-code error
messages, the tip rotation, the proxy adapters, and the docs site
still pointed agents and users at the dead command — so models loading
the skill kept running 'hermes login --provider openai-codex' and
getting a dead-end print.

Replacements use the canonical 'hermes auth add <provider>' surface
(or bare 'hermes auth' for the interactive manager).

Files:
- skills/autonomous-ai-agents/hermes-agent/SKILL.md (+ regenerated docs page)
- hermes_cli/tips.py (tip rotation)
- agent/google_oauth.py (gemini-cli error message)
- agent/conversation_loop.py (nous re-auth troubleshooting line)
- agent/credential_sources.py (docstring)
- hermes_cli/proxy/cli.py + hermes_cli/proxy/adapters/nous_portal.py (proxy auth hints)
- tests/hermes_cli/test_proxy.py (updated assertions)
- website/docs/reference/faq.md, website/docs/user-guide/features/subscription-proxy.md
- zh-Hans i18n mirrors for the above

'hermes logout' is still a live command and is left untouched.
The 'hermes login' stub in hermes_cli/auth.py:login_command() and
the cli-commands.md 'Deprecated' rows are intentionally kept as
the discoverable deprecation surface.
This commit is contained in:
Teknium 2026-05-26 15:40:24 -07:00
parent f05a47309e
commit bb4703c761
14 changed files with 46 additions and 38 deletions

View file

@ -2218,7 +2218,7 @@ def run_conversation(
print(f"{agent.log_prefix} Response: {_body_text}") print(f"{agent.log_prefix} Response: {_body_text}")
print(f"{agent.log_prefix} Most likely: Portal OAuth expired, account out of credits, or agent key revoked.") print(f"{agent.log_prefix} Most likely: Portal OAuth expired, account out of credits, or agent key revoked.")
print(f"{agent.log_prefix} Troubleshooting:") print(f"{agent.log_prefix} Troubleshooting:")
print(f"{agent.log_prefix} • Re-authenticate: hermes login --provider nous") print(f"{agent.log_prefix} • Re-authenticate: hermes auth add nous")
print(f"{agent.log_prefix} • Check credits / billing: https://portal.nousresearch.com") print(f"{agent.log_prefix} • Check credits / billing: https://portal.nousresearch.com")
print(f"{agent.log_prefix} • Verify stored credentials: {_dhh}/auth.json") print(f"{agent.log_prefix} • Verify stored credentials: {_dhh}/auth.json")
print(f"{agent.log_prefix} • Switch providers temporarily: /model <model> --provider openrouter") print(f"{agent.log_prefix} • Switch providers temporarily: /model <model> --provider openrouter")

View file

@ -240,11 +240,11 @@ def _clear_auth_store_provider(provider: str) -> bool:
def _remove_nous_device_code(provider: str, removed) -> RemovalResult: def _remove_nous_device_code(provider: str, removed) -> RemovalResult:
"""Nous OAuth lives in auth.json providers.nous — clear it and suppress. """Nous OAuth lives in auth.json providers.nous — clear it and suppress.
We suppress in addition to clearing because nothing else stops the We suppress in addition to clearing because nothing else stops a future
user's next `hermes login` run from writing providers.nous again `hermes auth add nous` (or any other path that writes providers.nous)
before they decide to. Suppression forces them to go through from re-seeding before the user has decided to. Suppression forces
`hermes auth add nous` to re-engage, which is the documented re-add them to go through `hermes auth add nous` to re-engage, which is the
path and clears the suppression atomically. documented re-add path and clears the suppression atomically.
""" """
result = RemovalResult() result = RemovalResult()
if _clear_auth_store_provider(provider): if _clear_auth_store_provider(provider):

View file

@ -656,7 +656,7 @@ def get_valid_access_token(*, force_refresh: bool = False) -> str:
creds = load_credentials() creds = load_credentials()
if creds is None: if creds is None:
raise GoogleOAuthError( raise GoogleOAuthError(
"No Google OAuth credentials found. Run `hermes login --provider google-gemini-cli` first.", "No Google OAuth credentials found. Run `hermes auth add google-gemini-cli` first.",
code="google_oauth_not_logged_in", code="google_oauth_not_logged_in",
) )

View file

@ -104,7 +104,7 @@ class NousPortalAdapter(UpstreamAdapter):
state = self._read_state() state = self._read_state()
if state is None: if state is None:
raise RuntimeError( raise RuntimeError(
"Not logged into Nous Portal. Run `hermes login nous` first." "Not logged into Nous Portal. Run `hermes auth add nous` first."
) )
try: try:
@ -135,7 +135,7 @@ class NousPortalAdapter(UpstreamAdapter):
if not agent_key: if not agent_key:
raise RuntimeError( raise RuntimeError(
"Nous Portal refresh did not return a usable agent_key. " "Nous Portal refresh did not return a usable agent_key. "
"Try `hermes login nous` to re-authenticate." "Try `hermes auth add nous` to re-authenticate."
) )
base_url = ( base_url = (

View file

@ -44,7 +44,7 @@ def cmd_proxy_start(args: Any) -> int:
return 2 return 2
if not adapter.is_authenticated(): if not adapter.is_authenticated():
auth_hint = getattr(adapter, "auth_hint", f"hermes login {adapter.name}") auth_hint = getattr(adapter, "auth_hint", f"hermes auth add {adapter.name}")
print( print(
f"Not logged into {adapter.display_name}. " f"Not logged into {adapter.display_name}. "
f"Run `{auth_hint}` first.", f"Run `{auth_hint}` first.",

View file

@ -263,7 +263,7 @@ TIPS = [
"Custom providers: save named endpoints in config.yaml under custom_providers.", "Custom providers: save named endpoints in config.yaml under custom_providers.",
"HERMES_EPHEMERAL_SYSTEM_PROMPT injects a system prompt that's never persisted to history.", "HERMES_EPHEMERAL_SYSTEM_PROMPT injects a system prompt that's never persisted to history.",
"credential_pool_strategies supports fill_first, round_robin, least_used, and random rotation.", "credential_pool_strategies supports fill_first, round_robin, least_used, and random rotation.",
"hermes login supports OAuth-based auth for Nous and OpenAI Codex providers.", "hermes auth add nous or hermes auth add openai-codex sets up OAuth-based providers.",
"The API server supports both Chat Completions and Responses API with server-side state.", "The API server supports both Chat Completions and Responses API with server-side state.",
"tool_preview_length: 0 in config shows full file paths in the spinner's activity feed.", "tool_preview_length: 0 in config shows full file paths in the spinner's activity feed.",
"hermes status --deep runs deeper diagnostic checks across all components.", "hermes status --deep runs deeper diagnostic checks across all components.",

View file

@ -100,8 +100,10 @@ hermes config path Print config.yaml path
hermes config env-path Print .env path hermes config env-path Print .env path
hermes config check Check for missing/outdated config hermes config check Check for missing/outdated config
hermes config migrate Update config with new options hermes config migrate Update config with new options
hermes login [--provider P] OAuth login (nous, openai-codex) hermes auth Interactive credential manager
hermes logout Clear stored auth hermes auth add PROVIDER Add OAuth or API-key credential (e.g. nous, openai-codex, qwen-oauth)
hermes auth list List stored credentials
hermes auth remove PROVIDER Remove a stored credential
hermes doctor [--fix] Check dependencies and config hermes doctor [--fix] Check dependencies and config
hermes status [--all] Show component status hermes status [--all] Show component status
``` ```
@ -390,7 +392,7 @@ Full config reference: https://hermes-agent.nousresearch.com/docs/user-guide/con
| AI Gateway (Vercel) | API key | `AI_GATEWAY_API_KEY` | | AI Gateway (Vercel) | API key | `AI_GATEWAY_API_KEY` |
| OpenCode Zen | API key | `OPENCODE_ZEN_API_KEY` | | OpenCode Zen | API key | `OPENCODE_ZEN_API_KEY` |
| OpenCode Go | API key | `OPENCODE_GO_API_KEY` | | OpenCode Go | API key | `OPENCODE_GO_API_KEY` |
| Qwen OAuth | OAuth | `hermes login --provider qwen-oauth` | | Qwen OAuth | OAuth | `hermes auth add qwen-oauth` |
| Custom endpoint | Config | `model.base_url` + `model.api_key` in config.yaml | | Custom endpoint | Config | `model.base_url` + `model.api_key` in config.yaml |
| GitHub Copilot ACP | External | `COPILOT_CLI_PATH` or Copilot CLI | | GitHub Copilot ACP | External | `COPILOT_CLI_PATH` or Copilot CLI |
@ -812,7 +814,7 @@ and logs — avoids shell-escaping backslashes in bash.
### Model/provider issues ### Model/provider issues
1. `hermes doctor` — check config and dependencies 1. `hermes doctor` — check config and dependencies
2. `hermes login` — re-authenticate OAuth providers 2. `hermes auth` — re-authenticate OAuth providers (or `hermes auth add <provider>`)
3. Check `.env` has the right API key 3. Check `.env` has the right API key
4. **Copilot 403**: `gh auth login` tokens do NOT work for Copilot API. You must use the Copilot-specific OAuth device code flow via `hermes model` → GitHub Copilot. 4. **Copilot 403**: `gh auth login` tokens do NOT work for Copilot API. You must use the Copilot-specific OAuth device code flow via `hermes model` → GitHub Copilot.

View file

@ -207,7 +207,7 @@ def test_nous_adapter_retry_credential_skips_opaque_bearer(tmp_path, monkeypatch
def test_nous_adapter_get_credential_raises_when_not_logged_in(tmp_path, monkeypatch): def test_nous_adapter_get_credential_raises_when_not_logged_in(tmp_path, monkeypatch):
monkeypatch.setenv("HERMES_HOME", str(tmp_path)) monkeypatch.setenv("HERMES_HOME", str(tmp_path))
adapter = NousPortalAdapter() adapter = NousPortalAdapter()
with pytest.raises(RuntimeError, match="hermes login nous"): with pytest.raises(RuntimeError, match="hermes auth add nous"):
adapter.get_credential() adapter.get_credential()
@ -784,4 +784,4 @@ def test_cmd_proxy_start_refuses_when_unauthenticated(capsys, tmp_path, monkeypa
rc = cmd_proxy_start(args) rc = cmd_proxy_start(args)
assert rc == 2 assert rc == 2
err = capsys.readouterr().err err = capsys.readouterr().err
assert "hermes login nous" in err assert "hermes auth add nous" in err

View file

@ -19,7 +19,7 @@ Hermes Agent works with any OpenAI-compatible API. Supported providers include:
- **[OpenRouter](https://openrouter.ai/)** — access hundreds of models through one API key (recommended for flexibility) - **[OpenRouter](https://openrouter.ai/)** — access hundreds of models through one API key (recommended for flexibility)
- **Nous Portal** — Nous Research's own inference endpoint - **Nous Portal** — Nous Research's own inference endpoint
- **OpenAI** — GPT-5.4, GPT-5-codex, GPT-4.1, GPT-4o, etc. - **OpenAI** — GPT-5.4, GPT-5-codex, GPT-4.1, GPT-4o, etc.
- **Anthropic** — Claude models (direct API, OAuth via `hermes login anthropic`, OpenRouter, or any compatible proxy) - **Anthropic** — Claude models (direct API, OAuth via `hermes auth add anthropic`, OpenRouter, or any compatible proxy)
- **Google** — Gemini models (direct API via `gemini` provider, the `google-gemini-cli` OAuth provider, OpenRouter, or compatible proxy) - **Google** — Gemini models (direct API via `gemini` provider, the `google-gemini-cli` OAuth provider, OpenRouter, or compatible proxy)
- **z.ai / ZhipuAI** — GLM models - **z.ai / ZhipuAI** — GLM models
- **Kimi / Moonshot AI** — Kimi models - **Kimi / Moonshot AI** — Kimi models

View file

@ -29,7 +29,7 @@ proxy when you just want **the model** through your subscription.
### 1. Log into your provider (one-time) ### 1. Log into your provider (one-time)
```bash ```bash
hermes login nous hermes auth add nous
``` ```
This opens your browser for the Nous Portal OAuth flow. Hermes stores This opens your browser for the Nous Portal OAuth flow. Hermes stores
@ -88,10 +88,10 @@ Hermes proxy upstream adapters
[nous ] Nous Portal — ready (bearer expires 2026-05-15T06:43:21Z) [nous ] Nous Portal — ready (bearer expires 2026-05-15T06:43:21Z)
``` ```
If you see `not logged in`, run `hermes login nous`. If you see If you see `not logged in`, run `hermes auth add nous`. If you see
`credentials need attention`, your refresh token was revoked (rare — `credentials need attention`, your refresh token was revoked (rare —
happens if you signed out from the Portal web UI) — just re-run happens if you signed out from the Portal web UI) — just re-run
`hermes login nous`. `hermes auth add nous`.
## Allowed paths ## Allowed paths

View file

@ -21,7 +21,7 @@ Configure, extend, or contribute to Hermes Agent.
| License | MIT | | License | MIT |
| Platforms | linux, macos, windows | | Platforms | linux, macos, windows |
| Tags | `hermes`, `setup`, `configuration`, `multi-agent`, `spawning`, `cli`, `gateway`, `development` | | Tags | `hermes`, `setup`, `configuration`, `multi-agent`, `spawning`, `cli`, `gateway`, `development` |
| Related skills | [`claude-code`](/user-guide/skills/bundled/autonomous-ai-agents/autonomous-ai-agents-claude-code), [`codex`](/user-guide/skills/bundled/autonomous-ai-agents/autonomous-ai-agents-codex), [`opencode`](/user-guide/skills/bundled/autonomous-ai-agents/autonomous-ai-agents-opencode) | | Related skills | [`claude-code`](/docs/user-guide/skills/bundled/autonomous-ai-agents/autonomous-ai-agents-claude-code), [`codex`](/docs/user-guide/skills/bundled/autonomous-ai-agents/autonomous-ai-agents-codex), [`opencode`](/docs/user-guide/skills/bundled/autonomous-ai-agents/autonomous-ai-agents-opencode) |
## Reference: full SKILL.md ## Reference: full SKILL.md
@ -117,8 +117,10 @@ hermes config path Print config.yaml path
hermes config env-path Print .env path hermes config env-path Print .env path
hermes config check Check for missing/outdated config hermes config check Check for missing/outdated config
hermes config migrate Update config with new options hermes config migrate Update config with new options
hermes login [--provider P] OAuth login (nous, openai-codex) hermes auth Interactive credential manager
hermes logout Clear stored auth hermes auth add PROVIDER Add OAuth or API-key credential (e.g. nous, openai-codex, qwen-oauth)
hermes auth list List stored credentials
hermes auth remove PROVIDER Remove a stored credential
hermes doctor [--fix] Check dependencies and config hermes doctor [--fix] Check dependencies and config
hermes status [--all] Show component status hermes status [--all] Show component status
``` ```
@ -353,7 +355,8 @@ The registry of record is `hermes_cli/commands.py` — every consumer
~/.hermes/config.yaml Main configuration ~/.hermes/config.yaml Main configuration
~/.hermes/.env API keys and secrets ~/.hermes/.env API keys and secrets
$HERMES_HOME/skills/ Installed skills $HERMES_HOME/skills/ Installed skills
~/.hermes/sessions/ Session transcripts ~/.hermes/sessions/ Gateway routing index, request dumps, *.jsonl transcripts (and optional per-session JSON snapshots when sessions.write_json_snapshots: true)
~/.hermes/state.db Canonical session store (SQLite + FTS5)
~/.hermes/logs/ Gateway and error logs ~/.hermes/logs/ Gateway and error logs
~/.hermes/auth.json OAuth tokens and credential pools ~/.hermes/auth.json OAuth tokens and credential pools
~/.hermes/hermes-agent/ Source code (if git-installed) ~/.hermes/hermes-agent/ Source code (if git-installed)
@ -406,7 +409,7 @@ Full config reference: https://hermes-agent.nousresearch.com/docs/user-guide/con
| AI Gateway (Vercel) | API key | `AI_GATEWAY_API_KEY` | | AI Gateway (Vercel) | API key | `AI_GATEWAY_API_KEY` |
| OpenCode Zen | API key | `OPENCODE_ZEN_API_KEY` | | OpenCode Zen | API key | `OPENCODE_ZEN_API_KEY` |
| OpenCode Go | API key | `OPENCODE_GO_API_KEY` | | OpenCode Go | API key | `OPENCODE_GO_API_KEY` |
| Qwen OAuth | OAuth | `hermes login --provider qwen-oauth` | | Qwen OAuth | OAuth | `hermes auth add qwen-oauth` |
| Custom endpoint | Config | `model.base_url` + `model.api_key` in config.yaml | | Custom endpoint | Config | `model.base_url` + `model.api_key` in config.yaml |
| GitHub Copilot ACP | External | `COPILOT_CLI_PATH` or Copilot CLI | | GitHub Copilot ACP | External | `COPILOT_CLI_PATH` or Copilot CLI |
@ -713,8 +716,9 @@ sessions still have zero `kanban_*` schema footprint unless configured.
- **Dispatcher** runs inside the gateway by default - **Dispatcher** runs inside the gateway by default
(`kanban.dispatch_in_gateway: true`) — reclaims stale claims, (`kanban.dispatch_in_gateway: true`) — reclaims stale claims,
promotes ready tasks, atomically claims, spawns assigned profiles. promotes ready tasks, atomically claims, spawns assigned profiles.
Auto-blocks a task after the configured `kanban.failure_limit` Auto-blocks a task after `failure_limit` consecutive spawn failures
consecutive non-success attempts (default: 2). (default 2; configurable via `kanban.failure_limit` or per-task
`max_retries`).
- **Isolation:** board is the hard boundary (workers get - **Isolation:** board is the hard boundary (workers get
`HERMES_KANBAN_BOARD` pinned in env); tenant is a soft namespace `HERMES_KANBAN_BOARD` pinned in env); tenant is a soft namespace
within a board for workspace-path + memory-key isolation. within a board for workspace-path + memory-key isolation.
@ -827,7 +831,7 @@ and logs — avoids shell-escaping backslashes in bash.
### Model/provider issues ### Model/provider issues
1. `hermes doctor` — check config and dependencies 1. `hermes doctor` — check config and dependencies
2. `hermes login` — re-authenticate OAuth providers 2. `hermes auth` — re-authenticate OAuth providers (or `hermes auth add <provider>`)
3. Check `.env` has the right API key 3. Check `.env` has the right API key
4. **Copilot 403**: `gh auth login` tokens do NOT work for Copilot API. You must use the Copilot-specific OAuth device code flow via `hermes model` → GitHub Copilot. 4. **Copilot 403**: `gh auth login` tokens do NOT work for Copilot API. You must use the Copilot-specific OAuth device code flow via `hermes model` → GitHub Copilot.
@ -858,7 +862,7 @@ Common gateway problems:
- **Windows-specific issues** (`Alt+Enter` newline, WinError 10106, UTF-8 BOM config, test suite, line endings): see the dedicated **Windows-Specific Quirks** section above. - **Windows-specific issues** (`Alt+Enter` newline, WinError 10106, UTF-8 BOM config, test suite, line endings): see the dedicated **Windows-Specific Quirks** section above.
### Auxiliary models not working ### Auxiliary models not working
If `auxiliary` tasks (vision, compression) fail silently, the `auto` provider can't find a backend. Either set `OPENROUTER_API_KEY` or `GOOGLE_API_KEY`, or explicitly configure each auxiliary task's provider: If `auxiliary` tasks (vision, compression, session_search) fail silently, the `auto` provider can't find a backend. Either set `OPENROUTER_API_KEY` or `GOOGLE_API_KEY`, or explicitly configure each auxiliary task's provider:
```bash ```bash
hermes config set auxiliary.vision.provider <your_provider> hermes config set auxiliary.vision.provider <your_provider>
hermes config set auxiliary.vision.model <model_name> hermes config set auxiliary.vision.model <model_name>
@ -883,7 +887,7 @@ hermes config set auxiliary.vision.model <model_name>
| Env variables | `hermes config env-path` or [Env vars reference](https://hermes-agent.nousresearch.com/docs/reference/environment-variables) | | Env variables | `hermes config env-path` or [Env vars reference](https://hermes-agent.nousresearch.com/docs/reference/environment-variables) |
| CLI commands | `hermes --help` or [CLI reference](https://hermes-agent.nousresearch.com/docs/reference/cli-commands) | | CLI commands | `hermes --help` or [CLI reference](https://hermes-agent.nousresearch.com/docs/reference/cli-commands) |
| Gateway logs | `~/.hermes/logs/gateway.log` | | Gateway logs | `~/.hermes/logs/gateway.log` |
| Session files | `~/.hermes/sessions/` or `hermes sessions browse` | | Session files | `hermes sessions browse` (reads state.db) |
| Source code | `~/.hermes/hermes-agent/` | | Source code | `~/.hermes/hermes-agent/` |
--- ---

View file

@ -19,7 +19,7 @@ Hermes Agent 可与任何兼容 OpenAI 的 API 配合使用。支持的提供商
- **[OpenRouter](https://openrouter.ai/)** — 通过一个 API key 访问数百个模型(推荐,灵活性强) - **[OpenRouter](https://openrouter.ai/)** — 通过一个 API key 访问数百个模型(推荐,灵活性强)
- **Nous Portal** — Nous Research 自有推理端点 - **Nous Portal** — Nous Research 自有推理端点
- **OpenAI** — GPT-5.4、GPT-5-codex、GPT-4.1、GPT-4o 等 - **OpenAI** — GPT-5.4、GPT-5-codex、GPT-4.1、GPT-4o 等
- **Anthropic** — Claude 模型(直接 API、通过 `hermes login anthropic` 进行 OAuth、OpenRouter 或任何兼容代理) - **Anthropic** — Claude 模型(直接 API、通过 `hermes auth add anthropic` 进行 OAuth、OpenRouter 或任何兼容代理)
- **Google** — Gemini 模型(通过 `gemini` 提供商直接调用 API、`google-gemini-cli` OAuth 提供商、OpenRouter 或兼容代理) - **Google** — Gemini 模型(通过 `gemini` 提供商直接调用 API、`google-gemini-cli` OAuth 提供商、OpenRouter 或兼容代理)
- **z.ai / ZhipuAI** — GLM 模型 - **z.ai / ZhipuAI** — GLM 模型
- **Kimi / Moonshot AI** — Kimi 模型 - **Kimi / Moonshot AI** — Kimi 模型

View file

@ -24,7 +24,7 @@ description: "将你的 Nous Portal 订阅(或其他 OAuth 提供商)用作
### 1. 登录你的提供商(仅需一次) ### 1. 登录你的提供商(仅需一次)
```bash ```bash
hermes login nous hermes auth add nous
``` ```
这会打开浏览器进行 Nous Portal OAuth 流程。Hermes 将刷新令牌存储在 `~/.hermes/auth.json` 中——与所有 Hermes 提供商登录信息存放在同一位置。 这会打开浏览器进行 Nous Portal OAuth 流程。Hermes 将刷新令牌存储在 `~/.hermes/auth.json` 中——与所有 Hermes 提供商登录信息存放在同一位置。
@ -76,7 +76,7 @@ Hermes proxy upstream adapters
[nous ] Nous Portal — ready (bearer expires 2026-05-15T06:43:21Z) [nous ] Nous Portal — ready (bearer expires 2026-05-15T06:43:21Z)
``` ```
如果显示 `not logged in`,请运行 `hermes login nous`。如果显示 `credentials need attention`,说明你的刷新令牌已被撤销(较少见——通常发生在你从 Portal Web UI 退出登录时)——重新运行 `hermes login nous` 即可。 如果显示 `not logged in`,请运行 `hermes auth add nous`。如果显示 `credentials need attention`,说明你的刷新令牌已被撤销(较少见——通常发生在你从 Portal Web UI 退出登录时)——重新运行 `hermes auth add nous` 即可。
## 允许的路径 ## 允许的路径

View file

@ -117,8 +117,10 @@ hermes config path Print config.yaml path
hermes config env-path Print .env path hermes config env-path Print .env path
hermes config check Check for missing/outdated config hermes config check Check for missing/outdated config
hermes config migrate Update config with new options hermes config migrate Update config with new options
hermes login [--provider P] OAuth login (nous, openai-codex) hermes auth 交互式凭据管理器
hermes logout Clear stored auth hermes auth add PROVIDER 添加 OAuth 或 API key 凭据(例如 nous、openai-codex、qwen-oauth
hermes auth list 列出已存储的凭据
hermes auth remove PROVIDER 移除已存储的凭据
hermes doctor [--fix] Check dependencies and config hermes doctor [--fix] Check dependencies and config
hermes status [--all] Show component status hermes status [--all] Show component status
``` ```
@ -402,7 +404,7 @@ Profiles 使用 `~/.hermes/profiles/<name>/`,布局相同。
| AI Gateway (Vercel) | API key | `AI_GATEWAY_API_KEY` | | AI Gateway (Vercel) | API key | `AI_GATEWAY_API_KEY` |
| OpenCode Zen | API key | `OPENCODE_ZEN_API_KEY` | | OpenCode Zen | API key | `OPENCODE_ZEN_API_KEY` |
| OpenCode Go | API key | `OPENCODE_GO_API_KEY` | | OpenCode Go | API key | `OPENCODE_GO_API_KEY` |
| Qwen OAuth | OAuth | `hermes login --provider qwen-oauth` | | Qwen OAuth | OAuth | `hermes auth add qwen-oauth` |
| 自定义端点 | 配置 | `config.yaml` 中的 `model.base_url` + `model.api_key` | | 自定义端点 | 配置 | `config.yaml` 中的 `model.base_url` + `model.api_key` |
| GitHub Copilot ACP | 外部 | `COPILOT_CLI_PATH` 或 Copilot CLI | | GitHub Copilot ACP | 外部 | `COPILOT_CLI_PATH` 或 Copilot CLI |
@ -737,7 +739,7 @@ export PYTHONPATH="$(pwd)"
### 模型/提供商问题 ### 模型/提供商问题
1. `hermes doctor` — 检查配置和依赖 1. `hermes doctor` — 检查配置和依赖
2. `hermes login` — 重新认证 OAuth 提供商 2. `hermes auth` — 重新认证 OAuth 提供商(或 `hermes auth add <provider>`
3. 检查 `.env` 中是否有正确的 API key 3. 检查 `.env` 中是否有正确的 API key
4. **Copilot 403**`gh auth login` 的 token **不适用于** Copilot API。必须通过 `hermes model` → GitHub Copilot 使用 Copilot 专用 OAuth 设备码流程。 4. **Copilot 403**`gh auth login` 的 token **不适用于** Copilot API。必须通过 `hermes model` → GitHub Copilot 使用 Copilot 专用 OAuth 设备码流程。