Jev examples
Runnable file: agentium-examples/models/jev-triage.ts. Guides: Jev as the model · Jev toolkit Jev does not write chat. It returns a label, a yes/no probability, or a score.npm install @typesafe-ai/sdk
export TYPESAFE_API_KEY="..."
1. Jev is the agent (run({ questions }))
import { Agent, choice, jev, noul, score } from "@agentium/core";
const agent = new Agent({
name: "ticket-triage",
model: jev("jev-latest"),
});
const questions = {
category: choice("What is this ticket about?", {
billing: "Charges, invoices, refunds",
technical: "Bugs, outages, API errors",
other: null,
}),
urgent: noul("Needs a reply in under 1 hour?"),
severity: score("Customer impact?", ["none", "low", "medium", "high", "critical"]),
};
const result = await agent.run("I was charged twice. Fix this ASAP.", { questions });
const a = JSON.parse(result.text);
console.log(a.category.choice); // "billing"
console.log(a.urgent.noul); // 0–1
console.log(Math.round(a.severity.score)); // 0-based level (API may return 2.46)
await agent.run(outageTicket, {
questions: {
page: noul("Should we page on-call right now?"),
scope: choice("What is down?", { api: "Public API", web: "Website", unknown: null }),
},
});
2. Several tickets
const tickets = [
"I was charged twice for last month. Please fix this ASAP.",
"The API returns 500 on /v1/shipments since 9am.",
"Where do I change the email on my account?",
];
for (const ticket of tickets) {
const result = await agent.run(ticket, { questions });
const a = JSON.parse(result.text);
console.log(ticket);
console.log(" ", a.category.choice, a.urgent.noul, a.severity.score);
}
TYPESAFE_API_KEY=... npx tsx models/jev-triage.ts
3. Branch in your code
const a = JSON.parse(result.text);
if (a.category.choice === "billing" && a.urgent.noul > 0.7) {
await slack.post("#billing-oncall", ticket);
} else if (a.severity.score >= 3) {
await jira.create({ priority: "high", body: ticket });
} else {
await queue.push(ticket);
}
4. Claude talks, Jev judges (toolkit)
import { Agent, anthropic } from "@agentium/core";
import { JevToolkit } from "@agentium/core/toolkits";
const agent = new Agent({
name: "support",
model: anthropic("claude-sonnet-4-6"),
instructions: `Help the user.
When you need a label, a yes/no, or a rating, call jev_choose / jev_noul / jev_score.
Prefer jev_ask when you need several judgments on the same text.`,
tools: [...new JevToolkit().getTools()],
});
await agent.run("I was charged twice. Fix this ASAP.");
5. Lock the questions in a pack
import { choice, noul, score } from "@agentium/core";
import { JevToolkit } from "@agentium/core/toolkits";
const jevTk = new JevToolkit({
packs: {
ticket: {
category: choice("What is this ticket about?", {
billing: "Charges, invoices, refunds",
technical: "Bugs, outages, API errors",
other: null,
}),
urgent: noul("Needs a reply in under 1 hour?"),
severity: score("Customer impact?", ["none", "low", "medium", "high", "critical"]),
},
},
});
const agent = new Agent({
name: "support",
model: anthropic("claude-sonnet-4-6"),
instructions: `Call jev_evaluate with pack "ticket" and the ticket text.
Then tell the human the category, urgency, and severity (0 = none).`,
tools: [...jevTk.getTools()],
});
await agent.run("I was charged twice. Fix this ASAP.");
6. Refund gate
const agent = new Agent({
name: "refunds",
model: anthropic("claude-sonnet-4-6"),
instructions: `Call jev_noul: "Does this describe a clear double charge we should refund?"
>= 0.85 → approve. 0.4–0.85 → ask for the invoice id. Below 0.4 → not a refund.`,
tools: [...new JevToolkit().getTools()],
});
await agent.run("You billed me twice for March on order #4412.");
7. Zod schema instead of questions
import { z } from "zod";
const agent = new Agent({
name: "triage",
model: jev("jev-latest"),
structuredOutput: z.object({
category: z.enum(["billing", "technical", "other"]).describe("Ticket topic"),
urgent: z.boolean().describe("Needs a reply in under an hour"),
severity: z.number().int().min(1).max(5).describe("Customer impact"),
}),
});
const result = await agent.run("I was charged twice.");
console.log(result.structured);
// { category: "billing", urgent: true, severity: 3 }
run({ questions }) if you want result.structured to parse. Per-run questions win and stay raw JSON.
8. Jev scores a chat agent (@agentium/eval)
The agent under test writes the reply. Jev only judges. Do not pass jev() to llmJudge.
Guide: Jev as an eval judge. File: eval/jev-judge.ts.
import { Agent, jev, noul, score } from "@agentium/core";
import { EvalSuite, custom, ConsoleReporter } from "@agentium/eval";
const judge = new Agent({ name: "jev-judge", model: jev("jev-latest") });
const suite = new EvalSuite({
name: "support quality",
agent: supportAgent,
cases: [{ name: "refund", input: "I was charged twice." }],
scorers: [
custom("faithful", async (input, output) => {
const result = await judge.run(
JSON.stringify({ ticket: input, reply: output.text }),
{
questions: {
faithful: noul("Does the reply stay true to the ticket — no fake systems or denials?"),
helpful: score("How useful is this reply?", [
"unhelpful",
"partial",
"useful",
"excellent",
]),
},
},
);
const a = JSON.parse(result.text);
return { score: a.faithful.noul, pass: a.faithful.noul >= 0.7, reason: `noul=${a.faithful.noul}` };
}),
],
});
await suite.run([new ConsoleReporter()]);
TYPESAFE_API_KEY=... npx tsx eval/jev-judge.ts