Which project does this relate to?
AI
Describe the bug
@tanstack/ai-openrouter unconditionally injects streamOptions: { includeUsage: true } into every streaming request (serialized to stream_options on the wire by @openrouter/sdk). Because it is hardcoded after the spread of the caller's streamOptions, there is no way to remove or override it via modelOptions.
This breaks OpenRouter's provider routing option provider: { require_parameters: true }: OpenRouter filters to endpoints that declare support for every parameter in the request, and stream_options is an OpenAI Chat-Completions-shaped parameter that e.g. Anthropic-family endpoints do not declare. Result: every streaming call to such providers fails with 404 No endpoints found that can handle the requested parameters (verified live A/B 2026-07-31 with anthropic/claude-sonnet-4.5 — require_parameters: false works, true 404s every call).
Injection sites (current main):
-
packages/ai-openrouter/src/adapters/text.ts — chatStream:
streamOptions: {
...(chatRequest.streamOptions ?? {}),
includeUsage: true, // hardcoded after the spread — caller cannot disable
},
-
same file, structuredOutputStream — strips the caller's streamOptions then re-adds a hardcoded streamOptions: { includeUsage: true }.
-
same pattern in packages/openai-base/src/adapters/chat-completions-text.ts (stream_options: { include_usage: true }), affecting any OpenAI-compatible gateway that routes to heterogeneous providers.
Expected behavior
One of:
- Respect an explicit caller value:
modelOptions.streamOptions.includeUsage: false (or streamOptions: null) suppresses the injection, or
- an adapter-level option to disable usage-tracking injection, or
- the OpenRouter adapter omits
stream_options when the request carries provider.require_parameters: true.
Usage accounting is valuable as a default, but it currently costs the ability to use require_parameters: true at all — which is OpenRouter's recommended guard against silent provider-side parameter dropping (e.g. tool schemas).
Steps to reproduce
import { chat } from "@tanstack/ai"
import { openRouterText } from "@tanstack/ai-openrouter"
const stream = chat({
adapter: openRouterText("anthropic/claude-sonnet-4.5"),
messages: [{ role: "user", content: "hi" }],
modelOptions: {
provider: { only: ["anthropic"], require_parameters: true }
}
})
for await (const chunk of stream) console.log(chunk.type)
// → RUN_ERROR: 404 "No endpoints found that can handle the requested parameters"
// Flip require_parameters to false → works.
Versions: @tanstack/ai@0.42.0, @tanstack/ai-openrouter@0.15.10 (latest at time of filing); injection sites confirmed still present on main.
Workaround we ship today: require_parameters: false and re-test on every adapter upgrade.
Which project does this relate to?
AI
Describe the bug
@tanstack/ai-openrouterunconditionally injectsstreamOptions: { includeUsage: true }into every streaming request (serialized tostream_optionson the wire by@openrouter/sdk). Because it is hardcoded after the spread of the caller'sstreamOptions, there is no way to remove or override it viamodelOptions.This breaks OpenRouter's provider routing option
provider: { require_parameters: true }: OpenRouter filters to endpoints that declare support for every parameter in the request, andstream_optionsis an OpenAI Chat-Completions-shaped parameter that e.g. Anthropic-family endpoints do not declare. Result: every streaming call to such providers fails with404 No endpoints found that can handle the requested parameters(verified live A/B 2026-07-31 withanthropic/claude-sonnet-4.5—require_parameters: falseworks,true404s every call).Injection sites (current
main):packages/ai-openrouter/src/adapters/text.ts—chatStream:same file,
structuredOutputStream— strips the caller'sstreamOptionsthen re-adds a hardcodedstreamOptions: { includeUsage: true }.same pattern in
packages/openai-base/src/adapters/chat-completions-text.ts(stream_options: { include_usage: true }), affecting any OpenAI-compatible gateway that routes to heterogeneous providers.Expected behavior
One of:
modelOptions.streamOptions.includeUsage: false(orstreamOptions: null) suppresses the injection, orstream_optionswhen the request carriesprovider.require_parameters: true.Usage accounting is valuable as a default, but it currently costs the ability to use
require_parameters: trueat all — which is OpenRouter's recommended guard against silent provider-side parameter dropping (e.g. tool schemas).Steps to reproduce
Versions:
@tanstack/ai@0.42.0,@tanstack/ai-openrouter@0.15.10(latest at time of filing); injection sites confirmed still present onmain.Workaround we ship today:
require_parameters: falseand re-test on every adapter upgrade.