rivetkit 2.3.27 → 2.3.28

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.
Files changed (85) hide show
  1. package/dist/browser/client.js +1 -4
  2. package/dist/browser/client.js.map +1 -1
  3. package/dist/browser/inspector/client.js +1 -4
  4. package/dist/browser/inspector/client.js.map +1 -1
  5. package/dist/tsup/agent-os/index.cjs +3 -2652
  6. package/dist/tsup/agent-os/index.cjs.map +1 -1
  7. package/dist/tsup/agent-os/index.d.cts +1 -2717
  8. package/dist/tsup/agent-os/index.d.ts +1 -2717
  9. package/dist/tsup/agent-os/index.js +3 -2652
  10. package/dist/tsup/agent-os/index.js.map +1 -1
  11. package/dist/tsup/{chunk-DIIXK2AW.js → chunk-3EYXDC64.js} +6 -6
  12. package/dist/tsup/chunk-3EYXDC64.js.map +1 -0
  13. package/dist/tsup/{chunk-HD5Y64WY.cjs → chunk-3X3QZVH6.cjs} +141 -141
  14. package/dist/tsup/chunk-3X3QZVH6.cjs.map +1 -0
  15. package/dist/tsup/{chunk-36WJAWHE.cjs → chunk-4LMR7FES.cjs} +7 -7
  16. package/dist/tsup/{chunk-36WJAWHE.cjs.map → chunk-4LMR7FES.cjs.map} +1 -1
  17. package/dist/tsup/{chunk-NEECPYAK.cjs → chunk-67PPGBOA.cjs} +3 -3
  18. package/dist/tsup/{chunk-NEECPYAK.cjs.map → chunk-67PPGBOA.cjs.map} +1 -1
  19. package/dist/tsup/{chunk-2WAICEBJ.cjs → chunk-DRG3YQ42.cjs} +3 -3
  20. package/dist/tsup/{chunk-2WAICEBJ.cjs.map → chunk-DRG3YQ42.cjs.map} +1 -1
  21. package/dist/tsup/{chunk-UR6UKRJW.cjs → chunk-FHZZ6PLK.cjs} +2 -5
  22. package/dist/tsup/chunk-FHZZ6PLK.cjs.map +1 -0
  23. package/dist/tsup/{chunk-NRYPHQWQ.js → chunk-IKMLO5KS.js} +4 -4
  24. package/dist/tsup/{chunk-M763VP2Z.js → chunk-KJBV7M2J.js} +3 -3
  25. package/dist/tsup/{chunk-PIRTTV4D.js → chunk-QLIVFNLT.js} +2 -2
  26. package/dist/tsup/{chunk-WU6DYFFQ.cjs → chunk-S5EZP52Q.cjs} +3 -3
  27. package/dist/tsup/{chunk-WU6DYFFQ.cjs.map → chunk-S5EZP52Q.cjs.map} +1 -1
  28. package/dist/tsup/{chunk-6JIDCRGT.cjs → chunk-SRRUW63T.cjs} +4 -4
  29. package/dist/tsup/{chunk-6JIDCRGT.cjs.map → chunk-SRRUW63T.cjs.map} +1 -1
  30. package/dist/tsup/{chunk-SREEDRMF.js → chunk-SWESH3VP.js} +2 -2
  31. package/dist/tsup/{chunk-ISPGIGCR.js → chunk-UEQ5NN24.js} +2 -2
  32. package/dist/tsup/{chunk-TCZ2DONE.js → chunk-WB3BJJWJ.js} +2 -5
  33. package/dist/tsup/chunk-WB3BJJWJ.js.map +1 -0
  34. package/dist/tsup/{chunk-AGGXTWDS.cjs → chunk-XQIPFU3I.cjs} +10 -10
  35. package/dist/tsup/{chunk-AGGXTWDS.cjs.map → chunk-XQIPFU3I.cjs.map} +1 -1
  36. package/dist/tsup/{chunk-V43A2WB2.js → chunk-XQVCT3CM.js} +2 -2
  37. package/dist/tsup/client/mod.cjs +5 -5
  38. package/dist/tsup/client/mod.js +4 -4
  39. package/dist/tsup/common/log.cjs +2 -2
  40. package/dist/tsup/common/log.js +1 -1
  41. package/dist/tsup/common/websocket.cjs +3 -3
  42. package/dist/tsup/common/websocket.js +2 -2
  43. package/dist/tsup/db/drizzle.cjs +2 -2
  44. package/dist/tsup/db/drizzle.js +1 -1
  45. package/dist/tsup/db/mod.cjs +3 -3
  46. package/dist/tsup/db/mod.js +2 -2
  47. package/dist/tsup/inspector/mod.cjs +5 -5
  48. package/dist/tsup/inspector/mod.js +4 -4
  49. package/dist/tsup/inspector/workflow.cjs +4 -4
  50. package/dist/tsup/inspector/workflow.js +3 -3
  51. package/dist/tsup/mod.cjs +84 -84
  52. package/dist/tsup/mod.cjs.map +1 -1
  53. package/dist/tsup/mod.js +5 -5
  54. package/dist/tsup/test/mod.cjs +6 -6
  55. package/dist/tsup/test/mod.js +4 -4
  56. package/dist/tsup/utils.cjs +2 -2
  57. package/dist/tsup/utils.js +1 -1
  58. package/dist/tsup/workflow/mod.cjs +7 -7
  59. package/dist/tsup/workflow/mod.js +4 -4
  60. package/package.json +9 -12
  61. package/src/agent-os/index.ts +5 -65
  62. package/src/client/actor-handle.ts +3 -1
  63. package/src/client/client.ts +8 -4
  64. package/dist/tsup/chunk-DIIXK2AW.js.map +0 -1
  65. package/dist/tsup/chunk-HD5Y64WY.cjs.map +0 -1
  66. package/dist/tsup/chunk-TCZ2DONE.js.map +0 -1
  67. package/dist/tsup/chunk-UR6UKRJW.cjs.map +0 -1
  68. package/src/agent-os/actor/cron.ts +0 -84
  69. package/src/agent-os/actor/db.ts +0 -54
  70. package/src/agent-os/actor/filesystem.ts +0 -131
  71. package/src/agent-os/actor/index.ts +0 -285
  72. package/src/agent-os/actor/network.ts +0 -58
  73. package/src/agent-os/actor/preview.ts +0 -190
  74. package/src/agent-os/actor/process.ts +0 -177
  75. package/src/agent-os/actor/session.ts +0 -518
  76. package/src/agent-os/actor/shell.ts +0 -60
  77. package/src/agent-os/config.ts +0 -79
  78. package/src/agent-os/fs/database-vfs.ts +0 -624
  79. package/src/agent-os/types.ts +0 -148
  80. /package/dist/tsup/{chunk-NRYPHQWQ.js.map → chunk-IKMLO5KS.js.map} +0 -0
  81. /package/dist/tsup/{chunk-M763VP2Z.js.map → chunk-KJBV7M2J.js.map} +0 -0
  82. /package/dist/tsup/{chunk-PIRTTV4D.js.map → chunk-QLIVFNLT.js.map} +0 -0
  83. /package/dist/tsup/{chunk-SREEDRMF.js.map → chunk-SWESH3VP.js.map} +0 -0
  84. /package/dist/tsup/{chunk-ISPGIGCR.js.map → chunk-UEQ5NN24.js.map} +0 -0
  85. /package/dist/tsup/{chunk-V43A2WB2.js.map → chunk-XQVCT3CM.js.map} +0 -0
@@ -1,2654 +1,5 @@
1
- // src/agent-os/actor/index.ts
2
- import { AgentOs, createInMemoryFileSystem } from "@rivet-dev/agent-os-core";
3
-
4
- // src/actor/config.ts
5
- import { z } from "zod/v4";
6
-
7
- // src/actor/actions.ts
8
- function flattenActionHandlers(actions) {
9
- const flattened = /* @__PURE__ */ Object.create(null);
10
- for (const { name, handler } of collectActionEntries(actions)) {
11
- flattened[name] = handler;
12
- }
13
- return flattened;
14
- }
15
- function flattenActionInputSchemas(actions, schemas) {
16
- if (schemas === void 0) return void 0;
17
- if (!isRecord(schemas)) {
18
- throw new TypeError("actionInputSchemas must be an object");
19
- }
20
- const flattened = /* @__PURE__ */ Object.create(null);
21
- for (const { name, path } of collectActionEntries(actions)) {
22
- const nestedSchema = lookupNestedSchema(schemas, path);
23
- const flatSchema = schemas[name];
24
- if (nestedSchema !== void 0 && flatSchema !== void 0 && nestedSchema !== flatSchema) {
25
- throw new TypeError(
26
- `Action input schema \`${name}\` is defined by both a nested path and a dotted key`
27
- );
28
- }
29
- const schema = nestedSchema ?? flatSchema;
30
- if (schema !== void 0) {
31
- flattened[name] = schema;
32
- }
33
- }
34
- return flattened;
35
- }
36
- function flattenActionTraceSamplers(actions, rates = {}) {
37
- const handlers = flattenActionHandlers(actions);
38
- const flattened = Object.fromEntries(flattenSampleRates(rates, []));
39
- for (const name of Object.keys(flattened)) {
40
- if (!Object.hasOwn(handlers, name)) {
41
- throw new TypeError(
42
- `tracing.actions.${name} does not name an action`
43
- );
44
- }
45
- }
46
- return flattened;
47
- }
48
- function flattenSampleRates(rates, path) {
49
- return Object.entries(rates).flatMap(
50
- ([segment, rate]) => {
51
- const childPath = [...path, segment];
52
- return typeof rate === "number" ? [[childPath.join("."), rate]] : flattenSampleRates(rate, childPath);
53
- }
54
- );
55
- }
56
- function collectActionEntries(actions) {
57
- const entries = [];
58
- const names = /* @__PURE__ */ new Set();
59
- visitActionGroup(actions ?? {}, [], entries, names);
60
- return entries;
61
- }
62
- function visitActionGroup(value, path, entries, names) {
63
- if (!isRecord(value)) {
64
- throw new TypeError(
65
- `${formatActionPath(path)} must be an action handler or group`
66
- );
67
- }
68
- for (const [segment, child] of Object.entries(value)) {
69
- const childPath = [...path, segment];
70
- if (typeof child === "function") {
71
- const name = childPath.join(".");
72
- if (names.has(name)) {
73
- throw new TypeError(
74
- `Multiple action definitions flatten to \`${name}\``
75
- );
76
- }
77
- names.add(name);
78
- entries.push({
79
- name,
80
- path: childPath,
81
- handler: child
82
- });
83
- } else {
84
- visitActionGroup(child, childPath, entries, names);
85
- }
86
- }
87
- }
88
- function lookupNestedSchema(schemas, path) {
89
- let value = schemas;
90
- for (const segment of path) {
91
- if (!isRecord(value) || !Object.hasOwn(value, segment)) {
92
- return void 0;
93
- }
94
- value = value[segment];
95
- }
96
- return value;
97
- }
98
- function isRecord(value) {
99
- if (typeof value !== "object" || value === null || Array.isArray(value)) {
100
- return false;
101
- }
102
- const prototype = Object.getPrototypeOf(value);
103
- return prototype === Object.prototype || prototype === null;
104
- }
105
- function formatActionPath(path) {
106
- return path.length === 0 ? "actions" : `Action \`${path.join(".")}\``;
107
- }
108
-
109
- // src/actor/config.ts
110
- var DEFAULT_SLEEP_GRACE_PERIOD = 15e3;
111
- var zFunction = () => z.custom((val) => typeof val === "function");
112
- var zActionTree = z.custom((value) => {
113
- if (typeof value !== "object" || value === null || Array.isArray(value)) {
114
- return false;
115
- }
116
- const prototype = Object.getPrototypeOf(value);
117
- return prototype === Object.prototype || prototype === null;
118
- }).superRefine((actions, ctx) => {
119
- try {
120
- flattenActionHandlers(actions);
121
- } catch (error) {
122
- ctx.addIssue({
123
- code: "custom",
124
- message: error instanceof Error ? error.message : "Invalid action definition"
125
- });
126
- }
127
- });
128
- var WorkflowInspectorConfigSchema = z.object({
129
- getHistory: zFunction(),
130
- getState: zFunction().optional(),
131
- onHistoryUpdated: zFunction().optional(),
132
- replayFromStep: zFunction().optional()
133
- });
134
- var RunInspectorConfigSchema = z.object({
135
- workflow: WorkflowInspectorConfigSchema.optional()
136
- }).optional();
137
- var BUILTIN_INSPECTOR_TAB_IDS = [
138
- "workflow",
139
- "database",
140
- "state",
141
- "queue",
142
- "schedules",
143
- "connections",
144
- "console"
145
- ];
146
- var BuiltinInspectorTabIdSchema = z.enum(BUILTIN_INSPECTOR_TAB_IDS);
147
- var CUSTOM_INSPECTOR_TAB_ID_RE = /^[A-Za-z0-9_-]+$/;
148
- var CustomInspectorTabEntrySchema = z.object({
149
- id: z.string().regex(
150
- CUSTOM_INSPECTOR_TAB_ID_RE,
151
- "inspector.tabs[].id must contain only letters, digits, underscore, or dash"
152
- ),
153
- label: z.string().min(1),
154
- source: z.string().min(1),
155
- /**
156
- * Optional icon id. The dashboard maps strings to glyphs (see its
157
- * icon registry); unknown ids fall back to a generic icon.
158
- */
159
- icon: z.string().min(1).optional(),
160
- hidden: z.literal(false).optional()
161
- }).strict();
162
- var HideInspectorTabEntrySchema = z.object({
163
- id: BuiltinInspectorTabIdSchema,
164
- hidden: z.literal(true)
165
- }).strict();
166
- var InspectorTabEntrySchema = z.union([
167
- CustomInspectorTabEntrySchema,
168
- HideInspectorTabEntrySchema
169
- ]);
170
- var ActorInspectorConfigSchema = z.object({
171
- tabs: z.array(InspectorTabEntrySchema).default(() => [])
172
- }).strict().refine(
173
- (data) => {
174
- const ids = data.tabs.map((t) => t.id);
175
- return new Set(ids).size === ids.length;
176
- },
177
- { message: "Duplicate id in inspector.tabs", path: ["tabs"] }
178
- ).refine(
179
- (data) => {
180
- const builtinSet = new Set(BUILTIN_INSPECTOR_TAB_IDS);
181
- return data.tabs.every(
182
- (t) => t.hidden === true || !builtinSet.has(t.id)
183
- );
184
- },
185
- {
186
- message: "Custom inspector tab id collides with a built-in (use hidden: true to hide a built-in)",
187
- path: ["tabs"]
188
- }
1
+ // src/agent-os/index.ts
2
+ throw new Error(
3
+ "rivetkit/agent-os has been removed. Use @rivet-dev/agentos-core to run agentOS VMs in your process, or hosted agentOS with @rivet-dev/agentos. See https://rivet.dev/agentos/docs"
189
4
  );
190
- var RunConfigSchema = z.object({
191
- /** Display name for the actor in the Inspector UI. */
192
- name: z.string().optional(),
193
- /** Icon for the actor in the Inspector UI. Can be an emoji or FontAwesome icon name. */
194
- icon: z.string().optional(),
195
- /** The run handler function. */
196
- run: zFunction(),
197
- /** Inspector integration for long-running run handlers. */
198
- inspector: RunInspectorConfigSchema.optional()
199
- });
200
- var zRunHandler = z.union([zFunction(), RunConfigSchema]).optional();
201
- var GlobalActorOptionsBaseSchema = z.object({
202
- /** Display name for the actor in the Inspector UI. */
203
- name: z.string().optional(),
204
- /** Icon for the actor in the Inspector UI. Can be an emoji or FontAwesome icon name. */
205
- icon: z.string().optional(),
206
- /** Enables the experimental Actor Runtime Socket for this actor. */
207
- enableActorRuntimeSocket: z.boolean().default(false),
208
- /**
209
- * Can hibernate WebSockets, both client connections for actions and
210
- * events and WebSockets for onWebSocket. A WebSocket that does not
211
- * hibernate closes when the actor sleeps, and the client reconnects.
212
- *
213
- * @experimental
214
- **/
215
- canHibernateWebSocket: z.union([z.boolean(), zFunction()]).default(false)
216
- }).strict();
217
- var GlobalActorOptionsSchema = GlobalActorOptionsBaseSchema.prefault(
218
- () => ({})
219
- );
220
- var InstanceActorOptionsBaseSchema = z.object({
221
- createVarsTimeout: z.number().positive().default(5e3),
222
- createConnStateTimeout: z.number().positive().default(5e3),
223
- onBeforeConnectTimeout: z.number().positive().default(5e3),
224
- onConnectTimeout: z.number().positive().default(5e3),
225
- onMigrateTimeout: z.number().positive().default(3e4),
226
- sleepGracePeriod: z.number().positive().default(DEFAULT_SLEEP_GRACE_PERIOD),
227
- /** @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. */
228
- onDestroyTimeout: z.number().positive().optional(),
229
- /** @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. */
230
- waitUntilTimeout: z.number().positive().optional(),
231
- stateSaveInterval: z.number().positive().default(1e3),
232
- actionTimeout: z.number().positive().default(6e4),
233
- connectionLivenessTimeout: z.number().positive().default(2500),
234
- connectionLivenessInterval: z.number().positive().default(5e3),
235
- /** @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. */
236
- noSleep: z.boolean().default(false),
237
- sleepTimeout: z.number().positive().default(3e4),
238
- maxQueueSize: z.number().positive().default(1e3),
239
- /** Maximum pending one-shot and recurring schedules. */
240
- maxSchedules: z.number().int().nonnegative().default(1e3),
241
- maxQueueMessageSize: z.number().positive().default(64 * 1024),
242
- /** @deprecated Internal storage moved to SQLite and no longer uses KV preloading, so this option is ignored. Will be removed in 2.2.0. */
243
- preloadMaxWorkflowBytes: z.number().nonnegative().optional(),
244
- /** @deprecated Internal storage moved to SQLite and no longer uses KV preloading, so this option is ignored. Will be removed in 2.2.0. */
245
- preloadMaxConnectionsBytes: z.number().nonnegative().optional()
246
- }).strict();
247
- var InstanceActorOptionsSchema = InstanceActorOptionsBaseSchema.prefault(() => ({}));
248
- var ActorOptionsSchema = GlobalActorOptionsBaseSchema.extend(
249
- InstanceActorOptionsBaseSchema.shape
250
- ).strict().prefault(() => ({}));
251
- var zSampleRate = z.number().min(0).max(1);
252
- var zActionSampleRates = z.lazy(
253
- () => z.record(z.string(), z.union([zSampleRate, zActionSampleRates]))
254
- );
255
- var ActorConfigSchema = z.object({
256
- onCreate: zFunction().optional(),
257
- onDestroy: zFunction().optional(),
258
- onMigrate: zFunction().optional(),
259
- onWake: zFunction().optional(),
260
- onSleep: zFunction().optional(),
261
- run: zRunHandler,
262
- onStateChange: zFunction().optional(),
263
- onBeforeConnect: zFunction().optional(),
264
- onConnect: zFunction().optional(),
265
- onDisconnect: zFunction().optional(),
266
- onBeforeActionResponse: zFunction().optional(),
267
- onRequest: zFunction().optional(),
268
- onWebSocket: zFunction().optional(),
269
- actions: zActionTree.default(() => ({})),
270
- actionInputSchemas: z.record(z.string(), z.any()).optional(),
271
- tracing: z.object({
272
- sampler: zSampleRate.optional(),
273
- actions: zActionSampleRates.optional()
274
- }).strict().optional(),
275
- connParamsSchema: z.any().optional(),
276
- events: z.record(z.string(), z.any()).optional(),
277
- queues: z.record(z.string(), z.any()).optional(),
278
- state: z.any().optional(),
279
- createState: zFunction().optional(),
280
- connState: z.any().optional(),
281
- createConnState: zFunction().optional(),
282
- vars: z.any().optional(),
283
- db: z.any().optional(),
284
- createVars: zFunction().optional(),
285
- options: ActorOptionsSchema,
286
- inspector: ActorInspectorConfigSchema.optional()
287
- }).strict().refine(
288
- (data) => !(data.state !== void 0 && data.createState !== void 0),
289
- {
290
- message: "Cannot define both 'state' and 'createState'",
291
- path: ["state"]
292
- }
293
- ).refine(
294
- (data) => !(data.connState !== void 0 && data.createConnState !== void 0),
295
- {
296
- message: "Cannot define both 'connState' and 'createConnState'",
297
- path: ["connState"]
298
- }
299
- ).refine(
300
- (data) => !(data.vars !== void 0 && data.createVars !== void 0),
301
- {
302
- message: "Cannot define both 'vars' and 'createVars'",
303
- path: ["vars"]
304
- }
305
- );
306
- var DocActorOptionsSchema = z.object({
307
- name: z.string().optional().describe("Display name for the actor in the Inspector UI."),
308
- icon: z.string().optional().describe(
309
- "Icon for the actor in the Inspector UI. Can be an emoji (e.g., '\u{1F680}') or FontAwesome icon name (e.g., 'rocket')."
310
- ),
311
- enableActorRuntimeSocket: z.boolean().optional().describe(
312
- "Enables the experimental Actor Runtime Socket for this actor. Default: false"
313
- ),
314
- createVarsTimeout: z.number().optional().describe("Timeout in ms for createVars handler. Default: 5000"),
315
- createConnStateTimeout: z.number().optional().describe(
316
- "Timeout in ms for createConnState handler. Default: 5000"
317
- ),
318
- onMigrateTimeout: z.number().optional().describe("Timeout in ms for onMigrate handler. Default: 30000"),
319
- onBeforeConnectTimeout: z.number().optional().describe(
320
- "Timeout in ms for onBeforeConnect handler. Default: 5000"
321
- ),
322
- onConnectTimeout: z.number().optional().describe("Timeout in ms for onConnect handler. Default: 5000"),
323
- sleepGracePeriod: z.number().optional().describe(
324
- `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}.`
325
- ),
326
- onDestroyTimeout: z.number().optional().describe(
327
- "Deprecated. Folded into sleepGracePeriod, which now bounds the entire graceful shutdown window for both sleep and destroy. Will be removed in 2.2.0."
328
- ),
329
- waitUntilTimeout: z.number().optional().describe(
330
- "Deprecated. Folded into sleepGracePeriod, which now bounds the entire graceful shutdown window for both sleep and destroy. Will be removed in 2.2.0."
331
- ),
332
- stateSaveInterval: z.number().optional().describe(
333
- "Interval in ms between automatic state saves. Default: 1000"
334
- ),
335
- actionTimeout: z.number().optional().describe("Timeout in ms for action handlers. Default: 60000"),
336
- connectionLivenessTimeout: z.number().optional().describe(
337
- "Timeout in ms for connection liveness checks. Default: 2500"
338
- ),
339
- connectionLivenessInterval: z.number().optional().describe(
340
- "Interval in ms between connection liveness checks. Default: 5000"
341
- ),
342
- noSleep: z.boolean().optional().describe(
343
- "Deprecated. If true, the actor will never sleep. Use c.keepAwake(promise) to scope keep-awake to a specific operation instead. Default: false"
344
- ),
345
- sleepTimeout: z.number().optional().describe(
346
- "Time in ms of inactivity before the actor sleeps. Default: 30000"
347
- ),
348
- maxQueueSize: z.number().optional().describe(
349
- "Maximum number of queue messages before rejecting new messages. Default: 1000"
350
- ),
351
- maxSchedules: z.number().int().nonnegative().optional().describe(
352
- "Maximum pending one-shot and recurring schedules before rejecting new schedules. Default: 1000"
353
- ),
354
- maxQueueMessageSize: z.number().optional().describe(
355
- "Maximum size of each queue message in bytes. Default: 65536"
356
- ),
357
- canHibernateWebSocket: z.boolean().optional().describe(
358
- "Whether WebSockets can be hibernated, both client connections for actions and events and WebSockets using onWebSocket. A WebSocket that does not hibernate closes when the actor sleeps. Default: false"
359
- )
360
- }).describe("Actor options for timeouts and behavior configuration.");
361
- var DocActorConfigSchema = z.object({
362
- state: z.unknown().optional().describe(
363
- "Initial state value for the actor. Cannot be used with createState."
364
- ),
365
- createState: z.unknown().optional().describe(
366
- "Function to create initial state. Receives context and input. Cannot be used with state."
367
- ),
368
- connState: z.unknown().optional().describe(
369
- "Initial connection state value. Cannot be used with createConnState."
370
- ),
371
- createConnState: z.unknown().optional().describe(
372
- "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."
373
- ),
374
- vars: z.unknown().optional().describe(
375
- "Initial ephemeral variables value. Cannot be used with createVars."
376
- ),
377
- createVars: z.unknown().optional().describe(
378
- "Function to create ephemeral variables. Receives context and driver context. Cannot be used with vars."
379
- ),
380
- db: z.unknown().optional().describe("Database provider instance for the actor."),
381
- onCreate: z.unknown().optional().describe(
382
- "Called when the actor is first initialized. Use to initialize state."
383
- ),
384
- onDestroy: z.unknown().optional().describe("Called when the actor is destroyed."),
385
- onMigrate: z.unknown().optional().describe(
386
- "Called on every actor start after persisted state loads and before onWake. Use for repeatable schema migrations."
387
- ),
388
- onWake: z.unknown().optional().describe(
389
- "Called when the actor wakes up and is ready to receive connections and actions."
390
- ),
391
- onSleep: z.unknown().optional().describe(
392
- "Called when the actor is stopping or sleeping. Use to clean up resources."
393
- ),
394
- run: z.unknown().optional().describe(
395
- "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."
396
- ),
397
- onStateChange: z.unknown().optional().describe(
398
- "Called when the actor's state changes. State changes within this hook won't trigger recursion."
399
- ),
400
- onBeforeConnect: z.unknown().optional().describe(
401
- "Called before a client connects. Throw an error to reject the connection. The pending connection is not visible in c.conns while this runs."
402
- ),
403
- onConnect: z.unknown().optional().describe(
404
- "Called when a client successfully connects. The connection is visible in c.conns before this runs."
405
- ),
406
- onDisconnect: z.unknown().optional().describe("Called when a client disconnects."),
407
- onBeforeActionResponse: z.unknown().optional().describe(
408
- "Called before sending an action response. Use to transform output."
409
- ),
410
- onRequest: z.unknown().optional().describe(
411
- "Called for raw HTTP requests to /actors/{name}/http/* endpoints."
412
- ),
413
- onWebSocket: z.unknown().optional().describe(
414
- "Called for raw WebSocket connections to /actors/{name}/websocket/* endpoints."
415
- ),
416
- actions: z.record(z.string(), z.unknown()).optional().describe(
417
- "Tree of action names or nested groups to handler functions. Nested paths use dot-separated low-level action names. Defaults to an empty object."
418
- ),
419
- actionInputSchemas: z.record(z.string(), z.unknown()).optional().describe(
420
- "Optional schemas for validating action argument tuples in native runtimes. May mirror nested action groups or use dot-separated low-level action names."
421
- ),
422
- tracing: z.unknown().optional().describe(
423
- "Trace sampling for this actor: `sampler` is the share of its invocations that are recorded, from 0 to 1, with optional per-action rates under `actions`. A rate lowers what is recorded and never raises it. Defaults to the process sampler from OTEL_TRACES_SAMPLER."
424
- ),
425
- connParamsSchema: z.unknown().optional().describe(
426
- "Optional schema for validating connection params in native runtimes."
427
- ),
428
- events: z.record(z.string(), z.unknown()).optional().describe("Map of event names to schemas."),
429
- queues: z.record(z.string(), z.unknown()).optional().describe("Map of queue names to schemas."),
430
- options: DocActorOptionsSchema.optional()
431
- }).describe("Actor configuration passed to the actor() function.");
432
-
433
- // src/common/log.ts
434
- import {
435
- pino,
436
- stdTimeFunctions
437
- } from "pino";
438
- import { z as z2 } from "zod/v4";
439
-
440
- // src/actor/errors.ts
441
- function isTypedErrorTag(value) {
442
- return value === "ActorError" || value === "RivetError";
443
- }
444
- function isRivetErrorLike(error) {
445
- return typeof error === "object" && error !== null && "group" in error && typeof error.group === "string" && "code" in error && typeof error.code === "string" && "message" in error && typeof error.message === "string" && (!("rayId" in error) || error.rayId === void 0 || typeof error.rayId === "string") && (!("__type" in error) || isTypedErrorTag(error.__type));
446
- }
447
- function isRivetErrorCode(error, group, code) {
448
- return isRivetErrorLike(error) && error.group === group && error.code === code;
449
- }
450
-
451
- // package.json
452
- var package_default = {
453
- name: "rivetkit",
454
- version: "2.3.27",
455
- description: "Lightweight libraries for building stateful actors on edge platforms",
456
- license: "Apache-2.0",
457
- keywords: [
458
- "rivetkit",
459
- "stateful",
460
- "serverless",
461
- "actors",
462
- "agents",
463
- "realtime",
464
- "websocket",
465
- "actors",
466
- "framework"
467
- ],
468
- files: [
469
- "dist",
470
- "schemas",
471
- "src",
472
- "package.json"
473
- ],
474
- type: "module",
475
- exports: {
476
- ".": {
477
- import: {
478
- types: "./dist/tsup/mod.d.ts",
479
- default: "./dist/tsup/mod.js"
480
- },
481
- require: {
482
- types: "./dist/tsup/mod.d.cts",
483
- default: "./dist/tsup/mod.cjs"
484
- }
485
- },
486
- "./workflow": {
487
- import: {
488
- types: "./dist/tsup/workflow/mod.d.ts",
489
- default: "./dist/tsup/workflow/mod.js"
490
- },
491
- require: {
492
- types: "./dist/tsup/workflow/mod.d.cts",
493
- default: "./dist/tsup/workflow/mod.cjs"
494
- }
495
- },
496
- "./test": {
497
- import: {
498
- types: "./dist/tsup/test/mod.d.ts",
499
- default: "./dist/tsup/test/mod.js"
500
- },
501
- require: {
502
- types: "./dist/tsup/test/mod.d.cts",
503
- default: "./dist/tsup/test/mod.cjs"
504
- }
505
- },
506
- "./db": {
507
- import: {
508
- types: "./dist/tsup/db/mod.d.ts",
509
- default: "./dist/tsup/db/mod.js"
510
- },
511
- require: {
512
- types: "./dist/tsup/db/mod.d.cts",
513
- default: "./dist/tsup/db/mod.cjs"
514
- }
515
- },
516
- "./db/drizzle": {
517
- import: {
518
- types: "./dist/tsup/db/drizzle.d.ts",
519
- default: "./dist/tsup/db/drizzle.js"
520
- },
521
- require: {
522
- types: "./dist/tsup/db/drizzle.d.cts",
523
- default: "./dist/tsup/db/drizzle.cjs"
524
- }
525
- },
526
- "./unstable/migrations": {
527
- import: {
528
- types: "./dist/tsup/unstable/migrations.d.ts",
529
- default: "./dist/tsup/unstable/migrations.js"
530
- },
531
- require: {
532
- types: "./dist/tsup/unstable/migrations.d.cts",
533
- default: "./dist/tsup/unstable/migrations.cjs"
534
- }
535
- },
536
- "./dynamic": {
537
- import: {
538
- types: "./dist/tsup/dynamic/mod.d.ts",
539
- default: "./dist/tsup/dynamic/mod.js"
540
- },
541
- require: {
542
- types: "./dist/tsup/dynamic/mod.d.cts",
543
- default: "./dist/tsup/dynamic/mod.cjs"
544
- }
545
- },
546
- "./client": {
547
- import: {
548
- browser: {
549
- types: "./dist/browser/client.d.ts",
550
- default: "./dist/browser/client.js"
551
- },
552
- types: "./dist/tsup/client/mod.d.ts",
553
- default: "./dist/tsup/client/mod.js"
554
- },
555
- require: {
556
- types: "./dist/tsup/client/mod.d.cts",
557
- default: "./dist/tsup/client/mod.cjs"
558
- }
559
- },
560
- "./log": {
561
- import: {
562
- types: "./dist/tsup/common/log.d.ts",
563
- default: "./dist/tsup/common/log.js"
564
- },
565
- require: {
566
- types: "./dist/tsup/common/log.d.cts",
567
- default: "./dist/tsup/common/log.cjs"
568
- }
569
- },
570
- "./errors": {
571
- import: {
572
- types: "./dist/tsup/actor/errors.d.ts",
573
- default: "./dist/tsup/actor/errors.js"
574
- },
575
- require: {
576
- types: "./dist/tsup/actor/errors.d.cts",
577
- default: "./dist/tsup/actor/errors.cjs"
578
- }
579
- },
580
- "./inspector": {
581
- import: {
582
- types: "./dist/tsup/inspector/mod.d.ts",
583
- default: "./dist/tsup/inspector/mod.js"
584
- },
585
- require: {
586
- types: "./dist/tsup/inspector/mod.d.cts",
587
- default: "./dist/tsup/inspector/mod.cjs"
588
- }
589
- },
590
- "./experimental/inspector/workflow": {
591
- import: {
592
- types: "./dist/tsup/inspector/workflow.d.ts",
593
- default: "./dist/tsup/inspector/workflow.js"
594
- },
595
- require: {
596
- types: "./dist/tsup/inspector/workflow.d.cts",
597
- default: "./dist/tsup/inspector/workflow.cjs"
598
- }
599
- },
600
- "./inspector-tab": {
601
- import: {
602
- types: "./dist/tsup/inspector-tab/mod.d.ts",
603
- default: "./dist/tsup/inspector-tab/mod.js"
604
- },
605
- require: {
606
- types: "./dist/tsup/inspector-tab/mod.d.cts",
607
- default: "./dist/tsup/inspector-tab/mod.cjs"
608
- }
609
- },
610
- "./inspector/client": {
611
- import: {
612
- types: "./dist/browser/inspector/client.d.ts",
613
- default: "./dist/browser/inspector/client.js"
614
- }
615
- },
616
- "./utils": {
617
- import: {
618
- types: "./dist/tsup/utils.d.ts",
619
- default: "./dist/tsup/utils.js"
620
- },
621
- require: {
622
- types: "./dist/tsup/utils.d.cts",
623
- default: "./dist/tsup/utils.cjs"
624
- }
625
- },
626
- "./agent-os": {
627
- import: {
628
- types: "./dist/tsup/agent-os/index.d.ts",
629
- default: "./dist/tsup/agent-os/index.js"
630
- },
631
- require: {
632
- types: "./dist/tsup/agent-os/index.d.cts",
633
- default: "./dist/tsup/agent-os/index.cjs"
634
- }
635
- }
636
- },
637
- engines: {
638
- node: ">=22.0.0"
639
- },
640
- sideEffects: [
641
- "./dist/tsup/chunk-*.js",
642
- "./dist/tsup/chunk-*.cjs"
643
- ],
644
- scripts: {
645
- 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/inspector/workflow.ts src/inspector-tab/mod.ts src/db/mod.ts src/db/drizzle.ts src/dynamic/mod.ts src/unstable/migrations.ts && tsup src/agent-os/index.ts --no-clean --out-dir dist/tsup/agent-os && node scripts/check-built-commonjs.mjs",
646
- "build:browser": "tsup --config tsup.browser.config.ts",
647
- "check-types": "tsc --noEmit",
648
- lint: "biome check . && pnpm run check:test-skips && pnpm run check:wait-for-comments",
649
- "lint:fix": "biome check --write .",
650
- "check:test-skips": "tsx scripts/check-annotated-skips.ts",
651
- "check:wait-for-comments": "tsx scripts/check-wait-for-comments.ts",
652
- format: "biome format .",
653
- "format:write": "biome format --write .",
654
- test: "vitest run",
655
- "test:platforms": "pnpm run build && RIVETKIT_INCLUDE_PLATFORM_TESTS=1 vitest run tests/platforms --passWithNoTests",
656
- "test:watch": "vitest",
657
- "dump-asyncapi": "tsx scripts/dump-asyncapi.ts",
658
- "registry-config-schema-gen": "tsx scripts/registry-config-schema-gen.ts",
659
- "actor-config-schema-gen": "tsx scripts/actor-config-schema-gen.ts"
660
- },
661
- dependencies: {
662
- "@hono/zod-openapi": "^1.1.5",
663
- "@opentelemetry/api": "^1.1.0",
664
- "@rivet-dev/agent-os-core": "^0.1.1",
665
- "@rivet-dev/services": "^0.2.0",
666
- "@rivetkit/bare-ts": "^0.6.2",
667
- "@rivetkit/engine-api-full": "workspace:*",
668
- "@rivetkit/engine-cli": "workspace:*",
669
- "@rivetkit/engine-envoy-protocol": "workspace:*",
670
- "@rivetkit/on-change": "6.0.1",
671
- "@rivetkit/rivetkit-napi": "workspace:*",
672
- "@rivetkit/rivetkit-wasm": "workspace:*",
673
- "@rivetkit/traces": "workspace:*",
674
- "@rivetkit/virtual-websocket": "workspace:*",
675
- "@rivetkit/workflow-engine": "workspace:*",
676
- "cbor-x": "^1.6.0",
677
- "drizzle-orm": "catalog:",
678
- hono: "^4.7.0",
679
- invariant: "^2.2.4",
680
- "p-retry": "^6.2.1",
681
- pino: "^9.5.0",
682
- uuid: "^12.0.0",
683
- vbare: "^0.0.4",
684
- zod: "^4.1.0"
685
- },
686
- devDependencies: {
687
- "@biomejs/biome": "^2.3",
688
- "@copilotkit/llmock": "^1.6.0",
689
- "@hono/node-server": "^1.18.2",
690
- "@hono/node-ws": "^1.1.1",
691
- "@opentelemetry/sdk-trace-node": "2.11.0",
692
- "@rivet-dev/agent-os-common": "*",
693
- "@rivet-dev/agent-os-pi": "^0.1.1",
694
- "@standard-schema/spec": "^1.0.0",
695
- "@types/invariant": "^2",
696
- "@types/node": "^22.13.1",
697
- eventsource: "^4.0.0",
698
- "get-port": "^7.1.0",
699
- tsup: "^8.4.0",
700
- tsx: "^4.19.4",
701
- typescript: "^5.7.3",
702
- "vite-tsconfig-paths": "^5.1.4",
703
- vitest: "^3.1.1",
704
- ws: "^8.18.1"
705
- },
706
- peerDependencies: {
707
- "drizzle-kit": "^0.31.2",
708
- eventsource: "^4.0.0",
709
- ws: "^8.0.0"
710
- },
711
- peerDependenciesMeta: {
712
- "drizzle-kit": {
713
- optional: true
714
- },
715
- eventsource: {
716
- optional: true
717
- },
718
- ws: {
719
- optional: true
720
- }
721
- },
722
- stableVersion: "0.8.0"
723
- };
724
-
725
- // src/utils.ts
726
- var VERSION = package_default.version;
727
- function getEnvUniversal(key) {
728
- if (typeof Deno !== "undefined") {
729
- return Deno.env.get(key);
730
- } else if (typeof process !== "undefined") {
731
- return process.env[key];
732
- }
733
- }
734
-
735
- // src/utils/env-vars.ts
736
- var getLogLevel = () => getEnvUniversal("RIVET_LOG_LEVEL") ?? getEnvUniversal("LOG_LEVEL");
737
- var getLogTarget = () => getEnvUniversal("RIVET_LOG_TARGET") === "1";
738
- var getLogTimestamp = () => getEnvUniversal("RIVET_LOG_TIMESTAMP") === "1";
739
-
740
- // src/common/log.ts
741
- var baseLogger;
742
- var configuredLogLevel;
743
- var loggerCache = /* @__PURE__ */ new Map();
744
- var LogLevelSchema = z2.enum([
745
- "trace",
746
- "debug",
747
- "info",
748
- "warn",
749
- "error",
750
- "fatal",
751
- "silent"
752
- ]);
753
- function getPinoLevel(logLevel) {
754
- if (logLevel) {
755
- return logLevel;
756
- }
757
- if (configuredLogLevel) {
758
- return configuredLogLevel;
759
- }
760
- const raw = (getLogLevel() || "warn").toString().toLowerCase();
761
- const parsed = LogLevelSchema.safeParse(raw);
762
- if (parsed.success) {
763
- return parsed.data;
764
- }
765
- return "info";
766
- }
767
- function getIncludeTarget() {
768
- return getLogTarget();
769
- }
770
- function makeDefaultLogger(logLevel) {
771
- return pino(
772
- {
773
- level: getPinoLevel(logLevel),
774
- messageKey: "msg",
775
- // Do not include pid/hostname in output
776
- base: {},
777
- errorKey: "error",
778
- // Keep the numeric level so the logfmt sink can match Pino's levels.
779
- formatters: {
780
- level(_label, number) {
781
- return { level: number };
782
- }
783
- },
784
- timestamp: getLogTimestamp() ? stdTimeFunctions.epochTime : false
785
- },
786
- createLogfmtDestination()
787
- );
788
- }
789
- function configureDefaultLogger(logLevel) {
790
- if (logLevel) {
791
- configuredLogLevel = logLevel;
792
- }
793
- baseLogger = makeDefaultLogger(logLevel);
794
- loggerCache.clear();
795
- }
796
- function getBaseLogger() {
797
- if (!baseLogger) {
798
- configureDefaultLogger();
799
- }
800
- return baseLogger;
801
- }
802
- function getLogger(name = "default") {
803
- const cached = loggerCache.get(name);
804
- if (cached) {
805
- return cached;
806
- }
807
- const base = getBaseLogger();
808
- const child = getIncludeTarget() ? base.child({ target: name }) : base;
809
- loggerCache.set(name, child);
810
- return child;
811
- }
812
- var PINO_LEVEL_LABELS = {
813
- 10: "trace",
814
- 20: "debug",
815
- 30: "info",
816
- 40: "warn",
817
- 50: "error",
818
- 60: "fatal"
819
- };
820
- function createLogfmtDestination() {
821
- return {
822
- write(msg) {
823
- var _a;
824
- const line = formatLogfmtLine(msg);
825
- if (typeof process !== "undefined" && ((_a = process.stdout) == null ? void 0 : _a.write)) {
826
- process.stdout.write(`${line}
827
- `);
828
- } else {
829
- console.log(line);
830
- }
831
- }
832
- };
833
- }
834
- function formatLogfmtLine(raw) {
835
- let data;
836
- try {
837
- data = JSON.parse(raw);
838
- } catch {
839
- return raw.trimEnd();
840
- }
841
- const parts = [];
842
- appendLogfmtEntry(parts, "level", formatPinoLevel(data.level));
843
- if (data.time !== void 0) {
844
- appendLogfmtEntry(parts, "ts", data.time);
845
- }
846
- for (const [key, value] of Object.entries(data)) {
847
- if (key === "level" || key === "time") {
848
- continue;
849
- }
850
- appendLogfmtEntry(parts, key, value);
851
- }
852
- return parts.join(" ");
853
- }
854
- function formatPinoLevel(level) {
855
- if (typeof level === "number") {
856
- return PINO_LEVEL_LABELS[level] ?? level.toString();
857
- }
858
- if (typeof level === "string") {
859
- return level.toLowerCase();
860
- }
861
- return "info";
862
- }
863
- function appendLogfmtEntry(parts, key, value) {
864
- const safeKey = key.replace(/[\s="]/g, "");
865
- if (safeKey.length === 0) {
866
- return;
867
- }
868
- parts.push(`${safeKey}=${formatLogfmtValue(value)}`);
869
- }
870
- function formatLogfmtValue(value) {
871
- if (typeof value === "number" || typeof value === "boolean") {
872
- return String(value);
873
- }
874
- if (value === null || value === void 0) {
875
- return "null";
876
- }
877
- if (typeof value === "string") {
878
- return quoteLogfmtString(value);
879
- }
880
- return quoteLogfmtString(JSON.stringify(value));
881
- }
882
- function quoteLogfmtString(value) {
883
- if (!/[\s="]/.test(value)) {
884
- return value;
885
- }
886
- return `"${value.replace(/\\/g, "\\\\").replace(/"/g, '\\"').replace(/\n/g, "\\n")}"`;
887
- }
888
-
889
- // src/actor/log.ts
890
- function loggerWithoutContext() {
891
- return getLogger("actor-runtime");
892
- }
893
-
894
- // src/actor/definition.ts
895
- var warnedDeprecatedOptionKeys = /* @__PURE__ */ new Set();
896
- var DEPRECATED_OPTION_MESSAGES = {
897
- onDestroyTimeout: "Configure `sleepGracePeriod` instead, which bounds the entire graceful shutdown window for both sleep and destroy.",
898
- waitUntilTimeout: "Configure `sleepGracePeriod` instead, which bounds the entire graceful shutdown window for both sleep and destroy.",
899
- preloadMaxWorkflowBytes: "Internal storage moved to SQLite and no longer uses KV preloading.",
900
- preloadMaxConnectionsBytes: "Internal storage moved to SQLite and no longer uses KV preloading."
901
- };
902
- function warnDeprecatedOptionKeys(options) {
903
- if (!options || typeof options !== "object") return;
904
- const opts = options;
905
- for (const [key, detail] of Object.entries(DEPRECATED_OPTION_MESSAGES)) {
906
- if (opts[key] !== void 0 && !warnedDeprecatedOptionKeys.has(key)) {
907
- warnedDeprecatedOptionKeys.add(key);
908
- loggerWithoutContext().warn({
909
- msg: `actor option \`${key}\` is deprecated and is now ignored. ${detail} Will be removed in 2.2.0.`
910
- });
911
- }
912
- }
913
- }
914
- var ActorDefinition = class {
915
- #config;
916
- constructor(config) {
917
- this.#config = config;
918
- }
919
- get config() {
920
- return this.#config;
921
- }
922
- };
923
- function actor(input) {
924
- var _a;
925
- warnDeprecatedOptionKeys(
926
- input == null ? void 0 : input.options
927
- );
928
- const config = ActorConfigSchema.parse(input);
929
- flattenActionHandlers(config.actions);
930
- flattenActionInputSchemas(config.actions, config.actionInputSchemas);
931
- flattenActionTraceSamplers(config.actions, (_a = config.tracing) == null ? void 0 : _a.actions);
932
- return new ActorDefinition(config);
933
- }
934
-
935
- // src/actor/schema.ts
936
- function event(options) {
937
- return options ?? {};
938
- }
939
-
940
- // src/common/database/shared.ts
941
- var MIGRATION_TRANSACTION_TIMEOUT_MS = 5 * 6e4;
942
- function isManualTransactionControl(query) {
943
- return /^\s*(?:BEGIN|SAVEPOINT|COMMIT|END|ROLLBACK)\b/i.test(query);
944
- }
945
- function validateTransactionTimeout(timeout) {
946
- if (timeout !== void 0 && (!Number.isFinite(timeout) || timeout <= 0)) {
947
- throw new Error(
948
- "db.transaction() timeout must be a positive finite number of milliseconds"
949
- );
950
- }
951
- }
952
- function validateTransactionName(name) {
953
- if (name === void 0) {
954
- return;
955
- }
956
- if (name.length === 0) {
957
- throw new Error("db.transaction() name must not be empty");
958
- }
959
- }
960
- function isSqliteBindingValue(value) {
961
- if (value === null || typeof value === "number" || typeof value === "string" || typeof value === "bigint" || value instanceof Uint8Array) {
962
- return true;
963
- }
964
- if (Array.isArray(value)) {
965
- return value.every((item) => typeof item === "number");
966
- }
967
- return false;
968
- }
969
- function isPlainObject(value) {
970
- if (!value || typeof value !== "object" || Array.isArray(value)) {
971
- return false;
972
- }
973
- return Object.getPrototypeOf(value) === Object.prototype;
974
- }
975
- function isSqliteBindingObject(value) {
976
- if (!isPlainObject(value)) {
977
- return false;
978
- }
979
- return Object.values(value).every((entry) => isSqliteBindingValue(entry));
980
- }
981
- function toSqliteBindings(input) {
982
- if (Array.isArray(input)) {
983
- for (const value of input) {
984
- if (!isSqliteBindingValue(value)) {
985
- throw new Error(
986
- `unsupported sqlite binding type: ${typeof value}`
987
- );
988
- }
989
- }
990
- return input;
991
- }
992
- if (isSqliteBindingObject(input)) {
993
- return input;
994
- }
995
- throw new Error("unsupported sqlite binding collection");
996
- }
997
-
998
- // src/common/database/mod.ts
999
- var nativeStateTransactionOpeners = /* @__PURE__ */ new WeakMap();
1000
- var nativeStateTransactionClientBinders = /* @__PURE__ */ new WeakMap();
1001
- function hasMultipleStatements(query) {
1002
- const trimmed = query.trim().replace(/;+$/, "").trimEnd();
1003
- return trimmed.includes(";");
1004
- }
1005
- function db({
1006
- onMigrate,
1007
- warnOnManualTransactions = true,
1008
- profiling
1009
- } = {}) {
1010
- const provider = {
1011
- sqliteProfiling: profiling,
1012
- createClient: async (ctx) => {
1013
- const nativeDatabaseProvider = ctx.nativeDatabaseProvider;
1014
- if (!nativeDatabaseProvider) {
1015
- throw new Error(
1016
- "native SQLite is required, but the current runtime did not provide a native database provider"
1017
- );
1018
- }
1019
- const db2 = await nativeDatabaseProvider.open(ctx.actorId);
1020
- let closed = false;
1021
- let manualTransactionWarned = false;
1022
- const ensureOpen = () => {
1023
- if (closed) {
1024
- throw new Error(
1025
- "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."
1026
- );
1027
- }
1028
- };
1029
- const createClient = (target, transactionScoped = false, stateTransactionContext) => {
1030
- const client2 = {
1031
- execute: async (query, ...args) => {
1032
- var _a, _b, _c, _d;
1033
- ensureOpen();
1034
- if (!transactionScoped && warnOnManualTransactions && !manualTransactionWarned && !hasMultipleStatements(query) && isManualTransactionControl(query)) {
1035
- manualTransactionWarned = true;
1036
- getLogger("database").warn(
1037
- { actorId: ctx.actorId },
1038
- "Manual cross-call SQLite transactions can interleave with other actor work. Use db.transaction() for coordinated transactions. Set warnOnManualTransactions: false in your db(...) configuration to disable this warning."
1039
- );
1040
- }
1041
- const kvReadsBefore = ((_a = ctx.metrics) == null ? void 0 : _a.totalKvReads) ?? 0;
1042
- const kvWritesBefore = ((_b = ctx.metrics) == null ? void 0 : _b.totalKvWrites) ?? 0;
1043
- const start = performance.now();
1044
- try {
1045
- if (args.length > 0) {
1046
- const bindings = args.length === 1 && isSqliteBindingObject(args[0]) ? toSqliteBindings(args[0]) : toSqliteBindings(args);
1047
- const { rows, columns } = await target.execute(
1048
- query,
1049
- bindings
1050
- );
1051
- return rows.map(
1052
- (row) => rowToObject(row, columns)
1053
- );
1054
- }
1055
- if (!hasMultipleStatements(query)) {
1056
- const { rows, columns } = await target.execute(
1057
- query,
1058
- void 0
1059
- );
1060
- return rows.map(
1061
- (row) => rowToObject(row, columns)
1062
- );
1063
- }
1064
- return await execMultiStatement(
1065
- target,
1066
- query
1067
- );
1068
- } finally {
1069
- const durationMs = performance.now() - start;
1070
- (_c = ctx.metrics) == null ? void 0 : _c.trackSql(query, durationMs);
1071
- if (ctx.metrics) {
1072
- const kvReads = ctx.metrics.totalKvReads - kvReadsBefore;
1073
- const kvWrites = ctx.metrics.totalKvWrites - kvWritesBefore;
1074
- (_d = ctx.log) == null ? void 0 : _d.debug({
1075
- msg: "sql query",
1076
- query: query.slice(0, 120),
1077
- durationMs,
1078
- kvReads,
1079
- kvWrites
1080
- });
1081
- }
1082
- }
1083
- },
1084
- transaction: async (callback, options) => {
1085
- var _a, _b;
1086
- validateTransactionTimeout(options == null ? void 0 : options.timeout);
1087
- validateTransactionName(options == null ? void 0 : options.name);
1088
- if (transactionScoped && ((_a = options == null ? void 0 : options.experimental) == null ? void 0 : _a.includeState)) {
1089
- throw new Error(
1090
- "experimental.includeState is not supported for nested transactions"
1091
- );
1092
- }
1093
- const includeState = ((_b = options == null ? void 0 : options.experimental) == null ? void 0 : _b.includeState) === true;
1094
- const stateScope = includeState && stateTransactionContext ? await stateTransactionContext.enter() : void 0;
1095
- try {
1096
- const transaction = includeState ? await (() => {
1097
- const beginStateTransaction = ctx.nativeDatabaseProvider && nativeStateTransactionOpeners.get(
1098
- ctx.nativeDatabaseProvider
1099
- );
1100
- if (!beginStateTransaction) {
1101
- throw new Error(
1102
- "experimental.includeState is only supported by RivetKit's embedded database provider"
1103
- );
1104
- }
1105
- return beginStateTransaction(
1106
- options == null ? void 0 : options.timeout,
1107
- stateScope
1108
- );
1109
- })() : await db2.beginTransaction(
1110
- options == null ? void 0 : options.timeout,
1111
- options == null ? void 0 : options.name
1112
- );
1113
- const tx = createClient(transaction, true);
1114
- try {
1115
- const result = await callback(tx);
1116
- await transaction.commit();
1117
- return result;
1118
- } catch (error) {
1119
- try {
1120
- await transaction.rollback();
1121
- } catch {
1122
- }
1123
- throw error;
1124
- }
1125
- } finally {
1126
- if (stateScope !== void 0) {
1127
- stateTransactionContext == null ? void 0 : stateTransactionContext.exit(stateScope);
1128
- }
1129
- }
1130
- },
1131
- close: async () => {
1132
- if (!closed) {
1133
- closed = true;
1134
- await db2.close();
1135
- }
1136
- },
1137
- nativeMetrics: () => {
1138
- var _a;
1139
- return ((_a = db2.nativeMetrics) == null ? void 0 : _a.call(db2)) ?? null;
1140
- }
1141
- };
1142
- if (!transactionScoped) {
1143
- nativeStateTransactionClientBinders.set(
1144
- client2,
1145
- (context) => createClient(target, false, context)
1146
- );
1147
- }
1148
- return client2;
1149
- };
1150
- const client = createClient(db2);
1151
- return client;
1152
- },
1153
- onMigrate: async (client) => {
1154
- if (onMigrate) {
1155
- await withMigrationSavepoint(
1156
- client,
1157
- (leased) => onMigrate(leased)
1158
- );
1159
- }
1160
- }
1161
- };
1162
- return provider;
1163
- }
1164
- function rowToObject(row, columns) {
1165
- const rowObj = {};
1166
- for (let i = 0; i < columns.length; i++) {
1167
- rowObj[columns[i]] = row[i];
1168
- }
1169
- return rowObj;
1170
- }
1171
- async function execMultiStatement(db2, query) {
1172
- const results = [];
1173
- let columnNames = null;
1174
- await db2.exec(query, (row, columns) => {
1175
- if (!columnNames) {
1176
- columnNames = columns;
1177
- }
1178
- results.push(rowToObject(row, columnNames));
1179
- });
1180
- return results;
1181
- }
1182
- async function withMigrationSavepoint(client, callback) {
1183
- return await client.transaction(
1184
- async (transaction) => {
1185
- await transaction.execute("SAVEPOINT __rivet_on_migrate");
1186
- try {
1187
- const result = await callback(transaction);
1188
- await transaction.execute(
1189
- "RELEASE SAVEPOINT __rivet_on_migrate"
1190
- );
1191
- return result;
1192
- } catch (error) {
1193
- try {
1194
- await transaction.execute(
1195
- "ROLLBACK TO SAVEPOINT __rivet_on_migrate"
1196
- );
1197
- } finally {
1198
- await transaction.execute(
1199
- "RELEASE SAVEPOINT __rivet_on_migrate"
1200
- );
1201
- }
1202
- throw error;
1203
- }
1204
- },
1205
- {
1206
- name: "rivetkit-migration",
1207
- timeout: MIGRATION_TRANSACTION_TIMEOUT_MS
1208
- }
1209
- );
1210
- }
1211
-
1212
- // src/agent-os/config.ts
1213
- import { z as z3 } from "zod/v4";
1214
- var zFunction2 = () => z3.custom((val) => typeof val === "function");
1215
- var AgentOsOptionsSchema = z3.custom(
1216
- (val) => typeof val === "object" && val !== null
1217
- );
1218
- var agentOsActorConfigSchema = z3.object({
1219
- options: AgentOsOptionsSchema.optional(),
1220
- preview: z3.object({
1221
- defaultExpiresInSeconds: z3.number().positive().default(3600),
1222
- maxExpiresInSeconds: z3.number().positive().default(86400)
1223
- }).strict().prefault(() => ({})),
1224
- onBeforeConnect: zFunction2().optional(),
1225
- onSessionEvent: zFunction2().optional(),
1226
- onPermissionRequest: zFunction2().optional()
1227
- }).strict();
1228
-
1229
- // src/agent-os/actor/db.ts
1230
- async function migrateAgentOsTables(db2) {
1231
- await db2.execute(`
1232
- CREATE TABLE IF NOT EXISTS agent_os_preview_tokens (
1233
- token TEXT PRIMARY KEY,
1234
- port INTEGER NOT NULL,
1235
- created_at INTEGER NOT NULL,
1236
- expires_at INTEGER NOT NULL
1237
- );
1238
-
1239
- CREATE INDEX IF NOT EXISTS idx_preview_tokens_expires_at
1240
- ON agent_os_preview_tokens(expires_at);
1241
-
1242
- CREATE TABLE IF NOT EXISTS agent_os_fs_entries (
1243
- path TEXT PRIMARY KEY,
1244
- is_directory INTEGER NOT NULL DEFAULT 0,
1245
- content BLOB,
1246
- mode INTEGER NOT NULL DEFAULT 33188,
1247
- uid INTEGER NOT NULL DEFAULT 0,
1248
- gid INTEGER NOT NULL DEFAULT 0,
1249
- size INTEGER NOT NULL DEFAULT 0,
1250
- atime_ms INTEGER NOT NULL,
1251
- mtime_ms INTEGER NOT NULL,
1252
- ctime_ms INTEGER NOT NULL,
1253
- birthtime_ms INTEGER NOT NULL,
1254
- symlink_target TEXT,
1255
- nlink INTEGER NOT NULL DEFAULT 1
1256
- );
1257
-
1258
- CREATE INDEX IF NOT EXISTS idx_fs_entries_parent
1259
- ON agent_os_fs_entries(path);
1260
-
1261
- CREATE TABLE IF NOT EXISTS agent_os_sessions (
1262
- session_id TEXT PRIMARY KEY,
1263
- agent_type TEXT NOT NULL,
1264
- capabilities TEXT NOT NULL,
1265
- agent_info TEXT,
1266
- created_at INTEGER NOT NULL
1267
- );
1268
-
1269
- CREATE TABLE IF NOT EXISTS agent_os_session_events (
1270
- id INTEGER PRIMARY KEY AUTOINCREMENT,
1271
- session_id TEXT NOT NULL,
1272
- seq INTEGER NOT NULL,
1273
- event TEXT NOT NULL,
1274
- created_at INTEGER NOT NULL,
1275
- FOREIGN KEY (session_id) REFERENCES agent_os_sessions(session_id) ON DELETE CASCADE
1276
- );
1277
-
1278
- CREATE INDEX IF NOT EXISTS idx_session_events_session_seq
1279
- ON agent_os_session_events(session_id, seq);
1280
- `);
1281
- }
1282
-
1283
- // src/agent-os/actor/filesystem.ts
1284
- function buildFilesystemActions(config) {
1285
- return {
1286
- readFile: async (c, path) => {
1287
- const agentOs2 = await ensureVm(c, config);
1288
- return agentOs2.readFile(path);
1289
- },
1290
- writeFile: async (c, path, content) => {
1291
- const agentOs2 = await ensureVm(c, config);
1292
- await agentOs2.writeFile(path, content);
1293
- },
1294
- readFiles: async (c, paths) => {
1295
- const agentOs2 = await ensureVm(c, config);
1296
- return agentOs2.readFiles(paths);
1297
- },
1298
- writeFiles: async (c, entries) => {
1299
- const agentOs2 = await ensureVm(c, config);
1300
- return agentOs2.writeFiles(entries);
1301
- },
1302
- mkdir: async (c, path, options) => {
1303
- const agentOs2 = await ensureVm(c, config);
1304
- await agentOs2.mkdir(path, options);
1305
- },
1306
- readdir: async (c, path) => {
1307
- const agentOs2 = await ensureVm(c, config);
1308
- return agentOs2.readdir(path);
1309
- },
1310
- readdirRecursive: async (c, path, options) => {
1311
- const agentOs2 = await ensureVm(c, config);
1312
- return agentOs2.readdirRecursive(path, options);
1313
- },
1314
- stat: async (c, path) => {
1315
- const agentOs2 = await ensureVm(c, config);
1316
- return agentOs2.stat(path);
1317
- },
1318
- exists: async (c, path) => {
1319
- const agentOs2 = await ensureVm(c, config);
1320
- return agentOs2.exists(path);
1321
- },
1322
- move: async (c, from, to) => {
1323
- const agentOs2 = await ensureVm(c, config);
1324
- await agentOs2.move(from, to);
1325
- },
1326
- deleteFile: async (c, path, options) => {
1327
- const agentOs2 = await ensureVm(c, config);
1328
- await agentOs2.delete(path, options);
1329
- },
1330
- // TODO: mountFs and unmountFs are not exposed as actor actions because
1331
- // filesystem drivers (VirtualFileSystem) are not serializable over the
1332
- // network. Mount filesystems via the `options.mounts` config in agentOs()
1333
- // instead. See: https://github.com/rivet-dev/rivet/issues/XXXX
1334
- listAgents: async (c) => {
1335
- const agentOs2 = await ensureVm(c, config);
1336
- return agentOs2.listAgents();
1337
- }
1338
- };
1339
- }
1340
-
1341
- // src/agent-os/actor/network.ts
1342
- function buildNetworkActions(config) {
1343
- return {
1344
- vmFetch: async (c, port, url, options) => {
1345
- const agentOs2 = await ensureVm(c, config);
1346
- const headers = new Headers(options == null ? void 0 : options.headers);
1347
- const request = new Request(url, {
1348
- method: (options == null ? void 0 : options.method) ?? "GET",
1349
- headers,
1350
- body: (options == null ? void 0 : options.body) ?? null
1351
- });
1352
- const response = await agentOs2.fetch(port, request);
1353
- const responseHeaders = {};
1354
- response.headers.forEach((value, key) => {
1355
- responseHeaders[key] = value;
1356
- });
1357
- const body = new Uint8Array(await response.arrayBuffer());
1358
- return {
1359
- status: response.status,
1360
- statusText: response.statusText,
1361
- headers: responseHeaders,
1362
- body
1363
- };
1364
- }
1365
- };
1366
- }
1367
-
1368
- // src/agent-os/actor/preview.ts
1369
- import crypto from "crypto";
1370
- function generateToken() {
1371
- const bytes = crypto.randomBytes(32);
1372
- const alphabet = "abcdefghijklmnopqrstuvwxyz0123456789";
1373
- let token = "";
1374
- for (let i = 0; i < 32; i++) {
1375
- token += alphabet[bytes[i] % alphabet.length];
1376
- }
1377
- return token;
1378
- }
1379
- var CORS_HEADERS = {
1380
- "Access-Control-Allow-Origin": "*",
1381
- "Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, OPTIONS",
1382
- "Access-Control-Allow-Headers": "*"
1383
- };
1384
- function addCorsHeaders(response) {
1385
- const headers = new Headers(response.headers);
1386
- for (const [key, value] of Object.entries(CORS_HEADERS)) {
1387
- headers.set(key, value);
1388
- }
1389
- return new Response(response.body, {
1390
- status: response.status,
1391
- statusText: response.statusText,
1392
- headers
1393
- });
1394
- }
1395
- function buildOnRequestHandler(config) {
1396
- return async (c, request) => {
1397
- var _a;
1398
- const url = new URL(request.url);
1399
- const pathname = url.pathname;
1400
- const match = pathname.match(/^\/fetch\/([a-z0-9]+)(\/.*)?$/);
1401
- if (!match) {
1402
- return new Response("Not Found", { status: 404 });
1403
- }
1404
- if (request.method === "OPTIONS") {
1405
- return new Response(null, { status: 204, headers: CORS_HEADERS });
1406
- }
1407
- const token = match[1];
1408
- const remainingPath = match[2] ?? "/";
1409
- const now = Date.now();
1410
- const rows = await c.db.execute(
1411
- `SELECT port FROM agent_os_preview_tokens WHERE token = ? AND expires_at > ?`,
1412
- token,
1413
- now
1414
- );
1415
- if (rows.length === 0) {
1416
- c.log.warn({ msg: "agent-os preview auth failed", token });
1417
- return addCorsHeaders(new Response("Forbidden", { status: 403 }));
1418
- }
1419
- const port = (_a = rows[0]) == null ? void 0 : _a.port;
1420
- const agentOs2 = await ensureVm(
1421
- c,
1422
- config
1423
- );
1424
- const vmUrl = `http://localhost:${port}${remainingPath}${url.search}`;
1425
- const vmRequest = new Request(vmUrl, {
1426
- method: request.method,
1427
- headers: request.headers,
1428
- body: request.body,
1429
- duplex: "half"
1430
- });
1431
- const vmResponse = await agentOs2.fetch(port, vmRequest);
1432
- c.log.info({
1433
- msg: "agent-os preview request proxied",
1434
- port,
1435
- method: request.method,
1436
- path: remainingPath,
1437
- status: vmResponse.status
1438
- });
1439
- return addCorsHeaders(vmResponse);
1440
- };
1441
- }
1442
- function buildPreviewActions(config) {
1443
- return {
1444
- createSignedPreviewUrl: async (c, port, expiresInSeconds) => {
1445
- await ensureVm(c, config);
1446
- const effectiveExpires = expiresInSeconds ?? config.preview.defaultExpiresInSeconds;
1447
- const maxExpires = config.preview.maxExpiresInSeconds;
1448
- if (effectiveExpires < 1 || effectiveExpires > maxExpires) {
1449
- throw new Error(
1450
- `expiresInSeconds must be between 1 and ${maxExpires}`
1451
- );
1452
- }
1453
- const token = generateToken();
1454
- const now = Date.now();
1455
- const expiresAt = now + effectiveExpires * 1e3;
1456
- await c.db.execute(
1457
- `INSERT INTO agent_os_preview_tokens (token, port, created_at, expires_at)
1458
- VALUES (?, ?, ?, ?)`,
1459
- token,
1460
- port,
1461
- now,
1462
- expiresAt
1463
- );
1464
- await c.db.execute(
1465
- `DELETE FROM agent_os_preview_tokens WHERE expires_at <= ?`,
1466
- now
1467
- );
1468
- const path = `/request/fetch/${token}`;
1469
- c.log.info({
1470
- msg: "agent-os preview token created",
1471
- port,
1472
- expiresInSeconds: effectiveExpires
1473
- });
1474
- return { path, token, port, expiresAt };
1475
- },
1476
- expireSignedPreviewUrl: async (c, token) => {
1477
- await c.db.execute(
1478
- `DELETE FROM agent_os_preview_tokens WHERE token = ?`,
1479
- token
1480
- );
1481
- c.log.info({ msg: "agent-os preview token expired", token });
1482
- }
1483
- };
1484
- }
1485
-
1486
- // src/agent-os/actor/process.ts
1487
- function broadcastProcessEvent(c, name, payload) {
1488
- try {
1489
- c.broadcast(name, payload);
1490
- } catch (error) {
1491
- if (isRivetErrorCode(error, "actor", "stopping")) {
1492
- return;
1493
- }
1494
- throw error;
1495
- }
1496
- }
1497
- function buildProcessActions(config) {
1498
- return {
1499
- exec: async (c, command, options) => {
1500
- const agentOs2 = await ensureVm(c, config);
1501
- return agentOs2.exec(command, options);
1502
- },
1503
- spawn: async (c, command, args, options) => {
1504
- const agentOs2 = await ensureVm(c, config);
1505
- const { pid } = agentOs2.spawn(command, args, {
1506
- ...options,
1507
- onStdout: (data) => {
1508
- var _a;
1509
- broadcastProcessEvent(c, "processOutput", {
1510
- pid,
1511
- stream: "stdout",
1512
- data
1513
- });
1514
- (_a = options == null ? void 0 : options.onStdout) == null ? void 0 : _a.call(options, data);
1515
- },
1516
- onStderr: (data) => {
1517
- var _a;
1518
- broadcastProcessEvent(c, "processOutput", {
1519
- pid,
1520
- stream: "stderr",
1521
- data
1522
- });
1523
- (_a = options == null ? void 0 : options.onStderr) == null ? void 0 : _a.call(options, data);
1524
- }
1525
- });
1526
- c.vars.activeProcesses.add(pid);
1527
- syncPreventSleep(c);
1528
- c.log.info({
1529
- msg: "agent-os process spawned",
1530
- pid,
1531
- command
1532
- });
1533
- agentOs2.waitProcess(pid).then((exitCode) => {
1534
- broadcastProcessEvent(c, "processExit", { pid, exitCode });
1535
- c.log.info({
1536
- msg: "agent-os process exited",
1537
- pid,
1538
- exitCode
1539
- });
1540
- }).catch(() => {
1541
- }).finally(() => {
1542
- c.vars.activeProcesses.delete(pid);
1543
- syncPreventSleep(c);
1544
- });
1545
- return { pid };
1546
- },
1547
- writeProcessStdin: async (c, pid, data) => {
1548
- const agentOs2 = await ensureVm(c, config);
1549
- agentOs2.writeProcessStdin(pid, data);
1550
- },
1551
- closeProcessStdin: async (c, pid) => {
1552
- const agentOs2 = await ensureVm(c, config);
1553
- agentOs2.closeProcessStdin(pid);
1554
- },
1555
- waitProcess: async (c, pid) => {
1556
- const agentOs2 = await ensureVm(c, config);
1557
- return agentOs2.waitProcess(pid);
1558
- },
1559
- listProcesses: async (c) => {
1560
- const agentOs2 = await ensureVm(c, config);
1561
- return agentOs2.listProcesses();
1562
- },
1563
- allProcesses: async (c) => {
1564
- const agentOs2 = await ensureVm(c, config);
1565
- return agentOs2.allProcesses();
1566
- },
1567
- processTree: async (c) => {
1568
- const agentOs2 = await ensureVm(c, config);
1569
- return agentOs2.processTree();
1570
- },
1571
- getProcess: async (c, pid) => {
1572
- const agentOs2 = await ensureVm(c, config);
1573
- return agentOs2.getProcess(pid);
1574
- },
1575
- stopProcess: async (c, pid) => {
1576
- const agentOs2 = await ensureVm(c, config);
1577
- agentOs2.stopProcess(pid);
1578
- },
1579
- killProcess: async (c, pid) => {
1580
- const agentOs2 = await ensureVm(c, config);
1581
- agentOs2.killProcess(pid);
1582
- }
1583
- };
1584
- }
1585
-
1586
- // src/agent-os/actor/session.ts
1587
- function stripFunctions(value) {
1588
- if (value === null || value === void 0) return value;
1589
- if (typeof value === "function") return void 0;
1590
- if (typeof value !== "object") return value;
1591
- if (Array.isArray(value)) return value.map(stripFunctions);
1592
- const out = {};
1593
- for (const [k, v] of Object.entries(value)) {
1594
- if (typeof v !== "function") {
1595
- out[k] = stripFunctions(v);
1596
- }
1597
- }
1598
- return out;
1599
- }
1600
- function assertSessionExists(c, sessionId) {
1601
- if (!c.vars.sessions.has(sessionId)) {
1602
- throw new Error(`session not found: ${sessionId}`);
1603
- }
1604
- }
1605
- function toSessionRecord(agentOs2, sessionId, agentType) {
1606
- return {
1607
- sessionId,
1608
- agentType,
1609
- capabilities: agentOs2.getSessionCapabilities(sessionId) ?? {},
1610
- agentInfo: agentOs2.getSessionAgentInfo(sessionId)
1611
- };
1612
- }
1613
- async function persistSession(c, agentOs2, sessionId, agentType) {
1614
- const now = Date.now();
1615
- const capabilities = agentOs2.getSessionCapabilities(sessionId) ?? {};
1616
- const agentInfo = agentOs2.getSessionAgentInfo(sessionId);
1617
- await c.db.execute(
1618
- `INSERT OR REPLACE INTO agent_os_sessions (session_id, agent_type, capabilities, agent_info, created_at)
1619
- VALUES (?, ?, ?, ?, ?)`,
1620
- sessionId,
1621
- agentType,
1622
- JSON.stringify(capabilities),
1623
- agentInfo ? JSON.stringify(agentInfo) : null,
1624
- now
1625
- );
1626
- }
1627
- async function persistSessionEvent(c, sessionId, event2) {
1628
- var _a;
1629
- const now = Date.now();
1630
- const rows = await c.db.execute(
1631
- `SELECT MAX(seq) as max_seq FROM agent_os_session_events WHERE session_id = ?`,
1632
- sessionId
1633
- );
1634
- const nextSeq = (((_a = rows[0]) == null ? void 0 : _a.max_seq) ?? -1) + 1;
1635
- await c.db.execute(
1636
- `INSERT INTO agent_os_session_events (session_id, seq, event, created_at)
1637
- VALUES (?, ?, ?, ?)`,
1638
- sessionId,
1639
- nextSeq,
1640
- JSON.stringify(event2),
1641
- now
1642
- );
1643
- }
1644
- async function deletePersistedSession(c, sessionId) {
1645
- await c.db.execute(
1646
- `DELETE FROM agent_os_session_events WHERE session_id = ?`,
1647
- sessionId
1648
- );
1649
- await c.db.execute(
1650
- `DELETE FROM agent_os_sessions WHERE session_id = ?`,
1651
- sessionId
1652
- );
1653
- }
1654
- function subscribeToSession(c, agentOs2, sessionId, parsedConfig) {
1655
- agentOs2.onSessionEvent(sessionId, (event2) => {
1656
- c.broadcast(
1657
- "sessionEvent",
1658
- JSON.parse(JSON.stringify({ sessionId, event: event2 }))
1659
- );
1660
- persistSessionEvent(c, sessionId, event2).catch(
1661
- (error) => c.log.error({
1662
- msg: "agent-os failed to persist session event",
1663
- sessionId,
1664
- error
1665
- })
1666
- );
1667
- if (parsedConfig.onSessionEvent) {
1668
- runHook(
1669
- c,
1670
- "onSessionEvent",
1671
- () => {
1672
- var _a;
1673
- return (_a = parsedConfig.onSessionEvent) == null ? void 0 : _a.call(parsedConfig, c, sessionId, event2);
1674
- }
1675
- );
1676
- }
1677
- });
1678
- agentOs2.onPermissionRequest(sessionId, (request) => {
1679
- c.broadcast(
1680
- "permissionRequest",
1681
- JSON.parse(JSON.stringify({ sessionId, request }))
1682
- );
1683
- if (parsedConfig.onPermissionRequest) {
1684
- runHook(
1685
- c,
1686
- "onPermissionRequest",
1687
- () => {
1688
- var _a;
1689
- return (_a = parsedConfig.onPermissionRequest) == null ? void 0 : _a.call(parsedConfig, c, sessionId, request);
1690
- }
1691
- );
1692
- }
1693
- });
1694
- c.vars.sessions.add(sessionId);
1695
- }
1696
- function buildSessionActions(config) {
1697
- return {
1698
- createSession: async (c, agentType, options) => {
1699
- const agentOs2 = await ensureVm(c, config);
1700
- const { sessionId } = await agentOs2.createSession(
1701
- agentType,
1702
- options
1703
- );
1704
- subscribeToSession(c, agentOs2, sessionId, config);
1705
- await persistSession(c, agentOs2, sessionId, agentType);
1706
- c.log.info({
1707
- msg: "agent-os session created",
1708
- sessionId,
1709
- agentType
1710
- });
1711
- return toSessionRecord(agentOs2, sessionId, agentType);
1712
- },
1713
- listSessions: async (c) => {
1714
- const agentOs2 = await ensureVm(c, config);
1715
- return agentOs2.listSessions();
1716
- },
1717
- getSession: async (c, sessionId) => {
1718
- assertSessionExists(c, sessionId);
1719
- const agentOs2 = await ensureVm(c, config);
1720
- const info = agentOs2.listSessions().find((s) => s.sessionId === sessionId);
1721
- if (!info) {
1722
- throw new Error(`session not found: ${sessionId}`);
1723
- }
1724
- return toSessionRecord(agentOs2, sessionId, info.agentType);
1725
- },
1726
- destroySession: async (c, sessionId) => {
1727
- const agentOs2 = await ensureVm(c, config);
1728
- await agentOs2.destroySession(sessionId);
1729
- c.vars.sessions.delete(sessionId);
1730
- c.vars.activeSessionIds.delete(sessionId);
1731
- syncPreventSleep(c);
1732
- await deletePersistedSession(c, sessionId);
1733
- c.log.info({ msg: "agent-os session destroyed", sessionId });
1734
- },
1735
- resumeSession: async (c, sessionId) => {
1736
- const agentOs2 = await ensureVm(c, config);
1737
- return agentOs2.resumeSession(sessionId);
1738
- },
1739
- closeSession: async (c, sessionId) => {
1740
- const agentOs2 = await ensureVm(c, config);
1741
- agentOs2.closeSession(sessionId);
1742
- c.vars.sessions.delete(sessionId);
1743
- c.vars.activeSessionIds.delete(sessionId);
1744
- syncPreventSleep(c);
1745
- await deletePersistedSession(c, sessionId);
1746
- c.log.info({ msg: "agent-os session closed", sessionId });
1747
- }
1748
- };
1749
- }
1750
- function buildPromptActions(_config) {
1751
- return {
1752
- sendPrompt: async (c, sessionId, text) => {
1753
- if (c.aborted) {
1754
- throw new Error(
1755
- "actor is shutting down, cannot start new prompt"
1756
- );
1757
- }
1758
- assertSessionExists(c, sessionId);
1759
- const agentOs2 = c.vars.agentOs;
1760
- if (!agentOs2) {
1761
- throw new Error("VM not initialized");
1762
- }
1763
- c.vars.activeSessionIds.add(sessionId);
1764
- syncPreventSleep(c);
1765
- c.log.info({ msg: "agent-os prompt turn started", sessionId });
1766
- const start = Date.now();
1767
- try {
1768
- const result = await agentOs2.prompt(sessionId, text);
1769
- return {
1770
- response: JSON.parse(JSON.stringify(result.response)),
1771
- text: result.text
1772
- };
1773
- } finally {
1774
- c.vars.activeSessionIds.delete(sessionId);
1775
- syncPreventSleep(c);
1776
- c.log.info({
1777
- msg: "agent-os prompt turn ended",
1778
- sessionId,
1779
- durationMs: Date.now() - start
1780
- });
1781
- }
1782
- },
1783
- cancelPrompt: async (c, sessionId) => {
1784
- assertSessionExists(c, sessionId);
1785
- const agentOs2 = c.vars.agentOs;
1786
- if (!agentOs2) {
1787
- throw new Error("VM not initialized");
1788
- }
1789
- return stripFunctions(
1790
- agentOs2.cancelSession(sessionId)
1791
- );
1792
- },
1793
- respondPermission: async (c, sessionId, permissionId, reply) => {
1794
- assertSessionExists(c, sessionId);
1795
- const agentOs2 = c.vars.agentOs;
1796
- if (!agentOs2) {
1797
- throw new Error("VM not initialized");
1798
- }
1799
- return stripFunctions(
1800
- agentOs2.respondPermission(sessionId, permissionId, reply)
1801
- );
1802
- }
1803
- };
1804
- }
1805
- function buildConfigActions(_config) {
1806
- return {
1807
- setMode: async (c, sessionId, modeId) => {
1808
- assertSessionExists(c, sessionId);
1809
- const agentOs2 = c.vars.agentOs;
1810
- if (!agentOs2) {
1811
- throw new Error("VM not initialized");
1812
- }
1813
- return stripFunctions(
1814
- agentOs2.setSessionMode(sessionId, modeId)
1815
- );
1816
- },
1817
- getModes: async (c, sessionId) => {
1818
- assertSessionExists(c, sessionId);
1819
- const agentOs2 = c.vars.agentOs;
1820
- if (!agentOs2) {
1821
- throw new Error("VM not initialized");
1822
- }
1823
- return agentOs2.getSessionModes(sessionId);
1824
- },
1825
- setModel: async (c, sessionId, model) => {
1826
- assertSessionExists(c, sessionId);
1827
- const agentOs2 = c.vars.agentOs;
1828
- if (!agentOs2) {
1829
- throw new Error("VM not initialized");
1830
- }
1831
- return stripFunctions(
1832
- agentOs2.setSessionModel(sessionId, model)
1833
- );
1834
- },
1835
- setThoughtLevel: async (c, sessionId, level) => {
1836
- assertSessionExists(c, sessionId);
1837
- const agentOs2 = c.vars.agentOs;
1838
- if (!agentOs2) {
1839
- throw new Error("VM not initialized");
1840
- }
1841
- return stripFunctions(
1842
- agentOs2.setSessionThoughtLevel(sessionId, level)
1843
- );
1844
- },
1845
- getConfigOptions: async (c, sessionId) => {
1846
- assertSessionExists(c, sessionId);
1847
- const agentOs2 = c.vars.agentOs;
1848
- if (!agentOs2) {
1849
- throw new Error("VM not initialized");
1850
- }
1851
- return agentOs2.getSessionConfigOptions(sessionId);
1852
- },
1853
- getEvents: async (c, sessionId, options) => {
1854
- assertSessionExists(c, sessionId);
1855
- const agentOs2 = c.vars.agentOs;
1856
- if (!agentOs2) {
1857
- throw new Error("VM not initialized");
1858
- }
1859
- return agentOs2.getSessionEvents(sessionId, options).map((e) => e.notification);
1860
- },
1861
- getSequencedEvents: async (c, sessionId, options) => {
1862
- assertSessionExists(c, sessionId);
1863
- const agentOs2 = c.vars.agentOs;
1864
- if (!agentOs2) {
1865
- throw new Error("VM not initialized");
1866
- }
1867
- return agentOs2.getSessionEvents(sessionId, options);
1868
- },
1869
- rawSend: async (c, sessionId, method, params) => {
1870
- assertSessionExists(c, sessionId);
1871
- const agentOs2 = c.vars.agentOs;
1872
- if (!agentOs2) {
1873
- throw new Error("VM not initialized");
1874
- }
1875
- return stripFunctions(
1876
- agentOs2.rawSessionSend(sessionId, method, params)
1877
- );
1878
- }
1879
- };
1880
- }
1881
- function buildSessionPersistenceActions(_config) {
1882
- return {
1883
- listPersistedSessions: async (c) => {
1884
- const rows = await c.db.execute(
1885
- `SELECT session_id, agent_type, capabilities, agent_info, created_at
1886
- FROM agent_os_sessions
1887
- ORDER BY created_at ASC`
1888
- );
1889
- return rows.map((row) => ({
1890
- sessionId: row.session_id,
1891
- agentType: row.agent_type,
1892
- capabilities: JSON.parse(row.capabilities),
1893
- agentInfo: row.agent_info ? JSON.parse(row.agent_info) : null,
1894
- createdAt: row.created_at
1895
- }));
1896
- },
1897
- getSessionEvents: async (c, sessionId) => {
1898
- const rows = await c.db.execute(
1899
- `SELECT session_id, seq, event, created_at
1900
- FROM agent_os_session_events
1901
- WHERE session_id = ?
1902
- ORDER BY seq ASC`,
1903
- sessionId
1904
- );
1905
- return rows.map((row) => ({
1906
- sessionId: row.session_id,
1907
- seq: row.seq,
1908
- event: JSON.parse(row.event),
1909
- createdAt: row.created_at
1910
- }));
1911
- }
1912
- };
1913
- }
1914
-
1915
- // src/agent-os/actor/shell.ts
1916
- function buildShellActions(config) {
1917
- return {
1918
- openShell: async (c, options) => {
1919
- const agentOs2 = await ensureVm(c, config);
1920
- const { shellId } = agentOs2.openShell(options);
1921
- agentOs2.onShellData(shellId, (data) => {
1922
- c.broadcast("shellData", { shellId, data });
1923
- });
1924
- c.vars.activeShells.add(shellId);
1925
- syncPreventSleep(c);
1926
- c.log.info({ msg: "agent-os shell opened", shellId });
1927
- return { shellId };
1928
- },
1929
- writeShell: async (c, shellId, data) => {
1930
- const agentOs2 = await ensureVm(c, config);
1931
- agentOs2.writeShell(shellId, data);
1932
- },
1933
- resizeShell: async (c, shellId, cols, rows) => {
1934
- const agentOs2 = await ensureVm(c, config);
1935
- agentOs2.resizeShell(shellId, cols, rows);
1936
- },
1937
- closeShell: async (c, shellId) => {
1938
- const agentOs2 = await ensureVm(c, config);
1939
- agentOs2.closeShell(shellId);
1940
- c.vars.activeShells.delete(shellId);
1941
- syncPreventSleep(c);
1942
- c.log.info({ msg: "agent-os shell closed", shellId });
1943
- }
1944
- };
1945
- }
1946
-
1947
- // src/agent-os/actor/index.ts
1948
- async function ensureVm(c, config) {
1949
- if (c.vars.agentOs) {
1950
- return c.vars.agentOs;
1951
- }
1952
- const start = Date.now();
1953
- const options = buildVmOptions(config.options);
1954
- const agentOs2 = await AgentOs.create(options);
1955
- c.vars.agentOs = agentOs2;
1956
- agentOs2.onCronEvent((cronEvent) => {
1957
- c.broadcast("cronEvent", { event: cronEvent });
1958
- });
1959
- c.broadcast("vmBooted", {});
1960
- c.log.info({
1961
- msg: "agent-os vm booted",
1962
- bootDurationMs: Date.now() - start
1963
- });
1964
- return agentOs2;
1965
- }
1966
- function buildVmOptions(userOptions) {
1967
- const userMounts = (userOptions == null ? void 0 : userOptions.mounts) ?? [];
1968
- const hasWorkdirMount = userMounts.some(
1969
- (m) => m.path === "/home/user"
1970
- );
1971
- if (hasWorkdirMount) {
1972
- return userOptions ?? {};
1973
- }
1974
- const memMount = {
1975
- path: "/home/user",
1976
- driver: createInMemoryFileSystem()
1977
- };
1978
- return {
1979
- ...userOptions,
1980
- mounts: [memMount, ...userMounts]
1981
- };
1982
- }
1983
- function syncPreventSleep(c) {
1984
- const shouldPrevent = c.vars.activeSessionIds.size > 0 || c.vars.activeProcesses.size > 0 || c.vars.activeHooks.size > 0 || c.vars.activeShells.size > 0;
1985
- c.setPreventSleep(shouldPrevent);
1986
- c.log.info({
1987
- msg: "agent-os prevent sleep sync",
1988
- preventSleep: shouldPrevent,
1989
- activeSessions: c.vars.activeSessionIds.size,
1990
- activeProcesses: c.vars.activeProcesses.size,
1991
- activeHooks: c.vars.activeHooks.size,
1992
- activeShells: c.vars.activeShells.size
1993
- });
1994
- }
1995
- function runHook(c, name, callback) {
1996
- const promise = Promise.resolve(callback()).catch(
1997
- (error) => c.log.error({ msg: "agent-os hook failed", hookName: name, error })
1998
- ).finally(() => {
1999
- c.vars.activeHooks.delete(promise);
2000
- syncPreventSleep(c);
2001
- });
2002
- c.vars.activeHooks.add(promise);
2003
- syncPreventSleep(c);
2004
- c.waitUntil(promise);
2005
- }
2006
- function agentOs(config) {
2007
- const parsedConfig = agentOsActorConfigSchema.parse(
2008
- config
2009
- );
2010
- const actions = {
2011
- ...buildSessionActions(parsedConfig),
2012
- ...buildPromptActions(parsedConfig),
2013
- ...buildConfigActions(parsedConfig),
2014
- ...buildSessionPersistenceActions(parsedConfig),
2015
- ...buildProcessActions(parsedConfig),
2016
- ...buildFilesystemActions(parsedConfig),
2017
- ...buildPreviewActions(parsedConfig),
2018
- ...buildShellActions(parsedConfig),
2019
- ...buildCronActions(parsedConfig),
2020
- ...buildNetworkActions(parsedConfig)
2021
- };
2022
- return actor({
2023
- options: {
2024
- sleepGracePeriod: 9e5,
2025
- actionTimeout: 9e5
2026
- },
2027
- createState: async () => ({}),
2028
- createVars: () => ({
2029
- agentOs: null,
2030
- activeSessionIds: /* @__PURE__ */ new Set(),
2031
- activeProcesses: /* @__PURE__ */ new Set(),
2032
- activeHooks: /* @__PURE__ */ new Set(),
2033
- activeShells: /* @__PURE__ */ new Set(),
2034
- sessions: /* @__PURE__ */ new Set()
2035
- }),
2036
- db: db({
2037
- onMigrate: migrateAgentOsTables
2038
- }),
2039
- events: {
2040
- sessionEvent: sessionEventToken,
2041
- permissionRequest: permissionRequestToken,
2042
- vmBooted: vmBootedToken,
2043
- vmShutdown: vmShutdownToken,
2044
- processOutput: processOutputToken,
2045
- processExit: processExitToken,
2046
- shellData: shellDataToken,
2047
- cronEvent: cronEventToken
2048
- },
2049
- onBeforeConnect: parsedConfig.onBeforeConnect ? async (ctx, params) => {
2050
- var _a;
2051
- if (ctx.request) {
2052
- const url = new URL(ctx.request.url);
2053
- if (url.pathname.startsWith("/fetch/")) {
2054
- return;
2055
- }
2056
- }
2057
- await ((_a = parsedConfig.onBeforeConnect) == null ? void 0 : _a.call(parsedConfig, ctx, params));
2058
- } : void 0,
2059
- onRequest: buildOnRequestHandler(parsedConfig),
2060
- onSleep: async (c) => {
2061
- c.log.info({
2062
- msg: "agent-os vm shutdown for sleep",
2063
- activeSessions: c.vars.sessions.size,
2064
- activeProcesses: c.vars.activeProcesses.size,
2065
- activeShells: c.vars.activeShells.size
2066
- });
2067
- if (c.vars.agentOs) {
2068
- await c.vars.agentOs.dispose();
2069
- c.vars.agentOs = null;
2070
- }
2071
- c.broadcast("vmShutdown", { reason: "sleep" });
2072
- },
2073
- onDestroy: async (c) => {
2074
- c.log.info({
2075
- msg: "agent-os vm shutdown for destroy",
2076
- activeSessions: c.vars.sessions.size,
2077
- activeProcesses: c.vars.activeProcesses.size,
2078
- activeShells: c.vars.activeShells.size
2079
- });
2080
- if (c.vars.agentOs) {
2081
- await c.vars.agentOs.dispose();
2082
- c.vars.agentOs = null;
2083
- }
2084
- c.broadcast("vmShutdown", { reason: "destroy" });
2085
- },
2086
- actions
2087
- });
2088
- }
2089
- var sessionEventToken = event();
2090
- var permissionRequestToken = event();
2091
- var vmBootedToken = event();
2092
- var vmShutdownToken = event();
2093
- var processOutputToken = event();
2094
- var processExitToken = event();
2095
- var shellDataToken = event();
2096
- var cronEventToken = event();
2097
-
2098
- // src/agent-os/actor/cron.ts
2099
- function serializeCronAction(action) {
2100
- var _a;
2101
- switch (action.type) {
2102
- case "session":
2103
- return {
2104
- type: "session",
2105
- agentType: action.agentType,
2106
- prompt: action.prompt,
2107
- cwd: (_a = action.options) == null ? void 0 : _a.cwd
2108
- };
2109
- case "exec":
2110
- return {
2111
- type: "exec",
2112
- command: action.command,
2113
- args: action.args
2114
- };
2115
- case "callback":
2116
- throw new TypeError("callback cron actions are not serializable");
2117
- }
2118
- }
2119
- function serializeCronJob(job) {
2120
- var _a, _b;
2121
- return {
2122
- id: job.id,
2123
- schedule: job.schedule,
2124
- action: serializeCronAction(job.action),
2125
- overlap: job.overlap,
2126
- lastRun: (_a = job.lastRun) == null ? void 0 : _a.toISOString(),
2127
- nextRun: (_b = job.nextRun) == null ? void 0 : _b.toISOString(),
2128
- runCount: job.runCount,
2129
- running: job.running
2130
- };
2131
- }
2132
- function buildCronActions(config) {
2133
- return {
2134
- scheduleCron: async (c, options) => {
2135
- const agentOs2 = await ensureVm(c, config);
2136
- const job = agentOs2.scheduleCron({
2137
- id: options.id,
2138
- schedule: options.schedule,
2139
- action: options.action,
2140
- overlap: options.overlap
2141
- });
2142
- c.log.info({
2143
- msg: "agent-os cron job scheduled",
2144
- jobId: job.id,
2145
- schedule: options.schedule
2146
- });
2147
- return { id: job.id };
2148
- },
2149
- listCronJobs: async (c) => {
2150
- const agentOs2 = await ensureVm(c, config);
2151
- return agentOs2.listCronJobs().map(serializeCronJob);
2152
- },
2153
- cancelCronJob: async (c, id) => {
2154
- const agentOs2 = await ensureVm(c, config);
2155
- agentOs2.cancelCronJob(id);
2156
- c.log.info({ msg: "agent-os cron job cancelled", jobId: id });
2157
- }
2158
- };
2159
- }
2160
-
2161
- // src/agent-os/fs/database-vfs.ts
2162
- import * as posixPath from "path/posix";
2163
- var S_IFDIR = 16384;
2164
- var S_IFREG = 32768;
2165
- var S_IFLNK = 40960;
2166
- var DEFAULT_FILE_MODE = S_IFREG | 420;
2167
- var DEFAULT_DIR_MODE = S_IFDIR | 493;
2168
- function normPath(p) {
2169
- const normalized = posixPath.normalize(`/${p}`);
2170
- if (normalized.length > 1 && normalized.endsWith("/")) {
2171
- return normalized.slice(0, -1);
2172
- }
2173
- return normalized;
2174
- }
2175
- function parentPath(p) {
2176
- const parent = posixPath.dirname(p);
2177
- return parent;
2178
- }
2179
- function throwENOENT(path) {
2180
- const err = new Error(`ENOENT: no such file or directory: ${path}`);
2181
- err.name = "ENOENT";
2182
- throw err;
2183
- }
2184
- function throwEEXIST(path) {
2185
- const err = new Error(`EEXIST: file already exists: ${path}`);
2186
- err.name = "EEXIST";
2187
- throw err;
2188
- }
2189
- function throwENOTDIR(path) {
2190
- const err = new Error(`ENOTDIR: not a directory: ${path}`);
2191
- err.name = "ENOTDIR";
2192
- throw err;
2193
- }
2194
- function throwEISDIR(path) {
2195
- const err = new Error(`EISDIR: illegal operation on a directory: ${path}`);
2196
- err.name = "EISDIR";
2197
- throw err;
2198
- }
2199
- function throwENOTEMPTY(path) {
2200
- const err = new Error(`ENOTEMPTY: directory not empty: ${path}`);
2201
- err.name = "ENOTEMPTY";
2202
- throw err;
2203
- }
2204
- function throwENOSYS(op) {
2205
- const err = new Error(`ENOSYS: function not implemented: ${op}`);
2206
- err.name = "ENOSYS";
2207
- throw err;
2208
- }
2209
- function rowToStat(row) {
2210
- return {
2211
- mode: row.mode,
2212
- size: row.size,
2213
- isDirectory: row.is_directory === 1,
2214
- isSymbolicLink: row.symlink_target !== null,
2215
- atimeMs: row.atime_ms,
2216
- mtimeMs: row.mtime_ms,
2217
- ctimeMs: row.ctime_ms,
2218
- birthtimeMs: row.birthtime_ms,
2219
- ino: 0,
2220
- nlink: row.nlink,
2221
- uid: row.uid,
2222
- gid: row.gid
2223
- };
2224
- }
2225
- function createDatabaseVfs(options) {
2226
- const { db: db2 } = options;
2227
- async function getEntry(path) {
2228
- const rows = await db2.execute(
2229
- "SELECT * FROM agent_os_fs_entries WHERE path = ?",
2230
- path
2231
- );
2232
- return rows[0];
2233
- }
2234
- async function getEntryOrThrow(path) {
2235
- const entry = await getEntry(path);
2236
- if (!entry) {
2237
- throwENOENT(path);
2238
- }
2239
- return entry;
2240
- }
2241
- async function ensureParentExists(path) {
2242
- const parent = parentPath(path);
2243
- if (parent === path) return;
2244
- const entry = await getEntry(parent);
2245
- if (!entry) {
2246
- throwENOENT(parent);
2247
- }
2248
- if (entry.is_directory !== 1) {
2249
- throwENOTDIR(parent);
2250
- }
2251
- }
2252
- async function getChildEntries(dirPath) {
2253
- const prefix = dirPath === "/" ? "/" : `${dirPath}/`;
2254
- const rows = await db2.execute(
2255
- "SELECT * FROM agent_os_fs_entries WHERE path LIKE ? AND path != ?",
2256
- `${prefix}%`,
2257
- dirPath
2258
- );
2259
- return rows.filter((row) => {
2260
- const relative = row.path.slice(prefix.length);
2261
- return relative.length > 0 && !relative.includes("/");
2262
- });
2263
- }
2264
- const rootInit = (async () => {
2265
- const root = await getEntry("/");
2266
- if (!root) {
2267
- const now = Date.now();
2268
- await db2.execute(
2269
- `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)`,
2270
- "/",
2271
- DEFAULT_DIR_MODE,
2272
- now,
2273
- now,
2274
- now,
2275
- now
2276
- );
2277
- }
2278
- })();
2279
- const backend = {
2280
- async readFile(p) {
2281
- await rootInit;
2282
- const path = normPath(p);
2283
- const entry = await getEntryOrThrow(path);
2284
- if (entry.is_directory === 1) {
2285
- throwEISDIR(path);
2286
- }
2287
- return entry.content ?? new Uint8Array(0);
2288
- },
2289
- async readTextFile(p) {
2290
- const data = await backend.readFile(p);
2291
- return new TextDecoder().decode(data);
2292
- },
2293
- async readDir(p) {
2294
- await rootInit;
2295
- const path = normPath(p);
2296
- const entry = await getEntryOrThrow(path);
2297
- if (entry.is_directory !== 1) {
2298
- throwENOTDIR(path);
2299
- }
2300
- const children = await getChildEntries(path);
2301
- return children.map((child) => posixPath.basename(child.path));
2302
- },
2303
- async readDirWithTypes(p) {
2304
- await rootInit;
2305
- const path = normPath(p);
2306
- const entry = await getEntryOrThrow(path);
2307
- if (entry.is_directory !== 1) {
2308
- throwENOTDIR(path);
2309
- }
2310
- const children = await getChildEntries(path);
2311
- return children.map((child) => ({
2312
- name: posixPath.basename(child.path),
2313
- isDirectory: child.is_directory === 1,
2314
- isSymbolicLink: child.symlink_target !== null,
2315
- ino: 0
2316
- }));
2317
- },
2318
- async writeFile(p, content) {
2319
- await rootInit;
2320
- const path = normPath(p);
2321
- await ensureParentExists(path);
2322
- const existing = await getEntry(path);
2323
- if (existing && existing.is_directory === 1) {
2324
- throwEISDIR(path);
2325
- }
2326
- const data = typeof content === "string" ? new TextEncoder().encode(content) : content;
2327
- const now = Date.now();
2328
- if (existing) {
2329
- await db2.execute(
2330
- `UPDATE agent_os_fs_entries SET content = ?, size = ?, mtime_ms = ?, ctime_ms = ?, atime_ms = ? WHERE path = ?`,
2331
- data,
2332
- data.byteLength,
2333
- now,
2334
- now,
2335
- now,
2336
- path
2337
- );
2338
- } else {
2339
- await db2.execute(
2340
- `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)`,
2341
- path,
2342
- data,
2343
- DEFAULT_FILE_MODE,
2344
- data.byteLength,
2345
- now,
2346
- now,
2347
- now,
2348
- now
2349
- );
2350
- }
2351
- },
2352
- async createDir(p) {
2353
- await rootInit;
2354
- const path = normPath(p);
2355
- await ensureParentExists(path);
2356
- const existing = await getEntry(path);
2357
- if (existing) {
2358
- throwEEXIST(path);
2359
- }
2360
- const now = Date.now();
2361
- await db2.execute(
2362
- `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)`,
2363
- path,
2364
- DEFAULT_DIR_MODE,
2365
- now,
2366
- now,
2367
- now,
2368
- now
2369
- );
2370
- },
2371
- async mkdir(p, options2) {
2372
- await rootInit;
2373
- const path = normPath(p);
2374
- if (options2 == null ? void 0 : options2.recursive) {
2375
- const parts = path.split("/").filter(Boolean);
2376
- let current = "";
2377
- for (const part of parts) {
2378
- current += `/${part}`;
2379
- const existing = await getEntry(current);
2380
- if (!existing) {
2381
- const now = Date.now();
2382
- await db2.execute(
2383
- `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)`,
2384
- current,
2385
- DEFAULT_DIR_MODE,
2386
- now,
2387
- now,
2388
- now,
2389
- now
2390
- );
2391
- } else if (existing.is_directory !== 1) {
2392
- throwENOTDIR(current);
2393
- }
2394
- }
2395
- } else {
2396
- await backend.createDir(p);
2397
- }
2398
- },
2399
- async exists(p) {
2400
- await rootInit;
2401
- const path = normPath(p);
2402
- const entry = await getEntry(path);
2403
- return entry !== void 0;
2404
- },
2405
- async stat(p) {
2406
- await rootInit;
2407
- const path = normPath(p);
2408
- const entry = await getEntryOrThrow(path);
2409
- return rowToStat(entry);
2410
- },
2411
- async removeFile(p) {
2412
- await rootInit;
2413
- const path = normPath(p);
2414
- const entry = await getEntryOrThrow(path);
2415
- if (entry.is_directory === 1) {
2416
- throwEISDIR(path);
2417
- }
2418
- await db2.execute(
2419
- "DELETE FROM agent_os_fs_entries WHERE path = ?",
2420
- path
2421
- );
2422
- },
2423
- async removeDir(p) {
2424
- await rootInit;
2425
- const path = normPath(p);
2426
- const entry = await getEntryOrThrow(path);
2427
- if (entry.is_directory !== 1) {
2428
- throwENOTDIR(path);
2429
- }
2430
- const children = await getChildEntries(path);
2431
- if (children.length > 0) {
2432
- throwENOTEMPTY(path);
2433
- }
2434
- await db2.execute(
2435
- "DELETE FROM agent_os_fs_entries WHERE path = ?",
2436
- path
2437
- );
2438
- },
2439
- async rename(oldPath, newPath) {
2440
- await rootInit;
2441
- const from = normPath(oldPath);
2442
- const to = normPath(newPath);
2443
- const entry = await getEntryOrThrow(from);
2444
- await ensureParentExists(to);
2445
- const destEntry = await getEntry(to);
2446
- if (destEntry) {
2447
- if (destEntry.is_directory === 1) {
2448
- const children = await getChildEntries(to);
2449
- if (children.length > 0) {
2450
- throwENOTEMPTY(to);
2451
- }
2452
- }
2453
- await db2.execute(
2454
- "DELETE FROM agent_os_fs_entries WHERE path = ?",
2455
- to
2456
- );
2457
- }
2458
- if (entry.is_directory === 1) {
2459
- const prefix = from === "/" ? "/" : `${from}/`;
2460
- const newPrefix = to === "/" ? "/" : `${to}/`;
2461
- const descendants = await db2.execute(
2462
- "SELECT path FROM agent_os_fs_entries WHERE path LIKE ?",
2463
- `${prefix}%`
2464
- );
2465
- for (const desc of descendants) {
2466
- const newDescPath = newPrefix + desc.path.slice(prefix.length);
2467
- await db2.execute(
2468
- "UPDATE agent_os_fs_entries SET path = ? WHERE path = ?",
2469
- newDescPath,
2470
- desc.path
2471
- );
2472
- }
2473
- }
2474
- const now = Date.now();
2475
- await db2.execute(
2476
- "UPDATE agent_os_fs_entries SET path = ?, ctime_ms = ? WHERE path = ?",
2477
- to,
2478
- now,
2479
- from
2480
- );
2481
- },
2482
- async realpath(p) {
2483
- await rootInit;
2484
- const path = normPath(p);
2485
- const entry = await getEntryOrThrow(path);
2486
- if (entry.symlink_target !== null) {
2487
- return normPath(entry.symlink_target);
2488
- }
2489
- return path;
2490
- },
2491
- async symlink(target, linkPath) {
2492
- await rootInit;
2493
- const link = normPath(linkPath);
2494
- await ensureParentExists(link);
2495
- const existing = await getEntry(link);
2496
- if (existing) {
2497
- throwEEXIST(link);
2498
- }
2499
- const now = Date.now();
2500
- await db2.execute(
2501
- `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)`,
2502
- link,
2503
- S_IFLNK | 511,
2504
- target.length,
2505
- now,
2506
- now,
2507
- now,
2508
- now,
2509
- target
2510
- );
2511
- },
2512
- async readlink(p) {
2513
- await rootInit;
2514
- const path = normPath(p);
2515
- const entry = await getEntryOrThrow(path);
2516
- if (entry.symlink_target === null) {
2517
- const err = new Error(`EINVAL: not a symlink: ${path}`);
2518
- err.name = "EINVAL";
2519
- throw err;
2520
- }
2521
- return entry.symlink_target;
2522
- },
2523
- async lstat(p) {
2524
- return backend.stat(p);
2525
- },
2526
- async link(_oldPath, _newPath) {
2527
- throwENOSYS("link");
2528
- },
2529
- async chmod(p, mode) {
2530
- await rootInit;
2531
- const path = normPath(p);
2532
- await getEntryOrThrow(path);
2533
- const now = Date.now();
2534
- await db2.execute(
2535
- "UPDATE agent_os_fs_entries SET mode = ?, ctime_ms = ? WHERE path = ?",
2536
- mode,
2537
- now,
2538
- path
2539
- );
2540
- },
2541
- async chown(p, uid, gid) {
2542
- await rootInit;
2543
- const path = normPath(p);
2544
- await getEntryOrThrow(path);
2545
- const now = Date.now();
2546
- await db2.execute(
2547
- "UPDATE agent_os_fs_entries SET uid = ?, gid = ?, ctime_ms = ? WHERE path = ?",
2548
- uid,
2549
- gid,
2550
- now,
2551
- path
2552
- );
2553
- },
2554
- async utimes(p, atime, mtime) {
2555
- await rootInit;
2556
- const path = normPath(p);
2557
- await getEntryOrThrow(path);
2558
- const now = Date.now();
2559
- await db2.execute(
2560
- "UPDATE agent_os_fs_entries SET atime_ms = ?, mtime_ms = ?, ctime_ms = ? WHERE path = ?",
2561
- atime,
2562
- mtime,
2563
- now,
2564
- path
2565
- );
2566
- },
2567
- async truncate(p, length) {
2568
- await rootInit;
2569
- const path = normPath(p);
2570
- const entry = await getEntryOrThrow(path);
2571
- if (entry.is_directory === 1) {
2572
- throwEISDIR(path);
2573
- }
2574
- const existing = entry.content ?? new Uint8Array(0);
2575
- let newContent;
2576
- if (length >= existing.byteLength) {
2577
- newContent = new Uint8Array(length);
2578
- newContent.set(existing);
2579
- } else {
2580
- newContent = existing.slice(0, length);
2581
- }
2582
- const now = Date.now();
2583
- await db2.execute(
2584
- "UPDATE agent_os_fs_entries SET content = ?, size = ?, mtime_ms = ?, ctime_ms = ? WHERE path = ?",
2585
- newContent,
2586
- length,
2587
- now,
2588
- now,
2589
- path
2590
- );
2591
- },
2592
- async pread(p, offset, length) {
2593
- await rootInit;
2594
- const path = normPath(p);
2595
- const entry = await getEntryOrThrow(path);
2596
- if (entry.is_directory === 1) {
2597
- throwEISDIR(path);
2598
- }
2599
- const content = entry.content ?? new Uint8Array(0);
2600
- const end = Math.min(offset + length, content.byteLength);
2601
- if (offset >= content.byteLength) {
2602
- return new Uint8Array(0);
2603
- }
2604
- return content.slice(offset, end);
2605
- },
2606
- async pwrite(p, offset, data) {
2607
- await rootInit;
2608
- const path = normPath(p);
2609
- const entry = await getEntryOrThrow(path);
2610
- if (entry.is_directory === 1) {
2611
- throwEISDIR(path);
2612
- }
2613
- const content = entry.content ?? new Uint8Array(0);
2614
- const end = offset + data.byteLength;
2615
- const newSize = Math.max(content.byteLength, end);
2616
- const buf = new Uint8Array(newSize);
2617
- buf.set(content);
2618
- buf.set(data, offset);
2619
- const now = Date.now();
2620
- await db2.execute(
2621
- `UPDATE agent_os_fs_entries SET content = ?, size = ?, mtime_ms = ?, ctime_ms = ? WHERE path = ?`,
2622
- buf,
2623
- newSize,
2624
- now,
2625
- now,
2626
- path
2627
- );
2628
- }
2629
- };
2630
- return backend;
2631
- }
2632
- export {
2633
- agentOs,
2634
- agentOsActorConfigSchema,
2635
- buildConfigActions,
2636
- buildCronActions,
2637
- buildFilesystemActions,
2638
- buildNetworkActions,
2639
- buildOnRequestHandler,
2640
- buildPreviewActions,
2641
- buildProcessActions,
2642
- buildPromptActions,
2643
- buildSessionActions,
2644
- buildSessionPersistenceActions,
2645
- buildShellActions,
2646
- createDatabaseVfs,
2647
- ensureVm,
2648
- generateToken,
2649
- migrateAgentOsTables,
2650
- runHook,
2651
- subscribeToSession,
2652
- syncPreventSleep
2653
- };
2654
5
  //# sourceMappingURL=index.js.map