librechat-data-provider 0.7.82 → 0.7.85
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 +3 -1
- package/specs/bedrock.spec.ts +114 -0
- package/specs/mcp.spec.ts +101 -1
- package/specs/web.spec.ts +903 -0
- package/src/api-endpoints.ts +2 -0
- package/src/bedrock.ts +4 -1
- package/src/config.ts +96 -4
- package/src/data-service.ts +8 -0
- package/src/file-config.ts +6 -0
- package/src/generate.ts +6 -5
- package/src/index.ts +4 -0
- package/src/keys.ts +1 -0
- package/src/mcp.ts +29 -4
- package/src/parameterSettings.ts +726 -0
- package/src/permissions.ts +10 -0
- package/src/roles.ts +8 -0
- package/src/schemas.ts +12 -2
- package/src/types/assistants.ts +2 -0
- package/src/types/files.ts +1 -0
- package/src/types/mutations.ts +21 -1
- package/src/types/queries.ts +5 -1
- package/src/types/web.ts +593 -0
- package/src/types.ts +8 -2
- package/src/utils.ts +10 -0
- package/src/web.ts +271 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "librechat-data-provider",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.85",
|
|
4
4
|
"description": "data services for librechat apps",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.es.js",
|
|
@@ -48,6 +48,7 @@
|
|
|
48
48
|
"@babel/preset-env": "^7.21.5",
|
|
49
49
|
"@babel/preset-react": "^7.18.6",
|
|
50
50
|
"@babel/preset-typescript": "^7.21.0",
|
|
51
|
+
"@langchain/core": "^0.3.57",
|
|
51
52
|
"@rollup/plugin-alias": "^5.1.0",
|
|
52
53
|
"@rollup/plugin-commonjs": "^25.0.2",
|
|
53
54
|
"@rollup/plugin-json": "^6.1.0",
|
|
@@ -58,6 +59,7 @@
|
|
|
58
59
|
"@types/js-yaml": "^4.0.9",
|
|
59
60
|
"@types/node": "^20.3.0",
|
|
60
61
|
"@types/react": "^18.2.18",
|
|
62
|
+
"@types/winston": "^2.4.4",
|
|
61
63
|
"jest": "^29.5.0",
|
|
62
64
|
"jest-junit": "^16.0.0",
|
|
63
65
|
"openai": "^4.76.3",
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { bedrockInputParser } from '../src/bedrock';
|
|
2
|
+
import type { BedrockConverseInput } from '../src/bedrock';
|
|
3
|
+
|
|
4
|
+
describe('bedrockInputParser', () => {
|
|
5
|
+
describe('Model Matching for Reasoning Configuration', () => {
|
|
6
|
+
test('should match anthropic.claude-3-7-sonnet model', () => {
|
|
7
|
+
const input = {
|
|
8
|
+
model: 'anthropic.claude-3-7-sonnet',
|
|
9
|
+
};
|
|
10
|
+
const result = bedrockInputParser.parse(input) as BedrockConverseInput;
|
|
11
|
+
const additionalFields = result.additionalModelRequestFields as Record<string, unknown>;
|
|
12
|
+
expect(additionalFields.thinking).toBe(true);
|
|
13
|
+
expect(additionalFields.thinkingBudget).toBe(2000);
|
|
14
|
+
expect(additionalFields.anthropic_beta).toEqual(['output-128k-2025-02-19']);
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
test('should match anthropic.claude-sonnet-4 model', () => {
|
|
18
|
+
const input = {
|
|
19
|
+
model: 'anthropic.claude-sonnet-4',
|
|
20
|
+
};
|
|
21
|
+
const result = bedrockInputParser.parse(input) as BedrockConverseInput;
|
|
22
|
+
const additionalFields = result.additionalModelRequestFields as Record<string, unknown>;
|
|
23
|
+
expect(additionalFields.thinking).toBe(true);
|
|
24
|
+
expect(additionalFields.thinkingBudget).toBe(2000);
|
|
25
|
+
expect(additionalFields.anthropic_beta).toEqual(['output-128k-2025-02-19']);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
test('should match anthropic.claude-opus-5 model', () => {
|
|
29
|
+
const input = {
|
|
30
|
+
model: 'anthropic.claude-opus-5',
|
|
31
|
+
};
|
|
32
|
+
const result = bedrockInputParser.parse(input) as BedrockConverseInput;
|
|
33
|
+
const additionalFields = result.additionalModelRequestFields as Record<string, unknown>;
|
|
34
|
+
expect(additionalFields.thinking).toBe(true);
|
|
35
|
+
expect(additionalFields.thinkingBudget).toBe(2000);
|
|
36
|
+
expect(additionalFields.anthropic_beta).toEqual(['output-128k-2025-02-19']);
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
test('should match anthropic.claude-haiku-6 model', () => {
|
|
40
|
+
const input = {
|
|
41
|
+
model: 'anthropic.claude-haiku-6',
|
|
42
|
+
};
|
|
43
|
+
const result = bedrockInputParser.parse(input) as BedrockConverseInput;
|
|
44
|
+
const additionalFields = result.additionalModelRequestFields as Record<string, unknown>;
|
|
45
|
+
expect(additionalFields.thinking).toBe(true);
|
|
46
|
+
expect(additionalFields.thinkingBudget).toBe(2000);
|
|
47
|
+
expect(additionalFields.anthropic_beta).toEqual(['output-128k-2025-02-19']);
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
test('should match anthropic.claude-4-sonnet model', () => {
|
|
51
|
+
const input = {
|
|
52
|
+
model: 'anthropic.claude-4-sonnet',
|
|
53
|
+
};
|
|
54
|
+
const result = bedrockInputParser.parse(input) as BedrockConverseInput;
|
|
55
|
+
const additionalFields = result.additionalModelRequestFields as Record<string, unknown>;
|
|
56
|
+
expect(additionalFields.thinking).toBe(true);
|
|
57
|
+
expect(additionalFields.thinkingBudget).toBe(2000);
|
|
58
|
+
expect(additionalFields.anthropic_beta).toEqual(['output-128k-2025-02-19']);
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
test('should match anthropic.claude-4.5-sonnet model', () => {
|
|
62
|
+
const input = {
|
|
63
|
+
model: 'anthropic.claude-4.5-sonnet',
|
|
64
|
+
};
|
|
65
|
+
const result = bedrockInputParser.parse(input) as BedrockConverseInput;
|
|
66
|
+
const additionalFields = result.additionalModelRequestFields as Record<string, unknown>;
|
|
67
|
+
expect(additionalFields.thinking).toBe(true);
|
|
68
|
+
expect(additionalFields.thinkingBudget).toBe(2000);
|
|
69
|
+
expect(additionalFields.anthropic_beta).toEqual(['output-128k-2025-02-19']);
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
test('should match anthropic.claude-4-7-sonnet model', () => {
|
|
73
|
+
const input = {
|
|
74
|
+
model: 'anthropic.claude-4-7-sonnet',
|
|
75
|
+
};
|
|
76
|
+
const result = bedrockInputParser.parse(input) as BedrockConverseInput;
|
|
77
|
+
const additionalFields = result.additionalModelRequestFields as Record<string, unknown>;
|
|
78
|
+
expect(additionalFields.thinking).toBe(true);
|
|
79
|
+
expect(additionalFields.thinkingBudget).toBe(2000);
|
|
80
|
+
expect(additionalFields.anthropic_beta).toEqual(['output-128k-2025-02-19']);
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
test('should not match non-Claude models', () => {
|
|
84
|
+
const input = {
|
|
85
|
+
model: 'some-other-model',
|
|
86
|
+
};
|
|
87
|
+
const result = bedrockInputParser.parse(input) as BedrockConverseInput;
|
|
88
|
+
expect(result.additionalModelRequestFields).toBeUndefined();
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
test('should respect explicit thinking configuration', () => {
|
|
92
|
+
const input = {
|
|
93
|
+
model: 'anthropic.claude-sonnet-4',
|
|
94
|
+
thinking: false,
|
|
95
|
+
};
|
|
96
|
+
const result = bedrockInputParser.parse(input) as BedrockConverseInput;
|
|
97
|
+
const additionalFields = result.additionalModelRequestFields as Record<string, unknown>;
|
|
98
|
+
expect(additionalFields.thinking).toBeUndefined();
|
|
99
|
+
expect(additionalFields.thinkingBudget).toBeUndefined();
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
test('should respect custom thinking budget', () => {
|
|
103
|
+
const input = {
|
|
104
|
+
model: 'anthropic.claude-sonnet-4',
|
|
105
|
+
thinking: true,
|
|
106
|
+
thinkingBudget: 3000,
|
|
107
|
+
};
|
|
108
|
+
const result = bedrockInputParser.parse(input) as BedrockConverseInput;
|
|
109
|
+
const additionalFields = result.additionalModelRequestFields as Record<string, unknown>;
|
|
110
|
+
expect(additionalFields.thinking).toBe(true);
|
|
111
|
+
expect(additionalFields.thinkingBudget).toBe(3000);
|
|
112
|
+
});
|
|
113
|
+
});
|
|
114
|
+
});
|
package/specs/mcp.spec.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { StdioOptionsSchema, processMCPEnv, MCPOptions } from '../src/mcp';
|
|
1
|
+
import { StdioOptionsSchema, StreamableHTTPOptionsSchema, processMCPEnv, MCPOptions } from '../src/mcp';
|
|
2
2
|
|
|
3
3
|
describe('Environment Variable Extraction (MCP)', () => {
|
|
4
4
|
const originalEnv = process.env;
|
|
@@ -50,6 +50,74 @@ describe('Environment Variable Extraction (MCP)', () => {
|
|
|
50
50
|
});
|
|
51
51
|
});
|
|
52
52
|
|
|
53
|
+
describe('StreamableHTTPOptionsSchema', () => {
|
|
54
|
+
it('should validate a valid streamable-http configuration', () => {
|
|
55
|
+
const options = {
|
|
56
|
+
type: 'streamable-http',
|
|
57
|
+
url: 'https://example.com/api',
|
|
58
|
+
headers: {
|
|
59
|
+
Authorization: 'Bearer token',
|
|
60
|
+
'Content-Type': 'application/json',
|
|
61
|
+
},
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
const result = StreamableHTTPOptionsSchema.parse(options);
|
|
65
|
+
|
|
66
|
+
expect(result).toEqual(options);
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
it('should reject websocket URLs', () => {
|
|
70
|
+
const options = {
|
|
71
|
+
type: 'streamable-http',
|
|
72
|
+
url: 'ws://example.com/socket',
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
expect(() => StreamableHTTPOptionsSchema.parse(options)).toThrow();
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
it('should reject secure websocket URLs', () => {
|
|
79
|
+
const options = {
|
|
80
|
+
type: 'streamable-http',
|
|
81
|
+
url: 'wss://example.com/socket',
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
expect(() => StreamableHTTPOptionsSchema.parse(options)).toThrow();
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
it('should require type field to be set explicitly', () => {
|
|
88
|
+
const options = {
|
|
89
|
+
url: 'https://example.com/api',
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
// Type is now required, so parsing should fail
|
|
93
|
+
expect(() => StreamableHTTPOptionsSchema.parse(options)).toThrow();
|
|
94
|
+
|
|
95
|
+
// With type provided, it should pass
|
|
96
|
+
const validOptions = {
|
|
97
|
+
type: 'streamable-http' as const,
|
|
98
|
+
url: 'https://example.com/api',
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
const result = StreamableHTTPOptionsSchema.parse(validOptions);
|
|
102
|
+
expect(result.type).toBe('streamable-http');
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
it('should validate headers as record of strings', () => {
|
|
106
|
+
const options = {
|
|
107
|
+
type: 'streamable-http',
|
|
108
|
+
url: 'https://example.com/api',
|
|
109
|
+
headers: {
|
|
110
|
+
'X-API-Key': '123456',
|
|
111
|
+
'User-Agent': 'MCP Client',
|
|
112
|
+
},
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
const result = StreamableHTTPOptionsSchema.parse(options);
|
|
116
|
+
|
|
117
|
+
expect(result.headers).toEqual(options.headers);
|
|
118
|
+
});
|
|
119
|
+
});
|
|
120
|
+
|
|
53
121
|
describe('processMCPEnv', () => {
|
|
54
122
|
it('should create a deep clone of the input object', () => {
|
|
55
123
|
const originalObj: MCPOptions = {
|
|
@@ -173,5 +241,37 @@ describe('Environment Variable Extraction (MCP)', () => {
|
|
|
173
241
|
// Second user's config should be unchanged
|
|
174
242
|
expect('headers' in resultUser2 && resultUser2.headers?.['User-Id']).toBe(user2Id);
|
|
175
243
|
});
|
|
244
|
+
|
|
245
|
+
it('should process headers in streamable-http options', () => {
|
|
246
|
+
const userId = 'test-user-123';
|
|
247
|
+
const obj: MCPOptions = {
|
|
248
|
+
type: 'streamable-http',
|
|
249
|
+
url: 'https://example.com',
|
|
250
|
+
headers: {
|
|
251
|
+
Authorization: '${TEST_API_KEY}',
|
|
252
|
+
'User-Id': '{{LIBRECHAT_USER_ID}}',
|
|
253
|
+
'Content-Type': 'application/json',
|
|
254
|
+
},
|
|
255
|
+
};
|
|
256
|
+
|
|
257
|
+
const result = processMCPEnv(obj, userId);
|
|
258
|
+
|
|
259
|
+
expect('headers' in result && result.headers).toEqual({
|
|
260
|
+
Authorization: 'test-api-key-value',
|
|
261
|
+
'User-Id': 'test-user-123',
|
|
262
|
+
'Content-Type': 'application/json',
|
|
263
|
+
});
|
|
264
|
+
});
|
|
265
|
+
|
|
266
|
+
it('should maintain streamable-http type in processed options', () => {
|
|
267
|
+
const obj: MCPOptions = {
|
|
268
|
+
type: 'streamable-http',
|
|
269
|
+
url: 'https://example.com/api',
|
|
270
|
+
};
|
|
271
|
+
|
|
272
|
+
const result = processMCPEnv(obj);
|
|
273
|
+
|
|
274
|
+
expect(result.type).toBe('streamable-http');
|
|
275
|
+
});
|
|
176
276
|
});
|
|
177
277
|
});
|