mirror of
https://github.com/microsoft/vscode.git
synced 2026-04-02 08:15:56 +01:00
committed by
GitHub
parent
abdf722266
commit
cae186c9f8
@@ -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
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
29
src/vs/sessions/contrib/sessions/browser/sessionTypes.ts
Normal file
29
src/vs/sessions/contrib/sessions/browser/sessionTypes.ts
Normal 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,
|
||||
};
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 });
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -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>;
|
||||
}
|
||||
|
||||
@@ -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),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -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));
|
||||
}));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user