Skip to main content
Harness sessions are scoped by (tenantId, userId, sessionId). Reuse that tuple to continue a conversation. Different users or tenants with the same session ID receive separate state.

Session history and state

The default InMemoryHarnessSessionStore stores: The store allows one writer per scoped session in this process. A concurrent acquisition throws HarnessSessionConflict with code: "session_conflict". Serialize runs for the same session in your application, or surface the conflict so the caller can retry after the active run settles. The runtime acquires a lease, clones history/state, and commits before releasing it. A failed or cancelled run may commit partial history marked replayable: false. This avoids representing an incomplete transcript as complete replay state. The default store advertises durable: false, compareAndSwap: false, and singleWriter: "process". A custom store must accurately report its guarantees and implement acquire(identity, sessionId) returning read(), commit(snapshot), and release(). A durable store alone does not give HarnessRuntime crash-resumable execution.

Inspect a completed session

Acquire a read lease only after the current run has settled. This uses the same exclusive acquisition contract as a writer:
InMemoryHarnessSessionStore.importLegacy() imports display-only ChatMessage[] with empty state and replayable: false. It is not a recovery adapter. An Agent’s own storage is not automatically imported or mirrored into harness sessions.

Choose a resource lifetime

In a driver, call services.resource(id, scope, initialize). The initializer returns { value, ownership, dispose? }; the runtime tracks the lease and releases it after the run. ownership: "runtime" allows the pool to call dispose(). ownership: "host" leaves disposal to the application. Incompatible host-scope ownership is rejected. Keep resource IDs stable and specific to the resource configuration you intend to reuse. This factory acquires a session-scoped connection from a custom driver’s services:
The host supplies connect; construction does not invent credentials or authenticate users. Keep any resource operations within the execution boundary appropriate to their effects.

Close a session’s resources

After all runs for a session finish, call await runtime.resources.closeSession(identity, sessionId). Active or still-initializing leases cause HarnessSessionConflict. Runtime-owned resources are disposed in reverse order. The returned string array contains IDs whose disposal failed. Closing resources does not delete the session transcript or artifact storage. There is no global runtime.close() method in the current API. Keep the runtime’s lifetime bounded to your application’s needs, and handle session-resource cleanup explicitly. See exact store and pool contracts and driver ownership.