{"id":50472466,"url":"https://github.com/semcod/pfix","last_synced_at":"2026-06-01T11:03:49.998Z","repository":{"id":347634592,"uuid":"1194699601","full_name":"semcod/pfix","owner":"semcod","description":null,"archived":false,"fork":false,"pushed_at":"2026-03-28T20:26:00.000Z","size":476,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-03-28T20:27:05.994Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/semcod.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-03-28T17:42:31.000Z","updated_at":"2026-03-28T20:26:02.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/semcod/pfix","commit_stats":null,"previous_names":["semcod/pfix"],"tags_count":40,"template":false,"template_full_name":null,"purl":"pkg:github/semcod/pfix","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/semcod%2Fpfix","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/semcod%2Fpfix/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/semcod%2Fpfix/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/semcod%2Fpfix/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/semcod","download_url":"https://codeload.github.com/semcod/pfix/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/semcod%2Fpfix/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33771632,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-01T02:00:06.963Z","response_time":115,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-06-01T11:03:49.920Z","updated_at":"2026-06-01T11:03:49.991Z","avatar_url":"https://github.com/semcod.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 🔧 pfix\n\n[![PyPI version](https://badge.fury.io/py/pfix.svg)](https://pypi.org/project/pfix/)\n[![PyPI downloads](https://img.shields.io/pypi/dm/pfix.svg)](https://pypi.org/project/pfix/)\n[![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/)\n[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)\n[![Ruff](https://img.shields.io/badge/linter-ruff-purple.svg)](https://github.com/astral-sh/ruff)\n[![pre-commit](https://img.shields.io/badge/pre--commit-enabled-brightgreen.svg)](https://pre-commit.com/)\n[![Tests: 56 examples](https://img.shields.io/badge/tests-56%20examples-blue)](examples/)\n[![Docs](https://img.shields.io/badge/docs-available-brightgreen.svg)](docs/)\n[![License: Apache-2.0](https://img.shields.io/badge/License-Apache%202.0-green.svg)](https://opensource.org/licenses/Apache-2.0)\n\n\n## AI Cost Tracking\n\n![PyPI](https://img.shields.io/badge/pypi-costs-blue) ![Version](https://img.shields.io/badge/version-0.1.73-blue) ![Python](https://img.shields.io/badge/python-3.9+-blue) ![License](https://img.shields.io/badge/license-Apache--2.0-green)\n![AI Cost](https://img.shields.io/badge/AI%20Cost-$2.65-orange) ![Human Time](https://img.shields.io/badge/Human%20Time-12.5h-blue) ![Model](https://img.shields.io/badge/Model-openrouter%2Fqwen%2Fqwen3--coder--next-lightgrey)\n\n- 🤖 **LLM usage:** $2.6490 (76 commits)\n- 👤 **Human dev:** ~$1246 (12.5h @ $100/h, 30min dedup)\n\nGenerated on 2026-05-12 using [openrouter/qwen/qwen3-coder-next](https://openrouter.ai/qwen/qwen3-coder-next)\n\n---\n\n**Self-healing Python** — catches runtime errors and fixes source code + dependencies via LLM + MCP.\n\nThe strategy of using a small tool for detecting errors in a single library or file enables quick bug fixes before writing a prompt, since all context is contained in the error file. This offloads large and expensive models that should be used where smaller ones are insufficient—allowing them to plan and create strategy for the entire library instead of handling individual errors, like in test files.\n\nThis automation can also be leveraged via CI/GitOps with provided API keys to the LLM provider for fixing encountered errors during testing across the entire ecosystem.\n\n\n\u003e 💡 **New in 0.1.5**: Zero-configuration mode! Just `import pfix` with `PFIX_AUTO_APPLY=true` in `.env` and any exception triggers automatic repair.\n\n## Features\n\n- **Zero-config mode** — `import pfix` + `.env` = auto-healing for entire project\n- **`@pfix` decorator** — wrap any function; errors trigger automatic repair\n- **Fast dep fix** — `ModuleNotFoundError` → instant `pip`/`uv install` (no LLM call)\n- **pipreqs scanning** — project-wide import analysis for missing dependencies\n- **LLM code repair** — sends error context to LLM (OpenRouter/LiteLLM) for intelligent fixes\n- **pip + uv** — auto-detects `uv` for faster installs, falls back to `pip`\n- **MCP server** — `@mcp.tool()` via FastMCP for IDE integration (Claude Code, Cursor, VS Code)\n- **Git auto-commit** — optional auto-commit of fixes with configurable prefix\n- **Auto-restart** — `os.execv` process restart after fix applied\n- **Interactive diff** — unified diff with confirmation before applying\n- **Backup system** — timestamped backups in `.pfix_backups/` (can be disabled)\n- **Async support** — `@apfix` for async functions\n\n### From PyPI (Users)\n\n```bash\npip install pfix\n\n# With MCP server support\npip install pfix[mcp]\n\n# With git auto-commit\npip install pfix[git]\n\n# Everything\npip install pfix[all]\n```\n\n### From Source (Developers)\n\nClone and install in editable mode:\n\n```bash\ngit clone https://github.com/softreck/pfix.git\ncd pfix\npip install -e .\n\n# Or with all optional dependencies\npip install -e \".[all]\"\n```\n\n**Editable mode** (`-e`) allows you to modify source code without reinstalling. Changes take effect immediately.\n\n### Running Examples\n\nAfter installation, examples can be run from any directory:\n\n```bash\n# From project root\ncd /path/to/pfix/examples\n\n# Run a single example category\ncd types \u0026\u0026 python main.py\ncd data \u0026\u0026 python main.py\n\n# The .env file in project root is automatically found\n```\n\n**Example workflow:**\n```bash\ncd examples\npython run_all.py              # Run all 12 categories, auto-reset at end\npython run_all.py --dry-run      # Preview what would run\npython run_all.py --no-reset     # Keep fixed versions for inspection\npython reset.py                  # Manual reset when needed\n```\n\n### Option 1: Zero Configuration (Recommended)\n\nJust `import pfix` with `PFIX_AUTO_APPLY=true` in your `.env`:\n\n```bash\n# .env\nOPENROUTER_API_KEY=sk-or-v1-...\nPFIX_AUTO_APPLY=true\n```\n\n```python\n# your_script.py\nimport pfix  # Auto-activates global exception hook\n\ndef buggy_function(x):\n    return 1 / x  # Division by zero? Auto-fixed!\n\nbuggy_function(0)  # pfix catches, analyzes, fixes, and retries\n```\n\n**What happens:**\n1. Exception is caught by global hook\n2. LLM analyzes the error context\n3. Fix is applied to source file\n4. Process restarts (if `PFIX_AUTO_RESTART=true`)\n\n### Option 2: Explicit Session Control\n\nUse `pfix_session` for fine-grained control:\n\n```python\nfrom pfix import configure, pfix_session\n\nconfigure(auto_apply=True, dry_run=False)\n\ndef process_data(data):\n    return data[0] / data[1]  # Might fail\n\nwith pfix_session(__file__, auto_apply=True):\n    result = process_data([1, 0])  # Auto-fixed on error\n    print(f\"Result: {result}\")\n```\n\n### Option 3: Decorator (Per-Function)\n\nUse `@pfix` for function-level control:\n\n```python\nfrom pfix import pfix\n\n@pfix(retries=3, hint=\"Processes CSV files\")\ndef analyze_csv(path):\n    import pandas as pd  # Auto-installed if missing\n    df = pd.read_csv(path)\n    return df.groupby(\"category\").sum()\n\n@pfix(deps=[\"requests\", \"python-dateutil\"])\ndef fetch_events(url: str):\n    import requests\n    from dateutil.parser import parse\n    return [parse(e[\"ts\"]) for e in requests.get(url).json()[\"events\"]]\n```\n\n### Pattern A: Development Mode (Interactive)\n\n```python\nfrom pfix import configure\n\n# Ask before applying fixes\nconfigure(auto_apply=False)\n\nimport pfix  # Hook installed\n\ndef risky_operation():\n    return undefined_variable  # NameError\n\nrisky_operation()  # Shows diff, asks for confirmation\n```\n\n### Pattern B: CI/CD Mode (Non-Interactive)\n\n```python\nfrom pfix import configure\n\n# Auto-apply everything, dry run for safety\nconfigure(auto_apply=True, dry_run=True, create_backups=False)\n\nimport pfix\n```\n\n### Pattern C: Library Mode (Specific Functions)\n\n```python\nfrom pfix import pfix, pfix_session\n\n# Only protect specific functions\n@pfix(auto_apply=True)\ndef unstable_api_call():\n    ...\n\n# Or specific code blocks\nwith pfix_session(__file__):\n    untrusted_code()\n```\n\n### How It Works\n\n```\n┌─────────────────────────────────────────────────────────────────┐\n│  Your Code                                                      │\n│  ┌─────────────────┐    ┌─────────────────┐    ┌─────────────┐   │\n│  │ Zero Config     │ or │ Session Block   │ or │ @pfix Decor │   │\n│  │ import pfix     │    │ with pfix_session│   │ @pfix       │   │\n│  └────────┬────────┘    └────────┬────────┘    └──────┬────┘   │\n│           │                        │                    │        │\n│           └────────────────────────┴────────────────────┘        │\n│                              │                                   │\n│                              ▼                                   │\n│  ┌──────────────────────────────────────────────────────────┐   │\n│  │  Exception Occurs                                        │   │\n│  │  ┌────────────────────────────────────────────────────┐ │   │\n│  │  │ 1. ModuleNotFoundError?                            │ │   │\n│  │  │    → pip/uv install → retry                          │ │   │\n│  │  └────────────────────────────────────────────────────┘ │   │\n│  │                          │                             │   │\n│  │                          ▼                             │   │\n│  │  ┌────────────────────────────────────────────────────┐ │   │\n│  │  │ 2. Build ErrorContext                              │ │   │\n│  │  │    - Traceback                                       │ │   │\n│  │  │    - Source code                                     │ │   │\n│  │  │    - Local variables                                 │ │   │\n│  │  │    - File imports                                    │ │   │\n│  │  │    - pipreqs scan                                    │ │   │\n│  │  └────────────────┬───────────────────────────────────┘ │   │\n│  │                   │                                       │   │\n│  │                   ▼                                       │   │\n│  │  ┌────────────────────────────────────────────────────┐   │   │\n│  │  │ 3. LLM Analysis (LiteLLM → OpenRouter)            │   │   │\n│  │  │    - Diagnosis                                     │   │   │\n│  │  │    - Fix proposal                                  │   │   │\n│  │  │    - Confidence score                              │   │   │\n│  │  └────────────────┬───────────────────────────────────┘   │   │\n│  │                   │                                       │   │\n│  │                   ▼                                       │   │\n│  │  ┌────────────────────────────────────────────────────┐   │   │\n│  │  │ 4. Apply Fix (if confidence \u003e 0.1)               │   │   │\n│  │  │    - Show diff (or auto-apply)                     │   │   │\n│  │  │    - Create backup (if create_backups=True)        │   │   │\n│  │  │    - Write fixed code                              │   │   │\n│  │  │    - Git commit (if git_auto_commit=True)          │   │   │\n│  │  └────────────────┬───────────────────────────────────┘   │   │\n│  │                   │                                       │   │\n│  │                   ▼                                       │   │\n│  │  ┌────────────────────────────────────────────────────┐   │   │\n│  │  │ 5. Recovery                                        │   │   │\n│  │  │    - Reload module → retry                         │   │   │\n│  │  │    - or os.execv restart                           │   │   │\n│  │  └────────────────────────────────────────────────────┘   │   │\n│  └──────────────────────────────────────────────────────────┘   │\n└─────────────────────────────────────────────────────────────────┘\n```\n\n### Error Types \u0026 Fixes\n\n| Error Type | Auto-Fix Strategy | Example Fix |\n|------------|-------------------|-------------|\n| `ModuleNotFoundError` | pip/uv install | `pip install requests` |\n| `NameError` | Add import | `import os` at top |\n| `TypeError` | Type conversion | `str(age)` instead of `age` |\n| `AttributeError` | Fix attribute access | `obj.get()` instead of `obj.attr` |\n| `ZeroDivisionError` | Add guard clause | `if x == 0: return 0` |\n| `IndexError` | Bounds checking | `if i \u003c len(list):` |\n| `KeyError` | Safe dict access | `dict.get(key, default)` |\n| `ValueError` | Input validation | Try/except or validation |\n| `FileNotFoundError` | Check path existence | `if os.path.exists():` |\n\n### Confidence Thresholds\n\n- **\u003e 90%**: High confidence fixes (type conversions, simple guards)\n- **50-90%**: Medium confidence (logic changes, API adjustments)\n- **10-50%**: Low confidence (complex refactorings)\n- **\u003c 10%**: Skipped (manual review recommended)\n\n\n## CLI\n\n```bash\npfix run script.py              # Run with global exception hook\npfix run script.py --auto       # Auto-apply fixes\npfix run script.py --restart    # Restart process after fix\npfix check                      # Show config status\npfix diagnose                   # Run environment diagnostics\npfix diagnose --category memory,filesystem  # Filter categories\npfix diagnose --fix             # Auto-fix what can be fixed\npfix diagnose --output TODO.md # Save to file\npfix deps scan                  # Scan for missing deps (pipreqs)\npfix deps install               # Install all missing deps\npfix deps generate              # Generate requirements.txt\npfix server                     # Start MCP server (stdio)\npfix server --http 3001         # Start MCP server (HTTP)\n```\n\n## MCP Integration\n\npfix exposes tools via FastMCP for IDE integration:\n\n| Tool | Description |\n|---|---|\n| `pfix_analyze` | Analyze error → diagnosis + fix proposal |\n| `pfix_fix` | Analyze + apply fix (with backup) |\n| `pfix_diagnose` | Run environment diagnostics |\n| `pfix_deps_scan` | Scan for missing deps |\n| `pfix_deps_install` | Install a package |\n| `pfix_deps_generate` | Generate requirements.txt |\n| `pfix_edit_file` | Write file content |\n\n### Claude Code / VS Code setup\n\nAdd to your MCP config (`.claude/mcp.json` or VS Code settings):\n\n```json\n{\n  \"mcpServers\": {\n    \"pfix\": {\n      \"command\": \"python\",\n      \"args\": [\"-m\", \"pfix.mcp_server\"]\n    }\n  }\n}\n```\n\n## Configuration\n\npfix supports multiple configuration methods (in order of priority):\n1. Environment variables (override everything)\n2. `.env` file in project root\n3. `pyproject.toml` `[tool.pfix]` section\n4. `setup.cfg` `[pfix]` section\n5. `setup.py` keyword arguments\n6. Programmatic `configure()`\n\n### Configuration Priority\n\nHigher numbers win (environment variables have highest priority):\n\n```\n[6] Environment variables (PFIX_*)\n[5] .env file\n[4] pyproject.toml [tool.pfix]\n[3] setup.cfg [pfix]\n[2] setup.py setup()\n[1] configure() programmatic\n```\n\n### Method 1: .env (Recommended for Development)\n\nCreate a `.env` file in your project root:\n\n```bash\n# Required\nOPENROUTER_API_KEY=sk-or-v1-...\n\n# Behavior\nPFIX_AUTO_APPLY=true              # Auto-apply fixes without confirmation\nPFIX_AUTO_INSTALL_DEPS=true       # Auto-install missing dependencies\nPFIX_AUTO_RESTART=true              # Restart process after fix\nPFIX_MAX_RETRIES=3\nPFIX_CREATE_BACKUPS=false           # Disable backups\n\n# Optional\nPFIX_MODEL=openrouter/qwen/qwen3-coder-next\nPFIX_PKG_MANAGER=uv               # pip or uv\nPFIX_GIT_COMMIT=false             # Auto-commit fixes\nPFIX_GIT_PREFIX=\"pfix: \"\n```\n\n**Note:** `.env` is searched from current working directory upward, so it works from any subdirectory (e.g., `examples/`).\n\n### Method 2: pyproject.toml (Recommended for Projects)\n\nAdd to your `pyproject.toml`:\n\n```toml\n[tool.pfix]\nmodel = \"openrouter/qwen/qwen3-coder-next\"\nauto_apply = true\nauto_install_deps = true\nauto_restart = true\nmax_retries = 3\ncreate_backups = false\ngit_auto_commit = false\ngit_commit_prefix = \"pfix: \"\nenabled = true\ndry_run = false\npkg_manager = \"uv\"  # auto, pip, or uv\nmcp_enabled = false\nmcp_transport = \"stdio\"\nmcp_server_url = \"http://localhost:3001\"\n```\n\n**Benefits:**\n- Version controlled with your project\n- Works with any Python packaging tool\n- No external files needed\n\n### Method 3: setup.cfg (Legacy Projects)\n\nFor projects using `setup.cfg`:\n\n```ini\n[metadata]\nname = myproject\nversion = 1.0.0\n...\n\n[pfix]\nmodel = openrouter/qwen/qwen3-coder-next\nauto_apply = true\nauto_install_deps = true\nauto_restart = false\nmax_retries = 3\ncreate_backups = true\n```\n\n### Method 4: setup.py (Legacy Projects)\n\nFor projects using `setup.py`:\n\n```python\nfrom setuptools import setup\n\nsetup(\n    name=\"myproject\",\n    version=\"1.0.0\",\n    # ... other setup args\n    \n    # pfix configuration\n    pfix_model=\"openrouter/qwen/qwen3-coder-next\",\n    pfix_auto_apply=True,\n    pfix_auto_install_deps=True,\n    pfix_auto_restart=False,\n    pfix_max_retries=3,\n    pfix_create_backups=True,\n    pfix_enabled=True,\n)\n```\n\n**Note:** `setup.py` config requires pfix to be installed in the same environment.\n\n### Method 5: Programmatic Configuration\n\nConfigure at runtime in your Python code:\n\n```python\nfrom pfix import configure\n\n# Before importing pfix or using the hook\nconfigure(\n    # LLM settings\n    llm_model=\"openrouter/qwen/qwen3-coder-next\",\n    llm_api_key=\"sk-or-v1-...\",\n    llm_temperature=0.2,\n    llm_max_tokens=4096,\n    \n    # Behavior\n    auto_apply=True,\n    auto_install_deps=True,\n    auto_restart=True,\n    max_retries=3,\n    enabled=True,\n    dry_run=False,\n    \n    # Project\n    pkg_manager=\"uv\",\n    create_backups=False,\n    project_root=\"/path/to/project\",\n    \n    # Git\n    git_auto_commit=False,\n    git_commit_prefix=\"pfix: \",\n    \n    # MCP\n    mcp_enabled=False,\n    mcp_transport=\"stdio\",\n)\n\n### Configuration Reference\n\n| Variable | Type | Default | Description |\n|----------|------|---------|-------------|\n| `OPENROUTER_API_KEY` | `str` | — | **Required** — OpenRouter API key |\n| `PFIX_MODEL` | `str` | `openrouter/qwen/qwen3-coder-next` | LLM model to use |\n| `PFIX_API_BASE` | `str` | `https://openrouter.ai/api/v1` | API base URL |\n| `PFIX_AUTO_APPLY` | `bool` | `false` | Auto-apply fixes without confirmation |\n| `PFIX_AUTO_INSTALL_DEPS` | `bool` | `true` | Auto-install missing dependencies |\n| `PFIX_AUTO_RESTART` | `bool` | `false` | Restart process after fix applied |\n| `PFIX_MAX_RETRIES` | `int` | `3` | Max fix attempts per error |\n| `PFIX_DRY_RUN` | `bool` | `false` | Show proposed fixes without applying |\n| `PFIX_CREATE_BACKUPS` | `bool` | `true` | Create `.pfix_backups/` before fixing |\n| `PFIX_ENABLED` | `bool` | `true` | Master switch to disable pfix |\n| `PFIX_PKG_MANAGER` | `str` | auto | `pip`, `uv`, or auto-detected |\n| `PFIX_GIT_COMMIT` | `bool` | `false` | Auto-commit fixes to git |\n| `PFIX_GIT_PREFIX` | `str` | `pfix: ` | Git commit message prefix |\n| `PFIX_MCP_ENABLED` | `bool` | `false` | Enable MCP server |\n| `PFIX_MCP_TRANSPORT` | `str` | `stdio` | `stdio` or `http` |\n| `PFIX_PROJECT_ROOT` | `str` | `.` | Project root for relative paths |\n\n## LLM Models \u0026 Providers\n\npfix uses [LiteLLM](https://litellm.ai) to support multiple LLM providers. You can use cloud APIs or run models locally.\n\n### OpenRouter (Cloud - Recommended)\n\nOpenRouter provides access to multiple models with a single API key.\n\n```bash\n# .env\nOPENROUTER_API_KEY=sk-or-v1-...\nPFIX_MODEL=openrouter/qwen/qwen3-coder-next\n```\n\n**Recommended models:**\n| Model | Description | Best For |\n|-------|-------------|----------|\n| `openrouter/qwen/qwen3-coder-next` | Claude 4 Sonnet | Balanced quality/speed |\n| `openrouter/anthropic/claude-opus-4` | Claude 4 Opus | Complex fixes |\n| `openrouter/anthropic/claude-haiku-4` | Claude 4 Haiku | Fast, cheap fixes |\n| `openrouter/qwen/qwen3-235b-a22b-2507` | Qwen3 235B | Code-heavy tasks |\n| `openrouter/qwen/qwen3.5-flash-02-23` | Qwen3.5 Flash | Fast responses |\n| `openrouter/nvidia/nemotron-3-super-120b-a12b:free` | Nemotron 3 Super | Free tier |\n| `openrouter/deepseek/deepseek-coder-v2` | DeepSeek Coder | Code-specific |\n\n### Ollama (Local - Free, Private)\n\nRun models locally for zero cost and complete privacy.\n\n**Setup:**\n```bash\n# Pull a code-capable model\nollama pull codellama:7b\nollama pull qwen2.5-coder:7b\nollama pull deepseek-coder:6.7b\n```\n\n**Configure pfix:**\n```bash\n# .env\nPFIX_MODEL=ollama/codellama:7b\nPFIX_API_BASE=http://localhost:11434\n# No API key needed for local models\n```\n\n**Recommended local models:**\n| Model | Size | Speed | Quality |\n|-------|------|-------|---------|\n| `ollama/codellama:7b` | 7B | Fast | Good |\n| `ollama/qwen2.5-coder:7b` | 7B | Fast | Very Good |\n| `ollama/deepseek-coder:6.7b` | 6.7B | Fast | Very Good |\n| `ollama/codellama:13b` | 13B | Medium | Excellent |\n| `ollama/qwen2.5-coder:14b` | 14B | Medium | Excellent |\n\n# .env\nPFIX_MODEL=gpt-4o\nPFIX_API_KEY=sk-...\nPFIX_API_BASE=https://api.openai.com/v1\n```\n\n**Models:** `gpt-4o`, `gpt-5.4-mini`, `gpt-4-turbo`, `gpt-3.5-turbo`\n\n# .env\nPFIX_MODEL=anthropic/claude-3-sonnet-20241022\nPFIX_API_KEY=sk-ant-...\n```\n\n**Models:** `claude-3-opus`, `claude-3-sonnet`, `claude-3-haiku`\n\n# .env\nPFIX_MODEL=azure/\u003cyour-deployment-name\u003e\nPFIX_API_KEY=...\nPFIX_API_BASE=https://\u003cresource\u003e.openai.azure.com\n```\n\n# .env\nPFIX_MODEL=vertex_ai/gemini-1.5-pro\n# or\nPFIX_MODEL=gemini/gemini-1.5-pro\n```\n\n### Choosing a Model\n\n**For beginners:** Start with `openrouter/qwen/qwen3-coder-next` (good balance)\n\n**For cost savings:** Use Ollama locally or OpenRouter free models (`:free` suffix)\n\n**For complex fixes:** Use larger models (Claude Opus, GPT-4, Qwen 235B)\n\n**For speed:** Use smaller models (Haiku, GPT-4o-mini, local 7B models)\n\n## Runtime Error Tracking\n\npfix can automatically capture runtime errors to `TODO.md` for production monitoring:\n\n```toml\n[tool.pfix.runtime_todo]\nenabled = true\ntodo_file = \"TODO.md\"\nmin_severity = \"medium\"\nmax_entries = 500\ndeduplicate = true\ninclude_local_vars = false\ninclude_traceback_depth = 5\n```\n\n**Features:**\n- **Absolute paths** — errors tracked with full file paths\n- **Deduplication** — same error 1000x = one entry with counter\n- **Full traceback** — complete call stack, not just last frame\n- **Environment context** — Python version, hostname, PID, venv path\n- **Thread-safe** — file locking for multi-worker setups (gunicorn/uvicorn)\n- **Append-only** — never loses history\n\n**Enable via environment:**\n```bash\nPFIX_RUNTIME_TODO=true\nPFIX_TODO_FILE=TODO.md\n```\n\n## Environment Diagnostics\n\nComprehensive environment checking with 14 diagnostic categories:\n\n```bash\npfix diagnose                    # Run all diagnostics\npfix diagnose --category venv,memory,network\npfix diagnose --json --check     # CI mode (exit 1 on errors)\npfix diagnose --fix              # Auto-fix what can be fixed\n```\n\n**Categories:**\n| Category | Checks |\n|----------|--------|\n| `import_dependency` | Missing imports, circular deps, version conflicts, stdlib shadowing |\n| `filesystem` | Disk space, permissions, broken symlinks, large files |\n| `venv` | Activation, integrity, global leaks, requirements sync |\n| `python_version` | pyproject.toml requires-python, deprecated features |\n| `memory` | Available RAM, swap, recursion limit, GC pressure |\n| `network` | DNS, connectivity, SSL certs, proxy config |\n| `process` | ulimits, signals, zombie processes |\n| `encoding` | UTF-8 BOM, line endings, locale |\n| `paths` | sys.path issues, PYTHONPATH, long paths |\n| `config_env` | .env security, required vars, gitignore |\n| `concurrency` | Thread count, asyncio loop issues |\n| `serialization` | Pickle protocol, corrupt cache files |\n| `hardware` | GPU availability, CPU count, Docker limits |\n| `third_party` | API rate limits, auth expiration, schema changes |\n\n**Auto-fixable issues:**\n- Stale `.pyc` files → `find . -name '*.pyc' -delete`\n- UTF-8 BOM → remove BOM markers\n- Mixed line endings → convert to LF\n- Missing `.env` → copy from `.env.example`\n- `.env` not gitignored → add to `.gitignore`\n- Large log files → truncate to last N lines\n\n**Usage in CI/CD:**\n```yaml\n- run: pfix diagnose --check --json\n  continue-on-error: true\n```\n\n### Custom Error Handlers\n\n```python\nfrom pfix import pfix\n\ndef log_error(exc):\n    with open(\"errors.log\", \"a\") as f:\n        f.write(f\"{type(exc).__name__}: {exc}\\n\")\n\n@pfix(on_error=log_error, retries=3)\ndef risky_operation():\n    ...\n```\n\n### Async Support\n\n```python\nfrom pfix import apfix\n\n@apfix(auto_apply=True)\nasync def fetch_data(url):\n    import aiohttp\n    async with aiohttp.ClientSession() as session:\n        async with session.get(url) as response:\n            return await response.json()\n```\n\n### Session with Custom Config\n\n```python\nfrom pfix import pfix_session, get_config\n\nconfig = get_config()\nconfig.llm_model = \"openrouter/anthropic/claude-opus-4\"\nconfig.llm_temperature = 0.1\n\nwith pfix_session(__file__, auto_apply=True, restart=True):\n    main()\n```\n\n## Examples\n\nSee [`examples/`](examples/) directory for working examples:\n\n- [`demo_auto.py`](examples/demo_auto.py) — Zero-config auto-healing\n- [`demo.py`](examples/demo.py) — Explicit session control\n- [`README.md`](examples/README.md) — Examples documentation\n\n## Best Practices\n\n1. **Start with `PFIX_AUTO_APPLY=false`** to review fixes before applying\n2. **Enable backups** (`PFIX_CREATE_BACKUPS=true`) in development\n3. **Use dry-run mode** in CI/CD to preview fixes without applying\n4. **Set `PFIX_AUTO_RESTART=true`** for long-running processes\n5. **Add hints** to decorators for better LLM context: `@pfix(hint=\"Processes CSV files\")`\n\n### \"LLM confidence too low\"\n- Increase context with `@pfix(hint=\"...\")`\n- Check your API key is valid\n- Try a different model in `PFIX_MODEL`\n\n### \"Could not locate function\"\n- Ensure the error is in a named function (not `lambda` or `exec`)\n- Use `pfix_session` for module-level code\n\n### Backups filling up disk\n- Set `PFIX_CREATE_BACKUPS=false`\n- Clean `.pfix_backups/` periodically: `rm -rf .pfix_backups/`\n\n### Too many restarts\n- Set `PFIX_MAX_RETRIES=1` to limit attempts\n- Use `PFIX_AUTO_RESTART=false` to disable restarts\n\n## Dependencies\n\n| Package | Role |\n|---------|------|\n| `litellm` | LLM proxy — OpenRouter, OpenAI, Anthropic, Ollama |\n| `python-dotenv` | Load `.env` configuration |\n| `rich` | Terminal UI (diffs, panels, tables) |\n| `pipreqs` | Project import scanning |\n| `pathspec` | Gitignore-aware file filtering |\n| `mcp` | FastMCP server (optional) |\n| `gitpython` | Git auto-commit (optional) |\n| `watchdog` | File change watching (optional) |\n\n## License\n\nLicensed under Apache-2.0.\n## Status\n\n_Last updated by [taskill](https://github.com/oqlos/taskill) at 2026-04-25 13:42 UTC_\n\n| Metric | Value |\n|---|---|\n| HEAD | `6ddd51f` |\n| Coverage | — |\n| Failing tests | — |\n| Commits in last cycle | 50 |\n\n\u003e Introduced a deep code analysis engine and a configuration management system, plus a number of documentation/refactor updates and CLI/config fixes across the project.\n\n\u003c!-- taskill:status:end --\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsemcod%2Fpfix","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsemcod%2Fpfix","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsemcod%2Fpfix/lists"}