Skip to main content
The heavy gateway implementation (WebSocketGateway) lives in the praisonai_bot.gateway package. praisonaiagents.gateway holds only protocols and lightweight utilities. praisonai serve gateway and from praisonai.gateway import WebSocketGateway still work exactly as documented here via re-export shims; for a standalone install see praisonai-bot Migration.
Agents can connect through a unified gateway providing single-entry access to multi-agent coordination, tools, and streaming events.

Quick Start

1

Simple Agent Gateway

Deploy an agent through the unified gateway:
2

Multi-Service Gateway

Configure agents with full gateway capabilities:

How It Works

Agents connect to services through gateway routing:
For bot gateways, use the one-line reliability="production" preset on BotOS, gateway YAML, or praisonai gateway start --reliability production instead of tuning drain and admission separately. See Gateway Reliability.

Hot Reload

Edit gateway.yaml while the gateway is running — file watch (with optional watchdog) and SIGHUP share the same diff-driven reload path, with drain-coordinated channel restarts. Rotating gateway.auth_token in the same reload also revokes any live sessions on the old secret — see Gateway Credential Rotation. See Gateway Config Reload. For proactive/scheduled outbound delivery routing — including friendly alias targets like "family" or "ops" — see Friendly Aliases for Scheduled Delivery.

Voice notes

Voice messages sent to your gateway bot are transcribed automatically on Telegram, Slack, and WhatsApp — no code changes required. Configure the stt: block under each channel to force a language or opt out. See Voice Notes (Speech-to-Text).

Authentication

Authentication posture changes automatically based on the bind interface.

Bind-Aware Authentication

Complete authentication security guide

Rotating the shared secret

Change gateway.auth_token in the running gateway.yaml and hot-reload — every already-connected session that authenticated under the old secret is force-closed with WebSocket close code 4001 and reason credentials_rotated. New connections use the new secret. Defaults on; opt out with gateway.revoke_on_secret_rotation: false. See Gateway Credential Rotation for the full behaviour matrix. The auto-generated per-install HMAC secret for pairing codes (.gateway_secret) is stored and permission-remediated separately — see Bot Pairing → Secret Management.

Pre-auth edge protections

Two guards protect internet-exposed gateway deployments by default: a per-IP connection budget (preauth_max_connections_per_ip=32) that caps unauthenticated WebSocket slots before auth runs, and a per-connection flood guard (max_unauthorized_frames=10) that closes connections sending too many unauthorized frames. Loopback clients are always exempt. Both are disabled by setting the option to 0.

Gateway Edge Protections

Per-IP connection budget, unauthorized-frame flood guard, and WebSocket close codes 4028 / 4029

Handshake and Version Negotiation

New WebSocket clients should send a hello frame to negotiate protocol version, capabilities, and policy limits in one round trip. The legacy joinjoined flow remains supported for existing clients.

Gateway Handshake Protocol

Version negotiation, capabilities, and structured connection errors

Handling connect errors

A rejected handshake carries a structured code and next_step, so a client can tell a terminal failure (revoked token, unpaired device, unsupported protocol) from a transient one (rate limit) instead of probing-by-failure. The bundled client classifies each rejection with the shared is_recoverable(code) helper: terminal codes stop the reconnect loop and fire on_reconnect_paused(code, next_step); transient codes back off and retry, honouring any server retry_after_seconds as a lower bound.

Gateway Client — Terminal vs Transient Errors

Connect-error classification, on_reconnect_paused, and the recoverable-code table

Configuration Options

Gateway Configuration

Python gateway configuration options
Edge protection fields (available on GatewayConfig and gateway.yaml):

Gateway YAML Configuration

The gateway.yaml schema accepts three optional top-level blocks alongside channels and agents. All three are optional and ignored when not present.

gateway: block

Global gateway settings — reliability preset, drain timeout, health monitor:
Inbound voice notes on Telegram, Slack, and WhatsApp are transcribed automatically — see Voice Notes.
Discord and Slack channels are auto-discovered on every refresh — your bot can address a channel before anyone messages it. See Channel Directory.

api: block

Serve OpenAI-compatible and MCP HTTP endpoints from the same gateway process, sharing the live agents and sessions that chat users reach:
Both surfaces are opt-in and off by default. See Gateway API Endpoints for the endpoint list, auth, and client examples.

hooks: block

Register shell-command hooks that fire at gateway and message lifecycle events:

BotOS.from_config and tool names

BotOS.from_config("botos.yaml") now routes tool names through the standard ToolResolver chain:
  1. Local tools.py in the working directory
  2. Wrapper ToolRegistry
  3. praisonaiagents built-in tools
  4. praisonai-tools package
  5. Installed plugins
This means a YAML bot referencing a praisonai-tools symbol or a local tools.py function just works — no ad-hoc importlib lookup required:

Gateway Agent Defaults

Gateway agents loaded from YAML use chat-optimised defaults that differ from the Python SDK.
Changed in PraisonAI v4.6.26: gateway agents now default to reflection: false. Previous versions defaulted to true. See PR #1485.

Per-Agent Approval Isolation

“Allow always” grants persist across gateway restart and default to being scoped to the approving agent, so one agent’s approval never authorises another. Grants live in a durable SQLite store at ~/.praisonai/state/gateway/approvals.sqlite.

Gateway Scoped Approvals

Durable, agent-scoped allow-always grants, resolver scoping options, and the /api/approval/allow-list endpoint
Gateway also supports isolated exec approval managers for multi-tenant environments where agents must not share approval state.

Default vs Per-Agent Managers

Multi-Agent Gateway with Isolation

The ttl parameter controls how long approval requests wait before auto-expiring (default: 5 minutes). The get_exec_approval_manager() function is preserved as a backward-compatible alias for get_default_exec_approval_manager().

Allow-list endpoint

GET/POST/DELETE /api/approval/allow-list manages allow-always grants. POST and DELETE accept an optional agent_id; GET returns a grants view alongside the legacy allow_list.
Omitting agent_id on POST/DELETE targets a legacy any-agent grant; supplying it scopes to that agent. See Gateway Scoped Approvals for full curl examples.

Gateway lifecycle predicates

Core SDK exports three pure predicates for gateway lifecycle decisions. Each is side-effect free and testable in isolation; the wrapper owns the actual teardown.

Kanban Dispatcher

Kanban dispatcher (v4.6.x): Worker file descriptors are now released as soon as the subprocess starts (fixes a slow leak under sustained dispatch). release_claim failures are logged with full stack traces instead of being silently swallowed — orphaned claimed tasks now leave a clear log trail for triage. KeyboardInterrupt / SystemExit / asyncio cancellation propagate cleanly through dispatcher shutdown.

Common Patterns

Single Gateway Deployment

Multi-Agent Gateway

Development Gateway


Best Practices

Use praisonai serve unified for simplicity. Agents connect automatically without configuration.
Enable --reload for development. Use separate services for production scaling.
All servers expose /__praisonai__/discovery for endpoint discovery. Agents can auto-discover capabilities.
Reserve port 8765 for unified gateway. Use default ports for service-specific deployments.

Exit Codes & Supervisor Integration

praisonai serve gateway uses sysexits-based exit codes so process supervisors can distinguish a transient failure (restart) from a fatal misconfiguration (stop and fix).

What Triggers Fatal (78)

systemd Unit

Kubernetes Restart Policy

For Kubernetes, use a wrapper script that maps exit code 78 to success (exit 0) to prevent the pod from restarting on fatal config:

In-Place Code Updates and /model

When a running gateway’s code changes on disk (via git pull, pip install -U, or an auto-update on a durable volume), the first-use lazy import triggered by a /model switch can hit a code mismatch and crash with a cryptic ImportError. The code-skew guard refuses with a clear message instead.

How It Works

At startup, the gateway captures a fingerprint of the installed code (git SHA + newest .py mtime). Before each /model switch it compares this to the current on-disk fingerprint:

User-Facing Message

When skew is detected, the user sees:
Where <boot-short> and <disk-short> are 7-character shortened fingerprints (e.g. git SHAs or mtime: suffixes).

Fail-Open

The guard is best-effort and fail-open: if the fingerprint cannot be determined (no git, unreadable directory), the guard returns None and the /model switch proceeds normally. Normal operation is never blocked by the guard itself.

Opt-Out

Disable the guard for a session manager:

Agents

Core agent functionality

MCP Protocol

Model Context Protocol integration

Gateway CLI

CLI commands for managing the gateway

Gateway API Endpoints

OpenAI-compat and MCP HTTP endpoints on the live gateway

Relay Transport

Out-of-process platform connector relay

Bot Chat Commands

Built-in and custom slash commands for gateway bots

Slash Command Menu

Native / autocomplete for Telegram and Discord bots

Voice Notes

Automatic transcription of inbound voice messages

Run Status Controller

Transport-agnostic run-progress state machine with a stall watchdog