Skip to content

feat(ai): add OpenRouter provider recipe#1210

Closed
davemorin wants to merge 1 commit into
garrytan:masterfrom
davemorin:codex/openrouter-provider
Closed

feat(ai): add OpenRouter provider recipe#1210
davemorin wants to merge 1 commit into
garrytan:masterfrom
davemorin:codex/openrouter-provider

Conversation

@davemorin
Copy link
Copy Markdown

Summary

Add OpenRouter as a first-class OpenAI-compatible provider recipe.

This lets users configure openrouter:<model-id> directly instead of routing through LiteLLM when they already have an OpenRouter key. The recipe covers:

  • embedding via openrouter:openai/text-embedding-3-small by default
  • chat through OpenRouter's OpenAI-compatible endpoint
  • OPENROUTER_API_KEY auth with optional OPENROUTER_BASE_URL
  • provider docs and a focused recipe smoke test

Verification

  • bun test test/ai/recipe-openrouter.test.ts
  • bun test test/ai/recipes-existing-regression.test.ts
  • bun test test/ai/gateway-chat.test.ts
  • bun test test/ai/no-batch-cap-suppression.serial.test.ts
  • bun test test/ai
  • bun run typecheck
  • bun run src/cli.ts providers env openrouter
  • OPENROUTER_API_KEY=fake bun run src/cli.ts providers list

Risk

Low. This adds a new static recipe and registry entry without changing existing provider behavior. Existing auth regression tests still pass.

@garrytan
Copy link
Copy Markdown
Owner

Thank you, @davemorin! Cherry-picked and shipped as #1246 (v0.37.4.0).

Master had moved past the base your PR was opened against (v0.37.0 → v0.37.3 shipped in between), so I extracted the OpenRouter additions onto current master and folded in corrections from a Codex outside-voice review:

  • Replaced unverified slug openai/gpt-5.2-pro with openai/gpt-5.5 (verified on OR's catalog)
  • Corrected attribution headers to current OR docs: X-OpenRouter-Title (preferred) + X-Title (back-compat alias)
  • max_batch_tokens: 8192300_000 (OpenAI's aggregate per-request token cap, not the per-input cap the original conflated)
  • Dropped misleading max_context_tokens: 200000 (mixed catalog spans 128K–1M+)
  • Added Matryoshka dims_options: [512, 768, 1024, 1536] for text-embedding-3-small
  • Added generic Recipe.default_headers / resolveDefaultHeaders?(env) seam so attribution headers ride alongside Bearer auth with mutual-exclusion + auth-shadow guards (usable by Together/Groq later)
  • supports_subagent_loop: false documented as informational only — the real gate is isAnthropicProvider() upstream
  • Added OPENROUTER_REFERER / OPENROUTER_TITLE env overrides so forks get their own attribution on OR's leaderboard
  • Added transport-level header test that proves headers actually reach the wire (synthetic recipe + custom fetch wrapper) — not just return-shape verification
  • Exported buildGatewayConfig for unit-test access, with a 5-way env-baseURL sweep

You're credited in the CHANGELOG + the recipe-add commit message. Closing this one in favor of #1246. Thanks again!

@garrytan garrytan closed this May 20, 2026
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.

2 participants