From f6284083d538c82caa19b3480821eb30c1e2e8f6 Mon Sep 17 00:00:00 2001 From: brittianwarner Date: Fri, 3 Apr 2026 12:42:55 -0400 Subject: [PATCH 1/2] fix(rivetkit): lazy-load agent-os-core to avoid node:sqlite crash on Bun --- .../rivetkit/src/agent-os/actor/index.ts | 45 ++++++++++++++++--- 1 file changed, 39 insertions(+), 6 deletions(-) diff --git a/rivetkit-typescript/packages/rivetkit/src/agent-os/actor/index.ts b/rivetkit-typescript/packages/rivetkit/src/agent-os/actor/index.ts index 30bdf37cfa..2f8ec22e1e 100644 --- a/rivetkit-typescript/packages/rivetkit/src/agent-os/actor/index.ts +++ b/rivetkit-typescript/packages/rivetkit/src/agent-os/actor/index.ts @@ -1,5 +1,8 @@ -import { AgentOs, createInMemoryFileSystem } from "@rivet-dev/agent-os-core"; -import type { AgentOsOptions, MountConfig } from "@rivet-dev/agent-os-core"; +import type { + AgentOs, + AgentOsOptions, + MountConfig, +} from "@rivet-dev/agent-os-core"; import type { DatabaseProvider } from "@/actor/database"; import { actor, event } from "@/actor/mod"; import type { RawAccess } from "@/db/config"; @@ -36,6 +39,30 @@ import { } from "./session"; import { buildShellActions } from "./shell"; +// Lazy-load @rivet-dev/agent-os-core to avoid triggering its eager +// require("node:sqlite") side-effect at import time. This keeps +// rivetkit/agent-os importable on runtimes that lack node:sqlite (e.g. Bun). +let agentOsCorePromise: Promise< + typeof import("@rivet-dev/agent-os-core") +> | null = null; + +async function loadAgentOsCore() { + if (agentOsCorePromise !== null) return agentOsCorePromise; + // Use Array.join() to prevent Turbopack from tracing into the module + // graph at compile time (same technique as sqlite-pool.ts). + const specifier = ["@rivet-dev", "agent-os-core"].join("/"); + const promise = import(specifier) as Promise< + typeof import("@rivet-dev/agent-os-core") + >; + // Clear the cache on failure so subsequent calls retry instead of + // returning a permanently rejected promise. + agentOsCorePromise = promise.catch((err) => { + agentOsCorePromise = null; + throw err; + }); + return agentOsCorePromise; +} + // --- VM lifecycle helpers --- async function ensureVm( @@ -48,10 +75,15 @@ async function ensureVm( const start = Date.now(); + const core = await loadAgentOsCore(); + // Build options with in-memory VFS as default working directory mount. - const options = buildVmOptions(config.options); + const options = buildVmOptions( + config.options, + core.createInMemoryFileSystem, + ); - const agentOs = await AgentOs.create(options); + const agentOs = await core.AgentOs.create(options); c.vars.agentOs = agentOs; // Wire cron events to actor events. @@ -69,7 +101,8 @@ async function ensureVm( } function buildVmOptions( - userOptions?: AgentOsOptions, + userOptions: AgentOsOptions | undefined, + createMemFs: typeof import("@rivet-dev/agent-os-core")["createInMemoryFileSystem"], ): AgentOsOptions { const userMounts = userOptions?.mounts ?? []; @@ -87,7 +120,7 @@ function buildVmOptions( // actor storage-backed blocks) so VM filesystem state survives sleep/wake. const memMount: MountConfig = { path: "/home/user", - driver: createInMemoryFileSystem(), + driver: createMemFs(), }; return { From 90e7817266abfc757ad29a950b80ae9164b0a69f Mon Sep 17 00:00:00 2001 From: brittianwarner Date: Fri, 3 Apr 2026 17:07:40 -0400 Subject: [PATCH 2/2] fix(agent-os): improve lazy-load error context and extract type alias Wrap loadAgentOsCore rejection with a descriptive error message and cause chain. Extract CreateMemFs type alias to clean up the verbose inline typeof import parameter on buildVmOptions. --- .../packages/rivetkit/src/agent-os/actor/index.ts | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/rivetkit-typescript/packages/rivetkit/src/agent-os/actor/index.ts b/rivetkit-typescript/packages/rivetkit/src/agent-os/actor/index.ts index 2f8ec22e1e..7501b57086 100644 --- a/rivetkit-typescript/packages/rivetkit/src/agent-os/actor/index.ts +++ b/rivetkit-typescript/packages/rivetkit/src/agent-os/actor/index.ts @@ -58,7 +58,10 @@ async function loadAgentOsCore() { // returning a permanently rejected promise. agentOsCorePromise = promise.catch((err) => { agentOsCorePromise = null; - throw err; + throw new Error( + `failed to load @rivet-dev/agent-os-core: ${err instanceof Error ? err.message : String(err)}`, + { cause: err }, + ); }); return agentOsCorePromise; } @@ -100,9 +103,12 @@ async function ensureVm( return agentOs; } +type CreateMemFs = + typeof import("@rivet-dev/agent-os-core")["createInMemoryFileSystem"]; + function buildVmOptions( userOptions: AgentOsOptions | undefined, - createMemFs: typeof import("@rivet-dev/agent-os-core")["createInMemoryFileSystem"], + createMemFs: CreateMemFs, ): AgentOsOptions { const userMounts = userOptions?.mounts ?? [];