Python API
Creating a client
from pyjev import Jev
with Jev(model="jev-latest") as jev:
result = jev.choice("Route this ticket", state=ticket, choices=choices)
Jev delegates transport, retries, API semantics, and models to typesafe-sdk.
The context manager closes clients created by Jev.
Primitive operations
jev.noul(...)and itsjev.ask(...)alias returnNoulResult.jev.choice(...)accepts a mapping of labels to criteria or a sequence of labels.jev.score(...)accepts 2–10 ordered levels.
All validation happens before the SDK call. Results preserve uncertainty instead of collapsing to a scalar convenience value.
Named decisions
result = jev.decide("ticket-route", state=ticket, config="ops/.pyjev.toml")
Explicit call model overrides the decision model. Configuration discovery and schema rules are described in Named decisions.
Mixed questions
jev.run(state=..., questions=...) sends several SDK question objects in one request.
Named bundles provide the same pattern from .pyjev.toml and return BundleResult.
Compiling offline
from pyjev import compile_decision
compiled = compile_decision("ticket-route", state="Stripe checkout fails")
print(compiled.to_dict())
Compilation resolves and validates configuration without creating a client or reading credentials. It is useful for review, debugging, and agent tooling.
Injected clients
from typesafe_sdk import TypeSafeClient
from pyjev import Jev
client = TypeSafeClient(...)
jev = Jev(client=client)
# use jev
jev.close() # does not close caller-owned client
An injected client is caller-owned. Constructor options such as api_key, model, and
timeout cannot be combined with it.
Result objects
Use .value, .confidence, .probabilities, and .legend as applicable. Every result
also preserves model, usage, raw answer data, and request ID. NoulResult.value remains
the raw probability of true.
Async API
When the installed official SDK supports native async transport, AsyncJev exposes the
same primitive, named-decision, bundle, validation, model-precedence, and result semantics:
from pyjev import AsyncJev
async with AsyncJev() as jev:
result = await jev.choice("Route this ticket", state=ticket, choices=choices)
It uses AsyncTypeSafeClient directly and does not hide synchronous work in a thread pool.