A pi extension that bridges Discord and Telegram channels to a sandboxed pi session. Each connected channel gets its own Gondolin micro-VM with persistent workspace, shared storage, memory, and skills.
# Install
pi install /path/to/pi-chat
# or
pi -e /path/to/pi-chat
# Configure accounts and channels
/chat-config
# Connect
/chat-connect
brew install qemu on macOS)tmux for multi-channel worker orchestration/chat-config → Create account → Discord/chat-config → Create account → Telegram| Command | Description |
|---|---|
/chat-config |
Configure accounts, channels, and secrets |
/chat-connect |
Connect to a configured channel |
/chat-disconnect |
Disconnect the current channel |
/chat-status |
Show connection status, model, usage, context |
/chat-list |
List configured channels |
/chat-spawn-all |
Spawn every configured channel in detached tmux/pi sessions |
/chat-spawn-all --restart |
Restart those tmux/pi sessions |
/chat-workers |
Show managed tmux/pi worker status |
/chat-open-all |
Open running workers in a tiled tmux dashboard |
/chat-kill-all |
Kill all managed tmux/pi workers |
/chat-new |
Start a new pi session, keeping the chat connection |
Workers also write status snapshots every 15 seconds under ~/.pi/agent/chat/worker-status/. The chat_workers tool exposes the same status to an orchestrating pi agent.
Users in the connected chat can send these commands (with or without mentioning the bot):
| Command | Effect |
|---|---|
stop |
Abort the current turn |
status |
Show model, usage, context stats |
compact |
Trigger context compaction |
new |
Start a new pi session |
Everything lives under ~/.pi/agent/chat/:
~/.pi/agent/chat/
├── config.json # Accounts, channels, secrets
├── cache/ # Discovery cache
└── accounts/<account>/
├── shared/ # Mounted as /shared in VM
│ ├── memory.md # Account-wide persistent memory
│ └── skills/ # Account-wide skills
└── channels/<channel>/
├── channel.jsonl # Chat log
├── .lock # Runtime lock
├── workspace/ # Mounted as /workspace in VM
│ ├── memory.md # Channel-specific persistent memory
│ ├── skills/ # Channel-specific skills
│ ├── incoming/ # Downloaded attachments
│ ├── .secrets/ # Encrypted secrets
│ └── SYSTEM.md # Environment modification log
└── gondolin/ # VM state
└── session.json
Each connection starts a Gondolin micro-VM with:
/workspace → channel workspace directory/shared → account shared directoryread, write, edit, bashThe agent sees /workspace as its working directory.
Two persistent memory files, injected into the system prompt on every turn:
| File | VM Path | Scope |
|---|---|---|
| Account memory | /shared/memory.md |
Shared across all channels for this account |
| Channel memory | /workspace/memory.md |
Specific to this channel |
The agent is instructed to write durable facts and preferences to these files when asked to remember something. Account-wide goes to /shared/memory.md, channel-specific to /workspace/memory.md.
The agent can create reusable tools as skills, following the Agent Skills standard:
/shared/skills//workspace/skills/A skill is either a single .md file (e.g. skills/foo.md) or a directory with SKILL.md plus supporting files (e.g. skills/foo/SKILL.md, skills/foo/run.sh).
Each skill needs YAML frontmatter:
---
name: skill-name
description: Short description of what this skill does
---
Skills are automatically discovered and listed in the system prompt. The agent reads the full skill file before using it.
Configure secrets at three levels via /chat-config:
Each secret has a value and allowed host patterns. Gondolin replaces placeholder env vars with real values only for outbound HTTP requests to allowed hosts. The agent never sees the real secret value.
For credentials the agent needs at runtime (API keys for skills, OAuth files, etc.):
chat_request_secret toolpi.dev/secret is sent to the chat with an embedded public key/workspace/.secrets/<name>The encrypted blob is useless without the ephemeral private key held in pi-chat's memory.
| Tool | Description |
|---|---|
read |
Read files (routed through Gondolin VM) |
write |
Create/overwrite files |
edit |
Precise in-place edits |
bash |
Execute commands (runs /bin/bash in the VM) |
chat_history |
Search older messages from the chat log |
chat_attach |
Queue files to send with the next reply |
chat_request_secret |
Request a secret from the user via encrypted exchange |
pi-chat includes vendored/adapted logic inspired by Vercel Chat SDK (MIT):
src/render/format.tssrc/render/streaming-markdown.tssrc/render/streaming.tsMIT
$ claude mcp add pi-chat \
-- python -m otcore.mcp_server <graph>