langchain 1.5.2 → 1.5.4

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.
Files changed (38) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/agents/errors.cjs +10 -1
  3. package/dist/agents/errors.cjs.map +1 -1
  4. package/dist/agents/errors.d.cts +8 -1
  5. package/dist/agents/errors.d.cts.map +1 -1
  6. package/dist/agents/errors.d.ts +8 -1
  7. package/dist/agents/errors.d.ts.map +1 -1
  8. package/dist/agents/errors.js +10 -1
  9. package/dist/agents/errors.js.map +1 -1
  10. package/dist/agents/middleware/index.cjs +1 -0
  11. package/dist/agents/middleware/index.d.cts +1 -0
  12. package/dist/agents/middleware/index.d.ts +1 -0
  13. package/dist/agents/middleware/index.js +1 -0
  14. package/dist/agents/middleware/toolError.cjs +68 -0
  15. package/dist/agents/middleware/toolError.cjs.map +1 -0
  16. package/dist/agents/middleware/toolError.d.cts +64 -0
  17. package/dist/agents/middleware/toolError.d.cts.map +1 -0
  18. package/dist/agents/middleware/toolError.d.ts +64 -0
  19. package/dist/agents/middleware/toolError.d.ts.map +1 -0
  20. package/dist/agents/middleware/toolError.js +67 -0
  21. package/dist/agents/middleware/toolError.js.map +1 -0
  22. package/dist/agents/nodes/ToolNode.cjs +25 -7
  23. package/dist/agents/nodes/ToolNode.cjs.map +1 -1
  24. package/dist/agents/nodes/ToolNode.js +26 -8
  25. package/dist/agents/nodes/ToolNode.js.map +1 -1
  26. package/dist/agents/utils.cjs +11 -4
  27. package/dist/agents/utils.cjs.map +1 -1
  28. package/dist/agents/utils.js +11 -4
  29. package/dist/agents/utils.js.map +1 -1
  30. package/dist/browser.cjs +3 -0
  31. package/dist/browser.d.cts +2 -1
  32. package/dist/browser.d.ts +2 -1
  33. package/dist/browser.js +3 -1
  34. package/dist/index.cjs +3 -0
  35. package/dist/index.d.cts +2 -1
  36. package/dist/index.d.ts +2 -1
  37. package/dist/index.js +3 -1
  38. package/package.json +15 -15
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # langchain
2
2
 
3
+ ## 1.5.4
4
+
5
+ ### Patch Changes
6
+
7
+ - [#11201](https://github.com/langchain-ai/langchainjs/pull/11201) [`a8cd4d9`](https://github.com/langchain-ai/langchainjs/commit/a8cd4d9ae35ae8ae05e011115a351d976560ade9) Thanks [@hntrl](https://github.com/hntrl)! - feat(langchain): add middleware for handling tool execution errors
8
+
9
+ ## 1.5.3
10
+
11
+ ### Patch Changes
12
+
13
+ - [#11167](https://github.com/langchain-ai/langchainjs/pull/11167) [`4c7a06e`](https://github.com/langchain-ai/langchainjs/commit/4c7a06ec3e4728bb036a28f678dd8ec2521e1c82) Thanks [@colifran](https://github.com/colifran)! - fix(langchain): malformed tool input schemas are unrecoverable
14
+
3
15
  ## 1.5.2
4
16
 
5
17
  ### Patch Changes
@@ -32,6 +32,7 @@ var StructuredOutputParsingError = class extends Error {
32
32
  * Raised when a tool call is throwing an error.
33
33
  */
34
34
  var ToolInvocationError = class extends Error {
35
+ "~brand" = "ToolInvocationError";
35
36
  toolCall;
36
37
  toolError;
37
38
  constructor(toolError, toolCall) {
@@ -41,6 +42,14 @@ var ToolInvocationError = class extends Error {
41
42
  this.toolCall = toolCall;
42
43
  this.toolError = error;
43
44
  }
45
+ /**
46
+ * Check if the error is a ToolInvocationError.
47
+ * @param error - The error to check
48
+ * @returns Whether the error is a ToolInvocationError
49
+ */
50
+ static isInstance(error) {
51
+ return error instanceof Error && "~brand" in error && error["~brand"] === "ToolInvocationError";
52
+ }
44
53
  };
45
54
  /**
46
55
  * Error thrown when a middleware fails.
@@ -49,7 +58,7 @@ var ToolInvocationError = class extends Error {
49
58
  * to ensure that GraphBubbleUp errors (like GraphInterrupt) are never wrapped.
50
59
  */
51
60
  var MiddlewareError = class MiddlewareError extends Error {
52
- static "~brand" = "MiddlewareError";
61
+ "~brand" = "MiddlewareError";
53
62
  constructor(error, middlewareName) {
54
63
  const errorMessage = error instanceof Error ? error.message : String(error);
55
64
  super(errorMessage);
@@ -1 +1 @@
1
- {"version":3,"file":"errors.cjs","names":[],"sources":["../../src/agents/errors.ts"],"sourcesContent":["/* oxlint-disable no-instanceof/no-instanceof */\nimport type { ToolCall } from \"@langchain/core/messages/tool\";\nimport { isGraphBubbleUp } from \"@langchain/langgraph\";\n\nexport class MultipleToolsBoundError extends Error {\n constructor() {\n super(\n \"The provided LLM already has bound tools. \" +\n \"Please provide an LLM without bound tools to createAgent. \" +\n \"The agent will bind the tools provided in the 'tools' parameter.\"\n );\n }\n}\n\n/**\n * Raised when model returns multiple structured output tool calls when only one is expected.\n */\nexport class MultipleStructuredOutputsError extends Error {\n public readonly toolNames: string[];\n\n constructor(toolNames: string[]) {\n super(\n `The model has called multiple tools: ${toolNames.join(\n \", \"\n )} to return a structured output. ` +\n \"This is not supported. Please provide a single structured output.\"\n );\n this.toolNames = toolNames;\n }\n}\n\n/**\n * Raised when structured output tool call arguments fail to parse according to the schema.\n */\nexport class StructuredOutputParsingError extends Error {\n public readonly toolName: string;\n\n public readonly errors: string[];\n\n constructor(toolName: string, errors: string[]) {\n super(\n `Failed to parse structured output for tool '${toolName}':${errors\n .map((e) => `\\n - ${e}`)\n .join(\"\")}.`\n );\n this.toolName = toolName;\n this.errors = errors;\n }\n}\n\n/**\n * Raised when a tool call is throwing an error.\n */\nexport class ToolInvocationError extends Error {\n public readonly toolCall: ToolCall;\n\n public readonly toolError: Error;\n\n constructor(toolError: unknown, toolCall: ToolCall) {\n const error =\n toolError instanceof Error ? toolError : new Error(String(toolError));\n const toolArgs = JSON.stringify(toolCall.args);\n super(\n `Error invoking tool '${toolCall.name}' with kwargs ${toolArgs} with error: ${error.stack}\\n Please fix the error and try again.`\n );\n\n this.toolCall = toolCall;\n this.toolError = error;\n }\n}\n\n/**\n * Error thrown when a middleware fails.\n *\n * Use `MiddlewareError.wrap()` to create instances. The constructor is private\n * to ensure that GraphBubbleUp errors (like GraphInterrupt) are never wrapped.\n */\nexport class MiddlewareError extends Error {\n static readonly \"~brand\" = \"MiddlewareError\";\n\n private constructor(error: unknown, middlewareName: string) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n super(errorMessage);\n this.name =\n error instanceof Error\n ? error.name\n : `${middlewareName[0].toUpperCase() + middlewareName.slice(1)}Error`;\n\n if (error instanceof Error) {\n this.cause = error;\n }\n }\n\n /**\n * Wrap an error in a MiddlewareError, unless it's a GraphBubbleUp error\n * (like GraphInterrupt) which should propagate unchanged.\n *\n * @param error - The error to wrap\n * @param middlewareName - The name of the middleware that threw the error\n * @returns The original error if it's a GraphBubbleUp, otherwise a new MiddlewareError\n */\n static wrap(error: unknown, middlewareName: string): Error {\n // Don't wrap GraphBubbleUp errors (GraphInterrupt, NodeInterrupt, etc.)\n // These are control flow mechanisms that need to bubble up unchanged\n if (isGraphBubbleUp(error)) {\n return error;\n }\n return new MiddlewareError(error, middlewareName);\n }\n\n /**\n * Check if the error is a MiddlewareError.\n * @param error - The error to check\n * @returns Whether the error is a MiddlewareError\n */\n static isInstance(error: unknown): error is MiddlewareError {\n return (\n error instanceof Error &&\n \"~brand\" in error &&\n error[\"~brand\"] === \"MiddlewareError\"\n );\n }\n}\n"],"mappings":";;;AAIA,IAAa,0BAAb,cAA6C,MAAM;CACjD,cAAc;AACZ,QACE,uKAGD;;;;;;AAOL,IAAa,iCAAb,cAAoD,MAAM;CACxD;CAEA,YAAY,WAAqB;AAC/B,QACE,wCAAwC,UAAU,KAChD,KACD,CAAC,mGAEH;AACD,OAAK,YAAY;;;;;;AAOrB,IAAa,+BAAb,cAAkD,MAAM;CACtD;CAEA;CAEA,YAAY,UAAkB,QAAkB;AAC9C,QACE,+CAA+C,SAAS,IAAI,OACzD,KAAK,MAAM,SAAS,IAAI,CACxB,KAAK,GAAG,CAAC,GACb;AACD,OAAK,WAAW;AAChB,OAAK,SAAS;;;;;;AAOlB,IAAa,sBAAb,cAAyC,MAAM;CAC7C;CAEA;CAEA,YAAY,WAAoB,UAAoB;EAClD,MAAM,QACJ,qBAAqB,QAAQ,YAAY,IAAI,MAAM,OAAO,UAAU,CAAC;EACvE,MAAM,WAAW,KAAK,UAAU,SAAS,KAAK;AAC9C,QACE,wBAAwB,SAAS,KAAK,gBAAgB,SAAS,eAAe,MAAM,MAAM,wCAC3F;AAED,OAAK,WAAW;AAChB,OAAK,YAAY;;;;;;;;;AAUrB,IAAa,kBAAb,MAAa,wBAAwB,MAAM;CACzC,OAAgB,WAAW;CAE3B,YAAoB,OAAgB,gBAAwB;EAC1D,MAAM,eAAe,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;AAC3E,QAAM,aAAa;AACnB,OAAK,OACH,iBAAiB,QACb,MAAM,OACN,GAAG,eAAe,GAAG,aAAa,GAAG,eAAe,MAAM,EAAE,CAAC;AAEnE,MAAI,iBAAiB,MACnB,MAAK,QAAQ;;;;;;;;;;CAYjB,OAAO,KAAK,OAAgB,gBAA+B;AAGzD,OAAA,GAAA,qBAAA,iBAAoB,MAAM,CACxB,QAAO;AAET,SAAO,IAAI,gBAAgB,OAAO,eAAe;;;;;;;CAQnD,OAAO,WAAW,OAA0C;AAC1D,SACE,iBAAiB,SACjB,YAAY,SACZ,MAAM,cAAc"}
1
+ {"version":3,"file":"errors.cjs","names":[],"sources":["../../src/agents/errors.ts"],"sourcesContent":["/* oxlint-disable no-instanceof/no-instanceof */\nimport type { ToolCall } from \"@langchain/core/messages/tool\";\nimport { isGraphBubbleUp } from \"@langchain/langgraph\";\n\nexport class MultipleToolsBoundError extends Error {\n constructor() {\n super(\n \"The provided LLM already has bound tools. \" +\n \"Please provide an LLM without bound tools to createAgent. \" +\n \"The agent will bind the tools provided in the 'tools' parameter.\"\n );\n }\n}\n\n/**\n * Raised when model returns multiple structured output tool calls when only one is expected.\n */\nexport class MultipleStructuredOutputsError extends Error {\n public readonly toolNames: string[];\n\n constructor(toolNames: string[]) {\n super(\n `The model has called multiple tools: ${toolNames.join(\n \", \"\n )} to return a structured output. ` +\n \"This is not supported. Please provide a single structured output.\"\n );\n this.toolNames = toolNames;\n }\n}\n\n/**\n * Raised when structured output tool call arguments fail to parse according to the schema.\n */\nexport class StructuredOutputParsingError extends Error {\n public readonly toolName: string;\n\n public readonly errors: string[];\n\n constructor(toolName: string, errors: string[]) {\n super(\n `Failed to parse structured output for tool '${toolName}':${errors\n .map((e) => `\\n - ${e}`)\n .join(\"\")}.`\n );\n this.toolName = toolName;\n this.errors = errors;\n }\n}\n\n/**\n * Raised when a tool call is throwing an error.\n */\nexport class ToolInvocationError extends Error {\n readonly \"~brand\" = \"ToolInvocationError\";\n\n public readonly toolCall: ToolCall;\n\n public readonly toolError: Error;\n\n constructor(toolError: unknown, toolCall: ToolCall) {\n const error =\n toolError instanceof Error ? toolError : new Error(String(toolError));\n const toolArgs = JSON.stringify(toolCall.args);\n super(\n `Error invoking tool '${toolCall.name}' with kwargs ${toolArgs} with error: ${error.stack}\\n Please fix the error and try again.`\n );\n\n this.toolCall = toolCall;\n this.toolError = error;\n }\n\n /**\n * Check if the error is a ToolInvocationError.\n * @param error - The error to check\n * @returns Whether the error is a ToolInvocationError\n */\n static isInstance(error: unknown): error is ToolInvocationError {\n return (\n error instanceof Error &&\n \"~brand\" in error &&\n error[\"~brand\"] === \"ToolInvocationError\"\n );\n }\n}\n\n/**\n * Error thrown when a middleware fails.\n *\n * Use `MiddlewareError.wrap()` to create instances. The constructor is private\n * to ensure that GraphBubbleUp errors (like GraphInterrupt) are never wrapped.\n */\nexport class MiddlewareError extends Error {\n readonly \"~brand\" = \"MiddlewareError\";\n\n private constructor(error: unknown, middlewareName: string) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n super(errorMessage);\n this.name =\n error instanceof Error\n ? error.name\n : `${middlewareName[0].toUpperCase() + middlewareName.slice(1)}Error`;\n\n if (error instanceof Error) {\n this.cause = error;\n }\n }\n\n /**\n * Wrap an error in a MiddlewareError, unless it's a GraphBubbleUp error\n * (like GraphInterrupt) which should propagate unchanged.\n *\n * @param error - The error to wrap\n * @param middlewareName - The name of the middleware that threw the error\n * @returns The original error if it's a GraphBubbleUp, otherwise a new MiddlewareError\n */\n static wrap(error: unknown, middlewareName: string): Error {\n // Don't wrap GraphBubbleUp errors (GraphInterrupt, NodeInterrupt, etc.)\n // These are control flow mechanisms that need to bubble up unchanged\n if (isGraphBubbleUp(error)) {\n return error;\n }\n return new MiddlewareError(error, middlewareName);\n }\n\n /**\n * Check if the error is a MiddlewareError.\n * @param error - The error to check\n * @returns Whether the error is a MiddlewareError\n */\n static isInstance(error: unknown): error is MiddlewareError {\n return (\n error instanceof Error &&\n \"~brand\" in error &&\n error[\"~brand\"] === \"MiddlewareError\"\n );\n }\n}\n"],"mappings":";;;AAIA,IAAa,0BAAb,cAA6C,MAAM;CACjD,cAAc;AACZ,QACE,uKAGD;;;;;;AAOL,IAAa,iCAAb,cAAoD,MAAM;CACxD;CAEA,YAAY,WAAqB;AAC/B,QACE,wCAAwC,UAAU,KAChD,KACD,CAAC,mGAEH;AACD,OAAK,YAAY;;;;;;AAOrB,IAAa,+BAAb,cAAkD,MAAM;CACtD;CAEA;CAEA,YAAY,UAAkB,QAAkB;AAC9C,QACE,+CAA+C,SAAS,IAAI,OACzD,KAAK,MAAM,SAAS,IAAI,CACxB,KAAK,GAAG,CAAC,GACb;AACD,OAAK,WAAW;AAChB,OAAK,SAAS;;;;;;AAOlB,IAAa,sBAAb,cAAyC,MAAM;CAC7C,WAAoB;CAEpB;CAEA;CAEA,YAAY,WAAoB,UAAoB;EAClD,MAAM,QACJ,qBAAqB,QAAQ,YAAY,IAAI,MAAM,OAAO,UAAU,CAAC;EACvE,MAAM,WAAW,KAAK,UAAU,SAAS,KAAK;AAC9C,QACE,wBAAwB,SAAS,KAAK,gBAAgB,SAAS,eAAe,MAAM,MAAM,wCAC3F;AAED,OAAK,WAAW;AAChB,OAAK,YAAY;;;;;;;CAQnB,OAAO,WAAW,OAA8C;AAC9D,SACE,iBAAiB,SACjB,YAAY,SACZ,MAAM,cAAc;;;;;;;;;AAW1B,IAAa,kBAAb,MAAa,wBAAwB,MAAM;CACzC,WAAoB;CAEpB,YAAoB,OAAgB,gBAAwB;EAC1D,MAAM,eAAe,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;AAC3E,QAAM,aAAa;AACnB,OAAK,OACH,iBAAiB,QACb,MAAM,OACN,GAAG,eAAe,GAAG,aAAa,GAAG,eAAe,MAAM,EAAE,CAAC;AAEnE,MAAI,iBAAiB,MACnB,MAAK,QAAQ;;;;;;;;;;CAYjB,OAAO,KAAK,OAAgB,gBAA+B;AAGzD,OAAA,GAAA,qBAAA,iBAAoB,MAAM,CACxB,QAAO;AAET,SAAO,IAAI,gBAAgB,OAAO,eAAe;;;;;;;CAQnD,OAAO,WAAW,OAA0C;AAC1D,SACE,iBAAiB,SACjB,YAAY,SACZ,MAAM,cAAc"}
@@ -23,9 +23,16 @@ declare class StructuredOutputParsingError extends Error {
23
23
  * Raised when a tool call is throwing an error.
24
24
  */
25
25
  declare class ToolInvocationError extends Error {
26
+ readonly "~brand" = "ToolInvocationError";
26
27
  readonly toolCall: ToolCall;
27
28
  readonly toolError: Error;
28
29
  constructor(toolError: unknown, toolCall: ToolCall);
30
+ /**
31
+ * Check if the error is a ToolInvocationError.
32
+ * @param error - The error to check
33
+ * @returns Whether the error is a ToolInvocationError
34
+ */
35
+ static isInstance(error: unknown): error is ToolInvocationError;
29
36
  }
30
37
  /**
31
38
  * Error thrown when a middleware fails.
@@ -34,7 +41,7 @@ declare class ToolInvocationError extends Error {
34
41
  * to ensure that GraphBubbleUp errors (like GraphInterrupt) are never wrapped.
35
42
  */
36
43
  declare class MiddlewareError extends Error {
37
- static readonly "~brand" = "MiddlewareError";
44
+ readonly "~brand" = "MiddlewareError";
38
45
  private constructor();
39
46
  /**
40
47
  * Wrap an error in a MiddlewareError, unless it's a GraphBubbleUp error
@@ -1 +1 @@
1
- {"version":3,"file":"errors.d.cts","names":[],"sources":["../../src/agents/errors.ts"],"mappings":";;;cAIa,uBAAA,SAAgC,KAAA;EAC3C,WAAA,CAAA;AAAA;;;;cAYW,8BAAA,SAAuC,KAAA;EAAA,SAClC,SAAA;EAEhB,WAAA,CAAY,SAAA;AAAA;;;;cAcD,4BAAA,SAAqC,KAAA;EAAA,SAChC,QAAA;EAAA,SAEA,MAAA;EAEhB,WAAA,CAAY,QAAA,UAAkB,MAAA;AAAA;;;;cAcnB,mBAAA,SAA4B,KAAA;EAAA,SACvB,QAAA,EAAU,QAAA;EAAA,SAEV,SAAA,EAAW,KAAA;EAE3B,WAAA,CAAY,SAAA,WAAoB,QAAA,EAAU,QAAA;AAAA;;;;AAL5C;;;cAwBa,eAAA,SAAwB,KAAA;EAAA;EAAA,QAG5B,WAAA,CAAA;EA3BgC;;;;;;;;EAAA,OAgDhC,IAAA,CAAK,KAAA,WAAgB,cAAA,WAAyB,KAAA;EA3CzC;;;;;EAAA,OAyDL,UAAA,CAAW,KAAA,YAAiB,KAAA,IAAS,eAAA;AAAA"}
1
+ {"version":3,"file":"errors.d.cts","names":[],"sources":["../../src/agents/errors.ts"],"mappings":";;;cAIa,uBAAA,SAAgC,KAAA;EAC3C,WAAA,CAAA;AAAA;;;;cAYW,8BAAA,SAAuC,KAAA;EAAA,SAClC,SAAA;EAEhB,WAAA,CAAY,SAAA;AAAA;;;;cAcD,4BAAA,SAAqC,KAAA;EAAA,SAChC,QAAA;EAAA,SAEA,MAAA;EAEhB,WAAA,CAAY,QAAA,UAAkB,MAAA;AAAA;;;;cAcnB,mBAAA,SAA4B,KAAA;EAAA;EAAA,SAGvB,QAAA,EAAU,QAAA;EAAA,SAEV,SAAA,EAAW,KAAA;EAE3B,WAAA,CAAY,SAAA,WAAoB,QAAA,EAAU,QAAA;EArBZ;;;AAchC;;EAdgC,OAsCvB,UAAA,CAAW,KAAA,YAAiB,KAAA,IAAS,mBAAA;AAAA;;;;;;;cAejC,eAAA,SAAwB,KAAA;EAAA;EAAA,QAG5B,WAAA,CAAA;EArCS;;;;;;;;EAAA,OA0DT,IAAA,CAAK,KAAA,WAAgB,cAAA,WAAyB,KAAA;EAvCT;;;AAe9C;;EAf8C,OAqDrC,UAAA,CAAW,KAAA,YAAiB,KAAA,IAAS,eAAA;AAAA"}
@@ -23,9 +23,16 @@ declare class StructuredOutputParsingError extends Error {
23
23
  * Raised when a tool call is throwing an error.
24
24
  */
25
25
  declare class ToolInvocationError extends Error {
26
+ readonly "~brand" = "ToolInvocationError";
26
27
  readonly toolCall: ToolCall;
27
28
  readonly toolError: Error;
28
29
  constructor(toolError: unknown, toolCall: ToolCall);
30
+ /**
31
+ * Check if the error is a ToolInvocationError.
32
+ * @param error - The error to check
33
+ * @returns Whether the error is a ToolInvocationError
34
+ */
35
+ static isInstance(error: unknown): error is ToolInvocationError;
29
36
  }
30
37
  /**
31
38
  * Error thrown when a middleware fails.
@@ -34,7 +41,7 @@ declare class ToolInvocationError extends Error {
34
41
  * to ensure that GraphBubbleUp errors (like GraphInterrupt) are never wrapped.
35
42
  */
36
43
  declare class MiddlewareError extends Error {
37
- static readonly "~brand" = "MiddlewareError";
44
+ readonly "~brand" = "MiddlewareError";
38
45
  private constructor();
39
46
  /**
40
47
  * Wrap an error in a MiddlewareError, unless it's a GraphBubbleUp error
@@ -1 +1 @@
1
- {"version":3,"file":"errors.d.ts","names":[],"sources":["../../src/agents/errors.ts"],"mappings":";;;cAIa,uBAAA,SAAgC,KAAA;EAC3C,WAAA,CAAA;AAAA;;;;cAYW,8BAAA,SAAuC,KAAA;EAAA,SAClC,SAAA;EAEhB,WAAA,CAAY,SAAA;AAAA;;;;cAcD,4BAAA,SAAqC,KAAA;EAAA,SAChC,QAAA;EAAA,SAEA,MAAA;EAEhB,WAAA,CAAY,QAAA,UAAkB,MAAA;AAAA;;;;cAcnB,mBAAA,SAA4B,KAAA;EAAA,SACvB,QAAA,EAAU,QAAA;EAAA,SAEV,SAAA,EAAW,KAAA;EAE3B,WAAA,CAAY,SAAA,WAAoB,QAAA,EAAU,QAAA;AAAA;;;;AAL5C;;;cAwBa,eAAA,SAAwB,KAAA;EAAA;EAAA,QAG5B,WAAA,CAAA;EA3BgC;;;;;;;;EAAA,OAgDhC,IAAA,CAAK,KAAA,WAAgB,cAAA,WAAyB,KAAA;EA3CzC;;;;;EAAA,OAyDL,UAAA,CAAW,KAAA,YAAiB,KAAA,IAAS,eAAA;AAAA"}
1
+ {"version":3,"file":"errors.d.ts","names":[],"sources":["../../src/agents/errors.ts"],"mappings":";;;cAIa,uBAAA,SAAgC,KAAA;EAC3C,WAAA,CAAA;AAAA;;;;cAYW,8BAAA,SAAuC,KAAA;EAAA,SAClC,SAAA;EAEhB,WAAA,CAAY,SAAA;AAAA;;;;cAcD,4BAAA,SAAqC,KAAA;EAAA,SAChC,QAAA;EAAA,SAEA,MAAA;EAEhB,WAAA,CAAY,QAAA,UAAkB,MAAA;AAAA;;;;cAcnB,mBAAA,SAA4B,KAAA;EAAA;EAAA,SAGvB,QAAA,EAAU,QAAA;EAAA,SAEV,SAAA,EAAW,KAAA;EAE3B,WAAA,CAAY,SAAA,WAAoB,QAAA,EAAU,QAAA;EArBZ;;;AAchC;;EAdgC,OAsCvB,UAAA,CAAW,KAAA,YAAiB,KAAA,IAAS,mBAAA;AAAA;;;;;;;cAejC,eAAA,SAAwB,KAAA;EAAA;EAAA,QAG5B,WAAA,CAAA;EArCS;;;;;;;;EAAA,OA0DT,IAAA,CAAK,KAAA,WAAgB,cAAA,WAAyB,KAAA;EAvCT;;;AAe9C;;EAf8C,OAqDrC,UAAA,CAAW,KAAA,YAAiB,KAAA,IAAS,eAAA;AAAA"}
@@ -31,6 +31,7 @@ var StructuredOutputParsingError = class extends Error {
31
31
  * Raised when a tool call is throwing an error.
32
32
  */
33
33
  var ToolInvocationError = class extends Error {
34
+ "~brand" = "ToolInvocationError";
34
35
  toolCall;
35
36
  toolError;
36
37
  constructor(toolError, toolCall) {
@@ -40,6 +41,14 @@ var ToolInvocationError = class extends Error {
40
41
  this.toolCall = toolCall;
41
42
  this.toolError = error;
42
43
  }
44
+ /**
45
+ * Check if the error is a ToolInvocationError.
46
+ * @param error - The error to check
47
+ * @returns Whether the error is a ToolInvocationError
48
+ */
49
+ static isInstance(error) {
50
+ return error instanceof Error && "~brand" in error && error["~brand"] === "ToolInvocationError";
51
+ }
43
52
  };
44
53
  /**
45
54
  * Error thrown when a middleware fails.
@@ -48,7 +57,7 @@ var ToolInvocationError = class extends Error {
48
57
  * to ensure that GraphBubbleUp errors (like GraphInterrupt) are never wrapped.
49
58
  */
50
59
  var MiddlewareError = class MiddlewareError extends Error {
51
- static "~brand" = "MiddlewareError";
60
+ "~brand" = "MiddlewareError";
52
61
  constructor(error, middlewareName) {
53
62
  const errorMessage = error instanceof Error ? error.message : String(error);
54
63
  super(errorMessage);
@@ -1 +1 @@
1
- {"version":3,"file":"errors.js","names":[],"sources":["../../src/agents/errors.ts"],"sourcesContent":["/* oxlint-disable no-instanceof/no-instanceof */\nimport type { ToolCall } from \"@langchain/core/messages/tool\";\nimport { isGraphBubbleUp } from \"@langchain/langgraph\";\n\nexport class MultipleToolsBoundError extends Error {\n constructor() {\n super(\n \"The provided LLM already has bound tools. \" +\n \"Please provide an LLM without bound tools to createAgent. \" +\n \"The agent will bind the tools provided in the 'tools' parameter.\"\n );\n }\n}\n\n/**\n * Raised when model returns multiple structured output tool calls when only one is expected.\n */\nexport class MultipleStructuredOutputsError extends Error {\n public readonly toolNames: string[];\n\n constructor(toolNames: string[]) {\n super(\n `The model has called multiple tools: ${toolNames.join(\n \", \"\n )} to return a structured output. ` +\n \"This is not supported. Please provide a single structured output.\"\n );\n this.toolNames = toolNames;\n }\n}\n\n/**\n * Raised when structured output tool call arguments fail to parse according to the schema.\n */\nexport class StructuredOutputParsingError extends Error {\n public readonly toolName: string;\n\n public readonly errors: string[];\n\n constructor(toolName: string, errors: string[]) {\n super(\n `Failed to parse structured output for tool '${toolName}':${errors\n .map((e) => `\\n - ${e}`)\n .join(\"\")}.`\n );\n this.toolName = toolName;\n this.errors = errors;\n }\n}\n\n/**\n * Raised when a tool call is throwing an error.\n */\nexport class ToolInvocationError extends Error {\n public readonly toolCall: ToolCall;\n\n public readonly toolError: Error;\n\n constructor(toolError: unknown, toolCall: ToolCall) {\n const error =\n toolError instanceof Error ? toolError : new Error(String(toolError));\n const toolArgs = JSON.stringify(toolCall.args);\n super(\n `Error invoking tool '${toolCall.name}' with kwargs ${toolArgs} with error: ${error.stack}\\n Please fix the error and try again.`\n );\n\n this.toolCall = toolCall;\n this.toolError = error;\n }\n}\n\n/**\n * Error thrown when a middleware fails.\n *\n * Use `MiddlewareError.wrap()` to create instances. The constructor is private\n * to ensure that GraphBubbleUp errors (like GraphInterrupt) are never wrapped.\n */\nexport class MiddlewareError extends Error {\n static readonly \"~brand\" = \"MiddlewareError\";\n\n private constructor(error: unknown, middlewareName: string) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n super(errorMessage);\n this.name =\n error instanceof Error\n ? error.name\n : `${middlewareName[0].toUpperCase() + middlewareName.slice(1)}Error`;\n\n if (error instanceof Error) {\n this.cause = error;\n }\n }\n\n /**\n * Wrap an error in a MiddlewareError, unless it's a GraphBubbleUp error\n * (like GraphInterrupt) which should propagate unchanged.\n *\n * @param error - The error to wrap\n * @param middlewareName - The name of the middleware that threw the error\n * @returns The original error if it's a GraphBubbleUp, otherwise a new MiddlewareError\n */\n static wrap(error: unknown, middlewareName: string): Error {\n // Don't wrap GraphBubbleUp errors (GraphInterrupt, NodeInterrupt, etc.)\n // These are control flow mechanisms that need to bubble up unchanged\n if (isGraphBubbleUp(error)) {\n return error;\n }\n return new MiddlewareError(error, middlewareName);\n }\n\n /**\n * Check if the error is a MiddlewareError.\n * @param error - The error to check\n * @returns Whether the error is a MiddlewareError\n */\n static isInstance(error: unknown): error is MiddlewareError {\n return (\n error instanceof Error &&\n \"~brand\" in error &&\n error[\"~brand\"] === \"MiddlewareError\"\n );\n }\n}\n"],"mappings":";;AAIA,IAAa,0BAAb,cAA6C,MAAM;CACjD,cAAc;AACZ,QACE,uKAGD;;;;;;AAOL,IAAa,iCAAb,cAAoD,MAAM;CACxD;CAEA,YAAY,WAAqB;AAC/B,QACE,wCAAwC,UAAU,KAChD,KACD,CAAC,mGAEH;AACD,OAAK,YAAY;;;;;;AAOrB,IAAa,+BAAb,cAAkD,MAAM;CACtD;CAEA;CAEA,YAAY,UAAkB,QAAkB;AAC9C,QACE,+CAA+C,SAAS,IAAI,OACzD,KAAK,MAAM,SAAS,IAAI,CACxB,KAAK,GAAG,CAAC,GACb;AACD,OAAK,WAAW;AAChB,OAAK,SAAS;;;;;;AAOlB,IAAa,sBAAb,cAAyC,MAAM;CAC7C;CAEA;CAEA,YAAY,WAAoB,UAAoB;EAClD,MAAM,QACJ,qBAAqB,QAAQ,YAAY,IAAI,MAAM,OAAO,UAAU,CAAC;EACvE,MAAM,WAAW,KAAK,UAAU,SAAS,KAAK;AAC9C,QACE,wBAAwB,SAAS,KAAK,gBAAgB,SAAS,eAAe,MAAM,MAAM,wCAC3F;AAED,OAAK,WAAW;AAChB,OAAK,YAAY;;;;;;;;;AAUrB,IAAa,kBAAb,MAAa,wBAAwB,MAAM;CACzC,OAAgB,WAAW;CAE3B,YAAoB,OAAgB,gBAAwB;EAC1D,MAAM,eAAe,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;AAC3E,QAAM,aAAa;AACnB,OAAK,OACH,iBAAiB,QACb,MAAM,OACN,GAAG,eAAe,GAAG,aAAa,GAAG,eAAe,MAAM,EAAE,CAAC;AAEnE,MAAI,iBAAiB,MACnB,MAAK,QAAQ;;;;;;;;;;CAYjB,OAAO,KAAK,OAAgB,gBAA+B;AAGzD,MAAI,gBAAgB,MAAM,CACxB,QAAO;AAET,SAAO,IAAI,gBAAgB,OAAO,eAAe;;;;;;;CAQnD,OAAO,WAAW,OAA0C;AAC1D,SACE,iBAAiB,SACjB,YAAY,SACZ,MAAM,cAAc"}
1
+ {"version":3,"file":"errors.js","names":[],"sources":["../../src/agents/errors.ts"],"sourcesContent":["/* oxlint-disable no-instanceof/no-instanceof */\nimport type { ToolCall } from \"@langchain/core/messages/tool\";\nimport { isGraphBubbleUp } from \"@langchain/langgraph\";\n\nexport class MultipleToolsBoundError extends Error {\n constructor() {\n super(\n \"The provided LLM already has bound tools. \" +\n \"Please provide an LLM without bound tools to createAgent. \" +\n \"The agent will bind the tools provided in the 'tools' parameter.\"\n );\n }\n}\n\n/**\n * Raised when model returns multiple structured output tool calls when only one is expected.\n */\nexport class MultipleStructuredOutputsError extends Error {\n public readonly toolNames: string[];\n\n constructor(toolNames: string[]) {\n super(\n `The model has called multiple tools: ${toolNames.join(\n \", \"\n )} to return a structured output. ` +\n \"This is not supported. Please provide a single structured output.\"\n );\n this.toolNames = toolNames;\n }\n}\n\n/**\n * Raised when structured output tool call arguments fail to parse according to the schema.\n */\nexport class StructuredOutputParsingError extends Error {\n public readonly toolName: string;\n\n public readonly errors: string[];\n\n constructor(toolName: string, errors: string[]) {\n super(\n `Failed to parse structured output for tool '${toolName}':${errors\n .map((e) => `\\n - ${e}`)\n .join(\"\")}.`\n );\n this.toolName = toolName;\n this.errors = errors;\n }\n}\n\n/**\n * Raised when a tool call is throwing an error.\n */\nexport class ToolInvocationError extends Error {\n readonly \"~brand\" = \"ToolInvocationError\";\n\n public readonly toolCall: ToolCall;\n\n public readonly toolError: Error;\n\n constructor(toolError: unknown, toolCall: ToolCall) {\n const error =\n toolError instanceof Error ? toolError : new Error(String(toolError));\n const toolArgs = JSON.stringify(toolCall.args);\n super(\n `Error invoking tool '${toolCall.name}' with kwargs ${toolArgs} with error: ${error.stack}\\n Please fix the error and try again.`\n );\n\n this.toolCall = toolCall;\n this.toolError = error;\n }\n\n /**\n * Check if the error is a ToolInvocationError.\n * @param error - The error to check\n * @returns Whether the error is a ToolInvocationError\n */\n static isInstance(error: unknown): error is ToolInvocationError {\n return (\n error instanceof Error &&\n \"~brand\" in error &&\n error[\"~brand\"] === \"ToolInvocationError\"\n );\n }\n}\n\n/**\n * Error thrown when a middleware fails.\n *\n * Use `MiddlewareError.wrap()` to create instances. The constructor is private\n * to ensure that GraphBubbleUp errors (like GraphInterrupt) are never wrapped.\n */\nexport class MiddlewareError extends Error {\n readonly \"~brand\" = \"MiddlewareError\";\n\n private constructor(error: unknown, middlewareName: string) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n super(errorMessage);\n this.name =\n error instanceof Error\n ? error.name\n : `${middlewareName[0].toUpperCase() + middlewareName.slice(1)}Error`;\n\n if (error instanceof Error) {\n this.cause = error;\n }\n }\n\n /**\n * Wrap an error in a MiddlewareError, unless it's a GraphBubbleUp error\n * (like GraphInterrupt) which should propagate unchanged.\n *\n * @param error - The error to wrap\n * @param middlewareName - The name of the middleware that threw the error\n * @returns The original error if it's a GraphBubbleUp, otherwise a new MiddlewareError\n */\n static wrap(error: unknown, middlewareName: string): Error {\n // Don't wrap GraphBubbleUp errors (GraphInterrupt, NodeInterrupt, etc.)\n // These are control flow mechanisms that need to bubble up unchanged\n if (isGraphBubbleUp(error)) {\n return error;\n }\n return new MiddlewareError(error, middlewareName);\n }\n\n /**\n * Check if the error is a MiddlewareError.\n * @param error - The error to check\n * @returns Whether the error is a MiddlewareError\n */\n static isInstance(error: unknown): error is MiddlewareError {\n return (\n error instanceof Error &&\n \"~brand\" in error &&\n error[\"~brand\"] === \"MiddlewareError\"\n );\n }\n}\n"],"mappings":";;AAIA,IAAa,0BAAb,cAA6C,MAAM;CACjD,cAAc;AACZ,QACE,uKAGD;;;;;;AAOL,IAAa,iCAAb,cAAoD,MAAM;CACxD;CAEA,YAAY,WAAqB;AAC/B,QACE,wCAAwC,UAAU,KAChD,KACD,CAAC,mGAEH;AACD,OAAK,YAAY;;;;;;AAOrB,IAAa,+BAAb,cAAkD,MAAM;CACtD;CAEA;CAEA,YAAY,UAAkB,QAAkB;AAC9C,QACE,+CAA+C,SAAS,IAAI,OACzD,KAAK,MAAM,SAAS,IAAI,CACxB,KAAK,GAAG,CAAC,GACb;AACD,OAAK,WAAW;AAChB,OAAK,SAAS;;;;;;AAOlB,IAAa,sBAAb,cAAyC,MAAM;CAC7C,WAAoB;CAEpB;CAEA;CAEA,YAAY,WAAoB,UAAoB;EAClD,MAAM,QACJ,qBAAqB,QAAQ,YAAY,IAAI,MAAM,OAAO,UAAU,CAAC;EACvE,MAAM,WAAW,KAAK,UAAU,SAAS,KAAK;AAC9C,QACE,wBAAwB,SAAS,KAAK,gBAAgB,SAAS,eAAe,MAAM,MAAM,wCAC3F;AAED,OAAK,WAAW;AAChB,OAAK,YAAY;;;;;;;CAQnB,OAAO,WAAW,OAA8C;AAC9D,SACE,iBAAiB,SACjB,YAAY,SACZ,MAAM,cAAc;;;;;;;;;AAW1B,IAAa,kBAAb,MAAa,wBAAwB,MAAM;CACzC,WAAoB;CAEpB,YAAoB,OAAgB,gBAAwB;EAC1D,MAAM,eAAe,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;AAC3E,QAAM,aAAa;AACnB,OAAK,OACH,iBAAiB,QACb,MAAM,OACN,GAAG,eAAe,GAAG,aAAa,GAAG,eAAe,MAAM,EAAE,CAAC;AAEnE,MAAI,iBAAiB,MACnB,MAAK,QAAQ;;;;;;;;;;CAYjB,OAAO,KAAK,OAAgB,gBAA+B;AAGzD,MAAI,gBAAgB,MAAM,CACxB,QAAO;AAET,SAAO,IAAI,gBAAgB,OAAO,eAAe;;;;;;;CAQnD,OAAO,WAAW,OAA0C;AAC1D,SACE,iBAAiB,SACjB,YAAY,SACZ,MAAM,cAAc"}
@@ -12,6 +12,7 @@ require("./modelCallLimit.cjs");
12
12
  require("./modelFallback.cjs");
13
13
  require("./modelRetry.cjs");
14
14
  require("./toolRetry.cjs");
15
+ require("./toolError.cjs");
15
16
  require("./toolEmulator.cjs");
16
17
  require("./providerToolSearch.cjs");
17
18
  require("./provider/openai/moderation.cjs");
@@ -12,6 +12,7 @@ import { ModelCallLimitMiddlewareConfig, modelCallLimitMiddleware } from "./mode
12
12
  import { modelFallbackMiddleware } from "./modelFallback.cjs";
13
13
  import { ModelRetryMiddlewareConfig, modelRetryMiddleware } from "./modelRetry.cjs";
14
14
  import { ToolRetryMiddlewareConfig, toolRetryMiddleware } from "./toolRetry.cjs";
15
+ import { ToolErrorHandler, ToolErrorMiddlewareConfig, toolErrorMiddleware } from "./toolError.cjs";
15
16
  import { ToolEmulatorOptions, toolEmulatorMiddleware } from "./toolEmulator.cjs";
16
17
  import { ProviderToolSearchMiddlewareConfig, providerToolSearchMiddleware } from "./providerToolSearch.cjs";
17
18
  import { OpenAIModerationMiddlewareOptions, openAIModerationMiddleware } from "./provider/openai/moderation.cjs";
@@ -12,6 +12,7 @@ import { ModelCallLimitMiddlewareConfig, modelCallLimitMiddleware } from "./mode
12
12
  import { modelFallbackMiddleware } from "./modelFallback.js";
13
13
  import { ModelRetryMiddlewareConfig, modelRetryMiddleware } from "./modelRetry.js";
14
14
  import { ToolRetryMiddlewareConfig, toolRetryMiddleware } from "./toolRetry.js";
15
+ import { ToolErrorHandler, ToolErrorMiddlewareConfig, toolErrorMiddleware } from "./toolError.js";
15
16
  import { ToolEmulatorOptions, toolEmulatorMiddleware } from "./toolEmulator.js";
16
17
  import { ProviderToolSearchMiddlewareConfig, providerToolSearchMiddleware } from "./providerToolSearch.js";
17
18
  import { OpenAIModerationMiddlewareOptions, openAIModerationMiddleware } from "./provider/openai/moderation.js";
@@ -12,6 +12,7 @@ import "./modelCallLimit.js";
12
12
  import "./modelFallback.js";
13
13
  import "./modelRetry.js";
14
14
  import "./toolRetry.js";
15
+ import "./toolError.js";
15
16
  import "./toolEmulator.js";
16
17
  import "./providerToolSearch.js";
17
18
  import "./provider/openai/moderation.js";
@@ -0,0 +1,68 @@
1
+ require("../../_virtual/_rolldown/runtime.cjs");
2
+ const require_middleware = require("../middleware.cjs");
3
+ let _langchain_core_messages = require("@langchain/core/messages");
4
+ let _langchain_langgraph = require("@langchain/langgraph");
5
+ //#region src/agents/middleware/toolError.ts
6
+ /**
7
+ * Tool error middleware for agents.
8
+ */
9
+ /**
10
+ * Converts selected tool execution errors into error `ToolMessage`s.
11
+ *
12
+ * Handling is opt-in: {@link ToolErrorMiddlewareConfig.onError} must return
13
+ * content for an error to be sent to the model. Returning nothing propagates
14
+ * the original error unchanged. LangGraph control-flow signals always
15
+ * propagate and are never passed to `onError`.
16
+ *
17
+ * Prefer returning content that identifies the error type without including
18
+ * the raw error message, which may contain sensitive or internal details.
19
+ *
20
+ * This middleware does not retry. To retry before handling an error, place
21
+ * `toolRetryMiddleware({ onFailure: "error" })` after this middleware.
22
+ *
23
+ * @example
24
+ * ```ts
25
+ * import { createAgent, toolErrorMiddleware } from "langchain";
26
+ *
27
+ * const agent = createAgent({
28
+ * model,
29
+ * tools: [searchTool],
30
+ * middleware: [
31
+ * toolErrorMiddleware({
32
+ * onError: (error, request) => {
33
+ * if (error instanceof TypeError) {
34
+ * return `Tool '${request.toolCall.name}' failed with TypeError.`;
35
+ * }
36
+ * },
37
+ * }),
38
+ * ],
39
+ * });
40
+ * ```
41
+ */
42
+ function toolErrorMiddleware(config) {
43
+ const toolFilter = config.tools?.map((tool) => typeof tool === "string" ? tool : tool.name);
44
+ return require_middleware.createMiddleware({
45
+ name: "toolErrorMiddleware",
46
+ wrapToolCall: async (request, handler) => {
47
+ const toolName = request.tool?.name ?? request.toolCall.name;
48
+ if (toolFilter !== void 0 && !toolFilter.includes(toolName)) return handler(request);
49
+ try {
50
+ return await handler(request);
51
+ } catch (error) {
52
+ if ((0, _langchain_langgraph.isGraphBubbleUp)(error)) throw error;
53
+ const content = await config.onError(error, request);
54
+ if (content === void 0) throw error;
55
+ return new _langchain_core_messages.ToolMessage({
56
+ content,
57
+ tool_call_id: request.toolCall.id ?? "",
58
+ ...typeof toolName === "string" ? { name: toolName } : {},
59
+ status: "error"
60
+ });
61
+ }
62
+ }
63
+ });
64
+ }
65
+ //#endregion
66
+ exports.toolErrorMiddleware = toolErrorMiddleware;
67
+
68
+ //# sourceMappingURL=toolError.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"toolError.cjs","names":["createMiddleware","ToolMessage"],"sources":["../../../src/agents/middleware/toolError.ts"],"sourcesContent":["/**\n * Tool error middleware for agents.\n */\nimport { ToolMessage, type MessageContent } from \"@langchain/core/messages\";\nimport type { ClientTool, ServerTool } from \"@langchain/core/tools\";\nimport { isGraphBubbleUp } from \"@langchain/langgraph\";\n\nimport { createMiddleware } from \"../middleware.js\";\nimport type { ToolCallRequest } from \"./types.js\";\n\n/**\n * Handler called when tool execution throws.\n *\n * Return content to surface the error to the model as an error `ToolMessage`.\n * Return nothing to propagate the original error.\n */\nexport type ToolErrorHandler = (\n error: unknown,\n request: ToolCallRequest\n) => MessageContent | void | Promise<MessageContent | void>;\n\n/**\n * Configuration for {@link toolErrorMiddleware}.\n */\nexport interface ToolErrorMiddlewareConfig {\n /**\n * Handler called when tool execution throws. Return content to convert the\n * error into an error `ToolMessage`, or return nothing to propagate it.\n */\n onError: ToolErrorHandler;\n\n /**\n * Optional tools or tool names to handle errors for. Handles all tools when\n * omitted.\n */\n tools?: Array<ClientTool | ServerTool | string>;\n}\n\n/**\n * Converts selected tool execution errors into error `ToolMessage`s.\n *\n * Handling is opt-in: {@link ToolErrorMiddlewareConfig.onError} must return\n * content for an error to be sent to the model. Returning nothing propagates\n * the original error unchanged. LangGraph control-flow signals always\n * propagate and are never passed to `onError`.\n *\n * Prefer returning content that identifies the error type without including\n * the raw error message, which may contain sensitive or internal details.\n *\n * This middleware does not retry. To retry before handling an error, place\n * `toolRetryMiddleware({ onFailure: \"error\" })` after this middleware.\n *\n * @example\n * ```ts\n * import { createAgent, toolErrorMiddleware } from \"langchain\";\n *\n * const agent = createAgent({\n * model,\n * tools: [searchTool],\n * middleware: [\n * toolErrorMiddleware({\n * onError: (error, request) => {\n * if (error instanceof TypeError) {\n * return `Tool '${request.toolCall.name}' failed with TypeError.`;\n * }\n * },\n * }),\n * ],\n * });\n * ```\n */\nexport function toolErrorMiddleware(config: ToolErrorMiddlewareConfig) {\n const toolFilter = config.tools?.map((tool) =>\n typeof tool === \"string\" ? tool : tool.name\n );\n\n return createMiddleware({\n name: \"toolErrorMiddleware\",\n wrapToolCall: async (request, handler) => {\n const toolName = request.tool?.name ?? request.toolCall.name;\n\n if (toolFilter !== undefined && !toolFilter.includes(toolName)) {\n return handler(request);\n }\n\n try {\n return await handler(request);\n } catch (error: unknown) {\n if (isGraphBubbleUp(error)) {\n throw error;\n }\n\n const content = await config.onError(error, request);\n if (content === undefined) {\n throw error;\n }\n\n return new ToolMessage({\n content,\n tool_call_id: request.toolCall.id ?? \"\",\n ...(typeof toolName === \"string\" ? { name: toolName } : {}),\n status: \"error\",\n });\n }\n },\n });\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAuEA,SAAgB,oBAAoB,QAAmC;CACrE,MAAM,aAAa,OAAO,OAAO,KAAK,SACpC,OAAO,SAAS,WAAW,OAAO,KAAK,KACxC;AAED,QAAOA,mBAAAA,iBAAiB;EACtB,MAAM;EACN,cAAc,OAAO,SAAS,YAAY;GACxC,MAAM,WAAW,QAAQ,MAAM,QAAQ,QAAQ,SAAS;AAExD,OAAI,eAAe,KAAA,KAAa,CAAC,WAAW,SAAS,SAAS,CAC5D,QAAO,QAAQ,QAAQ;AAGzB,OAAI;AACF,WAAO,MAAM,QAAQ,QAAQ;YACtB,OAAgB;AACvB,SAAA,GAAA,qBAAA,iBAAoB,MAAM,CACxB,OAAM;IAGR,MAAM,UAAU,MAAM,OAAO,QAAQ,OAAO,QAAQ;AACpD,QAAI,YAAY,KAAA,EACd,OAAM;AAGR,WAAO,IAAIC,yBAAAA,YAAY;KACrB;KACA,cAAc,QAAQ,SAAS,MAAM;KACrC,GAAI,OAAO,aAAa,WAAW,EAAE,MAAM,UAAU,GAAG,EAAE;KAC1D,QAAQ;KACT,CAAC;;;EAGP,CAAC"}
@@ -0,0 +1,64 @@
1
+ import { AgentMiddleware, ToolCallRequest } from "./types.cjs";
2
+ import { MessageContent } from "@langchain/core/messages";
3
+ import { ClientTool, ServerTool } from "@langchain/core/tools";
4
+
5
+ //#region src/agents/middleware/toolError.d.ts
6
+ /**
7
+ * Handler called when tool execution throws.
8
+ *
9
+ * Return content to surface the error to the model as an error `ToolMessage`.
10
+ * Return nothing to propagate the original error.
11
+ */
12
+ type ToolErrorHandler = (error: unknown, request: ToolCallRequest) => MessageContent | void | Promise<MessageContent | void>;
13
+ /**
14
+ * Configuration for {@link toolErrorMiddleware}.
15
+ */
16
+ interface ToolErrorMiddlewareConfig {
17
+ /**
18
+ * Handler called when tool execution throws. Return content to convert the
19
+ * error into an error `ToolMessage`, or return nothing to propagate it.
20
+ */
21
+ onError: ToolErrorHandler;
22
+ /**
23
+ * Optional tools or tool names to handle errors for. Handles all tools when
24
+ * omitted.
25
+ */
26
+ tools?: Array<ClientTool | ServerTool | string>;
27
+ }
28
+ /**
29
+ * Converts selected tool execution errors into error `ToolMessage`s.
30
+ *
31
+ * Handling is opt-in: {@link ToolErrorMiddlewareConfig.onError} must return
32
+ * content for an error to be sent to the model. Returning nothing propagates
33
+ * the original error unchanged. LangGraph control-flow signals always
34
+ * propagate and are never passed to `onError`.
35
+ *
36
+ * Prefer returning content that identifies the error type without including
37
+ * the raw error message, which may contain sensitive or internal details.
38
+ *
39
+ * This middleware does not retry. To retry before handling an error, place
40
+ * `toolRetryMiddleware({ onFailure: "error" })` after this middleware.
41
+ *
42
+ * @example
43
+ * ```ts
44
+ * import { createAgent, toolErrorMiddleware } from "langchain";
45
+ *
46
+ * const agent = createAgent({
47
+ * model,
48
+ * tools: [searchTool],
49
+ * middleware: [
50
+ * toolErrorMiddleware({
51
+ * onError: (error, request) => {
52
+ * if (error instanceof TypeError) {
53
+ * return `Tool '${request.toolCall.name}' failed with TypeError.`;
54
+ * }
55
+ * },
56
+ * }),
57
+ * ],
58
+ * });
59
+ * ```
60
+ */
61
+ declare function toolErrorMiddleware(config: ToolErrorMiddlewareConfig): AgentMiddleware<undefined, undefined, unknown, readonly (ServerTool | ClientTool)[], readonly []>;
62
+ //#endregion
63
+ export { ToolErrorHandler, ToolErrorMiddlewareConfig, toolErrorMiddleware };
64
+ //# sourceMappingURL=toolError.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"toolError.d.cts","names":[],"sources":["../../../src/agents/middleware/toolError.ts"],"mappings":";;;;;;;;;;;KAgBY,gBAAA,IACV,KAAA,WACA,OAAA,EAAS,eAAA,KACN,cAAA,UAAwB,OAAA,CAAQ,cAAA;;;;UAKpB,yBAAA;EALZ;;;;EAUH,OAAA,EAAS,gBAAA;EALM;;;;EAWf,KAAA,GAAQ,KAAA,CAAM,UAAA,GAAa,UAAA;AAAA;;;;;;;;;;;;AAoC7B;;;;;;;;;;;;;;;;;;;;;;iBAAgB,mBAAA,CAAoB,MAAA,EAAQ,yBAAA,GAAyB,eAAA,0CAAA,UAAA,GAAA,UAAA"}
@@ -0,0 +1,64 @@
1
+ import { AgentMiddleware, ToolCallRequest } from "./types.js";
2
+ import { MessageContent } from "@langchain/core/messages";
3
+ import { ClientTool, ServerTool } from "@langchain/core/tools";
4
+
5
+ //#region src/agents/middleware/toolError.d.ts
6
+ /**
7
+ * Handler called when tool execution throws.
8
+ *
9
+ * Return content to surface the error to the model as an error `ToolMessage`.
10
+ * Return nothing to propagate the original error.
11
+ */
12
+ type ToolErrorHandler = (error: unknown, request: ToolCallRequest) => MessageContent | void | Promise<MessageContent | void>;
13
+ /**
14
+ * Configuration for {@link toolErrorMiddleware}.
15
+ */
16
+ interface ToolErrorMiddlewareConfig {
17
+ /**
18
+ * Handler called when tool execution throws. Return content to convert the
19
+ * error into an error `ToolMessage`, or return nothing to propagate it.
20
+ */
21
+ onError: ToolErrorHandler;
22
+ /**
23
+ * Optional tools or tool names to handle errors for. Handles all tools when
24
+ * omitted.
25
+ */
26
+ tools?: Array<ClientTool | ServerTool | string>;
27
+ }
28
+ /**
29
+ * Converts selected tool execution errors into error `ToolMessage`s.
30
+ *
31
+ * Handling is opt-in: {@link ToolErrorMiddlewareConfig.onError} must return
32
+ * content for an error to be sent to the model. Returning nothing propagates
33
+ * the original error unchanged. LangGraph control-flow signals always
34
+ * propagate and are never passed to `onError`.
35
+ *
36
+ * Prefer returning content that identifies the error type without including
37
+ * the raw error message, which may contain sensitive or internal details.
38
+ *
39
+ * This middleware does not retry. To retry before handling an error, place
40
+ * `toolRetryMiddleware({ onFailure: "error" })` after this middleware.
41
+ *
42
+ * @example
43
+ * ```ts
44
+ * import { createAgent, toolErrorMiddleware } from "langchain";
45
+ *
46
+ * const agent = createAgent({
47
+ * model,
48
+ * tools: [searchTool],
49
+ * middleware: [
50
+ * toolErrorMiddleware({
51
+ * onError: (error, request) => {
52
+ * if (error instanceof TypeError) {
53
+ * return `Tool '${request.toolCall.name}' failed with TypeError.`;
54
+ * }
55
+ * },
56
+ * }),
57
+ * ],
58
+ * });
59
+ * ```
60
+ */
61
+ declare function toolErrorMiddleware(config: ToolErrorMiddlewareConfig): AgentMiddleware<undefined, undefined, unknown, readonly (ServerTool | ClientTool)[], readonly []>;
62
+ //#endregion
63
+ export { ToolErrorHandler, ToolErrorMiddlewareConfig, toolErrorMiddleware };
64
+ //# sourceMappingURL=toolError.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"toolError.d.ts","names":[],"sources":["../../../src/agents/middleware/toolError.ts"],"mappings":";;;;;;;;;;;KAgBY,gBAAA,IACV,KAAA,WACA,OAAA,EAAS,eAAA,KACN,cAAA,UAAwB,OAAA,CAAQ,cAAA;;;;UAKpB,yBAAA;EALZ;;;;EAUH,OAAA,EAAS,gBAAA;EALM;;;;EAWf,KAAA,GAAQ,KAAA,CAAM,UAAA,GAAa,UAAA;AAAA;;;;;;;;;;;;AAoC7B;;;;;;;;;;;;;;;;;;;;;;iBAAgB,mBAAA,CAAoB,MAAA,EAAQ,yBAAA,GAAyB,eAAA,0CAAA,UAAA,GAAA,UAAA"}
@@ -0,0 +1,67 @@
1
+ import { createMiddleware } from "../middleware.js";
2
+ import { ToolMessage } from "@langchain/core/messages";
3
+ import { isGraphBubbleUp } from "@langchain/langgraph";
4
+ //#region src/agents/middleware/toolError.ts
5
+ /**
6
+ * Tool error middleware for agents.
7
+ */
8
+ /**
9
+ * Converts selected tool execution errors into error `ToolMessage`s.
10
+ *
11
+ * Handling is opt-in: {@link ToolErrorMiddlewareConfig.onError} must return
12
+ * content for an error to be sent to the model. Returning nothing propagates
13
+ * the original error unchanged. LangGraph control-flow signals always
14
+ * propagate and are never passed to `onError`.
15
+ *
16
+ * Prefer returning content that identifies the error type without including
17
+ * the raw error message, which may contain sensitive or internal details.
18
+ *
19
+ * This middleware does not retry. To retry before handling an error, place
20
+ * `toolRetryMiddleware({ onFailure: "error" })` after this middleware.
21
+ *
22
+ * @example
23
+ * ```ts
24
+ * import { createAgent, toolErrorMiddleware } from "langchain";
25
+ *
26
+ * const agent = createAgent({
27
+ * model,
28
+ * tools: [searchTool],
29
+ * middleware: [
30
+ * toolErrorMiddleware({
31
+ * onError: (error, request) => {
32
+ * if (error instanceof TypeError) {
33
+ * return `Tool '${request.toolCall.name}' failed with TypeError.`;
34
+ * }
35
+ * },
36
+ * }),
37
+ * ],
38
+ * });
39
+ * ```
40
+ */
41
+ function toolErrorMiddleware(config) {
42
+ const toolFilter = config.tools?.map((tool) => typeof tool === "string" ? tool : tool.name);
43
+ return createMiddleware({
44
+ name: "toolErrorMiddleware",
45
+ wrapToolCall: async (request, handler) => {
46
+ const toolName = request.tool?.name ?? request.toolCall.name;
47
+ if (toolFilter !== void 0 && !toolFilter.includes(toolName)) return handler(request);
48
+ try {
49
+ return await handler(request);
50
+ } catch (error) {
51
+ if (isGraphBubbleUp(error)) throw error;
52
+ const content = await config.onError(error, request);
53
+ if (content === void 0) throw error;
54
+ return new ToolMessage({
55
+ content,
56
+ tool_call_id: request.toolCall.id ?? "",
57
+ ...typeof toolName === "string" ? { name: toolName } : {},
58
+ status: "error"
59
+ });
60
+ }
61
+ }
62
+ });
63
+ }
64
+ //#endregion
65
+ export { toolErrorMiddleware };
66
+
67
+ //# sourceMappingURL=toolError.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"toolError.js","names":[],"sources":["../../../src/agents/middleware/toolError.ts"],"sourcesContent":["/**\n * Tool error middleware for agents.\n */\nimport { ToolMessage, type MessageContent } from \"@langchain/core/messages\";\nimport type { ClientTool, ServerTool } from \"@langchain/core/tools\";\nimport { isGraphBubbleUp } from \"@langchain/langgraph\";\n\nimport { createMiddleware } from \"../middleware.js\";\nimport type { ToolCallRequest } from \"./types.js\";\n\n/**\n * Handler called when tool execution throws.\n *\n * Return content to surface the error to the model as an error `ToolMessage`.\n * Return nothing to propagate the original error.\n */\nexport type ToolErrorHandler = (\n error: unknown,\n request: ToolCallRequest\n) => MessageContent | void | Promise<MessageContent | void>;\n\n/**\n * Configuration for {@link toolErrorMiddleware}.\n */\nexport interface ToolErrorMiddlewareConfig {\n /**\n * Handler called when tool execution throws. Return content to convert the\n * error into an error `ToolMessage`, or return nothing to propagate it.\n */\n onError: ToolErrorHandler;\n\n /**\n * Optional tools or tool names to handle errors for. Handles all tools when\n * omitted.\n */\n tools?: Array<ClientTool | ServerTool | string>;\n}\n\n/**\n * Converts selected tool execution errors into error `ToolMessage`s.\n *\n * Handling is opt-in: {@link ToolErrorMiddlewareConfig.onError} must return\n * content for an error to be sent to the model. Returning nothing propagates\n * the original error unchanged. LangGraph control-flow signals always\n * propagate and are never passed to `onError`.\n *\n * Prefer returning content that identifies the error type without including\n * the raw error message, which may contain sensitive or internal details.\n *\n * This middleware does not retry. To retry before handling an error, place\n * `toolRetryMiddleware({ onFailure: \"error\" })` after this middleware.\n *\n * @example\n * ```ts\n * import { createAgent, toolErrorMiddleware } from \"langchain\";\n *\n * const agent = createAgent({\n * model,\n * tools: [searchTool],\n * middleware: [\n * toolErrorMiddleware({\n * onError: (error, request) => {\n * if (error instanceof TypeError) {\n * return `Tool '${request.toolCall.name}' failed with TypeError.`;\n * }\n * },\n * }),\n * ],\n * });\n * ```\n */\nexport function toolErrorMiddleware(config: ToolErrorMiddlewareConfig) {\n const toolFilter = config.tools?.map((tool) =>\n typeof tool === \"string\" ? tool : tool.name\n );\n\n return createMiddleware({\n name: \"toolErrorMiddleware\",\n wrapToolCall: async (request, handler) => {\n const toolName = request.tool?.name ?? request.toolCall.name;\n\n if (toolFilter !== undefined && !toolFilter.includes(toolName)) {\n return handler(request);\n }\n\n try {\n return await handler(request);\n } catch (error: unknown) {\n if (isGraphBubbleUp(error)) {\n throw error;\n }\n\n const content = await config.onError(error, request);\n if (content === undefined) {\n throw error;\n }\n\n return new ToolMessage({\n content,\n tool_call_id: request.toolCall.id ?? \"\",\n ...(typeof toolName === \"string\" ? { name: toolName } : {}),\n status: \"error\",\n });\n }\n },\n });\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAuEA,SAAgB,oBAAoB,QAAmC;CACrE,MAAM,aAAa,OAAO,OAAO,KAAK,SACpC,OAAO,SAAS,WAAW,OAAO,KAAK,KACxC;AAED,QAAO,iBAAiB;EACtB,MAAM;EACN,cAAc,OAAO,SAAS,YAAY;GACxC,MAAM,WAAW,QAAQ,MAAM,QAAQ,QAAQ,SAAS;AAExD,OAAI,eAAe,KAAA,KAAa,CAAC,WAAW,SAAS,SAAS,CAC5D,QAAO,QAAQ,QAAQ;AAGzB,OAAI;AACF,WAAO,MAAM,QAAQ,QAAQ;YACtB,OAAgB;AACvB,QAAI,gBAAgB,MAAM,CACxB,OAAM;IAGR,MAAM,UAAU,MAAM,OAAO,QAAQ,OAAO,QAAQ;AACpD,QAAI,YAAY,KAAA,EACd,OAAM;AAGR,WAAO,IAAI,YAAY;KACrB;KACA,cAAc,QAAQ,SAAS,MAAM;KACrC,GAAI,OAAO,aAAa,WAAW,EAAE,MAAM,UAAU,GAAG,EAAE;KAC1D,QAAQ;KACT,CAAC;;;EAGP,CAAC"}
@@ -30,7 +30,7 @@ const isSendInput = (input) => typeof input === "object" && input != null && "lg
30
30
  * This allows the LLM to see the error and potentially retry with different arguments.
31
31
  */
32
32
  function defaultHandleToolErrors(error, toolCall) {
33
- if (error instanceof require_errors.ToolInvocationError) return new _langchain_core_messages.ToolMessage({
33
+ if (require_errors.ToolInvocationError.isInstance(error)) return new _langchain_core_messages.ToolMessage({
34
34
  content: error.message,
35
35
  tool_call_id: toolCall.id,
36
36
  name: toolCall.name
@@ -126,33 +126,51 @@ var ToolNode = class extends require_RunnableCallable.RunnableCallable {
126
126
  */
127
127
  if (this.signal?.aborted) throw error;
128
128
  /**
129
+ * A recoverable tool error (e.g. tool-input schema validation) can be
130
+ * rewrapped as a {@link MiddlewareError} with the original error on `.cause`
131
+ * — once per `wrapToolCall` middleware, so it may be nested several layers
132
+ * deep. Walk the cause chain to the root; if it's a {@link ToolInvocationError},
133
+ * unwrap it so the intended `handleToolErrors` self-correction path still
134
+ * applies. Genuine middleware errors stay fatal by default.
135
+ */
136
+ let effectiveError = error;
137
+ let errorFromMiddleware = isMiddlewareError;
138
+ if (isMiddlewareError) {
139
+ let unwrapped = error;
140
+ while (require_errors.MiddlewareError.isInstance(unwrapped)) unwrapped = unwrapped.cause;
141
+ if (require_errors.ToolInvocationError.isInstance(unwrapped)) {
142
+ effectiveError = unwrapped;
143
+ errorFromMiddleware = false;
144
+ }
145
+ }
146
+ /**
129
147
  * If error is from middleware and handleToolErrors is not true, bubble up
130
148
  * (default handler and false both re-raise middleware errors)
131
149
  */
132
- if (isMiddlewareError && this.handleToolErrors !== true) throw error;
150
+ if (errorFromMiddleware && this.handleToolErrors !== true) throw effectiveError;
133
151
  /**
134
152
  * If handleToolErrors is false, throw all errors
135
153
  */
136
- if (!this.handleToolErrors) throw error;
154
+ if (!this.handleToolErrors) throw effectiveError;
137
155
  /**
138
156
  * Apply handleToolErrors to the error
139
157
  */
140
158
  if (typeof this.handleToolErrors === "function") {
141
- const result = this.handleToolErrors(error, call);
159
+ const result = this.handleToolErrors(effectiveError, call);
142
160
  if (result && _langchain_core_messages.ToolMessage.isInstance(result)) return result;
143
161
  /**
144
162
  * `handleToolErrors` returned undefined - re-raise
145
163
  */
146
- throw error;
164
+ throw effectiveError;
147
165
  } else if (this.handleToolErrors) return new _langchain_core_messages.ToolMessage({
148
166
  name: call.name,
149
- content: `${error}\n Please fix your mistakes.`,
167
+ content: `${effectiveError}\n Please fix your mistakes.`,
150
168
  tool_call_id: call.id
151
169
  });
152
170
  /**
153
171
  * Shouldn't reach here, but throw as fallback
154
172
  */
155
- throw error;
173
+ throw effectiveError;
156
174
  }
157
175
  async runTool(call, config, state) {
158
176
  /**