Omni Tools

Hex.pmLicenseBuild Status

Ready-to-use tools for Omni-powered agents — files, shell, REPL, web fetch, and web search. Built on Omni.

Tools

Installation

Add Omni Tools to your dependencies:

def deps do
  [
    {:omni_tools, "~> 0.3"}
  ]
end

Omni Tools depends on omni, which provides the LLM API layer. Configure your provider API keys as described in the Omni README.

The tools

Module What it does
Omni.Tools.Files CRUD over a scoped directory with read-only and flat modes
Omni.Tools.Bash Executes shell commands with timeout and output capture
Omni.Tools.Repl Evaluates Elixir code in a sandboxed peer node
Omni.Tools.WebFetch Fetches URLs, simplifies content for LLM consumption
Omni.Tools.WebSearch Web search via pluggable providers (Brave, Serper, Tavily)

Each tool is created with new/1 and returns an %Omni.Tool{} struct:

Files

Read, write, patch, list, and delete files within a scoped directory:

# Full access with nested paths
Omni.Tools.Files.new(base_dir: "/data/workspace")

# Read-only, flat (no subdirectories)
Omni.Tools.Files.new(base_dir: "/data/docs", read_only: true, nested: false)

Bash

Execute shell commands in a configured working directory:

Omni.Tools.Bash.new(dir: "/app", timeout: 60_000, env: [{"NODE_ENV", "test"}])

Repl

Evaluate Elixir code in a fresh peer node with optional extensions:

alias Omni.Tools.Repl.Extension

Omni.Tools.Repl.new(
  extensions: [
    {MyApp.ReplExtension, api_key: "sk-..."},
    Extension.new(description: "Req and Jason are available.")
  ]
)

WebFetch

Fetch URLs and extract content appropriate for LLM consumption:

Omni.Tools.WebFetch.new(max_output: 30_000, timeout: 10_000)

Three strategies are always active — GitHub (blob URLs to raw content), Reddit (JSON API to formatted Markdown), and a default catch-all. Custom strategies are prepended and matched first, so they can override or extend the built-ins:

Omni.Tools.WebFetch.new(strategies: [{MyApp.WikiStrategy, []}])

WebSearch

Search the web via pluggable provider backends. API keys resolve from environment variables by default:

# Uses BRAVE_API_KEY env var
Omni.Tools.WebSearch.new(provider: Omni.Tools.WebSearch.Providers.Brave)

# Explicit key
alias Omni.Tools.WebSearch.Providers.Tavily
Omni.Tools.WebSearch.new(provider: {Tavily, api_key: "tvly-..."})

# Custom env var
alias Omni.Tools.WebSearch.Providers.Serper
Omni.Tools.WebSearch.new(provider: {Serper, api_key: {:system, "MY_SERPER_KEY"}})

Providers can also be configured via application config:

config :omni_tools, Omni.Tools.WebSearch.Providers.Brave, api_key: "..."

Using tools in a conversation

Pass tools to Omni.generate_text/3 or Omni.stream_text/3 — the tool loop executes uses automatically and feeds results back to the model:

fs   = Omni.Tools.Files.new(base_dir: "/data/workspace")
bash = Omni.Tools.Bash.new(dir: "/data/workspace")

context = Omni.context(
  system: "You are a coding assistant with access to a project workspace.",
  messages: [Omni.message("List all Elixir files and count the lines in each.")],
  tools: [fs, bash]
)

{:ok, response} = Omni.generate_text({:anthropic, "claude-sonnet-4-6"}, context)

Tools work the same way with Omni.Agent — pass them as start options or set them in your agent's init/1 callback:

{:ok, agent} = Omni.Agent.start_link(
  model: {:anthropic, "claude-sonnet-4-6"},
  tools: [fs, bash],
  subscribe: true
)

Configuration

Every tool supports a three-layer configuration merge:

module defaults → application config → explicit opts

Explicit opts to new/1 always win. Application config provides per-environment defaults. Module defaults are sensible out of the box.

# config/runtime.exs
config :omni_tools, Omni.Tools.Bash,
  timeout: 60_000,
  max_output: 100_000

# At call site — :dir is required, :timeout overrides the app config
Omni.Tools.Bash.new(dir: "/app", timeout: 10_000)

No application config is required — every tool works with zero config and sensible defaults.

Documentation

Full API reference is available on HexDocs.

License

This package is open source and released under the Apache-2 License.

© Copyright 2026 Push Code Ltd.