@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
package/dist/index.mjs CHANGED
@@ -133,6 +133,11 @@ function formatToolsForGoogle(tools) {
133
133
  // src/core/generate-text.ts
134
134
  async function generateText(params) {
135
135
  const { model, tools, maxSteps = 1, signal } = params;
136
+ if (params.responseFormat && model.capabilities.supportsJsonMode === false) {
137
+ console.warn(
138
+ `[llm-sdk] ${model.provider}/${model.modelId} does not support structured output (responseFormat); the request will be sent but the provider may ignore it.`
139
+ );
140
+ }
136
141
  let messages = buildMessages(params);
137
142
  const steps = [];
138
143
  const allToolCalls = [];
@@ -147,6 +152,7 @@ async function generateText(params) {
147
152
  tools: formattedTools,
148
153
  temperature: params.temperature,
149
154
  maxTokens: params.maxTokens,
155
+ responseFormat: params.responseFormat,
150
156
  signal
151
157
  });
152
158
  const stepToolResults = [];
@@ -264,6 +270,11 @@ function sumUsage(steps) {
264
270
  // src/core/stream-text.ts
265
271
  async function streamText(params) {
266
272
  const { model, tools, maxSteps = 1, signal } = params;
273
+ if (params.responseFormat && model.capabilities.supportsJsonMode === false) {
274
+ console.warn(
275
+ `[llm-sdk] ${model.provider}/${model.modelId} does not support structured output (responseFormat); the request will be sent but the provider may ignore it.`
276
+ );
277
+ }
267
278
  let fullText = "";
268
279
  let finalUsage = {
269
280
  promptTokens: 0,
@@ -289,6 +300,7 @@ async function streamText(params) {
289
300
  tools: formattedTools,
290
301
  temperature: params.temperature,
291
302
  maxTokens: params.maxTokens,
303
+ responseFormat: params.responseFormat,
292
304
  signal
293
305
  })) {
294
306
  switch (chunk.type) {
@@ -1,7 +1,7 @@
1
- import { L as LanguageModel } from '../../types-CR8mi9I0.mjs';
2
- import { a as AnthropicProviderConfig, A as AIProvider } from '../../types-DRqxMIjF.mjs';
1
+ import { L as LanguageModel } from '../../types-BkQCSiIt.mjs';
2
+ import { a as AnthropicProviderConfig, 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
  * Anthropic Provider - Modern Pattern
@@ -1,7 +1,7 @@
1
- import { L as LanguageModel } from '../../types-CR8mi9I0.js';
2
- import { a as AnthropicProviderConfig, A as AIProvider } from '../../types-BctsnC3g.js';
1
+ import { L as LanguageModel } from '../../types-BkQCSiIt.js';
2
+ import { a as AnthropicProviderConfig, 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
  * Anthropic Provider - Modern Pattern
@@ -1,5 +1,243 @@
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 stripSchemaKeys(schema, keysToDrop, options = {}) {
43
+ if (Array.isArray(schema)) {
44
+ return schema.map((item) => stripSchemaKeys(item, keysToDrop, options));
45
+ }
46
+ if (!schema || typeof schema !== "object") return schema;
47
+ const out = {};
48
+ for (const [key, value] of Object.entries(
49
+ schema
50
+ )) {
51
+ if (keysToDrop.has(key)) continue;
52
+ const renamed = options.renameKeys?.[key] ?? key;
53
+ out[renamed] = stripSchemaKeys(value, keysToDrop, options);
54
+ }
55
+ if (options.forceAdditionalPropertiesFalse && out.type === "object") {
56
+ out.additionalProperties = false;
57
+ }
58
+ return out;
59
+ }
60
+ var ANTHROPIC_UNSUPPORTED_KEYS = /* @__PURE__ */ new Set([
61
+ "minimum",
62
+ "maximum",
63
+ "exclusiveMinimum",
64
+ "exclusiveMaximum",
65
+ "multipleOf",
66
+ "minLength",
67
+ "maxLength",
68
+ "minItems",
69
+ "maxItems",
70
+ "minProperties",
71
+ "maxProperties",
72
+ "pattern",
73
+ "$schema"
74
+ ]);
75
+ function toAnthropicOutputConfig(rf) {
76
+ if (!rf || rf.type !== "json_schema") return void 0;
77
+ const schema = stripSchemaKeys(
78
+ rf.json_schema.schema,
79
+ ANTHROPIC_UNSUPPORTED_KEYS,
80
+ {
81
+ forceAdditionalPropertiesFalse: true,
82
+ renameKeys: { oneOf: "anyOf" }
83
+ }
84
+ );
85
+ return {
86
+ format: {
87
+ type: "json_schema",
88
+ schema
89
+ }
90
+ };
91
+ }
92
+ function hasMediaAttachments(message) {
93
+ const attachments = message.metadata?.attachments;
94
+ return attachments?.some(
95
+ (a) => a.type === "image" || a.type === "file" && a.mimeType === "application/pdf"
96
+ ) ?? false;
97
+ }
98
+ function attachmentToAnthropicImage(attachment) {
99
+ if (attachment.type !== "image") return null;
100
+ if (attachment.url) {
101
+ return {
102
+ type: "image",
103
+ source: {
104
+ type: "url",
105
+ url: attachment.url
106
+ }
107
+ };
108
+ }
109
+ if (!attachment.data) return null;
110
+ let base64Data = attachment.data;
111
+ if (base64Data.startsWith("data:")) {
112
+ const commaIndex = base64Data.indexOf(",");
113
+ if (commaIndex !== -1) {
114
+ base64Data = base64Data.slice(commaIndex + 1);
115
+ }
116
+ }
117
+ return {
118
+ type: "image",
119
+ source: {
120
+ type: "base64",
121
+ media_type: attachment.mimeType || "image/png",
122
+ data: base64Data
123
+ }
124
+ };
125
+ }
126
+ function attachmentToAnthropicDocument(attachment) {
127
+ if (attachment.type !== "file" || attachment.mimeType !== "application/pdf") {
128
+ return null;
129
+ }
130
+ if (attachment.url) {
131
+ return {
132
+ type: "document",
133
+ source: {
134
+ type: "url",
135
+ url: attachment.url
136
+ }
137
+ };
138
+ }
139
+ if (!attachment.data) return null;
140
+ let base64Data = attachment.data;
141
+ if (base64Data.startsWith("data:")) {
142
+ const commaIndex = base64Data.indexOf(",");
143
+ if (commaIndex !== -1) {
144
+ base64Data = base64Data.slice(commaIndex + 1);
145
+ }
146
+ }
147
+ return {
148
+ type: "document",
149
+ source: {
150
+ type: "base64",
151
+ media_type: "application/pdf",
152
+ data: base64Data
153
+ }
154
+ };
155
+ }
156
+ function messageToAnthropicContent(message) {
157
+ const attachments = message.metadata?.attachments;
158
+ const content = message.content ?? "";
159
+ if (!hasMediaAttachments(message)) {
160
+ return content;
161
+ }
162
+ const blocks = [];
163
+ if (attachments) {
164
+ for (const attachment of attachments) {
165
+ const imageBlock = attachmentToAnthropicImage(attachment);
166
+ if (imageBlock) {
167
+ blocks.push(imageBlock);
168
+ continue;
169
+ }
170
+ const docBlock = attachmentToAnthropicDocument(attachment);
171
+ if (docBlock) {
172
+ blocks.push(docBlock);
173
+ }
174
+ }
175
+ }
176
+ if (content) {
177
+ blocks.push({ type: "text", text: content });
178
+ }
179
+ return blocks;
180
+ }
181
+ function formatMessagesForAnthropic(messages, systemPrompt) {
182
+ const formatted = [];
183
+ for (let i = 0; i < messages.length; i++) {
184
+ const msg = messages[i];
185
+ if (msg.role === "system") continue;
186
+ if (msg.role === "assistant") {
187
+ const content = [];
188
+ if (msg.content) {
189
+ content.push({ type: "text", text: msg.content });
190
+ }
191
+ if (msg.tool_calls && msg.tool_calls.length > 0) {
192
+ for (const tc of msg.tool_calls) {
193
+ content.push({
194
+ type: "tool_use",
195
+ id: tc.id,
196
+ name: tc.function.name,
197
+ input: JSON.parse(tc.function.arguments)
198
+ });
199
+ }
200
+ }
201
+ formatted.push({
202
+ role: "assistant",
203
+ content: content.length === 1 && content[0].type === "text" ? content[0].text : content
204
+ });
205
+ } else if (msg.role === "tool" && msg.tool_call_id) {
206
+ const toolResults = [
207
+ {
208
+ type: "tool_result",
209
+ tool_use_id: msg.tool_call_id,
210
+ content: msg.content ?? ""
211
+ }
212
+ ];
213
+ while (i + 1 < messages.length && messages[i + 1].role === "tool") {
214
+ i++;
215
+ const nextTool = messages[i];
216
+ if (nextTool.tool_call_id) {
217
+ toolResults.push({
218
+ type: "tool_result",
219
+ tool_use_id: nextTool.tool_call_id,
220
+ content: nextTool.content ?? ""
221
+ });
222
+ }
223
+ }
224
+ formatted.push({
225
+ role: "user",
226
+ content: toolResults
227
+ });
228
+ } else if (msg.role === "user") {
229
+ formatted.push({
230
+ role: "user",
231
+ content: messageToAnthropicContent(msg)
232
+ });
233
+ }
234
+ }
235
+ return {
236
+ system: "",
237
+ messages: formatted
238
+ };
239
+ }
240
+
3
241
  // src/providers/anthropic/provider.ts
4
242
  var ANTHROPIC_MODELS = {
5
243
  // Claude 4 series
@@ -8,6 +246,7 @@ var ANTHROPIC_MODELS = {
8
246
  tools: true,
9
247
  thinking: true,
10
248
  pdf: true,
249
+ jsonMode: true,
11
250
  maxTokens: 2e5
12
251
  },
13
252
  "claude-opus-4-20250514": {
@@ -15,6 +254,7 @@ var ANTHROPIC_MODELS = {
15
254
  tools: true,
16
255
  thinking: true,
17
256
  pdf: true,
257
+ jsonMode: true,
18
258
  maxTokens: 2e5
19
259
  },
20
260
  // Claude 3.7 series
@@ -23,6 +263,7 @@ var ANTHROPIC_MODELS = {
23
263
  tools: true,
24
264
  thinking: true,
25
265
  pdf: true,
266
+ jsonMode: true,
26
267
  maxTokens: 2e5
27
268
  },
28
269
  "claude-3-7-sonnet-latest": {
@@ -30,6 +271,7 @@ var ANTHROPIC_MODELS = {
30
271
  tools: true,
31
272
  thinking: true,
32
273
  pdf: true,
274
+ jsonMode: true,
33
275
  maxTokens: 2e5
34
276
  },
35
277
  // Claude 3.5 series
@@ -38,6 +280,7 @@ var ANTHROPIC_MODELS = {
38
280
  tools: true,
39
281
  thinking: false,
40
282
  pdf: true,
283
+ jsonMode: true,
41
284
  maxTokens: 2e5
42
285
  },
43
286
  "claude-3-5-sonnet-latest": {
@@ -45,6 +288,7 @@ var ANTHROPIC_MODELS = {
45
288
  tools: true,
46
289
  thinking: false,
47
290
  pdf: true,
291
+ jsonMode: true,
48
292
  maxTokens: 2e5
49
293
  },
50
294
  "claude-3-5-haiku-20241022": {
@@ -52,6 +296,7 @@ var ANTHROPIC_MODELS = {
52
296
  tools: true,
53
297
  thinking: false,
54
298
  pdf: false,
299
+ jsonMode: true,
55
300
  maxTokens: 2e5
56
301
  },
57
302
  "claude-3-5-haiku-latest": {
@@ -59,6 +304,7 @@ var ANTHROPIC_MODELS = {
59
304
  tools: true,
60
305
  thinking: false,
61
306
  pdf: false,
307
+ jsonMode: true,
62
308
  maxTokens: 2e5
63
309
  },
64
310
  // Claude 3 series
@@ -67,6 +313,7 @@ var ANTHROPIC_MODELS = {
67
313
  tools: true,
68
314
  thinking: false,
69
315
  pdf: false,
316
+ jsonMode: false,
70
317
  maxTokens: 2e5
71
318
  },
72
319
  "claude-3-sonnet-20240229": {
@@ -74,6 +321,7 @@ var ANTHROPIC_MODELS = {
74
321
  tools: true,
75
322
  thinking: false,
76
323
  pdf: false,
324
+ jsonMode: false,
77
325
  maxTokens: 2e5
78
326
  },
79
327
  "claude-3-haiku-20240307": {
@@ -81,6 +329,7 @@ var ANTHROPIC_MODELS = {
81
329
  tools: true,
82
330
  thinking: false,
83
331
  pdf: false,
332
+ jsonMode: false,
84
333
  maxTokens: 2e5
85
334
  }
86
335
  };
@@ -105,7 +354,7 @@ function anthropic(modelId, options = {}) {
105
354
  supportsVision: modelConfig.vision,
106
355
  supportsTools: modelConfig.tools,
107
356
  supportsStreaming: true,
108
- supportsJsonMode: false,
357
+ supportsJsonMode: modelConfig.jsonMode,
109
358
  supportsThinking: modelConfig.thinking,
110
359
  supportsPDF: modelConfig.pdf,
111
360
  maxTokens: modelConfig.maxTokens,
@@ -113,7 +362,7 @@ function anthropic(modelId, options = {}) {
113
362
  },
114
363
  async doGenerate(params) {
115
364
  const client2 = await getClient();
116
- const { system, messages } = formatMessagesForAnthropic(params.messages);
365
+ const { system, messages } = formatMessagesForAnthropic2(params.messages);
117
366
  const requestOptions = {
118
367
  model: modelId,
119
368
  max_tokens: params.maxTokens ?? 4096,
@@ -130,6 +379,10 @@ function anthropic(modelId, options = {}) {
130
379
  budget_tokens: options.thinking.budgetTokens ?? 1e4
131
380
  };
132
381
  }
382
+ const outputConfig = toAnthropicOutputConfig(params.responseFormat);
383
+ if (outputConfig) {
384
+ requestOptions.output_config = outputConfig;
385
+ }
133
386
  const response = await client2.messages.create(requestOptions);
134
387
  let text = "";
135
388
  const toolCalls = [];
@@ -158,7 +411,7 @@ function anthropic(modelId, options = {}) {
158
411
  },
159
412
  async *doStream(params) {
160
413
  const client2 = await getClient();
161
- const { system, messages } = formatMessagesForAnthropic(params.messages);
414
+ const { system, messages } = formatMessagesForAnthropic2(params.messages);
162
415
  const requestOptions = {
163
416
  model: modelId,
164
417
  max_tokens: params.maxTokens ?? 4096,
@@ -175,6 +428,10 @@ function anthropic(modelId, options = {}) {
175
428
  budget_tokens: options.thinking.budgetTokens ?? 1e4
176
429
  };
177
430
  }
431
+ const outputConfig = toAnthropicOutputConfig(params.responseFormat);
432
+ if (outputConfig) {
433
+ requestOptions.output_config = outputConfig;
434
+ }
178
435
  const stream = await client2.messages.stream(requestOptions);
179
436
  let currentToolUse = null;
180
437
  let inputTokens = 0;
@@ -253,7 +510,7 @@ function mapFinishReason(reason) {
253
510
  return "unknown";
254
511
  }
255
512
  }
256
- function formatMessagesForAnthropic(messages) {
513
+ function formatMessagesForAnthropic2(messages) {
257
514
  let system = "";
258
515
  const formatted = [];
259
516
  const pendingToolResults = [];
@@ -362,194 +619,6 @@ function generateMessageId() {
362
619
  return generateId("msg");
363
620
  }
364
621
 
365
- // src/adapters/base.ts
366
- function stringifyForDebug(value) {
367
- return JSON.stringify(
368
- value,
369
- (_key, currentValue) => {
370
- if (typeof currentValue === "bigint") {
371
- return currentValue.toString();
372
- }
373
- if (currentValue instanceof Error) {
374
- return {
375
- name: currentValue.name,
376
- message: currentValue.message,
377
- stack: currentValue.stack
378
- };
379
- }
380
- return currentValue;
381
- },
382
- 2
383
- );
384
- }
385
- function logProviderPayload(provider, label, payload, enabled) {
386
- if (!enabled) {
387
- return;
388
- }
389
- if (label.toLowerCase().includes("stream ")) {
390
- return;
391
- }
392
- try {
393
- console.log(
394
- `[llm-sdk:${provider}] ${label}
395
- ${stringifyForDebug(payload)}`
396
- );
397
- } catch (error) {
398
- console.log(
399
- `[llm-sdk:${provider}] ${label} (failed to stringify payload)`,
400
- error
401
- );
402
- }
403
- }
404
- function hasMediaAttachments(message) {
405
- const attachments = message.metadata?.attachments;
406
- return attachments?.some(
407
- (a) => a.type === "image" || a.type === "file" && a.mimeType === "application/pdf"
408
- ) ?? false;
409
- }
410
- function attachmentToAnthropicImage(attachment) {
411
- if (attachment.type !== "image") return null;
412
- if (attachment.url) {
413
- return {
414
- type: "image",
415
- source: {
416
- type: "url",
417
- url: attachment.url
418
- }
419
- };
420
- }
421
- if (!attachment.data) return null;
422
- let base64Data = attachment.data;
423
- if (base64Data.startsWith("data:")) {
424
- const commaIndex = base64Data.indexOf(",");
425
- if (commaIndex !== -1) {
426
- base64Data = base64Data.slice(commaIndex + 1);
427
- }
428
- }
429
- return {
430
- type: "image",
431
- source: {
432
- type: "base64",
433
- media_type: attachment.mimeType || "image/png",
434
- data: base64Data
435
- }
436
- };
437
- }
438
- function attachmentToAnthropicDocument(attachment) {
439
- if (attachment.type !== "file" || attachment.mimeType !== "application/pdf") {
440
- return null;
441
- }
442
- if (attachment.url) {
443
- return {
444
- type: "document",
445
- source: {
446
- type: "url",
447
- url: attachment.url
448
- }
449
- };
450
- }
451
- if (!attachment.data) return null;
452
- let base64Data = attachment.data;
453
- if (base64Data.startsWith("data:")) {
454
- const commaIndex = base64Data.indexOf(",");
455
- if (commaIndex !== -1) {
456
- base64Data = base64Data.slice(commaIndex + 1);
457
- }
458
- }
459
- return {
460
- type: "document",
461
- source: {
462
- type: "base64",
463
- media_type: "application/pdf",
464
- data: base64Data
465
- }
466
- };
467
- }
468
- function messageToAnthropicContent(message) {
469
- const attachments = message.metadata?.attachments;
470
- const content = message.content ?? "";
471
- if (!hasMediaAttachments(message)) {
472
- return content;
473
- }
474
- const blocks = [];
475
- if (attachments) {
476
- for (const attachment of attachments) {
477
- const imageBlock = attachmentToAnthropicImage(attachment);
478
- if (imageBlock) {
479
- blocks.push(imageBlock);
480
- continue;
481
- }
482
- const docBlock = attachmentToAnthropicDocument(attachment);
483
- if (docBlock) {
484
- blocks.push(docBlock);
485
- }
486
- }
487
- }
488
- if (content) {
489
- blocks.push({ type: "text", text: content });
490
- }
491
- return blocks;
492
- }
493
- function formatMessagesForAnthropic2(messages, systemPrompt) {
494
- const formatted = [];
495
- for (let i = 0; i < messages.length; i++) {
496
- const msg = messages[i];
497
- if (msg.role === "system") continue;
498
- if (msg.role === "assistant") {
499
- const content = [];
500
- if (msg.content) {
501
- content.push({ type: "text", text: msg.content });
502
- }
503
- if (msg.tool_calls && msg.tool_calls.length > 0) {
504
- for (const tc of msg.tool_calls) {
505
- content.push({
506
- type: "tool_use",
507
- id: tc.id,
508
- name: tc.function.name,
509
- input: JSON.parse(tc.function.arguments)
510
- });
511
- }
512
- }
513
- formatted.push({
514
- role: "assistant",
515
- content: content.length === 1 && content[0].type === "text" ? content[0].text : content
516
- });
517
- } else if (msg.role === "tool" && msg.tool_call_id) {
518
- const toolResults = [
519
- {
520
- type: "tool_result",
521
- tool_use_id: msg.tool_call_id,
522
- content: msg.content ?? ""
523
- }
524
- ];
525
- while (i + 1 < messages.length && messages[i + 1].role === "tool") {
526
- i++;
527
- const nextTool = messages[i];
528
- if (nextTool.tool_call_id) {
529
- toolResults.push({
530
- type: "tool_result",
531
- tool_use_id: nextTool.tool_call_id,
532
- content: nextTool.content ?? ""
533
- });
534
- }
535
- }
536
- formatted.push({
537
- role: "user",
538
- content: toolResults
539
- });
540
- } else if (msg.role === "user") {
541
- formatted.push({
542
- role: "user",
543
- content: messageToAnthropicContent(msg)
544
- });
545
- }
546
- }
547
- return {
548
- system: "",
549
- messages: formatted
550
- };
551
- }
552
-
553
622
  // src/adapters/anthropic.ts
554
623
  var AnthropicAdapter = class {
555
624
  constructor(config) {
@@ -772,12 +841,14 @@ var AnthropicAdapter = class {
772
841
  * Build common request options for both streaming and non-streaming
773
842
  */
774
843
  buildRequestOptions(request) {
775
- const systemMessage = request.systemPrompt || "";
844
+ const responseFormat = request.config?.responseFormat;
845
+ const jsonObjectSuffix = responseFormat?.type === "json_object" ? "\n\nRespond with a single JSON object and no other text." : "";
846
+ const systemMessage = (request.systemPrompt || "") + jsonObjectSuffix;
776
847
  let messages;
777
848
  if (request.rawMessages && request.rawMessages.length > 0) {
778
849
  messages = this.convertToAnthropicMessages(request.rawMessages);
779
850
  } else {
780
- const formatted = formatMessagesForAnthropic2(request.messages);
851
+ const formatted = formatMessagesForAnthropic(request.messages);
781
852
  messages = formatted.messages;
782
853
  }
783
854
  const anthropicNativeSearch = request.providerToolOptions?.anthropic?.nativeToolSearch;
@@ -853,6 +924,10 @@ var AnthropicAdapter = class {
853
924
  if (serverToolConfiguration) {
854
925
  options.server_tool_configuration = serverToolConfiguration;
855
926
  }
927
+ const outputConfig = toAnthropicOutputConfig(responseFormat);
928
+ if (outputConfig) {
929
+ options.output_config = outputConfig;
930
+ }
856
931
  if (this.config.thinking?.type === "enabled") {
857
932
  options.thinking = {
858
933
  type: "enabled",
@@ -1181,7 +1256,8 @@ function createAnthropic(config = {}) {
1181
1256
  "image/gif",
1182
1257
  "image/webp"
1183
1258
  ],
1184
- supportsJsonMode: false,
1259
+ // Native `output_config.format` — GA on Claude 3.5 and newer.
1260
+ supportsJsonMode: true,
1185
1261
  supportsSystemMessages: true
1186
1262
  };
1187
1263
  };