@langchain/anthropic 0.3.24 → 0.3.26

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.
@@ -44,7 +44,14 @@ function isAnthropicTool(tool) {
44
44
  return "input_schema" in tool;
45
45
  }
46
46
  function isBuiltinTool(tool) {
47
- const builtinTools = ["web_search"];
47
+ const builtinTools = [
48
+ "web_search",
49
+ "bash",
50
+ "code_execution",
51
+ "computer",
52
+ "str_replace_editor",
53
+ "str_replace_based_edit_tool",
54
+ ];
48
55
  return (typeof tool === "object" &&
49
56
  tool !== null &&
50
57
  "type" in tool &&
@@ -601,9 +608,20 @@ class ChatAnthropicMessages extends chat_models_1.BaseChatModel {
601
608
  this.modelName = fields?.model ?? fields?.modelName ?? this.model;
602
609
  this.model = this.modelName;
603
610
  this.invocationKwargs = fields?.invocationKwargs ?? {};
604
- this.temperature = fields?.temperature ?? this.temperature;
611
+ if (this.model.includes("opus-4-1")) {
612
+ // Default to `undefined` for `topP` for Opus 4.1 models
613
+ this.topP = fields?.topP === null ? undefined : fields?.topP;
614
+ }
615
+ else {
616
+ this.topP = fields?.topP ?? this.topP;
617
+ }
618
+ // If the user passes `null`, set it to `undefined`. Otherwise, use their value or the default. We have to check for null, because
619
+ // there's no way for us to know if they explicitly set it to `undefined`, or never passed a value
620
+ this.temperature =
621
+ fields?.temperature === null
622
+ ? undefined
623
+ : fields?.temperature ?? this.temperature;
605
624
  this.topK = fields?.topK ?? this.topK;
606
- this.topP = fields?.topP ?? this.topP;
607
625
  this.maxTokens =
608
626
  fields?.maxTokensToSample ?? fields?.maxTokens ?? this.maxTokens;
609
627
  this.stopSequences = fields?.stopSequences ?? this.stopSequences;
@@ -33,8 +33,10 @@ export interface AnthropicInput {
33
33
  * from 0 to 1. Use temp closer to 0 for analytical /
34
34
  * multiple choice, and temp closer to 1 for creative
35
35
  * and generative tasks.
36
+ * To not set this field, pass `null`. If `undefined` is passed,
37
+ * the default (1) will be used.
36
38
  */
37
- temperature?: number;
39
+ temperature?: number | null;
38
40
  /** Only sample from the top K options for each subsequent
39
41
  * token. Used to remove "long tail" low probability
40
42
  * responses. Defaults to -1, which disables it.
@@ -47,8 +49,13 @@ export interface AnthropicInput {
47
49
  * specified by top_p. Defaults to -1, which disables it.
48
50
  * Note that you should either alter temperature or top_p,
49
51
  * but not both.
52
+ *
53
+ * To not set this field, pass `null`. If `undefined` is passed,
54
+ * the default (-1) will be used.
55
+ *
56
+ * For Opus 4.1, this defaults to `null`.
50
57
  */
51
- topP?: number;
58
+ topP?: number | null;
52
59
  /** A maximum number of tokens to generate before stopping. */
53
60
  maxTokens?: number;
54
61
  /**
@@ -487,9 +494,9 @@ export declare class ChatAnthropicMessages<CallOptions extends ChatAnthropicCall
487
494
  anthropicApiKey?: string;
488
495
  apiKey?: string;
489
496
  apiUrl?: string;
490
- temperature: number;
497
+ temperature: number | undefined;
491
498
  topK: number;
492
- topP: number;
499
+ topP: number | undefined;
493
500
  maxTokens: number;
494
501
  modelName: string;
495
502
  model: string;
@@ -41,7 +41,14 @@ function isAnthropicTool(tool) {
41
41
  return "input_schema" in tool;
42
42
  }
43
43
  function isBuiltinTool(tool) {
44
- const builtinTools = ["web_search"];
44
+ const builtinTools = [
45
+ "web_search",
46
+ "bash",
47
+ "code_execution",
48
+ "computer",
49
+ "str_replace_editor",
50
+ "str_replace_based_edit_tool",
51
+ ];
45
52
  return (typeof tool === "object" &&
46
53
  tool !== null &&
47
54
  "type" in tool &&
@@ -598,9 +605,20 @@ export class ChatAnthropicMessages extends BaseChatModel {
598
605
  this.modelName = fields?.model ?? fields?.modelName ?? this.model;
599
606
  this.model = this.modelName;
600
607
  this.invocationKwargs = fields?.invocationKwargs ?? {};
601
- this.temperature = fields?.temperature ?? this.temperature;
608
+ if (this.model.includes("opus-4-1")) {
609
+ // Default to `undefined` for `topP` for Opus 4.1 models
610
+ this.topP = fields?.topP === null ? undefined : fields?.topP;
611
+ }
612
+ else {
613
+ this.topP = fields?.topP ?? this.topP;
614
+ }
615
+ // If the user passes `null`, set it to `undefined`. Otherwise, use their value or the default. We have to check for null, because
616
+ // there's no way for us to know if they explicitly set it to `undefined`, or never passed a value
617
+ this.temperature =
618
+ fields?.temperature === null
619
+ ? undefined
620
+ : fields?.temperature ?? this.temperature;
602
621
  this.topK = fields?.topK ?? this.topK;
603
- this.topP = fields?.topP ?? this.topP;
604
622
  this.maxTokens =
605
623
  fields?.maxTokensToSample ?? fields?.maxTokens ?? this.maxTokens;
606
624
  this.stopSequences = fields?.stopSequences ?? this.stopSequences;
@@ -101,16 +101,6 @@ function extractToolCalls(content) {
101
101
  type: "tool_call",
102
102
  });
103
103
  }
104
- else if (block.type === "server_tool_use" &&
105
- block.name === "web_search") {
106
- // Handle Anthropic built-in web search tool
107
- toolCalls.push({
108
- name: block.name,
109
- args: block.input,
110
- id: block.id,
111
- type: "tool_call",
112
- });
113
- }
114
104
  }
115
105
  return toolCalls;
116
106
  }
@@ -96,16 +96,6 @@ export function extractToolCalls(content) {
96
96
  type: "tool_call",
97
97
  });
98
98
  }
99
- else if (block.type === "server_tool_use" &&
100
- block.name === "web_search") {
101
- // Handle Anthropic built-in web search tool
102
- toolCalls.push({
103
- name: block.name,
104
- args: block.input,
105
- id: block.id,
106
- type: "tool_call",
107
- });
108
- }
109
99
  }
110
100
  return toolCalls;
111
101
  }
@@ -77,7 +77,7 @@ function _ensureMessageContents(messages) {
77
77
  type: "tool_result",
78
78
  // rare case: message.content could be undefined
79
79
  ...(message.content != null
80
- ? { content: _formatContent(message.content) }
80
+ ? { content: _formatContent(message) }
81
81
  : {}),
82
82
  tool_use_id: message.tool_call_id,
83
83
  },
@@ -284,7 +284,7 @@ const standardContentBlockConverter = {
284
284
  }
285
285
  },
286
286
  };
287
- function _formatContent(content) {
287
+ function _formatContent(message) {
288
288
  const toolTypes = [
289
289
  "tool_use",
290
290
  "tool_result",
@@ -294,6 +294,7 @@ function _formatContent(content) {
294
294
  "web_search_result",
295
295
  ];
296
296
  const textTypes = ["text", "text_delta"];
297
+ const { content } = message;
297
298
  if (typeof content === "string") {
298
299
  return content;
299
300
  }
@@ -400,6 +401,22 @@ function _formatContent(content) {
400
401
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
401
402
  };
402
403
  }
404
+ else if ("functionCall" in contentPart &&
405
+ contentPart.functionCall &&
406
+ typeof contentPart.functionCall === "object" &&
407
+ (0, messages_1.isAIMessage)(message)) {
408
+ const correspondingToolCall = message.tool_calls?.find((toolCall) => toolCall.name === contentPart.functionCall.name);
409
+ if (!correspondingToolCall) {
410
+ throw new Error(`Could not find tool call for function call ${contentPart.functionCall.name}`);
411
+ }
412
+ // Google GenAI models include a `functionCall` object inside content. We should ignore it as Anthropic will not support it.
413
+ return {
414
+ id: correspondingToolCall.id,
415
+ type: "tool_use",
416
+ name: correspondingToolCall.name,
417
+ input: contentPart.functionCall.args,
418
+ };
419
+ }
403
420
  else {
404
421
  throw new Error("Unsupported message content format");
405
422
  }
@@ -466,14 +483,14 @@ function _convertMessagesToAnthropicPayload(messages) {
466
483
  }
467
484
  return {
468
485
  role,
469
- content: _formatContent(message.content),
486
+ content: _formatContent(message),
470
487
  };
471
488
  }
472
489
  }
473
490
  else {
474
491
  return {
475
492
  role,
476
- content: _formatContent(message.content),
493
+ content: _formatContent(message),
477
494
  };
478
495
  }
479
496
  });
@@ -73,7 +73,7 @@ function _ensureMessageContents(messages) {
73
73
  type: "tool_result",
74
74
  // rare case: message.content could be undefined
75
75
  ...(message.content != null
76
- ? { content: _formatContent(message.content) }
76
+ ? { content: _formatContent(message) }
77
77
  : {}),
78
78
  tool_use_id: message.tool_call_id,
79
79
  },
@@ -280,7 +280,7 @@ const standardContentBlockConverter = {
280
280
  }
281
281
  },
282
282
  };
283
- function _formatContent(content) {
283
+ function _formatContent(message) {
284
284
  const toolTypes = [
285
285
  "tool_use",
286
286
  "tool_result",
@@ -290,6 +290,7 @@ function _formatContent(content) {
290
290
  "web_search_result",
291
291
  ];
292
292
  const textTypes = ["text", "text_delta"];
293
+ const { content } = message;
293
294
  if (typeof content === "string") {
294
295
  return content;
295
296
  }
@@ -396,6 +397,22 @@ function _formatContent(content) {
396
397
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
397
398
  };
398
399
  }
400
+ else if ("functionCall" in contentPart &&
401
+ contentPart.functionCall &&
402
+ typeof contentPart.functionCall === "object" &&
403
+ isAIMessage(message)) {
404
+ const correspondingToolCall = message.tool_calls?.find((toolCall) => toolCall.name === contentPart.functionCall.name);
405
+ if (!correspondingToolCall) {
406
+ throw new Error(`Could not find tool call for function call ${contentPart.functionCall.name}`);
407
+ }
408
+ // Google GenAI models include a `functionCall` object inside content. We should ignore it as Anthropic will not support it.
409
+ return {
410
+ id: correspondingToolCall.id,
411
+ type: "tool_use",
412
+ name: correspondingToolCall.name,
413
+ input: contentPart.functionCall.args,
414
+ };
415
+ }
399
416
  else {
400
417
  throw new Error("Unsupported message content format");
401
418
  }
@@ -462,14 +479,14 @@ export function _convertMessagesToAnthropicPayload(messages) {
462
479
  }
463
480
  return {
464
481
  role,
465
- content: _formatContent(message.content),
482
+ content: _formatContent(message),
466
483
  };
467
484
  }
468
485
  }
469
486
  else {
470
487
  return {
471
488
  role,
472
- content: _formatContent(message.content),
489
+ content: _formatContent(message),
473
490
  };
474
491
  }
475
492
  });
@@ -79,17 +79,6 @@ function _makeMessageChunkFromAnthropicEvent(data, fields) {
79
79
  },
80
80
  ];
81
81
  }
82
- else if (contentBlock.type === "server_tool_use") {
83
- // Handle anthropic built-in server tool use (like web search)
84
- toolCallChunks = [
85
- {
86
- id: contentBlock.id,
87
- index: data.index,
88
- name: contentBlock.name,
89
- args: "",
90
- },
91
- ];
92
- }
93
82
  else {
94
83
  toolCallChunks = [];
95
84
  }
@@ -75,17 +75,6 @@ export function _makeMessageChunkFromAnthropicEvent(data, fields) {
75
75
  },
76
76
  ];
77
77
  }
78
- else if (contentBlock.type === "server_tool_use") {
79
- // Handle anthropic built-in server tool use (like web search)
80
- toolCallChunks = [
81
- {
82
- id: contentBlock.id,
83
- index: data.index,
84
- name: contentBlock.name,
85
- args: "",
86
- },
87
- ];
88
- }
89
78
  else {
90
79
  toolCallChunks = [];
91
80
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@langchain/anthropic",
3
- "version": "0.3.24",
3
+ "version": "0.3.26",
4
4
  "description": "Anthropic integrations for LangChain.js",
5
5
  "type": "module",
6
6
  "engines": {