From 1481fb80ac2cc32a6a47d393296161d8f2ea8957 Mon Sep 17 00:00:00 2001 From: mousamax Date: Sun, 9 Aug 2026 18:22:29 +0200 Subject: [PATCH] fix(providers): mark image-capable OpenRouter models as vision-capable --- coworker/providers/matrix.py | 16 +++++++++++++--- tests/test_providers.py | 13 +++++++++++++ 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/coworker/providers/matrix.py b/coworker/providers/matrix.py index 052a19ff0..2420530db 100644 --- a/coworker/providers/matrix.py +++ b/coworker/providers/matrix.py @@ -211,16 +211,26 @@ class ModelEntry: "Llama 4 Maverick · via Fireworks", _AGENTIC, 1_000_000 ), # OpenRouter slugs are lowercase `/` (checked against their catalog - # 2026-07-25); same labs as above, one key for all of them. + # 2026-07-25); same labs as above, one key for all of them. Kimi K2.6 and Llama 4 + # Maverick declare image input (architecture.input_modalities, 2026-08-09); PDFs + # unverified over the compat surface, like Kimi K3 above. "openrouter:z-ai/glm-5.2": ModelEntry("GLM-5.2 · via OpenRouter", _AGENTIC, 128_000), "openrouter:moonshotai/kimi-k2.6": ModelEntry( - "Kimi K2.6 · via OpenRouter", _AGENTIC, 256_000 + "Kimi K2.6 · via OpenRouter", + ModelCapabilities( + tools=True, vision=True, parallel_tool_calls=True, streaming=True + ), + 256_000, ), "openrouter:deepseek/deepseek-v4-pro": ModelEntry( "DeepSeek V4 Pro · via OpenRouter", _AGENTIC, 128_000 ), "openrouter:meta-llama/llama-4-maverick": ModelEntry( - "Llama 4 Maverick · via OpenRouter", _AGENTIC, 1_000_000 + "Llama 4 Maverick · via OpenRouter", + ModelCapabilities( + tools=True, vision=True, parallel_tool_calls=True, streaming=True + ), + 1_000_000, ), # Stealth/cloaked alpha (catalog-checked 2026-08-24: 1,048,576 ctx, tool calling). # These are temporary lab previews — expect the slug to vanish when the lab ships diff --git a/tests/test_providers.py b/tests/test_providers.py index 99df73c3d..b0169544b 100644 --- a/tests/test_providers.py +++ b/tests/test_providers.py @@ -503,6 +503,19 @@ def test_matrix_answers_capabilities_for_reseller_ids(): assert caps.tools and caps.parallel_tool_calls and caps.streaming +def test_openrouter_vision_matches_declared_input_modalities(): + """Vision must track what OpenRouter declares per model, or the engine swaps in its + non-vision placeholder and the image never reaches a model that can read it.""" + for mid in ( + "openrouter:moonshotai/kimi-k2.6", + "openrouter:meta-llama/llama-4-maverick", + ): + caps = capabilities_for(mid) + assert caps.vision and not caps.pdf, mid + for mid in ("openrouter:z-ai/glm-5.2", "openrouter:deepseek/deepseek-v4-pro"): + assert not capabilities_for(mid).vision, mid + + def test_matrix_labels_and_custom_model_fallback(): from coworker.providers.matrix import MATRIX, model_labels