Bug Description
When using the openai-api provider with the default base URL https://api.openai.com/v1, Hermes sends additional HTTP GET requests to non‑OpenAI paths on api.openai.com:
- /api/v1/models
- /api/tags
- /v1/props
- /props
- /version
All of these return 404 Not Found (as expected, since they’re not part of the OpenAI API), but they create a lot of noise in egress logs and monitoring.
Why this matters
- In environments with strict monitoring and logging of outbound traffic, these 404s:
- pollute logs,
- can trigger false positives in alerting/IDS rules,
- make it harder to distinguish real issues from harmless probes.
- They also look confusing in service‑mesh dashboards when you see “Hermes hitting /version on api.openai.com with 404s” for no apparent reason.
Steps to Reproduce
Steps to reproduce
-
Configure Hermes with:
model:
provider: openai-api
default: gpt-5.1 # or any OpenAI Chat model
base_url: "https://api.openai.com/v1"
-
Use Hermes via the gateway (Telegram) or CLI to send a few prompts to an OpenAI model (including prompts that attach images, so image routing kicks in).
-
Inspect egress / proxy / mesh logs for api.openai.com.
-
You will see 404s to the following paths, in addition to normal /v1/... traffic:
- GET /api/v1/models
- GET /api/tags
- GET /v1/props
- GET /props
- GET /version
Expected Behavior
- For known public endpoints like https://api.openai.com/v1, Hermes should not attempt Ollama/LM Studio/vLLM/llama.cpp detection via private endpoints like /api/tags, /v1/props, /version.
- Only local or obviously custom endpoints (e.g. localhost, 10.x.x.x, host.docker.internal, user‑provided local URLs) should be probed that way.
Actual Behavior
- Hermes probes those detection endpoints even when base_url is the public OpenAI endpoint.
- This causes regular 404s to non‑existent paths on api.openai.com.
Affected Component
Configuration (config.yaml, .env, hermes setup)
Messaging Platform (if gateway-related)
No response
Debug Report
--- hermes dump ---
version: 0.18.2 [7ecc822e] (2026-07-08)
os: Linux 6.17.0-1011-oracle aarch64
python: 3.11.15
openai_sdk: 2.24.0
profile: default
hermes_home: ~/.hermes
model: gpt-5.1
provider: openai-api
terminal: local
api_keys:
openrouter not set
openai set
anthropic not set
anthropic_token not set
nous not set
google/gemini not set
gemini not set
glm/zai not set
zai not set
kimi not set
minimax not set
deepseek not set
dashscope not set
huggingface not set
nvidia not set
opencode_zen not set
opencode_go not set
kilocode not set
firecrawl not set
tavily not set
browserbase not set
fal not set
elevenlabs not set
github set
features:
toolsets: hermes-cli
mcp_servers: 0
memory_provider: built-in
gateway: running (systemd (system), pid 62619)
platforms: telegram
cron_jobs: 1 active / 1 total
skills: 76
config_overrides:
agent.max_turns: 150
display.streaming: True
display.show_reasoning: False
--- end dump ---
Operating System
ubuntu 24.04
Python Version
No response
Hermes Version
No response
Additional Logs / Traceback (optional)
Example log entries (sanitized):
Method: GET
Host: api.openai.com:443
Path: /version
Status: 404
Matched service: openai
Credential keys: OPENAI_API_KEY
Actor: hermes(agent:...)
Latency: ~130 ms
Similar entries appear for /api/tags, /v1/props, /props, /api/v1/models.
Root Cause Analysis (optional)
Root cause (code walkthrough)
The behavior matches the logic in agent/model_metadata.py::detect_local_server_type
def detect_local_server_type(base_url: str, api_key: str = "") -> Optional[str]:
"""Detect which local server is running at base_url by probing known endpoints.
Returns one of: "ollama", "lm-studio", "vllm", "llamacpp", or None.
"""
import httpx
normalized = _normalize_base_url(base_url)
server_url = normalized
if server_url.endswith("/v1"):
server_url = server_url[:-3]
lmstudio_url = _lmstudio_server_root(base_url)
headers = _auth_headers(api_key)
try:
with httpx.Client(timeout=2.0, headers=headers) as client:
# LM Studio exposes /api/v1/models — check first (most specific)
try:
r = client.get(f"{lmstudio_url}/api/v1/models")
if r.status_code == 200:
return "lm-studio"
except Exception:
pass
# Ollama exposes /api/tags ...
try:
r = client.get(f"{server_url}/api/tags")
...
except Exception:
pass
# llama.cpp exposes /v1/props (older builds used /props)
try:
r = client.get(f"{server_url}/v1/props")
if r.status_code != 200:
r = client.get(f"{server_url}/props")
...
except Exception:
pass
# vLLM: /version
try:
r = client.get(f"{server_url}/version")
...
except Exception:
pass
except Exception:
pass
return None
And this helper is used by:
agent/image_routing.py::_should_probe_ollama_vision (for vision routing):
def _should_probe_ollama_vision(provider: str, base_url: str) -> bool:
p = (provider or "").strip().lower()
if p == "ollama":
return True
if not base_url:
return False
try:
from agent.model_metadata import detect_local_server_type
return detect_local_server_type(base_url) == "ollama"
except Exception:
return False
With provider = "openai-api" and base_url = "https://api.openai.com/v1", detect_local_server_type strips /v1 and probes:
which all 404, as seen in logs.
Functionally it’s harmless, but it produces a lot of noisy 404s against a public API.
Proposed Fix (optional)
One minimal approach:
-
Add a hostname check to detect_local_server_type:
- Normalize the URL.
- Parse hostname via urlparse.
- For known public provider hosts (at least api.openai.com), short‑circuit and return None without doing any probes.
-
Optionally, constrain callers like _should_probe_ollama_vision to only invoke detect_local_server_type for “local‑looking” endpoints (loopback, RFC‑1918, container DNS, etc.).
Example patch (conceptual, based on current code):
from urllib.parse import urlparse
def detect_local_server_type(base_url: str, api_key: str = "") -> Optional[str]:
"""Detect which *local-style* server is running at base_url by probing known endpoints.
Returns one of: "ollama", "lm-studio", "vllm", "llamacpp", or None.
To avoid spamming public SaaS APIs (e.g. api.openai.com) with private
discovery endpoints like `/api/tags` and `/v1/props`, this helper
short-circuits for known public hosts.
"""
import httpx
normalized = _normalize_base_url(base_url)
if not normalized:
return None
try:
url = normalized if "://" in normalized else f"https://{normalized}"
host = urlparse(url).hostname or ""
except Exception:
host = ""
# Do not probe standard public OpenAI endpoints
if host in {"api.openai.com"}:
return None
server_url = normalized
if server_url.endswith("/v1"):
server_url = server_url[:-3]
lmstudio_url = _lmstudio_server_root(base_url)
headers = _auth_headers(api_key)
try:
with httpx.Client(timeout=2.0, headers=headers) as client:
# (existing /api/v1/models, /api/tags, /v1/props, /props, /version probes)
...
except Exception:
pass
return None
This keeps the local‑server detection behavior intact for actual local/custom endpoints, while avoiding pointless 404s against api.openai.com.
Are you willing to submit a PR for this?
Bug Description
When using the openai-api provider with the default base URL https://api.openai.com/v1, Hermes sends additional HTTP GET requests to non‑OpenAI paths on api.openai.com:
All of these return 404 Not Found (as expected, since they’re not part of the OpenAI API), but they create a lot of noise in egress logs and monitoring.
Why this matters
Steps to Reproduce
Steps to reproduce
Configure Hermes with:
model:
provider: openai-api
default: gpt-5.1 # or any OpenAI Chat model
base_url: "https://api.openai.com/v1"
Use Hermes via the gateway (Telegram) or CLI to send a few prompts to an OpenAI model (including prompts that attach images, so image routing kicks in).
Inspect egress / proxy / mesh logs for api.openai.com.
You will see 404s to the following paths, in addition to normal /v1/... traffic:
Expected Behavior
Actual Behavior
Affected Component
Configuration (config.yaml, .env, hermes setup)
Messaging Platform (if gateway-related)
No response
Debug Report
Operating System
ubuntu 24.04
Python Version
No response
Hermes Version
No response
Additional Logs / Traceback (optional)
Root Cause Analysis (optional)
Root cause (code walkthrough)
The behavior matches the logic in
agent/model_metadata.py::detect_local_server_typeAnd this helper is used by:
agent/image_routing.py::_should_probe_ollama_vision (for vision routing):With provider = "openai-api" and base_url = "https://api.openai.com/v1", detect_local_server_type strips /v1 and probes:
which all 404, as seen in logs.
Functionally it’s harmless, but it produces a lot of noisy 404s against a public API.
Proposed Fix (optional)
One minimal approach:
Add a hostname check to detect_local_server_type:
Optionally, constrain callers like _should_probe_ollama_vision to only invoke detect_local_server_type for “local‑looking” endpoints (loopback, RFC‑1918, container DNS, etc.).
Example patch (conceptual, based on current code):
This keeps the local‑server detection behavior intact for actual local/custom endpoints, while avoiding pointless 404s against api.openai.com.
Are you willing to submit a PR for this?