Jev Java SDK
September 19, 2026 ยท View on GitHub
Idiomatic Java 17+ client library for TypeSafe AI's Jev System One decision engine.
Installation
Maven
<dependency>
<groupId>io.github.olti1947</groupId>
<artifactId>jev-java</artifactId>
<version>2.0.0</version>
</dependency>
Gradle
implementation 'io.github.olti1947:jev-java:2.0.0'
Quick Start
JevClient jev = JevClient.create(System.getenv("TYPESAFE_API_KEY"));
JevResponse response = jev.evaluate(
"Cancel my subscription immediately!",
List.of(
new Choice("intent", "Select classification", List.of("billing", "support", "cancel")),
new Noul("is_angry", "Is the customer expressing anger?")
)
);
response.choice("intent").choice(); // "cancel"
response.choice("intent").probabilities(); // {billing=0.01, support=0.0, cancel=0.99}
response.noul("is_angry").noul(); // 0.79
response.noul("is_angry").isTrue(0.7); // true
Structured instructions and criteria
Everywhere a primitive takes a string, it also accepts a structured value. Plain strings keep working exactly as before; use structured values when you need to give Jev richer context. See the advanced primitives docs.
// Structured instructions: any map (question, focus, inspect, field, ...)
Noul invoiceCheck = Noul.builder("invoice_number_is_correct")
.instructions(Map.of(
"field", Map.of("name", "invoice_number", "type", "string"),
"extracted_value", "4471",
"question", "Does `extracted_value` match the `field` as it appears in `source_text`?"))
.build();
// Choice options with what / not_for / examples boundaries
Choice department = Choice.builder("department")
.instructions(Map.of("question", "Which team should handle this message?"))
.candidate("billing", Rubric.of("Charges, invoices, refunds", "I was charged twice")
.notFor("Order tracking or account access"))
.candidate("orders", "Order status, delivery, or returns") // strings still work
.candidate("other") // no description
.build();
// Score levels with a summary and signals (levels run low -> high)
Score prScope = Score.builder("pr_scope")
.instructions("How focused is this pull request on a single change?")
.addCriteriaLevel(ScoreLevel.of("One change, clearly stated", "A single fix or feature"))
.addCriteriaLevel(ScoreLevel.of("Several changes bundled together", "Two or more unrelated fixes"))
.build();
// Noul true / false boundaries
Noul credentials = Noul.builder("requests_credentials")
.instructions("Does the message ask for a sensitive credential?")
.criteria(
Rubric.of("Asks the recipient to send a password or one-time code", "Send us the 6-digit code"),
Rubric.of("No sensitive credential is requested", "Reset your password from settings"))
.build();
Rubric and ScoreLevel are typed helpers, but any Map/List works too, so
nested category maps and custom keys are supported. Constructors taking plain
strings (new Noul(name, "question"), new Score(name, "q", "low", "high")) are
unchanged.
Vercel AI Gateway
Jev is also available through the Vercel AI Gateway,
which is handy while direct TypeSafe API access is waitlisted. Use an AI Gateway
API key (vck_...) and enable gateway mode on the builder โ the rest of the API
is unchanged:
JevClient jev = JevClient.builder()
.apiKey(System.getenv("AI_GATEWAY_API_KEY"))
.vercelGateway()
.build();
Notes:
- The gateway model id defaults to
typesafe-ai/jevand can be overridden with.gatewayModel(...).