Skip to content

Repository files navigation

RustFox Logo

RustFox — Telegram AI Assistant

CI MIT License Buy Me a Coffee GitHub Sponsors

What is RustFox?

An open-source, self-hosted Telegram AI assistant written in Rust. It solves a simple problem: most AI assistants are locked inside proprietary chat UIs with no access to your files, tools, or schedule. RustFox lives in Telegram — your everyday messaging app — and acts as a full agentic AI teammate.

Why RustFox?

Drop a file, ask a question, schedule a task — RustFox handles it. Powered by OpenRouter LLM (Kimi K2.6), it runs an agentic loop: receive your message, call sandboxed tools (file I/O, command execution, web search via MCP), and loop until done. It remembers context via SQLite + vector RAG, runs skills and sub-agents, and even verifies its own work.

Self-hosted, no cloud dependency. Single binary. Setup wizard. Runs as systemd/launchd service. cargo install and you're running in 2 minutes.

Star the repo ⭐, fork to contribute, or open an issue for feedback.

docs: README.md · GUIDE.md · ARCHITECTURE.md


Features

🤖 AI Agent OpenRouter LLM (default: moonshotai/kimi-k2.6), agentic loop with tool calling, configurable max iterations
🔧 Built-in Tools File read/write, command execution, file sending, task scheduling — all sandboxed
🧩 MCP Servers Connect any MCP-compatible server (Git, Brave Search, GitHub, Filesystem, Threads…)
🧠 Persistent Memory SQLite-backed conversation history, vector embedding search (hybrid + FTS5), RAG
🧬 Skills & Agents Folder-based skill instructions auto-loaded at startup; subagent skills with own model and tool whitelist
🤝 Agent Layer Isolated agentic mini-loops in agents/ with own model/tools; invoke_agent, spawn_agents, zero-trust verifier
🔄 Task Scheduling Cron and one-shot task scheduler with SQLite persistence
🌐 Web Portal Built-in browser UI (chat, agents, memory, tasks, settings) served from the same binary — token-auth, loopback by default
📦 Self-Hosting Single binary, 2-min setup wizard, background service (systemd/launchd/Windows Service)

→ Full feature reference: docs/GUIDE.md

Agent Lifecycle & Runtime

Capability Description
Self-Upgrade Trigger an in-place upgrade: pulls from git source or downloads the latest GitHub release binary. Auto-restarts after upgrade — no SSH, no manual steps.
Model Switching Switch OpenRouter models at runtime via /models. Interactive picker lets you choose the best model per task: fast/cheap for simple queries, powerful for complex reasoning.
Soul Files SOUL.md (persona), AGENTS.md (behaviour), USER.md (preferences) — persistent identity files auto-injected into every system prompt. Session-end self-reflection with .bak backups.

💭 Multi-Session & Multi-Model (Brainstorming)

⚠️ Planning phase — not yet implemented. This section captures ideas explored in the feat/readme-improve-multi-session-brainstorm branch.

The vision: run multiple concurrent chat sessions, each with its own model and isolated context.

Use Case Description
Parallel execution Run a cheap model for quick tasks while a powerful model tackles deep analysis — concurrently, not sequentially
Per-user isolation Each Telegram user gets their own session with independent conversation context and model preference
Sub-agent delegation Spawn sub-agents with different models (e.g., GPT-4o for code review, Claude for writing) without polluting the main session

Topics to explore:

  • Session lifecycle — create, switch, merge, archive
  • Per-session model binding vs global default model
  • Context isolation between sessions (independent or shared RAG?)
  • Telegram UX for multi-session management (inline buttons? slash commands?)
  • Persistence and RAG across session boundaries

See docs/roadmap/multi-session.md for detailed design notes.

Quick Start

1. Install

Option A — Download a release (recommended)

Download from the Releases page:

tar xzf rustfox-*.tar.gz

Option B — Build from source (recommended script)

git clone https://github.com/chinkan/RustFox && cd RustFox
./scripts/build-all.sh --install

build-all.sh builds the web portal frontend first (npm ci + vite build), then the Rust binary — the portal UI is compiled into the binary via include_dir!, so build order matters (see Building & Verifying). If you don't need the portal, plain cargo install --path . --locked still works.

2. Configure

# Browser wizard
./rustfox --setup

# Or terminal wizard
./rustfox --setup --cli

The wizard guides you through: Telegram bot token, allowed user IDs, OpenRouter API key, model, and optional MCP tools.

3. Run

rustfox
# or with a custom config:
rustfox --config /path/to/config.toml

4. (Optional) Background service

rustfox --service install   # Linux (systemd), macOS (launchd), or Windows
rustfox --service status

Configuration

Setting Description
telegram.bot_token Telegram Bot API token (from @BotFather)
telegram.allowed_user_ids Comma-separated user IDs allowed to use the bot
openrouter.api_key OpenRouter API key (openrouter.ai/keys)
openrouter.model LLM model ID (default: moonshotai/kimi-k2.6)
sandbox.allowed_directory Directory for sandboxed file/command operations
mcp_servers List of MCP servers to connect (see GUIDE.md)

→ Full configuration reference: docs/GUIDE.md


🌐 Web Portal

RustFox can serve a built-in web UI from the same binary — no separate frontend deploy. Open http://127.0.0.1:8090 in your browser to chat with the agent (live SSE token streaming), browse memory, manage scheduled tasks and sub-agents, and inspect your config.

Enable it in config.toml:

[portal]
enabled = true
port = 8090
bind = "127.0.0.1"        # keep loopback/private-network only
token_sha256 = "<sha256>" # hash of your login token (preferred over plaintext)

Generate a token + hash:

python3 -c 'import hashlib,secrets; t=secrets.token_hex(32); print("token:", t); print("token_sha256:", hashlib.sha256(t.encode()).hexdigest())'
Page What you can do
💬 Chat Talk to the agent in the browser, watch tool calls stream live; history persisted and isolated from Telegram
🧬 Agents Browse configured sub-agents, filter by name
🧠 Memory Search conversation/knowledge store (FTS5 hybrid), browse recent entries
🔄 Tasks List cron/one-shot tasks, view run history, pause/resume
⚙️ Settings Inspect active config (secrets masked)

🔒 The portal is off by default and intended for loopback/private networks (e.g. a Tailscale IP). Public exposure/TLS is out of scope for now.


Quick Tool Overview

Tool Description
read_file / write_file Read and write files within the sandbox
send_file Send a file from the sandbox to the current chat
self_upgrade Trigger self-upgrade from git source or GitHub release, auto-restart
read_soul_file Read SOUL.md, AGENTS.md, or USER.md soul files
update_soul_file Append or replace content in a soul file with .bak backup
revert_soul_file Restore a soul file from its most recent .bak backup
try_new_tech Sandboxed experiment — run Rust/JS code and check results
execute_command Run shell commands within the sandbox
schedule_task Schedule recurring (cron) or one-shot tasks
invoke_agent Run a predefined agent from the agents/ directory

→ Full tool reference: docs/GUIDE.md


Architecture

RustFox runs an agentic loop: user message → LLM (OpenRouter) → tool calls → execute → loop until final response. Tools dispatch to built-in functions, MCP servers, or skill/agent directories.

→ Full architecture with source tree and data flow: docs/ARCHITECTURE.md


🛠 Building & Verifying

One-command build (portal-safe)

./scripts/build-all.sh                # web (vite) → dist → cargo build --release
./scripts/build-all.sh --install      # ...then install to ~/.cargo/bin/rustfox
./scripts/build-all.sh --skip-web     # reuse existing web/dist (Rust only)
./scripts/build-all.sh --profile dev  # debug build (faster compile)

Why a script? The portal frontend is embedded into the binary at compile time (include_dir!("web/dist")). Two traps this guards against:

  1. Build order — cargo before vite build embeds a stale/empty dist → the portal renders a white screen. build-all.sh enforces web-first and fails fast if web/dist/index.html is missing.
  2. Stale embedding — include_dir! has no cargo change-fingerprint, so updating dist alone won't trigger a rebuild. The script touches the embedding module to force re-embedding.

Try the portal without Telegram/LLM

cargo run --release --example portal_preview   # serves the real embedded UI + seeded demo data

End-to-end regression gate (35 checks)

node e2e-verify.mjs     # Playwright: login → chat SSE → agents → memory → tasks → settings

Covers every portal page against the real embedded-dist binary (same code path as production), including a stub-dist control test that catches white-screen regressions. Zero console errors is part of the gate. CI runs the web build before cargo tests, and the same sequence applies to release builds.


Contributing

MIT License. See CONTRIBUTING.md for how to open issues and submit PRs.

Support

Buy Me a Coffee GitHub Sponsors

About

A Rust-based Telegram AI assistant powered by OpenRouter LLM with built-in sandboxed tools, scheduling, persistent memory, and MCP server integration.

Topics

Resources

Contributing

Stars

9 stars

Watchers

0 watching

Forks

Releases

Sponsor this project

Packages

Contributors

Languages