Skip to content

feat(providers): add configurable OpenRouter and Gemini base URLs#963

Open
ipirojnoe wants to merge 2 commits into
rohitg00:mainfrom
ipirojnoe:feat/openrouter-gemini-base-urls
Open

feat(providers): add configurable OpenRouter and Gemini base URLs#963
ipirojnoe wants to merge 2 commits into
rohitg00:mainfrom
ipirojnoe:feat/openrouter-gemini-base-urls

Conversation

@ipirojnoe

@ipirojnoe ipirojnoe commented Jun 20, 2026

Copy link
Copy Markdown

What

Adds configurable base URLs for OpenRouter and Gemini.

  • OPENROUTER_BASE_URL is used by OpenRouter chat completions and embeddings.
  • GEMINI_BASE_URL is used by Gemini OpenAI-compatible chat completions and native embeddings.
  • Splits Gemini LLM handling into its own provider instead of reusing OpenRouterProvider.
  • Normalizes trailing slashes before appending API routes.

Why

OpenRouter endpoints were hardcoded, so deployments using an OpenRouter compatible proxy could not route LLM and embedding requests through it. Separating Gemini removes provider behavior inferred from the URL.

Verification

  • npm run build
  • npm test

Summary by CodeRabbit

  • New Features

    • Added configurable base URLs for Gemini and OpenRouter providers, enabling flexible support for custom proxies and alternative API endpoints.
    • Introduced new Gemini provider for LLM-based text compression and summarization.
  • Documentation

    • Updated environment variable documentation with new base URL configuration options.
  • Tests

    • Added test coverage for provider base URL configuration and functionality.

Ilia added 2 commits June 20, 2026 23:35
@vercel

vercel Bot commented Jun 20, 2026

Copy link
Copy Markdown

Someone 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

coderabbitai Bot commented Jun 20, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Adds a new GeminiProvider LLM class and refactors OpenRouterProvider and both Gemini/OpenRouter embedding providers to accept optional baseURL parameters, falling back to GEMINI_BASE_URL/OPENROUTER_BASE_URL env vars or hardcoded defaults. These URLs are threaded through config.ts and the provider factory, with new tests and documentation added.

Changes

Configurable base URL for Gemini and OpenRouter

Layer / File(s) Summary
GeminiProvider (new) and OpenRouterProvider refactor
src/providers/gemini.ts, src/providers/openrouter.ts
Adds GeminiProvider implementing MemoryProvider with a configurable base URL and a POST-based chat completions flow. Refactors OpenRouterProvider constructor to accept optional baseURL, derive a normalized /chat/completions endpoint internally, and always send HTTP-Referer.
Embedding providers: configurable base URL
src/providers/embedding/gemini.ts, src/providers/embedding/openrouter.ts
Updates both embedding providers to accept optional baseURL, construct a per-instance endpoint from env vars or defaults by trimming trailing slashes, and use that endpoint in embedBatch instead of static constants.
Config propagation, provider factory wiring, and docs
src/config.ts, src/providers/index.ts, .env.example, README.md
Propagates GEMINI_BASE_URL and OPENROUTER_BASE_URL into ProviderConfig. Updates createBaseProvider() to import GeminiProvider and pass config.baseURL into both Gemini and OpenRouter constructors, fixing the OpenRouter API key variable. Adds env var entries to .env.example and README.md.
Provider URL construction and timeout tests
test/gemini-provider.test.ts, test/openrouter-provider.test.ts, test/fallback-model-resolution.test.ts, test/fetch-timeout.test.ts
New test suites verify default and custom base URL usage for both provider pairs. Updates fallback-model-resolution mocks to record provider names without URL-based inference. Adds a GeminiProvider hang-regression timeout suite.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Suggested reviewers

  • rohitg00

Poem

🐇 Hop, hop, hooray for flexible URLs!
No more hardcoded paths down rigid halls,
Gemini and OpenRouter, pick your base,
Env vars now set the API's place.
The rabbit cheers: configurable is cool,
Proxy or default — each provider's tool! 🌟

🚥 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 summarizes the main change: adding configurable base URLs for both OpenRouter and Gemini providers, which is the core focus across all modified files.
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

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@test/fetch-timeout.test.ts`:
- Around line 122-129: The afterEach hook unconditionally deletes the
AGENTMEMORY_LLM_TIMEOUT_MS environment variable without checking if it existed
before the test suite ran, which can cause cross-test interference. Store the
original value of AGENTMEMORY_LLM_TIMEOUT_MS (if it exists) before the
beforeEach hook sets it, then in the afterEach hook restore the original value
if it existed, or only delete it if it didn't exist before the test suite
started. This ensures the environment is left in its original state after the
test completes.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: defbafe8-0f98-44da-8e4c-3280c448cdbc

📥 Commits

Reviewing files that changed from the base of the PR and between f6f9e3c and a926dd5.

📒 Files selected for processing (12)
  • .env.example
  • README.md
  • src/config.ts
  • src/providers/embedding/gemini.ts
  • src/providers/embedding/openrouter.ts
  • src/providers/gemini.ts
  • src/providers/index.ts
  • src/providers/openrouter.ts
  • test/fallback-model-resolution.test.ts
  • test/fetch-timeout.test.ts
  • test/gemini-provider.test.ts
  • test/openrouter-provider.test.ts

Comment on lines +122 to +129
beforeEach(() => {
vi.spyOn(globalThis, "fetch").mockImplementation(hangingFetch as typeof fetch);
process.env["AGENTMEMORY_LLM_TIMEOUT_MS"] = "50";
});
afterEach(() => {
vi.restoreAllMocks();
delete process.env["AGENTMEMORY_LLM_TIMEOUT_MS"];
});

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Preserve pre-existing timeout env var in teardown.

The suite always deletes AGENTMEMORY_LLM_TIMEOUT_MS in afterEach, which can clobber a value that existed before this suite ran and cause cross-test interference.

Proposed fix
+const originalTimeoutMs = process.env["AGENTMEMORY_LLM_TIMEOUT_MS"];
+
 describe("Provider hang regression — GeminiProvider", () => {
   beforeEach(() => {
     vi.spyOn(globalThis, "fetch").mockImplementation(hangingFetch as typeof fetch);
     process.env["AGENTMEMORY_LLM_TIMEOUT_MS"] = "50";
   });
   afterEach(() => {
     vi.restoreAllMocks();
-    delete process.env["AGENTMEMORY_LLM_TIMEOUT_MS"];
+    if (originalTimeoutMs === undefined) {
+      delete process.env["AGENTMEMORY_LLM_TIMEOUT_MS"];
+    } else {
+      process.env["AGENTMEMORY_LLM_TIMEOUT_MS"] = originalTimeoutMs;
+    }
   });
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@test/fetch-timeout.test.ts` around lines 122 - 129, The afterEach hook
unconditionally deletes the AGENTMEMORY_LLM_TIMEOUT_MS environment variable
without checking if it existed before the test suite ran, which can cause
cross-test interference. Store the original value of AGENTMEMORY_LLM_TIMEOUT_MS
(if it exists) before the beforeEach hook sets it, then in the afterEach hook
restore the original value if it existed, or only delete it if it didn't exist
before the test suite started. This ensures the environment is left in its
original state after the test completes.

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