Skip to content

[Bug]: Chat Completions translator omits reasoning.summary; gpt-6-astra 400s after tool turns #4628

Closed

Description

@rjoleinik

Client or integration

Direct HTTP/API client

Area

Proxy and routing

Summary

OpenCodex 2.55.0 translates Chat Completions history into Responses input items without a summary field on type: "reasoning" items. A subsequent gpt-6-astra turn that replays that history is rejected by the Responses backend with HTTP 400 missing_required_parameter for input[N].summary.

A new Chat Completions conversation hits the same error after the first tool/reasoning round-trip. This is not a stuck client transcript.

Expected: chatCompletionsToResponsesBody emits reasoning items with a summary array, matching the Claude inbound translator (summary: [{ type: "summary_text", text: ... }] or summary: []).

Reproduction

  1. Run stock OpenCodex 2.55.0 (@bitkyc08/opencodex) as the proxy.
  2. From any Chat Completions client, send gpt-6-astra (reasoning enabled) to OpenCodex /v1/chat/completions with tools.
  3. First assistant turn returns reasoning plus at least one tool call; the client posts the tool result.
  4. OpenCodex translates the follow-up via chatCompletionsToResponsesBody in src/chat/inbound.ts.
  5. The translated input item is { type: "reasoning", content: [{ type: "reasoning_text", text }] } with no summary key.
  6. The upstream Responses API returns 400: missing required parameter input[N].summary (N is the reasoning item index after preamble/tool items).

Suggested one-line shape (same file, assistant branch):

input.push({
  type: "reasoning",
  summary: [{ type: "summary_text", text: reasoningText }],
  content: [{ type: "reasoning_text", text: reasoningText }],
});

Version

2.55.0

Operating system

macOS 26.6.2

Provider and model

openai / gpt-6-astra

Logs or error output

Error: 400: {"message":"[ObjectParam] [input[17].summary] [missing_required_parameter] Missing required parameter: 'input[17].summary'.","type":"invalid_request_error","param":null,"code":"invalid_request_error"}

The index 17 is from one captured turn; the stable defect is the missing summary key on the reasoning item, not that specific index.

Screenshots and supporting files

No response

Redacted configuration

{
  "proxy": "opencodex /v1/chat/completions",
  "model": "gpt-6-astra",
  "client_api": "openai-chat-completions",
  "reasoning": true,
  "tools": true
}

Checks

  • I searched existing issues and documentation.
  • I removed secrets, tokens, account details, request credentials, and personal data.

Activity

  1. added
    bugSomething isn't working
    proxyHTTP proxy, routing, reverse-proxy / management auth
    toolstool_calls, MCP, web-search / sidecar tools
    on Sep 14, 2026
  2. Ingwannu commented on Sep 14, 2026

    @Ingwannu
    Owner

    Confirmed against current dev (4f788f916ed08f629303f5e5608b275f56e59f77). The Chat translator added plaintext reasoning replay in src/chat/inbound.ts, but the synthesized Responses reasoning item has content and no summary. The local schema permits that optional field, while the OpenAI Responses backend used by Astra requires it, so the follow-up tool turn can pass local validation and fail upstream with the reported 400.

    I am preparing a narrow fix and regression test. The fix will add summary: [] to synthesized raw-reasoning items rather than copy private reasoning_content into a visible summary. That matches the existing envelope-only reasoning contract: preserve continuity in content, satisfy the required wire shape, and avoid reclassifying raw chain-of-thought as a user-visible reasoning summary. I will link the exact-head PR and test evidence here before closing this issue.

  3. Ingwannu commented on Sep 14, 2026

    @Ingwannu
    Owner

    Fix PR opened: #4629 (f48e58290e2716dda307798ec590d9b4bb671203).

    The focused reasoning replay suite passes 11/11, typecheck/structure/privacy checks pass, and the broader Chat endpoint suite passes 121 tests. Its one remaining surrogate byte-accounting failure reproduces unchanged on clean origin/dev, so it is not caused by this patch. Hosted exact-head CI and @lidge-jun review are now pending. I am leaving the issue open until the fix is merged.

  4. lidge-jun commented on Sep 14, 2026

    @lidge-jun
    Owner

    리뷰 · 우선순위 74 / 80

    이 이슈는 Chat Completions 클라이언트가 reasoning + tools를 켠 채 gpt-6-astra(openai Responses 백엔드)로 치면, 첫 어시스턴트 턴(추론+tool call) 이후 tool result를 다시 넣을 때 OpenCodex가 히스토리를 Responses input으로 옮기면서 type: "reasoning" 항목에 필수 summary를 빼 먹어 upstream 400 missing_required_parameter / input[N].summary가 난다는 보고다. 새 대화에서도 tool 한 바퀴만 돌면 재현되므로 “끼어 있는 클라이언트 트랜스크립트” 문제가 아니다.

    현재 dev HEAD 00f1762d0(2.56.0)의 src/chat/inbound.ts chatCompletionsToResponsesBody assistant 분기는 여전히 다음 형태다.

    input.push({ type: "reasoning", content: [{ type: "reasoning_text", text: reasoningText }] });

    summary 키가 없다. 같은 저장소의 Claude inbound(src/claude/inbound.ts)는 thinking을 넣을 때 summary: [{ type: "summary_text", text }] 또는 summary: []를 항상 붙이고, src/bridge.ts와 여러 Responses repair 경로도 reasoning 아이템에 summary: []를 기본으로 둔다. 로컬 Zod 스키마(src/responses/schema.ts의 summary 파트)는 optional에 가깝게 허용하지만, Astra가 쓰는 OpenAI Responses 백엔드는 wire에서 required라서 “로컬 통과 → upstream 400” 구멍이 난다. Ingwannu가 dev 4f788f916 기준으로 동일하게 확인했고, 수정 PR #4629(fix(chat): include summary on replayed reasoning items, head f48e58290)가 이미 열려 있다.

    #4629의 방향(이슈 스레드 기준)은 raw reasoning_content를 사용자에게 보이는 summary로 복사하지 않고, 합성 reasoning 아이템에 summary: []만 넣어 envelope/continuity는 content에 두고 wire shape만 맞추는 것이다. 보고자가 제안한 summary: [{ type: "summary_text", text: reasoningText }]보다 개인 체인오브쏘트를 노출하지 않아서 계약상 더 안전하다. 파일 범위도 src/chat/inbound.ts + structure/data-planes/inbound-compat.md + tests/responses/chat-inbound-reasoning-replay.test.ts로 좁다.

    우선순위 74인 이유: tool loop가 두 번째 턴에서 하드 페일하므로 Chat Completions × reasoning 모델 사용자에게 즉시 막는 버그다. #4546 cost-guard와 무관한 독립 데이터면 수정이고, 픽스 PR이 이미 있어 “설계 토론”보다 “착륙 검증” 단계다. 80을 안 준 이유는 epic 블로커가 아니고, #4629 CI/리뷰만 남았기 때문이다. types/config 분할에 무효화될 PR도 아니다.

    라인 316 - src/chat/inbound.ts에서 reasoning push에 summary 없음. Astra 400의 직접 원인으로 이슈·멘테이너 확인과 일치한다.
    경로/src/claude/inbound.ts - 이미 summary를 항상 넣어 Chat 경로와 비대칭이다. 수정 후에도 두 inbound가 “빈 summary 배열 vs summary_text 복사” 정책이 다르면 주석으로 이유를 남겨야 한다.
    경로/src/responses/schema.ts - 로컬 스키마가 느슨하면 회귀가 upstream에서만 터진다. 유닛 테스트가 wire shape를 고정해야 한다(#4629가 replay 스위트에 추가).
    경로/src/bridge.ts·repair - 다른 경로는 summary: [] 관례가 있어 Chat inbound만 구멍이었다는 증거가 된다.
    이슈 제안 한 줄 - private reasoning을 summary_text로 넣는 안은 Continuity에는 편하지만 가시 summary 계약과 충돌한다. #4629의 summary: []가 더 맞다.

    메인테이너의 판단이 필요한 지점

    • #4629를 summary: []로 확정할지, 보고자안처럼 plaintext를 summary_text에 넣을지(권장: 빈 배열 유지)
    • Chat inbound만 고칠지, 스키마/컨포먼스에서 reasoning.summary required를 더 엄격히 할지
    • fix(chat): include summary on replayed reasoning items #4629 merge 후 이 이슈를 바로 close할지(스레드상 멘테이너가 merge까지 open 유지 의사 표명)

    너의 추천

    • #4629를 exact-head CI와 포커스 reasoning replay 스위트 기준으로 리뷰·merge한다. summary: [] 방향 유지. 이 이슈([Bug]: Chat Completions translator omits reasoning.summary; gpt-6-astra 400s after tool turns #4628)는 중복 close 대상이 아니라 픽스 트래커로 열어 두고, #4629에 Fixes #4628이 있으면 merge 시 자동 종료, 없으면 merge 직후 멘테이너가 닫으면 된다. 지금은 코드가 아직 dev에 없으므로 이슈를 닫지 않는다.

    이 댓글은 grok-bot이 작성했습니다

  5. Ingwannu commented on Sep 15, 2026

    @Ingwannu
    Owner

    Fixed on dev by merged PR #4673, commit 369be813c4c8bcfd9d99d000085f7f6baf97e4c5. The merged implementation covers both the reported Chat translation path and a final adapter repair for any remaining summary-less reasoning item. Closing as fixed in the integration branch; users on 2.55.0 still need the next release containing this commit.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingproxyHTTP proxy, routing, reverse-proxy / management authtoolstool_calls, MCP, web-search / sidecar tools

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions