A modular, self-correcting autonomous AI agent for Termux. Orion runs entirely on-device, uses free cloud LLM APIs for inference, and exposes a terminal chat loop with tool use, persistent memory, voice I/O, chunk-based context compression, and a full agentic execution layer.
- Multi-provider LLM fallback — Cycles through Google Gemini, OpenRouter, Groq, NVIDIA, and Ollama (cloud & local) models automatically. Rate-limited or invalid keys rotate to the next key for the same model; a transient server error (500/502/503/504) skips straight to the next model instead of retrying every key for it.
- Tool use —
run_code,read_file,write_file,web_scrape,save_memory,retrieve_memory,index_files,intermediate_print,sleep_mode. - Enhanced Tool Suite — 7 new utility tools added:
search_in_files- recursive file content search with advanced options and filterslist_directory- directory listing with configurable depthsearch_files- filename pattern matching with wildcard supportrename_file- safe file/directory rename/move with protectiondelete_file- secure file/directory deletion with safety checkshttp_request- HTTP client for API calls with comprehensive headersget_datetime- current time information in multiple formats
- Tool call transparency — every tool call prints a collapsed one-line status by default;
Ctrl+O(or/expand) reveals the full command/path and complete output. See Tool Call Display. - Chunk-based context memory — Conversation history is divided into stable numbered chunks. Old chunks are progressively compressed (short → micro → one-line summary) in a background thread. Raw chunks are permanently stored and retrievable by ID via
retrieve_chunk/list_chunkstool calls. - Persistent memory — Two-tier RAG system: personal facts (
memories.txt) and indexed code/docs (indexed_memory.txt). - Agentic execution —
/agenttriggers a Supervisor → Worker → Critic loop. Tasks are planned viaagent/planner.py, executed with one retry, and persisted across restarts throughdata/state.json. - Enhanced Agent Interface — Persistent agent mode state with direct prompts via
/agent [prompt]syntax, clean toggle commands (/normal,/chat),/expand//collapsefor tool-detail visibility, and improved history tracking. - Modern Terminal Rendering — Enhanced CLI code block styling with open-right gutter design, cleaner borders, and improved terminal integration.
- Orchestration —
orchestration/provides multi-process task delegation (Manager→Worker) over amultiprocessing.QueueIPC channel. - Self-correction —
reflection/logs every execution outcome and automatically retries failures viaattempt_correction(). - Voice I/O — Optional STT via Termux-STT and TTS via
edge-tts+mpv. - WhatsApp integration — Send/receive messages and enable busy mode via Termux-WP.
- Safe execution —
permissions.pyvalidates every shell command before dispatch. - Autonomous mode (opt-in) —
/autonomous onbypasses the permission layer entirely; off by default. See Autonomous Mode. - Advanced LLM Client — Enhanced model slot organization with agent-specific slots, advanced error handling for API failures, reasoning budget exhaustion management, native reasoning metadata preservation, and tool execution timeout tracking.
- Notifications (opt-in) — When
notify: trueinconfig/config.json, a system notification is sent viatermux-notificationafter agent tasks complete (both inline/agent [prompt]and persistent agent mode).
| Dependency | Install |
|---|---|
| Python 3.10+ | pkg install python |
| Rust / cmake / clang | pkg install rust cmake clang which |
openai SDK |
pip install openai |
beautifulsoup4 |
pip install beautifulsoup4 |
requests |
pip install requests |
jsonschema |
pip install jsonschema |
| Voice (optional) | |
edge-tts |
pip install edge-tts |
mpv |
pkg install mpv |
| Termux-STT | See Termux-STT repo |
| WhatsApp (optional) | |
| Node.js | pkg install nodejs |
| Termux-WP | See Termux-WP repo |
# 1. Clone
git clone https://github.com/opsonusdh/Termux-AI ~/Termux-AI
cd ~/Termux-AI
# 2. Install dependencies
bash setup.sh
# 3. Add API keys
nano config/api.keysconfig/api.keys must be valid JSON:
{
"google": ["YOUR_GEMINI_KEY_1", "YOUR_GEMINI_KEY_2"],
"openrouter": ["YOUR_OPENROUTER_KEY"],
"groq": ["YOUR_GROQ_KEY"],
"nvidia": ["YOUR_NVIDIA_KEY"],
"ollama": ["YOUR_OLLAMA_KEY"],
"ollama-local": ["No-Need"]
}# 4. Run
python coreFree API keys: Google AI Studio • Groq Console • NVIDIA NIM • OPENROUTER • OLLAMA
~/Termux-AI
.
├── CHANGELOG.md
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE.md
├── PROJECT_STRUCTURE.md
├── README.md
├── SECURITY.md
├── agent
│ ├── __init__.py
│ ├── executor.py
│ ├── planner.py
│ ├── state_manager.py
│ └── validator.py
├── config
│ ├── api.keys
│ ├── api.keys.template
│ ├── capability_registry.json
│ ├── config.json
│ └── whatsapp_filters.json
├── core
│ ├── PROMPT.md
│ ├── __main__.py
│ ├── context_manager.py
│ ├── display_state.py
│ ├── input_handler.py
│ ├── interface.py
│ ├── llm_client.py
│ ├── permissions.py
│ ├── models.py
│ ├── renderer.py
│ ├── tools.py
│ └── whatsapp_manager.py
├── data
│ ├── cli_history
│ ├── sessions
│ ├── state.json
│ └── validator_schema.json
├── indexed_memory.txt
├── logs
│ ├── chunk_summaries.json
│ ├── chunks.jsonl
│ ├── history.jsonl
│ ├── log.txt
│ ├── problem.txt
│ └── whatsapp_log.jsonl
├── memories.txt
├── orchestration
│ ├── __init__.py
│ ├── manager.py
│ ├── orchestrator.py
│ ├── protocol.py
│ └── worker.py
├── paths.py
├── reflection
│ ├── __init__.py
│ ├── reflector.py
│ └── self_correction.py
├── setup.sh
└── tools
├── __init__.py
├── tool_wrappers.py
├── wrapper_termux_audio.py
├── wrapper_termux_battery_status.py
├── wrapper_termux_brightness.py
├── wrapper_termux_camera.py
├── wrapper_termux_clipboard.py
├── wrapper_termux_contacts.py
├── wrapper_termux_filepicker.py
├── wrapper_termux_location.py
├── wrapper_termux_sensors.py
├── wrapper_termux_sms.py
├── wrapper_termux_telephony.py
├── wrapper_termux_torch.py
├── wrapper_termux_vibrate.py
├── wrapper_termux_volume.py
├── wrapper_termux_wallpaper.py
└── wrapper_termux_wifi_scaninfo.py
The following options are available in config/config.json:
| Key | Type | Default | Description |
|---|---|---|---|
stt_path |
string | ~/Termux-AI/Termux-STT |
Path to Termux-STT module |
tts_enabled |
boolean | false |
Start with voice mode enabled |
use_groq |
boolean | false |
Use Groq TTS (faster, requires internet) |
show_details |
boolean | false |
Show expanded tool output by default |
autonomous |
boolean | false |
Bypass permission layer (opt-in) |
notify |
boolean | true |
Send system notification after agent tasks complete |
Example config.json:
{
"stt_path": "/data/data/com.termux/files/home/Termux-AI/Termux-STT",
"tts_enabled": false,
"use_groq": false,
"show_details": false,
"autonomous": false,
"notify": true
}YOU > /agent # run one step: resolve next task → worker → critic
YOU > /agent auto # loop until no pending tasks or a failure
YOU > /agent [prompt] # direct agent prompt with custom instructions
YOU > /normal # switch to standard chat mode
YOU > /chat # switch to conversational mode
Initialize a project and add tasks through normal chat — Orion uses the initialize_project and add_subtask tools. State persists in data/state.json and survives restarts.
When notify: true in config/config.json, a system notification is sent via termux-notification after:
/agent autocompletes its loop/agent [prompt]finishes an inline agent task- Persistent agent mode (
/agentmode) completes a task
The notification appears in the Android notification shade with title "Termux-AI Agent" and message "Agent task completed" (or "Agent auto task completed").
To disable: set "notify": false in config/config.json.
YOU > /autonomous on # bypass the permission layer entirely
YOU > /autonomous off # restore normal permission gating (default)
YOU > /autonomous status # check which mode is currently active
While autonomous mode is on, run_code never asks for approval — not for writes into core/, not for commands on the forbidden list, nothing. It's off by default, and the setting persists in config/config.json. Turn it on only when you trust what you're about to have the agent do: there's no per-action confirmation left to catch a mistake once it's on.
Every tool call prints to the terminal as it runs. Collapsed (the default) gives a one-line status per call; Ctrl+O / /expand reveals the full command or path plus the complete output (see Input Controls).
Running code (run_code) — collapsed:
[EXEC]
echo "step 1"
echo "step 2"
echo "step 3"
[TOOL DONE] (0.34s)
only the first three lines of the command are shown, and expanded shows the rest plus the full output:
[EXEC]
echo "step 1"
echo "step 2"
echo "step 3"
[OUTPUT]
step 1
step 2
step 3
[TOOL DONE] (0.34s)
Editing a file (write_file) / reading one (read_file) — collapsed shows nothing but the bare tag:
[EDITING FILE]
[TOOL DONE] (0.08s)
expanded:
[EDITING FILE] core/llm_client.py | mode: overwrite | lines: 10-25
[OUTPUT]
Wrote 16 lines to core/llm_client.py
[TOOL DONE] (0.08s)
Every other tool follows the same shape — [TOOL_NAME] collapsed, [TOOL_NAME] <key argument> plus a full [OUTPUT] block expanded — and a failed call closes with [TOOL ERROR] (Xs) instead of [TOOL DONE]. This is presentation only: the model always receives the complete tool output regardless of what the terminal happens to be showing.
| Key | Action |
|---|---|
Enter |
Send the message |
Ctrl+N |
Insert a newline, for multiline messages |
Ctrl+J |
Also sends (compatibility alias) |
Ctrl+O |
Toggle collapsed ↔ expanded tool/reasoning detail |
If a terminal doesn't pass a key combo through, the same toggle is available as a command, in both /agent and normal chat:
YOU > /expand # aliases: /details on, /view extended
YOU > /collapse # aliases: /details off, /view collapsed
Every conversation turn is stored as a numbered chunk in logs/chunks.jsonl. The active context window always stays small:
[system] Chunk 1: <one-line summary>
[system] Chunk 2: <micro summary>
[system] Chunk 3: <short summary>
[user / assistant / tool] ← raw chunk N-1
[user / assistant / tool] ← raw chunk N (most recent)
Older chunks are compressed progressively in a background thread. The model can call list_chunks and retrieve_chunk to pull full raw history when needed.
Requires Termux-STT, edge-tts, and mpv.
cd ~/Termux-AI
git clone https://github.com/opsonusdh/Termux-STT
cd Termux-STT && bash setup.shYOU > start voice # switch to voice input + TTS output
YOU > stop voice # switch back to keyboard
Set "tts_enabled": true in config/config.json to start in voice mode by default.
Requires Termux-WP and Node.js.
cd ~/Termux-AI
git clone https://github.com/opsonusdh/Termux-WP
cd Termux-WP && bash setup.shYOU > Enable busy mode on WhatsApp for the next hour.
Multiple keys per provider rotate round-robin and are retired on an invalid credential or a rate-limit; a transient server error (5xx) skips the rest of that model's keys entirely and moves to the next model instead:
{
"google": ["key1", "key2"],
"openrouter": ["key1"],
"groq": ["key1"],
"nvidia": ["key1"],
"ollama": ["your-ollama-key"],
"ollama-local": ["No-Need"]
}MIT. Do anything. Just don't be evil.