3939class OpenAiAPIService {
4040 private IClient $ client ;
4141 private ?array $ modelsMemoryCache = null ;
42- private ?bool $ areCredsValid = null ;
4342
4443 public function __construct (
4544 private LoggerInterface $ logger ,
@@ -111,68 +110,77 @@ private function isModelListValid($models): bool {
111110
112111 /**
113112 * @param ?string $userId
113+ * @param bool $refresh
114114 * @return array|string[]
115115 * @throws Exception
116116 */
117- public function getModels (?string $ userId ): array {
118- // caching against 'getModelEnumValues' calls from all the providers
119- if ($ this ->areCredsValid === false ) {
120- $ this ->logger ->info ('Cannot get OpenAI models without an API key ' );
121- return [];
122- } elseif ($ this ->areCredsValid === null ) {
123- if ($ this ->isUsingOpenAi () && $ this ->openAiSettingsService ->getUserApiKey ($ userId , true ) === '' ) {
124- $ this ->areCredsValid = false ;
125- $ this ->logger ->info ('Cannot get OpenAI models without an API key ' );
126- return [];
117+ public function getModels (?string $ userId , bool $ refresh = false ): array {
118+ $ cache = $ this ->cacheFactory ->createDistributed (Application::APP_ID );
119+ if (!$ refresh ) {
120+ if ($ this ->modelsMemoryCache !== null ) {
121+ $ this ->logger ->debug ('Getting OpenAI models from the memory cache ' );
122+ return $ this ->modelsMemoryCache ;
127123 }
128- $ this ->areCredsValid = true ;
129- }
130124
131- if ($ this ->modelsMemoryCache !== null ) {
132- $ this ->logger ->debug ('Getting OpenAI models from the memory cache ' );
133- return $ this ->modelsMemoryCache ;
134- }
125+ $ userCacheKey = Application::MODELS_CACHE_KEY . '_ ' . ($ userId ?? '' );
126+ $ adminCacheKey = Application::MODELS_CACHE_KEY . '-main ' ;
135127
136- $ userCacheKey = Application::MODELS_CACHE_KEY . '_ ' . ($ userId ?? '' );
137- $ adminCacheKey = Application::MODELS_CACHE_KEY . '-main ' ;
138- $ cache = $ this ->cacheFactory ->createDistributed (Application::APP_ID );
128+ // try to get models from the user cache first
129+ if ($ userId !== null ) {
130+ $ userCachedModels = $ cache ->get ($ userCacheKey );
131+ if ($ userCachedModels ) {
132+ $ this ->logger ->debug ('Getting OpenAI models from user cache for user ' . $ userId );
133+ return $ userCachedModels ;
134+ }
135+ }
139136
140- // try to get models from the user cache first
141- if ($ userId !== null ) {
142- $ userCachedModels = $ cache ->get ($ userCacheKey );
143- if ($ userCachedModels ) {
144- $ this ->logger ->debug ('Getting OpenAI models from user cache for user ' . $ userId );
145- return $ userCachedModels ;
137+ // if the user has an API key or uses basic auth, skip the admin cache
138+ if (!(
139+ $ this ->openAiSettingsService ->getUserApiKey ($ userId , false ) !== ''
140+ || (
141+ $ this ->openAiSettingsService ->getUseBasicAuth ()
142+ && $ this ->openAiSettingsService ->getUserBasicUser ($ userId ) !== ''
143+ && $ this ->openAiSettingsService ->getUserBasicPassword ($ userId ) !== ''
144+ )
145+ )) {
146+ // if no user cache or userId is null, try to get from the admin cache
147+ if ($ adminCachedModels = $ cache ->get ($ adminCacheKey )) {
148+ $ this ->logger ->debug ('Getting OpenAI models from the main distributed cache ' );
149+ return $ adminCachedModels ;
150+ }
146151 }
147- }
148152
149- // if the user has an API key or uses basic auth, skip the admin cache
150- if (!(
151- $ this ->openAiSettingsService ->getUserApiKey ($ userId , false ) !== ''
152- || (
153- $ this ->openAiSettingsService ->getUseBasicAuth ()
154- && $ this ->openAiSettingsService ->getUserBasicUser ($ userId ) !== ''
155- && $ this ->openAiSettingsService ->getUserBasicPassword ($ userId ) !== ''
156- )
157- )) {
158- // if no user cache or userId is null, try to get from the admin cache
159- if ($ adminCachedModels = $ cache ->get ($ adminCacheKey )) {
160- $ this ->logger ->debug ('Getting OpenAI models from the main distributed cache ' );
161- return $ adminCachedModels ;
153+ // if we don't need to refresh to model list and it's not been found in the cache, it is obtained from the DB
154+ $ modelsObjectString = $ this ->appConfig ->getValueString (Application::APP_ID , 'models ' , '{"data":[],"object":"list"} ' );
155+ $ fallbackModels = [
156+ 'data ' => [],
157+ 'object ' => 'list ' ,
158+ ];
159+ try {
160+ $ newCache = json_decode ($ modelsObjectString , true ) ?? $ fallbackModels ;
161+ } catch (Throwable $ e ) {
162+ $ newCache = $ fallbackModels ;
162163 }
164+ $ cache ->set ($ userId !== null ? $ userCacheKey : $ adminCacheKey , $ newCache , Application::MODELS_CACHE_TTL );
165+ $ this ->modelsMemoryCache = $ newCache ;
166+ return $ newCache ;
163167 }
164168
169+ // we know we are refreshing so we clear the caches and make the network request
170+ $ adminCacheKey = Application::MODELS_CACHE_KEY . '-main ' ;
171+ $ cache ->remove ($ adminCacheKey );
172+ $ userCacheKey = Application::MODELS_CACHE_KEY . '_ ' . ($ userId ?? '' );
173+ $ cache ->remove ($ userCacheKey );
174+
165175 try {
166176 $ this ->logger ->debug ('Actually getting OpenAI models with a network request ' );
167177 $ modelsResponse = $ this ->request ($ userId , 'models ' );
168178 } catch (Exception $ e ) {
169179 $ this ->logger ->warning ('Error retrieving models (exc): ' . $ e ->getMessage ());
170- $ this ->areCredsValid = false ;
171180 throw $ e ;
172181 }
173182 if (isset ($ modelsResponse ['error ' ])) {
174183 $ this ->logger ->warning ('Error retrieving models: ' . json_encode ($ modelsResponse ));
175- $ this ->areCredsValid = false ;
176184 throw new Exception ($ modelsResponse ['error ' ], Http::STATUS_INTERNAL_SERVER_ERROR );
177185 }
178186 if (!isset ($ modelsResponse ['data ' ])) {
@@ -182,13 +190,14 @@ public function getModels(?string $userId): array {
182190
183191 if (!$ this ->isModelListValid ($ modelsResponse ['data ' ])) {
184192 $ this ->logger ->warning ('Invalid models response: ' . json_encode ($ modelsResponse ));
185- $ this ->areCredsValid = false ;
186193 throw new Exception ($ this ->l10n ->t ('Invalid models response received ' ), Http::STATUS_INTERNAL_SERVER_ERROR );
187194 }
188195
189196 $ cache ->set ($ userId !== null ? $ userCacheKey : $ adminCacheKey , $ modelsResponse , Application::MODELS_CACHE_TTL );
190197 $ this ->modelsMemoryCache = $ modelsResponse ;
191- $ this ->areCredsValid = true ;
198+ // we always store the model list after getting it
199+ $ modelsObjectString = json_encode ($ modelsResponse );
200+ $ this ->appConfig ->setValueString (Application::APP_ID , 'models ' , $ modelsObjectString );
192201 return $ modelsResponse ;
193202 }
194203
0 commit comments