@ai-sdk/anthropic 2.0.32 → 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,11 @@
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
+
3
9
  ## 2.0.32
4
10
 
5
11
  ### Patch Changes
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.32" : "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");
@@ -565,12 +565,46 @@ var anthropicProviderOptions = import_v43.z.object({
565
565
  var import_provider = require("@ai-sdk/provider");
566
566
 
567
567
  // src/get-cache-control.ts
568
+ var MAX_CACHE_BREAKPOINTS = 4;
568
569
  function getCacheControl(providerMetadata) {
569
570
  var _a;
570
571
  const anthropic2 = providerMetadata == null ? void 0 : providerMetadata.anthropic;
571
572
  const cacheControlValue = (_a = anthropic2 == null ? void 0 : anthropic2.cacheControl) != null ? _a : anthropic2 == null ? void 0 : anthropic2.cache_control;
572
573
  return cacheControlValue;
573
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
+ };
574
608
 
575
609
  // src/tool/text-editor_20250728.ts
576
610
  var import_provider_utils3 = require("@ai-sdk/provider-utils");
@@ -716,11 +750,13 @@ var import_provider_utils7 = require("@ai-sdk/provider-utils");
716
750
  async function prepareTools({
717
751
  tools,
718
752
  toolChoice,
719
- disableParallelToolUse
753
+ disableParallelToolUse,
754
+ cacheControlValidator
720
755
  }) {
721
756
  tools = (tools == null ? void 0 : tools.length) ? tools : void 0;
722
757
  const toolWarnings = [];
723
758
  const betas = /* @__PURE__ */ new Set();
759
+ const validator = cacheControlValidator || new CacheControlValidator();
724
760
  if (tools == null) {
725
761
  return { tools: void 0, toolChoice: void 0, toolWarnings, betas };
726
762
  }
@@ -728,7 +764,10 @@ async function prepareTools({
728
764
  for (const tool of tools) {
729
765
  switch (tool.type) {
730
766
  case "function": {
731
- const cacheControl = getCacheControl(tool.providerOptions);
767
+ const cacheControl = validator.getCacheControl(tool.providerOptions, {
768
+ type: "tool definition",
769
+ canCache: true
770
+ });
732
771
  anthropicTools2.push({
733
772
  name: tool.name,
734
773
  description: tool.description,
@@ -743,7 +782,8 @@ async function prepareTools({
743
782
  betas.add("code-execution-2025-05-22");
744
783
  anthropicTools2.push({
745
784
  type: "code_execution_20250522",
746
- name: "code_execution"
785
+ name: "code_execution",
786
+ cache_control: void 0
747
787
  });
748
788
  break;
749
789
  }
@@ -762,7 +802,8 @@ async function prepareTools({
762
802
  type: "computer_20250124",
763
803
  display_width_px: tool.args.displayWidthPx,
764
804
  display_height_px: tool.args.displayHeightPx,
765
- display_number: tool.args.displayNumber
805
+ display_number: tool.args.displayNumber,
806
+ cache_control: void 0
766
807
  });
767
808
  break;
768
809
  }
@@ -773,7 +814,8 @@ async function prepareTools({
773
814
  type: "computer_20241022",
774
815
  display_width_px: tool.args.displayWidthPx,
775
816
  display_height_px: tool.args.displayHeightPx,
776
- display_number: tool.args.displayNumber
817
+ display_number: tool.args.displayNumber,
818
+ cache_control: void 0
777
819
  });
778
820
  break;
779
821
  }
@@ -781,7 +823,8 @@ async function prepareTools({
781
823
  betas.add("computer-use-2025-01-24");
782
824
  anthropicTools2.push({
783
825
  name: "str_replace_editor",
784
- type: "text_editor_20250124"
826
+ type: "text_editor_20250124",
827
+ cache_control: void 0
785
828
  });
786
829
  break;
787
830
  }
@@ -789,7 +832,8 @@ async function prepareTools({
789
832
  betas.add("computer-use-2024-10-22");
790
833
  anthropicTools2.push({
791
834
  name: "str_replace_editor",
792
- type: "text_editor_20241022"
835
+ type: "text_editor_20241022",
836
+ cache_control: void 0
793
837
  });
794
838
  break;
795
839
  }
@@ -797,7 +841,8 @@ async function prepareTools({
797
841
  betas.add("computer-use-2025-01-24");
798
842
  anthropicTools2.push({
799
843
  name: "str_replace_based_edit_tool",
800
- type: "text_editor_20250429"
844
+ type: "text_editor_20250429",
845
+ cache_control: void 0
801
846
  });
802
847
  break;
803
848
  }
@@ -809,7 +854,8 @@ async function prepareTools({
809
854
  anthropicTools2.push({
810
855
  name: "str_replace_based_edit_tool",
811
856
  type: "text_editor_20250728",
812
- max_characters: args.maxCharacters
857
+ max_characters: args.maxCharacters,
858
+ cache_control: void 0
813
859
  });
814
860
  break;
815
861
  }
@@ -817,7 +863,8 @@ async function prepareTools({
817
863
  betas.add("computer-use-2025-01-24");
818
864
  anthropicTools2.push({
819
865
  name: "bash",
820
- type: "bash_20250124"
866
+ type: "bash_20250124",
867
+ cache_control: void 0
821
868
  });
822
869
  break;
823
870
  }
@@ -825,7 +872,8 @@ async function prepareTools({
825
872
  betas.add("computer-use-2024-10-22");
826
873
  anthropicTools2.push({
827
874
  name: "bash",
828
- type: "bash_20241022"
875
+ type: "bash_20241022",
876
+ cache_control: void 0
829
877
  });
830
878
  break;
831
879
  }
@@ -850,7 +898,8 @@ async function prepareTools({
850
898
  allowed_domains: args.allowedDomains,
851
899
  blocked_domains: args.blockedDomains,
852
900
  citations: args.citations,
853
- max_content_tokens: args.maxContentTokens
901
+ max_content_tokens: args.maxContentTokens,
902
+ cache_control: void 0
854
903
  });
855
904
  break;
856
905
  }
@@ -865,7 +914,8 @@ async function prepareTools({
865
914
  max_uses: args.maxUses,
866
915
  allowed_domains: args.allowedDomains,
867
916
  blocked_domains: args.blockedDomains,
868
- user_location: args.userLocation
917
+ user_location: args.userLocation,
918
+ cache_control: void 0
869
919
  });
870
920
  break;
871
921
  }
@@ -1077,11 +1127,13 @@ function convertToString(data) {
1077
1127
  async function convertToAnthropicMessagesPrompt({
1078
1128
  prompt,
1079
1129
  sendReasoning,
1080
- warnings
1130
+ warnings,
1131
+ cacheControlValidator
1081
1132
  }) {
1082
1133
  var _a, _b, _c, _d, _e;
1083
1134
  const betas = /* @__PURE__ */ new Set();
1084
1135
  const blocks = groupIntoBlocks(prompt);
1136
+ const validator = cacheControlValidator || new CacheControlValidator();
1085
1137
  let system = void 0;
1086
1138
  const messages = [];
1087
1139
  async function shouldEnableCitations(providerMetadata) {
@@ -1118,7 +1170,10 @@ async function convertToAnthropicMessagesPrompt({
1118
1170
  system = block.messages.map(({ content, providerOptions }) => ({
1119
1171
  type: "text",
1120
1172
  text: content,
1121
- cache_control: getCacheControl(providerOptions)
1173
+ cache_control: validator.getCacheControl(providerOptions, {
1174
+ type: "system message",
1175
+ canCache: true
1176
+ })
1122
1177
  }));
1123
1178
  break;
1124
1179
  }
@@ -1131,7 +1186,13 @@ async function convertToAnthropicMessagesPrompt({
1131
1186
  for (let j = 0; j < content.length; j++) {
1132
1187
  const part = content[j];
1133
1188
  const isLastPart = j === content.length - 1;
1134
- 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;
1135
1196
  switch (part.type) {
1136
1197
  case "text": {
1137
1198
  anthropicContent.push({
@@ -1219,7 +1280,13 @@ async function convertToAnthropicMessagesPrompt({
1219
1280
  for (let i2 = 0; i2 < content.length; i2++) {
1220
1281
  const part = content[i2];
1221
1282
  const isLastPart = i2 === content.length - 1;
1222
- 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;
1223
1290
  const output = part.output;
1224
1291
  let contentValue;
1225
1292
  switch (output.type) {
@@ -1229,8 +1296,7 @@ async function convertToAnthropicMessagesPrompt({
1229
1296
  case "text":
1230
1297
  return {
1231
1298
  type: "text",
1232
- text: contentPart.text,
1233
- cache_control: void 0
1299
+ text: contentPart.text
1234
1300
  };
1235
1301
  case "media": {
1236
1302
  if (contentPart.mediaType.startsWith("image/")) {
@@ -1240,8 +1306,7 @@ async function convertToAnthropicMessagesPrompt({
1240
1306
  type: "base64",
1241
1307
  media_type: contentPart.mediaType,
1242
1308
  data: contentPart.data
1243
- },
1244
- cache_control: void 0
1309
+ }
1245
1310
  };
1246
1311
  }
1247
1312
  if (contentPart.mediaType === "application/pdf") {
@@ -1252,8 +1317,7 @@ async function convertToAnthropicMessagesPrompt({
1252
1317
  type: "base64",
1253
1318
  media_type: contentPart.mediaType,
1254
1319
  data: contentPart.data
1255
- },
1256
- cache_control: void 0
1320
+ }
1257
1321
  };
1258
1322
  }
1259
1323
  throw new import_provider2.UnsupportedFunctionalityError({
@@ -1301,7 +1365,13 @@ async function convertToAnthropicMessagesPrompt({
1301
1365
  for (let k = 0; k < content.length; k++) {
1302
1366
  const part = content[k];
1303
1367
  const isLastContentPart = k === content.length - 1;
1304
- 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;
1305
1375
  switch (part.type) {
1306
1376
  case "text": {
1307
1377
  anthropicContent.push({
@@ -1325,17 +1395,23 @@ async function convertToAnthropicMessagesPrompt({
1325
1395
  });
1326
1396
  if (reasoningMetadata != null) {
1327
1397
  if (reasoningMetadata.signature != null) {
1398
+ validator.getCacheControl(part.providerOptions, {
1399
+ type: "thinking block",
1400
+ canCache: false
1401
+ });
1328
1402
  anthropicContent.push({
1329
1403
  type: "thinking",
1330
1404
  thinking: part.text,
1331
- signature: reasoningMetadata.signature,
1332
- cache_control: cacheControl
1405
+ signature: reasoningMetadata.signature
1333
1406
  });
1334
1407
  } else if (reasoningMetadata.redactedData != null) {
1408
+ validator.getCacheControl(part.providerOptions, {
1409
+ type: "redacted thinking block",
1410
+ canCache: false
1411
+ });
1335
1412
  anthropicContent.push({
1336
1413
  type: "redacted_thinking",
1337
- data: reasoningMetadata.redactedData,
1338
- cache_control: cacheControl
1414
+ data: reasoningMetadata.redactedData
1339
1415
  });
1340
1416
  } else {
1341
1417
  warnings.push({
@@ -1710,10 +1786,12 @@ var AnthropicMessagesLanguageModel = class {
1710
1786
  providerOptions,
1711
1787
  schema: anthropicProviderOptions
1712
1788
  });
1789
+ const cacheControlValidator = new CacheControlValidator();
1713
1790
  const { prompt: messagesPrompt, betas } = await convertToAnthropicMessagesPrompt({
1714
1791
  prompt,
1715
1792
  sendReasoning: (_a = anthropicOptions == null ? void 0 : anthropicOptions.sendReasoning) != null ? _a : true,
1716
- warnings
1793
+ warnings,
1794
+ cacheControlValidator
1717
1795
  });
1718
1796
  const isThinking = ((_b = anthropicOptions == null ? void 0 : anthropicOptions.thinking) == null ? void 0 : _b.type) === "enabled";
1719
1797
  const thinkingBudget = (_c = anthropicOptions == null ? void 0 : anthropicOptions.thinking) == null ? void 0 : _c.budgetTokens;
@@ -1811,20 +1889,23 @@ var AnthropicMessagesLanguageModel = class {
1811
1889
  jsonResponseTool != null ? {
1812
1890
  tools: [jsonResponseTool],
1813
1891
  toolChoice: { type: "tool", toolName: jsonResponseTool.name },
1814
- disableParallelToolUse: true
1892
+ disableParallelToolUse: true,
1893
+ cacheControlValidator
1815
1894
  } : {
1816
1895
  tools: tools != null ? tools : [],
1817
1896
  toolChoice,
1818
- disableParallelToolUse: anthropicOptions == null ? void 0 : anthropicOptions.disableParallelToolUse
1897
+ disableParallelToolUse: anthropicOptions == null ? void 0 : anthropicOptions.disableParallelToolUse,
1898
+ cacheControlValidator
1819
1899
  }
1820
1900
  );
1901
+ const cacheWarnings = cacheControlValidator.getWarnings();
1821
1902
  return {
1822
1903
  args: {
1823
1904
  ...baseArgs,
1824
1905
  tools: anthropicTools2,
1825
1906
  tool_choice: anthropicToolChoice
1826
1907
  },
1827
- warnings: [...warnings, ...toolWarnings],
1908
+ warnings: [...warnings, ...toolWarnings, ...cacheWarnings],
1828
1909
  betas: /* @__PURE__ */ new Set([...betas, ...toolsBetas]),
1829
1910
  usesJsonResponseTool: jsonResponseTool != null
1830
1911
  };