@@ -107,6 +107,8 @@ export interface AIModelChangeEvent {
107107 readonly model : AIModel | undefined ;
108108}
109109
110+ export type AIExplainSource = Source & { type : TelemetryEvents [ 'ai/explain' ] [ 'changeType' ] } ;
111+
110112// Order matters for sorting the picker
111113const supportedAIProviders = new Map < AIProviders , AIProviderDescriptorWithType > ( [
112114 [
@@ -479,14 +481,11 @@ export class AIProviderService implements Disposable {
479481
480482 async explainCommit (
481483 commitOrRevision : GitRevisionReference | GitCommit ,
482- sourceContext : Source & { type : TelemetryEvents [ 'ai/explain' ] [ 'changeType' ] } ,
484+ sourceContext : AIExplainSource ,
483485 options ?: { cancellation ?: CancellationToken ; progress ?: ProgressOptions } ,
484486 ) : Promise < AISummarizeResult | undefined > {
485- const { type, ...source } = sourceContext ;
486-
487- const result = await this . sendRequest (
488- 'explain-changes' ,
489- async ( model , reporting , cancellation , maxInputTokens , retries ) => {
487+ return this . explainChanges (
488+ async cancellation => {
490489 const diff = await this . container . git . diff ( commitOrRevision . repoPath ) . getDiff ?.( commitOrRevision . ref ) ;
491490 if ( ! diff ?. contents ) throw new AINoRequestDataError ( 'No changes found to explain.' ) ;
492491 if ( cancellation . isCancellationRequested ) throw new CancellationError ( ) ;
@@ -500,18 +499,45 @@ export class AIProviderService implements Disposable {
500499 if ( ! commit . hasFullDetails ( ) ) {
501500 await commit . ensureFullDetails ( ) ;
502501 assertsCommitHasFullDetails ( commit ) ;
503-
504502 if ( cancellation . isCancellationRequested ) throw new CancellationError ( ) ;
505503 }
506504
505+ return {
506+ diff : diff . contents ,
507+ message : commit . message ,
508+ } ;
509+ } ,
510+ sourceContext ,
511+ options ,
512+ ) ;
513+ }
514+
515+ async explainChanges (
516+ promptContext :
517+ | PromptTemplateContext < 'explain-changes' >
518+ | ( ( cancellationToken : CancellationToken ) => Promise < PromptTemplateContext < 'explain-changes' > > ) ,
519+ sourceContext : AIExplainSource ,
520+ options ?: { cancellation ?: CancellationToken ; progress ?: ProgressOptions } ,
521+ ) : Promise < AISummarizeResult | undefined > {
522+ const { type, ...source } = sourceContext ;
523+
524+ const result = await this . sendRequest (
525+ 'explain-changes' ,
526+ async ( model , reporting , cancellation , maxInputTokens , retries ) => {
527+ if ( typeof promptContext === 'function' ) {
528+ promptContext = await promptContext ( cancellation ) ;
529+ }
530+
531+ promptContext . instructions = `${
532+ promptContext . instructions ? `${ promptContext . instructions } \n` : ''
533+ } ${ configuration . get ( 'ai.explainChanges.customInstructions' ) } `;
534+
535+ if ( cancellation . isCancellationRequested ) throw new CancellationError ( ) ;
536+
507537 const { prompt } = await this . getPrompt (
508538 'explain-changes' ,
509539 model ,
510- {
511- diff : diff . contents ,
512- message : commit . message ,
513- instructions : configuration . get ( 'ai.explainChanges.customInstructions' ) ,
514- } ,
540+ promptContext ,
515541 maxInputTokens ,
516542 retries ,
517543 reporting ,
0 commit comments