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