Tasks and specialists
Delegate bounded work durably, resume the parent once, and keep specialist authority explicit.
Use a task when work should outlive the current model turn, run in parallel, or execute under a different instruction and tool boundary.
Durable tasks
@noir-agent/agent/tasks provides durableTasks(), the task engine, and Memory/Postgres task stores. A task definition is trusted application code with a name, input contract, execution function, and limits.
Tasks can run in two modes:
- foreground: suspend the parent and resume it once with the child result
- background: finish independently and re-enter the owning conversation with a completion event
The store persists state, checkpoints, leases, generation binding, cancellation, and notification status. Bounded fan-out preserves deterministic result order even when workers finish out of order.
Named specialists
@noir-agent/agent/specialists turns a reviewed model configuration into ordinary task definitions.
import {
createSpecialistTaskDefinitions,
defineSpecialist,
} from '@noir-agent/agent/specialists'
import { durableTasks } from '@noir-agent/agent/tasks'
const types = createSpecialistTaskDefinitions({
specialists: [defineSpecialist({
name: 'research',
description: 'Answer one evidence-backed research question.',
instructions: 'Use lookup. Cite its result. Do not infer missing facts.',
model: researchModel,
toolNames: ['lookup'],
})],
tools: { lookup },
})
const delegation = durableTasks({ types, store: taskStore })A specialist receives only its declared instructions, model, and tool names. It does not inherit every tool from the parent. Tool failures remain unresolved across checkpoints until that operation succeeds; fluent model text cannot turn a failed lookup into a successful task.
External model harness
Use @noir-agent/agent/harness when the model runs in another process or service. createHarnessModelBridge() supports direct calls or an opaque relay ticket. Each one-turn token is bound to the exact agent, run, actor, installation, conversation, and thread, then consumed once.
The bridge transfers a bounded prompt and response. It does not transfer provider credentials, tool implementations, or ambient runtime state. Memory and Postgres harness stores persist relay tickets; consumed prompt and response bodies are scrubbed.
Cancellation and latestness
Every task is bound to an owner and generation. Before user-visible delivery, check that the task is still current. Canceled or superseded tasks may record a result for audit, but cannot send it into a newer conversation state.
Use a single-flight key when concurrent requests should share one execution. Use distinct keys when repeated work is intentionally independent.
Failure model
- a worker crash leaves a lease that another worker can reclaim
- a completed checkpoint is not executed again
- a suspended task carries an explicit resume reason
- an invalid or oversized result fails validation before persistence
- notification delivery has its own state and cannot imply task success
- parent resumption is idempotent
Verify
Test foreground resume, background completion, two-worker claim contention, cancellation during a tool call, fan-out ordering, a crash after checkpoint, and a superseded task attempting delivery.