Skip to content

About

OpenDecision is an open-source semantic decision engine like typesafe's jev.

Topics

Resources

Stars

58 stars

Watchers

0 watching

Forks

Repository files navigation

OpenDecision

Typed decisions for text, documents, and images.

Tests Version Python License Documentation

Documentation · Image examples · Get started · API · Examples

Send text, JSON, a document, or an image with typed questions. OpenDecision runs locally and returns structured answers.

OpenDecision provides:

  • Choice to select one option from a list.
  • Noul to score a statement or compare explicit true/false descriptions.
  • Score to place state on an ordered scale.
  • Relation to report supports, contradicts, unknown, or conflicted.
  • Document processing with evidence retrieval and source passages.
  • Image decisions with optional SigLIP2 support and the same typed questions.
  • A Python API, a FastAPI server, and a TypeSafe SDK compatible endpoint.

The default backend is MoritzLaurer/ModernBERT-large-zeroshot-v2.0. MoritzLaurer/deberta-v3-large-zeroshot-v2.0 is an optional model. Image decisions use google/siglip2-base-patch16-224. See model selection and evaluation for the measured tradeoffs.

OpenDecision is licensed under Apache 2.0.

Image examples

Wildlife alert

A bear in a wooded landscape

Question Answer
Is an animal visible? Yes
What kind of animal is visible? bear

Animal present and type bear returns sound_alarm.

API call: 318 ms for both questions.

Bin collection

An overflowing bin with litter on the floor

Question Answer
Is a bin visible? Yes
What condition is the bin in? overflowing
Is litter scattered on the floor? Yes

Bin present and condition overflowing returns request_collection.

API call: 234 ms for all three questions.

Fence repair

A damaged metal fence leaning into vegetation

Question Answer
Is a fence visible? Yes
What condition is the fence in? damaged

Fence present and condition damaged returns create_repair_task.

API call: 155 ms for both questions.

These are recorded SigLIP2 results. The actions are simulated. Call times are medians of five local HTTP requests on an Apple M3 with the models loaded. The rules use a yes/no threshold of 0.5 and require a winning Choice probability of at least 0.6.

More images and answers · Image API and setup · Run the demo

Text and document examples

Customer routing

I was charged twice and I need this fixed before my meeting this afternoon.

Question Answer
Which department should handle this? billing
Is this request urgent? Yes

API call: 231 ms for both questions, measured with the same method as the image examples.

Answer questions about data and documents

OpenDecision accepts plain text, JSON, or other Python values as state. The document API splits long documents, finds relevant passages, answers each question, and returns the passages used.

Insurance claim example

The sample claim contains a demand letter, policy facts, a police report, medical records, bills, and employer records.

Question Answer
Are the medical expenses documented? established
Is a serious injury documented? refuted
Is the rental need fully supported? unknown
Are documents still outstanding? established

The saved synthetic claim benchmark retrieves 17 required facts and matches 10 composed decisions. See the insurance claim benchmark.

GDPR example

The GDPR example uses a 54,171-character document split into 31 sections.

Question Answer
Must a personal data breach be reported within 72 hours? true
Must every organization appoint a Data Protection Officer? false
Can pre-ticked boxes count as valid consent? false
What is the maximum fine for serious infringements? EUR 20 million or 4% of worldwide turnover

The saved retrieval benchmark answers 9 of 10 questions correctly. See the questions and saved results.

Yes/no answer modes

POST /v1/documents/decide has one noul_mode setting:

Mode Result
binary Always chooses true or false.
three_way Returns supports, contradicts, or unknown.
both Runs both evaluations. This is the default.

In both mode, OpenDecision reports confirmed, tentative, or conflicted. A conflict has answer: null. Both score distributions remain in the response.

The noul_mode setting applies to document Noul questions.

Get started

OpenDecision requires Python 3.13 or later.

pip install OpenDecision

Or add it to a uv project:

uv add OpenDecision

Run a decision in Python:

from opendecision import OpenDecisionEngine

engine = OpenDecisionEngine()

result = engine.choice(
    state="The customer was charged twice for one subscription.",
    instructions="Which team should handle this request?",
    criteria={
        "billing": "Payments, invoices, refunds, and duplicate charges",
        "technical": "Software bugs and integration problems",
        "sales": "Pricing and new purchases",
    },
)

print(result["choice"])
# billing

Start the API:

opendecision serve

In a uv project, run uv run opendecision serve.

Open http://127.0.0.1:8000/docs to send requests from the interactive API page.

The model downloads from Hugging Face on first use.

For image support:

pip install 'OpenDecision[images]'
from PIL import Image, ImageOps
from opendecision import ImageDecisionEngine

engine = ImageDecisionEngine()
with Image.open("photo.jpg") as source:
    image = ImageOps.exif_transpose(source).convert("RGB")

result = engine.choice(
    state=image,
    instructions="What kind of animal is visible?",
    criteria={"cat": "A photo of a cat", "bear": "A photo of a bear"},
)
print(result["choice"])

The API accepts the same question types with an image state:

{
  "state": {"type": "image", "data": "BASE64_IMAGE_BYTES"},
  "questions": {
    "animal_type": {
      "type": "choice",
      "instructions": "What kind of animal is visible?",
      "criteria": {"cat": "A photo of a cat", "bear": "A photo of a bear"}
    }
  }
}

Images must be single-frame JPEG, PNG, or WebP, up to 10 MiB and 20 megapixels. The server loads SigLIP2 on the first valid image request.

Documentation

API surface

GET  /health
POST /v1/systemone
POST /v1/documents/decide
GET  /docs
GET  /openapi.json

POST /v1/systemone accepts the core TypeSafe request shape. A local OpenDecision server can be used as the base_url for compatible clients.

Current status

OpenDecision v0.2.0 is a developer preview.

Model scores are uncalibrated. Test captions and thresholds on your own images and documents. Counting and negated image captions produced errors in the sample tests.

About

OpenDecision is an open-source semantic decision engine like typesafe's jev.

Topics

Resources

Stars

58 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages