Skip to content

Embedding

There are two ways to embed Omega in your own JavaScript/TypeScript application: the full runtime via omega-lisp, or the narrow kernel via @omega/core.

Pick one based on what you need

NeedUseWhy
LLM calls, sessions, REPL meta-commands, driver registryomega-lispfull surface, includes auto-pop of providers from env
Just evaluate Lisp source against a custom effect backend@omega/corenarrow facade, no driver/REPL deps
Embedded debugger / time travel / forkingomega-lisp (you need MachineVal + meta package)reflective primitives

Full runtime — omega-lisp

ts
import { OmegaRuntime, populateRegistryFromEnv } from 'omega-lisp';
import { DriverRegistry } from '@open-matrix/inference';

async function main() {
  const registry = new DriverRegistry();
  await populateRegistryFromEnv(registry);

  const omega = new OmegaRuntime({
    registry,
    defaultDriver: 'anthropic',
    maxOracleDepth: 4,
    maxSteps: 500_000,
  });

  const evalResult = await omega.eval('(map (lambda (x) (* x x)) (list 1 2 3))');
  console.log(evalResult.value);
  // → { tag: "List", items: [{ tag: "Num", n: 1 }, { tag: "Num", n: 4 }, { tag: "Num", n: 9 }] }

  const inferResult = await omega.infer('Summarize: ...');
  console.log(inferResult.meaning);

  await omega.dispose();
}

Narrow kernel — @omega/core

ts
import {
  compileTextToExpr,
  COWStore,
  runToCompletion,
  createKernelRuntime,
  createKernelPrimitives,
} from '@omega/core';

const expr = compileTextToExpr('(+ 1 2)');
const runtime = createKernelRuntime({ /* host-supplied effect backend */ });
const initialState = /* construct State with COWStore + Env + the kernel primitives */;
const finalState = runToCompletion(initialState, runtime);
// inspect finalState.control or finalState.kont

@omega/core doesn't ship the auto-pop helper or the driver-aware effect backend. The host is expected to construct its own EffectBackend that handles whatever effect ops the embedded Lisp will emit.

What goes in OmegaConfig

From runtime.ts:37-61:

ts
{
  adapter?: OracleAdapter;       // explicit adapter (overrides env auto-detect)
  maxOracleDepth?: number;       // default 4 — how many nested oracle calls
  defaultCaps?: CapSet;          // capability set installed at root context
  defaultBudgets?: BudgetLimits; // default budget for new contexts
  profile?: Profile;             // truth regime (DEFAULT_PROFILE if omitted)
  maxSteps?: number;             // default 500_000
  registry?: DriverRegistry;     // driver registry for named-driver routing
  defaultDriver?: string;        // default driver name
}

Browser embedding

@omega/core exposes a browser entry point (packages/core/src/index.browser.ts). The runtime depends on node:crypto in some primitives; the browser build uses Web Crypto where applicable. Some I/O effects (file.read.op, etc.) are not available in the browser — the host's EffectBackend should reject or stub those.

The browser bundle in this workspace is generated by packages/core/build.mjs and lives at packages/core/dist/index.browser.js.

Lifecycle

  • Construct once, evaluate many. OmegaRuntime is meant to be long-lived; constructing per call is wasteful (re-installs primitives, re-creates ctx).
  • Dispose explicitly. await omega.dispose() releases driver-side resources (close subprocess connections, fly the Anthropic SDK gracefully, etc.).
  • Per-tenant runtimes are fine. Spinning up one runtime per principal is reasonable; the snapshot/receipt repos are isolated.

See also

Source: projects/omega-lisp/src/runtime.ts:34-130+ (OmegaConfig, OmegaRuntime, populateRegistryFromEnv), projects/omega-lisp/packages/core/src/index.ts:1-24 (narrow facade), projects/omega-lisp/packages/core/src/kernel.ts (kernel runtime).