Repository navigation
v0.2.1 (beta)
Pre-release
Pre-release
thunc 0.2.1 adds durable agents: an optional runtime on Temporal that records each model turn and tool call. A run survives worker restarts, and you can reattach to it from another process. Local thunc stays dependency-free, and agent.run() works as before.
pip install --upgrade "thunc[temporal]"from thunc.temporal import Registry, Runtime, Worker
# Worker process: register an existing @agent.task with a version and a workspace.
registry = Registry(state_dir="/srv/thunc-state")
registry.agent_task("repo.review", review_task, version="1", workspace_id="repo")
worker = await Worker.connect("localhost:7233", task_queue="repo-v1", registry=registry)
await worker.run()
# Client process: submit by a stable request ID, then reattach from anywhere.
runtime = await Runtime.connect("localhost:7233", task_queue="repo-v1")
handle = await runtime.start("repo.review", version="1", workspace_id="repo", inputs={},
returns=str, request_id="review-123", deadline_seconds=1800)
run = await handle.result() # DurableRun[str]Durable agents
thunc.temporal:Registry,Worker,RuntimeandHandlelet you register versioned tasks, then start, reattach to, inspect, cancel and resolve runs. The same request ID reattaches to the same run; the same ID with different inputs is rejected (#37).- Resumes where it stopped: each model turn and each tool call is its own recorded step. After a worker restart, completed turns aren't sent to the model again (#37).
- Recoverable file writes and memory: an intent and receipt journal, atomic replacement and content hashes. An edit made outside the run is reported as a conflict, never overwritten (#37).
- Commands are never run twice by accident: if a worker dies while a command is running, the run waits in
needs_attentionuntil an operator callsresolve()withcomplete,abortorretry(#37). - One run at a time per workspace, in order, through a coordinator workflow (#37).
- Bounded retries for transient provider errors (connection errors, 408, 429 and 5xx), at most three attempts, with the provider SDK's own retries turned off (#37).
- Composition:
thunc.temporal.adapters.execute_taskcalls registered tasks from your own Temporal workflows.examples/temporalhas a runnable classify → agent analysis → typed summary pipeline (#38).
What durable mode needs
A Temporal service (the local dev server or your own), a worker process, and persistent storage on one volume. Temporal doesn't back up your workspace or reverse side effects. The Temporal guide covers setup, recovery, storage and upgrades.
Tested
- Offline tests run on Python 3.10–3.14 on Ubuntu, and on Windows.
- Integration tests run against the official local Temporal service on Python 3.10 and 3.14, without model calls. They cover worker kill and restart, history replay, Continue-As-New, duplicate submissions, cancellation and crash recovery in the write journal.
- Durable mode hasn't been smoke-tested against live model providers yet.
Behaviour changes
- Local and durable runs share one agent engine (#36). A
remembercall that fails no longer appears inRun.notes. - Agents with
tools=ortimeout=can't be registered for durable runs yet; durable runs usedeadline_seconds=instead. - Nothing changes for
@thunc.function,thunc.callor localagent.run().
Still beta: expect bugs, and the durable API may change. See CHANGELOG.md.
Full changelog: v0.2.0...v0.2.1