Metadata-Version: 2.4
Name: quaerium
Version: 0.4.1
Summary: Quaerium: RAG framework (vector + graph stores) and a LangGraph agents kernel with a human approval gate
Author-email: Gianmarco Mottola <gianmarcomottola00@gmail.com>
License: MIT
Project-URL: Homepage, https://github.com/gmottola00/quaerium
Project-URL: Documentation, https://gmottola00.github.io/quaerium/
Project-URL: Repository, https://github.com/gmottola00/quaerium
Project-URL: Issues, https://github.com/gmottola00/quaerium/issues
Keywords: rag,retrieval,llm,vector-search,graph-rag,neo4j,milvus,embeddings,knowledge-graph,agents,langgraph,anthropic
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Requires-Python: <3.14,>=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: pydantic<3.0.0,>=2.0.0
Requires-Dist: pydantic-settings<3.0.0,>=2.0.0
Provides-Extra: milvus
Requires-Dist: pymilvus<3.0.0,>=2.3.0; extra == "milvus"
Provides-Extra: qdrant
Requires-Dist: qdrant-client>=1.7.0; extra == "qdrant"
Provides-Extra: chroma
Requires-Dist: chromadb>=0.4.0; extra == "chroma"
Provides-Extra: neo4j
Requires-Dist: neo4j>=5.0.0; extra == "neo4j"
Provides-Extra: supabase
Requires-Dist: supabase>=2.0.0; extra == "supabase"
Provides-Extra: ollama
Requires-Dist: requests>=2.31.0; extra == "ollama"
Provides-Extra: openai
Requires-Dist: openai<2.0.0,>=1.0.0; extra == "openai"
Provides-Extra: pdf
Requires-Dist: pymupdf>=1.23.0; extra == "pdf"
Requires-Dist: pdfplumber>=0.10.0; extra == "pdf"
Requires-Dist: ftfy>=6.1.0; extra == "pdf"
Requires-Dist: charset-normalizer>=3.0.0; extra == "pdf"
Provides-Extra: docx
Requires-Dist: python-docx>=1.1.0; extra == "docx"
Requires-Dist: ftfy>=6.1.0; extra == "docx"
Requires-Dist: charset-normalizer>=3.0.0; extra == "docx"
Provides-Extra: lang
Requires-Dist: lingua-language-detector>=2.0.0; extra == "lang"
Provides-Extra: agents
Requires-Dist: anthropic>=0.75.0; extra == "agents"
Requires-Dist: langgraph>=0.2.60; extra == "agents"
Requires-Dist: structlog>=24.4.0; extra == "agents"
Provides-Extra: agents-postgres
Requires-Dist: quaerium[agents]; extra == "agents-postgres"
Requires-Dist: langgraph-checkpoint-postgres>=2.0.0; extra == "agents-postgres"
Requires-Dist: psycopg[binary,pool]>=3.2.0; extra == "agents-postgres"
Provides-Extra: agents-redis
Requires-Dist: quaerium[agents]; extra == "agents-redis"
Requires-Dist: redis>=5.2.0; extra == "agents-redis"
Provides-Extra: server
Requires-Dist: quaerium[agents]; extra == "server"
Requires-Dist: fastapi>=0.115.0; extra == "server"
Requires-Dist: sse-starlette>=2.1.0; extra == "server"
Provides-Extra: dev
Requires-Dist: pytest>=8.0.0; extra == "dev"
Requires-Dist: pytest-asyncio>=0.23.0; extra == "dev"
Requires-Dist: pytest-cov>=4.1.0; extra == "dev"
Requires-Dist: pytest-benchmark>=4.0.0; extra == "dev"
Requires-Dist: httpx>=0.27.0; extra == "dev"
Requires-Dist: mypy>=1.8.0; extra == "dev"
Requires-Dist: ruff>=0.1.0; extra == "dev"
Requires-Dist: black>=24.0.0; extra == "dev"
Requires-Dist: isort>=5.13.0; extra == "dev"
Provides-Extra: docs
Requires-Dist: mkdocs>=1.6.0; extra == "docs"
Requires-Dist: mkdocs-material>=9.5.0; extra == "docs"
Requires-Dist: mkdocs-git-revision-date-localized-plugin>=1.2.0; extra == "docs"
Requires-Dist: mkdocs-glightbox>=0.4.0; extra == "docs"
Requires-Dist: mkdocs-minify-plugin>=0.8.0; extra == "docs"
Requires-Dist: mkdocstrings[python]>=0.24.0; extra == "docs"
Provides-Extra: all
Requires-Dist: quaerium[agents-postgres,agents-redis,chroma,docx,lang,milvus,neo4j,ollama,openai,pdf,qdrant,server,supabase]; extra == "all"
Dynamic: license-file

# 🏛️ Quaerium

[![Python 3.11+](https://img.shields.io/badge/python-3.11+-blue.svg)](https://www.python.org/downloads/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![Tests](https://img.shields.io/badge/tests-27%20passed-success.svg)](https://github.com/gmottola00/quaerium)
[![Coverage](https://img.shields.io/badge/coverage-76%25-brightgreen.svg)](https://github.com/gmottola00/quaerium)
[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
[![Documentation](https://img.shields.io/badge/docs-online-brightgreen.svg)](https://gmottola00.github.io/quaerium/)

> **Advanced RAG framework with multi-store support (vector + graph) and protocol-based architecture**

*"Quaerere" (Latin): to seek, to search, to inquire - The art of intelligent knowledge retrieval.*

---

## Features

**Architecture**
- Protocol-based design — zero inheritance required, duck typing with type safety
- Swap implementations without rewriting pipeline code
- Clean layered architecture: `core` (protocols) → `infra` (implementations) → `rag` (orchestration)

**Vector & Graph Stores**
- LLMs: Ollama, OpenAI
- Embeddings: Ollama (`nomic-embed-text`), OpenAI (`text-embedding-3-small/large`)
- Vector Stores: Milvus, Qdrant, ChromaDB
- Graph Stores: Neo4j 5.x (async, APOC support)

**Pipeline**
- Hybrid search: vector + keyword with configurable alpha blending
- Query rewriting, LLM-based reranking, context assembly
- Document parsers: PDF (PyMuPDF), DOCX, plain text; optional OCR via EasyOCR
- Dynamic and token-based chunking with metadata preservation

**Evaluation**
- Retrieval metrics: Precision@K, Recall@K, MRR, NDCG, Hit Rate
- Generation metrics: LLM-as-judge for relevance, faithfulness, hallucination detection
- End-to-end observability: latency, token usage, cost estimation
- Dataset management: JSONL format

---

## Installation

```bash
pip install quaerium
```

| Extra | Command |
|-------|---------|
| Ollama | `pip install quaerium[ollama]` |
| OpenAI | `pip install quaerium[openai]` |
| PDF / DOCX | `pip install quaerium[pdf,docx]` |
| Milvus / Qdrant / Chroma | `pip install quaerium[milvus]` (or `qdrant`, `chroma`) |
| Neo4j (graph RAG) | `pip install quaerium[neo4j]` |
| Agents kernel | `pip install quaerium[agents]` |
| Durable approvals + HTTP layer | `pip install quaerium[agents-postgres,server]` |
| All | `pip install quaerium[all]` |

The core install depends on Pydantic only; every backend is an extra.

---

## Quick Start

```python
from quaerium import RagPipeline, get_ollama_embedding, get_ollama_llm
from quaerium.infra.vectorstore.milvus import MilvusVectorStore

embedding = get_ollama_embedding()(model="nomic-embed-text")
llm = get_ollama_llm()(model="llama3.2")
vectorstore = MilvusVectorStore(host="localhost", port=19530)

vectorstore.create_collection(name="my_docs", dimension=768, metric="IP")

texts = ["Document 1 content...", "Document 2 content..."]
vectors = [embedding.embed(text) for text in texts]
vectorstore.insert(
    collection_name="my_docs",
    vectors=vectors,
    texts=texts,
    metadata=[{"source": "doc1"}, {"source": "doc2"}]
)

pipeline = RagPipeline(
    vectorstore=vectorstore,
    embedding=embedding,
    llm=llm,
    collection_name="my_docs"
)

response = pipeline.run("What is mentioned in the documents?")
print(response.answer)
for citation in response.citations:
    print(f"- {citation.text[:100]}... (score: {citation.score:.2f})")
```

---

## Advanced Usage

### Hybrid Search

```python
results = vectorstore.hybrid_search(
    collection_name="docs",
    query_vector=embedding.embed("installation guide"),
    query_text="installation guide",
    top_k=10,
    alpha=0.7  # 0=keyword only, 1=vector only
)
```

### Evaluation & Metrics

```python
from quaerium.infra.evaluation.pipeline import MetricsObserver
from quaerium.infra.evaluation.retrieval import StandardRetrievalEvaluator
from quaerium.infra.evaluation.generation import StandardGenerationEvaluator, OpenAIJudge

observer = MetricsObserver()
pipeline = RagPipeline(..., observers=[observer])
response = pipeline.run("What is RAG?")

result = observer.get_results()
print(f"Latency: {result.end_to_end_metrics.total_latency_ms:.0f}ms")
print(f"Cost: ${result.end_to_end_metrics.cost_usd:.4f}")

retrieval_eval = StandardRetrievalEvaluator(k_values=[5, 10])
retrieval_metrics = retrieval_eval.evaluate_retrieval(
    query="What is RAG?",
    retrieved_docs=retrieved_docs,
    relevant_doc_ids=["doc1", "doc3"]
)
print(f"Precision@5: {retrieval_metrics.precision_at_k[5]:.2%}")

judge = OpenAIJudge(llm=llm)
generation_eval = StandardGenerationEvaluator(judge)
generation_metrics = generation_eval.evaluate_answer(
    question="What is RAG?",
    generated_answer=response.answer,
    context=[c.text for c in response.citations]
)
print(f"Relevance: {generation_metrics.relevance_score:.2%}")
print(f"Faithfulness: {generation_metrics.faithfulness_score:.2%}")
```

### Custom Vector Store

```python
from quaerium.core import VectorStoreClient, SearchResult

class PineconeVectorStore:
    def create_collection(self, name: str, dimension: int, **kwargs): ...
    def insert(self, collection_name: str, vectors, texts, metadata, **kwargs): ...
    def search(self, collection_name: str, query_vector, top_k=10, **kwargs): ...

store: VectorStoreClient = PineconeVectorStore()
```

---

## Documentation

Full documentation: [gmottola00.github.io/quaerium](https://gmottola00.github.io/quaerium/)

---

## License

MIT License — see [LICENSE](LICENSE) for details.
