Cross-run recall
Memory that survives and connects runs — automatic global knowledge, explicit run linking, per-user partitioning, and instant run snapshots.
Runs isolate by design, but most real work has history: the same customer returns, the same class of bug resurfaces, a new task continues an old one. Cross-run recall is the set of mechanisms by which a fresh run sees what earlier runs learned — some automatic, some explicit. Use this page when you're deciding which mechanism carries which kind of continuity, instead of stuffing old transcripts into new prompts.
How it works
Four mechanisms, from implicit to explicit:
| Mechanism | What crosses runs | You do |
|---|---|---|
| Scope ladder | Validated knowledge (lessons at session/global/org scope) | Nothing — surfaces automatically in any run's recall |
user_id partitioning | Everything written for one end-user | Pass user_id on writes and queries |
| Run linking | One specific run's full memory | client.advanced.link_run + include_linked_runs=True |
| Run snapshot | A distilled summary of one run | client.advanced.context_snapshot |
The scope ladder is the ambient channel: knowledge that has earned session, global, or org scope — chiefly lessons, via direct lesson_scope= writes or promotion — appears in every eligible run's retrieval without any linking. The other three are targeted: per-person, per-run, per-summary.
Walkthrough
Two weeks after the CSV-export incident, Acme Corp opens a new ticket. Ari starts a fresh run — and stitches the history back together with all four mechanisms:
new_run = "nimbus:ari:ticket-1201"
old_run = "nimbus:ari:ticket-1042" # the original CSV-export ticket
# 1. Automatic: the global-scope lesson from the old incident just shows up.
context = client.recall(
session_id=new_run,
query="Acme export failing again — anything we already know?",
entry_types=["lesson", "fact"],
)
# → "When an export times out, check the report row count before retrying…"
# surfaces even though this run has never seen it. No linking involved.
# 2. Per-user: facts written with user_id follow the customer, not the run.
client.remember(
session_id=new_run,
agent_id="ari",
content="Acme Corp is on the Scale plan (upgraded May 3)",
intent="fact",
user_id="acme-corp",
)
# Any future run passing user_id="acme-corp" recalls this — see
# cross-session recall in the SDK helpers.
# 3. Explicit continuity: link the original ticket run and read its evidence.
# link_run is a raw op — call it via the advanced passthrough
# (client.advanced.link_run in Python, client.advanced.linkRun in JS,
# client.advanced().link_run(json!({...})) in Rust); there is no typed helper.
client.advanced.link_run(run_id=new_run, linked_run_id=old_run)
history = client.recall(
session_id=new_run,
query="What was the root cause and fix for the previous export failure?",
include_linked_runs=True,
)
# 4. Instant orientation: "what happened in that run", without replaying it.
# context_snapshot is also a raw op (POST /v2/control/context/snapshot).
snap = client.advanced.context_snapshot(run_id=old_run)
print(snap["snapshot"]["summary"]) # LLM-generated run summary
print(snap["snapshot"]["facts"]) # key facts established in the run
print(snap["snapshot"]["uncertainties"]) # what was never resolved
print(snap["snapshot"]["blockers"]) # what stopped progress
print(snap["snapshot"]["next_actions"]) # where the run left offThe snapshot response also carries the run's agents, event timeline, and any promotions that originated there. Pass refresh=True to force regeneration instead of a cached snapshot. For a debugging human, context_snapshot on a two-week-old run answers "where did this leave off?" in one call.
All four mechanisms exist in every SDK: TypeScript uses client.advanced.linkRun({...}) and client.advanced.contextSnapshot({...}); Rust uses client.advanced().link_run(json!({...})) and client.advanced().context_snapshot(json!({...})). The typed helpers (recall, remember) take the same option fields shown here.
Pinning retrieval to the current run
Cross-run recall is the default posture — durable learning is the point. But sometimes you need the opposite: deterministic, self-contained retrieval that reflects only what this run established. Evaluation harnesses, reproducible tests, and strict-isolation tasks all qualify. Pass prefer_current_run=True on recall() to pin retrieval to the active run and skip the cross-run lesson overlay:
result = client.recall(
session_id=new_run,
query="current diagnosis for this ticket",
prefer_current_run=True, # this run's evidence only; no cross-run lessons
)Leave it off in production agents — withholding validated lessons from a live task is usually a bug, not a feature.
When not to use it
| Situation | Prefer instead |
|---|---|
| The "prior work" is in-flight, same task, multiple agents | One shared run — lanes and handoffs, no cross-run machinery needed |
| You need byte-exact artifacts from an old run (a diff, generated SQL) | archive() / dereference() by reference_id — semantic recall doesn't guarantee exactness (memory model) |
| Fan-out research whose runs you'll link back the same day | Subagent isolation — same linking, different lifecycle |
Related
- Runs, sessions, and scopes — the scope ladder, run linking, and
user_idpartitioning in depth - Subagent isolation — run linking for orchestrator-worker fan-out
- Cross-session recall — the
user_idhelper idiom - Temporal memory patterns — time-windowed queries over long-lived memory
- Control HTTP reference — wire contracts for run link and snapshot