@rpascene/shared 0.30.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (177) hide show
  1. package/README.md +9 -0
  2. package/dist/es/baseDB.mjs +109 -0
  3. package/dist/es/build/copy-static.mjs +29 -0
  4. package/dist/es/common.mjs +37 -0
  5. package/dist/es/constants/example-code.mjs +202 -0
  6. package/dist/es/constants/index.mjs +74 -0
  7. package/dist/es/env/basic.mjs +6 -0
  8. package/dist/es/env/constants.mjs +97 -0
  9. package/dist/es/env/decide-model-config.mjs +172 -0
  10. package/dist/es/env/global-config-manager.mjs +82 -0
  11. package/dist/es/env/helper.mjs +45 -0
  12. package/dist/es/env/index.mjs +5 -0
  13. package/dist/es/env/init-debug.mjs +18 -0
  14. package/dist/es/env/model-config-manager.mjs +99 -0
  15. package/dist/es/env/parse.mjs +69 -0
  16. package/dist/es/env/types.mjs +265 -0
  17. package/dist/es/env/utils.mjs +18 -0
  18. package/dist/es/extractor/constants.mjs +2 -0
  19. package/dist/es/extractor/cs_postmessage.mjs +61 -0
  20. package/dist/es/extractor/customLocator.mjs +646 -0
  21. package/dist/es/extractor/debug.mjs +6 -0
  22. package/dist/es/extractor/dom-util.mjs +92 -0
  23. package/dist/es/extractor/index.mjs +7 -0
  24. package/dist/es/extractor/locator.mjs +95 -0
  25. package/dist/es/extractor/tree.mjs +81 -0
  26. package/dist/es/extractor/util.mjs +244 -0
  27. package/dist/es/extractor/web-extractor.mjs +361 -0
  28. package/dist/es/img/box-select.mjs +184 -0
  29. package/dist/es/img/draw-box.mjs +42 -0
  30. package/dist/es/img/get-jimp.mjs +10 -0
  31. package/dist/es/img/get-photon.mjs +19 -0
  32. package/dist/es/img/get-sharp.mjs +11 -0
  33. package/dist/es/img/index.mjs +5 -0
  34. package/dist/es/img/info.mjs +32 -0
  35. package/dist/es/img/transform.mjs +192 -0
  36. package/dist/es/index.mjs +3 -0
  37. package/dist/es/logger.mjs +61 -0
  38. package/dist/es/node/fs.mjs +44 -0
  39. package/dist/es/node/index.mjs +1 -0
  40. package/dist/es/polyfills/async-hooks.mjs +2 -0
  41. package/dist/es/polyfills/index.mjs +1 -0
  42. package/dist/es/types/index.mjs +3 -0
  43. package/dist/es/us-keyboard-layout.mjs +1414 -0
  44. package/dist/es/us-keyboard-layout.mjs.LICENSE.txt +5 -0
  45. package/dist/es/utils.mjs +66 -0
  46. package/dist/lib/baseDB.js +149 -0
  47. package/dist/lib/build/copy-static.js +77 -0
  48. package/dist/lib/common.js +93 -0
  49. package/dist/lib/constants/example-code.js +239 -0
  50. package/dist/lib/constants/index.js +153 -0
  51. package/dist/lib/env/basic.js +40 -0
  52. package/dist/lib/env/constants.js +143 -0
  53. package/dist/lib/env/decide-model-config.js +212 -0
  54. package/dist/lib/env/global-config-manager.js +116 -0
  55. package/dist/lib/env/helper.js +85 -0
  56. package/dist/lib/env/index.js +94 -0
  57. package/dist/lib/env/init-debug.js +52 -0
  58. package/dist/lib/env/model-config-manager.js +133 -0
  59. package/dist/lib/env/parse.js +106 -0
  60. package/dist/lib/env/types.js +650 -0
  61. package/dist/lib/env/utils.js +61 -0
  62. package/dist/lib/extractor/constants.js +42 -0
  63. package/dist/lib/extractor/cs_postmessage.js +98 -0
  64. package/dist/lib/extractor/customLocator.js +698 -0
  65. package/dist/lib/extractor/debug.js +12 -0
  66. package/dist/lib/extractor/dom-util.js +150 -0
  67. package/dist/lib/extractor/index.js +153 -0
  68. package/dist/lib/extractor/locator.js +141 -0
  69. package/dist/lib/extractor/tree.js +127 -0
  70. package/dist/lib/extractor/util.js +335 -0
  71. package/dist/lib/extractor/web-extractor.js +407 -0
  72. package/dist/lib/img/box-select.js +232 -0
  73. package/dist/lib/img/draw-box.js +89 -0
  74. package/dist/lib/img/get-jimp.js +72 -0
  75. package/dist/lib/img/get-photon.js +76 -0
  76. package/dist/lib/img/get-sharp.js +63 -0
  77. package/dist/lib/img/index.js +102 -0
  78. package/dist/lib/img/info.js +86 -0
  79. package/dist/lib/img/transform.js +279 -0
  80. package/dist/lib/index.js +43 -0
  81. package/dist/lib/logger.js +114 -0
  82. package/dist/lib/node/fs.js +97 -0
  83. package/dist/lib/node/index.js +60 -0
  84. package/dist/lib/polyfills/async-hooks.js +36 -0
  85. package/dist/lib/polyfills/index.js +60 -0
  86. package/dist/lib/types/index.js +37 -0
  87. package/dist/lib/us-keyboard-layout.js +1457 -0
  88. package/dist/lib/us-keyboard-layout.js.LICENSE.txt +5 -0
  89. package/dist/lib/utils.js +136 -0
  90. package/dist/types/baseDB.d.ts +25 -0
  91. package/dist/types/build/copy-static.d.ts +31 -0
  92. package/dist/types/common.d.ts +12 -0
  93. package/dist/types/constants/example-code.d.ts +2 -0
  94. package/dist/types/constants/index.d.ts +23 -0
  95. package/dist/types/env/basic.d.ts +6 -0
  96. package/dist/types/env/constants.d.ts +40 -0
  97. package/dist/types/env/decide-model-config.d.ts +14 -0
  98. package/dist/types/env/global-config-manager.d.ts +32 -0
  99. package/dist/types/env/helper.d.ts +6 -0
  100. package/dist/types/env/index.d.ts +4 -0
  101. package/dist/types/env/init-debug.d.ts +1 -0
  102. package/dist/types/env/model-config-manager.d.ts +24 -0
  103. package/dist/types/env/parse.d.ts +12 -0
  104. package/dist/types/env/types.d.ts +295 -0
  105. package/dist/types/env/utils.d.ts +7 -0
  106. package/dist/types/extractor/constants.d.ts +1 -0
  107. package/dist/types/extractor/cs_postmessage.d.ts +2 -0
  108. package/dist/types/extractor/customLocator.d.ts +69 -0
  109. package/dist/types/extractor/debug.d.ts +1 -0
  110. package/dist/types/extractor/dom-util.d.ts +26 -0
  111. package/dist/types/extractor/index.d.ts +36 -0
  112. package/dist/types/extractor/locator.d.ts +7 -0
  113. package/dist/types/extractor/tree.d.ts +9 -0
  114. package/dist/types/extractor/util.d.ts +43 -0
  115. package/dist/types/extractor/web-extractor.d.ts +19 -0
  116. package/dist/types/img/box-select.d.ts +25 -0
  117. package/dist/types/img/draw-box.d.ts +15 -0
  118. package/dist/types/img/get-jimp.d.ts +2 -0
  119. package/dist/types/img/get-photon.d.ts +8 -0
  120. package/dist/types/img/get-sharp.d.ts +3 -0
  121. package/dist/types/img/index.d.ts +4 -0
  122. package/dist/types/img/info.d.ts +29 -0
  123. package/dist/types/img/transform.d.ts +88 -0
  124. package/dist/types/index.d.ts +3 -0
  125. package/dist/types/logger.d.ts +4 -0
  126. package/dist/types/node/fs.d.ts +15 -0
  127. package/dist/types/node/index.d.ts +1 -0
  128. package/dist/types/polyfills/async-hooks.d.ts +6 -0
  129. package/dist/types/polyfills/index.d.ts +4 -0
  130. package/dist/types/types/index.d.ts +37 -0
  131. package/dist/types/us-keyboard-layout.d.ts +32 -0
  132. package/dist/types/utils.d.ts +22 -0
  133. package/package.json +102 -0
  134. package/src/baseDB.ts +158 -0
  135. package/src/build/copy-static.ts +62 -0
  136. package/src/common.ts +67 -0
  137. package/src/constants/example-code.ts +202 -0
  138. package/src/constants/index.ts +81 -0
  139. package/src/env/basic.ts +12 -0
  140. package/src/env/constants.ts +291 -0
  141. package/src/env/decide-model-config.ts +319 -0
  142. package/src/env/global-config-manager.ts +174 -0
  143. package/src/env/helper.ts +80 -0
  144. package/src/env/index.ts +4 -0
  145. package/src/env/init-debug.ts +29 -0
  146. package/src/env/model-config-manager.ts +145 -0
  147. package/src/env/parse.ts +131 -0
  148. package/src/env/types.ts +573 -0
  149. package/src/env/utils.ts +39 -0
  150. package/src/extractor/constants.ts +5 -0
  151. package/src/extractor/cs_postmessage.ts +101 -0
  152. package/src/extractor/customLocator.ts +1138 -0
  153. package/src/extractor/debug.ts +10 -0
  154. package/src/extractor/dom-util.ts +141 -0
  155. package/src/extractor/index.ts +54 -0
  156. package/src/extractor/locator.ts +179 -0
  157. package/src/extractor/tree.ts +179 -0
  158. package/src/extractor/util.ts +468 -0
  159. package/src/extractor/web-extractor.ts +559 -0
  160. package/src/img/box-select.ts +346 -0
  161. package/src/img/draw-box.ts +60 -0
  162. package/src/img/get-jimp.ts +12 -0
  163. package/src/img/get-photon.ts +48 -0
  164. package/src/img/get-sharp.ts +18 -0
  165. package/src/img/index.ts +24 -0
  166. package/src/img/info.ts +79 -0
  167. package/src/img/jimp.d.ts +4 -0
  168. package/src/img/transform.ts +396 -0
  169. package/src/index.ts +6 -0
  170. package/src/logger.ts +93 -0
  171. package/src/node/fs.ts +84 -0
  172. package/src/node/index.ts +1 -0
  173. package/src/polyfills/async-hooks.ts +6 -0
  174. package/src/polyfills/index.ts +4 -0
  175. package/src/types/index.ts +53 -0
  176. package/src/us-keyboard-layout.ts +723 -0
  177. package/src/utils.ts +127 -0
@@ -0,0 +1,319 @@
1
+ import type {
2
+ IModelConfig,
3
+ TIntent,
4
+ TVlModeTypes,
5
+ UITarsModelVersion,
6
+ } from './types';
7
+
8
+ import {
9
+ DEFAULT_MODEL_CONFIG_KEYS,
10
+ DEFAULT_MODEL_CONFIG_KEYS_LEGACY,
11
+ GROUNDING_MODEL_CONFIG_KEYS,
12
+ PLANNING_MODEL_CONFIG_KEYS,
13
+ VQA_MODEL_CONFIG_KEYS,
14
+ } from './constants';
15
+
16
+ import { getDebug } from '../logger';
17
+ import { assert } from '../utils';
18
+ import { createAssert, maskConfig, parseJson } from './helper';
19
+ import { initDebugConfig } from './init-debug';
20
+ import {
21
+ parseVlModeAndUiTarsFromGlobalConfig,
22
+ parseVlModeAndUiTarsModelVersionFromRawValue,
23
+ } from './parse';
24
+
25
+ type TModelConfigKeys =
26
+ | typeof VQA_MODEL_CONFIG_KEYS
27
+ | typeof GROUNDING_MODEL_CONFIG_KEYS
28
+ | typeof PLANNING_MODEL_CONFIG_KEYS
29
+ | typeof DEFAULT_MODEL_CONFIG_KEYS
30
+ | typeof DEFAULT_MODEL_CONFIG_KEYS_LEGACY;
31
+
32
+ const KEYS_MAP: Record<TIntent, TModelConfigKeys> = {
33
+ VQA: VQA_MODEL_CONFIG_KEYS,
34
+ grounding: GROUNDING_MODEL_CONFIG_KEYS,
35
+ planning: PLANNING_MODEL_CONFIG_KEYS,
36
+ default: DEFAULT_MODEL_CONFIG_KEYS,
37
+ } as const;
38
+
39
+ /**
40
+ * Choose OpenAI SDK config, such as OpenAI, AzureOpenAI, AnthropicSDK, etc.
41
+ */
42
+ export const decideOpenaiSdkConfig = ({
43
+ keys,
44
+ provider,
45
+ valueAssert,
46
+ }: {
47
+ keys: TModelConfigKeys;
48
+ provider: Record<string, string | undefined>;
49
+ valueAssert: (
50
+ value: string | undefined,
51
+ key: string,
52
+ modelVendorFlag?: string,
53
+ ) => void;
54
+ }): Omit<
55
+ IModelConfig,
56
+ | 'modelName'
57
+ | 'from'
58
+ | 'vlMode'
59
+ | 'uiTarsVersion'
60
+ | 'modelDescription'
61
+ | 'intent'
62
+ > => {
63
+ initDebugConfig();
64
+ const debugLog = getDebug('ai:config');
65
+
66
+ const socksProxy = provider[keys.socksProxy];
67
+ const httpProxy = provider[keys.httpProxy];
68
+ const vlMode = provider[keys.vlMode];
69
+
70
+ debugLog('enter decideOpenaiSdkConfig with keys:', keys);
71
+ if (provider[keys.openaiUseAzureDeprecated]) {
72
+ debugLog(
73
+ `provider has ${keys.openaiUseAzureDeprecated} with value${provider[keys.openaiUseAzureDeprecated]}`,
74
+ );
75
+ const openaiBaseURL = provider[keys.openaiBaseURL];
76
+ const openaiApiKey = provider[keys.openaiApiKey];
77
+ const openaiExtraConfig = parseJson(
78
+ keys.openaiExtraConfig,
79
+ provider[keys.openaiExtraConfig],
80
+ );
81
+
82
+ valueAssert(openaiApiKey, keys.openaiApiKey, keys.openaiUseAzureDeprecated);
83
+
84
+ return {
85
+ socksProxy,
86
+ httpProxy,
87
+ vlModeRaw: vlMode,
88
+ openaiUseAzureDeprecated: true,
89
+ openaiApiKey,
90
+ openaiBaseURL,
91
+ openaiExtraConfig,
92
+ };
93
+ } else if (provider[keys.useAzureOpenai]) {
94
+ debugLog(
95
+ `provider has ${keys.useAzureOpenai} with value ${provider[keys.useAzureOpenai]}`,
96
+ );
97
+ const azureOpenaiScope = provider[keys.azureOpenaiScope];
98
+
99
+ const azureOpenaiKey = provider[keys.azureOpenaiKey];
100
+ const azureOpenaiEndpoint = provider[keys.azureOpenaiEndpoint];
101
+ const azureOpenaiDeployment = provider[keys.azureOpenaiDeployment];
102
+ const azureOpenaiApiVersion = provider[keys.azureOpenaiApiVersion];
103
+
104
+ const azureExtraConfig = parseJson(
105
+ keys.azureExtraConfig,
106
+ provider[keys.azureExtraConfig],
107
+ );
108
+ const openaiExtraConfig = parseJson(
109
+ keys.openaiExtraConfig,
110
+ provider[keys.openaiExtraConfig],
111
+ );
112
+
113
+ valueAssert(azureOpenaiKey, keys.azureOpenaiKey, keys.useAzureOpenai);
114
+
115
+ return {
116
+ socksProxy,
117
+ httpProxy,
118
+ vlModeRaw: vlMode,
119
+ useAzureOpenai: true,
120
+ azureOpenaiScope,
121
+ azureOpenaiKey,
122
+ azureOpenaiEndpoint,
123
+ azureOpenaiDeployment,
124
+ azureOpenaiApiVersion,
125
+ azureExtraConfig,
126
+ openaiExtraConfig,
127
+ };
128
+ } else if (provider[keys.useAnthropicSdk]) {
129
+ debugLog(
130
+ `provider has ${keys.useAnthropicSdk} with value ${provider[keys.useAnthropicSdk]}`,
131
+ );
132
+ const anthropicApiKey = provider[keys.anthropicApiKey];
133
+ valueAssert(anthropicApiKey, keys.anthropicApiKey, keys.useAnthropicSdk);
134
+
135
+ return {
136
+ socksProxy,
137
+ httpProxy,
138
+ useAnthropicSdk: true,
139
+ anthropicApiKey,
140
+ };
141
+ } else {
142
+ debugLog('provider has no specific model SDK declared');
143
+ const openaiBaseURL = provider[keys.openaiBaseURL];
144
+ const openaiApiKey = provider[keys.openaiApiKey];
145
+ const openaiExtraConfig = parseJson(
146
+ keys.openaiExtraConfig,
147
+ provider[keys.openaiExtraConfig],
148
+ );
149
+
150
+ valueAssert(openaiApiKey, keys.openaiApiKey);
151
+
152
+ return {
153
+ socksProxy,
154
+ httpProxy,
155
+ vlModeRaw: vlMode,
156
+ openaiBaseURL,
157
+ openaiApiKey,
158
+ openaiExtraConfig,
159
+ };
160
+ }
161
+ };
162
+
163
+ const getModelDescription = (
164
+ vlMode: TVlModeTypes | undefined,
165
+ uiTarsVersion: UITarsModelVersion | undefined,
166
+ ) => {
167
+ if (vlMode) {
168
+ if (uiTarsVersion) {
169
+ return `UI-TARS=${uiTarsVersion}`;
170
+ } else {
171
+ return `${vlMode} mode`;
172
+ }
173
+ }
174
+ return '';
175
+ };
176
+
177
+ export const decideModelConfigFromIntentConfig = (
178
+ intent: TIntent,
179
+ intentConfig: Record<string, string | undefined>,
180
+ ): IModelConfig => {
181
+ const debugLog = getDebug('ai:config');
182
+
183
+ debugLog('decideModelConfig base on agent.modelConfig()');
184
+
185
+ const keysForFn = KEYS_MAP[intent];
186
+
187
+ const candidateModelNameFromConfig = intentConfig[keysForFn.modelName];
188
+
189
+ debugLog('Got modelName from modelConfigFn', candidateModelNameFromConfig);
190
+
191
+ const chosenKeys = (() => {
192
+ if (candidateModelNameFromConfig) {
193
+ debugLog(
194
+ 'query modelConfig from fn by intent got corresponding modelName, will get other corresponding keys',
195
+ );
196
+ return keysForFn;
197
+ } else {
198
+ debugLog(
199
+ 'query modelConfig from fn by intent got no corresponding modelName, will get other keys by default',
200
+ );
201
+ assert(
202
+ intentConfig[DEFAULT_MODEL_CONFIG_KEYS.modelName],
203
+ `The return value of agent.modelConfig do not have a valid value with key ${DEFAULT_MODEL_CONFIG_KEYS.modelName}.`,
204
+ );
205
+ return DEFAULT_MODEL_CONFIG_KEYS;
206
+ }
207
+ })();
208
+
209
+ const result = decideOpenaiSdkConfig({
210
+ keys: chosenKeys,
211
+ provider: intentConfig,
212
+ valueAssert: createAssert(
213
+ chosenKeys.modelName,
214
+ 'modelConfig',
215
+ candidateModelNameFromConfig,
216
+ ),
217
+ });
218
+
219
+ const { vlMode, uiTarsVersion } =
220
+ parseVlModeAndUiTarsModelVersionFromRawValue(result.vlModeRaw);
221
+
222
+ const modelDescription = getModelDescription(vlMode, uiTarsVersion);
223
+
224
+ const finalResult: IModelConfig = {
225
+ ...result,
226
+ modelName: intentConfig[chosenKeys.modelName]!,
227
+ vlMode,
228
+ uiTarsModelVersion: uiTarsVersion,
229
+ modelDescription,
230
+ from: 'modelConfig',
231
+ intent,
232
+ };
233
+
234
+ debugLog(
235
+ `decideModelConfig result by agent.modelConfig() with intent ${intent}:`,
236
+ maskConfig(finalResult),
237
+ );
238
+ return finalResult;
239
+ };
240
+
241
+ export const decideModelConfigFromEnv = (
242
+ intent: TIntent,
243
+ allEnvConfig: Record<string, string | undefined>,
244
+ ): IModelConfig => {
245
+ initDebugConfig();
246
+ const debugLog = getDebug('ai:config');
247
+
248
+ const keysForEnv =
249
+ intent === 'default' ? DEFAULT_MODEL_CONFIG_KEYS_LEGACY : KEYS_MAP[intent];
250
+
251
+ if (intent !== 'default' && allEnvConfig[keysForEnv.modelName]) {
252
+ const modelName = allEnvConfig[keysForEnv.modelName]!;
253
+
254
+ debugLog(
255
+ `Got intent ${intent} corresponding modelName ${modelName} by key ${keysForEnv.modelName} from globalConfig, will get other config by intent.`,
256
+ );
257
+
258
+ const result = decideOpenaiSdkConfig({
259
+ keys: keysForEnv,
260
+ provider: allEnvConfig,
261
+ valueAssert: createAssert(keysForEnv.modelName, 'process.env', modelName),
262
+ });
263
+
264
+ const { vlMode, uiTarsVersion } =
265
+ parseVlModeAndUiTarsModelVersionFromRawValue(result.vlModeRaw);
266
+ const modelDescription = getModelDescription(vlMode, uiTarsVersion);
267
+
268
+ const finalResult: IModelConfig = {
269
+ ...result,
270
+ modelName,
271
+ vlMode,
272
+ uiTarsModelVersion: uiTarsVersion,
273
+ modelDescription,
274
+ from: 'env',
275
+ intent,
276
+ };
277
+
278
+ debugLog(
279
+ `decideModelConfig result by process.env with intent ${intent}:`,
280
+ maskConfig(finalResult),
281
+ );
282
+ return finalResult;
283
+ }
284
+
285
+ debugLog(`decideModelConfig as legacy logic with intent ${intent}.`);
286
+
287
+ // TODO: when fallback to legacy logic, prefer to read RPASCENE_OPENAI_API_KEY rather than OPENAI_API_KEY
288
+ const result = decideOpenaiSdkConfig({
289
+ keys: DEFAULT_MODEL_CONFIG_KEYS_LEGACY,
290
+ provider: allEnvConfig,
291
+ valueAssert: createAssert(
292
+ DEFAULT_MODEL_CONFIG_KEYS_LEGACY.modelName,
293
+ 'process.env',
294
+ ),
295
+ });
296
+
297
+ const { vlMode, uiTarsVersion } =
298
+ parseVlModeAndUiTarsFromGlobalConfig(allEnvConfig);
299
+
300
+ const modelDescription = getModelDescription(vlMode, uiTarsVersion);
301
+
302
+ const finalResult: IModelConfig = {
303
+ ...result,
304
+ // In the legacy logic, GPT-4o is the default model.
305
+ modelName:
306
+ allEnvConfig[DEFAULT_MODEL_CONFIG_KEYS_LEGACY.modelName] || 'gpt-4o',
307
+ vlMode,
308
+ uiTarsModelVersion: uiTarsVersion,
309
+ modelDescription,
310
+ from: 'legacy-env',
311
+ intent,
312
+ };
313
+
314
+ debugLog(
315
+ `decideModelConfig result by legacy logic with intent ${intent}:`,
316
+ maskConfig(finalResult),
317
+ );
318
+ return finalResult;
319
+ };
@@ -0,0 +1,174 @@
1
+ import { getDebug } from '../logger';
2
+ import { initDebugConfig } from './init-debug';
3
+ import type { ModelConfigManager } from './model-config-manager';
4
+ import {
5
+ BOOLEAN_ENV_KEYS,
6
+ GLOBAL_ENV_KEYS,
7
+ NUMBER_ENV_KEYS,
8
+ STRING_ENV_KEYS,
9
+ } from './types';
10
+
11
+ import {
12
+ ALL_ENV_KEYS,
13
+ MATCH_BY_POSITION,
14
+ MODEL_ENV_KEYS,
15
+ type TGlobalConfig,
16
+ } from './types';
17
+
18
+ /**
19
+ * Collect global configs from process.env, overrideAIConfig, etc.
20
+ * And provider methods to get merged config value
21
+ */
22
+ export class GlobalConfigManager {
23
+ private override:
24
+ | {
25
+ newConfig?: Partial<TGlobalConfig>;
26
+ extendMode?: boolean;
27
+ }
28
+ | undefined;
29
+
30
+ private keysHaveBeenRead: Record<string, boolean> = {};
31
+
32
+ private globalModelConfigManager: ModelConfigManager | undefined = undefined;
33
+
34
+ constructor() {
35
+ initDebugConfig();
36
+ }
37
+
38
+ /**
39
+ * recalculate allEnvConfig every time because process.env can be updated any time
40
+ */
41
+ public getAllEnvConfig() {
42
+ const envConfig = ALL_ENV_KEYS.reduce(
43
+ (p, name) => {
44
+ p[name] = process.env[name];
45
+ return p;
46
+ },
47
+ Object.create(null) as Record<string, string | undefined>,
48
+ );
49
+
50
+ if (this.override) {
51
+ const { newConfig, extendMode } = this.override;
52
+ if (extendMode) {
53
+ return { ...envConfig, ...newConfig };
54
+ } else {
55
+ return { ...newConfig };
56
+ }
57
+ } else {
58
+ return envConfig;
59
+ }
60
+ }
61
+
62
+ getEnvConfigValue(key: (typeof STRING_ENV_KEYS)[number]) {
63
+ const allConfig = this.getAllEnvConfig();
64
+
65
+ if (!STRING_ENV_KEYS.includes(key)) {
66
+ throw new Error(`getEnvConfigValue with key ${key} is not supported.`);
67
+ }
68
+ if (key === MATCH_BY_POSITION) {
69
+ throw new Error(
70
+ 'MATCH_BY_POSITION is deprecated, use RPASCENE_USE_VL_MODEL instead',
71
+ );
72
+ }
73
+ const value = allConfig[key];
74
+ this.keysHaveBeenRead[key] = true;
75
+ if (typeof value === 'string') {
76
+ return value.trim();
77
+ }
78
+ return value;
79
+ }
80
+
81
+ /**
82
+ * read number only from process.env
83
+ */
84
+ getEnvConfigInNumber(key: (typeof NUMBER_ENV_KEYS)[number]): number {
85
+ const allConfig = this.getAllEnvConfig();
86
+
87
+ if (!NUMBER_ENV_KEYS.includes(key)) {
88
+ throw new Error(`getEnvConfigInNumber with key ${key} is not supported`);
89
+ }
90
+ const value = allConfig[key];
91
+ this.keysHaveBeenRead[key] = true;
92
+ return Number(value || '');
93
+ }
94
+
95
+ /**
96
+ * read boolean only from process.env
97
+ */
98
+ getEnvConfigInBoolean(key: (typeof BOOLEAN_ENV_KEYS)[number]): boolean {
99
+ const allConfig = this.getAllEnvConfig();
100
+
101
+ if (!BOOLEAN_ENV_KEYS.includes(key)) {
102
+ throw new Error(`getEnvConfigInBoolean with key ${key} is not supported`);
103
+ }
104
+
105
+ const value = allConfig[key];
106
+ this.keysHaveBeenRead[key] = true;
107
+
108
+ if (!value) {
109
+ return false;
110
+ }
111
+ if (/^(true|1)$/i.test(value)) {
112
+ return true;
113
+ }
114
+ if (/^(false|0)$/i.test(value)) {
115
+ return false;
116
+ }
117
+ return !!value.trim();
118
+ }
119
+
120
+ registerModelConfigManager(globalModelConfigManager: ModelConfigManager) {
121
+ this.globalModelConfigManager = globalModelConfigManager;
122
+ }
123
+
124
+ /**
125
+ * for overrideAIConfig
126
+ * can only override keys in MODEL_ENV_KEYS
127
+ */
128
+ overrideAIConfig(
129
+ newConfig: Partial<
130
+ Record<
131
+ (typeof GLOBAL_ENV_KEYS)[number] | (typeof MODEL_ENV_KEYS)[number],
132
+ string
133
+ >
134
+ >,
135
+ extendMode = false, // true: merge with global config, false: override global config
136
+ ) {
137
+ // for (const key in newConfig) {
138
+ // if (![...GLOBAL_ENV_KEYS, ...MODEL_ENV_KEYS].includes(key as never)) {
139
+ // throw new Error(`Failed to override AI config, invalid key: ${key}`);
140
+ // }
141
+ // const value = newConfig[key as keyof typeof newConfig];
142
+ // if (typeof value !== 'string') {
143
+ // throw new Error(
144
+ // `Failed to override AI config, value for key ${key} must be a string, but got with type ${typeof value}`,
145
+ // );
146
+ // }
147
+ // if (this.keysHaveBeenRead[key]) {
148
+ // console.warn(
149
+ // `Warning: try to override AI config with key ${key} ,but it has been read.`,
150
+ // );
151
+ // }
152
+ // }
153
+ const savedNewConfig = extendMode
154
+ ? {
155
+ ...this.override?.newConfig,
156
+ ...newConfig,
157
+ }
158
+ : newConfig;
159
+
160
+ this.override = {
161
+ newConfig: {
162
+ ...savedNewConfig,
163
+ },
164
+ extendMode,
165
+ };
166
+
167
+ if (!this.globalModelConfigManager) {
168
+ throw new Error(
169
+ 'globalModelConfigManager is not registered, which should not happen',
170
+ );
171
+ }
172
+ this.globalModelConfigManager.clearModelConfigMap();
173
+ }
174
+ }
@@ -0,0 +1,80 @@
1
+ import { assert } from '../utils';
2
+ import type { IModelConfig } from './types';
3
+
4
+ const maskKey = (key: string, maskChar = '*') => {
5
+ if (typeof key !== 'string' || key.length === 0) {
6
+ return key;
7
+ }
8
+
9
+ const prefixLen = 3;
10
+ const suffixLen = 3;
11
+ const keepLength = prefixLen + suffixLen;
12
+
13
+ if (key.length <= keepLength) {
14
+ return key;
15
+ }
16
+
17
+ const prefix = key.substring(0, prefixLen);
18
+ const suffix = key.substring(key.length - suffixLen);
19
+ const maskLength = key.length - keepLength;
20
+ const mask = maskChar.repeat(maskLength);
21
+
22
+ return `${prefix}${mask}${suffix}`;
23
+ };
24
+
25
+ export const maskConfig = (config: IModelConfig) => {
26
+ return Object.fromEntries(
27
+ Object.entries(config).map(([key, value]) => {
28
+ if (['openaiApiKey', 'azureOpenaiKey', 'anthropicApiKey'].includes(key)) {
29
+ return [key, maskKey(value)];
30
+ } else if (['openaiExtraConfig', 'azureExtraConfig'].includes(key)) {
31
+ return [key, maskKey(JSON.stringify(value))];
32
+ }
33
+ return [key, value];
34
+ }),
35
+ );
36
+ };
37
+
38
+ export const parseJson = (key: string, value: string | undefined) => {
39
+ if (value) {
40
+ try {
41
+ return JSON.parse(value);
42
+ } catch (e) {
43
+ throw new Error(
44
+ `Failed to parse ${key} as a JSON. ${(e as Error).message}`,
45
+ {
46
+ cause: e,
47
+ },
48
+ );
49
+ }
50
+ }
51
+ return undefined;
52
+ };
53
+
54
+ export const createAssert =
55
+ (
56
+ modelNameKey: string,
57
+ provider: 'process.env' | 'modelConfig',
58
+ modelName?: string,
59
+ ) =>
60
+ (value: string | undefined, key: string, modelVendorFlag?: string) => {
61
+ return
62
+ if (modelName) {
63
+ if (modelVendorFlag) {
64
+ assert(
65
+ value,
66
+ `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}. Please check your config.`,
67
+ );
68
+ } else {
69
+ assert(
70
+ value,
71
+ `The ${key} must be a non-empty string because of the ${modelNameKey} is declared as ${modelName} in ${provider}, but got: ${value}. Please check your config.`,
72
+ );
73
+ }
74
+ } else {
75
+ assert(
76
+ value,
77
+ `The ${key} must be a non-empty string, but got: ${value}. Please check your config.`,
78
+ );
79
+ }
80
+ };
@@ -0,0 +1,4 @@
1
+ export * from './utils';
2
+ export * from './types';
3
+ export { ModelConfigManager } from './model-config-manager';
4
+ export { GlobalConfigManager } from './global-config-manager';
@@ -0,0 +1,29 @@
1
+ import { enableDebug } from '../logger';
2
+ import { getBasicEnvValue } from './basic';
3
+ import { RPASCENE_DEBUG_AI_PROFILE, RPASCENE_DEBUG_AI_RESPONSE } from './types';
4
+
5
+ export const initDebugConfig = () => {
6
+ const shouldPrintTiming = getBasicEnvValue(RPASCENE_DEBUG_AI_PROFILE);
7
+ let debugConfig = '';
8
+ if (shouldPrintTiming) {
9
+ console.warn(
10
+ 'RPASCENE_DEBUG_AI_PROFILE is deprecated, use DEBUG=rpascene:ai:profile instead',
11
+ );
12
+ debugConfig = 'ai:profile';
13
+ }
14
+ const shouldPrintAIResponse = getBasicEnvValue(RPASCENE_DEBUG_AI_RESPONSE);
15
+
16
+ if (shouldPrintAIResponse) {
17
+ console.warn(
18
+ 'RPASCENE_DEBUG_AI_RESPONSE is deprecated, use DEBUG=rpascene:ai:response instead',
19
+ );
20
+ if (debugConfig) {
21
+ debugConfig = 'ai:*';
22
+ } else {
23
+ debugConfig = 'ai:call';
24
+ }
25
+ }
26
+ if (debugConfig) {
27
+ enableDebug(debugConfig);
28
+ }
29
+ };