Skip to content

[bug] Embedder silently defaults to OpenAI when EMBEDDING_* unset; no way to disable create_observations embedding #915

Description

@PraveenKumarSridhar

Summary

Two related defects in the embedding configuration path that affect anyone running self-hosted Honcho with a non-OpenAI LLM provider (Anthropic, MiniMax, Gemini, OpenRouter, local vLLM/Ollama, etc.).

(a) Silent fallback to OpenAI when EMBEDDING_* is unset. If no embedder config is provided, Honcho defaults EMBEDDING_MODEL_CONFIG to transport="openai", model="text-embedding-3-small", and routes to https://api.openai.com/v1/embeddings regardless of which LLM transport the rest of the stack uses. There is no startup-time warning that the embedder is pointing at OpenAI. A user running Honcho with LLM_OPENAI_BASE_URL=https://api.minimax.io/v1 (or any non-OpenAI LLM) will hit OpenAI 401s on every POST /v3/conclusions/ call unless they also configure an embedder. We hit this on a self-hosted stack at v3.0.7 and only discovered it because every conclusion write started 500-ing.

(b) No way to disable embedding on create_observations. EMBED_MESSAGES=false only gates retrieval-time embedding. There is no parallel EMBED_OBSERVATIONS flag and no transport="none" option. For self-hosted users who can't afford / don't want / can't reach an embedding API, every conclusion write either fails outright or requires a source-code patch to swallow the embedding error. The EmbeddingTransport Literal in src/config.py is ["openai", "gemini"] only — no path to a no-op.

Reproduction (a)

# .env: route LLM to a non-OpenAI provider, leave EMBEDDING_* unset
LLM_OPENAI_BASE_URL=https://api.minimax.io/v1
DERIVER_MODEL_CONFIG__TRANSPORT=openai
DERIVER_MODEL_CONFIG__MODEL=MiniMax-M3
DERIVER_MODEL_CONFIG__OVERRIDES__BASE_URL=https://api.minimax.io/v1

docker compose up -d
curl -X POST http://localhost:8000/v3/workspaces/test/peers/user -d '{"id":"user"}'
curl -X POST http://localhost:8000/v3/workspaces/test/conclusions \
  -d '{"conclusions":[{"observer_id":"ai","observed_id":"user","content":"hello"}]}' \
  -H "Content-Type: application/json"
# -> HTTP 500 from create_observations
# -> server log: openai.AuthenticationError: 401 ... sk-cp-... api.openai.com

Expected: at minimum, a startup warning that the embedder is using OpenAI defaults while the LLM is routed elsewhere. Ideally, inherit the LLM provider's transport/base_url/key when embedder config is unset.

Reproduction (b)

# User wants to disable embedding entirely (no budget, no provider, no GPU)
echo "EMBED_MESSAGES=false" >> .env
echo "EMBED_OBSERVATIONS=false" >> .env   # doesn't exist, ignored
docker compose restart honcho
# POST /v3/conclusions/ still calls simple_batch_embed(), still tries to hit
# the configured (or default) embedder, still fails the same way.

Expected: a documented way to disable embedding on create_observations. Either an EMBED_OBSERVATIONS=false flag, or a transport="none" option in EmbeddingTransport.

Environment

  • Honcho v3.0.7 (self-hosted via docker-compose)
  • LLM: MiniMax-M3 via OpenAI-compatible transport (DERIVER_MODEL_CONFIG__*)
  • Embedder: left unset, defaults to OpenAI
  • DB: PostgreSQL 16 with pgvector
  • Reproduced on macOS 15.1, also confirmed by community on Raspberry Pi 4 / ARM64 with Ollama Cloud

Workarounds used

For (a), explicitly configure the embedder:

EMBEDDING_MODEL_CONFIG__TRANSPORT=openai
EMBEDDING_MODEL_CONFIG__MODEL=<embedding model>
EMBEDDING_MODEL_CONFIG__OVERRIDES__BASE_URL=<provider base url>
EMBEDDING_MODEL_CONFIG__OVERRIDES__API_KEY_ENV=LLM_OPENAI_API_KEY

For (b), source patch in src/embedding_client.py to swallow OpenAIAuthenticationError in simple_batch_embed and return zero-vectors. Documents save with NULL embedding; vector search is degraded but writes complete.

Adjacent issues considered but not duplicate

Suggested fix

Either:

  1. Inherit LLM provider config for embeddings when EMBEDDING_* is unset. If DERIVER_MODEL_CONFIG__OVERRIDES__BASE_URL is set, use that base URL for embeddings too. Same transport, same key.
  2. Fail-fast at startup. If EMBEDDING_* is unset, log a clear "embedder using OpenAI defaults, set EMBEDDING_MODEL_CONFIG__* to override" warning at INFO or WARN level.
  3. Add EMBED_OBSERVATIONS env flag parallel to EMBED_MESSAGES, default true.
  4. Add transport="none" to EmbeddingTransport Literal as a documented no-op option.

Any of these would prevent the silent-401 trap. (1) + (3) is the cleanest pair.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions