diff --git a/README.md b/README.md index 6f3a088..2cf65f5 100644 --- a/README.md +++ b/README.md @@ -37,9 +37,51 @@ How simple, lightweight and reliable can an agent be? Ask the agent a question (no quotes needed for simple text): ```sh -./ai.sh what is the capital of Japan? -./ai.sh -v what is 2 plus 2 -./ai.sh -m gpt-4o "write a hello world program in python. save it in ~/" +$ ./ai.sh what is the capital of Japan? +The capital of Japan is Tokyo. +``` + +```sh +$ ./ai.sh what is 2 plus 2 +2 plus 2 is 4. +``` + +```sh +$ ./ai.sh write a hello world program in python. save it in ~/ +I've created a Python hello world program at ~/hello.py: + +```python +print("Hello, World!") +``` + +You can run it with `python3 ~/hello.py`. +``` + +With options: + +```sh +$ ./ai.sh -v what is 2 plus 2 +[loaded /home/user/.aish/log.jsonl — 3 messages, $0.0001 spent] +[step 1] (reasoning) The user wants to know 2 plus 2. +[done] 2 plus 2 is 4. +2 plus 2 is 4. +[finished — 1 steps, $0.0001 spent] +``` + +```sh +$ ./ai.sh -m gpt-4o "write a hello world program in python. save it in ~/" +I've created a Python hello world program at ~/hello.py: + +```python +print("Hello, World!") +``` + +You can run it with `python3 ~/hello.py`. +``` + +```sh +$ ./ai.sh -R what is the capital of France +The capital of France is Paris. ``` The agent can run shell commands, read files, and execute multi-step @@ -51,9 +93,23 @@ Describe a command in English. The LLM generates the shell command, prints it, and runs it in your terminal: ```sh -./ai.sh -c show me all files including hidden ones -./ai.sh -c find all python files modified this week -./ai.sh -c show me disk usage sorted by size +$ ./ai.sh -c show me all files including hidden ones +$ ls -a +. .. .git .gitignore README.md ai.sh +``` + +```sh +$ ./ai.sh -c find all python files modified this week +$ find . -name '*.py' -mtime -7 +./scripts/build.py +./src/main.py +``` + +```sh +$ ./ai.sh -c show me disk usage sorted by size +$ du -sh * | sort -rh +4.0M ai.sh +2.0M README.md ``` ### Autonomous mode @@ -61,7 +117,16 @@ prints it, and runs it in your terminal: Give the agent a goal and let it run until done or budget exhausted: ```sh -./ai.sh -a "explore the codebase and summarize the architecture" +$ ./ai.sh -a "explore the codebase and summarize the architecture" +[autonomous mode — goal: explore the codebase and summarize the architecture] +[step 1] $ ls -la +[step 2] $ cat ai.sh | head -50 +[step 3] $ wc -l ai.sh +[done] This is a single-file shell script AI agent. It uses curl to call +an LLM API and jq to parse JSON. The script has three main parts: config +loading, an agent loop that calls the API and executes tool calls, and +a logger that writes append-only JSON lines. No build step required. +[finished — 3 steps, $0.0003 spent] ``` ### Initialize a local agent @@ -70,7 +135,10 @@ By default, aish stores everything globally in `~/.aish/`. To create a self-contained agent for a specific project: ```sh -./ai.sh -i +$ ./ai.sh -i +Initialized /home/user/myproject/.aish + Edit /home/user/myproject/.aish/config.json to change model, budget, etc. + Edit /home/user/myproject/.aish/system_prompt.txt to customize the agent's instructions. ``` This creates a `.aish/` directory in the current folder with its own @@ -83,18 +151,52 @@ The agent's answer goes to stdout; status messages go to stderr. So you can pipe the answer into other commands: ```sh -./ai.sh what is the capital of Japan | wc -w -./ai.sh list all python files in this dir | grep test -./ai.sh what is 2+2 > answer.txt +$ ./ai.sh what is the capital of Japan | wc -w +5 +``` + +```sh +$ ./ai.sh list all python files in this dir | grep test +./test_runner.py +./test_config.py +``` + +```sh +$ ./ai.sh what is 2+2 > answer.txt +$ cat answer.txt +2 + 2 is 4. ``` You can also pipe input in. If no message is given on the command line, stdin becomes the message. If both are given, stdin is appended: ```sh -echo "explain this error" | ./ai.sh -cat error.log | ./ai.sh explain this error -git diff | ./ai.sh -c generate a commit message +$ echo "explain this error" | ./ai.sh +The error message indicates a missing semicolon at the end of line 12. +Add a `;` after the closing brace to fix it. +``` + +```sh +$ cat error.log | ./ai.sh explain this error +Looking at the error log, there are three issues: + +1. Line 5: NullPointerException — the variable `config` was never + initialized before use. +2. Line 12: FileNotFound — the path `/etc/app.conf` doesn't exist on + this system. +3. Line 18: Timeout — the API call took longer than 30 seconds. + +The root cause is likely the missing config file. Create it and the +other errors should resolve. +``` + +```sh +$ git diff | ./ai.sh -c generate a commit message +$ git commit -m "Fix: handle empty config file gracefully + +- Add null check before reading config +- Fall back to defaults when config is missing +- Log warning when using fallback values" ``` ## Quick start diff --git a/readme2.md b/readme2.md deleted file mode 100644 index 2cf65f5..0000000 --- a/readme2.md +++ /dev/null @@ -1,314 +0,0 @@ ---- -slug: aish -title: AI.sh -summary: A simple shell script agent -image: https://example.com/cover.png -tags: [ai, agent, aiharness] ---- - -# aish - -``` - , , - (\____/) - (_oo_) - (O) -- ai.sh - __||__ \) - []/______\[] / - / \______/ \/ - / /__\ - (\ /____\ -``` - -## Idea -How simple, lightweight and reliable can an agent be? - -## Solution -- One shell script. -- Use tried and tested linux programs like curl and jq. -- Log file is simple so you can read it, and it is used for agent context. -- Just give the agent shell access. No special commands, no context bloat. -- Fast -- This repo has 2 files. - - -## Usage - -Ask the agent a question (no quotes needed for simple text): - -```sh -$ ./ai.sh what is the capital of Japan? -The capital of Japan is Tokyo. -``` - -```sh -$ ./ai.sh what is 2 plus 2 -2 plus 2 is 4. -``` - -```sh -$ ./ai.sh write a hello world program in python. save it in ~/ -I've created a Python hello world program at ~/hello.py: - -```python -print("Hello, World!") -``` - -You can run it with `python3 ~/hello.py`. -``` - -With options: - -```sh -$ ./ai.sh -v what is 2 plus 2 -[loaded /home/user/.aish/log.jsonl — 3 messages, $0.0001 spent] -[step 1] (reasoning) The user wants to know 2 plus 2. -[done] 2 plus 2 is 4. -2 plus 2 is 4. -[finished — 1 steps, $0.0001 spent] -``` - -```sh -$ ./ai.sh -m gpt-4o "write a hello world program in python. save it in ~/" -I've created a Python hello world program at ~/hello.py: - -```python -print("Hello, World!") -``` - -You can run it with `python3 ~/hello.py`. -``` - -```sh -$ ./ai.sh -R what is the capital of France -The capital of France is Paris. -``` - -The agent can run shell commands, read files, and execute multi-step -tasks. Context is saved and resumed on subsequent calls. - -### Command mode - -Describe a command in English. The LLM generates the shell command, -prints it, and runs it in your terminal: - -```sh -$ ./ai.sh -c show me all files including hidden ones -$ ls -a -. .. .git .gitignore README.md ai.sh -``` - -```sh -$ ./ai.sh -c find all python files modified this week -$ find . -name '*.py' -mtime -7 -./scripts/build.py -./src/main.py -``` - -```sh -$ ./ai.sh -c show me disk usage sorted by size -$ du -sh * | sort -rh -4.0M ai.sh -2.0M README.md -``` - -### Autonomous mode - -Give the agent a goal and let it run until done or budget exhausted: - -```sh -$ ./ai.sh -a "explore the codebase and summarize the architecture" -[autonomous mode — goal: explore the codebase and summarize the architecture] -[step 1] $ ls -la -[step 2] $ cat ai.sh | head -50 -[step 3] $ wc -l ai.sh -[done] This is a single-file shell script AI agent. It uses curl to call -an LLM API and jq to parse JSON. The script has three main parts: config -loading, an agent loop that calls the API and executes tool calls, and -a logger that writes append-only JSON lines. No build step required. -[finished — 3 steps, $0.0003 spent] -``` - -### Initialize a local agent - -By default, aish stores everything globally in `~/.aish/`. To create a -self-contained agent for a specific project: - -```sh -$ ./ai.sh -i -Initialized /home/user/myproject/.aish - Edit /home/user/myproject/.aish/config.json to change model, budget, etc. - Edit /home/user/myproject/.aish/system_prompt.txt to customize the agent's instructions. -``` - -This creates a `.aish/` directory in the current folder with its own -config, system prompt, and log. While `.aish/` exists, all storage is -local to that directory. Remove it to return to global mode. - -### Piping - -The agent's answer goes to stdout; status messages go to stderr. So you -can pipe the answer into other commands: - -```sh -$ ./ai.sh what is the capital of Japan | wc -w -5 -``` - -```sh -$ ./ai.sh list all python files in this dir | grep test -./test_runner.py -./test_config.py -``` - -```sh -$ ./ai.sh what is 2+2 > answer.txt -$ cat answer.txt -2 + 2 is 4. -``` - -You can also pipe input in. If no message is given on the command line, -stdin becomes the message. If both are given, stdin is appended: - -```sh -$ echo "explain this error" | ./ai.sh -The error message indicates a missing semicolon at the end of line 12. -Add a `;` after the closing brace to fix it. -``` - -```sh -$ cat error.log | ./ai.sh explain this error -Looking at the error log, there are three issues: - -1. Line 5: NullPointerException — the variable `config` was never - initialized before use. -2. Line 12: FileNotFound — the path `/etc/app.conf` doesn't exist on - this system. -3. Line 18: Timeout — the API call took longer than 30 seconds. - -The root cause is likely the missing config file. Create it and the -other errors should resolve. -``` - -```sh -$ git diff | ./ai.sh -c generate a commit message -$ git commit -m "Fix: handle empty config file gracefully - -- Add null check before reading config -- Fall back to defaults when config is missing -- Log warning when using fallback values" -``` - -## Quick start - -```sh -# 1. Install dependencies -sudo apt install curl jq coreutils # Debian/Ubuntu - -# 2. Add your API key (get one from https://ppq.ai) -cat > ~/.aish.conf <<'EOF' -DEFAULT_API_KEY="sk-your-key-here" -EOF -chmod 600 ~/.aish.conf - -# 3. Run it -./ai.sh what is the capital of Japan -``` - -That's it. No build step, no install script, no daemon. - -## Options - -| Short | Long | Description | -|-------|------|-------------| -| `-c` | `--cmd` | Command mode (generate and run a shell command) | -| `-a` | `--autonomous` | Autonomous mode (run until done or budget exhausted) | -| `-i` | `--init` | Create local `.aish/` with defaults, exit | -| `-x` | `--clear` | Clear the log file and exit | -| `-v` | `--verbose` | Show status lines | -| `-m` | `--model` | Override model | -| `-k` | `--api-key` | API key (or set `PPQ_API_KEY`) | -| `-C` | `--max-cost` | Override max cost (USD) | -| `-s` | `--max-steps` | Override max steps | -| `-t` | `--timeout` | Override overall timeout (seconds) | -| `-T` | `--cmd-timeout` | Override per-command timeout (seconds) | -| `-r` | `--resume` | Resume from existing log (default: yes) | -| `-R` | `--no-resume` | Start fresh (ignore existing log) | -| `-h` | `--help` | Show help | - -## Configuration - -### API key - -Create `~/.aish.conf` with your key: - -```sh -cat > ~/.aish.conf <<'EOF' -DEFAULT_API_KEY="sk-your-key-here" -EOF -chmod 600 ~/.aish.conf -``` - -This file lives in your home directory, outside the repo, and is never -committed. Any `DEFAULT_*` variable from `ai.sh` can be overridden there. - -### Config priority - -Settings are resolved in this order (first match wins): - -1. CLI flags (`-m`, `-C`, `-s`, etc.) -2. Local `.aish/config.json` (if `.aish/` exists in current directory) -3. Global `~/.aish/config.json` -4. `~/.aish.conf` shell vars -5. Built-in defaults in `ai.sh` - -### Storage - -**Global mode** (default): `~/.aish/` holds config, system prompt, and -log. The agent has shared global memory — conversations from any -directory are logged to the same file and resumed on subsequent calls. - -**Local mode**: Run `./ai.sh -i` to create a `.aish/` in the current -directory. While it exists, that directory uses its own config, prompt, -and log instead of the global ones. - -## Dependencies - -- `curl` -- `jq` -- coreutils (`date`, `mkdir`, `chmod`, `head`, `cat`, `printf`, `mktemp`, `timeout`, `sync`, `basename`, `sleep`, `wc`, `tail`, `sed`, `grep`) - -```sh -# Debian / Ubuntu -sudo apt install curl jq coreutils - -# Fedora / RHEL -sudo dnf install curl jq coreutils - -# Arch -sudo pacman -S curl jq coreutils - -# macOS (Homebrew — coreutils provides GNU versions like `timeout`) -brew install curl jq coreutils -``` - -## Log format - -Each line in `log.jsonl` is JSON with a `source` field: - -| source | event | who | -|--------|-------|-----| -| `user` | `user_input` | you | -| `model` | `response` | the AI | -| `aish` | `exec` | script ran a command | -| `aish` | `api_error` | script detected an error | - -## Warning - -**This agent has full shell access.** It can run any command on your -system — read files, write files, delete data, install software, make -network requests. There are no sandboxing or permission restrictions. - -Run it only on a computer, VM, or Qube that is dedicated to agent use. -Do not run it on a machine with sensitive data or credentials you cannot -afford to lose.