https://github.com/semcod/llx
Last synced: 8 days ago
JSON representation
- Host: GitHub
- URL: https://github.com/semcod/llx
- Owner: semcod
- License: other
- Created: 2026-03-25T15:57:02.000Z (3 months ago)
- Default Branch: main
- Last Pushed: 2026-04-25T20:24:26.000Z (about 1 month ago)
- Last Synced: 2026-04-25T22:09:08.713Z (about 1 month ago)
- Language: Python
- Size: 35.6 MB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Contributing: CONTRIBUTING.md
- License: LICENSE
Awesome Lists containing this project
README
# llx
**Intelligent LLM model router driven by real code metrics.**
[](https://pypi.org/project/llx/)
[](https://pypi.org/project/llx/)
[](https://opensource.org/licenses/Apache-2.0)
[](https://python.org)
## AI Cost Tracking
   
  
- π€ **LLM usage:** $7.5000 (107 commits)
- π€ **Human dev:** ~$3749 (37.5h @ $100/h, 30min dedup)
Generated on 2026-04-26 using [openrouter/qwen/qwen3-coder-next](https://openrouter.ai/qwen/qwen3-coder-next)
---
## Documentation map
- `README.md` β project overview, install, and quickstart
- `docs/README.md` β generated API inventory from source analysis
- `docs/llx-tools.md` β ecosystem CLI reference
- `docs/PLANFILE_CLEANUP.md` β ticket lifecycle, freshness, `llx plan clean`, prune flags
- `docs/PRIVACY.md` β anonymization and sensitive-data handling
**Successor to [preLLM](https://github.com/wronai/prellm)** β rebuilt with modular architecture, no god modules, and metric-driven routing.
llx 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.
**Principle**: larger + more coupled + more complex β stronger (and more expensive) model.
## CLI surface
llx is organized around a small set of command groups:
- `llx analyze`, `llx select`, `llx chat` β metric-driven analysis and model routing
- `llx proxy` β LiteLLM proxy config, start, and status
- `llx mcp` β MCP server start, config, and tool listing
- `llx plan` β planfile generation, review, code generation, and execution
- `llx strategy` β interactive strategy creation, validation, run, and verification
- `llx info`, `llx models`, `llx init`, `llx fix` β inspection and utility commands
## Why llx? (Lessons from preLLM)
preLLM proved the concept but had architectural issues that llx resolves:
| Problem in preLLM | llx Solution |
|---|---|
| `cli.py`: 999 lines, CC=30 (`main`), CC=27 (`query`) | CLI split into `app.py` + `formatters.py`, max CC β€ 8 |
| `core.py`: 893 lines god module | Config, analysis, routing in separate modules (β€250L each) |
| `trace.py`: 509 lines, CC=28 (`to_stdout`) | Output formatting as dedicated functions |
| Hardcoded model selection | Metric-driven thresholds from code2llm .toon data |
| No duplication/validation awareness | Integrates redup + vallm for richer metrics |
## Architecture
```
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β IDE / Agent Layer β
β Roo Code β Cline β Continue.dev β Aider β Claude Code β
β (point at localhost:4000 as OpenAI-compatible API) β
βββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββββββββββ
β
βββββββββββββββββββΌββββββββββββββββββββββββββββββββββββββββββββ
β LiteLLM Proxy (localhost:4000) β
β ββββββββββββ ββββββββββββββββ ββββββββββββββββββββββ β
β β Router β β Semantic β β Cost Tracking β β
β β (metrics)β β Cache (Redis)β β + Budget Limits β β
β ββββββ¬ββββββ ββββββββββββββββ ββββββββββββββββββββββ β
βββββββββΌββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
ββββββΌβββββββββββββββββββββββββββββββββββββββββ
β β Model Tiers β
β βββ premium: Claude Opus 4 β
β βββ balanced: Qwen 2.5 Coder (OpenRouter) β
β βββ cheap: Claude Haiku 4.5 β
β βββ free: Nemotron 3 Super (OpenRouter)β
β βββ openrouter: 300+ models (fallback) β
β βββ local: Ollama (Qwen2.5-Coder) β
ββββββββββββββββββββββββββββββββββββββββββββββββ
β
βββββββββΌββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Code Analysis Pipeline β
β code2llm β redup β vallm β llx β
β (metrics β duplication β validation β model selection) β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
```
## MCP server
llx exposes its MCP tools through a shared registry in `llx.mcp.tools.MCP_TOOLS`.
By default, the MCP server runs over **stdio** for Claude Desktop. Use SSE only when you need a remote or web client.
```bash
# Start MCP server over SSE for web/remote clients
llx mcp start --mode sse --port 8000
# Direct module entrypoint
python -m llx.mcp --sse --port 8000
```
### Tool groups
- `llx_analyze`, `llx_select`, `llx_chat` β project metrics and model routing
- `llx_preprocess`, `llx_context` β query preprocessing and environment context
- `code2llm_analyze`, `redup_scan`, `vallm_validate` β code-quality analysis helpers
- `llx_proxy_status`, `llx_proxym_status`, `llx_proxym_chat` β proxy and proxym integration
- `aider`, `planfile_generate`, `planfile_apply` β workflow and refactoring helpers
- `llx_privacy_scan`, `llx_project_anonymize`, `llx_project_deanonymize` β privacy tooling
### Claude Desktop setup
```json
{
"mcpServers": {
"llx": {
"command": "python3",
"args": ["-m", "llx.mcp"]
}
}
}
```
## Installation
```bash
# Recommended: Use uv for 10-100x faster installation
pip install uv
uv pip install -e ".[dev]"
# Or with pip
pip install llx
# With integrations
pip install llx[all] # Everything + MCP
pip install llx[mcp] # MCP server only
pip install llx[litellm] # LiteLLM proxy
pip install llx[code2llm] # Code analysis
pip install llx[redup] # Duplication detection
pip install llx[vallm] # Code validation
# Development environments
pip install -e ".[dev]" # Lightweight dev tools (pytest, ruff, mypy)
pip install -e ".[dev-full]" # Full dev with all tools (goal, costs, pfix)
```
**uv Installation (Recommended):**
```bash
pip install uv
uv pip install -e ".[dev]" # 10-100x faster than pip
```
### Test profiles
```bash
# Default test profile (used by goal.yaml)
pytest tests/ -v
# Full test profile with MCP tests enabled
pip install -e ".[mcp]"
pytest tests/ -v
```
`tests/test_mcp.py` and `tests/test_aider_mcp.py` require the optional `mcp` package.
When `llx[mcp]` is not installed, those modules are skipped automatically instead of
breaking test collection.
**Configuration:**
Model tiers are configured in `llx.yaml`:
```yaml
selection:
models:
balanced:
provider: openrouter
model_id: openrouter/x-ai/grok-code-fast-1
max_context: 200000
```
```bash
# Analyze project and get model recommendation
llx analyze ./my-project
# With task hint
llx select . --task refactor
# Point to pre-existing .toon files
llx analyze . --toon-dir ./analysis/
# JSON output for CI/CD
llx analyze . --json
# Chat with auto-selected model
llx chat . --prompt "Refactor the god modules"
# Force local model
llx select . --local
```
## Model Selection Logic
| Metric | Premium (β₯) | Balanced (β₯) | Cheap (β₯) | Free |
|--------|-------------|--------------|-----------|------|
| Files | 50 | 10 | 3 | <3 |
| Lines | 20,000 | 5,000 | 500 | <500 |
| Avg CC | 6.0 | 4.0 | 2.0 | <2.0 |
| Max fan-out | 30 | 10 | β | β |
| Max CC | 25 | 15 | β | β |
| Dup groups | 15 | 5 | β | β |
| Dep cycles | any | β | β | β |
## Privacy & Anonymization
LLX provides **reversible anonymization** to protect sensitive data when sending to LLMs:
### Features
- **Text anonymization**: Emails, API keys, passwords, PESEL, credit cards
- **Project-level**: AST-based code anonymization (variables, functions, classes)
- **Round-trip**: Anonymize β Send to LLM β Deanonymize response
- **Persistent mapping**: Save/restore context for later deanonymization
### Quick Usage
```python
from llx.privacy import quick_anonymize, quick_deanonymize
# Simple text anonymization
result = quick_anonymize("Email: user@example.com, API: sk-abc123")
print(result.text) # "Email: [EMAIL_A1B2], API: [APIKEY_C3D4]"
# Later: restore original values
restored = quick_deanonymize(llm_response, result.mapping)
```
### Project-Level Anonymization
```python
from llx.privacy.project import AnonymizationContext, ProjectAnonymizer
from llx.privacy.deanonymize import ProjectDeanonymizer
# Anonymize entire project
ctx = AnonymizationContext(project_path="./my-project")
anonymizer = ProjectAnonymizer(ctx)
result = anonymizer.anonymize_project()
# Save context for later
ctx.save("./my-project.anon.json")
# Deanonymize LLM response
deanonymizer = ProjectDeanonymizer(ctx)
restored = deanonymizer.deanonymize_chat_response(llm_response)
```
### MCP Tools
```json
// Scan for sensitive data
{"tool": "llx_privacy_scan", "text": "Email: user@example.com"}
// Anonymize project
{"tool": "llx_project_anonymize", "path": "./my-project", "output_dir": "./anon"}
// Deanonymize response
{"tool": "llx_project_deanonymize", "context_path": "./anon/.anonymization_context.json", "text": "Fix fn_ABC123"}
```
See `docs/PRIVACY.md` and `examples/privacy/` for complete documentation.
## Real-World Selection Examples
| Project | Files | Lines | CCΜ | Max CC | Fan-out | Tier |
|---------|-------|-------|-----|--------|---------|------|
| Single script | 1 | 80 | 2.0 | 4 | 0 | **free** |
| Small CLI | 5 | 600 | 3.0 | 8 | 3 | **cheap** |
| **preLLM** | **31** | **8,900** | **5.0** | **28** | **30** | **premium** |
| vallm | 56 | 8,604 | 3.5 | 42 | β | **balanced** |
| code2llm | 113 | 21,128 | 4.6 | 65 | 45 | **premium** |
| Monorepo | 500+ | 100K+ | 5.0+ | 30+ | 50+ | **premium** |
## LiteLLM Proxy
```bash
llx proxy config # Generate litellm_config.yaml
llx proxy start # Start proxy on :4000
llx proxy status # Check if running
```
Configure IDE tools to point at `http://localhost:4000`:
| Tool | Config |
|------|--------|
| Roo Code / Cline | `"apiBase": "http://localhost:4000/v1"` |
| Continue.dev | `"apiBase": "http://localhost:4000/v1"` |
| Aider | `OPENAI_API_BASE=http://localhost:4000` |
| Claude Code | `ANTHROPIC_BASE_URL=http://localhost:4000` |
| Cursor / Windsurf | OpenAI-compatible endpoint |
## Configuration
```bash
llx init # Creates llx.toml with defaults
```
Environment variables: `LLX_LITELLM_URL`, `LLX_DEFAULT_TIER`, `LLX_PROXY_PORT`, `LLX_VERBOSE`.
## Planfile Integration
llx supports planfile.yaml format (redsl-generated) for sequential task execution:
```python
from llx.planfile import execute_strategy
# Execute planfile.yaml (supports V1, V2, and redsl formats)
results = execute_strategy(
"planfile.yaml",
project_path=".",
dry_run=True
)
# Process results
for result in results:
print(f"{result.task_name}: {result.status}")
```
**CLI usage:**
```bash
# Basic execution
llx plan run . # Run planfile.yaml
llx plan run . --tier free # With specific model tier
llx plan run . --sprint 1 # Only sprint 1
llx plan run . --dry-run # Simulate without executing
# Concurrency and task limits
llx plan run . --max-concurrent 3 # Run 3 tasks in parallel
llx plan run . --max-tasks 10 # Process only 10 tasks total
llx plan run . -j 5 -n 20 # Short form: 5 concurrent, max 20 tasks
# Proxy management (automatic detection and startup)
llx plan run . # Auto-starts proxy if not running
llx plan run . --no-auto-start-proxy # Disable automatic proxy start
# Code editing with automatic backend detection
llx plan run . --use-aider # Auto-detect best backend (LOCAL > CURSOR > WINDSURF > CLAUDE_CODE > DOCKER > MCP > LLM_CHAT)
llx plan run . -a -j 3 -n 10 # Backend detection + concurrency + task limit
# Structured YAML output (always on stdout)
llx plan run . --sprint 1 --max-tasks 1 > run-results.yaml
# Also save a copy to file while keeping YAML on stdout
llx plan run . --output-yaml results.yaml
llx plan run . -o execution_results.yaml
# Optional: sync TODO.md checkboxes from planfile task status/results
# (configured in planfile.yaml)
# integrations:
# markdown:
# sync_on_plan_run: true
# todo_file: TODO.md
# Generation and review
llx plan generate strategy.yaml --output generated/
llx plan review strategy.yaml --project .
# Ticket freshness validation
llx plan validate . # Check if tickets are still current
llx plan validate . --prune-stale # Validate and delete stale tickets
# Cleanup resolved tickets
llx plan clean . # Remove canceled tickets from planfile.yaml + TODO.md
llx plan clean . --include-done # Also remove done tickets
llx plan clean . --dry-run # Preview without writing
# GitHub ticket creation (requires external planfile)
llx plan execute strategy.yaml --project . --dry-run
```
**Output format:**
All 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.
**Code Editing Backends:**
When using `--use-aider`, llx automatically detects and uses the best available backend:
- **LOCAL** - Local aider package (highest priority)
- **CURSOR** - Cursor AI
- **WINDSURF** - Windsurf AI
- **CLAUDE_CODE** - Claude Code
- **DOCKER** - Aider in Docker container
- **MCP** - MCP services
- **LLM_CHAT** - Fallback (always available)
The system automatically detects which backends are installed and selects the best one.
**Task validation:**
- `success` - Changes were made to code
- `no_changes` - Issue not found or already fixed; ticket obsolete (maps to `canceled`)
- `invalid` - No changes made (backend didn't modify files)
- `not_found` - Target file doesn't exist
- `already_fixed` - LLM reports issue not found or already fixed
- `failed` - Execution error
Use `--use-aider` for reliable code editing - the system automatically selects the best available backend.
**Supported formats:**
- **V1**: Tasks defined separately in `task_patterns`
- **V2**: Tasks embedded directly in sprints
- **planfile.yaml**: Redsl-generated format with flat tasks list and sprint task_patterns
See `llx/planfile/README_SIMPLIFIED.md` for details.
## Testql Integration
llx can execute tasks generated by testql audits:
```bash
# Generate planfile from testql audit
testql audit --output .testql/dom-audit-planfile.json
# Convert to planfile.yaml format (if needed)
# Then execute with llx
llx plan execute planfile.yaml --project . --dry-run
```
**Example workflow:**
```bash
# 1. Run testql audit
testql audit --path ./my-project
# 2. Generate planfile.yaml from audit results
# (use redsl or manual conversion)
# 3. Execute tasks with llx
from llx.planfile import execute_strategy
results = execute_strategy("planfile.yaml", project_path="./my-project")
```
## Python API
```python
from llx import analyze_project, select_model, LlxConfig
metrics = analyze_project("./my-project")
result = select_model(metrics)
print(result.model_id) # "claude-opus-4-20250514"
print(result.explain()) # Human-readable reasoning
```
## Integration with wronai Toolchain
| Tool | Role | llx Uses |
|------|------|----------|
| [code2llm](https://github.com/wronai/code2llm) | Static analysis | CC, fan-out, cycles, hotspots |
| [redup](https://github.com/semcod/redup) | Duplication detection | Groups, recoverable lines |
| [vallm](https://github.com/semcod/vallm) | Code validation | Pass rate, issue count |
| [planfile](https://github.com/semcod/planfile) | Strategy execution | Task execution, sprint management |
| [testql](https://github.com/semcod/testql) | Quality testing | Audit integration, ticket generation |
| **llx** | **Model routing + MCP server** | **Consumes all above** |
## Package structure
```
llx/
βββ __init__.py
βββ config.py
βββ analysis/ # Project metrics and external tool runners
βββ cli/ # Typer commands and terminal formatters
βββ commands/ # High-level command helpers
βββ detection/ # Project type detection
βββ integrations/ # Proxy, proxym, and context helpers
βββ mcp/ # MCP server, client, service, and tool registry
βββ orchestration/ # Multi-instance coordination utilities
βββ planfile/ # Strategy generation and execution helpers
βββ prellm/ # Smallβlarge LLM preprocessing pipeline
βββ privacy/ # Anonymization and deanonymization helpers
βββ routing/ # Model selection and LiteLLM client
βββ tools/ # Docker, VS Code, models, config, health utilities
```
Full generated API inventory: `docs/README.md`.
## Architecture notes
- **Shared MCP registry**: `llx.mcp.tools.MCP_TOOLS` powers both `llx mcp tools` and the server dispatcher.
- **Single tier order**: `routing/selector.py` uses one `TIER_ORDER` constant for selection and context-window upgrades.
- **Version alignment**: the package exports now match `pyproject.toml` and `VERSION`.
- **Focused modules**: CLI, routing, analysis, integrations, and planfile code are split by responsibility.
## License
Licensed under Apache-2.0.
## Status
_Last updated by [taskill](https://github.com/oqlos/taskill) at 2026-04-25 18:22 UTC_
| Metric | Value |
|---|---|
| HEAD | `2c593db` |
| Coverage | β |
| Failing tests | β |
| Commits in last cycle | 0 |
> No commits or file changes since the last taskill run.