# meshbot Bridges a [MeshCore](https://meshcore.io) companion radio to any OpenAI-compatible LLM endpoint (e.g. `llama-server`, vLLM, Ollama). Listens for direct messages on the device, runs each conversation through the LLM with full per-sender history stored in SQLite, and replies back over the mesh — trimmed to the MeshCore packet payload limit. ## Quick start ```sh python -m venv .venv && source .venv/bin/activate pip install -e . cp config.example.toml config.toml # edit serial_port and [llm] in config.toml python -m meshbot ``` Config file path defaults to `./config.toml` and can be overridden with `MESHBOT_CONFIG`. Any field can be overridden via env vars, e.g. `MESHBOT_LLM__API_KEY=sk-...`. ## Layout - `src/meshbot/bot.py` — connect, subscribe to `CONTACT_MSG_RECV`, dispatch each DM. - `src/meshbot/db.py` — SQLite schema and per-conversation repo functions. - `src/meshbot/llm.py` — `AsyncOpenAI` wrapper. - `src/meshbot/messages.py` — UTF-8-safe byte-length trimming. - `src/meshbot/config.py` — TOML + env-var settings (pydantic-settings). ## Docker Build and push a multi-arch image (`linux/amd64` + `linux/arm64`): ```sh docker login registry.example.com # once export MESHBOT_IMAGE=registry.example.com/team/meshbot ./scripts/build-and-push.sh # tags: latest + EXTRA_TAGS="v0.1.0" ./scripts/build-and-push.sh # add explicit version PUSH=0 PLATFORMS=linux/amd64 ./scripts/build-and-push.sh # local load only ``` Run via compose (set `MESHBOT_IMAGE`, `MESHBOT_LLM_BASE_URL`, `MESHBOT_LLM_MODEL`, optionally `MESHBOT_DEVICE`): ```sh export MESHBOT_IMAGE=registry.example.com/team/meshbot:latest export MESHBOT_LLM_BASE_URL=http://llama:8080/v1 export MESHBOT_LLM_MODEL=llama-3.1-8b-instruct export MESHBOT_DEVICE=/dev/ttyUSB0 docker compose up -d ``` The container expects `config.toml` mounted at `/etc/meshbot/config.toml` and persists SQLite to a named volume at `/data`. Any field can still be overridden via `MESHBOT_
__` env vars.