@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/google/provider.ts
2
231
  var GOOGLE_MODELS = {
3
232
  // Gemini 2.5 (Experimental)
@@ -117,7 +346,8 @@ function google(modelId, options = {}) {
117
346
  messages,
118
347
  tools: params.tools,
119
348
  temperature: params.temperature,
120
- max_tokens: params.maxTokens
349
+ max_tokens: params.maxTokens,
350
+ response_format: toOpenAIResponseFormat(params.responseFormat)
121
351
  });
122
352
  const choice = response.choices[0];
123
353
  const message = choice.message;
@@ -149,6 +379,7 @@ function google(modelId, options = {}) {
149
379
  tools: params.tools,
150
380
  temperature: params.temperature,
151
381
  max_tokens: params.maxTokens,
382
+ response_format: toOpenAIResponseFormat(params.responseFormat),
152
383
  stream: true
153
384
  });
154
385
  let currentToolCall = null;
@@ -294,204 +525,6 @@ function generateToolCallId() {
294
525
  return generateId("call");
295
526
  }
296
527
 
297
- // src/adapters/base.ts
298
- function stringifyForDebug(value) {
299
- return JSON.stringify(
300
- value,
301
- (_key, currentValue) => {
302
- if (typeof currentValue === "bigint") {
303
- return currentValue.toString();
304
- }
305
- if (currentValue instanceof Error) {
306
- return {
307
- name: currentValue.name,
308
- message: currentValue.message,
309
- stack: currentValue.stack
310
- };
311
- }
312
- return currentValue;
313
- },
314
- 2
315
- );
316
- }
317
- function logProviderPayload(provider, label, payload, enabled) {
318
- if (!enabled) {
319
- return;
320
- }
321
- if (label.toLowerCase().includes("stream ")) {
322
- return;
323
- }
324
- try {
325
- console.log(
326
- `[llm-sdk:${provider}] ${label}
327
- ${stringifyForDebug(payload)}`
328
- );
329
- } catch (error) {
330
- console.log(
331
- `[llm-sdk:${provider}] ${label} (failed to stringify payload)`,
332
- error
333
- );
334
- }
335
- }
336
- function parameterToJsonSchema(param) {
337
- const schema = {
338
- type: param.type
339
- };
340
- if (param.description) {
341
- schema.description = param.description;
342
- }
343
- if (param.enum) {
344
- schema.enum = param.enum;
345
- }
346
- if (param.type === "array" && param.items) {
347
- schema.items = parameterToJsonSchema(
348
- param.items
349
- );
350
- }
351
- if (param.type === "object" && param.properties) {
352
- schema.properties = Object.fromEntries(
353
- Object.entries(param.properties).map(([key, prop]) => [
354
- key,
355
- parameterToJsonSchema(
356
- prop
357
- )
358
- ])
359
- );
360
- schema.additionalProperties = false;
361
- }
362
- return schema;
363
- }
364
- function normalizeObjectJsonSchema(schema) {
365
- if (!schema || typeof schema !== "object") {
366
- return {
367
- type: "object",
368
- properties: {},
369
- required: [],
370
- additionalProperties: false
371
- };
372
- }
373
- const normalized = { ...schema };
374
- const type = normalized.type;
375
- if (type === "object") {
376
- const properties = normalized.properties && typeof normalized.properties === "object" && !Array.isArray(normalized.properties) ? normalized.properties : {};
377
- normalized.properties = Object.fromEntries(
378
- Object.entries(properties).map(([key, value]) => [
379
- key,
380
- normalizeObjectJsonSchema(value)
381
- ])
382
- );
383
- const propertyKeys = Object.keys(properties);
384
- const required = Array.isArray(normalized.required) ? normalized.required.filter(
385
- (value) => typeof value === "string"
386
- ) : [];
387
- normalized.required = Array.from(/* @__PURE__ */ new Set([...required, ...propertyKeys]));
388
- if (normalized.additionalProperties === void 0) {
389
- normalized.additionalProperties = false;
390
- }
391
- } else if (type === "array" && normalized.items && typeof normalized.items === "object") {
392
- normalized.items = normalizeObjectJsonSchema(
393
- normalized.items
394
- );
395
- }
396
- return normalized;
397
- }
398
- function formatTools(actions) {
399
- return actions.map((action) => ({
400
- type: "function",
401
- function: {
402
- name: action.name,
403
- description: action.description,
404
- parameters: {
405
- type: "object",
406
- properties: action.parameters ? Object.fromEntries(
407
- Object.entries(action.parameters).map(([key, param]) => [
408
- key,
409
- parameterToJsonSchema(param)
410
- ])
411
- ) : {},
412
- required: action.parameters ? Object.entries(action.parameters).filter(([, param]) => param.required).map(([key]) => key) : [],
413
- additionalProperties: false
414
- }
415
- }
416
- }));
417
- }
418
- function hasImageAttachments(message) {
419
- const attachments = message.metadata?.attachments;
420
- return attachments?.some((a) => a.type === "image") ?? false;
421
- }
422
- function attachmentToOpenAIImage(attachment) {
423
- if (attachment.type !== "image") return null;
424
- let imageUrl;
425
- if (attachment.url) {
426
- imageUrl = attachment.url;
427
- } else if (attachment.data) {
428
- imageUrl = attachment.data.startsWith("data:") ? attachment.data : `data:${attachment.mimeType || "image/png"};base64,${attachment.data}`;
429
- } else {
430
- return null;
431
- }
432
- return {
433
- type: "image_url",
434
- image_url: {
435
- url: imageUrl,
436
- detail: "auto"
437
- }
438
- };
439
- }
440
- function messageToOpenAIContent(message) {
441
- const attachments = message.metadata?.attachments;
442
- const content = message.content ?? "";
443
- if (!hasImageAttachments(message)) {
444
- return content;
445
- }
446
- const blocks = [];
447
- if (content) {
448
- blocks.push({ type: "text", text: content });
449
- }
450
- if (attachments) {
451
- for (const attachment of attachments) {
452
- const imageBlock = attachmentToOpenAIImage(attachment);
453
- if (imageBlock) {
454
- blocks.push(imageBlock);
455
- }
456
- }
457
- }
458
- return blocks;
459
- }
460
- function formatMessagesForOpenAI(messages, systemPrompt) {
461
- const formatted = [];
462
- if (systemPrompt) {
463
- formatted.push({ role: "system", content: systemPrompt });
464
- }
465
- for (const msg of messages) {
466
- if (msg.role === "system") {
467
- formatted.push({ role: "system", content: msg.content ?? "" });
468
- } else if (msg.role === "user") {
469
- formatted.push({
470
- role: "user",
471
- content: messageToOpenAIContent(msg)
472
- });
473
- } else if (msg.role === "assistant") {
474
- const hasToolCalls = msg.tool_calls && msg.tool_calls.length > 0;
475
- const assistantMsg = {
476
- role: "assistant",
477
- // Gemini/xAI (OpenAI-compatible) reject content: "" on assistant messages with tool_calls
478
- content: hasToolCalls ? msg.content || null : msg.content
479
- };
480
- if (hasToolCalls) {
481
- assistantMsg.tool_calls = msg.tool_calls;
482
- }
483
- formatted.push(assistantMsg);
484
- } else if (msg.role === "tool" && msg.tool_call_id) {
485
- formatted.push({
486
- role: "tool",
487
- content: msg.content ?? "",
488
- tool_call_id: msg.tool_call_id
489
- });
490
- }
491
- }
492
- return formatted;
493
- }
494
-
495
528
  // src/adapters/openai.ts
496
529
  var OpenAIAdapter = class _OpenAIAdapter {
497
530
  constructor(config) {
@@ -606,6 +639,9 @@ var OpenAIAdapter = class _OpenAIAdapter {
606
639
  async completeWithResponses(request) {
607
640
  const client = await this.getClient();
608
641
  const openaiToolOptions = request.providerToolOptions?.openai;
642
+ const responsesTextFormat = toOpenAIResponsesTextFormat(
643
+ request.config?.responseFormat
644
+ );
609
645
  const payload = {
610
646
  model: request.config?.model || this.model,
611
647
  instructions: request.systemPrompt,
@@ -615,6 +651,7 @@ var OpenAIAdapter = class _OpenAIAdapter {
615
651
  parallel_tool_calls: openaiToolOptions?.parallelToolCalls,
616
652
  temperature: request.config?.temperature ?? this.config.temperature,
617
653
  max_output_tokens: request.config?.maxTokens ?? this.config.maxTokens,
654
+ ...responsesTextFormat ? { text: { format: responsesTextFormat } } : {},
618
655
  stream: false
619
656
  };
620
657
  logProviderPayload("openai", "request payload", payload, request.debug);
@@ -736,14 +773,19 @@ var OpenAIAdapter = class _OpenAIAdapter {
736
773
  name: openaiToolOptions.toolChoice.name
737
774
  }
738
775
  } : openaiToolOptions?.toolChoice;
776
+ const modelIdForPayload = request.config?.model || this.model;
739
777
  const payload = {
740
- model: request.config?.model || this.model,
778
+ model: modelIdForPayload,
741
779
  messages,
742
780
  tools: tools.length > 0 ? tools : void 0,
743
781
  tool_choice: tools.length > 0 ? toolChoice : void 0,
744
782
  parallel_tool_calls: tools.length > 0 ? openaiToolOptions?.parallelToolCalls : void 0,
745
- temperature: request.config?.temperature ?? this.config.temperature,
746
- max_tokens: request.config?.maxTokens ?? this.config.maxTokens,
783
+ ...buildOpenAITokenParams(
784
+ modelIdForPayload,
785
+ request.config?.maxTokens ?? this.config.maxTokens,
786
+ request.config?.temperature ?? this.config.temperature
787
+ ),
788
+ response_format: toOpenAIResponseFormat(request.config?.responseFormat),
747
789
  stream: true,
748
790
  stream_options: { include_usage: true }
749
791
  };
@@ -885,14 +927,19 @@ var OpenAIAdapter = class _OpenAIAdapter {
885
927
  name: openaiToolOptions.toolChoice.name
886
928
  }
887
929
  } : openaiToolOptions?.toolChoice;
930
+ const modelIdForCompletePayload = request.config?.model || this.model;
888
931
  const payload = {
889
- model: request.config?.model || this.model,
932
+ model: modelIdForCompletePayload,
890
933
  messages,
891
934
  tools: tools.length > 0 ? tools : void 0,
892
935
  tool_choice: tools.length > 0 ? toolChoice : void 0,
893
936
  parallel_tool_calls: tools.length > 0 ? openaiToolOptions?.parallelToolCalls : void 0,
894
- temperature: request.config?.temperature ?? this.config.temperature,
895
- max_tokens: request.config?.maxTokens ?? this.config.maxTokens,
937
+ ...buildOpenAITokenParams(
938
+ modelIdForCompletePayload,
939
+ request.config?.maxTokens ?? this.config.maxTokens,
940
+ request.config?.temperature ?? this.config.temperature
941
+ ),
942
+ response_format: toOpenAIResponseFormat(request.config?.responseFormat),
896
943
  stream: false
897
944
  };
898
945
  logProviderPayload("openai", "request payload", payload, request.debug);
@@ -1,8 +1,8 @@
1
- import { c as OllamaProviderConfig, A as AIProvider } from '../../types-DRqxMIjF.mjs';
2
- export { d as OllamaModelOptions } from '../../types-DRqxMIjF.mjs';
3
- import '../../base-D-U61JaB.mjs';
4
- import '../../types-CR8mi9I0.mjs';
1
+ import { c as OllamaProviderConfig, A as AIProvider } from '../../types-BSSiJW2o.mjs';
2
+ export { d as OllamaModelOptions } from '../../types-BSSiJW2o.mjs';
3
+ import '../../types-BkQCSiIt.mjs';
5
4
  import 'zod';
5
+ import '../../base-tNgbBaSo.mjs';
6
6
 
7
7
  /**
8
8
  * Ollama Provider
@@ -1,8 +1,8 @@
1
- import { c as OllamaProviderConfig, A as AIProvider } from '../../types-BctsnC3g.js';
2
- export { d as OllamaModelOptions } from '../../types-BctsnC3g.js';
3
- import '../../base-iGi9Va6Z.js';
4
- import '../../types-CR8mi9I0.js';
1
+ import { c as OllamaProviderConfig, A as AIProvider } from '../../types-BQ31QIsA.js';
2
+ export { d as OllamaModelOptions } from '../../types-BQ31QIsA.js';
3
+ import '../../types-BkQCSiIt.js';
5
4
  import 'zod';
5
+ import '../../base-C58Dsr9p.js';
6
6
 
7
7
  /**
8
8
  * Ollama Provider
@@ -78,6 +78,11 @@ function parameterToJsonSchema(param) {
78
78
  }
79
79
  return schema;
80
80
  }
81
+ function toOllamaFormat(rf) {
82
+ if (!rf) return void 0;
83
+ if (rf.type === "json_object") return "json";
84
+ return rf.json_schema.schema;
85
+ }
81
86
  function formatTools(actions) {
82
87
  return actions.map((action) => ({
83
88
  type: "function",
@@ -240,12 +245,14 @@ var OllamaAdapter = class {
240
245
  if (this.config.options) {
241
246
  Object.assign(ollamaOptions, this.config.options);
242
247
  }
248
+ const ollamaFormat = toOllamaFormat(request.config?.responseFormat);
243
249
  const payload = {
244
250
  model: request.config?.model || this.model,
245
251
  messages,
246
252
  tools,
247
253
  stream: true,
248
- options: ollamaOptions
254
+ options: ollamaOptions,
255
+ ...ollamaFormat !== void 0 ? { format: ollamaFormat } : {}
249
256
  };
250
257
  logProviderPayload("ollama", "request payload", payload, request.debug);
251
258
  const response = await fetch(`${this.baseUrl}/api/chat`, {
@@ -496,7 +503,8 @@ function createOllama(config = {}) {
496
503
  supportsVideo: false,
497
504
  maxTokens: model.maxTokens,
498
505
  supportedImageTypes: model.vision ? ["image/png", "image/jpeg", "image/gif"] : [],
499
- supportsJsonMode: false,
506
+ // Ollama 0.5+ supports `format: "json"` and JSON-schema constrained output.
507
+ supportsJsonMode: true,
500
508
  supportsSystemMessages: true
501
509
  };
502
510
  };
@@ -76,6 +76,11 @@ function parameterToJsonSchema(param) {
76
76
  }
77
77
  return schema;
78
78
  }
79
+ function toOllamaFormat(rf) {
80
+ if (!rf) return void 0;
81
+ if (rf.type === "json_object") return "json";
82
+ return rf.json_schema.schema;
83
+ }
79
84
  function formatTools(actions) {
80
85
  return actions.map((action) => ({
81
86
  type: "function",
@@ -238,12 +243,14 @@ var OllamaAdapter = class {
238
243
  if (this.config.options) {
239
244
  Object.assign(ollamaOptions, this.config.options);
240
245
  }
246
+ const ollamaFormat = toOllamaFormat(request.config?.responseFormat);
241
247
  const payload = {
242
248
  model: request.config?.model || this.model,
243
249
  messages,
244
250
  tools,
245
251
  stream: true,
246
- options: ollamaOptions
252
+ options: ollamaOptions,
253
+ ...ollamaFormat !== void 0 ? { format: ollamaFormat } : {}
247
254
  };
248
255
  logProviderPayload("ollama", "request payload", payload, request.debug);
249
256
  const response = await fetch(`${this.baseUrl}/api/chat`, {
@@ -494,7 +501,8 @@ function createOllama(config = {}) {
494
501
  supportsVideo: false,
495
502
  maxTokens: model.maxTokens,
496
503
  supportedImageTypes: model.vision ? ["image/png", "image/jpeg", "image/gif"] : [],
497
- supportsJsonMode: false,
504
+ // Ollama 0.5+ supports `format: "json"` and JSON-schema constrained output.
505
+ supportsJsonMode: true,
498
506
  supportsSystemMessages: true
499
507
  };
500
508
  };
@@ -1,7 +1,7 @@
1
- import { L as LanguageModel } from '../../types-CR8mi9I0.mjs';
2
- import { O as OpenAIProviderConfig, A as AIProvider } from '../../types-DRqxMIjF.mjs';
1
+ import { L as LanguageModel } from '../../types-BkQCSiIt.mjs';
2
+ import { O as OpenAIProviderConfig, 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
  * OpenAI Provider - Modern Pattern
@@ -1,7 +1,7 @@
1
- import { L as LanguageModel } from '../../types-CR8mi9I0.js';
2
- import { O as OpenAIProviderConfig, A as AIProvider } from '../../types-BctsnC3g.js';
1
+ import { L as LanguageModel } from '../../types-BkQCSiIt.js';
2
+ import { O as OpenAIProviderConfig, 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
  * OpenAI Provider - Modern Pattern