librechat-data-provider 0.7.4 → 0.7.7

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 (49) hide show
  1. package/check_updates.sh +1 -0
  2. package/dist/index.es.js +1 -1
  3. package/dist/index.es.js.map +1 -1
  4. package/dist/index.js +1 -1
  5. package/dist/index.js.map +1 -1
  6. package/dist/react-query/index.es.js +1 -1
  7. package/dist/react-query/index.es.js.map +1 -1
  8. package/dist/react-query/package.json +1 -1
  9. package/package.json +6 -6
  10. package/react-query/package.json +1 -1
  11. package/server-rollup.config.js +3 -3
  12. package/specs/actions.spec.ts +700 -36
  13. package/specs/azure.spec.ts +8 -5
  14. package/specs/filetypes.spec.ts +1 -7
  15. package/specs/mcp.spec.ts +52 -0
  16. package/specs/openapiSpecs.ts +127 -0
  17. package/specs/utils.spec.ts +129 -0
  18. package/src/actions.ts +311 -101
  19. package/src/api-endpoints.ts +70 -13
  20. package/src/artifacts.ts +3104 -0
  21. package/src/azure.ts +40 -33
  22. package/src/bedrock.ts +227 -0
  23. package/src/config.ts +344 -78
  24. package/src/createPayload.ts +3 -1
  25. package/src/data-service.ts +353 -90
  26. package/src/file-config.ts +13 -2
  27. package/src/generate.ts +31 -2
  28. package/src/index.ts +12 -4
  29. package/src/keys.ts +17 -0
  30. package/src/mcp.ts +87 -0
  31. package/src/models.ts +1 -1
  32. package/src/parsers.ts +118 -60
  33. package/src/react-query/react-query-service.ts +54 -115
  34. package/src/request.ts +31 -7
  35. package/src/roles.ts +91 -2
  36. package/src/schemas.ts +513 -340
  37. package/src/types/agents.ts +276 -0
  38. package/src/types/assistants.ts +181 -27
  39. package/src/types/files.ts +6 -0
  40. package/src/types/mutations.ts +170 -7
  41. package/src/types/queries.ts +43 -21
  42. package/src/types/runs.ts +23 -0
  43. package/src/types.ts +132 -67
  44. package/src/utils.ts +44 -0
  45. package/src/zod.spec.ts +526 -0
  46. package/src/zod.ts +86 -0
  47. package/tsconfig.json +1 -2
  48. package/specs/parsers.spec.ts +0 -48
  49. package/src/sse.js +0 -242
@@ -94,8 +94,8 @@ describe('validateAzureGroups', () => {
94
94
  expect(isValid).toBe(true);
95
95
  const modelGroup = modelGroupMap['gpt-5-turbo'];
96
96
  expect(modelGroup).toBeDefined();
97
- expect(modelGroup.group).toBe('japan-east');
98
- expect(groupMap[modelGroup.group]).toBeDefined();
97
+ expect(modelGroup?.group).toBe('japan-east');
98
+ expect(groupMap[modelGroup?.group ?? '']).toBeDefined();
99
99
  expect(modelNames).toContain('gpt-5-turbo');
100
100
  const { azureOptions } = mapModelToAzureConfig({
101
101
  modelName: 'gpt-5-turbo',
@@ -323,6 +323,7 @@ describe('validateAzureGroups for Serverless Configurations', () => {
323
323
 
324
324
  expect(azureOptions).toEqual({
325
325
  azureOpenAIApiKey: 'def456',
326
+ azureOpenAIApiVersion: '',
326
327
  });
327
328
  expect(baseURL).toEqual('https://new-serverless.example.com/v1/completions');
328
329
  expect(serverless).toBe(true);
@@ -381,10 +382,10 @@ describe('validateAzureGroups with modelGroupMap and groupMap', () => {
381
382
  const { isValid, modelGroupMap, groupMap } = validateAzureGroups(validConfigs);
382
383
  expect(isValid).toBe(true);
383
384
  expect(modelGroupMap['gpt-4-turbo']).toBeDefined();
384
- expect(modelGroupMap['gpt-4-turbo'].group).toBe('us-east');
385
+ expect(modelGroupMap['gpt-4-turbo']?.group).toBe('us-east');
385
386
  expect(groupMap['us-east']).toBeDefined();
386
- expect(groupMap['us-east'].apiKey).toBe('prod-1234');
387
- expect(groupMap['us-east'].models['gpt-4-turbo']).toBeDefined();
387
+ expect(groupMap['us-east']?.apiKey).toBe('prod-1234');
388
+ expect(groupMap['us-east']?.models['gpt-4-turbo']).toBeDefined();
388
389
  const { azureOptions, baseURL, headers } = mapModelToAzureConfig({
389
390
  modelName: 'gpt-4-turbo',
390
391
  modelGroupMap,
@@ -765,6 +766,7 @@ describe('validateAzureGroups with modelGroupMap and groupMap', () => {
765
766
  );
766
767
  expect(azureOptions7).toEqual({
767
768
  azureOpenAIApiKey: 'mistral-key',
769
+ azureOpenAIApiVersion: '',
768
770
  });
769
771
 
770
772
  const {
@@ -782,6 +784,7 @@ describe('validateAzureGroups with modelGroupMap and groupMap', () => {
782
784
  );
783
785
  expect(azureOptions8).toEqual({
784
786
  azureOpenAIApiKey: 'llama-key',
787
+ azureOpenAIApiVersion: '',
785
788
  });
786
789
  });
787
790
  });
@@ -14,13 +14,7 @@ import {
14
14
  } from '../src/file-config';
15
15
 
16
16
  describe('MIME Type Regex Patterns', () => {
17
- const unsupportedMimeTypes = [
18
- 'text/x-unknown',
19
- 'application/unknown',
20
- 'image/bmp',
21
- 'image/svg',
22
- 'audio/mp3',
23
- ];
17
+ const unsupportedMimeTypes = ['text/x-unknown', 'application/unknown', 'image/bmp', 'audio/mp3'];
24
18
 
25
19
  // Testing general supported MIME types
26
20
  fullMimeTypesList.forEach((mimeType) => {
@@ -0,0 +1,52 @@
1
+ import { StdioOptionsSchema } from '../src/mcp';
2
+
3
+ describe('Environment Variable Extraction (MCP)', () => {
4
+ const originalEnv = process.env;
5
+
6
+ beforeEach(() => {
7
+ process.env = {
8
+ ...originalEnv,
9
+ TEST_API_KEY: 'test-api-key-value',
10
+ ANOTHER_SECRET: 'another-secret-value',
11
+ };
12
+ });
13
+
14
+ afterEach(() => {
15
+ process.env = originalEnv;
16
+ });
17
+
18
+ describe('StdioOptionsSchema', () => {
19
+ it('should transform environment variables in the env field', () => {
20
+ const options = {
21
+ command: 'node',
22
+ args: ['server.js'],
23
+ env: {
24
+ API_KEY: '${TEST_API_KEY}',
25
+ ANOTHER_KEY: '${ANOTHER_SECRET}',
26
+ PLAIN_VALUE: 'plain-value',
27
+ NON_EXISTENT: '${NON_EXISTENT_VAR}',
28
+ },
29
+ };
30
+
31
+ const result = StdioOptionsSchema.parse(options);
32
+
33
+ expect(result.env).toEqual({
34
+ API_KEY: 'test-api-key-value',
35
+ ANOTHER_KEY: 'another-secret-value',
36
+ PLAIN_VALUE: 'plain-value',
37
+ NON_EXISTENT: '${NON_EXISTENT_VAR}',
38
+ });
39
+ });
40
+
41
+ it('should handle undefined env field', () => {
42
+ const options = {
43
+ command: 'node',
44
+ args: ['server.js'],
45
+ };
46
+
47
+ const result = StdioOptionsSchema.parse(options);
48
+
49
+ expect(result.env).toBeUndefined();
50
+ });
51
+ });
52
+ });
@@ -348,3 +348,130 @@ components:
348
348
  message:
349
349
  type: string
350
350
  description: Confirmation of successful save or error message.`;
351
+
352
+ export const swapidev = `
353
+ openapi: 3.0.3
354
+ info:
355
+ title: Star Wars API
356
+ description: This is a simple API that provides information about the Star Wars universe.
357
+ version: 1.0.0
358
+ servers:
359
+ - url: https://swapi.dev
360
+
361
+ paths:
362
+ /api/people:
363
+ get:
364
+ summary: List all people
365
+ operationId: getPeople
366
+ tags:
367
+ - People
368
+ responses:
369
+ '200':
370
+ description: A list of people
371
+ content:
372
+ application/json:
373
+ schema:
374
+ type: object
375
+ properties:
376
+ count:
377
+ type: integer
378
+ example: 82
379
+ next:
380
+ type: string
381
+ nullable: true
382
+ example: https://swapi.dev/api/people/?page=2
383
+ previous:
384
+ type: string
385
+ nullable: true
386
+ example: null
387
+ results:
388
+ type: array
389
+ items:
390
+ $ref: '#/components/schemas/Person'
391
+
392
+ /api/people/{id}:
393
+ get:
394
+ summary: Get a person by ID
395
+ operationId: getPersonById
396
+ tags:
397
+ - People
398
+ parameters:
399
+ - name: id
400
+ in: path
401
+ required: true
402
+ description: The ID of the person to retrieve
403
+ schema:
404
+ type: string
405
+ responses:
406
+ '200':
407
+ description: A single person
408
+ content:
409
+ application/json:
410
+ schema:
411
+ $ref: '#/components/schemas/Person'
412
+ '404':
413
+ description: Person not found
414
+
415
+ components:
416
+ schemas:
417
+ Person:
418
+ type: object
419
+ properties:
420
+ name:
421
+ type: string
422
+ example: Luke Skywalker
423
+ height:
424
+ type: string
425
+ example: "172"
426
+ mass:
427
+ type: string
428
+ example: "77"
429
+ hair_color:
430
+ type: string
431
+ example: blond
432
+ skin_color:
433
+ type: string
434
+ example: fair
435
+ eye_color:
436
+ type: string
437
+ example: blue
438
+ birth_year:
439
+ type: string
440
+ example: "19BBY"
441
+ gender:
442
+ type: string
443
+ example: male
444
+ homeworld:
445
+ type: string
446
+ example: https://swapi.dev/api/planets/1/
447
+ films:
448
+ type: array
449
+ items:
450
+ type: string
451
+ example: https://swapi.dev/api/films/1/
452
+ species:
453
+ type: array
454
+ items:
455
+ type: string
456
+ example: https://swapi.dev/api/species/1/
457
+ vehicles:
458
+ type: array
459
+ items:
460
+ type: string
461
+ example: https://swapi.dev/api/vehicles/14/
462
+ starships:
463
+ type: array
464
+ items:
465
+ type: string
466
+ example: https://swapi.dev/api/starships/12/
467
+ created:
468
+ type: string
469
+ format: date-time
470
+ example: 2014-12-09T13:50:51.644000Z
471
+ edited:
472
+ type: string
473
+ format: date-time
474
+ example: 2014-12-20T21:17:56.891000Z
475
+ url:
476
+ type: string
477
+ example: https://swapi.dev/api/people/1/`;
@@ -0,0 +1,129 @@
1
+ import { extractEnvVariable } from '../src/utils';
2
+
3
+ describe('Environment Variable Extraction', () => {
4
+ const originalEnv = process.env;
5
+
6
+ beforeEach(() => {
7
+ process.env = {
8
+ ...originalEnv,
9
+ TEST_API_KEY: 'test-api-key-value',
10
+ ANOTHER_SECRET: 'another-secret-value',
11
+ };
12
+ });
13
+
14
+ afterEach(() => {
15
+ process.env = originalEnv;
16
+ });
17
+
18
+ describe('extractEnvVariable (original tests)', () => {
19
+ test('should return the value of the environment variable', () => {
20
+ process.env.TEST_VAR = 'test_value';
21
+ expect(extractEnvVariable('${TEST_VAR}')).toBe('test_value');
22
+ });
23
+
24
+ test('should return the original string if the envrionment variable is not defined correctly', () => {
25
+ process.env.TEST_VAR = 'test_value';
26
+ expect(extractEnvVariable('${ TEST_VAR }')).toBe('${ TEST_VAR }');
27
+ });
28
+
29
+ test('should return the original string if environment variable is not set', () => {
30
+ expect(extractEnvVariable('${NON_EXISTENT_VAR}')).toBe('${NON_EXISTENT_VAR}');
31
+ });
32
+
33
+ test('should return the original string if it does not contain an environment variable', () => {
34
+ expect(extractEnvVariable('some_string')).toBe('some_string');
35
+ });
36
+
37
+ test('should handle empty strings', () => {
38
+ expect(extractEnvVariable('')).toBe('');
39
+ });
40
+
41
+ test('should handle strings without variable format', () => {
42
+ expect(extractEnvVariable('no_var_here')).toBe('no_var_here');
43
+ });
44
+
45
+ /** No longer the expected behavior; keeping for reference */
46
+ test.skip('should not process multiple variable formats', () => {
47
+ process.env.FIRST_VAR = 'first';
48
+ process.env.SECOND_VAR = 'second';
49
+ expect(extractEnvVariable('${FIRST_VAR} and ${SECOND_VAR}')).toBe(
50
+ '${FIRST_VAR} and ${SECOND_VAR}',
51
+ );
52
+ });
53
+ });
54
+
55
+ describe('extractEnvVariable function', () => {
56
+ it('should extract environment variables from exact matches', () => {
57
+ expect(extractEnvVariable('${TEST_API_KEY}')).toBe('test-api-key-value');
58
+ expect(extractEnvVariable('${ANOTHER_SECRET}')).toBe('another-secret-value');
59
+ });
60
+
61
+ it('should extract environment variables from strings with prefixes', () => {
62
+ expect(extractEnvVariable('prefix-${TEST_API_KEY}')).toBe('prefix-test-api-key-value');
63
+ });
64
+
65
+ it('should extract environment variables from strings with suffixes', () => {
66
+ expect(extractEnvVariable('${TEST_API_KEY}-suffix')).toBe('test-api-key-value-suffix');
67
+ });
68
+
69
+ it('should extract environment variables from strings with both prefixes and suffixes', () => {
70
+ expect(extractEnvVariable('prefix-${TEST_API_KEY}-suffix')).toBe(
71
+ 'prefix-test-api-key-value-suffix',
72
+ );
73
+ });
74
+
75
+ it('should not match invalid patterns', () => {
76
+ expect(extractEnvVariable('$TEST_API_KEY')).toBe('$TEST_API_KEY');
77
+ expect(extractEnvVariable('{TEST_API_KEY}')).toBe('{TEST_API_KEY}');
78
+ expect(extractEnvVariable('TEST_API_KEY')).toBe('TEST_API_KEY');
79
+ });
80
+ });
81
+
82
+ describe('extractEnvVariable', () => {
83
+ it('should extract environment variable values', () => {
84
+ expect(extractEnvVariable('${TEST_API_KEY}')).toBe('test-api-key-value');
85
+ expect(extractEnvVariable('${ANOTHER_SECRET}')).toBe('another-secret-value');
86
+ });
87
+
88
+ it('should return the original string if environment variable is not found', () => {
89
+ expect(extractEnvVariable('${NON_EXISTENT_VAR}')).toBe('${NON_EXISTENT_VAR}');
90
+ });
91
+
92
+ it('should return the original string if no environment variable pattern is found', () => {
93
+ expect(extractEnvVariable('plain-string')).toBe('plain-string');
94
+ });
95
+ });
96
+
97
+ describe('extractEnvVariable space trimming', () => {
98
+ beforeEach(() => {
99
+ process.env.HELLO = 'world';
100
+ process.env.USER = 'testuser';
101
+ });
102
+
103
+ it('should extract the value when string contains only an environment variable with surrounding whitespace', () => {
104
+ expect(extractEnvVariable(' ${HELLO} ')).toBe('world');
105
+ expect(extractEnvVariable(' ${HELLO} ')).toBe('world');
106
+ expect(extractEnvVariable('\t${HELLO}\n')).toBe('world');
107
+ });
108
+
109
+ it('should preserve content when variable is part of a larger string', () => {
110
+ expect(extractEnvVariable('Hello ${USER}!')).toBe('Hello testuser!');
111
+ expect(extractEnvVariable(' Hello ${USER}! ')).toBe('Hello testuser!');
112
+ });
113
+
114
+ it('should not handle multiple variables', () => {
115
+ expect(extractEnvVariable('${HELLO} ${USER}')).toBe('${HELLO} ${USER}');
116
+ expect(extractEnvVariable(' ${HELLO} ${USER} ')).toBe('${HELLO} ${USER}');
117
+ });
118
+
119
+ it('should handle undefined variables', () => {
120
+ expect(extractEnvVariable(' ${UNDEFINED_VAR} ')).toBe('${UNDEFINED_VAR}');
121
+ });
122
+
123
+ it('should handle mixed content correctly', () => {
124
+ expect(extractEnvVariable('Welcome, ${USER}!\nYour message: ${HELLO}')).toBe(
125
+ 'Welcome, testuser!\nYour message: world',
126
+ );
127
+ });
128
+ });
129
+ });