The install.sh "OpenAI bridge" block bundled two distinct concerns under
one guard:
1. Auto-fill HERMES_CUSTOM_{BASE_URL,API_KEY,API_MODE} when operator
didn't set them
2. Strip the openai/ prefix from DEFAULT_MODEL (OpenAI rejects prefixed
model IDs with 400 "invalid model ID")
Both only fired when the operator had NOT pre-configured HERMES_CUSTOM_*.
That broke molecule-core#1987: the staging E2E now pins HERMES_CUSTOM_*
explicitly (to work around derive-provider.sh's #19 fix not reaching all
tenants). The pin skipped concern (1) intentionally — but also skipped
(2) unintentionally. Result: E2E routes to api.openai.com with the wrong
model name and hits 400.
Fix: separate the two concerns.
- (A) Auto-fill block keeps its original guard — runs only when operator
didn't configure.
- (B) New independent block: strip openai/ iff the FINAL
HERMES_CUSTOM_BASE_URL matches api.openai.com. Regex is anchored
(^https?://api\.openai\.com(/|$)) so lookalike domains
(api.openai.com.evil.internal, beta.api.openai.com) do NOT match.
Idempotent on already-bare model names.
Verified via scripts/test-install-prefix-strip.sh — 10 cases including:
A default bridge strips openai/ → gpt-4o
B operator-pinned OpenAI URL also strips → gpt-4o (#1987 path, was broken)
C vLLM URL keeps prefix → openai/my-finetune
D openrouter keeps prefix → openai/gpt-4o
E minimax untouched → minimax/MiniMax-M2.7
G lookalike domain NOT stripped → openai/gpt-4o (anti-spoofing)
H http://api.openai.com also strips → gpt-4o
I subdomain beta.api.openai.com NOT strip → openai/gpt-4o
All 10 pass. Plus a parity check greps install.sh to ensure the inlined
logic matches what ships.
No behavioral change for any existing working config (scenarios A, C, D,
E, F above — all unchanged). Only fixes the broken scenario B.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>