diff --git a/docs/configuration.md b/docs/configuration.md index 58210bea..4cb9973c 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -98,16 +98,28 @@ providers: qa_base_url: "" research_base_url: "" - api_keys: - voyage: "" - openai: "" - anthropic: "" - cohere: "" - a2a: max_contexts: 1000 ``` +## API Keys + +API keys are configured through **environment variables**, not in the YAML file. + +```bash +# OpenAI +export OPENAI_API_KEY=your-key-here + +# Anthropic +export ANTHROPIC_API_KEY=your-key-here + +# Voyage AI +export VOYAGE_API_KEY=your-key-here + +# Cohere +export CO_API_KEY=your-key-here +``` + ## File Monitoring Set directories to monitor for automatic indexing: @@ -145,10 +157,12 @@ embeddings: provider: voyageai model: voyage-3.5 vector_dim: 1024 +``` -providers: - api_keys: - voyage: your-api-key +Set your API key via environment variable: + +```bash +export VOYAGE_API_KEY=your-api-key ``` ### OpenAI @@ -160,10 +174,12 @@ embeddings: provider: openai model: text-embedding-3-small # or text-embedding-3-large vector_dim: 1536 +``` -providers: - api_keys: - openai: your-api-key +Set your API key via environment variable: + +```bash +export OPENAI_API_KEY=your-api-key ``` ### vLLM @@ -207,10 +223,12 @@ OpenAI QA is included in the default installation: qa: provider: openai model: gpt-4o-mini # or gpt-4, gpt-3.5-turbo, etc. +``` -providers: - api_keys: - openai: your-api-key +Set your API key via environment variable: + +```bash +export OPENAI_API_KEY=your-api-key ``` ### Anthropic @@ -221,10 +239,12 @@ Anthropic QA is included in the default installation: qa: provider: anthropic model: claude-3-5-haiku-20241022 # or claude-3-5-sonnet-20241022, etc. +``` -providers: - api_keys: - anthropic: your-api-key +Set your API key via environment variable: + +```bash +export ANTHROPIC_API_KEY=your-api-key ``` ### vLLM @@ -296,10 +316,12 @@ Cohere reranking is included in the default installation: reranking: provider: cohere model: rerank-v3.5 +``` -providers: - api_keys: - cohere: your-api-key +Set your API key via environment variable: + +```bash +export CO_API_KEY=your-api-key ``` ### vLLM diff --git a/src/haiku/rag/config/__init__.py b/src/haiku/rag/config/__init__.py index 7af9c6f2..e0299a6f 100644 --- a/src/haiku/rag/config/__init__.py +++ b/src/haiku/rag/config/__init__.py @@ -9,7 +9,6 @@ from haiku.rag.config.loader import ( ) from haiku.rag.config.models import ( A2AConfig, - APIKeysConfig, AppConfig, EmbeddingsConfig, LanceDBConfig, @@ -35,7 +34,6 @@ __all__ = [ "ProcessingConfig", "OllamaConfig", "VLLMConfig", - "APIKeysConfig", "ProvidersConfig", "A2AConfig", "find_config_file", @@ -54,14 +52,3 @@ else: # Check for deprecated .env file check_for_deprecated_env() - -# Export API keys to os.environ for provider libraries -if Config.providers.api_keys.openai: - os.environ["OPENAI_API_KEY"] = Config.providers.api_keys.openai -if Config.providers.api_keys.voyage: - os.environ["VOYAGE_API_KEY"] = Config.providers.api_keys.voyage -if Config.providers.api_keys.anthropic: - os.environ["ANTHROPIC_API_KEY"] = Config.providers.api_keys.anthropic -if Config.providers.api_keys.cohere: - # Cohere SDK expects CO_API_KEY (not COHERE_API_KEY) - os.environ["CO_API_KEY"] = Config.providers.api_keys.cohere diff --git a/src/haiku/rag/config/loader.py b/src/haiku/rag/config/loader.py index 147bb542..c2bf1240 100644 --- a/src/haiku/rag/config/loader.py +++ b/src/haiku/rag/config/loader.py @@ -90,7 +90,6 @@ def generate_default_config() -> dict: "qa_base_url": "", "research_base_url": "", }, - "api_keys": {"voyage": "", "openai": "", "anthropic": "", "cohere": ""}, }, "a2a": {"max_contexts": 1000}, } @@ -126,10 +125,6 @@ def load_config_from_env() -> dict: "VLLM_RERANK_BASE_URL": ("providers", "vllm", "rerank_base_url"), "VLLM_QA_BASE_URL": ("providers", "vllm", "qa_base_url"), "VLLM_RESEARCH_BASE_URL": ("providers", "vllm", "research_base_url"), - "VOYAGE_API_KEY": ("providers", "api_keys", "voyage"), - "OPENAI_API_KEY": ("providers", "api_keys", "openai"), - "ANTHROPIC_API_KEY": ("providers", "api_keys", "anthropic"), - "COHERE_API_KEY": ("providers", "api_keys", "cohere"), "A2A_MAX_CONTEXTS": ("a2a", "max_contexts"), } diff --git a/src/haiku/rag/config/models.py b/src/haiku/rag/config/models.py index 51bb55a5..3fdd6bc8 100644 --- a/src/haiku/rag/config/models.py +++ b/src/haiku/rag/config/models.py @@ -56,17 +56,9 @@ class VLLMConfig(BaseModel): research_base_url: str = "" -class APIKeysConfig(BaseModel): - voyage: str = "" - openai: str = "" - anthropic: str = "" - cohere: str = "" - - class ProvidersConfig(BaseModel): ollama: OllamaConfig = Field(default_factory=OllamaConfig) vllm: VLLMConfig = Field(default_factory=VLLMConfig) - api_keys: APIKeysConfig = Field(default_factory=APIKeysConfig) class A2AConfig(BaseModel): diff --git a/src/haiku/rag/reranking/cohere.py b/src/haiku/rag/reranking/cohere.py index 69f4f7d6..439cbca2 100644 --- a/src/haiku/rag/reranking/cohere.py +++ b/src/haiku/rag/reranking/cohere.py @@ -1,4 +1,3 @@ -from haiku.rag.config import Config from haiku.rag.reranking.base import RerankerBase from haiku.rag.store.models.chunk import Chunk @@ -12,7 +11,8 @@ except ImportError as e: class CohereReranker(RerankerBase): def __init__(self): - self._client = cohere.ClientV2(api_key=Config.providers.api_keys.cohere) + # Cohere SDK reads CO_API_KEY from environment by default + self._client = cohere.ClientV2() async def rerank( self, query: str, chunks: list[Chunk], top_n: int = 10 diff --git a/tests/test_config_loader.py b/tests/test_config_loader.py index a2b0869f..991d1628 100644 --- a/tests/test_config_loader.py +++ b/tests/test_config_loader.py @@ -112,7 +112,6 @@ def test_load_config_from_env(monkeypatch): monkeypatch.setenv("EMBEDDINGS_VECTOR_DIM", "1536") monkeypatch.setenv("QA_PROVIDER", "anthropic") monkeypatch.setenv("QA_MODEL", "claude-3-haiku") - monkeypatch.setenv("OPENAI_API_KEY", "test-key") config = load_config_from_env() @@ -122,7 +121,6 @@ def test_load_config_from_env(monkeypatch): assert config["embeddings"]["vector_dim"] == "1536" assert config["qa"]["provider"] == "anthropic" assert config["qa"]["model"] == "claude-3-haiku" - assert config["providers"]["api_keys"]["openai"] == "test-key" def test_load_config_from_env_empty(): diff --git a/tests/test_embedder.py b/tests/test_embedder.py index 1391fe35..4ef9e7bc 100644 --- a/tests/test_embedder.py +++ b/tests/test_embedder.py @@ -1,3 +1,5 @@ +import os + import numpy as np import pytest @@ -6,8 +8,8 @@ from haiku.rag.embeddings.ollama import Embedder as OllamaEmbedder from haiku.rag.embeddings.openai import Embedder as OpenAIEmbedder from haiku.rag.embeddings.vllm import Embedder as VLLMEmbedder -OPENAI_AVAILABLE = bool(Config.providers.api_keys.openai) -VOYAGEAI_AVAILABLE = bool(Config.providers.api_keys.voyage) +OPENAI_AVAILABLE = bool(os.getenv("OPENAI_API_KEY")) +VOYAGEAI_AVAILABLE = bool(os.getenv("VOYAGE_API_KEY")) VLLM_EMBEDDINGS_AVAILABLE = bool(Config.providers.vllm.embeddings_base_url) diff --git a/tests/test_qa.py b/tests/test_qa.py index 2bcf20a5..16c47971 100644 --- a/tests/test_qa.py +++ b/tests/test_qa.py @@ -1,3 +1,5 @@ +import os + import pytest from datasets import Dataset @@ -6,8 +8,8 @@ from haiku.rag.client import HaikuRAG from haiku.rag.config import Config from haiku.rag.qa.agent import QuestionAnswerAgent -OPENAI_AVAILABLE = bool(Config.providers.api_keys.openai) -ANTHROPIC_AVAILABLE = bool(Config.providers.api_keys.anthropic) +OPENAI_AVAILABLE = bool(os.getenv("OPENAI_API_KEY")) +ANTHROPIC_AVAILABLE = bool(os.getenv("ANTHROPIC_API_KEY")) VLLM_QA_AVAILABLE = bool(Config.providers.vllm.qa_base_url) diff --git a/tests/test_reranker.py b/tests/test_reranker.py index bc98b5b6..cc93f584 100644 --- a/tests/test_reranker.py +++ b/tests/test_reranker.py @@ -1,3 +1,5 @@ +import os + import pytest from haiku.rag.config import Config @@ -5,7 +7,7 @@ from haiku.rag.reranking.base import RerankerBase from haiku.rag.reranking.vllm import VLLMReranker from haiku.rag.store.models.chunk import Chunk -COHERE_AVAILABLE = bool(Config.providers.api_keys.cohere) +COHERE_AVAILABLE = bool(os.getenv("CO_API_KEY")) VLLM_RERANK_AVAILABLE = bool(Config.providers.vllm.rerank_base_url) chunks = [