@yourgpt/llm-sdk 2.5.0 → 2.5.1-beta.0

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 (59) hide show
  1. package/dist/adapters/index.d.mts +4 -4
  2. package/dist/adapters/index.d.ts +4 -4
  3. package/dist/adapters/index.js +156 -13
  4. package/dist/adapters/index.mjs +156 -13
  5. package/dist/base-C58Dsr9p.d.ts +259 -0
  6. package/dist/base-tNgbBaSo.d.mts +259 -0
  7. package/dist/fallback/index.d.mts +4 -4
  8. package/dist/fallback/index.d.ts +4 -4
  9. package/dist/index.d.mts +8 -7
  10. package/dist/index.d.ts +8 -7
  11. package/dist/index.js +12 -0
  12. package/dist/index.mjs +12 -0
  13. package/dist/providers/anthropic/index.d.mts +3 -3
  14. package/dist/providers/anthropic/index.d.ts +3 -3
  15. package/dist/providers/anthropic/index.js +271 -195
  16. package/dist/providers/anthropic/index.mjs +271 -195
  17. package/dist/providers/azure/index.d.mts +3 -3
  18. package/dist/providers/azure/index.d.ts +3 -3
  19. package/dist/providers/azure/index.js +49 -1
  20. package/dist/providers/azure/index.mjs +49 -1
  21. package/dist/providers/fireworks/index.d.mts +1 -1
  22. package/dist/providers/fireworks/index.d.ts +1 -1
  23. package/dist/providers/fireworks/index.js +56 -0
  24. package/dist/providers/fireworks/index.mjs +56 -0
  25. package/dist/providers/google/index.d.mts +3 -3
  26. package/dist/providers/google/index.d.ts +3 -3
  27. package/dist/providers/google/index.js +252 -205
  28. package/dist/providers/google/index.mjs +252 -205
  29. package/dist/providers/ollama/index.d.mts +4 -4
  30. package/dist/providers/ollama/index.d.ts +4 -4
  31. package/dist/providers/ollama/index.js +10 -2
  32. package/dist/providers/ollama/index.mjs +10 -2
  33. package/dist/providers/openai/index.d.mts +3 -3
  34. package/dist/providers/openai/index.d.ts +3 -3
  35. package/dist/providers/openai/index.js +267 -214
  36. package/dist/providers/openai/index.mjs +267 -214
  37. package/dist/providers/openrouter/index.d.mts +3 -3
  38. package/dist/providers/openrouter/index.d.ts +3 -3
  39. package/dist/providers/openrouter/index.js +257 -204
  40. package/dist/providers/openrouter/index.mjs +257 -204
  41. package/dist/providers/togetherai/index.d.mts +3 -3
  42. package/dist/providers/togetherai/index.d.ts +3 -3
  43. package/dist/providers/togetherai/index.js +257 -204
  44. package/dist/providers/togetherai/index.mjs +257 -204
  45. package/dist/providers/xai/index.d.mts +3 -3
  46. package/dist/providers/xai/index.d.ts +3 -3
  47. package/dist/providers/xai/index.js +256 -208
  48. package/dist/providers/xai/index.mjs +256 -208
  49. package/dist/{types-D4YfrQJR.d.mts → types-B6dhnguR.d.mts} +1 -1
  50. package/dist/{types-DRqxMIjF.d.mts → types-BQ31QIsA.d.ts} +2 -1
  51. package/dist/{types-BctsnC3g.d.ts → types-BSSiJW2o.d.mts} +2 -1
  52. package/dist/{base-D-U61JaB.d.mts → types-BkQCSiIt.d.mts} +388 -213
  53. package/dist/{base-iGi9Va6Z.d.ts → types-BkQCSiIt.d.ts} +388 -213
  54. package/dist/{types-38yolWJn.d.ts → types-CCxPmkmK.d.ts} +1 -1
  55. package/dist/yourgpt/index.d.mts +1 -1
  56. package/dist/yourgpt/index.d.ts +1 -1
  57. package/package.json +1 -1
  58. package/dist/types-CR8mi9I0.d.mts +0 -417
  59. package/dist/types-CR8mi9I0.d.ts +0 -417
@@ -1,5 +1,234 @@
1
1
  'use strict';
2
2
 
3
+ // src/adapters/base.ts
4
+ function stringifyForDebug(value) {
5
+ return JSON.stringify(
6
+ value,
7
+ (_key, currentValue) => {
8
+ if (typeof currentValue === "bigint") {
9
+ return currentValue.toString();
10
+ }
11
+ if (currentValue instanceof Error) {
12
+ return {
13
+ name: currentValue.name,
14
+ message: currentValue.message,
15
+ stack: currentValue.stack
16
+ };
17
+ }
18
+ return currentValue;
19
+ },
20
+ 2
21
+ );
22
+ }
23
+ function logProviderPayload(provider, label, payload, enabled) {
24
+ if (!enabled) {
25
+ return;
26
+ }
27
+ if (label.toLowerCase().includes("stream ")) {
28
+ return;
29
+ }
30
+ try {
31
+ console.log(
32
+ `[llm-sdk:${provider}] ${label}
33
+ ${stringifyForDebug(payload)}`
34
+ );
35
+ } catch (error) {
36
+ console.log(
37
+ `[llm-sdk:${provider}] ${label} (failed to stringify payload)`,
38
+ error
39
+ );
40
+ }
41
+ }
42
+ function parameterToJsonSchema(param) {
43
+ const schema = {
44
+ type: param.type
45
+ };
46
+ if (param.description) {
47
+ schema.description = param.description;
48
+ }
49
+ if (param.enum) {
50
+ schema.enum = param.enum;
51
+ }
52
+ if (param.type === "array" && param.items) {
53
+ schema.items = parameterToJsonSchema(
54
+ param.items
55
+ );
56
+ }
57
+ if (param.type === "object" && param.properties) {
58
+ schema.properties = Object.fromEntries(
59
+ Object.entries(param.properties).map(([key, prop]) => [
60
+ key,
61
+ parameterToJsonSchema(
62
+ prop
63
+ )
64
+ ])
65
+ );
66
+ schema.additionalProperties = false;
67
+ }
68
+ return schema;
69
+ }
70
+ function normalizeObjectJsonSchema(schema) {
71
+ if (!schema || typeof schema !== "object") {
72
+ return {
73
+ type: "object",
74
+ properties: {},
75
+ required: [],
76
+ additionalProperties: false
77
+ };
78
+ }
79
+ const normalized = { ...schema };
80
+ const type = normalized.type;
81
+ if (type === "object") {
82
+ const properties = normalized.properties && typeof normalized.properties === "object" && !Array.isArray(normalized.properties) ? normalized.properties : {};
83
+ normalized.properties = Object.fromEntries(
84
+ Object.entries(properties).map(([key, value]) => [
85
+ key,
86
+ normalizeObjectJsonSchema(value)
87
+ ])
88
+ );
89
+ const propertyKeys = Object.keys(properties);
90
+ const required = Array.isArray(normalized.required) ? normalized.required.filter(
91
+ (value) => typeof value === "string"
92
+ ) : [];
93
+ normalized.required = Array.from(/* @__PURE__ */ new Set([...required, ...propertyKeys]));
94
+ if (normalized.additionalProperties === void 0) {
95
+ normalized.additionalProperties = false;
96
+ }
97
+ } else if (type === "array" && normalized.items && typeof normalized.items === "object") {
98
+ normalized.items = normalizeObjectJsonSchema(
99
+ normalized.items
100
+ );
101
+ }
102
+ return normalized;
103
+ }
104
+ function isOpenAIReasoningModel(modelId) {
105
+ if (!modelId) return false;
106
+ return /^(o1|o3|o4|gpt-5)/i.test(modelId);
107
+ }
108
+ function buildOpenAITokenParams(modelId, maxTokens, temperature) {
109
+ if (isOpenAIReasoningModel(modelId)) {
110
+ return { max_completion_tokens: maxTokens };
111
+ }
112
+ return { max_tokens: maxTokens, temperature };
113
+ }
114
+ function toOpenAIResponseFormat(rf) {
115
+ if (!rf) return void 0;
116
+ if (rf.type === "json_object") return { type: "json_object" };
117
+ return {
118
+ type: "json_schema",
119
+ json_schema: {
120
+ name: rf.json_schema.name,
121
+ schema: normalizeObjectJsonSchema(rf.json_schema.schema),
122
+ strict: rf.json_schema.strict ?? true
123
+ }
124
+ };
125
+ }
126
+ function toOpenAIResponsesTextFormat(rf) {
127
+ if (!rf || rf.type !== "json_schema") return void 0;
128
+ return {
129
+ type: "json_schema",
130
+ name: rf.json_schema.name,
131
+ schema: normalizeObjectJsonSchema(rf.json_schema.schema),
132
+ strict: rf.json_schema.strict ?? true
133
+ };
134
+ }
135
+ function formatTools(actions) {
136
+ return actions.map((action) => ({
137
+ type: "function",
138
+ function: {
139
+ name: action.name,
140
+ description: action.description,
141
+ parameters: {
142
+ type: "object",
143
+ properties: action.parameters ? Object.fromEntries(
144
+ Object.entries(action.parameters).map(([key, param]) => [
145
+ key,
146
+ parameterToJsonSchema(param)
147
+ ])
148
+ ) : {},
149
+ required: action.parameters ? Object.entries(action.parameters).filter(([, param]) => param.required).map(([key]) => key) : [],
150
+ additionalProperties: false
151
+ }
152
+ }
153
+ }));
154
+ }
155
+ function hasImageAttachments(message) {
156
+ const attachments = message.metadata?.attachments;
157
+ return attachments?.some((a) => a.type === "image") ?? false;
158
+ }
159
+ function attachmentToOpenAIImage(attachment) {
160
+ if (attachment.type !== "image") return null;
161
+ let imageUrl;
162
+ if (attachment.url) {
163
+ imageUrl = attachment.url;
164
+ } else if (attachment.data) {
165
+ imageUrl = attachment.data.startsWith("data:") ? attachment.data : `data:${attachment.mimeType || "image/png"};base64,${attachment.data}`;
166
+ } else {
167
+ return null;
168
+ }
169
+ return {
170
+ type: "image_url",
171
+ image_url: {
172
+ url: imageUrl,
173
+ detail: "auto"
174
+ }
175
+ };
176
+ }
177
+ function messageToOpenAIContent(message) {
178
+ const attachments = message.metadata?.attachments;
179
+ const content = message.content ?? "";
180
+ if (!hasImageAttachments(message)) {
181
+ return content;
182
+ }
183
+ const blocks = [];
184
+ if (content) {
185
+ blocks.push({ type: "text", text: content });
186
+ }
187
+ if (attachments) {
188
+ for (const attachment of attachments) {
189
+ const imageBlock = attachmentToOpenAIImage(attachment);
190
+ if (imageBlock) {
191
+ blocks.push(imageBlock);
192
+ }
193
+ }
194
+ }
195
+ return blocks;
196
+ }
197
+ function formatMessagesForOpenAI(messages, systemPrompt) {
198
+ const formatted = [];
199
+ if (systemPrompt) {
200
+ formatted.push({ role: "system", content: systemPrompt });
201
+ }
202
+ for (const msg of messages) {
203
+ if (msg.role === "system") {
204
+ formatted.push({ role: "system", content: msg.content ?? "" });
205
+ } else if (msg.role === "user") {
206
+ formatted.push({
207
+ role: "user",
208
+ content: messageToOpenAIContent(msg)
209
+ });
210
+ } else if (msg.role === "assistant") {
211
+ const hasToolCalls = msg.tool_calls && msg.tool_calls.length > 0;
212
+ const assistantMsg = {
213
+ role: "assistant",
214
+ // Gemini/xAI (OpenAI-compatible) reject content: "" on assistant messages with tool_calls
215
+ content: hasToolCalls ? msg.content || null : msg.content
216
+ };
217
+ if (hasToolCalls) {
218
+ assistantMsg.tool_calls = msg.tool_calls;
219
+ }
220
+ formatted.push(assistantMsg);
221
+ } else if (msg.role === "tool" && msg.tool_call_id) {
222
+ formatted.push({
223
+ role: "tool",
224
+ content: msg.content ?? "",
225
+ tool_call_id: msg.tool_call_id
226
+ });
227
+ }
228
+ }
229
+ return formatted;
230
+ }
231
+
3
232
  // src/providers/openrouter/provider.ts
4
233
  var DEFAULT_MODEL_CONFIG = {
5
234
  vision: true,
@@ -58,6 +287,10 @@ function openrouter(modelId, options = {}) {
58
287
  if (options.providerPreferences) {
59
288
  requestBody.provider = options.providerPreferences;
60
289
  }
290
+ const responseFormat = toOpenAIResponseFormat(params.responseFormat);
291
+ if (responseFormat) {
292
+ requestBody.response_format = responseFormat;
293
+ }
61
294
  const response = await client2.chat.completions.create(requestBody);
62
295
  const choice = response.choices[0];
63
296
  const message = choice.message;
@@ -96,6 +329,10 @@ function openrouter(modelId, options = {}) {
96
329
  if (options.providerPreferences) {
97
330
  requestBody.provider = options.providerPreferences;
98
331
  }
332
+ const responseFormat = toOpenAIResponseFormat(params.responseFormat);
333
+ if (responseFormat) {
334
+ requestBody.response_format = responseFormat;
335
+ }
99
336
  const stream = await client2.chat.completions.create(requestBody);
100
337
  let currentToolCall = null;
101
338
  let totalPromptTokens = 0;
@@ -263,204 +500,6 @@ function generateToolCallId() {
263
500
  return generateId("call");
264
501
  }
265
502
 
266
- // src/adapters/base.ts
267
- function stringifyForDebug(value) {
268
- return JSON.stringify(
269
- value,
270
- (_key, currentValue) => {
271
- if (typeof currentValue === "bigint") {
272
- return currentValue.toString();
273
- }
274
- if (currentValue instanceof Error) {
275
- return {
276
- name: currentValue.name,
277
- message: currentValue.message,
278
- stack: currentValue.stack
279
- };
280
- }
281
- return currentValue;
282
- },
283
- 2
284
- );
285
- }
286
- function logProviderPayload(provider, label, payload, enabled) {
287
- if (!enabled) {
288
- return;
289
- }
290
- if (label.toLowerCase().includes("stream ")) {
291
- return;
292
- }
293
- try {
294
- console.log(
295
- `[llm-sdk:${provider}] ${label}
296
- ${stringifyForDebug(payload)}`
297
- );
298
- } catch (error) {
299
- console.log(
300
- `[llm-sdk:${provider}] ${label} (failed to stringify payload)`,
301
- error
302
- );
303
- }
304
- }
305
- function parameterToJsonSchema(param) {
306
- const schema = {
307
- type: param.type
308
- };
309
- if (param.description) {
310
- schema.description = param.description;
311
- }
312
- if (param.enum) {
313
- schema.enum = param.enum;
314
- }
315
- if (param.type === "array" && param.items) {
316
- schema.items = parameterToJsonSchema(
317
- param.items
318
- );
319
- }
320
- if (param.type === "object" && param.properties) {
321
- schema.properties = Object.fromEntries(
322
- Object.entries(param.properties).map(([key, prop]) => [
323
- key,
324
- parameterToJsonSchema(
325
- prop
326
- )
327
- ])
328
- );
329
- schema.additionalProperties = false;
330
- }
331
- return schema;
332
- }
333
- function normalizeObjectJsonSchema(schema) {
334
- if (!schema || typeof schema !== "object") {
335
- return {
336
- type: "object",
337
- properties: {},
338
- required: [],
339
- additionalProperties: false
340
- };
341
- }
342
- const normalized = { ...schema };
343
- const type = normalized.type;
344
- if (type === "object") {
345
- const properties = normalized.properties && typeof normalized.properties === "object" && !Array.isArray(normalized.properties) ? normalized.properties : {};
346
- normalized.properties = Object.fromEntries(
347
- Object.entries(properties).map(([key, value]) => [
348
- key,
349
- normalizeObjectJsonSchema(value)
350
- ])
351
- );
352
- const propertyKeys = Object.keys(properties);
353
- const required = Array.isArray(normalized.required) ? normalized.required.filter(
354
- (value) => typeof value === "string"
355
- ) : [];
356
- normalized.required = Array.from(/* @__PURE__ */ new Set([...required, ...propertyKeys]));
357
- if (normalized.additionalProperties === void 0) {
358
- normalized.additionalProperties = false;
359
- }
360
- } else if (type === "array" && normalized.items && typeof normalized.items === "object") {
361
- normalized.items = normalizeObjectJsonSchema(
362
- normalized.items
363
- );
364
- }
365
- return normalized;
366
- }
367
- function formatTools(actions) {
368
- return actions.map((action) => ({
369
- type: "function",
370
- function: {
371
- name: action.name,
372
- description: action.description,
373
- parameters: {
374
- type: "object",
375
- properties: action.parameters ? Object.fromEntries(
376
- Object.entries(action.parameters).map(([key, param]) => [
377
- key,
378
- parameterToJsonSchema(param)
379
- ])
380
- ) : {},
381
- required: action.parameters ? Object.entries(action.parameters).filter(([, param]) => param.required).map(([key]) => key) : [],
382
- additionalProperties: false
383
- }
384
- }
385
- }));
386
- }
387
- function hasImageAttachments(message) {
388
- const attachments = message.metadata?.attachments;
389
- return attachments?.some((a) => a.type === "image") ?? false;
390
- }
391
- function attachmentToOpenAIImage(attachment) {
392
- if (attachment.type !== "image") return null;
393
- let imageUrl;
394
- if (attachment.url) {
395
- imageUrl = attachment.url;
396
- } else if (attachment.data) {
397
- imageUrl = attachment.data.startsWith("data:") ? attachment.data : `data:${attachment.mimeType || "image/png"};base64,${attachment.data}`;
398
- } else {
399
- return null;
400
- }
401
- return {
402
- type: "image_url",
403
- image_url: {
404
- url: imageUrl,
405
- detail: "auto"
406
- }
407
- };
408
- }
409
- function messageToOpenAIContent(message) {
410
- const attachments = message.metadata?.attachments;
411
- const content = message.content ?? "";
412
- if (!hasImageAttachments(message)) {
413
- return content;
414
- }
415
- const blocks = [];
416
- if (content) {
417
- blocks.push({ type: "text", text: content });
418
- }
419
- if (attachments) {
420
- for (const attachment of attachments) {
421
- const imageBlock = attachmentToOpenAIImage(attachment);
422
- if (imageBlock) {
423
- blocks.push(imageBlock);
424
- }
425
- }
426
- }
427
- return blocks;
428
- }
429
- function formatMessagesForOpenAI(messages, systemPrompt) {
430
- const formatted = [];
431
- if (systemPrompt) {
432
- formatted.push({ role: "system", content: systemPrompt });
433
- }
434
- for (const msg of messages) {
435
- if (msg.role === "system") {
436
- formatted.push({ role: "system", content: msg.content ?? "" });
437
- } else if (msg.role === "user") {
438
- formatted.push({
439
- role: "user",
440
- content: messageToOpenAIContent(msg)
441
- });
442
- } else if (msg.role === "assistant") {
443
- const hasToolCalls = msg.tool_calls && msg.tool_calls.length > 0;
444
- const assistantMsg = {
445
- role: "assistant",
446
- // Gemini/xAI (OpenAI-compatible) reject content: "" on assistant messages with tool_calls
447
- content: hasToolCalls ? msg.content || null : msg.content
448
- };
449
- if (hasToolCalls) {
450
- assistantMsg.tool_calls = msg.tool_calls;
451
- }
452
- formatted.push(assistantMsg);
453
- } else if (msg.role === "tool" && msg.tool_call_id) {
454
- formatted.push({
455
- role: "tool",
456
- content: msg.content ?? "",
457
- tool_call_id: msg.tool_call_id
458
- });
459
- }
460
- }
461
- return formatted;
462
- }
463
-
464
503
  // src/adapters/openai.ts
465
504
  var OpenAIAdapter = class _OpenAIAdapter {
466
505
  constructor(config) {
@@ -575,6 +614,9 @@ var OpenAIAdapter = class _OpenAIAdapter {
575
614
  async completeWithResponses(request) {
576
615
  const client = await this.getClient();
577
616
  const openaiToolOptions = request.providerToolOptions?.openai;
617
+ const responsesTextFormat = toOpenAIResponsesTextFormat(
618
+ request.config?.responseFormat
619
+ );
578
620
  const payload = {
579
621
  model: request.config?.model || this.model,
580
622
  instructions: request.systemPrompt,
@@ -584,6 +626,7 @@ var OpenAIAdapter = class _OpenAIAdapter {
584
626
  parallel_tool_calls: openaiToolOptions?.parallelToolCalls,
585
627
  temperature: request.config?.temperature ?? this.config.temperature,
586
628
  max_output_tokens: request.config?.maxTokens ?? this.config.maxTokens,
629
+ ...responsesTextFormat ? { text: { format: responsesTextFormat } } : {},
587
630
  stream: false
588
631
  };
589
632
  logProviderPayload("openai", "request payload", payload, request.debug);
@@ -705,14 +748,19 @@ var OpenAIAdapter = class _OpenAIAdapter {
705
748
  name: openaiToolOptions.toolChoice.name
706
749
  }
707
750
  } : openaiToolOptions?.toolChoice;
751
+ const modelIdForPayload = request.config?.model || this.model;
708
752
  const payload = {
709
- model: request.config?.model || this.model,
753
+ model: modelIdForPayload,
710
754
  messages,
711
755
  tools: tools.length > 0 ? tools : void 0,
712
756
  tool_choice: tools.length > 0 ? toolChoice : void 0,
713
757
  parallel_tool_calls: tools.length > 0 ? openaiToolOptions?.parallelToolCalls : void 0,
714
- temperature: request.config?.temperature ?? this.config.temperature,
715
- max_tokens: request.config?.maxTokens ?? this.config.maxTokens,
758
+ ...buildOpenAITokenParams(
759
+ modelIdForPayload,
760
+ request.config?.maxTokens ?? this.config.maxTokens,
761
+ request.config?.temperature ?? this.config.temperature
762
+ ),
763
+ response_format: toOpenAIResponseFormat(request.config?.responseFormat),
716
764
  stream: true,
717
765
  stream_options: { include_usage: true }
718
766
  };
@@ -854,14 +902,19 @@ var OpenAIAdapter = class _OpenAIAdapter {
854
902
  name: openaiToolOptions.toolChoice.name
855
903
  }
856
904
  } : openaiToolOptions?.toolChoice;
905
+ const modelIdForCompletePayload = request.config?.model || this.model;
857
906
  const payload = {
858
- model: request.config?.model || this.model,
907
+ model: modelIdForCompletePayload,
859
908
  messages,
860
909
  tools: tools.length > 0 ? tools : void 0,
861
910
  tool_choice: tools.length > 0 ? toolChoice : void 0,
862
911
  parallel_tool_calls: tools.length > 0 ? openaiToolOptions?.parallelToolCalls : void 0,
863
- temperature: request.config?.temperature ?? this.config.temperature,
864
- max_tokens: request.config?.maxTokens ?? this.config.maxTokens,
912
+ ...buildOpenAITokenParams(
913
+ modelIdForCompletePayload,
914
+ request.config?.maxTokens ?? this.config.maxTokens,
915
+ request.config?.temperature ?? this.config.temperature
916
+ ),
917
+ response_format: toOpenAIResponseFormat(request.config?.responseFormat),
865
918
  stream: false
866
919
  };
867
920
  logProviderPayload("openai", "request payload", payload, request.debug);