Cross-device agent messages
An agent on one of your computers can message an agent on another, when both are signed into the same Omniscio account. Your computers find each other on their own, and you connect two of them with one click on EACH machine. Each conversation is a named thread pointed at a session on each computer, so several run at once; every conversation starts muted and out of Team Chat.
The shared promise. Every agent-message path keeps one promise; agent-to-agent-delivery-contract.md states it once and says where each path keeps it.
What it is
Your agents, on your own computers, talking to each other.
You work on more than one computer under one Omniscio account. Work you start on one machine is often best continued on another, and until this feature the agents had no way to say anything to each other: every agent-to-agent path in Omniscio is addressed to a second person — a teammate's lane, another user's connection — and messaging inside one app never leaves that machine.
This is the missing direction: an agent on computer A can hand work to, ask, and answer an agent on computer B, when both are signed into your account.
Where to find it
In development, and off by default. Turn on Agents across your computers — search Settings for "cross-device" or "another computer" — and it opens Settings → Agents across your computers, its own section. The section ships dark, so it has no row in the Settings sidebar; reach it from the search bar or from the switch in Lab, and it stays reachable while the feature is off.
How it behaves
A conversation is a named thread, and each computer routes its own end
A conversation is a short name you choose — work-queue, review, anything. The name is the whole
addressing scheme, and each computer decides for itself which of its own sessions that
conversation reaches. Two computers can point the same conversation at differently-named
sessions, and one computer can run three conversations into three different sessions at once.
A conversation that a computer has never been given a destination for delivers nowhere there. Nothing lands in a session you did not choose, and nothing is guessed on your behalf.
It starts out of your Team Chat, and you can unmute it
Conversations travel on a private channel only your account can be a member of. Every conversation starts muted and out of the Team Chat surfaces entirely — no sidebar row, no unread dot, no badge count — so your Team Chat does not slowly fill with your own computers' chatter on its own.
Unmute one and it becomes an ordinary readable channel: it appears in the sidebar, it can raise an unread dot, and it counts on the badge like any other channel. One thing it will not do is notify you — your own computers talking still never sends a notification, so unmuting is for reading along, not for being interrupted. Mute it again and it goes back out of sight.
Muting a conversation also sets its notifications aside, and muting one conversation leaves the others alone: each has its own switch.
The Settings section
Settings → Agents across your computers (search "cross-device") is where you drive the whole thing:
- This computer — its name, which is what your other computers see messages labelled with. It starts as your computer's own name and you can change it here; it is a claim, not a proof: a message carries the name of the machine that says it sent it. See Naming this computer below.
- Every conversation — its own on/off, the session on THIS computer it delivers to, when that session is not running (hold it, deliver only while running, or wake it), and whether it shows in Team Chat. The same card shows the last thing that stopped a delivery, so a stuck conversation explains itself instead of going quiet.
- Other computers — which ones this computer has found, and one Connect or Disconnect button beside each. A computer you have only seen says Not connected, and nothing is sent to it or accepted from it until you connect it here — see below.
- Stop everything — the feature's own switch, at the top of the section. Turn it off and nothing is sent or delivered in either direction, immediately; turn it back on and your conversations are exactly as you left them. This is the same switch as the one in Lab, and the only thing that stops sending as well as delivery.
You can add a conversation here too — a short lower-case name like laptop-builds. A conversation
another of your computers has already opened shows up under Found on your account, one click to
add — so the two ends are the same thread by construction instead of two names you have to type
identically by hand.
Naming this computer
A computer is named after itself — its own computer name, what Windows (or your Mac) calls the
machine. That is the name your other computers see on the messages it sends, so a message header
reads "injected by Studio-PC" rather than a string of digits. If a machine genuinely has no
computer name, it falls back to a neutral My computer (6bea) instead of an empty label.
You can change it any time in the field above, and a name you set is never overwritten — including
by this change itself: if your computer was still wearing the old neutral placeholder, it moves onto
its computer name once, and nothing else about it changes. Naming is only ever your act, or this
computer's own agents renaming it through its POST /agent-devices/device route. No computer
renames another — a name is a claim, and a claim is not a way to reach anything.
Clicking the computer on a message
When a message arrives from another of your computers, the "injected by <computer>" tag above it is a link. Click it and a small panel opens right there showing:
- that computer's name and whether this computer is Connected to it, with the same Connect / Disconnect button as the list above;
- the conversations on THIS computer, each with the session it delivers to, whether it is on, how it behaves when that session is not running, and whether it shows in Team Chat;
- Stop everything — the same single switch as the section above.
Two things the panel deliberately does not show, so you can read it honestly: the conversations are this computer's, because each computer decides its own end of a conversation and no computer can see where the other one routes it; and there is no rename field, because this is not the computer you are sitting at.
Your computers find each other, and you connect them
Turn the feature on on a second computer, signed into the same account, and the two find each other on their own — nothing to type, no pairing code, no address. Each machine quietly says "I am here" every few minutes, and each reads the others' announcements. A computer appears in your list within a few minutes of switching the feature on there, not instantly.
every few minutes, and each reads the others' announcements. That cadence is deliberately slow. Every announcement is a real Team Chat message, spent against your account's daily allowance, so a machine that said "I am here" every 20 seconds would burn thousands of messages a day to tell you nothing new — and would also crowd the genuine announcements out of the window your computer reads. A few minutes is often enough to keep a live computer visible and cheap enough to leave running all day. A computer that has just started announces itself immediately rather than waiting out the interval, so a machine you have only just switched on still appears promptly.
A computer that has been asked to slow down goes quiet for a while — and comes back on its own. Saying "I am here" costs one Team Chat message, and your account has a daily allowance for those across every automated sender. If that allowance runs out, the machine stops announcing instead of asking over and over, and resumes by itself once the wait it was given has passed. Your other computer may simply vanish from the list while this happens; nothing is lost, and it reappears when the machine starts announcing again.
Seeing a computer is not connecting to it. A computer that has only announced itself shows up in your list as not connected, and that is all it can do: nothing is sent to it, nothing is accepted from it, and none of your conversations reach it. This is the state a computer sits in until you decide otherwise, and it is a safe one to leave a machine in.
Connecting needs your click on each computer. Press Connect here, then press it there. Both ends must agree, and each computer reads only its own agreement — so a one-sided press changes nothing on either machine, rather than half-opening a path. When both have agreed, the pair reads Connected, and your conversations flow between them.
Disconnect stops it just as directly, from either end. The other computer stays in your list, so reconnecting later does not mean waiting for it to announce itself again — and a disconnect is not undone by a computer that keeps saying "I am here". Only you move that switch.
A name shown for another computer is that computer's own claim about itself, exactly as in a message: it is a label to recognise the machine by, never a verified identity, and renaming one machine never changes what it is allowed to do.
What arrives is clearly another machine's words
A message arriving from your other computer enters the session you chose there, framed as coming from an agent on another of your owner's computers — never as your own instructions, and holding no authority over that session. Which computer it says it came from is that computer's own claim: it is shown as a label, not a verified identity.
That framing also tells the receiving agent how to answer, and its answer goes back to the session that wrote — which is the point of connecting two computers. You are told how to answer because you switched this on and pointed the conversation at a session yourself, so the two agents do not need an owner in the middle of every exchange. Anything beyond the conversation is still yours to approve: spending money, changing or deleting files, running a suggested command, or reaching anyone else still needs you first.
It cannot run away, and it cannot resurrect
- No turn limit, and no message limit unless you set one. A conversation between two of your OWN computers is not the case the runaway guard exists for, so agent turns do not count against a budget and two agents may keep talking for as long as they have something to say. There is no daily cap and no gap between messages either — a bound exists only if a person sets one, per conversation, and both are off until then. Nothing inherits a number you never chose.
- A limit you do set is counted across BOTH computers, because each machine keeps its own tally and counting one side would let two agents sit one message under it forever.
- Nothing is thrown away at a limit you set. A message that arrives once the day's count is spent waits for the daily counter to reset and is delivered then. It is held, never stepped over — a message the cursor has passed is gone for good, and the cap lifts by itself, so there is no reason to destroy one.
- A message never restarts a session you archived or closed. Waking is for a sleeping session, and only when that conversation is set to wake it.
A message that cannot be delivered is reported back
The computer that receives a message decides what happens to it — and it tells the session that sent it when the answer is "nothing". If the session a conversation points at there is archived, has ended, or is not accepting messages, the sending agent is told why, on the same conversation, instead of waiting forever on a message that was refused. The same happens when a message is held for more than a few minutes behind a session that is busy or paused, and when a conversation set to only while running drops a message because its session is asleep.
The report goes to the exact session that asked, not to wherever that conversation is pointed on the sending computer — so an answer and a failure notice both land in the same place as the question.
Switching a conversation off does not hide what arrived while it was off. Turning one off stops it delivering, and turning it back on means "from here" — it will not replay what it missed, which is deliberate. What it will not do is pretend the missed messages never happened: each agent that sent one during the off period is told its message was not delivered and may be sent again — within a few seconds, from the watcher's own pass over the switched-off conversations, so you do not have to switch the conversation back on for the sender to be answered.
One refusal this feature does NOT control: your account has a daily allowance for Team Chat messages across everything automated in Omniscio. If that runs out, a send is refused — the caller is told how long to wait rather than being left to retry — and this computer stops sending on the bus until that wait has passed, so a conversation between two machines cannot turn a spent allowance into a storm of refused requests. It starts sending again on its own.
It says what is wrong, and only while it is wrong
GET /agent-devices shows each conversation's last problem, if it has one. A conversation nobody
has spoken on yet is simply empty, not an error. A failed read is shown until the conversation reads
cleanly again, and then it clears on its own. A problem with one message — the session it lands in
is archived, say — stays until a later message is delivered, so you can see why nothing arrived.
Your other computers can see which sessions you are running — if you let them
A conversation lands its messages in ONE session per computer, which is fine until the work you want is in a session that is not that one. Session discovery shows you the way through: an agent can ask one of your computers which sessions it is running, see them by name, and send straight to the one it wants — so work that belongs in a particular session gets there, instead of landing in whichever session that conversation happens to point at. You can equally read the list yourself to decide which session to point a conversation at; both routes now exist.
Nothing is visible until you say so, project by project. Nothing about a project — not its name, not its sessions' names — leaves your computer until you turn that project on in Settings → Agents across your computers. Projects you never turn on are never listed and never reachable, and the app's own built-in hubs (the ones that host integration panels, not your work) are never shared at all.
Your agents can only ask. An agent that wants a project shared raises ONE card in your inbox naming the project, and one click approves it — the token an agent session carries by default is refused by the route that grants, so an ordinary agent session cannot approve one for itself, and one click cannot approve several projects at once. Agents CAN narrow: hide a single session and it stops being offered. Putting one back is your call, not theirs.
What a sender sees for each session: its name, the project it is in, whether it is running, when it last did anything, its crew and role when it belongs to one, and how it answers messages. Only sessions that are actually live are listed — an archived, ended, paused or silently-hidden session is never offered. A very large answer is bounded by the wire, which carries at most 24 parts: past that the list is cut off and the answer says so, rather than quietly looking complete.
It is never broadcast. The list is fetched when somebody asks for it, and the answer carries the moment it was generated, so a stale list cannot be mistaken for a current one. Read it as a snapshot: it says what was live when it was built. That is exactly why an addressed message is checked again on the computer that receives it, at the moment it is sent rather than when the list was made — so a session you hide, or whose project you stop sharing, after the list was handed out is still refused, and the agent that sent it is told which of the reasons it met.
An address is honoured or refused — never quietly redirected. A message aimed at a named session either lands in that session or comes back refused; it is never delivered to the conversation's own destination instead, because a session that has gone since the list was made must not silently become a different one.
When it cannot be reached, it says which of the reasons it was: that computer is not connected · that project is not shared · that session is hidden · that session is gone. And an empty answer names why it is empty and when that computer was last heard from — so "nothing shared yet" is never mistaken for "that machine is offline".
Switching it off
Each conversation has its own on/off, and switching one off stops it immediately — nothing is sent and nothing is delivered for it. Turning one back on means "from here": the conversation does not replay what was said while it was off.
For agents
Agents drive the command line (127.0.0.1:19519, bearer auth); the Settings section is the same
service behind a UI, so every action below is reachable both ways:
| Route | Does |
|---|---|
GET /agent-devices |
This computer's name and id — plus the commit the RUNNING build was compiled from, so a cross-machine test can tell which code each side is actually executing — every conversation with its route and state, the other computers it has found with the connection state of each, and whether this computer is still LOOKING for them (presence: when discovery last succeeded, and the reason it last failed) |
GET /agent-devices/conversations/:id/messages |
Read one conversation's messages as they travel the bus — newest first, paged with limit and before, each carrying the sending computer and what THIS one knows about its delivery |
POST /agent-devices/conversations |
Open or configure one conversation: switch it on, choose the session it lands in here, set the delivery mode, mute or unmute, and set (or clear, with null) that conversation's own dailyCap and cooldownMs |
POST /agent-devices/messages |
Send one message on a conversation — optionally addressed to one of your computers with toDeviceId, and optionally to ONE session on that computer with toSessionId (which needs toDeviceId with it: a session id alone does not say which computer it belongs to). An addressed message is delivered to that session or refused with the reason; it is never rerouted to the conversation's own destination. Retry with the same X-Client-Request-Id and it is delivered once |
POST /agent-devices/device |
Rename this computer |
POST /agent-devices/connections |
Connect, accept, decline or disconnect one of your own computers — the same act as the button in Settings |
GET /agent-devices/discovery |
What THIS computer publishes, every project with its switch, the sessions currently visible, and how the discovery pass is doing |
POST /agent-devices/discovery/approvals |
Turn one project's visibility on or off. A person's alone — the scoped token an agent session carries cannot reach this route at all |
POST /agent-devices/discovery/sessions |
Hide one session (anyone may) or show it again (a person only — putting a session back in front of another computer is a widening) |
POST /agent-devices/discovery/ask |
An agent asking to turn a project on. Raises ONE card in the inbox; it grants nothing by itself |
POST /agent-devices/discovery/list |
Ask one of your computers what it has, and get its answer: the live sessions, with its generation time |
POST /agent-devices/discovery/check |
A dry run — would this address be honoured? Answers reachable, or refused with the reason, and sends nothing |
GET /agent-devices/receipts |
The last N messages that actually arrived on one conversation, with the session each landed in and when |
A send is refused while a computer this one has found is still unconnected, and an addressed send is refused if the computer it names is not connected — the agreement holds on the sending side as well as the receiving one, so nothing is posted into a channel the other machine has not agreed to read.
Routes are absent — not merely refusing — while the feature is off.
Related
- agent-device-contract.md — the invariants.
- cross-session-messaging.md — messaging between sessions inside ONE app.
- agent-lanes.md — the same idea between two people in one workspace.
Last verified 2026-10-04