Skip to content

Session VM — WIT interface

The LOKUST Session VM is a Rust library compiled to a WebAssembly Component (WASI Preview 2). It exposes a WIT-defined interface for session lifecycle operations.

Component size: ~113 KB. Runtime: Wasmtime 31+ (or any runtime implementing the Component Model).

WIT package

package lokust:session-vm;

Definition path: session-vm/crates/session-guest/wit/world.wit.

Interfaces

types

Shared record and enum definitions used by other interfaces.

interface types {
  record session-id {
    inner: string,
  }

  enum session-status { idle, running, paused, completed, failed }
  enum agent-status   { queued, running, paused, completed, failed }

  record agent-config {
    agent-id: string,
    name: string,
    role: string,
    phase-index: u32,
  }

  record phase-snapshot {
    agent-id: string,
    status: agent-status,
    output: list<u8>,
    duration-ms: u64,
    tokens-used: u64,
  }

  record session-snapshot {
    id: session-id,
    status: session-status,
    phases: list<phase-snapshot>,
    current-phase-index: u32,
    total-duration-ms: u64,
    total-tokens: u64,
    created-at-ms: u64,
  }

  record coordination-metrics {
    phases-completed: u32,
    phases-total: u32,
    total-duration-ms: u64,
    total-tokens: u64,
    compression-ratio: f64,
  }
}

gpu (host import)

Defined by the guest, implemented by the host. Lets the session VM request GPU acceleration without compiling GPU code into the WASM binary.

interface gpu {
  record tensor {
    shape: list<u32>,
    data: list<f32>,
  }

  available: func() -> bool;
  device-info: func() -> string;
  infer: func(model-id: string, input: tensor) -> result<tensor, string>;
}

Reference implementation (CPU fallback): session-vm/crates/gpu-backend/src/lib.rs. Production hosts wire this to native CUDA/Metal/Vulkan via cudarc/metal-rs/ash.

agent-runtime (host import)

Host-provided agent execution. The guest invokes this whenever a phase needs an agent's work done — the host routes to the Claude API or any other model backend.

interface agent-runtime {
  record agent-task {
    agent-id: string,
    system-prompt: string,
    user-prompt: string,
    prior-context: list<u8>,
  }

  record agent-result {
    output: list<u8>,
    tokens-used: u64,
    duration-ms: u64,
  }

  execute: func(task: agent-task) -> result<agent-result, string>;
}

Reference implementation: session-vm/crates/session-host/src/claude.rs.

session-ops (guest export)

The primary surface. Host applications call these functions on the instantiated component.

interface session-ops {
  use types.{session-id, session-status, agent-config, phase-snapshot,
             session-snapshot, coordination-metrics};

  create-session: func(agents: list<agent-config>) -> session-id;
  run-next-phase: func(id: session-id) -> result<phase-snapshot, string>;
  pause-session:  func(id: session-id) -> result<session-status, string>;
  resume-session: func(id: session-id) -> result<session-status, string>;
  get-snapshot:   func(id: session-id) -> option<session-snapshot>;
  import-snapshot:func(snapshot: session-snapshot) -> session-id;
  get-metrics:    func(id: session-id) -> option<coordination-metrics>;
}

World

world session-vm {
  import wasi:clocks/monotonic-clock@0.2.11;
  import wasi:random/random@0.2.11;
  import gpu;
  import agent-runtime;

  export session-ops;
}

Building

# Install cargo-component
cargo install cargo-component --locked

# Add wasm32-wasip2 target
rustup target add wasm32-wasip2

# Build the component
cd session-vm
cargo component build -p session-guest --release

Output: target/wasm32-wasip1/release/session_guest.wasm (despite the target name, cargo-component writes to the wasip1 directory for compatibility).

Hosting

The reference host is session-vm/crates/session-host/. It:

  1. Creates a Wasmtime Engine with the component model enabled
  2. Loads the component file
  3. Builds a Linker, registers the WASI P2 adapters + the custom gpu and agent-runtime imports
  4. Configures WASI preopens (./session-data/data)
  5. Instantiates the component and navigates to the session-ops interface
  6. Calls exported functions via Func.call

Full host implementation: session-vm/crates/session-host/src/main.rs.

Design notes

Why Component Model and not core WASM? Component Model handles record/variant/list marshaling across the boundary natively. The guest sees typed Rust structs; the host sees typed Rust structs; no manual pointer+length packing.

Why host-side GPU? cudarc does not compile to WASM. General CUDA access inside a WASM sandbox is not supported by any production runtime in 2026. The gpu WIT interface lets the guest treat GPU as an abstract capability provided by the host.

Why a separate agent-runtime import? So the same compiled component can run on different backends — Claude today, a local model tomorrow, a heuristic planner in tests. The guest has no knowledge of which.