Skip to content

fix(reply): keep webchat-origin main session replies on originating surface#33250

Closed
bmendonca3 wants to merge 4 commits intoopenclaw:mainfrom
bmendonca3:bm/33201-main-session-origin-route
Closed

fix(reply): keep webchat-origin main session replies on originating surface#33250
bmendonca3 wants to merge 4 commits intoopenclaw:mainfrom
bmendonca3:bm/33201-main-session-origin-route

Conversation

@bmendonca3
Copy link
Copy Markdown
Contributor

Summary

Describe the problem and fix in 2–5 bullets:

  • Problem: Main-session turns that originate from webchat (TUI/gateway client) can reuse a previously persisted external delivery route (for example WhatsApp), which causes replies to fan out to the wrong surface.
  • Why it matters: Control-surface messages should stay on the control surface; leaking those replies to external channels is user-visible and can send unintended content.
  • What changed: Adjusted resolveLastChannelRaw and resolveLastToRaw to prefer webchat origin routing when the session key is the main session (agent:<id>:main), then added a regression test that reproduces the leak and validates webchat pinning.
  • What did NOT change (scope boundary): Internal non-webchat handoff channels (for example sessions_send) still preserve persisted external fallback behavior; non-main session behavior is unchanged.

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

Main-session replies triggered from webchat/TUI now stay on webchat instead of reusing a stale external route (for example WhatsApp).

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 (dev)
  • Runtime/container: Node 22 + pnpm
  • Model/provider: N/A (routing/session behavior)
  • Integration/channel (if any): webchat main session + persisted external route
  • Relevant config (redacted): session store with main entry persisted as external channel route

Steps

  1. Seed session store so agent:main:main has persisted lastChannel=whatsapp, lastTo=<phone>.
  2. Initialize a turn on that same session with OriginatingChannel=webchat and OriginatingTo=session:webchat-main.
  3. Inspect resolved session delivery context.

Expected

  • Main-session reply route remains on webchat for that turn (lastChannel=webchat, lastTo=session:webchat-main).

Actual

  • Before fix, routing reused persisted external route (lastChannel=whatsapp) and could deliver to the wrong channel.

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:
    • Added regression test: prefers webchat route over persisted external route for main session turns.
    • Ran full src/auto-reply/reply/session.test.ts to ensure routing behavior remains coherent.
  • Edge cases checked:
    • Non-webchat internal channels still preserve persisted external fallback behavior.
    • Non-main session behavior remains unchanged.
  • What you did not verify:
    • Live multi-channel delivery against real WhatsApp/TUI runtime.

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 commit.
  • Files/config to restore: src/auto-reply/reply/session-delivery.ts, src/auto-reply/reply/session.test.ts.
  • Known bad symptoms reviewers should watch for: webchat main-session turns unexpectedly delivering to stale external channels.

Risks and Mitigations

List only real risks for this PR. Add/remove entries as needed. If none, write None.

  • Risk: Main-session webchat messages no longer inherit a previous external route in cases where users intentionally relied on that implicit fallback.
    • Mitigation: Scope is intentionally narrow to main-session + webchat origin only; tests preserve existing behavior for non-webchat internal channels.

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps bot commented Mar 3, 2026

Greptile Summary

This PR fixes a routing leak where main-session turns originating from webchat could reuse a previously persisted external delivery route (e.g., WhatsApp), causing replies to fan out to the wrong surface. The fix adds narrow early-return guards in resolveLastChannelRaw and resolveLastToRaw that short-circuit the external-fallback logic whenever the originating channel is webchat and the session key identifies the main session.

Key points:

  • Channel guard (resolveLastChannelRaw): Correctly returns originatingChannelRaw ("webchat") before the external-fallback branch, preventing stale external channels from overwriting it.
  • Potential to mismatch: The resolveLastToRaw early-return guard still falls back to persistedLastTo when no current destination is provided. In edge cases where a webchat main-session turn arrives without OriginatingTo or To but has persisted external lastTo data, this creates a logical mismatch: lastChannel="webchat" paired with an external address. The new regression test covers the primary scenario (where OriginatingTo is provided), but not this edge case.
  • Backward compatibility: Non-webchat internal channels and non-main sessions are unaffected.

Confidence Score: 3/5

  • Safe for the documented main-session webchat routing scenario, but carries an unaddressed channel/to mismatch risk for edge cases without OriginatingTo.
  • The primary bug (stale external channel leak on webchat main-session turns) is correctly fixed and covered by the regression test when OriginatingTo is provided. However, a secondary logic error exists in resolveLastToRaw: when a webchat main-session turn omits both OriginatingTo and To but inherits persisted external lastTo data, the code produces an inconsistent lastChannel="webchat" / lastTo=<external> pairing. This edge case is demonstrable via the existing test "keeps webchat channel for webchat/main sessions" (which passes no OriginatingTo) combined with persisted external data. Score is lowered from 4 to 3 because this mismatch represents a real logic error that could cause delivery failures, even though it is narrower in scope than the original leak.
  • src/auto-reply/reply/session-delivery.ts — resolveLastToRaw function should guard or remove the persistedLastTo fallback in the early-return branch for webchat main sessions.

Last reviewed commit: c4d04bc

Copy link
Copy Markdown
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

2 files reviewed, 2 comments

Edit Code Review Agent Settings | Greptile

@bmendonca3
Copy link
Copy Markdown
Contributor Author

@greptileai

Copy link
Copy Markdown

@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: 5f9f6c5e07

ℹ️ 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 labels Mar 4, 2026
Copy link
Copy Markdown

@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: a993ea6c56

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

@Takhoffman
Copy link
Copy Markdown
Contributor

Superseded by #33786.

The synthesis PR includes webchat/main reply-surface routing fixes and aligned session routing invariants.

@Takhoffman
Copy link
Copy Markdown
Contributor

Thanks again for this work.

This PR was triaged and merged using an AI-assisted review/synthesis workflow.

This landed indirectly via the synthesized PR #33786, and your contribution is credited in the changelog and as a co-author on the merge commit.

Closing this PR as superseded by #33786 (reason: superseded). If anything here looks incorrect or incomplete, reply to reopen and we can reassess.

@Takhoffman Takhoffman closed this Mar 4, 2026
@Takhoffman
Copy link
Copy Markdown
Contributor

Correction for accuracy: the synthesized work is credited in the changelog, but the squash merge commit for #33786 does not include explicit Co-authored-by trailers.

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 size: S

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Main session replies fan out to all connected surfaces instead of pinning to originating channel

2 participants