fix(agent): consult supports_vision override in auto-mode routing

The contributor PR (#17936) only patched the strip path in
`_model_supports_vision()`. The auto-mode router in
`agent/image_routing._lookup_supports_vision` still only read models.dev,
so a custom-provider model declared as vision-capable would still get its
images routed through vision_analyze in the default `agent.image_input_mode:
auto` setting. Users had to set both `supports_vision: true` AND
`image_input_mode: native` to bypass the text pipeline.

Single-knob behavior now: `supports_vision: true` alone is enough in auto
mode. The strip path and the routing path consult the same resolver.

- Extract override resolution into `_supports_vision_override()` in
  agent/image_routing.py and wire it into `_lookup_supports_vision()`.
- Refactor `run_agent._model_supports_vision` to call the same helper
  (DRY, single source of truth for the resolution order).
- Strict YAML boolean coercion: `supports_vision: "false"` (quoted —
  a common YAML mistake) no longer coerces to True via bool() truthiness.
  Recognised tokens: true/false/yes/no/on/off/1/0 plus real bools and 0/1.
  Unrecognised values return None and fall through to models.dev.
- Add @CNSeniorious000 to AUTHOR_MAP for release attribution.

Tests: 26 new (TestCoerceCapabilityBool, TestSupportsVisionOverride,
TestLookupSupportsVisionOverride, TestAutoModeRespectsOverride). Existing
contributor tests + image_routing + vision_native_fast_path +
native_image_buffer_isolation all green (92/92).
This commit is contained in:
Teknium 2026-05-20 22:59:14 -07:00
parent 1c76689b28
commit 32aea113f0
4 changed files with 263 additions and 23 deletions

View file

@ -3201,7 +3201,7 @@ class AIAgent:
messages (for non-vision models) or let the provider adapter handle
them natively (for vision-capable models).
Resolution order:
Resolution order (see ``agent.image_routing._supports_vision_override``):
1. ``model.supports_vision`` (top-level, single-model shortcut)
2. ``providers.<provider>.models.<model>.supports_vision``
3. models.dev capability lookup
@ -3209,28 +3209,12 @@ class AIAgent:
misclassified as non-vision and have their images stripped.
"""
try:
from hermes_cli.config import cfg_get, load_config
from hermes_cli.config import load_config
from agent.image_routing import _lookup_supports_vision
cfg = load_config()
provider = (getattr(self, "provider", "") or "").strip()
model = (getattr(self, "model", "") or "").strip()
# self.provider is the runtime-resolved value, which is rewritten
# to "custom" for named custom providers (see
# hermes_cli/runtime_provider.py:_resolve_named_custom_runtime),
# while the config still holds the user-declared name (e.g.
# "my-vllm") under model.provider. Try both as provider keys.
config_provider = str(cfg_get(cfg, "model", "provider") or "").strip()
candidates = [("model", "supports_vision")]
for p in dict.fromkeys(filter(None, (provider, config_provider))):
candidates.append(("providers", p, "models", model, "supports_vision"))
for keys in candidates:
override = cfg_get(cfg, *keys)
if override is not None:
return bool(override)
from agent.models_dev import get_model_capabilities
if not provider or not model:
return False
caps = get_model_capabilities(provider, model)
return bool(caps and caps.supports_vision)
return _lookup_supports_vision(provider, model, cfg) is True
except Exception:
return False