deepagents 1.8.1 → 1.8.3
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 +55 -3
- package/dist/index.cjs +140 -19
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +10 -1
- package/dist/index.d.ts +10 -1
- package/dist/index.js +140 -19
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
<div align="center">
|
|
2
2
|
<a href="https://docs.langchain.com/oss/python/deepagents/overview#deep-agents-overview">
|
|
3
3
|
<picture>
|
|
4
|
-
<source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/langchain-ai/deepagentsjs/refs/heads/main/.github/images/logo-
|
|
5
|
-
<source media="(prefers-color-scheme: dark)" srcset="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-dark.svg" width="
|
|
4
|
+
<source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/langchain-ai/deepagentsjs/refs/heads/main/.github/images/logo-light.svg">
|
|
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%">
|
|
7
7
|
</picture>
|
|
8
8
|
</a>
|
|
9
9
|
</div>
|
|
@@ -132,6 +132,9 @@ const researchInstructions = `You are an expert researcher. Your job is to condu
|
|
|
132
132
|
|
|
133
133
|
You have access to an internet search tool as your primary means of gathering information.
|
|
134
134
|
|
|
135
|
+
> [!TIP]
|
|
136
|
+
> For developing, debugging, and deploying AI agents and LLM applications, see [LangSmith](https://docs.langchain.com/langsmith/home).
|
|
137
|
+
|
|
135
138
|
## \`internet_search\`
|
|
136
139
|
|
|
137
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.
|
|
@@ -713,3 +716,52 @@ const agent = createAgent({
|
|
|
713
716
|
],
|
|
714
717
|
});
|
|
715
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
|
+
```
|
|
766
|
+
|
|
767
|
+
See the [deepagents-acp README](libs/acp/README.md) and the [ACP server example](examples/acp-server/) for full documentation and advanced configuration.
|
package/dist/index.cjs
CHANGED
|
@@ -125,6 +125,8 @@ var SandboxError = class SandboxError extends Error {
|
|
|
125
125
|
const EMPTY_CONTENT_WARNING = "System reminder: File exists but has empty contents";
|
|
126
126
|
const MAX_LINE_LENGTH = 1e4;
|
|
127
127
|
const LINE_NUMBER_WIDTH = 6;
|
|
128
|
+
const TOOL_RESULT_TOKEN_LIMIT = 2e4;
|
|
129
|
+
const TRUNCATION_GUIDANCE = "... [results truncated, try being more specific with your parameters]";
|
|
128
130
|
/**
|
|
129
131
|
* Sanitize tool_call_id to prevent path traversal and separator issues.
|
|
130
132
|
*
|
|
@@ -260,6 +262,21 @@ function performStringReplacement(content, oldString, newString, replaceAll) {
|
|
|
260
262
|
return [content.split(oldString).join(newString), occurrences];
|
|
261
263
|
}
|
|
262
264
|
/**
|
|
265
|
+
* Truncate list or string result if it exceeds token limit (rough estimate: 4 chars/token).
|
|
266
|
+
*/
|
|
267
|
+
function truncateIfTooLong(result) {
|
|
268
|
+
if (Array.isArray(result)) {
|
|
269
|
+
const totalChars = result.reduce((sum, item) => sum + item.length, 0);
|
|
270
|
+
if (totalChars > TOOL_RESULT_TOKEN_LIMIT * 4) {
|
|
271
|
+
const truncateAt = Math.floor(result.length * TOOL_RESULT_TOKEN_LIMIT * 4 / totalChars);
|
|
272
|
+
return [...result.slice(0, truncateAt), TRUNCATION_GUIDANCE];
|
|
273
|
+
}
|
|
274
|
+
return result;
|
|
275
|
+
}
|
|
276
|
+
if (result.length > TOOL_RESULT_TOKEN_LIMIT * 4) return result.substring(0, TOOL_RESULT_TOKEN_LIMIT * 4) + "\n... [results truncated, try being more specific with your parameters]";
|
|
277
|
+
return result;
|
|
278
|
+
}
|
|
279
|
+
/**
|
|
263
280
|
* Validate and normalize a directory path.
|
|
264
281
|
*
|
|
265
282
|
* Ensures paths are safe to use by preventing directory traversal attacks
|
|
@@ -839,7 +856,9 @@ function createLsTool(backend, options) {
|
|
|
839
856
|
const size = info.size ? ` (${info.size} bytes)` : "";
|
|
840
857
|
lines.push(`${info.path}${size}`);
|
|
841
858
|
}
|
|
842
|
-
|
|
859
|
+
const result = truncateIfTooLong(lines);
|
|
860
|
+
if (Array.isArray(result)) return result.join("\n");
|
|
861
|
+
return result;
|
|
843
862
|
}, {
|
|
844
863
|
name: "ls",
|
|
845
864
|
description: customDescription || LS_TOOL_DESCRIPTION,
|
|
@@ -957,7 +976,9 @@ function createGlobTool(backend, options) {
|
|
|
957
976
|
const { pattern, path = "/" } = input;
|
|
958
977
|
const infos = await resolvedBackend.globInfo(pattern, path);
|
|
959
978
|
if (infos.length === 0) return `No files found matching pattern '${pattern}'`;
|
|
960
|
-
|
|
979
|
+
const result = truncateIfTooLong(infos.map((info) => info.path));
|
|
980
|
+
if (Array.isArray(result)) return result.join("\n");
|
|
981
|
+
return result;
|
|
961
982
|
}, {
|
|
962
983
|
name: "glob",
|
|
963
984
|
description: customDescription || GLOB_TOOL_DESCRIPTION,
|
|
@@ -990,7 +1011,9 @@ function createGrepTool(backend, options) {
|
|
|
990
1011
|
}
|
|
991
1012
|
lines.push(` ${match.line}: ${match.text}`);
|
|
992
1013
|
}
|
|
993
|
-
|
|
1014
|
+
const truncated = truncateIfTooLong(lines);
|
|
1015
|
+
if (Array.isArray(truncated)) return truncated.join("\n");
|
|
1016
|
+
return truncated;
|
|
994
1017
|
}, {
|
|
995
1018
|
name: "grep",
|
|
996
1019
|
description: customDescription || GREP_TOOL_DESCRIPTION,
|
|
@@ -1462,7 +1485,16 @@ function createTaskTool(options) {
|
|
|
1462
1485
|
const subagentState = filterStateForSubagent((0, _langchain_langgraph.getCurrentTaskInput)());
|
|
1463
1486
|
subagentState.messages = [new _langchain_core_messages.HumanMessage({ content: description })];
|
|
1464
1487
|
const result = await subagent.invoke(subagentState, config);
|
|
1465
|
-
if (!config.toolCall?.id)
|
|
1488
|
+
if (!config.toolCall?.id) {
|
|
1489
|
+
const messages = result.messages;
|
|
1490
|
+
let content = (messages?.[messages.length - 1])?.content || "Task completed";
|
|
1491
|
+
if (Array.isArray(content)) {
|
|
1492
|
+
content = content.filter((block) => !INVALID_TOOL_MESSAGE_BLOCK_TYPES.includes(block.type));
|
|
1493
|
+
if (content.length === 0) return "Task completed";
|
|
1494
|
+
return content.map((block) => "text" in block ? block.text : JSON.stringify(block)).join("\n");
|
|
1495
|
+
}
|
|
1496
|
+
return content;
|
|
1497
|
+
}
|
|
1466
1498
|
return returnCommandWithStateUpdate(result, config.toolCall.id);
|
|
1467
1499
|
}, {
|
|
1468
1500
|
name: "task",
|
|
@@ -1799,7 +1831,7 @@ async function loadMemoryFromBackend(backend, path) {
|
|
|
1799
1831
|
* ```
|
|
1800
1832
|
*/
|
|
1801
1833
|
function createMemoryMiddleware(options) {
|
|
1802
|
-
const { backend, sources } = options;
|
|
1834
|
+
const { backend, sources, addCacheControl = false } = options;
|
|
1803
1835
|
/**
|
|
1804
1836
|
* Resolve backend from instance or factory.
|
|
1805
1837
|
*/
|
|
@@ -1824,7 +1856,16 @@ function createMemoryMiddleware(options) {
|
|
|
1824
1856
|
},
|
|
1825
1857
|
wrapModelCall(request, handler) {
|
|
1826
1858
|
const formattedContents = formatMemoryContents(request.state?.memoryContents || {}, sources);
|
|
1827
|
-
const
|
|
1859
|
+
const memorySection = MEMORY_SYSTEM_PROMPT.replace("{memory_contents}", formattedContents);
|
|
1860
|
+
const existingContent = request.systemMessage.content;
|
|
1861
|
+
const newSystemMessage = new langchain.SystemMessage({ content: [...typeof existingContent === "string" ? [{
|
|
1862
|
+
type: "text",
|
|
1863
|
+
text: existingContent
|
|
1864
|
+
}] : Array.isArray(existingContent) ? existingContent : [], {
|
|
1865
|
+
type: "text",
|
|
1866
|
+
text: memorySection,
|
|
1867
|
+
...addCacheControl && { cache_control: { type: "ephemeral" } }
|
|
1868
|
+
}] });
|
|
1828
1869
|
return handler({
|
|
1829
1870
|
...request,
|
|
1830
1871
|
systemMessage: newSystemMessage
|
|
@@ -2835,9 +2876,10 @@ ${summary}
|
|
|
2835
2876
|
*/
|
|
2836
2877
|
function isContextOverflow(err) {
|
|
2837
2878
|
let cause = err;
|
|
2838
|
-
|
|
2879
|
+
for (;;) {
|
|
2880
|
+
if (!cause) break;
|
|
2839
2881
|
if (_langchain_core_errors.ContextOverflowError.isInstance(cause)) return true;
|
|
2840
|
-
cause = typeof cause === "object" &&
|
|
2882
|
+
cause = typeof cause === "object" && "cause" in cause ? cause.cause : void 0;
|
|
2841
2883
|
}
|
|
2842
2884
|
return false;
|
|
2843
2885
|
}
|
|
@@ -3828,6 +3870,10 @@ var CompositeBackend = class {
|
|
|
3828
3870
|
this.routes = routes;
|
|
3829
3871
|
this.sortedRoutes = Object.entries(routes).sort((a, b) => b[0].length - a[0].length);
|
|
3830
3872
|
}
|
|
3873
|
+
/** Delegates to default backend's id if it is a sandbox, otherwise empty string. */
|
|
3874
|
+
get id() {
|
|
3875
|
+
return isSandboxBackend(this.default) ? this.default.id : "";
|
|
3876
|
+
}
|
|
3831
3877
|
/**
|
|
3832
3878
|
* Determine which backend handles this key and strip prefix.
|
|
3833
3879
|
*
|
|
@@ -4757,10 +4803,66 @@ var BaseSandbox = class {
|
|
|
4757
4803
|
}
|
|
4758
4804
|
};
|
|
4759
4805
|
|
|
4806
|
+
//#endregion
|
|
4807
|
+
//#region src/middleware/cache.ts
|
|
4808
|
+
/**
|
|
4809
|
+
* Creates a middleware that places a cache breakpoint at the end of the static
|
|
4810
|
+
* system prompt content.
|
|
4811
|
+
*
|
|
4812
|
+
* This middleware tags the last block of the system message with
|
|
4813
|
+
* `cache_control: { type: "ephemeral" }` at the time it runs, capturing all
|
|
4814
|
+
* static content injected by preceding middleware (e.g. todo list instructions,
|
|
4815
|
+
* filesystem tools, subagent instructions) in a single cache breakpoint.
|
|
4816
|
+
*
|
|
4817
|
+
* This should run after all static system prompt middleware and before any
|
|
4818
|
+
* dynamic middleware (e.g. memory) so the breakpoint sits at the boundary
|
|
4819
|
+
* between stable and changing content.
|
|
4820
|
+
*
|
|
4821
|
+
* When used alongside memory middleware (which adds its own breakpoint on the
|
|
4822
|
+
* memory block), the result is two separate cache breakpoints:
|
|
4823
|
+
* - One covering all static content
|
|
4824
|
+
* - One covering the memory block
|
|
4825
|
+
*
|
|
4826
|
+
* This is a no-op when the system message has no content blocks.
|
|
4827
|
+
*/
|
|
4828
|
+
function createCacheBreakpointMiddleware() {
|
|
4829
|
+
return (0, langchain.createMiddleware)({
|
|
4830
|
+
name: "CacheBreakpointMiddleware",
|
|
4831
|
+
wrapModelCall(request, handler) {
|
|
4832
|
+
const existingContent = request.systemMessage.content;
|
|
4833
|
+
const existingBlocks = typeof existingContent === "string" ? [{
|
|
4834
|
+
type: "text",
|
|
4835
|
+
text: existingContent
|
|
4836
|
+
}] : Array.isArray(existingContent) ? [...existingContent] : [];
|
|
4837
|
+
if (existingBlocks.length === 0) return handler(request);
|
|
4838
|
+
existingBlocks[existingBlocks.length - 1] = {
|
|
4839
|
+
...existingBlocks[existingBlocks.length - 1],
|
|
4840
|
+
cache_control: { type: "ephemeral" }
|
|
4841
|
+
};
|
|
4842
|
+
return handler({
|
|
4843
|
+
...request,
|
|
4844
|
+
systemMessage: new langchain.SystemMessage({ content: existingBlocks })
|
|
4845
|
+
});
|
|
4846
|
+
}
|
|
4847
|
+
});
|
|
4848
|
+
}
|
|
4849
|
+
|
|
4760
4850
|
//#endregion
|
|
4761
4851
|
//#region src/agent.ts
|
|
4762
4852
|
const BASE_PROMPT = `In order to complete the objective that the user asks of you, you have access to a number of standard tools.`;
|
|
4763
4853
|
/**
|
|
4854
|
+
* Detect whether a model is an Anthropic model.
|
|
4855
|
+
* Used to gate Anthropic-specific prompt caching optimizations (cache_control breakpoints).
|
|
4856
|
+
*/
|
|
4857
|
+
function isAnthropicModel(model) {
|
|
4858
|
+
if (typeof model === "string") {
|
|
4859
|
+
if (model.includes(":")) return model.split(":")[0] === "anthropic";
|
|
4860
|
+
return model.startsWith("claude");
|
|
4861
|
+
}
|
|
4862
|
+
if (model.getName() === "ConfigurableModel") return model._defaultConfig?.modelProvider === "anthropic";
|
|
4863
|
+
return model.getName() === "ChatAnthropic";
|
|
4864
|
+
}
|
|
4865
|
+
/**
|
|
4764
4866
|
* Create a Deep Agent with middleware-based architecture.
|
|
4765
4867
|
*
|
|
4766
4868
|
* Matches Python's create_deep_agent function, using middleware for all features:
|
|
@@ -4793,16 +4895,20 @@ const BASE_PROMPT = `In order to complete the objective that the user asks of yo
|
|
|
4793
4895
|
*/
|
|
4794
4896
|
function createDeepAgent(params = {}) {
|
|
4795
4897
|
const { model = "claude-sonnet-4-5-20250929", tools = [], systemPrompt, middleware: customMiddleware = [], subagents = [], responseFormat, contextSchema, checkpointer, store, backend, interruptOn, name, memory, skills } = params;
|
|
4796
|
-
|
|
4797
|
-
|
|
4798
|
-
|
|
4799
|
-
|
|
4898
|
+
const anthropicModel = isAnthropicModel(model);
|
|
4899
|
+
const finalSystemPrompt = new langchain.SystemMessage({ content: systemPrompt ? typeof systemPrompt === "string" ? [{
|
|
4900
|
+
type: "text",
|
|
4901
|
+
text: `${systemPrompt}\n\n${BASE_PROMPT}`
|
|
4902
|
+
}] : [{
|
|
4800
4903
|
type: "text",
|
|
4801
4904
|
text: BASE_PROMPT
|
|
4802
4905
|
}, ...typeof systemPrompt.content === "string" ? [{
|
|
4803
4906
|
type: "text",
|
|
4804
4907
|
text: systemPrompt.content
|
|
4805
|
-
}] : systemPrompt.content]
|
|
4908
|
+
}] : systemPrompt.content] : [{
|
|
4909
|
+
type: "text",
|
|
4910
|
+
text: BASE_PROMPT
|
|
4911
|
+
}] });
|
|
4806
4912
|
/**
|
|
4807
4913
|
* Create backend configuration for filesystem middleware
|
|
4808
4914
|
* If no backend is provided, use a factory that creates a StateBackend
|
|
@@ -4820,7 +4926,8 @@ function createDeepAgent(params = {}) {
|
|
|
4820
4926
|
*/
|
|
4821
4927
|
const memoryMiddlewareArray = memory != null && memory.length > 0 ? [createMemoryMiddleware({
|
|
4822
4928
|
backend: filesystemBackend,
|
|
4823
|
-
sources: memory
|
|
4929
|
+
sources: memory,
|
|
4930
|
+
addCacheControl: anthropicModel
|
|
4824
4931
|
})] : [];
|
|
4825
4932
|
/**
|
|
4826
4933
|
* Process subagents to add SkillsMiddleware for those with their own skills.
|
|
@@ -4869,7 +4976,10 @@ function createDeepAgent(params = {}) {
|
|
|
4869
4976
|
model,
|
|
4870
4977
|
backend: filesystemBackend
|
|
4871
4978
|
}),
|
|
4872
|
-
(0, langchain.anthropicPromptCachingMiddleware)({
|
|
4979
|
+
(0, langchain.anthropicPromptCachingMiddleware)({
|
|
4980
|
+
unsupportedModelBehavior: "ignore",
|
|
4981
|
+
minMessagesToCache: 1
|
|
4982
|
+
}),
|
|
4873
4983
|
createPatchToolCallsMiddleware()
|
|
4874
4984
|
];
|
|
4875
4985
|
/**
|
|
@@ -4892,8 +5002,12 @@ function createDeepAgent(params = {}) {
|
|
|
4892
5002
|
createSubAgentMiddleware({
|
|
4893
5003
|
defaultModel: model,
|
|
4894
5004
|
defaultTools: tools,
|
|
4895
|
-
defaultMiddleware: subagentMiddleware,
|
|
4896
|
-
generalPurposeMiddleware: [
|
|
5005
|
+
defaultMiddleware: [...subagentMiddleware, ...anthropicModel ? [createCacheBreakpointMiddleware()] : []],
|
|
5006
|
+
generalPurposeMiddleware: [
|
|
5007
|
+
...subagentMiddleware,
|
|
5008
|
+
...skillsMiddlewareArray,
|
|
5009
|
+
...anthropicModel ? [createCacheBreakpointMiddleware()] : []
|
|
5010
|
+
],
|
|
4897
5011
|
defaultInterruptOn: interruptOn,
|
|
4898
5012
|
subagents: processedSubagents,
|
|
4899
5013
|
generalPurposeAgent: true
|
|
@@ -4902,10 +5016,14 @@ function createDeepAgent(params = {}) {
|
|
|
4902
5016
|
model,
|
|
4903
5017
|
backend: filesystemBackend
|
|
4904
5018
|
}),
|
|
4905
|
-
(0, langchain.anthropicPromptCachingMiddleware)({
|
|
5019
|
+
(0, langchain.anthropicPromptCachingMiddleware)({
|
|
5020
|
+
unsupportedModelBehavior: "ignore",
|
|
5021
|
+
minMessagesToCache: 1
|
|
5022
|
+
}),
|
|
4906
5023
|
createPatchToolCallsMiddleware()
|
|
4907
5024
|
],
|
|
4908
5025
|
...skillsMiddlewareArray,
|
|
5026
|
+
...anthropicModel ? [createCacheBreakpointMiddleware()] : [],
|
|
4909
5027
|
...memoryMiddlewareArray,
|
|
4910
5028
|
...interruptOn ? [(0, langchain.humanInTheLoopMiddleware)({ interruptOn })] : [],
|
|
4911
5029
|
...customMiddleware
|
|
@@ -4915,7 +5033,10 @@ function createDeepAgent(params = {}) {
|
|
|
4915
5033
|
checkpointer,
|
|
4916
5034
|
store,
|
|
4917
5035
|
name
|
|
4918
|
-
}).withConfig({
|
|
5036
|
+
}).withConfig({
|
|
5037
|
+
recursionLimit: 1e4,
|
|
5038
|
+
metadata: { ls_integration: "deepagents" }
|
|
5039
|
+
});
|
|
4919
5040
|
}
|
|
4920
5041
|
|
|
4921
5042
|
//#endregion
|