Migrate 18 Hermes provider presets from anthropic_messages to
chat_completions to sidestep known upstream Hermes bugs (model-name
dot-mangling in normalize_model_name, api_mode drop after v11->v12
migration, and auxiliary_client OpenAI hardcode).
Native providers now target each vendor's official OpenAI-compatible
endpoint with correct model IDs: Kimi (kimi-k2.5-preview on /v1),
Bailian (compatible-mode/v1 with Qwen3 defaults), Xiaomi MiMo, Longcat
(/openai/v1), Zhipu GLM (/api/paas/v4), ModelScope, MiniMax, SiliconFlow,
and Novita (/v3/openai).
Aggregators (Shengsuanyun, AiHubMix, DMXAPI, Compshare, TheRouter)
default to GPT-5.4 on chat_completions, mirroring the Codex preset
lineup. TheRouter omits gpt-5.4-pro since that variant is Responses-only
and Hermes implements only chat_completions. OpenRouter's existing
openai/gpt-5 entry is bumped to openai/gpt-5.4.
Claude-only proxies are left on anthropic_messages; their Codex
counterparts use wire_api=responses, so there is no evidence their
chat_completions endpoints serve OpenAI models.
Remove the Anthropic, OpenAI, and Google AI presets from the Hermes
preset list. They were placeholder samples introduced when the Hermes
module first landed and do not match the actual user paths in
CC Switch (Claude / Codex go through OAuth, Gemini Native is its own
adapter), and the upstream endpoints are not reachable for most of
the target users anyway.
Fix the Nous Research preset: its base_url was a fabricated domain
(inference.nous.hermes.dev) that has never resolved. Point it at the
real Nous Portal endpoint (inference-api.nousresearch.com/v1) and
add apiKeyUrl so users can jump straight to portal.nousresearch.com
to provision a key.
Drop the now-orphan providerForm.presets.{anthropic,openai,googleai}
i18n keys from zh / en / ja since no preset references them anymore.
Import 38 Claude presets into Hermes by mapping env-style
ANTHROPIC_BASE_URL/AUTH_TOKEN to flat base_url/api_key, deriving
api_mode from apiFormat (anthropic_messages or chat_completions),
deduping ANTHROPIC_*_MODEL into models[], and pointing
suggestedDefaults at ANTHROPIC_MODEL. Skip OAuth-only presets
(Codex, Copilot), Bedrock SigV4, Gemini Native, and the three
already shipped on the Hermes side (OpenRouter, Anthropic,
DeepSeek). Place Shengsuanyun at the head of the Hermes array so
the partner shows first in the preset panel.
In the Claude preset list, restore Shengsuanyun back ahead of
Gemini Native. The Gemini Native preset (#1918) was inserted
between Claude Official and Shengsuanyun, which made the
third_party category register first in the reduce-based grouping
and pushed the aggregator block (and Shengsuanyun) behind it.
Backfill the missing providerForm.presets translations across zh,
en, and ja (openrouter, anthropic, openai, googleai, deepseek,
together; plus shengsuanyun for en and ja) so existing Hermes
preset names no longer render literal i18n keys.
The Hermes provider form previously only exposed Base URL and API Key,
forcing users to drop into the Model panel to hand-edit model IDs after
adding a provider. Following OpenClaw's shape, the form now carries:
- An API Mode selector (auto-detect / chat_completions / anthropic_messages).
"auto" is a UI-only sentinel — selecting it deletes api_mode from the
config so the YAML doesn't leak a redundant field.
- A model list editor where the first row is badged as the default and
each row has a collapsible Advanced panel for context_length and
max_tokens. Adding/removing rows uses a UUID-keyed ref so typing in
one input doesn't drop focus when another row is added.
- A Fetch Models button that pulls /v1/models from the configured
endpoint and exposes the catalog in a per-row dropdown, identical to
OpenClaw's flow. The vendor grouping is memoized so keystrokes don't
trigger a reduce+sort per model row — Radix DropdownMenuContent does
not lazy-mount, so the inner JSX evaluates on every render regardless
of whether the menu is open.
Three-locale i18n keys are added together (zh/en/ja).
Hermes custom_providers entries now carry an ordered models array
(id / context_length / max_tokens) plus suggestedDefaults. The backend
serializes the array to the YAML dict shape Hermes expects on write and
inverts it on read, preserving insertion order via the preserve_order
feature on serde_json.
When a user switches providers, switch_normal calls apply_switch_defaults
so the top-level model.default / model.provider follow the selected
provider's first model. Previously switching a Hermes provider only
shuffled custom_providers[] and left Hermes pointing at whatever
model.provider was set before.
Seven existing Hermes presets now ship with a curated models list so
switching lands on a working default without a detour through the
Model panel.