librechat-data-provider 0.7.41 → 0.7.52

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/src/parsers.ts CHANGED
@@ -2,23 +2,24 @@ import type { ZodIssue } from 'zod';
2
2
  import type * as a from './types/assistants';
3
3
  import type * as s from './schemas';
4
4
  import type * as t from './types';
5
- import { ContentTypes } from './types/assistants';
5
+ import { ContentTypes } from './types/runs';
6
6
  import {
7
- EModelEndpoint,
8
7
  openAISchema,
9
8
  googleSchema,
10
9
  bingAISchema,
10
+ EModelEndpoint,
11
11
  anthropicSchema,
12
- chatGPTBrowserSchema,
13
- gptPluginsSchema,
14
12
  assistantSchema,
15
- compactOpenAISchema,
13
+ gptPluginsSchema,
14
+ // agentsSchema,
15
+ compactAgentsSchema,
16
16
  compactGoogleSchema,
17
- compactAnthropicSchema,
18
17
  compactChatGPTSchema,
18
+ chatGPTBrowserSchema,
19
19
  compactPluginsSchema,
20
20
  compactAssistantSchema,
21
21
  } from './schemas';
22
+ import { bedrockInputSchema } from './bedrock';
22
23
  import { alternateName } from './config';
23
24
 
24
25
  type EndpointSchema =
@@ -28,7 +29,9 @@ type EndpointSchema =
28
29
  | typeof anthropicSchema
29
30
  | typeof chatGPTBrowserSchema
30
31
  | typeof gptPluginsSchema
31
- | typeof assistantSchema;
32
+ | typeof assistantSchema
33
+ | typeof compactAgentsSchema
34
+ | typeof bedrockInputSchema;
32
35
 
33
36
  const endpointSchemas: Record<EModelEndpoint, EndpointSchema> = {
34
37
  [EModelEndpoint.openAI]: openAISchema,
@@ -41,6 +44,8 @@ const endpointSchemas: Record<EModelEndpoint, EndpointSchema> = {
41
44
  [EModelEndpoint.gptPlugins]: gptPluginsSchema,
42
45
  [EModelEndpoint.assistants]: assistantSchema,
43
46
  [EModelEndpoint.azureAssistants]: assistantSchema,
47
+ [EModelEndpoint.agents]: compactAgentsSchema,
48
+ [EModelEndpoint.bedrock]: bedrockInputSchema,
44
49
  };
45
50
 
46
51
  // const schemaCreators: Record<EModelEndpoint, (customSchema: DefaultSchemaValues) => EndpointSchema> = {
@@ -51,6 +56,7 @@ const endpointSchemas: Record<EModelEndpoint, EndpointSchema> = {
51
56
  export function getEnabledEndpoints() {
52
57
  const defaultEndpoints: string[] = [
53
58
  EModelEndpoint.openAI,
59
+ EModelEndpoint.agents,
54
60
  EModelEndpoint.assistants,
55
61
  EModelEndpoint.azureAssistants,
56
62
  EModelEndpoint.azureOpenAI,
@@ -59,14 +65,15 @@ export function getEnabledEndpoints() {
59
65
  EModelEndpoint.chatGPTBrowser,
60
66
  EModelEndpoint.gptPlugins,
61
67
  EModelEndpoint.anthropic,
68
+ EModelEndpoint.bedrock,
62
69
  ];
63
70
 
64
- const endpointsEnv = process.env.ENDPOINTS || '';
71
+ const endpointsEnv = process.env.ENDPOINTS ?? '';
65
72
  let enabledEndpoints = defaultEndpoints;
66
73
  if (endpointsEnv) {
67
74
  enabledEndpoints = endpointsEnv
68
75
  .split(',')
69
- .filter((endpoint) => endpoint?.trim())
76
+ .filter((endpoint) => endpoint.trim())
70
77
  .map((endpoint) => endpoint.trim());
71
78
  }
72
79
  return enabledEndpoints;
@@ -125,6 +132,7 @@ export const envVarRegex = /^\${(.+)}$/;
125
132
  export function extractEnvVariable(value: string) {
126
133
  const envVarMatch = value.match(envVarRegex);
127
134
  if (envVarMatch) {
135
+ // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
128
136
  return process.env[envVarMatch[1]] || value;
129
137
  }
130
138
  return value;
@@ -154,6 +162,15 @@ export function getFirstDefinedValue(possibleValues: string[]) {
154
162
  return returnValue;
155
163
  }
156
164
 
165
+ export function getNonEmptyValue(possibleValues: string[]) {
166
+ for (const value of possibleValues) {
167
+ if (value && value.trim() !== '') {
168
+ return value;
169
+ }
170
+ }
171
+ return undefined;
172
+ }
173
+
157
174
  export type TPossibleValues = {
158
175
  models: string[];
159
176
  secondaryModels?: string[];
@@ -167,12 +184,12 @@ export const parseConvo = ({
167
184
  }: {
168
185
  endpoint: EModelEndpoint;
169
186
  endpointType?: EModelEndpoint;
170
- conversation: Partial<s.TConversation | s.TPreset>;
187
+ conversation: Partial<s.TConversation | s.TPreset> | null;
171
188
  possibleValues?: TPossibleValues;
172
189
  // TODO: POC for default schema
173
190
  // defaultSchema?: Partial<EndpointSchema>,
174
191
  }) => {
175
- let schema = endpointSchemas[endpoint];
192
+ let schema = endpointSchemas[endpoint] as EndpointSchema | undefined;
176
193
 
177
194
  if (!schema && !endpointType) {
178
195
  throw new Error(`Unknown endpoint: ${endpoint}`);
@@ -184,14 +201,14 @@ export const parseConvo = ({
184
201
  // schema = schemaCreators[endpoint](defaultSchema);
185
202
  // }
186
203
 
187
- const convo = schema.parse(conversation) as s.TConversation;
204
+ const convo = schema?.parse(conversation) as s.TConversation | undefined;
188
205
  const { models, secondaryModels } = possibleValues ?? {};
189
206
 
190
207
  if (models && convo) {
191
208
  convo.model = getFirstDefinedValue(models) ?? convo.model;
192
209
  }
193
210
 
194
- if (secondaryModels && convo.agentOptions) {
211
+ if (secondaryModels && convo?.agentOptions) {
195
212
  convo.agentOptions.model = getFirstDefinedValue(secondaryModels) ?? convo.agentOptions.model;
196
213
  }
197
214
 
@@ -199,35 +216,57 @@ export const parseConvo = ({
199
216
  };
200
217
 
201
218
  export const getResponseSender = (endpointOption: t.TEndpointOption): string => {
202
- const { model, endpoint, endpointType, modelDisplayLabel, chatGptLabel, modelLabel, jailbreak } =
203
- endpointOption;
204
-
219
+ const {
220
+ model: _m,
221
+ endpoint,
222
+ endpointType,
223
+ modelDisplayLabel: _mdl,
224
+ chatGptLabel: _cgl,
225
+ modelLabel: _ml,
226
+ jailbreak,
227
+ } = endpointOption;
228
+
229
+ const model = _m ?? '';
230
+ const modelDisplayLabel = _mdl ?? '';
231
+ const chatGptLabel = _cgl ?? '';
232
+ const modelLabel = _ml ?? '';
205
233
  if (
206
234
  [
207
235
  EModelEndpoint.openAI,
208
- EModelEndpoint.azureOpenAI,
236
+ EModelEndpoint.bedrock,
209
237
  EModelEndpoint.gptPlugins,
238
+ EModelEndpoint.azureOpenAI,
210
239
  EModelEndpoint.chatGPTBrowser,
211
240
  ].includes(endpoint)
212
241
  ) {
213
242
  if (chatGptLabel) {
214
243
  return chatGptLabel;
244
+ } else if (modelLabel) {
245
+ return modelLabel;
246
+ } else if (model && /\bo1\b/i.test(model)) {
247
+ return 'o1';
215
248
  } else if (model && model.includes('gpt-3')) {
216
249
  return 'GPT-3.5';
250
+ } else if (model && model.includes('gpt-4o')) {
251
+ return 'GPT-4o';
217
252
  } else if (model && model.includes('gpt-4')) {
218
253
  return 'GPT-4';
219
254
  } else if (model && model.includes('mistral')) {
220
255
  return 'Mistral';
221
256
  }
222
- return alternateName[endpoint] ?? 'ChatGPT';
257
+ return (alternateName[endpoint] as string | undefined) ?? 'ChatGPT';
223
258
  }
224
259
 
225
260
  if (endpoint === EModelEndpoint.bingAI) {
226
- return jailbreak ? 'Sydney' : 'BingAI';
261
+ return jailbreak === true ? 'Sydney' : 'BingAI';
227
262
  }
228
263
 
229
264
  if (endpoint === EModelEndpoint.anthropic) {
230
- return modelLabel ?? 'Claude';
265
+ return modelLabel || 'Claude';
266
+ }
267
+
268
+ if (endpoint === EModelEndpoint.bedrock) {
269
+ return modelLabel || alternateName[endpoint];
231
270
  }
232
271
 
233
272
  if (endpoint === EModelEndpoint.google) {
@@ -251,6 +290,8 @@ export const getResponseSender = (endpointOption: t.TEndpointOption): string =>
251
290
  return 'Mistral';
252
291
  } else if (model && model.includes('gpt-3')) {
253
292
  return 'GPT-3.5';
293
+ } else if (model && model.includes('gpt-4o')) {
294
+ return 'GPT-4o';
254
295
  } else if (model && model.includes('gpt-4')) {
255
296
  return 'GPT-4';
256
297
  } else if (modelDisplayLabel) {
@@ -264,24 +305,28 @@ export const getResponseSender = (endpointOption: t.TEndpointOption): string =>
264
305
  };
265
306
 
266
307
  type CompactEndpointSchema =
267
- | typeof compactOpenAISchema
308
+ | typeof openAISchema
268
309
  | typeof compactAssistantSchema
310
+ | typeof compactAgentsSchema
269
311
  | typeof compactGoogleSchema
270
312
  | typeof bingAISchema
271
- | typeof compactAnthropicSchema
313
+ | typeof anthropicSchema
272
314
  | typeof compactChatGPTSchema
315
+ | typeof bedrockInputSchema
273
316
  | typeof compactPluginsSchema;
274
317
 
275
318
  const compactEndpointSchemas: Record<string, CompactEndpointSchema> = {
276
- [EModelEndpoint.openAI]: compactOpenAISchema,
277
- [EModelEndpoint.azureOpenAI]: compactOpenAISchema,
278
- [EModelEndpoint.custom]: compactOpenAISchema,
319
+ [EModelEndpoint.openAI]: openAISchema,
320
+ [EModelEndpoint.azureOpenAI]: openAISchema,
321
+ [EModelEndpoint.custom]: openAISchema,
279
322
  [EModelEndpoint.assistants]: compactAssistantSchema,
280
323
  [EModelEndpoint.azureAssistants]: compactAssistantSchema,
324
+ [EModelEndpoint.agents]: compactAgentsSchema,
281
325
  [EModelEndpoint.google]: compactGoogleSchema,
326
+ [EModelEndpoint.bedrock]: bedrockInputSchema,
282
327
  /* BingAI needs all fields */
283
328
  [EModelEndpoint.bingAI]: bingAISchema,
284
- [EModelEndpoint.anthropic]: compactAnthropicSchema,
329
+ [EModelEndpoint.anthropic]: anthropicSchema,
285
330
  [EModelEndpoint.chatGPTBrowser]: compactChatGPTSchema,
286
331
  [EModelEndpoint.gptPlugins]: compactPluginsSchema,
287
332
  };
@@ -331,7 +376,7 @@ export function parseTextParts(contentParts: a.TMessageContentParts[]): string {
331
376
 
332
377
  for (const part of contentParts) {
333
378
  if (part.type === ContentTypes.TEXT) {
334
- const textValue = part.text.value;
379
+ const textValue = typeof part.text === 'string' ? part.text : part.text.value;
335
380
 
336
381
  if (
337
382
  result.length > 0 &&
@@ -347,3 +392,16 @@ export function parseTextParts(contentParts: a.TMessageContentParts[]): string {
347
392
 
348
393
  return result;
349
394
  }
395
+
396
+ export const SEPARATORS = ['.', '?', '!', '۔', '。', '‥', ';', '¡', '¿', '\n', '```'];
397
+
398
+ export function findLastSeparatorIndex(text: string, separators = SEPARATORS): number {
399
+ let lastIndex = -1;
400
+ for (const separator of separators) {
401
+ const index = text.lastIndexOf(separator);
402
+ if (index > lastIndex) {
403
+ lastIndex = index;
404
+ }
405
+ }
406
+ return lastIndex;
407
+ }
@@ -124,6 +124,20 @@ export const useUpdateMessageMutation = (
124
124
  });
125
125
  };
126
126
 
127
+ export const useUpdateMessageContentMutation = (
128
+ conversationId: string,
129
+ ): UseMutationResult<unknown, unknown, t.TUpdateMessageContent, unknown> => {
130
+ const queryClient = useQueryClient();
131
+ return useMutation(
132
+ (payload: t.TUpdateMessageContent) => dataService.updateMessageContent(payload),
133
+ {
134
+ onSuccess: () => {
135
+ queryClient.invalidateQueries([QueryKeys.messages, conversationId]);
136
+ },
137
+ },
138
+ );
139
+ };
140
+
127
141
  export const useUpdateUserKeysMutation = (): UseMutationResult<
128
142
  t.TUser,
129
143
  unknown,
@@ -394,16 +408,16 @@ export const useAvailablePluginsQuery = <TData = s.TPlugin[]>(
394
408
  );
395
409
  };
396
410
 
397
- export const useUpdateUserPluginsMutation = (): UseMutationResult<
398
- t.TUser,
399
- unknown,
400
- t.TUpdateUserPlugins,
401
- unknown
402
- > => {
411
+ export const useUpdateUserPluginsMutation = (
412
+ _options?: m.UpdatePluginAuthOptions,
413
+ ): UseMutationResult<t.TUser, unknown, t.TUpdateUserPlugins, unknown> => {
403
414
  const queryClient = useQueryClient();
415
+ const { onSuccess, ...options } = _options ?? {};
404
416
  return useMutation((payload: t.TUpdateUserPlugins) => dataService.updateUserPlugins(payload), {
405
- onSuccess: () => {
417
+ ...options,
418
+ onSuccess: (...args) => {
406
419
  queryClient.invalidateQueries([QueryKeys.user]);
420
+ onSuccess?.(...args);
407
421
  },
408
422
  });
409
423
  };
@@ -437,3 +451,14 @@ export const useGetCustomConfigSpeechQuery = (
437
451
  },
438
452
  );
439
453
  };
454
+
455
+ export const useGetBannerQuery = (
456
+ config?: UseQueryOptions<t.TBannerResponse>,
457
+ ): QueryObserverResult<t.TBannerResponse> => {
458
+ return useQuery<t.TBannerResponse>([QueryKeys.banner], () => dataService.getBanner(), {
459
+ refetchOnWindowFocus: false,
460
+ refetchOnReconnect: false,
461
+ refetchOnMount: false,
462
+ ...config,
463
+ });
464
+ };
package/src/request.ts CHANGED
@@ -80,6 +80,9 @@ axios.interceptors.response.use(
80
80
  (response) => response,
81
81
  async (error) => {
82
82
  const originalRequest = error.config;
83
+ if (!error.response) {
84
+ return Promise.reject(error);
85
+ }
83
86
 
84
87
  if (error.response.status === 401 && !originalRequest._retry) {
85
88
  originalRequest._retry = true;
package/src/roles.ts CHANGED
@@ -22,6 +22,18 @@ export enum PermissionTypes {
22
22
  * Type for Prompt Permissions
23
23
  */
24
24
  PROMPTS = 'PROMPTS',
25
+ /**
26
+ * Type for Bookmark Permissions
27
+ */
28
+ BOOKMARKS = 'BOOKMARKS',
29
+ /**
30
+ * Type for Agent Permissions
31
+ */
32
+ AGENTS = 'AGENTS',
33
+ /**
34
+ * Type for Multi-Conversation Permissions
35
+ */
36
+ MULTI_CONVO = 'MULTI_CONVO',
25
37
  }
26
38
 
27
39
  /**
@@ -31,6 +43,9 @@ export enum Permissions {
31
43
  SHARED_GLOBAL = 'SHARED_GLOBAL',
32
44
  USE = 'USE',
33
45
  CREATE = 'CREATE',
46
+ UPDATE = 'UPDATE',
47
+ READ = 'READ',
48
+ READ_AUTHOR = 'READ_AUTHOR',
34
49
  SHARE = 'SHARE',
35
50
  }
36
51
 
@@ -38,16 +53,37 @@ export const promptPermissionsSchema = z.object({
38
53
  [Permissions.SHARED_GLOBAL]: z.boolean().default(false),
39
54
  [Permissions.USE]: z.boolean().default(true),
40
55
  [Permissions.CREATE]: z.boolean().default(true),
41
- [Permissions.SHARE]: z.boolean().default(false),
56
+ // [Permissions.SHARE]: z.boolean().default(false),
57
+ });
58
+
59
+ export const bookmarkPermissionsSchema = z.object({
60
+ [Permissions.USE]: z.boolean().default(true),
61
+ });
62
+
63
+ export const agentPermissionsSchema = z.object({
64
+ [Permissions.SHARED_GLOBAL]: z.boolean().default(false),
65
+ [Permissions.USE]: z.boolean().default(true),
66
+ [Permissions.CREATE]: z.boolean().default(true),
67
+ // [Permissions.SHARE]: z.boolean().default(false),
68
+ });
69
+
70
+ export const multiConvoPermissionsSchema = z.object({
71
+ [Permissions.USE]: z.boolean().default(false),
42
72
  });
43
73
 
44
74
  export const roleSchema = z.object({
45
75
  name: z.string(),
46
76
  [PermissionTypes.PROMPTS]: promptPermissionsSchema,
77
+ [PermissionTypes.BOOKMARKS]: bookmarkPermissionsSchema,
78
+ [PermissionTypes.AGENTS]: agentPermissionsSchema,
79
+ [PermissionTypes.MULTI_CONVO]: multiConvoPermissionsSchema,
47
80
  });
48
81
 
49
82
  export type TRole = z.infer<typeof roleSchema>;
83
+ export type TAgentPermissions = z.infer<typeof agentPermissionsSchema>;
50
84
  export type TPromptPermissions = z.infer<typeof promptPermissionsSchema>;
85
+ export type TBookmarkPermissions = z.infer<typeof bookmarkPermissionsSchema>;
86
+ export type TMultiConvoPermissions = z.infer<typeof multiConvoPermissionsSchema>;
51
87
 
52
88
  const defaultRolesSchema = z.object({
53
89
  [SystemRoles.ADMIN]: roleSchema.extend({
@@ -56,12 +92,27 @@ const defaultRolesSchema = z.object({
56
92
  [Permissions.SHARED_GLOBAL]: z.boolean().default(true),
57
93
  [Permissions.USE]: z.boolean().default(true),
58
94
  [Permissions.CREATE]: z.boolean().default(true),
59
- [Permissions.SHARE]: z.boolean().default(true),
95
+ // [Permissions.SHARE]: z.boolean().default(true),
96
+ }),
97
+ [PermissionTypes.BOOKMARKS]: bookmarkPermissionsSchema.extend({
98
+ [Permissions.USE]: z.boolean().default(true),
99
+ }),
100
+ [PermissionTypes.AGENTS]: agentPermissionsSchema.extend({
101
+ [Permissions.SHARED_GLOBAL]: z.boolean().default(true),
102
+ [Permissions.USE]: z.boolean().default(true),
103
+ [Permissions.CREATE]: z.boolean().default(true),
104
+ // [Permissions.SHARE]: z.boolean().default(true),
105
+ }),
106
+ [PermissionTypes.MULTI_CONVO]: multiConvoPermissionsSchema.extend({
107
+ [Permissions.USE]: z.boolean().default(true),
60
108
  }),
61
109
  }),
62
110
  [SystemRoles.USER]: roleSchema.extend({
63
111
  name: z.literal(SystemRoles.USER),
64
112
  [PermissionTypes.PROMPTS]: promptPermissionsSchema,
113
+ [PermissionTypes.BOOKMARKS]: bookmarkPermissionsSchema,
114
+ [PermissionTypes.AGENTS]: agentPermissionsSchema,
115
+ [PermissionTypes.MULTI_CONVO]: multiConvoPermissionsSchema,
65
116
  }),
66
117
  });
67
118
 
@@ -69,9 +120,15 @@ export const roleDefaults = defaultRolesSchema.parse({
69
120
  [SystemRoles.ADMIN]: {
70
121
  name: SystemRoles.ADMIN,
71
122
  [PermissionTypes.PROMPTS]: {},
123
+ [PermissionTypes.BOOKMARKS]: {},
124
+ [PermissionTypes.AGENTS]: {},
125
+ [PermissionTypes.MULTI_CONVO]: {},
72
126
  },
73
127
  [SystemRoles.USER]: {
74
128
  name: SystemRoles.USER,
75
129
  [PermissionTypes.PROMPTS]: {},
130
+ [PermissionTypes.BOOKMARKS]: {},
131
+ [PermissionTypes.AGENTS]: {},
132
+ [PermissionTypes.MULTI_CONVO]: {},
76
133
  },
77
134
  });