A lightweight bash-based AI coding agent that uses the OpenRouter API with native tool calls.
┌─────────────────────────────────────────────────────────────────┐
│ agent.sh │
│ Tool-Call Based CLI Agent │
└─────────────────────────────────────────────────────────────────┘
┌──────────────────┐
│ User Input │
│ "› ___" │
└────────┬─────────┘
│ append {role:"user"}
▼
┌──────────────────────────────────────────────────┐
│ build_messages(): │
│ • System prompt (cache_control) │
│ • history.json, last msg (cache_control) │
└────────────────────┬─────────────────────────────┘
│
▼
┌─────────────┐ ┌─────────────────┐
│ agent.sh │──curl──▶│ OpenRouter API │
│ + TOOLS │◀────────│ (Claude model) │
└──────┬──────┘ └─────────────────┘
│
├──────────────────────────────┐
▼ ▼
┌──────────────┐ ┌───────────────┐
│ tool_calls │ │ Text reply │
│ run_script │ │ "● ..." │
└──────┬───────┘ └───────┬───────┘
│ for each call │
▼ ▼
┌──────────────────────┐ back to "›"
│ Show script │
│ Run? (y/n/a=all) │── n ──▶ "[Skipped by user]"
└────────┬─────────────┘ │
│ y / a │
▼ │
┌──────────────────────┐ │
│ bash -c "$script" │ │
│ (stdout + stderr) │ │
└────────┬─────────────┘ │
▼ │
┌──────────────────────────────────┐ │
│ append {role:"tool", │◀───┘
│ tool_call_id, content} │
└────────┬─────────────────────────┘
│
└──▶ call API again (loop until text reply)
├── agent.sh # Main agent (native tool calls)
├── agent-no-tools.sh # Alternative agent without tool calls: extracts bash from ```bash blocks,
│ # feeds output back via result.txt
├── system_prompt.txt # Customizable system instructions
├── history.json # Conversation memory (user/assistant/tool messages)
├── result.txt # Last script output (agent-no-tools.sh, created on run)
├── generated_script.sh# Last generated script (agent-no-tools.sh, created on run)
└── test.sh # Offline tests (fake curl)
- Set your OpenRouter API key:
export OPENROUTER_API_KEY="your-key"- Run the agent:
bash agent.sh- Describe tasks in plain English
- Review each script and answer
y(run),n(skip), ora(run this and all following without asking) - Type
exitto quit
AUTO=1 bash agent.shecho "[]" > history.json- curl
- jq
- coreutils
Offline tests (no API key or network needed; a fake curl replays canned responses):
bash test.sh| Variable | Default | Description |
|---|---|---|
| OPENROUTER_API_KEY | (required) | Your OpenRouter API key |
| MODEL | anthropic/claude-opus-5.5 | Model to use |
| ENDPOINT | https://openrouter.ai/api/v1/chat/completions | API endpoint |
| SYSTEM_PROMPT_FILE | system_prompt.txt | System prompt path |
| HISTORY_FILE | history.json (agent.sh), history-no-tools.json (agent-no-tools.sh) | Conversation history path |
| RESULT_FILE | result.txt | Last script output (agent-no-tools.sh) |
| SCRIPT_FILE | generated_script.sh | Last generated script (agent-no-tools.sh) |
| AUTO | 0 | Set to 1 to auto-execute scripts |
- User describes a task in natural language; it is appended to history
- Agent builds messages: system prompt + full history (prompt-cache markers on the system prompt and last message)
- Sends request to OpenRouter with the
run_scripttool definition - AI responds with either:
- Tool call(s): each script is shown for confirmation, executed with
bash -c, and its output appended as arole:"tool"message, then the API is called again - Text: displayed to the user, ending the turn
- Tool call(s): each script is shown for confirmation, executed with
- History persists in
history.jsonacross sessions - Prompt caching reduces API costs on repeated context