deepagents 1.13.4 → 1.13.5

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/browser.cjs CHANGED
@@ -1,5 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_langsmith = require("./langsmith-yA3yhBRa.cjs");
2
+ const require_langsmith = require("./langsmith-CG8px69t.cjs");
3
3
  exports.ASYNC_TASK_SYSTEM_PROMPT = require_langsmith.ASYNC_TASK_SYSTEM_PROMPT;
4
4
  exports.BASE_AGENT_PROMPT = require_langsmith.BASE_AGENT_PROMPT;
5
5
  exports.BaseSandbox = require_langsmith.BaseSandbox;
package/dist/browser.js CHANGED
@@ -1,2 +1,2 @@
1
- import { A as DEFAULT_GENERAL_PURPOSE_DESCRIPTION, B as StateBackend, C as MAX_SKILL_DESCRIPTION_LENGTH, D as createMemoryMiddleware, E as createSkillsMiddleware, F as createSubAgentMiddleware, G as resolveBackend, I as computeSummarizationDefaults, K as adaptBackendProtocol, L as createSummarizationMiddleware, M as GENERAL_PURPOSE_SUBAGENT, O as filesValue, R as createFilesystemMiddleware, S as createCompletionCallbackMiddleware, T as MAX_SKILL_NAME_LENGTH, U as isSandboxBackend, V as SandboxError, W as isSandboxProtocol, _ as createHarnessProfile, a as ASYNC_TASK_SYSTEM_PROMPT, b as createAsyncSubAgentMiddleware, c as TASK_SYSTEM_PROMPT, d as registerHarnessProfile, f as generalPurposeSubagentConfigSchema, g as EMPTY_HARNESS_PROFILE, h as serializeProfile, i as StoreBackend, j as DEFAULT_SUBAGENT_PROMPT, k as createPatchToolCallsMiddleware, l as createDeepAgent, m as parseHarnessProfileConfig, n as BaseSandbox, o as BASE_AGENT_PROMPT, p as harnessProfileConfigSchema, q as adaptSandboxProtocol, r as ContextHubBackend, s as EXECUTION_SYSTEM_PROMPT, t as LangSmithSandbox, u as getHarnessProfile, v as REQUIRED_MIDDLEWARE_NAMES, w as MAX_SKILL_FILE_SIZE, x as isAsyncSubAgent, y as ConfigurationError, z as CompositeBackend } from "./langsmith-BAO_h4J6.js";
1
+ import { A as DEFAULT_GENERAL_PURPOSE_DESCRIPTION, B as StateBackend, C as MAX_SKILL_DESCRIPTION_LENGTH, D as createMemoryMiddleware, E as createSkillsMiddleware, F as createSubAgentMiddleware, G as resolveBackend, I as computeSummarizationDefaults, K as adaptBackendProtocol, L as createSummarizationMiddleware, M as GENERAL_PURPOSE_SUBAGENT, O as filesValue, R as createFilesystemMiddleware, S as createCompletionCallbackMiddleware, T as MAX_SKILL_NAME_LENGTH, U as isSandboxBackend, V as SandboxError, W as isSandboxProtocol, _ as createHarnessProfile, a as ASYNC_TASK_SYSTEM_PROMPT, b as createAsyncSubAgentMiddleware, c as TASK_SYSTEM_PROMPT, d as registerHarnessProfile, f as generalPurposeSubagentConfigSchema, g as EMPTY_HARNESS_PROFILE, h as serializeProfile, i as StoreBackend, j as DEFAULT_SUBAGENT_PROMPT, k as createPatchToolCallsMiddleware, l as createDeepAgent, m as parseHarnessProfileConfig, n as BaseSandbox, o as BASE_AGENT_PROMPT, p as harnessProfileConfigSchema, q as adaptSandboxProtocol, r as ContextHubBackend, s as EXECUTION_SYSTEM_PROMPT, t as LangSmithSandbox, u as getHarnessProfile, v as REQUIRED_MIDDLEWARE_NAMES, w as MAX_SKILL_FILE_SIZE, x as isAsyncSubAgent, y as ConfigurationError, z as CompositeBackend } from "./langsmith-CY7MawjU.js";
2
2
  export { ASYNC_TASK_SYSTEM_PROMPT, BASE_AGENT_PROMPT, BaseSandbox, CompositeBackend, ConfigurationError, ContextHubBackend, DEFAULT_GENERAL_PURPOSE_DESCRIPTION, DEFAULT_SUBAGENT_PROMPT, EMPTY_HARNESS_PROFILE, EXECUTION_SYSTEM_PROMPT, GENERAL_PURPOSE_SUBAGENT, LangSmithSandbox, MAX_SKILL_DESCRIPTION_LENGTH, MAX_SKILL_FILE_SIZE, MAX_SKILL_NAME_LENGTH, REQUIRED_MIDDLEWARE_NAMES, SandboxError, StateBackend, StoreBackend, TASK_SYSTEM_PROMPT, adaptBackendProtocol, adaptSandboxProtocol, computeSummarizationDefaults, createAsyncSubAgentMiddleware, createCompletionCallbackMiddleware, createDeepAgent, createFilesystemMiddleware, createHarnessProfile, createMemoryMiddleware, createPatchToolCallsMiddleware, createSkillsMiddleware, createSubAgentMiddleware, createSummarizationMiddleware, filesValue, generalPurposeSubagentConfigSchema, getHarnessProfile, harnessProfileConfigSchema, isAsyncSubAgent, isSandboxBackend, isSandboxProtocol, parseHarnessProfileConfig, registerHarnessProfile, resolveBackend, serializeProfile };
package/dist/index.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_langsmith = require("./langsmith-yA3yhBRa.cjs");
3
- const require_src = require("./src-D_XxmEak.cjs");
2
+ const require_langsmith = require("./langsmith-CG8px69t.cjs");
3
+ const require_src = require("./src-C2ZohcHT.cjs");
4
4
  exports.ASYNC_TASK_SYSTEM_PROMPT = require_langsmith.ASYNC_TASK_SYSTEM_PROMPT;
5
5
  exports.BASE_AGENT_PROMPT = require_langsmith.BASE_AGENT_PROMPT;
6
6
  exports.BaseSandbox = require_langsmith.BaseSandbox;
package/dist/index.js CHANGED
@@ -1,3 +1,3 @@
1
- import { A as DEFAULT_GENERAL_PURPOSE_DESCRIPTION, B as StateBackend, C as MAX_SKILL_DESCRIPTION_LENGTH, D as createMemoryMiddleware, E as createSkillsMiddleware, F as createSubAgentMiddleware, G as resolveBackend, H as applyGrepMaxCount, I as computeSummarizationDefaults, K as adaptBackendProtocol, L as createSummarizationMiddleware, M as GENERAL_PURPOSE_SUBAGENT, N as SUBAGENT_RESPONSE_FORMAT_CONFIG_KEY, O as filesValue, P as createSubAgent, R as createFilesystemMiddleware, S as createCompletionCallbackMiddleware, T as MAX_SKILL_NAME_LENGTH, U as isSandboxBackend, V as SandboxError, W as isSandboxProtocol, Z as normalizeReadPagination, _ as createHarnessProfile, a as ASYNC_TASK_SYSTEM_PROMPT, b as createAsyncSubAgentMiddleware, c as TASK_SYSTEM_PROMPT, d as registerHarnessProfile, f as generalPurposeSubagentConfigSchema, g as EMPTY_HARNESS_PROFILE, h as serializeProfile, i as StoreBackend, j as DEFAULT_SUBAGENT_PROMPT, k as createPatchToolCallsMiddleware, l as createDeepAgent, m as parseHarnessProfileConfig, n as BaseSandbox, o as BASE_AGENT_PROMPT, p as harnessProfileConfigSchema, q as adaptSandboxProtocol, r as ContextHubBackend, s as EXECUTION_SYSTEM_PROMPT, t as LangSmithSandbox, u as getHarnessProfile, v as REQUIRED_MIDDLEWARE_NAMES, w as MAX_SKILL_FILE_SIZE, x as isAsyncSubAgent, y as ConfigurationError, z as CompositeBackend } from "./langsmith-BAO_h4J6.js";
2
- import { a as createAgentMemoryMiddleware, i as parseSkillMetadata, n as FilesystemBackend, o as createSettings, r as listSkills, s as findProjectRoot, t as LocalShellBackend } from "./src-CcY34Ckx.js";
1
+ import { A as DEFAULT_GENERAL_PURPOSE_DESCRIPTION, B as StateBackend, C as MAX_SKILL_DESCRIPTION_LENGTH, D as createMemoryMiddleware, E as createSkillsMiddleware, F as createSubAgentMiddleware, G as resolveBackend, H as applyGrepMaxCount, I as computeSummarizationDefaults, K as adaptBackendProtocol, L as createSummarizationMiddleware, M as GENERAL_PURPOSE_SUBAGENT, N as SUBAGENT_RESPONSE_FORMAT_CONFIG_KEY, O as filesValue, P as createSubAgent, R as createFilesystemMiddleware, S as createCompletionCallbackMiddleware, T as MAX_SKILL_NAME_LENGTH, U as isSandboxBackend, V as SandboxError, W as isSandboxProtocol, Z as normalizeReadPagination, _ as createHarnessProfile, a as ASYNC_TASK_SYSTEM_PROMPT, b as createAsyncSubAgentMiddleware, c as TASK_SYSTEM_PROMPT, d as registerHarnessProfile, f as generalPurposeSubagentConfigSchema, g as EMPTY_HARNESS_PROFILE, h as serializeProfile, i as StoreBackend, j as DEFAULT_SUBAGENT_PROMPT, k as createPatchToolCallsMiddleware, l as createDeepAgent, m as parseHarnessProfileConfig, n as BaseSandbox, o as BASE_AGENT_PROMPT, p as harnessProfileConfigSchema, q as adaptSandboxProtocol, r as ContextHubBackend, s as EXECUTION_SYSTEM_PROMPT, t as LangSmithSandbox, u as getHarnessProfile, v as REQUIRED_MIDDLEWARE_NAMES, w as MAX_SKILL_FILE_SIZE, x as isAsyncSubAgent, y as ConfigurationError, z as CompositeBackend } from "./langsmith-CY7MawjU.js";
2
+ import { a as createAgentMemoryMiddleware, i as parseSkillMetadata, n as FilesystemBackend, o as createSettings, r as listSkills, s as findProjectRoot, t as LocalShellBackend } from "./src-Bos_UCsK.js";
3
3
  export { ASYNC_TASK_SYSTEM_PROMPT, BASE_AGENT_PROMPT, BaseSandbox, CompositeBackend, ConfigurationError, ContextHubBackend, DEFAULT_GENERAL_PURPOSE_DESCRIPTION, DEFAULT_SUBAGENT_PROMPT, EMPTY_HARNESS_PROFILE, EXECUTION_SYSTEM_PROMPT, FilesystemBackend, GENERAL_PURPOSE_SUBAGENT, LangSmithSandbox, LocalShellBackend, MAX_SKILL_DESCRIPTION_LENGTH, MAX_SKILL_FILE_SIZE, MAX_SKILL_NAME_LENGTH, REQUIRED_MIDDLEWARE_NAMES, SUBAGENT_RESPONSE_FORMAT_CONFIG_KEY, SandboxError, StateBackend, StoreBackend, TASK_SYSTEM_PROMPT, adaptBackendProtocol, adaptSandboxProtocol, applyGrepMaxCount, computeSummarizationDefaults, createAgentMemoryMiddleware, createAsyncSubAgentMiddleware, createCompletionCallbackMiddleware, createDeepAgent, createFilesystemMiddleware, createHarnessProfile, createMemoryMiddleware, createPatchToolCallsMiddleware, createSettings, createSkillsMiddleware, createSubAgent, createSubAgentMiddleware, createSummarizationMiddleware, filesValue, findProjectRoot, generalPurposeSubagentConfigSchema, getHarnessProfile, harnessProfileConfigSchema, isAsyncSubAgent, isSandboxBackend, isSandboxProtocol, listSkills, normalizeReadPagination, parseHarnessProfileConfig, parseSkillMetadata, registerHarnessProfile, resolveBackend, serializeProfile };
@@ -230,6 +230,21 @@ function formatContentWithLineNumbers(content, startLine = 1) {
230
230
  return formatContentWithLineNumbersAndBoundaries(content, startLine).text;
231
231
  }
232
232
  /**
233
+ * Join file content into the unmodified source body of a `read_file` result.
234
+ *
235
+ * Source lines are emitted unchanged, with no numbering. A status header
236
+ * carries the line-range metadata separately, so nothing here needs to
237
+ * encode line numbers or escape anything.
238
+ */
239
+ function formatSourceBlock(content) {
240
+ let lines;
241
+ if (typeof content === "string") {
242
+ lines = content.split("\n");
243
+ if (lines.length > 0 && lines[lines.length - 1] === "") lines = lines.slice(0, -1);
244
+ } else lines = content;
245
+ return lines.join("\n");
246
+ }
247
+ /**
233
248
  * Check if content is empty and return warning message.
234
249
  *
235
250
  * @param content - Content to check
@@ -1563,7 +1578,6 @@ var CompositeBackend = class {
1563
1578
  * - Pluggable backends (StateBackend, StoreBackend, FilesystemBackend, CompositeBackend)
1564
1579
  * - Tool result eviction for large outputs
1565
1580
  */
1566
- const INT_FORMATTER = new Intl.NumberFormat("en-US");
1567
1581
  /**
1568
1582
  * Normalizes tool input so that models sending `path` instead of `file_path`
1569
1583
  * still work. If the input has `path` but not `file_path`, copies `path` into
@@ -1633,29 +1647,100 @@ const READ_FILE_TRUNCATION_MSG = `
1633
1647
 
1634
1648
  [Output was truncated due to size limits. The file content is very large. Consider reformatting the file to make it easier to navigate. For example, if this is JSON, use execute(command='jq . {file_path}') to pretty-print it with line breaks. For other formats, you can use appropriate formatting tools to split long lines.]`;
1635
1649
  /**
1636
- * Render backend pagination metadata as guidance for the model.
1650
+ * Describe the window a read returned, as status header fields.
1637
1651
  *
1638
1652
  * Backends own source-level pagination because only they know how much of the
1639
- * file was read. The middleware owns presentation: it line-numbers the text
1640
- * and turns optional metadata into a human-readable footer. Keeping the fields
1641
- * optional preserves compatibility with custom backends that predate this
1642
- * contract; those reads simply receive no pagination footer.
1653
+ * file was read. The middleware owns presentation: it renders the source
1654
+ * unmodified and turns optional metadata into a terse header. Keeping the
1655
+ * fields optional preserves compatibility with custom backends that predate
1656
+ * this contract — `prepareReadWindow` derives a range for those instead.
1643
1657
  *
1644
- * `nextOffset` is the signal that the read is partial. A result at EOF omits it,
1645
- * so complete reads retain their previous output shape.
1658
+ * Returns the `lines A-B[ of T]` field, followed by `next offset N` when the
1659
+ * window stopped short of the end of the file.
1646
1660
  */
1647
- function remainingLinesNotice(readResult) {
1661
+ function describeReadWindow(readResult) {
1648
1662
  const { startLine, endLine, nextOffset, totalLines } = readResult;
1649
- if (startLine === void 0 || endLine === void 0 || nextOffset === void 0 || !Number.isSafeInteger(startLine) || !Number.isSafeInteger(endLine) || !Number.isSafeInteger(nextOffset) || startLine < 1 || endLine < startLine || nextOffset !== endLine || totalLines !== void 0 && (!Number.isSafeInteger(totalLines) || totalLines < endLine)) return "";
1650
- const readCount = endLine - startLine + 1;
1651
- const readUnit = readCount === 1 ? "line" : "lines";
1652
- if (totalLines === void 0) return `\n\n[Read ${readCount} ${readUnit} (lines ${startLine}-${endLine}). More lines remain from offset ${nextOffset}.]`;
1653
- if (endLine >= totalLines) return "";
1654
- const remaining = totalLines - endLine;
1655
- return `\n\n[Read ${readCount} ${readUnit} (lines ${startLine}-${endLine} of ${totalLines} total). ${remaining} ${remaining === 1 ? "line" : "lines"} remaining from offset ${nextOffset}.]`;
1663
+ if (startLine === void 0 || endLine === void 0 || !Number.isSafeInteger(startLine) || !Number.isSafeInteger(endLine) || startLine < 1 || endLine < startLine || totalLines !== void 0 && (!Number.isSafeInteger(totalLines) || totalLines < endLine)) return [];
1664
+ let span = `lines ${startLine}-${endLine}`;
1665
+ if (totalLines !== void 0) span += ` of ${totalLines}`;
1666
+ const fields = [span];
1667
+ if (nextOffset !== void 0 && (totalLines === void 0 || endLine < totalLines)) fields.push(`next offset ${nextOffset}`);
1668
+ return fields;
1669
+ }
1670
+ /** Render the status header that sits above a text `read_file` result. */
1671
+ function readHeader(fields) {
1672
+ return `@@ ${fields.join(" | ")} @@`;
1673
+ }
1674
+ /** Notice disclosing that a negative `offset` was reinterpreted as the start of the file, or `undefined` for a non-negative offset. */
1675
+ function clampedOffsetNotice(offset) {
1676
+ if (offset >= 0) return;
1677
+ return `[Requested offset ${offset} is before the start of the file; read from line 1 instead.]`;
1678
+ }
1679
+ /**
1680
+ * Compose a read result from its notices, status header, and source body.
1681
+ *
1682
+ * Notices sit above the header, so every line below it is unmodified file
1683
+ * content and consumers (including `stripLineNumbers` in the quickjs
1684
+ * provider) can tell the two apart by position.
1685
+ */
1686
+ function assembleRead(body, options) {
1687
+ const { fields, notices = [] } = options;
1688
+ return [
1689
+ ...notices,
1690
+ readHeader(fields),
1691
+ body
1692
+ ].join("\n");
1693
+ }
1694
+ /** Derives a header range from `offset` when the backend left `startLine`/`endLine` unset. */
1695
+ function prepareReadWindow(readResult, content, offset) {
1696
+ const body = formatSourceBlock(content);
1697
+ if (readResult.startLine !== void 0 && readResult.endLine !== void 0) return {
1698
+ readResult,
1699
+ body
1700
+ };
1701
+ const startLine = offset + 1;
1702
+ const endLine = startLine + body.split("\n").length - 1;
1703
+ return {
1704
+ readResult: {
1705
+ ...readResult,
1706
+ startLine,
1707
+ endLine
1708
+ },
1709
+ body
1710
+ };
1711
+ }
1712
+ /**
1713
+ * Assemble a read cut inside a single source line too long to fit.
1714
+ *
1715
+ * No offset reaches the remainder of such a line, so the header reports how
1716
+ * much of it is shown in place of a resume point.
1717
+ */
1718
+ function midlineTruncatedRead(body, readResult, threshold, notices) {
1719
+ const newlineIdx = body.indexOf("\n");
1720
+ const oversized = newlineIdx === -1 ? body.length : newlineIdx;
1721
+ const clipped = {
1722
+ totalLines: readResult.totalLines,
1723
+ startLine: readResult.startLine,
1724
+ endLine: readResult.startLine,
1725
+ nextOffset: void 0
1726
+ };
1727
+ const fieldsFor = (shown) => [
1728
+ ...describeReadWindow(clipped),
1729
+ "truncated mid-line",
1730
+ `${shown} of ${oversized} chars`
1731
+ ];
1732
+ const reserved = assembleRead("", {
1733
+ fields: fieldsFor(oversized),
1734
+ notices
1735
+ }).length;
1736
+ const shown = Math.max(0, Math.min(oversized, threshold - reserved));
1737
+ return assembleRead(body.slice(0, shown), {
1738
+ fields: fieldsFor(shown),
1739
+ notices
1740
+ });
1656
1741
  }
1657
1742
  /**
1658
- * Fit a line-numbered read into the middleware's output budget without
1743
+ * Fit a paginated read into the middleware's output budget without
1659
1744
  * publishing a resume offset that skips content the model did not see.
1660
1745
  *
1661
1746
  * There are two independent forms of limiting:
@@ -1666,38 +1751,50 @@ function remainingLinesNotice(readResult) {
1666
1751
  * If the backend returned lines 1-100 but the middleware only displayed lines
1667
1752
  * 1-30, forwarding the backend's original `nextOffset: 100` would silently skip
1668
1753
  * lines 31-100 on the next read. This function therefore truncates only after a
1669
- * complete source line and rebuilds the remaining-lines notice using the last
1670
- * line actually displayed.
1671
- *
1672
- * Long source lines may occupy several formatted rows (`12`, `12.1`, ...). The
1673
- * formatter records a structured boundary only after the final chunk, so this
1674
- * function does not need to inspect or understand the gutter representation.
1675
- * If no complete source line can fit beside the truncation message, the function
1676
- * falls back to character truncation and omits pagination guidance rather than
1677
- * advertising an unsafe offset.
1678
- */
1679
- function truncatePaginatedRead(formatted, filePath, readResult, tokenLimit) {
1680
- const content = formatted.text;
1681
- const notice = remainingLinesNotice(readResult);
1682
- if (!tokenLimit || content.length + notice.length < 4 * tokenLimit) return content + notice;
1683
- const truncationMsg = READ_FILE_TRUNCATION_MSG.replace("{file_path}", filePath);
1754
+ * complete source line and rebuilds the header from the last line actually
1755
+ * displayed. If no complete source line fits alongside the truncation
1756
+ * message, it falls back to `midlineTruncatedRead`, which reports exactly how
1757
+ * much of the oversized line is shown rather than guessing at a resume point.
1758
+ */
1759
+ function truncatePaginatedRead(body, readResult, options) {
1760
+ const { filePath, tokenLimit, notices = [] } = options;
1761
+ const result = assembleRead(body, {
1762
+ fields: describeReadWindow(readResult),
1763
+ notices
1764
+ });
1765
+ if (!tokenLimit || result.length < 4 * tokenLimit) return result;
1766
+ const truncationMsg = READ_FILE_TRUNCATION_MSG.replace("{file_path}", filePath).trim();
1684
1767
  const threshold = 4 * tokenLimit;
1685
1768
  if (readResult.startLine !== void 0 && readResult.endLine !== void 0) {
1686
- const finalSourceLine = readResult.endLine;
1687
- const boundaries = formatted.sourceLineBoundaries.filter((boundary) => boundary.sourceLine <= finalSourceLine);
1769
+ const rows = body.split("\n");
1770
+ let position = 0;
1771
+ const boundaries = [];
1772
+ for (let index = 0; index < rows.length; index += 1) {
1773
+ const sourceLine = readResult.startLine + index;
1774
+ if (sourceLine > readResult.endLine) break;
1775
+ position += rows[index].length;
1776
+ boundaries.push({
1777
+ endOffset: position,
1778
+ endLine: sourceLine
1779
+ });
1780
+ position += 1;
1781
+ }
1688
1782
  for (let index = boundaries.length - 1; index >= 0; index -= 1) {
1689
- const boundary = boundaries[index];
1690
- const adjustedNotice = remainingLinesNotice({
1783
+ const { endOffset, endLine } = boundaries[index];
1784
+ const adjustedResult = {
1691
1785
  totalLines: readResult.totalLines,
1692
1786
  startLine: readResult.startLine,
1693
- endLine: boundary.sourceLine,
1694
- nextOffset: boundary.sourceLine
1787
+ endLine,
1788
+ nextOffset: endLine
1789
+ };
1790
+ const candidate = assembleRead(body.slice(0, endOffset), {
1791
+ fields: [...describeReadWindow(adjustedResult), "truncated due to size"],
1792
+ notices: [...notices, truncationMsg]
1695
1793
  });
1696
- if (boundary.endOffset + truncationMsg.length + adjustedNotice.length <= threshold) return content.slice(0, boundary.endOffset) + truncationMsg + adjustedNotice;
1794
+ if (candidate.length <= threshold) return candidate;
1697
1795
  }
1698
1796
  }
1699
- const maxContentLength = Math.max(0, threshold - truncationMsg.length);
1700
- return content.substring(0, maxContentLength) + truncationMsg;
1797
+ return midlineTruncatedRead(body, readResult, threshold, [...notices, truncationMsg]);
1701
1798
  }
1702
1799
  /**
1703
1800
  * Note appended to grep results that were cut short by the match-count cap.
@@ -2093,8 +2190,7 @@ const READ_FILE_TOOL_DESCRIPTION = langchain.context`
2093
2190
 
2094
2191
  Usage:
2095
2192
  - By default, it reads up to ${100} lines starting from the beginning of the file. Use \`offset\`/\`limit\` to page through large files instead of reading them whole.
2096
- - Results are returned with line numbers starting at \`offset\` + 1 (1 by default), then two spaces, then the source line. Never include these line-number prefixes when editing.
2097
- - Lines over ${INT_FORMATTER.format(MAX_LINE_LENGTH)} characters are split with continuation markers (e.g. 5.1, 5.2); \`limit\` counts source lines, so continuation rows do not consume the budget.
2193
+ - A status header, \`@@ field | field | ... @@\`, sits above the file content, and every line after it is unmodified file content. When content is truncated, there may be an explanation before the header. Never include the header when editing.
2098
2194
  - Speculatively batch multiple \`read_file\` calls in one response when several files may be useful.
2099
2195
  - An empty file returns a system-reminder warning in place of contents.
2100
2196
  - Large tool results may be offloaded to a file; the tool message gives the path. Read that path here, paging with \`offset\`/\`limit\`.
@@ -2114,7 +2210,7 @@ const EDIT_FILE_TOOL_DESCRIPTION = langchain.context`
2114
2210
 
2115
2211
  Usage:
2116
2212
  - You must read the file before editing; this tool errors otherwise.
2117
- - Preserve the exact indentation from the read output, and never include line-number prefixes in old_string or new_string.
2213
+ - Preserve the exact source indentation from the read output, and never include the read status header in old_string or new_string.
2118
2214
  - Prefer editing an existing file over creating a new one.
2119
2215
  - Only use emojis if the user explicitly requests it.
2120
2216
  `;
@@ -2249,6 +2345,10 @@ function createReadFileTool(backend, options) {
2249
2345
  }];
2250
2346
  }
2251
2347
  let content = typeof readResult.content === "string" ? readResult.content : "";
2348
+ if (content === "System reminder: File exists but has empty contents") return [{
2349
+ type: "text",
2350
+ text: content
2351
+ }];
2252
2352
  const lines = content.split("\n");
2253
2353
  let paginationResult = readResult;
2254
2354
  if (lines.length > limit) {
@@ -2262,9 +2362,15 @@ function createReadFileTool(backend, options) {
2262
2362
  };
2263
2363
  }
2264
2364
  }
2365
+ const { readResult: preparedResult, body } = prepareReadWindow(paginationResult, content, offset);
2366
+ const clampNotice = clampedOffsetNotice(requestedOffset);
2265
2367
  return [{
2266
2368
  type: "text",
2267
- text: truncatePaginatedRead(formatContentWithLineNumbersAndBoundaries(content, paginationResult.startLine ?? offset + 1), file_path, paginationResult, toolTokenLimitBeforeEvict)
2369
+ text: truncatePaginatedRead(body, preparedResult, {
2370
+ filePath: file_path,
2371
+ tokenLimit: toolTokenLimitBeforeEvict,
2372
+ notices: clampNotice ? [clampNotice] : []
2373
+ })
2268
2374
  }];
2269
2375
  }, {
2270
2376
  name: "read_file",
@@ -4851,17 +4957,11 @@ function validateModulePath(raw) {
4851
4957
  */
4852
4958
  function createSkillsMiddleware(options) {
4853
4959
  const { backend, sources } = options;
4854
- let loadedSkills = [];
4855
4960
  return (0, langchain.createMiddleware)({
4856
4961
  name: "SkillsMiddleware",
4857
4962
  stateSchema: SkillsStateSchema,
4858
4963
  async beforeAgent(state) {
4859
- const stateHasSkills = "skillsMetadata" in state && Array.isArray(state.skillsMetadata) && state.skillsMetadata.length > 0;
4860
- if (loadedSkills.length > 0) return stateHasSkills ? void 0 : { skillsMetadata: loadedSkills };
4861
- if (stateHasSkills) {
4862
- loadedSkills = state.skillsMetadata;
4863
- return;
4864
- }
4964
+ if ("skillsMetadata" in state && Array.isArray(state.skillsMetadata) && state.skillsMetadata.length > 0) return;
4865
4965
  const resolvedBackend = await resolveBackend(backend, { state });
4866
4966
  const allSkills = /* @__PURE__ */ new Map();
4867
4967
  for (const sourcePath of sources) try {
@@ -4870,11 +4970,10 @@ function createSkillsMiddleware(options) {
4870
4970
  } catch (error) {
4871
4971
  console.debug(`[BackendSkillsMiddleware] Failed to load skills from ${sourcePath}:`, error);
4872
4972
  }
4873
- loadedSkills = Array.from(allSkills.values());
4874
- return { skillsMetadata: loadedSkills };
4973
+ return { skillsMetadata: Array.from(allSkills.values()) };
4875
4974
  },
4876
4975
  wrapModelCall(request, handler) {
4877
- const skillsMetadata = loadedSkills.length > 0 ? loadedSkills : request.state?.skillsMetadata || [];
4976
+ const skillsMetadata = request.state?.skillsMetadata || [];
4878
4977
  const skillsLocations = formatSkillsLocations(sources);
4879
4978
  const skillsList = formatSkillsList(skillsMetadata, sources);
4880
4979
  const skillsSection = SKILLS_SYSTEM_PROMPT.replace("{skills_locations}", skillsLocations).replace("{skills_list}", skillsList);
@@ -9095,4 +9194,4 @@ Object.defineProperty(exports, "serializeProfile", {
9095
9194
  }
9096
9195
  });
9097
9196
 
9098
- //# sourceMappingURL=langsmith-yA3yhBRa.cjs.map
9197
+ //# sourceMappingURL=langsmith-CG8px69t.cjs.map