Add comprehensive config options matching fq51bbs

New features:
- Rate limiting (per-user and global)
- Enhanced logging with file rotation
- LLM fallback backend support
- Safety filtering (profanity, blocked phrases, emergency keywords)
- User management (blocklist, allowlist, admin/VIP nodes)
- Custom commands with static responses
- Personality/prompt templates with persona switching
- Web status page with JSON API
- Periodic announcements/broadcasts
- Webhook integrations

New modules:
- rate_limiter.py - Per-user and global rate limiting
- safety.py - Response filtering and user access control
- personality.py - Prompt templates and persona management
- web_status.py - Simple web status dashboard
- announcements.py - Periodic broadcast scheduler
- webhook.py - Webhook notification client
- log_setup.py - Enhanced logging configuration
- backends/fallback.py - LLM fallback wrapper

Config expanded from ~50 to ~200 lines with full documentation.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Matt 2025-12-15 13:10:02 -07:00
commit 165da72d8d
13 changed files with 1796 additions and 48 deletions

View file

@ -1,51 +1,191 @@
# MeshAI Configuration
# Copy to config.yaml and edit as needed
# LLM-powered Meshtastic assistant
#
# Copy this to config.yaml and customize as needed
# For Docker: mount as /data/config.yaml
# === BOT IDENTITY ===
bot:
name: "ai" # @mention trigger (e.g., @ai)
owner: "K7ZVX" # Owner callsign/name for logging
respond_to_mentions: true # Respond to @botname mentions
respond_to_dms: true # Respond to direct messages
name: ai # Bot's trigger name (users say "ai help")
owner: "" # Owner's callsign (optional)
respond_to_mentions: true # Respond when name is mentioned
respond_to_dms: true # Respond to direct messages
# === MESHTASTIC CONNECTION ===
connection:
type: "serial" # serial or tcp
serial_port: "/dev/ttyUSB0" # Serial port (if type=serial)
tcp_host: "192.168.1.100" # TCP host (if type=tcp)
tcp_port: 4403 # TCP port (if type=tcp)
type: tcp # serial | tcp
serial_port: /dev/ttyUSB0 # For serial connection
tcp_host: localhost # For TCP connection (meshtasticd)
tcp_port: 4403
# === CHANNEL FILTERING ===
channels:
mode: "all" # "all" or "whitelist"
whitelist: [0] # Channel indices (if mode=whitelist)
mode: all # all | whitelist
whitelist: # Only respond on these channels (if mode=whitelist)
- 0
# === RESPONSE BEHAVIOR ===
response:
delay_min: 2.2 # Minimum delay before responding (seconds)
delay_max: 3.0 # Maximum delay before responding (seconds)
max_length: 150 # Max characters per message chunk
max_messages: 2 # Max message chunks per response
delay_min: 2.2 # Min delay before responding (seconds)
delay_max: 3.0 # Max delay before responding
max_length: 150 # Max chars per message chunk
max_messages: 2 # Max message chunks per response
history:
database: "conversations.db" # SQLite database file
max_messages_per_user: 20 # Max conversation history per user
conversation_timeout: 86400 # Reset conversation after N seconds (24h)
# === RATE LIMITING ===
rate_limits:
messages_per_minute: 10 # Per-user message limit
global_messages_per_minute: 30 # Total across all users
cooldown_seconds: 5.0 # Min time between responses to same user
burst_allowance: 3 # Allow short bursts before limiting
# === LOGGING ===
logging:
level: INFO # DEBUG | INFO | WARNING | ERROR
file: "" # Log file path (empty = console only)
max_size_mb: 10 # Max log file size
backup_count: 3 # Number of backup log files
log_messages: true # Log incoming messages
log_responses: true # Log outgoing responses
log_api_calls: false # Log raw LLM API requests (verbose)
# === LLM BACKEND ===
llm:
backend: "openai" # openai, anthropic, or google
api_key: "" # API key (or use env: LLM_API_KEY)
base_url: "https://api.openai.com/v1" # API base URL
model: "gpt-4o-mini" # Model to use
system_prompt: |
backend: openai # openai | anthropic | google
api_key: "" # API key (or use LLM_API_KEY env var)
base_url: https://api.openai.com/v1 # API base URL
model: gpt-4o-mini # Model name
timeout: 30 # Request timeout (seconds)
system_prompt: >-
You are a helpful assistant on a Meshtastic mesh network.
Keep responses VERY brief - under 250 characters total.
Be concise but friendly. No markdown formatting.
You may have access to web search for current information.
# Fallback backend (optional) - used if primary fails
# fallback:
# backend: openai
# api_key: ""
# base_url: https://api.openai.com/v1
# model: gpt-4o-mini
# timeout: 30
retry_attempts: 2 # Retries before fallback
fallback_on_error: true # Use fallback on errors
fallback_on_timeout: true # Use fallback on timeouts
# === SAFETY & FILTERING ===
safety:
max_response_length: 250 # Hard cap on response length
filter_profanity: false # Basic profanity filter
blocked_phrases: [] # Phrases to filter out of responses
require_mention: true # Only respond when name is mentioned
ignore_self: true # Don't respond to own messages
emergency_keywords: # Always respond to these (bypass rate limits)
- emergency
- help
- sos
# === USER MANAGEMENT ===
users:
blocklist: [] # Never respond to these node IDs
# - "!abc12345"
allowlist_only: false # If true, only respond to allowlist
allowlist: [] # Exclusive users (if allowlist_only=true)
admin_nodes: [] # Nodes with admin command access
vip_nodes: [] # Nodes that bypass rate limits
# === COMMANDS ===
commands:
enabled: true
prefix: "!" # Command prefix (e.g., !weather, !help)
disabled_commands: [] # Built-in commands to disable
# - reset # Disable !reset command
custom_commands: {} # User-defined static response commands
# Example custom commands:
# custom_commands:
# ping:
# response: "Pong! MeshAI online."
# rules:
# response: "Be respectful. Keep it brief. No spam."
# freq:
# response: "Primary: 906.875 MHz | Alt: 903.125 MHz"
# === PERSONALITY ===
personality:
system_prompt: "" # Override llm.system_prompt if set
context_injection: "" # Template with {time}, {sender_name}, {channel}
# Example: "Current time: {time}. Speaking with {sender_name}."
personas: {} # Named personality variants
# Example personas:
# personas:
# serious:
# trigger: "!serious"
# prompt: "Respond formally and technically. No jokes."
# casual:
# trigger: "!casual"
# prompt: "Be casual and use humor when appropriate."
# === CONVERSATION HISTORY ===
history:
database: /data/conversations.db
max_messages_per_user: 50 # Messages to keep per user
conversation_timeout: 86400 # Conversation expiry (seconds, 86400=24h)
auto_cleanup: true # Auto-delete old conversations
cleanup_interval_hours: 24 # How often to run cleanup
max_age_days: 30 # Delete conversations older than this
# === MEMORY OPTIMIZATION ===
memory:
enabled: true # Enable rolling summary memory
window_size: 4 # Recent message pairs to keep in full
summarize_threshold: 8 # Messages before re-summarizing
# === WEB STATUS PAGE ===
web_status:
enabled: false # Enable web status page
port: 8080 # Status page port
show_uptime: true
show_message_count: true
show_connected_nodes: true
show_recent_activity: false # Privacy concern - disabled by default
require_auth: false # Require password
auth_password: "" # Password if require_auth=true
# === ANNOUNCEMENTS ===
announcements:
enabled: false # Enable periodic announcements
interval_hours: 24 # Time between announcements
channel: 0 # Channel to broadcast on
messages: [] # Messages to rotate through
# Example:
# messages:
# - "MeshAI online. Mention 'ai' for help!"
# - "Type !help for available commands."
random_order: true # Randomize message order
# === WEATHER ===
weather:
primary: "openmeteo" # openmeteo, wttr, or llm
fallback: "llm" # openmeteo, wttr, llm, or none
default_location: "" # Default location if no GPS
primary: openmeteo # openmeteo | wttr | llm
fallback: llm # Fallback provider
default_location: "" # Default location if none specified
openmeteo:
url: "https://api.open-meteo.com/v1"
url: https://api.open-meteo.com/v1
wttr:
url: "https://wttr.in"
url: https://wttr.in
# === INTEGRATIONS ===
integrations:
weather: # Duplicate of top-level weather (for nesting)
primary: openmeteo
fallback: llm
default_location: ""
openmeteo:
url: https://api.open-meteo.com/v1
wttr:
url: https://wttr.in
webhook:
enabled: false # Enable webhook notifications
url: "" # Webhook URL
events: # Events to send
- message_received
- response_sent
- error