fix(rag): consume top-level filters kwarg to avoid duplicate keyword in search

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
milan 2026-07-23 21:04:42 +00:00
parent 8a9ff04b4d
commit 232b9e8e78
2 changed files with 37 additions and 1 deletions

View file

@ -233,7 +233,8 @@ async def _execute_query_pipeline(
raise ValueError("No query found in messages for RAG query")
# 2. Search vector store
filters = retrieval_config.get("retrieval_filter") or retrieval_config.get("filters")
kwargs_filters = kwargs.pop("filters", None)
filters = retrieval_config.get("retrieval_filter") or retrieval_config.get("filters") or kwargs_filters
with _suppressed_sub_call_billing():
search_response = await litellm.vector_stores.asearch(
vector_store_id=retrieval_config["vector_store_id"],

View file

@ -301,6 +301,41 @@ async def test_aquery_forwards_retrieval_filter_to_vector_store_search(filter_ke
assert fake_search.await_args.kwargs["max_num_results"] == 50
@pytest.mark.asyncio
async def test_aquery_top_level_filters_kwarg_does_not_collide():
"""
An SDK caller may pass a top-level `filters` kwarg (it used to flow to the
search via **kwargs). Now that the pipeline passes `filters` explicitly, the
top-level kwarg must be consumed rather than forwarded twice, otherwise
asearch raises TypeError for a duplicate keyword before any search runs.
"""
from litellm.types.vector_stores import VectorStoreSearchResponse
top_level_filter = {"equals": {"key": "tenant", "value": "a"}}
fake_search = AsyncMock(
return_value=VectorStoreSearchResponse(
object="vector_store.search_results.page",
search_query="q",
data=[],
)
)
with patch("litellm.vector_stores.asearch", new=fake_search):
response = await litellm.aquery(
model="gpt-4o-mini",
messages=[{"role": "user", "content": "hello"}],
retrieval_config={"vector_store_id": "vs_test_123", "custom_llm_provider": "openai"},
filters=top_level_filter,
mock_response="hi",
)
assert isinstance(response, ModelResponse)
fake_search.assert_awaited_once()
assert fake_search.await_args.kwargs["filters"] == top_level_filter
assert "filters" not in fake_search.await_args.kwargs.get("kwargs", {})
@pytest.mark.asyncio
async def test_aquery_without_filter_forwards_none():
"""