Little documentation
Guides and APIReference

HarnessSession

Session handles, continuation, and out-of-band file staging.

Little Harness: published on npm as little-harness@0.2.0-alpha.0 (2026-10-05). Sections labeled UNRELEASED describe source-only changes. Release status

A HarnessSession is the durable isolated boundary for one conversation or job. It owns the private workspace, artifacts, Persistent Dir checkouts, trace, and continuation handle.

Most apps can pass a string session key directly to streamHarness() or generateHarness(). Use an explicit session handle when the host app needs to stage files or inspect state outside a model turn.

Basic Usage

const session = await harness.sessions.getOrCreate({
  id: chatId,
  extraBody,
});

await session.files.write("/session/app-context/customer-history.csv", stream, {
  mediaType: "text/csv",
  source: "app-context",
});

const result = streamHarness({
  harness,
  messages,
  session,
});

API Shape

type HarnessSession = {
  id: string;
  dataDir?: string;
  files: FileWriter;
  artifacts: HarnessArtifactAccessor;
  trace: TraceRef;
  status(): Promise<HarnessSessionStatus>;
  setStatus(patch: Partial<HarnessSessionStatus>): Promise<void>;
  markMessageStaged(messageId: string): Promise<void>;
  setReadOnlyPersistentDirs(harnessDirs: readonly string[]): void;
  getReadOnlyPersistentDirs(): readonly string[];
};

dataDir is an optional absolute directory for host-managed data the session owns, such as the event stores of workflow runs its workflow tools start (<dataDir>/workflows). localHost() sets it to the session folder; a custom host that omits it gets stores relative to the process working directory (<sessionId>/workflows).

The typed mutators (setStatus, markMessageStaged) and the read-only Persistent-Dir accessors are part of the session port — the loops record turn state through them instead of duck-typing host internals. Session handles should be stable enough to pass between host setup code and execution calls. The loops call the mutators as optional (session.setStatus?.(...)), so a session written against the older five-member shape still runs — it just loses status tracking and staging dedupe until the mutators are implemented.

Session Manager

type HarnessSessionManager<TExtraBody = unknown> = {
  getOrCreate(options: GetOrCreateSessionOptions<TExtraBody>): Promise<HarnessSession>;
  get(id: string): Promise<HarnessSession | undefined>;
};

getOrCreate

Creates a new isolated workspace or resumes an existing one.

const session = await harness.sessions.getOrCreate({
  id: "chat_123",
  extraBody: { userId: "user_123" },
});

get

Looks up an existing session without creating one.

const session = await harness.sessions.get("chat_123");

GetOrCreateSessionOptions

id

string

App-defined session key.

extraBody

TExtraBody

App-defined context used by storage, policy, events, and traces.

metadata

Host metadata object.

Optional host metadata for trace and debugging.

Out-Of-Band File Staging

Use session.files when data arrives between chat messages.

await session.files.write("/session/uploads/report.pdf", reportStream, {
  mediaType: "application/pdf",
  source: "background-upload",
});

The next agent turn can see the file in the same private workspace.

Persistent Dir Writes

If the staged path is inside a Persistent Dir, the write still lands in the session checkout only.

await session.files.write("/persistent/user/uploads/report.pdf", reportStream);

Nothing is committed at write time, and the next turn resets every /persistent/... checkout from backing storage before executing — discarding uncommitted host writes. To persist a host-staged write, stage it in a commit: "manual" dir and call result.commitManual() before starting another turn. See Persistent Dirs for the full commit model.

Isolation Rule

Two sessions must not see each other's files unless the developer configured a shared Persistent Dir or exposed an app tool that deliberately reads shared data.

On this page