@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.
@@ -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
- ### Text Batches
147
+ ### Batch
148
148
 
149
149
  <Note type="warning">
150
- Text batch support is experimental and the API may change in patch releases.
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
- Use the experimental text batch APIs to start a batch, poll its status, and
156
- stream its results:
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
- ```ts
159
- import { anthropic } from '@ai-sdk/anthropic';
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.49",
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.10",
39
- "@ai-sdk/provider-utils": "5.0.36"
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 Experimental_BatchLanguageModelV4 as BatchLanguageModelV4,
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 = Parameters<
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 AnthropicMessagesBatchLanguageModel
152
- extends AnthropicLanguageModel
153
- implements BatchLanguageModelV4
154
- {
155
- static [WORKFLOW_SERIALIZE](model: AnthropicMessagesBatchLanguageModel) {
156
- return AnthropicLanguageModel[WORKFLOW_SERIALIZE](model);
157
- }
158
-
159
- static [WORKFLOW_DESERIALIZE](options: {
160
- modelId: AnthropicModelId;
161
- config: AnthropicLanguageModelConfig;
162
- }) {
163
- return new AnthropicMessagesBatchLanguageModel(
164
- options.modelId,
165
- options.config,
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 experimental_doStartBatch({
171
+ async doStartBatch({
174
172
  requests,
175
173
  providerOptions,
176
174
  headers,
177
175
  abortSignal,
178
176
  webhookUrl,
179
- }: Parameters<
180
- BatchLanguageModelV4['experimental_doStartBatch']
181
- >[0]): Promise<BatchV4StartResult> {
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 startTextBatch instead.`,
218
+ `on startBatch instead.`,
221
219
  });
222
220
  }
223
221
 
224
- const prepared = await this.getArgs({
225
- ...request.options,
226
- stream: false,
227
- userSuppliedBetas: new Set(explicitBatchBetas),
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 = this.transformRequestBody(prepared.args, prepared.betas);
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 experimental_doGetBatchStatus(
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 experimental_doGetBatchResults(
298
+ async doGetBatchResults(
293
299
  options: BatchV4OperationOptions,
294
- ): Promise<ReadableStream<BatchV4ItemResult<LanguageModelV4GenerateResult>>> {
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<LanguageModelV4GenerateResult>> {
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.config.headers ? await resolve(this.config.headers) : undefined,
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<BatchV4ItemResult<LanguageModelV4GenerateResult>> {
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
- protected async getArgs({
274
- userSuppliedBetas,
275
- prompt,
276
- maxOutputTokens,
277
- temperature,
278
- topP,
279
- topK,
280
- frequencyPenalty,
281
- presencePenalty,
282
- stopSequences,
283
- responseFormat,
284
- seed,
285
- tools,
286
- toolChoice,
287
- reasoning,
288
- providerOptions,
289
- stream,
290
- }: LanguageModelV4CallOptions & {
291
- stream: boolean;
292
- userSuppliedBetas: Set<string>;
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 = this.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(this.modelId);
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 "${this.modelId}" is unknown. ` +
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 ${this.modelId} and will be ignored`,
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 ${this.modelId} and will be ignored`,
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 ${this.modelId} and will be ignored`,
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 || this.modelId.includes('claude-');
406
+ const isAnthropicModel = isKnownModel || modelId.includes('claude-');
413
407
 
414
408
  const supportsStructuredOutput =
415
- (this.config.supportsNativeStructuredOutput ?? true) &&
409
+ (config.supportsNativeStructuredOutput ?? true) &&
416
410
  modelSupportsStructuredOutput;
417
411
 
418
412
  const supportsStrictTools =
419
- (this.config.supportsStrictTools ?? true) &&
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 ${this.modelId} when thinking is disabled. ` +
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: this.modelId,
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 ${this.modelId} ${maxOutputTokensForModel} max output tokens. ` +
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 Experimental_BatchLanguageModelV4 as BatchLanguageModelV4,
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 { AnthropicMessagesBatchLanguageModel } from './anthropic-messages-batch';
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): BatchLanguageModelV4;
44
+ (modelId: AnthropicModelId): LanguageModelV4;
43
45
 
44
46
  /**
45
47
  * Creates a model for text generation.
46
48
  */
47
- languageModel(modelId: AnthropicModelId): BatchLanguageModelV4;
49
+ languageModel(modelId: AnthropicModelId): LanguageModelV4;
48
50
 
49
- chat(modelId: AnthropicModelId): BatchLanguageModelV4;
51
+ chat(modelId: AnthropicModelId): LanguageModelV4;
50
52
 
51
- messages(modelId: AnthropicModelId): BatchLanguageModelV4;
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 AnthropicMessagesBatchLanguageModel(modelId, {
160
- provider: providerName,
161
- baseURL,
162
- headers: getHeaders,
163
- fetch: options.fetch,
164
- generateId: options.generateId ?? generateId,
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' });