deepagents 1.8.5 → 1.8.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -106,6 +106,17 @@ var SandboxError = class SandboxError extends Error {
106
106
  return typeof error === "object" && error !== null && error[SANDBOX_ERROR_SYMBOL] === true;
107
107
  }
108
108
  };
109
+ /**
110
+ * Resolve a backend instance or await a {@link BackendFactory}.
111
+ *
112
+ * Accepts {@link BackendRuntime} or {@link ToolRuntime} — store typing differs
113
+ * between LangGraph checkpoint stores and core `ToolRuntime`; factories receive
114
+ * a value that is structurally compatible at runtime.
115
+ */
116
+ async function resolveBackend(backend, runtime) {
117
+ if (typeof backend === "function") return await backend(runtime);
118
+ return backend;
119
+ }
109
120
  //#endregion
110
121
  //#region src/backends/utils.ts
111
122
  /**
@@ -387,15 +398,15 @@ function grepMatchesFromFiles(files, pattern, path$9 = null, glob = null) {
387
398
  * for the middleware to apply via Command.
388
399
  */
389
400
  var StateBackend = class {
390
- stateAndStore;
391
- constructor(stateAndStore) {
392
- this.stateAndStore = stateAndStore;
401
+ runtime;
402
+ constructor(runtime) {
403
+ this.runtime = runtime;
393
404
  }
394
405
  /**
395
406
  * Get files from current state.
396
407
  */
397
408
  getFiles() {
398
- return this.stateAndStore.state.files || {};
409
+ return this.runtime.state.files || {};
399
410
  }
400
411
  /**
401
412
  * List files and directories in the specified directory (non-recursive).
@@ -708,16 +719,6 @@ const FilesystemStateSchema = new _langchain_langgraph.StateSchema({ files: new
708
719
  inputSchema: zod_v4.z.record(zod_v4.z.string(), FileDataSchema.nullable()).optional(),
709
720
  reducer: fileDataReducer
710
721
  }) });
711
- /**
712
- * Resolve backend from factory or instance.
713
- *
714
- * @param backend - Backend instance or factory function
715
- * @param stateAndStore - State and store container for backend initialization
716
- */
717
- function getBackend(backend, stateAndStore) {
718
- if (typeof backend === "function") return backend(stateAndStore);
719
- return backend;
720
- }
721
722
  const FILESYSTEM_SYSTEM_PROMPT = `## Filesystem Tools \`ls\`, \`read_file\`, \`write_file\`, \`edit_file\`, \`glob\`, \`grep\`
722
723
 
723
724
  You have access to a filesystem which you can interact with using these tools.
@@ -835,11 +836,8 @@ Use this tool to run commands, scripts, tests, builds, and other shell operation
835
836
  */
836
837
  function createLsTool(backend, options) {
837
838
  const { customDescription } = options;
838
- return (0, langchain.tool)(async (input, config) => {
839
- const resolvedBackend = getBackend(backend, {
840
- state: (0, _langchain_langgraph.getCurrentTaskInput)(config),
841
- store: config.store
842
- });
839
+ return (0, langchain.tool)(async (input, runtime) => {
840
+ const resolvedBackend = await resolveBackend(backend, runtime);
843
841
  const path = input.path || "/";
844
842
  const infos = await resolvedBackend.lsInfo(path);
845
843
  if (infos.length === 0) return `No files found in ${path}`;
@@ -863,11 +861,8 @@ function createLsTool(backend, options) {
863
861
  */
864
862
  function createReadFileTool(backend, options) {
865
863
  const { customDescription, toolTokenLimitBeforeEvict } = options;
866
- return (0, langchain.tool)(async (input, config) => {
867
- const resolvedBackend = getBackend(backend, {
868
- state: (0, _langchain_langgraph.getCurrentTaskInput)(config),
869
- store: config.store
870
- });
864
+ return (0, langchain.tool)(async (input, runtime) => {
865
+ const resolvedBackend = await resolveBackend(backend, runtime);
871
866
  const { file_path, offset = 0, limit = 100 } = input;
872
867
  let result = await resolvedBackend.read(file_path, offset, limit);
873
868
  const lines = result.split("\n");
@@ -893,17 +888,14 @@ function createReadFileTool(backend, options) {
893
888
  */
894
889
  function createWriteFileTool(backend, options) {
895
890
  const { customDescription } = options;
896
- return (0, langchain.tool)(async (input, config) => {
897
- const resolvedBackend = getBackend(backend, {
898
- state: (0, _langchain_langgraph.getCurrentTaskInput)(config),
899
- store: config.store
900
- });
891
+ return (0, langchain.tool)(async (input, runtime) => {
892
+ const resolvedBackend = await resolveBackend(backend, runtime);
901
893
  const { file_path, content } = input;
902
894
  const result = await resolvedBackend.write(file_path, content);
903
895
  if (result.error) return result.error;
904
896
  const message = new langchain.ToolMessage({
905
897
  content: `Successfully wrote to '${file_path}'`,
906
- tool_call_id: config.toolCall?.id,
898
+ tool_call_id: runtime.toolCall?.id,
907
899
  name: "write_file",
908
900
  metadata: result.metadata
909
901
  });
@@ -926,17 +918,14 @@ function createWriteFileTool(backend, options) {
926
918
  */
927
919
  function createEditFileTool(backend, options) {
928
920
  const { customDescription } = options;
929
- return (0, langchain.tool)(async (input, config) => {
930
- const resolvedBackend = getBackend(backend, {
931
- state: (0, _langchain_langgraph.getCurrentTaskInput)(config),
932
- store: config.store
933
- });
921
+ return (0, langchain.tool)(async (input, runtime) => {
922
+ const resolvedBackend = await resolveBackend(backend, runtime);
934
923
  const { file_path, old_string, new_string, replace_all = false } = input;
935
924
  const result = await resolvedBackend.edit(file_path, old_string, new_string, replace_all);
936
925
  if (result.error) return result.error;
937
926
  const message = new langchain.ToolMessage({
938
927
  content: `Successfully replaced ${result.occurrences} occurrence(s) in '${file_path}'`,
939
- tool_call_id: config.toolCall?.id,
928
+ tool_call_id: runtime.toolCall?.id,
940
929
  name: "edit_file",
941
930
  metadata: result.metadata
942
931
  });
@@ -961,11 +950,8 @@ function createEditFileTool(backend, options) {
961
950
  */
962
951
  function createGlobTool(backend, options) {
963
952
  const { customDescription } = options;
964
- return (0, langchain.tool)(async (input, config) => {
965
- const resolvedBackend = getBackend(backend, {
966
- state: (0, _langchain_langgraph.getCurrentTaskInput)(config),
967
- store: config.store
968
- });
953
+ return (0, langchain.tool)(async (input, runtime) => {
954
+ const resolvedBackend = await resolveBackend(backend, runtime);
969
955
  const { pattern, path = "/" } = input;
970
956
  const infos = await resolvedBackend.globInfo(pattern, path);
971
957
  if (infos.length === 0) return `No files found matching pattern '${pattern}'`;
@@ -986,11 +972,8 @@ function createGlobTool(backend, options) {
986
972
  */
987
973
  function createGrepTool(backend, options) {
988
974
  const { customDescription } = options;
989
- return (0, langchain.tool)(async (input, config) => {
990
- const resolvedBackend = getBackend(backend, {
991
- state: (0, _langchain_langgraph.getCurrentTaskInput)(config),
992
- store: config.store
993
- });
975
+ return (0, langchain.tool)(async (input, runtime) => {
976
+ const resolvedBackend = await resolveBackend(backend, runtime);
994
977
  const { pattern, path = "/", glob = null } = input;
995
978
  const result = await resolvedBackend.grepRaw(pattern, path, glob);
996
979
  if (typeof result === "string") return result;
@@ -1022,11 +1005,8 @@ function createGrepTool(backend, options) {
1022
1005
  */
1023
1006
  function createExecuteTool(backend, options) {
1024
1007
  const { customDescription } = options;
1025
- return (0, langchain.tool)(async (input, config) => {
1026
- const resolvedBackend = getBackend(backend, {
1027
- state: (0, _langchain_langgraph.getCurrentTaskInput)(config),
1028
- store: config.store
1029
- });
1008
+ return (0, langchain.tool)(async (input, runtime) => {
1009
+ const resolvedBackend = await resolveBackend(backend, runtime);
1030
1010
  if (!isSandboxBackend(resolvedBackend)) return "Error: Execution not available. This agent's backend does not support command execution (SandboxBackendProtocol). To use the execute tool, provide a backend that implements SandboxBackendProtocol.";
1031
1011
  const result = await resolvedBackend.execute(input.command);
1032
1012
  const parts = [result.output];
@@ -1046,7 +1026,7 @@ function createExecuteTool(backend, options) {
1046
1026
  * Create filesystem middleware with all tools and features.
1047
1027
  */
1048
1028
  function createFilesystemMiddleware(options = {}) {
1049
- const { backend = (stateAndStore) => new StateBackend(stateAndStore), systemPrompt: customSystemPrompt = null, customToolDescriptions = null, toolTokenLimitBeforeEvict = 2e4 } = options;
1029
+ const { backend = (runtime) => new StateBackend(runtime), systemPrompt: customSystemPrompt = null, customToolDescriptions = null, toolTokenLimitBeforeEvict = 2e4 } = options;
1050
1030
  const baseSystemPrompt = customSystemPrompt || FILESYSTEM_SYSTEM_PROMPT;
1051
1031
  const allToolsByName = {
1052
1032
  ls: createLsTool(backend, { customDescription: customToolDescriptions?.ls }),
@@ -1065,9 +1045,9 @@ function createFilesystemMiddleware(options = {}) {
1065
1045
  stateSchema: FilesystemStateSchema,
1066
1046
  tools: Object.values(allToolsByName),
1067
1047
  wrapModelCall: async (request, handler) => {
1068
- const supportsExecution = isSandboxBackend(getBackend(backend, {
1069
- state: request.state || {},
1070
- store: request.runtime?.store
1048
+ const supportsExecution = isSandboxBackend(await resolveBackend(backend, {
1049
+ ...request.runtime,
1050
+ state: request.state
1071
1051
  }));
1072
1052
  let tools = request.tools;
1073
1053
  if (!supportsExecution) tools = tools.filter((t) => t.name !== "execute");
@@ -1087,9 +1067,9 @@ function createFilesystemMiddleware(options = {}) {
1087
1067
  const result = await handler(request);
1088
1068
  async function processToolMessage(msg, toolTokenLimitBeforeEvict) {
1089
1069
  if (typeof msg.content === "string" && msg.content.length > toolTokenLimitBeforeEvict * 4) {
1090
- const resolvedBackend = getBackend(backend, {
1091
- state: request.state || {},
1092
- store: request.runtime?.store
1070
+ const resolvedBackend = await resolveBackend(backend, {
1071
+ ...request.runtime,
1072
+ state: request.state
1093
1073
  });
1094
1074
  const evictPath = `/large_tool_results/${sanitizeToolCallId(request.toolCall?.id || msg.tool_call_id)}`;
1095
1075
  const writeResult = await resolvedBackend.write(evictPath, msg.content);
@@ -1857,19 +1837,12 @@ async function loadMemoryFromBackend(backend, path) {
1857
1837
  */
1858
1838
  function createMemoryMiddleware(options) {
1859
1839
  const { backend, sources, addCacheControl = false } = options;
1860
- /**
1861
- * Resolve backend from instance or factory.
1862
- */
1863
- function getBackend(state) {
1864
- if (typeof backend === "function") return backend({ state });
1865
- return backend;
1866
- }
1867
1840
  return (0, langchain.createMiddleware)({
1868
1841
  name: "MemoryMiddleware",
1869
1842
  stateSchema: MemoryStateSchema,
1870
1843
  async beforeAgent(state) {
1871
1844
  if ("memoryContents" in state && state.memoryContents != null) return;
1872
- const resolvedBackend = getBackend(state);
1845
+ const resolvedBackend = await resolveBackend(backend, { state });
1873
1846
  const contents = {};
1874
1847
  for (const path of sources) try {
1875
1848
  const content = await loadMemoryFromBackend(resolvedBackend, path);
@@ -2271,13 +2244,6 @@ function formatSkillsList(skills, sources) {
2271
2244
  function createSkillsMiddleware(options) {
2272
2245
  const { backend, sources } = options;
2273
2246
  let loadedSkills = [];
2274
- /**
2275
- * Resolve backend from instance or factory.
2276
- */
2277
- function getBackend(state) {
2278
- if (typeof backend === "function") return backend({ state });
2279
- return backend;
2280
- }
2281
2247
  return (0, langchain.createMiddleware)({
2282
2248
  name: "SkillsMiddleware",
2283
2249
  stateSchema: SkillsStateSchema,
@@ -2287,7 +2253,7 @@ function createSkillsMiddleware(options) {
2287
2253
  loadedSkills = state.skillsMetadata;
2288
2254
  return;
2289
2255
  }
2290
- const resolvedBackend = getBackend(state);
2256
+ const resolvedBackend = await resolveBackend(backend, { state });
2291
2257
  const allSkills = /* @__PURE__ */ new Map();
2292
2258
  for (const sourcePath of sources) try {
2293
2259
  const skills = await listSkillsFromBackend(resolvedBackend, sourcePath);
@@ -2511,13 +2477,6 @@ function createSummarizationMiddleware(options) {
2511
2477
  let sessionId = null;
2512
2478
  let tokenEstimationMultiplier = 1;
2513
2479
  /**
2514
- * Resolve backend from instance or factory.
2515
- */
2516
- function getBackend(state) {
2517
- if (typeof backend === "function") return backend({ state });
2518
- return backend;
2519
- }
2520
- /**
2521
2480
  * Get or create session ID for history file naming.
2522
2481
  */
2523
2482
  function getSessionId(state) {
@@ -2883,7 +2842,7 @@ ${summary}
2883
2842
  * the file path, and the state cutoff index.
2884
2843
  */
2885
2844
  async function summarizeMessages(messagesToSummarize, resolvedModel, state, previousCutoffIndex, cutoffIndex) {
2886
- const filePath = await offloadToBackend(getBackend(state), messagesToSummarize, state);
2845
+ const filePath = await offloadToBackend(await resolveBackend(backend, { state }), messagesToSummarize, state);
2887
2846
  if (filePath === null) console.warn(`[SummarizationMiddleware] Backend offload failed during summarization. Proceeding with summary generation.`);
2888
2847
  return {
2889
2848
  summaryMessage: buildSummaryMessage(await createSummary(messagesToSummarize, resolvedModel), filePath),
@@ -4964,9 +4923,9 @@ var LangSmithSandbox = class LangSmithSandbox extends BaseSandbox {
4964
4923
  * ```
4965
4924
  */
4966
4925
  static async create(options = {}) {
4967
- const { templateName = "deepagents", apiKey = process.env.LANGSMITH_API_KEY, defaultTimeout } = options;
4926
+ const { templateName = "deepagents", apiKey = process.env.LANGSMITH_API_KEY, defaultTimeout, ...createSandboxOptions } = options;
4968
4927
  return new LangSmithSandbox({
4969
- sandbox: await new langsmith_experimental_sandbox.SandboxClient({ apiKey }).createSandbox(templateName),
4928
+ sandbox: await new langsmith_experimental_sandbox.SandboxClient({ apiKey }).createSandbox(templateName, createSandboxOptions),
4970
4929
  defaultTimeout
4971
4930
  });
4972
4931
  }
@@ -5125,7 +5084,7 @@ function createDeepAgent(params = {}) {
5125
5084
  * Create backend configuration for filesystem middleware
5126
5085
  * If no backend is provided, use a factory that creates a StateBackend
5127
5086
  */
5128
- const filesystemBackend = backend ? backend : (config) => new StateBackend(config);
5087
+ const filesystemBackend = backend ? backend : (runtime) => new StateBackend(runtime);
5129
5088
  /**
5130
5089
  * Skills middleware (created conditionally for runtime use)
5131
5090
  */
@@ -5793,5 +5752,6 @@ exports.findProjectRoot = findProjectRoot;
5793
5752
  exports.isSandboxBackend = isSandboxBackend;
5794
5753
  exports.listSkills = listSkills;
5795
5754
  exports.parseSkillMetadata = parseSkillMetadata;
5755
+ exports.resolveBackend = resolveBackend;
5796
5756
 
5797
5757
  //# sourceMappingURL=index.cjs.map