Repository navigation
feat(ai): type OpenRouter options on the Responses route - #60044
Conversation
There was a problem hiding this comment.
Looks good. The new Responses-route body test fails on the base, because provider/models/plugins/debug/user are missing from the /responses body, and passes with this change. The two OpenRouter test files pass (46 tests), and tsc passes for both tsconfigs, including the new type tests. The design matches the existing openrouter-chat protocol: the shared fields are added through SharedOptions, bad values are still dropped by the lenient decoding, and the stream parsing is reused unchanged. Nothing in packages/ai or packages/core checks for the open-responses protocol id, so the rename has no effect on behaviour elsewhere.
Public API (@opencode/ai):
- Adds the
OpenRouterResponsesProviderOptionsInputtype. - Widens
OpenRouter.responses(...)/responsesModel/providers/openrouter/responsesSettingsfromOpenResponsesProviderOptionsInputtoOpenRouterResponsesProviderOptionsInput, andConfig.providerOptionswith it. - Changes the OpenRouter Responses route's
protocolid fromopen-responsestoopenrouter-responses.
All of this is backwards compatible for type users. Only code that compared the route's protocol id to "open-responses" would notice.
No other concerns.
dbc9246 to
299ca48
Compare
There was a problem hiding this comment.
The new push is a rebase onto dev with no change to the PR's own diff. Re-checked on the new head: the OpenRouter provider and package tests pass (46), and tsc passes for both tsconfigs. The public API impact is the same as in my earlier review: it adds OpenRouterResponsesProviderOptionsInput, widens the OpenRouter Responses settings and options types, and changes the Responses route's protocol id from open-responses to openrouter-responses. All of it is backwards compatible. No new concerns.
Problem
OpenRouter.responses(id)used the generic Responses options type and protocol. OpenRouter's own request options (providerrouting,modelsfallbacks,plugins, ...) were not typed there, and the generic Responses body schema dropped them, so they only reached OpenRouter through a rawbodyoverlay.Change
I checked the
POST /responsesrequest schema in OpenRouter's API reference (https://openrouter.ai/docs/api/api-reference/responses/create-a-response, accessed 2026-10-28). Of the options the Chat route already types, these are also accepted on/responses, and are now typed and sent on the Responses route:providermodelspluginsdebuguserusage,web_search_options/responsesschemaThe Responses route keeps the standard Responses options (
reasoningEffort,include,store, ...), andreasoningkeeps going through them.Both routes share one schema and one lowering, so nothing is duplicated:
The type reuses the existing option types:
OpenResponsesProviderOptionsInput & Pick<OpenRouterOptions, "debug" | "models" | "plugins" | "provider" | "user">. Enum-like strings such asprovider.sortanddata_collectionstill accept any string, and the shared lenient decoding drops a malformed known option without failing the request.The Responses route now uses its own
openrouter-responsesprotocol (the Chat route already hasopenrouter-chat). Stream parsing is stillOpenResponses.protocol.stream.Live evidence
I sent requests through
OpenRouter.responses("openai/gpt-5.4-mini")with theX-OpenRouter-Metadata: enabledheader so OpenRouter reports its routing decision inopenrouter_metadataonresponse.completed.provider.only(5 endpoints in total; without a preference, 2 were available):providerOptionssummaryavailable=2, selected=OpenAIprovider: { only: ["azure"], allow_fallbacks: false }available=1, selected=Azureprovider: { only: ["openai"], allow_fallbacks: false }available=1, selected=OpenAImodelsfallbacks:providerOptionsrequestedstrategyopenai/gpt-5.4-minidirectmodels: ["openai/gpt-5.4-nano"]openai/gpt-5.4-mini,openai/gpt-5.4-nanofallbackTests
provider,models,plugins,debugandusernext to standard Responses fields. It fails without this change.modelsvalue.Out of scope
/responsesalso accepts OpenRouter fields that neither route types yet:session_id,trace,cache_control,prompt_cache_options,modalities,image_config,stop_server_tools_when,deferred_tools, and the OpenRouterreasoning.enabled/reasoning.max_tokensextensions. They can still be sent throughbody.Visual
Added by the opencode bot (AI-generated).
Public API: adds OpenRouter routing options (provider, models, plugins, debug, user) to the OpenRouter Responses options type; Responses route protocol id open-responses → openrouter-responses (backwards compatible)