@@ -1359,11 +1359,28 @@ agent = create_agent(
13591359:::
13601360
13611361:::js
1362- This middleware is only available in Python. For JavaScript/TypeScript, consider implementing retry logic in your tool definitions or using a wrap-style middleware.
1362+ ** API reference:** @[ ` toolRetryMiddleware ` ]
1363+
1364+ ``` typescript
1365+ import { createAgent , toolRetryMiddleware } from " langchain" ;
1366+
1367+ const agent = createAgent ({
1368+ model: " gpt-4o" ,
1369+ tools: [searchTool , databaseTool ],
1370+ middleware: [
1371+ toolRetryMiddleware ({
1372+ maxRetries: 3 ,
1373+ backoffFactor: 2.0 ,
1374+ initialDelayMs: 1000 ,
1375+ }),
1376+ ],
1377+ });
1378+ ```
13631379:::
13641380
13651381<Accordion title = " Configuration options" >
13661382
1383+ :::python
13671384<ParamField body = " max_retries" type = " number" default = " 2" >
13681385 Maximum number of retry attempts after the initial call (3 total attempts with default)
13691386</ParamField >
@@ -1398,13 +1415,52 @@ This middleware is only available in Python. For JavaScript/TypeScript, consider
13981415<ParamField body = " jitter" type = " boolean" default = " true" >
13991416 Whether to add random jitter (` ±25% ` ) to delay to avoid thundering herd
14001417</ParamField >
1418+ :::
1419+
1420+ :::js
1421+ <ParamField body = " maxRetries" type = " number" default = " 2" >
1422+ Maximum number of retry attempts after the initial call (3 total attempts with default). Must be >= 0.
1423+ </ParamField >
1424+
1425+ <ParamField body = " tools" type = " (ClientTool | ServerTool | string)[]" >
1426+ Optional array of tools or tool names to apply retry logic to. Can be a list of ` BaseTool ` instances or tool name strings. If ` undefined ` , applies to all tools.
1427+ </ParamField >
1428+
1429+ <ParamField body = " retryOn" type = " ((error: Error) => boolean) | (new (...args: any[]) => Error)[]" default = " () => true" >
1430+ Either an array of error constructors to retry on, or a function that takes an error and returns ` true ` if it should be retried. Default is to retry on all errors.
1431+ </ParamField >
1432+
1433+ <ParamField body = " onFailure" type = " 'raise' | 'return_message' | ((error: Error) => string)" default = " return_message" >
1434+ Behavior when all retries are exhausted. Options:
1435+ - ` 'return_message' ` (default) - Return a ` ToolMessage ` with error details, allowing the LLM to handle the failure and potentially recover
1436+ - ` 'raise' ` - Re-raise the exception, stopping agent execution
1437+ - Custom function - Function that takes the exception and returns a string for the ` ToolMessage ` content, allowing custom error formatting
1438+ </ParamField >
1439+
1440+ <ParamField body = " backoffFactor" type = " number" default = " 2.0" >
1441+ Multiplier for exponential backoff. Each retry waits ` initialDelayMs * (backoffFactor ** retryNumber) ` milliseconds. Set to ` 0.0 ` for constant delay. Must be >= 0.
1442+ </ParamField >
1443+
1444+ <ParamField body = " initialDelayMs" type = " number" default = " 1000" >
1445+ Initial delay in milliseconds before first retry. Must be >= 0.
1446+ </ParamField >
1447+
1448+ <ParamField body = " maxDelayMs" type = " number" default = " 60000" >
1449+ Maximum delay in milliseconds between retries (caps exponential backoff growth). Must be >= 0.
1450+ </ParamField >
1451+
1452+ <ParamField body = " jitter" type = " boolean" default = " true" >
1453+ Whether to add random jitter (` ±25% ` ) to delay to avoid thundering herd
1454+ </ParamField >
1455+ :::
14011456
14021457</Accordion >
14031458
14041459<Accordion title = " Full example" >
14051460
14061461The middleware automatically retries failed tool calls with exponential backoff.
14071462
1463+ :::python
14081464** Key configuration:**
14091465- ` max_retries ` - Number of retry attempts (default: 2)
14101466- ` backoff_factor ` - Multiplier for exponential backoff (default: 2.0)
@@ -1415,7 +1471,21 @@ The middleware automatically retries failed tool calls with exponential backoff.
14151471** Failure handling:**
14161472- ` on_failure='return_message' ` - Return error message
14171473- ` on_failure='raise' ` - Re-raise exception
1418- - Custom callable - Function returning error message
1474+ - Custom function - Function returning error message
1475+ :::
1476+ :::js
1477+ ** Key configuration:**
1478+ - ` maxRetries ` - Number of retry attempts (default: 2)
1479+ - ` backoffFactor ` - Multiplier for exponential backoff (default: 2.0)
1480+ - ` initialDelayMs ` - Starting delay in milliseconds (default: 1000ms)
1481+ - ` maxDelayMs ` - Cap on delay growth (default: 60000ms)
1482+ - ` jitter ` - Add random variation (default: true)
1483+
1484+ ** Failure handling:**
1485+ - ` onFailure: "return_message" ` - Return error message
1486+ - ` onFailure: "raise" ` - Re-raise exception
1487+ - Custom function - Function returning error message
1488+ :::
14191489
14201490:::python
14211491``` python
@@ -1442,6 +1512,84 @@ agent = create_agent(
14421512```
14431513:::
14441514
1515+ :::js
1516+ ``` typescript
1517+ import { createAgent , toolRetryMiddleware } from " langchain" ;
1518+ import { tool } from " @langchain/core/tools" ;
1519+ import { z } from " zod" ;
1520+
1521+ // Basic usage with default settings (2 retries, exponential backoff)
1522+ const agent = createAgent ({
1523+ model: " gpt-4o" ,
1524+ tools: [searchTool , databaseTool ],
1525+ middleware: [toolRetryMiddleware ()],
1526+ });
1527+
1528+ // Retry specific exceptions only
1529+ const retry = toolRetryMiddleware ({
1530+ maxRetries: 4 ,
1531+ retryOn: [TimeoutError , NetworkError ],
1532+ backoffFactor: 1.5 ,
1533+ });
1534+
1535+ // Custom exception filtering
1536+ function shouldRetry(error : Error ): boolean {
1537+ // Only retry on 5xx errors
1538+ if (error .name === " HTTPError" && " statusCode" in error ) {
1539+ const statusCode = (error as any ).statusCode ;
1540+ return 500 <= statusCode && statusCode < 600 ;
1541+ }
1542+ return false ;
1543+ }
1544+
1545+ const retryWithFilter = toolRetryMiddleware ({
1546+ maxRetries: 3 ,
1547+ retryOn: shouldRetry ,
1548+ });
1549+
1550+ // Apply to specific tools with custom error handling
1551+ const formatError = (error : Error ) =>
1552+ " Database temporarily unavailable. Please try again later." ;
1553+
1554+ const retrySpecificTools = toolRetryMiddleware ({
1555+ maxRetries: 4 ,
1556+ tools: [" search_database" ],
1557+ onFailure: formatError ,
1558+ });
1559+
1560+ // Apply to specific tools using BaseTool instances
1561+ const searchDatabase = tool (
1562+ async ({ query }) => {
1563+ // Search implementation
1564+ return results ;
1565+ },
1566+ {
1567+ name: " search_database" ,
1568+ description: " Search the database" ,
1569+ schema: z .object ({ query: z .string () }),
1570+ }
1571+ );
1572+
1573+ const retryWithToolInstance = toolRetryMiddleware ({
1574+ maxRetries: 4 ,
1575+ tools: [searchDatabase ], // Pass BaseTool instance
1576+ });
1577+
1578+ // Constant backoff (no exponential growth)
1579+ const constantBackoff = toolRetryMiddleware ({
1580+ maxRetries: 5 ,
1581+ backoffFactor: 0.0 , // No exponential growth
1582+ initialDelayMs: 2000 , // Always wait 2 seconds
1583+ });
1584+
1585+ // Raise exception on failure
1586+ const strictRetry = toolRetryMiddleware ({
1587+ maxRetries: 2 ,
1588+ onFailure: " raise" , // Re-raise exception instead of returning message
1589+ });
1590+ ```
1591+ :::
1592+
14451593</Accordion >
14461594
14471595
0 commit comments