[Feature] Add supports_computer_use to the model list (#10881)

* Add support for supports_computer_use in model info

* Corrected list of supports_computer_use models

* Further fix computer use compatible claude models, fix existing test that predated supports_computer_use in the model list

* Move computer use test case into existing test_utils file

* Moved tests in to test_utils.py
This commit is contained in:
slytechnical
2025-05-20 17:07:43 -07:00
committed by GitHub
parent 058503ea11
commit 98e9db340c
6 changed files with 127 additions and 3 deletions
@@ -4625,6 +4625,7 @@
"supports_tool_choice": true
},
"claude-3-5-sonnet-latest": {
"supports_computer_use": true,
"max_tokens": 8192,
"max_input_tokens": 200000,
"max_output_tokens": 8192,
@@ -4671,6 +4672,7 @@
"supports_tool_choice": true
},
"claude-3-7-sonnet-latest": {
"supports_computer_use": true,
"max_tokens": 128000,
"max_input_tokens": 200000,
"max_output_tokens": 128000,
@@ -4697,6 +4699,7 @@
"supports_reasoning": true
},
"claude-3-7-sonnet-20250219": {
"supports_computer_use": true,
"max_tokens": 128000,
"max_input_tokens": 200000,
"max_output_tokens": 128000,
@@ -4724,6 +4727,7 @@
"supports_web_search": true
},
"claude-3-5-sonnet-20241022": {
"supports_computer_use": true,
"max_tokens": 8192,
"max_input_tokens": 200000,
"max_output_tokens": 8192,
@@ -6458,6 +6462,7 @@
"supports_tool_choice": true
},
"vertex_ai/claude-3-5-sonnet": {
"supports_computer_use": true,
"max_tokens": 8192,
"max_input_tokens": 200000,
"max_output_tokens": 8192,
@@ -6486,6 +6491,7 @@
"supports_tool_choice": true
},
"vertex_ai/claude-3-5-sonnet-v2": {
"supports_computer_use": true,
"max_tokens": 8192,
"max_input_tokens": 200000,
"max_output_tokens": 8192,
@@ -6500,6 +6506,7 @@
"supports_tool_choice": true
},
"vertex_ai/claude-3-5-sonnet-v2@20241022": {
"supports_computer_use": true,
"max_tokens": 8192,
"max_input_tokens": 200000,
"max_output_tokens": 8192,
@@ -6514,6 +6521,7 @@
"supports_tool_choice": true
},
"vertex_ai/claude-3-7-sonnet@20250219": {
"supports_computer_use": true,
"max_tokens": 8192,
"max_input_tokens": 200000,
"max_output_tokens": 8192,
@@ -8055,6 +8063,7 @@
"supports_tool_choice": true
},
"openrouter/anthropic/claude-3.5-sonnet": {
"supports_computer_use": true,
"max_tokens": 8192,
"max_input_tokens": 200000,
"max_output_tokens": 8192,
@@ -8069,6 +8078,7 @@
"supports_tool_choice": true
},
"openrouter/anthropic/claude-3.5-sonnet:beta": {
"supports_computer_use": true,
"max_tokens": 8192,
"max_input_tokens": 200000,
"max_output_tokens": 8192,
@@ -8082,6 +8092,7 @@
"supports_tool_choice": true
},
"openrouter/anthropic/claude-3.7-sonnet": {
"supports_computer_use": true,
"max_tokens": 8192,
"max_input_tokens": 200000,
"max_output_tokens": 8192,
@@ -8098,6 +8109,7 @@
"supports_tool_choice": true
},
"openrouter/anthropic/claude-3.7-sonnet:beta": {
"supports_computer_use": true,
"max_tokens": 8192,
"max_input_tokens": 200000,
"max_output_tokens": 8192,
@@ -9110,6 +9122,7 @@
"supports_tool_choice": true
},
"anthropic.claude-3-7-sonnet-20250219-v1:0": {
"supports_computer_use": true,
"max_tokens": 8192,
"max_input_tokens": 200000,
"max_output_tokens": 8192,
@@ -9129,6 +9142,7 @@
"supports_tool_choice": true
},
"anthropic.claude-3-5-sonnet-20241022-v2:0": {
"supports_computer_use": true,
"max_tokens": 8192,
"max_input_tokens": 200000,
"max_output_tokens": 8192,
@@ -9219,6 +9233,7 @@
"supports_tool_choice": true
},
"us.anthropic.claude-3-5-sonnet-20241022-v2:0": {
"supports_computer_use": true,
"max_tokens": 8192,
"max_input_tokens": 200000,
"max_output_tokens": 8192,
@@ -9237,6 +9252,7 @@
"supports_tool_choice": true
},
"us.anthropic.claude-3-7-sonnet-20250219-v1:0": {
"supports_computer_use": true,
"max_tokens": 8192,
"max_input_tokens": 200000,
"max_output_tokens": 8192,
@@ -9328,6 +9344,7 @@
"supports_tool_choice": true
},
"eu.anthropic.claude-3-5-sonnet-20241022-v2:0": {
"supports_computer_use": true,
"max_tokens": 8192,
"max_input_tokens": 200000,
"max_output_tokens": 8192,
@@ -9344,6 +9361,7 @@
"supports_tool_choice": true
},
"eu.anthropic.claude-3-7-sonnet-20250219-v1:0": {
"supports_computer_use": true,
"max_tokens": 8192,
"max_input_tokens": 200000,
"max_output_tokens": 8192,
@@ -12434,6 +12452,7 @@
"mode": "chat"
},
"snowflake/claude-3-5-sonnet": {
"supports_computer_use": true,
"max_tokens": 18000,
"max_input_tokens": 18000,
"max_output_tokens": 8192,
@@ -12746,4 +12765,4 @@
"litellm_provider": "featherless_ai",
"mode": "chat"
}
}
}
+1
View File
@@ -111,6 +111,7 @@ class ProviderSpecificModelInfo(TypedDict, total=False):
supports_tool_choice: Optional[bool]
supports_assistant_prefill: Optional[bool]
supports_prompt_caching: Optional[bool]
supports_computer_use: Optional[bool]
supports_audio_input: Optional[bool]
supports_embedding_image_input: Optional[bool]
supports_audio_output: Optional[bool]
+24
View File
@@ -1967,6 +1967,28 @@ def supports_prompt_caching(
key="supports_prompt_caching",
)
def supports_computer_use(
model: str, custom_llm_provider: Optional[str] = None
) -> bool:
"""
Check if the given model supports computer use and return a boolean value.
Parameters:
model (str): The model name to be checked.
custom_llm_provider (Optional[str]): The provider to be checked.
Returns:
bool: True if the model supports computer use, False otherwise.
Raises:
Exception: If the given model is not found or there's an error in retrieval.
"""
return _supports_factory(
model=model,
custom_llm_provider=custom_llm_provider,
key="supports_computer_use",
)
def supports_vision(model: str, custom_llm_provider: Optional[str] = None) -> bool:
"""
@@ -4271,6 +4293,7 @@ def _get_model_info_helper( # noqa: PLR0915
supports_tool_choice=None,
supports_assistant_prefill=None,
supports_prompt_caching=None,
supports_computer_use=None,
supports_pdf_input=None,
)
elif (
@@ -4444,6 +4467,7 @@ def _get_model_info_helper( # noqa: PLR0915
),
supports_web_search=_model_info.get("supports_web_search", False),
supports_reasoning=_model_info.get("supports_reasoning", False),
supports_computer_use=_model_info.get("supports_computer_use", False),
search_context_cost_per_query=_model_info.get(
"search_context_cost_per_query", None
),
+20 -1
View File
@@ -4625,6 +4625,7 @@
"supports_tool_choice": true
},
"claude-3-5-sonnet-latest": {
"supports_computer_use": true,
"max_tokens": 8192,
"max_input_tokens": 200000,
"max_output_tokens": 8192,
@@ -4671,6 +4672,7 @@
"supports_tool_choice": true
},
"claude-3-7-sonnet-latest": {
"supports_computer_use": true,
"max_tokens": 128000,
"max_input_tokens": 200000,
"max_output_tokens": 128000,
@@ -4697,6 +4699,7 @@
"supports_reasoning": true
},
"claude-3-7-sonnet-20250219": {
"supports_computer_use": true,
"max_tokens": 128000,
"max_input_tokens": 200000,
"max_output_tokens": 128000,
@@ -4724,6 +4727,7 @@
"supports_web_search": true
},
"claude-3-5-sonnet-20241022": {
"supports_computer_use": true,
"max_tokens": 8192,
"max_input_tokens": 200000,
"max_output_tokens": 8192,
@@ -6458,6 +6462,7 @@
"supports_tool_choice": true
},
"vertex_ai/claude-3-5-sonnet": {
"supports_computer_use": true,
"max_tokens": 8192,
"max_input_tokens": 200000,
"max_output_tokens": 8192,
@@ -6486,6 +6491,7 @@
"supports_tool_choice": true
},
"vertex_ai/claude-3-5-sonnet-v2": {
"supports_computer_use": true,
"max_tokens": 8192,
"max_input_tokens": 200000,
"max_output_tokens": 8192,
@@ -6500,6 +6506,7 @@
"supports_tool_choice": true
},
"vertex_ai/claude-3-5-sonnet-v2@20241022": {
"supports_computer_use": true,
"max_tokens": 8192,
"max_input_tokens": 200000,
"max_output_tokens": 8192,
@@ -6514,6 +6521,7 @@
"supports_tool_choice": true
},
"vertex_ai/claude-3-7-sonnet@20250219": {
"supports_computer_use": true,
"max_tokens": 8192,
"max_input_tokens": 200000,
"max_output_tokens": 8192,
@@ -8055,6 +8063,7 @@
"supports_tool_choice": true
},
"openrouter/anthropic/claude-3.5-sonnet": {
"supports_computer_use": true,
"max_tokens": 8192,
"max_input_tokens": 200000,
"max_output_tokens": 8192,
@@ -8069,6 +8078,7 @@
"supports_tool_choice": true
},
"openrouter/anthropic/claude-3.5-sonnet:beta": {
"supports_computer_use": true,
"max_tokens": 8192,
"max_input_tokens": 200000,
"max_output_tokens": 8192,
@@ -8082,6 +8092,7 @@
"supports_tool_choice": true
},
"openrouter/anthropic/claude-3.7-sonnet": {
"supports_computer_use": true,
"max_tokens": 8192,
"max_input_tokens": 200000,
"max_output_tokens": 8192,
@@ -8098,6 +8109,7 @@
"supports_tool_choice": true
},
"openrouter/anthropic/claude-3.7-sonnet:beta": {
"supports_computer_use": true,
"max_tokens": 8192,
"max_input_tokens": 200000,
"max_output_tokens": 8192,
@@ -9110,6 +9122,7 @@
"supports_tool_choice": true
},
"anthropic.claude-3-7-sonnet-20250219-v1:0": {
"supports_computer_use": true,
"max_tokens": 8192,
"max_input_tokens": 200000,
"max_output_tokens": 8192,
@@ -9129,6 +9142,7 @@
"supports_tool_choice": true
},
"anthropic.claude-3-5-sonnet-20241022-v2:0": {
"supports_computer_use": true,
"max_tokens": 8192,
"max_input_tokens": 200000,
"max_output_tokens": 8192,
@@ -9219,6 +9233,7 @@
"supports_tool_choice": true
},
"us.anthropic.claude-3-5-sonnet-20241022-v2:0": {
"supports_computer_use": true,
"max_tokens": 8192,
"max_input_tokens": 200000,
"max_output_tokens": 8192,
@@ -9237,6 +9252,7 @@
"supports_tool_choice": true
},
"us.anthropic.claude-3-7-sonnet-20250219-v1:0": {
"supports_computer_use": true,
"max_tokens": 8192,
"max_input_tokens": 200000,
"max_output_tokens": 8192,
@@ -9328,6 +9344,7 @@
"supports_tool_choice": true
},
"eu.anthropic.claude-3-5-sonnet-20241022-v2:0": {
"supports_computer_use": true,
"max_tokens": 8192,
"max_input_tokens": 200000,
"max_output_tokens": 8192,
@@ -9344,6 +9361,7 @@
"supports_tool_choice": true
},
"eu.anthropic.claude-3-7-sonnet-20250219-v1:0": {
"supports_computer_use": true,
"max_tokens": 8192,
"max_input_tokens": 200000,
"max_output_tokens": 8192,
@@ -12434,6 +12452,7 @@
"mode": "chat"
},
"snowflake/claude-3-5-sonnet": {
"supports_computer_use": true,
"max_tokens": 18000,
"max_input_tokens": 18000,
"max_output_tokens": 8192,
@@ -12746,4 +12765,4 @@
"litellm_provider": "featherless_ai",
"mode": "chat"
}
}
}
+62
View File
@@ -339,6 +339,7 @@ def test_aaamodel_prices_and_context_window_json_is_valid():
"additionalProperties": {
"type": "object",
"properties": {
"supports_computer_use": {"type": "boolean"},
"cache_creation_input_audio_token_cost": {"type": "number"},
"cache_creation_input_token_cost": {"type": "number"},
"cache_read_input_token_cost": {"type": "number"},
@@ -693,3 +694,64 @@ async def test_supports_tool_choice():
assert (
supports_tool_choice_result == tool_choice_in_params
), f"Tool choice support mismatch for {model_name}. supports_tool_choice() returned: {supports_tool_choice_result}, tool_choice in supported params: {tool_choice_in_params}\nConfig: {config}"
def test_supports_computer_use_utility():
"""
Tests the litellm.utils.supports_computer_use utility function.
"""
from litellm.utils import supports_computer_use
# Ensure LITELLM_LOCAL_MODEL_COST_MAP is set for consistent test behavior,
# as supports_computer_use relies on get_model_info.
# This also requires litellm.model_cost to be populated.
original_env_var = os.getenv("LITELLM_LOCAL_MODEL_COST_MAP")
original_model_cost = getattr(litellm, "model_cost", None)
os.environ["LITELLM_LOCAL_MODEL_COST_MAP"] = "True"
litellm.model_cost = litellm.get_model_cost_map(url="") # Load with local/backup
try:
# Test a model known to support computer_use from backup JSON
supports_cu_anthropic = supports_computer_use(model="anthropic/claude-3-7-sonnet-20250219")
assert supports_cu_anthropic is True
# Test a model known not to have the flag or set to false (defaults to False via get_model_info)
supports_cu_gpt = supports_computer_use(model="gpt-3.5-turbo")
assert supports_cu_gpt is False
finally:
# Restore original environment and model_cost to avoid side effects
if original_env_var is None:
del os.environ["LITELLM_LOCAL_MODEL_COST_MAP"]
else:
os.environ["LITELLM_LOCAL_MODEL_COST_MAP"] = original_env_var
if original_model_cost is not None:
litellm.model_cost = original_model_cost
elif hasattr(litellm, "model_cost"):
delattr(litellm, "model_cost")
def test_get_model_info_shows_supports_computer_use():
"""
Tests if 'supports_computer_use' is correctly retrieved by get_model_info.
We'll use 'claude-3-7-sonnet-20250219' as it's configured
in the backup JSON to have supports_computer_use: True.
"""
os.environ["LITELLM_LOCAL_MODEL_COST_MAP"] = "True"
# Ensure litellm.model_cost is loaded, relying on the backup mechanism if primary fails
# as per previous debugging.
litellm.model_cost = litellm.get_model_cost_map(url="")
# This model should have 'supports_computer_use': True in the backup JSON
model_known_to_support_computer_use = "claude-3-7-sonnet-20250219"
info = litellm.get_model_info(model_known_to_support_computer_use)
print(f"Info for {model_known_to_support_computer_use}: {info}")
# After the fix in utils.py, this should now be present and True
assert info.get("supports_computer_use") is True
# Optionally, test a model known NOT to support it, or where it's undefined (should default to False)
# For example, if "gpt-3.5-turbo" doesn't have it defined, it should be False.
model_known_not_to_support_computer_use = "gpt-3.5-turbo"
info_gpt = litellm.get_model_info(model_known_not_to_support_computer_use)
print(f"Info for {model_known_not_to_support_computer_use}: {info_gpt}")
assert info_gpt.get("supports_computer_use") is False # Expecting False due to the default in ModelInfoBase
@@ -392,4 +392,3 @@ def test_get_model_info_cost_calculator_bedrock_region_cris_stripped(model, prov
print("info", info)
assert info["key"] == "us.anthropic.claude-3-haiku-20240307-v1:0"
assert info["litellm_provider"] == "bedrock"