1- import { ICompletionProviderManager } from '@jupyterlab/completer' ;
21import { BaseLanguageModel } from '@langchain/core/language_models/base' ;
32import { BaseChatModel } from '@langchain/core/language_models/chat_models' ;
43import { ISignal , Signal } from '@lumino/signaling' ;
54import { ReadonlyPartialJSONObject } from '@lumino/coreutils' ;
5+ import { JSONSchema7 } from 'json-schema' ;
6+ import { ISecretsManager } from 'jupyter-secrets-manager' ;
67
78import { IBaseCompleter } from './base-completer' ;
8- import { IAIProvider , IAIProviderRegistry } from './tokens' ;
9- import { JSONSchema7 } from 'json-schema' ;
9+ import {
10+ getSecretId ,
11+ SECRETS_NAMESPACE ,
12+ SECRETS_REPLACEMENT
13+ } from './settings' ;
14+ import {
15+ IAIProvider ,
16+ IAIProviderRegistry ,
17+ IDict ,
18+ ISetProviderOptions
19+ } from './tokens' ;
1020
1121export const chatSystemPrompt = (
1222 options : AIProviderRegistry . IPromptOptions
@@ -39,6 +49,13 @@ Do not include the prompt in the output, only the string that should be appended
3949` ;
4050
4151export class AIProviderRegistry implements IAIProviderRegistry {
52+ /**
53+ * The constructor of the provider registry.
54+ */
55+ constructor ( options : AIProviderRegistry . IOptions ) {
56+ this . _secretsManager = options . secretsManager || null ;
57+ }
58+
4259 /**
4360 * Get the list of provider names.
4461 */
@@ -56,6 +73,11 @@ export class AIProviderRegistry implements IAIProviderRegistry {
5673 ) ;
5774 }
5875 this . _providers . set ( provider . name , provider ) ;
76+
77+ // Set the provider if the loading has been deferred.
78+ if ( provider . name === this . _deferredProvider ?. name ) {
79+ this . setProvider ( this . _deferredProvider ) ;
80+ }
5981 }
6082
6183 /**
@@ -131,15 +153,36 @@ export class AIProviderRegistry implements IAIProviderRegistry {
131153 * Set the providers (chat model and completer).
132154 * Creates the providers if the name has changed, otherwise only updates their config.
133155 *
134- * @param name - the name of the provider to use.
135- * @param settings - the settings for the models.
156+ * @param options - An object with the name and the settings of the provider to use.
136157 */
137- setProvider ( name : string , settings : ReadonlyPartialJSONObject ) : void {
158+ async setProvider ( options : ISetProviderOptions ) : Promise < void > {
159+ const { name, settings } = options ;
138160 this . _currentProvider = this . _providers . get ( name ) ?? null ;
161+ if ( this . _currentProvider === null ) {
162+ // The current provider may not be loaded when the settings are first loaded.
163+ // Let's defer the provider loading.
164+ this . _deferredProvider = options ;
165+ } else {
166+ this . _deferredProvider = null ;
167+ }
168+
169+ // Build a new settings object containing the secrets.
170+ const fullSettings : IDict = { } ;
171+ for ( const key of Object . keys ( settings ) ) {
172+ if ( settings [ key ] === SECRETS_REPLACEMENT ) {
173+ const id = getSecretId ( name , key ) ;
174+ const secrets = await this . _secretsManager ?. get ( SECRETS_NAMESPACE , id ) ;
175+ fullSettings [ key ] = secrets ?. value || settings [ key ] ;
176+ continue ;
177+ }
178+ fullSettings [ key ] = settings [ key ] ;
179+ }
139180
140181 if ( this . _currentProvider ?. completer !== undefined ) {
141182 try {
142- this . _completer = new this . _currentProvider . completer ( { ...settings } ) ;
183+ this . _completer = new this . _currentProvider . completer ( {
184+ ...fullSettings
185+ } ) ;
143186 this . _completerError = '' ;
144187 } catch ( e : any ) {
145188 this . _completerError = e . message ;
@@ -150,7 +193,9 @@ export class AIProviderRegistry implements IAIProviderRegistry {
150193
151194 if ( this . _currentProvider ?. chatModel !== undefined ) {
152195 try {
153- this . _chatModel = new this . _currentProvider . chatModel ( { ...settings } ) ;
196+ this . _chatModel = new this . _currentProvider . chatModel ( {
197+ ...fullSettings
198+ } ) ;
154199 this . _chatError = '' ;
155200 } catch ( e : any ) {
156201 this . _chatError = e . message ;
@@ -170,6 +215,7 @@ export class AIProviderRegistry implements IAIProviderRegistry {
170215 return this . _providerChanged ;
171216 }
172217
218+ private _secretsManager : ISecretsManager | null ;
173219 private _currentProvider : IAIProvider | null = null ;
174220 private _completer : IBaseCompleter | null = null ;
175221 private _chatModel : BaseChatModel | null = null ;
@@ -178,6 +224,7 @@ export class AIProviderRegistry implements IAIProviderRegistry {
178224 private _chatError : string = '' ;
179225 private _completerError : string = '' ;
180226 private _providers = new Map < string , IAIProvider > ( ) ;
227+ private _deferredProvider : ISetProviderOptions | null = null ;
181228}
182229
183230export namespace AIProviderRegistry {
@@ -186,13 +233,9 @@ export namespace AIProviderRegistry {
186233 */
187234 export interface IOptions {
188235 /**
189- * The completion provider manager in which register the LLM completer.
190- */
191- completionProviderManager : ICompletionProviderManager ;
192- /**
193- * The application commands registry.
236+ * The secrets manager used in the application.
194237 */
195- requestCompletion : ( ) => void ;
238+ secretsManager ?: ISecretsManager ;
196239 }
197240
198241 /**
0 commit comments