Skip to content

feat(openrouter): configurable base URL with OPENROUTER_BASE_URL env override#19

Open
cryptoxdog wants to merge 1 commit into
mainfrom
feat/openrouter-base-url-override
Open

feat(openrouter): configurable base URL with OPENROUTER_BASE_URL env override#19
cryptoxdog wants to merge 1 commit into
mainfrom
feat/openrouter-base-url-override

Conversation

@cryptoxdog

Copy link
Copy Markdown
Collaborator

Summary

Makes the OpenRouter base URL configurable instead of hardcoded, using the standard OpenAI-compatible pattern: explicit config takes precedence, then the OPENROUTER_BASE_URL environment variable, then the built-in default. This unblocks routing through proxies, gateways, and regional endpoints without touching provider code.

Verification: tsc build clean, ESLint clean, Vitest 17 files / 88 tests pass (12 new).

Problem

src/providers/openrouter.ts constructed its transport with a hardcoded baseURL: 'https://openrouter.ai/api/v1'. During the Website-Bot go-live run this surfaced as a defect: any deployment that needs to reach OpenRouter through a proxy or an OpenAI-compatible gateway had no supported way to redirect traffic — the only options were forking the provider or monkey-patching the transport.

Changes

  • src/providers/openrouter.ts
    • New exported DEFAULT_OPENROUTER_BASE_URL constant and InvalidBaseUrlError typed error.
    • New resolveOpenRouterBaseUrl(configured?, env = process.env):
      • Precedence: explicit config → OPENROUTER_BASE_URL env var → default.
      • Trims whitespace, strips trailing slashes, validates the value parses as an absolute http(s) URL; anything else throws InvalidBaseUrlError (fail-fast at construction, not first request).
    • OpenRouterClient constructor accepts baseUrl as a new trailing optional parameter — fully backward compatible with all existing call sites.
  • src/types.tsRouterConfig.openrouterBaseUrl (optional, documented).
  • src/schemas.tsRouterConfigSchema.openrouterBaseUrl: Zod url() plus an http(s)-scheme refine.
  • src/index.ts — router wires validated.openrouterBaseUrl through to the client; new symbols re-exported.
  • README.md — new "Custom OpenRouter endpoint" section documenting both configuration paths and precedence.

Tests (12 new, tests/openrouter-base-url.test.ts)

  • Default resolution when nothing is configured.
  • Config value wins over env; env wins over default (full precedence matrix).
  • Trailing-slash and whitespace normalization.
  • Rejection of invalid values: empty string, non-URL, ftp://, missing scheme.
  • Constructor integration: client transport receives the resolved URL.
  • Schema-level validation of openrouterBaseUrl in RouterConfig.

How to verify

npm run build && npm run lint && npm test
OPENROUTER_BASE_URL=https://my-gateway.example.com/api/v1 node -e ""  # env override

…override

The OpenRouter transport was constructed with a hardcoded
baseURL 'https://openrouter.ai/api/v1', leaving no supported way to route
through proxies, gateways, or OpenAI-compatible regional endpoints.

- resolveOpenRouterBaseUrl(configured?, env): precedence explicit config >
  OPENROUTER_BASE_URL env var > default; trims, strips trailing slashes,
  validates absolute http(s) URL, throws typed InvalidBaseUrlError at
  construction time (fail-fast, not first request).
- OpenRouterClient constructor gains a trailing optional baseUrl param;
  all existing call sites remain source-compatible.
- RouterConfig.openrouterBaseUrl typed + zod-validated (url + http(s)
  scheme refine); router wires it through in index.ts.
- README: 'Custom OpenRouter endpoint' section.
- 12 new tests covering precedence matrix, normalization, invalid-value
  rejection, constructor integration, and schema validation.
@sonarqubecloud

Copy link
Copy Markdown

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