Inbound Message Lifecycle
The inbound pipeline follows a strict progression from raw connector event to a dispatched agent run.1. Admission and Matching
When a connector (e.g., Discord) receives a message, it is passed to theChannelRouter::route_inbound function crates/palyra-daemon/src/channel_router.rs#1-10. The router evaluates the message against ChannelRoutingRule sets crates/palyra-daemon/src/channel_router.rs#195-210.
- Mention Matching: The router checks if the message matches defined
mention_patternscrates/palyra-daemon/src/channel_router.rs#198. - Sender Filtering:
allow_fromanddeny_fromlists are checked to permit or block specific identities crates/palyra-daemon/src/channel_router.rs#200-201. - DM Policy: Direct messages are gated by
DirectMessagePolicy, which can beDeny,Allow, orPairingcrates/palyra-daemon/src/channel_router.rs#74-78.
2. Session Resolution
Once admitted, the router determines thesession_id. If isolate_session_by_sender is true, a unique session is created per user; otherwise, the conversation ID from the platform is used crates/palyra-daemon/src/channel_router.rs#204.
3. Inbound Coalescing
To prevent “message storms” from triggering excessive runs, the pipeline uses anInboundCoalescer (logic managed within the gateway runtime). This component merges multiple rapid-fire messages from the same conversation into a single buffer before dispatching a “Channel Turn.”
4. Dispatch
Accepted messages result in aRouteInboundResult crates/palyra-connectors/tests/simulator_harness.rs#53-77. This result contains the route_key and session_id required by the GatewayRuntime to initiate an agent run.
Inbound Data Flow Diagram
Sources: crates/palyra-daemon/src/channel_router.rs#1-210, crates/palyra-connectors/tests/simulator_harness.rs#47-78, crates/palyra-daemon/src/channels.rs#1-175
Channel Router Implementation
TheChannelRouter is a policy-driven engine that manages in-memory state for routing decisions, including rate limiting and quarantine for “poison” messages crates/palyra-daemon/src/channel_router.rs#1-10.
Key Structures
| Class/Struct | Responsibility |
|---|---|
ChannelRouter | Primary entry point for routing logic and policy enforcement. |
ChannelRoutingRule | Defines how a specific channel behaves (mentions, targets, etc.). |
DirectMessagePolicy | Enum defining Deny, Pairing, or Allow for DMs. |
BroadcastStrategy | Controls how fan-out requests are handled per channel. |
Direct Message Pairing
For channels usingDirectMessagePolicy::Pairing, the router manages a “handshake” flow:
- Code Generation: An operator generates a
PairingCodeRecordcrates/palyra-daemon/src/channel_router.rs#107-113. - Consumption: The user sends the code via DM. The router creates a
PairingPendingRecordcrates/palyra-daemon/src/channel_router.rs#118-125. - Approval: An operator approves the request, creating a
PairingGrantRecordcrates/palyra-daemon/src/channel_router.rs#129-135.
Outbound Lifecycle
Outbound messages follow a “Delivery Intent” pattern to ensure reliability across unstable network conditions.- Enqueue: The agent or a tool requests an outbound send. This is captured as an
OutboundMessageRequestcrates/palyra-daemon/src/channels/discord.rs#150-165. - Persistence: The request is stored in the outbox via the
ConnectorSupervisorcrates/palyra-daemon/src/channels/discord.rs#166. - Drain: A background worker or immediate trigger calls
drain_due_outbox_for_connectorcrates/palyra-daemon/src/channels/discord.rs#168-173. - Delivery: The specific adapter (e.g., Discord) executes the HTTPS/WebSocket request.
- Receipt: If successful, a
native_message_idis returned and associated with the internalenvelope_idcrates/palyra-daemon/src/channels/discord.rs#174-177.
Outbound Mutation and Approval
Mutations (Edit, Delete, Reactions) are subject toApprovalRiskLevel checks crates/palyra-daemon/src/channels/discord.rs#15.
- Preflight: The system checks if the connector supports the action crates/palyra-cli/src/client/message.rs#4-6.
- Governance:
classify_discord_message_mutation_governancedetermines if a mutation requires manual operator approval based on the target channel and message age crates/palyra-daemon/src/channels.rs#69-72.
Conversation Bindings
Palyra maintains a mapping between external platform entities and internal agent constructs.- Principal: The identity of the Palyra instance on the platform (e.g., the Bot User ID) crates/palyra-daemon/src/channels.rs#45.
- Connector ID: A unique string identifying a specific account/token (e.g.,
discord:my-server) crates/palyra-daemon/src/channels/discord.rs#20. - Route Key: A deterministic string combining connector and conversation IDs used to serialize access to session state crates/palyra-connectors/tests/simulator_harness.rs#68-71.
Implementation Reference
| Feature | Code Entity | File Path |
|---|---|---|
| Routing Entry | ChannelRouter::route_inbound | crates/palyra-daemon/src/channel_router.rs#1-10 |
| Platform Facade | ChannelPlatform | crates/palyra-daemon/src/channels.rs#169-174 |
| Outbound Send | submit_discord_test_send | crates/palyra-daemon/src/channels/discord.rs#99-103 |
| Mutation Risk | ApprovalRiskLevel | crates/palyra-daemon/src/channels/discord.rs#15 |
| Admin API | admin_channels_list_handler | crates/palyra-daemon/src/transport/http/handlers/admin/channels/mod.rs#26-30 |