mirror of
https://github.com/zvx-echo6/meshai.git
synced 2026-05-21 15:14:45 +02:00
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:
parent
784b2e3fea
commit
5ad8da47bb
3 changed files with 7 additions and 228 deletions
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
# === BOT IDENTITY ===
|
||||
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)
|
||||
respond_to_mentions: true # Respond when name is mentioned
|
||||
respond_to_dms: true # Respond to direct messages
|
||||
|
|
@ -32,13 +32,6 @@ response:
|
|||
max_length: 150 # Max chars per message chunk
|
||||
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 ===
|
||||
history:
|
||||
database: /data/conversations.db
|
||||
|
|
@ -66,25 +59,8 @@ llm:
|
|||
Keep responses VERY brief - under 250 characters total.
|
||||
Be concise but friendly. No markdown formatting.
|
||||
|
||||
# === 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 | llm
|
||||
fallback: llm # openmeteo | wttr | llm | none
|
||||
default_location: "" # Default location for !weather (optional)
|
||||
|
|
|
|||
|
|
@ -36,12 +36,6 @@ response:
|
|||
max_length: 150
|
||||
max_messages: 2
|
||||
|
||||
rate_limits:
|
||||
messages_per_minute: 10
|
||||
global_messages_per_minute: 30
|
||||
cooldown_seconds: 5.0
|
||||
burst_allowance: 3
|
||||
|
||||
history:
|
||||
database: /data/conversations.db
|
||||
max_messages_per_user: 50
|
||||
|
|
@ -65,23 +59,6 @@ llm:
|
|||
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.
|
||||
|
||||
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
|
||||
echo "Default config created. Configure via http://localhost:7682"
|
||||
fi
|
||||
|
|
|
|||
176
meshai/config.py
176
meshai/config.py
|
|
@ -22,132 +22,6 @@ class BotConfig:
|
|||
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
|
||||
class ConnectionConfig:
|
||||
"""Meshtastic connection settings."""
|
||||
|
|
@ -201,16 +75,14 @@ class MemoryConfig:
|
|||
|
||||
@dataclass
|
||||
class LLMConfig:
|
||||
"""LLM backend settings with fallback support."""
|
||||
"""LLM backend settings."""
|
||||
|
||||
# Primary backend (backwards compatible with old config)
|
||||
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
|
||||
|
||||
# System prompt (kept for backwards compat, personality.system_prompt preferred)
|
||||
system_prompt: str = (
|
||||
"You are a helpful assistant on a Meshtastic mesh network. "
|
||||
"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
|
||||
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
|
||||
class OpenMeteoConfig:
|
||||
|
|
@ -251,14 +117,6 @@ class WeatherConfig:
|
|||
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
|
||||
class Config:
|
||||
"""Main configuration container."""
|
||||
|
|
@ -270,37 +128,10 @@ class Config:
|
|||
history: HistoryConfig = field(default_factory=HistoryConfig)
|
||||
memory: MemoryConfig = field(default_factory=MemoryConfig)
|
||||
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)
|
||||
|
||||
_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:
|
||||
"""Resolve API key from config or environment."""
|
||||
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:
|
||||
f.write(header)
|
||||
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()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue