jevrecipes

Recipe catalog / model-route

Route a request to a model tier

Which of the described models should serve request, and how much reasoning effort does it need, decided in one call so a cheap model handles easy turns and a capable one handles hard turns?

An agent harness, gateway, or proxy chooses per request which LLM and thinking level to use, and you want that choice made in well under a second.

Explore this recipe interactively ยท Source and implementation guide

Use model-route in TypeScript

Install with npm install jev-recipes. Requires Node.js 22.9 or newer and ES modules. Set TYPESAFE_API_KEY in your server environment for live calls, which send input to TypeSafe and use API quota. See the installation guide.

import { modelRoute } from 'jev-recipes/model-route';

const result = await modelRoute({
  "request": "Rename the variable `usr` to `user` in src/session.ts and fix any references.",
  "models": [
    {
      "id": "fast",
      "text": "Small, cheap, fast model. Good for edits with one obvious approach, reformatting, short answers, and simple lookups. Weak at multi-step reasoning and subtle bugs."
    },
    {
      "id": "balanced",
      "text": "Mid-size model at moderate cost. Handles multi-file changes, explanations, and routine debugging. Occasionally misses subtle design issues."
    },
    {
      "id": "frontier",
      "text": "Largest, slowest, most expensive model. Best for architecture, security-sensitive code, ambiguous requirements, and hard debugging."
    }
  ],
  "context": "Coding agent inside a small TypeScript repository with tests.",
  "minConfidence": 0.8
});
console.log(result);

Input contract

FieldTypeNeeded
requeststringRequired
modelsarrayRequired
contextstringOptional
minConfidencenumberOptional
Full input and result schemas
{
  "input": {
    "$schema": "https://json-schema.org/draft/2020-12/schema",
    "type": "object",
    "properties": {
      "request": {
        "type": "string"
      },
      "models": {
        "minItems": 1,
        "maxItems": 50,
        "type": "array",
        "items": {
          "type": "object",
          "properties": {
            "id": {
              "type": "string"
            },
            "text": {
              "type": "string"
            }
          },
          "required": [
            "id",
            "text"
          ]
        }
      },
      "context": {
        "type": "string"
      },
      "minConfidence": {
        "type": "number",
        "minimum": 0,
        "maximum": 1
      }
    },
    "required": [
      "request",
      "models"
    ]
  },
  "result": {
    "$schema": "https://json-schema.org/draft/2020-12/schema",
    "type": "object",
    "properties": {
      "model": {
        "type": "string"
      },
      "usage": {
        "type": "object",
        "properties": {
          "input_tokens": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991
          },
          "output_tokens": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991
          }
        },
        "required": [
          "input_tokens",
          "output_tokens"
        ],
        "additionalProperties": false
      },
      "status": {
        "type": "string",
        "enum": [
          "ready",
          "review"
        ]
      },
      "verdict": {
        "type": "string",
        "enum": [
          "matched",
          "none",
          "ambiguous"
        ]
      },
      "selection": {
        "type": [
          "string",
          "null"
        ]
      },
      "suggestedSelection": {
        "type": [
          "string",
          "null"
        ]
      },
      "confidence": {
        "type": "number",
        "minimum": 0,
        "maximum": 1
      },
      "probabilities": {
        "type": "object",
        "properties": {
          "candidates": {
            "type": "object",
            "propertyNames": {
              "type": "string"
            },
            "additionalProperties": {
              "type": "number",
              "minimum": 0,
              "maximum": 1
            }
          },
          "none": {
            "type": "number",
            "minimum": 0,
            "maximum": 1
          },
          "ambiguous": {
            "type": "number",
            "minimum": 0,
            "maximum": 1
          }
        },
        "required": [
          "candidates",
          "none",
          "ambiguous"
        ],
        "additionalProperties": false
      },
      "effort": {
        "type": "string",
        "enum": [
          "low",
          "medium",
          "high"
        ]
      },
      "effortLevel": {
        "type": "integer",
        "minimum": 0,
        "maximum": 2
      },
      "effortScore": {
        "type": "number",
        "minimum": 0,
        "maximum": 2
      },
      "effortConfidence": {
        "type": "number",
        "minimum": 0,
        "maximum": 1
      },
      "effortProbabilities": {
        "type": "object",
        "propertyNames": {
          "type": "string"
        },
        "additionalProperties": {
          "type": "number",
          "minimum": 0,
          "maximum": 1
        }
      }
    },
    "required": [
      "model",
      "usage",
      "status",
      "verdict",
      "selection",
      "suggestedSelection",
      "confidence",
      "probabilities",
      "effort",
      "effortLevel",
      "effortScore",
      "effortConfidence",
      "effortProbabilities"
    ],
    "additionalProperties": false
  }
}

Saved example result

This hand-authored response demonstrates the contract. It is not a model accuracy measurement. Run it without an API key: npx jev-recipes demo model-route.

{
  "model": "demo-fixture",
  "usage": {
    "input_tokens": 0,
    "output_tokens": 0
  },
  "status": "ready",
  "verdict": "matched",
  "selection": "fast",
  "suggestedSelection": "fast",
  "confidence": 0.92,
  "probabilities": {
    "candidates": {
      "fast": 0.92,
      "balanced": 0.05,
      "frontier": 0.01
    },
    "none": 0.01,
    "ambiguous": 0.01
  },
  "effort": "low",
  "effortLevel": 0,
  "effortScore": 0.1,
  "effortConfidence": 0.9,
  "effortProbabilities": {
    "0": 0.9,
    "1": 0.1,
    "2": 0
  }
}

Evaluation evidence

Earlier-evaluator measurement

jev-1.13.0 / 2026-09-27 / 40 held-out cases

Scoring revision 1.

100%All-case accuracy
14Sent for review
0Failed calls / cases

26 ready decisions, with 100% accuracy among those decisions.

95% case-level interval: 91% to 100%. Related synthetic cases are correlated.

Measured on these synthetic cases

This measurement uses an earlier or unverified recipe or evaluator version. Rerun with the current recipe and evaluator before treating these numbers as current.

Use the evaluation guide to measure this decision on your own labeled cases.

Limitations

Related recipes