Give pi agents a real IM inbox/outbox through Onlyne.
pi-onlyne is the Pi extension for Onlyne. It adds tools and commands to pi so an agent can receive messages from IM channels and send replies without pretending that a chat platform is a terminal, a browser tab, or a custom workflow engine.
Onlyne is a small workspace-local IM channel daemon. It runs in your project directory, keeps its config/state under .onlyne/, and brokers local agent calls to real messaging adapters such as Telegram, Feishu/Lark, QQ Bot, and WeChat.
Onlyne is deliberately narrow:
- local workspace daemon, not a global cloud service
- channel broker, not an agent runtime
- Unix socket / stdio friendly, not a web dashboard
- local history and event stream, not a heavy message platform
pi-onlyne connects pi to an existing Onlyne workspace and exposes Onlyne as native pi tools.
Onlyne channels are singleton-routed: each enabled channel has one bind_conversation_id set in config or by sending /handshake from the desired conversation, so pi tools take channelId only.
With this extension, a pi agent can:
- watch an Onlyne workspace for inbound IM messages
- surface inbound messages into the current pi session
- reply to the current inbound message
- send a message to a channel's configured conversation
- broadcast the same message to multiple conversations
- inject a local loopback activation so background scripts can wake the session
- share Onlyne's FIFO consume cursor so
.onlyne/channels/<channel>/outdoes not re-read messages already surfaced to pi - mark an inbound message as intentionally not replied
Messages are Markdown by default, matching normal agent output. Use rawText: true only when the message must be sent literally. Onlyne can also expose FIFO IO under .onlyne/channels/<channel>/in|out; pi-onlyne stays on the socket/event API and advances the shared consume cursor after delivering inbound follow-ups.
pi install npm:pi-onlyneFor a one-off run without installing:
pi -e npm:pi-onlyneYou also need an initialized Onlyne workspace and a running workspace-local daemon:
onlyne init
onlyne run
# Optional, in another shell: refresh the workspace-local agent skill
onlyne export-skillpi-onlyne does not install launchd/systemd jobs and does not spawn a global daemon. If you want background supervision, wrap onlyne --workspace /path/to/project run yourself per workspace.
- Initialize/configure Onlyne in your project.
- Start that workspace's daemon with
onlyne run. - Install this Pi extension.
- Start watching from pi:
/onlyne watch on
When a normal user message arrives through Onlyne, pi receives it as a follow-up message. Onlyne control messages such as /handshake are consumed silently. The agent can then call onlyne_reply, or deliberately call onlyne_mark_no_reply.
/onlyne status
/onlyne watch on
/onlyne watch off
/onlyne config auto-start
/onlyne supports argument completions for status, watch on, watch off, and config auto-start.
onlyne_reply({ text })
onlyne_send({ channelId, text, rawText? })
onlyne_broadcast({ targets, text, rawText? })
onlyne_loopback({ text, rawText? })
onlyne_mark_no_reply({ reason? })
onlyne_send({
channelId: "telegram",
text: "# Build report\n\nAll checks passed."
})onlyne_send({
channelId: "telegram",
text: "# not a heading",
rawText: true
})onlyne_broadcast({
targets: [
{ channelId: "telegram" },
{ channelId: "feishu" }
],
text: "# Release shipped\n\nVersion 0.3.4 is live."
})From any local script, inject an inbound message into the current Onlyne daemon:
onlyne client '{"id":"wake","op":"loopback","text":"background job finished","raw_text":true}'
# or, with FIFO IO enabled by the daemon:
printf 'background job finished\n' > .onlyne/channels/loopback/inPi treats channel loopback as wake-up-only: it sends a follow-up to the session, but does not expect onlyne_reply.
This extension stores its own pi-side config at:
.pi/onlyne.json
Onlyne itself stores workspace state under:
.onlyne/
That keeps each project isolated: different workspaces can run different Onlyne daemons, channels, histories, and policies.
- Onlyne main repository: https://github.com/dbydd/onlyne
- pi-onlyne package: https://www.npmjs.com/package/pi-onlyne