feat(runinfra): add Ornith 1.5 35B and declare image input on the two vision models

Ornith 1.5 35B A3B went public on RunInfra after this PR was opened, so the
cost map advertised five of our six conversational models and LiteLLM users
could not route to the sixth at all. Prices are read from the production row
and match the published rates: $0.10/M input, $0.40/M output, $0.01/M cached.

Also declares supports_vision on the two models that accept image input,
Qwen3.8 27B and Ornith. Both accept image_url and input_image content parts on
the live gateway; the other four are text-only and stay unflagged. Without it
a user filtering LiteLLM for vision-capable providers sees neither.

Every value traces to a primary source: the production model row for prices
and capabilities, and the public model page named in each entry's `source`.
No capability is copied from a sibling entry.

The per-model test table gains Ornith, plus a vision table that asserts the
flag on exactly the two proven models and its ABSENCE on the other four, so a
flag copied onto a text-only model fails rather than passing quietly. Verified
by flipping Ornith's flag to false and watching test_runinfra_model_cost_map
fail, then restoring it.

Both price JSONs stay byte-identical, confirmed on the staged content.
tests/test_litellm/llms/openai_like/test_json_providers.py: 24 passed, 4 skipped.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
jaberjaber23 2026-08-23 04:42:54 +03:00
parent 2afae67225
commit 404609ccc4
3 changed files with 59 additions and 2 deletions

View file

@ -49944,7 +49944,8 @@
"supports_prompt_caching": true,
"supports_reasoning": true,
"supports_response_schema": true,
"supports_tool_choice": true
"supports_tool_choice": true,
"supports_vision": true
},
"runinfra/deepseek-ai/DeepSeek-V4-Flash-0731": {
"cache_read_input_token_cost": 1e-08,
@ -50004,6 +50005,27 @@
"supports_response_schema": true,
"supports_tool_choice": true
},
"runinfra/ornith-ai/Ornith-1.5-35B-A3B": {
"cache_read_input_token_cost": 1e-08,
"input_cost_per_token": 1e-07,
"litellm_provider": "runinfra",
"max_input_tokens": 262144,
"max_output_tokens": 32768,
"max_tokens": 32768,
"mode": "chat",
"output_cost_per_token": 4e-07,
"source": "https://runinfra.ai/inference-api/ornith-1-5-35b",
"supported_endpoints": [
"/v1/chat/completions"
],
"supports_function_calling": true,
"supports_native_streaming": true,
"supports_prompt_caching": true,
"supports_reasoning": true,
"supports_response_schema": true,
"supports_tool_choice": true,
"supports_vision": true
},
"xai/grok-4.20-0309-non-reasoning": {
"cache_read_input_token_cost": 2e-07,
"input_cost_per_token": 1.25e-06,

View file

@ -49944,7 +49944,8 @@
"supports_prompt_caching": true,
"supports_reasoning": true,
"supports_response_schema": true,
"supports_tool_choice": true
"supports_tool_choice": true,
"supports_vision": true
},
"runinfra/deepseek-ai/DeepSeek-V4-Flash-0731": {
"cache_read_input_token_cost": 1e-08,
@ -50004,6 +50005,27 @@
"supports_response_schema": true,
"supports_tool_choice": true
},
"runinfra/ornith-ai/Ornith-1.5-35B-A3B": {
"cache_read_input_token_cost": 1e-08,
"input_cost_per_token": 1e-07,
"litellm_provider": "runinfra",
"max_input_tokens": 262144,
"max_output_tokens": 32768,
"max_tokens": 32768,
"mode": "chat",
"output_cost_per_token": 4e-07,
"source": "https://runinfra.ai/inference-api/ornith-1-5-35b",
"supported_endpoints": [
"/v1/chat/completions"
],
"supports_function_calling": true,
"supports_native_streaming": true,
"supports_prompt_caching": true,
"supports_reasoning": true,
"supports_response_schema": true,
"supports_tool_choice": true,
"supports_vision": true
},
"xai/grok-4.20-0309-non-reasoning": {
"cache_read_input_token_cost": 2e-07,
"input_cost_per_token": 1.25e-06,

View file

@ -427,6 +427,7 @@ class TestRuninfra:
),
"runinfra/Inferact/Qwen3.8-2.4T-A95B-NVFP4": (2e-06, 6e-06, 2e-07),
"runinfra/Qwen/Qwen3.8-27B": (1e-07, 4e-07, 1e-08),
"runinfra/ornith-ai/Ornith-1.5-35B-A3B": (1e-07, 4e-07, 1e-08),
}
for model, (input_cost, output_cost, cache_read_cost) in expected_models.items():
assert model in model_cost
@ -449,6 +450,18 @@ class TestRuninfra:
assert model_cost["runinfra/Qwen/Qwen3.8-27B"]["max_input_tokens"] == 262144
assert model_cost["runinfra/Inferact/Qwen3.8-2.4T-A95B-NVFP4"]["supports_response_schema"] is True
assert model_cost["runinfra/Qwen/Qwen3.8-27B"]["supports_response_schema"] is True
assert model_cost["runinfra/ornith-ai/Ornith-1.5-35B-A3B"]["max_input_tokens"] == 262144
# Image input is proven on exactly these two and declared on no other,
# so a copied flag on a text-only model reddens here.
for model, expected_vision in (
("runinfra/Qwen/Qwen3.8-27B", True),
("runinfra/ornith-ai/Ornith-1.5-35B-A3B", True),
("runinfra/deepseek-ai/DeepSeek-V4-Flash-0731", False),
("runinfra/deepseek-ai/DeepSeek-V4-Pro-0813", False),
("runinfra/nvidia/NVIDIA-Nemotron-3.5-Lightning-30B-A3B-BF16", False),
("runinfra/Inferact/Qwen3.8-2.4T-A95B-NVFP4", False),
):
assert model_cost[model].get("supports_vision", False) is expected_vision
class TestPublicAIIntegration: