@@ -566,7 +566,11 @@ export class AIProviderService implements Disposable {
566566 commitOrRevision : GitRevisionReference | GitCommit ,
567567 sourceContext : AIExplainSource ,
568568 options ?: { cancellation ?: CancellationToken ; progress ?: ProgressOptions } ,
569- ) : Promise < AISummarizeResult | 'cancelled' | undefined > {
569+ ) : Promise <
570+ | undefined
571+ | 'cancelled'
572+ | { aiPromise : Promise < AISummarizeResult | 'cancelled' | undefined > ; info : { model : AIModel } }
573+ > {
570574 const svc = this . container . git . getRepositoryService ( commitOrRevision . repoPath ) ;
571575 return this . explainChanges (
572576 async cancellation => {
@@ -599,10 +603,14 @@ export class AIProviderService implements Disposable {
599603 | ( ( cancellationToken : CancellationToken ) => Promise < PromptTemplateContext < 'explain-changes' > > ) ,
600604 sourceContext : AIExplainSource ,
601605 options ?: { cancellation ?: CancellationToken ; progress ?: ProgressOptions } ,
602- ) : Promise < AISummarizeResult | 'cancelled' | undefined > {
606+ ) : Promise <
607+ | undefined
608+ | 'cancelled'
609+ | { aiPromise : Promise < AISummarizeResult | 'cancelled' | undefined > ; info : { model : AIModel } }
610+ > {
603611 const { type, ...source } = sourceContext ;
604612
605- const result = await this . sendRequest (
613+ const complexResult = await this . sendRequestAndGetPartialRequestInfo (
606614 'explain-changes' ,
607615 async ( model , reporting , cancellation , maxInputTokens , retries ) => {
608616 if ( typeof promptContext === 'function' ) {
@@ -645,16 +653,27 @@ export class AIProviderService implements Disposable {
645653 } ) ,
646654 options ,
647655 ) ;
648- return result === 'cancelled'
649- ? result
650- : result != null
651- ? {
652- ...result ,
653- type : 'explain-changes' ,
654- feature : `explain-${ type } ` ,
655- parsed : parseSummarizeResult ( result . content ) ,
656- }
657- : undefined ;
656+
657+ if ( complexResult === 'cancelled' ) return complexResult ;
658+ if ( complexResult == null ) return undefined ;
659+
660+ const aiPromise : Promise < AISummarizeResult | 'cancelled' | undefined > = complexResult . aiPromise . then ( result =>
661+ result === 'cancelled'
662+ ? result
663+ : result != null
664+ ? {
665+ ...result ,
666+ type : 'explain-changes' ,
667+ feature : `explain-${ type } ` ,
668+ parsed : parseSummarizeResult ( result . content ) ,
669+ }
670+ : undefined ,
671+ ) ;
672+
673+ return {
674+ aiPromise : aiPromise ,
675+ info : complexResult . info ,
676+ } ;
658677 }
659678
660679 async generateCommitMessage (
@@ -1422,6 +1441,56 @@ export class AIProviderService implements Disposable {
14221441 }
14231442 }
14241443
1444+ private async sendRequestAndGetPartialRequestInfo < T extends AIActionType > (
1445+ action : T ,
1446+ getMessages : (
1447+ model : AIModel ,
1448+ reporting : TelemetryEvents [ 'ai/generate' | 'ai/explain' ] ,
1449+ cancellation : CancellationToken ,
1450+ maxCodeCharacters : number ,
1451+ retries : number ,
1452+ ) => Promise < AIChatMessage [ ] > ,
1453+ getProgressTitle : ( model : AIModel ) => string ,
1454+ source : Source ,
1455+ getTelemetryInfo : ( model : AIModel ) => {
1456+ key : 'ai/generate' | 'ai/explain' ;
1457+ data : TelemetryEvents [ 'ai/generate' | 'ai/explain' ] ;
1458+ } ,
1459+ options ?: {
1460+ cancellation ?: CancellationToken ;
1461+ generating ?: Deferred < AIModel > ;
1462+ modelOptions ?: { outputTokens ?: number ; temperature ?: number } ;
1463+ progress ?: ProgressOptions ;
1464+ } ,
1465+ ) : Promise <
1466+ | undefined
1467+ | 'cancelled'
1468+ | {
1469+ aiPromise : Promise < AIRequestResult | 'cancelled' | undefined > ;
1470+ info : { model : AIModel } ;
1471+ }
1472+ > {
1473+ if ( ! ( await this . ensureFeatureAccess ( action , source ) ) ) {
1474+ return 'cancelled' ;
1475+ }
1476+ const model = await this . getModel ( undefined , source ) ;
1477+ if ( model == null || options ?. cancellation ?. isCancellationRequested ) {
1478+ options ?. generating ?. cancel ( ) ;
1479+ return undefined ;
1480+ }
1481+
1482+ const aiPromise = this . sendRequestWithModel (
1483+ model ,
1484+ action ,
1485+ getMessages ,
1486+ getProgressTitle ,
1487+ source ,
1488+ getTelemetryInfo ,
1489+ options ,
1490+ ) ;
1491+ return { aiPromise : aiPromise , info : { model : model } } ;
1492+ }
1493+
14251494 private async sendRequest < T extends AIActionType > (
14261495 action : T ,
14271496 getMessages : (
@@ -1449,6 +1518,44 @@ export class AIProviderService implements Disposable {
14491518 }
14501519
14511520 const model = await this . getModel ( undefined , source ) ;
1521+ return this . sendRequestWithModel (
1522+ model ,
1523+ action ,
1524+ getMessages ,
1525+ getProgressTitle ,
1526+ source ,
1527+ getTelemetryInfo ,
1528+ options ,
1529+ ) ;
1530+ }
1531+
1532+ private async sendRequestWithModel < T extends AIActionType > (
1533+ model : AIModel | undefined ,
1534+ action : T ,
1535+ getMessages : (
1536+ model : AIModel ,
1537+ reporting : TelemetryEvents [ 'ai/generate' | 'ai/explain' ] ,
1538+ cancellation : CancellationToken ,
1539+ maxCodeCharacters : number ,
1540+ retries : number ,
1541+ ) => Promise < AIChatMessage [ ] > ,
1542+ getProgressTitle : ( model : AIModel ) => string ,
1543+ source : Source ,
1544+ getTelemetryInfo : ( model : AIModel ) => {
1545+ key : 'ai/generate' | 'ai/explain' ;
1546+ data : TelemetryEvents [ 'ai/generate' | 'ai/explain' ] ;
1547+ } ,
1548+ options ?: {
1549+ cancellation ?: CancellationToken ;
1550+ generating ?: Deferred < AIModel > ;
1551+ modelOptions ?: { outputTokens ?: number ; temperature ?: number } ;
1552+ progress ?: ProgressOptions ;
1553+ } ,
1554+ ) : Promise < AIRequestResult | 'cancelled' | undefined > {
1555+ if ( ! ( await this . ensureFeatureAccess ( action , source ) ) ) {
1556+ return 'cancelled' ;
1557+ }
1558+
14521559 if ( options ?. cancellation ?. isCancellationRequested ) {
14531560 options ?. generating ?. cancel ( ) ;
14541561 return 'cancelled' ;
0 commit comments