Add proper truncation notices and comprehensive tests for read tool

**Improved output messages:**
1. File fits within limits: Just outputs content (no notices)
2. Lines get truncated: Shows "Some lines were truncated to 2000 characters for display"
3. File doesn't fit limit: Shows "N more lines not shown. Use offset=X to continue reading"
4. Offset beyond file: Shows "Error: Offset X is beyond end of file (N lines total)"
5. Both truncations: Combines both notices with ". " separator

**Comprehensive test coverage:**
- Files within limits (no notices)
- Large files (line truncation)
- Long lines (character truncation)
- Offset parameter
- Limit parameter
- Offset + limit together
- Invalid offset (out of bounds)
- Combined truncations (both notices)

All 17 tests passing ✓
This commit is contained in:
Mario Zechner 2025-11-12 17:13:03 +01:00
parent c7a73d4f81
commit 2f0f0a913e
3 changed files with 491 additions and 15 deletions

View file

@ -125,23 +125,50 @@ export const readTool: AgentTool<typeof readSchema> = {
const maxLines = limit || MAX_LINES;
const endLine = Math.min(startLine + maxLines, lines.length);
// Get the relevant lines
const selectedLines = lines.slice(startLine, endLine);
// Check if offset is out of bounds
if (startLine >= lines.length) {
content = [
{
type: "text",
text: `Error: Offset ${offset} is beyond end of file (${lines.length} lines total)`,
},
];
} else {
// Get the relevant lines
const selectedLines = lines.slice(startLine, endLine);
// Truncate long lines
const formattedLines = selectedLines.map((line) => {
return line.length > MAX_LINE_LENGTH ? line.slice(0, MAX_LINE_LENGTH) : line;
});
// Truncate long lines and track which were truncated
let hadTruncatedLines = false;
const formattedLines = selectedLines.map((line) => {
if (line.length > MAX_LINE_LENGTH) {
hadTruncatedLines = true;
return line.slice(0, MAX_LINE_LENGTH);
}
return line;
});
let outputText = formattedLines.join("\n");
let outputText = formattedLines.join("\n");
// Add truncation notice if needed
if (endLine < lines.length) {
const remaining = lines.length - endLine;
outputText += `\n\n... (${remaining} more lines not shown. Use offset=${endLine + 1} to continue reading)`;
// Add notices
const notices: string[] = [];
if (hadTruncatedLines) {
notices.push(`Some lines were truncated to ${MAX_LINE_LENGTH} characters for display`);
}
if (endLine < lines.length) {
const remaining = lines.length - endLine;
notices.push(
`${remaining} more lines not shown. Use offset=${endLine + 1} to continue reading`,
);
}
if (notices.length > 0) {
outputText += `\n\n... (${notices.join(". ")})`;
}
content = [{ type: "text", text: outputText }];
}
content = [{ type: "text", text: outputText }];
}
// Check if aborted after reading