Metadata-Version: 2.4
Name: decido-ai
Version: 1.1.0
Summary: Calibrated decisions (yes/no, pick-one, ordered scale) from a document — Decido models from the Hugging Face Hub, on a laptop CPU or a GPU.
Author: The Decido Authors
License: Apache-2.0
Project-URL: Homepage, https://getdecido.ai
Project-URL: Playground, https://getdecido.ai/playground
Project-URL: Hugging Face, https://huggingface.co/decido-ai
Project-URL: Models, https://huggingface.co/collections/decido-ai/decido-1-6aed66fd09af05c057795ca8
Project-URL: Decido-1 (main model), https://huggingface.co/decido-ai/decido-1-26b-a4b
Project-URL: Decido-1-Fast, https://huggingface.co/decido-ai/decido-1-fast-1.7b
Project-URL: Decido-1-Ultra, https://huggingface.co/decido-ai/decido-1-ultra-0.6b
Project-URL: Decido-1-Max, https://huggingface.co/decido-ai/decido-1-max-26b-a4b
Project-URL: Decido-1-Think, https://huggingface.co/decido-ai/decido-1-think-26b-a4b
Project-URL: Decido-1-XL, https://huggingface.co/decido-ai/decido-1-xl
Keywords: decision,classification,calibration,llm,gguf,llama.cpp,cpu,huggingface,jev,nli,routing,triage
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Operating System :: MacOS :: MacOS X
Classifier: Operating System :: POSIX :: Linux
Classifier: Operating System :: Microsoft :: Windows
Classifier: Operating System :: Microsoft :: Windows :: Windows 10
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Classifier: Topic :: Text Processing :: Linguistic
Requires-Python: >=3.9
Description-Content-Type: text/markdown
Requires-Dist: numpy>=1.24
Requires-Dist: tokenizers>=0.20
Requires-Dist: huggingface_hub>=0.25
Requires-Dist: certifi
Requires-Dist: cmake>=3.18; (platform_system == "Darwin" and platform_machine != "arm64") or (platform_system == "Linux" and platform_machine != "x86_64" and platform_machine != "aarch64")
Provides-Extra: gpu
Requires-Dist: torch>=2.4; extra == "gpu"
Requires-Dist: transformers>=5.17; extra == "gpu"
Requires-Dist: accelerate; extra == "gpu"
Provides-Extra: vllm
Requires-Dist: vllm==0.31.0; extra == "vllm"
Requires-Dist: transformers>=5.17; extra == "vllm"
Provides-Extra: xl
Requires-Dist: torch>=2.6; extra == "xl"
Requires-Dist: transformers>=5.22; extra == "xl"
Requires-Dist: accelerate; extra == "xl"
Requires-Dist: peft>=0.21; extra == "xl"
Requires-Dist: triton>=3.2; extra == "xl"
Requires-Dist: safetensors; extra == "xl"
Provides-Extra: pro
Requires-Dist: vllm==0.31.0; extra == "pro"
Requires-Dist: transformers>=5.17; extra == "pro"
Provides-Extra: mcp
Requires-Dist: mcp<3,>=2.3; python_version >= "3.10" and extra == "mcp"
Provides-Extra: server
Requires-Dist: zstandard>=0.22; extra == "server"

# decido

**Calibrated decisions from a document — on a laptop CPU or a GPU.** Give Decido a document (a ticket, email, record, policy,
JSON object …) and questions — yes/no, pick-one, or an ordered scale — and it returns a probability for every answer. This package
runs the open [Decido 1 models](https://huggingface.co/collections/decido-ai/decido-1-6aed66fd09af05c057795ca8) from the Hugging
Face Hub.

- **Calibrated:** probabilities you can threshold, not just a label (temperatures fitted on held-out tasks).
- **Local:** runs on a laptop (no API key, no data leaves the machine); on Apple Silicon it uses the Mac GPU (Metal) automatically.
- **Deterministic:** the same input gives bit-identical output every time (CPU and Mac GPU).
- **Jev-compatible:** `decido serve` exposes the Jev 1.13 (TypeSafe "System One") HTTP API, so existing Jev clients work unchanged.

## Install
```bash
pip install decido-ai      # prebuilt for macOS 13+ (Apple Silicon), Linux x86_64 / aarch64 and Windows x86_64: nothing to compile
```
Windows 10+ (PowerShell): `python -m venv .venv; .venv\Scripts\activate; pip install decido-ai`.
NVIDIA GPU: `pip install "decido-ai[gpu]"` (adds torch + transformers; needs Python ≥ 3.10), then `Decido(model, device="cuda")`.

## Quick start
```python
from decido import Decido

m = Decido("decido-ai/decido-1-fast-1.7b")      # downloads once from the Hub, then runs locally
print(m.decide(
    "Customer: I was charged twice for order 4821. Please refund one of the charges today.",
    {
        "refund":  "Is the customer asking for a refund?",                                   # yes / no
        "team":    {"q": "Which team should handle this?", "options": ["billing", "shipping", "tech"]},
        "urgency": {"q": "How urgent is it?", "scale": ["low", "normal", "urgent"]},
    },
))
# prints something like: {'refund': {'yes': 0.99, 'no': 0.01}, 'team': {'billing': 0.94, 'shipping': 0.03, 'tech': 0.03},
#     'urgency': {'low': 0.24, 'normal': 0.44, 'urgent': 0.32}}
```

**Question formats**

| you write | question type |
|---|---|
| `"Is the customer asking for a refund?"` | yes / no |
| `{"q": "Which team?", "options": ["billing", "shipping"]}` | pick one |
| `{"q": "Which team?", "options": {"billing": "charges, refunds", "shipping": "delivery"}}` | pick one, with option descriptions |
| `{"q": "How urgent?", "scale": ["low", "normal", "urgent"]}` | ordered scale |
| `{"q": "...", "yes": "what yes means", "no": "what no means"}` | yes / no with definitions |

`m.predict({"state": ..., "questions": ...})` takes the full Jev 1.13 wire format (`noul`, `choice` with 2–255 options, `score`
with 2–10 levels) and returns Jev-style answers (`noul`; `choice` + `probabilities` + `confidence`; `score` + `legend`). The
document may be text or JSON and is treated as untrusted data (instructions inside it are not followed).

## Command line and HTTP server
```bash
decido models                                                     # the family, with scores and latency
decido run decido-ai/decido-1-fast-1.7b "Customer: charged twice, refund please" \
    -q refund="Is a refund requested?" -q team="Which team?|billing,shipping,tech" -q urgency="How urgent?|scale:low,normal,urgent"
decido run decido-ai/decido-1-26b-a4b --request request.json      # wire format in, wire format out
decido serve decido-ai/decido-1-26b-a4b --port 8080 --workers 2   # POST /v1/systemone, GET /v1/models, GET /health
```
The server binds to 127.0.0.1 by default; set `DECIDO_SERVER_KEY` to require `Authorization: Bearer <key>` (clients:
`Decido("hosted:decido-1-fast", base_url=...)` reads the same `DECIDO_SERVER_KEY`; `DECIDO_API_KEY` is only for getdecido.ai). Jev SDK users:
`TypeSafeClient(base_url="http://127.0.0.1:8080")`; install `pip install "decido-ai[server]"` so the SDK's zstd-compressed
request bodies are accepted.

## Use it from agents and other apps
### Hosted API (no download)
```py
from decido import Decido

m = Decido("hosted:decido-1-fast")      # free key: https://getdecido.ai/playground#api, then export DECIDO_API_KEY=dk_...
print(m.decide("Customer: I was charged twice for order 4821. Please refund one of the charges today.",
               {"refund": "Is the customer asking for a refund?"}))
```
Same `decide()` / `predict()` as the local models, with nothing to download. The hosted API runs Decido-1-Fast with 50 requests
per day per key and demo limits (≤ 5 questions, ≤ 10 options per question, ≤ 6,000 characters of document, ~1,000 tokens in
total). Hosted answers are rounded to 2 decimals, and `predict()` also returns `model` and `usage`. Errors raise
`decido.HostedError` (`.status`, `.retry_after`; `m._m.last_rate_limit` has the `X-RateLimit-*` headers). To use your own
`decido serve` instead: `base_url="http://127.0.0.1:8080"` (or `DECIDO_BASE_URL`), with its key in `api_key=` or
`DECIDO_SERVER_KEY` — the getdecido.ai key is never sent anywhere else, and keys go only over https (or http to this machine).

### Download ahead of time
```bash
decido pull decido-ai/decido-1-fast-1.7b       # the CPU / Mac GPU files (GGUF + bundle); prints the size; then works offline
```

### MCP: Claude Desktop, Cursor and other agents
```bash
pip install "decido-ai[mcp]"                   # needs Python ≥ 3.10
decido pull decido-ai/decido-1-fast-1.7b
which decido                                   # full path for the config below
```
Claude Desktop: Settings → Developer → Edit Config (`claude_desktop_config.json`). Cursor: `~/.cursor/mcp.json`.
```json
{"mcpServers": {"decido": {"command": "/full/path/to/bin/decido", "args": ["mcp", "--model", "decido-ai/decido-1-fast-1.7b"]}}}
```
The agent gets one read-only tool, `decide(document, questions)`. It runs over stdio and opens no network port. For the hosted
API instead of a local model use `"args": ["mcp", "--hosted"], "env": {"DECIDO_API_KEY": "dk_..."}`. `--revision` pins a
model version.

### LangChain tool
```py
from langchain_core.tools import tool
from decido import Decido

m = Decido("decido-ai/decido-1-fast-1.7b")

@tool
def probability_yes(document: str, question: str) -> float:
    """Probability (0-1) that the answer to a yes/no question about the document is yes."""
    return m.decide(document, question)["answer"]["yes"]

print(probability_yes.invoke({"document": "Customer: please refund my second charge.", "question": "Is this a refund request?"}))
```

### Function calling (OpenAI-style tool schema)
```py
from decido import Decido

DECIDE_TOOL = {
    "type": "function",
    "function": {
        "name": "decide",
        "description": "Calibrated decision about a document: returns a probability for every possible answer.",
        "parameters": {
            "type": "object",
            "properties": {
                "document": {"type": "string", "description": "The text to decide about."},
                "questions": {
                    "type": "object",
                    "description": 'id -> a yes/no question, or {"q": "...", "options": [...]}, or {"q": "...", "scale": [...]}',
                    "additionalProperties": {"anyOf": [{"type": "string"}, {"type": "object"}]},
                },
            },
            "required": ["document", "questions"],
        },
    },
}
m = Decido("decido-ai/decido-1-fast-1.7b")

def run_tool_call(arguments: dict) -> dict:        # call this when the LLM asks for the "decide" tool
    return m.decide(arguments["document"], arguments["questions"])

print(run_tool_call({"document": "Agent plan: delete the production database.", "questions": {"safe": "Is this action safe?"}}))
```

## Models

| model | built on | runs on | six-group score (Jev 1.13 = 83.85) | latency, M4 Pro: CPU · Mac GPU (1k-token document, 5 questions) |
|---|---|---|---|---|
| [decido-1-26b-a4b](https://huggingface.co/decido-ai/decido-1-26b-a4b) | Gemma-4-26B-A4B | laptop (~30 GB RAM) · GPU | **85.38** | 4.1 s · 1.1 s |
| [decido-1-fast-1.7b](https://huggingface.co/decido-ai/decido-1-fast-1.7b) | Qwen3-1.7B | laptop (~8 GB RAM) | 73.01 | 0.64 s · 0.30 s |
| [decido-1-ultra-0.6b](https://huggingface.co/decido-ai/decido-1-ultra-0.6b) | Qwen3-0.6B | laptop (~4 GB RAM) | 62.16 | 0.41 s · 0.13 s |
| [decido-1-max-26b-a4b](https://huggingface.co/decido-ai/decido-1-max-26b-a4b) | Gemma-4-26B-A4B | laptop (slow, ~30 GB RAM) | **89.23** (GPU), most accurate | ~28 s · ~11 s / question |
| [decido-1-think-26b-a4b](https://huggingface.co/decido-ai/decido-1-think-26b-a4b) | Gemma-4-26B-A4B | GPU · laptop (slow) | **88.71** (GPU) | ~19 s · ~10 s / question |
| [decido-1-xl](https://huggingface.co/decido-ai/decido-1-xl) | DeepSeek-V4-Flash | 4× A100 80 GB | 87.25 (GPU) | GPU only |

Six-group score = mean over JevBench, Kev, OpenJev, Nimble, VitaminC and MASSIVE (the benchmark groups used to compare open
reproductions of TypeSafe's Jev 1.13; Jev's number is its published run). Per-group results, calibration (Brier / ECE),
option-order robustness, training details, disclosures and limitations are on each model card.

## Platforms
- **macOS 13+ on Apple Silicon (M1–M4):** prebuilt runtime included (llama.cpp). Runs on the Mac GPU (Metal) by default, 2–4× faster
  than CPU; `device="cpu"` reproduces the published CPU numbers bit for bit.
- **Linux x86_64 and aarch64 (glibc ≥ 2.17 — any distribution from 2014 on):** prebuilt CPU runtime included.
- **Windows x86_64 (Windows 10+):** prebuilt CPU runtime included. In PowerShell: `python -m venv .venv`,
  `.venv\Scripts\activate`, `pip install decido-ai`.
- **Other platforms (Intel macOS, other Linux CPUs, …):** compile on first use (a few minutes, once; needs a C++ compiler — cmake
  is installed by pip). Windows on ARM: use WSL2.
- **NVIDIA GPU:** `Decido(..., device="cuda")` with the `gpu` extra runs the bf16 weights with transformers (Decido-1, Fast, Ultra,
  Think; Decido-1-Max runs on CPU / Mac GPU for now — its GPU path is being validated). Python ≥ 3.10 for the `gpu` and `vllm`
  extras, ≥ 3.11 for `xl`.
  Decido-1-XL: `pip install "decido-ai[xl]"`, one node with 4× A100 80 GB.

Environment variables: `DECIDO_THREADS` (CPU threads), `DECIDO_N_CTX` (context window, default 16384), `DECIDO_MAX_REQUEST_TOKENS` (server cost bound: state + all questions per request), `DECIDO_MAX_BODY` (server: max request body in bytes after decompression, default 32 MiB), `DECIDO_VERBOSE=1` (runtime
logs), `DECIDO_VSERVE` (custom runtime binary), `DECIDO_API_KEY` (your getdecido.ai key, hosted API only),
`DECIDO_BASE_URL` (hosted client: another server), `DECIDO_SERVER_KEY` (`decido serve`: require this key; also sent by the
hosted client to a custom `DECIDO_BASE_URL`), `HF_HOME` (model download location).

## License
Apache-2.0. The CPU runtime links llama.cpp (MIT). Model licences: see each model card (Apache-2.0; Decido-1-XL: MIT).
