defmodule LlmToolkit do
@moduledoc """
Base code tools for agentic LLM execution.
LlmToolkit provides the fundamental tools every agentic consumer needs to
interact with a filesystem, shell, and the web — read, write, edit, bash,
grep, glob, tree, and http_get. Each tool implements `LlmToolkit.ToolResolver`.
## Usage
# Use the default tool resolver (cwd = ".")
defmodule MyAgent do
@resolver LlmToolkit.CodeTools
def run(task) do
MyAgent.Loop.run(task, @resolver, [])
end
end
# Use with a specific working directory
resolver = {LlmToolkit.CodeTools, "/path/to/project"}
"""
alias LlmToolkit.CodeTools
alias LlmToolkit.Tool.Call
@doc """
Creates a ToolResolver function bound to a working directory.
Returns a tuple `{LlmToolkit.CodeTools, cwd}` suitable for use
as a resolver in any agent loop that accepts `ToolResolver` modules.
## Examples
iex> LlmToolkit.resolver("/tmp/project")
{LlmToolkit.CodeTools, "/tmp/project"}
"""
@spec resolver(String.t()) :: {module(), String.t()}
def resolver(cwd) when is_binary(cwd) do
{CodeTools, cwd}
end
@doc """
Creates a resolver closure for use in contexts that expect
a simple function, not a tuple.
## Examples
resolver = LlmToolkit.resolver_fn("/tmp/project")
{:ok, content} = resolver.(%Call{name: "read_file", arguments: %{"path" => "README.md"}})
"""
@spec resolver_fn(String.t()) :: (Call.t() -> {:ok, String.t()} | {:error, String.t()})
def resolver_fn(cwd) when is_binary(cwd) do
fn %Call{} = call ->
CodeTools.resolve(call, cwd)
end
end
end