Skip to content
Merged

Dev #45

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,19 +24,17 @@
pip install vectorless
```

### Set your API key

```bash
export OPENAI_API_KEY="sk-..."
```

### Index and Query

```python
from vectorless import Engine, IndexContext

# Create engine with a workspace directory
engine = Engine(workspace="./data")
# Create engine — api_key and model are required
engine = Engine(
workspace="./data",
api_key="sk-...",
model="gpt-4o",
)

# Index a document (PDF or Markdown)
result = engine.index(IndexContext.from_file("./report.pdf"))
Expand All @@ -63,6 +61,8 @@ use vectorless::client::{EngineBuilder, IndexContext, QueryContext};
async fn main() -> vectorless::Result<()> {
let engine = EngineBuilder::new()
.with_workspace("./data")
.with_key("sk-...")
.with_model("gpt-4o")
.build()
.await?;

Expand Down
50 changes: 19 additions & 31 deletions python/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -452,32 +452,29 @@ impl PyDocumentInfo {

/// The main vectorless engine.
///
/// Configuration priority (later overrides earlier):
/// 1. Default configuration
/// 2. Explicit config file (config_path parameter)
/// 3. Environment variables (OPENAI_API_KEY, VECTORLESS_MODEL, etc.)
/// 4. Constructor parameters (api_key, model, endpoint) - highest priority
/// `api_key` and `model` are **required**.
///
/// # Zero Configuration (Recommended)
///
/// Just set OPENAI_API_KEY environment variable:
/// # Example
///
/// ```python
/// from vectorless import Engine
///
/// engine = Engine(workspace="./data")
/// ```
///
/// # With Custom Model
///
/// ```python
/// engine = Engine(workspace="./data", model="gpt-4o-mini")
/// engine = Engine(
/// workspace="./data",
/// api_key="sk-...",
/// model="gpt-4o",
/// )
/// ```
///
/// # With Config File (Advanced)
/// # With Custom Endpoint
///
/// ```python
/// engine = Engine(workspace="./data", config_path="./vectorless.toml")
/// engine = Engine(
/// workspace="./data",
/// api_key="sk-...",
/// model="deepseek-chat",
/// endpoint="https://api.deepseek.com/v1",
/// )
/// ```
#[pyclass(name = "Engine")]
pub struct PyEngine {
Expand All @@ -492,18 +489,12 @@ impl PyEngine {
/// Args:
/// workspace: Path to the workspace directory (optional if config_path provides it).
/// config_path: Path to configuration file (optional, advanced usage).
/// api_key: Optional API key. If not provided, uses OPENAI_API_KEY env var.
/// model: Optional model name. Default: "gpt-4o".
/// endpoint: Optional API endpoint.
///
/// Configuration priority (later overrides earlier):
/// 1. Default configuration
/// 2. config_path parameter (if provided)
/// 3. Environment variables (OPENAI_API_KEY, VECTORLESS_MODEL, etc.)
/// 4. Constructor parameters (api_key, model, endpoint)
/// api_key: **Required**. LLM API key.
/// model: **Required**. LLM model name (e.g., "gpt-4o", "deepseek-chat").
/// endpoint: Optional API endpoint (e.g., "https://api.deepseek.com/v1").
///
/// Raises:
/// VectorlessError: If engine creation fails.
/// VectorlessError: If engine creation fails (missing api_key/model, workspace error, etc.).
#[new]
#[pyo3(signature = (workspace=None, config_path=None, api_key=None, model=None, endpoint=None))]
fn new(
Expand All @@ -520,9 +511,6 @@ impl PyEngine {
))
})?;

// Resolve API key: explicit > env var
let resolved_api_key = api_key.or_else(|| std::env::var("OPENAI_API_KEY").ok());

let engine = rt.block_on(async {
let mut builder = EngineBuilder::new();

Expand All @@ -544,7 +532,7 @@ impl PyEngine {
builder = builder.with_endpoint(e);
}

if let Some(key) = resolved_api_key {
if let Some(key) = api_key {
builder = builder.with_key(key);
}

Expand Down
Loading