Skip to content

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-complexity
  • x-lunargate-complexity-score
  • x-lunargate-skill
  • x-lunargate-requires-tools when tools or tool_choice is 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 0 means "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