thunc()
Docs · thunc 0.2

Get started

thunc turns a Python function signature into an LLM call. The docstring is the prompt, the parameters are the inputs, and the return annotation is the type you get back, checked. This page takes you from install to a first answer in about a minute.

Install

thunc uses the standard library only and needs Python 3.10 or later.

pip install thunc

Provider SDKs are optional extras. Install the one for the backend you use:

pip install thunc               # Claude Code, Codex and Jev need nothing more
pip install "thunc[anthropic]"  # adds the Claude API backend
pip install "thunc[openai]"     # adds the OpenAI API backend, also used for local models
pip install "thunc[temporal]"   # adds durable agents on Temporal
pip install "thunc[watch]"      # adds thunc watch, a live dashboard in the terminal

Pick a backend

thunc runs on whatever you already have. No API key is needed if Claude Code or Codex is installed and logged in: thunc calls the CLI with your login.

You haveSetInstall
Claude Code, logged inTHUNC_BACKEND=claude-codepip install thunc
Codex, logged inTHUNC_BACKEND=codexpip install thunc
An Anthropic API keyANTHROPIC_API_KEYpip install "thunc[anthropic]"
An OpenAI API keyOPENAI_API_KEYpip install "thunc[openai]"
A local model (LM Studio)OPENAI_BASE_URL, see local modelspip install "thunc[openai]"

With an API key set, thunc picks that backend on its own. In code, thunc.configure(backend="...") does the same as THUNC_BACKEND. Backends covers each one.

Your first call

One line, through your Claude Code login. Swap the backend for the one you picked.

THUNC_BACKEND=claude-code python3 -c 'import thunc; print(thunc.call("Say hello in five words or fewer."))'

It prints something like Hello there, nice to meet you! A call takes a few seconds.

Your first function

Write a function with a docstring and a return type, and leave the body as .... Calling it asks the model and hands back a value of that type.

import thunc

thunc.configure(backend="claude-code")  # or "codex", "anthropic", "openai"


@thunc.function
def urgency(ticket: str) -> int:
    """Rate how urgent this ticket is, from 1 (can wait) to 5 (customer is blocked)."""
    ...


print(urgency("I was charged twice!"))  # 4

The answer is parsed into the declared type. If it doesn't fit, the model is asked again with the problem, and after that thunc.ThuncError is raised, so you never get a silent bad value. Functions and prompts covers the return types, retries and your own checks.

Beta (v0.2). The API may still change. Bug reports and feedback are welcome in issues or discussions.

Run the examples

Clone the repository and run the examples from its root. Most need no install and run through your Claude Code login; the Jev ones need the jev CLI, and temporal/ a Temporal service.

git clone https://github.com/Eltarras/thunc && cd thunc
python3 -m examples.hello
python3 -m examples.support_inbox
THUNC_BACKEND=codex python3 -m examples.log_triage
ExampleWhat it shows
hello.pyThe smallest call
support_inbox.pyDocstring functions returning a Literal, an int with ensure=, a dataclass and a reply; tickets processed in parallel
dynamic_prompts.pyPrompts built from a style guide with thunc.call, and a grading function generated from a rubric
log_triage.pyPlain Python and AI functions mixed, with tracing
repo_guide.pyAgents: read-only tasks over this repo returning a dataclass and lists, on Codex by default, with each run's steps read from the trace
jev_hello.pyThe smallest Jev calls: a yes/no, a label and a rating
jev_inbox.pyA support inbox triaged on Jev: spam, team and urgency for 8 tickets in about a second
jev_with_claude.pyJev decides which messages need a reply; Claude writes only those replies
thunc_write.pythunc write: a function writes itself into a scratch file on its first call, then runs as plain Python
temporal/Durable agents: a worker, a client and a classify → agent analysis → typed summary pipeline (needs thunc[temporal] and a Temporal service)

Where next

Edit this page on GitHub