deepagents 1.11.0 → 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.
@@ -1526,19 +1526,46 @@ const FilesystemStateSchema = new _langchain_langgraph.StateSchema({ files: new
1526
1526
  inputSchema: zod_v4.z.record(zod_v4.z.string(), FileDataSchema.nullable()).optional(),
1527
1527
  reducer: fileDataReducer
1528
1528
  }) });
1529
+ /** Extract a message string from an unknown thrown value without `instanceof`. */
1530
+ function getErrorMessage$1(error) {
1531
+ if (typeof error === "object" && error !== null && "message" in error && typeof error.message === "string") return error.message;
1532
+ return String(error);
1533
+ }
1529
1534
  /**
1530
- * Throw a permission-denied error if `path` is denied under `rules`.
1535
+ * Check whether `path` is permitted under `rules` for `operation`, returning an
1536
+ * error string to surface to the model (or `undefined` when allowed).
1531
1537
  *
1532
- * No-op when `rules` is empty (permissive default). Paths that fail
1533
- * `validatePath` are silently skipped the tool's own input validation
1534
- * will surface a better error.
1538
+ * Never throws: an invalid path (non-absolute, or containing `..` or `~`) or a
1539
+ * denied path is a recoverable tool error, not a fatal run-ending one. Such
1540
+ * paths are rejected, never normalized, so they cannot bypass a deny rule or
1541
+ * reach the backend.
1535
1542
  *
1536
1543
  * @internal
1537
1544
  */
1538
- function enforcePermission(rules, operation, path) {
1545
+ function checkPermission(rules, operation, path) {
1539
1546
  if (rules.length === 0) return;
1540
- const canonical = validatePath(path);
1541
- if (decidePathAccess(rules, operation, canonical) === "deny") throw new Error(`Error: permission denied for ${operation} on ${canonical}`);
1547
+ let canonical;
1548
+ try {
1549
+ canonical = validatePath(path);
1550
+ } catch (error) {
1551
+ return `Error: ${getErrorMessage$1(error)}`;
1552
+ }
1553
+ if (decidePathAccess(rules, operation, canonical) === "deny") return `Error: permission denied for ${operation} on ${canonical}`;
1554
+ }
1555
+ /**
1556
+ * Build an error {@link ToolMessage} for a rejected or denied path. Returning a
1557
+ * bare string would be wrapped as a `status: "success"` message whose content
1558
+ * merely starts with "Error:"; marking `status: "error"` reports the failure
1559
+ * accurately so callers and the model can distinguish a real failure from a
1560
+ * successful result.
1561
+ */
1562
+ function toolError(runtime, toolName, message) {
1563
+ return new langchain.ToolMessage({
1564
+ content: message,
1565
+ name: toolName,
1566
+ tool_call_id: runtime.toolCall?.id,
1567
+ status: "error"
1568
+ });
1542
1569
  }
1543
1570
  /**
1544
1571
  * Filter a list of filesystem entries to those the rules permit.
@@ -1709,7 +1736,8 @@ const EXECUTION_SYSTEM_PROMPT = langchain.context`
1709
1736
  function createLsTool(backend, options) {
1710
1737
  const { customDescription, permissions } = options;
1711
1738
  return (0, langchain.tool)(async (input, runtime) => {
1712
- enforcePermission(permissions, "read", input.path ?? "/");
1739
+ const permissionError = checkPermission(permissions, "read", input.path ?? "/");
1740
+ if (permissionError !== void 0) return toolError(runtime, "ls", permissionError);
1713
1741
  const resolvedBackend = await resolveBackend(backend, runtime);
1714
1742
  const path = input.path || "/";
1715
1743
  const lsResult = await resolvedBackend.ls(path);
@@ -1737,7 +1765,8 @@ function createLsTool(backend, options) {
1737
1765
  function createReadFileTool(backend, options) {
1738
1766
  const { customDescription, toolTokenLimitBeforeEvict, permissions } = options;
1739
1767
  return (0, langchain.tool)(async (input, runtime) => {
1740
- enforcePermission(permissions, "read", input.file_path);
1768
+ const permissionError = checkPermission(permissions, "read", input.file_path);
1769
+ if (permissionError !== void 0) return toolError(runtime, "read_file", permissionError);
1741
1770
  const resolvedBackend = await resolveBackend(backend, runtime);
1742
1771
  const { file_path, offset = 0, limit = 100 } = input;
1743
1772
  const readResult = await resolvedBackend.read(file_path, offset, limit);
@@ -1814,7 +1843,8 @@ function createReadFileTool(backend, options) {
1814
1843
  function createWriteFileTool(backend, options) {
1815
1844
  const { customDescription, permissions } = options;
1816
1845
  return (0, langchain.tool)(async (input, runtime) => {
1817
- enforcePermission(permissions, "write", input.file_path);
1846
+ const permissionError = checkPermission(permissions, "write", input.file_path);
1847
+ if (permissionError !== void 0) return toolError(runtime, "write_file", permissionError);
1818
1848
  const resolvedBackend = await resolveBackend(backend, runtime);
1819
1849
  const { file_path, content } = input;
1820
1850
  const result = await resolvedBackend.write(file_path, content);
@@ -1845,7 +1875,8 @@ function createWriteFileTool(backend, options) {
1845
1875
  function createEditFileTool(backend, options) {
1846
1876
  const { customDescription, permissions } = options;
1847
1877
  return (0, langchain.tool)(async (input, runtime) => {
1848
- enforcePermission(permissions, "write", input.file_path);
1878
+ const permissionError = checkPermission(permissions, "write", input.file_path);
1879
+ if (permissionError !== void 0) return toolError(runtime, "edit_file", permissionError);
1849
1880
  const resolvedBackend = await resolveBackend(backend, runtime);
1850
1881
  const { file_path, old_string, new_string, replace_all = false } = input;
1851
1882
  const result = await resolvedBackend.edit(file_path, old_string, new_string, replace_all);
@@ -1878,7 +1909,8 @@ function createEditFileTool(backend, options) {
1878
1909
  function createGlobTool(backend, options) {
1879
1910
  const { customDescription, permissions } = options;
1880
1911
  return (0, langchain.tool)(async (input, runtime) => {
1881
- enforcePermission(permissions, "read", input.path ?? "/");
1912
+ const permissionError = checkPermission(permissions, "read", input.path ?? "/");
1913
+ if (permissionError !== void 0) return toolError(runtime, "glob", permissionError);
1882
1914
  const resolvedBackend = await resolveBackend(backend, runtime);
1883
1915
  const { pattern, path = "/" } = input;
1884
1916
  const globResult = await resolvedBackend.glob(pattern, path);
@@ -1903,7 +1935,8 @@ function createGlobTool(backend, options) {
1903
1935
  function createGrepTool(backend, options) {
1904
1936
  const { customDescription, permissions } = options;
1905
1937
  return (0, langchain.tool)(async (input, runtime) => {
1906
- enforcePermission(permissions, "read", input.path ?? "/");
1938
+ const permissionError = checkPermission(permissions, "read", input.path ?? "/");
1939
+ if (permissionError !== void 0) return toolError(runtime, "grep", permissionError);
1907
1940
  const resolvedBackend = await resolveBackend(backend, runtime);
1908
1941
  const { pattern, path = "/", glob = null } = input;
1909
1942
  const result = await resolvedBackend.grep(pattern, path, glob);
@@ -7878,4 +7911,4 @@ Object.defineProperty(exports, "serializeProfile", {
7878
7911
  }
7879
7912
  });
7880
7913
 
7881
- //# sourceMappingURL=langsmith-DDhVumyX.cjs.map
7914
+ //# sourceMappingURL=langsmith-DhbsxI45.cjs.map