@langchain/anthropic 0.3.13 → 0.3.14

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.
@@ -36,6 +36,9 @@ function _documentsInParams(params) {
36
36
  }
37
37
  return false;
38
38
  }
39
+ function _thinkingInParams(params) {
40
+ return !!(params.thinking && params.thinking.type === "enabled");
41
+ }
39
42
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
40
43
  function isAnthropicTool(tool) {
41
44
  return "input_schema" in tool;
@@ -536,6 +539,12 @@ class ChatAnthropicMessages extends chat_models_1.BaseChatModel {
536
539
  writable: true,
537
540
  value: void 0
538
541
  });
542
+ Object.defineProperty(this, "thinking", {
543
+ enumerable: true,
544
+ configurable: true,
545
+ writable: true,
546
+ value: { type: "disabled" }
547
+ });
539
548
  // Used for non-streaming requests
540
549
  Object.defineProperty(this, "batchClient", {
541
550
  enumerable: true,
@@ -591,6 +600,7 @@ class ChatAnthropicMessages extends chat_models_1.BaseChatModel {
591
600
  this.stopSequences = fields?.stopSequences ?? this.stopSequences;
592
601
  this.streaming = fields?.streaming ?? false;
593
602
  this.streamUsage = fields?.streamUsage ?? this.streamUsage;
603
+ this.thinking = fields?.thinking ?? this.thinking;
594
604
  this.createClient =
595
605
  fields?.createClient ??
596
606
  ((options) => new sdk_1.Anthropic(options));
@@ -649,6 +659,27 @@ class ChatAnthropicMessages extends chat_models_1.BaseChatModel {
649
659
  */
650
660
  invocationParams(options) {
651
661
  const tool_choice = (0, tools_js_1.handleToolChoice)(options?.tool_choice);
662
+ if (this.thinking.type === "enabled") {
663
+ if (this.topK !== -1) {
664
+ throw new Error("topK is not supported when thinking is enabled");
665
+ }
666
+ if (this.topP !== -1) {
667
+ throw new Error("topP is not supported when thinking is enabled");
668
+ }
669
+ if (this.temperature !== 1) {
670
+ throw new Error("temperature is not supported when thinking is enabled");
671
+ }
672
+ return {
673
+ model: this.model,
674
+ stop_sequences: options?.stop ?? this.stopSequences,
675
+ stream: this.streaming,
676
+ max_tokens: this.maxTokens,
677
+ tools: this.formatStructuredToolToAnthropic(options?.tools),
678
+ tool_choice,
679
+ thinking: this.thinking,
680
+ ...this.invocationKwargs,
681
+ };
682
+ }
652
683
  return {
653
684
  model: this.model,
654
685
  temperature: this.temperature,
@@ -659,6 +690,7 @@ class ChatAnthropicMessages extends chat_models_1.BaseChatModel {
659
690
  max_tokens: this.maxTokens,
660
691
  tools: this.formatStructuredToolToAnthropic(options?.tools),
661
692
  tool_choice,
693
+ thinking: this.thinking,
662
694
  ...this.invocationKwargs,
663
695
  };
664
696
  }
@@ -686,7 +718,9 @@ class ChatAnthropicMessages extends chat_models_1.BaseChatModel {
686
718
  ...formattedMessages,
687
719
  stream: true,
688
720
  };
689
- const coerceContentToString = !_toolsInParams(payload) && !_documentsInParams(payload);
721
+ const coerceContentToString = !_toolsInParams(payload) &&
722
+ !_documentsInParams(payload) &&
723
+ !_thinkingInParams(payload);
690
724
  const stream = await this.createStreamWithRetry(payload, {
691
725
  headers: options.headers,
692
726
  });
@@ -7,7 +7,7 @@ import { BaseChatModel, BaseChatModelCallOptions, LangSmithParams, type BaseChat
7
7
  import { type StructuredOutputMethodOptions, type BaseLanguageModelInput } from "@langchain/core/language_models/base";
8
8
  import { Runnable } from "@langchain/core/runnables";
9
9
  import { z } from "zod";
10
- import { AnthropicMessageCreateParams, AnthropicMessageStreamEvent, AnthropicRequestOptions, AnthropicStreamingMessageCreateParams, AnthropicToolChoice, ChatAnthropicToolType } from "./types.js";
10
+ import { AnthropicMessageCreateParams, AnthropicMessageStreamEvent, AnthropicRequestOptions, AnthropicStreamingMessageCreateParams, AnthropicThinkingConfigParam, AnthropicToolChoice, ChatAnthropicToolType } from "./types.js";
11
11
  export interface ChatAnthropicCallOptions extends BaseChatModelCallOptions, Pick<AnthropicInput, "streamUsage"> {
12
12
  tools?: ChatAnthropicToolType[];
13
13
  /**
@@ -87,6 +87,10 @@ export interface AnthropicInput {
87
87
  * such as Google Vertex.
88
88
  */
89
89
  createClient?: (options: ClientOptions) => any;
90
+ /**
91
+ * Options for extended thinking.
92
+ */
93
+ thinking?: AnthropicThinkingConfigParam;
90
94
  }
91
95
  /**
92
96
  * A type representing additional parameters that can be passed to the
@@ -490,6 +494,7 @@ export declare class ChatAnthropicMessages<CallOptions extends ChatAnthropicCall
490
494
  stopSequences?: string[];
491
495
  streaming: boolean;
492
496
  clientOptions: ClientOptions;
497
+ thinking: AnthropicThinkingConfigParam;
493
498
  protected batchClient: Anthropic;
494
499
  protected streamingClient: Anthropic;
495
500
  streamUsage: boolean;
@@ -516,9 +521,10 @@ export declare class ChatAnthropicMessages<CallOptions extends ChatAnthropicCall
516
521
  /** @ignore */
517
522
  _identifyingParams(): {
518
523
  system?: string | Anthropic.Messages.TextBlockParam[] | undefined;
524
+ thinking?: Anthropic.Messages.ThinkingConfigParam | undefined;
519
525
  model: Anthropic.Messages.Model;
520
526
  max_tokens: number;
521
- tools?: Anthropic.Messages.Tool[] | undefined;
527
+ tools?: Anthropic.Messages.ToolUnion[] | undefined;
522
528
  tool_choice?: Anthropic.Messages.ToolChoice | undefined;
523
529
  metadata?: Anthropic.Messages.Metadata | undefined;
524
530
  temperature?: number | undefined;
@@ -533,9 +539,10 @@ export declare class ChatAnthropicMessages<CallOptions extends ChatAnthropicCall
533
539
  */
534
540
  identifyingParams(): {
535
541
  system?: string | Anthropic.Messages.TextBlockParam[] | undefined;
542
+ thinking?: Anthropic.Messages.ThinkingConfigParam | undefined;
536
543
  model: Anthropic.Messages.Model;
537
544
  max_tokens: number;
538
- tools?: Anthropic.Messages.Tool[] | undefined;
545
+ tools?: Anthropic.Messages.ToolUnion[] | undefined;
539
546
  tool_choice?: Anthropic.Messages.ToolChoice | undefined;
540
547
  metadata?: Anthropic.Messages.Metadata | undefined;
541
548
  temperature?: number | undefined;
@@ -33,6 +33,9 @@ function _documentsInParams(params) {
33
33
  }
34
34
  return false;
35
35
  }
36
+ function _thinkingInParams(params) {
37
+ return !!(params.thinking && params.thinking.type === "enabled");
38
+ }
36
39
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
37
40
  function isAnthropicTool(tool) {
38
41
  return "input_schema" in tool;
@@ -533,6 +536,12 @@ export class ChatAnthropicMessages extends BaseChatModel {
533
536
  writable: true,
534
537
  value: void 0
535
538
  });
539
+ Object.defineProperty(this, "thinking", {
540
+ enumerable: true,
541
+ configurable: true,
542
+ writable: true,
543
+ value: { type: "disabled" }
544
+ });
536
545
  // Used for non-streaming requests
537
546
  Object.defineProperty(this, "batchClient", {
538
547
  enumerable: true,
@@ -588,6 +597,7 @@ export class ChatAnthropicMessages extends BaseChatModel {
588
597
  this.stopSequences = fields?.stopSequences ?? this.stopSequences;
589
598
  this.streaming = fields?.streaming ?? false;
590
599
  this.streamUsage = fields?.streamUsage ?? this.streamUsage;
600
+ this.thinking = fields?.thinking ?? this.thinking;
591
601
  this.createClient =
592
602
  fields?.createClient ??
593
603
  ((options) => new Anthropic(options));
@@ -646,6 +656,27 @@ export class ChatAnthropicMessages extends BaseChatModel {
646
656
  */
647
657
  invocationParams(options) {
648
658
  const tool_choice = handleToolChoice(options?.tool_choice);
659
+ if (this.thinking.type === "enabled") {
660
+ if (this.topK !== -1) {
661
+ throw new Error("topK is not supported when thinking is enabled");
662
+ }
663
+ if (this.topP !== -1) {
664
+ throw new Error("topP is not supported when thinking is enabled");
665
+ }
666
+ if (this.temperature !== 1) {
667
+ throw new Error("temperature is not supported when thinking is enabled");
668
+ }
669
+ return {
670
+ model: this.model,
671
+ stop_sequences: options?.stop ?? this.stopSequences,
672
+ stream: this.streaming,
673
+ max_tokens: this.maxTokens,
674
+ tools: this.formatStructuredToolToAnthropic(options?.tools),
675
+ tool_choice,
676
+ thinking: this.thinking,
677
+ ...this.invocationKwargs,
678
+ };
679
+ }
649
680
  return {
650
681
  model: this.model,
651
682
  temperature: this.temperature,
@@ -656,6 +687,7 @@ export class ChatAnthropicMessages extends BaseChatModel {
656
687
  max_tokens: this.maxTokens,
657
688
  tools: this.formatStructuredToolToAnthropic(options?.tools),
658
689
  tool_choice,
690
+ thinking: this.thinking,
659
691
  ...this.invocationKwargs,
660
692
  };
661
693
  }
@@ -683,7 +715,9 @@ export class ChatAnthropicMessages extends BaseChatModel {
683
715
  ...formattedMessages,
684
716
  stream: true,
685
717
  };
686
- const coerceContentToString = !_toolsInParams(payload) && !_documentsInParams(payload);
718
+ const coerceContentToString = !_toolsInParams(payload) &&
719
+ !_documentsInParams(payload) &&
720
+ !_thinkingInParams(payload);
687
721
  const stream = await this.createStreamWithRetry(payload, {
688
722
  headers: options.headers,
689
723
  });
package/dist/types.d.ts CHANGED
@@ -10,6 +10,7 @@ export type AnthropicMessageParam = Anthropic.MessageParam;
10
10
  export type AnthropicMessageResponse = Anthropic.ContentBlock | AnthropicToolResponse;
11
11
  export type AnthropicMessageCreateParams = Anthropic.MessageCreateParamsNonStreaming;
12
12
  export type AnthropicStreamingMessageCreateParams = Anthropic.MessageCreateParamsStreaming;
13
+ export type AnthropicThinkingConfigParam = Anthropic.ThinkingConfigParam;
13
14
  export type AnthropicMessageStreamEvent = Anthropic.MessageStreamEvent;
14
15
  export type AnthropicRequestOptions = Anthropic.RequestOptions;
15
16
  export type AnthropicToolChoice = {
@@ -22,3 +23,5 @@ export type AnthropicImageBlockParam = Anthropic.Messages.ImageBlockParam;
22
23
  export type AnthropicToolUseBlockParam = Anthropic.Messages.ToolUseBlockParam;
23
24
  export type AnthropicToolResultBlockParam = Anthropic.Messages.ToolResultBlockParam;
24
25
  export type AnthropicDocumentBlockParam = Anthropic.Messages.DocumentBlockParam;
26
+ export type AnthropicThinkingBlockParam = Anthropic.Messages.ThinkingBlockParam;
27
+ export type AnthropicRedactedThinkingBlockParam = Anthropic.Messages.RedactedThinkingBlockParam;
@@ -112,6 +112,23 @@ function _formatContent(content) {
112
112
  ...(cacheControl ? { cache_control: cacheControl } : {}),
113
113
  };
114
114
  }
115
+ else if (contentPart.type === "thinking") {
116
+ const block = {
117
+ type: "thinking",
118
+ thinking: contentPart.thinking,
119
+ signature: contentPart.signature,
120
+ ...(cacheControl ? { cache_control: cacheControl } : {}),
121
+ };
122
+ return block;
123
+ }
124
+ else if (contentPart.type === "redacted_thinking") {
125
+ const block = {
126
+ type: "redacted_thinking",
127
+ data: contentPart.data,
128
+ ...(cacheControl ? { cache_control: cacheControl } : {}),
129
+ };
130
+ return block;
131
+ }
115
132
  else if (textTypes.find((t) => t === contentPart.type) &&
116
133
  "text" in contentPart) {
117
134
  // Assuming contentPart is of type MessageContentText here
@@ -108,6 +108,23 @@ function _formatContent(content) {
108
108
  ...(cacheControl ? { cache_control: cacheControl } : {}),
109
109
  };
110
110
  }
111
+ else if (contentPart.type === "thinking") {
112
+ const block = {
113
+ type: "thinking",
114
+ thinking: contentPart.thinking,
115
+ signature: contentPart.signature,
116
+ ...(cacheControl ? { cache_control: cacheControl } : {}),
117
+ };
118
+ return block;
119
+ }
120
+ else if (contentPart.type === "redacted_thinking") {
121
+ const block = {
122
+ type: "redacted_thinking",
123
+ data: contentPart.data,
124
+ ...(cacheControl ? { cache_control: cacheControl } : {}),
125
+ };
126
+ return block;
127
+ }
111
128
  else if (textTypes.find((t) => t === contentPart.type) &&
112
129
  "text" in contentPart) {
113
130
  // Assuming contentPart is of type MessageContentText here
@@ -93,7 +93,12 @@ function _makeMessageChunkFromAnthropicEvent(data, fields) {
93
93
  };
94
94
  }
95
95
  else if (data.type === "content_block_delta" &&
96
- ["text_delta", "citations_delta"].includes(data.delta.type)) {
96
+ [
97
+ "text_delta",
98
+ "citations_delta",
99
+ "thinking_delta",
100
+ "signature_delta",
101
+ ].includes(data.delta.type)) {
97
102
  if (fields.coerceContentToString && "text" in data.delta) {
98
103
  return {
99
104
  chunk: new messages_1.AIMessageChunk({
@@ -108,6 +113,14 @@ function _makeMessageChunkFromAnthropicEvent(data, fields) {
108
113
  contentBlock.citations = [contentBlock.citation];
109
114
  delete contentBlock.citation;
110
115
  }
116
+ if (contentBlock.type === "thinking_delta" ||
117
+ contentBlock.type === "signature_delta") {
118
+ return {
119
+ chunk: new messages_1.AIMessageChunk({
120
+ content: [{ index: data.index, ...contentBlock, type: "thinking" }],
121
+ }),
122
+ };
123
+ }
111
124
  return {
112
125
  chunk: new messages_1.AIMessageChunk({
113
126
  content: [{ index: data.index, ...contentBlock, type: "text" }],
@@ -157,6 +170,27 @@ function _makeMessageChunkFromAnthropicEvent(data, fields) {
157
170
  };
158
171
  }
159
172
  }
173
+ else if (data.type === "content_block_start" &&
174
+ data.content_block.type === "redacted_thinking") {
175
+ return {
176
+ chunk: new messages_1.AIMessageChunk({
177
+ content: fields.coerceContentToString
178
+ ? ""
179
+ : [{ index: data.index, ...data.content_block }],
180
+ }),
181
+ };
182
+ }
183
+ else if (data.type === "content_block_start" &&
184
+ data.content_block.type === "thinking") {
185
+ const content = data.content_block.thinking;
186
+ return {
187
+ chunk: new messages_1.AIMessageChunk({
188
+ content: fields.coerceContentToString
189
+ ? content
190
+ : [{ index: data.index, ...data.content_block }],
191
+ }),
192
+ };
193
+ }
160
194
  return null;
161
195
  }
162
196
  exports._makeMessageChunkFromAnthropicEvent = _makeMessageChunkFromAnthropicEvent;
@@ -90,7 +90,12 @@ export function _makeMessageChunkFromAnthropicEvent(data, fields) {
90
90
  };
91
91
  }
92
92
  else if (data.type === "content_block_delta" &&
93
- ["text_delta", "citations_delta"].includes(data.delta.type)) {
93
+ [
94
+ "text_delta",
95
+ "citations_delta",
96
+ "thinking_delta",
97
+ "signature_delta",
98
+ ].includes(data.delta.type)) {
94
99
  if (fields.coerceContentToString && "text" in data.delta) {
95
100
  return {
96
101
  chunk: new AIMessageChunk({
@@ -105,6 +110,14 @@ export function _makeMessageChunkFromAnthropicEvent(data, fields) {
105
110
  contentBlock.citations = [contentBlock.citation];
106
111
  delete contentBlock.citation;
107
112
  }
113
+ if (contentBlock.type === "thinking_delta" ||
114
+ contentBlock.type === "signature_delta") {
115
+ return {
116
+ chunk: new AIMessageChunk({
117
+ content: [{ index: data.index, ...contentBlock, type: "thinking" }],
118
+ }),
119
+ };
120
+ }
108
121
  return {
109
122
  chunk: new AIMessageChunk({
110
123
  content: [{ index: data.index, ...contentBlock, type: "text" }],
@@ -154,6 +167,27 @@ export function _makeMessageChunkFromAnthropicEvent(data, fields) {
154
167
  };
155
168
  }
156
169
  }
170
+ else if (data.type === "content_block_start" &&
171
+ data.content_block.type === "redacted_thinking") {
172
+ return {
173
+ chunk: new AIMessageChunk({
174
+ content: fields.coerceContentToString
175
+ ? ""
176
+ : [{ index: data.index, ...data.content_block }],
177
+ }),
178
+ };
179
+ }
180
+ else if (data.type === "content_block_start" &&
181
+ data.content_block.type === "thinking") {
182
+ const content = data.content_block.thinking;
183
+ return {
184
+ chunk: new AIMessageChunk({
185
+ content: fields.coerceContentToString
186
+ ? content
187
+ : [{ index: data.index, ...data.content_block }],
188
+ }),
189
+ };
190
+ }
157
191
  return null;
158
192
  }
159
193
  export function anthropicResponseToChatMessages(messages, additionalKwargs) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@langchain/anthropic",
3
- "version": "0.3.13",
3
+ "version": "0.3.14",
4
4
  "description": "Anthropic integrations for LangChain.js",
5
5
  "type": "module",
6
6
  "engines": {
@@ -35,7 +35,7 @@
35
35
  "author": "LangChain",
36
36
  "license": "MIT",
37
37
  "dependencies": {
38
- "@anthropic-ai/sdk": "^0.36.3",
38
+ "@anthropic-ai/sdk": "^0.37.0",
39
39
  "fast-xml-parser": "^4.4.1",
40
40
  "zod": "^3.22.4",
41
41
  "zod-to-json-schema": "^3.22.4"