Skip to content

feat(responses): deliver structured output to routed openai-chat models - #985

Open
DevMello wants to merge 5 commits into
lidge-jun:devfrom
DevMello:feat/routed-response-format
Open

feat(responses): deliver structured output to routed openai-chat models#985
DevMello wants to merge 5 commits into
lidge-jun:devfrom
DevMello:feat/routed-response-format

Conversation

@DevMello

@DevMello DevMello commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Responses text.format was reduced to a boolean and discarded, so structured output (Codex --output-schema) silently never reached routed models, and the chat surface returned HTTP 400 for response_format on routed openai-chat models.
  • The format object now rides the parsed request and the openai-chat adapter emits chat response_format, the exact inverse of the existing inbound mapping. The 400 guard is removed, routed compaction strips the format so summaries stay prose, and the native Responses passthrough is untouched.

Verification

  • bun run typecheck, the lint gate, bun run test, and bun run privacy:scan
  • New tests: parser carry, adapter re-nesting (json_object, json_schema, name default, schema-less), byte-identical round trip on the chat surface, /v1/responses to routed chat wire, compaction drops the format, Kiro rejection pinned.

Checklist

  • Scope stays focused and avoids unrelated cleanup.
  • Docs or release notes were updated when needed.
  • Security-sensitive changes were reviewed for secrets, auth, and unsafe defaults.

Summary by CodeRabbit

  • New Features

    • Added structured-output support for routed OpenAI Chat requests using JSON Object and JSON Schema formats.
    • Preserved schema names, descriptions, schemas, and strictness when translating between Responses and Chat Completions formats.
  • Bug Fixes

    • Unsupported backends now return their appropriate capability errors.
    • Compaction requests no longer inherit structured-output formatting.
    • Requests with internal text settings are no longer rejected unnecessarily.
  • Documentation

    • Documented structured-output forwarding and backend compatibility.

Review readiness checklist

This PR stays in draft until every box below is ticked. Tick all four boxes once the requirements are met:

  • All CI tests are green on my local testing.

  • I pushed my PR to the latest dev commit.

  • I resolved all correct Codex and CodeRabbit findings.

  • My PR is ready for review.

@github-actions github-actions Bot added the enhancement New feature or request label Aug 4, 2026
@coderabbitai

coderabbitai Bot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Important

Review skipped

No new commits to review since the last review.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 584c76d5-f8dc-4801-9c28-506045f805ae

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Structured output support preserves Responses text.format, translates it to Chat Completions response_format, permits routed openai-chat requests, defers unsupported-backend errors, and removes formatting during routed compaction.

Changes

Structured output handling

Layer / File(s) Summary
Structured output format contract
src/types.ts, src/responses/parser.ts, tests/responses-parser.test.ts
OcxRequestOptions.textFormat stores supported JSON object and JSON schema formats. The parser preserves format metadata and enables structured-output state only for valid supported formats.
Format translation, routing, and compaction
src/adapters/openai-chat.ts, src/adapters/openai-responses.ts, src/server/chat-completions.ts, src/server/responses/core.ts, tests/chat-completions-endpoint.test.ts, tests/openai-chat-hardening.test.ts, tests/responses-compaction-routing.test.ts, tests/server-kiro-completion-e2e.test.ts, tests/kiro-adapter.test.ts
The OpenAI Chat adapter maps structured-output options to response_format. Routed requests no longer reject internalBody.text unconditionally. Compaction removes structured-output settings before forwarding. Unsupported backends retain their own errors.
Forwarding documentation
docs/github-copilot-app.md, docs-site/src/content/docs/reference/proxy-formats.md
Documentation describes supported format forwarding and backend-owned errors.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant ResponsesAPI
  participant ResponsesParser
  participant OpenAIChatAdapter
  participant UpstreamChatCompletions
  ResponsesAPI->>ResponsesParser: Parse text.format
  ResponsesParser->>OpenAIChatAdapter: Pass options.textFormat
  OpenAIChatAdapter->>UpstreamChatCompletions: Send response_format
Loading

Possibly related PRs

Suggested reviewers: lidge-jun, wibias

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the primary change: forwarding structured output to routed openai-chat models.
✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/server/responses/core.ts`:
- Around line 1667-1669: Clear parsed._structuredOutput in the routed compaction
normalization block alongside the existing parsed.options.textFormat removal,
ensuring the synthetic compaction request is sent as plain prose to the Kiro
adapter. Add a regression test covering Kiro-routed compaction with text.format
and verify it succeeds with a prose summary.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 3e283b5a-c413-40ee-bb21-25f779684ab0

📥 Commits

Reviewing files that changed from the base of the PR and between 48338a1 and db284da.

📒 Files selected for processing (11)
  • docs/github-copilot-app.md
  • src/adapters/openai-chat.ts
  • src/responses/parser.ts
  • src/server/chat-completions.ts
  • src/server/responses/core.ts
  • src/types.ts
  • tests/chat-completions-endpoint.test.ts
  • tests/kiro-adapter.test.ts
  • tests/openai-chat-hardening.test.ts
  • tests/responses-compaction-routing.test.ts
  • tests/responses-parser.test.ts
💤 Files with no reviewable changes (1)
  • src/server/chat-completions.ts

Comment thread src/server/responses/core.ts

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: db284da38a

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

delete parsed.options.parallelToolCalls;
// The compaction turn is a plain prose summary; a surviving structured-output format
// would force schema-constrained JSON into the synthetic compaction item.
delete parsed.options.textFormat;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Strip text.format from raw compaction bodies

When routed compaction is sent to a noncanonical openai-responses provider, deleting only parsed.options.textFormat does not change the payload: that adapter's buildRequest starts from parsed._rawBody and buildRoutedCompactionBody only removes tools/tool_choice/parallel. With --output-schema/text.format, the compaction summarizer still receives text.format and can be forced to emit schema JSON instead of the prose summary that the synthetic compaction item needs. Strip text from the raw compaction body as well.

Useful? React with 👍 / 👎.

Comment on lines 52 to +54
tool calls, prompt cache keys, metadata, and `response_format` on native Responses
routes. Routed `openai-chat` models reject `response_format` with HTTP 400 because
their structured-output support is not verified. Other Chat Completions fields,
including penalties, `n`, and logprobs, are not currently supported.
routes and routed `openai-chat` models (`json_object` and `json_schema` are
forwarded as-is; a backend without structured-output support returns its own

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Update the public docs site for response_format

Because this change exposes response_format support to OpenAI-compatible clients, updating only docs/github-copilot-app.md leaves the hosted docs-site reference/guides without the new behavior; users reading the public docs still have no indication that routed openai-chat can accept structured output. Add the corresponding docs-site/ update, including locales if relevant, alongside this docs change.

AGENTS.md reference: AGENTS.md:L224-L225

Useful? React with 👍 / 👎.

@Wibias
Wibias marked this pull request as draft August 4, 2026 07:30
@github-actions

github-actions Bot commented Aug 6, 2026

Copy link
Copy Markdown

Deterministic PR hygiene checks passed.

@DevMello
DevMello marked this pull request as ready for review August 6, 2026 08:59

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs-site/src/content/docs/reference/proxy-formats.md`:
- Around line 141-145: Rewrite the structured-output section to distinguish the
two wire contracts: state that response_format is forwarded for routed
openai-chat models, native POST /v1/responses routes preserve text.format, and
text.format is translated to response_format only when /v1/responses routes to
openai-chat. Do not imply that response_format is accepted as the native
Responses request field.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 1bcfaa10-d88a-4ceb-93b7-ed1024208ee4

📥 Commits

Reviewing files that changed from the base of the PR and between db284da and 10ff220.

📒 Files selected for processing (5)
  • docs-site/src/content/docs/reference/proxy-formats.md
  • src/adapters/openai-responses.ts
  • src/server/responses/core.ts
  • tests/responses-compaction-routing.test.ts
  • tests/server-kiro-completion-e2e.test.ts

Comment thread docs-site/src/content/docs/reference/proxy-formats.md Outdated

@Ingwannu Ingwannu left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is valuable and the translation shape is correct, but the branch must be rebased before it is mergeable under the current repository gates.

I reviewed head f717017a. Preserving Responses text.format, re-nesting it as Chat Completions response_format, leaving native Responses passthrough on _rawBody, and stripping all structured-output state from routed compaction are the correct boundaries. Letting an incompatible chat backend return its own capability error is also preferable to OpenCodex silently returning unconstrained prose. I found no protocol blocker in the patch itself.

I built a local merge result against current dev (a5b37827) and verified:

  • six focused parser/adapter/endpoint/compaction/Kiro suites — 192 passed, 0 failed
  • bun run typecheck — passed

The blocking issue is branch/gate state: this head is 570 commits behind current dev. Its enforce-target job fails because the old checkout does not contain .github/scripts/pr-quality-state.cjs, and no required exact-head ci run is attached. Please rebase the contributor branch onto current dev (do not merge dev into it), resolve any review-readiness checklist the updated gate adds, and rerun CI on the new exact head. Once that is green, I consider this worth merging.

@DevMello
DevMello force-pushed the feat/routed-response-format branch from f717017 to 1ebdd83 Compare August 6, 2026 11:01
@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Note

GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer.

@github-actions

github-actions Bot commented Aug 6, 2026

Copy link
Copy Markdown

✅ READY

  • all PR quality gates passed; the review readiness checklist is complete.

Review readiness checklist

  • ✅ All CI tests are green on my local testing.
  • ✅ I pushed my PR to the latest dev commit.
  • ✅ I resolved all correct Codex and CodeRabbit findings.
  • ✅ My PR is ready for review.

4/4 boxes ticked.

This pull request is already Ready for Review.
CodeRabbit/Codex review was requested via the review-ready label. If no review appears, comment @coderabbitai review to request one.
Maintainers: @lidge-jun @Ingwannu @Wibias

@github-actions
github-actions Bot marked this pull request as draft August 6, 2026 11:01
@github-actions
github-actions Bot marked this pull request as ready for review August 6, 2026 11:02
@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

@github-actions[bot] The pull request is marked ready. I will review the changes.

⚠️ Action not completed

Already reviewed.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

@github-actions[bot] I will review pull request #985.

⚠️ Action not completed

Already reviewed.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/github-copilot-app.md`:
- Around line 53-55: Update the native Responses wire-field description in the
surrounding documentation to state that direct POST /v1/responses callers must
use text.format, while routed openai-chat requests use response_format. Clarify
that Chat Completions input is converted to Responses text.format rather than
forwarded unchanged.

In `@src/adapters/openai-chat.ts`:
- Around line 827-840: Update the json_schema branch in the response-format
mapping to preserve schema-less formats by removing the schema presence
requirement and conditionally adding the schema field only when defined. Keep
the existing name, description, and strict handling, and add a round-trip
regression test covering json_schema without schema.

In `@tests/responses-compaction-routing.test.ts`:
- Around line 420-421: Remove the duplicate const json declaration in
tests/responses-compaction-routing.test.ts lines 420-421, retaining one response
JSON parse for the test callback. Also remove the duplicate const json
declaration in tests/server-kiro-completion-e2e.test.ts lines 244-245, retaining
one response JSON parse there; separate test callback scopes may keep distinct
json declarations.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 31306e04-6768-44ac-ba3f-d9b44714dd93

📥 Commits

Reviewing files that changed from the base of the PR and between 8ed03e7 and 1ebdd83.

📒 Files selected for processing (14)
  • docs-site/src/content/docs/reference/proxy-formats.md
  • docs/github-copilot-app.md
  • src/adapters/openai-chat.ts
  • src/adapters/openai-responses.ts
  • src/responses/parser.ts
  • src/server/chat-completions.ts
  • src/server/responses/core.ts
  • src/types.ts
  • tests/chat-completions-endpoint.test.ts
  • tests/kiro-adapter.test.ts
  • tests/openai-chat-hardening.test.ts
  • tests/responses-compaction-routing.test.ts
  • tests/responses-parser.test.ts
  • tests/server-kiro-completion-e2e.test.ts
💤 Files with no reviewable changes (1)
  • src/server/chat-completions.ts

Comment on lines +53 to +55
routes and routed `openai-chat` models (`json_object` and `json_schema` are
forwarded as-is; a backend without structured-output support returns its own
error). Other Chat Completions fields, including penalties, `n`, and logprobs,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Correct the native Responses wire-field description.

response_format is not forwarded as-is to a native Responses provider. Chat Completions input is converted to Responses text.format. Direct POST /v1/responses callers must send text.format.

State that routed openai-chat uses response_format, while native Responses uses text.format. The current wording can cause clients to send an unsupported field to /v1/responses.

Proposed fix
- tool calls, prompt cache keys, metadata, and `response_format` on native Responses
- routes and routed `openai-chat` models (`json_object` and `json_schema` are
- forwarded as-is; a backend without structured-output support returns its own
- error). Other Chat Completions fields, including penalties, `n`, and logprobs,
+ tool calls, prompt cache keys, metadata, and structured output. Chat Completions
+ `response_format` is translated to Responses `text.format` for native Responses
+ providers and forwarded as `response_format` to routed `openai-chat` providers.
+ A backend without structured-output support returns its own error. Other Chat
+ Completions fields, including penalties, `n`, and logprobs,
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/github-copilot-app.md` around lines 53 - 55, Update the native Responses
wire-field description in the surrounding documentation to state that direct
POST /v1/responses callers must use text.format, while routed openai-chat
requests use response_format. Clarify that Chat Completions input is converted
to Responses text.format rather than forwarded unchanged.

Comment on lines +827 to +840
const textFormat = parsed.options.textFormat;
if (textFormat?.type === "json_object") {
body.response_format = { type: "json_object" };
} else if (textFormat?.type === "json_schema" && textFormat.schema !== undefined) {
body.response_format = {
type: "json_schema",
json_schema: {
name: textFormat.name ?? "response",
...(textFormat.description !== undefined ? { description: textFormat.description } : {}),
schema: textFormat.schema,
...(textFormat.strict !== undefined ? { strict: textFormat.strict } : {}),
},
};
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Preserve schema-less json_schema formats.

Line 830 drops response_format when textFormat.schema is absent. src/chat/inbound.ts:175-196 accepts that Chat Completions shape and maps it to text.format, so this is not the claimed inverse mapping. The routed request then silently loses structured-output handling and can return prose instead of the upstream capability or validation error.

Remove the schema !== undefined condition. Include schema only when it exists. Add a round-trip regression test for json_schema without schema.

Proposed fix
-      } else if (textFormat?.type === "json_schema" && textFormat.schema !== undefined) {
+      } else if (textFormat?.type === "json_schema") {
         body.response_format = {
           type: "json_schema",
           json_schema: {
             name: textFormat.name ?? "response",
             ...(textFormat.description !== undefined ? { description: textFormat.description } : {}),
-            schema: textFormat.schema,
+            ...(textFormat.schema !== undefined ? { schema: textFormat.schema } : {}),
             ...(textFormat.strict !== undefined ? { strict: textFormat.strict } : {}),
           },
         };
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const textFormat = parsed.options.textFormat;
if (textFormat?.type === "json_object") {
body.response_format = { type: "json_object" };
} else if (textFormat?.type === "json_schema" && textFormat.schema !== undefined) {
body.response_format = {
type: "json_schema",
json_schema: {
name: textFormat.name ?? "response",
...(textFormat.description !== undefined ? { description: textFormat.description } : {}),
schema: textFormat.schema,
...(textFormat.strict !== undefined ? { strict: textFormat.strict } : {}),
},
};
}
const textFormat = parsed.options.textFormat;
if (textFormat?.type === "json_object") {
body.response_format = { type: "json_object" };
} else if (textFormat?.type === "json_schema") {
body.response_format = {
type: "json_schema",
json_schema: {
name: textFormat.name ?? "response",
...(textFormat.description !== undefined ? { description: textFormat.description } : {}),
...(textFormat.schema !== undefined ? { schema: textFormat.schema } : {}),
...(textFormat.strict !== undefined ? { strict: textFormat.strict } : {}),
},
};
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/adapters/openai-chat.ts` around lines 827 - 840, Update the json_schema
branch in the response-format mapping to preserve schema-less formats by
removing the schema presence requirement and conditionally adding the schema
field only when defined. Keep the existing name, description, and strict
handling, and add a round-trip regression test covering json_schema without
schema.

Comment on lines 420 to 421
const json = await res.json() as { output?: Array<{ type?: string }> };
const compactionItems = (json.output ?? []).filter(item => item.type === "compaction");

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🔴 Critical | ⚡ Quick win

Remove the duplicate const json declarations.

Each test callback declares const json twice in the same lexical scope. TypeScript rejects both files before Bun can run the tests.

  • tests/responses-compaction-routing.test.ts#L420-L421: keep one const json = await res.json() declaration.
  • tests/server-kiro-completion-e2e.test.ts#L244-L245: keep one const json = await response.json() declaration.

Based on learnings, repeated const names are valid only in separate test callback scopes.

📍 Affects 2 files
  • tests/responses-compaction-routing.test.ts#L420-L421 (this comment)
  • tests/server-kiro-completion-e2e.test.ts#L244-L245
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/responses-compaction-routing.test.ts` around lines 420 - 421, Remove
the duplicate const json declaration in
tests/responses-compaction-routing.test.ts lines 420-421, retaining one response
JSON parse for the test callback. Also remove the duplicate const json
declaration in tests/server-kiro-completion-e2e.test.ts lines 244-245, retaining
one response JSON parse there; separate test callback scopes may keep distinct
json declarations.

Source: Learnings

@Ingwannu Ingwannu left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Confirmed that the branch is now rebased onto current dev, so the old freshness-only blocker is resolved. The current head is not merge-ready yet because the latest review found substantive exact-head issues:

  • Preserve a json_schema format even when its optional schema member is absent; conditionally include schema instead of dropping the whole format. Add the schema-less round-trip regression.
  • Remove the duplicate const json declarations in both tests/responses-compaction-routing.test.ts and tests/server-kiro-completion-e2e.test.ts; these are same-scope parse/type failures, not style nits.
  • Make both docs distinguish the native Responses text.format contract from routed Chat Completions response_format, including that Chat Completions input is converted rather than forwarded as a native Responses field.

The underlying translation boundary remains valuable and correctly placed. Keeping changes requested until those findings and exact-head CI are green.

@lidge-jun

Copy link
Copy Markdown
Owner

Thank you — this is landing as #1137 in the stacked campaign. Most of your commits were cherry-picked with your authorship intact; the one correction I made is co-authored with you.

Your architecture was right and I kept it as designed: carry the parsed format on options.textFormat, keep _structuredOutput for the web-search sidecar, and re-nest the flattened Responses fields under json_schema as the inverse of responseFormatToText. The comment explaining why response_format is forwarded unconditionally rather than capability-gated is a good one and it survived into the stack verbatim.

One correction. The json_schema branch was guarded by textFormat.schema !== undefined, so a schema-less json_schema fell through and no response_format was sent at all — silently reproducing the original defect on a narrower input. I moved the guard from the branch condition onto the schema member so the format is still emitted, and added a regression test asserting response_format.type === "json_schema" when no schema is supplied.

Your #978 landed in the same PR — see the comment there.

Verified: 129 pass / 0 fail across the openai-chat, parser, chat-completions and google suites; full bun run test exit 0; typecheck and privacy scan clean; docs build 221 pages.

Leaving this PR open for you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request review-ready

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants