rivetkit 2.3.0-rc.5 → 2.3.0-rc.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser/client.d.ts +21 -18
- package/dist/browser/client.js +735 -170
- package/dist/browser/client.js.map +1 -1
- package/dist/browser/inspector/client.js +1 -1
- package/dist/browser/inspector/client.js.map +1 -1
- package/dist/tsup/actor/errors.cjs +4 -2
- package/dist/tsup/actor/errors.cjs.map +1 -1
- package/dist/tsup/actor/errors.d.cts +1 -74
- package/dist/tsup/actor/errors.d.ts +1 -74
- package/dist/tsup/actor/errors.js +3 -1
- package/dist/tsup/agent-os/index.cjs +1 -1
- package/dist/tsup/agent-os/index.cjs.map +1 -1
- package/dist/tsup/agent-os/index.d.cts +18 -7
- package/dist/tsup/agent-os/index.d.ts +18 -7
- package/dist/tsup/agent-os/index.js +1 -1
- package/dist/tsup/agent-os/index.js.map +1 -1
- package/dist/tsup/{chunk-2GANBXVP.cjs → chunk-2G64KSZQ.cjs} +10 -10
- package/dist/tsup/{chunk-2GANBXVP.cjs.map → chunk-2G64KSZQ.cjs.map} +1 -1
- package/dist/tsup/{chunk-N2DQSJIW.js → chunk-6S25NVAP.js} +13 -46
- package/dist/tsup/chunk-6S25NVAP.js.map +1 -0
- package/dist/tsup/{chunk-NATOT3ET.js → chunk-CAF6JDJE.js} +4 -4
- package/dist/tsup/{chunk-PGYEMIOE.js → chunk-DEO7MMWQ.js} +2 -2
- package/dist/tsup/{chunk-SULB574D.js → chunk-EMO6E3PJ.js} +3 -3
- package/dist/tsup/{chunk-FTZIZ3JG.cjs → chunk-ENK7C66G.cjs} +838 -236
- package/dist/tsup/chunk-ENK7C66G.cjs.map +1 -0
- package/dist/tsup/{chunk-JY73X7VU.js → chunk-FLODVLYW.js} +690 -88
- package/dist/tsup/chunk-FLODVLYW.js.map +1 -0
- package/dist/tsup/{chunk-OVJX4IFY.cjs → chunk-HTR4YLNT.cjs} +4 -4
- package/dist/tsup/{chunk-OVJX4IFY.cjs.map → chunk-HTR4YLNT.cjs.map} +1 -1
- package/dist/tsup/{chunk-LELRJK66.cjs → chunk-JALSAX7Z.cjs} +3 -3
- package/dist/tsup/{chunk-LELRJK66.cjs.map → chunk-JALSAX7Z.cjs.map} +1 -1
- package/dist/tsup/{chunk-JRCZDHXT.cjs → chunk-K5BA2LEO.cjs} +19 -52
- package/dist/tsup/chunk-K5BA2LEO.cjs.map +1 -0
- package/dist/tsup/{chunk-K34B3OVG.js → chunk-KIWH5H3K.js} +30 -9
- package/dist/tsup/chunk-KIWH5H3K.js.map +1 -0
- package/dist/tsup/{chunk-NW2J4SOL.cjs → chunk-LIXXFXVR.cjs} +5 -5
- package/dist/tsup/{chunk-NW2J4SOL.cjs.map → chunk-LIXXFXVR.cjs.map} +1 -1
- package/dist/tsup/{chunk-HR547GVH.cjs → chunk-M5C7YNI5.cjs} +8 -8
- package/dist/tsup/{chunk-HR547GVH.cjs.map → chunk-M5C7YNI5.cjs.map} +1 -1
- package/dist/tsup/{chunk-V3QNBJ7N.cjs → chunk-QAZLM4WT.cjs} +31 -10
- package/dist/tsup/chunk-QAZLM4WT.cjs.map +1 -0
- package/dist/tsup/{chunk-LDTT6WKJ.js → chunk-RTC2AZGB.js} +2 -2
- package/dist/tsup/{chunk-UXTP4EBU.js → chunk-ZI5QJMKO.js} +2 -2
- package/dist/tsup/client/mod.cjs +7 -7
- package/dist/tsup/client/mod.d.cts +3 -4
- package/dist/tsup/client/mod.d.ts +3 -4
- package/dist/tsup/client/mod.js +6 -6
- package/dist/tsup/common/log.cjs +3 -3
- package/dist/tsup/common/log.js +2 -2
- package/dist/tsup/common/websocket.cjs +4 -4
- package/dist/tsup/common/websocket.js +3 -3
- package/dist/tsup/{config-CvQUtDp9.d.ts → config-0Ta55UV0.d.ts} +10 -9
- package/dist/tsup/{config-C-a9vrke.d.cts → config-Ca8dN4cS.d.cts} +10 -9
- package/dist/tsup/{context-A7R0bsZL.d.ts → context-B_IWbWne.d.ts} +1 -1
- package/dist/tsup/{context-CA3r-pf2.d.cts → context-CUrQ9MHc.d.cts} +1 -1
- package/dist/tsup/inspector/mod.cjs +6 -6
- package/dist/tsup/inspector/mod.js +5 -5
- package/dist/tsup/mod.cjs +252 -207
- package/dist/tsup/mod.cjs.map +1 -1
- package/dist/tsup/mod.d.cts +4 -5
- package/dist/tsup/mod.d.ts +4 -5
- package/dist/tsup/mod.js +183 -138
- package/dist/tsup/mod.js.map +1 -1
- package/dist/tsup/test/mod.cjs +10 -10
- package/dist/tsup/test/mod.d.cts +2 -3
- package/dist/tsup/test/mod.d.ts +2 -3
- package/dist/tsup/test/mod.js +6 -6
- package/dist/tsup/utils-DVekpm4I.d.cts +103 -0
- package/dist/tsup/utils-DVekpm4I.d.ts +103 -0
- package/dist/tsup/utils.cjs +3 -3
- package/dist/tsup/utils.d.cts +1 -1
- package/dist/tsup/utils.d.ts +1 -1
- package/dist/tsup/utils.js +2 -2
- package/dist/tsup/workflow/mod.cjs +9 -9
- package/dist/tsup/workflow/mod.d.cts +4 -5
- package/dist/tsup/workflow/mod.d.ts +4 -5
- package/dist/tsup/workflow/mod.js +5 -5
- package/package.json +8 -8
- package/src/actor/errors.ts +53 -7
- package/src/client/actor-conn.ts +52 -29
- package/src/client/actor-handle.ts +57 -23
- package/src/client/errors.ts +2 -1
- package/src/client/raw-utils.ts +2 -4
- package/src/client/utils.ts +32 -3
- package/src/common/actor-router-consts.ts +4 -0
- package/src/common/bare/generated/client-protocol/v4.ts +599 -0
- package/src/common/client-protocol-versioned.ts +125 -18
- package/src/common/client-protocol-zod.ts +7 -0
- package/src/common/client-protocol.ts +1 -1
- package/src/common/database/native-database.test.ts +35 -0
- package/src/common/database/native-database.ts +8 -4
- package/src/common/router.ts +38 -8
- package/src/common/utils.ts +9 -52
- package/src/drivers/engine/actor-driver.ts +18 -17
- package/src/registry/config/index.ts +3 -5
- package/src/registry/index.ts +156 -19
- package/src/registry/napi-runtime.ts +44 -6
- package/src/registry/native.ts +5 -152
- package/src/registry/runtime.ts +16 -5
- package/src/registry/wasm-runtime.ts +22 -2
- package/dist/tsup/chunk-FTZIZ3JG.cjs.map +0 -1
- package/dist/tsup/chunk-JRCZDHXT.cjs.map +0 -1
- package/dist/tsup/chunk-JY73X7VU.js.map +0 -1
- package/dist/tsup/chunk-K34B3OVG.js.map +0 -1
- package/dist/tsup/chunk-N2DQSJIW.js.map +0 -1
- package/dist/tsup/chunk-V3QNBJ7N.cjs.map +0 -1
- package/dist/tsup/utils-fwx3o3K9.d.cts +0 -18
- package/dist/tsup/utils-fwx3o3K9.d.ts +0 -18
- /package/dist/tsup/{chunk-NATOT3ET.js.map → chunk-CAF6JDJE.js.map} +0 -0
- /package/dist/tsup/{chunk-PGYEMIOE.js.map → chunk-DEO7MMWQ.js.map} +0 -0
- /package/dist/tsup/{chunk-SULB574D.js.map → chunk-EMO6E3PJ.js.map} +0 -0
- /package/dist/tsup/{chunk-LDTT6WKJ.js.map → chunk-RTC2AZGB.js.map} +0 -0
- /package/dist/tsup/{chunk-UXTP4EBU.js.map → chunk-ZI5QJMKO.js.map} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/home/runner/work/rivet/rivet/rivetkit-typescript/packages/rivetkit/dist/tsup/agent-os/index.cjs","../../../src/agent-os/actor/db.ts","../../../src/agent-os/fs/database-vfs.ts","../../../src/agent-os/actor/index.ts","../../../src/actor/config.ts","../../../src/common/log.ts","../../../src/actor/errors.ts","../../../package.json","../../../src/utils.ts","../../../src/utils/env-vars.ts","../../../src/actor/log.ts","../../../src/actor/definition.ts","../../../src/actor/schema.ts","../../../src/common/database/shared.ts","../../../src/common/database/mod.ts","../../../src/agent-os/config.ts","../../../src/agent-os/actor/cron.ts","../../../src/agent-os/actor/network.ts","../../../src/agent-os/actor/preview.ts","../../../src/agent-os/actor/process.ts","../../../src/agent-os/actor/session.ts","../../../src/agent-os/actor/shell.ts","../../../src/agent-os/actor/filesystem.ts"],"names":["db","event","agentOs"],"mappings":"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","file":"/home/runner/work/rivet/rivet/rivetkit-typescript/packages/rivetkit/dist/tsup/agent-os/index.cjs","sourcesContent":[null,"import type { RawAccess } from \"@/common/database/config\";\n\nexport async function migrateAgentOsTables(db: RawAccess): Promise<void> {\n\tawait db.execute(`\n\t\tCREATE TABLE IF NOT EXISTS agent_os_preview_tokens (\n\t\t\ttoken TEXT PRIMARY KEY,\n\t\t\tport INTEGER NOT NULL,\n\t\t\tcreated_at INTEGER NOT NULL,\n\t\t\texpires_at INTEGER NOT NULL\n\t\t);\n\n\t\tCREATE INDEX IF NOT EXISTS idx_preview_tokens_expires_at\n\t\t\tON agent_os_preview_tokens(expires_at);\n\n\t\tCREATE TABLE IF NOT EXISTS agent_os_fs_entries (\n\t\t\tpath TEXT PRIMARY KEY,\n\t\t\tis_directory INTEGER NOT NULL DEFAULT 0,\n\t\t\tcontent BLOB,\n\t\t\tmode INTEGER NOT NULL DEFAULT 33188,\n\t\t\tuid INTEGER NOT NULL DEFAULT 0,\n\t\t\tgid INTEGER NOT NULL DEFAULT 0,\n\t\t\tsize INTEGER NOT NULL DEFAULT 0,\n\t\t\tatime_ms INTEGER NOT NULL,\n\t\t\tmtime_ms INTEGER NOT NULL,\n\t\t\tctime_ms INTEGER NOT NULL,\n\t\t\tbirthtime_ms INTEGER NOT NULL,\n\t\t\tsymlink_target TEXT,\n\t\t\tnlink INTEGER NOT NULL DEFAULT 1\n\t\t);\n\n\t\tCREATE INDEX IF NOT EXISTS idx_fs_entries_parent\n\t\t\tON agent_os_fs_entries(path);\n\n\t\tCREATE TABLE IF NOT EXISTS agent_os_sessions (\n\t\t\tsession_id TEXT PRIMARY KEY,\n\t\t\tagent_type TEXT NOT NULL,\n\t\t\tcapabilities TEXT NOT NULL,\n\t\t\tagent_info TEXT,\n\t\t\tcreated_at INTEGER NOT NULL\n\t\t);\n\n\t\tCREATE TABLE IF NOT EXISTS agent_os_session_events (\n\t\t\tid INTEGER PRIMARY KEY AUTOINCREMENT,\n\t\t\tsession_id TEXT NOT NULL,\n\t\t\tseq INTEGER NOT NULL,\n\t\t\tevent TEXT NOT NULL,\n\t\t\tcreated_at INTEGER NOT NULL,\n\t\t\tFOREIGN KEY (session_id) REFERENCES agent_os_sessions(session_id) ON DELETE CASCADE\n\t\t);\n\n\t\tCREATE INDEX IF NOT EXISTS idx_session_events_session_seq\n\t\t\tON agent_os_session_events(session_id, seq);\n\t`);\n}\n","/**\n * SQLite-backed VirtualFileSystem implementation.\n *\n * Stores file content, metadata (mode, timestamps), and directory structure\n * in SQLite tables managed by the RivetKit actor's database. This allows VM\n * filesystem state to persist across sleep/wake cycles.\n *\n * We use SQLite instead of actor KV because SQLite handles bulk write\n * optimizations (transactions, WAL mode, page caching) under the hood. With KV\n * we would need to manually chunk writes to stay under batch size limits,\n * implement our own indexing for directory listing queries, and handle\n * consistency across multiple KV operations. SQLite gives us all of this for\n * free.\n *\n * All paths are normalized to POSIX form (forward slashes, rooted at \"/\").\n */\n\nimport * as posixPath from \"node:path/posix\";\nimport type { RawAccess } from \"@/common/database/config\";\n\n// Infer VirtualFileSystem from PlainMountConfig.driver since\n// @secure-exec/core is not a direct dependency of this package.\ntype VirtualFileSystem =\n\timport(\"@rivet-dev/agent-os-core\").PlainMountConfig[\"driver\"];\n\n// Infer VirtualStat from AgentOs.stat() return type.\ntype VirtualStat = Awaited<\n\tReturnType<import(\"@rivet-dev/agent-os-core\").AgentOs[\"stat\"]>\n>;\n\n// Infer VirtualDirEntry from readDirWithTypes.\n// VirtualDirEntry has: name, isDirectory, isSymbolicLink?, ino?\ninterface VirtualDirEntry {\n\tname: string;\n\tisDirectory: boolean;\n\tisSymbolicLink?: boolean;\n\tino?: number;\n}\n\n// POSIX mode constants.\nconst S_IFDIR = 0o040000;\nconst S_IFREG = 0o100000;\nconst S_IFLNK = 0o120000;\nconst DEFAULT_FILE_MODE = S_IFREG | 0o644;\nconst DEFAULT_DIR_MODE = S_IFDIR | 0o755;\n\ninterface FsRow extends Record<string, unknown> {\n\tpath: string;\n\tis_directory: number;\n\tcontent: Uint8Array | null;\n\tmode: number;\n\tuid: number;\n\tgid: number;\n\tsize: number;\n\tatime_ms: number;\n\tmtime_ms: number;\n\tctime_ms: number;\n\tbirthtime_ms: number;\n\tsymlink_target: string | null;\n\tnlink: number;\n}\n\nfunction normPath(p: string): string {\n\tconst normalized = posixPath.normalize(`/${p}`);\n\t// Remove trailing slash unless it's the root.\n\tif (normalized.length > 1 && normalized.endsWith(\"/\")) {\n\t\treturn normalized.slice(0, -1);\n\t}\n\treturn normalized;\n}\n\nfunction parentPath(p: string): string {\n\tconst parent = posixPath.dirname(p);\n\treturn parent;\n}\n\nfunction throwENOENT(path: string): never {\n\tconst err = new Error(`ENOENT: no such file or directory: ${path}`);\n\terr.name = \"ENOENT\";\n\tthrow err;\n}\n\nfunction throwEEXIST(path: string): never {\n\tconst err = new Error(`EEXIST: file already exists: ${path}`);\n\terr.name = \"EEXIST\";\n\tthrow err;\n}\n\nfunction throwENOTDIR(path: string): never {\n\tconst err = new Error(`ENOTDIR: not a directory: ${path}`);\n\terr.name = \"ENOTDIR\";\n\tthrow err;\n}\n\nfunction throwEISDIR(path: string): never {\n\tconst err = new Error(`EISDIR: illegal operation on a directory: ${path}`);\n\terr.name = \"EISDIR\";\n\tthrow err;\n}\n\nfunction throwENOTEMPTY(path: string): never {\n\tconst err = new Error(`ENOTEMPTY: directory not empty: ${path}`);\n\terr.name = \"ENOTEMPTY\";\n\tthrow err;\n}\n\nfunction throwENOSYS(op: string): never {\n\tconst err = new Error(`ENOSYS: function not implemented: ${op}`);\n\terr.name = \"ENOSYS\";\n\tthrow err;\n}\n\nfunction rowToStat(row: FsRow): VirtualStat {\n\treturn {\n\t\tmode: row.mode,\n\t\tsize: row.size,\n\t\tisDirectory: row.is_directory === 1,\n\t\tisSymbolicLink: row.symlink_target !== null,\n\t\tatimeMs: row.atime_ms,\n\t\tmtimeMs: row.mtime_ms,\n\t\tctimeMs: row.ctime_ms,\n\t\tbirthtimeMs: row.birthtime_ms,\n\t\tino: 0,\n\t\tnlink: row.nlink,\n\t\tuid: row.uid,\n\t\tgid: row.gid,\n\t};\n}\n\nexport interface DatabaseVfsOptions {\n\t/** The RawAccess database handle from the actor's db provider. */\n\tdb: RawAccess;\n}\n\n/**\n * Create a VirtualFileSystem backed by SQLite.\n *\n * The returned filesystem stores all content and metadata in the\n * `agent_os_fs_entries` table. The table must be created beforehand\n * via `migrateAgentOsTables()`.\n */\nexport function createDatabaseVfs(\n\toptions: DatabaseVfsOptions,\n): VirtualFileSystem {\n\tconst { db } = options;\n\n\tasync function getEntry(path: string): Promise<FsRow | undefined> {\n\t\tconst rows = await db.execute<FsRow>(\n\t\t\t\"SELECT * FROM agent_os_fs_entries WHERE path = ?\",\n\t\t\tpath,\n\t\t);\n\t\treturn rows[0];\n\t}\n\n\tasync function getEntryOrThrow(path: string): Promise<FsRow> {\n\t\tconst entry = await getEntry(path);\n\t\tif (!entry) {\n\t\t\tthrowENOENT(path);\n\t\t}\n\t\treturn entry;\n\t}\n\n\tasync function ensureParentExists(path: string): Promise<void> {\n\t\tconst parent = parentPath(path);\n\t\tif (parent === path) return; // root\n\t\tconst entry = await getEntry(parent);\n\t\tif (!entry) {\n\t\t\tthrowENOENT(parent);\n\t\t}\n\t\tif (entry.is_directory !== 1) {\n\t\t\tthrowENOTDIR(parent);\n\t\t}\n\t}\n\n\tasync function getChildEntries(dirPath: string): Promise<FsRow[]> {\n\t\t// Find direct children by matching paths that are one level deeper.\n\t\t// A direct child of \"/foo\" has path like \"/foo/bar\" but NOT \"/foo/bar/baz\".\n\t\tconst prefix = dirPath === \"/\" ? \"/\" : `${dirPath}/`;\n\t\tconst rows = await db.execute<FsRow>(\n\t\t\t\"SELECT * FROM agent_os_fs_entries WHERE path LIKE ? AND path != ?\",\n\t\t\t`${prefix}%`,\n\t\t\tdirPath,\n\t\t);\n\t\t// Filter to direct children only.\n\t\treturn rows.filter((row) => {\n\t\t\tconst relative = row.path.slice(prefix.length);\n\t\t\treturn relative.length > 0 && !relative.includes(\"/\");\n\t\t});\n\t}\n\n\t// Ensure root directory exists.\n\tconst rootInit = (async () => {\n\t\tconst root = await getEntry(\"/\");\n\t\tif (!root) {\n\t\t\tconst now = Date.now();\n\t\t\tawait db.execute(\n\t\t\t\t`INSERT OR IGNORE INTO agent_os_fs_entries (path, is_directory, content, mode, uid, gid, size, atime_ms, mtime_ms, ctime_ms, birthtime_ms, symlink_target, nlink) VALUES (?, 1, NULL, ?, 0, 0, 0, ?, ?, ?, ?, NULL, 2)`,\n\t\t\t\t\"/\",\n\t\t\t\tDEFAULT_DIR_MODE,\n\t\t\t\tnow,\n\t\t\t\tnow,\n\t\t\t\tnow,\n\t\t\t\tnow,\n\t\t\t);\n\t\t}\n\t})();\n\n\tconst backend: VirtualFileSystem = {\n\t\tasync readFile(p: string): Promise<Uint8Array> {\n\t\t\tawait rootInit;\n\t\t\tconst path = normPath(p);\n\t\t\tconst entry = await getEntryOrThrow(path);\n\t\t\tif (entry.is_directory === 1) {\n\t\t\t\tthrowEISDIR(path);\n\t\t\t}\n\t\t\treturn entry.content ?? new Uint8Array(0);\n\t\t},\n\n\t\tasync readTextFile(p: string): Promise<string> {\n\t\t\tconst data = await backend.readFile(p);\n\t\t\treturn new TextDecoder().decode(data);\n\t\t},\n\n\t\tasync readDir(p: string): Promise<string[]> {\n\t\t\tawait rootInit;\n\t\t\tconst path = normPath(p);\n\t\t\tconst entry = await getEntryOrThrow(path);\n\t\t\tif (entry.is_directory !== 1) {\n\t\t\t\tthrowENOTDIR(path);\n\t\t\t}\n\t\t\tconst children = await getChildEntries(path);\n\t\t\treturn children.map((child) => posixPath.basename(child.path));\n\t\t},\n\n\t\tasync readDirWithTypes(p: string): Promise<VirtualDirEntry[]> {\n\t\t\tawait rootInit;\n\t\t\tconst path = normPath(p);\n\t\t\tconst entry = await getEntryOrThrow(path);\n\t\t\tif (entry.is_directory !== 1) {\n\t\t\t\tthrowENOTDIR(path);\n\t\t\t}\n\t\t\tconst children = await getChildEntries(path);\n\t\t\treturn children.map((child) => ({\n\t\t\t\tname: posixPath.basename(child.path),\n\t\t\t\tisDirectory: child.is_directory === 1,\n\t\t\t\tisSymbolicLink: child.symlink_target !== null,\n\t\t\t\tino: 0,\n\t\t\t}));\n\t\t},\n\n\t\tasync writeFile(\n\t\t\tp: string,\n\t\t\tcontent: string | Uint8Array,\n\t\t): Promise<void> {\n\t\t\tawait rootInit;\n\t\t\tconst path = normPath(p);\n\t\t\tawait ensureParentExists(path);\n\n\t\t\tconst existing = await getEntry(path);\n\t\t\tif (existing && existing.is_directory === 1) {\n\t\t\t\tthrowEISDIR(path);\n\t\t\t}\n\n\t\t\tconst data =\n\t\t\t\ttypeof content === \"string\"\n\t\t\t\t\t? new TextEncoder().encode(content)\n\t\t\t\t\t: content;\n\t\t\tconst now = Date.now();\n\n\t\t\tif (existing) {\n\t\t\t\tawait db.execute(\n\t\t\t\t\t`UPDATE agent_os_fs_entries SET content = ?, size = ?, mtime_ms = ?, ctime_ms = ?, atime_ms = ? WHERE path = ?`,\n\t\t\t\t\tdata,\n\t\t\t\t\tdata.byteLength,\n\t\t\t\t\tnow,\n\t\t\t\t\tnow,\n\t\t\t\t\tnow,\n\t\t\t\t\tpath,\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tawait db.execute(\n\t\t\t\t\t`INSERT INTO agent_os_fs_entries (path, is_directory, content, mode, uid, gid, size, atime_ms, mtime_ms, ctime_ms, birthtime_ms, symlink_target, nlink) VALUES (?, 0, ?, ?, 0, 0, ?, ?, ?, ?, ?, NULL, 1)`,\n\t\t\t\t\tpath,\n\t\t\t\t\tdata,\n\t\t\t\t\tDEFAULT_FILE_MODE,\n\t\t\t\t\tdata.byteLength,\n\t\t\t\t\tnow,\n\t\t\t\t\tnow,\n\t\t\t\t\tnow,\n\t\t\t\t\tnow,\n\t\t\t\t);\n\t\t\t}\n\t\t},\n\n\t\tasync createDir(p: string): Promise<void> {\n\t\t\tawait rootInit;\n\t\t\tconst path = normPath(p);\n\t\t\tawait ensureParentExists(path);\n\n\t\t\tconst existing = await getEntry(path);\n\t\t\tif (existing) {\n\t\t\t\tthrowEEXIST(path);\n\t\t\t}\n\n\t\t\tconst now = Date.now();\n\t\t\tawait db.execute(\n\t\t\t\t`INSERT INTO agent_os_fs_entries (path, is_directory, content, mode, uid, gid, size, atime_ms, mtime_ms, ctime_ms, birthtime_ms, symlink_target, nlink) VALUES (?, 1, NULL, ?, 0, 0, 0, ?, ?, ?, ?, NULL, 2)`,\n\t\t\t\tpath,\n\t\t\t\tDEFAULT_DIR_MODE,\n\t\t\t\tnow,\n\t\t\t\tnow,\n\t\t\t\tnow,\n\t\t\t\tnow,\n\t\t\t);\n\t\t},\n\n\t\tasync mkdir(\n\t\t\tp: string,\n\t\t\toptions?: { recursive?: boolean },\n\t\t): Promise<void> {\n\t\t\tawait rootInit;\n\t\t\tconst path = normPath(p);\n\n\t\t\tif (options?.recursive) {\n\t\t\t\tconst parts = path.split(\"/\").filter(Boolean);\n\t\t\t\tlet current = \"\";\n\t\t\t\tfor (const part of parts) {\n\t\t\t\t\tcurrent += `/${part}`;\n\t\t\t\t\tconst existing = await getEntry(current);\n\t\t\t\t\tif (!existing) {\n\t\t\t\t\t\tconst now = Date.now();\n\t\t\t\t\t\tawait db.execute(\n\t\t\t\t\t\t\t`INSERT INTO agent_os_fs_entries (path, is_directory, content, mode, uid, gid, size, atime_ms, mtime_ms, ctime_ms, birthtime_ms, symlink_target, nlink) VALUES (?, 1, NULL, ?, 0, 0, 0, ?, ?, ?, ?, NULL, 2)`,\n\t\t\t\t\t\t\tcurrent,\n\t\t\t\t\t\t\tDEFAULT_DIR_MODE,\n\t\t\t\t\t\t\tnow,\n\t\t\t\t\t\t\tnow,\n\t\t\t\t\t\t\tnow,\n\t\t\t\t\t\t\tnow,\n\t\t\t\t\t\t);\n\t\t\t\t\t} else if (existing.is_directory !== 1) {\n\t\t\t\t\t\tthrowENOTDIR(current);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tawait backend.createDir(p);\n\t\t\t}\n\t\t},\n\n\t\tasync exists(p: string): Promise<boolean> {\n\t\t\tawait rootInit;\n\t\t\tconst path = normPath(p);\n\t\t\tconst entry = await getEntry(path);\n\t\t\treturn entry !== undefined;\n\t\t},\n\n\t\tasync stat(p: string): Promise<VirtualStat> {\n\t\t\tawait rootInit;\n\t\t\tconst path = normPath(p);\n\t\t\tconst entry = await getEntryOrThrow(path);\n\t\t\treturn rowToStat(entry);\n\t\t},\n\n\t\tasync removeFile(p: string): Promise<void> {\n\t\t\tawait rootInit;\n\t\t\tconst path = normPath(p);\n\t\t\tconst entry = await getEntryOrThrow(path);\n\t\t\tif (entry.is_directory === 1) {\n\t\t\t\tthrowEISDIR(path);\n\t\t\t}\n\t\t\tawait db.execute(\n\t\t\t\t\"DELETE FROM agent_os_fs_entries WHERE path = ?\",\n\t\t\t\tpath,\n\t\t\t);\n\t\t},\n\n\t\tasync removeDir(p: string): Promise<void> {\n\t\t\tawait rootInit;\n\t\t\tconst path = normPath(p);\n\t\t\tconst entry = await getEntryOrThrow(path);\n\t\t\tif (entry.is_directory !== 1) {\n\t\t\t\tthrowENOTDIR(path);\n\t\t\t}\n\t\t\tconst children = await getChildEntries(path);\n\t\t\tif (children.length > 0) {\n\t\t\t\tthrowENOTEMPTY(path);\n\t\t\t}\n\t\t\tawait db.execute(\n\t\t\t\t\"DELETE FROM agent_os_fs_entries WHERE path = ?\",\n\t\t\t\tpath,\n\t\t\t);\n\t\t},\n\n\t\tasync rename(oldPath: string, newPath: string): Promise<void> {\n\t\t\tawait rootInit;\n\t\t\tconst from = normPath(oldPath);\n\t\t\tconst to = normPath(newPath);\n\n\t\t\tconst entry = await getEntryOrThrow(from);\n\t\t\tawait ensureParentExists(to);\n\n\t\t\t// Remove destination if it exists (overwrite semantics).\n\t\t\tconst destEntry = await getEntry(to);\n\t\t\tif (destEntry) {\n\t\t\t\tif (destEntry.is_directory === 1) {\n\t\t\t\t\tconst children = await getChildEntries(to);\n\t\t\t\t\tif (children.length > 0) {\n\t\t\t\t\t\tthrowENOTEMPTY(to);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tawait db.execute(\n\t\t\t\t\t\"DELETE FROM agent_os_fs_entries WHERE path = ?\",\n\t\t\t\t\tto,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tif (entry.is_directory === 1) {\n\t\t\t\t// Move all descendants by updating path prefixes.\n\t\t\t\tconst prefix = from === \"/\" ? \"/\" : `${from}/`;\n\t\t\t\tconst newPrefix = to === \"/\" ? \"/\" : `${to}/`;\n\n\t\t\t\t// Get all descendants first, then update them.\n\t\t\t\tconst descendants = await db.execute<FsRow>(\n\t\t\t\t\t\"SELECT path FROM agent_os_fs_entries WHERE path LIKE ?\",\n\t\t\t\t\t`${prefix}%`,\n\t\t\t\t);\n\n\t\t\t\tfor (const desc of descendants) {\n\t\t\t\t\tconst newDescPath =\n\t\t\t\t\t\tnewPrefix + desc.path.slice(prefix.length);\n\t\t\t\t\tawait db.execute(\n\t\t\t\t\t\t\"UPDATE agent_os_fs_entries SET path = ? WHERE path = ?\",\n\t\t\t\t\t\tnewDescPath,\n\t\t\t\t\t\tdesc.path,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Update the entry itself.\n\t\t\tconst now = Date.now();\n\t\t\tawait db.execute(\n\t\t\t\t\"UPDATE agent_os_fs_entries SET path = ?, ctime_ms = ? WHERE path = ?\",\n\t\t\t\tto,\n\t\t\t\tnow,\n\t\t\t\tfrom,\n\t\t\t);\n\t\t},\n\n\t\tasync realpath(p: string): Promise<string> {\n\t\t\tawait rootInit;\n\t\t\tconst path = normPath(p);\n\t\t\tconst entry = await getEntryOrThrow(path);\n\t\t\tif (entry.symlink_target !== null) {\n\t\t\t\treturn normPath(entry.symlink_target);\n\t\t\t}\n\t\t\treturn path;\n\t\t},\n\n\t\tasync symlink(target: string, linkPath: string): Promise<void> {\n\t\t\tawait rootInit;\n\t\t\tconst link = normPath(linkPath);\n\t\t\tawait ensureParentExists(link);\n\n\t\t\tconst existing = await getEntry(link);\n\t\t\tif (existing) {\n\t\t\t\tthrowEEXIST(link);\n\t\t\t}\n\n\t\t\tconst now = Date.now();\n\t\t\tawait db.execute(\n\t\t\t\t`INSERT INTO agent_os_fs_entries (path, is_directory, content, mode, uid, gid, size, atime_ms, mtime_ms, ctime_ms, birthtime_ms, symlink_target, nlink) VALUES (?, 0, NULL, ?, 0, 0, ?, ?, ?, ?, ?, ?, 1)`,\n\t\t\t\tlink,\n\t\t\t\tS_IFLNK | 0o777,\n\t\t\t\ttarget.length,\n\t\t\t\tnow,\n\t\t\t\tnow,\n\t\t\t\tnow,\n\t\t\t\tnow,\n\t\t\t\ttarget,\n\t\t\t);\n\t\t},\n\n\t\tasync readlink(p: string): Promise<string> {\n\t\t\tawait rootInit;\n\t\t\tconst path = normPath(p);\n\t\t\tconst entry = await getEntryOrThrow(path);\n\t\t\tif (entry.symlink_target === null) {\n\t\t\t\tconst err = new Error(`EINVAL: not a symlink: ${path}`);\n\t\t\t\terr.name = \"EINVAL\";\n\t\t\t\tthrow err;\n\t\t\t}\n\t\t\treturn entry.symlink_target;\n\t\t},\n\n\t\tasync lstat(p: string): Promise<VirtualStat> {\n\t\t\t// lstat does not follow symlinks; same as stat for our storage model.\n\t\t\treturn backend.stat(p);\n\t\t},\n\n\t\tasync link(oldPath: string, newPath: string): Promise<void> {\n\t\t\tthrowENOSYS(\"link\");\n\t\t},\n\n\t\tasync chmod(p: string, mode: number): Promise<void> {\n\t\t\tawait rootInit;\n\t\t\tconst path = normPath(p);\n\t\t\tawait getEntryOrThrow(path);\n\t\t\tconst now = Date.now();\n\t\t\tawait db.execute(\n\t\t\t\t\"UPDATE agent_os_fs_entries SET mode = ?, ctime_ms = ? WHERE path = ?\",\n\t\t\t\tmode,\n\t\t\t\tnow,\n\t\t\t\tpath,\n\t\t\t);\n\t\t},\n\n\t\tasync chown(p: string, uid: number, gid: number): Promise<void> {\n\t\t\tawait rootInit;\n\t\t\tconst path = normPath(p);\n\t\t\tawait getEntryOrThrow(path);\n\t\t\tconst now = Date.now();\n\t\t\tawait db.execute(\n\t\t\t\t\"UPDATE agent_os_fs_entries SET uid = ?, gid = ?, ctime_ms = ? WHERE path = ?\",\n\t\t\t\tuid,\n\t\t\t\tgid,\n\t\t\t\tnow,\n\t\t\t\tpath,\n\t\t\t);\n\t\t},\n\n\t\tasync utimes(p: string, atime: number, mtime: number): Promise<void> {\n\t\t\tawait rootInit;\n\t\t\tconst path = normPath(p);\n\t\t\tawait getEntryOrThrow(path);\n\t\t\tconst now = Date.now();\n\t\t\tawait db.execute(\n\t\t\t\t\"UPDATE agent_os_fs_entries SET atime_ms = ?, mtime_ms = ?, ctime_ms = ? WHERE path = ?\",\n\t\t\t\tatime,\n\t\t\t\tmtime,\n\t\t\t\tnow,\n\t\t\t\tpath,\n\t\t\t);\n\t\t},\n\n\t\tasync truncate(p: string, length: number): Promise<void> {\n\t\t\tawait rootInit;\n\t\t\tconst path = normPath(p);\n\t\t\tconst entry = await getEntryOrThrow(path);\n\t\t\tif (entry.is_directory === 1) {\n\t\t\t\tthrowEISDIR(path);\n\t\t\t}\n\n\t\t\tconst existing = entry.content ?? new Uint8Array(0);\n\t\t\tlet newContent: Uint8Array;\n\t\t\tif (length >= existing.byteLength) {\n\t\t\t\t// Extend with zeros.\n\t\t\t\tnewContent = new Uint8Array(length);\n\t\t\t\tnewContent.set(existing);\n\t\t\t} else {\n\t\t\t\t// Truncate.\n\t\t\t\tnewContent = existing.slice(0, length);\n\t\t\t}\n\n\t\t\tconst now = Date.now();\n\t\t\tawait db.execute(\n\t\t\t\t\"UPDATE agent_os_fs_entries SET content = ?, size = ?, mtime_ms = ?, ctime_ms = ? WHERE path = ?\",\n\t\t\t\tnewContent,\n\t\t\t\tlength,\n\t\t\t\tnow,\n\t\t\t\tnow,\n\t\t\t\tpath,\n\t\t\t);\n\t\t},\n\n\t\tasync pread(\n\t\t\tp: string,\n\t\t\toffset: number,\n\t\t\tlength: number,\n\t\t): Promise<Uint8Array> {\n\t\t\tawait rootInit;\n\t\t\tconst path = normPath(p);\n\t\t\tconst entry = await getEntryOrThrow(path);\n\t\t\tif (entry.is_directory === 1) {\n\t\t\t\tthrowEISDIR(path);\n\t\t\t}\n\t\t\tconst content = entry.content ?? new Uint8Array(0);\n\t\t\tconst end = Math.min(offset + length, content.byteLength);\n\t\t\tif (offset >= content.byteLength) {\n\t\t\t\treturn new Uint8Array(0);\n\t\t\t}\n\t\t\treturn content.slice(offset, end);\n\t\t},\n\n\t\tasync pwrite(\n\t\t\tp: string,\n\t\t\toffset: number,\n\t\t\tdata: Uint8Array,\n\t\t): Promise<void> {\n\t\t\tawait rootInit;\n\t\t\tconst path = normPath(p);\n\t\t\tconst entry = await getEntryOrThrow(path);\n\t\t\tif (entry.is_directory === 1) {\n\t\t\t\tthrowEISDIR(path);\n\t\t\t}\n\t\t\tconst content = entry.content ?? new Uint8Array(0);\n\t\t\tconst end = offset + data.byteLength;\n\t\t\tconst newSize = Math.max(content.byteLength, end);\n\t\t\tconst buf = new Uint8Array(newSize);\n\t\t\tbuf.set(content);\n\t\t\tbuf.set(data, offset);\n\t\t\tconst now = Date.now();\n\t\t\tawait db.execute(\n\t\t\t\t`UPDATE agent_os_fs_entries SET content = ?, size = ?, mtime_ms = ?, ctime_ms = ? WHERE path = ?`,\n\t\t\t\tbuf,\n\t\t\t\tnewSize,\n\t\t\t\tnow,\n\t\t\t\tnow,\n\t\t\t\tpath,\n\t\t\t);\n\t\t},\n\t};\n\n\treturn backend;\n}\n","import { AgentOs, createInMemoryFileSystem } from \"@rivet-dev/agent-os-core\";\nimport type { AgentOsOptions, MountConfig } from \"@rivet-dev/agent-os-core\";\nimport type { DatabaseProvider } from \"@/common/database/config\";\nimport { actor, event } from \"@/actor/mod\";\nimport type { RawAccess } from \"@/common/database/config\";\nimport { db } from \"@/common/database/mod\";\nimport {\n\ttype AgentOsActorConfig,\n\ttype AgentOsActorConfigInput,\n\tagentOsActorConfigSchema,\n} from \"../config\";\nimport type {\n\tAgentOsActionContext,\n\tAgentOsActorState,\n\tAgentOsActorVars,\n\tCronEventPayload,\n\tPermissionRequestPayload,\n\tProcessExitPayload,\n\tProcessOutputPayload,\n\tSessionEventPayload,\n\tShellDataPayload,\n\tVmBootedPayload,\n\tVmShutdownPayload,\n} from \"../types\";\nimport { buildCronActions } from \"./cron\";\nimport { migrateAgentOsTables } from \"./db\";\nimport { buildFilesystemActions } from \"./filesystem\";\nimport { buildNetworkActions } from \"./network\";\nimport { buildOnRequestHandler, buildPreviewActions } from \"./preview\";\nimport { buildProcessActions } from \"./process\";\nimport {\n\tbuildConfigActions,\n\tbuildPromptActions,\n\tbuildSessionActions,\n\tbuildSessionPersistenceActions,\n} from \"./session\";\nimport { buildShellActions } from \"./shell\";\n\n// --- VM lifecycle helpers ---\n\nasync function ensureVm<TConnParams>(\n\tc: AgentOsActionContext<TConnParams>,\n\tconfig: AgentOsActorConfig<TConnParams>,\n): Promise<AgentOs> {\n\tif (c.vars.agentOs) {\n\t\treturn c.vars.agentOs;\n\t}\n\n\tconst start = Date.now();\n\n\t// Build options with in-memory VFS as default working directory mount.\n\tconst options = buildVmOptions(config.options);\n\n\tconst agentOs = await AgentOs.create(options);\n\tc.vars.agentOs = agentOs;\n\n\t// Wire cron events to actor events.\n\tagentOs.onCronEvent((cronEvent) => {\n\t\tc.broadcast(\"cronEvent\", { event: cronEvent });\n\t});\n\n\tc.broadcast(\"vmBooted\", {});\n\tc.log.info({\n\t\tmsg: \"agent-os vm booted\",\n\t\tbootDurationMs: Date.now() - start,\n\t});\n\n\treturn agentOs;\n}\n\nfunction buildVmOptions(userOptions?: AgentOsOptions): AgentOsOptions {\n\tconst userMounts = userOptions?.mounts ?? [];\n\n\t// Check if the user already provided a mount at /home/user. If so, respect\n\t// their override and skip the default in-memory VFS mount.\n\tconst hasWorkdirMount = userMounts.some(\n\t\t(m: MountConfig) => m.path === \"/home/user\",\n\t);\n\n\tif (hasWorkdirMount) {\n\t\treturn userOptions ?? {};\n\t}\n\n\t// TODO: Reimplement with persistent backend (actor KV-backed metadata +\n\t// actor storage-backed blocks) so VM filesystem state survives sleep/wake.\n\tconst memMount: MountConfig = {\n\t\tpath: \"/home/user\",\n\t\tdriver: createInMemoryFileSystem(),\n\t};\n\n\treturn {\n\t\t...userOptions,\n\t\tmounts: [memMount, ...userMounts],\n\t};\n}\n\n// --- Prevent-sleep coordination ---\n\nfunction syncPreventSleep<TConnParams>(\n\tc: AgentOsActionContext<TConnParams>,\n): void {\n\tconst shouldPrevent =\n\t\tc.vars.activeSessionIds.size > 0 ||\n\t\tc.vars.activeProcesses.size > 0 ||\n\t\tc.vars.activeHooks.size > 0 ||\n\t\tc.vars.activeShells.size > 0;\n\n\tc.setPreventSleep(shouldPrevent);\n\n\tc.log.info({\n\t\tmsg: \"agent-os prevent sleep sync\",\n\t\tpreventSleep: shouldPrevent,\n\t\tactiveSessions: c.vars.activeSessionIds.size,\n\t\tactiveProcesses: c.vars.activeProcesses.size,\n\t\tactiveHooks: c.vars.activeHooks.size,\n\t\tactiveShells: c.vars.activeShells.size,\n\t});\n}\n\n// --- Hook tracking ---\n\nfunction runHook<TConnParams>(\n\tc: AgentOsActionContext<TConnParams>,\n\tname: string,\n\tcallback: () => void | Promise<void>,\n): void {\n\tconst promise = Promise.resolve(callback())\n\t\t.catch((error) =>\n\t\t\tc.log.error({ msg: \"agent-os hook failed\", hookName: name, error }),\n\t\t)\n\t\t.finally(() => {\n\t\t\tc.vars.activeHooks.delete(promise);\n\t\t\tsyncPreventSleep(c);\n\t\t});\n\tc.vars.activeHooks.add(promise);\n\tsyncPreventSleep(c);\n\tc.waitUntil(promise);\n}\n\n// --- Public API ---\n\nexport function agentOs<TConnParams = undefined>(\n\tconfig: AgentOsActorConfigInput<TConnParams>,\n) {\n\tconst parsedConfig = agentOsActorConfigSchema.parse(\n\t\tconfig,\n\t) as AgentOsActorConfig<TConnParams>;\n\n\treturn actor<\n\t\tAgentOsActorState,\n\t\tTConnParams,\n\t\tundefined,\n\t\tAgentOsActorVars,\n\t\tundefined,\n\t\tDatabaseProvider<RawAccess>,\n\t\t{\n\t\t\tsessionEvent: typeof sessionEventToken;\n\t\t\tpermissionRequest: typeof permissionRequestToken;\n\t\t\tvmBooted: typeof vmBootedToken;\n\t\t\tvmShutdown: typeof vmShutdownToken;\n\t\t\tprocessOutput: typeof processOutputToken;\n\t\t\tprocessExit: typeof processExitToken;\n\t\t\tshellData: typeof shellDataToken;\n\t\t\tcronEvent: typeof cronEventToken;\n\t\t},\n\t\tRecord<never, never>\n\t>({\n\t\toptions: {\n\t\t\tsleepGracePeriod: 900_000,\n\t\t\tactionTimeout: 900_000,\n\t\t},\n\t\tcreateState: async () => ({}),\n\t\tcreateVars: () => ({\n\t\t\tagentOs: null,\n\t\t\tactiveSessionIds: new Set<string>(),\n\t\t\tactiveProcesses: new Set<number>(),\n\t\t\tactiveHooks: new Set<Promise<void>>(),\n\t\t\tactiveShells: new Set<string>(),\n\t\t\tsessions: new Set(),\n\t\t}),\n\t\tdb: db({\n\t\t\tonMigrate: migrateAgentOsTables,\n\t\t}),\n\t\tevents: {\n\t\t\tsessionEvent: sessionEventToken,\n\t\t\tpermissionRequest: permissionRequestToken,\n\t\t\tvmBooted: vmBootedToken,\n\t\t\tvmShutdown: vmShutdownToken,\n\t\t\tprocessOutput: processOutputToken,\n\t\t\tprocessExit: processExitToken,\n\t\t\tshellData: shellDataToken,\n\t\t\tcronEvent: cronEventToken,\n\t\t},\n\t\tonBeforeConnect: parsedConfig.onBeforeConnect\n\t\t\t? async (ctx, params) => {\n\t\t\t\t\t// Skip user auth for preview URL requests. The signed token\n\t\t\t\t\t// in onRequest is the credential; browsers navigating preview\n\t\t\t\t\t// URLs cannot supply actor connection params.\n\t\t\t\t\tif (ctx.request) {\n\t\t\t\t\t\tconst url = new URL(ctx.request.url);\n\t\t\t\t\t\tif (url.pathname.startsWith(\"/fetch/\")) {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tawait parsedConfig.onBeforeConnect?.(ctx, params);\n\t\t\t\t}\n\t\t\t: undefined,\n\t\tonRequest: buildOnRequestHandler(parsedConfig),\n\t\tonSleep: async (c) => {\n\t\t\tc.log.info({\n\t\t\t\tmsg: \"agent-os vm shutdown for sleep\",\n\t\t\t\tactiveSessions: c.vars.sessions.size,\n\t\t\t\tactiveProcesses: c.vars.activeProcesses.size,\n\t\t\t\tactiveShells: c.vars.activeShells.size,\n\t\t\t});\n\n\t\t\tif (c.vars.agentOs) {\n\t\t\t\tawait c.vars.agentOs.dispose();\n\t\t\t\tc.vars.agentOs = null;\n\t\t\t}\n\n\t\t\tc.broadcast(\"vmShutdown\", { reason: \"sleep\" as const });\n\t\t},\n\t\tonDestroy: async (c) => {\n\t\t\tc.log.info({\n\t\t\t\tmsg: \"agent-os vm shutdown for destroy\",\n\t\t\t\tactiveSessions: c.vars.sessions.size,\n\t\t\t\tactiveProcesses: c.vars.activeProcesses.size,\n\t\t\t\tactiveShells: c.vars.activeShells.size,\n\t\t\t});\n\n\t\t\tif (c.vars.agentOs) {\n\t\t\t\tawait c.vars.agentOs.dispose();\n\t\t\t\tc.vars.agentOs = null;\n\t\t\t}\n\n\t\t\tc.broadcast(\"vmShutdown\", { reason: \"destroy\" as const });\n\t\t},\n\t\tactions: {\n\t\t\t...buildSessionActions(parsedConfig),\n\t\t\t...buildPromptActions(parsedConfig),\n\t\t\t...buildConfigActions(parsedConfig),\n\t\t\t...buildSessionPersistenceActions(parsedConfig),\n\t\t\t...buildProcessActions(parsedConfig),\n\t\t\t...buildFilesystemActions(parsedConfig),\n\t\t\t...buildPreviewActions(parsedConfig),\n\t\t\t...buildShellActions(parsedConfig),\n\t\t\t...buildCronActions(parsedConfig),\n\t\t\t...buildNetworkActions(parsedConfig),\n\t\t},\n\t});\n}\n\n// Event type tokens. Declared at module level so they can be referenced in\n// the actor generic type parameters.\nconst sessionEventToken = event<SessionEventPayload>();\nconst permissionRequestToken = event<PermissionRequestPayload>();\nconst vmBootedToken = event<VmBootedPayload>();\nconst vmShutdownToken = event<VmShutdownPayload>();\nconst processOutputToken = event<ProcessOutputPayload>();\nconst processExitToken = event<ProcessExitPayload>();\nconst shellDataToken = event<ShellDataPayload>();\nconst cronEventToken = event<CronEventPayload>();\n\nexport { ensureVm, syncPreventSleep, runHook };\n","import { z } from \"zod/v4\";\nimport type { UniversalWebSocket } from \"@/common/websocket-interface\";\nimport type {\n\tAnyDatabaseProvider,\n\tInferDatabaseClient,\n\tRawDatabaseClient,\n\tDrizzleDatabaseClient,\n\tNativeDatabaseProvider,\n} from \"@/common/database/config\";\nimport type { Client } from \"@/client/client\";\nimport type { Registry } from \"@/registry\";\nimport type { BaseActorDefinition } from \"./definition\";\nimport type {\n\tEventSchemaConfig,\n\tPrimitiveSchema,\n\tQueueSchemaConfig,\n} from \"./schema\";\nimport type {\n\tInferEventArgs,\n\tInferQueueCompleteMap,\n\tInferSchemaMap,\n} from \"./schema\";\n\nexport const DEFAULT_SLEEP_GRACE_PERIOD = 15_000;\n\nexport const ACTOR_CONTEXT_INTERNAL_SYMBOL = Symbol(\n\t\"rivetkit.actor_context_internal\",\n);\nexport const CONN_DRIVER_SYMBOL = Symbol(\"rivetkit.conn_driver\");\nexport const CONN_STATE_MANAGER_SYMBOL = Symbol(\"rivetkit.conn_state_manager\");\n\nexport interface ActorLogger {\n\tlevel: any;\n\tfatal: any;\n\ttrace: any;\n\tsilent: any;\n\tmsgPrefix: any;\n\tdebug: any;\n\tinfo: any;\n\twarn: any;\n\terror: any;\n\t[key: string]: any;\n}\n\ntype ActorKvValueType = \"text\" | \"arrayBuffer\" | \"binary\";\ntype ActorKvKeyType = \"text\" | \"binary\";\ntype ActorKvValueTypeMap = {\n\ttext: string;\n\tarrayBuffer: ArrayBuffer;\n\tbinary: Uint8Array;\n};\ntype ActorKvKeyTypeMap = {\n\ttext: string;\n\tbinary: Uint8Array;\n};\ntype ActorKvValueOptions<T extends ActorKvValueType = \"text\"> = {\n\ttype?: T;\n};\ntype ActorKvListOptions<\n\tT extends ActorKvValueType = \"text\",\n\tK extends ActorKvKeyType = \"text\",\n> = ActorKvValueOptions<T> & {\n\tkeyType?: K;\n\treverse?: boolean;\n\tlimit?: number;\n};\n\ntype ActorClientFor<T> = T extends Registry<any> ? Client<T> : T;\n\nexport interface ActorKv {\n\tget<T extends ActorKvValueType = \"text\">(\n\t\tkey: Uint8Array | string,\n\t\toptions?: ActorKvValueOptions<T>,\n\t): Promise<ActorKvValueTypeMap[T] | null>;\n\tput<T extends ActorKvValueType = \"text\">(\n\t\tkey: Uint8Array | string,\n\t\tvalue: Uint8Array | string | ArrayBuffer,\n\t\toptions?: ActorKvValueOptions<T>,\n\t): Promise<void>;\n\tdelete(key: Uint8Array | string): Promise<void>;\n\tbatchPut(entries: [Uint8Array, Uint8Array][]): Promise<void>;\n\tbatchGet(keys: Uint8Array[]): Promise<(Uint8Array | null)[]>;\n\tbatchDelete(keys: Uint8Array[]): Promise<void>;\n\tdeleteRange(start: Uint8Array, end: Uint8Array): Promise<void>;\n\tlistPrefix<\n\t\tT extends ActorKvValueType = \"text\",\n\t\tK extends ActorKvKeyType = \"text\",\n\t>(\n\t\tprefix: Uint8Array | string,\n\t\toptions?: ActorKvListOptions<T, K>,\n\t): Promise<Array<[ActorKvKeyTypeMap[K], ActorKvValueTypeMap[T]]>>;\n\tlistRange<\n\t\tT extends ActorKvValueType = \"text\",\n\t\tK extends ActorKvKeyType = \"text\",\n\t>(\n\t\tstart: Uint8Array | string,\n\t\tend: Uint8Array | string,\n\t\toptions?: ActorKvListOptions<T, K>,\n\t): Promise<Array<[ActorKvKeyTypeMap[K], ActorKvValueTypeMap[T]]>>;\n\tlist<T extends ActorKvValueType = \"text\", K extends ActorKvKeyType = \"text\">(\n\t\tprefix: Uint8Array | string,\n\t\toptions?: ActorKvListOptions<T, K>,\n\t): Promise<Array<[ActorKvKeyTypeMap[K], ActorKvValueTypeMap[T]]>>;\n\t[key: string]: any;\n}\n\nexport interface ActorSchedule {\n\tafter(duration: number, action: string, ...args: unknown[]): Promise<void>;\n\tat(timestamp: number, action: string, ...args: unknown[]): Promise<void>;\n\t[key: string]: any;\n}\n\nexport type QueueMessageOf<Name extends string, Body> = {\n\tid: number | bigint;\n\tname: Name;\n\tbody: Body;\n\tcreatedAt: number;\n\t[key: string]: unknown;\n};\n\nexport type QueueName<TQueues extends QueueSchemaConfig> = keyof TQueues & string;\nexport type QueueFilterName<TQueues extends QueueSchemaConfig> =\n\tkeyof TQueues extends never ? string : QueueName<TQueues>;\n\ntype QueueMessageForName<\n\tTQueues extends QueueSchemaConfig,\n\tTName extends QueueFilterName<TQueues>,\n> = keyof TQueues extends never\n\t? QueueMessageOf<string, unknown>\n\t: TName extends QueueName<TQueues>\n\t\t? QueueMessageOf<TName, InferSchemaMap<TQueues>[TName]>\n\t\t: never;\n\ntype QueueCompleteArgs<T> = undefined extends T\n\t? [response?: T]\n\t: [response: T];\n\ntype QueueCompleteArgsForName<\n\tTQueues extends QueueSchemaConfig,\n\tTName extends QueueFilterName<TQueues>,\n> = keyof TQueues extends never\n\t? [response?: unknown]\n\t: TName extends QueueName<TQueues>\n\t\t? [InferQueueCompleteMap<TQueues>[TName]] extends [never]\n\t\t\t? [response?: unknown]\n\t\t\t: QueueCompleteArgs<InferQueueCompleteMap<TQueues>[TName]>\n\t\t: [response?: unknown];\n\ntype QueueCompletableMessageForName<\n\tTQueues extends QueueSchemaConfig,\n\tTName extends QueueFilterName<TQueues>,\n> = QueueMessageForName<TQueues, TName> & {\n\tcomplete(...args: QueueCompleteArgsForName<TQueues, TName>): Promise<void>;\n};\n\ntype QueueCompletionResultForName<\n\tTQueues extends QueueSchemaConfig,\n\tTName extends QueueFilterName<TQueues>,\n> = keyof TQueues extends never\n\t? unknown | undefined\n\t: TName extends QueueName<TQueues>\n\t\t? InferQueueCompleteMap<TQueues>[TName] | undefined\n\t\t: unknown | undefined;\n\nexport type QueueResultMessageForName<\n\tTQueues extends QueueSchemaConfig,\n\tTName extends QueueFilterName<TQueues>,\n\tTCompletable extends boolean,\n> = TCompletable extends true\n\t? QueueCompletableMessageForName<TQueues, TName>\n\t: QueueMessageForName<TQueues, TName>;\n\nexport interface QueueNextOptions<\n\tTName extends string = string,\n\tTCompletable extends boolean = boolean,\n> {\n\tnames?: readonly TName[];\n\ttimeout?: number;\n\tsignal?: AbortSignal;\n\tcompletable?: TCompletable;\n}\n\nexport interface QueueNextBatchOptions<\n\tTName extends string = string,\n\tTCompletable extends boolean = boolean,\n> {\n\tnames?: readonly TName[];\n\tcount?: number;\n\ttimeout?: number;\n\tsignal?: AbortSignal;\n\tcompletable?: TCompletable;\n}\n\nexport interface QueueWaitOptions<TCompletable extends boolean = boolean> {\n\ttimeout?: number;\n\tsignal?: AbortSignal;\n\tcompletable?: TCompletable;\n}\n\nexport interface QueueEnqueueAndWaitOptions {\n\ttimeout?: number;\n\tsignal?: AbortSignal;\n}\n\nexport interface QueueTryNextOptions<\n\tTName extends string = string,\n\tTCompletable extends boolean = boolean,\n> {\n\tnames?: readonly TName[];\n\tcompletable?: TCompletable;\n}\n\nexport interface QueueTryNextBatchOptions<\n\tTName extends string = string,\n\tTCompletable extends boolean = boolean,\n> {\n\tnames?: readonly TName[];\n\tcount?: number;\n\tcompletable?: TCompletable;\n}\n\nexport interface QueueIterOptions<\n\tTName extends string = string,\n\tTCompletable extends boolean = boolean,\n> {\n\tnames?: readonly TName[];\n\tsignal?: AbortSignal;\n\tcompletable?: TCompletable;\n}\n\nexport interface ActorQueue<TQueues extends QueueSchemaConfig = Record<never, never>> {\n\tsend<TName extends QueueFilterName<TQueues>>(\n\t\tname: TName,\n\t\tbody: QueueMessageForName<TQueues, TName>[\"body\"],\n\t): Promise<any>;\n\tnext<\n\t\tconst TName extends QueueFilterName<TQueues>,\n\t\tconst TCompletable extends boolean = false,\n\t>(\n\t\topts?: QueueNextOptions<TName, TCompletable>,\n\t): Promise<any>;\n\tnextBatch<\n\t\tconst TName extends QueueFilterName<TQueues>,\n\t\tconst TCompletable extends boolean = false,\n\t>(\n\t\topts?: QueueNextBatchOptions<TName, TCompletable>,\n\t): Promise<any[]>;\n\twaitForNames<\n\t\tconst TName extends QueueFilterName<TQueues>,\n\t\tconst TCompletable extends boolean = false,\n\t>(\n\t\tnames: readonly TName[],\n\t\topts?: QueueWaitOptions<TCompletable>,\n\t): Promise<any>;\n\tenqueueAndWait<const TName extends QueueFilterName<TQueues>>(\n\t\tname: TName,\n\t\tbody: QueueMessageForName<TQueues, TName>[\"body\"],\n\t\topts?: QueueEnqueueAndWaitOptions,\n\t): Promise<QueueCompletionResultForName<TQueues, TName>>;\n\ttryNext<\n\t\tconst TName extends QueueFilterName<TQueues>,\n\t\tconst TCompletable extends boolean = false,\n\t>(\n\t\topts?: QueueTryNextOptions<TName, TCompletable>,\n\t): Promise<any>;\n\ttryNextBatch<\n\t\tconst TName extends QueueFilterName<TQueues>,\n\t\tconst TCompletable extends boolean = false,\n\t>(\n\t\topts?: QueueTryNextBatchOptions<TName, TCompletable>,\n\t): Promise<any[]>;\n\titer<\n\t\tconst TName extends QueueFilterName<TQueues>,\n\t\tconst TCompletable extends boolean = false,\n\t>(\n\t\topts?: QueueIterOptions<TName, TCompletable>,\n\t): AsyncIterable<any>;\n\t[key: string]: any;\n}\n\nexport interface Conn<\n\tTState = unknown,\n\tTConnParams = unknown,\n\tTConnState = unknown,\n\tTVars = unknown,\n\tTInput = unknown,\n\tTDatabase extends AnyDatabaseProvider = AnyDatabaseProvider,\n\tTEvents extends EventSchemaConfig = Record<never, never>,\n\tTQueues extends QueueSchemaConfig = Record<never, never>,\n> {\n\tid: string;\n\tparams: TConnParams;\n\tstate: TConnState;\n\tisHibernatable: boolean;\n\tsend(name: string, ...args: any[]): void;\n\tdisconnect(reason?: string): Promise<void>;\n\t[key: string]: any;\n}\n\nexport type AnyConn = Conn<any, any, any, any, any, any, any, any>;\n\nexport interface ActorContext<\n\tTState,\n\tTConnParams,\n\tTConnState,\n\tTVars,\n\tTInput,\n\tTDatabase extends AnyDatabaseProvider,\n\tTEvents extends EventSchemaConfig = Record<never, never>,\n\tTQueues extends QueueSchemaConfig = Record<never, never>,\n> {\n\t[ACTOR_CONTEXT_INTERNAL_SYMBOL]?: unknown;\n\tstate: TState;\n\tvars: TVars;\n\treadonly kv: ActorKv;\n\treadonly db: InferDatabaseClient<TDatabase>;\n\treadonly schedule: ActorSchedule;\n\treadonly queue: ActorQueue<TQueues>;\n\treadonly actorId: string;\n\treadonly name: string;\n\treadonly key: string[];\n\treadonly region: string;\n\treadonly conns: Map<string, Conn<TState, TConnParams, TConnState, TVars, TInput, TDatabase, TEvents, TQueues>>;\n\treadonly log: ActorLogger;\n\treadonly abortSignal: AbortSignal;\n\treadonly aborted: boolean;\n\treadonly request?: Request;\n\t/** @deprecated No-op. Always returns `false`. Use `keepAwake(promise)` or `waitUntil(promise)` instead. Will be removed in 2.2.0. */\n\treadonly preventSleep: boolean;\n\tbroadcast(name: string, ...args: any[]): void;\n\tsaveState(opts?: { immediate?: boolean; maxWait?: number }): Promise<void>;\n\tkeepAwake<T>(promise: Promise<T>): Promise<T>;\n\twaitUntil(promise: Promise<unknown>): void;\n\t/** @deprecated No-op. Use `keepAwake(promise)` to hold the actor awake for a specific promise. Will be removed in 2.2.0. */\n\tsetPreventSleep(preventSleep: boolean): void;\n\tsleep(): void;\n\tdestroy(): void;\n\tclient<T = any>(): ActorClientFor<T>;\n\t[key: string]: any;\n}\n\nexport type ActionContext<\n\tTState,\n\tTConnParams,\n\tTConnState,\n\tTVars,\n\tTInput,\n\tTDatabase extends AnyDatabaseProvider,\n\tTEvents extends EventSchemaConfig = Record<never, never>,\n\tTQueues extends QueueSchemaConfig = Record<never, never>,\n> = ActorContext<\n\tTState,\n\tTConnParams,\n\tTConnState,\n\tTVars,\n\tTInput,\n\tTDatabase,\n\tTEvents,\n\tTQueues\n> & {\n\tconn: Conn<\n\t\tTState,\n\t\tTConnParams,\n\t\tTConnState,\n\t\tTVars,\n\t\tTInput,\n\t\tTDatabase,\n\t\tTEvents,\n\t\tTQueues\n\t>;\n};\n\nexport type BeforeActionResponseContext<\n\tTState,\n\tTConnParams,\n\tTConnState,\n\tTVars,\n\tTInput,\n\tTDatabase extends AnyDatabaseProvider,\n\tTEvents extends EventSchemaConfig = Record<never, never>,\n\tTQueues extends QueueSchemaConfig = Record<never, never>,\n> = ActionContext<\n\tTState,\n\tTConnParams,\n\tTConnState,\n\tTVars,\n\tTInput,\n\tTDatabase,\n\tTEvents,\n\tTQueues\n>;\n\nexport type BeforeConnectContext<\n\tTState,\n\tTVars,\n\tTInput,\n\tTDatabase extends AnyDatabaseProvider,\n\tTEvents extends EventSchemaConfig = Record<never, never>,\n\tTQueues extends QueueSchemaConfig = Record<never, never>,\n> = ActorContext<\n\tTState,\n\tunknown,\n\tunknown,\n\tTVars,\n\tTInput,\n\tTDatabase,\n\tTEvents,\n\tTQueues\n>;\n\nexport type ConnectContext<\n\tTState,\n\tTConnParams,\n\tTConnState,\n\tTVars,\n\tTInput,\n\tTDatabase extends AnyDatabaseProvider,\n\tTEvents extends EventSchemaConfig = Record<never, never>,\n\tTQueues extends QueueSchemaConfig = Record<never, never>,\n> = ActionContext<\n\tTState,\n\tTConnParams,\n\tTConnState,\n\tTVars,\n\tTInput,\n\tTDatabase,\n\tTEvents,\n\tTQueues\n>;\n\nexport type CreateConnStateContext<\n\tTState,\n\tTVars,\n\tTInput,\n\tTDatabase extends AnyDatabaseProvider,\n\tTEvents extends EventSchemaConfig = Record<never, never>,\n\tTQueues extends QueueSchemaConfig = Record<never, never>,\n> = ActorContext<\n\tTState,\n\tunknown,\n\tunknown,\n\tTVars,\n\tTInput,\n\tTDatabase,\n\tTEvents,\n\tTQueues\n>;\n\nexport type CreateContext<\n\tTState,\n\tTInput,\n\tTDatabase extends AnyDatabaseProvider,\n\tTEvents extends EventSchemaConfig = Record<never, never>,\n\tTQueues extends QueueSchemaConfig = Record<never, never>,\n> = ActorContext<\n\tTState,\n\tunknown,\n\tunknown,\n\tunknown,\n\tTInput,\n\tTDatabase,\n\tTEvents,\n\tTQueues\n>;\n\nexport type CreateVarsContext<\n\tTState,\n\tTInput,\n\tTDatabase extends AnyDatabaseProvider,\n\tTEvents extends EventSchemaConfig = Record<never, never>,\n\tTQueues extends QueueSchemaConfig = Record<never, never>,\n> = CreateContext<TState, TInput, TDatabase, TEvents, TQueues>;\n\nexport type DestroyContext<\n\tTState,\n\tTConnParams,\n\tTConnState,\n\tTVars,\n\tTInput,\n\tTDatabase extends AnyDatabaseProvider,\n\tTEvents extends EventSchemaConfig = Record<never, never>,\n\tTQueues extends QueueSchemaConfig = Record<never, never>,\n> = ActorContext<\n\tTState,\n\tTConnParams,\n\tTConnState,\n\tTVars,\n\tTInput,\n\tTDatabase,\n\tTEvents,\n\tTQueues\n>;\n\nexport type DisconnectContext<\n\tTState,\n\tTConnParams,\n\tTConnState,\n\tTVars,\n\tTInput,\n\tTDatabase extends AnyDatabaseProvider,\n\tTEvents extends EventSchemaConfig = Record<never, never>,\n\tTQueues extends QueueSchemaConfig = Record<never, never>,\n> = ActionContext<\n\tTState,\n\tTConnParams,\n\tTConnState,\n\tTVars,\n\tTInput,\n\tTDatabase,\n\tTEvents,\n\tTQueues\n>;\n\nexport type RequestContext<\n\tTState,\n\tTConnParams,\n\tTConnState,\n\tTVars,\n\tTInput,\n\tTDatabase extends AnyDatabaseProvider,\n\tTEvents extends EventSchemaConfig = Record<never, never>,\n\tTQueues extends QueueSchemaConfig = Record<never, never>,\n> = ActionContext<\n\tTState,\n\tTConnParams,\n\tTConnState,\n\tTVars,\n\tTInput,\n\tTDatabase,\n\tTEvents,\n\tTQueues\n>;\n\nexport type RunContext<\n\tTState,\n\tTConnParams,\n\tTConnState,\n\tTVars,\n\tTInput,\n\tTDatabase extends AnyDatabaseProvider,\n\tTEvents extends EventSchemaConfig = Record<never, never>,\n\tTQueues extends QueueSchemaConfig = Record<never, never>,\n> = ActorContext<\n\tTState,\n\tTConnParams,\n\tTConnState,\n\tTVars,\n\tTInput,\n\tTDatabase,\n\tTEvents,\n\tTQueues\n>;\n\nexport type SleepContext<\n\tTState,\n\tTConnParams,\n\tTConnState,\n\tTVars,\n\tTInput,\n\tTDatabase extends AnyDatabaseProvider,\n\tTEvents extends EventSchemaConfig = Record<never, never>,\n\tTQueues extends QueueSchemaConfig = Record<never, never>,\n> = RunContext<\n\tTState,\n\tTConnParams,\n\tTConnState,\n\tTVars,\n\tTInput,\n\tTDatabase,\n\tTEvents,\n\tTQueues\n>;\n\nexport type StateChangeContext<\n\tTState,\n\tTConnParams,\n\tTConnState,\n\tTVars,\n\tTInput,\n\tTDatabase extends AnyDatabaseProvider,\n\tTEvents extends EventSchemaConfig = Record<never, never>,\n\tTQueues extends QueueSchemaConfig = Record<never, never>,\n> = RunContext<\n\tTState,\n\tTConnParams,\n\tTConnState,\n\tTVars,\n\tTInput,\n\tTDatabase,\n\tTEvents,\n\tTQueues\n>;\n\nexport type WakeContext<\n\tTState,\n\tTConnParams,\n\tTConnState,\n\tTVars,\n\tTInput,\n\tTDatabase extends AnyDatabaseProvider,\n\tTEvents extends EventSchemaConfig = Record<never, never>,\n\tTQueues extends QueueSchemaConfig = Record<never, never>,\n> = RunContext<\n\tTState,\n\tTConnParams,\n\tTConnState,\n\tTVars,\n\tTInput,\n\tTDatabase,\n\tTEvents,\n\tTQueues\n>;\n\nexport type MigrateContext<\n\tTState,\n\tTConnParams,\n\tTConnState,\n\tTVars,\n\tTInput,\n\tTDatabase extends AnyDatabaseProvider,\n\tTEvents extends EventSchemaConfig = Record<never, never>,\n\tTQueues extends QueueSchemaConfig = Record<never, never>,\n> = WakeContext<\n\tTState,\n\tTConnParams,\n\tTConnState,\n\tTVars,\n\tTInput,\n\tTDatabase,\n\tTEvents,\n\tTQueues\n>;\n\nexport type WebSocketContext<\n\tTState,\n\tTConnParams,\n\tTConnState,\n\tTVars,\n\tTInput,\n\tTDatabase extends AnyDatabaseProvider,\n\tTEvents extends EventSchemaConfig = Record<never, never>,\n\tTQueues extends QueueSchemaConfig = Record<never, never>,\n> = ActionContext<\n\tTState,\n\tTConnParams,\n\tTConnState,\n\tTVars,\n\tTInput,\n\tTDatabase,\n\tTEvents,\n\tTQueues\n>;\n\nexport type ActorContextOf<AD extends BaseActorDefinition<any, any, any, any, any, any, any, any, any>> =\n\tAD extends BaseActorDefinition<\n\t\tinfer TState,\n\t\tinfer TConnParams,\n\t\tinfer TConnState,\n\t\tinfer TVars,\n\t\tinfer TInput,\n\t\tinfer TDatabase,\n\t\tinfer TEvents,\n\t\tinfer TQueues,\n\t\tany\n\t>\n\t\t? ActorContext<\n\t\t\t\tTState,\n\t\t\t\tTConnParams,\n\t\t\t\tTConnState,\n\t\t\t\tTVars,\n\t\t\t\tTInput,\n\t\t\t\tTDatabase,\n\t\t\t\tTEvents,\n\t\t\t\tTQueues\n\t\t\t>\n\t\t: never;\n\nexport interface ActorTypes<\n\tTState,\n\tTConnParams,\n\tTConnState,\n\tTVars,\n\tTInput,\n\tTDatabase extends AnyDatabaseProvider,\n> {\n\tstate?: TState;\n\tconnParams?: TConnParams;\n\tconnState?: TConnState;\n\tvars?: TVars;\n\tinput?: TInput;\n\tdatabase?: TDatabase;\n}\n\n// Helper for validating function types - accepts generic for specific function signatures\nconst zFunction = <\n\tT extends (...args: any[]) => any = (...args: unknown[]) => unknown,\n>() => z.custom<T>((val) => typeof val === \"function\");\n\nexport type InspectorUnsubscribe = () => void;\n\nexport interface WorkflowInspectorConfig<THistory = unknown> {\n\tgetHistory: () => THistory | null;\n\tonHistoryUpdated?: (\n\t\tlistener: (history: THistory) => void,\n\t) => InspectorUnsubscribe;\n\treplayFromStep?: (entryId?: string) => Promise<THistory | null>;\n}\n\nexport interface RunInspectorConfig<THistory = unknown> {\n\tworkflow?: WorkflowInspectorConfig<THistory>;\n}\n\nconst WorkflowInspectorConfigSchema = z.object({\n\tgetHistory: zFunction<WorkflowInspectorConfig<unknown>[\"getHistory\"]>(),\n\tonHistoryUpdated:\n\t\tzFunction<\n\t\t\tNonNullable<WorkflowInspectorConfig<unknown>[\"onHistoryUpdated\"]>\n\t\t>().optional(),\n\treplayFromStep:\n\t\tzFunction<\n\t\t\tNonNullable<WorkflowInspectorConfig<unknown>[\"replayFromStep\"]>\n\t\t>().optional(),\n});\n\nconst RunInspectorConfigSchema = z\n\t.object({\n\t\tworkflow: WorkflowInspectorConfigSchema.optional(),\n\t})\n\t.optional();\n\n// Schema for run handler with metadata\nexport const RunConfigSchema = z.object({\n\t/** Display name for the actor in the Inspector UI. */\n\tname: z.string().optional(),\n\t/** Icon for the actor in the Inspector UI. Can be an emoji or FontAwesome icon name. */\n\ticon: z.string().optional(),\n\t/** The run handler function. */\n\trun: zFunction(),\n\t/** Inspector integration for long-running run handlers. */\n\tinspector: RunInspectorConfigSchema.optional(),\n});\ntype RunConfigRuntime = z.infer<typeof RunConfigSchema>;\nexport type RunConfig<\n\tTState = unknown,\n\tTConnParams = unknown,\n\tTConnState = unknown,\n\tTVars = unknown,\n\tTInput = unknown,\n\tTDatabase extends AnyDatabaseProvider = AnyDatabaseProvider,\n\tTEvents extends EventSchemaConfig = Record<never, never>,\n\tTQueues extends QueueSchemaConfig = Record<never, never>,\n> = Omit<RunConfigRuntime, \"run\"> & {\n\trun: (\n\t\tc: RunContext<\n\t\t\tTState,\n\t\t\tTConnParams,\n\t\t\tTConnState,\n\t\t\tTVars,\n\t\t\tTInput,\n\t\t\tTDatabase,\n\t\t\tTEvents,\n\t\t\tTQueues\n\t\t>,\n\t) => void | Promise<void>;\n};\n\ntype AnyRunConfig = RunConfig<\n\tany,\n\tany,\n\tany,\n\tany,\n\tany,\n\tAnyDatabaseProvider,\n\tany,\n\tany\n>;\n\nexport const RUN_FUNCTION_CONFIG_SYMBOL = Symbol.for(\n\t\"rivetkit.run_function_config\",\n);\n\ninterface RunFunctionConfig {\n\tname?: string;\n\ticon?: string;\n\tinspector?: RunInspectorConfig;\n\tinspectorFactory?: (actor: unknown) => RunInspectorConfig | undefined;\n}\n\ntype RunFunctionWithConfig = ((...args: any[]) => any) & {\n\t[RUN_FUNCTION_CONFIG_SYMBOL]?: RunFunctionConfig;\n};\n\n// Run can be either a function or an object with name/icon/run\nconst zRunHandler = z.union([zFunction(), RunConfigSchema]).optional();\n\n/** Extract the run function from either a function or RunConfig object. */\nexport function getRunFunction(\n\trun: ((...args: any[]) => any) | AnyRunConfig | undefined,\n): ((...args: any[]) => any) | undefined {\n\tif (!run) return undefined;\n\tif (typeof run === \"function\") return run;\n\treturn run.run;\n}\n\n/** Extract run metadata (name/icon) from RunConfig if provided. */\nexport function getRunMetadata(\n\trun: ((...args: any[]) => any) | AnyRunConfig | undefined,\n): { name?: string; icon?: string } {\n\tif (!run) return {};\n\tif (typeof run === \"function\") {\n\t\tconst config = (run as RunFunctionWithConfig)[\n\t\t\tRUN_FUNCTION_CONFIG_SYMBOL\n\t\t];\n\t\tif (!config) return {};\n\t\treturn { name: config.name, icon: config.icon };\n\t}\n\treturn { name: run.name, icon: run.icon };\n}\n\n/** Extract run inspector configuration if provided. */\nexport function getRunInspectorConfig(\n\trun: ((...args: any[]) => any) | AnyRunConfig | undefined,\n\tactor?: unknown,\n): RunInspectorConfig | undefined {\n\tif (!run) return undefined;\n\tif (typeof run === \"function\") {\n\t\tconst config = (run as RunFunctionWithConfig)[\n\t\t\tRUN_FUNCTION_CONFIG_SYMBOL\n\t\t];\n\t\treturn config?.inspectorFactory\n\t\t\t? config.inspectorFactory(actor)\n\t\t\t: config?.inspector;\n\t}\n\treturn run.inspector;\n}\n\n// This schema is used to validate the input at runtime. The generic types are defined below in `ActorConfig`.\n//\n// We don't use Zod generics with `z.custom` because:\n// (a) there seems to be a weird bug in either Zod, tsup, or TSC that causese external packages to have different types from `z.infer` than from within the same package and\n// (b) it makes the type definitions incredibly difficult to read as opposed to vanilla TypeScript.\nconst GlobalActorOptionsBaseSchema = z\n\t.object({\n\t\t/** Display name for the actor in the Inspector UI. */\n\t\tname: z.string().optional(),\n\t\t/** Icon for the actor in the Inspector UI. Can be an emoji or FontAwesome icon name. */\n\t\ticon: z.string().optional(),\n\t\t/**\n\t\t * Can hibernate WebSockets for onWebSocket.\n\t\t *\n\t\t * WebSockets using actions/events are hibernatable by default.\n\t\t *\n\t\t * @experimental\n\t\t **/\n\t\tcanHibernateWebSocket: z\n\t\t\t.union([z.boolean(), zFunction<(request: Request) => boolean>()])\n\t\t\t.default(false),\n\t})\n\t.strict();\n\nexport const GlobalActorOptionsSchema = GlobalActorOptionsBaseSchema.prefault(\n\t() => ({}),\n);\n\nexport type GlobalActorOptions = z.infer<typeof GlobalActorOptionsSchema>;\nexport type GlobalActorOptionsInput = z.input<typeof GlobalActorOptionsSchema>;\n\nconst InstanceActorOptionsBaseSchema = z\n\t.object({\n\t\tcreateVarsTimeout: z.number().positive().default(5000),\n\t\tcreateConnStateTimeout: z.number().positive().default(5000),\n\t\tonBeforeConnectTimeout: z.number().positive().default(5000),\n\t\tonConnectTimeout: z.number().positive().default(5000),\n\t\tonMigrateTimeout: z.number().positive().default(30_000),\n\t\tsleepGracePeriod: z\n\t\t\t.number()\n\t\t\t.positive()\n\t\t\t.default(DEFAULT_SLEEP_GRACE_PERIOD),\n\t\t/** @deprecated `onDestroyTimeout` is folded into `sleepGracePeriod`, which now bounds the entire graceful shutdown window for both sleep and destroy. Will be removed in 2.2.0. */\n\t\tonDestroyTimeout: z.number().positive().optional(),\n\t\t/** @deprecated `waitUntilTimeout` is folded into `sleepGracePeriod`, which now bounds the entire graceful shutdown window for both sleep and destroy. Will be removed in 2.2.0. */\n\t\twaitUntilTimeout: z.number().positive().optional(),\n\t\tstateSaveInterval: z.number().positive().default(1_000),\n\t\tactionTimeout: z.number().positive().default(60_000),\n\t\tconnectionLivenessTimeout: z.number().positive().default(2500),\n\t\tconnectionLivenessInterval: z.number().positive().default(5000),\n\t\t/** @deprecated Use `c.keepAwake(promise)` to scope keep-awake to a specific operation, or keep `noSleep` for actors that must stay awake indefinitely. Will be removed in 2.2.0. */\n\t\tnoSleep: z.boolean().default(false),\n\t\tsleepTimeout: z.number().positive().default(30_000),\n\t\tmaxQueueSize: z.number().positive().default(1000),\n\t\tmaxQueueMessageSize: z\n\t\t\t.number()\n\t\t\t.positive()\n\t\t\t.default(64 * 1024),\n\t\t/** Override RivetKit's workflow preload budget for this actor. Set to 0 to disable workflow preloading. */\n\t\tpreloadMaxWorkflowBytes: z.number().nonnegative().optional(),\n\t\t/** Override RivetKit's connections preload budget for this actor. Set to 0 to disable connections preloading. */\n\t\tpreloadMaxConnectionsBytes: z.number().nonnegative().optional(),\n\t})\n\t.strict();\n\nexport const InstanceActorOptionsSchema =\n\tInstanceActorOptionsBaseSchema.prefault(() => ({}));\n\nexport type InstanceActorOptions = z.infer<typeof InstanceActorOptionsSchema>;\nexport type InstanceActorOptionsInput = z.input<\n\ttypeof InstanceActorOptionsSchema\n>;\n\nexport const ActorOptionsSchema = GlobalActorOptionsBaseSchema.extend(\n\tInstanceActorOptionsBaseSchema.shape,\n)\n\t.strict()\n\t.prefault(() => ({}));\n\nexport type ActorOptions = z.infer<typeof ActorOptionsSchema>;\nexport type ActorOptionsInput = z.input<typeof ActorOptionsSchema>;\n\nexport const ActorConfigSchema = z\n\t.object({\n\t\tonCreate: zFunction().optional(),\n\t\tonDestroy: zFunction().optional(),\n\t\tonMigrate: zFunction().optional(),\n\t\tonWake: zFunction().optional(),\n\t\tonSleep: zFunction().optional(),\n\t\trun: zRunHandler,\n\t\tonStateChange: zFunction().optional(),\n\t\tonBeforeConnect: zFunction().optional(),\n\t\tonConnect: zFunction().optional(),\n\t\tonDisconnect: zFunction().optional(),\n\t\tonBeforeActionResponse: zFunction().optional(),\n\t\tonRequest: zFunction().optional(),\n\t\tonWebSocket: zFunction().optional(),\n\t\tactions: z.record(z.string(), zFunction()).default(() => ({})),\n\t\tactionInputSchemas: z.record(z.string(), z.any()).optional(),\n\t\tconnParamsSchema: z.any().optional(),\n\t\tevents: z.record(z.string(), z.any()).optional(),\n\t\tqueues: z.record(z.string(), z.any()).optional(),\n\t\tstate: z.any().optional(),\n\t\tcreateState: zFunction().optional(),\n\t\tconnState: z.any().optional(),\n\t\tcreateConnState: zFunction().optional(),\n\t\tvars: z.any().optional(),\n\t\tdb: z.any().optional(),\n\t\tcreateVars: zFunction().optional(),\n\t\toptions: ActorOptionsSchema,\n\t})\n\t.strict()\n\t.refine(\n\t\t(data) => !(data.state !== undefined && data.createState !== undefined),\n\t\t{\n\t\t\tmessage: \"Cannot define both 'state' and 'createState'\",\n\t\t\tpath: [\"state\"],\n\t\t},\n\t)\n\t.refine(\n\t\t(data) =>\n\t\t\t!(\n\t\t\t\tdata.connState !== undefined &&\n\t\t\t\tdata.createConnState !== undefined\n\t\t\t),\n\t\t{\n\t\t\tmessage: \"Cannot define both 'connState' and 'createConnState'\",\n\t\t\tpath: [\"connState\"],\n\t\t},\n\t)\n\t.refine(\n\t\t(data) => !(data.vars !== undefined && data.createVars !== undefined),\n\t\t{\n\t\t\tmessage: \"Cannot define both 'vars' and 'createVars'\",\n\t\t\tpath: [\"vars\"],\n\t\t},\n\t);\n\n// Creates state config\n//\n// This must have only one or the other or else TState will not be able to be inferred\n//\n// Data returned from this handler will be available on `c.state`.\ntype CreateState<\n\tTState,\n\tTConnParams,\n\tTConnState,\n\tTVars,\n\tTInput,\n\tTDatabase extends AnyDatabaseProvider,\n\tTEvents extends EventSchemaConfig,\n\tTQueues extends QueueSchemaConfig,\n> =\n\t| { state: TState }\n\t| {\n\t\t\tcreateState: (\n\t\t\t\tc: CreateContext<TState, TInput, TDatabase, TEvents, TQueues>,\n\t\t\t\tinput: TInput,\n\t\t\t) => TState | Promise<TState>;\n\t }\n\t| Record<never, never>;\n\n// Creates connection state config\n//\n// This must have only one or the other or else TState will not be able to be inferred\n//\n// Data returned from this handler will be available on `c.conn.state`.\n// The pending connection is not visible in `c.conns` until this succeeds.\ntype CreateConnState<\n\tTState,\n\tTConnParams,\n\tTConnState,\n\tTVars,\n\tTInput,\n\tTDatabase extends AnyDatabaseProvider,\n\tTEvents extends EventSchemaConfig,\n\tTQueues extends QueueSchemaConfig,\n> =\n\t| { connState: TConnState }\n\t| {\n\t\t\tcreateConnState: (\n\t\t\t\tc: CreateConnStateContext<\n\t\t\t\t\tTState,\n\t\t\t\t\tTVars,\n\t\t\t\t\tTInput,\n\t\t\t\t\tTDatabase,\n\t\t\t\t\tTEvents,\n\t\t\t\t\tTQueues\n\t\t\t\t>,\n\t\t\t\tparams: TConnParams,\n\t\t\t) => TConnState | Promise<TConnState>;\n\t }\n\t| Record<never, never>;\n\n// Creates vars config\n//\n// This must have only one or the other or else TState will not be able to be inferred\n/**\n * @experimental\n */\ntype CreateVars<\n\tTState,\n\tTConnParams,\n\tTConnState,\n\tTVars,\n\tTInput,\n\tTDatabase extends AnyDatabaseProvider,\n\tTEvents extends EventSchemaConfig,\n\tTQueues extends QueueSchemaConfig,\n> =\n\t| {\n\t\t\t/**\n\t\t\t * @experimental\n\t\t\t */\n\t\t\tvars: TVars;\n\t }\n\t| {\n\t\t\t/**\n\t\t\t * @experimental\n\t\t\t */\n\t\t\tcreateVars: (\n\t\t\t\tc: CreateVarsContext<\n\t\t\t\t\tTState,\n\t\t\t\t\tTInput,\n\t\t\t\t\tTDatabase,\n\t\t\t\t\tTEvents,\n\t\t\t\t\tTQueues\n\t\t\t\t>,\n\t\t\t\tdriverCtx: any,\n\t\t\t) => TVars | Promise<TVars>;\n\t }\n\t| Record<never, never>;\n\nexport interface Actions<\n\tTState,\n\tTConnParams,\n\tTConnState,\n\tTVars,\n\tTInput,\n\tTDatabase extends AnyDatabaseProvider,\n\tTEvents extends EventSchemaConfig = Record<never, never>,\n\tTQueues extends QueueSchemaConfig = Record<never, never>,\n> {\n\t[Action: string]: (\n\t\tc: ActionContext<\n\t\t\tTState,\n\t\t\tTConnParams,\n\t\t\tTConnState,\n\t\t\tTVars,\n\t\t\tTInput,\n\t\t\tTDatabase,\n\t\t\tTEvents,\n\t\t\tTQueues\n\t\t>,\n\t\t...args: any[]\n\t) => any;\n}\n\n//export type ActorConfig<TState, TConnParams, TConnState, TVars, TInput, TAuthData> = BaseActorConfig<TState, TConnParams, TConnState, TVars, TInput, TAuthData> &\n//\tActorConfigLifecycle<TState, TConnParams, TConnState, TVars, TInput, TAuthData> &\n//\tCreateState<TState, TConnParams, TConnState, TVars, TInput, TAuthData> &\n//\tCreateConnState<TState, TConnParams, TConnState, TVars, TInput, TAuthData>;\n\n/**\n * @experimental\n */\nexport type AuthIntent = \"get\" | \"create\" | \"connect\" | \"action\" | \"message\";\n\ninterface BaseActorConfig<\n\tTState,\n\tTConnParams,\n\tTConnState,\n\tTVars,\n\tTInput,\n\tTDatabase extends AnyDatabaseProvider,\n\tTEvents extends EventSchemaConfig,\n\tTQueues extends QueueSchemaConfig,\n\tTActions extends Actions<\n\t\tTState,\n\t\tTConnParams,\n\t\tTConnState,\n\t\tTVars,\n\t\tTInput,\n\t\tTDatabase,\n\t\tTEvents,\n\t\tTQueues\n\t>,\n> {\n\t/**\n\t * Called when the actor is first initialized.\n\t *\n\t * Use this hook to initialize your actor's state.\n\t * This is called before any other lifecycle hooks.\n\t */\n\tonCreate?: (\n\t\tc: CreateContext<TState, TInput, TDatabase, TEvents, TQueues>,\n\t\tinput: TInput,\n\t) => void | Promise<void>;\n\n\t/**\n\t * Called when the actor is destroyed.\n\t */\n\tonDestroy?: (\n\t\tc: DestroyContext<\n\t\t\tTState,\n\t\t\tTConnParams,\n\t\t\tTConnState,\n\t\t\tTVars,\n\t\t\tTInput,\n\t\t\tTDatabase,\n\t\t\tTEvents,\n\t\t\tTQueues\n\t\t>,\n\t) => void | Promise<void>;\n\n\t/**\n\t * Called on every actor start after persisted state loads and before onWake.\n\t *\n\t * Use this hook for repeatable schema migrations or other startup work that\n\t * must run on both first boot and wake.\n\t */\n\tonMigrate?: (\n\t\tc: MigrateContext<\n\t\t\tTState,\n\t\t\tTConnParams,\n\t\t\tTConnState,\n\t\t\tTVars,\n\t\t\tTInput,\n\t\t\tTDatabase,\n\t\t\tTEvents,\n\t\t\tTQueues\n\t\t>,\n\t\tisNew: boolean,\n\t) => void | Promise<void>;\n\n\t/**\n\t * Called when the actor is started and ready to receive connections and action.\n\t *\n\t * Use this hook to initialize resources needed for the actor's operation\n\t * (timers, external connections, etc.)\n\t *\n\t * @returns Void or a Promise that resolves when startup is complete\n\t */\n\tonWake?: (\n\t\tc: WakeContext<\n\t\t\tTState,\n\t\t\tTConnParams,\n\t\t\tTConnState,\n\t\t\tTVars,\n\t\t\tTInput,\n\t\t\tTDatabase,\n\t\t\tTEvents,\n\t\t\tTQueues\n\t\t>,\n\t) => void | Promise<void>;\n\n\t/**\n\t * Called when the actor is stopping or sleeping.\n\t *\n\t * Use this hook to clean up resources, save state, or perform\n\t * any shutdown operations before the actor sleeps or stops.\n\t *\n\t * Not supported on all platforms.\n\t *\n\t * @returns Void or a Promise that resolves when shutdown is complete\n\t */\n\tonSleep?: (\n\t\tc: SleepContext<\n\t\t\tTState,\n\t\t\tTConnParams,\n\t\t\tTConnState,\n\t\t\tTVars,\n\t\t\tTInput,\n\t\t\tTDatabase,\n\t\t\tTEvents,\n\t\t\tTQueues\n\t\t>,\n\t) => void | Promise<void>;\n\n\t/**\n\t * Called after the actor starts up. Does not block actor startup.\n\t *\n\t * Use this for background tasks like:\n\t * - Reading from queues in a loop\n\t * - Tick loops for periodic work\n\t * - Custom workflow logic\n\t *\n\t * **Important:** The actor may go to sleep at any time during the `run`\n\t * handler. Wrap work that must keep the actor awake with\n\t * `c.keepAwake(promise)` to block idle sleep and shutdown finalize until\n\t * the promise settles, or use `c.waitUntil(promise)` to let the graceful\n\t * shutdown window (`sleepGracePeriod`) cover deferred work.\n\t *\n\t * The handler receives an abort signal via `c.abortSignal` and a\n\t * `c.aborted` alias. Use these to gracefully exit when shutdown starts.\n\t *\n\t * If this handler exits, the actor will follow the normal idle sleep timeout\n\t * once it becomes idle.\n\t * If this handler throws, the actor logs the error and then sleeps once it\n\t * becomes idle.\n\t * Call `c.destroy()` explicitly if a run handler should destroy the actor.\n\t *\n\t * Can be either a function or a RunConfig object with optional name/icon metadata.\n\t *\n\t * @returns Void or a Promise.\n\t */\n\trun?:\n\t\t| ((\n\t\t\t\tc: RunContext<\n\t\t\t\t\tTState,\n\t\t\t\t\tTConnParams,\n\t\t\t\t\tTConnState,\n\t\t\t\t\tTVars,\n\t\t\t\t\tTInput,\n\t\t\t\t\tTDatabase,\n\t\t\t\t\tTEvents,\n\t\t\t\t\tTQueues\n\t\t\t\t>,\n\t\t ) => void | Promise<void>)\n\t\t| RunConfig<\n\t\t\t\tTState,\n\t\t\t\tTConnParams,\n\t\t\t\tTConnState,\n\t\t\t\tTVars,\n\t\t\t\tTInput,\n\t\t\t\tTDatabase,\n\t\t\t\tTEvents,\n\t\t\t\tTQueues\n\t\t >;\n\n\t/**\n\t * Called when the actor's state changes.\n\t *\n\t * Use this hook to react to state changes, such as updating\n\t * external systems or triggering events.\n\t *\n\t * State changes made within this hook will NOT trigger\n\t * another onStateChange call, preventing infinite recursion.\n\t *\n\t * @param newState The updated state\n\t */\n\tonStateChange?: (\n\t\tc: StateChangeContext<\n\t\t\tTState,\n\t\t\tTConnParams,\n\t\t\tTConnState,\n\t\t\tTVars,\n\t\t\tTInput,\n\t\t\tTDatabase,\n\t\t\tTEvents,\n\t\t\tTQueues\n\t\t>,\n\t\tnewState: TState,\n\t) => void;\n\n\t/**\n\t * Called before a client connects to the actor.\n\t *\n\t * Use this hook to determine if a connection should be accepted\n\t * and to validate client-provided parameters. The pending connection\n\t * is not visible in `c.conns` while this hook runs.\n\t *\n\t * @param opts Connection parameters including client-provided data\n\t * @returns Void or a Promise.\n\t * @throws Throw an error to reject the connection\n\t */\n\tonBeforeConnect?: (\n\t\tc: BeforeConnectContext<\n\t\t\tTState,\n\t\t\tTVars,\n\t\t\tTInput,\n\t\t\tTDatabase,\n\t\t\tTEvents,\n\t\t\tTQueues\n\t\t>,\n\t\tparams: TConnParams,\n\t) => void | Promise<void>;\n\n\t/**\n\t * Called when a client successfully connects to the actor.\n\t *\n\t * Use this hook to perform actions when a connection is established,\n\t * such as sending initial data or updating the actor's state. The\n\t * connection is visible in `c.conns` before this hook runs.\n\t *\n\t * @param conn The connection object\n\t * @returns Void or a Promise that resolves when connection handling is complete\n\t */\n\tonConnect?: (\n\t\tc: ConnectContext<\n\t\t\tTState,\n\t\t\tTConnParams,\n\t\t\tTConnState,\n\t\t\tTVars,\n\t\t\tTInput,\n\t\t\tTDatabase,\n\t\t\tTEvents,\n\t\t\tTQueues\n\t\t>,\n\t\tconn: Conn<\n\t\t\tTState,\n\t\t\tTConnParams,\n\t\t\tTConnState,\n\t\t\tTVars,\n\t\t\tTInput,\n\t\t\tTDatabase,\n\t\t\tTEvents,\n\t\t\tTQueues\n\t\t>,\n\t) => void | Promise<void>;\n\n\t/**\n\t * Called when a client disconnects from the actor.\n\t *\n\t * Use this hook to clean up resources associated with the connection\n\t * or update the actor's state.\n\t *\n\t * @param conn The connection that is being closed\n\t * @returns Void or a Promise that resolves when disconnect handling is complete\n\t */\n\tonDisconnect?: (\n\t\tc: DisconnectContext<\n\t\t\tTState,\n\t\t\tTConnParams,\n\t\t\tTConnState,\n\t\t\tTVars,\n\t\t\tTInput,\n\t\t\tTDatabase,\n\t\t\tTEvents,\n\t\t\tTQueues\n\t\t>,\n\t\tconn: Conn<\n\t\t\tTState,\n\t\t\tTConnParams,\n\t\t\tTConnState,\n\t\t\tTVars,\n\t\t\tTInput,\n\t\t\tTDatabase,\n\t\t\tTEvents,\n\t\t\tTQueues\n\t\t>,\n\t) => void | Promise<void>;\n\n\t/**\n\t * Called before sending an action response to the client.\n\t *\n\t * Use this hook to modify or transform the output of an action before it's sent\n\t * to the client. This is useful for formatting responses, adding metadata,\n\t * or applying transformations to the output.\n\t *\n\t * @param name The name of the action that was called\n\t * @param args The arguments that were passed to the action\n\t * @param output The output that will be sent to the client\n\t * @returns The modified output to send to the client\n\t */\n\tonBeforeActionResponse?: <Out>(\n\t\tc: BeforeActionResponseContext<\n\t\t\tTState,\n\t\t\tTConnParams,\n\t\t\tTConnState,\n\t\t\tTVars,\n\t\t\tTInput,\n\t\t\tTDatabase,\n\t\t\tTEvents,\n\t\t\tTQueues\n\t\t>,\n\t\tname: string,\n\t\targs: unknown[],\n\t\toutput: Out,\n\t) => Out | Promise<Out>;\n\n\t/**\n\t * Called when a raw HTTP request is made to the actor.\n\t *\n\t * This handler receives raw HTTP requests made to `/actors/{actorName}/http/*` endpoints.\n\t * Use this hook to handle custom HTTP patterns, REST APIs, or other HTTP-based protocols.\n\t *\n\t * @param c The request context with access to the connection\n\t * @param request The raw HTTP request object\n\t * @param opts Additional options\n\t * @returns A Response object to send back, or void to continue with default routing\n\t */\n\tonRequest?: (\n\t\tc: RequestContext<\n\t\t\tTState,\n\t\t\tTConnParams,\n\t\t\tTConnState,\n\t\t\tTVars,\n\t\t\tTInput,\n\t\t\tTDatabase,\n\t\t\tTEvents,\n\t\t\tTQueues\n\t\t>,\n\t\trequest: Request,\n\t) => Response | Promise<Response>;\n\n\t/**\n\t * Called when a raw WebSocket connection is established to the actor.\n\t *\n\t * This handler receives WebSocket connections made to `/actors/{actorName}/websocket/*` endpoints.\n\t * Use this hook to handle custom WebSocket protocols, binary streams, or other WebSocket-based communication.\n\t *\n\t * @param c The WebSocket context with access to the connection\n\t * @param websocket The actor-facing raw WebSocket connection\n\t * @param opts Additional options including the original HTTP upgrade request\n\t */\n\tonWebSocket?: (\n\t\tc: WebSocketContext<\n\t\t\tTState,\n\t\t\tTConnParams,\n\t\t\tTConnState,\n\t\t\tTVars,\n\t\t\tTInput,\n\t\t\tTDatabase,\n\t\t\tTEvents,\n\t\t\tTQueues\n\t\t>,\n\t\twebsocket: UniversalWebSocket,\n\t) => void | Promise<void>;\n\n\tactions?: TActions;\n\n\t/**\n\t * Optional schema map for validating action argument tuples in native runtimes.\n\t */\n\tactionInputSchemas?: Record<string, PrimitiveSchema>;\n\n\t/**\n\t * Optional schema for validating connection params in native runtimes.\n\t */\n\tconnParamsSchema?: PrimitiveSchema;\n\n\t/**\n\t * Schema map for events broadcasted by this actor.\n\t */\n\tevents?: TEvents;\n\n\t/**\n\t * Schema map for queue payloads sent by this actor.\n\t */\n\tqueues?: TQueues;\n}\n\ntype ActorDatabaseConfig<TDatabase extends AnyDatabaseProvider> =\n\t| {\n\t\t\t/**\n\t\t\t * @experimental\n\t\t\t */\n\t\t\tdb: TDatabase;\n\t }\n\t| Record<never, never>;\n\n// 1. Infer schema\n// 2. Omit keys that we'll manually define (because of generics)\n// 3. Define our own types that have generic constraints\nexport type ActorConfig<\n\tTState,\n\tTConnParams,\n\tTConnState,\n\tTVars,\n\tTInput,\n\tTDatabase extends AnyDatabaseProvider,\n\tTEvents extends EventSchemaConfig = Record<never, never>,\n\tTQueues extends QueueSchemaConfig = Record<never, never>,\n> = Omit<\n\tz.infer<typeof ActorConfigSchema>,\n\t| \"actions\"\n\t| \"events\"\n\t| \"queues\"\n\t| \"onCreate\"\n\t| \"onDestroy\"\n\t| \"onMigrate\"\n\t| \"onWake\"\n\t| \"onSleep\"\n\t| \"run\"\n\t| \"onStateChange\"\n\t| \"onBeforeConnect\"\n\t| \"onConnect\"\n\t| \"onDisconnect\"\n\t| \"onBeforeActionResponse\"\n\t| \"onRequest\"\n\t| \"onWebSocket\"\n\t| \"state\"\n\t| \"createState\"\n\t| \"connState\"\n\t| \"createConnState\"\n\t| \"vars\"\n\t| \"createVars\"\n\t| \"db\"\n> &\n\tBaseActorConfig<\n\t\tTState,\n\t\tTConnParams,\n\t\tTConnState,\n\t\tTVars,\n\t\tTInput,\n\t\tTDatabase,\n\t\tTEvents,\n\t\tTQueues,\n\t\tActions<\n\t\t\tTState,\n\t\t\tTConnParams,\n\t\t\tTConnState,\n\t\t\tTVars,\n\t\t\tTInput,\n\t\t\tTDatabase,\n\t\t\tTEvents,\n\t\t\tTQueues\n\t\t>\n\t> &\n\tCreateState<\n\t\tTState,\n\t\tTConnParams,\n\t\tTConnState,\n\t\tTVars,\n\t\tTInput,\n\t\tTDatabase,\n\t\tTEvents,\n\t\tTQueues\n\t> &\n\tCreateConnState<\n\t\tTState,\n\t\tTConnParams,\n\t\tTConnState,\n\t\tTVars,\n\t\tTInput,\n\t\tTDatabase,\n\t\tTEvents,\n\t\tTQueues\n\t> &\n\tCreateVars<\n\t\tTState,\n\t\tTConnParams,\n\t\tTConnState,\n\t\tTVars,\n\t\tTInput,\n\t\tTDatabase,\n\t\tTEvents,\n\t\tTQueues\n\t> &\n\tActorDatabaseConfig<TDatabase>;\n\n// See description on `ActorConfig`\nexport type ActorConfigInput<\n\tTState = undefined,\n\tTConnParams = undefined,\n\tTConnState = undefined,\n\tTVars = undefined,\n\tTInput = undefined,\n\tTDatabase extends AnyDatabaseProvider = undefined,\n\tTEvents extends EventSchemaConfig = Record<never, never>,\n\tTQueues extends QueueSchemaConfig = Record<never, never>,\n\tTActions extends Actions<\n\t\tTState,\n\t\tTConnParams,\n\t\tTConnState,\n\t\tTVars,\n\t\tTInput,\n\t\tTDatabase,\n\t\tTEvents,\n\t\tTQueues\n\t> = Record<never, never>,\n> = {\n\ttypes?: ActorTypes<\n\t\tTState,\n\t\tTConnParams,\n\t\tTConnState,\n\t\tTVars,\n\t\tTInput,\n\t\tTDatabase\n\t>;\n} & Omit<\n\tz.input<typeof ActorConfigSchema>,\n\t| \"actions\"\n\t| \"events\"\n\t| \"queues\"\n\t| \"onCreate\"\n\t| \"onDestroy\"\n\t| \"onMigrate\"\n\t| \"onWake\"\n\t| \"onSleep\"\n\t| \"run\"\n\t| \"onStateChange\"\n\t| \"onBeforeConnect\"\n\t| \"onConnect\"\n\t| \"onDisconnect\"\n\t| \"onBeforeActionResponse\"\n\t| \"onRequest\"\n\t| \"onWebSocket\"\n\t| \"state\"\n\t| \"createState\"\n\t| \"connState\"\n\t| \"createConnState\"\n\t| \"vars\"\n\t| \"createVars\"\n\t| \"db\"\n> &\n\tBaseActorConfig<\n\t\tTState,\n\t\tTConnParams,\n\t\tTConnState,\n\t\tTVars,\n\t\tTInput,\n\t\tTDatabase,\n\t\tTEvents,\n\t\tTQueues,\n\t\tTActions\n\t> &\n\tCreateState<\n\t\tTState,\n\t\tTConnParams,\n\t\tTConnState,\n\t\tTVars,\n\t\tTInput,\n\t\tTDatabase,\n\t\tTEvents,\n\t\tTQueues\n\t> &\n\tCreateConnState<\n\t\tTState,\n\t\tTConnParams,\n\t\tTConnState,\n\t\tTVars,\n\t\tTInput,\n\t\tTDatabase,\n\t\tTEvents,\n\t\tTQueues\n\t> &\n\tCreateVars<\n\t\tTState,\n\t\tTConnParams,\n\t\tTConnState,\n\t\tTVars,\n\t\tTInput,\n\t\tTDatabase,\n\t\tTEvents,\n\t\tTQueues\n\t> &\n\tActorDatabaseConfig<TDatabase>;\n\n// For testing type definitions:\nexport function test<\n\tTState,\n\tTConnParams,\n\tTConnState,\n\tTVars,\n\tTInput,\n\tTDatabase extends AnyDatabaseProvider,\n\tTEvents extends EventSchemaConfig,\n\tTQueues extends QueueSchemaConfig,\n\tTActions extends Actions<\n\t\tTState,\n\t\tTConnParams,\n\t\tTConnState,\n\t\tTVars,\n\t\tTInput,\n\t\tTDatabase,\n\t\tTEvents,\n\t\tTQueues\n\t>,\n>(\n\tinput: ActorConfigInput<\n\t\tTState,\n\t\tTConnParams,\n\t\tTConnState,\n\t\tTVars,\n\t\tTInput,\n\t\tTDatabase,\n\t\tTEvents,\n\t\tTQueues,\n\t\tTActions\n\t>,\n): ActorConfig<\n\tTState,\n\tTConnParams,\n\tTConnState,\n\tTVars,\n\tTInput,\n\tTDatabase,\n\tTEvents,\n\tTQueues\n> {\n\tconst config = ActorConfigSchema.parse(input) as ActorConfig<\n\t\tTState,\n\t\tTConnParams,\n\t\tTConnState,\n\t\tTVars,\n\t\tTInput,\n\t\tTDatabase,\n\t\tTEvents,\n\t\tTQueues\n\t>;\n\treturn config;\n}\n\n// MARK: Documentation Schema\n// This schema is JSON-serializable for documentation generation.\n// It excludes function types and focuses on the configurable options.\n\nexport const DocActorOptionsSchema = z\n\t.object({\n\t\tname: z\n\t\t\t.string()\n\t\t\t.optional()\n\t\t\t.describe(\"Display name for the actor in the Inspector UI.\"),\n\t\ticon: z\n\t\t\t.string()\n\t\t\t.optional()\n\t\t\t.describe(\n\t\t\t\t\"Icon for the actor in the Inspector UI. Can be an emoji (e.g., '🚀') or FontAwesome icon name (e.g., 'rocket').\",\n\t\t\t),\n\t\tcreateVarsTimeout: z\n\t\t\t.number()\n\t\t\t.optional()\n\t\t\t.describe(\"Timeout in ms for createVars handler. Default: 5000\"),\n\t\tcreateConnStateTimeout: z\n\t\t\t.number()\n\t\t\t.optional()\n\t\t\t.describe(\n\t\t\t\t\"Timeout in ms for createConnState handler. Default: 5000\",\n\t\t\t),\n\t\tonMigrateTimeout: z\n\t\t\t.number()\n\t\t\t.optional()\n\t\t\t.describe(\"Timeout in ms for onMigrate handler. Default: 30000\"),\n\t\tonBeforeConnectTimeout: z\n\t\t\t.number()\n\t\t\t.optional()\n\t\t\t.describe(\n\t\t\t\t\"Timeout in ms for onBeforeConnect handler. Default: 5000\",\n\t\t\t),\n\t\tonConnectTimeout: z\n\t\t\t.number()\n\t\t\t.optional()\n\t\t\t.describe(\"Timeout in ms for onConnect handler. Default: 5000\"),\n\t\tsleepGracePeriod: z\n\t\t\t.number()\n\t\t\t.optional()\n\t\t\t.describe(\n\t\t\t\t`Max time in ms for the graceful shutdown window. Covers lifecycle hooks (onSleep, onDestroy), the run handler wait, async raw WebSocket handlers, disconnect callbacks, and final state serialization. Default: ${DEFAULT_SLEEP_GRACE_PERIOD}.`,\n\t\t\t),\n\t\tonDestroyTimeout: z\n\t\t\t.number()\n\t\t\t.optional()\n\t\t\t.describe(\n\t\t\t\t\"Deprecated. Folded into sleepGracePeriod, which now bounds the entire graceful shutdown window for both sleep and destroy. Will be removed in 2.2.0.\",\n\t\t\t),\n\t\twaitUntilTimeout: z\n\t\t\t.number()\n\t\t\t.optional()\n\t\t\t.describe(\n\t\t\t\t\"Deprecated. Folded into sleepGracePeriod, which now bounds the entire graceful shutdown window for both sleep and destroy. Will be removed in 2.2.0.\",\n\t\t\t),\n\t\tstateSaveInterval: z\n\t\t\t.number()\n\t\t\t.optional()\n\t\t\t.describe(\n\t\t\t\t\"Interval in ms between automatic state saves. Default: 1000\",\n\t\t\t),\n\t\tactionTimeout: z\n\t\t\t.number()\n\t\t\t.optional()\n\t\t\t.describe(\"Timeout in ms for action handlers. Default: 60000\"),\n\t\tconnectionLivenessTimeout: z\n\t\t\t.number()\n\t\t\t.optional()\n\t\t\t.describe(\n\t\t\t\t\"Timeout in ms for connection liveness checks. Default: 2500\",\n\t\t\t),\n\t\tconnectionLivenessInterval: z\n\t\t\t.number()\n\t\t\t.optional()\n\t\t\t.describe(\n\t\t\t\t\"Interval in ms between connection liveness checks. Default: 5000\",\n\t\t\t),\n\t\tnoSleep: z\n\t\t\t.boolean()\n\t\t\t.optional()\n\t\t\t.describe(\n\t\t\t\t\"Deprecated. If true, the actor will never sleep. Use c.keepAwake(promise) to scope keep-awake to a specific operation instead. Default: false\",\n\t\t\t),\n\t\tsleepTimeout: z\n\t\t\t.number()\n\t\t\t.optional()\n\t\t\t.describe(\n\t\t\t\t\"Time in ms of inactivity before the actor sleeps. Default: 30000\",\n\t\t\t),\n\t\tmaxQueueSize: z\n\t\t\t.number()\n\t\t\t.optional()\n\t\t\t.describe(\n\t\t\t\t\"Maximum number of queue messages before rejecting new messages. Default: 1000\",\n\t\t\t),\n\t\tmaxQueueMessageSize: z\n\t\t\t.number()\n\t\t\t.optional()\n\t\t\t.describe(\n\t\t\t\t\"Maximum size of each queue message in bytes. Default: 65536\",\n\t\t\t),\n\t\tcanHibernateWebSocket: z\n\t\t\t.boolean()\n\t\t\t.optional()\n\t\t\t.describe(\n\t\t\t\t\"Whether WebSockets using onWebSocket can be hibernated. WebSockets using actions/events are hibernatable by default. Default: false\",\n\t\t\t),\n\t\tpreloadMaxWorkflowBytes: z\n\t\t\t.number()\n\t\t\t.optional()\n\t\t\t.describe(\n\t\t\t\t\"Override RivetKit's workflow preload budget for this actor. Set to 0 to disable workflow preloading.\",\n\t\t\t),\n\t\tpreloadMaxConnectionsBytes: z\n\t\t\t.number()\n\t\t\t.optional()\n\t\t\t.describe(\n\t\t\t\t\"Override RivetKit's connections preload budget for this actor. Set to 0 to disable connections preloading.\",\n\t\t\t),\n\t})\n\t.describe(\"Actor options for timeouts and behavior configuration.\");\n\nexport const DocActorConfigSchema = z\n\t.object({\n\t\tstate: z\n\t\t\t.unknown()\n\t\t\t.optional()\n\t\t\t.describe(\n\t\t\t\t\"Initial state value for the actor. Cannot be used with createState.\",\n\t\t\t),\n\t\tcreateState: z\n\t\t\t.unknown()\n\t\t\t.optional()\n\t\t\t.describe(\n\t\t\t\t\"Function to create initial state. Receives context and input. Cannot be used with state.\",\n\t\t\t),\n\t\tconnState: z\n\t\t\t.unknown()\n\t\t\t.optional()\n\t\t\t.describe(\n\t\t\t\t\"Initial connection state value. Cannot be used with createConnState.\",\n\t\t\t),\n\t\tcreateConnState: z\n\t\t\t.unknown()\n\t\t\t.optional()\n\t\t\t.describe(\n\t\t\t\t\"Function to create connection state. Receives context and connection params. The pending connection is not visible in c.conns until this succeeds. Cannot be used with connState.\",\n\t\t\t),\n\t\tvars: z\n\t\t\t.unknown()\n\t\t\t.optional()\n\t\t\t.describe(\n\t\t\t\t\"Initial ephemeral variables value. Cannot be used with createVars.\",\n\t\t\t),\n\t\tcreateVars: z\n\t\t\t.unknown()\n\t\t\t.optional()\n\t\t\t.describe(\n\t\t\t\t\"Function to create ephemeral variables. Receives context and driver context. Cannot be used with vars.\",\n\t\t\t),\n\t\tdb: z\n\t\t\t.unknown()\n\t\t\t.optional()\n\t\t\t.describe(\"Database provider instance for the actor.\"),\n\t\tonCreate: z\n\t\t\t.unknown()\n\t\t\t.optional()\n\t\t\t.describe(\n\t\t\t\t\"Called when the actor is first initialized. Use to initialize state.\",\n\t\t\t),\n\t\tonDestroy: z\n\t\t\t.unknown()\n\t\t\t.optional()\n\t\t\t.describe(\"Called when the actor is destroyed.\"),\n\t\tonMigrate: z\n\t\t\t.unknown()\n\t\t\t.optional()\n\t\t\t.describe(\n\t\t\t\t\"Called on every actor start after persisted state loads and before onWake. Use for repeatable schema migrations.\",\n\t\t\t),\n\t\tonWake: z\n\t\t\t.unknown()\n\t\t\t.optional()\n\t\t\t.describe(\n\t\t\t\t\"Called when the actor wakes up and is ready to receive connections and actions.\",\n\t\t\t),\n\t\tonSleep: z\n\t\t\t.unknown()\n\t\t\t.optional()\n\t\t\t.describe(\n\t\t\t\t\"Called when the actor is stopping or sleeping. Use to clean up resources.\",\n\t\t\t),\n\t\trun: z\n\t\t\t.unknown()\n\t\t\t.optional()\n\t\t\t.describe(\n\t\t\t\t\"Called after actor starts. Does not block startup. Use for background tasks like queue processing or tick loops. If it exits, the actor follows the normal idle sleep timeout once idle. If it throws, the actor logs the error and then follows the normal idle sleep timeout once idle.\",\n\t\t\t),\n\t\tonStateChange: z\n\t\t\t.unknown()\n\t\t\t.optional()\n\t\t\t.describe(\n\t\t\t\t\"Called when the actor's state changes. State changes within this hook won't trigger recursion.\",\n\t\t\t),\n\t\tonBeforeConnect: z\n\t\t\t.unknown()\n\t\t\t.optional()\n\t\t\t.describe(\n\t\t\t\t\"Called before a client connects. Throw an error to reject the connection. The pending connection is not visible in c.conns while this runs.\",\n\t\t\t),\n\t\tonConnect: z\n\t\t\t.unknown()\n\t\t\t.optional()\n\t\t\t.describe(\n\t\t\t\t\"Called when a client successfully connects. The connection is visible in c.conns before this runs.\",\n\t\t\t),\n\t\tonDisconnect: z\n\t\t\t.unknown()\n\t\t\t.optional()\n\t\t\t.describe(\"Called when a client disconnects.\"),\n\t\tonBeforeActionResponse: z\n\t\t\t.unknown()\n\t\t\t.optional()\n\t\t\t.describe(\n\t\t\t\t\"Called before sending an action response. Use to transform output.\",\n\t\t\t),\n\t\tonRequest: z\n\t\t\t.unknown()\n\t\t\t.optional()\n\t\t\t.describe(\n\t\t\t\t\"Called for raw HTTP requests to /actors/{name}/http/* endpoints.\",\n\t\t\t),\n\t\tonWebSocket: z\n\t\t\t.unknown()\n\t\t\t.optional()\n\t\t\t.describe(\n\t\t\t\t\"Called for raw WebSocket connections to /actors/{name}/websocket/* endpoints.\",\n\t\t\t),\n\t\tactions: z\n\t\t\t.record(z.string(), z.unknown())\n\t\t\t.optional()\n\t\t\t.describe(\n\t\t\t\t\"Map of action name to handler function. Defaults to an empty object.\",\n\t\t\t),\n\t\tactionInputSchemas: z\n\t\t\t.record(z.string(), z.unknown())\n\t\t\t.optional()\n\t\t\t.describe(\n\t\t\t\t\"Optional schema map for validating action argument tuples in native runtimes.\",\n\t\t\t),\n\t\tconnParamsSchema: z\n\t\t\t.unknown()\n\t\t\t.optional()\n\t\t\t.describe(\n\t\t\t\t\"Optional schema for validating connection params in native runtimes.\",\n\t\t\t),\n\t\tevents: z\n\t\t\t.record(z.string(), z.unknown())\n\t\t\t.optional()\n\t\t\t.describe(\"Map of event names to schemas.\"),\n\t\tqueues: z\n\t\t\t.record(z.string(), z.unknown())\n\t\t\t.optional()\n\t\t\t.describe(\"Map of queue names to schemas.\"),\n\t\toptions: DocActorOptionsSchema.optional(),\n\t})\n\t.describe(\"Actor configuration passed to the actor() function.\");\n","import {\n\ttype DestinationStream,\n\ttype LevelWithSilent,\n\ttype Logger,\n\tpino,\n\tstdTimeFunctions,\n} from \"pino\";\nimport { z } from \"zod/v4\";\nimport { getLogLevel, getLogTarget, getLogTimestamp } from \"@/utils/env-vars\";\n\nexport type { Logger } from \"pino\";\n\nlet baseLogger: Logger | undefined;\nlet configuredLogLevel: LogLevel | undefined;\n\n/** Cache of child loggers by logger name. */\nconst loggerCache = new Map<string, Logger>();\n\nexport const LogLevelSchema = z.enum([\n\t\"trace\",\n\t\"debug\",\n\t\"info\",\n\t\"warn\",\n\t\"error\",\n\t\"fatal\",\n\t\"silent\",\n]);\n\nexport type LogLevel = z.infer<typeof LogLevelSchema>;\n\nexport function getPinoLevel(logLevel?: LogLevel): LevelWithSilent {\n\t// Priority: provided > configured > env > default\n\tif (logLevel) {\n\t\treturn logLevel;\n\t}\n\n\tif (configuredLogLevel) {\n\t\treturn configuredLogLevel;\n\t}\n\n\tconst raw = (getLogLevel() || \"warn\").toString().toLowerCase();\n\n\tconst parsed = LogLevelSchema.safeParse(raw);\n\tif (parsed.success) {\n\t\treturn parsed.data;\n\t}\n\n\t// Default to info if invalid\n\treturn \"info\";\n}\n\nexport function getIncludeTarget(): boolean {\n\treturn getLogTarget();\n}\n\n/**\n * Configure a custom base logger.\n */\nexport function configureBaseLogger(logger: Logger): void {\n\tbaseLogger = logger;\n\tloggerCache.clear();\n}\n\n/**\n * Configure the default logger with optional log level.\n */\nexport function configureDefaultLogger(logLevel?: LogLevel) {\n\t// Store the configured log level\n\tif (logLevel) {\n\t\tconfiguredLogLevel = logLevel;\n\t}\n\n\tbaseLogger = pino(\n\t\t{\n\t\t\tlevel: getPinoLevel(logLevel),\n\t\t\tmessageKey: \"msg\",\n\t\t\t// Do not include pid/hostname in output\n\t\t\tbase: {},\n\t\t\t// Keep the numeric level so the logfmt sink can match Pino's levels.\n\t\t\tformatters: {\n\t\t\t\tlevel(_label: string, number: number) {\n\t\t\t\t\treturn { level: number };\n\t\t\t\t},\n\t\t\t},\n\t\t\ttimestamp: getLogTimestamp() ? stdTimeFunctions.epochTime : false,\n\t\t},\n\t\tcreateLogfmtDestination(),\n\t);\n\n\tloggerCache.clear();\n}\n\n/**\n * Get or initialize the base logger.\n */\nexport function getBaseLogger(): Logger {\n\tif (!baseLogger) {\n\t\tconfigureDefaultLogger();\n\t}\n\treturn baseLogger!;\n}\n\n/**\n * Returns a child logger with `target` bound for the given name.\n */\nexport function getLogger(name = \"default\"): Logger {\n\t// Check cache first\n\tconst cached = loggerCache.get(name);\n\tif (cached) {\n\t\treturn cached;\n\t}\n\n\t// Create\n\tconst base = getBaseLogger();\n\n\t// Add target to log if enabled\n\tconst child = getIncludeTarget() ? base.child({ target: name }) : base;\n\n\t// Cache the logger\n\tloggerCache.set(name, child);\n\n\treturn child;\n}\n\nconst PINO_LEVEL_LABELS: Record<number, string> = {\n\t10: \"trace\",\n\t20: \"debug\",\n\t30: \"info\",\n\t40: \"warn\",\n\t50: \"error\",\n\t60: \"fatal\",\n};\n\nfunction createLogfmtDestination(): DestinationStream {\n\treturn {\n\t\twrite(msg: string): void {\n\t\t\tconst line = formatLogfmtLine(msg);\n\t\t\tif (typeof process !== \"undefined\" && process.stdout?.write) {\n\t\t\t\tprocess.stdout.write(`${line}\\n`);\n\t\t\t} else {\n\t\t\t\tconsole.log(line);\n\t\t\t}\n\t\t},\n\t};\n}\n\nfunction formatLogfmtLine(raw: string): string {\n\tlet data: Record<string, unknown>;\n\ttry {\n\t\tdata = JSON.parse(raw);\n\t} catch {\n\t\treturn raw.trimEnd();\n\t}\n\n\tconst parts: string[] = [];\n\tappendLogfmtEntry(parts, \"level\", formatPinoLevel(data.level));\n\n\tif (data.time !== undefined) {\n\t\tappendLogfmtEntry(parts, \"ts\", data.time);\n\t}\n\n\tfor (const [key, value] of Object.entries(data)) {\n\t\tif (key === \"level\" || key === \"time\") {\n\t\t\tcontinue;\n\t\t}\n\t\tappendLogfmtEntry(parts, key, value);\n\t}\n\n\treturn parts.join(\" \");\n}\n\nfunction formatPinoLevel(level: unknown): string {\n\tif (typeof level === \"number\") {\n\t\treturn PINO_LEVEL_LABELS[level] ?? level.toString();\n\t}\n\n\tif (typeof level === \"string\") {\n\t\treturn level.toLowerCase();\n\t}\n\n\treturn \"info\";\n}\n\nfunction appendLogfmtEntry(parts: string[], key: string, value: unknown): void {\n\tconst safeKey = key.replace(/[\\s=\"]/g, \"\");\n\tif (safeKey.length === 0) {\n\t\treturn;\n\t}\n\n\tparts.push(`${safeKey}=${formatLogfmtValue(value)}`);\n}\n\nfunction formatLogfmtValue(value: unknown): string {\n\tif (typeof value === \"number\" || typeof value === \"boolean\") {\n\t\treturn String(value);\n\t}\n\n\tif (value === null || value === undefined) {\n\t\treturn \"null\";\n\t}\n\n\tif (typeof value === \"string\") {\n\t\treturn quoteLogfmtString(value);\n\t}\n\n\treturn quoteLogfmtString(JSON.stringify(value));\n}\n\nfunction quoteLogfmtString(value: string): string {\n\tif (!/[\\s=\"]/.test(value)) {\n\t\treturn value;\n\t}\n\n\treturn `\"${value.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"').replace(/\\n/g, \"\\\\n\")}\"`;\n}\n","import type { DeconstructedError } from \"@/common/utils\";\n\nexport const INTERNAL_ERROR_CODE = \"internal_error\";\nexport const INTERNAL_ERROR_DESCRIPTION = \"An internal error occurred\";\nexport type InternalErrorMetadata = Record<string, never>;\n\nexport const USER_ERROR_CODE = \"user_error\";\nexport const BRIDGE_RIVET_ERROR_PREFIX = \"__RIVET_ERROR_JSON__:\";\n\nexport interface RivetErrorOptions extends ErrorOptions {\n\t/** Error data can safely be serialized in a response to the client. */\n\tpublic?: boolean;\n\t/** Metadata associated with this error. */\n\tmetadata?: unknown;\n\t/** Explicit HTTP status override for router responses. */\n\tstatusCode?: number;\n}\n\nexport interface RivetErrorLike {\n\t__type?: \"ActorError\" | \"RivetError\";\n\tgroup: string;\n\tcode: string;\n\tmessage: string;\n\tmetadata?: unknown;\n\tpublic?: boolean;\n\tstatusCode?: number;\n}\n\nexport interface UserErrorOptions extends ErrorOptions {\n\t/**\n\t * Machine readable code for this error. Useful for catching different types of\n\t * errors in try-catch.\n\t */\n\tcode?: string;\n\t/**\n\t * Additional metadata related to the error. Useful for understanding context\n\t * about the error.\n\t */\n\tmetadata?: unknown;\n}\n\nfunction looksLikeRivetErrorOptions(\n\tvalue: unknown,\n): value is RivetErrorOptions {\n\treturn (\n\t\ttypeof value === \"object\" &&\n\t\tvalue !== null &&\n\t\t(\"public\" in value ||\n\t\t\t\"metadata\" in value ||\n\t\t\t\"statusCode\" in value ||\n\t\t\t\"cause\" in value)\n\t);\n}\n\nfunction isTypedErrorTag(value: unknown): value is \"ActorError\" | \"RivetError\" {\n\treturn value === \"ActorError\" || value === \"RivetError\";\n}\n\nfunction errorMessage(error: unknown, fallback = String(error)): string {\n\tif (\n\t\terror &&\n\t\ttypeof error === \"object\" &&\n\t\t\"message\" in error &&\n\t\ttypeof error.message === \"string\"\n\t) {\n\t\treturn error.message;\n\t}\n\n\treturn fallback;\n}\n\nexport function isRivetErrorLike(\n\terror: unknown,\n): error is RivetError | DeconstructedError | RivetErrorLike {\n\treturn (\n\t\ttypeof error === \"object\" &&\n\t\terror !== null &&\n\t\t\"group\" in error &&\n\t\ttypeof error.group === \"string\" &&\n\t\t\"code\" in error &&\n\t\ttypeof error.code === \"string\" &&\n\t\t\"message\" in error &&\n\t\ttypeof error.message === \"string\" &&\n\t\t(!(\"__type\" in error) || isTypedErrorTag(error.__type))\n\t);\n}\n\nexport class RivetError extends Error {\n\t__type = \"RivetError\" as const;\n\n\tpublic public: boolean;\n\tpublic metadata?: unknown;\n\tpublic statusCode: number;\n\tpublic readonly group: string;\n\tpublic readonly code: string;\n\n\tpublic static isRivetError(\n\t\terror: unknown,\n\t): error is RivetError | DeconstructedError {\n\t\treturn isRivetErrorLike(error);\n\t}\n\n\tpublic static isActorError(\n\t\terror: unknown,\n\t): error is RivetError | DeconstructedError {\n\t\treturn isRivetErrorLike(error);\n\t}\n\n\tconstructor(\n\t\tgroup: string,\n\t\tcode: string,\n\t\tmessage: string,\n\t\toptions?: RivetErrorOptions | unknown,\n\t) {\n\t\tconst normalized = looksLikeRivetErrorOptions(options)\n\t\t\t? options\n\t\t\t: { metadata: options };\n\n\t\tsuper(message, { cause: normalized.cause });\n\t\tthis.name = \"RivetError\";\n\t\tthis.group = group;\n\t\tthis.code = code;\n\t\tthis.public = normalized.public ?? false;\n\t\tthis.metadata = normalized.metadata;\n\t\tthis.statusCode = normalized.statusCode ?? (this.public ? 400 : 500);\n\t}\n\n\ttoString() {\n\t\treturn this.message;\n\t}\n}\n\nexport { RivetError as ActorError };\n\nexport class UserError extends RivetError {\n\tconstructor(message: string, options?: UserErrorOptions) {\n\t\tsuper(\"user\", options?.code ?? USER_ERROR_CODE, message, {\n\t\t\tpublic: true,\n\t\t\tmetadata: options?.metadata,\n\t\t\tcause: options?.cause,\n\t\t});\n\t}\n}\n\nexport function toRivetError(\n\terror: unknown,\n\tfallback?: Partial<RivetErrorLike>,\n): RivetError {\n\tif (typeof error === \"string\") {\n\t\tconst bridged = decodeBridgeRivetError(error);\n\t\tif (bridged) {\n\t\t\treturn bridged;\n\t\t}\n\t}\n\n\tif (error instanceof Error) {\n\t\tconst bridged = decodeBridgeRivetError(error.message);\n\t\tif (bridged) {\n\t\t\treturn bridged;\n\t\t}\n\t}\n\n\tif (isRivetErrorLike(error)) {\n\t\treturn new RivetError(error.group, error.code, error.message, {\n\t\t\tpublic: error.public,\n\t\t\tstatusCode: error.statusCode,\n\t\t\tmetadata: error.metadata,\n\t\t\tcause: error instanceof Error ? error.cause : undefined,\n\t\t});\n\t}\n\n\treturn new RivetError(\n\t\tfallback?.group ?? \"actor\",\n\t\tfallback?.code ?? INTERNAL_ERROR_CODE,\n\t\terrorMessage(error, fallback?.message ?? \"Unknown error\"),\n\t\t{\n\t\t\tpublic: fallback?.public,\n\t\t\tstatusCode: fallback?.statusCode,\n\t\t\tmetadata: fallback?.metadata,\n\t\t\tcause: error instanceof Error ? error : undefined,\n\t\t},\n\t);\n}\n\nexport function encodeBridgeRivetError(error: RivetErrorLike): string {\n\treturn `${BRIDGE_RIVET_ERROR_PREFIX}${JSON.stringify({\n\t\tgroup: error.group,\n\t\tcode: error.code,\n\t\tmessage: error.message,\n\t\tmetadata: error.metadata,\n\t\tpublic: error.public,\n\t\tstatusCode: error.statusCode,\n\t})}`;\n}\n\nexport function decodeBridgeRivetError(value: string): RivetError | undefined {\n\tif (!value.startsWith(BRIDGE_RIVET_ERROR_PREFIX)) {\n\t\treturn undefined;\n\t}\n\n\ttry {\n\t\tconst payload = JSON.parse(\n\t\t\tvalue.slice(BRIDGE_RIVET_ERROR_PREFIX.length),\n\t\t) as RivetErrorLike;\n\t\tif (!isRivetErrorLike(payload)) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\treturn new RivetError(payload.group, payload.code, payload.message, {\n\t\t\tmetadata: payload.metadata,\n\t\t\tpublic: payload.public,\n\t\t\tstatusCode: payload.statusCode,\n\t\t});\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nexport function isRivetErrorCode(\n\terror: unknown,\n\tgroup: string,\n\tcode: string,\n): error is RivetError {\n\treturn (\n\t\tisRivetErrorLike(error) && error.group === group && error.code === code\n\t);\n}\n\nexport function internalError(\n\tmessage: string,\n\toptions?: Partial<RivetErrorOptions> & {\n\t\tgroup?: string;\n\t\tcode?: string;\n\t},\n): RivetError {\n\treturn new RivetError(\n\t\toptions?.group ?? \"actor\",\n\t\toptions?.code ?? INTERNAL_ERROR_CODE,\n\t\tmessage,\n\t\t{\n\t\t\tpublic: options?.public,\n\t\t\tstatusCode: options?.statusCode,\n\t\t\tmetadata: options?.metadata,\n\t\t\tcause: options?.cause,\n\t\t},\n\t);\n}\n\nexport function invalidEncoding(format?: string): RivetError {\n\treturn new RivetError(\n\t\t\"encoding\",\n\t\t\"invalid\",\n\t\t`Invalid encoding \\`${format}\\`. (https://www.rivet.dev/docs/clients/javascript)`,\n\t\t{\n\t\t\tpublic: true,\n\t\t},\n\t);\n}\n\nexport function invalidRequest(error?: unknown): RivetError {\n\treturn new RivetError(\n\t\t\"request\",\n\t\t\"invalid\",\n\t\t`Invalid request: ${errorMessage(error, String(error))}`,\n\t\t{\n\t\t\tpublic: true,\n\t\t\tcause: error instanceof Error ? error : undefined,\n\t\t},\n\t);\n}\n\nexport function actorNotFound(identifier?: string): RivetError {\n\treturn new RivetError(\n\t\t\"actor\",\n\t\t\"not_found\",\n\t\tidentifier\n\t\t\t? `Actor not found: ${identifier} (https://www.rivet.dev/docs/clients/javascript)`\n\t\t\t: \"Actor not found (https://www.rivet.dev/docs/clients/javascript)\",\n\t\t{ public: true },\n\t);\n}\n\nexport function actorStopping(identifier?: string): RivetError {\n\treturn new RivetError(\n\t\t\"actor\",\n\t\t\"stopping\",\n\t\tidentifier ? `Actor stopping: ${identifier}` : \"Actor stopping\",\n\t\t{ public: true },\n\t);\n}\n\nexport interface ActorRestartingOptions {\n\tphase?: \"stopping\" | \"sleeping\" | \"waking\" | \"runner_shutdown\";\n\tretryAfterMs?: number;\n}\n\nexport function actorRestarting(opts?: ActorRestartingOptions): RivetError {\n\treturn new RivetError(\n\t\t\"actor\",\n\t\t\"restarting\",\n\t\t\"Actor is restarting. Retry the request.\",\n\t\t{\n\t\t\tpublic: true,\n\t\t\tstatusCode: 503,\n\t\t\tmetadata: {\n\t\t\t\tretryable: true,\n\t\t\t\t...(opts?.phase ? { phase: opts.phase } : {}),\n\t\t\t\t...(opts?.retryAfterMs !== undefined\n\t\t\t\t\t? { retryAfterMs: opts.retryAfterMs }\n\t\t\t\t\t: {}),\n\t\t\t},\n\t\t},\n\t);\n}\n\nexport function forbiddenError(): RivetError {\n\treturn new RivetError(\"auth\", \"forbidden\", \"Forbidden\", {\n\t\tpublic: true,\n\t\tstatusCode: 403,\n\t});\n}\n\nexport function unsupportedFeature(feature: string): RivetError {\n\treturn new RivetError(\n\t\t\"feature\",\n\t\t\"unsupported\",\n\t\t`Unsupported feature: ${feature}`,\n\t);\n}\n","{\n\t\"name\": \"rivetkit\",\n\t\"version\": \"2.3.0-rc.5\",\n\t\"description\": \"Lightweight libraries for building stateful actors on edge platforms\",\n\t\"license\": \"Apache-2.0\",\n\t\"keywords\": [\n\t\t\"rivetkit\",\n\t\t\"stateful\",\n\t\t\"serverless\",\n\t\t\"actors\",\n\t\t\"agents\",\n\t\t\"realtime\",\n\t\t\"websocket\",\n\t\t\"actors\",\n\t\t\"framework\"\n\t],\n\t\"files\": [\n\t\t\"dist\",\n\t\t\"schemas\",\n\t\t\"src\",\n\t\t\"package.json\"\n\t],\n\t\"type\": \"module\",\n\t\"exports\": {\n\t\t\".\": {\n\t\t\t\"import\": {\n\t\t\t\t\"types\": \"./dist/tsup/mod.d.ts\",\n\t\t\t\t\"default\": \"./dist/tsup/mod.js\"\n\t\t\t},\n\t\t\t\"require\": {\n\t\t\t\t\"types\": \"./dist/tsup/mod.d.cts\",\n\t\t\t\t\"default\": \"./dist/tsup/mod.cjs\"\n\t\t\t}\n\t\t},\n\t\t\"./workflow\": {\n\t\t\t\"import\": {\n\t\t\t\t\"types\": \"./dist/tsup/workflow/mod.d.ts\",\n\t\t\t\t\"default\": \"./dist/tsup/workflow/mod.js\"\n\t\t\t},\n\t\t\t\"require\": {\n\t\t\t\t\"types\": \"./dist/tsup/workflow/mod.d.cts\",\n\t\t\t\t\"default\": \"./dist/tsup/workflow/mod.cjs\"\n\t\t\t}\n\t\t},\n\t\t\"./test\": {\n\t\t\t\"import\": {\n\t\t\t\t\"types\": \"./dist/tsup/test/mod.d.ts\",\n\t\t\t\t\"default\": \"./dist/tsup/test/mod.js\"\n\t\t\t},\n\t\t\t\"require\": {\n\t\t\t\t\"types\": \"./dist/tsup/test/mod.d.cts\",\n\t\t\t\t\"default\": \"./dist/tsup/test/mod.cjs\"\n\t\t\t}\n\t\t},\n\t\t\"./db\": {\n\t\t\t\"import\": {\n\t\t\t\t\"types\": \"./dist/tsup/db/mod.d.ts\",\n\t\t\t\t\"default\": \"./dist/tsup/db/mod.js\"\n\t\t\t},\n\t\t\t\"require\": {\n\t\t\t\t\"types\": \"./dist/tsup/db/mod.d.cts\",\n\t\t\t\t\"default\": \"./dist/tsup/db/mod.cjs\"\n\t\t\t}\n\t\t},\n\t\t\"./db/drizzle\": {\n\t\t\t\"import\": {\n\t\t\t\t\"types\": \"./dist/tsup/db/drizzle.d.ts\",\n\t\t\t\t\"default\": \"./dist/tsup/db/drizzle.js\"\n\t\t\t},\n\t\t\t\"require\": {\n\t\t\t\t\"types\": \"./dist/tsup/db/drizzle.d.cts\",\n\t\t\t\t\"default\": \"./dist/tsup/db/drizzle.cjs\"\n\t\t\t}\n\t\t},\n\t\t\"./client\": {\n\t\t\t\"import\": {\n\t\t\t\t\"browser\": {\n\t\t\t\t\t\"types\": \"./dist/browser/client.d.ts\",\n\t\t\t\t\t\"default\": \"./dist/browser/client.js\"\n\t\t\t\t},\n\t\t\t\t\"types\": \"./dist/tsup/client/mod.d.ts\",\n\t\t\t\t\"default\": \"./dist/tsup/client/mod.js\"\n\t\t\t},\n\t\t\t\"require\": {\n\t\t\t\t\"types\": \"./dist/tsup/client/mod.d.cts\",\n\t\t\t\t\"default\": \"./dist/tsup/client/mod.cjs\"\n\t\t\t}\n\t\t},\n\t\t\"./log\": {\n\t\t\t\"import\": {\n\t\t\t\t\"types\": \"./dist/tsup/common/log.d.ts\",\n\t\t\t\t\"default\": \"./dist/tsup/common/log.js\"\n\t\t\t},\n\t\t\t\"require\": {\n\t\t\t\t\"types\": \"./dist/tsup/common/log.d.cts\",\n\t\t\t\t\"default\": \"./dist/tsup/common/log.cjs\"\n\t\t\t}\n\t\t},\n\t\t\"./errors\": {\n\t\t\t\"import\": {\n\t\t\t\t\"types\": \"./dist/tsup/actor/errors.d.ts\",\n\t\t\t\t\"default\": \"./dist/tsup/actor/errors.js\"\n\t\t\t},\n\t\t\t\"require\": {\n\t\t\t\t\"types\": \"./dist/tsup/actor/errors.d.cts\",\n\t\t\t\t\"default\": \"./dist/tsup/actor/errors.cjs\"\n\t\t\t}\n\t\t},\n\t\t\"./inspector\": {\n\t\t\t\"import\": {\n\t\t\t\t\"types\": \"./dist/tsup/inspector/mod.d.ts\",\n\t\t\t\t\"default\": \"./dist/tsup/inspector/mod.js\"\n\t\t\t},\n\t\t\t\"require\": {\n\t\t\t\t\"types\": \"./dist/tsup/inspector/mod.d.cts\",\n\t\t\t\t\"default\": \"./dist/tsup/inspector/mod.cjs\"\n\t\t\t}\n\t\t},\n\t\t\"./inspector/client\": {\n\t\t\t\"import\": {\n\t\t\t\t\"types\": \"./dist/browser/inspector/client.d.ts\",\n\t\t\t\t\"default\": \"./dist/browser/inspector/client.js\"\n\t\t\t}\n\t\t},\n\t\t\"./utils\": {\n\t\t\t\"import\": {\n\t\t\t\t\"types\": \"./dist/tsup/utils.d.ts\",\n\t\t\t\t\"default\": \"./dist/tsup/utils.js\"\n\t\t\t},\n\t\t\t\"require\": {\n\t\t\t\t\"types\": \"./dist/tsup/utils.d.cts\",\n\t\t\t\t\"default\": \"./dist/tsup/utils.cjs\"\n\t\t\t}\n\t\t},\n\t\t\"./agent-os\": {\n\t\t\t\"import\": {\n\t\t\t\t\"types\": \"./dist/tsup/agent-os/index.d.ts\",\n\t\t\t\t\"default\": \"./dist/tsup/agent-os/index.js\"\n\t\t\t},\n\t\t\t\"require\": {\n\t\t\t\t\"types\": \"./dist/tsup/agent-os/index.d.cts\",\n\t\t\t\t\"default\": \"./dist/tsup/agent-os/index.cjs\"\n\t\t\t}\n\t\t}\n\t},\n\t\"engines\": {\n\t\t\"node\": \">=22.0.0\"\n\t},\n\t\"sideEffects\": [\n\t\t\"./dist/tsup/chunk-*.js\",\n\t\t\"./dist/tsup/chunk-*.cjs\"\n\t],\n\t\"scripts\": {\n\t\t\"build\": \"tsup src/mod.ts src/client/mod.ts src/common/log.ts src/common/websocket.ts src/actor/errors.ts src/utils.ts src/workflow/mod.ts src/test/mod.ts src/inspector/mod.ts src/db/mod.ts src/db/drizzle.ts && tsup src/agent-os/index.ts --no-clean --out-dir dist/tsup/agent-os\",\n\t\t\"build:browser\": \"tsup --config tsup.browser.config.ts\",\n\t\t\"check-types\": \"tsc --noEmit\",\n\t\t\"lint\": \"biome check . && pnpm run check:test-skips && pnpm run check:wait-for-comments\",\n\t\t\"lint:fix\": \"biome check --write .\",\n\t\t\"check:test-skips\": \"tsx scripts/check-annotated-skips.ts\",\n\t\t\"check:wait-for-comments\": \"tsx scripts/check-wait-for-comments.ts\",\n\t\t\"format\": \"biome format .\",\n\t\t\"format:write\": \"biome format --write .\",\n\t\t\"test\": \"vitest run\",\n\t\t\"test:platforms\": \"pnpm run build && RIVETKIT_INCLUDE_PLATFORM_TESTS=1 vitest run tests/platforms --passWithNoTests\",\n\t\t\"test:watch\": \"vitest\",\n\t\t\"dump-asyncapi\": \"tsx scripts/dump-asyncapi.ts\",\n\t\t\"registry-config-schema-gen\": \"tsx scripts/registry-config-schema-gen.ts\",\n\t\t\"actor-config-schema-gen\": \"tsx scripts/actor-config-schema-gen.ts\"\n\t},\n\t\"dependencies\": {\n\t\t\"@rivet-dev/agent-os-core\": \"^0.1.1\",\n\t\t\"@hono/node-server\": \"^1.18.2\",\n\t\t\"@hono/node-ws\": \"^1.1.1\",\n\t\t\"@hono/zod-openapi\": \"^1.1.5\",\n\t\t\"@rivetkit/bare-ts\": \"^0.6.2\",\n\t\t\"@rivetkit/engine-cli\": \"workspace:*\",\n\t\t\"@rivetkit/engine-envoy-protocol\": \"workspace:*\",\n\t\t\"@rivetkit/rivetkit-napi\": \"workspace:*\",\n\t\t\"@rivetkit/rivetkit-wasm\": \"workspace:*\",\n\t\t\"@rivetkit/traces\": \"workspace:*\",\n\t\t\"@rivetkit/virtual-websocket\": \"workspace:*\",\n\t\t\"@rivetkit/workflow-engine\": \"workspace:*\",\n\t\t\"cbor-x\": \"^1.6.0\",\n\t\t\"drizzle-orm\": \"^0.44.2\",\n\t\t\"get-port\": \"^7.1.0\",\n\t\t\"hono\": \"^4.7.0\",\n\t\t\"invariant\": \"^2.2.4\",\n\t\t\"p-retry\": \"^6.2.1\",\n\t\t\"pino\": \"^9.5.0\",\n\t\t\"uuid\": \"^12.0.0\",\n\t\t\"vbare\": \"^0.0.4\",\n\t\t\"zod\": \"^4.1.0\"\n\t},\n\t\"devDependencies\": {\n\t\t\"@copilotkit/llmock\": \"^1.6.0\",\n\t\t\"@rivet-dev/agent-os-common\": \"*\",\n\t\t\"@rivet-dev/agent-os-pi\": \"^0.1.1\",\n\t\t\"@biomejs/biome\": \"^2.3\",\n\t\t\"@standard-schema/spec\": \"^1.0.0\",\n\t\t\"@types/invariant\": \"^2\",\n\t\t\"@types/node\": \"^22.13.1\",\n\t\t\"eventsource\": \"^4.0.0\",\n\t\t\"tsup\": \"^8.4.0\",\n\t\t\"tsx\": \"^4.19.4\",\n\t\t\"typescript\": \"^5.7.3\",\n\t\t\"vite-tsconfig-paths\": \"^5.1.4\",\n\t\t\"vitest\": \"^3.1.1\",\n\t\t\"ws\": \"^8.18.1\"\n\t},\n\t\"peerDependencies\": {\n\t\t\"drizzle-kit\": \"^0.31.2\",\n\t\t\"eventsource\": \"^4.0.0\",\n\t\t\"ws\": \"^8.0.0\"\n\t},\n\t\"peerDependenciesMeta\": {\n\t\t\"drizzle-kit\": {\n\t\t\t\"optional\": true\n\t\t},\n\t\t\"eventsource\": {\n\t\t\t\"optional\": true\n\t\t},\n\t\t\"ws\": {\n\t\t\t\"optional\": true\n\t\t}\n\t},\n\t\"stableVersion\": \"0.8.0\"\n}\n","import { stringifyError } from \"@/common/utils\";\nimport type { Context as HonoContext, Handler as HonoHandler } from \"hono\";\nimport { stringify as uuidstringify } from \"uuid\";\nimport pkgJson from \"../package.json\" with { type: \"json\" };\nimport { getLogger } from \"./common/log\";\nimport { assertUnreachable } from \"./common/utils\";\n\n/** @experimental */\nexport { stringifyError };\n\n/** @experimental */\nexport { assertUnreachable };\n\n/**\n * Joins multiple abort signals into one.\n *\n * The returned signal aborts when the first input signal aborts.\n * Uses `AbortSignal.any(...)` when available, with a runtime fallback.\n *\n * @experimental\n */\nexport function joinSignals(\n\t...signals: Array<AbortSignal | undefined | null>\n): AbortSignal {\n\tconst validSignals = signals.filter(\n\t\t(signal): signal is AbortSignal => signal != null,\n\t);\n\n\tif (validSignals.length === 0) {\n\t\treturn new AbortController().signal;\n\t}\n\n\tif (validSignals.length === 1) {\n\t\treturn validSignals[0];\n\t}\n\n\tconst signalAny = (\n\t\tAbortSignal as typeof AbortSignal & {\n\t\t\tany?: (signals: AbortSignal[]) => AbortSignal;\n\t\t}\n\t).any;\n\tif (typeof signalAny === \"function\") {\n\t\treturn signalAny(validSignals);\n\t}\n\n\tconst controller = new AbortController();\n\tconst cleanups: Array<() => void> = [];\n\n\tconst abortWithSignal = (signal: AbortSignal) => {\n\t\tif (controller.signal.aborted) {\n\t\t\treturn;\n\t\t}\n\n\t\tfor (const cleanup of cleanups) {\n\t\t\tcleanup();\n\t\t}\n\n\t\tconst reason = (signal as AbortSignal & { reason?: unknown }).reason;\n\t\tcontroller.abort(reason);\n\t};\n\n\tfor (const signal of validSignals) {\n\t\tif (signal.aborted) {\n\t\t\tabortWithSignal(signal);\n\t\t\tbreak;\n\t\t}\n\n\t\tconst onAbort = () => abortWithSignal(signal);\n\t\tsignal.addEventListener(\"abort\", onAbort, { once: true });\n\t\tcleanups.push(() => signal.removeEventListener(\"abort\", onAbort));\n\t}\n\n\treturn controller.signal;\n}\n\n/**\n * Returns a promise that resolves after the given number of milliseconds.\n *\n * @experimental\n */\nexport function sleep(ms: number): Promise<void> {\n\treturn new Promise<void>((resolve) => setTimeout(resolve, ms));\n}\n\n/**\n * Creates a fixed-rate interval tick function that can be awaited in a loop.\n *\n * @example\n * const tick = interval(100);\n * while (!c.aborted) {\n * await tick();\n * if (c.aborted) break;\n * // ... game logic\n * }\n *\n * @experimental\n */\nexport function interval(ms: number): () => Promise<void> {\n\treturn () => sleep(ms);\n}\n\nexport const VERSION = pkgJson.version;\n\nlet _userAgent: string | undefined;\n\nfunction logger() {\n\treturn getLogger(\"utils\");\n}\n\n/**\n * Builds the HTTP user agent used by this library.\n *\n * @experimental\n */\nexport function httpUserAgent(): string {\n\t// Return cached value if already initialized\n\tif (_userAgent !== undefined) {\n\t\treturn _userAgent;\n\t}\n\n\t// Library\n\tlet userAgent = `RivetKit/${VERSION}`;\n\n\t// Navigator\n\tconst navigatorObj =\n\t\ttypeof navigator !== \"undefined\" ? navigator : undefined;\n\tif (navigatorObj?.userAgent) userAgent += ` ${navigatorObj.userAgent}`;\n\n\t_userAgent = userAgent;\n\n\treturn userAgent;\n}\n\nexport type UpgradeWebSocket = (\n\tcreateEvents: (c: HonoContext) => any,\n) => HonoHandler;\n\nexport type GetUpgradeWebSocket = () => UpgradeWebSocket;\n\n/**\n * Reads an environment variable from Deno or Node runtimes.\n *\n * @experimental\n */\nexport function getEnvUniversal(key: string): string | undefined {\n\tif (typeof Deno !== \"undefined\") {\n\t\treturn Deno.env.get(key);\n\t} else if (typeof process !== \"undefined\") {\n\t\t// Do this after Deno since `process` is sometimes polyfilled\n\t\treturn process.env[key];\n\t}\n}\n\n/**\n * Traces a debug value and returns it.\n *\n * @experimental\n */\nexport function dbg<T>(x: T): T {\n\tconsole.trace(`=== DEBUG ===\\n${x}`);\n\treturn x;\n}\n\n/**\n * Converts various ArrayBuffer-like types to Uint8Array.\n * Handles ArrayBuffer, ArrayBufferView (including typed arrays), and passes through existing Uint8Array.\n *\n * @param data - The ArrayBuffer or ArrayBufferView to convert\n * @returns A Uint8Array view of the data\n *\n * @experimental\n */\nexport function toUint8Array(data: ArrayBuffer | ArrayBufferView): Uint8Array {\n\tif (data instanceof Uint8Array) {\n\t\treturn data;\n\t} else if (data instanceof ArrayBuffer) {\n\t\treturn new Uint8Array(data);\n\t} else if (ArrayBuffer.isView(data)) {\n\t\t// Handle other ArrayBufferView types (Int8Array, Uint16Array, DataView, etc.)\n\t\treturn new Uint8Array(\n\t\t\tdata.buffer.slice(\n\t\t\t\tdata.byteOffset,\n\t\t\t\tdata.byteOffset + data.byteLength,\n\t\t\t),\n\t\t);\n\t} else {\n\t\tthrow new TypeError(\"Input must be ArrayBuffer or ArrayBufferView\");\n\t}\n}\n\n// Long timeouts\n//\n// JavaScript timers use a signed 32-bit integer for delays, so values above 2^31-1 (~24.8 days)\n// are not reliable and may fire immediately or overflow.\n//\n// https://developer.mozilla.org/en-US/docs/Web/API/Window/setTimeout#maximum_delay_value\nconst TIMEOUT_MAX = 2147483647; // 2^31-1\n\nexport type LongTimeoutHandle = { abort: () => void };\n\n/**\n * Polyfill for Promise.withResolvers().\n *\n * This is specifically for Cloudflare Workers. Their implementation of Promise.withResolvers does not work correctly.\n *\n * @experimental\n */\nexport function promiseWithResolvers<T>(onReject: (reason?: any) => void): {\n\tpromise: Promise<T>;\n\tresolve: (value: T | PromiseLike<T>) => void;\n\treject: (reason?: any) => void;\n} {\n\tlet resolve!: (value: T | PromiseLike<T>) => void;\n\tlet reject!: (reason?: any) => void;\n\tconst promise = new Promise<T>((res, rej) => {\n\t\tresolve = res;\n\t\treject = rej;\n\t});\n\tpromise.catch(onReject);\n\treturn { promise, resolve, reject };\n}\n\n/**\n * Sets a timeout that supports delays larger than the JavaScript timer limit.\n *\n * @experimental\n */\nexport function setLongTimeout(\n\tlistener: () => void,\n\tafter: number,\n): LongTimeoutHandle {\n\tlet timeout: ReturnType<typeof setTimeout> | undefined;\n\n\tfunction start(remaining: number) {\n\t\tif (remaining <= TIMEOUT_MAX) {\n\t\t\ttimeout = setTimeout(listener, remaining);\n\t\t} else {\n\t\t\ttimeout = setTimeout(() => {\n\t\t\t\tstart(remaining - TIMEOUT_MAX);\n\t\t\t}, TIMEOUT_MAX);\n\t\t}\n\t}\n\n\tstart(after);\n\n\treturn {\n\t\tabort: () => {\n\t\t\tif (timeout !== undefined) clearTimeout(timeout);\n\t\t},\n\t};\n}\n\n/**\n * A tiny utility that coalesces/enqueues async operations so only the latest\n * queued task runs per cycle, while callers receive a promise that resolves\n * when the task for the cycle they joined has completed.\n */\nexport class SinglePromiseQueue {\n\t/** Next operation to execute in the queue. If attempting to enqueue another op, it will override the existing op. */\n\t#queuedOp?: () => Promise<void>;\n\n\t/** The currently running promise of #drainLoop. Do not await this, instead await `pending` to await the current cycle. */\n\trunningDrainLoop?: Promise<void>;\n\n\t/** Pending resolver fro the currently queued entry. */\n\t#pending?: ReturnType<typeof promiseWithResolvers<void>>;\n\n\t/** Queue the next operation and return a promise that resolves when it flushes. */\n\tenqueue(op: () => Promise<void>): Promise<void> {\n\t\t// Replace any previously queued operation with the latest one\n\t\tthis.#queuedOp = op;\n\n\t\t// Ensure a shared resolver exists for all callers in this cycle\n\t\tif (!this.#pending) {\n\t\t\tthis.#pending = promiseWithResolvers<void>((reason) =>\n\t\t\t\tlogger().warn({\n\t\t\t\t\tmsg: \"unhandled single promise queue rejection\",\n\t\t\t\t\treason,\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\n\t\tconst waitForThisCycle = this.#pending.promise;\n\n\t\t// Start runner if not already running\n\t\tif (!this.runningDrainLoop) {\n\t\t\tthis.runningDrainLoop = this.#drainLoop();\n\t\t}\n\n\t\treturn waitForThisCycle;\n\t}\n\n\t/** Drain queued operations sequentially until there is nothing left. */\n\tasync #drainLoop(): Promise<void> {\n\t\ttry {\n\t\t\twhile (this.#queuedOp) {\n\t\t\t\t// Capture current cycle resolver then reset for the next cycle\n\t\t\t\tconst resolver = this.#pending;\n\t\t\t\tthis.#pending = undefined;\n\n\t\t\t\t// Capture and clear the currently queued operation\n\t\t\t\tconst op = this.#queuedOp;\n\t\t\t\tthis.#queuedOp = undefined;\n\n\t\t\t\ttry {\n\t\t\t\t\tawait op();\n\t\t\t\t\t// Notify all waiters for this cycle\n\t\t\t\t\tresolver?.resolve();\n\t\t\t\t} catch (err) {\n\t\t\t\t\tlogger().error({\n\t\t\t\t\t\tmsg: \"error in SinglePromiseQueue drain loop\",\n\t\t\t\t\t\terror: stringifyError(err),\n\t\t\t\t\t});\n\t\t\t\t\t// Reject all waiters for this cycle\n\t\t\t\t\tresolver?.reject(err);\n\t\t\t\t}\n\t\t\t}\n\t\t} finally {\n\t\t\tthis.runningDrainLoop = undefined;\n\t\t}\n\t}\n}\n\n/**\n * Converts a Buffer or Uint8Array into an ArrayBuffer view.\n *\n * @experimental\n */\nexport function bufferToArrayBuffer(buf: Buffer | Uint8Array): ArrayBuffer {\n\treturn buf.buffer.slice(\n\t\tbuf.byteOffset,\n\t\tbuf.byteOffset + buf.byteLength,\n\t) as ArrayBuffer;\n}\n\n/**\n * Properly combines a base URL endpoint with a path, preserving any base path in the endpoint.\n *\n * @example\n * combineUrlPath(\"http://localhost:8787/rivet\", \"/actors/action\")\n * // Returns: \"http://localhost:8787/rivet/actors/action\"\n *\n * @example\n * combineUrlPath(\"http://localhost:8787/rivet\", \"/actors?type=foo\", { namespace: \"test\" })\n * // Returns: \"http://localhost:8787/rivet/actors?type=foo&namespace=test\"\n *\n * @param endpoint The base URL endpoint that may contain a path component\n * @param path The path to append to the endpoint (may include query parameters)\n * @param queryParams Optional additional query parameters to append\n * @returns The properly combined URL string\n *\n * @experimental\n */\nexport function combineUrlPath(\n\tendpoint: string,\n\tpath: string,\n\tqueryParams?: Record<string, string | undefined>,\n): string {\n\tconst baseUrl = new URL(endpoint);\n\n\t// Extract path and query from the provided path\n\tconst pathParts = path.split(\"?\");\n\tconst pathOnly = pathParts[0];\n\tconst existingQuery = pathParts[1] || \"\";\n\n\t// Remove trailing slash from base path and ensure path starts with /\n\tconst basePath = baseUrl.pathname.replace(/\\/$/, \"\");\n\tconst cleanPath = pathOnly.startsWith(\"/\") ? pathOnly : `/${pathOnly}`;\n\t// Combine paths and remove any double slashes\n\tconst fullPath = (basePath + cleanPath).replace(/\\/\\//g, \"/\");\n\n\t// Build query string\n\tconst queryParts: string[] = [];\n\tif (existingQuery) {\n\t\tqueryParts.push(existingQuery);\n\t}\n\tif (queryParams) {\n\t\tfor (const [key, value] of Object.entries(queryParams)) {\n\t\t\tif (value !== undefined) {\n\t\t\t\tqueryParts.push(\n\t\t\t\t\t`${encodeURIComponent(key)}=${encodeURIComponent(value)}`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\tconst fullQuery = queryParts.length > 0 ? `?${queryParts.join(\"&\")}` : \"\";\n\treturn `${baseUrl.protocol}//${baseUrl.host}${fullPath}${fullQuery}`;\n}\n\n/**\n * Compares two ArrayBuffer values by byte content.\n *\n * @experimental\n */\nexport function arrayBuffersEqual(\n\tbuf1: ArrayBuffer,\n\tbuf2: ArrayBuffer,\n): boolean {\n\tif (buf1.byteLength !== buf2.byteLength) return false;\n\n\tconst view1 = new Uint8Array(buf1);\n\tconst view2 = new Uint8Array(buf2);\n\n\tfor (let i = 0; i < view1.length; i++) {\n\t\tif (view1[i] !== view2[i]) return false;\n\t}\n\treturn true;\n}\n\nexport const EXTRA_ERROR_LOG = {\n\tissues: \"https://github.com/rivet-dev/rivet/issues\",\n\tsupport: \"https://rivet.dev/discord\",\n\tversion: VERSION,\n};\n\nexport type Runtime = \"deno\" | \"bun\" | \"node\";\n\n/**\n * Detects the current JavaScript runtime from the user agent.\n *\n * @experimental\n */\nexport function detectRuntime(): Runtime {\n\tconst userAgent =\n\t\ttypeof navigator !== \"undefined\" ? navigator.userAgent : \"\";\n\tif (userAgent.includes(\"Deno\")) {\n\t\treturn \"deno\";\n\t}\n\tif (userAgent.includes(\"Bun\")) {\n\t\treturn \"bun\";\n\t}\n\treturn \"node\";\n}\n\nexport type DeepReadonly<T> = {\n\treadonly [K in keyof T]: T[K] extends object ? DeepReadonly<T[K]> : T[K];\n};\n\nexport type DeepMutable<T> = {\n\t-readonly [K in keyof T]: T[K] extends object ? DeepMutable<T[K]> : T[K];\n};\n","// This file consolidates all environment variables that affect RivetKit's behavior.\n//\n// IMPORTANT: When adding or modifying environment variables here, also update the\n// documentation at: website/src/content/docs/general/environment-variables.mdx\n\nimport { getEnvUniversal } from \"@/utils\";\n\n// Rivet configuration\nexport const getRivetEngine = (): string | undefined =>\n\tgetEnvUniversal(\"RIVET_ENGINE\");\nexport const getRivetEndpoint = (): string | undefined =>\n\tgetEnvUniversal(\"RIVET_ENDPOINT\");\nexport const getRivetToken = (): string | undefined =>\n\tgetEnvUniversal(\"RIVET_TOKEN\");\nexport const getRivetNamespace = (): string | undefined =>\n\tgetEnvUniversal(\"RIVET_NAMESPACE\");\nexport const getRivetPool = (): string | undefined =>\n\tgetEnvUniversal(\"RIVET_POOL\");\nexport const getRivetTotalSlots = (): number | undefined => {\n\tconst value = getEnvUniversal(\"RIVET_TOTAL_SLOTS\");\n\treturn value !== undefined ? parseInt(value, 10) : undefined;\n};\nexport const getRivetRunEngine = (): boolean =>\n\tgetEnvUniversal(\"RIVET_RUN_ENGINE\") === \"1\";\nexport const getRivetRunEngineVersion = (): string | undefined =>\n\tgetEnvUniversal(\"RIVET_RUN_ENGINE_VERSION\");\nexport const getRivetEnvoyKind = (): string | undefined =>\n\tgetEnvUniversal(\"RIVET_ENVOY_KIND\");\nexport const getRivetEnvoyVersion = (): number | undefined => {\n\tconst value = getEnvUniversal(\"RIVET_ENVOY_VERSION\");\n\treturn value !== undefined ? parseInt(value, 10) : undefined;\n};\nexport const getRivetPublicEndpoint = (): string | undefined =>\n\tgetEnvUniversal(\"RIVET_PUBLIC_ENDPOINT\");\nexport const getRivetPublicToken = (): string | undefined =>\n\tgetEnvUniversal(\"RIVET_PUBLIC_TOKEN\");\n// There is no RIVET_PUBLIC_NAMESPACE because the frontend and backend cannot\n// use different namespaces\n\n// RivetKit configuration\nexport const getRivetkitInspectorDisable = (): boolean =>\n\tgetEnvUniversal(\"RIVET_INSPECTOR_DISABLE\") === \"1\";\nexport const getRivetkitStoragePath = (): string | undefined =>\n\tgetEnvUniversal(\"RIVETKIT_STORAGE_PATH\");\nexport const getRivetkitRuntime = (): string | undefined =>\n\tgetEnvUniversal(\"RIVETKIT_RUNTIME\");\n\n// Logging configuration\n// DEPRECATED: LOG_LEVEL will be removed in a future version\nexport const getLogLevel = (): string | undefined =>\n\tgetEnvUniversal(\"RIVET_LOG_LEVEL\") ?? getEnvUniversal(\"LOG_LEVEL\");\nexport const getLogTarget = (): boolean =>\n\tgetEnvUniversal(\"RIVET_LOG_TARGET\") === \"1\";\nexport const getLogTimestamp = (): boolean =>\n\tgetEnvUniversal(\"RIVET_LOG_TIMESTAMP\") === \"1\";\nexport const getLogMessage = (): boolean =>\n\tgetEnvUniversal(\"RIVET_LOG_MESSAGE\") === \"1\";\nexport const getLogErrorStack = (): boolean =>\n\tgetEnvUniversal(\"RIVET_LOG_ERROR_STACK\") === \"1\";\nexport const getLogHeaders = (): boolean =>\n\tgetEnvUniversal(\"RIVET_LOG_HEADERS\") === \"1\";\n\n// Environment configuration\nexport const getNodeEnv = (): string | undefined => getEnvUniversal(\"NODE_ENV\");\nexport const getNextPhase = (): string | undefined =>\n\tgetEnvUniversal(\"NEXT_PHASE\");\nexport const isDev = (): boolean => getNodeEnv() !== \"production\";\n\n// Experimental\n/**\n * Enables experimental OTel tracing for Rivet Actors.\n *\n * When disabled, actors use an in-memory no-op traces implementation.\n */\nexport const getRivetExperimentalOtel = (): boolean =>\n\tgetEnvUniversal(\"RIVET_EXPERIMENTAL_OTEL\") === \"1\";\n","import { getLogger } from \"@/common/log\";\n\n/** Prever to use ActorInstance.rlog child logger. This does not provide context in the log, should only be used as a last resort if you cannot pass the actor's child logger. */\nexport function loggerWithoutContext() {\n\treturn getLogger(\"actor-runtime\");\n}\n","import type { RegistryConfig } from \"@/registry/config\";\nimport { ActorConfigSchema, type Actions, type ActorConfig, type ActorConfigInput } from \"./config\";\nimport { loggerWithoutContext } from \"./log\";\nimport type { AnyDatabaseProvider } from \"@/common/database/config\";\nimport type { EventSchemaConfig, QueueSchemaConfig } from \"./schema\";\n\nconst warnedDeprecatedTimeoutKeys = new Set<string>();\n\nfunction warnDeprecatedShutdownTimeoutKeys(options: unknown) {\n\tif (!options || typeof options !== \"object\") return;\n\tconst opts = options as Record<string, unknown>;\n\tfor (const key of [\"onDestroyTimeout\", \"waitUntilTimeout\"]) {\n\t\tif (opts[key] !== undefined && !warnedDeprecatedTimeoutKeys.has(key)) {\n\t\t\twarnedDeprecatedTimeoutKeys.add(key);\n\t\t\tloggerWithoutContext().warn({\n\t\t\t\tmsg: `actor option \\`${key}\\` is deprecated and is now ignored. Configure \\`sleepGracePeriod\\` instead, which bounds the entire graceful shutdown window for both sleep and destroy. Will be removed in 2.2.0.`,\n\t\t\t});\n\t\t}\n\t}\n}\n\nexport interface BaseActorDefinition<\n\tS,\n\tCP,\n\tCS,\n\tV,\n\tI,\n\tDB extends AnyDatabaseProvider,\n\tE extends EventSchemaConfig = Record<never, never>,\n\tQ extends QueueSchemaConfig = Record<never, never>,\n\tR extends Actions<S, CP, CS, V, I, DB, E, Q> = Actions<\n\t\tS,\n\t\tCP,\n\t\tCS,\n\t\tV,\n\t\tI,\n\t\tDB,\n\t\tE,\n\t\tQ\n\t>,\n> {\n\treadonly config: ActorConfig<S, CP, CS, V, I, DB, E, Q>;\n}\n\nexport type AnyActorDefinition = BaseActorDefinition<\n\tany,\n\tany,\n\tany,\n\tany,\n\tany,\n\tany,\n\tany,\n\tany,\n\tany\n>;\n\nexport type AnyStaticActorDefinition = ActorDefinition<\n\tany,\n\tany,\n\tany,\n\tany,\n\tany,\n\tany,\n\tany,\n\tany,\n\tany\n>;\n\nexport class ActorDefinition<\n\tS,\n\tCP,\n\tCS,\n\tV,\n\tI,\n\tDB extends AnyDatabaseProvider,\n\tE extends EventSchemaConfig = Record<never, never>,\n\tQ extends QueueSchemaConfig = Record<never, never>,\n\tR extends Actions<S, CP, CS, V, I, DB, E, Q> = Actions<\n\t\tS,\n\t\tCP,\n\t\tCS,\n\t\tV,\n\t\tI,\n\t\tDB,\n\t\tE,\n\t\tQ\n\t>,\n> implements BaseActorDefinition<S, CP, CS, V, I, DB, E, Q, R>\n{\n\t#config: ActorConfig<S, CP, CS, V, I, DB, E, Q>;\n\n\tconstructor(config: ActorConfig<S, CP, CS, V, I, DB, E, Q>) {\n\t\tthis.#config = config;\n\t}\n\n\tget config(): ActorConfig<S, CP, CS, V, I, DB, E, Q> {\n\t\treturn this.#config;\n\t}\n}\n\nexport interface BaseActorInstance<\n\tS = any,\n\tCP = any,\n\tCS = any,\n\tV = any,\n\tI = any,\n\tDB extends AnyDatabaseProvider = AnyDatabaseProvider,\n\tE extends EventSchemaConfig = Record<never, never>,\n\tQ extends QueueSchemaConfig = Record<never, never>,\n> {\n\tid: string;\n\tconfig: ActorConfig<S, CP, CS, V, I, DB, E, Q>;\n\trLog: Record<string, (...args: any[]) => any>;\n\t[key: string]: any;\n}\n\nexport type AnyActorInstance = BaseActorInstance<\n\tany,\n\tany,\n\tany,\n\tany,\n\tany,\n\tany,\n\tany,\n\tany\n>;\n\nexport type AnyStaticActorInstance = AnyActorInstance;\n\nexport function isStaticActorInstance(\n\t_actor: AnyActorInstance,\n): _actor is AnyStaticActorInstance {\n\treturn true;\n}\n\nexport function actor<\n\tTState,\n\tTConnParams,\n\tTConnState,\n\tTVars,\n\tTInput,\n\tTDatabase extends AnyDatabaseProvider,\n\tTEvents extends EventSchemaConfig = Record<never, never>,\n\tTQueues extends QueueSchemaConfig = Record<never, never>,\n\tTActions extends Actions<\n\t\tTState,\n\t\tTConnParams,\n\t\tTConnState,\n\t\tTVars,\n\t\tTInput,\n\t\tTDatabase,\n\t\tTEvents,\n\t\tTQueues\n\t> = Actions<\n\t\tTState,\n\t\tTConnParams,\n\t\tTConnState,\n\t\tTVars,\n\t\tTInput,\n\t\tTDatabase,\n\t\tTEvents,\n\t\tTQueues\n\t>,\n>(\n\tinput: ActorConfigInput<\n\t\tTState,\n\t\tTConnParams,\n\t\tTConnState,\n\t\tTVars,\n\t\tTInput,\n\t\tTDatabase,\n\t\tTEvents,\n\t\tTQueues,\n\t\tTActions\n\t>,\n): ActorDefinition<\n\tTState,\n\tTConnParams,\n\tTConnState,\n\tTVars,\n\tTInput,\n\tTDatabase,\n\tTEvents,\n\tTQueues,\n\tTActions\n> {\n\twarnDeprecatedShutdownTimeoutKeys(\n\t\t(input as { options?: unknown } | undefined)?.options,\n\t);\n\tconst config = ActorConfigSchema.parse(input) as ActorConfig<\n\t\tTState,\n\t\tTConnParams,\n\t\tTConnState,\n\t\tTVars,\n\t\tTInput,\n\t\tTDatabase,\n\t\tTEvents,\n\t\tTQueues\n\t>;\n\treturn new ActorDefinition(config);\n}\n\nexport function isStaticActorDefinition(\n\tdefinition: AnyActorDefinition,\n): definition is AnyStaticActorDefinition {\n\treturn definition instanceof ActorDefinition;\n}\n\nexport function lookupInRegistry(\n\tconfig: RegistryConfig,\n\tname: string,\n): AnyActorDefinition {\n\tconst definition = config.use[name];\n\tif (!definition) throw new Error(`no actor in registry for name ${name}`);\n\treturn definition;\n}\n","import type { StandardSchemaV1 } from \"@standard-schema/spec\";\nimport { unsupportedFeature } from \"./errors\";\n\nexport type SchemaHookResult = boolean | Promise<boolean>;\n\ntype SchemaHook<TContext = any> = (ctx: TContext) => SchemaHookResult;\n\nexport interface EventTypeToken<T, TContext = any> {\n\treadonly _eventType?: T;\n\treadonly canSubscribe?: SchemaHook<TContext>;\n\treadonly schema?: PrimitiveSchema;\n}\n\nexport interface QueueTypeToken<TMessage, TComplete = never, TContext = any> {\n\treadonly _queueMessage?: TMessage;\n\treadonly _queueComplete?: TComplete;\n\treadonly canPublish?: SchemaHook<TContext>;\n\treadonly message?: PrimitiveSchema;\n\treadonly complete?: PrimitiveSchema;\n}\n\n/** @deprecated Use `event<T>()`. */\nexport type Type<T> = EventTypeToken<T, any>;\n\ninterface EventOptions<TContext = any> {\n\tcanSubscribe?: SchemaHook<TContext>;\n\tschema?: PrimitiveSchema;\n}\n\ninterface QueueOptions<TContext = any> {\n\tcanPublish?: SchemaHook<TContext>;\n\tmessage?: PrimitiveSchema;\n\tcomplete?: PrimitiveSchema;\n}\n\nexport function event<T, TContext = any>(\n\toptions?: EventOptions<TContext>,\n): EventTypeToken<T, TContext> {\n\treturn (options ?? {}) as EventTypeToken<T, TContext>;\n}\n\nexport function queue<TMessage, TComplete = never, TContext = any>(\n\toptions?: QueueOptions<TContext>,\n): QueueTypeToken<TMessage, TComplete, TContext> {\n\treturn (options ?? {}) as QueueTypeToken<TMessage, TComplete, TContext>;\n}\n\nexport type PrimitiveSchema = StandardSchemaV1 | EventTypeToken<unknown, any>;\n\nexport interface EventSchemaDefinition<TContext = any> {\n\tschema: PrimitiveSchema;\n\tcanSubscribe?: SchemaHook<TContext>;\n}\n\nexport interface QueueSchemaDefinition<TContext = any> {\n\tmessage: PrimitiveSchema;\n\tcomplete?: PrimitiveSchema;\n\tcanPublish?: SchemaHook<TContext>;\n}\n\nexport type EventSchema<TContext = any> =\n\t| PrimitiveSchema\n\t| EventSchemaDefinition<TContext>;\nexport type QueueSchema =\n\t| PrimitiveSchema\n\t| QueueSchemaDefinition<any>\n\t| QueueTypeToken<unknown, unknown, any>;\nexport type EventSchemaConfig<TContext = any> = Record<\n\tstring,\n\tEventSchema<TContext>\n>;\nexport type QueueSchemaConfig<TContext = any> = Record<string, QueueSchema>;\nexport type AnySchemaConfig = EventSchemaConfig | QueueSchemaConfig;\n\n/** @deprecated Use `EventSchema` or `QueueSchema`. */\nexport type Schema = QueueSchema;\n/** @deprecated Use `EventSchemaConfig` or `QueueSchemaConfig`. */\nexport type SchemaConfig = QueueSchemaConfig;\n\nexport type InferSchema<T> =\n\tT extends QueueSchemaDefinition<any>\n\t\t? InferSchema<T[\"message\"]>\n\t\t: T extends QueueTypeToken<infer M, unknown, any>\n\t\t\t? M\n\t\t\t: T extends EventSchemaDefinition<any>\n\t\t\t\t? InferSchema<T[\"schema\"]>\n\t\t\t\t: T extends StandardSchemaV1<any, infer O>\n\t\t\t\t\t? O\n\t\t\t\t\t: T extends EventTypeToken<infer R, any>\n\t\t\t\t\t\t? R\n\t\t\t\t\t\t: never;\n\nexport type InferSchemaMap<T extends Record<string, unknown>> = {\n\t[K in keyof T]: InferSchema<T[K]>;\n};\n\nexport type InferQueueComplete<T> =\n\tT extends QueueTypeToken<unknown, infer C, any>\n\t\t? [C] extends [never]\n\t\t\t? never\n\t\t\t: C\n\t\t: T extends QueueSchemaDefinition<any>\n\t\t\t? T[\"complete\"] extends PrimitiveSchema\n\t\t\t\t? InferSchema<T[\"complete\"]>\n\t\t\t\t: never\n\t\t\t: never;\n\nexport type InferQueueCompleteMap<T extends QueueSchemaConfig> = {\n\t[K in keyof T]: InferQueueComplete<T[K]>;\n};\n\nexport type InferEventArgs<T> = T extends readonly unknown[]\n\t? number extends T[\"length\"]\n\t\t? [T]\n\t\t: T\n\t: [T];\n\nexport type ValidationResult<T> =\n\t| { success: true; data: T }\n\t| { success: false; issues: unknown[] };\n\nexport function isStandardSchema(value: unknown): value is StandardSchemaV1 {\n\treturn typeof value === \"object\" && value !== null && \"~standard\" in value;\n}\n\nexport function isQueueSchemaDefinition(\n\tvalue: unknown,\n): value is QueueSchemaDefinition<any> {\n\tif (isEventSchemaDefinition(value)) {\n\t\treturn false;\n\t}\n\treturn (\n\t\ttypeof value === \"object\" &&\n\t\tvalue !== null &&\n\t\t\"message\" in value &&\n\t\t(value as { message?: unknown }).message !== undefined\n\t);\n}\n\nexport function isEventSchemaDefinition(\n\tvalue: unknown,\n): value is EventSchemaDefinition<any> {\n\treturn (\n\t\ttypeof value === \"object\" &&\n\t\tvalue !== null &&\n\t\t\"schema\" in value &&\n\t\t(value as { schema?: unknown }).schema !== undefined\n\t);\n}\n\nexport function hasSchemaConfigKey<T extends AnySchemaConfig>(\n\tschemas: T | undefined,\n\tkey: string,\n): boolean {\n\tif (!schemas) {\n\t\treturn false;\n\t}\n\treturn Object.prototype.hasOwnProperty.call(schemas, key);\n}\n\nexport function getEventCanSubscribe<TContext = any>(\n\tschemas: EventSchemaConfig<TContext> | undefined,\n\tkey: string,\n): SchemaHook<TContext> | undefined {\n\tconst schema = schemas?.[key];\n\tif (!schema || isStandardSchema(schema)) {\n\t\treturn undefined;\n\t}\n\n\tconst maybeCanSubscribe = (schema as { canSubscribe?: unknown })\n\t\t.canSubscribe;\n\treturn typeof maybeCanSubscribe === \"function\"\n\t\t? (maybeCanSubscribe as SchemaHook<TContext>)\n\t\t: undefined;\n}\n\nexport function getQueueCanPublish<TContext = any>(\n\tschemas: QueueSchemaConfig | undefined,\n\tkey: string,\n): SchemaHook<TContext> | undefined {\n\tconst schema = schemas?.[key];\n\tif (!schema || isStandardSchema(schema)) {\n\t\treturn undefined;\n\t}\n\n\tconst maybeCanPublish = (schema as { canPublish?: unknown }).canPublish;\n\treturn typeof maybeCanPublish === \"function\"\n\t\t? (maybeCanPublish as SchemaHook<TContext>)\n\t\t: undefined;\n}\n\nfunction getValidationSchema(\n\tschema: QueueSchema | EventSchema | undefined,\n): QueueSchema | EventSchema | undefined {\n\tif (!schema) {\n\t\treturn undefined;\n\t}\n\tif (isEventSchemaDefinition(schema)) {\n\t\treturn schema.schema;\n\t}\n\tif (isQueueSchemaDefinition(schema)) {\n\t\treturn schema.message;\n\t}\n\tif (\n\t\ttypeof schema === \"object\" &&\n\t\tschema !== null &&\n\t\t\"schema\" in schema &&\n\t\t(schema as { schema?: unknown }).schema !== undefined\n\t) {\n\t\treturn (schema as { schema: QueueSchema | EventSchema }).schema;\n\t}\n\tif (\n\t\ttypeof schema === \"object\" &&\n\t\tschema !== null &&\n\t\t\"message\" in schema &&\n\t\t(schema as { message?: unknown }).message !== undefined\n\t) {\n\t\treturn (schema as { message: QueueSchema | EventSchema }).message;\n\t}\n\treturn schema;\n}\n\nfunction isPromiseLike(value: unknown): value is PromiseLike<unknown> {\n\treturn (\n\t\ttypeof value === \"object\" &&\n\t\tvalue !== null &&\n\t\t\"then\" in value &&\n\t\ttypeof (value as { then?: unknown }).then === \"function\"\n\t);\n}\n\nexport async function validateSchema<T extends AnySchemaConfig>(\n\tschemas: T | undefined,\n\tkey: keyof T & string,\n\tdata: unknown,\n): Promise<ValidationResult<InferSchemaMap<T>[typeof key]>> {\n\tconst schema = getValidationSchema(schemas?.[key]);\n\n\tif (!schema) {\n\t\treturn { success: true, data: data as InferSchemaMap<T>[typeof key] };\n\t}\n\n\tif (isStandardSchema(schema)) {\n\t\tconst result = await schema[\"~standard\"].validate(data);\n\t\tif (result.issues) {\n\t\t\treturn { success: false, issues: [...result.issues] };\n\t\t}\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tdata: result.value as InferSchemaMap<T>[typeof key],\n\t\t};\n\t}\n\n\treturn { success: true, data: data as InferSchemaMap<T>[typeof key] };\n}\n\nexport function validateSchemaSync<T extends AnySchemaConfig>(\n\tschemas: T | undefined,\n\tkey: keyof T & string,\n\tdata: unknown,\n): ValidationResult<InferSchemaMap<T>[typeof key]> {\n\tconst schema = getValidationSchema(schemas?.[key]);\n\n\tif (!schema) {\n\t\treturn { success: true, data: data as InferSchemaMap<T>[typeof key] };\n\t}\n\n\tif (isStandardSchema(schema)) {\n\t\tconst result = schema[\"~standard\"].validate(data);\n\t\tif (isPromiseLike(result)) {\n\t\t\tthrow unsupportedFeature(\"async schema validation\");\n\t\t}\n\t\tif (result.issues) {\n\t\t\treturn { success: false, issues: [...result.issues] };\n\t\t}\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tdata: result.value as InferSchemaMap<T>[typeof key],\n\t\t};\n\t}\n\n\treturn { success: true, data: data as InferSchemaMap<T>[typeof key] };\n}\n","import type { SqliteBindings } from \"./config\";\ntype SqliteBindingObject = Record<string, unknown>;\n\nfunction isSqliteBindingValue(value: unknown): boolean {\n\tif (\n\t\tvalue === null ||\n\t\ttypeof value === \"number\" ||\n\t\ttypeof value === \"string\" ||\n\t\ttypeof value === \"bigint\" ||\n\t\tvalue instanceof Uint8Array\n\t) {\n\t\treturn true;\n\t}\n\n\tif (Array.isArray(value)) {\n\t\treturn value.every((item) => typeof item === \"number\");\n\t}\n\n\treturn false;\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n\tif (!value || typeof value !== \"object\" || Array.isArray(value)) {\n\t\treturn false;\n\t}\n\treturn Object.getPrototypeOf(value) === Object.prototype;\n}\n\nexport function isSqliteBindingObject(\n\tvalue: unknown,\n): value is SqliteBindingObject {\n\tif (!isPlainObject(value)) {\n\t\treturn false;\n\t}\n\n\treturn Object.values(value).every((entry) => isSqliteBindingValue(entry));\n}\n\nexport function isSqliteBindingArray(value: unknown): value is unknown[] {\n\treturn (\n\t\tArray.isArray(value) &&\n\t\tvalue.every((entry) => isSqliteBindingValue(entry))\n\t);\n}\n\nexport function toSqliteBindings(\n\tinput: unknown[] | SqliteBindingObject,\n): SqliteBindings {\n\tif (Array.isArray(input)) {\n\t\tfor (const value of input) {\n\t\t\tif (!isSqliteBindingValue(value)) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`unsupported sqlite binding type: ${typeof value}`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t\treturn input as SqliteBindings;\n\t}\n\n\tif (isSqliteBindingObject(input)) {\n\t\treturn input as SqliteBindings;\n\t}\n\n\tthrow new Error(\"unsupported sqlite binding collection\");\n}\n\n/**\n * Serialize async operations on a shared non-reentrant resource.\n */\nexport class AsyncMutex {\n\t#locked = false;\n\t#waiting: (() => void)[] = [];\n\n\tasync acquire(): Promise<void> {\n\t\twhile (this.#locked) {\n\t\t\tawait new Promise<void>((resolve) => this.#waiting.push(resolve));\n\t\t}\n\t\tthis.#locked = true;\n\t}\n\n\trelease(): void {\n\t\tthis.#locked = false;\n\t\tconst next = this.#waiting.shift();\n\t\tif (next) {\n\t\t\tnext();\n\t\t}\n\t}\n\n\tasync run<T>(fn: () => Promise<T>): Promise<T> {\n\t\tawait this.acquire();\n\t\ttry {\n\t\t\treturn await fn();\n\t\t} finally {\n\t\t\tthis.release();\n\t\t}\n\t}\n}\n","import type { DatabaseProvider, RawAccess, SqliteDatabase } from \"./config\";\nimport { isSqliteBindingObject, toSqliteBindings } from \"./shared\";\n\nexport type { RawAccess } from \"./config\";\n\ninterface DatabaseFactoryConfig {\n\tonMigrate?: (db: RawAccess) => Promise<void> | void;\n}\n\nfunction hasMultipleStatements(query: string): boolean {\n\tconst trimmed = query.trim().replace(/;+$/, \"\").trimEnd();\n\treturn trimmed.includes(\";\");\n}\n\nexport function db({\n\tonMigrate,\n}: DatabaseFactoryConfig = {}): DatabaseProvider<RawAccess> {\n\treturn {\n\t\tcreateClient: async (ctx) => {\n\t\t\tconst nativeDatabaseProvider = ctx.nativeDatabaseProvider;\n\t\t\tif (!nativeDatabaseProvider) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t\"native SQLite is required, but the current runtime did not provide a native database provider\",\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst db = await nativeDatabaseProvider.open(ctx.actorId);\n\t\t\tlet closed = false;\n\t\t\tconst ensureOpen = () => {\n\t\t\t\tif (closed) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\"Database is closed. This usually means a background timer (setInterval, setTimeout) or a stray promise is still running after the actor stopped. Use c.abortSignal to clean up timers before the actor shuts down.\",\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tconst client: RawAccess = {\n\t\t\t\texecute: async <\n\t\t\t\t\tTRow extends Record<string, unknown> = Record<\n\t\t\t\t\t\tstring,\n\t\t\t\t\t\tunknown\n\t\t\t\t\t>,\n\t\t\t\t>(\n\t\t\t\t\tquery: string,\n\t\t\t\t\t...args: unknown[]\n\t\t\t\t): Promise<TRow[]> => {\n\t\t\t\t\tensureOpen();\n\n\t\t\t\t\tconst kvReadsBefore = ctx.metrics?.totalKvReads ?? 0;\n\t\t\t\t\tconst kvWritesBefore = ctx.metrics?.totalKvWrites ?? 0;\n\t\t\t\t\tconst start = performance.now();\n\n\t\t\t\t\ttry {\n\t\t\t\t\t\tif (args.length > 0) {\n\t\t\t\t\t\t\tconst bindings =\n\t\t\t\t\t\t\t\targs.length === 1 &&\n\t\t\t\t\t\t\t\tisSqliteBindingObject(args[0])\n\t\t\t\t\t\t\t\t\t? toSqliteBindings(args[0])\n\t\t\t\t\t\t\t\t\t: toSqliteBindings(args);\n\t\t\t\t\t\t\tconst { rows, columns } = await db.execute(\n\t\t\t\t\t\t\t\tquery,\n\t\t\t\t\t\t\t\tbindings,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\treturn rows.map((row) =>\n\t\t\t\t\t\t\t\trowToObject<TRow>(row, columns),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (!hasMultipleStatements(query)) {\n\t\t\t\t\t\t\tconst { rows, columns } = await db.execute(query);\n\t\t\t\t\t\t\treturn rows.map((row) =>\n\t\t\t\t\t\t\t\trowToObject<TRow>(row, columns),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn await execMultiStatement<TRow>(db, query);\n\t\t\t\t\t} finally {\n\t\t\t\t\t\tconst durationMs = performance.now() - start;\n\t\t\t\t\t\tctx.metrics?.trackSql(query, durationMs);\n\t\t\t\t\t\tif (ctx.metrics) {\n\t\t\t\t\t\t\tconst kvReads =\n\t\t\t\t\t\t\t\tctx.metrics.totalKvReads - kvReadsBefore;\n\t\t\t\t\t\t\tconst kvWrites =\n\t\t\t\t\t\t\t\tctx.metrics.totalKvWrites - kvWritesBefore;\n\t\t\t\t\t\t\tctx.log?.debug({\n\t\t\t\t\t\t\t\tmsg: \"sql query\",\n\t\t\t\t\t\t\t\tquery: query.slice(0, 120),\n\t\t\t\t\t\t\t\tdurationMs,\n\t\t\t\t\t\t\t\tkvReads,\n\t\t\t\t\t\t\t\tkvWrites,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tclose: async () => {\n\t\t\t\t\tif (!closed) {\n\t\t\t\t\t\tclosed = true;\n\t\t\t\t\t\tawait db.close();\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tnativeMetrics: () => db.nativeMetrics?.() ?? null,\n\t\t\t};\n\t\t\treturn client;\n\t\t},\n\t\tonMigrate: async (client) => {\n\t\t\tif (onMigrate) {\n\t\t\t\tawait withMigrationSavepoint(client, () => onMigrate(client));\n\t\t\t}\n\t\t},\n\t};\n}\n\nfunction rowToObject<TRow extends Record<string, unknown>>(\n\trow: unknown[],\n\tcolumns: string[],\n): TRow {\n\tconst rowObj: Record<string, unknown> = {};\n\tfor (let i = 0; i < columns.length; i++) {\n\t\trowObj[columns[i]] = row[i];\n\t}\n\treturn rowObj as TRow;\n}\n\nasync function execMultiStatement<TRow extends Record<string, unknown>>(\n\tdb: SqliteDatabase,\n\tquery: string,\n): Promise<TRow[]> {\n\tconst results: Record<string, unknown>[] = [];\n\tlet columnNames: string[] | null = null;\n\tawait db.exec(query, (row: unknown[], columns: string[]) => {\n\t\tif (!columnNames) {\n\t\t\tcolumnNames = columns;\n\t\t}\n\t\tresults.push(rowToObject(row, columnNames));\n\t});\n\treturn results as TRow[];\n}\n\nasync function withMigrationSavepoint<T>(\n\tclient: RawAccess,\n\tcallback: () => Promise<T> | T,\n): Promise<T> {\n\tawait client.execute(\"SAVEPOINT __rivet_on_migrate\");\n\ttry {\n\t\tconst result = await callback();\n\t\tawait client.execute(\"RELEASE SAVEPOINT __rivet_on_migrate\");\n\t\treturn result;\n\t} catch (error) {\n\t\ttry {\n\t\t\tawait client.execute(\"ROLLBACK TO SAVEPOINT __rivet_on_migrate\");\n\t\t} finally {\n\t\t\tawait client.execute(\"RELEASE SAVEPOINT __rivet_on_migrate\");\n\t\t}\n\t\tthrow error;\n\t}\n}\n","import type {\n\tAgentOsOptions,\n\tJsonRpcNotification,\n\tPermissionRequest,\n} from \"@rivet-dev/agent-os-core\";\nimport type { ActorContext, BeforeConnectContext } from \"@/actor/config\";\nimport { z } from \"zod/v4\";\nimport type { AgentOsActorState, AgentOsActorVars } from \"./types\";\n\nconst zFunction = <\n\tT extends (...args: any[]) => any = (...args: unknown[]) => unknown,\n>() => z.custom<T>((val) => typeof val === \"function\");\n\nconst AgentOsOptionsSchema = z.custom<AgentOsOptions>(\n\t(val) => typeof val === \"object\" && val !== null,\n);\n\nexport const agentOsActorConfigSchema = z\n\t.object({\n\t\toptions: AgentOsOptionsSchema.optional(),\n\t\tpreview: z\n\t\t\t.object({\n\t\t\t\tdefaultExpiresInSeconds: z.number().positive().default(3600),\n\t\t\t\tmaxExpiresInSeconds: z.number().positive().default(86400),\n\t\t\t})\n\t\t\t.strict()\n\t\t\t.prefault(() => ({})),\n\t\tonBeforeConnect: zFunction().optional(),\n\t\tonSessionEvent: zFunction().optional(),\n\t\tonPermissionRequest: zFunction().optional(),\n\t})\n\t.strict();\n\n// --- Typed config types (generic callbacks overlaid on the Zod schema) ---\n\ntype AgentOsActorContext<TConnParams> = ActorContext<\n\tAgentOsActorState,\n\tTConnParams,\n\tundefined,\n\tAgentOsActorVars,\n\tundefined,\n\tany\n>;\n\ninterface AgentOsActorConfigCallbacks<TConnParams> {\n\tonBeforeConnect?: (\n\t\tc: BeforeConnectContext<\n\t\t\tAgentOsActorState,\n\t\t\tAgentOsActorVars,\n\t\t\tundefined,\n\t\t\tany\n\t\t>,\n\t\tparams: TConnParams,\n\t) => void | Promise<void>;\n\tonSessionEvent?: (\n\t\tc: AgentOsActorContext<TConnParams>,\n\t\tsessionId: string,\n\t\tevent: JsonRpcNotification,\n\t) => void | Promise<void>;\n\tonPermissionRequest?: (\n\t\tc: AgentOsActorContext<TConnParams>,\n\t\tsessionId: string,\n\t\trequest: PermissionRequest,\n\t) => void | Promise<void>;\n}\n\n// Parsed config (after Zod defaults/transforms applied).\nexport type AgentOsActorConfig<TConnParams = undefined> = Omit<\n\tz.infer<typeof agentOsActorConfigSchema>,\n\t\"onBeforeConnect\" | \"onSessionEvent\" | \"onPermissionRequest\"\n> &\n\tAgentOsActorConfigCallbacks<TConnParams>;\n\n// Input config (what users pass in before Zod transforms).\nexport type AgentOsActorConfigInput<TConnParams = undefined> = Omit<\n\tz.input<typeof agentOsActorConfigSchema>,\n\t\"onBeforeConnect\" | \"onSessionEvent\" | \"onPermissionRequest\"\n> &\n\tAgentOsActorConfigCallbacks<TConnParams>;\n","import type { CronAction, CronJobInfo } from \"@rivet-dev/agent-os-core\";\nimport type { AgentOsActorConfig } from \"../config\";\nimport type {\n\tAgentOsActionContext,\n\tSerializableCronAction,\n\tSerializableCronJobInfo,\n\tSerializableCronJobOptions,\n} from \"../types\";\nimport { ensureVm } from \"./index\";\n\nfunction serializeCronAction(action: CronAction): SerializableCronAction {\n\tswitch (action.type) {\n\t\tcase \"session\":\n\t\t\treturn {\n\t\t\t\ttype: \"session\",\n\t\t\t\tagentType: action.agentType,\n\t\t\t\tprompt: action.prompt,\n\t\t\t\tcwd: action.options?.cwd,\n\t\t\t};\n\t\tcase \"exec\":\n\t\t\treturn {\n\t\t\t\ttype: \"exec\",\n\t\t\t\tcommand: action.command,\n\t\t\t\targs: action.args,\n\t\t\t};\n\t\tcase \"callback\":\n\t\t\tthrow new TypeError(\"callback cron actions are not serializable\");\n\t}\n}\n\nfunction serializeCronJob(job: CronJobInfo): SerializableCronJobInfo {\n\treturn {\n\t\tid: job.id,\n\t\tschedule: job.schedule,\n\t\taction: serializeCronAction(job.action),\n\t\toverlap: job.overlap,\n\t\tlastRun: job.lastRun?.toISOString(),\n\t\tnextRun: job.nextRun?.toISOString(),\n\t\trunCount: job.runCount,\n\t\trunning: job.running,\n\t};\n}\n\n// Build cron scheduling actions for the actor factory.\nexport function buildCronActions<TConnParams>(\n\tconfig: AgentOsActorConfig<TConnParams>,\n) {\n\treturn {\n\t\tscheduleCron: async (\n\t\t\tc: AgentOsActionContext<TConnParams>,\n\t\t\toptions: SerializableCronJobOptions,\n\t\t): Promise<{ id: string }> => {\n\t\t\tconst agentOs = await ensureVm(c, config);\n\t\t\tconst job = agentOs.scheduleCron({\n\t\t\t\tid: options.id,\n\t\t\t\tschedule: options.schedule,\n\t\t\t\taction: options.action as CronAction,\n\t\t\t\toverlap: options.overlap,\n\t\t\t});\n\t\t\tc.log.info({\n\t\t\t\tmsg: \"agent-os cron job scheduled\",\n\t\t\t\tjobId: job.id,\n\t\t\t\tschedule: options.schedule,\n\t\t\t});\n\t\t\treturn { id: job.id };\n\t\t},\n\n\t\tlistCronJobs: async (\n\t\t\tc: AgentOsActionContext<TConnParams>,\n\t\t): Promise<SerializableCronJobInfo[]> => {\n\t\t\tconst agentOs = await ensureVm(c, config);\n\t\t\treturn agentOs.listCronJobs().map(serializeCronJob);\n\t\t},\n\n\t\tcancelCronJob: async (\n\t\t\tc: AgentOsActionContext<TConnParams>,\n\t\t\tid: string,\n\t\t): Promise<void> => {\n\t\t\tconst agentOs = await ensureVm(c, config);\n\t\t\tagentOs.cancelCronJob(id);\n\t\t\tc.log.info({ msg: \"agent-os cron job cancelled\", jobId: id });\n\t\t},\n\t};\n}\n","import type { AgentOsActorConfig } from \"../config\";\nimport type { AgentOsActionContext } from \"../types\";\nimport { ensureVm } from \"./index\";\n\n// Serializable fetch options for the actor action boundary.\nexport interface VmFetchOptions {\n\tmethod?: string;\n\theaders?: Record<string, string>;\n\tbody?: string | Uint8Array;\n}\n\n// Serializable fetch result returned by the actor action.\nexport interface VmFetchResult {\n\tstatus: number;\n\tstatusText: string;\n\theaders: Record<string, string>;\n\tbody: Uint8Array;\n}\n\n// Build network actions for the actor factory.\nexport function buildNetworkActions<TConnParams>(\n\tconfig: AgentOsActorConfig<TConnParams>,\n) {\n\treturn {\n\t\tvmFetch: async (\n\t\t\tc: AgentOsActionContext<TConnParams>,\n\t\t\tport: number,\n\t\t\turl: string,\n\t\t\toptions?: VmFetchOptions,\n\t\t): Promise<VmFetchResult> => {\n\t\t\tconst agentOs = await ensureVm(c, config);\n\n\t\t\tconst headers = new Headers(options?.headers);\n\t\t\tconst request = new Request(url, {\n\t\t\t\tmethod: options?.method ?? \"GET\",\n\t\t\t\theaders,\n\t\t\t\tbody: options?.body ?? null,\n\t\t\t});\n\n\t\t\tconst response = await agentOs.fetch(port, request);\n\n\t\t\t// Serialize response headers to a plain object.\n\t\t\tconst responseHeaders: Record<string, string> = {};\n\t\t\tresponse.headers.forEach((value, key) => {\n\t\t\t\tresponseHeaders[key] = value;\n\t\t\t});\n\n\t\t\tconst body = new Uint8Array(await response.arrayBuffer());\n\n\t\t\treturn {\n\t\t\t\tstatus: response.status,\n\t\t\t\tstatusText: response.statusText,\n\t\t\t\theaders: responseHeaders,\n\t\t\t\tbody,\n\t\t\t};\n\t\t},\n\t};\n}\n","import crypto from \"node:crypto\";\nimport type { DatabaseProvider } from \"@/common/database/config\";\nimport type { RequestContext } from \"@/actor/config\";\nimport type { RawAccess } from \"@/common/database/config\";\nimport type { AgentOsActorConfig } from \"../config\";\nimport type {\n\tAgentOsActionContext,\n\tAgentOsActorState,\n\tAgentOsActorVars,\n} from \"../types\";\nimport { ensureVm } from \"./index\";\n\n// Generate a 32-character lowercase alphanumeric token (a-z0-9).\n// 36^32 ~= 1.6e49 possible tokens, brute-force infeasible.\nexport function generateToken(): string {\n\tconst bytes = crypto.randomBytes(32);\n\tconst alphabet = \"abcdefghijklmnopqrstuvwxyz0123456789\";\n\tlet token = \"\";\n\tfor (let i = 0; i < 32; i++) {\n\t\ttoken += alphabet[bytes[i]! % alphabet.length];\n\t}\n\treturn token;\n}\n\n// CORS headers added to all preview proxy responses.\nconst CORS_HEADERS: Record<string, string> = {\n\t\"Access-Control-Allow-Origin\": \"*\",\n\t\"Access-Control-Allow-Methods\": \"GET, POST, PUT, DELETE, OPTIONS\",\n\t\"Access-Control-Allow-Headers\": \"*\",\n};\n\nfunction addCorsHeaders(response: Response): Response {\n\tconst headers = new Headers(response.headers);\n\tfor (const [key, value] of Object.entries(CORS_HEADERS)) {\n\t\theaders.set(key, value);\n\t}\n\treturn new Response(response.body, {\n\t\tstatus: response.status,\n\t\tstatusText: response.statusText,\n\t\theaders,\n\t});\n}\n\ntype AgentOsRequestContext<TConnParams> = RequestContext<\n\tAgentOsActorState,\n\tTConnParams,\n\tundefined,\n\tAgentOsActorVars,\n\tundefined,\n\tDatabaseProvider<RawAccess>\n>;\n\nexport function buildOnRequestHandler<TConnParams>(\n\tconfig: AgentOsActorConfig<TConnParams>,\n) {\n\treturn async (\n\t\tc: AgentOsRequestContext<TConnParams>,\n\t\trequest: Request,\n\t): Promise<Response> => {\n\t\tconst url = new URL(request.url);\n\t\tconst pathname = url.pathname;\n\n\t\t// Expect paths like /fetch/{token} or /fetch/{token}/remaining/path.\n\t\tconst match = pathname.match(/^\\/fetch\\/([a-z0-9]+)(\\/.*)?$/);\n\t\tif (!match) {\n\t\t\treturn new Response(\"Not Found\", { status: 404 });\n\t\t}\n\n\t\t// Handle OPTIONS preflight before token validation.\n\t\tif (request.method === \"OPTIONS\") {\n\t\t\treturn new Response(null, { status: 204, headers: CORS_HEADERS });\n\t\t}\n\n\t\tconst token = match[1]!;\n\t\tconst remainingPath = match[2] ?? \"/\";\n\n\t\t// Validate token from SQLite.\n\t\tconst now = Date.now();\n\t\tconst rows: { port: number }[] = await c.db.execute(\n\t\t\t`SELECT port FROM agent_os_preview_tokens WHERE token = ? AND expires_at > ?`,\n\t\t\ttoken,\n\t\t\tnow,\n\t\t);\n\n\t\tif (rows.length === 0) {\n\t\t\tc.log.warn({ msg: \"agent-os preview auth failed\", token });\n\t\t\treturn addCorsHeaders(new Response(\"Forbidden\", { status: 403 }));\n\t\t}\n\n\t\tconst port = rows[0]?.port;\n\n\t\t// Boot the VM if needed.\n\t\tconst agentOs = await ensureVm(\n\t\t\tc as AgentOsActionContext<TConnParams>,\n\t\t\tconfig,\n\t\t);\n\n\t\t// Build the request to proxy through the VM's virtual network.\n\t\tconst vmUrl = `http://localhost:${port}${remainingPath}${url.search}`;\n\t\tconst vmRequest = new Request(vmUrl, {\n\t\t\tmethod: request.method,\n\t\t\theaders: request.headers,\n\t\t\tbody: request.body,\n\t\t\tduplex: \"half\",\n\t\t} as RequestInit);\n\n\t\tconst vmResponse = await agentOs.fetch(port, vmRequest);\n\n\t\tc.log.info({\n\t\t\tmsg: \"agent-os preview request proxied\",\n\t\t\tport,\n\t\t\tmethod: request.method,\n\t\t\tpath: remainingPath,\n\t\t\tstatus: vmResponse.status,\n\t\t});\n\n\t\treturn addCorsHeaders(vmResponse);\n\t};\n}\n\nexport function buildPreviewActions<TConnParams>(\n\tconfig: AgentOsActorConfig<TConnParams>,\n) {\n\treturn {\n\t\tcreateSignedPreviewUrl: async (\n\t\t\tc: AgentOsActionContext<TConnParams>,\n\t\t\tport: number,\n\t\t\texpiresInSeconds?: number,\n\t\t): Promise<{\n\t\t\tpath: string;\n\t\t\ttoken: string;\n\t\t\tport: number;\n\t\t\texpiresAt: number;\n\t\t}> => {\n\t\t\tawait ensureVm(c, config);\n\n\t\t\tconst effectiveExpires =\n\t\t\t\texpiresInSeconds ?? config.preview.defaultExpiresInSeconds;\n\t\t\tconst maxExpires = config.preview.maxExpiresInSeconds;\n\n\t\t\tif (effectiveExpires < 1 || effectiveExpires > maxExpires) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`expiresInSeconds must be between 1 and ${maxExpires}`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst token = generateToken();\n\t\t\tconst now = Date.now();\n\t\t\tconst expiresAt = now + effectiveExpires * 1000;\n\n\t\t\t// Insert token and lazy-delete expired tokens.\n\t\t\tawait c.db.execute(\n\t\t\t\t`INSERT INTO agent_os_preview_tokens (token, port, created_at, expires_at)\n\t\t\t\t VALUES (?, ?, ?, ?)`,\n\t\t\t\ttoken,\n\t\t\t\tport,\n\t\t\t\tnow,\n\t\t\t\texpiresAt,\n\t\t\t);\n\t\t\tawait c.db.execute(\n\t\t\t\t`DELETE FROM agent_os_preview_tokens WHERE expires_at <= ?`,\n\t\t\t\tnow,\n\t\t\t);\n\n\t\t\t// Path relative to the actor's gateway URL. Full URL is\n\t\t\t// `${gatewayUrl}/request/fetch/${token}` where gatewayUrl\n\t\t\t// comes from the client's getGatewayUrl().\n\t\t\tconst path = `/request/fetch/${token}`;\n\n\t\t\tc.log.info({\n\t\t\t\tmsg: \"agent-os preview token created\",\n\t\t\t\tport,\n\t\t\t\texpiresInSeconds: effectiveExpires,\n\t\t\t});\n\n\t\t\treturn { path, token, port, expiresAt };\n\t\t},\n\n\t\texpireSignedPreviewUrl: async (\n\t\t\tc: AgentOsActionContext<TConnParams>,\n\t\t\ttoken: string,\n\t\t): Promise<void> => {\n\t\t\tawait c.db.execute(\n\t\t\t\t`DELETE FROM agent_os_preview_tokens WHERE token = ?`,\n\t\t\t\ttoken,\n\t\t\t);\n\n\t\t\tc.log.info({ msg: \"agent-os preview token expired\", token });\n\t\t},\n\t};\n}\n","import type {\n\tProcessInfo,\n\tProcessTreeNode,\n\tSpawnedProcessInfo,\n} from \"@rivet-dev/agent-os-core\";\nimport { isRivetErrorCode } from \"@/actor/errors\";\nimport type { AgentOsActorConfig } from \"../config\";\nimport type { AgentOsActionContext } from \"../types\";\nimport { ensureVm, syncPreventSleep } from \"./index\";\n\n// Infer types from AgentOs methods since @secure-exec/core is not a direct dep.\ntype ExecResult = Awaited<\n\tReturnType<import(\"@rivet-dev/agent-os-core\").AgentOs[\"exec\"]>\n>;\ntype ExecOptions = Parameters<\n\timport(\"@rivet-dev/agent-os-core\").AgentOs[\"exec\"]\n>[1];\ntype SpawnOptions = Parameters<\n\timport(\"@rivet-dev/agent-os-core\").AgentOs[\"spawn\"]\n>[2];\n\nfunction broadcastProcessEvent<TConnParams>(\n\tc: AgentOsActionContext<TConnParams>,\n\tname: \"processOutput\" | \"processExit\",\n\tpayload: unknown,\n) {\n\ttry {\n\t\tc.broadcast(name, payload);\n\t} catch (error) {\n\t\tif (isRivetErrorCode(error, \"actor\", \"stopping\")) {\n\t\t\treturn;\n\t\t}\n\t\tthrow error;\n\t}\n}\n\n// Build process execution actions for the actor factory.\nexport function buildProcessActions<TConnParams>(\n\tconfig: AgentOsActorConfig<TConnParams>,\n) {\n\treturn {\n\t\texec: async (\n\t\t\tc: AgentOsActionContext<TConnParams>,\n\t\t\tcommand: string,\n\t\t\toptions?: ExecOptions,\n\t\t): Promise<ExecResult> => {\n\t\t\tconst agentOs = await ensureVm(c, config);\n\t\t\treturn agentOs.exec(command, options);\n\t\t},\n\n\t\tspawn: async (\n\t\t\tc: AgentOsActionContext<TConnParams>,\n\t\t\tcommand: string,\n\t\t\targs: string[],\n\t\t\toptions?: SpawnOptions,\n\t\t): Promise<{ pid: number }> => {\n\t\t\tconst agentOs = await ensureVm(c, config);\n\t\t\tconst { pid } = agentOs.spawn(command, args, {\n\t\t\t\t...options,\n\t\t\t\tonStdout: (data: Uint8Array) => {\n\t\t\t\t\tbroadcastProcessEvent(c, \"processOutput\", {\n\t\t\t\t\t\tpid,\n\t\t\t\t\t\tstream: \"stdout\" as const,\n\t\t\t\t\t\tdata,\n\t\t\t\t\t});\n\t\t\t\t\toptions?.onStdout?.(data);\n\t\t\t\t},\n\t\t\t\tonStderr: (data: Uint8Array) => {\n\t\t\t\t\tbroadcastProcessEvent(c, \"processOutput\", {\n\t\t\t\t\t\tpid,\n\t\t\t\t\t\tstream: \"stderr\" as const,\n\t\t\t\t\t\tdata,\n\t\t\t\t\t});\n\t\t\t\t\toptions?.onStderr?.(data);\n\t\t\t\t},\n\t\t\t});\n\n\t\t\tc.vars.activeProcesses.add(pid);\n\t\t\tsyncPreventSleep(c);\n\t\t\tc.log.info({\n\t\t\t\tmsg: \"agent-os process spawned\",\n\t\t\t\tpid,\n\t\t\t\tcommand,\n\t\t\t});\n\n\t\t\tagentOs\n\t\t\t\t.waitProcess(pid)\n\t\t\t\t.then((exitCode) => {\n\t\t\t\t\tbroadcastProcessEvent(c, \"processExit\", { pid, exitCode });\n\t\t\t\t\tc.log.info({\n\t\t\t\t\t\tmsg: \"agent-os process exited\",\n\t\t\t\t\t\tpid,\n\t\t\t\t\t\texitCode,\n\t\t\t\t\t});\n\t\t\t\t})\n\t\t\t\t.catch(() => {\n\t\t\t\t\t// Process killed during dispose. Silently clean up.\n\t\t\t\t})\n\t\t\t\t.finally(() => {\n\t\t\t\t\tc.vars.activeProcesses.delete(pid);\n\t\t\t\t\tsyncPreventSleep(c);\n\t\t\t\t});\n\n\t\t\treturn { pid };\n\t\t},\n\n\t\twriteProcessStdin: async (\n\t\t\tc: AgentOsActionContext<TConnParams>,\n\t\t\tpid: number,\n\t\t\tdata: string | Uint8Array,\n\t\t): Promise<void> => {\n\t\t\tconst agentOs = await ensureVm(c, config);\n\t\t\tagentOs.writeProcessStdin(pid, data);\n\t\t},\n\n\t\tcloseProcessStdin: async (\n\t\t\tc: AgentOsActionContext<TConnParams>,\n\t\t\tpid: number,\n\t\t): Promise<void> => {\n\t\t\tconst agentOs = await ensureVm(c, config);\n\t\t\tagentOs.closeProcessStdin(pid);\n\t\t},\n\n\t\twaitProcess: async (\n\t\t\tc: AgentOsActionContext<TConnParams>,\n\t\t\tpid: number,\n\t\t): Promise<number> => {\n\t\t\tconst agentOs = await ensureVm(c, config);\n\t\t\treturn agentOs.waitProcess(pid);\n\t\t},\n\n\t\tlistProcesses: async (\n\t\t\tc: AgentOsActionContext<TConnParams>,\n\t\t): Promise<SpawnedProcessInfo[]> => {\n\t\t\tconst agentOs = await ensureVm(c, config);\n\t\t\treturn agentOs.listProcesses();\n\t\t},\n\n\t\tallProcesses: async (\n\t\t\tc: AgentOsActionContext<TConnParams>,\n\t\t): Promise<ProcessInfo[]> => {\n\t\t\tconst agentOs = await ensureVm(c, config);\n\t\t\treturn agentOs.allProcesses();\n\t\t},\n\n\t\tprocessTree: async (\n\t\t\tc: AgentOsActionContext<TConnParams>,\n\t\t): Promise<ProcessTreeNode[]> => {\n\t\t\tconst agentOs = await ensureVm(c, config);\n\t\t\treturn agentOs.processTree();\n\t\t},\n\n\t\tgetProcess: async (\n\t\t\tc: AgentOsActionContext<TConnParams>,\n\t\t\tpid: number,\n\t\t): Promise<SpawnedProcessInfo> => {\n\t\t\tconst agentOs = await ensureVm(c, config);\n\t\t\treturn agentOs.getProcess(pid);\n\t\t},\n\n\t\tstopProcess: async (\n\t\t\tc: AgentOsActionContext<TConnParams>,\n\t\t\tpid: number,\n\t\t): Promise<void> => {\n\t\t\tconst agentOs = await ensureVm(c, config);\n\t\t\tagentOs.stopProcess(pid);\n\t\t},\n\n\t\tkillProcess: async (\n\t\t\tc: AgentOsActionContext<TConnParams>,\n\t\t\tpid: number,\n\t\t): Promise<void> => {\n\t\t\tconst agentOs = await ensureVm(c, config);\n\t\t\tagentOs.killProcess(pid);\n\t\t},\n\t};\n}\n","import type {\n\tAgentOs,\n\tAgentType,\n\tCreateSessionOptions,\n\tGetEventsOptions,\n\tJsonRpcNotification,\n\tJsonRpcResponse,\n\tPermissionReply,\n\tSequencedEvent,\n\tSessionConfigOption,\n\tSessionInfo,\n\tSessionModeState,\n} from \"@rivet-dev/agent-os-core\";\nimport type { AgentOsActorConfig } from \"../config\";\nimport type {\n\tAgentOsActionContext,\n\tPersistedSessionEvent,\n\tPersistedSessionRecord,\n\tPromptResult,\n\tSessionRecord,\n} from \"../types\";\nimport { ensureVm, runHook, syncPreventSleep } from \"./index\";\n\n// Strip non-serializable values (functions) from agent-os-core responses so\n// CBOR/BARE encoding doesn't fail. The JsonRpcResponse objects from\n// secure-exec can contain function properties.\nfunction stripFunctions(value: unknown): unknown {\n\tif (value === null || value === undefined) return value;\n\tif (typeof value === \"function\") return undefined;\n\tif (typeof value !== \"object\") return value;\n\tif (Array.isArray(value)) return value.map(stripFunctions);\n\tconst out: Record<string, unknown> = {};\n\tfor (const [k, v] of Object.entries(value as Record<string, unknown>)) {\n\t\tif (typeof v !== \"function\") {\n\t\t\tout[k] = stripFunctions(v);\n\t\t}\n\t}\n\treturn out;\n}\n\n// Helper to verify a session exists in the VM. Throws via AgentOs if not found.\nfunction assertSessionExists<TConnParams>(\n\tc: AgentOsActionContext<TConnParams>,\n\tsessionId: string,\n): void {\n\tif (!c.vars.sessions.has(sessionId)) {\n\t\tthrow new Error(`session not found: ${sessionId}`);\n\t}\n}\n\n// Build a SessionRecord from AgentOs flat API.\nfunction toSessionRecord(\n\tagentOs: AgentOs,\n\tsessionId: string,\n\tagentType: string,\n): SessionRecord {\n\treturn {\n\t\tsessionId,\n\t\tagentType,\n\t\tcapabilities: agentOs.getSessionCapabilities(sessionId) ?? {},\n\t\tagentInfo: agentOs.getSessionAgentInfo(sessionId),\n\t};\n}\n\n// --- Session persistence helpers ---\n\n// Persist a session record to SQLite when it is created.\nasync function persistSession<TConnParams>(\n\tc: AgentOsActionContext<TConnParams>,\n\tagentOs: AgentOs,\n\tsessionId: string,\n\tagentType: string,\n): Promise<void> {\n\tconst now = Date.now();\n\tconst capabilities = agentOs.getSessionCapabilities(sessionId) ?? {};\n\tconst agentInfo = agentOs.getSessionAgentInfo(sessionId);\n\tawait c.db.execute(\n\t\t`INSERT OR REPLACE INTO agent_os_sessions (session_id, agent_type, capabilities, agent_info, created_at)\n\t\t VALUES (?, ?, ?, ?, ?)`,\n\t\tsessionId,\n\t\tagentType,\n\t\tJSON.stringify(capabilities),\n\t\tagentInfo ? JSON.stringify(agentInfo) : null,\n\t\tnow,\n\t);\n}\n\n// Persist a session event to SQLite with an auto-incrementing sequence number.\nasync function persistSessionEvent<TConnParams>(\n\tc: AgentOsActionContext<TConnParams>,\n\tsessionId: string,\n\tevent: JsonRpcNotification,\n): Promise<void> {\n\tconst now = Date.now();\n\n\t// Compute next sequence number for this session.\n\tconst rows: { max_seq: number | null }[] = await c.db.execute(\n\t\t`SELECT MAX(seq) as max_seq FROM agent_os_session_events WHERE session_id = ?`,\n\t\tsessionId,\n\t);\n\tconst nextSeq = (rows[0]?.max_seq ?? -1) + 1;\n\n\tawait c.db.execute(\n\t\t`INSERT INTO agent_os_session_events (session_id, seq, event, created_at)\n\t\t VALUES (?, ?, ?, ?)`,\n\t\tsessionId,\n\t\tnextSeq,\n\t\tJSON.stringify(event),\n\t\tnow,\n\t);\n}\n\n// Remove a session and its events from SQLite.\nasync function deletePersistedSession<TConnParams>(\n\tc: AgentOsActionContext<TConnParams>,\n\tsessionId: string,\n): Promise<void> {\n\tawait c.db.execute(\n\t\t`DELETE FROM agent_os_session_events WHERE session_id = ?`,\n\t\tsessionId,\n\t);\n\tawait c.db.execute(\n\t\t`DELETE FROM agent_os_sessions WHERE session_id = ?`,\n\t\tsessionId,\n\t);\n}\n\n// Subscribe to a session's event and permission streams via the flat AgentOs API,\n// broadcasting events and running user-provided hooks.\nexport function subscribeToSession<TConnParams>(\n\tc: AgentOsActionContext<TConnParams>,\n\tagentOs: AgentOs,\n\tsessionId: string,\n\tparsedConfig: AgentOsActorConfig<TConnParams>,\n): void {\n\tagentOs.onSessionEvent(sessionId, (event) => {\n\t\tc.broadcast(\n\t\t\t\"sessionEvent\",\n\t\t\tJSON.parse(JSON.stringify({ sessionId, event })),\n\t\t);\n\n\t\t// Persist event to SQLite for sleep/wake recovery.\n\t\tpersistSessionEvent(c, sessionId, event).catch((err) =>\n\t\t\tc.log.error({\n\t\t\t\tmsg: \"agent-os failed to persist session event\",\n\t\t\t\tsessionId,\n\t\t\t\terror: err,\n\t\t\t}),\n\t\t);\n\n\t\tif (parsedConfig.onSessionEvent) {\n\t\t\trunHook(c, \"onSessionEvent\", () =>\n\t\t\t\tparsedConfig.onSessionEvent?.(c, sessionId, event),\n\t\t\t);\n\t\t}\n\t});\n\n\tagentOs.onPermissionRequest(sessionId, (request) => {\n\t\tc.broadcast(\n\t\t\t\"permissionRequest\",\n\t\t\tJSON.parse(JSON.stringify({ sessionId, request })),\n\t\t);\n\n\t\tif (parsedConfig.onPermissionRequest) {\n\t\t\trunHook(c, \"onPermissionRequest\", () =>\n\t\t\t\tparsedConfig.onPermissionRequest?.(c, sessionId, request),\n\t\t\t);\n\t\t}\n\t});\n\n\tc.vars.sessions.add(sessionId);\n}\n\n// Build session management actions for the actor factory.\nexport function buildSessionActions<TConnParams>(\n\tconfig: AgentOsActorConfig<TConnParams>,\n) {\n\treturn {\n\t\tcreateSession: async (\n\t\t\tc: AgentOsActionContext<TConnParams>,\n\t\t\tagentType: AgentType,\n\t\t\toptions?: CreateSessionOptions,\n\t\t): Promise<SessionRecord> => {\n\t\t\tconst agentOs = await ensureVm(c, config);\n\t\t\tconst { sessionId } = await agentOs.createSession(\n\t\t\t\tagentType,\n\t\t\t\toptions,\n\t\t\t);\n\t\t\tsubscribeToSession(c, agentOs, sessionId, config);\n\n\t\t\t// Persist session metadata to SQLite for sleep/wake recovery.\n\t\t\tawait persistSession(c, agentOs, sessionId, agentType);\n\n\t\t\tc.log.info({\n\t\t\t\tmsg: \"agent-os session created\",\n\t\t\t\tsessionId,\n\t\t\t\tagentType,\n\t\t\t});\n\t\t\treturn toSessionRecord(agentOs, sessionId, agentType);\n\t\t},\n\n\t\tlistSessions: async (\n\t\t\tc: AgentOsActionContext<TConnParams>,\n\t\t): Promise<SessionInfo[]> => {\n\t\t\tconst agentOs = await ensureVm(c, config);\n\t\t\treturn agentOs.listSessions();\n\t\t},\n\n\t\tgetSession: async (\n\t\t\tc: AgentOsActionContext<TConnParams>,\n\t\t\tsessionId: string,\n\t\t): Promise<SessionRecord> => {\n\t\t\tassertSessionExists(c, sessionId);\n\t\t\tconst agentOs = await ensureVm(c, config);\n\t\t\tconst info = agentOs\n\t\t\t\t.listSessions()\n\t\t\t\t.find((s) => s.sessionId === sessionId);\n\t\t\tif (!info) {\n\t\t\t\tthrow new Error(`session not found: ${sessionId}`);\n\t\t\t}\n\t\t\treturn toSessionRecord(agentOs, sessionId, info.agentType);\n\t\t},\n\n\t\tdestroySession: async (\n\t\t\tc: AgentOsActionContext<TConnParams>,\n\t\t\tsessionId: string,\n\t\t): Promise<void> => {\n\t\t\tconst agentOs = await ensureVm(c, config);\n\t\t\tawait agentOs.destroySession(sessionId);\n\t\t\tc.vars.sessions.delete(sessionId);\n\t\t\tc.vars.activeSessionIds.delete(sessionId);\n\t\t\tsyncPreventSleep(c);\n\n\t\t\t// Clean up persisted session and events from SQLite.\n\t\t\tawait deletePersistedSession(c, sessionId);\n\n\t\t\tc.log.info({ msg: \"agent-os session destroyed\", sessionId });\n\t\t},\n\n\t\tresumeSession: async (\n\t\t\tc: AgentOsActionContext<TConnParams>,\n\t\t\tsessionId: string,\n\t\t): Promise<{ sessionId: string }> => {\n\t\t\tconst agentOs = await ensureVm(c, config);\n\t\t\treturn agentOs.resumeSession(sessionId);\n\t\t},\n\n\t\tcloseSession: async (\n\t\t\tc: AgentOsActionContext<TConnParams>,\n\t\t\tsessionId: string,\n\t\t): Promise<void> => {\n\t\t\tconst agentOs = await ensureVm(c, config);\n\t\t\tagentOs.closeSession(sessionId);\n\t\t\tc.vars.sessions.delete(sessionId);\n\t\t\tc.vars.activeSessionIds.delete(sessionId);\n\t\t\tsyncPreventSleep(c);\n\n\t\t\t// Clean up persisted session and events from SQLite.\n\t\t\tawait deletePersistedSession(c, sessionId);\n\n\t\t\tc.log.info({ msg: \"agent-os session closed\", sessionId });\n\t\t},\n\t};\n}\n\n// Build prompt, cancel, and permission actions for the actor factory.\nexport function buildPromptActions<TConnParams>(\n\t_config: AgentOsActorConfig<TConnParams>,\n) {\n\treturn {\n\t\tsendPrompt: async (\n\t\t\tc: AgentOsActionContext<TConnParams>,\n\t\t\tsessionId: string,\n\t\t\ttext: string,\n\t\t): Promise<PromptResult> => {\n\t\t\tif (c.aborted) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t\"actor is shutting down, cannot start new prompt\",\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tassertSessionExists(c, sessionId);\n\t\t\tconst agentOs = c.vars.agentOs;\n\t\t\tif (!agentOs) {\n\t\t\t\tthrow new Error(\"VM not initialized\");\n\t\t\t}\n\n\t\t\tc.vars.activeSessionIds.add(sessionId);\n\t\t\tsyncPreventSleep(c);\n\t\t\tc.log.info({ msg: \"agent-os prompt turn started\", sessionId });\n\n\t\t\tconst start = Date.now();\n\t\t\ttry {\n\t\t\t\tconst result = await agentOs.prompt(sessionId, text);\n\t\t\t\treturn {\n\t\t\t\t\tresponse: JSON.parse(JSON.stringify(result.response)),\n\t\t\t\t\ttext: result.text,\n\t\t\t\t};\n\t\t\t} finally {\n\t\t\t\tc.vars.activeSessionIds.delete(sessionId);\n\t\t\t\tsyncPreventSleep(c);\n\t\t\t\tc.log.info({\n\t\t\t\t\tmsg: \"agent-os prompt turn ended\",\n\t\t\t\t\tsessionId,\n\t\t\t\t\tdurationMs: Date.now() - start,\n\t\t\t\t});\n\t\t\t}\n\t\t},\n\n\t\tcancelPrompt: async (\n\t\t\tc: AgentOsActionContext<TConnParams>,\n\t\t\tsessionId: string,\n\t\t): Promise<JsonRpcResponse> => {\n\t\t\tassertSessionExists(c, sessionId);\n\t\t\tconst agentOs = c.vars.agentOs;\n\t\t\tif (!agentOs) {\n\t\t\t\tthrow new Error(\"VM not initialized\");\n\t\t\t}\n\t\t\treturn stripFunctions(\n\t\t\t\tagentOs.cancelSession(sessionId),\n\t\t\t) as JsonRpcResponse;\n\t\t},\n\n\t\trespondPermission: async (\n\t\t\tc: AgentOsActionContext<TConnParams>,\n\t\t\tsessionId: string,\n\t\t\tpermissionId: string,\n\t\t\treply: PermissionReply,\n\t\t): Promise<JsonRpcResponse> => {\n\t\t\tassertSessionExists(c, sessionId);\n\t\t\tconst agentOs = c.vars.agentOs;\n\t\t\tif (!agentOs) {\n\t\t\t\tthrow new Error(\"VM not initialized\");\n\t\t\t}\n\t\t\treturn stripFunctions(\n\t\t\t\tagentOs.respondPermission(sessionId, permissionId, reply),\n\t\t\t) as JsonRpcResponse;\n\t\t},\n\t};\n}\n\n// Build session configuration proxy actions for the actor factory.\nexport function buildConfigActions<TConnParams>(\n\t_config: AgentOsActorConfig<TConnParams>,\n) {\n\treturn {\n\t\tsetMode: async (\n\t\t\tc: AgentOsActionContext<TConnParams>,\n\t\t\tsessionId: string,\n\t\t\tmodeId: string,\n\t\t): Promise<JsonRpcResponse> => {\n\t\t\tassertSessionExists(c, sessionId);\n\t\t\tconst agentOs = c.vars.agentOs;\n\t\t\tif (!agentOs) {\n\t\t\t\tthrow new Error(\"VM not initialized\");\n\t\t\t}\n\t\t\treturn stripFunctions(\n\t\t\t\tagentOs.setSessionMode(sessionId, modeId),\n\t\t\t) as JsonRpcResponse;\n\t\t},\n\n\t\tgetModes: async (\n\t\t\tc: AgentOsActionContext<TConnParams>,\n\t\t\tsessionId: string,\n\t\t): Promise<SessionModeState | null> => {\n\t\t\tassertSessionExists(c, sessionId);\n\t\t\tconst agentOs = c.vars.agentOs;\n\t\t\tif (!agentOs) {\n\t\t\t\tthrow new Error(\"VM not initialized\");\n\t\t\t}\n\t\t\treturn agentOs.getSessionModes(sessionId);\n\t\t},\n\n\t\tsetModel: async (\n\t\t\tc: AgentOsActionContext<TConnParams>,\n\t\t\tsessionId: string,\n\t\t\tmodel: string,\n\t\t): Promise<JsonRpcResponse> => {\n\t\t\tassertSessionExists(c, sessionId);\n\t\t\tconst agentOs = c.vars.agentOs;\n\t\t\tif (!agentOs) {\n\t\t\t\tthrow new Error(\"VM not initialized\");\n\t\t\t}\n\t\t\treturn stripFunctions(\n\t\t\t\tagentOs.setSessionModel(sessionId, model),\n\t\t\t) as JsonRpcResponse;\n\t\t},\n\n\t\tsetThoughtLevel: async (\n\t\t\tc: AgentOsActionContext<TConnParams>,\n\t\t\tsessionId: string,\n\t\t\tlevel: string,\n\t\t): Promise<JsonRpcResponse> => {\n\t\t\tassertSessionExists(c, sessionId);\n\t\t\tconst agentOs = c.vars.agentOs;\n\t\t\tif (!agentOs) {\n\t\t\t\tthrow new Error(\"VM not initialized\");\n\t\t\t}\n\t\t\treturn stripFunctions(\n\t\t\t\tagentOs.setSessionThoughtLevel(sessionId, level),\n\t\t\t) as JsonRpcResponse;\n\t\t},\n\n\t\tgetConfigOptions: async (\n\t\t\tc: AgentOsActionContext<TConnParams>,\n\t\t\tsessionId: string,\n\t\t): Promise<SessionConfigOption[]> => {\n\t\t\tassertSessionExists(c, sessionId);\n\t\t\tconst agentOs = c.vars.agentOs;\n\t\t\tif (!agentOs) {\n\t\t\t\tthrow new Error(\"VM not initialized\");\n\t\t\t}\n\t\t\treturn agentOs.getSessionConfigOptions(sessionId);\n\t\t},\n\n\t\tgetEvents: async (\n\t\t\tc: AgentOsActionContext<TConnParams>,\n\t\t\tsessionId: string,\n\t\t\toptions?: GetEventsOptions,\n\t\t): Promise<JsonRpcNotification[]> => {\n\t\t\tassertSessionExists(c, sessionId);\n\t\t\tconst agentOs = c.vars.agentOs;\n\t\t\tif (!agentOs) {\n\t\t\t\tthrow new Error(\"VM not initialized\");\n\t\t\t}\n\t\t\treturn agentOs\n\t\t\t\t.getSessionEvents(sessionId, options)\n\t\t\t\t.map((e) => e.notification);\n\t\t},\n\n\t\tgetSequencedEvents: async (\n\t\t\tc: AgentOsActionContext<TConnParams>,\n\t\t\tsessionId: string,\n\t\t\toptions?: GetEventsOptions,\n\t\t): Promise<SequencedEvent[]> => {\n\t\t\tassertSessionExists(c, sessionId);\n\t\t\tconst agentOs = c.vars.agentOs;\n\t\t\tif (!agentOs) {\n\t\t\t\tthrow new Error(\"VM not initialized\");\n\t\t\t}\n\t\t\treturn agentOs.getSessionEvents(sessionId, options);\n\t\t},\n\n\t\trawSend: async (\n\t\t\tc: AgentOsActionContext<TConnParams>,\n\t\t\tsessionId: string,\n\t\t\tmethod: string,\n\t\t\tparams?: Record<string, unknown>,\n\t\t): Promise<JsonRpcResponse> => {\n\t\t\tassertSessionExists(c, sessionId);\n\t\t\tconst agentOs = c.vars.agentOs;\n\t\t\tif (!agentOs) {\n\t\t\t\tthrow new Error(\"VM not initialized\");\n\t\t\t}\n\t\t\treturn stripFunctions(\n\t\t\t\tagentOs.rawSessionSend(sessionId, method, params),\n\t\t\t) as JsonRpcResponse;\n\t\t},\n\t};\n}\n\n// Build actions for querying persisted session data from SQLite.\n// These work without a running VM and return data from prior sessions\n// that survived sleep/wake cycles.\nexport function buildSessionPersistenceActions<TConnParams>(\n\t_config: AgentOsActorConfig<TConnParams>,\n) {\n\treturn {\n\t\tlistPersistedSessions: async (\n\t\t\tc: AgentOsActionContext<TConnParams>,\n\t\t): Promise<PersistedSessionRecord[]> => {\n\t\t\tconst rows: {\n\t\t\t\tsession_id: string;\n\t\t\t\tagent_type: string;\n\t\t\t\tcapabilities: string;\n\t\t\t\tagent_info: string | null;\n\t\t\t\tcreated_at: number;\n\t\t\t}[] = await c.db.execute(\n\t\t\t\t`SELECT session_id, agent_type, capabilities, agent_info, created_at\n\t\t\t\t FROM agent_os_sessions\n\t\t\t\t ORDER BY created_at ASC`,\n\t\t\t);\n\n\t\t\treturn rows.map((row) => ({\n\t\t\t\tsessionId: row.session_id,\n\t\t\t\tagentType: row.agent_type,\n\t\t\t\tcapabilities: JSON.parse(row.capabilities),\n\t\t\t\tagentInfo: row.agent_info ? JSON.parse(row.agent_info) : null,\n\t\t\t\tcreatedAt: row.created_at,\n\t\t\t}));\n\t\t},\n\n\t\tgetSessionEvents: async (\n\t\t\tc: AgentOsActionContext<TConnParams>,\n\t\t\tsessionId: string,\n\t\t): Promise<PersistedSessionEvent[]> => {\n\t\t\tconst rows: {\n\t\t\t\tsession_id: string;\n\t\t\t\tseq: number;\n\t\t\t\tevent: string;\n\t\t\t\tcreated_at: number;\n\t\t\t}[] = await c.db.execute(\n\t\t\t\t`SELECT session_id, seq, event, created_at\n\t\t\t\t FROM agent_os_session_events\n\t\t\t\t WHERE session_id = ?\n\t\t\t\t ORDER BY seq ASC`,\n\t\t\t\tsessionId,\n\t\t\t);\n\n\t\t\treturn rows.map((row) => ({\n\t\t\t\tsessionId: row.session_id,\n\t\t\t\tseq: row.seq,\n\t\t\t\tevent: JSON.parse(row.event),\n\t\t\t\tcreatedAt: row.created_at,\n\t\t\t}));\n\t\t},\n\t};\n}\n","import type { OpenShellOptions } from \"@rivet-dev/agent-os-core\";\nimport type { AgentOsActorConfig } from \"../config\";\nimport type { AgentOsActionContext } from \"../types\";\nimport { ensureVm, syncPreventSleep } from \"./index\";\n\n// Build shell actions for the actor factory.\nexport function buildShellActions<TConnParams>(\n\tconfig: AgentOsActorConfig<TConnParams>,\n) {\n\treturn {\n\t\topenShell: async (\n\t\t\tc: AgentOsActionContext<TConnParams>,\n\t\t\toptions?: OpenShellOptions,\n\t\t): Promise<{ shellId: string }> => {\n\t\t\tconst agentOs = await ensureVm(c, config);\n\t\t\tconst { shellId } = agentOs.openShell(options);\n\n\t\t\t// Wire shell data to actor events.\n\t\t\tagentOs.onShellData(shellId, (data: Uint8Array) => {\n\t\t\t\tc.broadcast(\"shellData\", { shellId, data });\n\t\t\t});\n\n\t\t\tc.vars.activeShells.add(shellId);\n\t\t\tsyncPreventSleep(c);\n\t\t\tc.log.info({ msg: \"agent-os shell opened\", shellId });\n\n\t\t\treturn { shellId };\n\t\t},\n\n\t\twriteShell: async (\n\t\t\tc: AgentOsActionContext<TConnParams>,\n\t\t\tshellId: string,\n\t\t\tdata: string | Uint8Array,\n\t\t): Promise<void> => {\n\t\t\tconst agentOs = await ensureVm(c, config);\n\t\t\tagentOs.writeShell(shellId, data);\n\t\t},\n\n\t\tresizeShell: async (\n\t\t\tc: AgentOsActionContext<TConnParams>,\n\t\t\tshellId: string,\n\t\t\tcols: number,\n\t\t\trows: number,\n\t\t): Promise<void> => {\n\t\t\tconst agentOs = await ensureVm(c, config);\n\t\t\tagentOs.resizeShell(shellId, cols, rows);\n\t\t},\n\n\t\tcloseShell: async (\n\t\t\tc: AgentOsActionContext<TConnParams>,\n\t\t\tshellId: string,\n\t\t): Promise<void> => {\n\t\t\tconst agentOs = await ensureVm(c, config);\n\t\t\tagentOs.closeShell(shellId);\n\t\t\tc.vars.activeShells.delete(shellId);\n\t\t\tsyncPreventSleep(c);\n\t\t\tc.log.info({ msg: \"agent-os shell closed\", shellId });\n\t\t},\n\t};\n}\n","import type {\n\tAgentRegistryEntry,\n\tBatchReadResult,\n\tBatchWriteEntry,\n\tBatchWriteResult,\n\tDirEntry,\n\tReaddirRecursiveOptions,\n} from \"@rivet-dev/agent-os-core\";\nimport type { AgentOsActorConfig } from \"../config\";\nimport type { AgentOsActionContext } from \"../types\";\nimport { ensureVm } from \"./index\";\n\n// Infer types from AgentOs methods since @secure-exec/core is not a direct dep.\ntype VirtualStat = Awaited<\n\tReturnType<import(\"@rivet-dev/agent-os-core\").AgentOs[\"stat\"]>\n>;\ntype DeleteOptions = Parameters<\n\timport(\"@rivet-dev/agent-os-core\").AgentOs[\"delete\"]\n>[1];\n\n// Build filesystem and agent registry actions for the actor factory.\nexport function buildFilesystemActions<TConnParams>(\n\tconfig: AgentOsActorConfig<TConnParams>,\n) {\n\treturn {\n\t\treadFile: async (\n\t\t\tc: AgentOsActionContext<TConnParams>,\n\t\t\tpath: string,\n\t\t): Promise<Uint8Array> => {\n\t\t\tconst agentOs = await ensureVm(c, config);\n\t\t\treturn agentOs.readFile(path);\n\t\t},\n\n\t\twriteFile: async (\n\t\t\tc: AgentOsActionContext<TConnParams>,\n\t\t\tpath: string,\n\t\t\tcontent: string | Uint8Array,\n\t\t): Promise<void> => {\n\t\t\tconst agentOs = await ensureVm(c, config);\n\t\t\tawait agentOs.writeFile(path, content);\n\t\t},\n\n\t\treadFiles: async (\n\t\t\tc: AgentOsActionContext<TConnParams>,\n\t\t\tpaths: string[],\n\t\t): Promise<BatchReadResult[]> => {\n\t\t\tconst agentOs = await ensureVm(c, config);\n\t\t\treturn agentOs.readFiles(paths);\n\t\t},\n\n\t\twriteFiles: async (\n\t\t\tc: AgentOsActionContext<TConnParams>,\n\t\t\tentries: BatchWriteEntry[],\n\t\t): Promise<BatchWriteResult[]> => {\n\t\t\tconst agentOs = await ensureVm(c, config);\n\t\t\treturn agentOs.writeFiles(entries);\n\t\t},\n\n\t\tmkdir: async (\n\t\t\tc: AgentOsActionContext<TConnParams>,\n\t\t\tpath: string,\n\t\t\toptions?: { recursive?: boolean },\n\t\t): Promise<void> => {\n\t\t\tconst agentOs = await ensureVm(c, config);\n\t\t\tawait agentOs.mkdir(path, options);\n\t\t},\n\n\t\treaddir: async (\n\t\t\tc: AgentOsActionContext<TConnParams>,\n\t\t\tpath: string,\n\t\t): Promise<string[]> => {\n\t\t\tconst agentOs = await ensureVm(c, config);\n\t\t\treturn agentOs.readdir(path);\n\t\t},\n\n\t\treaddirRecursive: async (\n\t\t\tc: AgentOsActionContext<TConnParams>,\n\t\t\tpath: string,\n\t\t\toptions?: ReaddirRecursiveOptions,\n\t\t): Promise<DirEntry[]> => {\n\t\t\tconst agentOs = await ensureVm(c, config);\n\t\t\treturn agentOs.readdirRecursive(path, options);\n\t\t},\n\n\t\tstat: async (\n\t\t\tc: AgentOsActionContext<TConnParams>,\n\t\t\tpath: string,\n\t\t): Promise<VirtualStat> => {\n\t\t\tconst agentOs = await ensureVm(c, config);\n\t\t\treturn agentOs.stat(path);\n\t\t},\n\n\t\texists: async (\n\t\t\tc: AgentOsActionContext<TConnParams>,\n\t\t\tpath: string,\n\t\t): Promise<boolean> => {\n\t\t\tconst agentOs = await ensureVm(c, config);\n\t\t\treturn agentOs.exists(path);\n\t\t},\n\n\t\tmove: async (\n\t\t\tc: AgentOsActionContext<TConnParams>,\n\t\t\tfrom: string,\n\t\t\tto: string,\n\t\t): Promise<void> => {\n\t\t\tconst agentOs = await ensureVm(c, config);\n\t\t\tawait agentOs.move(from, to);\n\t\t},\n\n\t\tdeleteFile: async (\n\t\t\tc: AgentOsActionContext<TConnParams>,\n\t\t\tpath: string,\n\t\t\toptions?: DeleteOptions,\n\t\t): Promise<void> => {\n\t\t\tconst agentOs = await ensureVm(c, config);\n\t\t\tawait agentOs.delete(path, options);\n\t\t},\n\n\t\t// TODO: mountFs and unmountFs are not exposed as actor actions because\n\t\t// filesystem drivers (VirtualFileSystem) are not serializable over the\n\t\t// network. Mount filesystems via the `options.mounts` config in agentOs()\n\t\t// instead. See: https://github.com/rivet-dev/rivet/issues/XXXX\n\n\t\tlistAgents: async (\n\t\t\tc: AgentOsActionContext<TConnParams>,\n\t\t): Promise<AgentRegistryEntry[]> => {\n\t\t\tconst agentOs = await ensureVm(c, config);\n\t\t\treturn agentOs.listAgents();\n\t\t},\n\t};\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["/home/runner/work/rivet/rivet/rivetkit-typescript/packages/rivetkit/dist/tsup/agent-os/index.cjs","../../../src/agent-os/actor/db.ts","../../../src/agent-os/fs/database-vfs.ts","../../../src/agent-os/actor/index.ts","../../../src/actor/config.ts","../../../src/common/log.ts","../../../src/actor/errors.ts","../../../package.json","../../../src/utils.ts","../../../src/utils/env-vars.ts","../../../src/actor/log.ts","../../../src/actor/definition.ts","../../../src/actor/schema.ts","../../../src/common/database/shared.ts","../../../src/common/database/mod.ts","../../../src/agent-os/config.ts","../../../src/agent-os/actor/cron.ts","../../../src/agent-os/actor/network.ts","../../../src/agent-os/actor/preview.ts","../../../src/agent-os/actor/process.ts","../../../src/agent-os/actor/session.ts","../../../src/agent-os/actor/shell.ts","../../../src/agent-os/actor/filesystem.ts"],"names":["db","event","agentOs"],"mappings":"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","file":"/home/runner/work/rivet/rivet/rivetkit-typescript/packages/rivetkit/dist/tsup/agent-os/index.cjs","sourcesContent":[null,"import type { RawAccess } from \"@/common/database/config\";\n\nexport async function migrateAgentOsTables(db: RawAccess): Promise<void> {\n\tawait db.execute(`\n\t\tCREATE TABLE IF NOT EXISTS agent_os_preview_tokens (\n\t\t\ttoken TEXT PRIMARY KEY,\n\t\t\tport INTEGER NOT NULL,\n\t\t\tcreated_at INTEGER NOT NULL,\n\t\t\texpires_at INTEGER NOT NULL\n\t\t);\n\n\t\tCREATE INDEX IF NOT EXISTS idx_preview_tokens_expires_at\n\t\t\tON agent_os_preview_tokens(expires_at);\n\n\t\tCREATE TABLE IF NOT EXISTS agent_os_fs_entries (\n\t\t\tpath TEXT PRIMARY KEY,\n\t\t\tis_directory INTEGER NOT NULL DEFAULT 0,\n\t\t\tcontent BLOB,\n\t\t\tmode INTEGER NOT NULL DEFAULT 33188,\n\t\t\tuid INTEGER NOT NULL DEFAULT 0,\n\t\t\tgid INTEGER NOT NULL DEFAULT 0,\n\t\t\tsize INTEGER NOT NULL DEFAULT 0,\n\t\t\tatime_ms INTEGER NOT NULL,\n\t\t\tmtime_ms INTEGER NOT NULL,\n\t\t\tctime_ms INTEGER NOT NULL,\n\t\t\tbirthtime_ms INTEGER NOT NULL,\n\t\t\tsymlink_target TEXT,\n\t\t\tnlink INTEGER NOT NULL DEFAULT 1\n\t\t);\n\n\t\tCREATE INDEX IF NOT EXISTS idx_fs_entries_parent\n\t\t\tON agent_os_fs_entries(path);\n\n\t\tCREATE TABLE IF NOT EXISTS agent_os_sessions (\n\t\t\tsession_id TEXT PRIMARY KEY,\n\t\t\tagent_type TEXT NOT NULL,\n\t\t\tcapabilities TEXT NOT NULL,\n\t\t\tagent_info TEXT,\n\t\t\tcreated_at INTEGER NOT NULL\n\t\t);\n\n\t\tCREATE TABLE IF NOT EXISTS agent_os_session_events (\n\t\t\tid INTEGER PRIMARY KEY AUTOINCREMENT,\n\t\t\tsession_id TEXT NOT NULL,\n\t\t\tseq INTEGER NOT NULL,\n\t\t\tevent TEXT NOT NULL,\n\t\t\tcreated_at INTEGER NOT NULL,\n\t\t\tFOREIGN KEY (session_id) REFERENCES agent_os_sessions(session_id) ON DELETE CASCADE\n\t\t);\n\n\t\tCREATE INDEX IF NOT EXISTS idx_session_events_session_seq\n\t\t\tON agent_os_session_events(session_id, seq);\n\t`);\n}\n","/**\n * SQLite-backed VirtualFileSystem implementation.\n *\n * Stores file content, metadata (mode, timestamps), and directory structure\n * in SQLite tables managed by the RivetKit actor's database. This allows VM\n * filesystem state to persist across sleep/wake cycles.\n *\n * We use SQLite instead of actor KV because SQLite handles bulk write\n * optimizations (transactions, WAL mode, page caching) under the hood. With KV\n * we would need to manually chunk writes to stay under batch size limits,\n * implement our own indexing for directory listing queries, and handle\n * consistency across multiple KV operations. SQLite gives us all of this for\n * free.\n *\n * All paths are normalized to POSIX form (forward slashes, rooted at \"/\").\n */\n\nimport * as posixPath from \"node:path/posix\";\nimport type { RawAccess } from \"@/common/database/config\";\n\n// Infer VirtualFileSystem from PlainMountConfig.driver since\n// @secure-exec/core is not a direct dependency of this package.\ntype VirtualFileSystem =\n\timport(\"@rivet-dev/agent-os-core\").PlainMountConfig[\"driver\"];\n\n// Infer VirtualStat from AgentOs.stat() return type.\ntype VirtualStat = Awaited<\n\tReturnType<import(\"@rivet-dev/agent-os-core\").AgentOs[\"stat\"]>\n>;\n\n// Infer VirtualDirEntry from readDirWithTypes.\n// VirtualDirEntry has: name, isDirectory, isSymbolicLink?, ino?\ninterface VirtualDirEntry {\n\tname: string;\n\tisDirectory: boolean;\n\tisSymbolicLink?: boolean;\n\tino?: number;\n}\n\n// POSIX mode constants.\nconst S_IFDIR = 0o040000;\nconst S_IFREG = 0o100000;\nconst S_IFLNK = 0o120000;\nconst DEFAULT_FILE_MODE = S_IFREG | 0o644;\nconst DEFAULT_DIR_MODE = S_IFDIR | 0o755;\n\ninterface FsRow extends Record<string, unknown> {\n\tpath: string;\n\tis_directory: number;\n\tcontent: Uint8Array | null;\n\tmode: number;\n\tuid: number;\n\tgid: number;\n\tsize: number;\n\tatime_ms: number;\n\tmtime_ms: number;\n\tctime_ms: number;\n\tbirthtime_ms: number;\n\tsymlink_target: string | null;\n\tnlink: number;\n}\n\nfunction normPath(p: string): string {\n\tconst normalized = posixPath.normalize(`/${p}`);\n\t// Remove trailing slash unless it's the root.\n\tif (normalized.length > 1 && normalized.endsWith(\"/\")) {\n\t\treturn normalized.slice(0, -1);\n\t}\n\treturn normalized;\n}\n\nfunction parentPath(p: string): string {\n\tconst parent = posixPath.dirname(p);\n\treturn parent;\n}\n\nfunction throwENOENT(path: string): never {\n\tconst err = new Error(`ENOENT: no such file or directory: ${path}`);\n\terr.name = \"ENOENT\";\n\tthrow err;\n}\n\nfunction throwEEXIST(path: string): never {\n\tconst err = new Error(`EEXIST: file already exists: ${path}`);\n\terr.name = \"EEXIST\";\n\tthrow err;\n}\n\nfunction throwENOTDIR(path: string): never {\n\tconst err = new Error(`ENOTDIR: not a directory: ${path}`);\n\terr.name = \"ENOTDIR\";\n\tthrow err;\n}\n\nfunction throwEISDIR(path: string): never {\n\tconst err = new Error(`EISDIR: illegal operation on a directory: ${path}`);\n\terr.name = \"EISDIR\";\n\tthrow err;\n}\n\nfunction throwENOTEMPTY(path: string): never {\n\tconst err = new Error(`ENOTEMPTY: directory not empty: ${path}`);\n\terr.name = \"ENOTEMPTY\";\n\tthrow err;\n}\n\nfunction throwENOSYS(op: string): never {\n\tconst err = new Error(`ENOSYS: function not implemented: ${op}`);\n\terr.name = \"ENOSYS\";\n\tthrow err;\n}\n\nfunction rowToStat(row: FsRow): VirtualStat {\n\treturn {\n\t\tmode: row.mode,\n\t\tsize: row.size,\n\t\tisDirectory: row.is_directory === 1,\n\t\tisSymbolicLink: row.symlink_target !== null,\n\t\tatimeMs: row.atime_ms,\n\t\tmtimeMs: row.mtime_ms,\n\t\tctimeMs: row.ctime_ms,\n\t\tbirthtimeMs: row.birthtime_ms,\n\t\tino: 0,\n\t\tnlink: row.nlink,\n\t\tuid: row.uid,\n\t\tgid: row.gid,\n\t};\n}\n\nexport interface DatabaseVfsOptions {\n\t/** The RawAccess database handle from the actor's db provider. */\n\tdb: RawAccess;\n}\n\n/**\n * Create a VirtualFileSystem backed by SQLite.\n *\n * The returned filesystem stores all content and metadata in the\n * `agent_os_fs_entries` table. The table must be created beforehand\n * via `migrateAgentOsTables()`.\n */\nexport function createDatabaseVfs(\n\toptions: DatabaseVfsOptions,\n): VirtualFileSystem {\n\tconst { db } = options;\n\n\tasync function getEntry(path: string): Promise<FsRow | undefined> {\n\t\tconst rows = await db.execute<FsRow>(\n\t\t\t\"SELECT * FROM agent_os_fs_entries WHERE path = ?\",\n\t\t\tpath,\n\t\t);\n\t\treturn rows[0];\n\t}\n\n\tasync function getEntryOrThrow(path: string): Promise<FsRow> {\n\t\tconst entry = await getEntry(path);\n\t\tif (!entry) {\n\t\t\tthrowENOENT(path);\n\t\t}\n\t\treturn entry;\n\t}\n\n\tasync function ensureParentExists(path: string): Promise<void> {\n\t\tconst parent = parentPath(path);\n\t\tif (parent === path) return; // root\n\t\tconst entry = await getEntry(parent);\n\t\tif (!entry) {\n\t\t\tthrowENOENT(parent);\n\t\t}\n\t\tif (entry.is_directory !== 1) {\n\t\t\tthrowENOTDIR(parent);\n\t\t}\n\t}\n\n\tasync function getChildEntries(dirPath: string): Promise<FsRow[]> {\n\t\t// Find direct children by matching paths that are one level deeper.\n\t\t// A direct child of \"/foo\" has path like \"/foo/bar\" but NOT \"/foo/bar/baz\".\n\t\tconst prefix = dirPath === \"/\" ? \"/\" : `${dirPath}/`;\n\t\tconst rows = await db.execute<FsRow>(\n\t\t\t\"SELECT * FROM agent_os_fs_entries WHERE path LIKE ? AND path != ?\",\n\t\t\t`${prefix}%`,\n\t\t\tdirPath,\n\t\t);\n\t\t// Filter to direct children only.\n\t\treturn rows.filter((row) => {\n\t\t\tconst relative = row.path.slice(prefix.length);\n\t\t\treturn relative.length > 0 && !relative.includes(\"/\");\n\t\t});\n\t}\n\n\t// Ensure root directory exists.\n\tconst rootInit = (async () => {\n\t\tconst root = await getEntry(\"/\");\n\t\tif (!root) {\n\t\t\tconst now = Date.now();\n\t\t\tawait db.execute(\n\t\t\t\t`INSERT OR IGNORE INTO agent_os_fs_entries (path, is_directory, content, mode, uid, gid, size, atime_ms, mtime_ms, ctime_ms, birthtime_ms, symlink_target, nlink) VALUES (?, 1, NULL, ?, 0, 0, 0, ?, ?, ?, ?, NULL, 2)`,\n\t\t\t\t\"/\",\n\t\t\t\tDEFAULT_DIR_MODE,\n\t\t\t\tnow,\n\t\t\t\tnow,\n\t\t\t\tnow,\n\t\t\t\tnow,\n\t\t\t);\n\t\t}\n\t})();\n\n\tconst backend: VirtualFileSystem = {\n\t\tasync readFile(p: string): Promise<Uint8Array> {\n\t\t\tawait rootInit;\n\t\t\tconst path = normPath(p);\n\t\t\tconst entry = await getEntryOrThrow(path);\n\t\t\tif (entry.is_directory === 1) {\n\t\t\t\tthrowEISDIR(path);\n\t\t\t}\n\t\t\treturn entry.content ?? new Uint8Array(0);\n\t\t},\n\n\t\tasync readTextFile(p: string): Promise<string> {\n\t\t\tconst data = await backend.readFile(p);\n\t\t\treturn new TextDecoder().decode(data);\n\t\t},\n\n\t\tasync readDir(p: string): Promise<string[]> {\n\t\t\tawait rootInit;\n\t\t\tconst path = normPath(p);\n\t\t\tconst entry = await getEntryOrThrow(path);\n\t\t\tif (entry.is_directory !== 1) {\n\t\t\t\tthrowENOTDIR(path);\n\t\t\t}\n\t\t\tconst children = await getChildEntries(path);\n\t\t\treturn children.map((child) => posixPath.basename(child.path));\n\t\t},\n\n\t\tasync readDirWithTypes(p: string): Promise<VirtualDirEntry[]> {\n\t\t\tawait rootInit;\n\t\t\tconst path = normPath(p);\n\t\t\tconst entry = await getEntryOrThrow(path);\n\t\t\tif (entry.is_directory !== 1) {\n\t\t\t\tthrowENOTDIR(path);\n\t\t\t}\n\t\t\tconst children = await getChildEntries(path);\n\t\t\treturn children.map((child) => ({\n\t\t\t\tname: posixPath.basename(child.path),\n\t\t\t\tisDirectory: child.is_directory === 1,\n\t\t\t\tisSymbolicLink: child.symlink_target !== null,\n\t\t\t\tino: 0,\n\t\t\t}));\n\t\t},\n\n\t\tasync writeFile(\n\t\t\tp: string,\n\t\t\tcontent: string | Uint8Array,\n\t\t): Promise<void> {\n\t\t\tawait rootInit;\n\t\t\tconst path = normPath(p);\n\t\t\tawait ensureParentExists(path);\n\n\t\t\tconst existing = await getEntry(path);\n\t\t\tif (existing && existing.is_directory === 1) {\n\t\t\t\tthrowEISDIR(path);\n\t\t\t}\n\n\t\t\tconst data =\n\t\t\t\ttypeof content === \"string\"\n\t\t\t\t\t? new TextEncoder().encode(content)\n\t\t\t\t\t: content;\n\t\t\tconst now = Date.now();\n\n\t\t\tif (existing) {\n\t\t\t\tawait db.execute(\n\t\t\t\t\t`UPDATE agent_os_fs_entries SET content = ?, size = ?, mtime_ms = ?, ctime_ms = ?, atime_ms = ? WHERE path = ?`,\n\t\t\t\t\tdata,\n\t\t\t\t\tdata.byteLength,\n\t\t\t\t\tnow,\n\t\t\t\t\tnow,\n\t\t\t\t\tnow,\n\t\t\t\t\tpath,\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tawait db.execute(\n\t\t\t\t\t`INSERT INTO agent_os_fs_entries (path, is_directory, content, mode, uid, gid, size, atime_ms, mtime_ms, ctime_ms, birthtime_ms, symlink_target, nlink) VALUES (?, 0, ?, ?, 0, 0, ?, ?, ?, ?, ?, NULL, 1)`,\n\t\t\t\t\tpath,\n\t\t\t\t\tdata,\n\t\t\t\t\tDEFAULT_FILE_MODE,\n\t\t\t\t\tdata.byteLength,\n\t\t\t\t\tnow,\n\t\t\t\t\tnow,\n\t\t\t\t\tnow,\n\t\t\t\t\tnow,\n\t\t\t\t);\n\t\t\t}\n\t\t},\n\n\t\tasync createDir(p: string): Promise<void> {\n\t\t\tawait rootInit;\n\t\t\tconst path = normPath(p);\n\t\t\tawait ensureParentExists(path);\n\n\t\t\tconst existing = await getEntry(path);\n\t\t\tif (existing) {\n\t\t\t\tthrowEEXIST(path);\n\t\t\t}\n\n\t\t\tconst now = Date.now();\n\t\t\tawait db.execute(\n\t\t\t\t`INSERT INTO agent_os_fs_entries (path, is_directory, content, mode, uid, gid, size, atime_ms, mtime_ms, ctime_ms, birthtime_ms, symlink_target, nlink) VALUES (?, 1, NULL, ?, 0, 0, 0, ?, ?, ?, ?, NULL, 2)`,\n\t\t\t\tpath,\n\t\t\t\tDEFAULT_DIR_MODE,\n\t\t\t\tnow,\n\t\t\t\tnow,\n\t\t\t\tnow,\n\t\t\t\tnow,\n\t\t\t);\n\t\t},\n\n\t\tasync mkdir(\n\t\t\tp: string,\n\t\t\toptions?: { recursive?: boolean },\n\t\t): Promise<void> {\n\t\t\tawait rootInit;\n\t\t\tconst path = normPath(p);\n\n\t\t\tif (options?.recursive) {\n\t\t\t\tconst parts = path.split(\"/\").filter(Boolean);\n\t\t\t\tlet current = \"\";\n\t\t\t\tfor (const part of parts) {\n\t\t\t\t\tcurrent += `/${part}`;\n\t\t\t\t\tconst existing = await getEntry(current);\n\t\t\t\t\tif (!existing) {\n\t\t\t\t\t\tconst now = Date.now();\n\t\t\t\t\t\tawait db.execute(\n\t\t\t\t\t\t\t`INSERT INTO agent_os_fs_entries (path, is_directory, content, mode, uid, gid, size, atime_ms, mtime_ms, ctime_ms, birthtime_ms, symlink_target, nlink) VALUES (?, 1, NULL, ?, 0, 0, 0, ?, ?, ?, ?, NULL, 2)`,\n\t\t\t\t\t\t\tcurrent,\n\t\t\t\t\t\t\tDEFAULT_DIR_MODE,\n\t\t\t\t\t\t\tnow,\n\t\t\t\t\t\t\tnow,\n\t\t\t\t\t\t\tnow,\n\t\t\t\t\t\t\tnow,\n\t\t\t\t\t\t);\n\t\t\t\t\t} else if (existing.is_directory !== 1) {\n\t\t\t\t\t\tthrowENOTDIR(current);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tawait backend.createDir(p);\n\t\t\t}\n\t\t},\n\n\t\tasync exists(p: string): Promise<boolean> {\n\t\t\tawait rootInit;\n\t\t\tconst path = normPath(p);\n\t\t\tconst entry = await getEntry(path);\n\t\t\treturn entry !== undefined;\n\t\t},\n\n\t\tasync stat(p: string): Promise<VirtualStat> {\n\t\t\tawait rootInit;\n\t\t\tconst path = normPath(p);\n\t\t\tconst entry = await getEntryOrThrow(path);\n\t\t\treturn rowToStat(entry);\n\t\t},\n\n\t\tasync removeFile(p: string): Promise<void> {\n\t\t\tawait rootInit;\n\t\t\tconst path = normPath(p);\n\t\t\tconst entry = await getEntryOrThrow(path);\n\t\t\tif (entry.is_directory === 1) {\n\t\t\t\tthrowEISDIR(path);\n\t\t\t}\n\t\t\tawait db.execute(\n\t\t\t\t\"DELETE FROM agent_os_fs_entries WHERE path = ?\",\n\t\t\t\tpath,\n\t\t\t);\n\t\t},\n\n\t\tasync removeDir(p: string): Promise<void> {\n\t\t\tawait rootInit;\n\t\t\tconst path = normPath(p);\n\t\t\tconst entry = await getEntryOrThrow(path);\n\t\t\tif (entry.is_directory !== 1) {\n\t\t\t\tthrowENOTDIR(path);\n\t\t\t}\n\t\t\tconst children = await getChildEntries(path);\n\t\t\tif (children.length > 0) {\n\t\t\t\tthrowENOTEMPTY(path);\n\t\t\t}\n\t\t\tawait db.execute(\n\t\t\t\t\"DELETE FROM agent_os_fs_entries WHERE path = ?\",\n\t\t\t\tpath,\n\t\t\t);\n\t\t},\n\n\t\tasync rename(oldPath: string, newPath: string): Promise<void> {\n\t\t\tawait rootInit;\n\t\t\tconst from = normPath(oldPath);\n\t\t\tconst to = normPath(newPath);\n\n\t\t\tconst entry = await getEntryOrThrow(from);\n\t\t\tawait ensureParentExists(to);\n\n\t\t\t// Remove destination if it exists (overwrite semantics).\n\t\t\tconst destEntry = await getEntry(to);\n\t\t\tif (destEntry) {\n\t\t\t\tif (destEntry.is_directory === 1) {\n\t\t\t\t\tconst children = await getChildEntries(to);\n\t\t\t\t\tif (children.length > 0) {\n\t\t\t\t\t\tthrowENOTEMPTY(to);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tawait db.execute(\n\t\t\t\t\t\"DELETE FROM agent_os_fs_entries WHERE path = ?\",\n\t\t\t\t\tto,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tif (entry.is_directory === 1) {\n\t\t\t\t// Move all descendants by updating path prefixes.\n\t\t\t\tconst prefix = from === \"/\" ? \"/\" : `${from}/`;\n\t\t\t\tconst newPrefix = to === \"/\" ? \"/\" : `${to}/`;\n\n\t\t\t\t// Get all descendants first, then update them.\n\t\t\t\tconst descendants = await db.execute<FsRow>(\n\t\t\t\t\t\"SELECT path FROM agent_os_fs_entries WHERE path LIKE ?\",\n\t\t\t\t\t`${prefix}%`,\n\t\t\t\t);\n\n\t\t\t\tfor (const desc of descendants) {\n\t\t\t\t\tconst newDescPath =\n\t\t\t\t\t\tnewPrefix + desc.path.slice(prefix.length);\n\t\t\t\t\tawait db.execute(\n\t\t\t\t\t\t\"UPDATE agent_os_fs_entries SET path = ? WHERE path = ?\",\n\t\t\t\t\t\tnewDescPath,\n\t\t\t\t\t\tdesc.path,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Update the entry itself.\n\t\t\tconst now = Date.now();\n\t\t\tawait db.execute(\n\t\t\t\t\"UPDATE agent_os_fs_entries SET path = ?, ctime_ms = ? WHERE path = ?\",\n\t\t\t\tto,\n\t\t\t\tnow,\n\t\t\t\tfrom,\n\t\t\t);\n\t\t},\n\n\t\tasync realpath(p: string): Promise<string> {\n\t\t\tawait rootInit;\n\t\t\tconst path = normPath(p);\n\t\t\tconst entry = await getEntryOrThrow(path);\n\t\t\tif (entry.symlink_target !== null) {\n\t\t\t\treturn normPath(entry.symlink_target);\n\t\t\t}\n\t\t\treturn path;\n\t\t},\n\n\t\tasync symlink(target: string, linkPath: string): Promise<void> {\n\t\t\tawait rootInit;\n\t\t\tconst link = normPath(linkPath);\n\t\t\tawait ensureParentExists(link);\n\n\t\t\tconst existing = await getEntry(link);\n\t\t\tif (existing) {\n\t\t\t\tthrowEEXIST(link);\n\t\t\t}\n\n\t\t\tconst now = Date.now();\n\t\t\tawait db.execute(\n\t\t\t\t`INSERT INTO agent_os_fs_entries (path, is_directory, content, mode, uid, gid, size, atime_ms, mtime_ms, ctime_ms, birthtime_ms, symlink_target, nlink) VALUES (?, 0, NULL, ?, 0, 0, ?, ?, ?, ?, ?, ?, 1)`,\n\t\t\t\tlink,\n\t\t\t\tS_IFLNK | 0o777,\n\t\t\t\ttarget.length,\n\t\t\t\tnow,\n\t\t\t\tnow,\n\t\t\t\tnow,\n\t\t\t\tnow,\n\t\t\t\ttarget,\n\t\t\t);\n\t\t},\n\n\t\tasync readlink(p: string): Promise<string> {\n\t\t\tawait rootInit;\n\t\t\tconst path = normPath(p);\n\t\t\tconst entry = await getEntryOrThrow(path);\n\t\t\tif (entry.symlink_target === null) {\n\t\t\t\tconst err = new Error(`EINVAL: not a symlink: ${path}`);\n\t\t\t\terr.name = \"EINVAL\";\n\t\t\t\tthrow err;\n\t\t\t}\n\t\t\treturn entry.symlink_target;\n\t\t},\n\n\t\tasync lstat(p: string): Promise<VirtualStat> {\n\t\t\t// lstat does not follow symlinks; same as stat for our storage model.\n\t\t\treturn backend.stat(p);\n\t\t},\n\n\t\tasync link(oldPath: string, newPath: string): Promise<void> {\n\t\t\tthrowENOSYS(\"link\");\n\t\t},\n\n\t\tasync chmod(p: string, mode: number): Promise<void> {\n\t\t\tawait rootInit;\n\t\t\tconst path = normPath(p);\n\t\t\tawait getEntryOrThrow(path);\n\t\t\tconst now = Date.now();\n\t\t\tawait db.execute(\n\t\t\t\t\"UPDATE agent_os_fs_entries SET mode = ?, ctime_ms = ? WHERE path = ?\",\n\t\t\t\tmode,\n\t\t\t\tnow,\n\t\t\t\tpath,\n\t\t\t);\n\t\t},\n\n\t\tasync chown(p: string, uid: number, gid: number): Promise<void> {\n\t\t\tawait rootInit;\n\t\t\tconst path = normPath(p);\n\t\t\tawait getEntryOrThrow(path);\n\t\t\tconst now = Date.now();\n\t\t\tawait db.execute(\n\t\t\t\t\"UPDATE agent_os_fs_entries SET uid = ?, gid = ?, ctime_ms = ? WHERE path = ?\",\n\t\t\t\tuid,\n\t\t\t\tgid,\n\t\t\t\tnow,\n\t\t\t\tpath,\n\t\t\t);\n\t\t},\n\n\t\tasync utimes(p: string, atime: number, mtime: number): Promise<void> {\n\t\t\tawait rootInit;\n\t\t\tconst path = normPath(p);\n\t\t\tawait getEntryOrThrow(path);\n\t\t\tconst now = Date.now();\n\t\t\tawait db.execute(\n\t\t\t\t\"UPDATE agent_os_fs_entries SET atime_ms = ?, mtime_ms = ?, ctime_ms = ? WHERE path = ?\",\n\t\t\t\tatime,\n\t\t\t\tmtime,\n\t\t\t\tnow,\n\t\t\t\tpath,\n\t\t\t);\n\t\t},\n\n\t\tasync truncate(p: string, length: number): Promise<void> {\n\t\t\tawait rootInit;\n\t\t\tconst path = normPath(p);\n\t\t\tconst entry = await getEntryOrThrow(path);\n\t\t\tif (entry.is_directory === 1) {\n\t\t\t\tthrowEISDIR(path);\n\t\t\t}\n\n\t\t\tconst existing = entry.content ?? new Uint8Array(0);\n\t\t\tlet newContent: Uint8Array;\n\t\t\tif (length >= existing.byteLength) {\n\t\t\t\t// Extend with zeros.\n\t\t\t\tnewContent = new Uint8Array(length);\n\t\t\t\tnewContent.set(existing);\n\t\t\t} else {\n\t\t\t\t// Truncate.\n\t\t\t\tnewContent = existing.slice(0, length);\n\t\t\t}\n\n\t\t\tconst now = Date.now();\n\t\t\tawait db.execute(\n\t\t\t\t\"UPDATE agent_os_fs_entries SET content = ?, size = ?, mtime_ms = ?, ctime_ms = ? WHERE path = ?\",\n\t\t\t\tnewContent,\n\t\t\t\tlength,\n\t\t\t\tnow,\n\t\t\t\tnow,\n\t\t\t\tpath,\n\t\t\t);\n\t\t},\n\n\t\tasync pread(\n\t\t\tp: string,\n\t\t\toffset: number,\n\t\t\tlength: number,\n\t\t): Promise<Uint8Array> {\n\t\t\tawait rootInit;\n\t\t\tconst path = normPath(p);\n\t\t\tconst entry = await getEntryOrThrow(path);\n\t\t\tif (entry.is_directory === 1) {\n\t\t\t\tthrowEISDIR(path);\n\t\t\t}\n\t\t\tconst content = entry.content ?? new Uint8Array(0);\n\t\t\tconst end = Math.min(offset + length, content.byteLength);\n\t\t\tif (offset >= content.byteLength) {\n\t\t\t\treturn new Uint8Array(0);\n\t\t\t}\n\t\t\treturn content.slice(offset, end);\n\t\t},\n\n\t\tasync pwrite(\n\t\t\tp: string,\n\t\t\toffset: number,\n\t\t\tdata: Uint8Array,\n\t\t): Promise<void> {\n\t\t\tawait rootInit;\n\t\t\tconst path = normPath(p);\n\t\t\tconst entry = await getEntryOrThrow(path);\n\t\t\tif (entry.is_directory === 1) {\n\t\t\t\tthrowEISDIR(path);\n\t\t\t}\n\t\t\tconst content = entry.content ?? new Uint8Array(0);\n\t\t\tconst end = offset + data.byteLength;\n\t\t\tconst newSize = Math.max(content.byteLength, end);\n\t\t\tconst buf = new Uint8Array(newSize);\n\t\t\tbuf.set(content);\n\t\t\tbuf.set(data, offset);\n\t\t\tconst now = Date.now();\n\t\t\tawait db.execute(\n\t\t\t\t`UPDATE agent_os_fs_entries SET content = ?, size = ?, mtime_ms = ?, ctime_ms = ? WHERE path = ?`,\n\t\t\t\tbuf,\n\t\t\t\tnewSize,\n\t\t\t\tnow,\n\t\t\t\tnow,\n\t\t\t\tpath,\n\t\t\t);\n\t\t},\n\t};\n\n\treturn backend;\n}\n","import { AgentOs, createInMemoryFileSystem } from \"@rivet-dev/agent-os-core\";\nimport type { AgentOsOptions, MountConfig } from \"@rivet-dev/agent-os-core\";\nimport type { DatabaseProvider } from \"@/common/database/config\";\nimport { actor, event } from \"@/actor/mod\";\nimport type { RawAccess } from \"@/common/database/config\";\nimport { db } from \"@/common/database/mod\";\nimport {\n\ttype AgentOsActorConfig,\n\ttype AgentOsActorConfigInput,\n\tagentOsActorConfigSchema,\n} from \"../config\";\nimport type {\n\tAgentOsActionContext,\n\tAgentOsActorState,\n\tAgentOsActorVars,\n\tCronEventPayload,\n\tPermissionRequestPayload,\n\tProcessExitPayload,\n\tProcessOutputPayload,\n\tSessionEventPayload,\n\tShellDataPayload,\n\tVmBootedPayload,\n\tVmShutdownPayload,\n} from \"../types\";\nimport { buildCronActions } from \"./cron\";\nimport { migrateAgentOsTables } from \"./db\";\nimport { buildFilesystemActions } from \"./filesystem\";\nimport { buildNetworkActions } from \"./network\";\nimport { buildOnRequestHandler, buildPreviewActions } from \"./preview\";\nimport { buildProcessActions } from \"./process\";\nimport {\n\tbuildConfigActions,\n\tbuildPromptActions,\n\tbuildSessionActions,\n\tbuildSessionPersistenceActions,\n} from \"./session\";\nimport { buildShellActions } from \"./shell\";\n\n// --- VM lifecycle helpers ---\n\nasync function ensureVm<TConnParams>(\n\tc: AgentOsActionContext<TConnParams>,\n\tconfig: AgentOsActorConfig<TConnParams>,\n): Promise<AgentOs> {\n\tif (c.vars.agentOs) {\n\t\treturn c.vars.agentOs;\n\t}\n\n\tconst start = Date.now();\n\n\t// Build options with in-memory VFS as default working directory mount.\n\tconst options = buildVmOptions(config.options);\n\n\tconst agentOs = await AgentOs.create(options);\n\tc.vars.agentOs = agentOs;\n\n\t// Wire cron events to actor events.\n\tagentOs.onCronEvent((cronEvent) => {\n\t\tc.broadcast(\"cronEvent\", { event: cronEvent });\n\t});\n\n\tc.broadcast(\"vmBooted\", {});\n\tc.log.info({\n\t\tmsg: \"agent-os vm booted\",\n\t\tbootDurationMs: Date.now() - start,\n\t});\n\n\treturn agentOs;\n}\n\nfunction buildVmOptions(userOptions?: AgentOsOptions): AgentOsOptions {\n\tconst userMounts = userOptions?.mounts ?? [];\n\n\t// Check if the user already provided a mount at /home/user. If so, respect\n\t// their override and skip the default in-memory VFS mount.\n\tconst hasWorkdirMount = userMounts.some(\n\t\t(m: MountConfig) => m.path === \"/home/user\",\n\t);\n\n\tif (hasWorkdirMount) {\n\t\treturn userOptions ?? {};\n\t}\n\n\t// TODO: Reimplement with persistent backend (actor KV-backed metadata +\n\t// actor storage-backed blocks) so VM filesystem state survives sleep/wake.\n\tconst memMount: MountConfig = {\n\t\tpath: \"/home/user\",\n\t\tdriver: createInMemoryFileSystem(),\n\t};\n\n\treturn {\n\t\t...userOptions,\n\t\tmounts: [memMount, ...userMounts],\n\t};\n}\n\n// --- Prevent-sleep coordination ---\n\nfunction syncPreventSleep<TConnParams>(\n\tc: AgentOsActionContext<TConnParams>,\n): void {\n\tconst shouldPrevent =\n\t\tc.vars.activeSessionIds.size > 0 ||\n\t\tc.vars.activeProcesses.size > 0 ||\n\t\tc.vars.activeHooks.size > 0 ||\n\t\tc.vars.activeShells.size > 0;\n\n\tc.setPreventSleep(shouldPrevent);\n\n\tc.log.info({\n\t\tmsg: \"agent-os prevent sleep sync\",\n\t\tpreventSleep: shouldPrevent,\n\t\tactiveSessions: c.vars.activeSessionIds.size,\n\t\tactiveProcesses: c.vars.activeProcesses.size,\n\t\tactiveHooks: c.vars.activeHooks.size,\n\t\tactiveShells: c.vars.activeShells.size,\n\t});\n}\n\n// --- Hook tracking ---\n\nfunction runHook<TConnParams>(\n\tc: AgentOsActionContext<TConnParams>,\n\tname: string,\n\tcallback: () => void | Promise<void>,\n): void {\n\tconst promise = Promise.resolve(callback())\n\t\t.catch((error) =>\n\t\t\tc.log.error({ msg: \"agent-os hook failed\", hookName: name, error }),\n\t\t)\n\t\t.finally(() => {\n\t\t\tc.vars.activeHooks.delete(promise);\n\t\t\tsyncPreventSleep(c);\n\t\t});\n\tc.vars.activeHooks.add(promise);\n\tsyncPreventSleep(c);\n\tc.waitUntil(promise);\n}\n\n// --- Public API ---\n\nexport function agentOs<TConnParams = undefined>(\n\tconfig: AgentOsActorConfigInput<TConnParams>,\n) {\n\tconst parsedConfig = agentOsActorConfigSchema.parse(\n\t\tconfig,\n\t) as AgentOsActorConfig<TConnParams>;\n\n\treturn actor<\n\t\tAgentOsActorState,\n\t\tTConnParams,\n\t\tundefined,\n\t\tAgentOsActorVars,\n\t\tundefined,\n\t\tDatabaseProvider<RawAccess>,\n\t\t{\n\t\t\tsessionEvent: typeof sessionEventToken;\n\t\t\tpermissionRequest: typeof permissionRequestToken;\n\t\t\tvmBooted: typeof vmBootedToken;\n\t\t\tvmShutdown: typeof vmShutdownToken;\n\t\t\tprocessOutput: typeof processOutputToken;\n\t\t\tprocessExit: typeof processExitToken;\n\t\t\tshellData: typeof shellDataToken;\n\t\t\tcronEvent: typeof cronEventToken;\n\t\t},\n\t\tRecord<never, never>\n\t>({\n\t\toptions: {\n\t\t\tsleepGracePeriod: 900_000,\n\t\t\tactionTimeout: 900_000,\n\t\t},\n\t\tcreateState: async () => ({}),\n\t\tcreateVars: () => ({\n\t\t\tagentOs: null,\n\t\t\tactiveSessionIds: new Set<string>(),\n\t\t\tactiveProcesses: new Set<number>(),\n\t\t\tactiveHooks: new Set<Promise<void>>(),\n\t\t\tactiveShells: new Set<string>(),\n\t\t\tsessions: new Set(),\n\t\t}),\n\t\tdb: db({\n\t\t\tonMigrate: migrateAgentOsTables,\n\t\t}),\n\t\tevents: {\n\t\t\tsessionEvent: sessionEventToken,\n\t\t\tpermissionRequest: permissionRequestToken,\n\t\t\tvmBooted: vmBootedToken,\n\t\t\tvmShutdown: vmShutdownToken,\n\t\t\tprocessOutput: processOutputToken,\n\t\t\tprocessExit: processExitToken,\n\t\t\tshellData: shellDataToken,\n\t\t\tcronEvent: cronEventToken,\n\t\t},\n\t\tonBeforeConnect: parsedConfig.onBeforeConnect\n\t\t\t? async (ctx, params) => {\n\t\t\t\t\t// Skip user auth for preview URL requests. The signed token\n\t\t\t\t\t// in onRequest is the credential; browsers navigating preview\n\t\t\t\t\t// URLs cannot supply actor connection params.\n\t\t\t\t\tif (ctx.request) {\n\t\t\t\t\t\tconst url = new URL(ctx.request.url);\n\t\t\t\t\t\tif (url.pathname.startsWith(\"/fetch/\")) {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tawait parsedConfig.onBeforeConnect?.(ctx, params);\n\t\t\t\t}\n\t\t\t: undefined,\n\t\tonRequest: buildOnRequestHandler(parsedConfig),\n\t\tonSleep: async (c) => {\n\t\t\tc.log.info({\n\t\t\t\tmsg: \"agent-os vm shutdown for sleep\",\n\t\t\t\tactiveSessions: c.vars.sessions.size,\n\t\t\t\tactiveProcesses: c.vars.activeProcesses.size,\n\t\t\t\tactiveShells: c.vars.activeShells.size,\n\t\t\t});\n\n\t\t\tif (c.vars.agentOs) {\n\t\t\t\tawait c.vars.agentOs.dispose();\n\t\t\t\tc.vars.agentOs = null;\n\t\t\t}\n\n\t\t\tc.broadcast(\"vmShutdown\", { reason: \"sleep\" as const });\n\t\t},\n\t\tonDestroy: async (c) => {\n\t\t\tc.log.info({\n\t\t\t\tmsg: \"agent-os vm shutdown for destroy\",\n\t\t\t\tactiveSessions: c.vars.sessions.size,\n\t\t\t\tactiveProcesses: c.vars.activeProcesses.size,\n\t\t\t\tactiveShells: c.vars.activeShells.size,\n\t\t\t});\n\n\t\t\tif (c.vars.agentOs) {\n\t\t\t\tawait c.vars.agentOs.dispose();\n\t\t\t\tc.vars.agentOs = null;\n\t\t\t}\n\n\t\t\tc.broadcast(\"vmShutdown\", { reason: \"destroy\" as const });\n\t\t},\n\t\tactions: {\n\t\t\t...buildSessionActions(parsedConfig),\n\t\t\t...buildPromptActions(parsedConfig),\n\t\t\t...buildConfigActions(parsedConfig),\n\t\t\t...buildSessionPersistenceActions(parsedConfig),\n\t\t\t...buildProcessActions(parsedConfig),\n\t\t\t...buildFilesystemActions(parsedConfig),\n\t\t\t...buildPreviewActions(parsedConfig),\n\t\t\t...buildShellActions(parsedConfig),\n\t\t\t...buildCronActions(parsedConfig),\n\t\t\t...buildNetworkActions(parsedConfig),\n\t\t},\n\t});\n}\n\n// Event type tokens. Declared at module level so they can be referenced in\n// the actor generic type parameters.\nconst sessionEventToken = event<SessionEventPayload>();\nconst permissionRequestToken = event<PermissionRequestPayload>();\nconst vmBootedToken = event<VmBootedPayload>();\nconst vmShutdownToken = event<VmShutdownPayload>();\nconst processOutputToken = event<ProcessOutputPayload>();\nconst processExitToken = event<ProcessExitPayload>();\nconst shellDataToken = event<ShellDataPayload>();\nconst cronEventToken = event<CronEventPayload>();\n\nexport { ensureVm, syncPreventSleep, runHook };\n","import { z } from \"zod/v4\";\nimport type { UniversalWebSocket } from \"@/common/websocket-interface\";\nimport type {\n\tAnyDatabaseProvider,\n\tInferDatabaseClient,\n\tRawDatabaseClient,\n\tDrizzleDatabaseClient,\n\tNativeDatabaseProvider,\n} from \"@/common/database/config\";\nimport type { Client } from \"@/client/client\";\nimport type { Registry } from \"@/registry\";\nimport type { BaseActorDefinition } from \"./definition\";\nimport type {\n\tEventSchemaConfig,\n\tPrimitiveSchema,\n\tQueueSchemaConfig,\n} from \"./schema\";\nimport type {\n\tInferEventArgs,\n\tInferQueueCompleteMap,\n\tInferSchemaMap,\n} from \"./schema\";\n\nexport const DEFAULT_SLEEP_GRACE_PERIOD = 15_000;\n\nexport const ACTOR_CONTEXT_INTERNAL_SYMBOL = Symbol(\n\t\"rivetkit.actor_context_internal\",\n);\nexport const CONN_DRIVER_SYMBOL = Symbol(\"rivetkit.conn_driver\");\nexport const CONN_STATE_MANAGER_SYMBOL = Symbol(\"rivetkit.conn_state_manager\");\n\nexport interface ActorLogger {\n\tlevel: any;\n\tfatal: any;\n\ttrace: any;\n\tsilent: any;\n\tmsgPrefix: any;\n\tdebug: any;\n\tinfo: any;\n\twarn: any;\n\terror: any;\n\t[key: string]: any;\n}\n\ntype ActorKvValueType = \"text\" | \"arrayBuffer\" | \"binary\";\ntype ActorKvKeyType = \"text\" | \"binary\";\ntype ActorKvValueTypeMap = {\n\ttext: string;\n\tarrayBuffer: ArrayBuffer;\n\tbinary: Uint8Array;\n};\ntype ActorKvKeyTypeMap = {\n\ttext: string;\n\tbinary: Uint8Array;\n};\ntype ActorKvValueOptions<T extends ActorKvValueType = \"text\"> = {\n\ttype?: T;\n};\ntype ActorKvListOptions<\n\tT extends ActorKvValueType = \"text\",\n\tK extends ActorKvKeyType = \"text\",\n> = ActorKvValueOptions<T> & {\n\tkeyType?: K;\n\treverse?: boolean;\n\tlimit?: number;\n};\n\ntype ActorClientFor<T> = T extends Registry<any> ? Client<T> : T;\n\nexport interface ActorKv {\n\tget<T extends ActorKvValueType = \"text\">(\n\t\tkey: Uint8Array | string,\n\t\toptions?: ActorKvValueOptions<T>,\n\t): Promise<ActorKvValueTypeMap[T] | null>;\n\tput<T extends ActorKvValueType = \"text\">(\n\t\tkey: Uint8Array | string,\n\t\tvalue: Uint8Array | string | ArrayBuffer,\n\t\toptions?: ActorKvValueOptions<T>,\n\t): Promise<void>;\n\tdelete(key: Uint8Array | string): Promise<void>;\n\tbatchPut(entries: [Uint8Array, Uint8Array][]): Promise<void>;\n\tbatchGet(keys: Uint8Array[]): Promise<(Uint8Array | null)[]>;\n\tbatchDelete(keys: Uint8Array[]): Promise<void>;\n\tdeleteRange(start: Uint8Array, end: Uint8Array): Promise<void>;\n\tlistPrefix<\n\t\tT extends ActorKvValueType = \"text\",\n\t\tK extends ActorKvKeyType = \"text\",\n\t>(\n\t\tprefix: Uint8Array | string,\n\t\toptions?: ActorKvListOptions<T, K>,\n\t): Promise<Array<[ActorKvKeyTypeMap[K], ActorKvValueTypeMap[T]]>>;\n\tlistRange<\n\t\tT extends ActorKvValueType = \"text\",\n\t\tK extends ActorKvKeyType = \"text\",\n\t>(\n\t\tstart: Uint8Array | string,\n\t\tend: Uint8Array | string,\n\t\toptions?: ActorKvListOptions<T, K>,\n\t): Promise<Array<[ActorKvKeyTypeMap[K], ActorKvValueTypeMap[T]]>>;\n\tlist<T extends ActorKvValueType = \"text\", K extends ActorKvKeyType = \"text\">(\n\t\tprefix: Uint8Array | string,\n\t\toptions?: ActorKvListOptions<T, K>,\n\t): Promise<Array<[ActorKvKeyTypeMap[K], ActorKvValueTypeMap[T]]>>;\n\t[key: string]: any;\n}\n\nexport interface ActorSchedule {\n\tafter(duration: number, action: string, ...args: unknown[]): Promise<void>;\n\tat(timestamp: number, action: string, ...args: unknown[]): Promise<void>;\n\t[key: string]: any;\n}\n\nexport type QueueMessageOf<Name extends string, Body> = {\n\tid: number | bigint;\n\tname: Name;\n\tbody: Body;\n\tcreatedAt: number;\n\t[key: string]: unknown;\n};\n\nexport type QueueName<TQueues extends QueueSchemaConfig> = keyof TQueues & string;\nexport type QueueFilterName<TQueues extends QueueSchemaConfig> =\n\tkeyof TQueues extends never ? string : QueueName<TQueues>;\n\ntype QueueMessageForName<\n\tTQueues extends QueueSchemaConfig,\n\tTName extends QueueFilterName<TQueues>,\n> = keyof TQueues extends never\n\t? QueueMessageOf<string, unknown>\n\t: TName extends QueueName<TQueues>\n\t\t? QueueMessageOf<TName, InferSchemaMap<TQueues>[TName]>\n\t\t: never;\n\ntype QueueCompleteArgs<T> = undefined extends T\n\t? [response?: T]\n\t: [response: T];\n\ntype QueueCompleteArgsForName<\n\tTQueues extends QueueSchemaConfig,\n\tTName extends QueueFilterName<TQueues>,\n> = keyof TQueues extends never\n\t? [response?: unknown]\n\t: TName extends QueueName<TQueues>\n\t\t? [InferQueueCompleteMap<TQueues>[TName]] extends [never]\n\t\t\t? [response?: unknown]\n\t\t\t: QueueCompleteArgs<InferQueueCompleteMap<TQueues>[TName]>\n\t\t: [response?: unknown];\n\ntype QueueCompletableMessageForName<\n\tTQueues extends QueueSchemaConfig,\n\tTName extends QueueFilterName<TQueues>,\n> = QueueMessageForName<TQueues, TName> & {\n\tcomplete(...args: QueueCompleteArgsForName<TQueues, TName>): Promise<void>;\n};\n\ntype QueueCompletionResultForName<\n\tTQueues extends QueueSchemaConfig,\n\tTName extends QueueFilterName<TQueues>,\n> = keyof TQueues extends never\n\t? unknown | undefined\n\t: TName extends QueueName<TQueues>\n\t\t? InferQueueCompleteMap<TQueues>[TName] | undefined\n\t\t: unknown | undefined;\n\nexport type QueueResultMessageForName<\n\tTQueues extends QueueSchemaConfig,\n\tTName extends QueueFilterName<TQueues>,\n\tTCompletable extends boolean,\n> = TCompletable extends true\n\t? QueueCompletableMessageForName<TQueues, TName>\n\t: QueueMessageForName<TQueues, TName>;\n\nexport interface QueueNextOptions<\n\tTName extends string = string,\n\tTCompletable extends boolean = boolean,\n> {\n\tnames?: readonly TName[];\n\ttimeout?: number;\n\tsignal?: AbortSignal;\n\tcompletable?: TCompletable;\n}\n\nexport interface QueueNextBatchOptions<\n\tTName extends string = string,\n\tTCompletable extends boolean = boolean,\n> {\n\tnames?: readonly TName[];\n\tcount?: number;\n\ttimeout?: number;\n\tsignal?: AbortSignal;\n\tcompletable?: TCompletable;\n}\n\nexport interface QueueWaitOptions<TCompletable extends boolean = boolean> {\n\ttimeout?: number;\n\tsignal?: AbortSignal;\n\tcompletable?: TCompletable;\n}\n\nexport interface QueueEnqueueAndWaitOptions {\n\ttimeout?: number;\n\tsignal?: AbortSignal;\n}\n\nexport interface QueueTryNextOptions<\n\tTName extends string = string,\n\tTCompletable extends boolean = boolean,\n> {\n\tnames?: readonly TName[];\n\tcompletable?: TCompletable;\n}\n\nexport interface QueueTryNextBatchOptions<\n\tTName extends string = string,\n\tTCompletable extends boolean = boolean,\n> {\n\tnames?: readonly TName[];\n\tcount?: number;\n\tcompletable?: TCompletable;\n}\n\nexport interface QueueIterOptions<\n\tTName extends string = string,\n\tTCompletable extends boolean = boolean,\n> {\n\tnames?: readonly TName[];\n\tsignal?: AbortSignal;\n\tcompletable?: TCompletable;\n}\n\nexport interface ActorQueue<TQueues extends QueueSchemaConfig = Record<never, never>> {\n\tsend<TName extends QueueFilterName<TQueues>>(\n\t\tname: TName,\n\t\tbody: QueueMessageForName<TQueues, TName>[\"body\"],\n\t): Promise<any>;\n\tnext<\n\t\tconst TName extends QueueFilterName<TQueues>,\n\t\tconst TCompletable extends boolean = false,\n\t>(\n\t\topts?: QueueNextOptions<TName, TCompletable>,\n\t): Promise<any>;\n\tnextBatch<\n\t\tconst TName extends QueueFilterName<TQueues>,\n\t\tconst TCompletable extends boolean = false,\n\t>(\n\t\topts?: QueueNextBatchOptions<TName, TCompletable>,\n\t): Promise<any[]>;\n\twaitForNames<\n\t\tconst TName extends QueueFilterName<TQueues>,\n\t\tconst TCompletable extends boolean = false,\n\t>(\n\t\tnames: readonly TName[],\n\t\topts?: QueueWaitOptions<TCompletable>,\n\t): Promise<any>;\n\tenqueueAndWait<const TName extends QueueFilterName<TQueues>>(\n\t\tname: TName,\n\t\tbody: QueueMessageForName<TQueues, TName>[\"body\"],\n\t\topts?: QueueEnqueueAndWaitOptions,\n\t): Promise<QueueCompletionResultForName<TQueues, TName>>;\n\ttryNext<\n\t\tconst TName extends QueueFilterName<TQueues>,\n\t\tconst TCompletable extends boolean = false,\n\t>(\n\t\topts?: QueueTryNextOptions<TName, TCompletable>,\n\t): Promise<any>;\n\ttryNextBatch<\n\t\tconst TName extends QueueFilterName<TQueues>,\n\t\tconst TCompletable extends boolean = false,\n\t>(\n\t\topts?: QueueTryNextBatchOptions<TName, TCompletable>,\n\t): Promise<any[]>;\n\titer<\n\t\tconst TName extends QueueFilterName<TQueues>,\n\t\tconst TCompletable extends boolean = false,\n\t>(\n\t\topts?: QueueIterOptions<TName, TCompletable>,\n\t): AsyncIterable<any>;\n\t[key: string]: any;\n}\n\nexport interface Conn<\n\tTState = unknown,\n\tTConnParams = unknown,\n\tTConnState = unknown,\n\tTVars = unknown,\n\tTInput = unknown,\n\tTDatabase extends AnyDatabaseProvider = AnyDatabaseProvider,\n\tTEvents extends EventSchemaConfig = Record<never, never>,\n\tTQueues extends QueueSchemaConfig = Record<never, never>,\n> {\n\tid: string;\n\tparams: TConnParams;\n\tstate: TConnState;\n\tisHibernatable: boolean;\n\tsend(name: string, ...args: any[]): void;\n\tdisconnect(reason?: string): Promise<void>;\n\t[key: string]: any;\n}\n\nexport type AnyConn = Conn<any, any, any, any, any, any, any, any>;\n\nexport interface ActorContext<\n\tTState,\n\tTConnParams,\n\tTConnState,\n\tTVars,\n\tTInput,\n\tTDatabase extends AnyDatabaseProvider,\n\tTEvents extends EventSchemaConfig = Record<never, never>,\n\tTQueues extends QueueSchemaConfig = Record<never, never>,\n> {\n\t[ACTOR_CONTEXT_INTERNAL_SYMBOL]?: unknown;\n\tstate: TState;\n\tvars: TVars;\n\treadonly kv: ActorKv;\n\treadonly db: InferDatabaseClient<TDatabase>;\n\treadonly schedule: ActorSchedule;\n\treadonly queue: ActorQueue<TQueues>;\n\treadonly actorId: string;\n\treadonly name: string;\n\treadonly key: string[];\n\treadonly region: string;\n\treadonly conns: Map<string, Conn<TState, TConnParams, TConnState, TVars, TInput, TDatabase, TEvents, TQueues>>;\n\treadonly log: ActorLogger;\n\treadonly abortSignal: AbortSignal;\n\treadonly aborted: boolean;\n\treadonly request?: Request;\n\t/** @deprecated No-op. Always returns `false`. Use `keepAwake(promise)` or `waitUntil(promise)` instead. Will be removed in 2.2.0. */\n\treadonly preventSleep: boolean;\n\tbroadcast(name: string, ...args: any[]): void;\n\tsaveState(opts?: { immediate?: boolean; maxWait?: number }): Promise<void>;\n\tkeepAwake<T>(promise: Promise<T>): Promise<T>;\n\twaitUntil(promise: Promise<unknown>): void;\n\t/** @deprecated No-op. Use `keepAwake(promise)` to hold the actor awake for a specific promise. Will be removed in 2.2.0. */\n\tsetPreventSleep(preventSleep: boolean): void;\n\tsleep(): void;\n\tdestroy(): void;\n\tclient<T = any>(): ActorClientFor<T>;\n\t[key: string]: any;\n}\n\nexport type ActionContext<\n\tTState,\n\tTConnParams,\n\tTConnState,\n\tTVars,\n\tTInput,\n\tTDatabase extends AnyDatabaseProvider,\n\tTEvents extends EventSchemaConfig = Record<never, never>,\n\tTQueues extends QueueSchemaConfig = Record<never, never>,\n> = ActorContext<\n\tTState,\n\tTConnParams,\n\tTConnState,\n\tTVars,\n\tTInput,\n\tTDatabase,\n\tTEvents,\n\tTQueues\n> & {\n\tconn: Conn<\n\t\tTState,\n\t\tTConnParams,\n\t\tTConnState,\n\t\tTVars,\n\t\tTInput,\n\t\tTDatabase,\n\t\tTEvents,\n\t\tTQueues\n\t>;\n};\n\nexport type BeforeActionResponseContext<\n\tTState,\n\tTConnParams,\n\tTConnState,\n\tTVars,\n\tTInput,\n\tTDatabase extends AnyDatabaseProvider,\n\tTEvents extends EventSchemaConfig = Record<never, never>,\n\tTQueues extends QueueSchemaConfig = Record<never, never>,\n> = ActionContext<\n\tTState,\n\tTConnParams,\n\tTConnState,\n\tTVars,\n\tTInput,\n\tTDatabase,\n\tTEvents,\n\tTQueues\n>;\n\nexport type BeforeConnectContext<\n\tTState,\n\tTVars,\n\tTInput,\n\tTDatabase extends AnyDatabaseProvider,\n\tTEvents extends EventSchemaConfig = Record<never, never>,\n\tTQueues extends QueueSchemaConfig = Record<never, never>,\n> = ActorContext<\n\tTState,\n\tunknown,\n\tunknown,\n\tTVars,\n\tTInput,\n\tTDatabase,\n\tTEvents,\n\tTQueues\n>;\n\nexport type ConnectContext<\n\tTState,\n\tTConnParams,\n\tTConnState,\n\tTVars,\n\tTInput,\n\tTDatabase extends AnyDatabaseProvider,\n\tTEvents extends EventSchemaConfig = Record<never, never>,\n\tTQueues extends QueueSchemaConfig = Record<never, never>,\n> = ActionContext<\n\tTState,\n\tTConnParams,\n\tTConnState,\n\tTVars,\n\tTInput,\n\tTDatabase,\n\tTEvents,\n\tTQueues\n>;\n\nexport type CreateConnStateContext<\n\tTState,\n\tTVars,\n\tTInput,\n\tTDatabase extends AnyDatabaseProvider,\n\tTEvents extends EventSchemaConfig = Record<never, never>,\n\tTQueues extends QueueSchemaConfig = Record<never, never>,\n> = ActorContext<\n\tTState,\n\tunknown,\n\tunknown,\n\tTVars,\n\tTInput,\n\tTDatabase,\n\tTEvents,\n\tTQueues\n>;\n\nexport type CreateContext<\n\tTState,\n\tTInput,\n\tTDatabase extends AnyDatabaseProvider,\n\tTEvents extends EventSchemaConfig = Record<never, never>,\n\tTQueues extends QueueSchemaConfig = Record<never, never>,\n> = ActorContext<\n\tTState,\n\tunknown,\n\tunknown,\n\tunknown,\n\tTInput,\n\tTDatabase,\n\tTEvents,\n\tTQueues\n>;\n\nexport type CreateVarsContext<\n\tTState,\n\tTInput,\n\tTDatabase extends AnyDatabaseProvider,\n\tTEvents extends EventSchemaConfig = Record<never, never>,\n\tTQueues extends QueueSchemaConfig = Record<never, never>,\n> = CreateContext<TState, TInput, TDatabase, TEvents, TQueues>;\n\nexport type DestroyContext<\n\tTState,\n\tTConnParams,\n\tTConnState,\n\tTVars,\n\tTInput,\n\tTDatabase extends AnyDatabaseProvider,\n\tTEvents extends EventSchemaConfig = Record<never, never>,\n\tTQueues extends QueueSchemaConfig = Record<never, never>,\n> = ActorContext<\n\tTState,\n\tTConnParams,\n\tTConnState,\n\tTVars,\n\tTInput,\n\tTDatabase,\n\tTEvents,\n\tTQueues\n>;\n\nexport type DisconnectContext<\n\tTState,\n\tTConnParams,\n\tTConnState,\n\tTVars,\n\tTInput,\n\tTDatabase extends AnyDatabaseProvider,\n\tTEvents extends EventSchemaConfig = Record<never, never>,\n\tTQueues extends QueueSchemaConfig = Record<never, never>,\n> = ActionContext<\n\tTState,\n\tTConnParams,\n\tTConnState,\n\tTVars,\n\tTInput,\n\tTDatabase,\n\tTEvents,\n\tTQueues\n>;\n\nexport type RequestContext<\n\tTState,\n\tTConnParams,\n\tTConnState,\n\tTVars,\n\tTInput,\n\tTDatabase extends AnyDatabaseProvider,\n\tTEvents extends EventSchemaConfig = Record<never, never>,\n\tTQueues extends QueueSchemaConfig = Record<never, never>,\n> = ActionContext<\n\tTState,\n\tTConnParams,\n\tTConnState,\n\tTVars,\n\tTInput,\n\tTDatabase,\n\tTEvents,\n\tTQueues\n>;\n\nexport type RunContext<\n\tTState,\n\tTConnParams,\n\tTConnState,\n\tTVars,\n\tTInput,\n\tTDatabase extends AnyDatabaseProvider,\n\tTEvents extends EventSchemaConfig = Record<never, never>,\n\tTQueues extends QueueSchemaConfig = Record<never, never>,\n> = ActorContext<\n\tTState,\n\tTConnParams,\n\tTConnState,\n\tTVars,\n\tTInput,\n\tTDatabase,\n\tTEvents,\n\tTQueues\n>;\n\nexport type SleepContext<\n\tTState,\n\tTConnParams,\n\tTConnState,\n\tTVars,\n\tTInput,\n\tTDatabase extends AnyDatabaseProvider,\n\tTEvents extends EventSchemaConfig = Record<never, never>,\n\tTQueues extends QueueSchemaConfig = Record<never, never>,\n> = RunContext<\n\tTState,\n\tTConnParams,\n\tTConnState,\n\tTVars,\n\tTInput,\n\tTDatabase,\n\tTEvents,\n\tTQueues\n>;\n\nexport type StateChangeContext<\n\tTState,\n\tTConnParams,\n\tTConnState,\n\tTVars,\n\tTInput,\n\tTDatabase extends AnyDatabaseProvider,\n\tTEvents extends EventSchemaConfig = Record<never, never>,\n\tTQueues extends QueueSchemaConfig = Record<never, never>,\n> = RunContext<\n\tTState,\n\tTConnParams,\n\tTConnState,\n\tTVars,\n\tTInput,\n\tTDatabase,\n\tTEvents,\n\tTQueues\n>;\n\nexport type WakeContext<\n\tTState,\n\tTConnParams,\n\tTConnState,\n\tTVars,\n\tTInput,\n\tTDatabase extends AnyDatabaseProvider,\n\tTEvents extends EventSchemaConfig = Record<never, never>,\n\tTQueues extends QueueSchemaConfig = Record<never, never>,\n> = RunContext<\n\tTState,\n\tTConnParams,\n\tTConnState,\n\tTVars,\n\tTInput,\n\tTDatabase,\n\tTEvents,\n\tTQueues\n>;\n\nexport type MigrateContext<\n\tTState,\n\tTConnParams,\n\tTConnState,\n\tTVars,\n\tTInput,\n\tTDatabase extends AnyDatabaseProvider,\n\tTEvents extends EventSchemaConfig = Record<never, never>,\n\tTQueues extends QueueSchemaConfig = Record<never, never>,\n> = WakeContext<\n\tTState,\n\tTConnParams,\n\tTConnState,\n\tTVars,\n\tTInput,\n\tTDatabase,\n\tTEvents,\n\tTQueues\n>;\n\nexport type WebSocketContext<\n\tTState,\n\tTConnParams,\n\tTConnState,\n\tTVars,\n\tTInput,\n\tTDatabase extends AnyDatabaseProvider,\n\tTEvents extends EventSchemaConfig = Record<never, never>,\n\tTQueues extends QueueSchemaConfig = Record<never, never>,\n> = ActionContext<\n\tTState,\n\tTConnParams,\n\tTConnState,\n\tTVars,\n\tTInput,\n\tTDatabase,\n\tTEvents,\n\tTQueues\n>;\n\nexport type ActorContextOf<AD extends BaseActorDefinition<any, any, any, any, any, any, any, any, any>> =\n\tAD extends BaseActorDefinition<\n\t\tinfer TState,\n\t\tinfer TConnParams,\n\t\tinfer TConnState,\n\t\tinfer TVars,\n\t\tinfer TInput,\n\t\tinfer TDatabase,\n\t\tinfer TEvents,\n\t\tinfer TQueues,\n\t\tany\n\t>\n\t\t? ActorContext<\n\t\t\t\tTState,\n\t\t\t\tTConnParams,\n\t\t\t\tTConnState,\n\t\t\t\tTVars,\n\t\t\t\tTInput,\n\t\t\t\tTDatabase,\n\t\t\t\tTEvents,\n\t\t\t\tTQueues\n\t\t\t>\n\t\t: never;\n\nexport interface ActorTypes<\n\tTState,\n\tTConnParams,\n\tTConnState,\n\tTVars,\n\tTInput,\n\tTDatabase extends AnyDatabaseProvider,\n> {\n\tstate?: TState;\n\tconnParams?: TConnParams;\n\tconnState?: TConnState;\n\tvars?: TVars;\n\tinput?: TInput;\n\tdatabase?: TDatabase;\n}\n\n// Helper for validating function types - accepts generic for specific function signatures\nconst zFunction = <\n\tT extends (...args: any[]) => any = (...args: unknown[]) => unknown,\n>() => z.custom<T>((val) => typeof val === \"function\");\n\nexport type InspectorUnsubscribe = () => void;\n\nexport interface WorkflowInspectorConfig<THistory = unknown> {\n\tgetHistory: () => THistory | null;\n\tonHistoryUpdated?: (\n\t\tlistener: (history: THistory) => void,\n\t) => InspectorUnsubscribe;\n\treplayFromStep?: (entryId?: string) => Promise<THistory | null>;\n}\n\nexport interface RunInspectorConfig<THistory = unknown> {\n\tworkflow?: WorkflowInspectorConfig<THistory>;\n}\n\nconst WorkflowInspectorConfigSchema = z.object({\n\tgetHistory: zFunction<WorkflowInspectorConfig<unknown>[\"getHistory\"]>(),\n\tonHistoryUpdated:\n\t\tzFunction<\n\t\t\tNonNullable<WorkflowInspectorConfig<unknown>[\"onHistoryUpdated\"]>\n\t\t>().optional(),\n\treplayFromStep:\n\t\tzFunction<\n\t\t\tNonNullable<WorkflowInspectorConfig<unknown>[\"replayFromStep\"]>\n\t\t>().optional(),\n});\n\nconst RunInspectorConfigSchema = z\n\t.object({\n\t\tworkflow: WorkflowInspectorConfigSchema.optional(),\n\t})\n\t.optional();\n\n// Schema for run handler with metadata\nexport const RunConfigSchema = z.object({\n\t/** Display name for the actor in the Inspector UI. */\n\tname: z.string().optional(),\n\t/** Icon for the actor in the Inspector UI. Can be an emoji or FontAwesome icon name. */\n\ticon: z.string().optional(),\n\t/** The run handler function. */\n\trun: zFunction(),\n\t/** Inspector integration for long-running run handlers. */\n\tinspector: RunInspectorConfigSchema.optional(),\n});\ntype RunConfigRuntime = z.infer<typeof RunConfigSchema>;\nexport type RunConfig<\n\tTState = unknown,\n\tTConnParams = unknown,\n\tTConnState = unknown,\n\tTVars = unknown,\n\tTInput = unknown,\n\tTDatabase extends AnyDatabaseProvider = AnyDatabaseProvider,\n\tTEvents extends EventSchemaConfig = Record<never, never>,\n\tTQueues extends QueueSchemaConfig = Record<never, never>,\n> = Omit<RunConfigRuntime, \"run\"> & {\n\trun: (\n\t\tc: RunContext<\n\t\t\tTState,\n\t\t\tTConnParams,\n\t\t\tTConnState,\n\t\t\tTVars,\n\t\t\tTInput,\n\t\t\tTDatabase,\n\t\t\tTEvents,\n\t\t\tTQueues\n\t\t>,\n\t) => void | Promise<void>;\n};\n\ntype AnyRunConfig = RunConfig<\n\tany,\n\tany,\n\tany,\n\tany,\n\tany,\n\tAnyDatabaseProvider,\n\tany,\n\tany\n>;\n\nexport const RUN_FUNCTION_CONFIG_SYMBOL = Symbol.for(\n\t\"rivetkit.run_function_config\",\n);\n\ninterface RunFunctionConfig {\n\tname?: string;\n\ticon?: string;\n\tinspector?: RunInspectorConfig;\n\tinspectorFactory?: (actor: unknown) => RunInspectorConfig | undefined;\n}\n\ntype RunFunctionWithConfig = ((...args: any[]) => any) & {\n\t[RUN_FUNCTION_CONFIG_SYMBOL]?: RunFunctionConfig;\n};\n\n// Run can be either a function or an object with name/icon/run\nconst zRunHandler = z.union([zFunction(), RunConfigSchema]).optional();\n\n/** Extract the run function from either a function or RunConfig object. */\nexport function getRunFunction(\n\trun: ((...args: any[]) => any) | AnyRunConfig | undefined,\n): ((...args: any[]) => any) | undefined {\n\tif (!run) return undefined;\n\tif (typeof run === \"function\") return run;\n\treturn run.run;\n}\n\n/** Extract run metadata (name/icon) from RunConfig if provided. */\nexport function getRunMetadata(\n\trun: ((...args: any[]) => any) | AnyRunConfig | undefined,\n): { name?: string; icon?: string } {\n\tif (!run) return {};\n\tif (typeof run === \"function\") {\n\t\tconst config = (run as RunFunctionWithConfig)[\n\t\t\tRUN_FUNCTION_CONFIG_SYMBOL\n\t\t];\n\t\tif (!config) return {};\n\t\treturn { name: config.name, icon: config.icon };\n\t}\n\treturn { name: run.name, icon: run.icon };\n}\n\n/** Extract run inspector configuration if provided. */\nexport function getRunInspectorConfig(\n\trun: ((...args: any[]) => any) | AnyRunConfig | undefined,\n\tactor?: unknown,\n): RunInspectorConfig | undefined {\n\tif (!run) return undefined;\n\tif (typeof run === \"function\") {\n\t\tconst config = (run as RunFunctionWithConfig)[\n\t\t\tRUN_FUNCTION_CONFIG_SYMBOL\n\t\t];\n\t\treturn config?.inspectorFactory\n\t\t\t? config.inspectorFactory(actor)\n\t\t\t: config?.inspector;\n\t}\n\treturn run.inspector;\n}\n\n// This schema is used to validate the input at runtime. The generic types are defined below in `ActorConfig`.\n//\n// We don't use Zod generics with `z.custom` because:\n// (a) there seems to be a weird bug in either Zod, tsup, or TSC that causese external packages to have different types from `z.infer` than from within the same package and\n// (b) it makes the type definitions incredibly difficult to read as opposed to vanilla TypeScript.\nconst GlobalActorOptionsBaseSchema = z\n\t.object({\n\t\t/** Display name for the actor in the Inspector UI. */\n\t\tname: z.string().optional(),\n\t\t/** Icon for the actor in the Inspector UI. Can be an emoji or FontAwesome icon name. */\n\t\ticon: z.string().optional(),\n\t\t/**\n\t\t * Can hibernate WebSockets for onWebSocket.\n\t\t *\n\t\t * WebSockets using actions/events are hibernatable by default.\n\t\t *\n\t\t * @experimental\n\t\t **/\n\t\tcanHibernateWebSocket: z\n\t\t\t.union([z.boolean(), zFunction<(request: Request) => boolean>()])\n\t\t\t.default(false),\n\t})\n\t.strict();\n\nexport const GlobalActorOptionsSchema = GlobalActorOptionsBaseSchema.prefault(\n\t() => ({}),\n);\n\nexport type GlobalActorOptions = z.infer<typeof GlobalActorOptionsSchema>;\nexport type GlobalActorOptionsInput = z.input<typeof GlobalActorOptionsSchema>;\n\nconst InstanceActorOptionsBaseSchema = z\n\t.object({\n\t\tcreateVarsTimeout: z.number().positive().default(5000),\n\t\tcreateConnStateTimeout: z.number().positive().default(5000),\n\t\tonBeforeConnectTimeout: z.number().positive().default(5000),\n\t\tonConnectTimeout: z.number().positive().default(5000),\n\t\tonMigrateTimeout: z.number().positive().default(30_000),\n\t\tsleepGracePeriod: z\n\t\t\t.number()\n\t\t\t.positive()\n\t\t\t.default(DEFAULT_SLEEP_GRACE_PERIOD),\n\t\t/** @deprecated `onDestroyTimeout` is folded into `sleepGracePeriod`, which now bounds the entire graceful shutdown window for both sleep and destroy. Will be removed in 2.2.0. */\n\t\tonDestroyTimeout: z.number().positive().optional(),\n\t\t/** @deprecated `waitUntilTimeout` is folded into `sleepGracePeriod`, which now bounds the entire graceful shutdown window for both sleep and destroy. Will be removed in 2.2.0. */\n\t\twaitUntilTimeout: z.number().positive().optional(),\n\t\tstateSaveInterval: z.number().positive().default(1_000),\n\t\tactionTimeout: z.number().positive().default(60_000),\n\t\tconnectionLivenessTimeout: z.number().positive().default(2500),\n\t\tconnectionLivenessInterval: z.number().positive().default(5000),\n\t\t/** @deprecated Use `c.keepAwake(promise)` to scope keep-awake to a specific operation, or keep `noSleep` for actors that must stay awake indefinitely. Will be removed in 2.2.0. */\n\t\tnoSleep: z.boolean().default(false),\n\t\tsleepTimeout: z.number().positive().default(30_000),\n\t\tmaxQueueSize: z.number().positive().default(1000),\n\t\tmaxQueueMessageSize: z\n\t\t\t.number()\n\t\t\t.positive()\n\t\t\t.default(64 * 1024),\n\t\t/** Override RivetKit's workflow preload budget for this actor. Set to 0 to disable workflow preloading. */\n\t\tpreloadMaxWorkflowBytes: z.number().nonnegative().optional(),\n\t\t/** Override RivetKit's connections preload budget for this actor. Set to 0 to disable connections preloading. */\n\t\tpreloadMaxConnectionsBytes: z.number().nonnegative().optional(),\n\t})\n\t.strict();\n\nexport const InstanceActorOptionsSchema =\n\tInstanceActorOptionsBaseSchema.prefault(() => ({}));\n\nexport type InstanceActorOptions = z.infer<typeof InstanceActorOptionsSchema>;\nexport type InstanceActorOptionsInput = z.input<\n\ttypeof InstanceActorOptionsSchema\n>;\n\nexport const ActorOptionsSchema = GlobalActorOptionsBaseSchema.extend(\n\tInstanceActorOptionsBaseSchema.shape,\n)\n\t.strict()\n\t.prefault(() => ({}));\n\nexport type ActorOptions = z.infer<typeof ActorOptionsSchema>;\nexport type ActorOptionsInput = z.input<typeof ActorOptionsSchema>;\n\nexport const ActorConfigSchema = z\n\t.object({\n\t\tonCreate: zFunction().optional(),\n\t\tonDestroy: zFunction().optional(),\n\t\tonMigrate: zFunction().optional(),\n\t\tonWake: zFunction().optional(),\n\t\tonSleep: zFunction().optional(),\n\t\trun: zRunHandler,\n\t\tonStateChange: zFunction().optional(),\n\t\tonBeforeConnect: zFunction().optional(),\n\t\tonConnect: zFunction().optional(),\n\t\tonDisconnect: zFunction().optional(),\n\t\tonBeforeActionResponse: zFunction().optional(),\n\t\tonRequest: zFunction().optional(),\n\t\tonWebSocket: zFunction().optional(),\n\t\tactions: z.record(z.string(), zFunction()).default(() => ({})),\n\t\tactionInputSchemas: z.record(z.string(), z.any()).optional(),\n\t\tconnParamsSchema: z.any().optional(),\n\t\tevents: z.record(z.string(), z.any()).optional(),\n\t\tqueues: z.record(z.string(), z.any()).optional(),\n\t\tstate: z.any().optional(),\n\t\tcreateState: zFunction().optional(),\n\t\tconnState: z.any().optional(),\n\t\tcreateConnState: zFunction().optional(),\n\t\tvars: z.any().optional(),\n\t\tdb: z.any().optional(),\n\t\tcreateVars: zFunction().optional(),\n\t\toptions: ActorOptionsSchema,\n\t})\n\t.strict()\n\t.refine(\n\t\t(data) => !(data.state !== undefined && data.createState !== undefined),\n\t\t{\n\t\t\tmessage: \"Cannot define both 'state' and 'createState'\",\n\t\t\tpath: [\"state\"],\n\t\t},\n\t)\n\t.refine(\n\t\t(data) =>\n\t\t\t!(\n\t\t\t\tdata.connState !== undefined &&\n\t\t\t\tdata.createConnState !== undefined\n\t\t\t),\n\t\t{\n\t\t\tmessage: \"Cannot define both 'connState' and 'createConnState'\",\n\t\t\tpath: [\"connState\"],\n\t\t},\n\t)\n\t.refine(\n\t\t(data) => !(data.vars !== undefined && data.createVars !== undefined),\n\t\t{\n\t\t\tmessage: \"Cannot define both 'vars' and 'createVars'\",\n\t\t\tpath: [\"vars\"],\n\t\t},\n\t);\n\n// Creates state config\n//\n// This must have only one or the other or else TState will not be able to be inferred\n//\n// Data returned from this handler will be available on `c.state`.\ntype CreateState<\n\tTState,\n\tTConnParams,\n\tTConnState,\n\tTVars,\n\tTInput,\n\tTDatabase extends AnyDatabaseProvider,\n\tTEvents extends EventSchemaConfig,\n\tTQueues extends QueueSchemaConfig,\n> =\n\t| { state: TState }\n\t| {\n\t\t\tcreateState: (\n\t\t\t\tc: CreateContext<TState, TInput, TDatabase, TEvents, TQueues>,\n\t\t\t\tinput: TInput,\n\t\t\t) => TState | Promise<TState>;\n\t }\n\t| Record<never, never>;\n\n// Creates connection state config\n//\n// This must have only one or the other or else TState will not be able to be inferred\n//\n// Data returned from this handler will be available on `c.conn.state`.\n// The pending connection is not visible in `c.conns` until this succeeds.\ntype CreateConnState<\n\tTState,\n\tTConnParams,\n\tTConnState,\n\tTVars,\n\tTInput,\n\tTDatabase extends AnyDatabaseProvider,\n\tTEvents extends EventSchemaConfig,\n\tTQueues extends QueueSchemaConfig,\n> =\n\t| { connState: TConnState }\n\t| {\n\t\t\tcreateConnState: (\n\t\t\t\tc: CreateConnStateContext<\n\t\t\t\t\tTState,\n\t\t\t\t\tTVars,\n\t\t\t\t\tTInput,\n\t\t\t\t\tTDatabase,\n\t\t\t\t\tTEvents,\n\t\t\t\t\tTQueues\n\t\t\t\t>,\n\t\t\t\tparams: TConnParams,\n\t\t\t) => TConnState | Promise<TConnState>;\n\t }\n\t| Record<never, never>;\n\n// Creates vars config\n//\n// This must have only one or the other or else TState will not be able to be inferred\n/**\n * @experimental\n */\ntype CreateVars<\n\tTState,\n\tTConnParams,\n\tTConnState,\n\tTVars,\n\tTInput,\n\tTDatabase extends AnyDatabaseProvider,\n\tTEvents extends EventSchemaConfig,\n\tTQueues extends QueueSchemaConfig,\n> =\n\t| {\n\t\t\t/**\n\t\t\t * @experimental\n\t\t\t */\n\t\t\tvars: TVars;\n\t }\n\t| {\n\t\t\t/**\n\t\t\t * @experimental\n\t\t\t */\n\t\t\tcreateVars: (\n\t\t\t\tc: CreateVarsContext<\n\t\t\t\t\tTState,\n\t\t\t\t\tTInput,\n\t\t\t\t\tTDatabase,\n\t\t\t\t\tTEvents,\n\t\t\t\t\tTQueues\n\t\t\t\t>,\n\t\t\t\tdriverCtx: any,\n\t\t\t) => TVars | Promise<TVars>;\n\t }\n\t| Record<never, never>;\n\nexport interface Actions<\n\tTState,\n\tTConnParams,\n\tTConnState,\n\tTVars,\n\tTInput,\n\tTDatabase extends AnyDatabaseProvider,\n\tTEvents extends EventSchemaConfig = Record<never, never>,\n\tTQueues extends QueueSchemaConfig = Record<never, never>,\n> {\n\t[Action: string]: (\n\t\tc: ActionContext<\n\t\t\tTState,\n\t\t\tTConnParams,\n\t\t\tTConnState,\n\t\t\tTVars,\n\t\t\tTInput,\n\t\t\tTDatabase,\n\t\t\tTEvents,\n\t\t\tTQueues\n\t\t>,\n\t\t...args: any[]\n\t) => any;\n}\n\n//export type ActorConfig<TState, TConnParams, TConnState, TVars, TInput, TAuthData> = BaseActorConfig<TState, TConnParams, TConnState, TVars, TInput, TAuthData> &\n//\tActorConfigLifecycle<TState, TConnParams, TConnState, TVars, TInput, TAuthData> &\n//\tCreateState<TState, TConnParams, TConnState, TVars, TInput, TAuthData> &\n//\tCreateConnState<TState, TConnParams, TConnState, TVars, TInput, TAuthData>;\n\n/**\n * @experimental\n */\nexport type AuthIntent = \"get\" | \"create\" | \"connect\" | \"action\" | \"message\";\n\ninterface BaseActorConfig<\n\tTState,\n\tTConnParams,\n\tTConnState,\n\tTVars,\n\tTInput,\n\tTDatabase extends AnyDatabaseProvider,\n\tTEvents extends EventSchemaConfig,\n\tTQueues extends QueueSchemaConfig,\n\tTActions extends Actions<\n\t\tTState,\n\t\tTConnParams,\n\t\tTConnState,\n\t\tTVars,\n\t\tTInput,\n\t\tTDatabase,\n\t\tTEvents,\n\t\tTQueues\n\t>,\n> {\n\t/**\n\t * Called when the actor is first initialized.\n\t *\n\t * Use this hook to initialize your actor's state.\n\t * This is called before any other lifecycle hooks.\n\t */\n\tonCreate?: (\n\t\tc: CreateContext<TState, TInput, TDatabase, TEvents, TQueues>,\n\t\tinput: TInput,\n\t) => void | Promise<void>;\n\n\t/**\n\t * Called when the actor is destroyed.\n\t */\n\tonDestroy?: (\n\t\tc: DestroyContext<\n\t\t\tTState,\n\t\t\tTConnParams,\n\t\t\tTConnState,\n\t\t\tTVars,\n\t\t\tTInput,\n\t\t\tTDatabase,\n\t\t\tTEvents,\n\t\t\tTQueues\n\t\t>,\n\t) => void | Promise<void>;\n\n\t/**\n\t * Called on every actor start after persisted state loads and before onWake.\n\t *\n\t * Use this hook for repeatable schema migrations or other startup work that\n\t * must run on both first boot and wake.\n\t */\n\tonMigrate?: (\n\t\tc: MigrateContext<\n\t\t\tTState,\n\t\t\tTConnParams,\n\t\t\tTConnState,\n\t\t\tTVars,\n\t\t\tTInput,\n\t\t\tTDatabase,\n\t\t\tTEvents,\n\t\t\tTQueues\n\t\t>,\n\t\tisNew: boolean,\n\t) => void | Promise<void>;\n\n\t/**\n\t * Called when the actor is started and ready to receive connections and action.\n\t *\n\t * Use this hook to initialize resources needed for the actor's operation\n\t * (timers, external connections, etc.)\n\t *\n\t * @returns Void or a Promise that resolves when startup is complete\n\t */\n\tonWake?: (\n\t\tc: WakeContext<\n\t\t\tTState,\n\t\t\tTConnParams,\n\t\t\tTConnState,\n\t\t\tTVars,\n\t\t\tTInput,\n\t\t\tTDatabase,\n\t\t\tTEvents,\n\t\t\tTQueues\n\t\t>,\n\t) => void | Promise<void>;\n\n\t/**\n\t * Called when the actor is stopping or sleeping.\n\t *\n\t * Use this hook to clean up resources, save state, or perform\n\t * any shutdown operations before the actor sleeps or stops.\n\t *\n\t * Not supported on all platforms.\n\t *\n\t * @returns Void or a Promise that resolves when shutdown is complete\n\t */\n\tonSleep?: (\n\t\tc: SleepContext<\n\t\t\tTState,\n\t\t\tTConnParams,\n\t\t\tTConnState,\n\t\t\tTVars,\n\t\t\tTInput,\n\t\t\tTDatabase,\n\t\t\tTEvents,\n\t\t\tTQueues\n\t\t>,\n\t) => void | Promise<void>;\n\n\t/**\n\t * Called after the actor starts up. Does not block actor startup.\n\t *\n\t * Use this for background tasks like:\n\t * - Reading from queues in a loop\n\t * - Tick loops for periodic work\n\t * - Custom workflow logic\n\t *\n\t * **Important:** The actor may go to sleep at any time during the `run`\n\t * handler. Wrap work that must keep the actor awake with\n\t * `c.keepAwake(promise)` to block idle sleep and shutdown finalize until\n\t * the promise settles, or use `c.waitUntil(promise)` to let the graceful\n\t * shutdown window (`sleepGracePeriod`) cover deferred work.\n\t *\n\t * The handler receives an abort signal via `c.abortSignal` and a\n\t * `c.aborted` alias. Use these to gracefully exit when shutdown starts.\n\t *\n\t * If this handler exits, the actor will follow the normal idle sleep timeout\n\t * once it becomes idle.\n\t * If this handler throws, the actor logs the error and then sleeps once it\n\t * becomes idle.\n\t * Call `c.destroy()` explicitly if a run handler should destroy the actor.\n\t *\n\t * Can be either a function or a RunConfig object with optional name/icon metadata.\n\t *\n\t * @returns Void or a Promise.\n\t */\n\trun?:\n\t\t| ((\n\t\t\t\tc: RunContext<\n\t\t\t\t\tTState,\n\t\t\t\t\tTConnParams,\n\t\t\t\t\tTConnState,\n\t\t\t\t\tTVars,\n\t\t\t\t\tTInput,\n\t\t\t\t\tTDatabase,\n\t\t\t\t\tTEvents,\n\t\t\t\t\tTQueues\n\t\t\t\t>,\n\t\t ) => void | Promise<void>)\n\t\t| RunConfig<\n\t\t\t\tTState,\n\t\t\t\tTConnParams,\n\t\t\t\tTConnState,\n\t\t\t\tTVars,\n\t\t\t\tTInput,\n\t\t\t\tTDatabase,\n\t\t\t\tTEvents,\n\t\t\t\tTQueues\n\t\t >;\n\n\t/**\n\t * Called when the actor's state changes.\n\t *\n\t * Use this hook to react to state changes, such as updating\n\t * external systems or triggering events.\n\t *\n\t * State changes made within this hook will NOT trigger\n\t * another onStateChange call, preventing infinite recursion.\n\t *\n\t * @param newState The updated state\n\t */\n\tonStateChange?: (\n\t\tc: StateChangeContext<\n\t\t\tTState,\n\t\t\tTConnParams,\n\t\t\tTConnState,\n\t\t\tTVars,\n\t\t\tTInput,\n\t\t\tTDatabase,\n\t\t\tTEvents,\n\t\t\tTQueues\n\t\t>,\n\t\tnewState: TState,\n\t) => void;\n\n\t/**\n\t * Called before a client connects to the actor.\n\t *\n\t * Use this hook to determine if a connection should be accepted\n\t * and to validate client-provided parameters. The pending connection\n\t * is not visible in `c.conns` while this hook runs.\n\t *\n\t * @param opts Connection parameters including client-provided data\n\t * @returns Void or a Promise.\n\t * @throws Throw an error to reject the connection\n\t */\n\tonBeforeConnect?: (\n\t\tc: BeforeConnectContext<\n\t\t\tTState,\n\t\t\tTVars,\n\t\t\tTInput,\n\t\t\tTDatabase,\n\t\t\tTEvents,\n\t\t\tTQueues\n\t\t>,\n\t\tparams: TConnParams,\n\t) => void | Promise<void>;\n\n\t/**\n\t * Called when a client successfully connects to the actor.\n\t *\n\t * Use this hook to perform actions when a connection is established,\n\t * such as sending initial data or updating the actor's state. The\n\t * connection is visible in `c.conns` before this hook runs.\n\t *\n\t * @param conn The connection object\n\t * @returns Void or a Promise that resolves when connection handling is complete\n\t */\n\tonConnect?: (\n\t\tc: ConnectContext<\n\t\t\tTState,\n\t\t\tTConnParams,\n\t\t\tTConnState,\n\t\t\tTVars,\n\t\t\tTInput,\n\t\t\tTDatabase,\n\t\t\tTEvents,\n\t\t\tTQueues\n\t\t>,\n\t\tconn: Conn<\n\t\t\tTState,\n\t\t\tTConnParams,\n\t\t\tTConnState,\n\t\t\tTVars,\n\t\t\tTInput,\n\t\t\tTDatabase,\n\t\t\tTEvents,\n\t\t\tTQueues\n\t\t>,\n\t) => void | Promise<void>;\n\n\t/**\n\t * Called when a client disconnects from the actor.\n\t *\n\t * Use this hook to clean up resources associated with the connection\n\t * or update the actor's state.\n\t *\n\t * @param conn The connection that is being closed\n\t * @returns Void or a Promise that resolves when disconnect handling is complete\n\t */\n\tonDisconnect?: (\n\t\tc: DisconnectContext<\n\t\t\tTState,\n\t\t\tTConnParams,\n\t\t\tTConnState,\n\t\t\tTVars,\n\t\t\tTInput,\n\t\t\tTDatabase,\n\t\t\tTEvents,\n\t\t\tTQueues\n\t\t>,\n\t\tconn: Conn<\n\t\t\tTState,\n\t\t\tTConnParams,\n\t\t\tTConnState,\n\t\t\tTVars,\n\t\t\tTInput,\n\t\t\tTDatabase,\n\t\t\tTEvents,\n\t\t\tTQueues\n\t\t>,\n\t) => void | Promise<void>;\n\n\t/**\n\t * Called before sending an action response to the client.\n\t *\n\t * Use this hook to modify or transform the output of an action before it's sent\n\t * to the client. This is useful for formatting responses, adding metadata,\n\t * or applying transformations to the output.\n\t *\n\t * @param name The name of the action that was called\n\t * @param args The arguments that were passed to the action\n\t * @param output The output that will be sent to the client\n\t * @returns The modified output to send to the client\n\t */\n\tonBeforeActionResponse?: <Out>(\n\t\tc: BeforeActionResponseContext<\n\t\t\tTState,\n\t\t\tTConnParams,\n\t\t\tTConnState,\n\t\t\tTVars,\n\t\t\tTInput,\n\t\t\tTDatabase,\n\t\t\tTEvents,\n\t\t\tTQueues\n\t\t>,\n\t\tname: string,\n\t\targs: unknown[],\n\t\toutput: Out,\n\t) => Out | Promise<Out>;\n\n\t/**\n\t * Called when a raw HTTP request is made to the actor.\n\t *\n\t * This handler receives raw HTTP requests made to `/actors/{actorName}/http/*` endpoints.\n\t * Use this hook to handle custom HTTP patterns, REST APIs, or other HTTP-based protocols.\n\t *\n\t * @param c The request context with access to the connection\n\t * @param request The raw HTTP request object\n\t * @param opts Additional options\n\t * @returns A Response object to send back, or void to continue with default routing\n\t */\n\tonRequest?: (\n\t\tc: RequestContext<\n\t\t\tTState,\n\t\t\tTConnParams,\n\t\t\tTConnState,\n\t\t\tTVars,\n\t\t\tTInput,\n\t\t\tTDatabase,\n\t\t\tTEvents,\n\t\t\tTQueues\n\t\t>,\n\t\trequest: Request,\n\t) => Response | Promise<Response>;\n\n\t/**\n\t * Called when a raw WebSocket connection is established to the actor.\n\t *\n\t * This handler receives WebSocket connections made to `/actors/{actorName}/websocket/*` endpoints.\n\t * Use this hook to handle custom WebSocket protocols, binary streams, or other WebSocket-based communication.\n\t *\n\t * @param c The WebSocket context with access to the connection\n\t * @param websocket The actor-facing raw WebSocket connection\n\t * @param opts Additional options including the original HTTP upgrade request\n\t */\n\tonWebSocket?: (\n\t\tc: WebSocketContext<\n\t\t\tTState,\n\t\t\tTConnParams,\n\t\t\tTConnState,\n\t\t\tTVars,\n\t\t\tTInput,\n\t\t\tTDatabase,\n\t\t\tTEvents,\n\t\t\tTQueues\n\t\t>,\n\t\twebsocket: UniversalWebSocket,\n\t) => void | Promise<void>;\n\n\tactions?: TActions;\n\n\t/**\n\t * Optional schema map for validating action argument tuples in native runtimes.\n\t */\n\tactionInputSchemas?: Record<string, PrimitiveSchema>;\n\n\t/**\n\t * Optional schema for validating connection params in native runtimes.\n\t */\n\tconnParamsSchema?: PrimitiveSchema;\n\n\t/**\n\t * Schema map for events broadcasted by this actor.\n\t */\n\tevents?: TEvents;\n\n\t/**\n\t * Schema map for queue payloads sent by this actor.\n\t */\n\tqueues?: TQueues;\n}\n\ntype ActorDatabaseConfig<TDatabase extends AnyDatabaseProvider> =\n\t| {\n\t\t\t/**\n\t\t\t * @experimental\n\t\t\t */\n\t\t\tdb: TDatabase;\n\t }\n\t| Record<never, never>;\n\n// 1. Infer schema\n// 2. Omit keys that we'll manually define (because of generics)\n// 3. Define our own types that have generic constraints\nexport type ActorConfig<\n\tTState,\n\tTConnParams,\n\tTConnState,\n\tTVars,\n\tTInput,\n\tTDatabase extends AnyDatabaseProvider,\n\tTEvents extends EventSchemaConfig = Record<never, never>,\n\tTQueues extends QueueSchemaConfig = Record<never, never>,\n> = Omit<\n\tz.infer<typeof ActorConfigSchema>,\n\t| \"actions\"\n\t| \"events\"\n\t| \"queues\"\n\t| \"onCreate\"\n\t| \"onDestroy\"\n\t| \"onMigrate\"\n\t| \"onWake\"\n\t| \"onSleep\"\n\t| \"run\"\n\t| \"onStateChange\"\n\t| \"onBeforeConnect\"\n\t| \"onConnect\"\n\t| \"onDisconnect\"\n\t| \"onBeforeActionResponse\"\n\t| \"onRequest\"\n\t| \"onWebSocket\"\n\t| \"state\"\n\t| \"createState\"\n\t| \"connState\"\n\t| \"createConnState\"\n\t| \"vars\"\n\t| \"createVars\"\n\t| \"db\"\n> &\n\tBaseActorConfig<\n\t\tTState,\n\t\tTConnParams,\n\t\tTConnState,\n\t\tTVars,\n\t\tTInput,\n\t\tTDatabase,\n\t\tTEvents,\n\t\tTQueues,\n\t\tActions<\n\t\t\tTState,\n\t\t\tTConnParams,\n\t\t\tTConnState,\n\t\t\tTVars,\n\t\t\tTInput,\n\t\t\tTDatabase,\n\t\t\tTEvents,\n\t\t\tTQueues\n\t\t>\n\t> &\n\tCreateState<\n\t\tTState,\n\t\tTConnParams,\n\t\tTConnState,\n\t\tTVars,\n\t\tTInput,\n\t\tTDatabase,\n\t\tTEvents,\n\t\tTQueues\n\t> &\n\tCreateConnState<\n\t\tTState,\n\t\tTConnParams,\n\t\tTConnState,\n\t\tTVars,\n\t\tTInput,\n\t\tTDatabase,\n\t\tTEvents,\n\t\tTQueues\n\t> &\n\tCreateVars<\n\t\tTState,\n\t\tTConnParams,\n\t\tTConnState,\n\t\tTVars,\n\t\tTInput,\n\t\tTDatabase,\n\t\tTEvents,\n\t\tTQueues\n\t> &\n\tActorDatabaseConfig<TDatabase>;\n\n// See description on `ActorConfig`\nexport type ActorConfigInput<\n\tTState = undefined,\n\tTConnParams = undefined,\n\tTConnState = undefined,\n\tTVars = undefined,\n\tTInput = undefined,\n\tTDatabase extends AnyDatabaseProvider = undefined,\n\tTEvents extends EventSchemaConfig = Record<never, never>,\n\tTQueues extends QueueSchemaConfig = Record<never, never>,\n\tTActions extends Actions<\n\t\tTState,\n\t\tTConnParams,\n\t\tTConnState,\n\t\tTVars,\n\t\tTInput,\n\t\tTDatabase,\n\t\tTEvents,\n\t\tTQueues\n\t> = Record<never, never>,\n> = {\n\ttypes?: ActorTypes<\n\t\tTState,\n\t\tTConnParams,\n\t\tTConnState,\n\t\tTVars,\n\t\tTInput,\n\t\tTDatabase\n\t>;\n} & Omit<\n\tz.input<typeof ActorConfigSchema>,\n\t| \"actions\"\n\t| \"events\"\n\t| \"queues\"\n\t| \"onCreate\"\n\t| \"onDestroy\"\n\t| \"onMigrate\"\n\t| \"onWake\"\n\t| \"onSleep\"\n\t| \"run\"\n\t| \"onStateChange\"\n\t| \"onBeforeConnect\"\n\t| \"onConnect\"\n\t| \"onDisconnect\"\n\t| \"onBeforeActionResponse\"\n\t| \"onRequest\"\n\t| \"onWebSocket\"\n\t| \"state\"\n\t| \"createState\"\n\t| \"connState\"\n\t| \"createConnState\"\n\t| \"vars\"\n\t| \"createVars\"\n\t| \"db\"\n> &\n\tBaseActorConfig<\n\t\tTState,\n\t\tTConnParams,\n\t\tTConnState,\n\t\tTVars,\n\t\tTInput,\n\t\tTDatabase,\n\t\tTEvents,\n\t\tTQueues,\n\t\tTActions\n\t> &\n\tCreateState<\n\t\tTState,\n\t\tTConnParams,\n\t\tTConnState,\n\t\tTVars,\n\t\tTInput,\n\t\tTDatabase,\n\t\tTEvents,\n\t\tTQueues\n\t> &\n\tCreateConnState<\n\t\tTState,\n\t\tTConnParams,\n\t\tTConnState,\n\t\tTVars,\n\t\tTInput,\n\t\tTDatabase,\n\t\tTEvents,\n\t\tTQueues\n\t> &\n\tCreateVars<\n\t\tTState,\n\t\tTConnParams,\n\t\tTConnState,\n\t\tTVars,\n\t\tTInput,\n\t\tTDatabase,\n\t\tTEvents,\n\t\tTQueues\n\t> &\n\tActorDatabaseConfig<TDatabase>;\n\n// For testing type definitions:\nexport function test<\n\tTState,\n\tTConnParams,\n\tTConnState,\n\tTVars,\n\tTInput,\n\tTDatabase extends AnyDatabaseProvider,\n\tTEvents extends EventSchemaConfig,\n\tTQueues extends QueueSchemaConfig,\n\tTActions extends Actions<\n\t\tTState,\n\t\tTConnParams,\n\t\tTConnState,\n\t\tTVars,\n\t\tTInput,\n\t\tTDatabase,\n\t\tTEvents,\n\t\tTQueues\n\t>,\n>(\n\tinput: ActorConfigInput<\n\t\tTState,\n\t\tTConnParams,\n\t\tTConnState,\n\t\tTVars,\n\t\tTInput,\n\t\tTDatabase,\n\t\tTEvents,\n\t\tTQueues,\n\t\tTActions\n\t>,\n): ActorConfig<\n\tTState,\n\tTConnParams,\n\tTConnState,\n\tTVars,\n\tTInput,\n\tTDatabase,\n\tTEvents,\n\tTQueues\n> {\n\tconst config = ActorConfigSchema.parse(input) as ActorConfig<\n\t\tTState,\n\t\tTConnParams,\n\t\tTConnState,\n\t\tTVars,\n\t\tTInput,\n\t\tTDatabase,\n\t\tTEvents,\n\t\tTQueues\n\t>;\n\treturn config;\n}\n\n// MARK: Documentation Schema\n// This schema is JSON-serializable for documentation generation.\n// It excludes function types and focuses on the configurable options.\n\nexport const DocActorOptionsSchema = z\n\t.object({\n\t\tname: z\n\t\t\t.string()\n\t\t\t.optional()\n\t\t\t.describe(\"Display name for the actor in the Inspector UI.\"),\n\t\ticon: z\n\t\t\t.string()\n\t\t\t.optional()\n\t\t\t.describe(\n\t\t\t\t\"Icon for the actor in the Inspector UI. Can be an emoji (e.g., '🚀') or FontAwesome icon name (e.g., 'rocket').\",\n\t\t\t),\n\t\tcreateVarsTimeout: z\n\t\t\t.number()\n\t\t\t.optional()\n\t\t\t.describe(\"Timeout in ms for createVars handler. Default: 5000\"),\n\t\tcreateConnStateTimeout: z\n\t\t\t.number()\n\t\t\t.optional()\n\t\t\t.describe(\n\t\t\t\t\"Timeout in ms for createConnState handler. Default: 5000\",\n\t\t\t),\n\t\tonMigrateTimeout: z\n\t\t\t.number()\n\t\t\t.optional()\n\t\t\t.describe(\"Timeout in ms for onMigrate handler. Default: 30000\"),\n\t\tonBeforeConnectTimeout: z\n\t\t\t.number()\n\t\t\t.optional()\n\t\t\t.describe(\n\t\t\t\t\"Timeout in ms for onBeforeConnect handler. Default: 5000\",\n\t\t\t),\n\t\tonConnectTimeout: z\n\t\t\t.number()\n\t\t\t.optional()\n\t\t\t.describe(\"Timeout in ms for onConnect handler. Default: 5000\"),\n\t\tsleepGracePeriod: z\n\t\t\t.number()\n\t\t\t.optional()\n\t\t\t.describe(\n\t\t\t\t`Max time in ms for the graceful shutdown window. Covers lifecycle hooks (onSleep, onDestroy), the run handler wait, async raw WebSocket handlers, disconnect callbacks, and final state serialization. Default: ${DEFAULT_SLEEP_GRACE_PERIOD}.`,\n\t\t\t),\n\t\tonDestroyTimeout: z\n\t\t\t.number()\n\t\t\t.optional()\n\t\t\t.describe(\n\t\t\t\t\"Deprecated. Folded into sleepGracePeriod, which now bounds the entire graceful shutdown window for both sleep and destroy. Will be removed in 2.2.0.\",\n\t\t\t),\n\t\twaitUntilTimeout: z\n\t\t\t.number()\n\t\t\t.optional()\n\t\t\t.describe(\n\t\t\t\t\"Deprecated. Folded into sleepGracePeriod, which now bounds the entire graceful shutdown window for both sleep and destroy. Will be removed in 2.2.0.\",\n\t\t\t),\n\t\tstateSaveInterval: z\n\t\t\t.number()\n\t\t\t.optional()\n\t\t\t.describe(\n\t\t\t\t\"Interval in ms between automatic state saves. Default: 1000\",\n\t\t\t),\n\t\tactionTimeout: z\n\t\t\t.number()\n\t\t\t.optional()\n\t\t\t.describe(\"Timeout in ms for action handlers. Default: 60000\"),\n\t\tconnectionLivenessTimeout: z\n\t\t\t.number()\n\t\t\t.optional()\n\t\t\t.describe(\n\t\t\t\t\"Timeout in ms for connection liveness checks. Default: 2500\",\n\t\t\t),\n\t\tconnectionLivenessInterval: z\n\t\t\t.number()\n\t\t\t.optional()\n\t\t\t.describe(\n\t\t\t\t\"Interval in ms between connection liveness checks. Default: 5000\",\n\t\t\t),\n\t\tnoSleep: z\n\t\t\t.boolean()\n\t\t\t.optional()\n\t\t\t.describe(\n\t\t\t\t\"Deprecated. If true, the actor will never sleep. Use c.keepAwake(promise) to scope keep-awake to a specific operation instead. Default: false\",\n\t\t\t),\n\t\tsleepTimeout: z\n\t\t\t.number()\n\t\t\t.optional()\n\t\t\t.describe(\n\t\t\t\t\"Time in ms of inactivity before the actor sleeps. Default: 30000\",\n\t\t\t),\n\t\tmaxQueueSize: z\n\t\t\t.number()\n\t\t\t.optional()\n\t\t\t.describe(\n\t\t\t\t\"Maximum number of queue messages before rejecting new messages. Default: 1000\",\n\t\t\t),\n\t\tmaxQueueMessageSize: z\n\t\t\t.number()\n\t\t\t.optional()\n\t\t\t.describe(\n\t\t\t\t\"Maximum size of each queue message in bytes. Default: 65536\",\n\t\t\t),\n\t\tcanHibernateWebSocket: z\n\t\t\t.boolean()\n\t\t\t.optional()\n\t\t\t.describe(\n\t\t\t\t\"Whether WebSockets using onWebSocket can be hibernated. WebSockets using actions/events are hibernatable by default. Default: false\",\n\t\t\t),\n\t\tpreloadMaxWorkflowBytes: z\n\t\t\t.number()\n\t\t\t.optional()\n\t\t\t.describe(\n\t\t\t\t\"Override RivetKit's workflow preload budget for this actor. Set to 0 to disable workflow preloading.\",\n\t\t\t),\n\t\tpreloadMaxConnectionsBytes: z\n\t\t\t.number()\n\t\t\t.optional()\n\t\t\t.describe(\n\t\t\t\t\"Override RivetKit's connections preload budget for this actor. Set to 0 to disable connections preloading.\",\n\t\t\t),\n\t})\n\t.describe(\"Actor options for timeouts and behavior configuration.\");\n\nexport const DocActorConfigSchema = z\n\t.object({\n\t\tstate: z\n\t\t\t.unknown()\n\t\t\t.optional()\n\t\t\t.describe(\n\t\t\t\t\"Initial state value for the actor. Cannot be used with createState.\",\n\t\t\t),\n\t\tcreateState: z\n\t\t\t.unknown()\n\t\t\t.optional()\n\t\t\t.describe(\n\t\t\t\t\"Function to create initial state. Receives context and input. Cannot be used with state.\",\n\t\t\t),\n\t\tconnState: z\n\t\t\t.unknown()\n\t\t\t.optional()\n\t\t\t.describe(\n\t\t\t\t\"Initial connection state value. Cannot be used with createConnState.\",\n\t\t\t),\n\t\tcreateConnState: z\n\t\t\t.unknown()\n\t\t\t.optional()\n\t\t\t.describe(\n\t\t\t\t\"Function to create connection state. Receives context and connection params. The pending connection is not visible in c.conns until this succeeds. Cannot be used with connState.\",\n\t\t\t),\n\t\tvars: z\n\t\t\t.unknown()\n\t\t\t.optional()\n\t\t\t.describe(\n\t\t\t\t\"Initial ephemeral variables value. Cannot be used with createVars.\",\n\t\t\t),\n\t\tcreateVars: z\n\t\t\t.unknown()\n\t\t\t.optional()\n\t\t\t.describe(\n\t\t\t\t\"Function to create ephemeral variables. Receives context and driver context. Cannot be used with vars.\",\n\t\t\t),\n\t\tdb: z\n\t\t\t.unknown()\n\t\t\t.optional()\n\t\t\t.describe(\"Database provider instance for the actor.\"),\n\t\tonCreate: z\n\t\t\t.unknown()\n\t\t\t.optional()\n\t\t\t.describe(\n\t\t\t\t\"Called when the actor is first initialized. Use to initialize state.\",\n\t\t\t),\n\t\tonDestroy: z\n\t\t\t.unknown()\n\t\t\t.optional()\n\t\t\t.describe(\"Called when the actor is destroyed.\"),\n\t\tonMigrate: z\n\t\t\t.unknown()\n\t\t\t.optional()\n\t\t\t.describe(\n\t\t\t\t\"Called on every actor start after persisted state loads and before onWake. Use for repeatable schema migrations.\",\n\t\t\t),\n\t\tonWake: z\n\t\t\t.unknown()\n\t\t\t.optional()\n\t\t\t.describe(\n\t\t\t\t\"Called when the actor wakes up and is ready to receive connections and actions.\",\n\t\t\t),\n\t\tonSleep: z\n\t\t\t.unknown()\n\t\t\t.optional()\n\t\t\t.describe(\n\t\t\t\t\"Called when the actor is stopping or sleeping. Use to clean up resources.\",\n\t\t\t),\n\t\trun: z\n\t\t\t.unknown()\n\t\t\t.optional()\n\t\t\t.describe(\n\t\t\t\t\"Called after actor starts. Does not block startup. Use for background tasks like queue processing or tick loops. If it exits, the actor follows the normal idle sleep timeout once idle. If it throws, the actor logs the error and then follows the normal idle sleep timeout once idle.\",\n\t\t\t),\n\t\tonStateChange: z\n\t\t\t.unknown()\n\t\t\t.optional()\n\t\t\t.describe(\n\t\t\t\t\"Called when the actor's state changes. State changes within this hook won't trigger recursion.\",\n\t\t\t),\n\t\tonBeforeConnect: z\n\t\t\t.unknown()\n\t\t\t.optional()\n\t\t\t.describe(\n\t\t\t\t\"Called before a client connects. Throw an error to reject the connection. The pending connection is not visible in c.conns while this runs.\",\n\t\t\t),\n\t\tonConnect: z\n\t\t\t.unknown()\n\t\t\t.optional()\n\t\t\t.describe(\n\t\t\t\t\"Called when a client successfully connects. The connection is visible in c.conns before this runs.\",\n\t\t\t),\n\t\tonDisconnect: z\n\t\t\t.unknown()\n\t\t\t.optional()\n\t\t\t.describe(\"Called when a client disconnects.\"),\n\t\tonBeforeActionResponse: z\n\t\t\t.unknown()\n\t\t\t.optional()\n\t\t\t.describe(\n\t\t\t\t\"Called before sending an action response. Use to transform output.\",\n\t\t\t),\n\t\tonRequest: z\n\t\t\t.unknown()\n\t\t\t.optional()\n\t\t\t.describe(\n\t\t\t\t\"Called for raw HTTP requests to /actors/{name}/http/* endpoints.\",\n\t\t\t),\n\t\tonWebSocket: z\n\t\t\t.unknown()\n\t\t\t.optional()\n\t\t\t.describe(\n\t\t\t\t\"Called for raw WebSocket connections to /actors/{name}/websocket/* endpoints.\",\n\t\t\t),\n\t\tactions: z\n\t\t\t.record(z.string(), z.unknown())\n\t\t\t.optional()\n\t\t\t.describe(\n\t\t\t\t\"Map of action name to handler function. Defaults to an empty object.\",\n\t\t\t),\n\t\tactionInputSchemas: z\n\t\t\t.record(z.string(), z.unknown())\n\t\t\t.optional()\n\t\t\t.describe(\n\t\t\t\t\"Optional schema map for validating action argument tuples in native runtimes.\",\n\t\t\t),\n\t\tconnParamsSchema: z\n\t\t\t.unknown()\n\t\t\t.optional()\n\t\t\t.describe(\n\t\t\t\t\"Optional schema for validating connection params in native runtimes.\",\n\t\t\t),\n\t\tevents: z\n\t\t\t.record(z.string(), z.unknown())\n\t\t\t.optional()\n\t\t\t.describe(\"Map of event names to schemas.\"),\n\t\tqueues: z\n\t\t\t.record(z.string(), z.unknown())\n\t\t\t.optional()\n\t\t\t.describe(\"Map of queue names to schemas.\"),\n\t\toptions: DocActorOptionsSchema.optional(),\n\t})\n\t.describe(\"Actor configuration passed to the actor() function.\");\n","import {\n\ttype DestinationStream,\n\ttype LevelWithSilent,\n\ttype Logger,\n\tpino,\n\tstdTimeFunctions,\n} from \"pino\";\nimport { z } from \"zod/v4\";\nimport { getLogLevel, getLogTarget, getLogTimestamp } from \"@/utils/env-vars\";\n\nexport type { Logger } from \"pino\";\n\nlet baseLogger: Logger | undefined;\nlet configuredLogLevel: LogLevel | undefined;\n\n/** Cache of child loggers by logger name. */\nconst loggerCache = new Map<string, Logger>();\n\nexport const LogLevelSchema = z.enum([\n\t\"trace\",\n\t\"debug\",\n\t\"info\",\n\t\"warn\",\n\t\"error\",\n\t\"fatal\",\n\t\"silent\",\n]);\n\nexport type LogLevel = z.infer<typeof LogLevelSchema>;\n\nexport function getPinoLevel(logLevel?: LogLevel): LevelWithSilent {\n\t// Priority: provided > configured > env > default\n\tif (logLevel) {\n\t\treturn logLevel;\n\t}\n\n\tif (configuredLogLevel) {\n\t\treturn configuredLogLevel;\n\t}\n\n\tconst raw = (getLogLevel() || \"warn\").toString().toLowerCase();\n\n\tconst parsed = LogLevelSchema.safeParse(raw);\n\tif (parsed.success) {\n\t\treturn parsed.data;\n\t}\n\n\t// Default to info if invalid\n\treturn \"info\";\n}\n\nexport function getIncludeTarget(): boolean {\n\treturn getLogTarget();\n}\n\n/**\n * Configure a custom base logger.\n */\nexport function configureBaseLogger(logger: Logger): void {\n\tbaseLogger = logger;\n\tloggerCache.clear();\n}\n\n/**\n * Configure the default logger with optional log level.\n */\nexport function configureDefaultLogger(logLevel?: LogLevel) {\n\t// Store the configured log level\n\tif (logLevel) {\n\t\tconfiguredLogLevel = logLevel;\n\t}\n\n\tbaseLogger = pino(\n\t\t{\n\t\t\tlevel: getPinoLevel(logLevel),\n\t\t\tmessageKey: \"msg\",\n\t\t\t// Do not include pid/hostname in output\n\t\t\tbase: {},\n\t\t\t// Keep the numeric level so the logfmt sink can match Pino's levels.\n\t\t\tformatters: {\n\t\t\t\tlevel(_label: string, number: number) {\n\t\t\t\t\treturn { level: number };\n\t\t\t\t},\n\t\t\t},\n\t\t\ttimestamp: getLogTimestamp() ? stdTimeFunctions.epochTime : false,\n\t\t},\n\t\tcreateLogfmtDestination(),\n\t);\n\n\tloggerCache.clear();\n}\n\n/**\n * Get or initialize the base logger.\n */\nexport function getBaseLogger(): Logger {\n\tif (!baseLogger) {\n\t\tconfigureDefaultLogger();\n\t}\n\treturn baseLogger!;\n}\n\n/**\n * Returns a child logger with `target` bound for the given name.\n */\nexport function getLogger(name = \"default\"): Logger {\n\t// Check cache first\n\tconst cached = loggerCache.get(name);\n\tif (cached) {\n\t\treturn cached;\n\t}\n\n\t// Create\n\tconst base = getBaseLogger();\n\n\t// Add target to log if enabled\n\tconst child = getIncludeTarget() ? base.child({ target: name }) : base;\n\n\t// Cache the logger\n\tloggerCache.set(name, child);\n\n\treturn child;\n}\n\nconst PINO_LEVEL_LABELS: Record<number, string> = {\n\t10: \"trace\",\n\t20: \"debug\",\n\t30: \"info\",\n\t40: \"warn\",\n\t50: \"error\",\n\t60: \"fatal\",\n};\n\nfunction createLogfmtDestination(): DestinationStream {\n\treturn {\n\t\twrite(msg: string): void {\n\t\t\tconst line = formatLogfmtLine(msg);\n\t\t\tif (typeof process !== \"undefined\" && process.stdout?.write) {\n\t\t\t\tprocess.stdout.write(`${line}\\n`);\n\t\t\t} else {\n\t\t\t\tconsole.log(line);\n\t\t\t}\n\t\t},\n\t};\n}\n\nfunction formatLogfmtLine(raw: string): string {\n\tlet data: Record<string, unknown>;\n\ttry {\n\t\tdata = JSON.parse(raw);\n\t} catch {\n\t\treturn raw.trimEnd();\n\t}\n\n\tconst parts: string[] = [];\n\tappendLogfmtEntry(parts, \"level\", formatPinoLevel(data.level));\n\n\tif (data.time !== undefined) {\n\t\tappendLogfmtEntry(parts, \"ts\", data.time);\n\t}\n\n\tfor (const [key, value] of Object.entries(data)) {\n\t\tif (key === \"level\" || key === \"time\") {\n\t\t\tcontinue;\n\t\t}\n\t\tappendLogfmtEntry(parts, key, value);\n\t}\n\n\treturn parts.join(\" \");\n}\n\nfunction formatPinoLevel(level: unknown): string {\n\tif (typeof level === \"number\") {\n\t\treturn PINO_LEVEL_LABELS[level] ?? level.toString();\n\t}\n\n\tif (typeof level === \"string\") {\n\t\treturn level.toLowerCase();\n\t}\n\n\treturn \"info\";\n}\n\nfunction appendLogfmtEntry(parts: string[], key: string, value: unknown): void {\n\tconst safeKey = key.replace(/[\\s=\"]/g, \"\");\n\tif (safeKey.length === 0) {\n\t\treturn;\n\t}\n\n\tparts.push(`${safeKey}=${formatLogfmtValue(value)}`);\n}\n\nfunction formatLogfmtValue(value: unknown): string {\n\tif (typeof value === \"number\" || typeof value === \"boolean\") {\n\t\treturn String(value);\n\t}\n\n\tif (value === null || value === undefined) {\n\t\treturn \"null\";\n\t}\n\n\tif (typeof value === \"string\") {\n\t\treturn quoteLogfmtString(value);\n\t}\n\n\treturn quoteLogfmtString(JSON.stringify(value));\n}\n\nfunction quoteLogfmtString(value: string): string {\n\tif (!/[\\s=\"]/.test(value)) {\n\t\treturn value;\n\t}\n\n\treturn `\"${value.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"').replace(/\\n/g, \"\\\\n\")}\"`;\n}\n","import type { DeconstructedError } from \"@/common/utils\";\n\nexport const INTERNAL_ERROR_CODE = \"internal_error\";\nexport const INTERNAL_ERROR_DESCRIPTION = \"An internal error occurred\";\nexport type InternalErrorMetadata = Record<string, never>;\n\nexport const USER_ERROR_CODE = \"user_error\";\nexport const BRIDGE_RIVET_ERROR_PREFIX = \"__RIVET_ERROR_JSON__:\";\n\nexport interface RivetErrorOptions extends ErrorOptions {\n\t/** Error data can safely be serialized in a response to the client. */\n\tpublic?: boolean;\n\t/** Metadata associated with this error. */\n\tmetadata?: unknown;\n\t/** Explicit HTTP status override for router responses. */\n\tstatusCode?: number;\n\t/** Actor context associated with this error. */\n\tactor?: ActorSpecifier;\n}\n\n/** Identifies the actor that was handling work when an error was produced. */\nexport interface ActorSpecifier {\n\tactorId: string;\n\tgeneration: number;\n\tkey?: string;\n}\n\nexport interface RivetErrorLike {\n\t__type?: \"ActorError\" | \"RivetError\";\n\tgroup: string;\n\tcode: string;\n\tmessage: string;\n\tmetadata?: unknown;\n\tpublic?: boolean;\n\tstatusCode?: number;\n\tactor?: ActorSpecifier;\n}\n\nexport interface BridgeRivetErrorPayload extends RivetErrorLike {}\n\nexport interface UserErrorOptions extends ErrorOptions {\n\t/**\n\t * Machine readable code for this error. Useful for catching different types of\n\t * errors in try-catch.\n\t */\n\tcode?: string;\n\t/**\n\t * Additional metadata related to the error. Useful for understanding context\n\t * about the error.\n\t */\n\tmetadata?: unknown;\n}\n\nfunction looksLikeRivetErrorOptions(\n\tvalue: unknown,\n): value is RivetErrorOptions {\n\treturn (\n\t\ttypeof value === \"object\" &&\n\t\tvalue !== null &&\n\t\t(\"public\" in value ||\n\t\t\t\"metadata\" in value ||\n\t\t\t\"statusCode\" in value ||\n\t\t\t\"actor\" in value ||\n\t\t\t\"cause\" in value)\n\t);\n}\n\nfunction isTypedErrorTag(value: unknown): value is \"ActorError\" | \"RivetError\" {\n\treturn value === \"ActorError\" || value === \"RivetError\";\n}\n\nfunction errorMessage(error: unknown, fallback = String(error)): string {\n\tif (\n\t\terror &&\n\t\ttypeof error === \"object\" &&\n\t\t\"message\" in error &&\n\t\ttypeof error.message === \"string\"\n\t) {\n\t\treturn error.message;\n\t}\n\n\treturn fallback;\n}\n\nexport function isRivetErrorLike(\n\terror: unknown,\n): error is RivetError | DeconstructedError | RivetErrorLike {\n\treturn (\n\t\ttypeof error === \"object\" &&\n\t\terror !== null &&\n\t\t\"group\" in error &&\n\t\ttypeof error.group === \"string\" &&\n\t\t\"code\" in error &&\n\t\ttypeof error.code === \"string\" &&\n\t\t\"message\" in error &&\n\t\ttypeof error.message === \"string\" &&\n\t\t(!(\"__type\" in error) || isTypedErrorTag(error.__type))\n\t);\n}\n\nfunction isActorSpecifier(value: unknown): value is ActorSpecifier {\n\treturn (\n\t\ttypeof value === \"object\" &&\n\t\tvalue !== null &&\n\t\t\"actorId\" in value &&\n\t\ttypeof value.actorId === \"string\" &&\n\t\t\"generation\" in value &&\n\t\ttypeof value.generation === \"number\" &&\n\t\t(!(\"key\" in value) || value.key === undefined || typeof value.key === \"string\")\n\t);\n}\n\nexport class RivetError extends Error {\n\t__type = \"RivetError\" as const;\n\n\tpublic public: boolean;\n\tpublic metadata?: unknown;\n\tpublic statusCode: number;\n\tpublic actor?: ActorSpecifier;\n\tpublic readonly group: string;\n\tpublic readonly code: string;\n\n\tpublic static isRivetError(\n\t\terror: unknown,\n\t): error is RivetError | DeconstructedError {\n\t\treturn isRivetErrorLike(error);\n\t}\n\n\tpublic static isActorError(\n\t\terror: unknown,\n\t): error is RivetError | DeconstructedError {\n\t\treturn isRivetErrorLike(error);\n\t}\n\n\tconstructor(\n\t\tgroup: string,\n\t\tcode: string,\n\t\tmessage: string,\n\t\toptions?: RivetErrorOptions | unknown,\n\t) {\n\t\tconst normalized = looksLikeRivetErrorOptions(options)\n\t\t\t? options\n\t\t\t: { metadata: options };\n\n\t\tsuper(message, { cause: normalized.cause });\n\t\tthis.name = \"RivetError\";\n\t\tthis.group = group;\n\t\tthis.code = code;\n\t\tthis.public = normalized.public ?? false;\n\t\tthis.metadata = normalized.metadata;\n\t\tthis.statusCode = normalized.statusCode ?? (this.public ? 400 : 500);\n\t\tthis.actor = normalized.actor;\n\t}\n\n\ttoString() {\n\t\treturn this.message;\n\t}\n}\n\nexport { RivetError as ActorError };\n\nexport class UserError extends RivetError {\n\tconstructor(message: string, options?: UserErrorOptions) {\n\t\tsuper(\"user\", options?.code ?? USER_ERROR_CODE, message, {\n\t\t\tpublic: true,\n\t\t\tmetadata: options?.metadata,\n\t\t\tcause: options?.cause,\n\t\t});\n\t}\n}\n\nexport function toRivetError(\n\terror: unknown,\n\tfallback?: Partial<RivetErrorLike>,\n): RivetError {\n\tif (typeof error === \"string\") {\n\t\tconst bridged = decodeBridgeRivetError(error);\n\t\tif (bridged) {\n\t\t\treturn bridged;\n\t\t}\n\t}\n\n\tif (error instanceof Error) {\n\t\tconst bridged = decodeBridgeRivetError(error.message);\n\t\tif (bridged) {\n\t\t\treturn bridged;\n\t\t}\n\t}\n\n\tif (isRivetErrorLike(error)) {\n\t\treturn new RivetError(error.group, error.code, error.message, {\n\t\t\tpublic: error.public,\n\t\t\tstatusCode: error.statusCode,\n\t\t\tmetadata: error.metadata,\n\t\t\tactor: error.actor,\n\t\t\tcause: error instanceof Error ? error.cause : undefined,\n\t\t});\n\t}\n\n\treturn new RivetError(\n\t\tfallback?.group ?? \"actor\",\n\t\tfallback?.code ?? INTERNAL_ERROR_CODE,\n\t\terrorMessage(error, fallback?.message ?? \"Unknown error\"),\n\t\t{\n\t\t\tpublic: fallback?.public,\n\t\t\tstatusCode: fallback?.statusCode,\n\t\t\tmetadata: fallback?.metadata,\n\t\t\tactor: fallback?.actor,\n\t\t\tcause: error instanceof Error ? error : undefined,\n\t\t},\n\t);\n}\n\nexport function encodeBridgeRivetError(error: RivetErrorLike): string {\n\treturn `${BRIDGE_RIVET_ERROR_PREFIX}${JSON.stringify({\n\t\tgroup: error.group,\n\t\tcode: error.code,\n\t\tmessage: error.message,\n\t\tmetadata: error.metadata,\n\t\tpublic: error.public,\n\t\tstatusCode: error.statusCode,\n\t\tactor: error.actor,\n\t})}`;\n}\n\nexport function decodeBridgeRivetErrorPayload(\n\tvalue: string,\n): BridgeRivetErrorPayload | undefined {\n\tif (!value.startsWith(BRIDGE_RIVET_ERROR_PREFIX)) {\n\t\treturn undefined;\n\t}\n\n\ttry {\n\t\tconst payload = JSON.parse(\n\t\t\tvalue.slice(BRIDGE_RIVET_ERROR_PREFIX.length),\n\t\t) as BridgeRivetErrorPayload;\n\t\tif (!isRivetErrorLike(payload)) {\n\t\t\treturn undefined;\n\t\t}\n\t\tif (payload.actor !== undefined && !isActorSpecifier(payload.actor)) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\treturn payload;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nexport function decodeBridgeRivetError(value: string): RivetError | undefined {\n\tconst payload = decodeBridgeRivetErrorPayload(value);\n\tif (!payload) {\n\t\treturn undefined;\n\t}\n\n\treturn new RivetError(payload.group, payload.code, payload.message, {\n\t\tmetadata: payload.metadata,\n\t\tpublic: payload.public,\n\t\tstatusCode: payload.statusCode,\n\t\tactor: payload.actor,\n\t});\n}\n\nexport function isRivetErrorCode(\n\terror: unknown,\n\tgroup: string,\n\tcode: string,\n): error is RivetError {\n\treturn (\n\t\tisRivetErrorLike(error) && error.group === group && error.code === code\n\t);\n}\n\nexport function internalError(\n\tmessage: string,\n\toptions?: Partial<RivetErrorOptions> & {\n\t\tgroup?: string;\n\t\tcode?: string;\n\t},\n): RivetError {\n\treturn new RivetError(\n\t\toptions?.group ?? \"actor\",\n\t\toptions?.code ?? INTERNAL_ERROR_CODE,\n\t\tmessage,\n\t\t{\n\t\t\tpublic: options?.public,\n\t\t\tstatusCode: options?.statusCode,\n\t\t\tmetadata: options?.metadata,\n\t\t\tactor: options?.actor,\n\t\t\tcause: options?.cause,\n\t\t},\n\t);\n}\n\nexport function invalidEncoding(format?: string): RivetError {\n\treturn new RivetError(\n\t\t\"encoding\",\n\t\t\"invalid\",\n\t\t`Invalid encoding \\`${format}\\`. (https://www.rivet.dev/docs/clients/javascript)`,\n\t\t{\n\t\t\tpublic: true,\n\t\t},\n\t);\n}\n\nexport function invalidRequest(error?: unknown): RivetError {\n\treturn new RivetError(\n\t\t\"request\",\n\t\t\"invalid\",\n\t\t`Invalid request: ${errorMessage(error, String(error))}`,\n\t\t{\n\t\t\tpublic: true,\n\t\t\tcause: error instanceof Error ? error : undefined,\n\t\t},\n\t);\n}\n\nexport function actorNotFound(identifier?: string): RivetError {\n\treturn new RivetError(\n\t\t\"actor\",\n\t\t\"not_found\",\n\t\tidentifier\n\t\t\t? `Actor not found: ${identifier} (https://www.rivet.dev/docs/clients/javascript)`\n\t\t\t: \"Actor not found (https://www.rivet.dev/docs/clients/javascript)\",\n\t\t{ public: true },\n\t);\n}\n\nexport function actorStopping(identifier?: string): RivetError {\n\treturn new RivetError(\n\t\t\"actor\",\n\t\t\"stopping\",\n\t\tidentifier ? `Actor stopping: ${identifier}` : \"Actor stopping\",\n\t\t{ public: true },\n\t);\n}\n\nexport interface ActorRestartingOptions {\n\tphase?: \"stopping\" | \"sleeping\" | \"waking\" | \"runner_shutdown\";\n\tretryAfterMs?: number;\n}\n\nexport function actorRestarting(opts?: ActorRestartingOptions): RivetError {\n\treturn new RivetError(\n\t\t\"actor\",\n\t\t\"restarting\",\n\t\t\"Actor is restarting. Retry the request.\",\n\t\t{\n\t\t\tpublic: true,\n\t\t\tstatusCode: 503,\n\t\t\tmetadata: {\n\t\t\t\tretryable: true,\n\t\t\t\t...(opts?.phase ? { phase: opts.phase } : {}),\n\t\t\t\t...(opts?.retryAfterMs !== undefined\n\t\t\t\t\t? { retryAfterMs: opts.retryAfterMs }\n\t\t\t\t\t: {}),\n\t\t\t},\n\t\t},\n\t);\n}\n\nexport function forbiddenError(): RivetError {\n\treturn new RivetError(\"auth\", \"forbidden\", \"Forbidden\", {\n\t\tpublic: true,\n\t\tstatusCode: 403,\n\t});\n}\n\nexport function unsupportedFeature(feature: string): RivetError {\n\treturn new RivetError(\n\t\t\"feature\",\n\t\t\"unsupported\",\n\t\t`Unsupported feature: ${feature}`,\n\t);\n}\n","{\n\t\"name\": \"rivetkit\",\n\t\"version\": \"2.3.0-rc.6\",\n\t\"description\": \"Lightweight libraries for building stateful actors on edge platforms\",\n\t\"license\": \"Apache-2.0\",\n\t\"keywords\": [\n\t\t\"rivetkit\",\n\t\t\"stateful\",\n\t\t\"serverless\",\n\t\t\"actors\",\n\t\t\"agents\",\n\t\t\"realtime\",\n\t\t\"websocket\",\n\t\t\"actors\",\n\t\t\"framework\"\n\t],\n\t\"files\": [\n\t\t\"dist\",\n\t\t\"schemas\",\n\t\t\"src\",\n\t\t\"package.json\"\n\t],\n\t\"type\": \"module\",\n\t\"exports\": {\n\t\t\".\": {\n\t\t\t\"import\": {\n\t\t\t\t\"types\": \"./dist/tsup/mod.d.ts\",\n\t\t\t\t\"default\": \"./dist/tsup/mod.js\"\n\t\t\t},\n\t\t\t\"require\": {\n\t\t\t\t\"types\": \"./dist/tsup/mod.d.cts\",\n\t\t\t\t\"default\": \"./dist/tsup/mod.cjs\"\n\t\t\t}\n\t\t},\n\t\t\"./workflow\": {\n\t\t\t\"import\": {\n\t\t\t\t\"types\": \"./dist/tsup/workflow/mod.d.ts\",\n\t\t\t\t\"default\": \"./dist/tsup/workflow/mod.js\"\n\t\t\t},\n\t\t\t\"require\": {\n\t\t\t\t\"types\": \"./dist/tsup/workflow/mod.d.cts\",\n\t\t\t\t\"default\": \"./dist/tsup/workflow/mod.cjs\"\n\t\t\t}\n\t\t},\n\t\t\"./test\": {\n\t\t\t\"import\": {\n\t\t\t\t\"types\": \"./dist/tsup/test/mod.d.ts\",\n\t\t\t\t\"default\": \"./dist/tsup/test/mod.js\"\n\t\t\t},\n\t\t\t\"require\": {\n\t\t\t\t\"types\": \"./dist/tsup/test/mod.d.cts\",\n\t\t\t\t\"default\": \"./dist/tsup/test/mod.cjs\"\n\t\t\t}\n\t\t},\n\t\t\"./db\": {\n\t\t\t\"import\": {\n\t\t\t\t\"types\": \"./dist/tsup/db/mod.d.ts\",\n\t\t\t\t\"default\": \"./dist/tsup/db/mod.js\"\n\t\t\t},\n\t\t\t\"require\": {\n\t\t\t\t\"types\": \"./dist/tsup/db/mod.d.cts\",\n\t\t\t\t\"default\": \"./dist/tsup/db/mod.cjs\"\n\t\t\t}\n\t\t},\n\t\t\"./db/drizzle\": {\n\t\t\t\"import\": {\n\t\t\t\t\"types\": \"./dist/tsup/db/drizzle.d.ts\",\n\t\t\t\t\"default\": \"./dist/tsup/db/drizzle.js\"\n\t\t\t},\n\t\t\t\"require\": {\n\t\t\t\t\"types\": \"./dist/tsup/db/drizzle.d.cts\",\n\t\t\t\t\"default\": \"./dist/tsup/db/drizzle.cjs\"\n\t\t\t}\n\t\t},\n\t\t\"./client\": {\n\t\t\t\"import\": {\n\t\t\t\t\"browser\": {\n\t\t\t\t\t\"types\": \"./dist/browser/client.d.ts\",\n\t\t\t\t\t\"default\": \"./dist/browser/client.js\"\n\t\t\t\t},\n\t\t\t\t\"types\": \"./dist/tsup/client/mod.d.ts\",\n\t\t\t\t\"default\": \"./dist/tsup/client/mod.js\"\n\t\t\t},\n\t\t\t\"require\": {\n\t\t\t\t\"types\": \"./dist/tsup/client/mod.d.cts\",\n\t\t\t\t\"default\": \"./dist/tsup/client/mod.cjs\"\n\t\t\t}\n\t\t},\n\t\t\"./log\": {\n\t\t\t\"import\": {\n\t\t\t\t\"types\": \"./dist/tsup/common/log.d.ts\",\n\t\t\t\t\"default\": \"./dist/tsup/common/log.js\"\n\t\t\t},\n\t\t\t\"require\": {\n\t\t\t\t\"types\": \"./dist/tsup/common/log.d.cts\",\n\t\t\t\t\"default\": \"./dist/tsup/common/log.cjs\"\n\t\t\t}\n\t\t},\n\t\t\"./errors\": {\n\t\t\t\"import\": {\n\t\t\t\t\"types\": \"./dist/tsup/actor/errors.d.ts\",\n\t\t\t\t\"default\": \"./dist/tsup/actor/errors.js\"\n\t\t\t},\n\t\t\t\"require\": {\n\t\t\t\t\"types\": \"./dist/tsup/actor/errors.d.cts\",\n\t\t\t\t\"default\": \"./dist/tsup/actor/errors.cjs\"\n\t\t\t}\n\t\t},\n\t\t\"./inspector\": {\n\t\t\t\"import\": {\n\t\t\t\t\"types\": \"./dist/tsup/inspector/mod.d.ts\",\n\t\t\t\t\"default\": \"./dist/tsup/inspector/mod.js\"\n\t\t\t},\n\t\t\t\"require\": {\n\t\t\t\t\"types\": \"./dist/tsup/inspector/mod.d.cts\",\n\t\t\t\t\"default\": \"./dist/tsup/inspector/mod.cjs\"\n\t\t\t}\n\t\t},\n\t\t\"./inspector/client\": {\n\t\t\t\"import\": {\n\t\t\t\t\"types\": \"./dist/browser/inspector/client.d.ts\",\n\t\t\t\t\"default\": \"./dist/browser/inspector/client.js\"\n\t\t\t}\n\t\t},\n\t\t\"./utils\": {\n\t\t\t\"import\": {\n\t\t\t\t\"types\": \"./dist/tsup/utils.d.ts\",\n\t\t\t\t\"default\": \"./dist/tsup/utils.js\"\n\t\t\t},\n\t\t\t\"require\": {\n\t\t\t\t\"types\": \"./dist/tsup/utils.d.cts\",\n\t\t\t\t\"default\": \"./dist/tsup/utils.cjs\"\n\t\t\t}\n\t\t},\n\t\t\"./agent-os\": {\n\t\t\t\"import\": {\n\t\t\t\t\"types\": \"./dist/tsup/agent-os/index.d.ts\",\n\t\t\t\t\"default\": \"./dist/tsup/agent-os/index.js\"\n\t\t\t},\n\t\t\t\"require\": {\n\t\t\t\t\"types\": \"./dist/tsup/agent-os/index.d.cts\",\n\t\t\t\t\"default\": \"./dist/tsup/agent-os/index.cjs\"\n\t\t\t}\n\t\t}\n\t},\n\t\"engines\": {\n\t\t\"node\": \">=22.0.0\"\n\t},\n\t\"sideEffects\": [\n\t\t\"./dist/tsup/chunk-*.js\",\n\t\t\"./dist/tsup/chunk-*.cjs\"\n\t],\n\t\"scripts\": {\n\t\t\"build\": \"tsup src/mod.ts src/client/mod.ts src/common/log.ts src/common/websocket.ts src/actor/errors.ts src/utils.ts src/workflow/mod.ts src/test/mod.ts src/inspector/mod.ts src/db/mod.ts src/db/drizzle.ts && tsup src/agent-os/index.ts --no-clean --out-dir dist/tsup/agent-os\",\n\t\t\"build:browser\": \"tsup --config tsup.browser.config.ts\",\n\t\t\"check-types\": \"tsc --noEmit\",\n\t\t\"lint\": \"biome check . && pnpm run check:test-skips && pnpm run check:wait-for-comments\",\n\t\t\"lint:fix\": \"biome check --write .\",\n\t\t\"check:test-skips\": \"tsx scripts/check-annotated-skips.ts\",\n\t\t\"check:wait-for-comments\": \"tsx scripts/check-wait-for-comments.ts\",\n\t\t\"format\": \"biome format .\",\n\t\t\"format:write\": \"biome format --write .\",\n\t\t\"test\": \"vitest run\",\n\t\t\"test:platforms\": \"pnpm run build && RIVETKIT_INCLUDE_PLATFORM_TESTS=1 vitest run tests/platforms --passWithNoTests\",\n\t\t\"test:watch\": \"vitest\",\n\t\t\"dump-asyncapi\": \"tsx scripts/dump-asyncapi.ts\",\n\t\t\"registry-config-schema-gen\": \"tsx scripts/registry-config-schema-gen.ts\",\n\t\t\"actor-config-schema-gen\": \"tsx scripts/actor-config-schema-gen.ts\"\n\t},\n\t\"dependencies\": {\n\t\t\"@rivet-dev/agent-os-core\": \"^0.1.1\",\n\t\t\"@hono/node-server\": \"^1.18.2\",\n\t\t\"@hono/node-ws\": \"^1.1.1\",\n\t\t\"@hono/zod-openapi\": \"^1.1.5\",\n\t\t\"@rivetkit/bare-ts\": \"^0.6.2\",\n\t\t\"@rivetkit/engine-cli\": \"workspace:*\",\n\t\t\"@rivetkit/engine-envoy-protocol\": \"workspace:*\",\n\t\t\"@rivetkit/rivetkit-napi\": \"workspace:*\",\n\t\t\"@rivetkit/rivetkit-wasm\": \"workspace:*\",\n\t\t\"@rivetkit/traces\": \"workspace:*\",\n\t\t\"@rivetkit/virtual-websocket\": \"workspace:*\",\n\t\t\"@rivetkit/workflow-engine\": \"workspace:*\",\n\t\t\"cbor-x\": \"^1.6.0\",\n\t\t\"drizzle-orm\": \"^0.44.2\",\n\t\t\"get-port\": \"^7.1.0\",\n\t\t\"hono\": \"^4.7.0\",\n\t\t\"invariant\": \"^2.2.4\",\n\t\t\"p-retry\": \"^6.2.1\",\n\t\t\"pino\": \"^9.5.0\",\n\t\t\"uuid\": \"^12.0.0\",\n\t\t\"vbare\": \"^0.0.4\",\n\t\t\"zod\": \"^4.1.0\"\n\t},\n\t\"devDependencies\": {\n\t\t\"@copilotkit/llmock\": \"^1.6.0\",\n\t\t\"@rivet-dev/agent-os-common\": \"*\",\n\t\t\"@rivet-dev/agent-os-pi\": \"^0.1.1\",\n\t\t\"@biomejs/biome\": \"^2.3\",\n\t\t\"@standard-schema/spec\": \"^1.0.0\",\n\t\t\"@types/invariant\": \"^2\",\n\t\t\"@types/node\": \"^22.13.1\",\n\t\t\"eventsource\": \"^4.0.0\",\n\t\t\"tsup\": \"^8.4.0\",\n\t\t\"tsx\": \"^4.19.4\",\n\t\t\"typescript\": \"^5.7.3\",\n\t\t\"vite-tsconfig-paths\": \"^5.1.4\",\n\t\t\"vitest\": \"^3.1.1\",\n\t\t\"ws\": \"^8.18.1\"\n\t},\n\t\"peerDependencies\": {\n\t\t\"drizzle-kit\": \"^0.31.2\",\n\t\t\"eventsource\": \"^4.0.0\",\n\t\t\"ws\": \"^8.0.0\"\n\t},\n\t\"peerDependenciesMeta\": {\n\t\t\"drizzle-kit\": {\n\t\t\t\"optional\": true\n\t\t},\n\t\t\"eventsource\": {\n\t\t\t\"optional\": true\n\t\t},\n\t\t\"ws\": {\n\t\t\t\"optional\": true\n\t\t}\n\t},\n\t\"stableVersion\": \"0.8.0\"\n}\n","import { stringifyError } from \"@/common/utils\";\nimport type { Context as HonoContext, Handler as HonoHandler } from \"hono\";\nimport { stringify as uuidstringify } from \"uuid\";\nimport pkgJson from \"../package.json\" with { type: \"json\" };\nimport { getLogger } from \"./common/log\";\nimport { assertUnreachable } from \"./common/utils\";\n\n/** @experimental */\nexport { stringifyError };\n\n/** @experimental */\nexport { assertUnreachable };\n\n/**\n * Joins multiple abort signals into one.\n *\n * The returned signal aborts when the first input signal aborts.\n * Uses `AbortSignal.any(...)` when available, with a runtime fallback.\n *\n * @experimental\n */\nexport function joinSignals(\n\t...signals: Array<AbortSignal | undefined | null>\n): AbortSignal {\n\tconst validSignals = signals.filter(\n\t\t(signal): signal is AbortSignal => signal != null,\n\t);\n\n\tif (validSignals.length === 0) {\n\t\treturn new AbortController().signal;\n\t}\n\n\tif (validSignals.length === 1) {\n\t\treturn validSignals[0];\n\t}\n\n\tconst signalAny = (\n\t\tAbortSignal as typeof AbortSignal & {\n\t\t\tany?: (signals: AbortSignal[]) => AbortSignal;\n\t\t}\n\t).any;\n\tif (typeof signalAny === \"function\") {\n\t\treturn signalAny(validSignals);\n\t}\n\n\tconst controller = new AbortController();\n\tconst cleanups: Array<() => void> = [];\n\n\tconst abortWithSignal = (signal: AbortSignal) => {\n\t\tif (controller.signal.aborted) {\n\t\t\treturn;\n\t\t}\n\n\t\tfor (const cleanup of cleanups) {\n\t\t\tcleanup();\n\t\t}\n\n\t\tconst reason = (signal as AbortSignal & { reason?: unknown }).reason;\n\t\tcontroller.abort(reason);\n\t};\n\n\tfor (const signal of validSignals) {\n\t\tif (signal.aborted) {\n\t\t\tabortWithSignal(signal);\n\t\t\tbreak;\n\t\t}\n\n\t\tconst onAbort = () => abortWithSignal(signal);\n\t\tsignal.addEventListener(\"abort\", onAbort, { once: true });\n\t\tcleanups.push(() => signal.removeEventListener(\"abort\", onAbort));\n\t}\n\n\treturn controller.signal;\n}\n\n/**\n * Returns a promise that resolves after the given number of milliseconds.\n *\n * @experimental\n */\nexport function sleep(ms: number): Promise<void> {\n\treturn new Promise<void>((resolve) => setTimeout(resolve, ms));\n}\n\n/**\n * Creates a fixed-rate interval tick function that can be awaited in a loop.\n *\n * @example\n * const tick = interval(100);\n * while (!c.aborted) {\n * await tick();\n * if (c.aborted) break;\n * // ... game logic\n * }\n *\n * @experimental\n */\nexport function interval(ms: number): () => Promise<void> {\n\treturn () => sleep(ms);\n}\n\nexport const VERSION = pkgJson.version;\n\nlet _userAgent: string | undefined;\n\nfunction logger() {\n\treturn getLogger(\"utils\");\n}\n\n/**\n * Builds the HTTP user agent used by this library.\n *\n * @experimental\n */\nexport function httpUserAgent(): string {\n\t// Return cached value if already initialized\n\tif (_userAgent !== undefined) {\n\t\treturn _userAgent;\n\t}\n\n\t// Library\n\tlet userAgent = `RivetKit/${VERSION}`;\n\n\t// Navigator\n\tconst navigatorObj =\n\t\ttypeof navigator !== \"undefined\" ? navigator : undefined;\n\tif (navigatorObj?.userAgent) userAgent += ` ${navigatorObj.userAgent}`;\n\n\t_userAgent = userAgent;\n\n\treturn userAgent;\n}\n\nexport type UpgradeWebSocket = (\n\tcreateEvents: (c: HonoContext) => any,\n) => HonoHandler;\n\nexport type GetUpgradeWebSocket = () => UpgradeWebSocket;\n\n/**\n * Reads an environment variable from Deno or Node runtimes.\n *\n * @experimental\n */\nexport function getEnvUniversal(key: string): string | undefined {\n\tif (typeof Deno !== \"undefined\") {\n\t\treturn Deno.env.get(key);\n\t} else if (typeof process !== \"undefined\") {\n\t\t// Do this after Deno since `process` is sometimes polyfilled\n\t\treturn process.env[key];\n\t}\n}\n\n/**\n * Traces a debug value and returns it.\n *\n * @experimental\n */\nexport function dbg<T>(x: T): T {\n\tconsole.trace(`=== DEBUG ===\\n${x}`);\n\treturn x;\n}\n\n/**\n * Converts various ArrayBuffer-like types to Uint8Array.\n * Handles ArrayBuffer, ArrayBufferView (including typed arrays), and passes through existing Uint8Array.\n *\n * @param data - The ArrayBuffer or ArrayBufferView to convert\n * @returns A Uint8Array view of the data\n *\n * @experimental\n */\nexport function toUint8Array(data: ArrayBuffer | ArrayBufferView): Uint8Array {\n\tif (data instanceof Uint8Array) {\n\t\treturn data;\n\t} else if (data instanceof ArrayBuffer) {\n\t\treturn new Uint8Array(data);\n\t} else if (ArrayBuffer.isView(data)) {\n\t\t// Handle other ArrayBufferView types (Int8Array, Uint16Array, DataView, etc.)\n\t\treturn new Uint8Array(\n\t\t\tdata.buffer.slice(\n\t\t\t\tdata.byteOffset,\n\t\t\t\tdata.byteOffset + data.byteLength,\n\t\t\t),\n\t\t);\n\t} else {\n\t\tthrow new TypeError(\"Input must be ArrayBuffer or ArrayBufferView\");\n\t}\n}\n\n// Long timeouts\n//\n// JavaScript timers use a signed 32-bit integer for delays, so values above 2^31-1 (~24.8 days)\n// are not reliable and may fire immediately or overflow.\n//\n// https://developer.mozilla.org/en-US/docs/Web/API/Window/setTimeout#maximum_delay_value\nconst TIMEOUT_MAX = 2147483647; // 2^31-1\n\nexport type LongTimeoutHandle = { abort: () => void };\n\n/**\n * Polyfill for Promise.withResolvers().\n *\n * This is specifically for Cloudflare Workers. Their implementation of Promise.withResolvers does not work correctly.\n *\n * @experimental\n */\nexport function promiseWithResolvers<T>(onReject: (reason?: any) => void): {\n\tpromise: Promise<T>;\n\tresolve: (value: T | PromiseLike<T>) => void;\n\treject: (reason?: any) => void;\n} {\n\tlet resolve!: (value: T | PromiseLike<T>) => void;\n\tlet reject!: (reason?: any) => void;\n\tconst promise = new Promise<T>((res, rej) => {\n\t\tresolve = res;\n\t\treject = rej;\n\t});\n\tpromise.catch(onReject);\n\treturn { promise, resolve, reject };\n}\n\n/**\n * Sets a timeout that supports delays larger than the JavaScript timer limit.\n *\n * @experimental\n */\nexport function setLongTimeout(\n\tlistener: () => void,\n\tafter: number,\n): LongTimeoutHandle {\n\tlet timeout: ReturnType<typeof setTimeout> | undefined;\n\n\tfunction start(remaining: number) {\n\t\tif (remaining <= TIMEOUT_MAX) {\n\t\t\ttimeout = setTimeout(listener, remaining);\n\t\t} else {\n\t\t\ttimeout = setTimeout(() => {\n\t\t\t\tstart(remaining - TIMEOUT_MAX);\n\t\t\t}, TIMEOUT_MAX);\n\t\t}\n\t}\n\n\tstart(after);\n\n\treturn {\n\t\tabort: () => {\n\t\t\tif (timeout !== undefined) clearTimeout(timeout);\n\t\t},\n\t};\n}\n\n/**\n * A tiny utility that coalesces/enqueues async operations so only the latest\n * queued task runs per cycle, while callers receive a promise that resolves\n * when the task for the cycle they joined has completed.\n */\nexport class SinglePromiseQueue {\n\t/** Next operation to execute in the queue. If attempting to enqueue another op, it will override the existing op. */\n\t#queuedOp?: () => Promise<void>;\n\n\t/** The currently running promise of #drainLoop. Do not await this, instead await `pending` to await the current cycle. */\n\trunningDrainLoop?: Promise<void>;\n\n\t/** Pending resolver fro the currently queued entry. */\n\t#pending?: ReturnType<typeof promiseWithResolvers<void>>;\n\n\t/** Queue the next operation and return a promise that resolves when it flushes. */\n\tenqueue(op: () => Promise<void>): Promise<void> {\n\t\t// Replace any previously queued operation with the latest one\n\t\tthis.#queuedOp = op;\n\n\t\t// Ensure a shared resolver exists for all callers in this cycle\n\t\tif (!this.#pending) {\n\t\t\tthis.#pending = promiseWithResolvers<void>((reason) =>\n\t\t\t\tlogger().warn({\n\t\t\t\t\tmsg: \"unhandled single promise queue rejection\",\n\t\t\t\t\treason,\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\n\t\tconst waitForThisCycle = this.#pending.promise;\n\n\t\t// Start runner if not already running\n\t\tif (!this.runningDrainLoop) {\n\t\t\tthis.runningDrainLoop = this.#drainLoop();\n\t\t}\n\n\t\treturn waitForThisCycle;\n\t}\n\n\t/** Drain queued operations sequentially until there is nothing left. */\n\tasync #drainLoop(): Promise<void> {\n\t\ttry {\n\t\t\twhile (this.#queuedOp) {\n\t\t\t\t// Capture current cycle resolver then reset for the next cycle\n\t\t\t\tconst resolver = this.#pending;\n\t\t\t\tthis.#pending = undefined;\n\n\t\t\t\t// Capture and clear the currently queued operation\n\t\t\t\tconst op = this.#queuedOp;\n\t\t\t\tthis.#queuedOp = undefined;\n\n\t\t\t\ttry {\n\t\t\t\t\tawait op();\n\t\t\t\t\t// Notify all waiters for this cycle\n\t\t\t\t\tresolver?.resolve();\n\t\t\t\t} catch (err) {\n\t\t\t\t\tlogger().error({\n\t\t\t\t\t\tmsg: \"error in SinglePromiseQueue drain loop\",\n\t\t\t\t\t\terror: stringifyError(err),\n\t\t\t\t\t});\n\t\t\t\t\t// Reject all waiters for this cycle\n\t\t\t\t\tresolver?.reject(err);\n\t\t\t\t}\n\t\t\t}\n\t\t} finally {\n\t\t\tthis.runningDrainLoop = undefined;\n\t\t}\n\t}\n}\n\n/**\n * Converts a Buffer or Uint8Array into an ArrayBuffer view.\n *\n * @experimental\n */\nexport function bufferToArrayBuffer(buf: Buffer | Uint8Array): ArrayBuffer {\n\treturn buf.buffer.slice(\n\t\tbuf.byteOffset,\n\t\tbuf.byteOffset + buf.byteLength,\n\t) as ArrayBuffer;\n}\n\n/**\n * Properly combines a base URL endpoint with a path, preserving any base path in the endpoint.\n *\n * @example\n * combineUrlPath(\"http://localhost:8787/rivet\", \"/actors/action\")\n * // Returns: \"http://localhost:8787/rivet/actors/action\"\n *\n * @example\n * combineUrlPath(\"http://localhost:8787/rivet\", \"/actors?type=foo\", { namespace: \"test\" })\n * // Returns: \"http://localhost:8787/rivet/actors?type=foo&namespace=test\"\n *\n * @param endpoint The base URL endpoint that may contain a path component\n * @param path The path to append to the endpoint (may include query parameters)\n * @param queryParams Optional additional query parameters to append\n * @returns The properly combined URL string\n *\n * @experimental\n */\nexport function combineUrlPath(\n\tendpoint: string,\n\tpath: string,\n\tqueryParams?: Record<string, string | undefined>,\n): string {\n\tconst baseUrl = new URL(endpoint);\n\n\t// Extract path and query from the provided path\n\tconst pathParts = path.split(\"?\");\n\tconst pathOnly = pathParts[0];\n\tconst existingQuery = pathParts[1] || \"\";\n\n\t// Remove trailing slash from base path and ensure path starts with /\n\tconst basePath = baseUrl.pathname.replace(/\\/$/, \"\");\n\tconst cleanPath = pathOnly.startsWith(\"/\") ? pathOnly : `/${pathOnly}`;\n\t// Combine paths and remove any double slashes\n\tconst fullPath = (basePath + cleanPath).replace(/\\/\\//g, \"/\");\n\n\t// Build query string\n\tconst queryParts: string[] = [];\n\tif (existingQuery) {\n\t\tqueryParts.push(existingQuery);\n\t}\n\tif (queryParams) {\n\t\tfor (const [key, value] of Object.entries(queryParams)) {\n\t\t\tif (value !== undefined) {\n\t\t\t\tqueryParts.push(\n\t\t\t\t\t`${encodeURIComponent(key)}=${encodeURIComponent(value)}`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\tconst fullQuery = queryParts.length > 0 ? `?${queryParts.join(\"&\")}` : \"\";\n\treturn `${baseUrl.protocol}//${baseUrl.host}${fullPath}${fullQuery}`;\n}\n\n/**\n * Compares two ArrayBuffer values by byte content.\n *\n * @experimental\n */\nexport function arrayBuffersEqual(\n\tbuf1: ArrayBuffer,\n\tbuf2: ArrayBuffer,\n): boolean {\n\tif (buf1.byteLength !== buf2.byteLength) return false;\n\n\tconst view1 = new Uint8Array(buf1);\n\tconst view2 = new Uint8Array(buf2);\n\n\tfor (let i = 0; i < view1.length; i++) {\n\t\tif (view1[i] !== view2[i]) return false;\n\t}\n\treturn true;\n}\n\nexport const EXTRA_ERROR_LOG = {\n\tissues: \"https://github.com/rivet-dev/rivet/issues\",\n\tsupport: \"https://rivet.dev/discord\",\n\tversion: VERSION,\n};\n\nexport type Runtime = \"deno\" | \"bun\" | \"node\";\n\n/**\n * Detects the current JavaScript runtime from the user agent.\n *\n * @experimental\n */\nexport function detectRuntime(): Runtime {\n\tconst userAgent =\n\t\ttypeof navigator !== \"undefined\" ? navigator.userAgent : \"\";\n\tif (userAgent.includes(\"Deno\")) {\n\t\treturn \"deno\";\n\t}\n\tif (userAgent.includes(\"Bun\")) {\n\t\treturn \"bun\";\n\t}\n\treturn \"node\";\n}\n\nexport type DeepReadonly<T> = {\n\treadonly [K in keyof T]: T[K] extends object ? DeepReadonly<T[K]> : T[K];\n};\n\nexport type DeepMutable<T> = {\n\t-readonly [K in keyof T]: T[K] extends object ? DeepMutable<T[K]> : T[K];\n};\n","// This file consolidates all environment variables that affect RivetKit's behavior.\n//\n// IMPORTANT: When adding or modifying environment variables here, also update the\n// documentation at: website/src/content/docs/general/environment-variables.mdx\n\nimport { getEnvUniversal } from \"@/utils\";\n\n// Rivet configuration\nexport const getRivetEngine = (): string | undefined =>\n\tgetEnvUniversal(\"RIVET_ENGINE\");\nexport const getRivetEndpoint = (): string | undefined =>\n\tgetEnvUniversal(\"RIVET_ENDPOINT\");\nexport const getRivetToken = (): string | undefined =>\n\tgetEnvUniversal(\"RIVET_TOKEN\");\nexport const getRivetNamespace = (): string | undefined =>\n\tgetEnvUniversal(\"RIVET_NAMESPACE\");\nexport const getRivetPool = (): string | undefined =>\n\tgetEnvUniversal(\"RIVET_POOL\");\nexport const getRivetTotalSlots = (): number | undefined => {\n\tconst value = getEnvUniversal(\"RIVET_TOTAL_SLOTS\");\n\treturn value !== undefined ? parseInt(value, 10) : undefined;\n};\nexport const getRivetRunEngine = (): boolean =>\n\tgetEnvUniversal(\"RIVET_RUN_ENGINE\") === \"1\";\nexport const getRivetRunEngineVersion = (): string | undefined =>\n\tgetEnvUniversal(\"RIVET_RUN_ENGINE_VERSION\");\nexport const getRivetEnvoyKind = (): string | undefined =>\n\tgetEnvUniversal(\"RIVET_ENVOY_KIND\");\nexport const getRivetEnvoyVersion = (): number | undefined => {\n\tconst value = getEnvUniversal(\"RIVET_ENVOY_VERSION\");\n\treturn value !== undefined ? parseInt(value, 10) : undefined;\n};\nexport const getRivetPublicEndpoint = (): string | undefined =>\n\tgetEnvUniversal(\"RIVET_PUBLIC_ENDPOINT\");\nexport const getRivetPublicToken = (): string | undefined =>\n\tgetEnvUniversal(\"RIVET_PUBLIC_TOKEN\");\n// There is no RIVET_PUBLIC_NAMESPACE because the frontend and backend cannot\n// use different namespaces\n\n// RivetKit configuration\nexport const getRivetkitInspectorDisable = (): boolean =>\n\tgetEnvUniversal(\"RIVET_INSPECTOR_DISABLE\") === \"1\";\nexport const getRivetkitStoragePath = (): string | undefined =>\n\tgetEnvUniversal(\"RIVETKIT_STORAGE_PATH\");\nexport const getRivetkitRuntime = (): string | undefined =>\n\tgetEnvUniversal(\"RIVETKIT_RUNTIME\");\n\n// Logging configuration\n// DEPRECATED: LOG_LEVEL will be removed in a future version\nexport const getLogLevel = (): string | undefined =>\n\tgetEnvUniversal(\"RIVET_LOG_LEVEL\") ?? getEnvUniversal(\"LOG_LEVEL\");\nexport const getLogTarget = (): boolean =>\n\tgetEnvUniversal(\"RIVET_LOG_TARGET\") === \"1\";\nexport const getLogTimestamp = (): boolean =>\n\tgetEnvUniversal(\"RIVET_LOG_TIMESTAMP\") === \"1\";\nexport const getLogMessage = (): boolean =>\n\tgetEnvUniversal(\"RIVET_LOG_MESSAGE\") === \"1\";\nexport const getLogErrorStack = (): boolean =>\n\tgetEnvUniversal(\"RIVET_LOG_ERROR_STACK\") === \"1\";\nexport const getLogHeaders = (): boolean =>\n\tgetEnvUniversal(\"RIVET_LOG_HEADERS\") === \"1\";\n\n// Environment configuration\nexport const getNodeEnv = (): string | undefined => getEnvUniversal(\"NODE_ENV\");\nexport const getNextPhase = (): string | undefined =>\n\tgetEnvUniversal(\"NEXT_PHASE\");\nexport const isDev = (): boolean => getNodeEnv() !== \"production\";\n\n// Experimental\n/**\n * Enables experimental OTel tracing for Rivet Actors.\n *\n * When disabled, actors use an in-memory no-op traces implementation.\n */\nexport const getRivetExperimentalOtel = (): boolean =>\n\tgetEnvUniversal(\"RIVET_EXPERIMENTAL_OTEL\") === \"1\";\n","import { getLogger } from \"@/common/log\";\n\n/** Prever to use ActorInstance.rlog child logger. This does not provide context in the log, should only be used as a last resort if you cannot pass the actor's child logger. */\nexport function loggerWithoutContext() {\n\treturn getLogger(\"actor-runtime\");\n}\n","import type { RegistryConfig } from \"@/registry/config\";\nimport { ActorConfigSchema, type Actions, type ActorConfig, type ActorConfigInput } from \"./config\";\nimport { loggerWithoutContext } from \"./log\";\nimport type { AnyDatabaseProvider } from \"@/common/database/config\";\nimport type { EventSchemaConfig, QueueSchemaConfig } from \"./schema\";\n\nconst warnedDeprecatedTimeoutKeys = new Set<string>();\n\nfunction warnDeprecatedShutdownTimeoutKeys(options: unknown) {\n\tif (!options || typeof options !== \"object\") return;\n\tconst opts = options as Record<string, unknown>;\n\tfor (const key of [\"onDestroyTimeout\", \"waitUntilTimeout\"]) {\n\t\tif (opts[key] !== undefined && !warnedDeprecatedTimeoutKeys.has(key)) {\n\t\t\twarnedDeprecatedTimeoutKeys.add(key);\n\t\t\tloggerWithoutContext().warn({\n\t\t\t\tmsg: `actor option \\`${key}\\` is deprecated and is now ignored. Configure \\`sleepGracePeriod\\` instead, which bounds the entire graceful shutdown window for both sleep and destroy. Will be removed in 2.2.0.`,\n\t\t\t});\n\t\t}\n\t}\n}\n\nexport interface BaseActorDefinition<\n\tS,\n\tCP,\n\tCS,\n\tV,\n\tI,\n\tDB extends AnyDatabaseProvider,\n\tE extends EventSchemaConfig = Record<never, never>,\n\tQ extends QueueSchemaConfig = Record<never, never>,\n\tR extends Actions<S, CP, CS, V, I, DB, E, Q> = Actions<\n\t\tS,\n\t\tCP,\n\t\tCS,\n\t\tV,\n\t\tI,\n\t\tDB,\n\t\tE,\n\t\tQ\n\t>,\n> {\n\treadonly config: ActorConfig<S, CP, CS, V, I, DB, E, Q>;\n}\n\nexport type AnyActorDefinition = BaseActorDefinition<\n\tany,\n\tany,\n\tany,\n\tany,\n\tany,\n\tany,\n\tany,\n\tany,\n\tany\n>;\n\nexport type AnyStaticActorDefinition = ActorDefinition<\n\tany,\n\tany,\n\tany,\n\tany,\n\tany,\n\tany,\n\tany,\n\tany,\n\tany\n>;\n\nexport class ActorDefinition<\n\tS,\n\tCP,\n\tCS,\n\tV,\n\tI,\n\tDB extends AnyDatabaseProvider,\n\tE extends EventSchemaConfig = Record<never, never>,\n\tQ extends QueueSchemaConfig = Record<never, never>,\n\tR extends Actions<S, CP, CS, V, I, DB, E, Q> = Actions<\n\t\tS,\n\t\tCP,\n\t\tCS,\n\t\tV,\n\t\tI,\n\t\tDB,\n\t\tE,\n\t\tQ\n\t>,\n> implements BaseActorDefinition<S, CP, CS, V, I, DB, E, Q, R>\n{\n\t#config: ActorConfig<S, CP, CS, V, I, DB, E, Q>;\n\n\tconstructor(config: ActorConfig<S, CP, CS, V, I, DB, E, Q>) {\n\t\tthis.#config = config;\n\t}\n\n\tget config(): ActorConfig<S, CP, CS, V, I, DB, E, Q> {\n\t\treturn this.#config;\n\t}\n}\n\nexport interface BaseActorInstance<\n\tS = any,\n\tCP = any,\n\tCS = any,\n\tV = any,\n\tI = any,\n\tDB extends AnyDatabaseProvider = AnyDatabaseProvider,\n\tE extends EventSchemaConfig = Record<never, never>,\n\tQ extends QueueSchemaConfig = Record<never, never>,\n> {\n\tid: string;\n\tconfig: ActorConfig<S, CP, CS, V, I, DB, E, Q>;\n\trLog: Record<string, (...args: any[]) => any>;\n\t[key: string]: any;\n}\n\nexport type AnyActorInstance = BaseActorInstance<\n\tany,\n\tany,\n\tany,\n\tany,\n\tany,\n\tany,\n\tany,\n\tany\n>;\n\nexport type AnyStaticActorInstance = AnyActorInstance;\n\nexport function isStaticActorInstance(\n\t_actor: AnyActorInstance,\n): _actor is AnyStaticActorInstance {\n\treturn true;\n}\n\nexport function actor<\n\tTState,\n\tTConnParams,\n\tTConnState,\n\tTVars,\n\tTInput,\n\tTDatabase extends AnyDatabaseProvider,\n\tTEvents extends EventSchemaConfig = Record<never, never>,\n\tTQueues extends QueueSchemaConfig = Record<never, never>,\n\tTActions extends Actions<\n\t\tTState,\n\t\tTConnParams,\n\t\tTConnState,\n\t\tTVars,\n\t\tTInput,\n\t\tTDatabase,\n\t\tTEvents,\n\t\tTQueues\n\t> = Actions<\n\t\tTState,\n\t\tTConnParams,\n\t\tTConnState,\n\t\tTVars,\n\t\tTInput,\n\t\tTDatabase,\n\t\tTEvents,\n\t\tTQueues\n\t>,\n>(\n\tinput: ActorConfigInput<\n\t\tTState,\n\t\tTConnParams,\n\t\tTConnState,\n\t\tTVars,\n\t\tTInput,\n\t\tTDatabase,\n\t\tTEvents,\n\t\tTQueues,\n\t\tTActions\n\t>,\n): ActorDefinition<\n\tTState,\n\tTConnParams,\n\tTConnState,\n\tTVars,\n\tTInput,\n\tTDatabase,\n\tTEvents,\n\tTQueues,\n\tTActions\n> {\n\twarnDeprecatedShutdownTimeoutKeys(\n\t\t(input as { options?: unknown } | undefined)?.options,\n\t);\n\tconst config = ActorConfigSchema.parse(input) as ActorConfig<\n\t\tTState,\n\t\tTConnParams,\n\t\tTConnState,\n\t\tTVars,\n\t\tTInput,\n\t\tTDatabase,\n\t\tTEvents,\n\t\tTQueues\n\t>;\n\treturn new ActorDefinition(config);\n}\n\nexport function isStaticActorDefinition(\n\tdefinition: AnyActorDefinition,\n): definition is AnyStaticActorDefinition {\n\treturn definition instanceof ActorDefinition;\n}\n\nexport function lookupInRegistry(\n\tconfig: RegistryConfig,\n\tname: string,\n): AnyActorDefinition {\n\tconst definition = config.use[name];\n\tif (!definition) throw new Error(`no actor in registry for name ${name}`);\n\treturn definition;\n}\n","import type { StandardSchemaV1 } from \"@standard-schema/spec\";\nimport { unsupportedFeature } from \"./errors\";\n\nexport type SchemaHookResult = boolean | Promise<boolean>;\n\ntype SchemaHook<TContext = any> = (ctx: TContext) => SchemaHookResult;\n\nexport interface EventTypeToken<T, TContext = any> {\n\treadonly _eventType?: T;\n\treadonly canSubscribe?: SchemaHook<TContext>;\n\treadonly schema?: PrimitiveSchema;\n}\n\nexport interface QueueTypeToken<TMessage, TComplete = never, TContext = any> {\n\treadonly _queueMessage?: TMessage;\n\treadonly _queueComplete?: TComplete;\n\treadonly canPublish?: SchemaHook<TContext>;\n\treadonly message?: PrimitiveSchema;\n\treadonly complete?: PrimitiveSchema;\n}\n\n/** @deprecated Use `event<T>()`. */\nexport type Type<T> = EventTypeToken<T, any>;\n\ninterface EventOptions<TContext = any> {\n\tcanSubscribe?: SchemaHook<TContext>;\n\tschema?: PrimitiveSchema;\n}\n\ninterface QueueOptions<TContext = any> {\n\tcanPublish?: SchemaHook<TContext>;\n\tmessage?: PrimitiveSchema;\n\tcomplete?: PrimitiveSchema;\n}\n\nexport function event<T, TContext = any>(\n\toptions?: EventOptions<TContext>,\n): EventTypeToken<T, TContext> {\n\treturn (options ?? {}) as EventTypeToken<T, TContext>;\n}\n\nexport function queue<TMessage, TComplete = never, TContext = any>(\n\toptions?: QueueOptions<TContext>,\n): QueueTypeToken<TMessage, TComplete, TContext> {\n\treturn (options ?? {}) as QueueTypeToken<TMessage, TComplete, TContext>;\n}\n\nexport type PrimitiveSchema = StandardSchemaV1 | EventTypeToken<unknown, any>;\n\nexport interface EventSchemaDefinition<TContext = any> {\n\tschema: PrimitiveSchema;\n\tcanSubscribe?: SchemaHook<TContext>;\n}\n\nexport interface QueueSchemaDefinition<TContext = any> {\n\tmessage: PrimitiveSchema;\n\tcomplete?: PrimitiveSchema;\n\tcanPublish?: SchemaHook<TContext>;\n}\n\nexport type EventSchema<TContext = any> =\n\t| PrimitiveSchema\n\t| EventSchemaDefinition<TContext>;\nexport type QueueSchema =\n\t| PrimitiveSchema\n\t| QueueSchemaDefinition<any>\n\t| QueueTypeToken<unknown, unknown, any>;\nexport type EventSchemaConfig<TContext = any> = Record<\n\tstring,\n\tEventSchema<TContext>\n>;\nexport type QueueSchemaConfig<TContext = any> = Record<string, QueueSchema>;\nexport type AnySchemaConfig = EventSchemaConfig | QueueSchemaConfig;\n\n/** @deprecated Use `EventSchema` or `QueueSchema`. */\nexport type Schema = QueueSchema;\n/** @deprecated Use `EventSchemaConfig` or `QueueSchemaConfig`. */\nexport type SchemaConfig = QueueSchemaConfig;\n\nexport type InferSchema<T> =\n\tT extends QueueSchemaDefinition<any>\n\t\t? InferSchema<T[\"message\"]>\n\t\t: T extends QueueTypeToken<infer M, unknown, any>\n\t\t\t? M\n\t\t\t: T extends EventSchemaDefinition<any>\n\t\t\t\t? InferSchema<T[\"schema\"]>\n\t\t\t\t: T extends StandardSchemaV1<any, infer O>\n\t\t\t\t\t? O\n\t\t\t\t\t: T extends EventTypeToken<infer R, any>\n\t\t\t\t\t\t? R\n\t\t\t\t\t\t: never;\n\nexport type InferSchemaMap<T extends Record<string, unknown>> = {\n\t[K in keyof T]: InferSchema<T[K]>;\n};\n\nexport type InferQueueComplete<T> =\n\tT extends QueueTypeToken<unknown, infer C, any>\n\t\t? [C] extends [never]\n\t\t\t? never\n\t\t\t: C\n\t\t: T extends QueueSchemaDefinition<any>\n\t\t\t? T[\"complete\"] extends PrimitiveSchema\n\t\t\t\t? InferSchema<T[\"complete\"]>\n\t\t\t\t: never\n\t\t\t: never;\n\nexport type InferQueueCompleteMap<T extends QueueSchemaConfig> = {\n\t[K in keyof T]: InferQueueComplete<T[K]>;\n};\n\nexport type InferEventArgs<T> = T extends readonly unknown[]\n\t? number extends T[\"length\"]\n\t\t? [T]\n\t\t: T\n\t: [T];\n\nexport type ValidationResult<T> =\n\t| { success: true; data: T }\n\t| { success: false; issues: unknown[] };\n\nexport function isStandardSchema(value: unknown): value is StandardSchemaV1 {\n\treturn typeof value === \"object\" && value !== null && \"~standard\" in value;\n}\n\nexport function isQueueSchemaDefinition(\n\tvalue: unknown,\n): value is QueueSchemaDefinition<any> {\n\tif (isEventSchemaDefinition(value)) {\n\t\treturn false;\n\t}\n\treturn (\n\t\ttypeof value === \"object\" &&\n\t\tvalue !== null &&\n\t\t\"message\" in value &&\n\t\t(value as { message?: unknown }).message !== undefined\n\t);\n}\n\nexport function isEventSchemaDefinition(\n\tvalue: unknown,\n): value is EventSchemaDefinition<any> {\n\treturn (\n\t\ttypeof value === \"object\" &&\n\t\tvalue !== null &&\n\t\t\"schema\" in value &&\n\t\t(value as { schema?: unknown }).schema !== undefined\n\t);\n}\n\nexport function hasSchemaConfigKey<T extends AnySchemaConfig>(\n\tschemas: T | undefined,\n\tkey: string,\n): boolean {\n\tif (!schemas) {\n\t\treturn false;\n\t}\n\treturn Object.prototype.hasOwnProperty.call(schemas, key);\n}\n\nexport function getEventCanSubscribe<TContext = any>(\n\tschemas: EventSchemaConfig<TContext> | undefined,\n\tkey: string,\n): SchemaHook<TContext> | undefined {\n\tconst schema = schemas?.[key];\n\tif (!schema || isStandardSchema(schema)) {\n\t\treturn undefined;\n\t}\n\n\tconst maybeCanSubscribe = (schema as { canSubscribe?: unknown })\n\t\t.canSubscribe;\n\treturn typeof maybeCanSubscribe === \"function\"\n\t\t? (maybeCanSubscribe as SchemaHook<TContext>)\n\t\t: undefined;\n}\n\nexport function getQueueCanPublish<TContext = any>(\n\tschemas: QueueSchemaConfig | undefined,\n\tkey: string,\n): SchemaHook<TContext> | undefined {\n\tconst schema = schemas?.[key];\n\tif (!schema || isStandardSchema(schema)) {\n\t\treturn undefined;\n\t}\n\n\tconst maybeCanPublish = (schema as { canPublish?: unknown }).canPublish;\n\treturn typeof maybeCanPublish === \"function\"\n\t\t? (maybeCanPublish as SchemaHook<TContext>)\n\t\t: undefined;\n}\n\nfunction getValidationSchema(\n\tschema: QueueSchema | EventSchema | undefined,\n): QueueSchema | EventSchema | undefined {\n\tif (!schema) {\n\t\treturn undefined;\n\t}\n\tif (isEventSchemaDefinition(schema)) {\n\t\treturn schema.schema;\n\t}\n\tif (isQueueSchemaDefinition(schema)) {\n\t\treturn schema.message;\n\t}\n\tif (\n\t\ttypeof schema === \"object\" &&\n\t\tschema !== null &&\n\t\t\"schema\" in schema &&\n\t\t(schema as { schema?: unknown }).schema !== undefined\n\t) {\n\t\treturn (schema as { schema: QueueSchema | EventSchema }).schema;\n\t}\n\tif (\n\t\ttypeof schema === \"object\" &&\n\t\tschema !== null &&\n\t\t\"message\" in schema &&\n\t\t(schema as { message?: unknown }).message !== undefined\n\t) {\n\t\treturn (schema as { message: QueueSchema | EventSchema }).message;\n\t}\n\treturn schema;\n}\n\nfunction isPromiseLike(value: unknown): value is PromiseLike<unknown> {\n\treturn (\n\t\ttypeof value === \"object\" &&\n\t\tvalue !== null &&\n\t\t\"then\" in value &&\n\t\ttypeof (value as { then?: unknown }).then === \"function\"\n\t);\n}\n\nexport async function validateSchema<T extends AnySchemaConfig>(\n\tschemas: T | undefined,\n\tkey: keyof T & string,\n\tdata: unknown,\n): Promise<ValidationResult<InferSchemaMap<T>[typeof key]>> {\n\tconst schema = getValidationSchema(schemas?.[key]);\n\n\tif (!schema) {\n\t\treturn { success: true, data: data as InferSchemaMap<T>[typeof key] };\n\t}\n\n\tif (isStandardSchema(schema)) {\n\t\tconst result = await schema[\"~standard\"].validate(data);\n\t\tif (result.issues) {\n\t\t\treturn { success: false, issues: [...result.issues] };\n\t\t}\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tdata: result.value as InferSchemaMap<T>[typeof key],\n\t\t};\n\t}\n\n\treturn { success: true, data: data as InferSchemaMap<T>[typeof key] };\n}\n\nexport function validateSchemaSync<T extends AnySchemaConfig>(\n\tschemas: T | undefined,\n\tkey: keyof T & string,\n\tdata: unknown,\n): ValidationResult<InferSchemaMap<T>[typeof key]> {\n\tconst schema = getValidationSchema(schemas?.[key]);\n\n\tif (!schema) {\n\t\treturn { success: true, data: data as InferSchemaMap<T>[typeof key] };\n\t}\n\n\tif (isStandardSchema(schema)) {\n\t\tconst result = schema[\"~standard\"].validate(data);\n\t\tif (isPromiseLike(result)) {\n\t\t\tthrow unsupportedFeature(\"async schema validation\");\n\t\t}\n\t\tif (result.issues) {\n\t\t\treturn { success: false, issues: [...result.issues] };\n\t\t}\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tdata: result.value as InferSchemaMap<T>[typeof key],\n\t\t};\n\t}\n\n\treturn { success: true, data: data as InferSchemaMap<T>[typeof key] };\n}\n","import type { SqliteBindings } from \"./config\";\ntype SqliteBindingObject = Record<string, unknown>;\n\nfunction isSqliteBindingValue(value: unknown): boolean {\n\tif (\n\t\tvalue === null ||\n\t\ttypeof value === \"number\" ||\n\t\ttypeof value === \"string\" ||\n\t\ttypeof value === \"bigint\" ||\n\t\tvalue instanceof Uint8Array\n\t) {\n\t\treturn true;\n\t}\n\n\tif (Array.isArray(value)) {\n\t\treturn value.every((item) => typeof item === \"number\");\n\t}\n\n\treturn false;\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n\tif (!value || typeof value !== \"object\" || Array.isArray(value)) {\n\t\treturn false;\n\t}\n\treturn Object.getPrototypeOf(value) === Object.prototype;\n}\n\nexport function isSqliteBindingObject(\n\tvalue: unknown,\n): value is SqliteBindingObject {\n\tif (!isPlainObject(value)) {\n\t\treturn false;\n\t}\n\n\treturn Object.values(value).every((entry) => isSqliteBindingValue(entry));\n}\n\nexport function isSqliteBindingArray(value: unknown): value is unknown[] {\n\treturn (\n\t\tArray.isArray(value) &&\n\t\tvalue.every((entry) => isSqliteBindingValue(entry))\n\t);\n}\n\nexport function toSqliteBindings(\n\tinput: unknown[] | SqliteBindingObject,\n): SqliteBindings {\n\tif (Array.isArray(input)) {\n\t\tfor (const value of input) {\n\t\t\tif (!isSqliteBindingValue(value)) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`unsupported sqlite binding type: ${typeof value}`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t\treturn input as SqliteBindings;\n\t}\n\n\tif (isSqliteBindingObject(input)) {\n\t\treturn input as SqliteBindings;\n\t}\n\n\tthrow new Error(\"unsupported sqlite binding collection\");\n}\n\n/**\n * Serialize async operations on a shared non-reentrant resource.\n */\nexport class AsyncMutex {\n\t#locked = false;\n\t#waiting: (() => void)[] = [];\n\n\tasync acquire(): Promise<void> {\n\t\twhile (this.#locked) {\n\t\t\tawait new Promise<void>((resolve) => this.#waiting.push(resolve));\n\t\t}\n\t\tthis.#locked = true;\n\t}\n\n\trelease(): void {\n\t\tthis.#locked = false;\n\t\tconst next = this.#waiting.shift();\n\t\tif (next) {\n\t\t\tnext();\n\t\t}\n\t}\n\n\tasync run<T>(fn: () => Promise<T>): Promise<T> {\n\t\tawait this.acquire();\n\t\ttry {\n\t\t\treturn await fn();\n\t\t} finally {\n\t\t\tthis.release();\n\t\t}\n\t}\n}\n","import type { DatabaseProvider, RawAccess, SqliteDatabase } from \"./config\";\nimport { isSqliteBindingObject, toSqliteBindings } from \"./shared\";\n\nexport type { RawAccess } from \"./config\";\n\ninterface DatabaseFactoryConfig {\n\tonMigrate?: (db: RawAccess) => Promise<void> | void;\n}\n\nfunction hasMultipleStatements(query: string): boolean {\n\tconst trimmed = query.trim().replace(/;+$/, \"\").trimEnd();\n\treturn trimmed.includes(\";\");\n}\n\nexport function db({\n\tonMigrate,\n}: DatabaseFactoryConfig = {}): DatabaseProvider<RawAccess> {\n\treturn {\n\t\tcreateClient: async (ctx) => {\n\t\t\tconst nativeDatabaseProvider = ctx.nativeDatabaseProvider;\n\t\t\tif (!nativeDatabaseProvider) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t\"native SQLite is required, but the current runtime did not provide a native database provider\",\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst db = await nativeDatabaseProvider.open(ctx.actorId);\n\t\t\tlet closed = false;\n\t\t\tconst ensureOpen = () => {\n\t\t\t\tif (closed) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\"Database is closed. This usually means a background timer (setInterval, setTimeout) or a stray promise is still running after the actor stopped. Use c.abortSignal to clean up timers before the actor shuts down.\",\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tconst client: RawAccess = {\n\t\t\t\texecute: async <\n\t\t\t\t\tTRow extends Record<string, unknown> = Record<\n\t\t\t\t\t\tstring,\n\t\t\t\t\t\tunknown\n\t\t\t\t\t>,\n\t\t\t\t>(\n\t\t\t\t\tquery: string,\n\t\t\t\t\t...args: unknown[]\n\t\t\t\t): Promise<TRow[]> => {\n\t\t\t\t\tensureOpen();\n\n\t\t\t\t\tconst kvReadsBefore = ctx.metrics?.totalKvReads ?? 0;\n\t\t\t\t\tconst kvWritesBefore = ctx.metrics?.totalKvWrites ?? 0;\n\t\t\t\t\tconst start = performance.now();\n\n\t\t\t\t\ttry {\n\t\t\t\t\t\tif (args.length > 0) {\n\t\t\t\t\t\t\tconst bindings =\n\t\t\t\t\t\t\t\targs.length === 1 &&\n\t\t\t\t\t\t\t\tisSqliteBindingObject(args[0])\n\t\t\t\t\t\t\t\t\t? toSqliteBindings(args[0])\n\t\t\t\t\t\t\t\t\t: toSqliteBindings(args);\n\t\t\t\t\t\t\tconst { rows, columns } = await db.execute(\n\t\t\t\t\t\t\t\tquery,\n\t\t\t\t\t\t\t\tbindings,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\treturn rows.map((row) =>\n\t\t\t\t\t\t\t\trowToObject<TRow>(row, columns),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (!hasMultipleStatements(query)) {\n\t\t\t\t\t\t\tconst { rows, columns } = await db.execute(query);\n\t\t\t\t\t\t\treturn rows.map((row) =>\n\t\t\t\t\t\t\t\trowToObject<TRow>(row, columns),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn await execMultiStatement<TRow>(db, query);\n\t\t\t\t\t} finally {\n\t\t\t\t\t\tconst durationMs = performance.now() - start;\n\t\t\t\t\t\tctx.metrics?.trackSql(query, durationMs);\n\t\t\t\t\t\tif (ctx.metrics) {\n\t\t\t\t\t\t\tconst kvReads =\n\t\t\t\t\t\t\t\tctx.metrics.totalKvReads - kvReadsBefore;\n\t\t\t\t\t\t\tconst kvWrites =\n\t\t\t\t\t\t\t\tctx.metrics.totalKvWrites - kvWritesBefore;\n\t\t\t\t\t\t\tctx.log?.debug({\n\t\t\t\t\t\t\t\tmsg: \"sql query\",\n\t\t\t\t\t\t\t\tquery: query.slice(0, 120),\n\t\t\t\t\t\t\t\tdurationMs,\n\t\t\t\t\t\t\t\tkvReads,\n\t\t\t\t\t\t\t\tkvWrites,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tclose: async () => {\n\t\t\t\t\tif (!closed) {\n\t\t\t\t\t\tclosed = true;\n\t\t\t\t\t\tawait db.close();\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tnativeMetrics: () => db.nativeMetrics?.() ?? null,\n\t\t\t};\n\t\t\treturn client;\n\t\t},\n\t\tonMigrate: async (client) => {\n\t\t\tif (onMigrate) {\n\t\t\t\tawait withMigrationSavepoint(client, () => onMigrate(client));\n\t\t\t}\n\t\t},\n\t};\n}\n\nfunction rowToObject<TRow extends Record<string, unknown>>(\n\trow: unknown[],\n\tcolumns: string[],\n): TRow {\n\tconst rowObj: Record<string, unknown> = {};\n\tfor (let i = 0; i < columns.length; i++) {\n\t\trowObj[columns[i]] = row[i];\n\t}\n\treturn rowObj as TRow;\n}\n\nasync function execMultiStatement<TRow extends Record<string, unknown>>(\n\tdb: SqliteDatabase,\n\tquery: string,\n): Promise<TRow[]> {\n\tconst results: Record<string, unknown>[] = [];\n\tlet columnNames: string[] | null = null;\n\tawait db.exec(query, (row: unknown[], columns: string[]) => {\n\t\tif (!columnNames) {\n\t\t\tcolumnNames = columns;\n\t\t}\n\t\tresults.push(rowToObject(row, columnNames));\n\t});\n\treturn results as TRow[];\n}\n\nasync function withMigrationSavepoint<T>(\n\tclient: RawAccess,\n\tcallback: () => Promise<T> | T,\n): Promise<T> {\n\tawait client.execute(\"SAVEPOINT __rivet_on_migrate\");\n\ttry {\n\t\tconst result = await callback();\n\t\tawait client.execute(\"RELEASE SAVEPOINT __rivet_on_migrate\");\n\t\treturn result;\n\t} catch (error) {\n\t\ttry {\n\t\t\tawait client.execute(\"ROLLBACK TO SAVEPOINT __rivet_on_migrate\");\n\t\t} finally {\n\t\t\tawait client.execute(\"RELEASE SAVEPOINT __rivet_on_migrate\");\n\t\t}\n\t\tthrow error;\n\t}\n}\n","import type {\n\tAgentOsOptions,\n\tJsonRpcNotification,\n\tPermissionRequest,\n} from \"@rivet-dev/agent-os-core\";\nimport type { ActorContext, BeforeConnectContext } from \"@/actor/config\";\nimport { z } from \"zod/v4\";\nimport type { AgentOsActorState, AgentOsActorVars } from \"./types\";\n\nconst zFunction = <\n\tT extends (...args: any[]) => any = (...args: unknown[]) => unknown,\n>() => z.custom<T>((val) => typeof val === \"function\");\n\nconst AgentOsOptionsSchema = z.custom<AgentOsOptions>(\n\t(val) => typeof val === \"object\" && val !== null,\n);\n\nexport const agentOsActorConfigSchema = z\n\t.object({\n\t\toptions: AgentOsOptionsSchema.optional(),\n\t\tpreview: z\n\t\t\t.object({\n\t\t\t\tdefaultExpiresInSeconds: z.number().positive().default(3600),\n\t\t\t\tmaxExpiresInSeconds: z.number().positive().default(86400),\n\t\t\t})\n\t\t\t.strict()\n\t\t\t.prefault(() => ({})),\n\t\tonBeforeConnect: zFunction().optional(),\n\t\tonSessionEvent: zFunction().optional(),\n\t\tonPermissionRequest: zFunction().optional(),\n\t})\n\t.strict();\n\n// --- Typed config types (generic callbacks overlaid on the Zod schema) ---\n\ntype AgentOsActorContext<TConnParams> = ActorContext<\n\tAgentOsActorState,\n\tTConnParams,\n\tundefined,\n\tAgentOsActorVars,\n\tundefined,\n\tany\n>;\n\ninterface AgentOsActorConfigCallbacks<TConnParams> {\n\tonBeforeConnect?: (\n\t\tc: BeforeConnectContext<\n\t\t\tAgentOsActorState,\n\t\t\tAgentOsActorVars,\n\t\t\tundefined,\n\t\t\tany\n\t\t>,\n\t\tparams: TConnParams,\n\t) => void | Promise<void>;\n\tonSessionEvent?: (\n\t\tc: AgentOsActorContext<TConnParams>,\n\t\tsessionId: string,\n\t\tevent: JsonRpcNotification,\n\t) => void | Promise<void>;\n\tonPermissionRequest?: (\n\t\tc: AgentOsActorContext<TConnParams>,\n\t\tsessionId: string,\n\t\trequest: PermissionRequest,\n\t) => void | Promise<void>;\n}\n\n// Parsed config (after Zod defaults/transforms applied).\nexport type AgentOsActorConfig<TConnParams = undefined> = Omit<\n\tz.infer<typeof agentOsActorConfigSchema>,\n\t\"onBeforeConnect\" | \"onSessionEvent\" | \"onPermissionRequest\"\n> &\n\tAgentOsActorConfigCallbacks<TConnParams>;\n\n// Input config (what users pass in before Zod transforms).\nexport type AgentOsActorConfigInput<TConnParams = undefined> = Omit<\n\tz.input<typeof agentOsActorConfigSchema>,\n\t\"onBeforeConnect\" | \"onSessionEvent\" | \"onPermissionRequest\"\n> &\n\tAgentOsActorConfigCallbacks<TConnParams>;\n","import type { CronAction, CronJobInfo } from \"@rivet-dev/agent-os-core\";\nimport type { AgentOsActorConfig } from \"../config\";\nimport type {\n\tAgentOsActionContext,\n\tSerializableCronAction,\n\tSerializableCronJobInfo,\n\tSerializableCronJobOptions,\n} from \"../types\";\nimport { ensureVm } from \"./index\";\n\nfunction serializeCronAction(action: CronAction): SerializableCronAction {\n\tswitch (action.type) {\n\t\tcase \"session\":\n\t\t\treturn {\n\t\t\t\ttype: \"session\",\n\t\t\t\tagentType: action.agentType,\n\t\t\t\tprompt: action.prompt,\n\t\t\t\tcwd: action.options?.cwd,\n\t\t\t};\n\t\tcase \"exec\":\n\t\t\treturn {\n\t\t\t\ttype: \"exec\",\n\t\t\t\tcommand: action.command,\n\t\t\t\targs: action.args,\n\t\t\t};\n\t\tcase \"callback\":\n\t\t\tthrow new TypeError(\"callback cron actions are not serializable\");\n\t}\n}\n\nfunction serializeCronJob(job: CronJobInfo): SerializableCronJobInfo {\n\treturn {\n\t\tid: job.id,\n\t\tschedule: job.schedule,\n\t\taction: serializeCronAction(job.action),\n\t\toverlap: job.overlap,\n\t\tlastRun: job.lastRun?.toISOString(),\n\t\tnextRun: job.nextRun?.toISOString(),\n\t\trunCount: job.runCount,\n\t\trunning: job.running,\n\t};\n}\n\n// Build cron scheduling actions for the actor factory.\nexport function buildCronActions<TConnParams>(\n\tconfig: AgentOsActorConfig<TConnParams>,\n) {\n\treturn {\n\t\tscheduleCron: async (\n\t\t\tc: AgentOsActionContext<TConnParams>,\n\t\t\toptions: SerializableCronJobOptions,\n\t\t): Promise<{ id: string }> => {\n\t\t\tconst agentOs = await ensureVm(c, config);\n\t\t\tconst job = agentOs.scheduleCron({\n\t\t\t\tid: options.id,\n\t\t\t\tschedule: options.schedule,\n\t\t\t\taction: options.action as CronAction,\n\t\t\t\toverlap: options.overlap,\n\t\t\t});\n\t\t\tc.log.info({\n\t\t\t\tmsg: \"agent-os cron job scheduled\",\n\t\t\t\tjobId: job.id,\n\t\t\t\tschedule: options.schedule,\n\t\t\t});\n\t\t\treturn { id: job.id };\n\t\t},\n\n\t\tlistCronJobs: async (\n\t\t\tc: AgentOsActionContext<TConnParams>,\n\t\t): Promise<SerializableCronJobInfo[]> => {\n\t\t\tconst agentOs = await ensureVm(c, config);\n\t\t\treturn agentOs.listCronJobs().map(serializeCronJob);\n\t\t},\n\n\t\tcancelCronJob: async (\n\t\t\tc: AgentOsActionContext<TConnParams>,\n\t\t\tid: string,\n\t\t): Promise<void> => {\n\t\t\tconst agentOs = await ensureVm(c, config);\n\t\t\tagentOs.cancelCronJob(id);\n\t\t\tc.log.info({ msg: \"agent-os cron job cancelled\", jobId: id });\n\t\t},\n\t};\n}\n","import type { AgentOsActorConfig } from \"../config\";\nimport type { AgentOsActionContext } from \"../types\";\nimport { ensureVm } from \"./index\";\n\n// Serializable fetch options for the actor action boundary.\nexport interface VmFetchOptions {\n\tmethod?: string;\n\theaders?: Record<string, string>;\n\tbody?: string | Uint8Array;\n}\n\n// Serializable fetch result returned by the actor action.\nexport interface VmFetchResult {\n\tstatus: number;\n\tstatusText: string;\n\theaders: Record<string, string>;\n\tbody: Uint8Array;\n}\n\n// Build network actions for the actor factory.\nexport function buildNetworkActions<TConnParams>(\n\tconfig: AgentOsActorConfig<TConnParams>,\n) {\n\treturn {\n\t\tvmFetch: async (\n\t\t\tc: AgentOsActionContext<TConnParams>,\n\t\t\tport: number,\n\t\t\turl: string,\n\t\t\toptions?: VmFetchOptions,\n\t\t): Promise<VmFetchResult> => {\n\t\t\tconst agentOs = await ensureVm(c, config);\n\n\t\t\tconst headers = new Headers(options?.headers);\n\t\t\tconst request = new Request(url, {\n\t\t\t\tmethod: options?.method ?? \"GET\",\n\t\t\t\theaders,\n\t\t\t\tbody: options?.body ?? null,\n\t\t\t});\n\n\t\t\tconst response = await agentOs.fetch(port, request);\n\n\t\t\t// Serialize response headers to a plain object.\n\t\t\tconst responseHeaders: Record<string, string> = {};\n\t\t\tresponse.headers.forEach((value, key) => {\n\t\t\t\tresponseHeaders[key] = value;\n\t\t\t});\n\n\t\t\tconst body = new Uint8Array(await response.arrayBuffer());\n\n\t\t\treturn {\n\t\t\t\tstatus: response.status,\n\t\t\t\tstatusText: response.statusText,\n\t\t\t\theaders: responseHeaders,\n\t\t\t\tbody,\n\t\t\t};\n\t\t},\n\t};\n}\n","import crypto from \"node:crypto\";\nimport type { DatabaseProvider } from \"@/common/database/config\";\nimport type { RequestContext } from \"@/actor/config\";\nimport type { RawAccess } from \"@/common/database/config\";\nimport type { AgentOsActorConfig } from \"../config\";\nimport type {\n\tAgentOsActionContext,\n\tAgentOsActorState,\n\tAgentOsActorVars,\n} from \"../types\";\nimport { ensureVm } from \"./index\";\n\n// Generate a 32-character lowercase alphanumeric token (a-z0-9).\n// 36^32 ~= 1.6e49 possible tokens, brute-force infeasible.\nexport function generateToken(): string {\n\tconst bytes = crypto.randomBytes(32);\n\tconst alphabet = \"abcdefghijklmnopqrstuvwxyz0123456789\";\n\tlet token = \"\";\n\tfor (let i = 0; i < 32; i++) {\n\t\ttoken += alphabet[bytes[i]! % alphabet.length];\n\t}\n\treturn token;\n}\n\n// CORS headers added to all preview proxy responses.\nconst CORS_HEADERS: Record<string, string> = {\n\t\"Access-Control-Allow-Origin\": \"*\",\n\t\"Access-Control-Allow-Methods\": \"GET, POST, PUT, DELETE, OPTIONS\",\n\t\"Access-Control-Allow-Headers\": \"*\",\n};\n\nfunction addCorsHeaders(response: Response): Response {\n\tconst headers = new Headers(response.headers);\n\tfor (const [key, value] of Object.entries(CORS_HEADERS)) {\n\t\theaders.set(key, value);\n\t}\n\treturn new Response(response.body, {\n\t\tstatus: response.status,\n\t\tstatusText: response.statusText,\n\t\theaders,\n\t});\n}\n\ntype AgentOsRequestContext<TConnParams> = RequestContext<\n\tAgentOsActorState,\n\tTConnParams,\n\tundefined,\n\tAgentOsActorVars,\n\tundefined,\n\tDatabaseProvider<RawAccess>\n>;\n\nexport function buildOnRequestHandler<TConnParams>(\n\tconfig: AgentOsActorConfig<TConnParams>,\n) {\n\treturn async (\n\t\tc: AgentOsRequestContext<TConnParams>,\n\t\trequest: Request,\n\t): Promise<Response> => {\n\t\tconst url = new URL(request.url);\n\t\tconst pathname = url.pathname;\n\n\t\t// Expect paths like /fetch/{token} or /fetch/{token}/remaining/path.\n\t\tconst match = pathname.match(/^\\/fetch\\/([a-z0-9]+)(\\/.*)?$/);\n\t\tif (!match) {\n\t\t\treturn new Response(\"Not Found\", { status: 404 });\n\t\t}\n\n\t\t// Handle OPTIONS preflight before token validation.\n\t\tif (request.method === \"OPTIONS\") {\n\t\t\treturn new Response(null, { status: 204, headers: CORS_HEADERS });\n\t\t}\n\n\t\tconst token = match[1]!;\n\t\tconst remainingPath = match[2] ?? \"/\";\n\n\t\t// Validate token from SQLite.\n\t\tconst now = Date.now();\n\t\tconst rows: { port: number }[] = await c.db.execute(\n\t\t\t`SELECT port FROM agent_os_preview_tokens WHERE token = ? AND expires_at > ?`,\n\t\t\ttoken,\n\t\t\tnow,\n\t\t);\n\n\t\tif (rows.length === 0) {\n\t\t\tc.log.warn({ msg: \"agent-os preview auth failed\", token });\n\t\t\treturn addCorsHeaders(new Response(\"Forbidden\", { status: 403 }));\n\t\t}\n\n\t\tconst port = rows[0]?.port;\n\n\t\t// Boot the VM if needed.\n\t\tconst agentOs = await ensureVm(\n\t\t\tc as AgentOsActionContext<TConnParams>,\n\t\t\tconfig,\n\t\t);\n\n\t\t// Build the request to proxy through the VM's virtual network.\n\t\tconst vmUrl = `http://localhost:${port}${remainingPath}${url.search}`;\n\t\tconst vmRequest = new Request(vmUrl, {\n\t\t\tmethod: request.method,\n\t\t\theaders: request.headers,\n\t\t\tbody: request.body,\n\t\t\tduplex: \"half\",\n\t\t} as RequestInit);\n\n\t\tconst vmResponse = await agentOs.fetch(port, vmRequest);\n\n\t\tc.log.info({\n\t\t\tmsg: \"agent-os preview request proxied\",\n\t\t\tport,\n\t\t\tmethod: request.method,\n\t\t\tpath: remainingPath,\n\t\t\tstatus: vmResponse.status,\n\t\t});\n\n\t\treturn addCorsHeaders(vmResponse);\n\t};\n}\n\nexport function buildPreviewActions<TConnParams>(\n\tconfig: AgentOsActorConfig<TConnParams>,\n) {\n\treturn {\n\t\tcreateSignedPreviewUrl: async (\n\t\t\tc: AgentOsActionContext<TConnParams>,\n\t\t\tport: number,\n\t\t\texpiresInSeconds?: number,\n\t\t): Promise<{\n\t\t\tpath: string;\n\t\t\ttoken: string;\n\t\t\tport: number;\n\t\t\texpiresAt: number;\n\t\t}> => {\n\t\t\tawait ensureVm(c, config);\n\n\t\t\tconst effectiveExpires =\n\t\t\t\texpiresInSeconds ?? config.preview.defaultExpiresInSeconds;\n\t\t\tconst maxExpires = config.preview.maxExpiresInSeconds;\n\n\t\t\tif (effectiveExpires < 1 || effectiveExpires > maxExpires) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`expiresInSeconds must be between 1 and ${maxExpires}`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst token = generateToken();\n\t\t\tconst now = Date.now();\n\t\t\tconst expiresAt = now + effectiveExpires * 1000;\n\n\t\t\t// Insert token and lazy-delete expired tokens.\n\t\t\tawait c.db.execute(\n\t\t\t\t`INSERT INTO agent_os_preview_tokens (token, port, created_at, expires_at)\n\t\t\t\t VALUES (?, ?, ?, ?)`,\n\t\t\t\ttoken,\n\t\t\t\tport,\n\t\t\t\tnow,\n\t\t\t\texpiresAt,\n\t\t\t);\n\t\t\tawait c.db.execute(\n\t\t\t\t`DELETE FROM agent_os_preview_tokens WHERE expires_at <= ?`,\n\t\t\t\tnow,\n\t\t\t);\n\n\t\t\t// Path relative to the actor's gateway URL. Full URL is\n\t\t\t// `${gatewayUrl}/request/fetch/${token}` where gatewayUrl\n\t\t\t// comes from the client's getGatewayUrl().\n\t\t\tconst path = `/request/fetch/${token}`;\n\n\t\t\tc.log.info({\n\t\t\t\tmsg: \"agent-os preview token created\",\n\t\t\t\tport,\n\t\t\t\texpiresInSeconds: effectiveExpires,\n\t\t\t});\n\n\t\t\treturn { path, token, port, expiresAt };\n\t\t},\n\n\t\texpireSignedPreviewUrl: async (\n\t\t\tc: AgentOsActionContext<TConnParams>,\n\t\t\ttoken: string,\n\t\t): Promise<void> => {\n\t\t\tawait c.db.execute(\n\t\t\t\t`DELETE FROM agent_os_preview_tokens WHERE token = ?`,\n\t\t\t\ttoken,\n\t\t\t);\n\n\t\t\tc.log.info({ msg: \"agent-os preview token expired\", token });\n\t\t},\n\t};\n}\n","import type {\n\tProcessInfo,\n\tProcessTreeNode,\n\tSpawnedProcessInfo,\n} from \"@rivet-dev/agent-os-core\";\nimport { isRivetErrorCode } from \"@/actor/errors\";\nimport type { AgentOsActorConfig } from \"../config\";\nimport type { AgentOsActionContext } from \"../types\";\nimport { ensureVm, syncPreventSleep } from \"./index\";\n\n// Infer types from AgentOs methods since @secure-exec/core is not a direct dep.\ntype ExecResult = Awaited<\n\tReturnType<import(\"@rivet-dev/agent-os-core\").AgentOs[\"exec\"]>\n>;\ntype ExecOptions = Parameters<\n\timport(\"@rivet-dev/agent-os-core\").AgentOs[\"exec\"]\n>[1];\ntype SpawnOptions = Parameters<\n\timport(\"@rivet-dev/agent-os-core\").AgentOs[\"spawn\"]\n>[2];\n\nfunction broadcastProcessEvent<TConnParams>(\n\tc: AgentOsActionContext<TConnParams>,\n\tname: \"processOutput\" | \"processExit\",\n\tpayload: unknown,\n) {\n\ttry {\n\t\tc.broadcast(name, payload);\n\t} catch (error) {\n\t\tif (isRivetErrorCode(error, \"actor\", \"stopping\")) {\n\t\t\treturn;\n\t\t}\n\t\tthrow error;\n\t}\n}\n\n// Build process execution actions for the actor factory.\nexport function buildProcessActions<TConnParams>(\n\tconfig: AgentOsActorConfig<TConnParams>,\n) {\n\treturn {\n\t\texec: async (\n\t\t\tc: AgentOsActionContext<TConnParams>,\n\t\t\tcommand: string,\n\t\t\toptions?: ExecOptions,\n\t\t): Promise<ExecResult> => {\n\t\t\tconst agentOs = await ensureVm(c, config);\n\t\t\treturn agentOs.exec(command, options);\n\t\t},\n\n\t\tspawn: async (\n\t\t\tc: AgentOsActionContext<TConnParams>,\n\t\t\tcommand: string,\n\t\t\targs: string[],\n\t\t\toptions?: SpawnOptions,\n\t\t): Promise<{ pid: number }> => {\n\t\t\tconst agentOs = await ensureVm(c, config);\n\t\t\tconst { pid } = agentOs.spawn(command, args, {\n\t\t\t\t...options,\n\t\t\t\tonStdout: (data: Uint8Array) => {\n\t\t\t\t\tbroadcastProcessEvent(c, \"processOutput\", {\n\t\t\t\t\t\tpid,\n\t\t\t\t\t\tstream: \"stdout\" as const,\n\t\t\t\t\t\tdata,\n\t\t\t\t\t});\n\t\t\t\t\toptions?.onStdout?.(data);\n\t\t\t\t},\n\t\t\t\tonStderr: (data: Uint8Array) => {\n\t\t\t\t\tbroadcastProcessEvent(c, \"processOutput\", {\n\t\t\t\t\t\tpid,\n\t\t\t\t\t\tstream: \"stderr\" as const,\n\t\t\t\t\t\tdata,\n\t\t\t\t\t});\n\t\t\t\t\toptions?.onStderr?.(data);\n\t\t\t\t},\n\t\t\t});\n\n\t\t\tc.vars.activeProcesses.add(pid);\n\t\t\tsyncPreventSleep(c);\n\t\t\tc.log.info({\n\t\t\t\tmsg: \"agent-os process spawned\",\n\t\t\t\tpid,\n\t\t\t\tcommand,\n\t\t\t});\n\n\t\t\tagentOs\n\t\t\t\t.waitProcess(pid)\n\t\t\t\t.then((exitCode) => {\n\t\t\t\t\tbroadcastProcessEvent(c, \"processExit\", { pid, exitCode });\n\t\t\t\t\tc.log.info({\n\t\t\t\t\t\tmsg: \"agent-os process exited\",\n\t\t\t\t\t\tpid,\n\t\t\t\t\t\texitCode,\n\t\t\t\t\t});\n\t\t\t\t})\n\t\t\t\t.catch(() => {\n\t\t\t\t\t// Process killed during dispose. Silently clean up.\n\t\t\t\t})\n\t\t\t\t.finally(() => {\n\t\t\t\t\tc.vars.activeProcesses.delete(pid);\n\t\t\t\t\tsyncPreventSleep(c);\n\t\t\t\t});\n\n\t\t\treturn { pid };\n\t\t},\n\n\t\twriteProcessStdin: async (\n\t\t\tc: AgentOsActionContext<TConnParams>,\n\t\t\tpid: number,\n\t\t\tdata: string | Uint8Array,\n\t\t): Promise<void> => {\n\t\t\tconst agentOs = await ensureVm(c, config);\n\t\t\tagentOs.writeProcessStdin(pid, data);\n\t\t},\n\n\t\tcloseProcessStdin: async (\n\t\t\tc: AgentOsActionContext<TConnParams>,\n\t\t\tpid: number,\n\t\t): Promise<void> => {\n\t\t\tconst agentOs = await ensureVm(c, config);\n\t\t\tagentOs.closeProcessStdin(pid);\n\t\t},\n\n\t\twaitProcess: async (\n\t\t\tc: AgentOsActionContext<TConnParams>,\n\t\t\tpid: number,\n\t\t): Promise<number> => {\n\t\t\tconst agentOs = await ensureVm(c, config);\n\t\t\treturn agentOs.waitProcess(pid);\n\t\t},\n\n\t\tlistProcesses: async (\n\t\t\tc: AgentOsActionContext<TConnParams>,\n\t\t): Promise<SpawnedProcessInfo[]> => {\n\t\t\tconst agentOs = await ensureVm(c, config);\n\t\t\treturn agentOs.listProcesses();\n\t\t},\n\n\t\tallProcesses: async (\n\t\t\tc: AgentOsActionContext<TConnParams>,\n\t\t): Promise<ProcessInfo[]> => {\n\t\t\tconst agentOs = await ensureVm(c, config);\n\t\t\treturn agentOs.allProcesses();\n\t\t},\n\n\t\tprocessTree: async (\n\t\t\tc: AgentOsActionContext<TConnParams>,\n\t\t): Promise<ProcessTreeNode[]> => {\n\t\t\tconst agentOs = await ensureVm(c, config);\n\t\t\treturn agentOs.processTree();\n\t\t},\n\n\t\tgetProcess: async (\n\t\t\tc: AgentOsActionContext<TConnParams>,\n\t\t\tpid: number,\n\t\t): Promise<SpawnedProcessInfo> => {\n\t\t\tconst agentOs = await ensureVm(c, config);\n\t\t\treturn agentOs.getProcess(pid);\n\t\t},\n\n\t\tstopProcess: async (\n\t\t\tc: AgentOsActionContext<TConnParams>,\n\t\t\tpid: number,\n\t\t): Promise<void> => {\n\t\t\tconst agentOs = await ensureVm(c, config);\n\t\t\tagentOs.stopProcess(pid);\n\t\t},\n\n\t\tkillProcess: async (\n\t\t\tc: AgentOsActionContext<TConnParams>,\n\t\t\tpid: number,\n\t\t): Promise<void> => {\n\t\t\tconst agentOs = await ensureVm(c, config);\n\t\t\tagentOs.killProcess(pid);\n\t\t},\n\t};\n}\n","import type {\n\tAgentOs,\n\tAgentType,\n\tCreateSessionOptions,\n\tGetEventsOptions,\n\tJsonRpcNotification,\n\tJsonRpcResponse,\n\tPermissionReply,\n\tSequencedEvent,\n\tSessionConfigOption,\n\tSessionInfo,\n\tSessionModeState,\n} from \"@rivet-dev/agent-os-core\";\nimport type { AgentOsActorConfig } from \"../config\";\nimport type {\n\tAgentOsActionContext,\n\tPersistedSessionEvent,\n\tPersistedSessionRecord,\n\tPromptResult,\n\tSessionRecord,\n} from \"../types\";\nimport { ensureVm, runHook, syncPreventSleep } from \"./index\";\n\n// Strip non-serializable values (functions) from agent-os-core responses so\n// CBOR/BARE encoding doesn't fail. The JsonRpcResponse objects from\n// secure-exec can contain function properties.\nfunction stripFunctions(value: unknown): unknown {\n\tif (value === null || value === undefined) return value;\n\tif (typeof value === \"function\") return undefined;\n\tif (typeof value !== \"object\") return value;\n\tif (Array.isArray(value)) return value.map(stripFunctions);\n\tconst out: Record<string, unknown> = {};\n\tfor (const [k, v] of Object.entries(value as Record<string, unknown>)) {\n\t\tif (typeof v !== \"function\") {\n\t\t\tout[k] = stripFunctions(v);\n\t\t}\n\t}\n\treturn out;\n}\n\n// Helper to verify a session exists in the VM. Throws via AgentOs if not found.\nfunction assertSessionExists<TConnParams>(\n\tc: AgentOsActionContext<TConnParams>,\n\tsessionId: string,\n): void {\n\tif (!c.vars.sessions.has(sessionId)) {\n\t\tthrow new Error(`session not found: ${sessionId}`);\n\t}\n}\n\n// Build a SessionRecord from AgentOs flat API.\nfunction toSessionRecord(\n\tagentOs: AgentOs,\n\tsessionId: string,\n\tagentType: string,\n): SessionRecord {\n\treturn {\n\t\tsessionId,\n\t\tagentType,\n\t\tcapabilities: agentOs.getSessionCapabilities(sessionId) ?? {},\n\t\tagentInfo: agentOs.getSessionAgentInfo(sessionId),\n\t};\n}\n\n// --- Session persistence helpers ---\n\n// Persist a session record to SQLite when it is created.\nasync function persistSession<TConnParams>(\n\tc: AgentOsActionContext<TConnParams>,\n\tagentOs: AgentOs,\n\tsessionId: string,\n\tagentType: string,\n): Promise<void> {\n\tconst now = Date.now();\n\tconst capabilities = agentOs.getSessionCapabilities(sessionId) ?? {};\n\tconst agentInfo = agentOs.getSessionAgentInfo(sessionId);\n\tawait c.db.execute(\n\t\t`INSERT OR REPLACE INTO agent_os_sessions (session_id, agent_type, capabilities, agent_info, created_at)\n\t\t VALUES (?, ?, ?, ?, ?)`,\n\t\tsessionId,\n\t\tagentType,\n\t\tJSON.stringify(capabilities),\n\t\tagentInfo ? JSON.stringify(agentInfo) : null,\n\t\tnow,\n\t);\n}\n\n// Persist a session event to SQLite with an auto-incrementing sequence number.\nasync function persistSessionEvent<TConnParams>(\n\tc: AgentOsActionContext<TConnParams>,\n\tsessionId: string,\n\tevent: JsonRpcNotification,\n): Promise<void> {\n\tconst now = Date.now();\n\n\t// Compute next sequence number for this session.\n\tconst rows: { max_seq: number | null }[] = await c.db.execute(\n\t\t`SELECT MAX(seq) as max_seq FROM agent_os_session_events WHERE session_id = ?`,\n\t\tsessionId,\n\t);\n\tconst nextSeq = (rows[0]?.max_seq ?? -1) + 1;\n\n\tawait c.db.execute(\n\t\t`INSERT INTO agent_os_session_events (session_id, seq, event, created_at)\n\t\t VALUES (?, ?, ?, ?)`,\n\t\tsessionId,\n\t\tnextSeq,\n\t\tJSON.stringify(event),\n\t\tnow,\n\t);\n}\n\n// Remove a session and its events from SQLite.\nasync function deletePersistedSession<TConnParams>(\n\tc: AgentOsActionContext<TConnParams>,\n\tsessionId: string,\n): Promise<void> {\n\tawait c.db.execute(\n\t\t`DELETE FROM agent_os_session_events WHERE session_id = ?`,\n\t\tsessionId,\n\t);\n\tawait c.db.execute(\n\t\t`DELETE FROM agent_os_sessions WHERE session_id = ?`,\n\t\tsessionId,\n\t);\n}\n\n// Subscribe to a session's event and permission streams via the flat AgentOs API,\n// broadcasting events and running user-provided hooks.\nexport function subscribeToSession<TConnParams>(\n\tc: AgentOsActionContext<TConnParams>,\n\tagentOs: AgentOs,\n\tsessionId: string,\n\tparsedConfig: AgentOsActorConfig<TConnParams>,\n): void {\n\tagentOs.onSessionEvent(sessionId, (event) => {\n\t\tc.broadcast(\n\t\t\t\"sessionEvent\",\n\t\t\tJSON.parse(JSON.stringify({ sessionId, event })),\n\t\t);\n\n\t\t// Persist event to SQLite for sleep/wake recovery.\n\t\tpersistSessionEvent(c, sessionId, event).catch((err) =>\n\t\t\tc.log.error({\n\t\t\t\tmsg: \"agent-os failed to persist session event\",\n\t\t\t\tsessionId,\n\t\t\t\terror: err,\n\t\t\t}),\n\t\t);\n\n\t\tif (parsedConfig.onSessionEvent) {\n\t\t\trunHook(c, \"onSessionEvent\", () =>\n\t\t\t\tparsedConfig.onSessionEvent?.(c, sessionId, event),\n\t\t\t);\n\t\t}\n\t});\n\n\tagentOs.onPermissionRequest(sessionId, (request) => {\n\t\tc.broadcast(\n\t\t\t\"permissionRequest\",\n\t\t\tJSON.parse(JSON.stringify({ sessionId, request })),\n\t\t);\n\n\t\tif (parsedConfig.onPermissionRequest) {\n\t\t\trunHook(c, \"onPermissionRequest\", () =>\n\t\t\t\tparsedConfig.onPermissionRequest?.(c, sessionId, request),\n\t\t\t);\n\t\t}\n\t});\n\n\tc.vars.sessions.add(sessionId);\n}\n\n// Build session management actions for the actor factory.\nexport function buildSessionActions<TConnParams>(\n\tconfig: AgentOsActorConfig<TConnParams>,\n) {\n\treturn {\n\t\tcreateSession: async (\n\t\t\tc: AgentOsActionContext<TConnParams>,\n\t\t\tagentType: AgentType,\n\t\t\toptions?: CreateSessionOptions,\n\t\t): Promise<SessionRecord> => {\n\t\t\tconst agentOs = await ensureVm(c, config);\n\t\t\tconst { sessionId } = await agentOs.createSession(\n\t\t\t\tagentType,\n\t\t\t\toptions,\n\t\t\t);\n\t\t\tsubscribeToSession(c, agentOs, sessionId, config);\n\n\t\t\t// Persist session metadata to SQLite for sleep/wake recovery.\n\t\t\tawait persistSession(c, agentOs, sessionId, agentType);\n\n\t\t\tc.log.info({\n\t\t\t\tmsg: \"agent-os session created\",\n\t\t\t\tsessionId,\n\t\t\t\tagentType,\n\t\t\t});\n\t\t\treturn toSessionRecord(agentOs, sessionId, agentType);\n\t\t},\n\n\t\tlistSessions: async (\n\t\t\tc: AgentOsActionContext<TConnParams>,\n\t\t): Promise<SessionInfo[]> => {\n\t\t\tconst agentOs = await ensureVm(c, config);\n\t\t\treturn agentOs.listSessions();\n\t\t},\n\n\t\tgetSession: async (\n\t\t\tc: AgentOsActionContext<TConnParams>,\n\t\t\tsessionId: string,\n\t\t): Promise<SessionRecord> => {\n\t\t\tassertSessionExists(c, sessionId);\n\t\t\tconst agentOs = await ensureVm(c, config);\n\t\t\tconst info = agentOs\n\t\t\t\t.listSessions()\n\t\t\t\t.find((s) => s.sessionId === sessionId);\n\t\t\tif (!info) {\n\t\t\t\tthrow new Error(`session not found: ${sessionId}`);\n\t\t\t}\n\t\t\treturn toSessionRecord(agentOs, sessionId, info.agentType);\n\t\t},\n\n\t\tdestroySession: async (\n\t\t\tc: AgentOsActionContext<TConnParams>,\n\t\t\tsessionId: string,\n\t\t): Promise<void> => {\n\t\t\tconst agentOs = await ensureVm(c, config);\n\t\t\tawait agentOs.destroySession(sessionId);\n\t\t\tc.vars.sessions.delete(sessionId);\n\t\t\tc.vars.activeSessionIds.delete(sessionId);\n\t\t\tsyncPreventSleep(c);\n\n\t\t\t// Clean up persisted session and events from SQLite.\n\t\t\tawait deletePersistedSession(c, sessionId);\n\n\t\t\tc.log.info({ msg: \"agent-os session destroyed\", sessionId });\n\t\t},\n\n\t\tresumeSession: async (\n\t\t\tc: AgentOsActionContext<TConnParams>,\n\t\t\tsessionId: string,\n\t\t): Promise<{ sessionId: string }> => {\n\t\t\tconst agentOs = await ensureVm(c, config);\n\t\t\treturn agentOs.resumeSession(sessionId);\n\t\t},\n\n\t\tcloseSession: async (\n\t\t\tc: AgentOsActionContext<TConnParams>,\n\t\t\tsessionId: string,\n\t\t): Promise<void> => {\n\t\t\tconst agentOs = await ensureVm(c, config);\n\t\t\tagentOs.closeSession(sessionId);\n\t\t\tc.vars.sessions.delete(sessionId);\n\t\t\tc.vars.activeSessionIds.delete(sessionId);\n\t\t\tsyncPreventSleep(c);\n\n\t\t\t// Clean up persisted session and events from SQLite.\n\t\t\tawait deletePersistedSession(c, sessionId);\n\n\t\t\tc.log.info({ msg: \"agent-os session closed\", sessionId });\n\t\t},\n\t};\n}\n\n// Build prompt, cancel, and permission actions for the actor factory.\nexport function buildPromptActions<TConnParams>(\n\t_config: AgentOsActorConfig<TConnParams>,\n) {\n\treturn {\n\t\tsendPrompt: async (\n\t\t\tc: AgentOsActionContext<TConnParams>,\n\t\t\tsessionId: string,\n\t\t\ttext: string,\n\t\t): Promise<PromptResult> => {\n\t\t\tif (c.aborted) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t\"actor is shutting down, cannot start new prompt\",\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tassertSessionExists(c, sessionId);\n\t\t\tconst agentOs = c.vars.agentOs;\n\t\t\tif (!agentOs) {\n\t\t\t\tthrow new Error(\"VM not initialized\");\n\t\t\t}\n\n\t\t\tc.vars.activeSessionIds.add(sessionId);\n\t\t\tsyncPreventSleep(c);\n\t\t\tc.log.info({ msg: \"agent-os prompt turn started\", sessionId });\n\n\t\t\tconst start = Date.now();\n\t\t\ttry {\n\t\t\t\tconst result = await agentOs.prompt(sessionId, text);\n\t\t\t\treturn {\n\t\t\t\t\tresponse: JSON.parse(JSON.stringify(result.response)),\n\t\t\t\t\ttext: result.text,\n\t\t\t\t};\n\t\t\t} finally {\n\t\t\t\tc.vars.activeSessionIds.delete(sessionId);\n\t\t\t\tsyncPreventSleep(c);\n\t\t\t\tc.log.info({\n\t\t\t\t\tmsg: \"agent-os prompt turn ended\",\n\t\t\t\t\tsessionId,\n\t\t\t\t\tdurationMs: Date.now() - start,\n\t\t\t\t});\n\t\t\t}\n\t\t},\n\n\t\tcancelPrompt: async (\n\t\t\tc: AgentOsActionContext<TConnParams>,\n\t\t\tsessionId: string,\n\t\t): Promise<JsonRpcResponse> => {\n\t\t\tassertSessionExists(c, sessionId);\n\t\t\tconst agentOs = c.vars.agentOs;\n\t\t\tif (!agentOs) {\n\t\t\t\tthrow new Error(\"VM not initialized\");\n\t\t\t}\n\t\t\treturn stripFunctions(\n\t\t\t\tagentOs.cancelSession(sessionId),\n\t\t\t) as JsonRpcResponse;\n\t\t},\n\n\t\trespondPermission: async (\n\t\t\tc: AgentOsActionContext<TConnParams>,\n\t\t\tsessionId: string,\n\t\t\tpermissionId: string,\n\t\t\treply: PermissionReply,\n\t\t): Promise<JsonRpcResponse> => {\n\t\t\tassertSessionExists(c, sessionId);\n\t\t\tconst agentOs = c.vars.agentOs;\n\t\t\tif (!agentOs) {\n\t\t\t\tthrow new Error(\"VM not initialized\");\n\t\t\t}\n\t\t\treturn stripFunctions(\n\t\t\t\tagentOs.respondPermission(sessionId, permissionId, reply),\n\t\t\t) as JsonRpcResponse;\n\t\t},\n\t};\n}\n\n// Build session configuration proxy actions for the actor factory.\nexport function buildConfigActions<TConnParams>(\n\t_config: AgentOsActorConfig<TConnParams>,\n) {\n\treturn {\n\t\tsetMode: async (\n\t\t\tc: AgentOsActionContext<TConnParams>,\n\t\t\tsessionId: string,\n\t\t\tmodeId: string,\n\t\t): Promise<JsonRpcResponse> => {\n\t\t\tassertSessionExists(c, sessionId);\n\t\t\tconst agentOs = c.vars.agentOs;\n\t\t\tif (!agentOs) {\n\t\t\t\tthrow new Error(\"VM not initialized\");\n\t\t\t}\n\t\t\treturn stripFunctions(\n\t\t\t\tagentOs.setSessionMode(sessionId, modeId),\n\t\t\t) as JsonRpcResponse;\n\t\t},\n\n\t\tgetModes: async (\n\t\t\tc: AgentOsActionContext<TConnParams>,\n\t\t\tsessionId: string,\n\t\t): Promise<SessionModeState | null> => {\n\t\t\tassertSessionExists(c, sessionId);\n\t\t\tconst agentOs = c.vars.agentOs;\n\t\t\tif (!agentOs) {\n\t\t\t\tthrow new Error(\"VM not initialized\");\n\t\t\t}\n\t\t\treturn agentOs.getSessionModes(sessionId);\n\t\t},\n\n\t\tsetModel: async (\n\t\t\tc: AgentOsActionContext<TConnParams>,\n\t\t\tsessionId: string,\n\t\t\tmodel: string,\n\t\t): Promise<JsonRpcResponse> => {\n\t\t\tassertSessionExists(c, sessionId);\n\t\t\tconst agentOs = c.vars.agentOs;\n\t\t\tif (!agentOs) {\n\t\t\t\tthrow new Error(\"VM not initialized\");\n\t\t\t}\n\t\t\treturn stripFunctions(\n\t\t\t\tagentOs.setSessionModel(sessionId, model),\n\t\t\t) as JsonRpcResponse;\n\t\t},\n\n\t\tsetThoughtLevel: async (\n\t\t\tc: AgentOsActionContext<TConnParams>,\n\t\t\tsessionId: string,\n\t\t\tlevel: string,\n\t\t): Promise<JsonRpcResponse> => {\n\t\t\tassertSessionExists(c, sessionId);\n\t\t\tconst agentOs = c.vars.agentOs;\n\t\t\tif (!agentOs) {\n\t\t\t\tthrow new Error(\"VM not initialized\");\n\t\t\t}\n\t\t\treturn stripFunctions(\n\t\t\t\tagentOs.setSessionThoughtLevel(sessionId, level),\n\t\t\t) as JsonRpcResponse;\n\t\t},\n\n\t\tgetConfigOptions: async (\n\t\t\tc: AgentOsActionContext<TConnParams>,\n\t\t\tsessionId: string,\n\t\t): Promise<SessionConfigOption[]> => {\n\t\t\tassertSessionExists(c, sessionId);\n\t\t\tconst agentOs = c.vars.agentOs;\n\t\t\tif (!agentOs) {\n\t\t\t\tthrow new Error(\"VM not initialized\");\n\t\t\t}\n\t\t\treturn agentOs.getSessionConfigOptions(sessionId);\n\t\t},\n\n\t\tgetEvents: async (\n\t\t\tc: AgentOsActionContext<TConnParams>,\n\t\t\tsessionId: string,\n\t\t\toptions?: GetEventsOptions,\n\t\t): Promise<JsonRpcNotification[]> => {\n\t\t\tassertSessionExists(c, sessionId);\n\t\t\tconst agentOs = c.vars.agentOs;\n\t\t\tif (!agentOs) {\n\t\t\t\tthrow new Error(\"VM not initialized\");\n\t\t\t}\n\t\t\treturn agentOs\n\t\t\t\t.getSessionEvents(sessionId, options)\n\t\t\t\t.map((e) => e.notification);\n\t\t},\n\n\t\tgetSequencedEvents: async (\n\t\t\tc: AgentOsActionContext<TConnParams>,\n\t\t\tsessionId: string,\n\t\t\toptions?: GetEventsOptions,\n\t\t): Promise<SequencedEvent[]> => {\n\t\t\tassertSessionExists(c, sessionId);\n\t\t\tconst agentOs = c.vars.agentOs;\n\t\t\tif (!agentOs) {\n\t\t\t\tthrow new Error(\"VM not initialized\");\n\t\t\t}\n\t\t\treturn agentOs.getSessionEvents(sessionId, options);\n\t\t},\n\n\t\trawSend: async (\n\t\t\tc: AgentOsActionContext<TConnParams>,\n\t\t\tsessionId: string,\n\t\t\tmethod: string,\n\t\t\tparams?: Record<string, unknown>,\n\t\t): Promise<JsonRpcResponse> => {\n\t\t\tassertSessionExists(c, sessionId);\n\t\t\tconst agentOs = c.vars.agentOs;\n\t\t\tif (!agentOs) {\n\t\t\t\tthrow new Error(\"VM not initialized\");\n\t\t\t}\n\t\t\treturn stripFunctions(\n\t\t\t\tagentOs.rawSessionSend(sessionId, method, params),\n\t\t\t) as JsonRpcResponse;\n\t\t},\n\t};\n}\n\n// Build actions for querying persisted session data from SQLite.\n// These work without a running VM and return data from prior sessions\n// that survived sleep/wake cycles.\nexport function buildSessionPersistenceActions<TConnParams>(\n\t_config: AgentOsActorConfig<TConnParams>,\n) {\n\treturn {\n\t\tlistPersistedSessions: async (\n\t\t\tc: AgentOsActionContext<TConnParams>,\n\t\t): Promise<PersistedSessionRecord[]> => {\n\t\t\tconst rows: {\n\t\t\t\tsession_id: string;\n\t\t\t\tagent_type: string;\n\t\t\t\tcapabilities: string;\n\t\t\t\tagent_info: string | null;\n\t\t\t\tcreated_at: number;\n\t\t\t}[] = await c.db.execute(\n\t\t\t\t`SELECT session_id, agent_type, capabilities, agent_info, created_at\n\t\t\t\t FROM agent_os_sessions\n\t\t\t\t ORDER BY created_at ASC`,\n\t\t\t);\n\n\t\t\treturn rows.map((row) => ({\n\t\t\t\tsessionId: row.session_id,\n\t\t\t\tagentType: row.agent_type,\n\t\t\t\tcapabilities: JSON.parse(row.capabilities),\n\t\t\t\tagentInfo: row.agent_info ? JSON.parse(row.agent_info) : null,\n\t\t\t\tcreatedAt: row.created_at,\n\t\t\t}));\n\t\t},\n\n\t\tgetSessionEvents: async (\n\t\t\tc: AgentOsActionContext<TConnParams>,\n\t\t\tsessionId: string,\n\t\t): Promise<PersistedSessionEvent[]> => {\n\t\t\tconst rows: {\n\t\t\t\tsession_id: string;\n\t\t\t\tseq: number;\n\t\t\t\tevent: string;\n\t\t\t\tcreated_at: number;\n\t\t\t}[] = await c.db.execute(\n\t\t\t\t`SELECT session_id, seq, event, created_at\n\t\t\t\t FROM agent_os_session_events\n\t\t\t\t WHERE session_id = ?\n\t\t\t\t ORDER BY seq ASC`,\n\t\t\t\tsessionId,\n\t\t\t);\n\n\t\t\treturn rows.map((row) => ({\n\t\t\t\tsessionId: row.session_id,\n\t\t\t\tseq: row.seq,\n\t\t\t\tevent: JSON.parse(row.event),\n\t\t\t\tcreatedAt: row.created_at,\n\t\t\t}));\n\t\t},\n\t};\n}\n","import type { OpenShellOptions } from \"@rivet-dev/agent-os-core\";\nimport type { AgentOsActorConfig } from \"../config\";\nimport type { AgentOsActionContext } from \"../types\";\nimport { ensureVm, syncPreventSleep } from \"./index\";\n\n// Build shell actions for the actor factory.\nexport function buildShellActions<TConnParams>(\n\tconfig: AgentOsActorConfig<TConnParams>,\n) {\n\treturn {\n\t\topenShell: async (\n\t\t\tc: AgentOsActionContext<TConnParams>,\n\t\t\toptions?: OpenShellOptions,\n\t\t): Promise<{ shellId: string }> => {\n\t\t\tconst agentOs = await ensureVm(c, config);\n\t\t\tconst { shellId } = agentOs.openShell(options);\n\n\t\t\t// Wire shell data to actor events.\n\t\t\tagentOs.onShellData(shellId, (data: Uint8Array) => {\n\t\t\t\tc.broadcast(\"shellData\", { shellId, data });\n\t\t\t});\n\n\t\t\tc.vars.activeShells.add(shellId);\n\t\t\tsyncPreventSleep(c);\n\t\t\tc.log.info({ msg: \"agent-os shell opened\", shellId });\n\n\t\t\treturn { shellId };\n\t\t},\n\n\t\twriteShell: async (\n\t\t\tc: AgentOsActionContext<TConnParams>,\n\t\t\tshellId: string,\n\t\t\tdata: string | Uint8Array,\n\t\t): Promise<void> => {\n\t\t\tconst agentOs = await ensureVm(c, config);\n\t\t\tagentOs.writeShell(shellId, data);\n\t\t},\n\n\t\tresizeShell: async (\n\t\t\tc: AgentOsActionContext<TConnParams>,\n\t\t\tshellId: string,\n\t\t\tcols: number,\n\t\t\trows: number,\n\t\t): Promise<void> => {\n\t\t\tconst agentOs = await ensureVm(c, config);\n\t\t\tagentOs.resizeShell(shellId, cols, rows);\n\t\t},\n\n\t\tcloseShell: async (\n\t\t\tc: AgentOsActionContext<TConnParams>,\n\t\t\tshellId: string,\n\t\t): Promise<void> => {\n\t\t\tconst agentOs = await ensureVm(c, config);\n\t\t\tagentOs.closeShell(shellId);\n\t\t\tc.vars.activeShells.delete(shellId);\n\t\t\tsyncPreventSleep(c);\n\t\t\tc.log.info({ msg: \"agent-os shell closed\", shellId });\n\t\t},\n\t};\n}\n","import type {\n\tAgentRegistryEntry,\n\tBatchReadResult,\n\tBatchWriteEntry,\n\tBatchWriteResult,\n\tDirEntry,\n\tReaddirRecursiveOptions,\n} from \"@rivet-dev/agent-os-core\";\nimport type { AgentOsActorConfig } from \"../config\";\nimport type { AgentOsActionContext } from \"../types\";\nimport { ensureVm } from \"./index\";\n\n// Infer types from AgentOs methods since @secure-exec/core is not a direct dep.\ntype VirtualStat = Awaited<\n\tReturnType<import(\"@rivet-dev/agent-os-core\").AgentOs[\"stat\"]>\n>;\ntype DeleteOptions = Parameters<\n\timport(\"@rivet-dev/agent-os-core\").AgentOs[\"delete\"]\n>[1];\n\n// Build filesystem and agent registry actions for the actor factory.\nexport function buildFilesystemActions<TConnParams>(\n\tconfig: AgentOsActorConfig<TConnParams>,\n) {\n\treturn {\n\t\treadFile: async (\n\t\t\tc: AgentOsActionContext<TConnParams>,\n\t\t\tpath: string,\n\t\t): Promise<Uint8Array> => {\n\t\t\tconst agentOs = await ensureVm(c, config);\n\t\t\treturn agentOs.readFile(path);\n\t\t},\n\n\t\twriteFile: async (\n\t\t\tc: AgentOsActionContext<TConnParams>,\n\t\t\tpath: string,\n\t\t\tcontent: string | Uint8Array,\n\t\t): Promise<void> => {\n\t\t\tconst agentOs = await ensureVm(c, config);\n\t\t\tawait agentOs.writeFile(path, content);\n\t\t},\n\n\t\treadFiles: async (\n\t\t\tc: AgentOsActionContext<TConnParams>,\n\t\t\tpaths: string[],\n\t\t): Promise<BatchReadResult[]> => {\n\t\t\tconst agentOs = await ensureVm(c, config);\n\t\t\treturn agentOs.readFiles(paths);\n\t\t},\n\n\t\twriteFiles: async (\n\t\t\tc: AgentOsActionContext<TConnParams>,\n\t\t\tentries: BatchWriteEntry[],\n\t\t): Promise<BatchWriteResult[]> => {\n\t\t\tconst agentOs = await ensureVm(c, config);\n\t\t\treturn agentOs.writeFiles(entries);\n\t\t},\n\n\t\tmkdir: async (\n\t\t\tc: AgentOsActionContext<TConnParams>,\n\t\t\tpath: string,\n\t\t\toptions?: { recursive?: boolean },\n\t\t): Promise<void> => {\n\t\t\tconst agentOs = await ensureVm(c, config);\n\t\t\tawait agentOs.mkdir(path, options);\n\t\t},\n\n\t\treaddir: async (\n\t\t\tc: AgentOsActionContext<TConnParams>,\n\t\t\tpath: string,\n\t\t): Promise<string[]> => {\n\t\t\tconst agentOs = await ensureVm(c, config);\n\t\t\treturn agentOs.readdir(path);\n\t\t},\n\n\t\treaddirRecursive: async (\n\t\t\tc: AgentOsActionContext<TConnParams>,\n\t\t\tpath: string,\n\t\t\toptions?: ReaddirRecursiveOptions,\n\t\t): Promise<DirEntry[]> => {\n\t\t\tconst agentOs = await ensureVm(c, config);\n\t\t\treturn agentOs.readdirRecursive(path, options);\n\t\t},\n\n\t\tstat: async (\n\t\t\tc: AgentOsActionContext<TConnParams>,\n\t\t\tpath: string,\n\t\t): Promise<VirtualStat> => {\n\t\t\tconst agentOs = await ensureVm(c, config);\n\t\t\treturn agentOs.stat(path);\n\t\t},\n\n\t\texists: async (\n\t\t\tc: AgentOsActionContext<TConnParams>,\n\t\t\tpath: string,\n\t\t): Promise<boolean> => {\n\t\t\tconst agentOs = await ensureVm(c, config);\n\t\t\treturn agentOs.exists(path);\n\t\t},\n\n\t\tmove: async (\n\t\t\tc: AgentOsActionContext<TConnParams>,\n\t\t\tfrom: string,\n\t\t\tto: string,\n\t\t): Promise<void> => {\n\t\t\tconst agentOs = await ensureVm(c, config);\n\t\t\tawait agentOs.move(from, to);\n\t\t},\n\n\t\tdeleteFile: async (\n\t\t\tc: AgentOsActionContext<TConnParams>,\n\t\t\tpath: string,\n\t\t\toptions?: DeleteOptions,\n\t\t): Promise<void> => {\n\t\t\tconst agentOs = await ensureVm(c, config);\n\t\t\tawait agentOs.delete(path, options);\n\t\t},\n\n\t\t// TODO: mountFs and unmountFs are not exposed as actor actions because\n\t\t// filesystem drivers (VirtualFileSystem) are not serializable over the\n\t\t// network. Mount filesystems via the `options.mounts` config in agentOs()\n\t\t// instead. See: https://github.com/rivet-dev/rivet/issues/XXXX\n\n\t\tlistAgents: async (\n\t\t\tc: AgentOsActionContext<TConnParams>,\n\t\t): Promise<AgentRegistryEntry[]> => {\n\t\t\tconst agentOs = await ensureVm(c, config);\n\t\t\treturn agentOs.listAgents();\n\t\t},\n\t};\n}\n"]}
|