@llmgateway/models 1.1.0 → 1.1.1

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 (34) hide show
  1. package/dist/get-cheapest-from-available-providers.d.ts +30 -0
  2. package/dist/get-cheapest-from-available-providers.js +183 -0
  3. package/dist/get-cheapest-from-available-providers.js.map +1 -0
  4. package/dist/get-cheapest-model-for-provider.d.ts +2 -0
  5. package/dist/get-cheapest-model-for-provider.js +49 -0
  6. package/dist/get-cheapest-model-for-provider.js.map +1 -0
  7. package/dist/get-provider-endpoint.d.ts +3 -0
  8. package/dist/get-provider-endpoint.js +243 -0
  9. package/dist/get-provider-endpoint.js.map +1 -0
  10. package/dist/get-provider-headers.d.ts +5 -0
  11. package/dist/get-provider-headers.js +45 -0
  12. package/dist/get-provider-headers.js.map +1 -0
  13. package/dist/models.spec.d.ts +1 -0
  14. package/dist/models.spec.js +263 -0
  15. package/dist/models.spec.js.map +1 -0
  16. package/dist/prepare-request-body.d.ts +10 -0
  17. package/dist/prepare-request-body.js +1081 -0
  18. package/dist/prepare-request-body.js.map +1 -0
  19. package/dist/prepare-request-body.spec.d.ts +1 -0
  20. package/dist/prepare-request-body.spec.js +231 -0
  21. package/dist/prepare-request-body.spec.js.map +1 -0
  22. package/dist/process-image-url.d.ts +4 -0
  23. package/dist/process-image-url.js +121 -0
  24. package/dist/process-image-url.js.map +1 -0
  25. package/dist/transform-anthropic-messages.d.ts +2 -0
  26. package/dist/transform-anthropic-messages.js +185 -0
  27. package/dist/transform-anthropic-messages.js.map +1 -0
  28. package/dist/transform-google-messages.d.ts +25 -0
  29. package/dist/transform-google-messages.js +122 -0
  30. package/dist/transform-google-messages.js.map +1 -0
  31. package/dist/validate-provider-key.d.ts +4 -0
  32. package/dist/validate-provider-key.js +113 -0
  33. package/dist/validate-provider-key.js.map +1 -0
  34. package/package.json +1 -1
@@ -0,0 +1,1081 @@
1
+ import { models, } from "./models.js";
2
+ import { transformAnthropicMessages } from "./transform-anthropic-messages.js";
3
+ import { transformGoogleMessages } from "./transform-google-messages.js";
4
+ function isFunctionTool(tool) {
5
+ return tool.type === "function";
6
+ }
7
+ function convertOpenAISchemaToGoogle(schema) {
8
+ if (!schema || typeof schema !== "object") {
9
+ return schema;
10
+ }
11
+ const converted = {};
12
+ if (schema.type) {
13
+ converted.type = schema.type.toUpperCase();
14
+ }
15
+ if (schema.description) {
16
+ converted.description = schema.description;
17
+ }
18
+ if (schema.properties) {
19
+ converted.properties = {};
20
+ for (const [key, value] of Object.entries(schema.properties)) {
21
+ converted.properties[key] = convertOpenAISchemaToGoogle(value);
22
+ }
23
+ }
24
+ if (schema.items) {
25
+ converted.items = convertOpenAISchemaToGoogle(schema.items);
26
+ }
27
+ if (schema.required) {
28
+ converted.required = schema.required;
29
+ }
30
+ if (schema.enum) {
31
+ converted.enum = schema.enum;
32
+ }
33
+ if (schema.format) {
34
+ converted.format = schema.format;
35
+ }
36
+ return converted;
37
+ }
38
+ function sanitizeCerebrasSchema(schema) {
39
+ if (!schema || typeof schema !== "object") {
40
+ return schema;
41
+ }
42
+ if (Array.isArray(schema)) {
43
+ return schema.map((item) => sanitizeCerebrasSchema(item));
44
+ }
45
+ const result = { ...schema };
46
+ if (result.type === "object") {
47
+ result.additionalProperties = false;
48
+ }
49
+ if (result.type === "string") {
50
+ delete result.format;
51
+ delete result.minLength;
52
+ delete result.maxLength;
53
+ delete result.pattern;
54
+ }
55
+ if (result.properties) {
56
+ result.properties = Object.fromEntries(Object.entries(result.properties).map(([key, value]) => [
57
+ key,
58
+ sanitizeCerebrasSchema(value),
59
+ ]));
60
+ }
61
+ if (result.items) {
62
+ result.items = sanitizeCerebrasSchema(result.items);
63
+ }
64
+ for (const key of ["anyOf", "oneOf", "allOf"]) {
65
+ if (result[key] && Array.isArray(result[key])) {
66
+ result[key] = result[key].map((item) => sanitizeCerebrasSchema(item));
67
+ }
68
+ }
69
+ if (result.$defs) {
70
+ result.$defs = Object.fromEntries(Object.entries(result.$defs).map(([key, value]) => [
71
+ key,
72
+ sanitizeCerebrasSchema(value),
73
+ ]));
74
+ }
75
+ if (result.definitions) {
76
+ result.definitions = Object.fromEntries(Object.entries(result.definitions).map(([key, value]) => [
77
+ key,
78
+ sanitizeCerebrasSchema(value),
79
+ ]));
80
+ }
81
+ return result;
82
+ }
83
+ function resolveRef(ref, rootDefs) {
84
+ const match = ref.match(/^#\/(\$defs|definitions)\/(.+)$/);
85
+ if (match) {
86
+ const defName = match[2];
87
+ return rootDefs[defName];
88
+ }
89
+ return null;
90
+ }
91
+ function stripUnsupportedSchemaProperties(schema, rootDefs) {
92
+ if (!schema || typeof schema !== "object") {
93
+ return schema;
94
+ }
95
+ if (Array.isArray(schema)) {
96
+ return schema.map((item) => stripUnsupportedSchemaProperties(item, rootDefs));
97
+ }
98
+ const defs = rootDefs ?? schema.$defs ?? schema.definitions ?? {};
99
+ if (schema.$ref) {
100
+ const resolved = resolveRef(schema.$ref, defs);
101
+ if (resolved) {
102
+ const expanded = stripUnsupportedSchemaProperties({ ...resolved }, defs);
103
+ if (schema.description && !expanded.description) {
104
+ expanded.description = schema.description;
105
+ }
106
+ if (schema.default !== undefined && expanded.default === undefined) {
107
+ expanded.default = schema.default;
108
+ }
109
+ return expanded;
110
+ }
111
+ }
112
+ const cleaned = {};
113
+ for (const [key, value] of Object.entries(schema)) {
114
+ if (key === "additionalProperties" ||
115
+ key === "$schema" ||
116
+ key === "$defs" ||
117
+ key === "definitions" ||
118
+ key === "$ref" ||
119
+ key === "ref" ||
120
+ key === "maxLength" ||
121
+ key === "minLength" ||
122
+ key === "minimum" ||
123
+ key === "maximum" ||
124
+ key === "pattern") {
125
+ continue;
126
+ }
127
+ if (value && typeof value === "object") {
128
+ cleaned[key] = stripUnsupportedSchemaProperties(value, defs);
129
+ }
130
+ else {
131
+ cleaned[key] = value;
132
+ }
133
+ }
134
+ if (cleaned.required &&
135
+ Array.isArray(cleaned.required) &&
136
+ cleaned.properties) {
137
+ const existingProps = Object.keys(cleaned.properties);
138
+ cleaned.required = cleaned.required.filter((prop) => existingProps.includes(prop));
139
+ if (cleaned.required.length === 0) {
140
+ delete cleaned.required;
141
+ }
142
+ }
143
+ return cleaned;
144
+ }
145
+ function transformMessagesForNoSystemRole(messages) {
146
+ return messages.map((message) => {
147
+ if (message.role === "system") {
148
+ return {
149
+ ...message,
150
+ role: "user",
151
+ };
152
+ }
153
+ return message;
154
+ });
155
+ }
156
+ function transformContentForResponsesApi(content, role) {
157
+ if (typeof content === "string") {
158
+ if (role === "assistant") {
159
+ return [{ type: "output_text", text: content }];
160
+ }
161
+ return [{ type: "input_text", text: content }];
162
+ }
163
+ if (Array.isArray(content)) {
164
+ return content.map((part) => {
165
+ if (part.type === "text") {
166
+ if (role === "assistant") {
167
+ return { type: "output_text", text: part.text };
168
+ }
169
+ return { type: "input_text", text: part.text };
170
+ }
171
+ if (part.type === "image_url") {
172
+ const imageUrl = part.image_url?.url || part.image_url;
173
+ if (typeof imageUrl === "string" && imageUrl.startsWith("data:")) {
174
+ const matches = imageUrl.match(/^data:([^;]+);base64,(.+)$/);
175
+ if (matches) {
176
+ return {
177
+ type: "input_image",
178
+ image_url: imageUrl,
179
+ };
180
+ }
181
+ }
182
+ return {
183
+ type: "input_image",
184
+ image_url: imageUrl,
185
+ };
186
+ }
187
+ return part;
188
+ });
189
+ }
190
+ return content;
191
+ }
192
+ function transformMessagesForResponsesApi(messages) {
193
+ return messages.map((msg) => {
194
+ const transformed = {
195
+ role: msg.role,
196
+ };
197
+ if (transformed.role === "tool") {
198
+ transformed.role = "user";
199
+ }
200
+ transformed.content = transformContentForResponsesApi(msg.content, transformed.role);
201
+ if (msg.name) {
202
+ transformed.name = msg.name;
203
+ }
204
+ return transformed;
205
+ });
206
+ }
207
+ export async function prepareRequestBody(usedProvider, usedModel, messages, stream, temperature, max_tokens, top_p, frequency_penalty, presence_penalty, response_format, tools, tool_choice, reasoning_effort, supportsReasoning, isProd = false, maxImageSizeMB = 20, userPlan = null, sensitive_word_check, image_config, effort, imageGenerations, webSearchTool) {
208
+ if (imageGenerations && usedProvider === "zai") {
209
+ const lastUserMessage = [...messages]
210
+ .reverse()
211
+ .find((m) => m.role === "user");
212
+ let prompt = "";
213
+ if (lastUserMessage) {
214
+ if (typeof lastUserMessage.content === "string") {
215
+ prompt = lastUserMessage.content;
216
+ }
217
+ else if (Array.isArray(lastUserMessage.content)) {
218
+ prompt = lastUserMessage.content
219
+ .filter((p) => p.type === "text")
220
+ .map((p) => p.text)
221
+ .join("\n");
222
+ }
223
+ }
224
+ const zaiImageRequest = {
225
+ model: usedModel,
226
+ prompt,
227
+ ...(image_config?.image_size && { size: image_config.image_size }),
228
+ ...(image_config?.n && { n: image_config.n }),
229
+ };
230
+ return zaiImageRequest;
231
+ }
232
+ if (imageGenerations && usedProvider === "alibaba") {
233
+ const lastUserMessage = [...messages]
234
+ .reverse()
235
+ .find((m) => m.role === "user");
236
+ let prompt = "";
237
+ if (lastUserMessage) {
238
+ if (typeof lastUserMessage.content === "string") {
239
+ prompt = lastUserMessage.content;
240
+ }
241
+ else if (Array.isArray(lastUserMessage.content)) {
242
+ prompt = lastUserMessage.content
243
+ .filter((p) => p.type === "text")
244
+ .map((p) => p.text)
245
+ .join("\n");
246
+ }
247
+ }
248
+ const alibabaImageRequest = {
249
+ model: usedModel,
250
+ input: {
251
+ messages: [
252
+ {
253
+ role: "user",
254
+ content: [{ text: prompt }],
255
+ },
256
+ ],
257
+ },
258
+ parameters: {
259
+ watermark: false,
260
+ ...(image_config?.n && { n: image_config.n }),
261
+ ...(image_config?.seed !== undefined && { seed: image_config.seed }),
262
+ },
263
+ };
264
+ if (image_config?.image_size) {
265
+ alibabaImageRequest.parameters.size = image_config.image_size.replace("x", "*");
266
+ }
267
+ return alibabaImageRequest;
268
+ }
269
+ if (imageGenerations && usedProvider === "bytedance") {
270
+ const lastUserMessage = [...messages]
271
+ .reverse()
272
+ .find((m) => m.role === "user");
273
+ let prompt = "";
274
+ if (lastUserMessage) {
275
+ if (typeof lastUserMessage.content === "string") {
276
+ prompt = lastUserMessage.content;
277
+ }
278
+ else if (Array.isArray(lastUserMessage.content)) {
279
+ prompt = lastUserMessage.content
280
+ .filter((p) => p.type === "text")
281
+ .map((p) => p.text)
282
+ .join("\n");
283
+ }
284
+ }
285
+ const bytedanceImageRequest = {
286
+ model: usedModel,
287
+ prompt,
288
+ ...(image_config?.image_size && { size: image_config.image_size }),
289
+ };
290
+ return bytedanceImageRequest;
291
+ }
292
+ const modelDef = models.find((m) => m.id === usedModel ||
293
+ m.providers.some((p) => p.modelName === usedModel && p.providerId === usedProvider));
294
+ const supportsSystemRole = modelDef?.supportsSystemRole !== false;
295
+ let processedMessages = messages;
296
+ if (!supportsSystemRole) {
297
+ processedMessages = transformMessagesForNoSystemRole(messages);
298
+ }
299
+ const requestBody = {
300
+ model: usedModel,
301
+ messages: processedMessages,
302
+ stream: stream,
303
+ };
304
+ if (tools && tools.length > 0) {
305
+ const functionTools = tools.filter(isFunctionTool);
306
+ if (functionTools.length > 0) {
307
+ requestBody.tools = functionTools;
308
+ }
309
+ }
310
+ if (tool_choice) {
311
+ requestBody.tool_choice = tool_choice;
312
+ }
313
+ if (usedModel.startsWith("gpt-5")) {
314
+ temperature = 1;
315
+ }
316
+ if (modelDef?.family === "openai" &&
317
+ max_tokens !== undefined &&
318
+ max_tokens < 16) {
319
+ max_tokens = 16;
320
+ }
321
+ switch (usedProvider) {
322
+ case "openai": {
323
+ const providerMapping = modelDef?.providers.find((p) => p.providerId === "openai");
324
+ const supportsResponsesApi = providerMapping?.supportsResponsesApi ===
325
+ true;
326
+ if (supportsResponsesApi) {
327
+ const defaultEffort = usedModel === "gpt-5-pro" ? "high" : "medium";
328
+ const transformedMessages = transformMessagesForResponsesApi(processedMessages);
329
+ const responsesBody = {
330
+ model: usedModel,
331
+ input: transformedMessages,
332
+ reasoning: {
333
+ effort: reasoning_effort || defaultEffort,
334
+ summary: "detailed",
335
+ },
336
+ };
337
+ if (stream) {
338
+ responsesBody.stream = true;
339
+ }
340
+ if (tools && tools.length > 0) {
341
+ const functionTools = tools.filter(isFunctionTool);
342
+ if (functionTools.length > 0) {
343
+ responsesBody.tools = functionTools.map((tool) => ({
344
+ type: "function",
345
+ name: tool.function.name,
346
+ description: tool.function.description,
347
+ parameters: tool.function.parameters,
348
+ }));
349
+ }
350
+ }
351
+ if (webSearchTool) {
352
+ if (!responsesBody.tools) {
353
+ responsesBody.tools = [];
354
+ }
355
+ const webSearch = { type: "web_search" };
356
+ if (webSearchTool.user_location) {
357
+ webSearch.user_location = webSearchTool.user_location;
358
+ }
359
+ if (webSearchTool.search_context_size) {
360
+ webSearch.search_context_size = webSearchTool.search_context_size;
361
+ }
362
+ responsesBody.tools.push(webSearch);
363
+ }
364
+ if (tool_choice) {
365
+ responsesBody.tool_choice = tool_choice;
366
+ }
367
+ if (temperature !== undefined) {
368
+ responsesBody.temperature = temperature;
369
+ }
370
+ if (max_tokens !== undefined) {
371
+ responsesBody.max_output_tokens = max_tokens;
372
+ }
373
+ if (response_format) {
374
+ if (response_format.type === "json_schema" &&
375
+ response_format.json_schema) {
376
+ responsesBody.text = {
377
+ format: {
378
+ type: "json_schema",
379
+ name: response_format.json_schema.name,
380
+ schema: response_format.json_schema.schema,
381
+ strict: response_format.json_schema.strict,
382
+ },
383
+ };
384
+ }
385
+ else if (response_format.type === "json_object") {
386
+ responsesBody.text = {
387
+ format: { type: "json_object" },
388
+ };
389
+ }
390
+ }
391
+ return responsesBody;
392
+ }
393
+ else {
394
+ if (stream) {
395
+ requestBody.stream_options = {
396
+ include_usage: true,
397
+ };
398
+ }
399
+ if (response_format) {
400
+ requestBody.response_format = response_format;
401
+ }
402
+ if (webSearchTool) {
403
+ if (usedModel.includes("-search-")) {
404
+ const webSearchOptions = {};
405
+ if (webSearchTool.user_location) {
406
+ webSearchOptions.user_location = {
407
+ type: "approximate",
408
+ approximate: {
409
+ city: webSearchTool.user_location.city,
410
+ region: webSearchTool.user_location.region,
411
+ country: webSearchTool.user_location.country,
412
+ },
413
+ };
414
+ }
415
+ if (webSearchTool.search_context_size) {
416
+ webSearchOptions.search_context_size =
417
+ webSearchTool.search_context_size;
418
+ }
419
+ requestBody.web_search_options =
420
+ Object.keys(webSearchOptions).length > 0 ? webSearchOptions : {};
421
+ }
422
+ else {
423
+ if (!requestBody.tools) {
424
+ requestBody.tools = [];
425
+ }
426
+ const webSearch = { type: "web_search" };
427
+ if (webSearchTool.user_location) {
428
+ webSearch.user_location = webSearchTool.user_location;
429
+ }
430
+ if (webSearchTool.search_context_size) {
431
+ webSearch.search_context_size = webSearchTool.search_context_size;
432
+ }
433
+ requestBody.tools.push(webSearch);
434
+ }
435
+ }
436
+ if (temperature !== undefined) {
437
+ requestBody.temperature = temperature;
438
+ }
439
+ if (max_tokens !== undefined) {
440
+ if (usedModel.startsWith("gpt-5")) {
441
+ requestBody.max_completion_tokens = max_tokens;
442
+ }
443
+ else {
444
+ requestBody.max_tokens = max_tokens;
445
+ }
446
+ }
447
+ if (top_p !== undefined) {
448
+ requestBody.top_p = top_p;
449
+ }
450
+ if (frequency_penalty !== undefined) {
451
+ requestBody.frequency_penalty = frequency_penalty;
452
+ }
453
+ if (presence_penalty !== undefined) {
454
+ requestBody.presence_penalty = presence_penalty;
455
+ }
456
+ if (reasoning_effort !== undefined) {
457
+ requestBody.reasoning_effort = reasoning_effort;
458
+ }
459
+ }
460
+ break;
461
+ }
462
+ case "zai": {
463
+ if (stream) {
464
+ requestBody.stream_options = {
465
+ include_usage: true,
466
+ };
467
+ }
468
+ if (response_format) {
469
+ requestBody.response_format = response_format;
470
+ }
471
+ if (webSearchTool) {
472
+ if (!requestBody.tools) {
473
+ requestBody.tools = [];
474
+ }
475
+ requestBody.tools.push({
476
+ type: "web_search",
477
+ web_search: {
478
+ enable: true,
479
+ search_engine: "search-prime",
480
+ },
481
+ });
482
+ }
483
+ if (temperature !== undefined) {
484
+ requestBody.temperature = temperature;
485
+ }
486
+ if (max_tokens !== undefined) {
487
+ requestBody.max_tokens = max_tokens;
488
+ }
489
+ if (top_p !== undefined) {
490
+ requestBody.top_p = top_p;
491
+ }
492
+ if (frequency_penalty !== undefined) {
493
+ requestBody.frequency_penalty = frequency_penalty;
494
+ }
495
+ if (presence_penalty !== undefined) {
496
+ requestBody.presence_penalty = presence_penalty;
497
+ }
498
+ if (supportsReasoning) {
499
+ requestBody.thinking = {
500
+ type: "enabled",
501
+ };
502
+ }
503
+ if (sensitive_word_check) {
504
+ requestBody.sensitive_word_check = sensitive_word_check;
505
+ }
506
+ break;
507
+ }
508
+ case "anthropic": {
509
+ delete requestBody.tool_choice;
510
+ const getThinkingBudget = (effort) => {
511
+ if (!supportsReasoning) {
512
+ return 0;
513
+ }
514
+ if (!reasoning_effort) {
515
+ return 0;
516
+ }
517
+ switch (effort) {
518
+ case "low":
519
+ return 1024;
520
+ case "high":
521
+ return 4000;
522
+ default:
523
+ return 2000;
524
+ }
525
+ };
526
+ const thinkingBudget = getThinkingBudget(reasoning_effort);
527
+ const minMaxTokens = Math.max(1024, thinkingBudget + 1000);
528
+ requestBody.max_tokens = max_tokens ?? minMaxTokens;
529
+ const systemMessages = processedMessages.filter((m) => m.role === "system");
530
+ const nonSystemMessages = processedMessages.filter((m) => m.role !== "system");
531
+ let systemCacheControlCount = 0;
532
+ const maxCacheControlBlocks = 4;
533
+ const providerMapping = modelDef?.providers.find((p) => p.providerId === usedProvider);
534
+ const minCacheableTokens = providerMapping?.minCacheableTokens ?? 1024;
535
+ const minCacheableChars = minCacheableTokens * 4;
536
+ if (systemMessages.length > 0) {
537
+ const systemContent = [];
538
+ for (const sysMsg of systemMessages) {
539
+ let text;
540
+ if (typeof sysMsg.content === "string") {
541
+ text = sysMsg.content;
542
+ }
543
+ else if (Array.isArray(sysMsg.content)) {
544
+ text = sysMsg.content
545
+ .filter((c) => c.type === "text" && "text" in c)
546
+ .map((c) => c.text)
547
+ .join("");
548
+ }
549
+ else {
550
+ continue;
551
+ }
552
+ if (!text || text.trim() === "") {
553
+ continue;
554
+ }
555
+ const shouldCache = text.length >= minCacheableChars &&
556
+ systemCacheControlCount < maxCacheControlBlocks;
557
+ if (shouldCache) {
558
+ systemCacheControlCount++;
559
+ systemContent.push({
560
+ type: "text",
561
+ text,
562
+ cache_control: { type: "ephemeral" },
563
+ });
564
+ }
565
+ else {
566
+ systemContent.push({
567
+ type: "text",
568
+ text,
569
+ });
570
+ }
571
+ }
572
+ if (systemContent.length > 0) {
573
+ requestBody.system = systemContent;
574
+ }
575
+ }
576
+ requestBody.messages = await transformAnthropicMessages(nonSystemMessages.map((m) => ({
577
+ ...m,
578
+ role: m.role === "assistant"
579
+ ? "assistant"
580
+ : m.role === "tool"
581
+ ? "user"
582
+ : "user",
583
+ content: m.content,
584
+ tool_calls: m.tool_calls,
585
+ })), isProd, usedProvider, usedModel, maxImageSizeMB, userPlan, systemCacheControlCount, minCacheableChars);
586
+ if (tools && tools.length > 0) {
587
+ const functionTools = tools.filter(isFunctionTool);
588
+ if (functionTools.length > 0) {
589
+ requestBody.tools = functionTools.map((tool) => ({
590
+ name: tool.function.name,
591
+ description: tool.function.description,
592
+ input_schema: tool.function.parameters,
593
+ }));
594
+ }
595
+ }
596
+ if (webSearchTool) {
597
+ if (!requestBody.tools) {
598
+ requestBody.tools = [];
599
+ }
600
+ const webSearch = {
601
+ type: "web_search_20250305",
602
+ name: "web_search",
603
+ };
604
+ if (webSearchTool.max_uses) {
605
+ webSearch.max_uses = webSearchTool.max_uses;
606
+ }
607
+ requestBody.tools.push(webSearch);
608
+ }
609
+ if (tool_choice) {
610
+ if (typeof tool_choice === "object" &&
611
+ tool_choice.type === "function") {
612
+ requestBody.tool_choice = {
613
+ type: "tool",
614
+ name: tool_choice.function.name,
615
+ };
616
+ }
617
+ else if (tool_choice === "auto") {
618
+ }
619
+ else if (tool_choice === "none") {
620
+ requestBody.tool_choice = tool_choice;
621
+ }
622
+ else {
623
+ requestBody.tool_choice = tool_choice;
624
+ }
625
+ }
626
+ if (supportsReasoning && reasoning_effort) {
627
+ requestBody.thinking = {
628
+ type: "enabled",
629
+ budget_tokens: thinkingBudget,
630
+ };
631
+ }
632
+ if (temperature !== undefined) {
633
+ requestBody.temperature = temperature;
634
+ }
635
+ if (top_p !== undefined) {
636
+ requestBody.top_p = top_p;
637
+ }
638
+ if (frequency_penalty !== undefined) {
639
+ requestBody.frequency_penalty = frequency_penalty;
640
+ }
641
+ if (presence_penalty !== undefined) {
642
+ requestBody.presence_penalty = presence_penalty;
643
+ }
644
+ if (effort !== undefined) {
645
+ if (!requestBody.output_config) {
646
+ requestBody.output_config = {};
647
+ }
648
+ requestBody.output_config.effort = effort;
649
+ }
650
+ if (response_format) {
651
+ if (response_format.type === "json_schema" &&
652
+ response_format.json_schema) {
653
+ const schema = {
654
+ ...response_format.json_schema.schema,
655
+ additionalProperties: false,
656
+ };
657
+ requestBody.output_format = {
658
+ type: "json_schema",
659
+ schema,
660
+ };
661
+ }
662
+ else if (response_format.type === "json_object") {
663
+ }
664
+ }
665
+ break;
666
+ }
667
+ case "aws-bedrock": {
668
+ delete requestBody.model;
669
+ delete requestBody.stream;
670
+ delete requestBody.messages;
671
+ delete requestBody.tools;
672
+ delete requestBody.tool_choice;
673
+ let bedrockCacheControlCount = 0;
674
+ const bedrockMaxCacheControlBlocks = 4;
675
+ const bedrockProviderMapping = modelDef?.providers.find((p) => p.providerId === usedProvider);
676
+ const bedrockMinCacheableTokens = bedrockProviderMapping?.minCacheableTokens ?? 1024;
677
+ const bedrockMinCacheableChars = bedrockMinCacheableTokens * 4;
678
+ const bedrockSystemMessages = processedMessages.filter((m) => m.role === "system");
679
+ const bedrockNonSystemMessages = processedMessages.filter((m) => m.role !== "system");
680
+ if (bedrockSystemMessages.length > 0) {
681
+ const systemContent = [];
682
+ for (const sysMsg of bedrockSystemMessages) {
683
+ let text;
684
+ if (typeof sysMsg.content === "string") {
685
+ text = sysMsg.content;
686
+ }
687
+ else if (Array.isArray(sysMsg.content)) {
688
+ text = sysMsg.content
689
+ .filter((c) => c.type === "text" && "text" in c)
690
+ .map((c) => c.text)
691
+ .join("");
692
+ }
693
+ else {
694
+ continue;
695
+ }
696
+ if (!text || text.trim() === "") {
697
+ continue;
698
+ }
699
+ systemContent.push({ text });
700
+ const shouldCache = text.length >= bedrockMinCacheableChars &&
701
+ bedrockCacheControlCount < bedrockMaxCacheControlBlocks;
702
+ if (shouldCache) {
703
+ bedrockCacheControlCount++;
704
+ systemContent.push({ cachePoint: { type: "default" } });
705
+ }
706
+ }
707
+ if (systemContent.length > 0) {
708
+ requestBody.system = systemContent;
709
+ }
710
+ }
711
+ requestBody.messages = bedrockNonSystemMessages.map((msg) => {
712
+ const role = msg.role === "user" || msg.role === "tool" ? "user" : "assistant";
713
+ const bedrockMessage = {
714
+ role: role,
715
+ content: [],
716
+ };
717
+ if (msg.role === "tool") {
718
+ bedrockMessage.content.push({
719
+ toolResult: {
720
+ toolUseId: msg.tool_call_id,
721
+ content: [
722
+ {
723
+ text: msg.content || "",
724
+ },
725
+ ],
726
+ },
727
+ });
728
+ return bedrockMessage;
729
+ }
730
+ if (msg.role === "assistant" && msg.tool_calls) {
731
+ if (msg.content) {
732
+ bedrockMessage.content.push({
733
+ text: msg.content,
734
+ });
735
+ }
736
+ msg.tool_calls.forEach((toolCall) => {
737
+ bedrockMessage.content.push({
738
+ toolUse: {
739
+ toolUseId: toolCall.id,
740
+ name: toolCall.function.name,
741
+ input: JSON.parse(toolCall.function.arguments),
742
+ },
743
+ });
744
+ });
745
+ return bedrockMessage;
746
+ }
747
+ if (typeof msg.content === "string") {
748
+ if (msg.content.trim()) {
749
+ bedrockMessage.content.push({
750
+ text: msg.content,
751
+ });
752
+ const shouldCache = msg.content.length >= bedrockMinCacheableChars &&
753
+ bedrockCacheControlCount < bedrockMaxCacheControlBlocks;
754
+ if (shouldCache) {
755
+ bedrockCacheControlCount++;
756
+ bedrockMessage.content.push({
757
+ cachePoint: { type: "default" },
758
+ });
759
+ }
760
+ }
761
+ }
762
+ else if (Array.isArray(msg.content)) {
763
+ msg.content.forEach((part) => {
764
+ if (part.type === "text") {
765
+ if (part.text && part.text.trim()) {
766
+ bedrockMessage.content.push({
767
+ text: part.text,
768
+ });
769
+ const shouldCache = part.text.length >= bedrockMinCacheableChars &&
770
+ bedrockCacheControlCount < bedrockMaxCacheControlBlocks;
771
+ if (shouldCache) {
772
+ bedrockCacheControlCount++;
773
+ bedrockMessage.content.push({
774
+ cachePoint: { type: "default" },
775
+ });
776
+ }
777
+ }
778
+ }
779
+ else if (part.type === "image_url") {
780
+ }
781
+ });
782
+ }
783
+ return bedrockMessage;
784
+ });
785
+ if (tools && tools.length > 0) {
786
+ const functionTools = tools.filter(isFunctionTool);
787
+ if (functionTools.length > 0) {
788
+ requestBody.toolConfig = {
789
+ tools: functionTools.map((tool) => ({
790
+ toolSpec: {
791
+ name: tool.function.name,
792
+ description: tool.function.description,
793
+ inputSchema: {
794
+ json: tool.function.parameters,
795
+ },
796
+ },
797
+ })),
798
+ };
799
+ }
800
+ }
801
+ const inferenceConfig = {};
802
+ if (temperature !== undefined) {
803
+ inferenceConfig.temperature = temperature;
804
+ }
805
+ if (max_tokens !== undefined) {
806
+ inferenceConfig.maxTokens = max_tokens;
807
+ }
808
+ if (top_p !== undefined) {
809
+ inferenceConfig.topP = top_p;
810
+ }
811
+ if (Object.keys(inferenceConfig).length > 0) {
812
+ requestBody.inferenceConfig = inferenceConfig;
813
+ }
814
+ if (response_format?.type === "json_schema" &&
815
+ response_format.json_schema) {
816
+ const schema = {
817
+ ...response_format.json_schema.schema,
818
+ additionalProperties: false,
819
+ };
820
+ requestBody.additionalModelRequestFields = {
821
+ anthropic_beta: ["structured-outputs-2025-11-13"],
822
+ output_format: {
823
+ type: "json_schema",
824
+ schema,
825
+ },
826
+ };
827
+ requestBody.additionalModelResponseFieldPaths = ["/output_format"];
828
+ }
829
+ break;
830
+ }
831
+ case "google-ai-studio":
832
+ case "google-vertex": {
833
+ delete requestBody.model;
834
+ delete requestBody.stream;
835
+ delete requestBody.messages;
836
+ delete requestBody.tool_choice;
837
+ requestBody.contents = await transformGoogleMessages(processedMessages, isProd, maxImageSizeMB, userPlan);
838
+ if (tools && tools.length > 0) {
839
+ const functionTools = tools.filter(isFunctionTool);
840
+ if (functionTools.length > 0) {
841
+ requestBody.tools = [
842
+ {
843
+ functionDeclarations: functionTools.map((tool) => {
844
+ const cleanParameters = stripUnsupportedSchemaProperties(tool.function.parameters || {});
845
+ return {
846
+ name: tool.function.name,
847
+ description: tool.function.description,
848
+ parameters: cleanParameters,
849
+ };
850
+ }),
851
+ },
852
+ ];
853
+ }
854
+ }
855
+ if (webSearchTool) {
856
+ if (!requestBody.tools) {
857
+ requestBody.tools = [];
858
+ }
859
+ requestBody.tools.push({ google_search: {} });
860
+ }
861
+ requestBody.generationConfig = {};
862
+ if (temperature !== undefined) {
863
+ requestBody.generationConfig.temperature = temperature;
864
+ }
865
+ if (max_tokens !== undefined) {
866
+ requestBody.generationConfig.maxOutputTokens = max_tokens;
867
+ }
868
+ if (top_p !== undefined) {
869
+ requestBody.generationConfig.topP = top_p;
870
+ }
871
+ if (response_format?.type === "json_object") {
872
+ requestBody.generationConfig.responseMimeType = "application/json";
873
+ }
874
+ else if (response_format?.type === "json_schema") {
875
+ requestBody.generationConfig.responseMimeType = "application/json";
876
+ if (response_format.json_schema?.schema) {
877
+ requestBody.generationConfig.responseSchema =
878
+ convertOpenAISchemaToGoogle(response_format.json_schema.schema);
879
+ }
880
+ }
881
+ if (supportsReasoning) {
882
+ requestBody.generationConfig.thinkingConfig = {
883
+ includeThoughts: true,
884
+ };
885
+ if (reasoning_effort !== undefined) {
886
+ const getThinkingBudget = (effort) => {
887
+ switch (effort) {
888
+ case "minimal":
889
+ return 512;
890
+ case "low":
891
+ return 2048;
892
+ case "high":
893
+ return 24576;
894
+ case "medium":
895
+ default:
896
+ return 8192;
897
+ }
898
+ };
899
+ requestBody.generationConfig.thinkingConfig.thinkingBudget =
900
+ getThinkingBudget(reasoning_effort);
901
+ }
902
+ }
903
+ if (image_config?.aspect_ratio !== undefined ||
904
+ image_config?.image_size !== undefined) {
905
+ requestBody.generationConfig.responseModalities = ["TEXT", "IMAGE"];
906
+ requestBody.generationConfig.imageConfig = {};
907
+ if (image_config.aspect_ratio !== undefined) {
908
+ requestBody.generationConfig.imageConfig.aspectRatio =
909
+ image_config.aspect_ratio;
910
+ }
911
+ if (image_config.image_size !== undefined) {
912
+ requestBody.generationConfig.imageConfig.imageSize =
913
+ image_config.image_size;
914
+ }
915
+ }
916
+ requestBody.safetySettings = [
917
+ { category: "HARM_CATEGORY_HARASSMENT", threshold: "BLOCK_NONE" },
918
+ { category: "HARM_CATEGORY_HATE_SPEECH", threshold: "BLOCK_NONE" },
919
+ {
920
+ category: "HARM_CATEGORY_SEXUALLY_EXPLICIT",
921
+ threshold: "BLOCK_NONE",
922
+ },
923
+ {
924
+ category: "HARM_CATEGORY_DANGEROUS_CONTENT",
925
+ threshold: "BLOCK_NONE",
926
+ },
927
+ ];
928
+ break;
929
+ }
930
+ case "inference.net":
931
+ case "together.ai": {
932
+ if (usedModel.startsWith(`${usedProvider}/`)) {
933
+ requestBody.model = usedModel.substring(usedProvider.length + 1);
934
+ }
935
+ if (temperature !== undefined) {
936
+ requestBody.temperature = temperature;
937
+ }
938
+ if (max_tokens !== undefined) {
939
+ requestBody.max_tokens = max_tokens;
940
+ }
941
+ if (top_p !== undefined) {
942
+ requestBody.top_p = top_p;
943
+ }
944
+ if (frequency_penalty !== undefined) {
945
+ requestBody.frequency_penalty = frequency_penalty;
946
+ }
947
+ if (presence_penalty !== undefined) {
948
+ requestBody.presence_penalty = presence_penalty;
949
+ }
950
+ break;
951
+ }
952
+ case "cerebras": {
953
+ if (stream) {
954
+ requestBody.stream_options = {
955
+ include_usage: true,
956
+ };
957
+ }
958
+ if (response_format) {
959
+ if (response_format.type === "json_schema") {
960
+ requestBody.response_format = {
961
+ ...response_format,
962
+ json_schema: {
963
+ ...response_format.json_schema,
964
+ strict: true,
965
+ schema: response_format.json_schema?.schema
966
+ ? sanitizeCerebrasSchema(response_format.json_schema.schema)
967
+ : response_format.json_schema?.schema,
968
+ },
969
+ };
970
+ }
971
+ else {
972
+ requestBody.response_format = response_format;
973
+ }
974
+ }
975
+ if (requestBody.tools && Array.isArray(requestBody.tools)) {
976
+ requestBody.tools = requestBody.tools.map((tool) => ({
977
+ ...tool,
978
+ function: {
979
+ ...tool.function,
980
+ strict: true,
981
+ parameters: tool.function.parameters
982
+ ? sanitizeCerebrasSchema(tool.function.parameters)
983
+ : tool.function.parameters,
984
+ },
985
+ }));
986
+ }
987
+ if (temperature !== undefined) {
988
+ requestBody.temperature = temperature;
989
+ }
990
+ if (max_tokens !== undefined) {
991
+ requestBody.max_tokens = max_tokens;
992
+ }
993
+ if (top_p !== undefined) {
994
+ requestBody.top_p = top_p;
995
+ }
996
+ if (frequency_penalty !== undefined) {
997
+ requestBody.frequency_penalty = frequency_penalty;
998
+ }
999
+ if (presence_penalty !== undefined) {
1000
+ requestBody.presence_penalty = presence_penalty;
1001
+ }
1002
+ if (reasoning_effort !== undefined) {
1003
+ requestBody.reasoning_effort = reasoning_effort;
1004
+ }
1005
+ break;
1006
+ }
1007
+ case "perplexity": {
1008
+ if (stream) {
1009
+ requestBody.stream_options = {
1010
+ include_usage: true,
1011
+ };
1012
+ }
1013
+ if (response_format) {
1014
+ if (response_format.type === "json_schema" &&
1015
+ response_format.json_schema) {
1016
+ requestBody.response_format = {
1017
+ type: "json_schema",
1018
+ json_schema: {
1019
+ schema: response_format.json_schema.schema,
1020
+ },
1021
+ };
1022
+ }
1023
+ else {
1024
+ requestBody.response_format = response_format;
1025
+ }
1026
+ }
1027
+ if (temperature !== undefined) {
1028
+ requestBody.temperature = temperature;
1029
+ }
1030
+ if (max_tokens !== undefined) {
1031
+ requestBody.max_tokens = max_tokens;
1032
+ }
1033
+ if (top_p !== undefined) {
1034
+ requestBody.top_p = top_p;
1035
+ }
1036
+ if (frequency_penalty !== undefined) {
1037
+ requestBody.frequency_penalty = frequency_penalty;
1038
+ }
1039
+ if (presence_penalty !== undefined) {
1040
+ requestBody.presence_penalty = presence_penalty;
1041
+ }
1042
+ break;
1043
+ }
1044
+ default: {
1045
+ if (stream) {
1046
+ requestBody.stream_options = {
1047
+ include_usage: true,
1048
+ };
1049
+ }
1050
+ if (response_format) {
1051
+ requestBody.response_format = response_format;
1052
+ }
1053
+ if (temperature !== undefined) {
1054
+ requestBody.temperature = temperature;
1055
+ }
1056
+ if (max_tokens !== undefined) {
1057
+ if (usedModel.startsWith("gpt-5")) {
1058
+ requestBody.max_completion_tokens = max_tokens;
1059
+ }
1060
+ else {
1061
+ requestBody.max_tokens = max_tokens;
1062
+ }
1063
+ }
1064
+ if (top_p !== undefined) {
1065
+ requestBody.top_p = top_p;
1066
+ }
1067
+ if (frequency_penalty !== undefined) {
1068
+ requestBody.frequency_penalty = frequency_penalty;
1069
+ }
1070
+ if (presence_penalty !== undefined) {
1071
+ requestBody.presence_penalty = presence_penalty;
1072
+ }
1073
+ if (reasoning_effort !== undefined) {
1074
+ requestBody.reasoning_effort = reasoning_effort;
1075
+ }
1076
+ break;
1077
+ }
1078
+ }
1079
+ return requestBody;
1080
+ }
1081
+ //# sourceMappingURL=prepare-request-body.js.map