Deterministic strategy router instead of LLM-based routing
ADR-002: Deterministic strategy router instead of LLM-based routing
Status: Accepted Date: 2026-04-14 Deciders: Mishaal Murawala
Context
With two scheduling engines (Graph + Cal.com) and four possible outputs (Graph, Google Calendar, Cal.com, SES email), the system needs to decide which engine handles each request. The routing decision could be made by the LLM agent (letting Claude decide) or by deterministic code (domain matching).
Decision
We will use a deterministic strategy router (src/lib/scheduling/router.ts) that classifies attendees by email domain and routes to the appropriate engine without LLM involvement.
Consequences
Positive
- Zero latency for routing — no Bedrock call needed to decide which engine to use
- Predictable behavior — same inputs always produce same routing decision
- Testable with unit tests (9 tests, all deterministic)
- No token cost for routing decisions
- Per-tenant policy overrides via KV (
scheduling_policy:{tenant_id})
Negative
- Can’t handle ambiguous cases where the user’s intent matters more than domain (e.g., “I want to use Cal.com even though everyone is internal”)
- Requires explicit
requestTypeoverride for non-standard flows
Risks
- If a tenant has users on multiple domains (e.g., acquired company), the domain-matching heuristic may misclassify attendees. Mitigated by the
requestTypeoverride parameter.
Alternatives Considered
LLM-based routing (let Claude decide)
- Rejected because: adds 500-1000ms Bedrock latency to every scheduling request, unpredictable routing behavior, and the routing decision is actually trivial — it’s just domain matching. LLMs are for understanding natural language, not for if/else logic.
User-selected routing (ask the user every time)
- Rejected because: defeats the purpose of a conversational agent. Users shouldn’t need to know about scheduling engines.