hermes - 💡(How to fix) Fix Bug: supports_vision override ignores stripped named custom provider key [4 pull requests]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…

For a named custom provider configured as model.provider: custom:<name>, native image routing does not honor providers.<name>.models.<model>.supports_vision: true.

Hermes resolves the runtime provider to custom, and agent.image_routing._supports_vision_override() tries:

  • the runtime provider key, e.g. custom
  • the raw model.provider value, e.g. custom:litellm

It does not try the stripped named provider key, e.g. litellm, even though that is where the provider is defined in providers:.

Root Cause

For a named custom provider configured as model.provider: custom:<name>, native image routing does not honor providers.<name>.models.<model>.supports_vision: true.

Hermes resolves the runtime provider to custom, and agent.image_routing._supports_vision_override() tries:

  • the runtime provider key, e.g. custom
  • the raw model.provider value, e.g. custom:litellm

It does not try the stripped named provider key, e.g. litellm, even though that is where the provider is defined in providers:.

Fix Action

Fixed

Code Example

agent:
  image_input_mode: auto

model:
  default: gpt-5.5
  provider: custom:my-proxy

providers:
  my-proxy:
    api_mode: chat_completions
    base_url: https://proxy.example.com/v1
    key_env: OPENAI_API_KEY
    model: gpt-5.5
    models:
      gpt-5.5:
        supports_vision: true

auxiliary:
  vision:
    provider: auto
    model: ''
    base_url: ''

---

from hermes_cli.config import load_config
from gateway.run import _resolve_runtime_agent_kwargs, _resolve_gateway_model
from agent.image_routing import _lookup_supports_vision, decide_image_input_mode

cfg = load_config()
kwargs = _resolve_runtime_agent_kwargs()
provider = kwargs["provider"]      # "custom"
model = _resolve_gateway_model()    # "gpt-5.5"
print(_lookup_supports_vision(provider, model, cfg))
print(decide_image_input_mode(provider, model, cfg))

---

None
text

---

model:
  supports_vision: true

---

providers:
  custom:
    models:
      gpt-5.5:
        supports_vision: true

---

No LLM provider configured for task=vision provider=auto. Run: hermes setup
RAW_BUFFERClick to expand / collapse

Summary

For a named custom provider configured as model.provider: custom:<name>, native image routing does not honor providers.<name>.models.<model>.supports_vision: true.

Hermes resolves the runtime provider to custom, and agent.image_routing._supports_vision_override() tries:

  • the runtime provider key, e.g. custom
  • the raw model.provider value, e.g. custom:litellm

It does not try the stripped named provider key, e.g. litellm, even though that is where the provider is defined in providers:.

Reproduction

Config shape:

agent:
  image_input_mode: auto

model:
  default: gpt-5.5
  provider: custom:my-proxy

providers:
  my-proxy:
    api_mode: chat_completions
    base_url: https://proxy.example.com/v1
    key_env: OPENAI_API_KEY
    model: gpt-5.5
    models:
      gpt-5.5:
        supports_vision: true

auxiliary:
  vision:
    provider: auto
    model: ''
    base_url: ''

Observed with a direct router probe:

from hermes_cli.config import load_config
from gateway.run import _resolve_runtime_agent_kwargs, _resolve_gateway_model
from agent.image_routing import _lookup_supports_vision, decide_image_input_mode

cfg = load_config()
kwargs = _resolve_runtime_agent_kwargs()
provider = kwargs["provider"]      # "custom"
model = _resolve_gateway_model()    # "gpt-5.5"
print(_lookup_supports_vision(provider, model, cfg))
print(decide_image_input_mode(provider, model, cfg))

Actual:

None
text

If I place the same override under either of these locations, routing flips to native:

model:
  supports_vision: true

or

providers:
  custom:
    models:
      gpt-5.5:
        supports_vision: true

So this appears to be specifically the missing custom:<name> -> <name> candidate in _supports_vision_override().

Impact

When image_input_mode: auto is used with a vision-capable model behind a named custom OpenAI-compatible proxy, Hermes falls back to the text pipeline and calls vision_analyze instead of passing image content to the main model natively. If auxiliary vision is not configured, image turns fail with:

No LLM provider configured for task=vision provider=auto. Run: hermes setup

Even when the proxied main model handles the same image_url payload correctly via direct /v1/chat/completions.

Expected behavior

For model.provider: custom:my-proxy, _supports_vision_override() should also check providers.my-proxy.models.<model>.supports_vision.

A minimal fix might be to add the stripped suffix from custom:<name> to the provider-key candidates before falling back to models.dev.

Related issues

This is related to the broader custom-provider capability work in #8731, but narrower: Hermes already has a supports_vision override path; the named custom provider key is just not included in the lookup candidates.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

FAQ

Expected behavior

For model.provider: custom:my-proxy, _supports_vision_override() should also check providers.my-proxy.models.<model>.supports_vision.

A minimal fix might be to add the stripped suffix from custom:<name> to the provider-key candidates before falling back to models.dev.

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING