Skip to content

Commit ac8b1a8

Browse files
feat(anthropic): implement Anthropic memory tool in provider package (#9406)
1 parent 8f37cb4 commit ac8b1a8

File tree

8 files changed

+668
-5
lines changed

8 files changed

+668
-5
lines changed

libs/providers/langchain-anthropic/README.md

Lines changed: 62 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,65 @@ const response = await model.stream({
7575
});
7676
```
7777

78+
## Tools
79+
80+
This package provides LangChain-compatible wrappers for Anthropic's built-in tools. These tools can be bound to `ChatAnthropic` using `bindTools()` or any [`ReactAgent`](https://docs.langchain.com/oss/javascript/langchain/agents).
81+
82+
### Memory Tool
83+
84+
The memory tool (`memory_20250818`) enables Claude to store and retrieve information across conversations through a memory file directory. Claude can create, read, update, and delete files that persist between sessions, allowing it to build knowledge over time without keeping everything in the context window.
85+
86+
```typescript
87+
import { ChatAnthropic, tools } from "@langchain/anthropic";
88+
89+
// Create a simple in-memory file store (or use your own persistence layer)
90+
const files = new Map<string, string>();
91+
92+
const memory = tools.memory_20250818({
93+
execute: async (command) => {
94+
switch (command.command) {
95+
case "view":
96+
if (!command.path || command.path === "/") {
97+
return Array.from(files.keys()).join("\n") || "Directory is empty.";
98+
}
99+
return (
100+
files.get(command.path) ?? `Error: File not found: ${command.path}`
101+
);
102+
case "create":
103+
files.set(command.path!, command.file_text ?? "");
104+
return `Successfully created file: ${command.path}`;
105+
case "str_replace":
106+
const content = files.get(command.path!);
107+
if (content && command.old_str) {
108+
files.set(
109+
command.path!,
110+
content.replace(command.old_str, command.new_str ?? "")
111+
);
112+
}
113+
return `Successfully replaced text in: ${command.path}`;
114+
case "delete":
115+
files.delete(command.path!);
116+
return `Successfully deleted: ${command.path}`;
117+
// Handle other commands: insert, rename
118+
default:
119+
return `Unknown command`;
120+
}
121+
},
122+
});
123+
124+
const llm = new ChatAnthropic({
125+
model: "claude-sonnet-4-5-20250929",
126+
});
127+
128+
const llmWithMemory = llm.bindTools([memory]);
129+
130+
const response = await llmWithMemory.invoke(
131+
"Remember that my favorite programming language is TypeScript"
132+
);
133+
```
134+
135+
For more information, see [Anthropic's Memory Tool documentation](https://docs.anthropic.com/en/docs/agents-and-tools/tool-use/memory-tool).
136+
78137
## Development
79138

80139
To develop the Anthropic package, you'll need to follow these instructions:
@@ -103,8 +162,8 @@ Test files should live within a `tests/` file in the `src/` folder. Unit tests s
103162
end in `.int.test.ts`:
104163

105164
```bash
106-
$ pnpm test
107-
$ pnpm test:int
165+
pnpm test
166+
pnpm test:int
108167
```
109168

110169
### Lint & Format
@@ -124,5 +183,5 @@ If you add a new file to be exported, either import & re-export from `src/index.
124183
After running `pnpm build`, publish a new version with:
125184

126185
```bash
127-
$ npm publish
186+
npm publish
128187
```

libs/providers/langchain-anthropic/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@
7575
"vectorstores"
7676
],
7777
"main": "./dist/index.cjs",
78+
"module": "./dist/index.js",
7879
"types": "./dist/index.d.cts",
7980
"exports": {
8081
".": {
@@ -95,6 +96,5 @@
9596
"CHANGELOG.md",
9697
"README.md",
9798
"LICENSE"
98-
],
99-
"module": "./dist/index.js"
99+
]
100100
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
export * from "./chat_models.js";
22
export { convertPromptToAnthropic } from "./utils/prompts.js";
33
export { type ChatAnthropicContentBlock } from "./types.js";
4+
export * from "./tools/index.js";
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export { memory_20250818 } from "./memory.js";
2+
export type * from "./types.js";
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
import { tool } from "@langchain/core/tools";
2+
import type { DynamicStructuredTool, ToolRuntime } from "@langchain/core/tools";
3+
4+
import type { MemoryTool20250818Options } from "./types.js";
5+
6+
/**
7+
* Creates an Anthropic memory tool that can be used with ChatAnthropic.
8+
*
9+
* The memory tool enables Claude to store and retrieve information across conversations
10+
* through a memory file directory. Claude can create, read, update, and delete files that
11+
* persist between sessions, allowing it to build knowledge over time without keeping
12+
* everything in the context window.
13+
*
14+
* @example
15+
* ```typescript
16+
* import { ChatAnthropic, memory_20250818 } from "@langchain/anthropic";
17+
*
18+
* const llm = new ChatAnthropic({
19+
* model: "claude-sonnet-4-5-20250929"
20+
* });
21+
*
22+
* const memory = memory_20250818({
23+
* execute: async (args) => {
24+
* // handle memory command execution
25+
* // ...
26+
* },
27+
* });
28+
* const llmWithMemory = llm.bindTools([memory]);
29+
*
30+
* const response = await llmWithMemory.invoke("Remember that I like Python");
31+
* ```
32+
*
33+
* @param options - Optional configuration for the memory tool (currently unused)
34+
* @param options.execute - Optional execute function that handles memory command execution.
35+
* @returns The memory tool object that can be passed to `bindTools`
36+
*
37+
* @see https://docs.anthropic.com/en/docs/agents-and-tools/tool-use/memory-tool
38+
*/
39+
export function memory_20250818(
40+
options?: MemoryTool20250818Options
41+
): DynamicStructuredTool {
42+
const memoryTool = tool(
43+
options?.execute as (
44+
input: unknown,
45+
runtime: ToolRuntime<unknown, unknown>
46+
) => string | Promise<string>,
47+
{
48+
name: "memory",
49+
schema: {
50+
type: "object",
51+
properties: {
52+
command: {
53+
type: "string",
54+
enum: [
55+
"view",
56+
"create",
57+
"str_replace",
58+
"insert",
59+
"delete",
60+
"rename",
61+
],
62+
},
63+
},
64+
required: ["command"],
65+
},
66+
}
67+
);
68+
69+
memoryTool.extras = {
70+
...(memoryTool.extras ?? {}),
71+
providerToolDefinition: {
72+
type: "memory_20250818",
73+
name: "memory",
74+
},
75+
};
76+
77+
return memoryTool;
78+
}

0 commit comments

Comments
 (0)