deepagents 1.10.8 → 1.11.1
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-B2XFuA-E.d.cts} +172 -19
- package/dist/{agent-DgVtHOV7.d.ts → agent-k6GiDPCY.d.ts} +172 -19
- 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-DVh4u6Za.js} +318 -96
- package/dist/langsmith-DVh4u6Za.js.map +1 -0
- package/dist/{langsmith-CiAeUke2.cjs → langsmith-DhbsxI45.cjs} +316 -96
- package/dist/langsmith-DhbsxI45.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-Bzfzo6KX.js → src-Cqag72HH.js} +51 -2
- package/dist/src-Cqag72HH.js.map +1 -0
- package/dist/{src-BgDEYOGN.cjs → src-DtpWpNrN.cjs} +51 -2
- package/dist/src-DtpWpNrN.cjs.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-BgDEYOGN.cjs.map +0 -1
- package/dist/src-Bzfzo6KX.js.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.
|
|
@@ -1475,19 +1502,46 @@ const FilesystemStateSchema = new StateSchema({ files: new ReducedValue(z.record
|
|
|
1475
1502
|
inputSchema: z.record(z.string(), FileDataSchema.nullable()).optional(),
|
|
1476
1503
|
reducer: fileDataReducer
|
|
1477
1504
|
}) });
|
|
1505
|
+
/** Extract a message string from an unknown thrown value without `instanceof`. */
|
|
1506
|
+
function getErrorMessage$1(error) {
|
|
1507
|
+
if (typeof error === "object" && error !== null && "message" in error && typeof error.message === "string") return error.message;
|
|
1508
|
+
return String(error);
|
|
1509
|
+
}
|
|
1478
1510
|
/**
|
|
1479
|
-
*
|
|
1511
|
+
* Check whether `path` is permitted under `rules` for `operation`, returning an
|
|
1512
|
+
* error string to surface to the model (or `undefined` when allowed).
|
|
1480
1513
|
*
|
|
1481
|
-
*
|
|
1482
|
-
*
|
|
1483
|
-
*
|
|
1514
|
+
* Never throws: an invalid path (non-absolute, or containing `..` or `~`) or a
|
|
1515
|
+
* denied path is a recoverable tool error, not a fatal run-ending one. Such
|
|
1516
|
+
* paths are rejected, never normalized, so they cannot bypass a deny rule or
|
|
1517
|
+
* reach the backend.
|
|
1484
1518
|
*
|
|
1485
1519
|
* @internal
|
|
1486
1520
|
*/
|
|
1487
|
-
function
|
|
1521
|
+
function checkPermission(rules, operation, path) {
|
|
1488
1522
|
if (rules.length === 0) return;
|
|
1489
|
-
|
|
1490
|
-
|
|
1523
|
+
let canonical;
|
|
1524
|
+
try {
|
|
1525
|
+
canonical = validatePath(path);
|
|
1526
|
+
} catch (error) {
|
|
1527
|
+
return `Error: ${getErrorMessage$1(error)}`;
|
|
1528
|
+
}
|
|
1529
|
+
if (decidePathAccess(rules, operation, canonical) === "deny") return `Error: permission denied for ${operation} on ${canonical}`;
|
|
1530
|
+
}
|
|
1531
|
+
/**
|
|
1532
|
+
* Build an error {@link ToolMessage} for a rejected or denied path. Returning a
|
|
1533
|
+
* bare string would be wrapped as a `status: "success"` message whose content
|
|
1534
|
+
* merely starts with "Error:"; marking `status: "error"` reports the failure
|
|
1535
|
+
* accurately so callers and the model can distinguish a real failure from a
|
|
1536
|
+
* successful result.
|
|
1537
|
+
*/
|
|
1538
|
+
function toolError(runtime, toolName, message) {
|
|
1539
|
+
return new ToolMessage({
|
|
1540
|
+
content: message,
|
|
1541
|
+
name: toolName,
|
|
1542
|
+
tool_call_id: runtime.toolCall?.id,
|
|
1543
|
+
status: "error"
|
|
1544
|
+
});
|
|
1491
1545
|
}
|
|
1492
1546
|
/**
|
|
1493
1547
|
* Filter a list of filesystem entries to those the rules permit.
|
|
@@ -1508,24 +1562,33 @@ function filterByPermissions(entries, rules, operation, getPath) {
|
|
|
1508
1562
|
}
|
|
1509
1563
|
});
|
|
1510
1564
|
}
|
|
1511
|
-
const
|
|
1512
|
-
|
|
1565
|
+
const FILESYSTEM_TOOL_DESCRIPTION_LINES = {
|
|
1566
|
+
ls: "ls: list files in a directory (requires absolute path)",
|
|
1567
|
+
read_file: "read_file: read a file from the filesystem",
|
|
1568
|
+
write_file: "write_file: write to a file in the filesystem",
|
|
1569
|
+
edit_file: "edit_file: edit a file in the filesystem",
|
|
1570
|
+
glob: "glob: find files matching a pattern (e.g., \"**/*.py\")",
|
|
1571
|
+
grep: "grep: search for text within files"
|
|
1572
|
+
};
|
|
1573
|
+
function hasFilesystemToolDescription(name) {
|
|
1574
|
+
return name in FILESYSTEM_TOOL_DESCRIPTION_LINES;
|
|
1575
|
+
}
|
|
1576
|
+
function buildFilesystemSystemPrompt(visibleTools) {
|
|
1577
|
+
const promptToolNames = FILESYSTEM_TOOL_NAMES.filter((name) => visibleTools.has(name));
|
|
1578
|
+
return context`
|
|
1579
|
+
## Following Conventions
|
|
1513
1580
|
|
|
1514
|
-
|
|
1515
|
-
|
|
1581
|
+
- Read files before editing — understand existing content before making changes
|
|
1582
|
+
- Mimic existing style, naming conventions, and patterns
|
|
1516
1583
|
|
|
1517
|
-
|
|
1584
|
+
## Filesystem Tools ${promptToolNames.map((name) => `\`${name}\``).join(", ")}
|
|
1518
1585
|
|
|
1519
|
-
|
|
1520
|
-
|
|
1586
|
+
You have access to a filesystem which you can interact with using these tools.
|
|
1587
|
+
All file paths must start with a /.
|
|
1521
1588
|
|
|
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
|
-
`;
|
|
1589
|
+
${promptToolNames.filter(hasFilesystemToolDescription).map((name) => `- ${FILESYSTEM_TOOL_DESCRIPTION_LINES[name]}`).join("\n")}
|
|
1590
|
+
`;
|
|
1591
|
+
}
|
|
1529
1592
|
const LS_TOOL_DESCRIPTION = context`
|
|
1530
1593
|
Lists all files in a directory.
|
|
1531
1594
|
|
|
@@ -1649,7 +1712,8 @@ const EXECUTION_SYSTEM_PROMPT = context`
|
|
|
1649
1712
|
function createLsTool(backend, options) {
|
|
1650
1713
|
const { customDescription, permissions } = options;
|
|
1651
1714
|
return tool(async (input, runtime) => {
|
|
1652
|
-
|
|
1715
|
+
const permissionError = checkPermission(permissions, "read", input.path ?? "/");
|
|
1716
|
+
if (permissionError !== void 0) return toolError(runtime, "ls", permissionError);
|
|
1653
1717
|
const resolvedBackend = await resolveBackend(backend, runtime);
|
|
1654
1718
|
const path = input.path || "/";
|
|
1655
1719
|
const lsResult = await resolvedBackend.ls(path);
|
|
@@ -1677,7 +1741,8 @@ function createLsTool(backend, options) {
|
|
|
1677
1741
|
function createReadFileTool(backend, options) {
|
|
1678
1742
|
const { customDescription, toolTokenLimitBeforeEvict, permissions } = options;
|
|
1679
1743
|
return tool(async (input, runtime) => {
|
|
1680
|
-
|
|
1744
|
+
const permissionError = checkPermission(permissions, "read", input.file_path);
|
|
1745
|
+
if (permissionError !== void 0) return toolError(runtime, "read_file", permissionError);
|
|
1681
1746
|
const resolvedBackend = await resolveBackend(backend, runtime);
|
|
1682
1747
|
const { file_path, offset = 0, limit = 100 } = input;
|
|
1683
1748
|
const readResult = await resolvedBackend.read(file_path, offset, limit);
|
|
@@ -1754,7 +1819,8 @@ function createReadFileTool(backend, options) {
|
|
|
1754
1819
|
function createWriteFileTool(backend, options) {
|
|
1755
1820
|
const { customDescription, permissions } = options;
|
|
1756
1821
|
return tool(async (input, runtime) => {
|
|
1757
|
-
|
|
1822
|
+
const permissionError = checkPermission(permissions, "write", input.file_path);
|
|
1823
|
+
if (permissionError !== void 0) return toolError(runtime, "write_file", permissionError);
|
|
1758
1824
|
const resolvedBackend = await resolveBackend(backend, runtime);
|
|
1759
1825
|
const { file_path, content } = input;
|
|
1760
1826
|
const result = await resolvedBackend.write(file_path, content);
|
|
@@ -1785,7 +1851,8 @@ function createWriteFileTool(backend, options) {
|
|
|
1785
1851
|
function createEditFileTool(backend, options) {
|
|
1786
1852
|
const { customDescription, permissions } = options;
|
|
1787
1853
|
return tool(async (input, runtime) => {
|
|
1788
|
-
|
|
1854
|
+
const permissionError = checkPermission(permissions, "write", input.file_path);
|
|
1855
|
+
if (permissionError !== void 0) return toolError(runtime, "edit_file", permissionError);
|
|
1789
1856
|
const resolvedBackend = await resolveBackend(backend, runtime);
|
|
1790
1857
|
const { file_path, old_string, new_string, replace_all = false } = input;
|
|
1791
1858
|
const result = await resolvedBackend.edit(file_path, old_string, new_string, replace_all);
|
|
@@ -1818,7 +1885,8 @@ function createEditFileTool(backend, options) {
|
|
|
1818
1885
|
function createGlobTool(backend, options) {
|
|
1819
1886
|
const { customDescription, permissions } = options;
|
|
1820
1887
|
return tool(async (input, runtime) => {
|
|
1821
|
-
|
|
1888
|
+
const permissionError = checkPermission(permissions, "read", input.path ?? "/");
|
|
1889
|
+
if (permissionError !== void 0) return toolError(runtime, "glob", permissionError);
|
|
1822
1890
|
const resolvedBackend = await resolveBackend(backend, runtime);
|
|
1823
1891
|
const { pattern, path = "/" } = input;
|
|
1824
1892
|
const globResult = await resolvedBackend.glob(pattern, path);
|
|
@@ -1843,7 +1911,8 @@ function createGlobTool(backend, options) {
|
|
|
1843
1911
|
function createGrepTool(backend, options) {
|
|
1844
1912
|
const { customDescription, permissions } = options;
|
|
1845
1913
|
return tool(async (input, runtime) => {
|
|
1846
|
-
|
|
1914
|
+
const permissionError = checkPermission(permissions, "read", input.path ?? "/");
|
|
1915
|
+
if (permissionError !== void 0) return toolError(runtime, "grep", permissionError);
|
|
1847
1916
|
const resolvedBackend = await resolveBackend(backend, runtime);
|
|
1848
1917
|
const { pattern, path = "/", glob = null } = input;
|
|
1849
1918
|
const result = await resolvedBackend.grep(pattern, path, glob);
|
|
@@ -1899,6 +1968,12 @@ function createExecuteTool(backend, options) {
|
|
|
1899
1968
|
* Returns true only when backend exposes route prefixes (CompositeBackend) and
|
|
1900
1969
|
* every permission path is scoped under one of them.
|
|
1901
1970
|
*/
|
|
1971
|
+
function normalizeFilesystemTools(tools) {
|
|
1972
|
+
if (tools == null || tools === "all") return null;
|
|
1973
|
+
const enabledTools = new Set(tools);
|
|
1974
|
+
if (!enabledTools.has("read_file")) throw new Error("read_file must be included in tools; it is required by FilesystemMiddleware");
|
|
1975
|
+
return enabledTools;
|
|
1976
|
+
}
|
|
1902
1977
|
function allPathsScopedToRoutes(permissions, backend) {
|
|
1903
1978
|
if (!CompositeBackend.isInstance(backend)) return false;
|
|
1904
1979
|
const prefixes = backend.routePrefixes;
|
|
@@ -1906,13 +1981,43 @@ function allPathsScopedToRoutes(permissions, backend) {
|
|
|
1906
1981
|
return permissions.every((rule) => rule.paths.every((path) => prefixes.some((prefix) => path.startsWith(prefix.endsWith("/") ? prefix : `${prefix}/`))));
|
|
1907
1982
|
}
|
|
1908
1983
|
/**
|
|
1909
|
-
* Create
|
|
1984
|
+
* Create middleware that provides built-in filesystem tools and filesystem-aware
|
|
1985
|
+
* prompt guidance.
|
|
1986
|
+
*
|
|
1987
|
+
* By default, the middleware registers every built-in filesystem tool listed in
|
|
1988
|
+
* {@link FILESYSTEM_TOOL_NAMES}. Use {@link FilesystemMiddlewareOptions.tools}
|
|
1989
|
+
* to narrow that set for read-only, search-only, or otherwise restricted
|
|
1990
|
+
* agents. The allowlist only controls built-in filesystem tools; custom tools
|
|
1991
|
+
* from the agent or other middleware are left untouched.
|
|
1992
|
+
*
|
|
1993
|
+
* The middleware also filters tools whose backend capabilities are unavailable
|
|
1994
|
+
* at request time. In particular, `execute` is only visible when the resolved
|
|
1995
|
+
* backend supports command execution. The filesystem prompt is generated from
|
|
1996
|
+
* the final visible filesystem tools so the model is not instructed to call
|
|
1997
|
+
* tools it cannot see.
|
|
1998
|
+
*
|
|
1999
|
+
* @param options Filesystem middleware configuration.
|
|
2000
|
+
* @returns Agent middleware that contributes filesystem state, tools, prompt
|
|
2001
|
+
* guidance, permission checks, and large-result eviction.
|
|
2002
|
+
*
|
|
2003
|
+
* @example Read-only filesystem middleware
|
|
2004
|
+
* ```ts
|
|
2005
|
+
* const middleware = createFilesystemMiddleware({
|
|
2006
|
+
* tools: ["read_file", "ls", "glob", "grep"],
|
|
2007
|
+
* });
|
|
2008
|
+
* ```
|
|
1910
2009
|
*/
|
|
1911
2010
|
function createFilesystemMiddleware(options = {}) {
|
|
1912
|
-
const { backend = (runtime) => new StateBackend(runtime), systemPrompt: customSystemPrompt = null, customToolDescriptions = null, toolTokenLimitBeforeEvict = 2e4, humanMessageTokenLimitBeforeEvict = 5e4, permissions = [] } = options;
|
|
2011
|
+
const { backend = (runtime) => new StateBackend(runtime), systemPrompt: customSystemPrompt = null, customToolDescriptions = null, toolTokenLimitBeforeEvict = 2e4, humanMessageTokenLimitBeforeEvict = 5e4, permissions = [], tools: filesystemTools = null } = options;
|
|
2012
|
+
const enabledFilesystemTools = normalizeFilesystemTools(filesystemTools);
|
|
2013
|
+
const executeToolEnabled = enabledFilesystemTools == null || enabledFilesystemTools.has("execute");
|
|
1913
2014
|
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
|
|
2015
|
+
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.");
|
|
2016
|
+
const baseSystemPrompt = customSystemPrompt ?? null;
|
|
2017
|
+
/**
|
|
2018
|
+
* All tools including execute
|
|
2019
|
+
* (execute will be filtered at runtime if backend doesn't support it)
|
|
2020
|
+
*/
|
|
1916
2021
|
const allToolsByName = {
|
|
1917
2022
|
ls: createLsTool(backend, {
|
|
1918
2023
|
customDescription: customToolDescriptions?.ls,
|
|
@@ -1944,7 +2049,7 @@ function createFilesystemMiddleware(options = {}) {
|
|
|
1944
2049
|
permissions
|
|
1945
2050
|
})
|
|
1946
2051
|
};
|
|
1947
|
-
const allTools =
|
|
2052
|
+
const allTools = FILESYSTEM_TOOL_NAMES.filter((name) => enabledFilesystemTools == null || enabledFilesystemTools.has(name)).map((name) => allToolsByName[name]);
|
|
1948
2053
|
async function processToolMessage(msg, runtime, state, fallbackToolCallId) {
|
|
1949
2054
|
if (!toolTokenLimitBeforeEvict) return {
|
|
1950
2055
|
message: msg,
|
|
@@ -2018,8 +2123,14 @@ function createFilesystemMiddleware(options = {}) {
|
|
|
2018
2123
|
}));
|
|
2019
2124
|
let tools = request.tools;
|
|
2020
2125
|
if (!supportsExecution) tools = tools.filter((t) => t.name !== "execute");
|
|
2021
|
-
|
|
2022
|
-
|
|
2126
|
+
const visibleFilesystemTools = /* @__PURE__ */ new Set();
|
|
2127
|
+
for (const currentTool of tools) {
|
|
2128
|
+
const toolName = typeof currentTool.name === "string" ? currentTool.name : void 0;
|
|
2129
|
+
if (isFilesystemToolName(toolName)) visibleFilesystemTools.add(toolName);
|
|
2130
|
+
}
|
|
2131
|
+
const executionActive = supportsExecution && visibleFilesystemTools.has("execute");
|
|
2132
|
+
let filesystemPrompt = baseSystemPrompt ?? buildFilesystemSystemPrompt(visibleFilesystemTools);
|
|
2133
|
+
if (executionActive) filesystemPrompt = `${filesystemPrompt}\n\n${EXECUTION_SYSTEM_PROMPT}`;
|
|
2023
2134
|
const newSystemMessage = request.systemMessage.concat(filesystemPrompt);
|
|
2024
2135
|
let messages = request.messages;
|
|
2025
2136
|
if (humanMessageTokenLimitBeforeEvict && messages) {
|
|
@@ -3457,6 +3568,43 @@ function createSkillsMiddleware(options) {
|
|
|
3457
3568
|
});
|
|
3458
3569
|
}
|
|
3459
3570
|
//#endregion
|
|
3571
|
+
//#region src/middleware/utils.ts
|
|
3572
|
+
/**
|
|
3573
|
+
* Merge custom middleware into an assembled stack by `.name`.
|
|
3574
|
+
*
|
|
3575
|
+
* Matching custom middleware replaces the existing entry in place. New
|
|
3576
|
+
* middleware is appended after the base stack in caller-provided order.
|
|
3577
|
+
*/
|
|
3578
|
+
function mergeMiddleware$1(base, custom) {
|
|
3579
|
+
const merged = new Map(base.map((middleware) => [middleware.name, middleware]));
|
|
3580
|
+
for (const middleware of custom) merged.set(middleware.name, middleware);
|
|
3581
|
+
return [...merged.values()];
|
|
3582
|
+
}
|
|
3583
|
+
function middlewareNames(middleware) {
|
|
3584
|
+
return new Set(middleware.map((entry) => entry.name));
|
|
3585
|
+
}
|
|
3586
|
+
function matchingMiddleware(middleware, names) {
|
|
3587
|
+
return middleware.filter((entry) => names.has(entry.name));
|
|
3588
|
+
}
|
|
3589
|
+
/**
|
|
3590
|
+
* Merge custom middleware into default and tail middleware segments.
|
|
3591
|
+
*
|
|
3592
|
+
* Same-name custom entries replace matching defaults in either segment. Novel
|
|
3593
|
+
* custom entries are inserted between the default and tail segments unless
|
|
3594
|
+
* `appendNew` is false.
|
|
3595
|
+
*/
|
|
3596
|
+
function mergeMiddlewareStack(defaultMiddleware, customMiddleware, tailMiddleware = [], options = {}) {
|
|
3597
|
+
const defaultMiddlewareNames = middlewareNames(defaultMiddleware);
|
|
3598
|
+
const tailMiddlewareNames = middlewareNames(tailMiddleware);
|
|
3599
|
+
const knownMiddlewareNames = /* @__PURE__ */ new Set([...defaultMiddlewareNames, ...tailMiddlewareNames]);
|
|
3600
|
+
const novelMiddleware = options.appendNew === false ? [] : customMiddleware.filter((entry) => !knownMiddlewareNames.has(entry.name));
|
|
3601
|
+
return [
|
|
3602
|
+
...mergeMiddleware$1(defaultMiddleware, matchingMiddleware(customMiddleware, defaultMiddlewareNames)),
|
|
3603
|
+
...novelMiddleware,
|
|
3604
|
+
...mergeMiddleware$1(tailMiddleware, matchingMiddleware(customMiddleware, tailMiddlewareNames))
|
|
3605
|
+
];
|
|
3606
|
+
}
|
|
3607
|
+
//#endregion
|
|
3460
3608
|
//#region src/middleware/completion_callback.ts
|
|
3461
3609
|
/**
|
|
3462
3610
|
* Callback middleware for async subagents.
|
|
@@ -5048,6 +5196,28 @@ function createCacheBreakpointMiddleware() {
|
|
|
5048
5196
|
});
|
|
5049
5197
|
}
|
|
5050
5198
|
//#endregion
|
|
5199
|
+
//#region src/middleware/tool_exclusion.ts
|
|
5200
|
+
function hasToolName(tool) {
|
|
5201
|
+
return tool !== null && typeof tool === "object" && "name" in tool && typeof tool.name === "string";
|
|
5202
|
+
}
|
|
5203
|
+
/**
|
|
5204
|
+
* Create middleware that removes excluded tools after all tool-injecting
|
|
5205
|
+
* middleware has had a chance to add tools to the request.
|
|
5206
|
+
*
|
|
5207
|
+
* @internal
|
|
5208
|
+
*/
|
|
5209
|
+
function createToolExclusionMiddleware(excludedTools) {
|
|
5210
|
+
return createMiddleware({
|
|
5211
|
+
name: "_ToolExclusionMiddleware",
|
|
5212
|
+
wrapModelCall(request, handler) {
|
|
5213
|
+
return handler({
|
|
5214
|
+
...request,
|
|
5215
|
+
tools: request.tools?.filter((tool) => !hasToolName(tool) || !excludedTools.has(tool.name))
|
|
5216
|
+
});
|
|
5217
|
+
}
|
|
5218
|
+
});
|
|
5219
|
+
}
|
|
5220
|
+
//#endregion
|
|
5051
5221
|
//#region src/profiles/keys.ts
|
|
5052
5222
|
/**
|
|
5053
5223
|
* Normalize and validate a profile registry key.
|
|
@@ -5751,6 +5921,31 @@ const BASE_AGENT_PROMPT = context`
|
|
|
5751
5921
|
|
|
5752
5922
|
For longer tasks, provide brief progress updates at reasonable intervals — a concise sentence recapping what you've done and what's next.
|
|
5753
5923
|
`;
|
|
5924
|
+
const PROMPT_SEPARATOR = "\n\n";
|
|
5925
|
+
/** Normalize legacy system prompt values to the structured representation. */
|
|
5926
|
+
function normalizeSystemPrompt(systemPrompt) {
|
|
5927
|
+
if (systemPrompt === void 0) return {};
|
|
5928
|
+
if (typeof systemPrompt === "string" || SystemMessage.isInstance(systemPrompt)) return { prefix: systemPrompt };
|
|
5929
|
+
return systemPrompt;
|
|
5930
|
+
}
|
|
5931
|
+
/** Assemble prompt parts while preserving structured message content blocks. */
|
|
5932
|
+
function assemblePromptParts(parts) {
|
|
5933
|
+
if (parts.length === 0) return "";
|
|
5934
|
+
if (parts.every((part) => typeof part === "string")) return parts.join(PROMPT_SEPARATOR);
|
|
5935
|
+
const contentBlocks = [];
|
|
5936
|
+
for (const [index, part] of parts.entries()) {
|
|
5937
|
+
if (index > 0) contentBlocks.push({
|
|
5938
|
+
type: "text",
|
|
5939
|
+
text: PROMPT_SEPARATOR
|
|
5940
|
+
});
|
|
5941
|
+
if (SystemMessage.isInstance(part)) contentBlocks.push(...part.contentBlocks);
|
|
5942
|
+
else contentBlocks.push({
|
|
5943
|
+
type: "text",
|
|
5944
|
+
text: part
|
|
5945
|
+
});
|
|
5946
|
+
}
|
|
5947
|
+
return new SystemMessage({ contentBlocks });
|
|
5948
|
+
}
|
|
5754
5949
|
const BUILTIN_TOOL_NAMES = /* @__PURE__ */ new Set([
|
|
5755
5950
|
...FILESYSTEM_TOOL_NAMES,
|
|
5756
5951
|
...ASYNC_TASK_TOOL_NAMES,
|
|
@@ -5796,6 +5991,8 @@ function createDeepAgent(params = {}) {
|
|
|
5796
5991
|
providerHint: getModelProvider(model),
|
|
5797
5992
|
identifierHint: getModelIdentifier(model)
|
|
5798
5993
|
});
|
|
5994
|
+
const filesystemTools = FILESYSTEM_TOOL_NAMES.filter((toolName) => !harnessProfile.excludedTools.has(toolName));
|
|
5995
|
+
const profileFilesystemTools = filesystemTools.length === FILESYSTEM_TOOL_NAMES.length || !filesystemTools.includes("read_file") ? void 0 : filesystemTools;
|
|
5799
5996
|
const toolOverrides = harnessProfile.toolDescriptionOverrides;
|
|
5800
5997
|
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
5998
|
const anthropicModel = isAnthropicModel(model);
|
|
@@ -5817,23 +6014,26 @@ function createDeepAgent(params = {}) {
|
|
|
5817
6014
|
* Only the general-purpose subagent inherits the main agent's skills.
|
|
5818
6015
|
* If a custom subagent needs skills, it must specify its own `skills` array.
|
|
5819
6016
|
*/
|
|
5820
|
-
const
|
|
6017
|
+
const createSubagentDefaultMiddleware = (input) => {
|
|
5821
6018
|
const effectivePermissions = input.permissions ?? permissions;
|
|
5822
|
-
|
|
6019
|
+
return [
|
|
5823
6020
|
todoListMiddleware(),
|
|
5824
6021
|
createFilesystemMiddleware({
|
|
5825
6022
|
backend,
|
|
5826
|
-
permissions: effectivePermissions
|
|
6023
|
+
permissions: effectivePermissions,
|
|
6024
|
+
tools: profileFilesystemTools
|
|
5827
6025
|
}),
|
|
5828
6026
|
createSummarizationMiddleware({ backend }),
|
|
5829
6027
|
createPatchToolCallsMiddleware(),
|
|
5830
6028
|
...input.skills != null && input.skills.length > 0 ? [createSkillsMiddleware({
|
|
5831
6029
|
backend,
|
|
5832
6030
|
sources: input.skills
|
|
5833
|
-
})] : []
|
|
5834
|
-
...input.middleware ?? [],
|
|
5835
|
-
...cacheMiddleware
|
|
6031
|
+
})] : []
|
|
5836
6032
|
];
|
|
6033
|
+
};
|
|
6034
|
+
const normalizeSubagentSpec = (input) => {
|
|
6035
|
+
let subagentMiddleware = mergeMiddlewareStack(createSubagentDefaultMiddleware(input), input.middleware ?? [], cacheMiddleware);
|
|
6036
|
+
if (harnessProfile.excludedMiddleware.size > 0) subagentMiddleware = subagentMiddleware.filter((middleware) => !harnessProfile.excludedMiddleware.has(middleware.name));
|
|
5837
6037
|
return {
|
|
5838
6038
|
...input,
|
|
5839
6039
|
tools: input.tools ?? [],
|
|
@@ -5854,6 +6054,7 @@ function createDeepAgent(params = {}) {
|
|
|
5854
6054
|
skills,
|
|
5855
6055
|
tools: effectiveTools
|
|
5856
6056
|
});
|
|
6057
|
+
generalPurposeSpec.middleware = mergeMiddlewareStack(generalPurposeSpec.middleware ?? [], customMiddleware, [], { appendNew: false });
|
|
5857
6058
|
inlineSubagents.unshift(generalPurposeSpec);
|
|
5858
6059
|
}
|
|
5859
6060
|
const skillsMiddleware = skills != null && skills.length > 0 ? [createSkillsMiddleware({
|
|
@@ -5864,7 +6065,8 @@ function createDeepAgent(params = {}) {
|
|
|
5864
6065
|
todoListMiddleware(),
|
|
5865
6066
|
createFilesystemMiddleware({
|
|
5866
6067
|
backend,
|
|
5867
|
-
permissions
|
|
6068
|
+
permissions,
|
|
6069
|
+
tools: profileFilesystemTools
|
|
5868
6070
|
}),
|
|
5869
6071
|
createSubAgentMiddleware({
|
|
5870
6072
|
defaultModel: model,
|
|
@@ -5876,15 +6078,16 @@ function createDeepAgent(params = {}) {
|
|
|
5876
6078
|
createSummarizationMiddleware({ backend }),
|
|
5877
6079
|
createPatchToolCallsMiddleware()
|
|
5878
6080
|
];
|
|
5879
|
-
|
|
6081
|
+
let middleware = mergeMiddlewareStack([
|
|
5880
6082
|
todoMiddleware,
|
|
5881
6083
|
...skillsMiddleware,
|
|
5882
6084
|
fsMiddleware,
|
|
5883
6085
|
subagentMiddleware,
|
|
5884
6086
|
summarizationMiddleware,
|
|
5885
6087
|
patchToolCallsMiddleware,
|
|
5886
|
-
...asyncSubAgents.length > 0 ? [createAsyncSubAgentMiddleware({ asyncSubAgents })] : []
|
|
5887
|
-
|
|
6088
|
+
...asyncSubAgents.length > 0 ? [createAsyncSubAgentMiddleware({ asyncSubAgents })] : []
|
|
6089
|
+
], customMiddleware, [
|
|
6090
|
+
...resolveMiddleware(harnessProfile.extraMiddleware),
|
|
5888
6091
|
...cacheMiddleware,
|
|
5889
6092
|
...memory && memory.length > 0 ? [createMemoryMiddleware({
|
|
5890
6093
|
backend,
|
|
@@ -5892,32 +6095,19 @@ function createDeepAgent(params = {}) {
|
|
|
5892
6095
|
addCacheControl: anthropicModel
|
|
5893
6096
|
})] : [],
|
|
5894
6097
|
...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
|
-
}
|
|
6098
|
+
]);
|
|
5902
6099
|
if (harnessProfile.excludedMiddleware.size > 0) {
|
|
5903
6100
|
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);
|
|
6101
|
+
middleware = middleware.filter((entry) => !excluded.has(entry.name));
|
|
6102
|
+
}
|
|
6103
|
+
if (harnessProfile.excludedTools.size > 0) middleware.push(createToolExclusionMiddleware(harnessProfile.excludedTools));
|
|
6104
|
+
const promptConfig = normalizeSystemPrompt(systemPrompt);
|
|
6105
|
+
const promptParts = [];
|
|
6106
|
+
if (promptConfig.prefix !== void 0 && promptConfig.prefix !== null) promptParts.push(promptConfig.prefix);
|
|
6107
|
+
const activeBasePrompt = promptConfig.base !== void 0 ? promptConfig.base : harnessProfile.baseSystemPrompt ?? BASE_AGENT_PROMPT;
|
|
6108
|
+
if (activeBasePrompt !== null) promptParts.push(activeBasePrompt);
|
|
6109
|
+
if (promptConfig.suffix) promptParts.push(promptConfig.suffix);
|
|
6110
|
+
if (harnessProfile.systemPromptSuffix) promptParts.push(harnessProfile.systemPromptSuffix);
|
|
5921
6111
|
/**
|
|
5922
6112
|
* Return as DeepAgent with proper DeepAgentTypeConfig
|
|
5923
6113
|
* - Response: InferStructuredResponse<TResponse> (unwraps ToolStrategy<T>/ProviderStrategy<T> → T)
|
|
@@ -5930,19 +6120,7 @@ function createDeepAgent(params = {}) {
|
|
|
5930
6120
|
*/
|
|
5931
6121
|
return createAgent({
|
|
5932
6122
|
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
|
-
}] }),
|
|
6123
|
+
systemPrompt: assemblePromptParts(promptParts),
|
|
5946
6124
|
stateSchema,
|
|
5947
6125
|
tools: effectiveTools,
|
|
5948
6126
|
middleware,
|
|
@@ -6294,6 +6472,19 @@ var StoreBackend = class {
|
|
|
6294
6472
|
}
|
|
6295
6473
|
}
|
|
6296
6474
|
/**
|
|
6475
|
+
* Delete a file from the store.
|
|
6476
|
+
*
|
|
6477
|
+
* The file path is used as an exact store key. Wildcards are treated
|
|
6478
|
+
* literally and do not expand to multiple entries.
|
|
6479
|
+
*/
|
|
6480
|
+
async delete(filePath) {
|
|
6481
|
+
const store = this.getStore();
|
|
6482
|
+
const namespace = this.getNamespace();
|
|
6483
|
+
if (!await store.get(namespace, filePath)) return { error: `Error: File '${filePath}' not found` };
|
|
6484
|
+
await store.delete(namespace, filePath);
|
|
6485
|
+
return { path: filePath };
|
|
6486
|
+
}
|
|
6487
|
+
/**
|
|
6297
6488
|
* Search file contents for a literal text pattern.
|
|
6298
6489
|
* Binary files are skipped.
|
|
6299
6490
|
*/
|
|
@@ -6506,10 +6697,10 @@ var ContextHubBackend = class ContextHubBackend {
|
|
|
6506
6697
|
if (this.cache === null) throw new Error("Context Hub cache failed to initialize");
|
|
6507
6698
|
return this.cache;
|
|
6508
6699
|
}
|
|
6509
|
-
async commit(
|
|
6510
|
-
if (Object.keys(
|
|
6700
|
+
async commit(changes) {
|
|
6701
|
+
if (Object.keys(changes).length === 0) return;
|
|
6511
6702
|
const payload = {};
|
|
6512
|
-
for (const [path, content] of Object.entries(
|
|
6703
|
+
for (const [path, content] of Object.entries(changes)) payload[path] = content === null ? null : {
|
|
6513
6704
|
type: "file",
|
|
6514
6705
|
content
|
|
6515
6706
|
};
|
|
@@ -6519,7 +6710,14 @@ var ContextHubBackend = class ContextHubBackend {
|
|
|
6519
6710
|
});
|
|
6520
6711
|
const match = URL_COMMIT_SUFFIX_RE.exec(url);
|
|
6521
6712
|
if (match) this.commitHash = match[1];
|
|
6522
|
-
if (this.cache !== null)
|
|
6713
|
+
if (this.cache !== null) {
|
|
6714
|
+
const deletions = new Set(Object.entries(changes).filter(([, content]) => content === null).map(([path]) => path));
|
|
6715
|
+
const updates = Object.fromEntries(Object.entries(changes).filter((entry) => entry[1] !== null));
|
|
6716
|
+
this.cache = {
|
|
6717
|
+
...Object.fromEntries(Object.entries(this.cache).filter(([path]) => !deletions.has(path))),
|
|
6718
|
+
...updates
|
|
6719
|
+
};
|
|
6720
|
+
}
|
|
6523
6721
|
}
|
|
6524
6722
|
/**
|
|
6525
6723
|
* Return linked-entry paths mapped to their repo handles.
|
|
@@ -6678,6 +6876,20 @@ var ContextHubBackend = class ContextHubBackend {
|
|
|
6678
6876
|
throw error;
|
|
6679
6877
|
}
|
|
6680
6878
|
}
|
|
6879
|
+
async delete(filePath) {
|
|
6880
|
+
const hubPath = ContextHubBackend.stripPrefix(filePath);
|
|
6881
|
+
try {
|
|
6882
|
+
if (!(hubPath in await this.ensureCache())) return { error: `Error: File '${filePath}' not found` };
|
|
6883
|
+
await this.commit({ [hubPath]: null });
|
|
6884
|
+
return { path: filePath };
|
|
6885
|
+
} catch (error) {
|
|
6886
|
+
if (isLangSmithError(error)) {
|
|
6887
|
+
this.cache = null;
|
|
6888
|
+
return { error: ContextHubBackend.toHubUnavailableError(error) };
|
|
6889
|
+
}
|
|
6890
|
+
throw error;
|
|
6891
|
+
}
|
|
6892
|
+
}
|
|
6681
6893
|
async uploadFiles(files) {
|
|
6682
6894
|
const decoder = new TextDecoder("utf-8", { fatal: true });
|
|
6683
6895
|
const decoded = [];
|
|
@@ -7170,6 +7382,16 @@ var BaseSandbox = class {
|
|
|
7170
7382
|
occurrences: count
|
|
7171
7383
|
};
|
|
7172
7384
|
}
|
|
7385
|
+
/**
|
|
7386
|
+
* Delete a file from the sandbox via a server-side rm.
|
|
7387
|
+
*
|
|
7388
|
+
* Uses rm -f, so deleting a path that does not exist succeeds silently.
|
|
7389
|
+
*/
|
|
7390
|
+
async delete(filePath) {
|
|
7391
|
+
const result = await this.execute(`rm -f ${shellQuote(filePath)}`);
|
|
7392
|
+
if (result.exitCode === 0) return { path: filePath };
|
|
7393
|
+
return { error: `Error deleting file '${filePath}': ${result.output.trim() || "unknown error"}` };
|
|
7394
|
+
}
|
|
7173
7395
|
};
|
|
7174
7396
|
//#endregion
|
|
7175
7397
|
//#region src/backends/langsmith.ts
|
|
@@ -7373,4 +7595,4 @@ var LangSmithSandbox = class LangSmithSandbox extends BaseSandbox {
|
|
|
7373
7595
|
//#endregion
|
|
7374
7596
|
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
7597
|
|
|
7376
|
-
//# sourceMappingURL=langsmith-
|
|
7598
|
+
//# sourceMappingURL=langsmith-DVh4u6Za.js.map
|