Skip to content

Commit 5d7d85a

Browse files
authored
Merge pull request #96 from vectorlessflow/dev
Dev
2 parents 99bb2c2 + f44fdbe commit 5d7d85a

24 files changed

Lines changed: 47 additions & 732 deletions

File tree

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ members = ["rust", "python"]
33
resolver = "2"
44

55
[workspace.package]
6-
version = "0.1.30"
6+
version = "0.1.31"
77
edition = "2024"
88
authors = ["zTgx <beautifularea@gmail.com>"]
99
license = "Apache-2.0"

README.md

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
<img src="https://vectorless.dev/img/with-title.png" alt="Vectorless" width="400">
44

5-
<h1>Document Engine for AI</h1>
5+
<h1>Agentic-based Document Engine</h1>
66

77
[![PyPI](https://img.shields.io/pypi/v/vectorless.svg)](https://pypi.org/project/vectorless/)
88
[![PyPI Downloads](https://static.pepy.tech/badge/vectorless/month)](https://pepy.tech/projects/vectorless)
@@ -13,11 +13,9 @@
1313

1414
</div>
1515

16-
**Vectorless** is a reasoning-native document engine with the core written in Rust. It will reason through any of your structured documents — **PDFs, Markdown, reports, contracts** — and retrieve only what's relevant. Nothing more, nothing less.
16+
**Reason, don't vector.**
1717

18-
- **Reason, don't vector.** — Retrieval is guided by reasoning over document structure.
19-
- **Model fails, we fail.** — No silent degradation. No heuristic fallbacks.
20-
- **No thought, no answer.** — Only LLM-reasoned output counts as an answer.
18+
**Vectorless** is an agentic-based document engine with the core written in Rust. It will reason through any of your structured documents — **PDFs, Markdown, reports, contracts** — and retrieve only what's relevant. Nothing more, nothing less.
2119

2220

2321
## Quick Start

docs/docs/sdk/python.mdx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -111,9 +111,8 @@ answer = await engine.query(
111111
answer = await engine.query(
112112
QueryContext("Explain the architecture")
113113
.with_doc_ids([doc_id])
114-
.with_max_tokens(4000) # Max tokens in result
115-
.with_include_reasoning(True) # Include reasoning chain
116-
.with_depth_limit(10) # Max traversal depth
114+
.with_timeout_secs(60) # Per-operation timeout
115+
.with_force_analysis(True) # Force Orchestrator analysis
117116
)
118117
```
119118

docs/docs/sdk/rust.mdx

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,14 +52,11 @@ let result = engine.index(
5252

5353
```rust
5454
use vectorless::QueryContext;
55-
use vectorless::StrategyPreference;
5655

5756
let result = engine.query(
5857
QueryContext::new("What is the total revenue?")
5958
.with_doc_ids(vec![doc_id.to_string()])
60-
.with_strategy(StrategyPreference::ForceHybrid)
61-
.with_max_tokens(4000)
62-
.with_include_reasoning(true)
59+
.with_timeout_secs(60)
6360
).await?;
6461

6562
if let Some(item) = result.single() {

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "maturin"
44

55
[project]
66
name = "vectorless"
7-
version = "0.1.9"
7+
version = "0.1.10"
88
description = "Reasoning-native document intelligence engine for AI"
99
readme = "README.md"
1010
requires-python = ">=3.9"

python/README.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -116,9 +116,8 @@ class QueryContext:
116116

117117
def with_doc_ids(self, doc_ids: list[str]) -> QueryContext: ...
118118
def with_workspace(self) -> QueryContext: ...
119-
def with_max_tokens(self, tokens: int) -> QueryContext: ...
120-
def with_include_reasoning(self, include: bool) -> QueryContext: ...
121-
def with_depth_limit(self, depth: int) -> QueryContext: ...
119+
def with_timeout_secs(self, secs: int) -> QueryContext: ...
120+
def with_force_analysis(self, force: bool) -> QueryContext: ...
122121
```
123122

124123
### IndexResult

python/src/context.rs

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,14 @@ pub struct PyIndexOptions {
4444
#[pymethods]
4545
impl PyIndexOptions {
4646
#[new]
47-
#[pyo3(signature = (mode="default", generate_summaries=true, generate_description=false, generate_ids=true, enable_synonym_expansion=false))]
47+
#[pyo3(signature = (mode="default", generate_summaries=true, generate_description=false, generate_ids=true, enable_synonym_expansion=true, timeout_secs=None))]
4848
fn new(
4949
mode: &str,
5050
generate_summaries: bool,
5151
generate_description: bool,
5252
generate_ids: bool,
5353
enable_synonym_expansion: bool,
54+
timeout_secs: Option<u64>,
5455
) -> PyResult<Self> {
5556
let mut opts = IndexOptions::new();
5657
match mode {
@@ -71,6 +72,9 @@ impl PyIndexOptions {
7172
opts.generate_description = generate_description;
7273
opts.generate_ids = generate_ids;
7374
opts.enable_synonym_expansion = enable_synonym_expansion;
75+
if let Some(secs) = timeout_secs {
76+
opts = opts.with_timeout_secs(secs);
77+
}
7478
Ok(Self { inner: opts })
7579
}
7680

@@ -260,9 +264,15 @@ impl PyQueryContext {
260264
Self { inner: ctx }
261265
}
262266

263-
/// Set the maximum tokens for the result content.
264-
fn with_max_tokens(&self, tokens: usize) -> Self {
265-
let ctx = self.inner.clone().with_max_tokens(tokens);
267+
/// Set per-operation timeout in seconds.
268+
fn with_timeout_secs(&self, secs: u64) -> Self {
269+
let ctx = self.inner.clone().with_timeout_secs(secs);
270+
Self { inner: ctx }
271+
}
272+
273+
/// Force the Orchestrator to analyze documents before dispatching Workers.
274+
fn with_force_analysis(&self, force: bool) -> Self {
275+
let ctx = self.inner.clone().with_force_analysis(force);
266276
Self { inner: ctx }
267277
}
268278

python/src/lib.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,7 @@ use document::PyDocumentInfo;
2020
use engine::PyEngine;
2121
use error::VectorlessError;
2222
use graph::{PyDocumentGraph, PyDocumentGraphNode, PyEdgeEvidence, PyGraphEdge, PyWeightedKeyword};
23-
use metrics::{
24-
PyLlmMetricsReport, PyMetricsReport, PyPilotMetricsReport, PyRetrievalMetricsReport,
25-
};
23+
use metrics::{PyLlmMetricsReport, PyMetricsReport, PyRetrievalMetricsReport};
2624
use results::{
2725
PyEvidenceItem, PyFailedItem, PyIndexItem, PyIndexMetrics, PyIndexResult, PyQueryMetrics,
2826
PyQueryResult, PyQueryResultItem,
@@ -59,7 +57,6 @@ fn _vectorless(m: &Bound<'_, PyModule>) -> PyResult<()> {
5957
m.add_class::<PyEdgeEvidence>()?;
6058
m.add_class::<PyWeightedKeyword>()?;
6159
m.add_class::<PyLlmMetricsReport>()?;
62-
m.add_class::<PyPilotMetricsReport>()?;
6360
m.add_class::<PyRetrievalMetricsReport>()?;
6461
m.add_class::<PyMetricsReport>()?;
6562
m.add_class::<PyConfig>()?;

python/src/metrics.rs

Lines changed: 1 addition & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
66
use pyo3::prelude::*;
77

8-
use ::vectorless::{LlmMetricsReport, MetricsReport, PilotMetricsReport, RetrievalMetricsReport};
8+
use ::vectorless::{LlmMetricsReport, MetricsReport, RetrievalMetricsReport};
99

1010
/// LLM usage metrics report.
1111
#[pyclass(name = "LlmMetricsReport")]
@@ -101,106 +101,6 @@ impl PyLlmMetricsReport {
101101
}
102102
}
103103

104-
/// Pilot decision metrics report.
105-
#[pyclass(name = "PilotMetricsReport")]
106-
pub struct PyPilotMetricsReport {
107-
pub(crate) inner: PilotMetricsReport,
108-
}
109-
110-
#[pymethods]
111-
impl PyPilotMetricsReport {
112-
/// Total number of Pilot decisions.
113-
#[getter]
114-
fn total_decisions(&self) -> u64 {
115-
self.inner.total_decisions
116-
}
117-
118-
/// Number of start guidance calls.
119-
#[getter]
120-
fn start_guidance_calls(&self) -> u64 {
121-
self.inner.start_guidance_calls
122-
}
123-
124-
/// Number of fork decisions.
125-
#[getter]
126-
fn fork_decisions(&self) -> u64 {
127-
self.inner.fork_decisions
128-
}
129-
130-
/// Number of backtrack calls.
131-
#[getter]
132-
fn backtrack_calls(&self) -> u64 {
133-
self.inner.backtrack_calls
134-
}
135-
136-
/// Number of evaluate calls.
137-
#[getter]
138-
fn evaluate_calls(&self) -> u64 {
139-
self.inner.evaluate_calls
140-
}
141-
142-
/// Decision accuracy based on feedback (0.0 - 1.0).
143-
#[getter]
144-
fn accuracy(&self) -> f64 {
145-
self.inner.accuracy
146-
}
147-
148-
/// Number of correct decisions.
149-
#[getter]
150-
fn correct_decisions(&self) -> u64 {
151-
self.inner.correct_decisions
152-
}
153-
154-
/// Number of incorrect decisions.
155-
#[getter]
156-
fn incorrect_decisions(&self) -> u64 {
157-
self.inner.incorrect_decisions
158-
}
159-
160-
/// Average confidence across all decisions.
161-
#[getter]
162-
fn avg_confidence(&self) -> f64 {
163-
self.inner.avg_confidence
164-
}
165-
166-
/// Number of LLM calls made by Pilot.
167-
#[getter]
168-
fn llm_calls(&self) -> u64 {
169-
self.inner.llm_calls
170-
}
171-
172-
/// Number of interventions.
173-
#[getter]
174-
fn interventions(&self) -> u64 {
175-
self.inner.interventions
176-
}
177-
178-
/// Number of skipped interventions.
179-
#[getter]
180-
fn skipped_interventions(&self) -> u64 {
181-
self.inner.skipped_interventions
182-
}
183-
184-
/// Number of budget exhausted events.
185-
#[getter]
186-
fn budget_exhausted(&self) -> u64 {
187-
self.inner.budget_exhausted
188-
}
189-
190-
/// Number of algorithm fallbacks.
191-
#[getter]
192-
fn algorithm_fallbacks(&self) -> u64 {
193-
self.inner.algorithm_fallbacks
194-
}
195-
196-
fn __repr__(&self) -> String {
197-
format!(
198-
"PilotMetricsReport(decisions={}, accuracy={:.2}, avg_confidence={:.2})",
199-
self.inner.total_decisions, self.inner.accuracy, self.inner.avg_confidence,
200-
)
201-
}
202-
}
203-
204104
/// Retrieval operation metrics report.
205105
#[pyclass(name = "RetrievalMetricsReport")]
206106
pub struct PyRetrievalMetricsReport {
@@ -337,14 +237,6 @@ impl PyMetricsReport {
337237
}
338238
}
339239

340-
/// Pilot metrics.
341-
#[getter]
342-
fn pilot(&self) -> PyPilotMetricsReport {
343-
PyPilotMetricsReport {
344-
inner: self.inner.pilot.clone(),
345-
}
346-
}
347-
348240
/// Retrieval metrics.
349241
#[getter]
350242
fn retrieval(&self) -> PyRetrievalMetricsReport {

python/vectorless/cli/commands/query.py

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ def query_cmd(
1212
workspace_scope: bool = False,
1313
fmt: str = "text",
1414
verbose: bool = False,
15-
max_tokens: Optional[int] = None,
15+
timeout_secs: Optional[int] = None,
1616
) -> None:
1717
"""Execute a single query against indexed documents.
1818
@@ -22,19 +22,12 @@ def query_cmd(
2222
workspace_scope: Query across all documents.
2323
fmt: Output format — "text" or "json".
2424
verbose: Show Agent navigation steps.
25-
max_tokens: Max result tokens.
25+
timeout_secs: Per-operation timeout in seconds.
2626
2727
Uses:
2828
Engine.query(QueryContext(question)
2929
.with_doc_ids([...]) or .with_workspace()
30-
.with_max_tokens(n))
30+
.with_timeout_secs(n))
3131
-> QueryResult
32-
33-
Verbose mode prints Agent navigation:
34-
[1/8] Bird's-eye: 3 top-level branches
35-
[2/8] Descend → payment-configuration
36-
[3/8] GetContent → doc 29139b
37-
[4/8] Evaluate → sufficient
38-
→ Answer: ...
3932
"""
4033
raise NotImplementedError

0 commit comments

Comments
 (0)