Skip to content

[17.14] Move Copilot context provider to EA.Copilot and handler to LanguageServer #78322

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

Draft
wants to merge 1 commit into
base: release/dev17.14
Choose a base branch
from

Conversation

genlu
Copy link
Member

@genlu genlu commented Apr 25, 2025

backport #77973

@ghost ghost added Area-IDE untriaged Issues and PRs which have not yet been triaged by a lead labels Apr 25, 2025

namespace Microsoft.CodeAnalysis.ExternalAccess.Copilot.Completion;

internal record CodeSnippetItem : IContextItem
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
internal record CodeSnippetItem : IContextItem
internal selaed record CodeSnippetItem : IContextItem


internal record CodeSnippetItem : IContextItem
{
public CodeSnippetItem(string uri, string value, string[]? additionalUris = null, int importance = Completion.Importance.Default)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

primary constructor?

public string[]? AdditionalUris { get; init; }

[JsonPropertyName("importance")]
public int Importance { get; init; }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can just be [property: attributes on primary constructor parameters.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

consider doc'ing these.


internal interface ICSharpCopilotContextProviderService
{
IAsyncEnumerable<IContextItem> GetContextItemsAsync(Document document, int position, IReadOnlyDictionary<string, object> activeExperiments, CancellationToken cancellationToken);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what's teh object value for activeExperiments?

namespace Microsoft.CodeAnalysis.ExternalAccess.Copilot.Completion;

[JsonDerivedType(typeof(CodeSnippetItem))]
[JsonDerivedType(typeof(TraitItem))]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ni: call these CodeSnippetContextItem and TraitContextItem to make it clearer what they are.

Document document,
int position,
IReadOnlyDictionary<string, object> activeExperiments,
Func<ImmutableArray<IContextItem>, CancellationToken, ValueTask> callback,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why pass an array, instead of just an itemt at a time, if it's a callback?


namespace Microsoft.CodeAnalysis.ExternalAccess.Copilot.Completion;

internal record TraitItem : IContextItem
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
internal record TraitItem : IContextItem
internal sealed record TraitItem : IContextItem


internal record TraitItem : IContextItem
{
public TraitItem(string name, string value, int importance = Completion.Importance.Default)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

primary constructor, with attribute on params.


namespace Microsoft.CodeAnalysis.ExternalAccess.Copilot.Completion;

internal record TraitItem : IContextItem
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what does 'trait' mean here?

Comment on lines +21 to +22
[Shared]
[Export(typeof(ICSharpCopilotContextProviderService))]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
[Shared]
[Export(typeof(ICSharpCopilotContextProviderService))]
[Export(typeof(ICSharpCopilotContextProviderService)), Shared]

nit.

public CSharpContextProviderService([ImportMany] IEnumerable<IContextProvider> providers)
{
Providers = providers.ToImmutableArray();
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

primary constructor.

{
}
},
cancellationToken));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we have a better api for this. ProducerConsumer. You can write this as:

return ProducerConsumer<IContextItem>.RunAsync(
    static (callback, args, cancellationToken) => 
    {
        await RoslynParallel.ForEachAsync(
            [email protected],
            cancellationToken,
            (provider, cancellationToken) => provider.ProviderContextItemsAsync(
                args.document, args.position, args.activeExperiments, callback, cancellationToken).ConfigureAwait(False);
    }
    args: (@this: this, document, position, activeExperiments),
    cancellationToken);

@@ -29,6 +30,10 @@
<ProjectReference Include="..\..\Core\Portable\Microsoft.CodeAnalysis.Features.csproj" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.VisualStudio.Threading" />
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this seems undesirable. this will also make it so we can't use this code in vscode. i dont' see anything that would make this necessary.


namespace Microsoft.CodeAnalysis.LanguageServer.Handler.Copilot;

internal sealed class CodeSnippetContextItem
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

called 'ContextItem', but doesn't implement `IContextItem'?


namespace Microsoft.CodeAnalysis.LanguageServer.Handler.Copilot;

internal sealed class ContextResolveParam
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is a fairly vague name. consider calling CopilotContextResultParam

Comment on lines +13 to +15
[Shared]
[Method(MethodName)]
[ExportCSharpVisualBasicStatelessLspService(typeof(CopilotCompletionResolveContextHandler), WellKnownLspServerKinds.Any)]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
[Shared]
[Method(MethodName)]
[ExportCSharpVisualBasicStatelessLspService(typeof(CopilotCompletionResolveContextHandler), WellKnownLspServerKinds.Any)]
[Method(MethodName)]
[ExportCSharpVisualBasicStatelessLspService(typeof(CopilotCompletionResolveContextHandler), WellKnownLspServerKinds.Any), Shared]


[ImportingConstructor]
[Obsolete("This exported object must be obtained through the MEF export provider.", error: true)]
public CopilotCompletionResolveContextHandler(ICSharpCopilotContextProviderService contextProviderService)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

primary constructor

var builder = ImmutableArray.CreateBuilder<IContextItem>();
var activeExperiments = param.GetUnpackedActiveExperiments();

await foreach (var item in ContextProviderService.GetContextItemsAsync(document, position, activeExperiments, cancellationToken).ConfigureAwait(false))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

since your'e not streaming anything, you can just make GetContextItemsAsync return an immtuable array. in that case, the impl of it gets a lot simpler too.

i would recomend that htis stream though. that way the host can call into this, and we do the best we can. and it cancels us once enough time has passed.


namespace Microsoft.CodeAnalysis.LanguageServer.Handler.Copilot;

internal sealed class TraitContextItem
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

doesn't implement IContextItem?

@CyrusNajmabadi
Copy link
Member

Since this is a backport, i'm ok with it being mechanical. but i do think we should clean up some code here, and potentially rethink how some things are wokring.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area-IDE untriaged Issues and PRs which have not yet been triaged by a lead VSCode
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants