WhatsApp: send commentary updates live#42489
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: f5efe4ade8
ℹ️ About Codex in GitHub
Your team has set up Codex to 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 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Greptile SummaryThis PR adds WhatsApp live commentary delivery for GPT-5.4's Key findings from review:
Confidence Score: 3/5
Last reviewed commit: f5efe4a |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c7fc5d726e
ℹ️ About Codex in GitHub
Your team has set up Codex to 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 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e76dbb1e9d
ℹ️ About Codex in GitHub
Your team has set up Codex to 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 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: f8a92b4143
ℹ️ About Codex in GitHub
Your team has set up Codex to 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 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
This reverts commit 669999a.
This reverts commit 0e97659517b7e3c99c75f08e9a94b8ac89694a26.
edb658f to
334398c
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 334398cff7
ℹ️ About Codex in GitHub
Your team has set up Codex to 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 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 37719ae8e8
ℹ️ About Codex in GitHub
Your team has set up Codex to 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 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ea49855566
ℹ️ About Codex in GitHub
Your team has set up Codex to 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 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| const errorContext = | ||
| messageRecord?.stopReason === "error" || | ||
| (typeof messageRecord?.errorMessage === "string" && | ||
| messageRecord.errorMessage.trim().length > 0); |
There was a problem hiding this comment.
Gate assistant error rewriting on stopReason only
extractAssistantOutputCandidates marks errorContext true whenever errorMessage is present, but non-error assistant turns can legitimately carry errorMessage metadata (see the existing guard in src/agents/pi-embedded-utils.ts:246-251). Because this commit now prefers assistantOutputs in final payload construction, normal replies that merely have background tool failures can be rewritten into generic error text, corrupting user-facing output.
Useful? React with 👍 / 👎.
| const normalizedStartIndex = | ||
| params.startIndex >= 0 && params.startIndex <= params.messages.length | ||
| ? params.startIndex | ||
| : resolveCompactedPromptBoundaryIndex(params.messages, params.historyBeforePrompt); |
There was a problem hiding this comment.
Rewind reconciliation cursor when boundary shifts in-range
The cursor is only rewound when startIndex is out of bounds, but compaction can shift the pre-prompt boundary left while keeping messages.length >= startIndex (for example, dropping old history while adding new turn messages). In that case reconciliation starts too far right and permanently skips finalized assistant messages between the shifted boundary and the stale cursor, which can drop terminal reply segments from assistantOutputs.
Useful? React with 👍 / 👎.
…t week (openclaw#43642) * Models: add temporary Hunter and Healer alpha to OpenRouter catalog * Add temporary OpenRouter stealth catalog entries --------- Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
|
Closing this PR because it looks dirty (too many unrelated or unexpected changes). This usually happens when a branch picks up unrelated commits or a merge went sideways. Please recreate the PR from a clean branch. |
|
Closing this PR because it looks dirty (too many unrelated or unexpected changes). This usually happens when a branch picks up unrelated commits or a merge went sideways. Please recreate the PR from a clean branch. |
24 similar comments
|
Closing this PR because it looks dirty (too many unrelated or unexpected changes). This usually happens when a branch picks up unrelated commits or a merge went sideways. Please recreate the PR from a clean branch. |
|
Closing this PR because it looks dirty (too many unrelated or unexpected changes). This usually happens when a branch picks up unrelated commits or a merge went sideways. Please recreate the PR from a clean branch. |
|
Closing this PR because it looks dirty (too many unrelated or unexpected changes). This usually happens when a branch picks up unrelated commits or a merge went sideways. Please recreate the PR from a clean branch. |
|
Closing this PR because it looks dirty (too many unrelated or unexpected changes). This usually happens when a branch picks up unrelated commits or a merge went sideways. Please recreate the PR from a clean branch. |
|
Closing this PR because it looks dirty (too many unrelated or unexpected changes). This usually happens when a branch picks up unrelated commits or a merge went sideways. Please recreate the PR from a clean branch. |
|
Closing this PR because it looks dirty (too many unrelated or unexpected changes). This usually happens when a branch picks up unrelated commits or a merge went sideways. Please recreate the PR from a clean branch. |
|
Closing this PR because it looks dirty (too many unrelated or unexpected changes). This usually happens when a branch picks up unrelated commits or a merge went sideways. Please recreate the PR from a clean branch. |
|
Closing this PR because it looks dirty (too many unrelated or unexpected changes). This usually happens when a branch picks up unrelated commits or a merge went sideways. Please recreate the PR from a clean branch. |
|
Closing this PR because it looks dirty (too many unrelated or unexpected changes). This usually happens when a branch picks up unrelated commits or a merge went sideways. Please recreate the PR from a clean branch. |
|
Closing this PR because it looks dirty (too many unrelated or unexpected changes). This usually happens when a branch picks up unrelated commits or a merge went sideways. Please recreate the PR from a clean branch. |
|
Closing this PR because it looks dirty (too many unrelated or unexpected changes). This usually happens when a branch picks up unrelated commits or a merge went sideways. Please recreate the PR from a clean branch. |
|
Closing this PR because it looks dirty (too many unrelated or unexpected changes). This usually happens when a branch picks up unrelated commits or a merge went sideways. Please recreate the PR from a clean branch. |
|
Closing this PR because it looks dirty (too many unrelated or unexpected changes). This usually happens when a branch picks up unrelated commits or a merge went sideways. Please recreate the PR from a clean branch. |
|
Closing this PR because it looks dirty (too many unrelated or unexpected changes). This usually happens when a branch picks up unrelated commits or a merge went sideways. Please recreate the PR from a clean branch. |
|
Closing this PR because it looks dirty (too many unrelated or unexpected changes). This usually happens when a branch picks up unrelated commits or a merge went sideways. Please recreate the PR from a clean branch. |
|
Closing this PR because it looks dirty (too many unrelated or unexpected changes). This usually happens when a branch picks up unrelated commits or a merge went sideways. Please recreate the PR from a clean branch. |
|
Closing this PR because it looks dirty (too many unrelated or unexpected changes). This usually happens when a branch picks up unrelated commits or a merge went sideways. Please recreate the PR from a clean branch. |
|
Closing this PR because it looks dirty (too many unrelated or unexpected changes). This usually happens when a branch picks up unrelated commits or a merge went sideways. Please recreate the PR from a clean branch. |
|
Closing this PR because it looks dirty (too many unrelated or unexpected changes). This usually happens when a branch picks up unrelated commits or a merge went sideways. Please recreate the PR from a clean branch. |
|
Closing this PR because it looks dirty (too many unrelated or unexpected changes). This usually happens when a branch picks up unrelated commits or a merge went sideways. Please recreate the PR from a clean branch. |
|
Closing this PR because it looks dirty (too many unrelated or unexpected changes). This usually happens when a branch picks up unrelated commits or a merge went sideways. Please recreate the PR from a clean branch. |
|
Closing this PR because it looks dirty (too many unrelated or unexpected changes). This usually happens when a branch picks up unrelated commits or a merge went sideways. Please recreate the PR from a clean branch. |
|
Closing this PR because it looks dirty (too many unrelated or unexpected changes). This usually happens when a branch picks up unrelated commits or a merge went sideways. Please recreate the PR from a clean branch. |
|
Closing this PR because it looks dirty (too many unrelated or unexpected changes). This usually happens when a branch picks up unrelated commits or a merge went sideways. Please recreate the PR from a clean branch. |
|
Replacement PR opened from a clean branch rebased on current This branch contains the same WhatsApp live-commentary / assistant-output reconciliation work without the stale branch ancestry that triggered the dirty close. |
Summary
commentarytext was discovered during the run but usually arrived only after completion, bundled with the final reply. In practice users got the commentary messages dumped at the end instead of seeing progress live.commentary.phaseparameter guidance in the latest-model docs: usephase: "commentary"for interim updates andphase: "final_answer"for the terminal reply.phase/ signature metadata so commentary and final-answer segments can be identified reliably.onCommentaryReplythrough the embedded runner and finalized-message fallback.reply-delivery.tsso directive normalization, silent suppression, and commentary/final bookkeeping are reusable instead of being inlined in the WhatsApp monitor.assistantOutputsbecome empty, and websocket delta metadata that preservesphase/ signature identity beforeresponse.completed.cced1e0f7694f8e1c98086370612f5a41e811230(Preserve Responses API phase param, PR Preserve Responses APIphaseparam #43475). This PR builds on that samephasecontract and now also extracts the delivery-side plumbing into shared infrastructure while hardening the downstream reconciliation logic that consumes it.Change Type (select all)
Scope (select all touched areas)
Linked Issue/PR
phaseparameterphaseparam #43475openclaw/openclawafter targeted search for WhatsApp commentary / partial-reply / external-chat final-only behavior.User-visible / Behavior Changes
channels.whatsapp.commentaryDelivery = "off" | "live".commentaryDelivery: "live", provider-emitted assistantcommentarymessages are sent as separate WhatsApp messages during the run.[[reply_to_current]]are normalized before send and no longer leak into user-facing commentary messages.assistantTexts/fallbackAnswerTextwhen allassistantOutputswere stripped as already-delivered commentary, preventing commentary-only terminal payloads.Security Impact (required)
Yes/No) NoYes/No) NoYes/No) NoYes/No) NoYes/No) NoYes, explain risk + mitigation:Repro + Verification
Environment
pnpm openclaw gateway runopenai-codex/gpt-5.4channels.whatsapp.commentaryDelivery=liveSteps
channels.whatsapp.commentaryDelivery=live.Expected
Actual
embedded run done, together with the final reply.Evidence
Attach at least one:
Human Verification (required)
What you personally verified (not just CI), and how:
20:54:37,20:54:40, and20:56:40, while the run completed later at20:57:14.20:57:14.[[reply_to_current]]no longer leaked into commentary messages.errorMessagemetadata is present, and it still finds finalized output after both out-of-bounds and in-range compaction cursor shifts.streamMessageupdates do not send only the first partial fragment.assistantOutputsfall back toassistantTextsinstead of dropping the final answer.Review Conversations
If a bot review conversation is addressed by this PR, resolve that conversation yourself. Do not leave bot review conversation cleanup for maintainers.
Compatibility / Migration
Yes/No) YesYes/No) YesYes/No) NoFailure Recovery (if this breaks)
channels.whatsapp.commentaryDelivery=off.embedded run done, non-WhatsApp channels unexpectedly wiring commentary callbacks, or final replies missing after commentary was already delivered live.Risks and Mitigations
streamMessagegrowth.assistantTexts/fallbackAnswerTextif filtering emptiesassistantOutputs.onCommentaryReplyremains unwired there.