@@ -565,7 +565,11 @@ export class AIProviderService implements Disposable {
565565 commitOrRevision : GitRevisionReference | GitCommit ,
566566 sourceContext : AIExplainSource ,
567567 options ?: { cancellation ?: CancellationToken ; progress ?: ProgressOptions } ,
568- ) : Promise < AISummarizeResult | 'cancelled' | undefined > {
568+ ) : Promise <
569+ | undefined
570+ | 'cancelled'
571+ | { aiPromise : Promise < AISummarizeResult | 'cancelled' | undefined > ; info : { model : AIModel } }
572+ > {
569573 const svc = this . container . git . getRepositoryService ( commitOrRevision . repoPath ) ;
570574 return this . explainChanges (
571575 async cancellation => {
@@ -598,10 +602,14 @@ export class AIProviderService implements Disposable {
598602 | ( ( cancellationToken : CancellationToken ) => Promise < PromptTemplateContext < 'explain-changes' > > ) ,
599603 sourceContext : AIExplainSource ,
600604 options ?: { cancellation ?: CancellationToken ; progress ?: ProgressOptions } ,
601- ) : Promise < AISummarizeResult | 'cancelled' | undefined > {
605+ ) : Promise <
606+ | undefined
607+ | 'cancelled'
608+ | { aiPromise : Promise < AISummarizeResult | 'cancelled' | undefined > ; info : { model : AIModel } }
609+ > {
602610 const { type, ...source } = sourceContext ;
603611
604- const result = await this . sendRequest (
612+ const complexResult = await this . sendRequestAndGetPartialRequestInfo (
605613 'explain-changes' ,
606614 async ( model , reporting , cancellation , maxInputTokens , retries ) => {
607615 if ( typeof promptContext === 'function' ) {
@@ -644,11 +652,22 @@ export class AIProviderService implements Disposable {
644652 } ) ,
645653 options ,
646654 ) ;
647- return result === 'cancelled'
648- ? result
649- : result != null
650- ? { ...result , type : 'explain-changes' , parsed : parseSummarizeResult ( result . content ) }
651- : undefined ;
655+
656+ if ( complexResult === 'cancelled' ) return complexResult ;
657+ if ( complexResult == null ) return undefined ;
658+
659+ const aiPromise : Promise < AISummarizeResult | 'cancelled' | undefined > = complexResult . aiPromise . then ( result =>
660+ result === 'cancelled'
661+ ? result
662+ : result != null
663+ ? { ...result , type : 'explain-changes' , parsed : parseSummarizeResult ( result . content ) }
664+ : undefined ,
665+ ) ;
666+
667+ return {
668+ aiPromise : aiPromise ,
669+ info : complexResult . info ,
670+ } ;
652671 }
653672
654673 async generateCommitMessage (
@@ -1392,6 +1411,56 @@ export class AIProviderService implements Disposable {
13921411 }
13931412 }
13941413
1414+ private async sendRequestAndGetPartialRequestInfo < T extends AIActionType > (
1415+ action : T ,
1416+ getMessages : (
1417+ model : AIModel ,
1418+ reporting : TelemetryEvents [ 'ai/generate' | 'ai/explain' ] ,
1419+ cancellation : CancellationToken ,
1420+ maxCodeCharacters : number ,
1421+ retries : number ,
1422+ ) => Promise < AIChatMessage [ ] > ,
1423+ getProgressTitle : ( model : AIModel ) => string ,
1424+ source : Source ,
1425+ getTelemetryInfo : ( model : AIModel ) => {
1426+ key : 'ai/generate' | 'ai/explain' ;
1427+ data : TelemetryEvents [ 'ai/generate' | 'ai/explain' ] ;
1428+ } ,
1429+ options ?: {
1430+ cancellation ?: CancellationToken ;
1431+ generating ?: Deferred < AIModel > ;
1432+ modelOptions ?: { outputTokens ?: number ; temperature ?: number } ;
1433+ progress ?: ProgressOptions ;
1434+ } ,
1435+ ) : Promise <
1436+ | undefined
1437+ | 'cancelled'
1438+ | {
1439+ aiPromise : Promise < AIRequestResult | 'cancelled' | undefined > ;
1440+ info : { model : AIModel } ;
1441+ }
1442+ > {
1443+ if ( ! ( await this . ensureFeatureAccess ( action , source ) ) ) {
1444+ return 'cancelled' ;
1445+ }
1446+ const model = await this . getModel ( undefined , source ) ;
1447+ if ( model == null || options ?. cancellation ?. isCancellationRequested ) {
1448+ options ?. generating ?. cancel ( ) ;
1449+ return undefined ;
1450+ }
1451+
1452+ const aiPromise = this . sendRequestWithModel (
1453+ model ,
1454+ action ,
1455+ getMessages ,
1456+ getProgressTitle ,
1457+ source ,
1458+ getTelemetryInfo ,
1459+ options ,
1460+ ) ;
1461+ return { aiPromise : aiPromise , info : { model : model } } ;
1462+ }
1463+
13951464 private async sendRequest < T extends AIActionType > (
13961465 action : T ,
13971466 getMessages : (
@@ -1419,6 +1488,44 @@ export class AIProviderService implements Disposable {
14191488 }
14201489
14211490 const model = await this . getModel ( undefined , source ) ;
1491+ return this . sendRequestWithModel (
1492+ model ,
1493+ action ,
1494+ getMessages ,
1495+ getProgressTitle ,
1496+ source ,
1497+ getTelemetryInfo ,
1498+ options ,
1499+ ) ;
1500+ }
1501+
1502+ private async sendRequestWithModel < T extends AIActionType > (
1503+ model : AIModel | undefined ,
1504+ action : T ,
1505+ getMessages : (
1506+ model : AIModel ,
1507+ reporting : TelemetryEvents [ 'ai/generate' | 'ai/explain' ] ,
1508+ cancellation : CancellationToken ,
1509+ maxCodeCharacters : number ,
1510+ retries : number ,
1511+ ) => Promise < AIChatMessage [ ] > ,
1512+ getProgressTitle : ( model : AIModel ) => string ,
1513+ source : Source ,
1514+ getTelemetryInfo : ( model : AIModel ) => {
1515+ key : 'ai/generate' | 'ai/explain' ;
1516+ data : TelemetryEvents [ 'ai/generate' | 'ai/explain' ] ;
1517+ } ,
1518+ options ?: {
1519+ cancellation ?: CancellationToken ;
1520+ generating ?: Deferred < AIModel > ;
1521+ modelOptions ?: { outputTokens ?: number ; temperature ?: number } ;
1522+ progress ?: ProgressOptions ;
1523+ } ,
1524+ ) : Promise < AIRequestResult | 'cancelled' | undefined > {
1525+ if ( ! ( await this . ensureFeatureAccess ( action , source ) ) ) {
1526+ return 'cancelled' ;
1527+ }
1528+
14221529 if ( options ?. cancellation ?. isCancellationRequested ) {
14231530 options ?. generating ?. cancel ( ) ;
14241531 return 'cancelled' ;
0 commit comments