@yourgpt/llm-sdk 2.5.0 → 2.5.1-beta.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 (62) hide show
  1. package/README.md +19 -1
  2. package/dist/adapters/index.d.mts +4 -4
  3. package/dist/adapters/index.d.ts +4 -4
  4. package/dist/adapters/index.js +293 -23
  5. package/dist/adapters/index.mjs +293 -23
  6. package/dist/base-BYQKp9TW.d.mts +263 -0
  7. package/dist/base-Cxq3ni0t.d.ts +263 -0
  8. package/dist/fallback/index.d.mts +4 -4
  9. package/dist/fallback/index.d.ts +4 -4
  10. package/dist/index.d.mts +61 -8
  11. package/dist/index.d.ts +61 -8
  12. package/dist/index.js +71 -0
  13. package/dist/index.mjs +71 -0
  14. package/dist/providers/anthropic/index.d.mts +3 -3
  15. package/dist/providers/anthropic/index.d.ts +3 -3
  16. package/dist/providers/anthropic/index.js +360 -203
  17. package/dist/providers/anthropic/index.mjs +360 -203
  18. package/dist/providers/azure/index.d.mts +3 -3
  19. package/dist/providers/azure/index.d.ts +3 -3
  20. package/dist/providers/azure/index.js +49 -1
  21. package/dist/providers/azure/index.mjs +49 -1
  22. package/dist/providers/fireworks/index.d.mts +1 -1
  23. package/dist/providers/fireworks/index.d.ts +1 -1
  24. package/dist/providers/fireworks/index.js +56 -0
  25. package/dist/providers/fireworks/index.mjs +56 -0
  26. package/dist/providers/google/index.d.mts +3 -3
  27. package/dist/providers/google/index.d.ts +3 -3
  28. package/dist/providers/google/index.js +303 -207
  29. package/dist/providers/google/index.mjs +303 -207
  30. package/dist/providers/ollama/index.d.mts +4 -4
  31. package/dist/providers/ollama/index.d.ts +4 -4
  32. package/dist/providers/ollama/index.js +10 -2
  33. package/dist/providers/ollama/index.mjs +10 -2
  34. package/dist/providers/openai/index.d.mts +3 -3
  35. package/dist/providers/openai/index.d.ts +3 -3
  36. package/dist/providers/openai/index.js +318 -216
  37. package/dist/providers/openai/index.mjs +318 -216
  38. package/dist/providers/openrouter/index.d.mts +3 -3
  39. package/dist/providers/openrouter/index.d.ts +3 -3
  40. package/dist/providers/openrouter/index.js +308 -206
  41. package/dist/providers/openrouter/index.mjs +308 -206
  42. package/dist/providers/togetherai/index.d.mts +3 -3
  43. package/dist/providers/togetherai/index.d.ts +3 -3
  44. package/dist/providers/togetherai/index.js +308 -206
  45. package/dist/providers/togetherai/index.mjs +308 -206
  46. package/dist/providers/xai/index.d.mts +3 -3
  47. package/dist/providers/xai/index.d.ts +3 -3
  48. package/dist/providers/xai/index.js +307 -210
  49. package/dist/providers/xai/index.mjs +307 -210
  50. package/dist/{types-BctsnC3g.d.ts → types-BvkiJ1dd.d.mts} +2 -1
  51. package/dist/{types-38yolWJn.d.ts → types-ChORafYS.d.ts} +1 -1
  52. package/dist/types-D774b0dg.d.mts +1018 -0
  53. package/dist/types-D774b0dg.d.ts +1018 -0
  54. package/dist/{types-DRqxMIjF.d.mts → types-TMilS-Dz.d.ts} +2 -1
  55. package/dist/{types-D4YfrQJR.d.mts → types-mwMhCwOq.d.mts} +1 -1
  56. package/dist/yourgpt/index.d.mts +1 -1
  57. package/dist/yourgpt/index.d.ts +1 -1
  58. package/package.json +1 -1
  59. package/dist/base-D-U61JaB.d.mts +0 -788
  60. package/dist/base-iGi9Va6Z.d.ts +0 -788
  61. package/dist/types-CR8mi9I0.d.mts +0 -417
  62. package/dist/types-CR8mi9I0.d.ts +0 -417
@@ -1,3 +1,259 @@
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 toOpenAIResponsesMcpTools(mcpServers) {
134
+ if (!mcpServers || mcpServers.length === 0) return [];
135
+ return mcpServers.map((mcp) => ({
136
+ type: "mcp",
137
+ server_label: mcp.label,
138
+ server_url: mcp.url,
139
+ ...mcp.headers ? { headers: mcp.headers } : {},
140
+ ...mcp.allowedTools ? { allowed_tools: mcp.allowedTools } : {},
141
+ require_approval: mcp.requireApproval ?? "never"
142
+ }));
143
+ }
144
+ function isStringEffort(effort) {
145
+ return typeof effort === "string" && (effort === "minimal" || effort === "low" || effort === "medium" || effort === "high");
146
+ }
147
+ function toOpenAIReasoning(effort) {
148
+ if (!effort) return void 0;
149
+ if (typeof effort === "object" && "raw" in effort) return effort.raw;
150
+ if (typeof effort === "object" && "budgetTokens" in effort) {
151
+ const budget = effort.budgetTokens;
152
+ const mapped = budget >= 16e3 ? "high" : budget >= 8e3 ? "medium" : "low";
153
+ return { effort: mapped, summary: "auto" };
154
+ }
155
+ if (isStringEffort(effort)) {
156
+ return { effort, summary: "auto" };
157
+ }
158
+ return void 0;
159
+ }
160
+ function formatTools(actions) {
161
+ return actions.map((action) => ({
162
+ type: "function",
163
+ function: {
164
+ name: action.name,
165
+ description: action.description,
166
+ parameters: {
167
+ type: "object",
168
+ properties: action.parameters ? Object.fromEntries(
169
+ Object.entries(action.parameters).map(([key, param]) => [
170
+ key,
171
+ parameterToJsonSchema(param)
172
+ ])
173
+ ) : {},
174
+ required: action.parameters ? Object.entries(action.parameters).filter(([, param]) => param.required).map(([key]) => key) : [],
175
+ additionalProperties: false
176
+ }
177
+ }
178
+ }));
179
+ }
180
+ function hasImageAttachments(message) {
181
+ const attachments = message.metadata?.attachments;
182
+ return attachments?.some((a) => a.type === "image") ?? false;
183
+ }
184
+ function attachmentToOpenAIImage(attachment) {
185
+ if (attachment.type !== "image") return null;
186
+ let imageUrl;
187
+ if (attachment.url) {
188
+ imageUrl = attachment.url;
189
+ } else if (attachment.data) {
190
+ imageUrl = attachment.data.startsWith("data:") ? attachment.data : `data:${attachment.mimeType || "image/png"};base64,${attachment.data}`;
191
+ } else {
192
+ return null;
193
+ }
194
+ return {
195
+ type: "image_url",
196
+ image_url: {
197
+ url: imageUrl,
198
+ detail: "auto"
199
+ }
200
+ };
201
+ }
202
+ function messageToOpenAIContent(message) {
203
+ const attachments = message.metadata?.attachments;
204
+ const content = message.content ?? "";
205
+ if (!hasImageAttachments(message)) {
206
+ return content;
207
+ }
208
+ const blocks = [];
209
+ if (content) {
210
+ blocks.push({ type: "text", text: content });
211
+ }
212
+ if (attachments) {
213
+ for (const attachment of attachments) {
214
+ const imageBlock = attachmentToOpenAIImage(attachment);
215
+ if (imageBlock) {
216
+ blocks.push(imageBlock);
217
+ }
218
+ }
219
+ }
220
+ return blocks;
221
+ }
222
+ function formatMessagesForOpenAI(messages, systemPrompt) {
223
+ const formatted = [];
224
+ if (systemPrompt) {
225
+ formatted.push({ role: "system", content: systemPrompt });
226
+ }
227
+ for (const msg of messages) {
228
+ if (msg.role === "system") {
229
+ formatted.push({ role: "system", content: msg.content ?? "" });
230
+ } else if (msg.role === "user") {
231
+ formatted.push({
232
+ role: "user",
233
+ content: messageToOpenAIContent(msg)
234
+ });
235
+ } else if (msg.role === "assistant") {
236
+ const hasToolCalls = msg.tool_calls && msg.tool_calls.length > 0;
237
+ const assistantMsg = {
238
+ role: "assistant",
239
+ // Gemini/xAI (OpenAI-compatible) reject content: "" on assistant messages with tool_calls
240
+ content: hasToolCalls ? msg.content || null : msg.content
241
+ };
242
+ if (hasToolCalls) {
243
+ assistantMsg.tool_calls = msg.tool_calls;
244
+ }
245
+ formatted.push(assistantMsg);
246
+ } else if (msg.role === "tool" && msg.tool_call_id) {
247
+ formatted.push({
248
+ role: "tool",
249
+ content: msg.content ?? "",
250
+ tool_call_id: msg.tool_call_id
251
+ });
252
+ }
253
+ }
254
+ return formatted;
255
+ }
256
+
1
257
  // src/providers/google/provider.ts
2
258
  var GOOGLE_MODELS = {
3
259
  // Gemini 2.5 (Experimental)
@@ -117,7 +373,8 @@ function google(modelId, options = {}) {
117
373
  messages,
118
374
  tools: params.tools,
119
375
  temperature: params.temperature,
120
- max_tokens: params.maxTokens
376
+ max_tokens: params.maxTokens,
377
+ response_format: toOpenAIResponseFormat(params.responseFormat)
121
378
  });
122
379
  const choice = response.choices[0];
123
380
  const message = choice.message;
@@ -149,6 +406,7 @@ function google(modelId, options = {}) {
149
406
  tools: params.tools,
150
407
  temperature: params.temperature,
151
408
  max_tokens: params.maxTokens,
409
+ response_format: toOpenAIResponseFormat(params.responseFormat),
152
410
  stream: true
153
411
  });
154
412
  let currentToolCall = null;
@@ -294,204 +552,6 @@ function generateToolCallId() {
294
552
  return generateId("call");
295
553
  }
296
554
 
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
555
  // src/adapters/openai.ts
496
556
  var OpenAIAdapter = class _OpenAIAdapter {
497
557
  constructor(config) {
@@ -517,6 +577,14 @@ var OpenAIAdapter = class _OpenAIAdapter {
517
577
  return this.client;
518
578
  }
519
579
  shouldUseResponsesApi(request) {
580
+ if (request.config?.mcpServers && request.config.mcpServers.length > 0 || request.config?.reasoningEffort !== void 0) {
581
+ if (this.provider !== "openai" && this.provider !== "azure") {
582
+ throw new Error(
583
+ `[llm-sdk] Provider "${this.provider}" does not support MCP servers or per-request reasoning effort. Use OpenAI or Anthropic for these features.`
584
+ );
585
+ }
586
+ return true;
587
+ }
520
588
  return request.providerToolOptions?.openai?.nativeToolSearch?.enabled === true && request.providerToolOptions.openai.nativeToolSearch.useResponsesApi !== false && Array.isArray(request.toolDefinitions) && request.toolDefinitions.length > 0;
521
589
  }
522
590
  buildResponsesInput(request) {
@@ -577,7 +645,7 @@ var OpenAIAdapter = class _OpenAIAdapter {
577
645
  strict: true,
578
646
  defer_loading: tool.deferLoading === true
579
647
  }));
580
- return [{ type: "tool_search" }, ...nativeTools];
648
+ return nativeTools.length > 0 ? [{ type: "tool_search" }, ...nativeTools] : [];
581
649
  }
582
650
  parseResponsesResult(response) {
583
651
  const content = typeof response?.output_text === "string" ? response.output_text : "";
@@ -606,15 +674,33 @@ var OpenAIAdapter = class _OpenAIAdapter {
606
674
  async completeWithResponses(request) {
607
675
  const client = await this.getClient();
608
676
  const openaiToolOptions = request.providerToolOptions?.openai;
677
+ const responsesTextFormat = toOpenAIResponsesTextFormat(
678
+ request.config?.responseFormat
679
+ );
680
+ const mcpTools = toOpenAIResponsesMcpTools(request.config?.mcpServers);
681
+ const modelId = request.config?.model || this.model;
682
+ const reasoning = isOpenAIReasoningModel(modelId) ? toOpenAIReasoning(request.config?.reasoningEffort) : void 0;
683
+ if (request.config?.reasoningEffort && !isOpenAIReasoningModel(modelId)) {
684
+ console.warn(
685
+ `[llm-sdk] openai/${modelId} is not a reasoning model; \`reasoningEffort\` is ignored. Use o1/o3/o4/gpt-5.x for reasoning.`
686
+ );
687
+ }
688
+ const functionTools = this.buildResponsesTools(
689
+ request.toolDefinitions ?? []
690
+ );
691
+ const tools = [...functionTools, ...mcpTools];
609
692
  const payload = {
610
693
  model: request.config?.model || this.model,
611
694
  instructions: request.systemPrompt,
612
695
  input: this.buildResponsesInput(request),
613
- tools: this.buildResponsesTools(request.toolDefinitions ?? []),
696
+ tools: tools.length > 0 ? tools : void 0,
614
697
  tool_choice: openaiToolOptions?.toolChoice === "required" ? "required" : openaiToolOptions?.toolChoice === "auto" ? "auto" : void 0,
615
698
  parallel_tool_calls: openaiToolOptions?.parallelToolCalls,
616
699
  temperature: request.config?.temperature ?? this.config.temperature,
617
700
  max_output_tokens: request.config?.maxTokens ?? this.config.maxTokens,
701
+ ...responsesTextFormat ? { text: { format: responsesTextFormat } } : {},
702
+ ...reasoning ? { reasoning } : {},
703
+ store: false,
618
704
  stream: false
619
705
  };
620
706
  logProviderPayload("openai", "request payload", payload, request.debug);
@@ -736,14 +822,19 @@ var OpenAIAdapter = class _OpenAIAdapter {
736
822
  name: openaiToolOptions.toolChoice.name
737
823
  }
738
824
  } : openaiToolOptions?.toolChoice;
825
+ const modelIdForPayload = request.config?.model || this.model;
739
826
  const payload = {
740
- model: request.config?.model || this.model,
827
+ model: modelIdForPayload,
741
828
  messages,
742
829
  tools: tools.length > 0 ? tools : void 0,
743
830
  tool_choice: tools.length > 0 ? toolChoice : void 0,
744
831
  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,
832
+ ...buildOpenAITokenParams(
833
+ modelIdForPayload,
834
+ request.config?.maxTokens ?? this.config.maxTokens,
835
+ request.config?.temperature ?? this.config.temperature
836
+ ),
837
+ response_format: toOpenAIResponseFormat(request.config?.responseFormat),
747
838
  stream: true,
748
839
  stream_options: { include_usage: true }
749
840
  };
@@ -885,14 +976,19 @@ var OpenAIAdapter = class _OpenAIAdapter {
885
976
  name: openaiToolOptions.toolChoice.name
886
977
  }
887
978
  } : openaiToolOptions?.toolChoice;
979
+ const modelIdForCompletePayload = request.config?.model || this.model;
888
980
  const payload = {
889
- model: request.config?.model || this.model,
981
+ model: modelIdForCompletePayload,
890
982
  messages,
891
983
  tools: tools.length > 0 ? tools : void 0,
892
984
  tool_choice: tools.length > 0 ? toolChoice : void 0,
893
985
  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,
986
+ ...buildOpenAITokenParams(
987
+ modelIdForCompletePayload,
988
+ request.config?.maxTokens ?? this.config.maxTokens,
989
+ request.config?.temperature ?? this.config.temperature
990
+ ),
991
+ response_format: toOpenAIResponseFormat(request.config?.responseFormat),
896
992
  stream: false
897
993
  };
898
994
  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-BvkiJ1dd.mjs';
2
+ export { d as OllamaModelOptions } from '../../types-BvkiJ1dd.mjs';
3
+ import '../../types-D774b0dg.mjs';
5
4
  import 'zod';
5
+ import '../../base-BYQKp9TW.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-TMilS-Dz.js';
2
+ export { d as OllamaModelOptions } from '../../types-TMilS-Dz.js';
3
+ import '../../types-D774b0dg.js';
5
4
  import 'zod';
5
+ import '../../base-Cxq3ni0t.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-D774b0dg.mjs';
2
+ import { O as OpenAIProviderConfig, A as AIProvider } from '../../types-BvkiJ1dd.mjs';
3
3
  import 'zod';
4
- import '../../base-D-U61JaB.mjs';
4
+ import '../../base-BYQKp9TW.mjs';
5
5
 
6
6
  /**
7
7
  * OpenAI Provider - Modern Pattern