Mirasim Documentation
Session messaging
Sessions that can reach each other: a switch per session, an @ that names one, and four verbs the agent gets in return.
When one session should talk to another
By default sessions cannot see each other at all: separate processes, separate transcripts, separate queues. That isolation is exactly why a second session costs the first one nothing — and it is also why, when one session is holding a fact another one needs, the fact travels through you. Session messaging is the one path that lets it travel directly, and you open that path per session.
Three situations account for nearly all real use:
- Two divided sessions keeping each other current — the one on the API renames a field, and the one on the UI needs to know now rather than after you notice.
- Handing work to a different agent or a different model tier — bulk mechanical work to a cheap model, one hard sub-problem to a strong one. The session you start has its own transcript and keeps running after your own turn ends.
- Naming a session inside your own prompt, so this session's agent can go and read it, tell it something, or watch it finish — without you copying text between two panes.
Turning it on, one session at a time
The switch is Session messaging, in the menu on a session's row in the sidebar. It is off by default and it belongs to that one session: connected, other connected sessions can address it and its own agent gets the messaging tools; off, it is invisible to them — it is not listed, and holding its exact key does not get a message in.
- Open the switch on the sessions that need it
Find the session in the sidebar, open the menu at the end of its row, and click Session messaging. Clicking it again turns it back off.
- Both ends have to be connected
A message travels between two sessions, so both of them need to be on — or use the shortcut in the next section: naming a session in your prompt connects both ends on the spot.
- Leave it on only where it earns its place
A connected session that nobody has messaged in a while stops paying for the tools it is not using, and the switch you flipped by hand keeps its authorization either way. Turning it off is still the honest way to say this session is done talking.
Naming a session in your own prompt
Type `@` in the composer and the menu lists files first, then your sessions — each row showing its title, the agent running it, and whether it is running, idle, or a terminal session. Picking one writes `@session[the session's name]` into your draft, coloured in place as you keep typing. Up to three of them expand in one message.
A mention is a name, not an action. There is no send-to-that-session button and Enter always starts a turn in the session you are looking at. What the mention expands into is one line of fact — this session exists, here is its key, its agent, and whether it is running. Whether to read it, tell it something, or watch it finish is read by the agent out of the sentence you wrote around the mention.
- “Read where @session[Login rework] has got to before we change anything here.” — it looks, and reports back what it found.
- “Tell @session[Login rework] that the field is now `tenant_id`.” — it writes the message itself. Your sentence is not forwarded verbatim; a note meant for another agent is composed by an agent that knows what that one is doing.
- “Watch @session[Login rework] and tell me when that turn is done.” — it waits for that session's turn to settle instead of asking every minute.
In the message you already sent, the mention stays clickable: click it to jump to that session. If it has been renamed or deleted, it says so plainly instead of opening whichever session looks closest.
The four verbs the agent gets
A connected session's agent has four extra tools this turn. Their own descriptions are the whole manual — nothing about session messaging is added to the agent's system prompt.
| Tool | What it does |
|---|---|
| list_sessions | Lists the sessions it can reach, with their live state. Only connected sessions appear; one that is not listed cannot be reached. It sees this workspace by default and other workspaces only if it asks. |
| read_session | Reads what another session is doing: a summary of its last four turns, capped at 2KB, plus whether it is still running. With its wait option it becomes watch it — it answers the moment that session's turn settles, and after five minutes of waiting it says plainly that the session is still running rather than implying it finished. |
| send_session_message | Sends one message to another session, and is also how it replies to one it received. Up to 8KB of text; what comes back is how the message was delivered. |
| start_session | Starts a new session on a chosen agent, model and reasoning level, with an opening task. It does not block: the new session's reply comes back as a message. |
`start_session` is not a rename of the agent's own sub-agents. Ordinary fan-out inside a task is still a sub-agent's job; this is for the three things a sub-agent cannot do — run a different agent, run a different model tier, and keep going after the turn that started it has ended. Both ends of it are connected automatically, because a session created in order to be talked to should not need a switch flipped first.
How a message actually lands
Delivery depends on one thing: what the target session was doing at that moment.
| Target state | What happens |
|---|---|
| Idle, or its last turn has ended | A new turn starts there right away, with the message itself as the prompt. |
| Running, on an agent that takes mid-turn input | It goes into the turn already in flight and is picked up at the next step boundary — no tool call in progress is interrupted. |
| Running on an agent that does not, or waiting on a question to you | It is held and delivered at the next turn boundary, for up to five minutes. Past that it expires, and says so. |
| Not connected, or an internal session | Refused, with wording that tells the sender not to retry a guess. |
| A terminal (TUI) session | Can be read, cannot be written to — there is no input handle to inject into. |
What arrives is never rendered as if you had said it. The message comes in an envelope that states which session it came from and which verb to reply with; one an agent sent on its own initiative also carries a fixed line saying it is a message from another session and not an instruction from this session's user. On screen it appears with its source attached, and the source is clickable — one click back to the session that wrote it.
The limits, and where the record lives
The guardrails exist because two agents can exchange messages far faster than you can read them. None of them is adjustable; all of them are stated here so a refusal is never a mystery.
- One message
- Up to 8KB. Past that, send a pointer — a path, a key — rather than the text.
- One read
- The last four turns, capped at 2KB. It is an orientation, not a second transcript.
- Holding and waiting
- A held message waits 300 seconds; a read that waits for a turn to settle also waits at most 300 seconds.
- Send rate
- A bucket of 30 per sending session, refilling at 0.5 per second; the same text to the same session inside 30 seconds is dropped as a duplicate.
- Chain depth
- A chain of messages relaying onward stops at 24 hops. Any turn a human took part in resets the count.
- Ping-pong breaker
- More than 12 messages inside five minutes between the same pair, with no human input on either side during those five minutes, cuts that pair off and shows it in the interface.
Every message is written to a local, append-only ledger: who sent it to whom, the text itself, how it was delivered, and how it ended. Monthly files, kept 90 days, never uploaded — and plain enough to read with the tools you already use. The per-session switches live beside it in `~/.mirasim/messages/enrolled.json`.
# the last few messages this month, as they were recorded
tail -n 5 ~/.mirasim/messages/msgs-<YYYY-MM>.jsonl
# everything one session sent or received
grep '<sessionKey>' ~/.mirasim/messages/msgs-<YYYY-MM>.jsonlUsing it without losing the thread
- Connect the pair that genuinely holds facts for each other. Three sessions reporting progress to one another is usually slower than one session doing both jobs.
- Every message has to stand on its own. The other session sees this text and nothing else — not your conversation, not what you meant by it.
- Do not poll. If something has to be waited for, the wait belongs in one read that returns when the turn settles, not in a call every minute.
- Reach for a new session only when the agent, the model tier, or surviving past this turn is the point. Otherwise a sub-agent is cheaper and stays inside one transcript.
Something wrong or missing on this page? Tell us

