From 4c88d4b7f70505c577e0465f95b4052073d49e59 Mon Sep 17 00:00:00 2001 From: Tyler Leonhardt Date: Mon, 17 Nov 2025 15:29:03 -0800 Subject: [PATCH 01/15] Support GitHub MCP inbox Fixes https://github.com/microsoft/vscode/issues/254836 --- package.json | 28 ++++++ package.nls.json | 4 +- .../extension/vscode-node/contributions.ts | 4 +- .../common/githubMcpDefinitionProvider.ts | 45 +++++++++ .../vscode-node/githubMcp.contribution.ts | 52 ++++++++++ .../vscode.proposed.mcpToolDefinitions.d.ts | 98 +++++++++++++++++++ .../common/configurationService.ts | 3 + 7 files changed, 232 insertions(+), 2 deletions(-) create mode 100644 src/extension/githubMcp/common/githubMcpDefinitionProvider.ts create mode 100644 src/extension/githubMcp/vscode-node/githubMcp.contribution.ts create mode 100644 src/extension/vscode.proposed.mcpToolDefinitions.d.ts diff --git a/package.json b/package.json index adffe9a1d4..e8503337c3 100644 --- a/package.json +++ b/package.json @@ -107,6 +107,7 @@ "terminalSelection", "terminalQuickFixProvider", "mappedEditsProvider", + "mcpToolDefinitions", "aiRelatedInformation", "aiSettingsSearch", "chatParticipantAdditions", @@ -3785,6 +3786,27 @@ "advanced", "experimental" ] + }, + "github.copilot.chat.githubMcpServer.enabled": { + "type": "boolean", + "default": false, + "markdownDescription": "%github.copilot.config.githubMcpServer.enabled%", + "tags": [ + "advanced", + "experimental" + ] + }, + "github.copilot.chat.githubMcpServer.toolsets": { + "type": "array", + "default": ["default"], + "markdownDescription": "%github.copilot.config.githubMcpServer.toolsets%", + "items": { + "type": "string" + }, + "tags": [ + "advanced", + "experimental" + ] } } } @@ -3813,6 +3835,12 @@ "icon": "$(file-export)" } ], + "mcpServerDefinitionProviders": [ + { + "id": "github", + "label": "GitHub" + } + ], "menus": { "editor/title": [ { diff --git a/package.nls.json b/package.nls.json index eaa27aca16..55749ca877 100644 --- a/package.nls.json +++ b/package.nls.json @@ -414,5 +414,7 @@ "github.copilot.cli.sessions.newTerminalSession": "New Agent Session in Terminal", "github.copilot.command.openCopilotAgentSessionsInBrowser": "Open in Browser", "github.copilot.command.closeChatSessionPullRequest.title": "Close Pull Request", - "github.copilot.command.applyCopilotCLIAgentSessionChanges": "Apply Changes" + "github.copilot.command.applyCopilotCLIAgentSessionChanges": "Apply Changes", + "github.copilot.config.githubMcpServer.enabled": "Enable built-in support for the GitHub MCP Server.", + "github.copilot.config.githubMcpServer.toolsets": "Specify toolsets to use from the GitHub MCP Server." } diff --git a/src/extension/extension/vscode-node/contributions.ts b/src/extension/extension/vscode-node/contributions.ts index 81826ebe4b..ddf54ceb0a 100644 --- a/src/extension/extension/vscode-node/contributions.ts +++ b/src/extension/extension/vscode-node/contributions.ts @@ -24,6 +24,7 @@ import { DiagnosticsContextContribution } from '../../diagnosticsContext/vscode/ import { LanguageModelProxyContrib } from '../../externalAgents/vscode-node/lmProxyContrib'; import { WalkthroughCommandContribution } from '../../getting-started/vscode-node/commands'; import * as newWorkspaceContribution from '../../getting-started/vscode-node/newWorkspace.contribution'; +import { GitHubMcpContrib } from '../../githubMcp/vscode-node/githubMcp.contribution'; import { IgnoredFileProviderContribution } from '../../ignore/vscode-node/ignoreProvider'; import { InlineEditProviderFeature } from '../../inlineEdits/vscode-node/inlineEditProviderFeature'; import { FixTestFailureContribution } from '../../intents/vscode-node/fixTestFailureContributions'; @@ -86,7 +87,8 @@ export const vscodeNodeContributions: IExtensionContributionFactory[] = [ asContributionFactory(CompletionsCoreContribution), asContributionFactory(CompletionsUnificationContribution), workspaceIndexingContribution, - asContributionFactory(ChatSessionsContrib) + asContributionFactory(ChatSessionsContrib), + asContributionFactory(GitHubMcpContrib) ]; /** diff --git a/src/extension/githubMcp/common/githubMcpDefinitionProvider.ts b/src/extension/githubMcp/common/githubMcpDefinitionProvider.ts new file mode 100644 index 0000000000..34f912b069 --- /dev/null +++ b/src/extension/githubMcp/common/githubMcpDefinitionProvider.ts @@ -0,0 +1,45 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import type { McpHttpServerDefinition2, McpServerDefinitionProvider } from 'vscode'; +import { GITHUB_SCOPE_ALIGNED } from '../../../platform/authentication/common/authentication'; +import { ConfigKey, IConfigurationService } from '../../../platform/configuration/common/configurationService'; +import { Event } from '../../../util/vs/base/common/event'; +import { Disposable } from '../../../util/vs/base/common/lifecycle'; +import { URI } from '../../../util/vs/base/common/uri'; + +export class GitHubMcpDefinitionProvider extends Disposable implements McpServerDefinitionProvider { + + readonly onDidChangeMcpServerDefinitions: Event; + + constructor(@IConfigurationService private readonly configurationService: IConfigurationService) { + super(); + this.onDidChangeMcpServerDefinitions = Event.chain(configurationService.onDidChangeConfiguration, $ => $ + .filter(e => e.affectsConfiguration(ConfigKey.GitHubMcpToolsets.fullyQualifiedId)) + .map(() => { }) + ); + } + + private get toolsets(): string[] { + return this.configurationService.getConfig(ConfigKey.GitHubMcpToolsets); + } + + provideMcpServerDefinitions(): McpHttpServerDefinition2[] { + return [ + { + label: 'GitHub', + uri: URI.parse('https://api.githubcopilot.com/mcp/'), + headers: { + 'X-MCP-Toolsets': this.toolsets.join(',') + }, + version: '1.0', + authentication: { + providerId: 'github', + scopes: GITHUB_SCOPE_ALIGNED + } + } + ]; + } +} diff --git a/src/extension/githubMcp/vscode-node/githubMcp.contribution.ts b/src/extension/githubMcp/vscode-node/githubMcp.contribution.ts new file mode 100644 index 0000000000..dd44b4a2b0 --- /dev/null +++ b/src/extension/githubMcp/vscode-node/githubMcp.contribution.ts @@ -0,0 +1,52 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { lm } from 'vscode'; +import { ConfigKey, IConfigurationService } from '../../../platform/configuration/common/configurationService'; +import { IExperimentationService } from '../../../platform/telemetry/common/nullExperimentationService'; +import { Disposable, IDisposable } from '../../../util/vs/base/common/lifecycle'; +import { GitHubMcpDefinitionProvider } from '../common/githubMcpDefinitionProvider'; + +export class GitHubMcpContrib extends Disposable { + private disposable?: IDisposable; + private definitionProvider?: GitHubMcpDefinitionProvider; + + constructor( + @IConfigurationService private readonly configurationService: IConfigurationService, + @IExperimentationService private readonly experimentationService: IExperimentationService, + ) { + super(); + this._registerConfigurationListener(); + if (this.enabled) { + this._registerGitHubMcpDefinitionProvider(); + } + } + + private _registerConfigurationListener() { + this.configurationService.onDidChangeConfiguration(e => { + if (e.affectsConfiguration(ConfigKey.GitHubMcpEnabled.fullyQualifiedId)) { + if (this.enabled) { + this._registerGitHubMcpDefinitionProvider(); + } else { + this.disposable?.dispose(); + this.disposable = undefined; + this.definitionProvider = undefined; + } + } + }); + } + + private _registerGitHubMcpDefinitionProvider() { + if (!this.definitionProvider) { + // Register the GitHub MCP Definition Provider + this.definitionProvider = new GitHubMcpDefinitionProvider(this.configurationService); + this.disposable = lm.registerMcpServerDefinitionProvider('github', this.definitionProvider); + } + } + + private get enabled(): boolean { + return this.configurationService.getExperimentBasedConfig(ConfigKey.GitHubMcpEnabled, this.experimentationService); + } +} diff --git a/src/extension/vscode.proposed.mcpToolDefinitions.d.ts b/src/extension/vscode.proposed.mcpToolDefinitions.d.ts new file mode 100644 index 0000000000..c53aba12c7 --- /dev/null +++ b/src/extension/vscode.proposed.mcpToolDefinitions.d.ts @@ -0,0 +1,98 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +declare module 'vscode' { + + // https://github.com/microsoft/vscode/issues/272000 @connor4312 + + /** + * Defines when a {@link McpServerLanguageModelToolDefinition} is available + * for calling. + */ + export enum McpToolAvailability { + /** + * The MCP tool is available when the server starts up. + */ + Initial = 0, + + /** + * The MCP tool is conditionally available when certain preconditions are met. + */ + Dynamic = 1, + } + + /** + * The definition for a tool an MCP server provides. Extensions may provide + * this as part of their server metadata to allow the editor to defer + * starting the server until it's called by a language model. + */ + export interface McpServerLanguageModelToolDefinition { + /** + * The definition of the tool as it appears on the MCP protocol. This should + * be an object that includes the `inputSchema` and `name`, + * among other optional properties. + */ + definition?: unknown; + + /** + * An indicator for when the tool is available for calling. + */ + availability: McpToolAvailability; + } + + /** + * Metadata which the editor can use to hydrate information about the server + * prior to starting it. The extension can provide tools and basic server + * instructions as they would be expected to appear on MCP itself. + * + * Once a server is started, the observed values will be cached and take + * precedence over those statically declared here unless and until the + * server's {@link McpStdioServerDefinition.version version} is updated. If + * you can ensure the metadata is always accurate and do not otherwise have + * a server `version` to use, it is reasonable to set the server `version` + * to a hash of this object to ensure the cache tracks the {@link McpServerMetadata}. + */ + export interface McpServerMetadata { + /** + * Tools the MCP server exposes. + */ + tools?: McpServerLanguageModelToolDefinition[]; + + /** + * MCP server instructions as it would appear on the `initialize` result in the protocol. + */ + instructions?: string; + + /** + * MCP server capabilities as they would appear on the `initialize` result in the protocol. + */ + capabilities?: unknown; + + /** + * MCP server info as it would appear on the `initialize` result in the protocol. + */ + serverInfo?: unknown; + } + + + export class McpStdioServerDefinition2 extends McpStdioServerDefinition { + metadata?: McpServerMetadata; + constructor(label: string, command: string, args?: string[], env?: Record, version?: string, metadata?: McpServerMetadata); + } + + export class McpHttpServerDefinition2 extends McpHttpServerDefinition { + metadata?: McpServerMetadata; + + /** + * Authentication information to use to get a session for the initial MCP server connection. + */ + authentication?: { + providerId: string; + scopes: string[]; + } + + constructor(label: string, uri: Uri, headers?: Record, version?: string, metadata?: McpServerMetadata); + } +} diff --git a/src/platform/configuration/common/configurationService.ts b/src/platform/configuration/common/configurationService.ts index 0a4de7636e..5571a395b1 100644 --- a/src/platform/configuration/common/configurationService.ts +++ b/src/platform/configuration/common/configurationService.ts @@ -867,6 +867,9 @@ export namespace ConfigKey { export const CompletionsFetcher = defineSetting('chat.completionsFetcher', ConfigType.ExperimentBased, undefined); export const NextEditSuggestionsFetcher = defineSetting('chat.nesFetcher', ConfigType.ExperimentBased, undefined); + + export const GitHubMcpEnabled = defineSetting('chat.githubMcpServer.enabled', ConfigType.ExperimentBased, false); + export const GitHubMcpToolsets = defineSetting('chat.githubMcpServer.toolsets', ConfigType.Simple, ['default']); } export function getAllConfigKeys(): string[] { From df62afc7ea24af717a9d944fab115ace72e699f2 Mon Sep 17 00:00:00 2001 From: Tyler Leonhardt Date: Tue, 18 Nov 2025 12:52:21 -0800 Subject: [PATCH 02/15] Be auth provider aware, and bump version on every config change --- .../vscode-node/githubMcp.contribution.ts | 2 +- .../githubMcpDefinitionProvider.ts | 39 +++++++++++++++---- 2 files changed, 33 insertions(+), 8 deletions(-) rename src/extension/githubMcp/{common => vscode-node}/githubMcpDefinitionProvider.ts (51%) diff --git a/src/extension/githubMcp/vscode-node/githubMcp.contribution.ts b/src/extension/githubMcp/vscode-node/githubMcp.contribution.ts index dd44b4a2b0..19b48f175d 100644 --- a/src/extension/githubMcp/vscode-node/githubMcp.contribution.ts +++ b/src/extension/githubMcp/vscode-node/githubMcp.contribution.ts @@ -7,7 +7,7 @@ import { lm } from 'vscode'; import { ConfigKey, IConfigurationService } from '../../../platform/configuration/common/configurationService'; import { IExperimentationService } from '../../../platform/telemetry/common/nullExperimentationService'; import { Disposable, IDisposable } from '../../../util/vs/base/common/lifecycle'; -import { GitHubMcpDefinitionProvider } from '../common/githubMcpDefinitionProvider'; +import { GitHubMcpDefinitionProvider } from './githubMcpDefinitionProvider'; export class GitHubMcpContrib extends Disposable { private disposable?: IDisposable; diff --git a/src/extension/githubMcp/common/githubMcpDefinitionProvider.ts b/src/extension/githubMcp/vscode-node/githubMcpDefinitionProvider.ts similarity index 51% rename from src/extension/githubMcp/common/githubMcpDefinitionProvider.ts rename to src/extension/githubMcp/vscode-node/githubMcpDefinitionProvider.ts index 34f912b069..0dbfdad75d 100644 --- a/src/extension/githubMcp/common/githubMcpDefinitionProvider.ts +++ b/src/extension/githubMcp/vscode-node/githubMcpDefinitionProvider.ts @@ -5,19 +5,33 @@ import type { McpHttpServerDefinition2, McpServerDefinitionProvider } from 'vscode'; import { GITHUB_SCOPE_ALIGNED } from '../../../platform/authentication/common/authentication'; -import { ConfigKey, IConfigurationService } from '../../../platform/configuration/common/configurationService'; +import { authProviderId } from '../../../platform/authentication/vscode-node/session'; +import { AuthProviderId, ConfigKey, IConfigurationService } from '../../../platform/configuration/common/configurationService'; import { Event } from '../../../util/vs/base/common/event'; import { Disposable } from '../../../util/vs/base/common/lifecycle'; import { URI } from '../../../util/vs/base/common/uri'; +const EnterpriseURLConfig = 'github-enterprise.uri'; + export class GitHubMcpDefinitionProvider extends Disposable implements McpServerDefinitionProvider { readonly onDidChangeMcpServerDefinitions: Event; + private _version = 0; - constructor(@IConfigurationService private readonly configurationService: IConfigurationService) { + constructor( + @IConfigurationService private readonly configurationService: IConfigurationService + ) { super(); this.onDidChangeMcpServerDefinitions = Event.chain(configurationService.onDidChangeConfiguration, $ => $ - .filter(e => e.affectsConfiguration(ConfigKey.GitHubMcpToolsets.fullyQualifiedId)) + .filter(e => + // If they change the toolsets + e.affectsConfiguration(ConfigKey.GitHubMcpToolsets.fullyQualifiedId) || + // If they change to GHE or GitHub.com + e.affectsConfiguration(ConfigKey.Shared.AuthProvider.fullyQualifiedId) || + // If they change the GHE URL + e.affectsConfiguration(EnterpriseURLConfig) + ) + // void event .map(() => { }) ); } @@ -26,17 +40,28 @@ export class GitHubMcpDefinitionProvider extends Disposable implements McpServer return this.configurationService.getConfig(ConfigKey.GitHubMcpToolsets); } + private getGheUri(): URI { + const uri = this.configurationService.getNonExtensionConfig(EnterpriseURLConfig); + if (!uri) { + throw new Error('GitHub Enterprise URI is not configured.'); + } + return URI.parse(uri); + } + provideMcpServerDefinitions(): McpHttpServerDefinition2[] { + const providerId = authProviderId(this.configurationService); + const basics = providerId === AuthProviderId.GitHubEnterprise + ? { label: 'GitHub Enterprise', uri: this.getGheUri() } + : { label: 'GitHub', uri: URI.parse('https://api.githubcopilot.com/mcp/') }; return [ { - label: 'GitHub', - uri: URI.parse('https://api.githubcopilot.com/mcp/'), + ...basics, headers: { 'X-MCP-Toolsets': this.toolsets.join(',') }, - version: '1.0', + version: `1.${this._version++}`, authentication: { - providerId: 'github', + providerId, scopes: GITHUB_SCOPE_ALIGNED } } From 0907196de117b2607f831887533c93795b3925e9 Mon Sep 17 00:00:00 2001 From: Tyler Leonhardt Date: Tue, 18 Nov 2025 14:19:26 -0800 Subject: [PATCH 03/15] tests and fixed ghe url --- .../githubMcpDefinitionProvider.ts | 2 +- .../test/githubMcpDefinitionProvider.spec.ts | 179 ++++++++++++++++++ .../common/inMemoryConfigurationService.ts | 6 + 3 files changed, 186 insertions(+), 1 deletion(-) create mode 100644 src/extension/githubMcp/vscode-node/test/githubMcpDefinitionProvider.spec.ts diff --git a/src/extension/githubMcp/vscode-node/githubMcpDefinitionProvider.ts b/src/extension/githubMcp/vscode-node/githubMcpDefinitionProvider.ts index 0dbfdad75d..2667d75294 100644 --- a/src/extension/githubMcp/vscode-node/githubMcpDefinitionProvider.ts +++ b/src/extension/githubMcp/vscode-node/githubMcpDefinitionProvider.ts @@ -45,7 +45,7 @@ export class GitHubMcpDefinitionProvider extends Disposable implements McpServer if (!uri) { throw new Error('GitHub Enterprise URI is not configured.'); } - return URI.parse(uri); + return URI.parse(uri).with({ path: '/mcp/' }); } provideMcpServerDefinitions(): McpHttpServerDefinition2[] { diff --git a/src/extension/githubMcp/vscode-node/test/githubMcpDefinitionProvider.spec.ts b/src/extension/githubMcp/vscode-node/test/githubMcpDefinitionProvider.spec.ts new file mode 100644 index 0000000000..4620e6703b --- /dev/null +++ b/src/extension/githubMcp/vscode-node/test/githubMcpDefinitionProvider.spec.ts @@ -0,0 +1,179 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { afterEach, beforeEach, describe, expect, test } from 'vitest'; +import { GITHUB_SCOPE_ALIGNED } from '../../../../platform/authentication/common/authentication'; +import { AuthProviderId, ConfigKey, IConfigurationService } from '../../../../platform/configuration/common/configurationService'; +import { DefaultsOnlyConfigurationService } from '../../../../platform/configuration/common/defaultsOnlyConfigurationService'; +import { InMemoryConfigurationService } from '../../../../platform/configuration/test/common/inMemoryConfigurationService'; +import { TestingServiceCollection } from '../../../../platform/test/node/services'; +import { raceTimeout } from '../../../../util/vs/base/common/async'; +import { Event } from '../../../../util/vs/base/common/event'; +import { DisposableStore } from '../../../../util/vs/base/common/lifecycle'; +import { GitHubMcpDefinitionProvider } from '../githubMcpDefinitionProvider'; + +describe('GitHubMcpDefinitionProvider', () => { + let disposables: DisposableStore; + let provider: GitHubMcpDefinitionProvider; + let configService: InMemoryConfigurationService; + + /** + * Helper to create a provider with specific configuration values. + */ + async function createProvider(configOverrides?: { + authProvider?: AuthProviderId; + gheUri?: string; + toolsets?: string[]; + }): Promise { + const serviceCollection = new TestingServiceCollection(); + configService = disposables.add(new InMemoryConfigurationService(new DefaultsOnlyConfigurationService())); + + // Set configuration values before creating the provider + if (configOverrides?.authProvider) { + await configService.setConfig(ConfigKey.Shared.AuthProvider, configOverrides.authProvider); + } + if (configOverrides?.gheUri) { + await configService.setNonExtensionConfig('github-enterprise.uri', configOverrides.gheUri); + } + if (configOverrides?.toolsets) { + await configService.setConfig(ConfigKey.GitHubMcpToolsets, configOverrides.toolsets); + } + + serviceCollection.define(IConfigurationService, configService); + const accessor = serviceCollection.createTestingAccessor(); + return disposables.add(new GitHubMcpDefinitionProvider( + accessor.get(IConfigurationService) + )); + } + + beforeEach(async () => { + disposables = new DisposableStore(); + provider = await createProvider(); + }); + + afterEach(() => { + disposables.dispose(); + }); + + describe('provideMcpServerDefinitions', () => { + test('returns GitHub.com configuration by default', () => { + const definitions = provider.provideMcpServerDefinitions(); + + expect(definitions).toHaveLength(1); + expect(definitions[0].label).toBe('GitHub'); + expect(definitions[0].uri.toString()).toBe('https://api.githubcopilot.com/mcp/'); + expect(definitions[0].authentication?.providerId).toBe(AuthProviderId.GitHub); + expect(definitions[0].authentication?.scopes).toBe(GITHUB_SCOPE_ALIGNED); + }); + + test('returns GitHub Enterprise configuration when auth provider is set to GHE', async () => { + const gheUri = 'https://github.enterprise.com'; + const gheProvider = await createProvider({ + authProvider: AuthProviderId.GitHubEnterprise, + gheUri + }); + + const definitions = gheProvider.provideMcpServerDefinitions(); + + expect(definitions).toHaveLength(1); + expect(definitions[0].label).toBe('GitHub Enterprise'); + // URI.parse adds a trailing slash to bare domain URIs + expect(definitions[0].uri.toString()).toBe(gheUri + '/mcp/'); + expect(definitions[0].authentication?.providerId).toBe(AuthProviderId.GitHubEnterprise); + expect(definitions[0].authentication?.scopes).toBe(GITHUB_SCOPE_ALIGNED); + }); + + test('includes configured toolsets in headers', async () => { + const toolsets = ['code_search', 'issues', 'pull_requests']; + const providerWithToolsets = await createProvider({ toolsets }); + + const definitions = providerWithToolsets.provideMcpServerDefinitions(); + + expect(definitions[0].headers['X-MCP-Toolsets']).toBe('code_search,issues,pull_requests'); + }); + + test('handles empty toolsets configuration', async () => { + const providerWithEmptyToolsets = await createProvider({ toolsets: [] }); + + const definitions = providerWithEmptyToolsets.provideMcpServerDefinitions(); + + expect(definitions[0].headers['X-MCP-Toolsets']).toBe(''); + }); + + test('increments version on each call', () => { + const def1 = provider.provideMcpServerDefinitions(); + const def2 = provider.provideMcpServerDefinitions(); + const def3 = provider.provideMcpServerDefinitions(); + + expect(def1[0].version).toBe('1.0'); + expect(def2[0].version).toBe('1.1'); + expect(def3[0].version).toBe('1.2'); + }); + + test('throws when GHE is configured but URI is missing', async () => { + const gheProviderWithoutUri = await createProvider({ + authProvider: AuthProviderId.GitHubEnterprise + // Don't set the GHE URI + }); + + expect(() => gheProviderWithoutUri.provideMcpServerDefinitions()).toThrow('GitHub Enterprise URI is not configured.'); + }); + }); + + describe('onDidChangeMcpServerDefinitions', () => { + test('fires when toolsets configuration changes', async () => { + const eventPromise = Event.toPromise(provider.onDidChangeMcpServerDefinitions); + + await configService.setConfig(ConfigKey.GitHubMcpToolsets, ['new_toolset']); + + await eventPromise; + }); + + test('fires when auth provider configuration changes', async () => { + const eventPromise = Event.toPromise(provider.onDidChangeMcpServerDefinitions); + + await configService.setConfig(ConfigKey.Shared.AuthProvider, AuthProviderId.GitHubEnterprise); + + await eventPromise; + }); + + test('fires when GHE URI configuration changes', async () => { + await configService.setConfig(ConfigKey.Shared.AuthProvider, AuthProviderId.GitHubEnterprise); + await configService.setNonExtensionConfig('github-enterprise.uri', 'https://old.enterprise.com'); + + const eventPromise = Event.toPromise(provider.onDidChangeMcpServerDefinitions); + + await configService.setNonExtensionConfig('github-enterprise.uri', 'https://new.enterprise.com'); + + await eventPromise; + }); + + test('does not fire for unrelated configuration changes', async () => { + let eventFired = false; + disposables.add(provider.onDidChangeMcpServerDefinitions(() => { + eventFired = true; + })); + + await configService.setNonExtensionConfig('some.unrelated.config', 'value'); + + const eventPromise = new Promise(resolve => { + disposables.add(provider.onDidChangeMcpServerDefinitions(() => resolve())); + }); + const result = await raceTimeout(eventPromise, 50); + + expect(result).toBeUndefined(); + expect(eventFired).toBe(false); + }); + }); + + describe('edge cases', () => { + test('uses default toolsets value when not configured', () => { + const definitions = provider.provideMcpServerDefinitions(); + + expect(definitions).toHaveLength(1); + expect(definitions[0].headers['X-MCP-Toolsets']).toBe('default'); + }); + }); +}); diff --git a/src/platform/configuration/test/common/inMemoryConfigurationService.ts b/src/platform/configuration/test/common/inMemoryConfigurationService.ts index 45f19c3632..a72d6673a4 100644 --- a/src/platform/configuration/test/common/inMemoryConfigurationService.ts +++ b/src/platform/configuration/test/common/inMemoryConfigurationService.ts @@ -46,11 +46,17 @@ export class InMemoryConfigurationService extends AbstractConfigurationService { override setConfig(key: BaseConfig, value: T): Promise { this.overrides.set(key, value); + this._onDidChangeConfiguration.fire({ + affectsConfiguration: (section: string) => section === key.fullyQualifiedId || key.fullyQualifiedId.startsWith(section + '.') + }); return Promise.resolve(); } setNonExtensionConfig(key: string, value: T): Promise { this.nonExtensionOverrides.set(key, value); + this._onDidChangeConfiguration.fire({ + affectsConfiguration: (section: string) => section === key || key.startsWith(section + '.') + }); return Promise.resolve(); } From 121b949c7ec1fd8c30da9a03126de68455527143 Mon Sep 17 00:00:00 2001 From: Tyler Leonhardt Date: Tue, 18 Nov 2025 14:30:59 -0800 Subject: [PATCH 04/15] Move things around so the layers make more sense --- .../githubMcpDefinitionProvider.ts | 3 +-- .../node}/githubMcpDefinitionProvider.spec.ts | 2 +- .../vscode-node/githubMcp.contribution.ts | 2 +- .../authentication/common/authentication.ts | 10 +++++++++- .../vscode-node/authenticationService.ts | 4 ++-- .../authentication/vscode-node/session.ts | 16 ++++------------ 6 files changed, 18 insertions(+), 19 deletions(-) rename src/extension/githubMcp/{vscode-node => common}/githubMcpDefinitionProvider.ts (93%) rename src/extension/githubMcp/{vscode-node/test => test/node}/githubMcpDefinitionProvider.spec.ts (98%) diff --git a/src/extension/githubMcp/vscode-node/githubMcpDefinitionProvider.ts b/src/extension/githubMcp/common/githubMcpDefinitionProvider.ts similarity index 93% rename from src/extension/githubMcp/vscode-node/githubMcpDefinitionProvider.ts rename to src/extension/githubMcp/common/githubMcpDefinitionProvider.ts index 2667d75294..989a9efc60 100644 --- a/src/extension/githubMcp/vscode-node/githubMcpDefinitionProvider.ts +++ b/src/extension/githubMcp/common/githubMcpDefinitionProvider.ts @@ -4,8 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import type { McpHttpServerDefinition2, McpServerDefinitionProvider } from 'vscode'; -import { GITHUB_SCOPE_ALIGNED } from '../../../platform/authentication/common/authentication'; -import { authProviderId } from '../../../platform/authentication/vscode-node/session'; +import { authProviderId, GITHUB_SCOPE_ALIGNED } from '../../../platform/authentication/common/authentication'; import { AuthProviderId, ConfigKey, IConfigurationService } from '../../../platform/configuration/common/configurationService'; import { Event } from '../../../util/vs/base/common/event'; import { Disposable } from '../../../util/vs/base/common/lifecycle'; diff --git a/src/extension/githubMcp/vscode-node/test/githubMcpDefinitionProvider.spec.ts b/src/extension/githubMcp/test/node/githubMcpDefinitionProvider.spec.ts similarity index 98% rename from src/extension/githubMcp/vscode-node/test/githubMcpDefinitionProvider.spec.ts rename to src/extension/githubMcp/test/node/githubMcpDefinitionProvider.spec.ts index 4620e6703b..dcc139e595 100644 --- a/src/extension/githubMcp/vscode-node/test/githubMcpDefinitionProvider.spec.ts +++ b/src/extension/githubMcp/test/node/githubMcpDefinitionProvider.spec.ts @@ -12,7 +12,7 @@ import { TestingServiceCollection } from '../../../../platform/test/node/service import { raceTimeout } from '../../../../util/vs/base/common/async'; import { Event } from '../../../../util/vs/base/common/event'; import { DisposableStore } from '../../../../util/vs/base/common/lifecycle'; -import { GitHubMcpDefinitionProvider } from '../githubMcpDefinitionProvider'; +import { GitHubMcpDefinitionProvider } from '../../common/githubMcpDefinitionProvider'; describe('GitHubMcpDefinitionProvider', () => { let disposables: DisposableStore; diff --git a/src/extension/githubMcp/vscode-node/githubMcp.contribution.ts b/src/extension/githubMcp/vscode-node/githubMcp.contribution.ts index 19b48f175d..dd44b4a2b0 100644 --- a/src/extension/githubMcp/vscode-node/githubMcp.contribution.ts +++ b/src/extension/githubMcp/vscode-node/githubMcp.contribution.ts @@ -7,7 +7,7 @@ import { lm } from 'vscode'; import { ConfigKey, IConfigurationService } from '../../../platform/configuration/common/configurationService'; import { IExperimentationService } from '../../../platform/telemetry/common/nullExperimentationService'; import { Disposable, IDisposable } from '../../../util/vs/base/common/lifecycle'; -import { GitHubMcpDefinitionProvider } from './githubMcpDefinitionProvider'; +import { GitHubMcpDefinitionProvider } from '../common/githubMcpDefinitionProvider'; export class GitHubMcpContrib extends Disposable { private disposable?: IDisposable; diff --git a/src/platform/authentication/common/authentication.ts b/src/platform/authentication/common/authentication.ts index 365fa87a84..03467b7375 100644 --- a/src/platform/authentication/common/authentication.ts +++ b/src/platform/authentication/common/authentication.ts @@ -7,7 +7,7 @@ import { createServiceIdentifier } from '../../../util/common/services'; import { Emitter, Event } from '../../../util/vs/base/common/event'; import { Disposable } from '../../../util/vs/base/common/lifecycle'; import { derived } from '../../../util/vs/base/common/observableInternal'; -import { AuthPermissionMode, ConfigKey, IConfigurationService } from '../../configuration/common/configurationService'; +import { AuthPermissionMode, AuthProviderId, ConfigKey, IConfigurationService } from '../../configuration/common/configurationService'; import { ILogService } from '../../log/common/logService'; import { CopilotToken } from './copilotToken'; import { ICopilotTokenManager } from './copilotTokenManager'; @@ -305,3 +305,11 @@ export abstract class BaseAuthenticationService extends Disposable implements IA this._logService.debug('Finished handling auth change event.'); } } + +export function authProviderId(configurationService: IConfigurationService): AuthProviderId { + return ( + configurationService.getConfig(ConfigKey.Shared.AuthProvider) === AuthProviderId.GitHubEnterprise + ? AuthProviderId.GitHubEnterprise + : AuthProviderId.GitHub + ); +} diff --git a/src/platform/authentication/vscode-node/authenticationService.ts b/src/platform/authentication/vscode-node/authenticationService.ts index dd0fd79114..b3b0661aae 100644 --- a/src/platform/authentication/vscode-node/authenticationService.ts +++ b/src/platform/authentication/vscode-node/authenticationService.ts @@ -8,10 +8,10 @@ import { TaskSingler } from '../../../util/common/taskSingler'; import { AuthProviderId, IConfigurationService } from '../../configuration/common/configurationService'; import { IDomainService } from '../../endpoint/common/domainService'; import { ILogService } from '../../log/common/logService'; -import { BaseAuthenticationService } from '../common/authentication'; +import { authProviderId, BaseAuthenticationService } from '../common/authentication'; import { ICopilotTokenManager } from '../common/copilotTokenManager'; import { ICopilotTokenStore } from '../common/copilotTokenStore'; -import { authProviderId, getAlignedSession, getAnyAuthSession } from './session'; +import { getAlignedSession, getAnyAuthSession } from './session'; export class AuthenticationService extends BaseAuthenticationService { private _taskSingler = new TaskSingler(); diff --git a/src/platform/authentication/vscode-node/session.ts b/src/platform/authentication/vscode-node/session.ts index c0a712802b..7853f4eee9 100644 --- a/src/platform/authentication/vscode-node/session.ts +++ b/src/platform/authentication/vscode-node/session.ts @@ -3,11 +3,11 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { AuthenticationGetSessionOptions, AuthenticationSession, AuthenticationSessionsChangeEvent, authentication } from 'vscode'; -import { URI } from '../../../util/vs/base/common/uri'; -import { AuthPermissionMode, AuthProviderId, ConfigKey, IConfigurationService } from '../../configuration/common/configurationService'; -import { GITHUB_SCOPE_ALIGNED, GITHUB_SCOPE_READ_USER, GITHUB_SCOPE_USER_EMAIL, MinimalModeError } from '../common/authentication'; +import { authentication, AuthenticationGetSessionOptions, AuthenticationSession, AuthenticationSessionsChangeEvent } from 'vscode'; import { mixin } from '../../../util/vs/base/common/objects'; +import { URI } from '../../../util/vs/base/common/uri'; +import { AuthPermissionMode, ConfigKey, IConfigurationService } from '../../configuration/common/configurationService'; +import { authProviderId, GITHUB_SCOPE_ALIGNED, GITHUB_SCOPE_READ_USER, GITHUB_SCOPE_USER_EMAIL, MinimalModeError } from '../common/authentication'; export const SESSION_LOGIN_MESSAGE = 'You are not signed in to GitHub. Please sign in to use Copilot.'; // These types are subsets of the "real" types AuthenticationSessionAccountInformation and @@ -22,14 +22,6 @@ export type CopilotAuthenticationSession = { account: CopilotAuthenticationSessionAccountInformation; }; -export function authProviderId(configurationService: IConfigurationService): AuthProviderId { - return ( - configurationService.getConfig(ConfigKey.Shared.AuthProvider) === AuthProviderId.GitHubEnterprise - ? AuthProviderId.GitHubEnterprise - : AuthProviderId.GitHub - ); -} - async function getAuthSession(providerId: string, defaultScopes: string[], getSilentSession: () => Promise, options: AuthenticationGetSessionOptions = {}) { const accounts = await authentication.getAccounts(providerId); if (!accounts.length) { From 9e4d9653686972bf3be77dedceb3aa44c08210d3 Mon Sep 17 00:00:00 2001 From: Tyler Leonhardt Date: Tue, 18 Nov 2025 14:41:07 -0800 Subject: [PATCH 05/15] move settings to experimental section --- package.json | 40 +++++++++++++++++++--------------------- 1 file changed, 19 insertions(+), 21 deletions(-) diff --git a/package.json b/package.json index 965f9a603d..a485c3b128 100644 --- a/package.json +++ b/package.json @@ -2665,6 +2665,25 @@ { "id": "experimental", "properties": { + "github.copilot.chat.githubMcpServer.enabled": { + "type": "boolean", + "default": false, + "markdownDescription": "%github.copilot.config.githubMcpServer.enabled%", + "tags": [ + "experimental" + ] + }, + "github.copilot.chat.githubMcpServer.toolsets": { + "type": "array", + "default": ["default"], + "markdownDescription": "%github.copilot.config.githubMcpServer.toolsets%", + "items": { + "type": "string" + }, + "tags": [ + "experimental" + ] + }, "github.copilot.chat.imageUpload.enabled": { "type": "boolean", "default": true, @@ -3861,27 +3880,6 @@ "advanced", "experimental" ] - }, - "github.copilot.chat.githubMcpServer.enabled": { - "type": "boolean", - "default": false, - "markdownDescription": "%github.copilot.config.githubMcpServer.enabled%", - "tags": [ - "advanced", - "experimental" - ] - }, - "github.copilot.chat.githubMcpServer.toolsets": { - "type": "array", - "default": ["default"], - "markdownDescription": "%github.copilot.config.githubMcpServer.toolsets%", - "items": { - "type": "string" - }, - "tags": [ - "advanced", - "experimental" - ] } } } From 3148dc17ec39dc92b9c699d0e0f09f006c602744 Mon Sep 17 00:00:00 2001 From: Tyler Leonhardt Date: Tue, 18 Nov 2025 14:41:58 -0800 Subject: [PATCH 06/15] move def prov --- package.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index a485c3b128..9a7dc3e9e2 100644 --- a/package.json +++ b/package.json @@ -1770,6 +1770,12 @@ "when": "!github.copilot.interactiveSession.disabled" } ], + "mcpServerDefinitionProviders": [ + { + "id": "github", + "label": "GitHub" + } + ], "viewsWelcome": [ { "view": "debug", @@ -3908,12 +3914,6 @@ "icon": "$(file-export)" } ], - "mcpServerDefinitionProviders": [ - { - "id": "github", - "label": "GitHub" - } - ], "menus": { "editor/title": [ { From a84222663b62bec8022ec14fd8f051b88ac79a62 Mon Sep 17 00:00:00 2001 From: Tyler Leonhardt Date: Tue, 18 Nov 2025 17:20:33 -0800 Subject: [PATCH 07/15] who needs new APIs anyway? --- package.json | 1 - .../common/githubMcpDefinitionProvider.ts | 77 +++++--- .../node/githubMcpDefinitionProvider.spec.ts | 177 ++++++++++++++---- .../vscode-node/githubMcp.contribution.ts | 12 +- .../vscode.proposed.mcpToolDefinitions.d.ts | 98 ---------- 5 files changed, 203 insertions(+), 162 deletions(-) delete mode 100644 src/extension/vscode.proposed.mcpToolDefinitions.d.ts diff --git a/package.json b/package.json index 9a7dc3e9e2..8ccc70cc09 100644 --- a/package.json +++ b/package.json @@ -107,7 +107,6 @@ "terminalSelection", "terminalQuickFixProvider", "mappedEditsProvider", - "mcpToolDefinitions", "aiRelatedInformation", "aiSettingsSearch", "chatParticipantAdditions", diff --git a/src/extension/githubMcp/common/githubMcpDefinitionProvider.ts b/src/extension/githubMcp/common/githubMcpDefinitionProvider.ts index 989a9efc60..6a9dbcc16e 100644 --- a/src/extension/githubMcp/common/githubMcpDefinitionProvider.ts +++ b/src/extension/githubMcp/common/githubMcpDefinitionProvider.ts @@ -3,52 +3,80 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import type { McpHttpServerDefinition2, McpServerDefinitionProvider } from 'vscode'; -import { authProviderId, GITHUB_SCOPE_ALIGNED } from '../../../platform/authentication/common/authentication'; +import type { CancellationToken, McpHttpServerDefinition, McpServerDefinitionProvider } from 'vscode'; +import { authProviderId, IAuthenticationService } from '../../../platform/authentication/common/authentication'; import { AuthProviderId, ConfigKey, IConfigurationService } from '../../../platform/configuration/common/configurationService'; +import { ILogService } from '../../../platform/log/common/logService'; import { Event } from '../../../util/vs/base/common/event'; -import { Disposable } from '../../../util/vs/base/common/lifecycle'; import { URI } from '../../../util/vs/base/common/uri'; const EnterpriseURLConfig = 'github-enterprise.uri'; -export class GitHubMcpDefinitionProvider extends Disposable implements McpServerDefinitionProvider { +export class GitHubMcpDefinitionProvider implements McpServerDefinitionProvider { readonly onDidChangeMcpServerDefinitions: Event; - private _version = 0; constructor( - @IConfigurationService private readonly configurationService: IConfigurationService + @IConfigurationService private readonly configurationService: IConfigurationService, + @IAuthenticationService private readonly authenticationService: IAuthenticationService, + @ILogService private readonly logService: ILogService ) { - super(); - this.onDidChangeMcpServerDefinitions = Event.chain(configurationService.onDidChangeConfiguration, $ => $ - .filter(e => + const configurationEvent = Event.chain(configurationService.onDidChangeConfiguration, $ => $ + .filter(e => { // If they change the toolsets - e.affectsConfiguration(ConfigKey.GitHubMcpToolsets.fullyQualifiedId) || + if (e.affectsConfiguration(ConfigKey.GitHubMcpToolsets.fullyQualifiedId)) { + logService.debug('GitHubMcpDefinitionProvider: Configuration change affects GitHub MCP toolsets.'); + return true; + } // If they change to GHE or GitHub.com - e.affectsConfiguration(ConfigKey.Shared.AuthProvider.fullyQualifiedId) || + if (e.affectsConfiguration(ConfigKey.Shared.AuthProvider.fullyQualifiedId)) { + logService.debug('GitHubMcpDefinitionProvider: Configuration change affects GitHub auth provider.'); + return true; + } // If they change the GHE URL - e.affectsConfiguration(EnterpriseURLConfig) - ) + if (e.affectsConfiguration(EnterpriseURLConfig)) { + logService.debug('GitHubMcpDefinitionProvider: Configuration change affects GitHub Enterprise URL.'); + return true; + } + return false; + }) // void event .map(() => { }) ); + let havePermissiveToken = !!this.authenticationService.permissiveGitHubSession; + const authEvent = Event.chain(this.authenticationService.onDidAuthenticationChange, $ => $ + .filter(() => { + const hadToken = havePermissiveToken; + havePermissiveToken = !!this.authenticationService.permissiveGitHubSession; + return hadToken !== havePermissiveToken; + }) + .map(() => + this.logService.debug(`GitHubMcpDefinitionProvider: Permissive GitHub session availability changed: ${havePermissiveToken}`)) + ); + this.onDidChangeMcpServerDefinitions = Event.any(configurationEvent, authEvent); } private get toolsets(): string[] { return this.configurationService.getConfig(ConfigKey.GitHubMcpToolsets); } + private get gheConfig(): string | undefined { + return this.configurationService.getNonExtensionConfig(EnterpriseURLConfig); + } + private getGheUri(): URI { - const uri = this.configurationService.getNonExtensionConfig(EnterpriseURLConfig); + const uri = this.gheConfig; if (!uri) { throw new Error('GitHub Enterprise URI is not configured.'); } - return URI.parse(uri).with({ path: '/mcp/' }); + // Prefix with 'copilot-api.' + const url = URI.parse(uri).with({ path: '/mcp/' }); + return url.with({ authority: `copilot-api.${url.authority}` }); } - provideMcpServerDefinitions(): McpHttpServerDefinition2[] { + provideMcpServerDefinitions(): McpHttpServerDefinition[] { const providerId = authProviderId(this.configurationService); + const toolsets = this.toolsets.sort().join(','); const basics = providerId === AuthProviderId.GitHubEnterprise ? { label: 'GitHub Enterprise', uri: this.getGheUri() } : { label: 'GitHub', uri: URI.parse('https://api.githubcopilot.com/mcp/') }; @@ -56,14 +84,19 @@ export class GitHubMcpDefinitionProvider extends Disposable implements McpServer { ...basics, headers: { - 'X-MCP-Toolsets': this.toolsets.join(',') + 'X-MCP-Toolsets': toolsets }, - version: `1.${this._version++}`, - authentication: { - providerId, - scopes: GITHUB_SCOPE_ALIGNED - } + version: toolsets } ]; } + + resolveMcpServerDefinition(server: McpHttpServerDefinition, token: CancellationToken): McpHttpServerDefinition | undefined { + if (!this.authenticationService.permissiveGitHubSession) { + this.logService.trace('GitHubMcpDefinitionProvider: No permissive GitHub session available to resolve MCP server definition.'); + return undefined; + } + server.headers['Authorization'] = `Bearer ${this.authenticationService.permissiveGitHubSession.accessToken}`; + return server; + } } diff --git a/src/extension/githubMcp/test/node/githubMcpDefinitionProvider.spec.ts b/src/extension/githubMcp/test/node/githubMcpDefinitionProvider.spec.ts index dcc139e595..ca55f5b987 100644 --- a/src/extension/githubMcp/test/node/githubMcpDefinitionProvider.spec.ts +++ b/src/extension/githubMcp/test/node/githubMcpDefinitionProvider.spec.ts @@ -3,21 +3,70 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { afterEach, beforeEach, describe, expect, test } from 'vitest'; -import { GITHUB_SCOPE_ALIGNED } from '../../../../platform/authentication/common/authentication'; +import { beforeEach, describe, expect, test } from 'vitest'; +import type { AuthenticationGetSessionOptions, AuthenticationSession } from 'vscode'; +import { BaseAuthenticationService, IAuthenticationService } from '../../../../platform/authentication/common/authentication'; +import { CopilotToken } from '../../../../platform/authentication/common/copilotToken'; +import { ICopilotTokenManager } from '../../../../platform/authentication/common/copilotTokenManager'; +import { CopilotTokenStore, ICopilotTokenStore } from '../../../../platform/authentication/common/copilotTokenStore'; +import { SimulationTestCopilotTokenManager } from '../../../../platform/authentication/test/node/simulationTestCopilotTokenManager'; import { AuthProviderId, ConfigKey, IConfigurationService } from '../../../../platform/configuration/common/configurationService'; import { DefaultsOnlyConfigurationService } from '../../../../platform/configuration/common/defaultsOnlyConfigurationService'; import { InMemoryConfigurationService } from '../../../../platform/configuration/test/common/inMemoryConfigurationService'; +import { ILogService, LogServiceImpl } from '../../../../platform/log/common/logService'; import { TestingServiceCollection } from '../../../../platform/test/node/services'; import { raceTimeout } from '../../../../util/vs/base/common/async'; -import { Event } from '../../../../util/vs/base/common/event'; -import { DisposableStore } from '../../../../util/vs/base/common/lifecycle'; +import { CancellationToken } from '../../../../util/vs/base/common/cancellation'; +import { Emitter, Event } from '../../../../util/vs/base/common/event'; +import { SyncDescriptor } from '../../../../util/vs/platform/instantiation/common/descriptors'; import { GitHubMcpDefinitionProvider } from '../../common/githubMcpDefinitionProvider'; +/** + * Test implementation of authentication service that allows setting sessions dynamically + */ +class TestAuthenticationService extends BaseAuthenticationService { + private readonly _onDidChange = new Emitter(); + + constructor( + @ILogService logService: ILogService, + @ICopilotTokenStore tokenStore: ICopilotTokenStore, + @ICopilotTokenManager tokenManager: ICopilotTokenManager, + @IConfigurationService configurationService: IConfigurationService + ) { + super(logService, tokenStore, tokenManager, configurationService); + this._register(this._onDidChange); + } + + setPermissiveGitHubSession(session: AuthenticationSession | undefined): void { + this._permissiveGitHubSession = session; + this._onDidAuthenticationChange.fire(); + } + + getAnyGitHubSession(_options?: AuthenticationGetSessionOptions): Promise { + return Promise.resolve(this._anyGitHubSession); + } + + getPermissiveGitHubSession(_options?: AuthenticationGetSessionOptions): Promise { + return Promise.resolve(this._permissiveGitHubSession); + } + + override getAnyAdoSession(_options?: AuthenticationGetSessionOptions): Promise { + return Promise.resolve(undefined); + } + + override getAdoAccessTokenBase64(_options?: AuthenticationGetSessionOptions): Promise { + return Promise.resolve(undefined); + } + + override async getCopilotToken(_force?: boolean): Promise { + return await super.getCopilotToken(_force); + } +} + describe('GitHubMcpDefinitionProvider', () => { - let disposables: DisposableStore; - let provider: GitHubMcpDefinitionProvider; let configService: InMemoryConfigurationService; + let authService: TestAuthenticationService; + let provider: GitHubMcpDefinitionProvider; /** * Helper to create a provider with specific configuration values. @@ -26,9 +75,10 @@ describe('GitHubMcpDefinitionProvider', () => { authProvider?: AuthProviderId; gheUri?: string; toolsets?: string[]; + hasPermissiveToken?: boolean; }): Promise { const serviceCollection = new TestingServiceCollection(); - configService = disposables.add(new InMemoryConfigurationService(new DefaultsOnlyConfigurationService())); + configService = new InMemoryConfigurationService(new DefaultsOnlyConfigurationService()); // Set configuration values before creating the provider if (configOverrides?.authProvider) { @@ -42,21 +92,29 @@ describe('GitHubMcpDefinitionProvider', () => { } serviceCollection.define(IConfigurationService, configService); + serviceCollection.define(ICopilotTokenStore, new SyncDescriptor(CopilotTokenStore)); + serviceCollection.define(ICopilotTokenManager, new SyncDescriptor(SimulationTestCopilotTokenManager)); + serviceCollection.define(IAuthenticationService, new SyncDescriptor(TestAuthenticationService)); + serviceCollection.define(ILogService, new LogServiceImpl([])); const accessor = serviceCollection.createTestingAccessor(); - return disposables.add(new GitHubMcpDefinitionProvider( - accessor.get(IConfigurationService) - )); + + // Get the auth service and set up permissive token if needed + authService = accessor.get(IAuthenticationService) as TestAuthenticationService; + if (configOverrides?.hasPermissiveToken !== false) { + authService.setPermissiveGitHubSession({ accessToken: 'test-token', id: 'test-id', account: { id: 'test-account', label: 'test' }, scopes: [] }); + } + + return new GitHubMcpDefinitionProvider( + accessor.get(IConfigurationService), + accessor.get(IAuthenticationService), + accessor.get(ILogService) + ); } beforeEach(async () => { - disposables = new DisposableStore(); provider = await createProvider(); }); - afterEach(() => { - disposables.dispose(); - }); - describe('provideMcpServerDefinitions', () => { test('returns GitHub.com configuration by default', () => { const definitions = provider.provideMcpServerDefinitions(); @@ -64,8 +122,6 @@ describe('GitHubMcpDefinitionProvider', () => { expect(definitions).toHaveLength(1); expect(definitions[0].label).toBe('GitHub'); expect(definitions[0].uri.toString()).toBe('https://api.githubcopilot.com/mcp/'); - expect(definitions[0].authentication?.providerId).toBe(AuthProviderId.GitHub); - expect(definitions[0].authentication?.scopes).toBe(GITHUB_SCOPE_ALIGNED); }); test('returns GitHub Enterprise configuration when auth provider is set to GHE', async () => { @@ -79,10 +135,8 @@ describe('GitHubMcpDefinitionProvider', () => { expect(definitions).toHaveLength(1); expect(definitions[0].label).toBe('GitHub Enterprise'); - // URI.parse adds a trailing slash to bare domain URIs - expect(definitions[0].uri.toString()).toBe(gheUri + '/mcp/'); - expect(definitions[0].authentication?.providerId).toBe(AuthProviderId.GitHubEnterprise); - expect(definitions[0].authentication?.scopes).toBe(GITHUB_SCOPE_ALIGNED); + // Should include the copilot-api. prefix + expect(definitions[0].uri.toString()).toBe('https://copilot-api.github.enterprise.com/mcp/'); }); test('includes configured toolsets in headers', async () => { @@ -102,14 +156,12 @@ describe('GitHubMcpDefinitionProvider', () => { expect(definitions[0].headers['X-MCP-Toolsets']).toBe(''); }); - test('increments version on each call', () => { - const def1 = provider.provideMcpServerDefinitions(); - const def2 = provider.provideMcpServerDefinitions(); - const def3 = provider.provideMcpServerDefinitions(); - - expect(def1[0].version).toBe('1.0'); - expect(def2[0].version).toBe('1.1'); - expect(def3[0].version).toBe('1.2'); + test('version is the sorted toolset string', async () => { + const toolsets = ['pull_requests', 'code_search', 'issues']; + const providerWithToolsets = await createProvider({ toolsets }); + const definitions = providerWithToolsets.provideMcpServerDefinitions(); + // Sorted toolsets string + expect(definitions[0].version).toBe('code_search,issues,pull_requests'); }); test('throws when GHE is configured but URI is missing', async () => { @@ -152,28 +204,79 @@ describe('GitHubMcpDefinitionProvider', () => { test('does not fire for unrelated configuration changes', async () => { let eventFired = false; - disposables.add(provider.onDidChangeMcpServerDefinitions(() => { + const handler = () => { eventFired = true; - })); + }; + const disposable = provider.onDidChangeMcpServerDefinitions(handler); await configService.setNonExtensionConfig('some.unrelated.config', 'value'); - const eventPromise = new Promise(resolve => { - disposables.add(provider.onDidChangeMcpServerDefinitions(() => resolve())); - }); - const result = await raceTimeout(eventPromise, 50); + await raceTimeout(Promise.resolve(), 50); - expect(result).toBeUndefined(); expect(eventFired).toBe(false); + disposable.dispose(); }); }); describe('edge cases', () => { test('uses default toolsets value when not configured', () => { const definitions = provider.provideMcpServerDefinitions(); - expect(definitions).toHaveLength(1); expect(definitions[0].headers['X-MCP-Toolsets']).toBe('default'); + expect(definitions[0].version).toBe('default'); + }); + }); + + describe('resolveMcpServerDefinition', () => { + test('adds authorization header when permissive token is available', () => { + const definitions = provider.provideMcpServerDefinitions(); + const resolved = provider.resolveMcpServerDefinition(definitions[0], CancellationToken.None); + + expect(resolved).toBeDefined(); + expect(resolved!.headers['Authorization']).toBe('Bearer test-token'); + }); + + test('returns undefined when no permissive token is available', async () => { + const providerWithoutToken = await createProvider({ hasPermissiveToken: false }); + const definitions = providerWithoutToken.provideMcpServerDefinitions(); + const resolved = providerWithoutToken.resolveMcpServerDefinition(definitions[0], CancellationToken.None); + + expect(resolved).toBeUndefined(); + }); + }); + + describe('authentication change events', () => { + test('fires onDidChangeMcpServerDefinitions when token becomes available', async () => { + const providerWithoutToken = await createProvider({ hasPermissiveToken: false }); + const eventPromise = Event.toPromise(providerWithoutToken.onDidChangeMcpServerDefinitions); + + authService.setPermissiveGitHubSession({ accessToken: 'new-token', id: 'new-id', account: { id: 'new-account', label: 'new' }, scopes: [] }); + + await eventPromise; + }); + + test('fires onDidChangeMcpServerDefinitions when token is removed', async () => { + const eventPromise = Event.toPromise(provider.onDidChangeMcpServerDefinitions); + + authService.setPermissiveGitHubSession(undefined); + + await eventPromise; + }); + + test('does not fire when token changes but availability remains the same', async () => { + let eventFired = false; + const handler = () => { + eventFired = true; + }; + const disposable = provider.onDidChangeMcpServerDefinitions(handler); + + // Change the token value but keep it defined + authService.setPermissiveGitHubSession({ accessToken: 'different-token', id: 'different-id', account: { id: 'different-account', label: 'different' }, scopes: [] }); + + await raceTimeout(Promise.resolve(), 50); + + expect(eventFired).toBe(false); + disposable.dispose(); }); }); }); diff --git a/src/extension/githubMcp/vscode-node/githubMcp.contribution.ts b/src/extension/githubMcp/vscode-node/githubMcp.contribution.ts index dd44b4a2b0..485af2f652 100644 --- a/src/extension/githubMcp/vscode-node/githubMcp.contribution.ts +++ b/src/extension/githubMcp/vscode-node/githubMcp.contribution.ts @@ -4,7 +4,9 @@ *--------------------------------------------------------------------------------------------*/ import { lm } from 'vscode'; +import { IAuthenticationService } from '../../../platform/authentication/common/authentication'; import { ConfigKey, IConfigurationService } from '../../../platform/configuration/common/configurationService'; +import { ILogService } from '../../../platform/log/common/logService'; import { IExperimentationService } from '../../../platform/telemetry/common/nullExperimentationService'; import { Disposable, IDisposable } from '../../../util/vs/base/common/lifecycle'; import { GitHubMcpDefinitionProvider } from '../common/githubMcpDefinitionProvider'; @@ -16,11 +18,13 @@ export class GitHubMcpContrib extends Disposable { constructor( @IConfigurationService private readonly configurationService: IConfigurationService, @IExperimentationService private readonly experimentationService: IExperimentationService, + @IAuthenticationService private readonly authenticationService: IAuthenticationService, + @ILogService private readonly logService: ILogService ) { super(); this._registerConfigurationListener(); if (this.enabled) { - this._registerGitHubMcpDefinitionProvider(); + void this._registerGitHubMcpDefinitionProvider(); } } @@ -28,7 +32,7 @@ export class GitHubMcpContrib extends Disposable { this.configurationService.onDidChangeConfiguration(e => { if (e.affectsConfiguration(ConfigKey.GitHubMcpEnabled.fullyQualifiedId)) { if (this.enabled) { - this._registerGitHubMcpDefinitionProvider(); + void this._registerGitHubMcpDefinitionProvider(); } else { this.disposable?.dispose(); this.disposable = undefined; @@ -38,10 +42,10 @@ export class GitHubMcpContrib extends Disposable { }); } - private _registerGitHubMcpDefinitionProvider() { + private async _registerGitHubMcpDefinitionProvider() { if (!this.definitionProvider) { // Register the GitHub MCP Definition Provider - this.definitionProvider = new GitHubMcpDefinitionProvider(this.configurationService); + this.definitionProvider = new GitHubMcpDefinitionProvider(this.configurationService, this.authenticationService, this.logService); this.disposable = lm.registerMcpServerDefinitionProvider('github', this.definitionProvider); } } diff --git a/src/extension/vscode.proposed.mcpToolDefinitions.d.ts b/src/extension/vscode.proposed.mcpToolDefinitions.d.ts deleted file mode 100644 index c53aba12c7..0000000000 --- a/src/extension/vscode.proposed.mcpToolDefinitions.d.ts +++ /dev/null @@ -1,98 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -declare module 'vscode' { - - // https://github.com/microsoft/vscode/issues/272000 @connor4312 - - /** - * Defines when a {@link McpServerLanguageModelToolDefinition} is available - * for calling. - */ - export enum McpToolAvailability { - /** - * The MCP tool is available when the server starts up. - */ - Initial = 0, - - /** - * The MCP tool is conditionally available when certain preconditions are met. - */ - Dynamic = 1, - } - - /** - * The definition for a tool an MCP server provides. Extensions may provide - * this as part of their server metadata to allow the editor to defer - * starting the server until it's called by a language model. - */ - export interface McpServerLanguageModelToolDefinition { - /** - * The definition of the tool as it appears on the MCP protocol. This should - * be an object that includes the `inputSchema` and `name`, - * among other optional properties. - */ - definition?: unknown; - - /** - * An indicator for when the tool is available for calling. - */ - availability: McpToolAvailability; - } - - /** - * Metadata which the editor can use to hydrate information about the server - * prior to starting it. The extension can provide tools and basic server - * instructions as they would be expected to appear on MCP itself. - * - * Once a server is started, the observed values will be cached and take - * precedence over those statically declared here unless and until the - * server's {@link McpStdioServerDefinition.version version} is updated. If - * you can ensure the metadata is always accurate and do not otherwise have - * a server `version` to use, it is reasonable to set the server `version` - * to a hash of this object to ensure the cache tracks the {@link McpServerMetadata}. - */ - export interface McpServerMetadata { - /** - * Tools the MCP server exposes. - */ - tools?: McpServerLanguageModelToolDefinition[]; - - /** - * MCP server instructions as it would appear on the `initialize` result in the protocol. - */ - instructions?: string; - - /** - * MCP server capabilities as they would appear on the `initialize` result in the protocol. - */ - capabilities?: unknown; - - /** - * MCP server info as it would appear on the `initialize` result in the protocol. - */ - serverInfo?: unknown; - } - - - export class McpStdioServerDefinition2 extends McpStdioServerDefinition { - metadata?: McpServerMetadata; - constructor(label: string, command: string, args?: string[], env?: Record, version?: string, metadata?: McpServerMetadata); - } - - export class McpHttpServerDefinition2 extends McpHttpServerDefinition { - metadata?: McpServerMetadata; - - /** - * Authentication information to use to get a session for the initial MCP server connection. - */ - authentication?: { - providerId: string; - scopes: string[]; - } - - constructor(label: string, uri: Uri, headers?: Record, version?: string, metadata?: McpServerMetadata); - } -} From e773b5d07140d40e7b1ff5d4629a302c57442d4d Mon Sep 17 00:00:00 2001 From: Tyler Leonhardt Date: Wed, 19 Nov 2025 09:27:07 -0800 Subject: [PATCH 08/15] Ask for auth --- .../common/githubMcpDefinitionProvider.ts | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/extension/githubMcp/common/githubMcpDefinitionProvider.ts b/src/extension/githubMcp/common/githubMcpDefinitionProvider.ts index 6a9dbcc16e..04380ceaec 100644 --- a/src/extension/githubMcp/common/githubMcpDefinitionProvider.ts +++ b/src/extension/githubMcp/common/githubMcpDefinitionProvider.ts @@ -9,6 +9,7 @@ import { AuthProviderId, ConfigKey, IConfigurationService } from '../../../platf import { ILogService } from '../../../platform/log/common/logService'; import { Event } from '../../../util/vs/base/common/event'; import { URI } from '../../../util/vs/base/common/uri'; +import * as l10n from '@vscode/l10n'; const EnterpriseURLConfig = 'github-enterprise.uri'; @@ -91,12 +92,13 @@ export class GitHubMcpDefinitionProvider implements McpServerDefinitionProvider< ]; } - resolveMcpServerDefinition(server: McpHttpServerDefinition, token: CancellationToken): McpHttpServerDefinition | undefined { - if (!this.authenticationService.permissiveGitHubSession) { - this.logService.trace('GitHubMcpDefinitionProvider: No permissive GitHub session available to resolve MCP server definition.'); - return undefined; - } - server.headers['Authorization'] = `Bearer ${this.authenticationService.permissiveGitHubSession.accessToken}`; + async resolveMcpServerDefinition(server: McpHttpServerDefinition, token: CancellationToken): Promise { + const session = await this.authenticationService.getPermissiveGitHubSession({ + createIfNone: { + detail: l10n.t('Additional permissions are required to use GitHub MCP Server'), + }, + }); + server.headers['Authorization'] = `Bearer ${session!.accessToken}`; return server; } } From 8b7337a12fda9b0509497e0ce9b47b76cb224b36 Mon Sep 17 00:00:00 2001 From: Tyler Leonhardt Date: Wed, 19 Nov 2025 09:44:43 -0800 Subject: [PATCH 09/15] fix tests --- .../common/githubMcpDefinitionProvider.ts | 2 +- .../node/githubMcpDefinitionProvider.spec.ts | 18 +++++++++++------- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/extension/githubMcp/common/githubMcpDefinitionProvider.ts b/src/extension/githubMcp/common/githubMcpDefinitionProvider.ts index 04380ceaec..d7212e4b77 100644 --- a/src/extension/githubMcp/common/githubMcpDefinitionProvider.ts +++ b/src/extension/githubMcp/common/githubMcpDefinitionProvider.ts @@ -92,7 +92,7 @@ export class GitHubMcpDefinitionProvider implements McpServerDefinitionProvider< ]; } - async resolveMcpServerDefinition(server: McpHttpServerDefinition, token: CancellationToken): Promise { + async resolveMcpServerDefinition(server: McpHttpServerDefinition, token: CancellationToken): Promise { const session = await this.authenticationService.getPermissiveGitHubSession({ createIfNone: { detail: l10n.t('Additional permissions are required to use GitHub MCP Server'), diff --git a/src/extension/githubMcp/test/node/githubMcpDefinitionProvider.spec.ts b/src/extension/githubMcp/test/node/githubMcpDefinitionProvider.spec.ts index ca55f5b987..19fe8aa2f9 100644 --- a/src/extension/githubMcp/test/node/githubMcpDefinitionProvider.spec.ts +++ b/src/extension/githubMcp/test/node/githubMcpDefinitionProvider.spec.ts @@ -46,7 +46,10 @@ class TestAuthenticationService extends BaseAuthenticationService { return Promise.resolve(this._anyGitHubSession); } - getPermissiveGitHubSession(_options?: AuthenticationGetSessionOptions): Promise { + getPermissiveGitHubSession(options?: AuthenticationGetSessionOptions): Promise { + if (options?.createIfNone && !this._permissiveGitHubSession) { + throw new Error('No permissive GitHub session available'); + } return Promise.resolve(this._permissiveGitHubSession); } @@ -228,20 +231,21 @@ describe('GitHubMcpDefinitionProvider', () => { }); describe('resolveMcpServerDefinition', () => { - test('adds authorization header when permissive token is available', () => { + test('adds authorization header when permissive token is available', async () => { const definitions = provider.provideMcpServerDefinitions(); - const resolved = provider.resolveMcpServerDefinition(definitions[0], CancellationToken.None); + const resolved = await provider.resolveMcpServerDefinition(definitions[0], CancellationToken.None); expect(resolved).toBeDefined(); - expect(resolved!.headers['Authorization']).toBe('Bearer test-token'); + expect(resolved.headers['Authorization']).toBe('Bearer test-token'); }); - test('returns undefined when no permissive token is available', async () => { + test('throws when no permissive token is available and session cannot be created', async () => { const providerWithoutToken = await createProvider({ hasPermissiveToken: false }); const definitions = providerWithoutToken.provideMcpServerDefinitions(); - const resolved = providerWithoutToken.resolveMcpServerDefinition(definitions[0], CancellationToken.None); - expect(resolved).toBeUndefined(); + // Since the mock returns undefined and the implementation uses session!.accessToken, + // this will throw when trying to access accessToken on undefined + await expect(providerWithoutToken.resolveMcpServerDefinition(definitions[0], CancellationToken.None)).rejects.toThrow(); }); }); From 27a52d84f436e21c16db41c43113def4357c8334 Mon Sep 17 00:00:00 2001 From: Tyler Leonhardt Date: Wed, 19 Nov 2025 15:56:55 -0800 Subject: [PATCH 10/15] disable `#githubRepo` when GH MCP is enabled --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index 8ccc70cc09..63aa042cf4 100644 --- a/package.json +++ b/package.json @@ -1012,6 +1012,7 @@ "userDescription": "%github.copilot.tools.githubRepo.userDescription%", "icon": "$(repo)", "canBeReferencedInPrompt": true, + "when": "!config.github.copilot.chat.githubMcpServer.enabled", "inputSchema": { "type": "object", "properties": { From 48be3658b16f8a5d8521728aff3fd4b9d51ff1d0 Mon Sep 17 00:00:00 2001 From: Tyler Leonhardt Date: Wed, 19 Nov 2025 16:26:01 -0800 Subject: [PATCH 11/15] Include settings for readonly & lockdown --- package.json | 16 +++ package.nls.json | 4 +- .../common/githubMcpDefinitionProvider.ts | 45 +++++++- .../node/githubMcpDefinitionProvider.spec.ts | 108 +++++++++++++++++- .../common/configurationService.ts | 2 + 5 files changed, 168 insertions(+), 7 deletions(-) diff --git a/package.json b/package.json index 63aa042cf4..27644ed915 100644 --- a/package.json +++ b/package.json @@ -2690,6 +2690,22 @@ "experimental" ] }, + "github.copilot.chat.githubMcpServer.readonly": { + "type": "boolean", + "default": false, + "markdownDescription": "%github.copilot.config.githubMcpServer.readonly%", + "tags": [ + "experimental" + ] + }, + "github.copilot.chat.githubMcpServer.lockdown": { + "type": "boolean", + "default": false, + "markdownDescription": "%github.copilot.config.githubMcpServer.lockdown%", + "tags": [ + "experimental" + ] + }, "github.copilot.chat.imageUpload.enabled": { "type": "boolean", "default": true, diff --git a/package.nls.json b/package.nls.json index 55749ca877..b427150f0d 100644 --- a/package.nls.json +++ b/package.nls.json @@ -416,5 +416,7 @@ "github.copilot.command.closeChatSessionPullRequest.title": "Close Pull Request", "github.copilot.command.applyCopilotCLIAgentSessionChanges": "Apply Changes", "github.copilot.config.githubMcpServer.enabled": "Enable built-in support for the GitHub MCP Server.", - "github.copilot.config.githubMcpServer.toolsets": "Specify toolsets to use from the GitHub MCP Server." + "github.copilot.config.githubMcpServer.toolsets": "Specify toolsets to use from the GitHub MCP Server.", + "github.copilot.config.githubMcpServer.readonly": "Enable read-only mode for the GitHub MCP Server. When enabled, only read tools are available.", + "github.copilot.config.githubMcpServer.lockdown": "Enable lockdown mode for the GitHub MCP Server. When enabled, hides public issue details created by users without push access." } diff --git a/src/extension/githubMcp/common/githubMcpDefinitionProvider.ts b/src/extension/githubMcp/common/githubMcpDefinitionProvider.ts index d7212e4b77..465d0de94f 100644 --- a/src/extension/githubMcp/common/githubMcpDefinitionProvider.ts +++ b/src/extension/githubMcp/common/githubMcpDefinitionProvider.ts @@ -3,13 +3,13 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import * as l10n from '@vscode/l10n'; import type { CancellationToken, McpHttpServerDefinition, McpServerDefinitionProvider } from 'vscode'; import { authProviderId, IAuthenticationService } from '../../../platform/authentication/common/authentication'; import { AuthProviderId, ConfigKey, IConfigurationService } from '../../../platform/configuration/common/configurationService'; import { ILogService } from '../../../platform/log/common/logService'; import { Event } from '../../../util/vs/base/common/event'; import { URI } from '../../../util/vs/base/common/uri'; -import * as l10n from '@vscode/l10n'; const EnterpriseURLConfig = 'github-enterprise.uri'; @@ -29,6 +29,16 @@ export class GitHubMcpDefinitionProvider implements McpServerDefinitionProvider< logService.debug('GitHubMcpDefinitionProvider: Configuration change affects GitHub MCP toolsets.'); return true; } + // If they change readonly mode + if (e.affectsConfiguration(ConfigKey.GitHubMcpReadonly.fullyQualifiedId)) { + logService.debug('GitHubMcpDefinitionProvider: Configuration change affects GitHub MCP readonly mode.'); + return true; + } + // If they change lockdown mode + if (e.affectsConfiguration(ConfigKey.GitHubMcpLockdown.fullyQualifiedId)) { + logService.debug('GitHubMcpDefinitionProvider: Configuration change affects GitHub MCP lockdown mode.'); + return true; + } // If they change to GHE or GitHub.com if (e.affectsConfiguration(ConfigKey.Shared.AuthProvider.fullyQualifiedId)) { logService.debug('GitHubMcpDefinitionProvider: Configuration change affects GitHub auth provider.'); @@ -61,6 +71,14 @@ export class GitHubMcpDefinitionProvider implements McpServerDefinitionProvider< return this.configurationService.getConfig(ConfigKey.GitHubMcpToolsets); } + private get readonly(): boolean { + return this.configurationService.getConfig(ConfigKey.GitHubMcpReadonly); + } + + private get lockdown(): boolean { + return this.configurationService.getConfig(ConfigKey.GitHubMcpLockdown); + } + private get gheConfig(): string | undefined { return this.configurationService.getNonExtensionConfig(EnterpriseURLConfig); } @@ -78,16 +96,33 @@ export class GitHubMcpDefinitionProvider implements McpServerDefinitionProvider< provideMcpServerDefinitions(): McpHttpServerDefinition[] { const providerId = authProviderId(this.configurationService); const toolsets = this.toolsets.sort().join(','); + const readonly = this.readonly; + const lockdown = this.lockdown; + const basics = providerId === AuthProviderId.GitHubEnterprise ? { label: 'GitHub Enterprise', uri: this.getGheUri() } : { label: 'GitHub', uri: URI.parse('https://api.githubcopilot.com/mcp/') }; + + // Build headers object conditionally + const headers: Record = {}; + // Build version string with toolsets and flags + let version = toolsets ?? '0'; + if (toolsets.length > 0) { + headers['X-MCP-Toolsets'] = toolsets; + } + if (readonly) { + headers['X-MCP-Readonly'] = 'true'; + version += '|readonly'; + } + if (lockdown) { + headers['X-MCP-Lockdown'] = 'true'; + version += '|lockdown'; + } return [ { ...basics, - headers: { - 'X-MCP-Toolsets': toolsets - }, - version: toolsets + headers, + version } ]; } diff --git a/src/extension/githubMcp/test/node/githubMcpDefinitionProvider.spec.ts b/src/extension/githubMcp/test/node/githubMcpDefinitionProvider.spec.ts index 19fe8aa2f9..a406d51ed9 100644 --- a/src/extension/githubMcp/test/node/githubMcpDefinitionProvider.spec.ts +++ b/src/extension/githubMcp/test/node/githubMcpDefinitionProvider.spec.ts @@ -78,6 +78,8 @@ describe('GitHubMcpDefinitionProvider', () => { authProvider?: AuthProviderId; gheUri?: string; toolsets?: string[]; + readonly?: boolean; + lockdown?: boolean; hasPermissiveToken?: boolean; }): Promise { const serviceCollection = new TestingServiceCollection(); @@ -93,6 +95,12 @@ describe('GitHubMcpDefinitionProvider', () => { if (configOverrides?.toolsets) { await configService.setConfig(ConfigKey.GitHubMcpToolsets, configOverrides.toolsets); } + if (configOverrides?.readonly !== undefined) { + await configService.setConfig(ConfigKey.GitHubMcpReadonly, configOverrides.readonly); + } + if (configOverrides?.lockdown !== undefined) { + await configService.setConfig(ConfigKey.GitHubMcpLockdown, configOverrides.lockdown); + } serviceCollection.define(IConfigurationService, configService); serviceCollection.define(ICopilotTokenStore, new SyncDescriptor(CopilotTokenStore)); @@ -156,7 +164,7 @@ describe('GitHubMcpDefinitionProvider', () => { const definitions = providerWithEmptyToolsets.provideMcpServerDefinitions(); - expect(definitions[0].headers['X-MCP-Toolsets']).toBe(''); + expect(definitions[0].headers['X-MCP-Toolsets']).toBeUndefined(); }); test('version is the sorted toolset string', async () => { @@ -175,6 +183,88 @@ describe('GitHubMcpDefinitionProvider', () => { expect(() => gheProviderWithoutUri.provideMcpServerDefinitions()).toThrow('GitHub Enterprise URI is not configured.'); }); + + test('includes X-MCP-Readonly header when readonly is true', async () => { + const readonlyProvider = await createProvider({ readonly: true }); + + const definitions = readonlyProvider.provideMcpServerDefinitions(); + + expect(definitions[0].headers['X-MCP-Readonly']).toBe('true'); + }); + + test('does not include X-MCP-Readonly header when readonly is false', async () => { + const nonReadonlyProvider = await createProvider({ readonly: false }); + + const definitions = nonReadonlyProvider.provideMcpServerDefinitions(); + + expect(definitions[0].headers['X-MCP-Readonly']).toBeUndefined(); + }); + + test('includes X-MCP-Lockdown header when lockdown is true', async () => { + const lockdownProvider = await createProvider({ lockdown: true }); + + const definitions = lockdownProvider.provideMcpServerDefinitions(); + + expect(definitions[0].headers['X-MCP-Lockdown']).toBe('true'); + }); + + test('does not include X-MCP-Lockdown header when lockdown is false', async () => { + const nonLockdownProvider = await createProvider({ lockdown: false }); + + const definitions = nonLockdownProvider.provideMcpServerDefinitions(); + + expect(definitions[0].headers['X-MCP-Lockdown']).toBeUndefined(); + }); + + test('includes both readonly and lockdown headers when both are true', async () => { + const bothProvider = await createProvider({ readonly: true, lockdown: true }); + + const definitions = bothProvider.provideMcpServerDefinitions(); + + expect(definitions[0].headers['X-MCP-Readonly']).toBe('true'); + expect(definitions[0].headers['X-MCP-Lockdown']).toBe('true'); + }); + + test('version includes readonly flag when readonly is true', async () => { + const readonlyProvider = await createProvider({ readonly: true }); + + const definitions = readonlyProvider.provideMcpServerDefinitions(); + + expect(definitions[0].version).toBe('default|readonly'); + }); + + test('version includes lockdown flag when lockdown is true', async () => { + const lockdownProvider = await createProvider({ lockdown: true }); + + const definitions = lockdownProvider.provideMcpServerDefinitions(); + + expect(definitions[0].version).toBe('default|lockdown'); + }); + + test('version includes both flags when both readonly and lockdown are true', async () => { + const bothProvider = await createProvider({ readonly: true, lockdown: true }); + + const definitions = bothProvider.provideMcpServerDefinitions(); + + expect(definitions[0].version).toBe('default|readonly|lockdown'); + }); + + test('version is just toolsets when readonly and lockdown are false', async () => { + const toolsets = ['issues', 'pull_requests']; + const normalProvider = await createProvider({ toolsets, readonly: false, lockdown: false }); + + const definitions = normalProvider.provideMcpServerDefinitions(); + + expect(definitions[0].version).toBe('issues,pull_requests'); + }); + + test('version with empty toolsets and readonly', async () => { + const readonlyEmptyProvider = await createProvider({ toolsets: [], readonly: true }); + + const definitions = readonlyEmptyProvider.provideMcpServerDefinitions(); + + expect(definitions[0].version).toBe('|readonly'); + }); }); describe('onDidChangeMcpServerDefinitions', () => { @@ -219,6 +309,22 @@ describe('GitHubMcpDefinitionProvider', () => { expect(eventFired).toBe(false); disposable.dispose(); }); + + test('fires when readonly configuration changes', async () => { + const eventPromise = Event.toPromise(provider.onDidChangeMcpServerDefinitions); + + await configService.setConfig(ConfigKey.GitHubMcpReadonly, true); + + await eventPromise; + }); + + test('fires when lockdown configuration changes', async () => { + const eventPromise = Event.toPromise(provider.onDidChangeMcpServerDefinitions); + + await configService.setConfig(ConfigKey.GitHubMcpLockdown, true); + + await eventPromise; + }); }); describe('edge cases', () => { diff --git a/src/platform/configuration/common/configurationService.ts b/src/platform/configuration/common/configurationService.ts index 5571a395b1..c113c0589f 100644 --- a/src/platform/configuration/common/configurationService.ts +++ b/src/platform/configuration/common/configurationService.ts @@ -870,6 +870,8 @@ export namespace ConfigKey { export const GitHubMcpEnabled = defineSetting('chat.githubMcpServer.enabled', ConfigType.ExperimentBased, false); export const GitHubMcpToolsets = defineSetting('chat.githubMcpServer.toolsets', ConfigType.Simple, ['default']); + export const GitHubMcpReadonly = defineSetting('chat.githubMcpServer.readonly', ConfigType.Simple, false); + export const GitHubMcpLockdown = defineSetting('chat.githubMcpServer.lockdown', ConfigType.Simple, false); } export function getAllConfigKeys(): string[] { From 7a18b32e5440cc9d9f490df38ee4748d0d799d47 Mon Sep 17 00:00:00 2001 From: Tyler Leonhardt Date: Wed, 19 Nov 2025 16:40:39 -0800 Subject: [PATCH 12/15] misc --- .../githubMcp/common/githubMcpDefinitionProvider.ts | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/extension/githubMcp/common/githubMcpDefinitionProvider.ts b/src/extension/githubMcp/common/githubMcpDefinitionProvider.ts index 465d0de94f..8d95e40726 100644 --- a/src/extension/githubMcp/common/githubMcpDefinitionProvider.ts +++ b/src/extension/githubMcp/common/githubMcpDefinitionProvider.ts @@ -61,8 +61,9 @@ export class GitHubMcpDefinitionProvider implements McpServerDefinitionProvider< havePermissiveToken = !!this.authenticationService.permissiveGitHubSession; return hadToken !== havePermissiveToken; }) - .map(() => - this.logService.debug(`GitHubMcpDefinitionProvider: Permissive GitHub session availability changed: ${havePermissiveToken}`)) + .map(() => { + this.logService.debug(`GitHubMcpDefinitionProvider: Permissive GitHub session availability changed: ${havePermissiveToken}`); + }) ); this.onDidChangeMcpServerDefinitions = Event.any(configurationEvent, authEvent); } @@ -106,7 +107,7 @@ export class GitHubMcpDefinitionProvider implements McpServerDefinitionProvider< // Build headers object conditionally const headers: Record = {}; // Build version string with toolsets and flags - let version = toolsets ?? '0'; + let version = toolsets.length ? toolsets : '0'; if (toolsets.length > 0) { headers['X-MCP-Toolsets'] = toolsets; } @@ -133,7 +134,10 @@ export class GitHubMcpDefinitionProvider implements McpServerDefinitionProvider< detail: l10n.t('Additional permissions are required to use GitHub MCP Server'), }, }); - server.headers['Authorization'] = `Bearer ${session!.accessToken}`; + if (!session) { + throw new Error('Authentication required'); + } + server.headers['Authorization'] = `Bearer ${session.accessToken}`; return server; } } From f23c6290c4f74f7c4c996d75caaac5f57dd49866 Mon Sep 17 00:00:00 2001 From: Tyler Leonhardt Date: Wed, 19 Nov 2025 16:56:12 -0800 Subject: [PATCH 13/15] fix test --- .../githubMcp/test/node/githubMcpDefinitionProvider.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/extension/githubMcp/test/node/githubMcpDefinitionProvider.spec.ts b/src/extension/githubMcp/test/node/githubMcpDefinitionProvider.spec.ts index a406d51ed9..bfb4dcb83b 100644 --- a/src/extension/githubMcp/test/node/githubMcpDefinitionProvider.spec.ts +++ b/src/extension/githubMcp/test/node/githubMcpDefinitionProvider.spec.ts @@ -263,7 +263,7 @@ describe('GitHubMcpDefinitionProvider', () => { const definitions = readonlyEmptyProvider.provideMcpServerDefinitions(); - expect(definitions[0].version).toBe('|readonly'); + expect(definitions[0].version).toBe('0|readonly'); }); }); From 433e5cffdbe4a94a02788f9f131ef9d35e0dd669 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 20 Nov 2025 02:45:02 +0000 Subject: [PATCH 14/15] Initial plan From 9bd7986598b6b1146e3aba6c525387ec37f07d75 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 20 Nov 2025 02:58:22 +0000 Subject: [PATCH 15/15] Merge main into copilot/sub-pr-2051 Co-authored-by: TylerLeonhardt <2644648+TylerLeonhardt@users.noreply.github.com> --- chat-lib/package-lock.json | 61 ++- chat-lib/package.json | 3 +- package-lock.json | 125 +++-- package.nls.json | 17 +- .../agents/copilotcli/node/copilotCli.ts | 18 +- .../copilotcli/node/copilotcliSession.ts | 7 +- .../node/copilotcliSessionService.ts | 24 +- .../test/copilotCliSessionService.spec.ts | 2 +- .../node/test/copilotcliSession.spec.ts | 20 +- .../copilotCLIChatSessionsContribution.ts | 37 +- .../copilotCloudGitOperationsManager.ts | 158 ++++++ .../copilotCloudSessionsProvider.ts | 141 ++++-- .../copilotCLIChatSessionParticipant.spec.ts | 26 +- src/extension/intents/node/agentIntent.ts | 2 +- .../node/test/repoInfoTelemetry.spec.ts | 2 + .../node/agent/openai/gpt51CodexPrompt.tsx | 2 +- .../prompts/node/agent/openai/gpt51Prompt.tsx | 2 +- .../node/agent/openai/gpt5CodexPrompt.tsx | 2 +- .../prompts/node/inline/inlineChat2Prompt.tsx | 37 +- .../tools/common/test/toolService.spec.ts | 12 + src/extension/tools/common/toolNames.ts | 2 - src/extension/tools/common/toolsRegistry.ts | 9 +- src/extension/tools/common/toolsService.ts | 12 +- .../tools/node/test/searchToolTestUtils.ts | 33 +- .../tools/node/test/testFailure.spec.tsx | 8 +- .../tools/node/test/testToolsService.ts | 4 +- src/extension/tools/node/testFailureTool.tsx | 4 +- .../tools/vscode-node/toolsService.ts | 6 +- .../common/serverProtocol.ts | 10 +- .../src/common/baseContextProviders.ts | 8 +- .../src/common/contextProvider.ts | 19 +- .../serverPlugin/src/common/protocol.ts | 8 +- .../serverPlugin/src/common/typescripts.ts | 4 +- .../serverPlugin/src/common/utils.ts | 2 +- .../vscode-node/inspector.ts | 6 +- .../vscode-node/languageContextService.ts | 15 +- .../vscode.proposed.chatSessionsProvider.d.ts | 4 - src/extension/xtab/node/xtabProvider.ts | 2 +- .../common/configurationService.ts | 5 +- .../endpoint/common/endpointProvider.ts | 3 +- src/platform/endpoint/node/chatEndpoint.ts | 21 +- src/platform/endpoint/node/messagesApi.ts | 456 ++++++++++++++++++ src/platform/git/common/gitService.ts | 3 + src/platform/git/vscode/git.d.ts | 7 + src/platform/git/vscode/gitServiceImpl.ts | 12 + src/platform/github/common/githubService.ts | 51 +- .../github/common/octoKitServiceImpl.ts | 218 +++++++-- src/platform/networking/common/fetch.ts | 12 +- src/platform/networking/common/networking.ts | 10 +- .../test/node/simulationWorkspaceServices.ts | 8 + .../outcome/edit-inlinechatintent-inline.json | 285 +++++------ .../fix-inlinechatintent-cpp-inline.json | 2 +- .../fix-inlinechatintent-eslint-inline.json | 86 ++-- ...ix-inlinechatintent-powershell-inline.json | 5 +- .../fix-inlinechatintent-pylint-inline.json | 15 +- .../fix-inlinechatintent-pyright-inline.json | 51 +- .../fix-inlinechatintent-roslyn-inline.json | 43 +- .../fix-inlinechatintent-ruff-inline.json | 2 +- .../fix-inlinechatintent-tsc-inline.json | 176 +++---- .../generate-inlinechatintent-inline.json | 342 +++++++------ test/simulation/baseline.json | 360 +++++++------- ...451045a-da8c-43fa-ba6f-8198c2eb0975.sqlite | 3 + 62 files changed, 2048 insertions(+), 982 deletions(-) create mode 100644 src/extension/chatSessions/vscode-node/copilotCloudGitOperationsManager.ts create mode 100644 src/platform/endpoint/node/messagesApi.ts create mode 100644 test/simulation/cache/layers/c451045a-da8c-43fa-ba6f-8198c2eb0975.sqlite diff --git a/chat-lib/package-lock.json b/chat-lib/package-lock.json index 4439953914..0dff9261bc 100644 --- a/chat-lib/package-lock.json +++ b/chat-lib/package-lock.json @@ -10,7 +10,7 @@ "license": "SEE LICENSE IN LICENSE.txt", "dependencies": { "@microsoft/tiktokenizer": "^1.0.10", - "@vscode/copilot-api": "^0.1.13", + "@vscode/copilot-api": "^0.2.2", "@vscode/l10n": "^0.0.18", "@vscode/prompt-tsx": "^0.4.0-alpha.5", "jsonc-parser": "^3.3.1", @@ -19,6 +19,7 @@ "yaml": "^2.8.0" }, "devDependencies": { + "@anthropic-ai/sdk": "^0.68.0", "@octokit/types": "^14.1.0", "@types/node": "^22.16.3", "@types/vscode": "^1.102.0", @@ -34,6 +35,37 @@ "node": ">=22.14.0" } }, + "node_modules/@anthropic-ai/sdk": { + "version": "0.68.0", + "resolved": "https://registry.npmjs.org/@anthropic-ai/sdk/-/sdk-0.68.0.tgz", + "integrity": "sha512-SMYAmbbiprG8k1EjEPMTwaTqssDT7Ae+jxcR5kWXiqTlbwMR2AthXtscEVWOHkRfyAV5+y3PFYTJRNa3OJWIEw==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-schema-to-ts": "^3.1.1" + }, + "bin": { + "anthropic-ai-sdk": "bin/cli" + }, + "peerDependencies": { + "zod": "^3.25.0 || ^4.0.0" + }, + "peerDependenciesMeta": { + "zod": { + "optional": true + } + } + }, + "node_modules/@babel/runtime": { + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.4.tgz", + "integrity": "sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@esbuild/aix-ppc64": { "version": "0.25.6", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.6.tgz", @@ -1001,9 +1033,9 @@ } }, "node_modules/@vscode/copilot-api": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/@vscode/copilot-api/-/copilot-api-0.1.13.tgz", - "integrity": "sha512-bVNAtC9y2nqF5LV7HpDd9BbuV81hstV+oIovo5MgJw1NWWNgeGpyBzcRJP0u6Dz6stRjka5UtEvC5dxqSWowyA==", + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/@vscode/copilot-api/-/copilot-api-0.2.2.tgz", + "integrity": "sha512-Q2aJR9FgXpVN/UO8WmGjY1o2fJavwPjDUP28H42WwocRAPtJlJXUpQ94Qg7ewu/fp21JnXJkDTlRL9Yg0RIlIQ==", "license": "SEE LICENSE" }, "node_modules/@vscode/l10n": { @@ -2564,6 +2596,20 @@ "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", "dev": true }, + "node_modules/json-schema-to-ts": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/json-schema-to-ts/-/json-schema-to-ts-3.1.1.tgz", + "integrity": "sha512-+DWg8jCJG2TEnpy7kOm/7/AxaYoaRbjVB4LFZLySZlWn8exGs3A4OLJR966cVvU26N7X9TWxl+Jsw7dzAqKT6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.18.3", + "ts-algebra": "^2.0.0" + }, + "engines": { + "node": ">=16" + } + }, "node_modules/jsonc-parser": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz", @@ -4008,6 +4054,13 @@ "node": ">=14.0.0" } }, + "node_modules/ts-algebra": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ts-algebra/-/ts-algebra-2.0.0.tgz", + "integrity": "sha512-FPAhNPFMrkwz76P7cdjdmiShwMynZYN6SgOujD1urY4oNm80Ou9oMdmbR45LotcKOXoy7wSmHkRFE6Mxbrhefw==", + "dev": true, + "license": "MIT" + }, "node_modules/tsx": { "version": "4.20.3", "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.20.3.tgz", diff --git a/chat-lib/package.json b/chat-lib/package.json index 3cc425c4d1..d5bf035da8 100644 --- a/chat-lib/package.json +++ b/chat-lib/package.json @@ -15,7 +15,7 @@ }, "dependencies": { "@microsoft/tiktokenizer": "^1.0.10", - "@vscode/copilot-api": "^0.1.13", + "@vscode/copilot-api": "^0.2.2", "@vscode/l10n": "^0.0.18", "@vscode/prompt-tsx": "^0.4.0-alpha.5", "jsonc-parser": "^3.3.1", @@ -24,6 +24,7 @@ "yaml": "^2.8.0" }, "devDependencies": { + "@anthropic-ai/sdk": "^0.68.0", "@octokit/types": "^14.1.0", "@types/node": "^22.16.3", "@types/vscode": "^1.102.0", diff --git a/package-lock.json b/package-lock.json index 3814b02fba..db268e5bbb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,11 +12,11 @@ "dependencies": { "@anthropic-ai/claude-code": "^1.0.120", "@anthropic-ai/sdk": "^0.68.0", - "@github/copilot": "^0.0.356", + "@github/copilot": "^0.0.358", "@google/genai": "^1.22.0", "@humanwhocodes/gitignore-to-minimatch": "1.0.2", "@microsoft/tiktokenizer": "^1.0.10", - "@vscode/copilot-api": "^0.2.0", + "@vscode/copilot-api": "^0.2.2", "@vscode/extension-telemetry": "^1.2.0", "@vscode/l10n": "^0.0.18", "@vscode/prompt-tsx": "^0.4.0-alpha.5", @@ -91,9 +91,9 @@ "eslint-plugin-jsdoc": "^51.3.4", "eslint-plugin-no-only-tests": "^3.3.0", "fastq": "^1.19.1", - "glob": "^11.0.3", + "glob": "^11.1.0", "husky": "^9.1.7", - "js-yaml": "^4.1.0", + "js-yaml": "^4.1.1", "keyv": "^5.3.2", "lint-staged": "15.2.9", "minimist": "^1.2.8", @@ -135,7 +135,7 @@ "engines": { "node": ">=22.14.0", "npm": ">=9.0.0", - "vscode": "^1.107.0" + "vscode": "^1.107.20251119" } }, "node_modules/@aashutoshrathi/word-wrap": { @@ -1429,6 +1429,7 @@ "integrity": "sha512-7cfaOQuCS27HD7DX+6ib2OrnW+b4ZBwDNnCcT0uTyidcmyWb03FnQqJybDBoCnpdxwBSfA94UAYlRCt7mV+TbA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@floating-ui/core": "^1.7.2", "@floating-ui/utils": "^0.2.10" @@ -3056,9 +3057,9 @@ } }, "node_modules/@github/copilot": { - "version": "0.0.356", - "resolved": "https://registry.npmjs.org/@github/copilot/-/copilot-0.0.356.tgz", - "integrity": "sha512-ZCRUXRM0bpSpAu3PbVFQY9go0mBLQNmGcv/SBKziGUQiL5ucpghNbhhCo7D/y2GA14rL5Wf0vcnrXrKF/vsnHQ==", + "version": "0.0.358", + "resolved": "https://registry.npmjs.org/@github/copilot/-/copilot-0.0.358.tgz", + "integrity": "sha512-Bo3B6wWL+jhwdLmQ4V1O9QzifQP+fEJCMxTjcan4MWHkzCc8qqf70krvIfrjFmbz624FYY6gHaLka8frXQNV5w==", "license": "SEE LICENSE IN LICENSE.md", "bin": { "copilot": "index.js" @@ -3924,6 +3925,7 @@ "version": "1.6.0", "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.6.0.tgz", "integrity": "sha512-OWlrQAnWn9577PhVgqjUvMr1pg57Bc4jv0iL4w0PRuOSRvq67rvHW9Ie/dZVMvCzhSCB+UxhcY/PmCmFj33Q+g==", + "peer": true, "engines": { "node": ">=8.0.0" } @@ -5562,6 +5564,7 @@ "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.44.tgz", "integrity": "sha512-Ye0nlw09GeMp2Suh8qoOv0odfgCoowfM/9MG6WeRD60Gq9wS90bdkdRtYbRkNhXOpG4H+YXGvj4wOWhAC0LJ1g==", "dev": true, + "peer": true, "dependencies": { "@types/prop-types": "*", "@types/scheduler": "*", @@ -5573,6 +5576,7 @@ "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.17.tgz", "integrity": "sha512-rvrT/M7Df5eykWFxn6MYt5Pem/Dbyc1N8Y0S9Mrkw2WFCRiqUgw9P7ul2NpwsXCSM1DVdENzdG9J5SreqfAIWg==", "dev": true, + "peer": true, "dependencies": { "@types/react": "*" } @@ -5747,6 +5751,7 @@ "integrity": "sha512-FuYgkHwZLuPbZjQHzJXrtXreJdFMKl16BFYyRrLxDhWr6Qr7Kbcu2s1Yhu8tsiMXw1S0W1pjfFfYEt+R604s+Q==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "8.36.0", "@typescript-eslint/types": "8.36.0", @@ -6422,9 +6427,9 @@ } }, "node_modules/@vscode/copilot-api": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/@vscode/copilot-api/-/copilot-api-0.2.0.tgz", - "integrity": "sha512-uVruOXmIqCn1H2zgtrbvgXUxKC2/Jfri8vjBOaMV60BfyjFZl4OPbNv81o5klw187PTgAQNYF2WBlY+vDz0q6A==", + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/@vscode/copilot-api/-/copilot-api-0.2.2.tgz", + "integrity": "sha512-Q2aJR9FgXpVN/UO8WmGjY1o2fJavwPjDUP28H42WwocRAPtJlJXUpQ94Qg7ewu/fp21JnXJkDTlRL9Yg0RIlIQ==", "license": "SEE LICENSE" }, "node_modules/@vscode/debugadapter": { @@ -6548,9 +6553,9 @@ } }, "node_modules/@vscode/test-cli/node_modules/glob": { - "version": "10.4.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", - "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", + "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", "dev": true, "license": "ISC", "dependencies": { @@ -6972,6 +6977,7 @@ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "license": "MIT", + "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -8910,6 +8916,7 @@ "resolved": "https://registry.npmjs.org/diagnostic-channel/-/diagnostic-channel-1.1.1.tgz", "integrity": "sha512-r2HV5qFkUICyoaKlBEpLKHjxMXATUf/l+h8UZPGBHGLy4DDiY2sOLcIctax4eRnTw5wH2jTMExLntGPJ8eOJxw==", "license": "MIT", + "peer": true, "dependencies": { "semver": "^7.5.3" } @@ -9155,7 +9162,8 @@ "resolved": "https://registry.npmjs.org/embla-carousel/-/embla-carousel-8.6.0.tgz", "integrity": "sha512-SjWyZBHJPbqxHOzckOfo8lHisEaJWmwd23XppYFYVh10bU66/Pn5tkVkbkCMZVdbUE5eTCI2nD8OyIP4Z+uwkA==", "dev": true, - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/embla-carousel-autoplay": { "version": "8.6.0", @@ -9513,6 +9521,7 @@ "integrity": "sha512-zmxXPNMOXmwm9E0yQLi5uqXHs7uq2UIiqEKo3Gq+3fwo1XrJ+hijAZImyF7hclW3E6oHz43Yk3RP8at6OTKflQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.12.1", @@ -9701,6 +9710,7 @@ "integrity": "sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@rtsao/scc": "^1.1.0", "array-includes": "^3.1.9", @@ -10586,15 +10596,15 @@ "dev": true }, "node_modules/glob": { - "version": "11.0.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-11.0.3.tgz", - "integrity": "sha512-2Nim7dha1KVkaiF4q6Dj+ngPPMdfvLJEOpZk/jKiUAkqKebpGAWQXAq9z1xu9HKu5lWfqw/FASuccEjyznjPaA==", + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-11.1.0.tgz", + "integrity": "sha512-vuNwKSaKiqm7g0THUBu2x7ckSs3XJLXE+2ssL7/MfTGPLLcrJQ/4Uq1CjPTtO5cCIiRxqvN6Twy1qOwhL0Xjcw==", "dev": true, - "license": "ISC", + "license": "BlueOak-1.0.0", "dependencies": { "foreground-child": "^3.3.1", "jackspeak": "^4.1.1", - "minimatch": "^10.0.3", + "minimatch": "^10.1.1", "minipass": "^7.1.2", "package-json-from-dist": "^1.0.0", "path-scurry": "^2.0.0" @@ -11086,6 +11096,19 @@ "url": "https://github.com/sponsors/typicode" } }, + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "license": "MIT", + "optional": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/ieee754": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", @@ -11894,10 +11917,11 @@ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" }, "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", "dev": true, + "license": "MIT", "dependencies": { "argparse": "^2.0.1" }, @@ -12132,6 +12156,7 @@ "integrity": "sha512-ypEvQvInNpUe+u+w8BIcPkQvEqXquyyibWE/1NB5T2BTzIpS5cGEV1LZskDzPSTvNAaT4+5FutvzlvnkxOSKlw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@keyv/serialize": "^1.0.3" } @@ -13185,10 +13210,10 @@ } }, "node_modules/minimatch": { - "version": "10.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.3.tgz", - "integrity": "sha512-IPZ167aShDZZUMdRk66cyQAW3qr0WzbHkPdMYa8bzZhlHhO3jALbKdxcaak7W9FfT2rZNpQuUu4Od7ILEpXSaw==", - "license": "ISC", + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.1.1.tgz", + "integrity": "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==", + "license": "BlueOak-1.0.0", "dependencies": { "@isaacs/brace-expansion": "^5.0.0" }, @@ -13375,6 +13400,7 @@ "integrity": "sha512-aChaVU/DO5aRPmk1GX8L+whocagUUpBQqoPtJk+cm7UOXUk87J4PeWCh6nNmTTIfEhiR9DI/+FnA8dln/hTK7g==", "dev": true, "license": "MIT", + "peer": true, "funding": { "type": "opencollective", "url": "https://opencollective.com/mobx" @@ -13412,6 +13438,7 @@ "integrity": "sha512-5EK+Cty6KheMS/YLPPMJC64g5V61gIR25KsRItHw6x4hEKT6Njp1n9LOlH4gpevuwMVS66SXaBBpg+RWZkza4A==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "browser-stdout": "^1.3.1", "chokidar": "^4.0.1", @@ -13529,9 +13556,9 @@ } }, "node_modules/mocha/node_modules/glob": { - "version": "10.4.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", - "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", + "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", "dev": true, "license": "ISC", "dependencies": { @@ -15271,6 +15298,7 @@ "version": "17.0.2", "resolved": "https://registry.npmjs.org/react/-/react-17.0.2.tgz", "integrity": "sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==", + "peer": true, "dependencies": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1" @@ -15284,6 +15312,7 @@ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz", "integrity": "sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==", "dev": true, + "peer": true, "dependencies": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1", @@ -15677,6 +15706,7 @@ "integrity": "sha512-3GuObel8h7Kqdjt0gxkEzaifHTqLVW56Y/bjN7PSQtkKr0w3V/QYSdt6QWYtd7A1xUtYQigtdUfgj1RvWVtorw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@types/estree": "1.0.8" }, @@ -15842,6 +15872,13 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "license": "MIT", + "optional": true + }, "node_modules/sax": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/sax/-/sax-1.3.0.tgz", @@ -15853,6 +15890,7 @@ "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz", "integrity": "sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==", "dev": true, + "peer": true, "dependencies": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1" @@ -16577,9 +16615,9 @@ } }, "node_modules/sqlite3/node_modules/glob": { - "version": "10.4.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", - "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", + "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", "dev": true, "license": "ISC", "optional": true, @@ -17526,9 +17564,9 @@ } }, "node_modules/tar/node_modules/glob": { - "version": "10.4.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", - "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", + "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", "dev": true, "license": "ISC", "dependencies": { @@ -17745,9 +17783,9 @@ } }, "node_modules/test-exclude/node_modules/glob": { - "version": "10.4.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", - "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", + "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", "dev": true, "license": "ISC", "dependencies": { @@ -18018,7 +18056,8 @@ "version": "2.8.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", - "license": "0BSD" + "license": "0BSD", + "peer": true }, "node_modules/tsscmp": { "version": "1.0.6", @@ -18036,6 +18075,7 @@ "integrity": "sha512-qjbnuR9Tr+FJOMBqJCW5ehvIo/buZq7vH7qD7JziU98h6l3qGy0a/yPFjwO+y0/T7GFpNgNAvEcPPVfyT8rrPQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "esbuild": "~0.25.0", "get-tsconfig": "^4.7.5" @@ -18228,6 +18268,7 @@ "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", "dev": true, "license": "Apache-2.0", + "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -18352,6 +18393,7 @@ "dev": true, "hasInstallScript": true, "license": "MIT", + "peer": true, "dependencies": { "napi-postinstall": "^0.2.4" }, @@ -18497,6 +18539,7 @@ "integrity": "sha512-ZWyE8YXEXqJrrSLvYgrRP7p62OziLW7xI5HYGWFzOvupfAlrLvURSzv/FyGyy0eidogEM3ujU+kUG1zuHgb6Ug==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.5.0", @@ -18651,6 +18694,7 @@ "integrity": "sha512-LUCP5ev3GURDysTWiP47wRRUpLKMOfPh+yKTx3kVIEiu5KOMeqzpnYNsKyOoVrULivR8tLcks4+lga33Whn90A==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@types/chai": "^5.2.2", "@vitest/expect": "3.2.4", @@ -19140,6 +19184,7 @@ "integrity": "sha512-4lLa/EcQCB0cJkyts+FpIRx5G/llPxfP6VQU5KByHEhLxY3IJCH0f0Hy1MHI8sClTvsIb8qwRJ6R/ZdlDJ/leQ==", "dev": true, "license": "ISC", + "peer": true, "bin": { "yaml": "bin.mjs" }, diff --git a/package.nls.json b/package.nls.json index b427150f0d..6eba3bfdfd 100644 --- a/package.nls.json +++ b/package.nls.json @@ -216,7 +216,7 @@ "copilot.listCodeUsages.tool.description": "Find references, definitions, and other usages of a symbol", "copilot.codebase.tool.description": "Find relevant file chunks, symbols, and other information in your codebase", "copilot.vscode.tool.description": "Use VS Code API references to answer questions about VS Code extension development.", - "copilot.testFailure.tool.description": "Includes information about the last unit test failure", + "copilot.testFailure.tool.description": "Include information about the last unit test failure", "copilot.vscode.sampleRequest": "What is the command to open the integrated terminal?", "copilot.vscode.api.description": "Ask about VS Code extension development", "copilot.vscode.api.sampleRequest": "How do I add text to the status bar?", @@ -234,6 +234,7 @@ "github.copilot.submenu.reviewComment.discardAndNext.label": "Discard and Go to Next", "github.copilot.submenu.reviewComment.discard.label": "Discard", "github.copilot.config.useProjectTemplates": "Use relevant GitHub projects as starter projects when using `/new`", + "github.copilot.config.agent.delegate.autoCommitAndPush": "When enabled, Copilot will automatically commit and push your pending changes before delegating work to the cloud agent.", "github.copilot.chat.attachFile": "Add File to Chat", "github.copilot.chat.attachSelection": "Add Selection to Chat", "github.copilot.command.collectDiagnostics": "Chat Diagnostics", @@ -294,9 +295,9 @@ "github.copilot.tools.openEmptyFolder.name": "Open an empty folder as VS Code workspace", "github.copilot.tools.getProjectSetupInfo.name": "Get Project Setup Info", "github.copilot.tools.searchResults.name": "Search View Results", - "github.copilot.tools.searchResults.description": "The results from the search view", + "github.copilot.tools.searchResults.description": "Get the results of the search view", "github.copilot.tools.githubRepo.name": "Search GitHub Repository", - "github.copilot.tools.githubRepo.userDescription": "Searches a GitHub repository for relevant source code snippets. You can specify a repository using `owner/repo`", + "github.copilot.tools.githubRepo.userDescription": "Search a GitHub repository for relevant source code snippets. You can specify a repository using `owner/repo`", "github.copilot.config.autoFix": "Automatically fix diagnostics for edited files.", "github.copilot.tools.createNewWorkspace.userDescription": "Scaffold a new workspace in VS Code", "copilot.tools.errors.description": "Check errors for a particular file", @@ -306,6 +307,7 @@ "copilot.tools.getDocInfo.description": "For a symbol like a class or function, find the information about how to document it", "copilot.tools.changes.description": "Get diffs of changed files", "copilot.tools.newJupyterNotebook.description": "Create a new Jupyter Notebook", + "copilot.tools.editNotebook.description": "Edit a notebook file in the workspace", "copilot.tools.runNotebookCell.description": "Trigger the execution of a cell in a notebook file", "copilot.tools.getNotebookCellOutput.description": "Read the output of a previously executed cell", "copilot.tools.fetchWebPage.description": "Fetch the main content from a web page. You should include the URL of the page you want to fetch.", @@ -344,12 +346,11 @@ "github.copilot.config.agent.currentEditorContext.enabled": "When enabled, Copilot will include the name of the current active editor in the context for agent mode.", "github.copilot.config.customInstructionsInSystemMessage": "When enabled, custom instructions and mode instructions will be appended to the system message instead of a user message.", "copilot.toolSet.editing.description": "Edit files in your workspace", - "copilot.toolSet.runCommand.description": "Run commands in the terminal", - "copilot.toolSet.runNotebook.description": "Run notebook cells", - "copilot.toolSet.search.description": "Search and read files in your workspace", - "copilot.toolSet.new.description": "Scaffold a new workspace with VS Code-specific configurations to compile, debug and run new projects.", - "copilot.toolSet.runTasks.description": "Run tasks in your workspace", + "copilot.toolSet.read.description": "Read files in your workspace", + "copilot.toolSet.search.description": "Search files in your workspace", + "copilot.toolSet.web.description": "Fetch information from the web", "github.copilot.config.useResponsesApi": "Use the Responses API instead of the Chat Completions API when supported. Enables reasoning and reasoning summaries.\n\n**Note**: This is an experimental feature that is not yet activated for all users.\n\n**Important**: URL API path resolution for custom OpenAI-compatible and Azure models is independent of this setting and fully determined by `url` property of `#github.copilot.chat.customOAIModels#` or `#github.copilot.chat.azureModels#` respectively.", + "github.copilot.config.useMessagesApi": "Use the Messages API instead of the Chat Completions API when supported. Enables thinking blocks and native Anthropic message format.\n\n**Note**: This is an experimental feature that is not yet activated for all users.", "github.copilot.config.responsesApiReasoningEffort": "Sets the reasoning effort used for the Responses API. Requires `#github.copilot.chat.useResponsesApi#`.", "github.copilot.config.responsesApiReasoningSummary": "Sets the reasoning summary style used for the Responses API. Requires `#github.copilot.chat.useResponsesApi#`.", "github.copilot.config.anthropic.thinking.enabled": "Enable extended thinking for Anthropic models that support it. \n\n **Note**: This is an experimental feature only supported in BYOK Anthropic models.", diff --git a/src/extension/agents/copilotcli/node/copilotCli.ts b/src/extension/agents/copilotcli/node/copilotCli.ts index dba840d83e..11f090a748 100644 --- a/src/extension/agents/copilotcli/node/copilotCli.ts +++ b/src/extension/agents/copilotcli/node/copilotCli.ts @@ -136,6 +136,7 @@ export class CopilotCLIModels implements ICopilotCLIModels { export interface ICopilotCLISDK { readonly _serviceBrand: undefined; getPackage(): Promise; + getAuthInfo(): Promise; } export class CopilotCLISDK implements ICopilotCLISDK { @@ -145,6 +146,7 @@ export class CopilotCLISDK implements ICopilotCLISDK { @IVSCodeExtensionContext private readonly extensionContext: IVSCodeExtensionContext, @IEnvService private readonly envService: IEnvService, @ILogService private readonly logService: ILogService, + @IAuthenticationService private readonly authentService: IAuthenticationService, ) { } public async getPackage(): Promise { @@ -164,13 +166,13 @@ export class CopilotCLISDK implements ICopilotCLISDK { ensureRipgrepShim(this.extensionContext.extensionPath, this.envService.appRoot, this.logService) ]); } -} -export async function getAuthInfo(authentService: IAuthenticationService): Promise { - const copilotToken = await authentService.getAnyGitHubSession(); - return { - type: 'token', - token: copilotToken?.accessToken ?? '', - host: 'https://github.com' - }; + public async getAuthInfo(): Promise { + const copilotToken = await this.authentService.getAnyGitHubSession(); + return { + type: 'token', + token: copilotToken?.accessToken ?? '', + host: 'https://github.com' + }; + } } diff --git a/src/extension/agents/copilotcli/node/copilotcliSession.ts b/src/extension/agents/copilotcli/node/copilotcliSession.ts index 074c65d689..861fe70788 100644 --- a/src/extension/agents/copilotcli/node/copilotcliSession.ts +++ b/src/extension/agents/copilotcli/node/copilotcliSession.ts @@ -5,7 +5,6 @@ import type { Attachment, Session } from '@github/copilot/sdk'; import type * as vscode from 'vscode'; -import { IAuthenticationService } from '../../../../platform/authentication/common/authentication'; import { IGitService } from '../../../../platform/git/common/gitService'; import { ILogService } from '../../../../platform/log/common/logService'; import { IWorkspaceService } from '../../../../platform/workspace/common/workspaceService'; @@ -19,7 +18,7 @@ import { IInstantiationService } from '../../../../util/vs/platform/instantiatio import { ChatRequestTurn2, ChatResponseThinkingProgressPart, ChatResponseTurn2, ChatSessionStatus, EventEmitter, Uri } from '../../../../vscodeTypes'; import { ExternalEditTracker } from '../../common/externalEditTracker'; import { buildChatHistoryFromEvents, getAffectedUrisForEditTool, isCopilotCliEditToolCall, processToolExecutionComplete, processToolExecutionStart, ToolCall, UnknownToolCall } from '../common/copilotCLITools'; -import { CopilotCLISessionOptions, getAuthInfo } from './copilotCli'; +import { CopilotCLISessionOptions, ICopilotCLISDK } from './copilotCli'; import { PermissionRequest, requiresFileEditconfirmation } from './permissionHelpers'; type PermissionHandler = ( @@ -80,7 +79,7 @@ export class CopilotCLISession extends DisposableStore implements ICopilotCLISes @IGitService private readonly gitService: IGitService, @ILogService private readonly logService: ILogService, @IWorkspaceService private readonly workspaceService: IWorkspaceService, - @IAuthenticationService private readonly authenticationService: IAuthenticationService, + @ICopilotCLISDK private readonly copilotCLISDK: ICopilotCLISDK, @IInstantiationService private readonly instantiationService: IInstantiationService ) { super(); @@ -146,7 +145,7 @@ export class CopilotCLISession extends DisposableStore implements ICopilotCLISes // Where possible try to avoid an extra call to getSelectedModel by using cached value. const [currentModel, authInfo] = await Promise.all([ modelId ? (this._lastUsedModel ?? raceCancellation(this._sdkSession.getSelectedModel(), token)) : undefined, - raceCancellation(getAuthInfo(this.authenticationService), token) + raceCancellation(this.copilotCLISDK.getAuthInfo(), token) ]); if (authInfo) { this._sdkSession.setAuthInfo(authInfo); diff --git a/src/extension/agents/copilotcli/node/copilotcliSessionService.ts b/src/extension/agents/copilotcli/node/copilotcliSessionService.ts index aa20e5c76d..79acc3c082 100644 --- a/src/extension/agents/copilotcli/node/copilotcliSessionService.ts +++ b/src/extension/agents/copilotcli/node/copilotcliSessionService.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import type { Session, SessionEvent, internal } from '@github/copilot/sdk'; +import type { Session, SessionEvent, SessionOptions, internal } from '@github/copilot/sdk'; import type { CancellationToken, ChatRequest } from 'vscode'; import { INativeEnvService } from '../../../../platform/env/common/envService'; import { IFileSystemService } from '../../../../platform/filesystem/common/fileSystemService'; @@ -27,7 +27,8 @@ import { ICopilotCLIMCPHandler } from './mcpHandler'; export interface ICopilotCLISessionItem { readonly id: string; readonly label: string; - readonly timestamp: Date; + readonly startTime: Date; + readonly endTime?: Date; readonly status?: ChatSessionStatus; } @@ -122,7 +123,8 @@ export class CopilotCLISessionService extends Disposable implements ICopilotCLIS return undefined; } const id = metadata.sessionId; - const timestamp = metadata.modifiedTime; + const startTime = metadata.startTime; + const endTime = metadata.modifiedTime; const label = metadata.summary ? labelFromPrompt(metadata.summary) : undefined; // CLI adds `` tags to user prompt, this needs to be removed. // However in summary CLI can end up truncating the prompt and adding `... { const mcpServers = await this.mcpHandler.loadMcpConfig(workingDirectory); - const options = new CopilotCLISessionOptions({ model, workingDirectory, isolationEnabled, mcpServers }, this.logService); + const options = await this.createSessionsOptions({ model, workingDirectory, isolationEnabled, mcpServers }); const sessionManager = await raceCancellationError(this.getSessionManager(), token); const sdkSession = await sessionManager.createSession(options.toSessionOptions()); const label = labelFromPrompt(prompt); const newSession: ICopilotCLISessionItem = { id: sdkSession.sessionId, label, - timestamp: sdkSession.startTime + startTime: sdkSession.startTime }; this._newActiveSessions.set(sdkSession.sessionId, newSession); this.logService.trace(`[CopilotCLISession] Created new CopilotCLI session ${sdkSession.sessionId}.`); @@ -199,6 +203,10 @@ export class CopilotCLISessionService extends Disposable implements ICopilotCLIS return session; } + protected async createSessionsOptions(options: { model?: string; isolationEnabled?: boolean; workingDirectory?: string; mcpServers?: SessionOptions['mcpServers'] }): Promise { + return new CopilotCLISessionOptions(options, this.logService); + } + public async getSession(sessionId: string, { model, workingDirectory, isolationEnabled, readonly }: { model?: string; workingDirectory?: string; isolationEnabled?: boolean; readonly: boolean }, token: CancellationToken): Promise { // https://github.com/microsoft/vscode/issues/276573 const lock = this.sessionMutexForGetSession.get(sessionId) ?? new Mutex(); @@ -223,7 +231,7 @@ export class CopilotCLISessionService extends Disposable implements ICopilotCLIS raceCancellationError(this.getSessionManager(), token), this.mcpHandler.loadMcpConfig(workingDirectory) ]); - const options = new CopilotCLISessionOptions({ model, workingDirectory, isolationEnabled, mcpServers }, this.logService); + const options = await this.createSessionsOptions({ model, workingDirectory, isolationEnabled, mcpServers }); const sdkSession = await sessionManager.getSession({ ...options.toSessionOptions(), sessionId }, !readonly); if (!sdkSession) { diff --git a/src/extension/agents/copilotcli/node/test/copilotCliSessionService.spec.ts b/src/extension/agents/copilotcli/node/test/copilotCliSessionService.spec.ts index fe2eaca65a..980714bc0d 100644 --- a/src/extension/agents/copilotcli/node/test/copilotCliSessionService.spec.ts +++ b/src/extension/agents/copilotcli/node/test/copilotCliSessionService.spec.ts @@ -87,7 +87,7 @@ describe('CopilotCLISessionService', () => { return fn(accessor, ...args); }, createInstance: (_ctor: unknown, options: any, sdkSession: any) => { - return disposables.add(new CopilotCLISession(options, sdkSession, gitService, logService, workspaceService, authService, instantiationService)); + return disposables.add(new CopilotCLISession(options, sdkSession, gitService, logService, workspaceService, sdk, instantiationService)); } } as unknown as IInstantiationService; diff --git a/src/extension/agents/copilotcli/node/test/copilotcliSession.spec.ts b/src/extension/agents/copilotcli/node/test/copilotcliSession.spec.ts index c201fa67f7..ad9baccdff 100644 --- a/src/extension/agents/copilotcli/node/test/copilotcliSession.spec.ts +++ b/src/extension/agents/copilotcli/node/test/copilotcliSession.spec.ts @@ -5,8 +5,6 @@ import type { Session, SessionOptions } from '@github/copilot/sdk'; import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; -import type { AuthenticationSession } from 'vscode'; -import { IAuthenticationService } from '../../../../../platform/authentication/common/authentication'; import { IGitService } from '../../../../../platform/git/common/gitService'; import { ILogService } from '../../../../../platform/log/common/logService'; import { TestWorkspaceService } from '../../../../../platform/test/node/testWorkspaceService'; @@ -20,7 +18,7 @@ import { ChatSessionStatus, Uri } from '../../../../../vscodeTypes'; import { createExtensionUnitTestingServices } from '../../../../test/node/services'; import { MockChatResponseStream } from '../../../../test/node/testHelpers'; import { ExternalEditTracker } from '../../../common/externalEditTracker'; -import { CopilotCLISessionOptions } from '../copilotCli'; +import { CopilotCLISessionOptions, ICopilotCLISDK } from '../copilotCli'; import { CopilotCLISession } from '../copilotcliSession'; import { PermissionRequest } from '../permissionHelpers'; @@ -81,20 +79,22 @@ describe('CopilotCLISession', () => { let logger: ILogService; let gitService: IGitService; let sessionOptions: CopilotCLISessionOptions; - let authService: IAuthenticationService; let instaService: IInstantiationService; + let sdk: ICopilotCLISDK; beforeEach(async () => { const services = disposables.add(createExtensionUnitTestingServices()); const accessor = services.createTestingAccessor(); logger = accessor.get(ILogService); gitService = accessor.get(IGitService); - authService = new class extends mock() { - override async getAnyGitHubSession() { + sdk = new class extends mock() { + override async getAuthInfo(): Promise { return { - accessToken: '', - } satisfies Partial as AuthenticationSession; + type: 'token', + token: '', + host: 'https://github.com' + }; } - }(); + }; sdkSession = new MockSdkSession(); workspaceService = createWorkspaceService('/workspace'); sessionOptions = new CopilotCLISessionOptions({ workingDirectory: workspaceService.getWorkspaceFolders()![0].fsPath }, logger); @@ -114,7 +114,7 @@ describe('CopilotCLISession', () => { gitService, logger, workspaceService, - authService, + sdk, instaService )); } diff --git a/src/extension/chatSessions/vscode-node/copilotCLIChatSessionsContribution.ts b/src/extension/chatSessions/vscode-node/copilotCLIChatSessionsContribution.ts index 5116da5a1f..b8d8b2d46a 100644 --- a/src/extension/chatSessions/vscode-node/copilotCLIChatSessionsContribution.ts +++ b/src/extension/chatSessions/vscode-node/copilotCLIChatSessionsContribution.ts @@ -42,19 +42,24 @@ export class CopilotCLIWorktreeManager { private _sessionIsolation: Map = new Map(); private _sessionWorktrees: Map = new Map(); constructor( - @IVSCodeExtensionContext private readonly extensionContext: IVSCodeExtensionContext, - @IRunCommandExecutionService private readonly commandExecutionService: IRunCommandExecutionService) { } + @IGitService private readonly gitService: IGitService, + @IVSCodeExtensionContext private readonly extensionContext: IVSCodeExtensionContext) { } async createWorktree(stream: vscode.ChatResponseStream): Promise { return new Promise((resolve) => { stream.progress(vscode.l10n.t('Creating isolated worktree for Copilot CLI session...'), async progress => { try { - const worktreePath = await this.commandExecutionService.executeCommand('git.createWorktreeWithDefaults') as string | undefined; - if (worktreePath) { - resolve(worktreePath); - return vscode.l10n.t('Created isolated worktree at {0}', worktreePath); - } else { + const repository = this.gitService.activeRepository.get(); + if (!repository) { progress.report(new vscode.ChatResponseWarningPart(vscode.l10n.t('Failed to create worktree for isolation, using default workspace directory'))); + } else { + const worktreePath = await this.gitService.createWorktree(repository.rootUri); + if (worktreePath) { + resolve(worktreePath); + return vscode.l10n.t('Created isolated worktree at {0}', worktreePath); + } else { + progress.report(new vscode.ChatResponseWarningPart(vscode.l10n.t('Failed to create worktree for isolation, using default workspace directory'))); + } } } catch (error) { progress.report(new vscode.ChatResponseWarningPart(vscode.l10n.t('Error creating worktree for isolation: {0}', error instanceof Error ? error.message : String(error)))); @@ -173,7 +178,7 @@ export class CopilotCLIChatSessionItemProvider extends Disposable implements vsc return diskSessions; } - private async _toChatSessionItem(session: { id: string; label: string; timestamp: Date; status?: vscode.ChatSessionStatus }): Promise { + private async _toChatSessionItem(session: { id: string; label: string; startTime: Date; endTime?: Date; status?: vscode.ChatSessionStatus }): Promise { const resource = SessionIdForCLI.getResource(session.id); const worktreePath = this.worktreeManager.getWorktreePath(session.id); const worktreeRelativePath = this.worktreeManager.getWorktreeRelativePath(session.id); @@ -201,7 +206,7 @@ export class CopilotCLIChatSessionItemProvider extends Disposable implements vsc label, description, tooltip: tooltipLines.join('\n'), - timing: { startTime: session.timestamp.getTime() }, + timing: { startTime: session.startTime.getTime(), endTime: session.endTime?.getTime() }, statistics, status } satisfies vscode.ChatSessionItem; @@ -473,16 +478,13 @@ export class CopilotCLIChatSessionParticipant extends Disposable { stream.warning(vscode.l10n.t('You have uncommitted changes in your workspace. The cloud agent will start from the last committed state. Consider committing your changes first if you want to include them.')); } - const history = await this.summarizer.provideChatSummary(context, token); const prompt = request.prompt.substring('/delegate'.length).trim(); if (!await this.cloudSessionProvider.tryHandleUncommittedChanges({ prompt: prompt, - history: history, chatContext: context }, stream, token)) { const prInfo = await this.cloudSessionProvider.createDelegatedChatSession({ prompt, - history, chatContext: context }, stream, token); if (prInfo) { @@ -513,7 +515,8 @@ export class CopilotCLIChatSessionParticipant extends Disposable { const prInfo = await this.cloudSessionProvider?.createDelegatedChatSession({ prompt: uncommittedChangesData.metadata.prompt, - history: uncommittedChangesData.metadata.history, + references: uncommittedChangesData.metadata.references, + autoPushAndCommit: uncommittedChangesData.metadata.autoPushAndCommit, chatContext: context }, stream, token); if (prInfo) { @@ -528,7 +531,7 @@ export class CopilotCLIChatSessionParticipant extends Disposable { token: vscode.CancellationToken ): Promise { const prompt = request.prompt; - const history = context.chatSummary?.history ?? await this.summarizer.provideChatSummary(context, token); + const history = await this.summarizer.provideChatSummary(context, token); const requestPrompt = history ? `${prompt}\n**Summary**\n${history}` : prompt; const session = await this.sessionService.createSession(requestPrompt, {}, token); @@ -588,7 +591,11 @@ export function registerCLIChatCommands(copilotcliSessionItemProvider: CopilotCL if (worktreePath) { try { - await vscode.commands.executeCommand('git.deleteWorktree', Uri.file(worktreePath)); + const repository = gitService.activeRepository.get(); + if (!repository) { + throw new Error(vscode.l10n.t('No active repository found to delete worktree.')); + } + await gitService.deleteWorktree(repository.rootUri, worktreePath); } catch (error) { vscode.window.showErrorMessage(vscode.l10n.t('Failed to delete worktree: {0}', error instanceof Error ? error.message : String(error))); } diff --git a/src/extension/chatSessions/vscode-node/copilotCloudGitOperationsManager.ts b/src/extension/chatSessions/vscode-node/copilotCloudGitOperationsManager.ts new file mode 100644 index 0000000000..7f65581036 --- /dev/null +++ b/src/extension/chatSessions/vscode-node/copilotCloudGitOperationsManager.ts @@ -0,0 +1,158 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as vscode from 'vscode'; +import { Repository } from '../../../platform/git/vscode/git'; +import { ILogService } from '../../../platform/log/common/logService'; + +export interface GitRepoInfo { + repository: Repository; + remoteName: string; + baseRef: string; +} + +export class CopilotCloudGitOperationsManager { + constructor(private readonly logService: ILogService) { } + + async commitAndPushChanges(repoInfo: GitRepoInfo): Promise { + const { repository, remoteName, baseRef } = repoInfo; + const asyncBranch = await this.generateRandomBranchName(repository, 'copilot'); + + const commitMessage = vscode.l10n.t('Checkpoint from VS Code for cloud agent session'); + try { + await repository.createBranch(asyncBranch, true); + await this.performCommit(asyncBranch, repository, commitMessage); + await repository.push(remoteName, asyncBranch, true); + this.showBranchSwitchNotification(repository, baseRef, asyncBranch); + return asyncBranch; + } catch (error) { + await this.rollbackToOriginalBranch(repository, baseRef); + this.logService.error(`Failed to automatically commit and push your changes: ${error instanceof Error ? error.message : String(error)}`); + throw new Error(vscode.l10n.t('Failed to automatically commit and push your changes. Please commit or stash your changes manually and try again.')); + } + } + + private async performCommit(asyncBranch: string, repository: Repository, commitMessage: string): Promise { + try { + await repository.commit(commitMessage, { all: true }); + if (repository.state.HEAD?.name !== asyncBranch || repository.state.workingTreeChanges.length > 0 || repository.state.indexChanges.length > 0) { + throw new Error(vscode.l10n.t('Uncommitted changes still detected.')); + } + } catch (error) { + const commitSuccessful = await this.handleInteractiveCommit(repository); + if (!commitSuccessful) { + throw new Error(vscode.l10n.t('Failed to commit changes. Please commit or stash your changes manually before using the cloud agent.')); + } + } + } + + private async handleInteractiveCommit(repository: Repository): Promise { + const COMMIT_YOUR_CHANGES = vscode.l10n.t('Commit your changes to continue cloud agent session. Close integrated terminal to cancel.'); + return vscode.window.withProgress({ + title: COMMIT_YOUR_CHANGES, + cancellable: true, + location: vscode.ProgressLocation.Notification + }, async (_, token) => { + return new Promise((resolve) => { + const startingCommit = repository.state.HEAD?.commit; + const terminal = vscode.window.createTerminal({ + name: 'GitHub Copilot Cloud Agent', + cwd: repository.rootUri.fsPath, + message: `\x1b[1m${COMMIT_YOUR_CHANGES}\x1b[0m` + }); + + terminal.show(); + + let disposed = false; + let timeoutId: TimeoutHandle | undefined = undefined; + let stateListener: vscode.Disposable | undefined = undefined; + let disposalListener: vscode.Disposable | undefined = undefined; + let cancellationListener: vscode.Disposable | undefined = undefined; + const cleanup = () => { + if (disposed) { + return; + } + disposed = true; + clearTimeout(timeoutId); + stateListener?.dispose(); + disposalListener?.dispose(); + cancellationListener?.dispose(); + terminal.dispose(); + }; + + if (token) { + cancellationListener = token.onCancellationRequested(() => { + cleanup(); + resolve(false); + }); + } + + stateListener = repository.state.onDidChange(() => { + if (repository.state.HEAD?.commit !== startingCommit) { + cleanup(); + resolve(true); + } + }); + + timeoutId = setTimeout(() => { + cleanup(); + resolve(false); + }, 5 * 60 * 1000); + + disposalListener = vscode.window.onDidCloseTerminal((closedTerminal) => { + if (closedTerminal === terminal) { + setTimeout(() => { + if (!disposed) { + cleanup(); + resolve(repository.state.HEAD?.commit !== startingCommit); + } + }, 1000); + } + }); + }); + }); + } + + private showBranchSwitchNotification(repository: Repository, baseRef: string, newRef: string): void { + if (repository.state.HEAD?.name !== baseRef) { + const SWAP_BACK_TO_ORIGINAL_BRANCH = vscode.l10n.t('Swap back to \'{0}\'', baseRef); + vscode.window.showInformationMessage( + vscode.l10n.t('Pending changes pushed to remote branch \'{0}\'.', newRef), + SWAP_BACK_TO_ORIGINAL_BRANCH, + ).then(async (selection) => { + if (selection === SWAP_BACK_TO_ORIGINAL_BRANCH) { + await repository.checkout(baseRef); + } + }); + } + } + + private async rollbackToOriginalBranch(repository: Repository, baseRef: string): Promise { + if (repository.state.HEAD?.name !== baseRef) { + try { + await repository.checkout(baseRef); + } catch (error) { + this.logService.error(`Failed to checkout back to original branch '${baseRef}': ${error instanceof Error ? error.message : String(error)}`); + } + } + } + + private async generateRandomBranchName(repository: Repository, prefix: string): Promise { + for (let index = 0; index < 5; index++) { + const randomName = `${prefix}/vscode-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 6)}`; + try { + const refs = await repository.getRefs({ pattern: `refs/heads/${randomName}` }); + if (!refs || refs.length === 0) { + return randomName; + } + } catch (error) { + this.logService.warn(`Failed to check refs for ${randomName}: ${error instanceof Error ? error.message : String(error)}`); + return randomName; + } + } + + return `${prefix}/vscode-${Date.now().toString(36)}`; + } +} diff --git a/src/extension/chatSessions/vscode-node/copilotCloudSessionsProvider.ts b/src/extension/chatSessions/vscode-node/copilotCloudSessionsProvider.ts index 0f2316ac28..a6edcd6bb8 100644 --- a/src/extension/chatSessions/vscode-node/copilotCloudSessionsProvider.ts +++ b/src/extension/chatSessions/vscode-node/copilotCloudSessionsProvider.ts @@ -9,6 +9,7 @@ import * as vscode from 'vscode'; import { Uri } from 'vscode'; import { IAuthenticationService } from '../../../platform/authentication/common/authentication'; import { IAuthenticationChatUpgradeService } from '../../../platform/authentication/common/authenticationUpgrade'; +import { ConfigKey, IConfigurationService } from '../../../platform/configuration/common/configurationService'; import { IGitExtensionService } from '../../../platform/git/common/gitExtensionService'; import { IGitService } from '../../../platform/git/common/gitService'; import { PullRequestSearchItem, SessionInfo } from '../../../platform/github/common/githubAPI'; @@ -17,7 +18,10 @@ import { ILogService } from '../../../platform/log/common/logService'; import { ITelemetryService } from '../../../platform/telemetry/common/telemetry'; import { Disposable, toDisposable } from '../../../util/vs/base/common/lifecycle'; import { ResourceMap } from '../../../util/vs/base/common/map'; +import { IInstantiationService } from '../../../util/vs/platform/instantiation/common/instantiation'; +import { ChatSummarizerProvider } from '../../prompt/node/summarizer'; import { body_suffix, CONTINUE_TRUNCATION, extractTitle, formatBodyPlaceholder, getAuthorDisplayName, getRepoId, JOBS_API_VERSION, RemoteAgentResult, SessionIdForPr, toOpenPullRequestWebviewUri, truncatePrompt } from '../vscode/copilotCodingAgentUtils'; +import { CopilotCloudGitOperationsManager } from './copilotCloudGitOperationsManager'; import { ChatSessionContentBuilder } from './copilotCloudSessionContentBuilder'; import { IPullRequestFileChangesService } from './pullRequestFileChangesService'; @@ -26,9 +30,9 @@ export const UncommittedChangesStep = 'uncommitted-changes'; interface ConfirmationMetadata { prompt: string; - history?: string; references?: readonly vscode.ChatPromptReference[]; chatContext: vscode.ChatContext; + autoPushAndCommit?: boolean; } export interface PullRequestInfo { @@ -145,6 +149,8 @@ export class CopilotCloudSessionsProvider extends Disposable implements vscode.C ); private cachedSessionsSize: number = 0; private readonly plainTextRenderer = new PlainTextRenderer(); + private readonly gitOperationsManager = new CopilotCloudGitOperationsManager(this.logService); + private readonly _summarizer: ChatSummarizerProvider; constructor( @IOctoKitService private readonly _octoKitService: IOctoKitService, @@ -155,8 +161,11 @@ export class CopilotCloudSessionsProvider extends Disposable implements vscode.C @IPullRequestFileChangesService private readonly _prFileChangesService: IPullRequestFileChangesService, @IAuthenticationService private readonly _authenticationService: IAuthenticationService, @IAuthenticationChatUpgradeService private readonly _authenticationUpgradeService: IAuthenticationChatUpgradeService, + @IConfigurationService private readonly configurationService: IConfigurationService, + @IInstantiationService instantiationService: IInstantiationService, ) { super(); + this._summarizer = instantiationService.createInstance(ChatSummarizerProvider); const interval = setInterval(async () => { const repoId = await getRepoId(this._gitService); if (repoId) { @@ -180,6 +189,10 @@ export class CopilotCloudSessionsProvider extends Disposable implements vscode.C this._onDidChangeChatSessionItems.fire(); } + private get autoCommitAndPushEnabled(): boolean { + return this.configurationService.getConfig(ConfigKey.AgentDelegateAutoCommitAndPush); + } + async provideChatSessionProviderOptions(token: vscode.CancellationToken): Promise { const repoId = await getRepoId(this._gitService); if (!repoId) { @@ -583,7 +596,7 @@ export class CopilotCloudSessionsProvider extends Disposable implements vscode.C return state === 'MERGED' ? '$(git-merge)' : '$(git-pull-request)'; } - private async startSession(stream: vscode.ChatResponseStream, token: vscode.CancellationToken, source: string, prompt: string, history?: string, references?: readonly vscode.ChatPromptReference[], customAgentName?: string) { + private async startSession(stream: vscode.ChatResponseStream, token: vscode.CancellationToken, source: string, prompt: string, history?: string, references?: readonly vscode.ChatPromptReference[], customAgentName?: string, autoPushAndCommit?: boolean) { /* __GDPR__ "copilot.codingAgent.editor.invoke" : { "promptLength" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, @@ -605,7 +618,7 @@ export class CopilotCloudSessionsProvider extends Disposable implements vscode.C history ].join('\n\n').trim(), token, - false, + autoPushAndCommit ?? false, stream, customAgentName, ); @@ -633,10 +646,10 @@ export class CopilotCloudSessionsProvider extends Disposable implements vscode.C stream.markdown(vscode.l10n.t('Cloud agent request cancelled.')); return {}; } - if (!await this.tryHandleUncommittedChanges(data.metadata, stream, token)) { + if (!await this.tryHandleUncommittedChanges({ ...data.metadata, chatContext: context }, stream, token)) { // We are NOT handling an uncommitted changes case, so no confirmation was pushed. // This means we (the caller) should continue processing the request. - await this.createDelegatedChatSession(data.metadata, stream, token); + await this.createDelegatedChatSession({ ...data.metadata, chatContext: context }, stream, token); } break; } @@ -648,9 +661,9 @@ export class CopilotCloudSessionsProvider extends Disposable implements vscode.C } if (data.metadata.chatContext?.chatSessionContext?.isUntitled) { - await this.doUntitledCreation(data.metadata, stream, token); + await this.doUntitledCreation({ ...data.metadata, chatContext: context }, stream, token); } else { - await this.createDelegatedChatSession(data.metadata, stream, token); + await this.createDelegatedChatSession({ ...data.metadata, chatContext: context }, stream, token); } break; } @@ -662,9 +675,27 @@ export class CopilotCloudSessionsProvider extends Disposable implements vscode.C return {}; } + private hasHistoryToSummarize(history: readonly (vscode.ChatRequestTurn | vscode.ChatResponseTurn)[]): boolean { + if (!history || history.length === 0) { + return false; + } + const allResponsesEmpty = history.every(turn => { + if (turn instanceof vscode.ChatResponseTurn) { + return turn.response.length === 0; + } + return true; + }); + return !allResponsesEmpty; + } + async createDelegatedChatSession(metadata: ConfirmationMetadata, stream: vscode.ChatResponseStream, token: vscode.CancellationToken): Promise { - const { prompt, history, references } = metadata; - const number = await this.startSession(stream, token, 'chat', prompt, history, references); + const { prompt, references } = metadata; + let history: string | undefined; + if (this.hasHistoryToSummarize(metadata.chatContext.history)) { + stream.progress(vscode.l10n.t('Analyzing chat history')); + history = await this._summarizer.provideChatSummary(metadata.chatContext, token); + } + const number = await this.startSession(stream, token, 'chat', prompt, history, references, undefined, metadata.autoPushAndCommit); if (!number) { return undefined; } @@ -724,7 +755,7 @@ export class CopilotCloudSessionsProvider extends Disposable implements vscode.C // Check for uncommitted changes and prompt user if checking is enabled const hasChanges = repo.state.workingTreeChanges.length > 0 || repo.state.indexChanges.length > 0; - if (hasChanges) { + if (hasChanges && !this.autoCommitAndPushEnabled) { this.logService.warn('Uncommitted changes detected, prompting user for confirmation.'); stream.confirmation( vscode.l10n.t('Uncommitted changes detected'), @@ -737,6 +768,38 @@ export class CopilotCloudSessionsProvider extends Disposable implements vscode.C ); return true; // A confirmation was pushed, meaning a new request will be sent to handleConfirmationData(). The caller should STOP processing. } + + if (hasChanges) { + const repoName = `${repoId.org}/${repoId.repo}`; + const message = vscode.l10n.t('Copilot cloud agent will continue your work in \'{0}\'.', repoName); + const detail = vscode.l10n.t('Choose how to handle your uncommitted changes before delegating to the cloud agent.'); + const push_changes = vscode.l10n.t('Push changes'); + const learn_more = vscode.l10n.t('Learn more'); + const continue_without_pushing = vscode.l10n.t('Continue without pushing'); + const modalResult = await vscode.window.showInformationMessage( + message, + { + modal: true, + detail, + }, + push_changes, + continue_without_pushing, + learn_more, + ); + + if (!modalResult) { + stream.markdown(vscode.l10n.t('Cloud agent request cancelled due to uncommitted changes.')); + return true; + } + + if (modalResult === learn_more) { + await vscode.env.openExternal(vscode.Uri.parse('https://aka.ms/coding-agent-docs')); + return true; + } + + metadata.autoPushAndCommit = modalResult === push_changes; + return false; + } } catch (error) { this.logService.warn(`Skipping detection of uncommitted changes due to error: ${error}`); } @@ -754,9 +817,10 @@ export class CopilotCloudSessionsProvider extends Disposable implements vscode.C token, 'untitledChatSession', metadata.prompt, - metadata.history, + undefined, metadata.references, selectedAgent, + metadata.autoPushAndCommit, ); if (!number) { return {}; @@ -824,8 +888,8 @@ export class CopilotCloudSessionsProvider extends Disposable implements vscode.C /* Generate new cloud agent session from an 'untitled' session */ const handledUncommittedChanges = await this.tryHandleUncommittedChanges({ - prompt: context.chatSummary?.prompt ?? request.prompt, - history: context.chatSummary?.history, + prompt: request.prompt, + references: request.references, chatContext: context }, stream, token); @@ -835,10 +899,10 @@ export class CopilotCloudSessionsProvider extends Disposable implements vscode.C return {}; } + const { prompt, references } = request; await this.doUntitledCreation({ - prompt: context.chatSummary?.prompt ?? request.prompt, - history: context.chatSummary?.history, - references: request.references, + prompt, + references, chatContext: context, }, stream, token); @@ -911,8 +975,7 @@ export class CopilotCloudSessionsProvider extends Disposable implements vscode.C { step: 'create', metadata: { - prompt: context.chatSummary?.prompt ?? request.prompt, - history: context.chatSummary?.history, + prompt: request.prompt, references: request.references, chatContext: context, } satisfies ConfirmationMetadata @@ -1337,13 +1400,32 @@ export class CopilotCloudSessionsProvider extends Disposable implements vscode.C if (!base_ref) { return { error: vscode.l10n.t('Unable to determine the current branch.'), state: 'error' }; } - let head_ref: string | undefined; // TODO: UNUSED! This is the ref cloud agent starts work from (omitted unless we push local changes) + let head_ref: string | undefined; - // TODO: Make this automatic instead of a fatal error. const remoteName = - repo?.state.HEAD?.upstream?.remote ?? + repo.state.HEAD?.upstream?.remote ?? currentRepository?.upstreamRemote ?? - repo?.state.remotes?.[0]?.name; + repo.state.remotes?.[0]?.name; + + const hasChanges = repo.state.workingTreeChanges.length > 0 || repo.state.indexChanges.length > 0; + if (hasChanges && autoPushAndCommit) { + if (!remoteName) { + return { + error: vscode.l10n.t('Unable to determine a Git remote for this repository. Configure an upstream remote and try again.'), + state: 'error' + }; + } + try { + chatStream?.progress(vscode.l10n.t('Committing and pushing local changes')); + head_ref = await this.gitOperationsManager.commitAndPushChanges({ repository: repo, remoteName, baseRef: base_ref }); + } catch (error) { + return { + error: vscode.l10n.t('Failed to commit and push changes: {0}. Please commit or stash your changes manually and try again.', error instanceof Error ? error.message : String(error)), + innerError: error instanceof Error ? error.message : String(error), + state: 'error' + }; + } + } if (repo && remoteName && base_ref) { try { @@ -1371,11 +1453,16 @@ export class CopilotCloudSessionsProvider extends Disposable implements vscode.C }); if (!hasRemoteBranch) { - this.logService.warn(`Base branch '${expectedRemoteBranch}' not found on remote.`); - return { - error: vscode.l10n.t('The branch \'{0}\' does not exist on remote \'{1}\'. Please push the branch and try again.', base_ref, remoteName), - state: 'error' - }; + if (this.autoCommitAndPushEnabled) { + this.logService.warn(`Base branch '${expectedRemoteBranch}' not found on remote. Auto-pushing because autoCommitAndPush is enabled.`); + await repo.push(remoteName, base_ref, true); + } else { + this.logService.warn(`Base branch '${expectedRemoteBranch}' not found on remote.`); + return { + error: vscode.l10n.t('The branch \'{0}\' does not exist on remote \'{1}\'. Please push the branch and try again.', base_ref, remoteName), + state: 'error' + }; + } } } catch (error) { this.logService.error(`Failed to verify remote branch for cloud agent: ${error instanceof Error ? error.message : String(error)}`); diff --git a/src/extension/chatSessions/vscode-node/test/copilotCLIChatSessionParticipant.spec.ts b/src/extension/chatSessions/vscode-node/test/copilotCLIChatSessionParticipant.spec.ts index cf8196daba..d0f30d88df 100644 --- a/src/extension/chatSessions/vscode-node/test/copilotCLIChatSessionParticipant.spec.ts +++ b/src/extension/chatSessions/vscode-node/test/copilotCLIChatSessionParticipant.spec.ts @@ -6,7 +6,6 @@ import { Attachment } from '@github/copilot/sdk'; import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; import * as vscode from 'vscode'; -import { IAuthenticationService } from '../../../../platform/authentication/common/authentication'; import { MockRunCommandExecutionService } from '../../../../platform/commands/common/mockRunCommandExecutionService'; import { IRunCommandExecutionService } from '../../../../platform/commands/common/runCommandExecutionService'; import { NullNativeEnvService } from '../../../../platform/env/common/nullEnvService'; @@ -82,7 +81,6 @@ function createChatContext(sessionId: string, isUntitled: boolean): vscode.ChatC chatSessionItem: { resource: vscode.Uri.from({ scheme: 'copilotcli', path: `/${sessionId}` }), label: 'temp' } as vscode.ChatSessionItem, isUntitled } as vscode.ChatSessionContext, - chatSummary: undefined } as vscode.ChatContext; } @@ -141,7 +139,6 @@ describe('CopilotCLIChatSessionParticipant.handleRequest', () => { tools = new class FakeToolsService extends mock() { }(); workspaceService = new NullWorkspaceService(); commandExecutionService = new MockRunCommandExecutionService(); - const authService = new class extends mock() { }(); const logService = accessor.get(ILogService); const gitService = accessor.get(IGitService); mcpHandler = new class extends mock() { @@ -154,7 +151,7 @@ describe('CopilotCLIChatSessionParticipant.handleRequest', () => { return fn(accessor, ...args); }, createInstance: (_ctor: unknown, options: any, sdkSession: any) => { - const session = new TestCopilotCLISession(options, sdkSession, gitService, logService, workspaceService, authService, instantiationService); + const session = new TestCopilotCLISession(options, sdkSession, gitService, logService, workspaceService, sdk, instantiationService); cliSessions.push(session); return disposables.add(session); } @@ -295,23 +292,6 @@ describe('CopilotCLIChatSessionParticipant.handleRequest', () => { expect(String(execSpy.mock.calls[0].at(1))).toContain(`copilotcli:/${sessionId}`); expect(execSpy.mock.calls[1]).toEqual(['workbench.action.chat.submit', { inputValue: expectedPrompt }]); }); - it('invokes handlePushConfirmationData using existing chatSummary and skips summarizer', async () => { - const request = new TestChatRequest('Push that'); - const context = { chatSessionContext: undefined, chatSummary: { history: 'precomputed history' } } as unknown as vscode.ChatContext; - const stream = new MockChatResponseStream(); - const token = disposables.add(new CancellationTokenSource()).token; - const summarySpy = vi.spyOn(summarizer, 'provideChatSummary'); - const execSpy = vi.spyOn(commandExecutionService, 'executeCommand'); - - await participant.createHandler()(request, context, stream, token); - - expect(manager.sessions.size).toBe(1); - const expectedPrompt = 'Push that\n**Summary**\nprecomputed history'; - expect(summarySpy).not.toHaveBeenCalled(); - expect(execSpy).toHaveBeenCalledTimes(2); - expect(execSpy.mock.calls[0].at(0)).toBe('vscode.open'); - expect(execSpy.mock.calls[1]).toEqual(['workbench.action.chat.submit', { inputValue: expectedPrompt }]); - }); it('handleConfirmationData accepts uncommitted-changes and records push', async () => { // Existing session (non-untitled) so confirmation path is hit @@ -319,7 +299,7 @@ describe('CopilotCLIChatSessionParticipant.handleRequest', () => { const sdkSession = new MockCliSdkSession(sessionId, new Date()); manager.sessions.set(sessionId, sdkSession); const request = new TestChatRequest('Apply'); - (request as any).acceptedConfirmationData = [{ step: 'uncommitted-changes', metadata: { prompt: 'delegate work', history: 'hist' } }]; + (request as any).acceptedConfirmationData = [{ step: 'uncommitted-changes', metadata: { prompt: 'delegate work' } }]; const context = createChatContext(sessionId, false); const stream = new MockChatResponseStream(); const token = disposables.add(new CancellationTokenSource()).token; @@ -336,7 +316,7 @@ describe('CopilotCLIChatSessionParticipant.handleRequest', () => { expect(sdkSession.emittedEvents[1].event).toBe('assistant.message'); expect(sdkSession.emittedEvents[1].content).toContain('pr://2'); // Cloud provider used with provided metadata - expect(cloudProvider.createDelegatedChatSession).toHaveBeenCalledWith({ prompt: 'delegate work', history: 'hist', chatContext: context }, expect.anything(), token); + expect(cloudProvider.createDelegatedChatSession).toHaveBeenCalledWith({ prompt: 'delegate work', chatContext: context }, expect.anything(), token); }); it('handleConfirmationData cancels when uncommitted-changes rejected', async () => { diff --git a/src/extension/intents/node/agentIntent.ts b/src/extension/intents/node/agentIntent.ts index 854715c599..f3213344b0 100644 --- a/src/extension/intents/node/agentIntent.ts +++ b/src/extension/intents/node/agentIntent.ts @@ -90,7 +90,7 @@ export const getAgentTools = (instaService: IInstantiationService, request: vsco } } - allowTools[ToolName.RunTests] = await testService.hasAnyTests(); + allowTools[ToolName.CoreRunTest] = await testService.hasAnyTests(); allowTools[ToolName.CoreRunTask] = tasksService.getTasks().length > 0; if (model.family === 'gpt-5-codex' || model.family.includes('grok-code')) { diff --git a/src/extension/prompt/node/test/repoInfoTelemetry.spec.ts b/src/extension/prompt/node/test/repoInfoTelemetry.spec.ts index 5ac3a22d78..695004fb96 100644 --- a/src/extension/prompt/node/test/repoInfoTelemetry.spec.ts +++ b/src/extension/prompt/node/test/repoInfoTelemetry.spec.ts @@ -86,6 +86,8 @@ suite('RepoInfoTelemetry', () => { fetch: vi.fn(), getMergeBase: vi.fn(), add: vi.fn(), + createWorktree: vi.fn(), + deleteWorktree: vi.fn(), dispose: vi.fn() }; services.define(IGitService, mockGitService); diff --git a/src/extension/prompts/node/agent/openai/gpt51CodexPrompt.tsx b/src/extension/prompts/node/agent/openai/gpt51CodexPrompt.tsx index ff0760d677..4bfe58a37b 100644 --- a/src/extension/prompts/node/agent/openai/gpt51CodexPrompt.tsx +++ b/src/extension/prompts/node/agent/openai/gpt51CodexPrompt.tsx @@ -34,7 +34,7 @@ class Gpt51CodexPrompt extends PromptElement { - You have access to many tools. If a tool exists to perform a specific task, you MUST use that tool instead of running a terminal command to perform that task.
- {tools[ToolName.RunTests] && <>- Use the {ToolName.RunTests} tool to run tests instead of running terminal commands.
} + {tools[ToolName.CoreRunTest] && <>- Use the {ToolName.CoreRunTest} tool to run tests instead of running terminal commands.
} {tools[ToolName.CoreManageTodoList] && <>
## {ToolName.CoreManageTodoList} tool
diff --git a/src/extension/prompts/node/agent/openai/gpt51Prompt.tsx b/src/extension/prompts/node/agent/openai/gpt51Prompt.tsx index 2d9d1d3292..6e28181040 100644 --- a/src/extension/prompts/node/agent/openai/gpt51Prompt.tsx +++ b/src/extension/prompts/node/agent/openai/gpt51Prompt.tsx @@ -158,7 +158,7 @@ class Gpt51Prompt extends PromptElement { - Do not use one-letter variable names unless explicitly requested.
- NEVER output inline citations like "【F:README.md†L5-L14】" in your outputs. The UI is not able to render these so they will just be broken in the UI. Instead, if you output valid filepaths, users will be able to click on them to open the files in their editor.
- You have access to many tools. If a tool exists to perform a specific task, you MUST use that tool instead of running a terminal command to perform that task.
- {tools[ToolName.RunTests] && <>- Use the {ToolName.RunTests} tool to run tests instead of running terminal commands.
} + {tools[ToolName.CoreRunTest] && <>- Use the {ToolName.CoreRunTest} tool to run tests instead of running terminal commands.
}
If the codebase has tests or the ability to build or run, consider using them to verify changes once your work is complete.
diff --git a/src/extension/prompts/node/agent/openai/gpt5CodexPrompt.tsx b/src/extension/prompts/node/agent/openai/gpt5CodexPrompt.tsx index 1946ae24aa..a65898e902 100644 --- a/src/extension/prompts/node/agent/openai/gpt5CodexPrompt.tsx +++ b/src/extension/prompts/node/agent/openai/gpt5CodexPrompt.tsx @@ -29,7 +29,7 @@ class CodexStyleGpt5CodexPrompt extends PromptElement {
## Tool use
- You have access to many tools. If a tool exists to perform a specific task, you MUST use that tool instead of running a terminal command to perform that task.
- {tools[ToolName.RunTests] && <>- Use the {ToolName.RunTests} tool to run tests instead of running terminal commands.
} + {tools[ToolName.CoreRunTest] && <>- Use the {ToolName.CoreRunTest} tool to run tests instead of running terminal commands.
} {tools[ToolName.CoreManageTodoList] && <>
## {ToolName.CoreManageTodoList} tool
diff --git a/src/extension/prompts/node/inline/inlineChat2Prompt.tsx b/src/extension/prompts/node/inline/inlineChat2Prompt.tsx index 4df6880e38..6757da7ccf 100644 --- a/src/extension/prompts/node/inline/inlineChat2Prompt.tsx +++ b/src/extension/prompts/node/inline/inlineChat2Prompt.tsx @@ -3,18 +3,17 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { PromptElement, PromptElementProps, PromptSizing, SystemMessage, UserMessage } from '@vscode/prompt-tsx'; +import { PromptElement, PromptElementProps, PromptReference, PromptSizing, SystemMessage, UserMessage } from '@vscode/prompt-tsx'; import { TextDocumentSnapshot } from '../../../../platform/editing/common/textDocumentSnapshot'; import { CacheType } from '../../../../platform/endpoint/common/endpointTypes'; import { IPromptPathRepresentationService } from '../../../../platform/prompts/common/promptPathRepresentationService'; import { ChatRequest, ChatRequestEditorData } from '../../../../vscodeTypes'; import { ChatVariablesCollection } from '../../../prompt/common/chatVariablesCollection'; -import { ITextDocumentWorkingSetEntry, IWorkingSet, WorkingSetEntryState } from '../../../prompt/common/intents'; import { CopilotIdentityRules } from '../base/copilotIdentity'; import { SafetyRules } from '../base/safetyRules'; import { Tag } from '../base/tag'; import { ChatVariables, UserQuery } from '../panel/chatVariables'; -import { WorkingSet } from '../panel/editCodePrompt'; +import { CodeBlock } from '../panel/safeElements'; export type InlineChat2PromptProps = PromptElementProps<{ @@ -35,18 +34,20 @@ export class InlineChat2Prompt extends PromptElement { override render(state: void, sizing: PromptSizing): Promise { - const workingSet: IWorkingSet = [{ - document: TextDocumentSnapshot.create(this.props.data.document), - isMarkedReadonly: false, - state: WorkingSetEntryState.Initial, - range: this.props.data.selection - } satisfies ITextDocumentWorkingSetEntry]; + const snapshot = TextDocumentSnapshot.create(this.props.data.document); - const variables = new ChatVariablesCollection(this.props.request.references); - const filepath = this._promptPathRepresentationService.getFilePath(this.props.data.document.uri); + // the full lines of the selection + // TODO@jrieken + // * if the selection is empty and if the line with the selection is empty we could hint to add code and + // generally with empty selections we could allow the model to be a bit more creative + // * use the true selected text (now we extend to full lines) + const selectedLines = snapshot.getText(this.props.data.selection.with({ + start: this.props.data.selection.start.with({ character: 0 }), + end: this.props.data.selection.end.with({ character: Number.MAX_SAFE_INTEGER }), + })); - // TODO@jrieken: if the selection is empty and if the line with the selection is empty we could hint to add code and - // generally with empty selections we could allow the model to be a bit more creative + const variables = new ChatVariablesCollection(this.props.request.references); + const filepath = this._promptPathRepresentationService.getFilePath(snapshot.uri); // TODO@jrieken APPLY_PATCH_INSTRUCTIONS return ( @@ -62,7 +63,15 @@ export class InlineChat2Prompt extends PromptElement { - + <> + This is the file you are editing: + + + + + + + If there is a user selection, focus on it, and try to make changes to the selected code and its context.
diff --git a/src/extension/tools/common/test/toolService.spec.ts b/src/extension/tools/common/test/toolService.spec.ts index fad6985733..844fb0b74c 100644 --- a/src/extension/tools/common/test/toolService.spec.ts +++ b/src/extension/tools/common/test/toolService.spec.ts @@ -212,6 +212,18 @@ describe('Tool Service', () => { } }); + + const multiResult2 = toolsService.validateToolInput('multiNestedTool', JSON.stringify({ + config: { setting: 'value' }, + metadata: { tags: JSON.stringify(['tag1', 'tag2']) } + })); + expect(multiResult2).toEqual({ + inputObj: { + config: { setting: 'value' }, + metadata: { tags: ['tag1', 'tag2'] } + } + }); + // Test that malformed nested JSON strings still fail gracefully const malformedResult = toolsService.validateToolInput('nestedJsonTool', '{"thread_id": "i6747", "action_json": "{\\"command\\": invalid}"}'); expect(malformedResult).toMatchObject({ diff --git a/src/extension/tools/common/toolNames.ts b/src/extension/tools/common/toolNames.ts index a057a6a595..a6601c45a6 100644 --- a/src/extension/tools/common/toolNames.ts +++ b/src/extension/tools/common/toolNames.ts @@ -23,7 +23,6 @@ export enum ToolName { Codebase = 'semantic_search', VSCodeAPI = 'get_vscode_api', TestFailure = 'test_failure', - RunTests = 'run_tests', FindFiles = 'file_search', FindTextInFiles = 'grep_search', ReadFile = 'read_file', @@ -211,7 +210,6 @@ export const toolCategories: Record = { [ToolName.CoreTerminalLastCommand]: ToolCategory.VSCodeInteraction, // Testing - [ToolName.RunTests]: ToolCategory.Testing, [ToolName.TestFailure]: ToolCategory.Testing, [ToolName.FindTestFiles]: ToolCategory.Testing, [ToolName.CoreRunTest]: ToolCategory.Testing, diff --git a/src/extension/tools/common/toolsRegistry.ts b/src/extension/tools/common/toolsRegistry.ts index d06951e7e5..8a1ab3d958 100644 --- a/src/extension/tools/common/toolsRegistry.ts +++ b/src/extension/tools/common/toolsRegistry.ts @@ -67,20 +67,19 @@ export interface ICopilotToolExtension { export interface ICopilotTool extends vscode.LanguageModelTool, ICopilotToolExtension { } - export interface ICopilotToolCtor { readonly toolName: ToolName; - new(...args: any[]): ICopilotTool; + new(...args: never[]): ICopilotTool; } export interface ICopilotToolExtensionCtor { readonly toolName: ToolName; - new(...args: any[]): ICopilotToolExtension; + new(...args: never[]): ICopilotToolExtension; } export const ToolRegistry = new class { - private _tools: ICopilotToolCtor[] = []; - private _toolExtensions: ICopilotToolExtensionCtor[] = []; + private _tools: Array = []; + private _toolExtensions: Array = []; public registerTool(tool: ICopilotToolCtor) { this._tools.push(tool); diff --git a/src/extension/tools/common/toolsService.ts b/src/extension/tools/common/toolsService.ts index 849a06be3a..03a364a4d7 100644 --- a/src/extension/tools/common/toolsService.ts +++ b/src/extension/tools/common/toolsService.ts @@ -57,8 +57,8 @@ export interface IToolsService { /** * Tool implementations from tools in this extension */ - copilotTools: ReadonlyMap>; - getCopilotTool(name: string): ICopilotTool | undefined; + copilotTools: ReadonlyMap>; + getCopilotTool(name: string): ICopilotTool | undefined; invokeTool(name: string, options: vscode.LanguageModelToolInvocationOptions, token: vscode.CancellationToken): Thenable; getTool(name: string): vscode.LanguageModelToolInformation | undefined; @@ -121,7 +121,7 @@ function ajvValidateForTool(toolName: string, fn: ValidateFunction, inputObj: un let hasNestedJsonStrings = false; for (const error of fn.errors) { // Check if the error is about expecting an object but getting a string - const isObjError = error.keyword === 'type' && error.params?.type === 'object' && error.instancePath; + const isObjError = error.keyword === 'type' && (error.params?.type === 'object' || error.params?.type === 'array') && error.instancePath; if (!isObjError) { continue; } @@ -159,13 +159,13 @@ export abstract class BaseToolsService extends Disposable implements IToolsServi public get onWillInvokeTool() { return this._onWillInvokeTool.event; } abstract tools: ReadonlyArray; - abstract copilotTools: ReadonlyMap>; + abstract copilotTools: ReadonlyMap>; private readonly ajv = new Ajv({ coerceTypes: true }); private didWarnAboutValidationError?: Set; private readonly schemaCache = new LRUCache(16); - abstract getCopilotTool(name: string): ICopilotTool | undefined; + abstract getCopilotTool(name: string): ICopilotTool | undefined; abstract invokeTool(name: string, options: vscode.LanguageModelToolInvocationOptions, token: vscode.CancellationToken): Thenable; abstract getTool(name: string): vscode.LanguageModelToolInformation | undefined; abstract getToolByToolReferenceName(name: string): vscode.LanguageModelToolInformation | undefined; @@ -239,7 +239,7 @@ export class NullToolsService extends BaseToolsService implements IToolsService return undefined; } - override getCopilotTool(name: string): ICopilotTool | undefined { + override getCopilotTool(name: string): ICopilotTool | undefined { return undefined; } diff --git a/src/extension/tools/node/test/searchToolTestUtils.ts b/src/extension/tools/node/test/searchToolTestUtils.ts index 1b298a43c2..928bf540d6 100644 --- a/src/extension/tools/node/test/searchToolTestUtils.ts +++ b/src/extension/tools/node/test/searchToolTestUtils.ts @@ -3,9 +3,25 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import { OutputMode } from '@vscode/prompt-tsx'; import type * as vscode from 'vscode'; import { IEndpointProvider } from '../../../../platform/endpoint/common/endpointProvider'; -import { IChatEndpoint } from '../../../../platform/networking/common/networking'; +import { IChatEndpoint, IEmbeddingsEndpoint } from '../../../../platform/networking/common/networking'; +import { ITokenizer as IUtilTokenizer, TokenizerType } from '../../../../util/common/tokenizer'; + +/** + * Creates a mock tokenizer for testing + */ +function createMockTokenizer(): IUtilTokenizer { + const mockTokenizer: IUtilTokenizer = { + mode: OutputMode.Raw, + tokenLength: async () => 0, + countMessageTokens: async () => 0, + countMessagesTokens: async () => 0, + countToolTokens: async () => 0, + }; + return mockTokenizer; +} /** * Creates a mock endpoint provider for search tool tests @@ -24,7 +40,20 @@ export function createMockEndpointProvider(modelFamily: string): IEndpointProvid } as IChatEndpoint), getAllChatEndpoints: async () => [], getAllCompletionModels: async () => [], - getEmbeddingsEndpoint: async () => ({} as any), + getEmbeddingsEndpoint: async () => ({ + urlOrRequestMetadata: 'https://mock-embeddings-endpoint', + acquireTokenizer: createMockTokenizer, + modelMaxPromptTokens: 1000, + modelMaxOutputTokens: 1000, + model: 'test-embeddings-model', + family: modelFamily, + showInModelPicker: true, + embeddingDimensions: 768, + maxBatchSize: 16, + name: 'Test Embeddings Model', + version: '1.0', + tokenizer: TokenizerType.CL100K + } as IEmbeddingsEndpoint), } as IEndpointProvider; } diff --git a/src/extension/tools/node/test/testFailure.spec.tsx b/src/extension/tools/node/test/testFailure.spec.tsx index 253b93f2c0..eaa8cb7b89 100644 --- a/src/extension/tools/node/test/testFailure.spec.tsx +++ b/src/extension/tools/node/test/testFailure.spec.tsx @@ -91,7 +91,7 @@ suite('TestFailureTool', () => { test('returns a message when no failures exist', async () => { failures = []; const result = await resolver.invoke({ input: {}, toolInvocationToken: '' as any }); - expect(await toolResultToString(accessor, result)).toMatchInlineSnapshot(`"No test failures were found yet, call the tool run_tests to run tests and find failures."`); + expect(await toolResultToString(accessor, result)).toMatchInlineSnapshot(`"No test failures were found yet, call the tool runTests to run tests and find failures."`); }); test('formats stack frames', async () => { @@ -129,7 +129,7 @@ suite('TestFailureTool', () => { ## Rules: - Always try to find an error in the implementation code first. Don't suggest any changes in my test cases unless I tell you to. - If you need more information about anything in the codebase, use a tool like read_file, list_dir, or file_search to find and read it. Never ask the user to provide it themselves. - - If you make changes to fix the test, call run_tests to run the tests and verify the fix. + - If you make changes to fix the test, call runTests to run the tests and verify the fix. - Don't try to make the same changes you made before to fix the test. If you're stuck, ask the user for pointers. " `); @@ -165,7 +165,7 @@ suite('TestFailureTool', () => { ## Rules: - Always try to find an error in the implementation code first. Don't suggest any changes in my test cases unless I tell you to. - If you need more information about anything in the codebase, use a tool like read_file, list_dir, or file_search to find and read it. Never ask the user to provide it themselves. - - If you make changes to fix the test, call run_tests to run the tests and verify the fix. + - If you make changes to fix the test, call runTests to run the tests and verify the fix. - Don't try to make the same changes you made before to fix the test. If you're stuck, ask the user for pointers. " `); @@ -264,7 +264,7 @@ suite('TestFailureTool', () => { ## Rules: - Always try to find an error in the implementation code first. Don't suggest any changes in my test cases unless I tell you to. - If you need more information about anything in the codebase, use a tool like read_file, list_dir, or file_search to find and read it. Never ask the user to provide it themselves. - - If you make changes to fix the test, call run_tests to run the tests and verify the fix. + - If you make changes to fix the test, call runTests to run the tests and verify the fix. - Don't try to make the same changes you made before to fix the test. If you're stuck, ask the user for pointers. " `); diff --git a/src/extension/tools/node/test/testToolsService.ts b/src/extension/tools/node/test/testToolsService.ts index d3de3f012f..d72a1eeb4d 100644 --- a/src/extension/tools/node/test/testToolsService.ts +++ b/src/extension/tools/node/test/testToolsService.ts @@ -40,7 +40,7 @@ export class TestToolsService extends BaseToolsService implements IToolsService }); } - private readonly _copilotTools: Map>>; + private readonly _copilotTools: Map>>; get copilotTools() { return new Map(Iterable.map(this._copilotTools.entries(), ([name, tool]) => [name, tool.value])); @@ -115,7 +115,7 @@ export class TestToolsService extends BaseToolsService implements IToolsService throw new Error('unknown tool: ' + name); } - override getCopilotTool(name: string): ICopilotTool | undefined { + override getCopilotTool(name: string): ICopilotTool | undefined { const tool = this._copilotTools.get(name as ToolName)?.value; return tool; } diff --git a/src/extension/tools/node/testFailureTool.tsx b/src/extension/tools/node/testFailureTool.tsx index 887ca23111..4179140fb4 100644 --- a/src/extension/tools/node/testFailureTool.tsx +++ b/src/extension/tools/node/testFailureTool.tsx @@ -58,7 +58,7 @@ export class TestFailureTool implements ICopilotTool<{}> { const failures = Array.from(this.testProvider.getAllFailures()); if (failures.length === 0) { return new LanguageModelToolResult([ - new LanguageModelTextPart(`No test failures were found yet, call the tool ${ToolName.RunTests} to run tests and find failures.`), + new LanguageModelTextPart(`No test failures were found yet, call the tool ${ToolName.CoreRunTest} to run tests and find failures.`), ]); } @@ -118,7 +118,7 @@ export class TestFailureList extends PromptElement ## Rules:
- Always try to find an error in the implementation code first. Don't suggest any changes in my test cases unless I tell you to.
- If you need more information about anything in the codebase, use a tool like {ToolName.ReadFile}, {ToolName.ListDirectory}, or {ToolName.FindFiles} to find and read it. Never ask the user to provide it themselves.
- - If you make changes to fix the test, call {ToolName.RunTests} to run the tests and verify the fix.
+ - If you make changes to fix the test, call {ToolName.CoreRunTest} to run the tests and verify the fix.
- Don't try to make the same changes you made before to fix the test. If you're stuck, ask the user for pointers.
; diff --git a/src/extension/tools/vscode-node/toolsService.ts b/src/extension/tools/vscode-node/toolsService.ts index 059368973b..c110ef0369 100644 --- a/src/extension/tools/vscode-node/toolsService.ts +++ b/src/extension/tools/vscode-node/toolsService.ts @@ -16,10 +16,10 @@ import { BaseToolsService } from '../common/toolsService'; export class ToolsService extends BaseToolsService { declare _serviceBrand: undefined; - private readonly _copilotTools: Lazy>>; + private readonly _copilotTools: Lazy>>; // Extensions to override definitions for existing tools. - private readonly _toolExtensions: Lazy>>; + private readonly _toolExtensions: Lazy>>; private readonly _contributedToolCache: { input: readonly vscode.LanguageModelToolInformation[]; @@ -83,7 +83,7 @@ export class ToolsService extends BaseToolsService { return vscode.lm.invokeTool(getContributedToolName(name), options, token); } - override getCopilotTool(name: string): ICopilotTool | undefined { + override getCopilotTool(name: string): ICopilotTool | undefined { const tool = this._copilotTools.value.get(name as ToolName); return tool; } diff --git a/src/extension/typescriptContext/common/serverProtocol.ts b/src/extension/typescriptContext/common/serverProtocol.ts index 4d769d4a05..7113839d4d 100644 --- a/src/extension/typescriptContext/common/serverProtocol.ts +++ b/src/extension/typescriptContext/common/serverProtocol.ts @@ -69,8 +69,8 @@ export type CacheInfo = { } export namespace CacheInfo { export type has = { cache: CacheInfo }; - export function has(item: any): item is has { - return item.cache !== undefined; + export function has(item: unknown): item is has { + return (item as has).cache !== undefined; } } export type CachedContextItem = { @@ -288,7 +288,7 @@ export type ContextRunnableResult = { speculativeKind: SpeculativeKind; /** - * A human readable path to ease debugging. + * A human readable path to the signature to ease debugging. */ debugPath?: ContextRunnableResultId | undefined; } @@ -441,10 +441,10 @@ export namespace ComputeContextResponse { } export function isOk(response: ComputeContextResponse): response is tt.server.protocol.Response & { body: OK } { - return response.type === 'response' && (response.body as any).state !== undefined; + return response.type === 'response' && (response.body as OK).state !== undefined; } export function isError(response: ComputeContextResponse): response is tt.server.protocol.Response & { body: Failed } { - return response.type === 'response' && (response.body as any).error !== undefined; + return response.type === 'response' && (response.body as Failed).error !== undefined; } } diff --git a/src/extension/typescriptContext/serverPlugin/src/common/baseContextProviders.ts b/src/extension/typescriptContext/serverPlugin/src/common/baseContextProviders.ts index c5a589b512..9a3cc210e1 100644 --- a/src/extension/typescriptContext/serverPlugin/src/common/baseContextProviders.ts +++ b/src/extension/typescriptContext/serverPlugin/src/common/baseContextProviders.ts @@ -28,7 +28,7 @@ export class CompilerOptionsRunnable extends AbstractContextRunnable { public static VersionTraitKey: string = Trait.createContextItemKey(TraitKind.Version); // Traits to collect from the compiler options in the format of [trait kind, trait description, context key, CompilerOptions.enumType (if applicable)] - public static traitsToCollect: [TraitKind, string, ContextItemKey, any][] = [ + public static traitsToCollect: [TraitKind, string, ContextItemKey, unknown | undefined][] = [ [TraitKind.Module, 'The TypeScript module system used in this project is ', Trait.createContextItemKey(TraitKind.Module), ts.ModuleKind], [TraitKind.ModuleResolution, 'The TypeScript module resolution strategy used in this project is ', Trait.createContextItemKey(TraitKind.ModuleResolution), ts.ModuleResolutionKind], [TraitKind.Target, 'The target version of JavaScript for this project is ', Trait.createContextItemKey(TraitKind.Target), ts.ScriptTarget], @@ -55,14 +55,14 @@ export class CompilerOptionsRunnable extends AbstractContextRunnable { if (!result.addFromKnownItems(CompilerOptionsRunnable.VersionTraitKey)) { result.addTrait(TraitKind.Version, 'The TypeScript version used in this project is ', ts.version); } - for (const [traitKind, trait, key, enumType,] of CompilerOptionsRunnable.traitsToCollect) { + for (const [traitKind, trait, key, enumType] of CompilerOptionsRunnable.traitsToCollect) { if (result.addFromKnownItems(key)) { continue; } let traitValue = compilerOptions[traitKind as keyof tt.CompilerOptions]; if (traitValue) { if (typeof traitValue === "number") { - const enumName = CompilerOptionsRunnable.getEnumName(enumType, traitValue); + const enumName = CompilerOptionsRunnable.getEnumName(enumType as Record, traitValue); if (enumName) { traitValue = enumName; } @@ -72,7 +72,7 @@ export class CompilerOptionsRunnable extends AbstractContextRunnable { } } - private static getEnumName(enumObj: any, value: any): string | undefined { + private static getEnumName(enumObj: Record, value: unknown): string | undefined { return Object.keys(enumObj).find(key => enumObj[key] === value); } } diff --git a/src/extension/typescriptContext/serverPlugin/src/common/contextProvider.ts b/src/extension/typescriptContext/serverPlugin/src/common/contextProvider.ts index 27c2e13d6e..e3ad85e024 100644 --- a/src/extension/typescriptContext/serverPlugin/src/common/contextProvider.ts +++ b/src/extension/typescriptContext/serverPlugin/src/common/contextProvider.ts @@ -696,12 +696,19 @@ export namespace CacheScopes { } export function createWithinCacheScope(node: tt.Node, sourceFile?: tt.SourceFile | undefined): CacheScope; - export function createWithinCacheScope(node: tt.NodeArray, sourceFile: tt.SourceFile | undefined): CacheScope; + export function createWithinCacheScope(node: tt.NodeArray, sourceFile?: tt.SourceFile | undefined): CacheScope; export function createWithinCacheScope(node: tt.Node | tt.NodeArray, sourceFile?: tt.SourceFile | undefined): CacheScope { - return { - kind: CacheScopeKind.WithinRange, - range: createRange(node as any, sourceFile), - }; + if (isNodeArray(node)) { + return { + kind: CacheScopeKind.WithinRange, + range: createRange(node as tt.NodeArray, sourceFile), + }; + } else { + return { + kind: CacheScopeKind.WithinRange, + range: createRange(node as tt.Node, sourceFile), + }; + } } export function createOutsideCacheScope(nodes: Iterable, sourceFile: tt.SourceFile | undefined): CacheScope { @@ -722,7 +729,7 @@ export namespace CacheScopes { } export function createRange(node: tt.Node, sourceFile?: tt.SourceFile | undefined): Range; - export function createRange(node: tt.NodeArray, sourceFile: tt.SourceFile | undefined): Range; + export function createRange(node: tt.NodeArray, sourceFile?: tt.SourceFile | undefined): Range; export function createRange(node: tt.Node | tt.NodeArray, sourceFile?: tt.SourceFile | undefined): Range { let startOffset: number; let endOffset: number; diff --git a/src/extension/typescriptContext/serverPlugin/src/common/protocol.ts b/src/extension/typescriptContext/serverPlugin/src/common/protocol.ts index dea001b002..7113839d4d 100644 --- a/src/extension/typescriptContext/serverPlugin/src/common/protocol.ts +++ b/src/extension/typescriptContext/serverPlugin/src/common/protocol.ts @@ -69,8 +69,8 @@ export type CacheInfo = { } export namespace CacheInfo { export type has = { cache: CacheInfo }; - export function has(item: any): item is has { - return item.cache !== undefined; + export function has(item: unknown): item is has { + return (item as has).cache !== undefined; } } export type CachedContextItem = { @@ -441,10 +441,10 @@ export namespace ComputeContextResponse { } export function isOk(response: ComputeContextResponse): response is tt.server.protocol.Response & { body: OK } { - return response.type === 'response' && (response.body as any).state !== undefined; + return response.type === 'response' && (response.body as OK).state !== undefined; } export function isError(response: ComputeContextResponse): response is tt.server.protocol.Response & { body: Failed } { - return response.type === 'response' && (response.body as any).error !== undefined; + return response.type === 'response' && (response.body as Failed).error !== undefined; } } diff --git a/src/extension/typescriptContext/serverPlugin/src/common/typescripts.ts b/src/extension/typescriptContext/serverPlugin/src/common/typescripts.ts index 8b57b99488..3f55b02b34 100644 --- a/src/extension/typescriptContext/serverPlugin/src/common/typescripts.ts +++ b/src/extension/typescriptContext/serverPlugin/src/common/typescripts.ts @@ -20,7 +20,7 @@ namespace tss { getSymbolId(symbol: tt.Symbol): SymbolId; } & typeof ts; - const its = ts as any as InternalTypeScript; + const its = ts as unknown as InternalTypeScript; export const getTokenAtPosition: (sourceFile: tt.SourceFile, position: number) => tt.Node = its.getTokenAtPosition; export const getTouchingToken: (sourceFile: tt.SourceFile, position: number, includePrecedingTokenAtEndPosition?: (n: tt.Node) => boolean) => tt.Node = its.getTouchingToken; @@ -547,7 +547,7 @@ namespace tss { if (this.internalSymbolNames === undefined) { this.internalSymbolNames = new Set(); for (const item in ts.InternalSymbolName) { - this.internalSymbolNames.add((ts.InternalSymbolName as any)[item]); + this.internalSymbolNames.add((ts.InternalSymbolName as Record)[item]); } } return this.internalSymbolNames.has(symbol.escapedName as string); diff --git a/src/extension/typescriptContext/serverPlugin/src/common/utils.ts b/src/extension/typescriptContext/serverPlugin/src/common/utils.ts index d3d0ee7c1d..b01076b913 100644 --- a/src/extension/typescriptContext/serverPlugin/src/common/utils.ts +++ b/src/extension/typescriptContext/serverPlugin/src/common/utils.ts @@ -132,7 +132,7 @@ export class LinkedMap implements Map { return item.value; } - forEach(callbackfn: (value: V, key: K, map: LinkedMap) => void, thisArg?: any): void { + forEach(callbackfn: (value: V, key: K, map: LinkedMap) => void, thisArg?: unknown): void { const state = this._state; let current = this._head; while (current) { diff --git a/src/extension/typescriptContext/vscode-node/inspector.ts b/src/extension/typescriptContext/vscode-node/inspector.ts index 7d776f2cc8..cd4ed11d3a 100644 --- a/src/extension/typescriptContext/vscode-node/inspector.ts +++ b/src/extension/typescriptContext/vscode-node/inspector.ts @@ -405,7 +405,7 @@ abstract class TreeContextRequest { return markdown; } - protected abstract createJson(): any; + protected abstract createJson(): {}; public abstract children(): (TreeRunnableResult | TreeYieldedContextItem)[]; @@ -423,7 +423,7 @@ class TreeCachePopulateContextRequest extends TreeContextRequest { this.items = event.items; } - protected createJson(): any { + protected createJson(): {} { return { document: this.document, position: { @@ -458,7 +458,7 @@ class TreeYieldContextRequest extends TreeContextRequest { this.items = event.items; } - protected createJson(): any { + protected createJson(): {} { return { document: this.document, position: { diff --git a/src/extension/typescriptContext/vscode-node/languageContextService.ts b/src/extension/typescriptContext/vscode-node/languageContextService.ts index dbd7c7487d..d6d8183f1f 100644 --- a/src/extension/typescriptContext/vscode-node/languageContextService.ts +++ b/src/extension/typescriptContext/vscode-node/languageContextService.ts @@ -319,7 +319,7 @@ class TelemetrySender { this.logService.debug(`TypeScript Copilot context request ${context.requestId} got cancelled.`); } - public sendActivationTelemetry(response: protocol.PingResponse | undefined, error: any | undefined): void { + public sendActivationTelemetry(response: protocol.PingResponse | undefined, error: unknown | undefined): void { if (response !== undefined) { const body: protocol.PingResponse['body'] | undefined = response?.body; if (body?.kind === 'ok') { @@ -346,9 +346,10 @@ class TelemetrySender { this.sendUnknownPingResponseTelemetry(ErrorLocation.Server, ErrorPart.ServerPlugin, response); } } else if (error !== undefined) { - if (TypeScriptServerError.is(error)) { + const isError = error instanceof Error; + if (isError && TypeScriptServerError.is(error)) { this.sendActivationFailedTelemetry(ErrorLocation.Server, ErrorPart.ServerPlugin, error.response.message ?? error.message, undefined, error.version.displayName); - } else if (error instanceof Error) { + } else if (isError) { this.sendActivationFailedTelemetry(ErrorLocation.Client, ErrorPart.ServerPlugin, error.message, error.stack); } else { this.sendActivationFailedTelemetry(ErrorLocation.Client, ErrorPart.ServerPlugin, 'Unknown error', undefined); @@ -1822,7 +1823,7 @@ export class InlineCompletionContribution implements vscode.Disposable, TokenBud } else { this.unregister(); } - }).catch((error: any) => this.logService.error('Error checking TypeScript context provider registration:', error)); + }).catch((error) => this.logService.error(error, 'Error checking TypeScript context provider registration')); } private async register(): Promise { @@ -1881,7 +1882,7 @@ export class InlineCompletionContribution implements vscode.Disposable, TokenBud convertedItems.push(converted); } return Promise.resolve(convertedItems); - } else if (typeof (items as any)[Symbol.asyncIterator] === 'function') { + } else if (typeof (items as AsyncIterable)[Symbol.asyncIterator] === 'function') { return mapAsyncIterable(items as AsyncIterable, (item) => self.convertItem(item)); } else if (items instanceof Promise) { return items.then((resolvedItems) => { @@ -2025,8 +2026,8 @@ export class InlineCompletionContribution implements vscode.Disposable, TokenBud private async getCopilotApi(): Promise { const copilotExtension = vscode.extensions.getExtension('GitHub.copilot'); if (copilotExtension === undefined) { - this.telemetrySender.sendActivationFailedTelemetry(ErrorLocation.Client, ErrorPart.CopilotExtension, 'Copilot extension not found', undefined); - this.logService.error('Copilot extension not found'); + // this.telemetrySender.sendActivationFailedTelemetry(ErrorLocation.Client, ErrorPart.CopilotExtension, 'Copilot extension not found', undefined); + // this.logService.error('Copilot extension not found'); return undefined; } try { diff --git a/src/extension/vscode.proposed.chatSessionsProvider.d.ts b/src/extension/vscode.proposed.chatSessionsProvider.d.ts index 489e5f952c..e47cdbb1fe 100644 --- a/src/extension/vscode.proposed.chatSessionsProvider.d.ts +++ b/src/extension/vscode.proposed.chatSessionsProvider.d.ts @@ -245,10 +245,6 @@ declare module 'vscode' { export interface ChatContext { readonly chatSessionContext?: ChatSessionContext; - readonly chatSummary?: { - readonly prompt?: string; - readonly history?: string; - }; } export interface ChatSessionContext { diff --git a/src/extension/xtab/node/xtabProvider.ts b/src/extension/xtab/node/xtabProvider.ts index 81520e28e7..6312eafe3f 100644 --- a/src/extension/xtab/node/xtabProvider.ts +++ b/src/extension/xtab/node/xtabProvider.ts @@ -1139,7 +1139,7 @@ export class XtabProvider implements IStatelessNextEditProvider { const tracer = this.tracer.sub('predictNextCursorPosition'); - const systemMessage = 'Your task is to predict the next line number in the current file where the developer is most likely to make their next edit, using the provided context.'; + const systemMessage = `Your task is to predict the next line number in the current file where the developer is most likely to make their next edit, using the provided context. If you don't think anywhere is a good next line jump target, just output the current line number of the cursor. Make sure to just output the line number and nothing else (no explanation, reasoning, etc,).`; const maxTokens = this.configService.getExperimentBasedConfig(ConfigKey.Advanced.InlineEditsNextCursorPredictionCurrentFileMaxTokens, this.expService); diff --git a/src/platform/configuration/common/configurationService.ts b/src/platform/configuration/common/configurationService.ts index c113c0589f..635680dd3d 100644 --- a/src/platform/configuration/common/configurationService.ts +++ b/src/platform/configuration/common/configurationService.ts @@ -792,6 +792,8 @@ export namespace ConfigKey { export const ResponsesApiReasoningEffort = defineSetting<'low' | 'medium' | 'high' | 'default'>('chat.responsesApiReasoningEffort', ConfigType.ExperimentBased, 'default'); /** Configure reasoning summary style sent to Responses API */ export const ResponsesApiReasoningSummary = defineSetting<'off' | 'detailed'>('chat.responsesApiReasoningSummary', ConfigType.ExperimentBased, 'detailed'); + /** Use the Messages API instead of Chat Completions when supported */ + export const UseMessagesApi = defineSetting('chat.useMessagesApi', ConfigType.ExperimentBased, false); export const EnableChatImageUpload = defineSetting('chat.imageUpload.enabled', ConfigType.ExperimentBased, true); /** Enable extended thinking for Anthropic models that support it */ export const AnthropicThinkingEnabled = defineSetting('chat.anthropic.thinking.enabled', ConfigType.ExperimentBased, false); @@ -826,7 +828,7 @@ export namespace ConfigKey { export const SetupTests = defineSetting('chat.setupTests.enabled', ConfigType.Simple, true); /** Whether the Copilot TypeScript context provider is enabled and if how */ export const TypeScriptLanguageContext = defineSetting('chat.languageContext.typescript.enabled', ConfigType.ExperimentBased, false); - export const TypeScriptLanguageContextMode = defineSetting<'minimal' | 'double' | 'fillHalf' | 'fill'>('chat.languageContext.typescript.items', ConfigType.ExperimentBased, 'minimal'); + export const TypeScriptLanguageContextMode = defineSetting<'minimal' | 'double' | 'fillHalf' | 'fill'>('chat.languageContext.typescript.items', ConfigType.ExperimentBased, 'double'); export const TypeScriptLanguageContextIncludeDocumentation = defineSetting('chat.languageContext.typescript.includeDocumentation', ConfigType.ExperimentBased, false); export const TypeScriptLanguageContextCacheTimeout = defineSetting('chat.languageContext.typescript.cacheTimeout', ConfigType.ExperimentBased, 500); export const TypeScriptLanguageContextFix = defineSetting('chat.languageContext.fix.typescript.enabled', ConfigType.ExperimentBased, false); @@ -837,6 +839,7 @@ export namespace ConfigKey { export const CodeFeedbackInstructions = defineSetting('chat.reviewSelection.instructions', ConfigType.Simple, [] as CodeGenerationInstruction[]); export const UseProjectTemplates = defineSetting('chat.useProjectTemplates', ConfigType.Simple, true); + export const AgentDelegateAutoCommitAndPush = defineSetting('chat.agent.delegate.autoCommitAndPush', ConfigType.Simple, false); export const ExplainScopeSelection = defineSetting('chat.scopeSelection', ConfigType.Simple, false); export const EnableCodeActions = defineSetting('editor.enableCodeActions', ConfigType.Simple, true); export const LocaleOverride = defineSetting('chat.localeOverride', ConfigType.Simple, 'auto'); diff --git a/src/platform/endpoint/common/endpointProvider.ts b/src/platform/endpoint/common/endpointProvider.ts index d60b3c9c78..5a2806982c 100644 --- a/src/platform/endpoint/common/endpointProvider.ts +++ b/src/platform/endpoint/common/endpointProvider.ts @@ -69,7 +69,8 @@ type ICompletionModelCapabilities = { export enum ModelSupportedEndpoint { ChatCompletions = '/chat/completions', - Responses = '/responses' + Responses = '/responses', + Messages = '/v1/messages' } export interface IModelAPIResponse { diff --git a/src/platform/endpoint/node/chatEndpoint.ts b/src/platform/endpoint/node/chatEndpoint.ts index 57d822c0f2..620beb5a5c 100644 --- a/src/platform/endpoint/node/chatEndpoint.ts +++ b/src/platform/endpoint/node/chatEndpoint.ts @@ -30,6 +30,7 @@ import { ITokenizerProvider } from '../../tokenizer/node/tokenizer'; import { ICAPIClientService } from '../common/capiClient'; import { IDomainService } from '../common/domainService'; import { CustomModel, IChatModelInformation, ModelPolicy, ModelSupportedEndpoint } from '../common/endpointProvider'; +import { createMessagesRequestBody, processResponseFromMessagesEndpoint } from './messagesApi'; import { createResponsesRequestBody, processResponseFromChatEndpoint } from './responsesApi'; /** @@ -182,7 +183,8 @@ export class ChatEndpoint implements IChatEndpoint { // Use override or respect setting. // TODO unlikely but would break if it changes in the middle of a request being constructed return this.modelMetadata.urlOrRequestMetadata ?? - (this.useResponsesApi ? { type: RequestType.ChatResponses } : { type: RequestType.ChatCompletions }); + (this.useResponsesApi ? { type: RequestType.ChatResponses } : + this.useMessagesApi ? { type: RequestType.ChatMessages } : { type: RequestType.ChatCompletions }); } protected get useResponsesApi(): boolean { @@ -197,6 +199,11 @@ export class ChatEndpoint implements IChatEndpoint { return !!(enableResponsesApi && this.modelMetadata.supported_endpoints?.includes(ModelSupportedEndpoint.Responses)); } + protected get useMessagesApi(): boolean { + const enableMessagesApi = this._configurationService.getExperimentBasedConfig(ConfigKey.UseMessagesApi, this._expService); + return !!(enableMessagesApi && this.modelMetadata.supported_endpoints?.includes(ModelSupportedEndpoint.Messages)); + } + public get degradationReason(): string | undefined { return this.modelMetadata.warning_messages?.at(0)?.message ?? this.modelMetadata.info_messages?.at(0)?.message; } @@ -212,7 +219,8 @@ export class ChatEndpoint implements IChatEndpoint { } public get apiType(): string { - return this.useResponsesApi ? 'responses' : 'chatCompletions'; + return this.useResponsesApi ? 'responses' : + this.useMessagesApi ? 'messages' : 'chatCompletions'; } interceptBody(body: IEndpointBody | undefined): void { @@ -248,6 +256,9 @@ export class ChatEndpoint implements IChatEndpoint { if (this.useResponsesApi) { const body = this._instantiationService.invokeFunction(createResponsesRequestBody, options, this.model, this); return this.customizeResponsesBody(body); + } else if (this.useMessagesApi) { + const body = this._instantiationService.invokeFunction(createMessagesRequestBody, options, this.model, this); + return this.customizeMessagesBody(body); } else { const body = createCapiRequestBody(options, this.model, this.getCompletionsCallback()); return this.customizeCapiBody(body); @@ -258,6 +269,10 @@ export class ChatEndpoint implements IChatEndpoint { return undefined; } + protected customizeMessagesBody(body: IEndpointBody): IEndpointBody { + return body; + } + protected customizeResponsesBody(body: IEndpointBody): IEndpointBody { return body; } @@ -277,6 +292,8 @@ export class ChatEndpoint implements IChatEndpoint { ): Promise> { if (this.useResponsesApi) { return processResponseFromChatEndpoint(this._instantiationService, telemetryService, logService, response, expectedNumChoices, finishCallback, telemetryData); + } else if (this.useMessagesApi) { + return processResponseFromMessagesEndpoint(this._instantiationService, telemetryService, logService, response, expectedNumChoices, finishCallback, telemetryData); } else if (!this._supportsStreaming) { return defaultNonStreamChatResponseProcessor(response, finishCallback, telemetryData); } else { diff --git a/src/platform/endpoint/node/messagesApi.ts b/src/platform/endpoint/node/messagesApi.ts new file mode 100644 index 0000000000..29fd123b46 --- /dev/null +++ b/src/platform/endpoint/node/messagesApi.ts @@ -0,0 +1,456 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { ContentBlockParam, MessageParam, RedactedThinkingBlockParam, TextBlockParam, ThinkingBlockParam } from '@anthropic-ai/sdk/resources'; +import { Raw } from '@vscode/prompt-tsx'; +import { ClientHttp2Stream } from 'http2'; +import { Response } from '../../../platform/networking/common/fetcherService'; +import { AsyncIterableObject } from '../../../util/vs/base/common/async'; +import { SSEParser } from '../../../util/vs/base/common/sseParser'; +import { isDefined } from '../../../util/vs/base/common/types'; +import { generateUuid } from '../../../util/vs/base/common/uuid'; +import { IInstantiationService, ServicesAccessor } from '../../../util/vs/platform/instantiation/common/instantiation'; +import { ILogService } from '../../log/common/logService'; +import { AnthropicMessagesTool, FinishedCallback, IResponseDelta } from '../../networking/common/fetch'; +import { IChatEndpoint, ICreateEndpointBodyOptions, IEndpointBody } from '../../networking/common/networking'; +import { ChatCompletion, FinishedCompletionReason } from '../../networking/common/openai'; +import { ITelemetryService } from '../../telemetry/common/telemetry'; +import { TelemetryData } from '../../telemetry/common/telemetryData'; + +interface AnthropicStreamEvent { + type: string; + message?: { + id: string; + type: string; + role: string; + content: ContentBlockParam[]; + model: string; + stop_reason: string | null; + stop_sequence: string | null; + usage: { + input_tokens: number; + output_tokens: number; + cache_creation_input_tokens?: number; + cache_read_input_tokens?: number; + }; + }; + index?: number; + content_block?: ContentBlockParam | ThinkingBlockParam | RedactedThinkingBlockParam; + delta?: { + type: string; + text?: string; + partial_json?: string; + thinking?: string; + signature?: string; + stop_reason?: string; + stop_sequence?: string; + }; + usage?: { + output_tokens: number; + input_tokens?: number; + cache_creation_input_tokens?: number; + cache_read_input_tokens?: number; + }; +} + +export function createMessagesRequestBody(accessor: ServicesAccessor, options: ICreateEndpointBodyOptions, model: string, endpoint: IChatEndpoint): IEndpointBody { + + const anthropicTools = options.requestOptions?.tools + ?.filter(tool => tool.function.name && tool.function.name.length > 0) + .map((tool): AnthropicMessagesTool => ({ + name: tool.function.name, + description: tool.function.description || '', + input_schema: { + type: 'object', + properties: (tool.function.parameters as { properties?: Record })?.properties ?? {}, + required: (tool.function.parameters as { required?: string[] })?.required ?? [], + }, + })); + + return { + model, + ...rawMessagesToMessagesAPI(options.messages), + stream: true, + tools: anthropicTools, + top_p: options.postOptions.top_p, + max_tokens: options.postOptions.max_tokens, + // TODO: Make thinking configuration controllable via settings (enable/disable and budget_tokens) + thinking: { + type: 'enabled', + budget_tokens: 1024, + }, + }; +} + +function rawMessagesToMessagesAPI(messages: readonly Raw.ChatMessage[]): { messages: MessageParam[]; system?: TextBlockParam[] } { + const unmergedMessages: MessageParam[] = []; + const systemParts: string[] = []; + + for (const message of messages) { + switch (message.role) { + case Raw.ChatRole.System: { + const systemText = message.content + .filter(c => c.type === Raw.ChatCompletionContentPartKind.Text) + .map(c => c.text) + .join('\n'); + if (systemText) { + systemParts.push(systemText); + } + break; + } + case Raw.ChatRole.User: { + const content = message.content + .map(rawContentToAnthropicContent) + .filter(isDefined); + if (content.length > 0) { + unmergedMessages.push({ + role: 'user', + content, + }); + } + break; + } + case Raw.ChatRole.Assistant: { + const content: ContentBlockParam[] = []; + for (const part of message.content) { + const anthropicPart = rawContentToAnthropicContent(part); + if (anthropicPart) { + content.push(anthropicPart); + } + } + if (message.toolCalls) { + for (const toolCall of message.toolCalls) { + let parsedInput: Record = {}; + try { + parsedInput = JSON.parse(toolCall.function.arguments); + } catch { + // Keep empty object if parse fails + } + content.push({ + type: 'tool_use', + id: toolCall.id, + name: toolCall.function.name, + input: parsedInput, + }); + } + } + + if (content.length > 0) { + unmergedMessages.push({ + role: 'assistant', + content, + }); + } + break; + } + case Raw.ChatRole.Tool: { + if (message.toolCallId) { + const toolContent: (TextBlockParam | ContentBlockParam)[] = message.content + .map(c => { + if (c.type === Raw.ChatCompletionContentPartKind.Text) { + return { type: 'text' as const, text: c.text }; + } else if (c.type === Raw.ChatCompletionContentPartKind.Image) { + return rawContentToAnthropicContent(c); + } + return undefined; + }) + .filter(isDefined); + const validToolContent = toolContent.filter( + (c): c is TextBlockParam | { type: 'image'; source: { type: 'base64'; media_type: 'image/jpeg' | 'image/png' | 'image/gif' | 'image/webp'; data: string } } => + c.type === 'text' || c.type === 'image' + ); + unmergedMessages.push({ + role: 'user', + content: [{ + type: 'tool_result', + tool_use_id: message.toolCallId, + content: validToolContent, + }], + }); + } + break; + } + } + } + + const mergedMessages: MessageParam[] = []; + for (const message of unmergedMessages) { + const lastMessage = mergedMessages[mergedMessages.length - 1]; + if (lastMessage && lastMessage.role === message.role) { + const prevContent = Array.isArray(lastMessage.content) ? lastMessage.content : [{ type: 'text' as const, text: lastMessage.content }]; + const newContent = Array.isArray(message.content) ? message.content : [{ type: 'text' as const, text: message.content }]; + lastMessage.content = [...prevContent, ...newContent]; + } else { + mergedMessages.push(message); + } + } + + const systemText = systemParts.join('\n'); + return { + messages: mergedMessages, + ...(systemText ? { system: [{ type: 'text', text: systemText }] } : {}), + }; +} + +function rawContentToAnthropicContent(part: Raw.ChatCompletionContentPart): ContentBlockParam | ThinkingBlockParam | RedactedThinkingBlockParam | undefined { + switch (part.type) { + case Raw.ChatCompletionContentPartKind.Text: + if (part.text.trim()) { + return { type: 'text', text: part.text }; + } + return undefined; + case Raw.ChatCompletionContentPartKind.Image: + // TODO: Add support for image content blocks in Messages API + return undefined; + case Raw.ChatCompletionContentPartKind.Opaque: { + if (part.value && typeof part.value === 'object' && 'type' in part.value) { + const opaqueValue = part.value as { type: string; thinking?: { id: string; text?: string; encrypted?: string } }; + if (opaqueValue.type === 'thinking' && opaqueValue.thinking) { + if (opaqueValue.thinking.encrypted) { + return { + type: 'redacted_thinking', + data: opaqueValue.thinking.encrypted, + }; + } else if (opaqueValue.thinking.text) { + return { + type: 'thinking', + thinking: opaqueValue.thinking.text, + signature: '', + }; + } + } + } + return undefined; + } + default: + return undefined; + } +} + +export async function processResponseFromMessagesEndpoint( + instantiationService: IInstantiationService, + telemetryService: ITelemetryService, + logService: ILogService, + response: Response, + expectedNumChoices: number, + finishCallback: FinishedCallback, + telemetryData: TelemetryData +): Promise> { + const body = (await response.body()) as ClientHttp2Stream; + return new AsyncIterableObject(async feed => { + const requestId = response.headers.get('X-Request-ID') ?? generateUuid(); + const ghRequestId = response.headers.get('x-github-request-id') ?? ''; + const processor = instantiationService.createInstance(AnthropicMessagesProcessor, telemetryData, requestId, ghRequestId); + const parser = new SSEParser((ev) => { + try { + const trimmed = ev.data?.trim(); + if (!trimmed || trimmed === '[DONE]') { + return; + } + + logService.trace(`SSE: ${trimmed}`); + const parsed = JSON.parse(trimmed) as Partial; + const type = parsed.type ?? ev.type; + if (!type) { + return; + } + const completion = processor.push({ ...parsed, type } as AnthropicStreamEvent, finishCallback); + if (completion) { + feed.emitOne(completion); + } + } catch (e) { + feed.reject(e); + } + }); + + for await (const chunk of body) { + parser.feed(chunk); + } + }, () => { + body.destroy(); + }); +} + +export class AnthropicMessagesProcessor { + private textAccumulator: string = ''; + private toolCallAccumulator: Map = new Map(); + private thinkingAccumulator: Map = new Map(); + private completedToolCalls: Array<{ id: string; name: string; arguments: string }> = []; + private messageId: string = ''; + private model: string = ''; + private inputTokens: number = 0; + private outputTokens: number = 0; + private cachedTokens: number = 0; + + constructor( + private readonly telemetryData: TelemetryData, + private readonly requestId: string, + private readonly ghRequestId: string, + ) { } + + public push(chunk: AnthropicStreamEvent, _onProgress: FinishedCallback): ChatCompletion | undefined { + const onProgress = (delta: IResponseDelta): undefined => { + this.textAccumulator += delta.text; + _onProgress(this.textAccumulator, 0, delta); + }; + + switch (chunk.type) { + case 'message_start': + if (chunk.message) { + this.messageId = chunk.message.id; + this.model = chunk.message.model; + this.inputTokens = chunk.message.usage.input_tokens; + this.outputTokens = chunk.message.usage.output_tokens; + if (chunk.message.usage.cache_read_input_tokens) { + this.cachedTokens = chunk.message.usage.cache_read_input_tokens; + } + } + return; + case 'content_block_start': + if (chunk.content_block?.type === 'tool_use' && chunk.index !== undefined) { + this.toolCallAccumulator.set(chunk.index, { + id: chunk.content_block.id || generateUuid(), + name: chunk.content_block.name || '', + arguments: '', + }); + onProgress({ + text: '', + beginToolCalls: [{ name: chunk.content_block.name || '' }] + }); + } else if (chunk.content_block?.type === 'thinking' && chunk.index !== undefined) { + this.thinkingAccumulator.set(chunk.index, { + thinking: '', + signature: '', + }); + } + return; + case 'content_block_delta': + if (chunk.delta) { + if (chunk.delta.type === 'text_delta' && chunk.delta.text) { + return onProgress({ text: chunk.delta.text }); + } else if (chunk.delta.type === 'thinking_delta' && chunk.delta.thinking && chunk.index !== undefined) { + const thinking = this.thinkingAccumulator.get(chunk.index); + if (thinking) { + thinking.thinking += chunk.delta.thinking; + } + return onProgress({ + text: '', + thinking: { + id: `thinking_${chunk.index}`, + text: chunk.delta.thinking, + } + }); + } else if (chunk.delta.type === 'signature_delta' && chunk.delta.signature && chunk.index !== undefined) { + const thinking = this.thinkingAccumulator.get(chunk.index); + if (thinking) { + thinking.signature += chunk.delta.signature; + } + // Don't report signature deltas to the user + } else if (chunk.delta.type === 'input_json_delta' && chunk.delta.partial_json && chunk.index !== undefined) { + const toolCall = this.toolCallAccumulator.get(chunk.index); + if (toolCall) { + toolCall.arguments += chunk.delta.partial_json; + } + } + } + return; + case 'content_block_stop': + if (chunk.index !== undefined) { + const toolCall = this.toolCallAccumulator.get(chunk.index); + if (toolCall) { + this.completedToolCalls.push(toolCall); + onProgress({ + text: '', + copilotToolCalls: [{ + id: toolCall.id, + name: toolCall.name, + arguments: toolCall.arguments, + }], + }); + this.toolCallAccumulator.delete(chunk.index); + } + const thinking = this.thinkingAccumulator.get(chunk.index); + if (thinking && thinking.signature) { + onProgress({ + text: '', + thinking: { + id: `thinking_${chunk.index}`, + encrypted: thinking.signature, + } + }); + this.thinkingAccumulator.delete(chunk.index); + } + } + return; + case 'message_delta': + if (chunk.usage) { + this.outputTokens = chunk.usage.output_tokens; + } + return; + case 'message_stop': + return { + blockFinished: true, + choiceIndex: 0, + model: this.model, + tokens: [], + telemetryData: this.telemetryData, + requestId: { + headerRequestId: this.requestId, + gitHubRequestId: this.ghRequestId, + completionId: this.messageId, + created: Date.now(), + deploymentId: '', + serverExperiments: '' + }, + usage: { + prompt_tokens: this.inputTokens, + completion_tokens: this.outputTokens, + total_tokens: this.inputTokens + this.outputTokens, + prompt_tokens_details: { + cached_tokens: this.cachedTokens, + }, + completion_tokens_details: { + reasoning_tokens: 0, + accepted_prediction_tokens: 0, + rejected_prediction_tokens: 0, + }, + }, + finishReason: FinishedCompletionReason.Stop, + message: { + role: Raw.ChatRole.Assistant, + content: this.textAccumulator ? [{ + type: Raw.ChatCompletionContentPartKind.Text, + text: this.textAccumulator + }] : [], + ...(this.completedToolCalls.length > 0 ? { + toolCalls: this.completedToolCalls.map(tc => ({ + id: tc.id, + type: 'function' as const, + function: { + name: tc.name, + arguments: tc.arguments + } + })) + } : {}) + } + }; + case 'error': { + const errorMessage = (chunk as unknown as { error?: { message?: string } }).error?.message || 'Unknown error'; + return onProgress({ + text: '', + copilotErrors: [{ + agent: 'anthropic', + code: 'unknown', + message: errorMessage, + type: 'error', + identifier: undefined + }] + }); + } + } + } +} + + diff --git a/src/platform/git/common/gitService.ts b/src/platform/git/common/gitService.ts index 8b8413b66e..ec0836c820 100644 --- a/src/platform/git/common/gitService.ts +++ b/src/platform/git/common/gitService.ts @@ -59,6 +59,9 @@ export interface IGitService extends IDisposable { diffIndexWithHEADShortStats(uri: URI): Promise; fetch(uri: URI, remote?: string, ref?: string, depth?: number): Promise; getMergeBase(uri: URI, ref1: string, ref2: string): Promise; + + createWorktree(uri: URI, options?: { path?: string; commitish?: string; branch?: string }): Promise; + deleteWorktree(uri: URI, path: string, options?: { force?: boolean }): Promise; } /** diff --git a/src/platform/git/vscode/git.d.ts b/src/platform/git/vscode/git.d.ts index a14173e3b0..d2c6dbba2d 100644 --- a/src/platform/git/vscode/git.d.ts +++ b/src/platform/git/vscode/git.d.ts @@ -281,6 +281,13 @@ export interface Repository { commit(message: string, opts?: CommitOptions): Promise; merge(ref: string): Promise; mergeAbort(): Promise; + + applyStash(index?: number): Promise; + popStash(index?: number): Promise; + dropStash(index?: number): Promise; + + createWorktree(options?: { path?: string; commitish?: string; branch?: string }): Promise; + deleteWorktree(path: string, options?: { force?: boolean }): Promise; } export interface RemoteSource { diff --git a/src/platform/git/vscode/gitServiceImpl.ts b/src/platform/git/vscode/gitServiceImpl.ts index f11573aa3b..f2e66f974d 100644 --- a/src/platform/git/vscode/gitServiceImpl.ts +++ b/src/platform/git/vscode/gitServiceImpl.ts @@ -229,6 +229,18 @@ export class GitServiceImpl extends Disposable implements IGitService { return repository?.getMergeBase(ref1, ref2); } + async createWorktree(uri: URI, options?: { path?: string; commitish?: string; branch?: string }): Promise { + const gitAPI = this.gitExtensionService.getExtensionApi(); + const repository = gitAPI?.getRepository(uri); + return await repository?.createWorktree(options); + } + + async deleteWorktree(uri: URI, path: string, options?: { force?: boolean }): Promise { + const gitAPI = this.gitExtensionService.getExtensionApi(); + const repository = gitAPI?.getRepository(uri); + return await repository?.deleteWorktree(path, options); + } + async initialize(): Promise { if (this._isInitialized.get()) { return; diff --git a/src/platform/github/common/githubService.ts b/src/platform/github/common/githubService.ts index 89bd84e07d..1c96b74ea1 100644 --- a/src/platform/github/common/githubService.ts +++ b/src/platform/github/common/githubService.ts @@ -10,7 +10,7 @@ import { ICAPIClientService } from '../../endpoint/common/capiClient'; import { ILogService } from '../../log/common/logService'; import { IFetcherService } from '../../networking/common/fetcherService'; import { ITelemetryService } from '../../telemetry/common/telemetry'; -import { addPullRequestCommentGraphQLRequest, closePullRequest, getPullRequestFromGlobalId, makeGitHubAPIRequest, makeGitHubAPIRequestWithPagination, makeSearchGraphQLRequest, PullRequestComment, PullRequestSearchItem, SessionInfo } from './githubAPI'; +import { addPullRequestCommentGraphQLRequest, closePullRequest, getPullRequestFromGlobalId, makeGitHubAPIRequest, makeSearchGraphQLRequest, PullRequestComment, PullRequestSearchItem, SessionInfo } from './githubAPI'; export type IGetRepositoryInfoResponseData = Endpoints["GET /repos/{owner}/{repo}"]["response"]["data"]; @@ -120,10 +120,6 @@ export interface RemoteAgentJobPayload { custom_agent?: string; } -interface GetCustomAgentsResponse { - agents: CustomAgentListItem[]; -} - export interface CustomAgentListItem { name: string; repo_owner_id: number; @@ -199,7 +195,7 @@ export interface IOctoKitService { /** * Returns the information for a specific Copilot session. */ - getSessionInfo(sessionId: string): Promise; + getSessionInfo(sessionId: string): Promise; /** * Posts a new Copilot agent job. @@ -209,17 +205,17 @@ export interface IOctoKitService { name: string, apiVersion: string, payload: RemoteAgentJobPayload, - ): Promise; + ): Promise; /** * Gets a job by its job ID. */ - getJobByJobId(owner: string, repo: string, jobId: string, userAgent: string): Promise; + getJobByJobId(owner: string, repo: string, jobId: string, userAgent: string): Promise; /** * Gets a job by session ID */ - getJobBySessionId(owner: string, repo: string, sessionId: string, userAgent: string): Promise; + getJobBySessionId(owner: string, repo: string, sessionId: string, userAgent: string): Promise; /** * Adds a comment to a pull request. @@ -282,9 +278,9 @@ export interface IOctoKitService { */ export class BaseOctoKitService { constructor( - private readonly _capiClientService: ICAPIClientService, + protected readonly _capiClientService: ICAPIClientService, private readonly _fetcherService: IFetcherService, - private readonly _logService: ILogService, + protected readonly _logService: ILogService, private readonly _telemetryService: ITelemetryService ) { } @@ -305,47 +301,14 @@ export class BaseOctoKitService { return makeSearchGraphQLRequest(this._fetcherService, this._logService, this._telemetryService, this._capiClientService.dotcomAPIURL, token, query); } - protected async getCopilotSessionsForPRWithToken(prId: string, token: string) { - return makeGitHubAPIRequest(this._fetcherService, this._logService, this._telemetryService, 'https://api.githubcopilot.com', `agents/sessions/resource/pull/${prId}`, 'GET', token); - } - - protected async getSessionLogsWithToken(sessionId: string, token: string) { - return makeGitHubAPIRequest(this._fetcherService, this._logService, this._telemetryService, 'https://api.githubcopilot.com', `agents/sessions/${sessionId}/logs`, 'GET', token, undefined, undefined, 'text'); - } - - protected async getSessionInfoWithToken(sessionId: string, token: string) { - return makeGitHubAPIRequest(this._fetcherService, this._logService, this._telemetryService, 'https://api.githubcopilot.com', `agents/sessions/${sessionId}`, 'GET', token, undefined, undefined, 'text'); - } - - protected async postCopilotAgentJobWithToken(owner: string, name: string, apiVersion: string, userAgent: string, payload: RemoteAgentJobPayload, token: string) { - return makeGitHubAPIRequest(this._fetcherService, this._logService, this._telemetryService, 'https://api.githubcopilot.com', `agents/swe/${apiVersion}/jobs/${owner}/${name}`, 'POST', token, payload, undefined, undefined, userAgent, true); - } - - protected async getJobByJobIdWithToken(owner: string, repo: string, jobId: string, userAgent: string, token: string): Promise { - return makeGitHubAPIRequest(this._fetcherService, this._logService, this._telemetryService, 'https://api.githubcopilot.com', `agents/swe/v1/jobs/${owner}/${repo}/${jobId}`, 'GET', token, undefined, undefined, undefined, userAgent); - } - - protected async getJobBySessionIdWithToken(owner: string, repo: string, sessionId: string, userAgent: string, token: string): Promise { - return makeGitHubAPIRequest(this._fetcherService, this._logService, this._telemetryService, 'https://api.githubcopilot.com', `agents/swe/v1/jobs/${owner}/${repo}/session/${sessionId}`, 'GET', token, undefined, undefined, undefined, userAgent); - } - protected async addPullRequestCommentWithToken(pullRequestId: string, commentBody: string, token: string): Promise { return addPullRequestCommentGraphQLRequest(this._fetcherService, this._logService, this._telemetryService, this._capiClientService.dotcomAPIURL, token, pullRequestId, commentBody); } - protected async getAllOpenSessionsWithToken(nwo: string, token: string): Promise { - return makeGitHubAPIRequestWithPagination(this._fetcherService, this._logService, `https://api.githubcopilot.com`, 'agents/sessions', nwo, token); - } - protected async getPullRequestFromSessionWithToken(globalId: string, token: string): Promise { return getPullRequestFromGlobalId(this._fetcherService, this._logService, this._telemetryService, this._capiClientService.dotcomAPIURL, token, globalId); } - protected async getCustomAgentsWithToken(owner: string, repo: string, token: string): Promise { - const queryParams = '?exclude_invalid_config=true'; - return makeGitHubAPIRequest(this._fetcherService, this._logService, this._telemetryService, 'https://api.githubcopilot.com', `agents/swe/custom-agents/${owner}/${repo}${queryParams}`, 'GET', token, undefined, undefined, 'json', 'vscode-copilot-chat'); - } - protected async getPullRequestFilesWithToken(owner: string, repo: string, pullNumber: number, token: string): Promise { const result = await makeGitHubAPIRequest(this._fetcherService, this._logService, this._telemetryService, this._capiClientService.dotcomAPIURL, `repos/${owner}/${repo}/pulls/${pullNumber}/files`, 'GET', token, undefined, '2022-11-28'); return result || []; diff --git a/src/platform/github/common/octoKitServiceImpl.ts b/src/platform/github/common/octoKitServiceImpl.ts index 7ee15b78d6..e2d60385f3 100644 --- a/src/platform/github/common/octoKitServiceImpl.ts +++ b/src/platform/github/common/octoKitServiceImpl.ts @@ -2,6 +2,7 @@ * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import { RequestType } from '@vscode/copilot-api'; import { IAuthenticationService } from '../../authentication/common/authentication'; import { ICAPIClientService } from '../../endpoint/common/capiClient'; import { ILogService } from '../../log/common/logService'; @@ -46,67 +47,146 @@ export class OctoKitService extends BaseOctoKitService implements IOctoKitServic } async getCopilotSessionsForPR(prId: string): Promise { - const authToken = (await this._authService.getPermissiveGitHubSession({ createIfNone: true }))?.accessToken; - if (!authToken) { + try { + const authToken = (await this._authService.getPermissiveGitHubSession({ createIfNone: true }))?.accessToken; + if (!authToken) { + throw new Error('No authentication token available'); + } + const response = await this._capiClientService.makeRequest({ + method: 'GET', + headers: { + Authorization: `Bearer ${authToken}`, + } + }, { type: RequestType.CopilotSessions, prId }); + if (!response.ok) { + throw new Error(`Failed to fetch copilot sessions for PR ${prId}: ${response.statusText}`); + } + const data = await response.json() as { sessions?: SessionInfo[] }; + if (data && Array.isArray(data.sessions)) { + return data.sessions; + } + throw new Error('Invalid response format'); + } catch (e) { + this._logService.error(e); return []; } - const response = await this.getCopilotSessionsForPRWithToken( - prId, - authToken, - ); - const { sessions } = response; - return sessions; } async getSessionLogs(sessionId: string): Promise { - const authToken = (await this._authService.getPermissiveGitHubSession({ createIfNone: true }))?.accessToken; - if (!authToken) { + try { + const authToken = (await this._authService.getPermissiveGitHubSession({ createIfNone: true }))?.accessToken; + if (!authToken) { + throw new Error('No authentication token available'); + } + const response = await this._capiClientService.makeRequest({ + method: 'GET', + headers: { + Authorization: `Bearer ${authToken}`, + } + }, { type: RequestType.CopilotSessionLogs, sessionId }); + if (!response.ok) { + throw new Error(`Failed to fetch session logs for session ${sessionId}: ${response.statusText}`); + } + return response.text(); + } catch (e) { + this._logService.error(e); return ''; } - const response = await this.getSessionLogsWithToken( - sessionId, - authToken, - ); - return response; } - async getSessionInfo(sessionId: string): Promise { - const authToken = (await this._authService.getPermissiveGitHubSession({ createIfNone: true }))?.accessToken; - if (!authToken) { - throw new Error('No authentication token available'); - } - const response = await this.getSessionInfoWithToken( - sessionId, - authToken, - ); - if (typeof response === 'string') { - return JSON.parse(response) as SessionInfo; + async getSessionInfo(sessionId: string): Promise { + try { + const authToken = (await this._authService.getPermissiveGitHubSession({ createIfNone: true }))?.accessToken; + if (!authToken) { + throw new Error('No authentication token available'); + } + const response = await this._capiClientService.makeRequest({ + method: 'GET', + headers: { + Authorization: `Bearer ${authToken}`, + } + }, { type: RequestType.CopilotSessionDetails, sessionId }); + if (!response.ok) { + throw new Error(`Failed to fetch session info for session ${sessionId}: ${response.statusText}`); + } + const responseData = await response.text(); + if (typeof responseData === 'string') { + return JSON.parse(responseData) as SessionInfo; + } + throw new Error('Invalid response format'); + } catch (e) { + this._logService.error(e); + return undefined; } - return response; } - async postCopilotAgentJob(owner: string, name: string, apiVersion: string, payload: RemoteAgentJobPayload): Promise { - const authToken = (await this._authService.getPermissiveGitHubSession({ createIfNone: true }))?.accessToken; - if (!authToken) { - throw new Error('No authentication token available'); + async postCopilotAgentJob(owner: string, name: string, apiVersion: string, payload: RemoteAgentJobPayload): Promise { + try { + const authToken = (await this._authService.getPermissiveGitHubSession({ createIfNone: true }))?.accessToken; + if (!authToken) { + throw new Error('No authentication token available'); + } + const response = await this._capiClientService.makeRequest({ + method: 'POST', + body: JSON.stringify(payload), + headers: { + Authorization: `Bearer ${authToken}`, + } + }, { type: RequestType.CopilotAgentJob, owner, repo: name, apiVersion, payload }); + if (!response.ok) { + return { + status: response.status, + }; + } + return await response.json() as RemoteAgentJobResponse; + } catch (e) { + this._logService.error(e); + return undefined; } - return this.postCopilotAgentJobWithToken(owner, name, apiVersion, 'vscode-copilot-chat', payload, authToken); } - async getJobByJobId(owner: string, repo: string, jobId: string, userAgent: string): Promise { - const authToken = (await this._authService.getPermissiveGitHubSession({ createIfNone: true }))?.accessToken; - if (!authToken) { - throw new Error('No authentication token available'); + async getJobByJobId(owner: string, repo: string, jobId: string, userAgent: string): Promise { + try { + const authToken = (await this._authService.getPermissiveGitHubSession({ createIfNone: true }))?.accessToken; + if (!authToken) { + throw new Error('No authentication token available'); + } + const response = await this._capiClientService.makeRequest({ + method: 'GET', + headers: { + Authorization: `Bearer ${authToken}`, + } + }, { type: RequestType.CopilotAgentJob, owner, repo, jobId }); + if (!response.ok) { + throw new Error(`Failed to fetch job info for job ${jobId}: ${response.statusText}`); + } + return await response.json() as JobInfo; + } catch (e) { + this._logService.error(e); + return undefined; } - return this.getJobByJobIdWithToken(owner, repo, jobId, userAgent, authToken); } - async getJobBySessionId(owner: string, repo: string, sessionId: string, userAgent: string): Promise { - const authToken = (await this._authService.getPermissiveGitHubSession({ createIfNone: true }))?.accessToken; - if (!authToken) { - throw new Error('No authentication token available'); + async getJobBySessionId(owner: string, repo: string, sessionId: string, userAgent: string): Promise { + try { + const authToken = (await this._authService.getPermissiveGitHubSession({ createIfNone: true }))?.accessToken; + if (!authToken) { + throw new Error('No authentication token available'); + } + const response = await this._capiClientService.makeRequest({ + method: 'GET', + headers: { + Authorization: `Bearer ${authToken}`, + } + }, { type: RequestType.CopilotAgentJob, owner, repo, sessionId }); + if (!response.ok) { + throw new Error(`Failed to fetch job info for session ${sessionId}: ${response.statusText}`); + } + return await response.json() as JobInfo; + } catch (e) { + this._logService.error(e); + return undefined; } - return this.getJobBySessionIdWithToken(owner, repo, sessionId, userAgent, authToken); } async addPullRequestComment(pullRequestId: string, commentBody: string): Promise { @@ -118,11 +198,29 @@ export class OctoKitService extends BaseOctoKitService implements IOctoKitServic } async getAllOpenSessions(nwo: string): Promise { - const authToken = (await this._authService.getPermissiveGitHubSession({ createIfNone: true }))?.accessToken; - if (!authToken) { + try { + const authToken = (await this._authService.getPermissiveGitHubSession({ createIfNone: true }))?.accessToken; + if (!authToken) { + throw new Error('No authentication token available'); + } + const response = await this._capiClientService.makeRequest({ + method: 'GET', + headers: { + Authorization: `Bearer ${authToken}`, + } + }, { type: RequestType.CopilotSessions, nwo }); + if (!response.ok) { + throw new Error(`Failed to fetch copilot sessions for ${nwo}: ${response.statusText}`); + } + const data = await response.json() as { sessions?: SessionInfo[] }; + if (data && Array.isArray(data.sessions)) { + return data.sessions; + } + throw new Error('Invalid response format'); + } catch (e) { + this._logService.error(e); return []; } - return this.getAllOpenSessionsWithToken(nwo, authToken); } async getPullRequestFromGlobalId(globalId: string): Promise { @@ -134,15 +232,31 @@ export class OctoKitService extends BaseOctoKitService implements IOctoKitServic } async getCustomAgents(owner: string, repo: string): Promise { - const authToken = (await this._authService.getPermissiveGitHubSession({ createIfNone: true }))?.accessToken; - if (!authToken) { - return []; - } - const { agents } = await this.getCustomAgentsWithToken(owner, repo, authToken); - if (!Array.isArray(agents)) { + try { + const authToken = (await this._authService.getPermissiveGitHubSession({ createIfNone: true }))?.accessToken; + if (!authToken) { + throw new Error('No authentication token available'); + } + const response = await this._capiClientService.makeRequest({ + method: 'GET', + headers: { + Authorization: `Bearer ${authToken}`, + } + }, { type: RequestType.CopilotCustomAgents, owner, repo }); + if (!response.ok) { + throw new Error(`Failed to fetch custom agents for ${owner} ${repo}: ${response.statusText}`); + } + const data = await response.json() as { + agents?: CustomAgentListItem[]; + }; + if (data && Array.isArray(data.agents)) { + return data.agents; + } + throw new Error('Invalid response format'); + } catch (e) { + this._logService.error(e); return []; } - return agents; } async getPullRequestFiles(owner: string, repo: string, pullNumber: number): Promise { diff --git a/src/platform/networking/common/fetch.ts b/src/platform/networking/common/fetch.ts index e3cfb8eb57..13f16a9750 100644 --- a/src/platform/networking/common/fetch.ts +++ b/src/platform/networking/common/fetch.ts @@ -264,10 +264,20 @@ export interface OpenAiResponsesFunctionTool extends OpenAiFunctionDef { type: 'function'; } -export function isOpenAiFunctionTool(tool: OpenAiResponsesFunctionTool | OpenAiFunctionTool): tool is OpenAiFunctionTool { +export function isOpenAiFunctionTool(tool: OpenAiResponsesFunctionTool | OpenAiFunctionTool | AnthropicMessagesTool): tool is OpenAiFunctionTool { return (tool as OpenAiFunctionTool).function !== undefined; } +export interface AnthropicMessagesTool { + name: string; + description?: string; + input_schema: { + type: 'object'; + properties?: Record; + required?: string[]; + }; +} + /** * Options for streaming response. Only set this when you set stream: true. * diff --git a/src/platform/networking/common/networking.ts b/src/platform/networking/common/networking.ts index b89af7d6ee..749e7dea46 100644 --- a/src/platform/networking/common/networking.ts +++ b/src/platform/networking/common/networking.ts @@ -17,7 +17,7 @@ import { CustomModel, EndpointEditToolName } from '../../endpoint/common/endpoin import { ILogService } from '../../log/common/logService'; import { ITelemetryService, TelemetryProperties } from '../../telemetry/common/telemetry'; import { TelemetryData } from '../../telemetry/common/telemetryData'; -import { FinishedCallback, OpenAiFunctionTool, OpenAiResponsesFunctionTool, OptionalChatRequestParams, Prediction } from './fetch'; +import { AnthropicMessagesTool, FinishedCallback, OpenAiFunctionTool, OpenAiResponsesFunctionTool, OptionalChatRequestParams, Prediction } from './fetch'; import { FetcherId, FetchOptions, IAbortController, IFetcherService, Response } from './fetcherService'; import { ChatCompletion, RawMessageConversionCallback, rawMessageToCAPI } from './openai'; @@ -58,7 +58,7 @@ const requestTimeoutMs = 30 * 1000; // 30 seconds */ export interface IEndpointBody { /** General or completions: */ - tools?: (OpenAiFunctionTool | OpenAiResponsesFunctionTool)[]; + tools?: (OpenAiFunctionTool | OpenAiResponsesFunctionTool | AnthropicMessagesTool)[]; model?: string; previous_response_id?: string; max_tokens?: number; @@ -104,6 +104,12 @@ export interface IEndpointBody { text?: { verbosity?: 'low' | 'medium' | 'high'; }; + + /** Messages API */ + thinking?: { + type: 'enabled' | 'disabled'; + budget_tokens?: number; + }; } export interface IEndpointFetchOptions { diff --git a/src/platform/test/node/simulationWorkspaceServices.ts b/src/platform/test/node/simulationWorkspaceServices.ts index 680f13b412..f1a6304136 100644 --- a/src/platform/test/node/simulationWorkspaceServices.ts +++ b/src/platform/test/node/simulationWorkspaceServices.ts @@ -756,6 +756,14 @@ export class TestingGitService implements IGitService { async add(uri: URI, paths: string[]): Promise { return; } + + async createWorktree(uri: URI, options?: { path?: string; commitish?: string; branch?: string }): Promise { + return undefined; + } + + async deleteWorktree(uri: URI, path: string, options?: { force?: boolean }): Promise { + return; + } } export class TestingTerminalService extends Disposable implements ITerminalService { diff --git a/test/outcome/edit-inlinechatintent-inline.json b/test/outcome/edit-inlinechatintent-inline.json index cc69a1849b..6a9c00aeb8 100644 --- a/test/outcome/edit-inlinechatintent-inline.json +++ b/test/outcome/edit-inlinechatintent-inline.json @@ -2,225 +2,236 @@ { "name": "edit-InlineChatIntent [inline] [cpp] - edit for cpp", "requests": [ - "cc297f3dc1c1731de9eb179dc56da62d4db69c0f00338d36192b6f64fb00493f" + "784be3dd5c84974dc442e16ec4685ec10a38b5628bca9558649dda5a56023f13" ] }, { "name": "edit-InlineChatIntent [inline] [cpp] - edit for macro", "requests": [ - "4547bdaa5826446891c18047f2a44b36018c8e117dda8f9e8f5d309d6d13cca6" + "02c872bf5dee13ed873cc1c3f1ab2d151d33605773fe829912544d1b5d069bb2", + "06f6fe00ef030f1977303cf91e15947476bded82131180f25000d865987a20d5", + "7351c23b5e260e770c13139802812310c514ca1c537f31dc197d7a9fc83e8939" ] }, { "name": "edit-InlineChatIntent [inline] [csharp] - issue release#275: Inline Diff refinement causes massive duplication of code", "requests": [ - "2f610ee20822e0ce212e529e336478bb92e478979ef8f8f2c2948a3b8cab6ba7" + "5edf58f38fac23cadcb37fb3c5e547377f69cdf6c769a962e326baee536f666b" ] }, { "name": "edit-InlineChatIntent [inline] [css] - issue #6469", "requests": [ - "89245bf13a874198e5e685cc73edaba37b2e68b4b43806c3d7ecd4570719a102" + "c23d1113954aefaa5c886b27c7d4315eb735268bffb73e625fd8055945ac857e" ] }, { "name": "edit-InlineChatIntent [inline] [html] - issue #6614", "requests": [ - "198cf20a2d7cd6a0c3b60e297f55d5258627bbf1753281e2f97503508f115fe4", - "517ad2ec5080dff03efe93d183563e64de404eb94eda008cb1e9165b0ffcb8b2", - "9ba66f98ba77a96f5da70e1811f96103e98cafdf3cdc04e530c830e49d35aee7", - "acbde829d524d2019119b44b6cb8052cfe08fa2ef6ba50d96b7123f1978c3a8f" + "0801ccdb97da81aedb8d8d8b0a65ea62751a0381344f43788628885d2527621b", + "24a69dbba625619862baaae7b8fa9b378792c1aacde62e6cdc815c4be876336b", + "29d738475e33fb81c6b2b7c83c20779af42b4d5ef11d3a21c8a73973ff420a55", + "9b6e5c2188f6cc4bcc11172a387ab04feb327d4b6a4a63ba2d179ed777d83593", + "a65d29aaab1042ca0d44ff3b4283af879a144276bc88701efe4d626f7a8d1471" ] }, { "name": "edit-InlineChatIntent [inline] [javascript] - issue #2946: Inline chat markers don't work", "requests": [ - "1d4906e36a08d2f60754350e4a98ce8aa3c5e1b5a0b66f9b7caa78b1adda5d87", - "1d6efc7b3d39c277efc7543411b8e1bafcf75969314f918ea70eaefbed36e61b" + "1d6efc7b3d39c277efc7543411b8e1bafcf75969314f918ea70eaefbed36e61b", + "c5d4a2689a6b49b8b4f88cd36724e315c5bc4d011ec5cbfe4bff0ebc5fb836d4" ] }, { "name": "edit-InlineChatIntent [inline] [javascript] - issue #6329", "requests": [ - "4d9b5b3bb5776c62d9d3e0de30daa03d347f709d8bc463deb7e7aadc3d4d3661", - "5303e6a4062d0654ad72bb7f756a8e9b201ece5db8fed9203299b1a9afa44bdb", - "6b38326359e7a4fa73d4b243952068430691fc70de26a4d8ccac98c0256ec47a", - "7fde4d10eecfc6c495e6f1286441b9be91c1b85567010d6d80570513ba7e32c6", - "9e20c04b2fd70dce40af9b2db30b8bd3adbffc932c6dd41969bdabf39c5e61af", - "b113e346f0d253833757e57b13aca2ec28568b5fd7cc2802025bfa5b95613f12", - "c1b7c68bde76c1c5fa450dc0d41df60a3178dc2e03f7fcd5715352374880b3c8" + "28f9b8827367d2d841b80dfef65e1522adcbbdbc46bda1efd7072a39ee3a8c18", + "2e99c97bf4083a22ab0e54eb55156a62caec78d4b9b02d2710ce3321fe944e68", + "3974fc2b9f60acb80734eb30b56781ddc5fd0ee4e96f08254a79c388c1489000", + "80d417413558a2a7e813343e6258467ff8c7003d1b854de1c407664f0d5ee9f0", + "8ef73014f76c2fce814f039d141ca616b54bf56d9adecab31a66d5e1007f221e", + "ee77f28ac49784fef60fda9151878b6b4cdc2c83e2d9b5559a93b5566b02f205", + "f16520927c94d49e93576353dedb9ca09045028b86128f542d4eb286a5bd3b10", + "f5c60154f3bf29d4fb5dc614fc1271e02008c7979d5721264a5f5d38dcb83549" ] }, { "name": "edit-InlineChatIntent [inline] [javascript] - issue #6956", "requests": [ - "05f383ab1cbb7a754804df38fd83d49d69e6b01193b226e5b52b0c91f20b3ba3", - "4ff793791f6c29e62795613b7d4fc6312a8e3f97e547267ec48631ca4a06366f", - "6c1c6d9223d385265554fde45d90b3cdfebb60ea4f6fe02e063eccc32b7bae98", - "78b21a6df3e1be591894dc57c7377649d7a153f167f7c5faa76e521446045241", - "acfda67e24b2e4e6cd364ba2fe0d1b36732816d6fff0e056397d2bb4d618e778", - "b21018fdaccc39af2954345c83c9a94b6adeffa6ba3997015ab199f5df51b765", - "ba0eeb3029e0fe2cf03d58fa683237ee0aa44b1c672004d23285a4437518a5d9", - "bd95d2aa7c8bdfad42b4e416d1e58a66eea557bf5a5f4bfb01ba868aef0493fb", - "e3403fac2a98ec4258d20443b814ae2ab90a2121210d9288fc0805f4b652b1ca", - "e70ad578e493a942639d86b1b55e7b1c09c852d37db107a8e9dd56608c5d6638" + "16edacf97aa16d9c9b7a4a677df5110e3f85970d19ac8a44d06592c877bdddf7", + "1decf22eb8acaba757ababa660e5c99df3301fc0c87a8909fb0fb4908cf86b03", + "26d925962129048427ac4cd72a8a977fed1ac210fbf78f519f010c101f9e0b4f", + "59bfa38344d1efff9c06b21c7187c5b2bb55ca58354dfa7a0a0f28cc7a7a3ee0", + "78509346a7c9bfe72ecff487c2a6a734e3f483d12c0181b47814a7b5e4d92f4b", + "7b8d0ef32d30f588888707e1a19bd362737a40c49e64cec965239eca709ad9e0", + "8b5e23d8cea06e3a1c81cd9593acf504440931c8c45ab124acd16a77eaae1510", + "b39a1b9325a6a581de7ca2f175a2ae838fe8e2b42e22f4ed622c777e065fff74", + "d5d6774d6ddc6583c9f1bb2114bb60a6e35d0e34c5d89265228b07a48ecd18cb", + "dfd851ef42005102e477008eb057c8f5d1098c685b9d192d60e1da7eebf00199" ] }, { "name": "edit-InlineChatIntent [inline] [javascript] - Issue #7282", "requests": [ - "a8b36ce149f242c38cd4f4c9e8c788c2aa2ba5f85e765ab9118e6a869175c751", - "b3f51b4ed8c868eb99854b491890112fedf99f891357b6349c12fe3b9a17c041", - "e3b0c63c03b2d210399c569d848b8bdef0e6d2e3c88865610a2ed6018a7cdb03" + "d41fcf480601886bbb2c0cc86db8fbb944b3def002fa0ce61486bc722bffe69e" ] }, { "name": "edit-InlineChatIntent [inline] [json] - Inline chat does not leak system prompt", "requests": [ - "7e2255e17937141845d18ed70472adbce79a5ad9befc934e7ad898101a2a91bb" + "c6ee1990923af963fffdcedfa1116de88e7defe97e0a2be549ac02f5c821c530" ] }, { "name": "edit-InlineChatIntent [inline] [markdown] - issue #5899: make this code more efficient inside markdown", "requests": [ - "b6d9f28ec221485e80e2d582d36d45800df2aac7b2b01f90e1fb3db3d3d52f92" + "3248769fb720bcab5da7611c68d4c69797cdba90dbc275f7584fcd0fcaf68a87" ] }, { "name": "edit-InlineChatIntent [inline] [markdown] - merge markdown sections", "requests": [ - "37324dd98f12b68761d84457128a3b696f73adf6b92f454f3183817830f9fff9" + "e70f3103a50884560a706448d3f5763787078b4a48b4138dac46770b5da452cf" ] }, { "name": "edit-InlineChatIntent [inline] [python] - issue #1198: Multi-lingual queries throw off the inline response formatting", "requests": [ - "b826da85c8d3013c48882652e03055597d488e4f5349ee2fb06d131b79339f06" + "6912aa135e8ac78f7160b4ca4eebef250b9727beec2f1dbbd17590644d3160a1" ] }, { "name": "edit-InlineChatIntent [inline] [typescript] - Context Outline: TypeScript between methods", "requests": [ - "1b4c059a80c1d133b46392c573fc8c01e2968c235c066842d318d4d336e2fe06" + "db4959276c2e6b0e4ad120b856406682fa6ee6cfb7168d2b1f989d737714769e" ] }, { "name": "edit-InlineChatIntent [inline] [typescript] - Context Outline: TypeScript in method", "requests": [ - "1af224c35cbeb17577794b430e5953a3e7755c38d198dd0d52fccaf22eece49a", - "35ce4645c950812fac124754228706a878a9c34a775562476487d1c87f11ce89", - "5f5864b4a6cd47ae37cd2f7366dffb9499c47195fd780a1c2e6b7e6d6004c84b", - "d98af0d694e0cde6daf412a020a8131495759d5a8ddafcc70a7ea69a099eba2e" + "a2b6309207dd9c7f4eeac74a1f70a72aee7acf5fb47628767d67ddb477b31218" ] }, { "name": "edit-InlineChatIntent [inline] [typescript] - convert ternary to if/else in short function", "requests": [ - "3020828aebdbaab50e2d0ca16506344e17d9567f714026cf025cc58553e4bb39" + "4b4766eb5f4168282dec92609f6744f6ce943379ca2f95b966b9fe3222fa6454", + "d17d8a1dff67accf1d7ed713197e80073669dc827dd39199dbfa5a1aa5b4988e", + "fe0cbdfcab289948b1ec923b999a5975ca073a802a90ded9d3214cef1b05efbc" ] }, { "name": "edit-InlineChatIntent [inline] [typescript] - edit: add enum variant", "requests": [ "428086c020766539a303e1f031dbe79be77f058b2a2175228ac0c2807aa5885d", - "93eb14ef0847b3fdeb501b67666289c9fbb9a909214d74a954cb068d8873b1f3", - "d0f0c193a89a82c8170de0be69c7b56c73676c4752c39d23036ef60be4d2a778", - "eff59bdec811d3967d03a3354e00b935a799d30882a7490522bd7b4ec727624c" + "5dfe665ba32e1fb879b4d772224712a1ea83966f4b2b12e4eccdf7aee2a1bab3", + "746a569e3374d8e75abc93c77b7b2254ed9aa2c113f96257df7aaca2d7bc9a2f", + "e173b96bf97cde6853d27495c7b80def173d7995c2aea7fa6d02bf8cae73284e", + "face3f11fc502a247b7bd925922c230986842a3af71336ff531ede8ff4f549d0" ] }, { "name": "edit-InlineChatIntent [inline] [typescript] - edit: add toString1", "requests": [ - "0c3e88cf3cfcf47676fd14d6a920bb2e7b1e4b8bdcb4017ba32f10a3223dfcdb", - "457486a625f8e6651f708daff46de01cfb45dcda78bb408b6b5c83d33fd43820", - "78ff92cae2885c0d965d01fc32c9a4ae82aa8ad6bc116b7df0b4bafba6d08bb3", - "8168464ffa4b3f3e46cb45e9207e1720c3fbd578416547fc87a3381df642c0eb", - "bf5d30d6a4bb3a018d337292e01a07f145220fd1c3bd9559bb29f07a8b222817", - "daf7e6cf37b3b65afe201402bdd05956f6ffea476d5fa42e9e04a401525429bf" + "8bf6f22e73698fc6dd08119bf855e2813c69d90f4ace038e41dc9710f871f7d5", + "fbbd20b412e445e070b3e41c20deb93714c4fa71b7efcc44bac17513403d8789" ] }, { "name": "edit-InlineChatIntent [inline] [typescript] - edit: add toString2", "requests": [ - "d59bcec58931dc021ea4a0bf0e2ec5bc45d1dbd2928664241bfd539f208992ec", - "e4329de6ae229839226822f31c702eda20ffad310fe3f521bd9853b8f00bba6f" + "1ba879153b42296bfa25dde6fb66f9b47f23cd261713005802761c4975773c15", + "1ec876a32ceb87d7f1f899b32f5e7f2ea21840b9dd7d2fa90107ce84e7cf7aec", + "2337f89a97102355d1b758931d765c1388b48614b922b8e2e22ef4a20e16db83", + "34288d81490c81eac42e1d8e7f5b087bec19fb8b5509032664a9af76a2c7d29d", + "4b619c7e9fe776a1e1e81de7b2fa7c2ad311411d57227ddcd456c0b7ca7c83d1", + "64e20e67a986799fcdbd86450c01eb3e25e496a42487a424beffe70be7e8cf4b", + "a4c12276bf97521a3f420e4d06badcd63450e6553d9942b277d045d6794cfc28", + "b5f331bcb4729c79883b986b6ca520abdc86984befa90509defce6f217a182ab", + "c0a14f50ac8f57d13d281c4a6fcbd4be084364b38a43d56de5bbe20bd88c2016", + "cbe545d406449377332cb2bcb5f359427c3f6f64619ab1577d534c978e2efc1e", + "e7c49d8f403d56d6feebe85632c63fa65afdee27a63af87e6176ae21be5b10b8" ] }, { "name": "edit-InlineChatIntent [inline] [typescript] - edit: import assert", "requests": [ - "6363425f000122fa1ee7990532a8746ed19c7482e59814d7f614a3750545c031", - "b8a2dbf2e114ad169628cf1e1199475f42372774d22824212ad6dbfa270612d3", - "c96146d14f37dabb4e71b1ebf9067682f5961d089fd6b8f44762c8343f2adc7d", - "d416a1f84a946e86a8df35dab7ec4c13089e1bfe7377315980b12250d64b0988" + "0e893eb4214912fb51503636dafd7c45dc1efc3a941db00d08a069558e70d211", + "3a48c0a43137c25a1b5419aaec4d4de93be29e74b2574b4878a980d0bbc230eb", + "48ede68722562931aa121c60208391a564e7080c25373a68096210ba2d619602", + "7dc770d3e027d2346a8dd7d7021c6dca7d2988175a978126cb1941cf3a345f4d", + "b7189d0023d000bc76ed8018c6c0a844c0887b5042e763afb2d0aeda89d745b4", + "b72f7e81b4e1d651173e5ead99f88e51fe43e3457e35cd9abe25625f076ecf44", + "c6f17b68fcd2eaf7475addc97dab49bc94789aeff7094145126ce404dfbb5c85", + "fc1434415f97dd7dac13902458fe5c58b622f411da5f3b6b6419a053c2c50b5d" ] }, { "name": "edit-InlineChatIntent [inline] [typescript] - edit: import assert 2", "requests": [ - "0f0f1f8e752ad22f622a1a4d10f83e00546f5ff8d48256cec30990437d2d305a", - "86c2c0820963b800aa82f741b59c042e69d0bc441a02f6d024b3efdbfc6499c2", + "28ae7724ff3d07d13a8bd5c666f680aee232626e1a5eb7a337515f9fdebc3673", + "30b31dd37d45890a877a5208e123808c0a4c3fc6c83083b4730ffec4190b9917", + "45b4b87c1abf8b56b4996a86b76265bb9bcd802de356489f5605ebfe2b9cecc5", + "4e964654357e62217b1061297b5a75ae5108e3d23b17f533dfcb098259b9bde4", "8a081528063ecd58d0da5be1246da958bd7fbb0ee39a027b77c45041c47a3ef3", - "925f6de1f92bb8bc55e94b4f28603350bdefeb1e268277500d96a0075690c1e2", - "b9ca38e7618de6e40cb76756f187354f763428e81595b700d11e59ee57bcdcd4", - "e325993c6eb775797c19ef7cfb36a04052c55d71be0093fa2848ddfc1bd672be", - "f4271f75110954c6bcba2a573fc8772cd455b4d2faf4a395df7cbb1cf1cbd76d" + "9cce31cb02110a9d8e3f3c4ed8dff1b5d1118c9d30a1fe1f46d08b97288ab036", + "a876045d43a9bb3a28454317e401dc90e86c0e3fc92d12d1e51d9ef9574787a6" ] }, { "name": "edit-InlineChatIntent [inline] [typescript] - Inline chat touching code outside of my selection #2988", "requests": [ - "edc10e9e09fa5720be0f2357e0c8216266408a3a6339367a76260e60a8ed3e78" + "26d2dff159edc73ed75ed487d3d8502870282ee9ad58b8245de78894e76e9f60", + "6643b8f29a93e052e64c1c6c2907345bc4d548fc4cc65239e04ae35beb2ecf8d", + "95e8f30d95c6556240da75658683f08364d2512ddfaddc3d170f570e5718c9fb", + "b0f82c8d069063dae8df65be31b94aa3a293028b04f2c8ce192786a95f034ff2", + "ebed110450ff85b447747c37a083f8ce4af09f420746f8ee4d1ac7378d006227" ] }, { "name": "edit-InlineChatIntent [inline] [typescript] - Inline chat touching code outside of my selection #2988 with good selection", "requests": [ - "a90b285723b45c0b924f80b5406db5e47a8d43d9c7fa946cdda72ea6c4d6d273" + "1f118ade007a558ca796f5aeef389d0dd916441bf3258ff8e3464bdb0800aebb" ] }, { "name": "edit-InlineChatIntent [inline] [typescript] - issue #2431: Inline Chat follow-up tweak ends up in noop text-only answer", "requests": [ - "0fca2f41ee2d44c4d1fc6ef29b329f7e3621206f5d983296e455589df4b5b47e", - "309bd7e9f9967a4174c03d2d9b96f4fa64659cccd0401441f716083a2891bc1a", - "77012e1db147f3b58c0e0c079fd18736f3437cebc766bf06bdd9643bb5b8f070", - "a30e023668c918e86d7b9d5319586e2ecbb86547761e47c41ed01892e19bfb30", - "b9f13a00556dda87696418442da5a035958985d309baa525ea6d4df82a07449e", - "be21de1e3b5a57a95c97ed987f045bdfc0dc8db9ff06a465c3bd2cd3af19dba1", - "ca96a87ab196583f032fe267359f7c8433c57fd02a57ddb8ef8396d4edd3c93e", - "d47461eb5eef31fecfe59f4cd2a336419388754404376913fd0555421a79e19b", - "e4303b22353458230b3fc27510335514fe1f2b848d1e2fceb32c8c8c94076c33", - "f7f80e90728d2458164013dd7087a4c66dc05cb311dca09565961ddfeced118c", - "fda45c7191fc27d2aa3b8a3640c85a2d7fd69cf9f4fb1df0d5aa07183dead62b" + "03a8a1a6a02b45cdf1ffee29e32d08ccbbde525add26625e95ce650d4a7754bb", + "285e5f4f4bfade07753fea9dc0f9e688977005eaaf5b10ad356c721e77fda2af", + "47b573a465d2ba87dc74a2543739fa82d224bb759bd51e49aca4fb318d97bdbc", + "5c74ff0c6888412e52c2bee8df993f45144263c6eca75f87dade3b39e64c043d", + "5f10981b5636d053bed682b4a1e83ddce4e3dc6cc3b8f659482217fbad41244b", + "b04ef3c31183b9c047d3ae31316ed65981d27a93a726c006e7ed60dea35228d8", + "b560434f47eb9f01a94f12eaf044cba6c29001762495924a461e0318588ae331", + "bb63506c8fe8e9a6e2f0227a6f3b1d909a9846af15632a768a6364618b9ff6fa", + "d4ff57a1273356cc53441bd526ca2bec0e0eed58a1fdbca29e3330c72d11bba6", + "e42fabead23796bdca52716b9b969392cefea38e71245ed2f5f6276d63268259", + "f8e837f69c5de15a32a01017aa4faf14ffd5ed8c564d6f69b36e20c4ada3a8fe", + "fe72722fb5a69cff12b32a955b4e5791f35ad98f8acc1c4e6cb6a04eb4af330a" ] }, { "name": "edit-InlineChatIntent [inline] [typescript] - issue #246: Add comment sends request to sidebar", "requests": [ - "1a7ad62c0997917329ee23bdaa410b909f6fc895e84c86aa63c98ef6130e9a78" + "4c1bd282532ec249afcac59fbda1eb92662707c03d898859fa6bca560eb5f21c", + "8605439e67fe145e359d05fd3f35b130e02958573dbd4ac262b950d32b185733" ] }, { "name": "edit-InlineChatIntent [inline] [typescript] - issue #3257: Inline chat ends up duplicating code", "requests": [ - "477698b9ab73ce15bc5cc4c0767ab444a2c7cf383ba3bad7fae7f4d850767c65", - "4ce77c39ba683552961f3b9e1c67ab7e01bf0a2f3c4df0cd75c25c05aa83a83e", - "5c34c6b4a7069f56b30c9a1cbc6fa902bb4b3d362a7a0f48af9b80a27da5549d", - "8db685dfaa006e0b5502324d489b864cfdc7d3228c5fa81d995df1c74cd15a71", - "91b501fcdfc77baa4b7c2371ecbab3b22bf19eb2017a8b46eb0060e004d27c2a", - "962d18c60430101524883de63c9bebbb047fbd3163acafc383d2d26dc46d727a", - "97317b0e6bdbda7d778bbeb3819e4344b5d6825d0dd3fe3e09fe74583897bd8d", - "9c994645405b5d97650e7f5504814dc45371dcbee95cb288f2f5c695ff6dac0b", - "bfc55948de4538ca3ecee0e1344fae0209b9693579cb000b8d07ca80af3baac5", - "d28c18b1fcc36761a407fbe602d32ddf7b83bc78d15ae78862cd94601965496f", - "da4f54dd6285f230dc710b93eb29c4872c8e111448d8aee7ee21c414fee9b570" + "078bace09f3fb8e31bc251fad193c93d7c4a9bbeeb3353f3d090b55867f297ac", + "0b58fae162590727d3256fdab4c66ac4e476bdf6a84259d4c5c29b111a56c783", + "24efd2ac2c8e33624e9aaaa1b91a351ce9f7336747df303de3818ce1f8fff956", + "889a476584d90ca08df8dca82a2772f7a354f03df374553e09baf225a2b15b31", + "fc16eac0acf6bfd7e61489216f978cce7606f619c9fc024bc7e38258d8e99ba7" ] }, { "name": "edit-InlineChatIntent [inline] [typescript] - issue #3575: Inline Chat in function expands to delete whole file", "requests": [ - "76142f81746ff026167caaa3dde58cd57c6ab1898eeb19d9c528c76273c96f4d" + "17ff2df77ea71d17d85ca36f8c7f625fb0759a311254f3a79a9609dbc1d62c3f" ] }, { @@ -230,7 +241,7 @@ { "name": "edit-InlineChatIntent [inline] [typescript] - issue #404: Add a cat to a comment", "requests": [ - "9116d98aa54bb62ed79069f448fed4c636592d51bd87b1e771e9b3e80e539c01" + "c06ccf36d61cb8fd4cadf4cdafa6cf1dbf4e21bbff38a544c8658f924df89c4b" ] }, { @@ -240,126 +251,126 @@ { "name": "edit-InlineChatIntent [inline] [typescript] - issue #4149: If ChatGPT makes the request, send only the first 20 episodes", "requests": [ - "22d25f9b2008d8ebdcb5fa878bb3b814cd68ce1494b9bcc9192934f9d5c939e1", - "36c886ee35c4eea4d2441eeb23859b59017593630fe427c8bc5e2245b3aa46dd", - "861e659f27feae785dca7f09add67df103816a97d29c4fa38c3049fdb65f5f18", - "d277490fd5a107edd28337669d1c042ae41a5ed4f2dc508f2c7fcd39babf737c", - "e6a2e34f491405ebec3c81eff67ce0b10601bef1dba457fc20082e760d268281", - "f507231c0351f5f003b7beadf58b5a3089e81af7b5608dbd7a491411717e6461", - "fa18f1f173d03f577fd2a0f635cf92579d694ebdfa22c6e1839d655713f9d38e" + "052d5a98eec35970ffc06b2eb751ae81ddd16f56d6f72e39d9b21e733b34843f", + "2bf4fe818e224cc5e778461173c82d84527e72cdace5f9ba8581b3167949755f", + "61847e7f84d372ba105895e33655c4fc4a5961946e3ac2a1d06191537357e7f3", + "721c65b5a91fe03b827905952b0228580a0b6830278cc3e935e61f49316ac49d", + "92b5639bf2ff819070022805f55dea957b7115d5914c88ef96672bbf78b3b4d8", + "cc370f712d1e50edcef8bce4632d31d75c93385aae1c5b9c38817799fd7c0390", + "e9878577a3f7b9172410275cc66588700df0c848e65904b8484344c933386461", + "f967dd63849397dea57420b902fc0f335215bd8f14a37bdf944d137c6945fa1b" ] }, { "name": "edit-InlineChatIntent [inline] [typescript] - issue #4151: Rewrite the selection to use async/await", "requests": [ "4a14193e83e219f22c2d5cc39183bb6020695300ce00b8e36c352c1451cd7fec", - "c51b3c5d74b09801d717121e3e82706b0da538deabfa9705c00f065eecf04783" + "c2ef64f9390e64e1a9fbd2af14a8a1d771520d514b132b1265f6de05f603ecc5" ] }, { "name": "edit-InlineChatIntent [inline] [typescript] - issue #4302: Code doesn't come with backticks", "requests": [ - "ce9d9f7585de8239ceb16a2687c818adaac1335d4fa8c3916f10e274b6a385fb" + "1bf6940ebe0f8b2215806ec82c8237afef32f05f442e145a941b3ba087192fbd" ] }, { "name": "edit-InlineChatIntent [inline] [typescript] - issue #5710: Code doesn't come with backticks", "requests": [ - "bbc3d06e918d6011cca6eef61b3fc681f71a79e7b7edac75339904db76a0baf7" + "11472ac1206cf536390c9d35b09b4c8f5f1b16de8e6097e4b4c2b1832e349e8b" ] }, { "name": "edit-InlineChatIntent [inline] [typescript] - issue #5755: Inline edits go outside the selection", "requests": [ - "ddea5019c110557709f043f35055ffc73a7949a24a62b27b4d409283d68eeb28" + "00a59ff37b976d5ffa4aae04f3f4daaec4ab2682fdf5645cb7efa69d9b356359" ] }, { "name": "edit-InlineChatIntent [inline] [typescript] - issue #6059", "requests": [ - "85102bdf8998d3a2476e175a6774b7f0b38a5c8aa28230fd8a80c6b0aabd4fe8" + "782f4c975c99c2323c67a2c1b0ec6ece2cbdcc90d2f442222fbc21236a01b82c" ] }, { "name": "edit-InlineChatIntent [inline] [typescript] - issue #6276", "requests": [ - "42f8db3851765b4ba7938034dea204fc210e6896b1e3c3f893839b6aa67b797a", - "4432a3fdb4ebaf5496c2d72449fece526303fed7edd2f333f321aa153941e9fc", - "67aa688136111ee392a559e532671fbbd67c720fafd84f980421582d05d7ee07", - "67d29f7954392099a07c4045d12024d251078badac7a422f5f82a52b8a0489e1", - "7f8c2db24ec95dc384ac37fc7bd3758dda8c0bd0934434cb097e878aa1f31844", - "849814e1502e90ae927cbc620086bf132549a51ca0d52b8f380c9697b5a51d37", - "f56a172ed91bb5b1f4509ac7a16c430a5e7d36556dbef2f3b5c7283baea04e0a", - "f89ae88c36a80ed066916090b14f70376991e103979e5b78dfc25f3ae9715529", - "fdd7d7e236318b714701f11cd4cb64bea09599c87865f38754c9d6d7234cef92" + "4929903d9d1e9ccf8d10b54c112b6573f2606da6e0b91abcc66737feaa440758" ] }, { "name": "edit-InlineChatIntent [inline] [typescript] - issue #6973", "requests": [ - "0ad4339f913ad91aa8dd26c9679428038f66ba99dc938447b17af8daf60d09b0", - "487b490d842d87f15ce3a324d9d19d327d713c463266ca92a6aad7608434e105", - "c83bb3f64d852d866a71c86ba03d5f09b1af06f55565a42f96c594fa5f322087" + "8adf32a98dc07e3fc9e8e2035620326549854815438e74ca9bc2e6fd859536f4", + "9cfbe9f56aa38fe0bcf90a02f8a01fedcdf48d06969e12f1f3c4ff64a9184796" ] }, { "name": "edit-InlineChatIntent [inline] [typescript] - issue #7202", "requests": [ - "976b78b5412bde6deaaeaeabc9385ee468b0f60db53a7ed8475128df1f38e7c8" + "6884220f8ea75ed888c392149e578c1948c55bb6df4f3d721459a17411cbd36b" ] }, { "name": "edit-InlineChatIntent [inline] [typescript] - issue #7660", "requests": [ - "4536e10a0c80d70c4413504e1356eb4f45e002929484d15fb997e4a1bab4e14a" + "9b31de1bc1dc811bcd8960ece65a35429ac13e97f7c593370b6aa6f53deeaa8e" ] }, { "name": "edit-InlineChatIntent [inline] [typescript] - Issue #7996 - use entire context window", "requests": [ - "803d0ce2795a87b1085cf8f79c8d6d42bc15b7711b1d0d8c24aa9d2a4a96bb80" + "43cd1468a5101adb36f29dc44ca2252ec5c2fb810ae2e44a408b15a089862a7a" ] }, { "name": "edit-InlineChatIntent [inline] [typescript] - Issue #8129 (no errors)", "requests": [ - "1c745f211a5e7ed72268654b7288c6de0f61e26299045d88804916121a7f1b5b", - "218ba8f7042fa96f33669cbb801921181e2e74992fcde42907804a425102731d", - "3e6057c6b4ff40da2e926bb2a0e645fecfa0e7b3068732b8614b5164f200d5f1", - "76c2839c637e396d4fa251bf8f02ba826a9a57cde727557336faacc459101cbf", - "7a4d89cf538d8128ddd182653977e0c0c12bd7d053bec4809c702d52233a6926", - "9dbc2c239300a1334505322f493393eea4a583d4e7c32df3e42f70739ca73b38", - "ab28f98acd84f4b886fb50895c632f0c60b63f9d23d03409bae4c7ba4dcaea07", - "b405691a24f9a1c514c1cadc810955f4fe7b591ff79c256e845bd173930005c0", - "bbea3a91761743237b405b2fa051786b7393932bb8117fb69aa9b20ee6b577c2", - "cee4155a02e7179c420492ff1d82122067615d325af38290c2c31baa5d8bcb15" + "09b20ae81a1c62f8a777cbf55dbd3de2895188eba793028e008dcf01612e38b5", + "248e152f8469be12c7e9547097675eaed984a3cb0cc0b888752528890e413897", + "3ac8c766caa32517e40bb3a1a60615923192e587ae62b4e3e72266470c58031f", + "5f0f79b9bd6b3edf71f4a3c9eae2c19ccf05c28c4e5af5f6d829f56e0739dc80", + "645ccf8f6489a93871ebbe03c4ee8adfa3cd52186f019825d30043f4c6f7dfce", + "67e4b57ec9cb17762bd0bf150f20e6fa45dd445eac8aa1008050dec7fc752aae", + "7ffa8d9699117b5cdb5f2c37090d61840ff0b6613894f017d506ac8f372c2d57", + "8aab799b81038577e6abefa65dd28a6753341dd59dc616f358a64386b9094340", + "c855af82997632bf8f296d502df30a19322b6e3fe423bb95b47b2f4d03894f9f", + "dcd657f2b58dc4a243f0d76764e7056ba64d77c27bd516b87a4a96db5f5b6825", + "f44d92abb9568f500825a444067ecd9af90dcc602dc2bf4ada648e648a64a69a" ] }, { "name": "edit-InlineChatIntent [inline] [typescript] - Issue #8129 (no syntax errors)", "requests": [ - "1c745f211a5e7ed72268654b7288c6de0f61e26299045d88804916121a7f1b5b", - "218ba8f7042fa96f33669cbb801921181e2e74992fcde42907804a425102731d", - "3e6057c6b4ff40da2e926bb2a0e645fecfa0e7b3068732b8614b5164f200d5f1", - "76c2839c637e396d4fa251bf8f02ba826a9a57cde727557336faacc459101cbf", - "7a4d89cf538d8128ddd182653977e0c0c12bd7d053bec4809c702d52233a6926", - "9dbc2c239300a1334505322f493393eea4a583d4e7c32df3e42f70739ca73b38", - "ab28f98acd84f4b886fb50895c632f0c60b63f9d23d03409bae4c7ba4dcaea07", - "b405691a24f9a1c514c1cadc810955f4fe7b591ff79c256e845bd173930005c0", - "bbea3a91761743237b405b2fa051786b7393932bb8117fb69aa9b20ee6b577c2", - "cee4155a02e7179c420492ff1d82122067615d325af38290c2c31baa5d8bcb15" + "09b20ae81a1c62f8a777cbf55dbd3de2895188eba793028e008dcf01612e38b5", + "248e152f8469be12c7e9547097675eaed984a3cb0cc0b888752528890e413897", + "3ac8c766caa32517e40bb3a1a60615923192e587ae62b4e3e72266470c58031f", + "5f0f79b9bd6b3edf71f4a3c9eae2c19ccf05c28c4e5af5f6d829f56e0739dc80", + "645ccf8f6489a93871ebbe03c4ee8adfa3cd52186f019825d30043f4c6f7dfce", + "67e4b57ec9cb17762bd0bf150f20e6fa45dd445eac8aa1008050dec7fc752aae", + "7ffa8d9699117b5cdb5f2c37090d61840ff0b6613894f017d506ac8f372c2d57", + "8aab799b81038577e6abefa65dd28a6753341dd59dc616f358a64386b9094340", + "c855af82997632bf8f296d502df30a19322b6e3fe423bb95b47b2f4d03894f9f", + "dcd657f2b58dc4a243f0d76764e7056ba64d77c27bd516b87a4a96db5f5b6825", + "f44d92abb9568f500825a444067ecd9af90dcc602dc2bf4ada648e648a64a69a" ] }, { "name": "edit-InlineChatIntent [inline] [typescript] - refactor forloop, but only selected one", "requests": [ - "1f66f9191abc073b35ce0c6be118789e1f360566af8871e742b2c24e38e75e76" + "fb9ab981ab190af6b1f0d89824ad510648529c6f1ab0e4b6c989f712ad962f1e" ] }, { "name": "edit-InlineChatIntent [inline] [typescriptreact] - issue #7487", "requests": [ - "7ccc587388e9ab2b9a0bc738a6a4e595d22bcd1216de5ae23a63cf988847530f" + "1736a21781fab7c1f8db5005762c71fd0fac662b12257dbb37701a19f36c8702", + "2c4f9c7ebc75638962493a9559ee09e851ca3d06b5eb8cd9242346be43446408", + "542c2ac94a3ed857e33658761f2e59b965d28e969bb4eb065f9f3c37ff53ceaa", + "5d7683d49d29a6c74d1dc6301add1aae47e20b636e06b620ac4583fbaace5a63", + "63411481bb59466ac59efe50d21cbbb421f2ab230ddb9ed60b61deb6815c9659", + "80e1b27a56ed8558b3e571690385fef8aadcef8f265e5f2864c4b78e18eb12b1", + "a1107061bf5d285331dea4e57e94deb6c8a4ca94eac36f8ce58406b465ec3254" ] } ] \ No newline at end of file diff --git a/test/outcome/fix-inlinechatintent-cpp-inline.json b/test/outcome/fix-inlinechatintent-cpp-inline.json index 84677bff66..ae25b741ee 100644 --- a/test/outcome/fix-inlinechatintent-cpp-inline.json +++ b/test/outcome/fix-inlinechatintent-cpp-inline.json @@ -2,7 +2,7 @@ { "name": "fix-InlineChatIntent (cpp) [inline] [cpp] - code fix for C++", "requests": [ - "4fd05c66345dadf69cffa61ca7732b412e34f083c8c62c93211d52fe303c9c9e" + "0e92f3e3618276f7851259e7ed0d454aed553e24ef2c78e4b8645dcdd6726378" ] } ] \ No newline at end of file diff --git a/test/outcome/fix-inlinechatintent-eslint-inline.json b/test/outcome/fix-inlinechatintent-eslint-inline.json index 4bbe0c0682..0d7d1ff8ac 100644 --- a/test/outcome/fix-inlinechatintent-eslint-inline.json +++ b/test/outcome/fix-inlinechatintent-eslint-inline.json @@ -2,200 +2,218 @@ { "name": "fix-InlineChatIntent (eslint) [inline] [typescript] - (AML-10-1) do not access hasOwnProperty", "requests": [ - "beccd7a8ce382d2b5c7af9e4a4abd0c36e5ede736de84b00aff25a2481ec8b79" + "0bf3bf09230d9eeb2842cbec38543d7b6a70deefa60baf2b65bf246725f9b8e3" ] }, { "name": "fix-InlineChatIntent (eslint) [inline] [typescript] - (AML-10-52) expected conditional expression", "requests": [ - "d53fca993d217ae6240b0fb20245d9a16f3493c94f882d4a4258c33beb5c5fd3" + "19296cb93325b3e8234a8ba13e34a878af714cb5f8aec1aa4e6f92399e6f1b8d" ] }, { "name": "fix-InlineChatIntent (eslint) [inline] [typescript] - (AML-17-10) unexpected constant condition 1", "requests": [ - "1f2f0fff82b048388122135e406353e788bbaf5fc30c1723e13be296083c6f98" + "e92c7f0f538c3f9c675e13b93916eeb17f16d0583841261b4c8858bfe8ae9418" ] }, { "name": "fix-InlineChatIntent (eslint) [inline] [typescript] - (AML-17-152) unreachable code", "requests": [ - "e90277af11e3238e3bb1507b61b098adfb443323a52035f6f4eeb3c8fef1026a" + "6f685ed26ce56d45947a7b84ecd94027838e667d9a888594406fa5be864b4f5b" ] }, { "name": "fix-InlineChatIntent (eslint) [inline] [typescript] - (AML-17-166) unexpected control character", "requests": [ - "d731313ab51b63837c1c555adedbd7f8fbf8e3cfbd0cd240b8bc13136fa516df" + "f94c58dc4f3029f524f47b13a59da561d9b50b0d50b5d4e6b8038d26d293175c" ] }, { "name": "fix-InlineChatIntent (eslint) [inline] [typescript] - (AML-17-243) unexpected constant condition 2", "requests": [ - "06ce4a09fccec099f0565183924dc57f24525d31bd2b61187575b0ac9f013abc" + "226842bf2c5b05575b2e739a8012bced18b0a99623146a1ca9d6388017e684a3", + "54f95eac5806f6ccbcef5a60ab88f104c94b3b008255fff58532b0706d192d8a", + "887430858eb55825e9656dbb400fe45b9ac1f624e5e731b46aab8af0818bfbd3", + "b01b5275f688613d1eee5027409edb0ea658622f48208afb5dde0d6e8202261a", + "d49fff58e5bb32f59ceb4d69377fa1ed7cd577f1e199bf2bd13f67bb52c88c9f", + "e0ed741f01170ddaca4c068e3a1bb869e4ea4742c7e49f74d775f140cbce9af2", + "f112cf60c395494b0d638879f1dd3965b04b996037a213165ff52b833b56abdb" ] }, { "name": "fix-InlineChatIntent (eslint) [inline] [typescript] - class-methods-use-this with cookbook", "requests": [ - "2cb222926eda7cda0c7bb857c22ef36927e05b4ba78613926e56b4f487d5cb5a", - "82f981e9021b96d3aa9909cb6445d72bc359cf05b498057723869207b52e7860" + "2580f5bd8b90ab6d8f2e12dffc3e1314207dce618698a723249fee4ebb11ba79" ] }, { "name": "fix-InlineChatIntent (eslint) [inline] [typescript] - comma expected", "requests": [ - "6a8e08766fc0dd716c6928299b2f6b11350d3486b3b872c37ae01e58bc097b16" + "40bec371bba93d522f15d85b7224828baa8e282f286f79363c460755a5e43429" ] }, { "name": "fix-InlineChatIntent (eslint) [inline] [typescript] - consistent-this with cookbook", "requests": [ - "28ae2b16a971fef33e295ddf7e4a3beeb162214400ceb58781285059fd6280b3" + "21616e4c8ed1360a1a18d37e74a9e9ef083482f004e77bf7066e6c4c8bd5a132" ] }, { "name": "fix-InlineChatIntent (eslint) [inline] [typescript] - constructor-super with cookbook", "requests": [ - "fd28bf25ca17b5886936fa16604fa9791435ed6c05838bf01377ac0d1897a5a6" + "3d5e9d8d6298933667bd3a1c56eb2fa3bc30e6d261045de6c5c31d36ed08eaa1" ] }, { "name": "fix-InlineChatIntent (eslint) [inline] [typescript] - func-names with cookbook", "requests": [ - "e346ff1a88d27306ed4d16a6bd499267ac628d542d92418cdf44c5b31e4498e1" + "998ecfe1a98dce826fd29e3d77899703b0dfb48735dd3741397441b48ef4ff72" ] }, { "name": "fix-InlineChatIntent (eslint) [inline] [typescript] - func-style with cookbook", "requests": [ - "c79d4c5ec8afdf123c8d99f01c95f302241d6abf5f354b4e2511a80bfcc9ae72" + "ecad45a7b74aad4d18d3f6782e14e3a30e57ec584a5b16437aebd35f8cedea0f" ] }, { "name": "fix-InlineChatIntent (eslint) [inline] [typescript] - Issue #7544", "requests": [ - "9af3ff2e9d13a28fb5efa41554173223c7689dd9ca8d9698fa663e59cec1b6e9" + "ec9b575183b1a35a8035676c3fd5ccc2df8c0a31c938b6bd603063a95eb383e2" ] }, { "name": "fix-InlineChatIntent (eslint) [inline] [typescript] - max-lines-per-function with cookbook", "requests": [ - "85e0201db9e8f7028228ffff3d42a5306f608d6924ede0e4ce954e660ba48355" + "16ff3c89e440835426cec5c03cef9210ba09297193a512446e738c69611bd3f7", + "25d629ea1c1e96f4156d567908285d8337e5c0b5b16836a4a495865e74709a29", + "3529abbf4066a383dd67b01ec023bdc296cbae4624277a588dc96e8605f1e2a9", + "64f02642a91279742104e00045656efae783170db749907885c399d6a2f681ba", + "7196218eb40560a3bc897ac0aac83fe1858e557fd5e9adcbc9a93e59c72f3a2f", + "8a20e3b9a165b1617dbdbb7d5cca57230390578bae3c6839adf2af203145663b", + "c919cdd763d10d9fb0d47263aa68711d995d9aee1d0ffee3f8a1af062e3afac8" ] }, { "name": "fix-InlineChatIntent (eslint) [inline] [typescript] - max-params with cookbook", "requests": [ - "fa5e95227384c94ebe1a54601c65a6100ea041ca6e127b6255cdeaecf9812dd6" + "f09d80544e9965d28e0d18054462a8981d4e70d649675c378f150eba1df3b7c3" ] }, { "name": "fix-InlineChatIntent (eslint) [inline] [typescript] - max-statements with cookbook", "requests": [ - "b9432021824b63635972147f9ea9a3a87f563efa23816d837065f5084b3f9149" + "b71b0f3e4e15b8907a8d617182f54400bb403bcd92d9dbae41d5117ec48a56fb" ] }, { "name": "fix-InlineChatIntent (eslint) [inline] [typescript] - no-case-declarations with cookbook", "requests": [ - "252b599387a574053007bd5c36ac74cf182fa14dc89f8e843e04af62b8285fe0" + "527c06aa7b9d81b113d9b544e8804a64f15efb5767c175d3f35e88b49d4b934d" ] }, { "name": "fix-InlineChatIntent (eslint) [inline] [typescript] - no-dupe-else-if with cookbook", "requests": [ - "9ef55c1a8ce76ee2206b26e667aaecda737fac9652c73b6c3b44fcb0dd28aff2" + "52885cf76b22bdb9fbae7b74404b38f1e75d4c8205d9fbe463c2ac750299e4bd", + "a748ac63416f8d1114e482c4713b4475050eb8bfe8e6fa2e12cea14e2c8ce0f2" ] }, { "name": "fix-InlineChatIntent (eslint) [inline] [typescript] - no-duplicate-case with cookbook", "requests": [ - "267af448a5e5f372d9fee4cb937c1c49fb8023e02fec22b81523f370b690a854" + "4bc92bdda6b2518486ad0287d4384a6ff7b2ddabc245892df351ad4073fc9a03" ] }, { "name": "fix-InlineChatIntent (eslint) [inline] [typescript] - no-duplicate-imports with cookbook", "requests": [ - "55b0cbbea365b5624bae0d8765fa4fd72883f2c048d1dfd3ef4195d006fd94db" + "56399ecb835ee1d5e39cf3311aea26e06843eaa027b54598b9a3e9dc1c58175e", + "d5b7eaab55497fbced14f1e4e14244de7d363c1636076680e3f15eb49e650351", + "f306de4267392716aa103018937d0b32eb1a27cec97e3a0e0f0f3c9d439b9439" ] }, { "name": "fix-InlineChatIntent (eslint) [inline] [typescript] - no-fallthrough with cookbook", "requests": [ - "f1db4248f34246ec483c58a6fdfe46ead5e78ee20814a7806f880c2d95c23e3a" + "176cfb9ab76f707932e4064eb22979a160dda58604c4e1c334aaf5a9d4bda071" ] }, { "name": "fix-InlineChatIntent (eslint) [inline] [typescript] - no-inner-declarations with cookbook", "requests": [ - "1cf1b108646cbcf0e96409c2a26013079528074b7df978c390c0ba6356a27d15" + "c95d113874e025c636117c74dd1d344660d20d4b74da1bba6ae49b90731e7301" ] }, { "name": "fix-InlineChatIntent (eslint) [inline] [typescript] - no-multi-assign with cookbook", "requests": [ - "890a1cba5253933b050837094dbde5c3ff6f55a6d2daa4c4bbae1a49cc161f61" + "495357698d957d758ad102fb342843a4d1b005a05e92d908cd2a6dad2be596dc" ] }, { "name": "fix-InlineChatIntent (eslint) [inline] [typescript] - no-negated-condition 2 with cookbook", "requests": [ - "ba1aa76cf36e20db3a2ab4b379aa93539b378d151a67a66bc86c99044de89bc1" + "3dc33bfe43b0565d78ee41c80ca30401aff7407329d1860c84cf3349868b4450" ] }, { "name": "fix-InlineChatIntent (eslint) [inline] [typescript] - no-negated-condition with cookbook", "requests": [ - "5c5629a5cc1692e2df6157bfaf1a536168c341c2057a7a48991d8d8ad50ae51f" + "7c4d3181b473e9a283686bbba6a6e3b32532e7f61c67226fcafebfcc8356af3e" ] }, { "name": "fix-InlineChatIntent (eslint) [inline] [typescript] - no-new with cookbook", "requests": [ - "c6e50adca559f95d8a0f0d683cf40bbedd147452e55676bb33e51cbc4272cafb" + "5288089a6f1e80f507b3df8e93dbce2ef421bc28a15721a5a00291264db39ef9" ] }, { "name": "fix-InlineChatIntent (eslint) [inline] [typescript] - no-sequences with cookbook", "requests": [ - "5942325ddc5fef69bedfed7334cfb14ae14eca388c821984fdaaada8695a2f1e" + "b53059ae7b62301774b258edc11980fd1015c290c60adddb6fb2e8395635a4f5" ] }, { "name": "fix-InlineChatIntent (eslint) [inline] [typescript] - no-sparse-arrays 2 with cookbook", "requests": [ - "d365376f834b7fe5d0ab39acc35e9784f2414a17633847de45d6b11062cd0f03" + "da27a79b62a72bc9eb82ff162546bfab82a9fde693dd6b23e6b5ae4da255973f" ] }, { "name": "fix-InlineChatIntent (eslint) [inline] [typescript] - no-sparse-arrays 3 with cookbook", "requests": [ - "c7765c0430539d94b0b6e9e317e64fb6bc51d61aacb0821b81fc625a4ce1ae89" + "3028cd67dd55cff256a5cea3a821821dbe0d75770edb5848627096a04cfd03c2" ] }, { "name": "fix-InlineChatIntent (eslint) [inline] [typescript] - no-sparse-arrays with cookbook", "requests": [ - "eb8142b22f9582c12100653cff0cde001330660803fdf075e23d293526106a6f" + "6154d8b20c911e5e5ff518d14ff2215c81f5670af4b296eda41e667768083157" ] }, { "name": "fix-InlineChatIntent (eslint) [inline] [typescript] - require-await with cookbook", "requests": [ - "64e5e6f14ab4497d2c4866f975ef78ebab4ba3df9fe3257ee96b84b164f81617" + "daa3ba9e4a55627444fd9341c01db18a70058a2d116835e459b3f3aa9ec61167" ] }, { "name": "fix-InlineChatIntent (eslint) [inline] [typescript] - sort-keys with cookbook", "requests": [ - "53926f5d19f183cfe0f7f0269be5f5bfc4e6cd5b03b6da0303960ce67caac699" + "e919c4a88ac3764d61cab3089bdbc83f5af4fd60dac3da3fd70e5eb8d080f5aa" ] }, { "name": "fix-InlineChatIntent (eslint) [inline] [typescript] - unexpected token", "requests": [ - "2f3d823fbb43dab55482e27dd335bfa2ef646781c70b208df7bd953243a032d9" + "4e445cb33ad9ce038bd70da1e1a4697108b888d084b68b11d5f11902f374935c", + "63324d1661f05f010f5c5e868198b3514684d9b5f9de4bea7ae346e0e38db09e", + "76e43e1dbbf93f4b623f92df6d45693387efe0bcf3158e0b1aa12b9a81cb4fbd", + "d9fd270a4038b100b6211409f687ef2cdeb29585fdaf97fe3940f0a6118e4c3b", + "fd25e043602f61109a52f713ed93a04a389af78dc01bb546630bb85da22f5b4f" ] } ] \ No newline at end of file diff --git a/test/outcome/fix-inlinechatintent-powershell-inline.json b/test/outcome/fix-inlinechatintent-powershell-inline.json index c724e47af5..602e62ac23 100644 --- a/test/outcome/fix-inlinechatintent-powershell-inline.json +++ b/test/outcome/fix-inlinechatintent-powershell-inline.json @@ -2,7 +2,10 @@ { "name": "fix-InlineChatIntent (powershell) [inline] [powershell] - Issue #7894", "requests": [ - "8f747b6f7f5223be785223b9f5d817ce531c287f0e8bf4300feb8ac1ef96ec0b" + "40b4e0998490f06ba33db916bdbfcf07ff7c4567bd964835e2182133acd2bb1a", + "455285c3acc9af7db3afe2341d4a26f68f94d7bea57fcc2a814dc592ac4bde5e", + "839629bc55997bd50a9d742825933f9c1383e9756a2a43b70faab26f68613cb9", + "a85317ccf6e8d298a6cad8295c7432fe454845d2578940361903824f7126f738" ] } ] \ No newline at end of file diff --git a/test/outcome/fix-inlinechatintent-pylint-inline.json b/test/outcome/fix-inlinechatintent-pylint-inline.json index 737f5c65e7..bd5ebde7a2 100644 --- a/test/outcome/fix-inlinechatintent-pylint-inline.json +++ b/test/outcome/fix-inlinechatintent-pylint-inline.json @@ -2,43 +2,44 @@ { "name": "fix-InlineChatIntent (pylint) [inline] [python] - line-too-long cookbook 1 function definition with long parameters", "requests": [ - "534732cdd0c5dd08f53c96f7a094b99f21f7921dc2368adba6a60f247ffbb745" + "9118c20330ddb50fe8accff7e8b5bd4a73b10f56b123ed9bf659f9e2ab8aa4ee" ] }, { "name": "fix-InlineChatIntent (pylint) [inline] [python] - line-too-long cookbook 2 long print statememt", "requests": [ - "237547c39fae3a52cc895f73300693154d277b937fe81b9bc3e0b6cdf1fe9712" + "3dea716799c32a54d5ebc2d6f2bd144cbf63d2eda61f444155a4c5d68116004c" ] }, { "name": "fix-InlineChatIntent (pylint) [inline] [python] - line-too-long cookbook 3 long dictionary / list", "requests": [ - "0d1e5fa5f2bcdfac80343485d914b825c42d1c950d1c8deb1b44b80f9a521609" + "1c36f0a74986cfeb99fb05fcb3a662dbfe18bf83c753b3e6c8dc95f280ae6e78" ] }, { "name": "fix-InlineChatIntent (pylint) [inline] [python] - line-too-long cookbook 4 long if condition and function call", "requests": [ - "dcb6a94a6209869cae75f0f64b9ca3ade6f7166244a7af4e2e1fe03717278cf0" + "6e9e92f193a519f90b5e3e0fc53a638285849ae8c478278a16de90e0fea2d16f" ] }, { "name": "fix-InlineChatIntent (pylint) [inline] [python] - line-too-long cookbook 5 multi-line docstring", "requests": [ - "3401dbde1e76a51b1952d20d5682d9b3088cfb09eac0ecee8e9625c626fde457" + "ea5433ec64aaffdefc80610124a941de01e85de2e583a830ef292688c9e55ba9" ] }, { "name": "fix-InlineChatIntent (pylint) [inline] [python] - unecessary parenthesis", "requests": [ - "66e8affc45c7891eb7618a7cbbd957cedc9d31b71896e70056b645f4e7e58de6" + "a71ecd717c0c9cffc920c56645b268e0e9775650109ea0d00516b0ac9e1a5531" ] }, { "name": "fix-InlineChatIntent (pylint) [inline] [python] - unused module imported", "requests": [ - "047e9bdc5ae5ffc9721132e47bdc1d40769630910346c9d0e32f04f02b6b6151" + "6365ac28219a0bd17244b47def94efb99544c612da5eb084facf40ae9cc3a040", + "aba22482e574c70c988268489d84c22ef87a475594d492eeb9ec2da0cdd390a0" ] } ] \ No newline at end of file diff --git a/test/outcome/fix-inlinechatintent-pyright-inline.json b/test/outcome/fix-inlinechatintent-pyright-inline.json index ab18326b62..c8762bed18 100644 --- a/test/outcome/fix-inlinechatintent-pyright-inline.json +++ b/test/outcome/fix-inlinechatintent-pyright-inline.json @@ -2,85 +2,88 @@ { "name": "fix-InlineChatIntent (pyright) [inline] [python] - (AML-10-15) object not subscriptable", "requests": [ - "762636228db202b2fb37538a28d7c7f24433ed2c1c5a686a0cc151bee25491e1" + "31c70fe06ba83e7f0cdffb0aeb1e6c07a49e875e19d90d8e2a8ba5d17e35c611" ] }, { "name": "fix-InlineChatIntent (pyright) [inline] [python] - (AML-10-2) can not be assigned 1", "requests": [ - "e5149e3938452848f6c1d6298e0f68403c1d6e49553f33fc93ac60b27b1f4e68" + "c4a8ecdef6368121f9075298bfedd2b2c924cb5dbcb5d9b72c13c5e74a691ab0" ] }, { "name": "fix-InlineChatIntent (pyright) [inline] [python] - (AML-10-29) instance of bool has no to_string member", "requests": [ - "592a140b79c1dd603c59b2db50644fb4a4a75bbd36de22c6153723fd8ffa4028" + "d68db7883728fbee2be21188ac5fff88676f514ef7bc9761ad948bfba423f4e0" ] }, { "name": "fix-InlineChatIntent (pyright) [inline] [python] - (AML-10-35) can not access member", "requests": [ - "e56c19d82902f9c43927e8fdafac366338b8565757c87a73c008d0ac00ccc15d" + "54f03ec60b265efa9a88e9152d9f54a8703c47ac6c1cbe8c97b50fba9322cbce", + "ea07043284d481bcb2272705ddba063b658e72568d7a98258977bdf5b1e2031e" ] }, { "name": "fix-InlineChatIntent (pyright) [inline] [python] - (AML-10-36) can not be assigned 2", "requests": [ - "65d07f940a7e347275283de84ac72fb8005b781dd77a9bd423a6fe128f4ea10c" + "c06f545ae361247a2788190f9bc3a234b52790bb0f5d1895aa89cf97e2bf51e0" ] }, { "name": "fix-InlineChatIntent (pyright) [inline] [python] - (AML-10-4) parameter already assigned", "requests": [ - "09940e1a13e1a7822f49ec49ef0c3a9777c44dda493a26b8b7271e2a9b128be6" + "75f11702672c8e509c69aebbbf8a66cacf0530d505b4a85d149670bdbe544e94" ] }, { "name": "fix-InlineChatIntent (pyright) [inline] [python] - (AML-10-48) can not be assigned 3", "requests": [ - "0bf7ab9f9f9b5e5356f3fb425351452b6861b2fe47a459dd6080396a69f5536c" + "c0efe1a56136ac32d67b8f0b388982f297fac671cc25592a0a939dda8d420ad0" ] }, { "name": "fix-InlineChatIntent (pyright) [inline] [python] - (AML-10-58) not defined", "requests": [ - "1f3ecb4766c8c19ab878650e38a0ba3b0c035c371a49179dec9e24e2797ee3c8" + "04f0f3eef2e23124d7c8cedd209de6fdad1e721abe0d0afc8716abaa2d512570", + "b4d823e4918501036a1e677d8accb1ccf97fd3b65a00b48b8378ad3b008adc14" ] }, { "name": "fix-InlineChatIntent (pyright) [inline] [python] - (AML-8-110) not defined", "requests": [ - "d31c8783054028324a99c180be74a012a0392a046e66c23d4506dad86292ecfa" + "d45ac20e9bf6a9faabe770f8b5e0c18860a914d03d54de44106eb9c5a0722b09" ] }, { "name": "fix-InlineChatIntent (pyright) [inline] [python] - (AML-8-73) no value for argument in function call", "requests": [ - "5023e50519deddd591e35e2da716c15c0611ec20d1118794a2ff2c15faa670ca" + "0aaa558147c92c89a0c18062d41b003e8bcfdd570564c21c324f0f0f4fd17b50" ] }, { "name": "fix-InlineChatIntent (pyright) [inline] [python] - all Annotated types should include at least two type arguments", "requests": [ - "eb41d61ad07ffdd1adbfc0c438e3a939d0452a296490ad4a38cbb05657dcfbdc" + "4b81b0a0dfc5051595b75b32571b93a07241603fa327a6b1193aabcd1d163c78" ] }, { "name": "fix-InlineChatIntent (pyright) [inline] [python] - async cannot be used in a non-async function", "requests": [ - "13b01a34677e11b0a8ab9fd5413a239a54c8d42c4d1e8ba0e98c9313d6f46bca" + "5efe11dafd20ae8aba5f7bad422568641206e4484e5e5fbd818453b6c74ef303" ] }, { "name": "fix-InlineChatIntent (pyright) [inline] [python] - await cannot be used in a non-async function", "requests": [ - "3fdccb06997e6012ff52cfa011e1e8c1fd9c8c2b80a5d8e3ebc5d9222c5b2a1c" + "c227231014fe04d5054969e48aeef2f2e7f5fdbe45d1182a8e9d55372b3b3a32" ] }, { "name": "fix-InlineChatIntent (pyright) [inline] [python] - bad token", "requests": [ - "7efb676bab003eba60bc69c77213128bce5fa71e66475159efe73528b0202ff0", + "3f390aa45754bdf680f5f32ea03c69027bd57f549dafc304ec1b7f2325acb40b", + "662aeaad6b10c5212cc233dcfc2c514a460894bf65ae7157afa1faa2a61e30d4", "92416661a3040cfe13ef19ebdd56f23f7c2e9871fd58d8a761bdb164fc5d0e03", "c3ce46d083cb1131281b00662a8ff4cfbb876315e875955370def9efd838e8ca" ] @@ -88,52 +91,50 @@ { "name": "fix-InlineChatIntent (pyright) [inline] [python] - Bar does not define a do_something2 method", "requests": [ - "5565712e4725fca921d47309b80892abdafb3a09fe0947b634a4721698550aaa" + "9f83ad5dbe255248fdd71fcd4827f1d998aae63cd513b58cee7685f2e435959b" ] }, { "name": "fix-InlineChatIntent (pyright) [inline] [python] - cannot instantiate abstract class", "requests": [ - "5b83ee199e9ce8b4a1b5fee1fef1f6d183dc3340c230c007c6208bbd1dd3123c" + "ea90f86f2184d0696ff1f9e2720a16869be6685555300b720ff0ad481ddc2a37" ] }, { "name": "fix-InlineChatIntent (pyright) [inline] [python] - general type issue", "requests": [ - "77a92201e2ba3fe2b464754b03931b46d9ce96fabea4a3d27d00a1e161a349fa" + "259dbdf08b45154bb4b985c94cce1258560d2ba5fed6861da87cfd1d16a4d57f" ] }, { "name": "fix-InlineChatIntent (pyright) [inline] [python] - import missing", "requests": [ - "1f8b44236fde4827b8c6b164b7f98212feb17eca4cea1dde108f4b2fdaf88a6a", - "423b6e0ad7b81c538da9edc677a8734db88c4a977df79ef3b0ab1bd174839055", - "9fbba308d0d33be160d889ccc7ebc62a6bf87ddd8cd2fb2b558fed42deb3ed8b", - "b26746f60ceda5273cf9fcd6af7576a936fef16875c726543a969fbc719237de" + "75306be129b5e38836737186331637d88f8c2abc9f30147464fa3e19acf7370f", + "9d6d998f58ba0f973d23054cdd2ac8c3d92ff1fc1ae31b1711e1aa0e789098a7" ] }, { "name": "fix-InlineChatIntent (pyright) [inline] [python] - optional member access", "requests": [ - "2298951a652bfe96955bba177564d64ec37d0b34abe77118e40f26d9edd49d6e" + "cb8d61e5e8ec9ec3577dcdf458694c28bc6c522cb49a87276111997e5d4e720b" ] }, { "name": "fix-InlineChatIntent (pyright) [inline] [python] - should not generate an error for variables declared in outer scopes", "requests": [ - "61fe6d430121856cf332b06fa23f30a6d265886002d6b200a32c3b910115a187" + "9ee22af0c46077a957f1f25674dacbabe4b150a334376776a941821898635dd0" ] }, { "name": "fix-InlineChatIntent (pyright) [inline] [python] - unbound variable", "requests": [ - "6d5f31a5710ead4e8c7f03fbd9d66a1b3ba628b921fc1b363bc9a2777ac9c8ab" + "1b3659a8cd73ed1f838f2bdada5d75c980911b4f30c96f4fd963f5f14c242ace" ] }, { "name": "fix-InlineChatIntent (pyright) [inline] [python] - undefined variable", "requests": [ - "98e4984493189c68897b1b8993b9fd7b569055a6a3cf57d01c0063c8bb7cd537" + "8eb6c43365f03d4112312dce2c8f81697a7203b8b69de8b329a043623bd9a12b" ] } ] \ No newline at end of file diff --git a/test/outcome/fix-inlinechatintent-roslyn-inline.json b/test/outcome/fix-inlinechatintent-roslyn-inline.json index 5fad927e0d..f1e50b875f 100644 --- a/test/outcome/fix-inlinechatintent-roslyn-inline.json +++ b/test/outcome/fix-inlinechatintent-roslyn-inline.json @@ -2,61 +2,66 @@ { "name": "fix-InlineChatIntent (roslyn) [inline] [csharp] - (AML-10-28) field is never used", "requests": [ - "454bc822b215471d7b9556af5fa999f88817ecbc97331ff1b1e74e195acddec2", - "6ca392891afa89f4826d931b0d9f852f786b3447ac97072a0581cd1efc25a815", - "af14b4434c2148f435b6887270fc4e225c248eca18fb1cb78bb61e90a71f6545", - "cb45da5423e8e9b62cb29ce2be3c21b6014fd14922e7717086a37452598feb73", - "dd12bf375f8fc6f9c42cf1c571ad8e1f4928a677f172920e813e4419a067d1b2", - "e2a589cc15e3f220e1ab4ac96c8cf4a98f2232c4b010cdc66e70fe2816c6a1b2", - "fa89a7b4b11c36037aa0d090f4bb1b26013036de7ea254bee9fa1a78145604b7" + "180f601c0756a597532b448af1be573550f0d44c87c14a910b48fbd8a52b47a6", + "1deb172d197192d0390f2142a23cd5695b020e38e530853cb21897f269dacd97", + "2f7671ec5b7a1502bf4e799a14ba9523a3d5149527ba6783c67205b07cbe4506", + "404bf7037c282877a1600fdcb7829279f47f9d8734b6133fe0d8e534e2abcfd1", + "4d0ed3ae8bbb76154aea684483fc7f611fee52c8d5d62798db5af210562cb9ac", + "69ef0974c9d71883c6f0c8bc097a8220e23975905fd8adc8a20e38142ee7f286", + "76cebe09ca0536930827f669cc59771f0084bb633ac3751f75520b4beba76b12", + "b62ea07883ca50e9d1889179535722c0525fbd0735155d63f6e404c9d17bb61c", + "c92771e2f53f2d3322d4eb14db694f758b1c82774b3970d8352d3354cccf5fde", + "f4f4219460a92c1fcb5e665bd95a9e276a1fa8716e37576b679ae62cc3d192c6" ] }, { "name": "fix-InlineChatIntent (roslyn) [inline] [csharp] - (AML-10-57) call is not awaited, execution continues", "requests": [ - "9bfcd1c99a0abd103737e3d3a918102712c2f5da0cf27e758f57d132bcf79ea5" + "b5fe48e496d40e0bcbf92491ab1741f0339791986222a20714250ee29a892b8e" ] }, { "name": "fix-InlineChatIntent (roslyn) [inline] [csharp] - (AML-17-3523) has same name as", "requests": [ - "5cb6936a379da436ceb98e2d5ae6774e45f8d144186659bc39d9d0fb1693fbd6" + "ec44d28f8a09d530d958900b4d5d1e2a415fe543fff2e6569d3026af0b274d82" ] }, { "name": "fix-InlineChatIntent (roslyn) [inline] [csharp] - does not contain a definition", "requests": [ - "2109f61813630b089df80b1ac0eb0162c15a2b972b43f32b30e19fd12f717c2a", + "1f441af34530624d2d4d40a7f72fe3add52a0ff528bdec1b797c039c98431d08", + "4316806b3cdab957e9f5ff99beb34392c7732295e499430faeb3200709130a69", "45f3d34d2d1032a34bb42b26f8271c8b50be2d1eb2b8411254014e6b56bb3d40", - "5e9b3115e40ce3471a27b43c75a130cff96e4925b9c1f66489fd9326de3382d7", - "a6216a5b85c25bdeed6263fa86f8cab5806352d6a51e6f3803de6400b8034b00" + "5ba11fdfa49c9ba0038bea4ce23e338281065a05561c5ac7e48caa3916a5d902" ] }, { "name": "fix-InlineChatIntent (roslyn) [inline] [csharp] - does not exist", "requests": [ - "5486a8c6de9eb5bb165671672f7498e30c2ff682ef8ebea97a5e78f9c937ab32" + "d6f4617735688d7a1ed7ef23292c96af11559686aa969b1dff340143f1867004" ] }, { "name": "fix-InlineChatIntent (roslyn) [inline] [csharp] - missing using directive", "requests": [ - "4daf6ece1de3114819e94b874d3812dae97dd5cbdfd688d3b1dd6da96822a3b8", - "51ed64dcc974a380a851f870f04ae7992837ff5f3db95b45237104c13653ac54", - "6545111d03ead47355c984ca7fc48c4c5fb8718d437c632d814b1d471bf98cbe", - "d2b4926fb00e6864c2fc6e5a004d64ec39281ae725fdfbd24bc0dbe68487267f" + "1a6c1e3785233c646ca5afbecadb71ab4291b52c22c13834f10356b39915dc4d", + "20789f386a791cfcc470ab3346c2dfe5762e82e64af067c942910451f13e7cbb", + "4487618f8e7743fc1dff916eb5da25b02ca2dcdcf9b7307cc254843aff92c002", + "83a6118a7d1a52981fdac629a1b5798ebec2ff12c8a29d4b5cec0a6750dc7595", + "b2e3b4b1350b4f8424a0c8074cadb5dfd565f6d5632ca8f52a0642e5e314bd1f", + "e302edb778d7a0d734503148ded3f082a1a9f668d9254f654c92391f6b6344a4" ] }, { "name": "fix-InlineChatIntent (roslyn) [inline] [csharp] - no argument given", "requests": [ - "afdb49bf9250c10ba4783c11bd76eba87b9c5d75e6c6452b67a0e59058cbbba4" + "5dfb0dced8da316487d3f8864e02108c31c725bcb0518589e7c5c79011a1004d" ] }, { "name": "fix-InlineChatIntent (roslyn) [inline] [csharp] - semi-colon expected", "requests": [ - "9113a5a21a298b3cc0a903cc3f32f8dbd6f5b07414163bc2b4e0f4595612874b" + "ec51b2c57056b38679eef3671a6de6afcd18fe20c01fa3984dbd28e78280c259" ] } ] \ No newline at end of file diff --git a/test/outcome/fix-inlinechatintent-ruff-inline.json b/test/outcome/fix-inlinechatintent-ruff-inline.json index db4fe071e7..a875f18471 100644 --- a/test/outcome/fix-inlinechatintent-ruff-inline.json +++ b/test/outcome/fix-inlinechatintent-ruff-inline.json @@ -2,7 +2,7 @@ { "name": "fix-InlineChatIntent (ruff) [inline] [python] - Ruff(E231) Missing whitespace after ':'", "requests": [ - "29c75fd1bedf9a9f932481ca056e3d01f68b8ed04a90293ac2a1608a7e4481f9" + "1927d39af1f9b1fdedd490638b2c36ad93ed607339c7c9c71776be1a624ee881" ] } ] \ No newline at end of file diff --git a/test/outcome/fix-inlinechatintent-tsc-inline.json b/test/outcome/fix-inlinechatintent-tsc-inline.json index 63347e92ad..4201ffb1cb 100644 --- a/test/outcome/fix-inlinechatintent-tsc-inline.json +++ b/test/outcome/fix-inlinechatintent-tsc-inline.json @@ -2,270 +2,272 @@ { "name": "fix-InlineChatIntent (TSC) [inline] [typescript] - (AML-10-31) Parameter data implicitly has an any type.", "requests": [ - "5a3b231c56942074ca6211610f9ad936c530393488124d06338605b3274898a2", - "7b934ea8ee4899333274a8d0b8422cce89a7be868f59445c8a9a67274b01c60a", - "848345275d69155efc3afdfe0f499c93bc34488135a3a1643da94f455bba0454", - "c41f5feecf12ed70f9a9689b80c55e3e8b572db903dcfd4432cdd3369b80ce1a", - "d7ad5fcf4520b1efcc26cdb03c886d4af0bffb26846ee31a767a8a138a4a6a02" + "873b9801bd3d6ea4ba73695bd2edfe73f3ae255855a83a290b5a723fa3bae65e" ] }, { "name": "fix-InlineChatIntent (TSC) [inline] [typescript] - 22222 Error 2322 - type undefined is not assignable to type", "requests": [ - "c5d94c31e86b1c3841d7975c46d8f68971c90e473efde7927c20905266b862af" + "65a8567c58e61ba612eab81cc17b22e77053f692c0a4223569ce00ac1ad539a0" ] }, { "name": "fix-InlineChatIntent (TSC) [inline] [typescript] - can not assign to parameter of type", "requests": [ - "9db049e5d049ae9950b02e21a5cf5ca2fa6f73de1d548c8242a6a23403708ba5" + "91e7f0d2e83f1e26a7550b7c9796be5f1eca246858aa19248ce0e18af16a4a3c" ] }, { "name": "fix-InlineChatIntent (TSC) [inline] [typescript] - declaration or statement expected", "requests": [ - "63f9d3fb77b32cdc500151044e36ab8c84c43fae18f4b025f380301271e8e7cc" + "351f3131f10b79ef68ccd408738e3df77af087fcc30613d77accdd1a0ebb3878" ] }, { "name": "fix-InlineChatIntent (TSC) [inline] [typescript] - duplicate identifier", "requests": [ - "5a041c19067beb9612158cdcb357b88718d22470555fac6165b6f82240968f74" + "a59519c2e1afa82384f9ceccbf25fd343037b81848377450b13366b7182e303a" ] }, { "name": "fix-InlineChatIntent (TSC) [inline] [typescript] - Error 1015 - parameter cannot have question mark and initializer, with corresponding diagnostics", "requests": [ - "7d64b24a27091b788bc2a6e79b55b6b0abbdd1240553e02c3eb2afeb053f8b72" + "09405ec5d7f5b74d08fba265e906544bf20d461c779507df688c6fd7aa7a09f1" ] }, { "name": "fix-InlineChatIntent (TSC) [inline] [typescript] - Error 1015 - parameter cannot have question mark and initializer, without corresponding diagnostics", "requests": [ - "7d64b24a27091b788bc2a6e79b55b6b0abbdd1240553e02c3eb2afeb053f8b72" + "09405ec5d7f5b74d08fba265e906544bf20d461c779507df688c6fd7aa7a09f1" ] }, { "name": "fix-InlineChatIntent (TSC) [inline] [typescript] - Error 18047 - (AML-10-64) possibly null", "requests": [ - "27bb25333fd732bc08a90df1b3ae73ffbdd334bbd98f8124ae3630dec1c9d8ea" + "c4cf09c741c885d7b9dd501c83369e896abe1dfa06ef5992f25ef34af9d1c2a8" ] }, { "name": "fix-InlineChatIntent (TSC) [inline] [typescript] - Error 18047 - (AML-8-1) property does not exist on type window", "requests": [ - "0849a385fe3fabea2b522d606a3a43da208b49c20a2c3ce7ad6014559d62c435", - "43e345200f9c466ffa5848156d7d74a71a672d94d2db9ab0b3c8bc989a978bfa", - "475dc4628ff9c100e5e160f6b593cb01913524c82082bbc5671426643e06f0cb", - "4ce053298e19ae6315013389e87db1dd8f4e7dfc46fc368323bbdc1cb67d17fe", - "8441ed482010fa7b4caf2f506f1fb12f1027af28d17a738c6cfecb7ff1f5a281", - "dd9c9d20a0366e8e65aea3b487db362a6d9c90e8147fc7049f0175669100a0f1", - "f66c2c6e506988cd69730b93951da0f7d367f0dc5ad84639d9cbf7b0eb023d2e" + "131f55c39df9f354a36de86a8f27ca4c7a11303f80c9d2696f1735882de24c64", + "137a29f0acbff93e0ddb3c295d086b2b0863964badbb52dcd8ff2e0e1cf677b1", + "1b356b5ef5eb974a6c244b38ca947aa4b531b95a51df7aebec1925203a1db4c2", + "384b3953a89cccf5a33fd0c061eaf2f3fae7aaed91a4b3acf48b326898a4faf3", + "4743651e7277dde50de102e50364eb4e4c8888a8a2491220756a6210100ad3c7", + "50b2571a89fef8354d6ad4953f54e058cacf48765141d27d4374debfeceba37c", + "a81cf4cb5e882ac23644ad94a527716565c0ce144e48f5fedfda385f5f91962d", + "b1cc838ee41ca00c0939df0dd8114cecf2d0c6b8e2a8c0b3113f0122335745ab", + "cb3ca8ed54746aa571dbc159af899bc2c6e7a6703ffd02997b6728a1af7a51e0", + "f4984d2a70db4db48a04848cf44228b8ac142512de3cd6a89957043d91329865" ] }, { "name": "fix-InlineChatIntent (TSC) [inline] [typescript] - Error 18048 - (AML-10-86) possibly undefined", "requests": [ - "5f71e713416cbfe89281f90c7d0b7497e4719fd67c4f6bb794f5fe0ff67c33f2" + "085f47fb9156e4699177b7ac8271de2166c6d2f3031a4e627961dd7dbe2e603d", + "30386c4efef1df9212f0863e7ddb89a36a592544174923a2f2d5f9e07f719b77" ] }, { "name": "fix-InlineChatIntent (TSC) [inline] [typescript] - Error 2304 - (AML-10-14) can not find module", "requests": [ - "04fca9633930850adf8fff994c50df64274430bf33c0b95c333db6a8336362ed", - "4c7e91bd1bef8d2fc8eb9c62fdd02e5b73238b169299e2bd0ddd1f85e11f2a39", - "6a65843090a96ff2b4f180928b12900f890a1be589dd5784d8851441970962de", - "97ce32374f26923ea3651071a6e5893c6f39b156c7e242054fd2e59dfc84d418" + "ae2eb7499a37c8d98844f3f253dc3752f035a459f3b74f75610298869106ff3c" ] }, { "name": "fix-InlineChatIntent (TSC) [inline] [typescript] - Error 2304 - (AML-8-125) can not find name", "requests": [ - "0e660449eeffa14e5f9bc8e18f0fc31f6562c5549ae67e639bb93b502396c1db", - "308773d56540ee60f279402245cbffa0a936b990590d87da35db0cc288da9ea7", - "31182e742e426c47474ca3df3234e1bc97840054b842da265a2c106d351f4ad7", - "772ebdfc4eac6ae0e936881d9b09e28704b00209d465614ebd1edce8434adfe7", - "dc810cbbc9ef3c2aa72ab999649b50fa9d785cfe0908c6d9fbe4053bc0496515", - "ec90b9ca7178c4a6fc9f89ead1e9627c9756c88509124788d22a7eeffae5ea48" + "0095dfcbc72d062f0eddae8adc45cbf2b2d0bdf156665f2297e0dabde3085ba1", + "2d7b90fba08de5b20984b5f742ffd2ad7b20ca837fff740c2f1ba2e65f1c5f91", + "4ca6ff2f09b062f91951fcd14a0e959ca7987c99409fb7020c59b6ad3de42eea", + "985b46fc7c10d5b86cbc372c420304463699a0498850f761c55c20ce1182404b", + "d2dfee6f8a1fa3e766070ed6128151c14dda53d5101882c7ea98b8b09cc2c06c", + "ef7cee3988c0fe788bdc56e7c2def1a7c44ecbd171c0abb82090473cbf9cdb91", + "f30bd1937a4cb71c97b2a9826bfe5b93514c8dcc5dcd90f4412afaed070d1ce3", + "fcf3d5ee1417a8eff4a9eb873d0706f934b28a40b3f40d2594941df987405640" ] }, { "name": "fix-InlineChatIntent (TSC) [inline] [typescript] - Error 2304 - (AML-8-125) can not find name 2", "requests": [ - "2d73a5dfdbecec3cdbc01c75612499a5e3430ce4607fa6975f256efc29c5353e", - "30c1c822416d85ae5c3624a4ac4f1e711e2ef8543c483d33486d07ee7768b46f", - "9a80b91659b201765632850f7a5286b9c1a21b4b891ceea9cfa28be6a7618e71", - "f332eeaafad3209e1b16af37e909701556e6ad005dd92325be07e368e2bb68fd" + "0259aee6cae33e2345bdc0b2d9ca63cfef812756895f7094159f37ce371fe646", + "0c5204ecb2d4f5e8fd9f456c4eee27a58b84e3e5f5dfff90fb5c21da1b639149", + "8d07af10ddd813be02162c3fd51e1776f531bece8a8b5cff59768a64b26acc5b", + "92d43243db0efcc7c4ec931974d044c831d0bf0da699409fdfef479be67f9783", + "aa54f6a2336fb3c4dfd7832548b610d0349a97fdbc741af7c7f0c2fced3b42ba" ] }, { "name": "fix-InlineChatIntent (TSC) [inline] [typescript] - Error 2304 - can not find name", "requests": [ - "775122a7f0457592cad3fec0eca9c7ae2c21c56da501e71d2e4c6aafd742e092", - "b303f60ab57ab07abdf36be043c4d133e944631d2c52e8d27a61c46dc9f49ea3", - "edd71630079703ea9ae6a705f2648ac4253eb2b4e40234c2389b3f14133dfee9" + "4e0f2d73fc96d60799f430a442d39f64f341328a0d66528e385d24825d17016d", + "5797504eae5c83c9a9e987454f86352e8ca65356b1cd240f841a9ad643d040c0" ] }, { "name": "fix-InlineChatIntent (TSC) [inline] [typescript] - Error 2307 - can not find module", "requests": [ - "92dd5a42ae40b9439b333d3b049adf1a97e949e39257deb8dd8f38ea204100e4" + "abf3853012e6dbd626e728583e4f643f6f7af064b65146992cc422522e37300c" ] }, { "name": "fix-InlineChatIntent (TSC) [inline] [typescript] - Error 2322 - type undefined is not assignable to type", "requests": [ - "c5d94c31e86b1c3841d7975c46d8f68971c90e473efde7927c20905266b862af" + "65a8567c58e61ba612eab81cc17b22e77053f692c0a4223569ce00ac1ad539a0" ] }, { "name": "fix-InlineChatIntent (TSC) [inline] [typescript] - Error 2339 - (AML-10-55) property does not exist on type 2", "requests": [ - "06093e0cefd6cdc183356eadc39ba1e7be1559406b5ba6898af07f17ca42b784", - "1e84e9d12cf6e811f1a431b6e96ba5542c28db1ce6a4cc6ecf6e0b14421514f0", - "4009ec2a8660e7cca90b413b092e0909a6d0ad1701346bad8e2d8f98ece12a70", - "4586786915b4c99bf097ab44a7479a6dd8e9e9808ed9857f899c08d736225c56", - "5c7fa982ea4856238304a22f9bb24075ebb4745d75ff286ed2e0606d7638568b", - "6c45df85d9448c8b08f69a5f67b4949653e7268c28e0f6e57d3539fed4420b31", - "8097667addd95f0e741e816801914eb8ba6ed7d575254373893b6cb4c36c8553", - "be58de9d16b11702b443acbe98965b532c50574fdc64a240178b01c839779a2e" + "036f4d04089dd44f2d67b24ea0ca548505a0c8ae831721ff530c201212f57795", + "08b4bc7c5329cf387280f432819c51ff1ac3c85d75b151a8c1696ce92150736c", + "0ff5c4b1bd2de6209fc05d7cf743f966f170a162dc7c008642ce89f712c23632", + "213e8758dd2177a1ca2b727bf999f735de04a469a8fad21fba7004a7873d81e6", + "60450c35f630978b1deb0d707ff63e694c52d5c7f8677e4b06154f014e72c93d", + "a18a199d48633ba91eeff77c4264c54d0e8f27df232a6f1335576e1f11f978d7", + "cab6aee856c728e48ec7b10289ad54373c4b2bee9117ebfe6716765a72685be6", + "d46da3426f76853f42dfdc6a533c5ea40c5773ba56edeb880ebf3cd46af19be9", + "d9b4ed9bf4ba5f88e72c2ae26a21590c5bb312b732191ab3ca2f3fa561ae516d", + "dec09f0c4740f3b1336c27562ec4930409dce4ab0fa7aa8976e379110051086b" ] }, { "name": "fix-InlineChatIntent (TSC) [inline] [typescript] - Error 2339 - (AML-10-98) property does not exist on type 3", "requests": [ - "10656653ce0031f6c2d0ab239693864b17abd320cf1462600b420b84cb8c51b2", - "50e01facea423404d93924ce2af6ba7daef8d35c15395c41208621f4fcd3a557", - "56446c0dc6f9882615a370c9474228909bf59159eae4d6cb1db675962f28f4b9", - "6cdc64e0cd86b3e7c56c85532ac6fae954efce39834fc9746fb3ebfa162a32dc", - "6d6c78e49955f9e4ea532253d0b43bb8d3932cbbbebf3f075e415e47d42ad0ac", - "c3908ff1b96a7d2f3f19e343c4b89f6cb7e883e007cda92810848c4e8e721be8", - "d03fc24ffddd0c49ddeb2b62409a9da37af29ae51903d267e3b61103d0e8e5c7", - "df5af8c929b00860a0e6b86ff6ca2befdff897a9912a327ea4193450bb570ada", - "dfc5aba28b372e592c27e6be6cc71fcb0b10db141eda857db17db9111525a21c" + "1ac62640af31416cae16ebd3dcbaf5ee22665f71f2d4785233828ff9d40e501d", + "2531c09e407338719d9da67a250f525c45f11c48782c1a9ff265800c5c189832", + "66522993753a0479fe26109ca3eca72f3adac797e7b1060ac154810160d229b4", + "74065c79ebd955ff932984504dda715bdeac960817fe2f8a3e2cf906ee381ce5", + "746698454d3e5a55c60631a39a9bc19783f6fc632c7d4836f6331b524d43762d", + "d88a296aca38daacaa969be34fc97ebaeab75f3d96d3da9ea5f112769d1de0ff", + "e2d7b83bed8d94627b32e59b95f703b3efef149c5a9ce66b89c2bb0c81ca4bc9", + "f0f6567bc7979d48ea78455b6292a5cc715acd1de74ecfc0341c3a306b3e95c3" ] }, { "name": "fix-InlineChatIntent (TSC) [inline] [typescript] - Error 2339 - property does not exist on type 1", "requests": [ - "a9fb73f729cf262d896ffb56e86fb031ab944bbe3d0aed592a3ceaa3936402cf" + "33f4d960332d0b4dce3ba0206743f460f9278cc6381bdf25a9a8141b8850fabf", + "6e02cbfcd4b292c5368a50d06e44f82c2be75577136bdc62a0d2bfb9841f1127", + "a4136356fb5e9fe9875d577770aa7865a5aa39d044d8e614b6b1e873adbe0101" ] }, { "name": "fix-InlineChatIntent (TSC) [inline] [typescript] - Error 2341 - property is private and only accessible within class", "requests": [ - "03047138ae340e93e5e7495dbed36a3e0587981d675b468e974fc5b536c7332a" + "abe31dc05d8734654e4780295125e2c69cf629ca9e7d222d91fa2455c90e64e7" ] }, { "name": "fix-InlineChatIntent (TSC) [inline] [typescript] - Error 2345 - Got boolean but expected options bag", "requests": [ - "76e07e9b277115dede4c59dbd497ae12154a0ce00a56fce703f8c9466dd3a913" + "4f7621930f922aac75ed68feea396950c172765b221ec398340acd9f4429dac2" ] }, { "name": "fix-InlineChatIntent (TSC) [inline] [typescript] - Error 2345 - Last two arguments swapped", "requests": [ - "9384193b99a5cd57b5d104a84fbdf0b85ffa7313d02b60f940d3edba3cf3ed19" + "d9d8bf7b6fd9749974b825fad5abc0d28522f7888b79fd74f49c53c8b476c275" ] }, { "name": "fix-InlineChatIntent (TSC) [inline] [typescript] - Error 2355 - a function whose declared type is neither undefined, void, nor any must return a value.", "requests": [ - "635d80ce4dab7e8625ab68147b4f0a50c7b9d1651237e8b694cd51a7ea318102", - "d7d439f82955dbaf94c6f7cf8f20f5b9e8a46f94fc121478eef1b7f88dc8defe", - "ffc56fe8ae62c6fb843b673eaa02dc26a8fb3fe78d01831676875273199a9541" + "4a9e4135f0a33edbc9b96f058c4044e8de46e53d350c93f2b29656a7792437f4" ] }, { "name": "fix-InlineChatIntent (TSC) [inline] [typescript] - Error 2391 - function implementation is missing or not immediately following the declaration", "requests": [ - "a15e7b897b9166990daeb264354abb4bdf3ad1e0adb3f3ebfb0f941eb0838877" + "886c1175b505686cca452ead4929380349f9c3743fdae5b4f4083b717966fb12" ] }, { "name": "fix-InlineChatIntent (TSC) [inline] [typescript] - Error 2420 - incorrect interface implementation", "requests": [ - "09c89937d8e2d83bc7528c6ae2a73fd533da951fe0c6c12050bba450bce219b5", + "0a5f1fe5cd8136e999c7115c6c4e3c1383dae1a74b26fb9e3ed0575b170f3be7", "2de61ef57dc5b78fe5cc2e1f6f22644e8b20f3fe85c87cd56c1ef1d0a3c41dac", - "b52a3111208f1cda06248e3555f4eb26f7abbbb96c3aea60f259a324325892bc", - "cc9122fe43946c495d3c921a4e9719d95ed2239215ae1139df5161042ebb2634", - "dd4aa9542eaeab4a63d841b104f404f7cb08b1cd6ff92534ee2e6e49be02d9b5", + "a1ac1be4cd11e64d881876beef036d55f694ea1ddb206ecb5bdc06c71b00a4ec", + "e0ed2184a2c5a6ec55c9186fba0f8ef7aa3b179645e8a3bbf74798b1cf641d2c", "f35907cf011b96f5918fdfd2e41cfcdeea8a053ef5cb629de94ca40029a5ea9f" ] }, { "name": "fix-InlineChatIntent (TSC) [inline] [typescript] - Error 2420 - incorrect interface implementation, with related information", "requests": [ - "714df1e30477c5b37968e955ba12daed8b7f0dbcc6ec4db75e837de6be36e31b", - "dd4aa9542eaeab4a63d841b104f404f7cb08b1cd6ff92534ee2e6e49be02d9b5", - "f35907cf011b96f5918fdfd2e41cfcdeea8a053ef5cb629de94ca40029a5ea9f" + "0a772a9bdc4e6ddc144e4d7fac62a141d208070d22104cadb0dcf82817fe6ebc", + "b59eded86c4a8b35a858ad271657eaa94f795c02f7abf43c4e15a0d2bfe09662", + "f35907cf011b96f5918fdfd2e41cfcdeea8a053ef5cb629de94ca40029a5ea9f", + "f8d52b6d61f0442c42d7ffc2386467b296c1c26e85d96bb4a6f990c791789c90", + "ff34a53355230c9da78497af5a324596ab76880638d0e722649aa834aa08bb05" ] }, { "name": "fix-InlineChatIntent (TSC) [inline] [typescript] - Error 2454 - variable is used before being assigned", "requests": [ - "1e23dff6aab3eed233b03628af4410bb12a09486dffd2713c2447d8be12b0bd5" + "1d46c76559436f5b92cc2b050f676c34508d63010516e31c37a34b63bf6df1c2", + "e5a1a30f2be143541bf0d57ca56682b24fc6b6958328b0f5f6f86edc81d1b335" ] }, { "name": "fix-InlineChatIntent (TSC) [inline] [typescript] - Error 2554 - expected m arguments, but got n.", "requests": [ - "fde0c21e211496eb6161adb8caea1d8ca70f499ee72d032abe773654f4968632" + "7b7ca9cbfc0db95c74369cffb1b862663be777d53dc360d690312b16da1ade78", + "91ff2bca0f9227a3e48276cd40bda326773e5612913c6012edbacc6b1e54cb52", + "cc8e71a31f3190d634e1f09131cc5892319baf25ae1cd23641ee2fbf2f6b08d0", + "e0579344263ee9d6fba9241aba2b7a9c46cc6cd291ce96fbdc15fe16e0a8ec80", + "f9ad569c9fa383cfc220a3a5fbc1718d6ede62d119885882f54f6ada1b566bd3" ] }, { "name": "fix-InlineChatIntent (TSC) [inline] [typescript] - Error 2554 - Got two args but expected options bag", "requests": [ - "09ba6ac8e20397b14d0c261ae0018e4c626f8e1ff7fdda42e2390554a38e8960" + "0864ee6c199d88932ed8946af3ed8521b3e4dda0e657200cbe4828e68d4d3784" ] }, { "name": "fix-InlineChatIntent (TSC) [inline] [typescript] - Error 2802 - large file - Type Uint32Array can only be iterated through", "requests": [ - "68e939d4c9e00befd6788a2a25f7db468ec636e343bd4fa8027c55d70fa5e57e" + "0b394768bcf4658ccf5dde20bdf36749cd5c225793399586439954344db0f7a6" ] }, { "name": "fix-InlineChatIntent (TSC) [inline] [typescript] - Error 7006 - (AML-10-23) implicitly has any type", "requests": [ - "7772364122f846a21b9e22a402c52028f55ade50da51ce183cf2374af33704c6" + "dccb2df0ee1222a984be181d21f48e65cee7aff5c6270fac887afb3f8658fd96" ] }, { "name": "fix-InlineChatIntent (TSC) [inline] [typescript] - Error 7053 - (AML-10-25) expression of type can't be used to index", "requests": [ - "a4b67c54255140ee8f8d5391605327d3e63b9fc03e92a3023e38972a69e620cf" + "019fdd48b448ec0625184337650cc33073dbd04315012c7f6f950a514dcfbdb3" ] }, { "name": "fix-InlineChatIntent (TSC) [inline] [typescript] - Issue #7300", "requests": [ - "0ee97ddbcf0a8b0e30df538048cb69b3b1ad155b89e5b35ef93bc55b4fb94108", - "86e6208722f6d5853a8b5bf05062727adf3d624cc9cff649c43ef0e2df384303" + "bc3dd583947bc9b61b700aef948a33b42d61114f30c5fb39510c95a644ecdc63" ] }, { "name": "fix-InlineChatIntent (TSC) [inline] [typescript] - Issue 6571", "requests": [ - "09446168f0496e6884f2c7eb05a705c05237ece81be250f86ff173bd041cdfef", - "10fadc9e0b0ad8377a1a13074dfee5efa39a0305fa8e39145cf2dd5548ac8245", - "2b7b1f526614118622790b92c01292f22e107deb6cce21e0c784656eab6a1e06", - "7732422bea93e620f249698351a6a760023aa25cc7b42cc15beaa8c25cad7eb0", - "f0ac2f0c4ffdb45859090562fa0c17093a6e95954090f3084dd69fb9bd3a2722", - "f5e9068916ecd6b5f0de23bf08155c33c085135ee6f5df865ee211d5e465db9d" + "a150c58d814e68873de1f9d0150c740fb5acbe7268179c2523a534e7b7a5d7ca" ] }, { "name": "fix-InlineChatIntent (TSC) [inline] [typescript] - left side of comma operator is unused", "requests": [ - "6709aa94d46d2d9e6f793e7f5deff8cdd2c28e7888555723e04c220df419fd52" + "583f98b122cd428d7cc81c77d0cc9983d421f1314d0ba4eb39a89d52ed37bbe0" ] }, { "name": "fix-InlineChatIntent (TSC) [inline] [typescript] - object is possibly undefined", "requests": [ - "8df1da3e0e7023276c57feda70118cf8d810576293c8a7b40eb7064a39a7f4a6" + "1ddd271107c275ed88ece29bebca95a851c98f67411b169dbac4af3e4b319ddd", + "8e26b3f336a529cd5f40a9aa1cdc8a7f189c38a3f7018808e619c61fda27bff7", + "b453f1a21272df61d6cb892a72e07df313006da493f86ad61d976e3eb992ee6a" ] } ] \ No newline at end of file diff --git a/test/outcome/generate-inlinechatintent-inline.json b/test/outcome/generate-inlinechatintent-inline.json index 0ba3afec45..0298d19c53 100644 --- a/test/outcome/generate-inlinechatintent-inline.json +++ b/test/outcome/generate-inlinechatintent-inline.json @@ -2,71 +2,67 @@ { "name": "generate-InlineChatIntent [inline] [cpp] - cpp code generation", "requests": [ - "49140ee4fc72914e739a38ebf9fb7a3dc353a0b9d33ac134fe9d633597135ad5" + "dcbdd8a6a65ea6ba38c2efd05537f44d8ea5a598d88a59ad6e61edbb683c8493" ] }, { "name": "generate-InlineChatIntent [inline] [cpp] - templated code generation", "requests": [ - "4d57c5a047613e6909a1fcc79a1aba1b41f8d78d514726ee7fbfaf598e0996b8", - "52ecbf6e2b76ffe9dea30f018e78352afa78ae10a5e8b5d581a651b27b567ae1", - "799747dbab2922c715925bd41b0cb7eb75997f614b1239a9735b1ebbad910d9a", - "94024a661b344298765984e2c7a1af3002c9f6e9772554d5ed4b56c749032fb2", - "ccdb0ec5936d1454acfe53eb5bd112fa7f4a86b1fd92a8352b87bfef7834f612", - "eeeedbd8c9b50558ccab6690de08fc7ea795d120cdbadc98e0b2497bc499d957", - "f033df5331ba6d1047b57ea37eedb289a00c81890477c19c67c6f9abd6667664" + "42a1b2298350ef3921c469d5ce06d229d02a5e6dca1c277a97619e8f393a0c7e", + "a20e96d6503e4d4334fdabf68fd2649764f2abba0e609a0b12400a298dc77e55", + "b644f3a2abf39fdf745f787c042cb1f8f55f1ad2c32d392a8cf57dddc4570cef" ] }, { "name": "generate-InlineChatIntent [inline] [html] - code below cursor is not duplicated", "requests": [ - "ba65d55dd767325e5c612f73a6f15429d991984063370771e3f9eb0ab9e75891" + "5a3519d08a2fab30c55f030ea2d520f077ec5a9ce1e92639cd21459d5e73d6f1" ] }, { "name": "generate-InlineChatIntent [inline] [javascript] - Generate a nodejs server", "requests": [ - "143b5a3dc5874f5ac148ea21e622869a825a40c674989e6f93ac9f728dfa23c1", - "80fbfa4125917b7f21a76e8b6ea8c7131079bc35510829f69df5c7efc84dfb0e", - "a4966881ac26f268d19af5cc5ad813493a8fc1a84cf575da8337479bb172ad1c", - "b6e533b95fb63f359147b97463912c2748752207f51f0a40108cf62ed670a04d", - "e830a0e41d2563978f5822577a296661d4781fa8abccf6725d1e7f76b3aa20e5" + "79806ceaf9d70d959f2be45c137cf952bd3577a4bd57753a9d5b2585b2fc34af", + "91c347bf47a4cfef747a5ff940cb31dc3d62d5a8c88d95efcc41863c4859a434", + "eadcaef325bdfb81482184fe815a439b1738a3dbbbe59ec3c20c3f692b1991fb" ] }, { "name": "generate-InlineChatIntent [inline] [javascript] - issue #3597: gen twice", "requests": [ - "45bb7691670ad81b79ee17276bfe8f3b5fba266eac1c57bc4f06428f87eee032", - "9ade40a5450f437443ebaa3de1fff242feb50934dabaaa2713c33a6e4c1e0d54", - "ad57a4c5ea3fca77e891298942dc6b22c1c9b1dbba55299bc164ebdf6c410dd9" + "2c7477c9718d2b0a41f8d57f8c95c0111d73f7272317b8eff8e6faab69db9049", + "36c35d69f3d73dffc5947d0ed2dad5c20fdc71fb8fb00fc6ceeb5212e5be0e5f", + "5d6a9bea9ba6bb645d9d1db62691d17879571fe1b8a3c8324b2a6d670881ad41", + "902b1c3c094bc988a295a579d61b362b740ecb6aba9c770b5115f00a91f9fbd2", + "9ade40a5450f437443ebaa3de1fff242feb50934dabaaa2713c33a6e4c1e0d54" ] }, { "name": "generate-InlineChatIntent [inline] [javascript] - issue #3782: gen twice", "requests": [ - "7471248b173c9021debc5b7b62ebe27ca23fb8a3cea3961b2e0e5e561160d4d6" + "88e4ab5c5c37f3e66c2c3e35aed5492f7f658fc0772e18d812a819d65f352be9" ] }, { "name": "generate-InlineChatIntent [inline] [javascript] - Remember my name", "requests": [ - "8ccf1232f3112f7558a75d98253723c1eb0893c636e3b2d6542a3ba276c7b99e" + "844448e96b8b46411b438874e858cde887cac7764439e1e060fcd7b88e6ce368" ] }, { "name": "generate-InlineChatIntent [inline] [json] - issue #2589: IllegalArgument: line must be non-negative", "requests": [ - "0e22e17d8974a1ace891feb9e95fa2293120022f79b7fd9185bb232c4b15eaff" + "3e0614a6659539819e916c028ea0d53e06e324ba1454e22285eed85e9a6e6986", + "5d0de62e16479820f8521df8888394ede002ede59558acec11c077c0ab2bf604", + "b453e3b9dcb5cbdad1799c1c770895ef0922fefe072fa71f3b350d5a5a11f8f0", + "e53183eddbfd53d4207190dbaba7ea3e2f2b38939854d08df0e6c824fa970310" ] }, { "name": "generate-InlineChatIntent [inline] [json] - issue #6163", "requests": [ - "26fb42f7f1a5dfc0e5a1f7ab49146da9cb533116697be07d617f600bd550b2f3", - "79002bf5043102e6b926dc7eeb20d80cf115cc9d306cbbebe6751a485b056df3", - "8bcd7d0bf4bc1e66d29d7d1c83da56d742295a4eeba0f712182a1ab28b8faa60", - "a405e315867603045a9aa9d5f39d1ce8bd26d801df6776299db9f5359444334d", - "c1a0a978ca75fb4b0b86b64e0b514ab4bb3a96500e86cf78ade0982a6b568810" + "21138cfa24002e10811150b23ca96533fa4c2543495fde09d4315df6f8842896", + "5923b135498f8d3e4083d788d7665b53c1a6b4c4084ef4eac5467923ec89d915" ] }, { @@ -76,10 +72,7 @@ { "name": "generate-InlineChatIntent [inline] [markdown] - doesn't handle markdown code response", "requests": [ - "16199182ded2535c3b070e08742033c9cb0a3d50b7740d07f45b455fc74f93b1", - "e2399b84c33b484280e2fcab3c11a0ac145c1c01cacb3cc18fb97dfcc5fc42c2", - "eb4d3bad205e168959a280f5c0eeb14fd69e5768731b2f504edb6a7a83d8a3c1", - "fbc19bf13116d07967e603c8d3eab104a115bcccad44c4036bb83e6d5b2a654b" + "d3225031cc6546c08e27cec01c2a060c5618fbbd697243e00d6cfec898f88634" ] }, { @@ -89,77 +82,95 @@ { "name": "generate-InlineChatIntent [inline] [powershell] - Inline chat response did not use code block #6554", "requests": [ - "701e000d5c244813cba3317d1cdd0ff7bb6aae56bb56bd0f2e1dccc10d36efcb" + "435bc26c5e347989127b1f850a3cebf95e176c4039d926ddf08c0507c04a00ae", + "9111201a6204347af8145572587d6d625d9706bd91e664bd023c0866d58b41f9", + "ccd51c2a9209fea990874290a4e1c4ca6cecd020188379687954d095d2fbe1d2" ] }, { "name": "generate-InlineChatIntent [inline] [powershell] - Issue #7088", "requests": [ - "0fd749ce3afca00060c9088cfa39fff713408d4baa3e2175a21608baf5320d1d", - "2bc6ea25daa42f7a7a49360dab0099608c33a99dde590a7baf8a5fd1baad2ca0", - "9d5b0f4c5cf545f8038599c454a6ea92b8429131757ead4e2adafcc34881a230" + "92f19dbe0b1df6b6f1399835e2172b3eb27dddd38678b916531038c1b00022ea", + "a2b49f33d870782e16eefb75dcb793912392143fe93258d1927f880aea331888" ] }, { "name": "generate-InlineChatIntent [inline] [python] - gen a palindrom fn", "requests": [ - "6608bdbac1cbe3dc0aab962e1328fbcb845dd730b58def32bdbb9f159eaa5e44" + "ce031f8972c7ed5a009b868ac58ac8dfc085458dfd6d3053aa6aba37100c8d4e" ] }, { "name": "generate-InlineChatIntent [inline] [python] - issue #2269: BEGIN and END were included in diff", "requests": [ - "002bb5cff7b51861092506e462c4de7dcbaba897b713c291c8fea72891f13aad", - "02884b4890b3b5513ff6c8ddb72b796215ee65cbe62d9b53e93de3c9e6f20ac2", + "0263dcc0e9047da0c1760bc98c478ff5c7e0ba51bf296146c4d58899b56289ce", "049df81ea0bf4eb6c14f8b111c1c144de0deda3313472926e239c6666e0ee6d0", - "08a414ac5621702be36bb8267e33d11b5d53480647f6894ef31d110c097738d6", - "08feb6b8875c29ba971d5253438b48dc06b540229ee99250d4bd9c9859346e83", - "1d4ce1b93507ab5d537f2fe649de5fd3e544e6bd2c64fff5e3bae58310438c42", - "1d79943eae6e0ae122f222e3dc209a8b61a837a85b46ee05368f68c78bbc1328", - "2a643e06dc45ec939495bf9dcf0d1a9887e9368e9152998d5cabb5cf36968417", - "2d3abb5f0c02d6a14075547dd254a428168705868c3bbbc6ef2ebbbefa5fbf91", - "359296a909f17ef72824792364700ad376923303198cc30e5c19f25fb44125bc", - "40bd70bca8a9b2cb67c008ce57d9c9a6fa08daad78dae5d5036ad97eb2ab7f6f", - "4be2d0ae4af419ac7b3104810f52fd854dc9b2489f921938dffc0c1e81ad0c24", - "51df2079c0730ceb45d86523b539bdaabfd07cbbf328c42f29a5d40ad226b579", - "60d2ba695a6fd600ab28e2ef6adeeb69a33580b1ee642ccf8ba0c5801a17fc88", - "67c4e817d7c5558c97911355d6e1171d6b536a2e8005d3a442b84057082d20df", - "72882f9858475ddc4c818db8190dc505a3cfe114740495e48d8c2c0bfc08cde0", - "82e0024447b8533ef947a331b0f42419b13e167cb1e2324b6e8c0126064d8e75", - "a9d99e468ff7df45dad7cec0bcf7f4807aceea1ebdf0912ec1a57c282dc62328", - "ba5620cb3467ca9c8a8707c250f6ad55a9c508cf739fc52a4945137a93545727", - "bc7659aac2e967fc57242e6097a2839a9c824a772f2cec3e01959878e256a119", - "fdc1bd8232316e57431329a969ebebec48584fd9ea65993f969bfd8422c02d73" + "0c715b72c892d7bb774c165e954802f4e5cc12e80a45350bb9510c9a734bc9d5", + "198afcc2e245948e29b4a4e022b7b226f1aefd889c98cecc37f095c090f82608", + "28a43f01b04e89c2de19d834e6ba2fe1f4bc01ba8593df63be3ffff6cdb7eb86", + "3156a7cd1974f194d91a7cdc4c2f69140cb1f086c53f02fc93e0a4df87b4ecf4", + "3bc172a82537307c1911aab442e604830ce38f742cc32106288278ae8c37cce2", + "4152e2ac5896e8542425099649f1aecd6355af036ee173482e7ea66a9a71d2b0", + "4ab95277b0acc04738ad9aafe341c7a71a41247dc4847870966d11ee5071a792", + "5e2e9e0d5f990a1efbd8c90f4b1aea3b84f41bb55c01d2e136e3965b985f46e3", + "611a042bdb0f208769e49f36d4d1529d06ca981cb8a9865c26df8e9ff6feb7e0", + "6460e56949c60bd0a3f66f53d22a5e5ee4242c622699b254674e706757046276", + "6655bfe127033f0b823dae3d78636f5ff6831c9fe66bbf4a5815b355706a6fae", + "70982db68d02a70c7944fe0c05357b58e9a5d3f45d9cd80a516d5e0ed826a816", + "785d055b557db130812409e9d4612c95b22b44b2477dd746d8da6084cd55707a", + "8ebdd4f3e89f84fae7a869778a068da18520d1a8711077edf373cf86be463f0b", + "9af1c7b35cd682401e3794cd868b0b98f73a11484cf18557d1be8089db53a7c3", + "afb60bd3d388b7fb83b9ffa588d67dbafbd456d6913e3c3594729cd60168b4d7", + "b94317e4c4cc50840ac94ba74f299efdf5fded6c24d14e0b0080f6669f991be7", + "cdd72709df1bdae171c9e7d3c0969effef893343772b04585443f54ea5995528", + "ceee0435cf668aff2b6e66172373b38f37c7e31e6413a13fba7d8618597ea969", + "d60d57f2b92c10d337ede1a6d09e4a66b79a5fe8cde8b99664cfc239e57a20c1", + "e107c9fb819926c06db7bd0902790b88807ab77ad4c4364f8a1813cc46ba333e", + "ea35c9f9da708cc7c8945318d6e5918690fc5ed9d26f5732a45a75b1e1fc63ac", + "eb843d68c85f15280ca09646fcc590742c54721512d9f73a44f2156836629bd9", + "f066952a1855b4ad946bd4e3bc714f284fc08d25ad83c35577d2d29fb9a89ecb", + "f80afc3de66dee2211dcfb806ec84534a967bd1f988c4711601ef1ffa3ec88ae" ] }, { "name": "generate-InlineChatIntent [inline] [python] - issue #2303: FILEPATH not removed from generated code in empty file", "requests": [ - "a948f01e268439a175369cfde65c491348046f9ce9f01467adc44950d850a72c" + "c87228b0a4408d63619e86c66b30d10584d7e733215ae4326e958ed024bbe59f" ] }, { "name": "generate-InlineChatIntent [inline] [python] - issue #5439: import List in python", "requests": [ - "0d949675ec30a76c8f570caa7f8c6ab2650066b482fdf24965a66bcf021369f9", - "5e2119901e5a4b7232e876a66a6d63ed5d0ba9329f8b8c2c2f8cb725d847137a", - "7d3957acd73ee7efced704b4dab4d3304b9d17308df8e21075aa05d685ac0ced", - "a461b4548e14c11b0603b7d577d3bca3faf9e3ac13cf2ff7e7bb94fa472559e9" + "7e01dcfc1a44feb7743196e8fa085df77efe8199a866456d1c415863c31158dd" ] }, { "name": "generate-InlineChatIntent [inline] [typescript] - gen-ts-ltrim", "requests": [ - "2b9c88379652455ad3fc3b15fb8700485f5f2932fe4fef5feea9cf230362bd4e", - "320ddb913c090794d7433ac3a2d7872d5261e982c2abd1127578793145965cfd", - "4bb325eb321dc7b938b70d80ffe1cd4240e2e871eec0b8b1d486cac7a1bb0421", - "65a85c870fd8ec0d386a919bab2160ba026d783707a83b144295da5e63551161", - "6cc16fb51f23f7e1ad0faf7688ec6eeaa32904e722da40c5a387cf18f9804a5b", - "7b0289987cda9a23f8a69becfa5892b6e8dbf7cf7037f98c4a03f77c72bb51dd", - "98f7deba6abf468dc52f768b9c17dd0a2fda383a65411f0dcb995f8828fe3a38", - "c2df37ca8bade73b0e783dffa597d88ba10b95c99b3aa07ef4805e6191950912", - "c7a30d6859b108d4eefe3d53362a1a3e60c9bbb3628e782aebbc692108a2f7c5", - "d9990359c12b661a429f23673b6e5dcf5737b8965d060cd8f7dcb76c3a8a0edd" + "274e4bebff2c262d9f1fcc95a0b959dd60b1dedbabbb36ea6ba5e9a28f54fd5d", + "2ece887d334b9f0d84fd92d420f7ce8d9e3a70ae80085a93d133df5371651fda", + "30d3962fee9afa8e79583f62f7737b3015aefe2394de1c83fb9ae0755b06b62c", + "56e6d3832806417215a2aebe2afc77ae3e82a6461a71668769196bd29224df0f", + "6806db6be430e6d364c71adae13a06182f2f84f51780eb2250d001655bed96fb", + "69ef45a4b4c6eea9bb9074cf1429e448083d39a03dd7bbbdfe43596051677e2d", + "6b71ff1088f2e92201c5a635abe424a48331ca1538073fe8f72436fc23385300", + "6e570ffa012e426a3aa088b3caa23cd93ce49aa2f87d68b2385d6fc51dec577a", + "6f69e7c235db465f8a31ed63c14f0d058de611bd8e0940ee75b34d8b2f87eb64", + "726f6928ddbd6e9e4052dcba74ce07c11025f8bbc308675bd7d36f9d4b9b9ab1", + "857b7c6ea57f2c1f83945b98ebffabc7e52fbf1e9a73f664a0df92ec4ab4ae59", + "98bd2f93cba4c611a9ae339553407891d6d7c74281d698df4f47e6177e077ea3", + "9940d9aba7ca13f183dc8c1d769a62bb985d2d6c849d1e888119b5c511d0b9f0", + "996c51ba58d82b14d81a7a45b791cca4741c7348f5890ec7c24cd31d835f72a3", + "9e9ad72a394e8d26cf3f42809c6e3fe69760a2ee794fb5bd906eaf03bbd26d02", + "aaf151ea98a69133bc1d10be4caa114c350dd3fcac742371886bb3f45dd49173", + "ae5a7639faf023d0d73cdea2231dbc84d92e29fc72d523dfb18b53cfcd5a1737", + "b7fa014e045ac284821d5acd9f418a6154c22930251c98ca70883228b892ee0d", + "bcf626954a60124b3e569cad59fb788ecc5c8ff7c85dee2566015ffafad7cc23", + "d1f8df32f3261e58536694cbb7a67a725a4d36287f5002a34ce2d9b0914b47e5", + "dab8305534b0a4cf3f89919b4f0345d6ffd6d7d1b7e86b6b0d6c06b24859cb95", + "e1ea8234650a91266cde854a664df0a7899ae5e7506027cee4a7c0f6c6d12e64", + "f13fe4f24cd1a6d1e1a979764a518247d0e320de542d4d8ab35b2eaf21748bc7", + "f6e3bb8d59c2b55530d85c510406083f04055487a3bdac90eadd685d42c99ad3" ] }, { @@ -169,27 +180,16 @@ { "name": "generate-InlineChatIntent [inline] [typescript] - issue #2342: Use inline chat to generate a new function/property replaces other code", "requests": [ - "09664b9d2e897840643e8da2709040a57e674d5f276035eb2556e7292bf194f6", - "0af01e967654553f9caa8837c3da83059aaede33151bf6840c01aa91e15b34bb", - "154a8fd8322820ff31e8d1b3cecb5fdba244d4a94e2084a6aea59203b8262f0d", - "2973109143b65f2d2a5a79578886dfca2d3e8c7e7a7d3f5751b9ffaf5adb80d3", - "3668bf94d8deaca58ba1368a8105eac4ffc5c315c3376fddc4b155622c03508e", - "3d805d6f5ac688540afeb40284d22c4924dde60a58eedf38657c668387b424fa", - "3e9026627223667c75844b74435a470fcc64f3f9166d5816070b10999567461a", - "53acb455e9f1d15882f78755bd4167b9af9905f1f7478b59474a789041be98e7", - "8b917462c75bc75ec980aeefd0b459bf797fad62ef292a31b5997ed340e34841", - "99548383b89114589913a3343a3a7837719760afdd619900b8011b64b1dfa235", - "9ffa301e4c5559be83cc9dc2db6b8491302e67c5ac783d04701081e9a97a52e6", - "ab775a4a064e877114d7b3de3477b2a126983a78c31c29c80010a8a065d9a979", - "acdee5729f6a930b0ebd20c8870a06e6fcb811184eb5e15a1ea7f954c17f2651", - "b39e62813132001a758a9964bc52425fd2c8c385bca5736e9bdf988e70dc2656", - "bc99e76c21301d9c3ddd79e9c11c4aadbb422d8a12050f3cbef0ade540ec70be", - "c09392d21bea6542c0eb3fe95cafd2ef611df5f1166c11c61680c97c53d548ee", - "c449e8f4da4400003bcec5427cf90d3a169597bd792252693d778bb4135f0e40", - "ce5136a07d4a703cf50ef03bdc6fe8d0036ae729fd4f8c7df91da41c1917beb4", + "09561fcb1c51bd901825580cf33ae98583fa075a8fa56b4b4ed6afd1d5db14ec", + "1059ffd127251b408d8c70612af6ca00b4a26ddd407b7f48ab61edfa28e39143", + "2cb9490d0b35139398c078a9af2a1b5bcd89a58f86dfb460e308c67cc5af8fed", + "309891719bc11bc39b2bc9136c0fe59e1a5e6b3d69c0eae7b7065c853d56151d", + "a3134c1f122a6cd9b5d4c7439b9c1e4129a331d1910f6ed35f6445ac4002875e", + "a38fa722b751bbce67f56fe7cdbb89ac751f3edb07354790cced4b1fa7a69413", + "b500d1d618fc7a30ea5f00eaa9875b27a8927db4548100f0eabf790e4c37fd60", + "d759a031bde49bc9506a501864d23581fea6c0aa6acbca525a5e255e39232a42", "d9773df0fecf39413ed0696aefa92cd4ebc828a1d6477e6f8974bc781f0c33d8", - "e19a7ec4c49e6664576fcb4c70b6435c11577a28851f021a466b5f0b03d74dbc", - "ed598acaa691f1021ddae949fbb0592ca787f18925b20e168d6f32495b881e7f" + "e19a7ec4c49e6664576fcb4c70b6435c11577a28851f021a466b5f0b03d74dbc" ] }, { @@ -199,144 +199,172 @@ { "name": "generate-InlineChatIntent [inline] [typescript] - issue #3370: generate code duplicates too much", "requests": [ - "011f5b33c1bb16aec91b5686b16ec70741d4d1a22ae9755782f00af055641c87", - "0a8f64415342051ccb5a65ef8cc36ef114c40c7609e0deb6975e8f0d74a9268a", - "0b9c310a2e43a33996379d33b67bc052597398413f3c3452ac66d355fbac4ab7", - "2935ca56a0db9cde70b9b36b9f3342e6e7e38b50b1fecef5355bfc925b9f04c2", - "3747dbd491febe01ee004c1838473f70e21c1fe917ac236f1e83813d8816822b", - "43e9d677808102b008e27f6378f4021b004330713db5c41a136e9afc8e93c9e1", - "a06555e54991287167135fb341c29d2e9d6f4b440e0e95ac1b76477440e4149d", - "a4dc27c55972360147727bd807d6684903dc382aba8b621a2196936d51802c56", - "c558d981a80cd7a3a4c6de37be7e39f19911d0031e2a5b2c3d1df1f8c5edd719", - "df0465bedc22719a5fb5cca52dbf1b2f8c0a8403ef2ba0568a0d1a483c63aa64", - "f6e8a317f731c2db5895564b5579539b7f42d9b5f26d8ccfb62c4537b682a965" + "13616885c0ef7d4b3a34669f0cddba99631851f63332ca53c0f80e001be8c69e", + "169460c00ab5191f66367909b52b1a3c157072fd4ae787beeef36f2956dfe063", + "1f21b9ca70c37ad8aa0290d029c97c58b9d391d65ba4f92e75f5b2a178ef735e", + "36c7b68af8cc6bc43675e613a25ef6cd4b51dab23199c7b8b98e740e624044b3", + "5502ded69eb9aaa24dd3433aaab63911d6706a52d691437f5f1159b0152a2c04", + "67a9dfffa21b9975e106df500a849e7206a7fa4b327aaa9b9ead972417b66e7b", + "782b2e11c1a7b16b1f1a7e845479d5e7a6114c052f6b5185ed785f71e9feff5a", + "79c5e344b1b901144b999095fa9739be705bc8ec22e999ea98e9c11fe43dbeff", + "c0c7916fba3396ddf15276a507eb31b2dac2bd31d85c8a677a8371229ec9339a", + "e49eceedf74a35a65dd6874d89c161e9eff928a3210583eaa0dbc2d14610b4a5", + "ea917dc011f0ae3d02e6ecbd8771d7006bd79e5c2c42fe7cd66e2bf6a76c49c3" ] }, { "name": "generate-InlineChatIntent [inline] [typescript] - issue #3439: Bad edits in this case", "requests": [ - "41164e4b4b1ff7beb6f09e149d902dc1610662645bd78eaf7c8451b4b6de2f8d" + "07fcea9019fe05856c6c4a3a966f3183b14614a7e03e68ef2aacfb1ed7112a38", + "157fd86a5c581cdee909dc303ff17fc81e2106995f7b59859de5a673e389ab0f", + "4538dfdebe3cb1589c33f5c25cea50e3e49580805b3ec4036d7588bf65eeab94", + "53a7fd6d88cd0803fcfcd52997513b149f738d4f27e0c90f6d252f71ba97ab3e", + "679c40ff583afa080fd40dda688ecf8c0c32ab815f3700b1b2971115cdd30a90", + "aaa4888d6fbe180f7bce1fc1fe6529f38418cf08405c564927169413c296e36e", + "bebc6b77d8f39847ca8daf0c793326b76202fc11a2fac8639667540c40a9856a", + "ea1c7e50a86592bf5f5e360ac2a52b39c74616f3a6eeed4a3df629ceae48d987" ] }, { "name": "generate-InlineChatIntent [inline] [typescript] - issue #3602: gen method", "requests": [ - "0d49e6564d944ed4c6d9ab3344e49213dac57e81f235a11fed27644b28f87e77", - "0f51320e3f81729077640a7110a43bf064cc9758ed113140d6d5de85f3e1adf2", - "1697363ccf213530a2899309ad04bb655a3f01fac4b7b17d05e7375bba7172d6", - "2939dfa874c47a1d609769b074e53f0b68aebc5574fce640c17e91e80db6f28c", - "56a6e64ffe7c7f5060212fd374eb2212e101739f2acab48e741efbc5ed4c7b24", - "65147e87a18d6735943d18414c817eeb2d554310ce454c5d7d60e1655297e29e", - "66cd2562318354635126500baca7c708c12ae423e28edf112182bef4ad382207", - "888fc9f6405f349fa83777ab8952e3413c14c85866d0b2453861456eb88fc19f", - "95d8e6ff07ca15fda2eea317b19ccc5a691d599d7314bc19c0b3d9d83e1459df", - "b3315360f0aa1347eb1145d8506c3baca26bab95263ecf6a33d7b85c6ab15fdc", - "f013c3770f47e67d90768bcc225086b133544a7741eaf2c9945ad11df3592f0a" + "00c62cb698611f3bc2671ec569e72f82c7cbc0ac1ddd05ce489e3cbddba7570d", + "00fdd640cdc5238771799e573bc565ef94717b0bb2bb275a7240b7881bcee32d", + "2801c3cfbfc29c247e910270b257f97b548958d4b57a6d6eb5cd4eba79c96945", + "58565de4cfa7073ca2c605961f97e724d562bc0684a35067df9af65c58ce9330", + "7c92bdbcb4584568f06b07f097fee87af18e589c1c675618e244ad5867989fe2", + "806eaccda53edb54eef42ca2aab56f8e1a82ae97473c8eee4a1dfb023463937b", + "9a9ef9a14bff97fb460e0d16b0e9d38d047062fca41d1e48a7c3d19b3d993242", + "d6e10dd696c77f866102b7e041eabd5f61f16377f9c6b82ed2703a1646c0869a", + "ea102d6a60eea2946c75be4602a85de5a6ae9e531e4f504239ea043db115e0bb", + "ed717d97216a0536a32193415808c8302372888349848568fe719df5c5e93e2b", + "f61f34f52018c1c00c68acdc133725efe8fbf3c7e7a8693c5889eef504434700" ] }, { "name": "generate-InlineChatIntent [inline] [typescript] - issue #3604: gen nestjs route", "requests": [ - "52b214f7fc07cac79dfd0842279c1020ea2b9de3e20e16913dd802266e8c2a58", - "d1de467a702901d0de7de0876a9f4f0960fc270fd07cf2dc0c1b591185029211" + "188db017047426abbcd87430d5a2626c793fbc825e619c19d129f9f49907a476", + "360ceadde84f72ac72624d7c7932631fe21fd607e95358becbb4b895ebe60c1f", + "50202baf3581e25766ad92ef85eb4e1a0eac68e90e67393510f1946314a64376", + "51cb1d0ec700b42896a0ceb8994ce0d771501fb02f9de7c040fa4affed47722e", + "563767b26c0b0594295c00743ef84e2691e816977e7971925011860d90f43cc6", + "7670ca140caceac4f2db853b1e59436459d88ad3474a2aaf55fb6195f691c08a", + "778518d319d7999a3e7947ba960c2c6657077d802ff383446813f8645ea5a95f", + "cdd08ae9a7067acf54a50faf3245bc45f98a196da5fa523cbaa5d4df98716eb7" ] }, { "name": "generate-InlineChatIntent [inline] [typescript] - issue #3778: Incorrect streaming edits", "requests": [ - "d30cacf5c2628b9bc314b9b1e441c117ca9776672266d704ec59a60091ed3811" + "ac64c41e95b1f8401e1003f59173bac91303291303a5acfe311ecfda9a1e8855", + "da4629f33d7637e7689c490aa7762045a5d42bdb3a5038d14236bdc6f2c402ce", + "f93c07b1be701f0006a06e4e4a77ce22a511a0244d25a33ca448b1f5f8a62400" ] }, { "name": "generate-InlineChatIntent [inline] [typescript] - issue #4080: Implementing a getter/method duplicates the signature", "requests": [ - "20045736e0204ca5d9bdf2b70411caf49cd4f52649999622c0c5cecd25078691" + "07be99448a374cf0e5f80d68057bbbacdcf79ee3e6da79823884ca9d8dac9fea", + "a4cb673cb0fba3473a187a6ef748fd641f8a4a7be484a2e245d6f4475158a49c", + "ae4bcc71ae3379255991ff0c11185ab9f6335e64dbafc1f4c754c82819fee51d", + "c5505900b83b9ff11f218ca73cc7524fe5b13565d0d107ff767fd58a5977188f", + "e5a931686e9ebae04af8e94d2aa3575aaa195f3f470922f5fadabac64fefdcb9", + "f2844eb4bde6e185d936bac9f86ced1e00d741facd06fd949f562d7ee7375b8b" ] }, { "name": "generate-InlineChatIntent [inline] [typescript] - issue #4179: Imports aren't inserted to the top of the file anymore", "requests": [ - "12a682261e7a0c975afbdcbc602f5da765d1d0982c0fe11d3bc820574bb495d4", - "175cf427a0444030e1fa46b27de8cb34f2c310ca8940537788814be48093c9ed", - "22246f1c96f9b3a86f1ed71c09fd377ee15c506a79dccfd21c930f948d90d1f1", - "26e9585bc7e8f1672d09f4af14e21f7cbaad7f830890dc1c4b7234ff2a6f3c2d", - "2e22f39907ecd936df0c4ecd00e209344f846c8db1e85bd81b542b68e9abdcfe", - "78ee077f151e42cf463b3ea72d987d71e5e3aa02bc996e656fb8e702c7336a16", - "846633d3459648d1992c7643c0dbd0c2cd726e76f26559e44a8df88f87906205", - "b1cdf7870748d54a1cb2f6161c4dd494be95051b40fd08e07a9909c7f2f1eeb2", - "b897b6ff1e337b5498bead4f58e01d7340091415f4492c33ab2d74506b41c42c", - "cff43fb9b577e4722d3f3679c884dbbdeb0cf6dc68d64004a4221dccef723a0b" + "181eb6dd3543663e2d6c81ec6ab94388d0c282ef054688fd30edd4d4ba852e1f", + "30995cd2c2c1376e6225e3440607c704afd82ed863aa437930261c26b8a3dc0f", + "39dc6214ce689bcc25c627ce2aa4289cdefa1420e2143acc60d186d2661ffc01", + "48c230507867d0568d962223c172d07a79cec438d4ba501355ad57f4d8c134e1", + "4a64c60b58342914c195ab053fc722eda30f1bfaee21121dd6495af4375f7102", + "806c23d4a4766447985e852bea61f9a224812af2513261e8f163e9a9e03dec4c", + "cd8e24ae91976432a7b4a2cfcba730277537a612bf29ff665dc02954750539ad", + "f60b699de20da61c97247badaa7acc977f3cadf09c369c97bd64ac6a4e5e161b", + "f91fc766c787cefae04bc92e527be3040ff479f51d1ed90cccee0bfaa9606b4d" ] }, { "name": "generate-InlineChatIntent [inline] [typescript] - issue #6234: generate a TS interface for some JSON", "requests": [ - "3ff407d1904e67d680f568c79b87b73bd0852b49945cea92345858c51592b4d1" + "5022111496ec4fe5c0e38d69f5fac882429a223a7000a85586214c583a10abf7" ] }, { "name": "generate-InlineChatIntent [inline] [typescript] - issue #6505", "requests": [ - "50b7c0ed00f7ca0b783cf7726c0932f4c0c98ffa39d0c08044f8fdf8d3c0b9e7" + "375ea7716649d806765e8370b13d21d696e25ae44fb40315cad63da95e82415f", + "38d8459821d29437c05bdbb32c33c766eab0d5a604740bc27c7e11ec4a4a073b", + "4af79776776d6c26c524a8517b67e01896501de41e6a33b241fbd2f9c905eaf0", + "67e007309b7a8aafd3f590ed91ee6cf57737106deb7465f6fd495be5d71bcbfd", + "90a7a59e7521cb1e35bf3648fe02e5e5b1de6905fbfaa7ecd73b1b8984c4eaf9", + "a9cf5f735b59ecb3fd569ba579b7a7b5d6ba492489aacbe6795c44405850db34", + "b71c5bf0c23adc78e0bfc2605f314e17e823bce5e3f8bf6ab54c3ba0264b99dc", + "b8d89a05f3876729375fe6c3c12f9a9f4cdf413d71cdeda184eea2706e05c274", + "bad6b3fd7a1a8d0e97b924750e5f0bea9a35b98f913f08e9194e6f24030d50c9", + "dcf2938548800ab3d7547005c0459f1f94f6c68398dff5e2023e1d3d575e4fa0" ] }, { "name": "generate-InlineChatIntent [inline] [typescript] - issue #6788", "requests": [ - "31d0dfb616a404e5aee21fb07b115a96d6a95558964b6c865da6b2f68d8975f8", - "4b388b2efe0d0196e1e825532d1990e7e4eff340a37c583c3db306090a2720bf", - "622c6ee431d60690ccbf04c24fb67bd91b1135f9c5ef77b3e9d0057ff4704c7c", - "62dfd6ae6a918c6b3f673b47f586f51ec5d35eaddfef2f594c7b03085935d030", - "651a86a8e30f81597531ca684985758aca1759d267c7372e07ec03609ac5de53", - "6530296cfcb75c363159f6257aa21148ded4393ea8a8157970e2e94fed7b514a", - "d373db992a1f4feacfc6977434b2132cdcd7530a191c491c3a8d87cfd8b3c833", - "f0846ff25376ad20cf4a8df4b029a1cd192749207fe92cdfbaefe99838a488cc" + "1d2af8aff58c8d5896f0e9848033684903a5360265342dfef040d6402d3825a1", + "32b6559e5387e9d3080dd9826b558b443749b0a22574b54727af6be9f9cfc634", + "40c1a042f573b5337d52a7adb3e09edc12d9c43ef76795afa6d611d7716fe303", + "57af89a798236c4b0bd9a86c3c1154f10c670bfccb32f3fd55b6628dd469813f", + "63429e2dbbc045dbde29354df420f0b62798acb2ffab00316a518daaae502107", + "6e4a82baabfa2133c923bd862658d0cda3a2f520c1b395412964c630562ba2c9", + "af105e816b2d990da407313fc1b2a60555f1f9166bbbee33a8607ab49aa9089f", + "b83405fb172e7b8bb7a35b22ed650fa4c66fa5090d947be804ebbc4c050e2aaf", + "d95877db832f7fc26721dfb15500acf5ae3690c008a199feb6fee85b7a1cd3f5", + "e968be2137752586a31477d350e32f0ad6203fcdd513c7ce741445a52c3f16b2", + "f42b360429bd23afe3727a6a074fdcdc6263f69538e04050c7701ac33a0f6aae" ] }, { "name": "generate-InlineChatIntent [inline] [typescript] - issue #7772", "requests": [ - "0fd23730a6d6c9a2976c2c75fad3e000e5e503e321436326977a0f1f4ab7f054", - "36705983e2510e9f61a38931c4e6eb759102828bb64e6d1b87bd5ef33889b12f", - "3e83f8fec6d4f08e48a931ef8655050d4fe9f041f62171ee04da4a20291394e2", - "5729a89fc276ae428073c79d2d44c4edf7f18b08b52fd21b4bf197a8dc9993d3", - "73a24d99162e7b245ce55cb3b2e64ca059dca68e08462106d2326e84fb8b5ca3", - "780015b12a268255c288babd32b7453f671941d66e9b0a96acd03f06d5c2b1cb", - "99076bd1ca7eb1e20d96da3ba7f4a53386ed99ef51cb52a87bb8c4730a5e444e", - "a1467c46801ed0a5cf21235ded169205fdb8ec02e94456da576d1f8ee7433df6", - "c98a151900e9d34d7a1daa1940deabb328ebe29a4a4c90535e09d1659a8e10ea", - "db70523a66145a3e325c7e80106d12b302f5f53a11203ce6003b7a144c4a8b90", - "ef960415a38b0f9c51fa09627515bc2005986ef49cb815d8825610a268341de6" + "07e99d3e339815e6ef0a6be96775e8ac331adef6b0913407564b76b676e62f5d", + "0af74ddb96b3ea31691ad595fb716fe50aabea0b4bc39209486e2859ba72bd61", + "0ebe61f69a2be3b5968649af2d63faba9f778e1a34d9b1d29cc20ba8460a8cdb", + "24c81d3a40a68400f6519f5ca767ad2e8b341bb6d5034723c12f9797dcd8a14b", + "29cfa626c92c967d4026bd5d1c19b04a65aadfea54c2c306860c29386aa161e5", + "3a7b97d20bda4c3bbfbaf64d91a553010519cd875b9faa76d8f6de0e2866bebf", + "3ec3c37517441478f43a0571d90dd74fa247113b6f6123f6714a701d223c0819", + "61ad91eba0c131bcc1384fefd823667e726aa60887d4078ff1349480e80034f8", + "920219dca25e7386f471601e57b5487b963eceda4d5cd85242df4b9650eae2d6", + "cee579894abbfc7365cb445c59c779e64d94ae6141c0492327f2f9a668d5bfb4", + "fe4966aeb5edeb1d17ab6148a85acb66e847f205b370561b71b00d7705db5d08" ] }, { "name": "generate-InlineChatIntent [inline] [typescript] - issue release#142: Inline chat updates code outside of area I expect", "requests": [ - "0478cf51f8cdb9999452b9aa8ad7b87dadcf09be7b8d6bc3d568743bacda26db", - "0f41bb4aeff98212be7623a7cb07cb7bbcef4cc33d3b20a4595d12501ee844ee", - "168f3a9d05da7fadf49b29a17c9afa5a7e2370e2de2e02d71459704b31fe01c9", - "18b452482131f42de6ef97154ccfba0646ae0646f2e9e701fee9dcdec28f93a9", - "3daf2560311fbdd8b23b3f2b9a9ee430231cc8ced7a8f6ba5a2868d0dc396d74", - "563b3ed15aba8a7b6bd263428f9f2b1d32fa181615484aa48a40e3e9428df51b", - "a948e53e2ca49b8d031175c19bc669a035a00a5e78144b3b496b5a4555a09482" + "4852514e4c0c3656d1ae709fca2691061d9be8b85812255e542e14c394018414", + "c2bae4e0761fcaca862f589555d076b24b640f3d4eb0c1e8dbecba572af56f0c" ] }, { "name": "generate-InlineChatIntent [inline] [typescript] - parse keybindings", "requests": [ - "7c1c7c99ef3959ad1bdfe44c672166cd8e8364d9260c0c97cbcb721cd29d8b1a" + "4d0439ec531004aad81a01fb495264e0aff2d0df1f69616b0dedf75892f4df05" ] }, { "name": "generate-InlineChatIntent [inline] [typescript] - too much code generated #6696", "requests": [ - "8bb5e64d75fa9430fcea38abab8597391bc79a6c1dba334c602f3881222eebc1" + "219b88fab7612ab384208539c1c0e468c83e843b1482e40729bb6fd65b34de57", + "2c2bc3bc17360300c6195585923c6afc6ae23aa77112e0d108c729e8997a16c9", + "62d02e5ff40c33ef4f9388f89f4cf9d885dbd82087f57bc8e03f1c255088de51" ] }, { "name": "generate-InlineChatIntent [inline] [typescript] - variables are used when generating", "requests": [ - "15cd8a85a59a4eef8e947665a9fbdf2cecc6c2369ea9da044d3f854f9f93640b" + "8cfab1a7e970a842b9574a069ce75aecc0ca0ae750843e42b1e4e009864867b4" ] } ] \ No newline at end of file diff --git a/test/simulation/baseline.json b/test/simulation/baseline.json index 3c9d5453db..34723f5a15 100644 --- a/test/simulation/baseline.json +++ b/test/simulation/baseline.json @@ -1104,16 +1104,16 @@ { "name": "edit-InlineChatIntent [inline] [cpp] - edit for macro", "contentFilterCount": 0, - "passCount": 10, - "failCount": 0, - "score": 1 + "passCount": 7, + "failCount": 3, + "score": 0.7 }, { "name": "edit-InlineChatIntent [inline] [csharp] - issue release#275: Inline Diff refinement causes massive duplication of code", "contentFilterCount": 0, - "passCount": 8, - "failCount": 2, - "score": 0.8 + "passCount": 10, + "failCount": 0, + "score": 1 }, { "name": "edit-InlineChatIntent [inline] [css] - issue #6469", @@ -1160,9 +1160,9 @@ { "name": "edit-InlineChatIntent [inline] [json] - Inline chat does not leak system prompt", "contentFilterCount": 0, - "passCount": 10, - "failCount": 0, - "score": 1 + "passCount": 9, + "failCount": 1, + "score": 0.9 }, { "name": "edit-InlineChatIntent [inline] [markdown] - issue #5899: make this code more efficient inside markdown", @@ -1181,23 +1181,23 @@ { "name": "edit-InlineChatIntent [inline] [python] - issue #1198: Multi-lingual queries throw off the inline response formatting", "contentFilterCount": 0, - "passCount": 10, - "failCount": 0, - "score": 1 + "passCount": 9, + "failCount": 1, + "score": 0.9 }, { "name": "edit-InlineChatIntent [inline] [typescript] - Context Outline: TypeScript between methods", "contentFilterCount": 0, - "passCount": 10, - "failCount": 0, - "score": 1 + "passCount": 2, + "failCount": 8, + "score": 0.2 }, { "name": "edit-InlineChatIntent [inline] [typescript] - Context Outline: TypeScript in method", "contentFilterCount": 0, - "passCount": 5, - "failCount": 5, - "score": 0.5 + "passCount": 4, + "failCount": 6, + "score": 0.4 }, { "name": "edit-InlineChatIntent [inline] [typescript] - convert ternary to if/else in short function", @@ -1244,9 +1244,9 @@ { "name": "edit-InlineChatIntent [inline] [typescript] - Inline chat touching code outside of my selection #2988", "contentFilterCount": 0, - "passCount": 10, - "failCount": 0, - "score": 1 + "passCount": 4, + "failCount": 6, + "score": 0.4 }, { "name": "edit-InlineChatIntent [inline] [typescript] - Inline chat touching code outside of my selection #2988 with good selection", @@ -1265,9 +1265,9 @@ { "name": "edit-InlineChatIntent [inline] [typescript] - issue #246: Add comment sends request to sidebar", "contentFilterCount": 0, - "passCount": 10, - "failCount": 0, - "score": 1 + "passCount": 9, + "failCount": 1, + "score": 0.9 }, { "name": "edit-InlineChatIntent [inline] [typescript] - issue #3257: Inline chat ends up duplicating code", @@ -1307,16 +1307,16 @@ { "name": "edit-InlineChatIntent [inline] [typescript] - issue #4149: If ChatGPT makes the request, send only the first 20 episodes", "contentFilterCount": 0, - "passCount": 0, - "failCount": 10, - "score": 0 + "passCount": 10, + "failCount": 0, + "score": 1 }, { "name": "edit-InlineChatIntent [inline] [typescript] - issue #4151: Rewrite the selection to use async/await", "contentFilterCount": 0, - "passCount": 5, - "failCount": 5, - "score": 0.5 + "passCount": 10, + "failCount": 0, + "score": 1 }, { "name": "edit-InlineChatIntent [inline] [typescript] - issue #4302: Code doesn't come with backticks", @@ -1328,9 +1328,9 @@ { "name": "edit-InlineChatIntent [inline] [typescript] - issue #5710: Code doesn't come with backticks", "contentFilterCount": 0, - "passCount": 10, - "failCount": 0, - "score": 1 + "passCount": 9, + "failCount": 1, + "score": 0.9 }, { "name": "edit-InlineChatIntent [inline] [typescript] - issue #5755: Inline edits go outside the selection", @@ -1349,9 +1349,9 @@ { "name": "edit-InlineChatIntent [inline] [typescript] - issue #6276", "contentFilterCount": 0, - "passCount": 1, - "failCount": 9, - "score": 0.1 + "passCount": 0, + "failCount": 10, + "score": 0 }, { "name": "edit-InlineChatIntent [inline] [typescript] - issue #6973", @@ -1363,16 +1363,16 @@ { "name": "edit-InlineChatIntent [inline] [typescript] - issue #7202", "contentFilterCount": 0, - "passCount": 5, - "failCount": 5, - "score": 0.5 + "passCount": 9, + "failCount": 1, + "score": 0.9 }, { "name": "edit-InlineChatIntent [inline] [typescript] - issue #7660", "contentFilterCount": 0, - "passCount": 1, - "failCount": 9, - "score": 0.1 + "passCount": 4, + "failCount": 6, + "score": 0.4 }, { "name": "edit-InlineChatIntent [inline] [typescript] - Issue #7996 - use entire context window", @@ -1398,9 +1398,9 @@ { "name": "edit-InlineChatIntent [inline] [typescript] - refactor forloop, but only selected one", "contentFilterCount": 0, - "passCount": 10, - "failCount": 0, - "score": 1 + "passCount": 1, + "failCount": 9, + "score": 0.1 }, { "name": "edit-InlineChatIntent [inline] [typescriptreact] - issue #7487", @@ -2439,16 +2439,16 @@ { "name": "fix-InlineChatIntent (eslint) [inline] [typescript] - (AML-17-152) unreachable code", "contentFilterCount": 0, - "passCount": 10, - "failCount": 0, - "score": 1 + "passCount": 9, + "failCount": 1, + "score": 0.9 }, { "name": "fix-InlineChatIntent (eslint) [inline] [typescript] - (AML-17-166) unexpected control character", "contentFilterCount": 0, - "passCount": 0, - "failCount": 10, - "score": 0 + "passCount": 10, + "failCount": 0, + "score": 1 }, { "name": "fix-InlineChatIntent (eslint) [inline] [typescript] - (AML-17-243) unexpected constant condition 2", @@ -2460,23 +2460,23 @@ { "name": "fix-InlineChatIntent (eslint) [inline] [typescript] - class-methods-use-this with cookbook", "contentFilterCount": 0, - "passCount": 4, - "failCount": 6, - "score": 0.4 + "passCount": 3, + "failCount": 7, + "score": 0.3 }, { "name": "fix-InlineChatIntent (eslint) [inline] [typescript] - comma expected", "contentFilterCount": 0, - "passCount": 10, - "failCount": 0, - "score": 1 + "passCount": 0, + "failCount": 10, + "score": 0 }, { "name": "fix-InlineChatIntent (eslint) [inline] [typescript] - consistent-this with cookbook", "contentFilterCount": 0, - "passCount": 1, - "failCount": 9, - "score": 0.1 + "passCount": 10, + "failCount": 0, + "score": 1 }, { "name": "fix-InlineChatIntent (eslint) [inline] [typescript] - constructor-super with cookbook", @@ -2509,16 +2509,16 @@ { "name": "fix-InlineChatIntent (eslint) [inline] [typescript] - max-lines-per-function with cookbook", "contentFilterCount": 0, - "passCount": 0, - "failCount": 10, - "score": 0 + "passCount": 1, + "failCount": 9, + "score": 0.1 }, { "name": "fix-InlineChatIntent (eslint) [inline] [typescript] - max-params with cookbook", "contentFilterCount": 0, - "passCount": 10, - "failCount": 0, - "score": 1 + "passCount": 0, + "failCount": 10, + "score": 0 }, { "name": "fix-InlineChatIntent (eslint) [inline] [typescript] - max-statements with cookbook", @@ -2537,37 +2537,37 @@ { "name": "fix-InlineChatIntent (eslint) [inline] [typescript] - no-dupe-else-if with cookbook", "contentFilterCount": 0, - "passCount": 5, - "failCount": 5, - "score": 0.5 + "passCount": 0, + "failCount": 10, + "score": 0 }, { "name": "fix-InlineChatIntent (eslint) [inline] [typescript] - no-duplicate-case with cookbook", "contentFilterCount": 0, - "passCount": 10, - "failCount": 0, - "score": 1 + "passCount": 4, + "failCount": 6, + "score": 0.4 }, { "name": "fix-InlineChatIntent (eslint) [inline] [typescript] - no-duplicate-imports with cookbook", "contentFilterCount": 0, - "passCount": 10, - "failCount": 0, - "score": 1 + "passCount": 0, + "failCount": 10, + "score": 0 }, { "name": "fix-InlineChatIntent (eslint) [inline] [typescript] - no-fallthrough with cookbook", "contentFilterCount": 0, - "passCount": 9, - "failCount": 1, - "score": 0.9 + "passCount": 2, + "failCount": 8, + "score": 0.2 }, { "name": "fix-InlineChatIntent (eslint) [inline] [typescript] - no-inner-declarations with cookbook", "contentFilterCount": 0, - "passCount": 4, - "failCount": 6, - "score": 0.4 + "passCount": 5, + "failCount": 5, + "score": 0.5 }, { "name": "fix-InlineChatIntent (eslint) [inline] [typescript] - no-multi-assign with cookbook", @@ -2607,23 +2607,23 @@ { "name": "fix-InlineChatIntent (eslint) [inline] [typescript] - no-sparse-arrays 2 with cookbook", "contentFilterCount": 0, - "passCount": 1, - "failCount": 9, - "score": 0.1 + "passCount": 10, + "failCount": 0, + "score": 1 }, { "name": "fix-InlineChatIntent (eslint) [inline] [typescript] - no-sparse-arrays 3 with cookbook", "contentFilterCount": 0, - "passCount": 8, - "failCount": 2, - "score": 0.8 + "passCount": 7, + "failCount": 3, + "score": 0.7 }, { "name": "fix-InlineChatIntent (eslint) [inline] [typescript] - no-sparse-arrays with cookbook", "contentFilterCount": 0, - "passCount": 9, - "failCount": 1, - "score": 0.9 + "passCount": 7, + "failCount": 3, + "score": 0.7 }, { "name": "fix-InlineChatIntent (eslint) [inline] [typescript] - require-await with cookbook", @@ -2635,16 +2635,16 @@ { "name": "fix-InlineChatIntent (eslint) [inline] [typescript] - sort-keys with cookbook", "contentFilterCount": 0, - "passCount": 2, - "failCount": 8, - "score": 0.2 + "passCount": 10, + "failCount": 0, + "score": 1 }, { "name": "fix-InlineChatIntent (eslint) [inline] [typescript] - unexpected token", "contentFilterCount": 0, - "passCount": 2, - "failCount": 8, - "score": 0.2 + "passCount": 10, + "failCount": 0, + "score": 1 }, { "name": "fix-InlineChatIntent (powershell) [inline] [powershell] - Issue #7894", @@ -2663,16 +2663,16 @@ { "name": "fix-InlineChatIntent (pylint) [inline] [python] - line-too-long cookbook 2 long print statememt", "contentFilterCount": 0, - "passCount": 10, - "failCount": 0, - "score": 1 + "passCount": 9, + "failCount": 1, + "score": 0.9 }, { "name": "fix-InlineChatIntent (pylint) [inline] [python] - line-too-long cookbook 3 long dictionary / list", "contentFilterCount": 0, - "passCount": 9, - "failCount": 1, - "score": 0.9 + "passCount": 6, + "failCount": 4, + "score": 0.6 }, { "name": "fix-InlineChatIntent (pylint) [inline] [python] - line-too-long cookbook 4 long if condition and function call", @@ -2698,9 +2698,9 @@ { "name": "fix-InlineChatIntent (pylint) [inline] [python] - unused module imported", "contentFilterCount": 0, - "passCount": 10, - "failCount": 0, - "score": 1 + "passCount": 9, + "failCount": 1, + "score": 0.9 }, { "name": "fix-InlineChatIntent (pyright) [inline] [python] - (AML-10-15) object not subscriptable", @@ -2726,9 +2726,9 @@ { "name": "fix-InlineChatIntent (pyright) [inline] [python] - (AML-10-35) can not access member", "contentFilterCount": 0, - "passCount": 10, - "failCount": 0, - "score": 1 + "passCount": 9, + "failCount": 1, + "score": 0.9 }, { "name": "fix-InlineChatIntent (pyright) [inline] [python] - (AML-10-36) can not be assigned 2", @@ -2782,51 +2782,51 @@ { "name": "fix-InlineChatIntent (pyright) [inline] [python] - async cannot be used in a non-async function", "contentFilterCount": 0, - "passCount": 1, - "failCount": 9, - "score": 0.1 + "passCount": 0, + "failCount": 10, + "score": 0 }, { "name": "fix-InlineChatIntent (pyright) [inline] [python] - await cannot be used in a non-async function", "contentFilterCount": 0, - "passCount": 6, - "failCount": 4, - "score": 0.6 + "passCount": 10, + "failCount": 0, + "score": 1 }, { "name": "fix-InlineChatIntent (pyright) [inline] [python] - bad token", "contentFilterCount": 0, - "passCount": 7, - "failCount": 3, - "score": 0.7 + "passCount": 5, + "failCount": 5, + "score": 0.5 }, { "name": "fix-InlineChatIntent (pyright) [inline] [python] - Bar does not define a do_something2 method", "contentFilterCount": 0, - "passCount": 10, - "failCount": 0, - "score": 1 + "passCount": 0, + "failCount": 10, + "score": 0 }, { "name": "fix-InlineChatIntent (pyright) [inline] [python] - cannot instantiate abstract class", "contentFilterCount": 0, - "passCount": 10, - "failCount": 0, - "score": 1 + "passCount": 9, + "failCount": 1, + "score": 0.9 }, { "name": "fix-InlineChatIntent (pyright) [inline] [python] - general type issue", "contentFilterCount": 0, - "passCount": 3, - "failCount": 7, - "score": 0.3 + "passCount": 9, + "failCount": 1, + "score": 0.9 }, { "name": "fix-InlineChatIntent (pyright) [inline] [python] - import missing", "contentFilterCount": 0, - "passCount": 5, - "failCount": 5, - "score": 0.5 + "passCount": 3, + "failCount": 7, + "score": 0.3 }, { "name": "fix-InlineChatIntent (pyright) [inline] [python] - optional member access", @@ -2838,9 +2838,9 @@ { "name": "fix-InlineChatIntent (pyright) [inline] [python] - should not generate an error for variables declared in outer scopes", "contentFilterCount": 0, - "passCount": 10, - "failCount": 0, - "score": 1 + "passCount": 9, + "failCount": 1, + "score": 0.9 }, { "name": "fix-InlineChatIntent (pyright) [inline] [python] - unbound variable", @@ -2859,9 +2859,9 @@ { "name": "fix-InlineChatIntent (roslyn) [inline] [csharp] - (AML-10-28) field is never used", "contentFilterCount": 0, - "passCount": 9, - "failCount": 1, - "score": 0.9 + "passCount": 10, + "failCount": 0, + "score": 1 }, { "name": "fix-InlineChatIntent (roslyn) [inline] [csharp] - (AML-10-57) call is not awaited, execution continues", @@ -2922,9 +2922,9 @@ { "name": "fix-InlineChatIntent (TSC) [inline] [typescript] - (AML-10-31) Parameter data implicitly has an any type.", "contentFilterCount": 0, - "passCount": 6, - "failCount": 4, - "score": 0.6 + "passCount": 2, + "failCount": 8, + "score": 0.2 }, { "name": "fix-InlineChatIntent (TSC) [inline] [typescript] - 22222 Error 2322 - type undefined is not assignable to type", @@ -2971,16 +2971,16 @@ { "name": "fix-InlineChatIntent (TSC) [inline] [typescript] - Error 18047 - (AML-10-64) possibly null", "contentFilterCount": 0, - "passCount": 10, - "failCount": 0, - "score": 1 + "passCount": 7, + "failCount": 3, + "score": 0.7 }, { "name": "fix-InlineChatIntent (TSC) [inline] [typescript] - Error 18047 - (AML-8-1) property does not exist on type window", "contentFilterCount": 0, - "passCount": 0, - "failCount": 10, - "score": 0 + "passCount": 1, + "failCount": 9, + "score": 0.1 }, { "name": "fix-InlineChatIntent (TSC) [inline] [typescript] - Error 18048 - (AML-10-86) possibly undefined", @@ -2999,9 +2999,9 @@ { "name": "fix-InlineChatIntent (TSC) [inline] [typescript] - Error 2304 - (AML-8-125) can not find name", "contentFilterCount": 0, - "passCount": 10, - "failCount": 0, - "score": 1 + "passCount": 6, + "failCount": 4, + "score": 0.6 }, { "name": "fix-InlineChatIntent (TSC) [inline] [typescript] - Error 2304 - (AML-8-125) can not find name 2", @@ -3076,9 +3076,9 @@ { "name": "fix-InlineChatIntent (TSC) [inline] [typescript] - Error 2355 - a function whose declared type is neither undefined, void, nor any must return a value.", "contentFilterCount": 0, - "passCount": 10, - "failCount": 0, - "score": 1 + "passCount": 2, + "failCount": 8, + "score": 0.2 }, { "name": "fix-InlineChatIntent (TSC) [inline] [typescript] - Error 2391 - function implementation is missing or not immediately following the declaration", @@ -3104,9 +3104,9 @@ { "name": "fix-InlineChatIntent (TSC) [inline] [typescript] - Error 2454 - variable is used before being assigned", "contentFilterCount": 0, - "passCount": 10, - "failCount": 0, - "score": 1 + "passCount": 9, + "failCount": 1, + "score": 0.9 }, { "name": "fix-InlineChatIntent (TSC) [inline] [typescript] - Error 2554 - expected m arguments, but got n.", @@ -3139,9 +3139,9 @@ { "name": "fix-InlineChatIntent (TSC) [inline] [typescript] - Error 7053 - (AML-10-25) expression of type can't be used to index", "contentFilterCount": 0, - "passCount": 10, - "failCount": 0, - "score": 1 + "passCount": 4, + "failCount": 6, + "score": 0.4 }, { "name": "fix-InlineChatIntent (TSC) [inline] [typescript] - Issue #7300", @@ -3489,9 +3489,9 @@ { "name": "generate-InlineChatIntent [inline] [json] - issue #2589: IllegalArgument: line must be non-negative", "contentFilterCount": 0, - "passCount": 10, - "failCount": 0, - "score": 1 + "passCount": 9, + "failCount": 1, + "score": 0.9 }, { "name": "generate-InlineChatIntent [inline] [json] - issue #6163", @@ -3510,9 +3510,9 @@ { "name": "generate-InlineChatIntent [inline] [markdown] - doesn't handle markdown code response", "contentFilterCount": 0, - "passCount": 9, - "failCount": 1, - "score": 0.9 + "passCount": 10, + "failCount": 0, + "score": 1 }, { "name": "generate-InlineChatIntent [inline] [markdown] - issue #224: Lots of lines deleted when using interactive chat in a markdown file", @@ -3566,9 +3566,9 @@ { "name": "generate-InlineChatIntent [inline] [typescript] - gen-ts-ltrim", "contentFilterCount": 0, - "passCount": 4, - "failCount": 6, - "score": 0.4 + "passCount": 10, + "failCount": 0, + "score": 1 }, { "name": "generate-InlineChatIntent [inline] [typescript] - generate rtrim", @@ -3629,9 +3629,9 @@ { "name": "generate-InlineChatIntent [inline] [typescript] - issue #4080: Implementing a getter/method duplicates the signature", "contentFilterCount": 0, - "passCount": 1, - "failCount": 9, - "score": 0.1 + "passCount": 10, + "failCount": 0, + "score": 1 }, { "name": "generate-InlineChatIntent [inline] [typescript] - issue #4179: Imports aren't inserted to the top of the file anymore", @@ -3643,16 +3643,16 @@ { "name": "generate-InlineChatIntent [inline] [typescript] - issue #6234: generate a TS interface for some JSON", "contentFilterCount": 0, - "passCount": 4, - "failCount": 6, - "score": 0.4 + "passCount": 10, + "failCount": 0, + "score": 1 }, { "name": "generate-InlineChatIntent [inline] [typescript] - issue #6505", "contentFilterCount": 0, - "passCount": 3, - "failCount": 7, - "score": 0.3 + "passCount": 0, + "failCount": 10, + "score": 0 }, { "name": "generate-InlineChatIntent [inline] [typescript] - issue #6788", @@ -3671,16 +3671,16 @@ { "name": "generate-InlineChatIntent [inline] [typescript] - issue release#142: Inline chat updates code outside of area I expect", "contentFilterCount": 0, - "passCount": 10, - "failCount": 0, - "score": 1 + "passCount": 0, + "failCount": 10, + "score": 0 }, { "name": "generate-InlineChatIntent [inline] [typescript] - parse keybindings", "contentFilterCount": 0, - "passCount": 4, - "failCount": 6, - "score": 0.4 + "passCount": 9, + "failCount": 1, + "score": 0.9 }, { "name": "generate-InlineChatIntent [inline] [typescript] - too much code generated #6696", diff --git a/test/simulation/cache/layers/c451045a-da8c-43fa-ba6f-8198c2eb0975.sqlite b/test/simulation/cache/layers/c451045a-da8c-43fa-ba6f-8198c2eb0975.sqlite new file mode 100644 index 0000000000..1e9656fcea --- /dev/null +++ b/test/simulation/cache/layers/c451045a-da8c-43fa-ba6f-8198c2eb0975.sqlite @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:03490cf9f3f5c0869e3237e94efa86640f5bf59a738dc1ca44580d66b5cc17f2 +size 7745536