Files
orca/tests
Brennan BensonandMerge Sim 2513e21390 fix(native-chat): publish structured session status from the host so the sidebar never goes stale (#18776)
* fix(native-chat): publish structured session status from the host

The sidebar learned whether a structured chat was mid-turn by replaying
the session journal in the renderer, through a reader whose lifetime was
tied to the chat pane. Hiding the pane stopped the reader before the
turn's settlement arrived, so the row stayed on "working" until the chat
was reopened. The same coupling meant a tab never opened this session
showed no status at all, and a reloaded renderer lost every settled row.

The host owns the journal, so it now projects each session's status once
per journal publication and fans the changes out on one stream per client
(`agentSession.subscribeStatus`). The projection survives eviction of an
idle session's provider child and is republished when readable sessions
are restored. The renderer bridge subscribes to that feed per runtime
target and never opens a transcript reader; the observation hook is gone.

Additive wire surface behind the existing structured capability; old
hosts reject the method and the renderer retries, showing no status.

* fix(native-chat): negotiate the status feed and stop losing a change on subscribe

The status stream is additive to a surface that already shipped, so a host
advertising agent-session.structured.v1 can still answer subscribeStatus with
method_not_found. Every renderer error path reconnected, so a remote host one
release behind got a relay round-trip every 5s and no sidebar status at all.
Give the method its own capability and probe it before subscribing; a failed
probe still retries, an absent capability does not.

Re-projecting on subscribe also wrote straight into the shared cache, so a
second client could pin the first to a stale summary. Route those diffs
through publish() before the arriving subscriber is registered.

* fix(native-chat): bound the status prompt, merge snapshots, and prove the unread path

One status frame carries every retained session and a send admits 256 KB per
prompt, so ~16 large-prompt sessions could push the snapshot past the 4 MB
outbound guard and into the retry loop. Bound latestPrompt to the same
200-char single-line preview every other agent-status row already carries.

A snapshot also replaced the cached map wholesale, so the empty first frame
from a restarting host retracted every row before restore republished them.
Merge instead; the tab map, not this feed, decides which sessions are listed.

Tests: the hidden-pane claim now sits at the host, where a journal with no
transcript subscriber is driven from running to idle; the RPC test reads a
real projection instead of its own stub.

* fix(native-chat): merge the duplicated status-event type import

* test(native-chat): pin the restart status publication, and log the unsupported host

Startup restore indexes a readable session and publishes its status, which is
what puts a never-reopened tab back in the sidebar. Only an Electron screenshot
covered that wiring; a sitting status subscriber now pins it directly.

The terminal "host too old" branch was silent, so a mixed-version report showed
an empty sidebar with nothing in the log to explain it.

---------

Co-authored-by: Merge Sim <sim@local>
2026-09-05 15:35:03 -07:00
..