Skip to content

Commit 730ba92

Browse files
authored
Merge pull request #61 from vectorlessflow/dev
Dev
2 parents b0aea5b + 2595b07 commit 730ba92

58 files changed

Lines changed: 1418 additions & 1116 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

config.example.toml

Lines changed: 0 additions & 254 deletions
This file was deleted.

python/src/lib.rs

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ use ::vectorless::client::{
1515
};
1616
use ::vectorless::error::Error as RustError;
1717
use ::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>()?;

python/vectorless/__init__.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,11 @@
2626
IndexOptions,
2727
IndexResult,
2828
IndexItem,
29+
IndexMetrics,
2930
QueryContext,
3031
QueryResult,
3132
QueryResultItem,
33+
StrategyPreference,
3234
DocumentInfo,
3335
DocumentGraph,
3436
DocumentGraphNode,
@@ -46,9 +48,11 @@
4648
"IndexOptions",
4749
"IndexResult",
4850
"IndexItem",
51+
"IndexMetrics",
4952
"QueryContext",
5053
"QueryResult",
5154
"QueryResultItem",
55+
"StrategyPreference",
5256
"DocumentInfo",
5357
"DocumentGraph",
5458
"DocumentGraphNode",

0 commit comments

Comments
 (0)