@@ -15,6 +15,7 @@ use ::vectorless::client::{
1515} ;
1616use :: vectorless:: error:: Error as RustError ;
1717use :: vectorless:: metrics:: IndexMetrics ;
18+ use :: vectorless:: StrategyPreference ;
1819
1920// ============================================================
2021// Error Types
@@ -266,6 +267,83 @@ impl PyIndexContext {
266267 }
267268}
268269
270+ // ============================================================
271+ // StrategyPreference
272+ // ============================================================
273+
274+ /// Retrieval strategy preference.
275+ ///
276+ /// Controls how the engine searches the document tree.
277+ ///
278+ /// ```python
279+ /// from vectorless import QueryContext, StrategyPreference
280+ ///
281+ /// # Force keyword-only (fastest, no LLM calls during search)
282+ /// ctx = QueryContext("revenue").with_doc_id(doc_id).with_strategy(StrategyPreference.KEYWORD)
283+ ///
284+ /// # Force LLM-guided navigation (most accurate, uses more tokens)
285+ /// ctx = QueryContext("explain the architecture").with_doc_id(doc_id).with_strategy(StrategyPreference.LLM)
286+ ///
287+ /// # Force hybrid (BM25 + LLM refinement)
288+ /// ctx = QueryContext("growth trends").with_doc_id(doc_id).with_strategy(StrategyPreference.HYBRID)
289+ /// ```
290+ #[ pyclass( name = "StrategyPreference" , skip_from_py_object) ]
291+ #[ derive( Clone ) ]
292+ pub struct PyStrategyPreference {
293+ inner : StrategyPreference ,
294+ }
295+
296+ #[ pymethods]
297+ impl PyStrategyPreference {
298+ /// Auto-select based on query complexity (default).
299+ #[ classattr]
300+ const AUTO : PyStrategyPreference = PyStrategyPreference {
301+ inner : StrategyPreference :: Auto ,
302+ } ;
303+
304+ /// Force keyword-based strategy (fast, no LLM during search).
305+ #[ classattr]
306+ const KEYWORD : PyStrategyPreference = PyStrategyPreference {
307+ inner : StrategyPreference :: ForceKeyword ,
308+ } ;
309+
310+ /// Force LLM-guided navigation (deep reasoning).
311+ #[ classattr]
312+ const LLM : PyStrategyPreference = PyStrategyPreference {
313+ inner : StrategyPreference :: ForceLlm ,
314+ } ;
315+
316+ /// Force hybrid strategy (BM25 + LLM refinement).
317+ #[ classattr]
318+ const HYBRID : PyStrategyPreference = PyStrategyPreference {
319+ inner : StrategyPreference :: ForceHybrid ,
320+ } ;
321+
322+ /// Force cross-document strategy (multi-document retrieval).
323+ #[ classattr]
324+ const CROSS_DOCUMENT : PyStrategyPreference = PyStrategyPreference {
325+ inner : StrategyPreference :: ForceCrossDocument ,
326+ } ;
327+
328+ /// Force page-range strategy (filter by page range).
329+ #[ classattr]
330+ const PAGE_RANGE : PyStrategyPreference = PyStrategyPreference {
331+ inner : StrategyPreference :: ForcePageRange ,
332+ } ;
333+
334+ fn __repr__ ( & self ) -> String {
335+ let name = match self . inner {
336+ StrategyPreference :: Auto => "AUTO" ,
337+ StrategyPreference :: ForceKeyword => "KEYWORD" ,
338+ StrategyPreference :: ForceLlm => "LLM" ,
339+ StrategyPreference :: ForceHybrid => "HYBRID" ,
340+ StrategyPreference :: ForceCrossDocument => "CROSS_DOCUMENT" ,
341+ StrategyPreference :: ForcePageRange => "PAGE_RANGE" ,
342+ } ;
343+ format ! ( "StrategyPreference.{}" , name)
344+ }
345+ }
346+
269347// ============================================================
270348// QueryContext
271349// ============================================================
@@ -335,6 +413,15 @@ impl PyQueryContext {
335413 Self { inner : ctx }
336414 }
337415
416+ /// Set the retrieval strategy.
417+ ///
418+ /// Args:
419+ /// strategy: A StrategyPreference constant, e.g. StrategyPreference.LLM.
420+ fn with_strategy ( & self , strategy : & PyStrategyPreference ) -> Self {
421+ let ctx = self . inner . clone ( ) . with_strategy ( strategy. inner ) ;
422+ Self { inner : ctx }
423+ }
424+
338425 fn __repr__ ( & self ) -> String {
339426 "QueryContext(...)" . to_string ( )
340427 }
@@ -1169,6 +1256,7 @@ fn _vectorless(m: &Bound<'_, PyModule>) -> PyResult<()> {
11691256 m. add_class :: < VectorlessError > ( ) ?;
11701257 m. add_class :: < PyIndexOptions > ( ) ?;
11711258 m. add_class :: < PyIndexContext > ( ) ?;
1259+ m. add_class :: < PyStrategyPreference > ( ) ?;
11721260 m. add_class :: < PyQueryContext > ( ) ?;
11731261 m. add_class :: < PyIndexResult > ( ) ?;
11741262 m. add_class :: < PyIndexItem > ( ) ?;
0 commit comments