@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.
- package/dist/adapters/index.d.mts +4 -4
- package/dist/adapters/index.d.ts +4 -4
- package/dist/adapters/index.js +156 -13
- package/dist/adapters/index.mjs +156 -13
- package/dist/base-C58Dsr9p.d.ts +259 -0
- package/dist/base-tNgbBaSo.d.mts +259 -0
- package/dist/fallback/index.d.mts +4 -4
- package/dist/fallback/index.d.ts +4 -4
- package/dist/index.d.mts +8 -7
- package/dist/index.d.ts +8 -7
- package/dist/index.js +12 -0
- package/dist/index.mjs +12 -0
- package/dist/providers/anthropic/index.d.mts +3 -3
- package/dist/providers/anthropic/index.d.ts +3 -3
- package/dist/providers/anthropic/index.js +271 -195
- package/dist/providers/anthropic/index.mjs +271 -195
- package/dist/providers/azure/index.d.mts +3 -3
- package/dist/providers/azure/index.d.ts +3 -3
- package/dist/providers/azure/index.js +49 -1
- package/dist/providers/azure/index.mjs +49 -1
- package/dist/providers/fireworks/index.d.mts +1 -1
- package/dist/providers/fireworks/index.d.ts +1 -1
- package/dist/providers/fireworks/index.js +56 -0
- package/dist/providers/fireworks/index.mjs +56 -0
- package/dist/providers/google/index.d.mts +3 -3
- package/dist/providers/google/index.d.ts +3 -3
- package/dist/providers/google/index.js +252 -205
- package/dist/providers/google/index.mjs +252 -205
- package/dist/providers/ollama/index.d.mts +4 -4
- package/dist/providers/ollama/index.d.ts +4 -4
- package/dist/providers/ollama/index.js +10 -2
- package/dist/providers/ollama/index.mjs +10 -2
- package/dist/providers/openai/index.d.mts +3 -3
- package/dist/providers/openai/index.d.ts +3 -3
- package/dist/providers/openai/index.js +267 -214
- package/dist/providers/openai/index.mjs +267 -214
- package/dist/providers/openrouter/index.d.mts +3 -3
- package/dist/providers/openrouter/index.d.ts +3 -3
- package/dist/providers/openrouter/index.js +257 -204
- package/dist/providers/openrouter/index.mjs +257 -204
- package/dist/providers/togetherai/index.d.mts +3 -3
- package/dist/providers/togetherai/index.d.ts +3 -3
- package/dist/providers/togetherai/index.js +257 -204
- package/dist/providers/togetherai/index.mjs +257 -204
- package/dist/providers/xai/index.d.mts +3 -3
- package/dist/providers/xai/index.d.ts +3 -3
- package/dist/providers/xai/index.js +256 -208
- package/dist/providers/xai/index.mjs +256 -208
- package/dist/{types-D4YfrQJR.d.mts → types-B6dhnguR.d.mts} +1 -1
- package/dist/{types-DRqxMIjF.d.mts → types-BQ31QIsA.d.ts} +2 -1
- package/dist/{types-BctsnC3g.d.ts → types-BSSiJW2o.d.mts} +2 -1
- package/dist/{base-D-U61JaB.d.mts → types-BkQCSiIt.d.mts} +388 -213
- package/dist/{base-iGi9Va6Z.d.ts → types-BkQCSiIt.d.ts} +388 -213
- package/dist/{types-38yolWJn.d.ts → types-CCxPmkmK.d.ts} +1 -1
- package/dist/yourgpt/index.d.mts +1 -1
- package/dist/yourgpt/index.d.ts +1 -1
- package/package.json +1 -1
- package/dist/types-CR8mi9I0.d.mts +0 -417
- 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-
|
|
2
|
-
import { a as AnthropicProviderConfig, A as AIProvider } from '../../types-
|
|
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-
|
|
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-
|
|
2
|
-
import { a as AnthropicProviderConfig, A as AIProvider } from '../../types-
|
|
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-
|
|
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:
|
|
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 } =
|
|
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 } =
|
|
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
|
|
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
|
|
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 =
|
|
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
|
-
|
|
1259
|
+
// Native `output_config.format` — GA on Claude 3.5 and newer.
|
|
1260
|
+
supportsJsonMode: true,
|
|
1185
1261
|
supportsSystemMessages: true
|
|
1186
1262
|
};
|
|
1187
1263
|
};
|