Skip to main content

pi-gateway

Telegram gateway for persistent Pi coding-agent sessions.

The gateway is a long-running process. Telegram conversations are mapped to Pi JSONL session files in SQLite, while Pi remains the source of truth for agent history.

Documentation

See docs/ for architecture, startup flow, Telegram gateway internals, Pi RPC integration, session mapping, deployment, and troubleshooting notes.

Install with uv

Directly from GitHub (no clone needed):

uv tool install git+https://github.com/alejandro-ao/pi-gateway.git

Install a specific tag or branch:

uv tool install git+https://github.com/alejandro-ao/pi-gateway.git@v0.2.1

Upgrade later:

uv tool install --force git+https://github.com/alejandro-ao/pi-gateway.git
# or
uv tool upgrade pi-gateway

From a local checkout:

uv tool install .

Or for development:

uv sync
uv run pi-gateway --help
uv run ruff check .
uv run mypy pi_gateway tests
uv run pytest -q

Pi must already be installed and authenticated on the machine as the same user that runs the gateway.

Configure Telegram

Create an instance in the directory where Pi should work:

mkdir -p ~/bots/my-bot && cd ~/bots/my-bot
pi-gateway init

init prompts for Telegram setup and writes .pi-gateway/config.yaml. The bot's SQLite database, PID and log also live under .pi-gateway/; add .pi-gateway/ to your project's .gitignore (config may contain a bot token). pi-gateway configure telegram creates/updates the local config as well. Commands in this directory automatically select it; -c <config-path> always overrides discovery. Existing ~/.config/pi-gateway/config.yaml installations remain usable when no local instance exists.

Set a distinct bot token and allowed user ID for each instance. Each bot needs its own token. For separate global Pi skills/auth, use pi-gateway init --pi-agent-dir /path/to/agent-dir and authenticate Pi in that agent directory; otherwise Pi uses the OS user's shared agent directory. Project-local skills follow the configured Pi working directory. For an interactive update:

pi-gateway configure telegram

It will ask for your BotFather token, your allowed Telegram user id, the Pi working directory, and optionally a Pi model and thinking level. Leave the model and thinking prompts blank to use Pi's defaults; when updating an existing config, blank keeps the current selections. Run pi --list-models to see model IDs (listed models may still require authentication).

You can also configure non-interactively:

pi-gateway configure telegram \
  --allowed-user-id YOUR_TELEGRAM_USER_ID \
  --pi-cwd /home/agent/pi-workspace \
  --model anthropic/claude-sonnet-4-5 \
  --thinking high

pi-gateway init accepts the same --model and --thinking flags. Model IDs may contain additional / characters (for example, huggingface/org/model-id); the first part is the provider. Thinking levels: off, minimal, low, medium, high, xhigh, max. Omitted flags leave existing settings unchanged. The defaults are stored per gateway in .pi-gateway/config.yaml (or your explicit -c file) as pi.defaultProvider, pi.defaultModel, and pi.defaultThinking; they apply to new Pi RPC processes. Existing Pi sessions can have their own model/thinking settings; use Telegram /model and /thinking for an active session. Restart a running gateway to pick up config edits.

By default the bot token can be read from TELEGRAM_BOT_TOKEN. You can also write it into the config:

pi-gateway configure telegram \
  --bot-token '123:abc' \
  --allowed-user-id YOUR_TELEGRAM_USER_ID \
  --pi-cwd /home/agent/pi-workspace

Security note: --allowed-user-id writes a single allowlisted Telegram user id. Messages from other users are ignored. Group chats are disabled unless you pass --allow-groups.

Print the installed version:

pi-gateway --version

Print the default config path:

pi-gateway config-path

You can still maintain config manually; see examples/config.yaml.

Run

Foreground mode, useful for debugging or systemd:

export TELEGRAM_BOT_TOKEN=123:abc
pi-gateway run

Background mode, useful for a simple VPS setup without systemd:

pi-gateway start
pi-gateway status
pi-gateway logs -f
pi-gateway stop

Repeat init and start in other directories to run multiple bots concurrently. From anywhere, use pi-gateway instances to list initialized bots and pi-gateway -i ~/bots/my-bot status|start|stop|logs to manage one. The -i option expects an initialized bot directory; -c takes precedence if both are given. For production, use one systemd service per bot with its working directory set to the bot directory.

start writes logs to:

.pi-gateway/pi-gateway.log (local instances) or ~/.local/state/pi-gateway/pi-gateway.log (legacy config)

With an explicit config (including two bots sharing one Pi working directory):

pi-gateway -c a.yaml start
pi-gateway -c b.yaml start
pi-gateway -c a.yaml stop
pi-gateway -c config.yaml start
pi-gateway -c config.yaml run
# or
pi-gateway run -c config.yaml

Nonstandard -c configs use separate PID, log, and default SQLite paths derived from their absolute config paths, even when they live in the same directory. Set distinct Telegram tokens. Explicit databasePath values in YAML are respected; choose different ones per bot. Moving a config changes its derived paths, so move its database or set databasePath explicitly if you need its history. If you previously ran an explicit -c config without databasePath, set databasePath to the old pi-gateway.sqlite3 file before upgrading to retain its conversation mappings.

Development checkout:

uv run pi-gateway run

Telegram commands

  • /status current Pi session/model/stats
  • /new fresh Pi session for this Telegram chat
  • /name <name> name current Pi session
  • /compact [instructions] compact current Pi context
  • /stop abort current Pi operation
  • /last resend last assistant response
  • /export export current session to HTML
  • /sessions list known sessions
  • /switch <id> point this chat at another known Pi session
  • /clone clone current branch into a new session
  • /models list available models
  • /model <provider/model-id> switch model
  • /thinking <level> set thinking level
  • /queue <text> queue follow-up
  • /steer <text> steer current/next turn
  • /pi <text> send raw text to Pi, including Pi slash commands

Normal Telegram messages are sent to Pi as prompts.

Session mapping

Gateway key:

telegram:<chat_id>:<thread_id?>:<user_id?>

SQLite stores that key plus Pi's sessionId and sessionFile. On restart the gateway resumes with:

pi --mode rpc --session <stored-session-file>

systemd

See systemd/pi-gateway.service and adjust paths/user/env.

Example with uv tool install:

[Service]
User=agent
Environment=TELEGRAM_BOT_TOKEN=123:abc
ExecStart=/home/agent/.local/bin/pi-gateway run
Restart=always

Metadata

Release files for pi-gateway 0.2.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pi-gateway 0.2.1
File Size Uploaded
pi_gateway-0.2.1.tar.gz 65.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for pi-gateway 0.2.1
File Interpreter ABI Platform
pi_gateway-0.2.1-py3-none-any.whl Python 3 none any Details

Total release size: 89.6 kB

Release files / pi_gateway-0.2.1.tar.gz

Download URL pi_gateway-0.2.1.tar.gz
Size 65.2 kB
Tags Source
SHA-256 checksum
How to use checksums
f2e9a8f4ce32669d4ef7e30460c4d0099f6abc2599bba024dac5683f56a7b061
BLAKE2b-256 checksum
How to use checksums
698f5810f8bb5967d5898f101855ce49d92916d189cc3ee56efd83ddcf498793
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.21 {"installer":{"name":"uv","version":"0.12.21","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / pi_gateway-0.2.1-py3-none-any.whl

Download URL pi_gateway-0.2.1-py3-none-any.whl
Size 24.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
6427d25048e468cbc508fcd32aba9812b437da38c073c111ffd15921c4ce6ad2
BLAKE2b-256 checksum
How to use checksums
3cfa5899d255c586b1e2f02bc0e67b48bf51fb8b1f0fa11c6ab426730020883c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.21 {"installer":{"name":"uv","version":"0.12.21","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release history Release notifications | RSS feed

0.2.2

2 release files

This release

0.2.1 This release

2 release files

0.2.0

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page