Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/workbench/contrib/chat/browser/chat.contribution.ts
5263 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
import { timeout } from '../../../../base/common/async.js';
7
import { Event } from '../../../../base/common/event.js';
8
import { MarkdownString, isMarkdownString } from '../../../../base/common/htmlContent.js';
9
import { Disposable, DisposableMap } from '../../../../base/common/lifecycle.js';
10
import { Schemas } from '../../../../base/common/network.js';
11
import { isMacintosh } from '../../../../base/common/platform.js';
12
import { PolicyCategory } from '../../../../base/common/policy.js';
13
import { registerEditorFeature } from '../../../../editor/common/editorFeatures.js';
14
import * as nls from '../../../../nls.js';
15
import { AccessibleViewRegistry } from '../../../../platform/accessibility/browser/accessibleViewRegistry.js';
16
import { registerAction2 } from '../../../../platform/actions/common/actions.js';
17
import { ICommandService } from '../../../../platform/commands/common/commands.js';
18
import { Extensions as ConfigurationExtensions, ConfigurationScope, IConfigurationNode, IConfigurationRegistry } from '../../../../platform/configuration/common/configurationRegistry.js';
19
import { SyncDescriptor } from '../../../../platform/instantiation/common/descriptors.js';
20
import { InstantiationType, registerSingleton } from '../../../../platform/instantiation/common/extensions.js';
21
import { IInstantiationService } from '../../../../platform/instantiation/common/instantiation.js';
22
import { McpAccessValue, McpAutoStartValue, mcpAccessConfig, mcpAutoStartConfig, mcpGalleryServiceEnablementConfig, mcpGalleryServiceUrlConfig, mcpAppsEnabledConfig } from '../../../../platform/mcp/common/mcpManagement.js';
23
import product from '../../../../platform/product/common/product.js';
24
import { Registry } from '../../../../platform/registry/common/platform.js';
25
import { EditorPaneDescriptor, IEditorPaneRegistry } from '../../../browser/editor.js';
26
import { Extensions, IConfigurationMigrationRegistry } from '../../../common/configuration.js';
27
import { IWorkbenchContribution, WorkbenchPhase, registerWorkbenchContribution2 } from '../../../common/contributions.js';
28
import { EditorExtensions, IEditorFactoryRegistry } from '../../../common/editor.js';
29
import { IWorkbenchAssignmentService } from '../../../services/assignment/common/assignmentService.js';
30
import { ChatEntitlement, IChatEntitlementService } from '../../../services/chat/common/chatEntitlementService.js';
31
import { IEditorResolverService, RegisteredEditorPriority } from '../../../services/editor/common/editorResolverService.js';
32
import { AddConfigurationType, AssistedTypes } from '../../mcp/browser/mcpCommandsAddConfiguration.js';
33
import { allDiscoverySources, discoverySourceSettingsLabel, mcpDiscoverySection, mcpServerSamplingSection } from '../../mcp/common/mcpConfiguration.js';
34
import { ChatAgentNameService, ChatAgentService, IChatAgentNameService, IChatAgentService } from '../common/participants/chatAgents.js';
35
import { CodeMapperService, ICodeMapperService } from '../common/editing/chatCodeMapperService.js';
36
import '../common/widget/chatColors.js';
37
import { IChatEditingService } from '../common/editing/chatEditingService.js';
38
import { IChatLayoutService } from '../common/widget/chatLayoutService.js';
39
import { ChatModeService, IChatMode, IChatModeService } from '../common/chatModes.js';
40
import { ChatResponseResourceFileSystemProvider } from '../common/widget/chatResponseResourceFileSystemProvider.js';
41
import { IChatService } from '../common/chatService/chatService.js';
42
import { ChatService } from '../common/chatService/chatServiceImpl.js';
43
import { IChatSessionsService } from '../common/chatSessionsService.js';
44
import { ChatSlashCommandService, IChatSlashCommandService } from '../common/participants/chatSlashCommands.js';
45
import { ChatTodoListService, IChatTodoListService } from '../common/tools/chatTodoListService.js';
46
import { ChatTransferService, IChatTransferService } from '../common/model/chatTransferService.js';
47
import { IChatVariablesService } from '../common/attachments/chatVariables.js';
48
import { ChatWidgetHistoryService, IChatWidgetHistoryService } from '../common/widget/chatWidgetHistoryService.js';
49
import { AgentsControlClickBehavior, ChatAgentLocation, ChatConfiguration, ChatModeKind } from '../common/constants.js';
50
import { ILanguageModelIgnoredFilesService, LanguageModelIgnoredFilesService } from '../common/ignoredFiles.js';
51
import { ILanguageModelsService, LanguageModelsService } from '../common/languageModels.js';
52
import { ILanguageModelStatsService, LanguageModelStatsService } from '../common/languageModelStats.js';
53
import { ILanguageModelToolsConfirmationService } from '../common/tools/languageModelToolsConfirmationService.js';
54
import { ILanguageModelToolsService } from '../common/tools/languageModelToolsService.js';
55
import { ChatPromptFilesExtensionPointHandler } from '../common/promptSyntax/chatPromptFilesContribution.js';
56
import { PromptsConfig } from '../common/promptSyntax/config/config.js';
57
import { INSTRUCTIONS_DEFAULT_SOURCE_FOLDER, INSTRUCTION_FILE_EXTENSION, LEGACY_MODE_DEFAULT_SOURCE_FOLDER, LEGACY_MODE_FILE_EXTENSION, PROMPT_DEFAULT_SOURCE_FOLDER, PROMPT_FILE_EXTENSION, DEFAULT_SKILL_SOURCE_FOLDERS, AGENTS_SOURCE_FOLDER, AGENT_FILE_EXTENSION, SKILL_FILENAME, CLAUDE_AGENTS_SOURCE_FOLDER, CLAUDE_RULES_SOURCE_FOLDER, DEFAULT_HOOK_FILE_PATHS } from '../common/promptSyntax/config/promptFileLocations.js';
58
import { PromptLanguageFeaturesProvider } from '../common/promptSyntax/promptFileContributions.js';
59
import { AGENT_DOCUMENTATION_URL, INSTRUCTIONS_DOCUMENTATION_URL, PROMPT_DOCUMENTATION_URL, SKILL_DOCUMENTATION_URL, HOOK_DOCUMENTATION_URL } from '../common/promptSyntax/promptTypes.js';
60
import { hookFileSchema, HOOK_SCHEMA_URI, HOOK_FILE_GLOB } from '../common/promptSyntax/hookSchema.js';
61
import { Extensions as JSONExtensions, IJSONContributionRegistry } from '../../../../platform/jsonschemas/common/jsonContributionRegistry.js';
62
import { IPromptsService } from '../common/promptSyntax/service/promptsService.js';
63
import { PromptsService } from '../common/promptSyntax/service/promptsServiceImpl.js';
64
import { LanguageModelToolsExtensionPointHandler } from '../common/tools/languageModelToolsContribution.js';
65
import { BuiltinToolsContribution } from '../common/tools/builtinTools/tools.js';
66
import { IVoiceChatService, VoiceChatService } from '../common/voiceChatService.js';
67
import { registerChatAccessibilityActions } from './actions/chatAccessibilityActions.js';
68
import { AgentChatAccessibilityHelp, EditsChatAccessibilityHelp, PanelChatAccessibilityHelp, QuickChatAccessibilityHelp } from './actions/chatAccessibilityHelp.js';
69
import { ACTION_ID_NEW_CHAT, ModeOpenChatGlobalAction, registerChatActions } from './actions/chatActions.js';
70
import { CodeBlockActionRendering, registerChatCodeBlockActions, registerChatCodeCompareBlockActions } from './actions/chatCodeblockActions.js';
71
import { ChatContextContributions } from './actions/chatContext.js';
72
import { registerChatContextActions } from './actions/chatContextActions.js';
73
import { registerChatCopyActions } from './actions/chatCopyActions.js';
74
import { registerChatDeveloperActions } from './actions/chatDeveloperActions.js';
75
import { ChatSubmitAction, registerChatExecuteActions } from './actions/chatExecuteActions.js';
76
import { registerChatFileTreeActions } from './actions/chatFileTreeActions.js';
77
import { ChatGettingStartedContribution } from './actions/chatGettingStarted.js';
78
import { registerChatExportActions } from './actions/chatImportExport.js';
79
import { registerLanguageModelActions } from './actions/chatLanguageModelActions.js';
80
import { registerMoveActions } from './actions/chatMoveActions.js';
81
import { registerNewChatActions } from './actions/chatNewActions.js';
82
import { registerChatPromptNavigationActions } from './actions/chatPromptNavigationActions.js';
83
import { registerChatQueueActions } from './actions/chatQueueActions.js';
84
import { registerQuickChatActions } from './actions/chatQuickInputActions.js';
85
import { ChatAgentRecommendation } from './actions/chatAgentRecommendationActions.js';
86
import { registerChatTitleActions } from './actions/chatTitleActions.js';
87
import { registerChatElicitationActions } from './actions/chatElicitationActions.js';
88
import { registerChatToolActions } from './actions/chatToolActions.js';
89
import { ChatTransferContribution } from './actions/chatTransfer.js';
90
import { registerChatCustomizationDiagnosticsAction } from './actions/chatCustomizationDiagnosticsAction.js';
91
import './agentSessions/agentSessions.contribution.js';
92
import { backgroundAgentDisplayName } from './agentSessions/agentSessions.js';
93
import { IAgentSessionsService } from './agentSessions/agentSessionsService.js';
94
import { IChatAccessibilityService, IChatCodeBlockContextProviderService, IChatWidgetService, IQuickChatService } from './chat.js';
95
import { ChatAccessibilityService } from './accessibility/chatAccessibilityService.js';
96
import './attachments/chatAttachmentModel.js';
97
import './widget/input/chatStatusWidget.js';
98
import { ChatAttachmentResolveService, IChatAttachmentResolveService } from './attachments/chatAttachmentResolveService.js';
99
import { ChatMarkdownAnchorService, IChatMarkdownAnchorService } from './widget/chatContentParts/chatMarkdownAnchorService.js';
100
import { ChatContextPickService, IChatContextPickService } from './attachments/chatContextPickService.js';
101
import { ChatInputBoxContentProvider } from './widget/input/editor/chatEditorInputContentProvider.js';
102
import { ChatEditingEditorAccessibility } from './chatEditing/chatEditingEditorAccessibility.js';
103
import { registerChatEditorActions } from './chatEditing/chatEditingEditorActions.js';
104
import { ChatEditingEditorContextKeys } from './chatEditing/chatEditingEditorContextKeys.js';
105
import { ChatEditingEditorOverlay } from './chatEditing/chatEditingEditorOverlay.js';
106
import { ChatEditingService } from './chatEditing/chatEditingServiceImpl.js';
107
import { ChatEditingNotebookFileSystemProviderContrib } from './chatEditing/notebook/chatEditingNotebookFileSystemProvider.js';
108
import { SimpleBrowserOverlay } from './attachments/simpleBrowserEditorOverlay.js';
109
import { ChatEditor, IChatEditorOptions } from './widgetHosts/editor/chatEditor.js';
110
import { ChatEditorInput, ChatEditorInputSerializer } from './widgetHosts/editor/chatEditorInput.js';
111
import { ChatLayoutService } from './widget/chatLayoutService.js';
112
import { ChatLanguageModelsDataContribution, LanguageModelsConfigurationService } from './languageModelsConfigurationService.js';
113
import './chatManagement/chatManagement.contribution.js';
114
import { agentSlashCommandToMarkdown, agentToMarkdown } from './widget/chatContentParts/chatMarkdownDecorationsRenderer.js';
115
import { ChatOutputRendererService, IChatOutputRendererService } from './chatOutputItemRenderer.js';
116
import { ChatCompatibilityNotifier, ChatExtensionPointHandler } from './chatParticipant.contribution.js';
117
import { ChatPasteProvidersFeature } from './widget/input/editor/chatPasteProviders.js';
118
import { QuickChatService } from './widgetHosts/chatQuick.js';
119
import { ChatResponseAccessibleView } from './accessibility/chatResponseAccessibleView.js';
120
import { ChatTerminalOutputAccessibleView } from './accessibility/chatTerminalOutputAccessibleView.js';
121
import { ChatSetupContribution, ChatTeardownContribution } from './chatSetup/chatSetupContributions.js';
122
import { ChatStatusBarEntry } from './chatStatus/chatStatusEntry.js';
123
import { ChatVariablesService } from './attachments/chatVariables.js';
124
import { ChatWidget } from './widget/chatWidget.js';
125
import { ChatCodeBlockContextProviderService } from './codeBlockContextProviderService.js';
126
import { ChatDynamicVariableModel } from './attachments/chatDynamicVariables.js';
127
import { ChatImplicitContextContribution } from './attachments/chatImplicitContext.js';
128
import './widget/input/editor/chatInputCompletions.js';
129
import './widget/input/editor/chatInputEditorContrib.js';
130
import './widget/input/editor/chatInputEditorHover.js';
131
import { LanguageModelToolsConfirmationService } from './tools/languageModelToolsConfirmationService.js';
132
import { LanguageModelToolsService, globalAutoApproveDescription } from './tools/languageModelToolsService.js';
133
import './promptSyntax/promptCodingAgentActionContribution.js';
134
import './promptSyntax/promptToolsCodeLensProvider.js';
135
import { showConfigureHooksQuickPick } from './promptSyntax/hookActions.js';
136
import { PromptUrlHandler } from './promptSyntax/promptUrlHandler.js';
137
import { ConfigureToolSets, UserToolSetsContributions } from './tools/toolSetsContribution.js';
138
import { ChatViewsWelcomeHandler } from './viewsWelcome/chatViewsWelcomeHandler.js';
139
import { ChatWidgetService } from './widget/chatWidgetService.js';
140
import { ILanguageModelsConfigurationService } from '../common/languageModelsConfiguration.js';
141
import { ChatWindowNotifier } from './chatWindowNotifier.js';
142
import { ChatRepoInfoContribution } from './chatRepoInfo.js';
143
import { VALID_PROMPT_FOLDER_PATTERN } from '../common/promptSyntax/utils/promptFilesLocator.js';
144
import { ChatTipService, IChatTipService } from './chatTipService.js';
145
import { ChatQueuePickerRendering } from './widget/input/chatQueuePickerActionItem.js';
146
import { PlanAgentDefaultModel } from './planAgentDefaultModel.js';
147
148
const toolReferenceNameEnumValues: string[] = [];
149
const toolReferenceNameEnumDescriptions: string[] = [];
150
151
// Register JSON schema for hook files
152
const jsonContributionRegistry = Registry.as<IJSONContributionRegistry>(JSONExtensions.JSONContribution);
153
jsonContributionRegistry.registerSchema(HOOK_SCHEMA_URI, hookFileSchema);
154
jsonContributionRegistry.registerSchemaAssociation(HOOK_SCHEMA_URI, HOOK_FILE_GLOB);
155
156
// Register configuration
157
const configurationRegistry = Registry.as<IConfigurationRegistry>(ConfigurationExtensions.Configuration);
158
configurationRegistry.registerConfiguration({
159
id: 'chatSidebar',
160
title: nls.localize('interactiveSessionConfigurationTitle', "Chat"),
161
type: 'object',
162
properties: {
163
'chat.fontSize': {
164
type: 'number',
165
description: nls.localize('chat.fontSize', "Controls the font size in pixels in chat messages."),
166
default: 13,
167
minimum: 6,
168
maximum: 100
169
},
170
'chat.fontFamily': {
171
type: 'string',
172
description: nls.localize('chat.fontFamily', "Controls the font family in chat messages."),
173
default: 'default'
174
},
175
'chat.editor.fontSize': {
176
type: 'number',
177
description: nls.localize('interactiveSession.editor.fontSize', "Controls the font size in pixels in chat codeblocks."),
178
default: isMacintosh ? 12 : 14,
179
},
180
'chat.editor.fontFamily': {
181
type: 'string',
182
description: nls.localize('interactiveSession.editor.fontFamily', "Controls the font family in chat codeblocks."),
183
default: 'default'
184
},
185
'chat.editor.fontWeight': {
186
type: 'string',
187
description: nls.localize('interactiveSession.editor.fontWeight', "Controls the font weight in chat codeblocks."),
188
default: 'default'
189
},
190
'chat.editor.wordWrap': {
191
type: 'string',
192
description: nls.localize('interactiveSession.editor.wordWrap', "Controls whether lines should wrap in chat codeblocks."),
193
default: 'off',
194
enum: ['on', 'off']
195
},
196
'chat.editor.lineHeight': {
197
type: 'number',
198
description: nls.localize('interactiveSession.editor.lineHeight', "Controls the line height in pixels in chat codeblocks. Use 0 to compute the line height from the font size."),
199
default: 0
200
},
201
[ChatConfiguration.AgentsControlClickBehavior]: {
202
type: 'string',
203
enum: [AgentsControlClickBehavior.Default, AgentsControlClickBehavior.Cycle, AgentsControlClickBehavior.Focus],
204
enumDescriptions: [
205
nls.localize('chat.agentsControl.clickBehavior.default', "Clicking chat icon toggles chat visibility."),
206
nls.localize('chat.agentsControl.clickBehavior.cycle', "Clicking chat icon cycles through: show chat, maximize chat, hide chat. This requires chat to be contained in the secondary sidebar."),
207
nls.localize('chat.agentsControl.clickBehavior.focus', "Clicking chat icon focuses the chat view and maximizes it if located in the secondary sidebar.")
208
],
209
markdownDescription: nls.localize('chat.agentsControl.clickBehavior', "Controls the behavior when clicking on the chat icon in the command center."),
210
default: product.quality !== 'stable' ? AgentsControlClickBehavior.Cycle : AgentsControlClickBehavior.Default,
211
tags: ['experimental']
212
},
213
[ChatConfiguration.AgentStatusEnabled]: {
214
type: 'boolean',
215
markdownDescription: nls.localize('chat.agentsControl.enabled', "Controls whether the 'Agent Status' indicator is shown in the title bar command center. Enabling this setting will automatically enable {0}. The unread/in-progress session indicators require {1} to be enabled.", '`#window.commandCenter#`', '`#chat.viewSessions.enabled#`'),
216
default: true,
217
tags: ['experimental']
218
},
219
[ChatConfiguration.UnifiedAgentsBar]: {
220
type: 'boolean',
221
markdownDescription: nls.localize('chat.unifiedAgentsBar.enabled', "Replaces the command center search box with a unified chat and search widget."),
222
default: false,
223
tags: ['experimental']
224
},
225
[ChatConfiguration.AgentSessionProjectionEnabled]: {
226
type: 'boolean',
227
markdownDescription: nls.localize('chat.agentSessionProjection.enabled', "Controls whether Agent Session Projection mode is enabled for reviewing agent sessions in a focused workspace."),
228
default: false,
229
tags: ['experimental'],
230
},
231
'chat.implicitContext.enabled': {
232
type: 'object',
233
description: nls.localize('chat.implicitContext.enabled.1', "Enables automatically using the active editor as chat context for specified chat locations."),
234
additionalProperties: {
235
type: 'string',
236
enum: ['never', 'first', 'always'],
237
description: nls.localize('chat.implicitContext.value', "The value for the implicit context."),
238
enumDescriptions: [
239
nls.localize('chat.implicitContext.value.never', "Implicit context is never enabled."),
240
nls.localize('chat.implicitContext.value.first', "Implicit context is enabled for the first interaction."),
241
nls.localize('chat.implicitContext.value.always', "Implicit context is always enabled.")
242
]
243
},
244
default: {
245
'panel': 'always',
246
}
247
},
248
'chat.implicitContext.suggestedContext': {
249
type: 'boolean',
250
markdownDescription: nls.localize('chat.implicitContext.suggestedContext', "Controls whether the new implicit context flow is shown. In Ask and Edit modes, the context will automatically be included. When using an agent, context will be suggested as an attachment. Selections are always included as context."),
251
default: true,
252
},
253
'chat.editing.autoAcceptDelay': {
254
type: 'number',
255
markdownDescription: nls.localize('chat.editing.autoAcceptDelay', "Delay after which changes made by chat are automatically accepted. Values are in seconds, `0` means disabled and `100` seconds is the maximum."),
256
default: 0,
257
minimum: 0,
258
maximum: 100
259
},
260
'chat.editing.confirmEditRequestRemoval': {
261
type: 'boolean',
262
scope: ConfigurationScope.APPLICATION,
263
markdownDescription: nls.localize('chat.editing.confirmEditRequestRemoval', "Whether to show a confirmation before removing a request and its associated edits."),
264
default: true,
265
},
266
'chat.editing.confirmEditRequestRetry': {
267
type: 'boolean',
268
scope: ConfigurationScope.APPLICATION,
269
markdownDescription: nls.localize('chat.editing.confirmEditRequestRetry', "Whether to show a confirmation before retrying a request and its associated edits."),
270
default: true,
271
},
272
'chat.editing.explainChanges.enabled': {
273
type: 'boolean',
274
markdownDescription: nls.localize('chat.editing.explainChanges.enabled', "Controls whether the Explain button in the Chat panel and the Explain Changes context menu in the SCM view are shown. This is an experimental feature."),
275
default: false,
276
tags: ['experimental'],
277
experiment: {
278
mode: 'auto'
279
}
280
},
281
'chat.tips.enabled': {
282
type: 'boolean',
283
description: nls.localize('chat.tips.enabled', "Controls whether tips are shown above user messages in chat. This is an experimental feature."),
284
default: false,
285
tags: ['experimental'],
286
experiment: {
287
mode: 'auto'
288
}
289
},
290
'chat.confettiOnThumbsUp': {
291
type: 'boolean',
292
description: nls.localize('chat.confettiOnThumbsUp', "Controls whether a confetti animation is shown when clicking the thumbs up button on a chat response."),
293
default: false,
294
},
295
'chat.experimental.detectParticipant.enabled': {
296
type: 'boolean',
297
deprecationMessage: nls.localize('chat.experimental.detectParticipant.enabled.deprecated', "This setting is deprecated. Please use `chat.detectParticipant.enabled` instead."),
298
description: nls.localize('chat.experimental.detectParticipant.enabled', "Enables chat participant autodetection for panel chat."),
299
default: null
300
},
301
'chat.detectParticipant.enabled': {
302
type: 'boolean',
303
description: nls.localize('chat.detectParticipant.enabled', "Enables chat participant autodetection for panel chat."),
304
default: true
305
},
306
[ChatConfiguration.InlineReferencesStyle]: {
307
type: 'string',
308
enum: ['box', 'link'],
309
enumDescriptions: [
310
nls.localize('chat.inlineReferences.style.box', "Display file and symbol references as boxed widgets with icons."),
311
nls.localize('chat.inlineReferences.style.link', "Display file and symbol references as simple blue links without icons.")
312
],
313
description: nls.localize('chat.inlineReferences.style', "Controls how file and symbol references are displayed in chat messages."),
314
default: 'box'
315
},
316
[ChatConfiguration.EditorAssociations]: {
317
type: 'object',
318
markdownDescription: nls.localize('chat.editorAssociations', "Configure [glob patterns](https://aka.ms/vscode-glob-patterns) to editors for opening files from chat (for example `\"*.md\": \"vscode.markdown.preview.editor\"`)."),
319
additionalProperties: {
320
type: 'string'
321
},
322
default: {
323
}
324
},
325
'chat.notifyWindowOnConfirmation': {
326
type: 'boolean',
327
description: nls.localize('chat.notifyWindowOnConfirmation', "Controls whether a chat session should present the user with an OS notification when a confirmation is needed while the window is not in focus. This includes a window badge as well as notification toast."),
328
default: true,
329
},
330
[ChatConfiguration.GlobalAutoApprove]: {
331
default: false,
332
markdownDescription: globalAutoApproveDescription.value,
333
type: 'boolean',
334
scope: ConfigurationScope.APPLICATION_MACHINE,
335
tags: ['experimental'],
336
policy: {
337
name: 'ChatToolsAutoApprove',
338
category: PolicyCategory.InteractiveSession,
339
minimumVersion: '1.99',
340
value: (policyData) => policyData.chat_preview_features_enabled === false ? false : undefined,
341
localization: {
342
description: {
343
key: 'autoApprove2.description',
344
value: nls.localize('autoApprove2.description', 'Global auto approve also known as "YOLO mode" disables manual approval completely for all tools in all workspaces, allowing the agent to act fully autonomously. This is extremely dangerous and is *never* recommended, even containerized environments like Codespaces and Dev Containers have user keys forwarded into the container that could be compromised.\n\nThis feature disables critical security protections and makes it much easier for an attacker to compromise the machine.')
345
}
346
},
347
}
348
},
349
[ChatConfiguration.AutoApproveEdits]: {
350
default: {
351
'**/*': true,
352
'**/.vscode/*.json': false,
353
'**/.git/**': false,
354
'**/{package.json,server.xml,build.rs,web.config,.gitattributes,.env}': false,
355
'**/*.{code-workspace,csproj,fsproj,vbproj,vcxproj,proj,targets,props}': false,
356
'**/*.lock': false, // yarn.lock, bun.lock, etc.
357
'**/*-lock.{yaml,json}': false, // pnpm-lock.yaml, package-lock.json
358
},
359
markdownDescription: nls.localize('chat.tools.autoApprove.edits', "Controls whether edits made by chat are automatically approved. The default is to approve all edits except those made to certain files which have the potential to cause immediate unintended side-effects, such as `**/.vscode/*.json`.\n\nSet to `true` to automatically approve edits to matching files, `false` to always require explicit approval. The last pattern matching a given file will determine whether the edit is automatically approved."),
360
type: 'object',
361
additionalProperties: {
362
type: 'boolean',
363
}
364
},
365
[ChatConfiguration.AutoApprovedUrls]: {
366
default: {},
367
markdownDescription: nls.localize('chat.tools.fetchPage.approvedUrls', "Controls which URLs are automatically approved when requested by chat tools. Keys are URL patterns and values can be `true` to approve both requests and responses, `false` to deny, or an object with `approveRequest` and `approveResponse` properties for granular control.\n\nExamples:\n- `\"https://example.com\": true` - Approve all requests to example.com\n- `\"https://*.example.com\": true` - Approve all requests to any subdomain of example.com\n- `\"https://example.com/api/*\": { \"approveRequest\": true, \"approveResponse\": false }` - Approve requests but not responses for example.com/api paths"),
368
type: 'object',
369
additionalProperties: {
370
oneOf: [
371
{ type: 'boolean' },
372
{
373
type: 'object',
374
properties: {
375
approveRequest: { type: 'boolean' },
376
approveResponse: { type: 'boolean' }
377
}
378
}
379
]
380
}
381
},
382
[ChatConfiguration.EligibleForAutoApproval]: {
383
default: {},
384
markdownDescription: nls.localize('chat.tools.eligibleForAutoApproval', 'Controls which tools are eligible for automatic approval. Tools set to \'false\' will always present a confirmation and will never offer the option to auto-approve. The default behavior (or setting a tool to \'true\') may result in the tool offering auto-approval options.'),
385
type: 'object',
386
propertyNames: {
387
enum: toolReferenceNameEnumValues,
388
enumDescriptions: toolReferenceNameEnumDescriptions,
389
},
390
additionalProperties: {
391
type: 'boolean',
392
},
393
examples: [
394
{
395
'fetch': false,
396
'runTask': false
397
}
398
],
399
policy: {
400
name: 'ChatToolsEligibleForAutoApproval',
401
category: PolicyCategory.InteractiveSession,
402
minimumVersion: '1.107',
403
localization: {
404
description: {
405
key: 'chat.tools.eligibleForAutoApproval',
406
value: nls.localize('chat.tools.eligibleForAutoApproval', 'Controls which tools are eligible for automatic approval. Tools set to \'false\' will always present a confirmation and will never offer the option to auto-approve. The default behavior (or setting a tool to \'true\') may result in the tool offering auto-approval options.')
407
}
408
},
409
}
410
},
411
'chat.sendElementsToChat.enabled': {
412
default: true,
413
description: nls.localize('chat.sendElementsToChat.enabled', "Controls whether elements can be sent to chat from the Simple Browser."),
414
type: 'boolean',
415
tags: ['preview']
416
},
417
'chat.sendElementsToChat.attachCSS': {
418
default: true,
419
markdownDescription: nls.localize('chat.sendElementsToChat.attachCSS', "Controls whether CSS of the selected element will be added to the chat. {0} must be enabled.", '`#chat.sendElementsToChat.enabled#`'),
420
type: 'boolean',
421
tags: ['preview']
422
},
423
'chat.sendElementsToChat.attachImages': {
424
default: true,
425
markdownDescription: nls.localize('chat.sendElementsToChat.attachImages', "Controls whether a screenshot of the selected element will be added to the chat. {0} must be enabled.", '`#chat.sendElementsToChat.enabled#`'),
426
type: 'boolean',
427
tags: ['experimental']
428
},
429
'chat.undoRequests.restoreInput': {
430
default: true,
431
markdownDescription: nls.localize('chat.undoRequests.restoreInput', "Controls whether the input of the chat should be restored when an undo request is made. The input will be filled with the text of the request that was restored."),
432
type: 'boolean',
433
},
434
'chat.editRequests': {
435
markdownDescription: nls.localize('chat.editRequests', "Enables editing of requests in the chat. This allows you to change the request content and resubmit it to the model."),
436
type: 'string',
437
enum: ['inline', 'hover', 'input', 'none'],
438
default: 'inline',
439
},
440
[ChatConfiguration.ChatViewSessionsEnabled]: {
441
type: 'boolean',
442
default: true,
443
description: nls.localize('chat.viewSessions.enabled', "Show chat agent sessions when chat is empty or to the side when chat view is wide enough."),
444
},
445
[ChatConfiguration.ChatViewSessionsOrientation]: {
446
type: 'string',
447
enum: ['stacked', 'sideBySide'],
448
enumDescriptions: [
449
nls.localize('chat.viewSessions.orientation.stacked', "Display chat sessions vertically stacked above the chat input unless a chat session is visible."),
450
nls.localize('chat.viewSessions.orientation.sideBySide', "Display chat sessions side by side if space is sufficient, otherwise fallback to stacked above the chat input unless a chat session is visible.")
451
],
452
default: 'sideBySide',
453
description: nls.localize('chat.viewSessions.orientation', "Controls the orientation of the chat agent sessions view when it is shown alongside the chat."),
454
},
455
[ChatConfiguration.ChatViewProgressBadgeEnabled]: {
456
type: 'boolean',
457
default: false,
458
description: nls.localize('chat.viewProgressBadge.enabled', "Show a progress badge on the chat view when an agent session is in progress that is opened in that view."),
459
},
460
[ChatConfiguration.NotifyWindowOnResponseReceived]: {
461
type: 'boolean',
462
default: true,
463
description: nls.localize('chat.notifyWindowOnResponseReceived', "Controls whether a chat session should present the user with an OS notification when a response is received while the window is not in focus. This includes a window badge as well as notification toast."),
464
},
465
'chat.checkpoints.enabled': {
466
type: 'boolean',
467
default: true,
468
description: nls.localize('chat.checkpoints.enabled', "Enables checkpoints in chat. Checkpoints allow you to restore the chat to a previous state."),
469
},
470
'chat.checkpoints.showFileChanges': {
471
type: 'boolean',
472
description: nls.localize('chat.checkpoints.showFileChanges', "Controls whether to show chat checkpoint file changes."),
473
default: false
474
},
475
[mcpAccessConfig]: {
476
type: 'string',
477
description: nls.localize('chat.mcp.access', "Controls access to installed Model Context Protocol servers."),
478
enum: [
479
McpAccessValue.None,
480
McpAccessValue.Registry,
481
McpAccessValue.All
482
],
483
enumDescriptions: [
484
nls.localize('chat.mcp.access.none', "No access to MCP servers."),
485
nls.localize('chat.mcp.access.registry', "Allows access to MCP servers installed from the registry that VS Code is connected to."),
486
nls.localize('chat.mcp.access.any', "Allow access to any installed MCP server.")
487
],
488
default: McpAccessValue.All,
489
policy: {
490
name: 'ChatMCP',
491
category: PolicyCategory.InteractiveSession,
492
minimumVersion: '1.99',
493
value: (policyData) => {
494
if (policyData.mcp === false) {
495
return McpAccessValue.None;
496
}
497
if (policyData.mcpAccess === 'registry_only') {
498
return McpAccessValue.Registry;
499
}
500
return undefined;
501
},
502
localization: {
503
description: {
504
key: 'chat.mcp.access',
505
value: nls.localize('chat.mcp.access', "Controls access to installed Model Context Protocol servers.")
506
},
507
enumDescriptions: [
508
{
509
key: 'chat.mcp.access.none', value: nls.localize('chat.mcp.access.none', "No access to MCP servers."),
510
},
511
{
512
key: 'chat.mcp.access.registry', value: nls.localize('chat.mcp.access.registry', "Allows access to MCP servers installed from the registry that VS Code is connected to."),
513
},
514
{
515
key: 'chat.mcp.access.any', value: nls.localize('chat.mcp.access.any', "Allow access to any installed MCP server.")
516
}
517
]
518
},
519
}
520
},
521
[mcpAutoStartConfig]: {
522
type: 'string',
523
description: nls.localize('chat.mcp.autostart', "Controls whether MCP servers should be automatically started when the chat messages are submitted."),
524
default: McpAutoStartValue.NewAndOutdated,
525
enum: [
526
McpAutoStartValue.Never,
527
McpAutoStartValue.OnlyNew,
528
McpAutoStartValue.NewAndOutdated
529
],
530
enumDescriptions: [
531
nls.localize('chat.mcp.autostart.never', "Never automatically start MCP servers."),
532
nls.localize('chat.mcp.autostart.onlyNew', "Only automatically start new MCP servers that have never been run."),
533
nls.localize('chat.mcp.autostart.newAndOutdated', "Automatically start new and outdated MCP servers that are not yet running.")
534
],
535
tags: ['experimental'],
536
},
537
[mcpAppsEnabledConfig]: {
538
type: 'boolean',
539
description: nls.localize('chat.mcp.ui.enabled', "Controls whether MCP servers can provide custom UI for tool invocations."),
540
default: true,
541
tags: ['experimental'],
542
},
543
[mcpServerSamplingSection]: {
544
type: 'object',
545
description: nls.localize('chat.mcp.serverSampling', "Configures which models are exposed to MCP servers for sampling (making model requests in the background). This setting can be edited in a graphical way under the `{0}` command.", 'MCP: ' + nls.localize('mcp.list', 'List Servers')),
546
scope: ConfigurationScope.RESOURCE,
547
additionalProperties: {
548
type: 'object',
549
properties: {
550
allowedDuringChat: {
551
type: 'boolean',
552
description: nls.localize('chat.mcp.serverSampling.allowedDuringChat', "Whether this server is make sampling requests during its tool calls in a chat session."),
553
default: true,
554
},
555
allowedOutsideChat: {
556
type: 'boolean',
557
description: nls.localize('chat.mcp.serverSampling.allowedOutsideChat', "Whether this server is allowed to make sampling requests outside of a chat session."),
558
default: false,
559
},
560
allowedModels: {
561
type: 'array',
562
items: {
563
type: 'string',
564
description: nls.localize('chat.mcp.serverSampling.model', "A model the MCP server has access to."),
565
},
566
}
567
}
568
},
569
},
570
[AssistedTypes[AddConfigurationType.NuGetPackage].enabledConfigKey]: {
571
type: 'boolean',
572
description: nls.localize('chat.mcp.assisted.nuget.enabled.description', "Enables NuGet packages for AI-assisted MCP server installation. Used to install MCP servers by name from the central registry for .NET packages (NuGet.org)."),
573
default: false,
574
tags: ['experimental'],
575
experiment: {
576
mode: 'startup'
577
}
578
},
579
[ChatConfiguration.Edits2Enabled]: {
580
type: 'boolean',
581
description: nls.localize('chat.edits2Enabled', "Enable the new Edits mode that is based on tool-calling. When this is enabled, models that don't support tool-calling are unavailable for Edits mode."),
582
default: false,
583
},
584
[ChatConfiguration.ExtensionToolsEnabled]: {
585
type: 'boolean',
586
description: nls.localize('chat.extensionToolsEnabled', "Enable using tools contributed by third-party extensions."),
587
default: true,
588
policy: {
589
name: 'ChatAgentExtensionTools',
590
category: PolicyCategory.InteractiveSession,
591
minimumVersion: '1.99',
592
localization: {
593
description: {
594
key: 'chat.extensionToolsEnabled',
595
value: nls.localize('chat.extensionToolsEnabled', "Enable using tools contributed by third-party extensions.")
596
}
597
},
598
}
599
},
600
[ChatConfiguration.AgentEnabled]: {
601
type: 'boolean',
602
description: nls.localize('chat.agent.enabled.description', "When enabled, agent mode can be activated from chat and tools in agentic contexts with side effects can be used."),
603
default: true,
604
order: 1,
605
policy: {
606
name: 'ChatAgentMode',
607
category: PolicyCategory.InteractiveSession,
608
minimumVersion: '1.99',
609
value: (policyData) => policyData.chat_agent_enabled === false ? false : undefined,
610
localization: {
611
description: {
612
key: 'chat.agent.enabled.description',
613
value: nls.localize('chat.agent.enabled.description', "When enabled, agent mode can be activated from chat and tools in agentic contexts with side effects can be used."),
614
}
615
}
616
}
617
},
618
[ChatConfiguration.PlanAgentDefaultModel]: {
619
type: 'string',
620
description: nls.localize('chat.planAgent.defaultModel.description', "Select the default language model to use for the Plan agent from the available providers."),
621
default: '',
622
enum: PlanAgentDefaultModel.modelIds,
623
enumItemLabels: PlanAgentDefaultModel.modelLabels,
624
markdownEnumDescriptions: PlanAgentDefaultModel.modelDescriptions
625
},
626
[ChatConfiguration.RequestQueueingEnabled]: {
627
type: 'boolean',
628
description: nls.localize('chat.requestQueuing.enabled.description', "When enabled, allows queuing additional messages while a request is in progress and steering the current request with a new message."),
629
default: true,
630
tags: ['experimental'],
631
},
632
[ChatConfiguration.RequestQueueingDefaultAction]: {
633
type: 'string',
634
enum: ['queue', 'steer'],
635
enumDescriptions: [
636
nls.localize('chat.requestQueuing.defaultAction.queue', "Queue the message to send after the current request completes."),
637
nls.localize('chat.requestQueuing.defaultAction.steer', "Steer the current request by sending the message immediately, signaling the current request to yield."),
638
],
639
description: nls.localize('chat.requestQueuing.defaultAction.description', "Controls which action is the default for the queue button when a request is in progress."),
640
default: 'steer',
641
},
642
[ChatConfiguration.EditModeHidden]: {
643
type: 'boolean',
644
description: nls.localize('chat.editMode.hidden', "When enabled, hides the Edit mode from the chat mode picker."),
645
default: false,
646
tags: ['experimental'],
647
experiment: {
648
mode: 'auto'
649
}
650
},
651
[ChatConfiguration.AlternativeToolAction]: {
652
type: 'boolean',
653
description: nls.localize('chat.alternativeToolAction', "When enabled, shows the Configure Tools action in the mode picker dropdown on hover instead of in the chat input."),
654
default: false,
655
tags: ['experimental'],
656
experiment: {
657
mode: 'auto'
658
}
659
},
660
[ChatConfiguration.EnableMath]: {
661
type: 'boolean',
662
description: nls.localize('chat.mathEnabled.description', "Enable math rendering in chat responses using KaTeX."),
663
default: true,
664
},
665
[ChatConfiguration.ShowCodeBlockProgressAnimation]: {
666
type: 'boolean',
667
description: nls.localize('chat.codeBlock.showProgressAnimation.description', "When applying edits, show a progress animation in the code block pill. If disabled, shows the progress percentage instead."),
668
default: true,
669
tags: ['experimental'],
670
},
671
['chat.statusWidget.sku']: {
672
type: 'string',
673
enum: ['free', 'anonymous'],
674
enumDescriptions: [
675
nls.localize('chat.statusWidget.sku.free', "Show status widget for free tier users."),
676
nls.localize('chat.statusWidget.sku.anonymous', "Show status widget for anonymous users.")
677
],
678
description: nls.localize('chat.statusWidget.enabled.description', "Controls which user type should see the status widget in new chat sessions when quota is exceeded."),
679
default: undefined,
680
tags: ['experimental', 'advanced'],
681
experiment: {
682
mode: 'auto'
683
}
684
},
685
[mcpDiscoverySection]: {
686
type: 'object',
687
properties: Object.fromEntries(allDiscoverySources.map(k => [k, { type: 'boolean', description: discoverySourceSettingsLabel[k] }])),
688
additionalProperties: false,
689
default: Object.fromEntries(allDiscoverySources.map(k => [k, false])),
690
markdownDescription: nls.localize('mcp.discovery.enabled', "Configures discovery of Model Context Protocol servers from configuration from various other applications."),
691
},
692
[mcpGalleryServiceEnablementConfig]: {
693
type: 'boolean',
694
default: false,
695
tags: ['preview'],
696
description: nls.localize('chat.mcp.gallery.enabled', "Enables the default Marketplace for Model Context Protocol (MCP) servers."),
697
included: product.quality === 'stable'
698
},
699
[mcpGalleryServiceUrlConfig]: {
700
type: 'string',
701
description: nls.localize('mcp.gallery.serviceUrl', "Configure the MCP Gallery service URL to connect to"),
702
default: '',
703
scope: ConfigurationScope.APPLICATION,
704
tags: ['usesOnlineServices', 'advanced'],
705
included: false,
706
policy: {
707
name: 'McpGalleryServiceUrl',
708
category: PolicyCategory.InteractiveSession,
709
minimumVersion: '1.101',
710
value: (policyData) => policyData.mcpRegistryUrl,
711
localization: {
712
description: {
713
key: 'mcp.gallery.serviceUrl',
714
value: nls.localize('mcp.gallery.serviceUrl', "Configure the MCP Gallery service URL to connect to"),
715
}
716
}
717
},
718
},
719
[PromptsConfig.INSTRUCTIONS_LOCATION_KEY]: {
720
type: 'object',
721
title: nls.localize(
722
'chat.instructions.config.locations.title',
723
"Instructions File Locations",
724
),
725
markdownDescription: nls.localize(
726
'chat.instructions.config.locations.description',
727
"Specify location(s) of instructions files (`*{0}`) that can be attached in Chat sessions. [Learn More]({1}).\n\nRelative paths are resolved from the root folder(s) of your workspace.",
728
INSTRUCTION_FILE_EXTENSION,
729
INSTRUCTIONS_DOCUMENTATION_URL,
730
),
731
default: {
732
[INSTRUCTIONS_DEFAULT_SOURCE_FOLDER]: true,
733
[CLAUDE_RULES_SOURCE_FOLDER]: true,
734
},
735
additionalProperties: { type: 'boolean' },
736
propertyNames: {
737
pattern: VALID_PROMPT_FOLDER_PATTERN,
738
patternErrorMessage: nls.localize('chat.instructionsLocations.invalidPath', "Paths must be relative or start with '~/'. Absolute paths and '\\' separators are not supported. Glob patterns are deprecated and will be removed in future versions."),
739
},
740
restricted: true,
741
tags: ['prompts', 'reusable prompts', 'prompt snippets', 'instructions'],
742
examples: [
743
{
744
[INSTRUCTIONS_DEFAULT_SOURCE_FOLDER]: true,
745
[CLAUDE_RULES_SOURCE_FOLDER]: true,
746
},
747
{
748
[INSTRUCTIONS_DEFAULT_SOURCE_FOLDER]: true,
749
'/Users/vscode/repos/instructions': true,
750
},
751
],
752
},
753
[PromptsConfig.PROMPT_LOCATIONS_KEY]: {
754
type: 'object',
755
title: nls.localize(
756
'chat.reusablePrompts.config.locations.title',
757
"Prompt File Locations",
758
),
759
markdownDescription: nls.localize(
760
'chat.reusablePrompts.config.locations.description',
761
"Specify location(s) of reusable prompt files (`*{0}`) that can be run in Chat sessions. [Learn More]({1}).\n\nRelative paths are resolved from the root folder(s) of your workspace.",
762
PROMPT_FILE_EXTENSION,
763
PROMPT_DOCUMENTATION_URL,
764
),
765
default: {
766
[PROMPT_DEFAULT_SOURCE_FOLDER]: true,
767
},
768
additionalProperties: { type: 'boolean' },
769
unevaluatedProperties: { type: 'boolean' },
770
propertyNames: {
771
pattern: VALID_PROMPT_FOLDER_PATTERN,
772
patternErrorMessage: nls.localize('chat.promptFileLocations.invalidPath', "Paths must be relative or start with '~/'. Absolute paths and '\\' separators are not supported. Glob patterns are deprecated and will be removed in future versions."),
773
},
774
restricted: true,
775
tags: ['prompts', 'reusable prompts', 'prompt snippets', 'instructions'],
776
examples: [
777
{
778
[PROMPT_DEFAULT_SOURCE_FOLDER]: true,
779
},
780
{
781
[PROMPT_DEFAULT_SOURCE_FOLDER]: true,
782
'/Users/vscode/repos/prompts': true,
783
},
784
],
785
},
786
[PromptsConfig.MODE_LOCATION_KEY]: {
787
type: 'object',
788
title: nls.localize(
789
'chat.mode.config.locations.title',
790
"Mode File Locations",
791
),
792
markdownDescription: nls.localize(
793
'chat.mode.config.locations.description',
794
"Specify location(s) of custom chat mode files (`*{0}`). [Learn More]({1}).\n\nRelative paths are resolved from the root folder(s) of your workspace.",
795
LEGACY_MODE_FILE_EXTENSION,
796
AGENT_DOCUMENTATION_URL,
797
),
798
default: {
799
[LEGACY_MODE_DEFAULT_SOURCE_FOLDER]: true,
800
},
801
deprecationMessage: nls.localize('chat.mode.config.locations.deprecated', "This setting is deprecated and will be removed in future releases. Chat modes are now called custom agents and are located in `.github/agents`"),
802
additionalProperties: { type: 'boolean' },
803
unevaluatedProperties: { type: 'boolean' },
804
restricted: true,
805
tags: ['experimental', 'prompts', 'reusable prompts', 'prompt snippets', 'instructions'],
806
examples: [
807
{
808
[LEGACY_MODE_DEFAULT_SOURCE_FOLDER]: true,
809
},
810
{
811
[LEGACY_MODE_DEFAULT_SOURCE_FOLDER]: true,
812
'/Users/vscode/repos/chatmodes': true,
813
},
814
],
815
},
816
[PromptsConfig.AGENTS_LOCATION_KEY]: {
817
type: 'object',
818
title: nls.localize(
819
'chat.agents.config.locations.title',
820
"Agent File Locations",
821
),
822
markdownDescription: nls.localize(
823
'chat.agents.config.locations.description',
824
"Specify location(s) of custom agent files (`*{0}`). [Learn More]({1}).\n\nRelative paths are resolved from the root folder(s) of your workspace.",
825
AGENT_FILE_EXTENSION,
826
AGENT_DOCUMENTATION_URL,
827
),
828
default: {
829
[AGENTS_SOURCE_FOLDER]: true,
830
[CLAUDE_AGENTS_SOURCE_FOLDER]: true,
831
},
832
additionalProperties: { type: 'boolean' },
833
propertyNames: {
834
pattern: VALID_PROMPT_FOLDER_PATTERN,
835
patternErrorMessage: nls.localize('chat.agentLocations.invalidPath', "Paths must be relative or start with '~/'. Absolute paths and '\\' separators are not supported."),
836
},
837
restricted: true,
838
tags: ['prompts', 'reusable prompts', 'prompt snippets', 'instructions'],
839
examples: [
840
{
841
[AGENTS_SOURCE_FOLDER]: true,
842
},
843
{
844
[AGENTS_SOURCE_FOLDER]: true,
845
'my-agents': true,
846
'../shared-agents': true,
847
'~/.copilot/agents': true,
848
},
849
],
850
},
851
[PromptsConfig.USE_AGENT_MD]: {
852
type: 'boolean',
853
title: nls.localize('chat.useAgentMd.title', "Use AGENTS.md file",),
854
markdownDescription: nls.localize('chat.useAgentMd.description', "Controls whether instructions from `AGENTS.md` file found in a workspace roots are attached to all chat requests.",),
855
default: true,
856
restricted: true,
857
disallowConfigurationDefault: true,
858
tags: ['prompts', 'reusable prompts', 'prompt snippets', 'instructions']
859
},
860
[PromptsConfig.USE_NESTED_AGENT_MD]: {
861
type: 'boolean',
862
title: nls.localize('chat.useNestedAgentMd.title', "Use nested AGENTS.md files",),
863
markdownDescription: nls.localize('chat.useNestedAgentMd.description', "Controls whether instructions from nested `AGENTS.md` files found in the workspace are listed in all chat requests. The language model can load these skills on-demand if the `read` tool is available.",),
864
default: false,
865
restricted: true,
866
disallowConfigurationDefault: true,
867
tags: ['experimental', 'prompts', 'reusable prompts', 'prompt snippets', 'instructions']
868
},
869
[PromptsConfig.USE_CLAUDE_MD]: {
870
type: 'boolean',
871
title: nls.localize('chat.useClaudeMd.title', "Use CLAUDE.md file",),
872
markdownDescription: nls.localize('chat.useClaudeMd.description', "Controls whether instructions from `CLAUDE.md` file found in workspace roots, .claude and ~/.claude folder are attached to all chat requests.",),
873
default: true,
874
restricted: true,
875
disallowConfigurationDefault: true,
876
tags: ['prompts', 'reusable prompts', 'prompt snippets', 'instructions']
877
},
878
[PromptsConfig.USE_AGENT_SKILLS]: {
879
type: 'boolean',
880
title: nls.localize('chat.useAgentSkills.title', "Use Agent skills",),
881
markdownDescription: nls.localize('chat.useAgentSkills.description', "Controls whether skills are provided as specialized capabilities to the chat requests. Skills are loaded from the folders configured in `#chat.agentSkillsLocations#`. The language model can load these skills on-demand if the `read` tool is available. Learn more about [Agent Skills](https://aka.ms/vscode-agent-skills).",),
882
default: true,
883
restricted: true,
884
disallowConfigurationDefault: true,
885
tags: ['prompts', 'reusable prompts', 'prompt snippets', 'instructions']
886
},
887
[PromptsConfig.USE_SKILL_ADHERENCE_PROMPT]: {
888
type: 'boolean',
889
title: nls.localize('chat.useSkillAdherencePrompt.title', "Use Skill Adherence Prompt",),
890
markdownDescription: nls.localize('chat.useSkillAdherencePrompt.description', "Controls whether a stronger skill adherence prompt is used that encourages the model to immediately invoke skills when relevant rather than just announcing them."),
891
default: false,
892
restricted: true,
893
disallowConfigurationDefault: true,
894
tags: ['experimental', 'prompts', 'reusable prompts', 'prompt snippets', 'instructions'],
895
experiment: {
896
mode: 'auto'
897
}
898
},
899
[PromptsConfig.INCLUDE_APPLYING_INSTRUCTIONS]: {
900
type: 'boolean',
901
title: nls.localize('chat.includeApplyingInstructions.title', "Include Applying Instructions",),
902
markdownDescription: nls.localize('chat.includeApplyingInstructions.description', "Controls whether instructions with a matching 'applyTo' attribute are automatically included in chat requests.",),
903
default: true,
904
restricted: true,
905
disallowConfigurationDefault: true,
906
tags: ['prompts', 'reusable prompts', 'prompt snippets', 'instructions']
907
},
908
[PromptsConfig.INCLUDE_REFERENCED_INSTRUCTIONS]: {
909
type: 'boolean',
910
title: nls.localize('chat.includeReferencedInstructions.title', "Include Referenced Instructions",),
911
markdownDescription: nls.localize('chat.includeReferencedInstructions.description', "Controls whether referenced instructions are automatically included in chat requests.",),
912
default: false,
913
restricted: true,
914
disallowConfigurationDefault: true,
915
tags: ['prompts', 'reusable prompts', 'prompt snippets', 'instructions']
916
},
917
[PromptsConfig.SKILLS_LOCATION_KEY]: {
918
type: 'object',
919
title: nls.localize('chat.agentSkillsLocations.title', "Agent Skills Locations",),
920
markdownDescription: nls.localize(
921
'chat.agentSkillsLocations.description',
922
"Specify location(s) of agent skills (`{0}`) that can be used in Chat Sessions. [Learn More]({1}).\n\nEach path should contain skill subfolders with SKILL.md files (e.g., add `my-skills` if you have `my-skills/skillA/SKILL.md`). Relative paths are resolved from the root folder(s) of your workspace.",
923
SKILL_FILENAME,
924
SKILL_DOCUMENTATION_URL,
925
),
926
default: {
927
...DEFAULT_SKILL_SOURCE_FOLDERS.map((folder) => ({ [folder.path]: true })).reduce((acc, curr) => ({ ...acc, ...curr }), {}),
928
},
929
additionalProperties: { type: 'boolean' },
930
propertyNames: {
931
pattern: VALID_PROMPT_FOLDER_PATTERN,
932
patternErrorMessage: nls.localize('chat.agentSkillsLocations.invalidPath', "Paths must be relative or start with '~/'. Absolute paths and '\\' separators are not supported."),
933
},
934
restricted: true,
935
tags: ['prompts', 'reusable prompts', 'prompt snippets', 'instructions'],
936
examples: [
937
{
938
[DEFAULT_SKILL_SOURCE_FOLDERS[0].path]: true,
939
},
940
{
941
[DEFAULT_SKILL_SOURCE_FOLDERS[0].path]: true,
942
'my-skills': true,
943
'../shared-skills': true,
944
'~/.custom/skills': true,
945
},
946
],
947
},
948
[PromptsConfig.HOOKS_LOCATION_KEY]: {
949
type: 'object',
950
title: nls.localize('chat.hookFilesLocations.title', "Hook File Locations",),
951
markdownDescription: nls.localize(
952
'chat.hookFilesLocations.description',
953
"Specify paths to hook configuration files that define custom shell commands to execute at strategic points in an agent's workflow. [Learn More]({0}).\n\nRelative paths are resolved from the root folder(s) of your workspace. Supports Copilot hooks (`*.json`) and Claude Code hooks (`settings.json`, `settings.local.json`).",
954
HOOK_DOCUMENTATION_URL,
955
),
956
default: {
957
...DEFAULT_HOOK_FILE_PATHS.map((f) => ({ [f.path]: true })).reduce((acc, curr) => ({ ...acc, ...curr }), {}),
958
},
959
additionalProperties: { type: 'boolean' },
960
propertyNames: {
961
pattern: VALID_PROMPT_FOLDER_PATTERN,
962
patternErrorMessage: nls.localize('chat.hookFilesLocations.invalidPath', "Paths must be relative or start with '~/'. Absolute paths and '\\' separators are not supported."),
963
},
964
restricted: true,
965
tags: ['prompts', 'hooks', 'agent'],
966
examples: [
967
{
968
[DEFAULT_HOOK_FILE_PATHS[0].path]: true,
969
},
970
{
971
[DEFAULT_HOOK_FILE_PATHS[0].path]: true,
972
'custom-hooks/hooks.json': true,
973
},
974
],
975
},
976
[PromptsConfig.USE_CHAT_HOOKS]: {
977
type: 'boolean',
978
title: nls.localize('chat.useChatHooks.title', "Use Chat Hooks",),
979
markdownDescription: nls.localize('chat.useChatHooks.description', "Controls whether chat hooks are executed at strategic points during an agent's workflow. Hooks are loaded from the files configured in `#chat.hookFilesLocations#`.",),
980
default: true,
981
restricted: true,
982
disallowConfigurationDefault: true,
983
tags: ['prompts', 'hooks', 'agent']
984
},
985
[PromptsConfig.PROMPT_FILES_SUGGEST_KEY]: {
986
type: 'object',
987
scope: ConfigurationScope.RESOURCE,
988
title: nls.localize(
989
'chat.promptFilesRecommendations.title',
990
"Prompt File Recommendations",
991
),
992
markdownDescription: nls.localize(
993
'chat.promptFilesRecommendations.description',
994
"Configure which prompt files to recommend in the chat welcome view. Each key is a prompt file name, and the value can be `true` to always recommend, `false` to never recommend, or a [when clause](https://aka.ms/vscode-when-clause) expression like `resourceExtname == .js` or `resourceLangId == markdown`.",
995
),
996
default: {},
997
additionalProperties: {
998
oneOf: [
999
{ type: 'boolean' },
1000
{ type: 'string' }
1001
]
1002
},
1003
tags: ['prompts', 'reusable prompts', 'prompt snippets', 'instructions'],
1004
examples: [
1005
{
1006
'plan': true,
1007
'a11y-audit': 'resourceExtname == .html',
1008
'document': 'resourceLangId == markdown'
1009
}
1010
],
1011
},
1012
[ChatConfiguration.TodosShowWidget]: {
1013
type: 'boolean',
1014
default: true,
1015
description: nls.localize('chat.tools.todos.showWidget', "Controls whether to show the todo list widget above the chat input. When enabled, the widget displays todo items created by the agent and updates as progress is made."),
1016
},
1017
[ChatConfiguration.ThinkingStyle]: {
1018
type: 'string',
1019
default: 'fixedScrolling',
1020
enum: ['collapsed', 'collapsedPreview', 'fixedScrolling'],
1021
enumDescriptions: [
1022
nls.localize('chat.agent.thinkingMode.collapsed', "Thinking parts will be collapsed by default."),
1023
nls.localize('chat.agent.thinkingMode.collapsedPreview', "Thinking parts will be expanded first, then collapse once we reach a part that is not thinking."),
1024
nls.localize('chat.agent.thinkingMode.fixedScrolling', "Show thinking in a fixed-height streaming panel that auto-scrolls; click header to expand to full height."),
1025
],
1026
description: nls.localize('chat.agent.thinkingStyle', "Controls how thinking is rendered."),
1027
tags: ['experimental'],
1028
},
1029
[ChatConfiguration.ThinkingGenerateTitles]: {
1030
type: 'boolean',
1031
default: true,
1032
description: nls.localize('chat.agent.thinking.generateTitles', "Controls whether to use an LLM to generate summary titles for thinking sections."),
1033
tags: ['experimental'],
1034
},
1035
'chat.agent.thinking.collapsedTools': {
1036
type: 'string',
1037
default: 'always',
1038
enum: ['off', 'withThinking', 'always'],
1039
enumDescriptions: [
1040
nls.localize('chat.agent.thinking.collapsedTools.off', "Tool calls are shown separately, not collapsed into thinking."),
1041
nls.localize('chat.agent.thinking.collapsedTools.withThinking', "Tool calls are collapsed into thinking sections when thinking is present."),
1042
nls.localize('chat.agent.thinking.collapsedTools.always', "Tool calls are always collapsed, even without thinking."),
1043
],
1044
markdownDescription: nls.localize('chat.agent.thinking.collapsedTools', "Controls how tool calls are displayed in relation to thinking sections."),
1045
tags: ['experimental'],
1046
},
1047
[ChatConfiguration.TerminalToolsInThinking]: {
1048
type: 'boolean',
1049
default: true,
1050
markdownDescription: nls.localize('chat.agent.thinking.terminalTools', "When enabled, terminal tool calls are displayed inside the thinking dropdown with a simplified view."),
1051
tags: ['experimental'],
1052
},
1053
[ChatConfiguration.AutoExpandToolFailures]: {
1054
type: 'boolean',
1055
default: true,
1056
markdownDescription: nls.localize('chat.tools.autoExpandFailures', "When enabled, tool failures are automatically expanded in the chat UI to show error details."),
1057
},
1058
[ChatConfiguration.AIDisabled]: {
1059
type: 'boolean',
1060
description: nls.localize('chat.disableAIFeatures', "Disable and hide built-in AI features provided by GitHub Copilot, including chat and inline suggestions."),
1061
default: false,
1062
scope: ConfigurationScope.WINDOW
1063
},
1064
'chat.allowAnonymousAccess': { // TODO@bpasero remove me eventually
1065
type: 'boolean',
1066
description: nls.localize('chat.allowAnonymousAccess', "Controls whether anonymous access is allowed in chat."),
1067
default: false,
1068
tags: ['experimental'],
1069
experiment: {
1070
mode: 'auto'
1071
}
1072
},
1073
[ChatConfiguration.RestoreLastPanelSession]: {
1074
type: 'boolean',
1075
description: nls.localize('chat.restoreLastPanelSession', "Controls whether the last session is restored in panel after restart."),
1076
default: false
1077
},
1078
[ChatConfiguration.ExitAfterDelegation]: {
1079
type: 'boolean',
1080
description: nls.localize('chat.exitAfterDelegation', "Controls whether the chat panel automatically exits after delegating a request to another session."),
1081
default: true,
1082
tags: ['preview'],
1083
},
1084
'chat.extensionUnification.enabled': {
1085
type: 'boolean',
1086
description: nls.localize('chat.extensionUnification.enabled', "Enables the unification of GitHub Copilot extensions. When enabled, all GitHub Copilot functionality is served from the GitHub Copilot Chat extension. When disabled, the GitHub Copilot and GitHub Copilot Chat extensions operate independently."),
1087
default: true,
1088
tags: ['experimental'],
1089
experiment: {
1090
mode: 'auto'
1091
}
1092
},
1093
[ChatConfiguration.SubagentToolCustomAgents]: {
1094
type: 'boolean',
1095
description: nls.localize('chat.subagentTool.customAgents', "Whether the runSubagent tool is able to use custom agents. When enabled, the tool can take the name of a custom agent, but it must be given the exact name of the agent."),
1096
default: false,
1097
tags: ['experimental'],
1098
experiment: {
1099
mode: 'auto'
1100
}
1101
}
1102
}
1103
});
1104
Registry.as<IEditorPaneRegistry>(EditorExtensions.EditorPane).registerEditorPane(
1105
EditorPaneDescriptor.create(
1106
ChatEditor,
1107
ChatEditorInput.EditorID,
1108
nls.localize('chat', "Chat")
1109
),
1110
[
1111
new SyncDescriptor(ChatEditorInput)
1112
]
1113
);
1114
Registry.as<IConfigurationMigrationRegistry>(Extensions.ConfigurationMigration).registerConfigurationMigrations([
1115
{
1116
key: 'chat.experimental.detectParticipant.enabled',
1117
migrateFn: (value, _accessor) => ([
1118
['chat.experimental.detectParticipant.enabled', { value: undefined }],
1119
['chat.detectParticipant.enabled', { value: value !== false }]
1120
])
1121
},
1122
{
1123
key: 'chat.useClaudeSkills',
1124
migrateFn: (value, _accessor) => ([
1125
['chat.useClaudeSkills', { value: undefined }],
1126
['chat.useAgentSkills', { value }]
1127
])
1128
},
1129
{
1130
key: mcpDiscoverySection,
1131
migrateFn: (value: unknown) => {
1132
if (typeof value === 'boolean') {
1133
return { value: Object.fromEntries(allDiscoverySources.map(k => [k, value])) };
1134
}
1135
1136
return { value };
1137
}
1138
},
1139
]);
1140
1141
class ChatResolverContribution extends Disposable {
1142
1143
static readonly ID = 'workbench.contrib.chatResolver';
1144
1145
private readonly _editorRegistrations = this._register(new DisposableMap<string>());
1146
1147
constructor(
1148
@IChatSessionsService chatSessionsService: IChatSessionsService,
1149
@IEditorResolverService private readonly editorResolverService: IEditorResolverService,
1150
@IInstantiationService private readonly instantiationService: IInstantiationService,
1151
) {
1152
super();
1153
1154
this._registerEditor(Schemas.vscodeChatEditor);
1155
this._registerEditor(Schemas.vscodeLocalChatSession);
1156
1157
this._register(chatSessionsService.onDidChangeContentProviderSchemes((e) => {
1158
for (const scheme of e.added) {
1159
this._registerEditor(scheme);
1160
}
1161
for (const scheme of e.removed) {
1162
this._editorRegistrations.deleteAndDispose(scheme);
1163
}
1164
}));
1165
1166
for (const scheme of chatSessionsService.getContentProviderSchemes()) {
1167
this._registerEditor(scheme);
1168
}
1169
}
1170
1171
private _registerEditor(scheme: string): void {
1172
this._editorRegistrations.set(scheme, this.editorResolverService.registerEditor(`${scheme}:**/**`,
1173
{
1174
id: ChatEditorInput.EditorID,
1175
label: nls.localize('chat', "Chat"),
1176
priority: RegisteredEditorPriority.builtin
1177
},
1178
{
1179
singlePerResource: true,
1180
canSupportResource: resource => resource.scheme === scheme,
1181
},
1182
{
1183
createEditorInput: ({ resource, options }) => {
1184
return {
1185
editor: this.instantiationService.createInstance(ChatEditorInput, resource, options as IChatEditorOptions),
1186
options
1187
};
1188
}
1189
}
1190
));
1191
}
1192
}
1193
1194
class ChatAgentSettingContribution extends Disposable implements IWorkbenchContribution {
1195
1196
static readonly ID = 'workbench.contrib.chatAgentSetting';
1197
1198
constructor(
1199
@IWorkbenchAssignmentService private readonly experimentService: IWorkbenchAssignmentService,
1200
@IChatEntitlementService private readonly entitlementService: IChatEntitlementService,
1201
) {
1202
super();
1203
this.registerMaxRequestsSetting();
1204
this.registerBackgroundAgentDisplayName();
1205
}
1206
1207
1208
private registerMaxRequestsSetting(): void {
1209
let lastNode: IConfigurationNode | undefined;
1210
const registerMaxRequestsSetting = () => {
1211
const treatmentId = this.entitlementService.entitlement === ChatEntitlement.Free ?
1212
'chatAgentMaxRequestsFree' :
1213
'chatAgentMaxRequestsPro';
1214
this.experimentService.getTreatment<number>(treatmentId).then((value) => {
1215
const defaultValue = value ?? (this.entitlementService.entitlement === ChatEntitlement.Free ? 25 : 25);
1216
const node: IConfigurationNode = {
1217
id: 'chatSidebar',
1218
title: nls.localize('interactiveSessionConfigurationTitle', "Chat"),
1219
type: 'object',
1220
properties: {
1221
'chat.agent.maxRequests': {
1222
type: 'number',
1223
markdownDescription: nls.localize('chat.agent.maxRequests', "The maximum number of requests to allow per-turn when using an agent. When the limit is reached, will ask to confirm to continue."),
1224
default: defaultValue,
1225
order: 2,
1226
},
1227
}
1228
};
1229
configurationRegistry.updateConfigurations({ remove: lastNode ? [lastNode] : [], add: [node] });
1230
lastNode = node;
1231
});
1232
};
1233
this._register(Event.runAndSubscribe(Event.debounce(this.entitlementService.onDidChangeEntitlement, () => { }, 1000), () => registerMaxRequestsSetting()));
1234
}
1235
1236
private registerBackgroundAgentDisplayName(): void {
1237
this.experimentService.getTreatment<string>('backgroundAgentDisplayName').then((value) => {
1238
if (value) {
1239
backgroundAgentDisplayName.set(value, undefined);
1240
}
1241
});
1242
}
1243
}
1244
1245
1246
/**
1247
* Given builtin and custom modes, returns only the custom mode IDs that should have actions registered.
1248
* Custom modes whose names conflict with builtin modes are excluded.
1249
* If there are name collisions among custom modes, the later mode in the list wins.
1250
*/
1251
function getCustomModesWithUniqueNames(builtinModes: readonly IChatMode[], customModes: readonly IChatMode[]): Set<string> {
1252
const customModeIds = new Set<string>();
1253
const builtinNames = new Set(builtinModes.map(mode => mode.name.get()));
1254
const customNameToId = new Map<string, string>();
1255
1256
for (const mode of customModes) {
1257
const modeName = mode.name.get();
1258
1259
// Skip custom modes that conflict with builtin mode names
1260
if (builtinNames.has(modeName)) {
1261
continue;
1262
}
1263
1264
// If there is a name collision among custom modes, the later one in the list wins
1265
const existingId = customNameToId.get(modeName);
1266
if (existingId) {
1267
customModeIds.delete(existingId);
1268
}
1269
1270
customNameToId.set(modeName, mode.id);
1271
customModeIds.add(mode.id);
1272
}
1273
1274
return customModeIds;
1275
}
1276
1277
/**
1278
* Workbench contribution to register actions for custom chat modes via events
1279
*/
1280
class ChatAgentActionsContribution extends Disposable implements IWorkbenchContribution {
1281
1282
static readonly ID = 'workbench.contrib.chatAgentActions';
1283
1284
private readonly _modeActionDisposables = new DisposableMap<string>();
1285
1286
constructor(
1287
@IChatModeService private readonly chatModeService: IChatModeService,
1288
) {
1289
super();
1290
this._store.add(this._modeActionDisposables);
1291
1292
// Register actions for existing custom modes (avoiding name collisions)
1293
const { builtin, custom } = this.chatModeService.getModes();
1294
const currentModeIds = getCustomModesWithUniqueNames(builtin, custom);
1295
for (const mode of custom) {
1296
if (currentModeIds.has(mode.id)) {
1297
this._registerModeAction(mode);
1298
}
1299
}
1300
1301
// Listen for custom mode changes by tracking snapshots
1302
this._register(this.chatModeService.onDidChangeChatModes(() => {
1303
const { builtin, custom } = this.chatModeService.getModes();
1304
const currentModeIds = getCustomModesWithUniqueNames(builtin, custom);
1305
1306
// Remove modes that no longer exist and those replaced by modes later in the list with same name
1307
for (const modeId of this._modeActionDisposables.keys()) {
1308
if (!currentModeIds.has(modeId)) {
1309
this._modeActionDisposables.deleteAndDispose(modeId);
1310
}
1311
}
1312
1313
// Register new modes
1314
for (const mode of custom) {
1315
if (currentModeIds.has(mode.id) && !this._modeActionDisposables.has(mode.id)) {
1316
this._registerModeAction(mode);
1317
}
1318
}
1319
}));
1320
}
1321
1322
private _registerModeAction(mode: IChatMode): void {
1323
const actionClass = class extends ModeOpenChatGlobalAction {
1324
constructor() {
1325
super(mode);
1326
}
1327
};
1328
this._modeActionDisposables.set(mode.id, registerAction2(actionClass));
1329
}
1330
}
1331
1332
class ToolReferenceNamesContribution extends Disposable implements IWorkbenchContribution {
1333
1334
static readonly ID = 'workbench.contrib.toolReferenceNames';
1335
1336
constructor(
1337
@ILanguageModelToolsService private readonly _languageModelToolsService: ILanguageModelToolsService,
1338
) {
1339
super();
1340
this._updateToolReferenceNames();
1341
this._register(this._languageModelToolsService.onDidChangeTools(() => this._updateToolReferenceNames()));
1342
}
1343
1344
private _updateToolReferenceNames(): void {
1345
const tools =
1346
Array.from(this._languageModelToolsService.getAllToolsIncludingDisabled())
1347
.filter((tool): tool is typeof tool & { toolReferenceName: string } => typeof tool.toolReferenceName === 'string')
1348
.sort((a, b) => a.toolReferenceName.localeCompare(b.toolReferenceName));
1349
toolReferenceNameEnumValues.length = 0;
1350
toolReferenceNameEnumDescriptions.length = 0;
1351
for (const tool of tools) {
1352
toolReferenceNameEnumValues.push(tool.toolReferenceName);
1353
toolReferenceNameEnumDescriptions.push(nls.localize(
1354
'chat.toolReferenceName.description',
1355
"{0} - {1}",
1356
tool.toolReferenceName,
1357
tool.userDescription || tool.displayName
1358
));
1359
}
1360
configurationRegistry.notifyConfigurationSchemaUpdated({
1361
id: 'chatSidebar',
1362
properties: {
1363
[ChatConfiguration.EligibleForAutoApproval]: {}
1364
}
1365
});
1366
}
1367
}
1368
1369
AccessibleViewRegistry.register(new ChatTerminalOutputAccessibleView());
1370
AccessibleViewRegistry.register(new ChatResponseAccessibleView());
1371
AccessibleViewRegistry.register(new PanelChatAccessibilityHelp());
1372
AccessibleViewRegistry.register(new QuickChatAccessibilityHelp());
1373
AccessibleViewRegistry.register(new EditsChatAccessibilityHelp());
1374
AccessibleViewRegistry.register(new AgentChatAccessibilityHelp());
1375
1376
registerEditorFeature(ChatInputBoxContentProvider);
1377
1378
class ChatSlashStaticSlashCommandsContribution extends Disposable {
1379
1380
static readonly ID = 'workbench.contrib.chatSlashStaticSlashCommands';
1381
1382
constructor(
1383
@IChatSlashCommandService slashCommandService: IChatSlashCommandService,
1384
@ICommandService commandService: ICommandService,
1385
@IChatAgentService chatAgentService: IChatAgentService,
1386
@IChatWidgetService chatWidgetService: IChatWidgetService,
1387
@IInstantiationService instantiationService: IInstantiationService,
1388
@IAgentSessionsService agentSessionsService: IAgentSessionsService,
1389
) {
1390
super();
1391
this._store.add(slashCommandService.registerSlashCommand({
1392
command: 'clear',
1393
detail: nls.localize('clear', "Start a new chat and archive the current one"),
1394
sortText: 'z2_clear',
1395
executeImmediately: true,
1396
locations: [ChatAgentLocation.Chat]
1397
}, async (_prompt, _progress, _history, _location, sessionResource) => {
1398
agentSessionsService.getSession(sessionResource)?.setArchived(true);
1399
commandService.executeCommand(ACTION_ID_NEW_CHAT);
1400
}));
1401
this._store.add(slashCommandService.registerSlashCommand({
1402
command: 'hooks',
1403
detail: nls.localize('hooks', "Configure hooks"),
1404
sortText: 'z3_hooks',
1405
executeImmediately: true,
1406
silent: true,
1407
locations: [ChatAgentLocation.Chat]
1408
}, async () => {
1409
await instantiationService.invokeFunction(showConfigureHooksQuickPick);
1410
}));
1411
this._store.add(slashCommandService.registerSlashCommand({
1412
command: 'agents',
1413
detail: nls.localize('agents', "Configure custom agents"),
1414
sortText: 'z3_agents',
1415
executeImmediately: true,
1416
silent: true,
1417
locations: [ChatAgentLocation.Chat]
1418
}, async () => {
1419
await commandService.executeCommand('workbench.action.chat.configure.customagents');
1420
}));
1421
this._store.add(slashCommandService.registerSlashCommand({
1422
command: 'skills',
1423
detail: nls.localize('skills', "Configure skills"),
1424
sortText: 'z3_skills',
1425
executeImmediately: true,
1426
silent: true,
1427
locations: [ChatAgentLocation.Chat]
1428
}, async () => {
1429
await commandService.executeCommand('workbench.action.chat.configure.skills');
1430
}));
1431
this._store.add(slashCommandService.registerSlashCommand({
1432
command: 'instructions',
1433
detail: nls.localize('instructions', "Configure instructions"),
1434
sortText: 'z3_instructions',
1435
executeImmediately: true,
1436
silent: true,
1437
locations: [ChatAgentLocation.Chat]
1438
}, async () => {
1439
await commandService.executeCommand('workbench.action.chat.configure.instructions');
1440
}));
1441
this._store.add(slashCommandService.registerSlashCommand({
1442
command: 'prompts',
1443
detail: nls.localize('prompts', "Configure prompt files"),
1444
sortText: 'z3_prompts',
1445
executeImmediately: true,
1446
silent: true,
1447
locations: [ChatAgentLocation.Chat]
1448
}, async () => {
1449
await commandService.executeCommand('workbench.action.chat.configure.prompts');
1450
}));
1451
this._store.add(slashCommandService.registerSlashCommand({
1452
command: 'help',
1453
detail: '',
1454
sortText: 'z1_help',
1455
executeImmediately: true,
1456
locations: [ChatAgentLocation.Chat],
1457
modes: [ChatModeKind.Ask]
1458
}, async (prompt, progress, _history, _location, sessionResource) => {
1459
const defaultAgent = chatAgentService.getDefaultAgent(ChatAgentLocation.Chat);
1460
const agents = chatAgentService.getAgents();
1461
1462
// Report prefix
1463
if (defaultAgent?.metadata.helpTextPrefix) {
1464
if (isMarkdownString(defaultAgent.metadata.helpTextPrefix)) {
1465
progress.report({ content: defaultAgent.metadata.helpTextPrefix, kind: 'markdownContent' });
1466
} else {
1467
progress.report({ content: new MarkdownString(defaultAgent.metadata.helpTextPrefix), kind: 'markdownContent' });
1468
}
1469
progress.report({ content: new MarkdownString('\n\n'), kind: 'markdownContent' });
1470
}
1471
1472
// Report agent list
1473
const agentText = (await Promise.all(agents
1474
.filter(a => !a.isDefault && !a.isCore)
1475
.filter(a => a.locations.includes(ChatAgentLocation.Chat))
1476
.map(async a => {
1477
const description = a.description ? `- ${a.description}` : '';
1478
const agentMarkdown = instantiationService.invokeFunction(accessor => agentToMarkdown(a, sessionResource, true, accessor));
1479
const agentLine = `- ${agentMarkdown} ${description}`;
1480
const commandText = a.slashCommands.map(c => {
1481
const description = c.description ? `- ${c.description}` : '';
1482
return `\t* ${agentSlashCommandToMarkdown(a, c, sessionResource)} ${description}`;
1483
}).join('\n');
1484
1485
return (agentLine + '\n' + commandText).trim();
1486
}))).join('\n');
1487
progress.report({ content: new MarkdownString(agentText, { isTrusted: { enabledCommands: [ChatSubmitAction.ID] } }), kind: 'markdownContent' });
1488
1489
// Report help text ending
1490
if (defaultAgent?.metadata.helpTextPostfix) {
1491
progress.report({ content: new MarkdownString('\n\n'), kind: 'markdownContent' });
1492
if (isMarkdownString(defaultAgent.metadata.helpTextPostfix)) {
1493
progress.report({ content: defaultAgent.metadata.helpTextPostfix, kind: 'markdownContent' });
1494
} else {
1495
progress.report({ content: new MarkdownString(defaultAgent.metadata.helpTextPostfix), kind: 'markdownContent' });
1496
}
1497
}
1498
1499
// Without this, the response will be done before it renders and so it will not stream. This ensures that if the response starts
1500
// rendering during the next 200ms, then it will be streamed. Once it starts streaming, the whole response streams even after
1501
// it has received all response data has been received.
1502
await timeout(200);
1503
}));
1504
}
1505
}
1506
Registry.as<IEditorFactoryRegistry>(EditorExtensions.EditorFactory).registerEditorSerializer(ChatEditorInput.TypeID, ChatEditorInputSerializer);
1507
1508
registerWorkbenchContribution2(ChatResolverContribution.ID, ChatResolverContribution, WorkbenchPhase.BlockStartup);
1509
registerWorkbenchContribution2(ChatLanguageModelsDataContribution.ID, ChatLanguageModelsDataContribution, WorkbenchPhase.BlockRestore);
1510
registerWorkbenchContribution2(ChatSlashStaticSlashCommandsContribution.ID, ChatSlashStaticSlashCommandsContribution, WorkbenchPhase.Eventually);
1511
1512
registerWorkbenchContribution2(ChatExtensionPointHandler.ID, ChatExtensionPointHandler, WorkbenchPhase.BlockStartup);
1513
registerWorkbenchContribution2(LanguageModelToolsExtensionPointHandler.ID, LanguageModelToolsExtensionPointHandler, WorkbenchPhase.BlockRestore);
1514
registerWorkbenchContribution2(ChatPromptFilesExtensionPointHandler.ID, ChatPromptFilesExtensionPointHandler, WorkbenchPhase.BlockRestore);
1515
registerWorkbenchContribution2(ChatCompatibilityNotifier.ID, ChatCompatibilityNotifier, WorkbenchPhase.Eventually);
1516
registerWorkbenchContribution2(CodeBlockActionRendering.ID, CodeBlockActionRendering, WorkbenchPhase.BlockRestore);
1517
registerWorkbenchContribution2(ChatImplicitContextContribution.ID, ChatImplicitContextContribution, WorkbenchPhase.Eventually);
1518
registerWorkbenchContribution2(ChatViewsWelcomeHandler.ID, ChatViewsWelcomeHandler, WorkbenchPhase.BlockStartup);
1519
registerWorkbenchContribution2(ChatGettingStartedContribution.ID, ChatGettingStartedContribution, WorkbenchPhase.Eventually);
1520
registerWorkbenchContribution2(ChatSetupContribution.ID, ChatSetupContribution, WorkbenchPhase.BlockRestore);
1521
registerWorkbenchContribution2(ChatTeardownContribution.ID, ChatTeardownContribution, WorkbenchPhase.AfterRestored);
1522
registerWorkbenchContribution2(ChatStatusBarEntry.ID, ChatStatusBarEntry, WorkbenchPhase.BlockRestore);
1523
registerWorkbenchContribution2(BuiltinToolsContribution.ID, BuiltinToolsContribution, WorkbenchPhase.Eventually);
1524
registerWorkbenchContribution2(ChatAgentSettingContribution.ID, ChatAgentSettingContribution, WorkbenchPhase.AfterRestored);
1525
registerWorkbenchContribution2(ChatAgentActionsContribution.ID, ChatAgentActionsContribution, WorkbenchPhase.Eventually);
1526
registerWorkbenchContribution2(ToolReferenceNamesContribution.ID, ToolReferenceNamesContribution, WorkbenchPhase.AfterRestored);
1527
registerWorkbenchContribution2(ChatAgentRecommendation.ID, ChatAgentRecommendation, WorkbenchPhase.Eventually);
1528
registerWorkbenchContribution2(ChatEditingEditorAccessibility.ID, ChatEditingEditorAccessibility, WorkbenchPhase.AfterRestored);
1529
registerWorkbenchContribution2(ChatQueuePickerRendering.ID, ChatQueuePickerRendering, WorkbenchPhase.BlockRestore);
1530
registerWorkbenchContribution2(ChatEditingEditorOverlay.ID, ChatEditingEditorOverlay, WorkbenchPhase.AfterRestored);
1531
registerWorkbenchContribution2(SimpleBrowserOverlay.ID, SimpleBrowserOverlay, WorkbenchPhase.AfterRestored);
1532
registerWorkbenchContribution2(ChatEditingEditorContextKeys.ID, ChatEditingEditorContextKeys, WorkbenchPhase.AfterRestored);
1533
registerWorkbenchContribution2(ChatTransferContribution.ID, ChatTransferContribution, WorkbenchPhase.BlockRestore);
1534
registerWorkbenchContribution2(ChatContextContributions.ID, ChatContextContributions, WorkbenchPhase.AfterRestored);
1535
registerWorkbenchContribution2(ChatResponseResourceFileSystemProvider.ID, ChatResponseResourceFileSystemProvider, WorkbenchPhase.AfterRestored);
1536
registerWorkbenchContribution2(PromptUrlHandler.ID, PromptUrlHandler, WorkbenchPhase.BlockRestore);
1537
registerWorkbenchContribution2(ChatEditingNotebookFileSystemProviderContrib.ID, ChatEditingNotebookFileSystemProviderContrib, WorkbenchPhase.BlockStartup);
1538
registerWorkbenchContribution2(UserToolSetsContributions.ID, UserToolSetsContributions, WorkbenchPhase.Eventually);
1539
registerWorkbenchContribution2(PromptLanguageFeaturesProvider.ID, PromptLanguageFeaturesProvider, WorkbenchPhase.Eventually);
1540
registerWorkbenchContribution2(ChatWindowNotifier.ID, ChatWindowNotifier, WorkbenchPhase.AfterRestored);
1541
registerWorkbenchContribution2(ChatRepoInfoContribution.ID, ChatRepoInfoContribution, WorkbenchPhase.Eventually);
1542
1543
registerChatActions();
1544
registerChatAccessibilityActions();
1545
registerChatCopyActions();
1546
registerChatCustomizationDiagnosticsAction();
1547
registerChatCodeBlockActions();
1548
registerChatCodeCompareBlockActions();
1549
registerChatFileTreeActions();
1550
registerChatPromptNavigationActions();
1551
registerChatTitleActions();
1552
registerChatExecuteActions();
1553
registerChatQueueActions();
1554
registerQuickChatActions();
1555
registerChatExportActions();
1556
registerMoveActions();
1557
registerNewChatActions();
1558
registerChatContextActions();
1559
registerChatDeveloperActions();
1560
registerChatEditorActions();
1561
registerChatElicitationActions();
1562
registerChatToolActions();
1563
registerLanguageModelActions();
1564
registerAction2(ConfigureToolSets);
1565
registerEditorFeature(ChatPasteProvidersFeature);
1566
1567
1568
registerSingleton(IChatTransferService, ChatTransferService, InstantiationType.Delayed);
1569
registerSingleton(IChatService, ChatService, InstantiationType.Delayed);
1570
registerSingleton(IChatWidgetService, ChatWidgetService, InstantiationType.Delayed);
1571
registerSingleton(IQuickChatService, QuickChatService, InstantiationType.Delayed);
1572
registerSingleton(IChatAccessibilityService, ChatAccessibilityService, InstantiationType.Delayed);
1573
registerSingleton(IChatWidgetHistoryService, ChatWidgetHistoryService, InstantiationType.Delayed);
1574
registerSingleton(ILanguageModelsConfigurationService, LanguageModelsConfigurationService, InstantiationType.Delayed);
1575
registerSingleton(ILanguageModelsService, LanguageModelsService, InstantiationType.Delayed);
1576
registerSingleton(ILanguageModelStatsService, LanguageModelStatsService, InstantiationType.Delayed);
1577
registerSingleton(IChatSlashCommandService, ChatSlashCommandService, InstantiationType.Delayed);
1578
registerSingleton(IChatAgentService, ChatAgentService, InstantiationType.Delayed);
1579
registerSingleton(IChatAgentNameService, ChatAgentNameService, InstantiationType.Delayed);
1580
registerSingleton(IChatVariablesService, ChatVariablesService, InstantiationType.Delayed);
1581
registerSingleton(ILanguageModelToolsService, LanguageModelToolsService, InstantiationType.Delayed);
1582
registerSingleton(ILanguageModelToolsConfirmationService, LanguageModelToolsConfirmationService, InstantiationType.Delayed);
1583
registerSingleton(IVoiceChatService, VoiceChatService, InstantiationType.Delayed);
1584
registerSingleton(IChatCodeBlockContextProviderService, ChatCodeBlockContextProviderService, InstantiationType.Delayed);
1585
registerSingleton(ICodeMapperService, CodeMapperService, InstantiationType.Delayed);
1586
registerSingleton(IChatEditingService, ChatEditingService, InstantiationType.Delayed);
1587
registerSingleton(IChatMarkdownAnchorService, ChatMarkdownAnchorService, InstantiationType.Delayed);
1588
registerSingleton(ILanguageModelIgnoredFilesService, LanguageModelIgnoredFilesService, InstantiationType.Delayed);
1589
registerSingleton(IPromptsService, PromptsService, InstantiationType.Delayed);
1590
registerSingleton(IChatContextPickService, ChatContextPickService, InstantiationType.Delayed);
1591
registerSingleton(IChatModeService, ChatModeService, InstantiationType.Delayed);
1592
registerSingleton(IChatAttachmentResolveService, ChatAttachmentResolveService, InstantiationType.Delayed);
1593
registerSingleton(IChatTodoListService, ChatTodoListService, InstantiationType.Delayed);
1594
registerSingleton(IChatOutputRendererService, ChatOutputRendererService, InstantiationType.Delayed);
1595
registerSingleton(IChatLayoutService, ChatLayoutService, InstantiationType.Delayed);
1596
registerSingleton(IChatTipService, ChatTipService, InstantiationType.Delayed);
1597
1598
ChatWidget.CONTRIBS.push(ChatDynamicVariableModel);
1599
1600