deepagents 1.13.0 → 1.13.2

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.
@@ -2,7 +2,7 @@ import { AIMessage, HumanMessage, SystemMessage, ToolMessage, anthropicPromptCac
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";
5
- import { AIMessage as AIMessage$1, HumanMessage as HumanMessage$1, RemoveMessage, getBufferString } from "@langchain/core/messages";
5
+ import { AIMessage as AIMessage$1, HumanMessage as HumanMessage$1, RemoveMessage, ToolMessage as ToolMessage$1, getBufferString } from "@langchain/core/messages";
6
6
  import * as z$2 from "zod";
7
7
  import { z as z$1 } from "zod";
8
8
  import { ContextOverflowError } from "@langchain/core/errors";
@@ -23,6 +23,22 @@ const EMPTY_CONTENT_WARNING = "System reminder: File exists but has empty conten
23
23
  const MAX_LINE_LENGTH = 5e3;
24
24
  const TOOL_RESULT_TOKEN_LIMIT = 2e4;
25
25
  const TRUNCATION_GUIDANCE = "... [results truncated, try being more specific with your parameters]";
26
+ /**
27
+ * Normalize model- or caller-supplied text pagination bounds.
28
+ *
29
+ * Every backend must slice content and calculate pagination metadata from the
30
+ * same normalized values. Otherwise a fractional or negative argument could
31
+ * return one window while advertising a different `nextOffset`.
32
+ *
33
+ * Binary reads do not use this helper because their backend contract ignores
34
+ * line-based offset and limit values.
35
+ */
36
+ function normalizeReadPagination(offset, limit) {
37
+ return {
38
+ offset: Number.isFinite(offset) ? Math.max(0, Math.floor(offset)) : 0,
39
+ limit: Number.isFinite(limit) ? Math.max(0, Math.floor(limit)) : 0
40
+ };
41
+ }
26
42
  const MIME_TYPES = {
27
43
  ".png": "image/png",
28
44
  ".jpg": "image/jpeg",
@@ -134,40 +150,60 @@ function sanitizeToolCallId(toolCallId) {
134
150
  return toolCallId.replace(/\./g, "_").replace(/\//g, "_").replace(/\\/g, "_");
135
151
  }
136
152
  /**
137
- * Format file content with line numbers (cat -n style).
138
- *
139
- * Chunks lines longer than MAX_LINE_LENGTH with continuation markers (e.g., 5.1, 5.2).
153
+ * Format file content with line numbers and structured source-line boundaries.
140
154
  *
141
- * @param content - File content as string or list of lines
142
- * @param startLine - Starting line number (default: 1)
143
- * @returns Formatted content with line numbers and continuation markers
155
+ * The boundaries let downstream size limiting truncate only after complete
156
+ * source lines without reparsing the rendered gutter. This keeps presentation
157
+ * details (padding, tab separators, and continuation labels) encapsulated in
158
+ * the formatter that creates them.
144
159
  */
145
- function formatContentWithLineNumbers(content, startLine = 1) {
160
+ function formatContentWithLineNumbersAndBoundaries(content, startLine = 1) {
146
161
  let lines;
147
162
  if (typeof content === "string") {
148
163
  lines = content.split("\n");
149
164
  if (lines.length > 0 && lines[lines.length - 1] === "") lines = lines.slice(0, -1);
150
165
  } else lines = content;
151
166
  const resultLines = [];
167
+ const sourceLineBoundaries = [];
168
+ let renderedLength = 0;
169
+ const appendRow = (row, sourceLine, completesSourceLine) => {
170
+ if (resultLines.length > 0) renderedLength += 1;
171
+ resultLines.push(row);
172
+ renderedLength += row.length;
173
+ if (completesSourceLine) sourceLineBoundaries.push({
174
+ sourceLine,
175
+ endOffset: renderedLength
176
+ });
177
+ };
152
178
  for (let i = 0; i < lines.length; i++) {
153
179
  const line = lines[i];
154
180
  const lineNum = i + startLine;
155
- if (line.length <= 5e3) resultLines.push(`${lineNum.toString().padStart(6)}\t${line}`);
156
- else {
157
- const numChunks = Math.ceil(line.length / MAX_LINE_LENGTH);
158
- for (let chunkIdx = 0; chunkIdx < numChunks; chunkIdx++) {
159
- const start = chunkIdx * MAX_LINE_LENGTH;
160
- const end = Math.min(start + MAX_LINE_LENGTH, line.length);
161
- const chunk = line.substring(start, end);
162
- if (chunkIdx === 0) resultLines.push(`${lineNum.toString().padStart(6)}\t${chunk}`);
163
- else {
164
- const continuationMarker = `${lineNum}.${chunkIdx}`;
165
- resultLines.push(`${continuationMarker.padStart(6)}\t${chunk}`);
166
- }
167
- }
181
+ if (line.length <= 5e3) {
182
+ appendRow(`${lineNum.toString().padStart(6)}\t${line}`, lineNum, true);
183
+ continue;
184
+ }
185
+ const numChunks = Math.ceil(line.length / MAX_LINE_LENGTH);
186
+ for (let chunkIdx = 0; chunkIdx < numChunks; chunkIdx++) {
187
+ const start = chunkIdx * MAX_LINE_LENGTH;
188
+ const end = Math.min(start + MAX_LINE_LENGTH, line.length);
189
+ const chunk = line.substring(start, end);
190
+ appendRow(`${(chunkIdx === 0 ? `${lineNum}` : `${lineNum}.${chunkIdx}`).padStart(6)}\t${chunk}`, lineNum, chunkIdx === numChunks - 1);
168
191
  }
169
192
  }
170
- return resultLines.join("\n");
193
+ return {
194
+ text: resultLines.join("\n"),
195
+ sourceLineBoundaries
196
+ };
197
+ }
198
+ /**
199
+ * Format file content with line numbers (cat -n style).
200
+ *
201
+ * Lines longer than `MAX_LINE_LENGTH` are split into continuation rows such as
202
+ * `5.1` and `5.2`. Use `formatContentWithLineNumbersAndBoundaries` when a
203
+ * caller also needs safe source-line truncation points.
204
+ */
205
+ function formatContentWithLineNumbers(content, startLine = 1) {
206
+ return formatContentWithLineNumbersAndBoundaries(content, startLine).text;
171
207
  }
172
208
  /**
173
209
  * Check if content is empty and return warning message.
@@ -841,10 +877,23 @@ var StateBackend = class {
841
877
  mimeType: fileDataV2.mimeType
842
878
  };
843
879
  if (typeof fileDataV2.content !== "string") return { error: `File '${filePath}' has binary content but text MIME type` };
844
- return {
845
- content: fileDataV2.content.split("\n").slice(offset, offset + limit).join("\n"),
880
+ const { offset: normalizedOffset, limit: normalizedLimit } = normalizeReadPagination(offset, limit);
881
+ const lines = fileDataV2.content.split("\n");
882
+ const totalLines = lines[lines.length - 1] === "" ? lines.length - 1 : lines.length;
883
+ const selected = lines.slice(normalizedOffset, normalizedOffset + normalizedLimit);
884
+ if (selected.length === 0 || normalizedOffset >= totalLines || normalizedLimit === 0) return {
885
+ content: selected.join("\n"),
846
886
  mimeType: fileDataV2.mimeType
847
887
  };
888
+ const endOffset = Math.min(normalizedOffset + selected.length, totalLines);
889
+ return {
890
+ content: selected.join("\n"),
891
+ mimeType: fileDataV2.mimeType,
892
+ totalLines,
893
+ startLine: normalizedOffset + 1,
894
+ endLine: endOffset,
895
+ nextOffset: endOffset < totalLines ? endOffset : void 0
896
+ };
848
897
  }
849
898
  /**
850
899
  * Read file content as raw FileData.
@@ -1560,6 +1609,73 @@ const READ_FILE_TRUNCATION_MSG = `
1560
1609
 
1561
1610
  [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.]`;
1562
1611
  /**
1612
+ * Render backend pagination metadata as guidance for the model.
1613
+ *
1614
+ * Backends own source-level pagination because only they know how much of the
1615
+ * file was read. The middleware owns presentation: it line-numbers the text
1616
+ * and turns optional metadata into a human-readable footer. Keeping the fields
1617
+ * optional preserves compatibility with custom backends that predate this
1618
+ * contract; those reads simply receive no pagination footer.
1619
+ *
1620
+ * `nextOffset` is the signal that the read is partial. A result at EOF omits it,
1621
+ * so complete reads retain their previous output shape.
1622
+ */
1623
+ function remainingLinesNotice(readResult) {
1624
+ const { startLine, endLine, nextOffset, totalLines } = readResult;
1625
+ 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 "";
1626
+ const readCount = endLine - startLine + 1;
1627
+ const readUnit = readCount === 1 ? "line" : "lines";
1628
+ if (totalLines === void 0) return `\n\n[Read ${readCount} ${readUnit} (lines ${startLine}-${endLine}). More lines remain from offset ${nextOffset}.]`;
1629
+ if (endLine >= totalLines) return "";
1630
+ const remaining = totalLines - endLine;
1631
+ return `\n\n[Read ${readCount} ${readUnit} (lines ${startLine}-${endLine} of ${totalLines} total). ${remaining} ${remaining === 1 ? "line" : "lines"} remaining from offset ${nextOffset}.]`;
1632
+ }
1633
+ /**
1634
+ * Fit a line-numbered read into the middleware's output budget without
1635
+ * publishing a resume offset that skips content the model did not see.
1636
+ *
1637
+ * There are two independent forms of limiting:
1638
+ *
1639
+ * 1. The backend paginates the source file with `offset` and `limit`.
1640
+ * 2. The middleware may further shorten that page to fit its token budget.
1641
+ *
1642
+ * If the backend returned lines 1-100 but the middleware only displayed lines
1643
+ * 1-30, forwarding the backend's original `nextOffset: 100` would silently skip
1644
+ * lines 31-100 on the next read. This function therefore truncates only after a
1645
+ * complete source line and rebuilds the remaining-lines notice using the last
1646
+ * line actually displayed.
1647
+ *
1648
+ * Long source lines may occupy several formatted rows (`12`, `12.1`, ...). The
1649
+ * formatter records a structured boundary only after the final chunk, so this
1650
+ * function does not need to inspect or understand the gutter representation.
1651
+ * If no complete source line can fit beside the truncation message, the function
1652
+ * falls back to character truncation and omits pagination guidance rather than
1653
+ * advertising an unsafe offset.
1654
+ */
1655
+ function truncatePaginatedRead(formatted, filePath, readResult, tokenLimit) {
1656
+ const content = formatted.text;
1657
+ const notice = remainingLinesNotice(readResult);
1658
+ if (!tokenLimit || content.length + notice.length < 4 * tokenLimit) return content + notice;
1659
+ const truncationMsg = READ_FILE_TRUNCATION_MSG.replace("{file_path}", filePath);
1660
+ const threshold = 4 * tokenLimit;
1661
+ if (readResult.startLine !== void 0 && readResult.endLine !== void 0) {
1662
+ const finalSourceLine = readResult.endLine;
1663
+ const boundaries = formatted.sourceLineBoundaries.filter((boundary) => boundary.sourceLine <= finalSourceLine);
1664
+ for (let index = boundaries.length - 1; index >= 0; index -= 1) {
1665
+ const boundary = boundaries[index];
1666
+ const adjustedNotice = remainingLinesNotice({
1667
+ totalLines: readResult.totalLines,
1668
+ startLine: readResult.startLine,
1669
+ endLine: boundary.sourceLine,
1670
+ nextOffset: boundary.sourceLine
1671
+ });
1672
+ if (boundary.endOffset + truncationMsg.length + adjustedNotice.length <= threshold) return content.slice(0, boundary.endOffset) + truncationMsg + adjustedNotice;
1673
+ }
1674
+ }
1675
+ const maxContentLength = Math.max(0, threshold - truncationMsg.length);
1676
+ return content.substring(0, maxContentLength) + truncationMsg;
1677
+ }
1678
+ /**
1563
1679
  * Note appended to grep results that were cut short by the match-count cap.
1564
1680
  */
1565
1681
  const GREP_TRUNCATION_NOTE = "Note: the search stopped early because it hit the maximum match count. The matches above are valid but incomplete. Narrow the search (a more specific pattern or a narrower path), or raise max_count, to see the rest.";
@@ -2061,7 +2177,8 @@ function createReadFileTool(backend, options) {
2061
2177
  const permissionError = checkPermission(permissions, "read", input.file_path);
2062
2178
  if (permissionError !== void 0) return toolError(runtime, "read_file", permissionError);
2063
2179
  const resolvedBackend = await resolveBackend(backend, runtime);
2064
- const { file_path, offset = 0, limit = 100 } = input;
2180
+ const { file_path, offset: requestedOffset = 0, limit: requestedLimit = 100 } = input;
2181
+ const { offset, limit } = normalizeReadPagination(requestedOffset, requestedLimit);
2065
2182
  const readResult = await resolvedBackend.read(file_path, offset, limit);
2066
2183
  if (readResult.error) return [{
2067
2184
  type: "text",
@@ -2109,16 +2226,21 @@ function createReadFileTool(backend, options) {
2109
2226
  }
2110
2227
  let content = typeof readResult.content === "string" ? readResult.content : "";
2111
2228
  const lines = content.split("\n");
2112
- if (lines.length > limit) content = lines.slice(0, limit).join("\n");
2113
- let formatted = formatContentWithLineNumbers(content, offset + 1);
2114
- if (toolTokenLimitBeforeEvict && formatted.length >= 4 * toolTokenLimitBeforeEvict) {
2115
- const truncationMsg = READ_FILE_TRUNCATION_MSG.replace("{file_path}", file_path);
2116
- const maxContentLength = 4 * toolTokenLimitBeforeEvict - truncationMsg.length;
2117
- formatted = formatted.substring(0, maxContentLength) + truncationMsg;
2229
+ let paginationResult = readResult;
2230
+ if (lines.length > limit) {
2231
+ content = lines.slice(0, limit).join("\n");
2232
+ if (limit > 0 && readResult.startLine !== void 0 && readResult.endLine !== void 0) {
2233
+ const endLine = Math.min(readResult.startLine + limit - 1, readResult.endLine, readResult.totalLines ?? Number.POSITIVE_INFINITY);
2234
+ paginationResult = {
2235
+ ...readResult,
2236
+ endLine,
2237
+ nextOffset: endLine
2238
+ };
2239
+ }
2118
2240
  }
2119
2241
  return [{
2120
2242
  type: "text",
2121
- text: formatted
2243
+ text: truncatePaginatedRead(formatContentWithLineNumbersAndBoundaries(content, paginationResult.startLine ?? offset + 1), file_path, paginationResult, toolTokenLimitBeforeEvict)
2122
2244
  }];
2123
2245
  }, {
2124
2246
  name: "read_file",
@@ -5447,8 +5569,9 @@ function hasToolName(tool) {
5447
5569
  return tool !== null && typeof tool === "object" && "name" in tool && typeof tool.name === "string";
5448
5570
  }
5449
5571
  /**
5450
- * Create middleware that removes excluded tools after all tool-injecting
5451
- * middleware has had a chance to add tools to the request.
5572
+ * Create middleware that hides excluded tools from the model and rejects calls
5573
+ * to them. Exclusions calibrate the agent per model; they are not a security
5574
+ * boundary.
5452
5575
  *
5453
5576
  * @internal
5454
5577
  */
@@ -5460,6 +5583,16 @@ function createToolExclusionMiddleware(excludedTools) {
5460
5583
  ...request,
5461
5584
  tools: request.tools?.filter((tool) => !hasToolName(tool) || !excludedTools.has(tool.name))
5462
5585
  });
5586
+ },
5587
+ wrapToolCall(request, handler) {
5588
+ const { name, id } = request.toolCall;
5589
+ if (!excludedTools.has(name)) return handler(request);
5590
+ return new ToolMessage$1({
5591
+ content: `Error: ${name} is not available.`,
5592
+ tool_call_id: id ?? "",
5593
+ name,
5594
+ status: "error"
5595
+ });
5463
5596
  }
5464
5597
  });
5465
5598
  }
@@ -6771,10 +6904,23 @@ var StoreBackend = class {
6771
6904
  mimeType: fileDataV2.mimeType
6772
6905
  };
6773
6906
  if (typeof fileDataV2.content !== "string") return { error: `File '${filePath}' has binary content but text MIME type` };
6774
- return {
6775
- content: fileDataV2.content.split("\n").slice(offset, offset + limit).join("\n"),
6907
+ const { offset: normalizedOffset, limit: normalizedLimit } = normalizeReadPagination(offset, limit);
6908
+ const lines = fileDataV2.content.split("\n");
6909
+ const totalLines = lines[lines.length - 1] === "" ? lines.length - 1 : lines.length;
6910
+ const selected = lines.slice(normalizedOffset, normalizedOffset + normalizedLimit);
6911
+ if (selected.length === 0 || normalizedOffset >= totalLines || normalizedLimit === 0) return {
6912
+ content: selected.join("\n"),
6776
6913
  mimeType: fileDataV2.mimeType
6777
6914
  };
6915
+ const endOffset = Math.min(normalizedOffset + selected.length, totalLines);
6916
+ return {
6917
+ content: selected.join("\n"),
6918
+ mimeType: fileDataV2.mimeType,
6919
+ totalLines,
6920
+ startLine: normalizedOffset + 1,
6921
+ endLine: endOffset,
6922
+ nextOffset: endOffset < totalLines ? endOffset : void 0
6923
+ };
6778
6924
  } catch (e) {
6779
6925
  return { error: e.message };
6780
6926
  }
@@ -7040,12 +7186,20 @@ function splitLinesKeepEnds(content) {
7040
7186
  return lines;
7041
7187
  }
7042
7188
  function sliceReadContent(content, offset, limit) {
7043
- if (!content || content.trim() === "") return { content };
7189
+ if (!content) return { content };
7044
7190
  const lines = splitLinesKeepEnds(content.replace(/\r\n/g, "\n").replace(/\r/g, "\n"));
7045
7191
  const startIndex = offset;
7046
7192
  const endIndex = Math.min(startIndex + limit, lines.length);
7047
7193
  if (startIndex >= lines.length) return { error: `Line offset ${offset} exceeds file length (${lines.length} lines)` };
7048
- return { content: lines.slice(startIndex, endIndex).join("") };
7194
+ const selected = lines.slice(startIndex, endIndex);
7195
+ if (selected.length === 0 || offset < 0 || limit <= 0) return { content: selected.join("") };
7196
+ return {
7197
+ content: selected.join(""),
7198
+ totalLines: lines.length,
7199
+ startLine: startIndex + 1,
7200
+ endLine: endIndex,
7201
+ nextOffset: endIndex < lines.length ? endIndex : void 0
7202
+ };
7049
7203
  }
7050
7204
  function isLangSmithNotFoundError(error) {
7051
7205
  if (typeof error !== "object" || error === null) return false;
@@ -7524,9 +7678,11 @@ var ContextHubBackend = class ContextHubBackend {
7524
7678
  }
7525
7679
  const content = cache[hubPath];
7526
7680
  if (content === void 0) return { error: `File '${filePath}' not found` };
7527
- const sliced = sliceReadContent(content, offset, limit);
7681
+ const { offset: normalizedOffset, limit: normalizedLimit } = normalizeReadPagination(offset, limit);
7682
+ const sliced = sliceReadContent(content, normalizedOffset, normalizedLimit);
7528
7683
  if (sliced.error) return { error: sliced.error };
7529
7684
  return {
7685
+ ...sliced,
7530
7686
  content: sliced.content ?? "",
7531
7687
  mimeType: TEXT_MIME_TYPE
7532
7688
  };
@@ -7865,6 +8021,7 @@ function buildFindCommand(searchPath) {
7865
8021
  const findBase = `find -L ${quotedPath} ${`\\( -path /proc -o -path /sys -o -path /dev -o -path /run -o -path ${quotedPath}/proc -o -path ${quotedPath}/sys -o -path ${quotedPath}/dev -o -path ${quotedPath}/run \\) -prune`} -o -not -path ${quotedPath}`;
7866
8022
  return `{ ${`if find /dev/null -maxdepth 0 -printf '' 2>/dev/null; then ${findBase} -printf '%s\\t%T@\\t%y\\t%p\\n' 2>/dev/null; elif stat -c %s /dev/null >/dev/null 2>&1; then ${findBase} -exec sh -c '${STAT_C_SCRIPT}' _ {} +; else ${findBase} -exec stat -f '%z\t%m\t%Sp\t%N' {} + 2>/dev/null; fi || true`}; } | head -n 50001`;
7867
8023
  }
8024
+ const READ_METADATA_PREFIX = "__DEEPAGENTS_READ_METADATA__";
7868
8025
  /**
7869
8026
  * Pure POSIX shell command for reading files with line numbers.
7870
8027
  * Uses awk for line numbering with offset/limit — works on any Linux including Alpine.
@@ -7878,9 +8035,32 @@ function buildReadCommand(filePath, offset, limit) {
7878
8035
  return [
7879
8036
  `if [ ! -f ${quotedPath} ]; then echo "Error: File not found"; exit 1; fi`,
7880
8037
  `if [ ! -s ${quotedPath} ]; then echo "System reminder: File exists but has empty contents"; exit 0; fi`,
7881
- `awk 'NR >= ${start} && NR <= ${end} { printf "%6d\\t%s\\n", NR, $0 }' ${quotedPath}`
8038
+ `awk 'NR >= ${start} && NR <= ${end} { printf "%6d\\t%s\\n", NR, $0 } END { printf "${READ_METADATA_PREFIX}\\t%d\\n", NR }' ${quotedPath}`
7882
8039
  ].join("; ");
7883
8040
  }
8041
+ function parseReadOutput(output, offset, limit) {
8042
+ const rows = output.split("\n");
8043
+ let metadataIndex = -1;
8044
+ for (let index = rows.length - 1; index >= 0; index -= 1) if (rows[index].startsWith(`${READ_METADATA_PREFIX}\t`)) {
8045
+ metadataIndex = index;
8046
+ break;
8047
+ }
8048
+ if (metadataIndex === -1) return { content: output };
8049
+ const totalLines = Number(rows[metadataIndex].slice(29));
8050
+ if (!Number.isSafeInteger(totalLines) || totalLines < 0) return { content: output };
8051
+ const contentRows = rows.slice(0, metadataIndex);
8052
+ const content = contentRows.length > 0 ? `${contentRows.join("\n")}\n` : "";
8053
+ const startOffset = Math.floor(offset);
8054
+ const endOffset = Math.min(startOffset + Math.floor(limit), totalLines);
8055
+ if (startOffset >= totalLines || endOffset <= startOffset) return { content };
8056
+ return {
8057
+ content,
8058
+ totalLines,
8059
+ startLine: startOffset + 1,
8060
+ endLine: endOffset,
8061
+ nextOffset: endOffset < totalLines ? endOffset : void 0
8062
+ };
8063
+ }
7884
8064
  /**
7885
8065
  * Build a grep command for literal (fixed-string) search.
7886
8066
  * Uses grep -rHnF for recursive, with-filename, with-line-number, fixed-string search.
@@ -7958,15 +8138,17 @@ var BaseSandbox = class {
7958
8138
  mimeType
7959
8139
  };
7960
8140
  }
7961
- if (limit === 0) return {
8141
+ const { offset: normalizedOffset, limit: normalizedLimit } = normalizeReadPagination(offset, limit);
8142
+ if (normalizedLimit === 0) return {
7962
8143
  content: "",
7963
8144
  mimeType
7964
8145
  };
7965
- const command = buildReadCommand(filePath, offset, limit);
8146
+ const command = buildReadCommand(filePath, normalizedOffset, normalizedLimit);
7966
8147
  const result = await this.execute(command);
7967
8148
  if (result.exitCode !== 0) return { error: `File '${filePath}' not found` };
8149
+ const parsed = parseReadOutput(result.output, normalizedOffset, normalizedLimit);
7968
8150
  return {
7969
- content: result.output,
8151
+ ...result.truncated ? { content: parsed.content } : parsed,
7970
8152
  mimeType
7971
8153
  };
7972
8154
  }
@@ -8401,6 +8583,6 @@ var LangSmithSandbox = class LangSmithSandbox extends BaseSandbox {
8401
8583
  }
8402
8584
  };
8403
8585
  //#endregion
8404
- export { DEFAULT_GENERAL_PURPOSE_DESCRIPTION as A, StateBackend as B, MAX_SKILL_DESCRIPTION_LENGTH as C, createMemoryMiddleware as D, createSkillsMiddleware as E, createSubAgentMiddleware as F, resolveBackend as G, applyGrepMaxCount as H, computeSummarizationDefaults as I, checkEmptyContent as J, adaptBackendProtocol as K, createSummarizationMiddleware as L, GENERAL_PURPOSE_SUBAGENT as M, SUBAGENT_RESPONSE_FORMAT_CONFIG_KEY as N, filesValue as O, createSubAgent as P, createFilesystemMiddleware as R, createCompletionCallbackMiddleware as S, MAX_SKILL_NAME_LENGTH as T, isSandboxBackend as U, SandboxError as V, isSandboxProtocol as W, isTextMimeType as X, getMimeType as Y, performStringReplacement as Z, createHarnessProfile as _, ASYNC_TASK_SYSTEM_PROMPT as a, createAsyncSubAgentMiddleware as b, TASK_SYSTEM_PROMPT as c, registerHarnessProfile as d, generalPurposeSubagentConfigSchema as f, EMPTY_HARNESS_PROFILE as g, serializeProfile as h, StoreBackend as i, DEFAULT_SUBAGENT_PROMPT as j, createPatchToolCallsMiddleware as k, createDeepAgent as l, parseHarnessProfileConfig as m, BaseSandbox as n, BASE_AGENT_PROMPT as o, harnessProfileConfigSchema as p, adaptSandboxProtocol as q, ContextHubBackend as r, EXECUTION_SYSTEM_PROMPT as s, LangSmithSandbox as t, getHarnessProfile as u, REQUIRED_MIDDLEWARE_NAMES as v, MAX_SKILL_FILE_SIZE as w, isAsyncSubAgent as x, ConfigurationError as y, CompositeBackend as z };
8586
+ export { DEFAULT_GENERAL_PURPOSE_DESCRIPTION as A, StateBackend as B, MAX_SKILL_DESCRIPTION_LENGTH as C, createMemoryMiddleware as D, createSkillsMiddleware as E, createSubAgentMiddleware as F, resolveBackend as G, applyGrepMaxCount as H, computeSummarizationDefaults as I, checkEmptyContent as J, adaptBackendProtocol as K, createSummarizationMiddleware as L, GENERAL_PURPOSE_SUBAGENT as M, SUBAGENT_RESPONSE_FORMAT_CONFIG_KEY as N, filesValue as O, createSubAgent as P, performStringReplacement as Q, createFilesystemMiddleware as R, createCompletionCallbackMiddleware as S, MAX_SKILL_NAME_LENGTH as T, isSandboxBackend as U, SandboxError as V, isSandboxProtocol as W, isTextMimeType as X, getMimeType as Y, normalizeReadPagination as Z, createHarnessProfile as _, ASYNC_TASK_SYSTEM_PROMPT as a, createAsyncSubAgentMiddleware as b, TASK_SYSTEM_PROMPT as c, registerHarnessProfile as d, generalPurposeSubagentConfigSchema as f, EMPTY_HARNESS_PROFILE as g, serializeProfile as h, StoreBackend as i, DEFAULT_SUBAGENT_PROMPT as j, createPatchToolCallsMiddleware as k, createDeepAgent as l, parseHarnessProfileConfig as m, BaseSandbox as n, BASE_AGENT_PROMPT as o, harnessProfileConfigSchema as p, adaptSandboxProtocol as q, ContextHubBackend as r, EXECUTION_SYSTEM_PROMPT as s, LangSmithSandbox as t, getHarnessProfile as u, REQUIRED_MIDDLEWARE_NAMES as v, MAX_SKILL_FILE_SIZE as w, isAsyncSubAgent as x, ConfigurationError as y, CompositeBackend as z };
8405
8587
 
8406
- //# sourceMappingURL=langsmith-zm0ILQsV.js.map
8588
+ //# sourceMappingURL=langsmith-BBV5JlNW.js.map