model_selection¶
The model_selection section enriches requests with synthetic headers that routing can match.
This is the core building block behind lunargate/auto.
Top-level fields¶
| Field | Type | Default | Notes |
|---|---|---|---|
enabled |
bool | false |
master switch |
override_user_model |
bool | false |
controls how aggressively the gateway can replace the user model with the resolved route model |
output_headers.complexity |
string | x-lunargate-complexity |
emitted complexity tier header |
output_headers.score |
string | x-lunargate-complexity-score |
emitted numeric score header |
output_headers.skill |
string | x-lunargate-skill |
emitted skill header |
Scoring fields¶
| Field | Default | Notes |
|---|---|---|
complexity_scoring.input_tokens_threshold |
2000 |
approximate token threshold based on user-char count |
weight_input_tokens |
2 |
token-length contribution |
weight_contains_code |
2 |
code-heavy prompt contribution |
weight_math_reasoning |
2 |
math/reasoning contribution |
weight_analysis_synthesis |
1 |
planning/analysis contribution |
weight_safety_sensitive |
2 |
safety-sensitive content contribution |
weight_tools |
2 |
tool/tool_choice contribution |
complexity_tiers.tier_01_max |
1 |
upper bound for 0-1 tier |
complexity_tiers.tier_23_max |
3 |
upper bound for 2-3 tier |
complexity_tiers.tier_45_max |
5 |
upper bound for 4-5 tier |
Example¶
model_selection:
enabled: true
override_user_model: false
output_headers:
complexity: "x-lunargate-complexity"
score: "x-lunargate-complexity-score"
skill: "x-lunargate-skill"
complexity_scoring:
input_tokens_threshold: 120
weight_input_tokens: 2
weight_contains_code: 2
weight_math_reasoning: 2
weight_analysis_synthesis: 2
weight_safety_sensitive: 1
weight_tools: 2
complexity_tiers:
tier_01_max: 1
tier_23_max: 3
tier_45_max: 5
skills:
- name: "planning"
regex_any:
- '(?i)\b(plan|rollout|migration|risk|strategy)\b'
What the selector emits¶
When enabled, the selector can add:
x-lunargate-complexityx-lunargate-complexity-scorex-lunargate-skillx-lunargate-requires-toolswhentoolsortool_choiceis present
Those headers are meant to be consumed by routing rules.
override_user_model¶
When false:
- explicit provider/model choices from the client still matter
- the selector mainly enriches headers for route matching
When true:
- the gateway is freer to replace the user model with the route-selected target model
Skills¶
skills is a list of named regex groups matched against user text.
The first matching rule wins. If no skill matches, the runtime uses default.
Important runtime nuance about weights¶
In the current implementation:
- a weight of
0means "use the built-in default weight" - a negative weight effectively disables that heuristic contribution
So if you truly want a scoring factor to contribute nothing, use a negative value, not 0.
Important runtime nuance about complexity.simple / complexity.complex¶
The config schema also includes a rule-based complexity section with simple and complex rules.
That logic exists in the code, but the current runtime always computes the numeric score/tier path first, so practical routing today should target the emitted tier headers like 0-1, 2-3, 4-5, and 6+.
Best companion pages¶
- Technique:
lunargate/autoand autorouting - Config reference:
routing - Example: Python
lunargate/autodemo