Skip to content

fix(openai-embeddings): honor embedding-specific API key in factory and auto-detect#692

Open
moonshardx wants to merge 1 commit into
rohitg00:mainfrom
moonshardx:fix/openai-embedding-precedence-followup-503
Open

fix(openai-embeddings): honor embedding-specific API key in factory and auto-detect#692
moonshardx wants to merge 1 commit into
rohitg00:mainfrom
moonshardx:fix/openai-embedding-precedence-followup-503

Conversation

@moonshardx
Copy link
Copy Markdown

@moonshardx moonshardx commented May 28, 2026

Follow-up to #503.

Repro

OPENAI_API_KEY=sk-deepseek-...                  # chat on a self-hosted/proxy
OPENAI_EMBEDDING_API_KEY=sk-openai-real-...
OPENAI_EMBEDDING_BASE_URL=https://api.openai.com

Embedding requests 401 from OpenAI because the LLM key is still sent. The bug is invisible against local endpoints (vLLM / Ollama / LM Studio) that ignore Authorization, which is why #503's verification didn't surface it.

Fix

Two call sites still bypass the embedding-specific env added in #503:

File Change
src/providers/embedding/index.ts:38 Drop the explicit OPENAI_API_KEY argument; let the constructor resolve precedence (apiKey arg > OPENAI_EMBEDDING_API_KEY > OPENAI_API_KEY).
src/config.ts detectEmbeddingProvider Check OPENAI_EMBEDDING_API_KEY ahead of generic provider keys so "chat on X, embeddings on OpenAI" auto-detects without forcing EMBEDDING_PROVIDER=openai.
src/providers/embedding/openai.ts JSDoc Fix one reversed-fallback summary line (lines 65-69 are already correct).
.env.example, README.md Document OPENAI_EMBEDDING_API_KEY and OPENAI_EMBEDDING_BASE_URL; update the detection-order comment.
test/embedding-provider.test.ts 3 regression tests + expanded beforeEach to strip embedding-specific env.

Compatibility

Existing config Before After
Only OPENAI_API_KEY set factory passes it in → constructor falls through to OPENAI_API_KEY factory passes nothing → constructor falls through to OPENAI_API_KEYidentical
Only GEMINI_API_KEY set detect → "gemini" detect → "gemini"identical
OPENAI_API_KEY + EMBEDDING_PROVIDER=openai constructor uses OPENAI_API_KEY constructor uses OPENAI_API_KEYidentical
OPENAI_API_KEY + OPENAI_EMBEDDING_API_KEY broken (LLM key wins) embedding key wins — fixed
GEMINI_API_KEY + OPENAI_EMBEDDING_API_KEY (no EMBEDDING_PROVIDER) broken (detect → "gemini") detect → "openai"fixed

The only behavior shifts are in the two currently-broken rows — those configurations misroute embeddings today, so changing them is the intent. No silent regression for any working config.

Test plan

  • npm test -- embedding-provider — 20/20 green (17 existing + 3 new regression tests).
  • npm test — full suite green (1241/1241; integration test under test/integration.test.ts skipped per CONTRIBUTING.md).
  • npm run buildtsdown clean.

Summary by CodeRabbit

  • New Features

    • Support for embedding-specific OpenAI API keys and base URLs that take precedence over general settings.
  • Documentation

    • Updated configuration guides with new embedding-specific environment variables.
  • Tests

    • Added test coverage for embedding key precedence and provider detection.

Review Change Stack

…nd auto-detect

Follow-up to rohitg00#503.

PR rohitg00#503 added OPENAI_EMBEDDING_API_KEY / OPENAI_EMBEDDING_BASE_URL to
OpenAIEmbeddingProvider but two call sites still bypass them, so the env
vars do not take effect when set alongside OPENAI_API_KEY:

  1. src/providers/embedding/index.ts:38 — factory passes
     getEnvVar("OPENAI_API_KEY")! into the constructor's apiKey arg,
     beating the constructor's documented precedence
     (apiKey > OPENAI_EMBEDDING_API_KEY > OPENAI_API_KEY).

  2. src/config.ts — detectEmbeddingProvider() does not consider
     OPENAI_EMBEDDING_API_KEY, so an embedding-only OpenAI config
     paired with a different chat provider (e.g. Gemini) misroutes
     embeddings to whichever generic provider key is also set.

Reproduces against real OpenAI:

  OPENAI_API_KEY=sk-deepseek-...        # chat on a self-hosted/proxy
  OPENAI_EMBEDDING_API_KEY=sk-openai-real-...
  OPENAI_EMBEDDING_BASE_URL=https://api.openai.com

Embedding requests 401 because the LLM key is sent. The bug is invisible
when the embedding endpoint ignores Authorization (local vLLM / Ollama /
LM Studio), which is why rohitg00#503's verification missed it.

Fix:

- index.ts: drop the explicit OPENAI_API_KEY argument; the constructor
  already documents and implements the correct precedence.
- config.ts: check OPENAI_EMBEDDING_API_KEY ahead of generic provider
  keys so "chat on X, embeddings on OpenAI" auto-detects without forcing
  EMBEDDING_PROVIDER=openai.
- .env.example, README.md, openai.ts JSDoc: sync docs to match the
  now-functional behavior.
- test/embedding-provider.test.ts: 3 regression tests (both-keys factory
  path, embedding-only detect, gemini+embedding precedence); expand
  beforeEach to strip embedding-specific env vars.

Compatibility: zero behavior change for users not setting
OPENAI_EMBEDDING_*; only the two currently-broken configurations above
shift, which is the intent.

Signed-off-by: Ning <cningwei@gmail.com>
@vercel
Copy link
Copy Markdown

vercel Bot commented May 28, 2026

@moonshardx is attempting to deploy a commit to the rohitg00's projects Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 28, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 814c714e-afb2-40e2-948d-a9fceb1021e9

📥 Commits

Reviewing files that changed from the base of the PR and between 37fff9a and ac32224.

📒 Files selected for processing (6)
  • .env.example
  • README.md
  • src/config.ts
  • src/providers/embedding/index.ts
  • src/providers/embedding/openai.ts
  • test/embedding-provider.test.ts

📝 Walkthrough

Walkthrough

This PR introduces embedding-specific OpenAI configuration variables (OPENAI_EMBEDDING_API_KEY and OPENAI_EMBEDDING_BASE_URL) that override generic settings. Detection priority, provider instantiation, and test coverage are updated to honor this precedence when set.

Changes

Embedding-Specific OpenAI Configuration

Layer / File(s) Summary
Environment Variable Documentation
.env.example, README.md
Documents new embedding-specific override variables OPENAI_EMBEDDING_API_KEY and OPENAI_EMBEDDING_BASE_URL, noting they take precedence over general OpenAI settings when present. Detection order in .env.example is updated to reflect the new priority chain.
Provider Detection Priority
src/config.ts
detectEmbeddingProvider() now checks for OPENAI_EMBEDDING_API_KEY first and returns "openai" before evaluating other provider keys, ensuring embedding-specific configuration drives provider selection.
OpenAI Embedding Provider Instantiation
src/providers/embedding/index.ts, src/providers/embedding/openai.ts
OpenAI embedding provider is instantiated without explicit API key argument, relying on internal environment variable resolution. Inline documentation updated to reflect OPENAI_EMBEDDING_API_KEY precedence.
Test Coverage for Key Precedence
test/embedding-provider.test.ts
Test setup preserves embedding-specific environment variables. New tests verify authorization uses OPENAI_EMBEDDING_API_KEY over OPENAI_API_KEY, that OpenAI is detected when only the embedding key is set, and that embedding keys override other provider keys.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

  • rohitg00/agentmemory#503: Coordinates embedding-specific override behavior by updating OpenAI embedding provider resolution logic to use OPENAI_EMBEDDING_API_KEY and related base URL handling.

Suggested reviewers

  • rohitg00

Poem

🐰 A key for embeddings, distinct and dear,
No longer lost in the general sphere,
Precedence granted, priorities clear,
OpenAI's specifics now take the cheer!
Tests affirm the path we hold,
Configuration stories, newly told.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main fix: honoring embedding-specific API keys in both the factory function and auto-detection logic.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint skipped: no ESLint configuration detected in root package.json. To enable, add eslint to devDependencies.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant