@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,298 @@
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 stripSchemaKeys(schema, keysToDrop, options = {}) {
41
+ if (Array.isArray(schema)) {
42
+ return schema.map((item) => stripSchemaKeys(item, keysToDrop, options));
43
+ }
44
+ if (!schema || typeof schema !== "object") return schema;
45
+ const out = {};
46
+ for (const [key, value] of Object.entries(
47
+ schema
48
+ )) {
49
+ if (keysToDrop.has(key)) continue;
50
+ const renamed = options.renameKeys?.[key] ?? key;
51
+ out[renamed] = stripSchemaKeys(value, keysToDrop, options);
52
+ }
53
+ if (options.forceAdditionalPropertiesFalse && out.type === "object") {
54
+ out.additionalProperties = false;
55
+ }
56
+ return out;
57
+ }
58
+ var ANTHROPIC_UNSUPPORTED_KEYS = /* @__PURE__ */ new Set([
59
+ "minimum",
60
+ "maximum",
61
+ "exclusiveMinimum",
62
+ "exclusiveMaximum",
63
+ "multipleOf",
64
+ "minLength",
65
+ "maxLength",
66
+ "minItems",
67
+ "maxItems",
68
+ "minProperties",
69
+ "maxProperties",
70
+ "pattern",
71
+ "$schema"
72
+ ]);
73
+ function toAnthropicOutputConfig(rf) {
74
+ if (!rf || rf.type !== "json_schema") return void 0;
75
+ const schema = stripSchemaKeys(
76
+ rf.json_schema.schema,
77
+ ANTHROPIC_UNSUPPORTED_KEYS,
78
+ {
79
+ forceAdditionalPropertiesFalse: true,
80
+ renameKeys: { oneOf: "anyOf" }
81
+ }
82
+ );
83
+ return {
84
+ format: {
85
+ type: "json_schema",
86
+ schema
87
+ }
88
+ };
89
+ }
90
+ function toAnthropicMcp(mcpServers) {
91
+ if (!mcpServers || mcpServers.length === 0) {
92
+ return { mcpServers: [], tools: [], betas: [] };
93
+ }
94
+ const serverEntries = [];
95
+ const toolEntries = [];
96
+ for (const mcp of mcpServers) {
97
+ const authHeader = mcp.headers?.Authorization ?? mcp.headers?.authorization;
98
+ const token = authHeader?.replace(/^Bearer\s+/i, "");
99
+ serverEntries.push({
100
+ type: "url",
101
+ url: mcp.url,
102
+ name: mcp.label,
103
+ ...token ? { authorization_token: token } : {}
104
+ });
105
+ if (mcp.allowedTools && mcp.allowedTools.length > 0) {
106
+ toolEntries.push({
107
+ type: "mcp_toolset",
108
+ mcp_server_name: mcp.label,
109
+ configs: Object.fromEntries(
110
+ mcp.allowedTools.map((toolName) => [toolName, {}])
111
+ )
112
+ });
113
+ }
114
+ }
115
+ return {
116
+ mcpServers: serverEntries,
117
+ tools: toolEntries,
118
+ betas: ["mcp-client-2025-11-20"]
119
+ };
120
+ }
121
+ function isStringEffort(effort) {
122
+ return typeof effort === "string" && (effort === "minimal" || effort === "low" || effort === "medium" || effort === "high");
123
+ }
124
+ var ANTHROPIC_ADAPTIVE_MODELS = /(claude-opus-4-7|claude-opus-4-6|claude-sonnet-4-6)/i;
125
+ function toAnthropicThinking(effort, modelId) {
126
+ if (!effort) return {};
127
+ if (typeof effort === "object" && "raw" in effort) {
128
+ return { thinking: effort.raw };
129
+ }
130
+ const isAdaptive = !!modelId && ANTHROPIC_ADAPTIVE_MODELS.test(modelId);
131
+ if (typeof effort === "object" && "budgetTokens" in effort) {
132
+ return {
133
+ thinking: { type: "enabled", budget_tokens: effort.budgetTokens }
134
+ };
135
+ }
136
+ if (!isStringEffort(effort)) return {};
137
+ if (isAdaptive) {
138
+ const mapped = effort === "minimal" ? "low" : effort;
139
+ return {
140
+ thinking: { type: "adaptive" },
141
+ outputConfigEffort: mapped
142
+ };
143
+ }
144
+ const budget = effort === "high" ? 16e3 : effort === "medium" ? 8e3 : effort === "low" ? 4e3 : 2048;
145
+ return { thinking: { type: "enabled", budget_tokens: budget } };
146
+ }
147
+ function hasMediaAttachments(message) {
148
+ const attachments = message.metadata?.attachments;
149
+ return attachments?.some(
150
+ (a) => a.type === "image" || a.type === "file" && a.mimeType === "application/pdf"
151
+ ) ?? false;
152
+ }
153
+ function attachmentToAnthropicImage(attachment) {
154
+ if (attachment.type !== "image") return null;
155
+ if (attachment.url) {
156
+ return {
157
+ type: "image",
158
+ source: {
159
+ type: "url",
160
+ url: attachment.url
161
+ }
162
+ };
163
+ }
164
+ if (!attachment.data) return null;
165
+ let base64Data = attachment.data;
166
+ if (base64Data.startsWith("data:")) {
167
+ const commaIndex = base64Data.indexOf(",");
168
+ if (commaIndex !== -1) {
169
+ base64Data = base64Data.slice(commaIndex + 1);
170
+ }
171
+ }
172
+ return {
173
+ type: "image",
174
+ source: {
175
+ type: "base64",
176
+ media_type: attachment.mimeType || "image/png",
177
+ data: base64Data
178
+ }
179
+ };
180
+ }
181
+ function attachmentToAnthropicDocument(attachment) {
182
+ if (attachment.type !== "file" || attachment.mimeType !== "application/pdf") {
183
+ return null;
184
+ }
185
+ if (attachment.url) {
186
+ return {
187
+ type: "document",
188
+ source: {
189
+ type: "url",
190
+ url: attachment.url
191
+ }
192
+ };
193
+ }
194
+ if (!attachment.data) return null;
195
+ let base64Data = attachment.data;
196
+ if (base64Data.startsWith("data:")) {
197
+ const commaIndex = base64Data.indexOf(",");
198
+ if (commaIndex !== -1) {
199
+ base64Data = base64Data.slice(commaIndex + 1);
200
+ }
201
+ }
202
+ return {
203
+ type: "document",
204
+ source: {
205
+ type: "base64",
206
+ media_type: "application/pdf",
207
+ data: base64Data
208
+ }
209
+ };
210
+ }
211
+ function messageToAnthropicContent(message) {
212
+ const attachments = message.metadata?.attachments;
213
+ const content = message.content ?? "";
214
+ if (!hasMediaAttachments(message)) {
215
+ return content;
216
+ }
217
+ const blocks = [];
218
+ if (attachments) {
219
+ for (const attachment of attachments) {
220
+ const imageBlock = attachmentToAnthropicImage(attachment);
221
+ if (imageBlock) {
222
+ blocks.push(imageBlock);
223
+ continue;
224
+ }
225
+ const docBlock = attachmentToAnthropicDocument(attachment);
226
+ if (docBlock) {
227
+ blocks.push(docBlock);
228
+ }
229
+ }
230
+ }
231
+ if (content) {
232
+ blocks.push({ type: "text", text: content });
233
+ }
234
+ return blocks;
235
+ }
236
+ function formatMessagesForAnthropic(messages, systemPrompt) {
237
+ const formatted = [];
238
+ for (let i = 0; i < messages.length; i++) {
239
+ const msg = messages[i];
240
+ if (msg.role === "system") continue;
241
+ if (msg.role === "assistant") {
242
+ const content = [];
243
+ if (msg.content) {
244
+ content.push({ type: "text", text: msg.content });
245
+ }
246
+ if (msg.tool_calls && msg.tool_calls.length > 0) {
247
+ for (const tc of msg.tool_calls) {
248
+ content.push({
249
+ type: "tool_use",
250
+ id: tc.id,
251
+ name: tc.function.name,
252
+ input: JSON.parse(tc.function.arguments)
253
+ });
254
+ }
255
+ }
256
+ formatted.push({
257
+ role: "assistant",
258
+ content: content.length === 1 && content[0].type === "text" ? content[0].text : content
259
+ });
260
+ } else if (msg.role === "tool" && msg.tool_call_id) {
261
+ const toolResults = [
262
+ {
263
+ type: "tool_result",
264
+ tool_use_id: msg.tool_call_id,
265
+ content: msg.content ?? ""
266
+ }
267
+ ];
268
+ while (i + 1 < messages.length && messages[i + 1].role === "tool") {
269
+ i++;
270
+ const nextTool = messages[i];
271
+ if (nextTool.tool_call_id) {
272
+ toolResults.push({
273
+ type: "tool_result",
274
+ tool_use_id: nextTool.tool_call_id,
275
+ content: nextTool.content ?? ""
276
+ });
277
+ }
278
+ }
279
+ formatted.push({
280
+ role: "user",
281
+ content: toolResults
282
+ });
283
+ } else if (msg.role === "user") {
284
+ formatted.push({
285
+ role: "user",
286
+ content: messageToAnthropicContent(msg)
287
+ });
288
+ }
289
+ }
290
+ return {
291
+ system: "",
292
+ messages: formatted
293
+ };
294
+ }
295
+
1
296
  // src/providers/anthropic/provider.ts
2
297
  var ANTHROPIC_MODELS = {
3
298
  // Claude 4 series
@@ -6,6 +301,7 @@ var ANTHROPIC_MODELS = {
6
301
  tools: true,
7
302
  thinking: true,
8
303
  pdf: true,
304
+ jsonMode: true,
9
305
  maxTokens: 2e5
10
306
  },
11
307
  "claude-opus-4-20250514": {
@@ -13,6 +309,7 @@ var ANTHROPIC_MODELS = {
13
309
  tools: true,
14
310
  thinking: true,
15
311
  pdf: true,
312
+ jsonMode: true,
16
313
  maxTokens: 2e5
17
314
  },
18
315
  // Claude 3.7 series
@@ -21,6 +318,7 @@ var ANTHROPIC_MODELS = {
21
318
  tools: true,
22
319
  thinking: true,
23
320
  pdf: true,
321
+ jsonMode: true,
24
322
  maxTokens: 2e5
25
323
  },
26
324
  "claude-3-7-sonnet-latest": {
@@ -28,6 +326,7 @@ var ANTHROPIC_MODELS = {
28
326
  tools: true,
29
327
  thinking: true,
30
328
  pdf: true,
329
+ jsonMode: true,
31
330
  maxTokens: 2e5
32
331
  },
33
332
  // Claude 3.5 series
@@ -36,6 +335,7 @@ var ANTHROPIC_MODELS = {
36
335
  tools: true,
37
336
  thinking: false,
38
337
  pdf: true,
338
+ jsonMode: true,
39
339
  maxTokens: 2e5
40
340
  },
41
341
  "claude-3-5-sonnet-latest": {
@@ -43,6 +343,7 @@ var ANTHROPIC_MODELS = {
43
343
  tools: true,
44
344
  thinking: false,
45
345
  pdf: true,
346
+ jsonMode: true,
46
347
  maxTokens: 2e5
47
348
  },
48
349
  "claude-3-5-haiku-20241022": {
@@ -50,6 +351,7 @@ var ANTHROPIC_MODELS = {
50
351
  tools: true,
51
352
  thinking: false,
52
353
  pdf: false,
354
+ jsonMode: true,
53
355
  maxTokens: 2e5
54
356
  },
55
357
  "claude-3-5-haiku-latest": {
@@ -57,6 +359,7 @@ var ANTHROPIC_MODELS = {
57
359
  tools: true,
58
360
  thinking: false,
59
361
  pdf: false,
362
+ jsonMode: true,
60
363
  maxTokens: 2e5
61
364
  },
62
365
  // Claude 3 series
@@ -65,6 +368,7 @@ var ANTHROPIC_MODELS = {
65
368
  tools: true,
66
369
  thinking: false,
67
370
  pdf: false,
371
+ jsonMode: false,
68
372
  maxTokens: 2e5
69
373
  },
70
374
  "claude-3-sonnet-20240229": {
@@ -72,6 +376,7 @@ var ANTHROPIC_MODELS = {
72
376
  tools: true,
73
377
  thinking: false,
74
378
  pdf: false,
379
+ jsonMode: false,
75
380
  maxTokens: 2e5
76
381
  },
77
382
  "claude-3-haiku-20240307": {
@@ -79,6 +384,7 @@ var ANTHROPIC_MODELS = {
79
384
  tools: true,
80
385
  thinking: false,
81
386
  pdf: false,
387
+ jsonMode: false,
82
388
  maxTokens: 2e5
83
389
  }
84
390
  };
@@ -103,7 +409,7 @@ function anthropic(modelId, options = {}) {
103
409
  supportsVision: modelConfig.vision,
104
410
  supportsTools: modelConfig.tools,
105
411
  supportsStreaming: true,
106
- supportsJsonMode: false,
412
+ supportsJsonMode: modelConfig.jsonMode,
107
413
  supportsThinking: modelConfig.thinking,
108
414
  supportsPDF: modelConfig.pdf,
109
415
  maxTokens: modelConfig.maxTokens,
@@ -111,7 +417,7 @@ function anthropic(modelId, options = {}) {
111
417
  },
112
418
  async doGenerate(params) {
113
419
  const client2 = await getClient();
114
- const { system, messages } = formatMessagesForAnthropic(params.messages);
420
+ const { system, messages } = formatMessagesForAnthropic2(params.messages);
115
421
  const requestOptions = {
116
422
  model: modelId,
117
423
  max_tokens: params.maxTokens ?? 4096,
@@ -128,6 +434,10 @@ function anthropic(modelId, options = {}) {
128
434
  budget_tokens: options.thinking.budgetTokens ?? 1e4
129
435
  };
130
436
  }
437
+ const outputConfig = toAnthropicOutputConfig(params.responseFormat);
438
+ if (outputConfig) {
439
+ requestOptions.output_config = outputConfig;
440
+ }
131
441
  const response = await client2.messages.create(requestOptions);
132
442
  let text = "";
133
443
  const toolCalls = [];
@@ -156,7 +466,7 @@ function anthropic(modelId, options = {}) {
156
466
  },
157
467
  async *doStream(params) {
158
468
  const client2 = await getClient();
159
- const { system, messages } = formatMessagesForAnthropic(params.messages);
469
+ const { system, messages } = formatMessagesForAnthropic2(params.messages);
160
470
  const requestOptions = {
161
471
  model: modelId,
162
472
  max_tokens: params.maxTokens ?? 4096,
@@ -173,6 +483,10 @@ function anthropic(modelId, options = {}) {
173
483
  budget_tokens: options.thinking.budgetTokens ?? 1e4
174
484
  };
175
485
  }
486
+ const outputConfig = toAnthropicOutputConfig(params.responseFormat);
487
+ if (outputConfig) {
488
+ requestOptions.output_config = outputConfig;
489
+ }
176
490
  const stream = await client2.messages.stream(requestOptions);
177
491
  let currentToolUse = null;
178
492
  let inputTokens = 0;
@@ -251,7 +565,7 @@ function mapFinishReason(reason) {
251
565
  return "unknown";
252
566
  }
253
567
  }
254
- function formatMessagesForAnthropic(messages) {
568
+ function formatMessagesForAnthropic2(messages) {
255
569
  let system = "";
256
570
  const formatted = [];
257
571
  const pendingToolResults = [];
@@ -360,194 +674,6 @@ function generateMessageId() {
360
674
  return generateId("msg");
361
675
  }
362
676
 
363
- // src/adapters/base.ts
364
- function stringifyForDebug(value) {
365
- return JSON.stringify(
366
- value,
367
- (_key, currentValue) => {
368
- if (typeof currentValue === "bigint") {
369
- return currentValue.toString();
370
- }
371
- if (currentValue instanceof Error) {
372
- return {
373
- name: currentValue.name,
374
- message: currentValue.message,
375
- stack: currentValue.stack
376
- };
377
- }
378
- return currentValue;
379
- },
380
- 2
381
- );
382
- }
383
- function logProviderPayload(provider, label, payload, enabled) {
384
- if (!enabled) {
385
- return;
386
- }
387
- if (label.toLowerCase().includes("stream ")) {
388
- return;
389
- }
390
- try {
391
- console.log(
392
- `[llm-sdk:${provider}] ${label}
393
- ${stringifyForDebug(payload)}`
394
- );
395
- } catch (error) {
396
- console.log(
397
- `[llm-sdk:${provider}] ${label} (failed to stringify payload)`,
398
- error
399
- );
400
- }
401
- }
402
- function hasMediaAttachments(message) {
403
- const attachments = message.metadata?.attachments;
404
- return attachments?.some(
405
- (a) => a.type === "image" || a.type === "file" && a.mimeType === "application/pdf"
406
- ) ?? false;
407
- }
408
- function attachmentToAnthropicImage(attachment) {
409
- if (attachment.type !== "image") return null;
410
- if (attachment.url) {
411
- return {
412
- type: "image",
413
- source: {
414
- type: "url",
415
- url: attachment.url
416
- }
417
- };
418
- }
419
- if (!attachment.data) return null;
420
- let base64Data = attachment.data;
421
- if (base64Data.startsWith("data:")) {
422
- const commaIndex = base64Data.indexOf(",");
423
- if (commaIndex !== -1) {
424
- base64Data = base64Data.slice(commaIndex + 1);
425
- }
426
- }
427
- return {
428
- type: "image",
429
- source: {
430
- type: "base64",
431
- media_type: attachment.mimeType || "image/png",
432
- data: base64Data
433
- }
434
- };
435
- }
436
- function attachmentToAnthropicDocument(attachment) {
437
- if (attachment.type !== "file" || attachment.mimeType !== "application/pdf") {
438
- return null;
439
- }
440
- if (attachment.url) {
441
- return {
442
- type: "document",
443
- source: {
444
- type: "url",
445
- url: attachment.url
446
- }
447
- };
448
- }
449
- if (!attachment.data) return null;
450
- let base64Data = attachment.data;
451
- if (base64Data.startsWith("data:")) {
452
- const commaIndex = base64Data.indexOf(",");
453
- if (commaIndex !== -1) {
454
- base64Data = base64Data.slice(commaIndex + 1);
455
- }
456
- }
457
- return {
458
- type: "document",
459
- source: {
460
- type: "base64",
461
- media_type: "application/pdf",
462
- data: base64Data
463
- }
464
- };
465
- }
466
- function messageToAnthropicContent(message) {
467
- const attachments = message.metadata?.attachments;
468
- const content = message.content ?? "";
469
- if (!hasMediaAttachments(message)) {
470
- return content;
471
- }
472
- const blocks = [];
473
- if (attachments) {
474
- for (const attachment of attachments) {
475
- const imageBlock = attachmentToAnthropicImage(attachment);
476
- if (imageBlock) {
477
- blocks.push(imageBlock);
478
- continue;
479
- }
480
- const docBlock = attachmentToAnthropicDocument(attachment);
481
- if (docBlock) {
482
- blocks.push(docBlock);
483
- }
484
- }
485
- }
486
- if (content) {
487
- blocks.push({ type: "text", text: content });
488
- }
489
- return blocks;
490
- }
491
- function formatMessagesForAnthropic2(messages, systemPrompt) {
492
- const formatted = [];
493
- for (let i = 0; i < messages.length; i++) {
494
- const msg = messages[i];
495
- if (msg.role === "system") continue;
496
- if (msg.role === "assistant") {
497
- const content = [];
498
- if (msg.content) {
499
- content.push({ type: "text", text: msg.content });
500
- }
501
- if (msg.tool_calls && msg.tool_calls.length > 0) {
502
- for (const tc of msg.tool_calls) {
503
- content.push({
504
- type: "tool_use",
505
- id: tc.id,
506
- name: tc.function.name,
507
- input: JSON.parse(tc.function.arguments)
508
- });
509
- }
510
- }
511
- formatted.push({
512
- role: "assistant",
513
- content: content.length === 1 && content[0].type === "text" ? content[0].text : content
514
- });
515
- } else if (msg.role === "tool" && msg.tool_call_id) {
516
- const toolResults = [
517
- {
518
- type: "tool_result",
519
- tool_use_id: msg.tool_call_id,
520
- content: msg.content ?? ""
521
- }
522
- ];
523
- while (i + 1 < messages.length && messages[i + 1].role === "tool") {
524
- i++;
525
- const nextTool = messages[i];
526
- if (nextTool.tool_call_id) {
527
- toolResults.push({
528
- type: "tool_result",
529
- tool_use_id: nextTool.tool_call_id,
530
- content: nextTool.content ?? ""
531
- });
532
- }
533
- }
534
- formatted.push({
535
- role: "user",
536
- content: toolResults
537
- });
538
- } else if (msg.role === "user") {
539
- formatted.push({
540
- role: "user",
541
- content: messageToAnthropicContent(msg)
542
- });
543
- }
544
- }
545
- return {
546
- system: "",
547
- messages: formatted
548
- };
549
- }
550
-
551
677
  // src/adapters/anthropic.ts
552
678
  var AnthropicAdapter = class {
553
679
  constructor(config) {
@@ -770,12 +896,14 @@ var AnthropicAdapter = class {
770
896
  * Build common request options for both streaming and non-streaming
771
897
  */
772
898
  buildRequestOptions(request) {
773
- const systemMessage = request.systemPrompt || "";
899
+ const responseFormat = request.config?.responseFormat;
900
+ const jsonObjectSuffix = responseFormat?.type === "json_object" ? "\n\nRespond with a single JSON object and no other text." : "";
901
+ const systemMessage = (request.systemPrompt || "") + jsonObjectSuffix;
774
902
  let messages;
775
903
  if (request.rawMessages && request.rawMessages.length > 0) {
776
904
  messages = this.convertToAnthropicMessages(request.rawMessages);
777
905
  } else {
778
- const formatted = formatMessagesForAnthropic2(request.messages);
906
+ const formatted = formatMessagesForAnthropic(request.messages);
779
907
  messages = formatted.messages;
780
908
  }
781
909
  const anthropicNativeSearch = request.providerToolOptions?.anthropic?.nativeToolSearch;
@@ -851,32 +979,58 @@ var AnthropicAdapter = class {
851
979
  if (serverToolConfiguration) {
852
980
  options.server_tool_configuration = serverToolConfiguration;
853
981
  }
854
- if (this.config.thinking?.type === "enabled") {
982
+ const modelForThinking = request.config?.model || this.model;
983
+ const thinkingTranslation = toAnthropicThinking(
984
+ request.config?.reasoningEffort,
985
+ modelForThinking
986
+ );
987
+ const outputConfig = toAnthropicOutputConfig(responseFormat);
988
+ if (outputConfig || thinkingTranslation.outputConfigEffort) {
989
+ options.output_config = {
990
+ ...outputConfig ?? {},
991
+ ...thinkingTranslation.outputConfigEffort ? { effort: thinkingTranslation.outputConfigEffort } : {}
992
+ };
993
+ }
994
+ if (thinkingTranslation.thinking) {
995
+ options.thinking = thinkingTranslation.thinking;
996
+ } else if (this.config.thinking?.type === "enabled") {
855
997
  options.thinking = {
856
998
  type: "enabled",
857
999
  budget_tokens: this.config.thinking.budgetTokens || 1e4
858
1000
  };
859
1001
  }
860
- return { options, messages };
1002
+ const mcp = toAnthropicMcp(request.config?.mcpServers);
1003
+ const betas = [];
1004
+ if (mcp.mcpServers.length > 0) {
1005
+ options.mcp_servers = mcp.mcpServers;
1006
+ betas.push(...mcp.betas);
1007
+ if (mcp.tools.length > 0) {
1008
+ const existingTools = Array.isArray(options.tools) ? options.tools : [];
1009
+ options.tools = [...existingTools, ...mcp.tools];
1010
+ }
1011
+ }
1012
+ return { options, messages, betas };
861
1013
  }
862
1014
  /**
863
1015
  * Non-streaming completion (for debugging/comparison with original studio-ai)
864
1016
  */
865
1017
  async complete(request) {
866
1018
  const client = await this.getClient();
867
- const { options } = this.buildRequestOptions(request);
1019
+ const { options, betas } = this.buildRequestOptions(request);
868
1020
  const nonStreamingOptions = {
869
1021
  ...options,
870
1022
  stream: false
871
1023
  };
872
1024
  try {
1025
+ const finalOptions = betas.length > 0 ? { ...nonStreamingOptions, betas } : nonStreamingOptions;
1026
+ const messagesApi = betas.length > 0 ? client.beta.messages : client.messages;
873
1027
  logProviderPayload(
874
1028
  "anthropic",
875
1029
  "request payload",
876
- nonStreamingOptions,
1030
+ finalOptions,
877
1031
  request.debug
878
1032
  );
879
- const response = await client.messages.create(nonStreamingOptions);
1033
+ const response = await messagesApi.create(finalOptions);
880
1034
  logProviderPayload(
881
1035
  "anthropic",
882
1036
  "response payload",
@@ -911,17 +1065,19 @@ var AnthropicAdapter = class {
911
1065
  }
912
1066
  async *stream(request) {
913
1067
  const client = await this.getClient();
914
- const { options } = this.buildRequestOptions(request);
1068
+ const { options, betas } = this.buildRequestOptions(request);
915
1069
  const messageId = generateMessageId();
916
1070
  yield { type: "message:start", id: messageId };
917
1071
  try {
1072
+ const finalOptions = betas.length > 0 ? { ...options, betas } : options;
1073
+ const streamApi = betas.length > 0 ? client.beta.messages : client.messages;
918
1074
  logProviderPayload(
919
1075
  "anthropic",
920
1076
  "request payload",
921
- options,
1077
+ finalOptions,
922
1078
  request.debug
923
1079
  );
924
- const stream = await client.messages.stream(options);
1080
+ const stream = await streamApi.stream(finalOptions);
925
1081
  let currentToolUse = null;
926
1082
  let isInThinkingBlock = false;
927
1083
  const collectedCitations = [];
@@ -1179,7 +1335,8 @@ function createAnthropic(config = {}) {
1179
1335
  "image/gif",
1180
1336
  "image/webp"
1181
1337
  ],
1182
- supportsJsonMode: false,
1338
+ // Native `output_config.format` — GA on Claude 3.5 and newer.
1339
+ supportsJsonMode: true,
1183
1340
  supportsSystemMessages: true
1184
1341
  };
1185
1342
  };