Free forever, no credit card.Get Started for Free →
← All posts
October 3, 2026 · 4 min read

Vilix AI x Jev Cookbook: Turn Fast Agent Judgments Into Durable Cross-Tool Memory

Judge once with Jev, store the judgment in Vilix AI over MCP, and never pay for the same agent decision twice. Full working Python pattern inside.

Vilix AI x Jev Cookbook: Turn Fast Agent Judgments Into Durable Cross-Tool Memory

Jev makes a judgment in 200 milliseconds and forgets it instantly. Vilix AI remembers everything across every tool you use. Put them together and you get this pattern: judge once with Jev, store the judgment in shared memory, and never pay for the same decision twice.

This cookbook shows the full working pattern in Python. It is aimed at operators running scheduled agents that triage, route, or score the same kinds of inputs every run.

What you need

  • A Jev API key. Jev is in early access at TypeSafe AI, and it is also served with no waitlist through Vercel AI Gateway and OpenRouter. The endpoint and model alias below come from the community API reference.
  • A Vilix AI API key. Create one in the Vilix AI dashboard, then send it as a Bearer header to https://api.vilix.ai/mcp. Headless agents (cron jobs, Hermes, OpenClaw) use this exact path.

The pattern in five steps

  1. Your scheduled agent gathers state: a ticket, a log line, a tool result.
  2. It checks Vilix AI memory first: was this already judged?
  3. If not, it asks Jev one or more typed questions about the state.
  4. It saves the judgment (state, question, answer, confidence) to Vilix AI.
  5. Every future run, in every tool, reads the stored judgment instead of re-judging.

The code

import json
import os
import requests

JEV_KEY = os.environ["JEV_API_KEY"]
VILIX_KEY = os.environ["VILIX_API_KEY"]
JEV_URL = "https://api.typesafe.ai/v1/systemone"   # model: "jev-latest"
VILIX_MCP = "https://api.vilix.ai/mcp"


def jev_judge(state, questions):
    """One parallel pass: every question answered with a calibrated confidence."""
    r = requests.post(
        JEV_URL,
        headers={"Authorization": f"Bearer {JEV_KEY}"},
        json={"model": "jev-latest", "state": state, "questions": questions},
        timeout=30,
    )
    r.raise_for_status()
    return r.json()


class VilixMemory:
    """Minimal MCP client: initialize once, then call tools."""

    def __init__(self):
        self.sid = None
        self._rpc("initialize", {
            "protocolVersion": "2024-11-05",
            "capabilities": {},
            "clientInfo": {"name": "jev-cookbook", "version": "1.0"},
        }, req_id=1)
        try:
            self._rpc("notifications/initialized", {}, req_id=None)
        except Exception:
            pass

    def _rpc(self, method, params, req_id=2):
        payload = {"jsonrpc": "2.0", "method": method, "params": params}
        if req_id is not None:
            payload["id"] = req_id
        headers = {
            "Content-Type": "application/json",
            "Accept": "application/json, text/event-stream",
            "Authorization": f"Bearer {VILIX_KEY}",
        }
        if self.sid:
            headers["Mcp-Session-Id"] = self.sid
        r = requests.post(VILIX_MCP, headers=headers, json=payload, timeout=30)
        r.raise_for_status()
        self.sid = r.headers.get("Mcp-Session-Id", self.sid)
        try:
            return r.json()
        except Exception:
            for line in r.text.splitlines():  # SSE fallback
                line = line.strip()
                if line.startswith("data:"):
                    d = line[5:].strip()
                    if d != "[DONE]":
                        return json.loads(d)

    def save_turn(self, user_message, assistant_message, chat_id="jev-judgments"):
        return self._rpc("tools/call", {"name": "save_turn", "arguments": {
            "user_message": user_message,
            "assistant_message": assistant_message,
            "chat_id": chat_id,
        }}, req_id=3)

    def get_context(self, user_prompt):
        return self._rpc("tools/call", {"name": "get_context", "arguments": {
            "user_prompt": user_prompt,
        }}, req_id=4)


def triage_ticket(ticket_text):
    mem = VilixMemory()

    # 1. Memory first: was this already judged?
    seen = mem.get_context(
        f"Have we triaged this ticket before? {ticket_text[:200]}")

    # 2. Fresh judgment from Jev (one parallel pass, ~200ms)
    judgment = jev_judge(
        state=ticket_text,
        questions={
            "team": {"type": "choice",
                     "options": ["billing", "support", "sales", "spam"]},
            "urgent": {"type": "noul",
                       "statement": "This ticket needs a human today"},
            "priority": {"type": "score",
                         "description": "How important is this ticket, 0 to 100"},
        },
    )

    # 3. Store it where every tool can read it
    mem.save_turn(
        user_message=f"Triaged ticket: {ticket_text[:300]}",
        assistant_message=(
            f"Jev judgment: {json.dumps(judgment)}. "
            "Treat as decided unless the ticket text changes."),
    )
    return judgment, seen

Two honesty notes. First, the Jev question schema above follows TypeSafe's documented shape (endpoint POST /v1/systemone, model / state / questions map, Choice / Score / Noul types); check their docs for the latest field names, since the API is still in early access. Second, the Vilix AI half is exact: MCP JSON-RPC with an initialize handshake, Mcp-Session-Id header, and tools/call for save_turn and get_context.

Why this beats re-judging every run

  • Cost. At $0.042 per million input tokens with free output tokens, roughly $1 covers tens of thousands of Jev judgments. A memory lookup on top of that costs nothing extra, and it lets you skip the judgment entirely next time.
  • Speed. A get_context check for an already-decided ticket is faster than even a 200ms Jev call.
  • Consistency. The same ticket gets the same answer in every tool, because there is one shared memory. If you ever correct a judgment, the latest write wins, so the fix propagates everywhere instantly.

Reading it back in any tool

Connect Claude, Codex, Cursor, OpenClaw, or any MCP-compatible client to the same Vilix AI account and call get_context at the start of the run. Past judgments arrive as context automatically. Vilix AI stores full conversation history, not just the label, so the reasoning behind a judgment survives too. And when a judgment graduates into a lasting lesson, save it as a reusable skill or rule once, and every agent follows it from then on.

Jev is the fast gut. Vilix AI is the long memory. Wire them together and your agents stop paying for the same decision twice.

Get Started for Free

Free forever, no credit card. Paid plans start at $10/mo, with a 7-day Pro trial that needs no credit card.

Get Started for Free

Persistent memory across ChatGPT, Claude, and the AI tools you already use in Vilix AI.

Get Started for Free

Free forever, no credit card.

Keep reading
ChatGPT's Agent Has No Memory on Purpose. Your Recurring Workflows Still Need One.

ChatGPT's Agent Has No Memory on Purpose. Your Recurring Workflows Still Need One. In July 2025, OpenAI launched ChatGPT Agent: a full virtual computer inside ChatGPT that browses the web, runs code in a terminal, edits spreadsheets, and chains multi-step tasks with minimal input. It is the closest thing to a digital employee that a chat product has shipped. It also remembers nothing between tasks. Run a competitor-research task on Monday and the same task again on Friday, and Friday's run has

Does Trigger.dev Remember Between Runs?

If you run scheduled AI work, you have probably looked at Trigger.dev. It is the background-jobs platform a lot of AI teams reach for: cron triggers, long-running tasks, durable execution, and now a whole AI chat stack with chat.agent. One question comes up constantly from automation operators: does Trigger.dev remember between runs? The short answer is layered: yes within a run, yes within a chat session, and no everywhere else. That last part is where scheduled agents quietly lose everything

Why Your AI Receptionist Keeps Double-Booking (and How Memory Fixes It)

Why Your AI Receptionist Keeps Double-Booking (and How Memory Fixes It) Picture a dental clinic running an AI receptionist on its phones. Monday morning, two patients call within five minutes of each other. Both need a cleaning, both want Wednesday at 4 PM, and both hear the same warm confirmation: "You're all set for Wednesday at 4." Wednesday arrives, two patients are in the waiting room, and there is one hygienist. The receptionist sounded flawless on both calls. It had no idea the other cal