librechat-data-provider 0.8.402 → 0.8.404

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 (109) hide show
  1. package/dist/index.es.js +1 -1
  2. package/dist/index.es.js.map +1 -1
  3. package/dist/index.js +1 -1
  4. package/dist/index.js.map +1 -1
  5. package/dist/react-query/index.es.js +1 -1
  6. package/dist/react-query/index.es.js.map +1 -1
  7. package/dist/types/accessPermissions.d.ts +744 -0
  8. package/dist/types/actions.d.ts +118 -0
  9. package/dist/types/api-endpoints.d.ts +150 -0
  10. package/dist/types/artifacts.d.ts +97 -0
  11. package/dist/types/azure.d.ts +22 -0
  12. package/dist/types/bedrock.d.ts +1220 -0
  13. package/dist/types/config.d.ts +14849 -0
  14. package/dist/types/config.spec.d.ts +1 -0
  15. package/dist/types/createPayload.d.ts +5 -0
  16. package/dist/types/data-service.d.ts +287 -0
  17. package/dist/types/feedback.d.ts +36 -0
  18. package/dist/types/file-config.d.ts +263 -0
  19. package/dist/types/file-config.spec.d.ts +1 -0
  20. package/dist/types/generate.d.ts +597 -0
  21. package/dist/types/headers-helpers.d.ts +2 -0
  22. package/{src/index.ts → dist/types/index.d.ts} +0 -15
  23. package/dist/types/keys.d.ts +92 -0
  24. package/dist/types/mcp.d.ts +2760 -0
  25. package/dist/types/messages.d.ts +10 -0
  26. package/dist/types/models.d.ts +1547 -0
  27. package/dist/types/parameterSettings.d.ts +69 -0
  28. package/dist/types/parsers.d.ts +110 -0
  29. package/dist/types/permissions.d.ts +522 -0
  30. package/dist/types/react-query/react-query-service.d.ts +85 -0
  31. package/dist/types/request.d.ts +25 -0
  32. package/dist/types/roles.d.ts +554 -0
  33. package/dist/types/roles.spec.d.ts +1 -0
  34. package/dist/types/schemas.d.ts +5110 -0
  35. package/dist/types/schemas.spec.d.ts +1 -0
  36. package/dist/types/types/agents.d.ts +433 -0
  37. package/dist/types/types/assistants.d.ts +547 -0
  38. package/dist/types/types/files.d.ts +172 -0
  39. package/dist/types/types/graph.d.ts +135 -0
  40. package/{src/types/mcpServers.ts → dist/types/types/mcpServers.d.ts} +12 -18
  41. package/dist/types/types/mutations.d.ts +209 -0
  42. package/dist/types/types/queries.d.ts +169 -0
  43. package/dist/types/types/runs.d.ts +36 -0
  44. package/dist/types/types/web.d.ts +520 -0
  45. package/dist/types/types.d.ts +503 -0
  46. package/dist/types/utils.d.ts +12 -0
  47. package/package.json +5 -1
  48. package/babel.config.js +0 -4
  49. package/check_updates.sh +0 -52
  50. package/jest.config.js +0 -19
  51. package/react-query/package-lock.json +0 -292
  52. package/react-query/package.json +0 -10
  53. package/rollup.config.js +0 -74
  54. package/server-rollup.config.js +0 -40
  55. package/specs/actions.spec.ts +0 -2533
  56. package/specs/api-endpoints-subdir.spec.ts +0 -140
  57. package/specs/api-endpoints.spec.ts +0 -74
  58. package/specs/azure.spec.ts +0 -844
  59. package/specs/bedrock.spec.ts +0 -862
  60. package/specs/filetypes.spec.ts +0 -175
  61. package/specs/generate.spec.ts +0 -770
  62. package/specs/headers-helpers.spec.ts +0 -24
  63. package/specs/mcp.spec.ts +0 -147
  64. package/specs/openapiSpecs.ts +0 -524
  65. package/specs/parsers.spec.ts +0 -601
  66. package/specs/request-interceptor.spec.ts +0 -304
  67. package/specs/utils.spec.ts +0 -196
  68. package/src/accessPermissions.ts +0 -346
  69. package/src/actions.ts +0 -813
  70. package/src/api-endpoints.ts +0 -440
  71. package/src/artifacts.ts +0 -3104
  72. package/src/azure.ts +0 -328
  73. package/src/bedrock.ts +0 -425
  74. package/src/config.spec.ts +0 -315
  75. package/src/config.ts +0 -2006
  76. package/src/createPayload.ts +0 -46
  77. package/src/data-service.ts +0 -1087
  78. package/src/feedback.ts +0 -141
  79. package/src/file-config.spec.ts +0 -1248
  80. package/src/file-config.ts +0 -764
  81. package/src/generate.ts +0 -634
  82. package/src/headers-helpers.ts +0 -13
  83. package/src/keys.ts +0 -99
  84. package/src/mcp.ts +0 -271
  85. package/src/messages.ts +0 -50
  86. package/src/models.ts +0 -69
  87. package/src/parameterSettings.ts +0 -1111
  88. package/src/parsers.ts +0 -563
  89. package/src/permissions.ts +0 -188
  90. package/src/react-query/react-query-service.ts +0 -566
  91. package/src/request.ts +0 -171
  92. package/src/roles.spec.ts +0 -132
  93. package/src/roles.ts +0 -225
  94. package/src/schemas.spec.ts +0 -355
  95. package/src/schemas.ts +0 -1234
  96. package/src/types/agents.ts +0 -470
  97. package/src/types/assistants.ts +0 -654
  98. package/src/types/files.ts +0 -191
  99. package/src/types/graph.ts +0 -145
  100. package/src/types/mutations.ts +0 -422
  101. package/src/types/queries.ts +0 -208
  102. package/src/types/runs.ts +0 -40
  103. package/src/types/web.ts +0 -588
  104. package/src/types.ts +0 -676
  105. package/src/utils.ts +0 -85
  106. package/tsconfig.json +0 -28
  107. package/tsconfig.spec.json +0 -10
  108. /package/{src/react-query/index.ts → dist/types/react-query/index.d.ts} +0 -0
  109. /package/{src/types/index.ts → dist/types/types/index.d.ts} +0 -0
@@ -1,862 +0,0 @@
1
- import {
2
- supportsAdaptiveThinking,
3
- bedrockOutputParser,
4
- bedrockInputParser,
5
- supportsContext1m,
6
- } from '../src/bedrock';
7
-
8
- describe('supportsAdaptiveThinking', () => {
9
- test('should return true for claude-opus-4-6', () => {
10
- expect(supportsAdaptiveThinking('claude-opus-4-6')).toBe(true);
11
- });
12
-
13
- test('should return true for claude-opus-4.6', () => {
14
- expect(supportsAdaptiveThinking('claude-opus-4.6')).toBe(true);
15
- });
16
-
17
- test('should return true for claude-opus-4-7 (future)', () => {
18
- expect(supportsAdaptiveThinking('claude-opus-4-7')).toBe(true);
19
- });
20
-
21
- test('should return true for claude-opus-5 (future)', () => {
22
- expect(supportsAdaptiveThinking('claude-opus-5')).toBe(true);
23
- });
24
-
25
- test('should return true for claude-opus-9 (future)', () => {
26
- expect(supportsAdaptiveThinking('claude-opus-9')).toBe(true);
27
- });
28
-
29
- test('should return true for claude-sonnet-5 (future)', () => {
30
- expect(supportsAdaptiveThinking('claude-sonnet-5')).toBe(true);
31
- });
32
-
33
- test('should return true for claude-sonnet-6 (future)', () => {
34
- expect(supportsAdaptiveThinking('claude-sonnet-6')).toBe(true);
35
- });
36
-
37
- test('should return false for claude-opus-4-5', () => {
38
- expect(supportsAdaptiveThinking('claude-opus-4-5')).toBe(false);
39
- });
40
-
41
- test('should return false for claude-opus-4', () => {
42
- expect(supportsAdaptiveThinking('claude-opus-4')).toBe(false);
43
- });
44
-
45
- test('should return false for claude-opus-4-0', () => {
46
- expect(supportsAdaptiveThinking('claude-opus-4-0')).toBe(false);
47
- });
48
-
49
- test('should return true for claude-sonnet-4-6', () => {
50
- expect(supportsAdaptiveThinking('claude-sonnet-4-6')).toBe(true);
51
- });
52
-
53
- test('should return true for claude-sonnet-4.6', () => {
54
- expect(supportsAdaptiveThinking('claude-sonnet-4.6')).toBe(true);
55
- });
56
-
57
- test('should return true for claude-sonnet-4-7 (future)', () => {
58
- expect(supportsAdaptiveThinking('claude-sonnet-4-7')).toBe(true);
59
- });
60
-
61
- test('should return true for anthropic.claude-sonnet-4-6 (Bedrock)', () => {
62
- expect(supportsAdaptiveThinking('anthropic.claude-sonnet-4-6')).toBe(true);
63
- });
64
-
65
- test('should return true for us.anthropic.claude-sonnet-4-6 (cross-region Bedrock)', () => {
66
- expect(supportsAdaptiveThinking('us.anthropic.claude-sonnet-4-6')).toBe(true);
67
- });
68
-
69
- test('should return true for claude-4-6-sonnet (alternate naming)', () => {
70
- expect(supportsAdaptiveThinking('claude-4-6-sonnet')).toBe(true);
71
- });
72
-
73
- test('should return false for claude-sonnet-4-5', () => {
74
- expect(supportsAdaptiveThinking('claude-sonnet-4-5')).toBe(false);
75
- });
76
-
77
- test('should return false for claude-sonnet-4', () => {
78
- expect(supportsAdaptiveThinking('claude-sonnet-4')).toBe(false);
79
- });
80
-
81
- test('should return false for claude-3-7-sonnet', () => {
82
- expect(supportsAdaptiveThinking('claude-3-7-sonnet')).toBe(false);
83
- });
84
-
85
- test('should return false for unrelated model', () => {
86
- expect(supportsAdaptiveThinking('gpt-4o')).toBe(false);
87
- });
88
-
89
- test('should handle Bedrock model ID with prefix stripping', () => {
90
- expect(supportsAdaptiveThinking('anthropic.claude-opus-4-6-v1:0')).toBe(true);
91
- });
92
-
93
- test('should handle cross-region Bedrock model ID', () => {
94
- expect(supportsAdaptiveThinking('us.anthropic.claude-opus-4-6-v1')).toBe(true);
95
- });
96
-
97
- test('should return true for claude-4-6-opus (alternate naming)', () => {
98
- expect(supportsAdaptiveThinking('claude-4-6-opus')).toBe(true);
99
- });
100
-
101
- test('should return true for anthropic.claude-4-6-opus (alternate naming)', () => {
102
- expect(supportsAdaptiveThinking('anthropic.claude-4-6-opus')).toBe(true);
103
- });
104
-
105
- test('should return true for claude-5-sonnet (alternate naming)', () => {
106
- expect(supportsAdaptiveThinking('claude-5-sonnet')).toBe(true);
107
- });
108
-
109
- test('should return true for anthropic.claude-5-sonnet (alternate naming)', () => {
110
- expect(supportsAdaptiveThinking('anthropic.claude-5-sonnet')).toBe(true);
111
- });
112
-
113
- test('should return false for claude-4-5-opus (alternate naming, below threshold)', () => {
114
- expect(supportsAdaptiveThinking('claude-4-5-opus')).toBe(false);
115
- });
116
-
117
- test('should return false for claude-4-sonnet (alternate naming, below threshold)', () => {
118
- expect(supportsAdaptiveThinking('claude-4-sonnet')).toBe(false);
119
- });
120
- });
121
-
122
- describe('supportsContext1m', () => {
123
- test('should return true for claude-sonnet-4', () => {
124
- expect(supportsContext1m('claude-sonnet-4')).toBe(true);
125
- });
126
-
127
- test('should return true for claude-sonnet-4-5', () => {
128
- expect(supportsContext1m('claude-sonnet-4-5')).toBe(true);
129
- });
130
-
131
- test('should return true for claude-sonnet-4-6', () => {
132
- expect(supportsContext1m('claude-sonnet-4-6')).toBe(true);
133
- });
134
-
135
- test('should return true for anthropic.claude-sonnet-4-6 (Bedrock)', () => {
136
- expect(supportsContext1m('anthropic.claude-sonnet-4-6')).toBe(true);
137
- });
138
-
139
- test('should return true for claude-sonnet-5 (future)', () => {
140
- expect(supportsContext1m('claude-sonnet-5')).toBe(true);
141
- });
142
-
143
- test('should return true for claude-opus-4-6', () => {
144
- expect(supportsContext1m('claude-opus-4-6')).toBe(true);
145
- });
146
-
147
- test('should return true for claude-opus-5 (future)', () => {
148
- expect(supportsContext1m('claude-opus-5')).toBe(true);
149
- });
150
-
151
- test('should return false for claude-opus-4-5', () => {
152
- expect(supportsContext1m('claude-opus-4-5')).toBe(false);
153
- });
154
-
155
- test('should return false for claude-opus-4', () => {
156
- expect(supportsContext1m('claude-opus-4')).toBe(false);
157
- });
158
-
159
- test('should return false for claude-3-7-sonnet', () => {
160
- expect(supportsContext1m('claude-3-7-sonnet')).toBe(false);
161
- });
162
-
163
- test('should return false for claude-sonnet-3', () => {
164
- expect(supportsContext1m('claude-sonnet-3')).toBe(false);
165
- });
166
-
167
- test('should return false for unrelated model', () => {
168
- expect(supportsContext1m('gpt-4o')).toBe(false);
169
- });
170
-
171
- test('should return true for claude-4-sonnet (alternate naming)', () => {
172
- expect(supportsContext1m('claude-4-sonnet')).toBe(true);
173
- });
174
-
175
- test('should return true for claude-5-sonnet (alternate naming)', () => {
176
- expect(supportsContext1m('claude-5-sonnet')).toBe(true);
177
- });
178
-
179
- test('should return true for claude-4-6-opus (alternate naming)', () => {
180
- expect(supportsContext1m('claude-4-6-opus')).toBe(true);
181
- });
182
-
183
- test('should return false for claude-3-sonnet (alternate naming, below threshold)', () => {
184
- expect(supportsContext1m('claude-3-sonnet')).toBe(false);
185
- });
186
-
187
- test('should return false for claude-4-5-opus (alternate naming, below threshold)', () => {
188
- expect(supportsContext1m('claude-4-5-opus')).toBe(false);
189
- });
190
- });
191
-
192
- describe('bedrockInputParser', () => {
193
- describe('Model Matching for Reasoning Configuration', () => {
194
- test('should match anthropic.claude-3-7-sonnet model', () => {
195
- const input = {
196
- model: 'anthropic.claude-3-7-sonnet',
197
- };
198
- const result = bedrockInputParser.parse(input) as Record<string, unknown>;
199
- const additionalFields = result.additionalModelRequestFields as Record<string, unknown>;
200
- expect(additionalFields.thinking).toBe(true);
201
- expect(additionalFields.thinkingBudget).toBe(2000);
202
- expect(additionalFields.anthropic_beta).toEqual(['output-128k-2025-02-19']);
203
- });
204
-
205
- test('should match anthropic.claude-sonnet-4 model with 1M context header', () => {
206
- const input = {
207
- model: 'anthropic.claude-sonnet-4',
208
- };
209
- const result = bedrockInputParser.parse(input) as Record<string, unknown>;
210
- const additionalFields = result.additionalModelRequestFields as Record<string, unknown>;
211
- expect(additionalFields.thinking).toBe(true);
212
- expect(additionalFields.thinkingBudget).toBe(2000);
213
- expect(additionalFields.anthropic_beta).toEqual([
214
- 'output-128k-2025-02-19',
215
- 'context-1m-2025-08-07',
216
- ]);
217
- });
218
-
219
- test('should match anthropic.claude-opus-5 model with adaptive thinking and 1M context', () => {
220
- const input = {
221
- model: 'anthropic.claude-opus-5',
222
- };
223
- const result = bedrockInputParser.parse(input) as Record<string, unknown>;
224
- const additionalFields = result.additionalModelRequestFields as Record<string, unknown>;
225
- expect(additionalFields.thinking).toEqual({ type: 'adaptive' });
226
- expect(additionalFields.thinkingBudget).toBeUndefined();
227
- expect(additionalFields.anthropic_beta).toEqual([
228
- 'output-128k-2025-02-19',
229
- 'context-1m-2025-08-07',
230
- ]);
231
- });
232
-
233
- test('should match anthropic.claude-haiku-6 model without 1M context header', () => {
234
- const input = {
235
- model: 'anthropic.claude-haiku-6',
236
- };
237
- const result = bedrockInputParser.parse(input) as Record<string, unknown>;
238
- const additionalFields = result.additionalModelRequestFields as Record<string, unknown>;
239
- expect(additionalFields.thinking).toBe(true);
240
- expect(additionalFields.thinkingBudget).toBe(2000);
241
- expect(additionalFields.anthropic_beta).toEqual(['output-128k-2025-02-19']);
242
- });
243
-
244
- test('should match anthropic.claude-4-sonnet model with 1M context header', () => {
245
- const input = {
246
- model: 'anthropic.claude-4-sonnet',
247
- };
248
- const result = bedrockInputParser.parse(input) as Record<string, unknown>;
249
- const additionalFields = result.additionalModelRequestFields as Record<string, unknown>;
250
- expect(additionalFields.thinking).toBe(true);
251
- expect(additionalFields.thinkingBudget).toBe(2000);
252
- expect(additionalFields.anthropic_beta).toEqual([
253
- 'output-128k-2025-02-19',
254
- 'context-1m-2025-08-07',
255
- ]);
256
- });
257
-
258
- test('should match anthropic.claude-4.5-sonnet model with 1M context header', () => {
259
- const input = {
260
- model: 'anthropic.claude-4.5-sonnet',
261
- };
262
- const result = bedrockInputParser.parse(input) as Record<string, unknown>;
263
- const additionalFields = result.additionalModelRequestFields as Record<string, unknown>;
264
- expect(additionalFields.thinking).toBe(true);
265
- expect(additionalFields.thinkingBudget).toBe(2000);
266
- expect(additionalFields.anthropic_beta).toEqual([
267
- 'output-128k-2025-02-19',
268
- 'context-1m-2025-08-07',
269
- ]);
270
- });
271
-
272
- test('should match anthropic.claude-sonnet-4-6 with adaptive thinking and 1M context header', () => {
273
- const input = {
274
- model: 'anthropic.claude-sonnet-4-6',
275
- };
276
- const result = bedrockInputParser.parse(input) as Record<string, unknown>;
277
- const additionalFields = result.additionalModelRequestFields as Record<string, unknown>;
278
- expect(additionalFields.thinking).toEqual({ type: 'adaptive' });
279
- expect(additionalFields.thinkingBudget).toBeUndefined();
280
- expect(additionalFields.anthropic_beta).toEqual([
281
- 'output-128k-2025-02-19',
282
- 'context-1m-2025-08-07',
283
- ]);
284
- });
285
-
286
- test('should match us.anthropic.claude-sonnet-4-6 with adaptive thinking and 1M context header', () => {
287
- const input = {
288
- model: 'us.anthropic.claude-sonnet-4-6',
289
- };
290
- const result = bedrockInputParser.parse(input) as Record<string, unknown>;
291
- const additionalFields = result.additionalModelRequestFields as Record<string, unknown>;
292
- expect(additionalFields.thinking).toEqual({ type: 'adaptive' });
293
- expect(additionalFields.thinkingBudget).toBeUndefined();
294
- expect(additionalFields.anthropic_beta).toEqual([
295
- 'output-128k-2025-02-19',
296
- 'context-1m-2025-08-07',
297
- ]);
298
- });
299
-
300
- test('should match anthropic.claude-4-7-sonnet model with adaptive thinking and 1M context header', () => {
301
- const input = {
302
- model: 'anthropic.claude-4-7-sonnet',
303
- };
304
- const result = bedrockInputParser.parse(input) as Record<string, unknown>;
305
- const additionalFields = result.additionalModelRequestFields as Record<string, unknown>;
306
- expect(additionalFields.thinking).toEqual({ type: 'adaptive' });
307
- expect(additionalFields.thinkingBudget).toBeUndefined();
308
- expect(additionalFields.anthropic_beta).toEqual([
309
- 'output-128k-2025-02-19',
310
- 'context-1m-2025-08-07',
311
- ]);
312
- });
313
-
314
- test('should match anthropic.claude-sonnet-4-20250514-v1:0 with full model ID', () => {
315
- const input = {
316
- model: 'anthropic.claude-sonnet-4-20250514-v1:0',
317
- };
318
- const result = bedrockInputParser.parse(input) as Record<string, unknown>;
319
- const additionalFields = result.additionalModelRequestFields as Record<string, unknown>;
320
- expect(additionalFields.thinking).toBe(true);
321
- expect(additionalFields.thinkingBudget).toBe(2000);
322
- expect(additionalFields.anthropic_beta).toEqual([
323
- 'output-128k-2025-02-19',
324
- 'context-1m-2025-08-07',
325
- ]);
326
- });
327
-
328
- test('should not match non-Claude models', () => {
329
- const input = {
330
- model: 'some-other-model',
331
- };
332
- const result = bedrockInputParser.parse(input) as Record<string, unknown>;
333
- expect(result.additionalModelRequestFields).toBeUndefined();
334
- });
335
-
336
- test('should not add anthropic_beta to Moonshot Kimi K2 models', () => {
337
- const input = {
338
- model: 'moonshot.kimi-k2-0711-thinking',
339
- };
340
- const result = bedrockInputParser.parse(input) as Record<string, unknown>;
341
- const additionalFields = result.additionalModelRequestFields as
342
- | Record<string, unknown>
343
- | undefined;
344
- expect(additionalFields?.anthropic_beta).toBeUndefined();
345
- });
346
-
347
- test('should not add anthropic_beta to DeepSeek models', () => {
348
- const input = {
349
- model: 'deepseek.deepseek-r1',
350
- };
351
- const result = bedrockInputParser.parse(input) as Record<string, unknown>;
352
- const additionalFields = result.additionalModelRequestFields as
353
- | Record<string, unknown>
354
- | undefined;
355
- expect(additionalFields?.anthropic_beta).toBeUndefined();
356
- });
357
-
358
- test('should respect explicit thinking configuration but still add beta headers', () => {
359
- const input = {
360
- model: 'anthropic.claude-sonnet-4',
361
- thinking: false,
362
- };
363
- const result = bedrockInputParser.parse(input) as Record<string, unknown>;
364
- const additionalFields = result.additionalModelRequestFields as Record<string, unknown>;
365
- expect(additionalFields.thinking).toBeUndefined();
366
- expect(additionalFields.thinkingBudget).toBeUndefined();
367
- expect(additionalFields.anthropic_beta).toEqual([
368
- 'output-128k-2025-02-19',
369
- 'context-1m-2025-08-07',
370
- ]);
371
- });
372
-
373
- test('should respect custom thinking budget', () => {
374
- const input = {
375
- model: 'anthropic.claude-sonnet-4',
376
- thinking: true,
377
- thinkingBudget: 3000,
378
- };
379
- const result = bedrockInputParser.parse(input) as Record<string, unknown>;
380
- const additionalFields = result.additionalModelRequestFields as Record<string, unknown>;
381
- expect(additionalFields.thinking).toBe(true);
382
- expect(additionalFields.thinkingBudget).toBe(3000);
383
- });
384
- });
385
-
386
- describe('Opus 4.6 Adaptive Thinking', () => {
387
- test('should default to adaptive thinking for anthropic.claude-opus-4-6-v1', () => {
388
- const input = {
389
- model: 'anthropic.claude-opus-4-6-v1',
390
- };
391
- const result = bedrockInputParser.parse(input) as Record<string, unknown>;
392
- const additionalFields = result.additionalModelRequestFields as Record<string, unknown>;
393
- expect(additionalFields.thinking).toEqual({ type: 'adaptive' });
394
- expect(additionalFields.thinkingBudget).toBeUndefined();
395
- expect(additionalFields.anthropic_beta).toEqual([
396
- 'output-128k-2025-02-19',
397
- 'context-1m-2025-08-07',
398
- ]);
399
- });
400
-
401
- test('should handle cross-region model ID us.anthropic.claude-opus-4-6-v1', () => {
402
- const input = {
403
- model: 'us.anthropic.claude-opus-4-6-v1',
404
- };
405
- const result = bedrockInputParser.parse(input) as Record<string, unknown>;
406
- const additionalFields = result.additionalModelRequestFields as Record<string, unknown>;
407
- expect(additionalFields.thinking).toEqual({ type: 'adaptive' });
408
- expect(additionalFields.thinkingBudget).toBeUndefined();
409
- expect(additionalFields.anthropic_beta).toEqual([
410
- 'output-128k-2025-02-19',
411
- 'context-1m-2025-08-07',
412
- ]);
413
- });
414
-
415
- test('should handle cross-region model ID global.anthropic.claude-opus-4-6-v1', () => {
416
- const input = {
417
- model: 'global.anthropic.claude-opus-4-6-v1',
418
- };
419
- const result = bedrockInputParser.parse(input) as Record<string, unknown>;
420
- const additionalFields = result.additionalModelRequestFields as Record<string, unknown>;
421
- expect(additionalFields.thinking).toEqual({ type: 'adaptive' });
422
- expect(additionalFields.anthropic_beta).toEqual([
423
- 'output-128k-2025-02-19',
424
- 'context-1m-2025-08-07',
425
- ]);
426
- });
427
-
428
- test('should pass effort parameter via output_config for adaptive models', () => {
429
- const input = {
430
- model: 'anthropic.claude-opus-4-6-v1',
431
- effort: 'medium',
432
- };
433
- const result = bedrockInputParser.parse(input) as Record<string, unknown>;
434
- const additionalFields = result.additionalModelRequestFields as Record<string, unknown>;
435
- expect(additionalFields.thinking).toEqual({ type: 'adaptive' });
436
- expect(additionalFields.output_config).toEqual({ effort: 'medium' });
437
- expect(additionalFields.effort).toBeUndefined();
438
- });
439
-
440
- test('should not include output_config when effort is unset (empty string)', () => {
441
- const input = {
442
- model: 'anthropic.claude-opus-4-6-v1',
443
- effort: '',
444
- };
445
- const result = bedrockInputParser.parse(input) as Record<string, unknown>;
446
- const additionalFields = result.additionalModelRequestFields as Record<string, unknown>;
447
- expect(additionalFields.thinking).toEqual({ type: 'adaptive' });
448
- expect(additionalFields.output_config).toBeUndefined();
449
- });
450
-
451
- test('should respect thinking=false for adaptive models', () => {
452
- const input = {
453
- model: 'anthropic.claude-opus-4-6-v1',
454
- thinking: false,
455
- };
456
- const result = bedrockInputParser.parse(input) as Record<string, unknown>;
457
- const additionalFields = result.additionalModelRequestFields as Record<string, unknown>;
458
- expect(additionalFields.thinking).toBeUndefined();
459
- expect(additionalFields.thinkingBudget).toBeUndefined();
460
- expect(additionalFields.anthropic_beta).toEqual([
461
- 'output-128k-2025-02-19',
462
- 'context-1m-2025-08-07',
463
- ]);
464
- });
465
-
466
- test('should preserve effort when thinking=false for adaptive models', () => {
467
- const input = {
468
- model: 'anthropic.claude-opus-4-6-v1',
469
- thinking: false,
470
- effort: 'high',
471
- };
472
- const result = bedrockInputParser.parse(input) as Record<string, unknown>;
473
- const additionalFields = result.additionalModelRequestFields as Record<string, unknown>;
474
- expect(additionalFields.thinking).toBeUndefined();
475
- expect(additionalFields.thinkingBudget).toBeUndefined();
476
- expect(additionalFields.output_config).toEqual({ effort: 'high' });
477
- expect(additionalFields.effort).toBeUndefined();
478
- });
479
-
480
- test('should strip effort for non-adaptive thinking models', () => {
481
- const input = {
482
- model: 'anthropic.claude-sonnet-4-5-20250929-v1:0',
483
- effort: 'high',
484
- };
485
- const result = bedrockInputParser.parse(input) as Record<string, unknown>;
486
- const additionalFields = result.additionalModelRequestFields as Record<string, unknown>;
487
- expect(additionalFields.thinking).toBe(true);
488
- expect(additionalFields.thinkingBudget).toBe(2000);
489
- expect(additionalFields.effort).toBeUndefined();
490
- expect(additionalFields.output_config).toBeUndefined();
491
- });
492
-
493
- test('should not include effort for Opus 4.5 (non-adaptive)', () => {
494
- const input = {
495
- model: 'anthropic.claude-opus-4-5-v1:0',
496
- effort: 'low',
497
- };
498
- const result = bedrockInputParser.parse(input) as Record<string, unknown>;
499
- const additionalFields = result.additionalModelRequestFields as Record<string, unknown>;
500
- expect(additionalFields.thinking).toBe(true);
501
- expect(additionalFields.effort).toBeUndefined();
502
- expect(additionalFields.output_config).toBeUndefined();
503
- });
504
-
505
- test('should support max effort for Opus 4.6', () => {
506
- const input = {
507
- model: 'anthropic.claude-opus-4-6-v1',
508
- effort: 'max',
509
- };
510
- const result = bedrockInputParser.parse(input) as Record<string, unknown>;
511
- const additionalFields = result.additionalModelRequestFields as Record<string, unknown>;
512
- expect(additionalFields.thinking).toEqual({ type: 'adaptive' });
513
- expect(additionalFields.output_config).toEqual({ effort: 'max' });
514
- });
515
- });
516
-
517
- describe('bedrockOutputParser with configureThinking', () => {
518
- test('should preserve adaptive thinking config without setting default maxTokens', () => {
519
- const parsed = bedrockInputParser.parse({
520
- model: 'anthropic.claude-opus-4-6-v1',
521
- }) as Record<string, unknown>;
522
- const output = bedrockOutputParser(parsed as Record<string, unknown>);
523
- const amrf = output.additionalModelRequestFields as Record<string, unknown>;
524
- expect(amrf.thinking).toEqual({ type: 'adaptive' });
525
- expect(output.maxTokens).toBeUndefined();
526
- expect(output.maxOutputTokens).toBeUndefined();
527
- });
528
-
529
- test('should respect user-provided maxTokens for adaptive model', () => {
530
- const parsed = bedrockInputParser.parse({
531
- model: 'anthropic.claude-opus-4-6-v1',
532
- maxTokens: 32000,
533
- }) as Record<string, unknown>;
534
- const output = bedrockOutputParser(parsed as Record<string, unknown>);
535
- expect(output.maxTokens).toBe(32000);
536
- });
537
-
538
- test('should use maxOutputTokens as maxTokens for adaptive model when maxTokens is not set', () => {
539
- const parsed = bedrockInputParser.parse({
540
- model: 'anthropic.claude-opus-4-6-v1',
541
- maxOutputTokens: 24000,
542
- }) as Record<string, unknown>;
543
- const output = bedrockOutputParser(parsed as Record<string, unknown>);
544
- expect(output.maxTokens).toBe(24000);
545
- expect(output.maxOutputTokens).toBeUndefined();
546
- });
547
-
548
- test('should convert thinking=true to enabled config for non-adaptive models', () => {
549
- const parsed = bedrockInputParser.parse({
550
- model: 'anthropic.claude-sonnet-4-5-20250929-v1:0',
551
- }) as Record<string, unknown>;
552
- const output = bedrockOutputParser(parsed as Record<string, unknown>);
553
- const amrf = output.additionalModelRequestFields as Record<string, unknown>;
554
- expect(amrf.thinking).toEqual({ type: 'enabled', budget_tokens: 2000 });
555
- expect(output.maxTokens).toBe(8192);
556
- });
557
-
558
- test('should pass output_config through for adaptive model with effort', () => {
559
- const parsed = bedrockInputParser.parse({
560
- model: 'anthropic.claude-opus-4-6-v1',
561
- effort: 'low',
562
- }) as Record<string, unknown>;
563
- const output = bedrockOutputParser(parsed as Record<string, unknown>);
564
- const amrf = output.additionalModelRequestFields as Record<string, unknown>;
565
- expect(amrf.thinking).toEqual({ type: 'adaptive' });
566
- expect(amrf.output_config).toEqual({ effort: 'low' });
567
- });
568
-
569
- test('should not set maxTokens for adaptive models when neither maxTokens nor maxOutputTokens are provided', () => {
570
- const parsed = bedrockInputParser.parse({
571
- model: 'anthropic.claude-opus-4-6-v1',
572
- }) as Record<string, unknown>;
573
- parsed.maxOutputTokens = undefined;
574
- (parsed as Record<string, unknown>).maxTokens = undefined;
575
- const output = bedrockOutputParser(parsed as Record<string, unknown>);
576
- expect(output.maxTokens).toBeUndefined();
577
- });
578
-
579
- test('should use enabled default maxTokens (8192) for non-adaptive thinking models', () => {
580
- const parsed = bedrockInputParser.parse({
581
- model: 'anthropic.claude-sonnet-4-5-20250929-v1:0',
582
- }) as Record<string, unknown>;
583
- parsed.maxOutputTokens = undefined;
584
- (parsed as Record<string, unknown>).maxTokens = undefined;
585
- const output = bedrockOutputParser(parsed as Record<string, unknown>);
586
- expect(output.maxTokens).toBe(8192);
587
- });
588
-
589
- test('should use default thinking budget (2000) when no custom budget is set', () => {
590
- const parsed = bedrockInputParser.parse({
591
- model: 'anthropic.claude-3-7-sonnet',
592
- }) as Record<string, unknown>;
593
- const output = bedrockOutputParser(parsed as Record<string, unknown>);
594
- const amrf = output.additionalModelRequestFields as Record<string, unknown>;
595
- const thinking = amrf.thinking as { type: string; budget_tokens: number };
596
- expect(thinking.budget_tokens).toBe(2000);
597
- });
598
-
599
- test('should override default thinking budget with custom value', () => {
600
- const parsed = bedrockInputParser.parse({
601
- model: 'anthropic.claude-3-7-sonnet',
602
- thinkingBudget: 5000,
603
- maxTokens: 8192,
604
- }) as Record<string, unknown>;
605
- const output = bedrockOutputParser(parsed as Record<string, unknown>);
606
- const amrf = output.additionalModelRequestFields as Record<string, unknown>;
607
- const thinking = amrf.thinking as { type: string; budget_tokens: number };
608
- expect(thinking.budget_tokens).toBe(5000);
609
- });
610
-
611
- test('should remove additionalModelRequestFields when thinking disabled and no other fields', () => {
612
- const parsed = bedrockInputParser.parse({
613
- model: 'some-other-model',
614
- }) as Record<string, unknown>;
615
- const output = bedrockOutputParser(parsed as Record<string, unknown>);
616
- expect(output.additionalModelRequestFields).toBeUndefined();
617
- });
618
- });
619
-
620
- describe('Model switching cleanup', () => {
621
- test('should strip anthropic_beta when switching from Anthropic to non-Anthropic model', () => {
622
- const staleConversationData = {
623
- model: 'openai.gpt-oss-120b-1:0',
624
- promptCache: true,
625
- additionalModelRequestFields: {
626
- anthropic_beta: ['output-128k-2025-02-19', 'context-1m-2025-08-07'],
627
- thinking: { type: 'adaptive' },
628
- output_config: { effort: 'high' },
629
- },
630
- };
631
- const result = bedrockInputParser.parse(staleConversationData) as Record<string, unknown>;
632
- const amrf = result.additionalModelRequestFields as Record<string, unknown> | undefined;
633
- expect(amrf?.anthropic_beta).toBeUndefined();
634
- expect(amrf?.thinking).toBeUndefined();
635
- expect(amrf?.output_config).toBeUndefined();
636
- expect(result.promptCache).toBeUndefined();
637
- });
638
-
639
- test('should strip promptCache when switching from Claude to non-Claude/Nova model', () => {
640
- const staleConversationData = {
641
- model: 'deepseek.deepseek-r1',
642
- promptCache: true,
643
- };
644
- const result = bedrockInputParser.parse(staleConversationData) as Record<string, unknown>;
645
- expect(result.promptCache).toBeUndefined();
646
- });
647
-
648
- test('should preserve promptCache for Claude models', () => {
649
- const input = {
650
- model: 'anthropic.claude-sonnet-4-20250514-v1:0',
651
- promptCache: true,
652
- };
653
- const result = bedrockInputParser.parse(input) as Record<string, unknown>;
654
- expect(result.promptCache).toBe(true);
655
- });
656
-
657
- test('should preserve promptCache for Nova models', () => {
658
- const input = {
659
- model: 'amazon.nova-pro-v1:0',
660
- promptCache: true,
661
- };
662
- const result = bedrockInputParser.parse(input) as Record<string, unknown>;
663
- expect(result.promptCache).toBe(true);
664
- });
665
-
666
- test('should strip stale thinking config from additionalModelRequestFields for non-Anthropic models', () => {
667
- const staleConversationData = {
668
- model: 'moonshot.kimi-k2-0711-thinking',
669
- additionalModelRequestFields: {
670
- thinking: { type: 'enabled', budget_tokens: 2000 },
671
- thinkingBudget: 2000,
672
- anthropic_beta: ['output-128k-2025-02-19'],
673
- },
674
- };
675
- const result = bedrockInputParser.parse(staleConversationData) as Record<string, unknown>;
676
- const amrf = result.additionalModelRequestFields as Record<string, unknown> | undefined;
677
- expect(amrf?.anthropic_beta).toBeUndefined();
678
- expect(amrf?.thinking).toBeUndefined();
679
- expect(amrf?.thinkingBudget).toBeUndefined();
680
- });
681
-
682
- test('should not strip anthropic_beta when staying on an Anthropic model', () => {
683
- const input = {
684
- model: 'anthropic.claude-opus-4-6-v1',
685
- };
686
- const result = bedrockInputParser.parse(input) as Record<string, unknown>;
687
- const amrf = result.additionalModelRequestFields as Record<string, unknown>;
688
- expect(amrf.anthropic_beta).toBeDefined();
689
- expect(Array.isArray(amrf.anthropic_beta)).toBe(true);
690
- });
691
-
692
- test('should strip stale reasoning_config when switching to Anthropic model', () => {
693
- const staleConversationData = {
694
- model: 'anthropic.claude-sonnet-4-6',
695
- additionalModelRequestFields: {
696
- reasoning_config: 'high',
697
- },
698
- };
699
- const result = bedrockInputParser.parse(staleConversationData) as Record<string, unknown>;
700
- const amrf = result.additionalModelRequestFields as Record<string, unknown>;
701
- expect(amrf.reasoning_config).toBeUndefined();
702
- });
703
-
704
- test('should strip stale reasoning_config when switching from Moonshot to Meta model', () => {
705
- const staleData = {
706
- model: 'meta.llama-3-1-70b',
707
- additionalModelRequestFields: {
708
- reasoning_config: 'high',
709
- },
710
- };
711
- const result = bedrockInputParser.parse(staleData) as Record<string, unknown>;
712
- const amrf = result.additionalModelRequestFields as Record<string, unknown> | undefined;
713
- expect(amrf?.reasoning_config).toBeUndefined();
714
- });
715
-
716
- test('should strip stale reasoning_config when switching from ZAI to DeepSeek model', () => {
717
- const staleData = {
718
- model: 'deepseek.deepseek-r1',
719
- additionalModelRequestFields: {
720
- reasoning_config: 'medium',
721
- },
722
- };
723
- const result = bedrockInputParser.parse(staleData) as Record<string, unknown>;
724
- const amrf = result.additionalModelRequestFields as Record<string, unknown> | undefined;
725
- expect(amrf?.reasoning_config).toBeUndefined();
726
- });
727
- });
728
-
729
- describe('Bedrock reasoning_effort → reasoning_config for Moonshot/ZAI models', () => {
730
- test('should map reasoning_effort to reasoning_config for moonshotai.kimi-k2.5', () => {
731
- const input = {
732
- model: 'moonshotai.kimi-k2.5',
733
- reasoning_effort: 'high',
734
- };
735
- const result = bedrockInputParser.parse(input) as Record<string, unknown>;
736
- const amrf = result.additionalModelRequestFields as Record<string, unknown>;
737
- expect(amrf.reasoning_config).toBe('high');
738
- expect(amrf.reasoning_effort).toBeUndefined();
739
- });
740
-
741
- test('should map reasoning_effort to reasoning_config for moonshot.kimi-k2.5', () => {
742
- const input = {
743
- model: 'moonshot.kimi-k2.5',
744
- reasoning_effort: 'medium',
745
- };
746
- const result = bedrockInputParser.parse(input) as Record<string, unknown>;
747
- const amrf = result.additionalModelRequestFields as Record<string, unknown>;
748
- expect(amrf.reasoning_config).toBe('medium');
749
- });
750
-
751
- test('should map reasoning_effort to reasoning_config for zai.glm-4.7', () => {
752
- const input = {
753
- model: 'zai.glm-4.7',
754
- reasoning_effort: 'high',
755
- };
756
- const result = bedrockInputParser.parse(input) as Record<string, unknown>;
757
- const amrf = result.additionalModelRequestFields as Record<string, unknown>;
758
- expect(amrf.reasoning_config).toBe('high');
759
- });
760
-
761
- test('should map reasoning_effort "low" to reasoning_config for Moonshot model', () => {
762
- const input = {
763
- model: 'moonshotai.kimi-k2.5',
764
- reasoning_effort: 'low',
765
- };
766
- const result = bedrockInputParser.parse(input) as Record<string, unknown>;
767
- const amrf = result.additionalModelRequestFields as Record<string, unknown>;
768
- expect(amrf.reasoning_config).toBe('low');
769
- });
770
-
771
- test('should not include reasoning_config when reasoning_effort is unset (empty string)', () => {
772
- const input = {
773
- model: 'moonshotai.kimi-k2.5',
774
- reasoning_effort: '',
775
- };
776
- const result = bedrockInputParser.parse(input) as Record<string, unknown>;
777
- const amrf = result.additionalModelRequestFields as Record<string, unknown> | undefined;
778
- expect(amrf?.reasoning_config).toBeUndefined();
779
- });
780
-
781
- test('should not include reasoning_config when reasoning_effort is not provided', () => {
782
- const input = {
783
- model: 'moonshotai.kimi-k2.5',
784
- };
785
- const result = bedrockInputParser.parse(input) as Record<string, unknown>;
786
- const amrf = result.additionalModelRequestFields as Record<string, unknown> | undefined;
787
- expect(amrf?.reasoning_config).toBeUndefined();
788
- });
789
-
790
- test('should not forward reasoning_effort "none" to reasoning_config', () => {
791
- const result = bedrockInputParser.parse({
792
- model: 'moonshotai.kimi-k2.5',
793
- reasoning_effort: 'none',
794
- }) as Record<string, unknown>;
795
- const amrf = result.additionalModelRequestFields as Record<string, unknown> | undefined;
796
- expect(amrf?.reasoning_config).toBeUndefined();
797
- });
798
-
799
- test('should not forward reasoning_effort "minimal" to reasoning_config', () => {
800
- const result = bedrockInputParser.parse({
801
- model: 'moonshotai.kimi-k2.5',
802
- reasoning_effort: 'minimal',
803
- }) as Record<string, unknown>;
804
- const amrf = result.additionalModelRequestFields as Record<string, unknown> | undefined;
805
- expect(amrf?.reasoning_config).toBeUndefined();
806
- });
807
-
808
- test('should not forward reasoning_effort "xhigh" to reasoning_config', () => {
809
- const result = bedrockInputParser.parse({
810
- model: 'zai.glm-4.7',
811
- reasoning_effort: 'xhigh',
812
- }) as Record<string, unknown>;
813
- const amrf = result.additionalModelRequestFields as Record<string, unknown> | undefined;
814
- expect(amrf?.reasoning_config).toBeUndefined();
815
- });
816
-
817
- test('should not add reasoning_config to Anthropic models', () => {
818
- const input = {
819
- model: 'anthropic.claude-sonnet-4-6',
820
- reasoning_effort: 'high',
821
- };
822
- const result = bedrockInputParser.parse(input) as Record<string, unknown>;
823
- const amrf = result.additionalModelRequestFields as Record<string, unknown>;
824
- expect(amrf.reasoning_config).toBeUndefined();
825
- expect(amrf.reasoning_effort).toBeUndefined();
826
- });
827
-
828
- test('should not add thinking or anthropic_beta to Moonshot models with reasoning_effort', () => {
829
- const input = {
830
- model: 'moonshotai.kimi-k2.5',
831
- reasoning_effort: 'high',
832
- };
833
- const result = bedrockInputParser.parse(input) as Record<string, unknown>;
834
- const amrf = result.additionalModelRequestFields as Record<string, unknown>;
835
- expect(amrf.thinking).toBeUndefined();
836
- expect(amrf.thinkingBudget).toBeUndefined();
837
- expect(amrf.anthropic_beta).toBeUndefined();
838
- });
839
-
840
- test('should pass reasoning_config through bedrockOutputParser', () => {
841
- const parsed = bedrockInputParser.parse({
842
- model: 'moonshotai.kimi-k2.5',
843
- reasoning_effort: 'high',
844
- }) as Record<string, unknown>;
845
- const output = bedrockOutputParser(parsed);
846
- const amrf = output.additionalModelRequestFields as Record<string, unknown>;
847
- expect(amrf.reasoning_config).toBe('high');
848
- });
849
-
850
- test('should strip stale reasoning_config from additionalModelRequestFields for Anthropic models', () => {
851
- const staleData = {
852
- model: 'anthropic.claude-opus-4-6-v1',
853
- additionalModelRequestFields: {
854
- reasoning_config: 'high',
855
- },
856
- };
857
- const result = bedrockInputParser.parse(staleData) as Record<string, unknown>;
858
- const amrf = result.additionalModelRequestFields as Record<string, unknown>;
859
- expect(amrf.reasoning_config).toBeUndefined();
860
- });
861
- });
862
- });