librechat-data-provider 0.4.7 → 0.4.9
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.
- package/dist/index.es.js +1 -1
- package/dist/index.es.js.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/react-query/index.es.js +1 -1
- package/dist/react-query/index.es.js.map +1 -1
- package/package.json +1 -1
- package/specs/azure.spec.ts +55 -1
- package/src/api-endpoints.ts +14 -1
- package/src/azure.ts +92 -7
- package/src/config.ts +56 -11
- package/src/data-service.ts +6 -3
- package/src/schemas.ts +1 -1
- package/src/types/mutations.ts +3 -0
- package/src/types.ts +14 -0
package/specs/azure.spec.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { TAzureGroups } from '../src/config';
|
|
2
|
-
import { validateAzureGroups, mapModelToAzureConfig } from '../src/azure';
|
|
2
|
+
import { validateAzureGroups, mapModelToAzureConfig, mapGroupToAzureConfig } from '../src/azure';
|
|
3
3
|
|
|
4
4
|
describe('validateAzureGroups', () => {
|
|
5
5
|
it('should validate a correct configuration', () => {
|
|
@@ -785,3 +785,57 @@ describe('validateAzureGroups with modelGroupMap and groupMap', () => {
|
|
|
785
785
|
});
|
|
786
786
|
});
|
|
787
787
|
});
|
|
788
|
+
|
|
789
|
+
describe('mapGroupToAzureConfig', () => {
|
|
790
|
+
// Test setup for a basic config with 2 groups
|
|
791
|
+
const groupMap = {
|
|
792
|
+
group1: {
|
|
793
|
+
apiKey: 'key-for-group1',
|
|
794
|
+
instanceName: 'instance-group1',
|
|
795
|
+
models: {
|
|
796
|
+
model1: { deploymentName: 'deployment1', version: '1.0' },
|
|
797
|
+
},
|
|
798
|
+
},
|
|
799
|
+
group2: {
|
|
800
|
+
apiKey: 'key-for-group2',
|
|
801
|
+
instanceName: 'instance-group2',
|
|
802
|
+
serverless: true,
|
|
803
|
+
baseURL: 'https://group2.example.com',
|
|
804
|
+
models: {
|
|
805
|
+
model2: true, // demonstrating a boolean style model configuration
|
|
806
|
+
},
|
|
807
|
+
},
|
|
808
|
+
};
|
|
809
|
+
|
|
810
|
+
it('should successfully map non-serverless group configuration', () => {
|
|
811
|
+
const groupName = 'group1';
|
|
812
|
+
const result = mapGroupToAzureConfig({ groupName, groupMap });
|
|
813
|
+
expect(result).toEqual({
|
|
814
|
+
azureOptions: expect.objectContaining({
|
|
815
|
+
azureOpenAIApiKey: 'key-for-group1',
|
|
816
|
+
azureOpenAIApiInstanceName: 'instance-group1',
|
|
817
|
+
azureOpenAIApiDeploymentName: expect.any(String),
|
|
818
|
+
azureOpenAIApiVersion: expect.any(String),
|
|
819
|
+
}),
|
|
820
|
+
});
|
|
821
|
+
});
|
|
822
|
+
|
|
823
|
+
it('should successfully map serverless group configuration', () => {
|
|
824
|
+
const groupName = 'group2';
|
|
825
|
+
const result = mapGroupToAzureConfig({ groupName, groupMap });
|
|
826
|
+
expect(result).toEqual({
|
|
827
|
+
azureOptions: expect.objectContaining({
|
|
828
|
+
azureOpenAIApiKey: 'key-for-group2',
|
|
829
|
+
}),
|
|
830
|
+
baseURL: 'https://group2.example.com',
|
|
831
|
+
serverless: true,
|
|
832
|
+
});
|
|
833
|
+
});
|
|
834
|
+
|
|
835
|
+
it('should throw error for nonexistent group name', () => {
|
|
836
|
+
const groupName = 'nonexistent-group';
|
|
837
|
+
expect(() => {
|
|
838
|
+
mapGroupToAzureConfig({ groupName, groupMap });
|
|
839
|
+
}).toThrow(`Group named "${groupName}" not found in configuration.`);
|
|
840
|
+
});
|
|
841
|
+
});
|
package/src/api-endpoints.ts
CHANGED
|
@@ -66,7 +66,20 @@ export const plugins = () => '/api/plugins';
|
|
|
66
66
|
|
|
67
67
|
export const config = () => '/api/config';
|
|
68
68
|
|
|
69
|
-
export const assistants = (id?: string) =>
|
|
69
|
+
export const assistants = (id?: string, options?: Record<string, string>) => {
|
|
70
|
+
let url = '/api/assistants';
|
|
71
|
+
|
|
72
|
+
if (id) {
|
|
73
|
+
url += `/${id}`;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
if (options && Object.keys(options).length > 0) {
|
|
77
|
+
const queryParams = new URLSearchParams(options).toString();
|
|
78
|
+
url += `?${queryParams}`;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return url;
|
|
82
|
+
};
|
|
70
83
|
|
|
71
84
|
export const files = () => '/api/files';
|
|
72
85
|
|
package/src/azure.ts
CHANGED
|
@@ -234,14 +234,16 @@ export function mapModelToAzureConfig({
|
|
|
234
234
|
}
|
|
235
235
|
|
|
236
236
|
const modelDetails = groupConfig.models[modelName];
|
|
237
|
-
const deploymentName =
|
|
237
|
+
const { deploymentName, version } =
|
|
238
238
|
typeof modelDetails === 'object'
|
|
239
|
-
?
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
239
|
+
? {
|
|
240
|
+
deploymentName: modelDetails.deploymentName || groupConfig.deploymentName,
|
|
241
|
+
version: modelDetails.version || groupConfig.version,
|
|
242
|
+
}
|
|
243
|
+
: {
|
|
244
|
+
deploymentName: groupConfig.deploymentName,
|
|
245
|
+
version: groupConfig.version,
|
|
246
|
+
};
|
|
245
247
|
|
|
246
248
|
if (!deploymentName || !version) {
|
|
247
249
|
throw new Error(
|
|
@@ -274,3 +276,86 @@ export function mapModelToAzureConfig({
|
|
|
274
276
|
|
|
275
277
|
return result;
|
|
276
278
|
}
|
|
279
|
+
|
|
280
|
+
export function mapGroupToAzureConfig({
|
|
281
|
+
groupName,
|
|
282
|
+
groupMap,
|
|
283
|
+
}: {
|
|
284
|
+
groupName: string;
|
|
285
|
+
groupMap: TAzureGroupMap;
|
|
286
|
+
}): MappedAzureConfig {
|
|
287
|
+
const groupConfig = groupMap[groupName];
|
|
288
|
+
if (!groupConfig) {
|
|
289
|
+
throw new Error(`Group named "${groupName}" not found in configuration.`);
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
const instanceName = groupConfig.instanceName as string;
|
|
293
|
+
|
|
294
|
+
if (!instanceName && !groupConfig.serverless) {
|
|
295
|
+
throw new Error(
|
|
296
|
+
`Group "${groupName}" is missing an instanceName for non-serverless configuration.`,
|
|
297
|
+
);
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
if (groupConfig.serverless && !groupConfig.baseURL) {
|
|
301
|
+
throw new Error(
|
|
302
|
+
`Group "${groupName}" is missing the required base URL for serverless configuration.`,
|
|
303
|
+
);
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
const models = Object.keys(groupConfig.models);
|
|
307
|
+
if (models.length === 0) {
|
|
308
|
+
throw new Error(`Group "${groupName}" does not have any models configured.`);
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
// Use the first available model in the group
|
|
312
|
+
const firstModelName = models[0];
|
|
313
|
+
const modelDetails = groupConfig.models[firstModelName];
|
|
314
|
+
|
|
315
|
+
const azureOptions: AzureOptions = {
|
|
316
|
+
azureOpenAIApiKey: extractEnvVariable(groupConfig.apiKey),
|
|
317
|
+
azureOpenAIApiInstanceName: extractEnvVariable(instanceName),
|
|
318
|
+
// DeploymentName and Version set below
|
|
319
|
+
};
|
|
320
|
+
|
|
321
|
+
if (groupConfig.serverless) {
|
|
322
|
+
return {
|
|
323
|
+
azureOptions,
|
|
324
|
+
baseURL: extractEnvVariable(groupConfig.baseURL ?? ''),
|
|
325
|
+
serverless: true,
|
|
326
|
+
...(groupConfig.additionalHeaders && { headers: groupConfig.additionalHeaders }),
|
|
327
|
+
};
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
const { deploymentName, version } =
|
|
331
|
+
typeof modelDetails === 'object'
|
|
332
|
+
? {
|
|
333
|
+
deploymentName: modelDetails.deploymentName || groupConfig.deploymentName,
|
|
334
|
+
version: modelDetails.version || groupConfig.version,
|
|
335
|
+
}
|
|
336
|
+
: {
|
|
337
|
+
deploymentName: groupConfig.deploymentName,
|
|
338
|
+
version: groupConfig.version,
|
|
339
|
+
};
|
|
340
|
+
|
|
341
|
+
if (!deploymentName || !version) {
|
|
342
|
+
throw new Error(
|
|
343
|
+
`Model "${firstModelName}" in group "${groupName}" or the group itself is missing a deploymentName ("${deploymentName}") or version ("${version}").`,
|
|
344
|
+
);
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
azureOptions.azureOpenAIApiDeploymentName = extractEnvVariable(deploymentName);
|
|
348
|
+
azureOptions.azureOpenAIApiVersion = extractEnvVariable(version);
|
|
349
|
+
|
|
350
|
+
const result: MappedAzureConfig = { azureOptions };
|
|
351
|
+
|
|
352
|
+
if (groupConfig.baseURL) {
|
|
353
|
+
result.baseURL = extractEnvVariable(groupConfig.baseURL);
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
if (groupConfig.additionalHeaders) {
|
|
357
|
+
result.headers = groupConfig.additionalHeaders;
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
return result;
|
|
361
|
+
}
|
package/src/config.ts
CHANGED
|
@@ -6,12 +6,25 @@ import { FileSources } from './types/files';
|
|
|
6
6
|
|
|
7
7
|
export const defaultSocialLogins = ['google', 'facebook', 'openid', 'github', 'discord'];
|
|
8
8
|
|
|
9
|
+
export const defaultRetrievalModels = [
|
|
10
|
+
'gpt-4-turbo-preview',
|
|
11
|
+
'gpt-3.5-turbo-0125',
|
|
12
|
+
'gpt-4-0125-preview',
|
|
13
|
+
'gpt-4-1106-preview',
|
|
14
|
+
'gpt-3.5-turbo-1106',
|
|
15
|
+
'gpt-3.5-turbo-0125',
|
|
16
|
+
'gpt-4-turbo',
|
|
17
|
+
'gpt-4-0125',
|
|
18
|
+
'gpt-4-1106',
|
|
19
|
+
];
|
|
20
|
+
|
|
9
21
|
export const fileSourceSchema = z.nativeEnum(FileSources);
|
|
10
22
|
|
|
11
23
|
export const modelConfigSchema = z
|
|
12
24
|
.object({
|
|
13
25
|
deploymentName: z.string().optional(),
|
|
14
26
|
version: z.string().optional(),
|
|
27
|
+
assistants: z.boolean().optional(),
|
|
15
28
|
})
|
|
16
29
|
.or(z.boolean());
|
|
17
30
|
|
|
@@ -22,6 +35,7 @@ export const azureBaseSchema = z.object({
|
|
|
22
35
|
serverless: z.boolean().optional(),
|
|
23
36
|
instanceName: z.string().optional(),
|
|
24
37
|
deploymentName: z.string().optional(),
|
|
38
|
+
assistants: z.boolean().optional(),
|
|
25
39
|
addParams: z.record(z.any()).optional(),
|
|
26
40
|
dropParams: z.array(z.string()).optional(),
|
|
27
41
|
forcePrompt: z.boolean().optional(),
|
|
@@ -61,6 +75,13 @@ export type TValidatedAzureConfig = {
|
|
|
61
75
|
groupMap: TAzureGroupMap;
|
|
62
76
|
};
|
|
63
77
|
|
|
78
|
+
export enum Capabilities {
|
|
79
|
+
code_interpreter = 'code_interpreter',
|
|
80
|
+
retrieval = 'retrieval',
|
|
81
|
+
actions = 'actions',
|
|
82
|
+
tools = 'tools',
|
|
83
|
+
}
|
|
84
|
+
|
|
64
85
|
export const assistantEndpointSchema = z.object({
|
|
65
86
|
/* assistants specific */
|
|
66
87
|
disableBuilder: z.boolean().optional(),
|
|
@@ -68,6 +89,16 @@ export const assistantEndpointSchema = z.object({
|
|
|
68
89
|
timeoutMs: z.number().optional(),
|
|
69
90
|
supportedIds: z.array(z.string()).min(1).optional(),
|
|
70
91
|
excludedIds: z.array(z.string()).min(1).optional(),
|
|
92
|
+
retrievalModels: z.array(z.string()).min(1).optional().default(defaultRetrievalModels),
|
|
93
|
+
capabilities: z
|
|
94
|
+
.array(z.nativeEnum(Capabilities))
|
|
95
|
+
.optional()
|
|
96
|
+
.default([
|
|
97
|
+
Capabilities.code_interpreter,
|
|
98
|
+
Capabilities.retrieval,
|
|
99
|
+
Capabilities.actions,
|
|
100
|
+
Capabilities.tools,
|
|
101
|
+
]),
|
|
71
102
|
/* general */
|
|
72
103
|
apiKey: z.string().optional(),
|
|
73
104
|
baseURL: z.string().optional(),
|
|
@@ -116,6 +147,7 @@ export const azureEndpointSchema = z
|
|
|
116
147
|
.object({
|
|
117
148
|
groups: azureGroupConfigsSchema,
|
|
118
149
|
plugins: z.boolean().optional(),
|
|
150
|
+
assistants: z.boolean().optional(),
|
|
119
151
|
})
|
|
120
152
|
.and(
|
|
121
153
|
endpointSchema
|
|
@@ -147,6 +179,22 @@ export const rateLimitSchema = z.object({
|
|
|
147
179
|
export const configSchema = z.object({
|
|
148
180
|
version: z.string(),
|
|
149
181
|
cache: z.boolean(),
|
|
182
|
+
interface: z
|
|
183
|
+
.object({
|
|
184
|
+
privacyPolicy: z
|
|
185
|
+
.object({
|
|
186
|
+
externalUrl: z.string().optional(),
|
|
187
|
+
openNewTab: z.boolean().optional(),
|
|
188
|
+
})
|
|
189
|
+
.optional(),
|
|
190
|
+
termsOfService: z
|
|
191
|
+
.object({
|
|
192
|
+
externalUrl: z.string().optional(),
|
|
193
|
+
openNewTab: z.boolean().optional(),
|
|
194
|
+
})
|
|
195
|
+
.optional(),
|
|
196
|
+
})
|
|
197
|
+
.optional(),
|
|
150
198
|
fileStrategy: fileSourceSchema.optional(),
|
|
151
199
|
registration: z
|
|
152
200
|
.object({
|
|
@@ -272,14 +320,6 @@ export const defaultModels = {
|
|
|
272
320
|
],
|
|
273
321
|
};
|
|
274
322
|
|
|
275
|
-
export const supportsRetrieval = new Set([
|
|
276
|
-
'gpt-3.5-turbo-0125',
|
|
277
|
-
'gpt-4-0125-preview',
|
|
278
|
-
'gpt-4-turbo-preview',
|
|
279
|
-
'gpt-4-1106-preview',
|
|
280
|
-
'gpt-3.5-turbo-1106',
|
|
281
|
-
]);
|
|
282
|
-
|
|
283
323
|
export const EndpointURLs: { [key in EModelEndpoint]: string } = {
|
|
284
324
|
[EModelEndpoint.openAI]: `/api/ask/${EModelEndpoint.openAI}`,
|
|
285
325
|
[EModelEndpoint.bingAI]: `/api/ask/${EModelEndpoint.bingAI}`,
|
|
@@ -302,11 +342,12 @@ export const modularEndpoints = new Set<EModelEndpoint | string>([
|
|
|
302
342
|
]);
|
|
303
343
|
|
|
304
344
|
export const supportsBalanceCheck = {
|
|
345
|
+
[EModelEndpoint.custom]: true,
|
|
305
346
|
[EModelEndpoint.openAI]: true,
|
|
306
347
|
[EModelEndpoint.anthropic]: true,
|
|
307
|
-
[EModelEndpoint.azureOpenAI]: true,
|
|
308
348
|
[EModelEndpoint.gptPlugins]: true,
|
|
309
|
-
[EModelEndpoint.
|
|
349
|
+
[EModelEndpoint.assistants]: true,
|
|
350
|
+
[EModelEndpoint.azureOpenAI]: true,
|
|
310
351
|
};
|
|
311
352
|
|
|
312
353
|
export const visionModels = ['gpt-4-vision', 'llava-13b', 'gemini-pro-vision', 'claude-3'];
|
|
@@ -396,6 +437,10 @@ export enum ViolationTypes {
|
|
|
396
437
|
* Illegal Model Request (not available).
|
|
397
438
|
*/
|
|
398
439
|
ILLEGAL_MODEL_REQUEST = 'illegal_model_request',
|
|
440
|
+
/**
|
|
441
|
+
* Token Limit Violation.
|
|
442
|
+
*/
|
|
443
|
+
TOKEN_BALANCE = 'token_balance',
|
|
399
444
|
}
|
|
400
445
|
|
|
401
446
|
/**
|
|
@@ -469,7 +514,7 @@ export enum Constants {
|
|
|
469
514
|
/**
|
|
470
515
|
* Key for the Custom Config's version (librechat.yaml).
|
|
471
516
|
*/
|
|
472
|
-
CONFIG_VERSION = '1.0.
|
|
517
|
+
CONFIG_VERSION = '1.0.5',
|
|
473
518
|
/**
|
|
474
519
|
* Standard value for the first message's `parentMessageId` value, to indicate no parent exists.
|
|
475
520
|
*/
|
package/src/data-service.ts
CHANGED
|
@@ -186,8 +186,8 @@ export const updateAssistant = (
|
|
|
186
186
|
return request.patch(endpoints.assistants(assistant_id), data);
|
|
187
187
|
};
|
|
188
188
|
|
|
189
|
-
export const deleteAssistant = (assistant_id: string): Promise<void> => {
|
|
190
|
-
return request.delete(endpoints.assistants(assistant_id));
|
|
189
|
+
export const deleteAssistant = (assistant_id: string, model: string): Promise<void> => {
|
|
190
|
+
return request.delete(endpoints.assistants(assistant_id, { model }));
|
|
191
191
|
};
|
|
192
192
|
|
|
193
193
|
export const listAssistants = (
|
|
@@ -225,7 +225,10 @@ export const uploadAvatar = (data: FormData): Promise<f.AvatarUploadResponse> =>
|
|
|
225
225
|
};
|
|
226
226
|
|
|
227
227
|
export const uploadAssistantAvatar = (data: m.AssistantAvatarVariables): Promise<a.Assistant> => {
|
|
228
|
-
return request.postMultiPart(
|
|
228
|
+
return request.postMultiPart(
|
|
229
|
+
endpoints.assistants(`avatar/${data.assistant_id}`, { model: data.model }),
|
|
230
|
+
data.formData,
|
|
231
|
+
);
|
|
229
232
|
};
|
|
230
233
|
|
|
231
234
|
export const updateAction = (data: m.UpdateActionVariables): Promise<m.UpdateActionResponse> => {
|
package/src/schemas.ts
CHANGED
package/src/types/mutations.ts
CHANGED
|
@@ -46,6 +46,7 @@ export type LogoutOptions = {
|
|
|
46
46
|
|
|
47
47
|
export type AssistantAvatarVariables = {
|
|
48
48
|
assistant_id: string;
|
|
49
|
+
model: string;
|
|
49
50
|
formData: FormData;
|
|
50
51
|
postCreation?: boolean;
|
|
51
52
|
};
|
|
@@ -86,6 +87,8 @@ export type UpdateAssistantMutationOptions = {
|
|
|
86
87
|
) => void;
|
|
87
88
|
};
|
|
88
89
|
|
|
90
|
+
export type DeleteAssistantBody = { assistant_id: string; model: string };
|
|
91
|
+
|
|
89
92
|
export type DeleteAssistantMutationOptions = {
|
|
90
93
|
onSuccess?: (data: void, variables: { assistant_id: string }, context?: unknown) => void;
|
|
91
94
|
onMutate?: (variables: { assistant_id: string }) => void | Promise<unknown>;
|
package/src/types.ts
CHANGED
|
@@ -146,6 +146,8 @@ export type TConfig = {
|
|
|
146
146
|
userProvide?: boolean | null;
|
|
147
147
|
userProvideURL?: boolean | null;
|
|
148
148
|
disableBuilder?: boolean;
|
|
149
|
+
retrievalModels?: string[];
|
|
150
|
+
capabilities?: string[];
|
|
149
151
|
};
|
|
150
152
|
|
|
151
153
|
export type TEndpointsConfig =
|
|
@@ -193,9 +195,21 @@ export type TResetPassword = {
|
|
|
193
195
|
confirm_password?: string;
|
|
194
196
|
};
|
|
195
197
|
|
|
198
|
+
export type TInterfaceConfig = {
|
|
199
|
+
privacyPolicy?: {
|
|
200
|
+
externalUrl?: string;
|
|
201
|
+
openNewTab?: boolean;
|
|
202
|
+
};
|
|
203
|
+
termsOfService?: {
|
|
204
|
+
externalUrl?: string;
|
|
205
|
+
openNewTab?: boolean;
|
|
206
|
+
};
|
|
207
|
+
};
|
|
208
|
+
|
|
196
209
|
export type TStartupConfig = {
|
|
197
210
|
appTitle: string;
|
|
198
211
|
socialLogins?: string[];
|
|
212
|
+
interface?: TInterfaceConfig;
|
|
199
213
|
discordLoginEnabled: boolean;
|
|
200
214
|
facebookLoginEnabled: boolean;
|
|
201
215
|
githubLoginEnabled: boolean;
|