Files
Hamza Kyamanywa cf08ef0a29 fix(openrouter): support default_headers for custom HTTP header injection (#36582)
Fixes #36581

## Problem

`ChatOpenRouter` had no way to set custom HTTP headers on requests to
OpenRouter. Passing `default_headers` to the constructor silently
misfired: `build_extra` treated it as an unrecognized kwarg, emitted a
"transferred to model_kwargs" warning, and dumped the header into the
request body instead of the HTTP layer. This blocked any feature that
needs per-request header injection — for example xAI's `x-grok-conv-id`
for sticky-routing prompt cache hits.

## What changed

- `default_headers` is now a first-class field on `ChatOpenRouter`
(`Mapping[str, str] | None`). Because headers may carry credentials, the
field is excluded from serialization.
- User-supplied headers are merged with the built-in app-attribution
headers (`HTTP-Referer`, `X-Title`, `X-OpenRouter-Categories`). On
collision the user value wins; because HTTP header names are
case-insensitive, the merge drops any built-in whose name
case-insensitively matches a user header before applying, so
`http-referer` replaces `HTTP-Referer` rather than producing a doubled
header.
- Corrected the documented `session_id` length limit from 128 to 256
characters.

Example:

    ChatOpenRouter(
        model="x-ai/grok-4",
        default_headers={"x-grok-conv-id": "session-abc123"},
    )

---------

Co-authored-by: Mason Daugherty <github@mdrxy.com>
2026-07-05 16:40:25 -04:00
..