@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/togetherai/provider.ts
4
233
  function togetherai(modelId, options = {}) {
5
234
  const apiKey = options.apiKey ?? process.env.TOGETHER_API_KEY;
@@ -42,6 +271,10 @@ function togetherai(modelId, options = {}) {
42
271
  if (params.tools) {
43
272
  requestBody.tools = params.tools;
44
273
  }
274
+ const responseFormat = toOpenAIResponseFormat(params.responseFormat);
275
+ if (responseFormat) {
276
+ requestBody.response_format = responseFormat;
277
+ }
45
278
  const response = await client2.chat.completions.create(requestBody);
46
279
  const choice = response.choices[0];
47
280
  const message = choice.message;
@@ -77,6 +310,10 @@ function togetherai(modelId, options = {}) {
77
310
  if (params.tools) {
78
311
  requestBody.tools = params.tools;
79
312
  }
313
+ const responseFormat = toOpenAIResponseFormat(params.responseFormat);
314
+ if (responseFormat) {
315
+ requestBody.response_format = responseFormat;
316
+ }
80
317
  const stream = await client2.chat.completions.create(requestBody);
81
318
  const toolCallMap = /* @__PURE__ */ new Map();
82
319
  let totalPromptTokens = 0;
@@ -215,204 +452,6 @@ function generateToolCallId() {
215
452
  return generateId("call");
216
453
  }
217
454
 
218
- // src/adapters/base.ts
219
- function stringifyForDebug(value) {
220
- return JSON.stringify(
221
- value,
222
- (_key, currentValue) => {
223
- if (typeof currentValue === "bigint") {
224
- return currentValue.toString();
225
- }
226
- if (currentValue instanceof Error) {
227
- return {
228
- name: currentValue.name,
229
- message: currentValue.message,
230
- stack: currentValue.stack
231
- };
232
- }
233
- return currentValue;
234
- },
235
- 2
236
- );
237
- }
238
- function logProviderPayload(provider, label, payload, enabled) {
239
- if (!enabled) {
240
- return;
241
- }
242
- if (label.toLowerCase().includes("stream ")) {
243
- return;
244
- }
245
- try {
246
- console.log(
247
- `[llm-sdk:${provider}] ${label}
248
- ${stringifyForDebug(payload)}`
249
- );
250
- } catch (error) {
251
- console.log(
252
- `[llm-sdk:${provider}] ${label} (failed to stringify payload)`,
253
- error
254
- );
255
- }
256
- }
257
- function parameterToJsonSchema(param) {
258
- const schema = {
259
- type: param.type
260
- };
261
- if (param.description) {
262
- schema.description = param.description;
263
- }
264
- if (param.enum) {
265
- schema.enum = param.enum;
266
- }
267
- if (param.type === "array" && param.items) {
268
- schema.items = parameterToJsonSchema(
269
- param.items
270
- );
271
- }
272
- if (param.type === "object" && param.properties) {
273
- schema.properties = Object.fromEntries(
274
- Object.entries(param.properties).map(([key, prop]) => [
275
- key,
276
- parameterToJsonSchema(
277
- prop
278
- )
279
- ])
280
- );
281
- schema.additionalProperties = false;
282
- }
283
- return schema;
284
- }
285
- function normalizeObjectJsonSchema(schema) {
286
- if (!schema || typeof schema !== "object") {
287
- return {
288
- type: "object",
289
- properties: {},
290
- required: [],
291
- additionalProperties: false
292
- };
293
- }
294
- const normalized = { ...schema };
295
- const type = normalized.type;
296
- if (type === "object") {
297
- const properties = normalized.properties && typeof normalized.properties === "object" && !Array.isArray(normalized.properties) ? normalized.properties : {};
298
- normalized.properties = Object.fromEntries(
299
- Object.entries(properties).map(([key, value]) => [
300
- key,
301
- normalizeObjectJsonSchema(value)
302
- ])
303
- );
304
- const propertyKeys = Object.keys(properties);
305
- const required = Array.isArray(normalized.required) ? normalized.required.filter(
306
- (value) => typeof value === "string"
307
- ) : [];
308
- normalized.required = Array.from(/* @__PURE__ */ new Set([...required, ...propertyKeys]));
309
- if (normalized.additionalProperties === void 0) {
310
- normalized.additionalProperties = false;
311
- }
312
- } else if (type === "array" && normalized.items && typeof normalized.items === "object") {
313
- normalized.items = normalizeObjectJsonSchema(
314
- normalized.items
315
- );
316
- }
317
- return normalized;
318
- }
319
- function formatTools(actions) {
320
- return actions.map((action) => ({
321
- type: "function",
322
- function: {
323
- name: action.name,
324
- description: action.description,
325
- parameters: {
326
- type: "object",
327
- properties: action.parameters ? Object.fromEntries(
328
- Object.entries(action.parameters).map(([key, param]) => [
329
- key,
330
- parameterToJsonSchema(param)
331
- ])
332
- ) : {},
333
- required: action.parameters ? Object.entries(action.parameters).filter(([, param]) => param.required).map(([key]) => key) : [],
334
- additionalProperties: false
335
- }
336
- }
337
- }));
338
- }
339
- function hasImageAttachments(message) {
340
- const attachments = message.metadata?.attachments;
341
- return attachments?.some((a) => a.type === "image") ?? false;
342
- }
343
- function attachmentToOpenAIImage(attachment) {
344
- if (attachment.type !== "image") return null;
345
- let imageUrl;
346
- if (attachment.url) {
347
- imageUrl = attachment.url;
348
- } else if (attachment.data) {
349
- imageUrl = attachment.data.startsWith("data:") ? attachment.data : `data:${attachment.mimeType || "image/png"};base64,${attachment.data}`;
350
- } else {
351
- return null;
352
- }
353
- return {
354
- type: "image_url",
355
- image_url: {
356
- url: imageUrl,
357
- detail: "auto"
358
- }
359
- };
360
- }
361
- function messageToOpenAIContent(message) {
362
- const attachments = message.metadata?.attachments;
363
- const content = message.content ?? "";
364
- if (!hasImageAttachments(message)) {
365
- return content;
366
- }
367
- const blocks = [];
368
- if (content) {
369
- blocks.push({ type: "text", text: content });
370
- }
371
- if (attachments) {
372
- for (const attachment of attachments) {
373
- const imageBlock = attachmentToOpenAIImage(attachment);
374
- if (imageBlock) {
375
- blocks.push(imageBlock);
376
- }
377
- }
378
- }
379
- return blocks;
380
- }
381
- function formatMessagesForOpenAI(messages, systemPrompt) {
382
- const formatted = [];
383
- if (systemPrompt) {
384
- formatted.push({ role: "system", content: systemPrompt });
385
- }
386
- for (const msg of messages) {
387
- if (msg.role === "system") {
388
- formatted.push({ role: "system", content: msg.content ?? "" });
389
- } else if (msg.role === "user") {
390
- formatted.push({
391
- role: "user",
392
- content: messageToOpenAIContent(msg)
393
- });
394
- } else if (msg.role === "assistant") {
395
- const hasToolCalls = msg.tool_calls && msg.tool_calls.length > 0;
396
- const assistantMsg = {
397
- role: "assistant",
398
- // Gemini/xAI (OpenAI-compatible) reject content: "" on assistant messages with tool_calls
399
- content: hasToolCalls ? msg.content || null : msg.content
400
- };
401
- if (hasToolCalls) {
402
- assistantMsg.tool_calls = msg.tool_calls;
403
- }
404
- formatted.push(assistantMsg);
405
- } else if (msg.role === "tool" && msg.tool_call_id) {
406
- formatted.push({
407
- role: "tool",
408
- content: msg.content ?? "",
409
- tool_call_id: msg.tool_call_id
410
- });
411
- }
412
- }
413
- return formatted;
414
- }
415
-
416
455
  // src/adapters/openai.ts
417
456
  var OpenAIAdapter = class _OpenAIAdapter {
418
457
  constructor(config) {
@@ -527,6 +566,9 @@ var OpenAIAdapter = class _OpenAIAdapter {
527
566
  async completeWithResponses(request) {
528
567
  const client = await this.getClient();
529
568
  const openaiToolOptions = request.providerToolOptions?.openai;
569
+ const responsesTextFormat = toOpenAIResponsesTextFormat(
570
+ request.config?.responseFormat
571
+ );
530
572
  const payload = {
531
573
  model: request.config?.model || this.model,
532
574
  instructions: request.systemPrompt,
@@ -536,6 +578,7 @@ var OpenAIAdapter = class _OpenAIAdapter {
536
578
  parallel_tool_calls: openaiToolOptions?.parallelToolCalls,
537
579
  temperature: request.config?.temperature ?? this.config.temperature,
538
580
  max_output_tokens: request.config?.maxTokens ?? this.config.maxTokens,
581
+ ...responsesTextFormat ? { text: { format: responsesTextFormat } } : {},
539
582
  stream: false
540
583
  };
541
584
  logProviderPayload("openai", "request payload", payload, request.debug);
@@ -657,14 +700,19 @@ var OpenAIAdapter = class _OpenAIAdapter {
657
700
  name: openaiToolOptions.toolChoice.name
658
701
  }
659
702
  } : openaiToolOptions?.toolChoice;
703
+ const modelIdForPayload = request.config?.model || this.model;
660
704
  const payload = {
661
- model: request.config?.model || this.model,
705
+ model: modelIdForPayload,
662
706
  messages,
663
707
  tools: tools.length > 0 ? tools : void 0,
664
708
  tool_choice: tools.length > 0 ? toolChoice : void 0,
665
709
  parallel_tool_calls: tools.length > 0 ? openaiToolOptions?.parallelToolCalls : void 0,
666
- temperature: request.config?.temperature ?? this.config.temperature,
667
- max_tokens: request.config?.maxTokens ?? this.config.maxTokens,
710
+ ...buildOpenAITokenParams(
711
+ modelIdForPayload,
712
+ request.config?.maxTokens ?? this.config.maxTokens,
713
+ request.config?.temperature ?? this.config.temperature
714
+ ),
715
+ response_format: toOpenAIResponseFormat(request.config?.responseFormat),
668
716
  stream: true,
669
717
  stream_options: { include_usage: true }
670
718
  };
@@ -806,14 +854,19 @@ var OpenAIAdapter = class _OpenAIAdapter {
806
854
  name: openaiToolOptions.toolChoice.name
807
855
  }
808
856
  } : openaiToolOptions?.toolChoice;
857
+ const modelIdForCompletePayload = request.config?.model || this.model;
809
858
  const payload = {
810
- model: request.config?.model || this.model,
859
+ model: modelIdForCompletePayload,
811
860
  messages,
812
861
  tools: tools.length > 0 ? tools : void 0,
813
862
  tool_choice: tools.length > 0 ? toolChoice : void 0,
814
863
  parallel_tool_calls: tools.length > 0 ? openaiToolOptions?.parallelToolCalls : void 0,
815
- temperature: request.config?.temperature ?? this.config.temperature,
816
- max_tokens: request.config?.maxTokens ?? this.config.maxTokens,
864
+ ...buildOpenAITokenParams(
865
+ modelIdForCompletePayload,
866
+ request.config?.maxTokens ?? this.config.maxTokens,
867
+ request.config?.temperature ?? this.config.temperature
868
+ ),
869
+ response_format: toOpenAIResponseFormat(request.config?.responseFormat),
817
870
  stream: false
818
871
  };
819
872
  logProviderPayload("openai", "request payload", payload, request.debug);