@ai-sdk/anthropic 4.0.41 → 4.0.44

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 CHANGED
@@ -1,5 +1,33 @@
1
1
  # @ai-sdk/anthropic
2
2
 
3
+ ## 4.0.44
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies [3e125ba]
8
+ - @ai-sdk/provider-utils@5.0.32
9
+
10
+ ## 4.0.43
11
+
12
+ ### Patch Changes
13
+
14
+ - 7de3612: Encode provider-returned identifiers before using them in credentialed follow-up request paths.
15
+ - a9782e1: fix: align batch result parsing, request counts, and lifecycle behavior across providers
16
+ - 35841f5: feat: normalize mid-stream provider error events across supported providers into public StreamProviderError instances and preserve provider-owned type, code, status, retry, and raw payload metadata
17
+ - Updated dependencies [a9782e1]
18
+ - Updated dependencies [35841f5]
19
+ - Updated dependencies [d2f3353]
20
+ - @ai-sdk/provider-utils@5.0.31
21
+
22
+ ## 4.0.42
23
+
24
+ ### Patch Changes
25
+
26
+ - 591d25b: feat: add batch completion webhooks. `experimental_startTextBatch` accepts a `webhookUrl`, and the gateway provider registers it through the batch `callbackUrl` contract and exports typed async-job metadata. Direct Anthropic and OpenAI batch providers return an unsupported warning when the option is provided.
27
+ - Updated dependencies [591d25b]
28
+ - @ai-sdk/provider@4.0.8
29
+ - @ai-sdk/provider-utils@5.0.30
30
+
3
31
  ## 4.0.41
4
32
 
5
33
  ### Patch Changes
package/dist/index.js CHANGED
@@ -114,18 +114,19 @@ var AnthropicFiles = class {
114
114
 
115
115
  // src/anthropic-messages-batch.ts
116
116
  import {
117
- EmptyResponseBodyError,
118
117
  InvalidArgumentError,
118
+ InvalidResponseDataError as InvalidResponseDataError2,
119
119
  UnsupportedFunctionalityError as UnsupportedFunctionalityError3
120
120
  } from "@ai-sdk/provider";
121
121
  import {
122
122
  combineHeaders as combineHeaders3,
123
123
  convertAsyncIteratorToReadableStream,
124
+ createJsonLinesResponseHandler,
124
125
  createJsonResponseHandler as createJsonResponseHandler3,
125
126
  getFromApi,
126
127
  lazySchema as lazySchema14,
128
+ normalizeBatchRequestCounts,
127
129
  normalizeHeaders,
128
- parseJSON,
129
130
  parseProviderOptions as parseProviderOptions3,
130
131
  postJsonToApi as postJsonToApi2,
131
132
  resolve as resolve2,
@@ -840,7 +841,11 @@ var anthropicChunkSchema = lazySchema3(
840
841
  type: z3.literal("error"),
841
842
  error: z3.object({
842
843
  type: z3.string(),
843
- message: z3.string()
844
+ message: z3.string(),
845
+ code: z3.union([z3.string(), z3.number()]).nullish(),
846
+ statusCode: z3.number().nullish(),
847
+ isRetryable: z3.boolean().nullish(),
848
+ data: z3.unknown().nullish()
844
849
  })
845
850
  }),
846
851
  z3.object({
@@ -935,9 +940,11 @@ import {
935
940
  combineHeaders as combineHeaders2,
936
941
  createEventSourceResponseHandler,
937
942
  createJsonResponseHandler as createJsonResponseHandler2,
943
+ createProviderStreamError,
938
944
  createToolNameMapping,
939
945
  generateId,
940
946
  isCustomReasoning,
947
+ isProviderStreamError,
941
948
  mapReasoningToProviderBudget,
942
949
  mapReasoningToProviderEffort,
943
950
  parseProviderOptions as parseProviderOptions2,
@@ -3611,6 +3618,41 @@ function formatConstraintValue(value) {
3611
3618
  }
3612
3619
 
3613
3620
  // src/anthropic-language-model.ts
3621
+ function createAnthropicStreamError(error) {
3622
+ var _a, _b, _c;
3623
+ const inferredMetadata = getAnthropicStreamErrorMetadata(error.type);
3624
+ return createProviderStreamError({
3625
+ message: error.message,
3626
+ type: error.type,
3627
+ code: (_a = error.code) != null ? _a : void 0,
3628
+ statusCode: (_b = error.statusCode) != null ? _b : inferredMetadata.statusCode,
3629
+ isRetryable: (_c = error.isRetryable) != null ? _c : inferredMetadata.isRetryable,
3630
+ data: "data" in error ? error.data : error
3631
+ });
3632
+ }
3633
+ function getAnthropicStreamErrorMetadata(type) {
3634
+ switch (type) {
3635
+ case "api_error":
3636
+ return { statusCode: 500, isRetryable: true };
3637
+ case "overloaded_error":
3638
+ return { statusCode: 529, isRetryable: true };
3639
+ case "rate_limit_error":
3640
+ return { statusCode: 429, isRetryable: true };
3641
+ case "request_too_large":
3642
+ return { statusCode: 413, isRetryable: false };
3643
+ case "authentication_error":
3644
+ return { statusCode: 401, isRetryable: false };
3645
+ case "permission_error":
3646
+ return { statusCode: 403, isRetryable: false };
3647
+ case "not_found_error":
3648
+ return { statusCode: 404, isRetryable: false };
3649
+ case "billing_error":
3650
+ case "invalid_request_error":
3651
+ return { statusCode: 400, isRetryable: false };
3652
+ default:
3653
+ return {};
3654
+ }
3655
+ }
3614
3656
  function createCitationSource(citation, citationDocuments, generateId3) {
3615
3657
  var _a;
3616
3658
  if (citation.type === "web_search_result_location") {
@@ -4737,7 +4779,7 @@ var AnthropicLanguageModel = class _AnthropicLanguageModel {
4737
4779
  }
4738
4780
  async doStream(options) {
4739
4781
  "use step";
4740
- var _a, _b;
4782
+ var _a, _b, _c, _d;
4741
4783
  const {
4742
4784
  args: body,
4743
4785
  warnings,
@@ -4798,7 +4840,7 @@ var AnthropicLanguageModel = class _AnthropicLanguageModel {
4798
4840
  controller.enqueue({ type: "stream-start", warnings });
4799
4841
  },
4800
4842
  transform(chunk, controller) {
4801
- var _a2, _b2, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m;
4843
+ var _a2, _b2, _c2, _d2, _e, _f, _g, _h, _i, _j, _k, _l, _m;
4802
4844
  if (hasInvalidMessageSequence) {
4803
4845
  return;
4804
4846
  }
@@ -5091,7 +5133,7 @@ var AnthropicLanguageModel = class _AnthropicLanguageModel {
5091
5133
  stdout: part.content.stdout,
5092
5134
  stderr: part.content.stderr,
5093
5135
  return_code: part.content.return_code,
5094
- content: (_c = part.content.content) != null ? _c : []
5136
+ content: (_c2 = part.content.content) != null ? _c2 : []
5095
5137
  }
5096
5138
  });
5097
5139
  } else if (part.content.type === "encrypted_code_execution_result") {
@@ -5104,7 +5146,7 @@ var AnthropicLanguageModel = class _AnthropicLanguageModel {
5104
5146
  encrypted_stdout: part.content.encrypted_stdout,
5105
5147
  stderr: part.content.stderr,
5106
5148
  return_code: part.content.return_code,
5107
- content: (_d = part.content.content) != null ? _d : []
5149
+ content: (_d2 = part.content.content) != null ? _d2 : []
5108
5150
  }
5109
5151
  });
5110
5152
  } else if (part.content.type === "code_execution_tool_result_error") {
@@ -5598,7 +5640,10 @@ var AnthropicLanguageModel = class _AnthropicLanguageModel {
5598
5640
  return;
5599
5641
  }
5600
5642
  case "error": {
5601
- controller.enqueue({ type: "error", error: value.error });
5643
+ controller.enqueue({
5644
+ type: "error",
5645
+ error: createAnthropicStreamError(value.error)
5646
+ });
5602
5647
  return;
5603
5648
  }
5604
5649
  default: {
@@ -5619,14 +5664,17 @@ var AnthropicLanguageModel = class _AnthropicLanguageModel {
5619
5664
  }
5620
5665
  if (((_b = result.value) == null ? void 0 : _b.type) === "error") {
5621
5666
  const error = result.value.error;
5667
+ if (!isProviderStreamError(error)) {
5668
+ throw new Error("Expected a normalized Anthropic stream error");
5669
+ }
5622
5670
  throw new APICallError({
5623
5671
  message: error.message,
5624
5672
  url,
5625
5673
  requestBodyValues: body,
5626
- statusCode: error.type === "overloaded_error" ? 529 : 500,
5674
+ statusCode: (_c = error.statusCode) != null ? _c : 500,
5627
5675
  responseHeaders,
5628
- responseBody: JSON.stringify(error),
5629
- isRetryable: error.type === "overloaded_error"
5676
+ responseBody: JSON.stringify(error.data),
5677
+ isRetryable: (_d = error.isRetryable) != null ? _d : false
5630
5678
  });
5631
5679
  }
5632
5680
  } finally {
@@ -5918,7 +5966,8 @@ var AnthropicMessagesBatchLanguageModel = class _AnthropicMessagesBatchLanguageM
5918
5966
  requests,
5919
5967
  providerOptions,
5920
5968
  headers,
5921
- abortSignal
5969
+ abortSignal,
5970
+ webhookUrl
5922
5971
  }) {
5923
5972
  validateRequestIds(requests);
5924
5973
  const explicitBatchBetas = new Set(
@@ -5929,7 +5978,15 @@ var AnthropicMessagesBatchLanguageModel = class _AnthropicMessagesBatchLanguageM
5929
5978
  );
5930
5979
  const batchBetas = new Set(explicitBatchBetas);
5931
5980
  const preparedRequests = [];
5932
- const batchWarnings = [];
5981
+ const batchWarnings = webhookUrl == null ? [] : [
5982
+ {
5983
+ warning: {
5984
+ type: "unsupported",
5985
+ feature: "webhookUrl",
5986
+ details: "The Anthropic Message Batches API does not support completion webhooks."
5987
+ }
5988
+ }
5989
+ ];
5933
5990
  for (const request of requests) {
5934
5991
  const requestBetas = await getAnthropicBatchProviderBetas({
5935
5992
  provider: this.config.provider,
@@ -5994,24 +6051,26 @@ var AnthropicMessagesBatchLanguageModel = class _AnthropicMessagesBatchLanguageM
5994
6051
  });
5995
6052
  }
5996
6053
  if (batch.results_url == null) {
5997
- throw new InvalidArgumentError({
5998
- argument: "batchId",
5999
- message: `Anthropic batch "${options.batchId}" does not have a results URL.`
6054
+ throw new InvalidResponseDataError2({
6055
+ data: batch,
6056
+ message: `Anthropic batch "${options.batchId}" completed without batch output.`
6000
6057
  });
6001
6058
  }
6002
- const { value: stream } = await getFromApi({
6059
+ const { value: lines } = await getFromApi({
6003
6060
  url: batch.results_url,
6004
6061
  validateUrl: true,
6005
6062
  credentialedOrigin: this.config.baseURL,
6006
6063
  trustedOrigin: this.config.baseURL,
6007
6064
  headers: await this.getBatchHeaders(options.headers),
6008
6065
  failedResponseHandler: anthropicFailedResponseHandler,
6009
- successfulResponseHandler: rawStreamResponseHandler,
6066
+ successfulResponseHandler: createJsonLinesResponseHandler(
6067
+ anthropicBatchResultLineSchema
6068
+ ),
6010
6069
  abortSignal: options.abortSignal,
6011
6070
  fetch: this.config.fetch
6012
6071
  });
6013
6072
  return convertAsyncIteratorToReadableStream(
6014
- this.iterateBatchResults(stream)
6073
+ this.iterateBatchResults(lines)
6015
6074
  );
6016
6075
  }
6017
6076
  async retrieveBatch(options) {
@@ -6028,8 +6087,8 @@ var AnthropicMessagesBatchLanguageModel = class _AnthropicMessagesBatchLanguageM
6028
6087
  });
6029
6088
  return batch;
6030
6089
  }
6031
- async *iterateBatchResults(stream) {
6032
- for await (const line of parseJsonLines(stream)) {
6090
+ async *iterateBatchResults(lines) {
6091
+ for await (const line of lines) {
6033
6092
  yield await convertAnthropicBatchResult(line);
6034
6093
  }
6035
6094
  }
@@ -6135,22 +6194,12 @@ function mapAnthropicBatchStatus(rawStatus) {
6135
6194
  }
6136
6195
  }
6137
6196
  function convertAnthropicRequestCounts(counts) {
6138
- const values = [
6139
- counts.processing,
6140
- counts.succeeded,
6141
- counts.errored,
6142
- counts.canceled,
6143
- counts.expired
6144
- ];
6145
- if (values.some((value) => !Number.isFinite(value) || value < 0)) {
6146
- return void 0;
6147
- }
6148
- return {
6149
- total: values.reduce((total, value) => total + value, 0),
6197
+ return normalizeBatchRequestCounts({
6198
+ total: counts.processing + counts.succeeded + counts.errored + counts.canceled + counts.expired,
6150
6199
  pending: counts.processing,
6151
6200
  completed: counts.succeeded,
6152
6201
  failed: counts.errored + counts.canceled + counts.expired
6153
- };
6202
+ });
6154
6203
  }
6155
6204
  async function convertAnthropicBatchResult(line) {
6156
6205
  switch (line.result.type) {
@@ -6199,7 +6248,7 @@ async function convertAnthropicBatchResult(line) {
6199
6248
  status: "failed",
6200
6249
  error: {
6201
6250
  message: `Anthropic returned a "${unsupportedPart.type}" content block, but tool content is not supported in AI SDK text batches.`,
6202
- code: "unsupported_tool_content"
6251
+ code: "unsupported_content"
6203
6252
  }
6204
6253
  };
6205
6254
  }
@@ -6344,54 +6393,6 @@ function mapAnthropicStopDetails2(stopDetails) {
6344
6393
  ...stopDetails.recommended_model != null ? { recommendedModel: stopDetails.recommended_model } : {}
6345
6394
  };
6346
6395
  }
6347
- var rawStreamResponseHandler = async ({ response }) => {
6348
- if (response.body == null) {
6349
- throw new EmptyResponseBodyError();
6350
- }
6351
- return { value: response.body };
6352
- };
6353
- async function* parseJsonLines(stream) {
6354
- const reader = stream.getReader();
6355
- const decoder = new TextDecoder();
6356
- let buffer = "";
6357
- let finished = false;
6358
- try {
6359
- while (true) {
6360
- const { done, value } = await reader.read();
6361
- if (done) {
6362
- finished = true;
6363
- buffer += decoder.decode();
6364
- break;
6365
- }
6366
- buffer += decoder.decode(value, { stream: true });
6367
- let lineEnd = buffer.indexOf("\n");
6368
- while (lineEnd !== -1) {
6369
- const line = buffer.slice(0, lineEnd).replace(/\r$/, "");
6370
- buffer = buffer.slice(lineEnd + 1);
6371
- if (line.trim().length > 0) {
6372
- yield await parseJSON({
6373
- text: line,
6374
- schema: anthropicBatchResultLineSchema
6375
- });
6376
- }
6377
- lineEnd = buffer.indexOf("\n");
6378
- }
6379
- }
6380
- const finalLine = buffer.replace(/\r$/, "");
6381
- if (finalLine.trim().length > 0) {
6382
- yield await parseJSON({
6383
- text: finalLine,
6384
- schema: anthropicBatchResultLineSchema
6385
- });
6386
- }
6387
- } finally {
6388
- if (!finished) {
6389
- await reader.cancel().catch(() => {
6390
- });
6391
- }
6392
- reader.releaseLock();
6393
- }
6394
- }
6395
6396
 
6396
6397
  // src/tool/bash_20241022.ts
6397
6398
  import {
@@ -7050,6 +7051,10 @@ var anthropicSkillVersionResponseSchema = lazySchema25(
7050
7051
  );
7051
7052
 
7052
7053
  // src/skills/anthropic-skills.ts
7054
+ function encodePathSegment(value) {
7055
+ const encodedValue = encodeURIComponent(value);
7056
+ return encodedValue === "." ? "%252E" : encodedValue === ".." ? "%252E%252E" : encodedValue;
7057
+ }
7053
7058
  var AnthropicSkills = class {
7054
7059
  constructor(config) {
7055
7060
  this.config = config;
@@ -7069,7 +7074,7 @@ var AnthropicSkills = class {
7069
7074
  headers
7070
7075
  }) {
7071
7076
  const { value: versionResponse } = await getFromApi2({
7072
- url: `${this.config.baseURL}/skills/${skillId}/versions/${version}`,
7077
+ url: `${this.config.baseURL}/skills/${encodePathSegment(skillId)}/versions/${encodePathSegment(version)}`,
7073
7078
  validateUrl: false,
7074
7079
  headers,
7075
7080
  failedResponseHandler: anthropicFailedResponseHandler,
@@ -7131,7 +7136,7 @@ var AnthropicSkills = class {
7131
7136
  };
7132
7137
 
7133
7138
  // src/version.ts
7134
- var VERSION = true ? "4.0.41" : "0.0.0-test";
7139
+ var VERSION = true ? "4.0.44" : "0.0.0-test";
7135
7140
 
7136
7141
  // src/anthropic-provider.ts
7137
7142
  var ANTHROPIC_API_URL = "https://api.anthropic.com";