1
1
import type { CancellationToken , Disposable , Event , MessageItem , ProgressOptions } from 'vscode' ;
2
2
import { env , EventEmitter , ThemeIcon , window } from 'vscode' ;
3
3
import type { AIPrimaryProviders , AIProviderAndModel , AIProviders , SupportedAIModels } from '../../constants.ai' ;
4
- import { primaryAIProviders } from '../../constants.ai' ;
4
+ import { aiProviderDataDisclaimer , primaryAIProviders } from '../../constants.ai' ;
5
5
import type { AIGenerateDraftEventData , Source , TelemetryEvents } from '../../constants.telemetry' ;
6
6
import type { Container } from '../../container' ;
7
7
import { CancellationError } from '../../errors' ;
@@ -11,7 +11,7 @@ import type { GitRevisionReference } from '../../git/models/reference';
11
11
import type { Repository } from '../../git/models/repository' ;
12
12
import { uncommitted , uncommittedStaged } from '../../git/models/revision' ;
13
13
import { assertsCommitHasFullDetails } from '../../git/utils/commit.utils' ;
14
- import { showAIModelPicker , showAIProviderPicker } from '../../quickpicks/aiPicker ' ;
14
+ import { showAIModelPicker , showAIProviderPicker } from '../../quickpicks/aiModelPicker ' ;
15
15
import { configuration } from '../../system/-webview/configuration' ;
16
16
import type { Storage } from '../../system/-webview/storage' ;
17
17
import { supportedInVSCodeVersion } from '../../system/-webview/vscode' ;
@@ -127,6 +127,14 @@ export class AIProviderService implements Disposable {
127
127
return this . _provider ?. id ;
128
128
}
129
129
130
+ get supportedProviders ( ) : readonly AIProviders [ ] {
131
+ return [ ..._supportedProviderTypes . keys ( ) ] ;
132
+ }
133
+
134
+ get currentModelName ( ) : string | undefined {
135
+ return this . _model ?. name ;
136
+ }
137
+
130
138
private getConfiguredModel ( ) : AIModelDescriptor | undefined {
131
139
const qualifiedModelId = configuration . get ( 'ai.model' ) ?? undefined ;
132
140
if ( qualifiedModelId == null ) return undefined ;
@@ -240,6 +248,7 @@ export class AIProviderService implements Disposable {
240
248
source ,
241
249
) ;
242
250
251
+ await showAIProviderToS ( this . container . storage ) ;
243
252
return model ;
244
253
}
245
254
@@ -553,12 +562,7 @@ export class AIProviderService implements Disposable {
553
562
progress ?: ProgressOptions ;
554
563
} ,
555
564
) : Promise < AIRequestResult | undefined > {
556
- const { confirmed, model } = await getModelAndConfirmAIProviderToS (
557
- 'diff' ,
558
- source ,
559
- this ,
560
- this . container . storage ,
561
- ) ;
565
+ const { confirmed, model } = await getModelAndConfirmAIProviderToS ( source , this , this . container . storage ) ;
562
566
if ( model == null ) {
563
567
options ?. generating ?. cancel ( ) ;
564
568
return undefined ;
@@ -716,8 +720,30 @@ export class AIProviderService implements Disposable {
716
720
}
717
721
}
718
722
723
+ async function showAIProviderToS ( storage : Storage ) : Promise < void > {
724
+ const confirmed = storage . get ( `confirm:ai:tos` , false ) || storage . getWorkspace ( `confirm:ai:tos` , false ) ;
725
+ if ( confirmed ) return ;
726
+
727
+ const acceptWorkspace : MessageItem = { title : 'Always for this Workspace' } ;
728
+ const acceptAlways : MessageItem = { title : 'Always' } ;
729
+
730
+ const result = await window . showInformationMessage (
731
+ aiProviderDataDisclaimer ,
732
+ { modal : true } ,
733
+ acceptWorkspace ,
734
+ acceptAlways ,
735
+ ) ;
736
+
737
+ if ( result === acceptWorkspace || result == null ) {
738
+ void storage . storeWorkspace ( `confirm:ai:tos` , true ) . catch ( ) ;
739
+ }
740
+
741
+ if ( result === acceptAlways ) {
742
+ void storage . store ( `confirm:ai:tos` , true ) . catch ( ) ;
743
+ }
744
+ }
745
+
719
746
async function getModelAndConfirmAIProviderToS (
720
- confirmationType : 'data' | 'diff' ,
721
747
source : Source ,
722
748
service : AIProviderService ,
723
749
storage : Storage ,
@@ -726,9 +752,7 @@ async function getModelAndConfirmAIProviderToS(
726
752
while ( true ) {
727
753
if ( model == null ) return { confirmed : false , model : model } ;
728
754
729
- const confirmed =
730
- storage . get ( `confirm:ai:tos:${ model . provider . id } ` , false ) ||
731
- storage . getWorkspace ( `confirm:ai:tos:${ model . provider . id } ` , false ) ;
755
+ const confirmed = storage . get ( `confirm:ai:tos` , false ) || storage . getWorkspace ( `confirm:ai:tos` , false ) ;
732
756
if ( confirmed ) return { confirmed : true , model : model } ;
733
757
734
758
const accept : MessageItem = { title : 'Continue' } ;
@@ -738,11 +762,7 @@ async function getModelAndConfirmAIProviderToS(
738
762
const decline : MessageItem = { title : 'Cancel' , isCloseAffordance : true } ;
739
763
740
764
const result = await window . showInformationMessage (
741
- `GitLens AI features require sending ${
742
- confirmationType === 'data' ? 'data' : 'a diff of the code changes'
743
- } to ${
744
- model . provider . name
745
- } for analysis. This may contain sensitive information.\n\nDo you want to continue?`,
765
+ `${ aiProviderDataDisclaimer } \n\nDo you want to continue?` ,
746
766
{ modal : true } ,
747
767
accept ,
748
768
switchModel ,
@@ -759,12 +779,12 @@ async function getModelAndConfirmAIProviderToS(
759
779
if ( result === accept ) return { confirmed : true , model : model } ;
760
780
761
781
if ( result === acceptWorkspace ) {
762
- void storage . storeWorkspace ( `confirm:ai:tos: ${ model . provider . id } ` , true ) . catch ( ) ;
782
+ void storage . storeWorkspace ( `confirm:ai:tos` , true ) . catch ( ) ;
763
783
return { confirmed : true , model : model } ;
764
784
}
765
785
766
786
if ( result === acceptAlways ) {
767
- void storage . store ( `confirm:ai:tos: ${ model . provider . id } ` , true ) . catch ( ) ;
787
+ void storage . store ( `confirm:ai:tos` , true ) . catch ( ) ;
768
788
return { confirmed : true , model : model } ;
769
789
}
770
790
0 commit comments