@@ -304,9 +304,9 @@ export class CopilotCompletionContextProvider implements ContextResolver<Support
304304 return Math . round ( performance . now ( ) - startTime ) ;
305305 }
306306
307- public static async Create ( ) {
307+ public static Create ( ) {
308308 const copilotCompletionProvider = new CopilotCompletionContextProvider ( getOutputChannelLogger ( ) ) ;
309- await copilotCompletionProvider . registerCopilotContextProvider ( ) ;
309+ copilotCompletionProvider . registerCopilotContextProvider ( ) ;
310310 return copilotCompletionProvider ;
311311 }
312312
@@ -445,58 +445,94 @@ ${copilotCompletionContext?.areSnippetsMissing ? "(missing code snippets)" : ""}
445445 }
446446 }
447447
448- public async registerCopilotContextProvider ( ) : Promise < void > {
449- const properties : Record < string , string > = { } ;
448+ public registerCopilotContextProvider ( ) : void {
450449 const registerCopilotContextProvider = 'registerCopilotContextProvider' ;
451- try {
452- const copilotApi = await getCopilotClientApi ( ) ;
453- const copilotChatApi = await getCopilotChatApi ( ) ;
454- if ( ! copilotApi && ! copilotChatApi ) { throw new CopilotContextProviderException ( "getCopilotApi() returned null, Copilot is missing or inactive." ) ; }
455- const contextProvider = {
456- id : CopilotCompletionContextProvider . providerId ,
457- selector : CopilotCompletionContextProvider . defaultCppDocumentSelector ,
458- resolver : this
459- } ;
460- type InstallSummary = { hasGetContextProviderAPI : boolean ; hasAPI : boolean } ;
461- const installSummary : { client ?: InstallSummary ; chat ?: InstallSummary } = { } ;
462- if ( copilotApi ) {
463- installSummary . client = await this . installContextProvider ( copilotApi , contextProvider ) ;
450+ const contextProvider = {
451+ id : CopilotCompletionContextProvider . providerId ,
452+ selector : CopilotCompletionContextProvider . defaultCppDocumentSelector ,
453+ resolver : this
454+ } ;
455+ type RegistrationResult = { message : string } | boolean ;
456+ const clientPromise : Promise < RegistrationResult > = getCopilotClientApi ( ) . then ( async ( api ) => {
457+ if ( ! api ) {
458+ throw new CopilotContextProviderException ( "getCopilotApi() returned null, Copilot client is missing or inactive." ) ;
459+ }
460+ const disposable = await this . installContextProvider ( api , contextProvider ) ;
461+ if ( disposable ) {
462+ this . contextProviderDisposables = this . contextProviderDisposables ?? [ ] ;
463+ this . contextProviderDisposables . push ( disposable ) ;
464+ return true ;
465+ } else {
466+ throw new CopilotContextProviderException ( "getContextProviderAPI() is not available in Copilot client." ) ;
464467 }
465- if ( copilotChatApi ) {
466- installSummary . chat = await this . installContextProvider ( copilotChatApi , contextProvider ) ;
468+ } ) . catch ( ( e ) => {
469+ console . debug ( "Failed to register the Copilot Context Provider with Copilot client." ) ;
470+ let message = "Failed to register the Copilot Context Provider with Copilot client" ;
471+ if ( e instanceof CopilotContextProviderException ) {
472+ message += `: ${ e . message } ` ;
467473 }
468- if ( installSummary . client ?. hasAPI || installSummary . chat ?. hasAPI ) {
469- properties [ "cppCodeSnippetsProviderRegistered" ] = "true" ;
474+ return { message } ;
475+ } ) ;
476+ const chatPromise : Promise < RegistrationResult > = getCopilotChatApi ( ) . then ( async ( api ) => {
477+ if ( ! api ) {
478+ throw new CopilotContextProviderException ( "getCopilotChatApi() returned null, Copilot Chat is missing or inactive." ) ;
479+ }
480+ const disposable = await this . installContextProvider ( api , contextProvider ) ;
481+ if ( disposable ) {
482+ this . contextProviderDisposables = this . contextProviderDisposables ?? [ ] ;
483+ this . contextProviderDisposables . push ( disposable ) ;
484+ return true ;
470485 } else {
471- if ( installSummary . client ?. hasGetContextProviderAPI === false &&
472- installSummary . chat ?. hasGetContextProviderAPI === false ) {
473- throw new CopilotContextProviderException ( "getContextProviderAPI() is not available." ) ;
474- } else {
475- throw new CopilotContextProviderException ( "getContextProviderAPI(v1) returned null." ) ;
476- }
486+ throw new CopilotContextProviderException ( "getContextProviderAPI() is not available in Copilot Chat." ) ;
477487 }
478- } catch ( e ) {
479- console . debug ( "Failed to register the Copilot Context Provider." ) ;
480- properties [ "error" ] = "Failed to register the Copilot Context Provider" ;
488+ } ) . catch ( ( e ) => {
489+ console . debug ( "Failed to register the Copilot Context Provider with Copilot Chat ." ) ;
490+ let message = "Failed to register the Copilot Context Provider with Copilot Chat " ;
481491 if ( e instanceof CopilotContextProviderException ) {
482- properties [ "error" ] += `: ${ e . message } ` ;
492+ message += `: ${ e . message } ` ;
483493 }
484- } finally {
494+ return { message } ;
495+ } ) ;
496+ // The client usually doesn't block. So test it first.
497+ clientPromise . then ( ( clientResult ) => {
498+ const properties : Record < string , string > = { } ;
499+ if ( isBoolean ( clientResult ) && clientResult ) {
500+ properties [ "cppCodeSnippetsProviderRegistered" ] = "true" ;
501+ telemetry . logCopilotEvent ( registerCopilotContextProvider , { ...properties } ) ;
502+ return ;
503+ }
504+ return chatPromise . then ( ( chatResult ) => {
505+ const properties : Record < string , string > = { } ;
506+ if ( isBoolean ( chatResult ) && chatResult ) {
507+ properties [ "cppCodeSnippetsProviderRegistered" ] = "true" ;
508+ telemetry . logCopilotEvent ( registerCopilotContextProvider , { ...properties } ) ;
509+ return ;
510+ } else if ( ! isBoolean ( clientResult ) && isString ( clientResult . message ) ) {
511+ properties [ "error" ] = clientResult . message ;
512+ } else if ( ! isBoolean ( chatResult ) && isString ( chatResult . message ) ) {
513+ properties [ "error" ] = chatResult . message ;
514+ } else {
515+ properties [ "error" ] = "Failed to register the Copilot Context Provider for unknown reason." ;
516+ }
517+ telemetry . logCopilotEvent ( registerCopilotContextProvider , { ...properties } ) ;
518+ } ) ;
519+ } ) . catch ( ( e ) => {
520+ const properties : Record < string , string > = { } ;
521+ properties [ "error" ] = `Failed to register the Copilot Context Provider with exception: ${ e } ` ;
485522 telemetry . logCopilotEvent ( registerCopilotContextProvider , { ...properties } ) ;
486- }
523+ } ) ;
487524 }
488525
489- private async installContextProvider ( copilotAPI : CopilotContextProviderAPI , contextProvider : ContextProvider < SupportedContextItem > ) : Promise < { hasGetContextProviderAPI : boolean ; hasAPI : boolean } > {
526+ private async installContextProvider ( copilotAPI : CopilotContextProviderAPI , contextProvider : ContextProvider < SupportedContextItem > ) : Promise < vscode . Disposable | undefined > {
490527 const hasGetContextProviderAPI = typeof copilotAPI . getContextProviderAPI === 'function' ;
491528 if ( hasGetContextProviderAPI ) {
492529 const contextAPI = await copilotAPI . getContextProviderAPI ( "v1" ) ;
493530 if ( contextAPI ) {
494- this . contextProviderDisposables = this . contextProviderDisposables ?? [ ] ;
495- this . contextProviderDisposables . push ( contextAPI . registerContextProvider ( contextProvider ) ) ;
531+ return contextAPI . registerContextProvider ( contextProvider ) ;
496532 }
497- return { hasGetContextProviderAPI , hasAPI : contextAPI !== undefined } ;
533+ return undefined ;
498534 } else {
499- return { hasGetContextProviderAPI : false , hasAPI : false } ;
535+ return undefined ;
500536 }
501537 }
502538}
0 commit comments