Skip to content

Fix Control UI duplicate iMessage replies for internal webchat turns#36151

Merged
vincentkoc merged 9 commits intomainfrom
vincentkoc-code/fix-webchat-origin-routing-guard
Mar 6, 2026
Merged

Fix Control UI duplicate iMessage replies for internal webchat turns#36151
vincentkoc merged 9 commits intomainfrom
vincentkoc-code/fix-webchat-origin-routing-guard

Conversation

@vincentkoc
Copy link
Member

Summary

  • Problem: Control UI webchat turns were rerouting replies to OriginatingChannel and duplicating messages into iMessage.
  • Why it matters: Dashboard users were seeing every reply echoed to iMessage after upgrading to 2026.3.2+.
  • What changed: tightened routing guard in dispatchReplyFromConfig to keep true internal webchat turns on dispatcher delivery.
  • What did NOT change (scope boundary): preserved webchat-provider relay behavior when Surface carries a non-webchat external channel.

Change Type (select all)

  • Bug fix
  • Feature
  • Refactor
  • 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

User-visible / Behavior Changes

  • Control UI chat replies no longer duplicate to iMessage when the turn is internal webchat (provider=webchat, surface=webchat).
  • Existing routed relay flows (for example provider webchat with external surface metadata) still route to the originating external channel.

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:

Repro + Verification

Environment

  • OS: macOS
  • Runtime/container: Node.js + pnpm
  • Model/provider: n/a
  • Integration/channel (if any): Control UI webchat + iMessage
  • Relevant config (redacted): provider=webchat, surface=webchat, originatingChannel=imessage

Steps

  1. Send a message from Control UI webchat in a shared/main session with iMessage origin metadata present.
  2. Observe reply dispatch path.
  3. Repeat for relayed flow where provider is webchat but surface/origin is external.

Expected

  • Internal webchat turns stay in UI dispatcher path.
  • Relayed external surface turns still route externally.

Actual

  • Verified with targeted regression tests.

Evidence

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

pnpm test src/auto-reply/reply/dispatch-from-config.test.ts

Human Verification (required)

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

  • Verified scenarios: targeted routing behavior for internal webchat vs relayed external surface cases.
  • Edge cases checked: provider=webchat with Surface=telegram|feishu still routes; provider=webchat with Surface=webchat does not reroute externally.
  • What you did not verify: full end-to-end live iMessage run on hardware.

Compatibility / Migration

  • Backward compatible? (Yes)
  • Config/env changes? (No)
  • Migration needed? (No)
  • If yes, exact upgrade steps:

Failure Recovery (if this breaks)

  • How to disable/revert this change quickly: revert this PR commits.
  • Files/config to restore: src/auto-reply/reply/dispatch-from-config.ts
  • Known bad symptoms reviewers should watch for: relayed webchat-origin messages failing to route to their external channel.

Risks and Mitigations

  • Risk: Routing guard could suppress legitimate cross-provider relay sends.
    • Mitigation: explicit regression tests cover provider=webchat + external surface routing and provider-matches-origin no-route behavior.

@vincentkoc vincentkoc self-assigned this Mar 5, 2026
@openclaw-barnacle openclaw-barnacle bot added size: XS maintainer Maintainer-authored PR labels Mar 5, 2026
@vincentkoc vincentkoc marked this pull request as ready for review March 6, 2026 05:29
@greptile-apps
Copy link
Contributor

greptile-apps bot commented Mar 6, 2026

Greptile Summary

This PR fixes a regression introduced in 2026.3.2 where Control UI webchat replies were being erroneously duplicated into iMessage. The root cause was that dispatchReplyFromConfig would route to OriginatingChannel (e.g., iMessage) even when the current turn was a pure internal webchat turn (provider=webchat, surface=webchat), because the existing guard only checked that originatingChannel !== currentSurface without accounting for the fact that webchat surface metadata can have iMessage origin context from a shared session.

Key changes:

  • Introduces an isInternalWebchatTurn boolean that is true when both currentSurface and surfaceChannel resolve to INTERNAL_MESSAGE_CHANNEL ("webchat"), or when surfaceChannel is absent (indicating no relay metadata).
  • Gates shouldRouteToOriginating behind !isInternalWebchatTurn, so pure webchat turns stay on the local dispatcher delivery path.
  • Preserves the relay path for cases where Provider=webchat but Surface carries an external channel identifier (e.g., Surface=feishu), which is the legitimate cross-provider relay scenario.
  • Adds a targeted regression test covering provider=webchat, surface=webchat, originatingChannel=imessage to confirm routeReply is not invoked.

Confidence Score: 4/5

  • This PR is safe to merge — the routing guard is logically sound and well-tested, with a minor unverified attribution in the CHANGELOG.
  • The fix is minimal and focused: a two-condition boolean guard that correctly preserves the relay path for external surfaces while blocking erroneous rerouting for pure internal webchat turns. The new test directly covers the regression scenario, and existing tests confirm relay flows (feishu, telegram, provider-matches-origin) still behave correctly. The only flag is a potential @alicexmolt vs @vincentkoc attribution mismatch in the CHANGELOG, which is cosmetic and doesn't affect correctness.
  • CHANGELOG.md — verify the @alicexmolt attribution is intentional given the PR author is vincentkoc.

Comments Outside Diff (1)

  1. CHANGELOG.md, line 24 (link)

    Potential attribution mismatch

    The new CHANGELOG entry credits @alicexmolt, but the PR author is vincentkoc. The preceding entry (for the inline reply tags fix) correctly credits @vincentkoc. If @alicexmolt is not the actual contributor of this fix, this attribution should be corrected to avoid crediting the wrong person.

Last reviewed commit: 07498a7

Copy link

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

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: 07498a78e0

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

@openclaw-barnacle openclaw-barnacle bot added app: web-ui App: web-ui gateway Gateway runtime size: S and removed size: XS labels Mar 6, 2026
@vincentkoc vincentkoc merged commit 6c39616 into main Mar 6, 2026
31 of 32 checks passed
@vincentkoc vincentkoc deleted the vincentkoc-code/fix-webchat-origin-routing-guard branch March 6, 2026 05:48
thinstripe pushed a commit to thinstripe/openclaw that referenced this pull request Mar 6, 2026
…penclaw#36151)

* Auto-reply: avoid routing external replies from internal webchat turns

* Auto-reply tests: cover internal webchat non-routing with external origin metadata

* Changelog: add Control UI iMessage duplicate-reply fix note

* Auto-reply context: track explicit deliver routes

* Gateway chat: mark explicit external deliver routes in context

* Auto-reply: preserve explicit deliver routes for internal webchat turns

* Auto-reply tests: cover explicit deliver routes from internal webchat turns

* Gateway chat tests: assert explicit deliver route context tagging
handsdiff pushed a commit to handsdiff/activeclaw that referenced this pull request Mar 6, 2026
…penclaw#36151)

* Auto-reply: avoid routing external replies from internal webchat turns

* Auto-reply tests: cover internal webchat non-routing with external origin metadata

* Changelog: add Control UI iMessage duplicate-reply fix note

* Auto-reply context: track explicit deliver routes

* Gateway chat: mark explicit external deliver routes in context

* Auto-reply: preserve explicit deliver routes for internal webchat turns

* Auto-reply tests: cover explicit deliver routes from internal webchat turns

* Gateway chat tests: assert explicit deliver route context tagging
jenawant pushed a commit to jenawant/openclaw that referenced this pull request Mar 10, 2026
…penclaw#36151)

* Auto-reply: avoid routing external replies from internal webchat turns

* Auto-reply tests: cover internal webchat non-routing with external origin metadata

* Changelog: add Control UI iMessage duplicate-reply fix note

* Auto-reply context: track explicit deliver routes

* Gateway chat: mark explicit external deliver routes in context

* Auto-reply: preserve explicit deliver routes for internal webchat turns

* Auto-reply tests: cover explicit deliver routes from internal webchat turns

* Gateway chat tests: assert explicit deliver route context tagging
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

app: web-ui App: web-ui gateway Gateway runtime maintainer Maintainer-authored PR size: S

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Control UI chat duplicates replies to iMessage channel

1 participant