diff --git a/litellm/vector_stores/vector_store_registry.py b/litellm/vector_stores/vector_store_registry.py index b5c19cddee2..e0b536d6c57 100644 --- a/litellm/vector_stores/vector_store_registry.py +++ b/litellm/vector_stores/vector_store_registry.py @@ -2,6 +2,7 @@ import json from collections.abc import Mapping from datetime import datetime, timezone +from itertools import chain from typing import ( TYPE_CHECKING, Any, # noqa: TID251 # untyped non_default_params dict is the only source of the unknown key type @@ -36,8 +37,10 @@ _DB_ROW: Final = TypeAdapter(Mapping[str, object], config=ConfigDict(strict=True class VectorStoreIndexRegistry: - def __init__(self, vector_store_indexes: list[LiteLLM_ManagedVectorStoreIndex] = []): - self.vector_store_indexes: list[LiteLLM_ManagedVectorStoreIndex] = vector_store_indexes + def __init__(self, vector_store_indexes: list[LiteLLM_ManagedVectorStoreIndex] | None = None): + self.vector_store_indexes: list[LiteLLM_ManagedVectorStoreIndex] = ( + vector_store_indexes if vector_store_indexes is not None else [] + ) def get_vector_store_indexes(self) -> list[LiteLLM_ManagedVectorStoreIndex]: """ @@ -109,8 +112,8 @@ class VectorStoreIndexRegistry: class VectorStoreRegistry: - def __init__(self, vector_stores: list[LiteLLM_ManagedVectorStore] = []): - self.vector_stores: list[LiteLLM_ManagedVectorStore] = vector_stores + def __init__(self, vector_stores: list[LiteLLM_ManagedVectorStore] | None = None): + self.vector_stores: list[LiteLLM_ManagedVectorStore] = vector_stores if vector_stores is not None else [] self.vector_store_ids_to_vector_store_map: dict[str, LiteLLM_ManagedVectorStore] = {} def _extract_tool_params(self, tool: dict) -> VectorStoreToolParams: @@ -392,17 +395,14 @@ class VectorStoreRegistry: return vector_stores_to_run - def _get_vector_store_ids_from_tool_calls( - self, tools: list[dict] | None = None, vector_store_ids: list[str] = [] - ) -> list[str]: + def _get_vector_store_ids_from_tool_calls(self, tools: list[dict] | None, vector_store_ids: list[str]) -> list[str]: """ Returns the vector store ids from the tool calls """ - if tools: - for tool in tools: - if "vector_store_ids" in tool: - vector_store_ids.extend(tool["vector_store_ids"]) - return vector_store_ids + return [ + *vector_store_ids, + *chain.from_iterable(tool["vector_store_ids"] for tool in tools or () if "vector_store_ids" in tool), + ] def load_vector_stores_from_config(self, vector_stores_config: list[dict]): """ diff --git a/tests/unit/vector_stores/test_vector_store_registry.py b/tests/unit/vector_stores/test_vector_store_registry.py index a29ce1463ab..f6c888d20ff 100644 --- a/tests/unit/vector_stores/test_vector_store_registry.py +++ b/tests/unit/vector_stores/test_vector_store_registry.py @@ -15,7 +15,11 @@ from datetime import datetime, timezone from unittest.mock import AsyncMock, MagicMock import litellm -from litellm.types.vector_stores import LiteLLM_ManagedVectorStore +from litellm.types.vector_stores import ( + IndexCreateLiteLLMParams, + LiteLLM_ManagedVectorStore, + LiteLLM_ManagedVectorStoreIndex, +) from litellm.vector_stores.main import search from litellm.vector_stores.vector_store_registry import VectorStoreIndexRegistry, VectorStoreRegistry @@ -343,3 +347,30 @@ async def test_vector_store_index_row_without_optional_columns_gets_empty_defaul async def test_malformed_vector_store_index_row_from_the_db_raises_a_validation_error(row: object) -> None: with pytest.raises(ValidationError): await VectorStoreIndexRegistry.get_vector_store_indexes_from_db(_database_listing_index_rows([row])) + + +class TestRegistriesDoNotShareDefaultState: + def test_adding_to_one_registry_leaves_the_next_one_empty(self): + VectorStoreRegistry().add_vector_store_to_registry( + LiteLLM_ManagedVectorStore(vector_store_id="vs-leak", custom_llm_provider="bedrock") + ) + assert VectorStoreRegistry().vector_stores == [] + + def test_upserting_into_one_index_registry_leaves_the_next_one_empty(self): + VectorStoreIndexRegistry().upsert_vector_store_index( + LiteLLM_ManagedVectorStoreIndex( + id="idx-leak", + index_name="leak", + litellm_params=IndexCreateLiteLLMParams(vector_store_index="vs-leak", vector_store_name="leak"), + ) + ) + assert VectorStoreIndexRegistry().get_vector_store_indexes() == [] + + +def test_vector_store_ids_to_run_merge_the_param_and_tools_once_per_request(): + registry: Final = VectorStoreRegistry() + first: Final = registry.get_vector_store_ids_to_run( + {"vector_store_ids": ["vs-a"]}, tools=[{"type": "file_search", "vector_store_ids": ["vs-b", "vs-a"]}] + ) + second: Final = registry.get_vector_store_ids_to_run({}, tools=[{"type": "file_search", "vector_store_ids": ["vs-c"]}]) + assert (first, second) == (["vs-a", "vs-b"], ["vs-c"])