@langchain/anthropic 0.3.4 → 0.3.6-rc.0

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.
@@ -15,6 +15,7 @@ const output_parsers_js_1 = require("./output_parsers.cjs");
15
15
  const tools_js_1 = require("./utils/tools.cjs");
16
16
  const message_inputs_js_1 = require("./utils/message_inputs.cjs");
17
17
  const message_outputs_js_1 = require("./utils/message_outputs.cjs");
18
+ const errors_js_1 = require("./utils/errors.cjs");
18
19
  function _toolsInParams(params) {
19
20
  return !!(params.tools && params.tools.length > 0);
20
21
  }
@@ -687,7 +688,6 @@ class ChatAnthropicMessages extends chat_models_1.BaseChatModel {
687
688
  if (!result)
688
689
  continue;
689
690
  const { chunk } = result;
690
- const newToolCallChunk = (0, tools_js_1.extractToolCallChunk)(chunk);
691
691
  // Extract the text content token for text field and runManager.
692
692
  const token = extractToken(chunk);
693
693
  const generationChunk = new outputs_1.ChatGenerationChunk({
@@ -695,7 +695,7 @@ class ChatAnthropicMessages extends chat_models_1.BaseChatModel {
695
695
  // Just yield chunk as it is and tool_use will be concat by BaseChatModel._generateUncached().
696
696
  content: chunk.content,
697
697
  additional_kwargs: chunk.additional_kwargs,
698
- tool_call_chunks: newToolCallChunk ? [newToolCallChunk] : undefined,
698
+ tool_call_chunks: chunk.tool_call_chunks,
699
699
  usage_metadata: shouldStreamUsage ? chunk.usage_metadata : undefined,
700
700
  response_metadata: chunk.response_metadata,
701
701
  id: chunk.id,
@@ -773,11 +773,19 @@ class ChatAnthropicMessages extends chat_models_1.BaseChatModel {
773
773
  maxRetries: 0,
774
774
  });
775
775
  }
776
- const makeCompletionRequest = async () => this.streamingClient.messages.create({
777
- ...request,
778
- ...this.invocationKwargs,
779
- stream: true,
780
- }, options);
776
+ const makeCompletionRequest = async () => {
777
+ try {
778
+ return await this.streamingClient.messages.create({
779
+ ...request,
780
+ ...this.invocationKwargs,
781
+ stream: true,
782
+ }, options);
783
+ }
784
+ catch (e) {
785
+ const error = (0, errors_js_1.wrapAnthropicClientError)(e);
786
+ throw error;
787
+ }
788
+ };
781
789
  return this.caller.call(makeCompletionRequest);
782
790
  }
783
791
  /** @ignore */
@@ -792,10 +800,18 @@ class ChatAnthropicMessages extends chat_models_1.BaseChatModel {
792
800
  maxRetries: 0,
793
801
  });
794
802
  }
795
- const makeCompletionRequest = async () => this.batchClient.messages.create({
796
- ...request,
797
- ...this.invocationKwargs,
798
- }, options);
803
+ const makeCompletionRequest = async () => {
804
+ try {
805
+ return await this.batchClient.messages.create({
806
+ ...request,
807
+ ...this.invocationKwargs,
808
+ }, options);
809
+ }
810
+ catch (e) {
811
+ const error = (0, errors_js_1.wrapAnthropicClientError)(e);
812
+ throw error;
813
+ }
814
+ };
799
815
  return this.caller.callWithOptions({ signal: options.signal ?? undefined }, makeCompletionRequest);
800
816
  }
801
817
  _llmType() {
@@ -9,9 +9,10 @@ import { RunnablePassthrough, RunnableSequence, } from "@langchain/core/runnable
9
9
  import { isZodSchema } from "@langchain/core/utils/types";
10
10
  import { isLangChainTool } from "@langchain/core/utils/function_calling";
11
11
  import { AnthropicToolsOutputParser } from "./output_parsers.js";
12
- import { extractToolCallChunk, handleToolChoice } from "./utils/tools.js";
12
+ import { handleToolChoice } from "./utils/tools.js";
13
13
  import { _convertMessagesToAnthropicPayload } from "./utils/message_inputs.js";
14
14
  import { _makeMessageChunkFromAnthropicEvent, anthropicResponseToChatMessages, } from "./utils/message_outputs.js";
15
+ import { wrapAnthropicClientError } from "./utils/errors.js";
15
16
  function _toolsInParams(params) {
16
17
  return !!(params.tools && params.tools.length > 0);
17
18
  }
@@ -684,7 +685,6 @@ export class ChatAnthropicMessages extends BaseChatModel {
684
685
  if (!result)
685
686
  continue;
686
687
  const { chunk } = result;
687
- const newToolCallChunk = extractToolCallChunk(chunk);
688
688
  // Extract the text content token for text field and runManager.
689
689
  const token = extractToken(chunk);
690
690
  const generationChunk = new ChatGenerationChunk({
@@ -692,7 +692,7 @@ export class ChatAnthropicMessages extends BaseChatModel {
692
692
  // Just yield chunk as it is and tool_use will be concat by BaseChatModel._generateUncached().
693
693
  content: chunk.content,
694
694
  additional_kwargs: chunk.additional_kwargs,
695
- tool_call_chunks: newToolCallChunk ? [newToolCallChunk] : undefined,
695
+ tool_call_chunks: chunk.tool_call_chunks,
696
696
  usage_metadata: shouldStreamUsage ? chunk.usage_metadata : undefined,
697
697
  response_metadata: chunk.response_metadata,
698
698
  id: chunk.id,
@@ -770,11 +770,19 @@ export class ChatAnthropicMessages extends BaseChatModel {
770
770
  maxRetries: 0,
771
771
  });
772
772
  }
773
- const makeCompletionRequest = async () => this.streamingClient.messages.create({
774
- ...request,
775
- ...this.invocationKwargs,
776
- stream: true,
777
- }, options);
773
+ const makeCompletionRequest = async () => {
774
+ try {
775
+ return await this.streamingClient.messages.create({
776
+ ...request,
777
+ ...this.invocationKwargs,
778
+ stream: true,
779
+ }, options);
780
+ }
781
+ catch (e) {
782
+ const error = wrapAnthropicClientError(e);
783
+ throw error;
784
+ }
785
+ };
778
786
  return this.caller.call(makeCompletionRequest);
779
787
  }
780
788
  /** @ignore */
@@ -789,10 +797,18 @@ export class ChatAnthropicMessages extends BaseChatModel {
789
797
  maxRetries: 0,
790
798
  });
791
799
  }
792
- const makeCompletionRequest = async () => this.batchClient.messages.create({
793
- ...request,
794
- ...this.invocationKwargs,
795
- }, options);
800
+ const makeCompletionRequest = async () => {
801
+ try {
802
+ return await this.batchClient.messages.create({
803
+ ...request,
804
+ ...this.invocationKwargs,
805
+ }, options);
806
+ }
807
+ catch (e) {
808
+ const error = wrapAnthropicClientError(e);
809
+ throw error;
810
+ }
811
+ };
796
812
  return this.caller.callWithOptions({ signal: options.signal ?? undefined }, makeCompletionRequest);
797
813
  }
798
814
  _llmType() {
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ /* eslint-disable @typescript-eslint/no-explicit-any */
3
+ /* eslint-disable no-param-reassign */
4
+ Object.defineProperty(exports, "__esModule", { value: true });
5
+ exports.wrapAnthropicClientError = exports.addLangChainErrorFields = void 0;
6
+ function addLangChainErrorFields(error, lc_error_code) {
7
+ error.lc_error_code = lc_error_code;
8
+ error.message = `${error.message}\n\nTroubleshooting URL: https://js.langchain.com/docs/troubleshooting/errors/${lc_error_code}/\n`;
9
+ return error;
10
+ }
11
+ exports.addLangChainErrorFields = addLangChainErrorFields;
12
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
13
+ function wrapAnthropicClientError(e) {
14
+ let error;
15
+ if (e.status === 400 && e.message.includes("tool")) {
16
+ error = addLangChainErrorFields(e, "INVALID_TOOL_RESULTS");
17
+ }
18
+ else if (e.status === 401) {
19
+ error = addLangChainErrorFields(e, "MODEL_AUTHENTICATION");
20
+ }
21
+ else if (e.status === 404) {
22
+ error = addLangChainErrorFields(e, "MODEL_NOT_FOUND");
23
+ }
24
+ else if (e.status === 429) {
25
+ error = addLangChainErrorFields(e, "MODEL_RATE_LIMIT");
26
+ }
27
+ else {
28
+ error = e;
29
+ }
30
+ return error;
31
+ }
32
+ exports.wrapAnthropicClientError = wrapAnthropicClientError;
@@ -0,0 +1,3 @@
1
+ export type LangChainErrorCodes = "INVALID_PROMPT_INPUT" | "INVALID_TOOL_RESULTS" | "MESSAGE_COERCION_FAILURE" | "MODEL_AUTHENTICATION" | "MODEL_NOT_FOUND" | "MODEL_RATE_LIMIT" | "OUTPUT_PARSING_FAILURE";
2
+ export declare function addLangChainErrorFields(error: any, lc_error_code: LangChainErrorCodes): any;
3
+ export declare function wrapAnthropicClientError(e: any): any;
@@ -0,0 +1,27 @@
1
+ /* eslint-disable @typescript-eslint/no-explicit-any */
2
+ /* eslint-disable no-param-reassign */
3
+ export function addLangChainErrorFields(error, lc_error_code) {
4
+ error.lc_error_code = lc_error_code;
5
+ error.message = `${error.message}\n\nTroubleshooting URL: https://js.langchain.com/docs/troubleshooting/errors/${lc_error_code}/\n`;
6
+ return error;
7
+ }
8
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
9
+ export function wrapAnthropicClientError(e) {
10
+ let error;
11
+ if (e.status === 400 && e.message.includes("tool")) {
12
+ error = addLangChainErrorFields(e, "INVALID_TOOL_RESULTS");
13
+ }
14
+ else if (e.status === 401) {
15
+ error = addLangChainErrorFields(e, "MODEL_AUTHENTICATION");
16
+ }
17
+ else if (e.status === 404) {
18
+ error = addLangChainErrorFields(e, "MODEL_NOT_FOUND");
19
+ }
20
+ else if (e.status === 429) {
21
+ error = addLangChainErrorFields(e, "MODEL_RATE_LIMIT");
22
+ }
23
+ else {
24
+ error = e;
25
+ }
26
+ return error;
27
+ }
@@ -44,6 +44,7 @@ function _makeMessageChunkFromAnthropicEvent(data, fields) {
44
44
  }
45
45
  else if (data.type === "content_block_start" &&
46
46
  data.content_block.type === "tool_use") {
47
+ const toolCallContentBlock = data.content_block;
47
48
  return {
48
49
  chunk: new messages_1.AIMessageChunk({
49
50
  content: fields.coerceContentToString
@@ -56,6 +57,14 @@ function _makeMessageChunkFromAnthropicEvent(data, fields) {
56
57
  },
57
58
  ],
58
59
  additional_kwargs: {},
60
+ tool_call_chunks: [
61
+ {
62
+ id: toolCallContentBlock.id,
63
+ index: data.index,
64
+ name: toolCallContentBlock.name,
65
+ args: "",
66
+ },
67
+ ],
59
68
  }),
60
69
  };
61
70
  }
@@ -92,6 +101,12 @@ function _makeMessageChunkFromAnthropicEvent(data, fields) {
92
101
  },
93
102
  ],
94
103
  additional_kwargs: {},
104
+ tool_call_chunks: [
105
+ {
106
+ index: data.index,
107
+ args: data.delta.partial_json,
108
+ },
109
+ ],
95
110
  }),
96
111
  };
97
112
  }
@@ -41,6 +41,7 @@ export function _makeMessageChunkFromAnthropicEvent(data, fields) {
41
41
  }
42
42
  else if (data.type === "content_block_start" &&
43
43
  data.content_block.type === "tool_use") {
44
+ const toolCallContentBlock = data.content_block;
44
45
  return {
45
46
  chunk: new AIMessageChunk({
46
47
  content: fields.coerceContentToString
@@ -53,6 +54,14 @@ export function _makeMessageChunkFromAnthropicEvent(data, fields) {
53
54
  },
54
55
  ],
55
56
  additional_kwargs: {},
57
+ tool_call_chunks: [
58
+ {
59
+ id: toolCallContentBlock.id,
60
+ index: data.index,
61
+ name: toolCallContentBlock.name,
62
+ args: "",
63
+ },
64
+ ],
56
65
  }),
57
66
  };
58
67
  }
@@ -89,6 +98,12 @@ export function _makeMessageChunkFromAnthropicEvent(data, fields) {
89
98
  },
90
99
  ],
91
100
  additional_kwargs: {},
101
+ tool_call_chunks: [
102
+ {
103
+ index: data.index,
104
+ args: data.delta.partial_json,
105
+ },
106
+ ],
92
107
  }),
93
108
  };
94
109
  }
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.extractToolCallChunk = exports.handleToolChoice = void 0;
3
+ exports.handleToolChoice = void 0;
4
4
  function handleToolChoice(toolChoice) {
5
5
  if (!toolChoice) {
6
6
  return undefined;
@@ -26,51 +26,3 @@ function handleToolChoice(toolChoice) {
26
26
  }
27
27
  }
28
28
  exports.handleToolChoice = handleToolChoice;
29
- function extractToolCallChunk(chunk) {
30
- let newToolCallChunk;
31
- // Initial chunk for tool calls from anthropic contains identifying information like ID and name.
32
- // This chunk does not contain any input JSON.
33
- const toolUseChunks = Array.isArray(chunk.content)
34
- ? chunk.content.find((c) => c.type === "tool_use")
35
- : undefined;
36
- if (toolUseChunks &&
37
- "index" in toolUseChunks &&
38
- "name" in toolUseChunks &&
39
- "id" in toolUseChunks) {
40
- newToolCallChunk = {
41
- args: "",
42
- id: toolUseChunks.id,
43
- name: toolUseChunks.name,
44
- index: toolUseChunks.index,
45
- type: "tool_call_chunk",
46
- };
47
- }
48
- // Chunks after the initial chunk only contain the index and partial JSON.
49
- const inputJsonDeltaChunks = Array.isArray(chunk.content)
50
- ? chunk.content.find((c) => c.type === "input_json_delta")
51
- : undefined;
52
- if (inputJsonDeltaChunks &&
53
- "index" in inputJsonDeltaChunks &&
54
- "input" in inputJsonDeltaChunks) {
55
- if (typeof inputJsonDeltaChunks.input === "string") {
56
- newToolCallChunk = {
57
- id: inputJsonDeltaChunks.id,
58
- name: inputJsonDeltaChunks.name,
59
- args: inputJsonDeltaChunks.input,
60
- index: inputJsonDeltaChunks.index,
61
- type: "tool_call_chunk",
62
- };
63
- }
64
- else {
65
- newToolCallChunk = {
66
- id: inputJsonDeltaChunks.id,
67
- name: inputJsonDeltaChunks.name,
68
- args: JSON.stringify(inputJsonDeltaChunks.input, null, 2),
69
- index: inputJsonDeltaChunks.index,
70
- type: "tool_call_chunk",
71
- };
72
- }
73
- }
74
- return newToolCallChunk;
75
- }
76
- exports.extractToolCallChunk = extractToolCallChunk;
@@ -1,6 +1,3 @@
1
1
  import type { MessageCreateParams } from "@anthropic-ai/sdk/resources/index.mjs";
2
- import { AIMessageChunk } from "@langchain/core/messages";
3
- import { ToolCallChunk } from "@langchain/core/messages/tool";
4
2
  import { AnthropicToolChoice } from "../types.js";
5
3
  export declare function handleToolChoice(toolChoice?: AnthropicToolChoice): MessageCreateParams.ToolChoiceAuto | MessageCreateParams.ToolChoiceAny | MessageCreateParams.ToolChoiceTool | undefined;
6
- export declare function extractToolCallChunk(chunk: AIMessageChunk): ToolCallChunk | undefined;
@@ -22,50 +22,3 @@ export function handleToolChoice(toolChoice) {
22
22
  return toolChoice;
23
23
  }
24
24
  }
25
- export function extractToolCallChunk(chunk) {
26
- let newToolCallChunk;
27
- // Initial chunk for tool calls from anthropic contains identifying information like ID and name.
28
- // This chunk does not contain any input JSON.
29
- const toolUseChunks = Array.isArray(chunk.content)
30
- ? chunk.content.find((c) => c.type === "tool_use")
31
- : undefined;
32
- if (toolUseChunks &&
33
- "index" in toolUseChunks &&
34
- "name" in toolUseChunks &&
35
- "id" in toolUseChunks) {
36
- newToolCallChunk = {
37
- args: "",
38
- id: toolUseChunks.id,
39
- name: toolUseChunks.name,
40
- index: toolUseChunks.index,
41
- type: "tool_call_chunk",
42
- };
43
- }
44
- // Chunks after the initial chunk only contain the index and partial JSON.
45
- const inputJsonDeltaChunks = Array.isArray(chunk.content)
46
- ? chunk.content.find((c) => c.type === "input_json_delta")
47
- : undefined;
48
- if (inputJsonDeltaChunks &&
49
- "index" in inputJsonDeltaChunks &&
50
- "input" in inputJsonDeltaChunks) {
51
- if (typeof inputJsonDeltaChunks.input === "string") {
52
- newToolCallChunk = {
53
- id: inputJsonDeltaChunks.id,
54
- name: inputJsonDeltaChunks.name,
55
- args: inputJsonDeltaChunks.input,
56
- index: inputJsonDeltaChunks.index,
57
- type: "tool_call_chunk",
58
- };
59
- }
60
- else {
61
- newToolCallChunk = {
62
- id: inputJsonDeltaChunks.id,
63
- name: inputJsonDeltaChunks.name,
64
- args: JSON.stringify(inputJsonDeltaChunks.input, null, 2),
65
- index: inputJsonDeltaChunks.index,
66
- type: "tool_call_chunk",
67
- };
68
- }
69
- }
70
- return newToolCallChunk;
71
- }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@langchain/anthropic",
3
- "version": "0.3.4",
3
+ "version": "0.3.6-rc.0",
4
4
  "description": "Anthropic integrations for LangChain.js",
5
5
  "type": "module",
6
6
  "engines": {