decisionsmith
Use and fine-tune System One models (Jev, Laya) on your data. Start with an LLM. End with a fast decision model you trained. One line in between.
uv add "decisionsmith[all]"
import decisionsmith as ds
h = ds.harness(Ticket, teacher="claude-sonnet-5", student="laya")
h("You charged me twice, refund now!")
# Ticket(team='billing', wants_refund=True)
That's it. Ticket is a normal Pydantic model:
from typing import Annotated, Literal
from pydantic import BaseModel, Field
import decisionsmith as ds
class Ticket(BaseModel):
team: Annotated[
Literal["billing", "technical", "sales"],
ds.Options(billing="payments, refunds", technical="bugs, outages", sales="pricing"),
]
wants_refund: bool = Field(description="Does the customer ask for their money back?")
Literal / Enum → pick one · bool → yes/no · Annotated[Literal["low", "medium", "high"], ds.Scale] → a rating.
Why
Decision models like Laya are fast and free to run, and weak zero-shot (0.36 accuracy on typed-decisions before fine-tuning, 0.77 after, per Laya's benchmarks). LLMs are good zero-shot, and slow and paid per call. decisionsmith starts with the LLM, logs every answer, fine-tunes the fast model on those answers, and moves traffic to it field by field once the numbers say it's ready.
So don't trust a System One model zero-shot on your task. Let a normal LLM make the decisions first (mode="teacher"
or "shadow"), behind the guardrails decisionsmith already has: answers validated against your schema, the text
fenced as data, a fallback when an engine fails, and a per-field confidence threshold plus a 5% audit before any
field moves to the student.
The loop
texts = open("texts.txt", encoding="utf-8").read().splitlines() # your texts, one per line
h = ds.harness(Ticket, teacher="claude-sonnet-5", student="laya", mode="shadow") # teacher answers, student measured
h.many(texts) # every decision is logged (decisions.db)
print(h.status()) # per field: agreement, sure rate, accuracy when sure, what to do next
h.adapt() # calibrate the student's confidence + pick safe thresholds (seconds, any engine)
h.finetune() # train Laya on the logged answers; switches only if it beats the current student
team: shadow · student agrees 94% · sure on 71% · accuracy when sure 97% (vs teacher) -> ready for cascade
wants_refund: shadow · student agrees 81% · 420 labelled -> ready to finetune: run h.finetune()
Then move a field when it's ready: mode={"team": "cascade", "wants_refund": "shadow"}.
Four modes, per field
| mode | who answers | use when |
|---|---|---|
teacher |
the LLM | day 0 |
shadow |
the LLM; the student runs silently and is measured | measuring the student |
cascade (default) |
the student when it's sure, else the LLM (5% of sure answers are audited) | student proven on some fields |
student |
the student | student proven everywhere |
If an engine fails, the other one answers and the result says sure=False. Nothing crashes in the middle.
Connect anything
| engine | string | notes |
|---|---|---|
| Any LLM | "claude-sonnet-5", "gpt-5", "ollama/qwen3" … |
via LiteLLM |
| Jev (TypeSafe) | "jev" |
hosted, needs TYPESAFE_API_KEY; can be adapted, not fine-tuned |
| Laya (local) | "laya", "laya:multilingual", "laya:./runs/v1" |
runs on your machine |
| Laya server / laya.cpp | "systemone:http://localhost:8000" |
any Jev-compatible /v1/systemone endpoint |
Any engine can be the teacher or the student.
Fine-tune with labels you already have
decisionsmith finetune tickets.csv --schema app.py:Ticket --out runs/v1
A CSV needs a text column and one column per field. Small data (under 1,000 rows) trains only the decision
head, fast even on a laptop; bigger data trains the whole model (use a GPU, or the Kaggle/Colab notebook in
examples/). You get runs/v1/: a plain Laya checkpoint (laya.load("runs/v1") works), a report comparing it
with the base model on held-out data, and a go/no-go verdict with the reasons.
Or from Python, and keep the result as a versioned folder you can load anywhere:
model = ds.model(["billing", "technical", "sales"])
model.train("tickets.csv")
print(model.evaluate("test.csv")) # held-out numbers and go/no-go
m = ds.load(model.save("models/ticket")) # models/ticket-v1
In production, ds.harness(m, teacher=llm, collect=0.1) keeps a sample of real texts, and
ds.golden("decisions.db", teacher=llm, schema=labels) turns them into the next labelled dataset
(golden, collect).
Compare engines on your data
decisionsmith bench tickets.csv --schema app.py:Ticket --engines claude-sonnet-5,jev,laya,laya:./runs/v1
From agents
uvx --from "decisionsmith[all]" decisionsmith mcp gives Claude Code, Codex, Cursor and other MCP clients the
harness, bench, status, finetune and label as tools. There's also a Claude Code plugin; see
docs/agents.md.
Docs
Quickstart · Fine-tuning · Guide: engines, modes, status, adapt, bench · FAQ · Integrations
Runnable examples (gallery, every one runs offline) and notebooks.
Built on Laya (Apache-2.0) by Nandakishor M / Convai Innovations. Jev and TypeSafe are trademarks of their owners; decisionsmith is an independent project, not affiliated with TypeSafe AI or Convai Innovations.
Metadata
Release files for decisionsmith 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| decisionsmith-0.1.0.tar.gz | 93.4 kB | Without provenance | Details for decisionsmith-0.1.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| decisionsmith-0.1.0-py3-none-any.whl | Python 3 | none | any | Details for decisionsmith-0.1.0-py3-none-any.whl |
Total release size: 219.1 kB
Release files / decisionsmith-0.1.0.tar.gz
| Download URL | decisionsmith-0.1.0.tar.gz |
|---|---|
| Size | 93.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
d1576904057d069f8453e3c2c5001a76508ac8fc483885a1b2779a7ca5c9b7e1
|
|
BLAKE2b-256 checksum How to use checksums |
2f513836eb52fadd55b18151213b75b97635dc3435db4dd45e7692d97014cffe
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.19 {"installer":{"name":"uv","version":"0.12.19","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / decisionsmith-0.1.0-py3-none-any.whl
| Download URL | decisionsmith-0.1.0-py3-none-any.whl |
|---|---|
| Size | 125.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
0b039254e496d86bf484661d769a66a164cfb97825396f5cfa26fcca7374a2b3
|
|
BLAKE2b-256 checksum How to use checksums |
23f4685e75b312a1e750d85e3fa775b73407cc454a1fa4f2ec8b235e42701e18
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.19 {"installer":{"name":"uv","version":"0.12.19","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Security for decisionsmith 0.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.