opencrabs

The self-hosted AI agent. Rust. Single binary. Fully autonomous. Built with Ratatui

RustMIT459452
Created Feb 14, 2026Last commit Mar 2, 2026Last human commit Mar 2, 2026
agentic-frameworkopen-sourceopencraborchestration-framework
Embed Badge
Play on Codakey
Markdown
[![Play on Codakey](https://codakey.io/badge.svg)](https://codakey.io/projects/opencrabs)
HTML
<a href="https://codakey.io/projects/opencrabs"><img src="https://codakey.io/badge.svg" alt="Play on Codakey" height="28" /></a>

Daily Activity

Monthly Activity

Star History

README

Rust Rust Edition Ratatui Docker CI GitHub Stars

πŸ¦€ OpenCrabs

The autonomous AI agent. Single Rust binary. Every channel.

Autonomous multi-channel AI agent built in Rust. Inspired by Open Claw.

    ___                    ___           _
   / _ \ _ __  ___ _ _    / __|_ _ __ _| |__  ___
  | (_) | '_ \/ -_) ' \  | (__| '_/ _` | '_ \(_-<
   \___/| .__/\___|_||_|  \___|_| \__,_|_.__//__/
        |_|

 πŸ¦€ The autonomous AI agent. Single Rust binary. Every channel.

Author: Adolfo Usier

⭐ Star us on GitHub if you like what you see!


Table of Contents


πŸ“Έ Screenshots

Demo


🎯 Core Features

AI & Providers

FeatureDescription
Multi-ProviderAnthropic Claude, OpenAI, OpenRouter (400+ models), MiniMax, and any OpenAI-compatible API (Ollama, LM Studio, LocalAI). Model lists fetched live from provider APIs β€” new models available instantly. Each session remembers its provider + model and restores it on switch
Real-time StreamingCharacter-by-character response streaming with animated spinner showing model name and live text
Local LLM SupportRun with LM Studio, Ollama, or any OpenAI-compatible endpoint β€” 100% private, zero-cost
Cost TrackingPer-message token count and cost displayed in header; /usage shows all-time breakdown grouped by model with real costs + estimates for historical sessions
Context AwarenessLive context usage indicator showing actual token counts (e.g. ctx: 45K/200K (23%)); auto-compaction at 70% with tool overhead budgeting; accurate tiktoken-based counting calibrated against API actuals
3-Tier Memory(1) Brain MEMORY.md β€” user-curated durable memory loaded every turn, (2) Daily Logs β€” auto-compaction summaries at ~/.opencrabs/memory/YYYY-MM-DD.md, (3) Hybrid Memory Search β€” FTS5 keyword search + local vector embeddings (embeddinggemma-300M, 768-dim) combined via Reciprocal Rank Fusion. Runs entirely local β€” no API key, no cost, works offline
Dynamic Brain SystemSystem brain assembled from workspace MD files (SOUL, IDENTITY, USER, AGENTS, TOOLS, MEMORY) β€” all editable live between turns

Multimodal Input

FeatureDescription
Image AttachmentsPaste image paths or URLs into the input β€” auto-detected and attached as vision content blocks for multimodal models
PDF SupportAttach PDF files by path β€” native Anthropic PDF support; for other providers, text is extracted locally via pdf-extract
Document ParsingBuilt-in parse_document tool extracts text from PDF, DOCX, HTML, TXT, MD, JSON, XML
Voice (STT)Telegram voice notes transcribed via Groq Whisper (whisper-large-v3-turbo) and processed as text. API key in keys.toml
Voice (TTS)Agent replies to voice notes with audio via OpenAI TTS (gpt-4o-mini-tts, ash voice); falls back to text if disabled
Attachment IndicatorAttached images show as [IMG1:filename.png] in the input title bar

Messaging Integrations

FeatureDescription
Telegram BotFull-featured Telegram bot β€” shared session with TUI, photo/voice support, allowed user IDs, allowed chat/group IDs, respond_to filter (all/dm_only/mention)
WhatsAppConnect via QR code pairing at runtime or from onboarding wizard. Text + image, shared session with TUI, phone allowlist, session persists across restarts
DiscordFull Discord bot β€” text + image + voice, allowed user IDs, allowed channel IDs, respond_to filter, shared session with TUI
SlackFull Slack bot via Socket Mode β€” allowed user IDs, allowed channel IDs, respond_to filter, shared session with TUI. Full proactive control via slack_send (16 actions): send, reply, react, unreact, edit, delete, pin, unpin, get_messages, get_channel, list_channels, get_user, list_members, kick_user, set_topic, send_blocks. Bot token + app token from api.slack.com/apps (Socket Mode required)
TrelloTool-only by default β€” the AI acts on Trello only when explicitly asked via trello_send. Opt-in polling via poll_interval_secs in config; when enabled, only @bot_username mentions from allowed users trigger a response. Full card management via trello_send: add_comment, create_card, move_card, find_cards, list_boards, get_card, get_card_comments, update_card, archive_card, add_member_to_card, remove_member_from_card, add_label_to_card, remove_label_from_card, add_checklist, add_checklist_item, complete_checklist_item, list_lists, get_board_members, search, get_notifications, mark_notifications_read. API Key + Token from trello.com/power-ups/admin, board IDs and member-ID allowlist configurable

Terminal UI

FeatureDescription
Cursor NavigationFull cursor movement: Left/Right arrows, Ctrl+Left/Right word jump, Home/End, Delete, Backspace at position
Input HistoryPersistent command history (~/.opencrabs/history.txt), loaded on startup, capped at 500 entries
Inline Tool ApprovalClaude Code-style ❯ Yes / Always / No selector with arrow key navigation
Inline Plan ApprovalInteractive plan review selector (Approve / Reject / Request Changes / View Plan)
Session ManagementCreate, rename, delete sessions with persistent SQLite storage; each session remembers its provider + model β€” switching sessions auto-restores the provider (no manual /models needed); token counts and context % per session
Parallel SessionsMultiple sessions can have in-flight requests to different providers simultaneously. Send a message in one session, switch to another, send another β€” both process in parallel. Background sessions auto-approve tool calls; you'll see results when you switch back
Scroll While StreamingScroll up during streaming without being yanked back to bottom; auto-scroll re-enables when you scroll back down or send a message
Compaction SummaryAuto-compaction shows the full summary in chat as a system message β€” see exactly what the agent remembered
Syntax Highlighting100+ languages with line numbers via syntect
Markdown RenderingRich text formatting with code blocks, headings, lists, and inline styles
Tool Context PersistenceTool call groups saved to DB and reconstructed on session reload β€” no vanishing tool history
Multi-line InputAlt+Enter / Shift+Enter for newlines; Enter to send
Abort ProcessingEscapeΓ—2 within 3 seconds to cancel any in-progress request

Agent Capabilities

FeatureDescription
Built-in ToolsRead/write/edit files, bash, glob, grep, web search (DuckDuckGo + EXA default, no key needed; Brave optional), and more
Per-Session IsolationEach session is an independent agent with its own provider, model, context, and tool state. Sessions can run tasks in parallel against different providers β€” ask Claude a question in one session while Kimi works on code in another
Self-SustainingAgent can modify its own source, build, test, and hot-restart via Unix exec()
Natural Language CommandsTell OpenCrabs to create slash commands β€” it writes them to commands.toml autonomously via the config_manager tool
Live SettingsAgent can read/write config.toml at runtime; Settings TUI screen (press S) shows current config; approval policy persists across restarts
Web SearchDuckDuckGo (built-in, no key needed) + EXA AI (neural, free via MCP) by default; Brave Search optional (key in keys.toml)
Debug Logging--debug flag enables file logging; DEBUG_LOGS_LOCATION env var for custom log directory
Agent-to-Agent (A2A)HTTP gateway implementing A2A Protocol RC v1.0 β€” peer-to-peer agent communication via JSON-RPC 2.0. Supports message/send, tasks/get, tasks/cancel. Includes multi-agent debate (Bee Colony) with confidence-weighted consensus. Loopback-only by default; CORS origins must be explicitly configured

🌐 Supported AI Providers

Anthropic Claude

Models: claude-opus-4-6, claude-sonnet-4-5-20250929, claude-haiku-4-5-20251001, plus legacy Claude 3.x models

Setup in keys.toml:

[providers.anthropic]
api_key = "sk-ant-api03-YOUR_KEY"

OAuth tokens (sk-ant-oat prefix) are auto-detected β€” uses Authorization: Bearer with anthropic-beta: oauth-2025-04-20 header automatically.

Features: Streaming, tools, cost tracking, automatic retry with backoff

OpenAI

Models: GPT-5 Turbo, GPT-5

Setup in keys.toml:

[providers.openai]
api_key = "sk-YOUR_KEY"

OpenRouter β€” 400+ Models, One Key

Setup in keys.toml β€” get a key at openrouter.ai/keys:

[providers.openrouter]
api_key = "sk-or-YOUR_KEY"

Access 400+ models from every major provider through a single API key β€” Anthropic, OpenAI, Google, Meta, Mistral, DeepSeek, Qwen, and many more. Includes free models (DeepSeek-R1, Llama 3.3, Gemma 2, Mistral 7B) and stealth/preview models as they drop.

Model list is fetched live from the OpenRouter API during onboarding and via /models β€” no binary update needed when new models are added.

MiniMax

Models: MiniMax-M2.5, MiniMax-M2.1, MiniMax-Text-01

Setup β€” get your API key from platform.minimax.io. Add to keys.toml:

[providers.minimax]
api_key = "your-api-key"

MiniMax is an OpenAI-compatible provider with competitive pricing. It does not expose a /models endpoint, so the model list comes from config.toml (pre-configured with available models).

Custom (OpenAI-Compatible)

Use for: Ollama, LM Studio, LocalAI, Groq, or any OpenAI-compatible API.

Setup in config.toml β€” every custom provider needs a name (the label after custom.):

[providers.custom.lm_studio]
enabled = true
base_url = "http://localhost:1234/v1"  # or your endpoint
default_model = "qwen2.5-coder-7b-instruct"
# Optional: list your available models β€” shows up in /models and /onboard
# so you can switch between them without editing config
models = ["qwen2.5-coder-7b-instruct", "llama-3-8B", "mistral-7B-instruct"]

Local LLMs (Ollama, LM Studio): No API key needed β€” just set base_url and default_model.

Remote APIs (Groq, Together, etc.): Add the key in keys.toml using the same name:

[providers.custom.groq]
api_key = "your-api-key"

Note: /chat/completions is auto-appended to base URLs that don't include it.

Multiple custom providers coexist β€” define as many as you need with different names and switch between them via /models:

[providers.custom.lm_studio]
enabled = true
base_url = "http://localhost:1234/v1"
default_model = "qwen2.5-coder-7b-instruct"

[providers.custom.ollama]
enabled = false
base_url = "http://localhost:11434/v1"
default_model = "mistral"

The name after custom. is a label you choose (e.g. lm_studio, nvidia, groq). The one with enabled = true is active. Keys go in keys.toml using the same label. All configured custom providers persist β€” switching via /models just toggles enabled.

Free Prototyping with NVIDIA API + Kimi K2.5

Kimi K2.5 is a frontier-scale multimodal Mixture-of-Experts (MoE) model available for free on the NVIDIA API Catalog β€” no billing setup or credit card required. It handles complex reasoning and image/video understanding, making it a strong free alternative to paid models like Claude or Gemini for experimentation and agentic workflows.

Tested and verified with OpenCrabs Custom provider setup.

Quick start:

  1. Sign up at the NVIDIA API Catalog and verify your account
  2. Go to the Kimi K2.5 model page and click Get API Key (or "View Code" to see an auto-generated key)
  3. Configure in OpenCrabs via /models or config.toml:
[providers.custom.nvidia]
enabled = true
base_url = "https://integrate.api.nvidia.com/v1"
default_model = "moonshotai/kimi-k2.5"
# keys.toml
[providers.custom.nvidia]
api_key = "nvapi-..."

Provider priority: MiniMax > OpenRouter > Anthropic > OpenAI > Custom. The first provider with enabled = true is used on new sessions. Each provider has its own API key in keys.toml β€” no sharing or confusion.

Per-session provider: Each session remembers which provider and model it was using. Switch to Claude in one session, Kimi in another β€” when you /sessions switch between them, the provider restores automatically. No need to /models every time. New sessions inherit the current provider.


🀝 Agent-to-Agent (A2A) Protocol

OpenCrabs includes a built-in A2A gateway β€” an HTTP server implementing the A2A Protocol RC v1.0 for peer-to-peer agent communication. Other A2A-compatible agents can discover OpenCrabs, send it tasks, and get results back β€” all via standard JSON-RPC 2.0.

Enabling A2A

Add to ~/.opencrabs/config.toml:

[a2a]
enabled = true
bind = "127.0.0.1"   # Loopback only (default)
port = 18790          # Gateway port
# allowed_origins = ["http://localhost:3000"]  # CORS (empty = blocked)

No API keys required β€” A2A is config-only.

Endpoints

EndpointMethodDescription
/.well-known/agent.jsonGETAgent Card β€” discover skills, capabilities, supported content types
/a2a/v1POSTJSON-RPC 2.0 β€” message/send, tasks/get, tasks/cancel
/a2a/healthGETHealth check

Quick Start Examples

# Discover the agent
curl http://127.0.0.1:18790/.well-known/agent.json | jq .

# Send a message (creates a task)
curl -X POST http://127.0.0.1:18790/a2a/v1 \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "message/send",
    "params": {
      "message": {
        "role": "user",
        "parts": [{"kind": "text", "text": "What tools do you have?"}]
      }
    }
  }'

# Poll a task by ID
curl -X POST http://127.0.0.1:18790/a2a/v1 \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":2,"method":"tasks/get","params":{"id":"TASK_ID"}}'

# Cancel a running task
curl -X POST http://127.0.0.1:18790/a2a/v1 \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":3,"method":"tasks/cancel","params":{"id":"TASK_ID"}}'

Bee Colony Debate

OpenCrabs supports multi-agent structured debate via the Bee Colony protocol β€” based on ReConcile (ACL 2024) confidence-weighted voting. Multiple "bee" agents argue across configurable rounds, each enriched with knowledge context from QMD memory search, then converge on a consensus answer with confidence scores.

Security Notes

  • Loopback only by default β€” binds to 127.0.0.1, not 0.0.0.0
  • CORS locked down β€” no cross-origin requests unless allowed_origins is explicitly set
  • No authentication built in β€” do not expose to public internet without a reverse proxy + auth layer

πŸš€ Quick Start

Option 1: Download Binary (just run it)

Grab a pre-built binary from GitHub Releases β€” available for Linux (amd64/arm64), macOS (amd64/arm64), and Windows.

# Download, extract, run
tar xzf opencrabs-linux-amd64.tar.gz
./opencrabs

The onboarding wizard handles everything on first run.

Note: /rebuild works even with pre-built binaries β€” it auto-clones the source to ~/.opencrabs/source/ on first use, then builds and hot-restarts. For active development or adding custom tools, Option 2 gives you the source tree directly.

Option 2: Build from Source (full control)

Required for /rebuild, adding custom tools, or modifying the agent.

Prerequisites:

  • Rust nightly (2024 edition) β€” Install Rust, then rustup toolchain install nightly. The project includes a rust-toolchain.toml that selects nightly automatically
  • An API key from at least one supported provider
  • SQLite (bundled via sqlx)
  • Linux: build-essential, pkg-config, libssl-dev, libchafa-dev
# Clone
git clone https://github.com/adolfousier/opencrabs.git
cd opencrabs

# Build & run (development)
cargo run --bin opencrabs

# Or build release and run directly
cargo build --release
./target/release/opencrabs

API Keys: OpenCrabs uses keys.toml instead of .env for API keys. The onboarding wizard will help you set it up, or edit ~/.opencrabs/keys.toml directly. Keys are handled at runtime β€” no OS environment pollution.

First run? The onboarding wizard will guide you through provider setup, workspace, and more. See Onboarding Wizard.

Option 3: Docker (sandboxed)

Run OpenCrabs in an isolated container. Build takes ~15min (Rust release + LTO).

# Clone and run
git clone https://github.com/adolfousier/opencrabs.git
cd opencrabs

# Run with docker compose
# API keys are mounted from keys.toml on host
docker compose -f src/docker/compose.yml up --build

Config, workspace, and memory DB persist in a Docker volume across restarts. API keys in keys.toml are mounted into the container at runtime β€” never baked into the image.

CLI Commands

# Interactive TUI (default)
cargo run --bin opencrabs
cargo run --bin opencrabs -- chat

# Onboarding wizard (first-time setup)
cargo run --bin opencrabs -- onboard
cargo run --bin opencrabs -- chat --onboard   # Force wizard before chat

# Non-interactive single command
cargo run --bin opencrabs -- run "What is Rust?"
cargo run --bin opencrabs -- run --format json "List 3 programming languages"
cargo run --bin opencrabs -- run --format markdown "Explain async/await"

# Configuration
cargo run --bin opencrabs -- init              # Initialize config
cargo run --bin opencrabs -- config            # Show current config
cargo run --bin opencrabs -- config --show-secrets

# Database
cargo run --bin opencrabs -- db init           # Initialize database
cargo run --bin opencrabs -- db stats          # Show statistics

# Debug mode
cargo run --bin opencrabs -- -d                # Enable file logging
cargo run --bin opencrabs -- -d run "analyze this"

# Log management
cargo run --bin opencrabs -- logs status
cargo run --bin opencrabs -- logs view
cargo run --bin opencrabs -- logs view -l 100
cargo run --bin opencrabs -- logs clean
cargo run --bin opencrabs -- logs clean -d 3

Tip: After cargo build --release, run the binary directly: ./target/release/opencrabs

Make It Available System-Wide

After downloading or building, add the binary to your PATH so you can run opencrabs from any project directory:

# Symlink (recommended β€” always points to latest build)
sudo ln -sf $(pwd)/target/release/opencrabs /usr/local/bin/opencrabs

# Or copy
sudo cp target/release/opencrabs /usr/local/bin/

Then from any project:

cd /your/project
opencrabs

Use /cd inside OpenCrabs to switch working directory at runtime without restarting.

Output formats for non-interactive mode: text (default), json, markdown


πŸ§™ Onboarding Wizard

First-time users are guided through an 8-step setup wizard that appears automatically after the splash screen.

How It Triggers

  • Automatic: When no ~/.opencrabs/config.toml exists and no API keys are set in keys.toml
  • CLI: cargo run --bin opencrabs -- onboard (or opencrabs onboard after install)
  • Chat flag: cargo run --bin opencrabs -- chat --onboard to force the wizard before chat
  • Slash command: Type /onboard in the chat to re-run it anytime

The 8 Steps

StepTitleWhat It Does
1Mode SelectionQuickStart (sensible defaults) vs Advanced (full control)
2Model & AuthPick provider (Anthropic, OpenAI, Gemini, OpenRouter, Minimax, Custom) β†’ enter token/key β†’ model list fetched live from API β†’ select model. Auto-detects existing keys from keys.toml
3WorkspaceSet brain workspace path (default ~/.opencrabs/) β†’ seed template files (SOUL.md, IDENTITY.md, etc.)
4GatewayConfigure HTTP API gateway: port, bind address, auth mode
5ChannelsToggle messaging integrations (Telegram, Discord, WhatsApp, Slack, Trello)
6DaemonInstall background service (systemd on Linux, LaunchAgent on macOS)
7Health CheckVerify API key, config, workspace β€” shows pass/fail summary
8Brain PersonalizationTell the agent about yourself and how you want it to behave β†’ AI generates personalized brain files (SOUL.md, IDENTITY.md, USER.md, etc.)

QuickStart mode skips steps 4-6 with sensible defaults. Advanced mode lets you configure everything.

Brain Personalization (Step 8)

Two input fields: About You (who you are) and Your OpenCrabs (how the agent should behave). The LLM uses these plus the 6 workspace template files to generate personalized brain files.

  • First run: Empty fields, static templates as reference β†’ LLM generates β†’ writes to workspace
  • Re-run: Fields pre-populated with truncated preview of existing USER.md / IDENTITY.md β†’ edit to regenerate or Esc to skip
  • Regeneration: LLM receives the current workspace files (not static templates), so any manual edits you made are preserved as context
  • Overwrite: Only files with new AI-generated content are overwritten; untouched files keep their current state
  • No extra persistence files β€” the brain files themselves are the source of truth

Wizard Navigation

KeyAction
Tab / Shift+TabNavigate between fields
Up / DownScroll through lists
EnterConfirm / next step
SpaceToggle checkboxes
EscGo back one step

πŸ”‘ API Keys (keys.toml)

OpenCrabs uses ~/.opencrabs/keys.toml as the single source for all API keys, bot tokens, and search keys. No .env files, no OS keyring, no environment variables for secrets. Keys are loaded at runtime and can be modified by the agent.

# ~/.opencrabs/keys.toml β€” chmod 600!

# LLM Providers
[providers.anthropic]
api_key = "sk-ant-api03-YOUR_KEY"    # or OAuth: "sk-ant-oat01-..."

[providers.openai]
api_key = "sk-YOUR_KEY"

[providers.openrouter]
api_key = "sk-or-YOUR_KEY"

[providers.minimax]
api_key = "your-minimax-key"

[providers.custom.your_name]
api_key = "your-key"                 # not required for local LLMs

# Messaging Channels β€” tokens/secrets only (config.toml holds allowed_users, allowed_channels, etc.)
[channels.telegram]
token = "123456789:ABCdef..."

[channels.discord]
token = "your-discord-bot-token"

[channels.slack]
token = "xoxb-your-bot-token"
app_token = "xapp-your-app-token"   # Required for Socket Mode

[channels.trello]
app_token = "your-trello-api-key"   # API Key from trello.com/power-ups/admin
token = "your-trello-api-token"     # Token from the authorization URL

# Web Search
[providers.web_search.exa]
api_key = "your-exa-key"

[providers.web_search.brave]
api_key = "your-brave-key"

# Voice (STT/TTS)
[providers.stt.groq]
api_key = "your-groq-key"

[providers.tts.openai]
api_key = "your-openai-key"

OAuth tokens (sk-ant-oat prefix) are auto-detected β€” OpenCrabs uses Authorization: Bearer with the anthropic-beta: oauth-2025-04-20 header automatically.

Trello note: app_token holds the Trello API Key and token holds the Trello API Token β€” this naming follows the shared ChannelConfig schema used by all channels, where app_token is the app-level credential and token is the user-level credential.

Security: Always chmod 600 ~/.opencrabs/keys.toml and add keys.toml to .gitignore.


🏠 Using Local LLMs

OpenCrabs works with any OpenAI-compatible local inference server for 100% private, zero-cost operation.

LM Studio (Recommended)

  1. Download and install LM Studio
  2. Download a model (e.g., qwen2.5-coder-7b-instruct, Mistral-7B-Instruct, Llama-3-8B)
  3. Start the local server (default port 1234)
  4. Add to config.toml β€” no API key needed:
[providers.custom.lm_studio]
enabled = true
base_url = "http://localhost:1234/v1"
default_model = "qwen2.5-coder-7b-instruct"   # Must EXACTLY match LM Studio model name
models = ["qwen2.5-coder-7b-instruct", "llama-3-8B", "mistral-7B-instruct"]

Critical: The default_model value must exactly match the model name shown in LM Studio's Local Server tab (case-sensitive).

Ollama

ollama pull mistral

Add to config.toml β€” no API key needed:

[providers.custom.ollama]
enabled = true
base_url = "http://localhost:11434/v1"
default_model = "mistral"
models = ["mistral", "llama3", "codellama"]

Multiple Local Providers

Want both LM Studio and Ollama configured? Use named providers and switch via /models:

[providers.custom.lm_studio]
enabled = true
base_url = "http://localhost:1234/v1"
default_model = "qwen2.5-coder-7b-instruct"
models = ["qwen2.5-coder-7b-instruct", "llama-3-8B", "mistral-7B-instruct"]

[providers.custom.ollama]
enabled = false
base_url = "http://localhost:11434/v1"
default_model = "mistral"
models = ["mistral", "llama3", "codellama"]

The name after custom. is just a label you choose. The first one with enabled = true is used. Switch anytime via /models or /onboard.

Recommended Models

ModelRAMBest For
Qwen-2.5-7B-Instruct16 GBCoding tasks
Mistral-7B-Instruct16 GBGeneral purpose, fast
Llama-3-8B-Instruct16 GBBalanced performance
DeepSeek-Coder-6.7B16 GBCode-focused
TinyLlama-1.1B4 GBQuick responses, lightweight

Tips:

  • Start with Q4_K_M quantization for best speed/quality balance
  • Set context length to 8192+ in LM Studio settings
  • Use Ctrl+N to start a new session if you hit context limits
  • GPU acceleration significantly improves inference speed

Cloud vs Local Comparison

AspectCloud (Anthropic)Local (LM Studio)
PrivacyData sent to API100% private
CostPer-token pricingFree after download
Speed1-2s (network)2-10s (hardware-dependent)
QualityExcellent (Claude 4.x)Good (model-dependent)
OfflineRequires internetWorks offline

See LM_STUDIO_GUIDE.md for detailed setup and troubleshooting.


πŸ“ Configuration

Configuration Files

OpenCrabs uses two config files:

  1. ~/.opencrabs/config.toml β€” Provider settings, models, channels (safe to commit)
  2. ~/.opencrabs/keys.toml β€” API keys (chmod 600, NEVER commit!)

Search order for config.toml:

  1. ~/.opencrabs/config.toml (primary)
  2. ~/.config/opencrabs/config.toml (legacy fallback)
  3. ./opencrabs.toml (current directory override)
# Initialize config
cargo run -- init

# Copy the examples
cp config.toml.example ~/.opencrabs/config.toml
cp keys.toml.example ~/.opencrabs/keys.toml
chmod 600 ~/.opencrabs/keys.toml  # IMPORTANT: Secure the keys file!

Example: Hybrid Setup (Local + Cloud)

Keep multiple providers configured β€” enable the one you want to use, disable the rest. Switch anytime by toggling enabled or using /onboard.

In config.toml:

# Local LLM β€” currently active
[providers.custom.lm_studio]
enabled = true
base_url = "http://localhost:1234/v1"
default_model = "qwen2.5-coder-7b-instruct"
models = ["qwen2.5-coder-7b-instruct", "llama-3-8B"]

# Cloud API β€” disabled, enable when you need it
[providers.anthropic]
enabled = false
default_model = "claude-opus-4-6"

In keys.toml:

[providers.anthropic]
api_key = "sk-ant-api03-YOUR_KEY"

Operational Environment Variables

All API keys and secrets are stored in keys.toml β€” not in environment variables. The only env vars OpenCrabs uses are operational:

VariableDescription
DEBUG_LOGS_LOCATIONCustom log directory path (default: .opencrabs/logs/)
OPENCRABS_BRAIN_PATHCustom brain workspace path (default: ~/.opencrabs/)

πŸ’° Pricing Customization (usage_pricing.toml)

OpenCrabs tracks real token costs per model using a centralized pricing table at ~/.opencrabs/usage_pricing.toml. It's written automatically on first run with sensible defaults.

Why it matters:

  • /usage shows real costs grouped by model across all sessions
  • Old sessions with stored tokens but zero cost get estimated costs (shown as ~$X.XX in yellow)
  • Unknown models show $0.00 instead of silently ignoring them

Customizing prices:

# ~/.opencrabs/usage_pricing.toml
# Edit live β€” changes take effect on next /usage open, no restart needed.

[providers.anthropic]
entries = [
  { prefix = "claude-sonnet-4",  input_per_m = 3.0,  output_per_m = 15.0 },
  { prefix = "claude-opus-4",    input_per_m = 5.0,  output_per_m = 25.0 },
  { prefix = "claude-haiku-4",   input_per_m = 1.0,  output_per_m = 5.0  },
]

[providers.minimax]
entries = [
  { prefix = "minimax-m2.5",     input_per_m = 0.30, output_per_m = 1.20 },
]

# Add any provider β€” prefix is matched case-insensitively as a substring
[providers.my_custom_model]
entries = [
  { prefix = "my-model-v1",      input_per_m = 1.00, output_per_m = 3.00 },
]

A full example with all built-in providers (Anthropic, OpenAI, MiniMax, Google, DeepSeek, Meta) is available at usage_pricing.toml.example in the repo root.


πŸ”§ Tool System

OpenCrabs includes a built-in tool execution system. The AI can use these tools during conversation:

ToolDescription
read_fileRead file contents with syntax awareness
write_fileCreate or modify files
edit_filePrecise text replacements in files
bashExecute shell commands
lsList directory contents
globFind files matching patterns
grepSearch file contents with regex
web_searchSearch the web (DuckDuckGo, always available, no key needed)
exa_searchNeural web search via EXA AI (free via MCP, no API key needed; set key in keys.toml for higher rate limits)
brave_searchWeb search via Brave Search (set key in keys.toml β€” free $5/mo credits at brave.com/search/api)
execute_codeRun code in various languages
notebook_editEdit Jupyter notebooks
parse_documentExtract text from PDF, DOCX, HTML
task_managerManage agent tasks
http_requestMake HTTP requests
memory_searchHybrid semantic search across past memory logs β€” FTS5 keyword + vector embeddings (768-dim, local GGUF model) combined via RRF. No API key needed, runs offline
config_managerRead/write config.toml and commands.toml at runtime (change settings, add/remove commands, reload config)
session_contextAccess session information
planCreate structured execution plans

⌨️ Keyboard Shortcuts

Global

ShortcutAction
Ctrl+CFirst press clears input, second press (within 3s) quits
Ctrl+NNew session
Ctrl+LList/switch sessions
Ctrl+KClear current session
Page Up/DownScroll chat history
Mouse ScrollScroll chat history
EscapeClear input / close overlay

Chat Mode

ShortcutAction
EnterSend message
Alt+Enter / Shift+EnterNew line in input
← / β†’Move cursor one character
Ctrl+← / Ctrl+β†’Jump by word
Home / EndJump to start/end of input
DeleteDelete character after cursor
Ctrl+Backspace / Alt+BackspaceDelete word before cursor
Escape Γ—2Abort in-progress request
/helpOpen help dialog
/modelShow current model
/modelsSwitch model (fetches live from provider API)
/usageToken/cost stats β€” shows current session + all-time breakdown grouped by model with estimated costs for historical sessions
/onboardRun setup wizard
/sessionsOpen session manager
/approveTool approval policy selector (approve-only / session / yolo)
/compactCompact context (summarize + trim for long sessions)
/rebuildBuild from source & hot-restart β€” streams live compiler output to chat, auto exec() restarts on success (no prompt), auto-clones repo if no source tree found
/cdChange working directory (directory picker)
/settings or SOpen Settings screen (provider, approval, commands, paths)

Sessions Mode

Each session shows its provider/model badge (e.g. [anthropic/claude-sonnet-4-6]) and token count. Sessions processing in the background show a spinner; sessions with unread responses show a green dot.

ShortcutAction
↑ / ↓Navigate sessions
EnterLoad selected session (auto-restores its provider + model)
RRename session
DDelete session
EscBack to chat

Tool Approval (Inline)

When the AI requests a tool that needs permission, an inline approval prompt appears in chat. Approvals are session-aware: background sessions auto-approve tool calls so they don't block, and switching sessions never loses a pending approval.

ShortcutAction
↑ / ↓Navigate approval options
EnterConfirm selected option
D / EscDeny the tool request
VToggle parameter details

Approval options:

OptionEffect
Allow onceApprove this single tool call
Allow all for this taskAuto-approve all tools this session (resets on session switch)
Allow all moving forwardAuto-approve all tools permanently (app lifetime)

Use /approve to change your approval policy at any time (persisted to config.toml):

PolicyDescription
Approve-onlyAlways ask before executing tools (default)
Allow all (session)Auto-approve all tools for the current session
Yolo modeExecute everything without approval until reset

πŸ” Debug and Logging

OpenCrabs uses a conditional logging system β€” no log files by default.

# Enable debug mode (creates log files)
opencrabs -d
cargo run -- -d

# Logs stored in ~/.opencrabs/logs/ (user workspace, not in repo)
# Daily rolling rotation, auto-cleanup after 7 days

# Management
opencrabs logs status    # Check logging status
opencrabs logs view      # View recent entries
opencrabs logs clean     # Clean old logs
opencrabs logs clean -d 3  # Clean logs older than 3 days

When debug mode is enabled:

  • Log files created in ~/.opencrabs/logs/
  • DEBUG level with thread IDs, file names, line numbers
  • Daily rolling rotation

When disabled (default):

  • No log files created
  • Only warnings and errors to stderr
  • Clean workspace

🧠 Brain System & 3-Tier Memory

OpenCrabs's brain is dynamic and self-sustaining. Instead of a hardcoded system prompt, the agent assembles its personality, knowledge, and behavior from workspace files that can be edited between turns.

Brain Workspace

The brain reads markdown files from ~/.opencrabs/:

~/.opencrabs/                  # Home β€” everything lives here
β”œβ”€β”€ SOUL.md                    # Personality, tone, hard behavioral rules
β”œβ”€β”€ IDENTITY.md                # Agent name, vibe, style, workspace path
β”œβ”€β”€ USER.md                    # Who the human is, how to work with them
β”œβ”€β”€ AGENTS.md                  # Workspace rules, memory system, safety policies
β”œβ”€β”€ TOOLS.md                   # Environment-specific notes (SSH hosts, API accounts)
β”œβ”€β”€ MEMORY.md                  # Long-term curated context (never touched by auto-compaction)
β”œβ”€β”€ SECURITY.md                # Security policies and access controls
β”œβ”€β”€ BOOT.md                    # Startup checklist (optional, runs on launch)
β”œβ”€β”€ HEARTBEAT.md               # Periodic task definitions (optional)
β”œβ”€β”€ BOOTSTRAP.md               # First-run onboarding wizard (deleted after setup)
β”œβ”€β”€ config.toml                # App configuration (provider, model, approval policy)
β”œβ”€β”€ keys.toml                  # API keys (provider, channel, STT/TTS)
β”œβ”€β”€ commands.toml              # User-defined slash commands
β”œβ”€β”€ opencrabs.db               # SQLite β€” sessions, messages, plans
└── memory/                    # Daily memory logs (auto-compaction summaries)
    └── YYYY-MM-DD.md          # One per day, multiple compactions stack

Brain files are re-read every turn β€” edit them between messages and the agent immediately reflects the changes. Missing files are silently skipped; a hardcoded brain preamble is always present.

3-Tier Memory Architecture

TierLocationPurposeManaged By
1. Brain MEMORY.md~/.opencrabs/MEMORY.mdDurable, curated knowledge loaded into system brain every turnYou (the user)
2. Daily Memory Logs~/.opencrabs/memory/YYYY-MM-DD.mdAuto-compaction summaries with structured breakdowns of each sessionAuto (on compaction)
3. Hybrid Memory Searchmemory_search tool (FTS5 + vector)Hybrid semantic search β€” BM25 keyword + vector embeddings (768-dim, local GGUF) combined via Reciprocal Rank Fusion. No API key, zero cost, runs offlineAgent (via tool call)

How it works:

  1. When context hits 70%, auto-compaction summarizes the conversation into a structured breakdown (current task, decisions, files modified, errors, next steps)
  2. The summary is saved to a daily log at ~/.opencrabs/memory/2026-02-15.md (multiple compactions per day stack in the same file)
  3. The summary is shown to you in chat so you see exactly what was remembered
  4. The file is indexed in the background into the FTS5 database so the agent can search past logs with memory_search
  5. Brain MEMORY.md is never touched by auto-compaction β€” it stays as your curated, always-loaded context

Hybrid Memory Search (FTS5 + Vector Embeddings)

Memory search combines two strategies via Reciprocal Rank Fusion (RRF) for best-of-both-worlds recall:

  1. FTS5 keyword search β€” BM25-ranked full-text matching with porter stemming
  2. Vector semantic search β€” 768-dimensional embeddings via a local GGUF model (embeddinggemma-300M, ~300 MB)

The embedding model downloads automatically on first TUI launch (~300 MB, one-time) and runs entirely on CPU. No API key, no cloud service, no per-query cost, works offline. If the model isn't available yet (first launch, still downloading), search gracefully falls back to FTS-only.

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  ~/.opencrabs/memory/               β”‚
β”‚  β”œβ”€β”€ 2026-02-15.md                  β”‚  Markdown files (daily logs)
β”‚  β”œβ”€β”€ 2026-02-16.md                  β”‚
β”‚  └── 2026-02-17.md                  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
               β”‚ index on startup +
               β”‚ after each compaction
               β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  memory.db  (SQLite WAL mode)                   β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚  β”‚ documents + FTS5      β”‚ β”‚ vector embeddingsβ”‚ β”‚
β”‚  β”‚ (BM25, porter stem)   β”‚ β”‚ (768-dim, cosine)β”‚ β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
               β”‚ MATCH query          β”‚ cosine similarity
               β–Ό                      β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Reciprocal Rank Fusion (k=60)                  β”‚
β”‚  Merges keyword + semantic results              β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                      β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Hybrid-ranked results with snippets            β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Why local embeddings instead of OpenAI/cloud?

Local (embeddinggemma-300M)Cloud API (e.g. OpenAI)
CostFree forever~$0.0001/query, adds up
Privacy100% local, nothing leaves your machineData sent to third party
Latency~2ms (in-process, no network)100-500ms (HTTP round-trip)
OfflineWorks without internetRequires internet
SetupAutomatic, no API key neededRequires API key + billing
QualityExcellent for code/session recall (768-dim)Slightly better for general-purpose
Size~300 MB one-time downloadN/A

User-Defined Slash Commands

Tell OpenCrabs in natural language: "Create a /deploy command that runs deploy.sh" β€” and it writes the command to ~/.opencrabs/commands.toml via the config_manager tool:

[[commands]]
name = "/deploy"
description = "Deploy to staging server"
action = "prompt"
prompt = "Run the deployment script at ./scripts/deploy.sh for the staging environment."

Commands appear in autocomplete alongside built-in commands. After each agent response, commands.toml is automatically reloaded β€” no restart needed. Legacy commands.json files are auto-migrated on first load.

Self-Sustaining Architecture

OpenCrabs can modify its own source code, build, test, and hot-restart itself β€” triggered by the agent via the rebuild tool or by the user via /rebuild:

/rebuild          # User-triggered: build β†’ restart prompt
rebuild tool      # Agent-triggered: build β†’ ProgressEvent::RestartReady β†’ restart prompt

How it works:

  1. The agent edits source files using its built-in tools (read, write, edit, bash)
  2. SelfUpdater::build() runs cargo build --release asynchronously
  3. On success, a ProgressEvent::RestartReady is emitted β†’ bridged to TuiEvent::RestartReady
  4. The TUI switches to RestartPending mode β€” user presses Enter to confirm
  5. SelfUpdater::restart(session_id) replaces the process via Unix exec()
  6. The new binary starts with opencrabs chat --session <uuid> β€” resuming the same conversation
  7. A hidden wake-up message is sent to the agent so it greets the user and continues where it left off

Two trigger paths:

PathEntry pointSignal
Agent-triggeredrebuild tool (called by the agent after editing source)ProgressCallback β†’ RestartReady
User-triggered/rebuild slash commandTuiEvent::RestartReady directly

Key details:

  • The running binary is in memory β€” source changes on disk don't affect it until restart
  • If the build fails, the agent stays running and can read compiler errors to fix them
  • Session persistence via SQLite means no conversation context is lost across restarts
  • After restart, the agent auto-wakes with session context β€” no user input needed
  • Brain files (SOUL.md, MEMORY.md, etc.) are re-read every turn, so edits take effect immediately without rebuild
  • User-defined slash commands (commands.toml) also auto-reload after each agent response
  • Hot restart is Unix-only (exec() syscall); on Windows the build/test steps work but restart requires manual relaunch

Modules:

  • src/brain/self_update.rs β€” SelfUpdater struct with auto_detect(), build(), test(), restart()
  • src/brain/tools/rebuild.rs β€” RebuildTool (agent-callable, emits ProgressEvent::RestartReady)

πŸ—οΈ Architecture

Presentation Layer
    ↓
CLI (Clap) + TUI (Ratatui + Crossterm)
    ↓
Brain Layer (Dynamic system brain, user commands, config management, self-update)
    ↓
Application Layer
    ↓
Service Layer (Session, Message, Agent, Plan)
    ↓
Data Access Layer (SQLx + SQLite)
    ↓
Integration Layer (LLM Providers, LSP)

Key Technologies:

ComponentCrate
Async RuntimeTokio
Terminal UIRatatui + Crossterm
CLI ParsingClap (derive)
DatabaseSQLx (SQLite)
SerializationSerde + TOML
HTTP ClientReqwest
Syntax HighlightingSyntect
Markdownpulldown-cmark
LSP ClientTower-LSP
Provider RegistryCrabrace
Memory Searchqmd (FTS5 + vector embeddings)
Error Handlinganyhow + thiserror
Loggingtracing + tracing-subscriber
Securityzeroize

πŸ“ Project Structure

opencrabs/
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ main.rs           # Entry point
β”‚   β”œβ”€β”€ lib.rs            # Library root (crate root β€” required by Rust)
β”‚   β”œβ”€β”€ error/            # Error types (OpenCrabsError, ErrorCode)
β”‚   β”œβ”€β”€ logging/          # Conditional logging system
β”‚   β”œβ”€β”€ app/              # Application lifecycle
β”‚   β”œβ”€β”€ brain/            # Intelligence layer β€” LLM providers, agent, tools, brain system
β”‚   β”‚   β”œβ”€β”€ agent/        # Agent service + context management
β”‚   β”‚   β”œβ”€β”€ provider/     # Provider implementations (Anthropic, OpenAI-Compatible: OpenRouter, Minimax, Custom)
β”‚   β”‚   β”œβ”€β”€ tools/        # Tool system (read, write, bash, glob, grep, memory_search, etc.)
β”‚   β”‚   β”œβ”€β”€ tokenizer.rs  # Token counting (tiktoken-based)
β”‚   β”‚   β”œβ”€β”€ prompt_builder.rs  # BrainLoader β€” assembles system brain from workspace files
β”‚   β”‚   β”œβ”€β”€ commands.rs   # CommandLoader β€” user-defined slash commands (TOML)
β”‚   β”‚   └── self_update.rs # SelfUpdater β€” build, test, hot-restart via exec()
β”‚   β”œβ”€β”€ channels/         # Messaging integrations + voice (feature-gated)
β”‚   β”‚   β”œβ”€β”€ factory.rs    # ChannelFactory β€” shared factory for channel agent services
β”‚   β”‚   β”œβ”€β”€ telegram/     # Telegram bot (agent, handler)
β”‚   β”‚   β”œβ”€β”€ whatsapp/     # WhatsApp Web client (agent, handler, sqlx_store)
β”‚   β”‚   β”œβ”€β”€ discord/      # Discord bot (agent, handler)
β”‚   β”‚   β”œβ”€β”€ slack/        # Slack bot via Socket Mode (agent, handler)
β”‚   β”‚   β”œβ”€β”€ trello/       # Trello board poller (agent, client, handler, models)
β”‚   β”‚   └── voice/        # STT (Groq Whisper) + TTS (OpenAI)
β”‚   β”œβ”€β”€ cli/              # Command-line interface (Clap)
β”‚   β”œβ”€β”€ config/           # Configuration (config.toml + keys.toml)
β”‚   β”œβ”€β”€ db/               # Database layer (SQLx + SQLite)
β”‚   β”œβ”€β”€ services/         # Business logic (Session, Message, File, Plan)
β”‚   β”œβ”€β”€ memory/           # Memory search (FTS5 + vector embeddings via qmd)
β”‚   β”œβ”€β”€ tui/              # Terminal UI (Ratatui)
β”‚   β”‚   β”œβ”€β”€ onboarding.rs     # 8-step onboarding wizard (state + logic)
β”‚   β”‚   β”œβ”€β”€ onboarding_render.rs  # Wizard rendering
β”‚   β”‚   β”œβ”€β”€ splash.rs     # Splash screen
β”‚   β”‚   β”œβ”€β”€ app.rs        # App state + event handling
β”‚   β”‚   β”œβ”€β”€ render.rs     # Main render dispatch
β”‚   β”‚   └── runner.rs     # TUI event loop
β”‚   β”œβ”€β”€ utils/            # Utilities (retry, etc.)
β”‚   β”œβ”€β”€ migrations/       # SQLite migrations
β”‚   β”œβ”€β”€ tests/            # Integration tests
β”‚   β”œβ”€β”€ benches/          # Criterion benchmarks
β”‚   └── docs/             # Documentation + screenshots
β”œβ”€β”€ Cargo.toml
β”œβ”€β”€ config.toml.example
β”œβ”€β”€ keys.toml.example
└── LICENSE.md

πŸ› οΈ Development

Build from Source

# Development build
cargo build

# Release build (optimized, LTO, stripped)
cargo build --release

# Small release build
cargo build --profile release-small

# Run tests
cargo test

# Run benchmarks
cargo bench

# Format + lint
cargo fmt
cargo clippy -- -D warnings

Feature Flags

FeatureDescription
telegramTelegram bot integration (default: enabled)
whatsappWhatsApp Web integration (default: enabled)
discordDiscord bot integration (default: enabled)
slackSlack bot integration (default: enabled)
trelloTrello board polling + card management (default: enabled)
profilingEnable pprof flamegraph profiling (Unix only)

Performance

MetricValue
Binary size34 MB (release, stripped, LTO)
RAM idle (RSS)57 MB
RAM active (100 msgs)~20 MB
Startup time< 50 ms
Database ops< 10 ms (session), < 5 ms (message)
Embedding engineembeddinggemma-300M (~300 MB, local GGUF, auto-downloaded)

Memory Search (qmd β€” FTS5 + Vector Embeddings)

Hybrid semantic search: FTS5 BM25 keyword matching + 768-dim vector embeddings combined via Reciprocal Rank Fusion. Embedding model runs locally β€” no API key, zero cost, works offline.

Benchmarked with cargo bench --bench memory on release builds:

OperationTimeNotes
Store open1.81 msCold start (create DB + schema)
Index file214 Β΅sInsert content + document
Hash skip19.5 Β΅sAlready indexed, unchanged β€” fast path
FTS search (10 docs)397 Β΅s2-term BM25 query
FTS search (50 docs)2.57 msTypical user corpus
FTS search (100 docs)9.22 ms
FTS search (500 docs)88.1 msLarge corpus
Vector search (10 docs)247 Β΅s768-dim cosine similarity
Vector search (50 docs)1.02 ms768-dim cosine similarity
Vector search (100 docs)2.04 ms768-dim cosine similarity
Hybrid RRF (50 docs)3.49 msFTS + vector β†’ Reciprocal Rank Fusion
Insert embedding301 Β΅sSingle 768-dim vector
Bulk reindex (50 files)11.4 msFrom cold, includes store open
Deactivate document267 Β΅sPrune a single entry

Benchmarks (release build, in-memory SQLite, criterion):

OperationTime
Index 50 files (first run)11.4 ms
Per-file index214 Β΅s
Hash skip (unchanged file)19.5 Β΅s
FTS search (10 docs)397 Β΅s
FTS search (50 docs)2.57 ms
FTS search (100 docs)9.2 ms
Vector search (10 docs, 768-dim)247 Β΅s
Vector search (50 docs, 768-dim)1.02 ms
Vector search (100 docs, 768-dim)2.04 ms
Hybrid RRF (FTS + vector, 50 docs)3.49 ms
Insert embedding301 Β΅s
Deactivate document267 Β΅s

πŸ› Platform Notes

Linux

sudo apt-get install build-essential pkg-config libssl-dev libchafa-dev

Older CPUs (Sandy Bridge / AVX-only)

The default release binary requires AVX2 (Haswell 2013+). If you have an older CPU with only AVX support (Sandy Bridge/Ivy Bridge, 2011-2012), build from source with:

RUSTFLAGS="-C target-cpu=native" cargo build --release

Pre-built *-compat binaries are also available on the releases page for AVX-only CPUs. If your CPU lacks AVX entirely (pre-2011), vector embeddings are disabled and search falls back to FTS-only keyword matching.

macOS

No additional dependencies required.

Windows

Requires CMake, NASM, and Visual Studio Build Tools for native crypto dependencies:

# Option 1: Install build tools
# - CMake (add to PATH)
# - NASM (add to PATH)
# - Visual Studio Build Tools ("Desktop development with C++")

# Option 2: Use WSL2 (recommended)
sudo apt-get install build-essential pkg-config libssl-dev

See BUILD_NOTES.md for detailed troubleshooting.


πŸ”§ Troubleshooting

Agent Hallucinating Tool Calls

If the agent starts sending tool call approvals that don't render in the UI β€” meaning it believes it executed actions that never actually ran β€” the session context has become corrupted.

Fix: Start a new session.

  1. Press / and type sessions (or navigate to the Sessions panel)
  2. Press N to create a new session
  3. Continue your work in the fresh session

This reliably resolves the issue. A fix is coming in a future release.


⚠️ Disclaimers

Development Status

OpenCrabs is under active development. While functional, it may contain bugs or incomplete features.

Token Cost Responsibility

You are responsible for monitoring and managing your own API usage and costs.

  • API costs from cloud providers (Anthropic, OpenAI, etc.) are your responsibility
  • Set billing alerts with your provider
  • Consider local LLMs for cost-free operation
  • Use the built-in cost tracker to monitor spending

Support

Cloud API issues, billing questions, and account problems should be directed to the respective providers. OpenCrabs provides the tool; you manage your API relationships.


🀝 Contributing

Contributions welcome! Please read CONTRIBUTING.md for guidelines.

# Setup
git clone https://github.com/adolfousier/opencrabs.git
cd opencrabs
cargo build
cargo test
# Make changes, then submit a PR

πŸ“„ License

MIT License β€” See LICENSE.md for details.


πŸ™ Acknowledgments


πŸ“ž Support


Star History Chart

Star History Chart

✨ Stay Tuned


Built with Rust πŸ¦€ by Adolfo Usier

Related Projects