Skip to main content

Intelligent LLM model router driven by real code metrics โ€” successor to preLLM

Project description

llx

Intelligent LLM model router driven by real code metrics.

PyPI Version License: Apache-2.0 Python

AI Cost Tracking

PyPI Version Python License AI Cost Human Time Model

  • ๐Ÿค– LLM usage: $7.5000 (81 commits)
  • ๐Ÿ‘ค Human dev: ~$3090 (30.9h @ $100/h, 30min dedup)

Generated on 2026-04-26 using openrouter/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/PRIVACY.md โ€” anonymization and sensitive-data handling

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.

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.

# 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

{
  "mcpServers": {
    "llx": {
      "command": "python3",
      "args": ["-m", "llx.mcp"]
    }
  }
}

Installation

# 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):

pip install uv
uv pip install -e ".[dev]"  # 10-100x faster than pip

Test profiles

# 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:

selection:
  models:
    balanced:
      provider: openrouter
      model_id: openrouter/x-ai/grok-code-fast-1
      max_context: 200000
# 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

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

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

// 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

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.

Planfile Integration

llx supports planfile.yaml format (redsl-generated) for sequential task execution:

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:

# 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

# Output to YAML
llx plan run . --output-yaml results.yaml
llx plan run . -o execution_results.yaml

# Generation and review
llx plan generate strategy.yaml --output generated/
llx plan review strategy.yaml --project .

# GitHub ticket creation (requires external planfile)
llx plan execute strategy.yaml --project . --dry-run

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
  • 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:

# 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:

# 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

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
planfile Strategy execution Task execution, sprint management
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 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.

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

llx-0.1.62.tar.gz (321.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

llx-0.1.62-py3-none-any.whl (379.9 kB view details)

Uploaded Python 3

File details

Details for the file llx-0.1.62.tar.gz.

File metadata

  • Download URL: llx-0.1.62.tar.gz
  • Upload date:
  • Size: 321.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.7

File hashes

Hashes for llx-0.1.62.tar.gz
Algorithm Hash digest
SHA256 81df17a153fde3d87c928313b92df12f1d0285f71cffa5e54c5e24ccc3994e70
MD5 50a8bbc9c2f78831b1ab8c8edd6a2236
BLAKE2b-256 b14c8742ea0ef7a87dfce1d172f7d9342c00852cabec4c8f17712876eacb0bd1

See more details on using hashes here.

File details

Details for the file llx-0.1.62-py3-none-any.whl.

File metadata

  • Download URL: llx-0.1.62-py3-none-any.whl
  • Upload date:
  • Size: 379.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.7

File hashes

Hashes for llx-0.1.62-py3-none-any.whl
Algorithm Hash digest
SHA256 b92194939718b7d4e5750bc7a3b9bf74268ec207f851f149be6e3866c292227e
MD5 cccff9f275898dd0c3b9a3ee0379b2b8
BLAKE2b-256 965ee37360d83c3079e52acb6f3a48a3ff6ff9fa829feadbed7c9c29090ce60b

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page