fixes to sessions (#305205)

* fixes to sessions

* copilot feedback
This commit is contained in:
Sandeep Somavarapu
2026-03-26 17:10:25 +01:00
committed by GitHub
parent abdf722266
commit cae186c9f8
15 changed files with 120 additions and 80 deletions

View File

@@ -67,7 +67,7 @@ The common session interface exposed by all providers. It is a self-contained fa
| `isRead` | `IObservable<boolean>` | Read/unread state |
| `description` | `IObservable<string \| undefined>` | Status description (e.g., current agent action) |
| `lastTurnEnd` | `IObservable<Date \| undefined>` | When the last agent turn ended |
| `pullRequestUri` | `IObservable<URI \| undefined>` | Associated pull request URI |
| `pullRequest` | `IObservable<ISessionPullRequest \\| undefined>` | Associated pull request |
#### Supporting Types

View File

@@ -645,10 +645,7 @@ class NewChatWidget extends Disposable implements IHistoryNavigationWidget {
* Requests folder trust if needed and creates a new session.
*/
private async _onWorkspaceSelected(selection: IWorkspaceSelection): Promise<void> {
// Check if the provider's session type requires workspace trust
const sessionTypes = this.sessionsProvidersService.getSessionTypesForProvider(selection.providerId);
const requiresTrust = sessionTypes.some(t => t.requiresWorkspaceTrust);
if (requiresTrust) {
if (selection.workspace.requiresWorkspaceTrust) {
const workspaceUri = selection.workspace.repositories[0]?.uri;
if (workspaceUri && !await this._requestFolderTrust(workspaceUri)) {
return;
@@ -677,6 +674,10 @@ class NewChatWidget extends Disposable implements IHistoryNavigationWidget {
this._send();
}
}
selectWorkspace(workspace: IWorkspaceSelection): void {
this._workspacePicker.setSelectedWorkspace(workspace);
}
}
// #endregion
@@ -736,6 +737,10 @@ export class NewChatViewPane extends ViewPane {
this._widget?.sendQuery(text);
}
selectWorkspace(workspace: IWorkspaceSelection): void {
this._widget?.selectWorkspace(workspace);
}
override setVisible(visible: boolean): void {
super.setVisible(visible);
if (visible) {

View File

@@ -189,7 +189,7 @@ export class WorkspacePicker extends Disposable {
* Programmatically set the selected project.
* @param fireEvent Whether to fire the onDidSelectWorkspace event. Defaults to true.
*/
setSelectedProject(project: IWorkspaceSelection, fireEvent = true): void {
setSelectedWorkspace(project: IWorkspaceSelection, fireEvent = true): void {
this._selectProject(project, fireEvent);
}

View File

@@ -33,6 +33,7 @@ function makeSession(opts: { repository?: URI; worktree?: URI } = {}): ISessionD
detail: undefined,
baseBranchProtected: undefined,
}],
requiresWorkspaceTrust: false,
} : undefined;
return {
sessionId: 'test:session',
@@ -53,8 +54,7 @@ function makeSession(opts: { repository?: URI; worktree?: URI } = {}): ISessionD
isRead: observableValue('isRead', true),
lastTurnEnd: observableValue('lastTurnEnd', undefined),
description: observableValue('description', undefined),
pullRequestUri: observableValue('pullRequestUri', undefined),
pullRequestStateIcon: observableValue('pullRequestStateIcon', undefined),
pullRequest: observableValue('pullRequest', undefined),
};
}

View File

@@ -20,13 +20,15 @@ import { IChatInputPickerOptions } from '../../../../workbench/contrib/chat/brow
import { EnhancedModelPickerActionItem } from '../../../../workbench/contrib/chat/browser/widget/input/modelPickerActionItem2.js';
import { HoverPosition } from '../../../../base/browser/ui/hover/hoverWidget.js';
import { IContextKeyService, ContextKeyExpr, RawContextKey } from '../../../../platform/contextkey/common/contextkey.js';
import { IStorageService, StorageScope, StorageTarget } from '../../../../platform/storage/common/storage.js';
import { Menus } from '../../../browser/menus.js';
import { ISessionsManagementService } from '../../sessions/browser/sessionsManagementService.js';
import { ISessionsProvidersService } from '../../sessions/browser/sessionsProvidersService.js';
import { SessionItemContextMenuId } from '../../sessions/browser/views/sessionsList.js';
import { ISessionData } from '../../sessions/common/sessionData.js';
import { IAgentSessionsService } from '../../../../workbench/contrib/chat/browser/agentSessions/agentSessionsService.js';
import { CopilotCLISession, COPILOT_PROVIDER_ID, COPILOT_CLI_SESSION_TYPE, COPILOT_CLOUD_SESSION_TYPE } from './copilotChatSessionsProvider.js';
import { CopilotCLISession, COPILOT_PROVIDER_ID } from './copilotChatSessionsProvider.js';
import { COPILOT_CLI_SESSION_TYPE, COPILOT_CLOUD_SESSION_TYPE } from '../../sessions/browser/sessionTypes.js';
import { IsolationPicker } from './isolationPicker.js';
import { BranchPicker } from './branchPicker.js';
import { ModePicker } from './modePicker.js';
@@ -181,6 +183,7 @@ class CopilotPickerActionViewItemContribution extends Disposable implements IWor
@ILanguageModelsService languageModelsService: ILanguageModelsService,
@ISessionsManagementService sessionsManagementService: ISessionsManagementService,
@ISessionsProvidersService sessionsProvidersService: ISessionsProvidersService,
@IStorageService storageService: IStorageService,
) {
super();
@@ -213,6 +216,7 @@ class CopilotPickerActionViewItemContribution extends Disposable implements IWor
currentModel,
setModel: (model: ILanguageModelChatMetadataAndIdentifier) => {
currentModel.set(model, undefined);
storageService.store('sessions.localModelPicker.selectedModelId', model.identifier, StorageScope.PROFILE, StorageTarget.MACHINE);
const session = sessionsManagementService.activeSession.get();
if (session) {
const provider = sessionsProvidersService.getProviders().find(p => p.id === session.providerId);
@@ -232,12 +236,14 @@ class CopilotPickerActionViewItemContribution extends Disposable implements IWor
const action = { id: 'sessions.modelPicker', label: '', enabled: true, class: undefined, tooltip: '', run: () => { } };
const modelPicker = instantiationService.createInstance(EnhancedModelPickerActionItem, action, delegate, pickerOptions);
// Initialize with first available model, or wait for models to load
// Initialize with remembered model or first available model
const rememberedModelId = storageService.get('sessions.localModelPicker.selectedModelId', StorageScope.PROFILE);
const initModel = () => {
const models = getAvailableModels(languageModelsService);
modelPicker.setEnabled(models.length > 0);
if (!currentModel.get() && models[0]) {
currentModel.set(models[0], undefined);
if (!currentModel.get() && models.length > 0) {
const remembered = rememberedModelId ? models.find(m => m.identifier === rememberedModelId) : undefined;
currentModel.set(remembered ?? models[0], undefined);
}
};
initModel();

View File

@@ -18,10 +18,11 @@ import { IAgentSessionsService } from '../../../../workbench/contrib/chat/browse
import { AgentSessionProviders, AgentSessionTarget } from '../../../../workbench/contrib/chat/browser/agentSessions/agentSessions.js';
import { IChatService, IChatSendRequestOptions } from '../../../../workbench/contrib/chat/common/chatService/chatService.js';
import { ChatSessionStatus, IChatSessionFileChange, IChatSessionsService, IChatSessionProviderOptionGroup, IChatSessionProviderOptionItem } from '../../../../workbench/contrib/chat/common/chatSessionsService.js';
import { ISessionData, ISessionRepository, ISessionWorkspace, SessionStatus, GITHUB_REMOTE_FILE_SCHEME } from '../../sessions/common/sessionData.js';
import { ISessionData, ISessionPullRequest, ISessionRepository, ISessionWorkspace, SessionStatus, GITHUB_REMOTE_FILE_SCHEME } from '../../sessions/common/sessionData.js';
import { ChatAgentLocation, ChatModeKind, ChatPermissionLevel } from '../../../../workbench/contrib/chat/common/constants.js';
import { basename } from '../../../../base/common/resources.js';
import { ISendRequestOptions, ISessionsBrowseAction, ISessionsChangeEvent, ISessionsProvider, ISessionType } from '../../sessions/browser/sessionsProvider.js';
import { CopilotCLISessionType, CopilotCloudSessionType } from '../../sessions/browser/sessionTypes.js';
import { ISessionOptionGroup } from '../../chat/browser/newSession.js';
import { IsolationMode } from './isolationPicker.js';
import { ChatViewPaneTarget, IChatWidgetService } from '../../../../workbench/contrib/chat/browser/chat.js';
@@ -41,22 +42,6 @@ const OPEN_REPO_COMMAND = 'github.copilot.chat.cloudSessions.openRepository';
/** Provider ID for the Copilot Chat Sessions provider. */
export const COPILOT_PROVIDER_ID = 'default-copilot';
/** Session type ID for local Copilot CLI sessions. */
export const COPILOT_CLI_SESSION_TYPE = AgentSessionProviders.Background;
export const COPILOT_CLOUD_SESSION_TYPE = AgentSessionProviders.Cloud;
const CopilotCLISessionType: ISessionType = {
id: COPILOT_CLI_SESSION_TYPE,
label: localize('copilotCLI', "Copilot"),
icon: Codicon.copilot,
requiresWorkspaceTrust: true,
};
const CopilotCloudSessionType: ISessionType = {
id: COPILOT_CLOUD_SESSION_TYPE,
label: localize('copilotCloud', "Cloud"),
icon: Codicon.cloud,
};
const REPOSITORY_OPTION_ID = 'repository';
const BRANCH_OPTION_ID = 'branch';
@@ -126,8 +111,7 @@ export class CopilotCLISession extends Disposable implements ISessionData {
readonly isRead: IObservable<boolean> = observableValue(this, true);
readonly description: IObservable<string | undefined> = observableValue(this, undefined);
readonly lastTurnEnd: IObservable<Date | undefined> = observableValue(this, undefined);
readonly pullRequestUri: IObservable<URI | undefined> = observableValue(this, undefined);
readonly pullRequestStateIcon: IObservable<ThemeIcon | undefined> = observableValue(this, undefined);
readonly pullRequest: IObservable<ISessionPullRequest | undefined> = observableValue(this, undefined);
private _gitRepository: IGitRepository | undefined;
private readonly _loadBranchesCts = this._register(new MutableDisposable<CancellationTokenSource>());
@@ -312,6 +296,10 @@ export class CopilotCLISession extends Disposable implements ISessionData {
}
this.chatSessionsService.setSessionOption(this.resource, optionId, value);
}
update(session: ISessionData): void {
this._workspaceData.set(session.workspace.get(), undefined);
}
}
function isModelOptionGroup(group: IChatSessionProviderOptionGroup): boolean {
@@ -369,8 +357,7 @@ export class RemoteNewSession extends Disposable implements ISessionData {
readonly isRead: IObservable<boolean> = observableValue(this, true);
readonly description: IObservable<string | undefined> = observableValue(this, undefined);
readonly lastTurnEnd: IObservable<Date | undefined> = observableValue(this, undefined);
readonly pullRequestUri: IObservable<URI | undefined> = observableValue(this, undefined);
readonly pullRequestStateIcon: IObservable<ThemeIcon | undefined> = observableValue(this, undefined);
readonly pullRequest: IObservable<ISessionPullRequest | undefined> = observableValue(this, undefined);
readonly _hasGitRepo = observableValue(this, false);
readonly hasGitRepo: IObservable<boolean> = this._hasGitRepo;
@@ -545,6 +532,8 @@ export class RemoteNewSession extends Disposable implements ISessionData {
// Default to first item marked as default, or first item
return group.items.find(i => i.default === true) ?? group.items[0];
}
update(session: ISessionData): void { }
}
/**
@@ -606,11 +595,8 @@ class AgentSessionAdapter implements ISessionData {
private readonly _lastTurnEnd: ReturnType<typeof observableValue<Date | undefined>>;
readonly lastTurnEnd: IObservable<Date | undefined>;
private readonly _pullRequestUri: ReturnType<typeof observableValue<URI | undefined>>;
readonly pullRequestUri: IObservable<URI | undefined>;
private readonly _pullRequestStateIcon: ReturnType<typeof observableValue<ThemeIcon | undefined>>;
readonly pullRequestStateIcon: IObservable<ThemeIcon | undefined>;
private readonly _pullRequest: ReturnType<typeof observableValue<ISessionPullRequest | undefined>>;
readonly pullRequest: IObservable<ISessionPullRequest | undefined>;
constructor(
session: IAgentSession,
@@ -650,10 +636,8 @@ class AgentSessionAdapter implements ISessionData {
this.description = this._description;
this._lastTurnEnd = observableValue(this, session.timing.lastRequestEnded ? new Date(session.timing.lastRequestEnded) : undefined);
this.lastTurnEnd = this._lastTurnEnd;
this._pullRequestUri = observableValue(this, this._extractPullRequestUri(session));
this.pullRequestUri = this._pullRequestUri;
this._pullRequestStateIcon = observableValue(this, this._extractPullRequestStateIcon(session));
this.pullRequestStateIcon = this._pullRequestStateIcon;
this._pullRequest = observableValue(this, this._extractPullRequest(session));
this.pullRequest = this._pullRequest;
}
/**
@@ -670,8 +654,7 @@ class AgentSessionAdapter implements ISessionData {
this._isRead.set(session.isRead(), tx);
this._description.set(this._extractDescription(session), tx);
this._lastTurnEnd.set(session.timing.lastRequestEnded ? new Date(session.timing.lastRequestEnded) : undefined, tx);
this._pullRequestUri.set(this._extractPullRequestUri(session), tx);
this._pullRequestStateIcon.set(this._extractPullRequestStateIcon(session), tx);
this._pullRequest.set(this._extractPullRequest(session), tx);
});
}
@@ -682,6 +665,15 @@ class AgentSessionAdapter implements ISessionData {
return typeof session.description === 'string' ? session.description : session.description.value;
}
private _extractPullRequest(session: IAgentSession): ISessionPullRequest | undefined {
const uri = this._extractPullRequestUri(session);
if (!uri) {
return undefined;
}
const icon = this._extractPullRequestStateIcon(session);
return { uri, icon: icon };
}
private _extractPullRequestStateIcon(session: IAgentSession): ThemeIcon | undefined {
const metadata = session.metadata;
const state = metadata?.pullRequestState;
@@ -748,12 +740,6 @@ class AgentSessionAdapter implements ISessionData {
}
private _buildWorkspace(session: IAgentSession): ISessionWorkspace | undefined {
// Use the same repository name extraction as the old agent sessions view
const label = getRepositoryName(session);
if (!label) {
return undefined;
}
const [repoUri, worktreeUri, branchName, baseBranchProtected] = this._extractRepositoryFromMetadata(session);
const repository: ISessionRepository = {
@@ -764,9 +750,10 @@ class AgentSessionAdapter implements ISessionData {
};
return {
label,
label: getRepositoryName(session) ?? basename(repository.uri),
icon: repoUri?.scheme === GITHUB_REMOTE_FILE_SCHEME ? Codicon.repo : Codicon.folder,
repositories: [repository],
requiresWorkspaceTrust: session.providerType !== AgentSessionProviders.Cloud,
};
}
@@ -1047,7 +1034,10 @@ export class CopilotChatSessionsProvider extends Disposable implements ISessions
}
// Wait for the agent session to appear
return this._waitForNewAgentSession(session.target, existingSessions);
const createdSession = await this._waitForNewAgentSession(session.target, existingSessions);
this._currentNewSession?.dispose();
this._currentNewSession = undefined;
return createdSession;
}
private async _waitForNewAgentSession(target: AgentSessionTarget, existingSessions: ResourceSet): Promise<ISessionData> {
@@ -1080,6 +1070,7 @@ export class CopilotChatSessionsProvider extends Disposable implements ISessions
label: this._labelFromUri(uri),
icon: this._iconFromUri(uri),
repositories: [{ uri, workingDirectory: undefined, detail: undefined, baseBranchProtected: undefined }],
requiresWorkspaceTrust: true
};
}
return undefined;
@@ -1093,6 +1084,7 @@ export class CopilotChatSessionsProvider extends Disposable implements ISessions
label: this._labelFromUri(uri),
icon: this._iconFromUri(uri),
repositories: [{ uri, workingDirectory: undefined, detail: undefined, baseBranchProtected: undefined }],
requiresWorkspaceTrust: false,
};
}
return undefined;
@@ -1103,6 +1095,7 @@ export class CopilotChatSessionsProvider extends Disposable implements ISessions
label: this._labelFromUri(repositoryUri),
icon: this._iconFromUri(repositoryUri),
repositories: [{ uri: repositoryUri, workingDirectory: undefined, detail: undefined, baseBranchProtected: undefined }],
requiresWorkspaceTrust: repositoryUri.scheme !== GITHUB_REMOTE_FILE_SCHEME
};
}
@@ -1134,6 +1127,7 @@ export class CopilotChatSessionsProvider extends Disposable implements ISessions
for (const session of this.agentSessionsService.model.sessions) {
if (session.resource.toString() === this._currentNewSession?.resource.toString()) {
this._currentNewSession.update(new AgentSessionAdapter(session, this.id));
continue;
}

View File

@@ -14,17 +14,10 @@ import { localize } from '../../../../nls.js';
import { IFileDialogService } from '../../../../platform/dialogs/common/dialogs.js';
import { ISessionData, ISessionWorkspace, SessionStatus } from '../../sessions/common/sessionData.js';
import { ISendRequestOptions, ISessionsBrowseAction, ISessionsChangeEvent, ISessionsProvider, ISessionType } from '../../sessions/browser/sessionsProvider.js';
import { CopilotCLISessionType } from '../../sessions/browser/sessionTypes.js';
import { IChatSessionFileChange } from '../../../../workbench/contrib/chat/common/chatSessionsService.js';
import { agentHostUri } from '../../../../platform/agentHost/common/agentHostFileSystemProvider.js';
import { AGENT_HOST_SCHEME, agentHostAuthority } from '../../../../platform/agentHost/common/agentHostUri.js';
import { AgentSessionProviders } from '../../../../workbench/contrib/chat/browser/agentSessions/agentSessions.js';
const CopilotCLISessionType: ISessionType = {
id: AgentSessionProviders.AgentHostCopilot,
label: localize('copilotCLI', "Copilot"),
icon: Codicon.copilot,
requiresWorkspaceTrust: true,
};
/**
* A sessions provider for a single agent on a remote agent host connection.
@@ -73,6 +66,7 @@ export class RemoteAgentHostSessionsProvider extends Disposable implements ISess
label: repositoryUri.path.split('/').pop() || repositoryUri.path,
icon: Codicon.remote,
repositories: [{ uri: repositoryUri, workingDirectory: undefined, detail: this.label, baseBranchProtected: undefined }],
requiresWorkspaceTrust: true
};
}
@@ -108,6 +102,7 @@ export class RemoteAgentHostSessionsProvider extends Disposable implements ISess
label: workspaceUri.path.split('/').pop() || workspaceUri.path,
icon: Codicon.remote,
repositories: [{ uri: workspaceUri, workingDirectory: undefined, detail: this.label, baseBranchProtected: undefined }],
requiresWorkspaceTrust: true
}),
title: observableValue(this, ''),
updatedAt: observableValue(this, new Date()),
@@ -120,8 +115,7 @@ export class RemoteAgentHostSessionsProvider extends Disposable implements ISess
isRead: observableValue(this, true),
description: observableValue(this, undefined),
lastTurnEnd: observableValue(this, undefined),
pullRequestUri: observableValue(this, undefined),
pullRequestStateIcon: observableValue(this, undefined),
pullRequest: observableValue(this, undefined),
};
}
@@ -183,6 +177,7 @@ export class RemoteAgentHostSessionsProvider extends Disposable implements ISess
label,
icon: Codicon.remote,
repositories: [{ uri, workingDirectory: undefined, detail: this.label, baseBranchProtected: undefined }],
requiresWorkspaceTrust: true
};
}
} catch {

View File

@@ -0,0 +1,29 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { Codicon } from '../../../../base/common/codicons.js';
import { localize } from '../../../../nls.js';
import { AgentSessionProviders } from '../../../../workbench/contrib/chat/browser/agentSessions/agentSessions.js';
import { ISessionType } from './sessionsProvider.js';
/** Session type ID for local Copilot CLI sessions. */
export const COPILOT_CLI_SESSION_TYPE = AgentSessionProviders.Background;
/** Session type ID for Copilot Cloud sessions. */
export const COPILOT_CLOUD_SESSION_TYPE = AgentSessionProviders.Cloud;
/** Copilot CLI session type — local background agent running in a Git worktree. */
export const CopilotCLISessionType: ISessionType = {
id: COPILOT_CLI_SESSION_TYPE,
label: localize('copilotCLI', "Copilot CLI"),
icon: Codicon.copilot,
};
/** Copilot Cloud session type - cloud-hosted agent. */
export const CopilotCloudSessionType: ISessionType = {
id: COPILOT_CLOUD_SESSION_TYPE,
label: localize('copilotCloud', "Cloud"),
icon: Codicon.cloud,
};

View File

@@ -558,7 +558,7 @@ export class SessionsManagementService extends Disposable implements ISessionsMa
}
private _parsePRNumberFromSession(session: ISessionData): number | undefined {
const prUri = session.pullRequestUri.get();
const prUri = session.pullRequest.get()?.uri;
if (prUri) {
const match = /\/pull\/(\d+)/.exec(prUri.path);
if (match) {

View File

@@ -20,8 +20,6 @@ export interface ISessionType {
readonly label: string;
/** Icon for this session type. */
readonly icon: ThemeIcon;
/** Whether this session type requires workspace trust before creating a session. */
readonly requiresWorkspaceTrust?: boolean;
}
/**

View File

@@ -225,10 +225,10 @@ class SessionItemRenderer implements ITreeRenderer<SessionListItem, FuzzyScore,
const sessionStatus = element.status.read(reader);
const isRead = element.isRead.read(reader);
const isArchived = element.isArchived.read(reader);
const pullRequestStateIcon = element.pullRequestStateIcon.read(reader);
const pullRequest = element.pullRequest.read(reader);
DOM.clearNode(template.iconContainer);
const hasPrIcon = !!pullRequestStateIcon;
const icon = hasPrIcon ? pullRequestStateIcon : this.getStatusIcon(sessionStatus, isRead, isArchived);
const hasPrIcon = !!pullRequest;
const icon = pullRequest?.icon ? pullRequest.icon : this.getStatusIcon(sessionStatus, isRead, isArchived);
const iconSpan = DOM.append(template.iconContainer, $(`span${ThemeIcon.asCSSSelector(icon)}`));
iconSpan.style.color = icon.color ? asCssVariable(icon.color.id) : '';
template.iconContainer.classList.toggle('session-icon-pulse', !hasPrIcon && sessionStatus === SessionStatus.NeedsInput);

View File

@@ -21,7 +21,7 @@ import { SessionItemToolbarMenuId, SessionItemContextMenuId, SessionSectionToolb
import { ISessionsManagementService, IsNewChatSessionContext } from '../sessionsManagementService.js';
import { ISessionData, SessionStatus } from '../../common/sessionData.js';
import { IsRepositoryGroupCappedContext, SessionsViewFilterOptionsSubMenu, SessionsViewFilterSubMenu, SessionsViewGroupingContext, SessionsViewId, SessionsView, SessionsViewSortingContext } from './sessionsView.js';
import { SessionsViewId as NewChatViewId } from '../../../chat/browser/newChatViewPane.js';
import { SessionsViewId as NewChatViewId, NewChatViewPane } from '../../../chat/browser/newChatViewPane.js';
import { Menus } from '../../../../browser/menus.js';
import { SessionsWelcomeVisibleContext } from '../../../../common/contextkeys.js';
@@ -261,7 +261,11 @@ registerAction2(class NewSessionForRepositoryAction extends Action2 {
const sessionsManagementService = accessor.get(ISessionsManagementService);
const viewsService = accessor.get(IViewsService);
sessionsManagementService.openNewSessionView();
await viewsService.openView(NewChatViewId, true);
const view = await viewsService.openView<NewChatViewPane>(NewChatViewId, true);
const workspace = context.sessions[0].workspace.get();
if (view && workspace) {
view.selectWorkspace({ providerId: context.sessions[0].providerId, workspace });
}
}
});

View File

@@ -50,6 +50,18 @@ export interface ISessionWorkspace {
readonly icon: ThemeIcon;
/** Repositories in this workspace. */
readonly repositories: ISessionRepository[];
/** Whether the session requires workspace trust to operate. */
readonly requiresWorkspaceTrust: boolean;
}
/**
* Pull request information associated with a session.
*/
export interface ISessionPullRequest {
/** URI of the pull request. */
readonly uri: URI;
/** Icon reflecting the PR state. */
readonly icon?: ThemeIcon;
}
/**
@@ -97,8 +109,6 @@ export interface ISessionData {
readonly description: IObservable<string | undefined>;
/** Timestamp of when the last agent turn ended, if any. */
readonly lastTurnEnd: IObservable<Date | undefined>;
/** URI of the pull request associated with this session, if any. */
readonly pullRequestUri: IObservable<URI | undefined>;
/** Icon reflecting the PR state */
readonly pullRequestStateIcon: IObservable<ThemeIcon | undefined>;
/** Pull request associated with this session, if any. */
readonly pullRequest: IObservable<ISessionPullRequest | undefined>;
}

View File

@@ -61,7 +61,7 @@ function makeAgentSession(opts: {
sessionType: opts.providerType ?? AgentSessionProviders.Local,
icon: Codicon.copilot,
createdAt: new Date(),
workspace: observableValue('test.workspace', repo ? { label: 'test', icon: Codicon.repo, repositories: [repo] } : undefined),
workspace: observableValue('test.workspace', repo ? { label: 'test', icon: Codicon.repo, repositories: [repo], requiresWorkspaceTrust: false, } : undefined),
title: observableValue('test.title', 'Test Session'),
updatedAt: observableValue('test.updatedAt', new Date()),
status: observableValue('test.status', 0),
@@ -73,8 +73,7 @@ function makeAgentSession(opts: {
isRead: observableValue('test.isRead', true),
lastTurnEnd: observableValue('test.lastTurnEnd', undefined),
description: observableValue('test.description', undefined),
pullRequestUri: observableValue('test.pullRequestUri', undefined),
pullRequestStateIcon: observableValue('test.pullRequestStateIcon', undefined),
pullRequest: observableValue('test.pullRequest', undefined),
};
}
@@ -92,7 +91,7 @@ function makeNonAgentSession(opts: { repository?: URI; worktree?: URI; providerT
sessionType: opts.providerType ?? AgentSessionProviders.Local,
icon: Codicon.copilot,
createdAt: new Date(),
workspace: observableValue('test.workspace', repo ? { label: 'test', icon: Codicon.repo, repositories: [repo] } : undefined),
workspace: observableValue('test.workspace', repo ? { label: 'test', icon: Codicon.repo, repositories: [repo], requiresWorkspaceTrust: false, } : undefined),
title: observableValue('test.title', 'Test Session'),
updatedAt: observableValue('test.updatedAt', new Date()),
status: observableValue('test.status', 0),
@@ -104,8 +103,7 @@ function makeNonAgentSession(opts: { repository?: URI; worktree?: URI; providerT
isRead: observableValue('test.isRead', true),
lastTurnEnd: observableValue('test.lastTurnEnd', undefined),
description: observableValue('test.description', undefined),
pullRequestUri: observableValue('test.pullRequestUri', undefined),
pullRequestStateIcon: observableValue('test.pullRequestStateIcon', undefined),
pullRequest: observableValue('test.pullRequest', undefined),
};
}

View File

@@ -34,6 +34,7 @@ export class WorkspaceFolderManagementContribution extends Disposable implements
super();
this._register(autorun(reader => {
const activeSession = this.sessionManagementService.activeSession.read(reader);
activeSession?.workspace.read(reader);
this.queue.queue(() => this.updateWorkspaceFoldersForSession(activeSession));
}));
}