From 3e2a16335166205c789ff0da433179acaf60c5fb Mon Sep 17 00:00:00 2001 From: Connor Shorten Date: Wed, 20 May 2026 19:51:14 -0400 Subject: [PATCH 1/9] add search_strategy argument to search mode --- test/query_agent/test_query_model.py | 75 ++++++++++++++++++++++++ weaviate_agents/query/classes/request.py | 1 + weaviate_agents/query/query_agent.py | 13 ++++ weaviate_agents/query/search.py | 6 +- 4 files changed, 94 insertions(+), 1 deletion(-) diff --git a/test/query_agent/test_query_model.py b/test/query_agent/test_query_model.py index 3bb0c76..8b9aadb 100644 --- a/test/query_agent/test_query_model.py +++ b/test/query_agent/test_query_model.py @@ -797,6 +797,54 @@ def fake_post_with_capture(url, headers=None, json=None, timeout=None): assert captured["json"]["diversity_weight"] is None +def test_search_only_mode_with_search_strategy(monkeypatch): + captured = {} + + def fake_post_with_capture(url, headers=None, json=None, timeout=None): + captured["json"] = json + return fake_post_search_only_success() + + monkeypatch.setattr(httpx, "post", fake_post_with_capture) + dummy_client = DummyClient() + agent = QueryAgent( + dummy_client, ["test_collection"], agents_host="http://dummy-agent" + ) + agent._connection = dummy_client + agent._headers = dummy_client.additional_headers + + # Test with search_strategy set + results = agent.search("test query", limit=2, search_strategy="recall") + assert isinstance(results, SearchModeResponse) + assert captured["json"]["search_strategy"] == "recall" + + # Reset captured json, then paginate — search_strategy should persist + captured = {} + results_2 = results.next(limit=2, offset=1) + assert isinstance(results_2, SearchModeResponse) + assert captured["json"]["search_strategy"] == "recall" + + +def test_search_only_mode_without_search_strategy(monkeypatch): + captured = {} + + def fake_post_with_capture(url, headers=None, json=None, timeout=None): + captured["json"] = json + return fake_post_search_only_success() + + monkeypatch.setattr(httpx, "post", fake_post_with_capture) + dummy_client = DummyClient() + agent = QueryAgent( + dummy_client, ["test_collection"], agents_host="http://dummy-agent" + ) + agent._connection = dummy_client + agent._headers = dummy_client.additional_headers + + # Test without search_strategy — should default to None + results = agent.search("test query", limit=2) + assert isinstance(results, SearchModeResponse) + assert captured["json"]["search_strategy"] is None + + def test_search_only_mode_failure(monkeypatch): monkeypatch.setattr(httpx, "post", fake_post_failure) dummy_client = DummyClient() @@ -893,6 +941,33 @@ async def fake_post_with_capture(self, url, headers=None, json=None, timeout=Non assert captured["json"]["diversity_weight"] == 0.7 +async def test_async_search_only_mode_with_search_strategy(monkeypatch): + captured = {} + + async def fake_post_with_capture(self, url, headers=None, json=None, timeout=None): + captured["json"] = json + return await fake_async_post_search_only_success() + + monkeypatch.setattr(httpx.AsyncClient, "post", fake_post_with_capture) + dummy_client = DummyClient() + agent = AsyncQueryAgent( + dummy_client, ["test_collection"], agents_host="http://dummy-agent" + ) + agent._connection = dummy_client + agent._headers = dummy_client.additional_headers + + # Test with search_strategy set + results = await agent.search("test query", limit=2, search_strategy="precision") + assert isinstance(results, AsyncSearchModeResponse) + assert captured["json"]["search_strategy"] == "precision" + + # Reset captured json, then paginate — search_strategy should persist + captured = {} + results_2 = await results.next(limit=2, offset=1) + assert isinstance(results_2, AsyncSearchModeResponse) + assert captured["json"]["search_strategy"] == "precision" + + async def test_async_search_only_mode_failure(monkeypatch): monkeypatch.setattr(httpx.AsyncClient, "post", fake_async_post_failure) dummy_client = DummyClient() diff --git a/weaviate_agents/query/classes/request.py b/weaviate_agents/query/classes/request.py index aee9ee7..800ab2e 100644 --- a/weaviate_agents/query/classes/request.py +++ b/weaviate_agents/query/classes/request.py @@ -18,6 +18,7 @@ class SearchModeRequestBase(BaseModel): limit: int offset: int diversity_weight: Optional[float] = None + search_strategy: Optional[Literal["recall", "precision"]] = None class SearchModeExecutionRequest(SearchModeRequestBase): diff --git a/weaviate_agents/query/query_agent.py b/weaviate_agents/query/query_agent.py index d3e9a64..fbaabb4 100644 --- a/weaviate_agents/query/query_agent.py +++ b/weaviate_agents/query/query_agent.py @@ -499,6 +499,7 @@ def search( limit: int = 20, collections: Union[list[Union[str, QueryAgentCollectionConfig]], None] = None, diversity_weight: Optional[float] = None, + search_strategy: Optional[Literal["recall", "precision"]] = None, ) -> Union[SearchModeResponse, Coroutine[Any, Any, AsyncSearchModeResponse]]: pass @@ -1014,6 +1015,7 @@ def search( limit: int = 20, collections: Union[list[Union[str, QueryAgentCollectionConfig]], None] = None, diversity_weight: Optional[float] = None, + search_strategy: Optional[Literal["recall", "precision"]] = None, ) -> SearchModeResponse: """Run the Query Agent search-only mode. @@ -1031,6 +1033,10 @@ def search( results with MMR reranking. Higher values push for more topical variety at the cost of relevance. Defaults to None (no diversity). + search_strategy: The search strategy to use for this search. + Use ``"recall"`` to optimize for finding all relevant results, + or ``"precision"`` to optimize for the accuracy of returned results. + Defaults to None. Returns: An instance of :class:`~weaviate_agents.query.classes.response.SearchModeResponse` for the first page of results. Use @@ -1066,6 +1072,7 @@ def search( collections=collections, system_prompt=self._system_prompt, diversity_weight=diversity_weight, + search_strategy=search_strategy, ) return searcher.run(limit=limit) @@ -1653,6 +1660,7 @@ async def search( limit: int = 20, collections: Union[list[Union[str, QueryAgentCollectionConfig]], None] = None, diversity_weight: Optional[float] = None, + search_strategy: Optional[Literal["recall", "precision"]] = None, ) -> AsyncSearchModeResponse: """Run the Query Agent search-only mode. @@ -1671,6 +1679,10 @@ async def search( results with MMR reranking. Higher values push for more topical variety at the cost of relevance. Defaults to None (no diversity). + search_strategy: The search strategy to use for this search. + Use ``"recall"`` to optimize for finding all relevant results, + or ``"precision"`` to optimize for the accuracy of returned results. + Defaults to None. Returns: An instance of :class:`~weaviate_agents.query.classes.response.AsyncSearchModeResponse` for the first page of results. Use @@ -1706,6 +1718,7 @@ async def search( collections=collections, system_prompt=self._system_prompt, diversity_weight=diversity_weight, + search_strategy=search_strategy, ) return await searcher.run(limit=limit) diff --git a/weaviate_agents/query/search.py b/weaviate_agents/query/search.py index 77c2365..52aff30 100644 --- a/weaviate_agents/query/search.py +++ b/weaviate_agents/query/search.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import Any, Optional, Union +from typing import Any, Literal, Optional, Union import httpx @@ -36,6 +36,7 @@ def __init__( collections: list[Union[str, QueryAgentCollectionConfig]], system_prompt: Optional[str], diversity_weight: Optional[float] = None, + search_strategy: Optional[Literal["recall", "precision"]] = None, ): self.headers = headers self.connection_headers = connection_headers @@ -45,6 +46,7 @@ def __init__( self.collections = collections self.system_prompt = system_prompt self.diversity_weight = diversity_weight + self.search_strategy = search_strategy self._cached_searches: Optional[list[QueryResultWithCollectionNormalized]] = ( None ) @@ -64,6 +66,7 @@ def _get_request_body(self, limit: int, offset: int) -> dict[str, Any]: offset=offset, system_prompt=self.system_prompt, diversity_weight=self.diversity_weight, + search_strategy=self.search_strategy, ).model_dump(mode="json") else: return SearchModeExecutionRequest( @@ -74,6 +77,7 @@ def _get_request_body(self, limit: int, offset: int) -> dict[str, Any]: offset=offset, searches=self._cached_searches, diversity_weight=self.diversity_weight, + search_strategy=self.search_strategy, ).model_dump(mode="json") From 05bab20d1eeffc948925385911f9269de41179fe Mon Sep 17 00:00:00 2001 From: Connor Shorten Date: Wed, 20 May 2026 19:54:51 -0400 Subject: [PATCH 2/9] fix --- test/query_agent/test_query_model.py | 6 +++--- weaviate_agents/query/classes/request.py | 2 +- weaviate_agents/query/query_agent.py | 10 +++++----- weaviate_agents/query/search.py | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/test/query_agent/test_query_model.py b/test/query_agent/test_query_model.py index 8b9aadb..285a01a 100644 --- a/test/query_agent/test_query_model.py +++ b/test/query_agent/test_query_model.py @@ -824,7 +824,7 @@ def fake_post_with_capture(url, headers=None, json=None, timeout=None): assert captured["json"]["search_strategy"] == "recall" -def test_search_only_mode_without_search_strategy(monkeypatch): +def test_search_only_mode_default_search_strategy(monkeypatch): captured = {} def fake_post_with_capture(url, headers=None, json=None, timeout=None): @@ -839,10 +839,10 @@ def fake_post_with_capture(url, headers=None, json=None, timeout=None): agent._connection = dummy_client agent._headers = dummy_client.additional_headers - # Test without search_strategy — should default to None + # Test without search_strategy — should default to "recall" results = agent.search("test query", limit=2) assert isinstance(results, SearchModeResponse) - assert captured["json"]["search_strategy"] is None + assert captured["json"]["search_strategy"] == "recall" def test_search_only_mode_failure(monkeypatch): diff --git a/weaviate_agents/query/classes/request.py b/weaviate_agents/query/classes/request.py index 800ab2e..ea04c2c 100644 --- a/weaviate_agents/query/classes/request.py +++ b/weaviate_agents/query/classes/request.py @@ -18,7 +18,7 @@ class SearchModeRequestBase(BaseModel): limit: int offset: int diversity_weight: Optional[float] = None - search_strategy: Optional[Literal["recall", "precision"]] = None + search_strategy: Literal["recall", "precision"] = "recall" class SearchModeExecutionRequest(SearchModeRequestBase): diff --git a/weaviate_agents/query/query_agent.py b/weaviate_agents/query/query_agent.py index fbaabb4..0e5c544 100644 --- a/weaviate_agents/query/query_agent.py +++ b/weaviate_agents/query/query_agent.py @@ -499,7 +499,7 @@ def search( limit: int = 20, collections: Union[list[Union[str, QueryAgentCollectionConfig]], None] = None, diversity_weight: Optional[float] = None, - search_strategy: Optional[Literal["recall", "precision"]] = None, + search_strategy: Literal["recall", "precision"] = "recall", ) -> Union[SearchModeResponse, Coroutine[Any, Any, AsyncSearchModeResponse]]: pass @@ -1015,7 +1015,7 @@ def search( limit: int = 20, collections: Union[list[Union[str, QueryAgentCollectionConfig]], None] = None, diversity_weight: Optional[float] = None, - search_strategy: Optional[Literal["recall", "precision"]] = None, + search_strategy: Literal["recall", "precision"] = "recall", ) -> SearchModeResponse: """Run the Query Agent search-only mode. @@ -1036,7 +1036,7 @@ def search( search_strategy: The search strategy to use for this search. Use ``"recall"`` to optimize for finding all relevant results, or ``"precision"`` to optimize for the accuracy of returned results. - Defaults to None. + Defaults to ``"recall"``. Returns: An instance of :class:`~weaviate_agents.query.classes.response.SearchModeResponse` for the first page of results. Use @@ -1660,7 +1660,7 @@ async def search( limit: int = 20, collections: Union[list[Union[str, QueryAgentCollectionConfig]], None] = None, diversity_weight: Optional[float] = None, - search_strategy: Optional[Literal["recall", "precision"]] = None, + search_strategy: Literal["recall", "precision"] = "recall", ) -> AsyncSearchModeResponse: """Run the Query Agent search-only mode. @@ -1682,7 +1682,7 @@ async def search( search_strategy: The search strategy to use for this search. Use ``"recall"`` to optimize for finding all relevant results, or ``"precision"`` to optimize for the accuracy of returned results. - Defaults to None. + Defaults to ``"recall"``. Returns: An instance of :class:`~weaviate_agents.query.classes.response.AsyncSearchModeResponse` for the first page of results. Use diff --git a/weaviate_agents/query/search.py b/weaviate_agents/query/search.py index 52aff30..ea151df 100644 --- a/weaviate_agents/query/search.py +++ b/weaviate_agents/query/search.py @@ -36,7 +36,7 @@ def __init__( collections: list[Union[str, QueryAgentCollectionConfig]], system_prompt: Optional[str], diversity_weight: Optional[float] = None, - search_strategy: Optional[Literal["recall", "precision"]] = None, + search_strategy: Literal["recall", "precision"] = "recall", ): self.headers = headers self.connection_headers = connection_headers From 8f70a45581c0dd7f0f92ed1dc596f8201bf33e88 Mon Sep 17 00:00:00 2001 From: Connor Shorten Date: Wed, 20 May 2026 19:57:52 -0400 Subject: [PATCH 3/9] fixes --- weaviate_agents/query/classes/request.py | 2 +- weaviate_agents/query/query_agent.py | 26 ++++++++++++------------ weaviate_agents/query/search.py | 8 ++++---- 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/weaviate_agents/query/classes/request.py b/weaviate_agents/query/classes/request.py index ea04c2c..5fe2e8d 100644 --- a/weaviate_agents/query/classes/request.py +++ b/weaviate_agents/query/classes/request.py @@ -17,8 +17,8 @@ class SearchModeRequestBase(BaseModel): collections: list[Union[str, QueryAgentCollectionConfig]] limit: int offset: int - diversity_weight: Optional[float] = None search_strategy: Literal["recall", "precision"] = "recall" + diversity_weight: Optional[float] = None class SearchModeExecutionRequest(SearchModeRequestBase): diff --git a/weaviate_agents/query/query_agent.py b/weaviate_agents/query/query_agent.py index 0e5c544..0790a34 100644 --- a/weaviate_agents/query/query_agent.py +++ b/weaviate_agents/query/query_agent.py @@ -498,8 +498,8 @@ def search( query: Union[str, list[ChatMessage]], limit: int = 20, collections: Union[list[Union[str, QueryAgentCollectionConfig]], None] = None, - diversity_weight: Optional[float] = None, search_strategy: Literal["recall", "precision"] = "recall", + diversity_weight: Optional[float] = None, ) -> Union[SearchModeResponse, Coroutine[Any, Any, AsyncSearchModeResponse]]: pass @@ -1014,8 +1014,8 @@ def search( query: Union[str, list[ChatMessage]], limit: int = 20, collections: Union[list[Union[str, QueryAgentCollectionConfig]], None] = None, - diversity_weight: Optional[float] = None, search_strategy: Literal["recall", "precision"] = "recall", + diversity_weight: Optional[float] = None, ) -> SearchModeResponse: """Run the Query Agent search-only mode. @@ -1029,14 +1029,14 @@ def search( limit: The maximum number of results to return for the first page. collections: The collections to query. Either a list of strings, or a list of :class:`~weaviate_agents.query.classes.QueryAgentCollectionConfig` objects. Overrides any collections provided in the constructor when set. + search_strategy: The search strategy to use for this search. + Use "recall" to optimize for finding all relevant results, + or "precision" to optimize for the accuracy of returned results. + Defaults to "recall". diversity_weight: Optional float between 0.0 and 1.0 to diversify results with MMR reranking. Higher values push for more topical variety at the cost of relevance. Defaults to None (no diversity). - search_strategy: The search strategy to use for this search. - Use ``"recall"`` to optimize for finding all relevant results, - or ``"precision"`` to optimize for the accuracy of returned results. - Defaults to ``"recall"``. Returns: An instance of :class:`~weaviate_agents.query.classes.response.SearchModeResponse` for the first page of results. Use @@ -1071,8 +1071,8 @@ def search( query=query, collections=collections, system_prompt=self._system_prompt, - diversity_weight=diversity_weight, search_strategy=search_strategy, + diversity_weight=diversity_weight, ) return searcher.run(limit=limit) @@ -1659,8 +1659,8 @@ async def search( query: Union[str, list[ChatMessage]], limit: int = 20, collections: Union[list[Union[str, QueryAgentCollectionConfig]], None] = None, - diversity_weight: Optional[float] = None, search_strategy: Literal["recall", "precision"] = "recall", + diversity_weight: Optional[float] = None, ) -> AsyncSearchModeResponse: """Run the Query Agent search-only mode. @@ -1675,14 +1675,14 @@ async def search( limit: The maximum number of results to return for the first page. collections: The collections to query. Overrides any collections provided in the constructor when set. + search_strategy: The search strategy to use for this search. + Use "recall" to optimize for finding all relevant results, + or "precision" to optimize for the accuracy of returned results. + Defaults to "recall". diversity_weight: Optional float between 0.0 and 1.0 to diversify results with MMR reranking. Higher values push for more topical variety at the cost of relevance. Defaults to None (no diversity). - search_strategy: The search strategy to use for this search. - Use ``"recall"`` to optimize for finding all relevant results, - or ``"precision"`` to optimize for the accuracy of returned results. - Defaults to ``"recall"``. Returns: An instance of :class:`~weaviate_agents.query.classes.response.AsyncSearchModeResponse` for the first page of results. Use @@ -1717,8 +1717,8 @@ async def search( query=query, collections=collections, system_prompt=self._system_prompt, - diversity_weight=diversity_weight, search_strategy=search_strategy, + diversity_weight=diversity_weight, ) return await searcher.run(limit=limit) diff --git a/weaviate_agents/query/search.py b/weaviate_agents/query/search.py index ea151df..ff30cff 100644 --- a/weaviate_agents/query/search.py +++ b/weaviate_agents/query/search.py @@ -35,8 +35,8 @@ def __init__( query: Union[str, list[ChatMessage]], collections: list[Union[str, QueryAgentCollectionConfig]], system_prompt: Optional[str], - diversity_weight: Optional[float] = None, search_strategy: Literal["recall", "precision"] = "recall", + diversity_weight: Optional[float] = None, ): self.headers = headers self.connection_headers = connection_headers @@ -45,8 +45,8 @@ def __init__( self.query = query self.collections = collections self.system_prompt = system_prompt - self.diversity_weight = diversity_weight self.search_strategy = search_strategy + self.diversity_weight = diversity_weight self._cached_searches: Optional[list[QueryResultWithCollectionNormalized]] = ( None ) @@ -65,8 +65,8 @@ def _get_request_body(self, limit: int, offset: int) -> dict[str, Any]: limit=limit, offset=offset, system_prompt=self.system_prompt, - diversity_weight=self.diversity_weight, search_strategy=self.search_strategy, + diversity_weight=self.diversity_weight, ).model_dump(mode="json") else: return SearchModeExecutionRequest( @@ -76,8 +76,8 @@ def _get_request_body(self, limit: int, offset: int) -> dict[str, Any]: limit=limit, offset=offset, searches=self._cached_searches, - diversity_weight=self.diversity_weight, search_strategy=self.search_strategy, + diversity_weight=self.diversity_weight, ).model_dump(mode="json") From 2be3dd2a12a268bf7bbb0ab1dda312dffe9c3277 Mon Sep 17 00:00:00 2001 From: Connor Shorten Date: Thu, 21 May 2026 06:52:37 -0400 Subject: [PATCH 4/9] fix for pagination with no searches --- weaviate_agents/query/search.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/weaviate_agents/query/search.py b/weaviate_agents/query/search.py index ff30cff..7c801b9 100644 --- a/weaviate_agents/query/search.py +++ b/weaviate_agents/query/search.py @@ -97,7 +97,7 @@ def _handle_response(self, response: httpx.Response) -> SearchModeResponse: raise Exception(response.text) parsed_response = SearchModeResponse(**response.json()) - if parsed_response.searches: + if parsed_response.searches is not None: self._cached_searches = parsed_response.searches parsed_response._searcher = self return parsed_response @@ -142,7 +142,7 @@ def _handle_response(self, response: httpx.Response) -> AsyncSearchModeResponse: raise Exception(response.text) parsed_response = AsyncSearchModeResponse(**response.json()) - if parsed_response.searches: + if parsed_response.searches is not None: self._cached_searches = parsed_response.searches parsed_response._searcher = self return parsed_response From bf2ec1716edbe3e2b66d41592f0b72bd58548873 Mon Sep 17 00:00:00 2001 From: Connor Shorten Date: Thu, 21 May 2026 07:02:07 -0400 Subject: [PATCH 5/9] rename to --- test/query_agent/test_query_model.py | 30 ++++++++++++------------ weaviate_agents/query/classes/request.py | 2 +- weaviate_agents/query/query_agent.py | 14 +++++------ weaviate_agents/query/search.py | 8 +++---- 4 files changed, 27 insertions(+), 27 deletions(-) diff --git a/test/query_agent/test_query_model.py b/test/query_agent/test_query_model.py index 285a01a..da3afcb 100644 --- a/test/query_agent/test_query_model.py +++ b/test/query_agent/test_query_model.py @@ -797,7 +797,7 @@ def fake_post_with_capture(url, headers=None, json=None, timeout=None): assert captured["json"]["diversity_weight"] is None -def test_search_only_mode_with_search_strategy(monkeypatch): +def test_search_only_mode_with_retrieval_strategy(monkeypatch): captured = {} def fake_post_with_capture(url, headers=None, json=None, timeout=None): @@ -812,19 +812,19 @@ def fake_post_with_capture(url, headers=None, json=None, timeout=None): agent._connection = dummy_client agent._headers = dummy_client.additional_headers - # Test with search_strategy set - results = agent.search("test query", limit=2, search_strategy="recall") + # Test with retrieval_strategy set + results = agent.search("test query", limit=2, retrieval_strategy="recall") assert isinstance(results, SearchModeResponse) - assert captured["json"]["search_strategy"] == "recall" + assert captured["json"]["retrieval_strategy"] == "recall" - # Reset captured json, then paginate — search_strategy should persist + # Reset captured json, then paginate — retrieval_strategy should persist captured = {} results_2 = results.next(limit=2, offset=1) assert isinstance(results_2, SearchModeResponse) - assert captured["json"]["search_strategy"] == "recall" + assert captured["json"]["retrieval_strategy"] == "recall" -def test_search_only_mode_default_search_strategy(monkeypatch): +def test_search_only_mode_default_retrieval_strategy(monkeypatch): captured = {} def fake_post_with_capture(url, headers=None, json=None, timeout=None): @@ -839,10 +839,10 @@ def fake_post_with_capture(url, headers=None, json=None, timeout=None): agent._connection = dummy_client agent._headers = dummy_client.additional_headers - # Test without search_strategy — should default to "recall" + # Test without retrieval_strategy — should default to "recall" results = agent.search("test query", limit=2) assert isinstance(results, SearchModeResponse) - assert captured["json"]["search_strategy"] == "recall" + assert captured["json"]["retrieval_strategy"] == "recall" def test_search_only_mode_failure(monkeypatch): @@ -941,7 +941,7 @@ async def fake_post_with_capture(self, url, headers=None, json=None, timeout=Non assert captured["json"]["diversity_weight"] == 0.7 -async def test_async_search_only_mode_with_search_strategy(monkeypatch): +async def test_async_search_only_mode_with_retrieval_strategy(monkeypatch): captured = {} async def fake_post_with_capture(self, url, headers=None, json=None, timeout=None): @@ -956,16 +956,16 @@ async def fake_post_with_capture(self, url, headers=None, json=None, timeout=Non agent._connection = dummy_client agent._headers = dummy_client.additional_headers - # Test with search_strategy set - results = await agent.search("test query", limit=2, search_strategy="precision") + # Test with retrieval_strategy set + results = await agent.search("test query", limit=2, retrieval_strategy="precision") assert isinstance(results, AsyncSearchModeResponse) - assert captured["json"]["search_strategy"] == "precision" + assert captured["json"]["retrieval_strategy"] == "precision" - # Reset captured json, then paginate — search_strategy should persist + # Reset captured json, then paginate — retrieval_strategy should persist captured = {} results_2 = await results.next(limit=2, offset=1) assert isinstance(results_2, AsyncSearchModeResponse) - assert captured["json"]["search_strategy"] == "precision" + assert captured["json"]["retrieval_strategy"] == "precision" async def test_async_search_only_mode_failure(monkeypatch): diff --git a/weaviate_agents/query/classes/request.py b/weaviate_agents/query/classes/request.py index 5fe2e8d..7c1432a 100644 --- a/weaviate_agents/query/classes/request.py +++ b/weaviate_agents/query/classes/request.py @@ -17,7 +17,7 @@ class SearchModeRequestBase(BaseModel): collections: list[Union[str, QueryAgentCollectionConfig]] limit: int offset: int - search_strategy: Literal["recall", "precision"] = "recall" + retrieval_strategy: Literal["recall", "precision"] = "recall" diversity_weight: Optional[float] = None diff --git a/weaviate_agents/query/query_agent.py b/weaviate_agents/query/query_agent.py index 0790a34..7d2d7b8 100644 --- a/weaviate_agents/query/query_agent.py +++ b/weaviate_agents/query/query_agent.py @@ -498,7 +498,7 @@ def search( query: Union[str, list[ChatMessage]], limit: int = 20, collections: Union[list[Union[str, QueryAgentCollectionConfig]], None] = None, - search_strategy: Literal["recall", "precision"] = "recall", + retrieval_strategy: Literal["recall", "precision"] = "recall", diversity_weight: Optional[float] = None, ) -> Union[SearchModeResponse, Coroutine[Any, Any, AsyncSearchModeResponse]]: pass @@ -1014,7 +1014,7 @@ def search( query: Union[str, list[ChatMessage]], limit: int = 20, collections: Union[list[Union[str, QueryAgentCollectionConfig]], None] = None, - search_strategy: Literal["recall", "precision"] = "recall", + retrieval_strategy: Literal["recall", "precision"] = "recall", diversity_weight: Optional[float] = None, ) -> SearchModeResponse: """Run the Query Agent search-only mode. @@ -1029,7 +1029,7 @@ def search( limit: The maximum number of results to return for the first page. collections: The collections to query. Either a list of strings, or a list of :class:`~weaviate_agents.query.classes.QueryAgentCollectionConfig` objects. Overrides any collections provided in the constructor when set. - search_strategy: The search strategy to use for this search. + retrieval_strategy: The retrieval strategy to use for this search. Use "recall" to optimize for finding all relevant results, or "precision" to optimize for the accuracy of returned results. Defaults to "recall". @@ -1071,7 +1071,7 @@ def search( query=query, collections=collections, system_prompt=self._system_prompt, - search_strategy=search_strategy, + retrieval_strategy=retrieval_strategy, diversity_weight=diversity_weight, ) return searcher.run(limit=limit) @@ -1659,7 +1659,7 @@ async def search( query: Union[str, list[ChatMessage]], limit: int = 20, collections: Union[list[Union[str, QueryAgentCollectionConfig]], None] = None, - search_strategy: Literal["recall", "precision"] = "recall", + retrieval_strategy: Literal["recall", "precision"] = "recall", diversity_weight: Optional[float] = None, ) -> AsyncSearchModeResponse: """Run the Query Agent search-only mode. @@ -1675,7 +1675,7 @@ async def search( limit: The maximum number of results to return for the first page. collections: The collections to query. Overrides any collections provided in the constructor when set. - search_strategy: The search strategy to use for this search. + retrieval_strategy: The retrieval strategy to use for this search. Use "recall" to optimize for finding all relevant results, or "precision" to optimize for the accuracy of returned results. Defaults to "recall". @@ -1717,7 +1717,7 @@ async def search( query=query, collections=collections, system_prompt=self._system_prompt, - search_strategy=search_strategy, + retrieval_strategy=retrieval_strategy, diversity_weight=diversity_weight, ) return await searcher.run(limit=limit) diff --git a/weaviate_agents/query/search.py b/weaviate_agents/query/search.py index 7c801b9..7315303 100644 --- a/weaviate_agents/query/search.py +++ b/weaviate_agents/query/search.py @@ -35,7 +35,7 @@ def __init__( query: Union[str, list[ChatMessage]], collections: list[Union[str, QueryAgentCollectionConfig]], system_prompt: Optional[str], - search_strategy: Literal["recall", "precision"] = "recall", + retrieval_strategy: Literal["recall", "precision"] = "recall", diversity_weight: Optional[float] = None, ): self.headers = headers @@ -45,7 +45,7 @@ def __init__( self.query = query self.collections = collections self.system_prompt = system_prompt - self.search_strategy = search_strategy + self.retrieval_strategy = retrieval_strategy self.diversity_weight = diversity_weight self._cached_searches: Optional[list[QueryResultWithCollectionNormalized]] = ( None @@ -65,7 +65,7 @@ def _get_request_body(self, limit: int, offset: int) -> dict[str, Any]: limit=limit, offset=offset, system_prompt=self.system_prompt, - search_strategy=self.search_strategy, + retrieval_strategy=self.retrieval_strategy, diversity_weight=self.diversity_weight, ).model_dump(mode="json") else: @@ -76,7 +76,7 @@ def _get_request_body(self, limit: int, offset: int) -> dict[str, Any]: limit=limit, offset=offset, searches=self._cached_searches, - search_strategy=self.search_strategy, + retrieval_strategy=self.retrieval_strategy, diversity_weight=self.diversity_weight, ).model_dump(mode="json") From e12cb431e78269ce58e32c264bd2f57d2f414411 Mon Sep 17 00:00:00 2001 From: Connor Shorten Date: Tue, 26 May 2026 13:47:46 -0400 Subject: [PATCH 6/9] rename to filtering --- test/query_agent/test_query_model.py | 30 ++++++++++++------------ weaviate_agents/query/classes/request.py | 2 +- weaviate_agents/query/query_agent.py | 14 +++++------ weaviate_agents/query/search.py | 8 +++---- 4 files changed, 27 insertions(+), 27 deletions(-) diff --git a/test/query_agent/test_query_model.py b/test/query_agent/test_query_model.py index da3afcb..f1db0f9 100644 --- a/test/query_agent/test_query_model.py +++ b/test/query_agent/test_query_model.py @@ -797,7 +797,7 @@ def fake_post_with_capture(url, headers=None, json=None, timeout=None): assert captured["json"]["diversity_weight"] is None -def test_search_only_mode_with_retrieval_strategy(monkeypatch): +def test_search_only_mode_with_filtering(monkeypatch): captured = {} def fake_post_with_capture(url, headers=None, json=None, timeout=None): @@ -812,19 +812,19 @@ def fake_post_with_capture(url, headers=None, json=None, timeout=None): agent._connection = dummy_client agent._headers = dummy_client.additional_headers - # Test with retrieval_strategy set - results = agent.search("test query", limit=2, retrieval_strategy="recall") + # Test with filtering set + results = agent.search("test query", limit=2, filtering="recall") assert isinstance(results, SearchModeResponse) - assert captured["json"]["retrieval_strategy"] == "recall" + assert captured["json"]["filtering"] == "recall" - # Reset captured json, then paginate — retrieval_strategy should persist + # Reset captured json, then paginate — filtering should persist captured = {} results_2 = results.next(limit=2, offset=1) assert isinstance(results_2, SearchModeResponse) - assert captured["json"]["retrieval_strategy"] == "recall" + assert captured["json"]["filtering"] == "recall" -def test_search_only_mode_default_retrieval_strategy(monkeypatch): +def test_search_only_mode_default_filtering(monkeypatch): captured = {} def fake_post_with_capture(url, headers=None, json=None, timeout=None): @@ -839,10 +839,10 @@ def fake_post_with_capture(url, headers=None, json=None, timeout=None): agent._connection = dummy_client agent._headers = dummy_client.additional_headers - # Test without retrieval_strategy — should default to "recall" + # Test without filtering — should default to "recall" results = agent.search("test query", limit=2) assert isinstance(results, SearchModeResponse) - assert captured["json"]["retrieval_strategy"] == "recall" + assert captured["json"]["filtering"] == "recall" def test_search_only_mode_failure(monkeypatch): @@ -941,7 +941,7 @@ async def fake_post_with_capture(self, url, headers=None, json=None, timeout=Non assert captured["json"]["diversity_weight"] == 0.7 -async def test_async_search_only_mode_with_retrieval_strategy(monkeypatch): +async def test_async_search_only_mode_with_filtering(monkeypatch): captured = {} async def fake_post_with_capture(self, url, headers=None, json=None, timeout=None): @@ -956,16 +956,16 @@ async def fake_post_with_capture(self, url, headers=None, json=None, timeout=Non agent._connection = dummy_client agent._headers = dummy_client.additional_headers - # Test with retrieval_strategy set - results = await agent.search("test query", limit=2, retrieval_strategy="precision") + # Test with filtering set + results = await agent.search("test query", limit=2, filtering="precision") assert isinstance(results, AsyncSearchModeResponse) - assert captured["json"]["retrieval_strategy"] == "precision" + assert captured["json"]["filtering"] == "precision" - # Reset captured json, then paginate — retrieval_strategy should persist + # Reset captured json, then paginate — filtering should persist captured = {} results_2 = await results.next(limit=2, offset=1) assert isinstance(results_2, AsyncSearchModeResponse) - assert captured["json"]["retrieval_strategy"] == "precision" + assert captured["json"]["filtering"] == "precision" async def test_async_search_only_mode_failure(monkeypatch): diff --git a/weaviate_agents/query/classes/request.py b/weaviate_agents/query/classes/request.py index 7c1432a..416df6a 100644 --- a/weaviate_agents/query/classes/request.py +++ b/weaviate_agents/query/classes/request.py @@ -17,7 +17,7 @@ class SearchModeRequestBase(BaseModel): collections: list[Union[str, QueryAgentCollectionConfig]] limit: int offset: int - retrieval_strategy: Literal["recall", "precision"] = "recall" + filtering: Literal["recall", "precision"] = "recall" diversity_weight: Optional[float] = None diff --git a/weaviate_agents/query/query_agent.py b/weaviate_agents/query/query_agent.py index 7d2d7b8..df9396a 100644 --- a/weaviate_agents/query/query_agent.py +++ b/weaviate_agents/query/query_agent.py @@ -498,7 +498,7 @@ def search( query: Union[str, list[ChatMessage]], limit: int = 20, collections: Union[list[Union[str, QueryAgentCollectionConfig]], None] = None, - retrieval_strategy: Literal["recall", "precision"] = "recall", + filtering: Literal["recall", "precision"] = "recall", diversity_weight: Optional[float] = None, ) -> Union[SearchModeResponse, Coroutine[Any, Any, AsyncSearchModeResponse]]: pass @@ -1014,7 +1014,7 @@ def search( query: Union[str, list[ChatMessage]], limit: int = 20, collections: Union[list[Union[str, QueryAgentCollectionConfig]], None] = None, - retrieval_strategy: Literal["recall", "precision"] = "recall", + filtering: Literal["recall", "precision"] = "recall", diversity_weight: Optional[float] = None, ) -> SearchModeResponse: """Run the Query Agent search-only mode. @@ -1029,7 +1029,7 @@ def search( limit: The maximum number of results to return for the first page. collections: The collections to query. Either a list of strings, or a list of :class:`~weaviate_agents.query.classes.QueryAgentCollectionConfig` objects. Overrides any collections provided in the constructor when set. - retrieval_strategy: The retrieval strategy to use for this search. + filtering: The filtering strategy to use for this search. Use "recall" to optimize for finding all relevant results, or "precision" to optimize for the accuracy of returned results. Defaults to "recall". @@ -1071,7 +1071,7 @@ def search( query=query, collections=collections, system_prompt=self._system_prompt, - retrieval_strategy=retrieval_strategy, + filtering=filtering, diversity_weight=diversity_weight, ) return searcher.run(limit=limit) @@ -1659,7 +1659,7 @@ async def search( query: Union[str, list[ChatMessage]], limit: int = 20, collections: Union[list[Union[str, QueryAgentCollectionConfig]], None] = None, - retrieval_strategy: Literal["recall", "precision"] = "recall", + filtering: Literal["recall", "precision"] = "recall", diversity_weight: Optional[float] = None, ) -> AsyncSearchModeResponse: """Run the Query Agent search-only mode. @@ -1675,7 +1675,7 @@ async def search( limit: The maximum number of results to return for the first page. collections: The collections to query. Overrides any collections provided in the constructor when set. - retrieval_strategy: The retrieval strategy to use for this search. + filtering: The filtering strategy to use for this search. Use "recall" to optimize for finding all relevant results, or "precision" to optimize for the accuracy of returned results. Defaults to "recall". @@ -1717,7 +1717,7 @@ async def search( query=query, collections=collections, system_prompt=self._system_prompt, - retrieval_strategy=retrieval_strategy, + filtering=filtering, diversity_weight=diversity_weight, ) return await searcher.run(limit=limit) diff --git a/weaviate_agents/query/search.py b/weaviate_agents/query/search.py index 7315303..94ee72e 100644 --- a/weaviate_agents/query/search.py +++ b/weaviate_agents/query/search.py @@ -35,7 +35,7 @@ def __init__( query: Union[str, list[ChatMessage]], collections: list[Union[str, QueryAgentCollectionConfig]], system_prompt: Optional[str], - retrieval_strategy: Literal["recall", "precision"] = "recall", + filtering: Literal["recall", "precision"] = "recall", diversity_weight: Optional[float] = None, ): self.headers = headers @@ -45,7 +45,7 @@ def __init__( self.query = query self.collections = collections self.system_prompt = system_prompt - self.retrieval_strategy = retrieval_strategy + self.filtering = filtering self.diversity_weight = diversity_weight self._cached_searches: Optional[list[QueryResultWithCollectionNormalized]] = ( None @@ -65,7 +65,7 @@ def _get_request_body(self, limit: int, offset: int) -> dict[str, Any]: limit=limit, offset=offset, system_prompt=self.system_prompt, - retrieval_strategy=self.retrieval_strategy, + filtering=self.filtering, diversity_weight=self.diversity_weight, ).model_dump(mode="json") else: @@ -76,7 +76,7 @@ def _get_request_body(self, limit: int, offset: int) -> dict[str, Any]: limit=limit, offset=offset, searches=self._cached_searches, - retrieval_strategy=self.retrieval_strategy, + filtering=self.filtering, diversity_weight=self.diversity_weight, ).model_dump(mode="json") From e304497960bb17aa0f357ae36b9f98d78f5860a7 Mon Sep 17 00:00:00 2001 From: Connor Shorten Date: Thu, 28 May 2026 08:38:24 -0400 Subject: [PATCH 7/9] remove default in request --- weaviate_agents/query/classes/request.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/weaviate_agents/query/classes/request.py b/weaviate_agents/query/classes/request.py index 416df6a..a7089bd 100644 --- a/weaviate_agents/query/classes/request.py +++ b/weaviate_agents/query/classes/request.py @@ -17,7 +17,7 @@ class SearchModeRequestBase(BaseModel): collections: list[Union[str, QueryAgentCollectionConfig]] limit: int offset: int - filtering: Literal["recall", "precision"] = "recall" + filtering: Literal["recall", "precision"] diversity_weight: Optional[float] = None From 0150f0995b7246d6f4d0c7675caceacf034d44c8 Mon Sep 17 00:00:00 2001 From: Connor Shorten Date: Thu, 28 May 2026 10:18:11 -0400 Subject: [PATCH 8/9] make filtering optional client-side --- test/query_agent/test_query_model.py | 4 ++-- weaviate_agents/query/classes/request.py | 2 +- weaviate_agents/query/query_agent.py | 8 +++----- weaviate_agents/query/search.py | 2 +- 4 files changed, 7 insertions(+), 9 deletions(-) diff --git a/test/query_agent/test_query_model.py b/test/query_agent/test_query_model.py index f1db0f9..02eb7bc 100644 --- a/test/query_agent/test_query_model.py +++ b/test/query_agent/test_query_model.py @@ -839,10 +839,10 @@ def fake_post_with_capture(url, headers=None, json=None, timeout=None): agent._connection = dummy_client agent._headers = dummy_client.additional_headers - # Test without filtering — should default to "recall" + # Test without filtering — should default to None results = agent.search("test query", limit=2) assert isinstance(results, SearchModeResponse) - assert captured["json"]["filtering"] == "recall" + assert captured["json"]["filtering"] is None def test_search_only_mode_failure(monkeypatch): diff --git a/weaviate_agents/query/classes/request.py b/weaviate_agents/query/classes/request.py index a7089bd..1247aa7 100644 --- a/weaviate_agents/query/classes/request.py +++ b/weaviate_agents/query/classes/request.py @@ -17,7 +17,7 @@ class SearchModeRequestBase(BaseModel): collections: list[Union[str, QueryAgentCollectionConfig]] limit: int offset: int - filtering: Literal["recall", "precision"] + filtering: Optional[Literal["recall", "precision"]] = None diversity_weight: Optional[float] = None diff --git a/weaviate_agents/query/query_agent.py b/weaviate_agents/query/query_agent.py index df9396a..8dd41c5 100644 --- a/weaviate_agents/query/query_agent.py +++ b/weaviate_agents/query/query_agent.py @@ -498,7 +498,7 @@ def search( query: Union[str, list[ChatMessage]], limit: int = 20, collections: Union[list[Union[str, QueryAgentCollectionConfig]], None] = None, - filtering: Literal["recall", "precision"] = "recall", + filtering: Optional[Literal["recall", "precision"]] = None, diversity_weight: Optional[float] = None, ) -> Union[SearchModeResponse, Coroutine[Any, Any, AsyncSearchModeResponse]]: pass @@ -1014,7 +1014,7 @@ def search( query: Union[str, list[ChatMessage]], limit: int = 20, collections: Union[list[Union[str, QueryAgentCollectionConfig]], None] = None, - filtering: Literal["recall", "precision"] = "recall", + filtering: Optional[Literal["recall", "precision"]] = None, diversity_weight: Optional[float] = None, ) -> SearchModeResponse: """Run the Query Agent search-only mode. @@ -1032,7 +1032,6 @@ def search( filtering: The filtering strategy to use for this search. Use "recall" to optimize for finding all relevant results, or "precision" to optimize for the accuracy of returned results. - Defaults to "recall". diversity_weight: Optional float between 0.0 and 1.0 to diversify results with MMR reranking. Higher values push for more topical variety at the cost of relevance. @@ -1659,7 +1658,7 @@ async def search( query: Union[str, list[ChatMessage]], limit: int = 20, collections: Union[list[Union[str, QueryAgentCollectionConfig]], None] = None, - filtering: Literal["recall", "precision"] = "recall", + filtering: Optional[Literal["recall", "precision"]] = None, diversity_weight: Optional[float] = None, ) -> AsyncSearchModeResponse: """Run the Query Agent search-only mode. @@ -1678,7 +1677,6 @@ async def search( filtering: The filtering strategy to use for this search. Use "recall" to optimize for finding all relevant results, or "precision" to optimize for the accuracy of returned results. - Defaults to "recall". diversity_weight: Optional float between 0.0 and 1.0 to diversify results with MMR reranking. Higher values push for more topical variety at the cost of relevance. diff --git a/weaviate_agents/query/search.py b/weaviate_agents/query/search.py index 94ee72e..6a2feb4 100644 --- a/weaviate_agents/query/search.py +++ b/weaviate_agents/query/search.py @@ -35,7 +35,7 @@ def __init__( query: Union[str, list[ChatMessage]], collections: list[Union[str, QueryAgentCollectionConfig]], system_prompt: Optional[str], - filtering: Literal["recall", "precision"] = "recall", + filtering: Optional[Literal["recall", "precision"]] = None, diversity_weight: Optional[float] = None, ): self.headers = headers From 5acc6641d130d11addffd6b5712e595fca157ccb Mon Sep 17 00:00:00 2001 From: Connor Shorten Date: Thu, 28 May 2026 10:23:26 -0400 Subject: [PATCH 9/9] add comment about default recall --- weaviate_agents/query/query_agent.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/weaviate_agents/query/query_agent.py b/weaviate_agents/query/query_agent.py index 8dd41c5..7f0756c 100644 --- a/weaviate_agents/query/query_agent.py +++ b/weaviate_agents/query/query_agent.py @@ -1032,6 +1032,7 @@ def search( filtering: The filtering strategy to use for this search. Use "recall" to optimize for finding all relevant results, or "precision" to optimize for the accuracy of returned results. + Defaults to "recall". diversity_weight: Optional float between 0.0 and 1.0 to diversify results with MMR reranking. Higher values push for more topical variety at the cost of relevance. @@ -1677,6 +1678,7 @@ async def search( filtering: The filtering strategy to use for this search. Use "recall" to optimize for finding all relevant results, or "precision" to optimize for the accuracy of returned results. + Defaults to "recall". diversity_weight: Optional float between 0.0 and 1.0 to diversify results with MMR reranking. Higher values push for more topical variety at the cost of relevance.