@ai-sdk/anthropic 3.0.136 → 3.0.137

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/dist/index.mjs CHANGED
@@ -12,7 +12,7 @@ import {
12
12
  } from "@ai-sdk/provider-utils";
13
13
 
14
14
  // src/version.ts
15
- var VERSION = true ? "3.0.136" : "0.0.0-test";
15
+ var VERSION = true ? "3.0.137" : "0.0.0-test";
16
16
 
17
17
  // src/anthropic-messages-language-model.ts
18
18
  import {
@@ -3644,9 +3644,8 @@ function sanitizeDefinition(definition) {
3644
3644
  }
3645
3645
  function sanitizeSchema(schema) {
3646
3646
  const result = {};
3647
- const schemaWithDefs = schema;
3648
3647
  if (schema.$ref != null) {
3649
- return { $ref: schema.$ref };
3648
+ return { $ref: schema.$ref, ...sanitizeSchemaDefinitions(schema) };
3650
3649
  }
3651
3650
  if (schema.$schema != null) {
3652
3651
  result.$schema = schema.$schema;
@@ -3680,23 +3679,7 @@ function sanitizeSchema(schema) {
3680
3679
  if (schema.allOf != null) {
3681
3680
  result.allOf = schema.allOf.map(sanitizeDefinition);
3682
3681
  }
3683
- if (schema.definitions != null) {
3684
- result.definitions = Object.fromEntries(
3685
- Object.entries(schema.definitions).map(([name, definition]) => [
3686
- name,
3687
- sanitizeDefinition(definition)
3688
- ])
3689
- );
3690
- }
3691
- if (schemaWithDefs.$defs != null) {
3692
- const resultWithDefs = result;
3693
- resultWithDefs.$defs = Object.fromEntries(
3694
- Object.entries(schemaWithDefs.$defs).map(([name, definition]) => [
3695
- name,
3696
- sanitizeDefinition(definition)
3697
- ])
3698
- );
3699
- }
3682
+ Object.assign(result, sanitizeSchemaDefinitions(schema));
3700
3683
  if (schema.type === "object" || schema.properties != null) {
3701
3684
  if (schema.properties != null) {
3702
3685
  result.properties = Object.fromEntries(
@@ -3724,6 +3707,21 @@ ${constraintDescription}`;
3724
3707
  }
3725
3708
  return result;
3726
3709
  }
3710
+ function sanitizeSchemaDefinitions(schema) {
3711
+ const { $defs } = schema;
3712
+ const sanitizeAll = (definitions) => Object.fromEntries(
3713
+ Object.entries(definitions).map(([name, definition]) => [
3714
+ name,
3715
+ sanitizeDefinition(definition)
3716
+ ])
3717
+ );
3718
+ return {
3719
+ ...schema.definitions != null && {
3720
+ definitions: sanitizeAll(schema.definitions)
3721
+ },
3722
+ ...$defs != null && { $defs: sanitizeAll($defs) }
3723
+ };
3724
+ }
3727
3725
  function getConstraintDescription(schema) {
3728
3726
  const descriptions = DESCRIPTION_CONSTRAINT_KEYS.flatMap((key) => {
3729
3727
  const value = schema[key];
@@ -3750,6 +3748,187 @@ function isPlainObject(value) {
3750
3748
  return typeof value === "object" && value !== null && !Array.isArray(value);
3751
3749
  }
3752
3750
 
3751
+ // src/has-circular-schema-reference.ts
3752
+ var SCHEMA_MAP_KEYWORDS = /* @__PURE__ */ new Set([
3753
+ "dependentSchemas",
3754
+ "patternProperties",
3755
+ "properties"
3756
+ ]);
3757
+ var DATA_KEYWORDS = /* @__PURE__ */ new Set(["const", "default", "enum", "examples"]);
3758
+ function hasCircularSchemaReference(schema) {
3759
+ const visiting = /* @__PURE__ */ new Set();
3760
+ const visited = /* @__PURE__ */ new Set();
3761
+ const visit = (pointer) => {
3762
+ if (visiting.has(pointer)) {
3763
+ return true;
3764
+ }
3765
+ if (visited.has(pointer)) {
3766
+ return false;
3767
+ }
3768
+ const target = resolveSchemaPointer(schema, pointer);
3769
+ if (target === void 0) {
3770
+ return false;
3771
+ }
3772
+ visiting.add(pointer);
3773
+ const isCircular = collectLocalRefs(target).some(visit);
3774
+ visiting.delete(pointer);
3775
+ visited.add(pointer);
3776
+ return isCircular;
3777
+ };
3778
+ return visit("#");
3779
+ }
3780
+ function collectLocalRefs(node, refs = []) {
3781
+ if (Array.isArray(node)) {
3782
+ for (const item of node) {
3783
+ collectLocalRefs(item, refs);
3784
+ }
3785
+ return refs;
3786
+ }
3787
+ if (!isRecord(node)) {
3788
+ return refs;
3789
+ }
3790
+ for (const [key, value] of Object.entries(node)) {
3791
+ if (key === "$ref") {
3792
+ if (typeof value === "string" && value.startsWith("#")) {
3793
+ refs.push(value);
3794
+ }
3795
+ } else if (SCHEMA_MAP_KEYWORDS.has(key) && isRecord(value)) {
3796
+ for (const subschema of Object.values(value)) {
3797
+ collectLocalRefs(subschema, refs);
3798
+ }
3799
+ } else if (
3800
+ // definitions are only reached through a `$ref`:
3801
+ key !== "$defs" && key !== "definitions" && !DATA_KEYWORDS.has(key)
3802
+ ) {
3803
+ collectLocalRefs(value, refs);
3804
+ }
3805
+ }
3806
+ return refs;
3807
+ }
3808
+ function resolveSchemaPointer(schema, pointer) {
3809
+ if (pointer === "#") {
3810
+ return schema;
3811
+ }
3812
+ if (!pointer.startsWith("#/")) {
3813
+ return void 0;
3814
+ }
3815
+ let decodedPointer;
3816
+ try {
3817
+ decodedPointer = decodeURIComponent(pointer.slice(2));
3818
+ } catch (e) {
3819
+ return void 0;
3820
+ }
3821
+ let current = schema;
3822
+ for (const rawSegment of decodedPointer.split("/")) {
3823
+ const segment = rawSegment.replace(/~1/g, "/").replace(/~0/g, "~");
3824
+ if (Array.isArray(current)) {
3825
+ current = current[Number(segment)];
3826
+ } else if (isRecord(current)) {
3827
+ current = current[segment];
3828
+ } else {
3829
+ return void 0;
3830
+ }
3831
+ }
3832
+ return current;
3833
+ }
3834
+ function isRecord(value) {
3835
+ return typeof value === "object" && value !== null && !Array.isArray(value);
3836
+ }
3837
+
3838
+ // src/supports-native-structured-output-schema.ts
3839
+ var MAX_OPTIONAL_PROPERTIES = 10;
3840
+ var SUBSCHEMA_KEYWORDS = [
3841
+ "additionalProperties",
3842
+ "contains",
3843
+ "else",
3844
+ "if",
3845
+ "items",
3846
+ "not",
3847
+ "then"
3848
+ ];
3849
+ var SUBSCHEMA_LIST_KEYWORDS = ["allOf", "anyOf", "oneOf", "prefixItems"];
3850
+ var SUBSCHEMA_MAP_KEYWORDS = [
3851
+ "dependentSchemas",
3852
+ "patternProperties",
3853
+ "properties"
3854
+ ];
3855
+ function supportsNativeStructuredOutputSchema(schema) {
3856
+ if (hasCircularSchemaReference(schema)) {
3857
+ return false;
3858
+ }
3859
+ const { optionalProperties, hasOpenObject } = getSchemaStats(
3860
+ schema,
3861
+ schema,
3862
+ /* @__PURE__ */ new Map()
3863
+ );
3864
+ return !hasOpenObject && optionalProperties <= MAX_OPTIONAL_PROPERTIES;
3865
+ }
3866
+ function getSchemaStats(node, root, refStats) {
3867
+ const stats = { optionalProperties: 0, hasOpenObject: false };
3868
+ if (!isRecord(node)) {
3869
+ return stats;
3870
+ }
3871
+ const add = (child) => {
3872
+ const childStats = getSchemaStats(child, root, refStats);
3873
+ stats.optionalProperties += childStats.optionalProperties;
3874
+ stats.hasOpenObject || (stats.hasOpenObject = childStats.hasOpenObject);
3875
+ };
3876
+ if (typeof node.$ref === "string" && node.$ref.startsWith("#")) {
3877
+ let resolved = refStats.get(node.$ref);
3878
+ if (resolved == null) {
3879
+ resolved = getSchemaStats(
3880
+ resolveSchemaPointer(root, node.$ref),
3881
+ root,
3882
+ refStats
3883
+ );
3884
+ refStats.set(node.$ref, resolved);
3885
+ }
3886
+ stats.optionalProperties += resolved.optionalProperties;
3887
+ stats.hasOpenObject || (stats.hasOpenObject = resolved.hasOpenObject);
3888
+ }
3889
+ if (isOpenObject(node)) {
3890
+ stats.hasOpenObject = true;
3891
+ }
3892
+ if (isRecord(node.properties)) {
3893
+ const required = new Set(Array.isArray(node.required) ? node.required : []);
3894
+ stats.optionalProperties += Object.keys(node.properties).filter(
3895
+ (name) => !required.has(name)
3896
+ ).length;
3897
+ }
3898
+ for (const keyword of SUBSCHEMA_KEYWORDS) {
3899
+ const value = node[keyword];
3900
+ if (Array.isArray(value)) {
3901
+ value.forEach(add);
3902
+ } else {
3903
+ add(value);
3904
+ }
3905
+ }
3906
+ for (const keyword of SUBSCHEMA_LIST_KEYWORDS) {
3907
+ const value = node[keyword];
3908
+ if (Array.isArray(value)) {
3909
+ value.forEach(add);
3910
+ }
3911
+ }
3912
+ for (const keyword of SUBSCHEMA_MAP_KEYWORDS) {
3913
+ const value = node[keyword];
3914
+ if (isRecord(value)) {
3915
+ Object.values(value).forEach(add);
3916
+ }
3917
+ }
3918
+ return stats;
3919
+ }
3920
+ function isOpenObject(node) {
3921
+ const { additionalProperties, patternProperties, properties, type } = node;
3922
+ if (additionalProperties === true || isRecord(additionalProperties)) {
3923
+ return true;
3924
+ }
3925
+ if (isRecord(patternProperties) && Object.keys(patternProperties).length > 0) {
3926
+ return true;
3927
+ }
3928
+ const isObjectType = type === "object" || Array.isArray(type) && type.includes("object");
3929
+ return isObjectType && properties == null && additionalProperties !== false;
3930
+ }
3931
+
3753
3932
  // src/anthropic-messages-language-model.ts
3754
3933
  function createCitationSource(citation, citationDocuments, generateId3) {
3755
3934
  var _a;
@@ -3823,6 +4002,31 @@ function toToolsetMemberInput({
3823
4002
  ...typeof input === "object" && input !== null && !Array.isArray(input) ? input : {}
3824
4003
  };
3825
4004
  }
4005
+ var TEXT_OR_THINKING_BLOCK_TYPES = /* @__PURE__ */ new Set([
4006
+ "redacted_thinking",
4007
+ "text",
4008
+ "thinking"
4009
+ ]);
4010
+ function isContinuationStopReason(stopReason) {
4011
+ return stopReason === "pause_turn" || stopReason === "tool_use";
4012
+ }
4013
+ function getJsonResponseToolFallbackText(content, stopReason) {
4014
+ const text = /* @__PURE__ */ new Set();
4015
+ if (isContinuationStopReason(stopReason)) {
4016
+ return text;
4017
+ }
4018
+ for (const part of content) {
4019
+ if (part.type === "tool_use" && part.name === "json") {
4020
+ return /* @__PURE__ */ new Set();
4021
+ }
4022
+ if (part.type === "text") {
4023
+ text.add(part);
4024
+ } else if (!TEXT_OR_THINKING_BLOCK_TYPES.has(part.type)) {
4025
+ text.clear();
4026
+ }
4027
+ }
4028
+ return text;
4029
+ }
3826
4030
  var AnthropicMessagesLanguageModel = class {
3827
4031
  constructor(modelId, config) {
3828
4032
  this.specificationVersion = "v3";
@@ -3970,7 +4174,7 @@ var AnthropicMessagesLanguageModel = class {
3970
4174
  const supportsStrictTools = ((_c = this.config.supportsStrictTools) != null ? _c : true) && modelSupportsStructuredOutput;
3971
4175
  const structureOutputMode = (_d = anthropicOptions == null ? void 0 : anthropicOptions.structuredOutputMode) != null ? _d : "auto";
3972
4176
  let useStructuredOutput = structureOutputMode === "outputFormat" || structureOutputMode === "auto" && supportsStructuredOutput;
3973
- if (!useStructuredOutput && rejectsForcedToolUse && supportsStructuredOutput && (responseFormat == null ? void 0 : responseFormat.type) === "json" && responseFormat.schema != null) {
4177
+ if (!useStructuredOutput && rejectsForcedToolUse && modelSupportsStructuredOutput && (responseFormat == null ? void 0 : responseFormat.type) === "json" && responseFormat.schema != null && supportsNativeStructuredOutputSchema(responseFormat.schema)) {
3974
4178
  warnings.push({
3975
4179
  type: "unsupported",
3976
4180
  feature: "providerOptions.anthropic.structuredOutputMode",
@@ -4476,10 +4680,11 @@ var AnthropicMessagesLanguageModel = class {
4476
4680
  const mcpToolCalls = {};
4477
4681
  const serverToolCalls = {};
4478
4682
  let isJsonResponseFromTool = false;
4683
+ const jsonResponseToolFallbackText = usesJsonResponseTool ? getJsonResponseToolFallbackText(response.content, response.stop_reason) : void 0;
4479
4684
  for (const part of response.content) {
4480
4685
  switch (part.type) {
4481
4686
  case "text": {
4482
- if (!usesJsonResponseTool) {
4687
+ if (jsonResponseToolFallbackText == null || jsonResponseToolFallbackText.has(part)) {
4483
4688
  const webSearchCitations = (_a = part.citations) == null ? void 0 : _a.filter(
4484
4689
  (citation) => citation.type === "web_search_result_location"
4485
4690
  );
@@ -5015,6 +5220,15 @@ var AnthropicMessagesLanguageModel = class {
5015
5220
  let safeguardResults;
5016
5221
  let container = null;
5017
5222
  let isJsonResponseFromTool = false;
5223
+ const heldBackText = [];
5224
+ const heldBackTextByIndex = /* @__PURE__ */ new Map();
5225
+ const createTextEnd = (id, citations) => ({
5226
+ type: "text-end",
5227
+ id,
5228
+ ...citations.length > 0 && {
5229
+ providerMetadata: { anthropic: { citations } }
5230
+ }
5231
+ });
5018
5232
  let isMessageOpen = false;
5019
5233
  let activeMessageId;
5020
5234
  let hasInvalidMessageSequence = false;
@@ -5026,7 +5240,7 @@ var AnthropicMessagesLanguageModel = class {
5026
5240
  controller.enqueue({ type: "stream-start", warnings });
5027
5241
  },
5028
5242
  transform(chunk, controller) {
5029
- var _a2, _b2, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n;
5243
+ var _a2, _b2, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o;
5030
5244
  if (hasInvalidMessageSequence) {
5031
5245
  return;
5032
5246
  }
@@ -5049,9 +5263,19 @@ var AnthropicMessagesLanguageModel = class {
5049
5263
  return;
5050
5264
  }
5051
5265
  blockType = contentBlockType;
5266
+ if (!TEXT_OR_THINKING_BLOCK_TYPES.has(contentBlockType)) {
5267
+ heldBackText.length = 0;
5268
+ }
5052
5269
  switch (contentBlockType) {
5053
5270
  case "text": {
5054
5271
  if (usesJsonResponseTool) {
5272
+ const entry = {
5273
+ id: String(value.index),
5274
+ text: "",
5275
+ citations: []
5276
+ };
5277
+ heldBackText.push(entry);
5278
+ heldBackTextByIndex.set(value.index, entry);
5055
5279
  return;
5056
5280
  }
5057
5281
  contentBlocks[value.index] = {
@@ -5506,17 +5730,12 @@ var AnthropicMessagesLanguageModel = class {
5506
5730
  const contentBlock = contentBlocks[value.index];
5507
5731
  switch (contentBlock.type) {
5508
5732
  case "text": {
5509
- controller.enqueue({
5510
- type: "text-end",
5511
- id: String(value.index),
5512
- ...contentBlock.citations.length > 0 && {
5513
- providerMetadata: {
5514
- anthropic: {
5515
- citations: contentBlock.citations
5516
- }
5517
- }
5518
- }
5519
- });
5733
+ controller.enqueue(
5734
+ createTextEnd(
5735
+ String(value.index),
5736
+ contentBlock.citations
5737
+ )
5738
+ );
5520
5739
  break;
5521
5740
  }
5522
5741
  case "reasoning": {
@@ -5602,6 +5821,10 @@ var AnthropicMessagesLanguageModel = class {
5602
5821
  switch (deltaType) {
5603
5822
  case "text_delta": {
5604
5823
  if (usesJsonResponseTool) {
5824
+ const entry = heldBackTextByIndex.get(value.index);
5825
+ if (entry != null) {
5826
+ entry.text += value.delta.text;
5827
+ }
5605
5828
  return;
5606
5829
  }
5607
5830
  controller.enqueue({
@@ -5683,8 +5906,11 @@ var AnthropicMessagesLanguageModel = class {
5683
5906
  case "citations_delta": {
5684
5907
  const citation = value.delta.citation;
5685
5908
  const contentBlock = contentBlocks[value.index];
5686
- if ((contentBlock == null ? void 0 : contentBlock.type) === "text" && citation.type === "web_search_result_location") {
5687
- contentBlock.citations.push(citation);
5909
+ if (citation.type === "web_search_result_location") {
5910
+ if ((contentBlock == null ? void 0 : contentBlock.type) === "text") {
5911
+ contentBlock.citations.push(citation);
5912
+ }
5913
+ (_e = heldBackTextByIndex.get(value.index)) == null ? void 0 : _e.citations.push(citation);
5688
5914
  }
5689
5915
  const source = createCitationSource(
5690
5916
  citation,
@@ -5721,13 +5947,14 @@ var AnthropicMessagesLanguageModel = class {
5721
5947
  }
5722
5948
  isMessageOpen = true;
5723
5949
  activeMessageId = value.message.id;
5950
+ heldBackTextByIndex.clear();
5724
5951
  usage.input_tokens = value.message.usage.input_tokens;
5725
- usage.cache_read_input_tokens = (_e = value.message.usage.cache_read_input_tokens) != null ? _e : 0;
5726
- usage.cache_creation_input_tokens = (_f = value.message.usage.cache_creation_input_tokens) != null ? _f : 0;
5952
+ usage.cache_read_input_tokens = (_f = value.message.usage.cache_read_input_tokens) != null ? _f : 0;
5953
+ usage.cache_creation_input_tokens = (_g = value.message.usage.cache_creation_input_tokens) != null ? _g : 0;
5727
5954
  rawUsage = {
5728
5955
  ...value.message.usage
5729
5956
  };
5730
- cacheCreationInputTokens = (_g = value.message.usage.cache_creation_input_tokens) != null ? _g : null;
5957
+ cacheCreationInputTokens = (_h = value.message.usage.cache_creation_input_tokens) != null ? _h : null;
5731
5958
  if (value.message.input_transformations != null) {
5732
5959
  inputTransformations = value.message.input_transformations;
5733
5960
  }
@@ -5749,8 +5976,8 @@ var AnthropicMessagesLanguageModel = class {
5749
5976
  }
5750
5977
  controller.enqueue({
5751
5978
  type: "response-metadata",
5752
- id: (_h = value.message.id) != null ? _h : void 0,
5753
- modelId: (_i = value.message.model) != null ? _i : void 0
5979
+ id: (_i = value.message.id) != null ? _i : void 0,
5980
+ modelId: (_j = value.message.model) != null ? _j : void 0
5754
5981
  });
5755
5982
  if (value.message.content != null) {
5756
5983
  for (let contentIndex = 0; contentIndex < value.message.content.length; contentIndex++) {
@@ -5762,7 +5989,7 @@ var AnthropicMessagesLanguageModel = class {
5762
5989
  id: part.id,
5763
5990
  toolName: part.name
5764
5991
  });
5765
- const inputStr = JSON.stringify((_j = part.input) != null ? _j : {});
5992
+ const inputStr = JSON.stringify((_k = part.input) != null ? _k : {});
5766
5993
  controller.enqueue({
5767
5994
  type: "tool-input-delta",
5768
5995
  id: part.id,
@@ -5813,18 +6040,18 @@ var AnthropicMessagesLanguageModel = class {
5813
6040
  finishReason: value.delta.stop_reason,
5814
6041
  isJsonResponseFromTool
5815
6042
  }),
5816
- raw: (_k = value.delta.stop_reason) != null ? _k : void 0
6043
+ raw: (_l = value.delta.stop_reason) != null ? _l : void 0
5817
6044
  };
5818
- stopSequence = (_l = value.delta.stop_sequence) != null ? _l : null;
6045
+ stopSequence = (_m = value.delta.stop_sequence) != null ? _m : null;
5819
6046
  stopDetails = mapAnthropicStopDetails(value.delta.stop_details);
5820
6047
  container = value.delta.container != null ? {
5821
6048
  expiresAt: value.delta.container.expires_at,
5822
6049
  id: value.delta.container.id,
5823
- skills: (_n = (_m = value.delta.container.skills) == null ? void 0 : _m.map((skill) => ({
6050
+ skills: (_o = (_n = value.delta.container.skills) == null ? void 0 : _n.map((skill) => ({
5824
6051
  type: skill.type,
5825
6052
  skillId: skill.skill_id,
5826
6053
  version: skill.version
5827
- }))) != null ? _n : null
6054
+ }))) != null ? _o : null
5828
6055
  } : null;
5829
6056
  if (value.context_management) {
5830
6057
  contextManagement = mapAnthropicResponseContextManagement(
@@ -5876,6 +6103,15 @@ var AnthropicMessagesLanguageModel = class {
5876
6103
  if (usedCustomProviderKey && providerOptionsName !== "anthropic") {
5877
6104
  providerMetadata[providerOptionsName] = anthropicMetadata;
5878
6105
  }
6106
+ if (!isJsonResponseFromTool && !isContinuationStopReason(finishReason.raw)) {
6107
+ for (const { id, text, citations } of heldBackText) {
6108
+ if (text.length === 0) continue;
6109
+ controller.enqueue({ type: "text-start", id });
6110
+ controller.enqueue({ type: "text-delta", id, delta: text });
6111
+ controller.enqueue(createTextEnd(id, citations));
6112
+ }
6113
+ }
6114
+ heldBackText.length = 0;
5879
6115
  controller.enqueue({
5880
6116
  type: "finish",
5881
6117
  finishReason,