{"id":50472338,"url":"https://github.com/semcod/llx","last_synced_at":"2026-06-01T11:03:13.064Z","repository":{"id":346880970,"uuid":"1191811587","full_name":"semcod/llx","owner":"semcod","description":null,"archived":false,"fork":false,"pushed_at":"2026-04-25T20:24:26.000Z","size":37326,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-25T22:09:08.713Z","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":"CONTRIBUTING.md","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-25T15:57:02.000Z","updated_at":"2026-04-25T20:24:30.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/semcod/llx","commit_stats":null,"previous_names":["semcod/llx"],"tags_count":57,"template":false,"template_full_name":null,"purl":"pkg:github/semcod/llx","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/semcod%2Fllx","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/semcod%2Fllx/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/semcod%2Fllx/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/semcod%2Fllx/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/semcod","download_url":"https://codeload.github.com/semcod/llx/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/semcod%2Fllx/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33771630,"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:09.792Z","updated_at":"2026-06-01T11:03:13.052Z","avatar_url":"https://github.com/semcod.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# llx\n\n**Intelligent LLM model router driven by real code metrics.**\n\n[![PyPI](https://img.shields.io/pypi/v/llx)](https://pypi.org/project/llx/)\n[![Version](https://img.shields.io/badge/version-0.1.82-blue)](https://pypi.org/project/llx/)\n[![License: Apache-2.0](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)\n[![Python](https://img.shields.io/badge/python-3.10%2B-blue.svg)](https://python.org)\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.82-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-$7.50-orange) ![Human Time](https://img.shields.io/badge/Human%20Time-37.5h-blue) ![Model](https://img.shields.io/badge/Model-openrouter%2Fqwen%2Fqwen3--coder--next-lightgrey)\n\n- 🤖 **LLM usage:** $7.5000 (107 commits)\n- 👤 **Human dev:** ~$3749 (37.5h @ $100/h, 30min dedup)\n\nGenerated on 2026-04-26 using [openrouter/qwen/qwen3-coder-next](https://openrouter.ai/qwen/qwen3-coder-next)\n\n---\n\n## Documentation map\n\n- `README.md` — project overview, install, and quickstart\n- `docs/README.md` — generated API inventory from source analysis\n- `docs/llx-tools.md` — ecosystem CLI reference\n- `docs/PLANFILE_CLEANUP.md` — ticket lifecycle, freshness, `llx plan clean`, prune flags\n- `docs/PRIVACY.md` — anonymization and sensitive-data handling\n\n**Successor to [preLLM](https://github.com/wronai/prellm)** — rebuilt with modular architecture, no god modules, and metric-driven routing.\n\nllx analyzes your codebase with **code2llm**, **redup**, and **vallm**, then selects the optimal LLM model based on actual project metrics — file count, complexity, coupling, duplication — not abstract scores.\n\n**Principle**: larger + more coupled + more complex → stronger (and more expensive) model.\n\n## CLI surface\n\nllx is organized around a small set of command groups:\n\n- `llx analyze`, `llx select`, `llx chat` — metric-driven analysis and model routing\n- `llx proxy` — LiteLLM proxy config, start, and status\n- `llx mcp` — MCP server start, config, and tool listing\n- `llx plan` — planfile generation, review, code generation, and execution\n- `llx strategy` — interactive strategy creation, validation, run, and verification\n- `llx info`, `llx models`, `llx init`, `llx fix` — inspection and utility commands\n\n## Why llx? (Lessons from preLLM)\n\npreLLM proved the concept but had architectural issues that llx resolves:\n\n| Problem in preLLM | llx Solution |\n|---|---|\n| `cli.py`: 999 lines, CC=30 (`main`), CC=27 (`query`) | CLI split into `app.py` + `formatters.py`, max CC ≤ 8 |\n| `core.py`: 893 lines god module | Config, analysis, routing in separate modules (≤250L each) |\n| `trace.py`: 509 lines, CC=28 (`to_stdout`) | Output formatting as dedicated functions |\n| Hardcoded model selection | Metric-driven thresholds from code2llm .toon data |\n| No duplication/validation awareness | Integrates redup + vallm for richer metrics |\n\n## Architecture\n\n```\n┌─────────────────────────────────────────────────────────────┐\n│                    IDE / Agent Layer                        │\n│  Roo Code │ Cline │ Continue.dev │ Aider │ Claude Code      │\n│  (point at localhost:4000 as OpenAI-compatible API)         │\n└─────────────────┬───────────────────────────────────────────┘\n                  │\n┌─────────────────▼───────────────────────────────────────────┐\n│              LiteLLM Proxy (localhost:4000)                 │\n│  ┌──────────┐  ┌──────────────┐  ┌────────────────────┐     │\n│  │ Router   │  │ Semantic     │  │ Cost Tracking      │     │\n│  │ (metrics)│  │ Cache (Redis)│  │ + Budget Limits    │     │\n│  └────┬─────┘  └──────────────┘  └────────────────────┘     │\n└───────┼─────────────────────────────────────────────────────┘\n        │\n   ┌────┼────────────────────────────────────────┐\n   │    │           Model Tiers                   │\n   │    ├── premium:  Claude Opus 4               │\n   │    ├── balanced: Qwen 2.5 Coder (OpenRouter) │\n   │    ├── cheap:    Claude Haiku 4.5            │\n   │    ├── free:     Nemotron 3 Super (OpenRouter)│\n   │    ├── openrouter: 300+ models (fallback)    │\n   │    └── local:    Ollama (Qwen2.5-Coder)      │\n   └──────────────────────────────────────────────┘\n        │\n┌───────▼─────────────────────────────────────────────────────┐\n│            Code Analysis Pipeline                           │\n│  code2llm → redup → vallm → llx                             │\n│  (metrics → duplication → validation → model selection)     │\n└─────────────────────────────────────────────────────────────┘\n```\n\n## MCP server\n\nllx exposes its MCP tools through a shared registry in `llx.mcp.tools.MCP_TOOLS`.\n\nBy default, the MCP server runs over **stdio** for Claude Desktop. Use SSE only when you need a remote or web client.\n\n```bash\n# Start MCP server over SSE for web/remote clients\nllx mcp start --mode sse --port 8000\n\n# Direct module entrypoint\npython -m llx.mcp --sse --port 8000\n```\n\n### Tool groups\n\n- `llx_analyze`, `llx_select`, `llx_chat` — project metrics and model routing\n- `llx_preprocess`, `llx_context` — query preprocessing and environment context\n- `code2llm_analyze`, `redup_scan`, `vallm_validate` — code-quality analysis helpers\n- `llx_proxy_status`, `llx_proxym_status`, `llx_proxym_chat` — proxy and proxym integration\n- `aider`, `planfile_generate`, `planfile_apply` — workflow and refactoring helpers\n- `llx_privacy_scan`, `llx_project_anonymize`, `llx_project_deanonymize` — privacy tooling\n\n### Claude Desktop setup\n\n```json\n{\n  \"mcpServers\": {\n    \"llx\": {\n      \"command\": \"python3\",\n      \"args\": [\"-m\", \"llx.mcp\"]\n    }\n  }\n}\n```\n\n## Installation\n\n```bash\n# Recommended: Use uv for 10-100x faster installation\npip install uv\nuv pip install -e \".[dev]\"\n\n# Or with pip\npip install llx\n\n# With integrations\npip install llx[all]        # Everything + MCP\npip install llx[mcp]       # MCP server only\npip install llx[litellm]    # LiteLLM proxy\npip install llx[code2llm]   # Code analysis\npip install llx[redup]      # Duplication detection\npip install llx[vallm]      # Code validation\n\n# Development environments\npip install -e \".[dev]\"      # Lightweight dev tools (pytest, ruff, mypy)\npip install -e \".[dev-full]\" # Full dev with all tools (goal, costs, pfix)\n```\n\n**uv Installation (Recommended):**\n```bash\npip install uv\nuv pip install -e \".[dev]\"  # 10-100x faster than pip\n```\n\n### Test profiles\n\n```bash\n# Default test profile (used by goal.yaml)\npytest tests/ -v\n\n# Full test profile with MCP tests enabled\npip install -e \".[mcp]\"\npytest tests/ -v\n```\n\n`tests/test_mcp.py` and `tests/test_aider_mcp.py` require the optional `mcp` package.\nWhen `llx[mcp]` is not installed, those modules are skipped automatically instead of\nbreaking test collection.\n\n**Configuration:**\nModel tiers are configured in `llx.yaml`:\n```yaml\nselection:\n  models:\n    balanced:\n      provider: openrouter\n      model_id: openrouter/x-ai/grok-code-fast-1\n      max_context: 200000\n```\n\n```bash\n# Analyze project and get model recommendation\nllx analyze ./my-project\n\n# With task hint\nllx select . --task refactor\n\n# Point to pre-existing .toon files\nllx analyze . --toon-dir ./analysis/\n\n# JSON output for CI/CD\nllx analyze . --json\n\n# Chat with auto-selected model\nllx chat . --prompt \"Refactor the god modules\"\n\n# Force local model\nllx select . --local\n```\n\n## Model Selection Logic\n\n| Metric | Premium (≥) | Balanced (≥) | Cheap (≥) | Free |\n|--------|-------------|--------------|-----------|------|\n| Files | 50 | 10 | 3 | \u003c3 |\n| Lines | 20,000 | 5,000 | 500 | \u003c500 |\n| Avg CC | 6.0 | 4.0 | 2.0 | \u003c2.0 |\n| Max fan-out | 30 | 10 | — | — |\n| Max CC | 25 | 15 | — | — |\n| Dup groups | 15 | 5 | — | — |\n| Dep cycles | any | — | — | — |\n\n## Privacy \u0026 Anonymization\n\nLLX provides **reversible anonymization** to protect sensitive data when sending to LLMs:\n\n### Features\n- **Text anonymization**: Emails, API keys, passwords, PESEL, credit cards\n- **Project-level**: AST-based code anonymization (variables, functions, classes)\n- **Round-trip**: Anonymize → Send to LLM → Deanonymize response\n- **Persistent mapping**: Save/restore context for later deanonymization\n\n### Quick Usage\n\n```python\nfrom llx.privacy import quick_anonymize, quick_deanonymize\n\n# Simple text anonymization\nresult = quick_anonymize(\"Email: user@example.com, API: sk-abc123\")\nprint(result.text)  # \"Email: [EMAIL_A1B2], API: [APIKEY_C3D4]\"\n\n# Later: restore original values\nrestored = quick_deanonymize(llm_response, result.mapping)\n```\n\n### Project-Level Anonymization\n\n```python\nfrom llx.privacy.project import AnonymizationContext, ProjectAnonymizer\nfrom llx.privacy.deanonymize import ProjectDeanonymizer\n\n# Anonymize entire project\nctx = AnonymizationContext(project_path=\"./my-project\")\nanonymizer = ProjectAnonymizer(ctx)\nresult = anonymizer.anonymize_project()\n\n# Save context for later\nctx.save(\"./my-project.anon.json\")\n\n# Deanonymize LLM response\ndeanonymizer = ProjectDeanonymizer(ctx)\nrestored = deanonymizer.deanonymize_chat_response(llm_response)\n```\n\n### MCP Tools\n\n```json\n// Scan for sensitive data\n{\"tool\": \"llx_privacy_scan\", \"text\": \"Email: user@example.com\"}\n\n// Anonymize project\n{\"tool\": \"llx_project_anonymize\", \"path\": \"./my-project\", \"output_dir\": \"./anon\"}\n\n// Deanonymize response\n{\"tool\": \"llx_project_deanonymize\", \"context_path\": \"./anon/.anonymization_context.json\", \"text\": \"Fix fn_ABC123\"}\n```\n\nSee `docs/PRIVACY.md` and `examples/privacy/` for complete documentation.\n\n## Real-World Selection Examples\n\n| Project | Files | Lines | CC̄ | Max CC | Fan-out | Tier |\n|---------|-------|-------|-----|--------|---------|------|\n| Single script | 1 | 80 | 2.0 | 4 | 0 | **free** |\n| Small CLI | 5 | 600 | 3.0 | 8 | 3 | **cheap** |\n| **preLLM** | **31** | **8,900** | **5.0** | **28** | **30** | **premium** |\n| vallm | 56 | 8,604 | 3.5 | 42 | — | **balanced** |\n| code2llm | 113 | 21,128 | 4.6 | 65 | 45 | **premium** |\n| Monorepo | 500+ | 100K+ | 5.0+ | 30+ | 50+ | **premium** |\n\n## LiteLLM Proxy\n\n```bash\nllx proxy config     # Generate litellm_config.yaml\nllx proxy start      # Start proxy on :4000\nllx proxy status     # Check if running\n```\n\nConfigure IDE tools to point at `http://localhost:4000`:\n\n| Tool | Config |\n|------|--------|\n| Roo Code / Cline | `\"apiBase\": \"http://localhost:4000/v1\"` |\n| Continue.dev | `\"apiBase\": \"http://localhost:4000/v1\"` |\n| Aider | `OPENAI_API_BASE=http://localhost:4000` |\n| Claude Code | `ANTHROPIC_BASE_URL=http://localhost:4000` |\n| Cursor / Windsurf | OpenAI-compatible endpoint |\n\n## Configuration\n\n```bash\nllx init  # Creates llx.toml with defaults\n```\n\nEnvironment variables: `LLX_LITELLM_URL`, `LLX_DEFAULT_TIER`, `LLX_PROXY_PORT`, `LLX_VERBOSE`.\n\n## Planfile Integration\n\nllx supports planfile.yaml format (redsl-generated) for sequential task execution:\n\n```python\nfrom llx.planfile import execute_strategy\n\n# Execute planfile.yaml (supports V1, V2, and redsl formats)\nresults = execute_strategy(\n    \"planfile.yaml\",\n    project_path=\".\",\n    dry_run=True\n)\n\n# Process results\nfor result in results:\n    print(f\"{result.task_name}: {result.status}\")\n```\n\n**CLI usage:**\n```bash\n# Basic execution\nllx plan run .                          # Run planfile.yaml\nllx plan run . --tier free               # With specific model tier\nllx plan run . --sprint 1                # Only sprint 1\nllx plan run . --dry-run                 # Simulate without executing\n\n# Concurrency and task limits\nllx plan run . --max-concurrent 3        # Run 3 tasks in parallel\nllx plan run . --max-tasks 10            # Process only 10 tasks total\nllx plan run . -j 5 -n 20                # Short form: 5 concurrent, max 20 tasks\n\n# Proxy management (automatic detection and startup)\nllx plan run .                          # Auto-starts proxy if not running\nllx plan run . --no-auto-start-proxy     # Disable automatic proxy start\n\n# Code editing with automatic backend detection\nllx plan run . --use-aider               # Auto-detect best backend (LOCAL \u003e CURSOR \u003e WINDSURF \u003e CLAUDE_CODE \u003e DOCKER \u003e MCP \u003e LLM_CHAT)\nllx plan run . -a -j 3 -n 10             # Backend detection + concurrency + task limit\n\n# Structured YAML output (always on stdout)\nllx plan run . --sprint 1 --max-tasks 1 \u003e run-results.yaml\n\n# Also save a copy to file while keeping YAML on stdout\nllx plan run . --output-yaml results.yaml\nllx plan run . -o execution_results.yaml\n\n# Optional: sync TODO.md checkboxes from planfile task status/results\n# (configured in planfile.yaml)\n# integrations:\n#   markdown:\n#     sync_on_plan_run: true\n#     todo_file: TODO.md\n\n# Generation and review\nllx plan generate strategy.yaml --output generated/\nllx plan review strategy.yaml --project .\n\n# Ticket freshness validation\nllx plan validate .                          # Check if tickets are still current\nllx plan validate . --prune-stale            # Validate and delete stale tickets\n\n# Cleanup resolved tickets\nllx plan clean .                             # Remove canceled tickets from planfile.yaml + TODO.md\nllx plan clean . --include-done              # Also remove done tickets\nllx plan clean . --dry-run                   # Preview without writing\n\n# GitHub ticket creation (requires external planfile)\nllx plan execute strategy.yaml --project . --dry-run\n```\n\n**Output format:**\nAll planfile commands emit colored markdown with syntax-highlighted YAML codeblocks. When piping to a file, raw markdown is preserved. Use `--format yaml` for pure YAML output.\n\n**Code Editing Backends:**\nWhen using `--use-aider`, llx automatically detects and uses the best available backend:\n\n- **LOCAL** - Local aider package (highest priority)\n- **CURSOR** - Cursor AI\n- **WINDSURF** - Windsurf AI\n- **CLAUDE_CODE** - Claude Code\n- **DOCKER** - Aider in Docker container\n- **MCP** - MCP services\n- **LLM_CHAT** - Fallback (always available)\n\nThe system automatically detects which backends are installed and selects the best one.\n\n**Task validation:**\n- `success` - Changes were made to code\n- `no_changes` - Issue not found or already fixed; ticket obsolete (maps to `canceled`)\n- `invalid` - No changes made (backend didn't modify files)\n- `not_found` - Target file doesn't exist\n- `already_fixed` - LLM reports issue not found or already fixed\n- `failed` - Execution error\n\nUse `--use-aider` for reliable code editing - the system automatically selects the best available backend.\n\n**Supported formats:**\n- **V1**: Tasks defined separately in `task_patterns`\n- **V2**: Tasks embedded directly in sprints\n- **planfile.yaml**: Redsl-generated format with flat tasks list and sprint task_patterns\n\nSee `llx/planfile/README_SIMPLIFIED.md` for details.\n\n## Testql Integration\n\nllx can execute tasks generated by testql audits:\n\n```bash\n# Generate planfile from testql audit\ntestql audit --output .testql/dom-audit-planfile.json\n\n# Convert to planfile.yaml format (if needed)\n# Then execute with llx\nllx plan execute planfile.yaml --project . --dry-run\n```\n\n**Example workflow:**\n```bash\n# 1. Run testql audit\ntestql audit --path ./my-project\n\n# 2. Generate planfile.yaml from audit results\n# (use redsl or manual conversion)\n\n# 3. Execute tasks with llx\nfrom llx.planfile import execute_strategy\nresults = execute_strategy(\"planfile.yaml\", project_path=\"./my-project\")\n```\n\n## Python API\n\n```python\nfrom llx import analyze_project, select_model, LlxConfig\n\nmetrics = analyze_project(\"./my-project\")\nresult = select_model(metrics)\nprint(result.model_id)   # \"claude-opus-4-20250514\"\nprint(result.explain())   # Human-readable reasoning\n```\n\n## Integration with wronai Toolchain\n\n| Tool | Role | llx Uses |\n|------|------|----------|\n| [code2llm](https://github.com/wronai/code2llm) | Static analysis | CC, fan-out, cycles, hotspots |\n| [redup](https://github.com/semcod/redup) | Duplication detection | Groups, recoverable lines |\n| [vallm](https://github.com/semcod/vallm) | Code validation | Pass rate, issue count |\n| [planfile](https://github.com/semcod/planfile) | Strategy execution | Task execution, sprint management |\n| [testql](https://github.com/semcod/testql) | Quality testing | Audit integration, ticket generation |\n| **llx** | **Model routing + MCP server** | **Consumes all above** |\n\n## Package structure\n\n```\nllx/\n├── __init__.py\n├── config.py\n├── analysis/            # Project metrics and external tool runners\n├── cli/                 # Typer commands and terminal formatters\n├── commands/            # High-level command helpers\n├── detection/           # Project type detection\n├── integrations/        # Proxy, proxym, and context helpers\n├── mcp/                 # MCP server, client, service, and tool registry\n├── orchestration/       # Multi-instance coordination utilities\n├── planfile/            # Strategy generation and execution helpers\n├── prellm/              # Small→large LLM preprocessing pipeline\n├── privacy/             # Anonymization and deanonymization helpers\n├── routing/             # Model selection and LiteLLM client\n└── tools/               # Docker, VS Code, models, config, health utilities\n```\n\nFull generated API inventory: `docs/README.md`.\n\n## Architecture notes\n\n- **Shared MCP registry**: `llx.mcp.tools.MCP_TOOLS` powers both `llx mcp tools` and the server dispatcher.\n- **Single tier order**: `routing/selector.py` uses one `TIER_ORDER` constant for selection and context-window upgrades.\n- **Version alignment**: the package exports now match `pyproject.toml` and `VERSION`.\n- **Focused modules**: CLI, routing, analysis, integrations, and planfile code are split by responsibility.\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 18:22 UTC_\n\n| Metric | Value |\n|---|---|\n| HEAD | `2c593db` |\n| Coverage | — |\n| Failing tests | — |\n| Commits in last cycle | 0 |\n\n\u003e No commits or file changes since the last taskill run.\n\n\u003c!-- taskill:status:end --\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsemcod%2Fllx","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsemcod%2Fllx","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsemcod%2Fllx/lists"}