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 thuncProvider 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 TemporalPick 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 have | Set | Install |
|---|---|---|
| Claude Code, logged in | THUNC_BACKEND=claude-code | pip install thunc |
| Codex, logged in | THUNC_BACKEND=codex | pip install thunc |
| An Anthropic API key | ANTHROPIC_API_KEY | pip install "thunc[anthropic]" |
| An OpenAI API key | OPENAI_API_KEY | pip install "thunc[openai]" |
| A local model (LM Studio) | OPENAI_BASE_URL, see local models | pip 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!")) # 4The 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. They need no install and run through your Claude Code login.
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| Example | What it shows |
|---|---|
| hello.py | The smallest call |
| support_inbox.py | Docstring functions returning a Literal, an int with ensure=, a dataclass and a reply; tickets processed in parallel |
| dynamic_prompts.py | Prompts built from a style guide with thunc.call, and a grading function generated from a rubric |
| log_triage.py | Plain Python and AI functions mixed, with tracing |
| repo_guide.py | Agents: read-only tasks over this repo returning a dataclass and lists, with each run's steps read from the trace |
| jev_with_claude.py | Jev decides which messages need a reply; Claude writes only those replies |