@ai-sdk/anthropic 3.0.0-beta.30 → 3.0.0-beta.31

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
+ ## 3.0.0-beta.31
4
+
5
+ ### Patch Changes
6
+
7
+ - ca07285: feat(anthropic): add prompt caching validation
8
+
3
9
  ## 3.0.0-beta.30
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 ? "3.0.0-beta.30" : "0.0.0-test";
34
+ var VERSION = true ? "3.0.0-beta.31" : "0.0.0-test";
35
35
 
36
36
  // src/anthropic-messages-language-model.ts
37
37
  var import_provider3 = require("@ai-sdk/provider");
@@ -613,12 +613,46 @@ var anthropicProviderOptions = import_v43.z.object({
613
613
  var import_provider = require("@ai-sdk/provider");
614
614
 
615
615
  // src/get-cache-control.ts
616
+ var MAX_CACHE_BREAKPOINTS = 4;
616
617
  function getCacheControl(providerMetadata) {
617
618
  var _a;
618
619
  const anthropic2 = providerMetadata == null ? void 0 : providerMetadata.anthropic;
619
620
  const cacheControlValue = (_a = anthropic2 == null ? void 0 : anthropic2.cacheControl) != null ? _a : anthropic2 == null ? void 0 : anthropic2.cache_control;
620
621
  return cacheControlValue;
621
622
  }
623
+ var CacheControlValidator = class {
624
+ constructor() {
625
+ this.breakpointCount = 0;
626
+ this.warnings = [];
627
+ }
628
+ getCacheControl(providerMetadata, context) {
629
+ const cacheControlValue = getCacheControl(providerMetadata);
630
+ if (!cacheControlValue) {
631
+ return void 0;
632
+ }
633
+ if (!context.canCache) {
634
+ this.warnings.push({
635
+ type: "unsupported-setting",
636
+ setting: "cacheControl",
637
+ details: `cache_control cannot be set on ${context.type}. It will be ignored.`
638
+ });
639
+ return void 0;
640
+ }
641
+ this.breakpointCount++;
642
+ if (this.breakpointCount > MAX_CACHE_BREAKPOINTS) {
643
+ this.warnings.push({
644
+ type: "unsupported-setting",
645
+ setting: "cacheControl",
646
+ details: `Maximum ${MAX_CACHE_BREAKPOINTS} cache breakpoints exceeded (found ${this.breakpointCount}). This breakpoint will be ignored.`
647
+ });
648
+ return void 0;
649
+ }
650
+ return cacheControlValue;
651
+ }
652
+ getWarnings() {
653
+ return this.warnings;
654
+ }
655
+ };
622
656
 
623
657
  // src/tool/text-editor_20250728.ts
624
658
  var import_provider_utils3 = require("@ai-sdk/provider-utils");
@@ -764,11 +798,13 @@ var import_provider_utils7 = require("@ai-sdk/provider-utils");
764
798
  async function prepareTools({
765
799
  tools,
766
800
  toolChoice,
767
- disableParallelToolUse
801
+ disableParallelToolUse,
802
+ cacheControlValidator
768
803
  }) {
769
804
  tools = (tools == null ? void 0 : tools.length) ? tools : void 0;
770
805
  const toolWarnings = [];
771
806
  const betas = /* @__PURE__ */ new Set();
807
+ const validator = cacheControlValidator || new CacheControlValidator();
772
808
  if (tools == null) {
773
809
  return { tools: void 0, toolChoice: void 0, toolWarnings, betas };
774
810
  }
@@ -776,7 +812,10 @@ async function prepareTools({
776
812
  for (const tool of tools) {
777
813
  switch (tool.type) {
778
814
  case "function": {
779
- const cacheControl = getCacheControl(tool.providerOptions);
815
+ const cacheControl = validator.getCacheControl(tool.providerOptions, {
816
+ type: "tool definition",
817
+ canCache: true
818
+ });
780
819
  anthropicTools2.push({
781
820
  name: tool.name,
782
821
  description: tool.description,
@@ -791,7 +830,8 @@ async function prepareTools({
791
830
  betas.add("code-execution-2025-05-22");
792
831
  anthropicTools2.push({
793
832
  type: "code_execution_20250522",
794
- name: "code_execution"
833
+ name: "code_execution",
834
+ cache_control: void 0
795
835
  });
796
836
  break;
797
837
  }
@@ -810,7 +850,8 @@ async function prepareTools({
810
850
  type: "computer_20250124",
811
851
  display_width_px: tool.args.displayWidthPx,
812
852
  display_height_px: tool.args.displayHeightPx,
813
- display_number: tool.args.displayNumber
853
+ display_number: tool.args.displayNumber,
854
+ cache_control: void 0
814
855
  });
815
856
  break;
816
857
  }
@@ -821,7 +862,8 @@ async function prepareTools({
821
862
  type: "computer_20241022",
822
863
  display_width_px: tool.args.displayWidthPx,
823
864
  display_height_px: tool.args.displayHeightPx,
824
- display_number: tool.args.displayNumber
865
+ display_number: tool.args.displayNumber,
866
+ cache_control: void 0
825
867
  });
826
868
  break;
827
869
  }
@@ -829,7 +871,8 @@ async function prepareTools({
829
871
  betas.add("computer-use-2025-01-24");
830
872
  anthropicTools2.push({
831
873
  name: "str_replace_editor",
832
- type: "text_editor_20250124"
874
+ type: "text_editor_20250124",
875
+ cache_control: void 0
833
876
  });
834
877
  break;
835
878
  }
@@ -837,7 +880,8 @@ async function prepareTools({
837
880
  betas.add("computer-use-2024-10-22");
838
881
  anthropicTools2.push({
839
882
  name: "str_replace_editor",
840
- type: "text_editor_20241022"
883
+ type: "text_editor_20241022",
884
+ cache_control: void 0
841
885
  });
842
886
  break;
843
887
  }
@@ -845,7 +889,8 @@ async function prepareTools({
845
889
  betas.add("computer-use-2025-01-24");
846
890
  anthropicTools2.push({
847
891
  name: "str_replace_based_edit_tool",
848
- type: "text_editor_20250429"
892
+ type: "text_editor_20250429",
893
+ cache_control: void 0
849
894
  });
850
895
  break;
851
896
  }
@@ -857,7 +902,8 @@ async function prepareTools({
857
902
  anthropicTools2.push({
858
903
  name: "str_replace_based_edit_tool",
859
904
  type: "text_editor_20250728",
860
- max_characters: args.maxCharacters
905
+ max_characters: args.maxCharacters,
906
+ cache_control: void 0
861
907
  });
862
908
  break;
863
909
  }
@@ -865,7 +911,8 @@ async function prepareTools({
865
911
  betas.add("computer-use-2025-01-24");
866
912
  anthropicTools2.push({
867
913
  name: "bash",
868
- type: "bash_20250124"
914
+ type: "bash_20250124",
915
+ cache_control: void 0
869
916
  });
870
917
  break;
871
918
  }
@@ -873,7 +920,8 @@ async function prepareTools({
873
920
  betas.add("computer-use-2024-10-22");
874
921
  anthropicTools2.push({
875
922
  name: "bash",
876
- type: "bash_20241022"
923
+ type: "bash_20241022",
924
+ cache_control: void 0
877
925
  });
878
926
  break;
879
927
  }
@@ -898,7 +946,8 @@ async function prepareTools({
898
946
  allowed_domains: args.allowedDomains,
899
947
  blocked_domains: args.blockedDomains,
900
948
  citations: args.citations,
901
- max_content_tokens: args.maxContentTokens
949
+ max_content_tokens: args.maxContentTokens,
950
+ cache_control: void 0
902
951
  });
903
952
  break;
904
953
  }
@@ -913,7 +962,8 @@ async function prepareTools({
913
962
  max_uses: args.maxUses,
914
963
  allowed_domains: args.allowedDomains,
915
964
  blocked_domains: args.blockedDomains,
916
- user_location: args.userLocation
965
+ user_location: args.userLocation,
966
+ cache_control: void 0
917
967
  });
918
968
  break;
919
969
  }
@@ -1125,11 +1175,13 @@ function convertToString(data) {
1125
1175
  async function convertToAnthropicMessagesPrompt({
1126
1176
  prompt,
1127
1177
  sendReasoning,
1128
- warnings
1178
+ warnings,
1179
+ cacheControlValidator
1129
1180
  }) {
1130
1181
  var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
1131
1182
  const betas = /* @__PURE__ */ new Set();
1132
1183
  const blocks = groupIntoBlocks(prompt);
1184
+ const validator = cacheControlValidator || new CacheControlValidator();
1133
1185
  let system = void 0;
1134
1186
  const messages = [];
1135
1187
  async function shouldEnableCitations(providerMetadata) {
@@ -1166,7 +1218,10 @@ async function convertToAnthropicMessagesPrompt({
1166
1218
  system = block.messages.map(({ content, providerOptions }) => ({
1167
1219
  type: "text",
1168
1220
  text: content,
1169
- cache_control: getCacheControl(providerOptions)
1221
+ cache_control: validator.getCacheControl(providerOptions, {
1222
+ type: "system message",
1223
+ canCache: true
1224
+ })
1170
1225
  }));
1171
1226
  break;
1172
1227
  }
@@ -1179,7 +1234,13 @@ async function convertToAnthropicMessagesPrompt({
1179
1234
  for (let j = 0; j < content.length; j++) {
1180
1235
  const part = content[j];
1181
1236
  const isLastPart = j === content.length - 1;
1182
- const cacheControl = (_a = getCacheControl(part.providerOptions)) != null ? _a : isLastPart ? getCacheControl(message.providerOptions) : void 0;
1237
+ const cacheControl = (_a = validator.getCacheControl(part.providerOptions, {
1238
+ type: "user message part",
1239
+ canCache: true
1240
+ })) != null ? _a : isLastPart ? validator.getCacheControl(message.providerOptions, {
1241
+ type: "user message",
1242
+ canCache: true
1243
+ }) : void 0;
1183
1244
  switch (part.type) {
1184
1245
  case "text": {
1185
1246
  anthropicContent.push({
@@ -1267,7 +1328,13 @@ async function convertToAnthropicMessagesPrompt({
1267
1328
  for (let i2 = 0; i2 < content.length; i2++) {
1268
1329
  const part = content[i2];
1269
1330
  const isLastPart = i2 === content.length - 1;
1270
- const cacheControl = (_d = getCacheControl(part.providerOptions)) != null ? _d : isLastPart ? getCacheControl(message.providerOptions) : void 0;
1331
+ const cacheControl = (_d = validator.getCacheControl(part.providerOptions, {
1332
+ type: "tool result part",
1333
+ canCache: true
1334
+ })) != null ? _d : isLastPart ? validator.getCacheControl(message.providerOptions, {
1335
+ type: "tool result message",
1336
+ canCache: true
1337
+ }) : void 0;
1271
1338
  const output = part.output;
1272
1339
  let contentValue;
1273
1340
  switch (output.type) {
@@ -1277,8 +1344,7 @@ async function convertToAnthropicMessagesPrompt({
1277
1344
  case "text":
1278
1345
  return {
1279
1346
  type: "text",
1280
- text: contentPart.text,
1281
- cache_control: cacheControl
1347
+ text: contentPart.text
1282
1348
  };
1283
1349
  case "image-data": {
1284
1350
  return {
@@ -1287,8 +1353,7 @@ async function convertToAnthropicMessagesPrompt({
1287
1353
  type: "base64",
1288
1354
  media_type: contentPart.mediaType,
1289
1355
  data: contentPart.data
1290
- },
1291
- cache_control: cacheControl
1356
+ }
1292
1357
  };
1293
1358
  }
1294
1359
  case "file-data": {
@@ -1300,8 +1365,7 @@ async function convertToAnthropicMessagesPrompt({
1300
1365
  type: "base64",
1301
1366
  media_type: contentPart.mediaType,
1302
1367
  data: contentPart.data
1303
- },
1304
- cache_control: cacheControl
1368
+ }
1305
1369
  };
1306
1370
  }
1307
1371
  warnings.push({
@@ -1362,7 +1426,13 @@ async function convertToAnthropicMessagesPrompt({
1362
1426
  for (let k = 0; k < content.length; k++) {
1363
1427
  const part = content[k];
1364
1428
  const isLastContentPart = k === content.length - 1;
1365
- const cacheControl = (_f = getCacheControl(part.providerOptions)) != null ? _f : isLastContentPart ? getCacheControl(message.providerOptions) : void 0;
1429
+ const cacheControl = (_f = validator.getCacheControl(part.providerOptions, {
1430
+ type: "assistant message part",
1431
+ canCache: true
1432
+ })) != null ? _f : isLastContentPart ? validator.getCacheControl(message.providerOptions, {
1433
+ type: "assistant message",
1434
+ canCache: true
1435
+ }) : void 0;
1366
1436
  switch (part.type) {
1367
1437
  case "text": {
1368
1438
  anthropicContent.push({
@@ -1386,17 +1456,23 @@ async function convertToAnthropicMessagesPrompt({
1386
1456
  });
1387
1457
  if (reasoningMetadata != null) {
1388
1458
  if (reasoningMetadata.signature != null) {
1459
+ validator.getCacheControl(part.providerOptions, {
1460
+ type: "thinking block",
1461
+ canCache: false
1462
+ });
1389
1463
  anthropicContent.push({
1390
1464
  type: "thinking",
1391
1465
  thinking: part.text,
1392
- signature: reasoningMetadata.signature,
1393
- cache_control: cacheControl
1466
+ signature: reasoningMetadata.signature
1394
1467
  });
1395
1468
  } else if (reasoningMetadata.redactedData != null) {
1469
+ validator.getCacheControl(part.providerOptions, {
1470
+ type: "redacted thinking block",
1471
+ canCache: false
1472
+ });
1396
1473
  anthropicContent.push({
1397
1474
  type: "redacted_thinking",
1398
- data: reasoningMetadata.redactedData,
1399
- cache_control: cacheControl
1475
+ data: reasoningMetadata.redactedData
1400
1476
  });
1401
1477
  } else {
1402
1478
  warnings.push({
@@ -1809,10 +1885,12 @@ var AnthropicMessagesLanguageModel = class {
1809
1885
  providerOptions,
1810
1886
  schema: anthropicProviderOptions
1811
1887
  });
1888
+ const cacheControlValidator = new CacheControlValidator();
1812
1889
  const { prompt: messagesPrompt, betas } = await convertToAnthropicMessagesPrompt({
1813
1890
  prompt,
1814
1891
  sendReasoning: (_a = anthropicOptions == null ? void 0 : anthropicOptions.sendReasoning) != null ? _a : true,
1815
- warnings
1892
+ warnings,
1893
+ cacheControlValidator
1816
1894
  });
1817
1895
  const isThinking = ((_b = anthropicOptions == null ? void 0 : anthropicOptions.thinking) == null ? void 0 : _b.type) === "enabled";
1818
1896
  const thinkingBudget = (_c = anthropicOptions == null ? void 0 : anthropicOptions.thinking) == null ? void 0 : _c.budgetTokens;
@@ -1926,20 +2004,23 @@ var AnthropicMessagesLanguageModel = class {
1926
2004
  jsonResponseTool != null ? {
1927
2005
  tools: [jsonResponseTool],
1928
2006
  toolChoice: { type: "tool", toolName: jsonResponseTool.name },
1929
- disableParallelToolUse: true
2007
+ disableParallelToolUse: true,
2008
+ cacheControlValidator
1930
2009
  } : {
1931
2010
  tools: tools != null ? tools : [],
1932
2011
  toolChoice,
1933
- disableParallelToolUse: anthropicOptions == null ? void 0 : anthropicOptions.disableParallelToolUse
2012
+ disableParallelToolUse: anthropicOptions == null ? void 0 : anthropicOptions.disableParallelToolUse,
2013
+ cacheControlValidator
1934
2014
  }
1935
2015
  );
2016
+ const cacheWarnings = cacheControlValidator.getWarnings();
1936
2017
  return {
1937
2018
  args: {
1938
2019
  ...baseArgs,
1939
2020
  tools: anthropicTools2,
1940
2021
  tool_choice: anthropicToolChoice
1941
2022
  },
1942
- warnings: [...warnings, ...toolWarnings],
2023
+ warnings: [...warnings, ...toolWarnings, ...cacheWarnings],
1943
2024
  betas: /* @__PURE__ */ new Set([...betas, ...toolsBetas]),
1944
2025
  usesJsonResponseTool: jsonResponseTool != null
1945
2026
  };