mirror of
https://github.com/zvx-echo6/meshai.git
synced 2026-05-21 15:14:45 +02:00
329 lines
11 KiB
Markdown
329 lines
11 KiB
Markdown
# 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](https://github.com/zvx-echo6/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](https://github.com/Yeraze/meshmonitor) by Yeraze to avoid duplicate responses
|
|
|
|
## Installation
|
|
|
|
```bash
|
|
# 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
|
|
|
|
```bash
|
|
# 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
|
|
|
|
```yaml
|
|
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:**
|
|
|
|
```bash
|
|
# 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:**
|
|
|
|
```yaml
|
|
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:**
|
|
|
|
```yaml
|
|
response:
|
|
max_length: 200 # Max chars per message
|
|
max_messages: 3 # Messages before continuation prompt
|
|
```
|
|
|
|
## Docker
|
|
|
|
### Quick Start with Docker
|
|
|
|
```bash
|
|
# 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):
|
|
```yaml
|
|
# data/config.yaml
|
|
connection:
|
|
type: "tcp"
|
|
tcp_host: "192.168.1.100" # Your Meshtastic node IP
|
|
tcp_port: 4403
|
|
```
|
|
|
|
**Serial Connection**:
|
|
```yaml
|
|
# 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:
|
|
|
|
```bash
|
|
LLM_API_KEY=your-key-here docker compose up -d
|
|
```
|
|
|
|
Or create a `.env` file:
|
|
```bash
|
|
LLM_API_KEY=your-key-here
|
|
```
|
|
|
|
### View Logs
|
|
|
|
```bash
|
|
docker compose logs -f meshai
|
|
```
|
|
|
|
## Running Alongside advBBS
|
|
|
|
MeshAI is designed to coexist with [advBBS](https://github.com/zvx-echo6/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`:
|
|
|
|
```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](https://github.com/Yeraze/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:**
|
|
|
|
```yaml
|
|
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`:
|
|
|
|
```ini
|
|
[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:
|
|
```bash
|
|
sudo systemctl daemon-reload
|
|
sudo systemctl enable meshai
|
|
sudo systemctl start meshai
|
|
```
|
|
|
|
## Acknowledgments
|
|
|
|
- [Meshtastic](https://meshtastic.org/) — the mesh networking platform
|
|
- [MeshMonitor](https://github.com/Yeraze/meshmonitor) by Yeraze — monitoring integration
|
|
- [advBBS](https://github.com/zvx-echo6/advbbs) — BBS coexistence design
|
|
- [sqlite-vec](https://github.com/asg017/sqlite-vec) by Alex Garcia — vector search in SQLite
|
|
- [fastembed](https://github.com/qdrant/fastembed) by Qdrant — fast local embeddings
|
|
|
|
## License
|
|
|
|
MIT License
|
|
|
|
## Author
|
|
|
|
K7ZVX - matt@echo6.co
|