Files
llm-connect/contracts/functional/routing-policy.md
Bernd Worsch d51d6303e2
Some checks failed
CI / test (3.10) (push) Has been cancelled
CI / test (3.11) (push) Has been cancelled
CI / test (3.12) (push) Has been cancelled
feat: WP-0003 — RoutingPolicy (FR-2) and HTTP serve mode (FR-1)
FR-2 RoutingPolicy:
- RoutingPolicy + RoutingRule dataclasses in llm_connect/routing.py
- resolve(task_type, estimated_cost_per_1k=None) with cost-cap fallback
- Exported from llm_connect.__init__; contract doc at contracts/functional/routing-policy.md
- 11 tests covering rule match, cost-cap, fallback, unknown type, no-match

FR-1 HTTP serve mode:
- LLMServer in llm_connect/server.py (stdlib http.server, zero extra deps)
- POST /execute + GET /health; CLI via python -m llm_connect.server
- [server] optional-dep group added to pyproject.toml
- Contract doc at contracts/functional/server.md
- 9 tests: health, round-trip, 400/404/500 errors, config forwarding
- Added "mock" provider to factory for CLI default

All 101 tests pass.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-01 22:34:00 +00:00

1.5 KiB

Contract: RoutingPolicy

layer: Functional
maturity: Beta
module: llm_connect.routing
since: WP-0003

Purpose

Route logical task types to concrete LLMAdapter instances based on a prioritised rule list, with optional per-rule cost-cap fallback.

Public surface

@dataclass
class RoutingRule:
    task_type: str
    prefer: LLMAdapter
    max_cost_per_1k: Optional[float] = None   # USD per 1 000 tokens
    fallback: Optional[LLMAdapter] = None

@dataclass
class RoutingPolicy:
    rules: List[RoutingRule] = field(default_factory=list)
    default: Optional[LLMAdapter] = None

    def resolve(
        self,
        task_type: str,
        estimated_cost_per_1k: Optional[float] = None,
    ) -> LLMAdapter: ...

Invariants

  1. Rules are evaluated in list order; the first rule whose task_type matches wins.
  2. When estimated_cost_per_1k is supplied and a matching rule has max_cost_per_1k set:
    • If estimated_cost_per_1k > max_cost_per_1k and fallback is not None → return fallback.
    • Otherwise → return prefer (no fallback configured or cost within cap).
  3. When no rule matches and default is not None → return default.
  4. When no rule matches and default is None → raise LookupError.
  5. resolve() never mutates policy state.

Error contract

Condition Exception
No matching rule, no default LookupError

Known consumers

  • inter-hub (IHUB-WP-0012 Phase 11): uses RoutingPolicy to select federation adapters per task class.