fix: add store to OPENAI_CHAT_COMPLETION_PARAMS (#21195)

The OpenAI `store` parameter (used for storing completions for
distillation/evals) was missing from `OPENAI_CHAT_COMPLETION_PARAMS`.

This caused it to be unrecognized by `get_standard_openai_params()` and
the `litellm_proxy` provider config. It also meant that code paths using
this list (rather than `DEFAULT_CHAT_COMPLETION_PARAM_VALUES`) would
treat `store` as a provider-specific parameter and forward it to
non-OpenAI providers like Anthropic, resulting in:

    "store: Extra inputs are not permitted"

Fixes #19700
This commit is contained in:
Nick Amabile
2026-02-16 23:28:34 -05:00
committed by GitHub
parent ddb48fa116
commit 4978df8ebd
2 changed files with 77 additions and 12 deletions
+1
View File
@@ -576,6 +576,7 @@ OPENAI_CHAT_COMPLETION_PARAMS = [
"thinking",
"web_search_options",
"service_tier",
"store",
]
OPENAI_TRANSCRIPTION_PARAMS = [
+76 -12
View File
@@ -1894,28 +1894,28 @@ def test_validate_openai_optional_params_stop_truncation():
result = validate_openai_optional_params(stop=stop_sequences)
assert result == ["stop1", "stop2", "stop3", "stop4"]
assert len(result) == 4
# Test with exactly 4 stop sequences - should not truncate
stop_sequences_4 = ["stop1", "stop2", "stop3", "stop4"]
result = validate_openai_optional_params(stop=stop_sequences_4)
assert result == ["stop1", "stop2", "stop3", "stop4"]
assert len(result) == 4
# Test with less than 4 stop sequences - should not truncate
stop_sequences_2 = ["stop1", "stop2"]
result = validate_openai_optional_params(stop=stop_sequences_2)
assert result == ["stop1", "stop2"]
assert len(result) == 2
# Test with single stop sequence as string - should return as is
stop_string = "stop1"
result = validate_openai_optional_params(stop=stop_string)
assert result == "stop1"
# Test with None - should return None
result = validate_openai_optional_params(stop=None)
assert result is None
# Test with empty list - should return empty list
result = validate_openai_optional_params(stop=[])
assert result == []
@@ -1928,7 +1928,7 @@ def test_validate_openai_optional_params_disable_stop_sequence_limit():
"""
# Save original value
original_value = litellm.disable_stop_sequence_limit
try:
# Test with disable_stop_sequence_limit = True - should NOT truncate
litellm.disable_stop_sequence_limit = True
@@ -1936,7 +1936,7 @@ def test_validate_openai_optional_params_disable_stop_sequence_limit():
result = validate_openai_optional_params(stop=stop_sequences)
assert result == ["stop1", "stop2", "stop3", "stop4", "stop5", "stop6"]
assert len(result) == 6
# Test with disable_stop_sequence_limit = False - should truncate to 4
litellm.disable_stop_sequence_limit = False
stop_sequences = ["stop1", "stop2", "stop3", "stop4", "stop5", "stop6"]
@@ -1965,19 +1965,83 @@ def test_validate_openai_optional_params_integration():
mock_response.usage.prompt_tokens = 10
mock_response.usage.completion_tokens = 5
mock_response.usage.total_tokens = 15
mock_client.return_value.chat.completions.create.return_value = mock_response
mock_client.return_value.chat.completions.create.return_value = (
mock_response
)
# Call completion with more than 4 stop sequences
response = litellm.completion(
model="gpt-3.5-turbo",
messages=[{"role": "user", "content": "Hello"}],
stop=["stop1", "stop2", "stop3", "stop4", "stop5", "stop6"],
mock_response="Test response" # This will use mock
mock_response="Test response", # This will use mock
)
# Verify the call was made (stop sequences should be truncated internally)
assert response is not None
except Exception as e:
# Should not raise an exception
pytest.fail(f"validate_openai_optional_params integration failed: {e}")
def test_drop_store_param_for_anthropic():
"""
Test that the OpenAI-specific `store` parameter is correctly dropped
when calling Anthropic with drop_params=True.
`store` is an OpenAI Chat Completion parameter (for storing completions
for distillation/evals) that Anthropic does not support. Without proper
handling, it leaks through to the Anthropic API and causes a
"store: Extra inputs are not permitted" error.
Ref: https://github.com/BerriAI/litellm/issues/19700
"""
optional_params = get_optional_params(
model="claude-sonnet-4-20250514",
custom_llm_provider="anthropic",
drop_params=True,
store=True,
)
assert "store" not in optional_params
def test_additional_drop_params_store_for_anthropic():
"""
Test that `additional_drop_params=["store"]` correctly strips the `store`
parameter for non-OpenAI providers like Anthropic.
Ref: https://github.com/BerriAI/litellm/issues/19700
"""
optional_params = get_optional_params(
model="claude-sonnet-4-20250514",
custom_llm_provider="anthropic",
additional_drop_params=["store"],
store=True,
)
assert "store" not in optional_params
def test_store_in_openai_chat_completion_params():
"""
Test that `store` is recognized as a standard OpenAI Chat Completion
parameter. This ensures it is correctly handled by helper functions
like `get_standard_openai_params()` and provider configs that rely on
`OPENAI_CHAT_COMPLETION_PARAMS`.
Without `store` in this list, functions that filter by known OpenAI
params will silently drop it for OpenAI calls or incorrectly treat
it as a provider-specific param for non-OpenAI providers.
Ref: https://github.com/BerriAI/litellm/issues/19700
"""
from litellm.constants import OPENAI_CHAT_COMPLETION_PARAMS
assert "store" in OPENAI_CHAT_COMPLETION_PARAMS
# Verify get_standard_openai_params recognizes store
from litellm.utils import get_standard_openai_params
result = get_standard_openai_params({"store": True, "temperature": 0.7})
assert "store" in result
assert result["store"] is True