fix(codex): keep omitted-final source replies from releasing the turn#107388
fix(codex): keep omitted-final source replies from releasing the turn#107388mrfandu1 wants to merge 1 commit into
Conversation
There was a problem hiding this comment.
Pull request overview
This PR adjusts the Codex extension’s app-server dynamic-tool bridge so that, in message_tool_only delivery mode, inferred source-reply message deliveries only release the turn when the model explicitly sets final: true (rather than treating omitted final as terminal), and updates the schema guidance plus tests to match.
Changes:
- Clarify the Codex-only
message.finalparameter description to state that omittingfinal(or setting it false) is for progress updates and should not end the turn. - Update
createCodexDynamicToolBridgeturn-release inference so delivered/receipt-confirmed source replies only terminate on explicitfinal === true. - Update dynamic-tool bridge tests to cover omitted-final non-terminal behavior and explicit-final terminal behavior.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| extensions/codex/src/app-server/message-tool-final-control.ts | Updates the final parameter description to align model guidance with the intended continuation semantics. |
| extensions/codex/src/app-server/dynamic-tools.ts | Changes inferred termination for delivered source replies to require explicit final: true while preserving delivery markers/telemetry. |
| extensions/codex/src/app-server/dynamic-tools.test.ts | Updates expectations and adds coverage for omitted-final vs explicit-final terminal behavior. |
9006f6f to
f299e64
Compare
|
Codex review: needs real behavior proof before merge. Reviewed July 15, 2026, 12:03 AM ET / 04:03 UTC. Summary PR surface: Source -5, Tests +8. Total +3 across 3 files. Reproducibility: yes. at source level: current terminal classification releases a Review metrics: 1 noteworthy metric.
Root-cause cluster Members:
Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything. Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Rank-up moves:
Proof guidance:
Mantis proof suggestion Risk before merge
Maintainer options:
Next step before merge
Maintainer decision needed
Security Review detailsBest possible solution: Keep this PR open until a linked canonical PR proves it covers this PR's unique work, or a maintainer confirms closure. Do we have a high-confidence way to reproduce the issue? Yes at source level: current terminal classification releases a Is this the best way to solve the issue? Yes, provisionally: changing the Codex bridge's inferred terminal classification and schema guidance is narrower and safer than adding config or a parallel message tool, and preserving the completed marker improves on the competing PR; live exactly-once proof is still required. AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against 3eb8b3a0f838. Label changesLabel justifications:
Evidence reviewedPR surface: Source -5, Tests +8. Total +3 across 3 files. View PR surface stats
What I checked:
Likely related people:
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. How this review workflow works
Review history (5 earlier review cycles)
|
f299e64 to
e91e2f3
Compare
…inating turn Delivered and receipt-confirmed source replies in message_tool_only mode no longer set terminate=true on the dynamic tool response, matching the generic embedded-runner behavior established by PR openclaw#92343. - Remove deliveredSourceReply/receiptConfirmedSourceReply from withDynamicToolTermination conditions - Only final=true + actual source reply explicitly terminates - toolConfirmedSourceReply (tool-returned terminate:true) still terminates unless overridden by final=false - sourceReplyFinal telemetry: still true when final omitted (preserves completed marker for stranded-reply recovery) - Model-facing final guidance updated to explain progress semantics (incorporated from openclaw#107388) Related to openclaw#106961
…inating turn Delivered and receipt-confirmed source replies in message_tool_only mode no longer set terminate=true on the dynamic tool response, matching the generic embedded-runner behavior established by PR openclaw#92343. - Remove deliveredSourceReply/receiptConfirmedSourceReply from withDynamicToolTermination conditions - Only final=true + actual source reply explicitly terminates - toolConfirmedSourceReply (tool-returned terminate:true) still terminates unless overridden by final=false - sourceReplyFinal telemetry: still true when final omitted (preserves completed marker for stranded-reply recovery) - Model-facing final guidance updated to explain progress semantics (incorporated from openclaw#107388) Related to openclaw#106961
6b078d2 to
2c256aa
Compare
Live Telegram evidenceEnvironment: real Telegram DM to the test bot, OpenClaw Codex app-server backed by OpenAI Controlled fixture used identically for before/after: the workspace instructions required the intermediate progress The channel transcript and runtime excerpts below are redacted: they expose no token, phone number, personal username, chat/user ID, real name, or absolute home/workspace path. Before (main @
|
|
@clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. Re-review progress:
|
|
Thanks @mrfandu1 for the careful contribution and especially the live Telegram before/after and recovery evidence. Your PR correctly identified that an omitted We landed the maintainer replacement at #108487. The remaining gap was finality settlement: simply continuing the turn while treating the delivered reply as already complete could suppress recovery after a later failure. The landed fix carries omitted finality to the authoritative turn outcome, promotes only the latest omitted reply on success, and leaves it non-final on failure. Closing this as superseded by the merged root-cause fix. Thank you—your investigation and proof materially helped validate the direction. |
Closes #106961
What Problem This Solves
In
message_tool_onlydelivery mode, the Codex app-server treated any deliveredmessagesource reply as terminal unless the model explicitly passedfinal: false. An agent that sent an early progress update ("on it, will report back") had its turn released immediately: the remaining tool calls and the real final reply never ran. From the user's side the agent posts one status line and then goes silent (log signal:codex app-server turn released after terminal dynamic tool result).Why This Change Was Made
The projected
finalschema control tells the model to "set true only when this message is intended to complete the reply" - so models naturally omitfinalon progress sends, and the runtime contradicted its own schema by terminating anyway.This change makes inferred source-reply delivery release the turn only on explicit
final: true, matching the generic embedded-runner contract established in #92343: intermediate delivery continues the turn, and termination follows the normal Codexturn/completedlifecycle.Safety properties preserved:
sourceReplyFinalcompleted marker for omittedfinalis unchanged, so stranded-reply recovery still cannot re-deliver a duplicate of a delivered reply.didDeliverSourceReplyViaMessageToolis unchanged.terminateresults and yield results still release as before.resolveTerminalDynamicToolBatchAction) are untouched.The
finalschema description now also tells models that omitting it keeps the turn alive, so the control is learnable instead of discipline-based.User Impact
Codex-backed agents on Discord/Telegram/etc. can post intermediate progress messages and keep executing until the work is done. Explicit
final: truestill stops the turn after confirmed delivery.Evidence
extensions/codex/src/app-server/dynamic-tools.test.ts: 99/99 pass. Omitted-final delivered replies are now non-terminal with a completed marker; explicitfinal: truestill releases across implicit sends, explicit source routes, receipt-confirmed replies, and middleware-redacted receipts.extensions/codex/src/app-server/dynamic-tool-build.test.ts+dynamic-tool-execution.test.ts: 74/74 pass.pnpm tsgo:extensionsclean,oxfmt --checkclean on changed files.checks-ui(chat-tool-cards.test.tsMCP App preview test, unrelated to this change) andchecks-fast-bundled-protocolon a base 106 commits behind main; branch has since been rebased onto currentmain(no upstream changes to the touched files).AI-assisted: implemented and validated with an AI coding agent; I have reviewed and understand the change.