Skip to content

fix(responses): default text.format for openai-compatible responses providers (#2093) - #2112

Open
StevanusPangau wants to merge 1 commit into
decolua:masterfrom
StevanusPangau:fix/openai-compat-responses-text-format
Open

StevanusPangau wants to merge 1 commit into
decolua:masterfrom
StevanusPangau:fix/openai-compat-responses-text-format

Conversation

@StevanusPangau

Copy link
Copy Markdown
Contributor

Problem

When using a custom OpenAI-compatible provider configured with API Type responses, 9Router forwards a request body whose text is an object missing text.format. Some Responses-compatible upstreams (e.g. LM Studio) reject this with:

{ "error": { "message": "Required", "type": "invalid_request_error", "param": "text.format", "code": "missing_required_parameter" } }

This happens because a client calling /v1/responses (source format openai-responses) routed to an openai-compatible responses provider (target format openai-responses) hits the translator passthrough path — source === target, so translation is skipped and the client's text object is forwarded verbatim, without a default text.format.

Fix

Default text.format to { type: "text" } (the Responses API default for that field) in the executor before forwarding upstream, scoped to openai-compatible responses providers:

  • Only applies when the provider id is openai-compatible-* and includes responses.
  • Only applies when body.text is a plain object without a format.
  • Builds a new text object instead of mutating the caller's, and never overwrites an existing format.

Why this is safe

  • Scoped to openai-compatible responses providers; official OpenAI/codex/github executors are untouched.
  • No-op when text is absent, non-object, or already has format.
  • { type: "text" } is the documented Responses API default, so it does not change behavior for upstreams that were already accepting the request.

Tests

Adds tests/unit/openai-compat-responses-text-format.test.js:

  • Defaults text.format to { type: "text" } when text is an object without format.
  • Preserves an existing text.format.
  • No-op when there is no text.
  • Does not touch a non-responses (chat) openai-compatible provider.
  • Ignores a non-object text value.
npm exec -- vitest run tests/unit/openai-compat-responses-text-format.test.js --config tests/vitest.config.js
npm run build

All pass; related executor unit suites stay green (no regressions).

Fixes #2093

diegosouzapw added a commit to diegosouzapw/OmniRoute that referenced this pull request Jun 26, 2026
…roviders

Some Responses-compatible upstreams (e.g. LM Studio) reject a `text` object
missing `text.format` with a 400 missing_required_parameter. DefaultExecutor
now fills the Responses-API default { type: "text" } before forwarding, guarded
to openai-compatible-*responses* providers and never overwriting an existing
format. Port of decolua/9router#2112.

Includes the file-size rebaseline for default.ts (859->876) covering this growth.

Co-authored-by: StevanusPangau <StevanusPangau@users.noreply.github.com>
afandiaziz pushed a commit to afandiaziz/9router that referenced this pull request Aug 9, 2026
29 PR upstream di-cherry-pick (semua masih open upstream per 2026-08-09).
Rincian lengkap + link per PR ada di FORK-CHANGES.md.

P1 skala 2475 koneksi : decolua#2798 decolua#410 decolua#2879 decolua#879 decolua#2997
P2 akurasi token/usage: decolua#2422 decolua#2658 decolua#2762 decolua#2453 decolua#2668 decolua#2361
P3 provider & combo   : decolua#2526 decolua#3125 decolua#1434 decolua#2689 decolua#2439 decolua#2724 decolua#2647 decolua#1805
                        decolua#2909 decolua#2853 decolua#2508 decolua#2928 decolua#2345 decolua#2112 decolua#2786
P4 keamanan           : decolua#1666 decolua#2776

Revert decolua#664: menambah transformRequest kedua di DefaultExecutor sehingga
menimpa yang pertama dan mematikan stream_options/text.format/
injectReasoningContent/stripUnsupportedParams — termasuk PR decolua#3081 yang
sudah dipakai produksi.

Test: 88 gagal / 1783 lulus — nol regresi vs baseline v0.5.50 (88/1656).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

OpenAI-compatible Responses provider should default text.format when text options are present

1 participant