Metadata-Version: 2.4
Name: cognity-ai
Version: 2.0.0
Summary: Modular, provider-agnostic RAG library — any LLM, any vector store, any graph DB, any file format
Author-email: Aayush Joshi <aayushjoshi.dev@gmail.com>
License: MIT
Project-URL: Homepage, https://github.com/Aayush-Joshi-01/Cognity-AI
Project-URL: Documentation, https://Aayush-Joshi-01.github.io/Cognity-AI
Project-URL: Repository, https://github.com/Aayush-Joshi-01/Cognity-AI
Project-URL: Bug Tracker, https://github.com/Aayush-Joshi-01/Cognity-AI/issues
Project-URL: Changelog, https://github.com/Aayush-Joshi-01/Cognity-AI/blob/main/CHANGELOG.md
Keywords: rag,llm,graph,vector,knowledge-graph,embeddings,ai
Classifier: Development Status :: 4 - Beta
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: Topic :: Scientific/Engineering :: Artificial Intelligence
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: pydantic>=2.0.0
Requires-Dist: tenacity>=8.0.0
Requires-Dist: numpy>=1.24.0
Provides-Extra: gemini
Requires-Dist: google-generativeai>=0.5.0; extra == "gemini"
Provides-Extra: vertex-ai
Requires-Dist: google-cloud-aiplatform>=1.50.0; extra == "vertex-ai"
Requires-Dist: google-generativeai>=0.5.0; extra == "vertex-ai"
Provides-Extra: openai
Requires-Dist: openai>=1.0.0; extra == "openai"
Provides-Extra: azure
Requires-Dist: openai>=1.0.0; extra == "azure"
Provides-Extra: anthropic
Requires-Dist: anthropic>=0.25.0; extra == "anthropic"
Provides-Extra: bedrock
Requires-Dist: boto3>=1.34.0; extra == "bedrock"
Requires-Dist: botocore>=1.34.0; extra == "bedrock"
Provides-Extra: cohere
Requires-Dist: cohere>=5.0.0; extra == "cohere"
Provides-Extra: ollama
Requires-Dist: ollama>=0.1.0; extra == "ollama"
Provides-Extra: sentence-transformers
Requires-Dist: sentence-transformers>=2.2.0; extra == "sentence-transformers"
Provides-Extra: neo4j
Requires-Dist: neo4j>=5.0.0; extra == "neo4j"
Provides-Extra: networkx
Requires-Dist: networkx>=3.0; extra == "networkx"
Provides-Extra: memgraph
Requires-Dist: neo4j>=5.0.0; extra == "memgraph"
Provides-Extra: arangodb
Requires-Dist: python-arango>=7.0.0; extra == "arangodb"
Provides-Extra: microsoft-graphrag
Requires-Dist: graphrag>=0.3.0; extra == "microsoft-graphrag"
Requires-Dist: pandas>=2.0.0; extra == "microsoft-graphrag"
Provides-Extra: chroma
Requires-Dist: chromadb>=0.4.0; extra == "chroma"
Provides-Extra: qdrant
Requires-Dist: qdrant-client>=1.7.0; extra == "qdrant"
Provides-Extra: pinecone
Requires-Dist: pinecone-client>=3.0.0; extra == "pinecone"
Provides-Extra: faiss
Requires-Dist: faiss-cpu>=1.7.4; extra == "faiss"
Requires-Dist: numpy>=1.24.0; extra == "faiss"
Provides-Extra: weaviate
Requires-Dist: weaviate-client>=4.0.0; extra == "weaviate"
Provides-Extra: milvus
Requires-Dist: pymilvus>=2.3.0; extra == "milvus"
Provides-Extra: pgvector
Requires-Dist: psycopg2-binary>=2.9.0; extra == "pgvector"
Provides-Extra: azure-search
Requires-Dist: azure-search-documents>=11.6.0; extra == "azure-search"
Requires-Dist: azure-core>=1.30.0; extra == "azure-search"
Provides-Extra: nlp
Requires-Dist: spacy>=3.7.0; extra == "nlp"
Provides-Extra: pdf
Requires-Dist: pdfplumber>=0.10.0; extra == "pdf"
Requires-Dist: pypdf>=3.0.0; extra == "pdf"
Requires-Dist: pdfminer.six>=20221105; extra == "pdf"
Provides-Extra: office
Requires-Dist: python-docx>=1.0.0; extra == "office"
Requires-Dist: openpyxl>=3.1.0; extra == "office"
Requires-Dist: pandas>=2.0.0; extra == "office"
Requires-Dist: python-pptx>=0.6.21; extra == "office"
Provides-Extra: csv
Requires-Dist: pandas>=2.0.0; extra == "csv"
Provides-Extra: html
Requires-Dist: beautifulsoup4>=4.12.0; extra == "html"
Provides-Extra: yaml
Requires-Dist: PyYAML>=6.0; extra == "yaml"
Provides-Extra: ocr-local
Requires-Dist: pytesseract>=0.3.10; extra == "ocr-local"
Requires-Dist: Pillow>=10.0.0; extra == "ocr-local"
Provides-Extra: ocr
Requires-Dist: Pillow>=10.0.0; extra == "ocr"
Provides-Extra: clip
Requires-Dist: transformers>=4.40.0; extra == "clip"
Requires-Dist: torch>=2.0.0; extra == "clip"
Requires-Dist: Pillow>=10.0.0; extra == "clip"
Provides-Extra: siglip
Requires-Dist: transformers>=4.40.0; extra == "siglip"
Requires-Dist: torch>=2.0.0; extra == "siglip"
Requires-Dist: Pillow>=10.0.0; extra == "siglip"
Provides-Extra: imagebind
Requires-Dist: torch>=2.0.0; extra == "imagebind"
Requires-Dist: torchvision>=0.15.0; extra == "imagebind"
Requires-Dist: torchaudio>=2.0.0; extra == "imagebind"
Requires-Dist: Pillow>=10.0.0; extra == "imagebind"
Provides-Extra: blip2
Requires-Dist: transformers>=4.40.0; extra == "blip2"
Requires-Dist: torch>=2.0.0; extra == "blip2"
Requires-Dist: Pillow>=10.0.0; extra == "blip2"
Provides-Extra: video
Requires-Dist: opencv-python>=4.8.0; extra == "video"
Requires-Dist: moviepy>=1.0.3; extra == "video"
Requires-Dist: scenedetect>=0.6.0; extra == "video"
Requires-Dist: Pillow>=10.0.0; extra == "video"
Provides-Extra: audio
Requires-Dist: librosa>=0.10.0; extra == "audio"
Requires-Dist: soundfile>=0.12.0; extra == "audio"
Requires-Dist: pydub>=0.25.0; extra == "audio"
Provides-Extra: whisper
Requires-Dist: openai-whisper>=20231117; extra == "whisper"
Requires-Dist: ffmpeg-python>=0.2.0; extra == "whisper"
Provides-Extra: google-stt
Requires-Dist: google-cloud-speech>=2.21.0; extra == "google-stt"
Provides-Extra: aws-transcribe
Requires-Dist: boto3>=1.34.0; extra == "aws-transcribe"
Requires-Dist: botocore>=1.34.0; extra == "aws-transcribe"
Provides-Extra: multimodal
Requires-Dist: transformers>=4.40.0; extra == "multimodal"
Requires-Dist: torch>=2.0.0; extra == "multimodal"
Requires-Dist: torchvision>=0.15.0; extra == "multimodal"
Requires-Dist: torchaudio>=2.0.0; extra == "multimodal"
Requires-Dist: Pillow>=10.0.0; extra == "multimodal"
Requires-Dist: opencv-python>=4.8.0; extra == "multimodal"
Requires-Dist: moviepy>=1.0.3; extra == "multimodal"
Requires-Dist: scenedetect>=0.6.0; extra == "multimodal"
Requires-Dist: librosa>=0.10.0; extra == "multimodal"
Requires-Dist: soundfile>=0.12.0; extra == "multimodal"
Requires-Dist: pydub>=0.25.0; extra == "multimodal"
Requires-Dist: openai-whisper>=20231117; extra == "multimodal"
Requires-Dist: ffmpeg-python>=0.2.0; extra == "multimodal"
Provides-Extra: full-loaders
Requires-Dist: pdfplumber>=0.10.0; extra == "full-loaders"
Requires-Dist: pypdf>=3.0.0; extra == "full-loaders"
Requires-Dist: python-docx>=1.0.0; extra == "full-loaders"
Requires-Dist: openpyxl>=3.1.0; extra == "full-loaders"
Requires-Dist: pandas>=2.0.0; extra == "full-loaders"
Requires-Dist: python-pptx>=0.6.21; extra == "full-loaders"
Requires-Dist: beautifulsoup4>=4.12.0; extra == "full-loaders"
Requires-Dist: PyYAML>=6.0; extra == "full-loaders"
Requires-Dist: Pillow>=10.0.0; extra == "full-loaders"
Requires-Dist: pytesseract>=0.3.10; extra == "full-loaders"
Provides-Extra: default
Requires-Dist: google-generativeai>=0.5.0; extra == "default"
Requires-Dist: neo4j>=5.0.0; extra == "default"
Requires-Dist: chromadb>=0.4.0; extra == "default"
Requires-Dist: spacy>=3.7.0; extra == "default"
Requires-Dist: pdfplumber>=0.10.0; extra == "default"
Requires-Dist: python-docx>=1.0.0; extra == "default"
Requires-Dist: openpyxl>=3.1.0; extra == "default"
Requires-Dist: pandas>=2.0.0; extra == "default"
Requires-Dist: python-pptx>=0.6.21; extra == "default"
Requires-Dist: beautifulsoup4>=4.12.0; extra == "default"
Requires-Dist: Pillow>=10.0.0; extra == "default"
Requires-Dist: PyYAML>=6.0; extra == "default"
Provides-Extra: all
Requires-Dist: google-generativeai>=0.5.0; extra == "all"
Requires-Dist: google-cloud-aiplatform>=1.50.0; extra == "all"
Requires-Dist: openai>=1.0.0; extra == "all"
Requires-Dist: anthropic>=0.25.0; extra == "all"
Requires-Dist: boto3>=1.34.0; extra == "all"
Requires-Dist: cohere>=5.0.0; extra == "all"
Requires-Dist: ollama>=0.1.0; extra == "all"
Requires-Dist: sentence-transformers>=2.2.0; extra == "all"
Requires-Dist: neo4j>=5.0.0; extra == "all"
Requires-Dist: networkx>=3.0; extra == "all"
Requires-Dist: python-arango>=7.0.0; extra == "all"
Requires-Dist: chromadb>=0.4.0; extra == "all"
Requires-Dist: qdrant-client>=1.7.0; extra == "all"
Requires-Dist: pinecone-client>=3.0.0; extra == "all"
Requires-Dist: faiss-cpu>=1.7.4; extra == "all"
Requires-Dist: weaviate-client>=4.0.0; extra == "all"
Requires-Dist: pymilvus>=2.3.0; extra == "all"
Requires-Dist: psycopg2-binary>=2.9.0; extra == "all"
Requires-Dist: azure-search-documents>=11.6.0; extra == "all"
Requires-Dist: azure-core>=1.30.0; extra == "all"
Requires-Dist: spacy>=3.7.0; extra == "all"
Requires-Dist: pdfplumber>=0.10.0; extra == "all"
Requires-Dist: pypdf>=3.0.0; extra == "all"
Requires-Dist: python-docx>=1.0.0; extra == "all"
Requires-Dist: openpyxl>=3.1.0; extra == "all"
Requires-Dist: pandas>=2.0.0; extra == "all"
Requires-Dist: python-pptx>=0.6.21; extra == "all"
Requires-Dist: beautifulsoup4>=4.12.0; extra == "all"
Requires-Dist: Pillow>=10.0.0; extra == "all"
Requires-Dist: pytesseract>=0.3.10; extra == "all"
Requires-Dist: PyYAML>=6.0; extra == "all"
Requires-Dist: transformers>=4.40.0; extra == "all"
Requires-Dist: torch>=2.0.0; extra == "all"
Requires-Dist: torchvision>=0.15.0; extra == "all"
Requires-Dist: torchaudio>=2.0.0; extra == "all"
Requires-Dist: opencv-python>=4.8.0; extra == "all"
Requires-Dist: moviepy>=1.0.3; extra == "all"
Requires-Dist: scenedetect>=0.6.0; extra == "all"
Requires-Dist: librosa>=0.10.0; extra == "all"
Requires-Dist: soundfile>=0.12.0; extra == "all"
Requires-Dist: pydub>=0.25.0; extra == "all"
Requires-Dist: openai-whisper>=20231117; extra == "all"
Requires-Dist: ffmpeg-python>=0.2.0; extra == "all"
Dynamic: license-file

# cognity-ai

**Modular, provider-agnostic RAG library — any LLM, any vector store, any graph DB, any file format.**

<p align="center">
  <img src="https://img.shields.io/badge/Python-3.11+-blue?logo=python&logoColor=white" alt="Python 3.11+"/>
  <img src="https://img.shields.io/badge/License-MIT-green" alt="License: MIT"/>
  <img src="https://img.shields.io/badge/Version-1.0.0-blue" alt="Version: 1.0.0"/>
  <img src="https://img.shields.io/badge/Neo4j-supported-blue?logo=neo4j&logoColor=white" alt="Neo4j"/>
  <img src="https://img.shields.io/badge/ChromaDB-supported-orange" alt="ChromaDB"/>
  <img src="https://img.shields.io/badge/Gemini-supported-4285F4?logo=google&logoColor=white" alt="Gemini"/>
  <img src="https://img.shields.io/badge/spaCy-supported-09A3D5" alt="spaCy"/>
  <img src="https://img.shields.io/badge/OpenAI-supported-000000?logo=openai&logoColor=white" alt="OpenAI"/>
  <img src="https://img.shields.io/badge/Anthropic-supported-7C3AED" alt="Anthropic"/>
</p>

---

## Overview

`cognity-ai` is a drop-in RAG (Retrieval-Augmented Generation) service for AI agents. It was extracted and redesigned from the original `hybrid_rag` monolith into a fully modular library — every component is swappable at runtime with zero code changes beyond configuration.

**What makes it different:**

- **Any LLM:** Gemini, OpenAI, Azure OpenAI, Anthropic, AWS Bedrock, Cohere, Ollama, Vertex AI
- **Any embedder:** Same provider list — Anthropic automatically falls back to `sentence-transformers` since it has no native embedding API
- **Any vector store:** ChromaDB, Qdrant, Pinecone, FAISS, Weaviate, Milvus, pgvector, Azure AI Search
- **Any graph DB:** Neo4j, Memgraph, ArangoDB, NetworkX (in-memory), Microsoft GraphRAG
- **Any file format:** PDF, DOCX, XLSX, PPTX, CSV, HTML, JSON, YAML, TXT, MD, images (via multimodal OCR)
- **Multiple RAG methodologies:** `hybrid_graph`, `naive`, `vector_only`, `graph_only`, `parent_child`, `multi_query`, `microsoft_graphrag`, `adaptive`
- **Smart defaults:** The best available methodology is automatically selected based on which stores are configured

The primary API surface is a single class — `RAGLibrary` — which wires up the full pipeline from ingestion through retrieval and generation.

---

## Architecture Overview

```
Files (PDF / DOCX / XLSX / PPTX / images / ...)
        |
        v
   [ Loaders ]  ──► OCR (if image: Gemini Vision / GPT-4o / Claude / Tesseract)
        |
        v
   [ PageIndex ]  (regex / structural / hybrid page boundary detection)
        |
        v
   [ Chunkers ]  (sentence / fixed / recursive / semantic / parent_child / hybrid)
        |
        v
   [ Extractors ]  (NLP + LLM hybrid entity & relation extraction)
        |
        v
   [ Embedders ]  (Gemini / OpenAI / Bedrock / Cohere / Ollama / SentenceTransformers)
        |
        v
  ┌─────────────────────┐
  │   Graph Store       │   ◄── Neo4j / Memgraph / ArangoDB / NetworkX / MS GraphRAG
  │   Vector Store      │   ◄── ChromaDB / Qdrant / Pinecone / FAISS / Weaviate / ...
  └─────────────────────┘
        |
        v
   [ Retrievers ]
   4-channel Hybrid:
     ├── Graph BFS traversal
     ├── Vector similarity search
     ├── Community summary search
     └── Bridge node discovery
          └──► RRF fusion
        |
        v
   [ Generators ]  (Gemini / OpenAI / Anthropic / Bedrock / Cohere / Ollama / Vertex AI)
        |
        v
      Answer
```

---

## Quick Start

### Installation

```bash
# Default: Gemini + Neo4j + ChromaDB + spaCy + all loaders
pip install -e ".[default]"

# Selective extras — mix and match
pip install -e ".[openai,qdrant,pdf]"
pip install -e ".[anthropic,pinecone,office]"
pip install -e ".[bedrock,faiss]"

# Everything
pip install -e ".[all]"

# spaCy language model (required for NLP-based extraction)
python -m spacy download en_core_web_trf   # best accuracy (~500 MB)
python -m spacy download en_core_web_sm    # lightweight (~12 MB)
```

### Zero-config start

```python
from cognity_ai import RAGLibrary

rag = RAGLibrary(gemini_api_key="...", neo4j_password="...")

# Ingest any file format — format is auto-detected from extension
rag.ingest("report.pdf")
rag.ingest("data.xlsx")
rag.ingest("slides.pptx")
rag.ingest("photo.jpg")          # OCR via Gemini Vision
rag.ingest_dir("./docs/")        # recursive, all supported formats

# Optional: build GraphRAG community summaries for global search
rag.build_communities()

answer = rag.query("What are the key findings?")

result = rag.query_with_sources("Who founded Anthropic?")
print(result["answer"])
print(result["sources"])
```

### Full explicit configuration

```python
rag = RAGLibrary(
    rag_method="hybrid_graph",
    chunker="sentence",
    embedder="openai",
    vector_store="qdrant",
    graph_store="neo4j",
    llm="anthropic",
    ocr="gemini_vision",
    page_index="hybrid",
    openai_api_key="...",
    anthropic_api_key="...",
    neo4j_uri="bolt://localhost:7687",
    neo4j_password="...",
)
```

Every parameter has a sensible default. You only need to set the keys for the providers you actually use.

---

## Supported File Formats

| Format | Extensions | Notes |
|--------|------------|-------|
| PDF | `.pdf` | pdfplumber + pypdf; page-aware; extracts embedded images |
| Word | `.docx` | python-docx; tables, headings, embedded images |
| Excel | `.xlsx`, `.xls` | openpyxl + pandas; ingested per-sheet |
| PowerPoint | `.pptx` | python-pptx; slides + speaker notes + images |
| CSV / TSV | `.csv`, `.tsv` | pandas; auto-detects delimiter |
| HTML | `.html`, `.htm` | beautifulsoup4; strips tags, extracts text |
| Text / Markdown | `.txt`, `.md` | native; markdown heading detection |
| JSON / YAML | `.json`, `.yaml`, `.yml` | recursive key-value flattening |
| Images | `.jpg`, `.png`, `.jpeg`, `.bmp`, `.tiff`, `.webp` | multimodal OCR (see below) |

---

## OCR Providers

Image files are processed by a configurable OCR provider. The default is Gemini Vision, which handles complex layouts, mixed text/diagram pages, and handwriting well.

| Provider | Key | Method |
|----------|-----|--------|
| Gemini Vision (default) | `gemini_vision` | Gemini 2.0 Flash multimodal |
| OpenAI Vision | `openai_vision` | GPT-4o vision |
| Anthropic Vision | `anthropic_vision` | Claude 3.5 Sonnet vision |
| Azure Vision | `azure_vision` | Azure-deployed GPT-4o vision |
| Bedrock Vision | `bedrock_vision` | AWS Bedrock Claude vision |
| Tesseract | `tesseract` | Local pytesseract (fully offline) |

Configure via:

```python
rag = RAGLibrary(ocr="tesseract")                                         # offline
rag = RAGLibrary(ocr="anthropic_vision", anthropic_api_key="...")
```

---

## 🎬 Multimodal RAG (Experimental)

cognity-ai includes an experimental `cognity-ai.multimodal` subpackage for Image, Video, and Audio RAG using multimodal embedders.

### Multimodal Embedders

| Key | Class | Dims | Modalities | Install |
|---|---|---|---|---|
| CLIP | `CLIPEmbedder` | 512/768 | Image + Text | `pip install cognity-ai[clip]` |
| SigLIP | `SigLIPEmbedder` | 768/1024 | Image + Text | `pip install cognity-ai[siglip]` |
| ImageBind | `ImageBindEmbedder` | 1024 | Image + Text + Audio + Video | See [ImageBind](https://github.com/facebookresearch/ImageBind) |
| BLIP-2 | `BLIP2Embedder` | 256 | Image → Caption | `pip install cognity-ai[blip2]` |

### Image RAG

```python
from cognity_ai.multimodal import ImageIngestionPipeline, ImageRetriever
from cognity_ai.multimodal.embedders import CLIPEmbedder
from cognity_ai.multimodal.stores import ChromaMultimodalStore

embedder = CLIPEmbedder()
store = ChromaMultimodalStore()

# Ingest images
pipeline = ImageIngestionPipeline(embedder=embedder, store=store)
pipeline.ingest("photo.jpg")
pipeline.ingest_batch(["img1.png", "img2.jpg"])

# Text-to-image retrieval
retriever = ImageRetriever(embedder=embedder, store=store)
results = retriever.retrieve("a dog playing in a park", top_k=5)
for r in results:
    print(r.chunk_id, r.score, r.metadata.get("caption"))
```

### Video RAG

```python
from cognity_ai.multimodal import VideoIngestionPipeline, VideoRetriever
from cognity_ai.multimodal.embedders import CLIPEmbedder
from cognity_ai.multimodal.transcribers import WhisperLocalTranscriber
from cognity_ai.multimodal.stores import ChromaMultimodalStore

embedder = CLIPEmbedder()
transcriber = WhisperLocalTranscriber(model_size="base")
store = ChromaMultimodalStore()

# Ingest video (extracts frames + transcribes audio)
pipeline = VideoIngestionPipeline(
    embedder=embedder,
    store=store,
    transcriber=transcriber,
)
pipeline.ingest("lecture.mp4")

# Retrieve relevant video segments with timestamps
retriever = VideoRetriever(embedder=embedder, store=store)
results = retriever.retrieve("neural networks training process")
for r in results:
    chunk = r.video_chunk
    print(f"At {chunk.start_ms//1000}s – {chunk.end_ms//1000}s: {chunk.transcript[:100]}")
```

### Audio RAG

```python
from cognity_ai.multimodal import AudioIngestionPipeline, AudioRetriever
from cognity_ai.multimodal.transcribers import WhisperLocalTranscriber
from cognity_ai.multimodal.stores import ChromaMultimodalStore
from cognity_ai.embedders import GeminiEmbedder

transcriber = WhisperLocalTranscriber(model_size="small")
store = ChromaMultimodalStore()
text_embedder = GeminiEmbedder(api_key="...")

pipeline = AudioIngestionPipeline(
    transcriber=transcriber,
    store=store,
    text_embedder=text_embedder,
)
pipeline.ingest("podcast.mp3")

retriever = AudioRetriever(embedder=None, store=store, text_embedder=text_embedder)
results = retriever.retrieve("discussion about machine learning")
```

### Cross-Modal Retrieval (ImageBind)

```python
from cognity_ai.multimodal.retrievers import CrossModalRetriever
from cognity_ai.multimodal.embedders import ImageBindEmbedder

# Query with text → find relevant images, video clips, AND audio segments
retriever = CrossModalRetriever(
    embedder=ImageBindEmbedder(),
    store=store,
    search_modalities=["image", "video", "audio"],
)
results = retriever.retrieve("product launch announcement")
# Returns mixed: ImageChunks, VideoChunks, AudioChunks unified by score
```

### Transcription Providers

| Provider | Class | Install |
|---|---|---|
| Whisper (local) | `WhisperLocalTranscriber` | `pip install cognity-ai[whisper]` |
| OpenAI Whisper API | `WhisperAPITranscriber` | `pip install openai` |
| Google Speech-to-Text | `GoogleSTTTranscriber` | `pip install google-cloud-speech` |
| AWS Transcribe | `AWSTranscribeTranscriber` | `pip install boto3` |

### Install

```bash
pip install cognity-ai[clip]          # Image RAG with CLIP
pip install cognity-ai[siglip]        # Image RAG with SigLIP (higher quality)
pip install cognity-ai[video]         # Video support (frame extraction, scene detection)
pip install cognity-ai[audio]         # Audio loading
pip install cognity-ai[whisper]       # Local Whisper transcription
pip install cognity-ai[multimodal]    # Everything above
```

> **Note:** ImageBind requires manual installation. See the [ImageBind GitHub](https://github.com/facebookresearch/ImageBind) for instructions.

---

## RAG Methodologies

| Method | Description | When to Use |
|--------|-------------|-------------|
| `hybrid_graph` (default) | 4-channel retrieval: Graph BFS + Vector + Community + Bridge nodes, fused with RRF | Knowledge graphs, multi-hop reasoning, structured corpora |
| `naive` | Pure vector cosine similarity, no graph | Quick setup, unstructured flat text |
| `vector_only` | Vector similarity + community summary search | No graph store, but communities exist |
| `graph_only` | Graph traversal only, no vector lookup | Structured knowledge bases with clear entity relationships |
| `parent_child` | Retrieve small precise chunks, return their larger parent context | Long documents where context window matters |
| `multi_query` | Generate N query variants, merge and deduplicate results | Complex or ambiguous queries |
| `microsoft_graphrag` | Official MS GraphRAG local + global search modes | Microsoft ecosystem integrations |
| `adaptive` | Auto-routes to the best method based on query classification | Unknown or mixed query patterns |

### Per-query method override

```python
# Override method for a single query without reconfiguring the library
answer = rag.query("What themes emerge across all documents?", method="multi_query")
result = rag.query_with_sources("Who founded Anthropic?", method="hybrid_graph")
```

---

## Provider Matrix

### LLMs and Embedders

| Provider | Key | Generator | Embedder | Notes |
|----------|-----|-----------|----------|-------|
| Gemini (default) | `gemini` | Yes | Yes | Gemini 2.0 Flash / text-embedding-004 |
| Vertex AI | `vertex_ai` | Yes | Yes | Gemini 1.5 Pro / text-embedding-005 |
| OpenAI | `openai` | Yes | Yes | GPT-4o / text-embedding-3-small |
| Azure OpenAI | `azure_openai` | Yes | Yes | Azure-deployed GPT-4o and embedding models |
| Anthropic | `anthropic` | Yes | No | claude-3-5-sonnet; embedding falls back to `sentence_transformers` |
| AWS Bedrock | `bedrock` | Yes | Yes | Claude / Titan / Llama + Titan Embeddings V2 |
| Cohere | `cohere` | Yes | Yes | Command R+ / embed-english-v3.0 |
| Ollama | `ollama` | Yes | Yes | llama3, mistral, nomic-embed-text (fully local) |
| SentenceTransformers | `sentence_transformers` | No | Yes | all-MiniLM-L6-v2 (offline, no API key needed) |

> **Note on Anthropic embeddings:** Anthropic does not provide an embedding API. When `llm="anthropic"` and no explicit `embedder` is set, `cognity-ai` automatically falls back to `sentence_transformers` for embeddings.

---

## Vector Stores

| Store | Key | Type |
|-------|-----|------|
| ChromaDB (default) | `chroma` | Local persistent |
| Qdrant | `qdrant` | Local or Qdrant Cloud |
| Pinecone | `pinecone` | Cloud (serverless or pod) |
| FAISS | `faiss` | Local in-memory |
| Weaviate | `weaviate` | Local or Weaviate Cloud |
| Milvus | `milvus` | Local or Zilliz Cloud |
| pgvector | `pgvector` | PostgreSQL extension |
| Azure AI Search | `azure_search` | Azure cloud |

---

## Graph Stores

| Store | Key | Type |
|-------|-----|------|
| Neo4j (default) | `neo4j` | Dedicated graph DB (Bolt protocol) |
| Microsoft GraphRAG | `microsoft_graphrag` | Wraps the official `graphrag` library |
| Memgraph | `memgraph` | Open source, Neo4j-compatible (Bolt) |
| ArangoDB | `arangodb` | Multi-model (document + graph) |
| NetworkX | `networkx` | In-memory Python graph (testing / no-DB mode) |

---

## Knowledge Lifecycle Management

`cognity-ai` tracks confidence scores for every extracted knowledge triple. Use the lifecycle API to manage knowledge quality over time.

```python
# Boost confidence for a confirmed, authoritative source
rag.confirm("doc_001")

# Penalize an outdated or superseded document — halves confidence,
# reduces retrieval score for all associated triples
rag.deprecate("old_doc")

# Find contradictions: returns triples that conflict with other sources
conflicts = rag.detect_conflicts("Anthropic")

# Remove low-confidence triples from both stores
rag.prune(threshold=0.5)

# Summarise store health: triple count, avg confidence, conflict rate
print(rag.health_report())
```

---

## Plugin System

Every component type is pluggable. Register custom implementations at runtime and they become available via their key string, just like built-in providers.

```python
from cognity_ai.loaders.base import BaseLoader
from cognity_ai.models.document import Document

class MyLoader(BaseLoader):
    def load(self, path: str) -> list[Document]:
        ...  # parse your custom format here

    @property
    def supported_extensions(self) -> list[str]:
        return [".myext"]


rag.register_loader(".myext", MyLoader)
rag.register_embedder("my_embedder", MyEmbedder)
rag.register_retriever("my_method", MyRetriever)

# Inspect all registered components
print(rag.available_plugins())
```

The same pattern applies to generators, chunkers, extractors, OCR providers, and stores.

---

## Project Structure

```
D:\Graph-RAG\
├── cognity-ai/                        # Main library package
│   ├── library.py                 # RAGLibrary — the primary public API
│   ├── factory.py                 # Component wiring + provider auto-fallback logic
│   ├── registry.py                # Plugin registry for all component types
│   ├── models/                    # Core data models
│   │   ├── document.py            # Document, Chunk, PageInfo
│   │   ├── knowledge.py           # Entity, Relation, Triple, Community
│   │   └── retrieval.py           # RetrievalResult, SourceReference
│   ├── config/                    # Configuration dataclasses
│   │   ├── base.py                # LibraryConfig
│   │   └── providers.py           # Per-provider config (Neo4jConfig, etc.)
│   ├── loaders/                   # File format loaders
│   │   ├── pdf.py                 # pdfplumber + pypdf
│   │   ├── docx.py                # python-docx
│   │   ├── excel.py               # openpyxl + pandas
│   │   ├── pptx.py                # python-pptx
│   │   ├── csv.py                 # pandas
│   │   ├── html.py                # beautifulsoup4
│   │   ├── text.py                # plain text + markdown
│   │   ├── json_loader.py         # JSON + YAML
│   │   ├── image.py               # delegates to OCR provider
│   │   └── factory.py             # extension → loader routing
│   ├── ocr/                       # OCR providers
│   │   ├── gemini_vision.py
│   │   ├── openai_vision.py
│   │   ├── anthropic_vision.py
│   │   ├── azure_vision.py
│   │   ├── bedrock_vision.py
│   │   └── tesseract.py
│   ├── chunkers/                  # Text splitting strategies
│   │   ├── sentence.py
│   │   ├── fixed.py
│   │   ├── recursive.py
│   │   ├── semantic.py
│   │   ├── parent_child.py
│   │   └── hybrid.py
│   ├── page_index/                # Page boundary detection
│   │   ├── regex_index.py
│   │   ├── structural_index.py
│   │   └── hybrid_index.py
│   ├── extractors/                # Entity + relation extraction
│   │   ├── nlp.py                 # spaCy NER + dependency parsing
│   │   ├── llm.py                 # LLM-guided extraction
│   │   └── hybrid.py              # NLP first, LLM gap-fill
│   ├── embedders/                 # Embedding providers
│   │   ├── gemini.py
│   │   ├── openai.py
│   │   ├── azure_openai.py
│   │   ├── vertex_ai.py
│   │   ├── bedrock.py
│   │   ├── cohere.py
│   │   ├── ollama.py
│   │   └── sentence_transformers.py
│   ├── generators/                # LLM response generators
│   │   ├── gemini.py
│   │   ├── openai.py
│   │   ├── azure_openai.py
│   │   ├── anthropic.py
│   │   ├── vertex_ai.py
│   │   ├── bedrock.py
│   │   ├── cohere.py
│   │   └── ollama.py
│   ├── stores/
│   │   ├── vector/                # Vector store adapters
│   │   │   ├── chroma.py
│   │   │   ├── qdrant.py
│   │   │   ├── pinecone.py
│   │   │   ├── faiss.py
│   │   │   └── ...
│   │   └── graph/                 # Graph store adapters
│   │       ├── neo4j.py
│   │       ├── memgraph.py
│   │       ├── arangodb.py
│   │       └── networkx.py
│   ├── retrievers/                # Retrieval strategies
│   │   ├── hybrid_graph.py        # 4-channel + RRF fusion
│   │   ├── naive.py
│   │   ├── vector_only.py
│   │   ├── graph_only.py
│   │   ├── parent_child.py
│   │   ├── multi_query.py
│   │   ├── microsoft_graphrag.py
│   │   └── adaptive.py
│   └── pipeline/                  # Orchestration
│       ├── ingestion.py           # IngestionPipeline
│       └── knowledge_updater.py   # KnowledgeUpdater (lifecycle ops)
├── hybrid_rag/                    # DEPRECATED legacy package (see Migration section)
├── pyproject.toml                 # Packaging + optional dependency groups
├── requirements.txt               # Default install dependencies
└── docs/                          # GitHub Pages documentation site
```

---

## Migration from `hybrid_rag`

The original `hybrid_rag` package is **deprecated** but still functional. It emits a `DeprecationWarning` on import. It will be removed in a future major version.

**Before (deprecated):**

```python
from hybrid_rag.main import build_pipeline

c = build_pipeline()
c["pipeline"].ingest(doc_id="d1", text="...", source_name="report")
answer = c["retriever"].query("What is X?")
```

**After (cognity-ai):**

```python
from cognity_ai import RAGLibrary

rag = RAGLibrary(gemini_api_key="...", neo4j_password="...")
rag.ingest_text("...", doc_id="d1", source_name="report")
answer = rag.query("What is X?")
```

The new API is a strict superset of the old one in terms of capability, with cleaner configuration and no internal coupling between components.

---

## Configuration Reference

The `LibraryConfig` dataclass (and the `RAGLibrary` constructor kwargs) accept the following top-level keys:

| Key | Type | Default | Description |
|-----|------|---------|-------------|
| `rag_method` | `str` | `"hybrid_graph"` | Retrieval methodology |
| `chunker` | `str` | `"sentence"` | Text chunking strategy |
| `embedder` | `str` | `"gemini"` | Embedding provider key |
| `vector_store` | `str` | `"chroma"` | Vector store key |
| `graph_store` | `str` | `"neo4j"` | Graph store key |
| `llm` | `str` | `"gemini"` | Generator LLM key |
| `extraction` | `str` | `"hybrid"` | Knowledge extraction strategy (`nlp`, `llm`, `hybrid`) |
| `ocr` | `str` | `"gemini_vision"` | OCR provider for images |
| `page_index` | `str` | `"hybrid"` | Page boundary detection strategy |

Provider-specific settings (API keys, URIs, model names) are passed as additional kwargs and are forwarded to the relevant provider config automatically.

---

## Contributing

Pull requests are welcome. High-priority areas:

- **New loaders:** EPUB, XML, Markdown front-matter, audio transcripts
- **New graph / vector store adapters:** Weaviate, Milvus, pgvector, ArangoDB
- **Streaming retrieval:** async generator interface for token-by-token output
- **Async pipeline:** full async/await ingestion and retrieval path
- **Web UI:** graph exploration and document management interface
- **Evaluation harness:** RAGAS / ARES integration for automated quality scoring

Please open an issue before starting large changes to align on design direction.

---

## License

MIT — see [LICENSE](LICENSE) for full terms.
