Skip to content

fix(openai): drop encrypted reasoning from history for Responses-family APIs (fixes #90093)#92857

Closed
liuhao1024 wants to merge 1 commit into
openclaw:mainfrom
liuhao1024:fix/chatgpt-responses-drop-encrypted-reasoning
Closed

fix(openai): drop encrypted reasoning from history for Responses-family APIs (fixes #90093)#92857
liuhao1024 wants to merge 1 commit into
openclaw:mainfrom
liuhao1024:fix/chatgpt-responses-drop-encrypted-reasoning

Conversation

@liuhao1024

Copy link
Copy Markdown
Contributor

Summary

Responses-family APIs (openai-chatgpt-responses, openai-responses, azure-openai-responses) request encrypted reasoning content via include: ["reasoning.encrypted_content"]. When replaying prior assistant turns, the encrypted thinkingSignature is sent back to the ChatGPT/Codex backend, which rejects it with 400 invalid_encrypted_content because it cannot verify stale encrypted content from a previous session.

Set dropReasoningFromHistory: true for all Responses-family APIs so reasoning blocks are stripped before replay, matching the existing behavior for openai-completions.

Root cause

buildOpenAIReplayPolicy in extensions/openai/replay-policy.ts did not set dropReasoningFromHistory for Responses-family APIs. The core fallback in src/agents/transcript-policy.ts:130 only sets it for openai-completions. This left openai-chatgpt-responses sessions replaying stale encrypted reasoning that the backend can no longer decrypt.

Fix

One line in extensions/openai/replay-policy.ts: add dropReasoningFromHistory: true for Responses-family APIs alongside the existing allowSyntheticToolResults: true.

Test

Updated the existing buildReplayPolicy test expectation in openai-provider.test.ts to include the new field.

Real behavior proof

  • Behavior addressed: openai-chatgpt-responses replaying encrypted reasoning causes 400 invalid_encrypted_content on subsequent turns
  • Environment tested: macOS 26.4.1 arm64, Node 25.9.0, OpenClaw main (4c0899c)
  • Steps run after the patch:
    1. Ran node scripts/run-vitest.mjs run extensions/openai/openai-provider.test.ts
    2. Ran pnpm build
    3. Verified the replay policy returns dropReasoningFromHistory: true for openai-chatgpt-responses
  • Evidence after fix:
$ node scripts/run-vitest.mjs run extensions/openai/openai-provider.test.ts
✓ extension-provider-openai (38 tests) 371ms
Test Files  1 passed (1)
     Tests  38 passed (38)

$ grep -n "dropReasoningFromHistory" extensions/openai/replay-policy.ts
24:    ...(isResponsesFamily ? { dropReasoningFromHistory: true } : {}),

$ node -e "const {buildOpenAIReplayPolicy}=require('./dist/extensions/openai/replay-policy.js'); const p=buildOpenAIReplayPolicy({modelApi:'openai-chatgpt-responses',modelId:'gpt-5.5'}); console.log('dropReasoningFromHistory:', p.dropReasoningFromHistory);"
dropReasoningFromHistory: true
  • Observed result after fix: The replay policy now returns dropReasoningFromHistory: true for all Responses-family APIs. openai-chatgpt-responses sessions will strip reasoning blocks before replay, preventing the 400 invalid_encrypted_content error.
  • What was not tested: Live ChatGPT/Codex backend roundtrip (requires ChatGPT subscription and native runtime). The fix follows the exact mitigation the issue reporter confirmed works locally.

…ly APIs

openai-chatgpt-responses (and other Responses-family APIs) request
encrypted reasoning content via include: ["reasoning.encrypted_content"].
When replaying prior assistant turns, the encrypted thinkingSignature
is sent back to the ChatGPT/Codex backend, which rejects it with
400 invalid_encrypted_content because it cannot verify stale encrypted
content from a previous session.

Set dropReasoningFromHistory: true for all Responses-family APIs so
reasoning blocks are stripped before replay, matching the existing
behavior for openai-completions.

Fixes openclaw#90093
@openclaw-barnacle openclaw-barnacle Bot added extensions: openai size: XS proof: supplied External PR includes structured after-fix real behavior proof. labels Jun 14, 2026
@clawsweeper

clawsweeper Bot commented Jun 14, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs real behavior proof before merge. Reviewed June 13, 2026, 11:52 PM ET / 03:52 UTC.

Summary
The PR adds dropReasoningFromHistory: true to the OpenAI provider replay policy for Responses-family APIs and updates one provider-policy test expectation.

PR surface: Source +1, Tests +1. Total +2 across 2 files.

Reproducibility: yes. at source level with linked live reports: current main can persist and replay encrypted Responses reasoning, and the linked issue shows released multi-turn sessions failing with invalid_encrypted_content. I did not run a live ChatGPT/OpenAI backend round trip in this read-only review.

Review metrics: 1 noteworthy metric.

  • Responses replay routes affected: 3 existing API routes. The new replay-policy flag applies to openai-responses, openai-chatgpt-responses, and azure-openai-responses, so maintainers need to review the compatibility impact before merge.

Merge readiness
Overall: 🧂 unranked krab
Proof: 🦪 silver shellfish
Patch quality: 🧂 unranked krab
Result: blocked until stronger real behavior proof is added.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • Narrow the replay-policy change to the affected native ChatGPT/Codex route or provide route-by-route proof for the broader policy.
  • [P1] Add proof from a redacted two-turn provider run or captured sanitized replay payload after the patch.
  • [P1] Keep or add regression coverage showing compatible openai-responses and Azure replay behavior is preserved.

Proof guidance:

  • [P1] Needs stronger real behavior proof before merge: The PR body shows terminal output for a focused test/build-policy check, but it does not show an after-fix real multi-turn provider run or captured replay payload proving the reported runtime failure is fixed. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.

Risk before merge

  • [P1] Merging as-is can silently drop prior assistant reasoning for openai-responses and azure-openai-responses, not only the reported native openai-chatgpt-responses failure.
  • [P1] The PR does not prove that all Responses-compatible or Azure routes should lose encrypted reasoning replay; upstream Codex still sends encrypted reasoning content with store:false while omitting item ids.
  • [P1] The supplied proof shows the policy flag value, but not a real multi-turn provider run or sanitized replay payload that demonstrates the user-visible failure is fixed.

Maintainer options:

  1. Narrow The Replay Policy (recommended)
    Change the patch so only the native ChatGPT/Codex route drops unverifiable encrypted replay, while preserving existing openai-responses and Azure-compatible reasoning replay behavior.
  2. Accept A Broad Provider Policy
    Maintainers can intentionally drop reasoning for all OpenAI Responses-family APIs, but that needs explicit owner approval and live or dependency-backed evidence for each affected route.
  3. Pause For Canonical Fix Coordination
    If the broader linked issue cluster is being consolidated elsewhere, pause this PR until maintainers choose the canonical replay/redaction fix path.
Copy recommended automerge instruction
@clawsweeper automerge

Special instructions:
Narrow `dropReasoningFromHistory` so it does not blanket-apply to `openai-responses` and `azure-openai-responses`; add focused regression coverage for the native `openai-chatgpt-responses` route and for preserved compatible Responses replay.

Next step before merge

  • [P1] A narrow automated repair can remove the blanket Responses-family policy and preserve unaffected replay behavior while retaining a focused native-route fix.

Security
Cleared: The diff only changes provider replay-policy behavior and one test expectation; I found no new dependency, workflow, secret-handling, permission, or code-execution concern.

Review findings

  • [P1] Narrow reasoning stripping to the affected route — extensions/openai/replay-policy.ts:24
Review details

Best possible solution:

Narrow the fix to the native ChatGPT/Codex encrypted-replay failure path, or add explicit maintainer-backed proof that every OpenAI Responses-family route must drop reasoning history.

Do we have a high-confidence way to reproduce the issue?

Yes, at source level with linked live reports: current main can persist and replay encrypted Responses reasoning, and the linked issue shows released multi-turn sessions failing with invalid_encrypted_content. I did not run a live ChatGPT/OpenAI backend round trip in this read-only review.

Is this the best way to solve the issue?

No. The plugin-owned replay-policy hook is a plausible location, but applying dropReasoningFromHistory to the whole Responses family is broader than the reported native ChatGPT/Codex failure and the checked Codex contract supports preserving encrypted replay content in some store-disabled flows.

Full review comments:

  • [P1] Narrow reasoning stripping to the affected route — extensions/openai/replay-policy.ts:24
    This applies dropReasoningFromHistory to all three Responses-family APIs. That makes openai-responses and azure-openai-responses lose prior reasoning blocks even though the linked bug is about native ChatGPT/Codex replay, and upstream Codex still sends encrypted reasoning content in store-disabled Responses requests while omitting item ids. Please narrow this to the affected native route or add explicit proof that every affected Responses route must drop reasoning history.
    Confidence: 0.84

Overall correctness: patch is incorrect
Overall confidence: 0.86

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against 889bc52ba5b3.

Label changes

Label changes:

  • add P1: The PR targets a released multi-turn OpenAI/Codex Responses workflow that can fail before producing a user-visible assistant turn.
  • add merge-risk: 🚨 compatibility: Blanket reasoning-history stripping can change existing openai-responses and Azure Responses replay behavior beyond the reported ChatGPT/Codex route.
  • add merge-risk: 🚨 session-state: The diff can remove prior assistant reasoning blocks from multi-turn session history, affecting context continuity.
  • add merge-risk: 🚨 auth-provider: The changed replay policy is owned by the OpenAI provider plugin and affects OpenAI/ChatGPT/Azure Responses routing behavior.
  • add rating: 🧂 unranked krab: Overall readiness is 🧂 unranked krab; proof is 🦪 silver shellfish and patch quality is 🧂 unranked krab.
  • add status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Needs stronger real behavior proof before merge: The PR body shows terminal output for a focused test/build-policy check, but it does not show an after-fix real multi-turn provider run or captured replay payload proving the reported runtime failure is fixed. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.

Label justifications:

  • P1: The PR targets a released multi-turn OpenAI/Codex Responses workflow that can fail before producing a user-visible assistant turn.
  • merge-risk: 🚨 compatibility: Blanket reasoning-history stripping can change existing openai-responses and Azure Responses replay behavior beyond the reported ChatGPT/Codex route.
  • merge-risk: 🚨 session-state: The diff can remove prior assistant reasoning blocks from multi-turn session history, affecting context continuity.
  • merge-risk: 🚨 auth-provider: The changed replay policy is owned by the OpenAI provider plugin and affects OpenAI/ChatGPT/Azure Responses routing behavior.
  • rating: 🧂 unranked krab: Overall readiness is 🧂 unranked krab; proof is 🦪 silver shellfish and patch quality is 🧂 unranked krab.
  • status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Needs stronger real behavior proof before merge: The PR body shows terminal output for a focused test/build-policy check, but it does not show an after-fix real multi-turn provider run or captured replay payload proving the reported runtime failure is fixed. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.
Evidence reviewed

PR surface:

Source +1, Tests +1. Total +2 across 2 files.

View PR surface stats
Area Files Added Removed Net
Source 1 1 0 +1
Tests 1 1 0 +1
Docs 0 0 0 0
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 2 2 0 +2

Acceptance criteria:

  • [P1] node scripts/run-vitest.mjs run extensions/openai/openai-provider.test.ts.
  • [P1] node scripts/run-vitest.mjs run src/agents/embedded-agent-runner.sanitize-session-history.test.ts -t "reasoning".
  • [P1] node scripts/run-vitest.mjs run src/agents/openai-transport-stream.test.ts -t "encrypted reasoning".

What I checked:

  • Current OpenAI replay policy surface: Current main classifies openai-responses, openai-chatgpt-responses, and azure-openai-responses as the Responses family; the PR adds reasoning-history dropping to that whole branch. (extensions/openai/replay-policy.ts:7, 889bc52ba5b3)
  • Reasoning drop removes thinking blocks from replay history: sanitizeSessionHistory applies policy.dropReasoningFromHistory, and that helper removes assistant thinking blocks from prior history except the current tool turn, so this is a broad session-replay behavior change rather than only an encrypted-content field scrub. (src/agents/embedded-agent-runner/replay-history.ts:737, 889bc52ba5b3)
  • OpenAI Responses replay currently preserves reasoning items: The Responses converter rebuilds assistant reasoning replay from thinkingSignature; current native ChatGPT/Codex request construction asks for reasoning.encrypted_content with store: false and disables item-id replay separately. (src/llm/providers/openai-chatgpt-responses.ts:482, 889bc52ba5b3)
  • Codex dependency contract checked: Upstream Codex builds non-Azure Responses requests with store: false and include: ["reasoning.encrypted_content"], and its ResponseItem::Reasoning skips serializing id while still serializing encrypted_content. (../codex/codex-rs/core/src/client.rs:734, 51316ead4a43)
  • Related issue and PR context: The linked issue includes live release reports for invalid_encrypted_content, a retracted id-preservation PR, and an open broader PR that is currently conflicting and has blocking review findings, so none of the related PRs is a clean superseding landing path.
  • History and ownership pass: Recent merged Responses replay work came through PRs 84904 and 85277, and OpenAI provider identity/replay policy work came through PR 88451; local blame is shallow/grafted, so PR metadata is the stronger provenance source. (extensions/openai/replay-policy.ts:16, 889bc52ba5b3)

Likely related people:

  • steipete: Authored the OpenAI provider identity refactor and several follow-up commits in the Responses replay path that this PR changes. (role: recent area contributor; confidence: high; commits: 4c33aaa86c16, ad856b70ef21, df3e7f3e2e11; files: extensions/openai/replay-policy.ts, src/llm/providers/openai-chatgpt-responses.ts, src/llm/providers/openai-responses-shared.ts)
  • zhanghang02: Authored the merged store-disabled Responses item-id replay fix that established the current no-id replay shape near this failure mode. (role: adjacent replay-policy contributor; confidence: high; commits: 03dec8bb3a00, 1598a62afb3e; files: src/agents/openai-transport-stream.ts, src/llm/providers/openai-chatgpt-responses.ts, src/llm/providers/openai-responses-shared.ts)
  • latensified: Authored a recent merged Responses message-id replay fix in the same shared conversion surface. (role: adjacent Responses replay contributor; confidence: medium; commits: 6653193fdb90, 5ac079ca520f; files: src/agents/openai-transport-stream.ts, src/llm/providers/openai-responses-shared.ts)
  • Vincent Koc: Local shallow blame attributes the current replay-policy extraction and sanitizer lines to the current main snapshot commit, but deeper provenance is obscured by the grafted checkout. (role: recent area contributor; confidence: low; commits: 97c5e6c2359a; files: extensions/openai/replay-policy.ts, src/agents/embedded-agent-runner/replay-history.ts, src/agents/transcript-policy.ts)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

How this review workflow works
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. labels Jun 14, 2026
@steipete

Copy link
Copy Markdown
Contributor

Closing as superseded by the narrower fix already merged in #90682 (66880a5d73). That change preserves opaque Responses reasoning fields during transcript redaction, fixing the corruption root cause tracked by #90093 without disabling reasoning replay globally.

This PR's blanket dropReasoningFromHistory policy affects openai-responses, openai-chatgpt-responses, and azure-openai-responses. That is broader than the reported native ChatGPT/Codex failure and would remove valid official OpenAI/Azure reasoning context. Current main also retains the bounded transport retry that strips encrypted content only after an actual invalid_encrypted_content rejection.

Thanks for isolating the replay-policy surface and adding focused coverage; the final fix belongs at the opaque transcript-field boundary instead.

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

Labels

extensions: openai proof: supplied External PR includes structured after-fix real behavior proof. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. size: XS status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants