@@ -24,11 +24,13 @@ import {
2424 CONDITIONS_KEY_NAME ,
2525 CLIENT_FILTERS_KEY_NAME
2626} from "./featureManagement/constants.js" ;
27- import { FM_PACKAGE_NAME } from "./requestTracing/constants.js" ;
27+ import { FM_PACKAGE_NAME , AI_MIME_PROFILE , AI_CHAT_COMPLETION_MIME_PROFILE } from "./requestTracing/constants.js" ;
28+ import { parseContentType , isJsonContentType , isFeatureFlagContentType , isSecretReferenceContentType } from "./common/contentType.js" ;
2829import { AzureKeyVaultKeyValueAdapter } from "./keyvault/AzureKeyVaultKeyValueAdapter.js" ;
2930import { RefreshTimer } from "./refresh/RefreshTimer.js" ;
3031import { RequestTracingOptions , getConfigurationSettingWithTrace , listConfigurationSettingsWithTrace , requestTracingEnabled } from "./requestTracing/utils.js" ;
3132import { FeatureFlagTracingOptions } from "./requestTracing/FeatureFlagTracingOptions.js" ;
33+ import { AIConfigurationTracingOptions } from "./requestTracing/AIConfigurationTracingOptions.js" ;
3234import { KeyFilter , LabelFilter , SettingSelector } from "./types.js" ;
3335import { ConfigurationClientManager } from "./ConfigurationClientManager.js" ;
3436
@@ -58,6 +60,7 @@ export class AzureAppConfigurationImpl implements AzureAppConfiguration {
5860 #isFailoverRequest: boolean = false ;
5961 #featureFlagTracing: FeatureFlagTracingOptions | undefined ;
6062 #fmVersion: string | undefined ;
63+ #aiConfigurationTracing: AIConfigurationTracingOptions | undefined ;
6164
6265 // Refresh
6366 #refreshInProgress: boolean = false ;
@@ -97,6 +100,7 @@ export class AzureAppConfigurationImpl implements AzureAppConfiguration {
97100 // enable request tracing if not opt-out
98101 this . #requestTracingEnabled = requestTracingEnabled ( ) ;
99102 if ( this . #requestTracingEnabled) {
103+ this . #aiConfigurationTracing = new AIConfigurationTracingOptions ( ) ;
100104 this . #featureFlagTracing = new FeatureFlagTracingOptions ( ) ;
101105 }
102106
@@ -178,7 +182,8 @@ export class AzureAppConfigurationImpl implements AzureAppConfiguration {
178182 replicaCount : this . #clientManager. getReplicaCount ( ) ,
179183 isFailoverRequest : this . #isFailoverRequest,
180184 featureFlagTracing : this . #featureFlagTracing,
181- fmVersion : this . #fmVersion
185+ fmVersion : this . #fmVersion,
186+ aiConfigurationTracing : this . #aiConfigurationTracing
182187 } ;
183188 }
184189
@@ -416,9 +421,14 @@ export class AzureAppConfigurationImpl implements AzureAppConfiguration {
416421 await this . #updateWatchedKeyValuesEtag( loadedSettings ) ;
417422 }
418423
424+ if ( this . #requestTracingEnabled && this . #aiConfigurationTracing !== undefined ) {
425+ // Reset old AI configuration tracing in order to track the information present in the current response from server.
426+ this . #aiConfigurationTracing. reset ( ) ;
427+ }
428+
419429 // process key-values, watched settings have higher priority
420430 for ( const setting of loadedSettings ) {
421- const [ key , value ] = await this . #processKeyValues ( setting ) ;
431+ const [ key , value ] = await this . #processKeyValue ( setting ) ;
422432 keyValues . push ( [ key , value ] ) ;
423433 }
424434
@@ -467,6 +477,11 @@ export class AzureAppConfigurationImpl implements AzureAppConfiguration {
467477 const loadFeatureFlag = true ;
468478 const featureFlagSettings = await this . #loadConfigurationSettings( loadFeatureFlag ) ;
469479
480+ if ( this . #requestTracingEnabled && this . #featureFlagTracing !== undefined ) {
481+ // Reset old feature flag tracing in order to track the information present in the current response from server.
482+ this . #featureFlagTracing. reset ( ) ;
483+ }
484+
470485 // parse feature flags
471486 const featureFlags = await Promise . all (
472487 featureFlagSettings . map ( setting => this . #parseFeatureFlag( setting ) )
@@ -633,12 +648,35 @@ export class AzureAppConfigurationImpl implements AzureAppConfiguration {
633648 throw new Error ( "All clients failed to get configuration settings." ) ;
634649 }
635650
636- async #processKeyValues( setting : ConfigurationSetting < string > ) : Promise < [ string , unknown ] > {
651+ async #processKeyValue( setting : ConfigurationSetting < string > ) : Promise < [ string , unknown ] > {
652+ this . #setAIConfigurationTracing( setting ) ;
653+
637654 const [ key , value ] = await this . #processAdapters( setting ) ;
638655 const trimmedKey = this . #keyWithPrefixesTrimmed( key ) ;
639656 return [ trimmedKey , value ] ;
640657 }
641658
659+ #setAIConfigurationTracing( setting : ConfigurationSetting < string > ) : void {
660+ if ( this . #requestTracingEnabled && this . #aiConfigurationTracing !== undefined ) {
661+ const contentType = parseContentType ( setting . contentType ) ;
662+ // content type: "application/json; profile=\"https://azconfig.io/mime-profiles/ai\"""
663+ if ( isJsonContentType ( contentType ) &&
664+ ! isFeatureFlagContentType ( contentType ) &&
665+ ! isSecretReferenceContentType ( contentType ) ) {
666+ const profile = contentType ?. parameters [ "profile" ] ;
667+ if ( profile === undefined ) {
668+ return ;
669+ }
670+ if ( profile . includes ( AI_MIME_PROFILE ) ) {
671+ this . #aiConfigurationTracing. usesAIConfiguration = true ;
672+ }
673+ if ( profile . includes ( AI_CHAT_COMPLETION_MIME_PROFILE ) ) {
674+ this . #aiConfigurationTracing. usesAIChatCompletionConfiguration = true ;
675+ }
676+ }
677+ }
678+ }
679+
642680 async #processAdapters( setting : ConfigurationSetting < string > ) : Promise < [ string , unknown ] > {
643681 for ( const adapter of this . #adapters) {
644682 if ( adapter . canProcess ( setting ) ) {
@@ -675,6 +713,20 @@ export class AzureAppConfigurationImpl implements AzureAppConfiguration {
675713 } ;
676714 }
677715
716+ this . #setFeatureFlagTracing( featureFlag ) ;
717+
718+ return featureFlag ;
719+ }
720+
721+ #createFeatureFlagReference( setting : ConfigurationSetting < string > ) : string {
722+ let featureFlagReference = `${ this . #clientManager. endpoint . origin } /kv/${ setting . key } ` ;
723+ if ( setting . label && setting . label . trim ( ) . length !== 0 ) {
724+ featureFlagReference += `?label=${ setting . label } ` ;
725+ }
726+ return featureFlagReference ;
727+ }
728+
729+ #setFeatureFlagTracing( featureFlag : any ) : void {
678730 if ( this . #requestTracingEnabled && this . #featureFlagTracing !== undefined ) {
679731 if ( featureFlag [ CONDITIONS_KEY_NAME ] &&
680732 featureFlag [ CONDITIONS_KEY_NAME ] [ CLIENT_FILTERS_KEY_NAME ] &&
@@ -693,16 +745,6 @@ export class AzureAppConfigurationImpl implements AzureAppConfiguration {
693745 this . #featureFlagTracing. usesSeed = true ;
694746 }
695747 }
696-
697- return featureFlag ;
698- }
699-
700- #createFeatureFlagReference( setting : ConfigurationSetting < string > ) : string {
701- let featureFlagReference = `${ this . #clientManager. endpoint . origin } /kv/${ setting . key } ` ;
702- if ( setting . label && setting . label . trim ( ) . length !== 0 ) {
703- featureFlagReference += `?label=${ setting . label } ` ;
704- }
705- return featureFlagReference ;
706748 }
707749}
708750
0 commit comments