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.
- package/dist/{agent-LUvc15zz.d.cts → agent-BwYXPTyT.d.cts} +50 -15
- package/dist/{agent-Bx0owr-O.d.ts → agent-CH8GB5HD.d.ts} +50 -15
- package/dist/browser.cjs +1 -1
- package/dist/browser.d.cts +1 -1
- package/dist/browser.d.ts +1 -1
- package/dist/browser.js +1 -1
- package/dist/index.cjs +3 -2
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +3 -3
- package/dist/{langsmith-zm0ILQsV.js → langsmith-BBV5JlNW.js} +227 -45
- package/dist/langsmith-BBV5JlNW.js.map +1 -0
- package/dist/{langsmith-Ck9t7AGW.cjs → langsmith-DL32swQ3.cjs} +231 -43
- package/dist/langsmith-DL32swQ3.cjs.map +1 -0
- package/dist/node.cjs +3 -2
- package/dist/node.d.cts +2 -2
- package/dist/node.d.ts +2 -2
- package/dist/node.js +3 -3
- package/dist/{src-C9o7b5C6.js → src-CKk0apeE.js} +18 -7
- package/dist/src-CKk0apeE.js.map +1 -0
- package/dist/{src-C97zNx7s.cjs → src-DdGDIhZk.cjs} +18 -7
- package/dist/src-DdGDIhZk.cjs.map +1 -0
- package/package.json +2 -2
- package/dist/langsmith-Ck9t7AGW.cjs.map +0 -1
- package/dist/langsmith-zm0ILQsV.js.map +0 -1
- package/dist/src-C97zNx7s.cjs.map +0 -1
- package/dist/src-C9o7b5C6.js.map +0 -1
|
@@ -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
|
|
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
|
-
*
|
|
142
|
-
*
|
|
143
|
-
*
|
|
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
|
|
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)
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
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
|
|
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
|
-
|
|
845
|
-
|
|
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
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
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:
|
|
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
|
|
5451
|
-
*
|
|
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
|
-
|
|
6775
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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,
|
|
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:
|
|
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,
|
|
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-
|
|
8588
|
+
//# sourceMappingURL=langsmith-BBV5JlNW.js.map
|