deepagents 1.6.3 → 1.7.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 +58 -12
- package/dist/index.cjs +201 -76
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +402 -55
- package/dist/index.d.ts +403 -56
- package/dist/index.js +190 -70
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { AIMessage, SystemMessage, ToolMessage, anthropicPromptCachingMiddleware, createAgent, createMiddleware, humanInTheLoopMiddleware, summarizationMiddleware, todoListMiddleware, tool } from "langchain";
|
|
2
|
+
import { Runnable } from "@langchain/core/runnables";
|
|
2
3
|
import { Command, REMOVE_ALL_MESSAGES, ReducedValue, StateSchema, getCurrentTaskInput, isCommand } from "@langchain/langgraph";
|
|
3
4
|
import { z } from "zod/v4";
|
|
4
5
|
import micromatch from "micromatch";
|
|
@@ -7,7 +8,7 @@ import { HumanMessage, RemoveMessage } from "@langchain/core/messages";
|
|
|
7
8
|
import { z as z$1 } from "zod";
|
|
8
9
|
import yaml from "yaml";
|
|
9
10
|
import "uuid";
|
|
10
|
-
import "
|
|
11
|
+
import "langchain/chat_models/universal";
|
|
11
12
|
import fs from "node:fs/promises";
|
|
12
13
|
import fs$1 from "node:fs";
|
|
13
14
|
import path from "node:path";
|
|
@@ -247,17 +248,13 @@ function globSearchFiles(files, pattern, path = "/") {
|
|
|
247
248
|
/**
|
|
248
249
|
* Return structured grep matches from an in-memory files mapping.
|
|
249
250
|
*
|
|
250
|
-
*
|
|
251
|
-
*
|
|
252
|
-
*
|
|
251
|
+
* Performs literal text search (not regex).
|
|
252
|
+
*
|
|
253
|
+
* Returns a list of GrepMatch on success, or a string for invalid inputs.
|
|
254
|
+
* We deliberately do not raise here to keep backends non-throwing in tool
|
|
255
|
+
* contexts and preserve user-facing error messages.
|
|
253
256
|
*/
|
|
254
257
|
function grepMatchesFromFiles(files, pattern, path = null, glob = null) {
|
|
255
|
-
let regex;
|
|
256
|
-
try {
|
|
257
|
-
regex = new RegExp(pattern);
|
|
258
|
-
} catch (e) {
|
|
259
|
-
return `Invalid regex pattern: ${e.message}`;
|
|
260
|
-
}
|
|
261
258
|
let normalizedPath;
|
|
262
259
|
try {
|
|
263
260
|
normalizedPath = validatePath(path);
|
|
@@ -273,7 +270,7 @@ function grepMatchesFromFiles(files, pattern, path = null, glob = null) {
|
|
|
273
270
|
for (const [filePath, fileData] of Object.entries(filtered)) for (let i = 0; i < fileData.content.length; i++) {
|
|
274
271
|
const line = fileData.content[i];
|
|
275
272
|
const lineNum = i + 1;
|
|
276
|
-
if (
|
|
273
|
+
if (line.includes(pattern)) matches.push({
|
|
277
274
|
path: filePath,
|
|
278
275
|
line: lineNum,
|
|
279
276
|
text: line
|
|
@@ -680,11 +677,13 @@ Examples:
|
|
|
680
677
|
const GREP_TOOL_DESCRIPTION = `Search for a text pattern across files.
|
|
681
678
|
|
|
682
679
|
Searches for literal text (not regex) and returns matching files or content based on output_mode.
|
|
680
|
+
Special characters like parentheses, brackets, pipes, etc. are treated as literal characters, not regex operators.
|
|
683
681
|
|
|
684
682
|
Examples:
|
|
685
683
|
- Search all files: \`grep(pattern="TODO")\`
|
|
686
684
|
- Search Python files only: \`grep(pattern="import", glob="*.py")\`
|
|
687
|
-
- Show matching lines: \`grep(pattern="error", output_mode="content")
|
|
685
|
+
- Show matching lines: \`grep(pattern="error", output_mode="content")\`
|
|
686
|
+
- Search for code with special chars: \`grep(pattern="def __init__(self):")\``;
|
|
688
687
|
const EXECUTE_TOOL_DESCRIPTION = `Executes a shell command in an isolated sandbox environment.
|
|
689
688
|
|
|
690
689
|
Usage:
|
|
@@ -969,14 +968,13 @@ function createFilesystemMiddleware(options = {}) {
|
|
|
969
968
|
}));
|
|
970
969
|
let tools = request.tools;
|
|
971
970
|
if (!supportsExecution) tools = tools.filter((t) => t.name !== "execute");
|
|
972
|
-
let
|
|
973
|
-
if (supportsExecution)
|
|
974
|
-
const
|
|
975
|
-
const newSystemPrompt = currentSystemPrompt ? `${currentSystemPrompt}\n\n${systemPrompt}` : systemPrompt;
|
|
971
|
+
let filesystemPrompt = baseSystemPrompt;
|
|
972
|
+
if (supportsExecution) filesystemPrompt = `${filesystemPrompt}\n\n${EXECUTION_SYSTEM_PROMPT}`;
|
|
973
|
+
const newSystemMessage = request.systemMessage.concat(filesystemPrompt);
|
|
976
974
|
return handler({
|
|
977
975
|
...request,
|
|
978
976
|
tools,
|
|
979
|
-
|
|
977
|
+
systemMessage: newSystemMessage
|
|
980
978
|
});
|
|
981
979
|
},
|
|
982
980
|
wrapToolCall: async (request, handler) => {
|
|
@@ -1046,12 +1044,34 @@ function createFilesystemMiddleware(options = {}) {
|
|
|
1046
1044
|
|
|
1047
1045
|
//#endregion
|
|
1048
1046
|
//#region src/middleware/subagents.ts
|
|
1047
|
+
/**
|
|
1048
|
+
* Default system prompt for subagents.
|
|
1049
|
+
* Provides a minimal base prompt that can be extended by specific subagent configurations.
|
|
1050
|
+
*/
|
|
1049
1051
|
const DEFAULT_SUBAGENT_PROMPT = "In order to complete the objective that the user asks of you, you have access to a number of standard tools.";
|
|
1052
|
+
/**
|
|
1053
|
+
* State keys that are excluded when passing state to subagents and when returning
|
|
1054
|
+
* updates from subagents.
|
|
1055
|
+
*
|
|
1056
|
+
* When returning updates:
|
|
1057
|
+
* 1. The messages key is handled explicitly to ensure only the final message is included
|
|
1058
|
+
* 2. The todos and structuredResponse keys are excluded as they do not have a defined reducer
|
|
1059
|
+
* and no clear meaning for returning them from a subagent to the main agent.
|
|
1060
|
+
* 3. The skillsMetadata and memoryContents keys are automatically excluded from subagent output
|
|
1061
|
+
* to prevent parent state from leaking to child agents. Each agent loads its own skills/memory
|
|
1062
|
+
* independently based on its middleware configuration.
|
|
1063
|
+
*/
|
|
1050
1064
|
const EXCLUDED_STATE_KEYS = [
|
|
1051
1065
|
"messages",
|
|
1052
1066
|
"todos",
|
|
1053
|
-
"structuredResponse"
|
|
1067
|
+
"structuredResponse",
|
|
1068
|
+
"skillsMetadata",
|
|
1069
|
+
"memoryContents"
|
|
1054
1070
|
];
|
|
1071
|
+
/**
|
|
1072
|
+
* Default description for the general-purpose subagent.
|
|
1073
|
+
* This description is shown to the model when selecting which subagent to use.
|
|
1074
|
+
*/
|
|
1055
1075
|
const DEFAULT_GENERAL_PURPOSE_DESCRIPTION = "General-purpose agent for researching complex questions, searching for files and content, and executing multi-step tasks. When you are searching for a keyword or file and are not confident that you will find the right match in the first few tries use this agent to perform the search for you. This agent has access to all tools as the main agent.";
|
|
1056
1076
|
function getTaskToolDescription(subagentDescriptions) {
|
|
1057
1077
|
return `
|
|
@@ -1166,6 +1186,19 @@ assistant: "I'm going to use the Task tool to launch with the greeting-responder
|
|
|
1166
1186
|
</example>
|
|
1167
1187
|
`.trim();
|
|
1168
1188
|
}
|
|
1189
|
+
/**
|
|
1190
|
+
* System prompt section that explains how to use the task tool for spawning subagents.
|
|
1191
|
+
*
|
|
1192
|
+
* This prompt is automatically appended to the main agent's system prompt when
|
|
1193
|
+
* using `createSubAgentMiddleware`. It provides guidance on:
|
|
1194
|
+
* - When to use the task tool
|
|
1195
|
+
* - Subagent lifecycle (spawn → run → return → reconcile)
|
|
1196
|
+
* - When NOT to use the task tool
|
|
1197
|
+
* - Best practices for parallel task execution
|
|
1198
|
+
*
|
|
1199
|
+
* You can provide a custom `systemPrompt` to `createSubAgentMiddleware` to override
|
|
1200
|
+
* or extend this default.
|
|
1201
|
+
*/
|
|
1169
1202
|
const TASK_SYSTEM_PROMPT = `## \`task\` (subagent spawner)
|
|
1170
1203
|
|
|
1171
1204
|
You have access to a \`task\` tool to launch short-lived subagents that handle isolated tasks. These agents are ephemeral — they live only for the duration of the task and return a single result.
|
|
@@ -1194,6 +1227,48 @@ When NOT to use the task tool:
|
|
|
1194
1227
|
- Remember to use the \`task\` tool to silo independent tasks within a multi-part objective.
|
|
1195
1228
|
- You should use the \`task\` tool whenever you have a complex task that will take multiple steps, and is independent from other tasks that the agent needs to complete. These agents are highly competent and efficient.`;
|
|
1196
1229
|
/**
|
|
1230
|
+
* Base specification for the general-purpose subagent.
|
|
1231
|
+
*
|
|
1232
|
+
* This constant provides the default configuration for the general-purpose subagent
|
|
1233
|
+
* that is automatically included when `generalPurposeAgent: true` (the default).
|
|
1234
|
+
*
|
|
1235
|
+
* The general-purpose subagent:
|
|
1236
|
+
* - Has access to all tools from the main agent
|
|
1237
|
+
* - Inherits skills from the main agent (when skills are configured)
|
|
1238
|
+
* - Uses the same model as the main agent (by default)
|
|
1239
|
+
* - Is ideal for delegating complex, multi-step tasks
|
|
1240
|
+
*
|
|
1241
|
+
* You can spread this constant and override specific properties when creating
|
|
1242
|
+
* custom subagents that should behave similarly to the general-purpose agent:
|
|
1243
|
+
*
|
|
1244
|
+
* @example
|
|
1245
|
+
* ```typescript
|
|
1246
|
+
* import { GENERAL_PURPOSE_SUBAGENT, createDeepAgent } from "@anthropic/deepagents";
|
|
1247
|
+
*
|
|
1248
|
+
* // Use as-is (automatically included with generalPurposeAgent: true)
|
|
1249
|
+
* const agent = createDeepAgent({ model: "claude-sonnet-4-5-20250929" });
|
|
1250
|
+
*
|
|
1251
|
+
* // Or create a custom variant with different tools
|
|
1252
|
+
* const customGP: SubAgent = {
|
|
1253
|
+
* ...GENERAL_PURPOSE_SUBAGENT,
|
|
1254
|
+
* name: "research-gp",
|
|
1255
|
+
* tools: [webSearchTool, readFileTool],
|
|
1256
|
+
* };
|
|
1257
|
+
*
|
|
1258
|
+
* const agent = createDeepAgent({
|
|
1259
|
+
* model: "claude-sonnet-4-5-20250929",
|
|
1260
|
+
* subagents: [customGP],
|
|
1261
|
+
* // Disable the default general-purpose agent since we're providing our own
|
|
1262
|
+
* // (handled automatically when using createSubAgentMiddleware directly)
|
|
1263
|
+
* });
|
|
1264
|
+
* ```
|
|
1265
|
+
*/
|
|
1266
|
+
const GENERAL_PURPOSE_SUBAGENT = {
|
|
1267
|
+
name: "general-purpose",
|
|
1268
|
+
description: DEFAULT_GENERAL_PURPOSE_DESCRIPTION,
|
|
1269
|
+
systemPrompt: DEFAULT_SUBAGENT_PROMPT
|
|
1270
|
+
};
|
|
1271
|
+
/**
|
|
1197
1272
|
* Filter state to exclude certain keys when passing to subagents
|
|
1198
1273
|
*/
|
|
1199
1274
|
function filterStateForSubagent(state) {
|
|
@@ -1221,12 +1296,13 @@ function returnCommandWithStateUpdate(result, toolCallId) {
|
|
|
1221
1296
|
* Create subagent instances from specifications
|
|
1222
1297
|
*/
|
|
1223
1298
|
function getSubagents(options) {
|
|
1224
|
-
const { defaultModel, defaultTools, defaultMiddleware, defaultInterruptOn, subagents, generalPurposeAgent } = options;
|
|
1299
|
+
const { defaultModel, defaultTools, defaultMiddleware, generalPurposeMiddleware: gpMiddleware, defaultInterruptOn, subagents, generalPurposeAgent } = options;
|
|
1225
1300
|
const defaultSubagentMiddleware = defaultMiddleware || [];
|
|
1301
|
+
const generalPurposeMiddlewareBase = gpMiddleware || defaultSubagentMiddleware;
|
|
1226
1302
|
const agents = {};
|
|
1227
1303
|
const subagentDescriptions = [];
|
|
1228
1304
|
if (generalPurposeAgent) {
|
|
1229
|
-
const generalPurposeMiddleware = [...
|
|
1305
|
+
const generalPurposeMiddleware = [...generalPurposeMiddlewareBase];
|
|
1230
1306
|
if (defaultInterruptOn) generalPurposeMiddleware.push(humanInTheLoopMiddleware({ interruptOn: defaultInterruptOn }));
|
|
1231
1307
|
agents["general-purpose"] = createAgent({
|
|
1232
1308
|
model: defaultModel,
|
|
@@ -1260,11 +1336,12 @@ function getSubagents(options) {
|
|
|
1260
1336
|
* Create the task tool for invoking subagents
|
|
1261
1337
|
*/
|
|
1262
1338
|
function createTaskTool(options) {
|
|
1263
|
-
const { defaultModel, defaultTools, defaultMiddleware, defaultInterruptOn, subagents, generalPurposeAgent, taskDescription } = options;
|
|
1339
|
+
const { defaultModel, defaultTools, defaultMiddleware, generalPurposeMiddleware, defaultInterruptOn, subagents, generalPurposeAgent, taskDescription } = options;
|
|
1264
1340
|
const { agents: subagentGraphs, descriptions: subagentDescriptions } = getSubagents({
|
|
1265
1341
|
defaultModel,
|
|
1266
1342
|
defaultTools,
|
|
1267
1343
|
defaultMiddleware,
|
|
1344
|
+
generalPurposeMiddleware,
|
|
1268
1345
|
defaultInterruptOn,
|
|
1269
1346
|
subagents,
|
|
1270
1347
|
generalPurposeAgent
|
|
@@ -1294,13 +1371,14 @@ function createTaskTool(options) {
|
|
|
1294
1371
|
* Create subagent middleware with task tool
|
|
1295
1372
|
*/
|
|
1296
1373
|
function createSubAgentMiddleware(options) {
|
|
1297
|
-
const { defaultModel, defaultTools = [], defaultMiddleware = null, defaultInterruptOn = null, subagents = [], systemPrompt = TASK_SYSTEM_PROMPT, generalPurposeAgent = true, taskDescription = null } = options;
|
|
1374
|
+
const { defaultModel, defaultTools = [], defaultMiddleware = null, generalPurposeMiddleware = null, defaultInterruptOn = null, subagents = [], systemPrompt = TASK_SYSTEM_PROMPT, generalPurposeAgent = true, taskDescription = null } = options;
|
|
1298
1375
|
return createMiddleware({
|
|
1299
1376
|
name: "subAgentMiddleware",
|
|
1300
1377
|
tools: [createTaskTool({
|
|
1301
1378
|
defaultModel,
|
|
1302
1379
|
defaultTools,
|
|
1303
1380
|
defaultMiddleware,
|
|
1381
|
+
generalPurposeMiddleware,
|
|
1304
1382
|
defaultInterruptOn,
|
|
1305
1383
|
subagents,
|
|
1306
1384
|
generalPurposeAgent,
|
|
@@ -2356,7 +2434,7 @@ var StoreBackend = class {
|
|
|
2356
2434
|
* Security and search upgrades:
|
|
2357
2435
|
* - Secure path resolution with root containment when in virtual_mode (sandboxed to cwd)
|
|
2358
2436
|
* - Prevent symlink-following on file I/O using O_NOFOLLOW when available
|
|
2359
|
-
* - Ripgrep-powered grep with
|
|
2437
|
+
* - Ripgrep-powered grep with literal (fixed-string) search, plus substring fallback
|
|
2360
2438
|
* and optional glob include filtering, while preserving virtual path behavior
|
|
2361
2439
|
*/
|
|
2362
2440
|
const SUPPORTS_NOFOLLOW = fs$1.constants.O_NOFOLLOW !== void 0;
|
|
@@ -2605,14 +2683,16 @@ var FilesystemBackend = class {
|
|
|
2605
2683
|
}
|
|
2606
2684
|
}
|
|
2607
2685
|
/**
|
|
2608
|
-
*
|
|
2686
|
+
* Search for a literal text pattern in files.
|
|
2687
|
+
*
|
|
2688
|
+
* Uses ripgrep if available, falling back to substring search.
|
|
2689
|
+
*
|
|
2690
|
+
* @param pattern - Literal string to search for (NOT regex).
|
|
2691
|
+
* @param dirPath - Directory or file path to search in. Defaults to current directory.
|
|
2692
|
+
* @param glob - Optional glob pattern to filter which files to search.
|
|
2693
|
+
* @returns List of GrepMatch dicts containing path, line number, and matched text.
|
|
2609
2694
|
*/
|
|
2610
2695
|
async grepRaw(pattern, dirPath = "/", glob = null) {
|
|
2611
|
-
try {
|
|
2612
|
-
new RegExp(pattern);
|
|
2613
|
-
} catch (e) {
|
|
2614
|
-
return `Invalid regex pattern: ${e.message}`;
|
|
2615
|
-
}
|
|
2616
2696
|
let baseFull;
|
|
2617
2697
|
try {
|
|
2618
2698
|
baseFull = this.resolvePath(dirPath || ".");
|
|
@@ -2625,7 +2705,7 @@ var FilesystemBackend = class {
|
|
|
2625
2705
|
return [];
|
|
2626
2706
|
}
|
|
2627
2707
|
let results = await this.ripgrepSearch(pattern, baseFull, glob);
|
|
2628
|
-
if (results === null) results = await this.
|
|
2708
|
+
if (results === null) results = await this.literalSearch(pattern, baseFull, glob);
|
|
2629
2709
|
const matches = [];
|
|
2630
2710
|
for (const [fpath, items] of Object.entries(results)) for (const [lineNum, lineText] of items) matches.push({
|
|
2631
2711
|
path: fpath,
|
|
@@ -2635,12 +2715,17 @@ var FilesystemBackend = class {
|
|
|
2635
2715
|
return matches;
|
|
2636
2716
|
}
|
|
2637
2717
|
/**
|
|
2638
|
-
*
|
|
2639
|
-
*
|
|
2718
|
+
* Search using ripgrep with fixed-string (literal) mode.
|
|
2719
|
+
*
|
|
2720
|
+
* @param pattern - Literal string to search for (unescaped).
|
|
2721
|
+
* @param baseFull - Resolved base path to search in.
|
|
2722
|
+
* @param includeGlob - Optional glob pattern to filter files.
|
|
2723
|
+
* @returns Dict mapping file paths to list of (line_number, line_text) tuples.
|
|
2724
|
+
* Returns null if ripgrep is unavailable or times out.
|
|
2640
2725
|
*/
|
|
2641
2726
|
async ripgrepSearch(pattern, baseFull, includeGlob) {
|
|
2642
2727
|
return new Promise((resolve) => {
|
|
2643
|
-
const args = ["--json"];
|
|
2728
|
+
const args = ["--json", "-F"];
|
|
2644
2729
|
if (includeGlob) args.push("--glob", includeGlob);
|
|
2645
2730
|
args.push("--", pattern, baseFull);
|
|
2646
2731
|
const proc = spawn("rg", args, { timeout: 3e4 });
|
|
@@ -2689,15 +2774,16 @@ var FilesystemBackend = class {
|
|
|
2689
2774
|
});
|
|
2690
2775
|
}
|
|
2691
2776
|
/**
|
|
2692
|
-
* Fallback
|
|
2777
|
+
* Fallback search using literal substring matching when ripgrep is unavailable.
|
|
2778
|
+
*
|
|
2779
|
+
* Recursively searches files, respecting maxFileSizeBytes limit.
|
|
2780
|
+
*
|
|
2781
|
+
* @param pattern - Literal string to search for.
|
|
2782
|
+
* @param baseFull - Resolved base path to search in.
|
|
2783
|
+
* @param includeGlob - Optional glob pattern to filter files by name.
|
|
2784
|
+
* @returns Dict mapping file paths to list of (line_number, line_text) tuples.
|
|
2693
2785
|
*/
|
|
2694
|
-
async
|
|
2695
|
-
let regex;
|
|
2696
|
-
try {
|
|
2697
|
-
regex = new RegExp(pattern);
|
|
2698
|
-
} catch {
|
|
2699
|
-
return {};
|
|
2700
|
-
}
|
|
2786
|
+
async literalSearch(pattern, baseFull, includeGlob) {
|
|
2701
2787
|
const results = {};
|
|
2702
2788
|
const files = await fg("**/*", {
|
|
2703
2789
|
cwd: (await fs.stat(baseFull)).isDirectory() ? baseFull : path.dirname(baseFull),
|
|
@@ -2711,7 +2797,7 @@ var FilesystemBackend = class {
|
|
|
2711
2797
|
const lines = (await fs.readFile(fp, "utf-8")).split("\n");
|
|
2712
2798
|
for (let i = 0; i < lines.length; i++) {
|
|
2713
2799
|
const line = lines[i];
|
|
2714
|
-
if (
|
|
2800
|
+
if (line.includes(pattern)) {
|
|
2715
2801
|
let virtPath;
|
|
2716
2802
|
if (this.virtualMode) try {
|
|
2717
2803
|
const relative = path.relative(this.cwd, fp);
|
|
@@ -3275,7 +3361,11 @@ console.log(count);
|
|
|
3275
3361
|
"`;
|
|
3276
3362
|
}
|
|
3277
3363
|
/**
|
|
3278
|
-
* Node.js command template for grep operations.
|
|
3364
|
+
* Node.js command template for grep operations with literal (fixed-string) search.
|
|
3365
|
+
*
|
|
3366
|
+
* @param pattern - Literal string to search for (NOT regex).
|
|
3367
|
+
* @param searchPath - Base path to search in.
|
|
3368
|
+
* @param globPattern - Optional glob pattern to filter files.
|
|
3279
3369
|
*/
|
|
3280
3370
|
function buildGrepCommand(pattern, searchPath, globPattern) {
|
|
3281
3371
|
const patternB64 = btoa(pattern);
|
|
@@ -3289,14 +3379,6 @@ const pattern = atob('${patternB64}');
|
|
|
3289
3379
|
const searchPath = atob('${pathB64}');
|
|
3290
3380
|
const globPattern = ${globPattern ? `atob('${globB64}')` : "null"};
|
|
3291
3381
|
|
|
3292
|
-
let regex;
|
|
3293
|
-
try {
|
|
3294
|
-
regex = new RegExp(pattern);
|
|
3295
|
-
} catch (e) {
|
|
3296
|
-
console.error('Invalid regex: ' + e.message);
|
|
3297
|
-
process.exit(1);
|
|
3298
|
-
}
|
|
3299
|
-
|
|
3300
3382
|
function globMatch(filePath, pattern) {
|
|
3301
3383
|
if (!pattern) return true;
|
|
3302
3384
|
const regexPattern = pattern
|
|
@@ -3321,7 +3403,8 @@ function walkDir(dir, results) {
|
|
|
3321
3403
|
const content = fs.readFileSync(fullPath, 'utf-8');
|
|
3322
3404
|
const lines = content.split('\\n');
|
|
3323
3405
|
for (let i = 0; i < lines.length; i++) {
|
|
3324
|
-
|
|
3406
|
+
// Simple substring search for literal matching
|
|
3407
|
+
if (lines[i].includes(pattern)) {
|
|
3325
3408
|
console.log(JSON.stringify({
|
|
3326
3409
|
path: fullPath,
|
|
3327
3410
|
line: i + 1,
|
|
@@ -3417,14 +3500,16 @@ var BaseSandbox = class {
|
|
|
3417
3500
|
};
|
|
3418
3501
|
}
|
|
3419
3502
|
/**
|
|
3420
|
-
*
|
|
3503
|
+
* Search for a literal text pattern in files.
|
|
3504
|
+
*
|
|
3505
|
+
* @param pattern - Literal string to search for (NOT regex).
|
|
3506
|
+
* @param path - Directory or file path to search in.
|
|
3507
|
+
* @param glob - Optional glob pattern to filter which files to search.
|
|
3508
|
+
* @returns List of GrepMatch dicts containing path, line number, and matched text.
|
|
3421
3509
|
*/
|
|
3422
3510
|
async grepRaw(pattern, path = "/", glob = null) {
|
|
3423
3511
|
const command = buildGrepCommand(pattern, path, glob);
|
|
3424
3512
|
const result = await this.execute(command);
|
|
3425
|
-
if (result.exitCode === 1) {
|
|
3426
|
-
if (result.output.includes("Invalid regex:")) return result.output.trim();
|
|
3427
|
-
}
|
|
3428
3513
|
const matches = [];
|
|
3429
3514
|
const lines = result.output.trim().split("\n").filter(Boolean);
|
|
3430
3515
|
for (const line of lines) try {
|
|
@@ -3553,6 +3638,51 @@ function createDeepAgent(params = {}) {
|
|
|
3553
3638
|
sources: memory
|
|
3554
3639
|
})] : [];
|
|
3555
3640
|
/**
|
|
3641
|
+
* Process subagents to add SkillsMiddleware for those with their own skills.
|
|
3642
|
+
*
|
|
3643
|
+
* Custom subagents do NOT inherit skills from the main agent by default.
|
|
3644
|
+
* Only the general-purpose subagent inherits the main agent's skills (via defaultMiddleware).
|
|
3645
|
+
* If a custom subagent needs skills, it must specify its own `skills` array.
|
|
3646
|
+
*/
|
|
3647
|
+
const processedSubagents = subagents.map((subagent) => {
|
|
3648
|
+
/**
|
|
3649
|
+
* CompiledSubAgent - use as-is (already has its own middleware baked in)
|
|
3650
|
+
*/
|
|
3651
|
+
if (Runnable.isRunnable(subagent)) return subagent;
|
|
3652
|
+
/**
|
|
3653
|
+
* SubAgent without skills - use as-is
|
|
3654
|
+
*/
|
|
3655
|
+
if (!("skills" in subagent) || subagent.skills?.length === 0) return subagent;
|
|
3656
|
+
/**
|
|
3657
|
+
* SubAgent with skills - add SkillsMiddleware BEFORE user's middleware
|
|
3658
|
+
* Order: base middleware (via defaultMiddleware) → skills → user's middleware
|
|
3659
|
+
* This matches Python's ordering in create_deep_agent
|
|
3660
|
+
*/
|
|
3661
|
+
const subagentSkillsMiddleware = createSkillsMiddleware({
|
|
3662
|
+
backend: filesystemBackend,
|
|
3663
|
+
sources: subagent.skills ?? []
|
|
3664
|
+
});
|
|
3665
|
+
return {
|
|
3666
|
+
...subagent,
|
|
3667
|
+
middleware: [subagentSkillsMiddleware, ...subagent.middleware || []]
|
|
3668
|
+
};
|
|
3669
|
+
});
|
|
3670
|
+
/**
|
|
3671
|
+
* Middleware for custom subagents (does NOT include skills from main agent).
|
|
3672
|
+
* Custom subagents must define their own `skills` property to get skills.
|
|
3673
|
+
*/
|
|
3674
|
+
const subagentMiddleware = [
|
|
3675
|
+
todoListMiddleware(),
|
|
3676
|
+
createFilesystemMiddleware({ backend: filesystemBackend }),
|
|
3677
|
+
summarizationMiddleware({
|
|
3678
|
+
model,
|
|
3679
|
+
trigger: { tokens: 17e4 },
|
|
3680
|
+
keep: { messages: 6 }
|
|
3681
|
+
}),
|
|
3682
|
+
anthropicPromptCachingMiddleware({ unsupportedModelBehavior: "ignore" }),
|
|
3683
|
+
createPatchToolCallsMiddleware()
|
|
3684
|
+
];
|
|
3685
|
+
/**
|
|
3556
3686
|
* Return as DeepAgent with proper DeepAgentTypeConfig
|
|
3557
3687
|
* - Response: TResponse (from responseFormat parameter)
|
|
3558
3688
|
* - State: undefined (state comes from middleware)
|
|
@@ -3572,20 +3702,10 @@ function createDeepAgent(params = {}) {
|
|
|
3572
3702
|
createSubAgentMiddleware({
|
|
3573
3703
|
defaultModel: model,
|
|
3574
3704
|
defaultTools: tools,
|
|
3575
|
-
defaultMiddleware:
|
|
3576
|
-
|
|
3577
|
-
...skillsMiddlewareArray,
|
|
3578
|
-
createFilesystemMiddleware({ backend: filesystemBackend }),
|
|
3579
|
-
summarizationMiddleware({
|
|
3580
|
-
model,
|
|
3581
|
-
trigger: { tokens: 17e4 },
|
|
3582
|
-
keep: { messages: 6 }
|
|
3583
|
-
}),
|
|
3584
|
-
anthropicPromptCachingMiddleware({ unsupportedModelBehavior: "ignore" }),
|
|
3585
|
-
createPatchToolCallsMiddleware()
|
|
3586
|
-
],
|
|
3705
|
+
defaultMiddleware: subagentMiddleware,
|
|
3706
|
+
generalPurposeMiddleware: [...subagentMiddleware, ...skillsMiddlewareArray],
|
|
3587
3707
|
defaultInterruptOn: interruptOn,
|
|
3588
|
-
subagents,
|
|
3708
|
+
subagents: processedSubagents,
|
|
3589
3709
|
generalPurposeAgent: true
|
|
3590
3710
|
}),
|
|
3591
3711
|
summarizationMiddleware({
|
|
@@ -4154,5 +4274,5 @@ function listSkills(options) {
|
|
|
4154
4274
|
}
|
|
4155
4275
|
|
|
4156
4276
|
//#endregion
|
|
4157
|
-
export { BaseSandbox, CompositeBackend, FilesystemBackend, MAX_SKILL_DESCRIPTION_LENGTH, MAX_SKILL_FILE_SIZE, MAX_SKILL_NAME_LENGTH, StateBackend, StoreBackend, createAgentMemoryMiddleware, createDeepAgent, createFilesystemMiddleware, createMemoryMiddleware, createPatchToolCallsMiddleware, createSettings, createSkillsMiddleware, createSubAgentMiddleware, filesValue, findProjectRoot, isSandboxBackend, listSkills, parseSkillMetadata };
|
|
4277
|
+
export { BaseSandbox, CompositeBackend, DEFAULT_GENERAL_PURPOSE_DESCRIPTION, DEFAULT_SUBAGENT_PROMPT, FilesystemBackend, GENERAL_PURPOSE_SUBAGENT, MAX_SKILL_DESCRIPTION_LENGTH, MAX_SKILL_FILE_SIZE, MAX_SKILL_NAME_LENGTH, StateBackend, StoreBackend, TASK_SYSTEM_PROMPT, createAgentMemoryMiddleware, createDeepAgent, createFilesystemMiddleware, createMemoryMiddleware, createPatchToolCallsMiddleware, createSettings, createSkillsMiddleware, createSubAgentMiddleware, filesValue, findProjectRoot, isSandboxBackend, listSkills, parseSkillMetadata };
|
|
4158
4278
|
//# sourceMappingURL=index.js.map
|