1
- import type { IModelPreferences } from '@/types' ;
1
+ import type { IModelConfigForVQA , IModelPreferences } from '@/types' ;
2
2
import {
3
3
ANTHROPIC_API_KEY ,
4
4
AZURE_OPENAI_API_VERSION ,
@@ -114,40 +114,52 @@ interface IModelConfigForCreateLLMClient {
114
114
}
115
115
116
116
const createAssert =
117
- ( modelNameKey : string , modelName : string ) =>
117
+ (
118
+ modelNameKey : string ,
119
+ modelName : string ,
120
+ provider : 'process.env' | 'modelConfig' ,
121
+ ) =>
118
122
( value : string | undefined , key : string , modelVendorFlag ?: string ) => {
119
123
if ( modelVendorFlag ) {
120
124
assert (
121
125
value ,
122
- `The ${ key } must be a non-empty string because of the ${ modelNameKey } is declared as ${ modelName } and ${ modelVendorFlag } has also been specified, but got: ${ value } \nPlease check your config.` ,
126
+ `The ${ key } must be a non-empty string because of the ${ modelNameKey } is declared as ${ modelName } and ${ modelVendorFlag } has also been specified in ${ provider } , but got: ${ value } \nPlease check your config.` ,
123
127
) ;
124
128
} else {
125
129
assert (
126
130
value ,
127
- `The ${ key } must be a non-empty string because of the ${ modelNameKey } is declared as ${ modelName } , but got: ${ value } \nPlease check your config.` ,
131
+ `The ${ key } must be a non-empty string because of the ${ modelNameKey } is declared as ${ modelName } in ${ provider } , but got: ${ value } \nPlease check your config.` ,
128
132
) ;
129
133
}
130
134
} ;
131
135
132
- const getModelConfigFromEnv = (
133
- modelName : string ,
136
+ const getModelConfigFromProvider = ( {
137
+ modelName,
138
+ keys,
139
+ valueAssert,
140
+ getStringConfig,
141
+ getJsonConfig,
142
+ } : {
143
+ modelName : string ;
134
144
keys : Record <
135
145
Exclude < keyof IModelConfigForCreateLLMClient , 'modelName' > ,
136
146
Parameters < typeof getAIConfig > [ 0 ]
137
- > ,
147
+ > ;
138
148
valueAssert : (
139
149
value : string | undefined ,
140
150
key : string ,
141
151
modelVendorFlag ?: string ,
142
- ) => void ,
143
- ) : IModelConfigForCreateLLMClient => {
144
- const socksProxy = getAIConfig ( keys . socksProxy ) ;
145
- const httpProxy = getAIConfig ( keys . httpProxy ) ;
146
-
147
- if ( getAIConfig ( keys . openaiUseAzureDeprecated ) ) {
148
- const openaiBaseURL = getAIConfig ( keys . openaiBaseURL ) ;
149
- const openaiApiKey = getAIConfig ( keys . openaiApiKey ) ;
150
- const openaiExtraConfig = getAIConfigInJson ( keys . openaiExtraConfig ) ;
152
+ ) => void ;
153
+ getStringConfig : ( key ?: string ) => string | undefined ;
154
+ getJsonConfig : ( key ?: string ) => Record < string , unknown > | undefined ;
155
+ } ) : IModelConfigForCreateLLMClient => {
156
+ const socksProxy = getStringConfig ( keys . socksProxy ) ;
157
+ const httpProxy = getStringConfig ( keys . httpProxy ) ;
158
+
159
+ if ( getStringConfig ( keys . openaiUseAzureDeprecated ) ) {
160
+ const openaiBaseURL = getStringConfig ( keys . openaiBaseURL ) ;
161
+ const openaiApiKey = getStringConfig ( keys . openaiApiKey ) ;
162
+ const openaiExtraConfig = getJsonConfig ( keys . openaiExtraConfig ) ;
151
163
152
164
valueAssert (
153
165
openaiBaseURL ,
@@ -165,16 +177,16 @@ const getModelConfigFromEnv = (
165
177
openaiBaseURL,
166
178
openaiExtraConfig,
167
179
} ;
168
- } else if ( getAIConfig ( keys . useAzureOpenai ) ) {
169
- const azureOpenaiScope = getAIConfig ( keys . azureOpenaiScope ) ;
180
+ } else if ( getStringConfig ( keys . useAzureOpenai ) ) {
181
+ const azureOpenaiScope = getStringConfig ( keys . azureOpenaiScope ) ;
170
182
171
- const azureOpenaiApiKey = getAIConfig ( keys . azureOpenaiApiKey ) ;
172
- const azureOpenaiEndpoint = getAIConfig ( keys . azureOpenaiEndpoint ) ;
173
- const azureOpenaiDeployment = getAIConfig ( keys . azureOpenaiDeployment ) ;
174
- const azureOpenaiApiVersion = getAIConfig ( keys . azureOpenaiApiVersion ) ;
183
+ const azureOpenaiApiKey = getStringConfig ( keys . azureOpenaiApiKey ) ;
184
+ const azureOpenaiEndpoint = getStringConfig ( keys . azureOpenaiEndpoint ) ;
185
+ const azureOpenaiDeployment = getStringConfig ( keys . azureOpenaiDeployment ) ;
186
+ const azureOpenaiApiVersion = getStringConfig ( keys . azureOpenaiApiVersion ) ;
175
187
176
- const azureExtraConfig = getAIConfigInJson ( keys . azureExtraConfig ) ;
177
- const openaiExtraConfig = getAIConfigInJson ( keys . openaiExtraConfig ) ;
188
+ const azureExtraConfig = getJsonConfig ( keys . azureExtraConfig ) ;
189
+ const openaiExtraConfig = getJsonConfig ( keys . openaiExtraConfig ) ;
178
190
179
191
valueAssert ( azureOpenaiApiKey , keys . azureOpenaiApiKey , keys . useAzureOpenai ) ;
180
192
@@ -191,8 +203,8 @@ const getModelConfigFromEnv = (
191
203
azureExtraConfig,
192
204
openaiExtraConfig,
193
205
} ;
194
- } else if ( getAIConfig ( keys . useAnthropicSdk ) ) {
195
- const anthropicApiKey = getAIConfig ( keys . anthropicApiKey ) ;
206
+ } else if ( getStringConfig ( keys . useAnthropicSdk ) ) {
207
+ const anthropicApiKey = getStringConfig ( keys . anthropicApiKey ) ;
196
208
valueAssert ( anthropicApiKey , keys . anthropicApiKey , keys . useAnthropicSdk ) ;
197
209
198
210
return {
@@ -203,9 +215,9 @@ const getModelConfigFromEnv = (
203
215
anthropicApiKey,
204
216
} ;
205
217
} else {
206
- const openaiBaseURL = getAIConfig ( keys . openaiBaseURL ) ;
207
- const openaiApiKey = getAIConfig ( keys . openaiApiKey ) ;
208
- const openaiExtraConfig = getAIConfigInJson ( keys . openaiExtraConfig ) ;
218
+ const openaiBaseURL = getStringConfig ( keys . openaiBaseURL ) ;
219
+ const openaiApiKey = getStringConfig ( keys . openaiApiKey ) ;
220
+ const openaiExtraConfig = getJsonConfig ( keys . openaiExtraConfig ) ;
209
221
210
222
valueAssert ( openaiBaseURL , keys . openaiBaseURL ) ;
211
223
valueAssert ( openaiApiKey , keys . openaiApiKey ) ;
@@ -253,6 +265,36 @@ const maskConfig = (config: IModelConfigForCreateLLMClient) => {
253
265
) ;
254
266
} ;
255
267
268
+ const vqaModelConfigKeys = {
269
+ /**
270
+ * proxy
271
+ */
272
+ socksProxy : MIDSCENE_VQA_OPENAI_SOCKS_PROXY ,
273
+ httpProxy : MIDSCENE_VQA_OPENAI_HTTP_PROXY ,
274
+ /**
275
+ * OpenAI
276
+ */
277
+ openaiBaseURL : MIDSCENE_VQA_OPENAI_BASE_URL ,
278
+ openaiApiKey : MIDSCENE_VQA_OPENAI_API_KEY ,
279
+ openaiExtraConfig : MIDSCENE_VQA_OPENAI_INIT_CONFIG_JSON ,
280
+ /**
281
+ * Azure
282
+ */
283
+ openaiUseAzureDeprecated : MIDSCENE_VQA_OPENAI_USE_AZURE ,
284
+ useAzureOpenai : MIDSCENE_VQA_USE_AZURE_OPENAI ,
285
+ azureOpenaiScope : MIDSCENE_VQA_AZURE_OPENAI_SCOPE ,
286
+ azureOpenaiApiKey : MIDSCENE_VQA_AZURE_OPENAI_KEY ,
287
+ azureOpenaiEndpoint : MIDSCENE_VQA_AZURE_OPENAI_ENDPOINT ,
288
+ azureOpenaiApiVersion : MIDSCENE_VQA_AZURE_OPENAI_API_VERSION ,
289
+ azureOpenaiDeployment : MIDSCENE_VQA_AZURE_OPENAI_DEPLOYMENT ,
290
+ azureExtraConfig : MIDSCENE_VQA_AZURE_OPENAI_INIT_CONFIG_JSON ,
291
+ /**
292
+ * Anthropic
293
+ */
294
+ useAnthropicSdk : MIDSCENE_VQA_USE_ANTHROPIC_SDK ,
295
+ anthropicApiKey : MIDSCENE_VQA_ANTHROPIC_API_KEY ,
296
+ } as const ;
297
+
256
298
/**
257
299
* get and validate model config for model client
258
300
*/
@@ -267,59 +309,91 @@ export const decideModelConfig = (
267
309
268
310
const isVQAIntent = modelPreferences ?. intent === 'VQA' ;
269
311
312
+ const vqaModelCallback = modelPreferences ?. modelConfigByIntent ?. VQA ;
270
313
const vqaModelName = getAIConfig ( MIDSCENE_VQA_MODEL_NAME ) ;
271
314
272
- if ( isVQAIntent && vqaModelName ) {
273
- debugLog (
274
- `current action is a VQA action and detected ${ MIDSCENE_VQA_MODEL_NAME } ${ vqaModelName } , will only read VQA related model config from process.env` ,
275
- ) ;
276
- const config = getModelConfigFromEnv (
277
- vqaModelName ,
278
- {
279
- /**
280
- * proxy
281
- */
282
- socksProxy : MIDSCENE_VQA_OPENAI_SOCKS_PROXY ,
283
- httpProxy : MIDSCENE_VQA_OPENAI_HTTP_PROXY ,
284
- /**
285
- * OpenAI
286
- */
287
- openaiBaseURL : MIDSCENE_VQA_OPENAI_BASE_URL ,
288
- openaiApiKey : MIDSCENE_VQA_OPENAI_API_KEY ,
289
- openaiExtraConfig : MIDSCENE_VQA_OPENAI_INIT_CONFIG_JSON ,
290
- /**
291
- * Azure
292
- */
293
- openaiUseAzureDeprecated : MIDSCENE_VQA_OPENAI_USE_AZURE ,
294
- useAzureOpenai : MIDSCENE_VQA_USE_AZURE_OPENAI ,
295
- azureOpenaiScope : MIDSCENE_VQA_AZURE_OPENAI_SCOPE ,
296
- azureOpenaiApiKey : MIDSCENE_VQA_AZURE_OPENAI_KEY ,
297
- azureOpenaiEndpoint : MIDSCENE_VQA_AZURE_OPENAI_ENDPOINT ,
298
- azureOpenaiApiVersion : MIDSCENE_VQA_AZURE_OPENAI_API_VERSION ,
299
- azureOpenaiDeployment : MIDSCENE_VQA_AZURE_OPENAI_DEPLOYMENT ,
300
- azureExtraConfig : MIDSCENE_VQA_AZURE_OPENAI_INIT_CONFIG_JSON ,
301
- /**
302
- * Anthropic
303
- */
304
- useAnthropicSdk : MIDSCENE_VQA_USE_ANTHROPIC_SDK ,
305
- anthropicApiKey : MIDSCENE_VQA_ANTHROPIC_API_KEY ,
306
- } ,
307
- createAssert ( MIDSCENE_VQA_MODEL_NAME , vqaModelName ) ,
308
- ) ;
315
+ const vqaModelConfig = vqaModelCallback ?.( ) ;
309
316
310
- debugLog ( 'got model config for VQA usage:' , maskConfig ( config ) ) ;
317
+ if ( isVQAIntent && ( vqaModelConfig || vqaModelName ) ) {
318
+ if ( vqaModelConfig ) {
319
+ debugLog (
320
+ 'current action is a VQA action and detected VQA declared in modelConfig, will only read VQA related model config from modelConfig.VQA' ,
321
+ ) ;
322
+ const modelName = vqaModelConfig [ MIDSCENE_VQA_MODEL_NAME ] ;
323
+ assert (
324
+ modelName ,
325
+ 'The return value of modelConfig.VQA() does not have a valid MIDSCENE_VQA_MODEL_NAME filed.' ,
326
+ ) ;
327
+ const config = getModelConfigFromProvider ( {
328
+ modelName,
329
+ keys : vqaModelConfigKeys ,
330
+ valueAssert : createAssert (
331
+ MIDSCENE_VQA_MODEL_NAME ,
332
+ modelName ,
333
+ 'modelConfig' ,
334
+ ) ,
335
+ getStringConfig : ( key ) =>
336
+ key ? vqaModelConfig [ key as keyof IModelConfigForVQA ] : undefined ,
337
+ getJsonConfig : ( key ) => {
338
+ if ( key ) {
339
+ const content = vqaModelConfig [ key as keyof IModelConfigForVQA ] ;
340
+ if ( content ) {
341
+ try {
342
+ return JSON . parse ( content ) ;
343
+ } catch ( e ) {
344
+ throw new Error (
345
+ `Failed to parse json config: ${ key } . ${ ( e as Error ) . message } ` ,
346
+ {
347
+ cause : e ,
348
+ } ,
349
+ ) ;
350
+ }
351
+ }
352
+ }
353
+ return undefined ;
354
+ } ,
355
+ } ) ;
356
+ debugLog (
357
+ 'got model config for VQA usage from modelConfig.VQA:' ,
358
+ maskConfig ( config ) ,
359
+ ) ;
311
360
312
- return config ;
361
+ return config ;
362
+ } else {
363
+ debugLog (
364
+ `current action is a VQA action and detected ${ MIDSCENE_VQA_MODEL_NAME } ${ vqaModelName } in process.env, will only read VQA related model config from process.env` ,
365
+ ) ;
366
+ const config = getModelConfigFromProvider ( {
367
+ modelName : vqaModelName ! ,
368
+ keys : vqaModelConfigKeys ,
369
+ valueAssert : createAssert (
370
+ MIDSCENE_VQA_MODEL_NAME ,
371
+ vqaModelName ! ,
372
+ 'process.env' ,
373
+ ) ,
374
+ getStringConfig : getAIConfig as ( key ?: string ) => string | undefined ,
375
+ getJsonConfig : getAIConfigInJson as (
376
+ key ?: string ,
377
+ ) => Record < string , unknown > | undefined ,
378
+ } ) ;
379
+
380
+ debugLog (
381
+ 'got model config for VQA usage from process.env:' ,
382
+ maskConfig ( config ) ,
383
+ ) ;
384
+
385
+ return config ;
386
+ }
313
387
} else {
314
388
debugLog ( 'read model config from process.env as normal.' ) ;
315
389
const commonModelName = getAIConfig ( MIDSCENE_MODEL_NAME ) ;
316
390
assert (
317
391
commonModelName ,
318
392
`${ MIDSCENE_MODEL_NAME } is empty, please check your config.` ,
319
393
) ;
320
- const config = getModelConfigFromEnv (
321
- commonModelName ,
322
- {
394
+ const config = getModelConfigFromProvider ( {
395
+ modelName : commonModelName ,
396
+ keys : {
323
397
/**
324
398
* proxy
325
399
*/
@@ -348,8 +422,16 @@ export const decideModelConfig = (
348
422
useAnthropicSdk : MIDSCENE_USE_ANTHROPIC_SDK ,
349
423
anthropicApiKey : ANTHROPIC_API_KEY ,
350
424
} ,
351
- createAssert ( MIDSCENE_MODEL_NAME , commonModelName ) ,
352
- ) ;
425
+ valueAssert : createAssert (
426
+ MIDSCENE_MODEL_NAME ,
427
+ commonModelName ,
428
+ 'process.env' ,
429
+ ) ,
430
+ getStringConfig : getAIConfig as ( key ?: string ) => string | undefined ,
431
+ getJsonConfig : getAIConfigInJson as (
432
+ key ?: string ,
433
+ ) => Record < string , unknown > | undefined ,
434
+ } ) ;
353
435
354
436
debugLog ( 'got model config for common usage:' , maskConfig ( config ) ) ;
355
437
0 commit comments