deepagents 1.9.0 → 1.10.0
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/README.md +47 -707
- package/dist/index.cjs +4698 -4141
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +421 -29
- package/dist/index.d.ts +421 -29
- package/dist/index.js +4688 -4132
- package/dist/index.js.map +1 -1
- package/package.json +7 -7
package/README.md
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
<div align="center">
|
|
2
|
-
<a href="https://docs.langchain.com/oss/
|
|
2
|
+
<a href="https://docs.langchain.com/oss/javascript/deepagents/overview#deep-agents-overview">
|
|
3
3
|
<picture>
|
|
4
4
|
<source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/langchain-ai/deepagentsjs/refs/heads/main/.github/images/logo-light.svg">
|
|
5
5
|
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/langchain-ai/deepagentsjs/refs/heads/main/.github/images/logo-dark.svg">
|
|
6
|
-
<img alt="Deep Agents Logo" src="https://raw.githubusercontent.com/langchain-ai/deepagentsjs/refs/heads/main/.github/images/logo-
|
|
6
|
+
<img alt="Deep Agents Logo" src="https://raw.githubusercontent.com/langchain-ai/deepagentsjs/refs/heads/main/.github/images/logo-light.svg" width="50%">
|
|
7
7
|
</picture>
|
|
8
8
|
</a>
|
|
9
9
|
</div>
|
|
@@ -16,752 +16,92 @@
|
|
|
16
16
|
<a href="https://www.npmjs.com/package/deepagents"><img src="https://img.shields.io/npm/v/deepagents.svg" alt="npm version"></a>
|
|
17
17
|
<a href="https://opensource.org/licenses/MIT"><img src="https://img.shields.io/badge/License-MIT-yellow.svg" alt="License: MIT"></a>
|
|
18
18
|
<a href="https://www.typescriptlang.org/"><img src="https://img.shields.io/badge/TypeScript-5.0+-blue.svg" alt="TypeScript"></a>
|
|
19
|
-
<a href="https://x.com/
|
|
19
|
+
<a href="https://x.com/langchain_js" target="_blank"><img src="https://img.shields.io/twitter/url/https/twitter.com/langchain_js.svg?style=social&label=Follow%20%40LangChain_JS" alt="Twitter / X"></a>
|
|
20
20
|
</div>
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
<br>
|
|
23
23
|
|
|
24
|
-
|
|
25
|
-
a **planning tool**, **sub agents**, access to a **file system**, and a **detailed prompt**.
|
|
24
|
+
Deep Agents is an agent harness. An opinionated, ready-to-run agent out of the box. Instead of wiring prompts, tools, and context management yourself, you get a working agent immediately and customize what you need.
|
|
26
25
|
|
|
27
|
-
|
|
26
|
+
**What's included:**
|
|
28
27
|
|
|
29
|
-
|
|
28
|
+
- **Planning** — `write_todos` for task breakdown and progress tracking
|
|
29
|
+
- **Filesystem** — `read_file`, `write_file`, `edit_file`, `ls`, `glob`, `grep` for working memory
|
|
30
|
+
- **Sub-agents** — `task` for delegating work with isolated context windows
|
|
31
|
+
- **Smart defaults** — built-in prompt and middleware that make these tools useful out of the box
|
|
32
|
+
- **Context management** — file-based workflows to keep long tasks manageable
|
|
30
33
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
[Documentation](https://docs.langchain.com/oss/javascript/deepagents/overview) | [Examples](./examples) | [Report Bug](https://github.com/langchain-ai/deepagentsjs/issues) | [Request Feature](https://github.com/langchain-ai/deepagentsjs/issues)
|
|
34
|
-
|
|
35
|
-
</div>
|
|
36
|
-
|
|
37
|
-
## 📖 Overview
|
|
38
|
-
|
|
39
|
-
Using an LLM to call tools in a loop is the simplest form of an agent. However, this architecture can yield agents that are "shallow" and fail to plan and act over longer, more complex tasks.
|
|
40
|
-
|
|
41
|
-
Applications like **Deep Research**, **Manus**, and **Claude Code** have overcome this limitation by implementing a combination of four key components:
|
|
34
|
+
> [!NOTE]
|
|
35
|
+
> Looking for the Python package? See [langchain-ai/deepagents](https://github.com/langchain-ai/deepagents).
|
|
42
36
|
|
|
43
|
-
|
|
44
|
-
2. **Sub-Agents** - Specialized agents for subtasks
|
|
45
|
-
3. **File System Access** - Persistent state and memory
|
|
46
|
-
4. **Detailed Prompts** - Context-rich instructions
|
|
47
|
-
|
|
48
|
-
**Deep Agents** is a TypeScript package that implements these patterns in a general-purpose way, enabling you to easily create sophisticated agents for your applications.
|
|
49
|
-
|
|
50
|
-
## ✨ Features
|
|
51
|
-
|
|
52
|
-
- 🎯 **Task Planning & Decomposition** - Break complex tasks into manageable steps
|
|
53
|
-
- 🤖 **Sub-Agent Architecture** - Delegate specialized work to focused agents
|
|
54
|
-
- 💾 **File System Integration** - Persistent memory and state management
|
|
55
|
-
- 🌊 **Streaming Support** - Real-time updates, token streaming, and progress tracking
|
|
56
|
-
- 🔄 **LangGraph Powered** - Built on the robust LangGraph framework
|
|
57
|
-
- 📝 **TypeScript First** - Full type safety and IntelliSense support
|
|
58
|
-
- 🔌 **Extensible** - Easy to customize and extend for your use case
|
|
59
|
-
|
|
60
|
-
## Installation
|
|
37
|
+
## Quickstart
|
|
61
38
|
|
|
62
39
|
```bash
|
|
63
|
-
# npm
|
|
64
40
|
npm install deepagents
|
|
65
|
-
|
|
66
|
-
# yarn
|
|
67
|
-
yarn add deepagents
|
|
68
|
-
|
|
69
|
-
# pnpm
|
|
41
|
+
# or
|
|
70
42
|
pnpm add deepagents
|
|
43
|
+
# or
|
|
44
|
+
yarn add deepagents
|
|
71
45
|
```
|
|
72
46
|
|
|
73
|
-
## Usage
|
|
74
|
-
|
|
75
|
-
(To run the example below, you will need to `npm install @langchain/tavily`).
|
|
76
|
-
|
|
77
|
-
Make sure to set `TAVILY_API_KEY` in your environment. You can generate one [here](https://www.tavily.com/).
|
|
78
|
-
|
|
79
47
|
```typescript
|
|
80
|
-
import { tool } from "langchain";
|
|
81
|
-
import { TavilySearch } from "@langchain/tavily";
|
|
82
48
|
import { createDeepAgent } from "deepagents";
|
|
83
|
-
import { z } from "zod";
|
|
84
|
-
|
|
85
|
-
// Web search tool
|
|
86
|
-
const internetSearch = tool(
|
|
87
|
-
async ({
|
|
88
|
-
query,
|
|
89
|
-
maxResults = 5,
|
|
90
|
-
topic = "general",
|
|
91
|
-
includeRawContent = false,
|
|
92
|
-
}: {
|
|
93
|
-
query: string;
|
|
94
|
-
maxResults?: number;
|
|
95
|
-
topic?: "general" | "news" | "finance";
|
|
96
|
-
includeRawContent?: boolean;
|
|
97
|
-
}) => {
|
|
98
|
-
const tavilySearch = new TavilySearch({
|
|
99
|
-
maxResults,
|
|
100
|
-
tavilyApiKey: process.env.TAVILY_API_KEY,
|
|
101
|
-
includeRawContent,
|
|
102
|
-
topic,
|
|
103
|
-
});
|
|
104
|
-
return await tavilySearch._call({ query });
|
|
105
|
-
},
|
|
106
|
-
{
|
|
107
|
-
name: "internet_search",
|
|
108
|
-
description: "Run a web search",
|
|
109
|
-
schema: z.object({
|
|
110
|
-
query: z.string().describe("The search query"),
|
|
111
|
-
maxResults: z
|
|
112
|
-
.number()
|
|
113
|
-
.optional()
|
|
114
|
-
.default(5)
|
|
115
|
-
.describe("Maximum number of results to return"),
|
|
116
|
-
topic: z
|
|
117
|
-
.enum(["general", "news", "finance"])
|
|
118
|
-
.optional()
|
|
119
|
-
.default("general")
|
|
120
|
-
.describe("Search topic category"),
|
|
121
|
-
includeRawContent: z
|
|
122
|
-
.boolean()
|
|
123
|
-
.optional()
|
|
124
|
-
.default(false)
|
|
125
|
-
.describe("Whether to include raw content"),
|
|
126
|
-
}),
|
|
127
|
-
},
|
|
128
|
-
);
|
|
129
|
-
|
|
130
|
-
// System prompt to steer the agent to be an expert researcher
|
|
131
|
-
const researchInstructions = `You are an expert researcher. Your job is to conduct thorough research, and then write a polished report.
|
|
132
|
-
|
|
133
|
-
You have access to an internet search tool as your primary means of gathering information.
|
|
134
|
-
|
|
135
|
-
> [!TIP]
|
|
136
|
-
> For developing, debugging, and deploying AI agents and LLM applications, see [LangSmith](https://docs.langchain.com/langsmith/home).
|
|
137
|
-
|
|
138
|
-
## \`internet_search\`
|
|
139
49
|
|
|
140
|
-
|
|
141
|
-
`;
|
|
50
|
+
const agent = createDeepAgent();
|
|
142
51
|
|
|
143
|
-
// Create the deep agent
|
|
144
|
-
const agent = createDeepAgent({
|
|
145
|
-
tools: [internetSearch],
|
|
146
|
-
systemPrompt: researchInstructions,
|
|
147
|
-
});
|
|
148
|
-
|
|
149
|
-
// Invoke the agent
|
|
150
52
|
const result = await agent.invoke({
|
|
151
|
-
messages: [
|
|
152
|
-
});
|
|
153
|
-
```
|
|
154
|
-
|
|
155
|
-
See [examples/research/research-agent.ts](examples/research/research-agent.ts) for a more complex example.
|
|
156
|
-
|
|
157
|
-
The agent created with `createDeepAgent` is just a LangGraph graph - so you can interact with it (streaming, human-in-the-loop, memory, studio)
|
|
158
|
-
in the same way you would any LangGraph agent.
|
|
159
|
-
|
|
160
|
-
## Core Capabilities
|
|
161
|
-
|
|
162
|
-
**Planning & Task Decomposition**
|
|
163
|
-
|
|
164
|
-
Deep Agents include a built-in `write_todos` tool that enables agents to break down complex tasks into discrete steps, track progress, and adapt plans as new information emerges.
|
|
165
|
-
|
|
166
|
-
**Context Management**
|
|
167
|
-
|
|
168
|
-
File system tools (`ls`, `read_file`, `write_file`, `edit_file`, `glob`, `grep`) allow agents to offload large context to memory, preventing context window overflow and enabling work with variable-length tool results.
|
|
169
|
-
|
|
170
|
-
**Subagent Spawning**
|
|
171
|
-
|
|
172
|
-
A built-in `task` tool enables agents to spawn specialized subagents for context isolation. This keeps the main agent's context clean while still going deep on specific subtasks.
|
|
173
|
-
|
|
174
|
-
**Long-term Memory**
|
|
175
|
-
|
|
176
|
-
Extend agents with persistent memory across threads using LangGraph's Store. Agents can save and retrieve information from previous conversations.
|
|
177
|
-
|
|
178
|
-
## Customizing Deep Agents
|
|
179
|
-
|
|
180
|
-
There are several parameters you can pass to `createDeepAgent` to create your own custom deep agent.
|
|
181
|
-
|
|
182
|
-
### `model`
|
|
183
|
-
|
|
184
|
-
By default, `deepagents` uses `"claude-sonnet-4-5-20250929"`. You can customize this by passing any [LangChain model object](https://js.langchain.com/docs/integrations/chat/).
|
|
185
|
-
|
|
186
|
-
```typescript
|
|
187
|
-
import { ChatAnthropic } from "@langchain/anthropic";
|
|
188
|
-
import { ChatOpenAI } from "@langchain/openai";
|
|
189
|
-
import { createDeepAgent } from "deepagents";
|
|
190
|
-
|
|
191
|
-
// Using Anthropic
|
|
192
|
-
const agent = createDeepAgent({
|
|
193
|
-
model: new ChatAnthropic({
|
|
194
|
-
model: "claude-sonnet-4-20250514",
|
|
195
|
-
temperature: 0,
|
|
196
|
-
}),
|
|
197
|
-
});
|
|
198
|
-
|
|
199
|
-
// Using OpenAI
|
|
200
|
-
const agent2 = createDeepAgent({
|
|
201
|
-
model: new ChatOpenAI({
|
|
202
|
-
model: "gpt-5",
|
|
203
|
-
temperature: 0,
|
|
204
|
-
}),
|
|
205
|
-
});
|
|
206
|
-
```
|
|
207
|
-
|
|
208
|
-
### `systemPrompt`
|
|
209
|
-
|
|
210
|
-
Deep Agents come with a built-in system prompt. This is relatively detailed prompt that is heavily based on and inspired by [attempts](https://github.com/kn1026/cc/blob/main/claudecode.md) to [replicate](https://github.com/asgeirtj/system_prompts_leaks/blob/main/Anthropic/claude-code.md)
|
|
211
|
-
Claude Code's system prompt. It was made more general purpose than Claude Code's system prompt. The default prompt contains detailed instructions for how to use the built-in planning tool, file system tools, and sub agents.
|
|
212
|
-
|
|
213
|
-
Each deep agent tailored to a use case should include a custom system prompt specific to that use case as well. The importance of prompting for creating a successful deep agent cannot be overstated.
|
|
214
|
-
|
|
215
|
-
```typescript
|
|
216
|
-
import { createDeepAgent } from "deepagents";
|
|
217
|
-
|
|
218
|
-
const researchInstructions = `You are an expert researcher. Your job is to conduct thorough research, and then write a polished report.`;
|
|
219
|
-
|
|
220
|
-
const agent = createDeepAgent({
|
|
221
|
-
systemPrompt: researchInstructions,
|
|
222
|
-
});
|
|
223
|
-
```
|
|
224
|
-
|
|
225
|
-
### `tools`
|
|
226
|
-
|
|
227
|
-
Just like with tool-calling agents, you can provide a deep agent with a set of tools that it has access to.
|
|
228
|
-
|
|
229
|
-
```typescript
|
|
230
|
-
import { tool } from "langchain";
|
|
231
|
-
import { TavilySearch } from "@langchain/tavily";
|
|
232
|
-
import { createDeepAgent } from "deepagents";
|
|
233
|
-
import { z } from "zod";
|
|
234
|
-
|
|
235
|
-
const internetSearch = tool(
|
|
236
|
-
async ({
|
|
237
|
-
query,
|
|
238
|
-
maxResults = 5,
|
|
239
|
-
topic = "general",
|
|
240
|
-
includeRawContent = false,
|
|
241
|
-
}: {
|
|
242
|
-
query: string;
|
|
243
|
-
maxResults?: number;
|
|
244
|
-
topic?: "general" | "news" | "finance";
|
|
245
|
-
includeRawContent?: boolean;
|
|
246
|
-
}) => {
|
|
247
|
-
const tavilySearch = new TavilySearch({
|
|
248
|
-
maxResults,
|
|
249
|
-
tavilyApiKey: process.env.TAVILY_API_KEY,
|
|
250
|
-
includeRawContent,
|
|
251
|
-
topic,
|
|
252
|
-
});
|
|
253
|
-
return await tavilySearch._call({ query });
|
|
254
|
-
},
|
|
255
|
-
{
|
|
256
|
-
name: "internet_search",
|
|
257
|
-
description: "Run a web search",
|
|
258
|
-
schema: z.object({
|
|
259
|
-
query: z.string().describe("The search query"),
|
|
260
|
-
maxResults: z.number().optional().default(5),
|
|
261
|
-
topic: z
|
|
262
|
-
.enum(["general", "news", "finance"])
|
|
263
|
-
.optional()
|
|
264
|
-
.default("general"),
|
|
265
|
-
includeRawContent: z.boolean().optional().default(false),
|
|
266
|
-
}),
|
|
267
|
-
},
|
|
268
|
-
);
|
|
269
|
-
|
|
270
|
-
const agent = createDeepAgent({
|
|
271
|
-
tools: [internetSearch],
|
|
272
|
-
});
|
|
273
|
-
```
|
|
274
|
-
|
|
275
|
-
### `middleware`
|
|
276
|
-
|
|
277
|
-
`createDeepAgent` is implemented with middleware that can be customized. You can provide additional middleware to extend functionality, add tools, or implement custom hooks.
|
|
278
|
-
|
|
279
|
-
```typescript
|
|
280
|
-
import { tool } from "langchain";
|
|
281
|
-
import { createDeepAgent } from "deepagents";
|
|
282
|
-
import type { AgentMiddleware } from "langchain";
|
|
283
|
-
import { z } from "zod";
|
|
284
|
-
|
|
285
|
-
const getWeather = tool(
|
|
286
|
-
async ({ city }: { city: string }) => {
|
|
287
|
-
return `The weather in ${city} is sunny.`;
|
|
288
|
-
},
|
|
289
|
-
{
|
|
290
|
-
name: "get_weather",
|
|
291
|
-
description: "Get the weather in a city.",
|
|
292
|
-
schema: z.object({
|
|
293
|
-
city: z.string().describe("The city to get weather for"),
|
|
294
|
-
}),
|
|
295
|
-
},
|
|
296
|
-
);
|
|
297
|
-
|
|
298
|
-
const getTemperature = tool(
|
|
299
|
-
async ({ city }: { city: string }) => {
|
|
300
|
-
return `The temperature in ${city} is 70 degrees Fahrenheit.`;
|
|
301
|
-
},
|
|
302
|
-
{
|
|
303
|
-
name: "get_temperature",
|
|
304
|
-
description: "Get the temperature in a city.",
|
|
305
|
-
schema: z.object({
|
|
306
|
-
city: z.string().describe("The city to get temperature for"),
|
|
307
|
-
}),
|
|
308
|
-
},
|
|
309
|
-
);
|
|
310
|
-
|
|
311
|
-
class WeatherMiddleware implements AgentMiddleware {
|
|
312
|
-
tools = [getWeather, getTemperature];
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
const agent = createDeepAgent({
|
|
316
|
-
model: "claude-sonnet-4-20250514",
|
|
317
|
-
middleware: [new WeatherMiddleware()],
|
|
318
|
-
});
|
|
319
|
-
```
|
|
320
|
-
|
|
321
|
-
### `subagents`
|
|
322
|
-
|
|
323
|
-
A main feature of Deep Agents is their ability to spawn subagents. You can specify custom subagents that your agent can hand off work to in the subagents parameter. Sub agents are useful for context quarantine (to help not pollute the overall context of the main agent) as well as custom instructions.
|
|
324
|
-
|
|
325
|
-
`subagents` should be a list of objects that follow the `SubAgent` interface:
|
|
326
|
-
|
|
327
|
-
```typescript
|
|
328
|
-
interface SubAgent {
|
|
329
|
-
name: string;
|
|
330
|
-
description: string;
|
|
331
|
-
systemPrompt: string;
|
|
332
|
-
tools?: StructuredTool[];
|
|
333
|
-
model?: LanguageModelLike | string;
|
|
334
|
-
middleware?: AgentMiddleware[];
|
|
335
|
-
interruptOn?: Record<string, boolean | InterruptOnConfig>;
|
|
336
|
-
skills?: string[];
|
|
337
|
-
}
|
|
338
|
-
```
|
|
339
|
-
|
|
340
|
-
**SubAgent fields:**
|
|
341
|
-
|
|
342
|
-
- **name**: This is the name of the subagent, and how the main agent will call the subagent
|
|
343
|
-
- **description**: This is the description of the subagent that is shown to the main agent
|
|
344
|
-
- **systemPrompt**: This is the prompt used for the subagent
|
|
345
|
-
- **tools**: This is the list of tools that the subagent has access to.
|
|
346
|
-
- **model**: Optional model name or model instance.
|
|
347
|
-
- **middleware**: Additional middleware to attach to the subagent. See [here](https://docs.langchain.com/oss/typescript/langchain/middleware) for an introduction into middleware and how it works with createAgent.
|
|
348
|
-
- **interruptOn**: A custom interrupt config that specifies human-in-the-loop interactions for your tools.
|
|
349
|
-
- **skills**: Skill source paths for the subagent (e.g., `["/skills/research/"]`). See skills inheritance below.
|
|
350
|
-
|
|
351
|
-
#### Skills Inheritance
|
|
352
|
-
|
|
353
|
-
When you configure `skills` on the main agent via `createDeepAgent`, the behavior differs between subagent types:
|
|
354
|
-
|
|
355
|
-
- **General-purpose subagent**: Automatically inherits skills from the main agent. This subagent has access to all the same skills as the main agent.
|
|
356
|
-
- **Custom subagents**: Do NOT inherit skills from the main agent by default. If you want a custom subagent to have access to skills, you must explicitly define the `skills` property on that subagent.
|
|
357
|
-
|
|
358
|
-
```typescript
|
|
359
|
-
const agent = createDeepAgent({
|
|
360
|
-
model: "claude-sonnet-4-20250514",
|
|
361
|
-
skills: ["/skills/"], // Main agent and general-purpose subagent get these skills
|
|
362
|
-
subagents: [
|
|
53
|
+
messages: [
|
|
363
54
|
{
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
systemPrompt: "You are a researcher.",
|
|
367
|
-
// This subagent will NOT have access to /skills/ from the main agent
|
|
368
|
-
},
|
|
369
|
-
{
|
|
370
|
-
name: "coder",
|
|
371
|
-
description: "Coding assistant",
|
|
372
|
-
systemPrompt: "You are a coder.",
|
|
373
|
-
skills: ["/skills/coding/"], // This subagent has its own skills
|
|
55
|
+
role: "user",
|
|
56
|
+
content: "Research LangGraph and write a summary in summary.md",
|
|
374
57
|
},
|
|
375
58
|
],
|
|
376
59
|
});
|
|
377
60
|
```
|
|
378
61
|
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
#### Using SubAgent
|
|
62
|
+
The agent can plan, read/write files, and manage longer tasks with sub-agents and filesystem tools.
|
|
382
63
|
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
import { TavilySearch } from "@langchain/tavily";
|
|
386
|
-
import { createDeepAgent, type SubAgent } from "deepagents";
|
|
387
|
-
import { z } from "zod";
|
|
388
|
-
|
|
389
|
-
const internetSearch = tool(
|
|
390
|
-
async ({
|
|
391
|
-
query,
|
|
392
|
-
maxResults = 5,
|
|
393
|
-
topic = "general",
|
|
394
|
-
includeRawContent = false,
|
|
395
|
-
}: {
|
|
396
|
-
query: string;
|
|
397
|
-
maxResults?: number;
|
|
398
|
-
topic?: "general" | "news" | "finance";
|
|
399
|
-
includeRawContent?: boolean;
|
|
400
|
-
}) => {
|
|
401
|
-
const tavilySearch = new TavilySearch({
|
|
402
|
-
maxResults,
|
|
403
|
-
tavilyApiKey: process.env.TAVILY_API_KEY,
|
|
404
|
-
includeRawContent,
|
|
405
|
-
topic,
|
|
406
|
-
});
|
|
407
|
-
return await tavilySearch._call({ query });
|
|
408
|
-
},
|
|
409
|
-
{
|
|
410
|
-
name: "internet_search",
|
|
411
|
-
description: "Run a web search",
|
|
412
|
-
schema: z.object({
|
|
413
|
-
query: z.string(),
|
|
414
|
-
maxResults: z.number().optional().default(5),
|
|
415
|
-
topic: z
|
|
416
|
-
.enum(["general", "news", "finance"])
|
|
417
|
-
.optional()
|
|
418
|
-
.default("general"),
|
|
419
|
-
includeRawContent: z.boolean().optional().default(false),
|
|
420
|
-
}),
|
|
421
|
-
},
|
|
422
|
-
);
|
|
423
|
-
|
|
424
|
-
const researchSubagent: SubAgent = {
|
|
425
|
-
name: "research-agent",
|
|
426
|
-
description: "Used to research more in depth questions",
|
|
427
|
-
systemPrompt: "You are a great researcher",
|
|
428
|
-
tools: [internetSearch],
|
|
429
|
-
model: "gpt-4o", // Optional override, defaults to main agent model
|
|
430
|
-
};
|
|
431
|
-
|
|
432
|
-
const subagents = [researchSubagent];
|
|
433
|
-
|
|
434
|
-
const agent = createDeepAgent({
|
|
435
|
-
model: "claude-sonnet-4-20250514",
|
|
436
|
-
subagents: subagents,
|
|
437
|
-
});
|
|
438
|
-
```
|
|
439
|
-
|
|
440
|
-
### `interruptOn`
|
|
64
|
+
> [!TIP]
|
|
65
|
+
> For developing, debugging, and deploying AI agents and LLM applications, see [LangSmith](https://docs.langchain.com/langsmith/home).
|
|
441
66
|
|
|
442
|
-
|
|
67
|
+
## Customization
|
|
443
68
|
|
|
444
|
-
|
|
69
|
+
Add tools, swap models, and customize prompts as needed:
|
|
445
70
|
|
|
446
71
|
```typescript
|
|
447
|
-
import {
|
|
72
|
+
import { ChatOpenAI } from "@langchain/openai";
|
|
448
73
|
import { createDeepAgent } from "deepagents";
|
|
449
|
-
import { z } from "zod";
|
|
450
|
-
|
|
451
|
-
const getWeather = tool(
|
|
452
|
-
async ({ city }: { city: string }) => {
|
|
453
|
-
return `The weather in ${city} is sunny.`;
|
|
454
|
-
},
|
|
455
|
-
{
|
|
456
|
-
name: "get_weather",
|
|
457
|
-
description: "Get the weather in a city.",
|
|
458
|
-
schema: z.object({
|
|
459
|
-
city: z.string(),
|
|
460
|
-
}),
|
|
461
|
-
},
|
|
462
|
-
);
|
|
463
74
|
|
|
464
75
|
const agent = createDeepAgent({
|
|
465
|
-
model: "
|
|
466
|
-
tools: [
|
|
467
|
-
|
|
468
|
-
get_weather: {
|
|
469
|
-
allowedDecisions: ["approve", "edit", "reject"],
|
|
470
|
-
},
|
|
471
|
-
},
|
|
472
|
-
});
|
|
473
|
-
```
|
|
474
|
-
|
|
475
|
-
### `backend`
|
|
476
|
-
|
|
477
|
-
Deep Agents use backends to manage file system operations and memory storage. You can configure different backends depending on your needs:
|
|
478
|
-
|
|
479
|
-
```typescript
|
|
480
|
-
import {
|
|
481
|
-
createDeepAgent,
|
|
482
|
-
StateBackend,
|
|
483
|
-
StoreBackend,
|
|
484
|
-
FilesystemBackend,
|
|
485
|
-
LocalShellBackend,
|
|
486
|
-
CompositeBackend,
|
|
487
|
-
} from "deepagents";
|
|
488
|
-
import { MemorySaver } from "@langchain/langgraph";
|
|
489
|
-
import { InMemoryStore } from "@langchain/langgraph-checkpoint";
|
|
490
|
-
|
|
491
|
-
// Default: StateBackend (in-memory, ephemeral)
|
|
492
|
-
const agent1 = createDeepAgent({
|
|
493
|
-
// No backend specified - uses StateBackend by default
|
|
494
|
-
});
|
|
495
|
-
|
|
496
|
-
// StoreBackend: Persistent storage using LangGraph Store
|
|
497
|
-
const agent2 = createDeepAgent({
|
|
498
|
-
backend: (config) => new StoreBackend(config),
|
|
499
|
-
store: new InMemoryStore(), // Provide a store
|
|
500
|
-
checkpointer: new MemorySaver(), // Optional: for conversation persistence
|
|
501
|
-
});
|
|
502
|
-
|
|
503
|
-
// FilesystemBackend: Store files on actual filesystem
|
|
504
|
-
const agent3 = createDeepAgent({
|
|
505
|
-
backend: (config) => new FilesystemBackend({ rootDir: "./agent-workspace" }),
|
|
506
|
-
});
|
|
507
|
-
|
|
508
|
-
// LocalShellBackend: Filesystem access + local shell command execution
|
|
509
|
-
const agent4 = createDeepAgent({
|
|
510
|
-
backend: new LocalShellBackend({
|
|
511
|
-
rootDir: "./agent-workspace",
|
|
512
|
-
inheritEnv: true,
|
|
513
|
-
}),
|
|
514
|
-
});
|
|
515
|
-
|
|
516
|
-
// CompositeBackend: Combine multiple backends
|
|
517
|
-
const agent5 = createDeepAgent({
|
|
518
|
-
backend: (config) =>
|
|
519
|
-
new CompositeBackend({
|
|
520
|
-
state: new StateBackend(config),
|
|
521
|
-
store: config.store ? new StoreBackend(config) : undefined,
|
|
522
|
-
}),
|
|
523
|
-
store: new InMemoryStore(),
|
|
524
|
-
checkpointer: new MemorySaver(),
|
|
76
|
+
model: new ChatOpenAI({ model: "gpt-5", temperature: 0 }),
|
|
77
|
+
tools: [myCustomTool],
|
|
78
|
+
systemPrompt: "You are a research assistant.",
|
|
525
79
|
});
|
|
526
80
|
```
|
|
527
81
|
|
|
528
|
-
See [
|
|
82
|
+
See the [JavaScript Deep Agents docs](https://docs.langchain.com/oss/javascript/deepagents/overview) for full configuration options.
|
|
529
83
|
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
For agents that need to run shell commands, you can create a sandbox backend by extending `BaseSandbox`. This enables the `execute` tool which allows agents to run arbitrary shell commands in an isolated environment.
|
|
533
|
-
|
|
534
|
-
```typescript
|
|
535
|
-
import {
|
|
536
|
-
createDeepAgent,
|
|
537
|
-
BaseSandbox,
|
|
538
|
-
type ExecuteResponse,
|
|
539
|
-
type FileUploadResponse,
|
|
540
|
-
type FileDownloadResponse,
|
|
541
|
-
} from "deepagents";
|
|
542
|
-
import { spawn } from "child_process";
|
|
543
|
-
|
|
544
|
-
// Create a concrete sandbox by extending BaseSandbox
|
|
545
|
-
class LocalShellSandbox extends BaseSandbox {
|
|
546
|
-
readonly id = "local-shell";
|
|
547
|
-
private readonly workingDirectory: string;
|
|
548
|
-
|
|
549
|
-
constructor(workingDirectory: string) {
|
|
550
|
-
super();
|
|
551
|
-
this.workingDirectory = workingDirectory;
|
|
552
|
-
}
|
|
553
|
-
|
|
554
|
-
// Only execute() is required - BaseSandbox implements all file operations
|
|
555
|
-
async execute(command: string): Promise<ExecuteResponse> {
|
|
556
|
-
return new Promise((resolve) => {
|
|
557
|
-
const child = spawn("/bin/bash", ["-c", command], {
|
|
558
|
-
cwd: this.workingDirectory,
|
|
559
|
-
});
|
|
560
|
-
|
|
561
|
-
const chunks: string[] = [];
|
|
562
|
-
child.stdout.on("data", (data) => chunks.push(data.toString()));
|
|
563
|
-
child.stderr.on("data", (data) => chunks.push(data.toString()));
|
|
564
|
-
|
|
565
|
-
child.on("close", (exitCode) => {
|
|
566
|
-
resolve({
|
|
567
|
-
output: chunks.join(""),
|
|
568
|
-
exitCode,
|
|
569
|
-
truncated: false,
|
|
570
|
-
});
|
|
571
|
-
});
|
|
572
|
-
});
|
|
573
|
-
}
|
|
574
|
-
|
|
575
|
-
async uploadFiles(
|
|
576
|
-
files: Array<[string, Uint8Array]>,
|
|
577
|
-
): Promise<FileUploadResponse[]> {
|
|
578
|
-
// Implement file upload logic
|
|
579
|
-
return files.map(([path]) => ({ path, error: null }));
|
|
580
|
-
}
|
|
581
|
-
|
|
582
|
-
async downloadFiles(paths: string[]): Promise<FileDownloadResponse[]> {
|
|
583
|
-
// Implement file download logic
|
|
584
|
-
return paths.map((path) => ({
|
|
585
|
-
path,
|
|
586
|
-
content: null,
|
|
587
|
-
error: "file_not_found",
|
|
588
|
-
}));
|
|
589
|
-
}
|
|
590
|
-
}
|
|
591
|
-
|
|
592
|
-
// Use the sandbox with your agent
|
|
593
|
-
const sandbox = new LocalShellSandbox("./workspace");
|
|
594
|
-
|
|
595
|
-
const agent = createDeepAgent({
|
|
596
|
-
backend: sandbox,
|
|
597
|
-
systemPrompt: "You can run shell commands using the execute tool.",
|
|
598
|
-
});
|
|
599
|
-
```
|
|
84
|
+
## LangGraph Native
|
|
600
85
|
|
|
601
|
-
|
|
86
|
+
`createDeepAgent` returns a compiled [LangGraph](https://docs.langchain.com/oss/javascript/langgraph/overview) graph, so you can use streaming, Studio, checkpointers, and other LangGraph features.
|
|
602
87
|
|
|
603
|
-
|
|
88
|
+
## Why Use It
|
|
604
89
|
|
|
605
|
-
|
|
90
|
+
- **100% open source** — MIT licensed and extensible
|
|
91
|
+
- **Provider agnostic** — works with tool-calling chat models
|
|
92
|
+
- **Built on LangGraph** — production runtime with streaming and persistence
|
|
93
|
+
- **Batteries included** — planning, file access, sub-agents, and defaults out of the box
|
|
94
|
+
- **Fast to start** — install and run with sensible defaults
|
|
95
|
+
- **Easy to customize** — add tools/models/prompts when you need to
|
|
606
96
|
|
|
607
|
-
|
|
97
|
+
---
|
|
608
98
|
|
|
609
|
-
|
|
610
|
-
- A filesystem for storing context and long-term memories
|
|
611
|
-
- The ability to spawn subagents
|
|
99
|
+
## Documentation
|
|
612
100
|
|
|
613
|
-
|
|
101
|
+
- [docs.langchain.com](https://docs.langchain.com/oss/javascript/deepagents/overview) - Concepts and guides
|
|
102
|
+
- [Examples](/examples) - Working agents and patterns
|
|
103
|
+
- [LangChain Forum](https://forum.langchain.com) - Community discussion and support
|
|
614
104
|
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
### TodoListMiddleware
|
|
618
|
-
|
|
619
|
-
Planning is integral to solving complex problems. If you've used claude code recently, you'll notice how it writes out a To-Do list before tackling complex, multi-part tasks. You'll also notice how it can adapt and update this To-Do list on the fly as more information comes in.
|
|
620
|
-
|
|
621
|
-
**todoListMiddleware** provides your agent with a tool specifically for updating this To-Do list. Before, and while it executes a multi-part task, the agent is prompted to use the write_todos tool to keep track of what its doing, and what still needs to be done.
|
|
622
|
-
|
|
623
|
-
```typescript
|
|
624
|
-
import { createAgent, todoListMiddleware } from "langchain";
|
|
625
|
-
|
|
626
|
-
// todoListMiddleware is included by default in createDeepAgent
|
|
627
|
-
// You can customize it if building a custom agent
|
|
628
|
-
const agent = createAgent({
|
|
629
|
-
model: "claude-sonnet-4-20250514",
|
|
630
|
-
middleware: [
|
|
631
|
-
todoListMiddleware({
|
|
632
|
-
// Optional: Custom addition to the system prompt
|
|
633
|
-
systemPrompt: "Use the write_todos tool to...",
|
|
634
|
-
}),
|
|
635
|
-
],
|
|
636
|
-
});
|
|
637
|
-
```
|
|
638
|
-
|
|
639
|
-
### FilesystemMiddleware
|
|
640
|
-
|
|
641
|
-
Context engineering is one of the main challenges in building effective agents. This can be particularly hard when using tools that can return variable length results (ex. web_search, rag), as long ToolResults can quickly fill up your context window.
|
|
642
|
-
|
|
643
|
-
**FilesystemMiddleware** provides tools to your agent to interact with both short-term and long-term memory:
|
|
644
|
-
|
|
645
|
-
- **ls**: List the files in your filesystem
|
|
646
|
-
- **read_file**: Read an entire file, or a certain number of lines from a file
|
|
647
|
-
- **write_file**: Write a new file to your filesystem
|
|
648
|
-
- **edit_file**: Edit an existing file in your filesystem
|
|
649
|
-
- **glob**: Find files matching a pattern
|
|
650
|
-
- **grep**: Search for text within files
|
|
651
|
-
- **execute**: Run shell commands (only available when using a `SandboxBackendProtocol`)
|
|
652
|
-
|
|
653
|
-
```typescript
|
|
654
|
-
import { createAgent } from "langchain";
|
|
655
|
-
import { createFilesystemMiddleware } from "deepagents";
|
|
656
|
-
|
|
657
|
-
// FilesystemMiddleware is included by default in createDeepAgent
|
|
658
|
-
// You can customize it if building a custom agent
|
|
659
|
-
const agent = createAgent({
|
|
660
|
-
model: "claude-sonnet-4-20250514",
|
|
661
|
-
middleware: [
|
|
662
|
-
createFilesystemMiddleware({
|
|
663
|
-
backend: ..., // Optional: customize storage backend
|
|
664
|
-
systemPrompt: "Write to the filesystem when...", // Optional custom system prompt override
|
|
665
|
-
customToolDescriptions: {
|
|
666
|
-
ls: "Use the ls tool when...",
|
|
667
|
-
read_file: "Use the read_file tool to...",
|
|
668
|
-
}, // Optional: Custom descriptions for filesystem tools
|
|
669
|
-
}),
|
|
670
|
-
],
|
|
671
|
-
});
|
|
672
|
-
```
|
|
673
|
-
|
|
674
|
-
### SubAgentMiddleware
|
|
675
|
-
|
|
676
|
-
Handing off tasks to subagents is a great way to isolate context, keeping the context window of the main (supervisor) agent clean while still going deep on a task. The subagents middleware allows you supply subagents through a task tool.
|
|
677
|
-
|
|
678
|
-
A subagent is defined with a name, description, system prompt, and tools. You can also provide a subagent with a custom model, or with additional middleware. This can be particularly useful when you want to give the subagent an additional state key to share with the main agent.
|
|
679
|
-
|
|
680
|
-
```typescript
|
|
681
|
-
import { tool } from "langchain";
|
|
682
|
-
import { createAgent } from "langchain";
|
|
683
|
-
import { createSubAgentMiddleware, type SubAgent } from "deepagents";
|
|
684
|
-
import { z } from "zod";
|
|
685
|
-
|
|
686
|
-
const getWeather = tool(
|
|
687
|
-
async ({ city }: { city: string }) => {
|
|
688
|
-
return `The weather in ${city} is sunny.`;
|
|
689
|
-
},
|
|
690
|
-
{
|
|
691
|
-
name: "get_weather",
|
|
692
|
-
description: "Get the weather in a city.",
|
|
693
|
-
schema: z.object({
|
|
694
|
-
city: z.string(),
|
|
695
|
-
}),
|
|
696
|
-
},
|
|
697
|
-
);
|
|
698
|
-
|
|
699
|
-
const weatherSubagent: SubAgent = {
|
|
700
|
-
name: "weather",
|
|
701
|
-
description: "This subagent can get weather in cities.",
|
|
702
|
-
systemPrompt: "Use the get_weather tool to get the weather in a city.",
|
|
703
|
-
tools: [getWeather],
|
|
704
|
-
model: "gpt-4o",
|
|
705
|
-
middleware: [],
|
|
706
|
-
};
|
|
707
|
-
|
|
708
|
-
const agent = createAgent({
|
|
709
|
-
model: "claude-sonnet-4-20250514",
|
|
710
|
-
middleware: [
|
|
711
|
-
createSubAgentMiddleware({
|
|
712
|
-
defaultModel: "claude-sonnet-4-20250514",
|
|
713
|
-
defaultTools: [],
|
|
714
|
-
subagents: [weatherSubagent],
|
|
715
|
-
}),
|
|
716
|
-
],
|
|
717
|
-
});
|
|
718
|
-
```
|
|
719
|
-
|
|
720
|
-
## ACP (Agent Client Protocol) Support
|
|
721
|
-
|
|
722
|
-
Deep Agents can be exposed as an [Agent Client Protocol](https://agentclientprotocol.com) server, enabling integration with IDEs like [Zed](https://zed.dev), JetBrains, and other ACP-compatible clients through a standardized JSON-RPC 2.0 protocol over stdio.
|
|
723
|
-
|
|
724
|
-
The `deepagents-acp` package wraps your Deep Agent with ACP support:
|
|
725
|
-
|
|
726
|
-
```bash
|
|
727
|
-
npm install deepagents-acp
|
|
728
|
-
```
|
|
729
|
-
|
|
730
|
-
The quickest way to get started is via the CLI:
|
|
731
|
-
|
|
732
|
-
```bash
|
|
733
|
-
npx deepagents-acp --name my-agent --workspace /path/to/project
|
|
734
|
-
```
|
|
735
|
-
|
|
736
|
-
Or programmatically:
|
|
737
|
-
|
|
738
|
-
```typescript
|
|
739
|
-
import { startServer } from "deepagents-acp";
|
|
740
|
-
|
|
741
|
-
await startServer({
|
|
742
|
-
agents: {
|
|
743
|
-
name: "coding-assistant",
|
|
744
|
-
description: "AI coding assistant with filesystem access",
|
|
745
|
-
skills: ["./skills/"],
|
|
746
|
-
},
|
|
747
|
-
workspaceRoot: process.cwd(),
|
|
748
|
-
});
|
|
749
|
-
```
|
|
750
|
-
|
|
751
|
-
To use with Zed, add the following to your Zed settings:
|
|
752
|
-
|
|
753
|
-
```json
|
|
754
|
-
{
|
|
755
|
-
"agent": {
|
|
756
|
-
"profiles": {
|
|
757
|
-
"deepagents": {
|
|
758
|
-
"name": "DeepAgents",
|
|
759
|
-
"command": "npx",
|
|
760
|
-
"args": ["deepagents-acp"]
|
|
761
|
-
}
|
|
762
|
-
}
|
|
763
|
-
}
|
|
764
|
-
}
|
|
765
|
-
```
|
|
105
|
+
## Security
|
|
766
106
|
|
|
767
|
-
|
|
107
|
+
Deep Agents follows a "trust the LLM" model. The agent can do anything its tools allow. Enforce boundaries at the tool/sandbox level, not by expecting the model to self-police. See the [security policy](https://github.com/langchain-ai/deepagentsjs?tab=security-ov-file) for more information.
|