docs(image-routing): stop claiming the reverted provider-wide supports_vision probe

_lookup_supports_vision and _accepts_tool_result_images still documented a
ProviderProfile.supports_vision probe that 08feaa98b5 deliberately removed.
That stale docstring led triage (claude-subscription-directsdk#67) to
propose re-adding it. Document the actual contract: the provider-wide flag
gates tool-result media only; per-model attachment vision comes from
ProviderProfile.model_capabilities via the catalog probe.

Add a guard test pinning that contract so the probe is not resurrected.
This commit is contained in:
Teknium
2026-10-04 17:26:53 -07:00
parent f304cf4a7d
commit 4cfffca7cd
3 changed files with 26 additions and 4 deletions

View File

@@ -337,8 +337,12 @@ def _lookup_supports_vision(
"""Return True/False if vision capability can be resolved, None if unknown.
Order: config ``supports_vision`` override → :data:`_VISION_PROBES`
(managed local runtime → models.dev catalog → Ollama probe → registered
``ProviderProfile.supports_vision`` declaration).
(managed local runtime → models.dev catalog → Ollama probe). A plugin's
per-model ``ProviderProfile.model_capabilities`` reaches this through the
catalog probe. The provider-wide ``ProviderProfile.supports_vision`` flag is
deliberately NOT consulted: it declares that tool-result messages may carry
images (``tools.vision_tools``), not that every model on the provider can see
user attachments — relays such as ``router`` set it for mixed catalogs.
"""
# Named custom providers are canonicalized to ``provider="custom"``; the
# original name lives in the context-local main runtime. Borrow it only on an

View File

@@ -72,3 +72,21 @@ def test_partial_plugin_metadata_preserves_unknowns_and_catalog_fields(monkeypat
assert unknown.context_window == 48000
assert unknown.supports_reasoning is None and unknown.supports_vision is None
assert catalog == original
def test_provider_wide_vision_flag_gates_tool_results_not_attachments(monkeypatch):
"""``ProviderProfile.supports_vision`` is a provider-wide tool-result wire capability; per-model attachment
routing comes only from ``model_capabilities``. Relays (``router``) set the flag over mixed catalogs, so
honouring it for attachments sent images to text-only models (reverted in 08feaa98b5b)."""
from agent.image_routing import decide_image_input_mode
from tools.vision_tools import _supports_media_in_tool_results
_isolated_registry(monkeypatch)
monkeypatch.setattr(models_dev, "_load_model_overrides", lambda: {})
providers.register_provider(ProviderProfile(
name="fixture-relay", supports_vision=True,
model_capabilities={"seeing": {"supports_vision": True}}))
assert _supports_media_in_tool_results("fixture-relay", "undeclared") is True
assert decide_image_input_mode("fixture-relay", "undeclared", {}) == "text"
assert decide_image_input_mode("fixture-relay", "seeing", {}) == "native"

View File

@@ -559,8 +559,8 @@ def _supports_media_in_tool_results(provider: str, model: str) -> bool:
def _accepts_tool_result_images(provider: str, model: str, cfg: Optional[Dict[str, Any]]) -> bool:
"""One gate for both native lanes — the ``vision_analyze`` fast path and the ``computer_use`` capture route
(#115248): the profile's ``supports_vision_tool_messages=False`` veto first, then either the provider's tool
results are known to carry media or the capability lookup (config override → catalog → probes → profile)
attests the model as vision-capable."""
results are known to carry media or the per-model capability lookup (config override → catalog incl. the
profile's ``model_capabilities`` → local probes) attests the model as vision-capable."""
if _profile_rejects_tool_media(provider, model):
return False
if _supports_media_in_tool_results(provider, model):