Gateway Windows Deployment
Complete guide for deploying PraisonAI Gateway on Windows with multi-channel bots
from praisonaiagents import Agent
agent = Agent(name="windows-agent", instructions="Deploy the gateway on Windows.")
agent.start("Deploy and start the gateway service on Windows Server.")Deploy the PraisonAI Gateway on Windows with multiple Telegram bots, proper encoding, and production-ready configuration.
# After UTF-8 env setup (see below), start the gateway from your config
praisonai gateway start --config gateway.yamlThe user runs the gateway on Windows; deployment settings handle paths, services, and encoding.
How It Works
Deployment Steps
graph TB
subgraph "Windows Environment Setup"
subgraph "Step 1: Dependencies"
PY[🐍 Python 3.9+]
PKG[📦 praisonai[bot,api]]
ENV[🔧 UTF-8 Environment]
end
subgraph "Step 2: Configuration"
YML[📄 gateway.yaml]
ENVF[🔐 .env file]
TOK[🔑 Bot Tokens]
end
subgraph "Step 3: Deployment"
GW[🌐 Gateway Process]
HEALTH[💚 Health Check]
LOGS[📋 Monitoring]
end
end
PY --> PKG
PKG --> ENV
ENV --> YML
YML --> ENVF
ENVF --> TOK
TOK --> GW
GW --> HEALTH
HEALTH --> LOGS
classDef setup fill:#6366F1,stroke:#7C90A0,color:#fff
classDef config fill:#F59E0B,stroke:#7C90A0,color:#fff
classDef deploy fill:#10B981,stroke:#7C90A0,color:#fff
class PY,PKG,ENV setup
class YML,ENVF,TOK config
class GW,HEALTH,LOGS deployQuick Start
- Install Dependencies
Install Python dependencies with both extras required for gateway:
powershell pip install "praisonai[bot,api]"Why both extras are needed:
Extra Provides Required For [bot]python-telegram-bot, discord.py, slack SDKs Platform integrations [api]uvicorn, fastapi, starlette Gateway HTTP/WebSocket server [all]Both + search tools + storage backends Complete installation Without
[api]you’ll get:ImportError: Gateway requires starlette and uvicorn. Install with: pip install praisonai[api] - Configure Windows UTF-8
Mandatory for Windows gateway deployments:
powershell $env:PYTHONUTF8 = "1" # Alternative: $env:PYTHONIOENCODING = "utf-8"Why this is required:
Without UTF-8 configuration, you’ll see encoding errors:
Error: 'charmap' codec can't encode character '\u26a0' in position 1: character maps to <undefined>This often appears after API failures (OpenAI 429 quota exceeded). Fix billing first, then encoding.
- Create Gateway Configuration
Create
gateway.yaml:yaml gateway: host: "127.0.0.1" port: 8765 agents: assistant: model: gpt-4o-mini instructions: "You are a helpful AI assistant." tools: [search_knowledge] channels: telegram: platform: telegram token: ${TELEGRAM_BOT_TOKEN} routes: default: assistantCreate
.envfile:env TELEGRAM_BOT_TOKEN=your_bot_token_here OPENAI_API_KEY=${OPENAI_API_KEY:?Set OPENAI_API_KEY in your shell} GATEWAY_AUTH_TOKEN=optional_auth_token PYTHONUTF8=1 - Start Gateway
Launch the gateway with configuration:
powershell praisonai gateway start --config gateway.yamlExpected output:
Gateway starting (host=127.0.0.1 port=8765 config=gateway.yaml agents=-) Loading gateway config from gateway.yaml Starting gateway on ws://127.0.0.1:8765 Press Ctrl+C to stop
Windows-Specific Configuration
Environment Variables
Windows PowerShell environment setup:
# Session variables (temporary)
$env:TELEGRAM_BOT_TOKEN = "123456:ABC-DEF1234"
$env:OPENAI_API_KEY = "sk-..."
$env:PYTHONUTF8 = "1"
# Persistent variables (permanent)
[Environment]::SetEnvironmentVariable("PYTHONUTF8", "1", "User")
[Environment]::SetEnvironmentVariable("TELEGRAM_BOT_TOKEN", "123456:ABC-DEF1234", "User")UTF-8 Encoding Setup
Three ways to configure UTF-8 on Windows:
Environment Variable
$env:PYTHONUTF8 = "1"Recommended approach – works for current session.
System Environment
[Environment]::SetEnvironmentVariable("PYTHONUTF8", "1", "Machine")System-wide setting – requires admin privileges.
Per-Process
$env:PYTHONIOENCODING = "utf-8"Alternative encoding setting.
Windows Service Installation
For production deployment as Windows service:
# Install NSSM (Non-Sucking Service Manager)
choco install nssm
# Create service
nssm install PraisonAIGateway "C:\Python\python.exe"
nssm set PraisonAIGateway Arguments "-m praisonai gateway start --config C:\PraisonAI\gateway.yaml"
nssm set PraisonAIGateway AppDirectory "C:\PraisonAI"
nssm set PraisonAIGateway AppEnvironmentExtra "PYTHONUTF8=1"
# Start service
sc start PraisonAIGatewayMulti-Channel Windows Setup
Hermes-Style Workforce Example
Complete gateway.yaml for 3-bot Hermes workforce:
gateway:
host: "127.0.0.1"
port: 8765
agents:
cfo:
model: gpt-4o-mini
instructions: "You are a CFO assistant. Help with financial analysis and reporting."
tools: [search_knowledge]
ops:
model: gpt-4o-mini
instructions: "You are an operations assistant. Help with process optimization."
tools: [search_knowledge]
content:
model: gpt-4o-mini
instructions: "You are a content assistant. Help with writing and marketing."
tools: [search_knowledge]
channels:
telegram_cfo:
platform: telegram
token: ${TELEGRAM_CFO_TOKEN}
routes:
default: cfo
telegram_ops:
platform: telegram
token: ${TELEGRAM_OPS_TOKEN}
routes:
default: ops
telegram_content:
platform: telegram
token: ${TELEGRAM_CONTENT_TOKEN}
routes:
default: contentMatching .env file:
# Bot tokens - create 3 separate bots in @BotFather
TELEGRAM_CFO_TOKEN=<cfo-bot-token-from-botfather>
TELEGRAM_OPS_TOKEN=<ops-bot-token-from-botfather>
TELEGRAM_CONTENT_TOKEN=<content-bot-token-from-botfather>
# API keys
OPENAI_API_KEY=<your-openai-key>
GATEWAY_AUTH_TOKEN=<optional-auth-token>
# Windows UTF-8 setup
PYTHONUTF8=1
PYTHONIOENCODING=utf-8Creating Multiple Telegram Bots
Important: Each channel needs its own Telegram bot token.
- Create CFO Bot:
- Message @BotFather
/newbot- Name: “CFO Assistant Bot”
- Username: “your_company_cfo_bot”
- Save token as
TELEGRAM_CFO_TOKEN
- Create Ops Bot:
/newbot(same BotFather)- Name: “Operations Assistant Bot”
- Username: “your_company_ops_bot”
- Save token as
TELEGRAM_OPS_TOKEN
- Create Content Bot:
/newbot(same BotFather)- Name: “Content Assistant Bot”
- Username: “your_company_content_bot”
- Save token as
TELEGRAM_CONTENT_TOKEN
Never reuse tokens – each bot must be separate.
Health Monitoring
Health Check Commands
Monitor gateway status:
# PowerShell health check
Invoke-RestMethod -Uri "http://127.0.0.1:8765/health"
# Using curl (if installed)
curl http://127.0.0.1:8765/health
# Using Python
python -c "import urllib.request, json; print(json.loads(urllib.request.urlopen('http://127.0.0.1:8765/health').read()))"Expected healthy response:
{
"status": "healthy",
"uptime": 3600.5,
"agents": 3,
"sessions": 12,
"clients": 8,
"channels": {
"telegram_cfo": { "platform": "telegram", "running": true },
"telegram_ops": { "platform": "telegram", "running": true },
"telegram_content": { "platform": "telegram", "running": true }
}
}Process Management
Check running gateway processes:
# Find gateway processes
Get-Process | Where-Object {$_.ProcessName -match "python" -and $_.MainWindowTitle -match "gateway"}
# Alternative: check port usage
netstat -ano | findstr ":8765"
# Kill gateway processes if needed
taskkill /F /IM python.exe /FI "WINDOWTITLE eq *gateway*"Security Configuration
User Access Control
Configure allowed users to prevent unauthorized access:
# In gateway.yaml
channels:
telegram_cfo:
platform: telegram
token: ${TELEGRAM_CFO_TOKEN}
allowed_users: ${TELEGRAM_ALLOWED_USERS}
routes:
default: cfo.env configuration:
TELEGRAM_ALLOWED_USERS=123456789,987654321,555666777Security caveat: Current gateway Telegram polling path may not enforce allowlist until PraisonAI security fix ships. Verify access control after update.
Token Security
Secure token storage on Windows:
# Use Windows Credential Manager (recommended)
cmdkey /add:TELEGRAM_BOT_TOKEN /user:praisonai /pass:"123456:ABC-DEF"
# Retrieve token in script
$token = cmdkey /list:TELEGRAM_BOT_TOKEN
# Encrypted environment file
# Use tools like sops or age for productionTroubleshooting Windows Issues
Common Windows Errors
gateway install fails: 'startup folder path still contains an unexpanded variable'
Symptoms:
Scheduled Task install path raises a RuntimeError:
startup folder path still contains an unexpanded variable
('%APPDATA%\Microsoft\Windows\Start Menu\Programs\Startup'); refusing to create it.Startup-folder fallback path returns {"ok": False, "error": "..."}:
startup folder path still contains an unexpanded variable
('%APPDATA%\Microsoft\Windows\Start Menu\Programs\Startup'); refusing to create it.
This happens off Windows, or when APPDATA is unset.Cause: APPDATA is not set in the current shell. This is normal on macOS/Linux, common in WSL where APPDATA isn’t inherited from the Windows host, and can happen inside containerised CI runners. The autostart installer expands %APPDATA%\Microsoft\Windows\Start Menu\Programs\Startup; with APPDATA unset the variable stays literal, so the installer refuses rather than write a stray path.
Solutions:
- On native Windows, verify APPDATA is set
powershell # cmd echo %APPDATA% # PowerShell $env:APPDATAIf empty, log out and back in, or set it explicitly to
C:\Users\<user>\AppData\Roaming. - Off Windows, use the native autostart mechanism
The Scheduled Task and Startup-folder mechanisms are Windows-only. Use
launchd(macOS) orsystemd --user(Linux) instead — see Platform-Specific Notes. - Clean up a stray directory from an older install
Installs that ran before PR #4996 could silently create a directory named
%APPDATA%\Microsoft\...in the working tree. Check for it and remove it:bash git statusOn Windows this is an invalid path that breaks
actions/checkoutif committed. Delete it if found.
charmap codec error
Symptoms:
Error: 'charmap' codec can't encode character '\u26a0' in position 1: character maps to <undefined>Causes:
- Missing UTF-8 environment configuration
- OpenAI API failure (429 quota) + encoding issue
Solutions:
# Set UTF-8 environment
$env:PYTHONUTF8 = "1"
# Check OpenAI billing
# Visit platform.openai.com/billing
# Restart gateway after both fixesgateway status PID-lock line (PID lock status: Unavailable)
Symptoms:
PID lock status: Unavailable (kill returned a result with an exception set)
Gateway Status: healthyCause: On Windows, os.kill(pid, 0) can raise SystemError. From PraisonAI ≥ v4.6.141 the message is advisory only — the /health probe still runs and shows the real gateway status.
POSIX behaviour (since PR #4197): On Linux/macOS, os.kill(pid, 0) raising PermissionError — a gateway owned by another user — is now treated as running rather than silently swallowed. The lock is preserved and a second gateway is refused, instead of the foreign-uid gateway being displaced.
Solution:
# Confirm the gateway is up regardless of the PID-lock line
curl http://127.0.0.1:8765/healthSee Windows: gateway status shows PID lock status: Unavailable and PraisonAI #2844 / PR #2849 for the underlying cause.
ImportError: Gateway requires starlette
Error:
ImportError: Gateway requires starlette and uvicorn.
Install with: pip install praisonai[api]Solution:
pip uninstall praisonai
pip install "praisonai[bot,api]"Bot stops responding (409 Conflict)
Symptoms:
- Bot works initially, then stops mid-session
- Log shows:
Conflict: terminated by other getUpdates request - Health check still shows
"running": true
Cause: Duplicate gateway processes polling same token
- Since PR #4197, the cross-uid cause of this conflict is removed on POSIX: a gateway owned by another user is now treated as running, so its lock is preserved and a second gateway is refused instead of being started on the same token.
Solution:
# Stop all gateway processes
Get-Process | Where-Object {$_.ProcessName -match "python"} | Stop-Process -Force
# Verify port is free
netstat -ano | findstr ":8765"
# Start single gateway instance
praisonai gateway start --config gateway.yamlError starting gateway: invalid attr name 'connections' (psutil 7)
Symptom:
Error starting gateway: invalid attr name 'connections'on praisonai gateway start with a busy port on psutil ≥ 6.
Cause: Older versions used the removed Process.connections attribute to identify the process holding the port.
Fix: PR #4197 switches to net_connections() (with a connections() fallback) and wraps the lookup so a diagnostic can never break startup. Upgrade praisonai-bot to the merged version — the friendly port-collision message (Another gateway may be running (PID ...). Stop it: praisonai gateway stop) renders again.
25-30 second response delay
Symptoms:
- Telegram typing indicator disappears after 5 seconds
- Reply comes 20-30 seconds later
- No error messages
Explanation: This is normal behavior for RAG + LLM processing.
User guidelines:
- Do not send duplicate messages during wait
- Do not restart gateway during response window
- Typing indicator renewal fix is pending in PraisonAI
gateway install fails: 'startup folder path still contains an unexpanded variable'
Symptoms:
Scheduled Task path — raised as a RuntimeError from install():
startup folder path still contains an unexpanded variable
('%APPDATA%\Microsoft\Windows\Start Menu\Programs\Startup'); refusing to create it.Startup-folder fallback path — returned in install()‘s aggregated result as {"ok": False, "error": "..."}:
startup folder path still contains an unexpanded variable
('%APPDATA%\Microsoft\Windows\Start Menu\Programs\Startup'); refusing to create it.
This happens off Windows, or when APPDATA is unset.Cause: APPDATA is not set in the current shell. The autostart installer builds the Startup-folder path from %APPDATA%\Microsoft\Windows\Start Menu\Programs\Startup, and %APPDATA% only expands on Windows with the variable set. This is the norm on macOS/Linux, common in WSL where APPDATA isn’t inherited from the Windows host, and can happen inside containerised CI runners.
Solution:
- On native Windows, verify APPDATA is set
powershell # PowerShell $env:APPDATA # cmd echo %APPDATA%If empty, log out and back in, or set it explicitly to
C:\Users\<user>\AppData\Roaming. - Off Windows, use the native autostart mechanism
The Scheduled Task and Startup-folder mechanisms are Windows-only. Do not run
praisonai gateway installon macOS/Linux — uselaunchd(macOS) orsystemd --user(Linux) instead. See Platform-Specific Notes. - Clean up a stray directory from a pre-fix install
An install that ran before PR #4996 may have created a literal directory named
%APPDATA%\Microsoft\...in the working tree. On Windows this is an invalid path that breaksactions/checkoutif committed.powershell git status git clean -fdn # preview; drop -n to delete
Behaviour since PR #4996: rather than silently creating a %APPDATA%\Microsoft\... directory in the current working directory, the installer now refuses cleanly and writes nothing.
Windows-Specific Debugging
Enable detailed logging:
# Set debug environment
$env:PRAISONAI_LOG_LEVEL = "DEBUG"
# Start with verbose output
praisonai gateway start --config gateway.yaml --verbose
# View logs
Get-Content ~/.praisonai/logs/gateway.log -Tail 50 -WaitCheck Windows firewall:
# Allow Python through firewall
New-NetFirewallRule -DisplayName "PraisonAI Gateway" -Direction Inbound -Protocol TCP -LocalPort 8765 -Action Allow
# Test connectivity
Test-NetConnection -ComputerName 127.0.0.1 -Port 8765Performance Optimization
Windows Resource Configuration
Optimize for Windows deployment:
# gateway.yaml - Windows optimizations
gateway:
host: "127.0.0.1"
port: 8765
max_connections: 50 # Lower for Windows
worker_processes: 1 # Single process on Windows
keep_alive_timeout: 30
client_timeout: 120
# Environment variables for performance
UVICORN_WORKERS=1
UVICORN_KEEP_ALIVE=30
PRAISONAI_CACHE_SIZE=1000PowerShell performance script:
# Optimize Python process priority
$proc = Get-Process | Where-Object {$_.ProcessName -eq "python" -and $_.MainWindowTitle -match "gateway"}
$proc.PriorityClass = "High"
# Set power plan to high performance
powercfg /setactive 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635cProduction Deployment
Windows Server Configuration
For production Windows Server deployment:
# Install as Windows Service
sc create "PraisonAI Gateway" binPath="C:\Python\python.exe -m praisonai gateway start --config C:\PraisonAI\gateway.yaml"
sc config "PraisonAI Gateway" start=auto
sc description "PraisonAI Gateway" "PraisonAI Multi-Channel Bot Gateway"
# Configure service recovery
sc failure "PraisonAI Gateway" reset=86400 actions=restart/30000/restart/60000/restart/60000
# Start service
sc start "PraisonAI Gateway"IIS reverse proxy (optional):
<!-- web.config for IIS reverse proxy -->
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="Gateway WebSocket" stopProcessing="true">
<match url="ws" />
<action type="Rewrite" url="http://127.0.0.1:8765/ws" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>Best Practices
Use Windows Task Scheduler for monitoring
Create monitoring task:
# Create health check script
@'
$response = Invoke-RestMethod -Uri "http://127.0.0.1:8765/health" -ErrorAction SilentlyContinue
if ($response.status -ne "healthy") {
Restart-Service "PraisonAI Gateway"
Write-EventLog -LogName Application -Source "PraisonAI" -EventID 1001 -Message "Gateway restarted"
}
'@ | Out-File -FilePath C:\PraisonAI\health-check.ps1
# Schedule every 5 minutes
schtasks /create /sc minute /mo 5 /tn "PraisonAI Health Check" /tr "powershell.exe C:\PraisonAI\health-check.ps1"Configure Windows Event Logging
Enable application logging:
# Create event source
New-EventLog -LogName Application -Source "PraisonAI Gateway"
# Log gateway events
Write-EventLog -LogName Application -Source "PraisonAI Gateway" -EventID 1000 -Message "Gateway started successfully"Use Windows Subsystem for Linux (WSL) alternative
For development, consider WSL:
# In WSL Ubuntu
sudo apt update && sudo apt install python3-pip
pip3 install "praisonai[bot,api]"
# UTF-8 is default in WSL
praisonai gateway start --config gateway.yamlThis avoids Windows-specific encoding issues during development.
Related
See Command-Aware Permissions → Windows / PowerShell dialect for how PraisonAI gates PowerShell/cmd commands under your permission rules.