Skip to main content

Scope your AI context before it explodes

Project description

context-router

Problem

Working with AI tools on large codebases causes context explosion. Every task loads the entire codebase into the prompt.

What context-router does

Routes a task to the agent that owns it. Scopes the prompt to only the relevant files. Keeps a lightweight map of who owns what.

What context-router does NOT do

Does not call any LLM. Does not automate anything. Does not execute code.

Without context-router:

"fix the auth bug" → loads 847 files → model touches 6 modules it shouldn't

With context-router:

context-router ask "fix the auth bug" --file src/auth/token.py → Agent: backend-engineer → Touch only: src/auth/token.py, src/auth/session.py → Do not modify: src/api/, src/db/, src/frontend/

Install

pip install context-router

Local dev:

pip install -e .

Usage

1. Define your agents

context-router init creates 3 core agents automatically:

agents/
├── dispatcher.agent.yaml      ← routes all tasks (do not edit)
├── memory-keeper.agent.yaml   ← syncs memory after commits (do not edit)
├── validator.agent.yaml       ← validates diffs before applying (do not edit)
└── default.agent.yaml         ← template — copy and rename for your domains

Add one agent per domain in your project.

Create an agents/ directory in your project and add one YAML file per agent:

# agents/backend-engineer.agent.yaml
name: backend-engineer
owned_paths:
  - src/auth/*.py
  - src/api/*.py
  - src/db/*.py
description: Handles backend logic including authentication, API routes, and database models.

2. Initialize

context-router init

Specify your AI tool:

context-router init --tool claude    # Claude Code
context-router init --tool cursor    # Cursor
context-router init --tool copilot   # GitHub Copilot
context-router init --tool codex     # Codex / OpenAI
context-router init --tool windsurf  # Windsurf
context-router init --tool aider     # Aider
context-router init --tool all       # generate all

If you skip --tool, context-router detects your tool automatically or asks you to choose.

Tool Config file generated
Claude Code CLAUDE.md + AGENTS.md
Cursor .cursorrules
GitHub Copilot .github/copilot-instructions.md
Codex AGENTS.md
Windsurf .windsurfrules
Aider .aider.conf.yml

Scans all *.agent.yaml files in agents/, writes .context-router/project_map.json, and scaffolds the full memory structure.

After context-router init your project contains:

.context-router/
├── CORE.md                    ← global invariants (always loaded)
├── CORE_LITE.md               ← minimal version for quick tasks
├── project_map.json           ← agent ownership map (auto-generated)
└── memory/
    ├── MEMORY.md              ← status, architecture, recent fixes
    ├── MEMORY_MAP.md          ← file/function ownership
    ├── MEMORY_CHANGELOG.md    ← full fix history (load on demand)
    ├── MEMORY_INTELLIGENCE.md ← domain knowledge (load on demand)
    └── MEMORY_REFERENCE.md   ← lessons learned, roadmap (load on demand)

Session start prompt for your AI tool:

Read: .context-router/CORE.md
Read: .context-router/memory/MEMORY.md
Read: .context-router/memory/MEMORY_MAP.md
Then paste: context-router ask "your task" --file path/to/file

For quick/simple tasks use CORE_LITE.md instead of CORE.md. Load MEMORY_CHANGELOG.md only when debugging old behavior. Load MEMORY_INTELLIGENCE.md only for domain-specialist tasks.

Initialized. 3 agents registered.

3. Route a task

context-router ask "fix the auth token expiry bug" --file src/auth/token.py
Agent:   backend-engineer
Files:   src/auth/token.py, src/auth/session.py
Prompt:
  Read: agents/backend-engineer.agent.yaml
  Task: fix the auth token expiry bug
  Touch only: src/auth/token.py, src/auth/session.py
  Do not modify: src/api/routes.py, src/db/models.py

Without --file, context-router keyword-matches your task against agent descriptions:

context-router ask "authentication is broken"
Agent:   backend-engineer
Files:   src/auth/*.py, src/api/*.py, src/db/*.py
Prompt:
  Read: agents/backend-engineer.agent.yaml
  Task: authentication is broken
  Touch only: src/auth/*.py, src/api/*.py, src/db/*.py
  Do not modify: src/ui/*.tsx, src/infra/*.sh

4. Validate a diff

context-router validate --staged          # checks git diff --cached
context-router validate --diff my.patch   # checks a saved diff file

Loads .context-router/validator.yaml and runs all matching rules against the diff. Exits 0 on PASS, 1 on FAIL.

STATUS: FAIL
REASON: 'reader.readtext' used outside `with _ocr_lock:` block
RETRY_WITH:
FIX_HINT: Wrap reader.readtext() inside `with _ocr_lock:`

Rule types: lock_guard, pair_call, no_output, line_count, threshold_drift. See .context-router/validator.yaml (generated by context-router init) for full field reference.

Usage — run command

Manual mode (no API key needed)

context-router run "fix the login form" --file src/frontend/login.js
─────────────────────────────────────
  Agent:   frontend
  Prompt:  .context-router/current-task.md
─────────────────────────────────────
  1. Paste the prompt into your AI tool
  2. Save the diff output as:
     .context-router/output.diff
  3. Run: context-router run --continue
─────────────────────────────────────

Auto mode (API key in .env)

cp .env.example .env
# add your key to .env
context-router run "fix the login form" --file src/frontend/login.js
Auto mode — using anthropic (claude-sonnet-4-6)
Attempt 1/3...
STATUS: PASS
Apply the diff to your codebase.

Override model

context-router run "task" --file path --model claude-opus-4-6

Meta-controller retry loop

MetaController wraps any agent/validator pair with a failure-aware retry loop.

from context_router.meta_controller import MetaController
from pathlib import Path

mc = MetaController(
    task="fix the token expiry bug",
    root=Path("."),
    config_path=Path(".context-router/retry_config.yaml"),
)
result = mc.run(agent_runner, validator)
# result = {"passed": True/False, "attempts": N, "report_path": None | "logs/..."}

agent_runner(task, prompt_patches, param_patches) → str validator(output) → (bool passed, str fail_text)

On FAIL, the controller:

  1. Stashes working tree (git stash)
  2. Builds a retry plan from retry_config.yaml (prompt constraints + param overrides)
  3. Re-runs the agent with accumulated patches
  4. On retry_with: human — escalates immediately, writes failure report
  5. After MAX_RETRIES (3) — restores working tree, writes report to logs/

retry_config.yaml example:

categories: [system, logic, output, cross_agent]

prompt_patches:
  logic:
    2: "add inline comments explaining each change"
    3: "minimal fix only  change one thing at a time"

category_map:
  my_rule_id: logic

human_hints:
  logic: "Logic error  review the change manually."

See examples/reel-engine/retry_config.yaml for a full real-world example.

Agent YAML format

name: string                    # unique identifier, used in output
owned_paths:                    # glob patterns — files this agent is responsible for
  - src/auth/*.py
  - src/api/*.py
description: one sentence       # used for keyword fallback matching when no --file given

Adding a new agent

  1. Create agents/<name>.agent.yaml
  2. Run context-router init

That's it.

How it works

context-router init
  └── scans agents/*.agent.yaml
  └── writes .context-router/project_map.json  {glob → agent_name}

context-router ask "task" --file src/auth/token.py
  └── loads project_map.json
  └── matches file path against globs
  └── prints structured prompt block
  └── no network, no LLM, no side effects

Optional: graphify

graphify builds an AST-based knowledge graph of your codebase. Zero API cost. Run it after every code change:

graphify update .

Output: graphify-out/GRAPH_REPORT.md — node/edge/community structure for your codebase.

How graphify integrates with context-router

Data flow:

code change
  → graphify update .
  → graphify-out/GRAPH_REPORT.md   (always regenerated)
  → @memory-keeper (post-commit)
      reads GRAPH_REPORT.md
      updates MEMORY_MAP.md        (always, after every commit)

agents during a task
  → read MEMORY_MAP.md             (session start, always)
  → read GRAPH_REPORT.md           (on demand only — unknown deps)

Rules:

  • graphify update . is always a plain shell command — no API calls
  • GRAPH_REPORT.md is read on demand only (not at session start)
  • MEMORY_MAP.md is the agent-readable ownership table
  • graphify-out/ files are never loaded at session start
  • graphify never writes to .context-router/ directly

Trigger graphify after every code change:

graphify update .

Your AI tool reads the output:

Read graphify-out/GRAPH_REPORT.md only when tracing
unknown cross-file dependencies.

Success criteria

  • Install in under 2 minutes
  • Understand it fully in under 5 minutes
  • Add a new agent by editing one YAML file
  • Reduces context size when working with any AI coding tool

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

llm_context_router-0.6.0.tar.gz (35.0 kB view details)

Uploaded Source

Built Distribution

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

llm_context_router-0.6.0-py3-none-any.whl (24.9 kB view details)

Uploaded Python 3

File details

Details for the file llm_context_router-0.6.0.tar.gz.

File metadata

  • Download URL: llm_context_router-0.6.0.tar.gz
  • Upload date:
  • Size: 35.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.4

File hashes

Hashes for llm_context_router-0.6.0.tar.gz
Algorithm Hash digest
SHA256 4da17e726fca7889cf177c5b8bc90870675fe6b61cabe7084e9eeac7b9f658d9
MD5 4ce9f111b6a30e378e1efc8ea6d23e9e
BLAKE2b-256 d1508b04b5e7a1f4e9e099a9582c1293df9817acd7eb0f99012bca5497267924

See more details on using hashes here.

File details

Details for the file llm_context_router-0.6.0-py3-none-any.whl.

File metadata

File hashes

Hashes for llm_context_router-0.6.0-py3-none-any.whl
Algorithm Hash digest
SHA256 7f0b2c7cfbcee5355779e05ef966050a1b969d4481c016e1cb5fc7b0e9f144c9
MD5 5f26db2dc07940988e9e5516147e3844
BLAKE2b-256 8a3cffcffb5a80ae7b2c06d1f38606942f6135b05b89bda4daf8f85ccf97de3f

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