Archived
Merge remote-tracking branch 'origin/main' into feat/model-questions-ux
# Conflicts: # src/server/sessiond.ts # src/server/sessions/sessionRoutes.test.ts
This commit is contained in:
@@ -204,6 +204,11 @@ type SessionCreationProvenance = "tracked-subsession";
|
||||
interface StartSessionOptions {
|
||||
parentSession?: string;
|
||||
initialModel?: AgentModel;
|
||||
/**
|
||||
* Opaque label, echoed on this construction's startup progress so a browser
|
||||
* row with no session id yet can recognise its own.
|
||||
*/
|
||||
startupToken?: string;
|
||||
}
|
||||
|
||||
interface InternalStartSessionOptions extends StartSessionOptions {
|
||||
@@ -395,7 +400,7 @@ interface PendingSessionOpen {
|
||||
promise: Promise<ActiveSession<PiSessionRuntime>>;
|
||||
}
|
||||
|
||||
interface CreateSessionRuntimeOptions extends Pick<InternalStartSessionOptions, "initialModel" | "creationProvenance"> {
|
||||
interface CreateSessionRuntimeOptions extends Pick<InternalStartSessionOptions, "initialModel" | "creationProvenance" | "startupToken"> {
|
||||
notificationGeneration?: SessionNotificationGeneration;
|
||||
notifications?: "enabled" | "disabled";
|
||||
/**
|
||||
@@ -1016,6 +1021,7 @@ export class PiSessionService implements SessionRouteService {
|
||||
cwd,
|
||||
{
|
||||
startupIntent: "create",
|
||||
...(options.startupToken === undefined ? {} : { startupToken: options.startupToken }),
|
||||
...(options.initialModel === undefined ? {} : { initialModel: options.initialModel }),
|
||||
...(options.creationProvenance === undefined ? {} : { creationProvenance: options.creationProvenance }),
|
||||
},
|
||||
@@ -2459,7 +2465,7 @@ export class PiSessionService implements SessionRouteService {
|
||||
cwd: string,
|
||||
options: CreateSessionRuntimeOptions = {},
|
||||
): Promise<ActiveSession<PiSessionRuntime>> {
|
||||
const startup = this.startupProgress(sessionManager, cwd, options.startupIntent ?? "open");
|
||||
const startup = this.startupProgress(sessionManager, options.startupIntent ?? "open", options.startupToken);
|
||||
try {
|
||||
return await this.createSessionRuntime(sessionManager, cwd, options, startup);
|
||||
} finally {
|
||||
@@ -3105,23 +3111,23 @@ export class PiSessionService implements SessionRouteService {
|
||||
/**
|
||||
* Build the reporter for one session construction.
|
||||
*
|
||||
* The session id and cwd are both known before any await — a `SessionManager`
|
||||
* has its id from construction — so the daemon can name what it is starting
|
||||
* even though the `PiAgentSession` that {@link publishActivity} needs does not
|
||||
* exist yet. When either is missing there is nothing honest to route on, so
|
||||
* the reporter stays silent and the browser keeps its own generic wording.
|
||||
* The session id is known before any await — a `SessionManager` has its id
|
||||
* from construction — so the daemon can name what it is starting even though
|
||||
* the `PiAgentSession` that {@link publishActivity} needs does not exist yet.
|
||||
* Without an id there is nothing to report against, so the reporter stays
|
||||
* silent and the browser keeps its own generic wording.
|
||||
*/
|
||||
private startupProgress(sessionManager: PiSessionManager, cwd: string, intent: "create" | "open"): SessionStartupProgressReporter {
|
||||
private startupProgress(sessionManager: PiSessionManager, intent: "create" | "open", startupToken: string | undefined): SessionStartupProgressReporter {
|
||||
const sessionId = sessionManager.getSessionId();
|
||||
if (sessionId === "" || cwd === "") return { report: noop, end: noop };
|
||||
if (sessionId === "") return { report: noop, end: noop };
|
||||
const label = intent === "create" ? "Creating session" : "Opening session";
|
||||
return {
|
||||
report: (phase) => { this.publishStartupProgress(sessionId, cwd, label, "active", this.startupDetail(phase)); },
|
||||
report: (phase) => { this.publishStartupProgress(sessionId, startupToken, label, "active", this.startupDetail(phase)); },
|
||||
end: () => {
|
||||
// A real activity published during the window (an extension error, say)
|
||||
// is the truth about this session and must survive the clear.
|
||||
if (this.activities.has(sessionId)) return;
|
||||
this.publishStartupProgress(sessionId, cwd, "idle", "idle", undefined);
|
||||
this.publishStartupProgress(sessionId, startupToken, "idle", "idle", undefined);
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -3133,17 +3139,22 @@ export class PiSessionService implements SessionRouteService {
|
||||
}
|
||||
|
||||
/**
|
||||
* Report startup progress on the global channel only, keyed by `cwd` so a
|
||||
* browser row that has no session id yet can find it.
|
||||
* Report startup progress on the global channel only, echoing the caller's
|
||||
* correlation token so a waiting browser row recognises its own construction.
|
||||
*
|
||||
* Unlike {@link publishActivity} this deliberately records nothing: no
|
||||
* `activities` entry, no workspace activity, no unread observation. There is
|
||||
* no session to own that state, and a failed creation would leave it stranded.
|
||||
*
|
||||
* Every report is marked `startup`, which is what keeps a session that is
|
||||
* merely opening from counting as one doing work. This is the only publisher
|
||||
* that sets the marker, and because it writes no `activities` entry no later
|
||||
* heartbeat re-publication can carry it.
|
||||
*/
|
||||
private publishStartupProgress(sessionId: string, cwd: string, label: string, phase: "active" | "idle", detail: string | undefined): void {
|
||||
private publishStartupProgress(sessionId: string, startupToken: string | undefined, label: string, phase: "active" | "idle", detail: string | undefined): void {
|
||||
const at = new Date().toISOString();
|
||||
const activity = detail === undefined ? { sessionId, phase, label, at } : { sessionId, phase, label, detail, at };
|
||||
this.events.publishGlobal({ type: "session.startup", cwd, activity });
|
||||
const activity = detail === undefined ? { sessionId, phase, label, at, startup: true } : { sessionId, phase, label, detail, at, startup: true };
|
||||
this.events.publishGlobal(startupToken === undefined ? { type: "session.startup", activity } : { type: "session.startup", startupToken, activity });
|
||||
}
|
||||
|
||||
private publishActivity(session: PiAgentSession, label: string, phase: "active" | "idle" | "error", detail?: string): void {
|
||||
|
||||
Reference in New Issue
Block a user