-
Notifications
You must be signed in to change notification settings - Fork 0
Smart Routing Jev Classifier
System One is a family of typed decision models. Instead of generating a text label that the gateway must parse, a System One endpoint returns typed Score and Choice answers with probability distributions and confidence. OBEY uses those answers to select a Fast, Balanced, or Powerful model tier before generating a response.
Two provider families are supported. They share one implementation and the same wire protocol, and differ only in defaults and in which confidence field gates the decision.
| Jev | Laya | |
|---|---|---|
| Vendor | TypeSafe AI | Convai Innovations |
classifier: value |
jev |
laya |
| Config block | smart_routing.jev |
smart_routing.laya |
Default base_url
|
https://api.typesafe.ai |
https://api.laya-ai.com |
Default timeout_ms
|
1000 | 800 |
Default min_confidence
|
0.60 | 0.55 |
| Gating confidence field | confidence |
answer_confidence, falling back to confidence when absent |
| Retried HTTP statuses | 429, 529 | 429, 529, 503 |
Model-id token for auto
|
jev |
laya |
Model when the endpoint has no /v1/models listing |
none (falls back to the classifier chain) | typed-decisions |
Only one family is active at a time, chosen by smart_routing.classifier. Everything below applies to both unless noted. Examples use jev:; swap in laya: for Laya.
The heuristic classifier is local, deterministic, and free. System One is useful when request complexity cannot be captured reliably by token counts and keywords alone:
- reasoning depth;
- tool-call coupling;
- synthesis across context;
- strict output-precision requirements;
- specialist code/math/domain load;
- ambiguity and underspecification.
All six dimensions and a task-type choice are evaluated in one System One call. The gateway normalizes and weights the dimensions in code, then applies the same existing decision engine, budgets, context filtering, tier specialization, and cascade behavior.
Jev (TypeSafe is the default endpoint):
smart_routing:
enabled: true
classifier: jev
jev:
api_key_env: JEV_API_KEY
base_url: https://api.typesafe.ai
model: autoLaya (Convai hosted endpoint):
smart_routing:
enabled: true
classifier: laya
laya:
api_key_env: LAYA_API_KEY
base_url: https://api.laya-ai.com
model: autoA key is required for the active family: set api_key_env (an environment variable name, or a literal value if no such variable exists) or api_key. Config validation rejects classifier: jev or classifier: laya without one. The same check applies to classifier values set in ab_test arms and model_group_overrides.
base_url is configurable, so any compatible endpoint can be used without changing the routing policy. For example, Jev through OpenRouter:
smart_routing:
enabled: true
classifier: jev
jev:
api_key_env: OPENROUTER_API_KEY
base_url: https://openrouter.ai/api
model: autoThe endpoint must expose compatible POST /v1/systemone and GET /v1/models paths. TLS is required: https URLs are accepted, and plain http is accepted only for localhost and private-network addresses (for example a self-hosted laya-serve instance). URLs with a query string or fragment are rejected.
model: auto queries the configured endpoint's /v1/models listing, keeps ids containing a word-delimited family token (jev or laya, case-insensitive), and selects the newest version. Semantic version components compare numerically (1.13 is newer than 1.9). Discovery is cached for discovery_ttl_secs (default 600 seconds). The token match is word-delimited, so layabout or notjev do not qualify.
Pin a concrete model id when reproducibility matters more than automatic upgrades:
jev:
model: typesafe/jev-1.13.0laya:
model: typed-decisions # or: english, multilingualIf no family model is available, discovery fails, a pinned model is unavailable, or the endpoint times out, smart routing falls back to the existing classifier chain. The generation request itself does not fail. Missing-model warnings are rate-limited to once per discovery TTL window.
With model: auto and Laya, an endpoint that exposes no model listing is pinned to the typed-decisions checkpoint. A listing request that fails outright is still treated as a discovery failure and falls back.
The default policy trusts the classifier only when its least-confident complexity dimension meets min_confidence:
jev:
min_confidence: 0.60 # Laya default: 0.55
min_task_confidence: 0.50
fallback_policy: fallback-
fallback: uncertain classifications use the existing heuristic/ML/LLM fallback behavior. -
blend: uncertain scores blend with the heuristic score in proportion to confidence. - Low task-type confidence keeps heuristic task detection even when the complexity score is accepted.
For Laya the gate reads answer_confidence when the response includes it and uses confidence otherwise. For Jev it always reads confidence.
Thresholds are policy controls, not universal constants. Validate them on your own traffic before reducing cost through more aggressive Fast-tier selection.
Weights are finite, non-negative, and cannot all be zero. They do not need to sum to one; the gateway normalizes them. The default is equal weighting (1/6 each).
jev:
dimension_weights:
reasoning_depth: 0.30
tool_coupling: 0.20
context_synthesis: 0.15
output_precision: 0.15
domain_load: 0.15
ambiguity: 0.05- Timeout: 250-2000 ms per call; default 1000 ms (Jev) or 800 ms (Laya).
- Retries: at most two (
retry.max_attempts, 0-2) with exponential backoff (retry.backoff_ms, default 200). Jev retries HTTP 429 and 529; Laya also retries 503.Retry-Afteris honored within the remaining time budget. - No retry: 401, 403, or 422 (operator action is required). HTTP 413 is a non-retryable payload-limit error; the gateway halves
char_budget(down to 256) after a 413. - Response bodies are capped (16 KiB for evaluations, 512 KiB for model listings) and payloads are never logged.
- A 1000-entry, 5-minute SimHash cache avoids classifying identical requests repeatedly.
The gateway sends only the latest user message (or latest non-tool message), bounded by char_budget (default 1024, range 256-65536). Tool-result content is excluded. The API key is resolved from api_key_env and is redacted from debug output, logs, metrics, dashboard responses, and request records. Configure credentials through environment variables where possible.
When smart routing is enabled, /metrics exposes the following series. Both families share the same metric names (the jev in the name is historical) and are told apart by the family label (jev or laya).
| Metric | Labels |
|---|---|
obey_api_smart_routing_jev_consults_total |
group, family
|
obey_api_smart_routing_jev_fallbacks_total |
reason, family
|
obey_api_smart_routing_jev_confidence (histogram) |
family |
obey_api_smart_routing_jev_latency_ms (histogram) |
family |
obey_api_smart_routing_jev_discovery_refreshes_total |
status, family
|
Labels are bounded. family is normalized to jev or laya, reason and status come from fixed sets, and the group label is a hashed bucket (bucket_NN) rather than the raw model-group name. Prompts, API keys, and response content are never used as labels.
Upgrading from v0.6.6 or earlier: the confidence and latency histograms previously carried a constant classifier="jev" label; it is now family. The consults, fallbacks, and discovery-refresh counters gained a family label. Update any dashboards or alerts that match on classifier for these series.
The per-decision smart-routing metrics that carry a classifier label report Laya decisions as classifier="laya" (and Jev as classifier="jev").

The Admin Panel's Smart Routing tab has a classifier dropdown with Jev (System One) and Laya (System One) options, plus a Jev Classifier and a Laya Classifier section. Each section exposes every field for its family: base URL, model, API key / env name, timeout, minimum confidence, task confidence, low-confidence policy, state character budget, discovery TTL, retries, retry backoff, and the six dimension weights. The screenshot above shows the Jev section; the Laya section has the same layout with Laya defaults.
gateway_smart_routing response metadata includes optional classifier_confidence and resolved_model fields for System One decisions, and the classifier used is reported as jev or laya. The fields are omitted from other classifiers' decisions.
api_key is a startup-only input and is never written to disk in plaintext. When a key is saved through the Admin Panel, it is encrypted at rest (the same master-key encryption used for provider keys) and stored in api_key_encrypted under the family's block (jev or laya). The admin API never returns the stored key, and saving other settings without retyping it preserves the stored value. api_key_env remains the recommended setup: either an environment variable name or a literal that the admin save path will encrypt on first write.
Model groups can require stricter confidence than the global policy via model_group_overrides.<group>.jev_trust (min_confidence, min_task_confidence, fallback_policy). The override is applied to whichever family is active, so the same key works for both Jev and Laya. Overrides apply at classification time; credentials and endpoint settings stay global.
smart_routing:
classifier: laya
model_group_overrides:
premium:
jev_trust:
min_confidence: 0.75
min_task_confidence: 0.60
fallback_policy: fallbackA model group can also switch families with model_group_overrides.<group>.classifier: jev or laya, as long as that family has a key configured.