What is the Memory Bank?
The Memory Bank is a profile-scoped store of long-lived knowledge that survives across every session of an agent. It captures preferences, facts, behaviors, and short-lived context the agent has decided to remember, and surfaces the most relevant entries back into the prompt on every run. Two delivery channels:- Automatic injection — every run for a profile that opts in to
@memorygets a prefixed--- CONTEXT FROM MEMORY ---block built from the core tier plus query-relevant entries. - On-demand — agents can call
memory_save,memory_recall,memory_list, ormemory_deleteat any point during a run.
Storage Layout
Memories are persisted to the same S3-compatible bucket as artifacts, under a dedicated prefix:<memoryId> is mem-<8hex>, matching Orca’s other ID conventions (run-, sess-, agent-, pool-).
The in-memory index is the runtime source of truth; S3 is the persistence tier hydrated at startup via LoadAll. A successful save does not return until the object lands in S3, so a crash never loses an explicitly saved memory. When S3 is not configured the bank still operates — degraded to in-memory only.
Memory Schema
RawInput is capped at 4 KiB. Larger inputs are rejected with a clear error.
Categories
The core tier is
preference + fact entries with confidence >= 0.8, ordered by confidence then access count. Cached per profile for 5 minutes to keep the run hot path off S3.
Relevance Scoring
QueryWithRelevance ranks active memories by a composite score:
Maturity
Until the bank has accumulated query history, recency and topic dominate. The maturity factor ismin(1, totalAccesses / 50) — once a profile has crossed ~50 cumulative recalls, the usage weight reaches its full 0.30, and the slack from the early-bank period is redistributed back to recency and topic.
Semantic clusters
Eight built-in vocabulary groups bridge cases where a query and a memory share a topic but no literal words. A “diet” query still matches a “peanut allergy” memory through thefood cluster. Clusters: food, health, work, tech, travel, entertainment, communication, shopping. A non-zero contribution requires the cluster to appear on both sides.
Staleness
Each memory carries astalenessScore in [0, 1] recomputed on every save and access:
preference=0.5, fact=0.7, behavior=1.0, context=1.5, general=1.0. The score is surfaced for inspection but does not currently gate retrieval (Brain Dump parity).
Prompt Injection
Profiles that opt in to the@memory capability receive an automatic context block prepended to every run’s prompt:
After the block is rendered, the IDs that made it in are passed to
MarkAccessed fire-and-forget — accessCount and lastAccessedAt update without blocking the run.
Profiles without @memory (or any of the four memory_* tools by name) never receive injection. Same opt-in shape as @artifacts.
LLM Processor
When an agent saves a memory with onlyrawInput (no pre-structured processedContent), the bank consults a fast LLM to extract processedContent, summary, category, and confidence. The processor is a thin wrapper around Anthropic’s Messages API with a 5-second deadline.
Configuration:
When the key is unset, or the call fails, or the response is malformed, the bank falls back to a deterministic preview:
processedContent = rawInput, summary = first 50 chars, category = general, confidence = 0.5.
Memory Tools
@memory is opt-in (not in @default). Every tool requires session context and operates against the session’s profile.
@memory (or naming any memory_* tool individually) both registers the tools and enables prompt injection.
REST API
All endpoints return503 Service Unavailable when the bank is not wired. Reads call a 2-second TTL RefreshIfStale so the dashboard sees runner-side saves promptly without paying for an S3 round-trip on every request.
Per-profile
Global
See the Conductor API reference for request and response shapes.
Configuration
The bank shares the artifact store’s environment contract — see Storage and Files. WhenS3_BUCKET is set it boots in fully persistent mode; otherwise it runs in-memory only and logs a warning at startup.
Both the runner and the conductor build their own bank from these variables. The runner’s bank is the source of truth on writes; the conductor’s bank is read-through synced every 2 seconds for dashboard reads.
Limits and Caveats
- Per-profile scope only. Memories are not shared across profiles or pools — by design. Use pools and the shared filesystem for cross-agent state.
- Listing cap.
LoadAllwalks at most 1000 entries per profile (the underlyingListObjectsV2page cap). Banks larger than that need pagination plumbed throughListInput. - No retention enforcement. Staleness is computed but not acted on. Operators delete cold memories by hand or via the dashboard.
MarkAccessedis best-effort. Access count and timestamp updates persist asynchronously; a runner crash within a few seconds of a recall may lose them.- Source
inferredis reserved for v2. All v1 saves carrysource: "explicit"; future post-run extraction will populateinferred.