Skip to content

WhatsApp: send commentary live#57484

Closed
tristanmanchester wants to merge 1 commit into
openclaw:mainfrom
tristanmanchester:codex/whatsapp-commentary-pr-reset
Closed

WhatsApp: send commentary live#57484
tristanmanchester wants to merge 1 commit into
openclaw:mainfrom
tristanmanchester:codex/whatsapp-commentary-pr-reset

Conversation

@tristanmanchester

@tristanmanchester tristanmanchester commented Mar 30, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Problem: WhatsApp only returned commentary once the final answer arrived, so agent progress updates were held back until the end of the turn.
  • Why it matters: live commentary is useful on chat surfaces only if it is delivered during the run, while still keeping the final answer separate and preserving existing behavior for other channels.
  • What changed: added a channel-agnostic onCommentaryReply seam in the embedded runner/subscribe path, wired it only for WhatsApp behind channels.whatsapp.commentaryDelivery: "off" | "live", filtered already-delivered commentary out of the final payload assembly, and restored the lastAssistant fallback so timeout/abort paths keep partial visible text.
  • What did NOT change (scope boundary): this does not enable live commentary for Telegram, Slack, or any other channel, and it does not route commentary through generic block streaming.

Change Type (select all)

  • Bug fix
  • Feature
  • Refactor required for the fix
  • Docs
  • Security hardening
  • Chore/infra

Scope (select all touched areas)

  • Gateway / orchestration
  • Skills / tool execution
  • Auth / tokens
  • Memory / storage
  • Integrations
  • API / contracts
  • UI / DX
  • CI/CD / infra

Linked Issue/PR

Root Cause / Regression History (if applicable)

N/A

Regression Test Plan (if applicable)

  • Coverage level that should have caught this:
    • Unit test
    • Seam / integration test
    • End-to-end test
    • Existing coverage already sufficient
  • Target test or file:
    • src/agents/pi-embedded-subscribe.commentary.test.ts
    • src/agents/pi-embedded-runner/run/payloads.test.ts
    • src/agents/pi-embedded-runner.e2e.test.ts
    • extensions/whatsapp/src/auto-reply/deliver-reply.test.ts
  • Scenario the test should lock in: live commentary emits once per finalized commentary segment, already-delivered commentary is filtered from the final reply, partial commentary suffixes are preserved, timeout/abort paths still surface lastAssistant text, and WhatsApp delivery honors timeout/abort semantics.
  • Why this is the smallest reliable guardrail: the feature is implemented at the embedded subscribe/runner seam and only channel-wired in WhatsApp, so seam tests plus WhatsApp delivery tests cover the real behavior without requiring a full live gateway run.
  • Existing test that already covers this (if any): Telegram boundary coverage continues to assert that other channels remain unwired.
  • If no new test is added, why not: N/A

User-visible / Behavior Changes

  • New WhatsApp config: channels.whatsapp.commentaryDelivery: "off" | "live"
  • Default behavior stays final-only.
  • When set to "live", commentary is sent to the WhatsApp chat in real time and the final answer is still delivered separately.
  • Commentary already sent live is not repeated in the final reply.
  • Timeout/abort paths keep partial visible assistant text when snapshot text exists.

Diagram (if applicable)

Before:
[assistant commentary] -> [buffer until run end] -> [commentary + final answer delivered together]
[timeout before message_end] -> [empty payloads] -> [generic timeout message]

After:
[assistant commentary] -> [subscribe seam emits commentary] -> [WhatsApp sends live commentary]
[final answer] -> [final payload assembly filters delivered commentary] -> [final answer only]
[timeout before message_end] -> [lastAssistant snapshot text] -> [partial visible reply]

Security Impact (required)

  • New permissions/capabilities? (No)
  • Secrets/tokens handling changed? (No)
  • New/changed network calls? (No)
  • Command/tool execution surface changed? (No)
  • Data access scope changed? (No)
  • If any Yes, explain risk + mitigation: N/A

Repro + Verification

Environment

  • OS: macOS
  • Runtime/container: Node 24 / pnpm workspace
  • Model/provider: N/A
  • Integration/channel (if any): WhatsApp
  • Relevant config (redacted): channels.whatsapp.commentaryDelivery: "live"

Steps

  1. Enable channels.whatsapp.commentaryDelivery: "live" for the WhatsApp account/channel.
  2. Send a prompt that produces assistant commentary before the final answer.
  3. Observe the WhatsApp thread during the run and after completion.

Expected

  • Commentary appears in the chat as it is produced.
  • The final answer still arrives as a separate reply.
  • Commentary already delivered live is not appended again to the final reply.
  • Timeout/abort paths preserve visible snapshot text when available.

Actual

  • Matches expected behavior in manual WhatsApp validation.

Evidence

Attach at least one:

  • Failing test/log before + passing after
  • Trace/log snippets
  • Screenshot/recording
  • Perf numbers (if relevant)

Human Verification (required)

What you personally verified (not just CI), and how:

  • Verified scenarios:
    • targeted tests passed:
      • src/agents/pi-embedded-runner/run/payloads.test.ts
      • src/agents/pi-embedded-runner.e2e.test.ts
      • src/agents/pi-embedded-subscribe.commentary.test.ts
      • extensions/whatsapp/src/auto-reply/deliver-reply.test.ts
    • pnpm build completed successfully on this reset branch
    • lastAssistant fallback now survives the timeout/empty-finalized-output path
  • Edge cases checked:
    • delivered live commentary is filtered from final payloads
    • undelivered commentary suffixes stay in the final reply
    • timeout/abort paths fall back to lastAssistant snapshot text when finalized outputs are empty
  • What you did not verify:
    • I did not re-run a live WhatsApp chat on this exact reset branch; the end-to-end WhatsApp behavior was manually validated by the operator on the equivalent feature branch.
    • pnpm check currently fails on untouched current-main files outside this PR (src/commands/doctor-memory-search.ts, src/commands/doctor-memory-search.test.ts, extensions/memory-core/src/memory/search-manager.test.ts). This reset branch does not modify those files.
    • extensions/whatsapp/src/auto-reply/monitor/process-message.inbound-context.test.ts remains the known wrapper-hang lane in this workspace, so I am not claiming a clean wrapper completion for that file.

Review Conversations

  • I replied to or resolved every bot review conversation I addressed in this PR.
  • I left unresolved only the conversations that still need reviewer or maintainer judgment.

Compatibility / Migration

  • Backward compatible? (Yes)
  • Config/env changes? (Yes)
  • Migration needed? (No)
  • If yes, exact upgrade steps:
    • optional: set channels.whatsapp.commentaryDelivery to "live"

Risks and Mitigations

  • Risk: commentary and final payload reconciliation could double-send or drop text on unusual run-end timing.
    • Mitigation: run-scoped segment IDs, commentary queue versioning, delivered-commentary filtering, suffix preservation, and timeout/abort regression coverage.
  • Risk: commentary delivery can hang or abort mid-send.
    • Mitigation: bounded WhatsApp send/load timeouts, abort-aware delivery cleanup, and final payload fallback to undelivered suffixes / lastAssistant snapshot text.

@openclaw-barnacle openclaw-barnacle Bot added docs Improvements or additions to documentation channel: telegram Channel integration: telegram channel: whatsapp-web Channel integration: whatsapp-web agents Agent runtime and tooling size: XL labels Mar 30, 2026
@greptile-apps

greptile-apps Bot commented Mar 30, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR adds live commentary delivery for WhatsApp: when channels.whatsapp.commentaryDelivery: \"live\" is configured, assistant commentary segments are sent to the WhatsApp chat in real time while the final answer is still delivered separately at run end. All other channels are explicitly kept out of scope.

Key implementation pieces:

  • pi-embedded-commentary.ts (new): extracts typed AssistantOutputCandidate segments from agent messages, carrying stable segmentId, text, and phase (\"commentary\" | \"final_answer\").
  • pi-embedded-subscribe.ts: adds a commentary delivery queue (promise chain), abort/generation counters for compaction-retry safety, and exposes onCommentaryReply / abortCommentaryDelivery / waitForCommentaryDelivery seams.
  • pi-embedded-subscribe.handlers.messages.ts: triggers live delivery in handleMessageUpdate only for non-terminal commentary segments, and finalises them in handleMessageEnd.
  • payloads.ts: filters already-delivered commentary from the final payload assembly, with suffix-preservation and lastAssistant fallback for timeout/abort paths.
  • deliver-reply.ts: refactored to be abort- and timeout-aware; awaitWithAbort / sleepWithAbort helpers wrap all I/O to unpin callers from hung sends once the turn is aborting.
  • process-message.ts: wires onCommentaryReply only when commentaryDelivery === \"live\", reuses sendWhatsAppPayload for both commentary and final sends, and correctly returns didSendReply when only commentary was sent.
  • Config surface: channels.whatsapp.commentaryDelivery: \"off\" | \"live\" (default \"off\"), Zod schema, labels, and help text all updated.
  • Test coverage: pi-embedded-subscribe.commentary.test.ts (new, 623 lines), payloads.test.ts extensions, deliver-reply.test.ts abort/timeout cases, Telegram boundary assertion.

Confidence Score: 5/5

This PR is safe to merge; all observable findings are style/quality suggestions with no impact on correctness.

The implementation is thorough: generation counters guard compaction retries, abort propagation is cleanly threaded through every async boundary, delivered-segment tracking is consistent, and finally blocks prevent resource leaks. Test coverage is comprehensive. No P0 or P1 issues found.

No files require special attention, but reviewers may wish to re-read the queueCommentaryDelivery closure in pi-embedded-subscribe.ts to confirm generation-vs-abort ordering satisfies their mental model.

Reviews (1): Last reviewed commit: "WhatsApp: send commentary live" | Re-trigger Greptile

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9631183600

ℹ️ 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".

Comment on lines +277 to +282
if (filteredAssistantOutputs.length > 0) {
return filteredAssistantOutputs;
}
}
if (params.assistantTexts.length > 0) {
return params.assistantTexts;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Skip assistantTexts fallback after full live-commentary delivery

When assistantOutputs exists but all commentary segments are filtered out as already delivered live, this branch falls back to assistantTexts. In timeout/abort runs where the only finalized text is that same commentary, the final payload re-sends content that users already received live, so commentary is duplicated despite deliveredCommentarySegmentIds. This is triggered specifically when filteredAssistantOutputs becomes empty because of live-delivery filtering, so fallback should distinguish “no finalized outputs” from “outputs intentionally filtered.”

Useful? React with 👍 / 👎.

@tristanmanchester tristanmanchester deleted the codex/whatsapp-commentary-pr-reset branch April 14, 2026 15:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agents Agent runtime and tooling channel: telegram Channel integration: telegram channel: whatsapp-web Channel integration: whatsapp-web docs Improvements or additions to documentation size: XL

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant