deepagents 1.10.7 → 1.11.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 +17 -0
- package/dist/{agent-DsjC63Eg.d.cts → agent-CBuaNmw7.d.cts} +164 -11
- package/dist/{agent-DgVtHOV7.d.ts → agent-D0AY-3B9.d.ts} +164 -11
- package/dist/browser.cjs +1 -1
- package/dist/browser.d.cts +2 -2
- package/dist/browser.d.ts +2 -2
- package/dist/browser.js +1 -1
- package/dist/index.cjs +2 -2
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/{langsmith-DjCMSywL.js → langsmith-C7Ok9lF-.js} +272 -83
- package/dist/langsmith-C7Ok9lF-.js.map +1 -0
- package/dist/{langsmith-CiAeUke2.cjs → langsmith-DDhVumyX.cjs} +270 -83
- package/dist/langsmith-DDhVumyX.cjs.map +1 -0
- package/dist/node.cjs +2 -2
- package/dist/node.d.cts +2 -2
- package/dist/node.d.ts +2 -2
- package/dist/node.js +2 -2
- package/dist/{src-ez4XwElW.cjs → src-CmBhLWZw.cjs} +63 -24
- package/dist/src-CmBhLWZw.cjs.map +1 -0
- package/dist/{src-CoLnjzWB.js → src-CokGewqt.js} +63 -24
- package/dist/src-CokGewqt.js.map +1 -0
- package/package.json +1 -1
- package/dist/langsmith-CiAeUke2.cjs.map +0 -1
- package/dist/langsmith-DjCMSywL.js.map +0 -1
- package/dist/src-CoLnjzWB.js.map +0 -1
- package/dist/src-ez4XwElW.cjs.map +0 -1
|
@@ -470,7 +470,7 @@ function migrateToFileDataV2(data, filePath) {
|
|
|
470
470
|
* @returns BackendProtocolV2-compatible backend
|
|
471
471
|
*/
|
|
472
472
|
function adaptBackendProtocol(backend) {
|
|
473
|
-
|
|
473
|
+
const adapted = {
|
|
474
474
|
async ls(path) {
|
|
475
475
|
const result = await ("ls" in backend ? backend.ls(path) : backend.lsInfo(path));
|
|
476
476
|
if (Array.isArray(result)) return { files: result };
|
|
@@ -488,6 +488,7 @@ function adaptBackendProtocol(backend) {
|
|
|
488
488
|
},
|
|
489
489
|
write: (filePath, content) => backend.write(filePath, content),
|
|
490
490
|
edit: (filePath, oldString, newString, replaceAll) => backend.edit(filePath, oldString, newString, replaceAll),
|
|
491
|
+
delete: backend.delete?.bind(backend),
|
|
491
492
|
uploadFiles: backend.uploadFiles ? (files) => backend.uploadFiles(files) : void 0,
|
|
492
493
|
downloadFiles: backend.downloadFiles ? (paths) => backend.downloadFiles(paths) : void 0,
|
|
493
494
|
async read(filePath, offset, limit) {
|
|
@@ -502,6 +503,13 @@ function adaptBackendProtocol(backend) {
|
|
|
502
503
|
return result;
|
|
503
504
|
}
|
|
504
505
|
};
|
|
506
|
+
const routePrefixes = backend.routePrefixes;
|
|
507
|
+
if (Array.isArray(routePrefixes)) Object.defineProperty(adapted, "routePrefixes", {
|
|
508
|
+
value: routePrefixes,
|
|
509
|
+
enumerable: true,
|
|
510
|
+
configurable: true
|
|
511
|
+
});
|
|
512
|
+
return adapted;
|
|
505
513
|
}
|
|
506
514
|
/**
|
|
507
515
|
* Adapt a sandbox backend from v1 to v2 interface.
|
|
@@ -669,7 +677,8 @@ var StateBackend = class {
|
|
|
669
677
|
* In legacy mode, this is a no-op — the caller uses `filesUpdate`
|
|
670
678
|
* from the return value instead.
|
|
671
679
|
*
|
|
672
|
-
* @param update - Map of file paths to their updated {@link FileData}
|
|
680
|
+
* @param update - Map of file paths to their updated {@link FileData},
|
|
681
|
+
* or null deletion markers.
|
|
673
682
|
*/
|
|
674
683
|
sendFilesUpdate(update) {
|
|
675
684
|
if (this.isLegacy) return;
|
|
@@ -793,6 +802,15 @@ var StateBackend = class {
|
|
|
793
802
|
};
|
|
794
803
|
}
|
|
795
804
|
/**
|
|
805
|
+
* Delete a file from state by sending a null deletion marker through Pregel.
|
|
806
|
+
*/
|
|
807
|
+
delete(filePath) {
|
|
808
|
+
if (!(filePath in this.files)) return { error: `Error: File '${filePath}' not found` };
|
|
809
|
+
if (this.isLegacy) return { error: "StateBackend.delete requires a zero-argument StateBackend in a LangGraph execution context." };
|
|
810
|
+
this.sendFilesUpdate({ [filePath]: null });
|
|
811
|
+
return { path: filePath };
|
|
812
|
+
}
|
|
813
|
+
/**
|
|
796
814
|
* Search file contents for a literal text pattern.
|
|
797
815
|
* Binary files are skipped.
|
|
798
816
|
*/
|
|
@@ -1159,6 +1177,19 @@ var CompositeBackend = class {
|
|
|
1159
1177
|
return await backend.edit(strippedKey, oldString, newString, replaceAll);
|
|
1160
1178
|
}
|
|
1161
1179
|
/**
|
|
1180
|
+
* Delete a file, routing to the appropriate backend.
|
|
1181
|
+
*/
|
|
1182
|
+
async delete(filePath) {
|
|
1183
|
+
const [backend, strippedKey] = this.getBackendAndKey(filePath);
|
|
1184
|
+
if (!backend.delete) return { error: "Backend does not support delete" };
|
|
1185
|
+
const result = await backend.delete(strippedKey);
|
|
1186
|
+
if (result.path !== void 0) return {
|
|
1187
|
+
...result,
|
|
1188
|
+
path: filePath
|
|
1189
|
+
};
|
|
1190
|
+
return result;
|
|
1191
|
+
}
|
|
1192
|
+
/**
|
|
1162
1193
|
* Execute a command via the default backend.
|
|
1163
1194
|
* Execution is not path-specific, so it always delegates to the default backend.
|
|
1164
1195
|
*
|
|
@@ -1300,14 +1331,10 @@ const FILESYSTEM_TOOL_NAMES = [
|
|
|
1300
1331
|
"grep",
|
|
1301
1332
|
"execute"
|
|
1302
1333
|
];
|
|
1303
|
-
|
|
1304
|
-
"
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
"read_file",
|
|
1308
|
-
"edit_file",
|
|
1309
|
-
"write_file"
|
|
1310
|
-
];
|
|
1334
|
+
function isFilesystemToolName(name) {
|
|
1335
|
+
return typeof name === "string" && FILESYSTEM_TOOL_NAMES.includes(name);
|
|
1336
|
+
}
|
|
1337
|
+
const TOOLS_EXCLUDED_FROM_EVICTION = FILESYSTEM_TOOL_NAMES.filter((name) => name !== "execute");
|
|
1311
1338
|
/**
|
|
1312
1339
|
* Maximum size for binary (non-text) files read via read_file, in bytes.
|
|
1313
1340
|
* Base64-encoded content is ~33% larger, so 10MB raw ≈ 13.3MB in context.
|
|
@@ -1508,24 +1535,33 @@ function filterByPermissions(entries, rules, operation, getPath) {
|
|
|
1508
1535
|
}
|
|
1509
1536
|
});
|
|
1510
1537
|
}
|
|
1511
|
-
const
|
|
1512
|
-
|
|
1538
|
+
const FILESYSTEM_TOOL_DESCRIPTION_LINES = {
|
|
1539
|
+
ls: "ls: list files in a directory (requires absolute path)",
|
|
1540
|
+
read_file: "read_file: read a file from the filesystem",
|
|
1541
|
+
write_file: "write_file: write to a file in the filesystem",
|
|
1542
|
+
edit_file: "edit_file: edit a file in the filesystem",
|
|
1543
|
+
glob: "glob: find files matching a pattern (e.g., \"**/*.py\")",
|
|
1544
|
+
grep: "grep: search for text within files"
|
|
1545
|
+
};
|
|
1546
|
+
function hasFilesystemToolDescription(name) {
|
|
1547
|
+
return name in FILESYSTEM_TOOL_DESCRIPTION_LINES;
|
|
1548
|
+
}
|
|
1549
|
+
function buildFilesystemSystemPrompt(visibleTools) {
|
|
1550
|
+
const promptToolNames = FILESYSTEM_TOOL_NAMES.filter((name) => visibleTools.has(name));
|
|
1551
|
+
return context`
|
|
1552
|
+
## Following Conventions
|
|
1513
1553
|
|
|
1514
|
-
|
|
1515
|
-
|
|
1554
|
+
- Read files before editing — understand existing content before making changes
|
|
1555
|
+
- Mimic existing style, naming conventions, and patterns
|
|
1516
1556
|
|
|
1517
|
-
|
|
1557
|
+
## Filesystem Tools ${promptToolNames.map((name) => `\`${name}\``).join(", ")}
|
|
1518
1558
|
|
|
1519
|
-
|
|
1520
|
-
|
|
1559
|
+
You have access to a filesystem which you can interact with using these tools.
|
|
1560
|
+
All file paths must start with a /.
|
|
1521
1561
|
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
- edit_file: edit a file in the filesystem
|
|
1526
|
-
- glob: find files matching a pattern (e.g., "**/*.py")
|
|
1527
|
-
- grep: search for text within files
|
|
1528
|
-
`;
|
|
1562
|
+
${promptToolNames.filter(hasFilesystemToolDescription).map((name) => `- ${FILESYSTEM_TOOL_DESCRIPTION_LINES[name]}`).join("\n")}
|
|
1563
|
+
`;
|
|
1564
|
+
}
|
|
1529
1565
|
const LS_TOOL_DESCRIPTION = context`
|
|
1530
1566
|
Lists all files in a directory.
|
|
1531
1567
|
|
|
@@ -1899,6 +1935,12 @@ function createExecuteTool(backend, options) {
|
|
|
1899
1935
|
* Returns true only when backend exposes route prefixes (CompositeBackend) and
|
|
1900
1936
|
* every permission path is scoped under one of them.
|
|
1901
1937
|
*/
|
|
1938
|
+
function normalizeFilesystemTools(tools) {
|
|
1939
|
+
if (tools == null || tools === "all") return null;
|
|
1940
|
+
const enabledTools = new Set(tools);
|
|
1941
|
+
if (!enabledTools.has("read_file")) throw new Error("read_file must be included in tools; it is required by FilesystemMiddleware");
|
|
1942
|
+
return enabledTools;
|
|
1943
|
+
}
|
|
1902
1944
|
function allPathsScopedToRoutes(permissions, backend) {
|
|
1903
1945
|
if (!CompositeBackend.isInstance(backend)) return false;
|
|
1904
1946
|
const prefixes = backend.routePrefixes;
|
|
@@ -1906,13 +1948,43 @@ function allPathsScopedToRoutes(permissions, backend) {
|
|
|
1906
1948
|
return permissions.every((rule) => rule.paths.every((path) => prefixes.some((prefix) => path.startsWith(prefix.endsWith("/") ? prefix : `${prefix}/`))));
|
|
1907
1949
|
}
|
|
1908
1950
|
/**
|
|
1909
|
-
* Create
|
|
1951
|
+
* Create middleware that provides built-in filesystem tools and filesystem-aware
|
|
1952
|
+
* prompt guidance.
|
|
1953
|
+
*
|
|
1954
|
+
* By default, the middleware registers every built-in filesystem tool listed in
|
|
1955
|
+
* {@link FILESYSTEM_TOOL_NAMES}. Use {@link FilesystemMiddlewareOptions.tools}
|
|
1956
|
+
* to narrow that set for read-only, search-only, or otherwise restricted
|
|
1957
|
+
* agents. The allowlist only controls built-in filesystem tools; custom tools
|
|
1958
|
+
* from the agent or other middleware are left untouched.
|
|
1959
|
+
*
|
|
1960
|
+
* The middleware also filters tools whose backend capabilities are unavailable
|
|
1961
|
+
* at request time. In particular, `execute` is only visible when the resolved
|
|
1962
|
+
* backend supports command execution. The filesystem prompt is generated from
|
|
1963
|
+
* the final visible filesystem tools so the model is not instructed to call
|
|
1964
|
+
* tools it cannot see.
|
|
1965
|
+
*
|
|
1966
|
+
* @param options Filesystem middleware configuration.
|
|
1967
|
+
* @returns Agent middleware that contributes filesystem state, tools, prompt
|
|
1968
|
+
* guidance, permission checks, and large-result eviction.
|
|
1969
|
+
*
|
|
1970
|
+
* @example Read-only filesystem middleware
|
|
1971
|
+
* ```ts
|
|
1972
|
+
* const middleware = createFilesystemMiddleware({
|
|
1973
|
+
* tools: ["read_file", "ls", "glob", "grep"],
|
|
1974
|
+
* });
|
|
1975
|
+
* ```
|
|
1910
1976
|
*/
|
|
1911
1977
|
function createFilesystemMiddleware(options = {}) {
|
|
1912
|
-
const { backend = (runtime) => new StateBackend(runtime), systemPrompt: customSystemPrompt = null, customToolDescriptions = null, toolTokenLimitBeforeEvict = 2e4, humanMessageTokenLimitBeforeEvict = 5e4, permissions = [] } = options;
|
|
1978
|
+
const { backend = (runtime) => new StateBackend(runtime), systemPrompt: customSystemPrompt = null, customToolDescriptions = null, toolTokenLimitBeforeEvict = 2e4, humanMessageTokenLimitBeforeEvict = 5e4, permissions = [], tools: filesystemTools = null } = options;
|
|
1979
|
+
const enabledFilesystemTools = normalizeFilesystemTools(filesystemTools);
|
|
1980
|
+
const executeToolEnabled = enabledFilesystemTools == null || enabledFilesystemTools.has("execute");
|
|
1913
1981
|
if (permissions.length > 0) validatePermissionPaths(permissions);
|
|
1914
|
-
if (permissions.length > 0 && typeof backend !== "function" && isSandboxBackend(backend) && !allPathsScopedToRoutes(permissions, backend)) throw new Error("Filesystem permissions cannot be used with a backend that supports command execution. Shell commands can access any path, making path-based rules ineffective. Either remove permissions, use a backend without execution support, or use a CompositeBackend with all permission paths scoped to a route prefix.");
|
|
1915
|
-
const baseSystemPrompt = customSystemPrompt
|
|
1982
|
+
if (permissions.length > 0 && executeToolEnabled && typeof backend !== "function" && isSandboxBackend(backend) && !allPathsScopedToRoutes(permissions, backend)) throw new Error("Filesystem permissions cannot be used with a backend that supports command execution. Shell commands can access any path, making path-based rules ineffective. Either remove permissions, use a backend without execution support, or use a CompositeBackend with all permission paths scoped to a route prefix.");
|
|
1983
|
+
const baseSystemPrompt = customSystemPrompt ?? null;
|
|
1984
|
+
/**
|
|
1985
|
+
* All tools including execute
|
|
1986
|
+
* (execute will be filtered at runtime if backend doesn't support it)
|
|
1987
|
+
*/
|
|
1916
1988
|
const allToolsByName = {
|
|
1917
1989
|
ls: createLsTool(backend, {
|
|
1918
1990
|
customDescription: customToolDescriptions?.ls,
|
|
@@ -1944,7 +2016,7 @@ function createFilesystemMiddleware(options = {}) {
|
|
|
1944
2016
|
permissions
|
|
1945
2017
|
})
|
|
1946
2018
|
};
|
|
1947
|
-
const allTools =
|
|
2019
|
+
const allTools = FILESYSTEM_TOOL_NAMES.filter((name) => enabledFilesystemTools == null || enabledFilesystemTools.has(name)).map((name) => allToolsByName[name]);
|
|
1948
2020
|
async function processToolMessage(msg, runtime, state, fallbackToolCallId) {
|
|
1949
2021
|
if (!toolTokenLimitBeforeEvict) return {
|
|
1950
2022
|
message: msg,
|
|
@@ -2018,8 +2090,14 @@ function createFilesystemMiddleware(options = {}) {
|
|
|
2018
2090
|
}));
|
|
2019
2091
|
let tools = request.tools;
|
|
2020
2092
|
if (!supportsExecution) tools = tools.filter((t) => t.name !== "execute");
|
|
2021
|
-
|
|
2022
|
-
|
|
2093
|
+
const visibleFilesystemTools = /* @__PURE__ */ new Set();
|
|
2094
|
+
for (const currentTool of tools) {
|
|
2095
|
+
const toolName = typeof currentTool.name === "string" ? currentTool.name : void 0;
|
|
2096
|
+
if (isFilesystemToolName(toolName)) visibleFilesystemTools.add(toolName);
|
|
2097
|
+
}
|
|
2098
|
+
const executionActive = supportsExecution && visibleFilesystemTools.has("execute");
|
|
2099
|
+
let filesystemPrompt = baseSystemPrompt ?? buildFilesystemSystemPrompt(visibleFilesystemTools);
|
|
2100
|
+
if (executionActive) filesystemPrompt = `${filesystemPrompt}\n\n${EXECUTION_SYSTEM_PROMPT}`;
|
|
2023
2101
|
const newSystemMessage = request.systemMessage.concat(filesystemPrompt);
|
|
2024
2102
|
let messages = request.messages;
|
|
2025
2103
|
if (humanMessageTokenLimitBeforeEvict && messages) {
|
|
@@ -3457,6 +3535,43 @@ function createSkillsMiddleware(options) {
|
|
|
3457
3535
|
});
|
|
3458
3536
|
}
|
|
3459
3537
|
//#endregion
|
|
3538
|
+
//#region src/middleware/utils.ts
|
|
3539
|
+
/**
|
|
3540
|
+
* Merge custom middleware into an assembled stack by `.name`.
|
|
3541
|
+
*
|
|
3542
|
+
* Matching custom middleware replaces the existing entry in place. New
|
|
3543
|
+
* middleware is appended after the base stack in caller-provided order.
|
|
3544
|
+
*/
|
|
3545
|
+
function mergeMiddleware$1(base, custom) {
|
|
3546
|
+
const merged = new Map(base.map((middleware) => [middleware.name, middleware]));
|
|
3547
|
+
for (const middleware of custom) merged.set(middleware.name, middleware);
|
|
3548
|
+
return [...merged.values()];
|
|
3549
|
+
}
|
|
3550
|
+
function middlewareNames(middleware) {
|
|
3551
|
+
return new Set(middleware.map((entry) => entry.name));
|
|
3552
|
+
}
|
|
3553
|
+
function matchingMiddleware(middleware, names) {
|
|
3554
|
+
return middleware.filter((entry) => names.has(entry.name));
|
|
3555
|
+
}
|
|
3556
|
+
/**
|
|
3557
|
+
* Merge custom middleware into default and tail middleware segments.
|
|
3558
|
+
*
|
|
3559
|
+
* Same-name custom entries replace matching defaults in either segment. Novel
|
|
3560
|
+
* custom entries are inserted between the default and tail segments unless
|
|
3561
|
+
* `appendNew` is false.
|
|
3562
|
+
*/
|
|
3563
|
+
function mergeMiddlewareStack(defaultMiddleware, customMiddleware, tailMiddleware = [], options = {}) {
|
|
3564
|
+
const defaultMiddlewareNames = middlewareNames(defaultMiddleware);
|
|
3565
|
+
const tailMiddlewareNames = middlewareNames(tailMiddleware);
|
|
3566
|
+
const knownMiddlewareNames = /* @__PURE__ */ new Set([...defaultMiddlewareNames, ...tailMiddlewareNames]);
|
|
3567
|
+
const novelMiddleware = options.appendNew === false ? [] : customMiddleware.filter((entry) => !knownMiddlewareNames.has(entry.name));
|
|
3568
|
+
return [
|
|
3569
|
+
...mergeMiddleware$1(defaultMiddleware, matchingMiddleware(customMiddleware, defaultMiddlewareNames)),
|
|
3570
|
+
...novelMiddleware,
|
|
3571
|
+
...mergeMiddleware$1(tailMiddleware, matchingMiddleware(customMiddleware, tailMiddlewareNames))
|
|
3572
|
+
];
|
|
3573
|
+
}
|
|
3574
|
+
//#endregion
|
|
3460
3575
|
//#region src/middleware/completion_callback.ts
|
|
3461
3576
|
/**
|
|
3462
3577
|
* Callback middleware for async subagents.
|
|
@@ -5048,6 +5163,28 @@ function createCacheBreakpointMiddleware() {
|
|
|
5048
5163
|
});
|
|
5049
5164
|
}
|
|
5050
5165
|
//#endregion
|
|
5166
|
+
//#region src/middleware/tool_exclusion.ts
|
|
5167
|
+
function hasToolName(tool) {
|
|
5168
|
+
return tool !== null && typeof tool === "object" && "name" in tool && typeof tool.name === "string";
|
|
5169
|
+
}
|
|
5170
|
+
/**
|
|
5171
|
+
* Create middleware that removes excluded tools after all tool-injecting
|
|
5172
|
+
* middleware has had a chance to add tools to the request.
|
|
5173
|
+
*
|
|
5174
|
+
* @internal
|
|
5175
|
+
*/
|
|
5176
|
+
function createToolExclusionMiddleware(excludedTools) {
|
|
5177
|
+
return createMiddleware({
|
|
5178
|
+
name: "_ToolExclusionMiddleware",
|
|
5179
|
+
wrapModelCall(request, handler) {
|
|
5180
|
+
return handler({
|
|
5181
|
+
...request,
|
|
5182
|
+
tools: request.tools?.filter((tool) => !hasToolName(tool) || !excludedTools.has(tool.name))
|
|
5183
|
+
});
|
|
5184
|
+
}
|
|
5185
|
+
});
|
|
5186
|
+
}
|
|
5187
|
+
//#endregion
|
|
5051
5188
|
//#region src/profiles/keys.ts
|
|
5052
5189
|
/**
|
|
5053
5190
|
* Normalize and validate a profile registry key.
|
|
@@ -5751,6 +5888,31 @@ const BASE_AGENT_PROMPT = context`
|
|
|
5751
5888
|
|
|
5752
5889
|
For longer tasks, provide brief progress updates at reasonable intervals — a concise sentence recapping what you've done and what's next.
|
|
5753
5890
|
`;
|
|
5891
|
+
const PROMPT_SEPARATOR = "\n\n";
|
|
5892
|
+
/** Normalize legacy system prompt values to the structured representation. */
|
|
5893
|
+
function normalizeSystemPrompt(systemPrompt) {
|
|
5894
|
+
if (systemPrompt === void 0) return {};
|
|
5895
|
+
if (typeof systemPrompt === "string" || SystemMessage.isInstance(systemPrompt)) return { prefix: systemPrompt };
|
|
5896
|
+
return systemPrompt;
|
|
5897
|
+
}
|
|
5898
|
+
/** Assemble prompt parts while preserving structured message content blocks. */
|
|
5899
|
+
function assemblePromptParts(parts) {
|
|
5900
|
+
if (parts.length === 0) return "";
|
|
5901
|
+
if (parts.every((part) => typeof part === "string")) return parts.join(PROMPT_SEPARATOR);
|
|
5902
|
+
const contentBlocks = [];
|
|
5903
|
+
for (const [index, part] of parts.entries()) {
|
|
5904
|
+
if (index > 0) contentBlocks.push({
|
|
5905
|
+
type: "text",
|
|
5906
|
+
text: PROMPT_SEPARATOR
|
|
5907
|
+
});
|
|
5908
|
+
if (SystemMessage.isInstance(part)) contentBlocks.push(...part.contentBlocks);
|
|
5909
|
+
else contentBlocks.push({
|
|
5910
|
+
type: "text",
|
|
5911
|
+
text: part
|
|
5912
|
+
});
|
|
5913
|
+
}
|
|
5914
|
+
return new SystemMessage({ contentBlocks });
|
|
5915
|
+
}
|
|
5754
5916
|
const BUILTIN_TOOL_NAMES = /* @__PURE__ */ new Set([
|
|
5755
5917
|
...FILESYSTEM_TOOL_NAMES,
|
|
5756
5918
|
...ASYNC_TASK_TOOL_NAMES,
|
|
@@ -5796,6 +5958,8 @@ function createDeepAgent(params = {}) {
|
|
|
5796
5958
|
providerHint: getModelProvider(model),
|
|
5797
5959
|
identifierHint: getModelIdentifier(model)
|
|
5798
5960
|
});
|
|
5961
|
+
const filesystemTools = FILESYSTEM_TOOL_NAMES.filter((toolName) => !harnessProfile.excludedTools.has(toolName));
|
|
5962
|
+
const profileFilesystemTools = filesystemTools.length === FILESYSTEM_TOOL_NAMES.length || !filesystemTools.includes("read_file") ? void 0 : filesystemTools;
|
|
5799
5963
|
const toolOverrides = harnessProfile.toolDescriptionOverrides;
|
|
5800
5964
|
const effectiveTools = Object.keys(toolOverrides).length > 0 ? tools.map((t) => t.name in toolOverrides ? Object.assign(Object.create(Object.getPrototypeOf(t)), t, { description: toolOverrides[t.name] }) : t) : tools;
|
|
5801
5965
|
const anthropicModel = isAnthropicModel(model);
|
|
@@ -5817,23 +5981,26 @@ function createDeepAgent(params = {}) {
|
|
|
5817
5981
|
* Only the general-purpose subagent inherits the main agent's skills.
|
|
5818
5982
|
* If a custom subagent needs skills, it must specify its own `skills` array.
|
|
5819
5983
|
*/
|
|
5820
|
-
const
|
|
5984
|
+
const createSubagentDefaultMiddleware = (input) => {
|
|
5821
5985
|
const effectivePermissions = input.permissions ?? permissions;
|
|
5822
|
-
|
|
5986
|
+
return [
|
|
5823
5987
|
todoListMiddleware(),
|
|
5824
5988
|
createFilesystemMiddleware({
|
|
5825
5989
|
backend,
|
|
5826
|
-
permissions: effectivePermissions
|
|
5990
|
+
permissions: effectivePermissions,
|
|
5991
|
+
tools: profileFilesystemTools
|
|
5827
5992
|
}),
|
|
5828
5993
|
createSummarizationMiddleware({ backend }),
|
|
5829
5994
|
createPatchToolCallsMiddleware(),
|
|
5830
5995
|
...input.skills != null && input.skills.length > 0 ? [createSkillsMiddleware({
|
|
5831
5996
|
backend,
|
|
5832
5997
|
sources: input.skills
|
|
5833
|
-
})] : []
|
|
5834
|
-
...input.middleware ?? [],
|
|
5835
|
-
...cacheMiddleware
|
|
5998
|
+
})] : []
|
|
5836
5999
|
];
|
|
6000
|
+
};
|
|
6001
|
+
const normalizeSubagentSpec = (input) => {
|
|
6002
|
+
let subagentMiddleware = mergeMiddlewareStack(createSubagentDefaultMiddleware(input), input.middleware ?? [], cacheMiddleware);
|
|
6003
|
+
if (harnessProfile.excludedMiddleware.size > 0) subagentMiddleware = subagentMiddleware.filter((middleware) => !harnessProfile.excludedMiddleware.has(middleware.name));
|
|
5837
6004
|
return {
|
|
5838
6005
|
...input,
|
|
5839
6006
|
tools: input.tools ?? [],
|
|
@@ -5854,6 +6021,7 @@ function createDeepAgent(params = {}) {
|
|
|
5854
6021
|
skills,
|
|
5855
6022
|
tools: effectiveTools
|
|
5856
6023
|
});
|
|
6024
|
+
generalPurposeSpec.middleware = mergeMiddlewareStack(generalPurposeSpec.middleware ?? [], customMiddleware, [], { appendNew: false });
|
|
5857
6025
|
inlineSubagents.unshift(generalPurposeSpec);
|
|
5858
6026
|
}
|
|
5859
6027
|
const skillsMiddleware = skills != null && skills.length > 0 ? [createSkillsMiddleware({
|
|
@@ -5864,7 +6032,8 @@ function createDeepAgent(params = {}) {
|
|
|
5864
6032
|
todoListMiddleware(),
|
|
5865
6033
|
createFilesystemMiddleware({
|
|
5866
6034
|
backend,
|
|
5867
|
-
permissions
|
|
6035
|
+
permissions,
|
|
6036
|
+
tools: profileFilesystemTools
|
|
5868
6037
|
}),
|
|
5869
6038
|
createSubAgentMiddleware({
|
|
5870
6039
|
defaultModel: model,
|
|
@@ -5876,15 +6045,16 @@ function createDeepAgent(params = {}) {
|
|
|
5876
6045
|
createSummarizationMiddleware({ backend }),
|
|
5877
6046
|
createPatchToolCallsMiddleware()
|
|
5878
6047
|
];
|
|
5879
|
-
|
|
6048
|
+
let middleware = mergeMiddlewareStack([
|
|
5880
6049
|
todoMiddleware,
|
|
5881
6050
|
...skillsMiddleware,
|
|
5882
6051
|
fsMiddleware,
|
|
5883
6052
|
subagentMiddleware,
|
|
5884
6053
|
summarizationMiddleware,
|
|
5885
6054
|
patchToolCallsMiddleware,
|
|
5886
|
-
...asyncSubAgents.length > 0 ? [createAsyncSubAgentMiddleware({ asyncSubAgents })] : []
|
|
5887
|
-
|
|
6055
|
+
...asyncSubAgents.length > 0 ? [createAsyncSubAgentMiddleware({ asyncSubAgents })] : []
|
|
6056
|
+
], customMiddleware, [
|
|
6057
|
+
...resolveMiddleware(harnessProfile.extraMiddleware),
|
|
5888
6058
|
...cacheMiddleware,
|
|
5889
6059
|
...memory && memory.length > 0 ? [createMemoryMiddleware({
|
|
5890
6060
|
backend,
|
|
@@ -5892,32 +6062,19 @@ function createDeepAgent(params = {}) {
|
|
|
5892
6062
|
addCacheControl: anthropicModel
|
|
5893
6063
|
})] : [],
|
|
5894
6064
|
...interruptOn ? [humanInTheLoopMiddleware({ interruptOn })] : []
|
|
5895
|
-
];
|
|
5896
|
-
const profileMiddleware = resolveMiddleware(harnessProfile.extraMiddleware);
|
|
5897
|
-
if (profileMiddleware.length > 0) {
|
|
5898
|
-
const cacheIdx = middleware.findIndex((m) => m.name === "AnthropicPromptCachingMiddleware");
|
|
5899
|
-
if (cacheIdx !== -1) middleware.splice(cacheIdx, 0, ...profileMiddleware);
|
|
5900
|
-
else middleware.push(...profileMiddleware);
|
|
5901
|
-
}
|
|
6065
|
+
]);
|
|
5902
6066
|
if (harnessProfile.excludedMiddleware.size > 0) {
|
|
5903
6067
|
const excluded = harnessProfile.excludedMiddleware;
|
|
5904
|
-
|
|
5905
|
-
|
|
5906
|
-
|
|
5907
|
-
|
|
5908
|
-
|
|
5909
|
-
|
|
5910
|
-
|
|
5911
|
-
|
|
5912
|
-
|
|
5913
|
-
|
|
5914
|
-
...request,
|
|
5915
|
-
tools: request.tools?.filter((t) => !excludedTools.has(t.name))
|
|
5916
|
-
});
|
|
5917
|
-
}
|
|
5918
|
-
}));
|
|
5919
|
-
}
|
|
5920
|
-
const effectiveBasePrompt = applyProfilePrompt(harnessProfile, BASE_AGENT_PROMPT);
|
|
6068
|
+
middleware = middleware.filter((entry) => !excluded.has(entry.name));
|
|
6069
|
+
}
|
|
6070
|
+
if (harnessProfile.excludedTools.size > 0) middleware.push(createToolExclusionMiddleware(harnessProfile.excludedTools));
|
|
6071
|
+
const promptConfig = normalizeSystemPrompt(systemPrompt);
|
|
6072
|
+
const promptParts = [];
|
|
6073
|
+
if (promptConfig.prefix !== void 0 && promptConfig.prefix !== null) promptParts.push(promptConfig.prefix);
|
|
6074
|
+
const activeBasePrompt = promptConfig.base !== void 0 ? promptConfig.base : harnessProfile.baseSystemPrompt ?? BASE_AGENT_PROMPT;
|
|
6075
|
+
if (activeBasePrompt !== null) promptParts.push(activeBasePrompt);
|
|
6076
|
+
if (promptConfig.suffix) promptParts.push(promptConfig.suffix);
|
|
6077
|
+
if (harnessProfile.systemPromptSuffix) promptParts.push(harnessProfile.systemPromptSuffix);
|
|
5921
6078
|
/**
|
|
5922
6079
|
* Return as DeepAgent with proper DeepAgentTypeConfig
|
|
5923
6080
|
* - Response: InferStructuredResponse<TResponse> (unwraps ToolStrategy<T>/ProviderStrategy<T> → T)
|
|
@@ -5930,19 +6087,7 @@ function createDeepAgent(params = {}) {
|
|
|
5930
6087
|
*/
|
|
5931
6088
|
return createAgent({
|
|
5932
6089
|
model,
|
|
5933
|
-
systemPrompt:
|
|
5934
|
-
type: "text",
|
|
5935
|
-
text: systemPrompt
|
|
5936
|
-
}, {
|
|
5937
|
-
type: "text",
|
|
5938
|
-
text: effectiveBasePrompt
|
|
5939
|
-
}] }) : SystemMessage.isInstance(systemPrompt) ? new SystemMessage({ contentBlocks: [...systemPrompt.contentBlocks, {
|
|
5940
|
-
type: "text",
|
|
5941
|
-
text: effectiveBasePrompt
|
|
5942
|
-
}] }) : new SystemMessage({ contentBlocks: [{
|
|
5943
|
-
type: "text",
|
|
5944
|
-
text: effectiveBasePrompt
|
|
5945
|
-
}] }),
|
|
6090
|
+
systemPrompt: assemblePromptParts(promptParts),
|
|
5946
6091
|
stateSchema,
|
|
5947
6092
|
tools: effectiveTools,
|
|
5948
6093
|
middleware,
|
|
@@ -6294,6 +6439,19 @@ var StoreBackend = class {
|
|
|
6294
6439
|
}
|
|
6295
6440
|
}
|
|
6296
6441
|
/**
|
|
6442
|
+
* Delete a file from the store.
|
|
6443
|
+
*
|
|
6444
|
+
* The file path is used as an exact store key. Wildcards are treated
|
|
6445
|
+
* literally and do not expand to multiple entries.
|
|
6446
|
+
*/
|
|
6447
|
+
async delete(filePath) {
|
|
6448
|
+
const store = this.getStore();
|
|
6449
|
+
const namespace = this.getNamespace();
|
|
6450
|
+
if (!await store.get(namespace, filePath)) return { error: `Error: File '${filePath}' not found` };
|
|
6451
|
+
await store.delete(namespace, filePath);
|
|
6452
|
+
return { path: filePath };
|
|
6453
|
+
}
|
|
6454
|
+
/**
|
|
6297
6455
|
* Search file contents for a literal text pattern.
|
|
6298
6456
|
* Binary files are skipped.
|
|
6299
6457
|
*/
|
|
@@ -6506,10 +6664,10 @@ var ContextHubBackend = class ContextHubBackend {
|
|
|
6506
6664
|
if (this.cache === null) throw new Error("Context Hub cache failed to initialize");
|
|
6507
6665
|
return this.cache;
|
|
6508
6666
|
}
|
|
6509
|
-
async commit(
|
|
6510
|
-
if (Object.keys(
|
|
6667
|
+
async commit(changes) {
|
|
6668
|
+
if (Object.keys(changes).length === 0) return;
|
|
6511
6669
|
const payload = {};
|
|
6512
|
-
for (const [path, content] of Object.entries(
|
|
6670
|
+
for (const [path, content] of Object.entries(changes)) payload[path] = content === null ? null : {
|
|
6513
6671
|
type: "file",
|
|
6514
6672
|
content
|
|
6515
6673
|
};
|
|
@@ -6519,7 +6677,14 @@ var ContextHubBackend = class ContextHubBackend {
|
|
|
6519
6677
|
});
|
|
6520
6678
|
const match = URL_COMMIT_SUFFIX_RE.exec(url);
|
|
6521
6679
|
if (match) this.commitHash = match[1];
|
|
6522
|
-
if (this.cache !== null)
|
|
6680
|
+
if (this.cache !== null) {
|
|
6681
|
+
const deletions = new Set(Object.entries(changes).filter(([, content]) => content === null).map(([path]) => path));
|
|
6682
|
+
const updates = Object.fromEntries(Object.entries(changes).filter((entry) => entry[1] !== null));
|
|
6683
|
+
this.cache = {
|
|
6684
|
+
...Object.fromEntries(Object.entries(this.cache).filter(([path]) => !deletions.has(path))),
|
|
6685
|
+
...updates
|
|
6686
|
+
};
|
|
6687
|
+
}
|
|
6523
6688
|
}
|
|
6524
6689
|
/**
|
|
6525
6690
|
* Return linked-entry paths mapped to their repo handles.
|
|
@@ -6678,6 +6843,20 @@ var ContextHubBackend = class ContextHubBackend {
|
|
|
6678
6843
|
throw error;
|
|
6679
6844
|
}
|
|
6680
6845
|
}
|
|
6846
|
+
async delete(filePath) {
|
|
6847
|
+
const hubPath = ContextHubBackend.stripPrefix(filePath);
|
|
6848
|
+
try {
|
|
6849
|
+
if (!(hubPath in await this.ensureCache())) return { error: `Error: File '${filePath}' not found` };
|
|
6850
|
+
await this.commit({ [hubPath]: null });
|
|
6851
|
+
return { path: filePath };
|
|
6852
|
+
} catch (error) {
|
|
6853
|
+
if (isLangSmithError(error)) {
|
|
6854
|
+
this.cache = null;
|
|
6855
|
+
return { error: ContextHubBackend.toHubUnavailableError(error) };
|
|
6856
|
+
}
|
|
6857
|
+
throw error;
|
|
6858
|
+
}
|
|
6859
|
+
}
|
|
6681
6860
|
async uploadFiles(files) {
|
|
6682
6861
|
const decoder = new TextDecoder("utf-8", { fatal: true });
|
|
6683
6862
|
const decoded = [];
|
|
@@ -7170,6 +7349,16 @@ var BaseSandbox = class {
|
|
|
7170
7349
|
occurrences: count
|
|
7171
7350
|
};
|
|
7172
7351
|
}
|
|
7352
|
+
/**
|
|
7353
|
+
* Delete a file from the sandbox via a server-side rm.
|
|
7354
|
+
*
|
|
7355
|
+
* Uses rm -f, so deleting a path that does not exist succeeds silently.
|
|
7356
|
+
*/
|
|
7357
|
+
async delete(filePath) {
|
|
7358
|
+
const result = await this.execute(`rm -f ${shellQuote(filePath)}`);
|
|
7359
|
+
if (result.exitCode === 0) return { path: filePath };
|
|
7360
|
+
return { error: `Error deleting file '${filePath}': ${result.output.trim() || "unknown error"}` };
|
|
7361
|
+
}
|
|
7173
7362
|
};
|
|
7174
7363
|
//#endregion
|
|
7175
7364
|
//#region src/backends/langsmith.ts
|
|
@@ -7373,4 +7562,4 @@ var LangSmithSandbox = class LangSmithSandbox extends BaseSandbox {
|
|
|
7373
7562
|
//#endregion
|
|
7374
7563
|
export { GENERAL_PURPOSE_SUBAGENT as A, isSandboxProtocol as B, MAX_SKILL_NAME_LENGTH as C, createPatchToolCallsMiddleware as D, filesValue as E, createFilesystemMiddleware as F, getMimeType as G, adaptBackendProtocol as H, CompositeBackend as I, isTextMimeType as K, StateBackend as L, TASK_SYSTEM_PROMPT as M, createSubAgent as N, DEFAULT_GENERAL_PURPOSE_DESCRIPTION as O, createSubAgentMiddleware as P, SandboxError as R, MAX_SKILL_FILE_SIZE as S, createMemoryMiddleware as T, adaptSandboxProtocol as U, resolveBackend as V, checkEmptyContent as W, isAsyncSubAgent as _, createDeepAgent as a, createCompletionCallbackMiddleware as b, generalPurposeSubagentConfigSchema as c, serializeProfile as d, EMPTY_HARNESS_PROFILE as f, createAsyncSubAgentMiddleware as g, ConfigurationError as h, StoreBackend as i, SUBAGENT_RESPONSE_FORMAT_CONFIG_KEY as j, DEFAULT_SUBAGENT_PROMPT as k, harnessProfileConfigSchema as l, REQUIRED_MIDDLEWARE_NAMES as m, BaseSandbox as n, getHarnessProfile as o, createHarnessProfile as p, performStringReplacement as q, ContextHubBackend as r, registerHarnessProfile as s, LangSmithSandbox as t, parseHarnessProfileConfig as u, computeSummarizationDefaults as v, createSkillsMiddleware as w, MAX_SKILL_DESCRIPTION_LENGTH as x, createSummarizationMiddleware as y, isSandboxBackend as z };
|
|
7375
7564
|
|
|
7376
|
-
//# sourceMappingURL=langsmith-
|
|
7565
|
+
//# sourceMappingURL=langsmith-C7Ok9lF-.js.map
|