fix line format

This commit is contained in:
afjcjsbx 2026-03-27 23:02:58 +01:00
parent 2f725bf0da
commit 7c0001cde2
2 changed files with 26 additions and 17 deletions

View file

@ -569,7 +569,7 @@ func (t *ReadFileLinesTool) Execute(ctx context.Context, args map[string]any) *T
reader := bufio.NewReaderSize(io.MultiReader(bytes.NewReader(sample), file), 32*1024) reader := bufio.NewReaderSize(io.MultiReader(bytes.NewReader(sample), file), 32*1024)
var content strings.Builder var content strings.Builder
var lineIndex int64 lineIndex := int64(1)
var linesRead int64 var linesRead int64
var bytesRead int64 var bytesRead int64
var reachedEOF bool var reachedEOF bool
@ -589,7 +589,8 @@ func (t *ReadFileLinesTool) Execute(ctx context.Context, args map[string]any) *T
} }
for !reachedEOF && (limit < 0 || linesRead < limit) { for !reachedEOF && (limit < 0 || linesRead < limit) {
remaining := t.maxSize - bytesRead prefix := formatReadFileLinePrefix(lineIndex)
remaining := t.maxSize - bytesRead - int64(len(prefix))
if remaining <= 0 { if remaining <= 0 {
byteBudgetTruncated = true byteBudgetTruncated = true
break break
@ -604,8 +605,9 @@ func (t *ReadFileLinesTool) Execute(ctx context.Context, args map[string]any) *T
break break
} }
content.WriteString(prefix)
content.Write(line) content.Write(line)
bytesRead += int64(len(line)) bytesRead += int64(len(prefix) + len(line))
linesRead++ linesRead++
lineIndex++ lineIndex++
@ -648,12 +650,12 @@ func (t *ReadFileLinesTool) Execute(ctx context.Context, args map[string]any) *T
) )
case byteBudgetTruncated: case byteBudgetTruncated:
header += fmt.Sprintf( header += fmt.Sprintf(
"\n[TRUNCATED - byte budget reached. Call read_file again with offset=%d to continue at the next line.]", "\n[TRUNCATED - byte budget reached. Call read_file again with start_line=%d to continue at the next line.]",
startLine+linesRead, startLine+linesRead,
) )
case !reachedEOF && limit > 0 && linesRead >= limit: case !reachedEOF && limit > 0 && linesRead >= limit:
header += fmt.Sprintf( header += fmt.Sprintf(
"\n[PARTIAL - more content remains. Call read_file again with offset=%d to continue.]", "\n[PARTIAL - more content remains. Call read_file again with start_line=%d to continue.]",
startLine+linesRead, startLine+linesRead,
) )
default: default:
@ -672,6 +674,10 @@ func (t *ReadFileLinesTool) Execute(ctx context.Context, args map[string]any) *T
return NewToolResult(header + "\n\n" + content.String()) return NewToolResult(header + "\n\n" + content.String())
} }
func formatReadFileLinePrefix(lineNumber int64) string {
return strconv.FormatInt(lineNumber, 10) + "|"
}
func isBinaryReadFileData(data []byte) bool { func isBinaryReadFileData(data []byte) bool {
if len(data) == 0 { if len(data) == 0 {
return false return false

View file

@ -888,14 +888,14 @@ func TestReadFileLinesTool_ChunkedReading(t *testing.T) {
if result1.IsError { if result1.IsError {
t.Fatalf("Chunk 1 failed: %s", result1.ForLLM) t.Fatalf("Chunk 1 failed: %s", result1.ForLLM)
} }
if !strings.Contains(result1.ForLLM, "line 2\nline 3\n") { if !strings.Contains(result1.ForLLM, "1|line 1\n2|line 2\n") {
t.Fatalf("expected first two lines, got: %s", result1.ForLLM) t.Fatalf("expected first two lines, got: %s", result1.ForLLM)
} }
if !strings.Contains(result1.ForLLM, "lines 1-2") { if !strings.Contains(result1.ForLLM, "lines 1-2") {
t.Fatalf("expected line range 1-2, got: %s", result1.ForLLM) t.Fatalf("expected line range 1-2, got: %s", result1.ForLLM)
} }
if !strings.Contains(result1.ForLLM, "offset=3") { if !strings.Contains(result1.ForLLM, "start_line=3") {
t.Fatalf("expected continuation offset=3, got: %s", result1.ForLLM) t.Fatalf("expected continuation start_line=3, got: %s", result1.ForLLM)
} }
result2 := tool.Execute(context.Background(), map[string]any{ result2 := tool.Execute(context.Background(), map[string]any{
@ -906,11 +906,11 @@ func TestReadFileLinesTool_ChunkedReading(t *testing.T) {
if result2.IsError { if result2.IsError {
t.Fatalf("Chunk 2 failed: %s", result2.ForLLM) t.Fatalf("Chunk 2 failed: %s", result2.ForLLM)
} }
if !strings.Contains(result2.ForLLM, "line 4\nline 5\n") { if !strings.Contains(result2.ForLLM, "3|line 3\n4|line 4\n") {
t.Fatalf("expected middle chunk, got: %s", result2.ForLLM) t.Fatalf("expected middle chunk, got: %s", result2.ForLLM)
} }
if !strings.Contains(result2.ForLLM, "offset=5") { if !strings.Contains(result2.ForLLM, "start_line=5") {
t.Fatalf("expected continuation offset=5, got: %s", result2.ForLLM) t.Fatalf("expected continuation start_line=5, got: %s", result2.ForLLM)
} }
result3 := tool.Execute(context.Background(), map[string]any{ result3 := tool.Execute(context.Background(), map[string]any{
@ -921,7 +921,7 @@ func TestReadFileLinesTool_ChunkedReading(t *testing.T) {
if result3.IsError { if result3.IsError {
t.Fatalf("Chunk 3 failed: %s", result3.ForLLM) t.Fatalf("Chunk 3 failed: %s", result3.ForLLM)
} }
if !strings.Contains(result3.ForLLM, "line 6\n") { if !strings.Contains(result3.ForLLM, "5|line 5\n6|line 6\n") {
t.Fatalf("expected final chunk, got: %s", result3.ForLLM) t.Fatalf("expected final chunk, got: %s", result3.ForLLM)
} }
if !strings.Contains(result3.ForLLM, "[END OF FILE") { if !strings.Contains(result3.ForLLM, "[END OF FILE") {
@ -946,11 +946,11 @@ func TestReadFileLinesTool_DefaultOffsetAndRemainingLines(t *testing.T) {
if result.IsError { if result.IsError {
t.Fatalf("Execute() error = %s", result.ForLLM) t.Fatalf("Execute() error = %s", result.ForLLM)
} }
if !strings.Contains(result.ForLLM, "line 2\nline 3\n") { if !strings.Contains(result.ForLLM, "1|line 1\n2|line 2\n3|line 3\n") {
t.Fatalf("expected remaining lines by default, got: %s", result.ForLLM) t.Fatalf("expected remaining lines by default, got: %s", result.ForLLM)
} }
if !strings.Contains(result.ForLLM, "lines 1-2") { if !strings.Contains(result.ForLLM, "lines 1-3") {
t.Fatalf("expected line range 1-2, got: %s", result.ForLLM) t.Fatalf("expected line range 1-3, got: %s", result.ForLLM)
} }
} }
@ -1052,7 +1052,10 @@ func TestReadFileLinesTool_TruncatesSingleLongLineAtByteBudget(t *testing.T) {
if !strings.Contains(result.ForLLM, "was cut mid-line") { if !strings.Contains(result.ForLLM, "was cut mid-line") {
t.Fatalf("expected explicit mid-line truncation warning, got: %s", result.ForLLM) t.Fatalf("expected explicit mid-line truncation warning, got: %s", result.ForLLM)
} }
if strings.Contains(result.ForLLM, "first line") { if !strings.Contains(result.ForLLM, "1|first line\n") {
t.Fatalf("did not expect the skipped first line in output, got: %s", result.ForLLM) t.Fatalf("expected the first line with line prefix, got: %s", result.ForLLM)
}
if !strings.Contains(result.ForLLM, "2|") {
t.Fatalf("expected line prefix for the truncated line, got: %s", result.ForLLM)
} }
} }