@hebo-ai/gateway 0.6.2-rc0 → 0.6.2

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 (134) hide show
  1. package/README.md +3 -3
  2. package/dist/endpoints/chat-completions/converters.js +26 -21
  3. package/dist/endpoints/chat-completions/handler.js +2 -0
  4. package/dist/endpoints/chat-completions/otel.js +1 -1
  5. package/dist/endpoints/chat-completions/schema.d.ts +4 -18
  6. package/dist/endpoints/chat-completions/schema.js +14 -17
  7. package/dist/endpoints/embeddings/handler.js +2 -0
  8. package/dist/endpoints/embeddings/otel.js +5 -0
  9. package/dist/endpoints/embeddings/schema.d.ts +6 -0
  10. package/dist/endpoints/embeddings/schema.js +4 -1
  11. package/dist/endpoints/models/converters.js +3 -3
  12. package/dist/lifecycle.js +2 -2
  13. package/dist/logger/default.js +3 -3
  14. package/dist/logger/index.d.ts +2 -5
  15. package/dist/middleware/common.js +1 -0
  16. package/dist/middleware/utils.js +0 -3
  17. package/dist/models/amazon/middleware.js +8 -5
  18. package/dist/models/anthropic/middleware.js +13 -13
  19. package/dist/models/catalog.js +5 -1
  20. package/dist/models/cohere/middleware.js +7 -5
  21. package/dist/models/google/middleware.d.ts +1 -1
  22. package/dist/models/google/middleware.js +29 -25
  23. package/dist/models/openai/middleware.js +13 -9
  24. package/dist/models/voyage/middleware.js +2 -1
  25. package/dist/providers/bedrock/middleware.js +21 -23
  26. package/dist/providers/registry.js +3 -0
  27. package/dist/telemetry/fetch.js +7 -2
  28. package/dist/telemetry/gen-ai.js +15 -12
  29. package/dist/telemetry/memory.d.ts +1 -1
  30. package/dist/telemetry/memory.js +30 -14
  31. package/dist/telemetry/span.js +1 -1
  32. package/dist/telemetry/stream.js +30 -23
  33. package/dist/utils/env.js +4 -2
  34. package/dist/utils/preset.js +1 -0
  35. package/dist/utils/response.js +3 -1
  36. package/package.json +36 -50
  37. package/src/config.ts +0 -98
  38. package/src/endpoints/chat-completions/converters.test.ts +0 -631
  39. package/src/endpoints/chat-completions/converters.ts +0 -899
  40. package/src/endpoints/chat-completions/handler.test.ts +0 -391
  41. package/src/endpoints/chat-completions/handler.ts +0 -201
  42. package/src/endpoints/chat-completions/index.ts +0 -4
  43. package/src/endpoints/chat-completions/otel.test.ts +0 -315
  44. package/src/endpoints/chat-completions/otel.ts +0 -214
  45. package/src/endpoints/chat-completions/schema.ts +0 -364
  46. package/src/endpoints/embeddings/converters.ts +0 -51
  47. package/src/endpoints/embeddings/handler.test.ts +0 -133
  48. package/src/endpoints/embeddings/handler.ts +0 -137
  49. package/src/endpoints/embeddings/index.ts +0 -4
  50. package/src/endpoints/embeddings/otel.ts +0 -40
  51. package/src/endpoints/embeddings/schema.ts +0 -36
  52. package/src/endpoints/models/converters.ts +0 -56
  53. package/src/endpoints/models/handler.test.ts +0 -122
  54. package/src/endpoints/models/handler.ts +0 -37
  55. package/src/endpoints/models/index.ts +0 -3
  56. package/src/endpoints/models/schema.ts +0 -37
  57. package/src/errors/ai-sdk.ts +0 -99
  58. package/src/errors/gateway.ts +0 -17
  59. package/src/errors/openai.ts +0 -57
  60. package/src/errors/utils.ts +0 -47
  61. package/src/gateway.ts +0 -50
  62. package/src/index.ts +0 -19
  63. package/src/lifecycle.ts +0 -135
  64. package/src/logger/default.ts +0 -105
  65. package/src/logger/index.ts +0 -42
  66. package/src/middleware/common.test.ts +0 -215
  67. package/src/middleware/common.ts +0 -163
  68. package/src/middleware/debug.ts +0 -37
  69. package/src/middleware/matcher.ts +0 -161
  70. package/src/middleware/utils.ts +0 -34
  71. package/src/models/amazon/index.ts +0 -2
  72. package/src/models/amazon/middleware.test.ts +0 -133
  73. package/src/models/amazon/middleware.ts +0 -79
  74. package/src/models/amazon/presets.ts +0 -104
  75. package/src/models/anthropic/index.ts +0 -2
  76. package/src/models/anthropic/middleware.test.ts +0 -643
  77. package/src/models/anthropic/middleware.ts +0 -148
  78. package/src/models/anthropic/presets.ts +0 -191
  79. package/src/models/catalog.ts +0 -13
  80. package/src/models/cohere/index.ts +0 -2
  81. package/src/models/cohere/middleware.test.ts +0 -138
  82. package/src/models/cohere/middleware.ts +0 -76
  83. package/src/models/cohere/presets.ts +0 -186
  84. package/src/models/google/index.ts +0 -2
  85. package/src/models/google/middleware.test.ts +0 -298
  86. package/src/models/google/middleware.ts +0 -137
  87. package/src/models/google/presets.ts +0 -118
  88. package/src/models/meta/index.ts +0 -1
  89. package/src/models/meta/presets.ts +0 -143
  90. package/src/models/openai/index.ts +0 -2
  91. package/src/models/openai/middleware.test.ts +0 -189
  92. package/src/models/openai/middleware.ts +0 -103
  93. package/src/models/openai/presets.ts +0 -280
  94. package/src/models/types.ts +0 -114
  95. package/src/models/voyage/index.ts +0 -2
  96. package/src/models/voyage/middleware.test.ts +0 -28
  97. package/src/models/voyage/middleware.ts +0 -23
  98. package/src/models/voyage/presets.ts +0 -126
  99. package/src/providers/anthropic/canonical.ts +0 -17
  100. package/src/providers/anthropic/index.ts +0 -1
  101. package/src/providers/bedrock/canonical.ts +0 -87
  102. package/src/providers/bedrock/index.ts +0 -2
  103. package/src/providers/bedrock/middleware.test.ts +0 -303
  104. package/src/providers/bedrock/middleware.ts +0 -128
  105. package/src/providers/cohere/canonical.ts +0 -26
  106. package/src/providers/cohere/index.ts +0 -1
  107. package/src/providers/groq/canonical.ts +0 -21
  108. package/src/providers/groq/index.ts +0 -1
  109. package/src/providers/openai/canonical.ts +0 -16
  110. package/src/providers/openai/index.ts +0 -1
  111. package/src/providers/registry.test.ts +0 -44
  112. package/src/providers/registry.ts +0 -165
  113. package/src/providers/types.ts +0 -20
  114. package/src/providers/vertex/canonical.ts +0 -17
  115. package/src/providers/vertex/index.ts +0 -1
  116. package/src/providers/voyage/canonical.ts +0 -16
  117. package/src/providers/voyage/index.ts +0 -1
  118. package/src/telemetry/ai-sdk.ts +0 -46
  119. package/src/telemetry/baggage.ts +0 -27
  120. package/src/telemetry/fetch.ts +0 -62
  121. package/src/telemetry/gen-ai.ts +0 -113
  122. package/src/telemetry/http.ts +0 -62
  123. package/src/telemetry/index.ts +0 -1
  124. package/src/telemetry/memory.ts +0 -36
  125. package/src/telemetry/span.ts +0 -85
  126. package/src/telemetry/stream.ts +0 -64
  127. package/src/types.ts +0 -223
  128. package/src/utils/env.ts +0 -7
  129. package/src/utils/headers.ts +0 -27
  130. package/src/utils/preset.ts +0 -65
  131. package/src/utils/request.test.ts +0 -75
  132. package/src/utils/request.ts +0 -52
  133. package/src/utils/response.ts +0 -84
  134. package/src/utils/url.ts +0 -26
@@ -1,643 +0,0 @@
1
- import { MockLanguageModelV3 } from "ai/test";
2
- import { expect, test } from "bun:test";
3
-
4
- import { modelMiddlewareMatcher } from "../../middleware/matcher";
5
- import { CANONICAL_MODEL_IDS } from "../../models/types";
6
- import { claudePromptCachingMiddleware, claudeReasoningMiddleware } from "./middleware";
7
-
8
- test("claudeReasoningMiddleware > matching patterns", () => {
9
- const matching = [
10
- "anthropic/claude-opus-4.6",
11
- "anthropic/claude-sonnet-4.6",
12
- "anthropic/claude-sonnet-3.7",
13
- "anthropic/claude-opus-4.5",
14
- "anthropic/claude-sonnet-4.5",
15
- "anthropic/claude-haiku-4.5",
16
- "anthropic/claude-opus-4.1",
17
- "anthropic/claude-sonnet-4",
18
- "anthropic/claude-opus-4",
19
- ] satisfies (typeof CANONICAL_MODEL_IDS)[number][];
20
-
21
- const nonMatching = [
22
- "anthropic/claude-sonnet-3.5",
23
- "anthropic/claude-haiku-3.5",
24
- "anthropic/claude-haiku-3",
25
- ] satisfies (typeof CANONICAL_MODEL_IDS)[number][];
26
-
27
- for (const id of matching) {
28
- const middleware = modelMiddlewareMatcher.resolve({ kind: "text", modelId: id });
29
- expect(middleware).toContain(claudeReasoningMiddleware);
30
- expect(middleware).toContain(claudePromptCachingMiddleware);
31
- }
32
-
33
- for (const id of nonMatching) {
34
- const middleware = modelMiddlewareMatcher.resolve({ kind: "text", modelId: id });
35
- expect(middleware).not.toContain(claudeReasoningMiddleware);
36
- }
37
- });
38
-
39
- test("claudePromptCachingMiddleware > should not auto-enable top-level cache control", async () => {
40
- const params = {
41
- prompt: [],
42
- providerOptions: {
43
- unknown: {},
44
- },
45
- };
46
-
47
- const result = await claudePromptCachingMiddleware.transformParams!({
48
- type: "generate",
49
- params,
50
- model: new MockLanguageModelV3({ modelId: "anthropic/claude-sonnet-4.6" }),
51
- });
52
-
53
- expect(result.providerOptions).toEqual({
54
- unknown: {},
55
- });
56
- });
57
-
58
- test("claudePromptCachingMiddleware > should map cache_control ttl", async () => {
59
- const params = {
60
- prompt: [],
61
- providerOptions: {
62
- unknown: {
63
- cache_control: { type: "ephemeral", ttl: "1h" },
64
- },
65
- },
66
- };
67
-
68
- const result = await claudePromptCachingMiddleware.transformParams!({
69
- type: "generate",
70
- params,
71
- model: new MockLanguageModelV3({ modelId: "anthropic/claude-sonnet-4.6" }),
72
- });
73
-
74
- expect(result.providerOptions).toEqual({
75
- anthropic: {
76
- cacheControl: { type: "ephemeral", ttl: "1h" },
77
- },
78
- unknown: {},
79
- });
80
- });
81
-
82
- test("claudeReasoningMiddleware > should transform reasoning_effort string to thinking budget", async () => {
83
- const params = {
84
- prompt: [],
85
- maxOutputTokens: 10000,
86
- providerOptions: {
87
- unknown: {
88
- reasoning: { enabled: true, effort: "high" },
89
- },
90
- },
91
- };
92
-
93
- const result = await claudeReasoningMiddleware.transformParams!({
94
- type: "generate",
95
- params,
96
- model: new MockLanguageModelV3(),
97
- });
98
-
99
- expect(result).toEqual({
100
- prompt: [],
101
- maxOutputTokens: 10000,
102
- providerOptions: {
103
- anthropic: {
104
- thinking: {
105
- type: "enabled",
106
- budgetTokens: 8000,
107
- },
108
- },
109
- unknown: {},
110
- },
111
- });
112
- });
113
-
114
- test("claudeReasoningMiddleware > should respect Anthropic minimum budget of 1024", async () => {
115
- const params = {
116
- prompt: [],
117
- maxOutputTokens: 2000,
118
- providerOptions: {
119
- unknown: {
120
- reasoning: { enabled: true, effort: "minimal" },
121
- },
122
- },
123
- };
124
-
125
- const result = await claudeReasoningMiddleware.transformParams!({
126
- type: "generate",
127
- params,
128
- model: new MockLanguageModelV3(),
129
- });
130
-
131
- expect(result).toEqual({
132
- prompt: [],
133
- maxOutputTokens: 2000,
134
- providerOptions: {
135
- anthropic: {
136
- thinking: {
137
- type: "enabled",
138
- budgetTokens: 1024,
139
- },
140
- },
141
- unknown: {},
142
- },
143
- });
144
- });
145
-
146
- test("claudeReasoningMiddleware > should transform reasoning object to thinking budget", async () => {
147
- const params = {
148
- prompt: [],
149
- providerOptions: {
150
- unknown: {
151
- reasoning: {
152
- enabled: true,
153
- effort: "medium",
154
- max_tokens: 2000,
155
- },
156
- },
157
- },
158
- };
159
-
160
- const result = await claudeReasoningMiddleware.transformParams!({
161
- type: "generate",
162
- params,
163
- model: new MockLanguageModelV3(),
164
- });
165
-
166
- expect(result).toEqual({
167
- prompt: [],
168
- providerOptions: {
169
- anthropic: {
170
- thinking: {
171
- type: "enabled",
172
- budgetTokens: 2000,
173
- },
174
- },
175
- unknown: {},
176
- },
177
- });
178
- });
179
-
180
- test("claudeReasoningMiddleware > should handle disabled reasoning", async () => {
181
- const params = {
182
- prompt: [],
183
- providerOptions: {
184
- unknown: {
185
- reasoning: {
186
- enabled: false,
187
- },
188
- },
189
- },
190
- };
191
-
192
- const result = await claudeReasoningMiddleware.transformParams!({
193
- type: "generate",
194
- params,
195
- model: new MockLanguageModelV3(),
196
- });
197
-
198
- expect(result).toEqual({
199
- prompt: [],
200
- providerOptions: {
201
- anthropic: {
202
- thinking: {
203
- type: "disabled",
204
- },
205
- },
206
- unknown: {},
207
- },
208
- });
209
- });
210
-
211
- test("claudeReasoningMiddleware > should default reasoning budget when enabled without effort", async () => {
212
- const params = {
213
- prompt: [],
214
- maxOutputTokens: 10000,
215
- providerOptions: {
216
- unknown: {
217
- reasoning: {
218
- enabled: true,
219
- },
220
- },
221
- },
222
- };
223
-
224
- const result = await claudeReasoningMiddleware.transformParams!({
225
- type: "generate",
226
- params,
227
- model: new MockLanguageModelV3(),
228
- });
229
-
230
- expect(result).toEqual({
231
- prompt: [],
232
- maxOutputTokens: 10000,
233
- providerOptions: {
234
- anthropic: {
235
- thinking: {
236
- type: "enabled",
237
- },
238
- },
239
- unknown: {},
240
- },
241
- });
242
- });
243
-
244
- test("claudeReasoningMiddleware > should use 64k as default fallback for maxOutputTokens", async () => {
245
- const params = {
246
- prompt: [],
247
- providerOptions: {
248
- unknown: {
249
- reasoning: {
250
- // 0.5 * 64000 = 32000
251
- enabled: true,
252
- effort: "medium",
253
- },
254
- },
255
- },
256
- };
257
-
258
- const result = await claudeReasoningMiddleware.transformParams!({
259
- type: "generate",
260
- params,
261
- model: new MockLanguageModelV3(),
262
- });
263
-
264
- expect(result.providerOptions?.anthropic?.thinking?.budgetTokens).toBe(32000);
265
- });
266
-
267
- test("claudeReasoningMiddleware > should cap default maxOutputTokens for Opus 4.1", async () => {
268
- const params = {
269
- prompt: [],
270
- providerOptions: {
271
- unknown: {
272
- reasoning: {
273
- enabled: true,
274
- effort: "medium",
275
- },
276
- },
277
- },
278
- };
279
-
280
- const result = await claudeReasoningMiddleware.transformParams!({
281
- type: "generate",
282
- params,
283
- model: new MockLanguageModelV3({ modelId: "anthropic/claude-opus-4.1" }),
284
- });
285
-
286
- expect(result.providerOptions?.anthropic?.thinking?.budgetTokens).toBe(16000);
287
- });
288
-
289
- test("claudeReasoningMiddleware > should clamp max_tokens for Opus 4", async () => {
290
- const params = {
291
- prompt: [],
292
- providerOptions: {
293
- unknown: {
294
- reasoning: {
295
- enabled: true,
296
- max_tokens: 50000,
297
- },
298
- },
299
- },
300
- };
301
-
302
- const result = await claudeReasoningMiddleware.transformParams!({
303
- type: "generate",
304
- params,
305
- model: new MockLanguageModelV3({ modelId: "anthropic/claude-opus-4" }),
306
- });
307
-
308
- expect(result.providerOptions?.anthropic?.thinking?.budgetTokens).toBe(32000);
309
- });
310
-
311
- test("claudeReasoningMiddleware > should pass through max effort for Claude 4.6", async () => {
312
- const params = {
313
- prompt: [],
314
- providerOptions: {
315
- unknown: {
316
- reasoning: {
317
- enabled: true,
318
- effort: "max",
319
- },
320
- },
321
- },
322
- };
323
-
324
- const result = await claudeReasoningMiddleware.transformParams!({
325
- type: "generate",
326
- params,
327
- model: new MockLanguageModelV3({ modelId: "anthropic/claude-opus-4.6" }),
328
- });
329
-
330
- expect(result.providerOptions?.anthropic?.thinking).toEqual({
331
- type: "adaptive",
332
- });
333
- expect(result.providerOptions?.anthropic?.effort).toBe("max");
334
- });
335
-
336
- test("claudeReasoningMiddleware > should map xhigh effort to max for Claude Opus 4.6", async () => {
337
- const params = {
338
- prompt: [],
339
- providerOptions: {
340
- unknown: {
341
- reasoning: {
342
- enabled: true,
343
- effort: "xhigh",
344
- },
345
- },
346
- },
347
- };
348
-
349
- const result = await claudeReasoningMiddleware.transformParams!({
350
- type: "generate",
351
- params,
352
- model: new MockLanguageModelV3({ modelId: "anthropic/claude-opus-4.6" }),
353
- });
354
-
355
- expect(result.providerOptions?.anthropic?.thinking).toEqual({
356
- type: "adaptive",
357
- });
358
- expect(result.providerOptions?.anthropic?.effort).toBe("max");
359
- });
360
-
361
- test("claudeReasoningMiddleware > should map max effort to high for Claude Sonnet 4.6", async () => {
362
- const params = {
363
- prompt: [],
364
- providerOptions: {
365
- unknown: {
366
- reasoning: {
367
- enabled: true,
368
- effort: "max",
369
- },
370
- },
371
- },
372
- };
373
-
374
- const result = await claudeReasoningMiddleware.transformParams!({
375
- type: "generate",
376
- params,
377
- model: new MockLanguageModelV3({ modelId: "anthropic/claude-sonnet-4.6" }),
378
- });
379
-
380
- expect(result.providerOptions?.anthropic?.thinking).toEqual({
381
- type: "adaptive",
382
- });
383
- expect(result.providerOptions?.anthropic?.effort).toBe("high");
384
- });
385
-
386
- test("claudeReasoningMiddleware > should map minimal effort to low for Claude Sonnet 4.6", async () => {
387
- const params = {
388
- prompt: [],
389
- providerOptions: {
390
- unknown: {
391
- reasoning: {
392
- enabled: true,
393
- effort: "minimal",
394
- },
395
- },
396
- },
397
- };
398
-
399
- const result = await claudeReasoningMiddleware.transformParams!({
400
- type: "generate",
401
- params,
402
- model: new MockLanguageModelV3({ modelId: "anthropic/claude-sonnet-4.6" }),
403
- });
404
-
405
- expect(result.providerOptions?.anthropic?.thinking).toEqual({
406
- type: "adaptive",
407
- });
408
- expect(result.providerOptions?.anthropic?.effort).toBe("low");
409
- });
410
-
411
- test("claudeReasoningMiddleware > should use manual thinking for Claude Sonnet 4.6 when max_tokens is provided", async () => {
412
- const params = {
413
- prompt: [],
414
- providerOptions: {
415
- unknown: {
416
- reasoning: {
417
- enabled: true,
418
- effort: "medium",
419
- max_tokens: 2000,
420
- },
421
- },
422
- },
423
- };
424
-
425
- const result = await claudeReasoningMiddleware.transformParams!({
426
- type: "generate",
427
- params,
428
- model: new MockLanguageModelV3({ modelId: "anthropic/claude-sonnet-4.6" }),
429
- });
430
-
431
- expect(result.providerOptions?.anthropic?.thinking).toEqual({
432
- type: "enabled",
433
- budgetTokens: 2000,
434
- });
435
- expect(result.providerOptions?.anthropic?.effort).toBe("medium");
436
- });
437
-
438
- test("claudeReasoningMiddleware > should map none effort to low for Claude Sonnet 4.5", async () => {
439
- const params = {
440
- prompt: [],
441
- providerOptions: {
442
- unknown: {
443
- reasoning: {
444
- enabled: true,
445
- effort: "none",
446
- },
447
- },
448
- },
449
- };
450
-
451
- const result = await claudeReasoningMiddleware.transformParams!({
452
- type: "generate",
453
- params,
454
- model: new MockLanguageModelV3({ modelId: "anthropic/claude-sonnet-4.5" }),
455
- });
456
-
457
- expect(result.providerOptions?.anthropic?.thinking).toEqual({
458
- type: "enabled",
459
- budgetTokens: 1024,
460
- });
461
- expect(result.providerOptions?.anthropic?.effort).toBe("low");
462
- });
463
-
464
- test("claudeReasoningMiddleware > should include effort and max_tokens for Claude 4.6", async () => {
465
- const params = {
466
- prompt: [],
467
- providerOptions: {
468
- unknown: {
469
- reasoning: {
470
- enabled: true,
471
- effort: "medium",
472
- max_tokens: 2000,
473
- },
474
- },
475
- },
476
- };
477
-
478
- const result = await claudeReasoningMiddleware.transformParams!({
479
- type: "generate",
480
- params,
481
- model: new MockLanguageModelV3({ modelId: "anthropic/claude-opus-4.6" }),
482
- });
483
-
484
- expect(result.providerOptions?.anthropic?.thinking).toEqual({
485
- type: "adaptive",
486
- budgetTokens: 2000,
487
- });
488
- expect(result.providerOptions?.anthropic?.effort).toBe("medium");
489
- });
490
-
491
- test("claudeReasoningMiddleware > should clamp max_tokens to 128k for Claude Opus 4.6", async () => {
492
- const params = {
493
- prompt: [],
494
- providerOptions: {
495
- unknown: {
496
- reasoning: {
497
- enabled: true,
498
- effort: "medium",
499
- max_tokens: 200000,
500
- },
501
- },
502
- },
503
- };
504
-
505
- const result = await claudeReasoningMiddleware.transformParams!({
506
- type: "generate",
507
- params,
508
- model: new MockLanguageModelV3({ modelId: "anthropic/claude-opus-4.6" }),
509
- });
510
-
511
- expect(result.providerOptions?.anthropic?.thinking).toEqual({
512
- type: "adaptive",
513
- budgetTokens: 128000,
514
- });
515
- expect(result.providerOptions?.anthropic?.effort).toBe("medium");
516
- });
517
-
518
- test("claudeReasoningMiddleware > should include effort and max_tokens for Claude Sonnet 4.5", async () => {
519
- const params = {
520
- prompt: [],
521
- providerOptions: {
522
- unknown: {
523
- reasoning: {
524
- enabled: true,
525
- effort: "medium",
526
- max_tokens: 2000,
527
- },
528
- },
529
- },
530
- };
531
-
532
- const result = await claudeReasoningMiddleware.transformParams!({
533
- type: "generate",
534
- params,
535
- model: new MockLanguageModelV3({ modelId: "anthropic/claude-sonnet-4.5" }),
536
- });
537
-
538
- expect(result.providerOptions?.anthropic?.thinking).toEqual({
539
- type: "enabled",
540
- budgetTokens: 2000,
541
- });
542
- expect(result.providerOptions?.anthropic?.effort).toBe("medium");
543
- });
544
-
545
- test("claudeReasoningMiddleware > should map max effort to high for Claude Sonnet 4.5", async () => {
546
- const params = {
547
- prompt: [],
548
- providerOptions: {
549
- unknown: {
550
- reasoning: {
551
- enabled: true,
552
- effort: "max",
553
- },
554
- },
555
- },
556
- };
557
-
558
- const result = await claudeReasoningMiddleware.transformParams!({
559
- type: "generate",
560
- params,
561
- model: new MockLanguageModelV3({ modelId: "anthropic/claude-sonnet-4.5" }),
562
- });
563
-
564
- expect(result.providerOptions?.anthropic?.thinking).toEqual({
565
- type: "enabled",
566
- budgetTokens: 60800,
567
- });
568
- expect(result.providerOptions?.anthropic?.effort).toBe("high");
569
- });
570
-
571
- test("claudeReasoningMiddleware > should map xhigh effort to high for Claude Sonnet 4.5", async () => {
572
- const params = {
573
- prompt: [],
574
- providerOptions: {
575
- unknown: {
576
- reasoning: {
577
- enabled: true,
578
- effort: "xhigh",
579
- },
580
- },
581
- },
582
- };
583
-
584
- const result = await claudeReasoningMiddleware.transformParams!({
585
- type: "generate",
586
- params,
587
- model: new MockLanguageModelV3({ modelId: "anthropic/claude-sonnet-4.5" }),
588
- });
589
-
590
- expect(result.providerOptions?.anthropic?.thinking).toEqual({
591
- type: "enabled",
592
- budgetTokens: 60800,
593
- });
594
- expect(result.providerOptions?.anthropic?.effort).toBe("high");
595
- });
596
-
597
- test("claudeReasoningMiddleware > should keep xhigh as budget for non-4.6 models", async () => {
598
- const params = {
599
- prompt: [],
600
- providerOptions: {
601
- unknown: {
602
- reasoning: {
603
- enabled: true,
604
- effort: "xhigh",
605
- },
606
- },
607
- },
608
- };
609
-
610
- const result = await claudeReasoningMiddleware.transformParams!({
611
- type: "generate",
612
- params,
613
- model: new MockLanguageModelV3({ modelId: "anthropic/claude-sonnet-4" }),
614
- });
615
-
616
- expect(result.providerOptions?.anthropic?.thinking?.budgetTokens).toBe(60800);
617
- });
618
-
619
- test("claudeReasoningMiddleware > should map xhigh effort for Claude Opus 4.5 without default budget", async () => {
620
- const params = {
621
- prompt: [],
622
- providerOptions: {
623
- unknown: {
624
- reasoning: {
625
- enabled: true,
626
- effort: "xhigh",
627
- },
628
- },
629
- },
630
- };
631
-
632
- const result = await claudeReasoningMiddleware.transformParams!({
633
- type: "generate",
634
- params,
635
- model: new MockLanguageModelV3({ modelId: "anthropic/claude-opus-4.5" }),
636
- });
637
-
638
- expect(result.providerOptions?.anthropic?.thinking).toEqual({
639
- type: "enabled",
640
- budgetTokens: 60800,
641
- });
642
- expect(result.providerOptions?.anthropic?.effort).toBe("high");
643
- });