deepagents 1.9.0 → 1.9.1

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 CHANGED
@@ -1,9 +1,9 @@
1
1
  <div align="center">
2
- <a href="https://docs.langchain.com/oss/python/deepagents/overview#deep-agents-overview">
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-dark.svg" width="50%">
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/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>
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
- Using an LLM to call tools in a loop is the simplest form of an agent. This architecture, however, can yield agents that are "shallow" and fail to plan and act over longer, more complex tasks.
22
+ <br>
23
23
 
24
- Applications like "Deep Research", "Manus", and "Claude Code" have gotten around this limitation by implementing a combination of four things:
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
- `deepagents` is a TypeScript package that implements these in a general purpose way so that you can easily create a Deep Agent for your application.
26
+ **What's included:**
28
27
 
29
- > 💡 **Tip:** Looking for the Python version of this package? See [langchain-ai/deepagents](https://github.com/langchain-ai/deepagents)
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
- <div align="center">
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
- 1. **Planning Tool** - Strategic task decomposition
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
- Use this to run an internet search for a given query. You can specify the max number of results to return, the topic, and whether raw content should be included.
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: [{ role: "user", content: "What is langgraph?" }],
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
- name: "researcher",
365
- description: "Research assistant",
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
- This design ensures context isolation - custom subagents only have access to the skills they explicitly need, preventing unintended skill leakage between specialized agents.
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
- ```typescript
384
- import { tool } from "langchain";
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
- A common reality for agents is that some tool operations may be sensitive and require human approval before execution. Deep Agents supports human-in-the-loop workflows through LangGraph's interrupt capabilities. You can configure which tools require approval using a checkpointer.
67
+ ## Customization
443
68
 
444
- These tool configs are passed to our prebuilt [HITL middleware](https://docs.langchain.com/oss/typescript/langchain/middleware#human-in-the-loop) so that the agent pauses execution and waits for feedback from the user before executing configured tools.
69
+ Add tools, swap models, and customize prompts as needed:
445
70
 
446
71
  ```typescript
447
- import { tool } from "langchain";
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: "claude-sonnet-4-20250514",
466
- tools: [getWeather],
467
- interruptOn: {
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 [examples/backends/](examples/backends/) for detailed examples of each backend type.
82
+ See the [JavaScript Deep Agents docs](https://docs.langchain.com/oss/javascript/deepagents/overview) for full configuration options.
529
83
 
530
- ### Sandbox Execution
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
- When using a sandbox backend, the agent gains access to an `execute` tool that can run shell commands. The tool automatically returns the command output, exit code, and whether the output was truncated.
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
- See [examples/sandbox/local-sandbox.ts](examples/sandbox/local-sandbox.ts) for a complete implementation.
88
+ ## Why Use It
604
89
 
605
- ## Deep Agents Middleware
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
- Deep Agents are built with a modular middleware architecture. As a reminder, Deep Agents have access to:
97
+ ---
608
98
 
609
- - A planning tool
610
- - A filesystem for storing context and long-term memories
611
- - The ability to spawn subagents
99
+ ## Documentation
612
100
 
613
- Each of these features is implemented as separate middleware. When you create a deep agent with `createDeepAgent`, we automatically attach **todoListMiddleware**, **FilesystemMiddleware** and **SubAgentMiddleware** to your agent.
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
- Middleware is a composable concept, and you can choose to add as many or as few middleware to an agent depending on your use case. That means that you can also use any of the aforementioned middleware independently!
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
- See the [deepagents-acp README](libs/acp/README.md) and the [ACP server example](examples/acp-server/) for full documentation and advanced configuration.
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.