Documentation / guides
Task Tools
Maintain a bounded, loop-local dependency graph with four task tools.
TaskDefinitions returns one bundle containing TaskCreate, TaskUpdate, TaskGet, and TaskList. The bundle owns one in-memory task graph for one loop. Separate NewTools calls do not share state. All four tools are sequential and prepared, but they need no workspace or process binding.
Operations
TaskCreaterequiressubjectanddescription, with optionalactiveForm,blockedBy, and JSONmetadata.TaskUpdatepatches fields, changes status, adds or removes blockers, replaces metadata, or uses the command-onlydeletedstatus to remove a task and its references.TaskGetreturns one task by UUID.TaskListreturns every task in deterministic ID order.
Preparation rejects duplicate or unknown JSON fields, malformed UUIDs, duplicate dependencies, oversized fields, invalid metadata, and missing required fields. The store caps the graph at 256 tasks, 128 dependencies per task, and a 2 MiB aggregate representation. It rejects self-dependencies and cycles. A task can become in_progress only when its blockers are completed.
Task results are JSON text blocks. Task operations use an opaque token artifact so execution never reparses the raw arguments. Audit summaries intentionally omit task content and IDs where the package defines a generic summary.
// The four tools share the same loop-local graph because they came from one
// NewTools call.
bundle := task.NewTools()
created := invoke(bundle[0], executionID,
`{"subject":"Document tools","description":"Add runnable examples"}`)
listed := invoke(bundle[3], executionID, `{}`)
fmt.Println(created, listed)
The task bundle fixture creates a task through TaskCreate and lists it through the same bundle. Link its result into Harness’s tool-call/result step when documenting how task state appears in a turn.