You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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.
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.
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.
Add EMBED_OBSERVATIONS env flag parallel to EMBED_MESSAGES, default true.
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.
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 defaultsEMBEDDING_MODEL_CONFIGtotransport="openai",model="text-embedding-3-small", and routes tohttps://api.openai.com/v1/embeddingsregardless 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 withLLM_OPENAI_BASE_URL=https://api.minimax.io/v1(or any non-OpenAI LLM) will hit OpenAI 401s on everyPOST /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=falseonly gates retrieval-time embedding. There is no parallelEMBED_OBSERVATIONSflag and notransport="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. TheEmbeddingTransportLiteral insrc/config.pyis["openai", "gemini"]only — no path to a no-op.Reproduction (a)
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)
Expected: a documented way to disable embedding on
create_observations. Either anEMBED_OBSERVATIONS=falseflag, or atransport="none"option inEmbeddingTransport.Environment
Workarounds used
For (a), explicitly configure the embedder:
For (b), source patch in
src/embedding_client.pyto swallowOpenAIAuthenticationErrorinsimple_batch_embedand return zero-vectors. Documents save with NULL embedding; vector search is degraded but writes complete.Adjacent issues considered but not duplicate
AsyncOpenAIclient lacksbase_url→ 401 againstapi.openai.com#641 (closed May 2026): LLM-side defaultAsyncOpenAIclient lacksbase_url, 401s against api.openai.com. Different layer (deriver LLM call, not embedder). Workaround wasDERIVER_MODEL_CONFIG__*env vars.response_format: json_schema).create_conclusionfails with local embedder dimension mismatch. Related but distinct: dimension mismatch vs. silent fallback.processedwhen the embedding save fails on a transient 429 (no retry, no fail-loud → silent memory loss) #728 (open): Deriver silently marks representationprocessedwhen embedding save fails on transient 429. Related thematically (silent failure on embedding errors) but specific to retry behavior, not config defaults.Suggested fix
Either:
EMBEDDING_*is unset. IfDERIVER_MODEL_CONFIG__OVERRIDES__BASE_URLis set, use that base URL for embeddings too. Same transport, same key.EMBEDDING_*is unset, log a clear "embedder using OpenAI defaults, set EMBEDDING_MODEL_CONFIG__* to override" warning at INFO or WARN level.EMBED_OBSERVATIONSenv flag parallel toEMBED_MESSAGES, default true.transport="none"toEmbeddingTransportLiteral as a documented no-op option.Any of these would prevent the silent-401 trap. (1) + (3) is the cleanest pair.