From documents to decisions: making unstructured content programmable with Jev

|
Share

This was originally published by @olga_stefaniuk as an X article on September 18, 2026. View it here.

In Thinking, Fast and Slow, Daniel Kahneman describes two different modes of thinking. System 1 is fast, intuitive, and good at making an initial judgment. System 2 is slower, deliberate, and better suited to careful analysis. The distinction is useful beyond psychology, but it also gives us a way to think about how software uses AI.

So far, we’ve seen LLM-powered applications that often act as chat interfaces. This can be the right shape when we need open-ended reasoning. But workflows often need something smaller first: a fast judgment that can be inspected and used by code.

This is where Jev comes into play. Jev is TypeSafe’s flagship System One model, inspired by Kahneman’s distinction and built for fast, focused judgments that software can consume directly. As the overview page puts it: “Think of Jev as a frontier-intelligence function call: unstructured state in, typed probabilistic decisions out.” But there’s more to it. Jev gives up text generation in favor of type-safe outputs whose possible values are defined in advance. Each answer includes probabilities and confidence, allowing software to distinguish a clear judgment from an uncertain one. Because Jev is optimized for structured decisions and generates its outputs in parallel, it is designed to sit directly inside application logic: classifying, routing, scoring, extracting, verifying, or branching. 

Jev is not a general-purpose language model that generates a wall of text and leaves the application to parse it. You give it a piece of state and define the questions your application needs answered. In return you get typed values and probabilities. In this example, we pass a Box document Markdown representation from a PDF as state and structured instructions, and criteria within the QUESTIONS object:

response = typesafe.system_one(
    state={"document_markdown": source_text},
    questions=QUESTIONS,
)

There is no prompt-to-JSON step and no generated explanation to turn back into a programmatic value. Jev operates with three different primitives: a Choice which selects from known options, a Score which places the state on a defined scale and a Noul a boolean question with a probability score returned. With these outputs the application can then branch, route, rank, or ask a person to review the results.

Box Blog Image

In this demo example, we are routing an incident management document through the System One model, getting typed judgments from defined rules with Jev, based on criteria moving the file to one of three folders: Escalate, Monitor and Review. Critical data like Severity score, Escalation probability, and the Incident type are written to Box as metadata attached to the incident file. Finally, the script creates a task so the human can be notified and review the incident document in case it’s classified as escalation. Box becomes the versioned content interface, while Jev acts as a semantic decision layer.

Let’s look at the demo file, a multi-page incident review packet stored as a PDF in Box. It is a mix of an executive summary, a timeline, customer reports, operational notes, and an incomplete investigation. This document contains the information needed to trigger different operational workflows.The screenshot below shows the outcome of this workflow with values attached to the file. Let’s see how this works under the hood.

Box Blog Image

The document becomes a decision mechanism

The application asks Box for the PDF's Markdown representation with the Box Python SDK. That preserves the document's headings, tables, lists, and other formatting cues while giving Jev text it can evaluate. The application then sends that representation to Jev with three typed questions. Each question includes an instruction and detailed criteria.

QUESTIONS = {
    "incident_type": Choice(
        instructions="What is the primary type of incident described in the report?",
        criteria={...},
    ),
    "severity": Score(
        instructions="How severe is the incident based on its customer impact and unresolved risk?",
        criteria=[...],
    ),
    "needs_escalation": Noul(
        instructions="Does this report require immediate security, privacy, or executive escalation?",
        criteria={...},
    ),
}

The result returned by Jev is an instant set of signals:

incident_type: security_or_privacy
severity: 1.7
needs_escalation: 0.86

Now the application has information it can use for triage:

def decide(answers: dict) -> str:
    escalation_probability = answers["needs_escalation"].noul
    severity = answers["severity"]
    incident_type = answers["incident_type"]

    if escalation_probability >= 0.75:
        return "ESCALATE"
    if severity.score >= 1.0 or severity.confidence < 0.60 or incident_type.confidence < 0.60:
        return "REVIEW"
    return "MONITOR"

Jev handles the part ordinary code cannot handle well: interpreting messy human language at an incredible speed. The application handles the part that should remain explicit: policy, thresholds, routing, and permissions, whatever fits your use case and industry. See this in action:

The document participates in a fully customizable workflow without being a database record. This is especially useful for the long tail of operational content: the emails, notes, reports, and requests that contain important information but do not fit a rigid schema.

The entire integration is a compact loop: a document stored and versioned in Box, typed judgments from Jev, explicit application rules, and a clear escalation path. The demo is intentionally simple, but it can be extended with webhook triggers, Box Tasks, and additional custom application logic. The system routes the work while humans retain ownership of decisions with real consequences.

Want to try this yourself 

All you need to do is:

Box Blog Image

Next, activate the environment and copy the .env example file:

cd jev-incident-triage
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
cp .env.example .env

Next, run the set up script which creates a predefined metadata template for you:

python incident_triage.py --setup-template

Add the following values; you can get the developer token from Box Developer Console. See this guide for locating the user IDs if you want to run the script with the optional create review task flag.

# shorted lived token can be found in Box Developer Console
BOX_DEVELOPER_TOKEN=your_box_developer_token

# entry point for you incident reports
BOX_FOLDER_ID=your_box_folder_id

# incident report file
BOX_FILE_ID=your_box_file_id

BOX_ESCALATE_FOLDER_ID=your_escalate_folder_id
BOX_MONITOR_FOLDER_ID=your_monitor_folder_id
BOX_REVIEW_FOLDER_ID=your_review_folder_id

BOX_METADATA_TEMPLATE_KEY=jevIncidentTriage

TYPESAFE_API_KEY=your_typesafe_api_key

# optional, can be found in Box Admin Console:
BOX_REVIEW_ASSIGNEE_ID=your_box_user_id
BOX_REVIEW_TASK_MESSAGE=Please review the incident triage and confirm the next action.

Now, you’re ready to kick off the incident report triage with this script. As mentioned, the create review task flag is optional:

python incident_triage.py --write-back --create-review-task

The result includes the response from Jev and action logs:

# Incident triage: incident-report.pdf

Decision: **ESCALATE**

| Signal | Result | Confidence / probability |
| --- | --- | --- |
| Incident type | `availability` | 0.81 confidence |
| Severity | `1.69` | 0.54 confidence |
| Needs escalation | `0.89` | probability of yes |

This is a triage signal for human follow-up, not a final security, legal, or customer-impact determination.

{
  "incident_type": {
    "type": "choice",
    "choice": "availability",
    "confidence": 0.81,
    "probabilities": {
      "availability": 0.86,
      "security_or_privacy": 0.12,
      "other": 0.0,
      "data_integrity": 0.02
    }
  },
  "severity": {
    "type": "score",
    "score": 1.69,
    "confidence": 0.54,
    "legend": {
      "0": "Limited impact with a clear workaround and no meaningful unresolved risk.",
      "1": "Multiple customers are affected, service is degraded, or the investigation is incomplete.",
      "2": "Broad customer impact, possible data exposure, material data loss, or an urgent unresolved risk."
    },
    "probabilities": {
      "0": 0.0,
      "1": 0.3,
      "2": 0.7
    }
  },
  "needs_escalation": {
    "type": "noul",
    "noul": 0.89
  }
}
Box metadata instance created on incident-report.pdf
Saved decision card to Box as incident-report-triage-20260918-091347.md
Moved incident-report.pdf to ESCALATE folder 419228423589
Created Box review task 43694785724 for escalate outcom

Upon a successful run, the incident file is moved to an appropriate folder, values and classification data are stored as metadata, and a task is created in case the document was classified as escalation. Run this script several times and see if results are consistent with your expectations. You might need to adjust the criteria and instructions passed to Jev to match for your use case.

Box Blog Image

That small loop is the point: Box keeps the document and its history, Jev turns unstructured content into typed probabilistic decisions, and your application turns those signals into smart if-statements with routing, review, and escalation logic that remains explicit and inspectable. Start with one workflow, evaluate it against real documents, and expand from there.