Skip to content

TypeSafe Classifier ​

Package: elsai-model  v2.1.3

Jev is TypeSafe’s System One classifier. One classify call answers typed questions about a state and returns probabilities. It does not generate chat text.

Installation ​

bash
pip install --extra-index-url https://core-packages.elsai.ai/root/elsai-model/ "elsai-model[typesafe]==2.1.3"

Requirements: Python >= 3.10

Create an API key in the TypeSafe console and export it:

bash
export TYPESAFE_API_KEY=sk-...

When client_args omits api_key, the SDK reads TYPESAFE_API_KEY.


TypeSafeClassifier ​

Classifies a state with the Jev model. The default model id is jev-latest. Pass model_id or set TYPESAFE_DEFAULT_MODEL to pin a version such as jev-1.13.0.

python
import os
from elsai_model.typesafe import TypeSafeClassifier

classifier = TypeSafeClassifier(
    model_id="jev-latest",
    client_args={"api_key": os.environ["TYPESAFE_API_KEY"]},
)

Constructor parameters:

ParameterDescription
model_idTypeSafe model id. Falls back to TYPESAFE_DEFAULT_MODEL, then jev-latest
client_argsForwarded to the TypeSafe clients (api_key, timeout, retry, base_url, and other SDK client options)

Methods:

MethodDescription
classify(state, questions, **kwargs)Evaluates questions against state and returns the SDK response
aclassify(state, questions, **kwargs)Async variant of classify
list_models(**kwargs)Returns the SDK model listing
close()Closes the synchronous client when this classifier created it
aclose()Closes the asynchronous client when this classifier created it

state may be text, a JSON object, or an array. A per-call model keyword overrides the client default. Rate limits and HTTP 529 are raised as ModelThrottledException.

Environment variables: TYPESAFE_API_KEY, TYPESAFE_DEFAULT_MODEL


Question types ​

Pass a map of question name to a Noul, Choice, or Score object. The same map can use plain dictionaries (type, instructions, criteria) instead of those objects. Every question is evaluated against the same state.

Noul ​

A yes-or-no question. The answer is a probability from 0 to 1 on response.nouls[name].noul. criteria is optional. Use it when you need a calibrated check, such as “does this need a human?” or “is this a billing request?”.

Choice ​

Picks one label from a fixed set. The answer includes choice, probabilities, and confidence on response.choices[name]. criteria is required: a map of label to description (None is allowed). Use it to route a request to a team, a tool, or a model.

Score ​

Places the state on an ordered rubric. The answer includes score, legend, probabilities, and confidence on response.scores[name]. criteria is required: an ordered list of 2–10 level descriptions. Use it for urgency, risk, or quality.


Example ​

This ticket is classified with all three question types in one call.

python
import os
from elsai_model.typesafe import Choice, Noul, Score, TypeSafeClassifier

classifier = TypeSafeClassifier(
    model_id="jev-latest",
    client_args={"api_key": os.environ["TYPESAFE_API_KEY"]},
)

response = classifier.classify(
    state="I was charged twice. Please fix this ASAP.",
    questions={
        "billing": Noul(
            instructions="Is this ticket about billing?",
            criteria={
                "true": "The request is about a charge, invoice, or refund",
                "false": "The request is not about billing",
            },
        ),
        "department": Choice(
            instructions="Which team should handle this?",
            criteria={
                "billing": "Payments, invoices, refunds",
                "technical": "Bugs, outages, integrations",
                "sales": None,
            },
        ),
        "urgency": Score(
            instructions="How urgent is this ticket?",
            criteria=["can wait", "this week", "today"],
        ),
    },
)

print(response.nouls["billing"].noul)
print(response.choices["department"].choice)
print(response.choices["department"].probabilities)
print(response.scores["urgency"].score)
print(response.scores["urgency"].legend)
classifier.close()

The same questions can be dictionaries. Objects and dictionaries can share one map.

python
response = classifier.classify(
    state={"message": "I was charged twice. Please fix this ASAP."},
    questions={
        "billing": {
            "type": "noul",
            "instructions": "Is this ticket about billing?",
            "criteria": {
                "true": "The request is about a charge, invoice, or refund",
                "false": "The request is not about billing",
            },
        },
        "department": {
            "type": "choice",
            "instructions": "Which team should handle this?",
            "criteria": {
                "billing": "Payments, invoices, refunds",
                "technical": "Bugs, outages, integrations",
                "sales": None,
            },
        },
        "urgency": {
            "type": "score",
            "instructions": "How urgent is this ticket?",
            "criteria": ["can wait", "this week", "today"],
        },
    },
)

List models ​

list_models returns the SDK listing for the account.

python
listing = classifier.list_models()
print(listing)
for model in listing.models:
    print(model.name, model.description)

Async ​

aclassify is the async form of classify. Close the client with aclose.

python
import asyncio
import os
from elsai_model.typesafe import Noul, TypeSafeClassifier

async def main() -> None:
    classifier = TypeSafeClassifier(
        model_id="jev-latest",
        client_args={"api_key": os.environ["TYPESAFE_API_KEY"]},
    )
    try:
        response = await classifier.aclassify(
            state="I was charged twice. Please fix this ASAP.",
            questions={
                "billing": Noul(instructions="Is this ticket about billing?"),
            },
        )
        print(response.nouls["billing"].noul)
    finally:
        await classifier.aclose()

asyncio.run(main())

Using Jev with AgentKit ​

Jev is not a replacement for LLM(...). Keep a normal chat model on the agent. Call TypeSafeClassifier from a hook when you want to route a request, skip or run the agent, or gate a side-effect tool. See TypeSafe Classifier.

Copyright © 2026 elsai foundry.