Memory
Memory lets an agent use what it learned in earlier threads. B4.run has three memory mechanisms, and you pick one by who writes the data and how the agent reads it. (Route state and checkpoints preserve workflow execution. They're not a fourth memory mechanism.)
| Mechanism | Scope and shape | Best for | Written by |
|---|---|---|---|
workspace/AGENTS.md | App-wide Markdown, re-read each model turn | Stable instructions and facts shared by consuming agent routes | You or an agent with writeFile |
Route memory.md | Route-local Markdown, re-read each model turn | Versioned prompt facts for one route | Application developer |
Route memory.ts | Typed, store-backed records in declared namespaces | Facts, episodes, and reflections accumulated across sessions | Application and agent tools |
Start with the prompt files for small, reviewed context. When records need a schema, governance, retention, or retrieval, the smallest useful memory.ts is:
import { defineMemory } from "@b4run/sdk"
import { z } from "zod"
export default defineMemory({
kind: "semantic",
scope: ["workspace", "route"],
schema: z.object({
subject: z.string(),
predicate: z.string(),
value: z.string(),
}),
})From this typed collection, continue with the guide for your task:
- Long-term Memory: schemas, the generated tools, write governance, candidate review, configuration, and testing.
- Recall and Retrieval: how recall ranks records, opt-in semantic recall, and the pgvector backend.
- Episodes: the run recorder, retention, and time-windowed recall.
- Distillation: consolidating and reflecting on stored records with
b4 memory. - Browse and Manage Memory: building an authenticated admin surface over the store.
Workspace profile (AGENTS.md)Copy link to section: Workspace profile (AGENTS.md)
If workspace/AGENTS.md exists and has content, B4.run injects it under # Memory on every model turn. Every agent route and subagent that uses the same app root shares it. Raw graph, workflow, and chain routes skip it.
# Workspace Memory
- Use pnpm for package commands.
- Prefer short, direct customer replies.
- Escalate billing exceptions to the finance queue.With the default local app root, every thread reads the same file on the host, even with a per-thread sandbox. Use separate app roots or trust domains for tenants, constrain untrusted writes, and review seeded content.
If the file is house style your team maintains rather than agent memory, set agentsMd: { writable: false }. B4.run then injects it under # Project guidance and tells the model not to modify it. That changes only the prompt, so enforce it with a filesystem middleware that refuses writes to AGENTS.md, and deny or gate runBash for routes that can reach the workspace, since a shell command bypasses that middleware.
Updating itCopy link to section: Updating it
See Workspace Filesystem for controlled writeFile access and backend behavior.
Route memory (memory.md)Copy link to section: Route memory (memory.md)
For stable context that applies to one agent route, place memory.md beside its index.ts:
src/app/navlog/
index.ts
memory.md# Navlog Route Memory
- The aircraft profile lives in long-term memory as subject `aircraft` with
predicates `tail_number`, `cruise_rpm`, `usable_fuel_gal`, `reserve_minutes`.
Recall it at the start of every plan; remember new facts the pilot states.
- Performance numbers come from POH tables the performance subagent read; cite
the figure. Weather comes from the live tools; quote the raw observation.
- `computeNavlog` owns every number on the navlog.B4.run trims the file and injects it under # Route Memory, after workspace/AGENTS.md, on every model turn. Creating the file is the whole opt-in. You don't import or register anything.
The file is a versioned prompt fragment that only you edit. The agent reads it and never writes to it. Empty files contribute nothing. Files larger than 32 KiB are skipped and produce a prompt note.