Strip config to working features only

Remove ~15 unused dataclasses (RateLimitsConfig, LoggingConfig,
SafetyConfig, UsersConfig, CommandsConfig, PersonalityConfig,
WebStatusConfig, AnnouncementsConfig, WebhookConfig, IntegrationsConfig,
etc). Strip config.example.yaml and docker-entrypoint.sh defaults.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Ubuntu 2026-02-24 00:25:34 +00:00
commit 5ad8da47bb
3 changed files with 7 additions and 228 deletions

View file

@ -6,7 +6,7 @@
# === BOT IDENTITY === # === BOT IDENTITY ===
bot: bot:
name: ai # Bot's trigger name (users say "ai help") name: ai # Bot's trigger name (users say "@ai help")
owner: "" # Owner's callsign (optional) owner: "" # Owner's callsign (optional)
respond_to_mentions: true # Respond when name is mentioned respond_to_mentions: true # Respond when name is mentioned
respond_to_dms: true # Respond to direct messages respond_to_dms: true # Respond to direct messages
@ -32,13 +32,6 @@ response:
max_length: 150 # Max chars per message chunk max_length: 150 # Max chars per message chunk
max_messages: 2 # Max message chunks per response max_messages: 2 # Max message chunks per response
# === 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
# === CONVERSATION HISTORY === # === CONVERSATION HISTORY ===
history: history:
database: /data/conversations.db database: /data/conversations.db
@ -66,25 +59,8 @@ llm:
Keep responses VERY brief - under 250 characters total. Keep responses VERY brief - under 250 characters total.
Be concise but friendly. No markdown formatting. Be concise but friendly. No markdown formatting.
# === WEB STATUS PAGE === # === WEATHER ===
web_status: weather:
enabled: false # Enable web status page primary: openmeteo # openmeteo | wttr | llm
port: 8080 # Status page port fallback: llm # openmeteo | wttr | llm | none
show_uptime: true default_location: "" # Default location for !weather (optional)
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

View file

@ -36,12 +36,6 @@ response:
max_length: 150 max_length: 150
max_messages: 2 max_messages: 2
rate_limits:
messages_per_minute: 10
global_messages_per_minute: 30
cooldown_seconds: 5.0
burst_allowance: 3
history: history:
database: /data/conversations.db database: /data/conversations.db
max_messages_per_user: 50 max_messages_per_user: 50
@ -65,23 +59,6 @@ llm:
You are a helpful assistant on a Meshtastic mesh network. You are a helpful assistant on a Meshtastic mesh network.
Keep responses VERY brief - under 250 characters total. Keep responses VERY brief - under 250 characters total.
Be concise but friendly. No markdown formatting. Be concise but friendly. No markdown formatting.
web_status:
enabled: false
port: 8080
show_uptime: true
show_message_count: true
show_connected_nodes: true
show_recent_activity: false
require_auth: false
auth_password: ""
announcements:
enabled: false
interval_hours: 24
channel: 0
messages: []
random_order: true
EOF EOF
echo "Default config created. Configure via http://localhost:7682" echo "Default config created. Configure via http://localhost:7682"
fi fi

View file

@ -22,132 +22,6 @@ class BotConfig:
filter_bbs_protocols: bool = True filter_bbs_protocols: bool = True
@dataclass
class RateLimitsConfig:
"""Rate limiting settings."""
messages_per_minute: int = 10 # Per-user message limit
global_messages_per_minute: int = 30 # Total across all users
cooldown_seconds: float = 5.0 # Min time between responses to same user
burst_allowance: int = 3 # Allow short bursts before limiting
@dataclass
class LoggingConfig:
"""Logging settings."""
level: str = "INFO" # DEBUG | INFO | WARNING | ERROR
file: str = "" # Empty = console only
max_size_mb: int = 10
backup_count: int = 3
log_messages: bool = True # Log incoming messages
log_responses: bool = True # Log outgoing responses
log_api_calls: bool = False # Log raw LLM API requests (verbose)
@dataclass
class LLMBackendConfig:
"""Single LLM backend configuration."""
backend: str = "openai" # openai, anthropic, google
api_key: str = ""
base_url: str = "https://api.openai.com/v1"
model: str = "gpt-4o-mini"
timeout: int = 30
@dataclass
class SafetyConfig:
"""Response filtering and safety settings."""
max_response_length: int = 250 # Hard cap on response length
filter_profanity: bool = False # Basic profanity filter
blocked_phrases: list[str] = field(default_factory=list) # Phrases to filter out
require_mention: bool = True # Only respond when mentioned by name
ignore_self: bool = True # Don't respond to own messages
emergency_keywords: list[str] = field(
default_factory=lambda: ["emergency", "help", "sos"]
) # Always respond to these
prompt_injection_guard: bool = True # Basic prompt injection detection
@dataclass
class UsersConfig:
"""User management settings."""
blocklist: list[str] = field(default_factory=list) # Never respond to these node IDs
allowlist_only: bool = False # If true, only respond to allowlist
allowlist: list[str] = field(default_factory=list) # Exclusive users
admin_nodes: list[str] = field(default_factory=list) # Nodes with admin commands
vip_nodes: list[str] = field(default_factory=list) # Skip rate limits
@dataclass
class CustomCommandConfig:
"""Custom static command definition."""
response: str = ""
@dataclass
class CommandsConfig:
"""Command customization settings."""
enabled: bool = True
prefix: str = "!" # Command prefix
custom_commands: dict = field(default_factory=dict) # name -> response mapping
disabled_commands: list[str] = field(default_factory=list) # Built-in commands to disable
@dataclass
class PersonalityConfig:
"""Personality and prompt settings."""
system_prompt: str = (
"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."
)
context_injection: str = "" # Template with {time}, {sender_name}, {channel}
personas: dict = field(default_factory=dict) # trigger -> prompt mapping
@dataclass
class WebStatusConfig:
"""Web status page settings."""
enabled: bool = False
port: int = 8080
show_uptime: bool = True
show_message_count: bool = True
show_connected_nodes: bool = True
show_recent_activity: bool = False # Privacy concern
require_auth: bool = False
auth_password: str = ""
@dataclass
class AnnouncementsConfig:
"""Periodic announcement settings."""
enabled: bool = False
interval_hours: int = 24
channel: int = 0
messages: list[str] = field(default_factory=list)
random_order: bool = True
@dataclass
class WebhookConfig:
"""Webhook integration settings."""
enabled: bool = False
url: str = ""
events: list[str] = field(
default_factory=lambda: ["message_received", "response_sent", "error"]
)
@dataclass @dataclass
class ConnectionConfig: class ConnectionConfig:
"""Meshtastic connection settings.""" """Meshtastic connection settings."""
@ -201,16 +75,14 @@ class MemoryConfig:
@dataclass @dataclass
class LLMConfig: class LLMConfig:
"""LLM backend settings with fallback support.""" """LLM backend settings."""
# Primary backend (backwards compatible with old config)
backend: str = "openai" # openai, anthropic, google backend: str = "openai" # openai, anthropic, google
api_key: str = "" api_key: str = ""
base_url: str = "https://api.openai.com/v1" base_url: str = "https://api.openai.com/v1"
model: str = "gpt-4o-mini" model: str = "gpt-4o-mini"
timeout: int = 30 timeout: int = 30
# System prompt (kept for backwards compat, personality.system_prompt preferred)
system_prompt: str = ( system_prompt: str = (
"You are a helpful assistant on a Meshtastic mesh network. " "You are a helpful assistant on a Meshtastic mesh network. "
"Keep responses VERY brief - under 250 characters total. " "Keep responses VERY brief - under 250 characters total. "
@ -219,12 +91,6 @@ class LLMConfig:
use_system_prompt: bool = True # Toggle to disable sending system prompt use_system_prompt: bool = True # Toggle to disable sending system prompt
web_search: bool = False # Enable web search (Open WebUI feature) web_search: bool = False # Enable web search (Open WebUI feature)
# Fallback settings
fallback: Optional[LLMBackendConfig] = None
retry_attempts: int = 2
fallback_on_error: bool = True
fallback_on_timeout: bool = True
@dataclass @dataclass
class OpenMeteoConfig: class OpenMeteoConfig:
@ -251,14 +117,6 @@ class WeatherConfig:
wttr: WttrConfig = field(default_factory=WttrConfig) wttr: WttrConfig = field(default_factory=WttrConfig)
@dataclass
class IntegrationsConfig:
"""External integrations settings."""
weather: WeatherConfig = field(default_factory=WeatherConfig)
webhook: WebhookConfig = field(default_factory=WebhookConfig)
@dataclass @dataclass
class Config: class Config:
"""Main configuration container.""" """Main configuration container."""
@ -270,37 +128,10 @@ class Config:
history: HistoryConfig = field(default_factory=HistoryConfig) history: HistoryConfig = field(default_factory=HistoryConfig)
memory: MemoryConfig = field(default_factory=MemoryConfig) memory: MemoryConfig = field(default_factory=MemoryConfig)
llm: LLMConfig = field(default_factory=LLMConfig) llm: LLMConfig = field(default_factory=LLMConfig)
# New config sections
rate_limits: RateLimitsConfig = field(default_factory=RateLimitsConfig)
logging: LoggingConfig = field(default_factory=LoggingConfig)
safety: SafetyConfig = field(default_factory=SafetyConfig)
users: UsersConfig = field(default_factory=UsersConfig)
commands: CommandsConfig = field(default_factory=CommandsConfig)
personality: PersonalityConfig = field(default_factory=PersonalityConfig)
web_status: WebStatusConfig = field(default_factory=WebStatusConfig)
announcements: AnnouncementsConfig = field(default_factory=AnnouncementsConfig)
integrations: IntegrationsConfig = field(default_factory=IntegrationsConfig)
# Keep weather at top level for backwards compatibility
weather: WeatherConfig = field(default_factory=WeatherConfig) weather: WeatherConfig = field(default_factory=WeatherConfig)
_config_path: Optional[Path] = field(default=None, repr=False) _config_path: Optional[Path] = field(default=None, repr=False)
def get_system_prompt(self) -> str:
"""Get effective system prompt, preferring personality config.
Deprecated: Use PersonalityManager.get_system_prompt() instead.
Kept for backwards compatibility.
"""
_config_logger.warning(
"Config.get_system_prompt() is deprecated. "
"Use PersonalityManager.get_system_prompt() instead."
)
if self.personality.system_prompt:
return self.personality.system_prompt
return self.llm.system_prompt
def resolve_api_key(self) -> str: def resolve_api_key(self) -> str:
"""Resolve API key from config or environment.""" """Resolve API key from config or environment."""
if self.llm.api_key: if self.llm.api_key:
@ -408,8 +239,3 @@ def save_config(config: Config, config_path: Optional[Path] = None) -> None:
with open(config_path, "w") as f: with open(config_path, "w") as f:
f.write(header) f.write(header)
yaml.dump(data, f, default_flow_style=False, sort_keys=False, allow_unicode=True) yaml.dump(data, f, default_flow_style=False, sort_keys=False, allow_unicode=True)
def get_default_config() -> Config:
"""Get a Config object with all default values."""
return Config()