A privacy-first ReAct CLI agent for Xiaomi MiMo and any OpenAI-compatible model. Drop a goal, watch the agent think → call a tool → observe → repeat until it has the answer.
agentlab is a single-file-install Python CLI that turns any OpenAI-compatible chat-completions endpoint into a tool-using autonomous agent. The default provider is Xiaomi MiMo (mimo-v2.5-reasoning at https://api.xiaomimimo.com/v1), but the same binary speaks OpenAI, DeepSeek, Groq, and Ollama out of the box.
- Closed-loop multi-step reasoning. Plan → tool → observation → plan → … until the agent emits a final answer or hits a step budget.
- Six built-in tools. Web search, web fetch, file read, file write, sandboxed Python, allow-listed shell — enough to actually do research and small-scale automation.
- MiMo / DeepSeek-R1 reasoning panel. Streaming SSE client extracts both
delta.contentanddelta.reasoning_contentso reasoning models render cleanly. - Privacy-first. No backend, no telemetry. Your API key lives in
~/.agentlab/config.yamlor your environment; traces stay on your disk. - Full JSONL trace + Markdown summary of every run, written under
~/.agentlab/runs/. - Strict typed Python (mypy strict, ruff clean, 31 tests).
pipx install git+https://github.com/lion7878/agentlab.git
# or, in a venv:
python -m venv .venv && source .venv/bin/activate
pip install git+https://github.com/lion7878/agentlab.gitSet a Xiaomi MiMo key (free credit at https://platform.xiaomimimo.com/):
export MIMO_API_KEY=sk-...…or any other supported provider:
export OPENAI_API_KEY=sk-...
export DEEPSEEK_API_KEY=sk-...
export GROQ_API_KEY=gsk_...agentlab run "Find the three highest-rated open-source ReAct frameworks on GitHub right now and summarise their differences in a Markdown table."Switch providers on the fly:
agentlab run "What is 7! ?" --provider openai --model gpt-4o-mini
agentlab run "Summarise the README of denoland/deno" --provider mimo --model mimo-v2.5-flagshipInspect what's available:
agentlab providers # list provider presets
agentlab tools # list built-in tools and arg schemas
agentlab config --show # show resolved configagentlab runs a strict JSON-envelope ReAct loop. The system prompt tells the model to reply with exactly one of:
{"thought": "<brief reasoning>", "tool": "<tool_name>", "args": {...}}{"thought": "<brief reasoning>", "final_answer": "<answer for the user>"}Each iteration:
- Plan — agent sends the conversation to the LLM and parses the JSON envelope.
- Act — if the model picked a tool, the tool is invoked with the supplied args.
- Observe — the tool's stdout is appended to the conversation as a
userturn tagged with the tool name. Errors are surfaced in the same channel so the model can self-correct. - Repeat until the model emits
final_answeror--max-stepsis hit.
If the model returns un-parseable text, the loop feeds it back a corrective message and continues, so a single bad turn doesn't kill the run.
┌──────────────┐
user goal ──▶ │ planner │ ──▶ JSON envelope
│ (LLM call) │
└──────┬───────┘
│
┌───────────┴───────────┐
▼ ▼
tool call? final_answer?
│ │
▼ ▼
run tool ──▶ obs done; print
│
└────▶ append to conversation ─┐
│
▼
next plan
Every run writes:
~/.agentlab/runs/run-<ts>.jsonl— append-only trace (start, every step, end + token totals).~/.agentlab/runs/run-<ts>.md— human-readable Markdown summary with thoughts, tool calls, observations, final answer.
| Tool | What it does | Notes |
|---|---|---|
web_search |
DuckDuckGo HTML search → numbered list of (title, url, snippet) | No API key required. |
web_fetch |
Fetch a URL and return readable plain text (HTML stripped) | 1.5 MB cap, configurable per-call truncation. |
file_read |
Read a UTF-8 file inside the workspace | Refuses paths that escape the workspace. |
file_write |
(Over)write or append a UTF-8 file inside the workspace | Auto-creates parent directories. |
python |
Tiny AST-vetted Python sandbox | No imports, no I/O — pure arithmetic / data wrangling, plus math. |
shell |
Allow-listed command runner | Only read-only / inspection binaries; git restricted to status/log/diff/show. |
Adding a new tool is a single-file change — see CONTRIBUTING.md.
| ID | Name | Default model | Base URL |
|---|---|---|---|
mimo (default) |
Xiaomi MiMo | mimo-v2.5-reasoning |
https://api.xiaomimimo.com/v1 |
openai |
OpenAI | gpt-4o-mini |
https://api.openai.com/v1 |
deepseek |
DeepSeek | deepseek-reasoner |
https://api.deepseek.com/v1 |
groq |
Groq | llama-3.3-70b-versatile |
https://api.groq.com/openai/v1 |
ollama |
Ollama (local) | llama3.2 |
http://localhost:11434/v1 |
Adding a new provider is one row in src/agentlab/presets.py.
agentlab reads (later overrides earlier):
- Defaults — provider
mimo,mimo-v2.5-reasoning,temperature=0.2,max_steps=12. ~/.agentlab/config.yaml(user-global)../.agentlab.yamlor./agentlab.yamlwalked up from the cwd (project-local).- Environment variables for API keys (
MIMO_API_KEY,OPENAI_API_KEY, …). - CLI flags (
--provider,--model,--api-key,--temperature,--max-steps, …).
Example ~/.agentlab/config.yaml:
provider: mimo
model: mimo-v2.5-reasoning
temperature: 0.2
max_steps: 12
trace_dir: ~/.agentlab/runsgit clone https://github.com/lion7878/agentlab.git
cd agentlab
python -m venv .venv && source .venv/bin/activate
pip install -e '.[dev]'
pytest -q # 31 tests, no network
ruff check . # lint
mypy src # type-check (strict)The repo also ships an offline demo that drives the agent loop with a scripted LLM (no API key needed) — handy for screenshots, CI smoke tests, and seeing the loop in action:
python examples/offline_demo.py- MiMo-first by design. Default preset is
mimo-v2.5-reasoning. The Settings/Help output deep-links toplatform.xiaomimimo.comso new users can grab a key in two clicks. - Closed-loop, not chat. agentlab doesn't replace your IDE chatbot — it's a goal-directed worker for tasks where you'd otherwise open four browser tabs and copy-paste.
- Tiny surface area. ~1 000 lines of strict-typed Python, six tools, no managed backend, no SaaS dashboard. Easy to audit, easy to extend.
MIT © agentlab contributors.


