enhanced infos

This commit is contained in:
afjcjsbx 2026-03-28 09:47:31 +01:00
parent 885aff8994
commit 8a9bc284a0
2 changed files with 73 additions and 6 deletions

View file

@ -534,6 +534,12 @@ func (t *ReadFileLinesTool) Execute(ctx context.Context, args map[string]any) *T
if startLine < 1 { if startLine < 1 {
return ErrorResult("start_line must be >= 1") return ErrorResult("start_line must be >= 1")
} }
if _, exists := args["offset"]; exists {
return ErrorResult("offset is not supported in line mode; use start_line")
}
if _, exists := args["length"]; exists {
return ErrorResult("length is not supported in line mode; use max_lines")
}
limit := int64(-1) limit := int64(-1)
if raw, exists := args["max_lines"]; exists && raw != nil { if raw, exists := args["max_lines"]; exists && raw != nil {
@ -644,19 +650,28 @@ func (t *ReadFileLinesTool) Execute(ctx context.Context, args map[string]any) *T
switch { switch {
case lineTruncated: case lineTruncated:
header += fmt.Sprintf( header += fmt.Sprintf(
"\n[TRUNCATED - line %d exceeded the %d byte read budget and was cut mid-line.", "\n[TRUNCATED - line %d exceeded the %d byte read budget and was cut mid-line.]",
endLine, endLine,
t.maxSize, t.maxSize,
) )
case byteBudgetTruncated: case byteBudgetTruncated:
if limit > 0 {
header += fmt.Sprintf(
"\n[TRUNCATED - byte budget reached. Call read_file again with start_line=%d and max_lines=%d to continue at the next line.]",
startLine+linesRead,
limit,
)
} else {
header += fmt.Sprintf( header += fmt.Sprintf(
"\n[TRUNCATED - byte budget reached. Call read_file again with start_line=%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 start_line=%d to continue.]", "\n[PARTIAL - more content remains. Call read_file again with start_line=%d and max_lines=%d to continue.]",
startLine+linesRead, startLine+linesRead,
limit,
) )
default: default:
header += "\n[END OF FILE - no further content.]" header += "\n[END OF FILE - no further content.]"

View file

@ -897,6 +897,9 @@ func TestReadFileLinesTool_ChunkedReading(t *testing.T) {
if !strings.Contains(result1.ForLLM, "start_line=3") { if !strings.Contains(result1.ForLLM, "start_line=3") {
t.Fatalf("expected continuation start_line=3, got: %s", result1.ForLLM) t.Fatalf("expected continuation start_line=3, got: %s", result1.ForLLM)
} }
if !strings.Contains(result1.ForLLM, "max_lines=2") {
t.Fatalf("expected continuation max_lines=2, got: %s", result1.ForLLM)
}
result2 := tool.Execute(context.Background(), map[string]any{ result2 := tool.Execute(context.Background(), map[string]any{
"path": testFile, "path": testFile,
@ -912,6 +915,9 @@ func TestReadFileLinesTool_ChunkedReading(t *testing.T) {
if !strings.Contains(result2.ForLLM, "start_line=5") { if !strings.Contains(result2.ForLLM, "start_line=5") {
t.Fatalf("expected continuation start_line=5, got: %s", result2.ForLLM) t.Fatalf("expected continuation start_line=5, got: %s", result2.ForLLM)
} }
if !strings.Contains(result2.ForLLM, "max_lines=2") {
t.Fatalf("expected continuation max_lines=2, got: %s", result2.ForLLM)
}
result3 := tool.Execute(context.Background(), map[string]any{ result3 := tool.Execute(context.Background(), map[string]any{
"path": testFile, "path": testFile,
@ -1042,6 +1048,52 @@ func TestReadFileLinesTool_RegistryValidationSupportsMaxLinesAndRejectsLimit(t *
} }
} }
func TestReadFileLinesTool_RejectsOffset(t *testing.T) {
tmpDir := t.TempDir()
testFile := filepath.Join(tmpDir, "legacy_offset.txt")
err := os.WriteFile(testFile, []byte("line 1\nline 2\n"), 0o644)
if err != nil {
t.Fatalf("Failed to write test file: %v", err)
}
tool := NewReadFileLinesTool(tmpDir, false, MaxReadFileSize)
result := tool.Execute(context.Background(), map[string]any{
"path": testFile,
"start_line": 1,
"offset": 1,
})
if !result.IsError {
t.Fatalf("expected offset to be rejected, got success: %s", result.ForLLM)
}
if !strings.Contains(result.ForLLM, "offset is not supported in line mode; use start_line") {
t.Fatalf("unexpected error for offset in line mode: %s", result.ForLLM)
}
}
func TestReadFileLinesTool_RejectsLength(t *testing.T) {
tmpDir := t.TempDir()
testFile := filepath.Join(tmpDir, "legacy_length.txt")
err := os.WriteFile(testFile, []byte("line 1\nline 2\n"), 0o644)
if err != nil {
t.Fatalf("Failed to write test file: %v", err)
}
tool := NewReadFileLinesTool(tmpDir, false, MaxReadFileSize)
result := tool.Execute(context.Background(), map[string]any{
"path": testFile,
"start_line": 1,
"length": 1,
})
if !result.IsError {
t.Fatalf("expected length to be rejected, got success: %s", result.ForLLM)
}
if !strings.Contains(result.ForLLM, "length is not supported in line mode; use max_lines") {
t.Fatalf("unexpected error for length in line mode: %s", result.ForLLM)
}
}
func TestReadFileLinesTool_BinaryFileRejected(t *testing.T) { func TestReadFileLinesTool_BinaryFileRejected(t *testing.T) {
tmpDir := t.TempDir() tmpDir := t.TempDir()
testFile := filepath.Join(tmpDir, "binary.dat") testFile := filepath.Join(tmpDir, "binary.dat")