A terminal LLM agent written in assembly. 16 KB on Linux — no libc, no
interpreter.
It streams, runs shell commands, and remembers the conversation.
curl -fsSL https://raw.githubusercontent.com/adilkairolla/smallest-agent/main/install.sh | shThe one-liner above downloads the release tarball for your platform, checks it
against the published SHA256SUMS, and installs to /usr/local/bin — or
~/.local/bin if that needs a password it cannot ask for. It is a short shell
script; read it first if you would rather:
curl -fsSL https://raw.githubusercontent.com/adilkairolla/smallest-agent/main/install.sh | lessPick the version or the location:
curl -fsSL .../install.sh | VERSION=1.0.0 PREFIX=~/.local shOr take the tarball yourself from releases — agent-VERSION-OS-ARCH.tar.gz,
alongside SHA256SUMS:
tar -xzf agent-1.0.0-linux-x86_64.tar.gz
sudo install -m 755 agent-1.0.0-linux-x86_64/agent /usr/local/bin/agentmake # clang or gcc, picks the source from uname -m
sudo make install # PREFIX=/usr/local, honours DESTDIR
make test # 425 assertions against a mock server
make test-linux # the same suite in a container (PLATFORM=linux/amd64)make dist builds the release tarball for the machine you are on.
curl, jq, and sh on PATH. Preinstalled on macOS; on minimal Linux
images, install them.
It does not do the hard parts itself: curl handles TLS and HTTP, jq handles
all JSON. Both are exec'd, never linked, so they cost nothing in the binary.
Linux builds are -nostdlib -static — no libc, no interpreter.
| macOS arm64 | macOS x86-64 | Linux arm64 | Linux x86-64 | |
|---|---|---|---|---|
| stripped binary | 34,200 B | 21,496 B | 16,832 B | 16,752 B |
export AGENT_ENDPOINT=https://openrouter.ai/api/v1/chat/completions
export AGENT_TOKEN=sk-...
export AGENT_MODEL=anthropic/claude-sonnet-4.5
agent # interactive
agent --prompt 'what changed today?' > out.txt # one answer, then exitPass the token in the environment, not as --token: ps shows argv to every
user on the machine.
Every flag has an AGENT_* environment fallback spelled from the flag —
--top-p is AGENT_TOP_P, --max-tools is AGENT_MAX_TOOLS. Run
agent --help for the full list.
--prompt TEXT answers once and exits, printing nothing but the reply. Tools
still run. Exit status is 0 for an answer, 1 for a failed turn or an exhausted
--max-tools cap, so it composes:
agent --prompt "$TASK" || echo 'no answer' >&2The bash tool runs whatever the model asks for. Three flags constrain it, and
a refusal is reported back to the model as a tool result:
--deny 'rm -rf|curl.*\|sh' # refuse commands matching
--allow '^(git|ls|cat) ' # refuse commands not matching
--confirm # ask on the terminal, y/N/a/help /clear /undo /retry /cost /tools, Ctrl-D to quit.
Each run gets its own directory under .agent/, named by process id, so two
agents in one working directory never share a transcript. .agent/cur points
at the newest; --resume continues it. Sessions idle for 7 days are removed.
The transcript is messages.jsonl, one JSON message per line.
src/agent_arm64.S src/agent_amd64.S per-architecture entry points
src/agent.inc shared: the shell and jq programs, flag tables, buffers
src/syscalls_*.inc the libc functions the Linux build replaces
tests/run.sh the suite; tests/mock_server.py is the endpoint it uses
install.sh what the one-liner runs
demo/ the recording pipeline behind the GIF above
MIT — see LICENSE.
