Skip to content

Commit 5202504

Browse files
fix(langchain): update JS docs on toolRetryMiddleware (#1414)
Updates to `toolRetryMiddleware` in JS
1 parent a6b8b31 commit 5202504

File tree

2 files changed

+151
-2
lines changed

2 files changed

+151
-2
lines changed

pipeline/preprocessors/link_map.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -377,6 +377,7 @@ class LinkMap(TypedDict):
377377
"RunsClient.stream": "classes/_langchain_langgraph-sdk.client.RunsClient.html#stream",
378378
"ClearToolUsesEdit": "classes/langchain.index.ClearToolUsesEdit.html",
379379
"ContextEdit": "interfaces/langchain.index.ContextEdit.html",
380+
"toolRetryMiddleware": "functions/langchain.index.toolRetryMiddleware.html",
380381
},
381382
},
382383
]

src/oss/langchain/middleware/built-in.mdx

Lines changed: 150 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -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

14061461
The 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

Comments
 (0)