mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-14 23:21:35 +00:00
fix(mistral): reject file purposes Mistral lacks instead of mapping them to batch
The proxy runs batch-file validation and guardrails only for purpose=batch, so a purpose such as assistants that was silently rewritten to batch on the way to Mistral let an upload skip both. Only batch, fine-tune and ocr pass through now; anything else is a 400.
This commit is contained in:
parent
95fdefa390
commit
e6bc4e47c7
2 changed files with 28 additions and 10 deletions
|
|
@ -89,11 +89,14 @@ def _to_openai_purpose(purpose: MistralFilePurpose) -> OpenAIFilesPurpose:
|
|||
|
||||
|
||||
def _to_mistral_purpose(purpose: str) -> MistralFilePurpose:
|
||||
"""Only Mistral's own purposes pass through. Silently mapping anything else to ``batch``
|
||||
would let an upload skip the proxy's batch-file validation and guardrails, which only
|
||||
run when the caller says ``purpose=batch``."""
|
||||
match purpose:
|
||||
case "fine-tune" | "ocr":
|
||||
case "batch" | "fine-tune" | "ocr":
|
||||
return purpose
|
||||
case _:
|
||||
return "batch"
|
||||
raise ValueError(f"Mistral does not support purpose={purpose!r}. Use one of: batch, fine-tune, ocr")
|
||||
|
||||
|
||||
def _api_base_from(litellm_params: Mapping[str, object]) -> str:
|
||||
|
|
@ -166,7 +169,7 @@ class MistralFilesConfig(BaseFilesConfig):
|
|||
content_type: Final = extracted.get("content_type") or "application/octet-stream"
|
||||
upload: Final = MistralMultipartUpload(
|
||||
file=(filename, extracted["content"], content_type),
|
||||
purpose=(None, _to_mistral_purpose(create_file_data.get("purpose", "batch"))),
|
||||
purpose=(None, _to_mistral_purpose(create_file_data.get("purpose") or "batch")),
|
||||
)
|
||||
return dict(upload) # mutable-ok: BaseFilesConfig signature
|
||||
|
||||
|
|
|
|||
|
|
@ -91,18 +91,28 @@ def test_upload_request_is_multipart_with_batch_purpose(config):
|
|||
}
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"openai_purpose,mistral_purpose",
|
||||
[("batch", "batch"), ("fine-tune", "fine-tune"), ("ocr", "ocr"), ("assistants", "batch"), ("user_data", "batch")],
|
||||
)
|
||||
def test_upload_request_maps_purpose_onto_mistral_enum(config, openai_purpose, mistral_purpose):
|
||||
@pytest.mark.parametrize("purpose", ["batch", "fine-tune", "ocr"])
|
||||
def test_upload_request_passes_mistral_purposes_through(config, purpose):
|
||||
body = config.transform_create_file_request(
|
||||
model="",
|
||||
create_file_data=CreateFileRequest(file=("f.bin", b"x"), purpose=openai_purpose),
|
||||
create_file_data=CreateFileRequest(file=("f.bin", b"x"), purpose=purpose),
|
||||
optional_params={},
|
||||
litellm_params={},
|
||||
)
|
||||
assert body["purpose"] == (None, mistral_purpose)
|
||||
assert body["purpose"] == (None, purpose)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("purpose", ["assistants", "user_data", "vision", "evals"])
|
||||
def test_upload_request_rejects_purposes_mistral_lacks(config, purpose):
|
||||
"""Regression: these used to be silently rewritten to ``batch``, so an upload that skipped the
|
||||
proxy's batch-only validation and guardrails still landed on Mistral as a batch input file."""
|
||||
with pytest.raises(ValueError, match=f"purpose={purpose!r}"):
|
||||
config.transform_create_file_request(
|
||||
model="",
|
||||
create_file_data=CreateFileRequest(file=("f.bin", b"x"), purpose=purpose),
|
||||
optional_params={},
|
||||
litellm_params={},
|
||||
)
|
||||
|
||||
|
||||
def test_upload_request_requires_file(config):
|
||||
|
|
@ -181,6 +191,11 @@ def test_list_request_filters_by_mapped_purpose(config):
|
|||
assert no_params == {}
|
||||
|
||||
|
||||
def test_list_request_rejects_purposes_mistral_lacks(config):
|
||||
with pytest.raises(ValueError, match="purpose='assistants'"):
|
||||
config.transform_list_files_request(purpose="assistants", optional_params={}, litellm_params={})
|
||||
|
||||
|
||||
def test_list_response(config):
|
||||
out = config.transform_list_files_response(
|
||||
raw_response=_response(
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue