deepagents 1.12.1 → 1.12.2
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/dist/{agent-B2Wfp1cf.d.cts → agent-DwU6Gs2-.d.cts} +61 -11
- package/dist/{agent-C_iR-pdx.d.ts → agent-pS9QvkWZ.d.ts} +61 -11
- package/dist/browser.cjs +1 -1
- package/dist/browser.d.cts +1 -1
- package/dist/browser.d.ts +1 -1
- package/dist/browser.js +1 -1
- package/dist/index.cjs +3 -2
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +3 -3
- package/dist/{langsmith-DdOXam6Z.cjs → langsmith-D2d3Dwcc.cjs} +121 -42
- package/dist/langsmith-D2d3Dwcc.cjs.map +1 -0
- package/dist/{langsmith-DgbmWtWj.js → langsmith-b3Dpu8rS.js} +116 -43
- package/dist/langsmith-b3Dpu8rS.js.map +1 -0
- package/dist/node.cjs +3 -2
- package/dist/node.d.cts +2 -2
- package/dist/node.d.ts +2 -2
- package/dist/node.js +3 -3
- package/dist/{src-DeCEf6Ie.js → src-DMUJ51B3.js} +9 -4
- package/dist/src-DMUJ51B3.js.map +1 -0
- package/dist/{src-BApYUljI.cjs → src-Dkrvbmp1.cjs} +9 -4
- package/dist/src-Dkrvbmp1.cjs.map +1 -0
- package/package.json +1 -1
- package/dist/langsmith-DdOXam6Z.cjs.map +0 -1
- package/dist/langsmith-DgbmWtWj.js.map +0 -1
- package/dist/src-BApYUljI.cjs.map +0 -1
- package/dist/src-DeCEf6Ie.js.map +0 -1
|
@@ -554,9 +554,12 @@ function adaptBackendProtocol(backend) {
|
|
|
554
554
|
if (typeof result === "string") return { content: result };
|
|
555
555
|
return result;
|
|
556
556
|
},
|
|
557
|
-
async grep(pattern, path, glob) {
|
|
558
|
-
const result = await ("grep" in backend ? backend.grep(pattern, path, glob) : backend.grepRaw(pattern, path, glob));
|
|
559
|
-
if (Array.isArray(result)) return {
|
|
557
|
+
async grep(pattern, path, glob, maxCount) {
|
|
558
|
+
const result = await ("grep" in backend ? backend.grep(pattern, path, glob, maxCount) : backend.grepRaw(pattern, path, glob));
|
|
559
|
+
if (Array.isArray(result)) return applyGrepMaxCount({
|
|
560
|
+
result: { matches: result },
|
|
561
|
+
maxCount
|
|
562
|
+
});
|
|
560
563
|
if (typeof result === "string") return { error: result };
|
|
561
564
|
return result;
|
|
562
565
|
}
|
|
@@ -591,6 +594,21 @@ function adaptSandboxProtocol(sandbox) {
|
|
|
591
594
|
//#endregion
|
|
592
595
|
//#region src/backends/protocol.ts
|
|
593
596
|
/**
|
|
597
|
+
* Enforce a match cap after a backend grep has completed.
|
|
598
|
+
*
|
|
599
|
+
* When `maxCount` is set and the result exceeds it, the matches are sliced
|
|
600
|
+
* to the cap and the result is flagged `truncated: true`.
|
|
601
|
+
*/
|
|
602
|
+
function applyGrepMaxCount(params) {
|
|
603
|
+
const { result, maxCount } = params;
|
|
604
|
+
if (maxCount == null || result.matches == null || result.matches.length <= maxCount) return result;
|
|
605
|
+
return {
|
|
606
|
+
error: result.error,
|
|
607
|
+
matches: result.matches.slice(0, maxCount),
|
|
608
|
+
truncated: true
|
|
609
|
+
};
|
|
610
|
+
}
|
|
611
|
+
/**
|
|
594
612
|
* Type guard to check if a backend supports execution.
|
|
595
613
|
*
|
|
596
614
|
* @param backend - Backend instance to check
|
|
@@ -871,9 +889,12 @@ var StateBackend = class {
|
|
|
871
889
|
* Search file contents for a literal text pattern.
|
|
872
890
|
* Binary files are skipped.
|
|
873
891
|
*/
|
|
874
|
-
grep(pattern, path = "/", glob = null) {
|
|
892
|
+
grep(pattern, path = "/", glob = null, maxCount = null) {
|
|
875
893
|
const files = this.files;
|
|
876
|
-
return {
|
|
894
|
+
return applyGrepMaxCount({
|
|
895
|
+
result: { matches: grepMatchesFromFiles(files, pattern, path, glob) },
|
|
896
|
+
maxCount
|
|
897
|
+
});
|
|
877
898
|
}
|
|
878
899
|
/**
|
|
879
900
|
* Structured glob matching returning FileInfo objects.
|
|
@@ -1115,7 +1136,7 @@ var CompositeBackend = class {
|
|
|
1115
1136
|
const results = [];
|
|
1116
1137
|
const defaultResult = await this.default.ls(path);
|
|
1117
1138
|
if (defaultResult.error) return defaultResult;
|
|
1118
|
-
|
|
1139
|
+
for (const fi of defaultResult.files || []) results.push(fi);
|
|
1119
1140
|
for (const [routePrefix] of this.sortedRoutes) results.push({
|
|
1120
1141
|
path: routePrefix,
|
|
1121
1142
|
is_dir: true,
|
|
@@ -1151,33 +1172,56 @@ var CompositeBackend = class {
|
|
|
1151
1172
|
}
|
|
1152
1173
|
/**
|
|
1153
1174
|
* Structured search results or error string for invalid input.
|
|
1175
|
+
*
|
|
1176
|
+
* @param maxCount - Optional total cap on returned matches across all routed
|
|
1177
|
+
* backends. When the cap is reached, remaining routes are
|
|
1178
|
+
* short-circuited and the result is flagged `truncated: true`.
|
|
1154
1179
|
*/
|
|
1155
|
-
async grep(pattern, path = "/", glob = null) {
|
|
1180
|
+
async grep(pattern, path = "/", glob = null, maxCount = null) {
|
|
1156
1181
|
const searchPath = path || "/";
|
|
1157
1182
|
for (const [routePrefix, backend] of this.sortedRoutes) if (this.isPathWithinRoute(searchPath, routePrefix)) {
|
|
1158
1183
|
const routeSearchPath = searchPath.substring(routePrefix.length - 1);
|
|
1159
|
-
const raw = await backend.grep(pattern, routeSearchPath || "/", glob);
|
|
1184
|
+
const raw = await backend.grep(pattern, routeSearchPath || "/", glob, maxCount);
|
|
1160
1185
|
if (raw.error) return raw;
|
|
1161
|
-
return
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1186
|
+
return applyGrepMaxCount({
|
|
1187
|
+
result: {
|
|
1188
|
+
matches: (raw.matches || []).map((m) => ({
|
|
1189
|
+
...m,
|
|
1190
|
+
path: routePrefix.slice(0, -1) + m.path
|
|
1191
|
+
})),
|
|
1192
|
+
truncated: raw.truncated
|
|
1193
|
+
},
|
|
1194
|
+
maxCount
|
|
1195
|
+
});
|
|
1165
1196
|
}
|
|
1166
1197
|
const allMatches = [];
|
|
1167
|
-
|
|
1198
|
+
let truncated = false;
|
|
1199
|
+
const rawDefault = await this.default.grep(pattern, searchPath, glob, maxCount);
|
|
1168
1200
|
if (rawDefault.error) return rawDefault;
|
|
1169
|
-
|
|
1201
|
+
for (const m of rawDefault.matches || []) allMatches.push(m);
|
|
1202
|
+
truncated = truncated || rawDefault.truncated === true;
|
|
1170
1203
|
for (const [routePrefix, backend] of Object.entries(this.routes)) {
|
|
1171
1204
|
if (!this.isRouteUnderPath(routePrefix, searchPath)) continue;
|
|
1172
|
-
const
|
|
1205
|
+
const remaining = maxCount == null ? null : Math.max(maxCount - allMatches.length, 0);
|
|
1206
|
+
if (remaining === 0) {
|
|
1207
|
+
truncated = true;
|
|
1208
|
+
break;
|
|
1209
|
+
}
|
|
1210
|
+
const raw = await backend.grep(pattern, "/", glob, remaining);
|
|
1173
1211
|
if (raw.error) return raw;
|
|
1174
|
-
const
|
|
1212
|
+
for (const m of raw.matches || []) allMatches.push({
|
|
1175
1213
|
...m,
|
|
1176
1214
|
path: routePrefix.slice(0, -1) + m.path
|
|
1177
|
-
})
|
|
1178
|
-
|
|
1215
|
+
});
|
|
1216
|
+
truncated = truncated || raw.truncated === true;
|
|
1179
1217
|
}
|
|
1180
|
-
return {
|
|
1218
|
+
return applyGrepMaxCount({
|
|
1219
|
+
result: {
|
|
1220
|
+
matches: allMatches,
|
|
1221
|
+
truncated
|
|
1222
|
+
},
|
|
1223
|
+
maxCount
|
|
1224
|
+
});
|
|
1181
1225
|
}
|
|
1182
1226
|
/**
|
|
1183
1227
|
* Structured glob matching returning FileInfo objects.
|
|
@@ -1188,26 +1232,33 @@ var CompositeBackend = class {
|
|
|
1188
1232
|
const searchPath = path.substring(routePrefix.length - 1);
|
|
1189
1233
|
const result = await backend.glob(pattern, searchPath || "/");
|
|
1190
1234
|
if (result.error) return result;
|
|
1191
|
-
return {
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1235
|
+
return {
|
|
1236
|
+
files: (result.files || []).map((fi) => ({
|
|
1237
|
+
...fi,
|
|
1238
|
+
path: routePrefix.slice(0, -1) + fi.path
|
|
1239
|
+
})),
|
|
1240
|
+
truncated: result.truncated
|
|
1241
|
+
};
|
|
1195
1242
|
}
|
|
1196
1243
|
const defaultResult = await this.default.glob(pattern, path);
|
|
1197
1244
|
if (defaultResult.error) return defaultResult;
|
|
1198
|
-
|
|
1245
|
+
for (const fi of defaultResult.files || []) results.push(fi);
|
|
1246
|
+
let truncated = defaultResult.truncated === true;
|
|
1199
1247
|
for (const [routePrefix, backend] of Object.entries(this.routes)) {
|
|
1200
1248
|
if (!this.isRouteUnderPath(routePrefix, path)) continue;
|
|
1201
1249
|
const result = await backend.glob(pattern, "/");
|
|
1202
1250
|
if (result.error) continue;
|
|
1203
|
-
const
|
|
1251
|
+
for (const fi of result.files || []) results.push({
|
|
1204
1252
|
...fi,
|
|
1205
1253
|
path: routePrefix.slice(0, -1) + fi.path
|
|
1206
|
-
})
|
|
1207
|
-
|
|
1254
|
+
});
|
|
1255
|
+
truncated = truncated || result.truncated === true;
|
|
1208
1256
|
}
|
|
1209
1257
|
results.sort((a, b) => a.path.localeCompare(b.path));
|
|
1210
|
-
return {
|
|
1258
|
+
return {
|
|
1259
|
+
files: results,
|
|
1260
|
+
truncated
|
|
1261
|
+
};
|
|
1211
1262
|
}
|
|
1212
1263
|
/**
|
|
1213
1264
|
* Write content to a file, routing to appropriate backend.
|
|
@@ -1403,6 +1454,15 @@ const READ_FILE_TRUNCATION_MSG = `
|
|
|
1403
1454
|
|
|
1404
1455
|
[Output was truncated due to size limits. The file content is very large. Consider reformatting the file to make it easier to navigate. For example, if this is JSON, use execute(command='jq . {file_path}') to pretty-print it with line breaks. For other formats, you can use appropriate formatting tools to split long lines.]`;
|
|
1405
1456
|
/**
|
|
1457
|
+
* Note appended to grep results that were cut short by the match-count cap.
|
|
1458
|
+
*/
|
|
1459
|
+
const GREP_TRUNCATION_NOTE = "Note: the search stopped early because it hit the maximum match count. The matches above are valid but incomplete. Narrow the search (a more specific pattern or a narrower path), or raise max_count, to see the rest.";
|
|
1460
|
+
/**
|
|
1461
|
+
* Default cap on the number of matches the grep tool returns.
|
|
1462
|
+
* Set to null to disable the cap.
|
|
1463
|
+
*/
|
|
1464
|
+
const DEFAULT_GREP_MAX_COUNT = 1e3;
|
|
1465
|
+
/**
|
|
1406
1466
|
* Message template for evicted tool results.
|
|
1407
1467
|
*/
|
|
1408
1468
|
const TOO_LARGE_TOOL_MSG = langchain.context`
|
|
@@ -1891,13 +1951,14 @@ function createGlobTool(backend, options) {
|
|
|
1891
1951
|
* Create grep tool using backend.
|
|
1892
1952
|
*/
|
|
1893
1953
|
function createGrepTool(backend, options) {
|
|
1894
|
-
const { customDescription, permissions, includeExecution } = options;
|
|
1954
|
+
const { customDescription, permissions, includeExecution, grepMaxCount } = options;
|
|
1895
1955
|
return (0, langchain.tool)(async (input, runtime) => {
|
|
1896
1956
|
const permissionError = checkPermission(permissions, "read", input.path ?? "/");
|
|
1897
1957
|
if (permissionError !== void 0) return toolError(runtime, "grep", permissionError);
|
|
1898
1958
|
const resolvedBackend = await resolveBackend(backend, runtime);
|
|
1899
1959
|
const { pattern, path = "/", glob = null } = input;
|
|
1900
|
-
const
|
|
1960
|
+
const maxCount = input.max_count ?? grepMaxCount;
|
|
1961
|
+
const result = await resolvedBackend.grep(pattern, path, glob, maxCount);
|
|
1901
1962
|
if (result.error) return result.error;
|
|
1902
1963
|
const matches = filterByPermissions(result.matches ?? [], permissions, "read", (m) => m.path);
|
|
1903
1964
|
if (matches.length === 0) return `No matches found for pattern '${pattern}'`;
|
|
@@ -1911,15 +1972,17 @@ function createGrepTool(backend, options) {
|
|
|
1911
1972
|
lines.push(` ${match.line}: ${match.text}`);
|
|
1912
1973
|
}
|
|
1913
1974
|
const truncated = truncateIfTooLong(lines);
|
|
1914
|
-
|
|
1915
|
-
|
|
1975
|
+
let content = Array.isArray(truncated) ? truncated.join("\n") : truncated;
|
|
1976
|
+
if (result.truncated) content += `\n\n${GREP_TRUNCATION_NOTE}`;
|
|
1977
|
+
return content;
|
|
1916
1978
|
}, {
|
|
1917
1979
|
name: "grep",
|
|
1918
1980
|
description: customDescription || getGrepToolDescription(includeExecution),
|
|
1919
1981
|
schema: zod_v4.z.object({
|
|
1920
1982
|
pattern: zod_v4.z.string().describe("Literal text pattern to search for (not regex)"),
|
|
1921
1983
|
path: zod_v4.z.string().optional().default("/").describe("Base path to search from (default: /)"),
|
|
1922
|
-
glob: zod_v4.z.string().optional().nullable().default(null).describe("Optional glob pattern to filter files (e.g., '*.py')")
|
|
1984
|
+
glob: zod_v4.z.string().optional().nullable().default(null).describe("Optional glob pattern to filter files (e.g., '*.py')"),
|
|
1985
|
+
max_count: zod_v4.z.number().int().positive().optional().nullable().default(null).describe("Optional cap on the total number of matches returned across all files. Leave unset to use the configured default. When the cap is hit, results are truncated and a note says so; narrow the pattern or path to see the rest.")
|
|
1923
1986
|
})
|
|
1924
1987
|
});
|
|
1925
1988
|
}
|
|
@@ -1988,7 +2051,7 @@ function allPathsScopedToRoutes(permissions, backend) {
|
|
|
1988
2051
|
* ```
|
|
1989
2052
|
*/
|
|
1990
2053
|
function createFilesystemMiddleware(options = {}) {
|
|
1991
|
-
const { backend = (runtime) => new StateBackend(runtime), systemPrompt: customSystemPrompt = null, customToolDescriptions = null, toolTokenLimitBeforeEvict = 2e4, humanMessageTokenLimitBeforeEvict = 5e4, permissions = [], tools: filesystemTools = null } = options;
|
|
2054
|
+
const { backend = (runtime) => new StateBackend(runtime), systemPrompt: customSystemPrompt = null, customToolDescriptions = null, toolTokenLimitBeforeEvict = 2e4, humanMessageTokenLimitBeforeEvict = 5e4, permissions = [], tools: filesystemTools = null, grepMaxCount = DEFAULT_GREP_MAX_COUNT } = options;
|
|
1992
2055
|
const enabledFilesystemTools = normalizeFilesystemTools(filesystemTools);
|
|
1993
2056
|
const executeToolEnabled = enabledFilesystemTools == null || enabledFilesystemTools.has("execute");
|
|
1994
2057
|
if (permissions.length > 0) validatePermissionPaths(permissions);
|
|
@@ -2024,7 +2087,8 @@ function createFilesystemMiddleware(options = {}) {
|
|
|
2024
2087
|
grep: createGrepTool(backend, {
|
|
2025
2088
|
customDescription: customToolDescriptions?.grep,
|
|
2026
2089
|
permissions,
|
|
2027
|
-
includeExecution: configuredToolNames.has("execute") && typeof backend !== "function" && isSandboxBackend(backend)
|
|
2090
|
+
includeExecution: configuredToolNames.has("execute") && typeof backend !== "function" && isSandboxBackend(backend),
|
|
2091
|
+
grepMaxCount
|
|
2028
2092
|
}),
|
|
2029
2093
|
execute: createExecuteTool(backend, {
|
|
2030
2094
|
customDescription: customToolDescriptions?.execute,
|
|
@@ -6386,7 +6450,7 @@ var StoreBackend = class {
|
|
|
6386
6450
|
* Search file contents for a literal text pattern.
|
|
6387
6451
|
* Binary files are skipped.
|
|
6388
6452
|
*/
|
|
6389
|
-
async grep(pattern, path = "/", glob = null) {
|
|
6453
|
+
async grep(pattern, path = "/", glob = null, maxCount = null) {
|
|
6390
6454
|
const store = this.getStore();
|
|
6391
6455
|
const namespace = this.getNamespace();
|
|
6392
6456
|
const items = await this.searchStorePaginated(store, namespace);
|
|
@@ -6396,7 +6460,10 @@ var StoreBackend = class {
|
|
|
6396
6460
|
} catch {
|
|
6397
6461
|
continue;
|
|
6398
6462
|
}
|
|
6399
|
-
return {
|
|
6463
|
+
return applyGrepMaxCount({
|
|
6464
|
+
result: { matches: grepMatchesFromFiles(files, pattern, path, glob) },
|
|
6465
|
+
maxCount
|
|
6466
|
+
});
|
|
6400
6467
|
}
|
|
6401
6468
|
/**
|
|
6402
6469
|
* Structured glob matching returning FileInfo objects.
|
|
@@ -6695,7 +6762,7 @@ var ContextHubBackend = class ContextHubBackend {
|
|
|
6695
6762
|
modified_at: now
|
|
6696
6763
|
} };
|
|
6697
6764
|
}
|
|
6698
|
-
async grep(pattern, path = null, glob = null) {
|
|
6765
|
+
async grep(pattern, path = null, glob = null, maxCount = null) {
|
|
6699
6766
|
let cache;
|
|
6700
6767
|
try {
|
|
6701
6768
|
cache = await this.ensureCache();
|
|
@@ -6718,7 +6785,10 @@ var ContextHubBackend = class ContextHubBackend {
|
|
|
6718
6785
|
});
|
|
6719
6786
|
}
|
|
6720
6787
|
}
|
|
6721
|
-
return {
|
|
6788
|
+
return applyGrepMaxCount({
|
|
6789
|
+
result: { matches },
|
|
6790
|
+
maxCount
|
|
6791
|
+
});
|
|
6722
6792
|
}
|
|
6723
6793
|
async glob(pattern, _path = "/") {
|
|
6724
6794
|
let cache;
|
|
@@ -7114,7 +7184,7 @@ var BaseSandbox = class {
|
|
|
7114
7184
|
* @param glob - Optional glob pattern to filter which files to search.
|
|
7115
7185
|
* @returns List of GrepMatch dicts containing path, line number, and matched text.
|
|
7116
7186
|
*/
|
|
7117
|
-
async grep(pattern, path = "/", glob = null) {
|
|
7187
|
+
async grep(pattern, path = "/", glob = null, maxCount = null) {
|
|
7118
7188
|
const command = buildGrepCommand(pattern, path, glob);
|
|
7119
7189
|
const output = (await this.execute(command)).output.trim();
|
|
7120
7190
|
if (!output) return { matches: [] };
|
|
@@ -7132,7 +7202,10 @@ var BaseSandbox = class {
|
|
|
7132
7202
|
});
|
|
7133
7203
|
}
|
|
7134
7204
|
}
|
|
7135
|
-
return {
|
|
7205
|
+
return applyGrepMaxCount({
|
|
7206
|
+
result: { matches },
|
|
7207
|
+
maxCount
|
|
7208
|
+
});
|
|
7136
7209
|
}
|
|
7137
7210
|
/**
|
|
7138
7211
|
* Structured glob matching returning FileInfo objects.
|
|
@@ -7631,6 +7704,12 @@ Object.defineProperty(exports, "adaptSandboxProtocol", {
|
|
|
7631
7704
|
return adaptSandboxProtocol;
|
|
7632
7705
|
}
|
|
7633
7706
|
});
|
|
7707
|
+
Object.defineProperty(exports, "applyGrepMaxCount", {
|
|
7708
|
+
enumerable: true,
|
|
7709
|
+
get: function() {
|
|
7710
|
+
return applyGrepMaxCount;
|
|
7711
|
+
}
|
|
7712
|
+
});
|
|
7634
7713
|
Object.defineProperty(exports, "checkEmptyContent", {
|
|
7635
7714
|
enumerable: true,
|
|
7636
7715
|
get: function() {
|
|
@@ -7794,4 +7873,4 @@ Object.defineProperty(exports, "serializeProfile", {
|
|
|
7794
7873
|
}
|
|
7795
7874
|
});
|
|
7796
7875
|
|
|
7797
|
-
//# sourceMappingURL=langsmith-
|
|
7876
|
+
//# sourceMappingURL=langsmith-D2d3Dwcc.cjs.map
|