Delivery Config

Configure durable inbound delivery for your bot channels — on by default, per-platform isolated

Every bot channel automatically gets crash-safe inbound delivery: a deduplicating journal and a dead-letter queue, stored in ~/.praisonai/state/<platform>/.

python
from praisonaiagents import Agent

# Durable inbound delivery is on by default — wire an agent in bot.yaml
agent = Agent(name="support", instructions="Reply helpfully on Telegram.")
# praisonai bot start --config bot.yaml

The user starts a bot; durable inbound delivery journals messages and routes failures to a DLQ automatically.

Diagram

Default Durable Delivery

🤖 Bot Start

build_session_manager

📒 InboundJournal\ningress.sqlite

📥 InboundDLQ\ninbound_dlq.sqlite

💾 ~/.praisonai/state/\nplatform/

How It Works

Diagram
Delivery ConfigAgentUserDelivery ConfigAgentUserRequestProcess requestResult Agent–>>User: Response

What’s on by default

When you start any bot via praisonai bot start, onboard, or bot.yaml, PraisonAI automatically wires:

  • Inbound Journal (ingress.sqlite) — deduplicates webhook redeliveries and replays in-flight messages on crash recovery
  • Inbound DLQ (inbound_dlq.sqlite) — persists failed-LLM messages for later replay

Both live in one canonical per-platform directory. No configuration needed.

Canonical path

~/.praisonai/state/<platform>/ingress.sqlite
~/.praisonai/state/<platform>/inbound_dlq.sqlite

<platform> is the sanitized platform name (characters outside [A-Za-z0-9_.-] replaced with _).

PlatformJournal pathDLQ path
telegram~/.praisonai/state/telegram/ingress.sqlite~/.praisonai/state/telegram/inbound_dlq.sqlite
discord~/.praisonai/state/discord/ingress.sqlite~/.praisonai/state/discord/inbound_dlq.sqlite
slack~/.praisonai/state/slack/ingress.sqlite~/.praisonai/state/slack/inbound_dlq.sqlite
whatsapp~/.praisonai/state/whatsapp/ingress.sqlite~/.praisonai/state/whatsapp/inbound_dlq.sqlite

Set PRAISONAI_HOME to change the base directory:

bash
export PRAISONAI_HOME=/var/lib/praisonai
# → /var/lib/praisonai/state/telegram/ingress.sqlite

delivery: schema

The delivery block is part of each channel configuration in bot.yaml / gateway.yaml:

FieldTypeDefaultDescription
durablebooltrueSet to false to fully opt out and return to in-memory delivery.
storestrNonePath override. If it has a file suffix, sibling DBs are placed in its parent directory. None resolves to the canonical per-platform path.

Quick Start

  1. Default (nothing to do)

    Just start your bot — durable delivery is already on.

    bash
    praisonai bot start --config bot.yaml
  2. Opt out for a channel
    yaml
    # bot.yaml
    channels:
      telegram:
        token: "${TELEGRAM_BOT_TOKEN}"
        delivery:
          durable: false   # returns to in-memory delivery
  3. Override the store directory
    yaml
    channels:
      telegram:
        token: "${TELEGRAM_BOT_TOKEN}"
        delivery:
          store: /var/lib/praisonai/telegram-state
          # → ingress.sqlite and inbound_dlq.sqlite in /var/lib/praisonai/telegram-state/

Per-platform isolation

Each platform gets its own directory so DLQ replays never cross platforms:

Diagram

~/.praisonai/state/

telegram/

discord/

slack/

ingress.sqlite

inbound_dlq.sqlite

ingress.sqlite

inbound_dlq.sqlite

ingress.sqlite

inbound_dlq.sqlite

A Discord DLQ replay never consumes a Telegram failed event. Dedup keys never collide cross-platform.

Failure mode

If durability is requested but the SQLite components fail to initialise (permissions, disk full, etc.), _build_durable_components logs a warning and the manager safely falls back to in-memory delivery. Your bot continues working — no crash.

Best Practices

Keep the default ON unless you have a reason to opt out

Durable delivery costs a tiny SQLite write per message. The benefit — zero silent message loss on crash or LLM failure — is almost always worth it.

Use PRAISONAI_HOME for containerized deployments

Mount a persistent volume and point PRAISONAI_HOME at it so the SQLite files survive container restarts.

bash
docker run -e PRAISONAI_HOME=/data -v /host/data:/data my-bot
Override store for multi-bot setups on one host

If you run two Telegram bots on the same host for different use cases, give each bot its own store directory to keep their journals isolated.

yaml
# bot-support.yaml
channels:
  telegram:
    token: "${SUPPORT_BOT_TOKEN}"
    delivery:
      store: /var/lib/praisonai/support-telegram

# bot-sales.yaml
channels:
  telegram:
    token: "${SALES_BOT_TOKEN}"
    delivery:
      store: /var/lib/praisonai/sales-telegram
Monitor DLQ size as a reliability indicator

A growing DLQ (praisonai bot dlq list) signals chronic LLM failures. Wire dlq.size() into your alerting stack. Since PR #3521, a growing DLQ is a stronger signal — transient outages no longer inflate the count. A trend rising over multi-hour windows indicates genuinely poisoned traffic worth paging on.


Related