Path: blob/main/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessions.ts
5272 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/45import { localize } from '../../../../../nls.js';6import { Codicon } from '../../../../../base/common/codicons.js';7import { URI } from '../../../../../base/common/uri.js';8import { ThemeIcon } from '../../../../../base/common/themables.js';9import { observableValue } from '../../../../../base/common/observable.js';10import { IChatSessionTiming } from '../../common/chatService/chatService.js';11import { IChatSessionsExtensionPoint } from '../../common/chatSessionsService.js';12import { foreground, listActiveSelectionForeground, registerColor, transparent } from '../../../../../platform/theme/common/colorRegistry.js';13import { getChatSessionType } from '../../common/model/chatUri.js';1415export enum AgentSessionProviders {16Local = 'local',17Background = 'copilotcli',18Cloud = 'copilot-cloud-agent',19Claude = 'claude-code',20Codex = 'openai-codex',21Growth = 'copilot-growth',22}2324export function isBuiltInAgentSessionProvider(provider: string): boolean {25return provider === AgentSessionProviders.Local ||26provider === AgentSessionProviders.Background ||27provider === AgentSessionProviders.Cloud ||28provider === AgentSessionProviders.Claude;29}3031export function getAgentSessionProvider(sessionResource: URI | string): AgentSessionProviders | undefined {32const type = URI.isUri(sessionResource) ? getChatSessionType(sessionResource) : sessionResource;33switch (type) {34case AgentSessionProviders.Local:35case AgentSessionProviders.Background:36case AgentSessionProviders.Cloud:37case AgentSessionProviders.Claude:38case AgentSessionProviders.Codex:39case AgentSessionProviders.Growth:40return type;41default:42return undefined;43}44}4546/**47* Observable holding the display name for the background agent session provider.48* Updated via experiment treatment to allow A/B testing of the display name.49*/50export const backgroundAgentDisplayName = observableValue<string>('backgroundAgentDisplayName', localize('chat.session.providerLabel.background', "Background"));5152export function getAgentSessionProviderName(provider: AgentSessionProviders): string {53switch (provider) {54case AgentSessionProviders.Local:55return localize('chat.session.providerLabel.local', "Local");56case AgentSessionProviders.Background:57return backgroundAgentDisplayName.get();58case AgentSessionProviders.Cloud:59return localize('chat.session.providerLabel.cloud', "Cloud");60case AgentSessionProviders.Claude:61return 'Claude';62case AgentSessionProviders.Codex:63return 'Codex';64case AgentSessionProviders.Growth:65return 'Growth';66}67}6869export function getAgentSessionProviderIcon(provider: AgentSessionProviders): ThemeIcon {70switch (provider) {71case AgentSessionProviders.Local:72return Codicon.vm;73case AgentSessionProviders.Background:74return Codicon.worktree;75case AgentSessionProviders.Cloud:76return Codicon.cloud;77case AgentSessionProviders.Codex:78return Codicon.openai;79case AgentSessionProviders.Claude:80return Codicon.claude;81case AgentSessionProviders.Growth:82return Codicon.lightbulb;83}84}8586export function isFirstPartyAgentSessionProvider(provider: AgentSessionProviders): boolean {87switch (provider) {88case AgentSessionProviders.Local:89case AgentSessionProviders.Background:90case AgentSessionProviders.Cloud:91return true;92case AgentSessionProviders.Claude:93case AgentSessionProviders.Codex:94case AgentSessionProviders.Growth:95return false;96}97}9899export function getAgentCanContinueIn(provider: AgentSessionProviders, contribution?: IChatSessionsExtensionPoint): boolean {100// Read-only sessions (e.g., Growth) are passive/informational and cannot be delegation targets101if (contribution?.isReadOnly) {102return false;103}104switch (provider) {105case AgentSessionProviders.Local:106case AgentSessionProviders.Background:107case AgentSessionProviders.Cloud:108return true;109case AgentSessionProviders.Claude:110case AgentSessionProviders.Codex:111case AgentSessionProviders.Growth:112return false;113}114}115116export function getAgentSessionProviderDescription(provider: AgentSessionProviders): string {117switch (provider) {118case AgentSessionProviders.Local:119return localize('chat.session.providerDescription.local', "Run tasks within VS Code chat. The agent iterates via chat and works interactively to implement changes on your main workspace.");120case AgentSessionProviders.Background:121return localize('chat.session.providerDescription.background', "Delegate tasks to a background agent running locally on your machine. The agent iterates via chat and works asynchronously in a Git worktree to implement changes isolated from your main workspace using the GitHub Copilot CLI.");122case AgentSessionProviders.Cloud:123return localize('chat.session.providerDescription.cloud', "Delegate tasks to the GitHub Copilot coding agent. The agent iterates via chat and works asynchronously in the cloud to implement changes and pull requests as needed.");124case AgentSessionProviders.Claude:125return localize('chat.session.providerDescription.claude', "Delegate tasks to the Claude Agent SDK using the Claude models included in your GitHub Copilot subscription. The agent iterates via chat and works interactively to implement changes on your main workspace.");126case AgentSessionProviders.Codex:127return localize('chat.session.providerDescription.codex', "Opens a new Codex session in the editor. Codex sessions can be managed from the chat sessions view.");128case AgentSessionProviders.Growth:129return localize('chat.session.providerDescription.growth', "Educational messages to help you learn Copilot features.");130}131}132133export enum AgentSessionsViewerOrientation {134Stacked = 1,135SideBySide,136}137138export enum AgentSessionsViewerPosition {139Left = 1,140Right,141}142143export interface IAgentSessionsControl {144145readonly element: HTMLElement | undefined;146147refresh(): void;148openFind(): void;149150reveal(sessionResource: URI): boolean;151152clearFocus(): void;153hasFocusOrSelection(): boolean;154}155156export const agentSessionReadIndicatorForeground = registerColor(157'agentSessionReadIndicator.foreground',158{ dark: transparent(foreground, 0.2), light: transparent(foreground, 0.2), hcDark: null, hcLight: null },159localize('agentSessionReadIndicatorForeground', "Foreground color for the read indicator in an agent session.")160);161162export const agentSessionSelectedBadgeBorder = registerColor(163'agentSessionSelectedBadge.border',164{ dark: transparent(listActiveSelectionForeground, 0.3), light: transparent(listActiveSelectionForeground, 0.3), hcDark: foreground, hcLight: foreground },165localize('agentSessionSelectedBadgeBorder', "Border color for the badges in selected agent session items.")166);167168export const agentSessionSelectedUnfocusedBadgeBorder = registerColor(169'agentSessionSelectedUnfocusedBadge.border',170{ dark: transparent(foreground, 0.3), light: transparent(foreground, 0.3), hcDark: foreground, hcLight: foreground },171localize('agentSessionSelectedUnfocusedBadgeBorder', "Border color for the badges in selected agent session items when the view is unfocused.")172);173174export const AGENT_SESSION_RENAME_ACTION_ID = 'agentSession.rename';175export const AGENT_SESSION_DELETE_ACTION_ID = 'agentSession.delete';176177export function getAgentSessionTime(timing: IChatSessionTiming): number {178return timing.lastRequestEnded ?? timing.lastRequestStarted ?? timing.created;179}180181182