A minimal AI agent loop written entirely in bash (~76 lines). It calls LLMs via OpenRouter, DeepSeek, or OpenAI, runs tools (bash, read, write, edit), and can import skills from the pi agent skills library.
| File | Lines | Purpose |
|---|---|---|
agent.sh |
76 | Main agent loop — bootstrap, config, tool runner, REPL |
skills.sh |
63 | Skill importer — lists and loads pi agent skills |
pipefail support)brew install jq or apt install jq)git clone git@github.com:kane-mar/bash-agent.git
cd bash-agent
# Copy and edit your API key
cp .env.example .env
Set at least one of these environment variables in .env or your shell profile:
# Option A: OpenRouter (recommended — access many models)
export OPENROUTER_API_KEY="sk-or-v1-..."
# Option B: DeepSeek
export DEEPSEEK_API_KEY="sk-..."
# Option C: OpenAI
export OPENAI_API_KEY="sk-..."
Tip: If you have multiple keys, set
PROVIDER=openai(ordeepseek/openrouter) to pick which one to use. If unset, the agent auto-detects in order: OpenRouter → DeepSeek → OpenAI.
./agent.sh
You’ll see a prompt like:
=== Agent [provider:openrouter model:openrouter/free skills:none] ===
>
> what files are in this directory?
The LLM will use its tools to explore, and you’ll see tool calls and results stream back:
◆ bash {"command":"ls -la"}
total 32
...
Type exit to quit.
Skills extend the agent with specialized capabilities from the pi agent skills library. Install the skills library separately, then:
source ./skills.sh # list available skills
source ./skills.sh clean-code # import a skill
./agent.sh # start the agent with the skill loaded
When a skill is imported, its instructions are automatically injected into the system prompt so the LLM knows how to use it.
agent.shAn interactive REPL that:
Environment variables:
| Variable | Default | Description |
|---|---|---|
PROVIDER |
(auto-detect) | Force a provider: openrouter, deepseek, or openai |
MODEL |
(per provider, see below) | Model ID (e.g. gpt-4o, deepseek-v4-flash) |
SYSTEM_PROMPT |
You are a coding agent... Work inside \$PWD. Be direct and thorough. |
System prompt |
OPENROUTER_API_KEY |
— | API key for OpenRouter |
DEEPSEEK_API_KEY |
— | API key for DeepSeek |
OPENAI_API_KEY |
— | API key for OpenAI |
Default models per provider:
| Provider | Default Model |
|---|---|
| OpenRouter | openrouter/free |
| DeepSeek | deepseek-v4-flash |
| OpenAI | gpt-4o |
All providers are accessed via OpenAI-compatible chat completions endpoints.
Tool calls — the LLM can use these tools:
bash — run any bash commandread — read a filewrite — write content to a file (overwrites)edit — replace exact text in a fileType exit to quit.
skills.shImport pi agent skills. Must be sourced (not executed) so the environment persists.
source ./skills.sh # list all skills
source ./skills.sh clean-code # import one skill
source ./skills.sh kanban-board tdd # import multiple
source ./skills.sh --help # usage
bash 3+ (for pipefail support)curl — API callsjq — JSON manipulationOPENROUTER_API_KEY, DEEPSEEK_API_KEY, or OPENAI_API_KEY┌─────────────────────────────────────┐
│ agent.sh (REPL loop) │
│ │
│ > your input │
│ ↓ │
│ ┌─────────────────────────┐ │
│ │ LLM (OpenRouter / │ │
│ │ DeepSeek / OpenAI) │ │
│ │ ← text or tool calls │ │
│ └─────────┬───────────────┘ │
│ ↓ │
│ tool calls → run() → result │
│ result → history → back to LLM │
│ │
│ skills.sh ← loaded before start │
└─────────────────────────────────────┘
agent.sh runs in six sequential phases:
.env, auto-detects provider from available API keysSYSTEM_PROMPT (base + optional skill injection) and TOOLS JSONrun() dispatches bash, read, write, editexit or Ctrl+D quitsMIT