thinair
Python objects whose attributes are beliefs, not values.
from thinair import Thing, model, human
from thinair.validators import TokenSubsetBelief
class Invoice(Thing):
"""An invoice document to be understood."""
__beliefs__ = [model("deepseek-v4-flash"), human("jane"),
TokenSubsetBelief("source_text")]
source_text: str
total = Thing(float, extracted_from="source_text", range=(0, 1e6))
inv = Invoice(source_text=open("invoice.txt").read())
+inv.total # 1249.5 — the value
~inv.total # 0.93 — how sure the answer is
You declared total but never computed it. Reading it asks a model,
checks the answer against the source text, and hands back a value with
an honest probability.
Code the certain, believe the rest.
Write what you know
Anything you set yourself is certain, and nothing can change it:
inv.total = 1249.50 # yours: probability 1.0, final
Anything you leave blank is believed — even attributes you never declared:
inv.due_date # works anyway: proposed on first read,
# validated like everything else
Every answer carries its price
Three operators cover the whole surface:
| form | meaning |
|---|---|
+thing |
the value |
~thing |
the probability |
thing @ 0.9 |
confidence gate — below the bar turns falsy |
thing @ {"total": float} |
coerce to a schema |
blob @ Invoice |
revive a saved one |
Low confidence fails visibly instead of flowing onward:
guess = inv.total @ 0.9
if guess: # only runs when the answer clears the bar
pay(+guess)
Validators keep answers honest
A declaration attaches checks that can veto a bad answer — a number that isn't in the source text, a value out of range, a string outside an enum. Checks reject; they never inflate. The probability you get is always the answering belief's own.
priority = Thing(str, enum=["low", "normal", "high", "urgent"])
amount = Thing(float, extracted_from="source_text", range=(0, 10_000))
You can also declare expectations — a probability bar, a maximum disagreement — which never block a read but mark the record wherever they are missed:
total = Thing(float, p=0.9, deviation=0.1)
Methods nobody wrote
Calling an undefined method runs the model against a sealed snapshot of the object. Proposed changes are validated and land atomically — or not at all. A model can never mark anything certain.
summary = inv.summarize()
+summary, ~summary # a value and a probability, like every read
Everything is remembered
Every opinion — who said it, what it saw, what the validators thought —
lands in a durable store (.thinair/opinions.db, automatic; set
THINAIR_STORE=off to opt out). Run the same program again and settled
answers come back from the record at zero cost. Nothing you or your
code established is ever asked twice.
Inspect it like git
The record maps onto git so cleanly the CLI is a deliberate copy: commits are whatever changed the object, every entity is a branch, and changing the belief panel is itself a commit.
$ thinair log --oneline
40ea1fe90c0f (HEAD -> ticket-4417) [freeze] refund_amount = 89.9 (frozen)
918571d773f7 [settle] sentiment ⇒ "frustrated" (p 0.66 ±0.00)
b68dab468888 [assign] priority = "urgent" (frozen)
01c676a6af53 [settle] customer ⇒ "Anna Virtanen" (p 0.91 ±0.04)
$ thinair show HEAD # the whole object + a belief × attribute matrix
$ thinair blame ticket-4417
$ thinair diff 01c676...40ea1fe
$ thinair branch
Every believed value wears its trust signature: (p 0.91 ±0.04) —
the probability, and how far apart the beliefs that checked it landed.
Color says the rest at a glance: the number is green when everything on
record agrees and slides toward red when readings disagree; the parens
are green when every belief that could be asked has been.
Ask for second opinions
show displays a matrix of every belief against every attribute, with
? on each question nobody asked yet. One command asks them all:
$ thinair evaluate HEAD # consults models and validators against the
# record, fills the matrix, remembers forever
Evaluation is idempotent — re-running costs nothing — and agreement between independent beliefs is the strongest evidence this system offers.
Bring your own beliefs
A belief is just a class with a judge method. Register one and the
CLI can rebuild and consult it like the built-ins:
$ thinair belief add checks.py # lives in .thinair/beliefs/
$ thinair belief list
Models register the same way. A def file (MODEL = ModelDef(...))
teaches thinair a model's request shape — defaults, structured output
mode, quirks — and travels with the store:
$ thinair model add housemodel.py # lives in .thinair/models/
$ thinair model list
Built for agents
One command gives a coding agent everything: the measurement theory, the list of built-in checks, and a manual for this CLI.
$ thinair ground # pipe it into the agent's context
$ thinair --ai-readable log # the colors, stated as text
Install
pip install thinair
Point it at any OpenAI-compatible endpoint — local or hosted:
export THINAIR_MODEL=... # model name
export THINAIR_BASE_URL=... # e.g. http://127.0.0.1:8000/v1
export THINAIR_API_KEY=... # if the endpoint wants one
Python ≥ 3.11, zero runtime dependencies.
Learn more
SPEC.md— the contract: every guarantee, stated so it can be checked.thinair/GROUNDING.md— the measurement theory, written to be handed to an LLM.experiments/— a real, disclosed run: strategy, ledger, findings.
MIT licensed.
Metadata
Release files for thinair 2.4.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 |
|---|---|---|---|---|
| thinair-2.4.0.tar.gz | 243.2 kB | Without provenance | Details for thinair-2.4.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| thinair-2.4.0-py3-none-any.whl | Python 3 | none | any | Details for thinair-2.4.0-py3-none-any.whl |
Total release size: 409.1 kB
Release files / thinair-2.4.0.tar.gz
| Download URL | thinair-2.4.0.tar.gz |
|---|---|
| Size | 243.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
84d5ba9e4c5f989374ffec0ce223c375293ba35035281b36e85afa1ec7e2edb3
|
|
BLAKE2b-256 checksum How to use checksums |
71ec3811af87d0835e77d8e83c5c75d0a4a72bc448e1d0e4de17444817b6433f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.13
|
Release files / thinair-2.4.0-py3-none-any.whl
| Download URL | thinair-2.4.0-py3-none-any.whl |
|---|---|
| Size | 165.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
48b99ae7fee09a4684d25315a8b4e5cc3273800a060a00a28136684297403d09
|
|
BLAKE2b-256 checksum How to use checksums |
188dc689e7bda47dad8094febd3c623f2493055cac23ee65e91a0eb191c5f89c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.13
|
Security for thinair 2.4.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.