Skip to content

OPENAI_EMBEDDING_API_KEY #863

@clzwqoii

Description

@clzwqoii

Issue draft
Title:

OPENAI_EMBEDDING_API_KEY is ignored when EMBEDDING_PROVIDER=openai and OPENAI_API_KEY is set

Body:

Summary

When EMBEDDING_PROVIDER=openai is used with both:

  • OPENAI_API_KEY for an OpenAI-compatible chat provider
  • OPENAI_EMBEDDING_API_KEY / OPENAI_EMBEDDING_BASE_URL for a separate local OpenAI-compatible embedding endpoint

the embedding provider still uses OPENAI_API_KEY, not OPENAI_EMBEDDING_API_KEY.

This makes it impossible to use a hosted OpenAI-compatible LLM while routing embeddings to a separate local endpoint such as LM Studio, even though OpenAIEmbeddingProvider documents and implements embedding-specific env vars.

Reproduction

Example config:

# Hosted OpenAI-compatible chat provider
OPENAI_API_KEY=hosted-chat-key
OPENAI_BASE_URL=https://example-chat-provider/v1
OPENAI_MODEL=some-chat-model

# Local OpenAI-compatible embedding provider
EMBEDDING_PROVIDER=openai
OPENAI_EMBEDDING_API_KEY=local-embedding-key
OPENAI_EMBEDDING_BASE_URL=http://127.0.0.1:1234/v1
OPENAI_EMBEDDING_MODEL=text-embedding-bge-m3
OPENAI_EMBEDDING_DIMENSIONS=1024
With this configuration, agentmemory sends hosted-chat-key to the local embedding endpoint. LM Studio rejects it with an invalid token error.

Expected behavior
For embeddings, OPENAI_EMBEDDING_API_KEY should take precedence over OPENAI_API_KEY, and OPENAI_EMBEDDING_BASE_URL should route embeddings independently from chat completions.

Actual behavior
createEmbeddingProvider() calls:

new OpenAIEmbeddingProvider(getEnvVar("OPENAI_API_KEY")!)
Because a constructor argument is passed, the provider's internal fallback:

apiKey || getEnvVar("OPENAI_EMBEDDING_API_KEY") || getEnvVar("OPENAI_API_KEY")
never reaches OPENAI_EMBEDDING_API_KEY.

Root cause
src/providers/embedding/index.ts passes OPENAI_API_KEY into OpenAIEmbeddingProvider for the openai embedding provider case.

Suggested fix
Let OpenAIEmbeddingProvider resolve its own env vars:

case "openai":
  return withDimensionGuard(new OpenAIEmbeddingProvider());
This keeps the documented precedence inside OpenAIEmbeddingProvider:

constructor override, if explicitly provided
OPENAI_EMBEDDING_API_KEY
OPENAI_API_KEY
Notes
This is especially useful for setups where:

chat/compression uses a hosted OpenAI-compatible provider
embeddings use local LM Studio / vLLM / Ollama / llama.cpp
the two endpoints require different API keys

## PR patch

```diff
diff --git a/src/providers/embedding/index.ts b/src/providers/embedding/index.ts
index 0000000..0000000 100644
--- a/src/providers/embedding/index.ts
+++ b/src/providers/embedding/index.ts
@@
-    case "openai": return withDimensionGuard(new OpenAIEmbeddingProvider(getEnvVar("OPENAI_API_KEY")!));
+    case "openai": return withDimensionGuard(new OpenAIEmbeddingProvider());
PR description draft
Title:

Respect OPENAI_EMBEDDING_API_KEY for OpenAI embedding provider

Body:

### What changed

This updates the OpenAI embedding provider factory to let `OpenAIEmbeddingProvider` resolve its own API key from the documented precedence:

1. explicit constructor argument
2. `OPENAI_EMBEDDING_API_KEY`
3. `OPENAI_API_KEY`

### Why

The current factory passes `OPENAI_API_KEY` directly:

```ts
new OpenAIEmbeddingProvider(getEnvVar("OPENAI_API_KEY")!)
That prevents OPENAI_EMBEDDING_API_KEY from being used when users configure:

OPENAI_API_KEY / OPENAI_BASE_URL for hosted OpenAI-compatible chat
OPENAI_EMBEDDING_API_KEY / OPENAI_EMBEDDING_BASE_URL for local embeddings
The provider already supports this split internally, so the factory should not override it.

Validation
The fix is behaviorally scoped to the OpenAI embedding provider construction path.
Existing configs that only set OPENAI_API_KEY continue to work because OpenAIEmbeddingProvider falls back to OPENAI_API_KEY.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions