<!-- source: https://deepwiki.com/openclaw/openclaw/4.4-message-flow-and-delivery -->

# Message Flow & Delivery

- docs/concepts/compaction.md
- docs/reference/session-management-compaction.md
- extensions/discord/src/channel-actions.test.ts
- extensions/discord/src/channel-actions.ts
- extensions/discord/src/channel.test.ts
- extensions/discord/src/send.permissions.authz.test.ts
- extensions/discord/src/send.permissions.ts
- extensions/discord/src/send.ts
- extensions/discord/src/shared.test.ts
- extensions/discord/src/shared.ts
- extensions/mattermost/src/channel.test.ts
- extensions/mattermost/src/channel.ts
- extensions/mattermost/src/mattermost/send.test.ts
- extensions/mattermost/src/mattermost/send.ts
- scripts/check-docker-e2e-boundaries.mjs
- scripts/ensure-playwright-chromium.mjs
- src/agents/agent-model-discovery.ts
- src/agents/embedded-agent-runner/model-discovery-cache.ts
- src/agents/model-catalog.test.ts
- src/agents/model-catalog.ts
- src/agents/model-discovery-context.ts
- src/agents/model-registry-loader.ts
- src/agents/plugin-model-catalog.ts
- src/agents/sessions/model-registry.ts
- src/agents/tools/message-tool.test.ts
- src/agents/tools/message-tool.ts
- src/auto-reply/reply/agent-runner-usage-line.test.ts
- src/auto-reply/reply/agent-runner-usage-line.ts
- src/gateway/runtime-plugin-config.test.ts
- src/gateway/runtime-plugin-config.ts
- src/gateway/server-methods/channels.start.test.ts
- src/gateway/server-methods/channels.status.test.ts
- src/gateway/server-methods/channels.ts
- src/gateway/server-methods/chat.directive-tags.test.ts
- src/gateway/server-methods/chat.ts
- src/gateway/server-methods/send.test.ts
- src/gateway/server-methods/send.ts
- src/gateway/server.chat.gateway-server-chat-b.test.ts
- src/gateway/server.sessions.permissions-hooks.test.ts
- src/gateway/session-compaction-checkpoints.test.ts
- src/gateway/session-compaction-checkpoints.ts
- src/infra/outbound/message-action-param-keys.ts
- src/infra/outbound/message-action-params.test.ts
- src/infra/outbound/message-action-params.ts
- src/infra/outbound/message-action-runner.media.test.ts
- src/infra/outbound/message-action-runner.send-validation.test.ts
- src/infra/outbound/message-action-runner.ts
- src/infra/outbound/outbound-send-service.test.ts
- src/infra/outbound/outbound-send-service.ts
- src/routing/session-key.test.ts
- src/routing/session-key.ts
- src/secrets/runtime-discord-surface.test.ts
- src/sessions/user-turn-transcript.test.ts
- src/sessions/user-turn-transcript.ts
- test/scripts/ensure-playwright-chromium.test.ts
- ui/src/test-helpers/control-ui-e2e.ts
- ui/src/ui/app-chat.test.ts
- ui/src/ui/app-chat.ts
- ui/src/ui/app-gateway-chat-load.node.test.ts
- ui/src/ui/app-gateway.sessions.node.test.ts
- ui/src/ui/app-gateway.ts
- ui/src/ui/chat/run-lifecycle.test.ts
- ui/src/ui/chat/run-lifecycle.ts
- ui/src/ui/controllers/chat.test.ts
- ui/src/ui/controllers/chat.ts
- ui/src/ui/controllers/sessions.test.ts
- ui/src/ui/controllers/sessions.ts
- ui/src/ui/e2e/chat-flow.e2e.test.ts
- ui/src/ui/e2e/cron-filters.e2e.test.ts
- ui/src/ui/session-key.ts

This page documents the message processing pipeline in OpenClaw, specifically focusing on the outbound delivery system, session key generation, update watermarking, deduplication, and reply delivery. It explains how OpenClaw routes messages from agents back to users across various platforms, ensuring continuity of conversations and reliable delivery.

## Overview

OpenClaw's message delivery architecture separates message intent from platform-specific implementation details. Outbound message dispatch follows a pipeline that progresses from agent message action invocation through layered resolution and finally to platform-specific delivery.

The fundamental stages are:

1. Action Initiation : Agents or commands invoke outbound message actions via the runInboundMessageDispatch or dispatchInboundMessage pipeline. src/gateway/server-methods/chat.ts 42
2. Target Resolution : Human-friendly identifiers or user/channel IDs are converted to concrete channel-account-message targets using session bindings and conversation routing. src/infra/outbound/message-action-runner.ts 88-90
3. Session Routing : The system calculates or confirms the appropriate session key to maintain conversation continuity. src/routing/session-key.ts 25-30
4. Delivery Execution : Payloads are chunked, sanitized, and dispatched via the outbound adapter specific to the messaging channel (e.g., Telegram, Discord, Slack, WhatsApp). src/infra/outbound/message-action-runner.ts 87

**Sources:** [src/gateway/server-methods/chat.ts42-44](https://github.com/openclaw/openclaw/blob/fbdf5937/src/gateway/server-methods/chat.ts#L42-L44) [src/routing/session-key.ts25-30](https://github.com/openclaw/openclaw/blob/fbdf5937/src/routing/session-key.ts#L25-L30) [src/infra/outbound/message-action-runner.ts87-91](https://github.com/openclaw/openclaw/blob/fbdf5937/src/infra/outbound/message-action-runner.ts#L87-L91)

## Outbound Delivery Pipeline

The core of the delivery system is the platform-specific dispatch logic. This logic encapsulates assembling outbound payloads, leveraging delivery hooks, and invoking dispatchers for final delivery.

### Message Action Flow

The flow of a message from the agent runtime to the physical channel involves several layers of normalization and policy checking.

**Diagram: Message Action Execution Flow**

```

```

- runMessageAction : Entry point for processing an outbound message request, handling parameter hydration and policy enforcement. src/infra/outbound/message-action-runner.ts 111
- normalizeMessageActionInput : Sanitizes input parameters and resolves media references. src/infra/outbound/message-action-runner.ts 58
- resolveOutboundChannelPlugin : Identifies the correct channel implementation based on the session or explicit target. src/infra/outbound/message-action-runner.ts 51
- executeSendAction : The final dispatcher that hands the payload to the channel-specific provider. src/infra/outbound/outbound-send-service.ts 11

**Sources:** [src/infra/outbound/message-action-runner.ts51-111](https://github.com/openclaw/openclaw/blob/fbdf5937/src/infra/outbound/message-action-runner.ts#L51-L111) [src/infra/outbound/outbound-send-service.ts11-20](https://github.com/openclaw/openclaw/blob/fbdf5937/src/infra/outbound/outbound-send-service.ts#L11-L20)

## Session Key Generation & Routing

Session keys uniquely identify conversations and are crucial for maintaining consistent state across message turns and platforms.

### Session Key Formation

Session keys are derived from the message context. OpenClaw uses `parseAgentSessionKey` and `normalizeAgentId` to determine the correct key based on the chat type and platform identifiers. [src/routing/session-key.ts25-30](https://github.com/openclaw/openclaw/blob/fbdf5937/src/routing/session-key.ts#L25-L30)

The system distinguishes between different interaction lanes:

- Direct Agent Sessions : Scoped to a specific agent (e.g., agent:main:sess-1 ). src/routing/session-key.ts 25
- Global Sessions : Shared across agents for specific integration types. ui/src/ui/session-key.ts 83
- Channel Bindings : Map platform-specific thread IDs to internal session keys. src/infra/outbound/message-action-runner.ts 71-74

### Outbound Session Resolution

When sending a message, OpenClaw resolves the effective reply route using session metadata and session binding services. [src/gateway/server-methods/chat.ts60](https://github.com/openclaw/openclaw/blob/fbdf5937/src/gateway/server-methods/chat.ts#L60-L60)

**Diagram: Session Route Resolution State**

```

```

**Sources:** [src/routing/session-key.ts25-30](https://github.com/openclaw/openclaw/blob/fbdf5937/src/routing/session-key.ts#L25-L30) [src/infra/outbound/message-action-runner.ts88](https://github.com/openclaw/openclaw/blob/fbdf5937/src/infra/outbound/message-action-runner.ts#L88-L88) [src/gateway/server-methods/chat.ts141-150](https://github.com/openclaw/openclaw/blob/fbdf5937/src/gateway/server-methods/chat.ts#L141-L150)

## Message Processing: Deduplication & Feedback

To prevent processing the same incoming update multiple times and handle race conditions, OpenClaw employs deduplication and feedback mechanisms.

- Inbound Deduplication : Managed via setGatewayDedupeEntry to prevent concurrent processing of duplicate message IDs. src/gateway/server-methods/chat.ts 153
- Update Watermarking : The system uses updateChatRunProvider and run lifecycle reconciliation to track session progress during long-running agent turns. src/gateway/server-methods/chat.ts 109-110
- Wait/Steer Queue : If a message arrives while an agent is already thinking, it is placed in a steering queue to be delivered to the active run. ui/src/ui/app-chat.ts 43

### User Turn Transcript Recording

OpenClaw records user inputs before they are even processed by the agent to ensure durability. The `UserTurnTranscriptRecorder` handles persisting the "user" role message to the session JSONL file. [src/sessions/user-turn-transcript.ts112-130](https://github.com/openclaw/openclaw/blob/fbdf5937/src/sessions/user-turn-transcript.ts#L112-L130)

- Persistence : persistUserTurnTranscript appends the message to the session file. src/sessions/user-turn-transcript.ts 67
- Media Support : Media inputs are normalized and paths resolved against the session workspace. src/sessions/user-turn-transcript.ts 190-204

### Progress and Metadata Injection

Before delivery, messages are enriched with metadata and formatted according to platform capabilities.

- Timestamp Injection : injectTimestamp adds precise timing metadata to agent turns. src/gateway/server-methods/chat.ts 152
- Directive Tags : Inline directives like /think or /verbose are parsed and stripped for display using stripInlineDirectiveTagsForDisplay . src/gateway/server-methods/chat.ts 91
- Canvas Rendering : Visual components are extracted from text using extractCanvasFromText for clients that support A2UI rendering. src/gateway/server-methods/chat.ts 47

**Sources:** [src/gateway/server-methods/chat.ts91-153](https://github.com/openclaw/openclaw/blob/fbdf5937/src/gateway/server-methods/chat.ts#L91-L153) [src/sessions/user-turn-transcript.ts112-130](https://github.com/openclaw/openclaw/blob/fbdf5937/src/sessions/user-turn-transcript.ts#L112-L130) [ui/src/ui/app-chat.ts43](https://github.com/openclaw/openclaw/blob/fbdf5937/ui/src/ui/app-chat.ts#L43-L43)

## Technical Data Flow: Reply Delivery

The following sequence diagram shows the flow from the Gateway receiving a message to the UI rendering the response.

**Diagram: Reply Delivery Sequence**

```

```

**Sources:** [src/gateway/server-methods/chat.ts147-153](https://github.com/openclaw/openclaw/blob/fbdf5937/src/gateway/server-methods/chat.ts#L147-L153) [src/infra/outbound/message-action-runner.ts111](https://github.com/openclaw/openclaw/blob/fbdf5937/src/infra/outbound/message-action-runner.ts#L111-L111) [ui/src/ui/app-chat.ts41-43](https://github.com/openclaw/openclaw/blob/fbdf5937/ui/src/ui/app-chat.ts#L41-L43)
