Manages user preferences with automatic learning. Preferences are learned from: - Existing code in the project - User corrections and feedback - Repeated patterns in generated code Preferences are used to: - Generate code matching user style - Suggest appropriate t
| 222 | |
| 223 | |
| 224 | class PreferenceManager: |
| 225 | """ |
| 226 | Manages user preferences with automatic learning. |
| 227 | |
| 228 | Preferences are learned from: |
| 229 | - Existing code in the project |
| 230 | - User corrections and feedback |
| 231 | - Repeated patterns in generated code |
| 232 | |
| 233 | Preferences are used to: |
| 234 | - Generate code matching user style |
| 235 | - Suggest appropriate tools and frameworks |
| 236 | - Avoid style mismatches |
| 237 | """ |
| 238 | |
| 239 | # Preference categories and their weights |
| 240 | CATEGORIES = { |
| 241 | "test_framework": {"weight": 1.0, "default": "pytest"}, |
| 242 | "code_style": {"weight": 0.8, "default": "black"}, |
| 243 | "naming_convention": {"weight": 0.9, "default": "snake_case"}, |
| 244 | "import_style": {"weight": 0.7, "default": "absolute"}, |
| 245 | "docstring_style": {"weight": 0.6, "default": "google"}, |
| 246 | "error_handling": {"weight": 0.8, "default": "explicit"}, |
| 247 | "type_hints": {"weight": 0.8, "default": None}, |
| 248 | "async_style": {"weight": 0.7, "default": None}, |
| 249 | "http_library": {"weight": 0.9, "default": None}, |
| 250 | "cli_library": {"weight": 0.9, "default": None}, |
| 251 | "log_style": {"weight": 0.7, "default": None}, |
| 252 | } |
| 253 | |
| 254 | # Natural language patterns for extracting preferences from user messages. |
| 255 | # Each entry: (regex, category, value_group_or_literal) |
| 256 | # value_group_or_literal: int → capture group index; str → literal value |
| 257 | NL_PATTERNS = [ |
| 258 | # "always use X" / "use X" / "prefer X" / "I like X" |
| 259 | (r"(?:always use|prefer|use|i (?:prefer|like|want)|stick to)\s+(pytest|unittest)", "test_framework", 1), |
| 260 | (r"(?:always use|prefer|use|i (?:prefer|like|want)|stick to)\s+(black|pep8|ruff)", "code_style", 1), |
| 261 | (r"(?:always use|prefer|use|i (?:prefer|like|want)|stick to)\s+(httpx|requests|aiohttp|urllib)", "http_library", 1), |
| 262 | (r"(?:always use|prefer|use|i (?:prefer|like|want)|stick to)\s+(click|argparse|typer)", "cli_library", 1), |
| 263 | (r"(?:always use|prefer|use|i (?:prefer|like|want)|stick to)\s+(loguru|logging|rich)\s*(?:for\s*log(?:ging)?)?", "log_style", 1), |
| 264 | # type hints |
| 265 | (r"(?:always (?:add|use|include)|i (?:want|prefer|like))\s+type\s*hints?", "type_hints", "yes"), |
| 266 | (r"(?:don'?t|no|skip|avoid)\s+type\s*hints?", "type_hints", "no"), |
| 267 | # async |
| 268 | (r"(?:always use|prefer|use|i (?:prefer|like|want))\s+async", "async_style", "async"), |
| 269 | # docstrings |
| 270 | (r"(?:always use|prefer|use|i (?:prefer|like|want)|stick to)\s+(google|numpy|sphinx|epytext)\s+docstrings?", "docstring_style", 1), |
| 271 | # error handling |
| 272 | (r"(?:always use|prefer|use|i (?:prefer|like|want)|stick to)\s+(explicit|try.except|raise)\s*(?:error\s*handling)?", "error_handling", 1), |
| 273 | # naming |
| 274 | (r"(?:always use|prefer|use|i (?:prefer|like|want)|stick to)\s+(snake_case|camelCase|PascalCase)\s*(?:naming)?", "naming_convention", 1), |
| 275 | # "don't use X" → negative preference |
| 276 | (r"(?:don'?t|do not|never|avoid)\s+use\s+(requests)\b", "http_library", "httpx"), |
| 277 | (r"(?:don'?t|do not|never|avoid)\s+use\s+(argparse)\b", "cli_library", "click"), |
| 278 | (r"(?:don'?t|do not|never|avoid)\s+use\s+print\b", "log_style", "logging"), |
| 279 | ] |
| 280 | |
| 281 | def __init__(self): |
no outgoing calls