kdeps-tools-tail_file
v2.0.0Read the last N lines of a file (default 20) -- for checking the end of a log or output file without knowing its total length upfront. Use as evidence that a command's output or a log ends the way a task claims it does.
set tools / shelf tools
LLM context: ~145 tokens when loaded (prompt or tool definition)
Where it runs
Part of the tools set, used in workflow and agent mode. What the model is told about each built-in tool: its description, usage notes and parameters. kdeps runs the tool itself.
- the agent loop builds the request
- the tool definitions are sent to the modeltools/tail_file
- the model calls a tool
- kdeps runs it
- the result goes back to the model
Loaded by: kdeps (agent loop), /update, /settings, kdeps run, kdeps install, kdeps list, kdeps uninstall, kdeps update
In the code: kdeps (agent loop)agent.RegisterBuiltinToolsagent.definedAs
Install
A kdeps asset: installed with the first-run profile that includes its set, or the first time a command needs it, and updated without a new release.
Pin a version with kdeps install tools/tail_file@<version>.
Contents
Read the last N lines of a file (default 20) -- for checking the end of a log or output file without knowing its total length upfront. Use as evidence that a command's output or a log ends the way a task claims it does.
- category
- file
- outputFormat
- numbered lines (number, tab, text); a "[last N/M lines shown]" note when the file is longer
- seeAlso
- read_file, md5_file, list_files
| Parameter | Type | Description |
|---|---|---|
| file_path * | string | Path to the file (absolute, or relative to the working directory) |
| lines | number | Number of lines from the end to return (default 20) |
Python script (declared in YAML, no Go code)
import collections, json, os, sys
a = json.loads(sys.argv[1])
path = a["file_path"] if os.path.isabs(a["file_path"]) else os.path.abspath(a["file_path"])
if os.path.isdir(path):
sys.exit("tail_file: %s is a directory" % path)
try:
n = int(float(a.get("lines") or 0))
except ValueError:
n = 0
if n <= 0:
n = 20
total, last = 0, collections.deque(maxlen=n)
try:
with open(path, "rb") as f:
if b"\0" in f.read(512):
sys.exit("tail_file: %s appears to be a binary file" % path)
f.seek(0)
for line in f: # streamed: a large log is never held in memory
total += 1
last.append(line)
except OSError as e:
sys.exit("tail_file: %s: %s" % (path, e.strerror or e))
start, width = total - len(last), len(str(total))
for i, line in enumerate(last):
text = line[:-1] if line.endswith(b"\n") else line
print("%*d\t%s" % (width, start + i + 1, text.decode("utf-8", "replace")))
if start > 0:
print("[last %d/%d lines shown]" % (len(last), total))
Paths kept in the workspace: file_path
aliases:
- tail
version: 2.0.0
category: file
aliases: [tail] # other names a model may call it by; the model is shown only this tool's name
description: Read the last N lines of a file (default 20) -- for checking the end of a log or output file without knowing its total length upfront. Use as evidence that a command's output or a log ends the way a task claims it does.
outputFormat: numbered lines (number, tab, text); a "[last N/M lines shown]" note when the file is longer
seeAlso: read_file, md5_file, list_files
parameters:
file_path:
type: string
description: Path to the file (absolute, or relative to the working directory)
required: true
lines:
type: number
description: Number of lines from the end to return (default 20)
python:
paths: [file_path] # checked against the workspace boundary
script: |
import collections, json, os, sys
a = json.loads(sys.argv[1])
path = a["file_path"] if os.path.isabs(a["file_path"]) else os.path.abspath(a["file_path"])
if os.path.isdir(path):
sys.exit("tail_file: %s is a directory" % path)
try:
n = int(float(a.get("lines") or 0))
except ValueError:
n = 0
if n <= 0:
n = 20
total, last = 0, collections.deque(maxlen=n)
try:
with open(path, "rb") as f:
if b"\0" in f.read(512):
sys.exit("tail_file: %s appears to be a binary file" % path)
f.seek(0)
for line in f: # streamed: a large log is never held in memory
total += 1
last.append(line)
except OSError as e:
sys.exit("tail_file: %s: %s" % (path, e.strerror or e))
start, width = total - len(last), len(str(total))
for i, line in enumerate(last):
text = line[:-1] if line.endswith(b"\n") else line
print("%*d\t%s" % (width, start + i + 1, text.decode("utf-8", "replace")))
if start > 0:
print("[last %d/%d lines shown]" % (len(last), total))
Versions
| Version | Published | Status |
|---|---|---|
| 2.0.0 | 10/24/2026 | active |
| 1.1.0 | 10/17/2026 | active |
| 1.0.0 | 10/11/2026 | active |
Details
- Author
- kdeps
- License
- Apache-2.0
- Latest Version
- 2.0.0
- Published
- 10/11/2026