Repository navigation
feat(ai): Responses routes for OpenRouter, DigitalOcean and Venice - #59991
Conversation
There was a problem hiding this comment.
The new Responses routes do what the description says, and each provider's default model() still uses Chat. The recorded tests and the full packages/ai suite pass, and tsc --noEmit is clean for packages/ai and packages/core.
Public API: additions only, backwards compatible:
OpenRouter,DigitalOceanandVeniceeach gainresponses(id)on the configured provider, plus top-levelresponsesandresponsesModelexports.- New
routesentries:openrouter-responses,digitalocean-responsesandvenice-responses. - New subpath exports:
@opencode/ai/providers/{openrouter,digitalocean,venice}/responses. Settingsbecomes generic, with the old type as its default, andConfig.providerOptionsalso accepts Responses options.
Existing callers don't need to change.
One gap: core's reasoning-effort table in packages/core/src/variant.ts (PROTOCOLS) has no entries for the three new entry points, so once models.dev moves to them those models lose their reasoning-effort options (see inline comment).
| ["@opencode/ai/providers/openrouter", () => import("@opencode/ai/providers/openrouter")], | ||
| ["@opencode/ai/providers/openrouter/decisions", () => import("@opencode/ai/providers/openrouter/decisions")], | ||
| ["@opencode/ai/providers/openrouter/images", () => import("@opencode/ai/providers/openrouter/images")], | ||
| ["@opencode/ai/providers/openrouter/responses", () => import("@opencode/ai/providers/openrouter/responses")], |
There was a problem hiding this comment.
These entry points are added to the loader, but core's reasoning-effort table in packages/core/src/variant.ts (PROTOCOLS) has no entries for them, so Variant.resolve returns []. I checked with an effort-capable model: @opencode/ai/providers/openai-compatible/responses gives 2 variants and each of the three new .../responses packages gives 0. Once models.dev points [api.responses] at these, those models would lose their reasoning-effort options. Could you map them to openResponses, as openai-compatible/responses is, and add a case to test/variant.test.ts?
There was a problem hiding this comment.
The new commit fixes the reasoning-effort gap: the three new .../responses entry points are now mapped to openResponses in variant.ts. I checked that Variant.resolve now gives effort options for each of them, the core variant tests pass, and tsc --noEmit is clean for packages/core. The public API impact is the same as in my earlier review (additions only, backwards compatible). Nothing else to raise.
Problem
OpenRouter, DigitalOcean and Venice all serve OpenAI's Responses API at
/responses, but their providers in@opencode/aionly had Chat Completions routes. To use Responses with them you had to go through the genericopenai-compatible/responsesentry point and set the base URL, auth and provider ID yourself.Change
I added a
responsesroute to each provider. Each one reuses the shared Open Responses protocol and has the same defaults as the generic Responses route (store: false, encrypted reasoning included). It also uses the provider's own base URL, API key env vars and provider metadata key.Each provider also gets a package entry point, following the existing subpath convention, and core lists them in its built-in loader map and its reasoning-effort table:
@opencode/ai/providers/openrouter/responses@opencode/ai/providers/digitalocean/responses@opencode/ai/providers/venice/responsesEach provider's default
model()stays on Chat, so existing callers see no change. Freeform (custom) tools, reasoning replay and the other Responses features now work through these routes.I recorded cassettes against all three live APIs on a GPT-5.4 mini model. They cover a streamed text reply, a full tool loop, and a freeform
{ type: "text" }tool call.Out of scope
tool_choice({ type: "custom", name }). It acceptsrequired. I left the request as is rather than rewriting it on the client.provider,plugins,models) are only typed on the Chat route. On the Responses route they can still be sent throughbody.[api.responses]entries at@opencode/ai/providers/openai-compatible/responses. They can move to the new entry points once this version is published.Visual
Added by the opencode bot (AI-generated).
Public API: adds Responses routes and
@opencode/ai/providers/{openrouter,digitalocean,venice}/responsesentry points (backwards compatible)