Getting started¶
Installation¶
Wallah is built from source with Cargo. The toolchain version is pinned by
rust-toolchain.toml, so a recent stable Rust (installed via
rustup) is all you need to get started.
A debug build lands at target/debug/wa and a release build at
target/release/wa. Copy that binary somewhere on your PATH (or add the
directory to PATH) so you can invoke it as wa.
Optional dependencies¶
- ripgrep (
rgonPATH) is recommended: thegrepandfindtools are only offered to the model when it is installed. - rtk is recommended if you want to cut token usage on shell commands (see Reducing token usage with rtk).
- The
claudeCLI is required only for theclaude-codeprovider, which runs under your Claude subscription. The nativeanthropicprovider talks to the Anthropic API directly with an API key and does not need it.
Configuring providers¶
Wallah reads its configuration from ~/.config/wallah/config.lua. This is a
shingetsu script which allows you to flexibly define
your configuration in code.
The config defines a
discover_providers event handler
to register the providers you want to use, and optionally names a default
provider, default model, and a set of favourite models to float to the top of
the /model picker.
A minimal config that wires up Claude Code, an OpenAI-compatible endpoint, and a local Ollama server:
agent.on('discover_providers', function(inventory)
-- Claude Code, running under your Claude subscription via the `claude` CLI.
inventory:add_claude_code {
name = 'claude-code',
billing = 'subscription',
}
-- The native Anthropic API, talking to the endpoint directly with an API
-- key. Unlike claude-code, this needs no `claude` CLI. Source the key from
-- the environment rather than hard-coding it.
inventory:add_anthropic {
name = 'anthropic',
api_key = os.getenv('ANTHROPIC_API_KEY'),
}
-- Any OpenAI-compatible endpoint (OpenAI itself, OpenRouter, vLLM, ...).
-- Source the key from the environment rather than hard-coding it.
inventory:add_openai {
name = 'openai',
base_url = 'https://api.openai.com/v1',
api_key = os.getenv('OPENAI_API_KEY'),
}
-- OpenRouter is also just an OpenAI-compatible endpoint: point `base_url` at
-- its API and supply your OpenRouter key.
inventory:add_openai {
name = 'openrouter',
base_url = 'https://openrouter.ai/api/v1',
api_key = os.getenv('OPENROUTER_API_KEY'),
}
-- Google Gemini exposes an OpenAI-compatible endpoint, so it too is just an
-- `add_openai` provider: point `base_url` at Gemini's OpenAI-compatible API
-- and supply your Gemini key. Models are named as usual, e.g.
-- `gemini/gemini-2.5-pro` or `gemini/gemini-2.5-flash`.
inventory:add_openai {
name = 'gemini',
base_url = 'https://generativelanguage.googleapis.com/v1beta/openai',
api_key = os.getenv('GEMINI_API_KEY'),
}
-- A local Ollama server. A bare local instance needs no api_key.
inventory:add_ollama {
name = 'ollama',
base_url = 'http://localhost:11434',
}
-- Optional: pick the default provider and model used when `--provider` and
-- `--model` are omitted. If unset, the first provider added is the default.
inventory:set_default_provider('claude-code')
inventory:set_default_model('claude-code/claude-sonnet-4-6')
-- Optional: `provider/model` references to float to the top of `/model`.
inventory:add_favourite_models {
'claude-code/claude-sonnet-4-6',
'openai/gpt-4o',
'ollama/llama3.1:8b',
}
end)
os.getenv above is the standard Lua os module.
Each add_* call is a method on the
Inventory handed to
the handler, and accepts an optional billing field, either 'subscription'
or 'metered', which only affects how cost is displayed. It defaults to
'metered' everywhere except Ollama, where a local server defaults to
'subscription'.
Wallah does not create the config for you, and it reports an error if the file
is missing, so on a fresh install create ~/.config/wallah/config.lua (and its
parent directory) yourself before the first run. Once it is in place, wa
list-providers is a quick way to confirm it loads.
With a config in place, launch the interactive TUI by running wa.