ConnectOnionConnectOnion

1.8.8b5 — one conversation on two devices, and a sweep of the CLI

An opt-in preview. Stable remains 1.8.7.

One conversation, open on a laptop and a phone at once

Opening a conversation on a second device used to fail with Session is already attached to another connection (#1606). The refusal came from the relay, but the rule behind it was in every layer: the protocol defined a session as a connection, and the Host streamed a turn only to the socket that sent the prompt. Now the session is the Host's, and every connection to it is a viewer:

  • a turn started on one device streams to the owner's other devices, each reading it from its own position, with the prompt first as user_message;
  • any device can answer an approval or stop the turn, whichever started it;
  • through the relay, each client socket gets its own conn_id — the agent declares it understands that inside its signed ANNOUNCE — and the Host, not the relay, decides who may read what.

"The same person" means the same identity: import your recovery phrase on the second device. A different identity naming the session id is given its own session and sees nothing, as before (#696).

The refusal was also hiding a bug that lost work. When a device reconnected, the Host kept whichever copy of the conversation had more LLM calls in its last turn — a count that restarts every turn — so going back to the laptop after a turn on the phone could erase the phone's turn. The merge now compares turns first.

Verified live with scripts/two_device_acceptance.py, which starts a real Host and drives three signed clients (two sharing an identity, one not) directly and through the production relay; all eight properties pass on both paths.

This needs the relay from oo-api v0.1.19 (deployed) and, for the web client to show the other device's question, @connectonion/react 0.4.4-rc.5.

The CLI sweep

  • co ai logs a refused command in full — the truncated call line had cut off | head -40, the part that was refused — and answers a call to a tool that does not exist with the tools that do, so the model stops retrying it (#1493, #1292). Includes a contribution from @521Peter (#1519).
  • co browser close snapshots the daemon's process tree before closing, waits at most a minute, stops anything it left running — Chrome sits in its own process group, so a hung daemon used to orphan a paid, still-billing browser — and exits 1 naming it (#1496). status no longer calls an ended paid session open (#1457); an explicit --no-headless with no display is refused instead of silently launching HeadlessChrome (#1339); a cron job finds the daemon a login shell started (#1475); the busy-tab note says this tab, and how to open your own (#1605).
  • co proxy diagnose lists every endpoint the relay announces for the host with how each answered, and says "usually a cloud firewall" when all time out (#1387). co deploy --to keeps a connectonion build the project's requirements.txt names and prints which version ended up on the server (#1375).
  • co whatsapp react <id> <emoji> reacts to anyone's message (#1633), and co whatsapp group create / group add report every number's outcome — added, invite-only, no account, or not confirmed — instead of trusting a success WhatsApp gives even when someone was left out (#1617).

Known limits

  • When one device answers an approval, the other device's dialog stays open until the turn moves on; resolution is not broadcast yet.
  • A native Codex/Claude Code Work Room turn does not fan out to other devices; ordinary agent turns do.
  • co whatsapp group and react were tested against the SDK's types, not on a live account (creating a group adds real people). A listener started before this version must be restarted to handle them.
  • On Windows, co browser close checks for leftover processes only when psutil is installed; otherwise it keeps its old behaviour.
  • Left for a decision rather than guessed at: co ai slash commands (#965), which co commands an unattended run may call (#1293), a busy daemon's status (#1473), adopting an existing deployment (#1505), and scheduled Gmail sends (#934).
python -m pip install --upgrade --pre 'connectonion==1.8.8b5'
co --version

View Markdown source

Star us on GitHub

If ConnectOnion saves you time, a ⭐ goes a long way — and earns you a coffee chat with our founder.