jarvis ask never routes: score_complexity() is used only for max_tokens, select_model() is never called
Description
jarvis ask never performs model routing. It computes a complexity score for every query and then uses that score only to size max_tokens -- the model and engine come from config or flags, and select_model() is never called anywhere in the path.
The result is that the documented local-first / cloud-escalation behaviour does not happen through the primary entry point. A trivial query and a hard reasoning query both run on whatever single model is configured.
Where
cli/ask.py:
from openjarvis.learning.routing.complexity import (
ComplexityResult,
adjust_tokens_for_model,
score_complexity,
)
complexity_result: ComplexityResult = score_complexity(query_text)
logger.debug(
"Complexity analysis: score=%.3f tier=%s suggested_max_tokens=%d",
complexity_result.score, complexity_result.tier,
complexity_result.suggested_max_tokens,
)
...
selection_model = model_name or config.intelligence.default_model or None
resolved = get_engine(config, effective_engine_key, model=selection_model)The score is logged at debug level and used for token budgeting. RouterPolicyRegistry, HeuristicRouter and select_model do not appear in this path.
Steps to Reproduce
- Configure a small local model and a larger cloud model.
jarvis ask "hi"jarvis ask "Prove that the sum of the first n odd integers equals n squared."- Both run on
intelligence.default_model. No escalation, no log line indicating a routing decision.
Expected Behavior
Per docs/architecture/learning.md, the Learning primitive "determines which model handles each query (router policies)". A user who configures [learning.routing] policy = "heuristic" would reasonably expect jarvis ask to honour it.
Actual Behavior
[learning.routing] has no effect on jarvis ask. Routing is configurable but inert.
Notes
The routing machinery itself works. Driving HeuristicRouter directly with a real two-model list produces correct decisions:
LOCAL llama3.2:3b <- "hi"
CLOUD <120b model> <- "Prove that the sum of the first n odd integers..."
CLOUD <120b model> <- "Write a Python function to parse nested JSON."So this is a wiring gap, not a logic defect. Two related issues compound it: #942 (cloud models cannot win _largest_model because parameter_count_b is 0.0), and the executor issue filed alongside this one (the router is constructed with a single-element model list).
Suggested fix
In ask.py, when config.learning.routing.policy is set, build the candidate list from the available engines' models, create the policy via RouterPolicyRegistry, and let it choose -- falling back to default_model when it returns nothing. Logging the chosen model and the reason would also make the behaviour observable, which it currently is not.
Version
1.0.4.dev210+gc1af3c94 -- Windows 11, Python 3.12.10, ollama + cloud engines
Found while setting up local-first routing with cloud escalation; investigated with Claude Code.
Source: open-jarvis/OpenJarvis