@ai-sdk/anthropic 4.0.49 → 4.0.51
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/CHANGELOG.md +20 -0
- package/dist/index.d.ts +8 -5
- package/dist/index.js +161 -146
- package/dist/index.js.map +1 -1
- package/dist/internal/index.d.ts +8 -15
- package/dist/internal/index.js +44 -38
- package/dist/internal/index.js.map +1 -1
- package/docs/05-anthropic.mdx +6 -42
- package/package.json +3 -3
- package/src/{anthropic-messages-batch.ts → anthropic-batch.ts} +64 -55
- package/src/anthropic-language-model.ts +58 -52
- package/src/anthropic-provider.ts +31 -16
package/docs/05-anthropic.mdx
CHANGED
|
@@ -144,55 +144,19 @@ The following optional provider options are available for Anthropic models:
|
|
|
144
144
|
Optional. Metadata to include with the request. See the [Anthropic API documentation](https://platform.claude.com/docs/en/api/messages/create) for details.
|
|
145
145
|
- `userId` _string_ - An external identifier for the end-user. Should be a UUID, hash, or other opaque identifier. Must not contain PII.
|
|
146
146
|
|
|
147
|
-
###
|
|
147
|
+
### Batch
|
|
148
148
|
|
|
149
149
|
<Note type="warning">
|
|
150
|
-
|
|
150
|
+
Batch support is experimental and the API may change in patch releases.
|
|
151
151
|
</Note>
|
|
152
152
|
|
|
153
153
|
Anthropic language models support asynchronous text generation through the
|
|
154
154
|
[Message Batches API](https://platform.claude.com/docs/en/build-with-claude/batch-processing).
|
|
155
|
-
|
|
156
|
-
|
|
155
|
+
Pass the Anthropic provider to the AI SDK's [Batch](/docs/ai-sdk-core/batch)
|
|
156
|
+
API for the complete workflow, including polling, persistence, and result handling.
|
|
157
157
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
import {
|
|
161
|
-
experimental_getBatchResults as getBatchResults,
|
|
162
|
-
experimental_getBatchStatus as getBatchStatus,
|
|
163
|
-
experimental_startTextBatch as startTextBatch,
|
|
164
|
-
} from 'ai';
|
|
165
|
-
import { setTimeout } from 'node:timers/promises';
|
|
166
|
-
|
|
167
|
-
const model = anthropic('claude-haiku-4-5');
|
|
168
|
-
|
|
169
|
-
const batch = await startTextBatch({
|
|
170
|
-
model,
|
|
171
|
-
requests: [
|
|
172
|
-
{ id: 'capital-france', prompt: 'What is the capital of France?' },
|
|
173
|
-
{ id: 'capital-germany', prompt: 'What is the capital of Germany?' },
|
|
174
|
-
],
|
|
175
|
-
});
|
|
176
|
-
|
|
177
|
-
let status = batch.status;
|
|
178
|
-
while (status === 'pending') {
|
|
179
|
-
await setTimeout(60_000);
|
|
180
|
-
({ status } = await getBatchStatus({ model, batch }));
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
for await (const item of getBatchResults({ model, batch })) {
|
|
184
|
-
if (item.status === 'succeeded') {
|
|
185
|
-
console.log(item.id, item.text);
|
|
186
|
-
} else {
|
|
187
|
-
console.error(item.id, item.error);
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
```
|
|
191
|
-
|
|
192
|
-
`startTextBatch` returns a serializable batch reference. Persist this reference
|
|
193
|
-
to check the batch status or retrieve its results from another process. Results
|
|
194
|
-
can arrive in a different order from the input requests, so match each result by
|
|
195
|
-
its `id`.
|
|
158
|
+
Each request specifies its `type` and `model`. Anthropic supports using
|
|
159
|
+
different text models within the same batch.
|
|
196
160
|
|
|
197
161
|
#### Batch Limitations
|
|
198
162
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ai-sdk/anthropic",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.51",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -35,8 +35,8 @@
|
|
|
35
35
|
}
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@ai-sdk/provider": "4.0.
|
|
39
|
-
"@ai-sdk/provider-utils": "5.0.
|
|
38
|
+
"@ai-sdk/provider": "4.0.12",
|
|
39
|
+
"@ai-sdk/provider-utils": "5.0.38"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
42
|
"@ai-sdk/test-server": "2.0.1",
|
|
@@ -2,11 +2,14 @@ import {
|
|
|
2
2
|
InvalidArgumentError,
|
|
3
3
|
InvalidResponseDataError,
|
|
4
4
|
UnsupportedFunctionalityError,
|
|
5
|
-
type
|
|
5
|
+
type Experimental_BatchV4 as BatchV4,
|
|
6
6
|
type Experimental_BatchV4ItemResult as BatchV4ItemResult,
|
|
7
7
|
type Experimental_BatchV4OperationOptions as BatchV4OperationOptions,
|
|
8
8
|
type Experimental_BatchV4StartResult as BatchV4StartResult,
|
|
9
9
|
type Experimental_BatchV4Status as BatchV4Status,
|
|
10
|
+
type Experimental_TextBatchV4Request as TextBatchV4Request,
|
|
11
|
+
type Experimental_TextBatchV4ItemResult as TextBatchV4ItemResult,
|
|
12
|
+
type Experimental_BatchV4StartOptions as BatchV4StartOptions,
|
|
10
13
|
type JSONObject,
|
|
11
14
|
type LanguageModelV4GenerateResult,
|
|
12
15
|
type SharedV4ProviderMetadata,
|
|
@@ -16,6 +19,7 @@ import {
|
|
|
16
19
|
convertAsyncIteratorToReadableStream,
|
|
17
20
|
createJsonLinesResponseHandler,
|
|
18
21
|
createJsonResponseHandler,
|
|
22
|
+
generateId,
|
|
19
23
|
getFromApi,
|
|
20
24
|
isRecord,
|
|
21
25
|
lazySchema,
|
|
@@ -25,8 +29,6 @@ import {
|
|
|
25
29
|
postJsonToApi,
|
|
26
30
|
resolve,
|
|
27
31
|
safeValidateTypes,
|
|
28
|
-
WORKFLOW_DESERIALIZE,
|
|
29
|
-
WORKFLOW_SERIALIZE,
|
|
30
32
|
zodSchema,
|
|
31
33
|
type InferSchema,
|
|
32
34
|
} from '@ai-sdk/provider-utils';
|
|
@@ -60,9 +62,7 @@ const anthropicBatchProviderOptionsSchema = anthropicLanguageModelOptions.pick({
|
|
|
60
62
|
anthropicBeta: true,
|
|
61
63
|
});
|
|
62
64
|
|
|
63
|
-
type AnthropicBatchRequest =
|
|
64
|
-
BatchLanguageModelV4['experimental_doStartBatch']
|
|
65
|
-
>[0]['requests'][number];
|
|
65
|
+
type AnthropicBatchRequest = TextBatchV4Request<AnthropicModelId>;
|
|
66
66
|
|
|
67
67
|
const anthropicBatchResponseSchema = lazySchema(() =>
|
|
68
68
|
zodSchema(
|
|
@@ -148,42 +148,40 @@ type AnthropicBatchResultLine = InferSchema<
|
|
|
148
148
|
|
|
149
149
|
type AnthropicResponse = InferSchema<typeof anthropicResponseSchema>;
|
|
150
150
|
|
|
151
|
-
export class
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
constructor(modelId: AnthropicModelId, config: AnthropicLanguageModelConfig) {
|
|
170
|
-
super(modelId, config);
|
|
151
|
+
export class AnthropicBatch implements BatchV4<{
|
|
152
|
+
readonly text: AnthropicModelId;
|
|
153
|
+
}> {
|
|
154
|
+
readonly specificationVersion = 'v4' as const;
|
|
155
|
+
readonly provider: string;
|
|
156
|
+
readonly supportedUrls: Record<string, RegExp[]>;
|
|
157
|
+
private readonly generateId: () => string;
|
|
158
|
+
|
|
159
|
+
constructor(
|
|
160
|
+
private readonly options: {
|
|
161
|
+
provider: string;
|
|
162
|
+
config: AnthropicLanguageModelConfig;
|
|
163
|
+
supportedUrls: Record<string, RegExp[]>;
|
|
164
|
+
},
|
|
165
|
+
) {
|
|
166
|
+
this.provider = options.provider;
|
|
167
|
+
this.supportedUrls = options.supportedUrls;
|
|
168
|
+
this.generateId = options.config.generateId ?? generateId;
|
|
171
169
|
}
|
|
172
170
|
|
|
173
|
-
async
|
|
171
|
+
async doStartBatch({
|
|
174
172
|
requests,
|
|
175
173
|
providerOptions,
|
|
176
174
|
headers,
|
|
177
175
|
abortSignal,
|
|
178
176
|
webhookUrl,
|
|
179
|
-
}:
|
|
180
|
-
|
|
181
|
-
>
|
|
177
|
+
}: BatchV4StartOptions<{
|
|
178
|
+
text: AnthropicModelId;
|
|
179
|
+
}>): Promise<BatchV4StartResult> {
|
|
182
180
|
validateRequestIds(requests);
|
|
183
181
|
|
|
184
182
|
const explicitBatchBetas = new Set(
|
|
185
183
|
await getAnthropicBatchProviderBetas({
|
|
186
|
-
provider: this.config.provider,
|
|
184
|
+
provider: this.options.config.provider,
|
|
187
185
|
providerOptions,
|
|
188
186
|
}),
|
|
189
187
|
);
|
|
@@ -208,7 +206,7 @@ export class AnthropicMessagesBatchLanguageModel
|
|
|
208
206
|
|
|
209
207
|
for (const request of requests) {
|
|
210
208
|
const requestBetas = await getAnthropicBatchProviderBetas({
|
|
211
|
-
provider: this.config.provider,
|
|
209
|
+
provider: this.options.config.provider,
|
|
212
210
|
providerOptions: request.options.providerOptions,
|
|
213
211
|
});
|
|
214
212
|
if (requestBetas.length > 0) {
|
|
@@ -217,14 +215,18 @@ export class AnthropicMessagesBatchLanguageModel
|
|
|
217
215
|
message:
|
|
218
216
|
`Anthropic Message Batches do not support per-request betas ` +
|
|
219
217
|
`(request "${request.id}"). Set providerOptions.anthropic.anthropicBeta ` +
|
|
220
|
-
`on
|
|
218
|
+
`on startBatch instead.`,
|
|
221
219
|
});
|
|
222
220
|
}
|
|
223
221
|
|
|
224
|
-
const prepared = await
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
222
|
+
const prepared = await AnthropicLanguageModel.prepareRequest({
|
|
223
|
+
modelId: request.modelId,
|
|
224
|
+
config: this.options.config,
|
|
225
|
+
options: {
|
|
226
|
+
...request.options,
|
|
227
|
+
stream: false,
|
|
228
|
+
userSuppliedBetas: new Set(explicitBatchBetas),
|
|
229
|
+
},
|
|
228
230
|
});
|
|
229
231
|
if (prepared.usesJsonResponseTool) {
|
|
230
232
|
throw new UnsupportedFunctionalityError({
|
|
@@ -249,7 +251,11 @@ export class AnthropicMessagesBatchLanguageModel
|
|
|
249
251
|
`(request "${request.id}"). Use the provider's canonical tool name.`,
|
|
250
252
|
});
|
|
251
253
|
}
|
|
252
|
-
const body =
|
|
254
|
+
const body =
|
|
255
|
+
this.options.config.transformRequestBody?.(
|
|
256
|
+
prepared.args,
|
|
257
|
+
prepared.betas,
|
|
258
|
+
) ?? prepared.args;
|
|
253
259
|
validateAnthropicBatchBody({
|
|
254
260
|
body,
|
|
255
261
|
requestId: request.id,
|
|
@@ -273,7 +279,7 @@ export class AnthropicMessagesBatchLanguageModel
|
|
|
273
279
|
anthropicBatchResponseSchema,
|
|
274
280
|
),
|
|
275
281
|
abortSignal,
|
|
276
|
-
fetch: this.config.fetch,
|
|
282
|
+
fetch: this.options.config.fetch,
|
|
277
283
|
});
|
|
278
284
|
|
|
279
285
|
return {
|
|
@@ -283,15 +289,15 @@ export class AnthropicMessagesBatchLanguageModel
|
|
|
283
289
|
};
|
|
284
290
|
}
|
|
285
291
|
|
|
286
|
-
async
|
|
292
|
+
async doGetBatchStatus(
|
|
287
293
|
options: BatchV4OperationOptions,
|
|
288
294
|
): Promise<BatchV4Status> {
|
|
289
295
|
return convertAnthropicBatchStatus(await this.retrieveBatch(options));
|
|
290
296
|
}
|
|
291
297
|
|
|
292
|
-
async
|
|
298
|
+
async doGetBatchResults(
|
|
293
299
|
options: BatchV4OperationOptions,
|
|
294
|
-
): Promise<ReadableStream<BatchV4ItemResult
|
|
300
|
+
): Promise<ReadableStream<BatchV4ItemResult>> {
|
|
295
301
|
const batch = await this.retrieveBatch(options);
|
|
296
302
|
|
|
297
303
|
if (convertAnthropicBatchStatus(batch).status === 'pending') {
|
|
@@ -318,15 +324,15 @@ export class AnthropicMessagesBatchLanguageModel
|
|
|
318
324
|
const { value: lines } = await getFromApi({
|
|
319
325
|
url: batch.results_url,
|
|
320
326
|
validateUrl: true,
|
|
321
|
-
credentialedOrigin: this.config.baseURL,
|
|
322
|
-
trustedOrigin: this.config.baseURL,
|
|
327
|
+
credentialedOrigin: this.options.config.baseURL,
|
|
328
|
+
trustedOrigin: this.options.config.baseURL,
|
|
323
329
|
headers: await this.getBatchHeaders(options.headers),
|
|
324
330
|
failedResponseHandler: anthropicFailedResponseHandler,
|
|
325
331
|
successfulResponseHandler: createJsonLinesResponseHandler(
|
|
326
332
|
anthropicBatchResultLineSchema,
|
|
327
333
|
),
|
|
328
334
|
abortSignal: options.abortSignal,
|
|
329
|
-
fetch: this.config.fetch,
|
|
335
|
+
fetch: this.options.config.fetch,
|
|
330
336
|
});
|
|
331
337
|
|
|
332
338
|
return convertAsyncIteratorToReadableStream(
|
|
@@ -346,7 +352,7 @@ export class AnthropicMessagesBatchLanguageModel
|
|
|
346
352
|
anthropicBatchResponseSchema,
|
|
347
353
|
),
|
|
348
354
|
abortSignal: options.abortSignal,
|
|
349
|
-
fetch: this.config.fetch,
|
|
355
|
+
fetch: this.options.config.fetch,
|
|
350
356
|
});
|
|
351
357
|
|
|
352
358
|
return batch;
|
|
@@ -354,14 +360,14 @@ export class AnthropicMessagesBatchLanguageModel
|
|
|
354
360
|
|
|
355
361
|
private async *iterateBatchResults(
|
|
356
362
|
lines: AsyncIterable<AnthropicBatchResultLine>,
|
|
357
|
-
): AsyncGenerator<BatchV4ItemResult
|
|
363
|
+
): AsyncGenerator<BatchV4ItemResult> {
|
|
358
364
|
for await (const line of lines) {
|
|
359
365
|
yield await convertAnthropicBatchResult(line, this.generateId);
|
|
360
366
|
}
|
|
361
367
|
}
|
|
362
368
|
|
|
363
369
|
private getBatchUrl(path: string) {
|
|
364
|
-
return `${this.config.baseURL}/messages/batches${path}`;
|
|
370
|
+
return `${this.options.config.baseURL}/messages/batches${path}`;
|
|
365
371
|
}
|
|
366
372
|
|
|
367
373
|
private async getStartBatchHeaders({
|
|
@@ -384,7 +390,9 @@ export class AnthropicMessagesBatchLanguageModel
|
|
|
384
390
|
headers: Record<string, string | undefined> | undefined,
|
|
385
391
|
) {
|
|
386
392
|
return combineHeaders(
|
|
387
|
-
this.
|
|
393
|
+
this.options.config.headers
|
|
394
|
+
? await resolve(this.options.config.headers)
|
|
395
|
+
: undefined,
|
|
388
396
|
headers,
|
|
389
397
|
);
|
|
390
398
|
}
|
|
@@ -533,7 +541,7 @@ function convertAnthropicRequestCounts(
|
|
|
533
541
|
async function convertAnthropicBatchResult(
|
|
534
542
|
line: AnthropicBatchResultLine,
|
|
535
543
|
generateId: () => string,
|
|
536
|
-
): Promise<
|
|
544
|
+
): Promise<TextBatchV4ItemResult> {
|
|
537
545
|
const resultValidation = await safeValidateTypes({
|
|
538
546
|
value: line.result,
|
|
539
547
|
schema: anthropicBatchResultSchema,
|
|
@@ -547,12 +555,13 @@ async function convertAnthropicBatchResult(
|
|
|
547
555
|
|
|
548
556
|
switch (result.type) {
|
|
549
557
|
case 'canceled':
|
|
550
|
-
return { id: line.custom_id, status: 'cancelled' };
|
|
558
|
+
return { type: 'text', id: line.custom_id, status: 'cancelled' };
|
|
551
559
|
case 'expired':
|
|
552
|
-
return { id: line.custom_id, status: 'expired' };
|
|
560
|
+
return { type: 'text', id: line.custom_id, status: 'expired' };
|
|
553
561
|
case 'errored': {
|
|
554
562
|
const requestId = result.error.request_id;
|
|
555
563
|
return {
|
|
564
|
+
type: 'text',
|
|
556
565
|
id: line.custom_id,
|
|
557
566
|
status: 'failed',
|
|
558
567
|
error: {
|
|
@@ -576,6 +585,7 @@ async function convertAnthropicBatchResult(
|
|
|
576
585
|
}
|
|
577
586
|
|
|
578
587
|
return {
|
|
588
|
+
type: 'text',
|
|
579
589
|
id: line.custom_id,
|
|
580
590
|
status: 'succeeded',
|
|
581
591
|
result: convertAnthropicBatchResponse(response, generateId),
|
|
@@ -584,10 +594,9 @@ async function convertAnthropicBatchResult(
|
|
|
584
594
|
}
|
|
585
595
|
}
|
|
586
596
|
|
|
587
|
-
function invalidAnthropicBatchResult(
|
|
588
|
-
id: string,
|
|
589
|
-
): BatchV4ItemResult<LanguageModelV4GenerateResult> {
|
|
597
|
+
function invalidAnthropicBatchResult(id: string): TextBatchV4ItemResult {
|
|
590
598
|
return {
|
|
599
|
+
type: 'text',
|
|
591
600
|
id,
|
|
592
601
|
status: 'failed',
|
|
593
602
|
error: {
|
|
@@ -195,6 +195,11 @@ function getAnthropicCallerMetadata(
|
|
|
195
195
|
: { providerMetadata: { anthropic: { caller: callerInfo } } };
|
|
196
196
|
}
|
|
197
197
|
|
|
198
|
+
function getProviderOptionsName(provider: string): string {
|
|
199
|
+
const dotIndex = provider.indexOf('.');
|
|
200
|
+
return dotIndex === -1 ? provider : provider.substring(0, dotIndex);
|
|
201
|
+
}
|
|
202
|
+
|
|
198
203
|
export type AnthropicLanguageModelConfig = {
|
|
199
204
|
provider: string;
|
|
200
205
|
baseURL: string;
|
|
@@ -207,16 +212,7 @@ export type AnthropicLanguageModelConfig = {
|
|
|
207
212
|
) => Record<string, any>;
|
|
208
213
|
supportedUrls?: () => LanguageModelV4['supportedUrls'];
|
|
209
214
|
generateId?: () => string;
|
|
210
|
-
|
|
211
|
-
/**
|
|
212
|
-
* When false, the model will use JSON tool fallback for structured outputs.
|
|
213
|
-
*/
|
|
214
215
|
supportsNativeStructuredOutput?: boolean;
|
|
215
|
-
|
|
216
|
-
/**
|
|
217
|
-
* When false, `strict` on tool definitions will be ignored and a warning emitted.
|
|
218
|
-
* Defaults to true.
|
|
219
|
-
*/
|
|
220
216
|
supportsStrictTools?: boolean;
|
|
221
217
|
};
|
|
222
218
|
|
|
@@ -256,40 +252,38 @@ export class AnthropicLanguageModel implements LanguageModelV4 {
|
|
|
256
252
|
return this.config.provider;
|
|
257
253
|
}
|
|
258
254
|
|
|
259
|
-
/**
|
|
260
|
-
* Extracts the dynamic provider name from the config.provider string.
|
|
261
|
-
* e.g., 'my-custom-anthropic.messages' -> 'my-custom-anthropic'
|
|
262
|
-
*/
|
|
263
|
-
private get providerOptionsName(): string {
|
|
264
|
-
const provider = this.config.provider;
|
|
265
|
-
const dotIndex = provider.indexOf('.');
|
|
266
|
-
return dotIndex === -1 ? provider : provider.substring(0, dotIndex);
|
|
267
|
-
}
|
|
268
|
-
|
|
269
255
|
get supportedUrls() {
|
|
270
256
|
return this.config.supportedUrls?.() ?? {};
|
|
271
257
|
}
|
|
272
258
|
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
259
|
+
static async prepareRequest({
|
|
260
|
+
modelId,
|
|
261
|
+
config,
|
|
262
|
+
options: {
|
|
263
|
+
userSuppliedBetas,
|
|
264
|
+
prompt,
|
|
265
|
+
maxOutputTokens,
|
|
266
|
+
temperature,
|
|
267
|
+
topP,
|
|
268
|
+
topK,
|
|
269
|
+
frequencyPenalty,
|
|
270
|
+
presencePenalty,
|
|
271
|
+
stopSequences,
|
|
272
|
+
responseFormat,
|
|
273
|
+
seed,
|
|
274
|
+
tools,
|
|
275
|
+
toolChoice,
|
|
276
|
+
reasoning,
|
|
277
|
+
providerOptions,
|
|
278
|
+
stream,
|
|
279
|
+
},
|
|
280
|
+
}: {
|
|
281
|
+
modelId: AnthropicModelId;
|
|
282
|
+
config: AnthropicLanguageModelConfig;
|
|
283
|
+
options: LanguageModelV4CallOptions & {
|
|
284
|
+
stream: boolean;
|
|
285
|
+
userSuppliedBetas: Set<string>;
|
|
286
|
+
};
|
|
293
287
|
}) {
|
|
294
288
|
const warnings: SharedV4Warning[] = [];
|
|
295
289
|
|
|
@@ -333,7 +327,7 @@ export class AnthropicLanguageModel implements LanguageModelV4 {
|
|
|
333
327
|
}
|
|
334
328
|
}
|
|
335
329
|
|
|
336
|
-
const providerOptionsName =
|
|
330
|
+
const providerOptionsName = getProviderOptionsName(config.provider);
|
|
337
331
|
|
|
338
332
|
// Parse provider options from both canonical 'anthropic' key and custom key
|
|
339
333
|
const canonicalOptions = await parseProviderOptions({
|
|
@@ -369,14 +363,14 @@ export class AnthropicLanguageModel implements LanguageModelV4 {
|
|
|
369
363
|
supportsXhighEffort,
|
|
370
364
|
rejectsThinkingDisabledAboveHighEffort,
|
|
371
365
|
isKnownModel,
|
|
372
|
-
} = getModelCapabilities(
|
|
366
|
+
} = getModelCapabilities(modelId);
|
|
373
367
|
|
|
374
368
|
if (!isKnownModel && maxOutputTokens == null) {
|
|
375
369
|
warnings.push({
|
|
376
370
|
type: 'compatibility',
|
|
377
371
|
feature: 'maxOutputTokens',
|
|
378
372
|
details:
|
|
379
|
-
`The model "${
|
|
373
|
+
`The model "${modelId}" is unknown. ` +
|
|
380
374
|
`The max output tokens have been limited to ${maxOutputTokensForModel}. ` +
|
|
381
375
|
`Set maxOutputTokens explicitly to override this limit.`,
|
|
382
376
|
});
|
|
@@ -387,7 +381,7 @@ export class AnthropicLanguageModel implements LanguageModelV4 {
|
|
|
387
381
|
warnings.push({
|
|
388
382
|
type: 'unsupported',
|
|
389
383
|
feature: 'temperature',
|
|
390
|
-
details: `temperature is not supported by ${
|
|
384
|
+
details: `temperature is not supported by ${modelId} and will be ignored`,
|
|
391
385
|
});
|
|
392
386
|
temperature = undefined;
|
|
393
387
|
}
|
|
@@ -395,7 +389,7 @@ export class AnthropicLanguageModel implements LanguageModelV4 {
|
|
|
395
389
|
warnings.push({
|
|
396
390
|
type: 'unsupported',
|
|
397
391
|
feature: 'topK',
|
|
398
|
-
details: `topK is not supported by ${
|
|
392
|
+
details: `topK is not supported by ${modelId} and will be ignored`,
|
|
399
393
|
});
|
|
400
394
|
topK = undefined;
|
|
401
395
|
}
|
|
@@ -403,21 +397,20 @@ export class AnthropicLanguageModel implements LanguageModelV4 {
|
|
|
403
397
|
warnings.push({
|
|
404
398
|
type: 'unsupported',
|
|
405
399
|
feature: 'topP',
|
|
406
|
-
details: `topP is not supported by ${
|
|
400
|
+
details: `topP is not supported by ${modelId} and will be ignored`,
|
|
407
401
|
});
|
|
408
402
|
topP = undefined;
|
|
409
403
|
}
|
|
410
404
|
}
|
|
411
405
|
|
|
412
|
-
const isAnthropicModel = isKnownModel ||
|
|
406
|
+
const isAnthropicModel = isKnownModel || modelId.includes('claude-');
|
|
413
407
|
|
|
414
408
|
const supportsStructuredOutput =
|
|
415
|
-
(
|
|
409
|
+
(config.supportsNativeStructuredOutput ?? true) &&
|
|
416
410
|
modelSupportsStructuredOutput;
|
|
417
411
|
|
|
418
412
|
const supportsStrictTools =
|
|
419
|
-
(
|
|
420
|
-
modelSupportsStructuredOutput;
|
|
413
|
+
(config.supportsStrictTools ?? true) && modelSupportsStructuredOutput;
|
|
421
414
|
|
|
422
415
|
const structureOutputMode =
|
|
423
416
|
anthropicOptions?.structuredOutputMode ?? 'auto';
|
|
@@ -526,7 +519,7 @@ export class AnthropicLanguageModel implements LanguageModelV4 {
|
|
|
526
519
|
type: 'unsupported',
|
|
527
520
|
feature: 'providerOptions.anthropic.effort',
|
|
528
521
|
details:
|
|
529
|
-
`effort '${anthropicOptions.effort}' is not supported by ${
|
|
522
|
+
`effort '${anthropicOptions.effort}' is not supported by ${modelId} when thinking is disabled. ` +
|
|
530
523
|
`The effort has been lowered to 'high'.`,
|
|
531
524
|
});
|
|
532
525
|
anthropicOptions.effort = 'high';
|
|
@@ -559,7 +552,7 @@ export class AnthropicLanguageModel implements LanguageModelV4 {
|
|
|
559
552
|
|
|
560
553
|
const baseArgs = {
|
|
561
554
|
// model id:
|
|
562
|
-
model:
|
|
555
|
+
model: modelId,
|
|
563
556
|
|
|
564
557
|
// standardized settings:
|
|
565
558
|
max_tokens: maxTokens,
|
|
@@ -801,7 +794,7 @@ export class AnthropicLanguageModel implements LanguageModelV4 {
|
|
|
801
794
|
type: 'unsupported',
|
|
802
795
|
feature: 'maxOutputTokens',
|
|
803
796
|
details:
|
|
804
|
-
`${baseArgs.max_tokens} (maxOutputTokens + thinkingBudget) is greater than ${
|
|
797
|
+
`${baseArgs.max_tokens} (maxOutputTokens + thinkingBudget) is greater than ${modelId} ${maxOutputTokensForModel} max output tokens. ` +
|
|
805
798
|
`The max output tokens have been limited to ${maxOutputTokensForModel}.`,
|
|
806
799
|
});
|
|
807
800
|
}
|
|
@@ -927,6 +920,19 @@ export class AnthropicLanguageModel implements LanguageModelV4 {
|
|
|
927
920
|
};
|
|
928
921
|
}
|
|
929
922
|
|
|
923
|
+
private getArgs(
|
|
924
|
+
options: LanguageModelV4CallOptions & {
|
|
925
|
+
stream: boolean;
|
|
926
|
+
userSuppliedBetas: Set<string>;
|
|
927
|
+
},
|
|
928
|
+
) {
|
|
929
|
+
return AnthropicLanguageModel.prepareRequest({
|
|
930
|
+
modelId: this.modelId,
|
|
931
|
+
config: this.config,
|
|
932
|
+
options,
|
|
933
|
+
});
|
|
934
|
+
}
|
|
935
|
+
|
|
930
936
|
private async getHeaders({
|
|
931
937
|
betas,
|
|
932
938
|
headers,
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
InvalidArgumentError,
|
|
3
3
|
NoSuchModelError,
|
|
4
|
-
type
|
|
4
|
+
type Experimental_BatchV4 as BatchV4,
|
|
5
5
|
type FilesV4,
|
|
6
|
+
type LanguageModelV4,
|
|
6
7
|
type ProviderV4,
|
|
7
8
|
type SkillsV4,
|
|
8
9
|
} from '@ai-sdk/provider';
|
|
@@ -16,7 +17,8 @@ import {
|
|
|
16
17
|
type FetchFunction,
|
|
17
18
|
} from '@ai-sdk/provider-utils';
|
|
18
19
|
import { AnthropicFiles } from './anthropic-files';
|
|
19
|
-
import {
|
|
20
|
+
import { AnthropicLanguageModel } from './anthropic-language-model';
|
|
21
|
+
import { AnthropicBatch } from './anthropic-batch';
|
|
20
22
|
import type { AnthropicModelId } from './anthropic-language-model-options';
|
|
21
23
|
import { anthropicTools } from './anthropic-tools';
|
|
22
24
|
import { AnthropicSkills } from './skills/anthropic-skills';
|
|
@@ -39,16 +41,18 @@ export interface AnthropicProvider extends ProviderV4 {
|
|
|
39
41
|
/**
|
|
40
42
|
* Creates a model for text generation.
|
|
41
43
|
*/
|
|
42
|
-
(modelId: AnthropicModelId):
|
|
44
|
+
(modelId: AnthropicModelId): LanguageModelV4;
|
|
43
45
|
|
|
44
46
|
/**
|
|
45
47
|
* Creates a model for text generation.
|
|
46
48
|
*/
|
|
47
|
-
languageModel(modelId: AnthropicModelId):
|
|
49
|
+
languageModel(modelId: AnthropicModelId): LanguageModelV4;
|
|
48
50
|
|
|
49
|
-
chat(modelId: AnthropicModelId):
|
|
51
|
+
chat(modelId: AnthropicModelId): LanguageModelV4;
|
|
50
52
|
|
|
51
|
-
messages(modelId: AnthropicModelId):
|
|
53
|
+
messages(modelId: AnthropicModelId): LanguageModelV4;
|
|
54
|
+
|
|
55
|
+
experimental_batch(): BatchV4<{ text: AnthropicModelId }>;
|
|
52
56
|
|
|
53
57
|
/**
|
|
54
58
|
* @deprecated Use `embeddingModel` instead.
|
|
@@ -124,6 +128,10 @@ export function createAnthropic(
|
|
|
124
128
|
) ?? ANTHROPIC_API_VERSIONED_URL;
|
|
125
129
|
|
|
126
130
|
const providerName = options.name ?? 'anthropic.messages';
|
|
131
|
+
const supportedUrls = {
|
|
132
|
+
'image/*': [/^https?:\/\/.*$/],
|
|
133
|
+
'application/pdf': [/^https?:\/\/.*$/],
|
|
134
|
+
};
|
|
127
135
|
|
|
128
136
|
// Only error if both are explicitly provided in options
|
|
129
137
|
if (options.apiKey && options.authToken) {
|
|
@@ -155,17 +163,23 @@ export function createAnthropic(
|
|
|
155
163
|
);
|
|
156
164
|
};
|
|
157
165
|
|
|
166
|
+
const languageModelConfig = {
|
|
167
|
+
provider: providerName,
|
|
168
|
+
baseURL,
|
|
169
|
+
headers: getHeaders,
|
|
170
|
+
fetch: options.fetch,
|
|
171
|
+
generateId: options.generateId ?? generateId,
|
|
172
|
+
supportedUrls: () => supportedUrls,
|
|
173
|
+
};
|
|
174
|
+
|
|
158
175
|
const createChatModel = (modelId: AnthropicModelId) =>
|
|
159
|
-
new
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
supportedUrls
|
|
166
|
-
'image/*': [/^https?:\/\/.*$/],
|
|
167
|
-
'application/pdf': [/^https?:\/\/.*$/],
|
|
168
|
-
}),
|
|
176
|
+
new AnthropicLanguageModel(modelId, languageModelConfig);
|
|
177
|
+
|
|
178
|
+
const createBatch = () =>
|
|
179
|
+
new AnthropicBatch({
|
|
180
|
+
provider: `${providerName.replace(/\.messages$/, '')}.batch`,
|
|
181
|
+
config: languageModelConfig,
|
|
182
|
+
supportedUrls,
|
|
169
183
|
});
|
|
170
184
|
|
|
171
185
|
const createSkills = () =>
|
|
@@ -190,6 +204,7 @@ export function createAnthropic(
|
|
|
190
204
|
provider.languageModel = createChatModel;
|
|
191
205
|
provider.chat = createChatModel;
|
|
192
206
|
provider.messages = createChatModel;
|
|
207
|
+
provider.experimental_batch = createBatch;
|
|
193
208
|
|
|
194
209
|
provider.embeddingModel = (modelId: string) => {
|
|
195
210
|
throw new NoSuchModelError({ modelId, modelType: 'embeddingModel' });
|