Skip to content

Commit

Permalink
Add Copilot UI prototype to Semantic Search window (#77222)
Browse files Browse the repository at this point in the history
  • Loading branch information
tmat authored Feb 21, 2025
1 parent aebe202 commit a0da860
Show file tree
Hide file tree
Showing 25 changed files with 559 additions and 20 deletions.
17 changes: 12 additions & 5 deletions Roslyn.sln
Original file line number Diff line number Diff line change
Expand Up @@ -579,6 +579,8 @@ Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "Microsoft.CodeAnalysis.Cont
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.CodeAnalysis.Contracts.Package", "src\Dependencies\Contracts\Microsoft.CodeAnalysis.Contracts.Package.csproj", "{A8D5CFFA-7F9E-C35B-4F19-D63F6EC1D5CA}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.VisualStudio.LanguageServices.ExternalAccess.Copilot", "src\VisualStudio\ExternalAccess\Copilot\Microsoft.VisualStudio.LanguageServices.ExternalAccess.Copilot.csproj", "{9EB058F3-10C9-8F3F-AD9E-72CB362A0928}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -1365,6 +1367,10 @@ Global
{B1481D94-682E-46EC-ADBE-A16EB46FEEE9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B1481D94-682E-46EC-ADBE-A16EB46FEEE9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B1481D94-682E-46EC-ADBE-A16EB46FEEE9}.Release|Any CPU.Build.0 = Release|Any CPU
{5D60CF30-28A9-9F0F-7610-D90E4A69AE73}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5D60CF30-28A9-9F0F-7610-D90E4A69AE73}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5D60CF30-28A9-9F0F-7610-D90E4A69AE73}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5D60CF30-28A9-9F0F-7610-D90E4A69AE73}.Release|Any CPU.Build.0 = Release|Any CPU
{09AEDEE4-6358-47C9-8022-3BD37A518070}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{09AEDEE4-6358-47C9-8022-3BD37A518070}.Debug|Any CPU.Build.0 = Debug|Any CPU
{09AEDEE4-6358-47C9-8022-3BD37A518070}.Release|Any CPU.ActiveCfg = Release|Any CPU
Expand Down Expand Up @@ -1409,10 +1415,6 @@ Global
{900168D7-D982-86CE-5097-C5F173BA4D8B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{900168D7-D982-86CE-5097-C5F173BA4D8B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{900168D7-D982-86CE-5097-C5F173BA4D8B}.Release|Any CPU.Build.0 = Release|Any CPU
{5D60CF30-28A9-9F0F-7610-D90E4A69AE73}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5D60CF30-28A9-9F0F-7610-D90E4A69AE73}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5D60CF30-28A9-9F0F-7610-D90E4A69AE73}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5D60CF30-28A9-9F0F-7610-D90E4A69AE73}.Release|Any CPU.Build.0 = Release|Any CPU
{2559DAF9-784E-4C29-E0E1-70204B1FD56E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2559DAF9-784E-4C29-E0E1-70204B1FD56E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2559DAF9-784E-4C29-E0E1-70204B1FD56E}.Release|Any CPU.ActiveCfg = Release|Any CPU
Expand All @@ -1421,6 +1423,10 @@ Global
{A8D5CFFA-7F9E-C35B-4F19-D63F6EC1D5CA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A8D5CFFA-7F9E-C35B-4F19-D63F6EC1D5CA}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A8D5CFFA-7F9E-C35B-4F19-D63F6EC1D5CA}.Release|Any CPU.Build.0 = Release|Any CPU
{9EB058F3-10C9-8F3F-AD9E-72CB362A0928}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9EB058F3-10C9-8F3F-AD9E-72CB362A0928}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9EB058F3-10C9-8F3F-AD9E-72CB362A0928}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9EB058F3-10C9-8F3F-AD9E-72CB362A0928}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -1666,6 +1672,7 @@ Global
{A833B11C-5072-4A1F-A32B-2700433B0D3D} = {806F0C6F-3640-4C92-8D55-6767B1535467}
{8988270E-393A-4B92-AC1A-534F903CFD34} = {8977A560-45C2-4EC2-A849-97335B382C74}
{B1481D94-682E-46EC-ADBE-A16EB46FEEE9} = {55A62CFA-1155-46F1-ADF3-BEEE51B58AB5}
{5D60CF30-28A9-9F0F-7610-D90E4A69AE73} = {58A2876A-618D-4AE6-A136-E44B42BBDE11}
{09AEDEE4-6358-47C9-8022-3BD37A518070} = {5880FECB-91F1-4AB8-8726-75EAFA8A918E}
{5BABC440-4F1B-46E8-9068-DD7F02ED25D3} = {3E5FE3DB-45F7-4D83-9097-8F05D3B3AEC6}
{5762E483-75CE-4328-A410-511F30737712} = {3E5FE3DB-45F7-4D83-9097-8F05D3B3AEC6}
Expand All @@ -1683,11 +1690,11 @@ Global
{806F0C6F-3640-4C92-8D55-6767B1535467} = {D449D505-CC6A-4E0B-AF1B-976E2D0AE67A}
{7465CE63-A7B7-475F-8C57-48D2F8BC665A} = {D449D505-CC6A-4E0B-AF1B-976E2D0AE67A}
{900168D7-D982-86CE-5097-C5F173BA4D8B} = {806F0C6F-3640-4C92-8D55-6767B1535467}
{5D60CF30-28A9-9F0F-7610-D90E4A69AE73} = {58A2876A-618D-4AE6-A136-E44B42BBDE11}
{967723E8-4FDD-447B-99F6-4F8C47CB5433} = {C2D1346B-9665-4150-B644-075CF1636BAA}
{2559DAF9-784E-4C29-E0E1-70204B1FD56E} = {C2D1346B-9665-4150-B644-075CF1636BAA}
{BD974609-C68B-4BE6-9682-EB132462B50D} = {C2D1346B-9665-4150-B644-075CF1636BAA}
{A8D5CFFA-7F9E-C35B-4F19-D63F6EC1D5CA} = {C2D1346B-9665-4150-B644-075CF1636BAA}
{9EB058F3-10C9-8F3F-AD9E-72CB362A0928} = {5880FECB-91F1-4AB8-8726-75EAFA8A918E}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {604E6B91-7BC0-4126-AE07-D4D2FEFC3D29}
Expand Down
3 changes: 2 additions & 1 deletion eng/config/PublishData.json
Original file line number Diff line number Diff line change
Expand Up @@ -83,14 +83,15 @@
"Microsoft.CodeAnalysis.ExternalAccess.UnitTesting": "vs-impl",
"Microsoft.CodeAnalysis.ExternalAccess.VisualDiagnostics": "vs-impl",
"Microsoft.CodeAnalysis.ExternalAccess.Xamarin.Remote": "vs-impl",
"Microsoft.CodeAnalysis.ExternalAccess.Xaml": "vs-impl",
"Microsoft.CodeAnalysis.ExternalAccess.Xaml": "vs-impl",
"Microsoft.CodeAnalysis.ExternalAccess.DotNetWatch": "vs-impl",
"Microsoft.CodeAnalysis.LanguageServer.ExternalAccess.Copilot": "vs-impl",
"Microsoft.CodeAnalysis.Remote.Razor.ServiceHub": "vs-impl",
"Microsoft.CodeAnalysis.Remote.ServiceHub": "vs-impl",
"Microsoft.CodeAnalysis.Remote.Workspaces": "vs-impl",
"Microsoft.VisualStudio.LanguageServices.LiveShare": "vs-impl",
"Microsoft.VisualStudio.LanguageServices.Razor.RemoteClient": "vs-impl",
"Microsoft.VisualStudio.LanguageServices.ExternalAccess.Copilot": "vs-impl",
"Microsoft.CommonLanguageServerProtocol.Framework": "vs-impl",
"Microsoft.CommonLanguageServerProtocol.Framework.Binary": "vs-impl"
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@
<InternalsVisibleTo Include="Microsoft.VisualStudio.LanguageServices.UnitTests" />
<InternalsVisibleTo Include="Microsoft.VisualStudio.LanguageServices.VisualBasic" />
<InternalsVisibleTo Include="Microsoft.VisualStudio.LanguageServices.Xaml" />
<InternalsVisibleTo Include="Microsoft.VisualStudio.LanguageServices.ExternalAccess.Copilot" />
<InternalsVisibleTo Include="Roslyn.Hosting.Diagnostics" />
<InternalsVisibleTo Include="Roslyn.Services.Editor.TypeScript.UnitTests" Key="$(TypeScriptKey)" WorkItem="https://github.com/dotnet/roslyn/issues/35077" />
<InternalsVisibleTo Include="Roslyn.VisualStudio.DiagnosticsWindow" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ internal sealed class CSharpSemanticSearchUtilities
Query = """
static IEnumerable<ISymbol> Find(Compilation compilation)
{
return compilation.GlobalNamespace.GetMembers("C");
return compilation.Assembly.GlobalNamespace.GetMembers("C");
}
""",
GlobalUsings = """
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@
<InternalsVisibleTo Include="Microsoft.VisualStudio.LanguageServices.UnitTests" />
<InternalsVisibleTo Include="Microsoft.VisualStudio.LanguageServices.VisualBasic" />
<InternalsVisibleTo Include="Microsoft.VisualStudio.LanguageServices.Xaml" />
<InternalsVisibleTo Include="Microsoft.VisualStudio.LanguageServices.ExternalAccess.Copilot" />
<InternalsVisibleTo Include="Roslyn.Hosting.Diagnostics" />
<InternalsVisibleTo Include="Roslyn.Services.Editor.TypeScript.UnitTests" Key="$(TypeScriptKey)" WorkItem="https://github.com/dotnet/roslyn/issues/35077" />
<InternalsVisibleTo Include="Roslyn.VisualStudio.DiagnosticsWindow" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System.Threading;
using System.Threading.Tasks;

namespace Microsoft.CodeAnalysis.SemanticSearch;

internal interface ISemanticSearchCopilotService
{
bool IsAvailable { get; }

/// <summary>
/// Translates natural language <paramref name="text"/> to C# query.
/// </summary>
ValueTask<SemanticSearchCopilotGeneratedQuery> TryGetQueryAsync(string text, SemanticSearchCopilotContext context, CancellationToken cancellationToken);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System;
using System.Collections.Generic;

namespace Microsoft.CodeAnalysis.SemanticSearch;

/// <summary>
/// Context necessary to generate Copilot prompt for semantic search query.
/// </summary>
internal sealed class SemanticSearchCopilotContext
{
public required string ModelName { get; init; }

/// <summary>
/// List of package names and versions that to include in the prompt.
/// </summary>
public required IEnumerable<(string name, Version version)> AvailablePackages { get; init; }
}

internal readonly struct SemanticSearchCopilotGeneratedQuery
{
/// <summary>
/// The generated code or an error message.
/// </summary>
public required string Text { get; init; }

/// <summary>
/// True if <see cref="Text"/> is an error message.
/// </summary>
public required bool IsError { get; init; }
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System;
using System.Composition;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.Host.Mef;
using Microsoft.CodeAnalysis.ExternalAccess.Copilot.SemanticSearch;
using Microsoft.CodeAnalysis.SemanticSearch;

namespace Microsoft.CodeAnalysis.ExternalAccess.Copilot.Internal.SemanticSearch;

[Export(typeof(ISemanticSearchCopilotService)), Shared]
[method: ImportingConstructor]
[method: Obsolete(MefConstruction.ImportingConstructorMessage, error: true)]
internal sealed class SemanticSearchCopilotServiceWrapper(
[Import(AllowDefault = true)] Lazy<ISemanticSearchCopilotServiceImpl>? impl) : ISemanticSearchCopilotService
{
bool ISemanticSearchCopilotService.IsAvailable
=> impl != null;

async ValueTask<SemanticSearchCopilotGeneratedQuery> ISemanticSearchCopilotService.TryGetQueryAsync(string text, SemanticSearchCopilotContext context, CancellationToken cancellationToken)
{
Contract.ThrowIfNull(impl);

var result = await impl.Value.TryGetQueryAsync(
text,
new SemanticSearchCopilotContextImpl()
{
ModelName = context.ModelName,
AvailablePackages = context.AvailablePackages,
},
cancellationToken).ConfigureAwait(false);

return new SemanticSearchCopilotGeneratedQuery()
{
IsError = result.IsError,
Text = result.Text,
};
}
}
16 changes: 16 additions & 0 deletions src/Features/ExternalAccess/Copilot/InternalAPI.Unshipped.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,22 @@ Microsoft.CodeAnalysis.ExternalAccess.Copilot.IExternalCSharpCopilotGenerateDocu
Microsoft.CodeAnalysis.ExternalAccess.Copilot.IExternalCSharpCopilotGenerateDocumentationService.GetDocumentationCommentAsync(Microsoft.CodeAnalysis.ExternalAccess.Copilot.CopilotDocumentationCommentProposalWrapper! proposal, System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task<(System.Collections.Generic.Dictionary<string!, string!>? responseDictionary, bool isQuotaExceeded)>!
Microsoft.CodeAnalysis.ExternalAccess.Copilot.RelatedDocuments.ICopilotRelatedDocumentsService
Microsoft.CodeAnalysis.ExternalAccess.Copilot.RelatedDocuments.ICopilotRelatedDocumentsService.GetRelatedDocumentIdsAsync(Microsoft.CodeAnalysis.Document! document, int position, System.Func<System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.DocumentId!>, System.Threading.CancellationToken, System.Threading.Tasks.ValueTask>! callbackAsync, System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.ValueTask
Microsoft.CodeAnalysis.ExternalAccess.Copilot.SemanticSearch.ISemanticSearchCopilotServiceImpl
Microsoft.CodeAnalysis.ExternalAccess.Copilot.SemanticSearch.ISemanticSearchCopilotServiceImpl.TryGetQueryAsync(string! text, Microsoft.CodeAnalysis.ExternalAccess.Copilot.SemanticSearch.SemanticSearchCopilotContextImpl! context, System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.ValueTask<Microsoft.CodeAnalysis.ExternalAccess.Copilot.SemanticSearch.SemanticSearchCopilotGeneratedQueryImpl>
Microsoft.CodeAnalysis.ExternalAccess.Copilot.SemanticSearch.SemanticSearchCopilotContextImpl
Microsoft.CodeAnalysis.ExternalAccess.Copilot.SemanticSearch.SemanticSearchCopilotContextImpl.AvailablePackages.get -> System.Collections.Generic.IEnumerable<(string! name, System.Version! version)>!
Microsoft.CodeAnalysis.ExternalAccess.Copilot.SemanticSearch.SemanticSearchCopilotContextImpl.AvailablePackages.init -> void
Microsoft.CodeAnalysis.ExternalAccess.Copilot.SemanticSearch.SemanticSearchCopilotContextImpl.ModelName.get -> string!
Microsoft.CodeAnalysis.ExternalAccess.Copilot.SemanticSearch.SemanticSearchCopilotContextImpl.ModelName.init -> void
Microsoft.CodeAnalysis.ExternalAccess.Copilot.SemanticSearch.SemanticSearchCopilotContextImpl.SemanticSearchCopilotContextImpl() -> void
Microsoft.CodeAnalysis.ExternalAccess.Copilot.SemanticSearch.SemanticSearchCopilotGeneratedQueryImpl
Microsoft.CodeAnalysis.ExternalAccess.Copilot.SemanticSearch.SemanticSearchCopilotGeneratedQueryImpl.IsError.get -> bool
Microsoft.CodeAnalysis.ExternalAccess.Copilot.SemanticSearch.SemanticSearchCopilotGeneratedQueryImpl.IsError.init -> void
Microsoft.CodeAnalysis.ExternalAccess.Copilot.SemanticSearch.SemanticSearchCopilotGeneratedQueryImpl.SemanticSearchCopilotGeneratedQueryImpl() -> void
Microsoft.CodeAnalysis.ExternalAccess.Copilot.SemanticSearch.SemanticSearchCopilotGeneratedQueryImpl.Text.get -> string!
Microsoft.CodeAnalysis.ExternalAccess.Copilot.SemanticSearch.SemanticSearchCopilotGeneratedQueryImpl.Text.init -> void
Microsoft.CodeAnalysis.SemanticSearch.SemanticSearchCopilotServiceWrapper
Microsoft.CodeAnalysis.SemanticSearch.SemanticSearchCopilotServiceWrapper.SemanticSearchCopilotServiceWrapper(System.Lazy<Microsoft.CodeAnalysis.ExternalAccess.Copilot.SemanticSearch.ISemanticSearchCopilotServiceImpl!>? impl) -> void
override Microsoft.CodeAnalysis.ExternalAccess.Copilot.CopilotChecksumWrapper.Equals(object? obj) -> bool
override Microsoft.CodeAnalysis.ExternalAccess.Copilot.CopilotChecksumWrapper.GetHashCode() -> int
static Microsoft.CodeAnalysis.ExternalAccess.Copilot.CopilotChecksumWrapper.Create(System.Collections.Immutable.ImmutableArray<string!> values) -> Microsoft.CodeAnalysis.ExternalAccess.Copilot.CopilotChecksumWrapper!
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;

namespace Microsoft.CodeAnalysis.ExternalAccess.Copilot.SemanticSearch;

internal interface ISemanticSearchCopilotServiceImpl
{
ValueTask<SemanticSearchCopilotGeneratedQueryImpl> TryGetQueryAsync(string text, SemanticSearchCopilotContextImpl context, CancellationToken cancellationToken);
}

internal sealed class SemanticSearchCopilotContextImpl
{
public required string ModelName { get; init; }

/// <summary>
/// List of package names and versions that to include in the prompt.
/// </summary>
public required IEnumerable<(string name, Version version)> AvailablePackages { get; init; }
}

internal readonly struct SemanticSearchCopilotGeneratedQueryImpl
{
/// <summary>
/// True if <see cref="Text"/> is an error message.
/// </summary>
public required bool IsError { get; init; }

/// <summary>
/// The generated code or an error message.
/// </summary>
public required string Text { get; init; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System.ComponentModel.Composition;
using Microsoft.CodeAnalysis.Editor;
using Microsoft.VisualStudio.Utilities;

namespace Microsoft.VisualStudio.LanguageServices.CSharp;

internal static class CSharpSemanticSearchContentType
{
public const string Name = "SemanticSearch-CSharp";

[Export]
[Name(Name)]
[BaseDefinition(ContentTypeNames.CSharpContentType)]
public static readonly ContentTypeDefinition Definition = null!;
}
Loading

0 comments on commit a0da860

Please sign in to comment.