Skip to main content
The gateway now ships in the praisonai-bot package. praisonai serve gateway still works exactly as documented here; for a standalone install see praisonai-bot Migration.
The gateway diffs gateway.yaml against the running config and restarts only affected agents or channels. The WebSocket server keeps running.
The user edits gateway.yaml on disk; the watcher diffs changes and reloads only affected agents or channels while the WebSocket server stays up.

How It Works

Quick Start

1

Run the gateway

2

Edit live

Change agent instructions or a single channel token in gateway.yaml and save. The watcher applies a selective reload within ~5 seconds (1s debounce).
3

Trigger reload manually with SIGHUP

Send SIGHUP to reload without editing a file — useful for orchestration scripts and systemd:

Event-driven vs Polling

The watcher prefers event-driven file notifications via the optional watchdog package and falls back gracefully to mtime polling when watchdog is unavailable or an observer cannot start. Both modes apply the same 1s debounce to coalesce rapid saves. Install watchdog for faster reload detection:
watchdog is optional — without it, polling continues exactly as before. Install it only when faster reaction times matter.

Operator-triggered Reload via SIGHUP

start_with_config installs a SIGHUP handler that runs the same reload_config path as a file-change reload — no shutdown, no dropped connections. Reload via SIGHUP is best-effort — it is silently skipped on platforms without SIGHUP support (e.g. Windows).

Drain-coordinated Channel Restart

When a reload triggers a channel restart, the gateway drains in-flight turns before bouncing the channel — no mid-conversation cuts. The drain window for reload-triggered restarts is controlled by a new YAML key:

Restart Scope

Full restart stops and starts all channels but does not restart the WebSocket server — connected clients stay connected.
Changing unknown_user_policy on a channel with an empty allowed_users re-fires the startup warning with the new policy’s text (PR #2856). Existing sessions are unaffected — the change applies to inbound DMs after the reload commits.

Observability

The gateway records every reload outcome so operators can confirm the last edit took effect without scraping logs. Reloads still log a concise summary line on completion:
The format is reload applied: <changed-sections>; restart[<channels>]. Grep for reload applied to trace all reloads in your log stream.

Reload status in health()

health() surfaces the reload outcome and config revisions when the gateway runs from a config file:
These four keys are additive — they only appear when the gateway runs from a config file, so existing health() consumers see no change:

ReloadStatus fields

ReloadStatus is a frozen dataclass describing the most recent reload attempt:

Compare configs offline

compute_config_revision returns the same 12-character revision id used by health(), so you can check an on-disk config before deploying it:
Identical logical configs produce identical revisions regardless of key order or whitespace; an empty or None config returns the sentinel "000000000000".

Reload observability flow

Inspect reload from the CLI

praisonai gateway status prints the reload result, watcher state, and config drift alongside the existing status:
When the running config no longer matches disk, the drift is shown with both revisions:

When config_drift is true

A drift means the config on disk has not taken effect — walk this path to recover:
The reload machinery is additive: ReloadStatus and compute_config_revision are new exports from praisonaiagents.gateway, and the existing reload applied: … log line is unchanged. Pre-existing health() consumers are unaffected.

Tuning


Backward compatibility: Leaving reload_drain_timeout unset preserves the prior immediate-restart behaviour. Not installing watchdog keeps polling as before. This is a fully additive change.

Best Practices

Changing agents.* avoids dropping live Telegram/Discord sessions.
Edit one channel block to restart only that platform.
Invalid saves are ignored — the previous config keeps running.
Add ExecReload=kill -HUP $MAINPID to your systemd unit so systemctl reload triggers a drain-coordinated reload without stopping the process.

Bot Gateway

Gateway server overview

Gateway Channel Supervision

Self-healing channels

Code-Skew Guard

Detect in-place code updates and refuse hot operations until the process restarts.

Gateway Reliability Preset

One switch to compose drain + admission control