Durable Task State
Persistent agent checkpoints that survive crashes and enable long-running task recovery.
Overview
Durable Task State tracks checkpoints, file artifacts, and arbitrary key-value data across an agent's execution. It is designed for long-running tasks where you need crash recovery and audit trails.
- Slot:
110(Slot.WORKING_MEMORY + 10) - Scope:
thread(state persists across executions within the same thread) - Default budget:
{ min: 100, max: 800 } - Store timeout:
30000ms
Usage
import { durableTaskState } from '@noetic-tools/core';
const layer = durableTaskState();The factory takes no configuration.
State Type
interface DurableTaskState {
checkpoints: Array<{
timestamp: number;
depth: number;
}>;
files: string[];
data: Record<string, unknown>;
}| Field | Type | Purpose |
|---|---|---|
checkpoints | Array<{ timestamp, depth }> | Ordered list of checkpoint timestamps and execution depths |
files | string[] | Paths to file artifacts produced during execution |
data | Record<string, unknown> | Arbitrary key-value store for task-specific data |
How It Works
init
Loads saved DurableTaskState from scoped storage. Falls back to empty checkpoints, files, and data.
recall
Serializes the state as JSON inside a <task_state> XML block and injects it as a developer message, trimmed to the allocated token budget: the oldest checkpoints are halved away while the render is over budget, and a final guard char-slices while preserving the closing tag. A zero budget is fail-open (full render).
store
Appends a new checkpoint with the current timestamp and execution depth on every store cycle. Checkpoints are capped at the newest 50 (also enforced in onReturn and onComplete), so the durably persisted state cannot grow without bound over a long-lived thread.
onSpawn
Deep-clones the parent state to the child. Unlike other layers, Durable Task State always provides child state to spawned agents.
onReturn
Merges child artifacts back into the parent:
- Checkpoints are concatenated (capped at the newest 50 after the merge)
- File lists are deduplicated via
Set - Data objects are shallow-merged (child keys overwrite parent keys)
onComplete
Records the execution outcome ('success', 'failure', or 'aborted') in data.__outcome and appends a final checkpoint.
StorageAdapter
Durable Task State relies on the StorageAdapter provided in your AgentConfig (via storage on the harness constructor). The adapter must implement:
interface StorageAdapter {
get<T>(key: string): Promise<T | null>;
set<T>(key: string, value: T): Promise<void>;
delete(key: string): Promise<void>;
list(prefix: string): Promise<string[]>;
}You can use the built-in AgentHarness for development or implement a persistent adapter backed by a database or file system.
Example: Task Recovery
import { durableTaskState } from '@noetic-tools/core';
const layer = durableTaskState();
// After a crash, the agent resumes with full checkpoint history
// The agent harness calls init(), which loads the saved state
// The LLM sees all previous checkpoints and can continue from where it left offNext Steps
- Working Memory -- lightweight scratchpad alternative
- Custom Layers -- build your own persistence layer