Intelligent LLM model router driven by real code metrics — successor to preLLM
Project description
llx
Intelligent LLM model router driven by real code metrics.
Successor to 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.
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: Claude Sonnet 4 / GPT-5 │
│ ├── cheap: Claude Haiku 4.5 │
│ ├── free: Gemini 2.5 Pro │
│ ├── openrouter: 300+ models (fallback) │
│ └── local: Ollama (Qwen2.5-Coder) │
└──────────────────────────────────────────────┘
│
┌───────▼─────────────────────────────────────────────────────┐
│ Code Analysis Pipeline │
│ code2llm → redup → vallm → llx │
│ (metrics → duplication → validation → model selection) │
└─────────────────────────────────────────────────────────────┘
Installation
pip install llx
# With integrations
pip install llx[all] # Everything
pip install llx[litellm] # LiteLLM proxy
pip install llx[code2llm] # Code analysis
pip install llx[redup] # Duplication detection
pip install llx[vallm] # Code validation
Quick Start
# Analyze project and get model recommendation
llx analyze ./my-project
# Quick model selection
llx select .
# 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 | — | — | — |
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
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
llx init # Creates llx.toml with defaults
Environment variables: LLX_LITELLM_URL, LLX_DEFAULT_TIER, LLX_PROXY_PORT, LLX_VERBOSE.
Python API
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 | Static analysis | CC, fan-out, cycles, hotspots |
| redup | Duplication detection | Groups, recoverable lines |
| vallm | Code validation | Pass rate, issue count |
| llx | Model routing | Consumes all above |
Package Structure
llx/
├── __init__.py # Public API (30L)
├── config.py # Config loader (160L)
├── analysis/
│ ├── collector.py # Metrics from .toon, filesystem (280L)
│ └── runner.py # Tool invocation (80L)
├── routing/
│ ├── selector.py # Metric → tier mapping (200L)
│ └── client.py # LiteLLM client wrapper (150L)
├── integrations/
│ ├── context_builder.py # .toon → LLM context (130L)
│ └── proxy.py # LiteLLM proxy management (100L)
└── cli/
├── app.py # Commands (230L, max CC ≤ 8)
└── formatters.py # Output formatting (120L)
Total: ~1,280 lines across 10 modules. No file exceeds 300L. Max CC ≤ 8.
Compare: preLLM had 8,900 lines with 3 god modules (cli.py: 999L, core.py: 893L, trace.py: 509L).
License
Apache License 2.0 - see LICENSE for details.
Author
Created by Tom Sapletta - tom@sapletta.com
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file llx-0.1.4.tar.gz.
File metadata
- Download URL: llx-0.1.4.tar.gz
- Upload date:
- Size: 32.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b46f4b6def41c80d65bee8f57a995730f06e4b21cc3658036243ebef1d1bb58a
|
|
| MD5 |
0e2a1e3e2f8431d80732553a12dc29b5
|
|
| BLAKE2b-256 |
55d05ae24b188f539cc8e28d1b53eb20e66f03b4a73368f1db48927a3e703040
|
File details
Details for the file llx-0.1.4-py3-none-any.whl.
File metadata
- Download URL: llx-0.1.4-py3-none-any.whl
- Upload date:
- Size: 32.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7c2be773631e423c1d1d6a951e74e26fdcbf52a11012e9e3ecb8c6c7cc071283
|
|
| MD5 |
3edf48fb3bbbff423fa3be879aa42774
|
|
| BLAKE2b-256 |
69e8ece74959791a7be2b3b54f32297a81224ab6e685f6df8e1bea8ee19b0aeb
|