@rivet-dev/agentos-core 0.2.20 → 0.2.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/sandbox.js CHANGED
@@ -1,8 +1,5 @@
1
1
  import { z } from "zod";
2
2
  const sandboxDisposeHooks = Symbol("agentos.sandboxDisposeHooks");
3
- function binding(def) {
4
- return def;
5
- }
6
3
  function normalizeHeaders(headers) {
7
4
  if (!headers) {
8
5
  return undefined;
@@ -47,137 +44,149 @@ export function createSandboxFs(input) {
47
44
  },
48
45
  };
49
46
  }
50
- export function createSandboxBindings(input) {
47
+ /**
48
+ * Identity helper so each `execute` below infers its input from its own
49
+ * `inputSchema`. Callers writing an object literal get that from
50
+ * `AgentOs.create()`; code that builds a collection programmatically has no
51
+ * contextual type to infer from, so it needs this.
52
+ */
53
+ function hostFunction(definition) {
54
+ return definition;
55
+ }
56
+ export function createSandboxHostFunctions(input) {
51
57
  const options = input;
52
58
  const { client } = options;
53
59
  return {
54
- name: "sandbox",
55
- description: "Execute commands and manage processes in a remote sandbox environment.",
56
- bindings: {
57
- "run-command": binding({
58
- description: "Run a command synchronously in the sandbox and return its stdout, stderr, and exit code.",
59
- inputSchema: z.object({
60
- command: z
61
- .string()
62
- .describe("The command to execute (e.g. 'ls', 'python3')."),
63
- args: z.array(z.string()).optional(),
64
- cwd: z.string().optional(),
65
- env: z.record(z.string(), z.string()).optional(),
66
- timeoutMs: z.number().optional(),
67
- }),
68
- timeout: 120_000,
69
- execute: async (input) => {
70
- const result = await client.runProcess(input);
71
- return {
72
- stdout: result.stdout,
73
- stderr: result.stderr,
74
- exitCode: result.exitCode,
75
- timedOut: result.timedOut,
76
- durationMs: result.durationMs,
77
- };
78
- },
79
- }),
80
- "create-process": binding({
81
- description: "Start a long-running background process in the sandbox. Returns a process ID for later management.",
82
- inputSchema: z.object({
83
- command: z.string(),
84
- args: z.array(z.string()).optional(),
85
- cwd: z.string().optional(),
86
- env: z.record(z.string(), z.string()).optional(),
87
- }),
88
- execute: async (input) => {
89
- const proc = await client.createProcess(input);
90
- return {
91
- id: proc.id,
92
- command: proc.command,
93
- args: proc.args,
94
- status: proc.status,
95
- pid: proc.pid,
96
- };
97
- },
98
- }),
99
- "list-processes": binding({
100
- description: "List all processes running in the sandbox.",
101
- inputSchema: z.object({}),
102
- execute: async () => {
103
- const result = await client.listProcesses();
104
- return {
105
- processes: result.processes.map((p) => ({
106
- id: p.id,
107
- command: p.command,
108
- args: p.args,
109
- status: p.status,
110
- exitCode: p.exitCode,
111
- pid: p.pid,
112
- })),
113
- };
114
- },
115
- }),
116
- "stop-process": binding({
117
- description: "Gracefully stop a running process in the sandbox.",
118
- inputSchema: z.object({ id: z.string() }),
119
- execute: async (input) => {
120
- const proc = await client.stopProcess(input.id);
121
- return {
122
- id: proc.id,
123
- status: proc.status,
124
- exitCode: proc.exitCode,
125
- };
126
- },
127
- }),
128
- "kill-process": binding({
129
- description: "Forcefully kill a running process in the sandbox.",
130
- inputSchema: z.object({ id: z.string() }),
131
- execute: async (input) => {
132
- const proc = await client.killProcess(input.id);
133
- return {
134
- id: proc.id,
135
- status: proc.status,
136
- exitCode: proc.exitCode,
137
- };
138
- },
139
- }),
140
- "get-process-logs": binding({
141
- description: "Get stdout/stderr logs from a sandbox process.",
142
- inputSchema: z.object({
143
- id: z.string(),
144
- stream: z.enum(["stdout", "stderr", "combined"]).optional(),
145
- tail: z.number().optional(),
146
- }),
147
- execute: async (input) => {
148
- const result = await client.getProcessLogs(input.id, {
149
- stream: input.stream,
150
- tail: input.tail,
151
- });
152
- return {
153
- logs: result.entries.map((e) => {
154
- const data = e.encoding === "base64"
155
- ? Buffer.from(e.data, "base64").toString("utf-8")
156
- : e.data;
157
- return {
158
- data,
159
- stream: e.stream,
160
- timestampMs: e.timestampMs,
161
- };
162
- }),
163
- };
164
- },
165
- }),
166
- "send-input": binding({
167
- description: "Send text input to an interactive sandbox process via stdin.",
168
- inputSchema: z.object({
169
- id: z.string(),
170
- data: z.string(),
171
- }),
172
- execute: async (input) => {
173
- await client.sendProcessInput(input.id, {
174
- data: Buffer.from(input.data, "utf-8").toString("base64"),
175
- encoding: "base64",
176
- });
177
- return { sent: true };
178
- },
179
- }),
180
- },
60
+ runCommand: hostFunction({
61
+ inputSchema: z
62
+ .object({
63
+ command: z
64
+ .string()
65
+ .describe("The command to execute (e.g. 'ls', 'python3')."),
66
+ args: z.array(z.string()).optional(),
67
+ cwd: z.string().optional(),
68
+ env: z.record(z.string(), z.string()).optional(),
69
+ timeoutMs: z.number().optional(),
70
+ })
71
+ .describe("Run a command synchronously in the sandbox and return its stdout, stderr, and exit code."),
72
+ timeout: 120_000,
73
+ execute: async (input) => {
74
+ const result = await client.runProcess(input);
75
+ return {
76
+ stdout: result.stdout,
77
+ stderr: result.stderr,
78
+ exitCode: result.exitCode,
79
+ timedOut: result.timedOut,
80
+ durationMs: result.durationMs,
81
+ };
82
+ },
83
+ }),
84
+ createProcess: hostFunction({
85
+ inputSchema: z
86
+ .object({
87
+ command: z.string(),
88
+ args: z.array(z.string()).optional(),
89
+ cwd: z.string().optional(),
90
+ env: z.record(z.string(), z.string()).optional(),
91
+ })
92
+ .describe("Start a long-running background process in the sandbox. Returns a process ID for later management."),
93
+ execute: async (input) => {
94
+ const proc = await client.createProcess(input);
95
+ return {
96
+ id: proc.id,
97
+ command: proc.command,
98
+ args: proc.args,
99
+ status: proc.status,
100
+ pid: proc.pid,
101
+ };
102
+ },
103
+ }),
104
+ listProcesses: hostFunction({
105
+ inputSchema: z
106
+ .object({})
107
+ .describe("List all processes running in the sandbox."),
108
+ execute: async () => {
109
+ const result = await client.listProcesses();
110
+ return {
111
+ processes: result.processes.map((p) => ({
112
+ id: p.id,
113
+ command: p.command,
114
+ args: p.args,
115
+ status: p.status,
116
+ exitCode: p.exitCode,
117
+ pid: p.pid,
118
+ })),
119
+ };
120
+ },
121
+ }),
122
+ stopProcess: hostFunction({
123
+ inputSchema: z
124
+ .object({ id: z.string() })
125
+ .describe("Gracefully stop a running process in the sandbox."),
126
+ execute: async (input) => {
127
+ const proc = await client.stopProcess(input.id);
128
+ return {
129
+ id: proc.id,
130
+ status: proc.status,
131
+ exitCode: proc.exitCode,
132
+ };
133
+ },
134
+ }),
135
+ killProcess: hostFunction({
136
+ inputSchema: z
137
+ .object({ id: z.string() })
138
+ .describe("Forcefully kill a running process in the sandbox."),
139
+ execute: async (input) => {
140
+ const proc = await client.killProcess(input.id);
141
+ return {
142
+ id: proc.id,
143
+ status: proc.status,
144
+ exitCode: proc.exitCode,
145
+ };
146
+ },
147
+ }),
148
+ getProcessLogs: hostFunction({
149
+ inputSchema: z
150
+ .object({
151
+ id: z.string(),
152
+ stream: z.enum(["stdout", "stderr", "combined"]).optional(),
153
+ tail: z.number().optional(),
154
+ })
155
+ .describe("Get stdout/stderr logs from a sandbox process."),
156
+ execute: async (input) => {
157
+ const result = await client.getProcessLogs(input.id, {
158
+ stream: input.stream,
159
+ tail: input.tail,
160
+ });
161
+ return {
162
+ logs: result.entries.map((e) => {
163
+ const data = e.encoding === "base64"
164
+ ? Buffer.from(e.data, "base64").toString("utf-8")
165
+ : e.data;
166
+ return {
167
+ data,
168
+ stream: e.stream,
169
+ timestampMs: e.timestampMs,
170
+ };
171
+ }),
172
+ };
173
+ },
174
+ }),
175
+ sendInput: hostFunction({
176
+ inputSchema: z
177
+ .object({
178
+ id: z.string(),
179
+ data: z.string(),
180
+ })
181
+ .describe("Send text input to an interactive sandbox process via stdin."),
182
+ execute: async (input) => {
183
+ await client.sendProcessInput(input.id, {
184
+ data: Buffer.from(input.data, "utf-8").toString("base64"),
185
+ encoding: "base64",
186
+ });
187
+ return { sent: true };
188
+ },
189
+ }),
181
190
  };
182
191
  }
183
192
  function isProviderOptions(input) {
@@ -187,13 +196,13 @@ function isClientOptions(input) {
187
196
  return "client" in input;
188
197
  }
189
198
  function assertNoLegacySandboxOptions(input) {
190
- const legacyKeys = ["mount", "bindings", "path", "basePath"];
199
+ const legacyKeys = ["mount", "hostFunctions", "path", "basePath"];
191
200
  for (const key of legacyKeys) {
192
201
  if (key in input) {
193
202
  const replacement = key === "path" || key === "basePath" ? "sandboxRoot" : undefined;
194
203
  throw new Error(replacement
195
204
  ? `sandbox.${key} has been removed; use sandbox.${replacement} instead.`
196
- : `sandbox.${key} has been removed; sandbox mounts and bindings are always enabled.`);
205
+ : `sandbox.${key} has been removed; sandbox mounts and host functions are always enabled.`);
197
206
  }
198
207
  }
199
208
  }
@@ -257,14 +266,14 @@ export async function resolveSandboxOptions(options) {
257
266
  readOnly: sandboxOptions.readOnly,
258
267
  },
259
268
  ];
260
- const bindings = [
261
- ...(expanded.bindings ?? []),
262
- createSandboxBindings(sandboxOptions),
263
- ];
269
+ const hostFunctions = {
270
+ ...expanded.hostFunctions,
271
+ sandbox: createSandboxHostFunctions(sandboxOptions),
272
+ };
264
273
  return attachSandboxDisposeHooks({
265
274
  ...expanded,
266
275
  mounts,
267
- bindings,
276
+ hostFunctions,
268
277
  }, normalizedSandbox.dispose ? [normalizedSandbox.dispose] : []);
269
278
  }
270
279
  catch (error) {
@@ -1,3 +1,7 @@
1
1
  import type { PermissionsPolicy } from "@rivet-dev/agentos-runtime-core/vm-config";
2
2
  import type { Permissions } from "../runtime-compat.js";
3
- export declare function serializePermissionsForSidecar(permissions?: Permissions): PermissionsPolicy;
3
+ /**
4
+ * Serialize only the scopes the caller set. The sidecar owns the defaults, so
5
+ * an omitted scope, or an omitted policy, takes the sidecar's default.
6
+ */
7
+ export declare function serializePermissionsForSidecar(permissions?: Permissions): PermissionsPolicy | undefined;
@@ -20,16 +20,13 @@ function serializePatternScope(scope) {
20
20
  })),
21
21
  };
22
22
  }
23
+ /**
24
+ * Serialize only the scopes the caller set. The sidecar owns the defaults, so
25
+ * an omitted scope, or an omitted policy, takes the sidecar's default.
26
+ */
23
27
  export function serializePermissionsForSidecar(permissions) {
24
28
  if (!permissions) {
25
- return {
26
- fs: "deny",
27
- network: "deny",
28
- childProcess: "deny",
29
- process: "deny",
30
- env: "deny",
31
- binding: "deny",
32
- };
29
+ return undefined;
33
30
  }
34
31
  return {
35
32
  fs: typeof permissions.fs === "string" || !permissions.fs
@@ -47,8 +44,8 @@ export function serializePermissionsForSidecar(permissions) {
47
44
  env: typeof permissions.env === "string" || !permissions.env
48
45
  ? permissions.env
49
46
  : serializePatternScope(permissions.env),
50
- binding: typeof permissions.binding === "string" || !permissions.binding
51
- ? permissions.binding
52
- : serializePatternScope(permissions.binding),
47
+ hostFunction: typeof permissions.hostFunction === "string" || !permissions.hostFunction
48
+ ? permissions.hostFunction
49
+ : serializePatternScope(permissions.hostFunction),
53
50
  };
54
51
  }
@@ -40,11 +40,11 @@ interface NativeSidecarKernelProxyOptions {
40
40
  * `configure_vm` rebuilds the whole VM configuration from each payload, so
41
41
  * every runtime mount reconfigure must resend these or a post-boot
42
42
  * `mountFs()` silently drops the `/opt/agentos` package projections and
43
- * binding shim commands applied at boot.
43
+ * host-function shim commands applied at boot.
44
44
  */
45
45
  packages?: Parameters<SidecarProcess["configureVm"]>[2]["packages"];
46
46
  packagesMountAt?: string;
47
- bindingShimCommands?: string[];
47
+ hostFunctionShimCommands?: string[];
48
48
  commandGuestPaths: ReadonlyMap<string, string>;
49
49
  onWasmCommandResolved?: (command: string) => void;
50
50
  onDispose?: () => Promise<void>;
@@ -76,7 +76,7 @@ export declare class NativeSidecarKernelProxy {
76
76
  private readonly loopbackExemptPorts;
77
77
  private packages;
78
78
  private readonly packagesMountAt;
79
- private readonly bindingShimCommands;
79
+ private readonly hostFunctionShimCommands;
80
80
  private readonly commandDrivers;
81
81
  private readonly onWasmCommandResolved;
82
82
  private readonly onDispose;
@@ -221,7 +221,7 @@ export class NativeSidecarKernelProxy {
221
221
  // later mount reconfigures resend linked packages too, not just boot ones.
222
222
  packages;
223
223
  packagesMountAt;
224
- bindingShimCommands;
224
+ hostFunctionShimCommands;
225
225
  commandDrivers;
226
226
  onWasmCommandResolved;
227
227
  onDispose;
@@ -260,7 +260,7 @@ export class NativeSidecarKernelProxy {
260
260
  this.loopbackExemptPorts = options.loopbackExemptPorts;
261
261
  this.packages = options.packages ? [...options.packages] : [];
262
262
  this.packagesMountAt = options.packagesMountAt;
263
- this.bindingShimCommands = options.bindingShimCommands;
263
+ this.hostFunctionShimCommands = options.hostFunctionShimCommands;
264
264
  this.commandDrivers = buildCommandMap(options.commandGuestPaths);
265
265
  this.onWasmCommandResolved = options.onWasmCommandResolved;
266
266
  this.onDispose = options.onDispose;
@@ -1212,8 +1212,8 @@ export class NativeSidecarKernelProxy {
1212
1212
  return;
1213
1213
  }
1214
1214
  // Rust `configure_vm` rebuilds the whole VM configuration from this
1215
- // payload, so resend the boot packages / binding shim commands too —
1216
- // omitting them here strips the `/opt/agentos` projections and binding
1215
+ // payload, so resend the boot packages and host-function shim commands too.
1216
+ // Omitting them here strips the `/opt/agentos` projections and host-function
1217
1217
  // shims from the VM as a side effect of a runtime mount change.
1218
1218
  await this.client.configureVm(this.session, this.vm, {
1219
1219
  mounts: this.desiredSidecarMounts(),
@@ -1222,7 +1222,7 @@ export class NativeSidecarKernelProxy {
1222
1222
  loopbackExemptPorts: this.loopbackExemptPorts,
1223
1223
  packages: this.packages,
1224
1224
  packagesMountAt: this.packagesMountAt,
1225
- bindingShimCommands: this.bindingShimCommands,
1225
+ hostFunctionShimCommands: this.hostFunctionShimCommands,
1226
1226
  });
1227
1227
  };
1228
1228
  const previous = this.mountReconfigurePromise ?? Promise.resolve();
@@ -1370,7 +1370,7 @@ export class NativeSidecarKernelProxy {
1370
1370
  this.updateTrackedProcessSnapshot(entry);
1371
1371
  void this.refreshProcessSnapshot().catch(() => { });
1372
1372
  // Signal metadata is advisory and must not hold process startup behind a
1373
- // second sidecar RPC. Very short binding commands can finish while the
1373
+ // second sidecar RPC. Very short hostFunction commands can finish while the
1374
1374
  // original execute response is still in flight; synchronously refreshing
1375
1375
  // here creates a circular wait with their output/exit delivery.
1376
1376
  this.scheduleSignalStateRefresh(entry);
package/dist/types.d.ts CHANGED
@@ -9,9 +9,9 @@ export type * from "./session-api.js";
9
9
  */
10
10
  export type AgentType = string;
11
11
  export type { AgentBlock, PackageDescriptor, PackageRef, SoftwarePackageRef, } from "./agentos-package.js";
12
- export type { Binding, BindingExample, Bindings } from "./bindings.js";
13
12
  export type { CronAction, CronActionInfo, CronEvent, CronEventHandler, CronJob, CronJobInfo, CronJobOptions, ScheduleDriver, ScheduleEntry, ScheduleHandle, } from "./cron/index.js";
14
13
  export type { HostDirBackendOptions, HostDirMountPluginConfig, NodeModulesMountConfig, } from "./host-dir-mount.js";
14
+ export type { HostFunction, HostFunctionCollection, HostFunctionCollections, HostFunctionExample, HostFunctionSchemas, ResolvedHostFunctions, } from "@rivet-dev/agentos-runtime-core/host-functions";
15
15
  export type { FilesystemSnapshotExport, LayerHandle, LayerStore, OverlayFilesystemMode, RootSnapshotExport, SnapshotImportSource, SnapshotLayerHandle, WritableLayerHandle, } from "./layers.js";
16
16
  export type { SoftwareInput, SoftwareRoot } from "./packages.js";
17
17
  export type { ChildProcessPermissions, ConnectTerminalOptions, EnvPermissions, ExecOptions, ExecResult, FsPermissionRule, FsPermissions, KernelExecOptions, KernelExecResult, KernelSpawnOptions, NetworkAccessRequest, NetworkPermissions, OpenShellOptions, PatternPermissionRule, PermissionDecision, PermissionMode, Permissions, ProcessInfo, RulePermissions, StdioChannel, TimingMitigation, VirtualDirEntry, VirtualFileSystem, VirtualStat, } from "./runtime.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rivet-dev/agentos-core",
3
- "version": "0.2.20",
3
+ "version": "0.2.21",
4
4
  "type": "module",
5
5
  "license": "Apache-2.0",
6
6
  "main": "./dist/index.js",
@@ -56,7 +56,7 @@
56
56
  "build:agentos-protocol": "node ./scripts/compile-agentos-protocol.mjs",
57
57
  "build:protocols": "pnpm run build:agentos-protocol",
58
58
  "test": "vitest run --exclude '**/*.nightly.test.ts' --reporter=verbose",
59
- "test:unit": "vitest run tests/agent-exit-event.test.ts tests/agentos-package.test.ts tests/agentos-protocol.test.ts tests/allowed-node-builtins.test.ts tests/bindings-zod.test.ts tests/bindings.test.ts tests/cron-manager.test.ts tests/cron-timer-driver.test.ts tests/execution-abort.test.ts tests/generated-protocol.test.ts tests/leak-agent-os-processes.test.ts tests/leak-rpc-client.test.ts tests/mount-descriptors.test.ts tests/mount-reconfigure.test.ts tests/options-schema.test.ts tests/public-api-exports.test.ts tests/root-filesystem-descriptors.test.ts tests/runtime-compat-mount.test.ts tests/session-event-ordering.test.ts tests/session-permission-surface.test.ts tests/sidecar-client.test.ts tests/sidecar-permission-descriptors.test.ts tests/wasm-permission-tiers.test.ts --fileParallelism=false",
59
+ "test:unit": "vitest run tests/agent-exit-event.test.ts tests/agentos-package.test.ts tests/agentos-protocol.test.ts tests/allowed-node-builtins.test.ts tests/host-functions-zod.test.ts tests/host-functions.test.ts tests/cron-manager.test.ts tests/cron-timer-driver.test.ts tests/execution-abort.test.ts tests/generated-protocol.test.ts tests/leak-agent-os-processes.test.ts tests/leak-rpc-client.test.ts tests/mount-descriptors.test.ts tests/mount-reconfigure.test.ts tests/options-schema.test.ts tests/public-api-exports.test.ts tests/root-filesystem-descriptors.test.ts tests/runtime-compat-mount.test.ts tests/session-event-ordering.test.ts tests/session-permission-surface.test.ts tests/sidecar-client.test.ts tests/sidecar-permission-descriptors.test.ts tests/wasm-permission-tiers.test.ts --fileParallelism=false",
60
60
  "test:pr": "pnpm test:unit && vitest run tests/migration-parity.test.ts tests/acp-reactor-regression.test.ts --fileParallelism=false --reporter=verbose",
61
61
  "test:nightly": "vitest run tests/*.nightly.test.ts --reporter=verbose --passWithNoTests"
62
62
  },
@@ -64,14 +64,14 @@
64
64
  "@agentclientprotocol/sdk": "0.16.1",
65
65
  "@agentos-software/claude-code": "0.2.7",
66
66
  "@agentos-software/codex-cli": "0.3.4",
67
- "@agentos-software/common": "0.2.20",
68
- "@agentos-software/manifest": "0.2.20",
67
+ "@agentos-software/common": "0.2.21",
68
+ "@agentos-software/manifest": "0.2.21",
69
69
  "@agentos-software/opencode": "0.2.7",
70
70
  "@agentos-software/pi": "0.2.7",
71
71
  "@aws-sdk/client-s3": "^3.1019.0",
72
- "@rivet-dev/agentos-sidecar": "0.2.20",
72
+ "@rivet-dev/agentos-sidecar": "0.2.21",
73
73
  "@rivetkit/bare-ts": "^0.6.2",
74
- "@rivet-dev/agentos-runtime-core": "0.2.20",
74
+ "@rivet-dev/agentos-runtime-core": "0.2.21",
75
75
  "@xterm/headless": "^6.0.0",
76
76
  "better-sqlite3": "^12.8.0",
77
77
  "croner": "^10.0.1",
@@ -105,7 +105,7 @@
105
105
  "@agentos-software/vim": "0.3.3",
106
106
  "@agentos-software/wget": "0.3.3",
107
107
  "@agentos-software/yq": "0.3.3",
108
- "@rivet-dev/agentos-test-harness": "0.2.20",
108
+ "@rivet-dev/agentos-test-harness": "0.2.21",
109
109
  "@anthropic-ai/claude-agent-sdk": "^0.2.87",
110
110
  "@anthropic-ai/claude-code": "^2.1.86",
111
111
  "@bare-ts/tools": "0.15.0",
@@ -1,7 +0,0 @@
1
- import type { ZodType } from "zod";
2
- export declare class BindingSchemaConversionError extends Error {
3
- readonly path: string;
4
- readonly zodType: string;
5
- constructor(path: string, zodType: string, details?: string);
6
- }
7
- export declare function zodToJsonSchema(schema: ZodType): unknown;