mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-14 23:21:35 +00:00
fix(vector-stores): fall back to annotate when the failure mode is unrecognized
litellm_settings keys are set on the litellm module with no allowlist, so a typo in vector_store_search_failure_mode reached assert_never and turned every vector-store request into a 500. Validate the configured value and fall back to the permissive default with a warning naming the supported modes.
This commit is contained in:
parent
6499ca349f
commit
e464e749e0
2 changed files with 49 additions and 2 deletions
|
|
@ -7,8 +7,9 @@ It searches the vector store for relevant context and appends it to the messages
|
|||
|
||||
from collections.abc import Awaitable, Callable, Mapping, Sequence
|
||||
from dataclasses import dataclass
|
||||
from typing import TYPE_CHECKING, Any, Final, Protocol, cast
|
||||
from typing import TYPE_CHECKING, Any, Final, Protocol, cast, get_args
|
||||
|
||||
from pydantic import TypeAdapter, ValidationError
|
||||
from typing_extensions import assert_never
|
||||
|
||||
import litellm
|
||||
|
|
@ -22,6 +23,7 @@ from litellm.types.utils import CallTypes, StandardCallbackDynamicParams
|
|||
from litellm.types.vector_stores import (
|
||||
LiteLLM_ManagedVectorStore,
|
||||
VectorStoreSearchFailure,
|
||||
VectorStoreSearchFailureMode,
|
||||
VectorStoreSearchResponse,
|
||||
VectorStoreSearchResult,
|
||||
)
|
||||
|
|
@ -34,6 +36,8 @@ else:
|
|||
LiteLLMLoggingObj = Any
|
||||
|
||||
SEARCH_FAILURES_FIELD: Final = "vector_store_search_failures"
|
||||
_DEFAULT_FAILURE_MODE: Final[VectorStoreSearchFailureMode] = "annotate"
|
||||
_FAILURE_MODE_ADAPTER: Final = TypeAdapter(VectorStoreSearchFailureMode)
|
||||
|
||||
|
||||
class ProxyRuntime(Protocol):
|
||||
|
|
@ -153,7 +157,7 @@ class VectorStorePreCallHook(CustomLogger):
|
|||
litellm_logging_obj.model_call_details[detail] = value
|
||||
|
||||
if augmentation.failures:
|
||||
match litellm.vector_store_search_failure_mode:
|
||||
match _configured_failure_mode():
|
||||
case "error":
|
||||
raise VectorStoreSearchError(failures=augmentation.failures, model=model)
|
||||
case "annotate":
|
||||
|
|
@ -435,3 +439,16 @@ def _requested_vector_store_ids(non_default_params: Mapping[str, object]) -> tup
|
|||
if not isinstance(requested, (list, tuple)):
|
||||
return ()
|
||||
return tuple(str(vector_store_id) for vector_store_id in requested)
|
||||
|
||||
|
||||
def _configured_failure_mode() -> VectorStoreSearchFailureMode:
|
||||
try:
|
||||
return _FAILURE_MODE_ADAPTER.validate_python(litellm.vector_store_search_failure_mode)
|
||||
except ValidationError:
|
||||
verbose_logger.warning(
|
||||
"Unsupported vector_store_search_failure_mode=%r, falling back to %r. Supported modes: %s",
|
||||
litellm.vector_store_search_failure_mode,
|
||||
_DEFAULT_FAILURE_MODE,
|
||||
", ".join(get_args(VectorStoreSearchFailureMode)),
|
||||
)
|
||||
return _DEFAULT_FAILURE_MODE
|
||||
|
|
|
|||
|
|
@ -425,6 +425,36 @@ async def test_error_mode_fails_the_request_instead_of_answering_without_the_kno
|
|||
assert "vs-broken: litellm.BadRequestError: no healthy deployments for vs-broken" in raised.value.message
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_a_misspelled_failure_mode_annotates_instead_of_erroring_the_request(
|
||||
registry_with: RegisterStores,
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
warnings: list[logging.LogRecord],
|
||||
) -> None:
|
||||
"""Regression (LIT-6809): litellm_settings takes any value, so a typo must not become a 500."""
|
||||
registry_with("vs-broken")
|
||||
monkeypatch.setattr(litellm, "vector_store_search_failure_mode", "erorr")
|
||||
|
||||
logging_obj = FakeLoggingObj({})
|
||||
_, messages, _ = await _run_hook(
|
||||
VectorStorePreCallHook(
|
||||
proxy_runtime=FakeProxyRuntime(router=RecordingRouter(failing_vector_store_ids=frozenset({"vs-broken"})))
|
||||
),
|
||||
["vs-broken"],
|
||||
logging_obj,
|
||||
)
|
||||
|
||||
assert messages[0]["content"] == "what is litellm?"
|
||||
assert logging_obj.model_call_details["vector_store_search_failures"] == (
|
||||
{
|
||||
"vector_store_id": "vs-broken",
|
||||
"custom_llm_provider": "bedrock",
|
||||
"error": "litellm.BadRequestError: no healthy deployments for vs-broken",
|
||||
},
|
||||
)
|
||||
assert any("erorr" in record.getMessage() for record in warnings)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_error_mode_leaves_a_fully_healthy_request_alone(
|
||||
registry_with: RegisterStores,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue