Inspired by Craig Reynolds' Boids, Mantis applies a minimal local-rule approach to emergent behavior: simple rules, repeated continuously, produce adaptive autonomous behavior.
Mantis is a local-first Python agent runtime built around a three-rule loop:
ATTEND -> ASSOCIATE -> ACT.
It runs as a single process (mantis.py) for local experimentation and autonomous workflows.
Boids showed that complex flocking can emerge from a few local rules. Mantis takes the same design principle for agent autonomy:
ATTEND: capture signals (user input, tools, files, autonomous prompts).ASSOCIATE: connect the signal to memory and context.ACT: decide and execute the next concrete step.
Autonomy comes from this loop running continuously across many event sources, not from a single giant planner pass.
- Hybrid memory:
- Chroma vectors (
MEMORY_DIR) - SQLite FTS5 (
MEMORY_DIR/fts.db) - append-only markdown log (
.agent/MEMORY.md)
- Chroma vectors (
- Event-driven runtime with per-source FIFO lanes
- Autonomous heartbeat prompts (
AUTONOMOUS_INTERVAL_SEC) - Scheduled tasks from
tasks.md(daily/weekly natural-language schedules) - Command execution with:
- sync and async paths
- safety checks for unsafe/incomplete commands
- one-shot auto-repair on syntax-like failures
- outcome tracking in SQLite (
command_outcomestable)
- Shared shell journal awareness via
.agent/shell.log+.bashrchook - Filesystem watcher ingestion
- Web tools:
SEARCH(tiered DDG) andFETCH - Linux computer-use tools:
SCREENSHOT,CLICK,TYPE - Skills loaded from local files or URLs (
.agent/skills/*.md) - Optional Discord bridge (inbound prompts + outbound agent/activity feed)
python3 -m pip install -r requirements.txtCreate .env (optional but recommended), example:
LLM_BASE=http://localhost:8001/v1
MODEL=Qwen2.5-14B-Instruct-Q4_K_M.gguf
SOUL_PATH=soul.mdpython3 mantis.pyExit with Ctrl+C, or type exit / quit.
Start mantis.py, then type natural language requests at the you: prompt.
Mantis can answer directly or choose tool directives internally (COMMAND, READ, WRITE, etc.).
Output prefixes:
agent:direct reply to user input[mantis]:autonomous or non-user-triggered streams (autonomous,shell,search,skill,discord, etc.)
Every AUTONOMOUS_INTERVAL_SEC (default 300), Mantis self-prompts across rotating themes:
- unfinished work
- system/todo checks
- memory synthesis
- reminders/open questions
- curiosity search
Time-of-day modifiers are UTC-based (Good morning. / End of day check.).
tasks.md is parsed at runtime and checked every minute. Supported schedule patterns:
daily 8amdaily 14:30weekly sunday 10am
If tasks.md does not exist, Mantis creates a default one on boot.
Skills live in .agent/skills/*.md and are injected into the system prompt (truncated per skill).
They can be loaded via:
- local path:
SKILL: .agent/skills/my_skill.md - URL:
SKILL: https://.../my_skill.md
Skill updates are guarded: removing previously known commands requires repeated failure evidence (MIN_FAILURES_BEFORE_SKILL_UPDATE).
Set DISCORD_TOKEN and DISCORD_CHANNEL_ID to enable:
- inbound channel messages -> Mantis events
- outbound replies and activity events
- special phrase:
approve soultriggers a soul-write instruction
For each event:
ATTEND: enqueue event with source + timestampASSOCIATE: recall related memory and persist new eventACT: call the LLM and execute optional tool directives
Events are serialized per source lane (FIFO per source), improving concurrency without cross-source race conditions.
The agent can emit:
COMMAND: <shell command>READ: <filepath>WRITE: <filepath>followed by full file contentSCREENSHOT: <filepath>CLICK: <x> <y>TYPE: <text>SEARCH: <query>FETCH: <url>SKILL: <url-or-path>
Tool results are fed back into the event bus and memory.
Mantis executes commands by writing a temporary bash script and running it non-interactively.
- Short commands: synchronous execution
- Long/install-like commands (for example
pip install,npm install,apt install,git clone, multiline scripts): async execution - Interactive commands are blocked or replaced with safe alternatives where configured
- Unsafe/incomplete command fragments are skipped
Mantis also logs command/result pairs to SHELL_LOG.
- Python
3.10+ - OpenAI-compatible API:
POST /v1/chat/completions- optional
POST /v1/embeddingswhen using LLM embeddings
- Python packages in
requirements.txt
System tools used by some features:
curlscrot(screenshots)xdotool(mouse/keyboard automation)- Playwright Firefox runtime (
playwright install firefox)
mantis.py attempts setup for some Linux tools on startup; manual install may still be required.
Environment variables are loaded from .env via python-dotenv.
| Variable | Default | Description |
|---|---|---|
LLM_BASE |
http://localhost:8001/v1 |
Base URL for LLM API |
MODEL |
Qwen2.5-14B-Instruct-Q4_K_M.gguf |
Model name sent to API |
MEMORY_DIR |
.agent/memory |
Chroma and SQLite storage path |
SOUL_PATH |
SOUL.md |
Soul prompt file |
TOP_K |
4 |
Recall depth per retrieval source |
MAX_TOKENS |
512 |
Completion max tokens |
MAX_LLM_TIMEOUT |
120 |
LLM request timeout (seconds) |
EMBEDDING_BACKEND |
hash |
hash, llm, or sentence-transformers |
AUTONOMOUS_INTERVAL_SEC |
300 |
Autonomous heartbeat interval |
WATCH_PATH |
. |
Filesystem watcher root |
MAX_HISTORY |
10 |
Messages kept in rolling history |
SHELL_LOG |
.agent/shell.log |
Shared shell journal path |
MAX_AUTO_REPAIR_ATTEMPTS |
1 |
Max automatic command repair retries |
MIN_FAILURES_BEFORE_SKILL_UPDATE |
3 |
Evidence threshold for removing skill commands |
SKILL_UPDATE_WINDOW |
50 |
Outcome window size for skill update gating |
MAX_PROMPT_CHARS |
24000 |
Total prompt budget before compaction |
MAX_SYSTEM_CHARS |
12000 |
System message char cap during compaction |
MAX_HISTORY_MSG_CHARS |
3000 |
Per-history-message char cap |
MAX_USER_INPUT_CHARS |
4000 |
User input char cap in prompt |
DISCORD_TOKEN |
`` | Discord bot token (optional) |
DISCORD_CHANNEL_ID |
0 |
Target Discord channel ID (optional) |
DISCORD_ACTIVITY_FEED |
true |
Enables Discord activity events |
This repo currently has soul.md (lowercase), while default config points to SOUL.md.
On case-sensitive filesystems, set:
SOUL_PATH=soul.mdmantis.py- runtimesoul.md- soul prompt/instructionstasks.md- scheduled autonomous tasksrequirements.txt- Python dependenciesdocs/assets/- logo/startup art
This runtime is intentionally permissive:
- shell commands run as the current OS user
- file writes are unconstrained within process permissions
- network calls are possible through tool directives
- no internal sandbox or policy engine is enforced in
mantis.py
Use in controlled environments.
- OpenClaw: https://github.com/OpenClaw/OpenClaw
- PicoClaw: https://github.com/sipeed/picoclaw