Handwave your problems away with LLMs.
Tired of trying to programmatically solve a problem that anyone could solve just by looking at it? Handwave it:
import Handwave.OpenAI
llm_if user_email, "looks suspicious?" do
{:error, :blocked}
else
create_user(user_email)
endWish your app could just tell user what to do with the error? Maybe it can:
iex> llm_rewrite(
%Req.Response{status: 401, body: "session token expired"},
"Tell user what to do without technical details"
)
"Your session has expired. Please log in again to continue."String module is too boring for you? I feel the same:
iex> llm_rewrite("HelloWorld", "convert to kebab-case", model: "gpt-4.1-nano")
"hello-world"Always wished Oban job would just do the right thing? I'm not here to judge:
import Handwave.OpenAI
@impl Oban.Worker
def process(job) do
# do things
catch
kind, error ->
formatted = Exception.format(kind, error, __STACKTRACE__)
formatted
|> llm_route([:snooze, :cancel, :error], "Snooze if it makes sense to try later, cancel if it's a lost cause, otherwise just error")
|> case do
:snooze -> {:snooze, 60}
:cancel -> {:cancel, error}
_ -> {:error, formatted}
end
endHandwave uses state-of-the-art, battle-tested, production-ready InstructorLite
library with a ✨comprehensive✨ test suite. It does not abstract different LLM
providers from you, but comes with support for most popular providers and makes
it easy to add support for your provider of choice.
Add handwave to your list of dependencies in mix.exs:
def deps do
[
{:handwave, "~> 0.1.0"}
]
endPut relevant api keys depending on what provider you want to use:
config :handwave,
openai_key: "api_key",
anthropic_key: "api_key",
gemini_key: "api_key"Use one of the existing providers (Handwave.OpenAI, Handwave.Claude,
Handwave.Gemini) or create your own.