citeformer.backends.openrouter¶
OpenRouter backend — multi-provider routing on the OpenAI wire format.
OpenRouter (https://openrouter.ai) is a thin proxy in front of every production LLM provider — OpenAI, Anthropic, Google, Mistral, Meta, DeepSeek, and so on. The wire format is identical to OpenAI’s chat completions API, so this backend is implemented as a thin
- class:
OpenAIBackendsubclass: schema construction, segment flattening, streaming, and usage extraction are all inherited unchanged. We only add the OpenRouter-specific knobs:
Per-model routing. Models are namespaced by provider, e.g.
"anthropic/claude-sonnet-4.6","openai/gpt-4o","google/gemini-2.5-pro". The default is configurable viamodel=...at construction time; see https://openrouter.ai/models for the live catalogue.Provider gating. OpenRouter’s
provider.require_parameters: trueknob refuses to route to any upstream that doesn’t accept every parameter you sent. Combined with the strictresponse_formatciteformer always sets, this means: if the upstream provider can’t do logit-tier strict schema enforcement, OpenRouter returns a 4xx instead of silently falling back to a non-strict provider. That preserves the citeformer guarantee end-to-end. Disable withrequire_provider_parameters=Falseif you’d rather take whatever upstream answers first.App attribution. OpenRouter encourages clients to identify themselves with
HTTP-Referer+X-Titleheaders. Passapp_nameand/orapp_urlat construction time and they’re threaded onto every request.Cost reporting. OpenRouter attaches a per-call
costto everyusagepayload unconditionally — the olderusage: {include: true}request flag isdeprecated and a no-op <https://openrouter.ai/docs/guides/administration/usage-accounting>_. The cost is reported in OpenRouter credits, not USD (1 credit ≈ 1 USD by default but the unit is credits); we surface it on- attr:
GenerationResult.usage.cost_creditsto keep the label honest.
Provider fallback. Pass
fallback_models=[...]to enable OpenRouter’s automatic failover when the primary upstream is down or rate-limited. Citeformer’s strictresponse_formatrequirement flows to fallback providers too.
.. note::
OpenRouter model ids spell the version segment with a dot
(anthropic/claude-sonnet-4.6), while Anthropic’s native API uses
a dash (claude-sonnet-4-6). They are the same model — easy
footgun if you copy-paste between configs.
Tier honesty: when require_provider_parameters=True (the default),
this backend is logit-tier on every modern upstream that supports
strict structured outputs (OpenAI gpt-4o-2024-08-06+, Anthropic
Sonnet 4.5+, Gemini 2.x, Mistral 2024-11+, Groq, Fireworks, Together).
With require_provider_parameters=False it falls back to schema-tier
post-validation on whichever provider answers — fabrication is still
structurally impossible in the returned payload, but enforcement isn’t
guaranteed at sample time anymore.
Requires the openrouter extra: pip install citeformer[openrouter]
(re-uses the openai SDK, since OpenRouter is OpenAI wire-compatible).
Module Contents¶
Classes¶
OpenRouter multi-provider backend with per-model routing. |
Data¶
API¶
- citeformer.backends.openrouter.DEFAULT_BASE_URL¶
- class citeformer.backends.openrouter.OpenRouterBackend(model: str = _DEFAULT_MODEL, *, client: Any | None = None, async_client: Any | None = None, api_key: str | None = None, base_url: str = DEFAULT_BASE_URL, app_name: str | None = None, app_url: str | None = None, require_provider_parameters: bool = True, fallback_models: list[str] | None = None, **client_kwargs: Any)¶
Bases:
citeformer.backends.openai.OpenAIBackendOpenRouter multi-provider backend with per-model routing.
Inherits OpenAI’s schema construction, segment flattening, streaming fallback, and token-usage extraction — only the request-augmentation hook and a handful of init knobs differ. See the module docstring for the OpenRouter-specific knobs (provider gating, app attribution, cost reporting, fallback models).
Attributes: model: OpenRouter model id including the provider prefix (
"anthropic/claude-sonnet-4.6","openai/gpt-4o", …). Note: OR uses a dot in the version (4.6) where Anthropic’s native API uses a dash (4-6). client: The underlyingopenai.OpenAIclient, configured with OpenRouter’s base URL + the user’s app-attribution headers. require_provider_parameters: IfTrue(default), only routes to upstreams that accept every request parameter — preserves the strict-schema enforcement guarantee end-to-end. fallback_models: Ordered list of secondary models OpenRouter may failover to.Nonedisables fallback.Initialization
Construct an OpenRouter backend.
Args: model: OpenRouter model id (
"<provider>/<model>"). See https://openrouter.ai/models for the live catalogue. client: Pre-builtopenai.OpenAIclient (already pointed at OpenRouter). WhenNone, one is constructed using the other arguments. api_key: OpenRouter API key. WhenNone, falls back toOPENROUTER_API_KEYfrom the environment, then toclient_kwargs["api_key"]if supplied. base_url: OpenRouter API base URL. Override only for staging / proxy testing. app_name: Sets theX-Titleheader — shown on the OpenRouter dashboard so you can attribute spend to your app. Optional but encouraged. app_url: Sets theHTTP-Refererheader — same purpose. Optional. require_provider_parameters: WhenTrue(default), refuses to route to upstreams that drop request parameters. Preserves citeformer’s strict-schema enforcement. fallback_models: Optional ordered list of secondary models for automatic failover if the primary upstream errors or rate limits. **client_kwargs: Forwarded toopenai.OpenAI(**kwargs)whenclientisNone(timeout,max_retries, …).