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:
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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):
|
||||
|
||||
Reference in New Issue
Block a user