Routing & stickiness

How routsi picks a model per request, and how it keeps a conversation on one answerer.

Dynamic groups

a virtual model with levels
- name: dynamic-1
  type: dynamic
  levels:
    low: gpt-cheap
    medium: openai/gpt-4o-mini
    high: devin/claude-opus-4.8    # hard tasks → a real agent

Ask for dynamic-1 and routsi classifies the current turn and dispatches to the mapped member. Missing levels fall back to the nearest declared one. auto works the same way over the global tiers: map — see How auto decides for the exact classification rules.

Sticky, escalate-only

Conversation identity comes from (in order) the X-Conversation-Id header, a body conversation_id field, or a hash of the first user message. A pinned thread only ever moves up a tier — it never silently downgrades mid-conversation. Fingerprint ids (fp- prefix) are used for stickiness only, never to trigger proxy-managed memory.

Pins are scoped per group: convID#group. A thread pinned inside dynamic-1 doesn't affect its pin inside auto.

Next: Agents as models →