Skip to main content

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.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

thinair-2.4.0.tar.gz (243.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

thinair-2.4.0-py3-none-any.whl (165.9 kB view details)

Uploaded Python 3

File details

Details for the file thinair-2.4.0.tar.gz.

File metadata

  • Download URL: thinair-2.4.0.tar.gz
  • Upload date:
  • Size: 243.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.12.13

File hashes

Hashes for thinair-2.4.0.tar.gz
Algorithm Hash digest
SHA256 84d5ba9e4c5f989374ffec0ce223c375293ba35035281b36e85afa1ec7e2edb3
MD5 3f030f1a0a6659974df26b5524a34e5a
BLAKE2b-256 71ec3811af87d0835e77d8e83c5c75d0a4a72bc448e1d0e4de17444817b6433f

See more details on using hashes here.

File details

Details for the file thinair-2.4.0-py3-none-any.whl.

File metadata

  • Download URL: thinair-2.4.0-py3-none-any.whl
  • Upload date:
  • Size: 165.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.12.13

File hashes

Hashes for thinair-2.4.0-py3-none-any.whl
Algorithm Hash digest
SHA256 48b99ae7fee09a4684d25315a8b4e5cc3273800a060a00a28136684297403d09
MD5 cc57043338bca5877a5307d21cfe4dc7
BLAKE2b-256 188dc689e7bda47dad8094febd3c623f2493055cac23ee65e91a0eb191c5f89c

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

2.4.0 This release

2 files

2.3.2

2 files

2.3.0

2 files

2.2.0

2 files

2.1.0

2 files

2.0.0

2 files

0.4.0

2 files

0.2.0

2 files

0.1.1

2 files

0.1.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page