fix(agents): recover invalid OpenAI Responses reasoning replay#84267
fix(agents): recover invalid OpenAI Responses reasoning replay#84267tianxiaochannel-oss88 wants to merge 5 commits into
Conversation
|
Codex review: needs maintainer review before merge. Workflow note: Future ClawSweeper reviews update this same comment in place. How this review workflow works
Summary Reproducibility: yes. at source level: current main preserves same-model replayable Responses reasoning and turns a pre-start provider rejection into an assistant error event with no retry. I did not run live OpenAI or Slack in this read-only review. PR rating Rank-up moves:
What the crustacean ranks mean
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. Real behavior proof Risk before merge
Maintainer options:
Next step before merge Security Review detailsBest possible solution: Land the focused Responses replay recovery after maintainers accept the transport-level proof or request live provider/channel evidence, while keeping Slack main/thread routing tracked separately in #84002. Do we have a high-confidence way to reproduce the issue? Yes at source level: current main preserves same-model replayable Responses reasoning and turns a pre-start provider rejection into an assistant error event with no retry. I did not run live OpenAI or Slack in this read-only review. Is this the best way to solve the issue? Yes: the PR uses a one-shot Responses stream wrapper, retries only before visible chunks, reuses the existing reasoning/tool-call downgrade helpers, and stays scoped to invalid replay state. Live provider or channel proof would reduce merge risk, but I did not find a better implementation path. Label changes:
Label justifications:
Acceptance criteria:
What I checked:
Likely related people:
Codex review notes: model gpt-5.5, reasoning high; reviewed against 94ac563399b3. |
|
@clawsweeper re-review Added committed transport-level proof in |
|
🦞🧹 I asked ClawSweeper to review this item again. Re-review progress:
|
|
@clawsweeper re-review Added committed real-HTTP transport proof in |
|
🦞🧹 I asked ClawSweeper to review this item again. Re-review progress:
|
|
ClawSweeper PR egg ✨ Hatched: 🌱 uncommon Brave Shellbean Hatch commandComment Hatchability rules:
Rarity: 🌱 uncommon. What is this egg doing here?
|
8481adf to
09f8de6
Compare
|
@clawsweeper re-review Rebased onto current The previous CI failure was from upstream |
|
🦞🧹 I asked ClawSweeper to review this item again. Re-review progress:
|
|
Cross-linking the Responses item-id coordination note from #85277: For this PR, the proposed final layering is that the retry still preserves visible assistant message content/phase, but after dropped/pruned reasoning it should not preserve a signed assistant Suggested merge order from the coordination pass: #84904 -> #85277 -> #84267 -> #85362. When rebasing with #85362, the clean combined shape should keep one exported |
|
Update from a fresh local validation on The latest release appears to improve the operational failure mode: after this class of Responses failure, the Slack lane no longer remains stuck in The remaining user-visible gap still reproduces, though: the turn terminates before producing a reply instead of rebuilding context and retrying the same user message. Sanitized signatures from the repro: So One local trigger that still makes this easy to reproduce is an OpenAI-compatible proxy with session affinity where a pinned auth can become temporarily unavailable and the proxy reselects auth. That can leave OpenClaw replaying encrypted reasoning / |
|
Superseded by #92941, landed as The landed fix handles Proof included 367 focused OpenAI/Anthropic regressions, six official provider tool-call tests, an official GPT-5.5 encrypted-reasoning replay, AWS Crabbox |
Fixes the OpenAI Responses half of #84002.
This intentionally does not change Slack main/thread session routing. The issue combines two continuation failures; this PR addresses the deterministic Responses replay failure where preserved encrypted reasoning can be rejected with
thinking_signature_invalid.Root cause
OpenAI Responses can reject a replayed encrypted reasoning item when the stored
rs_*content is no longer verifiable. Current history cleanup only drops replayable OpenAI reasoning when the model snapshot changes or when the reasoning block is orphaned, so a same-provider/same-model continuation can replay the stale encrypted reasoning again.That error was also classified as a generic schema/format rejection, so terminal failures surfaced as "provider rejected the request schema" instead of a replay-state recovery error.
What changed
thinking_signature_invalidand encrypted reasoning verification/decryption failures as replay-invalid.errorevent/result with invalid encrypted reasoning, drop replayable OpenAI reasoning blockscall|fctool call ids after dropping reasoningUser impact
A Slack or channel continuation that hits stale OpenAI Responses encrypted reasoning should get one clean retry instead of ending the turn with no visible assistant content. If the retry still fails, the user-facing error now points to invalid session/replay state instead of a generic schema rejection.
Real behavior proof
Behavior or issue addressed: OpenAI Responses continuation recovery for
thinking_signature_invalid/ invalid encrypted reasoning replay.Real environment tested: Local OpenClaw checkout on this PR branch at original proof head
edc7ccba2a0ab7a3f972362b5ee74753ff0fb302, then rebased/verified again at current PR head09f8de688fbfc88e49ac7dd3c27101a0b8a16142, on macOS with Nodev24.15.0. The committed proof harness uses the real OpenAI SDK HTTP transport and OpenClaw's currentcreateOpenAIResponsesTransportStreamFn()pluswrapOpenAIResponsesStreamWithReplayRecovery()against a loopback/v1/responsesendpoint. It does not mock the OpenAI SDK; the loopback endpoint returns provider-shaped HTTP 400 and SSE responses so reviewers can inspect the request/retry payload transition.Exact steps or command run after this patch:
Evidence after fix:
Observed result after fix: The first real SDK HTTP request contains replayed
reasoningand receives a provider-shapedthinking_signature_invalid400. The wrapper retries once. The second real SDK HTTP request drops replayedreasoning, preserves the replayed visiblemessage, consumes the SSE response, and returns assistant text withstopReason: stop.Committed inspectable proof:
scripts/proofs/openai-responses-replay-recovery.tsis the manual proof harness.src/agents/pi-embedded-runner/openai-responses-transport-replay-recovery.test.tsremains the regression test that locks in the mocked-SDK transport error-event path.What was not tested: Live Slack and live OpenAI Responses were not used. Slack session routing from #84002 is intentionally out of scope for this PR.
Exact steps or command run after this patch
Rebase refresh at current PR head
09f8de688fbfc88e49ac7dd3c27101a0b8a16142:Validation