Skip to content

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

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

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

Conversation

@DevMello

@DevMello DevMello commented Aug 4, 2026

Copy link
Copy Markdown

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 && bun run lint:gui && bun run test && 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 structured-output settings when translating between Responses and Chat Completions formats.
    • Added support for schema metadata, descriptions, and strictness options.
  • Bug Fixes

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

@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

Review Change Stack

📝 Walkthrough

Walkthrough

Structured output support now 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 sets structured-output state only for valid supported formats.
Format translation and routing
src/adapters/openai-chat.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/kiro-adapter.test.ts, docs/github-copilot-app.md
The OpenAI Chat adapter maps structured-output options to response_format. Routed requests no longer reject internalBody.text unconditionally. Compaction clears text formatting, while unsupported backends retain their own errors. Tests and documentation cover the translation and routing behavior.

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

Suggested reviewers: wibias, lidge-jun, ingwannu

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
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes forwarding structured output to routed openai-chat models, which is the main change.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@coderabbitai coderabbitai 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.

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 on lines +1667 to +1669
// 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.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Clear _structuredOutput for routed compaction.

Line 1669 removes options.textFormat, but _structuredOutput remains true. A Kiro-routed compaction request with text.format still reaches the Kiro adapter as structured output. The Kiro adapter rejects that flag, so compaction fails instead of returning the required prose summary.

Delete parsed._structuredOutput in this block. Add a Kiro routed-compaction regression test.

Proposed fix
     delete parsed.options.parallelToolCalls;
     delete parsed.options.textFormat;
+    delete parsed._structuredOutput;
     parsed.context.messages.push({ role: "user", content: COMPACT_PROMPT, timestamp: Date.now() });
🤖 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/server/responses/core.ts` around lines 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.

@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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant