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
|
@@ -494,7 +494,7 @@ function migrateToFileDataV2(data, filePath) {
|
|
|
494
494
|
* @returns BackendProtocolV2-compatible backend
|
|
495
495
|
*/
|
|
496
496
|
function adaptBackendProtocol(backend) {
|
|
497
|
-
|
|
497
|
+
const adapted = {
|
|
498
498
|
async ls(path) {
|
|
499
499
|
const result = await ("ls" in backend ? backend.ls(path) : backend.lsInfo(path));
|
|
500
500
|
if (Array.isArray(result)) return { files: result };
|
|
@@ -512,6 +512,7 @@ function adaptBackendProtocol(backend) {
|
|
|
512
512
|
},
|
|
513
513
|
write: (filePath, content) => backend.write(filePath, content),
|
|
514
514
|
edit: (filePath, oldString, newString, replaceAll) => backend.edit(filePath, oldString, newString, replaceAll),
|
|
515
|
+
delete: backend.delete?.bind(backend),
|
|
515
516
|
uploadFiles: backend.uploadFiles ? (files) => backend.uploadFiles(files) : void 0,
|
|
516
517
|
downloadFiles: backend.downloadFiles ? (paths) => backend.downloadFiles(paths) : void 0,
|
|
517
518
|
async read(filePath, offset, limit) {
|
|
@@ -526,6 +527,13 @@ function adaptBackendProtocol(backend) {
|
|
|
526
527
|
return result;
|
|
527
528
|
}
|
|
528
529
|
};
|
|
530
|
+
const routePrefixes = backend.routePrefixes;
|
|
531
|
+
if (Array.isArray(routePrefixes)) Object.defineProperty(adapted, "routePrefixes", {
|
|
532
|
+
value: routePrefixes,
|
|
533
|
+
enumerable: true,
|
|
534
|
+
configurable: true
|
|
535
|
+
});
|
|
536
|
+
return adapted;
|
|
529
537
|
}
|
|
530
538
|
/**
|
|
531
539
|
* Adapt a sandbox backend from v1 to v2 interface.
|
|
@@ -693,7 +701,8 @@ var StateBackend = class {
|
|
|
693
701
|
* In legacy mode, this is a no-op — the caller uses `filesUpdate`
|
|
694
702
|
* from the return value instead.
|
|
695
703
|
*
|
|
696
|
-
* @param update - Map of file paths to their updated {@link FileData}
|
|
704
|
+
* @param update - Map of file paths to their updated {@link FileData},
|
|
705
|
+
* or null deletion markers.
|
|
697
706
|
*/
|
|
698
707
|
sendFilesUpdate(update) {
|
|
699
708
|
if (this.isLegacy) return;
|
|
@@ -817,6 +826,15 @@ var StateBackend = class {
|
|
|
817
826
|
};
|
|
818
827
|
}
|
|
819
828
|
/**
|
|
829
|
+
* Delete a file from state by sending a null deletion marker through Pregel.
|
|
830
|
+
*/
|
|
831
|
+
delete(filePath) {
|
|
832
|
+
if (!(filePath in this.files)) return { error: `Error: File '${filePath}' not found` };
|
|
833
|
+
if (this.isLegacy) return { error: "StateBackend.delete requires a zero-argument StateBackend in a LangGraph execution context." };
|
|
834
|
+
this.sendFilesUpdate({ [filePath]: null });
|
|
835
|
+
return { path: filePath };
|
|
836
|
+
}
|
|
837
|
+
/**
|
|
820
838
|
* Search file contents for a literal text pattern.
|
|
821
839
|
* Binary files are skipped.
|
|
822
840
|
*/
|
|
@@ -1183,6 +1201,19 @@ var CompositeBackend = class {
|
|
|
1183
1201
|
return await backend.edit(strippedKey, oldString, newString, replaceAll);
|
|
1184
1202
|
}
|
|
1185
1203
|
/**
|
|
1204
|
+
* Delete a file, routing to the appropriate backend.
|
|
1205
|
+
*/
|
|
1206
|
+
async delete(filePath) {
|
|
1207
|
+
const [backend, strippedKey] = this.getBackendAndKey(filePath);
|
|
1208
|
+
if (!backend.delete) return { error: "Backend does not support delete" };
|
|
1209
|
+
const result = await backend.delete(strippedKey);
|
|
1210
|
+
if (result.path !== void 0) return {
|
|
1211
|
+
...result,
|
|
1212
|
+
path: filePath
|
|
1213
|
+
};
|
|
1214
|
+
return result;
|
|
1215
|
+
}
|
|
1216
|
+
/**
|
|
1186
1217
|
* Execute a command via the default backend.
|
|
1187
1218
|
* Execution is not path-specific, so it always delegates to the default backend.
|
|
1188
1219
|
*
|
|
@@ -1324,14 +1355,10 @@ const FILESYSTEM_TOOL_NAMES = [
|
|
|
1324
1355
|
"grep",
|
|
1325
1356
|
"execute"
|
|
1326
1357
|
];
|
|
1327
|
-
|
|
1328
|
-
"
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
"read_file",
|
|
1332
|
-
"edit_file",
|
|
1333
|
-
"write_file"
|
|
1334
|
-
];
|
|
1358
|
+
function isFilesystemToolName(name) {
|
|
1359
|
+
return typeof name === "string" && FILESYSTEM_TOOL_NAMES.includes(name);
|
|
1360
|
+
}
|
|
1361
|
+
const TOOLS_EXCLUDED_FROM_EVICTION = FILESYSTEM_TOOL_NAMES.filter((name) => name !== "execute");
|
|
1335
1362
|
/**
|
|
1336
1363
|
* Maximum size for binary (non-text) files read via read_file, in bytes.
|
|
1337
1364
|
* Base64-encoded content is ~33% larger, so 10MB raw ≈ 13.3MB in context.
|
|
@@ -1532,24 +1559,33 @@ function filterByPermissions(entries, rules, operation, getPath) {
|
|
|
1532
1559
|
}
|
|
1533
1560
|
});
|
|
1534
1561
|
}
|
|
1535
|
-
const
|
|
1536
|
-
|
|
1562
|
+
const FILESYSTEM_TOOL_DESCRIPTION_LINES = {
|
|
1563
|
+
ls: "ls: list files in a directory (requires absolute path)",
|
|
1564
|
+
read_file: "read_file: read a file from the filesystem",
|
|
1565
|
+
write_file: "write_file: write to a file in the filesystem",
|
|
1566
|
+
edit_file: "edit_file: edit a file in the filesystem",
|
|
1567
|
+
glob: "glob: find files matching a pattern (e.g., \"**/*.py\")",
|
|
1568
|
+
grep: "grep: search for text within files"
|
|
1569
|
+
};
|
|
1570
|
+
function hasFilesystemToolDescription(name) {
|
|
1571
|
+
return name in FILESYSTEM_TOOL_DESCRIPTION_LINES;
|
|
1572
|
+
}
|
|
1573
|
+
function buildFilesystemSystemPrompt(visibleTools) {
|
|
1574
|
+
const promptToolNames = FILESYSTEM_TOOL_NAMES.filter((name) => visibleTools.has(name));
|
|
1575
|
+
return langchain.context`
|
|
1576
|
+
## Following Conventions
|
|
1537
1577
|
|
|
1538
|
-
|
|
1539
|
-
|
|
1578
|
+
- Read files before editing — understand existing content before making changes
|
|
1579
|
+
- Mimic existing style, naming conventions, and patterns
|
|
1540
1580
|
|
|
1541
|
-
|
|
1581
|
+
## Filesystem Tools ${promptToolNames.map((name) => `\`${name}\``).join(", ")}
|
|
1542
1582
|
|
|
1543
|
-
|
|
1544
|
-
|
|
1583
|
+
You have access to a filesystem which you can interact with using these tools.
|
|
1584
|
+
All file paths must start with a /.
|
|
1545
1585
|
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
- edit_file: edit a file in the filesystem
|
|
1550
|
-
- glob: find files matching a pattern (e.g., "**/*.py")
|
|
1551
|
-
- grep: search for text within files
|
|
1552
|
-
`;
|
|
1586
|
+
${promptToolNames.filter(hasFilesystemToolDescription).map((name) => `- ${FILESYSTEM_TOOL_DESCRIPTION_LINES[name]}`).join("\n")}
|
|
1587
|
+
`;
|
|
1588
|
+
}
|
|
1553
1589
|
const LS_TOOL_DESCRIPTION = langchain.context`
|
|
1554
1590
|
Lists all files in a directory.
|
|
1555
1591
|
|
|
@@ -1923,6 +1959,12 @@ function createExecuteTool(backend, options) {
|
|
|
1923
1959
|
* Returns true only when backend exposes route prefixes (CompositeBackend) and
|
|
1924
1960
|
* every permission path is scoped under one of them.
|
|
1925
1961
|
*/
|
|
1962
|
+
function normalizeFilesystemTools(tools) {
|
|
1963
|
+
if (tools == null || tools === "all") return null;
|
|
1964
|
+
const enabledTools = new Set(tools);
|
|
1965
|
+
if (!enabledTools.has("read_file")) throw new Error("read_file must be included in tools; it is required by FilesystemMiddleware");
|
|
1966
|
+
return enabledTools;
|
|
1967
|
+
}
|
|
1926
1968
|
function allPathsScopedToRoutes(permissions, backend) {
|
|
1927
1969
|
if (!CompositeBackend.isInstance(backend)) return false;
|
|
1928
1970
|
const prefixes = backend.routePrefixes;
|
|
@@ -1930,13 +1972,43 @@ function allPathsScopedToRoutes(permissions, backend) {
|
|
|
1930
1972
|
return permissions.every((rule) => rule.paths.every((path) => prefixes.some((prefix) => path.startsWith(prefix.endsWith("/") ? prefix : `${prefix}/`))));
|
|
1931
1973
|
}
|
|
1932
1974
|
/**
|
|
1933
|
-
* Create
|
|
1975
|
+
* Create middleware that provides built-in filesystem tools and filesystem-aware
|
|
1976
|
+
* prompt guidance.
|
|
1977
|
+
*
|
|
1978
|
+
* By default, the middleware registers every built-in filesystem tool listed in
|
|
1979
|
+
* {@link FILESYSTEM_TOOL_NAMES}. Use {@link FilesystemMiddlewareOptions.tools}
|
|
1980
|
+
* to narrow that set for read-only, search-only, or otherwise restricted
|
|
1981
|
+
* agents. The allowlist only controls built-in filesystem tools; custom tools
|
|
1982
|
+
* from the agent or other middleware are left untouched.
|
|
1983
|
+
*
|
|
1984
|
+
* The middleware also filters tools whose backend capabilities are unavailable
|
|
1985
|
+
* at request time. In particular, `execute` is only visible when the resolved
|
|
1986
|
+
* backend supports command execution. The filesystem prompt is generated from
|
|
1987
|
+
* the final visible filesystem tools so the model is not instructed to call
|
|
1988
|
+
* tools it cannot see.
|
|
1989
|
+
*
|
|
1990
|
+
* @param options Filesystem middleware configuration.
|
|
1991
|
+
* @returns Agent middleware that contributes filesystem state, tools, prompt
|
|
1992
|
+
* guidance, permission checks, and large-result eviction.
|
|
1993
|
+
*
|
|
1994
|
+
* @example Read-only filesystem middleware
|
|
1995
|
+
* ```ts
|
|
1996
|
+
* const middleware = createFilesystemMiddleware({
|
|
1997
|
+
* tools: ["read_file", "ls", "glob", "grep"],
|
|
1998
|
+
* });
|
|
1999
|
+
* ```
|
|
1934
2000
|
*/
|
|
1935
2001
|
function createFilesystemMiddleware(options = {}) {
|
|
1936
|
-
const { backend = (runtime) => new StateBackend(runtime), systemPrompt: customSystemPrompt = null, customToolDescriptions = null, toolTokenLimitBeforeEvict = 2e4, humanMessageTokenLimitBeforeEvict = 5e4, permissions = [] } = options;
|
|
2002
|
+
const { backend = (runtime) => new StateBackend(runtime), systemPrompt: customSystemPrompt = null, customToolDescriptions = null, toolTokenLimitBeforeEvict = 2e4, humanMessageTokenLimitBeforeEvict = 5e4, permissions = [], tools: filesystemTools = null } = options;
|
|
2003
|
+
const enabledFilesystemTools = normalizeFilesystemTools(filesystemTools);
|
|
2004
|
+
const executeToolEnabled = enabledFilesystemTools == null || enabledFilesystemTools.has("execute");
|
|
1937
2005
|
if (permissions.length > 0) validatePermissionPaths(permissions);
|
|
1938
|
-
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.");
|
|
1939
|
-
const baseSystemPrompt = customSystemPrompt
|
|
2006
|
+
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.");
|
|
2007
|
+
const baseSystemPrompt = customSystemPrompt ?? null;
|
|
2008
|
+
/**
|
|
2009
|
+
* All tools including execute
|
|
2010
|
+
* (execute will be filtered at runtime if backend doesn't support it)
|
|
2011
|
+
*/
|
|
1940
2012
|
const allToolsByName = {
|
|
1941
2013
|
ls: createLsTool(backend, {
|
|
1942
2014
|
customDescription: customToolDescriptions?.ls,
|
|
@@ -1968,7 +2040,7 @@ function createFilesystemMiddleware(options = {}) {
|
|
|
1968
2040
|
permissions
|
|
1969
2041
|
})
|
|
1970
2042
|
};
|
|
1971
|
-
const allTools =
|
|
2043
|
+
const allTools = FILESYSTEM_TOOL_NAMES.filter((name) => enabledFilesystemTools == null || enabledFilesystemTools.has(name)).map((name) => allToolsByName[name]);
|
|
1972
2044
|
async function processToolMessage(msg, runtime, state, fallbackToolCallId) {
|
|
1973
2045
|
if (!toolTokenLimitBeforeEvict) return {
|
|
1974
2046
|
message: msg,
|
|
@@ -2042,8 +2114,14 @@ function createFilesystemMiddleware(options = {}) {
|
|
|
2042
2114
|
}));
|
|
2043
2115
|
let tools = request.tools;
|
|
2044
2116
|
if (!supportsExecution) tools = tools.filter((t) => t.name !== "execute");
|
|
2045
|
-
|
|
2046
|
-
|
|
2117
|
+
const visibleFilesystemTools = /* @__PURE__ */ new Set();
|
|
2118
|
+
for (const currentTool of tools) {
|
|
2119
|
+
const toolName = typeof currentTool.name === "string" ? currentTool.name : void 0;
|
|
2120
|
+
if (isFilesystemToolName(toolName)) visibleFilesystemTools.add(toolName);
|
|
2121
|
+
}
|
|
2122
|
+
const executionActive = supportsExecution && visibleFilesystemTools.has("execute");
|
|
2123
|
+
let filesystemPrompt = baseSystemPrompt ?? buildFilesystemSystemPrompt(visibleFilesystemTools);
|
|
2124
|
+
if (executionActive) filesystemPrompt = `${filesystemPrompt}\n\n${EXECUTION_SYSTEM_PROMPT}`;
|
|
2047
2125
|
const newSystemMessage = request.systemMessage.concat(filesystemPrompt);
|
|
2048
2126
|
let messages = request.messages;
|
|
2049
2127
|
if (humanMessageTokenLimitBeforeEvict && messages) {
|
|
@@ -3487,6 +3565,41 @@ function createSkillsMiddleware(options) {
|
|
|
3487
3565
|
*
|
|
3488
3566
|
* This module provides shared helpers used across middleware implementations.
|
|
3489
3567
|
*/
|
|
3568
|
+
/**
|
|
3569
|
+
* Merge custom middleware into an assembled stack by `.name`.
|
|
3570
|
+
*
|
|
3571
|
+
* Matching custom middleware replaces the existing entry in place. New
|
|
3572
|
+
* middleware is appended after the base stack in caller-provided order.
|
|
3573
|
+
*/
|
|
3574
|
+
function mergeMiddleware$1(base, custom) {
|
|
3575
|
+
const merged = new Map(base.map((middleware) => [middleware.name, middleware]));
|
|
3576
|
+
for (const middleware of custom) merged.set(middleware.name, middleware);
|
|
3577
|
+
return [...merged.values()];
|
|
3578
|
+
}
|
|
3579
|
+
function middlewareNames(middleware) {
|
|
3580
|
+
return new Set(middleware.map((entry) => entry.name));
|
|
3581
|
+
}
|
|
3582
|
+
function matchingMiddleware(middleware, names) {
|
|
3583
|
+
return middleware.filter((entry) => names.has(entry.name));
|
|
3584
|
+
}
|
|
3585
|
+
/**
|
|
3586
|
+
* Merge custom middleware into default and tail middleware segments.
|
|
3587
|
+
*
|
|
3588
|
+
* Same-name custom entries replace matching defaults in either segment. Novel
|
|
3589
|
+
* custom entries are inserted between the default and tail segments unless
|
|
3590
|
+
* `appendNew` is false.
|
|
3591
|
+
*/
|
|
3592
|
+
function mergeMiddlewareStack(defaultMiddleware, customMiddleware, tailMiddleware = [], options = {}) {
|
|
3593
|
+
const defaultMiddlewareNames = middlewareNames(defaultMiddleware);
|
|
3594
|
+
const tailMiddlewareNames = middlewareNames(tailMiddleware);
|
|
3595
|
+
const knownMiddlewareNames = /* @__PURE__ */ new Set([...defaultMiddlewareNames, ...tailMiddlewareNames]);
|
|
3596
|
+
const novelMiddleware = options.appendNew === false ? [] : customMiddleware.filter((entry) => !knownMiddlewareNames.has(entry.name));
|
|
3597
|
+
return [
|
|
3598
|
+
...mergeMiddleware$1(defaultMiddleware, matchingMiddleware(customMiddleware, defaultMiddlewareNames)),
|
|
3599
|
+
...novelMiddleware,
|
|
3600
|
+
...mergeMiddleware$1(tailMiddleware, matchingMiddleware(customMiddleware, tailMiddlewareNames))
|
|
3601
|
+
];
|
|
3602
|
+
}
|
|
3490
3603
|
//#endregion
|
|
3491
3604
|
//#region src/middleware/completion_callback.ts
|
|
3492
3605
|
/**
|
|
@@ -5079,6 +5192,28 @@ function createCacheBreakpointMiddleware() {
|
|
|
5079
5192
|
});
|
|
5080
5193
|
}
|
|
5081
5194
|
//#endregion
|
|
5195
|
+
//#region src/middleware/tool_exclusion.ts
|
|
5196
|
+
function hasToolName(tool) {
|
|
5197
|
+
return tool !== null && typeof tool === "object" && "name" in tool && typeof tool.name === "string";
|
|
5198
|
+
}
|
|
5199
|
+
/**
|
|
5200
|
+
* Create middleware that removes excluded tools after all tool-injecting
|
|
5201
|
+
* middleware has had a chance to add tools to the request.
|
|
5202
|
+
*
|
|
5203
|
+
* @internal
|
|
5204
|
+
*/
|
|
5205
|
+
function createToolExclusionMiddleware(excludedTools) {
|
|
5206
|
+
return (0, langchain.createMiddleware)({
|
|
5207
|
+
name: "_ToolExclusionMiddleware",
|
|
5208
|
+
wrapModelCall(request, handler) {
|
|
5209
|
+
return handler({
|
|
5210
|
+
...request,
|
|
5211
|
+
tools: request.tools?.filter((tool) => !hasToolName(tool) || !excludedTools.has(tool.name))
|
|
5212
|
+
});
|
|
5213
|
+
}
|
|
5214
|
+
});
|
|
5215
|
+
}
|
|
5216
|
+
//#endregion
|
|
5082
5217
|
//#region src/profiles/keys.ts
|
|
5083
5218
|
/**
|
|
5084
5219
|
* Normalize and validate a profile registry key.
|
|
@@ -5782,6 +5917,31 @@ const BASE_AGENT_PROMPT = langchain.context`
|
|
|
5782
5917
|
|
|
5783
5918
|
For longer tasks, provide brief progress updates at reasonable intervals — a concise sentence recapping what you've done and what's next.
|
|
5784
5919
|
`;
|
|
5920
|
+
const PROMPT_SEPARATOR = "\n\n";
|
|
5921
|
+
/** Normalize legacy system prompt values to the structured representation. */
|
|
5922
|
+
function normalizeSystemPrompt(systemPrompt) {
|
|
5923
|
+
if (systemPrompt === void 0) return {};
|
|
5924
|
+
if (typeof systemPrompt === "string" || langchain.SystemMessage.isInstance(systemPrompt)) return { prefix: systemPrompt };
|
|
5925
|
+
return systemPrompt;
|
|
5926
|
+
}
|
|
5927
|
+
/** Assemble prompt parts while preserving structured message content blocks. */
|
|
5928
|
+
function assemblePromptParts(parts) {
|
|
5929
|
+
if (parts.length === 0) return "";
|
|
5930
|
+
if (parts.every((part) => typeof part === "string")) return parts.join(PROMPT_SEPARATOR);
|
|
5931
|
+
const contentBlocks = [];
|
|
5932
|
+
for (const [index, part] of parts.entries()) {
|
|
5933
|
+
if (index > 0) contentBlocks.push({
|
|
5934
|
+
type: "text",
|
|
5935
|
+
text: PROMPT_SEPARATOR
|
|
5936
|
+
});
|
|
5937
|
+
if (langchain.SystemMessage.isInstance(part)) contentBlocks.push(...part.contentBlocks);
|
|
5938
|
+
else contentBlocks.push({
|
|
5939
|
+
type: "text",
|
|
5940
|
+
text: part
|
|
5941
|
+
});
|
|
5942
|
+
}
|
|
5943
|
+
return new langchain.SystemMessage({ contentBlocks });
|
|
5944
|
+
}
|
|
5785
5945
|
const BUILTIN_TOOL_NAMES = /* @__PURE__ */ new Set([
|
|
5786
5946
|
...FILESYSTEM_TOOL_NAMES,
|
|
5787
5947
|
...ASYNC_TASK_TOOL_NAMES,
|
|
@@ -5827,6 +5987,8 @@ function createDeepAgent(params = {}) {
|
|
|
5827
5987
|
providerHint: getModelProvider(model),
|
|
5828
5988
|
identifierHint: getModelIdentifier(model)
|
|
5829
5989
|
});
|
|
5990
|
+
const filesystemTools = FILESYSTEM_TOOL_NAMES.filter((toolName) => !harnessProfile.excludedTools.has(toolName));
|
|
5991
|
+
const profileFilesystemTools = filesystemTools.length === FILESYSTEM_TOOL_NAMES.length || !filesystemTools.includes("read_file") ? void 0 : filesystemTools;
|
|
5830
5992
|
const toolOverrides = harnessProfile.toolDescriptionOverrides;
|
|
5831
5993
|
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;
|
|
5832
5994
|
const anthropicModel = isAnthropicModel(model);
|
|
@@ -5848,23 +6010,26 @@ function createDeepAgent(params = {}) {
|
|
|
5848
6010
|
* Only the general-purpose subagent inherits the main agent's skills.
|
|
5849
6011
|
* If a custom subagent needs skills, it must specify its own `skills` array.
|
|
5850
6012
|
*/
|
|
5851
|
-
const
|
|
6013
|
+
const createSubagentDefaultMiddleware = (input) => {
|
|
5852
6014
|
const effectivePermissions = input.permissions ?? permissions;
|
|
5853
|
-
|
|
6015
|
+
return [
|
|
5854
6016
|
(0, langchain.todoListMiddleware)(),
|
|
5855
6017
|
createFilesystemMiddleware({
|
|
5856
6018
|
backend,
|
|
5857
|
-
permissions: effectivePermissions
|
|
6019
|
+
permissions: effectivePermissions,
|
|
6020
|
+
tools: profileFilesystemTools
|
|
5858
6021
|
}),
|
|
5859
6022
|
createSummarizationMiddleware({ backend }),
|
|
5860
6023
|
createPatchToolCallsMiddleware(),
|
|
5861
6024
|
...input.skills != null && input.skills.length > 0 ? [createSkillsMiddleware({
|
|
5862
6025
|
backend,
|
|
5863
6026
|
sources: input.skills
|
|
5864
|
-
})] : []
|
|
5865
|
-
...input.middleware ?? [],
|
|
5866
|
-
...cacheMiddleware
|
|
6027
|
+
})] : []
|
|
5867
6028
|
];
|
|
6029
|
+
};
|
|
6030
|
+
const normalizeSubagentSpec = (input) => {
|
|
6031
|
+
let subagentMiddleware = mergeMiddlewareStack(createSubagentDefaultMiddleware(input), input.middleware ?? [], cacheMiddleware);
|
|
6032
|
+
if (harnessProfile.excludedMiddleware.size > 0) subagentMiddleware = subagentMiddleware.filter((middleware) => !harnessProfile.excludedMiddleware.has(middleware.name));
|
|
5868
6033
|
return {
|
|
5869
6034
|
...input,
|
|
5870
6035
|
tools: input.tools ?? [],
|
|
@@ -5885,6 +6050,7 @@ function createDeepAgent(params = {}) {
|
|
|
5885
6050
|
skills,
|
|
5886
6051
|
tools: effectiveTools
|
|
5887
6052
|
});
|
|
6053
|
+
generalPurposeSpec.middleware = mergeMiddlewareStack(generalPurposeSpec.middleware ?? [], customMiddleware, [], { appendNew: false });
|
|
5888
6054
|
inlineSubagents.unshift(generalPurposeSpec);
|
|
5889
6055
|
}
|
|
5890
6056
|
const skillsMiddleware = skills != null && skills.length > 0 ? [createSkillsMiddleware({
|
|
@@ -5895,7 +6061,8 @@ function createDeepAgent(params = {}) {
|
|
|
5895
6061
|
(0, langchain.todoListMiddleware)(),
|
|
5896
6062
|
createFilesystemMiddleware({
|
|
5897
6063
|
backend,
|
|
5898
|
-
permissions
|
|
6064
|
+
permissions,
|
|
6065
|
+
tools: profileFilesystemTools
|
|
5899
6066
|
}),
|
|
5900
6067
|
createSubAgentMiddleware({
|
|
5901
6068
|
defaultModel: model,
|
|
@@ -5907,15 +6074,16 @@ function createDeepAgent(params = {}) {
|
|
|
5907
6074
|
createSummarizationMiddleware({ backend }),
|
|
5908
6075
|
createPatchToolCallsMiddleware()
|
|
5909
6076
|
];
|
|
5910
|
-
|
|
6077
|
+
let middleware = mergeMiddlewareStack([
|
|
5911
6078
|
todoMiddleware,
|
|
5912
6079
|
...skillsMiddleware,
|
|
5913
6080
|
fsMiddleware,
|
|
5914
6081
|
subagentMiddleware,
|
|
5915
6082
|
summarizationMiddleware,
|
|
5916
6083
|
patchToolCallsMiddleware,
|
|
5917
|
-
...asyncSubAgents.length > 0 ? [createAsyncSubAgentMiddleware({ asyncSubAgents })] : []
|
|
5918
|
-
|
|
6084
|
+
...asyncSubAgents.length > 0 ? [createAsyncSubAgentMiddleware({ asyncSubAgents })] : []
|
|
6085
|
+
], customMiddleware, [
|
|
6086
|
+
...resolveMiddleware(harnessProfile.extraMiddleware),
|
|
5919
6087
|
...cacheMiddleware,
|
|
5920
6088
|
...memory && memory.length > 0 ? [createMemoryMiddleware({
|
|
5921
6089
|
backend,
|
|
@@ -5923,32 +6091,19 @@ function createDeepAgent(params = {}) {
|
|
|
5923
6091
|
addCacheControl: anthropicModel
|
|
5924
6092
|
})] : [],
|
|
5925
6093
|
...interruptOn ? [(0, langchain.humanInTheLoopMiddleware)({ interruptOn })] : []
|
|
5926
|
-
];
|
|
5927
|
-
const profileMiddleware = resolveMiddleware(harnessProfile.extraMiddleware);
|
|
5928
|
-
if (profileMiddleware.length > 0) {
|
|
5929
|
-
const cacheIdx = middleware.findIndex((m) => m.name === "AnthropicPromptCachingMiddleware");
|
|
5930
|
-
if (cacheIdx !== -1) middleware.splice(cacheIdx, 0, ...profileMiddleware);
|
|
5931
|
-
else middleware.push(...profileMiddleware);
|
|
5932
|
-
}
|
|
6094
|
+
]);
|
|
5933
6095
|
if (harnessProfile.excludedMiddleware.size > 0) {
|
|
5934
6096
|
const excluded = harnessProfile.excludedMiddleware;
|
|
5935
|
-
|
|
5936
|
-
|
|
5937
|
-
|
|
5938
|
-
|
|
5939
|
-
|
|
5940
|
-
|
|
5941
|
-
|
|
5942
|
-
|
|
5943
|
-
|
|
5944
|
-
|
|
5945
|
-
...request,
|
|
5946
|
-
tools: request.tools?.filter((t) => !excludedTools.has(t.name))
|
|
5947
|
-
});
|
|
5948
|
-
}
|
|
5949
|
-
}));
|
|
5950
|
-
}
|
|
5951
|
-
const effectiveBasePrompt = applyProfilePrompt(harnessProfile, BASE_AGENT_PROMPT);
|
|
6097
|
+
middleware = middleware.filter((entry) => !excluded.has(entry.name));
|
|
6098
|
+
}
|
|
6099
|
+
if (harnessProfile.excludedTools.size > 0) middleware.push(createToolExclusionMiddleware(harnessProfile.excludedTools));
|
|
6100
|
+
const promptConfig = normalizeSystemPrompt(systemPrompt);
|
|
6101
|
+
const promptParts = [];
|
|
6102
|
+
if (promptConfig.prefix !== void 0 && promptConfig.prefix !== null) promptParts.push(promptConfig.prefix);
|
|
6103
|
+
const activeBasePrompt = promptConfig.base !== void 0 ? promptConfig.base : harnessProfile.baseSystemPrompt ?? BASE_AGENT_PROMPT;
|
|
6104
|
+
if (activeBasePrompt !== null) promptParts.push(activeBasePrompt);
|
|
6105
|
+
if (promptConfig.suffix) promptParts.push(promptConfig.suffix);
|
|
6106
|
+
if (harnessProfile.systemPromptSuffix) promptParts.push(harnessProfile.systemPromptSuffix);
|
|
5952
6107
|
/**
|
|
5953
6108
|
* Return as DeepAgent with proper DeepAgentTypeConfig
|
|
5954
6109
|
* - Response: InferStructuredResponse<TResponse> (unwraps ToolStrategy<T>/ProviderStrategy<T> → T)
|
|
@@ -5961,19 +6116,7 @@ function createDeepAgent(params = {}) {
|
|
|
5961
6116
|
*/
|
|
5962
6117
|
return (0, langchain.createAgent)({
|
|
5963
6118
|
model,
|
|
5964
|
-
systemPrompt:
|
|
5965
|
-
type: "text",
|
|
5966
|
-
text: systemPrompt
|
|
5967
|
-
}, {
|
|
5968
|
-
type: "text",
|
|
5969
|
-
text: effectiveBasePrompt
|
|
5970
|
-
}] }) : langchain.SystemMessage.isInstance(systemPrompt) ? new langchain.SystemMessage({ contentBlocks: [...systemPrompt.contentBlocks, {
|
|
5971
|
-
type: "text",
|
|
5972
|
-
text: effectiveBasePrompt
|
|
5973
|
-
}] }) : new langchain.SystemMessage({ contentBlocks: [{
|
|
5974
|
-
type: "text",
|
|
5975
|
-
text: effectiveBasePrompt
|
|
5976
|
-
}] }),
|
|
6119
|
+
systemPrompt: assemblePromptParts(promptParts),
|
|
5977
6120
|
stateSchema,
|
|
5978
6121
|
tools: effectiveTools,
|
|
5979
6122
|
middleware,
|
|
@@ -6325,6 +6468,19 @@ var StoreBackend = class {
|
|
|
6325
6468
|
}
|
|
6326
6469
|
}
|
|
6327
6470
|
/**
|
|
6471
|
+
* Delete a file from the store.
|
|
6472
|
+
*
|
|
6473
|
+
* The file path is used as an exact store key. Wildcards are treated
|
|
6474
|
+
* literally and do not expand to multiple entries.
|
|
6475
|
+
*/
|
|
6476
|
+
async delete(filePath) {
|
|
6477
|
+
const store = this.getStore();
|
|
6478
|
+
const namespace = this.getNamespace();
|
|
6479
|
+
if (!await store.get(namespace, filePath)) return { error: `Error: File '${filePath}' not found` };
|
|
6480
|
+
await store.delete(namespace, filePath);
|
|
6481
|
+
return { path: filePath };
|
|
6482
|
+
}
|
|
6483
|
+
/**
|
|
6328
6484
|
* Search file contents for a literal text pattern.
|
|
6329
6485
|
* Binary files are skipped.
|
|
6330
6486
|
*/
|
|
@@ -6537,10 +6693,10 @@ var ContextHubBackend = class ContextHubBackend {
|
|
|
6537
6693
|
if (this.cache === null) throw new Error("Context Hub cache failed to initialize");
|
|
6538
6694
|
return this.cache;
|
|
6539
6695
|
}
|
|
6540
|
-
async commit(
|
|
6541
|
-
if (Object.keys(
|
|
6696
|
+
async commit(changes) {
|
|
6697
|
+
if (Object.keys(changes).length === 0) return;
|
|
6542
6698
|
const payload = {};
|
|
6543
|
-
for (const [path, content] of Object.entries(
|
|
6699
|
+
for (const [path, content] of Object.entries(changes)) payload[path] = content === null ? null : {
|
|
6544
6700
|
type: "file",
|
|
6545
6701
|
content
|
|
6546
6702
|
};
|
|
@@ -6550,7 +6706,14 @@ var ContextHubBackend = class ContextHubBackend {
|
|
|
6550
6706
|
});
|
|
6551
6707
|
const match = URL_COMMIT_SUFFIX_RE.exec(url);
|
|
6552
6708
|
if (match) this.commitHash = match[1];
|
|
6553
|
-
if (this.cache !== null)
|
|
6709
|
+
if (this.cache !== null) {
|
|
6710
|
+
const deletions = new Set(Object.entries(changes).filter(([, content]) => content === null).map(([path]) => path));
|
|
6711
|
+
const updates = Object.fromEntries(Object.entries(changes).filter((entry) => entry[1] !== null));
|
|
6712
|
+
this.cache = {
|
|
6713
|
+
...Object.fromEntries(Object.entries(this.cache).filter(([path]) => !deletions.has(path))),
|
|
6714
|
+
...updates
|
|
6715
|
+
};
|
|
6716
|
+
}
|
|
6554
6717
|
}
|
|
6555
6718
|
/**
|
|
6556
6719
|
* Return linked-entry paths mapped to their repo handles.
|
|
@@ -6709,6 +6872,20 @@ var ContextHubBackend = class ContextHubBackend {
|
|
|
6709
6872
|
throw error;
|
|
6710
6873
|
}
|
|
6711
6874
|
}
|
|
6875
|
+
async delete(filePath) {
|
|
6876
|
+
const hubPath = ContextHubBackend.stripPrefix(filePath);
|
|
6877
|
+
try {
|
|
6878
|
+
if (!(hubPath in await this.ensureCache())) return { error: `Error: File '${filePath}' not found` };
|
|
6879
|
+
await this.commit({ [hubPath]: null });
|
|
6880
|
+
return { path: filePath };
|
|
6881
|
+
} catch (error) {
|
|
6882
|
+
if (isLangSmithError(error)) {
|
|
6883
|
+
this.cache = null;
|
|
6884
|
+
return { error: ContextHubBackend.toHubUnavailableError(error) };
|
|
6885
|
+
}
|
|
6886
|
+
throw error;
|
|
6887
|
+
}
|
|
6888
|
+
}
|
|
6712
6889
|
async uploadFiles(files) {
|
|
6713
6890
|
const decoder = new TextDecoder("utf-8", { fatal: true });
|
|
6714
6891
|
const decoded = [];
|
|
@@ -7201,6 +7378,16 @@ var BaseSandbox = class {
|
|
|
7201
7378
|
occurrences: count
|
|
7202
7379
|
};
|
|
7203
7380
|
}
|
|
7381
|
+
/**
|
|
7382
|
+
* Delete a file from the sandbox via a server-side rm.
|
|
7383
|
+
*
|
|
7384
|
+
* Uses rm -f, so deleting a path that does not exist succeeds silently.
|
|
7385
|
+
*/
|
|
7386
|
+
async delete(filePath) {
|
|
7387
|
+
const result = await this.execute(`rm -f ${shellQuote(filePath)}`);
|
|
7388
|
+
if (result.exitCode === 0) return { path: filePath };
|
|
7389
|
+
return { error: `Error deleting file '${filePath}': ${result.output.trim() || "unknown error"}` };
|
|
7390
|
+
}
|
|
7204
7391
|
};
|
|
7205
7392
|
//#endregion
|
|
7206
7393
|
//#region src/backends/langsmith.ts
|
|
@@ -7691,4 +7878,4 @@ Object.defineProperty(exports, "serializeProfile", {
|
|
|
7691
7878
|
}
|
|
7692
7879
|
});
|
|
7693
7880
|
|
|
7694
|
-
//# sourceMappingURL=langsmith-
|
|
7881
|
+
//# sourceMappingURL=langsmith-DDhVumyX.cjs.map
|