hybrid-model-routing
Summary
Section titled “Summary”A hybrid model-routing feature was added to the vir project’s distillation pipeline. It selects between a “smart” (distill) and “cheap” (distillFast) model based on content classification category and estimated token count. A security review confirmed no new vulnerabilities were introduced.
What Was Learned
Section titled “What Was Learned”Hybrid model routing pattern:
selectDistillModel(classification, inputTokens, models)picks model tier based on two signals: content category ("pattern","gotcha","decision","tool") and achars/4token heuristic on scrubbed content.- A
distillThresholdconfig field controls the token boundary between fast and smart tiers. Distiller.modelForplumbs routing through;--force-modelCLI flag short-circuits it entirely.Distiller.distill()accepts an optionalmodelparam, defaulting tothis.distillModel(smart model — safe default). The sole callerrun()always passes the routed model explicitly.
Config schema additions:
distillFastanddistillThresholdare optional fields in~/.vir/config.json.- CLI
initdefaultsdistillFastto Haiku for new installs.
Behavioral gotcha (re-init on existing installs):
- Re-running
initon an old install silently upgrades from “hybrid off” to “hybrid on with Haiku fast tier” viaexisting?.models?.distillFast ?? <default>. This contradicts the schema comment claiming existing installs keep usingdistillunchanged (that guarantee only holds vialoadConfig, notinit). A UX/doc inconsistency, not a security issue.
Security posture (confirmed clean):
- Model name strings flow from user-owned
~/.vir/config.json(0o600) →callKie/callAnthropicrequest body vianormalizeModelNamecanonicalization. Not attacker-controllable. - Classification
categoryis validated against a hard-codedCATEGORIESallowlist before reaching routing logic — junk LLM output is clamped to a wrong-tier pick at worst. - No shell, SQL, path traversal, eval, deserialization, SSRF, or template sinks touched by this change.
Context
Section titled “Context”- Project: vir
- Category: decision
- Date: 2026-05-29T14:44:41.573Z
Details
Section titled “Details”src/pipeline/distiller.ts—Distiller.modelFor,Distiller.distill,selectDistillModelsrc/config.ts— schema fordistillFast,distillThresholdsrc/cli.ts—initcommand defaultssrc/pipeline/run.ts— caller of routed model, prints tip line- Pattern: category-based routing with token-count threshold is reusable for any tiered LLM cost-optimization feature
Related
Section titled “Related”- cost-logging-architecture
- explicit-thinking-disable-on-model-upgrade
- auth-onboarding-routing
- v1-architecture-and-sequencing
- model-judge-human-mismatch