Cofone
Simple, fast, yours. Turn documents, websites and videos into a queryable knowledge base in a few lines of Python.
from dotenv import load_dotenv
from cofone import RAG
load_dotenv() # reads OPENROUTER_API_KEY from .env
answer = RAG().add_source("docs/").run("Who is Leonardo?")
print(answer)
What is Cofone?
Cofone is an open-source Python RAG (Retrieval-Augmented Generation) library.
Load any document, ask questions in natural language, get precise answers — without complex setup or boilerplate.
Key highlights:
- Fluent DSL — chain everything in one expression
- BM25 (default) + FAISS semantic search
- 19 LLM providers: OpenRouter, OpenAI, Anthropic, Gemini, Mistral, Groq, Cohere, DeepSeek, xAI, Together, Perplexity, Fireworks, Cerebras, NVIDIA, DeepInfra, Anyscale, Ollama, LM Studio, llama.cpp
- 10 embedding providers: local sentence-transformers, OpenAI, Gemini, Cohere, Mistral, Voyage, Jina, NVIDIA, Together, Ollama
- Smart chunking that respects document structure
- Chat memory, streaming, structured output (Pydantic)
- FAISS index persistence to disk
- Sources: files, folders, PDFs, web URLs, Wikipedia, YouTube
Installation
pip install cofone
With optional extras:
pip install "cofone[pdf]" # PDF support (pypdf)
pip install "cofone[faiss]" # FAISS semantic search (faiss-cpu + sentence-transformers)
pip install "cofone[web]" # Wikipedia + YouTube
pip install "cofone[all]" # everything above
Setup — API key required
Cofone needs at least one LLM provider API key.
The default provider is OpenRouter — free tier available, 200+ models, one key.
Step 1: Get a free key at openrouter.ai/keys
Step 2: Create a .env file in your project folder:
OPENROUTER_API_KEY=sk-or-...
Step 3: Load it in your script:
from dotenv import load_dotenv
load_dotenv()
Or pass the key directly (no .env needed):
RAG(model_api_key="sk-or-...").add_source("docs/").run("question")
→ Full setup guide for all providers: INSTALL.md
Examples
from dotenv import load_dotenv
from cofone import RAG
load_dotenv()
# ── Sources ───────────────────────────────────────────────────────────────────
# single file
RAG().add_source("notes.txt").run("Summarize")
# folder — loads all .txt .md .pdf recursively
RAG().add_source("docs/").run("What is the main topic?")
# PDF (requires pip install "cofone[pdf]")
RAG().add_source("report.pdf").run("What are the conclusions?")
# Wikipedia
RAG().add_source("https://en.wikipedia.org/wiki/Python").run("What is Python?")
# YouTube transcript
RAG().add_source("https://www.youtube.com/watch?v=VIDEO_ID").run("Summarize this video")
# multiple sources combined
RAG().add_source("docs/").add_source("https://en.wikipedia.org/wiki/AI").run("Overview")
# ── LLM providers ─────────────────────────────────────────────────────────────
RAG(model_provider="openai", model="gpt-4o-mini").add_source("docs/").run("question")
RAG(model_provider="anthropic", model="claude-3-5-haiku-20241022").add_source("docs/").run("question")
RAG(model_provider="gemini", model="gemini-2.0-flash").add_source("docs/").run("question")
RAG(model_provider="groq", model="llama-3.1-8b-instant").add_source("docs/").run("question")
RAG(model_provider="ollama", model="llama3").add_source("docs/").run("question") # local, no key
# ── FAISS semantic search ─────────────────────────────────────────────────────
# local embeddings (no extra key)
RAG(faiss=True).add_source("docs/").run("Find concepts related to learning")
# OpenAI embeddings
RAG(faiss=True,
embedding_provider="openai",
embedding_model="text-embedding-3-small"
).add_source("docs/").run("question")
# fully local — Ollama LLM + Ollama embeddings, no internet, no keys
RAG(model_provider="ollama", model="llama3",
faiss=True,
embedding_provider="ollama", embedding_model="nomic-embed-text"
).add_source("docs/").run("question")
# ── Chat memory ───────────────────────────────────────────────────────────────
bot = RAG().add_source("docs/")
bot.chat("Who is Leonardo da Vinci?")
bot.chat("When was he born?") # knows the context — "he" = Leonardo
bot.chat("What are his best works?")
# custom system prompt — tell the LLM how to behave
RAG(
system_prompt="You are an art historian. Answer only about paintings and sculptures."
).add_source("docs/").run("Tell me about Leonardo")
# ── Streaming ─────────────────────────────────────────────────────────────────
for token in RAG().add_source("docs/").stream("Tell me about this document"):
print(token, end="", flush=True)
print()
# ── Structured output (Pydantic) ──────────────────────────────────────────────
from pydantic import BaseModel
class Person(BaseModel):
name: str
birth_year: int
nationality: str
data = RAG().add_source("docs/").run("Extract data about Leonardo", schema=Person)
print(data.name) # Leonardo da Vinci
print(data.birth_year) # 1452
LLM Providers (19 total)
| Provider | model_provider= |
Key env var | Notes |
|---|---|---|---|
| OpenRouter | "openrouter" |
OPENROUTER_API_KEY |
Default. 200+ models, free tier |
| OpenAI | "openai" |
OPENAI_API_KEY |
GPT-4o, o3, etc. |
| Anthropic | "anthropic" |
ANTHROPIC_API_KEY |
Claude 3.5, Claude 3 |
| Gemini | "gemini" |
GEMINI_API_KEY |
Gemini 2.0 Flash, 1.5 Pro |
| Mistral | "mistral" |
MISTRAL_API_KEY |
Mistral Large, Codestral |
| Groq | "groq" |
GROQ_API_KEY |
Very fast inference |
| Cohere | "cohere" |
COHERE_API_KEY |
Command R+ |
| DeepSeek | "deepseek" |
DEEPSEEK_API_KEY |
DeepSeek-R1 reasoning |
| xAI | "xai" |
XAI_API_KEY |
Grok |
| Together | "together" |
TOGETHER_API_KEY |
Many open models |
| Perplexity | "perplexity" |
PERPLEXITY_API_KEY |
Web-connected |
| Fireworks | "fireworks" |
FIREWORKS_API_KEY |
Fast open models |
| Cerebras | "cerebras" |
CEREBRAS_API_KEY |
Ultra-fast |
| NVIDIA | "nvidia" |
NVIDIA_API_KEY |
NIM platform |
| DeepInfra | "deepinfra" |
DEEPINFRA_API_KEY |
Cheap open models |
| Anyscale | "anyscale" |
ANYSCALE_API_KEY |
Scalable inference |
| Ollama | "ollama" |
none | Local, no internet |
| LM Studio | "lmstudio" |
none | Local, no internet |
| llama.cpp | "llamacpp" |
none | Local, no internet |
Embedding Providers (10 total)
| Provider | embedding_provider= |
Key env var | Notes |
|---|---|---|---|
| sentence-transformers | "local" |
none | Default. Fully offline |
| OpenAI | "openai" |
OPENAI_API_KEY |
text-embedding-3-small/large |
| Gemini | "gemini" |
GEMINI_API_KEY |
text-embedding-004 |
| Cohere | "cohere" |
COHERE_API_KEY |
Multilingual, pip install cohere |
| Mistral | "mistral" |
MISTRAL_API_KEY |
mistral-embed |
| Voyage | "voyage" |
VOYAGE_API_KEY |
Top retrieval quality, pip install voyageai |
| Jina | "jina" |
JINA_API_KEY |
jina-embeddings-v3 |
| NVIDIA | "nvidia" |
NVIDIA_API_KEY |
nv-embed-v2 |
| Together | "together" |
TOGETHER_API_KEY |
BGE, UAE models |
| Ollama | "ollama" |
none | Local, nomic-embed-text |
Links
- 📦 PyPI: pypi.org/project/cofone
- 💻 GitHub: github.com/LeonardoCofone/cofone
- 📖 Full feature reference: FEATURE.md
- 🔧 Installation guide: INSTALL.md
License
MIT — see LICENSE
Metadata
Release files for cofone 0.2.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| cofone-0.2.2.tar.gz | 20.7 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| cofone-0.2.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 40.1 kB
Release files / cofone-0.2.2.tar.gz
| Download URL | cofone-0.2.2.tar.gz |
|---|---|
| Size | 20.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
22281616b1b464d0efdecf9c66b61b5d8204b674d15090a66d5a708c1f1febd7
|
|
BLAKE2b-256 checksum How to use checksums |
f78a27a21caf539d56a5f2ef1640863ee36961e4a08a230fbfa28bc2482188ac
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.0
|
Release files / cofone-0.2.2-py3-none-any.whl
| Download URL | cofone-0.2.2-py3-none-any.whl |
|---|---|
| Size | 19.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
4f0238d16ae967fc420505a8ec81099137463bf0510ff06946a91328852bca68
|
|
BLAKE2b-256 checksum How to use checksums |
1d6634b57352f5d8b3313b4a4bc0356edbb074ca255fdcc877dbf0903bf2d808
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.0
|