deepagents 1.10.5 → 1.10.7

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.
@@ -1,4 +1,4 @@
1
- import { AIMessage, HumanMessage, SystemMessage, ToolMessage, anthropicPromptCachingMiddleware, context, countTokensApproximately, createAgent, createMiddleware, humanInTheLoopMiddleware, todoListMiddleware, tool } from "langchain";
1
+ import { AIMessage, HumanMessage, SystemMessage, ToolMessage, anthropicPromptCachingMiddleware, bedrockPromptCachingMiddleware, context, countTokensApproximately, createAgent, createMiddleware, humanInTheLoopMiddleware, todoListMiddleware, tool } from "langchain";
2
2
  import { Command, REMOVE_ALL_MESSAGES, ReducedValue, StateSchema, getConfig, getCurrentTaskInput, getStore, isCommand } from "@langchain/langgraph";
3
3
  import { z } from "zod/v4";
4
4
  import micromatch from "micromatch";
@@ -400,16 +400,19 @@ function grepMatchesFromFiles(files, pattern, path = null, glob = null) {
400
400
  /**
401
401
  * Determine MIME type from a file path's extension.
402
402
  *
403
- * Returns "application/octet-stream" for unknown extensions so that
404
- * binary files are not accidentally treated as text (grep, read_file,
405
- * etc. rely on {@link isTextMimeType} which would return true for
406
- * "text/plain").
403
+ * Defaults to "text/plain" for unknown extensions. Only the known non-text
404
+ * formats above (images, audio, video, PDF/PPT) are treated as binary by
405
+ * {@link isTextMimeType}; everything else reads as text, including source files
406
+ * with uncommon extensions (.properties, .scss, .tf) and extension-less files
407
+ * (Dockerfile, mvnw). This avoids base64-encoding text into document blocks,
408
+ * which the model can't read and which the Anthropic provider rejects with a
409
+ * 400.
407
410
  *
408
411
  * @param filePath - File path to inspect
409
- * @returns MIME type string (e.g., "image/png", "application/octet-stream")
412
+ * @returns MIME type string (e.g., "image/png", "text/plain")
410
413
  */
411
414
  function getMimeType(filePath) {
412
- return MIME_TYPES[extname(filePath).toLocaleLowerCase()] || "application/octet-stream";
415
+ return MIME_TYPES[extname(filePath).toLocaleLowerCase()] || "text/plain";
413
416
  }
414
417
  /**
415
418
  * Check whether a MIME type represents text content.
@@ -1245,6 +1248,22 @@ var CompositeBackend = class {
1245
1248
  */
1246
1249
  const INT_FORMATTER = new Intl.NumberFormat("en-US");
1247
1250
  /**
1251
+ * Normalizes tool input so that models sending `path` instead of `file_path`
1252
+ * still work. If the input has `path` but not `file_path`, copies `path` into
1253
+ * `file_path`. This makes the filesystem tools resilient to parameter-name
1254
+ * variations across models of different capability levels.
1255
+ */
1256
+ function normalizeFilePathInput(input) {
1257
+ if (typeof input === "object" && input !== null && "path" in input && !("file_path" in input)) {
1258
+ const { path, ...rest } = input;
1259
+ return {
1260
+ ...rest,
1261
+ file_path: path
1262
+ };
1263
+ }
1264
+ return input;
1265
+ }
1266
+ /**
1248
1267
  * Tools that should be excluded from the large result eviction logic.
1249
1268
  *
1250
1269
  * This array contains tools that should NOT have their results evicted to the filesystem
@@ -1521,10 +1540,10 @@ const READ_FILE_TOOL_DESCRIPTION = context`
1521
1540
  Usage:
1522
1541
  - By default, it reads up to ${100} lines starting from the beginning of the file
1523
1542
  - **IMPORTANT for large files and codebase exploration**: Use pagination with offset and limit parameters to avoid context overflow
1524
- - First scan: read_file(path, limit=${100}) to see file structure
1525
- - Read more sections: read_file(path, offset=${100}, limit=200) for next 200 lines
1543
+ - First scan: read_file(file_path, limit=${100}) to see file structure
1544
+ - Read more sections: read_file(file_path, offset=${100}, limit=200) for next 200 lines
1526
1545
  - Only omit limit (read full file) when necessary for editing
1527
- - Specify offset and limit: read_file(path, offset=0, limit=${100}) reads first ${100} lines
1546
+ - Specify offset and limit: read_file(file_path, offset=0, limit=${100}) reads first ${100} lines
1528
1547
  - Results are returned using cat -n format, with line numbers starting at 1
1529
1548
  - Lines longer than ${INT_FORMATTER.format(MAX_LINE_LENGTH)} characters will be split into multiple lines with continuation markers (e.g., 5.1, 5.2, etc.). When you specify a limit, these continuation lines count towards the limit.
1530
1549
  - You have the capability to call multiple tools in a single response. It is always better to speculatively read multiple files as a batch that are potentially useful.
@@ -1722,11 +1741,11 @@ function createReadFileTool(backend, options) {
1722
1741
  }, {
1723
1742
  name: "read_file",
1724
1743
  description: customDescription || READ_FILE_TOOL_DESCRIPTION,
1725
- schema: z.object({
1744
+ schema: z.preprocess(normalizeFilePathInput, z.object({
1726
1745
  file_path: z.string().describe("Absolute path to the file to read"),
1727
1746
  offset: z.coerce.number().optional().default(0).describe("Line offset to start reading from (0-indexed)"),
1728
1747
  limit: z.coerce.number().optional().default(100).describe("Maximum number of lines to read")
1729
- })
1748
+ }))
1730
1749
  });
1731
1750
  }
1732
1751
  /**
@@ -1754,10 +1773,10 @@ function createWriteFileTool(backend, options) {
1754
1773
  }, {
1755
1774
  name: "write_file",
1756
1775
  description: customDescription || WRITE_FILE_TOOL_DESCRIPTION,
1757
- schema: z.object({
1776
+ schema: z.preprocess(normalizeFilePathInput, z.object({
1758
1777
  file_path: z.string().describe("Absolute path to the file to write"),
1759
1778
  content: z.string().default("").describe("Content to write to the file")
1760
- })
1779
+ }))
1761
1780
  });
1762
1781
  }
1763
1782
  /**
@@ -1785,12 +1804,12 @@ function createEditFileTool(backend, options) {
1785
1804
  }, {
1786
1805
  name: "edit_file",
1787
1806
  description: customDescription || EDIT_FILE_TOOL_DESCRIPTION,
1788
- schema: z.object({
1807
+ schema: z.preprocess(normalizeFilePathInput, z.object({
1789
1808
  file_path: z.string().describe("Absolute path to the file to edit"),
1790
1809
  old_string: z.string().describe("String to be replaced (must match exactly)"),
1791
1810
  new_string: z.string().describe("String to replace with"),
1792
1811
  replace_all: z.boolean().optional().default(false).describe("Whether to replace all occurrences")
1793
- })
1812
+ }))
1794
1813
  });
1795
1814
  }
1796
1815
  /**
@@ -2312,11 +2331,16 @@ function returnCommandWithStateUpdate(result, toolCallId) {
2312
2331
  let content;
2313
2332
  if (result.structuredResponse != null) content = JSON.stringify(result.structuredResponse);
2314
2333
  else {
2315
- const messages = result.messages;
2316
- content = (messages?.[messages.length - 1])?.content || "Task completed";
2317
- if (Array.isArray(content)) {
2318
- content = content.filter((block) => !INVALID_TOOL_MESSAGE_BLOCK_TYPES.includes(block.type));
2319
- if (content.length === 0) content = "Task completed";
2334
+ const messages = result.messages ?? [];
2335
+ content = "Task completed";
2336
+ for (let i = messages.length - 1; i >= 0; i -= 1) {
2337
+ const message = messages[i];
2338
+ if (!message || !AIMessage$1.isInstance(message)) continue;
2339
+ const text = typeof message.content === "string" ? message.content.trim() : message.text?.trim() ?? "";
2340
+ if (text) {
2341
+ content = text;
2342
+ break;
2343
+ }
2320
2344
  }
2321
2345
  }
2322
2346
  return new Command({ update: {
@@ -2678,6 +2702,30 @@ function isAnthropicModel(model) {
2678
2702
  return model.getName() === "ChatAnthropic";
2679
2703
  }
2680
2704
  /**
2705
+ * Detect whether a model is an AWS Bedrock Converse model.
2706
+ *
2707
+ * Accepts the wider `RunnableInterface` shape (the type of `request.model`
2708
+ * inside `wrapModelCall`, aliased as `AgentLanguageModelLike` in langchain)
2709
+ * because the function only depends on `.getName()`, which is part of the
2710
+ * Runnable contract. `BaseLanguageModel` extends `Runnable`, so existing
2711
+ * call sites still type-check.
2712
+ */
2713
+ function isBedrockConverseModel(model) {
2714
+ if (typeof model === "string") {
2715
+ const colonIdx = model.indexOf(":");
2716
+ if (colonIdx !== -1) {
2717
+ const prefix = model.slice(0, colonIdx);
2718
+ if (prefix === "bedrock" || prefix === "aws") return true;
2719
+ }
2720
+ return model.startsWith("amazon.");
2721
+ }
2722
+ if (model.getName() === "ConfigurableModel") {
2723
+ const provider = model._defaultConfig?.modelProvider;
2724
+ return provider === "bedrock" || provider === "aws";
2725
+ }
2726
+ return model.getName() === "ChatBedrockConverse";
2727
+ }
2728
+ /**
2681
2729
  * Extract the provider name from a model instance for profile lookup.
2682
2730
  *
2683
2731
  * Checks `_defaultConfig.modelProvider` (ConfigurableModel) and falls
@@ -3066,7 +3114,7 @@ const SKILLS_SYSTEM_PROMPT = context`
3066
3114
  User: "Can you research the latest developments in quantum computing?"
3067
3115
 
3068
3116
  1. Check available skills above → See "web-research" skill with its full path
3069
- 2. Read the full skill file: \`read_file(path, limit=${DEFAULT_SKILL_READ_LINE_LIMIT})\`
3117
+ 2. Read the full skill file: \`read_file(file_path, limit=${DEFAULT_SKILL_READ_LINE_LIMIT})\`
3070
3118
  3. Follow the skill's research workflow (search → organize → synthesize)
3071
3119
  4. Use any helper scripts with absolute paths
3072
3120
 
@@ -5751,10 +5799,17 @@ function createDeepAgent(params = {}) {
5751
5799
  const toolOverrides = harnessProfile.toolDescriptionOverrides;
5752
5800
  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;
5753
5801
  const anthropicModel = isAnthropicModel(model);
5754
- const cacheMiddleware = anthropicModel ? [anthropicPromptCachingMiddleware({
5755
- unsupportedModelBehavior: "ignore",
5756
- minMessagesToCache: 1
5757
- }), createCacheBreakpointMiddleware()] : [];
5802
+ const bedrockModel = isBedrockConverseModel(model);
5803
+ let cacheMiddleware = [];
5804
+ if (anthropicModel) cacheMiddleware = [
5805
+ ...cacheMiddleware,
5806
+ anthropicPromptCachingMiddleware({
5807
+ unsupportedModelBehavior: "ignore",
5808
+ minMessagesToCache: 1
5809
+ }),
5810
+ createCacheBreakpointMiddleware()
5811
+ ];
5812
+ if (bedrockModel) cacheMiddleware = [...cacheMiddleware, bedrockPromptCachingMiddleware({ unsupportedModelBehavior: "ignore" })];
5758
5813
  /**
5759
5814
  * Process subagents to add SkillsMiddleware for those with their own skills.
5760
5815
  *
@@ -7318,4 +7373,4 @@ var LangSmithSandbox = class LangSmithSandbox extends BaseSandbox {
7318
7373
  //#endregion
7319
7374
  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 };
7320
7375
 
7321
- //# sourceMappingURL=langsmith-wdF8zG42.js.map
7376
+ //# sourceMappingURL=langsmith-DjCMSywL.js.map