Skip to content

fix(whatsapp): restore direct inbound metadata for relay agents#31969

Merged
steipete merged 4 commits intoopenclaw:mainfrom
Lucenx9:fix/whatsapp-inbound-meta-29972
Mar 2, 2026
Merged

fix(whatsapp): restore direct inbound metadata for relay agents#31969
steipete merged 4 commits intoopenclaw:mainfrom
Lucenx9:fix/whatsapp-inbound-meta-29972

Conversation

@Lucenx9
Copy link
Contributor

@Lucenx9 Lucenx9 commented Mar 2, 2026

Summary

  • Problem: after 2026.2.26 migration/restart, WhatsApp direct messages routed to relay agents could lose the Conversation info (untrusted metadata) block (missing sender/message identifiers).
  • Why it matters: relay agents relying on sender metadata cannot attribute origin correctly (#29972).
  • What changed:
    • restored direct-chat conversation metadata for external channels (for example whatsapp) in buildInboundUserContextPrefix.
    • kept metadata hidden for internal webchat direct sessions to preserve the prior UX/privacy behavior.
    • extracted inbound channel resolution into a shared helper to keep logic consistent between system prompt and user-context prefix.
    • added regression tests for direct webchat (hidden) vs direct external channel (included).
  • What did NOT change (scope boundary): no changes to session routing, relay transport, or gateway delivery queues.

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

  • WhatsApp direct-channel turns once again include message/sender metadata in the model-facing untrusted context block.
  • Internal webchat direct sessions remain unchanged (metadata block still omitted).

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: Linux
  • Runtime/container: Node 22
  • Model/provider: relay model path (openai-completions style)
  • Integration/channel (if any): WhatsApp
  • Relevant config (redacted): direct-channel relay binding on whatsapp

Steps

  1. Route WhatsApp direct messages to a relay agent.
  2. Send inbound message and inspect model-facing user content.
  3. Verify Conversation info (untrusted metadata) block includes sender/message ids.

Expected

  • Direct external channels retain metadata block needed by relay.

Actual

  • Confirmed with tests: external direct channels include metadata; webchat direct remains hidden.

Evidence

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

Commands run locally:

  • pnpm vitest run src/auto-reply/reply/inbound-meta.test.ts src/auto-reply/reply/strip-inbound-meta.test.ts (pass)
  • pnpm check (pass)
  • pnpm build (pass)
  • pnpm protocol:check (pass)
  • pnpm lint:ui:no-raw-window-open (pass)

Human Verification (required)

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

  • Verified scenarios:
    • direct webchat still suppresses conversation metadata block.
    • direct whatsapp now includes message_id, message_id_full, sender.
  • Edge cases checked:
    • group-chat behavior unchanged.
    • conversation_label remains omitted for direct chats.
  • What you did not verify:
    • live end-to-end relay against a running WhatsApp account.

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/inbound-meta.ts, src/auto-reply/reply/inbound-meta.test.ts.
  • Known bad symptoms reviewers should watch for:
    • metadata unexpectedly appears in webchat direct sessions,
    • metadata still missing in WhatsApp direct relay prompts.

Risks and Mitigations

  • Risk: reintroducing noisy metadata into direct sessions.
    • Mitigation: explicit channel gate keeps direct webchat behavior unchanged; new tests cover both paths.

AI-Assisted Contribution

  • AI-assisted in implementation (Codex)
  • Fully tested for touched paths

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Mar 2, 2026

Greptile Summary

Restores conversation metadata (message IDs, sender info) for WhatsApp and other external direct channels while preserving the existing behavior of hiding metadata for webchat direct sessions. The change addresses relay agents losing critical sender attribution after the 2026.2.26 migration.

Key changes:

  • Extracted resolveInboundChannel helper to centralize channel resolution logic
  • Modified buildInboundUserContextPrefix to include metadata for direct external channels (non-webchat)
  • Added regression tests covering both direct webchat (hidden) and direct external channel (included) scenarios

Issue found:

  • Channel resolution inconsistency: buildInboundUserContextPrefix manually checks OriginatingChannel ?? Surface instead of using the extracted resolveInboundChannel helper, which could cause metadata to be hidden when channel info is only in Provider

Confidence Score: 3/5

  • Safe to merge with one logical issue that should be addressed
  • The PR addresses a real regression and includes good test coverage, but has an inconsistency in channel resolution logic that could cause the fix to not work in certain scenarios where channel info is only in Provider field
  • src/auto-reply/reply/inbound-meta.ts lines 87-91 need the channel resolution logic corrected to use the extracted helper

Last reviewed commit: b3c4538

Copy link
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, 1 comment

Edit Code Review Agent Settings | Greptile

Comment on lines 87 to +91
const isDirect = !chatType || chatType === "direct";
const directChannelValue = safeTrim(ctx.OriginatingChannel) ?? safeTrim(ctx.Surface);
const includeDirectConversationInfo = Boolean(
directChannelValue && directChannelValue !== "webchat",
);
Copy link
Contributor

Choose a reason for hiding this comment

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

Inconsistent channel resolution - should use resolveInboundChannel(ctx) instead of manually checking only OriginatingChannel and Surface.

The PR extracted resolveInboundChannel to centralize channel resolution logic, but it's not being used here. This helper includes fallback to Provider (lines 34-42), which is missing from this manual check.

If OriginatingChannel and Surface are both undefined but Provider is "whatsapp", this code would fail to include metadata for a direct WhatsApp chat, which contradicts the PR's goal.

Suggested change
const isDirect = !chatType || chatType === "direct";
const directChannelValue = safeTrim(ctx.OriginatingChannel) ?? safeTrim(ctx.Surface);
const includeDirectConversationInfo = Boolean(
directChannelValue && directChannelValue !== "webchat",
);
const directChannelValue = resolveInboundChannel(ctx);
const includeDirectConversationInfo = Boolean(
directChannelValue && directChannelValue !== "webchat",
);
const shouldIncludeConversationInfo = !isDirect || includeDirectConversationInfo;
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/auto-reply/reply/inbound-meta.ts
Line: 87-91

Comment:
Inconsistent channel resolution - should use `resolveInboundChannel(ctx)` instead of manually checking only `OriginatingChannel` and `Surface`.

The PR extracted `resolveInboundChannel` to centralize channel resolution logic, but it's not being used here. This helper includes fallback to `Provider` (lines 34-42), which is missing from this manual check.

If `OriginatingChannel` and `Surface` are both undefined but `Provider` is "whatsapp", this code would fail to include metadata for a direct WhatsApp chat, which contradicts the PR's goal.

```suggestion
  const directChannelValue = resolveInboundChannel(ctx);
  const includeDirectConversationInfo = Boolean(
    directChannelValue && directChannelValue !== "webchat",
  );
  const shouldIncludeConversationInfo = !isDirect || includeDirectConversationInfo;
```

How can I resolve this? If you propose a fix, please make it concise.

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: 6fe7c2f7cd

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +88 to +90
const directChannelValue = resolveInboundChannel(ctx);
const includeDirectConversationInfo = Boolean(
directChannelValue && directChannelValue !== "webchat",

Choose a reason for hiding this comment

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

P1 Badge Gate direct metadata on source surface, not route channel

For webchat-originated direct turns that are linked to an external delivery route, gateway/server-methods/chat.ts sets Provider/Surface to webchat but OriginatingChannel to the routed channel (for example whatsapp). Because this new logic derives directChannelValue from OriginatingChannel first, includeDirectConversationInfo becomes true and the direct Conversation info block (message/sender identifiers) is emitted, which reintroduces metadata in internal webchat sessions that were meant to stay hidden.

Useful? React with 👍 / 👎.

@steipete steipete force-pushed the fix/whatsapp-inbound-meta-29972 branch from 60d9d19 to 43e8dcf Compare March 2, 2026 18:39
@steipete steipete merged commit 5c1eb07 into openclaw:main Mar 2, 2026
9 checks passed
@steipete
Copy link
Contributor

steipete commented Mar 2, 2026

Landed via temp rebase onto main.

  • Gate: bunx vitest run src/auto-reply/reply/inbound-meta.test.ts src/auto-reply/reply/strip-inbound-meta.test.ts
  • Land commit: 43e8dcf
  • Merge commit: 5c1eb07

Thanks @Lucenx9!

execute008 pushed a commit to execute008/openclaw that referenced this pull request Mar 2, 2026
…claw#31969)

* fix(whatsapp): restore direct inbound metadata for relay agents

* fix(auto-reply): use shared inbound channel resolver for direct metadata

* chore(ci): retrigger checks after base update

* fix: add changelog attribution for inbound metadata relay fix (openclaw#31969) (thanks @Lucenx9)

---------

Co-authored-by: Simone <simone@example.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
dawi369 pushed a commit to dawi369/davis that referenced this pull request Mar 3, 2026
…claw#31969)

* fix(whatsapp): restore direct inbound metadata for relay agents

* fix(auto-reply): use shared inbound channel resolver for direct metadata

* chore(ci): retrigger checks after base update

* fix: add changelog attribution for inbound metadata relay fix (openclaw#31969) (thanks @Lucenx9)

---------

Co-authored-by: Simone <simone@example.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
OWALabuy pushed a commit to kcinzgg/openclaw that referenced this pull request Mar 4, 2026
…claw#31969)

* fix(whatsapp): restore direct inbound metadata for relay agents

* fix(auto-reply): use shared inbound channel resolver for direct metadata

* chore(ci): retrigger checks after base update

* fix: add changelog attribution for inbound metadata relay fix (openclaw#31969) (thanks @Lucenx9)

---------

Co-authored-by: Simone <simone@example.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
zooqueen pushed a commit to hanzoai/bot that referenced this pull request Mar 6, 2026
…claw#31969)

* fix(whatsapp): restore direct inbound metadata for relay agents

* fix(auto-reply): use shared inbound channel resolver for direct metadata

* chore(ci): retrigger checks after base update

* fix: add changelog attribution for inbound metadata relay fix (openclaw#31969) (thanks @Lucenx9)

---------

Co-authored-by: Simone <simone@example.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

WhatsApp: metadata envelope missing from messages sent to openai-completions relay agent after gateway restart

2 participants