SC-Router
AI routing based on Selector Complexity theory.
"What is the minimum cost of choosing the right strategy?"
SC-Router classifies queries by the difficulty of the routing decision itself — not just the query content. It determines whether a query needs direct dispatch, pipeline decomposition, combinatorial search, or full agent delegation.
v0.3.0 adds distributed execution: register remote agents, execute across microservices, health checks with circuit breaker, and an optional HTTP gateway — all without touching the core classifier (<0.5ms p99).
Part of kore-stack — the complete cognitive middleware for LLMs. pip install kore-stack for the full stack, or install individually:
Install
pip install sc-router # core router (zero dependencies)
pip install sc-router[gateway] # + HTTP gateway (starlette, uvicorn, httpx, pyyaml)
pip install kore-bridge[sc] # integrated with kore-bridge
pip install kore-stack # full stack: mind + bridge + SC routing
Quick Start
Local routing (as before)
from sc_router import ToolCatalog, Tool, route
catalog = ToolCatalog()
catalog.register(Tool(
name="weather",
description="Get weather forecast",
input_types={"location"},
output_types={"weather_data"},
capability_tags={"weather", "forecast", "temperature"}
))
catalog.register(Tool(
name="calculator",
description="Perform arithmetic calculations",
input_types={"expression"},
output_types={"number"},
capability_tags={"math", "calculate", "arithmetic"}
))
result = route("What's the weather in Madrid?", catalog)
print(result.sc_level) # 0
print(result.strategy) # 'direct'
print(result.tool_assignments) # [ToolAssignment(tool='weather', ...)]
Distributed routing (new in v0.3.0)
import asyncio
from sc_router import RemoteAgent, AgentRegistry, AgentStatus, route
from sc_router.executor import execute
from sc_router.catalog import Tool
# 1. Register remote agents
registry = AgentRegistry()
registry.register(RemoteAgent(
id="search-agent",
url="http://search-service:8081",
tool=Tool(
name="search",
description="Search the web",
input_types={"query"},
output_types={"search_results"},
capability_tags={"search", "web", "find"},
),
status=AgentStatus.HEALTHY,
))
# 2. Classify (still <50ms, zero overhead)
result = route("Search for Python tutorials", registry.catalog)
# 3. Execute against remote agents
exec_result = asyncio.run(execute(result, registry))
print(exec_result.outputs)
YAML config + Gateway
# config.yaml
agents:
- id: search-agent
url: http://search:8081
tool:
name: search
description: "Search the web"
capability_tags: [search, web]
input_types: [query]
output_types: [search_results]
- id: weather-agent
url: http://weather:8082
tool:
name: weather
description: "Get weather forecast"
capability_tags: [weather, forecast]
input_types: [location]
output_types: [weather_data]
health:
failure_threshold: 3
recovery_timeout_s: 30
# Start the gateway
python -m uvicorn sc_router.gateway:create_app --factory --host 0.0.0.0 --port 8080
# Classify + execute
curl -X POST http://localhost:8080/route \
-H "Content-Type: application/json" \
-d '{"query": "What is the weather in Madrid?"}'
# Classify only (no remote calls)
curl -X POST http://localhost:8080/route \
-H "Content-Type: application/json" \
-d '{"query": "What is the weather in Madrid?", "execute": false}'
# Health check
curl http://localhost:8080/health
# List agents
curl http://localhost:8080/agents
SC Levels
| SC | Query Type | Routing Action | Example |
|---|---|---|---|
| SC(0) | 1 tool, obvious | Direct dispatch | "What's the weather in Madrid?" |
| SC(1) | Decomposable | Pipeline/parallel | "Search flights to Paris, book the cheapest" |
| SC(2) | Ambiguous/complex | Search combinations | "Plan trip: flights+hotel+restaurants, budget $2000" |
| SC(3) | Globally entangled | Full agent | "Analyze market trends, cross with social sentiment, build predictive model" |
How It Works
SC-Router extracts 17 structural features from each query, then classifies the routing difficulty using a threshold-based decision tree — no ML required.
The classification runs in <0.5ms p99 and adds zero overhead to any routing pipeline.
Architecture (v0.3.0)
┌─────────────────┐
POST /route ──────►│ Gateway │
│ (Starlette) │
└────────┬─────────┘
│
┌─────────────▼──────────────┐
│ SC Classification │
│ 17 features, <0.5ms p99 │
└─────────────┬──────────────┘
│
┌─────────────▼──────────────┐
│ AgentRegistry │
│ RemoteAgent + ToolCatalog │
│ Health checks + Circuit │
│ breaker │
└─────────────┬──────────────┘
│
┌──────────────────┼──────────────────┐
│ │ │
┌──────▼──────┐ ┌───────▼──────┐ ┌────────▼──────┐
│ Agent A │ │ Agent B │ │ Agent C │
│ (search) │ │ (weather) │ │ (summarizer) │
└─────────────┘ └──────────────┘ └───────────────┘
Core (pip install sc-router): zero dependencies, classification + local routing.
Gateway (pip install sc-router[gateway]): Starlette HTTP gateway, distributed execution, health checks, YAML config.
Integration with kore-bridge
SC-Router plugs directly into kore-bridge as SCRouterProvider:
from kore_bridge import SCRouterProvider, Bridge, OllamaProvider
from kore_bridge.providers import OpenAIProvider
from kore_mind import Mind
from sc_router import ToolCatalog, Tool
catalog = ToolCatalog()
catalog.register(Tool(
name="calculator",
description="Arithmetic calculations",
input_types={"expression"},
output_types={"number"},
capability_tags={"math", "calculate"},
))
router = SCRouterProvider(
providers={
"fast": OllamaProvider(model="llama3.2"),
"quality": OpenAIProvider(model="gpt-4o"),
},
catalog=catalog,
)
bridge = Bridge(mind=Mind("agent.db"), llm=router)
bridge.think("What is 2+2?") # SC(0) → Ollama
print(router.last_sc_level) # 0
Performance
Benchmarked on 10-tool catalog, 100 iterations per query (v0.3.0):
| Query | avg | p50 | p95 | p99 |
|---|---|---|---|---|
| SC(0) direct | 0.08ms | 0.07ms | 0.13ms | 0.18ms |
| SC(1) pipeline | 0.27ms | 0.26ms | 0.41ms | 0.44ms |
| SC(2) constrained | 0.47ms | 0.46ms | 0.56ms | 0.59ms |
| SC(3) entangled | 0.22ms | 0.23ms | 0.32ms | 0.44ms |
Distributed layer adds zero overhead to classification. Scales to 50+ tools under 50ms.
Part of kore-stack
| Package | What it does |
|---|---|
| kore-mind | Memory, identity, traces, cache storage |
| kore-bridge | LLM integration, cache logic, rate limiting, A/B testing, SC routing |
| sc-router (this) | Query routing by Selector Complexity theory |
| kore-stack | All of the above, one install: pip install kore-stack |
License
MIT
Metadata
Release files for sc-router 0.4.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| sc_router-0.4.1.tar.gz | 62.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| sc_router-0.4.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 114.2 kB
Release files / sc_router-0.4.1.tar.gz
| Download URL | sc_router-0.4.1.tar.gz |
|---|---|
| Size | 62.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
cf9c50a873d656786aa19b8d198500a92a40b72866aea1319ad96ae59351349c
|
|
BLAKE2b-256 checksum How to use checksums |
13991e6a01f614a815d56165af3ffe46ca0750855569a8474cacfd2f4ea9b3be
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.3
|
Release files / sc_router-0.4.1-py3-none-any.whl
| Download URL | sc_router-0.4.1-py3-none-any.whl |
|---|---|
| Size | 51.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
880f3ef60626205ddca8fed1345210aed08c6e9137e2e44c230edec711e56d0d
|
|
BLAKE2b-256 checksum How to use checksums |
f719d97a464b7546c34b4b3cbcbc4c517ab40b5c014173edc460b375c01186ff
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.3
|