TanStack

InMemoryRunStore

Class: InMemoryRunStore

Defined in: packages/ai/src/activities/chat/middleware/run-store.ts:338

In-memory RunStore. Single process only.

Implements

Constructors

Constructor

ts
new InMemoryRunStore(): InMemoryRunStore;

Returns

InMemoryRunStore

Methods

createOrResume()

ts
createOrResume(input): Promise<RunRecord>;

Defined in: packages/ai/src/activities/chat/middleware/run-store.ts:341

Create a run record, or return the existing one unchanged if runId is already present.

INVARIANT (idempotency): an existing record is returned unchanged and the passed threadId/startedAt/status are ignored. This is what makes resuming a run safe. status defaults to 'running' on first creation.

Parameters

input

Pick<RunRecord, "threadId" | "runId" | "startedAt"> & object

Returns

Promise<RunRecord>

Implementation of

RunStore.createOrResume


findActiveRun()

ts
findActiveRun(threadId): Promise<RunRecord | null>;

Defined in: packages/ai/src/activities/chat/middleware/run-store.ts:404

The most recent 'running' run for threadId, or null if none is active.

REQUIRED. This resolves "does this thread have a live run to attach to?" from the STABLE thread id, which is the durable basis for reconnecting a client (a reload, or the same thread opened on another device) — independent of the ephemeral run id, which a single turn may mint several of. When more than one run is 'running', the one with the greatest startedAt wins.

A backend that stubs this to null turns reconnect off silently, because null is also the correct answer for an idle thread. A backend with no run lifecycle at all should omit the whole runs store instead — capability tiers belong at the store level, not the method level.

Parameters

threadId

string

Returns

Promise<RunRecord | null>

Implementation of

RunStore.findActiveRun


get()

ts
get(runId): Promise<RunRecord | null>;

Defined in: packages/ai/src/activities/chat/middleware/run-store.ts:379

Current record, or null when unknown.

Parameters

runId

string

Returns

Promise<RunRecord | null>

Implementation of

RunStore.get


listByThread()

ts
listByThread(threadId): Promise<RunRecord[]>;

Defined in: packages/ai/src/activities/chat/middleware/run-store.ts:383

Every run in a conversation, ascending by startedAt. OPTIONAL: only needed to render a thread's past agent activity. Consumers feature-detect.

Parameters

threadId

string

Returns

Promise<RunRecord[]>

Implementation of

RunStore.listByThread


listReclaimable()

ts
listReclaimable(opts): Promise<RunRecord[]>;

Defined in: packages/ai/src/activities/chat/middleware/run-store.ts:390

Runs that may be reclaimed: ALL THREE of status === 'running', detachedSince is set, and detachedSince <= now - ttlMs. The cutoff is inclusive — a run detached at exactly now - ttlMs IS reclaimable.

OPTIONAL: only needed by a reaper. Consumers feature-detect.

detachedSince is populated by withSandbox's detach path (see RunRecord.detachedSince). The sweep over the candidates this surfaces is @tanstack/ai-sandbox's reapDetachedRuns: it finalizes a run whose agent already finished, expires one past its TTL, and reclaims the sandbox. That is a function, not a scheduler — the application invokes it (cron, queue, alarm(), waitUntil) — and a backend that omits this method cannot be reaped at all.

Parameters

opts
now

number

ttlMs

number

Returns

Promise<RunRecord[]>

Implementation of

RunStore.listReclaimable


update()

ts
update(runId, patch): Promise<void>;

Defined in: packages/ai/src/activities/chat/middleware/run-store.ts:358

Patch a record's mutable fields.

INVARIANT: updating an unknown runId is a no-op — it must not throw and must not create a record.

Parameters

runId

string

patch

Partial<Pick<RunRecord, | "status" | "finishedAt" | "error" | "usage" | "sandboxKey" | "detachedSince" | "cancelRequested" | "driverEpoch">>

Returns

Promise<void>

Implementation of

RunStore.update