- connector.send_message accepts int or string destination
- channels.py converts node_id to str before string operations
- Rule stats write to /data/ (Docker volume) not /opt/meshai/data/
- 4a: Add threading.Lock to MeshConnector protecting _node_names and
_node_positions dicts that are read/written from Meshtastic's pubsub
thread callbacks (_on_receive, _on_node_update, _cache_node_info)
and read from async code (get_node_position, get_node_name)
- 4b: Add threading.Lock to StatusData protecting counters and activity
list that are written from the async event loop and read from the
HTTP server thread in to_dict()
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- 1a: Declare _position as proper dataclass field with field(default=None, init=False)
so hasattr() check isn't needed and the attribute always exists
- 1b: Load persisted conversation summaries from DB into memory cache on startup
via new _load_summaries() method called after backend creation
- 1c: Use Gemini's system_instruction parameter on GenerativeModel instead of
only prepending to first message, so system prompt persists across all turns
- 1d: Move 'import os' from line 198 to top of main.py with other imports
- 1e: Replace unreliable modulo-based cleanup timer with _last_cleanup timestamp
comparison that won't miss hours due to async sleep jitter
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Features:
- Multi-backend LLM support (OpenAI, Anthropic, Google)
- Rolling summary memory for token optimization (~70-80% reduction)
- Per-user conversation history with SQLite persistence
- Bang commands (!help, !ping, !reset, !status, !weather)
- Meshtastic integration via serial or TCP
- Message chunking for mesh network constraints (150 char limit)
- Rate limiting to prevent network congestion
- Rich TUI configurator
- Docker support
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>