A local-first, event-driven AI agent with persistent memory and a configurable persona, available through a web dashboard, Discord (text and voice), WhatsApp, and Telegram. Inspired by OpenClaw and the lightweight architecture of Nanobot.
LimeBot is a complete agent runtime rather than a thin API wrapper. A message from any channel enters an asynchronous event loop, is enriched with recalled memory, and is answered by the configured model, which can call tools to browse the web, work with files inside approved paths, schedule jobs, and delegate to sub-agents. Conversations, memory, and persona data are stored on your own machine.
- Quick start
- Architecture
- Capabilities
- Channels
- LLM support
- Skills
- Getting started
- Discord voice conversations
- Configuration
- Privacy and security
- Contributing
- License
You need two apps on the computer: Node.js 22.19 or newer and Python 3.11–3.14. If either one is missing or too old, LimeBot will say so in plain language and tell you which installer to download. It will not dump a stack trace.
npm startThat is the whole first run. LimeBot installs what it needs, then opens the dashboard. In the wizard, pick a model and paste your API key. To also get a real browser (click, type, download files) in one step:
npm run lime-bot setup -- --recommended
npm startIf you do not use Git: download the project ZIP from the GitHub page (Code → Download ZIP), unzip it, install Docker Desktop, then in that folder run:
sh docker/prepare.sh
docker compose up --build -dOn Windows PowerShell use powershell -ExecutionPolicy Bypass -File docker/prepare.ps1 instead of the sh line. Then open http://localhost:3000.
Details, optional extras, and developer commands are further down.
Already have a checkout? Update it with npm run update, then start LimeBot
again with npm start.
LimeBot operates on an event-driven agentic loop. When you send a message, it flows through the system as follows:
graph TD
User([User Inbound Message]) --> Channel[Channel: Web / Discord / WhatsApp / Telegram]
Channel --> Queue[MessageBus Queue]
Queue --> Loop[Agent Loop]
Loop --> RAG[Auto-RAG: LanceDB Vector Search + Grep]
RAG --> SystemPrompt[Compile Stable + Volatile Prompts]
SystemPrompt --> LLM[LLM Inference]
LLM --> XML[XML Tag Interceptor: save_soul / save_identity / log_memory]
XML --> Tools{Tool Execution Loop}
Tools -- Requires Confirmation --> Auth[Security Gate: Web Dashboard Approval]
Auth -- Approved --> Exec[Execute: edit_file / write_file / run_command / delete_file]
Tools -- Sensitive/No Auth --> Exec
Exec --> Loop
Tools -- No More Tools --> Reply[Compile Outbound Message]
Reply --> Channel
Every eligible non-empty turn gives the model the tools available to the current channel and agent profile. The model chooses what fits the request and can combine tools for multi-step work; tool selection does not depend on specific trigger words. Profile access, approval, and host safety checks still apply.
Three-tier memory system that persists across sessions:
- Episodic Memory every conversation is appended to a daily markdown journal (
persona/memory/YYYY-MM-DD.md) - Semantic Memory entries are embedded and stored in a local LanceDB vector database, enabling fuzzy recall of anything said weeks ago
- Auto-RAG before every reply, LimeBot automatically searches its memory (semantically first, grep fallback) and injects relevant context into the prompt without you asking
- Reflection Engine a background cron job runs every 4 hours, reads today's journal, and distills the key facts into a permanent
MEMORY.mdlong-term essence file
Not a hardcoded system prompt. A living identity that evolves:
SOUL.mdcore values, personality, and behavioral boundariesIDENTITY.mdname, emoji, avatar URL, style, catchphrases, interests, birthday- Local-first persona files first boot auto-creates starter
SOUL.md,IDENTITY.md, andMEMORY.mdfrom shipped.exampletemplates so users get a clean bot without committing live persona state - Per-platform styles separate voice for Discord, WhatsApp, and Web
- Per-user profiles builds a relationship profile for each person it talks to, tracking affinity scores, relationship level, in-jokes, and milestones
- Dynamic Mood optional
MOOD.mdthat shifts based on conversations and persists between sessions - Setup Interview if the local persona files are missing or invalid, the bot interviews you to rebuild its identity and saves the result automatically once it has enough to work with.
The dashboard's Agents page lets you create conversational agents with
their own display name, model choice, persona, memory, and chat history. The
existing LimeBot persona and chats stay under the built-in Default agent;
new agents keep their files under persona/profiles/<id>/. Switch agents from
the chat selector or the browser companion. Discord, WhatsApp, and Telegram
continue using Default.
Agent settings can restrict tools and narrow filesystem access. Global approval and allowed-path rules still apply, and an agent cannot relax them. Shell and sub-agent tools use LimeBot's shared workspace, so named agents start without those tools and need an explicit tool allowlist to enable them. The profile selector keeps a separate chat session for each agent.
Full Playwright-powered browser automation:
- Navigate to any URL, click elements, fill forms, scroll pages
web_search()for live web, news, and image lookup (the host parses results)- Extract page text, take DOM snapshots, list all media on a page
- Download high-resolution images from Pinterest, Reddit, Wikimedia, direct URLs
- Results stream back in real time with progress updates in the dashboard
Whitelisted filesystem operations:
- Read, write, create, delete, move, rename files and directories
- Apply exact hash-guarded patches to existing UTF-8 files with
edit_file; LimeBot previews the diff, rejects stale/no-op/overlapping edits, and runs read-only verification checks afterward - Run optional
diagnose_fileschecks with installed Ruff, Pyright, ESLint, or TypeScript tooling; missing providers returnskippedand are never required for core verification - All operations sandboxed to
ALLOWED_PATHSnothing outside those roots is touchable unless you explicitly allow it - Dangerous operations (write, delete, run) require explicit confirmation through the web UI before executing
Secure subprocess execution with real-time output streaming:
- Runs shell commands inside the project root
- Shell injection filter blocks
;,&&,||, redirects, backticks,$(), andIFS=/PYTHONPATH=assignments in live chat. Bare|is allowed except when piped into an interpreter. Isolated copy workspaces may use&&/||/|/ redirects;run_stepsruns a sequential command chain without&&. - Stall detection if a command produces no output for 30 seconds (likely waiting for interactive input), it's automatically terminated with guidance to retry using non-interactive flags
- Requires user confirmation via the dashboard before any command executes
- Autonomous Mode optionally bypass all confirmation prompts for full hands-off operation
- Session-based approval approve a tool once for the current session without enabling full autonomy
Persistent cron system:
- One-time reminders:
"remind me in 2 hours to call mom" - Repeating jobs: full cron expression support (
0 8 * * *) - Jobs survive restarts (persisted to
data/cron.json) - With Dynamic Personality enabled: automatic morning greetings and silence check-ins
For complex multi-step tasks, LimeBot can delegate work to an isolated background agent:
- Sub-agent runs in its own session with its own tool loop
- The model sees available specialist profiles and their descriptions, then decides whether and where to delegate
- Reports back to the parent session when complete
- Coding, repository, review, and verification work defaults to a temporary copy-on-write workspace; the report includes a bounded structured diff and changes are not merged into the live project implicitly
- Use
isolation="copy"to force isolation orisolation="none"only for an explicitly shared task - The web chat renders delegated results as a dedicated sub-agent report card instead of raw trace text
- Useful for long-running research, file processing, or anything that shouldn't block the main conversation
LimeBot also exposes an authenticated local companion API at /api/app/* for inspecting durable workspaces, steering a workspace with messages, resolving approvals, and streaming normalized workspace events. It remains local-first and does not expose direct shell execution, credentials, artifact paths, or file-reading endpoints.
For CI review, limebot review-diff --diff-file change.patch --output review.json creates a capped, secret-redacted artifact. .github/workflows/limebot-review.yml is artifact-only with contents: read; model invocation is opt-in and it never posts PR comments, edits files, or pushes commits.
LimeBot is a fully-featured MCP client:
- Universal Tool Integration connect to any MCP server (Fetch, Filesystem, Brave Search, etc.) to immediately expand the bot's capabilities.
- Dynamic Discovery tools from connected MCP servers are automatically prefixed with
mcp_server_name_and injected into the AI's tool registry. - Configurable Servers manage server arguments and environment variables directly from the web dashboard.
- Safety & Resilience built-in timeouts and error handling ensure that misbehaving MCP servers don't hang the main agent loop.
| Channel | How it works |
|---|---|
| Web Dashboard | React + Vite UI connecting over WebSocket. Streams tokens as they arrive, shows live tool execution cards, confirmation prompts, thinking traces, and ghost activity indicators. Includes a Custom CSS editor for global UI personalization. |
| Discord | Responds to DMs and @mentions, with configurable user and channel allow-lists. Optional experimental voice conversations answer when addressed by name, can list and move members between voice channels, and speak replies. |
Connects to a local whatsapp-web.js bridge over WebSocket. Contact approval whitelist with pending/blocked states. QR code displayed in the web dashboard for easy pairing. |
|
| Telegram | Bot API long-polling. Supports text send/receive, per-user allow-listing, optional per-chat allow-listing, typing indicators, and 4096-character chunking. |
LimeBot also ships with a browser companion extension for Chrome, Edge, and Opera GX.
- Ask LimeBot about the current page
- Send selected text to LimeBot
- View live task status and approvals while you browse
- Use the same LimeBot persona name and avatar when available
Setup instructions live in extension/README.md.
LimeBot uses LiteLLM any model it supports, LimeBot supports:
| Provider | Example model string |
|---|---|
| Gemini (default) | gemini/gemini-3.8-flash |
| OpenAI | openai/gpt-6.1-sol |
| Anthropic | anthropic/claude-opus-5 |
| xAI | xai/grok-4.7 |
| DeepSeek | deepseek/deepseek-v4-flash |
| Moonshot AI (Kimi) | moonshot/kimi-k3 |
| Qwen (DashScope) | qwen/qwen3.5-plus |
| NVIDIA | nvidia/deepseek-ai/deepseek-v4-flash-0731 |
| OpenRouter | openrouter/openai/gpt-6.1-sol |
| Switch models live from the web dashboard without restarting. |
LimeBot supports routing all LLM traffic through external security or caching middleware (like AI Gateway, Open Guardian, or Helicone):
LLM_PROXY_URLconfigure a global proxy URL in the dashboard or.env. This overrides the default base URL for all providers.- Provider Normalization LiteLLM handles the complex routing and header manipulation required to use custom gateways with cloud providers.
Skills extend what LimeBot can do. Each skill is a folder with a SKILL.md (the LLM instructions) and a skill.py or script (the execution logic).
Built-in skills:
| Skill | What it does |
|---|---|
browser |
Full Playwright web browsing navigate, click, type, search, extract |
download_image |
Download high-res images from Pinterest, Reddit, Wikimedia, or direct URLs |
filesystem |
Strategy guide for LimeBot's sandboxed file tools |
discord |
Optional higher-level Discord administration helpers |
docx-creator |
Create, inspect, edit, and validate Microsoft Word .docx documents |
scrapling |
Stealthy page extraction when the browser skill is not enough |
watch |
How to use the native analyze_video tool |
GitHub work is no longer a built-in LimeBot skill. Install the official Cursor plugin instead:
limebot plugin install cursor/plugins/github
# or from this repo's fixture / a local checkout:
limebot plugin install ./path/to/third_party/githubInstall community skills from GitHub:
# Full URL
python -m core.skill_installer install https://github.com/user/my-lime-skill
# GitHub shorthand
python -m core.skill_installer install user/my-lime-skill
# Or via the CLI wrapper
npm run lime-bot skill install https://github.com/user/my-lime-skillThe installer auto-detects the repo's default branch, and automatically runs pip install or npm install if dependency files are present.
Other skill commands:
python -m core.skill_installer list
python -m core.skill_installer update <skill_name>
python -m core.skill_installer uninstall <skill_name>
python -m core.skill_installer enable <skill_name>
python -m core.skill_installer disable <skill_name>Skills can also be managed from the Skills tab in the web dashboard.
LimeBot understands the Cursor plugin package format (.cursor-plugin/plugin.json,
optional marketplace.json, skills/*/SKILL.md, mcp.json, and rules).
limebot plugin install cursor/plugins/create-plugin
limebot plugin install ./tests/fixtures/cursor-plugins/github
limebot plugin listInstalled plugins land under $LIMEBOT_STATE_DIR/plugins. Their skills are
loaded by the existing skill registry; their MCP servers are merged into
mcp/mcp_config.json.
The short path is at the top of this file. This section is the same flow with more detail.
Install these two apps if you do not already have them:
- Node.js 22.19 or newer (the website calls this the LTS installer)
- Python 3.11 through 3.14 (on Windows, tick "Add python.exe to PATH")
You also need about 1 GB free and an API key from any supported model provider.
You do not need to create a virtual environment or run npm install yourself.
If npm start says Node or Python is wrong, follow the numbered steps it prints.
Close the terminal, open a new one, and try npm start again.
-
Open a terminal in the LimeBot folder (clone with Git, or unzip the GitHub download).
-
Optional but recommended — install a real browser so LimeBot can click and download files:
npm run lime-bot setup -- --recommended
-
Start LimeBot:
npm start
The first run creates
.venv, installs core dependencies, and opens the dashboard. -
Open http://localhost:5173 if it does not open itself.
-
In the setup wizard, choose a model and paste its key. Keys stay in the local
.envfile. -
Send a first message. LimeBot will ask a few persona questions and write
SOUL.mdandIDENTITY.md.
After one successful start, npm run start:quick is the fastest warm start.
Only one backend can run from a checkout at a time; use npm run stop before
starting it again.
The default installation is enough for web chat, the dashboard, Discord, core tools, scheduling, and supported LLM providers. Large or specialized features are opt-in, so a new user does not download them before reaching setup.
Install only what you use. Sizes are rough ranges and vary by platform and cache.
After one successful normal start, install every optional profile plus a launch-verified Chromium browser with:
npm run lime-bot feature install allThe command is retryable: profiles already recorded with unchanged manifests are skipped. If one installation fails, fix the reported issue and run the same command again.
| Feature | Command | Approximate extra disk |
|---|---|---|
| Browser Python support | npm run lime-bot feature install browser |
20-50 MB before Chromium |
| Browser + launch-verified Chromium | npm run install-browser |
300-700 MB |
| Semantic memory (LanceDB) | npm run lime-bot feature install memory |
100-300 MB |
| Word/PDF helpers | npm run lime-bot feature install documents |
10-30 MB |
| MCP integration | npm run lime-bot feature install mcp |
10-30 MB |
Video analysis (yt-dlp, Pillow, FFmpeg checks) |
npm run lime-bot feature install video |
100-300 MB |
| Discord voice conversations | npm run lime-bot feature install discord-voice |
Requires FFmpeg; replaces the standard Discord library with a pinned experimental DAVE receive build |
| WhatsApp bridge | npm run lime-bot feature install whatsapp |
200-500 MB |
| Browser companion build tools | npm run lime-bot feature install extension |
100-300 MB |
| All stable optional features + Chromium | npm run lime-bot feature install all |
Platform-dependent |
WhatsApp is installed and built automatically before its first launch.
npm run extension:build installs the extension workspace before building it.
If an optional package is absent, only that capability is unavailable; core
chat still starts.
Discord requires DAVE end-to-end encryption for normal voice channels. Pycord's
receive-side support is still an open upstream change, so this feature is
experimental and pins that revision. It is installed separately because it
replaces discord.py in the LimeBot virtual environment; the CLI keeps using
the selected Discord package on later starts and updates. The regular text bot
continues to use the default package unless this feature is installed.
Stop LimeBot before installation because the feature replaces its Discord
library.
-
Install FFmpeg if it is not already available on
PATH:winget install --id Gyan.FFmpeg -e # macOS: brew install ffmpeg # Debian/Ubuntu: sudo apt install ffmpeg
-
From the LimeBot folder, install the voice package:
npm run lime-bot feature install discord-voice
-
In
.env, setENABLE_DISCORD_VOICE=trueand addELEVENLABS_API_KEY. Start LimeBot again withnpm run start. -
Join a regular voice channel, then run
/voice_joinin a server text channel. Use/voice_leaveto stop the session. Only the person who started the session or a server moderator can stop it.
LimeBot waits for DAVE to become ready before listening. Before recording
starts it shows the transcription notice only to the person who ran /voice_join
(an ephemeral message), so the text channel stays quiet. After a pause in speech the
audio is sent to ElevenLabs for transcription, the transcript goes to the agent, and
the reply is spoken. The reply is posted as text only when speech cannot carry it:
links, code, long answers, warnings, or a playback failure. Audio is held temporarily for transcription and deleted
afterward. Only members allowed by DISCORD_ALLOW_FROM are transcribed; an
empty allow-list allows every member.
- Addressed by name. By default LimeBot answers only when its name is said at the start or end of a sentence ("Jennie, who is in the call?"). Every request needs the name; set a follow-up window under Voice if you want the same person to keep talking for a few seconds without repeating it. Set the name and mode under Voice in the dashboard (Voice name accepts several comma-separated nicknames; empty uses the persona name). Turning the mode off answers everything said in the channel. Audio is still transcribed to check for the name, then discarded.
- Listening control.
/voice_mutestops capture entirely: nothing is recorded or sent for transcription until/voice_unmute. Saying "stop listening" also mutes; unmuting always requires the slash command. - Voice actions.
voice_list_membersshows who is in the channel and in the server's other voice channels.voice_move_membersmoves people to another voice channel ("move us to Games"); LimeBot follows when everyone moves. Moving people and muting are limited to the person who started the session or a moderator, and need Discord's Move Members permission for the bot. - Restricted tools. Voice conversations can use web search, browsing,
memory, calculations, reminders, Discord messaging, and the voice actions
above. File, shell, sub-agent, image, and media-sharing tools are unavailable
and refused at run time. Add tool names to
DISCORD_VOICE_EXTRA_TOOLSonly if you trust everyone in the channel. - Brief speech. Replies are cleaned of links, code, and emoji and limited to about 500 characters when spoken; the full text stays in the channel.
- Noise handling. Background noise, keyboard clicks, and echo of LimeBot's own voice are filtered before transcription.
Tool calls appear in Discord only when they fail (set
DISCORD_TOOL_EMBEDS=full to show every call).
Video analysis accepts allowed local files and public, unauthenticated HTTP(S)
media. It rejects playlists, livestreams, private network destinations, media
over two hours, and downloads over 500 MiB. Enable the separately installed
watch skill to teach the model its /watch workflow. Native captions are
preferred. VIDEO_WHISPER_ENABLED=false keeps caption-less audio local; when
enabled, that audio is sent to OpenAI using the configured OPENAI_API_KEY.
The video installer verifies both ffmpeg and ffprobe. If they are missing,
install FFmpeg with winget install --id Gyan.FFmpeg -e (Windows),
brew install ffmpeg (macOS), or your Linux package manager, then retry.
Run the built-in diagnostic first:
npm run doctorCommon cases:
- Node is rejected before installation: install Node.js 22.19 or newer,
open a new terminal, and run
node --versionagain. - Python is rejected: install Python 3.11-3.14. On Windows, the
pylauncher helps LimeBot find a supported installation. - An interrupted
.venvis detected: LimeBot preserves the old directory as.venv.incomplete-<timestamp>, creates a replacement, and restores the preserved directory if repair fails. It never falls back to system pip. spawn EINVALwhile starting npm on Windows: update to the latest LimeBot checkout. Current releases route Windows.cmdshims throughcmd.exewithout enabling shell mode. Then rerunnpm start.- A dependency lane fails: the other lane is allowed to finish, but LimeBot
will not start or record the failed lane as current. Fix the reported error
and rerun
npm start; successful work is reused. - The UI opens but input is temporarily disabled: the process is live, but required skills/tools are still loading. The readiness banner will update automatically.
For more detail, use npm run logs. Use npm run start:quick only after a
normal start has completed successfully.
Once LimeBot is running, you can also build and load the browser companion extension:
npm run extension:buildLoad the unpacked extension from extension/dist. Full setup steps are in extension/README.md.
You can use the following commands in the root directory to manage your LimeBot instance:
| Command | Description |
|---|---|
npm start |
Recommended start command; installs/refreshes only changed core dependencies, then launches backend and frontend. |
npm run start:quick |
Launches with dependency and update checks skipped; use this only after a successful normal start. |
npm run stop |
Safely stops all active LimeBot background processes. |
npm run status |
Checks active ports (Backend on 8000, Frontend on 5173). |
npm run update |
Safely fast-forwards a Git checkout, backs up runtime state, and refreshes dependencies. |
npm run update:check |
Shows update availability and whether local changes can be updated automatically. |
npm run lime-bot update --rollback |
Reverts the last guarded update when no tracked source edits are present. |
npm run doctor |
Validates your local setup, environment variables, Node.js and Python runtimes. |
npm run logs |
Tails the live logger (logs/limebot.log). |
npm run test:cli |
Runs the Node.js CLI & dependency validation tests. |
npm run install-browser |
Manually downloads the browser binaries required for Playwright automation. |
npm run lime-bot feature install <name> |
Installs one optional profile and skips it when unchanged; use all for every profile plus Chromium. |
npm run lime-bot skill list |
Lists all installed and available skills. |
npm run lime-bot skill install <url> |
Installs a new skill from a GitHub URL or repository path. |
Normal combined startup opens the dashboard as soon as the backend reports process liveness at /api/live. Agent capabilities may continue loading after the UI appears; the authenticated /api/ready endpoint remains the source of full capability readiness. Remote update discovery also runs in the background after local processes launch. Backend-only startup continues to wait for full readiness so it can report a diagnostic result.
Run npm run update from the checkout. The updater only applies a
fast-forward, refuses to overwrite tracked source edits, and preserves legacy
runtime files such as .env, limebot.json, persona data, and custom skills.
Before changing source it writes a local backup under
.limebot-update-backups/. If a dependency refresh is unavailable, the next
normal npm start retries it automatically. Use --no-deps to defer the
refresh explicitly, or --rollback to restore the previous guarded commit.
For new installs, set LIMEBOT_STATE_DIR to a user-owned directory outside the
Git checkout. LimeBot then stores mutable configuration, persona data, and
installed skills there, so future updates do not create merge conflicts with
local state. Existing installs can adopt this path incrementally; the checkout
root remains the compatibility default when the variable is not set.
# Terminal 1 Backend
cp .env.example .env # fill in your keys
python -m pip install -r requirements-dev.txt
python main.py
# Terminal 2 Frontend
cd web && npm install && npm run devI don't use Git. Install Docker Desktop. On the LimeBot GitHub page click Code → Download ZIP, unzip it, and open a terminal in that folder. Then run the two commands below. Open http://localhost:3000 when Docker says the stack is up.
Prepare the ignored runtime files once, then build the core stack:
# macOS / Linux / Git Bash
sh docker/prepare.sh
docker compose up --build -d# Windows PowerShell
powershell -ExecutionPolicy Bypass -File docker/prepare.ps1
docker compose up --build -dOpen http://localhost:3000. Nginx is the only host
entry point; it proxies API, generated media, and WebSocket traffic to the
private backend. Compose binds Nginx to 127.0.0.1 by default.
The image is core-only by default. To bake optional Python profiles or
Chromium into the backend image, set these values in .env before building:
LIMEBOT_DOCKER_FEATURES="memory documents mcp"
LIMEBOT_DOCKER_INSTALL_BROWSER=1WhatsApp is an optional Compose profile. Set ENABLE_WHATSAPP=true in .env,
then start it with:
docker compose --profile whatsapp up --build -dUseful commands:
docker compose ps
docker compose logs -f backend
docker compose downDurable jobs are written to data/jobs.sqlite before the agent runs. A crash
re-queues interrupted work; cron is marked ok only after the agent turn
finishes. Live chat stays confirmation-gated, including after a restart.
Scheduled or explicitly unattended jobs use:
UNATTENDED_PATH_ALLOWLIST=./persona,./temp,./logs
UNATTENDED_COMMAND_ALLOWLIST=python,ghSupervise the process so recovery can actually happen:
# Linux host
limebot autorun enable
# or install deploy/systemd/limebot.service and point WorkingDirectory at your checkout
# Heartbeat
curl -fsS http://127.0.0.1:8000/api/liveDocker already uses restart: unless-stopped. See deploy/systemd/README.md.
The backend port is intentionally not published. Do not publish it while
LIMEBOT_TRUSTED_PROXY_ONLY=true unless APP_API_KEY is also configured.
To expose the dashboard on a LAN, set LIMEBOT_DOCKER_BIND_HOST=0.0.0.0 and a
strong APP_API_KEY in .env, then rebuild/restart the stack.
LimeBot can now store and manage ChatGPT Codex OAuth locally through the CLI without putting the login flow in the web dashboard.
limebot auth codex login
limebot auth codex import
limebot auth codex status
limebot auth codex logoutloginstarts the browser-based ChatGPT OAuth flow using the local CLIimportpulls an existing login from%USERPROFILE%\.codex\auth.json(orCODEX_HOME/auth.json)- credentials are stored locally in
data/oauth_profiles.json - the dashboard can read status, but sign-in itself stays CLI-only
Copy .env.example to .env:
# Core
LLM_MODEL=gemini/gemini-3.8-flash
GEMINI_API_KEY=your_key_here
DASHSCOPE_API_KEY=your_dashscope_key_here
# Optional for Qwen region routing:
# LLM_BASE_URL=https://dashscope-intl.aliyuncs.com/compatible-mode/v1
# Channels (all optional)
DISCORD_TOKEN=your_discord_bot_token
ENABLE_WHATSAPP=false
WEB_PORT=8000
FRONTEND_PORT=5173
# Security
ALLOWED_PATHS=./persona,./logs,./temp
APP_API_KEY=optional_dashboard_password
# Features
ENABLE_DYNAMIC_PERSONALITY=false # per-user affinity, mood tracking, proactive greetings
VIDEO_WHISPER_ENABLED=false # opt in to sending caption-less audio to OpenAI Whisper
LLM_PROXY_URL=http://localhost:8080/v1 # Optional: Route all traffic through a gateway
# Discord voice (optional)
ENABLE_DISCORD_VOICE=false
DISCORD_TOOL_EMBEDS=errors # errors (default) or full
DISCORD_VOICE_EXTRA_TOOLS= # extra tools allowed in voice sessions
# Terminal output (the full log is always written to logs/limebot.log)
LIMEBOT_CONSOLE_LEVEL=WARNING # WARNING (default), INFO, or DEBUGLimeBot defaults to the fast AI harness: Auto-RAG gets an 80ms request
budget. Every eligible non-empty turn receives the tools available to its
current profile and channel, and the model chooses whether to call them. Set
LIMEBOT_AI_HARNESS_MODE=balanced to use a 200ms Auto-RAG budget instead.
Tip
Most settings can also be changed from the Config tab of the web dashboard. Saving writes the .env file and restarts the backend cleanly.
- Local-first all conversations, memories, and personal data stay on your machine.
- Sandboxed Filesystem LimeBot can only read/write files in directories you explicitly whitelist.
- Human-in-the-loop sensitive actions (running shell commands, modifying/deleting files) require your explicit approval.
[!IMPORTANT] By default, dangerous actions in live chat pause for dashboard approval. Scheduled or explicitly unattended jobs use
UNATTENDED_PATH_ALLOWLIST/UNATTENDED_COMMAND_ALLOWLISTinstead of forcingAUTONOMOUS_MODE=true. - Voice privacy Discord voice audio is sent to ElevenLabs for transcription and not stored. Voice sessions tell the person who started them what is transcribed, can be muted, and cannot use file, shell, or sub-agent tools.
- Open Source audit the code yourself. No hidden telemetry.
Contributions are welcome. See CONTRIBUTING.md for how to submit pull requests, report bugs, and request features.
The offline task evaluator compares two source snapshots using synthetic local
replays and makes no provider requests. Create a clean baseline snapshot from
the revision you want to compare (for example, main~1), then use it as a
separate directory:
mkdir -p ../limebot-baseline
git archive main~1 | tar -x -C ../limebot-baseline
python scripts/evaluate_tasks.py compare \
--baseline ../limebot-baseline \
--candidate . \
--baseline-id main~1 \
--candidate-id working-treeThe baseline and candidate paths must be different; comparing the same source directory with itself does not measure a revision change.
Reports are stored under the local LimeBot state directory in
data/evaluations/. They contain normalized outcomes and timing evidence, not
raw prompts, replies, fixture contents, or persona text. See evals/README.md
for comparison options and limits.
MIT © LemonMantis5571
