diff --git a/.env.example b/.env.example index 04028a5..0d05a30 100644 --- a/.env.example +++ b/.env.example @@ -25,6 +25,16 @@ DB_TIMEZONE=auto # Choose: ollama, openrouter, openai, custom EMBEDDER_PROVIDER=ollama +# Embedding model and its vector width. Both fall back to +# config/settings.yaml (nomic-embed-text at 768) and only need setting to run +# a different model. +# +# These must agree with each other AND with the width of the `embedding` +# column in the database: a model emitting a different number of dimensions +# than the column declares will fail on insert. +# EMBEDDER_MODEL=nomic-embed-text +# EMBEDDER_DIMENSIONS=768 + # Ollama (local; default — no API key required) # Inside the docker network the api reaches ollama at http://ollama:11434 # (compose sets OLLAMA_BASE_URL automatically). diff --git a/src/embedder/__init__.py b/src/embedder/__init__.py index 2eb6cfb..c8c3618 100644 --- a/src/embedder/__init__.py +++ b/src/embedder/__init__.py @@ -60,14 +60,32 @@ def __init__(self, config_path: str = None): embedder_cfg = config.get('embedder', {}) - # Provider settings - self.provider = embedder_cfg.get('provider', 'openrouter') - - # Model - self.model = embedder_cfg.get('model', 'nomic-embed-text') - - # Dimensions - self.dimensions = embedder_cfg.get('dimensions', 768) + # Provider, model and dimensions follow the same env-over-config + # precedence as max_chars and chunk_overlap below, so a deployment can + # be pointed at a different embedding model without editing a file that + # is baked into the image at build time. + # + # EMBEDDER_PROVIDER is already documented in .env.example ("set + # EMBEDDER_PROVIDER and provide the matching API key below") but was + # never read, so setting it had no effect. + def _env_or(name, fallback): + # A set-but-empty variable means "not configured", not "configure + # this to the empty string". `.env` files routinely carry blank + # placeholders, and letting one through here would silently select + # no provider at all. + value = os.environ.get(name, '') + return value.strip() or fallback + + self.provider = _env_or( + 'EMBEDDER_PROVIDER', embedder_cfg.get('provider', 'openrouter')) + + self.model = _env_or( + 'EMBEDDER_MODEL', embedder_cfg.get('model', 'nomic-embed-text')) + + self.dimensions = int(_env_or( + 'EMBEDDER_DIMENSIONS', embedder_cfg.get('dimensions', 768))) + if self.dimensions <= 0: + raise ValueError("embedder.dimensions must be greater than zero") # Chunking guardrail for providers with smaller context windows self.max_chars = int(os.environ.get(