Skip to content

ExecProcess

A long-running exec as the AI SDK’s SandboxProcess shape.

See the module docs. Built by Session.spawn, never by a constructor: a process object with no exec behind it is one whose every method fails in a way that looks like a dead VM.

get execId(): string;

The exec id, which is the idempotency key.

Read it back to reattach from another process: session.exec(id) addresses the same server-side exec, and session.spawn with the same id does not start a second child.

string


get gaps(): OutputGap[];

Every byte range the daemon could not replay, under gapPolicy: 'event'.

Empty under the default policy, where a gap errors the streams instead — see the module docs for why the ignorable form is not the default.

OutputGap[]


get pid(): number | null;

The process id, if the sandbox exposes one.

Always null, and that is a true answer rather than a stub. The daemon signals a whole process group and addresses an exec by its caller-minted id; it publishes no pid, because a pid inside a MicroVM is not meaningful outside it and would invite a caller to signal it directly through a channel that does not exist. The harness contract marks pid optional for exactly this case.

number | null


get stderr(): ReadableStream<Uint8Array<ArrayBufferLike>>;

The child’s standard error as a stream of bytes.

Independent of [Self::stdout]: order is preserved within each and is not recoverable between them, which is what the wire supports (one shared offset space) and what the harness shape promises.

ReadableStream<Uint8Array<ArrayBufferLike>>


get stdout(): ReadableStream<Uint8Array<ArrayBufferLike>>;

The child’s standard output as a stream of bytes.

One stream per process: reading this twice hands back the same object, because two readers over one channel would split the bytes between them.

ReadableStream<Uint8Array<ArrayBufferLike>>

kill(): Promise<void>;

Terminates the process. Idempotent.

Signals the whole process group rather than the direct child, so a shell’s children go with it. Idempotent because the daemon answers 200 either way: a group that had already been reaped reports nothing signalled, which is the outcome a kill wanted — so a second call is a success and not a 404. That is what lets a harness call this in a finally without guarding it.

Promise<void>


wait(timeoutSeconds?: number | null): Promise<ProcessExit>;

Resolves when the process exits.

From the daemon’s exec record, not from the streams ending, and that is the whole reason a suspend/resume does not look like a clean exit here: a stream that stopped carrying bytes is a stream that stopped, which is the identical observation for a cut connection and a finished command. Only the daemon’s record distinguishes them.

Rejects with ERR_TIMEOUT past timeoutSeconds (300 by default). A timeout has not touched the exec — polling is read-only and the output lives until it is acked — so a caller that gives up can call this again.

Parameter Type
timeoutSeconds? number | null

Promise<ProcessExit>

This page is generated from bindings/microvms-js/index.d.ts by TypeDoc 0.28.20 and typedoc-plugin-markdown 4.13.1, run from site/scripts/gen-reference.mjs on every pnpm run sync, so an edit made here is overwritten by the next run.

To change the page, change the doc comment in the binding’s Rust source, then regenerate the declarations with mise run dts. mise run dts:check fails when the committed file no longer matches the source.