@llmgateway/models 0.0.1 → 1.0.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 (38) hide show
  1. package/README.md +104 -0
  2. package/dist/index.d.ts +0 -9
  3. package/dist/index.js +0 -9
  4. package/dist/index.js.map +1 -1
  5. package/package.json +7 -7
  6. package/dist/get-cheapest-from-available-providers.d.ts +0 -30
  7. package/dist/get-cheapest-from-available-providers.js +0 -183
  8. package/dist/get-cheapest-from-available-providers.js.map +0 -1
  9. package/dist/get-cheapest-model-for-provider.d.ts +0 -2
  10. package/dist/get-cheapest-model-for-provider.js +0 -49
  11. package/dist/get-cheapest-model-for-provider.js.map +0 -1
  12. package/dist/get-provider-endpoint.d.ts +0 -3
  13. package/dist/get-provider-endpoint.js +0 -243
  14. package/dist/get-provider-endpoint.js.map +0 -1
  15. package/dist/get-provider-headers.d.ts +0 -5
  16. package/dist/get-provider-headers.js +0 -45
  17. package/dist/get-provider-headers.js.map +0 -1
  18. package/dist/models.spec.d.ts +0 -1
  19. package/dist/models.spec.js +0 -263
  20. package/dist/models.spec.js.map +0 -1
  21. package/dist/prepare-request-body.d.ts +0 -10
  22. package/dist/prepare-request-body.js +0 -1081
  23. package/dist/prepare-request-body.js.map +0 -1
  24. package/dist/prepare-request-body.spec.d.ts +0 -1
  25. package/dist/prepare-request-body.spec.js +0 -231
  26. package/dist/prepare-request-body.spec.js.map +0 -1
  27. package/dist/process-image-url.d.ts +0 -4
  28. package/dist/process-image-url.js +0 -121
  29. package/dist/process-image-url.js.map +0 -1
  30. package/dist/transform-anthropic-messages.d.ts +0 -2
  31. package/dist/transform-anthropic-messages.js +0 -185
  32. package/dist/transform-anthropic-messages.js.map +0 -1
  33. package/dist/transform-google-messages.d.ts +0 -25
  34. package/dist/transform-google-messages.js +0 -122
  35. package/dist/transform-google-messages.js.map +0 -1
  36. package/dist/validate-provider-key.d.ts +0 -4
  37. package/dist/validate-provider-key.js +0 -113
  38. package/dist/validate-provider-key.js.map +0 -1
@@ -1,1081 +0,0 @@
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