Skip to content

fix: hermes apply switch defaults updates base url from settings#2333

Open
lehug wants to merge 1 commit intofarion1231:mainfrom
lehug:main
Open

fix: hermes apply switch defaults updates base url from settings#2333
lehug wants to merge 1 commit intofarion1231:mainfrom
lehug:main

Conversation

@lehug
Copy link
Copy Markdown

@lehug lehug commented Apr 25, 2026

Summary / 概述

hermes切换时,model的baseUrl未变更,导致配置不完整,不可用。

Related Issue / 关联 Issue

Fixes #

Screenshots / 截图

Before / 修改前 After / 修改后

Checklist / 检查清单

  • pnpm typecheck passes / 通过 TypeScript 类型检查
  • pnpm format:check passes / 通过代码格式检查
  • cargo clippy passes (if Rust code changed) / 通过 Clippy 检查(如修改了 Rust 代码)
  • Updated i18n files if user-facing text changed / 如修改了用户可见文本,已更新国际化文件

@lehug
Copy link
Copy Markdown
Author

lehug commented Apr 25, 2026

❯ 假如config.yaml中这样配置,model:
default: MiniMax-M2.7
provider: provider1
base_url: https://api.minimaxi.com/v1
custom_providers:

  • name: custom
    base_url: https://ark.cn-beijing.volces.com/api/coding/v3
    api_key: xxx1
    models:
    kimi-k2.6:
    name: kimi-k2.6
    glm-5.1:
    name: glm-5.1
    model: kimi-k2.6
  • name: provider1
    base_url: https://api.minimaxi.com/v1
    api_key: xxx2
    api_mode: anthropic_messages
    models:
    MiniMax-M2.7:
    name: MiniMax M2.7
    model: MiniMax-M2.7 那么 api_key在请求中使用哪个?告诉我代码,说明下具体执行逻辑

● 我需要先理解代码结构,搜索相关的provider和api_key选择逻辑。

Searched for 14 patterns, read 4 files, listed 1 directory (ctrl+o to expand)

● 根据代码分析,当 model.provider: provider1 时,使用的是 custom_providers 中的 api_key: xxx2。

完整执行逻辑

  1. 解析 provider

resolve_runtime_provider → _get_named_custom_provider("provider1")

在 hermes_cli/runtime_provider.py:318-430 中查找逻辑:

1. 先检查 providers: dict(新格式)- 不匹配

providers = config.get("providers") # 用户配置没有这个

2. 查找 custom_providers: list(legacy格式)

custom_providers = get_compatible_custom_providers(config)
for entry in custom_providers:
name_norm = _normalize_custom_provider_name("provider1") # -> "provider1"
menu_key = f"custom:{name_norm}" # -> "custom:provider1"

  # 匹配条件:requested_norm in {name_norm, menu_key, ...}
  # "provider1" in {"provider1", "custom:provider1"} = True

  return {
      "name": "provider1",
      "base_url": "https://api.minimaxi.com/v1",
      "api_key": "xxx2",      # <-- 来自 custom_providers
      "api_mode": "anthropic_messages",
      "model": "MiniMax-M2.7"
  }
  1. 解析运行时凭证

_resolve_named_custom_runtime(hermes_cli/runtime_provider.py:435-484):

api_key_candidates = [
explicit_api_key or "", # None(没有传)
str(custom_provider.get("api_key", "")), # "xxx2" ← 选中
os.getenv(key_env, ""), # key_env 未设置
os.getenv("OPENAI_API_KEY", ""), # 未设置
os.getenv("OPENROUTER_API_KEY", ""), # 未设置
]
api_key = next(candidate for candidate in api_key_candidates
if has_usable_secret(candidate)) # 取第一个有值的 → "xxx2"

  1. 最终请求配置

{
"provider": "custom",
"api_mode": "anthropic_messages", # 来自 custom_providers
"base_url": "https://api.minimaxi.com/v1",
"api_key": "xxx2", # ← 实际使用的 key
"source": "custom_provider:provider1",
"model": "MiniMax-M2.7"
}

关键点

┌──────────────────────────────────┬────────┬───────────────────────────┬─────────────────┐
│ 配置位置 │ 键 │ 值 │ 是否被使用 │
├──────────────────────────────────┼────────┼───────────────────────────┼─────────────────┤
│ model.base_url │ - │ https://api.minimaxi.com/ │ ✅ 用于请求 │
│ │ │ v1 │ │
├──────────────────────────────────┼────────┼───────────────────────────┼─────────────────┤
│ │ │ │ ✅ 用于定位 cus │
│ model.provider │ - │ provider1 │ tom_providers │
│ │ │ │ 条目 │
├──────────────────────────────────┼────────┼───────────────────────────┼─────────────────┤
│ custom_providers[provider1].api_ │ api_ke │ xxx2 │ ✅ 用于认证 │
│ key │ y │ │ │
├──────────────────────────────────┼────────┼───────────────────────────┼─────────────────┤
│ 根级别 provider1 │ api_ke │ xxx1 │ ❌ 未被引用 │
│ │ y │ │ │
└──────────────────────────────────┴────────┴───────────────────────────┴─────────────────┘

结论: 当 model.provider: provider1 时,代码通过 resolve_custom_provider 匹配到 custom_providers
中 name="provider1" 的条目,使用其 api_key: xxx2 和 base_url: https://api.minimaxi.com/v1 进行
API 请求。根级别的 provider1 配置(api_key: xxx1)虽然存在,但在这个流程中没有被使用。

@lehug
Copy link
Copy Markdown
Author

lehug commented Apr 25, 2026

本地验证了, #2301 这个问题 能解决。即使他的provider应该是 mimimax-cn,然后通过.env匹配key。但是因为有provider匹配到了api_key。然后api_key, base_url,model_name都匹配,接口能通

@lehug
Copy link
Copy Markdown
Author

lehug commented Apr 26, 2026

考虑切换的时候,舍弃base_url,但是发现test model这块对于当前使用的,会因为缺失base_url而失败。所以当前这个方案虽然数据多余,但是比舍弃base_url的方案更好

Copy link
Copy Markdown
Owner

@codex review

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9922b66f25

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".


// Extract base_url from new provider's settings if present.
let base_url = settings_config
.get("base_url")
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Handle legacy baseUrl when applying switch defaults

apply_switch_defaults only reads settings_config["base_url"], but this codebase explicitly supports legacy Hermes provider records with camelCase keys (see the sanitizer comments/tests around baseUrl handling). When such a provider is switched to, this branch returns None and falls back to the previous model.base_url, so requests can keep targeting the old provider endpoint even after a successful switch. Consider checking both base_url and baseUrl (or normalizing first) before merging.

Useful? React with 👍 / 👎.

@lehug
Copy link
Copy Markdown
Author

lehug commented Apr 27, 2026

@codex review

@chatgpt-codex-connector
Copy link
Copy Markdown

To use Codex here, create a Codex account and connect to github.

@lehug
Copy link
Copy Markdown
Author

lehug commented Apr 27, 2026

@farion1231 changed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants