librechat-data-provider 0.4.7 → 0.4.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.
- 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 +49 -9
- 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}`,
|
|
@@ -469,7 +509,7 @@ export enum Constants {
|
|
|
469
509
|
/**
|
|
470
510
|
* Key for the Custom Config's version (librechat.yaml).
|
|
471
511
|
*/
|
|
472
|
-
CONFIG_VERSION = '1.0.
|
|
512
|
+
CONFIG_VERSION = '1.0.5',
|
|
473
513
|
/**
|
|
474
514
|
* Standard value for the first message's `parentMessageId` value, to indicate no parent exists.
|
|
475
515
|
*/
|
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;
|