DecisionGator 🐊Your software probably needs this.
You're building an application. A user types, "Any chance I could come in next Tuesday?" Your software needs to make one simple decision: is this person asking for an appointment?
Do you really have to get an API key, ship their POTENTIALLY PRIVATE text across the internet to a company they've never heard of, and pay for an API call just to answer that? Or install Ollama, manage a separate runtime, and turn a simple question into an infrastructure project? And then, on top of all that, spend your afternoon begging for JSON?
User text: "Any chance I could come in next Tuesday?"
Is this user asking for an appointment?
Please return ONLY valid JSON: {"appointment_requested": true}
Use false if the answer is no. An actual boolean, not the string "false".
No explanation. No Markdown. No code fences. No extra keys.
Do not say "Certainly!"; just skip to the JSON.
Please. I have a family. Just valid JSON... I'm begging you.
You're thinking: "I wish I could just load a normal library and call a normal function."
Now you can.
from decisiongator import is_yes, choose
appointment_requested = is_yes(
"Any chance I could come in next Tuesday?",
"Is this person asking for an appointment?",
) # True
teams = ["support", "billing", "sales"]
team = teams[choose(
"Any chance I could get a discount if we buy 50 licenses?",
"Which team should handle this message?",
teams,
)] # "sales"
That's it. That's the whole product. A function that takes some text and a question, and returns a boolean, or picks one option from a list.
A software component. Not an AI.
Yes, there's a small trained model inside. It's so small and so thoroughly boxed in that you never have to think about it. There is no chat. No prompt. No agent. No "temperature." Nothing to talk to, nothing to coax, nothing to apologize to. You ship it inside your application and you call a function, the same way your grandfather used software components: a library, some arguments, a return value. The kind of thing people did in the 1990s, before every boolean needed a subscription.
No Ollama. No llama.cpp. No TensorFlow. No agent harness. No network. No API key. No bill. The whole thing runs on the CPU inside your own process, on the user's own machine. Their text never leaves it.
It's like a regex library
Every language has one. You hand it a pattern and some text, and you get back a boolean. Nobody runs a regex server. Nobody has a regex API key. Nobody thinks of it as AI. You just call it, thousands of times a second, and get on with your day.
DecisionGator is the same kind of thing, except the pattern is a question in plain English:
re.search(r"\b(appointment|come in|book|schedule)\b", text) # the old way
is_yes(text, "Is this person asking for an appointment?") # the new way
Reach for it on the day the regex stops working. Which, for human language input, is TODAY.
The other half of the brain
There is a famous set of experiments on people whose two brain hemispheres were surgically separated. Only one side can talk. The other side is silent, but it isn't stupid: ask it a question and it answers, correctly, by pointing. It just never explains itself. CGP Grey has a lovely video about it.
Large language models are the talking side. Wonderful at explaining, terrible at shutting up. DecisionGator is the silent side: it reads, it decides, it points at yes or no or one of your options, and it says nothing else. Give your code both halves and let each do what it's good at.
If you know JEV from TypeSafe AI, the brain under the hood is similar: a small classifier that takes some text and a question and returns a typed answer with a probability, instead of generating prose. But JEV is a paid API on somebody else's server. DecisionGator is a library file in your build. For a working programmer the two are as different as a web service and a function call: no account, no network, no bill, no one else's outage, and the model is yours to retrain.
In whatever language you already write
from decisiongator import is_yes
if is_yes(text, "Is the customer asking to cancel?"):
route_to_cancellations()
import org.decisiongator.Decisions;
if (Decisions.isYes(text, "Is the customer asking to cancel?")) {
routeToCancellations();
}
import { isYes } from "decisiongator";
if (await isYes(text, "Is the customer asking to cancel?")) {
routeToCancellations();
}
using DecisionGator;
if (Decisions.IsYes(text, "Is the customer asking to cancel?"))
RouteToCancellations();
#include "decisiongator.h"
uint8_t yes;
if (dg_is_yes(text, strlen(text), q, strlen(q), NULL, &yes) == DG_OK && yes)
route_to_cancellations();
// via the C interface; see examples/rust for the extern "C" block
match is_yes(text, "Is the customer asking to cancel?") {
Ok(true) => route_to_cancellations(),
Ok(false) => route_to_general(),
Err(e) => eprintln!("could not evaluate: {e}"),
}
import { isYes } from "decisiongator/web";
// Runs on the user's device. Their text never leaves the page.
if (await isYes(text, "Is the customer asking to cancel?")) {
showCancelButton();
}
// Go, Swift, Ruby, PHP, Zig, Kotlin/Native, Lua, ...: every one of them can
// call a plain C function. This is the whole interface:
dg_status dg_is_yes(const char *content, size_t content_bytes,
const char *question, size_t question_bytes,
const dg_criteria *criteria, uint8_t *out_yes);
It's fast, too. The first call loads the model and takes a moment; after that, a decision takes about half a second on a laptop CPU, with no network round trip to wait on. Same weights, same answers, on Apple silicon Macs, Windows, Linux, and in Chromium, Firefox, and WebKit. Want a probability instead of a boolean, so you can hold the uncertain ones for a human? Want to spell out what counts as yes and what counts as no? Want to pick between several options instead of two? All ordinary function arguments.
How it compares
Every row below can answer "is this person asking for an appointment?" The differences are the painful parts: what you have to set up, what shape the answer comes back in, and what you do when it's wrong.
| Setup | The answer comes back as | Offline | Wrong answer? | License | |
|---|---|---|---|---|---|
| DecisionGator | Add a library | A boolean | Yes | Add data, retrain | Apache-2.0 |
| Regex / keywords | None | A boolean, for the cases you thought of | Yes | Add a pattern, break another | Yours |
| LLM API | API key, billing, network | JSON, if you beg | No | Prompt harder and hope | Proprietary |
| Local LLM Ollama, llama.cpp | Runtime, model files, a GPU to wish for | JSON, if you beg | Yes | Prompt harder and hope | Varies |
| Jev TypeSafe AI | API key, waitlist, network | Typed answer with probability | No | Can't; it's hosted | Proprietary |
| Needle 3 Cactus | Python package or C library | JSON tool call | Yes, telemetry on by default | LoRA fine-tune | Apache-2.0 weights + restricted code |
| Zero-shot NLI model Hugging Face | PyTorch or ONNX, in Python | Logits you threshold | Yes | Write the training code | Varies |
Numbers come from each project's own published material as of September 2026 and will drift. Check the source before relying on any of them.
Regex and keyword matching is what most software actually does today, and it's the right tool until the day someone writes "no rush, but could I come in Tuesday?" Every fuzzy case becomes another pattern, and every new pattern breaks an old one. DecisionGator is for the decisions that were never really regular expressions.
A hosted LLM is the most flexible and the best on hard cases. It is also an API key, a bill, a network dependency, your users' text on someone else's server, and an afternoon of begging for JSON. That is the reason this project exists.
A local LLM through Ollama or llama.cpp removes the network and the bill and replaces them with a runtime to install, model files to manage, a GPU to wish for, and the same begging for JSON. It turns a simple question into an infrastructure project.
Jev is the closest in spirit: a purpose-built decision model that takes text plus a question and returns a typed answer with a probability, not prose. No begging. But it is a hosted API in early access behind a waitlist, at $0.042 per million input tokens and 70 to 500 milliseconds plus network per call. Your users' text leaves your machine every time, and you cannot retrain it.
Needle 3 is a remarkable piece of engineering aimed at a different job: tool calling, structured extraction, and embeddings on phones, wearables, and microcontrollers, in 8 to 29 MB. You can coax a classification out of it by defining one tool per label, but there is no is_yes(text, question), and it ships as a Python package or C library rather than ready-made Java, Node, browser, and Rust interfaces. Read the license twice: the weights and Python package are Apache-2.0, but the engine that runs them is free only for individuals, nonprofits, and companies under $2M in funding and revenue. Above that, you need a commercial license from Cactus Compute. The engine binary also has telemetry on by default.
A zero-shot NLI model is free and open, and a fine choice if you already live in Python with PyTorch installed and want to write the tokenization, prompting, thresholds, calibration, and packaging yourself. It is also what DecisionGator is built from, one layer down. DecisionGator is that work, done once, shipped as a component for seven languages.
What if it gives a wrong answer?
GREAT! 🐊
That means you can add training data, retrain the model yourself easily, right there in the project, and contribute your training data back so the whole world benefits.
A wrong answer from someone else's API is a dead end: you file a ticket and hope. A wrong answer here is an improvement you can make yourself. Write down the text, the question, and the right answer, add them to the training data, and retrain. The training data is plain text files in the repository, and the training recipe runs on an ordinary laptop. Keep the improved model for yourself, or send your examples back in a pull request and the next release gets better for everyone. No GPU, no machine-learning degree, no permission required.
Open weights. Open training data. Open recipes. Apache 2.0.
Get it on GitHub Try it in your browser
Clone it. Call it. Retrain it. Send us your examples. Or edit and run a live JavaScript example right here, with nothing leaving your device.