Metadata-Version: 2.4
Name: glassbox-rag
Version: 1.2.1
Summary: An open-source, high-transparency modular RAG framework for AI/ML applications
Author: averoe
Maintainer: averoe
License-Expression: Apache-2.0
Project-URL: Homepage, https://github.com/averoe/GlassBox
Project-URL: Documentation, https://github.com/averoe/GlassBox#readme
Project-URL: Repository, https://github.com/averoe/GlassBox
Project-URL: Issues, https://github.com/averoe/GlassBox/issues
Project-URL: Changelog, https://github.com/averoe/GlassBox/blob/main/CHANGELOG.md
Keywords: rag,retrieval,generation,onnx,ollama,vector-store,multimodal,ai,ml,embeddings
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Science/Research
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Typing :: Typed
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: pydantic<3.0.0,>=2.0.0
Requires-Dist: pyyaml<7.0,>=6.0
Requires-Dist: numpy>=1.24.0
Requires-Dist: httpx<1.0.0,>=0.25.0
Provides-Extra: dev
Requires-Dist: pytest>=7.0.0; extra == "dev"
Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
Requires-Dist: pytest-asyncio>=0.23.0; extra == "dev"
Requires-Dist: black>=23.0.0; extra == "dev"
Requires-Dist: isort>=5.12.0; extra == "dev"
Requires-Dist: flake8>=6.0.0; extra == "dev"
Requires-Dist: mypy>=1.0.0; extra == "dev"
Requires-Dist: ruff>=0.1.0; extra == "dev"
Provides-Extra: embeddings
Requires-Dist: onnxruntime>=1.16.0; extra == "embeddings"
Requires-Dist: tokenizers>=0.15.0; extra == "embeddings"
Requires-Dist: ollama>=0.0.50; extra == "embeddings"
Requires-Dist: openai>=1.3.0; extra == "embeddings"
Requires-Dist: cohere>=4.0.0; extra == "embeddings"
Requires-Dist: google-generativeai>=0.3.0; extra == "embeddings"
Requires-Dist: aiohttp>=3.8.0; extra == "embeddings"
Provides-Extra: vector-stores
Requires-Dist: qdrant-client>=2.4.0; extra == "vector-stores"
Requires-Dist: chromadb>=0.4.0; extra == "vector-stores"
Requires-Dist: faiss-cpu>=1.7.0; extra == "vector-stores"
Requires-Dist: pinecone-client>=2.2.0; extra == "vector-stores"
Requires-Dist: weaviate-client>=3.25.0; extra == "vector-stores"
Provides-Extra: databases
Requires-Dist: psycopg2-binary>=2.9.0; extra == "databases"
Requires-Dist: asyncpg>=0.29.0; extra == "databases"
Requires-Dist: aiosqlite>=0.19.0; extra == "databases"
Requires-Dist: pymongo>=4.6.0; extra == "databases"
Requires-Dist: mysql-connector-python>=8.1.0; extra == "databases"
Provides-Extra: multimodal
Requires-Dist: pillow>=10.0.0; extra == "multimodal"
Requires-Dist: pypdf>=3.17.0; extra == "multimodal"
Requires-Dist: python-pptx>=0.6.21; extra == "multimodal"
Requires-Dist: pytesseract>=0.3.10; extra == "multimodal"
Provides-Extra: telemetry
Requires-Dist: opentelemetry-api>=1.20.0; extra == "telemetry"
Requires-Dist: opentelemetry-sdk>=1.20.0; extra == "telemetry"
Requires-Dist: opentelemetry-exporter-otlp>=1.20.0; extra == "telemetry"
Requires-Dist: prometheus-client>=0.19.0; extra == "telemetry"
Provides-Extra: auth
Requires-Dist: redis>=5.0.0; extra == "auth"
Provides-Extra: reranking
Requires-Dist: sentence-transformers>=2.2.0; extra == "reranking"
Requires-Dist: cohere>=4.0.0; extra == "reranking"
Provides-Extra: generation
Requires-Dist: openai>=1.3.0; extra == "generation"
Requires-Dist: tiktoken>=0.5.0; extra == "generation"
Provides-Extra: anthropic
Requires-Dist: anthropic>=0.39.0; extra == "anthropic"
Provides-Extra: groq
Requires-Dist: openai>=1.3.0; extra == "groq"
Provides-Extra: huggingface-inference
Requires-Dist: httpx>=0.27.0; extra == "huggingface-inference"
Provides-Extra: providers
Requires-Dist: glassbox-rag[anthropic,generation,groq,huggingface-inference]; extra == "providers"
Provides-Extra: tokens
Requires-Dist: tiktoken>=0.5.0; extra == "tokens"
Provides-Extra: adapters-langchain
Requires-Dist: langchain-core>=0.1.0; extra == "adapters-langchain"
Provides-Extra: adapters-llamaindex
Requires-Dist: llama-index-core>=0.10.0; extra == "adapters-llamaindex"
Provides-Extra: adapters-haystack
Requires-Dist: haystack-ai>=2.0.0; extra == "adapters-haystack"
Provides-Extra: adapters
Requires-Dist: glassbox-rag[adapters-haystack,adapters-langchain,adapters-llamaindex]; extra == "adapters"
Provides-Extra: tui
Requires-Dist: textual>=0.80.0; extra == "tui"
Provides-Extra: graph
Requires-Dist: networkx>=3.0; extra == "graph"
Requires-Dist: neo4j>=5.0.0; extra == "graph"
Provides-Extra: api
Requires-Dist: fastapi>=0.110.0; extra == "api"
Requires-Dist: uvicorn>=0.29.0; extra == "api"
Provides-Extra: sync
Requires-Dist: httpx>=0.27.0; extra == "sync"
Requires-Dist: notion-client>=2.0.0; extra == "sync"
Requires-Dist: google-api-python-client>=2.100.0; extra == "sync"
Requires-Dist: google-auth>=2.30.0; extra == "sync"
Requires-Dist: atlassian-python-api>=3.41.0; extra == "sync"
Provides-Extra: corpus
Requires-Dist: duckdb>=0.10.0; extra == "corpus"
Requires-Dist: openpyxl>=3.1.0; extra == "corpus"
Provides-Extra: distributed
Requires-Dist: redis>=5.0.0; extra == "distributed"
Provides-Extra: sandbox
Requires-Dist: wasmtime>=20.0.0; extra == "sandbox"
Provides-Extra: grpc
Requires-Dist: grpcio>=1.60.0; extra == "grpc"
Requires-Dist: grpcio-tools>=1.60.0; extra == "grpc"
Provides-Extra: auto
Requires-Dist: glassbox-rag[embeddings,generation,tokens,tui]; extra == "auto"
Requires-Dist: qdrant-client>=2.4.0; extra == "auto"
Requires-Dist: aiosqlite>=0.19.0; extra == "auto"
Provides-Extra: auto-chroma
Requires-Dist: glassbox-rag[embeddings,generation,tokens]; extra == "auto-chroma"
Requires-Dist: chromadb>=0.4.0; extra == "auto-chroma"
Requires-Dist: aiosqlite>=0.19.0; extra == "auto-chroma"
Provides-Extra: all
Requires-Dist: glassbox-rag[adapters,api,auth,corpus,databases,embeddings,generation,graph,multimodal,providers,reranking,sync,telemetry,tokens,tui,vector-stores]; extra == "all"
Dynamic: license-file

# GlassBox RAG

A production-ready, high-transparency modular RAG (Retrieval-Augmented Generation) framework for enterprise AI/ML applications. GlassBox provides full-pipeline observability, an integrated terminal dashboard, extensible plugin architecture, built-in evaluation and experiment tracking, and real-time telemetry -- all from a single `pip install`.

It also includes advanced pipeline intelligence (GraphRAG, agentic RAG, chain-of-retrieval, HyDE, source attribution), enterprise controls (RBAC, PII redaction, prompt-injection defence, audit logging), an API toolkit (FastAPI + serverless), heterogeneous data connectors, and scale-out primitives (event bus, multi-tenancy, distributed workers, gRPC) -- each shipped as an optional, gracefully-degrading extra.

---

## Table of Contents

- [Features](#features)
- [Installation](#installation)
- [Quick Start](#quick-start)
- [CLI Reference](#cli-reference)
- [Configuration](#configuration)
- [Terminal Dashboard (TUI)](#terminal-dashboard-tui)
- [Python API Reference](#python-api-reference)
- [Plugin Architecture](#plugin-architecture)
- [Framework Adapters](#framework-adapters)
- [Evaluation System](#evaluation-system)
- [Experiment Tracking](#experiment-tracking)
- [Version Management](#version-management)
- [Advanced Retrieval Strategies](#advanced-retrieval-strategies)
- [GraphRAG and Agentic RAG](#graphrag-and-agentic-rag)
- [Source Attribution and Provenance](#source-attribution-and-provenance)
- [Enterprise Security](#enterprise-security)
- [API Toolkit and Serverless](#api-toolkit-and-serverless)
- [Data Syncing and Connectors](#data-syncing-and-connectors)
- [Heterogeneous Data Corpora](#heterogeneous-data-corpora)
- [Context Engine and Personalization](#context-engine-and-personalization)
- [Automated Optimization](#automated-optimization)
- [Scale and Distributed Mode](#scale-and-distributed-mode)
- [Solution Blueprints](#solution-blueprints)
- [Observability](#observability)
- [Deployment](#deployment)
- [Architecture](#architecture)
- [Testing](#testing)
- [Contributing](#contributing)
- [License](#license)

---

## Features

### Core RAG Pipeline

- **Modular Encoding Layer** -- Swap between OpenAI, Cohere, Google, Ollama, ONNX, and Hugging Face encoders at runtime. Per-query encoder overrides supported.
- **Embedding Cache** -- In-memory LRU cache with SHA-256 keying, configurable max size (default 2048), and batch hit/miss tracking. Eliminates redundant embedding API calls.
- **Adaptive Retrieval** -- Semantic, keyword, and hybrid retrieval strategies with configurable weighting. Heuristic-based strategy selection adapts to query characteristics.
- **Cross-Encoder Reranking** -- Optional reranking pass via cross-encoder, Cohere, or Hugging Face models for improved precision.
- **Advanced Chunking** -- Recursive, sentence-based, fixed-size, and content-adaptive dynamic strategies with overlap control and chunk-size monitoring.
- **Document Deduplication** -- Content-hash (SHA-256), SimHash (fuzzy), and semantic embedding-based deduplication with configurable thresholds. Runs automatically during batch ingestion.
- **Write-Back Protection** -- Confidence-gated document updates with configurable modes (read-only, protected, full) and optional human review workflow.

### LLM Generation

- **Streaming Generation** -- Async streaming for real-time token delivery via `engine.stream()`.
- **Multiple Backends** -- OpenAI, Ollama, Anthropic, Groq, Hugging Face Inference, and any OpenAI-compatible endpoint. Config-driven setup with auto-detection from environment variables (`OPENAI_API_KEY`, `ANTHROPIC_API_KEY`, `GROQ_API_KEY`, `HF_TOKEN`, `OLLAMA_BASE_URL`, with `GLASSBOX_LLM_BACKEND` override).
- **Token Counting** -- Accurate token usage tracking via tiktoken with per-model cost estimation. Supports custom context window mappings for 20+ models.
- **Configurable System Prompts** -- Per-request or config-level system prompt overrides.
- **Inline Evaluation** -- Optional faithfulness, groundedness, and context relevance scoring on every `generate()` call via the `evaluate=True` parameter.

### Pipeline Intelligence

- **GraphRAG** -- Knowledge-graph retrieval with multi-hop traversal. NetworkX backend (in-process, pure-Python fallback) for development and Neo4j for production. Query-derived entity extraction seeds the traversal.
- **Agentic RAG** -- `RAGAgent` performs iterative, tool-using reasoning: it decides whether context is sufficient, formulates follow-up sub-queries, calls registered tools, and self-corrects a draft answer against retrieved evidence.
- **Chain-of-Retrieval (CoRAG)** -- Iteratively refines retrieval across multiple LLM-guided steps, fusing and de-duplicating results.
- **HyDE** -- Hypothetical Document Embeddings: embeds a generated hypothetical answer instead of the raw query for better recall on under-specified questions.
- **Adaptive Query Router** -- `QueryComplexityClassifier` routes queries (simple/moderate/complex) to the optimal strategy, including graph and CoRAG.
- **Source Attribution** -- Sentence-level citation rendering with a reference list; full per-chunk provenance/lineage tracking.

### Enterprise and Scale

- **Security** -- RBAC with per-document ACL filtering, PII detection/redaction (Luhn-validated), prompt-injection defence (query and indirect/stored), tamper-evident audit logging, and data classification -- unified via `SecurityGateway`.
- **API Toolkit** -- FastAPI app factory with query/generate/ingest/health endpoints and optional API-key auth, plus framework-agnostic AWS Lambda and GCP Cloud Function handlers.
- **Data Syncing** -- Incremental sync engine with a persistent delta ledger and connectors (filesystem, webhook, HTTP, Notion, Google Drive, Confluence). Network-backed connectors degrade gracefully and accept seeded documents for offline testing.
- **Heterogeneous Corpora** -- Text-to-SQL, tabular (DuckDB), object storage (S3), NoSQL (MongoDB), and conversational-log adapters, all emitting the standard document shape.
- **Context Engine** -- Reciprocal-rank context fusion across sources, real-time API context nodes with TTL caching, and buffered streaming ingestion with backpressure.
- **Personalization** -- Session memory with follow-up resolution and a per-user context layer (interest boosting, source filtering).
- **Automated Optimization** -- Parameter auto-tuning (grid + Bayesian-style search) and continuous feedback learning for ranking adjustments.
- **Scale-out** -- Typed event bus, multi-tenancy with quotas, SQLite WAL crash recovery, versioned index migrations, a distributed task queue (in-memory + Redis Streams), an AOT pipeline compiler, and a gRPC transport.

### Terminal Dashboard (TUI)

GlassBox ships with a fully featured terminal dashboard built on Textual. Launch with `glassbox-rag tui` -- no browser or separate frontend required.

- **Overview** -- Live metrics (request count, latency, token usage, cost), component health status, and recent activity feed pulled from real trace data.
- **Pipeline** -- Interactive pipeline visualization with step-by-step execution flow and real-time test execution. Keyboard-driven step reordering.
- **Debugger** -- Trace listing with filtering, detailed step-by-step timing breakdown, anomaly detection, and trace export.
- **Telemetry** -- Latency and throughput charts, cost breakdown by operation, and performance percentile tables (p50/p95/p99) sourced from live metrics.
- **Config and Plugins** -- Interactive configuration editor and plugin documentation with code examples and inline API reference.
- **Ingest** -- File and directory ingestion interface with progress tracking.
- **Evaluation** -- Run evaluation suites against golden datasets and view per-query scoring breakdowns.
- **Experiments** -- Record, list, and compare experiment runs with metrics diff and git commit association.
- **Logs** -- Live-streaming, level-filterable structured log tab.
- **Playground** -- Side-by-side A/B query comparison with document-overlap and latency diff.
- **Replay** -- Step through a recorded pipeline execution with a timeline and per-step input/output.
- **Builder** -- Visual pipeline builder canvas (`b`) with a typed-slot stage catalog. Connections are validated by slot type and rejected if they create a cycle; seed the canvas from the live config with one keystroke.
- **Docs** -- In-app cookbook, starters, and help browser (`d`) with a searchable, grouped topic sidebar. A **Get started** group offers copy-paste "first code" snippets (minimal RAG, zero-config, ingest a folder, citations, build a pipeline) above the full **Cookbook** so guidance is available without leaving the terminal.
- **Command Palette** -- Fuzzy-searchable action overlay (`Ctrl+P`) for tab navigation, refresh, export, `Start: …` commands that open a get-started snippet, and `Help: …` commands that jump straight to a cookbook recipe.
- **Config-driven pipeline view** -- The Pipeline tab reflects the *actual* enabled strategies and hooks (query rewrite, HyDE, GraphRAG, CoRAG, rerank, compression) rather than a fixed diagram.

#### Screen Snapshots

Text renderings of each tab (the live UI is a full-colour Textual app). Run `glassbox-rag tui` to interact with them.

**Overview** (`1`) -- live metrics, component health, recent activity

```text
Overview
------------------------------------------------------------
Requests  1,284     p95 latency  412 ms    Tokens  1.9M
Cost      $12.47    Errors       0.3 %     Uptime  4h 12m

Components
  encoder   [ready]    vector_store [qdrant]   database [postgres]
  reranker  [ready]    generator    [openai]   traces   [sqlite]

Recent activity
  12:04:31  generate  "how does reranking work?"   412 ms  ok
  12:04:18  ingest    47 chunks from ./knowledge            ok
```

**Pipeline** (`2`) -- config-driven flow with live step timing

```text
Pipeline
------------------------------------------------------------
Input -> Encode -> Retrieve -> Rerank -> Generate -> Output
                               (active)

Execution timeline          Step details
  encode      62 ms           Retrieve Documents
  retrieve   228 ms           strategy : hybrid (alpha=0.6)
  rerank      49 ms           top_k    : 20 -> 5
  generate   101 ms           store    : qdrant

Alt+Up/Down reorder steps  -  Run Test Query  -  Reset
```

**Debugger** (`3`) -- trace list with step-by-step timing breakdown

```text
Debugger
------------------------------------------------------------
Traces                        Trace 8f3a - generate  (412 ms)
> 8f3a  generate  412 ms  ok    encode_query        62 ms
  7c1b  retrieve  240 ms  ok    adaptive_retrieve  228 ms
  6d90  ingest    1.2 s   ok      vector_search    201 ms
  5a22  generate  980 ms  warn  rerank              49 ms
                                generate           101 ms  (slow)

filter: [ all ]    export trace -> json
```

**Telemetry** (`4`) -- latency/throughput charts and cost breakdown

```text
Telemetry
------------------------------------------------------------
Latency (ms)                    Throughput (req/min)
  500 |         .:ill             60 |      .:ilil
  250 |    .:ill:.                30 |   .:il
    0 +-------------               0 +-----------

Percentiles            Cost by operation
  p50   180 ms           generate  $8.90
  p95   412 ms           encode    $2.10
  p99   705 ms           rerank    $1.47
```

**Config & Plugins** (`5`) -- interactive config editor and plugin reference

```text
Config & Plugins
------------------------------------------------------------
Section          encoding.default_encoder    : openai
> encoding       encoding.cloud.openai.model : text-embedding-3-large
  retrieval      retrieval.rerank_enabled    : true
  generation     retrieval.reranker_type     : cross-encoder
  vector_store

Registered plugins
  vector_store : qdrant  chroma  faiss  pinecone  weaviate
  encoder      : openai  cohere  hf        reranker : cross-encoder  cohere
```

**Ingest** (`6`) -- file/directory ingestion with progress

```text
Ingest
------------------------------------------------------------
Path: [ ./knowledge                       ]  [ Browse ]
Glob: [ **/*.md ]   Batch size: [ 50 ]   [x] deduplicate

Progress
  batch 3/5  [##############--------]  63%
  documents 188   chunks 1,204   duplicates skipped 12
  added 47    errors 0
```

**Evaluation** (`7`) -- run golden datasets, per-query scoring

```text
Evaluation
------------------------------------------------------------
Dataset: golden_v3.json  (42 cases)          [ Run suite ]

Results
  recall@5      0.91  (+0.03)    faithfulness   0.88
  precision@5   0.79  (-0.01)    groundedness   0.90
  ctx_relevance 0.84             regression: none

Per-query
  ok    "reset my password"       recall 1.00
  warn  "cancel subscription"     recall 0.60
```

**Experiments** (`8`) -- record and compare runs with metric diffs

```text
Experiments
------------------------------------------------------------
run         pipeline  dataset   recall@5  faith   commit
> exp-014   v1.2.0    gold_v3     0.91     0.88   a1b2c3d
  exp-013   v1.2.0    gold_v3     0.88     0.86   9f8e7d6
  exp-012   v1.1.0    gold_v2     0.85     0.84   4c3b2a1

Diff  exp-014 vs exp-013
  recall@5 +0.03    faithfulness +0.02    latency -18 ms
```

**Logs** (`9`) -- live-streaming, level-filterable structured logs

```text
Live Logs
------------------------------------------------------------
level: [ INFO ]   filter: [ retriev ]
  12:04:31 INFO   engine     retrieve strategy=hybrid top_k=20
  12:04:31 DEBUG  retriever  vector_search 201 ms -> 20 hits
  12:04:31 INFO   reranker   cross-encoder 20 -> 5
  12:04:32 WARN   generator  response near token budget (92%)
```

**Playground** (`0`) -- side-by-side A/B query comparison

```text
Query Playground
------------------------------------------------------------
Query: [ what is hybrid retrieval? ]            [ Compare ]

  A  top_k=5  alpha=0.5          B  top_k=10  alpha=0.7
  1 (0.82) hybrid combines...    1 (0.88) hybrid combines...
  2 (0.71) dense retrieval...    2 (0.74) BM25 keyword...
  latency 208 ms                 latency 331 ms

overlap: 3/5 docs   -   latency delta +123 ms
```

**Replay** (`Ctrl+P` -> Session Replay) -- step through a recorded trace

```text
Session Replay
------------------------------------------------------------
trace 8f3a   step 3/5    [ |< ] [ < ] [ > ] [ >| ]

Timeline
  o---o---O---.---.   encode  retrieve  [rerank]  generate  output

Step: rerank
  input  : 20 documents
  output : 5 documents  (cross-encoder)
  took   : 49 ms
```

**Builder** (`b`) -- visual pipeline builder with typed-slot validation

```text
Visual Pipeline Builder
------------------------------------------------------------
[ Add stage ]  +Add   [From] [To] ->Connect   Validate   From-Config

Canvas                             Validation
  input_1    (in: -      out: query)    + added retrieve_1
  encode_1   (in: query  out: embed)    -> connected encode_1 to retrieve_1
  retrieve_1 (in: embed  out: docs)     slot mismatch: input -> retrieve
  generate_1 (in: docs   out: answer)     (no matching slot)
  edges: input_1 -[query]-> encode_1    pipeline is valid
```

**Docs** (`d`) -- in-app cookbook, starters, and help browser

```text
Docs, Cookbook & Starters
------------------------------------------------------------
Filter: [                    ]

  -- Get started --          Minimal RAG in 15 lines
    Minimal RAG                engine = GlassBoxEngine(
    Zero-config (from_env)         GlassBoxConfig.from_env())
    Ingest a folder            await engine.initialize()
  -- Cookbook --               await engine.ingest([...])
    Getting started            answer = await engine.generate("...")
    Hybrid & reranking
    Syncing sources          Ctrl+P -> "Start: ..." / "Help: ..."
```

### Evaluation and Experiment Tracking

- **Golden Datasets** -- Define query-expected document pairs in YAML or JSON format for repeatable evaluation.
- **Retrieval Metrics** -- recall@k, precision@k, and other configurable retrieval quality metrics.
- **Generation Metrics** -- LLM-as-judge scoring for faithfulness, groundedness, and context relevance.
- **Regression Detection** -- Compare evaluation reports with configurable thresholds to catch metric regressions.
- **Experiment Tracker** -- Record pipeline version, dataset version, git commit, and evaluation results. Compare experiments side-by-side.

### Version Management

- **Pipeline Versioning** -- Auto-incrementing pipeline version snapshots stored in `.glassbox/versions/`.
- **Prompt Versioning** -- Track system prompt changes in `.glassbox/prompts/`.
- **Git Integration** -- Optional git commit association and branch tracking for experiment reproducibility.

```python
from glassbox_rag import VersionManager

# Point at your project workspace (defaults to the current directory)
vm = VersionManager.from_workspace(".")

version = vm.get_current_pipeline_version()   # current pipeline version (int)
snap = vm.snapshot(tag="v1-baseline")         # freeze config + prompt + dataset state
diff = vm.diff("v1-baseline", "v2-experiment")
vm.rollback("v1-baseline")                    # restore config from a snapshot
```

`snapshot()` takes a string `tag`; passing anything else raises a clear `TypeError`.

### Production Infrastructure

- **Rate Limiting** -- Redis-backed distributed rate limiting for production use.
- **Authentication** -- JWT token authentication and API key validation with configurable scoping.
- **OpenTelemetry** -- Optional trace export to OTLP, Jaeger, Zipkin, or console backends.
- **Prometheus Metrics** -- Exportable Prometheus metrics for Grafana integration.
- **Persistent Trace Backends** -- In-memory (default), Redis, or PostgreSQL trace storage with configurable retention.

### Developer Experience

- **Query Pipeline Hooks** -- Register before/after hooks at nine pipeline stages (PRE/POST_RETRIEVE, PRE/POST_GENERATE, PRE/POST_INGEST, PRE/POST_RERANK, ON_ERROR) with priority ordering and timeout enforcement.
- **Plugin System** -- Six plugin types (vector_store, database, encoder, reranker, chunker, processor) with a decorator-based registration API and test harness.
- **Framework Adapters** -- First-class integration with LangChain, LlamaIndex, and Haystack. Safe sync-to-async bridging for use inside running event loops (Jupyter, etc.).
- **Fluent Config Builder + DI** -- Build configs in code via `GlassBoxConfig.builder()`, and inject pre-built components with `GlassBoxEngine(config, retriever=..., encoder=..., generator=...)`.
- **Document Loaders** -- Built-in text, Markdown (heading-split), JSONL, and directory loaders emitting the standard document shape.
- **Plugin Registry** -- Discoverable plugin/marketplace index with entry-point discovery.
- **Solution Blueprints** -- Opinionated one-call configurations for common use cases (customer support, legal analysis, internal KB, research assistant).
- **Optional, gracefully-degrading extras** -- Heavy dependencies (PyYAML, DuckDB, Redis, FastAPI, Neo4j, wasmtime, grpc) are optional; a pure-Python YAML fallback and `glassbox_rag.utils.deps` feature-matrix keep the core working everywhere.
- **CLI** -- 12 commands covering project scaffolding, querying, ingestion, evaluation, experiment tracking, index migrations, health checks, data export, documentation browsing, and TUI dashboard.
- **Full Type Safety** -- Complete PEP 585/604 type annotations validated with mypy. Ships with `py.typed` marker.

---

## Installation

### From PyPI

```bash
pip install glassbox-rag
```

### With Optional Dependencies

```bash
# Common setup: embeddings + generation + token counting + Qdrant + SQLite
pip install "glassbox-rag[auto]"

# Same as auto but with ChromaDB instead of Qdrant
pip install "glassbox-rag[auto-chroma]"

# Full installation with all plugins
pip install "glassbox-rag[all]"

# Specific extras
pip install "glassbox-rag[tui]"                 # Terminal dashboard (textual) -- required for `glassbox-rag tui`
pip install "glassbox-rag[embeddings]"          # All embedding providers
pip install "glassbox-rag[vector-stores]"       # All vector store backends
pip install "glassbox-rag[databases]"           # All database backends
pip install "glassbox-rag[multimodal]"          # PDF, image, PPTX extraction
pip install "glassbox-rag[telemetry]"           # OpenTelemetry + Prometheus
pip install "glassbox-rag[auth]"               # Redis rate limiting
pip install "glassbox-rag[generation]"         # LLM generation (OpenAI + tiktoken)
pip install "glassbox-rag[tokens]"             # Token counting (tiktoken)
pip install "glassbox-rag[reranking]"          # Cross-encoder reranking
pip install "glassbox-rag[adapters]"           # LangChain, LlamaIndex, Haystack
pip install "glassbox-rag[providers]"          # Anthropic, Groq, Hugging Face inference
pip install "glassbox-rag[graph]"              # GraphRAG (NetworkX + Neo4j)
pip install "glassbox-rag[api]"                # FastAPI serving toolkit
pip install "glassbox-rag[sync]"               # Data sync connectors (httpx)
pip install "glassbox-rag[corpus]"             # Heterogeneous corpora (DuckDB)
pip install "glassbox-rag[distributed]"        # Distributed workers (Redis Streams)
pip install "glassbox-rag[sandbox]"            # WASM plugin sandbox (wasmtime)
pip install "glassbox-rag[grpc]"               # gRPC transport
```

### From Source

```bash
git clone https://github.com/averoe/GlassBox.git
cd glassbox-rag
pip install -e ".[dev]"
```

---

## Quick Start

### Python API

```python
import asyncio
from glassbox_rag import GlassBoxEngine, GlassBoxConfig, Document

async def main():
    # Initialize -- auto-detects config from environment variables
    config = GlassBoxConfig.from_env()
    engine = GlassBoxEngine(config)
    await engine.initialize()

    # Ingest documents
    documents = [
        {"content": "GlassBox is a modular RAG framework.", "metadata": {"source": "docs"}},
        {"content": "It supports multiple vector stores.", "metadata": {"source": "docs"}},
    ]
    result = await engine.ingest(documents)
    print(f"Ingested {result['chunks_created']} chunks")

    # Retrieve
    results = await engine.retrieve("What is GlassBox?", top_k=5)
    for doc in results.documents:
        print(f"  [{doc.score:.3f}] {doc.content[:80]}")

    # Generate (requires generation backend configured)
    response = await engine.generate("What is GlassBox?", top_k=5)
    print(response.answer)

    # Generate with inline evaluation scoring
    response = await engine.generate("What is GlassBox?", evaluate=True)
    if response.evaluation:
        print(f"Faithfulness: {response.evaluation.faithfulness:.2f}")
        print(f"Groundedness: {response.evaluation.groundedness:.2f}")

    await engine.shutdown()

asyncio.run(main())
```

### Zero-Config Constructor

```python
# No config file needed -- auto-detects from environment variables
engine = GlassBoxEngine.from_env()
await engine.initialize()
```

### Loading Config from a File

```python
# Load and validate a YAML config file. ${VAR} references are resolved from
# the environment; unresolved required variables halt loading by default.
from glassbox_rag import load_config

config = load_config("config/default.yaml")   # returns a GlassBoxConfig
engine = GlassBoxEngine(config)
```

`load_config` is the file-based counterpart to `GlassBoxConfig.from_env()`. (There is no `GlassBoxConfig.from_yaml`; use `load_config`.)

### Launch the Terminal Dashboard

The dashboard ships in the optional `tui` extra (also included in `[auto]` and `[all]`):

```bash
pip install "glassbox-rag[tui]"

glassbox-rag tui --config config/default.yaml

# With custom refresh interval
glassbox-rag tui --config config/default.yaml --refresh 10
```

### Cookbook

Task-oriented, layered recipes (first pipeline → configuration → hybrid + reranking → evaluation → syncing → visual builder → custom plugins → production) live in [`docs/cookbooks/cookbook.md`](docs/cookbooks/cookbook.md). The same content is browsable inside the TUI under the **Docs** tab (press `d`), which also groups a set of copy-paste **Get started** snippets above the cookbook for getting your first code running. Every snippet and recipe is reachable from the command palette via `Ctrl+P` → "Start: …" / "Help: …".

---

## CLI Reference

GlassBox provides 12 CLI commands accessible via the `glassbox-rag` entry point.

### init -- Scaffold a new project

```bash
glassbox-rag init [directory] [options]

Options:
  --encoder {openai,ollama,cohere,google,onnx}   Default encoder (default: openai)
  --vector-store {qdrant,chroma,faiss,pinecone}   Vector store (default: qdrant)
  --database {sqlite,postgresql}                  Database backend (default: sqlite)
  --force                                         Overwrite existing files
```

Creates `config/default.yaml`, `.env` template, `.gitignore`, and `data/` directory.

### tui -- Launch the terminal dashboard

```bash
glassbox-rag tui [options]

Options:
  --config PATH     Path to configuration file (default: config/default.yaml)
  --refresh INT     Auto-refresh interval in seconds (default: 5)
```

### query -- Run a retrieval query

```bash
glassbox-rag query "your query text" [options]

Options:
  --config PATH     Configuration file path
  --top-k INT       Number of results (default: 5)
  --encoder NAME    Encoder override
  --json            Output as JSON
```

### ingest -- Ingest files or directories

```bash
glassbox-rag ingest <paths...> [options]

Options:
  --config PATH     Configuration file path
  --encoder NAME    Encoder override
  --glob PATTERNS   Comma-separated file patterns (default: *.txt,*.md,*.csv,*.json,*.rst,*.html)
  --meta KEY=VALUE  Metadata pairs (repeatable)
  --json            Output as JSON
```

### health -- Run a health check

```bash
glassbox-rag health [options]

Options:
  --config PATH     Configuration file path
  --json            Output as JSON
```

Reports status of all components: encoder, retriever, vector store, database, telemetry, reranker, and write-back.

### export -- Export metrics, traces, or cache stats

```bash
glassbox-rag export [options]

Options:
  --config PATH                 Configuration file path
  --type {metrics,traces,cache,all}  Data type to export (default: all)
  --output PATH                 Output file path (default: stdout)
  --format {json,text}          Output format (default: json)
```

### check -- Validate configuration

```bash
glassbox-rag check --config config/default.yaml
```

### docs -- Interactive documentation browser

```bash
glassbox-rag docs [topic]
glassbox-rag docs --list

Available topics: config, retrieval, plugins, hooks, api, telemetry
```

### eval -- Evaluation commands

```bash
# Run evaluation on a golden dataset
glassbox-rag eval run --dataset path/to/golden.yaml --config config/default.yaml \
  --metrics "recall@5,precision@5,faithfulness" [--json]

# List evaluation reports
glassbox-rag eval list [--limit 20] [--json]

# Compare two reports for regressions
glassbox-rag eval compare <report_a> <report_b> [--threshold 0.05]
```

### experiment -- Experiment tracking

```bash
# List recorded experiments
glassbox-rag experiment list [--limit 20] [--json]

# Record a new experiment
glassbox-rag experiment record [--version INT] [--dataset STR] [--trace-id STR] [--json]

# Compare two experiments
glassbox-rag experiment compare <exp_a> <exp_b> [--json]
```

### migrate -- Run index/metadata migrations

```bash
glassbox-rag migrate --config config/default.yaml [--target N] [--list] [--json]
```

Applies registered versioned index migrations (metadata transforms, dual-index
re-embedding). Use `--list` to preview pending migrations.

### version -- Show version

```bash
glassbox-rag version
```

---

## Configuration

GlassBox uses YAML configuration with `${ENV_VAR}` and `${ENV_VAR:default}` substitution. A zero-config mode is also available via `GlassBoxConfig.from_env()`.

### Configuration Sections

| Section | Description |
|---------|-------------|
| `server` | Host, port, workers settings |
| `logging` | Log level (`DEBUG`/`INFO`/`WARNING`/`ERROR`/`CRITICAL`) and format (`json`/`text`) |
| `trace` | Trace backend (`sqlite` default/persistent, `memory`/`redis`/`postgresql`), retention, sample rate |
| `encoding` | Encoder setup: default encoder, cloud providers, local providers |
| `vector_store` | Vector store backend and connection settings |
| `database` | Document storage backend and connection settings |
| `chunking` | Strategy (`recursive`/`sentence`/`fixed`/`dynamic`), size, overlap |
| `retrieval` | Top-k, min score, adaptive strategies, reranking |
| `generation` | LLM backend (`openai`/`ollama`), model, temperature, system prompt |
| `writeback` | Write-back mode (`read-only`/`protected`/`full`), confidence threshold |
| `metrics` | Cost and latency tracking toggles |
| `telemetry` | OpenTelemetry and Prometheus export settings |
| `security` | API key requirements, CORS, rate limiting |
| `auth` | JWT authentication settings |
| `evaluation` | Evaluation backend, metrics, regression threshold |
| `versioning` | Pipeline/prompt versioning directories |
| `git` | Git integration (auto-commit, branch association) |
| `query_rewrite` | LLM-based query rewriting pre-retrieval |
| `context_compression` | LLM-based context compression pre-generation |
| `parent_child` | Parent-child document retrieval |
| `multi_query` | Multi-query expansion with reciprocal rank fusion |
| `hyde` | Hypothetical Document Embeddings pre-retrieval |
| `corag` | Chain-of-Retrieval iterative refinement |
| `graph` | GraphRAG knowledge-graph retrieval (backend, hops, Neo4j connection) |
| `citations` | Source attribution: inline citation markers + reference list on answers |
| `contextual_rag` | Prepend a document-level context summary to each chunk before embedding |
| `multi_tenancy` | Auto-tag ingest + filter retrieval by the active tenant |
| `indexing_extras` | Drift detection, freshness validation, lineage tracking |
| `plugins` | Custom plugin loading |

### Example Configuration

```yaml
encoding:
  default_encoder: "openai"
  cloud:
    openai:
      api_key: "${OPENAI_API_KEY}"
      model: "text-embedding-3-small"
      embedding_dim: 1536

vector_store:
  type: "qdrant"
  qdrant:
    host: "localhost"
    port: 6333
    collection_name: "glassbox_docs"

database:
  type: "sqlite"
  sqlite:
    path: "./data/glassbox.db"

chunking:
  strategy: "recursive"
  chunk_size: 512
  chunk_overlap: 50

retrieval:
  top_k: 5
  min_score: 0.3
  rerank_enabled: false
  adaptive:
    enabled: true
    strategies:
      - name: "semantic"
      - name: "hybrid"
        weight_semantic: 0.6
        weight_keyword: 0.4

generation:
  backend: "openai"
  model: "gpt-4o-mini"
  temperature: 0.7

trace:
  enabled: true
  backend: "memory"

writeback:
  enabled: true
  mode: "protected"
  protected:
    confidence_threshold: 0.8

metrics:
  enabled: true
  track_tokens: true
  track_latency: true
  track_cost: true
```

---

## Terminal Dashboard (TUI)

The TUI is built with [Textual](https://github.com/Textualize/textual) and runs the GlassBox engine in-process -- no separate server required.

Launch with `glassbox-rag tui` after configuring your project.

### A Glimpse

Text renderings of the Overview, Pipeline, and Playground tabs (the live UI is a full-colour Textual app):

```text
Overview
------------------------------------------------------------
Requests  1,284     p95 latency  412 ms    Tokens  1.9M
Cost      $12.47    Errors       0.3 %     Uptime  4h 12m

Components
  encoder   [ready]    vector_store [qdrant]   database [postgres]
  reranker  [off]      generator    [openai]   traces   [sqlite]

Recent activity
  14:02:11  retrieve  "vector db options"    142 ms  ok
  14:02:09  generate  "how does attention?"  890 ms  ok
  14:02:04  ingest    47 chunks                2.1 s  ok

q Quit   r Refresh   1-9,0 Tabs   b Builder   d Docs   Ctrl+P Palette
```

```text
Pipeline   (actual enabled stages: HyDE + rerank on)
------------------------------------------------------------
Query -> HyDE -> Encode -> Retrieve -> Rerank -> Generate -> Output
 2.1ms   48.7ms   15.3ms    82.4ms     12.0ms    41.2ms     3.1ms

Execution complete   strategy: hybrid   results: 5   total: 204.8 ms
```

```text
Query Playground     query: "how does attention work?"
------------------------------------------------------------
  A  top_k=3   (58.2 ms)        B  top_k=10  (71.9 ms)
  1 (0.912) Attention maps...   1 (0.912) Attention maps...
  2 (0.874) Scaled dot-prod...  2 (0.874) Scaled dot-prod...
  3 (0.841) Multi-head att...   ... 10 results

overlap: jaccard 0.30   -   latency delta +13.7 ms
```

A text rendering of every tab is in [Screen Snapshots](#screen-snapshots).

### Tabs

| Tab | Key | Description |
|-----|-----|-------------|
| **Overview** | `1` | System health, live metrics (requests, latency, tokens, cost), component status. |
| **Pipeline** | `2` | Interactive pipeline visualization. Run test queries and observe step-by-step execution with timing. Supports keyboard-driven step reordering (Alt+Up/Down). |
| **Debugger** | `3` | Browse execution traces, filter by status, inspect individual trace steps with duration breakdown, anomaly detection, and trace export. |
| **Telemetry** | `4` | Latency/throughput charts, per-operation cost breakdown, and performance percentile tables (p50/p95/p99). |
| **Config and Plugins** | `5` | Interactive configuration editor and plugin documentation with code examples and inline API reference for all plugin types. |
| **Ingest** | `6` | File and directory ingestion interface with progress tracking and metadata attachment. |
| **Evaluation** | `7` | Run evaluation suites, view per-query scores, and browse historical evaluation reports. |
| **Experiments** | `8` | Record experiments, list historical runs, and compare experiment metrics side-by-side. |
| **Logs** | `9` | Live structured log stream with level filtering and text search. |
| **Playground** | `0` | Side-by-side A/B query comparison with document-overlap and latency diff. |
| **Replay** | -- | Step through a recorded pipeline execution (open via Command Palette). |
| **Builder** | `b` | Visual pipeline builder canvas with a typed-slot stage catalog. Connections are validated by slot type and rejected on cycles; seed from the live config. |
| **Docs** | `d` | In-app cookbook, get-started starters, and help browser with a searchable, grouped topic sidebar. |

### Keyboard Shortcuts

| Key | Action |
|-----|--------|
| `q` | Quit |
| `r` | Refresh all data |
| `1` -- `9`, `0` | Switch tabs |
| `Ctrl+P` | Command palette (fuzzy action search) |
| `Ctrl+E` | Export current config |
| `Alt+↑` / `Alt+↓` | Reorder pipeline steps (Pipeline tab) |
| `?` / `F1` | Keyboard shortcuts help |

---

## Python API Reference

### Core Engine Methods

| Method | Description |
|--------|-------------|
| `engine.retrieve(query, top_k=5, encoder=None)` | Retrieve relevant documents for a query. Returns `RetrievalResult`. |
| `engine.ingest(documents, encoder=None)` | Ingest documents into the pipeline. Accepts list of dicts with `content` and `metadata` keys. |
| `engine.update(document_id, content, metadata=None, confidence_score=1.0)` | Update a document with write-back protection. Returns `WriteBackResult`. |
| `engine.generate(query, encoder=None, top_k=None, system_prompt=None, temperature=None, max_tokens=None, evaluate=False)` | Retrieve + generate an answer. Returns `GenerateResponse`. Set `evaluate=True` for inline scoring. |
| `engine.stream(query, encoder=None, top_k=None, system_prompt=None, temperature=None, max_tokens=None)` | Async streaming retrieve + generate. Yields `StreamEvent` objects (type: `token`, `metadata`, `done`). |
| `engine.batch_ingest(documents, batch_size=50, encoder=None, on_progress=None, deduplicate=True, max_concurrent_batches=3)` | Concurrent batch ingestion with progress callbacks and automatic deduplication. |

### Observability Methods

| Method | Description |
|--------|-------------|
| `engine.list_traces(limit=100)` | List execution traces. |
| `engine.get_trace(trace_id)` | Get a single trace with full step tree. |
| `engine.get_metrics_summary()` | JSON metrics summary (requests, cost, latency, histograms). |
| `engine.get_telemetry_status()` | OTel and Prometheus configuration and connection status. |
| `engine.get_cache_stats()` | Embedding cache hit/miss/eviction statistics. |
| `engine.get_chunk_report()` | Chunk size distribution report. |
| `engine.get_hook_info()` | Registered lifecycle hooks and their configuration. |
| `engine.get_token_counter()` | Access the engine's token counter for budget allocation. |

### Constructors

| Constructor | Description |
|-------------|-------------|
| `GlassBoxEngine(config)` | Standard constructor from a `GlassBoxConfig` object. |
| `GlassBoxEngine.from_env()` | Zero-config constructor. Auto-detects API keys and backends from environment variables. |
| `GlassBoxConfig.from_env()` | Build configuration purely from environment variables (`OPENAI_API_KEY`, `OLLAMA_BASE_URL`, `GLASSBOX_*`, etc.). |

### Response Types

**GenerateResponse** -- returned by `engine.generate()`:

| Field | Type | Description |
|-------|------|-------------|
| `answer` | `str` | Generated answer text |
| `sources` | `list[dict]` | Source documents used for generation |
| `retrieval` | `dict` | Retrieval metadata (strategy, timing, count) |
| `generation` | `dict` | Generation metadata (model, tokens, timing) |
| `trace_id` | `str` | Trace ID for debugging |
| `pipeline_version` | `int` | Current pipeline version number |
| `evaluation` | `InlineEvaluation or None` | Faithfulness, groundedness, context_relevance scores (only when `evaluate=True`) |

Supports dict-like access for backward compatibility: `response["answer"]` works alongside `response.answer`.

---

## Plugin Architecture

GlassBox supports six plugin types. The plugin registry is thread-safe and supports both built-in and third-party plugins.

### Supported Plugin Types

| Type | Description | Built-in Implementations |
|------|-------------|--------------------------|
| `vector_store` | Vector similarity search | Qdrant, Chroma, FAISS, Pinecone, Weaviate, Supabase |
| `database` | Document storage | PostgreSQL, SQLite, MongoDB, MySQL, Supabase |
| `encoder` | Text embedding providers | OpenAI, Cohere, Google, Ollama, ONNX, Hugging Face |
| `reranker` | Post-retrieval reranking | Cross-encoder, Cohere, Hugging Face |
| `chunker` | Text chunking strategies | Recursive, Sentence, Semantic, Fixed |
| `processor` | Content processors | PDF, Image (OCR), PPTX |

### Writing a Vector Store Plugin

```python
from glassbox_rag.plugins.base import VectorStorePlugin

class CustomVectorStore(VectorStorePlugin):
    async def initialize(self) -> bool:
        # Connect to your backend
        return True

    async def shutdown(self) -> None:
        # Clean up connections
        pass

    async def health_check(self) -> bool:
        return True

    async def add_vectors(self, vectors, ids=None, contents=None, metadata=None):
        # Store vectors and return list of IDs
        return ["id-1", "id-2"]

    async def search(self, query_vector, top_k=5):
        # Return list of (id, score, content, metadata) tuples
        return [("id-1", 0.95, "document text", {"source": "example"})]

    async def get_vector(self, vector_id):
        return {"id": vector_id, "content": "...", "metadata": {}}

    async def delete_vector(self, vector_id):
        return True

    async def count(self):
        return 42
```

### Writing a Database Plugin

```python
from glassbox_rag.plugins.base import DatabasePlugin

class CustomDatabase(DatabasePlugin):
    async def initialize(self) -> bool:
        return True

    async def shutdown(self) -> None:
        pass

    async def health_check(self) -> bool:
        return True

    async def connect(self) -> bool:
        return True

    async def insert(self, table, data):
        return "record-id"

    async def update(self, table, record_id, data):
        return True

    async def delete(self, table, record_id):
        return True

    async def query(self, table, filters=None):
        return [{"id": "1", "content": "..."}]

    async def search_text(self, terms, top_k=10):
        return [{"id": "1", "content": "...", "score": 0.9}]

    async def ensure_tables(self) -> None:
        pass
```

### Registering Custom Plugins

**Decorator-based registration:**

```python
from glassbox_rag.plugins.sdk import register_plugin

@register_plugin("vector_store", "my_store")
class MyStore(VectorStorePlugin):
    ...
```

**Programmatic registration:**

```python
from glassbox_rag.plugins.sdk import plugin_registry

plugin_registry.register("vector_store", "my_store", MyStore)
```

**Configuration-based loading:**

```yaml
plugins:
  custom:
    - type: vector_store
      name: my_store
      module: mypackage.my_vector_store
      class: MyVectorStore
```

### Plugin Test Harness

```python
from glassbox_rag.plugins.sdk import PluginTestHarness

results = await PluginTestHarness.test_vector_store(my_store_instance)
print(results["passed"])   # ["initialize", "health_check", "add_vectors", ...]
print(results["failed"])   # []
```

### Query Pipeline Hooks

```python
from glassbox_rag import GlassBoxEngine, HookPoint

engine = GlassBoxEngine(config)
await engine.initialize()

# Decorator-based registration
@engine.hooks.on(HookPoint.POST_RETRIEVE, priority=10)
async def log_results(context):
    print(f"Retrieved {len(context['documents'])} documents")
    return context

# Direct registration
async def filter_low_scores(context):
    context["documents"] = [d for d in context["documents"] if d.score > 0.5]
    return context

engine.hooks.register(HookPoint.POST_RETRIEVE, filter_low_scores, priority=20)
```

**Available Hook Points:**

| Hook Point | Trigger |
|------------|---------|
| `HookPoint.PRE_RETRIEVE` | Before query encoding and retrieval |
| `HookPoint.POST_RETRIEVE` | After retrieval, before returning results |
| `HookPoint.PRE_GENERATE` | Before LLM generation (RAG context ready) |
| `HookPoint.POST_GENERATE` | After LLM response is generated |
| `HookPoint.PRE_INGEST` | Before document ingestion |
| `HookPoint.POST_INGEST` | After document ingestion (drift detector runs here) |
| `HookPoint.PRE_RERANK` | Before reranking pass |
| `HookPoint.POST_RERANK` | After reranking pass |
| `HookPoint.ON_ERROR` | When any pipeline operation fails (errors swallowed) |

Hooks execute in priority order (lower values run first). Each hook has a configurable timeout (default: 30 seconds).

---

## Framework Adapters

GlassBox integrates with popular LLM frameworks. All adapters include safe sync-to-async bridging for use inside running event loops (Jupyter, Colab, etc.).

### LangChain

```python
from glassbox_rag.adapters.langchain import GlassBoxRetriever, GlassBoxEmbeddings

# As a retriever (LCEL-compatible)
retriever = GlassBoxRetriever(engine=engine, top_k=5, encoder="openai")
docs = await retriever.ainvoke("your query")        # async (primary)
docs = retriever.invoke("your query")               # sync (auto-bridged)

# As an embeddings provider
embeddings = GlassBoxEmbeddings(engine=engine, encoder="openai")
vectors = await embeddings.aembed_documents(["text1", "text2"])
query_vec = await embeddings.aembed_query("your query")
```

Registers as a virtual subclass of `langchain_core.retrievers.BaseRetriever` and `langchain_core.embeddings.Embeddings` when langchain-core is installed.

### LlamaIndex

```python
from glassbox_rag.adapters.llamaindex import GlassBoxQueryEngine, GlassBoxLlamaRetriever

# As a query engine (retrieve + generate)
query_engine = GlassBoxQueryEngine(engine=engine, top_k=5)
response = await query_engine.aquery("your query")  # returns llama_index Response

# As a retriever only
retriever = GlassBoxLlamaRetriever(engine=engine, top_k=5)
nodes = await retriever.aretrieve("your query")     # returns NodeWithScore list
```

### Haystack

```python
from glassbox_rag.adapters.haystack import GlassBoxHaystackRetriever

# As a Haystack component (decorated with @component when haystack-ai is installed)
retriever = GlassBoxHaystackRetriever(engine=engine, top_k=5)
result = await retriever.run(query="your query")
haystack_docs = result["documents"]
```

Install adapters with:

```bash
pip install "glassbox-rag[adapters-langchain]"    # langchain-core
pip install "glassbox-rag[adapters-llamaindex]"    # llama-index-core
pip install "glassbox-rag[adapters-haystack]"      # haystack-ai
pip install "glassbox-rag[adapters]"               # all three
```

---

## Evaluation System

GlassBox includes a built-in evaluation framework for measuring retrieval and generation quality.

### Golden Datasets

Define expected results in YAML:

```yaml
queries:
  - query: "What is GlassBox?"
    expected_doc_ids: ["doc-1", "doc-3"]
    expected_answer_keywords: ["modular", "RAG", "framework"]
  - query: "How does chunking work?"
    expected_doc_ids: ["doc-5"]
```

### Running Evaluations

```python
from glassbox_rag.evaluation import EvaluationRunner, GoldenDataset

dataset = GoldenDataset.from_yaml(".glassbox/datasets/golden.yaml")
runner = EvaluationRunner(pipeline=engine, eval_config=config.evaluation)
report = await runner.run(dataset, metrics=["recall@5", "precision@5", "faithfulness"])
print(report.summary())
```

### Regression Testing

```python
regression = report_a.compare(report_b, threshold=0.05)
print(regression.summary())
```

### CLI Evaluation

```bash
glassbox-rag eval run --dataset golden.yaml --metrics "recall@5,faithfulness"
glassbox-rag eval compare report_a.json report_b.json --threshold 0.05
```

---

## Experiment Tracking

Record and compare pipeline experiments with full provenance tracking.

```python
from glassbox_rag import ExperimentTracker

tracker = ExperimentTracker.from_workspace()

# Record an experiment
record = tracker.record(config_version=1, dataset_version="v2", trace_id="abc123")

# List experiments
experiments = tracker.list(limit=20)

# Compare two experiments
report = tracker.compare("exp-a-id", "exp-b-id")
print(report.summary)
```

Experiments are stored in `.glassbox/experiments/` and include:
- Pipeline version number
- Git commit hash (auto-detected)
- Dataset version identifier
- Evaluation metric results
- Timestamp

---

## Version Management

```python
from glassbox_rag import VersionManager

vm = VersionManager()
vm.snapshot(config)                    # Save current pipeline configuration
current_version = vm.current_version   # Get current version number
```

Versioning state is stored in `.glassbox/versions/` with auto-incrementing version numbers. The pipeline version is automatically attached to every `GenerateResponse`.

---

## Advanced Retrieval Strategies

GlassBox supports configurable retrieval strategies that can be composed as pipeline hooks.

### Query Rewriting

LLM-based query rewriting for improved retrieval quality:

```yaml
query_rewrite:
  enabled: true
  prompt_template: "Rewrite the following user query into a clearer form.\n\nQuery: {query}"
```

### Context Compression

Post-retrieval context compression to reduce noise before generation:

```yaml
context_compression:
  enabled: true
```

### Parent-Child Retrieval

Retrieve child chunks but return parent documents for broader context:

```yaml
parent_child:
  enabled: true
```

### Multi-Query Expansion

Expand a single query into multiple sub-queries with reciprocal rank fusion:

```yaml
multi_query:
  enabled: true
  num_queries: 3
  fusion_method: "rrf"
```

### HyDE (Hypothetical Document Embeddings)

Embed a generated hypothetical answer instead of the raw query:

```yaml
hyde:
  enabled: true
  keep_original: true   # append the original query to the hypothetical passage
```

### Chain-of-Retrieval (CoRAG)

Iteratively refine retrieval over multiple LLM-guided steps (requires a generation backend):

```yaml
corag:
  enabled: true
  max_steps: 3
  docs_per_step: 5
```

When enabled, `engine.retrieve()` runs the chain and returns fused, de-duplicated
documents with `strategy="corag"`.

### GraphRAG

Multi-hop knowledge-graph retrieval. When enabled, a `graph` strategy is
registered and the adaptive router sends relationship / multi-entity queries to it:

```yaml
graph:
  enabled: true
  backend: "networkx"     # networkx (in-process) or neo4j
  max_hops: 2
  max_seeds: 5
  # Neo4j connection (backend: neo4j)
  uri: "bolt://localhost:7687"
  user: "neo4j"
  password: "${NEO4J_PASSWORD}"
  database: "neo4j"
```

```python
# Programmatic graph construction
from glassbox_rag.plugins.graph_stores import create_graph_store, Entity, Relationship

store = create_graph_store("networkx")
await store.initialize()
await store.upsert_entity(Entity(id="1", name="Transformers", type="architecture"))
await store.upsert_entity(Entity(id="2", name="Attention", type="mechanism"))
await store.upsert_relationship(Relationship("1", "2", type="uses"))
```

### Contextual RAG

Prepend a document-level context summary to each chunk before embedding
(Anthropic-style Contextual Retrieval), improving recall for ambiguous chunks:

```yaml
contextual_rag:
  enabled: true
  max_context_chars: 200
```

### TreeRAG (Hierarchical Summaries)

Build a RAPTOR-style summary tree and ingest all levels (collapsed-tree retrieval):

```python
from glassbox_rag.core.strategies import TreeRAGBuilder

tree = await TreeRAGBuilder(generator=engine._generator, branching=4).build(chunk_texts)
await engine.ingest(tree.to_documents())   # leaves + multi-level summaries
```

### Dynamic Chunking

Content-adaptive chunk sizing (dense/structured text → smaller chunks, prose → larger):

```yaml
chunking:
  strategy: "dynamic"
  chunk_size: 512      # base target; adapts per document
```

### Automated Optimization

Tune retrieval parameters against a golden set (closes the optimize↔evaluate loop):

```python
from glassbox_rag.benchmarks import BenchmarkCase

cases = [BenchmarkCase(query="...", relevant_ids={"doc-1"})]
result = await engine.auto_tune(cases)   # searches top_k/min_score, applies best
print(result["best_params"])
```

### Multi-Tenancy

Isolate tenants at ingest + query time:

```yaml
multi_tenancy:
  enabled: true
```

```python
from glassbox_rag.core.tenancy import TenantContext, tenant_scope

engine.tenant_manager.register(TenantContext("acme"))
with tenant_scope(engine.tenant_manager, "acme"):
    await engine.ingest(docs)              # chunks tagged _tenant=acme
    result = await engine.retrieve("...")  # results filtered to acme
```

### Indexing Extras

```yaml
indexing_extras:
  drift_detection_enabled: true    # Detect embedding drift across ingestion batches
  drift_threshold: 0.15            # Cosine distance threshold for drift alerts
  freshness_validation: true       # Warn if encoder config changed since last ingestion
  lineage_tracking: true           # Track chunk-to-document lineage metadata
```

---

## GraphRAG and Agentic RAG

### Agentic RAG

`RAGAgent` performs multi-hop, tool-using reasoning with self-correction:

```python
from glassbox_rag.core.agent import RAGAgent, Tool

async def retrieve_fn(query: str):
    result = await engine.retrieve(query, top_k=5)
    return result.documents

async def calculator(expression: str = ""):
    return eval(expression, {"__builtins__": {}})  # illustrative only

agent = RAGAgent(retrieve_fn, generator=engine._generator, max_iterations=3)
agent.register_tool(Tool("calc", "evaluate arithmetic", calculator))

result = await agent.run("How do Transformers relate to attention, and why?")
print(result.answer)
for step in result.steps:      # full, inspectable reasoning trace
    print(step.kind, step.detail)
```

### Adaptive Query Router

```python
from glassbox_rag.core.query_router import QueryComplexityClassifier

router = QueryComplexityClassifier(available_strategies=["semantic", "hybrid", "graph", "corag"])
decision = router.classify("Compare the relationship between BERT and GPT")
print(decision.complexity, decision.strategy)   # complex -> graph/corag
```

---

## Source Attribution and Provenance

Enable citations in config and `engine.generate()` automatically attaches
inline markers + a reference list and returns a structured `citations` list:

```yaml
citations:
  enabled: true
  style: "numeric"    # numeric | bracket | footnote
  inline: true        # rewrite the answer with [n] markers + a Sources block
  min_overlap: 0.15
```

```python
response = await engine.generate("What is GlassBox?")
print(response.answer)        # "... modular RAG framework [1]. ... Sources: [1] ..."
print(response.citations)     # [{"index": 1, "document_id": "...", "title": "...", ...}]
```

You can also use the renderer and provenance tracker directly:

```python
from glassbox_rag.core.citations import CitationRenderer, CitationStyle
from glassbox_rag.core.provenance import ProvenanceTracker

# Attach inline citations to an answer
renderer = CitationRenderer(style=CitationStyle.NUMERIC)
attributed = renderer.attribute(answer_text, retrieved_documents)
print(attributed.with_references())

# Track full chunk lineage: source -> document -> chunk -> embedding
tracker = ProvenanceTracker()
tracker.track(chunk_id="c1", content="...", source_id="doc.pdf",
              document_id="d1", encoder="openai", embedding_dim=1536)
print(tracker.lineage("c1"))
```

---

## Enterprise Security

The `glassbox_rag.security` package provides opt-in, composable controls:

```python
from glassbox_rag.security import (
    SecurityGateway, RBACManager, Principal, Permission,
    PIIDetector, PromptInjectionDetector, AuditLog,
)

rbac = RBACManager()
rbac.add_principal(Principal(id="alice", roles={"viewer"}))

gateway = SecurityGateway(rbac=rbac, audit=AuditLog(".glassbox/audit.log"))

result = gateway.guard_query(user_query, retrieved_documents, principal_id="alice")
if result.allowed:
    context = result.documents          # ACL-filtered + PII-redacted + injection-sanitised
else:
    print("Blocked:", result.reason)    # e.g. prompt_injection_blocked
```

- **RBAC** -- roles/permissions with per-document ACL filtering. `filter_documents(principal_id, docs, acl_key="acl_roles")` keeps a document when the principal holds one of the roles listed under `metadata["acl_roles"]` (the `acl_key` is configurable). Documents with **no** ACL metadata are shown to everyone by default (fail-open); construct `RBACManager(fail_closed=True)` (or pass `fail_closed=True` to `filter_documents`) for deny-by-default. Untagged documents always emit a warning so gaps are visible.
- **PII** -- `PIIDetector.redact(text, reversible=True)` returns a token map for later restoration.
- **Prompt injection** -- scans queries and retrieved documents (indirect injection).
- **Audit** -- append-only, hash-chained trail. `AuditLog.verify_chain()` re-reads the log file from disk before verifying, so it detects tampering of the persisted record even from a fresh process (returns `False` on any altered or truncated line).

---

## API Toolkit and Serverless

```python
# FastAPI app (requires glassbox-rag[api])
from glassbox_rag.api_toolkit import create_api

app = create_api(engine, require_api_key="my-secret")
# uvicorn module:app  →  POST /query, POST /generate, POST /ingest, GET /health
```

```python
# AWS Lambda handler (no web framework required)
from glassbox_rag.api_toolkit import lambda_handler_factory

def build_engine():
    return GlassBoxEngine.from_env()

handler = lambda_handler_factory(build_engine)   # (event, context) -> response
```

A GCP `cloud_function_factory` is also provided.

---

## Data Syncing and Connectors

```python
from glassbox_rag.sync import SyncEngine, FileSystemConnector, SyncLedger

sync = SyncEngine(
    FileSystemConnector("./knowledge", glob="**/*.md"),
    engine,
    ledger=SyncLedger(".glassbox/sync.json"),
)
delta = await sync.sync_once()      # ingests added/changed, deletes removed
print(delta.summary())              # {"added": .., "changed": .., "deleted": .., "unchanged": ..}

# Or run continuously
# await sync.run_polling(interval_seconds=300)

# Network-backed sources (pip install glassbox-rag[sync]):
from glassbox_rag.sync import GoogleDriveConnector, ConfluenceConnector

drive = GoogleDriveConnector(folder_id="abc123")   # GOOGLE_APPLICATION_CREDENTIALS
wiki = ConfluenceConnector(space_key="ENG")        # CONFLUENCE_URL / _USER / _TOKEN
```

Connectors: `FileSystemConnector`, `WebhookConnector`, `HTTPConnector`, `NotionConnector`, `GoogleDriveConnector`, `ConfluenceConnector`. The network-backed connectors read credentials from the environment, request read-only scopes, and degrade gracefully (log + return `[]`) when a dependency or credential is missing. Each accepts `seed_documents=[...]` for offline/unit testing.

---

## Heterogeneous Data Corpora

```python
from glassbox_rag.corpus import TabularCorpus, TextToSQL, TableSchema, ConversationalCorpus

# Tabular (DuckDB, with a stdlib csv fallback)
tc = TabularCorpus()
tc.load("data/products.csv")
docs = tc.rows_to_documents(template="{name}: {description} (${price})")

# Text-to-SQL over a declared schema
t2s = TextToSQL([TableSchema("users", {"id": "int", "name": "text"})],
                generator=engine._generator, read_only=True)
sql = await t2s.to_sql("how many users are there?")
```

Adapters:
- **Text-to-SQL** — dialect-aware (SQLite/PostgreSQL/MySQL) with schema validation and read-only guards.
- **Tabular** — CSV / Parquet / Excel (`.xlsx`) via DuckDB (with a stdlib CSV fallback).
- **Object storage** — S3, Google Cloud Storage, and Azure Blob (sync-ledger friendly).
- **NoSQL** — MongoDB, DynamoDB, and Elasticsearch (BM25 + dense-vector hybrid). Connectors accept `principal_roles` for RBAC data-layer filtering.
- **Conversational** — `ConversationDocument` with temporal (`before`/`after`) filters and adjacent-window expansion.

---

## Context Engine and Personalization

```python
from glassbox_rag.context import ContextFusion, ContextSource
from glassbox_rag.personalization import SessionMemory, Turn, UserContextLayer, UserProfile

# Fuse results from multiple retrievers (RRF)
fused = ContextFusion().fuse([
    ContextSource("vector", vector_docs, weight=1.0),
    ContextSource("graph", graph_docs, weight=0.8),
], top_k=10)

# Session memory with follow-up resolution
mem = SessionMemory(max_turns=10)
mem.add("session-1", Turn("Tell me about Transformers", answer))
standalone = mem.resolve_followup("session-1", "how does it scale?")

# Per-user personalization (interest boosting + source filtering)
users = UserContextLayer()
users.upsert(UserProfile(user_id="u1", interests=["python"], allowed_sources={"wiki"}))
ranked = users.personalize("u1", documents)
```

---

## Automated Optimization

```python
from glassbox_rag.optimization import AutoTuner, ParamSpace, FeedbackLearner, FeedbackEvent

# Search retrieval parameters against an async objective (e.g. eval recall)
space = ParamSpace().add("top_k", [3, 5, 10]).add("alpha", [0.3, 0.5, 0.7])
async def objective(params):
    return await evaluate_recall(params)
result = await AutoTuner().optimize(space, objective, n_trials=20)
print(result.best_params, result.best_score)

# Continuous feedback learning re-ranks by learned quality priors
learner = FeedbackLearner()
learner.record(FeedbackEvent(query="python tutorial", document_id="doc1", signal=1.0))
reranked = learner.rerank("python tutorial", documents)
```

---

## Scale and Distributed Mode

```python
from glassbox_rag.distributed import create_task_queue, Worker, Task
from glassbox_rag.core.tenancy import TenantManager, TenantContext, TenantQuota
from glassbox_rag.core.events import EventBus, QueryReceived, ChunksRetrieved

# Distributed task queue (in-memory default; Redis Streams via [distributed])
queue = create_task_queue("redis", url="redis://localhost:6379")
worker = Worker(queue)

@worker.handler("ingest")
async def _ingest(task: Task):
    await engine.batch_ingest(task.payload["documents"])

# Multi-tenancy with quotas + namespace isolation
tenants = TenantManager()
tenants.register(TenantContext("acme", quota=TenantQuota(max_documents=100_000)))

# Typed event bus — every engine exposes one as an observability channel.
# The engine publishes retrieval.chunks and generation.answer events; subscribe
# without touching internals. (Hooks are never double-fired: the bus is not
# auto-bridged — call engine.event_bus.bridge_hook_manager(engine.hooks) to opt in.)
engine.event_bus.subscribe(ChunksRetrieved.name, lambda e: print("retrieved:", e.payload))
```

The adaptive retriever can also delegate strategy selection to the shared
`QueryComplexityClassifier` instead of its built-in heuristic:

```yaml
retrieval:
  adaptive:
    enabled: true
    use_router: true      # route via QueryComplexityClassifier (one routing brain)
```

Also included: SQLite WAL crash recovery (`glassbox_rag.core.wal`), versioned index
migrations (`glassbox_rag.versioning.migrations`), an AOT pipeline compiler
(`glassbox_rag.pipelines.compiler`), and a gRPC transport (`glassbox_rag.transport`).

---

## Solution Blueprints

Opinionated, one-call configurations for common use cases:

```python
from glassbox_rag.blueprints import get_blueprint, list_blueprints

blueprint = get_blueprint("customer_support")   # or legal_analysis, internal_kb, research_assistant
config = blueprint.to_config()
engine = GlassBoxEngine(config)
```

---

## Observability

### OpenTelemetry

Enable OTLP export in configuration:

```yaml
telemetry:
  otel_enabled: true
  otel_exporter: "otlp"              # otlp, jaeger, zipkin, console
  otel_endpoint: "http://localhost:4317"
  service_name: "glassbox-rag"
```

### Prometheus Metrics

Metrics can be exported in Prometheus text format via the engine's telemetry module:

```python
content = engine.telemetry.get_prometheus_metrics()
```

Tracked metrics include: total requests, tokens used, estimated cost, per-operation latency percentiles (p50/p95/p99), embedding cache hit rate, active request count, vector and chunk counts.

### Trace Storage

Traces can be stored in memory (default), Redis, or PostgreSQL:

```yaml
trace:
  enabled: true
  backend: "redis"            # or "postgresql" or "memory"
  retention_days: 30
  sample_rate: 1.0            # 0.0 to 1.0
```

---

## Deployment

GlassBox is a CLI / TUI tool and library (there is no built-in HTTP server —
expose one yourself with the optional [API toolkit](#api-toolkit-and-serverless)).
The provided Docker assets package the CLI and stand up its backing services.

### Docker

```bash
docker build -t glassbox-rag .

# Any CLI command (the TUI needs an interactive terminal, so add -it):
docker run --rm -it -v "$(pwd)/config:/app/config:ro" \
  -e OPENAI_API_KEY=your_key glassbox-rag tui
```

### Docker Compose (local stack)

`docker-compose.yml` brings up the backing services (Qdrant, PostgreSQL, Redis,
and optional Ollama) and a `glassbox` container wired to them via `from_env()`:

```bash
docker compose up -d qdrant postgres redis      # start backends
docker compose run --rm glassbox tui            # launch the dashboard
docker compose run --rm glassbox ingest ./data  # or any CLI command
docker compose --profile ollama up -d ollama    # optional local models
```

### Integration testing

`docker-compose.test.yml` runs the integration suite against real Qdrant /
PostgreSQL / Redis / Chroma backends:

```bash
docker compose -f docker-compose.test.yml up --build --abort-on-container-exit
```

---

## Architecture

```
  CLI / Python API
       |
       v
  GlassBox Engine
       |
       +-- Encoding Layer -----> [OpenAI | Cohere | Ollama | ONNX | Google | HF]
       +-- Chunker ------------> [Recursive | Sentence | Semantic | Fixed]
       +-- Deduplicator -------> [Content Hash | SimHash | Semantic Embedding]
       +-- Retriever ----------> [Semantic | Keyword | Hybrid | Adaptive]
       +-- Reranker -----------> [Cross-Encoder | Cohere | HuggingFace]
       +-- Generator ----------> [OpenAI | Ollama] (with streaming)
       +-- Vector Store -------> [Qdrant | Chroma | FAISS | Pinecone | Weaviate | Supabase]
       +-- Database -----------> [PostgreSQL | SQLite | MongoDB | MySQL | Supabase]
       +-- Write-Back Manager -> [Protected | Full | Read-Only]
       +-- Hook Manager -------> [Pre/Post Retrieve | Pre/Post Generate | ...]
       |
       +-- Trace Tracker ------> [Memory | Redis | PostgreSQL]
       +-- Metrics Tracker ----> [Prometheus | JSON]
       +-- Telemetry ----------> [OpenTelemetry | Console]
       |
       +-- Evaluation ----------> [Retrieval Metrics | Generation Metrics | Regression]
       +-- Experiments ---------> [Record | Compare | Git Association]
       +-- Versioning ----------> [Pipeline Snapshots | Prompt Versioning]
       |
       +-- Strategies ----------> [Query Rewrite | Multi-Query | Parent-Child | Context Compression | HyDE | CoRAG]
       +-- GraphRAG ------------> [NetworkX | Neo4j] + Graph Retriever (multi-hop)
       +-- Agentic RAG ---------> [Tool Calling | Multi-Hop | Self-Correction]
       +-- Security ------------> [RBAC | PII | Prompt-Injection | Audit | Classification]
       +-- Indexing Extras -----> [Drift Detection | Freshness Validation | Lineage Tracking]
       |
       v
  Terminal Dashboard (TUI)
       |
       +-- Overview (live metrics + health)
       +-- Pipeline (interactive visualization)
       +-- Debugger (trace inspection)
       +-- Telemetry (charts + tables)
       +-- Config & Plugins (editor + docs)
       +-- Ingest (file ingestion)
       +-- Evaluation (golden dataset scoring)
       +-- Experiments (experiment management)
```

### Project Structure

```
glassbox-rag/
  src/glassbox_rag/
    __init__.py              # Public API and version
    __main__.py              # python -m glassbox_rag support
    config.py                # Pydantic v2 configuration models
    cli.py                   # CLI entry point (12 commands)
    core/
      engine.py              # Main orchestrator
      retriever.py           # Adaptive retrieval strategies
      chunker.py             # Text chunking with size monitoring
      encoder.py             # Modular encoding layer with cache
      generator.py           # LLM generation with streaming
      hooks.py               # Pipeline hook system with timeouts
      dedup.py               # Document deduplication (exact, fuzzy, semantic)
      tokens.py              # Token counting with context window budgeting
      writeback.py           # Write-back protection
      metrics.py             # Cost and latency tracking
      reranker.py            # Cross-encoder reranking
      indexing_extras.py     # Lineage, drift detection, freshness validation
      agent.py               # Agentic RAG (tool calling, self-correction)
      graph_retriever.py     # GraphRAG multi-hop retrieval
      citations.py           # Source attribution / citation rendering
      provenance.py          # Chunk lineage tracking
      query_router.py        # Adaptive query complexity router
      events.py              # Typed event bus
      tenancy.py             # Multi-tenancy + quotas
      wal.py                 # SQLite WAL crash recovery
      strategies/
        query_rewrite.py     # LLM-based query rewriting hook
        multi_query.py       # Multi-query expansion with RRF
        parent_child.py      # Parent-child document retrieval
        context_compression.py  # LLM-based context compression
        hyde.py              # Hypothetical Document Embeddings hook
        corag.py             # Chain-of-Retrieval strategy
    trace/
      tracker.py             # Concurrency-safe trace system
      visualizer.py          # ASCII trace rendering
      backends.py            # Persistent trace storage (Redis, PostgreSQL)
    evaluation/
      runner.py              # Evaluation runner and reporting
      datasets.py            # Golden dataset loader
      retrieval.py           # Retrieval quality metrics
      generation.py          # LLM-as-judge generation metrics
    experiments/
      experiment_tracker.py  # Experiment recording and comparison
    versioning/
      version_manager.py     # Pipeline and prompt versioning
    git/
      manager.py             # Git integration for experiment provenance
    pipelines/
      manager.py             # Multi-pipeline workspace management
      dag.py                 # DAG-based pipeline execution
      context.py             # Typed pipeline context
      introspect.py          # Config-driven pipeline description
      compiler.py            # AOT pipeline compiler
    tui/
      app.py                 # Main TUI application
      client.py              # In-process engine client
      theme.py               # TUI styling
      commands.py            # Command palette provider (Ctrl+P)
      screens/               # Overview, Pipeline, Debugger, Telemetry, Config,
                             # Ingest, Evaluation, Experiments, Logs, Playground, Replay
      widgets/               # Reusable TUI widgets (metric cards,
                             # trace tree, pipeline view, etc.)
    plugins/
      base.py                # Abstract plugin interfaces
      sdk.py                 # Plugin registry and developer SDK
      registry.py            # Plugin marketplace index + entry-point discovery
      vector_stores/         # Qdrant, Chroma, FAISS, Pinecone, Weaviate
      databases/             # PostgreSQL, SQLite, MongoDB, MySQL
      graph_stores/          # NetworkX + Neo4j (GraphRAG)
      supabase.py            # Supabase (vector store + database)
    security/                # RBAC, PII, prompt-injection, audit, gateway
    api_toolkit/             # FastAPI app + serverless handlers
    sync/                    # Sync engine, connectors, delta ledger
    corpus/                  # Text-to-SQL, tabular, object storage, NoSQL, conversational
    context/                 # Context fusion, real-time nodes, streaming ingestion
    personalization/         # Session memory, user context layer
    optimization/            # Auto-tuning, feedback learning
    distributed/             # Task queue (in-memory + Redis Streams), workers
    accel/                   # Accelerated kernels (cosine, BM25, SimHash, LRU)
    sandbox/                 # WASM plugin sandbox
    transport/               # gRPC service + .proto
    blueprints/              # Solution blueprints
    benchmarks/              # Reproducible benchmark harness
    loaders.py               # Document loaders (text, markdown, jsonl, dir)
    adapters/
      langchain.py           # LangChain retriever and embeddings
      llamaindex.py          # LlamaIndex query engine and retriever
      haystack.py            # Haystack component retriever
      _utils.py              # Sync-to-async bridging utilities
    utils/
      auth.py                # JWT authentication + Redis rate limiting
      multimodal.py          # PDF, image, PPTX extraction
      telemetry.py           # OTel + Prometheus integration
      logging.py             # Structured logging
      helpers.py             # Shared utility functions
  config/
    default.yaml             # Default configuration
  examples/                  # Example scripts
  tests/                     # Unit and integration test suites
```

---

## Testing

```bash
# Run all tests
pytest tests/ -v

# Run with coverage
pytest tests/ --cov=glassbox_rag --cov-report=html

# Run specific categories
pytest tests/unit/ -v
pytest tests/integration/ -v

# Run integration tests that require external services
pytest tests/integration/ -v -m integration_real
```

---

## Contributing

Contributions are welcome. Please:

1. Fork the repository
2. Create a feature branch
3. Add tests for new functionality
4. Ensure all tests pass and type checks succeed
5. Submit a pull request

See [CONTRIBUTING.md](CONTRIBUTING.md) for detailed guidelines.

---

## License

Licensed under the Apache License 2.0. See the [LICENSE](LICENSE) file for details.

---

## Links

- **Repository**: [github.com/averoe/GlassBox](https://github.com/averoe/GlassBox)
- **Issues**: [github.com/averoe/GlassBox/issues](https://github.com/averoe/GlassBox/issues)
- **Changelog**: [CHANGELOG.md](CHANGELOG.md)
