feat(deepseek): add DeepSeek V4 Pro and V4 Flash model metadata

Add model pricing, context window, and capability metadata for the new DeepSeek V4 model series:

- deepseek-v4-flash: 1M context, 384K output, .14/M input, .28/M output

- deepseek-v4-pro: 1M context, 384K output, .74/M input, .48/M output

Both models support function calling, tool choice, reasoning, response schema, prompt caching, and streaming.

Entries added with both bare and provider-prefixed keys.

Source: https://api-docs.deepseek.com/quick_start/pricing
This commit is contained in:
neo1027144 2026-04-24 11:47:22 +08:00
parent 8e652d129d
commit 14d91d1ff0
2 changed files with 195 additions and 0 deletions

View file

@ -9641,6 +9641,56 @@
"supports_system_messages": true,
"supports_tool_choice": false
},
"deepseek-v4-flash": {
"cache_creation_input_token_cost": 0.0,
"cache_read_input_token_cost": 2.8e-08,
"input_cost_per_token": 1.4e-07,
"input_cost_per_token_cache_hit": 2.8e-08,
"litellm_provider": "deepseek",
"max_input_tokens": 1000000,
"max_output_tokens": 384000,
"max_tokens": 384000,
"mode": "chat",
"output_cost_per_token": 2.8e-07,
"source": "https://api-docs.deepseek.com/quick_start/pricing",
"supported_endpoints": [
"/v1/chat/completions"
],
"supports_assistant_prefill": true,
"supports_function_calling": true,
"supports_native_streaming": true,
"supports_parallel_function_calling": true,
"supports_prompt_caching": true,
"supports_reasoning": true,
"supports_response_schema": true,
"supports_system_messages": true,
"supports_tool_choice": true
},
"deepseek-v4-pro": {
"cache_creation_input_token_cost": 0.0,
"cache_read_input_token_cost": 1.4e-07,
"input_cost_per_token": 1.74e-06,
"input_cost_per_token_cache_hit": 1.4e-07,
"litellm_provider": "deepseek",
"max_input_tokens": 1000000,
"max_output_tokens": 384000,
"max_tokens": 384000,
"mode": "chat",
"output_cost_per_token": 3.48e-06,
"source": "https://api-docs.deepseek.com/quick_start/pricing",
"supported_endpoints": [
"/v1/chat/completions"
],
"supports_assistant_prefill": true,
"supports_function_calling": true,
"supports_native_streaming": true,
"supports_parallel_function_calling": true,
"supports_prompt_caching": true,
"supports_reasoning": true,
"supports_response_schema": true,
"supports_system_messages": true,
"supports_tool_choice": true
},
"dashscope/qwen-coder": {
"input_cost_per_token": 3e-07,
"litellm_provider": "dashscope",
@ -12231,6 +12281,56 @@
"supports_reasoning": true,
"supports_tool_choice": true
},
"deepseek/deepseek-v4-flash": {
"cache_creation_input_token_cost": 0.0,
"cache_read_input_token_cost": 2.8e-08,
"input_cost_per_token": 1.4e-07,
"input_cost_per_token_cache_hit": 2.8e-08,
"litellm_provider": "deepseek",
"max_input_tokens": 1000000,
"max_output_tokens": 384000,
"max_tokens": 384000,
"mode": "chat",
"output_cost_per_token": 2.8e-07,
"source": "https://api-docs.deepseek.com/quick_start/pricing",
"supported_endpoints": [
"/v1/chat/completions"
],
"supports_assistant_prefill": true,
"supports_function_calling": true,
"supports_native_streaming": true,
"supports_parallel_function_calling": true,
"supports_prompt_caching": true,
"supports_reasoning": true,
"supports_response_schema": true,
"supports_system_messages": true,
"supports_tool_choice": true
},
"deepseek/deepseek-v4-pro": {
"cache_creation_input_token_cost": 0.0,
"cache_read_input_token_cost": 1.4e-07,
"input_cost_per_token": 1.74e-06,
"input_cost_per_token_cache_hit": 1.4e-07,
"litellm_provider": "deepseek",
"max_input_tokens": 1000000,
"max_output_tokens": 384000,
"max_tokens": 384000,
"mode": "chat",
"output_cost_per_token": 3.48e-06,
"source": "https://api-docs.deepseek.com/quick_start/pricing",
"supported_endpoints": [
"/v1/chat/completions"
],
"supports_assistant_prefill": true,
"supports_function_calling": true,
"supports_native_streaming": true,
"supports_parallel_function_calling": true,
"supports_prompt_caching": true,
"supports_reasoning": true,
"supports_response_schema": true,
"supports_system_messages": true,
"supports_tool_choice": true
},
"deepseek.v3-v1:0": {
"input_cost_per_token": 5.8e-07,
"litellm_provider": "bedrock_converse",

View file

@ -178,3 +178,98 @@ class TestBareModelFallback:
finally:
if key in litellm.model_cost and original is not None:
litellm.model_cost[key]["supports_function_calling"] = original
# ---------------------------------------------------------------------------
# DeepSeek V4 model metadata tests
# ---------------------------------------------------------------------------
class TestDeepSeekV4ModelMetadata:
"""Verify that DeepSeek V4 Flash and V4 Pro model entries exist
and have correct metadata in the main JSON file."""
def _load_main_json(self) -> dict:
main_path = os.path.join(
os.path.dirname(os.path.dirname(litellm.__file__)),
"model_prices_and_context_window.json",
)
with open(main_path, encoding="utf-8") as f:
return json.load(f)
def test_v4_flash_exists_prefixed(self):
data = self._load_main_json()
assert "deepseek/deepseek-v4-flash" in data
def test_v4_pro_exists_prefixed(self):
data = self._load_main_json()
assert "deepseek/deepseek-v4-pro" in data
def test_v4_flash_exists_bare(self):
data = self._load_main_json()
assert "deepseek-v4-flash" in data
def test_v4_pro_exists_bare(self):
data = self._load_main_json()
assert "deepseek-v4-pro" in data
def test_v4_flash_context_window(self):
data = self._load_main_json()
entry = data["deepseek/deepseek-v4-flash"]
assert entry["max_input_tokens"] == 1000000
assert entry["max_output_tokens"] == 384000
def test_v4_pro_context_window(self):
data = self._load_main_json()
entry = data["deepseek/deepseek-v4-pro"]
assert entry["max_input_tokens"] == 1000000
assert entry["max_output_tokens"] == 384000
def test_v4_flash_supports_function_calling(self):
data = self._load_main_json()
entry = data["deepseek/deepseek-v4-flash"]
assert entry.get("supports_function_calling") is True
assert entry.get("supports_tool_choice") is True
def test_v4_pro_supports_function_calling(self):
data = self._load_main_json()
entry = data["deepseek/deepseek-v4-pro"]
assert entry.get("supports_function_calling") is True
assert entry.get("supports_tool_choice") is True
def test_v4_flash_supports_reasoning(self):
data = self._load_main_json()
entry = data["deepseek/deepseek-v4-flash"]
assert entry.get("supports_reasoning") is True
def test_v4_pro_supports_reasoning(self):
data = self._load_main_json()
entry = data["deepseek/deepseek-v4-pro"]
assert entry.get("supports_reasoning") is True
def test_v4_flash_provider_is_deepseek(self):
data = self._load_main_json()
entry = data["deepseek/deepseek-v4-flash"]
assert entry["litellm_provider"] == "deepseek"
def test_v4_pro_provider_is_deepseek(self):
data = self._load_main_json()
entry = data["deepseek/deepseek-v4-pro"]
assert entry["litellm_provider"] == "deepseek"
def test_v4_flash_bare_and_prefixed_match(self):
"""Bare and prefixed entries must have the same context window."""
data = self._load_main_json()
bare = data["deepseek-v4-flash"]
prefixed = data["deepseek/deepseek-v4-flash"]
assert bare["max_input_tokens"] == prefixed["max_input_tokens"]
assert bare["max_output_tokens"] == prefixed["max_output_tokens"]
def test_v4_pro_bare_and_prefixed_match(self):
"""Bare and prefixed entries must have the same context window."""
data = self._load_main_json()
bare = data["deepseek-v4-pro"]
prefixed = data["deepseek/deepseek-v4-pro"]
assert bare["max_input_tokens"] == prefixed["max_input_tokens"]
assert bare["max_output_tokens"] == prefixed["max_output_tokens"]