@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,5 +1,300 @@
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 toAnthropicMcp(mcpServers) {
93
+ if (!mcpServers || mcpServers.length === 0) {
94
+ return { mcpServers: [], tools: [], betas: [] };
95
+ }
96
+ const serverEntries = [];
97
+ const toolEntries = [];
98
+ for (const mcp of mcpServers) {
99
+ const authHeader = mcp.headers?.Authorization ?? mcp.headers?.authorization;
100
+ const token = authHeader?.replace(/^Bearer\s+/i, "");
101
+ serverEntries.push({
102
+ type: "url",
103
+ url: mcp.url,
104
+ name: mcp.label,
105
+ ...token ? { authorization_token: token } : {}
106
+ });
107
+ if (mcp.allowedTools && mcp.allowedTools.length > 0) {
108
+ toolEntries.push({
109
+ type: "mcp_toolset",
110
+ mcp_server_name: mcp.label,
111
+ configs: Object.fromEntries(
112
+ mcp.allowedTools.map((toolName) => [toolName, {}])
113
+ )
114
+ });
115
+ }
116
+ }
117
+ return {
118
+ mcpServers: serverEntries,
119
+ tools: toolEntries,
120
+ betas: ["mcp-client-2025-11-20"]
121
+ };
122
+ }
123
+ function isStringEffort(effort) {
124
+ return typeof effort === "string" && (effort === "minimal" || effort === "low" || effort === "medium" || effort === "high");
125
+ }
126
+ var ANTHROPIC_ADAPTIVE_MODELS = /(claude-opus-4-7|claude-opus-4-6|claude-sonnet-4-6)/i;
127
+ function toAnthropicThinking(effort, modelId) {
128
+ if (!effort) return {};
129
+ if (typeof effort === "object" && "raw" in effort) {
130
+ return { thinking: effort.raw };
131
+ }
132
+ const isAdaptive = !!modelId && ANTHROPIC_ADAPTIVE_MODELS.test(modelId);
133
+ if (typeof effort === "object" && "budgetTokens" in effort) {
134
+ return {
135
+ thinking: { type: "enabled", budget_tokens: effort.budgetTokens }
136
+ };
137
+ }
138
+ if (!isStringEffort(effort)) return {};
139
+ if (isAdaptive) {
140
+ const mapped = effort === "minimal" ? "low" : effort;
141
+ return {
142
+ thinking: { type: "adaptive" },
143
+ outputConfigEffort: mapped
144
+ };
145
+ }
146
+ const budget = effort === "high" ? 16e3 : effort === "medium" ? 8e3 : effort === "low" ? 4e3 : 2048;
147
+ return { thinking: { type: "enabled", budget_tokens: budget } };
148
+ }
149
+ function hasMediaAttachments(message) {
150
+ const attachments = message.metadata?.attachments;
151
+ return attachments?.some(
152
+ (a) => a.type === "image" || a.type === "file" && a.mimeType === "application/pdf"
153
+ ) ?? false;
154
+ }
155
+ function attachmentToAnthropicImage(attachment) {
156
+ if (attachment.type !== "image") return null;
157
+ if (attachment.url) {
158
+ return {
159
+ type: "image",
160
+ source: {
161
+ type: "url",
162
+ url: attachment.url
163
+ }
164
+ };
165
+ }
166
+ if (!attachment.data) return null;
167
+ let base64Data = attachment.data;
168
+ if (base64Data.startsWith("data:")) {
169
+ const commaIndex = base64Data.indexOf(",");
170
+ if (commaIndex !== -1) {
171
+ base64Data = base64Data.slice(commaIndex + 1);
172
+ }
173
+ }
174
+ return {
175
+ type: "image",
176
+ source: {
177
+ type: "base64",
178
+ media_type: attachment.mimeType || "image/png",
179
+ data: base64Data
180
+ }
181
+ };
182
+ }
183
+ function attachmentToAnthropicDocument(attachment) {
184
+ if (attachment.type !== "file" || attachment.mimeType !== "application/pdf") {
185
+ return null;
186
+ }
187
+ if (attachment.url) {
188
+ return {
189
+ type: "document",
190
+ source: {
191
+ type: "url",
192
+ url: attachment.url
193
+ }
194
+ };
195
+ }
196
+ if (!attachment.data) return null;
197
+ let base64Data = attachment.data;
198
+ if (base64Data.startsWith("data:")) {
199
+ const commaIndex = base64Data.indexOf(",");
200
+ if (commaIndex !== -1) {
201
+ base64Data = base64Data.slice(commaIndex + 1);
202
+ }
203
+ }
204
+ return {
205
+ type: "document",
206
+ source: {
207
+ type: "base64",
208
+ media_type: "application/pdf",
209
+ data: base64Data
210
+ }
211
+ };
212
+ }
213
+ function messageToAnthropicContent(message) {
214
+ const attachments = message.metadata?.attachments;
215
+ const content = message.content ?? "";
216
+ if (!hasMediaAttachments(message)) {
217
+ return content;
218
+ }
219
+ const blocks = [];
220
+ if (attachments) {
221
+ for (const attachment of attachments) {
222
+ const imageBlock = attachmentToAnthropicImage(attachment);
223
+ if (imageBlock) {
224
+ blocks.push(imageBlock);
225
+ continue;
226
+ }
227
+ const docBlock = attachmentToAnthropicDocument(attachment);
228
+ if (docBlock) {
229
+ blocks.push(docBlock);
230
+ }
231
+ }
232
+ }
233
+ if (content) {
234
+ blocks.push({ type: "text", text: content });
235
+ }
236
+ return blocks;
237
+ }
238
+ function formatMessagesForAnthropic(messages, systemPrompt) {
239
+ const formatted = [];
240
+ for (let i = 0; i < messages.length; i++) {
241
+ const msg = messages[i];
242
+ if (msg.role === "system") continue;
243
+ if (msg.role === "assistant") {
244
+ const content = [];
245
+ if (msg.content) {
246
+ content.push({ type: "text", text: msg.content });
247
+ }
248
+ if (msg.tool_calls && msg.tool_calls.length > 0) {
249
+ for (const tc of msg.tool_calls) {
250
+ content.push({
251
+ type: "tool_use",
252
+ id: tc.id,
253
+ name: tc.function.name,
254
+ input: JSON.parse(tc.function.arguments)
255
+ });
256
+ }
257
+ }
258
+ formatted.push({
259
+ role: "assistant",
260
+ content: content.length === 1 && content[0].type === "text" ? content[0].text : content
261
+ });
262
+ } else if (msg.role === "tool" && msg.tool_call_id) {
263
+ const toolResults = [
264
+ {
265
+ type: "tool_result",
266
+ tool_use_id: msg.tool_call_id,
267
+ content: msg.content ?? ""
268
+ }
269
+ ];
270
+ while (i + 1 < messages.length && messages[i + 1].role === "tool") {
271
+ i++;
272
+ const nextTool = messages[i];
273
+ if (nextTool.tool_call_id) {
274
+ toolResults.push({
275
+ type: "tool_result",
276
+ tool_use_id: nextTool.tool_call_id,
277
+ content: nextTool.content ?? ""
278
+ });
279
+ }
280
+ }
281
+ formatted.push({
282
+ role: "user",
283
+ content: toolResults
284
+ });
285
+ } else if (msg.role === "user") {
286
+ formatted.push({
287
+ role: "user",
288
+ content: messageToAnthropicContent(msg)
289
+ });
290
+ }
291
+ }
292
+ return {
293
+ system: "",
294
+ messages: formatted
295
+ };
296
+ }
297
+
3
298
  // src/providers/anthropic/provider.ts
4
299
  var ANTHROPIC_MODELS = {
5
300
  // Claude 4 series
@@ -8,6 +303,7 @@ var ANTHROPIC_MODELS = {
8
303
  tools: true,
9
304
  thinking: true,
10
305
  pdf: true,
306
+ jsonMode: true,
11
307
  maxTokens: 2e5
12
308
  },
13
309
  "claude-opus-4-20250514": {
@@ -15,6 +311,7 @@ var ANTHROPIC_MODELS = {
15
311
  tools: true,
16
312
  thinking: true,
17
313
  pdf: true,
314
+ jsonMode: true,
18
315
  maxTokens: 2e5
19
316
  },
20
317
  // Claude 3.7 series
@@ -23,6 +320,7 @@ var ANTHROPIC_MODELS = {
23
320
  tools: true,
24
321
  thinking: true,
25
322
  pdf: true,
323
+ jsonMode: true,
26
324
  maxTokens: 2e5
27
325
  },
28
326
  "claude-3-7-sonnet-latest": {
@@ -30,6 +328,7 @@ var ANTHROPIC_MODELS = {
30
328
  tools: true,
31
329
  thinking: true,
32
330
  pdf: true,
331
+ jsonMode: true,
33
332
  maxTokens: 2e5
34
333
  },
35
334
  // Claude 3.5 series
@@ -38,6 +337,7 @@ var ANTHROPIC_MODELS = {
38
337
  tools: true,
39
338
  thinking: false,
40
339
  pdf: true,
340
+ jsonMode: true,
41
341
  maxTokens: 2e5
42
342
  },
43
343
  "claude-3-5-sonnet-latest": {
@@ -45,6 +345,7 @@ var ANTHROPIC_MODELS = {
45
345
  tools: true,
46
346
  thinking: false,
47
347
  pdf: true,
348
+ jsonMode: true,
48
349
  maxTokens: 2e5
49
350
  },
50
351
  "claude-3-5-haiku-20241022": {
@@ -52,6 +353,7 @@ var ANTHROPIC_MODELS = {
52
353
  tools: true,
53
354
  thinking: false,
54
355
  pdf: false,
356
+ jsonMode: true,
55
357
  maxTokens: 2e5
56
358
  },
57
359
  "claude-3-5-haiku-latest": {
@@ -59,6 +361,7 @@ var ANTHROPIC_MODELS = {
59
361
  tools: true,
60
362
  thinking: false,
61
363
  pdf: false,
364
+ jsonMode: true,
62
365
  maxTokens: 2e5
63
366
  },
64
367
  // Claude 3 series
@@ -67,6 +370,7 @@ var ANTHROPIC_MODELS = {
67
370
  tools: true,
68
371
  thinking: false,
69
372
  pdf: false,
373
+ jsonMode: false,
70
374
  maxTokens: 2e5
71
375
  },
72
376
  "claude-3-sonnet-20240229": {
@@ -74,6 +378,7 @@ var ANTHROPIC_MODELS = {
74
378
  tools: true,
75
379
  thinking: false,
76
380
  pdf: false,
381
+ jsonMode: false,
77
382
  maxTokens: 2e5
78
383
  },
79
384
  "claude-3-haiku-20240307": {
@@ -81,6 +386,7 @@ var ANTHROPIC_MODELS = {
81
386
  tools: true,
82
387
  thinking: false,
83
388
  pdf: false,
389
+ jsonMode: false,
84
390
  maxTokens: 2e5
85
391
  }
86
392
  };
@@ -105,7 +411,7 @@ function anthropic(modelId, options = {}) {
105
411
  supportsVision: modelConfig.vision,
106
412
  supportsTools: modelConfig.tools,
107
413
  supportsStreaming: true,
108
- supportsJsonMode: false,
414
+ supportsJsonMode: modelConfig.jsonMode,
109
415
  supportsThinking: modelConfig.thinking,
110
416
  supportsPDF: modelConfig.pdf,
111
417
  maxTokens: modelConfig.maxTokens,
@@ -113,7 +419,7 @@ function anthropic(modelId, options = {}) {
113
419
  },
114
420
  async doGenerate(params) {
115
421
  const client2 = await getClient();
116
- const { system, messages } = formatMessagesForAnthropic(params.messages);
422
+ const { system, messages } = formatMessagesForAnthropic2(params.messages);
117
423
  const requestOptions = {
118
424
  model: modelId,
119
425
  max_tokens: params.maxTokens ?? 4096,
@@ -130,6 +436,10 @@ function anthropic(modelId, options = {}) {
130
436
  budget_tokens: options.thinking.budgetTokens ?? 1e4
131
437
  };
132
438
  }
439
+ const outputConfig = toAnthropicOutputConfig(params.responseFormat);
440
+ if (outputConfig) {
441
+ requestOptions.output_config = outputConfig;
442
+ }
133
443
  const response = await client2.messages.create(requestOptions);
134
444
  let text = "";
135
445
  const toolCalls = [];
@@ -158,7 +468,7 @@ function anthropic(modelId, options = {}) {
158
468
  },
159
469
  async *doStream(params) {
160
470
  const client2 = await getClient();
161
- const { system, messages } = formatMessagesForAnthropic(params.messages);
471
+ const { system, messages } = formatMessagesForAnthropic2(params.messages);
162
472
  const requestOptions = {
163
473
  model: modelId,
164
474
  max_tokens: params.maxTokens ?? 4096,
@@ -175,6 +485,10 @@ function anthropic(modelId, options = {}) {
175
485
  budget_tokens: options.thinking.budgetTokens ?? 1e4
176
486
  };
177
487
  }
488
+ const outputConfig = toAnthropicOutputConfig(params.responseFormat);
489
+ if (outputConfig) {
490
+ requestOptions.output_config = outputConfig;
491
+ }
178
492
  const stream = await client2.messages.stream(requestOptions);
179
493
  let currentToolUse = null;
180
494
  let inputTokens = 0;
@@ -253,7 +567,7 @@ function mapFinishReason(reason) {
253
567
  return "unknown";
254
568
  }
255
569
  }
256
- function formatMessagesForAnthropic(messages) {
570
+ function formatMessagesForAnthropic2(messages) {
257
571
  let system = "";
258
572
  const formatted = [];
259
573
  const pendingToolResults = [];
@@ -362,194 +676,6 @@ function generateMessageId() {
362
676
  return generateId("msg");
363
677
  }
364
678
 
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
679
  // src/adapters/anthropic.ts
554
680
  var AnthropicAdapter = class {
555
681
  constructor(config) {
@@ -772,12 +898,14 @@ var AnthropicAdapter = class {
772
898
  * Build common request options for both streaming and non-streaming
773
899
  */
774
900
  buildRequestOptions(request) {
775
- const systemMessage = request.systemPrompt || "";
901
+ const responseFormat = request.config?.responseFormat;
902
+ const jsonObjectSuffix = responseFormat?.type === "json_object" ? "\n\nRespond with a single JSON object and no other text." : "";
903
+ const systemMessage = (request.systemPrompt || "") + jsonObjectSuffix;
776
904
  let messages;
777
905
  if (request.rawMessages && request.rawMessages.length > 0) {
778
906
  messages = this.convertToAnthropicMessages(request.rawMessages);
779
907
  } else {
780
- const formatted = formatMessagesForAnthropic2(request.messages);
908
+ const formatted = formatMessagesForAnthropic(request.messages);
781
909
  messages = formatted.messages;
782
910
  }
783
911
  const anthropicNativeSearch = request.providerToolOptions?.anthropic?.nativeToolSearch;
@@ -853,32 +981,58 @@ var AnthropicAdapter = class {
853
981
  if (serverToolConfiguration) {
854
982
  options.server_tool_configuration = serverToolConfiguration;
855
983
  }
856
- if (this.config.thinking?.type === "enabled") {
984
+ const modelForThinking = request.config?.model || this.model;
985
+ const thinkingTranslation = toAnthropicThinking(
986
+ request.config?.reasoningEffort,
987
+ modelForThinking
988
+ );
989
+ const outputConfig = toAnthropicOutputConfig(responseFormat);
990
+ if (outputConfig || thinkingTranslation.outputConfigEffort) {
991
+ options.output_config = {
992
+ ...outputConfig ?? {},
993
+ ...thinkingTranslation.outputConfigEffort ? { effort: thinkingTranslation.outputConfigEffort } : {}
994
+ };
995
+ }
996
+ if (thinkingTranslation.thinking) {
997
+ options.thinking = thinkingTranslation.thinking;
998
+ } else if (this.config.thinking?.type === "enabled") {
857
999
  options.thinking = {
858
1000
  type: "enabled",
859
1001
  budget_tokens: this.config.thinking.budgetTokens || 1e4
860
1002
  };
861
1003
  }
862
- return { options, messages };
1004
+ const mcp = toAnthropicMcp(request.config?.mcpServers);
1005
+ const betas = [];
1006
+ if (mcp.mcpServers.length > 0) {
1007
+ options.mcp_servers = mcp.mcpServers;
1008
+ betas.push(...mcp.betas);
1009
+ if (mcp.tools.length > 0) {
1010
+ const existingTools = Array.isArray(options.tools) ? options.tools : [];
1011
+ options.tools = [...existingTools, ...mcp.tools];
1012
+ }
1013
+ }
1014
+ return { options, messages, betas };
863
1015
  }
864
1016
  /**
865
1017
  * Non-streaming completion (for debugging/comparison with original studio-ai)
866
1018
  */
867
1019
  async complete(request) {
868
1020
  const client = await this.getClient();
869
- const { options } = this.buildRequestOptions(request);
1021
+ const { options, betas } = this.buildRequestOptions(request);
870
1022
  const nonStreamingOptions = {
871
1023
  ...options,
872
1024
  stream: false
873
1025
  };
874
1026
  try {
1027
+ const finalOptions = betas.length > 0 ? { ...nonStreamingOptions, betas } : nonStreamingOptions;
1028
+ const messagesApi = betas.length > 0 ? client.beta.messages : client.messages;
875
1029
  logProviderPayload(
876
1030
  "anthropic",
877
1031
  "request payload",
878
- nonStreamingOptions,
1032
+ finalOptions,
879
1033
  request.debug
880
1034
  );
881
- const response = await client.messages.create(nonStreamingOptions);
1035
+ const response = await messagesApi.create(finalOptions);
882
1036
  logProviderPayload(
883
1037
  "anthropic",
884
1038
  "response payload",
@@ -913,17 +1067,19 @@ var AnthropicAdapter = class {
913
1067
  }
914
1068
  async *stream(request) {
915
1069
  const client = await this.getClient();
916
- const { options } = this.buildRequestOptions(request);
1070
+ const { options, betas } = this.buildRequestOptions(request);
917
1071
  const messageId = generateMessageId();
918
1072
  yield { type: "message:start", id: messageId };
919
1073
  try {
1074
+ const finalOptions = betas.length > 0 ? { ...options, betas } : options;
1075
+ const streamApi = betas.length > 0 ? client.beta.messages : client.messages;
920
1076
  logProviderPayload(
921
1077
  "anthropic",
922
1078
  "request payload",
923
- options,
1079
+ finalOptions,
924
1080
  request.debug
925
1081
  );
926
- const stream = await client.messages.stream(options);
1082
+ const stream = await streamApi.stream(finalOptions);
927
1083
  let currentToolUse = null;
928
1084
  let isInThinkingBlock = false;
929
1085
  const collectedCitations = [];
@@ -1181,7 +1337,8 @@ function createAnthropic(config = {}) {
1181
1337
  "image/gif",
1182
1338
  "image/webp"
1183
1339
  ],
1184
- supportsJsonMode: false,
1340
+ // Native `output_config.format` — GA on Claude 3.5 and newer.
1341
+ supportsJsonMode: true,
1185
1342
  supportsSystemMessages: true
1186
1343
  };
1187
1344
  };