Typesafe system one models and new /v1/decisions endpoint
Akshay Deo
Sep 23, 2026 · 7 min read

Bifrost now supports TypeSafe's jev judgment models behind a unified POST /v1/decisions endpoint and a 1:1 /typesafe drop-in for TypeSafe's official SDKs. This is available in v2.2.2 for both OSS and Enterprise.
TypeSafe's jev family takes a piece of state - a support ticket, a model's answer, a review, any string or JSON blob - and returns calibrated judgments: a probability, a pick from your options, or a rubric score, each with confidence and a full probability distribution. That makes them a natural fit for the decision points scattered through every AI product: content moderation, ticket routing, eval-in-the-loop grading of LLM outputs, churn and escalation triage, guardrail checks. Anywhere you force a chat model to answer "just say yes or no", a judgment model does it faster, cheaper, and with a number you can actually threshold on.
TypeSafe support, two ways in
Bifrost now supports TypeSafe's System One models (jev-1.13.0, jev-latest, jev-preview) as a first-class provider, with a new operation type built for judgment workloads.
POST /v1/decisions is the unified Bifrost format. Send state plus a map of named questions - noul for probabilities, choice for classifications, score for rubrics - and get one typed answer per question, with confidence, probabilities, and legend metadata normalized into a single value field. Model routing, virtual keys, governance, logging, and cost tracking all apply, and every request is strictly validated before it costs you anything.
The /typesafe integration is the 1:1 drop-in. If you already use TypeSafe's Python or JavaScript SDK, point TYPESAFE_BASE_URL at your Bifrost deployment's /typesafe prefix and you are done - one environment variable, zero code changes. Native request and response shapes are preserved byte-for-byte on the success path, and Bifrost adds what upstream does not have, including a models endpoint and automatic retries on rate limits and overloads.
LLM fallbacks
If jev is down or for some reason API calls fail - we have added support for LLM fallbacks on both /v1/decisions and /typesafe/v1/systemone endpoint.
How it maps to a normal fallback call
A decision request already carries a fallbacks list, exactly like chat and responses requests. The trick is what happens when a fallback provider has no native decision endpoint (only typesafe does today). Instead of returning "unsupported", Bifrost emulates the decision through that provider's Responses API:
- The decision dispatch calls
provider.Decision(...). - If the provider returns unsupported_operation (every non-typesafe provider), one shim at the dispatch layer takes over - no per-provider code.
- The shim rebuilds the question set as a single forced
emit_decisionfunction tool (tool_choice: "required"), sends it via provider.Responses, and maps the tool-call arguments back to the exact DecisionResponse shape - values, per-answer confidence, choice probabilities, and score legends.
Because emulation runs through the same fallback loop, both the primary path (name an LLM as the decision model) and the fallback path (LLM after jev fails) flow through that one shim.

A decision request already carries a fallbacks list, exactly like chat and responses requests. The trick is what happens when a fallback provider has no native decision endpoint (only typesafe does today). Instead of returning "unsupported", Bifrost emulates the decision through that provider's Responses API:
- The decision dispatch calls
provider.Decision(...). - If the provider returns
unsupported_operation(every non-typesafe provider), one shim at the dispatch layer takes over - no per-provider code. - The shim rebuilds the question set as a single forced
emit_decisionfunction tool (tool_choice: "required"), sends it viaprovider.Responses, and maps the tool-call arguments back to the exact DecisionResponse shape - values, per-answer confidence, choice probabilities, and score legends.
Because emulation runs through the same fallback loop, both the primary path (name an LLM as the decision model) and the fallback path (LLM after jev fails) flow through that one shim.
We did a 30 question benchmarking keeping jev as ground truth to ensure it doesn't impact the quality of the output. We have picked a few models in random order as an example : overall testsuite runs across 100+ models.
If jev is reachable, jev answers. If not, gpt-5.6-luna emulates the same decision and returns the identical response shape - the caller sees no difference beyond the resolved model name.
Client request (jev primary, gpt-5.6-luna as fallback)
jev is down, so the request falls to openai/gpt-5.6-luna
Bifrost catches the failure, moves to the fallback, and since openai has no native decision endpoint it emulates the decision through the provider's Responses API. This is the call it actually makes to gpt-5.6-luna:
gpt-5.6-luna is forced to call emit_decision, and Bifrost maps its tool-call arguments back to the standard decision shape.
Response the caller receives (identical shape to jev)
Benchmarking
Here are the results
| Combination | Score | Latency (ms) | Tokens | Status |
|---|---|---|---|---|
| typesafe/jev-1.13.0 | 30/30 | 920 | 2144 | REF |
| openai/gpt-5.6-luna | 30/30 | 6763 | 3534 | PASS |
| openai/gpt-5.6-terra | 30/30 | 11452 | 3596 | PASS |
| openai/gpt-5 | 30/30 | 25795 | 5901 | PASS |
| openai/gpt-5-mini | 29/30 | 36482 | 6487 | PASS |
| openai/gpt-4.1 | 30/30 | 3963 | 3336 | PASS |
| openai/gpt-4.1-mini | 29/30 | 13113 | 3365 | PASS |
| openai/gpt-4o | 30/30 | 7630 | 3470 | PASS |
| openai/gpt-4o-mini | 30/30 | 5852 | 3292 | PASS |
| anthropic/claude-opus-5 | 30/30 | 15667 | 8203 | PASS |
| anthropic/claude-sonnet-5 | 30/30 | 11768 | 8172 | PASS |
| anthropic/claude-fable-5-1 | 30/30 | 17789 | 8095 | PASS |
| anthropic/claude-haiku-4-5-20251001 | 30/30 | 7842 | 6784 | PASS |
| anthropic/claude-sonnet-4-5 | 30/30 | 16429 | 6784 | PASS |
| xai/grok-4.5 | 29/30 | 24335 | 6618 | PASS |
| xai/grok-4 | 30/30 | 11472 | 5958 | PASS |
| xai/grok-3 | 30/30 | 13600 | 5976 | PASS |
| xai/grok-3-mini | 29/30 | 12291 | 6147 | PASS |
| groq/openai/gpt-oss-120b | 30/30 | 4208 | 5194 | PASS |
| deepseek/deepseek-v4-pro | 30/30 | 10299 | 5841 | PASS |
| cohere/command-a-03-2025 | 30/30 | 9047 | 6487 | PASS |
| vertex/gemini-2.5-flash | 30/30 | 11127 | 1513 | PASS |
| vertex/claude-sonnet-4-6 | 30/30 | 16266 | 6477 | PASS |
| vertex/claude-opus-4-8 | 30/30 | 16091 | 8207 | PASS |
| gemini/gemini-2.5-flash | 30/30 | 9078 | 5307 | PASS |
| gemini/gemini-2.5-pro | 30/30 | 14811 | 5505 | PASS |
Try it
- Decisions quickstart - curl to first judgment in a minute
- API reference - full /v1/decisions and /typesafe/* schemas
- TypeSafe provider guide - complete field mapping to the native API
- TypeSafe - the jev models and System One