Say when a session is working, and what it was told

Three things a phone could not see, all of them the same shape: the
session was doing something and nothing on screen said so.

A turn nobody here started never reported itself. `Running` was sent
where a message was *sent*, so a session picked up mid-turn, one
compacting on its own, or one another agent wrote to sat there reading
as idle until it finished. The driver now says it from what it observes
-- output that could only come from a turn in flight -- which is the
same set of events that already announced a steer, with the ends
swapped.

An imported session had it worse: nothing but replayed lines ever
reaches it, and a status was not among them, so it was permanently
whatever it was when it was adopted. Its file does not record a turn
ending, but it does record why each assistant message stopped, and
`tool_use` versus anything else answers it. A record that says nothing
leaves the status alone rather than voting for idle.

Messages from other agents were dropped outright: the CLI marks them
meta, and this replayed everything except meta. They are now a row of
their own, closed by default like a tool call, named for the session
that sent it -- not the reader's own bubble, because they did not say
it, and a session working on something this phone never asked for is
exactly what one of these explains.

Measured against a real session file rather than guessed: the peer
record carries the sender's name and the message body in `origin`,
beside a copy wrapped for the model to read.
This commit is contained in:
iris committed 2026-08-29 15:27:46 -04:00
1 parent f18639e4b1
commit 404066fa7d
11 files changed
+577 -29

No files matched your search

@@ -37,6 +37,15 @@ sealed class SessionEvent {
data class Answered(val id: String, val answer: String) : SessionEvent()
/**
* A message another agent sent this session.
*
* Not a [UserMessage]: nobody holding the phone said it, and drawing it in their voice would
* claim they had. It is also the explanation for a session that starts working on something
* this device never asked for.
*/
data class PeerMessage(val from: String, val text: String) : SessionEvent()
data class Status(val state: String) : SessionEvent()
data class UsageDelta(val tokens: Long) : SessionEvent()
@@ -96,6 +105,8 @@ fun parseSeqEvent(json: String): SeqEvent {
about = body.optString("about").ifEmpty { null },
)
"answered" -> SessionEvent.Answered(body.getString("id"), body.getString("answer"))
"peerMessage" ->
SessionEvent.PeerMessage(body.getString("from"), body.getString("text"))
"status" -> SessionEvent.Status(body.getString("state"))
"usageDelta" -> SessionEvent.UsageDelta(body.getLong("tokens"))
"compacted" ->