Packages
nous
0.16.6
0.17.0
0.16.6
0.16.5
0.16.4
0.16.3
0.16.2
0.16.1
0.16.0
0.15.8
0.15.7
0.15.6
0.15.5
0.15.4
0.15.3
0.15.2
0.15.1
0.15.0
0.14.3
0.14.2
0.14.1
0.14.0
0.13.3
0.13.2
0.13.1
0.13.0
0.12.17
0.12.16
0.12.15
0.12.14
0.12.13
0.12.12
0.12.11
0.12.9
0.12.7
0.12.6
0.12.5
0.12.3
0.12.2
0.12.0
0.11.3
0.11.0
0.10.1
0.10.0
0.9.0
0.8.1
0.8.0
0.7.2
0.7.1
0.7.0
0.5.0
AI agent framework for Elixir with multi-provider LLM support
Current section
Files
Jump to
Current section
Files
lib/nous/tools/file_read.ex
defmodule Nous.Tools.FileRead do
@moduledoc """
File reading tool with line numbers.
Returns file content with `cat -n` style line numbers, supporting
offset and limit for reading specific sections of large files.
"""
@behaviour Nous.Tool.Behaviour
@default_limit 2000
@impl true
def metadata do
%{
name: "file_read",
description: "Read a file from the filesystem. Returns content with line numbers.",
category: :read,
requires_approval: false,
parameters: %{
"type" => "object",
"properties" => %{
"file_path" => %{
"type" => "string",
"description" => "Path to the file to read"
},
"offset" => %{
"type" => "integer",
"description" => "Line number to start reading from (1-based). Defaults to 1."
},
"limit" => %{
"type" => "integer",
"description" => "Number of lines to read. Defaults to 2000."
}
},
"required" => ["file_path"]
}
}
end
@impl true
def execute(ctx, %{"file_path" => file_path} = args) do
offset = Map.get(args, "offset", 1) |> max(1)
limit = Map.get(args, "limit", @default_limit)
with {:ok, safe_path} <- Nous.Tools.PathGuard.validate(file_path, ctx),
{:ok, content} <- File.read(safe_path) do
result =
content
|> String.split("\n")
|> Enum.with_index(1)
|> Enum.drop(offset - 1)
|> Enum.take(limit)
|> Enum.map(fn {line, num} -> "#{num}\t#{line}" end)
|> Enum.join("\n")
{:ok, result}
else
{:error, reason} when is_binary(reason) ->
{:error, reason}
{:error, reason} ->
{:error, "Failed to read #{file_path}: #{inspect(reason)}"}
end
end
end