← thunc

New in 0.2.1 · optional integration

Durable agents with Temporal

Keep task definitions. Use a separate runtime when execution needs to survive worker restarts.

New in thunc 0.2.1. Durable agents are new; their API may change in a later release. Local thunc calls remain dependency-free.

Start the service and worker

Install thunc with the Temporal extra and the official Temporal CLI. The service below is for local development and binds to loopback; production needs a properly operated Temporal service.

pip install "thunc[temporal,openai]"
mkdir -p .temporal-dev
temporal server start-dev --db-filename .temporal-dev/server.sqlite

# Another terminal, with provider credentials configured:
cd examples/temporal
python worker.py

# A third terminal in examples/temporal:
python client.py

The example creates an exclusively worker-owned workspace. Set THUNC_WORKSPACE to select its path and THUNC_TEMPORAL_STATE for persistent journal/artifact storage outside that workspace. Keep the same volume and paths across worker restarts.

Register and submit

from thunc.temporal import Registry, Runtime, Worker

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() in the worker process

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()
print(run.value)

Use registry.function(...) for typed @thunc.function definitions. runtime.get(handle.id, returns=str) reconnects; status() inspects and cancel() requests cooperative cancellation. Disconnecting a client does not cancel its run.

What recovers

Resolve an uncertain effect

status = await handle.status()
await handle.resolve(status["operation_id"], "complete",
    evidence="Verified the process exited and checked its effect",
    output="Recovered output")

Operators can complete, abort, or explicitly retry an uncertain command after checking the old process and effects. Resolutions are deduplicated. Namespace authorization controls access; the evidence text is an audit record, not authentication. Termination or cancellation alone is not rollback.

Boundaries

Temporal history is not a workspace backup. Preserve the service database, worker journal, artifacts and workspace. The beta supports a persistent local filesystem and same-volume restart, not arbitrary multi-host failover. Agent permissions are not an OS sandbox. Local agent execution refuses durable-owned workspaces.

Submissions and final results have a 256 KiB inline budget; immutable state snapshots have a 16 MiB ceiling. Larger final results should be represented by application-managed artifact references. Tombstones and artifacts are retained; there is no automatic garbage collection.

Version task definitions and deployment queues, retain compatible workers until runs drain, and replay saved histories before changing orchestration. A configured Temporal DataConverter/PayloadCodec protects service payloads as configured; local SQLite and artifacts require their own encrypted storage and filesystem permissions.

Compose and verify

examples/temporal/pipeline.py demonstrates classification → agent analysis → typed summary using native Temporal Workflows. thunc.temporal.adapters.execute_task submits and waits through stable identities; each agent still has separate model/tool Activities.

pip install -e '.[anthropic,openai,dev,temporal-test]'
pytest
THUNC_TEMPORAL_TESTS=1 pytest -c pytest-temporal.ini tests/temporal

Integration tests use the official local service and scripted providers, including actual worker termination, replay, rollover and cancellation. They incur no model calls. SDK 1.34.0 is the tested baseline.

See examples/temporal/README.md in the checkout for the complete operational guide.