- Python 99%
- Shell 0.5%
- Dockerfile 0.5%
- Replace build_lora_compact with personality version using emojis - Add _region_lora_compact helper for region-specific display - Skip empty regions in 3 loops (build_tier1_summary, utilization, list_regions_compact) - Update AIDA identity: she IS a physical node (!27780c47 AIDA-N2) - AIDA now knows she has real GPS coordinates and radio connections Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> |
||
|---|---|---|
| .github/workflows | ||
| meshai | ||
| .dockerignore | ||
| .gitignore | ||
| config.example.yaml | ||
| docker-compose.yml | ||
| docker-entrypoint.sh | ||
| Dockerfile | ||
| LICENSE | ||
| pyproject.toml | ||
| README.md | ||
| requirements.txt | ||
MeshAI
LLM-powered assistant for Meshtastic mesh networks.
Features
- LLM Chat: Responds to @mentions and DMs with AI-generated responses
- Multi-backend: Supports OpenAI, Anthropic Claude, Google Gemini, and local LLMs via LiteLLM
- Knowledge Base (RAG): Hybrid FTS5 + vector search over Meshtastic documentation
- Message Chunking: Sentence-aware splitting with continuation prompts for long responses
- Bang Commands:
!help,!ping,!reset,!status,!weather - Conversation History: Per-user context maintained in SQLite
- Rate Limiting: Configurable delays to avoid flooding the mesh
- advBBS Compatible: Runs alongside advBBS on the same node — protocol sync messages and mail notifications are automatically filtered
- Rich Configurator: Interactive TUI for easy setup
- MeshMonitor Integration: Syncs with MeshMonitor by Yeraze to avoid duplicate responses
Installation
# Clone the repository
git clone https://github.com/zvx-echo6/meshai.git
cd meshai
# Install with pip
pip install -e .
# Or install dependencies manually
pip install -r requirements.txt
Quick Start
# Run the configurator
meshai --config
# Or copy and edit the example config
cp config.example.yaml config.yaml
# Edit config.yaml with your settings
# Run the bot
meshai
Configuration
Run meshai --config to launch the interactive configurator, or edit config.yaml directly.
Key Settings
bot:
name: "ai" # @mention trigger
respond_to_mentions: true
respond_to_dms: true
connection:
type: "serial" # serial or tcp
serial_port: "/dev/ttyUSB0"
llm:
backend: "openai" # openai, anthropic, google
api_key: "your-api-key"
model: "gpt-4o-mini"
Using Local LLMs
MeshAI works with any OpenAI-compatible API, including:
- LiteLLM:
base_url: "http://localhost:4000/v1" - Open WebUI:
base_url: "http://localhost:3000/api" - Ollama:
base_url: "http://localhost:11434/v1"
Commands
| Command | Description |
|---|---|
!help |
Show available commands |
!ping |
Test connectivity |
!reset |
Clear your conversation history |
!status |
Show bot status and stats |
!weather [location] |
Get weather (uses GPS if no location given) |
Usage Examples
Chat via @mention:
@ai What's the weather like today?
> Seattle: 52F, Partly Cloudy, Wind 8mph
Direct message:
DM: Tell me a short joke
> Why don't scientists trust atoms? They make up everything!
Weather command:
!weather Portland
> Portland: 48F, Rain, Wind 12mph
Architecture
┌──────────────────────────────────────────────────────────────────┐
│ MeshAI │
├──────────────────────────────────────────────────────────────────┤
│ ┌─────────────┐ ┌─────────────┐ ┌──────────────────────┐ │
│ │ Meshtastic │ │ Message │ │ LLM Backend │ │
│ │ Connector │───▶│ Router │───▶│ (pluggable) │ │
│ │ Serial/TCP │ │ │ │ │ │
│ └─────────────┘ └──────┬──────┘ └──────────────────────┘ │
│ │ │ │ │
│ │ ┌──────▼──────┐ │ │
│ │ │ Conversation│ │ │
│ │ │ History │◀─────────────┘ │
│ │ │ (SQLite) │ │
│ │ └─────────────┘ │
│ │ │ │
│ │ ┌──────▼──────┐ ┌──────────────────────┐ │
│ │ │ Knowledge │───▶│ Hybrid FTS5+Vector │ │
│ │ │ Base │ │ (sqlite-vec + BGE) │ │
│ │ └─────────────┘ └──────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────┐ ┌─────────────┐ │
│ │ Responder │───▶│ Chunker │ Sentence-aware splitting │
│ │ │ │ │ + continuation prompts │
│ └─────────────┘ └─────────────┘ │
└──────────────────────────────────────────────────────────────────┘
Knowledge Base (RAG)
MeshAI can answer questions using a local knowledge base built from Meshtastic documentation. The system uses hybrid search combining:
- FTS5 keyword search — fast exact term matching with domain-aware query construction
- Vector embeddings — semantic similarity using
bge-small-en-v1.5(384 dimensions) - Reciprocal Rank Fusion — merges results from both methods for best relevance
Building the knowledge base:
# Extract from Meshtastic ZIM file
python scripts/zim_to_knowledge.py meshtastic.zim --output knowledge.db
# Or from markdown files
python scripts/md_to_knowledge.py docs/ --output knowledge.db
Configuration:
knowledge:
enabled: true
db_path: /data/meshai_knowledge.db
top_k: 5 # Number of chunks to retrieve
fts_weight: 0.5 # Weight for keyword matches (0-1)
vector_weight: 0.5 # Weight for semantic matches (0-1)
The knowledge base requires sqlite-vec and fastembed (installed automatically with requirements.txt).
Message Chunking
Long LLM responses are automatically split into mesh-friendly chunks:
- Sentence-aware — never splits a sentence across messages
- Configurable limits — max characters per message, max messages per response
- Continuation prompts — if content remains, asks "Want me to keep going?"
- Natural follow-ups — responds to "yes", "ok", "continue", "more", etc.
Configuration:
response:
max_length: 200 # Max chars per message
max_messages: 3 # Messages before continuation prompt
Docker
Quick Start with Docker
# Create working directory
mkdir -p meshai/data && cd meshai
# Download docker-compose file
curl -O https://raw.githubusercontent.com/zvx-echo6/meshai/main/docker-compose.yml
# Copy and edit config
curl -o data/config.yaml https://raw.githubusercontent.com/zvx-echo6/meshai/main/config.example.yaml
# Edit data/config.yaml with your settings
# Start
docker compose up -d
# View logs
docker compose logs -f
Docker Configuration
TCP Connection (recommended for Docker):
# data/config.yaml
connection:
type: "tcp"
tcp_host: "192.168.1.100" # Your Meshtastic node IP
tcp_port: 4403
Serial Connection:
# data/config.yaml
connection:
type: "serial"
serial_port: "/dev/ttyUSB0"
Then edit docker-compose.serial.yml to match your device path.
Environment Variables
You can pass the API key via environment variable instead of config file:
LLM_API_KEY=your-key-here docker compose up -d
Or create a .env file:
LLM_API_KEY=your-key-here
View Logs
docker compose logs -f meshai
Running Alongside advBBS
MeshAI is designed to coexist with advBBS on the same Meshtastic node. Both connect via TCP to meshtasticd and share the radio, but MeshAI automatically ignores advBBS traffic:
- Sync protocol —
MAILREQ|,MAILACK|,MAILDAT|,BOARDREQ|, etc. - RAP protocol —
advBBS|pings, pongs, and route advertisements - Mail notifications —
[MAIL]new message alerts - Bang commands in DMs —
!mail,!board, etc. are left for advBBS to handle
No special configuration is needed. The filter is enabled by default and can be toggled in config.yaml:
bot:
filter_bbs_protocols: true # set false to disable
Plain-text BBS responses (e.g. "Welcome back, matt!") are indistinguishable from normal user messages and will be processed normally — this is a known and accepted limitation.
MeshMonitor Integration
MeshAI integrates with MeshMonitor, a comprehensive Meshtastic monitoring platform by Yeraze. When enabled, MeshAI automatically fetches MeshMonitor's auto-responder trigger patterns and ignores messages that MeshMonitor handles, preventing duplicate responses on the mesh.
Features:
- Automatic trigger discovery via MeshMonitor's HTTP API
- Dynamic ignore list — no manual sync needed
- Trigger list injected into the LLM prompt so MeshAI can discuss MeshMonitor commands conversationally
- Configurable via TUI (option 9) or config.yaml
Configuration:
meshmonitor:
enabled: true
url: "http://192.168.1.100:8080"
inject_into_prompt: true
refresh_interval: 300
MeshMonitor is a separate project — get it at https://github.com/Yeraze/meshmonitor
Running as a Service
Create /etc/systemd/system/meshai.service:
[Unit]
Description=MeshAI - Meshtastic LLM Assistant
After=network.target
[Service]
Type=simple
User=your-user
WorkingDirectory=/path/to/meshai
ExecStart=/usr/bin/python3 -m meshai
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
Then:
sudo systemctl daemon-reload
sudo systemctl enable meshai
sudo systemctl start meshai
Acknowledgments
- Meshtastic — the mesh networking platform
- MeshMonitor by Yeraze — monitoring integration
- advBBS — BBS coexistence design
- sqlite-vec by Alex Garcia — vector search in SQLite
- fastembed by Qdrant — fast local embeddings
License
MIT License
Author
K7ZVX - matt@echo6.co