@lalalic/channel

Transparent channel bridge for pi — Discord and WeChat. No LLM tools. Inbound plain passthrough, auto-forward responses to last active channel.

Packages

Package details

extensionskill

Install @lalalic/channel from npm and Pi will load the resources declared by the package manifest.

$ pi install npm:@lalalic/channel
Package
@lalalic/channel
Version
1.0.6
Published
Aug 27, 2026
Downloads
702/mo · 35/wk
Author
lalalic
License
MIT
Types
extension, skill
Size
96.1 KB
Dependencies
1 dependency · 3 peers
Pi manifest JSON
{
  "extensions": [
    "./channel"
  ],
  "skills": [
    "./skills"
  ]
}

Security note

Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.

README

@lalalic/channel

Transparent channel bridge for pi — Discord and WeChat. Zero LLM impact. Messages forwarded as plain user messages, responses auto-dispatched back to the last active channel.

pi install npm:@lalalic/channel
# WeChat requires wechat-bro:
npm install -g wechat-bro
# Start wechat-bro daemon:
npx wechat-bro --headed  # Show QR code first time
# Subsequent runs:
npx wechat-bro          # Headless with saved cookies

How It Works

Discord/WeChat ──→ plain user message ──→ pi session
                                            ├──→ TUI (normal)
                                            └──→ auto-forward to channel
  1. Inbound: message from channel → sent as a channel-inbound custom message — the LLM context keeps a small <channel-ctx> block (channel type, sender, DM/group, reply destination, format hints, per-channel instructions), while the TUI shows a compact type/name title plus the message body
  2. Response: LLM replies in TUI → auto-forwarded to last active channel (reply is channel-aware thanks to the context)
  3. No tools: the LLM needs no channel tools — context arrives with the message

Configuration

// .pi/settings.json
{
  "channels": [
    {
      "id": "disc-main",
      "name": "Discord Main",
      "type": "discord",
      "enabled": true,
      "channel": "123456789012345678",
      "botToken": "your-bot-token",
      "default": true
    },
    {
      "id": "wechat-me",
      "name": "My WeChat",
      "type": "wechat",
      "enabled": true,
      "channel": "filehelper"
    }
  ]
}

Channel Fields

Field Required Description
id yes Unique id
name yes Display name
type yes "discord" or "wechat"
enabled yes Connect on startup
channel yes Platform channel ID (Discord: channel ID, WeChat: contact name)
botToken discord Bot token for REST API + polling
webhookUrl discord Webhook URL for outbound-only (discord only)
forwardToolCalls optional true — tool calls/results included in forwarded responses
default optional Initial active channel
ownerUserId discord Owner user ID for multi-user asking (discord only)
instructions optional Instructions for LLM

Architecture

Current Implementation

The WeChat channel uses wechat-bro CLI commands and existing pi extensions:

pi extension
    └─ wechat.ts
        ├─ npx wechat-bro send-text (CLI commands for sending)
        └─ wechat-event-listener extension (for receiving messages)
                └─ WeChat Web (wx.qq.com)

Benefits:

  • Browser lifecycle managed by wechat-bro
  • Cookie persistence via wechat-bro (~/.wechat-bro/cookies.json)
  • Multi-agent support via wechat-bro WebSocket
  • Simplified maintenance (no direct Puppeteer access needed)

How Each Channel Works

Discord

  • Bot token + REST API (api/v10)
  • Polls every 5s for new messages
  • Auto-reacts with 👀 to acknowledge inbound
  • Responses auto-formatted via mdToDiscord (headings→bold, tables→code blocks, links→text)

WeChat (wechat-bro CLI Architecture)

  • Prerequisite: Install and start wechat-bro: npx wechat-bro --headed (first time)
  • Sending messages: Uses wechat-bro CLI commands (send-text, send-image, send-file)
  • Receiving messages: Direct WebSocket connection to wechat-bro for event streaming
  • Message filtering: Filters messages by configured contact name
  • Cookie persistence: Managed by wechat-bro (~/.wechat-bro/cookies.json)
  • Auto-reconnect: Automatically reconnects WebSocket on connection loss

Auto-reply

  • LLM responds in TUI → text captured on agent_end
  • Forwarded to lastActiveChannel (set by most recent inbound)
  • Responses ≥10 chars only

Tool Calls

When forwardToolCalls: true, the channel receives tool calls too:

[tool: read] {"path":"src/main.ts"}
→ [result: (file contents preview)]

---

Found the issue — missing import on line 42.
  • Media support: Delegates image/file upload to wechat-bro daemon
  • Multi-agent: Multiple agents can share the same wechat-bro instance
  • Multi-agent support via WebSocket
  • Event-driven message handling
  • Media upload via wechat-bro commands

Auto-reply

  • LLM responds in TUI → text captured on agent_end
  • Forwarded to lastActiveChannel (set by most recent inbound)
  • Responses ≥10 chars only

Tool Calls

When forwardToolCalls: true, the channel receives tool calls too:

[tool: read] {"path":"src/main.ts"}
→ [result: (file contents preview)]

---

Found the issue — missing import on line 42.

License

MIT