Display pending CLI requests in Agents view (#2314)

This commit is contained in:
Don Jayamanne
2025-12-02 12:05:23 +11:00
committed by GitHub
parent 90f47be53f
commit 86ae3ca69e
2 changed files with 29 additions and 3 deletions
@@ -38,6 +38,7 @@ export interface ICopilotCLISession extends IDisposable {
readonly isolationEnabled: boolean;
readonly workingDirectory?: Uri;
};
readonly pendingPrompt: string | undefined;
attachPermissionHandler(handler: PermissionHandler): IDisposable;
attachStream(stream: vscode.ChatResponseStream): IDisposable;
handleRequest(
@@ -82,7 +83,10 @@ export class CopilotCLISession extends DisposableStore implements ICopilotCLISes
};
}
private _lastUsedModel: string | undefined;
private _pendingPrompt: string | undefined;
public get pendingPrompt(): string | undefined {
return this._pendingPrompt;
}
constructor(
private readonly _options: CopilotCLISessionOptions,
private readonly _sdkSession: Session,
@@ -127,6 +131,7 @@ export class CopilotCLISession extends DisposableStore implements ICopilotCLISes
if (this.isDisposed) {
throw new Error('Session disposed');
}
this._pendingPrompt = prompt;
this._status = ChatSessionStatus.InProgress;
this._statusChange.fire(this._status);
@@ -259,6 +264,7 @@ export class CopilotCLISession extends DisposableStore implements ICopilotCLISes
this.logService.error(`[CopilotCLISession] Invoking session (error) ${this.sessionId}`, error);
this._stream?.markdown(`\n\n❌ Error: ${error instanceof Error ? error.message : String(error)}`);
} finally {
this._pendingPrompt = undefined;
disposables.dispose();
}
}
@@ -153,6 +153,26 @@ export class CopilotCLISessionService extends Disposable implements ICopilotCLIS
})
));
const diskSessionIds = new Set(diskSessions.map(s => s.id));
// If we have a new session that has started, then return that as well.
// Possible SDK has not yet persisted it to disk.
const newSessions = coalesce(Array.from(this._sessionWrappers.values())
.filter(session => !diskSessionIds.has(session.object.sessionId))
.filter(session => session.object.status === ChatSessionStatus.InProgress)
.map(session => {
const label = labelFromPrompt(session.object.pendingPrompt ?? '');
if (!label) {
return;
}
return {
id: session.object.sessionId,
label,
status: session.object.status,
timing: { startTime: Date.now() },
} satisfies ICopilotCLISessionItem;
}));
// Merge with cached sessions (new sessions not yet persisted by SDK)
const allSessions = diskSessions
.map(session => {
@@ -160,7 +180,7 @@ export class CopilotCLISessionService extends Disposable implements ICopilotCLIS
...session,
status: this._sessionWrappers.get(session.id)?.object?.status
} satisfies ICopilotCLISessionItem;
});
}).concat(newSessions);
return allSessions;
} catch (error) {
@@ -336,4 +356,4 @@ export class RefCountedSession extends RefCountedDisposable implements IReferenc
dispose(): void {
this.release();
}
}
}