Vision-module-auto/claude_vision_auto/config.py
Svrnty 52b0813b64 feat: Add YAML-based configuration system
- Add default_config.yaml with customizable settings
- Model selection (minicpm-v, llama3.2-vision, llava)
- Customizable vision prompt for better responses
- Timing parameters (idle threshold, response delay)
- Approval keywords configuration
- User config at ~/.config/claude-vision-auto/config.yaml
- New command: claude-vision-config to generate user config
- Environment variables still override config files
- Added PyYAML dependency

Configuration priority:
1. Environment variables (highest)
2. User config (~/.config/claude-vision-auto/config.yaml)
3. Default config (package default)

Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Jean-Philippe Brule <jp@svrnty.io>
2025-10-29 10:19:35 -04:00

172 lines
5.4 KiB
Python
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""
Configuration for Claude Vision Auto
"""
import os
import yaml
from pathlib import Path
from typing import Dict, Any
def get_config_dir() -> Path:
"""Get configuration directory"""
config_dir = Path.home() / ".config" / "claude-vision-auto"
config_dir.mkdir(parents=True, exist_ok=True)
return config_dir
def get_cache_dir() -> Path:
"""Get cache directory for screenshots"""
cache_dir = Path.home() / ".cache" / "claude-vision-auto"
cache_dir.mkdir(parents=True, exist_ok=True)
return cache_dir
def load_config() -> Dict[str, Any]:
"""
Load configuration from YAML files with priority:
1. User config (~/.config/claude-vision-auto/config.yaml)
2. Default config (package default_config.yaml)
3. Environment variables (highest priority)
"""
# Load default config
default_config_path = Path(__file__).parent / "default_config.yaml"
with open(default_config_path, 'r') as f:
config = yaml.safe_load(f)
# Load user config if exists
user_config_path = get_config_dir() / "config.yaml"
if user_config_path.exists():
with open(user_config_path, 'r') as f:
user_config = yaml.safe_load(f)
# Deep merge user config
if user_config:
config = deep_merge(config, user_config)
# Override with environment variables
if os.getenv("OLLAMA_URL"):
config['ollama']['url'] = os.getenv("OLLAMA_URL")
if os.getenv("VISION_MODEL"):
config['ollama']['model'] = os.getenv("VISION_MODEL")
if os.getenv("IDLE_THRESHOLD"):
config['timing']['idle_threshold'] = float(os.getenv("IDLE_THRESHOLD"))
if os.getenv("RESPONSE_DELAY"):
config['timing']['response_delay'] = float(os.getenv("RESPONSE_DELAY"))
if os.getenv("DEBUG"):
config['debug'] = os.getenv("DEBUG", "false").lower() in ("true", "1", "yes")
return config
def deep_merge(base: Dict, override: Dict) -> Dict:
"""Deep merge two dictionaries"""
result = base.copy()
for key, value in override.items():
if key in result and isinstance(result[key], dict) and isinstance(value, dict):
result[key] = deep_merge(result[key], value)
else:
result[key] = value
return result
def create_user_config():
"""Create user config file with defaults"""
config_dir = get_config_dir()
user_config_path = config_dir / "config.yaml"
if not user_config_path.exists():
# Copy default config to user config
default_config_path = Path(__file__).parent / "default_config.yaml"
with open(default_config_path, 'r') as f:
default_content = f.read()
with open(user_config_path, 'w') as f:
f.write(default_content)
return user_config_path
return None
def create_user_config_cli():
"""CLI command to create user configuration file"""
import sys
config_path = create_user_config()
if config_path:
print(f"✅ Created user configuration file:")
print(f" {config_path}")
print()
print("Edit this file to customize:")
print(f" - Vision model (minicpm-v, llama3.2-vision, llava)")
print(f" - Vision prompt for better responses")
print(f" - Timing settings (idle threshold, response delay)")
print(f" - Approval keywords")
print()
print(f"Edit with: nano {config_path}")
else:
config_dir = get_config_dir()
config_path = config_dir / "config.yaml"
print(f" Configuration file already exists:")
print(f" {config_path}")
print()
print(f"Edit with: nano {config_path}")
sys.exit(0)
# Load configuration
_config = load_config()
# Export commonly used values
OLLAMA_URL = _config['ollama']['url']
VISION_MODEL = _config['ollama']['model']
VISION_TIMEOUT = _config['ollama']['timeout']
IDLE_THRESHOLD = _config['timing']['idle_threshold']
RESPONSE_DELAY = _config['timing']['response_delay']
SCREENSHOT_TIMEOUT = _config['timing']['screenshot_timeout']
VISION_PROMPT = _config['vision_prompt']
RESPONSE_MAPPING = _config['response_mapping']
APPROVAL_KEYWORDS = _config['approval_keywords']
OUTPUT_BUFFER_SIZE = _config['buffer']['size']
SCREENSHOT_TOOLS = _config['screenshot']['tools']
SCREENSHOT_CACHE_CLEANUP = _config['screenshot']['cache_cleanup_seconds']
DEBUG = _config['debug']
def get_config() -> Dict[str, Any]:
"""Get full configuration dict"""
return _config.copy()
def reload_config():
"""Reload configuration from files"""
global _config, OLLAMA_URL, VISION_MODEL, VISION_TIMEOUT
global IDLE_THRESHOLD, RESPONSE_DELAY, SCREENSHOT_TIMEOUT
global VISION_PROMPT, RESPONSE_MAPPING, APPROVAL_KEYWORDS
global OUTPUT_BUFFER_SIZE, SCREENSHOT_TOOLS, SCREENSHOT_CACHE_CLEANUP, DEBUG
_config = load_config()
OLLAMA_URL = _config['ollama']['url']
VISION_MODEL = _config['ollama']['model']
VISION_TIMEOUT = _config['ollama']['timeout']
IDLE_THRESHOLD = _config['timing']['idle_threshold']
RESPONSE_DELAY = _config['timing']['response_delay']
SCREENSHOT_TIMEOUT = _config['timing']['screenshot_timeout']
VISION_PROMPT = _config['vision_prompt']
RESPONSE_MAPPING = _config['response_mapping']
APPROVAL_KEYWORDS = _config['approval_keywords']
OUTPUT_BUFFER_SIZE = _config['buffer']['size']
SCREENSHOT_TOOLS = _config['screenshot']['tools']
SCREENSHOT_CACHE_CLEANUP = _config['screenshot']['cache_cleanup_seconds']
DEBUG = _config['debug']