Skip to content

Commit 3fa3ea4

Browse files
feat(langchain): add a big tool middleware
1 parent 66d0284 commit 3fa3ea4

File tree

5 files changed

+1268
-4
lines changed

5 files changed

+1268
-4
lines changed
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
import * as z from "zod";
2+
import { createAgent, HumanMessage, AIMessage, tool } from "langchain";
3+
import { bigToolMiddleware } from "langchain/middleware";
4+
import { ChatAnthropic } from "@langchain/anthropic";
5+
6+
/**
7+
* Capture the raw requests to verify the tools are being selected correctly
8+
*/
9+
const requestBodies: any[] = [];
10+
const llm = new ChatAnthropic({
11+
apiKey: process.env.ANTHROPIC_API_KEY,
12+
model: "claude-sonnet-4-20250514",
13+
clientOptions: {
14+
fetch: (url, options) => {
15+
requestBodies.push(JSON.parse(options?.body as string));
16+
return fetch(url, options);
17+
},
18+
},
19+
});
20+
21+
// Example usage
22+
const agent = createAgent({
23+
llm,
24+
tools: [
25+
tool(
26+
({ a, b, operation }: { a: number; b: number; operation: string }) => {
27+
if (operation === "add") {
28+
return a + b;
29+
} else if (operation === "multiply") {
30+
return a * b;
31+
} else if (operation === "subtract") {
32+
return a - b;
33+
} else if (operation === "divide") {
34+
return a / b;
35+
} else {
36+
return "Unknown operation";
37+
}
38+
},
39+
{
40+
name: "calculator",
41+
description: "Perform basic math operations",
42+
schema: z.object({
43+
a: z.number(),
44+
b: z.number(),
45+
operation: z.enum(["add", "multiply", "subtract", "divide"]),
46+
}),
47+
}
48+
),
49+
tool(
50+
() => {
51+
return "Database query result: 42";
52+
},
53+
{
54+
name: "database",
55+
description: "Query a database",
56+
schema: z.object({
57+
query: z.string(),
58+
}),
59+
}
60+
),
61+
],
62+
middleware: [
63+
bigToolMiddleware({
64+
strategy: "custom",
65+
customSelector: (tools, query) => {
66+
if (query.includes("calculator")) {
67+
return tools.filter((tool) => tool.name === "calculator");
68+
} else if (query.includes("database")) {
69+
return tools.filter((tool) => tool.name === "database");
70+
}
71+
72+
return [];
73+
},
74+
maxTools: 1,
75+
}),
76+
] as const,
77+
});
78+
79+
// Usage example with a long chat history for testing caching
80+
const result = await agent.invoke({
81+
messages: [new HumanMessage("Calculate 10 + 20")],
82+
});
83+
console.log(
84+
"Calculate 10 + 20\nAgent response:",
85+
result.messages.at(-1)?.content,
86+
`\nAll available tools: ${requestBodies
87+
.pop()
88+
.tools.map((tool: { name: string }) => tool.name)}`
89+
);
90+
91+
const result2 = await agent.invoke({
92+
messages: [new HumanMessage("Query the database for 42")],
93+
});
94+
console.log(
95+
"\nQuery the database for 42\nAgent response:",
96+
result2.messages.at(-1)?.content,
97+
`\nAll available tools: ${requestBodies
98+
.pop()
99+
.tools.map((tool: { name: string }) => tool.name)}`
100+
);

0 commit comments

Comments
 (0)