API Reference

Memory Types

Type definitions for memory layers, hooks, storage adapters, and projection policies in Noetic.

MemoryLayer

The core memory layer interface.

declare interface MemoryLayerShape<TState = unknown> {
  id: string;
  name?: string;
  slot: number;
  scope: MemoryScope;
  budget?: BudgetConfig;
  hooks: MemoryHooks<TState>;
  timeouts?: Partial<LayerTimeouts>;
  provides?: unknown;
  itemSchemas?: unknown;
  rerenderTiming?: 'immediate' | 'batched';
}
FieldTypeRequiredDescription
idstringyesUnique layer identifier.
namestringnoHuman-readable name for debugging and trace output.
slotnumberyesOrdering slot (lower = recalled first). Use the Slot constants for well-known positions.
scopeMemoryScopeyesPersistence boundary.
budgetBudgetConfignoToken budget allocation: a fixed number, a { min, max } range, or 'auto'.
hooksMemoryHooks<TState>yesLifecycle callbacks.
timeoutsPartial<LayerTimeouts>noPer-hook timeout overrides (ms).
providesLayerProvidesnoTyped data and function declarations exposed on ctx.memory['layerId']. Function entries are also auto-injected as LLM tools.
itemSchemasPick<ItemSchemaExtensions, 'developerMessages' | 'items'>noOptional item schemas contributed by this layer, primarily for developer-role memory items.
rerenderTiming'immediate' | 'batched'noDefault re-render timing when onItemAppend requests a re-render.

MemoryScope

type MemoryScope = 'thread' | 'resource' | 'global' | 'execution';

BudgetConfig

type BudgetConfig =
  | number
  | { min: number; max: number }
  | 'auto';

Slot Constants

const SlotShape = {
  REMINDER: 80,
  STEERING: 90,
  WORKING_MEMORY: 100,
  ENTITY: 150,
  OBSERVATIONS: 200,
  PROCEDURAL: 250,
  EPISODIC: 300,
  RAG: 350,
  SEMANTIC_RECALL: 400,
} as const satisfies Record<string, number>;

The runtime exports the Slot constant from @noetic/core with these values; pass any of them as a layer's slot field to position it consistently with built-in layers.

MemoryHooks

interface MemoryHooks<TState = unknown> {
  init?: (params: InitParams) => Promise<InitResult<TState>>;
  recall?: (params: RecallParams<TState>) => Promise<RecallResult<TState> | string | null>;
  store?: (params: StoreParams<TState>) => Promise<StoreResult<TState> | undefined>;
  onSpawn?: (params: SpawnParams<TState>) => Promise<SpawnResult<TState> | null>;
  onReturn?: (params: ReturnParams<TState>) => Promise<ReturnResult<TState> | undefined>;
  onComplete?: (params: CompleteParams<TState>) => Promise<void | { state: TState }>;
  dispose?: (params: DisposeParams<TState>) => Promise<void>;
}

Hook Parameter Types

InitParams

FieldTypeDescription
storageScopedStorageScoped storage for this layer
scopeKeystringResolved scope key
ctxExecutionContextExecution context

InitResult

FieldTypeDescription
stateTStateInitial layer state

RecallParams

FieldTypeDescription
logItemLogCurrent conversation log
querystringCurrent user query
ctxExecutionContextExecution context
stateTStateCurrent layer state
budgetnumberAllocated token budget

RecallResult

FieldTypeDescription
itemsItem[]Items to inject into the prompt
tokenCountnumberTokens consumed by the items
stateTStateUpdated state (optional)

StoreParams

FieldTypeDescription
newItemsItem[]New items from the LLM response
logItemLogFull conversation log
responseLLMResponseComplete LLM response
ctxExecutionContextExecution context
stateTStateCurrent layer state

StoreResult

FieldTypeDescription
stateTStateUpdated state

SpawnParams

FieldTypeDescription
parentStateTStateParent layer state
childCtxExecutionContextChild execution context

SpawnResult

FieldTypeDescription
childStateTState | nullState for the child (null = don't propagate)
itemsItem[]Additional items for the child (optional)

ReturnParams

FieldTypeDescription
childStateTStateChild's final state
childLogItemLogChild's conversation log
parentStateTStateParent's current state
resultunknownChild's completion result

ReturnResult

FieldTypeDescription
parentStateTStateUpdated parent state
resultunknownTransformed result for pipeline (optional)

CompleteParams

FieldTypeDescription
logItemLogFull conversation log
ctxExecutionContextExecution context
stateTStateCurrent layer state
outcomeExecutionOutcomeHow the execution ended

DisposeParams

FieldTypeDescription
stateTStateFinal layer state

ExecutionOutcome

type ExecutionOutcome = 'success' | 'failure' | 'aborted';

ExecutionContext

Context available to memory layer hooks (different from the step Context).

interface ExecutionContext {
  executionId: string;
  threadId: string;
  resourceId?: string;
  depth: number;
  stepNumber: number;
  tokenUsage: { input: number; output: number };
  cost: number;
  model?: string;
  fs: FsAdapter;
  tokenize(text: string): number;
  trace: {
    setAttribute(key: string, value: string | number | boolean): void;
    addEvent(name: string, attributes?: Record<string, string | number | boolean>): void;
  };
}

fs is the FsAdapter from ctx.harness.fs, giving memory layer hooks access to the same filesystem backend as tools and skill discovery (real, in-memory, or remote).

LayerTimeouts

FieldTypeDescription
initnumberTimeout for init hook (ms, optional)
recallnumberTimeout for recall hook (ms, optional)
storenumberTimeout for store hook (ms, optional)
onSpawnnumberTimeout for onSpawn hook (ms, optional)
onReturnnumberTimeout for onReturn hook (ms, optional)
onCompletenumberTimeout for onComplete hook (ms, optional)
disposenumberTimeout for dispose hook (ms, optional)

ProjectionPolicy

interface ProjectionPolicy {
  tokenBudget: number;
  responseReserve: number;
  overflow: 'truncate' | 'summarize' | 'sliding_window';
  overflowModel?: string;
  windowSize?: number;
}
FieldTypeRequiredDescription
tokenBudgetnumberyesTotal token budget for all layers
responseReservenumberyesTokens reserved for the model response
overflow'truncate' | 'summarize' | 'sliding_window'yesStrategy when total recall exceeds budget
overflowModelstringnoModel for summarization overflow
windowSizenumbernoItems to keep for sliding window overflow

StorageAdapter

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[]>;
}
MethodDescription
get(key)Retrieve a value by key (returns null if not found)
set(key, value)Store a value
delete(key)Delete a value
list(prefix)List all keys with the given prefix

ScopedStorage

Same interface as StorageAdapter but scoped to a specific layer and scope key.

interface ScopedStorage {
  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[]>;
}

MemoryTraceSpan

Observability data for a single memory hook execution.

interface MemoryTraceSpan {
  layerId: string;
  hook: 'init' | 'recall' | 'store' | 'onSpawn' | 'onReturn' | 'onComplete' | 'dispose';
  durationMs: number;
  status: 'ok' | 'error' | 'timeout' | 'skipped';
  budget?: { allocated: number; used: number; yielded: number };
  itemCount?: number;
  error?: { message: string; stack?: string };
}

ContextMemory

The default memory shape used when no typed memory config is provided.

type ContextMemory = Readonly<Record<string, Record<string, unknown>>>;

MemoryConfig

A typed memory configuration that carries a phantom _shape for compile-time memory access. Created via the memory() builder.

interface MemoryConfig<TLayers extends MemoryLayer[] = MemoryLayer[]> {
  layers: TLayers;
  _shape: InferMemoryShape<TLayers>;
}
FieldTypeDescription
layersTLayersArray of memory layers
_shapeInferMemoryShape<TLayers>Phantom field for compile-time shape inference (never set at runtime)

InferMemory

Extracts the memory shape type from a MemoryConfig.

type InferMemory<T extends MemoryConfig> = T['_shape'];

InferMemoryShape

A mapped type that collects each layer's provides declarations into a record keyed by layer id. Each key maps to the resolved data/function types declared by that layer.

LayerProvides

type LayerProvides = Record<string, LayerDataDecl | LayerFunctionDecl>;

A record of named declarations that a layer exposes on ctx.memory[layerId].

LayerDataDecl

interface LayerDataDecl<T = unknown, TState = unknown> {
  kind: 'data';
  read: (state: TState) => T;
}
FieldTypeDescription
kind'data'Discriminant
read(state: TState) => TDerives the value from layer state

LayerFunctionDecl

interface LayerFunctionDecl<TInput = unknown, TOutput = unknown, TState = unknown> {
  kind: 'function';
  description: string;
  input: ZodType<TInput>;
  output: ZodType<TOutput>;
  execute: (args: TInput, state: TState) => Promise<TOutput>;
}
FieldTypeDescription
kind'function'Discriminant
descriptionstringHuman-readable description for the LLM
inputZodType<TInput>Zod schema for input validation
outputZodType<TOutput>Zod schema for output validation
execute(args: TInput, state: TState) => Promise<TOutput>Execution function

Builder Functions

layerData

function layerData<T, TState>(read: (state: TState) => T): LayerDataDecl<T, TState>;

Creates a LayerDataDecl that derives a value from layer state.

layerFn

function layerFn<TInput, TOutput, TState>(opts: {
  description: string;
  input: ZodType<TInput>;
  output: ZodType<TOutput>;
  execute: (args: TInput, state: TState) => Promise<TOutput>;
}): LayerFunctionDecl<TInput, TOutput, TState>;

Creates a LayerFunctionDecl that exposes a callable function on the memory object.

memory

function memory<TLayers extends MemoryLayer[]>(...layers: TLayers): MemoryConfig<TLayers>;

Collects layers into a MemoryConfig with inferred _shape. Pass the result to StepSpawn.memory or AgentConfig to get typed ctx.memory access.

On this page