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.
- package/CHANGELOG.md +12 -0
- package/dist/agents/errors.cjs +10 -1
- package/dist/agents/errors.cjs.map +1 -1
- package/dist/agents/errors.d.cts +8 -1
- package/dist/agents/errors.d.cts.map +1 -1
- package/dist/agents/errors.d.ts +8 -1
- package/dist/agents/errors.d.ts.map +1 -1
- package/dist/agents/errors.js +10 -1
- package/dist/agents/errors.js.map +1 -1
- package/dist/agents/middleware/index.cjs +1 -0
- package/dist/agents/middleware/index.d.cts +1 -0
- package/dist/agents/middleware/index.d.ts +1 -0
- package/dist/agents/middleware/index.js +1 -0
- package/dist/agents/middleware/toolError.cjs +68 -0
- package/dist/agents/middleware/toolError.cjs.map +1 -0
- package/dist/agents/middleware/toolError.d.cts +64 -0
- package/dist/agents/middleware/toolError.d.cts.map +1 -0
- package/dist/agents/middleware/toolError.d.ts +64 -0
- package/dist/agents/middleware/toolError.d.ts.map +1 -0
- package/dist/agents/middleware/toolError.js +67 -0
- package/dist/agents/middleware/toolError.js.map +1 -0
- package/dist/agents/nodes/ToolNode.cjs +25 -7
- package/dist/agents/nodes/ToolNode.cjs.map +1 -1
- package/dist/agents/nodes/ToolNode.js +26 -8
- package/dist/agents/nodes/ToolNode.js.map +1 -1
- package/dist/agents/utils.cjs +11 -4
- package/dist/agents/utils.cjs.map +1 -1
- package/dist/agents/utils.js +11 -4
- package/dist/agents/utils.js.map +1 -1
- package/dist/browser.cjs +3 -0
- package/dist/browser.d.cts +2 -1
- package/dist/browser.d.ts +2 -1
- package/dist/browser.js +3 -1
- package/dist/index.cjs +3 -0
- package/dist/index.d.cts +2 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +3 -1
- 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
|
package/dist/agents/errors.cjs
CHANGED
|
@@ -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
|
-
|
|
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
|
|
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"}
|
package/dist/agents/errors.d.cts
CHANGED
|
@@ -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
|
-
|
|
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,
|
|
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"}
|
package/dist/agents/errors.d.ts
CHANGED
|
@@ -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
|
-
|
|
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,
|
|
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"}
|
package/dist/agents/errors.js
CHANGED
|
@@ -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
|
-
|
|
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
|
|
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";
|
|
@@ -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 (
|
|
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 (
|
|
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
|
|
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(
|
|
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
|
|
164
|
+
throw effectiveError;
|
|
147
165
|
} else if (this.handleToolErrors) return new _langchain_core_messages.ToolMessage({
|
|
148
166
|
name: call.name,
|
|
149
|
-
content: `${
|
|
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
|
|
173
|
+
throw effectiveError;
|
|
156
174
|
}
|
|
157
175
|
async runTool(call, config, state) {
|
|
158
176
|
/**
|