-
Notifications
You must be signed in to change notification settings - Fork 4.2k
Implement support for Semantic Search agent and tool #77784
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
3aa8cda
Implement support for Semantic Search agent
tmat 4598baf
Move compilation errors to ExecuteQueryResult
tmat 8a822c0
Separate query execution from Semantic Search window UI
tmat 0b83f6b
Add CopilotSemanticSearchQueryExecutor
tmat 7e52fa7
Feedback & fixes
tmat File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
109 changes: 109 additions & 0 deletions
109
...ures/ExternalAccess/Copilot/Internal/SemanticSearch/CopilotSemanticSearchQueryExecutor.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,109 @@ | ||
| // 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.Immutable; | ||
| using System.Composition; | ||
| using System.Threading; | ||
| using System.Threading.Tasks; | ||
| using Microsoft.CodeAnalysis.Classification; | ||
| using Microsoft.CodeAnalysis.ExternalAccess.Copilot.SemanticSearch; | ||
| using Microsoft.CodeAnalysis.FindUsages; | ||
| using Microsoft.CodeAnalysis.Host; | ||
| using Microsoft.CodeAnalysis.Host.Mef; | ||
| using Microsoft.CodeAnalysis.SemanticSearch; | ||
| using Roslyn.Utilities; | ||
|
|
||
| namespace Microsoft.CodeAnalysis.ExternalAccess.Copilot.Internal.SemanticSearch; | ||
|
|
||
| [Export(typeof(ICopilotSemanticSearchQueryExecutor)), Shared] | ||
| [method: ImportingConstructor] | ||
| [method: Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] | ||
| internal sealed class CopilotSemanticSearchQueryExecutor(IHostWorkspaceProvider workspaceProvider) : ICopilotSemanticSearchQueryExecutor | ||
| { | ||
| private sealed class ResultsObserver(CancellationTokenSource cancellationSource, int resultCountLimit) : ISemanticSearchResultsObserver | ||
| { | ||
| private ImmutableList<string> _results = []; | ||
| public string? RuntimeException { get; private set; } | ||
| public bool LimitReached { get; private set; } | ||
|
|
||
| public ImmutableList<string> Results => _results; | ||
|
|
||
| public ValueTask AddItemsAsync(int itemCount, CancellationToken cancellationToken) | ||
| => ValueTaskFactory.CompletedTask; | ||
|
|
||
| public ValueTask ItemsCompletedAsync(int itemCount, CancellationToken cancellationToken) | ||
| => ValueTaskFactory.CompletedTask; | ||
|
|
||
| public ValueTask OnUserCodeExceptionAsync(UserCodeExceptionInfo exception, CancellationToken cancellationToken) | ||
| { | ||
| RuntimeException ??= $"{exception.TypeName.ToVisibleDisplayString(includeLeftToRightMarker: false)}: {exception.Message}{Environment.NewLine}{exception.StackTrace.ToVisibleDisplayString(includeLeftToRightMarker: false)}"; | ||
| cancellationSource.Cancel(); | ||
| return ValueTaskFactory.CompletedTask; | ||
| } | ||
|
|
||
| public ValueTask OnDefinitionFoundAsync(DefinitionItem definition, CancellationToken cancellationToken) | ||
| { | ||
| if (!ImmutableInterlocked.Update(ref _results, | ||
| list => list.Count == resultCountLimit ? list : list.Add(definition.NameDisplayParts.ToVisibleDisplayString(includeLeftToRightMarker: false)))) | ||
| { | ||
| LimitReached = true; | ||
| cancellationSource.Cancel(); | ||
| } | ||
|
|
||
| return ValueTaskFactory.CompletedTask; | ||
| } | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// We only use symbol display names, classification is not relevant. | ||
| /// </summary> | ||
| private sealed class DefaultClassificationOptionsProvider : OptionsProvider<ClassificationOptions> | ||
| { | ||
| public static readonly DefaultClassificationOptionsProvider Instance = new(); | ||
|
|
||
| public ValueTask<ClassificationOptions> GetOptionsAsync(LanguageServices languageServices, CancellationToken cancellationToken) | ||
| => new(ClassificationOptions.Default); | ||
| } | ||
tmat marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| private readonly Workspace _workspace = workspaceProvider.Workspace; | ||
|
|
||
| public async Task<CopilotSemanticSearchQueryResults> ExecuteAsync(string query, int resultCountLimit, CancellationToken cancellationToken) | ||
| { | ||
| Contract.ThrowIfFalse(resultCountLimit > 0); | ||
|
|
||
| using var cancellationSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken); | ||
| var observer = new ResultsObserver(cancellationSource, resultCountLimit); | ||
|
|
||
| try | ||
| { | ||
| var result = await RemoteSemanticSearchServiceProxy.ExecuteQueryAsync( | ||
| _workspace.CurrentSolution, | ||
| LanguageNames.CSharp, | ||
tmat marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| query, | ||
| SemanticSearchUtilities.ReferenceAssembliesDirectory, | ||
| observer, | ||
| DefaultClassificationOptionsProvider.Instance, | ||
| cancellationSource.Token).ConfigureAwait(false); | ||
|
|
||
| return new CopilotSemanticSearchQueryResults() | ||
| { | ||
| Symbols = observer.Results, | ||
| CompilationErrors = result.compilationErrors.SelectAsArray(e => (e.Id, e.Message)), | ||
| Error = (result.ErrorMessage != null) ? string.Format(result.ErrorMessage, result.ErrorMessageArgs ?? []) : null, | ||
| LimitReached = false, | ||
| }; | ||
| } | ||
| catch (OperationCanceledException) when (cancellationSource.IsCancellationRequested) | ||
| { | ||
| return new CopilotSemanticSearchQueryResults() | ||
| { | ||
| Symbols = observer.Results, | ||
| CompilationErrors = [], | ||
| Error = observer.RuntimeException != null ? $"The query failed with an exception: {observer.RuntimeException}" : null, | ||
tmat marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| LimitReached = observer.LimitReached, | ||
| }; | ||
| } | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
22 changes: 22 additions & 0 deletions
22
src/Features/ExternalAccess/Copilot/SemanticSearch/ICopilotSemanticSearchQueryExecutor.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| // 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.Collections.Generic; | ||
| using System.Threading; | ||
| using System.Threading.Tasks; | ||
|
|
||
| namespace Microsoft.CodeAnalysis.ExternalAccess.Copilot.SemanticSearch; | ||
|
|
||
| internal interface ICopilotSemanticSearchQueryExecutor | ||
| { | ||
| Task<CopilotSemanticSearchQueryResults> ExecuteAsync(string query, int resultCountLimit, CancellationToken cancellationToken); | ||
| } | ||
|
|
||
| internal readonly struct CopilotSemanticSearchQueryResults | ||
| { | ||
| public required IReadOnlyList<string> Symbols { get; init; } | ||
| public required IReadOnlyList<(string id, string message)> CompilationErrors { get; init; } | ||
tmat marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| public string? Error { get; init; } | ||
| public required bool LimitReached { get; init; } | ||
| } | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.