Archived
feat(sessions): tell the user what a session start is waiting on
Creating or opening a session could stall for reasons the daemon knew
about and never shared. The browser invented the whole message it showed
while waiting -- "Creating session: Waiting for the backend session to be
ready" -- which says that we are waiting but never what for. A shared
ModelRuntime read during startup can be handed a network refresh that is
already in flight, and extensions may do their own network I/O while
loading, so the wait is real and previously unattributable.
The pre-session gap turned out to be a missing shared key rather than a
missing channel: publishActivity needs the PiAgentSession being built, but
the session id and cwd are both known before the first await. So create()
now publishes a new global session.startup event carrying an ordinary
SessionActivity, routed by cwd -- the one identity a browser row waiting
for a session id can match, since the client-invented pending id is
unknown to the daemon and the daemon's id is unknown to the browser.
Two phases are reported, each published before the await it describes so
the label changes during the wait rather than after it: "Starting the Pi
session" and "Loading session extensions". Both are facts, because the
service awaits exactly one call for each. A concurrent background catalog
refresh is appended as a note ("provider model lists are refreshing"),
never as the cause: the refresher can prove a refresh is running but not
that this startup joined it. ModelCatalogRefresher gains only a read-only
isRefreshInFlight() getter; cadence, timeout, and coalescing are untouched.
Reporting is event-only and synchronous. It writes no activities entry, no
workspace activity, and no unread state, so a failed creation leaves
nothing stranded, no await is added, and creation ordering and semantics
are unchanged. The window-ending idle report is skipped when a real
activity was published during startup, so an extension error survives.
The browser applies startup progress only when it can prove the target:
one non-discarded pending start in that cwd on the selected machine, or a
session whose id it already knows. A foreign workspace, another machine,
or two concurrent starts in one workspace keep today's generic wording
rather than showing one row the phase of another. An idle report restores
that generic wording, including the queued-messages variant.
docs/config.md said nothing a request triggers waits on a catalog fetch.
That is not strictly true for a refresh already in flight, so both it and
the generated docs/config.html now state the exception and say PI WEB
reports it while it happens.
This commit is contained in:
+22
-1
@@ -433,6 +433,26 @@ export interface QueuedSessionMessage {
|
||||
text: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Progress of the session startup window, where the daemon is still
|
||||
* constructing the agent session and no `PiAgentSession` exists yet, so
|
||||
* `activity.update` cannot be published for it.
|
||||
*
|
||||
* `cwd` is the routing key for a browser row that is still waiting for a
|
||||
* session id: a client-invented pending start knows its workspace path but not
|
||||
* the daemon's session id. `activity.sessionId` carries the daemon's real id, so
|
||||
* the same event also serves the case where the browser already knows it (an
|
||||
* open of an existing session).
|
||||
*
|
||||
* `activity.phase === "idle"` means the startup window ended with nothing left
|
||||
* to report, so a browser that substituted its own text should restore it.
|
||||
*/
|
||||
export interface SessionStartupProgressEvent {
|
||||
type: "session.startup";
|
||||
cwd: string;
|
||||
activity: SessionActivity;
|
||||
}
|
||||
|
||||
/**
|
||||
* A pi-native image attachment carried with a prompt. The wire format mirrors
|
||||
* pi's own `ImageContent` shape (`{ type: "image", data, mimeType }`) so these
|
||||
@@ -977,5 +997,6 @@ type SessionUiEventBody =
|
||||
export type GlobalSessionEvent =
|
||||
| Extract<SessionUiEventBody, { type: "status.update" | "activity.update" | "session.name" | "session.created" }>
|
||||
| SessionNotificationSummaryEvent
|
||||
| SessionUnreadEvent;
|
||||
| SessionUnreadEvent
|
||||
| SessionStartupProgressEvent;
|
||||
export type RealtimeEvent = GlobalSessionEvent | TerminalUiEvent | WorkspaceActivityUiEvent;
|
||||
|
||||
Reference in New Issue
Block a user