marfrit
|
3e57824684
|
router: classify_model heuristic + 31-case corpus (Phase 5 commit #1)
Phase 5 commit #1 per docs/PHASE5.md §11. Pure-Lua per-request model
routing — no IO, no LLM probe in v1.
router.classify_model(text, cfg) -> (model_name | nil, class_label):
1. classify_class(text) walks heuristics in priority order:
code class:
- triple-backtick fence anywhere
- "traceback" / "stacktrace" / "stack trace" (ci)
- "error:" / "exception:" in first 60 chars (ci)
- path-with-code-extension token (.py/.lua/.c/.js/.go/.rs/.cpp/.h/.ts)
- 5+ lines with indented content (looks like a paste)
reasoning class (requires text >= 15 chars to skip bare keywords):
- "explain" / "why " / "how does" / "compare" (ci)
- "?" + length > 100 chars
default class: everything else
2. Map class via cfg.routing.classes[class] → model name (or nil = keep current).
3. Return (model_name_or_nil, class_label).
ALWAYS evaluates regardless of cfg.routing.auto — caller (repl.ask_ai
in commit #3) gates on the flag. This separation lets `:route check`
introspect the heuristic even when routing is off (N1).
M._classify_class exposed for testing.
Test corpus (test_router_model.lua, 31 cases):
- 13 code-class positives (fence, traceback, paths, multi-line paste)
- 6 reasoning-class positives (explain/why/how does/compare/?+length)
- 8 default-class (short queries, bare keywords below 15-char threshold,
non-code paths like .md/.txt)
- 3 model-mapping cases (code→"deep", reasoning→"cloud", default→nil)
- 1 R-N2 default test: classes.reasoning=nil → reasoning text yields
nil model override (heuristic still fires, no swap)
- All 31 pass; 15-char threshold catches "how does ASLR work?" without
false-positive on bare "explain".
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
2026-05-13 11:17:22 +00:00 |
|