Skip to content

feat: add OpenRouter as embedding provider name#304

Open
BeamNawapat wants to merge 1 commit intozilliztech:masterfrom
BeamNawapat:feat/openrouter-provider
Open

feat: add OpenRouter as embedding provider name#304
BeamNawapat wants to merge 1 commit intozilliztech:masterfrom
BeamNawapat:feat/openrouter-provider

Conversation

@BeamNawapat
Copy link
Copy Markdown
Contributor

@BeamNawapat BeamNawapat commented Apr 20, 2026

Summary

Add OpenRouter as a first-class provider name for cleaner UX. Reuses OpenAIEmbedding internally with OpenRouter's OpenAI-compatible endpoint — zero code duplication.

Motivation

Users can achieve the same result via OPENAI_BASE_URL workaround, but a named provider gives better discoverability and simpler configuration.

Changes (2 files, ~30 lines)

  • packages/mcp/src/config.ts — Add OpenRouter to provider union, OPENROUTER_API_KEY env var, default model, help message
  • packages/mcp/src/embedding.ts — Add OpenRouter case that creates OpenAIEmbedding with baseURL: 'https://openrouter.ai/api/v1'

No new files. No new dependencies. No code duplication.

Usage

EMBEDDING_PROVIDER=OpenRouter \
OPENROUTER_API_KEY=sk-or-v1-xxx \
EMBEDDING_MODEL=openai/text-embedding-3-small \
npx @zilliz/claude-context-mcp@latest

Test plan

  • OpenRouter provider starts and connects
  • Existing providers unaffected (no regression)
  • pnpm build passes

Copilot AI review requested due to automatic review settings April 20, 2026 18:16
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds OpenRouter as a first-class embedding provider (via OpenRouter’s OpenAI-compatible API) so users no longer need to rely on the OPENAI_BASE_URL workaround and can use OpenRouter-style model IDs like openai/text-embedding-3-small.

Changes:

  • Introduce OpenRouterEmbedding provider in core (OpenAI SDK + OpenRouter base URL, supported-model metadata).
  • Wire OpenRouter into MCP config/env (OPENROUTER_API_KEY) and embedding-provider selection switch.
  • Export the new provider from the core embedding barrel.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.

File Description
packages/core/src/embedding/openrouter-embedding.ts New embedding provider implementation using OpenAI SDK routed through OpenRouter.
packages/core/src/embedding/index.ts Exports the new OpenRouter embedding provider.
packages/mcp/src/config.ts Extends config/provider union, adds OpenRouter default model and API key env wiring.
packages/mcp/src/embedding.ts Adds OpenRouter provider case to instance creation and provider-info logging.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread packages/core/src/embedding/index.ts Outdated
Comment thread packages/mcp/src/config.ts
Comment thread packages/mcp/src/embedding.ts Outdated
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

if (knownModels[model]) {
return knownModels[model].dimension;
}

Copy link

Copilot AI Apr 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OpenRouterEmbedding.getDimension() returns the default this.dimension for unknown/custom models without any warning. Since other implementations (e.g., OpenAIEmbedding) explicitly warn that the value may be incorrect until detectDimension()/embed() is called, this can lead to misleading logs and harder debugging when users supply non-listed OpenRouter model IDs. Consider adding a warning for the unknown-model path (or otherwise documenting that the returned dimension may be stale until detection runs).

Suggested change
console.warn(
`OpenRouter model "${model}" is not in the supported models list; returning cached/default dimension ` +
`${this.dimension}. This value may be incorrect until detectDimension(), embed(), or embedBatch() runs.`
);

Copilot uses AI. Check for mistakes.
Comment on lines 130 to +134
voyageaiApiKey: envManager.get('VOYAGEAI_API_KEY'),
geminiApiKey: envManager.get('GEMINI_API_KEY'),
geminiBaseUrl: envManager.get('GEMINI_BASE_URL'),
// OpenRouter configuration
openrouterApiKey: envManager.get('OPENROUTER_API_KEY'),
Copy link

Copilot AI Apr 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

createMcpConfig() prints a debug summary of relevant env vars (e.g., GEMINI_API_KEY, OPENAI_API_KEY), but the newly introduced OPENROUTER_API_KEY isn’t included. Adding it to the debug output (ideally with the same “SET (length: …)” pattern) would make troubleshooting OpenRouter configuration consistent with the other providers.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Collaborator

@zc277584121 zc277584121 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the contribution! The motivation makes sense — giving OpenRouter users a cleaner config experience. However, I have some concerns about the current approach.

Main issue: code duplication

openrouter-embedding.ts (151 lines) is nearly identical to openai-embedding.ts. Both use the openai npm package, same embeddings.create() calls, same error handling, same detectDimension logic. The only real differences are:

  • Default baseURLhttps://openrouter.ai/api/v1
  • Default model → openai/text-embedding-3-small
  • Supported model list (3 entries, all just OpenAI models with openai/ prefix)

Users can already achieve the same result today:

EMBEDDING_PROVIDER=OpenAI \
OPENAI_BASE_URL=https://openrouter.ai/api/v1 \
OPENAI_API_KEY=sk-or-v1-xxx \
EMBEDDING_MODEL=openai/text-embedding-3-small

Suggested alternatives

If we do want a first-class OpenRouter provider name for better UX, it should reuse OpenAIEmbedding rather than duplicate it. Something like:

// In createEmbeddingInstance:
case 'OpenRouter':
    if (!config.openrouterApiKey) {
        throw new Error('OPENROUTER_API_KEY is required');
    }
    return new OpenAIEmbedding({
        apiKey: config.openrouterApiKey,
        model: config.embeddingModel,
        baseURL: 'https://openrouter.ai/api/v1',
    });

This achieves the same user-facing behavior (~5 lines vs 151 lines) and avoids maintaining two copies of the same logic.

Alternatively, just document the OPENAI_BASE_URL approach in the README — that may be sufficient.

Add OpenRouter as a first-class provider name for cleaner UX. Reuses
OpenAIEmbedding internally with OpenRouter's OpenAI-compatible endpoint,
avoiding code duplication.

New env vars: EMBEDDING_PROVIDER=OpenRouter, OPENROUTER_API_KEY
@BeamNawapat BeamNawapat force-pushed the feat/openrouter-provider branch from df317bf to 24c2bb9 Compare April 22, 2026 04:55
@BeamNawapat BeamNawapat changed the title feat: add OpenRouter as first-class embedding provider feat: add OpenRouter as embedding provider name Apr 22, 2026
@BeamNawapat
Copy link
Copy Markdown
Contributor Author

Good call — 151 lines of duplication was unnecessary. Reworked to reuse OpenAIEmbedding directly:

case 'OpenRouter':
    return new OpenAIEmbedding({
        apiKey: config.openrouterApiKey,
        model: config.embeddingModel,
        baseURL: 'https://openrouter.ai/api/v1',
    });

Force-pushed. Now 2 files changed, ~30 lines total. No new files, no new dependencies.

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.

3 participants