@langchain/anthropic 0.3.12 → 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.
package/README.md CHANGED
@@ -49,24 +49,30 @@ export ANTHROPIC_API_KEY=your-api-key
49
49
  Then initialize
50
50
 
51
51
  ```typescript
52
- import { ChatAnthropicMessages } from "@langchain/anthropic";
52
+ import { ChatAnthropic } from "@langchain/anthropic";
53
53
 
54
54
  const model = new ChatAnthropic({
55
55
  apiKey: process.env.ANTHROPIC_API_KEY,
56
56
  });
57
- const response = await model.invoke(new HumanMessage("Hello world!"));
57
+ const response = await model.invoke({
58
+ role: "user",
59
+ content: "Hello world!",
60
+ });
58
61
  ```
59
62
 
60
63
  ### Streaming
61
64
 
62
65
  ```typescript
63
- import { ChatAnthropicMessages } from "@langchain/anthropic";
66
+ import { ChatAnthropic } from "@langchain/anthropic";
64
67
 
65
68
  const model = new ChatAnthropic({
66
69
  apiKey: process.env.ANTHROPIC_API_KEY,
67
70
  model: "claude-3-sonnet-20240229",
68
71
  });
69
- const response = await model.stream(new HumanMessage("Hello world!"));
72
+ const response = await model.stream({
73
+ role: "user",
74
+ content: "Hello world!",
75
+ });
70
76
  ```
71
77
 
72
78
  ## Development
@@ -119,4 +125,4 @@ After running `yarn build`, publish a new version with:
119
125
 
120
126
  ```bash
121
127
  $ npm publish
122
- ```
128
+ ```
@@ -19,6 +19,26 @@ const errors_js_1 = require("./utils/errors.cjs");
19
19
  function _toolsInParams(params) {
20
20
  return !!(params.tools && params.tools.length > 0);
21
21
  }
22
+ function _documentsInParams(params) {
23
+ for (const message of params.messages ?? []) {
24
+ if (typeof message.content === "string") {
25
+ continue;
26
+ }
27
+ for (const block of message.content ?? []) {
28
+ if (typeof block === "object" &&
29
+ block != null &&
30
+ block.type === "document" &&
31
+ typeof block.citations === "object" &&
32
+ block.citations.enabled) {
33
+ return true;
34
+ }
35
+ }
36
+ }
37
+ return false;
38
+ }
39
+ function _thinkingInParams(params) {
40
+ return !!(params.thinking && params.thinking.type === "enabled");
41
+ }
22
42
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
23
43
  function isAnthropicTool(tool) {
24
44
  return "input_schema" in tool;
@@ -519,6 +539,12 @@ class ChatAnthropicMessages extends chat_models_1.BaseChatModel {
519
539
  writable: true,
520
540
  value: void 0
521
541
  });
542
+ Object.defineProperty(this, "thinking", {
543
+ enumerable: true,
544
+ configurable: true,
545
+ writable: true,
546
+ value: { type: "disabled" }
547
+ });
522
548
  // Used for non-streaming requests
523
549
  Object.defineProperty(this, "batchClient", {
524
550
  enumerable: true,
@@ -574,6 +600,7 @@ class ChatAnthropicMessages extends chat_models_1.BaseChatModel {
574
600
  this.stopSequences = fields?.stopSequences ?? this.stopSequences;
575
601
  this.streaming = fields?.streaming ?? false;
576
602
  this.streamUsage = fields?.streamUsage ?? this.streamUsage;
603
+ this.thinking = fields?.thinking ?? this.thinking;
577
604
  this.createClient =
578
605
  fields?.createClient ??
579
606
  ((options) => new sdk_1.Anthropic(options));
@@ -607,7 +634,8 @@ class ChatAnthropicMessages extends chat_models_1.BaseChatModel {
607
634
  return {
608
635
  name: tool.function.name,
609
636
  description: tool.function.description,
610
- input_schema: tool.function.parameters,
637
+ input_schema: tool.function
638
+ .parameters,
611
639
  };
612
640
  }
613
641
  if ((0, function_calling_1.isLangChainTool)(tool)) {
@@ -631,6 +659,27 @@ class ChatAnthropicMessages extends chat_models_1.BaseChatModel {
631
659
  */
632
660
  invocationParams(options) {
633
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
+ }
634
683
  return {
635
684
  model: this.model,
636
685
  temperature: this.temperature,
@@ -641,6 +690,7 @@ class ChatAnthropicMessages extends chat_models_1.BaseChatModel {
641
690
  max_tokens: this.maxTokens,
642
691
  tools: this.formatStructuredToolToAnthropic(options?.tools),
643
692
  tool_choice,
693
+ thinking: this.thinking,
644
694
  ...this.invocationKwargs,
645
695
  };
646
696
  }
@@ -663,16 +713,15 @@ class ChatAnthropicMessages extends chat_models_1.BaseChatModel {
663
713
  async *_streamResponseChunks(messages, options, runManager) {
664
714
  const params = this.invocationParams(options);
665
715
  const formattedMessages = (0, message_inputs_js_1._convertMessagesToAnthropicPayload)(messages);
666
- const coerceContentToString = !_toolsInParams({
667
- ...params,
668
- ...formattedMessages,
669
- stream: false,
670
- });
671
- const stream = await this.createStreamWithRetry({
716
+ const payload = {
672
717
  ...params,
673
718
  ...formattedMessages,
674
719
  stream: true,
675
- }, {
720
+ };
721
+ const coerceContentToString = !_toolsInParams(payload) &&
722
+ !_documentsInParams(payload) &&
723
+ !_thinkingInParams(payload);
724
+ const stream = await this.createStreamWithRetry(payload, {
676
725
  headers: options.headers,
677
726
  });
678
727
  for await (const data of stream) {
@@ -7,8 +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 type { Tool as AnthropicTool } from "@anthropic-ai/sdk/resources/messages";
11
- import { AnthropicMessageCreateParams, AnthropicMessageStreamEvent, AnthropicRequestOptions, AnthropicStreamingMessageCreateParams, AnthropicToolChoice, ChatAnthropicToolType } from "./types.js";
10
+ import { AnthropicMessageCreateParams, AnthropicMessageStreamEvent, AnthropicRequestOptions, AnthropicStreamingMessageCreateParams, AnthropicThinkingConfigParam, AnthropicToolChoice, ChatAnthropicToolType } from "./types.js";
12
11
  export interface ChatAnthropicCallOptions extends BaseChatModelCallOptions, Pick<AnthropicInput, "streamUsage"> {
13
12
  tools?: ChatAnthropicToolType[];
14
13
  /**
@@ -88,6 +87,10 @@ export interface AnthropicInput {
88
87
  * such as Google Vertex.
89
88
  */
90
89
  createClient?: (options: ClientOptions) => any;
90
+ /**
91
+ * Options for extended thinking.
92
+ */
93
+ thinking?: AnthropicThinkingConfigParam;
91
94
  }
92
95
  /**
93
96
  * A type representing additional parameters that can be passed to the
@@ -491,6 +494,7 @@ export declare class ChatAnthropicMessages<CallOptions extends ChatAnthropicCall
491
494
  stopSequences?: string[];
492
495
  streaming: boolean;
493
496
  clientOptions: ClientOptions;
497
+ thinking: AnthropicThinkingConfigParam;
494
498
  protected batchClient: Anthropic;
495
499
  protected streamingClient: Anthropic;
496
500
  streamUsage: boolean;
@@ -508,7 +512,7 @@ export declare class ChatAnthropicMessages<CallOptions extends ChatAnthropicCall
508
512
  * @param {ChatAnthropicCallOptions["tools"]} tools The tools to format
509
513
  * @returns {AnthropicTool[] | undefined} The formatted tools, or undefined if none are passed.
510
514
  */
511
- formatStructuredToolToAnthropic(tools: ChatAnthropicCallOptions["tools"]): AnthropicTool[] | undefined;
515
+ formatStructuredToolToAnthropic(tools: ChatAnthropicCallOptions["tools"]): Anthropic.Messages.Tool[] | undefined;
512
516
  bindTools(tools: ChatAnthropicToolType[], kwargs?: Partial<CallOptions>): Runnable<BaseLanguageModelInput, AIMessageChunk, CallOptions>;
513
517
  /**
514
518
  * Get the parameters used to invoke the model
@@ -517,9 +521,10 @@ export declare class ChatAnthropicMessages<CallOptions extends ChatAnthropicCall
517
521
  /** @ignore */
518
522
  _identifyingParams(): {
519
523
  system?: string | Anthropic.Messages.TextBlockParam[] | undefined;
524
+ thinking?: Anthropic.Messages.ThinkingConfigParam | undefined;
520
525
  model: Anthropic.Messages.Model;
521
526
  max_tokens: number;
522
- tools?: Anthropic.Messages.Tool[] | undefined;
527
+ tools?: Anthropic.Messages.ToolUnion[] | undefined;
523
528
  tool_choice?: Anthropic.Messages.ToolChoice | undefined;
524
529
  metadata?: Anthropic.Messages.Metadata | undefined;
525
530
  temperature?: number | undefined;
@@ -534,9 +539,10 @@ export declare class ChatAnthropicMessages<CallOptions extends ChatAnthropicCall
534
539
  */
535
540
  identifyingParams(): {
536
541
  system?: string | Anthropic.Messages.TextBlockParam[] | undefined;
542
+ thinking?: Anthropic.Messages.ThinkingConfigParam | undefined;
537
543
  model: Anthropic.Messages.Model;
538
544
  max_tokens: number;
539
- tools?: Anthropic.Messages.Tool[] | undefined;
545
+ tools?: Anthropic.Messages.ToolUnion[] | undefined;
540
546
  tool_choice?: Anthropic.Messages.ToolChoice | undefined;
541
547
  metadata?: Anthropic.Messages.Metadata | undefined;
542
548
  temperature?: number | undefined;
@@ -16,6 +16,26 @@ import { wrapAnthropicClientError } from "./utils/errors.js";
16
16
  function _toolsInParams(params) {
17
17
  return !!(params.tools && params.tools.length > 0);
18
18
  }
19
+ function _documentsInParams(params) {
20
+ for (const message of params.messages ?? []) {
21
+ if (typeof message.content === "string") {
22
+ continue;
23
+ }
24
+ for (const block of message.content ?? []) {
25
+ if (typeof block === "object" &&
26
+ block != null &&
27
+ block.type === "document" &&
28
+ typeof block.citations === "object" &&
29
+ block.citations.enabled) {
30
+ return true;
31
+ }
32
+ }
33
+ }
34
+ return false;
35
+ }
36
+ function _thinkingInParams(params) {
37
+ return !!(params.thinking && params.thinking.type === "enabled");
38
+ }
19
39
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
20
40
  function isAnthropicTool(tool) {
21
41
  return "input_schema" in tool;
@@ -516,6 +536,12 @@ export class ChatAnthropicMessages extends BaseChatModel {
516
536
  writable: true,
517
537
  value: void 0
518
538
  });
539
+ Object.defineProperty(this, "thinking", {
540
+ enumerable: true,
541
+ configurable: true,
542
+ writable: true,
543
+ value: { type: "disabled" }
544
+ });
519
545
  // Used for non-streaming requests
520
546
  Object.defineProperty(this, "batchClient", {
521
547
  enumerable: true,
@@ -571,6 +597,7 @@ export class ChatAnthropicMessages extends BaseChatModel {
571
597
  this.stopSequences = fields?.stopSequences ?? this.stopSequences;
572
598
  this.streaming = fields?.streaming ?? false;
573
599
  this.streamUsage = fields?.streamUsage ?? this.streamUsage;
600
+ this.thinking = fields?.thinking ?? this.thinking;
574
601
  this.createClient =
575
602
  fields?.createClient ??
576
603
  ((options) => new Anthropic(options));
@@ -604,7 +631,8 @@ export class ChatAnthropicMessages extends BaseChatModel {
604
631
  return {
605
632
  name: tool.function.name,
606
633
  description: tool.function.description,
607
- input_schema: tool.function.parameters,
634
+ input_schema: tool.function
635
+ .parameters,
608
636
  };
609
637
  }
610
638
  if (isLangChainTool(tool)) {
@@ -628,6 +656,27 @@ export class ChatAnthropicMessages extends BaseChatModel {
628
656
  */
629
657
  invocationParams(options) {
630
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
+ }
631
680
  return {
632
681
  model: this.model,
633
682
  temperature: this.temperature,
@@ -638,6 +687,7 @@ export class ChatAnthropicMessages extends BaseChatModel {
638
687
  max_tokens: this.maxTokens,
639
688
  tools: this.formatStructuredToolToAnthropic(options?.tools),
640
689
  tool_choice,
690
+ thinking: this.thinking,
641
691
  ...this.invocationKwargs,
642
692
  };
643
693
  }
@@ -660,16 +710,15 @@ export class ChatAnthropicMessages extends BaseChatModel {
660
710
  async *_streamResponseChunks(messages, options, runManager) {
661
711
  const params = this.invocationParams(options);
662
712
  const formattedMessages = _convertMessagesToAnthropicPayload(messages);
663
- const coerceContentToString = !_toolsInParams({
664
- ...params,
665
- ...formattedMessages,
666
- stream: false,
667
- });
668
- const stream = await this.createStreamWithRetry({
713
+ const payload = {
669
714
  ...params,
670
715
  ...formattedMessages,
671
716
  stream: true,
672
- }, {
717
+ };
718
+ const coerceContentToString = !_toolsInParams(payload) &&
719
+ !_documentsInParams(payload) &&
720
+ !_thinkingInParams(payload);
721
+ const stream = await this.createStreamWithRetry(payload, {
673
722
  headers: options.headers,
674
723
  });
675
724
  for await (const data of stream) {
package/dist/types.d.ts CHANGED
@@ -1,5 +1,4 @@
1
1
  import Anthropic from "@anthropic-ai/sdk";
2
- import type { Tool as AnthropicTool } from "@anthropic-ai/sdk/resources/messages";
3
2
  import { BindToolsInput } from "@langchain/core/language_models/chat_models";
4
3
  export type AnthropicToolResponse = {
5
4
  type: "tool_use";
@@ -11,14 +10,18 @@ export type AnthropicMessageParam = Anthropic.MessageParam;
11
10
  export type AnthropicMessageResponse = Anthropic.ContentBlock | AnthropicToolResponse;
12
11
  export type AnthropicMessageCreateParams = Anthropic.MessageCreateParamsNonStreaming;
13
12
  export type AnthropicStreamingMessageCreateParams = Anthropic.MessageCreateParamsStreaming;
13
+ export type AnthropicThinkingConfigParam = Anthropic.ThinkingConfigParam;
14
14
  export type AnthropicMessageStreamEvent = Anthropic.MessageStreamEvent;
15
15
  export type AnthropicRequestOptions = Anthropic.RequestOptions;
16
16
  export type AnthropicToolChoice = {
17
17
  type: "tool";
18
18
  name: string;
19
19
  } | "any" | "auto" | "none" | string;
20
- export type ChatAnthropicToolType = AnthropicTool | BindToolsInput;
20
+ export type ChatAnthropicToolType = Anthropic.Messages.Tool | BindToolsInput;
21
21
  export type AnthropicTextBlockParam = Anthropic.Messages.TextBlockParam;
22
22
  export type AnthropicImageBlockParam = Anthropic.Messages.ImageBlockParam;
23
23
  export type AnthropicToolUseBlockParam = Anthropic.Messages.ToolUseBlockParam;
24
24
  export type AnthropicToolResultBlockParam = Anthropic.Messages.ToolResultBlockParam;
25
+ export type AnthropicDocumentBlockParam = Anthropic.Messages.DocumentBlockParam;
26
+ export type AnthropicThinkingBlockParam = Anthropic.Messages.ThinkingBlockParam;
27
+ export type AnthropicRedactedThinkingBlockParam = Anthropic.Messages.RedactedThinkingBlockParam;
@@ -108,11 +108,27 @@ function _formatContent(content) {
108
108
  else if (contentPart.type === "document") {
109
109
  // PDF
110
110
  return {
111
- type: "document",
112
- source: contentPart.source,
111
+ ...contentPart,
113
112
  ...(cacheControl ? { cache_control: cacheControl } : {}),
114
113
  };
115
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
+ }
116
132
  else if (textTypes.find((t) => t === contentPart.type) &&
117
133
  "text" in contentPart) {
118
134
  // Assuming contentPart is of type MessageContentText here
@@ -104,11 +104,27 @@ function _formatContent(content) {
104
104
  else if (contentPart.type === "document") {
105
105
  // PDF
106
106
  return {
107
- type: "document",
108
- source: contentPart.source,
107
+ ...contentPart,
109
108
  ...(cacheControl ? { cache_control: cacheControl } : {}),
110
109
  };
111
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
+ }
112
128
  else if (textTypes.find((t) => t === contentPart.type) &&
113
129
  "text" in contentPart) {
114
130
  // Assuming contentPart is of type MessageContentText here
@@ -60,8 +60,22 @@ function _makeMessageChunkFromAnthropicEvent(data, fields) {
60
60
  };
61
61
  }
62
62
  else if (data.type === "content_block_start" &&
63
- data.content_block.type === "tool_use") {
64
- const toolCallContentBlock = data.content_block;
63
+ ["tool_use", "document"].includes(data.content_block.type)) {
64
+ const contentBlock = data.content_block;
65
+ let toolCallChunks;
66
+ if (contentBlock.type === "tool_use") {
67
+ toolCallChunks = [
68
+ {
69
+ id: contentBlock.id,
70
+ index: data.index,
71
+ name: contentBlock.name,
72
+ args: "",
73
+ },
74
+ ];
75
+ }
76
+ else {
77
+ toolCallChunks = [];
78
+ }
65
79
  return {
66
80
  chunk: new messages_1.AIMessageChunk({
67
81
  content: fields.coerceContentToString
@@ -74,32 +88,42 @@ function _makeMessageChunkFromAnthropicEvent(data, fields) {
74
88
  },
75
89
  ],
76
90
  additional_kwargs: {},
77
- tool_call_chunks: [
78
- {
79
- id: toolCallContentBlock.id,
80
- index: data.index,
81
- name: toolCallContentBlock.name,
82
- args: "",
83
- },
84
- ],
91
+ tool_call_chunks: toolCallChunks,
85
92
  }),
86
93
  };
87
94
  }
88
95
  else if (data.type === "content_block_delta" &&
89
- data.delta.type === "text_delta") {
90
- const content = data.delta?.text;
91
- if (content !== undefined) {
96
+ [
97
+ "text_delta",
98
+ "citations_delta",
99
+ "thinking_delta",
100
+ "signature_delta",
101
+ ].includes(data.delta.type)) {
102
+ if (fields.coerceContentToString && "text" in data.delta) {
92
103
  return {
93
104
  chunk: new messages_1.AIMessageChunk({
94
- content: fields.coerceContentToString
95
- ? content
96
- : [
97
- {
98
- index: data.index,
99
- ...data.delta,
100
- },
101
- ],
102
- additional_kwargs: {},
105
+ content: data.delta.text,
106
+ }),
107
+ };
108
+ }
109
+ else {
110
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
111
+ const contentBlock = data.delta;
112
+ if ("citation" in contentBlock) {
113
+ contentBlock.citations = [contentBlock.citation];
114
+ delete contentBlock.citation;
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
+ }
124
+ return {
125
+ chunk: new messages_1.AIMessageChunk({
126
+ content: [{ index: data.index, ...contentBlock, type: "text" }],
103
127
  }),
104
128
  };
105
129
  }
@@ -146,6 +170,27 @@ function _makeMessageChunkFromAnthropicEvent(data, fields) {
146
170
  };
147
171
  }
148
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
+ }
149
194
  return null;
150
195
  }
151
196
  exports._makeMessageChunkFromAnthropicEvent = _makeMessageChunkFromAnthropicEvent;
@@ -57,8 +57,22 @@ export function _makeMessageChunkFromAnthropicEvent(data, fields) {
57
57
  };
58
58
  }
59
59
  else if (data.type === "content_block_start" &&
60
- data.content_block.type === "tool_use") {
61
- const toolCallContentBlock = data.content_block;
60
+ ["tool_use", "document"].includes(data.content_block.type)) {
61
+ const contentBlock = data.content_block;
62
+ let toolCallChunks;
63
+ if (contentBlock.type === "tool_use") {
64
+ toolCallChunks = [
65
+ {
66
+ id: contentBlock.id,
67
+ index: data.index,
68
+ name: contentBlock.name,
69
+ args: "",
70
+ },
71
+ ];
72
+ }
73
+ else {
74
+ toolCallChunks = [];
75
+ }
62
76
  return {
63
77
  chunk: new AIMessageChunk({
64
78
  content: fields.coerceContentToString
@@ -71,32 +85,42 @@ export function _makeMessageChunkFromAnthropicEvent(data, fields) {
71
85
  },
72
86
  ],
73
87
  additional_kwargs: {},
74
- tool_call_chunks: [
75
- {
76
- id: toolCallContentBlock.id,
77
- index: data.index,
78
- name: toolCallContentBlock.name,
79
- args: "",
80
- },
81
- ],
88
+ tool_call_chunks: toolCallChunks,
82
89
  }),
83
90
  };
84
91
  }
85
92
  else if (data.type === "content_block_delta" &&
86
- data.delta.type === "text_delta") {
87
- const content = data.delta?.text;
88
- if (content !== undefined) {
93
+ [
94
+ "text_delta",
95
+ "citations_delta",
96
+ "thinking_delta",
97
+ "signature_delta",
98
+ ].includes(data.delta.type)) {
99
+ if (fields.coerceContentToString && "text" in data.delta) {
89
100
  return {
90
101
  chunk: new AIMessageChunk({
91
- content: fields.coerceContentToString
92
- ? content
93
- : [
94
- {
95
- index: data.index,
96
- ...data.delta,
97
- },
98
- ],
99
- additional_kwargs: {},
102
+ content: data.delta.text,
103
+ }),
104
+ };
105
+ }
106
+ else {
107
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
108
+ const contentBlock = data.delta;
109
+ if ("citation" in contentBlock) {
110
+ contentBlock.citations = [contentBlock.citation];
111
+ delete contentBlock.citation;
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
+ }
121
+ return {
122
+ chunk: new AIMessageChunk({
123
+ content: [{ index: data.index, ...contentBlock, type: "text" }],
100
124
  }),
101
125
  };
102
126
  }
@@ -143,6 +167,27 @@ export function _makeMessageChunkFromAnthropicEvent(data, fields) {
143
167
  };
144
168
  }
145
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
+ }
146
191
  return null;
147
192
  }
148
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.12",
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.32.1",
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"