@ai-sdk/anthropic 2.0.31 → 2.0.33

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,17 @@
1
1
  # @ai-sdk/anthropic
2
2
 
3
+ ## 2.0.33
4
+
5
+ ### Patch Changes
6
+
7
+ - 28c9c6a: feat(anthropic): add prompt caching validation
8
+
9
+ ## 2.0.32
10
+
11
+ ### Patch Changes
12
+
13
+ - 492b1ee: feat(provider/anthropic): add support for Agent Skills
14
+
3
15
  ## 2.0.31
4
16
 
5
17
  ### Patch Changes
package/README.md CHANGED
@@ -6,7 +6,7 @@ The **[Anthropic provider](https://ai-sdk.dev/providers/ai-sdk-providers/anthrop
6
6
 
7
7
  The Anthropic provider is available in the `@ai-sdk/anthropic` module. You can install it with
8
8
 
9
- ```
9
+ ```bash
10
10
  npm i @ai-sdk/anthropic
11
11
  ```
12
12
 
package/dist/index.d.mts CHANGED
@@ -15,6 +15,14 @@ declare const anthropicProviderOptions: z.ZodObject<{
15
15
  type: z.ZodLiteral<"ephemeral">;
16
16
  ttl: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<"5m">, z.ZodLiteral<"1h">]>>;
17
17
  }, z.core.$strip>>;
18
+ container: z.ZodOptional<z.ZodObject<{
19
+ id: z.ZodOptional<z.ZodString>;
20
+ skills: z.ZodOptional<z.ZodArray<z.ZodObject<{
21
+ type: z.ZodUnion<readonly [z.ZodLiteral<"anthropic">, z.ZodLiteral<"custom">]>;
22
+ skillId: z.ZodString;
23
+ version: z.ZodOptional<z.ZodString>;
24
+ }, z.core.$strip>>>;
25
+ }, z.core.$strip>>;
18
26
  }, z.core.$strip>;
19
27
  type AnthropicProviderOptions = z.infer<typeof anthropicProviderOptions>;
20
28
 
package/dist/index.d.ts CHANGED
@@ -15,6 +15,14 @@ declare const anthropicProviderOptions: z.ZodObject<{
15
15
  type: z.ZodLiteral<"ephemeral">;
16
16
  ttl: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<"5m">, z.ZodLiteral<"1h">]>>;
17
17
  }, z.core.$strip>>;
18
+ container: z.ZodOptional<z.ZodObject<{
19
+ id: z.ZodOptional<z.ZodString>;
20
+ skills: z.ZodOptional<z.ZodArray<z.ZodObject<{
21
+ type: z.ZodUnion<readonly [z.ZodLiteral<"anthropic">, z.ZodLiteral<"custom">]>;
22
+ skillId: z.ZodString;
23
+ version: z.ZodOptional<z.ZodString>;
24
+ }, z.core.$strip>>>;
25
+ }, z.core.$strip>>;
18
26
  }, z.core.$strip>;
19
27
  type AnthropicProviderOptions = z.infer<typeof anthropicProviderOptions>;
20
28
 
package/dist/index.js CHANGED
@@ -31,7 +31,7 @@ var import_provider4 = require("@ai-sdk/provider");
31
31
  var import_provider_utils20 = require("@ai-sdk/provider-utils");
32
32
 
33
33
  // src/version.ts
34
- var VERSION = true ? "2.0.31" : "0.0.0-test";
34
+ var VERSION = true ? "2.0.33" : "0.0.0-test";
35
35
 
36
36
  // src/anthropic-messages-language-model.ts
37
37
  var import_provider3 = require("@ai-sdk/provider");
@@ -543,6 +543,21 @@ var anthropicProviderOptions = import_v43.z.object({
543
543
  cacheControl: import_v43.z.object({
544
544
  type: import_v43.z.literal("ephemeral"),
545
545
  ttl: import_v43.z.union([import_v43.z.literal("5m"), import_v43.z.literal("1h")]).optional()
546
+ }).optional(),
547
+ /**
548
+ * Agent Skills configuration. Skills enable Claude to perform specialized tasks
549
+ * like document processing (PPTX, DOCX, PDF, XLSX) and data analysis.
550
+ * Requires code execution tool to be enabled.
551
+ */
552
+ container: import_v43.z.object({
553
+ id: import_v43.z.string().optional(),
554
+ skills: import_v43.z.array(
555
+ import_v43.z.object({
556
+ type: import_v43.z.union([import_v43.z.literal("anthropic"), import_v43.z.literal("custom")]),
557
+ skillId: import_v43.z.string(),
558
+ version: import_v43.z.string().optional()
559
+ })
560
+ ).optional()
546
561
  }).optional()
547
562
  });
548
563
 
@@ -550,12 +565,46 @@ var anthropicProviderOptions = import_v43.z.object({
550
565
  var import_provider = require("@ai-sdk/provider");
551
566
 
552
567
  // src/get-cache-control.ts
568
+ var MAX_CACHE_BREAKPOINTS = 4;
553
569
  function getCacheControl(providerMetadata) {
554
570
  var _a;
555
571
  const anthropic2 = providerMetadata == null ? void 0 : providerMetadata.anthropic;
556
572
  const cacheControlValue = (_a = anthropic2 == null ? void 0 : anthropic2.cacheControl) != null ? _a : anthropic2 == null ? void 0 : anthropic2.cache_control;
557
573
  return cacheControlValue;
558
574
  }
575
+ var CacheControlValidator = class {
576
+ constructor() {
577
+ this.breakpointCount = 0;
578
+ this.warnings = [];
579
+ }
580
+ getCacheControl(providerMetadata, context) {
581
+ const cacheControlValue = getCacheControl(providerMetadata);
582
+ if (!cacheControlValue) {
583
+ return void 0;
584
+ }
585
+ if (!context.canCache) {
586
+ this.warnings.push({
587
+ type: "unsupported-setting",
588
+ setting: "cacheControl",
589
+ details: `cache_control cannot be set on ${context.type}. It will be ignored.`
590
+ });
591
+ return void 0;
592
+ }
593
+ this.breakpointCount++;
594
+ if (this.breakpointCount > MAX_CACHE_BREAKPOINTS) {
595
+ this.warnings.push({
596
+ type: "unsupported-setting",
597
+ setting: "cacheControl",
598
+ details: `Maximum ${MAX_CACHE_BREAKPOINTS} cache breakpoints exceeded (found ${this.breakpointCount}). This breakpoint will be ignored.`
599
+ });
600
+ return void 0;
601
+ }
602
+ return cacheControlValue;
603
+ }
604
+ getWarnings() {
605
+ return this.warnings;
606
+ }
607
+ };
559
608
 
560
609
  // src/tool/text-editor_20250728.ts
561
610
  var import_provider_utils3 = require("@ai-sdk/provider-utils");
@@ -701,11 +750,13 @@ var import_provider_utils7 = require("@ai-sdk/provider-utils");
701
750
  async function prepareTools({
702
751
  tools,
703
752
  toolChoice,
704
- disableParallelToolUse
753
+ disableParallelToolUse,
754
+ cacheControlValidator
705
755
  }) {
706
756
  tools = (tools == null ? void 0 : tools.length) ? tools : void 0;
707
757
  const toolWarnings = [];
708
758
  const betas = /* @__PURE__ */ new Set();
759
+ const validator = cacheControlValidator || new CacheControlValidator();
709
760
  if (tools == null) {
710
761
  return { tools: void 0, toolChoice: void 0, toolWarnings, betas };
711
762
  }
@@ -713,7 +764,10 @@ async function prepareTools({
713
764
  for (const tool of tools) {
714
765
  switch (tool.type) {
715
766
  case "function": {
716
- const cacheControl = getCacheControl(tool.providerOptions);
767
+ const cacheControl = validator.getCacheControl(tool.providerOptions, {
768
+ type: "tool definition",
769
+ canCache: true
770
+ });
717
771
  anthropicTools2.push({
718
772
  name: tool.name,
719
773
  description: tool.description,
@@ -728,7 +782,8 @@ async function prepareTools({
728
782
  betas.add("code-execution-2025-05-22");
729
783
  anthropicTools2.push({
730
784
  type: "code_execution_20250522",
731
- name: "code_execution"
785
+ name: "code_execution",
786
+ cache_control: void 0
732
787
  });
733
788
  break;
734
789
  }
@@ -747,7 +802,8 @@ async function prepareTools({
747
802
  type: "computer_20250124",
748
803
  display_width_px: tool.args.displayWidthPx,
749
804
  display_height_px: tool.args.displayHeightPx,
750
- display_number: tool.args.displayNumber
805
+ display_number: tool.args.displayNumber,
806
+ cache_control: void 0
751
807
  });
752
808
  break;
753
809
  }
@@ -758,7 +814,8 @@ async function prepareTools({
758
814
  type: "computer_20241022",
759
815
  display_width_px: tool.args.displayWidthPx,
760
816
  display_height_px: tool.args.displayHeightPx,
761
- display_number: tool.args.displayNumber
817
+ display_number: tool.args.displayNumber,
818
+ cache_control: void 0
762
819
  });
763
820
  break;
764
821
  }
@@ -766,7 +823,8 @@ async function prepareTools({
766
823
  betas.add("computer-use-2025-01-24");
767
824
  anthropicTools2.push({
768
825
  name: "str_replace_editor",
769
- type: "text_editor_20250124"
826
+ type: "text_editor_20250124",
827
+ cache_control: void 0
770
828
  });
771
829
  break;
772
830
  }
@@ -774,7 +832,8 @@ async function prepareTools({
774
832
  betas.add("computer-use-2024-10-22");
775
833
  anthropicTools2.push({
776
834
  name: "str_replace_editor",
777
- type: "text_editor_20241022"
835
+ type: "text_editor_20241022",
836
+ cache_control: void 0
778
837
  });
779
838
  break;
780
839
  }
@@ -782,7 +841,8 @@ async function prepareTools({
782
841
  betas.add("computer-use-2025-01-24");
783
842
  anthropicTools2.push({
784
843
  name: "str_replace_based_edit_tool",
785
- type: "text_editor_20250429"
844
+ type: "text_editor_20250429",
845
+ cache_control: void 0
786
846
  });
787
847
  break;
788
848
  }
@@ -794,7 +854,8 @@ async function prepareTools({
794
854
  anthropicTools2.push({
795
855
  name: "str_replace_based_edit_tool",
796
856
  type: "text_editor_20250728",
797
- max_characters: args.maxCharacters
857
+ max_characters: args.maxCharacters,
858
+ cache_control: void 0
798
859
  });
799
860
  break;
800
861
  }
@@ -802,7 +863,8 @@ async function prepareTools({
802
863
  betas.add("computer-use-2025-01-24");
803
864
  anthropicTools2.push({
804
865
  name: "bash",
805
- type: "bash_20250124"
866
+ type: "bash_20250124",
867
+ cache_control: void 0
806
868
  });
807
869
  break;
808
870
  }
@@ -810,7 +872,8 @@ async function prepareTools({
810
872
  betas.add("computer-use-2024-10-22");
811
873
  anthropicTools2.push({
812
874
  name: "bash",
813
- type: "bash_20241022"
875
+ type: "bash_20241022",
876
+ cache_control: void 0
814
877
  });
815
878
  break;
816
879
  }
@@ -835,7 +898,8 @@ async function prepareTools({
835
898
  allowed_domains: args.allowedDomains,
836
899
  blocked_domains: args.blockedDomains,
837
900
  citations: args.citations,
838
- max_content_tokens: args.maxContentTokens
901
+ max_content_tokens: args.maxContentTokens,
902
+ cache_control: void 0
839
903
  });
840
904
  break;
841
905
  }
@@ -850,7 +914,8 @@ async function prepareTools({
850
914
  max_uses: args.maxUses,
851
915
  allowed_domains: args.allowedDomains,
852
916
  blocked_domains: args.blockedDomains,
853
- user_location: args.userLocation
917
+ user_location: args.userLocation,
918
+ cache_control: void 0
854
919
  });
855
920
  break;
856
921
  }
@@ -1062,11 +1127,13 @@ function convertToString(data) {
1062
1127
  async function convertToAnthropicMessagesPrompt({
1063
1128
  prompt,
1064
1129
  sendReasoning,
1065
- warnings
1130
+ warnings,
1131
+ cacheControlValidator
1066
1132
  }) {
1067
1133
  var _a, _b, _c, _d, _e;
1068
1134
  const betas = /* @__PURE__ */ new Set();
1069
1135
  const blocks = groupIntoBlocks(prompt);
1136
+ const validator = cacheControlValidator || new CacheControlValidator();
1070
1137
  let system = void 0;
1071
1138
  const messages = [];
1072
1139
  async function shouldEnableCitations(providerMetadata) {
@@ -1103,7 +1170,10 @@ async function convertToAnthropicMessagesPrompt({
1103
1170
  system = block.messages.map(({ content, providerOptions }) => ({
1104
1171
  type: "text",
1105
1172
  text: content,
1106
- cache_control: getCacheControl(providerOptions)
1173
+ cache_control: validator.getCacheControl(providerOptions, {
1174
+ type: "system message",
1175
+ canCache: true
1176
+ })
1107
1177
  }));
1108
1178
  break;
1109
1179
  }
@@ -1116,7 +1186,13 @@ async function convertToAnthropicMessagesPrompt({
1116
1186
  for (let j = 0; j < content.length; j++) {
1117
1187
  const part = content[j];
1118
1188
  const isLastPart = j === content.length - 1;
1119
- const cacheControl = (_a = getCacheControl(part.providerOptions)) != null ? _a : isLastPart ? getCacheControl(message.providerOptions) : void 0;
1189
+ const cacheControl = (_a = validator.getCacheControl(part.providerOptions, {
1190
+ type: "user message part",
1191
+ canCache: true
1192
+ })) != null ? _a : isLastPart ? validator.getCacheControl(message.providerOptions, {
1193
+ type: "user message",
1194
+ canCache: true
1195
+ }) : void 0;
1120
1196
  switch (part.type) {
1121
1197
  case "text": {
1122
1198
  anthropicContent.push({
@@ -1204,7 +1280,13 @@ async function convertToAnthropicMessagesPrompt({
1204
1280
  for (let i2 = 0; i2 < content.length; i2++) {
1205
1281
  const part = content[i2];
1206
1282
  const isLastPart = i2 === content.length - 1;
1207
- const cacheControl = (_d = getCacheControl(part.providerOptions)) != null ? _d : isLastPart ? getCacheControl(message.providerOptions) : void 0;
1283
+ const cacheControl = (_d = validator.getCacheControl(part.providerOptions, {
1284
+ type: "tool result part",
1285
+ canCache: true
1286
+ })) != null ? _d : isLastPart ? validator.getCacheControl(message.providerOptions, {
1287
+ type: "tool result message",
1288
+ canCache: true
1289
+ }) : void 0;
1208
1290
  const output = part.output;
1209
1291
  let contentValue;
1210
1292
  switch (output.type) {
@@ -1214,8 +1296,7 @@ async function convertToAnthropicMessagesPrompt({
1214
1296
  case "text":
1215
1297
  return {
1216
1298
  type: "text",
1217
- text: contentPart.text,
1218
- cache_control: void 0
1299
+ text: contentPart.text
1219
1300
  };
1220
1301
  case "media": {
1221
1302
  if (contentPart.mediaType.startsWith("image/")) {
@@ -1225,8 +1306,7 @@ async function convertToAnthropicMessagesPrompt({
1225
1306
  type: "base64",
1226
1307
  media_type: contentPart.mediaType,
1227
1308
  data: contentPart.data
1228
- },
1229
- cache_control: void 0
1309
+ }
1230
1310
  };
1231
1311
  }
1232
1312
  if (contentPart.mediaType === "application/pdf") {
@@ -1237,8 +1317,7 @@ async function convertToAnthropicMessagesPrompt({
1237
1317
  type: "base64",
1238
1318
  media_type: contentPart.mediaType,
1239
1319
  data: contentPart.data
1240
- },
1241
- cache_control: void 0
1320
+ }
1242
1321
  };
1243
1322
  }
1244
1323
  throw new import_provider2.UnsupportedFunctionalityError({
@@ -1286,7 +1365,13 @@ async function convertToAnthropicMessagesPrompt({
1286
1365
  for (let k = 0; k < content.length; k++) {
1287
1366
  const part = content[k];
1288
1367
  const isLastContentPart = k === content.length - 1;
1289
- const cacheControl = (_e = getCacheControl(part.providerOptions)) != null ? _e : isLastContentPart ? getCacheControl(message.providerOptions) : void 0;
1368
+ const cacheControl = (_e = validator.getCacheControl(part.providerOptions, {
1369
+ type: "assistant message part",
1370
+ canCache: true
1371
+ })) != null ? _e : isLastContentPart ? validator.getCacheControl(message.providerOptions, {
1372
+ type: "assistant message",
1373
+ canCache: true
1374
+ }) : void 0;
1290
1375
  switch (part.type) {
1291
1376
  case "text": {
1292
1377
  anthropicContent.push({
@@ -1310,17 +1395,23 @@ async function convertToAnthropicMessagesPrompt({
1310
1395
  });
1311
1396
  if (reasoningMetadata != null) {
1312
1397
  if (reasoningMetadata.signature != null) {
1398
+ validator.getCacheControl(part.providerOptions, {
1399
+ type: "thinking block",
1400
+ canCache: false
1401
+ });
1313
1402
  anthropicContent.push({
1314
1403
  type: "thinking",
1315
1404
  thinking: part.text,
1316
- signature: reasoningMetadata.signature,
1317
- cache_control: cacheControl
1405
+ signature: reasoningMetadata.signature
1318
1406
  });
1319
1407
  } else if (reasoningMetadata.redactedData != null) {
1408
+ validator.getCacheControl(part.providerOptions, {
1409
+ type: "redacted thinking block",
1410
+ canCache: false
1411
+ });
1320
1412
  anthropicContent.push({
1321
1413
  type: "redacted_thinking",
1322
- data: reasoningMetadata.redactedData,
1323
- cache_control: cacheControl
1414
+ data: reasoningMetadata.redactedData
1324
1415
  });
1325
1416
  } else {
1326
1417
  warnings.push({
@@ -1649,7 +1740,7 @@ var AnthropicMessagesLanguageModel = class {
1649
1740
  toolChoice,
1650
1741
  providerOptions
1651
1742
  }) {
1652
- var _a, _b, _c;
1743
+ var _a, _b, _c, _d;
1653
1744
  const warnings = [];
1654
1745
  if (frequencyPenalty != null) {
1655
1746
  warnings.push({
@@ -1695,10 +1786,12 @@ var AnthropicMessagesLanguageModel = class {
1695
1786
  providerOptions,
1696
1787
  schema: anthropicProviderOptions
1697
1788
  });
1698
- const { prompt: messagesPrompt, betas: messagesBetas } = await convertToAnthropicMessagesPrompt({
1789
+ const cacheControlValidator = new CacheControlValidator();
1790
+ const { prompt: messagesPrompt, betas } = await convertToAnthropicMessagesPrompt({
1699
1791
  prompt,
1700
1792
  sendReasoning: (_a = anthropicOptions == null ? void 0 : anthropicOptions.sendReasoning) != null ? _a : true,
1701
- warnings
1793
+ warnings,
1794
+ cacheControlValidator
1702
1795
  });
1703
1796
  const isThinking = ((_b = anthropicOptions == null ? void 0 : anthropicOptions.thinking) == null ? void 0 : _b.type) === "enabled";
1704
1797
  const thinkingBudget = (_c = anthropicOptions == null ? void 0 : anthropicOptions.thinking) == null ? void 0 : _c.budgetTokens;
@@ -1717,6 +1810,17 @@ var AnthropicMessagesLanguageModel = class {
1717
1810
  ...isThinking && {
1718
1811
  thinking: { type: "enabled", budget_tokens: thinkingBudget }
1719
1812
  },
1813
+ // container with agent skills:
1814
+ ...(anthropicOptions == null ? void 0 : anthropicOptions.container) && {
1815
+ container: {
1816
+ id: anthropicOptions.container.id,
1817
+ skills: (_d = anthropicOptions.container.skills) == null ? void 0 : _d.map((skill) => ({
1818
+ type: skill.type,
1819
+ skill_id: skill.skillId,
1820
+ version: skill.version
1821
+ }))
1822
+ }
1823
+ },
1720
1824
  // prompt:
1721
1825
  system: messagesPrompt.system,
1722
1826
  messages: messagesPrompt.messages
@@ -1758,11 +1862,24 @@ var AnthropicMessagesLanguageModel = class {
1758
1862
  warnings.push({
1759
1863
  type: "unsupported-setting",
1760
1864
  setting: "maxOutputTokens",
1761
- details: `${maxTokens} (maxOutputTokens + thinkingBudget) is greater than ${this.modelId} ${maxOutputTokensForModel} max output tokens. The max output tokens have been limited to ${maxOutputTokensForModel}.`
1865
+ details: `${baseArgs.max_tokens} (maxOutputTokens + thinkingBudget) is greater than ${this.modelId} ${maxOutputTokensForModel} max output tokens. The max output tokens have been limited to ${maxOutputTokensForModel}.`
1762
1866
  });
1763
1867
  }
1764
1868
  baseArgs.max_tokens = maxOutputTokensForModel;
1765
1869
  }
1870
+ if ((anthropicOptions == null ? void 0 : anthropicOptions.container) && anthropicOptions.container.skills && anthropicOptions.container.skills.length > 0) {
1871
+ betas.add("code-execution-2025-08-25");
1872
+ betas.add("skills-2025-10-02");
1873
+ betas.add("files-api-2025-04-14");
1874
+ if (!(tools == null ? void 0 : tools.some(
1875
+ (tool) => tool.type === "provider-defined" && tool.id === "anthropic.code_execution_20250825"
1876
+ ))) {
1877
+ warnings.push({
1878
+ type: "other",
1879
+ message: "code execution tool is required when using skills"
1880
+ });
1881
+ }
1882
+ }
1766
1883
  const {
1767
1884
  tools: anthropicTools2,
1768
1885
  toolChoice: anthropicToolChoice,
@@ -1772,21 +1889,24 @@ var AnthropicMessagesLanguageModel = class {
1772
1889
  jsonResponseTool != null ? {
1773
1890
  tools: [jsonResponseTool],
1774
1891
  toolChoice: { type: "tool", toolName: jsonResponseTool.name },
1775
- disableParallelToolUse: true
1892
+ disableParallelToolUse: true,
1893
+ cacheControlValidator
1776
1894
  } : {
1777
1895
  tools: tools != null ? tools : [],
1778
1896
  toolChoice,
1779
- disableParallelToolUse: anthropicOptions == null ? void 0 : anthropicOptions.disableParallelToolUse
1897
+ disableParallelToolUse: anthropicOptions == null ? void 0 : anthropicOptions.disableParallelToolUse,
1898
+ cacheControlValidator
1780
1899
  }
1781
1900
  );
1901
+ const cacheWarnings = cacheControlValidator.getWarnings();
1782
1902
  return {
1783
1903
  args: {
1784
1904
  ...baseArgs,
1785
1905
  tools: anthropicTools2,
1786
1906
  tool_choice: anthropicToolChoice
1787
1907
  },
1788
- warnings: [...warnings, ...toolWarnings],
1789
- betas: /* @__PURE__ */ new Set([...messagesBetas, ...toolsBetas]),
1908
+ warnings: [...warnings, ...toolWarnings, ...cacheWarnings],
1909
+ betas: /* @__PURE__ */ new Set([...betas, ...toolsBetas]),
1790
1910
  usesJsonResponseTool: jsonResponseTool != null
1791
1911
  };
1792
1912
  }