A coding agent you can read
Fast, correct, autonomous.
Pick two.
Every coding agent trades speed, correctness, and how much it does on its own. elelem lets you choose: the model, the tools, and what needs your approval. It aims to be the Vim of coding agents: a core small enough to read in an afternoon, and plugins for everything else.
gem install elelem elelem-builtins elelem-ollamaThen run elelem chat -p ollama. Needs Ruby 4.0 and a running Ollama server.
> the date parser drops time zones. find out why and fix it.
+ grep({"pattern" => "parse_date", "path" => "lib/"})
+ read({"path" => "lib/calendar/parser.rb"})
+ edit({"path" => "lib/calendar/parser.rb", "old" => "Time.parse(date)", "new" => "Time.parse(input)"})
+ execute({"command" => "bundle exec rspec spec/parser_spec.rb"})
12 examples, 0 failures
The parser called Time.parse on the date portion only, so the
offset was discarded. It now parses the full string and keeps the zone.An illustration of a session. Tools shown come from elelem-builtins and elelem-tools.
Principles
Small enough to read.
You hand an agent your codebase and a shell. You should be able to read the agent. elelem's core fits in an afternoon: the loop, the conversation, the toolbox, the plugin registry. No framework underneath.
Everything else is a plugin.
The core is closed for modification and open for extension. Models, tools, and slash commands are plugins, and even the terminal UI can be replaced. A plugin is a Ruby file that calls
Elelem.configure. Drop it in.agents/plugins/and it loads. Package it as a gem to share it.Your model, your machine.
Use Claude through the Anthropic API, or Ollama. Or load a GGUF file straight into the elelem process with llama.cpp and keep every token on your laptop. No server, no API key, no network.
Unix at heart.
elelem chatopens a session.elelem askreads a pipe and writes the reply to stdout:git diff | elelem ask -p ollama "write a commit message".
How it fits together
A small loop in the middle. Plugins on every side.
The core sends the conversation to a provider, runs the tools the model asks for, and repeats until the model is done. Everything it talks to is swappable.
How the agent loop worksExtend it
Your plugins live in your repos.
elelem loads every Ruby file in ~/.agents/plugins/,
then .agents/plugins/ in the project you're in. That is
the whole plugin system: no registry, no install step, no config
file.
Keep personal tools in your dotfiles, and every machine you work on
has them. Commit project tools next to the code, and everyone on
the team gets them with git pull. Share one as a gem
when it's ready.
~/dotfiles/agents/ # symlinked to ~/.agents
├── AGENTS.md # how you like to work
└── plugins/
└── word_count.rb # yours, everywhere
~/src/shop/
├── AGENTS.md # how this project works
└── .agents/plugins/
└── deploy.rb # the team's, in gitElelem.configure do |config|
config.setup(:word_count) do |agent|
agent.toolbox.add("word_count",
description: "Count words in a file",
params: { path: { type: "string" } },
required: ["path"]) do |args|
{ words: File.read(args["path"]).split.size }
end
end
endElelem.configure do |config|
config.provider(:my_model) do |model: nil, **|
MyModel::Provider.new(model: model)
end
endProviders are plugins too. Register one and run
elelem chat -p my_model.
Write a provider
- Run elelem fully offline Run a GGUF model inside the elelem process with elelem-llama, with GPU offload and a context size you choose.
- Write a tool plugin Add a tool the model can call, in one Ruby file, then package it as a gem.
- Write a provider plugin Connect elelem to a new model API by implementing one method, fetch, that streams events back to the agent.
Start with one command.
gem install elelem elelem-builtins elelem-ollamaRequires Ruby 4.0 or later. Then run elelem chat -p ollama. Installation details
Who builds elelem, and why: Why elelem · About