@@ -101,6 +101,7 @@ export interface IChatEntitlementService {
101101 readonly onDidChangeEntitlement : Event < void > ;
102102
103103 readonly entitlement : ChatEntitlement ;
104+ readonly isInternal : boolean ;
104105
105106 readonly onDidChangeQuotaExceeded : Event < void > ;
106107 readonly onDidChangeQuotaRemaining : Event < void > ;
@@ -239,6 +240,10 @@ export class ChatEntitlementService extends Disposable implements IChatEntitleme
239240 return ChatEntitlement . Unresolved ;
240241 }
241242
243+ get isInternal ( ) : boolean {
244+ return this . contextKeyService . getContextKeyValue < boolean > ( ChatContextKeys . Entitlement . internal . key ) === true ;
245+ }
246+
242247 //#endregion
243248
244249 //#region --- Quotas
@@ -384,6 +389,7 @@ interface IEntitlementsResponse extends ILegacyQuotaSnapshotResponse {
384389 readonly can_signup_for_limited : boolean ;
385390 readonly chat_enabled : boolean ;
386391 readonly copilot_plan : string ;
392+ readonly organization_login_list : string [ ] ;
387393 readonly analytics_tracking_id : string ;
388394 readonly limited_user_reset_date ?: string ; // for Copilot Free
389395 readonly quota_reset_date ?: string ; // for all other Copilot SKUs
@@ -396,6 +402,7 @@ interface IEntitlementsResponse extends ILegacyQuotaSnapshotResponse {
396402
397403interface IEntitlements {
398404 readonly entitlement : ChatEntitlement ;
405+ readonly isInternal ?: boolean ;
399406 readonly quotas ?: IQuotas ;
400407}
401408
@@ -644,6 +651,7 @@ export class ChatEntitlementRequests extends Disposable {
644651
645652 const entitlements : IEntitlements = {
646653 entitlement,
654+ isInternal : this . containsInternalOrgs ( entitlementsResponse . organization_login_list ) ,
647655 quotas : this . toQuotas ( entitlementsResponse )
648656 } ;
649657
@@ -718,6 +726,11 @@ export class ChatEntitlementRequests extends Disposable {
718726 return quotas ;
719727 }
720728
729+ private containsInternalOrgs ( organizationLogins : string [ ] ) : boolean {
730+ const internalOrgs = [ 'github' , 'microsoft' ] ;
731+ return organizationLogins . some ( org => internalOrgs . includes ( org ) ) ;
732+ }
733+
721734 private async request ( url : string , type : 'GET' , body : undefined , sessions : AuthenticationSession [ ] , token : CancellationToken ) : Promise < IRequestContext | undefined > ;
722735 private async request ( url : string , type : 'POST' , body : object , sessions : AuthenticationSession [ ] , token : CancellationToken ) : Promise < IRequestContext | undefined > ;
723736 private async request ( url : string , type : 'GET' | 'POST' , body : object | undefined , sessions : AuthenticationSession [ ] , token : CancellationToken ) : Promise < IRequestContext | undefined > {
@@ -759,7 +772,7 @@ export class ChatEntitlementRequests extends Disposable {
759772 private update ( state : IEntitlements ) : void {
760773 this . state = state ;
761774
762- this . context . update ( { entitlement : this . state . entitlement } ) ;
775+ this . context . update ( { entitlement : this . state . entitlement , isInternal : this . state . isInternal } ) ;
763776
764777 if ( state . quotas ) {
765778 this . chatQuotasAccessor . acceptQuotas ( state . quotas ) ;
@@ -906,6 +919,11 @@ export interface IChatEntitlementContextState extends IChatSentiment {
906919 */
907920 entitlement : ChatEntitlement ;
908921
922+ /**
923+ * User is an internal chat user.
924+ */
925+ isInternal : boolean ;
926+
909927 /**
910928 * User is or was a registered Chat user.
911929 */
@@ -925,6 +943,8 @@ export class ChatEntitlementContext extends Disposable {
925943 private readonly businessContextKey : IContextKey < boolean > ;
926944 private readonly enterpriseContextKey : IContextKey < boolean > ;
927945
946+ private readonly internalContextKey : IContextKey < boolean > ;
947+
928948 private readonly hiddenContext : IContextKey < boolean > ;
929949 private readonly laterContext : IContextKey < boolean > ;
930950 private readonly installedContext : IContextKey < boolean > ;
@@ -956,13 +976,14 @@ export class ChatEntitlementContext extends Disposable {
956976 this . proPlusContextKey = ChatContextKeys . Entitlement . proPlus . bindTo ( contextKeyService ) ;
957977 this . businessContextKey = ChatContextKeys . Entitlement . business . bindTo ( contextKeyService ) ;
958978 this . enterpriseContextKey = ChatContextKeys . Entitlement . enterprise . bindTo ( contextKeyService ) ;
979+ this . internalContextKey = ChatContextKeys . Entitlement . internal . bindTo ( contextKeyService ) ;
959980 this . hiddenContext = ChatContextKeys . Setup . hidden . bindTo ( contextKeyService ) ;
960981 this . laterContext = ChatContextKeys . Setup . later . bindTo ( contextKeyService ) ;
961982 this . installedContext = ChatContextKeys . Setup . installed . bindTo ( contextKeyService ) ;
962983 this . disabledContext = ChatContextKeys . Setup . disabled . bindTo ( contextKeyService ) ;
963984 this . untrustedContext = ChatContextKeys . Setup . untrusted . bindTo ( contextKeyService ) ;
964985
965- this . _state = this . storageService . getObject < IChatEntitlementContextState > ( ChatEntitlementContext . CHAT_ENTITLEMENT_CONTEXT_STORAGE_KEY , StorageScope . PROFILE ) ?? { entitlement : ChatEntitlement . Unknown } ;
986+ this . _state = this . storageService . getObject < IChatEntitlementContextState > ( ChatEntitlementContext . CHAT_ENTITLEMENT_CONTEXT_STORAGE_KEY , StorageScope . PROFILE ) ?? { entitlement : ChatEntitlement . Unknown , isInternal : false } ;
966987
967988 this . checkExtensionInstallation ( ) ;
968989 this . updateContextSync ( ) ;
@@ -1004,9 +1025,10 @@ export class ChatEntitlementContext extends Disposable {
10041025 update ( context : { installed : boolean ; disabled : boolean ; untrusted : boolean } ) : Promise < void > ;
10051026 update ( context : { hidden : boolean } ) : Promise < void > ;
10061027 update ( context : { later : boolean } ) : Promise < void > ;
1007- update ( context : { entitlement : ChatEntitlement } ) : Promise < void > ;
1008- update ( context : { installed ?: boolean ; disabled ?: boolean ; untrusted ?: boolean ; hidden ?: boolean ; later ?: boolean ; entitlement ?: ChatEntitlement } ) : Promise < void > {
1028+ update ( context : { entitlement : ChatEntitlement ; isInternal ?: boolean } ) : Promise < void > ;
1029+ update ( context : { installed ?: boolean ; disabled ?: boolean ; untrusted ?: boolean ; hidden ?: boolean ; later ?: boolean ; entitlement ?: ChatEntitlement ; isInternal ?: boolean } ) : Promise < void > {
10091030 this . logService . trace ( `[chat entitlement context] update(): ${ JSON . stringify ( context ) } ` ) ;
1031+ this . state . isInternal = ! ! context . isInternal ;
10101032
10111033 if ( typeof context . installed === 'boolean' && typeof context . disabled === 'boolean' && typeof context . untrusted === 'boolean' ) {
10121034 this . _state . installed = context . installed ;
@@ -1060,6 +1082,7 @@ export class ChatEntitlementContext extends Disposable {
10601082 this . proPlusContextKey . set ( this . _state . entitlement === ChatEntitlement . ProPlus ) ;
10611083 this . businessContextKey . set ( this . _state . entitlement === ChatEntitlement . Business ) ;
10621084 this . enterpriseContextKey . set ( this . _state . entitlement === ChatEntitlement . Enterprise ) ;
1085+ this . internalContextKey . set ( this . _state . isInternal ) ;
10631086 this . hiddenContext . set ( ! ! this . _state . hidden ) ;
10641087 this . laterContext . set ( ! ! this . _state . later ) ;
10651088 this . installedContext . set ( ! ! this . _state . installed ) ;
0 commit comments