Skip to main content
<Memory> gives one memory configuration to every descendant <Task> via TaskDescriptor.memoryConfig; a task-level memory={...} prop replaces it for that task, under the same validation and defaults (below).

Props

At least one non-empty bank is required after inheritance. Nested <Memory> components inherit omitted fields; bank/banks on an inner component replaces the parent selection.

Prompt injection

Before an agent task starts, Smithers fetches configured primers and bank recalls, prepending them inside a fenced <smithers_memory_context> block, and enforces the maxTokens cap (a conservative UTF-8 byte ceiling, not a model-specific tokenizer) so recalled context can’t crowd out task instructions. Tasks with an active bank/banks configuration skip task-output caching, since the recalled snapshot can change even when prompt, agent, and worktree don’t, and a cached result would return stale output (legacy-only memory metadata is inert and keeps existing cache semantics). The snapshot itself stays frozen across retries of one task execution. Recall and primer reads are advisory: a timeout or backend error logs a warning and runs the task with its original prompt rather than failing it. Missing mental-model ids are handled per bank: user-primer may exist only in the user bank, project-primer only in the project bank, and both still inject.
Set recall={false} for tools-only memory:

Banks, tags, and run identity

Banks are isolation boundaries: a user bank for personal preferences, a project bank for team knowledge. Use stable, recall-relevant tags below the bank boundary:
Do not put run, task, session, or project ids in tags: Smithers records volatile identity in Hindsight metadata via a stable per-run document id with append mode, preserving provenance without fragmenting observation consolidation. Use scope:main with branch:main and scope:branch for branch-local writes. Omitting the scope tag on a project bank lets Smithers derive it from the configured branch tag, defaulting a tagless write to scope:main (the canonical project recall filter); a conflicting explicit scope is rejected before retention. Smithers applies the standard two-bank recall policy automatically:
  • user-* banks do not receive project branch, stream, or scope filters.
  • project-* banks use a tag_groups-only filter for (scope:main OR branch:current), then apply configured stream:* and other tags as additional constraints.
  • Other bank names use all configured tags as a strict filter.
The recall tool preserves those base filters; agent-supplied tags add constraints but can’t widen the configured branch or stream scope. remember rejects volatile tags and project-scope tags written to a user bank. The local SQLite fallback applies the same strict filters before keyword scoring, so branch-local facts can’t cross into another branch’s recall.

Backend selection

Hindsight is a Postgres-family feature Smithers selects only when HINDSIGHT_URL is set; openSmithersBackend performs the selection and attaches the resulting memory service to every workflow it creates.
Use one HindsightMemoryStore writer instance per transactional contract store: same-document projections serialize only inside that instance, so separate instances can project competing mutations out of order (process-local queues share no durable version fence).
When workflow state uses PGlite or Postgres and Hindsight is unset, Smithers keeps fallback facts in the local .smithers/smithers.db sidecar; the workflow database stays on its selected backend.
HINDSIGHT_API_KEY and HINDSIGHT_BANK_PREFIX are optional; the prefix applies to every configured bank before requests are sent.

CLI: cross-run memory facts

Outside a run, manage durable facts with the memory command: set writes (remember) a fact, get and list read (recall) facts.
Inside a run, set tools on <Memory> to expose the agent-facing remember and recall tools instead.

Task-level override

The Task.memory prop uses the same TaskMemoryConfig shape and wins over context:
Legacy namespace, remember, threadId, and object-form recall fields remain accepted on Task.memory for compatibility but are inert: the engine never uses them for prompt injection, retention, or message history. Use banks, tags, recall mode, primers, retention, and tools instead.