fix(infra): single-read file_read (no double disk I/O for hash) + bail health poll on dead process

This commit is contained in:
2026-07-12 12:55:12 +04:00
parent 363d880a69
commit b93729008d
2 changed files with 10 additions and 5 deletions
@@ -141,7 +141,10 @@ class FileReadTool(
}
private fun readFile(path: Path, startLine: Int?, endLine: Int?, request: ToolRequest): ToolResult = runCatching {
val lines = Files.readAllLines(path)
// Read the file once. Lines and the (whole-read) content hash both derive from these bytes,
// so a full read no longer hits the disk twice (readAllLines + readAllBytes for the hash).
val bytes = Files.readAllBytes(path)
val lines = bytes.inputStream().bufferedReader().readLines()
val start = ((startLine ?: 1) - 1).coerceAtLeast(0)
val end = (endLine ?: lines.size).coerceAtMost(lines.size)
val selected = lines.subList(start, end)
@@ -166,7 +169,7 @@ class FileReadTool(
// against what the agent actually saw. A partial or truncated view establishes no baseline —
// the agent must read the relevant range before editing.
val sawWholeFile = startLine == null && endLine == null && !lineCapped && !charCapped
val metadata = if (sawWholeFile) mapOf("contentHash" to sha256(path)) else emptyMap()
val metadata = if (sawWholeFile) mapOf("contentHash" to sha256(bytes)) else emptyMap()
ToolResult.Success(
invocationId = request.invocationId,
output = content + note,
@@ -180,8 +183,8 @@ class FileReadTool(
)
}
private fun sha256(path: Path): String =
java.security.MessageDigest.getInstance("SHA-256").digest(Files.readAllBytes(path))
private fun sha256(bytes: ByteArray): String =
java.security.MessageDigest.getInstance("SHA-256").digest(bytes)
.joinToString("") { "%02x".format(it) }
private fun listDir(path: Path, request: ToolRequest): ToolResult = runCatching {