|
2 | 2 | * Copyright (c) Microsoft Corporation. All rights reserved.
|
3 | 3 | * Licensed under the MIT License. See License.txt in the project root for license information.
|
4 | 4 | *--------------------------------------------------------------------------------------------*/
|
5 |
| -import { ContextProviderApiV1, ResolveRequest, SupportedContextItem } from '@github/copilot-language-server'; |
| 5 | +import { |
| 6 | + ContextProviderApiV1, |
| 7 | + ResolveRequest, |
| 8 | + SupportedContextItem, |
| 9 | + type ContextProvider, |
| 10 | +} from '@github/copilot-language-server'; |
6 | 11 | import * as vscode from 'vscode';
|
7 | 12 | import * as lsp from 'vscode-languageserver-protocol';
|
8 | 13 | import { RoslynLanguageServer } from '../server/roslynLanguageServer';
|
@@ -73,49 +78,105 @@ export function registerCopilotContextProviders(
|
73 | 78 |
|
74 | 79 | devkit.activate().then(async () => {
|
75 | 80 | try {
|
76 |
| - const copilotApi = vscode.extensions.getExtension<CopilotApi>('github.copilot'); |
77 |
| - if (!copilotApi) { |
| 81 | + const copilotClientApi = await getCopilotClientApi(); |
| 82 | + const copilotChatApi = await getCopilotChatApi(); |
| 83 | + if (!copilotClientApi && !copilotChatApi) { |
78 | 84 | channel.debug(
|
79 |
| - 'Failed to find compatible version of GitHub Copilot extension installed. Skip registeration of Copilot context provider.' |
| 85 | + 'Failed to find compatible version of GitHub Copilot extension installed. Skip registration of Copilot context provider.' |
80 | 86 | );
|
81 | 87 | return;
|
82 | 88 | }
|
83 | 89 |
|
84 |
| - const api = await copilotApi.activate(); |
85 |
| - const contextProviderApi = await api.getContextProviderAPI('v1'); |
| 90 | + const provider: ContextProvider<SupportedContextItem> = { |
| 91 | + id: CSharpExtensionId, // use extension id as provider id for now |
| 92 | + selector: [{ language: 'csharp' }], |
| 93 | + resolver: { |
| 94 | + resolve: async (request, token) => { |
| 95 | + const contextResolveParam = createContextResolveParam(request); |
| 96 | + if (!contextResolveParam) { |
| 97 | + return []; |
| 98 | + } |
| 99 | + const items = await languageServer.sendRequest( |
| 100 | + resolveContextRequest, |
| 101 | + contextResolveParam, |
| 102 | + token |
| 103 | + ); |
| 104 | + channel.trace(`Copilot context provider resolved ${items.length} items`); |
| 105 | + return items; |
| 106 | + }, |
| 107 | + }, |
| 108 | + }; |
| 109 | + |
| 110 | + let installCount = 0; |
| 111 | + if (copilotClientApi) { |
| 112 | + const disposable = await installContextProvider(copilotClientApi, provider); |
| 113 | + if (disposable) { |
| 114 | + context.subscriptions.push(disposable); |
| 115 | + installCount++; |
| 116 | + } |
| 117 | + } |
| 118 | + if (copilotChatApi) { |
| 119 | + const disposable = await installContextProvider(copilotChatApi, provider); |
| 120 | + if (disposable) { |
| 121 | + context.subscriptions.push(disposable); |
| 122 | + installCount++; |
| 123 | + } |
| 124 | + } |
86 | 125 |
|
87 |
| - if (!contextProviderApi) { |
| 126 | + if (installCount === 0) { |
88 | 127 | channel.debug(
|
89 |
| - 'Incompatible GitHub Copilot extension installed. Skip registeration of C# context providers.' |
| 128 | + 'Incompatible GitHub Copilot extension installed. Skip registration of C# context providers.' |
90 | 129 | );
|
91 | 130 | return;
|
92 | 131 | }
|
93 |
| - |
94 |
| - context.subscriptions.push( |
95 |
| - contextProviderApi.registerContextProvider<SupportedContextItem>({ |
96 |
| - id: CSharpExtensionId, // use extension id as provider id for now |
97 |
| - selector: [{ language: 'csharp' }], |
98 |
| - resolver: { |
99 |
| - resolve: async (request, token) => { |
100 |
| - const contextResolveParam = createContextResolveParam(request); |
101 |
| - if (!contextResolveParam) { |
102 |
| - return []; |
103 |
| - } |
104 |
| - const items = await languageServer.sendRequest( |
105 |
| - resolveContextRequest, |
106 |
| - contextResolveParam, |
107 |
| - token |
108 |
| - ); |
109 |
| - channel.trace(`Copilot context provider resolved ${items.length} items`); |
110 |
| - return items; |
111 |
| - }, |
112 |
| - }, |
113 |
| - }) |
114 |
| - ); |
115 |
| - |
116 | 132 | channel.debug('Registration of C# context provider for GitHub Copilot extension succeeded.');
|
117 | 133 | } catch (error) {
|
118 | 134 | channel.error('Failed to register Copilot context providers', error);
|
119 | 135 | }
|
120 | 136 | });
|
121 | 137 | }
|
| 138 | + |
| 139 | +async function getCopilotClientApi(): Promise<CopilotApi | undefined> { |
| 140 | + const extension = vscode.extensions.getExtension<CopilotApi>('github.copilot'); |
| 141 | + if (!extension) { |
| 142 | + return undefined; |
| 143 | + } |
| 144 | + try { |
| 145 | + return await extension.activate(); |
| 146 | + } catch { |
| 147 | + return undefined; |
| 148 | + } |
| 149 | +} |
| 150 | + |
| 151 | +async function getCopilotChatApi(): Promise<CopilotApi | undefined> { |
| 152 | + type CopilotChatApi = { getAPI?(version: number): CopilotApi | undefined }; |
| 153 | + const extension = vscode.extensions.getExtension<CopilotChatApi>('github.copilot-chat'); |
| 154 | + if (!extension) { |
| 155 | + return undefined; |
| 156 | + } |
| 157 | + |
| 158 | + let exports: CopilotChatApi | undefined; |
| 159 | + try { |
| 160 | + exports = await extension.activate(); |
| 161 | + } catch { |
| 162 | + return undefined; |
| 163 | + } |
| 164 | + if (!exports || typeof exports.getAPI !== 'function') { |
| 165 | + return undefined; |
| 166 | + } |
| 167 | + return exports.getAPI(1); |
| 168 | +} |
| 169 | + |
| 170 | +async function installContextProvider( |
| 171 | + copilotAPI: CopilotApi, |
| 172 | + contextProvider: ContextProvider<SupportedContextItem> |
| 173 | +): Promise<vscode.Disposable | undefined> { |
| 174 | + const hasGetContextProviderAPI = typeof copilotAPI.getContextProviderAPI === 'function'; |
| 175 | + if (hasGetContextProviderAPI) { |
| 176 | + const contextAPI = await copilotAPI.getContextProviderAPI('v1'); |
| 177 | + if (contextAPI) { |
| 178 | + return contextAPI.registerContextProvider(contextProvider); |
| 179 | + } |
| 180 | + } |
| 181 | + return undefined; |
| 182 | +} |
0 commit comments