Skip to main content
Use @task for application-owned queue work. A task is not model-visible; an Agent Tool decides when to defer it.

Define and call a task

When a tool needs the task callable, define it once in lib/ and re-export it from tasks/:
If nothing imports the task, you can define it directly in tasks/<name>.py. The file must export exactly one same-named @task callable.

Control a job

Inside @tool(durable=True), Harnest derives a replay-stable idempotency key when you omit one. Keep task effects idempotent because workers can retry.

Runtime requirements

If the application has multiple PostgreSQL stores, set HARNEST_TASK_DATABASE_URL explicitly. Every replica can run a worker against the shared queue.
An unfinished handle.result() requires an async @tool(durable=True) and a Harnest-owned checkpointer. Harnest resumes framework execution; it does not restore a Python stack.
See Durable execution for cross-replica resume behavior.