diff --git a/.claude/skills/publish-registry/SKILL.md b/.claude/skills/publish-registry/SKILL.md index d7ad81e43e..0f930f130f 100644 --- a/.claude/skills/publish-registry/SKILL.md +++ b/.claude/skills/publish-registry/SKILL.md @@ -29,7 +29,7 @@ just registry-publish-all [tag] ## Rules -- Do not publish registry packages from secure-exec. +- Do not publish registry packages from agentos. - Do not move `latest` unless the user explicitly asks for a release. - Prefer AgentOS workspace builds while iterating; published pins are for consumers and release validation. diff --git a/.claude/skills/release-preview/SKILL.md b/.claude/skills/release-preview/SKILL.md index 64738cb814..1af13060c4 100644 --- a/.claude/skills/release-preview/SKILL.md +++ b/.claude/skills/release-preview/SKILL.md @@ -9,8 +9,8 @@ AgentOS previews are branch snapshots from this repository. The workflow builds debug artifacts and publishes npm packages under a sanitized branch dist-tag. No crates.io release, git tag, or GitHub release is created. -secure-exec is a generated mirror. Do not bump a secure-exec ref or cut a -secure-exec preview by hand. +agentos is a generated mirror. Do not bump a agentos ref or cut a +agentos preview by hand. ## Procedure @@ -32,6 +32,6 @@ npm install @rivet-dev/agentos-core@ ## Rules - Release-preview is for previews only; releases use the `release` skill. -- All code changes belong in AgentOS. The secure-exec mirror is regenerated +- All code changes belong in AgentOS. The agentos mirror is regenerated from AgentOS and follows the published AgentOS version. - On failure: `gh run view --log-failed`, fix, re-dispatch, re-watch. diff --git a/.claude/skills/release/SKILL.md b/.claude/skills/release/SKILL.md index 056ac1ab2a..f1291a38bc 100644 --- a/.claude/skills/release/SKILL.md +++ b/.claude/skills/release/SKILL.md @@ -10,8 +10,8 @@ The publish flow lives in `scripts/publish` and is driven by AgentOS is the source of truth. It publishes npm packages, crates, runtime sidecars, Pyodide/R2 assets, and `@agentos-software/*` registry packages from -this repository. secure-exec releases are generated compatibility shims that -follow the AgentOS version; never release secure-exec first. +this repository. agentos releases are generated compatibility shims that +follow the AgentOS version; never release agentos first. ## Procedure @@ -37,6 +37,6 @@ gh run watch -R rivet-dev/agentos "$run" --exit-status - `scripts/publish/src/local/cut-release.ts` is a pure trigger; version changes happen in the ephemeral CI checkout. - `workspace:*` deps are rewritten to literal versions by the publish bump pass. -- Generated secure-exec shims are dispatched after AgentOS publishes and must +- Generated agentos shims are dispatched after AgentOS publishes and must use the same version. - If anything fails, stop and report — do not retry automatically. diff --git a/.gitattributes b/.gitattributes index 6fae589b06..e575d5386f 100644 --- a/.gitattributes +++ b/.gitattributes @@ -2,7 +2,7 @@ # # The Rust kernel is the substance of this repo; the rest is the TypeScript # client/protocol/registry plus a large test suite (the kernel itself lives in -# the secure-exec repo). We count Rust in full, plus the core client surface +# the agentos repo). We count Rust in full, plus the core client surface # (the AgentOS client entrypoint + its sidecar wire layer) and the core JS # binary-resolver shim, and exclude everything else (tests, demos, tooling, # generated bundles, the website, and the remaining client/registry code). diff --git a/.github/workflows/ci-nightly.yml b/.github/workflows/ci-nightly.yml index e0931f9eb2..e6f804f213 100644 --- a/.github/workflows/ci-nightly.yml +++ b/.github/workflows/ci-nightly.yml @@ -40,7 +40,6 @@ jobs: sudo apt-get install --yes cmake fi - run: pnpm install --frozen-lockfile - - run: node --test scripts/generate-secure-exec-mirror.test.mjs - run: make -C toolchain commands - run: make -C toolchain cmd/duckdb - run: make -C toolchain codex diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 12fcd8be58..d1c026e0f4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -72,7 +72,6 @@ jobs: - run: node scripts/verify-fixed-versions.mjs - run: node --test scripts/check-layout.test.mjs - run: pnpm check-layout - - run: node --test scripts/generate-secure-exec-mirror.test.mjs - run: node --test scripts/check-rustfmt.test.mjs - run: node scripts/check-rustfmt.mjs - run: pnpm check-types @@ -82,7 +81,6 @@ jobs: --filter '@rivet-dev/agentos-build-tools' \ --filter '@rivet-dev/agentos-toolchain' \ --filter '@rivet-dev/agentos-runtime-sidecar' \ - --filter 'secure-exec' \ test - run: pnpm lint continue-on-error: true diff --git a/.pnpmfile.cjs b/.pnpmfile.cjs new file mode 100644 index 0000000000..f587b62497 --- /dev/null +++ b/.pnpmfile.cjs @@ -0,0 +1,15 @@ +const PINNED_RIVETKIT_VERSION = "0.0.0-sqlite-uds.4e59a38"; + +module.exports = { + hooks: { + readPackage(pkg) { + if (pkg.name === "rivetkit" && pkg.version === PINNED_RIVETKIT_VERSION) { + // This preview bundles its ./agent-os implementation but still declares + // the retired external runtime. Keeping the declaration would restore the + // sunset package graph even though no bundled RivetKit module imports it. + delete pkg.dependencies?.["@rivet-dev/agent-os-core"]; + } + return pkg; + }, + }, +}; diff --git a/.secure-exec-local-path b/.secure-exec-local-path deleted file mode 100644 index 50a51e944b..0000000000 --- a/.secure-exec-local-path +++ /dev/null @@ -1,9 +0,0 @@ -# Local secure-exec checkout that carries the converged browser/wasm build. -# Agent OS depends on secure-exec; the web/wasm work links against this checkout -# via `just secure-exec-local` (which repoints crates to `path = "../secure-exec/..."` -# and npm to `link:`). The converged web architecture (the template for this work) -# currently lives on a branch, NOT yet on secure-exec main. - -SECURE_EXEC_CANONICAL=/home/nathan/secure-exec -SECURE_EXEC_CONVERGED_WEB_WORKSPACE=/home/nathan/secure-exec-convwasi -SECURE_EXEC_CONVERGED_WEB_BRANCH=browser-convergence-item-c diff --git a/CLAUDE.md b/CLAUDE.md index 7273a477f6..2cf60724e4 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1,8 +1,8 @@ # agentOS AgentOS owns the runtime, kernel, VFS, language execution, registry packages, -ACP/session layer, AgentOS client APIs, docs, and publish machinery. The -`secure-exec` repository is now a generated compatibility mirror only. +ACP/session layer, AgentOS client APIs, docs, and publish machinery. Agent OS +Exec is the JavaScript, TypeScript, and Python execution surface of AgentOS. ## Boundaries @@ -16,9 +16,8 @@ ACP/session layer, AgentOS client APIs, docs, and publish machinery. The or public API that already uses the word. - The protocol has no backward compatibility guarantee. Client, sidecar, and protocol crates ship in same-version lockstep; update both sides together. -- Generic runtime work belongs here, not in `../secure-exec`. Regenerate that - mirror with `node scripts/generate-secure-exec-mirror.mjs` after changing a - shimmed public surface. +- Generic runtime and language-execution work belongs here. Do not add a + compatibility mirror or a second package namespace for Agent OS Exec. - Keep root `package.json` scripts limited to Turbo orchestration; repo-specific commands belong in `justfile` recipes or scoped package scripts. - AgentOS targets native Linux/container execution. Browser support is not @@ -218,9 +217,10 @@ custom host-syscall imports. Treat that target as **native POSIX**; - `scripts/publish` is the source of truth for npm/crates discovery, version rewriting, npm publish, crates publish, release assets, and R2 upload. -- Publishable npm packages and Rust crates are AgentOS-owned. Compatibility - `@secure-exec/*`, `secure-exec`, and `secure-exec-*` artifacts are emitted - from the generated mirror. +- Publishable npm packages and Rust crates are AgentOS-owned. Agent OS Exec is + published through `@rivet-dev/agentos-javascript` and + `@rivet-dev/agentos-python`; `@rivet-dev/agentos` owns the actor API. Do not + publish compatibility artifacts or language subpaths from the actor package. - The release workflow must build and stage the native sidecar binaries, runtime-sidecar binaries, registry WASM commands, and pyodide assets before publish. diff --git a/TODO.md b/TODO.md index 048046cd7a..7ff5f3c317 100644 --- a/TODO.md +++ b/TODO.md @@ -78,7 +78,7 @@ fixtures and benchmarks that exercise host VFS callbacks. Disabled browser sources remain dormant reference code, not a supported production VFS. - [x] Remove the core in-memory VFS and overlay/layer-store implementations. -- [x] Remove their root and secure-exec compatibility exports. +- [x] Remove their root and agentos compatibility exports. - [x] Require a caller-owned filesystem in the low-level compatibility runtime. - [x] Move remaining repository fixtures to the explicit test-only surface. - [x] Remove obsolete duplicate semantic tests. diff --git a/biome.json b/biome.json index dfd8ce5d8c..af860c6ab1 100644 --- a/biome.json +++ b/biome.json @@ -8,7 +8,7 @@ "!packages/runtime-browser", "!packages/playground", "!packages/core/src/sidecar/generated-protocol.ts", - "!_secure-exec-sibling", + "!_agentos-sibling", "!/**/node_modules" ], "ignoreUnknown": true diff --git a/crates/CLAUDE.md b/crates/CLAUDE.md index fb92d0c360..b56394f676 100644 --- a/crates/CLAUDE.md +++ b/crates/CLAUDE.md @@ -5,7 +5,7 @@ The Rust sidecar implements the kernel: virtual filesystem, process table, socke The kernel orchestrates three execution environments: - **WASM processes** -- POSIX utilities (coreutils, sh, grep, etc.) compiled to WebAssembly, running within the sidecar's managed runtime. -- **Node.js (V8 isolates)** -- JS/TS executes inside isolated V8 contexts managed by the sidecar's execution engine. All Node.js builtin modules (`fs`, `net`, `child_process`, `dns`, `http`, `os`, etc.) are kernel-backed polyfills that route through the kernel VFS, socket table, and process table via synchronous RPC. Module loading is intercepted so guest code never touches real host APIs. **⚠️ CURRENTLY BROKEN**: The execution engine currently spawns real host `node` child processes instead of V8 isolates, and most builtins fall through to real host modules. This is being actively fixed. The complete working polyfill code from the original `@secure-exec` packages has been recovered to `~/.agents/recovery/secure-exec/` (source repo: `/home/nathan/secure-exec-1/`). See `crates/execution/CLAUDE.md` for the gap table and recovery file list. +- **Node.js (V8 isolates)** -- JS/TS executes inside isolated V8 contexts managed by the sidecar's execution engine. All Node.js builtin modules (`fs`, `net`, `child_process`, `dns`, `http`, `os`, etc.) are kernel-backed polyfills that route through the kernel VFS, socket table, and process table via synchronous RPC. Module loading is intercepted so guest code never touches real host APIs. **⚠️ CURRENTLY BROKEN**: The execution engine currently spawns real host `node` child processes instead of V8 isolates, and most builtins fall through to real host modules. This is being actively fixed. The complete working polyfill code from the original `@agentos` packages has been recovered to `~/.agents/recovery/agentos/` (source repo: `/home/nathan/agentos-1/`). See `crates/execution/CLAUDE.md` for the gap table and recovery file list. - **Python (Pyodide)** -- CPython compiled to WASM via Pyodide, with kernel-backed file/network I/O. **ALL guest code MUST execute inside the kernel with ZERO host escapes.** No runtime may spawn unsandboxed host processes, touch real host filesystems, open real network sockets, or call real Node.js builtins. Every syscall goes through the kernel. This is the single most important architectural invariant. Any path where guest code reaches the real host is a critical security violation. @@ -19,7 +19,7 @@ These are hard rules with no exceptions: 1. **Every guest syscall goes through the kernel.** File reads go through the kernel VFS, not real `node:fs`. Network connections go through the kernel socket table, not real `node:net`. Process spawning go through the kernel process table, not real `node:child_process`. DNS resolution goes through the kernel's DNS resolver, not real `node:dns`. There are no shortcuts where guest code touches host resources directly. 2. **No real host builtins.** When a guest does `require('fs')` or `import net from 'node:net'`, the module loader must return a kernel-backed polyfill. If no polyfill exists yet, the builtin must be denied (`ERR_ACCESS_DENIED`). The loader must never fall through to Node.js's default resolution and hand the guest the real host module. 3. **The host is an implementation detail.** Guest code should not be able to observe that it is running on a host Node.js process. `process.pid` should be the kernel PID, `os.hostname()` should be the kernel hostname, `fs.readdirSync('/')` should show the kernel VFS root. `process.cwd()` should return the kernel CWD, not a host path. `process.env` must not contain internal `AGENT_OS_*` control variables. Error messages and stack traces must not reveal host filesystem paths. `require.resolve()` must return guest-visible paths, not host paths. Any host state leaking through to the guest is a bug. -4. **Polyfills are ports, not wrappers.** A path-translating shim over real `node:fs` is not a polyfill -- it is a wrapper around a host API. A real polyfill implements the API semantics using only kernel primitives (VFS, socket table, process table, pipe manager). The original JS kernel (`@secure-exec/core` + `@secure-exec/nodejs`, deleted in commit `5a43882`) had full kernel-backed polyfills for `fs`, `net`, `http`, `dns`, `dgram`, `child_process`, and `os`. The Rust sidecar must reach the same level of isolation. +4. **Polyfills are ports, not wrappers.** A path-translating shim over real `node:fs` is not a polyfill -- it is a wrapper around a host API. A real polyfill implements the API semantics using only kernel primitives (VFS, socket table, process table, pipe manager). The original JavaScript kernel packages, deleted in commit `5a43882`, had full kernel-backed polyfills for `fs`, `net`, `http`, `dns`, `dgram`, `child_process`, and `os`. The Rust sidecar must reach the same level of isolation. 5. **Control channels must be out-of-band.** The sidecar must not use in-band magic prefixes on stdout/stderr for control signaling (exit codes, metrics, signal registration). Guest code can write these prefixes to inject fake control messages. Use dedicated file descriptors, separate pipes, or a side-channel protocol for all sidecar-internal communication. 6. **Resource consumption must be bounded.** Every guest-allocatable resource must have a configurable limit enforced by the kernel: filesystem total size, inode count, process count, open FDs, pipes, PTYs, sockets, connections. Unbounded allocation from guest input is a DoS vector. The kernel's `ResourceLimits` must cover all resource types, not just processes and FDs. Sidecar metadata parsing should start from `ResourceLimits::default()` and only override keys that are actually present; rebuilding the struct from sparse metadata drops default filesystem byte/inode caps. @@ -61,8 +61,8 @@ These are hard rules with no exceptions: - **`sandbox_agent` `pread` should prefer HTTP `Range` on `/v1/fs/file`, but older remotes may ignore it and return `200 OK`.** Keep the compatibility path that warns and slices the full response body instead of failing, because the sidecar still has to interoperate with pre-range sandbox-agent servers. - **Native sidecar security/audit telemetry should use structured bridge events, not ad hoc strings.** In `crates/sidecar/src/service.rs`, emit security-relevant records with `bridge.emit_structured_event(...)` and include a `timestamp` field plus stable keys such as `policy`, `path`, `source_pid`, `target_pid`, or `reason` so tests and downstream aggregation can assert on them directly. - **Native mount plugins live under `crates/sidecar/src/plugins/` and register through `plugins/mod.rs`.** Keep `host_dir`, `s3`, `google_drive`, and `sandbox_agent` there with shared registration glue, while `bridge.rs` only layers on sidecar-specific in-memory and JS-bridge plugin registration. -- **The sidecar execution driver's shell-visible builtin commands must mirror the compat runtime surface.** Seed `node` and `wasm` during `create_vm()` and preserve them when refreshing `/__secure_exec/commands/*` in `configure_vm()`, but do not materialize extra `/bin/*` runtime stubs such as `python` unless a lower snapshot or installed software explicitly provides them. Direct `ExecuteRequest { runtime: ... }` dispatch still covers runtimes that are not meant to appear in the guest filesystem. -- **Mounted WASM command directories need both command-map refresh and guest `PATH` refresh.** When `crates/sidecar/src/vm.rs` rediscovers `/__secure_exec/commands/*`, update `vm.command_guest_paths` and prepend those parent directories into `vm.guest_env["PATH"]`; `crates/sidecar/src/execution.rs` child-process resolution should search `PATH` entries before falling back to `/bin`, `/usr/bin`, and `/usr/local/bin`, or guest `child_process.spawn("sh")`/`spawn("grep")` misses mounted registry commands. +- **The sidecar execution driver's shell-visible builtin commands must mirror the compat runtime surface.** Seed `node` and `wasm` during `create_vm()` and preserve them when refreshing `/__agentos/commands/*` in `configure_vm()`, but do not materialize extra `/bin/*` runtime stubs such as `python` unless a lower snapshot or installed software explicitly provides them. Direct `ExecuteRequest { runtime: ... }` dispatch still covers runtimes that are not meant to appear in the guest filesystem. +- **Mounted WASM command directories need both command-map refresh and guest `PATH` refresh.** When `crates/sidecar/src/vm.rs` rediscovers `/__agentos/commands/*`, update `vm.command_guest_paths` and prepend those parent directories into `vm.guest_env["PATH"]`; `crates/sidecar/src/execution.rs` child-process resolution should search `PATH` entries before falling back to `/bin`, `/usr/bin`, and `/usr/local/bin`, or guest `child_process.spawn("sh")`/`spawn("grep")` misses mounted registry commands. - **Native-sidecar command resolution must use the caller's effective `PATH`, not just `vm.guest_env`.** In `crates/sidecar/src/execution.rs`, path-like guest candidates emitted by shells (for example `/home/agentos/.pi/agent/bin/printf`) should only be treated as executables when the candidate or mapped host file actually exists; if the parent directory came from `PATH` but the file is missing, fall back to the basename so registry command remapping can still find `printf`/`bash`/`which`. - **Native-sidecar WASM commands see the shadow root, so standard guest directories must be seeded there during VM creation.** In `crates/sidecar/src/vm.rs`, keep `/tmp`, `/var/tmp`, `/bin`, `/usr`, and the rest of the POSIX bootstrap tree materialized in the shadow root before any WASM command runs, or shell redirection and absolute-path checks will disagree with the kernel VFS (`vm.stat("/tmp")` works while `sh -c 'echo hi > /tmp/x'` fails). - **Host filesystem API writes that should be visible to WASM commands must mirror into the shadow root immediately.** In `crates/sidecar/src/filesystem.rs`, `GuestFilesystemOperation::WriteFile` needs to update both the kernel VFS and the VM shadow tree right away, or `vm.writeFile("/tmp/x")` will succeed while guest `sh`/`cat`/`ls` still miss the file until some later sync path runs. diff --git a/crates/agentos-protocol/protocol/agent_os_acp_v1.bare b/crates/agentos-protocol/protocol/agent_os_acp_v1.bare index 4cc34059c9..a594abd933 100644 --- a/crates/agentos-protocol/protocol/agent_os_acp_v1.bare +++ b/crates/agentos-protocol/protocol/agent_os_acp_v1.bare @@ -1,5 +1,5 @@ # Agent OS ACP extension protocol schema, version 1. -# This schema is intentionally standalone. It imports no secure-exec schema. +# This schema is intentionally standalone. It imports no agentos schema. type JsonUtf8 str diff --git a/crates/agentos-sidecar-browser/src/wasm.rs b/crates/agentos-sidecar-browser/src/wasm.rs index 3780937455..cc078fe557 100644 --- a/crates/agentos-sidecar-browser/src/wasm.rs +++ b/crates/agentos-sidecar-browser/src/wasm.rs @@ -1,10 +1,10 @@ //! wasm-bindgen entry point for the Agent OS browser sidecar. //! -//! Mirrors secure-exec's `BrowserSidecarWasm` (pushFrame/pollEvent over the shared +//! Mirrors agentos's `BrowserSidecarWasm` (pushFrame/pollEvent over the shared //! `BrowserWireDispatcher` + `BrowserJsBridge`) but registers the Agent OS ACP //! `BrowserExtension` into the dispatcher's sidecar, so guest ACP/session traffic //! is handled by the Agent OS wrapper while every kernel syscall still routes -//! through the converged secure-exec wasm kernel (the sole enforcement point). +//! through the converged agentos wasm kernel (the sole enforcement point). use agentos_native_sidecar_browser::wire_dispatch::{BrowserWireDispatcher, BROWSER_SIDECAR_ID}; use agentos_native_sidecar_browser::BrowserJsBridge; diff --git a/crates/agentos-sidecar-core/src/lib.rs b/crates/agentos-sidecar-core/src/lib.rs index 85b7547bf8..25034f58b5 100644 --- a/crates/agentos-sidecar-core/src/lib.rs +++ b/crates/agentos-sidecar-core/src/lib.rs @@ -3,7 +3,7 @@ //! Host-free core for the Agent OS ACP sidecar extension. //! //! This crate holds the parts of the ACP extension that do NOT depend on the host -//! runtime (tokio, std::fs, the native secure-exec sidecar): the request/response +//! runtime (tokio, std::fs, the native agentos sidecar): the request/response //! wire codec and the per-session data model. It compiles to wasm32 so the browser //! sidecar (`agentos-sidecar-browser`) can run the same ACP logic the native sidecar //! (`agentos-sidecar`) runs, with each backend supplying the host operations diff --git a/crates/agentos-sidecar/CLAUDE.md b/crates/agentos-sidecar/CLAUDE.md index 894ac4580a..4b19f04fe7 100644 --- a/crates/agentos-sidecar/CLAUDE.md +++ b/crates/agentos-sidecar/CLAUDE.md @@ -2,6 +2,6 @@ - Author ACP behavior as an `Ext` extension over `agentos-protocol`; do not add new top-level sidecar request/response variants for agent-session RPCs. - Keep `agentos-protocol` as the only ACP payload schema source; extension requests, responses, events, and callbacks must use the generated BARE types. -- Keep generic secure-exec sidecar code agent-agnostic; ACP namespace handling belongs in this wrapper extension, not in secure-exec transport or kernel layers. +- Keep generic agentos sidecar code agent-agnostic; ACP namespace handling belongs in this wrapper extension, not in agentos transport or kernel layers. - Extension guest work must still run through the kernel boundary via `ExtensionContext`; never spawn host-native agent adapters or touch host files directly from extension logic. - Emit live session notifications as generated `AcpEvent` payloads in `EventPayload::Ext`; do not add event cursor replay to snapshot state. diff --git a/crates/agentos-sidecar/src/acp/mod.rs b/crates/agentos-sidecar/src/acp/mod.rs index 835a923210..ed30ebe3e5 100644 --- a/crates/agentos-sidecar/src/acp/mod.rs +++ b/crates/agentos-sidecar/src/acp/mod.rs @@ -61,7 +61,7 @@ const ACP_INACTIVITY_WARNING_INTERVAL: Duration = Duration::from_secs(30); const PROMPT_RESPONSE_DRAIN_QUIET: Duration = Duration::from_millis(50); // While an ACP request is in flight the stdio loop is inside the extension // dispatch, so this wait loop becomes the cooperative VM I/O pump. Keep it at -// the same cadence as secure-exec's outer event pump so adapter fetches and +// the same cadence as agentos's outer event pump so adapter fetches and // process output keep moving mid-turn. const ACP_CANCEL_METHOD: &str = "session/cancel"; const ACP_TRACE_PATH_ENV: &str = "AGENT_OS_ACP_TRACE_PATH"; @@ -85,7 +85,7 @@ const AGENTOS_SYSTEM_PROMPT: &str = include_str!("../AGENTOS_SYSTEM_PROMPT.md"); /// evict the now-dead session record instead of leaking it until an explicit /// internal runtime cleanup that may never run. const ADAPTER_EXITED_ERROR_MARKER: &str = "exited with code"; -/// Substring of the secure-exec process-table error returned when an operation +/// Substring of the agentos process-table error returned when an operation /// targets a process that already exited ("VM has no active process "). /// Writing a request to an adapter that crashed while *idle* surfaces this way /// (the exit is observed lazily, on the next stdin write), so it is classified @@ -1424,7 +1424,7 @@ mod tests { assert_eq!(adapter_exit_code_from_error(&exited), Some(7)); // Lazy observation: a request write to an already-reaped adapter fails - // with secure-exec's process-table error (the exact production shape: + // with agentos's process-table error (the exact production shape: // "VM vm-5 has no active process agent-6"). No exit code is observed. let gone = SidecarError::InvalidState(String::from("VM vm-5 has no active process agent-6")); diff --git a/crates/agentos-sidecar/src/acp/runtime.rs b/crates/agentos-sidecar/src/acp/runtime.rs index 34e8d60238..b156edba26 100644 --- a/crates/agentos-sidecar/src/acp/runtime.rs +++ b/crates/agentos-sidecar/src/acp/runtime.rs @@ -1576,7 +1576,7 @@ pub(super) async fn resolve_agent( } /// Extract the owning connection id from an ownership scope. Every scope carries -/// a connection id, which is the tenant boundary secure-exec enforces; ACP +/// a connection id, which is the tenant boundary agentos enforces; ACP /// session ownership is keyed off this same connection id. /// Remove every session in `sessions` owned by `connection_id`, returning the /// adapter process ids of the dropped records. Split out from @@ -1624,7 +1624,7 @@ pub(super) fn is_adapter_exited_error(error: &SidecarError) -> bool { } /// True when `error` means the adapter process is gone: either the in-pump exit -/// observation (`is_adapter_exited_error`) or a secure-exec process-table +/// observation (`is_adapter_exited_error`) or a agentos process-table /// lookup failure from operating on an adapter that already exited — the lazy /// observation of an idle-time crash (`ADAPTER_NO_ACTIVE_PROCESS_MARKER`). pub(super) fn is_adapter_gone_error(error: &SidecarError) -> bool { diff --git a/crates/bridge/Cargo.toml b/crates/bridge/Cargo.toml index cddd3c08d1..2a4b4c3e90 100644 --- a/crates/bridge/Cargo.toml +++ b/crates/bridge/Cargo.toml @@ -4,7 +4,7 @@ version.workspace = true edition.workspace = true license.workspace = true repository.workspace = true -description = "Shared bridge contracts between the secure-exec kernel and execution planes" +description = "Shared bridge contracts between the agentos kernel and execution planes" [dependencies] serde = { version = "1.0", features = ["derive"] } diff --git a/crates/bridge/src/lib.rs b/crates/bridge/src/lib.rs index b7d9298b88..06ba41c19b 100644 --- a/crates/bridge/src/lib.rs +++ b/crates/bridge/src/lib.rs @@ -1,6 +1,6 @@ #![forbid(unsafe_code)] -//! Shared bridge contracts between the secure-exec kernel and execution planes. +//! Shared bridge contracts between the agentos kernel and execution planes. pub mod queue_tracker; diff --git a/crates/bridge/src/queue_tracker.rs b/crates/bridge/src/queue_tracker.rs index 06ef0ca1f6..7ef9130f9e 100644 --- a/crates/bridge/src/queue_tracker.rs +++ b/crates/bridge/src/queue_tracker.rs @@ -1,6 +1,6 @@ //! Centralized bounded-queue usage tracker. //! -//! secure-exec streams guest output through a *chain* of bounded queues: the +//! agentos streams guest output through a *chain* of bounded queues: the //! V8 -> host event channel, the sidecar stdout/stdin frame queues, and so on. //! Each queue applies backpressure when full (it parks the producer until the //! consumer drains) rather than crashing, but backpressure is invisible: a slow @@ -403,7 +403,7 @@ pub struct QueueRegistry { } impl QueueRegistry { - /// The shared registry. All `secure-exec` bounded queues register here so + /// The shared registry. All `agentos` bounded queues register here so /// their usage can be inspected from one place. pub fn global() -> &'static QueueRegistry { static REGISTRY: OnceLock = OnceLock::new(); diff --git a/crates/build-support/Cargo.toml b/crates/build-support/Cargo.toml index d9bed0e4d2..abfd01b416 100644 --- a/crates/build-support/Cargo.toml +++ b/crates/build-support/Cargo.toml @@ -4,7 +4,7 @@ version.workspace = true edition.workspace = true license.workspace = true repository.workspace = true -description = "Build script helpers for secure-exec crates" +description = "Build script helpers for agentos crates" [lib] path = "v8_bridge_build.rs" diff --git a/crates/build-support/v8_bridge_build.rs b/crates/build-support/v8_bridge_build.rs index fc40414f64..c9d64475fb 100644 --- a/crates/build-support/v8_bridge_build.rs +++ b/crates/build-support/v8_bridge_build.rs @@ -301,7 +301,7 @@ mod tests { fn temp_test_dir(name: &str) -> io::Result { let mut path = std::env::temp_dir(); path.push(format!( - "secure-exec-v8-bridge-build-{name}-{}", + "agentos-v8-bridge-build-{name}-{}", std::process::id() )); let _ = fs::remove_dir_all(&path); diff --git a/crates/client/Cargo.toml b/crates/client/Cargo.toml index 2f7d5499d6..77cb647d80 100644 --- a/crates/client/Cargo.toml +++ b/crates/client/Cargo.toml @@ -7,7 +7,7 @@ repository.workspace = true description = "High-level Rust client SDK for the Agent OS native sidecar (1:1 port of the TypeScript AgentOs client)" [dependencies] -# Reuse the secure-exec BARE wire schema + IPC transport. No new wire types are defined here. +# Reuse the agentos BARE wire schema + IPC transport. No new wire types are defined here. agent-client-protocol-schema = { workspace = true } agentos-sidecar-client = { workspace = true } agentos-vm-config = { workspace = true } diff --git a/crates/client/src/agent_os.rs b/crates/client/src/agent_os.rs index 325f52c27d..ce91086a29 100644 --- a/crates/client/src/agent_os.rs +++ b/crates/client/src/agent_os.rs @@ -392,7 +392,7 @@ impl AgentOs { permissions: Some(permissions), // Client-side `moduleAccessCwd` was removed in favor of an // explicit `nodeModulesMount(...)` entry in `mounts`; the - // secure-exec wire field is left unset. + // agentos wire field is left unset. module_access_cwd: None, instructions: config.additional_instructions.clone().into_iter().collect(), projected_modules: Vec::new(), diff --git a/crates/client/src/config.rs b/crates/client/src/config.rs index f8de322e9a..2b21a204cb 100644 --- a/crates/client/src/config.rs +++ b/crates/client/src/config.rs @@ -30,11 +30,11 @@ pub struct AgentOsConfig { /// Software packages to install (flattened). Default `[]`. pub software: Vec, /// Package directories to project into the VM's `/opt/agentos` tree (the - /// secure-exec package projection). Each entry is a host dir containing an + /// agentos package projection). Each entry is a host dir containing an /// `agentos-package.json` manifest + the package payload. Default `[]`. pub packages: Vec, /// Guest mount point for the package projection. Default `/opt/agentos` - /// (secure-exec's `OPT_AGENTOS_ROOT`) when `None`. + /// (agentos's `OPT_AGENTOS_ROOT`) when `None`. pub packages_mount_at: Option, /// Loopback ports exempt from the default outbound-to-host block. pub loopback_exempt_ports: Vec, @@ -166,7 +166,7 @@ impl AgentOsConfigBuilder { #[derive(Debug, Clone, Copy, PartialEq, Eq, Default, Serialize, Deserialize)] #[serde(rename_all = "kebab-case")] pub enum SoftwareKind { - /// A directory of wasm command binaries. Mounted at `/__secure_exec/commands/{index}/` so the + /// A directory of wasm command binaries. Mounted at `/__agentos/commands/{index}/` so the /// sidecar's command discovery can resolve guest commands (`echo`, `sh`, `grep`, ...). #[default] WasmCommands, @@ -221,7 +221,7 @@ pub struct SidecarJsBridgeCall { /// Host-side handler for sidecar `JsBridgeCallRequest` payloads. /// /// This is Rust-only and intentionally not JSON-serializable. RivetKit uses it to bind a native -/// sidecar root filesystem to actor-owned SQLite (`ctx.db_*`) without teaching secure-exec about +/// sidecar root filesystem to actor-owned SQLite (`ctx.db_*`) without teaching agentos about /// Rivet actors. pub type SidecarJsBridgeCallback = Arc< dyn Fn( diff --git a/crates/client/src/fs.rs b/crates/client/src/fs.rs index 069a498083..5595007a41 100644 --- a/crates/client/src/fs.rs +++ b/crates/client/src/fs.rs @@ -518,7 +518,7 @@ impl AgentOs { let result = self .guest_fs_call(Self::fs_request(GuestFilesystemOperation::ReadDir, path)) .await?; - // secure-exec's READ_DIR now returns rich entries (`entries: + // agentos's READ_DIR now returns rich entries (`entries: // list` with name + is_directory + is_symbolic_link); // this name-only accessor projects the basenames. The richer fields back // the typed [`Self::read_dir_with_types`] path. @@ -703,7 +703,7 @@ impl AgentOs { Ok(entries) } - /// Typed directory listing: each child reported with its resolved type. secure-exec's native + /// Typed directory listing: each child reported with its resolved type. agentos's native /// `READ_DIR` returns basenames only (`entries: list`), so the type of each entry is derived /// with a per-child `lstat` (a symlink is reported as such, lstat-style, not followed). Goes /// through the kernel, so mounts are listed correctly. `.`/`..` are filtered. diff --git a/crates/client/src/lib.rs b/crates/client/src/lib.rs index c0389caab2..c0111e904f 100644 --- a/crates/client/src/lib.rs +++ b/crates/client/src/lib.rs @@ -8,7 +8,7 @@ //! //! The client spawns the native `agentos-sidecar` binary and speaks the existing framed BARE //! protocol over its stdio (see [`transport`]). It does NOT embed the kernel in-process and does NOT -//! define a new sidecar wire protocol. The generated Secure Exec schema surface comes from +//! define a new sidecar wire protocol. The generated Agent OS Exec schema surface comes from //! `agentos_sidecar_client::wire`; Agent OS layers ACP/session semantics on top of those generated wire //! frames through the wrapper client. //! diff --git a/crates/client/tests/common/mod.rs b/crates/client/tests/common/mod.rs index fcebfbf55b..921946e7a2 100644 --- a/crates/client/tests/common/mod.rs +++ b/crates/client/tests/common/mod.rs @@ -147,7 +147,7 @@ fn wasm_command_mounts() -> Vec { }; vec![MountConfig::Native { - path: "/__secure_exec/commands/0".to_string(), + path: "/__agentos/commands/0".to_string(), plugin: MountPlugin { id: "host_dir".to_string(), config: Some(serde_json::json!({ diff --git a/crates/execution/CLAUDE.md b/crates/execution/CLAUDE.md index 8512bf579d..5b741aff1a 100644 --- a/crates/execution/CLAUDE.md +++ b/crates/execution/CLAUDE.md @@ -14,7 +14,7 @@ If tests fail because they were written for the old `Command::new("node")` path, ## Node.js Isolation Model -**Desired state:** Guest JS/TS runs inside isolated V8 contexts managed by the execution engine. All Node.js builtins (`fs`, `net`, `child_process`, `dns`, `http`, `os`, etc.) are kernel-backed polyfills that route through the kernel VFS, socket table, and process table. Module loading is fully intercepted — guest code never touches real host APIs. The execution engine previously had this working via `@secure-exec/core` + `@secure-exec/nodejs` with full kernel-backed polyfills for all builtins. +**Desired state:** Guest JS/TS runs inside isolated V8 contexts managed by the execution engine. All Node.js builtins (`fs`, `net`, `child_process`, `dns`, `http`, `os`, etc.) are kernel-backed polyfills that route through the kernel VFS, socket table, and process table. Module loading is fully intercepted — guest code never touches real host APIs. The previous JavaScript kernel packages had full kernel-backed polyfills for all builtins. **Current state (⚠️ STILL INCOMPLETE -- see `~/.agents/todo/node-isolation-gaps.md`):** @@ -23,7 +23,7 @@ Guest JavaScript entrypoints in `javascript.rs` now run only through the shared - Keep any real-host Node helpers isolated to clearly host-only modules used by benchmarks or import-cache tests. Guest JS/WASM/Python runtime code should depend only on neutral shared helpers (for example signal metadata or path resolution), not on files that also own host launch behavior. - Guest-side WebAssembly inside the V8 isolate must stay enabled on both fresh isolates and snapshot restores. Real npm packages rely on `WebAssembly.Module`, `WebAssembly.Instance`, and `WebAssembly.instantiate*`, and allowing those APIs does not violate the kernel-isolation boundary because compilation stays inside the isolate. Do not reintroduce an embedder callback that blocks WASM; rely on V8's own implementation limits instead. -**Recovery reference:** The complete working polyfill + V8 isolate code from the original `@secure-exec/core` + `@secure-exec/nodejs` + `@secure-exec/v8` packages has been recovered to `~/.agents/recovery/secure-exec/`. Key files to port: +**Recovery reference:** The complete working polyfill + V8 isolate code from the original JavaScript runtime packages has been recovered to `~/.agents/recovery/agentos/`. Key files to port: - `nodejs/src/bridge/fs.ts` (3,974 lines) -- full kernel-backed `fs`/`fs/promises` polyfill - `nodejs/src/bridge/network.ts` (11,149 lines) -- full `net`/`dgram`/`dns` polyfill via kernel socket table - `nodejs/src/bridge/child-process.ts` (1,058 lines) -- `child_process` polyfill via kernel process table @@ -34,11 +34,11 @@ Guest JavaScript entrypoints in `javascript.rs` now run only through the shared - `kernel/` -- the JS kernel (VFS, process table, socket table, PTY, pipes) - `v8/` -- V8 runtime process manager, IPC binary protocol -The original source repo is at `/home/nathan/secure-exec-1/` (tagged `v0.2.1`). +The original source repo is at `/home/nathan/agentos-1/` (tagged `v0.2.1`). **Prior art -- the original JS kernel had full polyfills:** -Before the Rust sidecar (commit `5a43882`), the JS kernel (`@secure-exec/core` + `@secure-exec/nodejs` + `packages/posix/`) had complete kernel-backed polyfills for all builtins. The pattern was: +Before the Rust sidecar (commit `5a43882`), the JavaScript kernel and `packages/posix/` had complete kernel-backed polyfills for all builtins. The pattern was: - **Kernel socket table** -- `kernel.socketTable.create/connect/send/recv` managed all TCP/UDP. Loopback stayed in-kernel; external connections went through a `HostNetworkAdapter`. - **Kernel VFS** -- All `fs` operations routed through the kernel VFS via syscall RPC. - **Kernel process table** -- `child_process.spawn` routed through `kernel.spawn()`. @@ -114,7 +114,7 @@ The host-support ESM loader hook (`loader.mjs`) is generated from a Rust string ## Runner Script Assets - Execution-host runner scripts materialized by `NodeImportCache` should live as checked-in assets under `crates/execution/assets/runners/` and be loaded via `include_str!`. -- The stdlib-backed V8 bridge bundle is generated from `packages/build-tools/bridge-src/` into Cargo `OUT_DIR`; `pnpm --dir packages/secure-exec-core build:v8-bridge` is only for manual debugging. Keep the heavier assert/util/zlib payload in `v8-bridge-zlib.js` so the main `v8-bridge.js` stays below the 500KB cap. +- The stdlib-backed V8 bridge bundle is generated from `packages/build-tools/bridge-src/` into Cargo `OUT_DIR`; `pnpm --dir packages/agentos-core build:v8-bridge` is only for manual debugging. Keep the heavier assert/util/zlib payload in `v8-bridge-zlib.js` so the main `v8-bridge.js` stays below the 500KB cap. - Guest `os` virtualization has two env surfaces: public `process.env` is intentionally scrubbed of `AGENTOS_*`, while the real per-execution values live in the hidden runtime env (`globalThis.__agentOSProcessConfigEnv` in `javascript.rs`, mirrored from the sidecar's `prepare_guest_runtime_env(...)`). If `bridge-src` needs VM-scoped CPU/memory/home metadata, read that hidden env path or `_processConfig.env` rather than the sanitized public env, and keep it aligned with `node_import_cache.rs`. - When `build:v8-bridge` pulls deeper undici API modules (for example `undici/lib/api/*`), keep `packages/build-tools/scripts/build-v8-bridge.mjs` aliasing any extra Node builtins they require to standalone shim files under `crates/execution/assets/undici-shims/`; those imports execute while the bundle is still bootstrapping, so they cannot depend on later `exposeCustomGlobal(...)` wiring like `_asyncHooksModule`. - Keep `http` and `https` default agents scoped to their own module instances inside `packages/build-tools/bridge-src/`; sharing a single global default agent makes `http.request()` inherit HTTPS TLS behavior. Guest-local loopback TLS upgrades must also short-circuit inside the bridge instead of calling `net.socket_upgrade_tls`, because loopback fast-path sockets never have a kernel socket id. diff --git a/crates/execution/Cargo.toml b/crates/execution/Cargo.toml index c772bb9f63..f7b05b573f 100644 --- a/crates/execution/Cargo.toml +++ b/crates/execution/Cargo.toml @@ -4,7 +4,7 @@ version.workspace = true edition.workspace = true license.workspace = true repository.workspace = true -description = "Native execution plane scaffold for secure-exec" +description = "Native execution plane scaffold for agentos" build = "build.rs" # Large Pyodide runtime assets are staged at build time (copied from the # in-tree assets directory during workspace builds, or downloaded from the diff --git a/crates/execution/assets/pyodide/README.md b/crates/execution/assets/pyodide/README.md index 5a59900469..d5fb73cf19 100644 --- a/crates/execution/assets/pyodide/README.md +++ b/crates/execution/assets/pyodide/README.md @@ -1,4 +1,4 @@ -Pyodide runtime bundle for the secure-exec Python sidecar. +Pyodide runtime bundle for the agentos Python sidecar. Bundled runtime files: - `pyodide.mjs` @@ -26,7 +26,7 @@ Bundle size as vendored in this directory: Dynamic package installs: - `AGENTOS_PYODIDE_PACKAGE_BASE_URL` can override the package base used by Pyodide package resolution when a Python execution needs to install additional wheels from a network-visible host. - The bundled `micropip` wheel is still loaded from the local asset directory first so package-manager bootstrap does not depend on external network access. -- `await micropip.install("https://.../package.whl")` goes through the Python runner's bridge-backed fetch path, which means network permissions are enforced by the secure-exec kernel rather than bypassing it. +- `await micropip.install("https://.../package.whl")` goes through the Python runner's bridge-backed fetch path, which means network permissions are enforced by the agentos kernel rather than bypassing it. Debug timing output: - Set `AGENTOS_PYTHON_WARMUP_DEBUG=1` on a Python execution request to emit `__AGENTOS_PYTHON_WARMUP_METRICS__:` JSON lines on stderr. diff --git a/crates/execution/assets/runners/python-runner.mjs b/crates/execution/assets/runners/python-runner.mjs index ebea35b7f0..41e261db24 100644 --- a/crates/execution/assets/runners/python-runner.mjs +++ b/crates/execution/assets/runners/python-runner.mjs @@ -25,7 +25,6 @@ const PYTHON_PRELOAD_PACKAGES_ENV = 'AGENTOS_PYTHON_PRELOAD_PACKAGES'; const PYTHON_VFS_RPC_REQUEST_FD_ENV = 'AGENTOS_PYTHON_VFS_RPC_REQUEST_FD'; const PYTHON_VFS_RPC_RESPONSE_FD_ENV = 'AGENTOS_PYTHON_VFS_RPC_RESPONSE_FD'; const FORWARD_KERNEL_STDIN_RPC_ENV = 'AGENTOS_FORWARD_KERNEL_STDIN_RPC'; -const PYTHON_RUNTIME_ENV_NAMES = ['HOME', 'USER', 'LOGNAME', 'SHELL', 'PWD', 'TMPDIR', 'PATH']; const INTERNAL_ENV = globalThis.__agentOSPythonInternalEnv ?? Object.create(null); const ALLOW_PROCESS_BINDINGS = readRunnerEnv('AGENTOS_ALLOW_PROCESS_BINDINGS') === '1'; const STDIN_FD = 0; @@ -408,7 +407,7 @@ async function normalizeFetchBody(body) { return Buffer.from(await body.arrayBuffer()).toString('base64'); } - throw new Error('unsupported fetch body type for secure-exec Python package loading'); + throw new Error('unsupported fetch body type for agentos Python package loading'); } function emitPythonStartupMetrics({ @@ -714,7 +713,7 @@ function createPythonFdRpcBridge() { const chunk = Buffer.alloc(4096); const bytesRead = readSync(responseFd, chunk, 0, chunk.length, null); if (bytesRead === 0) { - throw new Error('secure-exec Python VFS RPC response channel closed unexpectedly'); + throw new Error('agentos Python VFS RPC response channel closed unexpectedly'); } responseBuffer += chunk.subarray(0, bytesRead).toString('utf8'); } @@ -724,7 +723,7 @@ function createPythonFdRpcBridge() { try { return JSON.parse(line); } catch (error) { - throw new Error(`invalid secure-exec Python VFS RPC response: ${formatError(error)}`); + throw new Error(`invalid agentos Python VFS RPC response: ${formatError(error)}`); } } @@ -765,7 +764,7 @@ function createPythonFdRpcBridge() { return message.result ?? {}; } - const error = new Error(message?.error?.message || `secure-exec Python VFS RPC request ${id} failed`); + const error = new Error(message?.error?.message || `agentos Python VFS RPC request ${id} failed`); error.code = message?.error?.code || 'ERR_AGENTOS_PYTHON_VFS_RPC'; throw error; } @@ -897,7 +896,7 @@ function createPythonFdRpcBridge() { } function accessDenied(subject) { - const error = new Error(`${subject} is not available in the secure-exec guest Python runtime`); + const error = new Error(`${subject} is not available in the agentos guest Python runtime`); error.code = ACCESS_DENIED_CODE; return error; } @@ -917,9 +916,9 @@ except Exception: _agentos_safe_pyodide_js_api = None def _agentos_raise_access_denied(module_name): - raise RuntimeError(f"{module_name} is not available in the secure-exec guest Python runtime") + raise RuntimeError(f"{module_name} is not available in the agentos guest Python runtime") -class _SecureExecBlockedModule(_agentos_types.ModuleType): +class _AgentOsBlockedModule(_agentos_types.ModuleType): def __init__(self, name): super().__init__(name) self.__dict__['__all__'] = () @@ -931,7 +930,7 @@ class _SecureExecBlockedModule(_agentos_types.ModuleType): return [] _agentos_blocked_modules = { - _agentos_module_name: _SecureExecBlockedModule(_agentos_module_name) + _agentos_module_name: _AgentOsBlockedModule(_agentos_module_name) for _agentos_module_name in ('js', 'pyodide_js') } @@ -967,13 +966,13 @@ import sys as _agentos_sys import types as _agentos_types import urllib.error as _agentos_urllib_error import urllib.request as _agentos_urllib_request -from email.message import Message as _SecureExecMessage +from email.message import Message as _AgentOsMessage from js import __agentOSPythonVfsRpc as _agentos_rpc def _agentos_raise_from_error(error): if not isinstance(error, dict): raise RuntimeError(str(error)) - message = str(error.get("message", "secure-exec Python bridge request failed")) + message = str(error.get("message", "agentos Python bridge request failed")) if "EACCES:" in message: raise PermissionError(message) if "command not found" in message: @@ -998,17 +997,17 @@ def _agentos_dns_lookup(hostname, family=None): _agentos_raise_from_error({"message": str(error)}) addresses = result.get("addresses") or [] if not addresses: - raise OSError(f"secure-exec DNS lookup returned no addresses for {hostname}") + raise OSError(f"agentos DNS lookup returned no addresses for {hostname}") return addresses -class _SecureExecHttpResponse: +class _AgentOsHttpResponse: def __init__(self, payload): self.status = int(payload.get("status", 0)) self.reason = str(payload.get("reason", "")) self.url = str(payload.get("url", "")) self._body = _agentos_base64.b64decode(payload.get("bodyBase64", "") or "") headers = payload.get("headers") or {} - self.headers = _SecureExecMessage() + self.headers = _AgentOsMessage() for name, values in headers.items(): for value in values: self.headers.add_header(str(name), str(value)) @@ -1034,7 +1033,7 @@ class _SecureExecHttpResponse: self.close() return False -class _SecureExecPyfetchResponse: +class _AgentOsPyfetchResponse: def __init__(self, payload): self.status = int(payload.get("status", 0)) self.status_text = str(payload.get("reason", "")) @@ -1079,7 +1078,7 @@ def _agentos_http_request(url_or_request, data=None): ) except Exception as error: _agentos_raise_from_error({"message": str(error)}) - response = _SecureExecHttpResponse(payload) + response = _AgentOsHttpResponse(payload) if response.status >= 400: raise _agentos_urllib_error.HTTPError( url, @@ -1108,7 +1107,7 @@ async def _agentos_pyfetch(url, **kwargs): ) except Exception as error: _agentos_raise_from_error({"message": str(error)}) - return _SecureExecPyfetchResponse(payload) + return _AgentOsPyfetchResponse(payload) def _agentos_urlopen(url, data=None, timeout=None, *args, **kwargs): del timeout, args, kwargs @@ -1143,7 +1142,7 @@ def _agentos_getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): sockaddr = (address, port) results.append((entry_family, socktype, protocol, "", sockaddr)) if not results: - raise OSError(f"secure-exec DNS lookup returned no matching addresses for {host}") + raise OSError(f"agentos DNS lookup returned no matching addresses for {host}") return results def _agentos_gethostbyname(host): @@ -1178,7 +1177,7 @@ def _agentos_socket_rpc(call): except Exception as exc: raise _agentos_socket_oserror(exc) from None -class _SecureExecSocket: +class _AgentOsSocket: def __init__(self, family=None, type=None, proto=0, fileno=None): self.family = family if family is not None else _agentos_socket.AF_INET self.type = type if type is not None else _agentos_socket.SOCK_STREAM @@ -1334,12 +1333,12 @@ def _agentos_socket_factory(family=-1, type=-1, proto=0, fileno=None): and fam in (_agentos_socket.AF_INET, _agentos_socket.AF_INET6) and typ in (_agentos_socket.SOCK_STREAM, _agentos_socket.SOCK_DGRAM) ): - return _SecureExecSocket(fam, typ, proto) + return _AgentOsSocket(fam, typ, proto) return _agentos_original_socket_class(family, type, proto, fileno) _agentos_socket.socket = _agentos_socket_factory -class _SecureExecRequestsResponse: +class _AgentOsRequestsResponse: def __init__(self, payload): self.status_code = int(payload.get("status", 0)) self.reason = str(payload.get("reason", "")) @@ -1360,7 +1359,7 @@ class _SecureExecRequestsResponse: if self.status_code >= 400: raise RuntimeError(f"{self.status_code} {self.reason}") -class _SecureExecRequestsSession: +class _AgentOsRequestsSession: def request(self, method, url, **kwargs): headers = dict(kwargs.get("headers") or {}) data = kwargs.get("data") @@ -1378,16 +1377,16 @@ class _SecureExecRequestsSession: ) except Exception as error: _agentos_raise_from_error({"message": str(error)}) - return _SecureExecRequestsResponse(payload) + return _AgentOsRequestsResponse(payload) def get(self, url, **kwargs): return self.request("GET", url, **kwargs) def _agentos_install_requests_module(): module = _agentos_types.ModuleType("requests") - session = _SecureExecRequestsSession + session = _AgentOsRequestsSession module.Session = session - module.Response = _SecureExecRequestsResponse + module.Response = _AgentOsRequestsResponse module.request = lambda method, url, **kwargs: session().request(method, url, **kwargs) module.get = lambda url, **kwargs: session().get(url, **kwargs) module.exceptions = _agentos_types.SimpleNamespace(RequestException=RuntimeError) @@ -1398,12 +1397,12 @@ try: except ModuleNotFoundError: _agentos_install_requests_module() else: - _agentos_requests.Session = _SecureExecRequestsSession - _agentos_requests.Response = _SecureExecRequestsResponse - _agentos_requests.request = lambda method, url, **kwargs: _SecureExecRequestsSession().request(method, url, **kwargs) - _agentos_requests.get = lambda url, **kwargs: _SecureExecRequestsSession().get(url, **kwargs) + _agentos_requests.Session = _AgentOsRequestsSession + _agentos_requests.Response = _AgentOsRequestsResponse + _agentos_requests.request = lambda method, url, **kwargs: _AgentOsRequestsSession().request(method, url, **kwargs) + _agentos_requests.get = lambda url, **kwargs: _AgentOsRequestsSession().get(url, **kwargs) -class _SecureExecCompletedProcess: +class _AgentOsCompletedProcess: def __init__(self, args, returncode, stdout, stderr): self.args = args self.returncode = returncode @@ -1443,7 +1442,7 @@ def _agentos_subprocess_run(args, *, capture_output=False, check=False, cwd=None merged_env = dict(env or {}) resolved_cwd = cwd if cwd is not None else _agentos_os.environ.get("PWD") if input is not None: - raise NotImplementedError("subprocess.run input is not supported in the secure-exec Python runtime") + raise NotImplementedError("subprocess.run input is not supported in the agentos Python runtime") try: payload = _agentos_json.loads( _agentos_rpc.subprocessRunSync( @@ -1465,7 +1464,7 @@ def _agentos_subprocess_run(args, *, capture_output=False, check=False, cwd=None else: stdout_value = stdout_bytes stderr_value = stderr_bytes - result = _SecureExecCompletedProcess( + result = _AgentOsCompletedProcess( args, int(payload.get("exitCode", 1)), stdout_value if capture_output else None, @@ -1521,9 +1520,13 @@ function installPythonGuestImportBlocklist(pyodide) { function buildPythonRuntimeEnv() { const runtimeEnv = {}; - for (const name of PYTHON_RUNTIME_ENV_NAMES) { - if (typeof process.env[name] === 'string') { - runtimeEnv[name] = process.env[name]; + for (const [name, value] of Object.entries(process.env)) { + if ( + typeof value === 'string' && + !name.startsWith('AGENTOS_') && + !name.startsWith('NODE_SYNC_RPC_') + ) { + runtimeEnv[name] = value; } } return runtimeEnv; diff --git a/crates/execution/assets/runners/wasi-module.js b/crates/execution/assets/runners/wasi-module.js index 171efbd1dd..0a9949429f 100644 --- a/crates/execution/assets/runners/wasi-module.js +++ b/crates/execution/assets/runners/wasi-module.js @@ -85,7 +85,7 @@ if (typeof globalThis !== "undefined" && typeof globalThis.__agentOSWasiModule = return; } try { - process.stderr.write(`[secure-exec-wasi] ${message}\n`); + process.stderr.write(`[agentos-wasi] ${message}\n`); } catch { // Ignore debug logging failures. } diff --git a/crates/execution/assets/runners/wasi-module.js.orig b/crates/execution/assets/runners/wasi-module.js.orig index a21b8ea079..ad24d0a4fb 100644 --- a/crates/execution/assets/runners/wasi-module.js.orig +++ b/crates/execution/assets/runners/wasi-module.js.orig @@ -76,7 +76,7 @@ if (typeof globalThis !== "undefined" && typeof globalThis.__agentOSWasiModule = return; } try { - process.stderr.write(`[secure-exec-wasi] ${message}\n`); + process.stderr.write(`[agentos-wasi] ${message}\n`); } catch { // Ignore debug logging failures. } diff --git a/crates/execution/assets/runners/wasm-runner.mjs b/crates/execution/assets/runners/wasm-runner.mjs index 6911085427..2d5d7fe799 100644 --- a/crates/execution/assets/runners/wasm-runner.mjs +++ b/crates/execution/assets/runners/wasm-runner.mjs @@ -798,7 +798,7 @@ function isProjectedCommandGuestPath(subject) { ? path.posix.normalize(raw) : path.posix.resolve(HOST_FS_GUEST_CWD, raw); return ( - /^\/__secure_exec\/commands\/\d+(?:\/|$)/u.test(guestPath) || + /^\/__agentos\/commands\/\d+(?:\/|$)/u.test(guestPath) || /^\/opt\/agentos\/bin\/[^/]+$/u.test(guestPath) ); } @@ -860,7 +860,7 @@ function projectedCommandImageBytes(command) { if (!name || name === '.' || name === '/') return null; for (const mapping of GUEST_PATH_MAPPINGS) { if ( - !/^\/__secure_exec\/commands\/\d+$/u.test(mapping?.guestPath ?? '') && + !/^\/__agentos\/commands\/\d+$/u.test(mapping?.guestPath ?? '') && mapping?.guestPath !== '/opt/agentos/bin' ) continue; const guestCandidate = path.posix.join(mapping.guestPath, name); @@ -4501,7 +4501,7 @@ function readSyncRpcLine() { const chunk = Buffer.alloc(4096); const bytesRead = readSync(NODE_SYNC_RPC_RESPONSE_FD, chunk, 0, chunk.length, null); if (bytesRead === 0) { - throw new Error('secure-exec WASM sync RPC response channel closed unexpectedly'); + throw new Error('agentos WASM sync RPC response channel closed unexpectedly'); } syncRpcResponseBuffer += chunk.subarray(0, bytesRead).toString('utf8'); } @@ -4529,7 +4529,7 @@ function callSyncRpc(method, args = []) { } if (!NODE_SYNC_RPC_ENABLE || NODE_SYNC_RPC_REQUEST_FD == null || NODE_SYNC_RPC_RESPONSE_FD == null) { - const error = new Error(`secure-exec WASM sync RPC is unavailable for ${method}`); + const error = new Error(`agentos WASM sync RPC is unavailable for ${method}`); error.code = 'ERR_AGENTOS_WASM_SYNC_RPC_UNAVAILABLE'; throw error; } @@ -4549,7 +4549,7 @@ function callSyncRpc(method, args = []) { } const error = new Error( - response?.error?.message || `secure-exec WASM sync RPC ${method} failed`, + response?.error?.message || `agentos WASM sync RPC ${method} failed`, ); if (typeof response?.error?.code === 'string') { error.code = response.error.code; @@ -12573,7 +12573,7 @@ function resetCaughtWasmSignalDispositionsForExec(sidecarCommitted) { } } -Object.defineProperty(globalThis, '__secureExecWasmSignalDispatch', { +Object.defineProperty(globalThis, '__agentOsWasmSignalDispatch', { configurable: true, writable: true, value: (_eventType, payload) => { diff --git a/crates/execution/assets/undici-shims/async_hooks.js b/crates/execution/assets/undici-shims/async_hooks.js index 5cf4ad48e4..ca09cf8fe1 100644 --- a/crates/execution/assets/undici-shims/async_hooks.js +++ b/crates/execution/assets/undici-shims/async_hooks.js @@ -48,7 +48,7 @@ class AsyncLocalStorage { } class AsyncResource { - constructor(type = "SecureExecAsyncResource") { + constructor(type = "AgentOsAsyncResource") { this.type = type; } diff --git a/crates/execution/assets/undici-shims/http2.js b/crates/execution/assets/undici-shims/http2.js index d6bc80355e..9d055a1209 100644 --- a/crates/execution/assets/undici-shims/http2.js +++ b/crates/execution/assets/undici-shims/http2.js @@ -19,7 +19,7 @@ const constants = { }; function notImplemented(name) { - const error = new Error(`node:http2 ${name} is not available in the secure-exec bridge bootstrap`); + const error = new Error(`node:http2 ${name} is not available in the agentos bridge bootstrap`); error.code = "ERR_NOT_IMPLEMENTED"; throw error; } diff --git a/crates/execution/assets/undici-shims/stream.js b/crates/execution/assets/undici-shims/stream.js index 875ee53a21..524c6c21d4 100644 --- a/crates/execution/assets/undici-shims/stream.js +++ b/crates/execution/assets/undici-shims/stream.js @@ -1,6 +1,6 @@ "use strict"; -import streamDefault, * as streamNs from "secure-exec-stream-stdlib"; +import streamDefault, * as streamNs from "agentos-stream-stdlib"; import { Buffer } from "node:buffer"; const baseStreamModule = streamNs.default ?? streamDefault ?? {}; @@ -130,7 +130,7 @@ export const isDisturbed = (stream) => { ); }; -export * from "secure-exec-stream-stdlib"; +export * from "agentos-stream-stdlib"; export default { ...baseStreamModule, diff --git a/crates/execution/assets/undici-shims/zlib.js b/crates/execution/assets/undici-shims/zlib.js index 3af356f1b5..ef6275d914 100644 --- a/crates/execution/assets/undici-shims/zlib.js +++ b/crates/execution/assets/undici-shims/zlib.js @@ -1,7 +1,7 @@ "use strict"; function getZlibModule() { - const mod = globalThis.__secureExecBuiltinZlibModule; + const mod = globalThis.__agentOsBuiltinZlibModule; if (!mod) { throw new Error("node:zlib bridge module is not available"); } diff --git a/crates/execution/benchmarks/node-import-baseline.md b/crates/execution/benchmarks/node-import-baseline.md index 760df0c6e9..9b6b24b385 100644 --- a/crates/execution/benchmarks/node-import-baseline.md +++ b/crates/execution/benchmarks/node-import-baseline.md @@ -1,4 +1,4 @@ -# secure-exec Node Import Benchmark +# agentos Node Import Benchmark - Generated at unix ms: `1775118070728` - Node binary: `node` diff --git a/crates/execution/src/benchmark.rs b/crates/execution/src/benchmark.rs index cb406362c3..be426a539b 100644 --- a/crates/execution/src/benchmark.rs +++ b/crates/execution/src/benchmark.rs @@ -195,7 +195,7 @@ impl JavascriptBenchmarkReport { comparison: Option<&BenchmarkComparison>, ) -> String { let mut markdown = String::new(); - let _ = writeln!(&mut markdown, "# secure-exec Node Import Benchmark"); + let _ = writeln!(&mut markdown, "# agentos Node Import Benchmark"); let _ = writeln!(&mut markdown); let _ = writeln!( &mut markdown, @@ -3061,25 +3061,25 @@ fn projected_package_import_entrypoint_source() -> String { fn pdf_lib_startup_entrypoint_source() -> String { timed_entrypoint_source( - "const pdfLib = await import('pdf-lib');\nconst pdfDoc = await pdfLib.PDFDocument.create();\nconst page = pdfDoc.addPage([612, 792]);\nconst font = await pdfDoc.embedFont(pdfLib.StandardFonts.Helvetica);\npage.drawText('secure-exec pdf-lib benchmark', {\n x: 50,\n y: 750,\n font,\n size: 18,\n});\nif (pdfDoc.getPageCount() !== 1 || page.getSize().width !== 612) {\n throw new Error('pdf-lib fixture did not create the expected document');\n}", + "const pdfLib = await import('pdf-lib');\nconst pdfDoc = await pdfLib.PDFDocument.create();\nconst page = pdfDoc.addPage([612, 792]);\nconst font = await pdfDoc.embedFont(pdfLib.StandardFonts.Helvetica);\npage.drawText('agentos pdf-lib benchmark', {\n x: 50,\n y: 750,\n font,\n size: 18,\n});\nif (pdfDoc.getPageCount() !== 1 || page.getSize().width !== 612) {\n throw new Error('pdf-lib fixture did not create the expected document');\n}", ) } fn jszip_startup_entrypoint_source() -> String { timed_entrypoint_source( - "const jszipModule = await import('jszip');\nconst JSZip = jszipModule.default ?? jszipModule;\nconst zip = new JSZip();\nzip.file('README.txt', 'secure-exec benchmark archive');\nconst notes = zip.folder('notes');\nif (!notes) {\n throw new Error('jszip fixture failed to create nested folder');\n}\nnotes.file('todo.txt', 'benchmark staging payload');\nconst fileCount = Object.values(zip.files).filter((entry) => !entry.dir).length;\nif (typeof zip.generateAsync !== 'function' || fileCount !== 2) {\n throw new Error('jszip fixture did not stage the expected archive');\n}", + "const jszipModule = await import('jszip');\nconst JSZip = jszipModule.default ?? jszipModule;\nconst zip = new JSZip();\nzip.file('README.txt', 'agentos benchmark archive');\nconst notes = zip.folder('notes');\nif (!notes) {\n throw new Error('jszip fixture failed to create nested folder');\n}\nnotes.file('todo.txt', 'benchmark staging payload');\nconst fileCount = Object.values(zip.files).filter((entry) => !entry.dir).length;\nif (typeof zip.generateAsync !== 'function' || fileCount !== 2) {\n throw new Error('jszip fixture did not stage the expected archive');\n}", ) } fn jszip_end_to_end_entrypoint_source() -> String { timed_entrypoint_source( - "const jszipModule = await import('jszip');\nconst JSZip = jszipModule.default ?? jszipModule;\nconst zip = new JSZip();\nconst repeatedPayload = 'secure-exec benchmark payload '.repeat(512);\nzip.file('README.txt', repeatedPayload);\nconst notes = zip.folder('notes');\nif (!notes) {\n throw new Error('jszip end-to-end fixture failed to create notes folder');\n}\nnotes.file('todo.txt', 'complete the archive roundtrip');\nconst data = zip.folder('data');\nif (!data) {\n throw new Error('jszip end-to-end fixture failed to create data folder');\n}\ndata.file('payload.json', JSON.stringify({\n repeatedPayloadLength: repeatedPayload.length,\n mode: 'cold-end-to-end',\n}));\nconst archiveBytes = await zip.generateAsync({\n type: 'uint8array',\n compression: 'DEFLATE',\n compressionOptions: { level: 6 },\n});\nconst restored = await JSZip.loadAsync(archiveBytes);\nconst restoredFileCount = Object.values(restored.files).filter((entry) => !entry.dir).length;\nconst restoredReadme = await restored.file('README.txt')?.async('string');\nconst restoredTodo = await restored.file('notes/todo.txt')?.async('string');\nconst restoredPayload = await restored.file('data/payload.json')?.async('string');\nif (\n archiveBytes.byteLength >= repeatedPayload.length ||\n restoredFileCount !== 3 ||\n restoredReadme !== repeatedPayload ||\n restoredTodo !== 'complete the archive roundtrip' ||\n !restoredPayload?.includes('cold-end-to-end')\n) {\n throw new Error('jszip end-to-end fixture did not complete the compressed archive roundtrip');\n}", + "const jszipModule = await import('jszip');\nconst JSZip = jszipModule.default ?? jszipModule;\nconst zip = new JSZip();\nconst repeatedPayload = 'agentos benchmark payload '.repeat(512);\nzip.file('README.txt', repeatedPayload);\nconst notes = zip.folder('notes');\nif (!notes) {\n throw new Error('jszip end-to-end fixture failed to create notes folder');\n}\nnotes.file('todo.txt', 'complete the archive roundtrip');\nconst data = zip.folder('data');\nif (!data) {\n throw new Error('jszip end-to-end fixture failed to create data folder');\n}\ndata.file('payload.json', JSON.stringify({\n repeatedPayloadLength: repeatedPayload.length,\n mode: 'cold-end-to-end',\n}));\nconst archiveBytes = await zip.generateAsync({\n type: 'uint8array',\n compression: 'DEFLATE',\n compressionOptions: { level: 6 },\n});\nconst restored = await JSZip.loadAsync(archiveBytes);\nconst restoredFileCount = Object.values(restored.files).filter((entry) => !entry.dir).length;\nconst restoredReadme = await restored.file('README.txt')?.async('string');\nconst restoredTodo = await restored.file('notes/todo.txt')?.async('string');\nconst restoredPayload = await restored.file('data/payload.json')?.async('string');\nif (\n archiveBytes.byteLength >= repeatedPayload.length ||\n restoredFileCount !== 3 ||\n restoredReadme !== repeatedPayload ||\n restoredTodo !== 'complete the archive roundtrip' ||\n !restoredPayload?.includes('cold-end-to-end')\n) {\n throw new Error('jszip end-to-end fixture did not complete the compressed archive roundtrip');\n}", ) } fn jszip_repeated_session_compressed_entrypoint_source() -> String { timed_entrypoint_source( - "const jszipModule = await import('jszip');\nconst JSZip = jszipModule.default ?? jszipModule;\nconst zip = new JSZip();\nconst repeatedPayload = 'secure-exec benchmark payload '.repeat(512);\nzip.file('README.txt', repeatedPayload);\nconst notes = zip.folder('notes');\nif (!notes) {\n throw new Error('jszip repeated-session fixture failed to create notes folder');\n}\nnotes.file('todo.txt', 'repeat this session workload');\nconst data = zip.folder('data');\nif (!data) {\n throw new Error('jszip repeated-session fixture failed to create data folder');\n}\ndata.file('payload.json', JSON.stringify({\n repeatedPayloadLength: repeatedPayload.length,\n repeatedSessions: true,\n}));\nconst archiveBytes = await zip.generateAsync({\n type: 'uint8array',\n compression: 'DEFLATE',\n compressionOptions: { level: 6 },\n});\nconst restored = await JSZip.loadAsync(archiveBytes);\nconst restoredFileCount = Object.values(restored.files).filter((entry) => !entry.dir).length;\nconst restoredReadme = await restored.file('README.txt')?.async('string');\nconst restoredTodo = await restored.file('notes/todo.txt')?.async('string');\nif (\n archiveBytes.byteLength >= repeatedPayload.length ||\n restoredFileCount !== 3 ||\n restoredReadme !== repeatedPayload ||\n restoredTodo !== 'repeat this session workload'\n) {\n throw new Error('jszip repeated-session fixture did not complete the compressed archive roundtrip');\n}", + "const jszipModule = await import('jszip');\nconst JSZip = jszipModule.default ?? jszipModule;\nconst zip = new JSZip();\nconst repeatedPayload = 'agentos benchmark payload '.repeat(512);\nzip.file('README.txt', repeatedPayload);\nconst notes = zip.folder('notes');\nif (!notes) {\n throw new Error('jszip repeated-session fixture failed to create notes folder');\n}\nnotes.file('todo.txt', 'repeat this session workload');\nconst data = zip.folder('data');\nif (!data) {\n throw new Error('jszip repeated-session fixture failed to create data folder');\n}\ndata.file('payload.json', JSON.stringify({\n repeatedPayloadLength: repeatedPayload.length,\n repeatedSessions: true,\n}));\nconst archiveBytes = await zip.generateAsync({\n type: 'uint8array',\n compression: 'DEFLATE',\n compressionOptions: { level: 6 },\n});\nconst restored = await JSZip.loadAsync(archiveBytes);\nconst restoredFileCount = Object.values(restored.files).filter((entry) => !entry.dir).length;\nconst restoredReadme = await restored.file('README.txt')?.async('string');\nconst restoredTodo = await restored.file('notes/todo.txt')?.async('string');\nif (\n archiveBytes.byteLength >= repeatedPayload.length ||\n restoredFileCount !== 3 ||\n restoredReadme !== repeatedPayload ||\n restoredTodo !== 'repeat this session workload'\n) {\n throw new Error('jszip repeated-session fixture did not complete the compressed archive roundtrip');\n}", ) } diff --git a/crates/execution/src/javascript.rs b/crates/execution/src/javascript.rs index d71e776327..d75fe38902 100644 --- a/crates/execution/src/javascript.rs +++ b/crates/execution/src/javascript.rs @@ -161,10 +161,10 @@ const JAVASCRIPT_CAPTURED_OUTPUT_LIMIT_BYTES: usize = 16 * 1024 * 1024; const KERNEL_STDIN_BUFFER_LIMIT_BYTES: usize = 16 * 1024 * 1024; const NODE_WARMUP_MARKER_VERSION: &str = "1"; const NODE_WARMUP_SPECIFIERS: &[&str] = &[ - "secure-exec:builtin/path", - "secure-exec:builtin/url", - "secure-exec:builtin/fs-promises", - "secure-exec:polyfill/path", + "agentos:builtin/path", + "agentos:builtin/url", + "agentos:builtin/fs-promises", + "agentos:polyfill/path", ]; #[derive(Debug, Default, Clone)] @@ -5470,10 +5470,10 @@ fn polyfill_expression(request: &str) -> Option { format!( "(() => {{ const error = new Error({message}); error.code = {code}; throw error; }})()", message = serde_json::to_string(&format!( - "node:{normalized} is not available in the secure-exec guest runtime" + "node:{normalized} is not available in the agentos guest runtime" )) .unwrap_or_else(|_| format!( - "\"node:{normalized} is not available in the secure-exec guest runtime\"" + "\"node:{normalized} is not available in the agentos guest runtime\"" )), code = serde_json::to_string(error_code) .unwrap_or_else(|_| "\"ERR_ACCESS_DENIED\"".to_owned()) @@ -7264,11 +7264,11 @@ export default { if module_name == "vm" { return String::from( - r#"const VM_CONTEXT_TAG = typeof Symbol === "function" ? Symbol.for("secure-exec.vm.context") : "__secure_exec_vm_context__"; -const VM_CONTEXT_ID = typeof Symbol === "function" ? Symbol.for("secure-exec.vm.context.id") : "__secure_exec_vm_context_id__"; + r#"const VM_CONTEXT_TAG = typeof Symbol === "function" ? Symbol.for("agentos.vm.context") : "__agentos_vm_context__"; +const VM_CONTEXT_ID = typeof Symbol === "function" ? Symbol.for("agentos.vm.context.id") : "__agentos_vm_context_id__"; function createVmNotImplementedError(feature) { - const error = new Error(`node:vm ${feature} is not implemented in the secure-exec guest runtime`); + const error = new Error(`node:vm ${feature} is not implemented in the agentos guest runtime`); error.code = "ERR_NOT_IMPLEMENTED"; return error; } @@ -7406,7 +7406,7 @@ export default { Script, compileFunction, createContext, isContext, measureMemor if module_name == "worker_threads" { return String::from( r#"function createNotImplementedError(feature) { - const error = new Error(`node:worker_threads ${feature} is not available in the secure-exec guest runtime`); + const error = new Error(`node:worker_threads ${feature} is not available in the agentos guest runtime`); error.code = "ERR_NOT_IMPLEMENTED"; return error; } @@ -7460,7 +7460,7 @@ function setEnvironmentData() {} export const BroadcastChannel = globalThis.BroadcastChannel; export { MessageChannel, MessagePort, Worker, getEnvironmentData, markAsUncloneable, markAsUntransferable, moveMessagePortToContext, postMessageToThread, receiveMessageOnPort, setEnvironmentData }; -export const SHARE_ENV = Symbol.for("secure-exec.worker_threads.SHARE_ENV"); +export const SHARE_ENV = Symbol.for("agentos.worker_threads.SHARE_ENV"); export const isMainThread = true; export const parentPort = null; export const resourceLimits = {}; @@ -8761,7 +8761,7 @@ mod tests { .expect("system time") .as_nanos(); let root = std::env::temp_dir().join(format!( - "secure-exec-module-bridge-{}-{unique}", + "agentos-module-bridge-{}-{unique}", std::process::id() )); let bin_dir = root.join("node_modules/next/dist/bin"); diff --git a/crates/execution/src/lib.rs b/crates/execution/src/lib.rs index ba69788fac..a1bf7a3dc0 100644 --- a/crates/execution/src/lib.rs +++ b/crates/execution/src/lib.rs @@ -1,6 +1,6 @@ #![forbid(unsafe_code)] -//! Native execution plane scaffold for the secure-exec runtime migration. +//! Native execution plane scaffold for the agentos runtime migration. mod common; mod host_node; diff --git a/crates/execution/src/node_import_cache.rs b/crates/execution/src/node_import_cache.rs index 8cc1a04bd8..5dc6b68d01 100644 --- a/crates/execution/src/node_import_cache.rs +++ b/crates/execution/src/node_import_cache.rs @@ -26,8 +26,8 @@ const NODE_IMPORT_CACHE_DIR_PREFIX: &str = "agentos-node-import-cache"; const DEFAULT_NODE_IMPORT_CACHE_MATERIALIZE_TIMEOUT: Duration = Duration::from_secs(30); const NODE_IMPORT_CACHE_BLOCKING_JOB_RESERVATION_BYTES: usize = 64 * 1024; const PYODIDE_DIST_DIR: &str = "pyodide-dist"; -const AGENTOS_BUILTIN_SPECIFIER_PREFIX: &str = "secure-exec:builtin/"; -const AGENTOS_POLYFILL_SPECIFIER_PREFIX: &str = "secure-exec:polyfill/"; +const AGENTOS_BUILTIN_SPECIFIER_PREFIX: &str = "agentos:builtin/"; +const AGENTOS_POLYFILL_SPECIFIER_PREFIX: &str = "agentos:polyfill/"; const BUNDLED_PYODIDE_MJS: &[u8] = include_bytes!("../assets/pyodide/pyodide.mjs"); // Large Pyodide assets are excluded from the published crate and staged into // OUT_DIR by build.rs (copied from `assets/pyodide/` in-tree, or downloaded @@ -215,7 +215,7 @@ export async function resolve(specifier, context, nextResolve) { metrics.resolveMisses += 1; - const asset = resolveSecureExecAsset(specifier); + const asset = resolveAgentOsAsset(specifier); if (asset) { cacheState.resolutions[key] = { kind: 'explicit-file', @@ -640,7 +640,7 @@ function loadProjectedPackageSource(url, filePath, format) { return source; } -function resolveSecureExecAsset(specifier) { +function resolveAgentOsAsset(specifier) { if (typeof specifier !== 'string' || !ASSET_ROOT) { return null; } @@ -2900,7 +2900,7 @@ fn render_fs_builtin_asset_source(init_counter_key: &str) -> String { globalThis[{init_counter_key}] = initCount;\n\ const mod = globalThis.__agentOSBuiltinFs ?? globalThis.__agentOSGuestFs ?? process.getBuiltinModule?.(\"node:fs\");\n\ if (!mod) {{\n\ - throw new Error('secure-exec guest fs polyfill was not initialized');\n\ + throw new Error('agentos guest fs polyfill was not initialized');\n\ }}\n\n\ export const __agentOSInitCount = initCount;\n\ export default mod;\n\ @@ -2989,7 +2989,7 @@ fn render_fs_promises_builtin_asset_source(init_counter_key: &str) -> String { let init_counter_key = format!("{init_counter_key:?}"); format!( - "import fsModule from \"secure-exec:builtin/fs\";\n\n\ + "import fsModule from \"agentos:builtin/fs\";\n\n\ const initCount = (globalThis[{init_counter_key}] ?? 0) + 1;\n\ globalThis[{init_counter_key}] = initCount;\n\ const mod = fsModule.promises;\n\n\ @@ -3065,7 +3065,7 @@ class AsyncLocalStorage {{\n\ }}\n\ \n\ class AsyncResource {{\n\ - constructor(type = 'SecureExecAsyncResource') {{\n\ + constructor(type = 'AgentOsAsyncResource') {{\n\ this.type = type;\n\ }}\n\ emitBefore() {{}}\n\ @@ -3123,7 +3123,7 @@ fn render_child_process_builtin_asset_source(init_counter_key: &str) -> String { const initCount = (globalThis[{init_counter_key}] ?? 0) + 1;\n\ globalThis[{init_counter_key}] = initCount;\n\ if (!globalThis.__agentOSBuiltinChildProcess) {{\n\ - const error = new Error(\"node:child_process is not available in the secure-exec guest runtime\");\n\ + const error = new Error(\"node:child_process is not available in the agentos guest runtime\");\n\ error.code = ACCESS_DENIED_CODE;\n\ throw error;\n\ }}\n\n\ @@ -3150,7 +3150,7 @@ fn render_net_builtin_asset_source(init_counter_key: &str) -> String { const initCount = (globalThis[{init_counter_key}] ?? 0) + 1;\n\ globalThis[{init_counter_key}] = initCount;\n\ if (!globalThis.__agentOSBuiltinNet) {{\n\ - const error = new Error(\"node:net is not available in the secure-exec guest runtime\");\n\ + const error = new Error(\"node:net is not available in the agentos guest runtime\");\n\ error.code = ACCESS_DENIED_CODE;\n\ throw error;\n\ }}\n\n\ @@ -3183,7 +3183,7 @@ fn render_dgram_builtin_asset_source(init_counter_key: &str) -> String { const initCount = (globalThis[{init_counter_key}] ?? 0) + 1;\n\ globalThis[{init_counter_key}] = initCount;\n\ if (!globalThis.__agentOSBuiltinDgram) {{\n\ - const error = new Error(\"node:dgram is not available in the secure-exec guest runtime\");\n\ + const error = new Error(\"node:dgram is not available in the agentos guest runtime\");\n\ error.code = ACCESS_DENIED_CODE;\n\ throw error;\n\ }}\n\n\ @@ -3324,7 +3324,7 @@ fn render_dns_builtin_asset_source(init_counter_key: &str) -> String { const initCount = (globalThis[{init_counter_key}] ?? 0) + 1;\n\ globalThis[{init_counter_key}] = initCount;\n\ if (!globalThis.__agentOSBuiltinDns) {{\n\ - const error = new Error(\"node:dns is not available in the secure-exec guest runtime\");\n\ + const error = new Error(\"node:dns is not available in the agentos guest runtime\");\n\ error.code = ACCESS_DENIED_CODE;\n\ throw error;\n\ }}\n\n\ @@ -3358,7 +3358,7 @@ fn render_dns_promises_builtin_asset_source(init_counter_key: &str) -> String { const initCount = (globalThis[{init_counter_key}] ?? 0) + 1;\n\ globalThis[{init_counter_key}] = initCount;\n\ if (!globalThis.__agentOSBuiltinDns) {{\n\ - const error = new Error(\"node:dns/promises is not available in the secure-exec guest runtime\");\n\ + const error = new Error(\"node:dns/promises is not available in the agentos guest runtime\");\n\ error.code = ACCESS_DENIED_CODE;\n\ throw error;\n\ }}\n\n\ @@ -3391,7 +3391,7 @@ fn render_http_builtin_asset_source(init_counter_key: &str) -> String { const initCount = (globalThis[{init_counter_key}] ?? 0) + 1;\n\ globalThis[{init_counter_key}] = initCount;\n\ if (!globalThis.__agentOSBuiltinHttp) {{\n\ - const error = new Error(\"node:http is not available in the secure-exec guest runtime\");\n\ + const error = new Error(\"node:http is not available in the agentos guest runtime\");\n\ error.code = ACCESS_DENIED_CODE;\n\ throw error;\n\ }}\n\n\ @@ -3425,7 +3425,7 @@ fn render_http2_builtin_asset_source(init_counter_key: &str) -> String { const initCount = (globalThis[{init_counter_key}] ?? 0) + 1;\n\ globalThis[{init_counter_key}] = initCount;\n\ if (!globalThis.__agentOSBuiltinHttp2) {{\n\ - const error = new Error(\"node:http2 is not available in the secure-exec guest runtime\");\n\ + const error = new Error(\"node:http2 is not available in the agentos guest runtime\");\n\ error.code = ACCESS_DENIED_CODE;\n\ throw error;\n\ }}\n\n\ @@ -3455,7 +3455,7 @@ fn render_https_builtin_asset_source(init_counter_key: &str) -> String { const initCount = (globalThis[{init_counter_key}] ?? 0) + 1;\n\ globalThis[{init_counter_key}] = initCount;\n\ if (!globalThis.__agentOSBuiltinHttps) {{\n\ - const error = new Error(\"node:https is not available in the secure-exec guest runtime\");\n\ + const error = new Error(\"node:https is not available in the agentos guest runtime\");\n\ error.code = ACCESS_DENIED_CODE;\n\ throw error;\n\ }}\n\n\ @@ -3479,7 +3479,7 @@ fn render_tls_builtin_asset_source(init_counter_key: &str) -> String { const initCount = (globalThis[{init_counter_key}] ?? 0) + 1;\n\ globalThis[{init_counter_key}] = initCount;\n\ if (!globalThis.__agentOSBuiltinTls) {{\n\ - const error = new Error(\"node:tls is not available in the secure-exec guest runtime\");\n\ + const error = new Error(\"node:tls is not available in the agentos guest runtime\");\n\ error.code = ACCESS_DENIED_CODE;\n\ throw error;\n\ }}\n\n\ @@ -3514,7 +3514,7 @@ fn render_os_builtin_asset_source(init_counter_key: &str) -> String { const initCount = (globalThis[{init_counter_key}] ?? 0) + 1;\n\ globalThis[{init_counter_key}] = initCount;\n\ if (!globalThis.__agentOSBuiltinOs) {{\n\ - const error = new Error(\"node:os is not available in the secure-exec guest runtime\");\n\ + const error = new Error(\"node:os is not available in the agentos guest runtime\");\n\ error.code = ACCESS_DENIED_CODE;\n\ throw error;\n\ }}\n\n\ @@ -3555,7 +3555,7 @@ fn render_v8_builtin_asset_source(init_counter_key: &str) -> String { globalThis[{init_counter_key}] = initCount;\n\ const mod = process.getBuiltinModule?.(\"node:v8\");\n\ if (!mod) {{\n\ - throw new Error(\"secure-exec guest v8 compatibility module was not initialized\");\n\ + throw new Error(\"agentos guest v8 compatibility module was not initialized\");\n\ }}\n\n\ export const __agentOSInitCount = initCount;\n\ export default mod;\n\ @@ -3591,7 +3591,7 @@ fn render_vm_builtin_asset_source(init_counter_key: &str) -> String { globalThis[{init_counter_key}] = initCount;\n\ const mod = process.getBuiltinModule?.(\"node:vm\");\n\ if (!mod) {{\n\ - throw new Error(\"secure-exec guest vm compatibility module was not initialized\");\n\ + throw new Error(\"agentos guest vm compatibility module was not initialized\");\n\ }}\n\n\ export const __agentOSInitCount = initCount;\n\ export default mod;\n\ @@ -3611,7 +3611,7 @@ fn render_worker_threads_builtin_asset_source(init_counter_key: &str) -> String globalThis[{init_counter_key}] = initCount;\n\ \n\ function createNotImplementedError(feature) {{\n\ - const error = new Error(`node:worker_threads ${{feature}} is not available in the secure-exec guest runtime`);\n\ + const error = new Error(`node:worker_threads ${{feature}} is not available in the agentos guest runtime`);\n\ error.code = \"ERR_NOT_IMPLEMENTED\";\n\ return error;\n\ }}\n\ @@ -3667,7 +3667,7 @@ const mod = {{\n\ BroadcastChannel: globalThis.BroadcastChannel,\n\ MessageChannel,\n\ MessagePort,\n\ - SHARE_ENV: Symbol.for(\"secure-exec.worker_threads.SHARE_ENV\"),\n\ + SHARE_ENV: Symbol.for(\"agentos.worker_threads.SHARE_ENV\"),\n\ Worker,\n\ getEnvironmentData,\n\ isMainThread: true,\n\ @@ -3706,7 +3706,7 @@ export const workerData = mod.workerData;\n" } fn render_denied_asset_source(module_specifier: &str) -> String { - let message = format!("{module_specifier} is not available in the secure-exec guest runtime"); + let message = format!("{module_specifier} is not available in the agentos guest runtime"); format!( "const error = new Error({message:?});\nerror.code = \"ERR_ACCESS_DENIED\";\nthrow error;\n" ) diff --git a/crates/execution/src/python.rs b/crates/execution/src/python.rs index b976b0feb5..809e8de813 100644 --- a/crates/execution/src/python.rs +++ b/crates/execution/src/python.rs @@ -2776,7 +2776,7 @@ fn warmup_marker_contents( env!("CARGO_PKG_NAME").to_string(), env!("CARGO_PKG_VERSION").to_string(), PYTHON_WARMUP_MARKER_VERSION.to_string(), - String::from("secure-exec-v8"), + String::from("agentos-v8"), python_max_old_space_mb(request).to_string(), compile_cache_dir.display().to_string(), pyodide_dist_path.display().to_string(), diff --git a/crates/execution/src/v8_ipc.rs b/crates/execution/src/v8_ipc.rs index c9999d357b..6fe3b383b6 100644 --- a/crates/execution/src/v8_ipc.rs +++ b/crates/execution/src/v8_ipc.rs @@ -1,4 +1,4 @@ -//! Binary IPC framing for communication with the secure-exec-v8 runtime process. +//! Binary IPC framing for communication with the agentos-v8 runtime process. //! //! Wire format per frame: //! [4B total_len (u32 BE, excludes self)] diff --git a/crates/execution/src/wasm.rs b/crates/execution/src/wasm.rs index af52e69681..e295592c9b 100644 --- a/crates/execution/src/wasm.rs +++ b/crates/execution/src/wasm.rs @@ -3132,7 +3132,7 @@ const __agentOSRequireBuiltin = (specifier) => {{ if (typeof process?.getBuiltinModule === "function") {{ return process.getBuiltinModule(specifier); }} - throw new Error(`secure-exec WASM bootstrap cannot load ${{specifier}}`); + throw new Error(`agentos WASM bootstrap cannot load ${{specifier}}`); }}; {wasi_module_source} {env_merge_source} @@ -3176,42 +3176,42 @@ if (typeof globalThis !== "undefined") {{ return __agentOSRequireBuiltin("node:fs").chmodSync(...args); case "__kernel_stdio_write": if (typeof _kernelStdioWriteRaw === "undefined") {{ - throw new Error("secure-exec WASM kernel stdio bridge is unavailable"); + throw new Error("agentos WASM kernel stdio bridge is unavailable"); }} return _kernelStdioWriteRaw.applySync(void 0, args); case "__kernel_stdin_read": if (typeof _kernelStdinReadRaw === "undefined") {{ - throw new Error("secure-exec WASM kernel stdin bridge is unavailable"); + throw new Error("agentos WASM kernel stdin bridge is unavailable"); }} return _kernelStdinReadRaw.applySync(void 0, args); case "__kernel_poll": if (typeof _kernelPollRaw === "undefined") {{ - throw new Error("secure-exec WASM kernel poll bridge is unavailable"); + throw new Error("agentos WASM kernel poll bridge is unavailable"); }} return _kernelPollRaw.applySync(void 0, args); case "__kernel_isatty": if (typeof _kernelIsattyRaw === "undefined") {{ - throw new Error("secure-exec WASM kernel isatty bridge is unavailable"); + throw new Error("agentos WASM kernel isatty bridge is unavailable"); }} return _kernelIsattyRaw.applySync(void 0, args); case "__kernel_flock_path": if (typeof _kernelFlockRaw === "undefined") {{ - throw new Error("secure-exec WASM kernel file-lock bridge is unavailable"); + throw new Error("agentos WASM kernel file-lock bridge is unavailable"); }} return _kernelFlockRaw.applySync(void 0, args); case "__kernel_tty_size": if (typeof _kernelTtySizeRaw === "undefined") {{ - throw new Error("secure-exec WASM kernel tty size bridge is unavailable"); + throw new Error("agentos WASM kernel tty size bridge is unavailable"); }} return _kernelTtySizeRaw.applySync(void 0, args); case "__pty_set_raw_mode": if (typeof _ptySetRawMode === "undefined") {{ - throw new Error("secure-exec WASM PTY raw-mode bridge is unavailable"); + throw new Error("agentos WASM PTY raw-mode bridge is unavailable"); }} return _ptySetRawMode.applySync(void 0, args); case "child_process.spawn": {{ if (typeof _childProcessSpawnStart === "undefined") {{ - throw new Error("secure-exec WASM child_process bridge is unavailable"); + throw new Error("agentos WASM child_process bridge is unavailable"); }} const [request] = args; return _childProcessSpawnStart.applySync(void 0, [ @@ -3222,32 +3222,32 @@ if (typeof globalThis !== "undefined") {{ }} case "child_process.poll": if (typeof _childProcessPoll === "undefined") {{ - throw new Error("secure-exec WASM child_process poll bridge is unavailable"); + throw new Error("agentos WASM child_process poll bridge is unavailable"); }} return _childProcessPoll.applySync(void 0, args); case "child_process.kill": if (typeof _childProcessKill === "undefined") {{ - throw new Error("secure-exec WASM child_process kill bridge is unavailable"); + throw new Error("agentos WASM child_process kill bridge is unavailable"); }} return _childProcessKill.applySync(void 0, args); case "process.kill": if (typeof _processKill === "undefined") {{ - throw new Error("secure-exec WASM process kill bridge is unavailable"); + throw new Error("agentos WASM process kill bridge is unavailable"); }} return _processKill.applySync(void 0, args); case "process.exec": if (typeof _processExec === "undefined") {{ - throw new Error("secure-exec WASM process exec bridge is unavailable"); + throw new Error("agentos WASM process exec bridge is unavailable"); }} return _processExec.applySync(void 0, args); case "process.exec_fd_image_commit": if (typeof _processExecFdImageCommit === "undefined") {{ - throw new Error("secure-exec WASM process fd image commit bridge is unavailable"); + throw new Error("agentos WASM process fd image commit bridge is unavailable"); }} return _processExecFdImageCommit.applySync(void 0, args); case "child_process.write_stdin": {{ if (typeof _childProcessStdinWrite === "undefined") {{ - throw new Error("secure-exec WASM child_process stdin bridge is unavailable"); + throw new Error("agentos WASM child_process stdin bridge is unavailable"); }} const [childId, chunk] = args; return _childProcessStdinWrite.applySync(void 0, [ @@ -3257,67 +3257,67 @@ if (typeof globalThis !== "undefined") {{ }} case "child_process.close_stdin": if (typeof _childProcessStdinClose === "undefined") {{ - throw new Error("secure-exec WASM child_process stdin-close bridge is unavailable"); + throw new Error("agentos WASM child_process stdin-close bridge is unavailable"); }} return _childProcessStdinClose.applySync(void 0, args); case "net.connect": if (typeof _netSocketConnectRaw === "undefined") {{ - throw new Error("secure-exec WASM net.connect bridge is unavailable"); + throw new Error("agentos WASM net.connect bridge is unavailable"); }} return _netSocketConnectRaw.applySync(void 0, args); case "net.bind_unix": if (typeof _netBindUnixRaw === "undefined") {{ - throw new Error("secure-exec WASM net.bind_unix bridge is unavailable"); + throw new Error("agentos WASM net.bind_unix bridge is unavailable"); }} return _netBindUnixRaw.applySync(void 0, args); case "net.bind_connected_unix": if (typeof _netBindConnectedUnixRaw === "undefined") {{ - throw new Error("secure-exec WASM net.bind_connected_unix bridge is unavailable"); + throw new Error("agentos WASM net.bind_connected_unix bridge is unavailable"); }} return _netBindConnectedUnixRaw.applySync(void 0, args); case "net.reserve_tcp_port": if (typeof _netReserveTcpPortRaw === "undefined") {{ - throw new Error("secure-exec WASM net.reserve_tcp_port bridge is unavailable"); + throw new Error("agentos WASM net.reserve_tcp_port bridge is unavailable"); }} return _netReserveTcpPortRaw.applySync(void 0, args); case "net.release_tcp_port": if (typeof _netReleaseTcpPortRaw === "undefined") {{ - throw new Error("secure-exec WASM net.release_tcp_port bridge is unavailable"); + throw new Error("agentos WASM net.release_tcp_port bridge is unavailable"); }} return _netReleaseTcpPortRaw.applySync(void 0, args); case "net.listen": if (typeof _netServerListenRaw === "undefined") {{ - throw new Error("secure-exec WASM net.listen bridge is unavailable"); + throw new Error("agentos WASM net.listen bridge is unavailable"); }} return _netServerListenRaw.applySync(void 0, args); case "net.server_accept": if (typeof _netServerAcceptRaw === "undefined") {{ - throw new Error("secure-exec WASM net.server_accept bridge is unavailable"); + throw new Error("agentos WASM net.server_accept bridge is unavailable"); }} return _netServerAcceptRaw.applySync(void 0, args); case "net.server_close": if (typeof _netServerCloseSyncRaw === "undefined") {{ - throw new Error("secure-exec WASM net.server_close bridge is unavailable"); + throw new Error("agentos WASM net.server_close bridge is unavailable"); }} return _netServerCloseSyncRaw.applySync(void 0, args); case "net.poll": if (typeof _netSocketPollRaw === "undefined") {{ - throw new Error("secure-exec WASM net.poll bridge is unavailable"); + throw new Error("agentos WASM net.poll bridge is unavailable"); }} return _netSocketPollRaw.applySync(void 0, args); case "net.socket_read": if (typeof _netSocketReadRaw === "undefined") {{ - throw new Error("secure-exec WASM net.socket_read bridge is unavailable"); + throw new Error("agentos WASM net.socket_read bridge is unavailable"); }} return _netSocketReadRaw.applySync(void 0, args); case "net.socket_wait_connect": if (typeof _netSocketWaitConnectSyncRaw === "undefined") {{ - throw new Error("secure-exec WASM net.socket_wait_connect bridge is unavailable"); + throw new Error("agentos WASM net.socket_wait_connect bridge is unavailable"); }} return _netSocketWaitConnectSyncRaw.applySync(void 0, args); case "net.write": if (typeof _netSocketWriteSyncRaw === "undefined") {{ - throw new Error("secure-exec WASM net.write bridge is unavailable"); + throw new Error("agentos WASM net.write bridge is unavailable"); }} return _netSocketWriteSyncRaw.applySync(void 0, [ args[0], @@ -3326,27 +3326,27 @@ if (typeof globalThis !== "undefined") {{ ]); case "net.destroy": if (typeof _netSocketDestroyRaw === "undefined") {{ - throw new Error("secure-exec WASM net.destroy bridge is unavailable"); + throw new Error("agentos WASM net.destroy bridge is unavailable"); }} return _netSocketDestroyRaw.applySync(void 0, args); case "net.socket_upgrade_tls": if (typeof _netSocketUpgradeTlsRaw === "undefined") {{ - throw new Error("secure-exec WASM TLS-upgrade bridge is unavailable"); + throw new Error("agentos WASM TLS-upgrade bridge is unavailable"); }} return _netSocketUpgradeTlsRaw.applySync(void 0, args); case "dgram.createSocket": if (typeof _dgramSocketCreateRaw === "undefined") {{ - throw new Error("secure-exec WASM dgram.createSocket bridge is unavailable"); + throw new Error("agentos WASM dgram.createSocket bridge is unavailable"); }} return _dgramSocketCreateRaw.applySync(void 0, args); case "dgram.bind": if (typeof _dgramSocketBindRaw === "undefined") {{ - throw new Error("secure-exec WASM dgram.bind bridge is unavailable"); + throw new Error("agentos WASM dgram.bind bridge is unavailable"); }} return _dgramSocketBindRaw.applySync(void 0, args); case "dgram.send": {{ if (typeof _dgramSocketSendRaw === "undefined") {{ - throw new Error("secure-exec WASM dgram.send bridge is unavailable"); + throw new Error("agentos WASM dgram.send bridge is unavailable"); }} const [socketId, chunk, options = {{}}] = args; return _dgramSocketSendRaw.applySync(void 0, [ @@ -3357,7 +3357,7 @@ if (typeof globalThis !== "undefined") {{ }} case "dgram.poll": if (typeof _dgramSocketRecvRaw === "undefined") {{ - throw new Error("secure-exec WASM dgram.poll bridge is unavailable"); + throw new Error("agentos WASM dgram.poll bridge is unavailable"); }} const event = _dgramSocketRecvRaw.applySync(void 0, args); if (event && event.type === "message") {{ @@ -3384,32 +3384,32 @@ if (typeof globalThis !== "undefined") {{ return event; case "dgram.close": if (typeof _dgramSocketCloseRaw === "undefined") {{ - throw new Error("secure-exec WASM dgram.close bridge is unavailable"); + throw new Error("agentos WASM dgram.close bridge is unavailable"); }} return _dgramSocketCloseRaw.applySync(void 0, args); case "dgram.address": if (typeof _dgramSocketAddressRaw === "undefined") {{ - throw new Error("secure-exec WASM dgram.address bridge is unavailable"); + throw new Error("agentos WASM dgram.address bridge is unavailable"); }} return _dgramSocketAddressRaw.applySync(void 0, args); case "dgram.setBufferSize": if (typeof _dgramSocketSetBufferSizeRaw === "undefined") {{ - throw new Error("secure-exec WASM dgram.setBufferSize bridge is unavailable"); + throw new Error("agentos WASM dgram.setBufferSize bridge is unavailable"); }} return _dgramSocketSetBufferSizeRaw.applySync(void 0, args); case "dgram.getBufferSize": if (typeof _dgramSocketGetBufferSizeRaw === "undefined") {{ - throw new Error("secure-exec WASM dgram.getBufferSize bridge is unavailable"); + throw new Error("agentos WASM dgram.getBufferSize bridge is unavailable"); }} return _dgramSocketGetBufferSizeRaw.applySync(void 0, args); case "dns.lookup": if (typeof _networkDnsLookupSyncRaw === "undefined") {{ - throw new Error("secure-exec WASM dns.lookup bridge is unavailable"); + throw new Error("agentos WASM dns.lookup bridge is unavailable"); }} return _networkDnsLookupSyncRaw.applySync(void 0, args); case "process.signal_state": {{ if (typeof _processSignalState === "undefined") {{ - throw new Error("secure-exec WASM signal-state bridge is unavailable"); + throw new Error("agentos WASM signal-state bridge is unavailable"); }} const [signal, action = "default", maskJson = "[]", flags = 0] = args; return _processSignalState.applySyncPromise(void 0, [ @@ -3421,7 +3421,7 @@ if (typeof globalThis !== "undefined") {{ }} case "process.take_signal": if (typeof _processTakeSignal === "undefined") {{ - throw new Error("secure-exec WASM signal-drain bridge is unavailable"); + throw new Error("agentos WASM signal-drain bridge is unavailable"); }} return _processTakeSignal.applySync(void 0, args); case "process.getpgid": @@ -3517,11 +3517,11 @@ if (typeof globalThis !== "undefined") {{ case "process.fd_recvmsg_rights": case "process.fd_socket_shutdown": if (typeof _processWasmSyncRpc === "undefined") {{ - throw new Error("secure-exec WASM process-syscall bridge is unavailable"); + throw new Error("agentos WASM process-syscall bridge is unavailable"); }} return _processWasmSyncRpc.applySync(void 0, [method, ...args]); default: - throw new Error(`secure-exec WASM sync RPC method not implemented in V8 runtime: ${{method}}`); + throw new Error(`agentos WASM sync RPC method not implemented in V8 runtime: ${{method}}`); }} }}, async call(method, args = []) {{ @@ -5250,14 +5250,14 @@ mod tests { &BTreeMap::from([( String::from("AGENTOS_GUEST_PATH_MAPPINGS"), format!( - "[{{\"guestPath\":\"/__secure_exec/commands/0\",\"hostPath\":\"{}\"}}]", + "[{{\"guestPath\":\"/__agentos/commands/0\",\"hostPath\":\"{}\"}}]", command_root.display() ), )]), ); assert!(candidates.contains(&module.to_string_lossy().into_owned())); - assert!(candidates.contains(&String::from("/__secure_exec/commands/0/hello"))); + assert!(candidates.contains(&String::from("/__agentos/commands/0/hello"))); } #[test] @@ -5382,7 +5382,7 @@ mod tests { read_only: false, }, super::WasmGuestPathMapping { - guest_path: String::from("/__secure_exec/commands/0"), + guest_path: String::from("/__agentos/commands/0"), host_path: mapped_root.clone(), read_only: false, }, @@ -5609,9 +5609,9 @@ mod tests { fn wasm_sandbox_root_reads_absolute_env_only() { let sandbox_root = wasm_sandbox_root(&BTreeMap::from([( String::from(WASM_SANDBOX_ROOT_ENV), - String::from("/tmp/secure-exec-shadow"), + String::from("/tmp/agentos-shadow"), )])); - assert_eq!(sandbox_root, Some(PathBuf::from("/tmp/secure-exec-shadow"))); + assert_eq!(sandbox_root, Some(PathBuf::from("/tmp/agentos-shadow"))); let relative = wasm_sandbox_root(&BTreeMap::from([( String::from(WASM_SANDBOX_ROOT_ENV), @@ -5639,7 +5639,7 @@ mod tests { module_host_path: PathBuf::from("/tmp/module.wasm"), guest_cwd: String::from("/"), host_cwd: PathBuf::from("/tmp"), - sandbox_root: Some(PathBuf::from("/tmp/secure-exec-shadow")), + sandbox_root: Some(PathBuf::from("/tmp/agentos-shadow")), guest_path_mappings: Vec::new(), route_fs_through_sidecar: true, next_fd: 64, diff --git a/crates/execution/tests/javascript_v8.rs b/crates/execution/tests/javascript_v8.rs index 22e0014121..df4c26e216 100644 --- a/crates/execution/tests/javascript_v8.rs +++ b/crates/execution/tests/javascript_v8.rs @@ -917,7 +917,7 @@ fn javascript_execution_uses_v8_runtime_without_spawning_guest_node_binary() { env: BTreeMap::new(), cwd: temp.path().to_path_buf(), wasm_module_bytes: None, - inline_code: Some(String::from("globalThis.__secureExecRanInV8 = true;")), + inline_code: Some(String::from("globalThis.__agentOsRanInV8 = true;")), }) .expect("start JavaScript execution"); @@ -963,7 +963,7 @@ fn javascript_execution_virtual_os_identity_comes_from_guest_runtime_not_env() { os_tmpdir: Some(String::from("/vm-tmp")), os_type: Some(String::from("VMType")), os_release: Some(String::from("1.2.3-vm")), - os_version: Some(String::from("VM secure-exec build 42")), + os_version: Some(String::from("VM agentos build 42")), os_machine: Some(String::from("vm64")), ..Default::default() }, @@ -992,7 +992,7 @@ if (os.hostname() !== "vm-hostname") throw new Error(`hostname=${os.hostname()}` if (os.tmpdir() !== "/vm-tmp") throw new Error(`tmpdir=${os.tmpdir()}`); if (os.type() !== "VMType") throw new Error(`type=${os.type()}`); if (os.release() !== "1.2.3-vm") throw new Error(`release=${os.release()}`); -if (os.version() !== "VM secure-exec build 42") throw new Error(`version=${os.version()}`); +if (os.version() !== "VM agentos build 42") throw new Error(`version=${os.version()}`); if (os.machine() !== "vm64") throw new Error(`machine=${os.machine()}`); "#, )), @@ -1893,14 +1893,14 @@ fn javascript_execution_high_resolution_time_opt_in_enables_sub_ms_hrtime() { wasm_module_bytes: None, inline_code: Some(String::from( r#" -if (typeof __secureExecHrNowUs !== "function") { +if (typeof __agentOsHrNowUs !== "function") { throw new Error("high-resolution host clock was not installed"); } let sawSubMs = false; for (let attempt = 0; attempt < 80 && !sawSubMs; attempt++) { const start = process.hrtime.bigint(); - const until = __secureExecHrNowUs() + 200; - while (__secureExecHrNowUs() < until) {} + const until = __agentOsHrNowUs() + 200; + while (__agentOsHrNowUs() < until) {} const delta = process.hrtime.bigint() - start; if (delta > 0n && delta < 1000000n) { sawSubMs = true; @@ -1942,7 +1942,7 @@ fn javascript_execution_high_resolution_time_default_off_keeps_coarse_clock() { wasm_module_bytes: None, inline_code: Some(String::from( r#" -if (typeof __secureExecHrNowUs !== "undefined") { +if (typeof __agentOsHrNowUs !== "undefined") { throw new Error("high-resolution host clock exists without opt-in"); } for (let attempt = 0; attempt < 20; attempt++) { diff --git a/crates/execution/tests/process.rs b/crates/execution/tests/process.rs index 4cfc5f05d3..353b00a4d0 100644 --- a/crates/execution/tests/process.rs +++ b/crates/execution/tests/process.rs @@ -57,7 +57,7 @@ fn embedded_runtime_process_keeps_host_pid_internal_for_javascript() { env: BTreeMap::new(), cwd: temp.path().to_path_buf(), wasm_module_bytes: None, - inline_code: Some(String::from("globalThis.__secureExecRanInV8 = true;")), + inline_code: Some(String::from("globalThis.__agentOsRanInV8 = true;")), }) .expect("start JavaScript execution"); diff --git a/crates/kernel/Cargo.toml b/crates/kernel/Cargo.toml index d03fd751a5..007aeda414 100644 --- a/crates/kernel/Cargo.toml +++ b/crates/kernel/Cargo.toml @@ -4,7 +4,7 @@ version.workspace = true edition.workspace = true license.workspace = true repository.workspace = true -description = "Shared kernel plane for secure-exec native and browser sidecars" +description = "Shared kernel plane for agentos native and browser sidecars" [dependencies] agentos-bridge = { workspace = true } diff --git a/crates/kernel/src/kernel.rs b/crates/kernel/src/kernel.rs index 793bad5cfe..28aa7c7b39 100644 --- a/crates/kernel/src/kernel.rs +++ b/crates/kernel/src/kernel.rs @@ -6970,7 +6970,7 @@ impl KernelVm { interpreter_depth: usize, ) -> KernelResult<()> { let resolved = self.validate_executable_path(path, cwd)?; - // `/bin/` and `/__secure_exec/commands/.../` may be + // `/bin/` and `/__agentos/commands/.../` may be // kernel-owned command stubs whose backing bytes are a self-referential // launcher rather than the projected WASM blob the runner loads. Once // the exact path has resolved to a registered command, its trusted @@ -7014,7 +7014,7 @@ impl KernelVm { } if let Some(name) = normalized - .strip_prefix("/__secure_exec/commands/") + .strip_prefix("/__agentos/commands/") .and_then(|suffix| suffix.rsplit('/').next()) { if !name.is_empty() && !name.contains('/') && self.commands.resolve(name).is_some() { @@ -7727,7 +7727,7 @@ impl KernelVm { let mut body = String::new(); for processor in 0..self.proc_cpu_count() { body.push_str(&format!( - "processor\t: {processor}\nmodel name\t: secure-exec Virtual CPU\ncpu MHz\t\t: 1000.000\nsiblings\t: 1\ncpu cores\t: 1\n\n" + "processor\t: {processor}\nmodel name\t: agentos Virtual CPU\ncpu MHz\t\t: 1000.000\nsiblings\t: 1\ncpu cores\t: 1\n\n" )); } body.into_bytes() diff --git a/crates/kernel/src/lib.rs b/crates/kernel/src/lib.rs index 36f2506684..5090568ff4 100644 --- a/crates/kernel/src/lib.rs +++ b/crates/kernel/src/lib.rs @@ -1,6 +1,6 @@ #![forbid(unsafe_code)] -//! Shared per-VM kernel plane for the secure-exec runtime migration. +//! Shared per-VM kernel plane for the agentos runtime migration. pub use agentos_bridge as bridge; pub mod command_registry; diff --git a/crates/kernel/tests/command_registry.rs b/crates/kernel/tests/command_registry.rs index 6188aded6b..933a82b079 100644 --- a/crates/kernel/tests/command_registry.rs +++ b/crates/kernel/tests/command_registry.rs @@ -166,21 +166,21 @@ fn mounted_agentos_command_paths_resolve_to_registered_drivers() { .expect("register drivers"); kernel - .mkdir("/__secure_exec/commands/0", true) + .mkdir("/__agentos/commands/0", true) .expect("create mounted command root"); kernel .write_file( - "/__secure_exec/commands/0/xu", + "/__agentos/commands/0/xu", b"#!/bin/sh\n# kernel command stub\n".to_vec(), ) .expect("write mounted command stub"); kernel - .chmod("/__secure_exec/commands/0/xu", 0o755) + .chmod("/__agentos/commands/0/xu", 0o755) .expect("chmod mounted command stub"); let process = kernel .spawn_process( - "/__secure_exec/commands/0/xu", + "/__agentos/commands/0/xu", vec![String::from("hello-agentos")], SpawnOptions::default(), ) diff --git a/crates/kernel/tests/default_deny_guards.rs b/crates/kernel/tests/default_deny_guards.rs index 0db396f330..0fd804e703 100644 --- a/crates/kernel/tests/default_deny_guards.rs +++ b/crates/kernel/tests/default_deny_guards.rs @@ -1,6 +1,6 @@ //! Default-deny / fail-closed guards (CI hardening, item #5). //! -//! These tests pin down the secure-exec security posture so a refactor cannot +//! These tests pin down the agentos security posture so a refactor cannot //! silently weaken it: //! //! 1. Default-deny: with no policy configured (`Permissions::default()`), diff --git a/crates/kernel/tests/identity.rs b/crates/kernel/tests/identity.rs index 17f33e619a..905a979c8c 100644 --- a/crates/kernel/tests/identity.rs +++ b/crates/kernel/tests/identity.rs @@ -338,7 +338,7 @@ fn procfs_exposes_linux_like_identity_and_system_files() { let cpuinfo = read_utf8(&mut kernel, "/proc/cpuinfo"); assert!(cpuinfo.contains("processor\t: 0")); - assert!(cpuinfo.contains("model name\t: secure-exec Virtual CPU")); + assert!(cpuinfo.contains("model name\t: agentos Virtual CPU")); let meminfo = read_utf8(&mut kernel, "/proc/meminfo"); assert!(meminfo.contains("MemTotal: 262144 kB")); diff --git a/crates/native-baseline/Cargo.toml b/crates/native-baseline/Cargo.toml index 28d539203d..1dd78c7811 100644 --- a/crates/native-baseline/Cargo.toml +++ b/crates/native-baseline/Cargo.toml @@ -7,7 +7,7 @@ publish = false # Native floor for the differential perf harness. std-only on purpose: this is the # glibc fork/posix_spawn + execve baseline that the agent-os "emulation tax" divides -# against. No secure-exec deps — it must measure the host, not the emulator. +# against. No agentos deps — it must measure the host, not the emulator. [[bin]] name = "agentos-native-baseline" diff --git a/crates/native-baseline/src/main.rs b/crates/native-baseline/src/main.rs index ff180dd639..9fb7c88a12 100644 --- a/crates/native-baseline/src/main.rs +++ b/crates/native-baseline/src/main.rs @@ -410,13 +410,13 @@ fn run_once(op: Op, iter: usize, base_dir: &Path, config: &BenchConfig) { assert!(out.status.success(), "pipe chain failed: {out:?}"); } Op::FsStat => { - let path = base_dir.join("secure-exec-native-fs-stat.txt"); + let path = base_dir.join("agentos-native-fs-stat.txt"); std::fs::write(&path, b"hi").expect("write stat fixture"); let meta = std::fs::metadata(&path).expect("stat fixture"); assert!(meta.len() >= 2); } Op::FsStatX32 => { - let path = base_dir.join("secure-exec-native-fs-stat-x32.txt"); + let path = base_dir.join("agentos-native-fs-stat-x32.txt"); if !path.exists() { std::fs::write(&path, b"hi").expect("write stat fixture"); } @@ -433,7 +433,7 @@ fn run_once(op: Op, iter: usize, base_dir: &Path, config: &BenchConfig) { } } Op::FsWrite => { - let path = base_dir.join("secure-exec-native-fs-write.txt"); + let path = base_dir.join("agentos-native-fs-write.txt"); if let Some(size_bytes) = config.size_bytes { std::fs::write(path, vec![(iter & 255) as u8; size_bytes]).expect("write fixture"); } else { @@ -442,7 +442,7 @@ fn run_once(op: Op, iter: usize, base_dir: &Path, config: &BenchConfig) { } Op::FsRead => { let size_bytes = config.size_bytes.unwrap_or(64 * 1024); - let path = base_dir.join("secure-exec-native-fs-read.bin"); + let path = base_dir.join("agentos-native-fs-read.bin"); let rewrite = std::fs::metadata(&path) .map(|meta| meta.len() != size_bytes as u64) .unwrap_or(true); @@ -455,10 +455,10 @@ fn run_once(op: Op, iter: usize, base_dir: &Path, config: &BenchConfig) { Op::StreamCopy => { let size_bytes = config.size_bytes.unwrap_or(64 * 1024); let src = base_dir.join(format!( - "secure-exec-native-stream-copy-src-{size_bytes}.bin" + "agentos-native-stream-copy-src-{size_bytes}.bin" )); let dst = base_dir.join(format!( - "secure-exec-native-stream-copy-dst-{size_bytes}-{iter}.bin" + "agentos-native-stream-copy-dst-{size_bytes}-{iter}.bin" )); let rewrite = std::fs::metadata(&src) .map(|meta| meta.len() != size_bytes as u64) @@ -487,26 +487,26 @@ fn run_once(op: Op, iter: usize, base_dir: &Path, config: &BenchConfig) { assert_eq!(meta.len(), size_bytes as u64); } Op::FsOpenClose => { - let path = base_dir.join("secure-exec-native-fs-open-close.txt"); + let path = base_dir.join("agentos-native-fs-open-close.txt"); std::fs::write(&path, b"hi").expect("write open fixture"); let file = File::open(path).expect("open fixture"); drop(file); } Op::FsMkdirRmdir => { - let path = base_dir.join(format!("secure-exec-native-dir-{iter}")); + let path = base_dir.join(format!("agentos-native-dir-{iter}")); std::fs::create_dir(&path).expect("create dir"); std::fs::remove_dir(&path).expect("remove dir"); } Op::FsRename => { - let from = base_dir.join(format!("secure-exec-native-rename-{iter}.a")); - let to = base_dir.join(format!("secure-exec-native-rename-{iter}.b")); + let from = base_dir.join(format!("agentos-native-rename-{iter}.a")); + let to = base_dir.join(format!("agentos-native-rename-{iter}.b")); std::fs::write(&from, b"hi").expect("write rename fixture"); std::fs::rename(&from, &to).expect("rename fixture"); std::fs::remove_file(&to).expect("remove rename fixture"); } Op::FsReaddir => { let entry_count = config.entry_count.unwrap_or(32); - let dir = base_dir.join("secure-exec-native-readdir"); + let dir = base_dir.join("agentos-native-readdir"); std::fs::create_dir_all(&dir).expect("create readdir dir"); let marker = dir.join(format!(".fixture-ready-{entry_count}")); if !marker.exists() { @@ -522,7 +522,7 @@ fn run_once(op: Op, iter: usize, base_dir: &Path, config: &BenchConfig) { assert!(count > entry_count); } Op::FsFsync => { - let path = base_dir.join("secure-exec-native-fsync.txt"); + let path = base_dir.join("agentos-native-fsync.txt"); let mut file = File::create(path).expect("create fsync fixture"); file.write_all(b"hello").expect("write fsync fixture"); file.sync_all().expect("fsync fixture"); @@ -593,7 +593,7 @@ fn run_once(op: Op, iter: usize, base_dir: &Path, config: &BenchConfig) { } #[cfg(all(unix, not(target_family = "wasm")))] Op::UnixConnect => { - let sock = base_dir.join(format!("secure-exec-native-unix-connect-{iter}.sock")); + let sock = base_dir.join(format!("agentos-native-unix-connect-{iter}.sock")); let _ = std::fs::remove_file(&sock); let listener = UnixListener::bind(&sock).expect("bind unix listener"); let server = thread::spawn(move || { @@ -607,7 +607,7 @@ fn run_once(op: Op, iter: usize, base_dir: &Path, config: &BenchConfig) { #[cfg(all(unix, not(target_family = "wasm")))] Op::UnixEcho => { let payload = vec![7_u8; config.size_bytes.unwrap_or(16)]; - let sock = base_dir.join(format!("secure-exec-native-unix-echo-{iter}.sock")); + let sock = base_dir.join(format!("agentos-native-unix-echo-{iter}.sock")); let _ = std::fs::remove_file(&sock); let listener = UnixListener::bind(&sock).expect("bind unix listener"); let expected_len = payload.len(); diff --git a/crates/native-sidecar-browser/CLAUDE.md b/crates/native-sidecar-browser/CLAUDE.md index 91a5d062a9..fb974c10b3 100644 --- a/crates/native-sidecar-browser/CLAUDE.md +++ b/crates/native-sidecar-browser/CLAUDE.md @@ -1,5 +1,5 @@ # Browser Support -- Browser support is untested after the secure-exec split; only build-level validation is required during migration. +- Browser support is untested after the agentos split; only build-level validation is required during migration. - Provenance: moved from rivet-dev/agentos@87ed8e21e454. - Keep the browser sidecar separate from the native sidecar because worker transport and main-thread ownership differ from stdio/socket transport. diff --git a/crates/native-sidecar-browser/Cargo.toml b/crates/native-sidecar-browser/Cargo.toml index 2eeaa53c87..e280b135a1 100644 --- a/crates/native-sidecar-browser/Cargo.toml +++ b/crates/native-sidecar-browser/Cargo.toml @@ -3,7 +3,7 @@ name = "agentos-native-sidecar-browser" version.workspace = true edition.workspace = true license.workspace = true -description = "Browser-side Secure Exec sidecar scaffold" +description = "Browser-side Agent OS Exec sidecar scaffold" # Browser support is retained for a future migration but intentionally disabled # and must not be published while it is outside the unified reactor contract. publish = false diff --git a/crates/native-sidecar-browser/src/lib.rs b/crates/native-sidecar-browser/src/lib.rs index 4c6fa2c22e..574de48eb4 100644 --- a/crates/native-sidecar-browser/src/lib.rs +++ b/crates/native-sidecar-browser/src/lib.rs @@ -2,7 +2,7 @@ // AGENTOS_BROWSER_SUPPORT_DISABLED: retained for reference, but AgentOS is native-only. /* -//! Browser-side sidecar scaffold for the secure-exec runtime migration. +//! Browser-side sidecar scaffold for the agentos runtime migration. mod service; #[cfg(target_arch = "wasm32")] diff --git a/crates/native-sidecar-browser/tests/service.rs b/crates/native-sidecar-browser/tests/service.rs index 95ce97bede..b8539c475c 100644 --- a/crates/native-sidecar-browser/tests/service.rs +++ b/crates/native-sidecar-browser/tests/service.rs @@ -178,12 +178,12 @@ fn test_os_config() -> BrowserWorkerOsConfig { platform: String::from("linux"), arch: String::from("x64"), r#type: String::from("Linux"), - release: String::from("6.8.0-secure-exec"), - version: String::from("#1 SMP PREEMPT_DYNAMIC secure-exec"), + release: String::from("6.8.0-agentos"), + version: String::from("#1 SMP PREEMPT_DYNAMIC agentos"), cpu_count: 1, totalmem: 1024 * 1024 * 1024, freemem: 512 * 1024 * 1024, - hostname: String::from("secure-exec"), + hostname: String::from("agentos"), homedir: String::from("/home/user"), tmpdir: String::from("/tmp"), machine: String::from("x86_64"), @@ -355,16 +355,16 @@ fn browser_worker_spawn_receives_virtual_identity_config() { ); assert_eq!( spawn.get("os_hostname").map(String::as_str), - Some("secure-exec") + Some("agentos") ); assert_eq!(spawn.get("os_type").map(String::as_str), Some("Linux")); assert_eq!( spawn.get("os_release").map(String::as_str), - Some("6.8.0-secure-exec") + Some("6.8.0-agentos") ); assert_eq!( spawn.get("os_version").map(String::as_str), - Some("#1 SMP PREEMPT_DYNAMIC secure-exec") + Some("#1 SMP PREEMPT_DYNAMIC agentos") ); assert_eq!(spawn.get("os_tmpdir").map(String::as_str), Some("/tmp")); assert_eq!(spawn.get("os_machine").map(String::as_str), Some("x86_64")); diff --git a/crates/native-sidecar-browser/tests/wire_dispatch.rs b/crates/native-sidecar-browser/tests/wire_dispatch.rs index 6723d02e91..e9860e7761 100644 --- a/crates/native-sidecar-browser/tests/wire_dispatch.rs +++ b/crates/native-sidecar-browser/tests/wire_dispatch.rs @@ -33,7 +33,7 @@ struct WireExtension; impl BrowserExtension for WireExtension { fn namespace(&self) -> &str { - "dev.rivet.secure-exec.browser-wire-test" + "dev.rivet.agentos.browser-wire-test" } fn handle_request( @@ -775,7 +775,7 @@ fn browser_wire_dispatcher_routes_extension_frames() { connection_id: String::from("client"), }), payload: RequestPayload::ExtEnvelope(ExtEnvelope { - namespace: String::from("dev.rivet.secure-exec.browser-wire-test"), + namespace: String::from("dev.rivet.agentos.browser-wire-test"), payload: b"ping".to_vec(), }), }, @@ -786,7 +786,7 @@ fn browser_wire_dispatcher_routes_extension_frames() { }; assert_eq!( envelope.namespace, - "dev.rivet.secure-exec.browser-wire-test" + "dev.rivet.agentos.browser-wire-test" ); assert_eq!(envelope.payload, b"wire-ext:ping"); } diff --git a/crates/native-sidecar-core/Cargo.toml b/crates/native-sidecar-core/Cargo.toml index d153e0991b..29c0c1d92e 100644 --- a/crates/native-sidecar-core/Cargo.toml +++ b/crates/native-sidecar-core/Cargo.toml @@ -4,7 +4,7 @@ version.workspace = true edition.workspace = true license.workspace = true repository.workspace = true -description = "Shared Secure Exec sidecar logic for native and browser shells" +description = "Shared Agent OS Exec sidecar logic for native and browser shells" [dependencies] agentos-bridge = { workspace = true } diff --git a/crates/native-sidecar-core/src/frames.rs b/crates/native-sidecar-core/src/frames.rs index f3dd47b172..3d746a3e18 100644 --- a/crates/native-sidecar-core/src/frames.rs +++ b/crates/native-sidecar-core/src/frames.rs @@ -496,13 +496,13 @@ mod tests { #[test] fn authenticated_response_sets_connection_ownership() { let response = - authenticated_response(7, "secure-exec-test", String::from("conn-test"), 1024); + authenticated_response(7, "agentos-test", String::from("conn-test"), 1024); assert_eq!(response.request_id, 7); assert_eq!(response.ownership, OwnershipScope::connection("conn-test")); match response.payload { ResponsePayload::Authenticated(authenticated) => { - assert_eq!(authenticated.sidecar_id, "secure-exec-test"); + assert_eq!(authenticated.sidecar_id, "agentos-test"); assert_eq!(authenticated.connection_id, "conn-test"); assert_eq!(authenticated.max_frame_bytes, 1024); } diff --git a/crates/native-sidecar-core/src/identity.rs b/crates/native-sidecar-core/src/identity.rs index 11f2509b16..9a6c768882 100644 --- a/crates/native-sidecar-core/src/identity.rs +++ b/crates/native-sidecar-core/src/identity.rs @@ -42,13 +42,13 @@ pub fn shared_guest_runtime_identity( os_totalmem: virtual_os_totalmem_bytes(resource_limits), os_freemem: virtual_os_freemem_bytes(resource_limits), os_homedir: user.homedir.clone(), - os_hostname: String::from("secure-exec"), + os_hostname: String::from("agentos"), os_shell: user.shell.clone(), os_user: user.username.clone(), os_tmpdir: String::from("/tmp"), os_type: String::from("Linux"), - os_release: String::from("6.8.0-secure-exec"), - os_version: String::from("#1 SMP PREEMPT_DYNAMIC secure-exec"), + os_release: String::from("6.8.0-agentos"), + os_version: String::from("#1 SMP PREEMPT_DYNAMIC agentos"), os_machine: String::from("x86_64"), } } @@ -86,13 +86,13 @@ mod tests { assert_eq!(identity.os_cpu_count, 6); assert_eq!(identity.os_totalmem, 512 * 1024 * 1024); assert_eq!(identity.os_homedir, "/Users/runner"); - assert_eq!(identity.os_hostname, "secure-exec"); + assert_eq!(identity.os_hostname, "agentos"); assert_eq!(identity.os_shell, "/bin/zsh"); assert_eq!(identity.os_user, "runner"); assert_eq!(identity.os_tmpdir, "/tmp"); assert_eq!(identity.os_type, "Linux"); - assert_eq!(identity.os_release, "6.8.0-secure-exec"); - assert_eq!(identity.os_version, "#1 SMP PREEMPT_DYNAMIC secure-exec"); + assert_eq!(identity.os_release, "6.8.0-agentos"); + assert_eq!(identity.os_version, "#1 SMP PREEMPT_DYNAMIC agentos"); assert_eq!(identity.os_machine, "x86_64"); } } diff --git a/crates/native-sidecar/Cargo.toml b/crates/native-sidecar/Cargo.toml index 9ac6aa003e..608891b334 100644 --- a/crates/native-sidecar/Cargo.toml +++ b/crates/native-sidecar/Cargo.toml @@ -4,7 +4,7 @@ version.workspace = true edition.workspace = true license.workspace = true repository.workspace = true -description = "Native Secure Exec sidecar runtime" +description = "Native Agent OS Exec sidecar runtime" [lib] name = "agentos_native_sidecar" diff --git a/crates/native-sidecar/assets/base-filesystem.json b/crates/native-sidecar/assets/base-filesystem.json index e641efddd3..bdb7b06ec7 100644 --- a/crates/native-sidecar/assets/base-filesystem.json +++ b/crates/native-sidecar/assets/base-filesystem.json @@ -5,8 +5,8 @@ "snapshotCreatedAt": "2026-06-22T19:45:20.529Z", "builtAt": "2026-06-23T03:47:12.644Z", "transforms": [ - "Normalize HOSTNAME to secure-exec", - "Preserve the captured user-level environment and filesystem layout as the secure-exec base layer", + "Normalize HOSTNAME to agentos", + "Preserve the captured user-level environment and filesystem layout as the agentos base layer", "Add the non-Alpine /workspace directory (default agent working directory) owned by the base user", "Restore Alpine 3.22's /etc/services database and add the VM's Docker-style /etc/hosts entries for libc lookup parity" ] @@ -15,7 +15,7 @@ "env": { "CHARSET": "UTF-8", "HOME": "/home/agentos", - "HOSTNAME": "secure-exec", + "HOSTNAME": "agentos", "LANG": "C.UTF-8", "LC_COLLATE": "C", "LOGNAME": "agentos", @@ -92,7 +92,7 @@ "mode": "644", "uid": 0, "gid": 0, - "content": "secure-exec\n" + "content": "agentos\n" }, { "path": "/etc/hosts", @@ -100,7 +100,7 @@ "mode": "644", "uid": 0, "gid": 0, - "content": "127.0.0.1 localhost localhost.localdomain\n::1 localhost localhost.localdomain ip6-localhost ip6-loopback\nfe00:: ip6-localnet\nff00:: ip6-mcastprefix\nff02::1 ip6-allnodes\nff02::2 ip6-allrouters\n127.0.1.1 secure-exec\n" + "content": "127.0.0.1 localhost localhost.localdomain\n::1 localhost localhost.localdomain ip6-localhost ip6-loopback\nfe00:: ip6-localnet\nff00:: ip6-mcastprefix\nff02::1 ip6-allnodes\nff02::2 ip6-allrouters\n127.0.1.1 agentos\n" }, { "path": "/etc/logrotate.d", diff --git a/crates/native-sidecar/src/bindings.rs b/crates/native-sidecar/src/bindings.rs index 19ade95e46..6ba4acc312 100644 --- a/crates/native-sidecar/src/bindings.rs +++ b/crates/native-sidecar/src/bindings.rs @@ -199,7 +199,7 @@ fn binding_command_name_from_specifier(command: &str) -> Option<&str> { let file_name = Path::new(command).file_name()?.to_str()?; let normalized = normalize_path(command); let registered_internal_path = normalized - .strip_prefix("/__secure_exec/commands/") + .strip_prefix("/__agentos/commands/") .and_then(|suffix| suffix.rsplit('/').next()) .is_some_and(|name| name == file_name); if !matches!( diff --git a/crates/native-sidecar/src/bootstrap.rs b/crates/native-sidecar/src/bootstrap.rs index 4d9ded5d1a..558a9a1112 100644 --- a/crates/native-sidecar/src/bootstrap.rs +++ b/crates/native-sidecar/src/bootstrap.rs @@ -36,7 +36,7 @@ where pub(crate) fn discover_command_guest_paths(kernel: &mut SidecarKernel) -> BTreeMap { let mut command_guest_paths = BTreeMap::new(); - let Ok(command_roots) = kernel.read_dir("/__secure_exec/commands") else { + let Ok(command_roots) = kernel.read_dir("/__agentos/commands") else { return command_guest_paths; }; @@ -47,7 +47,7 @@ pub(crate) fn discover_command_guest_paths(kernel: &mut SidecarKernel) -> BTreeM ordered_roots.sort(); for root in ordered_roots { - let guest_root = format!("/__secure_exec/commands/{root}"); + let guest_root = format!("/__agentos/commands/{root}"); let Ok(entries) = kernel.read_dir(&guest_root) else { continue; }; diff --git a/crates/native-sidecar/src/crypto_cipher.rs b/crates/native-sidecar/src/crypto_cipher.rs index 088c352251..9728d503f0 100644 --- a/crates/native-sidecar/src/crypto_cipher.rs +++ b/crates/native-sidecar/src/crypto_cipher.rs @@ -527,7 +527,7 @@ mod tests { fn aes_256_cbc_roundtrip() { let key = [7_u8; 32]; let iv = [9_u8; 16]; - let plaintext = b"secure-exec-crypto-surface"; + let plaintext = b"agentos-crypto-surface"; let (ciphertext, _) = encrypt_all("aes-256-cbc", &key, &iv, plaintext); let recovered = decrypt_all("aes-256-cbc", &key, &iv, &ciphertext, None); assert_eq!(recovered, plaintext); diff --git a/crates/native-sidecar/src/execution/javascript/rpc.rs b/crates/native-sidecar/src/execution/javascript/rpc.rs index 2074204375..bbe575c27e 100644 --- a/crates/native-sidecar/src/execution/javascript/rpc.rs +++ b/crates/native-sidecar/src/execution/javascript/rpc.rs @@ -5079,7 +5079,7 @@ mod error_code_tests { } #[test] - fn guest_errno_code_accepts_trusted_secure_exec_prefixes() { + fn guest_errno_code_accepts_trusted_agentos_prefixes() { assert_eq!( guest_errno_code("ERR_AGENTOS_NODE_SYNC_RPC: EACCES: permission denied on /foo"), Some("EACCES") diff --git a/crates/native-sidecar/src/execution/launch.rs b/crates/native-sidecar/src/execution/launch.rs index 2b833ab87b..b45623ccc4 100644 --- a/crates/native-sidecar/src/execution/launch.rs +++ b/crates/native-sidecar/src/execution/launch.rs @@ -1837,7 +1837,7 @@ pub(super) fn resolve_host_node_cli_entrypoint( continue; }; let package_root = entrypoint.parent()?.parent()?.to_path_buf(); - let guest_root = format!("/__secure_exec/node-runtime/{command_name}"); + let guest_root = format!("/__agentos/node-runtime/{command_name}"); let relative_entrypoint = entrypoint.strip_prefix(&package_root).ok()?; let guest_entrypoint = normalize_path(&format!( "{guest_root}/{}", @@ -1942,7 +1942,7 @@ pub(super) fn build_host_node_cli_eval(cli: &ResolvedHostNodeCliEntrypoint) -> S let guest_display_module = normalize_path(&format!("{}/lib/utils/display.js", cli.guest_root)); let guest_log_file_module = normalize_path(&format!("{}/lib/utils/log-file.js", cli.guest_root)); - let debug_preamble = "const __agentOSDebugNpmCli = !!process.env.CODEX_DEBUG_NPM_CLI; const __agentOSDebugLog = (...args) => { if (__agentOSDebugNpmCli) { console.error('[secure-exec npm debug]', ...args); } }; const __agentOSIsProcessExitError = (error) => !!(error && typeof error === 'object' && (error._isProcessExit === true || error.name === 'ProcessExitError')); const __agentOSResolveExitCode = (code) => Number.isFinite(code) ? code : (Number.isFinite(process.exitCode) ? process.exitCode : 0); const __agentOSFinish = (code) => { process.exitCode = __agentOSResolveExitCode(code); }; if (__agentOSDebugNpmCli) { const __agentOSWrapAsyncFsMethod = (__agentOSTarget, __agentOSMethod) => { const __agentOSOriginal = __agentOSTarget[__agentOSMethod]; if (typeof __agentOSOriginal !== 'function' || __agentOSOriginal.__agentOSDebugWrapped) { return; } const __agentOSWrapped = async (...args) => { const target = args.length > 0 ? args[0] : ''; __agentOSDebugLog(`fs.${__agentOSMethod}:start`, String(target)); try { const result = await __agentOSOriginal.apply(__agentOSTarget, args); __agentOSDebugLog(`fs.${__agentOSMethod}:done`, String(target)); return result; } catch (error) { __agentOSDebugLog(`fs.${__agentOSMethod}:error`, String(target), error && error.stack ? error.stack : String(error)); throw error; } }; __agentOSWrapped.__agentOSDebugWrapped = true; __agentOSTarget[__agentOSMethod] = __agentOSWrapped; }; const __agentOSWrapSyncFsMethod = (__agentOSTarget, __agentOSMethod) => { const __agentOSOriginal = __agentOSTarget[__agentOSMethod]; if (typeof __agentOSOriginal !== 'function' || __agentOSOriginal.__agentOSDebugWrapped) { return; } const __agentOSWrapped = (...args) => { const target = args.length > 0 ? args[0] : ''; __agentOSDebugLog(`fs.${__agentOSMethod}:start`, String(target)); try { const result = __agentOSOriginal.apply(__agentOSTarget, args); __agentOSDebugLog(`fs.${__agentOSMethod}:done`, String(target)); return result; } catch (error) { __agentOSDebugLog(`fs.${__agentOSMethod}:error`, String(target), error && error.stack ? error.stack : String(error)); throw error; } }; __agentOSWrapped.__agentOSDebugWrapped = true; __agentOSTarget[__agentOSMethod] = __agentOSWrapped; }; const __agentOSFsPromiseModules = [require('fs/promises'), require('node:fs/promises')]; for (const __agentOSFsPromises of __agentOSFsPromiseModules) { for (const __agentOSMethod of ['access', 'lstat', 'mkdir', 'open', 'readFile', 'readdir', 'readlink', 'realpath', 'rename', 'rm', 'rmdir', 'stat', 'symlink', 'unlink', 'writeFile']) { __agentOSWrapAsyncFsMethod(__agentOSFsPromises, __agentOSMethod); } } const __agentOSFsModules = [require('fs'), require('node:fs')]; for (const __agentOSFs of __agentOSFsModules) { for (const __agentOSMethod of ['accessSync', 'existsSync', 'lstatSync', 'mkdirSync', 'openSync', 'readFileSync', 'readdirSync', 'readlinkSync', 'realpathSync', 'renameSync', 'rmSync', 'rmdirSync', 'statSync', 'symlinkSync', 'unlinkSync', 'writeFileSync']) { __agentOSWrapSyncFsMethod(__agentOSFs, __agentOSMethod); } } }"; + let debug_preamble = "const __agentOSDebugNpmCli = !!process.env.CODEX_DEBUG_NPM_CLI; const __agentOSDebugLog = (...args) => { if (__agentOSDebugNpmCli) { console.error('[agentos npm debug]', ...args); } }; const __agentOSIsProcessExitError = (error) => !!(error && typeof error === 'object' && (error._isProcessExit === true || error.name === 'ProcessExitError')); const __agentOSResolveExitCode = (code) => Number.isFinite(code) ? code : (Number.isFinite(process.exitCode) ? process.exitCode : 0); const __agentOSFinish = (code) => { process.exitCode = __agentOSResolveExitCode(code); }; if (__agentOSDebugNpmCli) { const __agentOSWrapAsyncFsMethod = (__agentOSTarget, __agentOSMethod) => { const __agentOSOriginal = __agentOSTarget[__agentOSMethod]; if (typeof __agentOSOriginal !== 'function' || __agentOSOriginal.__agentOSDebugWrapped) { return; } const __agentOSWrapped = async (...args) => { const target = args.length > 0 ? args[0] : ''; __agentOSDebugLog(`fs.${__agentOSMethod}:start`, String(target)); try { const result = await __agentOSOriginal.apply(__agentOSTarget, args); __agentOSDebugLog(`fs.${__agentOSMethod}:done`, String(target)); return result; } catch (error) { __agentOSDebugLog(`fs.${__agentOSMethod}:error`, String(target), error && error.stack ? error.stack : String(error)); throw error; } }; __agentOSWrapped.__agentOSDebugWrapped = true; __agentOSTarget[__agentOSMethod] = __agentOSWrapped; }; const __agentOSWrapSyncFsMethod = (__agentOSTarget, __agentOSMethod) => { const __agentOSOriginal = __agentOSTarget[__agentOSMethod]; if (typeof __agentOSOriginal !== 'function' || __agentOSOriginal.__agentOSDebugWrapped) { return; } const __agentOSWrapped = (...args) => { const target = args.length > 0 ? args[0] : ''; __agentOSDebugLog(`fs.${__agentOSMethod}:start`, String(target)); try { const result = __agentOSOriginal.apply(__agentOSTarget, args); __agentOSDebugLog(`fs.${__agentOSMethod}:done`, String(target)); return result; } catch (error) { __agentOSDebugLog(`fs.${__agentOSMethod}:error`, String(target), error && error.stack ? error.stack : String(error)); throw error; } }; __agentOSWrapped.__agentOSDebugWrapped = true; __agentOSTarget[__agentOSMethod] = __agentOSWrapped; }; const __agentOSFsPromiseModules = [require('fs/promises'), require('node:fs/promises')]; for (const __agentOSFsPromises of __agentOSFsPromiseModules) { for (const __agentOSMethod of ['access', 'lstat', 'mkdir', 'open', 'readFile', 'readdir', 'readlink', 'realpath', 'rename', 'rm', 'rmdir', 'stat', 'symlink', 'unlink', 'writeFile']) { __agentOSWrapAsyncFsMethod(__agentOSFsPromises, __agentOSMethod); } } const __agentOSFsModules = [require('fs'), require('node:fs')]; for (const __agentOSFs of __agentOSFsModules) { for (const __agentOSMethod of ['accessSync', 'existsSync', 'lstatSync', 'mkdirSync', 'openSync', 'readFileSync', 'readdirSync', 'readlinkSync', 'realpathSync', 'renameSync', 'rmSync', 'rmdirSync', 'statSync', 'symlinkSync', 'unlinkSync', 'writeFileSync']) { __agentOSWrapSyncFsMethod(__agentOSFs, __agentOSMethod); } } }"; let display_stub = format!( "const __agentOSDisplayModulePath = require.resolve({display_module}); const __agentOSLogFileModulePath = require.resolve({log_file_module}); const __agentOSColorPassthrough = new Proxy((value) => value, {{ get: () => __agentOSColorPassthrough, apply: (_target, _thisArg, args) => args[0] }}); class __AgentOSNpmDisplayStub {{ constructor() {{ this.chalk = {{ noColor: __agentOSColorPassthrough, stdout: __agentOSColorPassthrough, stderr: __agentOSColorPassthrough }}; this._logPaused = true; this._logBuffer = []; this._outputBuffer = []; const levels = {{ silent: 0, error: 1, warn: 2, notice: 3, http: 4, info: 5, verbose: 6, silly: 7 }}; const loglevelIndex = process.argv.findIndex((arg) => arg === '--loglevel' || arg.startsWith('--loglevel=')); const loglevelArg = loglevelIndex < 0 ? undefined : process.argv[loglevelIndex]; const configuredLevel = loglevelArg && loglevelArg.includes('=') ? loglevelArg.slice(loglevelArg.indexOf('=') + 1) : process.argv[loglevelIndex + 1]; this._logThreshold = levels[String(configuredLevel || process.env.npm_config_loglevel || 'notice').toLowerCase()] ?? levels.notice; this._shouldLog = (level) => levels[level] === undefined || levels[level] <= this._logThreshold; this._write = (stream, values) => {{ if (!Array.isArray(values) || values.length === 0) {{ return; }} const text = values.map((value) => typeof value === 'string' ? value : String(value)).join(' '); if (text.length === 0) {{ return; }} const normalized = text.replace(/\\r\\n/g, '\\n'); if (/^\\n?> npx\\n> /u.test(normalized)) {{ return; }} stream.write(text.endsWith('\\n') ? text : `${{text}}\\n`); }}; this._inputHandler = (level, ...args) => {{ if (level !== 'read') {{ return; }} const [resolve, reject, callback] = args; Promise.resolve().then(() => callback()).then(resolve, reject); }}; this._logHandler = (level, ...args) => {{ if (level === 'resume') {{ this._logPaused = false; for (const [bufferLevel, bufferArgs] of this._logBuffer.splice(0)) {{ if (this._shouldLog(bufferLevel)) {{ this._write(process.stderr, bufferArgs); }} }} return; }} if (level === 'pause') {{ this._logPaused = true; return; }} if (!this._shouldLog(level)) {{ return; }} if (this._logPaused) {{ this._logBuffer.push([level, args]); return; }} this._write(process.stderr, args); }}; this._outputHandler = (level, ...args) => {{ if (level === 'buffer') {{ this._outputBuffer.push(['standard', args]); return; }} if (level === 'flush') {{ for (const [bufferLevel, bufferArgs] of this._outputBuffer.splice(0)) {{ this._write(bufferLevel === 'error' ? process.stderr : process.stdout, bufferArgs); }} return; }} this._write(level === 'error' ? process.stderr : process.stdout, args); }}; process.on('input', this._inputHandler); process.on('log', this._logHandler); process.on('output', this._outputHandler); }} async load() {{ process.emit('log', 'resume'); process.emit('output', 'flush'); }} off() {{ if (this._inputHandler) {{ process.off('input', this._inputHandler); }} if (this._logHandler) {{ process.off('log', this._logHandler); }} if (this._outputHandler) {{ process.off('output', this._outputHandler); }} this._logBuffer.length = 0; this._outputBuffer.length = 0; }} }} class __AgentOSNpmLogFileStub {{ constructor() {{ this.files = []; }} async load() {{ return []; }} off() {{}} }} globalThis._moduleCache[__agentOSDisplayModulePath] = {{ exports: __AgentOSNpmDisplayStub }}; globalThis._moduleCache[__agentOSLogFileModulePath] = {{ exports: __AgentOSNpmLogFileStub }};", display_module = serde_json::to_string(&guest_display_module) @@ -2288,7 +2288,7 @@ pub(super) fn registered_command_name_for_path(vm: &VmState, path: &str) -> Opti .find_map(|prefix| normalized.strip_prefix(prefix)) .or_else(|| { normalized - .strip_prefix("/__secure_exec/commands/") + .strip_prefix("/__agentos/commands/") .and_then(|suffix| suffix.rsplit('/').next()) })?; (!name.is_empty() && !name.contains('/') && vm.kernel.commands().contains_key(name)) @@ -2608,7 +2608,7 @@ fn resolve_guest_command_path_candidate(vm: &VmState, candidate: &str) -> Option || candidate.starts_with("/usr/bin/") || candidate.starts_with("/usr/local/bin/") || candidate.starts_with(&format!("{}/", crate::package_projection::OPT_AGENTOS_BIN)) - || candidate.starts_with("/__secure_exec/commands/") + || candidate.starts_with("/__agentos/commands/") { if let Some(file_name) = Path::new(candidate) .file_name() diff --git a/crates/native-sidecar/src/execution/network/dns.rs b/crates/native-sidecar/src/execution/network/dns.rs index 6133600858..3bb18f532f 100644 --- a/crates/native-sidecar/src/execution/network/dns.rs +++ b/crates/native-sidecar/src/execution/network/dns.rs @@ -138,7 +138,7 @@ fn parse_dns_record_type(rrtype: &str) -> Result { "CAA" => Ok(RecordType::CAA), "ANY" => Ok(RecordType::ANY), other => Err(SidecarError::Execution(format!( - "ERR_NOT_IMPLEMENTED: dns rrtype {other} is not supported by the secure-exec dns bridge" + "ERR_NOT_IMPLEMENTED: dns rrtype {other} is not supported by the agentos dns bridge" ))), } } @@ -324,7 +324,7 @@ fn dns_resolution_to_node_value( .collect(), )), other => Err(SidecarError::Execution(format!( - "ERR_NOT_IMPLEMENTED: dns rrtype {other} is not supported by the secure-exec dns bridge" + "ERR_NOT_IMPLEMENTED: dns rrtype {other} is not supported by the agentos dns bridge" ))), } } diff --git a/crates/native-sidecar/src/execution/network/udp.rs b/crates/native-sidecar/src/execution/network/udp.rs index 9a683b7945..3411b29060 100644 --- a/crates/native-sidecar/src/execution/network/udp.rs +++ b/crates/native-sidecar/src/execution/network/udp.rs @@ -1207,7 +1207,7 @@ impl ActiveUdpSocket { ) -> Result { if self.native_commands.is_some() || self.guest_local_addr.is_some() { return Err(SidecarError::Execution(String::from( - "EINVAL: secure-exec dgram socket is already bound", + "EINVAL: agentos dgram socket is already bound", ))); } diff --git a/crates/native-sidecar/src/filesystem.rs b/crates/native-sidecar/src/filesystem.rs index 9cdb048dd6..f7d7c07f46 100644 --- a/crates/native-sidecar/src/filesystem.rs +++ b/crates/native-sidecar/src/filesystem.rs @@ -5869,7 +5869,7 @@ mod tests { ( Some(writable_mapping( "/mapped/file.txt", - "/tmp/secure-exec-mapped-source", + "/tmp/agentos-mapped-source", )), None, ), @@ -5877,7 +5877,7 @@ mod tests { None, Some(writable_mapping( "/mapped-dst/file.txt", - "/tmp/secure-exec-mapped-destination", + "/tmp/agentos-mapped-destination", )), ), ] { diff --git a/crates/native-sidecar/src/plugins/google_drive.rs b/crates/native-sidecar/src/plugins/google_drive.rs index a72afc8a6b..c12249cb70 100644 --- a/crates/native-sidecar/src/plugins/google_drive.rs +++ b/crates/native-sidecar/src/plugins/google_drive.rs @@ -19,7 +19,7 @@ use url::Url; const DEFAULT_CHUNK_SIZE: usize = 4 * 1024 * 1024; const DEFAULT_INLINE_THRESHOLD: usize = 64 * 1024; -const MANIFEST_FORMAT: &str = "secure_exec_google_drive_filesystem_manifest_v1"; +const MANIFEST_FORMAT: &str = "agentos_google_drive_filesystem_manifest_v1"; const LEGACY_AGENTOS_MANIFEST_FORMAT: &str = "agentos_google_drive_filesystem_manifest_v1"; const DRIVE_SCOPE: &str = "https://www.googleapis.com/auth/drive.file"; const DEFAULT_TOKEN_URL: &str = "https://oauth2.googleapis.com/token"; diff --git a/crates/native-sidecar/src/service.rs b/crates/native-sidecar/src/service.rs index 305f57046b..6ea5b33f71 100644 --- a/crates/native-sidecar/src/service.rs +++ b/crates/native-sidecar/src/service.rs @@ -4007,7 +4007,7 @@ pub(crate) fn vfs_error(error: VfsError) -> SidecarError { /// required. The empirically-supported package managers are captured in /// `crates/sidecar/tests/module_layout_e2e.rs`. #[allow(dead_code)] -const HOISTED_NODE_MODULES_GUIDANCE: &str = "secure-exec can't load mounted node_modules: the directory uses a non-flat layout (pnpm / bun / yarn workspaces store, or yarn Plug'n'Play) whose package store isn't visible inside the VM. A flat (hoisted) node_modules is required.\n - pnpm -> add `node-linker=hoisted` to .npmrc, then reinstall\n - yarn berry -> set `nodeLinker: node-modules` in .yarnrc.yml (not pnp/pnpm)\n - bun -> install dependencies outside a workspace (workspaces use a .bun store)\n - npm / yarn classic -> already flat, no change needed"; +const HOISTED_NODE_MODULES_GUIDANCE: &str = "agentos can't load mounted node_modules: the directory uses a non-flat layout (pnpm / bun / yarn workspaces store, or yarn Plug'n'Play) whose package store isn't visible inside the VM. A flat (hoisted) node_modules is required.\n - pnpm -> add `node-linker=hoisted` to .npmrc, then reinstall\n - yarn berry -> set `nodeLinker: node-modules` in .yarnrc.yml (not pnp/pnpm)\n - bun -> install dependencies outside a workspace (workspaces use a .bun store)\n - npm / yarn classic -> already flat, no change needed"; /// Detect, from an adapter's captured stderr, a non-flat-`node_modules` failure /// signature. Returns the actionable guidance to fold into the surfaced error, @@ -4178,7 +4178,7 @@ mod symlinked_node_modules_hint_tests { // dist/package.json inside the unreachable .pnpm store. let stderr = "Error: ENOENT: no such file or directory, open '/root/node_modules/.pnpm/@mariozechner+pi-coding-agent@0.60.0_x/node_modules/@mariozechner/pi-coding-agent/dist/package.json'"; let hint = symlinked_node_modules_hint(stderr).expect("expected hoisted guidance"); - assert!(hint.contains("secure-exec can't load mounted node_modules")); + assert!(hint.contains("agentos can't load mounted node_modules")); assert!(!hint.contains("agentos")); } diff --git a/crates/native-sidecar/src/state.rs b/crates/native-sidecar/src/state.rs index 41ce39cac2..6c3d1a16a3 100644 --- a/crates/native-sidecar/src/state.rs +++ b/crates/native-sidecar/src/state.rs @@ -528,7 +528,7 @@ pub(crate) const VM_LISTEN_PORT_MAX_METADATA_KEY: &str = "network.listen.port_ma pub(crate) const VM_LISTEN_ALLOW_PRIVILEGED_METADATA_KEY: &str = "network.listen.allow_privileged"; pub(crate) const DEFAULT_JAVASCRIPT_NET_BACKLOG: u32 = 511; pub(crate) const LOOPBACK_EXEMPT_PORTS_ENV: &str = "AGENTOS_LOOPBACK_EXEMPT_PORTS"; -pub(crate) const BINDING_DRIVER_NAME: &str = "secure-exec-host-callbacks"; +pub(crate) const BINDING_DRIVER_NAME: &str = "agentos-host-callbacks"; pub(crate) const MAPPED_HOST_FD_START: u32 = 1_000_000_000; // --------------------------------------------------------------------------- diff --git a/crates/native-sidecar/src/stdio.rs b/crates/native-sidecar/src/stdio.rs index ae94506c71..913b2eb022 100644 --- a/crates/native-sidecar/src/stdio.rs +++ b/crates/native-sidecar/src/stdio.rs @@ -1878,7 +1878,7 @@ mod tests { use crate::{ExtensionContext, ExtensionFuture, ExtensionInterruptResponse, ExtensionResponse}; use std::io::Cursor; - const TEST_EXTENSION_NAMESPACE: &str = "dev.rivet.secure-exec.test.blocking"; + const TEST_EXTENSION_NAMESPACE: &str = "dev.rivet.agentos.test.blocking"; fn test_protocol_budget( max_frames: usize, diff --git a/crates/native-sidecar/src/vm.rs b/crates/native-sidecar/src/vm.rs index 67cf2dcac7..39141704e8 100644 --- a/crates/native-sidecar/src/vm.rs +++ b/crates/native-sidecar/src/vm.rs @@ -680,7 +680,7 @@ where vm.command_guest_paths = discover_command_guest_paths(&mut vm.kernel); // The `{ packageDir }` projection lands each package's `bin/` at // `/opt/agentos/bin/` (on `$PATH`) but does NOT populate - // `/__secure_exec/commands`, so `discover_command_guest_paths` alone misses + // `/__agentos/commands`, so `discover_command_guest_paths` alone misses // projected commands and every projected wasm/js command resolves to // ENOEXEC (absolute path) / ENOENT (bare name). Register each projected // command by name -> its `/opt/agentos/bin/` entrypoint so both the @@ -3670,9 +3670,9 @@ mod tests { .expect("clock should be monotonic") .as_nanos(); let database_path = - std::env::temp_dir().join(format!("secure-exec-native-root-{unique}.sqlite")); + std::env::temp_dir().join(format!("agentos-native-root-{unique}.sqlite")); let block_root = - std::env::temp_dir().join(format!("secure-exec-native-root-blocks-{unique}")); + std::env::temp_dir().join(format!("agentos-native-root-blocks-{unique}")); let native_root = native_root_plugin_from_config(Some(&agentos_vm_config::NativeRootFilesystemConfig { plugin: agentos_vm_config::MountPluginDescriptor { diff --git a/crates/native-sidecar/tests/architecture_guards.rs b/crates/native-sidecar/tests/architecture_guards.rs index 09039f098d..560e26e393 100644 --- a/crates/native-sidecar/tests/architecture_guards.rs +++ b/crates/native-sidecar/tests/architecture_guards.rs @@ -20,7 +20,7 @@ //! (`sidecar::execution`), the embedded V8 runtime IPC pair, and //! host-backed storage plugins. //! * process -- `std::process::Command` / `tokio::process` / OS `fork`. -//! Sanctioned only where secure-exec spawns its own helper process (the +//! Sanctioned only where agentos spawns its own helper process (the //! client transport that launches the sidecar). Guest "process" spawns are //! dispatched through the kernel `CommandDriver` registry and never touch //! `Command::new`. @@ -394,12 +394,12 @@ const NET_ALLOW: &[&str] = &[ /// process: OS subprocess creation. /// -/// Sanctioned surface: only the client transport, which spawns secure-exec's +/// Sanctioned surface: only the client transport, which spawns agentos's /// own sidecar helper binary. Guest "process" spawns go through the kernel /// `CommandDriver` registry and never reach `Command::new`. const PROCESS_ALLOW: &[&str] = &[ "crates/sidecar-client/src/transport.rs", - // V8 snapshot builder re-execs secure-exec's OWN binary as a helper + // V8 snapshot builder re-execs agentos's OWN binary as a helper // (SNAPSHOT_HELPER_ENV) so snapshot creation runs in a clean process. // Host-side bootstrap only; no guest-controlled input picks the program. "crates/v8-runtime/src/snapshot.rs", @@ -1449,7 +1449,7 @@ fn browser_sources_are_retained_but_disabled_from_native_build_and_publish_gates } let mirror_generator = - std::fs::read_to_string(root.join("scripts/generate-secure-exec-mirror.mjs")) + std::fs::read_to_string(root.join("scripts/generate-agentos-mirror.mjs")) .expect("read compatibility mirror generator"); assert!( mirror_generator.contains("browserShim ? { private: true } : {}") @@ -1460,7 +1460,7 @@ fn browser_sources_are_retained_but_disabled_from_native_build_and_publish_gates let source = std::fs::read_to_string(root.join(relative_path)) .unwrap_or_else(|error| panic!("read {relative_path}: {error}")); assert!( - source.contains("node --test scripts/generate-secure-exec-mirror.test.mjs"), + source.contains("node --test scripts/generate-agentos-mirror.test.mjs"), "{relative_path} must enforce compatibility-mirror reproducibility" ); } diff --git a/crates/native-sidecar/tests/builtin_conformance.rs b/crates/native-sidecar/tests/builtin_conformance.rs index a633af8473..6f9c7a22be 100644 --- a/crates/native-sidecar/tests/builtin_conformance.rs +++ b/crates/native-sidecar/tests/builtin_conformance.rs @@ -579,7 +579,7 @@ fn fixture_dns_answers(query: &Query) -> Vec { ), fixture_dns_record( "bundle.example.test.", - RData::TXT(TXT::new(vec![String::from("secure-exec")])), + RData::TXT(TXT::new(vec![String::from("agentos")])), ), ], ("bundle.example.test.", RecordType::ANY) => vec![ @@ -2916,8 +2916,8 @@ console.log(JSON.stringify({ curvesIncludePrime256v1: curves.includes("prime256v1"), curvesIncludeSecp384r1: curves.includes("secp384r1"), curvesSorted: curves.join(",") === [...curves].sort().join(","), - sha256: crypto.createHash("sha256").update("secure-exec").digest("hex"), - hmacSha256: crypto.createHmac("sha256", "shared-secret").update("secure-exec").digest("hex"), + sha256: crypto.createHash("sha256").update("agentos").digest("hex"), + hmacSha256: crypto.createHmac("sha256", "shared-secret").update("agentos").digest("hex"), randomBytesLength: random.length, randomBytesHexLength: random.toString("hex").length, randomBytesAllZero: Array.from(random).every((value) => value === 0), @@ -2935,7 +2935,7 @@ import crypto from "node:crypto"; const cipherKey = Buffer.alloc(32, 7); const cipherIv = Buffer.alloc(16, 9); -const cipherPlaintext = Buffer.from("secure-exec-crypto-surface", "utf8"); +const cipherPlaintext = Buffer.from("agentos-crypto-surface", "utf8"); const cipher = crypto.createCipheriv("aes-256-cbc", cipherKey, cipherIv); const encrypted = Buffer.concat([cipher.update(cipherPlaintext), cipher.final()]); const decipher = crypto.createDecipheriv("aes-256-cbc", cipherKey, cipherIv); @@ -2968,24 +2968,24 @@ const importedPrivateKey = crypto.createPrivateKey(privatePem); const importedPublicKey = crypto.createPublicKey(publicPem); const signer = crypto.createSign("sha256"); -signer.update("secure-exec-signature"); +signer.update("agentos-signature"); const signature = signer.sign(importedPrivateKey); const verifier = crypto.createVerify("sha256"); -verifier.update("secure-exec-signature"); +verifier.update("agentos-signature"); const signatureVerified = verifier.verify(importedPublicKey, signature); -const oneShotSignature = crypto.sign("sha256", Buffer.from("secure-exec-signature"), importedPrivateKey); +const oneShotSignature = crypto.sign("sha256", Buffer.from("agentos-signature"), importedPrivateKey); const oneShotVerified = crypto.verify( "sha256", - Buffer.from("secure-exec-signature"), + Buffer.from("agentos-signature"), importedPublicKey, oneShotSignature, ); const rsaCiphertext = crypto.publicEncrypt( { key: importedPublicKey, padding: crypto.constants.RSA_PKCS1_PADDING }, - Buffer.from("secure-exec-rsa", "utf8"), + Buffer.from("agentos-rsa", "utf8"), ); const rsaPlaintext = crypto.privateDecrypt( { key: importedPrivateKey, padding: crypto.constants.RSA_PKCS1_PADDING }, @@ -3803,7 +3803,7 @@ const promisified = await util.promisify((value, callback) => callback(null, val const encodedLength = new util.TextEncoder().encode("Grüße").length; const decodedText = new util.TextDecoder().decode(textBytes); -const deflated = zlib.deflateSync(Buffer.from("secure-exec", "utf8")); +const deflated = zlib.deflateSync(Buffer.from("agentos", "utf8")); const inflated = zlib.inflateSync(deflated).toString("utf8"); console.log(JSON.stringify({ @@ -3938,7 +3938,7 @@ const bufferValue = await streamConsumers.buffer( makeAsyncStream([Buffer.from("buf")]), ); -const deflated = zlib.deflateSync(Buffer.from("secure-exec", "utf8")); +const deflated = zlib.deflateSync(Buffer.from("agentos", "utf8")); const inflated = zlib.inflateSync(deflated).toString("utf8"); process.stdout.write(`${JSON.stringify({ @@ -4060,7 +4060,7 @@ process.exit(0); assert_eq!(result["zlib"]["importConstantsHasSyncFlush"], true); assert_eq!(result["zlib"]["createDeflateType"], "function"); assert_eq!(result["zlib"]["createInflateType"], "function"); - assert_eq!(result["zlib"]["inflated"], "secure-exec"); + assert_eq!(result["zlib"]["inflated"], "agentos"); } fn timer_handle_ref_refresh_matches_host_node_impl() { diff --git a/crates/native-sidecar/tests/connection_auth.rs b/crates/native-sidecar/tests/connection_auth.rs index 7c35316838..aa80b2e3ae 100644 --- a/crates/native-sidecar/tests/connection_auth.rs +++ b/crates/native-sidecar/tests/connection_auth.rs @@ -149,7 +149,7 @@ fn ext_requests_fail_closed_when_namespace_is_unregistered() { 2, wire_connection(&connection_id), RequestPayload::ExtEnvelope(ExtEnvelope { - namespace: "dev.rivet.secure-exec.test".to_string(), + namespace: "dev.rivet.agentos.test".to_string(), payload: b"hello-ext".to_vec(), }), )) @@ -158,7 +158,7 @@ fn ext_requests_fail_closed_when_namespace_is_unregistered() { match result.response.payload { ResponsePayload::RejectedResponse(response) => { assert_eq!(response.code, "unknown_extension"); - assert!(response.message.contains("dev.rivet.secure-exec.test")); + assert!(response.message.contains("dev.rivet.agentos.test")); } other => panic!("unexpected ext response: {other:?}"), } diff --git a/crates/native-sidecar/tests/extension.rs b/crates/native-sidecar/tests/extension.rs index 9881739471..a0ba3b33c4 100644 --- a/crates/native-sidecar/tests/extension.rs +++ b/crates/native-sidecar/tests/extension.rs @@ -19,7 +19,7 @@ use support::{ temp_dir, wire_request, wire_vm, RecordingBridge, }; -const TEST_NAMESPACE: &str = "dev.rivet.secure-exec.extension-test"; +const TEST_NAMESPACE: &str = "dev.rivet.agentos.extension-test"; struct EchoExtension; struct VmLifetimeExtension; @@ -191,7 +191,7 @@ impl Extension for EchoExtension { impl Extension for VmLifetimeExtension { fn namespace(&self) -> &str { - "dev.rivet.secure-exec.extension-vm-lifetime-test" + "dev.rivet.agentos.extension-vm-lifetime-test" } fn handle_request<'a>( @@ -318,7 +318,7 @@ fn extension_session_resources_can_dispose_bound_vm() { 4, wire_vm(&connection_id, &session_id, &vm_id), RequestPayload::ExtEnvelope(ExtEnvelope { - namespace: String::from("dev.rivet.secure-exec.extension-vm-lifetime-test"), + namespace: String::from("dev.rivet.agentos.extension-vm-lifetime-test"), payload: Vec::new(), }), )) @@ -328,7 +328,7 @@ fn extension_session_resources_can_dispose_bound_vm() { ResponsePayload::ExtEnvelope(envelope) => { assert_eq!( envelope.namespace, - "dev.rivet.secure-exec.extension-vm-lifetime-test" + "dev.rivet.agentos.extension-vm-lifetime-test" ); assert_eq!(envelope.payload, b"vm-disposed"); } diff --git a/crates/native-sidecar/tests/filesystem.rs b/crates/native-sidecar/tests/filesystem.rs index b6816ab862..861b6a42a3 100644 --- a/crates/native-sidecar/tests/filesystem.rs +++ b/crates/native-sidecar/tests/filesystem.rs @@ -398,7 +398,7 @@ mod shadow_root { let command_root = registry_command_root() .expect("registry WASM commands are required before mounting command root"); let mut mounts = vec![MountDescriptor { - guest_path: String::from("/__secure_exec/commands/0"), + guest_path: String::from("/__agentos/commands/0"), guest_source: String::from("host_dir"), guest_fstype: String::from("host_dir"), read_only: true, diff --git a/crates/native-sidecar/tests/generated_protocol.rs b/crates/native-sidecar/tests/generated_protocol.rs index 4e9cf451a8..6bd8ee6ccc 100644 --- a/crates/native-sidecar/tests/generated_protocol.rs +++ b/crates/native-sidecar/tests/generated_protocol.rs @@ -127,7 +127,7 @@ fn live_bare_codec_matches_generated_request_bytes() { 11, live_protocol::OwnershipScope::connection("conn-1"), live_protocol::RequestPayload::Ext(live_protocol::ExtEnvelope { - namespace: "dev.rivet.secure-exec.test".to_string(), + namespace: "dev.rivet.agentos.test".to_string(), payload: b"extension-bytes".to_vec(), }), )); @@ -305,7 +305,7 @@ fn generated_ext_frame() -> ProtocolFrame { connection_id: "conn-1".to_string(), }), payload: RequestPayload::ExtEnvelope(ExtEnvelope { - namespace: "dev.rivet.secure-exec.test".to_string(), + namespace: "dev.rivet.agentos.test".to_string(), payload: b"extension-bytes".to_vec(), }), }) diff --git a/crates/native-sidecar/tests/guest_identity.rs b/crates/native-sidecar/tests/guest_identity.rs index 9e59ee4589..694dfdb718 100644 --- a/crates/native-sidecar/tests/guest_identity.rs +++ b/crates/native-sidecar/tests/guest_identity.rs @@ -1,7 +1,7 @@ mod support; use agentos_native_sidecar::wire::{ - CreateVmRequest, GuestRuntimeKind, RequestId, RequestPayload, ResponsePayload, + CreateVmRequest, ExecuteRequest, GuestRuntimeKind, RequestId, RequestPayload, ResponsePayload, RootFilesystemDescriptor, RootFilesystemEntry, RootFilesystemEntryEncoding, RootFilesystemEntryKind, RootFilesystemMode, }; @@ -197,6 +197,7 @@ print(json.dumps({ "env_pwd": os.environ.get("PWD"), "env_shell": os.environ.get("SHELL"), "env_path": os.environ.get("PATH"), + "custom_env": os.environ.get("EXEC_REVIEW"), "internal_keys": sorted([ key for key in os.environ if key.startswith("AGENTOS_") or key.startswith("NODE_SYNC_RPC_") @@ -213,17 +214,26 @@ print(json.dumps({ }, ); - execute_wire( - &mut sidecar, - 4, - &connection_id, - &session_id, - &vm_id, - "proc-python-identity", - GuestRuntimeKind::Python, - std::path::Path::new("/workspace/identity.py"), - Vec::new(), - ); + let result = sidecar + .dispatch_wire_blocking(wire_request( + 4, + support::wire_vm(&connection_id, &session_id, &vm_id), + RequestPayload::ExecuteRequest(ExecuteRequest { + process_id: String::from("proc-python-identity"), + command: None, + runtime: Some(GuestRuntimeKind::Python), + entrypoint: Some(String::from("/workspace/identity.py")), + args: Vec::new(), + env: HashMap::from([(String::from("EXEC_REVIEW"), String::from("visible"))]), + cwd: None, + wasm_permission_tier: None, + }), + )) + .expect("start Python identity execution"); + assert!(matches!( + result.response.payload, + ResponsePayload::ProcessStartedResponse(_) + )); let (stdout, stderr, exit_code) = collect_guest_identity_process_output( &mut sidecar, @@ -245,6 +255,7 @@ print(json.dumps({ assert_eq!(parsed["env_pwd"], "/"); assert_eq!(parsed["env_shell"], "/bin/sh"); assert_eq!(parsed["env_path"], DEFAULT_GUEST_PATH_ENV); + assert_eq!(parsed["custom_env"], "visible"); assert_eq!(parsed["internal_keys"], Value::Array(Vec::new())); assert_eq!(parsed["path_home"], "/home/agentos"); } diff --git a/crates/native-sidecar/tests/host_dir.rs b/crates/native-sidecar/tests/host_dir.rs index cb558a2281..899d704932 100644 --- a/crates/native-sidecar/tests/host_dir.rs +++ b/crates/native-sidecar/tests/host_dir.rs @@ -28,8 +28,8 @@ mod host_dir { #[test] fn filesystem_rejects_symlink_escapes_and_round_trips_writes() { - let host_dir = temp_dir("secure-exec-host-dir-plugin"); - let outside_dir = temp_dir("secure-exec-host-dir-plugin-outside"); + let host_dir = temp_dir("agentos-host-dir-plugin"); + let outside_dir = temp_dir("agentos-host-dir-plugin-outside"); fs::write(host_dir.join("hello.txt"), "hello from host").expect("seed host file"); std::os::unix::fs::symlink(&outside_dir, host_dir.join("escape")) .expect("seed escape symlink"); @@ -75,7 +75,7 @@ mod host_dir { #[test] fn filesystem_pwrite_updates_in_place_and_zero_fills_gaps() { - let host_dir = temp_dir("secure-exec-host-dir-plugin-pwrite"); + let host_dir = temp_dir("agentos-host-dir-plugin-pwrite"); fs::write(host_dir.join("data.txt"), b"abcdef").expect("seed host file"); let mut filesystem = HostDirFilesystem::new(&host_dir).expect("create host dir fs"); @@ -96,8 +96,8 @@ mod host_dir { #[test] fn filesystem_pwrite_rejects_symlink_escape_targets() { - let host_dir = temp_dir("secure-exec-host-dir-plugin-pwrite-escape"); - let outside_dir = temp_dir("secure-exec-host-dir-plugin-pwrite-escape-outside"); + let host_dir = temp_dir("agentos-host-dir-plugin-pwrite-escape"); + let outside_dir = temp_dir("agentos-host-dir-plugin-pwrite-escape-outside"); fs::write(outside_dir.join("outside.txt"), b"outside").expect("seed outside file"); std::os::unix::fs::symlink(&outside_dir, host_dir.join("escape")) .expect("seed escape symlink"); @@ -118,7 +118,7 @@ mod host_dir { #[test] fn filesystem_rejects_full_reads_above_host_dir_limit() { - let host_dir = temp_dir("secure-exec-host-dir-plugin-full-read-limit"); + let host_dir = temp_dir("agentos-host-dir-plugin-full-read-limit"); let huge_file = fs::File::create(host_dir.join("huge.bin")).expect("create huge file"); huge_file .set_len(MAX_HOST_DIR_READ_BYTES as u64 + 1) @@ -135,7 +135,7 @@ mod host_dir { #[test] fn filesystem_pread_rejects_lengths_above_host_dir_limit() { - let host_dir = temp_dir("secure-exec-host-dir-plugin-pread-limit"); + let host_dir = temp_dir("agentos-host-dir-plugin-pread-limit"); fs::write(host_dir.join("small.txt"), b"small").expect("seed host file"); let mut filesystem = HostDirFilesystem::new(&host_dir).expect("create host dir fs"); @@ -149,8 +149,8 @@ mod host_dir { #[test] fn filesystem_metadata_ops_reject_symlink_targets() { - let host_dir = temp_dir("secure-exec-host-dir-plugin-metadata"); - let outside_dir = temp_dir("secure-exec-host-dir-plugin-metadata-outside"); + let host_dir = temp_dir("agentos-host-dir-plugin-metadata"); + let outside_dir = temp_dir("agentos-host-dir-plugin-metadata-outside"); let outside_file = outside_dir.join("outside.txt"); fs::write(&outside_file, b"outside").expect("seed outside file"); std::os::unix::fs::symlink(&outside_file, host_dir.join("link")) @@ -293,7 +293,7 @@ mod host_dir { #[test] fn plugin_config_can_enforce_read_only_mounts() { - let host_dir = temp_dir("secure-exec-host-dir-plugin-readonly"); + let host_dir = temp_dir("agentos-host-dir-plugin-readonly"); fs::write(host_dir.join("hello.txt"), "hello from host").expect("seed host file"); let plugin = HostDirMountPlugin; diff --git a/crates/native-sidecar/tests/posix_path_repro.rs b/crates/native-sidecar/tests/posix_path_repro.rs index 0fb58251a8..03f3796ca0 100644 --- a/crates/native-sidecar/tests/posix_path_repro.rs +++ b/crates/native-sidecar/tests/posix_path_repro.rs @@ -73,7 +73,7 @@ fn configure_mounts( mounts.insert( 0, MountDescriptor { - guest_path: String::from("/__secure_exec/commands/0"), + guest_path: String::from("/__agentos/commands/0"), guest_source: String::from("host_dir"), guest_fstype: String::from("host_dir"), read_only: true, diff --git a/crates/native-sidecar/tests/projection_bench.rs b/crates/native-sidecar/tests/projection_bench.rs index 034b4830f8..c623c19635 100644 --- a/crates/native-sidecar/tests/projection_bench.rs +++ b/crates/native-sidecar/tests/projection_bench.rs @@ -199,7 +199,7 @@ impl Drop for SyntheticTargets { fn write_repeated_file(path: &Path, len: usize) { let mut file = fs::File::create(path) .unwrap_or_else(|e| panic!("create synthetic payload {} failed: {e}", path.display())); - let chunk = b"secure-exec projection bench payload\n"; + let chunk = b"agentos projection bench payload\n"; let mut remaining = len; while remaining > 0 { let n = remaining.min(chunk.len()); @@ -257,7 +257,7 @@ fn create_package_tar(label: &str, dest: &Path, commands: &[&str], payload_bytes fn create_synthetic_targets() -> SyntheticTargets { let unique = format!( - "secure-exec-projection-bench-{}-{}", + "agentos-projection-bench-{}-{}", std::process::id(), std::time::SystemTime::now() .duration_since(std::time::UNIX_EPOCH) @@ -304,7 +304,7 @@ fn create_synthetic_targets() -> SyntheticTargets { fn create_repacked_real_targets(sources: &[(&'static str, &Path)]) -> RealTargets { let unique = format!( - "secure-exec-projection-real-{}-{}", + "agentos-projection-real-{}-{}", std::process::id(), std::time::SystemTime::now() .duration_since(std::time::UNIX_EPOCH) diff --git a/crates/native-sidecar/tests/promisify_module_load.rs b/crates/native-sidecar/tests/promisify_module_load.rs index 540fa323bc..c2c049e9b4 100644 --- a/crates/native-sidecar/tests/promisify_module_load.rs +++ b/crates/native-sidecar/tests/promisify_module_load.rs @@ -1,6 +1,6 @@ //! Regression guard for issue #11: `util.promisify()` throws at module load. //! -//! Original failure mode: a hand-rolled `@secure-exec/core` `util` polyfill exposed many +//! Original failure mode: a hand-rolled legacy `util` polyfill exposed many //! builtin functions as `undefined`. Adapter dependencies (extract-zip, get-stream) called //! `promisify(undefined)` at module-load time, and the polyfill's `promisify` threw a //! `TypeError` synchronously, crashing the whole module load before any application code ran. diff --git a/crates/native-sidecar/tests/protocol.rs b/crates/native-sidecar/tests/protocol.rs index c920439557..b1a17c8cea 100644 --- a/crates/native-sidecar/tests/protocol.rs +++ b/crates/native-sidecar/tests/protocol.rs @@ -130,7 +130,7 @@ fn ext_envelope_event_encoding_microbench() { let ext_frame = ProtocolFrame::Event(EventFrame::new( ownership.clone(), EventPayload::Ext(ExtEnvelope { - namespace: String::from("dev.rivet.secure-exec.acp"), + namespace: String::from("dev.rivet.agentos.acp"), payload: inner, }), )); diff --git a/crates/native-sidecar/tests/sandbox_agent.rs b/crates/native-sidecar/tests/sandbox_agent.rs index 83ce1dcf4d..8b04ed3b86 100644 --- a/crates/native-sidecar/tests/sandbox_agent.rs +++ b/crates/native-sidecar/tests/sandbox_agent.rs @@ -16,7 +16,7 @@ mod sandbox_agent { #[test] fn filesystem_round_trips_small_files_and_uses_http_range_for_large_pread() { - let server = MockSandboxAgentServer::start("secure-exec-sandbox-plugin", None); + let server = MockSandboxAgentServer::start("agentos-sandbox-plugin", None); fs::write(server.root().join("hello.txt"), "hello from sandbox").expect("seed file"); let large_file = (0..100 * 1024) .map(|index| (index % 251) as u8) @@ -74,7 +74,7 @@ mod sandbox_agent { #[test] fn filesystem_pread_falls_back_to_full_fetch_when_remote_ignores_range() { let server = MockSandboxAgentServer::start_without_range_support( - "secure-exec-sandbox-plugin", + "agentos-sandbox-plugin", None, ); let large_file = (0..100 * 1024) @@ -117,7 +117,7 @@ mod sandbox_agent { #[test] fn filesystem_pread_rejects_full_fetch_fallback_above_limit() { let server = MockSandboxAgentServer::start_without_range_support( - "secure-exec-sandbox-plugin-limit", + "agentos-sandbox-plugin-limit", None, ); fs::write(server.root().join("large.bin"), vec![b'x'; 4096]).expect("seed large file"); @@ -145,7 +145,7 @@ mod sandbox_agent { #[test] fn filesystem_pread_rejects_streamed_full_fetch_fallback_above_limit() { let server = MockSandboxAgentServer::start_without_range_support( - "secure-exec-sandbox-plugin-stream-limit", + "agentos-sandbox-plugin-stream-limit", None, ); fs::write(server.root().join("stream-over-limit"), vec![b'x'; 4096]) @@ -185,7 +185,7 @@ mod sandbox_agent { #[test] fn sandbox_agent_client_does_not_follow_redirects() { - let server = MockSandboxAgentServer::start("secure-exec-sandbox-plugin-redirect", None); + let server = MockSandboxAgentServer::start("agentos-sandbox-plugin-redirect", None); let mut filesystem = SandboxAgentFilesystem::from_config(SandboxAgentMountConfig { base_url: server.base_url().to_owned(), @@ -274,7 +274,7 @@ mod sandbox_agent { #[test] fn filesystem_truncate_uses_process_api_without_full_file_buffering() { - let server = MockSandboxAgentServer::start("secure-exec-sandbox-plugin-truncate", None); + let server = MockSandboxAgentServer::start("agentos-sandbox-plugin-truncate", None); fs::write(server.root().join("large.bin"), vec![b'x'; 512]).expect("seed large file"); let mut filesystem = SandboxAgentFilesystem::from_config(SandboxAgentMountConfig { @@ -341,7 +341,7 @@ mod sandbox_agent { #[test] fn plugin_scopes_base_path_and_preserves_auth_headers() { let server = MockSandboxAgentServer::start( - "secure-exec-sandbox-plugin-auth", + "agentos-sandbox-plugin-auth", Some("secret-token"), ); fs::create_dir_all(server.root().join("scoped")).expect("create scoped root"); @@ -388,7 +388,7 @@ mod sandbox_agent { #[test] fn plugin_normalizes_relative_base_path_before_scoping_requests() { let server = - MockSandboxAgentServer::start("secure-exec-sandbox-plugin-base-path", None); + MockSandboxAgentServer::start("agentos-sandbox-plugin-base-path", None); fs::create_dir_all(server.root().join("scoped")).expect("create scoped root"); fs::write( server.root().join("scoped/hello.txt"), @@ -427,7 +427,7 @@ mod sandbox_agent { #[test] fn plugin_unscopes_process_helper_targets_for_relative_base_path() { let server = - MockSandboxAgentServer::start("secure-exec-sandbox-plugin-relative-process", None); + MockSandboxAgentServer::start("agentos-sandbox-plugin-relative-process", None); fs::create_dir_all(server.root().join("scoped")).expect("create scoped root"); fs::write( server.root().join("scoped/original.txt"), @@ -470,7 +470,7 @@ mod sandbox_agent { #[test] fn filesystem_uses_process_api_for_symlink_and_metadata_operations() { - let server = MockSandboxAgentServer::start("secure-exec-sandbox-plugin-process", None); + let server = MockSandboxAgentServer::start("agentos-sandbox-plugin-process", None); fs::write(server.root().join("original.txt"), "hello from sandbox") .expect("seed original file"); @@ -563,7 +563,7 @@ mod sandbox_agent { #[test] fn filesystem_reports_clear_error_when_process_api_is_unavailable() { let server = MockSandboxAgentServer::start_without_process_api( - "secure-exec-sandbox-plugin-no-proc", + "agentos-sandbox-plugin-no-proc", None, ); fs::write(server.root().join("original.txt"), "hello from sandbox") diff --git a/crates/native-sidecar/tests/service.rs b/crates/native-sidecar/tests/service.rs index 4a0769ce9b..c1fc5e645b 100644 --- a/crates/native-sidecar/tests/service.rs +++ b/crates/native-sidecar/tests/service.rs @@ -2209,7 +2209,7 @@ ykAheWCsAteSEWVc0w==\n\ OwnershipScope::vm(connection_id, session_id, vm_id), RequestPayload::ConfigureVm(ConfigureVmRequest { mounts: vec![MountDescriptor { - guest_path: String::from("/__secure_exec/commands/0"), + guest_path: String::from("/__agentos/commands/0"), guest_source: String::from("agentos"), guest_fstype: String::from("agentos"), read_only: true, @@ -3338,7 +3338,7 @@ console.log(JSON.stringify({ status: "ok", summary })); ), fixture_dns_record( "bundle.example.test.", - RData::TXT(TXT::new(vec![String::from("secure-exec")])), + RData::TXT(TXT::new(vec![String::from("agentos")])), ), ], ("bundle.example.test.", RecordType::ANY) => vec![ @@ -9556,7 +9556,7 @@ console.log(JSON.stringify({ status: "ok", summary })); .expect("clock should be monotonic") .as_nanos(); let metadata_path = - std::env::temp_dir().join(format!("secure-exec-service-s3-{unique}.sqlite")); + std::env::temp_dir().join(format!("agentos-service-s3-{unique}.sqlite")); let mut sidecar = create_test_sidecar(); let (connection_id, session_id) = @@ -11304,7 +11304,7 @@ console.log(JSON.stringify({ status: "ok", summary })); OwnershipScope::vm(&connection_id, &session_id, &vm_id), RequestPayload::ConfigureVm(ConfigureVmRequest { mounts: vec![MountDescriptor { - guest_path: String::from("/__secure_exec/commands/0"), + guest_path: String::from("/__agentos/commands/0"), guest_source: String::from("agentos"), guest_fstype: String::from("agentos"), read_only: true, @@ -11406,7 +11406,7 @@ console.log(JSON.stringify({ status: "ok", summary })); OwnershipScope::vm(&connection_id, &session_id, &vm_id), RequestPayload::ConfigureVm(ConfigureVmRequest { mounts: vec![MountDescriptor { - guest_path: String::from("/__secure_exec/commands/0"), + guest_path: String::from("/__agentos/commands/0"), guest_source: String::from("agentos"), guest_fstype: String::from("agentos"), read_only: true, @@ -11804,7 +11804,7 @@ console.log(JSON.stringify({ status: "ok", summary })); OwnershipScope::vm(&connection_id, &session_id, &vm_id), RequestPayload::ConfigureVm(ConfigureVmRequest { mounts: vec![MountDescriptor { - guest_path: String::from("/__secure_exec/commands/0"), + guest_path: String::from("/__agentos/commands/0"), guest_source: String::from("agentos"), guest_fstype: String::from("agentos"), read_only: true, @@ -11841,11 +11841,11 @@ console.log(JSON.stringify({ status: "ok", summary })); assert!( path_entries .first() - .is_some_and(|entry| *entry == "/__secure_exec/commands/0"), + .is_some_and(|entry| *entry == "/__agentos/commands/0"), "PATH should prioritize mounted command root: {path}" ); assert!( - path_entries.contains(&"/__secure_exec/commands/0"), + path_entries.contains(&"/__agentos/commands/0"), "PATH should include mounted command root: {path}" ); @@ -13512,7 +13512,7 @@ process.stdout.write(`${JSON.stringify(snapshot)}\n`); &vm_id, "proc-js-binding-rpc", crate::protocol::JavascriptChildProcessSpawnRequest { - command: String::from("/__secure_exec/commands/0/agentos-math"), + command: String::from("/__agentos/commands/0/agentos-math"), args: vec![ String::from("add"), String::from("--a"), @@ -13566,7 +13566,7 @@ process.stdout.write(`${JSON.stringify(snapshot)}\n`); &vm.guest_cwd, &vm.host_cwd, &crate::protocol::JavascriptChildProcessSpawnRequest { - command: String::from("/__secure_exec/commands/0/agentos-math"), + command: String::from("/__agentos/commands/0/agentos-math"), args: vec![ String::from("add"), String::from("--a"), @@ -17505,7 +17505,7 @@ await new Promise(() => {}); json!("aes-256-gcm"), json!(base64::engine::general_purpose::STANDARD.encode([7_u8; 32])), json!(base64::engine::general_purpose::STANDARD.encode([3_u8; 12])), - json!(base64::engine::general_purpose::STANDARD.encode(b"secure-exec")), + json!(base64::engine::general_purpose::STANDARD.encode(b"agentos")), json!(r#"{"aad":"YWR2YW5jZWQ=","authTagLength":16}"#), ], }, @@ -17535,7 +17535,7 @@ await new Promise(() => {}); .expect("decipheriv response"); assert_eq!( decode_base64(decipher_response.as_str().expect("decipher response")), - b"secure-exec" + b"agentos" ); let mut streaming_process = create_crypto_test_process(); @@ -18986,7 +18986,7 @@ console.log(JSON.stringify({ membershipAddress, sourceAddress, reboundAddress, d r#" import net from "node:net"; -const path = "/tmp/secure-exec-unix-echo.sock"; +const path = "/tmp/agentos-unix-echo.sock"; const summary = await new Promise((resolve, reject) => { const server = net.createServer((socket) => { socket.setEncoding("utf8"); @@ -23755,7 +23755,7 @@ console.log(`BODY:${{body}}`); sidecar.vms.get(&vm_id).expect("javascript vm"), ) .expect("build Unix socket path context"); - let socket_path = "/tmp/secure-exec.sock"; + let socket_path = "/tmp/agentos.sock"; let listen = { let vm = sidecar.vms.get_mut(&vm_id).expect("javascript vm"); @@ -24157,7 +24157,7 @@ console.log(`BODY:${{body}}`); 19_u64, "net.connect", vec![json!({ "path": socket_path })], - "unix:/tmp/secure-exec.sock", + "unix:/tmp/agentos.sock", ), ( 20_u64, @@ -24968,7 +24968,7 @@ try { ), ( String::from("AGENTOS_VIRTUAL_OS_HOSTNAME"), - String::from("secure-exec-test"), + String::from("agentos-test"), ), ( String::from("AGENTOS_PARENT_NODE_ALLOW_CHILD_PROCESS"), @@ -24998,7 +24998,7 @@ try { ); assert_eq!( filtered.get("AGENTOS_VIRTUAL_OS_HOSTNAME"), - Some(&String::from("secure-exec-test")) + Some(&String::from("agentos-test")) ); assert!(!filtered.contains_key("AGENTOS_PARENT_NODE_ALLOW_CHILD_PROCESS")); assert!(!filtered.contains_key("VISIBLE_MARKER")); diff --git a/crates/native-sidecar/tests/xfstests_correctness.rs b/crates/native-sidecar/tests/xfstests_correctness.rs index 175fcdf938..a652a2da52 100644 --- a/crates/native-sidecar/tests/xfstests_correctness.rs +++ b/crates/native-sidecar/tests/xfstests_correctness.rs @@ -467,14 +467,14 @@ fn configure_verification_mounts( vm_id, vec![ host_dir_mount( - "/__secure_exec/commands/0", + "/__agentos/commands/0", &command_root("coreutils"), true, ), - host_dir_mount("/__secure_exec/commands/1", &c_probe_root(), true), - host_dir_mount("/__secure_exec/commands/2", &command_root("attr"), true), - host_dir_mount("/__secure_exec/commands/3", &command_root("acl"), true), - host_dir_mount("/__secure_exec/commands/4", &command_root("sed"), true), + host_dir_mount("/__agentos/commands/1", &c_probe_root(), true), + host_dir_mount("/__agentos/commands/2", &command_root("attr"), true), + host_dir_mount("/__agentos/commands/3", &command_root("acl"), true), + host_dir_mount("/__agentos/commands/4", &command_root("sed"), true), xfstests_backend_mount( backend, "/mnt/test", @@ -3726,7 +3726,7 @@ fn xfstests_wasi_fifo_open_routes_to_kernel_pipe() { let vm_id = create_xfstests_vm_wire(&mut sidecar, 3, &connection_id, &session_id, &cwd); let mut mounts = xfstests_mounts(&source, root.path(), XFSTESTS_BACKEND, None); mounts.push(host_dir_mount( - &format!("/__secure_exec/commands/{}", COMMAND_PACKAGES.len()), + &format!("/__agentos/commands/{}", COMMAND_PACKAGES.len()), &c_probe_root(), true, )); @@ -3855,7 +3855,7 @@ fn xfstests_mknod_creates_a_working_null_device() { let vm_id = create_xfstests_vm_wire(&mut sidecar, 3, &connection_id, &session_id, &cwd); let mut mounts = xfstests_mounts(&source, root.path(), XFSTESTS_BACKEND, None); mounts.push(host_dir_mount( - &format!("/__secure_exec/commands/{}", COMMAND_PACKAGES.len()), + &format!("/__agentos/commands/{}", COMMAND_PACKAGES.len()), &c_probe_root(), true, )); @@ -4500,7 +4500,7 @@ fn xfstests_mounts( .enumerate() .map(|(index, package)| { host_dir_mount( - &format!("/__secure_exec/commands/{index}"), + &format!("/__agentos/commands/{index}"), &command_root(package), true, ) @@ -4889,7 +4889,7 @@ printf 'parent-commands-ok\\n'" &vm_id, filesystem_request( GuestFilesystemOperation::Exists, - "/__secure_exec/commands/2/rm", + "/__agentos/commands/2/rm", ), ) .exists; @@ -5048,7 +5048,7 @@ fn xfstests_wasi_waitpid_options_and_status() { let vm_id = create_xfstests_vm_wire(&mut sidecar, 3, &connection_id, &session_id, &cwd); let mut mounts = xfstests_mounts(&source, root.path(), XFSTESTS_BACKEND, None); mounts.push(host_dir_mount( - &format!("/__secure_exec/commands/{}", COMMAND_PACKAGES.len()), + &format!("/__agentos/commands/{}", COMMAND_PACKAGES.len()), &c_probe_root(), true, )); @@ -5107,7 +5107,7 @@ fn xfstests_wasi_self_stop_and_parent_continue() { let vm_id = create_xfstests_vm_wire(&mut sidecar, 3, &connection_id, &session_id, &cwd); let mut mounts = xfstests_mounts(&source, root.path(), XFSTESTS_BACKEND, None); mounts.push(host_dir_mount( - &format!("/__secure_exec/commands/{}", COMMAND_PACKAGES.len()), + &format!("/__agentos/commands/{}", COMMAND_PACKAGES.len()), &c_probe_root(), true, )); @@ -5422,7 +5422,7 @@ fn xfstests_truncfile_scaled_throughput_regression() { let vm_id = create_xfstests_vm_wire(&mut sidecar, 3, &connection_id, &session_id, &cwd); let mut mounts = xfstests_mounts(&source, root.path(), &backend, s3_endpoint); mounts.push(host_dir_mount( - &format!("/__secure_exec/commands/{}", COMMAND_PACKAGES.len()), + &format!("/__agentos/commands/{}", COMMAND_PACKAGES.len()), &source.join("src"), true, )); @@ -5507,7 +5507,7 @@ fn xfstests_wasi_helper_ports() { let vm_id = create_xfstests_vm_wire(&mut sidecar, 3, &connection_id, &session_id, &cwd); let mut mounts = xfstests_mounts(&source, root.path(), XFSTESTS_BACKEND, None); mounts.push(host_dir_mount( - &format!("/__secure_exec/commands/{}", COMMAND_PACKAGES.len()), + &format!("/__agentos/commands/{}", COMMAND_PACKAGES.len()), &c_probe_root(), true, )); diff --git a/crates/sidecar-client/CLAUDE.md b/crates/sidecar-client/CLAUDE.md index 037e9b94a2..402e15f2e9 100644 --- a/crates/sidecar-client/CLAUDE.md +++ b/crates/sidecar-client/CLAUDE.md @@ -4,4 +4,4 @@ See `../CLAUDE.md` for crate-wide runtime and testing rules. - Keep this crate Agent OS-agnostic: no `agentos-protocol`, `agentos-client`, `agentos-sidecar`, ACP, agents, sessions, or binding semantics. - The generic transport resolves `AGENTOS_SIDECAR_BIN` / `agentos-native-sidecar`; product wrappers such as Agent OS must resolve their own wrapper binary and pass it explicitly. -- Expose raw secure-exec wire types and transport primitives only; ergonomic product facades belong in product-specific client crates. +- Expose raw agentos wire types and transport primitives only; ergonomic product facades belong in product-specific client crates. diff --git a/crates/sidecar-client/Cargo.toml b/crates/sidecar-client/Cargo.toml index 9f7e17a230..0c2c489204 100644 --- a/crates/sidecar-client/Cargo.toml +++ b/crates/sidecar-client/Cargo.toml @@ -4,7 +4,7 @@ version.workspace = true edition.workspace = true license.workspace = true repository.workspace = true -description = "Rust client transport for the Secure Exec native sidecar" +description = "Rust client transport for the Agent OS Exec native sidecar" [dependencies] agentos-sidecar-protocol = { workspace = true } diff --git a/crates/sidecar-client/src/lib.rs b/crates/sidecar-client/src/lib.rs index 4da4ab71fe..6188a1bdd3 100644 --- a/crates/sidecar-client/src/lib.rs +++ b/crates/sidecar-client/src/lib.rs @@ -1,8 +1,8 @@ #![forbid(unsafe_code)] -//! Low-level Rust client transport for the Secure Exec native sidecar. +//! Low-level Rust client transport for the Agent OS Exec native sidecar. //! -//! This crate owns the framed stdio transport and exposes the generated Secure Exec wire protocol. +//! This crate owns the framed stdio transport and exposes the generated Agent OS Exec wire protocol. //! Higher level products layer their own authentication, extension payloads, and //! typed API surfaces on top of this transport. diff --git a/crates/sidecar-client/src/transport.rs b/crates/sidecar-client/src/transport.rs index b2ee2c715a..9f248181bc 100644 --- a/crates/sidecar-client/src/transport.rs +++ b/crates/sidecar-client/src/transport.rs @@ -660,7 +660,7 @@ mod tests { } #[test] - fn binary_path_uses_secure_exec_env_fallback() { + fn binary_path_uses_agentos_env_fallback() { let _guard = ENV_LOCK.lock().expect("env lock"); let previous = std::env::var(SIDECAR_BIN_ENV).ok(); std::env::set_var(SIDECAR_BIN_ENV, "/tmp/agentos-native-sidecar"); diff --git a/crates/sidecar-client/src/wire.rs b/crates/sidecar-client/src/wire.rs index 73505b95ad..4107c2f2d9 100644 --- a/crates/sidecar-client/src/wire.rs +++ b/crates/sidecar-client/src/wire.rs @@ -1,3 +1,3 @@ -//! Raw generated Secure Exec sidecar protocol types and BARE frame helpers. +//! Raw generated Agent OS Exec sidecar protocol types and BARE frame helpers. pub use agentos_sidecar_protocol::wire::*; diff --git a/crates/sidecar-protocol/Cargo.toml b/crates/sidecar-protocol/Cargo.toml index 3bb07d4dca..9253e4c383 100644 --- a/crates/sidecar-protocol/Cargo.toml +++ b/crates/sidecar-protocol/Cargo.toml @@ -4,7 +4,7 @@ version.workspace = true edition.workspace = true license.workspace = true repository.workspace = true -description = "Shared Secure Exec sidecar wire protocol and frame helpers" +description = "Shared Agent OS Exec sidecar wire protocol and frame helpers" [lib] name = "agentos_sidecar_protocol" diff --git a/crates/sidecar-protocol/protocol/agentos_sidecar_v1.bare b/crates/sidecar-protocol/protocol/agentos_sidecar_v1.bare index 315ecd9ad1..c2fcd08634 100644 --- a/crates/sidecar-protocol/protocol/agentos_sidecar_v1.bare +++ b/crates/sidecar-protocol/protocol/agentos_sidecar_v1.bare @@ -1,4 +1,4 @@ -# Secure Exec sidecar protocol schema, version 1. +# Agent OS Exec sidecar protocol schema, version 1. # This schema is generator-ready: numeric ordinals are intentionally omitted # and type blocks are ordered before first use. diff --git a/crates/sidecar-protocol/src/lib.rs b/crates/sidecar-protocol/src/lib.rs index 7929ac0511..be578b51a4 100644 --- a/crates/sidecar-protocol/src/lib.rs +++ b/crates/sidecar-protocol/src/lib.rs @@ -3,7 +3,7 @@ // payload variants); boxing them is a wire-adjacent refactor tracked separately. #![allow(clippy::large_enum_variant, clippy::result_large_err)] -//! Shared Secure Exec sidecar wire protocol surface. +//! Shared Agent OS Exec sidecar wire protocol surface. pub mod generated_protocol; pub mod protocol; diff --git a/crates/sidecar-protocol/src/wire.rs b/crates/sidecar-protocol/src/wire.rs index 61e2620560..30c5d2ce12 100644 --- a/crates/sidecar-protocol/src/wire.rs +++ b/crates/sidecar-protocol/src/wire.rs @@ -1,4 +1,4 @@ -//! Generated Secure Exec sidecar wire protocol surface. +//! Generated Agent OS Exec sidecar wire protocol surface. //! //! This module is the public generated protocol entrypoint. The hand-written //! `protocol` module remains an internal compatibility layer while callers move diff --git a/crates/v8-runtime/Cargo.toml b/crates/v8-runtime/Cargo.toml index 08e10dfee2..7d592de2ee 100644 --- a/crates/v8-runtime/Cargo.toml +++ b/crates/v8-runtime/Cargo.toml @@ -4,7 +4,7 @@ version.workspace = true edition.workspace = true license.workspace = true repository.workspace = true -description = "V8 isolate runtime for secure-exec guest JavaScript execution" +description = "V8 isolate runtime for agentos guest JavaScript execution" [features] test-support = [] diff --git a/crates/v8-runtime/npm/.gitignore b/crates/v8-runtime/npm/.gitignore index c37406f79d..d460955880 100644 --- a/crates/v8-runtime/npm/.gitignore +++ b/crates/v8-runtime/npm/.gitignore @@ -1,3 +1,3 @@ # Platform binaries are placed here by CI, not committed -*/secure-exec-v8 -*/secure-exec-v8.exe +*/agentos-v8 +*/agentos-v8.exe diff --git a/crates/v8-runtime/npm/linux-x64-gnu/README.md b/crates/v8-runtime/npm/linux-x64-gnu/README.md index 50fa0499ff..ca07d3d011 100644 --- a/crates/v8-runtime/npm/linux-x64-gnu/README.md +++ b/crates/v8-runtime/npm/linux-x64-gnu/README.md @@ -4,6 +4,6 @@ Linux x64 (glibc) binary for @rivet-dev/agentos-v8-runtime. This package is installed automatically by `@rivet-dev/agentos-v8-runtime` as a platform-specific optional dependency. -- Website: https://secureexec.dev -- Docs: https://secureexec.dev/docs -- GitHub: https://github.com/rivet-dev/secure-exec +- Website: https://agentos.dev +- Docs: https://agentos.dev/docs +- GitHub: https://github.com/rivet-dev/agentos diff --git a/crates/v8-runtime/src/bridge.rs b/crates/v8-runtime/src/bridge.rs index 9ec869c662..2f46e12228 100644 --- a/crates/v8-runtime/src/bridge.rs +++ b/crates/v8-runtime/src/bridge.rs @@ -2319,7 +2319,7 @@ mod tests { } #[test] - fn bridge_error_code_accepts_trusted_secure_exec_prefixes() { + fn bridge_error_code_accepts_trusted_agentos_prefixes() { assert_eq!( bridge_error_code("ERR_AGENTOS_NODE_SYNC_RPC: EACCES: permission denied on /foo"), Some("EACCES") diff --git a/crates/v8-runtime/src/execution.rs b/crates/v8-runtime/src/execution.rs index 24c1c03f8c..299d72129a 100644 --- a/crates/v8-runtime/src/execution.rs +++ b/crates/v8-runtime/src/execution.rs @@ -116,7 +116,7 @@ pub fn install_high_resolution_time_global(scope: &mut v8::HandleScope, origin: let Some(func) = template.get_function(scope) else { return; }; - let key = v8::String::new(scope, "__secureExecHrNowUs").unwrap(); + let key = v8::String::new(scope, "__agentOsHrNowUs").unwrap(); let attr = v8::PropertyAttribute::READ_ONLY | v8::PropertyAttribute::DONT_DELETE; global.define_own_property(scope, key.into(), func.into(), attr); } @@ -128,7 +128,7 @@ pub fn install_require_esm_sync_global(scope: &mut v8::HandleScope) { let Some(function) = template.get_function(scope) else { return; }; - let key = v8::String::new(scope, "__secureExecRequireEsmSync").unwrap(); + let key = v8::String::new(scope, "__agentOsRequireEsmSync").unwrap(); let attributes = v8::PropertyAttribute::READ_ONLY | v8::PropertyAttribute::DONT_DELETE; global.define_own_property(scope, key.into(), function.into(), attributes); } diff --git a/crates/v8-runtime/src/session.rs b/crates/v8-runtime/src/session.rs index 91ad64dd65..781f22bac2 100644 --- a/crates/v8-runtime/src/session.rs +++ b/crates/v8-runtime/src/session.rs @@ -832,7 +832,7 @@ fn spawn_warm_worker( let worker_userland_code = userland_code.clone(); // AGENTOS_THREAD_SITE: bounded-v8-warm-worker let join_handle = match thread::Builder::new() - .name(String::from("secure-exec-v8-warm-worker")) + .name(String::from("agentos-v8-warm-worker")) .spawn(move || { let precreated = precreate_warm_isolate( snapshot_cache, @@ -934,7 +934,7 @@ fn precreate_warm_isolate( /// Normalize an opt-in CPU-time budget: `Some(0)` means "disabled" and folds to /// `None` so the CPU-budget watchdog is NOT armed. The runtime layer does not -/// invent a default here: secure-exec sidecar VM executions pass the typed +/// invent a default here: agentos sidecar VM executions pass the typed /// `limits.jsRuntime.cpuTimeLimitMs` default, while lower-level callers can pass /// `None`/`0` deliberately. fn normalize_cpu_time_limit_ms(cpu_time_limit_ms: Option) -> Option { diff --git a/crates/v8-runtime/src/snapshot.rs b/crates/v8-runtime/src/snapshot.rs index 2df4e3b4eb..bafe92aa17 100644 --- a/crates/v8-runtime/src/snapshot.rs +++ b/crates/v8-runtime/src/snapshot.rs @@ -87,9 +87,9 @@ const SNAPSHOT_USERLAND_PREP: &str = r#" // snapshot eval; it also works post-restore (resolution flows through the real // bridge fns swapped in after restore). if (typeof globalThis.require === "undefined" && - typeof globalThis.__secureExecGuestCreateRequire === "function") { + typeof globalThis.__agentOsGuestCreateRequire === "function") { try { - globalThis.require = globalThis.__secureExecGuestCreateRequire("/root/index.js"); + globalThis.require = globalThis.__agentOsGuestCreateRequire("/root/index.js"); } catch (e) {} } // `process.versions` is a bridge-backed lazy getter: it derives `.node` from the diff --git a/crates/v8-runtime/src/stream.rs b/crates/v8-runtime/src/stream.rs index 596e034f7c..aeffefbfda 100644 --- a/crates/v8-runtime/src/stream.rs +++ b/crates/v8-runtime/src/stream.rs @@ -10,7 +10,7 @@ /// - "http2" → _http2Dispatch /// - "stdin", "stdin_end" → _stdinDispatch /// - "net_socket" → _netSocketDispatch -/// - "signal" → __secureExecWasmSignalDispatch or _signalDispatch +/// - "signal" → __agentOsWasmSignalDispatch or _signalDispatch /// - "timer" → _timerDispatch pub fn dispatch_stream_event(scope: &mut v8::HandleScope, event_type: &str, payload: &[u8]) { // Look up the dispatch function on the global object @@ -23,7 +23,7 @@ pub fn dispatch_stream_event(scope: &mut v8::HandleScope, event_type: &str, payl "http2" => &["_http2Dispatch"], "stdin" | "stdin_end" => &["_stdinDispatch"], "net_socket" => &["_netSocketDispatch"], - "signal" => &["__secureExecWasmSignalDispatch", "_signalDispatch"], + "signal" => &["__agentOsWasmSignalDispatch", "_signalDispatch"], "timer" => &["_timerDispatch"], _ => return, // Unknown event type — ignore }; @@ -94,7 +94,7 @@ fn dispatch_stream_value( let context = scope.get_current_context(); let global = context.global(scope); let dispatch_names: &[&str] = match event_type { - "signal" => &["__secureExecWasmSignalDispatch", "_signalDispatch"], + "signal" => &["__agentOsWasmSignalDispatch", "_signalDispatch"], "timer" => &["_timerDispatch"], _ => return, }; diff --git a/crates/v8-runtime/src/timeout.rs b/crates/v8-runtime/src/timeout.rs index ebacaee9d7..7e25814a1a 100644 --- a/crates/v8-runtime/src/timeout.rs +++ b/crates/v8-runtime/src/timeout.rs @@ -15,7 +15,7 @@ // EXCLUDES idle/await. V8 has no native budget primitive, so this poll + // `terminate_execution()` approach is the standard embedder pattern. Armed // when the caller passes a nonzero `limits.jsRuntime.cpuTimeLimitMs`. -// secure-exec sidecar VM executions supply a bounded default; lower-level +// agentos sidecar VM executions supply a bounded default; lower-level // embedders may pass `None`/`0` to leave the guard disabled. // // The two guards are independent: setting one typed limit arms only that guard, diff --git a/crates/vfs-store/CLAUDE.md b/crates/vfs-store/CLAUDE.md index 4d830a1f02..9808ec0129 100644 --- a/crates/vfs-store/CLAUDE.md +++ b/crates/vfs-store/CLAUDE.md @@ -1,5 +1,5 @@ # agentos-vfs -- `agentos-vfs` contains concrete backend adapters for secure-exec deployments: S3, host-disk metadata/block stores, and bridge/callback-backed stores. +- `agentos-vfs` contains concrete backend adapters for agentos deployments: S3, host-disk metadata/block stores, and bridge/callback-backed stores. - Keep policy decisions, trusted configuration validation, mount descriptor parsing, and sidecar lifecycle wiring in the sidecar plugin layer. - Generic filesystem algorithms and in-memory stores belong in `vfs`. diff --git a/crates/vfs-store/Cargo.toml b/crates/vfs-store/Cargo.toml index 3252ceedd4..11d5da0582 100644 --- a/crates/vfs-store/Cargo.toml +++ b/crates/vfs-store/Cargo.toml @@ -4,7 +4,7 @@ version.workspace = true edition.workspace = true license.workspace = true repository.workspace = true -description = "Secure Exec virtual filesystem backends" +description = "Agent OS Exec virtual filesystem backends" [dependencies] async-trait = "0.1" diff --git a/crates/vfs-store/src/callback_store.rs b/crates/vfs-store/src/callback_store.rs index a3de96a573..674ba501bc 100644 --- a/crates/vfs-store/src/callback_store.rs +++ b/crates/vfs-store/src/callback_store.rs @@ -7,7 +7,7 @@ use vfs::engine::{ MetadataStore, SnapshotId, VfsError, VfsResult, }; -pub const VFS_METADATA_EXT_NAMESPACE: &str = "secure-exec.vfs.metadata.v1"; +pub const VFS_METADATA_EXT_NAMESPACE: &str = "agentos.vfs.metadata.v1"; const CALLBACK_METADATA_TIMEOUT: Duration = Duration::from_secs(30); pub trait CallbackMetadataClient: Clone + Send + Sync + 'static { diff --git a/crates/vfs/CLAUDE.md b/crates/vfs/CLAUDE.md index 4cccd1bb89..2a99a33d70 100644 --- a/crates/vfs/CLAUDE.md +++ b/crates/vfs/CLAUDE.md @@ -1,6 +1,6 @@ # vfs -- `vfs` is generic filesystem infrastructure only. Do not add secure-exec sidecar, bridge, S3, SQLite, host-disk, or registry coupling here. +- `vfs` is generic filesystem infrastructure only. Do not add agentos sidecar, bridge, S3, SQLite, host-disk, or registry coupling here. - The crate intentionally contains separate filesystem type universes under explicit modules while the consolidation is in progress. Do not glob-merge names that would confuse those boundaries. - Concrete environment-bound backends belong in `agentos-vfs`. - The `chunked` engine deliberately decouples the `MetadataStore` from the `BlockStore`: blocks are content-addressed, opaque, and self-describing only as a set, while the directory tree, inode table, chunk map, and refcounts live entirely in the metadata store. The engine makes **no self-containment promise** about either half. Pairing a block store with a metadata store, and ensuring the metadata store is durable and co-located with whatever lifecycle the blocks need, is the **caller's responsibility** (the sidecar plugin / client config that wires the backends), not the engine's. So e.g. an `S3BlockStore` backed by a local `SqliteMetadataStore` is a valid, intended configuration; the engine does not assume blocks carry enough information to reconstruct the tree, and "the metadata lives elsewhere than the blocks" is by design, not a defect. If a deployment needs the tree to survive loss of the local metadata, it must choose a durable metadata store (e.g. the callback backend) — that is a wiring decision, not an engine concern. diff --git a/crates/vfs/assets/base-filesystem.json b/crates/vfs/assets/base-filesystem.json index e641efddd3..bdb7b06ec7 100644 --- a/crates/vfs/assets/base-filesystem.json +++ b/crates/vfs/assets/base-filesystem.json @@ -5,8 +5,8 @@ "snapshotCreatedAt": "2026-06-22T19:45:20.529Z", "builtAt": "2026-06-23T03:47:12.644Z", "transforms": [ - "Normalize HOSTNAME to secure-exec", - "Preserve the captured user-level environment and filesystem layout as the secure-exec base layer", + "Normalize HOSTNAME to agentos", + "Preserve the captured user-level environment and filesystem layout as the agentos base layer", "Add the non-Alpine /workspace directory (default agent working directory) owned by the base user", "Restore Alpine 3.22's /etc/services database and add the VM's Docker-style /etc/hosts entries for libc lookup parity" ] @@ -15,7 +15,7 @@ "env": { "CHARSET": "UTF-8", "HOME": "/home/agentos", - "HOSTNAME": "secure-exec", + "HOSTNAME": "agentos", "LANG": "C.UTF-8", "LC_COLLATE": "C", "LOGNAME": "agentos", @@ -92,7 +92,7 @@ "mode": "644", "uid": 0, "gid": 0, - "content": "secure-exec\n" + "content": "agentos\n" }, { "path": "/etc/hosts", @@ -100,7 +100,7 @@ "mode": "644", "uid": 0, "gid": 0, - "content": "127.0.0.1 localhost localhost.localdomain\n::1 localhost localhost.localdomain ip6-localhost ip6-loopback\nfe00:: ip6-localnet\nff00:: ip6-mcastprefix\nff02::1 ip6-allnodes\nff02::2 ip6-allrouters\n127.0.1.1 secure-exec\n" + "content": "127.0.0.1 localhost localhost.localdomain\n::1 localhost localhost.localdomain ip6-localhost ip6-loopback\nfe00:: ip6-localnet\nff00:: ip6-mcastprefix\nff02::1 ip6-allnodes\nff02::2 ip6-allrouters\n127.0.1.1 agentos\n" }, { "path": "/etc/logrotate.d", diff --git a/crates/vfs/src/posix/overlay_fs.rs b/crates/vfs/src/posix/overlay_fs.rs index 362975cfbb..c032828f09 100644 --- a/crates/vfs/src/posix/overlay_fs.rs +++ b/crates/vfs/src/posix/overlay_fs.rs @@ -6,9 +6,9 @@ use base64::Engine; use std::collections::BTreeSet; const MAX_SNAPSHOT_DEPTH: usize = 1024; -const OVERLAY_METADATA_ROOT: &str = "/.secure-exec-overlay"; -const OVERLAY_WHITEOUT_DIR: &str = "/.secure-exec-overlay/whiteouts"; -const OVERLAY_OPAQUE_DIR: &str = "/.secure-exec-overlay/opaque"; +const OVERLAY_METADATA_ROOT: &str = "/.agentos-overlay"; +const OVERLAY_WHITEOUT_DIR: &str = "/.agentos-overlay/whiteouts"; +const OVERLAY_OPAQUE_DIR: &str = "/.agentos-overlay/opaque"; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum OverlayMode { @@ -304,7 +304,7 @@ impl OverlayFileSystem { /// /// The lexical [`is_internal_metadata_path`] check alone is bypassable: the /// underlying `MemoryFileSystem` follows symlinks, so a guest-created symlink - /// whose resolved target enters `/.secure-exec-overlay` (directly, or via a + /// whose resolved target enters `/.agentos-overlay` (directly, or via a /// symlink to an ancestor such as `/`) would slip past a purely lexical guard /// and let the guest read or tamper with whiteout/opaque markers (e.g. /// resurrecting a deleted lower-layer file). Resolving before the check @@ -334,7 +334,7 @@ impl OverlayFileSystem { } fn hidden_root_entry_name() -> &'static str { - ".secure-exec-overlay" + ".agentos-overlay" } fn should_hide_directory_entry(path: &str, entry: &str) -> bool { @@ -2165,7 +2165,7 @@ mod tests { // A guest symlink whose target is the metadata root must not become a // window into the reserved namespace. overlay - .symlink("/.secure-exec-overlay/whiteouts", "/escape") + .symlink("/.agentos-overlay/whiteouts", "/escape") .expect("creating the symlink itself is allowed"); // Listing through the symlink must be denied, not disclose markers. @@ -2191,7 +2191,7 @@ mod tests { .expect("symlink to root is allowed"); assert!( overlay - .read_dir("/rootlink/.secure-exec-overlay/whiteouts") + .read_dir("/rootlink/.agentos-overlay/whiteouts") .is_err(), "metadata must be unreachable via an ancestor symlink too" ); @@ -2259,7 +2259,7 @@ mod tests { let root_entries = overlay.read_dir("/").expect("read root"); assert!(!root_entries .iter() - .any(|entry| entry == ".secure-exec-overlay")); + .any(|entry| entry == ".agentos-overlay")); } #[test] diff --git a/crates/vfs/src/posix/root_fs.rs b/crates/vfs/src/posix/root_fs.rs index 78c93523f4..a165a9ee54 100644 --- a/crates/vfs/src/posix/root_fs.rs +++ b/crates/vfs/src/posix/root_fs.rs @@ -12,12 +12,12 @@ use serde::Deserialize; use std::collections::BTreeSet; // The base filesystem fixture is staged into OUT_DIR by build.rs: copied from -// the canonical `packages/secure-exec-core/fixtures/base-filesystem.json` +// the canonical `packages/agentos-core/fixtures/base-filesystem.json` // during in-tree builds, or from the vendored `assets/base-filesystem.json` // copy bundled in the published crate. const BUNDLED_BASE_FILESYSTEM_JSON: &str = include_str!(concat!(env!("OUT_DIR"), "/base-filesystem.json")); -pub const ROOT_FILESYSTEM_SNAPSHOT_FORMAT: &str = "secure_exec_filesystem_snapshot_v1"; +pub const ROOT_FILESYSTEM_SNAPSHOT_FORMAT: &str = "agentos_filesystem_snapshot_v1"; const LEGACY_AGENTOS_ROOT_FILESYSTEM_SNAPSHOT_FORMAT: &str = "agentos_filesystem_snapshot_v1"; const ROOT_FILESYSTEM_SNAPSHOT_FIXED_OVERHEAD_BYTES: usize = 4 * 1024; const ROOT_FILESYSTEM_SNAPSHOT_ENTRY_OVERHEAD_BYTES: usize = MAX_PATH_LENGTH + 1024; diff --git a/crates/vfs/tests/package_format.rs b/crates/vfs/tests/package_format.rs index efadeea70e..31c670e774 100644 --- a/crates/vfs/tests/package_format.rs +++ b/crates/vfs/tests/package_format.rs @@ -97,7 +97,7 @@ fn package_format_rejects_unknown_schema_version_and_corrupt_headers() { #[test] fn tar_filesystem_rejects_unsorted_index() { - let path = unique_path("secure-exec-unsorted-aospkg"); + let path = unique_path("agentos-unsorted-aospkg"); let manifest = encode_package_manifest(v1::PackageManifest { name: String::from("unsorted"), version: String::from("1.0.0"), diff --git a/crates/vfs/tests/posix_root_fs.rs b/crates/vfs/tests/posix_root_fs.rs index 26af4db923..6bab39a9e3 100644 --- a/crates/vfs/tests/posix_root_fs.rs +++ b/crates/vfs/tests/posix_root_fs.rs @@ -304,7 +304,7 @@ fn root_filesystem_uses_bundled_base_and_round_trips_snapshots() { .any(|window| window == b"smtp\t\t25/tcp\t\tmail")); assert_eq!( root.read_file("/etc/hosts").expect("read bundled hosts file"), - b"127.0.0.1 localhost localhost.localdomain\n::1 localhost localhost.localdomain ip6-localhost ip6-loopback\nfe00:: ip6-localnet\nff00:: ip6-mcastprefix\nff02::1 ip6-allnodes\nff02::2 ip6-allrouters\n127.0.1.1 secure-exec\n" + b"127.0.0.1 localhost localhost.localdomain\n::1 localhost localhost.localdomain ip6-localhost ip6-loopback\nfe00:: ip6-localnet\nff00:: ip6-mcastprefix\nff02::1 ip6-allnodes\nff02::2 ip6-allrouters\n127.0.1.1 agentos\n" ); root.mkdir("/workspace", true).expect("create workspace"); @@ -503,7 +503,7 @@ fn snapshot_round_trip_preserves_file_type_bits_in_modes() { fn decode_snapshot_accepts_zero_mode_strings() { let decoded = decode_snapshot( br#"{ - "format": "secure_exec_filesystem_snapshot_v1", + "format": "agentos_filesystem_snapshot_v1", "filesystem": { "entries": [ { @@ -581,7 +581,7 @@ fn decode_snapshot_rejects_encoded_payloads_that_exceed_import_limits() { let error = decode_snapshot_with_import_limits( br#"{ - "format": "secure_exec_filesystem_snapshot_v1", + "format": "agentos_filesystem_snapshot_v1", "filesystem": { "entries": [] } }"#, &limits, @@ -601,7 +601,7 @@ fn decode_snapshot_rejects_entry_counts_that_exceed_import_limits() { let error = decode_snapshot_with_import_limits( br#"{ - "format": "secure_exec_filesystem_snapshot_v1", + "format": "agentos_filesystem_snapshot_v1", "filesystem": { "entries": [ { @@ -638,7 +638,7 @@ fn decode_snapshot_rejects_content_bytes_that_exceed_import_limits() { let error = decode_snapshot_with_import_limits( br#"{ - "format": "secure_exec_filesystem_snapshot_v1", + "format": "agentos_filesystem_snapshot_v1", "filesystem": { "entries": [ { @@ -665,7 +665,7 @@ fn decode_snapshot_allows_metadata_heavy_entries_within_import_limits() { let path = format!("/{}", "a".repeat(4000)); let snapshot = format!( r#"{{ - "format": "secure_exec_filesystem_snapshot_v1", + "format": "agentos_filesystem_snapshot_v1", "filesystem": {{ "entries": [ {{ diff --git a/crates/vfs/tests/posix_tar_fs.rs b/crates/vfs/tests/posix_tar_fs.rs index dc50551e23..daba597d75 100644 --- a/crates/vfs/tests/posix_tar_fs.rs +++ b/crates/vfs/tests/posix_tar_fs.rs @@ -101,7 +101,7 @@ fn tar_filesystem_cache_uses_file_identity_and_stable_guest_device() { assert_ne!(stat_a.dev, other_stat.dev); let same_bytes = std::fs::read(&tar_path).expect("read fixture tar"); - let copied_tar = unique_tar_path("secure-exec-tar-fs-copy"); + let copied_tar = unique_tar_path("agentos-tar-fs-copy"); std::fs::write(&copied_tar, same_bytes).expect("copy fixture tar bytes"); let fs_copy = TarFileSystem::open(&copied_tar).expect("open copied tar filesystem"); assert_ne!(fs_a.archive_ptr(), fs_copy.archive_ptr()); @@ -114,7 +114,7 @@ fn tar_filesystem_cache_uses_file_identity_and_stable_guest_device() { } fn write_fixture_tar() -> PathBuf { - let path = unique_tar_path("secure-exec-tar-fs-fixture"); + let path = unique_tar_path("agentos-tar-fs-fixture"); write_fixture_tar_at(path) } diff --git a/crates/vm-config/Cargo.toml b/crates/vm-config/Cargo.toml index bee108c954..cd60a9e866 100644 --- a/crates/vm-config/Cargo.toml +++ b/crates/vm-config/Cargo.toml @@ -4,7 +4,7 @@ version.workspace = true edition.workspace = true license.workspace = true repository.workspace = true -description = "Shared Secure Exec VM creation JSON config DTOs" +description = "Shared Agent OS Exec VM creation JSON config DTOs" [dependencies] serde = { version = "1.0", features = ["derive"] } diff --git a/docs-internal/kernel-runtime-subsystem-map.md b/docs-internal/kernel-runtime-subsystem-map.md index 40399736a1..5b8011f115 100644 --- a/docs-internal/kernel-runtime-subsystem-map.md +++ b/docs-internal/kernel-runtime-subsystem-map.md @@ -126,7 +126,7 @@ This is the baseline filesystem layer that everything else builds on. Relevant files: - `crates/kernel/src/vfs.rs` - `crates/kernel/src/root_fs.rs` -- `packages/secure-exec-core/fixtures/base-filesystem.json` +- `packages/agentos-core/fixtures/base-filesystem.json` - `crates/kernel/src/device_layer.rs` - `crates/kernel/src/overlay_fs.rs` - `crates/kernel/src/mount_table.rs` diff --git a/docs-internal/registry-flatten-colocation-spec.md b/docs-internal/registry-flatten-colocation-spec.md index b7a21b037f..227582cf5c 100644 --- a/docs-internal/registry-flatten-colocation-spec.md +++ b/docs-internal/registry-flatten-colocation-spec.md @@ -127,7 +127,7 @@ test-program fixtures stay in `toolchain/test-programs/` (not scattered into stub, or a hand-rolled CLI over a library. The only exception is a tool whose canonical upstream *is* the Rust project (`ripgrep`, `fd`). Several current commands violate this (coreutils=uutils, grep, curl driver, and the - `secureexec-*` rewrites) — tracked in `registry-parity-worklist.md` + `agentos-*` rewrites) — tracked in `registry-parity-worklist.md` Cross-cutting #0; new packages must not add more. ## What moves where @@ -325,7 +325,7 @@ Repo recipes orchestrate; they must not reimplement what the CLI does: | per-package `test` script + external authors | `agentos-toolchain test` | **Stays repo-specific** (not CLI, not overfit): `copy-wasm-commands` (vendor into -runtime-core), `verify-fixed-versions` (the 0.0.1 pin), `generate-secure-exec-mirror`, +runtime-core), `verify-fixed-versions` (the 0.0.1 pin), `generate-agentos-mirror`, registry-wide release orchestration, cross-repo dispatch, and the status reporter / coverage gate scoped to *our* registry. diff --git a/docs-internal/registry-parity-worklist.md b/docs-internal/registry-parity-worklist.md index e64c212335..deb88abcdf 100644 --- a/docs-internal/registry-parity-worklist.md +++ b/docs-internal/registry-parity-worklist.md @@ -85,7 +85,7 @@ fuel checkpoints that distinguish user CPU from user-plus-system CPU. **This is the highest-leverage item and reshapes several below.** Audit revealed that **most commands are NOT the real Linux tool** — they are custom Rust rewrites -(`secureexec-*` crates) or `uutils`, plus at least one hand-rolled C CLI (curl). +(`agentos-*` crates) or `uutils`, plus at least one hand-rolled C CLI (curl). Per the load-bearing rule, each must become the **real upstream tool** compiled to WASI and patched as needed. @@ -117,11 +117,11 @@ actual backing: | **wget** | DONE | our 174-line `wget.c` (dropped) | real GNU Wget vs our sysroot — stub `getrlimit`/`getgroups`, then build | | **http-get** | DONE | our 95-line `http_get.c` | dropped; real curl covers HTTP fetches | | **git** | DONE | our hand-rolled git from `sha1`+`flate2` | **real git** (upstream C), patched for WASI — **NOT gitoxide** | -| **fd** | DONE | our `secureexec-fd` on raw `regex` (not sharkdp/fd) | real **fd** (sharkdp) | +| **fd** | DONE | our `agentos-fd` on raw `regex` (not sharkdp/fd) | real **fd** (sharkdp) | | **findutils** (`find`,`xargs`) | DONE | our hand-rolled on `regex`/shims | replaced with `uutils/findutils` | | **tree** | DONE | our hand-rolled, zero deps | real `tree`, or an established one | -| **grep** | DONE | our `secureexec-grep` on raw `regex` (**not** an established grep pkg) | real **GNU grep** | -| **ripgrep** (`rg`) | DONE | our `secureexec-grep` recursive search shim, not real ripgrep | real upstream **ripgrep** | +| **grep** | DONE | our `agentos-grep` on raw `regex` (**not** an established grep pkg) | real **GNU grep** | +| **ripgrep** (`rg`) | DONE | our `agentos-grep` recursive search shim, not real ripgrep | real upstream **ripgrep** | | **zip** | DONE | our 203-line `zip.c` over zlib/minizip (not Info-ZIP) | real Info-ZIP, or an established lib's CLI | | **unzip** | DONE | our 669-line `unzip.c` over zlib/minizip | real Info-ZIP unzip | | **sqlite3 CLI** | DONE | our 558-line `sqlite3_cli.c` (engine is real SQLite; the shell is ours) | real SQLite `shell.c` (its official CLI) | @@ -244,7 +244,7 @@ works (`wasi-spawn` broker), so `xargs` is not a blocker. `2026-07-08T05-43-24-0700-http-get-clear-stale-generated-and-install.log`; cross-runtime network tests pass 11/11 with the WASM curl rows in `2026-07-08T05-47-43-0700-http-get-runtime-cross-network-test-pass.log`. -- **tree — DONE.** Replaced the custom Rust `secureexec-tree`/`cmd-tree` crates +- **tree — DONE.** Replaced the custom Rust `agentos-tree`/`cmd-tree` crates with upstream Steve Baker `tree` 2.3.2 from `OldManProgrammer/unix-tree`. It builds as a C toolchain command from pinned source, stages into `@agentos-software/tree`, and refreshes the tracked runtime-core fallback @@ -266,7 +266,7 @@ works (`wasi-spawn` broker), so `xargs` is not a blocker. longer includes the deleted Rust tree crates in `2026-07-08T05-33-17-0700-tree-cargo-metadata-after-removing-empty-dirs.log`. Rev: `kpmrwxln` — `fix(tree): build upstream tree`. -- **fd — DONE.** Replaced the custom Rust `secureexec-fd` regex walker with +- **fd — DONE.** Replaced the custom Rust `agentos-fd` regex walker with upstream sharkdp `fd-find` 10.4.2. Because `fd-find` is a bin-only crate, `cmd-fd` now acts as the workspace build trigger while the toolchain builds the upstream `fd` binary directly. WASI compatibility stays in dependency @@ -286,7 +286,7 @@ works (`wasi-spawn` broker), so `xargs` is not a blocker. `2026-07-08T06-25-00-0700-fd-vitest-upstream-after-dir-format.log`. Rev: `mrskpomv` — `fix(fd): build upstream fd-find`. - **grep — DONE.** Replaced the `@agentos-software/grep` package's custom - `secureexec-grep` command wrapper with upstream GNU grep 3.12 from the official + `agentos-grep` command wrapper with upstream GNU grep 3.12 from the official GNU release tarball. The real GNU `grep` binary builds through the C toolchain; `egrep` and `fgrep` are separate tiny WASM launchers that preserve GNU's upstream obsolescent scripts by spawning `grep -E` / `grep -F` through the @@ -308,10 +308,10 @@ works (`wasi-spawn` broker), so `xargs` is not a blocker. pass 8/8 in `2026-07-08T06-43-59-0700-grep-vitest-after-wrapper-cache-repair.log`. Rev: `uyukolvr` — `fix(grep): build upstream GNU grep`. - **ripgrep — DONE.** Replaced the `@agentos-software/ripgrep` package's custom - `secureexec-grep` recursive search shim with upstream ripgrep 15.1.0 from the + `agentos-grep` recursive search shim with upstream ripgrep 15.1.0 from the canonical `BurntSushi/ripgrep` crate/release. The local `cmd-rg` crate is now only a build trigger, and `toolchain/Makefile` builds ripgrep's own `rg` bin - directly. The old `secureexec-grep` library is gone. Proof: latest upstream + directly. The old `agentos-grep` library is gone. Proof: latest upstream release captured in `2026-07-08T06-50-40-0700-ripgrep-github-latest-release.json`; crate metadata captured in `2026-07-08T06-52-00-0700-ripgrep-cargo-info.log`; upstream WASM build passes in diff --git a/docs/features/typescript.mdx b/docs/features/typescript.mdx index dd4ae770ce..60546643fa 100644 --- a/docs/features/typescript.mdx +++ b/docs/features/typescript.mdx @@ -1,219 +1,40 @@ --- title: TypeScript -description: Sandboxed type checking and compilation via @rivet-dev/agentos-typescript. +description: Compile, type-check, execute, and evaluate TypeScript through @rivet-dev/agentos-javascript. icon: "code" --- -The AgentOS runtime includes a companion package -for sandboxed TypeScript tooling. `@rivet-dev/agentos-typescript` runs the TypeScript -compiler inside the sandbox runtime instead of the host process, so untrusted -compile and typecheck work stays inside the same execution boundary. - -## Runnable example - -```ts Type-Checked Execution -import { join } from "node:path"; -import { anthropic } from "@ai-sdk/anthropic"; -import { createTypeScriptTools } from "@rivet-dev/agentos-typescript"; -import { generateText, stepCountIs, tool } from "ai"; -import { - allowAll, - createInMemoryFileSystem, - createKernel, - createNodeDriver, - createNodeRuntime, - createNodeRuntimeDriverFactory, - nodeModulesMount, -} from "@rivet-dev/agentos-core"; -import { z } from "zod"; - -const filesystem = createInMemoryFileSystem(); -const systemDriver = createNodeDriver({ - filesystem, - mounts: [nodeModulesMount(join(process.cwd(), "node_modules"))], - permissions: allowAll, -}); -const runtimeDriverFactory = createNodeRuntimeDriverFactory(); -const ts = createTypeScriptTools({ - systemDriver, - runtimeDriverFactory, - memoryLimit: 256, - cpuTimeLimitMs: 5000, -}); - -const { text } = await generateText({ - model: anthropic("claude-sonnet-4-6"), - prompt: - "Write TypeScript that calculates the first 20 fibonacci numbers. Assign the result to module.exports.", - stopWhen: stepCountIs(5), - tools: { - execute_typescript: tool({ - description: - "Type-check TypeScript in a sandbox, compile it, then run the emitted JavaScript in a sandbox. Return diagnostics when validation fails.", - inputSchema: z.object({ code: z.string() }), - execute: async ({ code }) => { - const typecheck = await ts.typecheckSource({ - sourceText: code, - filePath: "/root/generated.ts", - compilerOptions: { - module: "commonjs", - target: "es2022", - }, - }); - - if (!typecheck.success) { - return { - ok: false, - stage: "typecheck", - diagnostics: typecheck.diagnostics, - }; - } - - const compiled = await ts.compileSource({ - sourceText: code, - filePath: "/root/generated.ts", - compilerOptions: { - module: "commonjs", - target: "es2022", - }, - }); - - if (!compiled.success || !compiled.outputText) { - return { - ok: false, - stage: "compile", - diagnostics: compiled.diagnostics, - }; - } - - try { - await filesystem.mkdir("/root", { recursive: true }); - await filesystem.writeFile("/root/generated.js", compiled.outputText); - const kernel = createKernel({ - filesystem, - permissions: allowAll, - syncFilesystemOnDispose: false, - }); - let stdout = ""; - let stderr = ""; - try { - await kernel.mount(createNodeRuntime()); - const child = kernel.spawn( - "node", - [ - "-e", - "const exportsValue = require('/root/generated.js'); console.log(JSON.stringify(exportsValue));", - ], - { - onStdout: (chunk) => { - stdout += Buffer.from(chunk).toString("utf8"); - }, - onStderr: (chunk) => { - stderr += Buffer.from(chunk).toString("utf8"); - }, - }, - ); - const exitCode = await child.wait(); - if (exitCode !== 0) { - throw new Error( - stderr.trim() || `sandboxed JavaScript exited ${exitCode}`, - ); - } - } finally { - await kernel.dispose(); - } - - return { - ok: true, - stage: "run", - exports: JSON.parse(stdout), - }; - } catch (error) { - return { - ok: false, - stage: "run", - errorMessage: - error instanceof Error ? error.message : String(error), - }; - } - }, - }), - }, -}); - -console.log(text); -``` - -Source: [`packages/secure-exec-example-ai-agent-type-check/src/index.ts`](../../packages/secure-exec-example-ai-agent-type-check/src/index.ts) +TypeScript is built into the JavaScript language API. There is no standalone +TypeScript package or `/typescript` subpath: create a `JavaScriptRuntime`, then +use its `typescript` property. Compilation and submitted code run in the same +AgentOS VM and share its files, mounts, permissions, limits, and lifecycle. ## Install ```bash -pnpm add @rivet-dev/agentos-core @rivet-dev/agentos-typescript typescript +pnpm add @rivet-dev/agentos-javascript ``` -## Setup - -```ts -import { join } from "node:path"; -import { createNodeDriver, createNodeRuntimeDriverFactory, nodeModulesMount } from "@rivet-dev/agentos-core"; -import { createTypeScriptTools } from "@rivet-dev/agentos-typescript"; - -const ts = createTypeScriptTools({ - systemDriver: createNodeDriver({ - mounts: [nodeModulesMount(join(process.cwd(), "node_modules"))], - }), - runtimeDriverFactory: createNodeRuntimeDriverFactory(), -}); -``` - -`nodeModulesMount` exposes the host package's `node_modules/` to the sandbox as -a read-only module tree, which lets the compiler runtime import packages like -`typescript` without copying them into the sandbox filesystem first. - -## Type-check a source string - -```ts -const result = await ts.typecheckSource({ - sourceText: "const value: string = 1;", - filePath: "/root/input.ts", -}); - -console.log(result.success); // false -console.log(result.diagnostics[0]?.message); -``` +## Runnable example -## Compile a source string + -```ts -const result = await ts.compileSource({ - sourceText: "export const value: number = 3;", - filePath: "/root/input.ts", - compilerOptions: { - module: "commonjs", - target: "es2022", - }, -}); +## API -console.log(result.outputText); -``` +The source methods are: -## Type-check or compile a project +- `runtime.typescript.check(source, options)` +- `runtime.typescript.compile(source, options)` +- `runtime.typescript.execute(source, options)` +- `runtime.typescript.evaluate(expression, options)` -```ts -await ts.typecheckProject({ cwd: "/root/project" }); -await ts.compileProject({ cwd: "/root/project" }); -``` +For projects already seeded or mounted in the VM, use +`checkProject({ cwd, tsconfigPath })` and +`compileProject({ cwd, tsconfigPath })`. -## Diagnostic shape +`check()` and `compile()` return structured diagnostics. `execute()` returns +`{ compile, execution? }`, and `evaluate()` returns +`{ compile, evaluation? }`; execution is omitted when compilation fails. -```ts -type TypeScriptDiagnostic = { - code: number; - category: "error" | "warning" | "suggestion" | "message"; - message: string; - filePath?: string; - line?: number; - column?: number; -}; -``` +See the [Agent OS Exec TypeScript guide](/docs/exec/features/typescript) and +[JavaScript and Python execution docs](/docs/exec). diff --git a/examples/agent-to-agent/package.json b/examples/agent-to-agent/package.json index f69c4001e8..6cf4cade56 100644 --- a/examples/agent-to-agent/package.json +++ b/examples/agent-to-agent/package.json @@ -7,7 +7,7 @@ "check-types": "tsc --noEmit" }, "dependencies": { - "@rivet-dev/agentos-core": "workspace:*", + "@rivet-dev/agentos": "workspace:*", "@rivet-dev/agentos-sandbox": "workspace:*", "sandbox-agent": "^0.4.2", "dockerode": "^4.0.9", diff --git a/examples/agentos-typecheck/src/index.ts b/examples/agentos-typecheck/src/index.ts index ebea84d48c..0c18cd23d9 100644 --- a/examples/agentos-typecheck/src/index.ts +++ b/examples/agentos-typecheck/src/index.ts @@ -2,7 +2,7 @@ * Type-checking example for `@rivet-dev/agentos`. * * This file exercises the public actor package surface. It is not meant to - * run: the actor delegates VM operations to the AgentOS core SDK and sidecar. + * run: the actor delegates VM operations to the AgentOS runtime and sidecar. */ import pi from "@agentos-software/pi"; diff --git a/examples/approvals/package.json b/examples/approvals/package.json index e1af4be618..95af0354e0 100644 --- a/examples/approvals/package.json +++ b/examples/approvals/package.json @@ -7,7 +7,7 @@ "check-types": "tsc --noEmit" }, "dependencies": { - "@rivet-dev/agentos-core": "workspace:*", + "@rivet-dev/agentos": "workspace:*", "@rivet-dev/agentos-sandbox": "workspace:*", "sandbox-agent": "^0.4.2", "dockerode": "^4.0.9", diff --git a/examples/authentication/package.json b/examples/authentication/package.json index 589a21d698..55ecab1108 100644 --- a/examples/authentication/package.json +++ b/examples/authentication/package.json @@ -7,7 +7,7 @@ "check-types": "tsc --noEmit" }, "dependencies": { - "@rivet-dev/agentos-core": "workspace:*", + "@rivet-dev/agentos": "workspace:*", "@rivet-dev/agentos-sandbox": "workspace:*", "sandbox-agent": "^0.4.2", "dockerode": "^4.0.9", diff --git a/examples/bindings/package.json b/examples/bindings/package.json index 15778143e0..7c395f6f01 100644 --- a/examples/bindings/package.json +++ b/examples/bindings/package.json @@ -7,7 +7,7 @@ "check-types": "tsc --noEmit" }, "dependencies": { - "@rivet-dev/agentos-core": "workspace:*", + "@rivet-dev/agentos": "workspace:*", "@rivet-dev/agentos-sandbox": "workspace:*", "sandbox-agent": "^0.4.2", "dockerode": "^4.0.9", diff --git a/examples/claude/package.json b/examples/claude/package.json index d13b93dd8e..9b49d802e1 100644 --- a/examples/claude/package.json +++ b/examples/claude/package.json @@ -7,7 +7,7 @@ "check-types": "tsc --noEmit" }, "dependencies": { - "@rivet-dev/agentos-core": "workspace:*", + "@rivet-dev/agentos": "workspace:*", "@rivet-dev/agentos-sandbox": "workspace:*", "sandbox-agent": "^0.4.2", "dockerode": "^4.0.9", diff --git a/examples/codex/package.json b/examples/codex/package.json index 5dacca690a..fba1f033db 100644 --- a/examples/codex/package.json +++ b/examples/codex/package.json @@ -7,7 +7,7 @@ "check-types": "tsc --noEmit" }, "dependencies": { - "@rivet-dev/agentos-core": "workspace:*", + "@rivet-dev/agentos": "workspace:*", "@rivet-dev/agentos-sandbox": "workspace:*", "sandbox-agent": "^0.4.2", "dockerode": "^4.0.9", diff --git a/examples/core/README.md b/examples/core/README.md index c9d4da948a..a5a4be6e07 100644 --- a/examples/core/README.md +++ b/examples/core/README.md @@ -5,7 +5,7 @@ category: "Reference" order: 1 --- -The core `@rivet-dev/agentos-core` API surface in one place: boot a VM with +The core `@rivet-dev/agentos` API surface in one place: boot a VM with `AgentOs.create()` and drive it directly for exec, filesystem, processes, agent sessions, networking, and cron — no actor runtime and no client/server split. Reach for this when you want a reference of what an `AgentOs` instance can do and diff --git a/examples/core/advanced.ts b/examples/core/advanced.ts index edb1e4cf1a..f1cf7f7b03 100644 --- a/examples/core/advanced.ts +++ b/examples/core/advanced.ts @@ -1,4 +1,4 @@ -import { AgentOs } from "@rivet-dev/agentos-core"; +import { AgentOs } from "@rivet-dev/agentos"; // One dedicated sidecar process hosting multiple VMs. const sidecar = await AgentOs.createSidecar(); diff --git a/examples/core/config-reference.ts b/examples/core/config-reference.ts index 451998c842..df004ffeac 100644 --- a/examples/core/config-reference.ts +++ b/examples/core/config-reference.ts @@ -1,4 +1,4 @@ -import { AgentOs, nodeModulesMount } from "@rivet-dev/agentos-core"; +import { AgentOs, nodeModulesMount } from "@rivet-dev/agentos"; import pi from "@agentos-software/pi"; // The full AgentOs.create() configuration surface. The agentOS() actor accepts diff --git a/examples/core/hooks.ts b/examples/core/hooks.ts index 52c54c7e9b..da9fbc839e 100644 --- a/examples/core/hooks.ts +++ b/examples/core/hooks.ts @@ -1,4 +1,4 @@ -import { AgentOs } from "@rivet-dev/agentos-core"; +import { AgentOs } from "@rivet-dev/agentos"; import pi from "@agentos-software/pi"; // ACP updates and interactive permission records share one durable event union. diff --git a/examples/core/mounts.ts b/examples/core/mounts.ts index ca304deb8b..e29a8fd0bb 100644 --- a/examples/core/mounts.ts +++ b/examples/core/mounts.ts @@ -1,4 +1,4 @@ -import { AgentOs } from "@rivet-dev/agentos-core"; +import { AgentOs } from "@rivet-dev/agentos"; // Configure filesystem backends at boot. Native mount plugins (host // directories, S3, etc.) are passed via `plugin`, each identified by an `id` diff --git a/examples/core/package.json b/examples/core/package.json index c0f9d544ea..a11b15e27f 100644 --- a/examples/core/package.json +++ b/examples/core/package.json @@ -7,7 +7,7 @@ "check-types": "tsc --noEmit" }, "dependencies": { - "@rivet-dev/agentos-core": "workspace:*", + "@rivet-dev/agentos": "workspace:*", "@rivet-dev/agentos-sandbox": "workspace:*", "sandbox-agent": "^0.4.2", "dockerode": "^4.0.9", diff --git a/examples/core/vm.ts b/examples/core/vm.ts index a9a23ade48..c14513c2be 100644 --- a/examples/core/vm.ts +++ b/examples/core/vm.ts @@ -1,8 +1,8 @@ // docs:start boot -import { AgentOs } from "@rivet-dev/agentos-core"; +import { AgentOs } from "@rivet-dev/agentos"; import pi from "@agentos-software/pi"; -// Create a VM directly with the core package — no actor runtime, no +// Create a VM directly with the AgentOS package — no actor runtime, no // client/server split. `AgentOs.create()` boots the VM in-process. const vm = await AgentOs.create({ software: [pi] }); diff --git a/examples/crash-course/package.json b/examples/crash-course/package.json index 7264a4b544..c1f9593a93 100644 --- a/examples/crash-course/package.json +++ b/examples/crash-course/package.json @@ -6,7 +6,7 @@ "scripts": { "check-types": "tsc --noEmit" }, "dependencies": { "@rivet-dev/agentos": "workspace:*", - "@rivet-dev/agentos-core": "workspace:*", + "@rivet-dev/agentos": "workspace:*", "@rivet-dev/agentos-sandbox": "workspace:*", "rivetkit": "catalog:rivetkit", "sandbox-agent": "^0.4.2", diff --git a/examples/crash-course/sandbox-stubs.d.ts b/examples/crash-course/sandbox-stubs.d.ts index f7aa49fff6..0be6a1f3f3 100644 --- a/examples/crash-course/sandbox-stubs.d.ts +++ b/examples/crash-course/sandbox-stubs.d.ts @@ -27,7 +27,7 @@ declare module "@rivet-dev/agentos-sandbox" { import type { NativeMountPluginDescriptor, Bindings, - } from "@rivet-dev/agentos-core"; + } from "@rivet-dev/agentos"; import type { SandboxAgent } from "sandbox-agent"; export interface SandboxFsOptions { diff --git a/examples/cron/package.json b/examples/cron/package.json index 75f4e8577d..d2a1f5390b 100644 --- a/examples/cron/package.json +++ b/examples/cron/package.json @@ -7,7 +7,7 @@ "check-types": "tsc --noEmit" }, "dependencies": { - "@rivet-dev/agentos-core": "workspace:*", + "@rivet-dev/agentos": "workspace:*", "@rivet-dev/agentos-sandbox": "workspace:*", "sandbox-agent": "^0.4.2", "dockerode": "^4.0.9", diff --git a/examples/custom/package.json b/examples/custom/package.json index 23c59fe9a2..36a676d514 100644 --- a/examples/custom/package.json +++ b/examples/custom/package.json @@ -7,7 +7,7 @@ "check-types": "tsc --noEmit" }, "dependencies": { - "@rivet-dev/agentos-core": "workspace:*", + "@rivet-dev/agentos": "workspace:*", "@rivet-dev/agentos-sandbox": "workspace:*", "sandbox-agent": "^0.4.2", "dockerode": "^4.0.9", diff --git a/examples/debugging/agent-logs.ts b/examples/debugging/agent-logs.ts index 09a08f4c21..4dc1e0080b 100644 --- a/examples/debugging/agent-logs.ts +++ b/examples/debugging/agent-logs.ts @@ -1,7 +1,7 @@ // Capture the coding agent's stderr at the VM level to diagnose tool calls, // model errors, and crashes mid-turn. -import { AgentOs } from "@rivet-dev/agentos-core"; +import { AgentOs } from "@rivet-dev/agentos"; import pi from "@agentos-software/pi"; const agentOs = await AgentOs.create({ diff --git a/examples/debugging/package.json b/examples/debugging/package.json index b176c9f840..2384c39433 100644 --- a/examples/debugging/package.json +++ b/examples/debugging/package.json @@ -7,7 +7,7 @@ "check-types": "tsc --noEmit" }, "dependencies": { - "@rivet-dev/agentos-core": "workspace:*", + "@rivet-dev/agentos": "workspace:*", "@rivet-dev/agentos-sandbox": "workspace:*", "sandbox-agent": "^0.4.2", "dockerode": "^4.0.9", diff --git a/examples/exec-js-ai-agent-code-exec/README.md b/examples/exec-js-ai-agent-code-exec/README.md new file mode 100644 index 0000000000..4fb9777685 --- /dev/null +++ b/examples/exec-js-ai-agent-code-exec/README.md @@ -0,0 +1,19 @@ +--- +title: "AI Agent Code Exec" +description: "Execute agent-generated code inside an isolated AgentOS VM." +--- + +Treat every generated program as hostile input. This example creates one +`JavaScriptRuntime`, evaluates a generated expression with a timeout, validates +the structured result, and disposes the VM. + +Use `evaluate()` for a JSON-serializable value, `execute()` for a complete +program whose output is the result, and `spawn()` for a long-running tool or +server. Configure permissions and VM resource limits before accepting untrusted +source. + +## Run it + +```bash +pnpm --dir examples/exec-js-ai-agent-code-exec start +``` diff --git a/examples/exec-js-ai-agent-code-exec/package.json b/examples/exec-js-ai-agent-code-exec/package.json new file mode 100644 index 0000000000..c09655f017 --- /dev/null +++ b/examples/exec-js-ai-agent-code-exec/package.json @@ -0,0 +1,17 @@ +{ + "name": "@rivet-dev/agentos-example-exec-js-ai-agent-code-exec", + "private": true, + "type": "module", + "scripts": { + "start": "tsx src/index.ts", + "check-types": "tsc --noEmit" + }, + "dependencies": { + "@rivet-dev/agentos-javascript": "workspace:*" + }, + "devDependencies": { + "@types/node": "^22.10.2", + "tsx": "^4.19.2", + "typescript": "^5.7.2" + } +} diff --git a/examples/exec-js-ai-agent-code-exec/src/index.ts b/examples/exec-js-ai-agent-code-exec/src/index.ts new file mode 100644 index 0000000000..e538a71749 --- /dev/null +++ b/examples/exec-js-ai-agent-code-exec/src/index.ts @@ -0,0 +1,28 @@ +import { JavaScriptRuntime } from "@rivet-dev/agentos-javascript"; + +// Imagine this expression came from an AI agent. It executes inside an +// isolated AgentOS VM and can only use capabilities granted to that VM. +const untrustedExpression = ` +(async () => { + const fib = [0, 1]; + while (fib.length < 20) { + fib.push(fib[fib.length - 1] + fib[fib.length - 2]); + } + console.log("computed", fib.length, "fibonacci numbers"); + return { fibonacci: fib, sum: fib.reduce((a, b) => a + b, 0) }; +})() +`; + +const runtime = await JavaScriptRuntime.create(); +try { + const result = await runtime.evaluate<{ + fibonacci: number[]; + sum: number; + }>(untrustedExpression, { timeoutMs: 5_000 }); + + console.log("exitCode:", result.exitCode); + console.log("stdout:", result.stdout.trim()); + if (result.success) console.log("returned value:", result.value); +} finally { + await runtime.dispose(); +} diff --git a/examples/exec-js-ai-agent-code-exec/tsconfig.json b/examples/exec-js-ai-agent-code-exec/tsconfig.json new file mode 100644 index 0000000000..ec30112241 --- /dev/null +++ b/examples/exec-js-ai-agent-code-exec/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "noEmit": true, + "rootDir": "./src" + }, + "include": ["src/**/*"], + "exclude": ["node_modules"] +} diff --git a/examples/exec-js-child-processes/package.json b/examples/exec-js-child-processes/package.json new file mode 100644 index 0000000000..98392bb4f3 --- /dev/null +++ b/examples/exec-js-child-processes/package.json @@ -0,0 +1,17 @@ +{ + "name": "@rivet-dev/agentos-example-exec-js-child-processes", + "private": true, + "type": "module", + "scripts": { + "start": "tsx src/index.ts", + "check-types": "tsc --noEmit" + }, + "dependencies": { + "@rivet-dev/agentos-javascript": "workspace:*" + }, + "devDependencies": { + "@types/node": "^22.10.2", + "tsx": "^4.19.2", + "typescript": "^5.7.2" + } +} diff --git a/examples/exec-js-child-processes/src/index.ts b/examples/exec-js-child-processes/src/index.ts new file mode 100644 index 0000000000..9169ac6f66 --- /dev/null +++ b/examples/exec-js-child-processes/src/index.ts @@ -0,0 +1,35 @@ +import { JavaScriptRuntime } from "@rivet-dev/agentos-javascript"; + +// Boot a fully virtualized VM. The guest runs inside the kernel isolation +// boundary, and any child processes it spawns are themselves kernel-managed +// processes - they never spawn real host processes. +const rt = await JavaScriptRuntime.create(); + +try { + // Guest code runs as an ES module inside the VM. It uses the standard + // node:child_process module to spawn a command available in the VM and read + // its output. Here we spawn `sh -c` to echo a message, and `node` to report + // its own version - both run as kernel-managed child processes. + const { stdout, stderr, exitCode } = await rt.execute(` + import { execFileSync } from "node:child_process"; + + // Spawn a shell command and capture its stdout. + const shellOut = execFileSync("sh", ["-c", "echo hello from a child process"], { + encoding: "utf8", + }); + console.log("sh output:", shellOut.trim()); + + // Spawn node as a child process and read its version. + const nodeVersion = execFileSync("node", ["--version"], { + encoding: "utf8", + }); + console.log("child node version:", nodeVersion.trim()); + `); + + console.log("exitCode:", exitCode); + if (stderr.trim()) console.log("guest stderr:", stderr.trim()); + console.log("guest stdout:"); + console.log(stdout.trim()); +} finally { + await rt.dispose(); +} diff --git a/examples/exec-js-child-processes/tsconfig.json b/examples/exec-js-child-processes/tsconfig.json new file mode 100644 index 0000000000..ec30112241 --- /dev/null +++ b/examples/exec-js-child-processes/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "noEmit": true, + "rootDir": "./src" + }, + "include": ["src/**/*"], + "exclude": ["node_modules"] +} diff --git a/examples/exec-js-code-mode/README.md b/examples/exec-js-code-mode/README.md new file mode 100644 index 0000000000..9db1fb371b --- /dev/null +++ b/examples/exec-js-code-mode/README.md @@ -0,0 +1,19 @@ +--- +title: "Code Mode" +description: "Let generated code orchestrate narrow host bindings in one VM process." +--- + +Code Mode gives an LLM one execution tool instead of exposing every host tool +directly. This example registers a Zod-validated weather binding, lets a +generated expression invoke it more than once, and returns one structured +result. + +Binding handlers run in the trusted host. Only validated input and JSON output +cross the AgentOS boundary, so credentials and direct host resources stay out +of generated code. + +## Run it + +```bash +pnpm --dir examples/exec-js-code-mode start +``` diff --git a/examples/exec-js-code-mode/package.json b/examples/exec-js-code-mode/package.json new file mode 100644 index 0000000000..3aad140e09 --- /dev/null +++ b/examples/exec-js-code-mode/package.json @@ -0,0 +1,18 @@ +{ + "name": "@rivet-dev/agentos-example-exec-js-code-mode", + "private": true, + "type": "module", + "scripts": { + "start": "tsx src/index.ts", + "check-types": "tsc --noEmit" + }, + "dependencies": { + "@rivet-dev/agentos-javascript": "workspace:*", + "zod": "^4.1.11" + }, + "devDependencies": { + "@types/node": "^22.10.2", + "tsx": "^4.19.2", + "typescript": "^5.7.2" + } +} diff --git a/examples/exec-js-code-mode/src/index.ts b/examples/exec-js-code-mode/src/index.ts new file mode 100644 index 0000000000..e06c4fdbc2 --- /dev/null +++ b/examples/exec-js-code-mode/src/index.ts @@ -0,0 +1,61 @@ +// docs:start bindings +import { + binding, + bindings, + JavaScriptRuntime, +} from "@rivet-dev/agentos-javascript"; +import { z } from "zod"; + +const toolBindings = bindings({ + name: "tools", + description: "Curated host capabilities for generated code.", + bindings: { + weather: binding({ + description: "Look up a city's temperature.", + inputSchema: z.object({ city: z.string() }), + execute: ({ city }) => ({ + city, + tempF: city === "San Francisco" ? 61 : 75, + }), + }), + }, +}); + +const runtime = await JavaScriptRuntime.create({ + bindings: [toolBindings], + permissions: { binding: "allow" }, +}); +// docs:end bindings + +// docs:start generated-code +const llmGeneratedExpression = `(async () => { + const { execFileSync } = await import("node:child_process"); + const call = (city) => JSON.parse( + execFileSync("agentos-tools", ["weather", "--city", city], { + encoding: "utf8", + }), + ); + const [sf, tokyo] = await Promise.all([ + Promise.resolve(call("San Francisco")), + Promise.resolve(call("Tokyo")), + ]); + return { + sanFrancisco: sf, + tokyo, + differenceF: Math.abs(sf.tempF - tokyo.tempF), + }; +})()`; +// docs:end generated-code + +// docs:start run +try { + const result = await runtime.evaluate<{ + sanFrancisco: { city: string; tempF: number }; + tokyo: { city: string; tempF: number }; + differenceF: number; + }>(llmGeneratedExpression, { timeoutMs: 5_000 }); + console.log(result); +} finally { + await runtime.dispose(); +} +// docs:end run diff --git a/examples/exec-js-code-mode/tsconfig.json b/examples/exec-js-code-mode/tsconfig.json new file mode 100644 index 0000000000..ec30112241 --- /dev/null +++ b/examples/exec-js-code-mode/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "noEmit": true, + "rootDir": "./src" + }, + "include": ["src/**/*"], + "exclude": ["node_modules"] +} diff --git a/examples/exec-js-dev-servers/README.md b/examples/exec-js-dev-servers/README.md new file mode 100644 index 0000000000..9ba85a466e --- /dev/null +++ b/examples/exec-js-dev-servers/README.md @@ -0,0 +1,18 @@ +--- +title: "Dev Servers" +description: "Run a long-lived guest server and request it through AgentOS." +--- + +This example starts a Node.js HTTP server with `runtime.spawn()`, waits for its +readiness output, and calls it through `runtime.vm.httpRequest()`. The guest +listener stays inside the VM; no host port is exposed. + +The returned process handle controls lifecycle through `kill()` and `wait()`. +Keep the runtime alive while its server is needed, then stop the process and +dispose the runtime. + +## Run it + +```bash +pnpm --dir examples/exec-js-dev-servers start +``` diff --git a/examples/exec-js-dev-servers/package.json b/examples/exec-js-dev-servers/package.json new file mode 100644 index 0000000000..d5bfdc4996 --- /dev/null +++ b/examples/exec-js-dev-servers/package.json @@ -0,0 +1,17 @@ +{ + "name": "@rivet-dev/agentos-example-exec-js-dev-servers", + "private": true, + "type": "module", + "scripts": { + "start": "tsx src/index.ts", + "check-types": "tsc --noEmit" + }, + "dependencies": { + "@rivet-dev/agentos-javascript": "workspace:*" + }, + "devDependencies": { + "@types/node": "^22.10.2", + "tsx": "^4.19.2", + "typescript": "^5.7.2" + } +} diff --git a/examples/exec-js-dev-servers/src/index.ts b/examples/exec-js-dev-servers/src/index.ts new file mode 100644 index 0000000000..e3cc68e87b --- /dev/null +++ b/examples/exec-js-dev-servers/src/index.ts @@ -0,0 +1,38 @@ +import { JavaScriptRuntime } from "@rivet-dev/agentos-javascript"; + +const serverSource = ` +import http from "node:http"; +const app = http.createServer((req, res) => { + res.writeHead(200, { "content-type": "application/json" }); + res.end(JSON.stringify({ ok: true, path: req.url })); +}); +app.listen(3000, "127.0.0.1", () => console.log("ready")); +await new Promise(() => {}); +`; + +const runtime = await JavaScriptRuntime.create({ + permissions: { network: "allow" }, +}); + +let ready!: () => void; +const serverReady = new Promise((resolve) => { + ready = resolve; +}); + +try { + const server = await runtime.spawn(serverSource, { + onStdout: (chunk) => { + process.stdout.write(chunk); + if (chunk.includes("ready")) ready(); + }, + }); + + await serverReady; + const response = await runtime.vm.httpRequest({ port: 3000, path: "/health" }); + console.log(response.status, new TextDecoder().decode(response.body)); + + server.kill("SIGTERM"); + await server.wait(); +} finally { + await runtime.dispose(); +} diff --git a/examples/exec-js-dev-servers/tsconfig.json b/examples/exec-js-dev-servers/tsconfig.json new file mode 100644 index 0000000000..ec30112241 --- /dev/null +++ b/examples/exec-js-dev-servers/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "noEmit": true, + "rootDir": "./src" + }, + "include": ["src/**/*"], + "exclude": ["node_modules"] +} diff --git a/examples/exec-js-filesystem/host-data/greeting.txt b/examples/exec-js-filesystem/host-data/greeting.txt new file mode 100644 index 0000000000..22aea324a8 --- /dev/null +++ b/examples/exec-js-filesystem/host-data/greeting.txt @@ -0,0 +1 @@ +value-from-host diff --git a/examples/exec-js-filesystem/package.json b/examples/exec-js-filesystem/package.json new file mode 100644 index 0000000000..b11449484d --- /dev/null +++ b/examples/exec-js-filesystem/package.json @@ -0,0 +1,17 @@ +{ + "name": "@rivet-dev/agentos-example-exec-js-filesystem", + "private": true, + "type": "module", + "scripts": { + "start": "tsx src/index.ts", + "check-types": "tsc --noEmit" + }, + "dependencies": { + "@rivet-dev/agentos-javascript": "workspace:*" + }, + "devDependencies": { + "@types/node": "^22.10.2", + "tsx": "^4.19.2", + "typescript": "^5.7.2" + } +} diff --git a/examples/exec-js-filesystem/src/index.ts b/examples/exec-js-filesystem/src/index.ts new file mode 100644 index 0000000000..6570d7ff86 --- /dev/null +++ b/examples/exec-js-filesystem/src/index.ts @@ -0,0 +1,77 @@ +import path from "node:path"; +import { fileURLToPath } from "node:url"; +// docs:start virtual-filesystem +import { + createHostDirBackend, + JavaScriptRuntime, +} from "@rivet-dev/agentos-javascript"; + +// Boot a fully virtualized VM. The guest filesystem lives entirely inside the +// kernel - writes never touch the host disk. +const rt = await JavaScriptRuntime.create(); + +try { + // Guest code runs as an ES module inside the VM. It writes and reads files + // using the standard node `fs` module, backed by the kernel's virtual + // filesystem. + const { stdout, stderr, exitCode } = await rt.execute(` + import { mkdirSync, writeFileSync, readFileSync, readdirSync } from "node:fs"; + + mkdirSync("/workspace", { recursive: true }); + writeFileSync("/workspace/hello.txt", "hello from the VM"); + + const message = readFileSync("/workspace/hello.txt", "utf8"); + const entries = readdirSync("/workspace"); + + console.log("read back from VM:", message); + console.log("/workspace contents:", JSON.stringify(entries)); + `); + + console.log("exitCode:", exitCode); + if (stderr.trim()) console.log("guest stderr:", stderr.trim()); + console.log("guest stdout:"); + console.log(stdout.trim()); +} finally { + await rt.dispose(); +} +// docs:end virtual-filesystem + +// Mounting a host directory into the VM. `mounts` projects a real host +// directory into the guest filesystem, Docker-style. Files are read lazily +// through the VFS, and the guest sees only the mounted subtree. +const hostDir = path.join( + path.dirname(fileURLToPath(import.meta.url)), + "..", + "host-data", +); + +const mounted = await JavaScriptRuntime.create({ + mounts: [ + { + path: "/mnt/host-data", + plugin: createHostDirBackend({ hostPath: hostDir, readOnly: true }), + readOnly: true, + }, + ], +}); + +try { + // The guest reads a file that lives on the real host, exposed read-only at + // the mount point. Nothing else on the host is visible. + const { stdout, stderr, exitCode } = await mounted.execute(` + import { readFileSync, readdirSync } from "node:fs"; + + const entries = readdirSync("/mnt/host-data"); + const greeting = readFileSync("/mnt/host-data/greeting.txt", "utf8"); + + console.log("mounted contents:", JSON.stringify(entries)); + console.log("guest read host file:", greeting.trim()); + `); + + console.log("[mount] exitCode:", exitCode); + if (stderr.trim()) console.log("[mount] guest stderr:", stderr.trim()); + console.log("[mount] guest stdout:"); + console.log(stdout.trim()); +} finally { + await mounted.dispose(); +} diff --git a/examples/exec-js-filesystem/tsconfig.json b/examples/exec-js-filesystem/tsconfig.json new file mode 100644 index 0000000000..ec30112241 --- /dev/null +++ b/examples/exec-js-filesystem/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "noEmit": true, + "rootDir": "./src" + }, + "include": ["src/**/*"], + "exclude": ["node_modules"] +} diff --git a/examples/exec-js-module-loading/package.json b/examples/exec-js-module-loading/package.json new file mode 100644 index 0000000000..f72d5e3f23 --- /dev/null +++ b/examples/exec-js-module-loading/package.json @@ -0,0 +1,17 @@ +{ + "name": "@rivet-dev/agentos-example-exec-js-module-loading", + "private": true, + "type": "module", + "scripts": { + "start": "tsx src/index.ts", + "check-types": "tsc --noEmit" + }, + "dependencies": { + "@rivet-dev/agentos-javascript": "workspace:*" + }, + "devDependencies": { + "@types/node": "^22.10.2", + "tsx": "^4.19.2", + "typescript": "^5.7.2" + } +} diff --git a/examples/exec-js-module-loading/src/index.ts b/examples/exec-js-module-loading/src/index.ts new file mode 100644 index 0000000000..d3e88f1000 --- /dev/null +++ b/examples/exec-js-module-loading/src/index.ts @@ -0,0 +1,89 @@ +import { fileURLToPath } from "node:url"; +import { JavaScriptRuntime } from "@rivet-dev/agentos-javascript"; + +// docs:start loading-modules +// Boot a fully virtualized VM. Module resolution runs entirely inside the +// kernel - `import` and `require` resolve against the guest's virtual +// filesystem, never the host's. +const rt = await JavaScriptRuntime.create(); + +try { + // Guest code runs as an ES module inside the VM, so it can `import` Node + // builtins directly. It can also build a CommonJS `require` with + // `createRequire` to load builtins the classic way. Both resolve through the + // kernel's module loader. + const { stdout, stderr, exitCode } = await rt.execute(` + // ESM import of a Node builtin. + import { basename, join } from "node:path"; + + // CommonJS require, created from the current module URL. + import { createRequire } from "node:module"; + const require = createRequire(import.meta.url); + const os = require("node:os"); + + const resolved = { + basename: basename("/workspace/data/report.txt"), + joined: join("/workspace", "data", "report.txt"), + platform: os.platform(), + }; + + console.log("resolved node:path via import ->", resolved.joined); + console.log("resolved node:os via require ->", resolved.platform); + console.log(JSON.stringify(resolved)); + `); + + console.log("exitCode:", exitCode); + if (stderr.trim()) console.log("guest stderr:\n" + stderr.trim()); + console.log("guest stdout:"); + console.log(stdout.trim()); +} finally { + await rt.dispose(); +} +// docs:end loading-modules + +// --- Loading real npm packages from the host ------------------------------ + +// docs:start npm-packages +// Point `nodeModules` at a host `node_modules` directory and the whole tree is +// projected into the VM in one call. Any package inside resolves the way Node +// would over a real filesystem, symlinks and all. Here we mount this repo's +// root node_modules, which includes the tiny `is-number` package. +const hostNodeModules = fileURLToPath( + new URL("../../../../node_modules", import.meta.url), +); + +const mounted = await JavaScriptRuntime.create({ + nodeModules: hostNodeModules, +}); + +try { + // The guest resolves `is-number` from the mounted host node_modules the same + // way Node would over a real filesystem, then uses the real package's code. + const { stdout, stderr, exitCode } = await mounted.execute(` + // ESM import of the real, host-mounted npm package. + import isNumber from "is-number"; + + // The same package also resolves through a CommonJS require. + import { createRequire } from "node:module"; + const require = createRequire(import.meta.url); + const isNumberCjs = require("is-number"); + + const result = { + "isNumber(42)": isNumber(42), + 'isNumber("3.14")': isNumber("3.14"), + 'isNumber("nope")': isNumber("nope"), + sameModule: isNumber === isNumberCjs, + }; + + console.log("loaded real npm package is-number"); + console.log(JSON.stringify(result)); + `); + + console.log("exitCode:", exitCode); + if (stderr.trim()) console.log("guest stderr:\n" + stderr.trim()); + console.log("guest stdout:"); + console.log(stdout.trim()); +} finally { + await mounted.dispose(); +} +// docs:end npm-packages diff --git a/examples/exec-js-module-loading/tsconfig.json b/examples/exec-js-module-loading/tsconfig.json new file mode 100644 index 0000000000..ec30112241 --- /dev/null +++ b/examples/exec-js-module-loading/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "noEmit": true, + "rootDir": "./src" + }, + "include": ["src/**/*"], + "exclude": ["node_modules"] +} diff --git a/examples/exec-js-networking-wasm/package.json b/examples/exec-js-networking-wasm/package.json new file mode 100644 index 0000000000..0e9e04a29e --- /dev/null +++ b/examples/exec-js-networking-wasm/package.json @@ -0,0 +1,17 @@ +{ + "name": "@rivet-dev/agentos-example-exec-js-networking-wasm", + "private": true, + "type": "module", + "scripts": { + "start": "tsx src/index.ts", + "check-types": "tsc --noEmit" + }, + "dependencies": { + "@rivet-dev/agentos-javascript": "workspace:*" + }, + "devDependencies": { + "@types/node": "^22.10.2", + "tsx": "^4.19.2", + "typescript": "^5.7.2" + } +} diff --git a/examples/exec-js-networking-wasm/src/index.ts b/examples/exec-js-networking-wasm/src/index.ts new file mode 100644 index 0000000000..e9871535a7 --- /dev/null +++ b/examples/exec-js-networking-wasm/src/index.ts @@ -0,0 +1,15 @@ +import { JavaScriptRuntime } from "@rivet-dev/agentos-javascript"; + +// The runtime exposes its underlying VM for advanced shell and WASM workflows. +const runtime = await JavaScriptRuntime.create({ + permissions: { network: "allow" }, +}); +try { + const result = await runtime.vm.execArgv("sh", [ + "-c", + "printf 'hello from a WASM-backed AgentOS command\\n'", + ]); + console.log(result.stdout.trim()); +} finally { + await runtime.dispose(); +} diff --git a/examples/exec-js-networking-wasm/tsconfig.json b/examples/exec-js-networking-wasm/tsconfig.json new file mode 100644 index 0000000000..ec30112241 --- /dev/null +++ b/examples/exec-js-networking-wasm/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "noEmit": true, + "rootDir": "./src" + }, + "include": ["src/**/*"], + "exclude": ["node_modules"] +} diff --git a/examples/exec-js-networking/package.json b/examples/exec-js-networking/package.json new file mode 100644 index 0000000000..baa9d1d93d --- /dev/null +++ b/examples/exec-js-networking/package.json @@ -0,0 +1,17 @@ +{ + "name": "@rivet-dev/agentos-example-exec-js-networking", + "private": true, + "type": "module", + "scripts": { + "start": "tsx src/index.ts", + "check-types": "tsc --noEmit" + }, + "dependencies": { + "@rivet-dev/agentos-javascript": "workspace:*" + }, + "devDependencies": { + "@types/node": "^22.10.2", + "tsx": "^4.19.2", + "typescript": "^5.7.2" + } +} diff --git a/examples/exec-js-networking/src/index.ts b/examples/exec-js-networking/src/index.ts new file mode 100644 index 0000000000..dd33d729de --- /dev/null +++ b/examples/exec-js-networking/src/index.ts @@ -0,0 +1,144 @@ +/** + * Networking example. + * + * Network access for guest code is governed by the VM permission policy. This + * example shows both sides of the gate: + * + * 1. With network "allow", the guest starts a loopback HTTP server inside the + * VM and fetches it - the request and response stay entirely within the + * kernel socket table (hermetic, no real host network). + * 2. With an explicit network deny policy, the same fetch is blocked. + * 3. Host loopback is separate from VM loopback: even with network "allow", + * a guest can reach a host loopback service only when the host port is in + * loopbackExemptPorts. + * + * Run with: + * AGENTOS_SIDECAR_BIN=../../../target/debug/agentos-sidecar \ + * npx tsx src/index.ts + */ + +import { createServer as createHttpServer } from "node:http"; +import type { AddressInfo } from "node:net"; +// docs:start vm-network +import { JavaScriptRuntime } from "@rivet-dev/agentos-javascript"; + +// Guest program: start a loopback HTTP server, then fetch it. Both the listen +// and the fetch go through the kernel socket table. +const GUEST = ` +import http from "node:http"; + +const server = http.createServer((_req, res) => { + res.writeHead(200, { "content-type": "text/plain" }); + res.end("network-ok"); +}); + +await new Promise((resolve, reject) => { + server.once("error", reject); + server.listen(0, "127.0.0.1", resolve); +}); + +const { port } = server.address(); +const response = await fetch("http://127.0.0.1:" + port + "/"); +const body = await response.text(); +console.log("status:", response.status); +console.log("body:", body); + +await new Promise((resolve) => server.close(resolve)); +`; + +// 1. Network allowed. This matches the high-level API default, but spelling it +// out makes the example's policy intent clear. +const allowed = await JavaScriptRuntime.create({ + permissions: { network: "allow" }, +}); +try { + const result = await allowed.execute(GUEST); + console.log("[network allowed] exitCode:", result.exitCode); + console.log( + "[network allowed] stdout:", + JSON.stringify(result.stdout.trim()), + ); + console.log( + "[network allowed] stderr:", + JSON.stringify(result.stderr.trim()), + ); +} finally { + await allowed.dispose(); +} +// docs:end vm-network + +// 2. Network denied explicitly. Supplying a partial policy denies omitted +// scopes too, so name the runtime capabilities needed to launch the program. +const denied = await JavaScriptRuntime.create({ + permissions: { + fs: "allow", + network: "deny", + childProcess: "allow", + process: "allow", + env: "allow", + }, +}); +try { + const result = await denied.execute(GUEST); + console.log("[network denied] exitCode:", result.exitCode); + console.log( + "[network denied] stderr:", + JSON.stringify(result.stderr.trim().split("\n")[0]), + ); +} finally { + await denied.dispose(); +} + +// 3. Host loopback access: network "allow" is not enough to reach real host +// loopback. The host must explicitly exempt the host port too. +const hostServer = createHttpServer((req, res) => { + res.writeHead(200, { "content-type": "text/plain" }); + res.end(`host-ok:${req.url}`); +}); +await new Promise((resolve) => { + hostServer.listen(0, "127.0.0.1", resolve); +}); +const hostPort = (hostServer.address() as AddressInfo).port; + +const HOST_FETCH_GUEST = ` +try { + const response = await fetch("http://127.0.0.1:${hostPort}/from-guest"); + console.log(response.status + ":" + await response.text()); +} catch (error) { + console.log(error.cause?.code || error.code || error.name); + process.exit(2); +} +`; + +try { + const blockedHostLoopback = await JavaScriptRuntime.create({ + permissions: { network: "allow" }, + }); + try { + const result = await blockedHostLoopback.execute(HOST_FETCH_GUEST); + console.log("[host loopback blocked] exitCode:", result.exitCode); + console.log( + "[host loopback blocked] stdout:", + JSON.stringify(result.stdout.trim()), + ); + } finally { + await blockedHostLoopback.dispose(); + } + + const allowedHostLoopback = await JavaScriptRuntime.create({ + permissions: { network: "allow" }, + loopbackExemptPorts: [hostPort], + }); + try { + const result = await allowedHostLoopback.execute(HOST_FETCH_GUEST); + console.log("[host loopback allowed] exitCode:", result.exitCode); + console.log( + "[host loopback allowed] stdout:", + JSON.stringify(result.stdout.trim()), + ); + } finally { + await allowedHostLoopback.dispose(); + } +} finally { + await new Promise((resolve) => hostServer.close(() => resolve())); +} diff --git a/examples/exec-js-networking/tsconfig.json b/examples/exec-js-networking/tsconfig.json new file mode 100644 index 0000000000..ec30112241 --- /dev/null +++ b/examples/exec-js-networking/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "noEmit": true, + "rootDir": "./src" + }, + "include": ["src/**/*"], + "exclude": ["node_modules"] +} diff --git a/examples/exec-js-output-capture/package.json b/examples/exec-js-output-capture/package.json new file mode 100644 index 0000000000..f456d12c22 --- /dev/null +++ b/examples/exec-js-output-capture/package.json @@ -0,0 +1,17 @@ +{ + "name": "@rivet-dev/agentos-example-exec-js-output-capture", + "private": true, + "type": "module", + "scripts": { + "start": "tsx src/index.ts", + "check-types": "tsc --noEmit" + }, + "dependencies": { + "@rivet-dev/agentos-javascript": "workspace:*" + }, + "devDependencies": { + "@types/node": "^22.10.2", + "tsx": "^4.19.2", + "typescript": "^5.7.2" + } +} diff --git a/examples/exec-js-output-capture/src/index.ts b/examples/exec-js-output-capture/src/index.ts new file mode 100644 index 0000000000..1c7c073709 --- /dev/null +++ b/examples/exec-js-output-capture/src/index.ts @@ -0,0 +1,17 @@ +import { JavaScriptRuntime } from "@rivet-dev/agentos-javascript"; + +const rt = await JavaScriptRuntime.create(); + +try { + const { stdout, stderr, exitCode } = await rt.execute(` + console.log("hello from the VM"); + console.error("oops from the VM"); + process.exit(3); + `); + + console.log("exitCode:", exitCode); + console.log("stdout:", JSON.stringify(stdout)); + console.log("stderr:", JSON.stringify(stderr)); +} finally { + await rt.dispose(); +} diff --git a/examples/exec-js-output-capture/tsconfig.json b/examples/exec-js-output-capture/tsconfig.json new file mode 100644 index 0000000000..ec30112241 --- /dev/null +++ b/examples/exec-js-output-capture/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "noEmit": true, + "rootDir": "./src" + }, + "include": ["src/**/*"], + "exclude": ["node_modules"] +} diff --git a/examples/exec-js-permissions/package.json b/examples/exec-js-permissions/package.json new file mode 100644 index 0000000000..3254e80824 --- /dev/null +++ b/examples/exec-js-permissions/package.json @@ -0,0 +1,17 @@ +{ + "name": "@rivet-dev/agentos-example-exec-js-permissions", + "private": true, + "type": "module", + "scripts": { + "start": "tsx src/index.ts", + "check-types": "tsc --noEmit" + }, + "dependencies": { + "@rivet-dev/agentos-javascript": "workspace:*" + }, + "devDependencies": { + "@types/node": "^22.10.2", + "tsx": "^4.19.2", + "typescript": "^5.7.2" + } +} diff --git a/examples/exec-js-permissions/src/index.ts b/examples/exec-js-permissions/src/index.ts new file mode 100644 index 0000000000..9bc6182650 --- /dev/null +++ b/examples/exec-js-permissions/src/index.ts @@ -0,0 +1,32 @@ +import { JavaScriptRuntime } from "@rivet-dev/agentos-javascript"; + +const runtime = await JavaScriptRuntime.create({ + permissions: { + fs: "allow", + network: "deny", + childProcess: "allow", + process: "allow", + env: "allow", + }, +}); + +try { + const result = await runtime.evaluate<{ + fileContents: string; + networkBlocked: boolean; + }>(`(async () => { + const { writeFileSync, readFileSync } = await import("node:fs"); + writeFileSync("/workspace/note.txt", "inside the VM"); + let networkBlocked = false; + try { await fetch("https://example.com"); } catch { networkBlocked = true; } + return { + fileContents: readFileSync("/workspace/note.txt", "utf8"), + networkBlocked, + }; + })()`); + + if (!result.success) throw new Error(result.error.message); + console.log(result.value); +} finally { + await runtime.dispose(); +} diff --git a/examples/exec-js-permissions/tsconfig.json b/examples/exec-js-permissions/tsconfig.json new file mode 100644 index 0000000000..ec30112241 --- /dev/null +++ b/examples/exec-js-permissions/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "noEmit": true, + "rootDir": "./src" + }, + "include": ["src/**/*"], + "exclude": ["node_modules"] +} diff --git a/examples/exec-js-plugin-systems/README.md b/examples/exec-js-plugin-systems/README.md new file mode 100644 index 0000000000..ba49524385 --- /dev/null +++ b/examples/exec-js-plugin-systems/README.md @@ -0,0 +1,19 @@ +--- +title: "Plugin Systems" +description: "Evaluate untrusted JavaScript plugins with a narrow AgentOS policy." +--- + +This example evaluates plugin source inside an isolated VM and returns a +structured value. The plugin can use only the filesystem, network, processes, +packages, and bindings allowed by the runtime configuration. + +Mount only the dependency tree a plugin needs, deny network unless it is part +of the contract, and expose privileged operations through validated bindings. +TypeScript plugins can be checked with `runtime.typescript.check()` before they +run in the same VM. + +## Run it + +```bash +pnpm --dir examples/exec-js-plugin-systems start +``` diff --git a/examples/exec-js-plugin-systems/package.json b/examples/exec-js-plugin-systems/package.json new file mode 100644 index 0000000000..869a047953 --- /dev/null +++ b/examples/exec-js-plugin-systems/package.json @@ -0,0 +1,17 @@ +{ + "name": "@rivet-dev/agentos-example-exec-js-plugin-systems", + "private": true, + "type": "module", + "scripts": { + "start": "tsx src/index.ts", + "check-types": "tsc --noEmit" + }, + "dependencies": { + "@rivet-dev/agentos-javascript": "workspace:*" + }, + "devDependencies": { + "@types/node": "^22.10.2", + "tsx": "^4.19.2", + "typescript": "^5.7.2" + } +} diff --git a/examples/exec-js-plugin-systems/src/index.ts b/examples/exec-js-plugin-systems/src/index.ts new file mode 100644 index 0000000000..928ddb04df --- /dev/null +++ b/examples/exec-js-plugin-systems/src/index.ts @@ -0,0 +1,39 @@ +import { JavaScriptRuntime } from "@rivet-dev/agentos-javascript"; + +const runtime = await JavaScriptRuntime.create({ + permissions: { + fs: "allow", + network: "deny", + childProcess: "allow", + process: "allow", + env: "allow", + }, +}); + +try { + const input = "hello from plugin land"; + const result = await runtime.evaluate<{ + manifest: { name: string; version: string }; + output: string; + networkBlocked: boolean; + }>(`(async () => { + function transform(input, prefix = "") { + return prefix + String(input) + .split(/\\s+/) + .filter(Boolean) + .map((word) => word[0].toUpperCase() + word.slice(1).toLowerCase()) + .join(" "); + } + let networkBlocked = false; + try { await fetch("http://example.com"); } catch { networkBlocked = true; } + return { + manifest: { name: "title-case", version: "1.0.0" }, + output: transform(${JSON.stringify(input)}, "Plugin says: "), + networkBlocked, + }; + })()`); + + console.log(result); +} finally { + await runtime.dispose(); +} diff --git a/examples/exec-js-plugin-systems/tsconfig.json b/examples/exec-js-plugin-systems/tsconfig.json new file mode 100644 index 0000000000..ec30112241 --- /dev/null +++ b/examples/exec-js-plugin-systems/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "noEmit": true, + "rootDir": "./src" + }, + "include": ["src/**/*"], + "exclude": ["node_modules"] +} diff --git a/examples/exec-js-process-isolation/package.json b/examples/exec-js-process-isolation/package.json new file mode 100644 index 0000000000..6ccb135b4d --- /dev/null +++ b/examples/exec-js-process-isolation/package.json @@ -0,0 +1,17 @@ +{ + "name": "@rivet-dev/agentos-example-exec-js-process-isolation", + "private": true, + "type": "module", + "scripts": { + "start": "tsx src/index.ts", + "check-types": "tsc --noEmit" + }, + "dependencies": { + "@rivet-dev/agentos-javascript": "workspace:*" + }, + "devDependencies": { + "@types/node": "^22.10.2", + "tsx": "^4.19.2", + "typescript": "^5.7.2" + } +} diff --git a/examples/exec-js-process-isolation/src/index.ts b/examples/exec-js-process-isolation/src/index.ts new file mode 100644 index 0000000000..45c3ba010b --- /dev/null +++ b/examples/exec-js-process-isolation/src/index.ts @@ -0,0 +1,36 @@ +import { JavaScriptRuntime } from "@rivet-dev/agentos-javascript"; + +const runtimeA = await JavaScriptRuntime.create(); +const runtimeB = await JavaScriptRuntime.create(); + +try { + await runtimeA.execute(` + import { writeFileSync } from "node:fs"; + writeFileSync("/tmp/value.txt", "A"); + `); + await runtimeB.execute(` + import { writeFileSync } from "node:fs"; + writeFileSync("/tmp/value.txt", "B"); + `); + + const read = `(async () => { + const { readFile } = await import("node:fs/promises"); + return readFile("/tmp/value.txt", "utf8"); + })()`; + const [valueA, valueB] = await Promise.all([ + runtimeA.evaluate(read), + runtimeB.evaluate(read), + ]); + console.log({ valueA, valueB }); + + // Each evaluate() launches a fresh process, so guest globals do not persist. + const globalValue = `(() => { + globalThis.counter = (globalThis.counter ?? 0) + 1; + return globalThis.counter; + })()`; + console.log(await runtimeA.evaluate(globalValue)); + console.log(await runtimeA.evaluate(globalValue)); +} finally { + await runtimeA.dispose(); + await runtimeB.dispose(); +} diff --git a/examples/exec-js-process-isolation/tsconfig.json b/examples/exec-js-process-isolation/tsconfig.json new file mode 100644 index 0000000000..ec30112241 --- /dev/null +++ b/examples/exec-js-process-isolation/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "noEmit": true, + "rootDir": "./src" + }, + "include": ["src/**/*"], + "exclude": ["node_modules"] +} diff --git a/examples/exec-js-quickstart/package.json b/examples/exec-js-quickstart/package.json new file mode 100644 index 0000000000..3531df8187 --- /dev/null +++ b/examples/exec-js-quickstart/package.json @@ -0,0 +1,17 @@ +{ + "name": "@rivet-dev/agentos-example-exec-js-quickstart", + "private": true, + "type": "module", + "scripts": { + "start": "tsx src/index.ts", + "check-types": "tsc --noEmit" + }, + "dependencies": { + "@rivet-dev/agentos-javascript": "workspace:*" + }, + "devDependencies": { + "@types/node": "^22.10.2", + "tsx": "^4.19.2", + "typescript": "^5.7.2" + } +} diff --git a/examples/exec-js-quickstart/src/index.ts b/examples/exec-js-quickstart/src/index.ts new file mode 100644 index 0000000000..72e72b8ece --- /dev/null +++ b/examples/exec-js-quickstart/src/index.ts @@ -0,0 +1,38 @@ +import { JavaScriptRuntime } from "@rivet-dev/agentos-javascript"; + +// docs:start vanilla-javascript +// Boot a fully virtualized runtime. Guest code runs inside the kernel +// isolation boundary - no host escapes. +const runtime = await JavaScriptRuntime.create(); + +try { + // evaluate() returns a JSON-serializable value and captures stdout/stderr. + const result = await runtime.evaluate<{ message: string; sum: number }>(` + (() => { + console.log("hello from Agent OS Exec"); + return { message: "hello from Agent OS Exec", sum: 1 + 2 }; + })() + `); + + if (!result.success) throw new Error(result.error.message); + console.log("stdout:", JSON.stringify(result.stdout.trim())); + console.log("value:", result.value); + console.log("exitCode:", result.exitCode); +} finally { + // Tear down the VM and release the sidecar. + await runtime.dispose(); +} +// docs:end vanilla-javascript + +// docs:start typescript +const typedRuntime = await JavaScriptRuntime.create(); +try { + const typed = await typedRuntime.typescript.execute(` + const answer: number = 21 * 2; + console.log(answer); + `); + if (!typed.success) throw new Error(typed.stderr); +} finally { + await typedRuntime.dispose(); +} +// docs:end typescript diff --git a/examples/exec-js-quickstart/tsconfig.json b/examples/exec-js-quickstart/tsconfig.json new file mode 100644 index 0000000000..ec30112241 --- /dev/null +++ b/examples/exec-js-quickstart/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "noEmit": true, + "rootDir": "./src" + }, + "include": ["src/**/*"], + "exclude": ["node_modules"] +} diff --git a/examples/exec-js-resource-limits/package.json b/examples/exec-js-resource-limits/package.json new file mode 100644 index 0000000000..98e7800040 --- /dev/null +++ b/examples/exec-js-resource-limits/package.json @@ -0,0 +1,17 @@ +{ + "name": "@rivet-dev/agentos-example-exec-js-resource-limits", + "private": true, + "type": "module", + "scripts": { + "start": "tsx src/index.ts", + "check-types": "tsc --noEmit" + }, + "dependencies": { + "@rivet-dev/agentos-javascript": "workspace:*" + }, + "devDependencies": { + "@types/node": "^22.10.2", + "tsx": "^4.19.2", + "typescript": "^5.7.2" + } +} diff --git a/examples/exec-js-resource-limits/src/index.ts b/examples/exec-js-resource-limits/src/index.ts new file mode 100644 index 0000000000..b2c3f644fd --- /dev/null +++ b/examples/exec-js-resource-limits/src/index.ts @@ -0,0 +1,39 @@ +import { JavaScriptRuntime } from "@rivet-dev/agentos-javascript"; + +const rt = await JavaScriptRuntime.create(); + +try { + // A normal program finishes well within the timeout budget. + const ok = await rt.execute(`console.log("finished work");`, { + timeoutMs: 5000, + }); + console.log("normal run:"); + console.log(" exitCode:", ok.exitCode); + console.log(" stdout:", JSON.stringify(ok.stdout.trim())); + + // A runaway program (infinite loop) never returns on its own. The exec + // timeout terminates the guest process after the budget elapses. + const start = Date.now(); + const runaway = await rt.execute(`while (true) {}`, { + timeoutMs: 1000, + }); + const elapsed = Date.now() - start; + + console.log("runaway run (timeoutMs: 1000ms):"); + console.log(" exitCode:", runaway.exitCode); + console.log(" elapsedMs:", elapsed); + + // A killed process exits non-zero; a clean exit would be 0. + const terminated = runaway.exitCode !== 0; + console.log( + terminated + ? "runaway guest was terminated by the timeout" + : "ERROR: runaway guest was NOT terminated", + ); + + if (!terminated) { + process.exitCode = 1; + } +} finally { + await rt.dispose(); +} diff --git a/examples/exec-js-resource-limits/tsconfig.json b/examples/exec-js-resource-limits/tsconfig.json new file mode 100644 index 0000000000..ec30112241 --- /dev/null +++ b/examples/exec-js-resource-limits/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "noEmit": true, + "rootDir": "./src" + }, + "include": ["src/**/*"], + "exclude": ["node_modules"] +} diff --git a/examples/exec-js-runtime-platform/package.json b/examples/exec-js-runtime-platform/package.json new file mode 100644 index 0000000000..427897d2aa --- /dev/null +++ b/examples/exec-js-runtime-platform/package.json @@ -0,0 +1,17 @@ +{ + "name": "@rivet-dev/agentos-example-exec-js-runtime-platform", + "private": true, + "type": "module", + "scripts": { + "start": "tsx src/index.ts", + "check-types": "tsc --noEmit" + }, + "dependencies": { + "@rivet-dev/agentos-javascript": "workspace:*" + }, + "devDependencies": { + "@types/node": "^22.10.2", + "tsx": "^4.19.2", + "typescript": "^5.7.2" + } +} diff --git a/examples/exec-js-runtime-platform/src/index.ts b/examples/exec-js-runtime-platform/src/index.ts new file mode 100644 index 0000000000..e5cf7a52da --- /dev/null +++ b/examples/exec-js-runtime-platform/src/index.ts @@ -0,0 +1,24 @@ +import { JavaScriptRuntime } from "@rivet-dev/agentos-javascript"; + +// docs:start nodejs +const runtime = await JavaScriptRuntime.create(); + +try { + const result = await runtime.evaluate<{ + filename: string; + digest: string; + }>(`(async () => { + const { createHash } = await import("node:crypto"); + const { join } = await import("node:path"); + return { + filename: join("/workspace", "report.json"), + digest: createHash("sha256").update("agentos").digest("hex"), + }; + })()`); + + if (!result.success) throw new Error(result.error.message); + console.log(result.value); +} finally { + await runtime.dispose(); +} +// docs:end nodejs diff --git a/examples/exec-js-runtime-platform/tsconfig.json b/examples/exec-js-runtime-platform/tsconfig.json new file mode 100644 index 0000000000..ec30112241 --- /dev/null +++ b/examples/exec-js-runtime-platform/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "noEmit": true, + "rootDir": "./src" + }, + "include": ["src/**/*"], + "exclude": ["node_modules"] +} diff --git a/examples/exec-js-sdk-overview/package.json b/examples/exec-js-sdk-overview/package.json new file mode 100644 index 0000000000..9b982200ba --- /dev/null +++ b/examples/exec-js-sdk-overview/package.json @@ -0,0 +1,17 @@ +{ + "name": "@rivet-dev/agentos-example-exec-js-sdk-overview", + "private": true, + "type": "module", + "scripts": { + "start": "tsx src/index.ts", + "check-types": "tsc --noEmit" + }, + "dependencies": { + "@rivet-dev/agentos-javascript": "workspace:*" + }, + "devDependencies": { + "@types/node": "^22.10.2", + "tsx": "^4.19.2", + "typescript": "^5.7.2" + } +} diff --git a/examples/exec-js-sdk-overview/src/index.ts b/examples/exec-js-sdk-overview/src/index.ts new file mode 100644 index 0000000000..8cd616f33b --- /dev/null +++ b/examples/exec-js-sdk-overview/src/index.ts @@ -0,0 +1,28 @@ +// docs:start imports +import { JavaScriptRuntime } from "@rivet-dev/agentos-javascript"; +// docs:end imports + +const javascript = await JavaScriptRuntime.create({ + cwd: "/workspace", + env: { GREETING: "hello from the VM" }, +}); + +try { + const execution = await javascript.execute(` + console.log(process.env.GREETING); + console.error("stderr is captured separately"); + `); + console.log(execution); + + const evaluation = await javascript.evaluate<{ sum: number; cwd: string }>( + `({ sum: 2 + 40, cwd: process.cwd() })`, + ); + console.log(evaluation); + + const typed = await javascript.typescript.evaluate( + `Promise.resolve(21 * 2 satisfies number)`, + ); + console.log(typed); +} finally { + await javascript.dispose(); +} diff --git a/examples/exec-js-sdk-overview/tsconfig.json b/examples/exec-js-sdk-overview/tsconfig.json new file mode 100644 index 0000000000..ec30112241 --- /dev/null +++ b/examples/exec-js-sdk-overview/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "noEmit": true, + "rootDir": "./src" + }, + "include": ["src/**/*"], + "exclude": ["node_modules"] +} diff --git a/examples/exec-js-typescript/package.json b/examples/exec-js-typescript/package.json new file mode 100644 index 0000000000..c76b9d213e --- /dev/null +++ b/examples/exec-js-typescript/package.json @@ -0,0 +1,17 @@ +{ + "name": "@rivet-dev/agentos-example-exec-js-typescript", + "private": true, + "type": "module", + "scripts": { + "start": "tsx src/index.ts", + "check-types": "tsc --noEmit" + }, + "dependencies": { + "@rivet-dev/agentos-javascript": "workspace:*", + "typescript": "^5.7.2" + }, + "devDependencies": { + "@types/node": "^22.10.2", + "tsx": "^4.19.2" + } +} diff --git a/examples/exec-js-typescript/src/index.ts b/examples/exec-js-typescript/src/index.ts new file mode 100644 index 0000000000..9f91f7e4ee --- /dev/null +++ b/examples/exec-js-typescript/src/index.ts @@ -0,0 +1,68 @@ +/** + * TypeScript example. + * + * `@rivet-dev/agentos-javascript` runs the TypeScript compiler INSIDE the VM. + * The compiler is projected into the VM and every compile/type-check happens + * in the guest, so untrusted TypeScript never executes (or compiles) on the + * host. Here we compile a typed snippet to JavaScript, run the emitted code in + * the VM, and type-check a snippet that has a type error. + */ +import { JavaScriptRuntime } from "@rivet-dev/agentos-javascript"; + +// A typed snippet we want to compile and run inside the VM. +const typeScriptSource = ` +interface Greeting { + name: string; + count: number; +} + +const greeting: Greeting = { name: "agentos", count: 3 }; +const lines: string[] = Array.from( + { length: greeting.count }, + (_unused, index) => \`hello \${greeting.name} #\${index + 1}\`, +); + +for (const line of lines) { + console.log(line); +} +`; + +// Step 1: compile TypeScript to JavaScript inside the VM. +const rt = await JavaScriptRuntime.create(); +try { + const compiled = await rt.typescript.compile(typeScriptSource, { + compilerOptions: { module: "ESNext", target: "ES2022" }, + }); + + if (!compiled.success) { + const messages = compiled.diagnostics.map((d) => d.message); + throw new Error(`TypeScript compile failed:\n${messages.join("\n")}`); + } + + console.log("Compiled TypeScript to JavaScript inside the VM."); + + // Step 2: run the emitted JavaScript inside the VM. + const result = await rt.execute(compiled.outputText ?? ""); + console.log("exitCode:", result.exitCode); + console.log("guest stdout:\n" + result.stdout.trimEnd()); + + // Step 3: type-check a snippet that has a type error inside the VM. + const typeCheck = await rt.typescript.check( + `const total: number = "not a number";`, + ); + + console.log("type check success:", typeCheck.success); + for (const diagnostic of typeCheck.diagnostics) { + console.log( + ` ${diagnostic.category} TS${diagnostic.code} (line ${diagnostic.line}): ${diagnostic.message}`, + ); + } + + if (typeCheck.success) { + throw new Error("Expected the ill-typed snippet to fail type checking."); + } + + console.log("OK: TypeScript compiled and type-checked inside the VM."); +} finally { + await rt.dispose(); +} diff --git a/examples/exec-js-typescript/tsconfig.json b/examples/exec-js-typescript/tsconfig.json new file mode 100644 index 0000000000..ec30112241 --- /dev/null +++ b/examples/exec-js-typescript/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "noEmit": true, + "rootDir": "./src" + }, + "include": ["src/**/*"], + "exclude": ["node_modules"] +} diff --git a/examples/exec-js-virtual-filesystem/package.json b/examples/exec-js-virtual-filesystem/package.json new file mode 100644 index 0000000000..2bd8ca9df2 --- /dev/null +++ b/examples/exec-js-virtual-filesystem/package.json @@ -0,0 +1,17 @@ +{ + "name": "@rivet-dev/agentos-example-exec-js-virtual-filesystem", + "private": true, + "type": "module", + "scripts": { + "start": "tsx src/index.ts", + "check-types": "tsc --noEmit" + }, + "dependencies": { + "@rivet-dev/agentos-javascript": "workspace:*" + }, + "devDependencies": { + "@types/node": "^22.10.2", + "tsx": "^4.19.2", + "typescript": "^5.7.2" + } +} diff --git a/examples/exec-js-virtual-filesystem/src/index.ts b/examples/exec-js-virtual-filesystem/src/index.ts new file mode 100644 index 0000000000..f8a812fb40 --- /dev/null +++ b/examples/exec-js-virtual-filesystem/src/index.ts @@ -0,0 +1,23 @@ +import { JavaScriptRuntime } from "@rivet-dev/agentos-javascript"; + +const runtime = await JavaScriptRuntime.create({ + files: { "/workspace/seed.json": JSON.stringify({ ok: true }) }, +}); + +try { + await runtime.vm.writeFile("/workspace/note.txt", "written from the host\n"); + const result = await runtime.evaluate<{ ok: boolean; note: string }>(` + (async () => { + const { readFile } = await import("node:fs/promises"); + const seed = JSON.parse(await readFile("/workspace/seed.json", "utf8")); + const note = (await readFile("/workspace/note.txt", "utf8")).trim(); + return { ok: seed.ok, note }; + })() + `); + console.log(result); + + const bytes = await runtime.vm.readFile("/workspace/seed.json"); + console.log(new TextDecoder().decode(bytes)); +} finally { + await runtime.dispose(); +} diff --git a/examples/exec-js-virtual-filesystem/tsconfig.json b/examples/exec-js-virtual-filesystem/tsconfig.json new file mode 100644 index 0000000000..ec30112241 --- /dev/null +++ b/examples/exec-js-virtual-filesystem/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "noEmit": true, + "rootDir": "./src" + }, + "include": ["src/**/*"], + "exclude": ["node_modules"] +} diff --git a/examples/exec-python-quickstart/package.json b/examples/exec-python-quickstart/package.json new file mode 100644 index 0000000000..0fd39f323a --- /dev/null +++ b/examples/exec-python-quickstart/package.json @@ -0,0 +1,17 @@ +{ + "name": "@rivet-dev/agentos-example-exec-python-quickstart", + "private": true, + "type": "module", + "scripts": { + "start": "tsx src/index.ts", + "check-types": "tsc --noEmit" + }, + "dependencies": { + "@rivet-dev/agentos-python": "workspace:*" + }, + "devDependencies": { + "@types/node": "^22.10.2", + "tsx": "^4.19.2", + "typescript": "^5.7.2" + } +} diff --git a/examples/exec-python-quickstart/src/index.ts b/examples/exec-python-quickstart/src/index.ts new file mode 100644 index 0000000000..15e69a7008 --- /dev/null +++ b/examples/exec-python-quickstart/src/index.ts @@ -0,0 +1,12 @@ +import { PythonRuntime } from "@rivet-dev/agentos-python"; + +// docs:start python +const runtime = await PythonRuntime.create(); + +try { + const result = await runtime.evaluate("21 * 2"); + console.log(result.success ? result.value : result.error); +} finally { + await runtime.dispose(); +} +// docs:end python diff --git a/examples/exec-python-quickstart/tsconfig.json b/examples/exec-python-quickstart/tsconfig.json new file mode 100644 index 0000000000..ec30112241 --- /dev/null +++ b/examples/exec-python-quickstart/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "noEmit": true, + "rootDir": "./src" + }, + "include": ["src/**/*"], + "exclude": ["node_modules"] +} diff --git a/examples/exec-python-sdk-overview/package.json b/examples/exec-python-sdk-overview/package.json new file mode 100644 index 0000000000..95a9ddf3f3 --- /dev/null +++ b/examples/exec-python-sdk-overview/package.json @@ -0,0 +1,17 @@ +{ + "name": "@rivet-dev/agentos-example-exec-python-sdk-overview", + "private": true, + "type": "module", + "scripts": { + "start": "tsx src/index.ts", + "check-types": "tsc --noEmit" + }, + "dependencies": { + "@rivet-dev/agentos-python": "workspace:*" + }, + "devDependencies": { + "@types/node": "^22.10.2", + "tsx": "^4.19.2", + "typescript": "^5.7.2" + } +} diff --git a/examples/exec-python-sdk-overview/src/index.ts b/examples/exec-python-sdk-overview/src/index.ts new file mode 100644 index 0000000000..d36311a3c0 --- /dev/null +++ b/examples/exec-python-sdk-overview/src/index.ts @@ -0,0 +1,29 @@ +// docs:start overview +// docs:start imports +import { PythonRuntime } from "@rivet-dev/agentos-python"; + +// docs:end imports + +const python = await PythonRuntime.create({ + cwd: "/workspace", + env: { GREETING: "hello from the VM" }, +}); + +try { + const execution = await python.execute(` +import os +import sys + +print(os.environ["GREETING"]) +print("stderr is captured separately", file=sys.stderr) + `); + console.log(execution); + + const evaluation = await python.evaluate<{ sum: number; cwd: string }>( + `{"sum": 2 + 40, "cwd": __import__("os").getcwd()}`, + ); + console.log(evaluation); +} finally { + await python.dispose(); +} +// docs:end overview diff --git a/examples/exec-python-sdk-overview/src/packages.ts b/examples/exec-python-sdk-overview/src/packages.ts new file mode 100644 index 0000000000..f49a9bdf01 --- /dev/null +++ b/examples/exec-python-sdk-overview/src/packages.ts @@ -0,0 +1,15 @@ +import { PythonRuntime } from "@rivet-dev/agentos-python"; + +const runtime = await PythonRuntime.create(); +try { + const installed = await runtime.install(["requests"], { upgrade: true }); + if (!installed.success) throw new Error(installed.stderr); + + const result = await runtime.execute(` +import requests +print(requests.__version__) + `); + if (!result.success) throw new Error(result.stderr); +} finally { + await runtime.dispose(); +} diff --git a/examples/exec-python-sdk-overview/tsconfig.json b/examples/exec-python-sdk-overview/tsconfig.json new file mode 100644 index 0000000000..ec30112241 --- /dev/null +++ b/examples/exec-python-sdk-overview/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "noEmit": true, + "rootDir": "./src" + }, + "include": ["src/**/*"], + "exclude": ["node_modules"] +} diff --git a/examples/filesystem/mount-custom-vfs.ts b/examples/filesystem/mount-custom-vfs.ts index 4d1b3b6f81..5646020cfd 100644 --- a/examples/filesystem/mount-custom-vfs.ts +++ b/examples/filesystem/mount-custom-vfs.ts @@ -1,4 +1,4 @@ -import { AgentOs } from "@rivet-dev/agentos-core"; +import { AgentOs } from "@rivet-dev/agentos"; const vm = await AgentOs.create({ defaultSoftware: false }); await vm.mountFs({ diff --git a/examples/filesystem/package.json b/examples/filesystem/package.json index f8e7878307..d508193e7a 100644 --- a/examples/filesystem/package.json +++ b/examples/filesystem/package.json @@ -7,7 +7,7 @@ "check-types": "tsc --noEmit" }, "dependencies": { - "@rivet-dev/agentos-core": "workspace:*", + "@rivet-dev/agentos": "workspace:*", "@rivet-dev/agentos-sandbox": "workspace:*", "sandbox-agent": "^0.4.2", "dockerode": "^4.0.9", diff --git a/examples/js-runtime/package.json b/examples/js-runtime/package.json index caccee91c3..30ac406970 100644 --- a/examples/js-runtime/package.json +++ b/examples/js-runtime/package.json @@ -7,7 +7,7 @@ "check-types": "tsc --noEmit" }, "dependencies": { - "@rivet-dev/agentos-core": "workspace:*", + "@rivet-dev/agentos": "workspace:*", "@rivet-dev/agentos-sandbox": "workspace:*", "sandbox-agent": "^0.4.2", "dockerode": "^4.0.9", diff --git a/examples/llm-credentials/package.json b/examples/llm-credentials/package.json index ba23a70e54..340ea1d355 100644 --- a/examples/llm-credentials/package.json +++ b/examples/llm-credentials/package.json @@ -7,7 +7,7 @@ "check-types": "tsc --noEmit" }, "dependencies": { - "@rivet-dev/agentos-core": "workspace:*", + "@rivet-dev/agentos": "workspace:*", "@rivet-dev/agentos-sandbox": "workspace:*", "sandbox-agent": "^0.4.2", "dockerode": "^4.0.9", diff --git a/examples/multiplayer/package.json b/examples/multiplayer/package.json index c492ddc6f9..b71a87b8d3 100644 --- a/examples/multiplayer/package.json +++ b/examples/multiplayer/package.json @@ -7,7 +7,7 @@ "check-types": "tsc --noEmit" }, "dependencies": { - "@rivet-dev/agentos-core": "workspace:*", + "@rivet-dev/agentos": "workspace:*", "@rivet-dev/agentos-sandbox": "workspace:*", "sandbox-agent": "^0.4.2", "dockerode": "^4.0.9", diff --git a/examples/networking/package.json b/examples/networking/package.json index 162f40dc05..eb25fff7f7 100644 --- a/examples/networking/package.json +++ b/examples/networking/package.json @@ -7,7 +7,7 @@ "check-types": "tsc --noEmit" }, "dependencies": { - "@rivet-dev/agentos-core": "workspace:*", + "@rivet-dev/agentos": "workspace:*", "@rivet-dev/agentos-sandbox": "workspace:*", "sandbox-agent": "^0.4.2", "dockerode": "^4.0.9", diff --git a/examples/opencode/package.json b/examples/opencode/package.json index 62af3e00f8..e31d4e165f 100644 --- a/examples/opencode/package.json +++ b/examples/opencode/package.json @@ -7,7 +7,7 @@ "check-types": "tsc --noEmit" }, "dependencies": { - "@rivet-dev/agentos-core": "workspace:*", + "@rivet-dev/agentos": "workspace:*", "@rivet-dev/agentos-sandbox": "workspace:*", "sandbox-agent": "^0.4.2", "dockerode": "^4.0.9", diff --git a/examples/permissions/combine.ts b/examples/permissions/combine.ts index 391f3edac6..f0fe2b2018 100644 --- a/examples/permissions/combine.ts +++ b/examples/permissions/combine.ts @@ -1,5 +1,5 @@ import { agentOS, setup } from "@rivet-dev/agentos"; -import type { Permissions } from "@rivet-dev/agentos-core"; +import type { Permissions } from "@rivet-dev/agentos"; // Allow the filesystem everywhere, but deny anything under /home/agentos/vault. const denyVault = { diff --git a/examples/permissions/fs-rules.ts b/examples/permissions/fs-rules.ts index f1eae4d286..5883c40128 100644 --- a/examples/permissions/fs-rules.ts +++ b/examples/permissions/fs-rules.ts @@ -1,5 +1,5 @@ import { agentOS, setup } from "@rivet-dev/agentos"; -import type { Permissions } from "@rivet-dev/agentos-core"; +import type { Permissions } from "@rivet-dev/agentos"; // docs:start deny-vault // Allow the filesystem everywhere, but deny anything under /home/agentos/vault. diff --git a/examples/permissions/package.json b/examples/permissions/package.json index 48668ab2b3..2ae34984ef 100644 --- a/examples/permissions/package.json +++ b/examples/permissions/package.json @@ -7,7 +7,7 @@ "check-types": "tsc --noEmit" }, "dependencies": { - "@rivet-dev/agentos-core": "workspace:*", + "@rivet-dev/agentos": "workspace:*", "@rivet-dev/agentos-sandbox": "workspace:*", "sandbox-agent": "^0.4.2", "dockerode": "^4.0.9", diff --git a/examples/permissions/server.ts b/examples/permissions/server.ts index 1289562340..f429690da0 100644 --- a/examples/permissions/server.ts +++ b/examples/permissions/server.ts @@ -1,5 +1,5 @@ import { agentOS, setup } from "@rivet-dev/agentos"; -import type { Permissions } from "@rivet-dev/agentos-core"; +import type { Permissions } from "@rivet-dev/agentos"; // docs:start grant-network // Grant the network, leave everything else at the secure default. diff --git a/examples/persistence/package.json b/examples/persistence/package.json index 6c5b20d887..bef232cd69 100644 --- a/examples/persistence/package.json +++ b/examples/persistence/package.json @@ -7,7 +7,7 @@ "check-types": "tsc --noEmit" }, "dependencies": { - "@rivet-dev/agentos-core": "workspace:*", + "@rivet-dev/agentos": "workspace:*", "@rivet-dev/agentos-sandbox": "workspace:*", "sandbox-agent": "^0.4.2", "dockerode": "^4.0.9", diff --git a/examples/pi/package.json b/examples/pi/package.json index 4784c43ce0..209dfe7940 100644 --- a/examples/pi/package.json +++ b/examples/pi/package.json @@ -7,7 +7,7 @@ "check-types": "tsc --noEmit" }, "dependencies": { - "@rivet-dev/agentos-core": "workspace:*", + "@rivet-dev/agentos": "workspace:*", "@rivet-dev/agentos-sandbox": "workspace:*", "sandbox-agent": "^0.4.2", "dockerode": "^4.0.9", diff --git a/examples/processes/package.json b/examples/processes/package.json index 42eb78fd0f..b45506357c 100644 --- a/examples/processes/package.json +++ b/examples/processes/package.json @@ -7,7 +7,7 @@ "check-types": "tsc --noEmit" }, "dependencies": { - "@rivet-dev/agentos-core": "workspace:*", + "@rivet-dev/agentos": "workspace:*", "@rivet-dev/agentos-sandbox": "workspace:*", "sandbox-agent": "^0.4.2", "dockerode": "^4.0.9", diff --git a/examples/quickstart-app/package.json b/examples/quickstart-app/package.json index 28ff0c9a62..0272be7558 100644 --- a/examples/quickstart-app/package.json +++ b/examples/quickstart-app/package.json @@ -7,7 +7,7 @@ "check-types": "tsc --noEmit" }, "dependencies": { - "@rivet-dev/agentos-core": "workspace:*", + "@rivet-dev/agentos": "workspace:*", "@rivet-dev/agentos-sandbox": "workspace:*", "sandbox-agent": "^0.4.2", "dockerode": "^4.0.9", diff --git a/examples/quickstart/agent-session/index.ts b/examples/quickstart/agent-session/index.ts index 37c57c2888..6104c205a9 100644 --- a/examples/quickstart/agent-session/index.ts +++ b/examples/quickstart/agent-session/index.ts @@ -4,8 +4,8 @@ // agent runtime. It may not complete in all environments. import claude from "@agentos-software/claude-code"; -import type { SoftwareInput } from "@rivet-dev/agentos-core"; -import { AgentOs } from "@rivet-dev/agentos-core"; +import type { SoftwareInput } from "@rivet-dev/agentos"; +import { AgentOs } from "@rivet-dev/agentos"; import opencode from "@agentos-software/opencode"; import pi from "@agentos-software/pi"; diff --git a/examples/quickstart/agent-session/package.json b/examples/quickstart/agent-session/package.json index a4268b28d5..6aa698f771 100644 --- a/examples/quickstart/agent-session/package.json +++ b/examples/quickstart/agent-session/package.json @@ -8,7 +8,7 @@ "check-types": "tsc --noEmit" }, "dependencies": { - "@rivet-dev/agentos-core": "workspace:*", + "@rivet-dev/agentos": "workspace:*", "@rivet-dev/agentos-sandbox": "workspace:*", "sandbox-agent": "^0.4.2", "dockerode": "^4.0.9", diff --git a/examples/quickstart/bash/index.ts b/examples/quickstart/bash/index.ts index 4922fd5828..a715cb0ffc 100644 --- a/examples/quickstart/bash/index.ts +++ b/examples/quickstart/bash/index.ts @@ -1,6 +1,6 @@ // Run shell commands inside the VM. -import { AgentOs } from "@rivet-dev/agentos-core"; +import { AgentOs } from "@rivet-dev/agentos"; const vm = await AgentOs.create(); diff --git a/examples/quickstart/bash/package.json b/examples/quickstart/bash/package.json index 0418a5426f..c47762b996 100644 --- a/examples/quickstart/bash/package.json +++ b/examples/quickstart/bash/package.json @@ -8,7 +8,7 @@ "check-types": "tsc --noEmit" }, "dependencies": { - "@rivet-dev/agentos-core": "workspace:*", + "@rivet-dev/agentos": "workspace:*", "@rivet-dev/agentos-sandbox": "workspace:*", "sandbox-agent": "^0.4.2", "dockerode": "^4.0.9", diff --git a/examples/quickstart/bindings/index.ts b/examples/quickstart/bindings/index.ts index d43d29de42..51d5e46822 100644 --- a/examples/quickstart/bindings/index.ts +++ b/examples/quickstart/bindings/index.ts @@ -1,4 +1,4 @@ -import { AgentOs, binding, bindings } from "@rivet-dev/agentos-core"; +import { AgentOs, binding, bindings } from "@rivet-dev/agentos"; import { z } from "zod"; const weatherBindings = bindings({ diff --git a/examples/quickstart/bindings/package.json b/examples/quickstart/bindings/package.json index 6fe9f34e69..dbcd29586e 100644 --- a/examples/quickstart/bindings/package.json +++ b/examples/quickstart/bindings/package.json @@ -8,7 +8,7 @@ "check-types": "tsc --noEmit" }, "dependencies": { - "@rivet-dev/agentos-core": "workspace:*", + "@rivet-dev/agentos": "workspace:*", "zod": "^4.1.11" }, "devDependencies": { diff --git a/examples/quickstart/cron/index.ts b/examples/quickstart/cron/index.ts index 206fb2bf60..9bbb55a011 100644 --- a/examples/quickstart/cron/index.ts +++ b/examples/quickstart/cron/index.ts @@ -1,6 +1,6 @@ // Cron scheduling: schedule recurring commands inside the VM. -import { AgentOs } from "@rivet-dev/agentos-core"; +import { AgentOs } from "@rivet-dev/agentos"; const vm = await AgentOs.create(); diff --git a/examples/quickstart/cron/package.json b/examples/quickstart/cron/package.json index 191fa0fa03..9d6f05fe1d 100644 --- a/examples/quickstart/cron/package.json +++ b/examples/quickstart/cron/package.json @@ -8,7 +8,7 @@ "check-types": "tsc --noEmit" }, "dependencies": { - "@rivet-dev/agentos-core": "workspace:*", + "@rivet-dev/agentos": "workspace:*", "@rivet-dev/agentos-sandbox": "workspace:*", "sandbox-agent": "^0.4.2", "dockerode": "^4.0.9", diff --git a/examples/quickstart/filesystem/index.ts b/examples/quickstart/filesystem/index.ts index 2b9c09f01c..e63038b326 100644 --- a/examples/quickstart/filesystem/index.ts +++ b/examples/quickstart/filesystem/index.ts @@ -10,7 +10,7 @@ // }], // }); -import { AgentOs } from "@rivet-dev/agentos-core"; +import { AgentOs } from "@rivet-dev/agentos"; const vm = await AgentOs.create(); diff --git a/examples/quickstart/filesystem/package.json b/examples/quickstart/filesystem/package.json index be67508a7d..841256ba42 100644 --- a/examples/quickstart/filesystem/package.json +++ b/examples/quickstart/filesystem/package.json @@ -8,7 +8,7 @@ "check-types": "tsc --noEmit" }, "dependencies": { - "@rivet-dev/agentos-core": "workspace:*", + "@rivet-dev/agentos": "workspace:*", "@rivet-dev/agentos-sandbox": "workspace:*", "sandbox-agent": "^0.4.2", "dockerode": "^4.0.9", diff --git a/examples/quickstart/git/index.ts b/examples/quickstart/git/index.ts index d52f3f9181..41c4e4f267 100644 --- a/examples/quickstart/git/index.ts +++ b/examples/quickstart/git/index.ts @@ -2,7 +2,7 @@ import { createRequire } from "node:module"; import { dirname, resolve } from "node:path"; -import { AgentOs } from "@rivet-dev/agentos-core"; +import { AgentOs } from "@rivet-dev/agentos"; import git from "@agentos-software/git"; type ExecResult = { @@ -13,7 +13,7 @@ type ExecResult = { const require = createRequire(import.meta.url); const MODULE_ACCESS_CWD = resolve( - dirname(require.resolve("@rivet-dev/agentos-core")), + dirname(require.resolve("@rivet-dev/agentos")), "..", ); const GIT_QUICKSTART_PERMISSIONS = { diff --git a/examples/quickstart/git/package.json b/examples/quickstart/git/package.json index 4a2657c150..43dbaaffb0 100644 --- a/examples/quickstart/git/package.json +++ b/examples/quickstart/git/package.json @@ -8,7 +8,7 @@ "check-types": "tsc --noEmit" }, "dependencies": { - "@rivet-dev/agentos-core": "workspace:*", + "@rivet-dev/agentos": "workspace:*", "@rivet-dev/agentos-sandbox": "workspace:*", "sandbox-agent": "^0.4.2", "dockerode": "^4.0.9", diff --git a/examples/quickstart/hello-world/README.md b/examples/quickstart/hello-world/README.md index 9a139c0053..547e020ed1 100644 --- a/examples/quickstart/hello-world/README.md +++ b/examples/quickstart/hello-world/README.md @@ -19,7 +19,7 @@ you are done, `dispose()` tears the VM down and releases its resources. ## Run it ```sh -npm install @rivet-dev/agentos-core +npm install @rivet-dev/agentos npx tsx index.ts ``` diff --git a/examples/quickstart/hello-world/index.ts b/examples/quickstart/hello-world/index.ts index f3523528f2..0e83c77ce9 100644 --- a/examples/quickstart/hello-world/index.ts +++ b/examples/quickstart/hello-world/index.ts @@ -1,6 +1,6 @@ // Minimal agentOS example: create a VM, write a file, read it back. -import { AgentOs } from "@rivet-dev/agentos-core"; +import { AgentOs } from "@rivet-dev/agentos"; const vm = await AgentOs.create(); diff --git a/examples/quickstart/hello-world/package.json b/examples/quickstart/hello-world/package.json index 510f2fc3ee..9b4d6774a0 100644 --- a/examples/quickstart/hello-world/package.json +++ b/examples/quickstart/hello-world/package.json @@ -8,7 +8,7 @@ "check-types": "tsc --noEmit" }, "dependencies": { - "@rivet-dev/agentos-core": "workspace:*", + "@rivet-dev/agentos": "workspace:*", "@rivet-dev/agentos-sandbox": "workspace:*", "sandbox-agent": "^0.4.2", "dockerode": "^4.0.9", diff --git a/examples/quickstart/network/README.md b/examples/quickstart/network/README.md index d8903379cc..cf9db5e3a5 100644 --- a/examples/quickstart/network/README.md +++ b/examples/quickstart/network/README.md @@ -13,7 +13,7 @@ Run a real HTTP server inside the VM and call it from your host code. Reach for Create a VM with `network` and `childProcess` permissions, then `writeFile` a small Node server script into the VM. `vm.spawn` launches it, and the server prints its bound port on stdout, which an `onProcessOutput` subscription parses out. With the port in hand, `vm.httpRequest({ port, path })` routes a buffered request to that in-VM server over localhost and returns the serializable `HttpResponse` DTO. Cleanup waits briefly on the process and disposes the VM. -> Preview URLs (`agent.createPreviewUrl`) live only in the RivetKit actor wrapper, not the core API — see `examples/networking/`. +> Preview URLs (`agent.createPreviewUrl`) live only in the RivetKit actor wrapper, not the direct VM API — see `examples/networking/`. ## Run it diff --git a/examples/quickstart/network/index.ts b/examples/quickstart/network/index.ts index e70a03d5eb..4b234eec35 100644 --- a/examples/quickstart/network/index.ts +++ b/examples/quickstart/network/index.ts @@ -2,9 +2,9 @@ // // vm.httpRequest() routes HTTP requests to services running inside the VM. // Note: Preview URLs (agent.createPreviewUrl) are only available in the -// RivetKit actor wrapper, not in the core API. See examples/agent-os/ for that. +// RivetKit actor wrapper, not in the direct VM API. See the actor examples for that. -import { AgentOs } from "@rivet-dev/agentos-core"; +import { AgentOs } from "@rivet-dev/agentos"; function settleWithin(promise: Promise, ms: number): Promise { return Promise.race([ diff --git a/examples/quickstart/network/package.json b/examples/quickstart/network/package.json index be0d14f360..0d869ce28a 100644 --- a/examples/quickstart/network/package.json +++ b/examples/quickstart/network/package.json @@ -8,7 +8,7 @@ "check-types": "tsc --noEmit" }, "dependencies": { - "@rivet-dev/agentos-core": "workspace:*", + "@rivet-dev/agentos": "workspace:*", "@rivet-dev/agentos-sandbox": "workspace:*", "sandbox-agent": "^0.4.2", "dockerode": "^4.0.9", diff --git a/examples/quickstart/nodejs/README.md b/examples/quickstart/nodejs/README.md index 3ab0750c12..e0f472035b 100644 --- a/examples/quickstart/nodejs/README.md +++ b/examples/quickstart/nodejs/README.md @@ -14,7 +14,7 @@ Create a VM with `AgentOs.create()`, then stage a script onto its filesystem wit ## Run it ```bash -npm install @rivet-dev/agentos-core +npm install @rivet-dev/agentos node index.ts ``` diff --git a/examples/quickstart/nodejs/index.ts b/examples/quickstart/nodejs/index.ts index 1415e4ae10..e8bafec3f2 100644 --- a/examples/quickstart/nodejs/index.ts +++ b/examples/quickstart/nodejs/index.ts @@ -1,6 +1,6 @@ // Run a Node.js script inside the VM that does filesystem operations. -import { AgentOs } from "@rivet-dev/agentos-core"; +import { AgentOs } from "@rivet-dev/agentos"; const vm = await AgentOs.create(); diff --git a/examples/quickstart/nodejs/package.json b/examples/quickstart/nodejs/package.json index c0242a2cc6..affdbd0ae8 100644 --- a/examples/quickstart/nodejs/package.json +++ b/examples/quickstart/nodejs/package.json @@ -8,7 +8,7 @@ "check-types": "tsc --noEmit" }, "dependencies": { - "@rivet-dev/agentos-core": "workspace:*", + "@rivet-dev/agentos": "workspace:*", "@rivet-dev/agentos-sandbox": "workspace:*", "sandbox-agent": "^0.4.2", "dockerode": "^4.0.9", diff --git a/examples/quickstart/package.json b/examples/quickstart/package.json index 0a5b0a7fd0..c52e28fa4b 100644 --- a/examples/quickstart/package.json +++ b/examples/quickstart/package.json @@ -22,7 +22,7 @@ "pi-extensions": "node --import tsx src/pi-extensions.ts" }, "dependencies": { - "@rivet-dev/agentos-core": "workspace:*", + "@rivet-dev/agentos": "workspace:*", "@rivet-dev/agentos-sandbox": "workspace:*", "sandbox-agent": "^0.4.2", "dockerode": "^4.0.9", diff --git a/examples/quickstart/pi-extensions/index.ts b/examples/quickstart/pi-extensions/index.ts index 68ff05351a..ce82e59f56 100644 --- a/examples/quickstart/pi-extensions/index.ts +++ b/examples/quickstart/pi-extensions/index.ts @@ -14,7 +14,7 @@ import { createRequire } from "node:module"; import { dirname, join, resolve } from "node:path"; -import { AgentOs, nodeModulesMount } from "@rivet-dev/agentos-core"; +import { AgentOs, nodeModulesMount } from "@rivet-dev/agentos"; import pi from "@agentos-software/pi"; const ANTHROPIC_API_KEY = process.env.ANTHROPIC_API_KEY; @@ -26,7 +26,7 @@ if (!ANTHROPIC_API_KEY) { const require = createRequire(import.meta.url); const MODULE_ACCESS_CWD = resolve( - dirname(require.resolve("@rivet-dev/agentos-core")), + dirname(require.resolve("@rivet-dev/agentos")), "..", ); const HOME_DIR = "/home/agentos"; diff --git a/examples/quickstart/pi-extensions/package.json b/examples/quickstart/pi-extensions/package.json index 992dc53488..1f5177e6e1 100644 --- a/examples/quickstart/pi-extensions/package.json +++ b/examples/quickstart/pi-extensions/package.json @@ -8,7 +8,7 @@ "check-types": "tsc --noEmit" }, "dependencies": { - "@rivet-dev/agentos-core": "workspace:*", + "@rivet-dev/agentos": "workspace:*", "@rivet-dev/agentos-sandbox": "workspace:*", "sandbox-agent": "^0.4.2", "dockerode": "^4.0.9", diff --git a/examples/quickstart/processes/index.ts b/examples/quickstart/processes/index.ts index b062d96265..17eb78acf0 100644 --- a/examples/quickstart/processes/index.ts +++ b/examples/quickstart/processes/index.ts @@ -1,6 +1,6 @@ // Execute commands and manage processes inside the VM. -import { AgentOs } from "@rivet-dev/agentos-core"; +import { AgentOs } from "@rivet-dev/agentos"; const vm = await AgentOs.create(); diff --git a/examples/quickstart/processes/package.json b/examples/quickstart/processes/package.json index 1112266fce..684303f658 100644 --- a/examples/quickstart/processes/package.json +++ b/examples/quickstart/processes/package.json @@ -8,7 +8,7 @@ "check-types": "tsc --noEmit" }, "dependencies": { - "@rivet-dev/agentos-core": "workspace:*", + "@rivet-dev/agentos": "workspace:*", "@rivet-dev/agentos-sandbox": "workspace:*", "sandbox-agent": "^0.4.2", "dockerode": "^4.0.9", diff --git a/examples/quickstart/s3-filesystem/README.md b/examples/quickstart/s3-filesystem/README.md index 2d942ea101..b8e7b472a3 100644 --- a/examples/quickstart/s3-filesystem/README.md +++ b/examples/quickstart/s3-filesystem/README.md @@ -9,7 +9,7 @@ Reach for this when you want a VM to read and write files that live in an S3-com ## How it works -A `chunked_s3` mount descriptor (built into `@rivet-dev/agentos-core`) configures an S3 plugin from a bucket, prefix, region, and credentials. Passing it as a mount at `/mnt/data` makes the VM treat the bucket as a normal directory, so `writeFile`, `readFile`, and `readdir` operate transparently against S3. Configure the real bucket through the `S3_*` environment variables; when they are absent the example boots a strict local S3 harness so the same flow still runs against signed requests. +A `chunked_s3` mount descriptor (built into `@rivet-dev/agentos`) configures an S3 plugin from a bucket, prefix, region, and credentials. Passing it as a mount at `/mnt/data` makes the VM treat the bucket as a normal directory, so `writeFile`, `readFile`, and `readdir` operate transparently against S3. Configure the real bucket through the `S3_*` environment variables; when they are absent the example boots a strict local S3 harness so the same flow still runs against signed requests. ## Run it diff --git a/examples/quickstart/s3-filesystem/index.ts b/examples/quickstart/s3-filesystem/index.ts index 538207906d..0834adc406 100644 --- a/examples/quickstart/s3-filesystem/index.ts +++ b/examples/quickstart/s3-filesystem/index.ts @@ -1,6 +1,6 @@ // S3 File System: mount an S3 bucket and use it like a local filesystem. // -// S3 mounting is built into @rivet-dev/agentos-core: pass a `chunked_s3` +// S3 mounting is built into @rivet-dev/agentos: pass a `chunked_s3` // mount descriptor to AgentOs.create({ mounts }) and the VM treats the bucket // as a normal directory, so writeFile/readFile/readdir operate transparently // against S3. @@ -16,8 +16,8 @@ // S3 harness so `pnpm --dir examples/quickstart/s3-filesystem start` // still exercises the real quickstart flow against signed S3 requests. -import { AgentOs } from "@rivet-dev/agentos-core"; -import type { MountConfigJsonObject } from "@rivet-dev/agentos-core"; +import { AgentOs } from "@rivet-dev/agentos"; +import type { MountConfigJsonObject } from "@rivet-dev/agentos"; import type { MockS3ServerHandle } from "../../../packages/core/src/test/mock-s3.js"; import { startMockS3Server } from "../../../packages/core/src/test/mock-s3.js"; diff --git a/examples/quickstart/s3-filesystem/package.json b/examples/quickstart/s3-filesystem/package.json index b37b817112..a4ea464b79 100644 --- a/examples/quickstart/s3-filesystem/package.json +++ b/examples/quickstart/s3-filesystem/package.json @@ -8,7 +8,7 @@ "check-types": "tsc --noEmit" }, "dependencies": { - "@rivet-dev/agentos-core": "workspace:*", + "@rivet-dev/agentos": "workspace:*", "@rivet-dev/agentos-sandbox": "workspace:*", "sandbox-agent": "^0.4.2", "dockerode": "^4.0.9", diff --git a/examples/quickstart/sandbox/index.ts b/examples/quickstart/sandbox/index.ts index 098de9652c..e8eb3fb705 100644 --- a/examples/quickstart/sandbox/index.ts +++ b/examples/quickstart/sandbox/index.ts @@ -3,7 +3,7 @@ // Requires Docker. Starts a sandbox-agent container, mounts its filesystem // at /mnt/sandbox, and registers sandbox bindings for running commands. -import { AgentOs } from "@rivet-dev/agentos-core"; +import { AgentOs } from "@rivet-dev/agentos"; import { createSandboxFs, createSandboxBindings, diff --git a/examples/quickstart/sandbox/package.json b/examples/quickstart/sandbox/package.json index f6748504ba..8e6556ce75 100644 --- a/examples/quickstart/sandbox/package.json +++ b/examples/quickstart/sandbox/package.json @@ -8,7 +8,7 @@ "check-types": "tsc --noEmit" }, "dependencies": { - "@rivet-dev/agentos-core": "workspace:*", + "@rivet-dev/agentos": "workspace:*", "@rivet-dev/agentos-sandbox": "workspace:*", "sandbox-agent": "^0.4.2", "dockerode": "^4.0.9", diff --git a/examples/resource-limits/package.json b/examples/resource-limits/package.json index 2014e284d4..f209169840 100644 --- a/examples/resource-limits/package.json +++ b/examples/resource-limits/package.json @@ -7,7 +7,7 @@ "check-types": "tsc --noEmit" }, "dependencies": { - "@rivet-dev/agentos-core": "workspace:*", + "@rivet-dev/agentos": "workspace:*", "@rivet-dev/agentos-sandbox": "workspace:*", "sandbox-agent": "^0.4.2", "dockerode": "^4.0.9", diff --git a/examples/sandbox/package.json b/examples/sandbox/package.json index 524f852e6a..b0c1e1e911 100644 --- a/examples/sandbox/package.json +++ b/examples/sandbox/package.json @@ -7,7 +7,7 @@ "check-types": "tsc --noEmit" }, "dependencies": { - "@rivet-dev/agentos-core": "workspace:*", + "@rivet-dev/agentos": "workspace:*", "@rivet-dev/agentos-sandbox": "workspace:*", "sandbox-agent": "^0.4.2", "dockerode": "^4.0.9", diff --git a/examples/sessions/package.json b/examples/sessions/package.json index 4ee1806cb2..27fe5c7164 100644 --- a/examples/sessions/package.json +++ b/examples/sessions/package.json @@ -7,7 +7,7 @@ "check-types": "tsc --noEmit" }, "dependencies": { - "@rivet-dev/agentos-core": "workspace:*", + "@rivet-dev/agentos": "workspace:*", "@rivet-dev/agentos-sandbox": "workspace:*", "sandbox-agent": "^0.4.2", "dockerode": "^4.0.9", diff --git a/examples/software/package.json b/examples/software/package.json index bef55b1aba..e8a2c2a1a7 100644 --- a/examples/software/package.json +++ b/examples/software/package.json @@ -7,7 +7,7 @@ "check-types": "tsc --noEmit" }, "dependencies": { - "@rivet-dev/agentos-core": "workspace:*", + "@rivet-dev/agentos": "workspace:*", "@rivet-dev/agentos-sandbox": "workspace:*", "sandbox-agent": "^0.4.2", "dockerode": "^4.0.9", diff --git a/examples/webhooks/package.json b/examples/webhooks/package.json index 6b6ce524d6..3cac521c6e 100644 --- a/examples/webhooks/package.json +++ b/examples/webhooks/package.json @@ -6,7 +6,7 @@ "scripts": { "check-types": "tsc --noEmit" }, "dependencies": { "@rivet-dev/agentos": "workspace:*", - "@rivet-dev/agentos-core": "workspace:*", + "@rivet-dev/agentos": "workspace:*", "@rivet-dev/agentos-sandbox": "workspace:*", "rivetkit": "catalog:rivetkit", "hono": "^4.6.0", diff --git a/examples/workflows/package.json b/examples/workflows/package.json index 5bcd5cfa82..2b50795386 100644 --- a/examples/workflows/package.json +++ b/examples/workflows/package.json @@ -7,7 +7,7 @@ "check-types": "tsc --noEmit" }, "dependencies": { - "@rivet-dev/agentos-core": "workspace:*", + "@rivet-dev/agentos": "workspace:*", "@rivet-dev/agentos-sandbox": "workspace:*", "sandbox-agent": "^0.4.2", "dockerode": "^4.0.9", diff --git a/experiments/gigacode/GOOSE_MIGRATION_PLAN.md b/experiments/gigacode/GOOSE_MIGRATION_PLAN.md index 0f9f02a2c9..8b0d8365a9 100644 --- a/experiments/gigacode/GOOSE_MIGRATION_PLAN.md +++ b/experiments/gigacode/GOOSE_MIGRATION_PLAN.md @@ -180,8 +180,8 @@ Delete OpenCode product functionality and references, including: - Gigacode compatibility routes, state projections, imports, launcher logic, installer repair, environment variables, and documentation. -Regenerate derived website/registry output and the secure-exec compatibility -mirror when affected public surfaces require it. Do not remove unrelated words +Regenerate derived website and registry output when affected public surfaces +require it. Do not remove unrelated words that merely contain the character sequence `opencode` unless they refer to the OpenCode product. @@ -465,7 +465,7 @@ Repository-wide removal criteria: - No runtime, client, website, example, installer, publish, or documentation surface references the OpenCode product. The migration specification is the only allowed historical reference. -- Generated website/registry artifacts and the secure-exec mirror are current. +- Generated website and registry artifacts are current. Goose/Gigacode criteria: diff --git a/packages/CLAUDE.md b/packages/CLAUDE.md index e3cfd51383..0159d1cd41 100644 --- a/packages/CLAUDE.md +++ b/packages/CLAUDE.md @@ -1,8 +1,11 @@ # agentOS Packages - Client packages must stay same-version with the sidecar: assert the single protocol version integer, and do not add wire back-compat, runtime negotiation, or converters. -- Generated client layers return raw generated protocol types; the `AgentOs` facade in `@rivet-dev/agentos-core` is the only sanctioned ergonomic wrapper. -- Generic secure-exec clients must stay agent-agnostic and must not branch on the Agent OS ACP namespace. -- secure-exec packages must never depend on agent-os packages; dependency direction is strictly agent-os to secure-exec and must be CI-enforced after the split. +- Generated client layers return raw generated protocol types; the `AgentOs` + facade is implemented in `@rivet-dev/agentos-core` and publicly exported from + `@rivet-dev/agentos`. User-facing docs and examples must import the public + package, not the internal core package. +- Generic agentos clients must stay agent-agnostic and must not branch on the Agent OS ACP namespace. +- agentos packages must never depend on agent-os packages; dependency direction is strictly agent-os to agentos and must be CI-enforced after the split. - The sidecar remains the source of truth for runtime behavior; TypeScript package code should forward generated requests instead of reimplementing sidecar state machines. - Cron and agent configuration types are Rust-owned after the split; TypeScript packages may re-export or mirror them only in lockstep. diff --git a/packages/agentos-toolchain/README.md b/packages/agentos-toolchain/README.md index bcf549ae60..566eb39182 100644 --- a/packages/agentos-toolchain/README.md +++ b/packages/agentos-toolchain/README.md @@ -7,10 +7,10 @@ package or a local script into a valid, self-contained agentOS package. npx @rivet-dev/agentos-toolchain pack [options] ``` -## Why this lives in secure-exec +## Why this lives in agentos -**Packaging is part of secure-exec's core behavior, so the tool that produces -packages lives here, next to the things it packages.** secure-exec owns the VM +**Packaging is part of agentos's core behavior, so the tool that produces +packages lives here, next to the things it packages.** agentos owns the VM runtime that *runs* packages — the kernel, the VFS, the `/opt/agentos` mount, the `$PATH` command resolver, and the header/`binfmt` dispatch — and it owns the package **definitions** themselves: the generic registry software (`software/*`) diff --git a/packages/agentos/package.json b/packages/agentos/package.json index 972af72ef8..87de11445c 100644 --- a/packages/agentos/package.json +++ b/packages/agentos/package.json @@ -1,7 +1,7 @@ { "name": "@rivet-dev/agentos", "version": "0.0.1", - "description": "A native TypeScript RivetKit actor backed by the AgentOS core SDK and sidecar.", + "description": "The AgentOS actor and orchestration SDK.", "license": "Apache-2.0", "keywords": [ "rivetkit", diff --git a/packages/agentos/src/index.ts b/packages/agentos/src/index.ts index 73d17afeec..b8f4ae9c51 100644 --- a/packages/agentos/src/index.ts +++ b/packages/agentos/src/index.ts @@ -16,26 +16,7 @@ export const setup: typeof rivetkitSetup = (( experimentalActorUds: true, } as Parameters[0])) as typeof rivetkitSetup; -export type { - AgentOsOptions, - DirEntry, - DynamicMountDescriptor, - ExportRootFilesystemOptions, - HttpRequest, - HttpResponse, - MountInfo, - NodeModulesMountConfig, - PackageDescriptor, - ProcessExit, - ProcessOutput, - PromptResult, - ReaddirEntry, - RootSnapshotExport, - SessionInfo, - ShellData, - ShellExit, -} from "@rivet-dev/agentos-core"; -export { defineSoftware, nodeModulesMount } from "@rivet-dev/agentos-core"; +export * from "@rivet-dev/agentos-core"; export type { AgentOsActorConfigInput as AgentOSActorConfigInput, AgentOsActorConfigInput as AgentOSConfigInput, diff --git a/packages/agentos/src/inspector-tabs/lib/actor-client.ts b/packages/agentos/src/inspector-tabs/lib/actor-client.ts index 99962cc799..e3d879ba7a 100644 --- a/packages/agentos/src/inspector-tabs/lib/actor-client.ts +++ b/packages/agentos/src/inspector-tabs/lib/actor-client.ts @@ -40,7 +40,9 @@ export interface ActionError { function getHandle(): Any { if (!client || !actorId) { - throw new Error("not initialized: rivet client unset (missing )"); + throw new Error( + "not initialized: rivet client unset (missing )", + ); } if (!handle) handle = client.getForId(INSPECTOR_ACTOR_NAME, actorId); return handle; @@ -60,7 +62,9 @@ export async function callAction( ): Promise { const h = getHandle(); const ctrl = new AbortController(); - const timer = opts.timeoutMs ? setTimeout(() => ctrl.abort(), opts.timeoutMs) : undefined; + const timer = opts.timeoutMs + ? setTimeout(() => ctrl.abort(), opts.timeoutMs) + : undefined; try { return (await h.action({ name, args, signal: ctrl.signal })) as T; } finally { diff --git a/packages/agentos/src/inspector-tabs/lib/source.ts b/packages/agentos/src/inspector-tabs/lib/source.ts index 45620692fa..0f3971cfe3 100644 --- a/packages/agentos/src/inspector-tabs/lib/source.ts +++ b/packages/agentos/src/inspector-tabs/lib/source.ts @@ -3,8 +3,9 @@ // the gateway (actor-client) and transforms the result into the display type the // ported component expects. Action names/shapes are the actual ones, not the // mockup's aspirational `agentOs*` names. -import { queryOptions } from "@tanstack/react-query"; + import type { SessionStreamEntry } from "@rivet-dev/agentos-core"; +import { queryOptions } from "@tanstack/react-query"; import { callAction } from "./actor-client"; import type { FileContent, diff --git a/packages/agentos/tsup.config.ts b/packages/agentos/tsup.config.ts index 2a55de7d41..d8987d3940 100644 --- a/packages/agentos/tsup.config.ts +++ b/packages/agentos/tsup.config.ts @@ -5,7 +5,7 @@ export default defineConfig({ dts: true, sourcemap: true, clean: true, - // Keep rivetkit / react out of the bundle so subpath conditions - // (browser client, react) resolve in the consumer's environment. + // Keep RivetKit and React out of the bundle so subpath conditions resolve in + // the consumer's environment. external: ["rivetkit", "@rivetkit/react", "react", "react-dom"], }); diff --git a/packages/browser/scripts/build-dist-wasm.mjs b/packages/browser/scripts/build-dist-wasm.mjs index a01ccd5d52..39765c9855 100644 --- a/packages/browser/scripts/build-dist-wasm.mjs +++ b/packages/browser/scripts/build-dist-wasm.mjs @@ -1,7 +1,7 @@ #!/usr/bin/env node // Builds the Agent OS browser wasm sidecar (web target) into dist/sidecar-wasm-web/ // so the shipped package's `createAgentOsConvergedSidecar` loader can resolve the -// wasm glue + binary relative to dist/converged-sidecar.js. Mirrors secure-exec's +// wasm glue + binary relative to dist/converged-sidecar.js. Mirrors agentos's // build-dist-wasm.mjs (which ships @rivet-dev/agentos-runtime-browser's dist/sidecar-wasm-web). // // Requires `wasm-pack` on PATH. Run as part of the package build (`pnpm build`). diff --git a/packages/browser/scripts/build-sidecar-wasm.mjs b/packages/browser/scripts/build-sidecar-wasm.mjs index 40dc82831f..106c8c5d3a 100644 --- a/packages/browser/scripts/build-sidecar-wasm.mjs +++ b/packages/browser/scripts/build-sidecar-wasm.mjs @@ -1,7 +1,7 @@ #!/usr/bin/env node // Builds the Agent OS browser sidecar (crates/agentos-sidecar-browser) to a // wasm-bindgen package under .cache/agentos-sidecar-wasm. This is the converged -// wasm kernel (from secure-exec) plus the Agent OS ACP BrowserExtension, driven by +// wasm kernel (from agentos) plus the Agent OS ACP BrowserExtension, driven by // the browser harness / integration tests over pushFrame/pollEvent. // // Requires `wasm-pack` on PATH. Targets nodejs by default so the bindings load diff --git a/packages/browser/scripts/build-wasm-test-assets.mjs b/packages/browser/scripts/build-wasm-test-assets.mjs index 429b34d591..9e63f2964c 100644 --- a/packages/browser/scripts/build-wasm-test-assets.mjs +++ b/packages/browser/scripts/build-wasm-test-assets.mjs @@ -61,10 +61,10 @@ run(esbuildBin, [ // kernel (createAgentOsConvergedSidecar). const browserTestsDir = path.join(packageRoot, "tests", "browser-wasm"); const workerEntry = require.resolve("@rivet-dev/agentos-runtime-browser/internal/worker"); -const secureExecBrowserRoot = path.resolve(path.dirname(workerEntry), ".."); -const secureExecRepoRoot = path.resolve(secureExecBrowserRoot, "..", ".."); -const secureExecCommandsDir = path.join( - secureExecRepoRoot, +const agentOsBrowserRoot = path.resolve(path.dirname(workerEntry), ".."); +const agentOsRepoRoot = path.resolve(agentOsBrowserRoot, "..", ".."); +const agentOsCommandsDir = path.join( + agentOsRepoRoot, "registry", "native", "target", @@ -95,15 +95,15 @@ function copyCommandsFrom(commandsDir) { if (existsSync(repoNativeCommandsDir)) { copyCommandsFrom(repoNativeCommandsDir); -} else if (existsSync(secureExecCommandsDir)) { - copyCommandsFrom(secureExecCommandsDir); +} else if (existsSync(agentOsCommandsDir)) { + copyCommandsFrom(agentOsCommandsDir); } else if (existsSync(runtimeCoreCommandsDir)) { copyCommandsFrom(runtimeCoreCommandsDir); } else if (existsSync(coreutilsCommandsDir)) { copyCommandsFrom(coreutilsCommandsDir); } else { console.log( - `skipping real wasm command copy; missing ${repoNativeCommandsDir}, ${secureExecCommandsDir}, ${runtimeCoreCommandsDir}, and ${coreutilsCommandsDir}`, + `skipping real wasm command copy; missing ${repoNativeCommandsDir}, ${agentOsCommandsDir}, ${runtimeCoreCommandsDir}, and ${coreutilsCommandsDir}`, ); } run(esbuildBin, [ diff --git a/packages/browser/scripts/check-converged-gates.mjs b/packages/browser/scripts/check-converged-gates.mjs index 64256291e6..06ff432f95 100644 --- a/packages/browser/scripts/check-converged-gates.mjs +++ b/packages/browser/scripts/check-converged-gates.mjs @@ -22,7 +22,7 @@ const here = path.dirname(fileURLToPath(import.meta.url)); // Resolve the linked @rivet-dev/agentos-runtime-browser package root via an exported subpath // (its package.json is not itself exported). dist/worker.js -> package root. const workerEntry = require.resolve("@rivet-dev/agentos-runtime-browser/internal/worker"); -const secureExecBrowserRoot = path.resolve(path.dirname(workerEntry), ".."); +const agentOsBrowserRoot = path.resolve(path.dirname(workerEntry), ".."); const gateScripts = [ "check-bridge-contract.mjs", "check-signal-table.mjs", @@ -31,7 +31,7 @@ const gateScripts = [ let failed = false; for (const script of gateScripts) { - const scriptPath = path.join(secureExecBrowserRoot, "scripts", script); + const scriptPath = path.join(agentOsBrowserRoot, "scripts", script); process.stdout.write(`▶ @rivet-dev/agentos-runtime-browser ${script}\n`); const result = spawnSync("node", [scriptPath], { stdio: "inherit" }); if (result.status !== 0) { diff --git a/packages/browser/scripts/verify-demo.mjs b/packages/browser/scripts/verify-demo.mjs index f095911653..7840f637a9 100644 --- a/packages/browser/scripts/verify-demo.mjs +++ b/packages/browser/scripts/verify-demo.mjs @@ -26,7 +26,7 @@ const here = path.dirname(fileURLToPath(import.meta.url)); const packageRoot = path.resolve(here, ".."); const AB = process.env.AGENT_BROWSER_BIN ?? "agent-browser"; const PORT = Number(process.env.DEMO_PORT ?? 43185); -const SESSION = "secure-exec-demo-verify"; +const SESSION = "agentos-demo-verify"; const URL = `http://localhost:${PORT}/agent-demo.html`; const PROMPT = process.argv[2] ?? "Reply with the single word PONG."; diff --git a/packages/browser/src/converged-execution-host-bridge.ts b/packages/browser/src/converged-execution-host-bridge.ts index b5afbf104e..46f4b96b2d 100644 --- a/packages/browser/src/converged-execution-host-bridge.ts +++ b/packages/browser/src/converged-execution-host-bridge.ts @@ -2,7 +2,7 @@ // // Two roles, selected by configuration: // -// 1. DRIVER mode (default, no `agentExecutor`): mirrors secure-exec's no-op +// 1. DRIVER mode (default, no `agentExecutor`): mirrors agentos's no-op // execution host bridge. In the converged browser runtime the guest runs in the // browser worker (driven by @rivet-dev/agentos-runtime-browser's runtime driver), not in the // wasm sidecar; the sidecar only needs a kernel process (pid) for socket diff --git a/packages/browser/src/converged-sidecar.ts b/packages/browser/src/converged-sidecar.ts index 7282756180..a1199ca57c 100644 --- a/packages/browser/src/converged-sidecar.ts +++ b/packages/browser/src/converged-sidecar.ts @@ -4,7 +4,7 @@ // SharedArrayBuffer sync-bridge, and the fs/net/dns/module servicers are all // reused verbatim. Agent OS plugs in its OWN wasm sidecar — the one that registers // `BrowserAcpExtension` — via `createBrowserRuntimeDriverFactory({ convergedSidecar })`. -// This is the Agent OS analogue of secure-exec's `createDefaultConvergedSidecar`: +// This is the Agent OS analogue of agentos's `createDefaultConvergedSidecar`: // same `ConvergedSidecarFactoryOptions` contract, different (ACP-bearing) wasm. // // The kernel (wasm) remains the sole enforcement point; no guest-side permission diff --git a/packages/browser/tests/browser-wasm/agent-demo.html b/packages/browser/tests/browser-wasm/agent-demo.html index c4e667ee8f..2e9c6b2e98 100644 --- a/packages/browser/tests/browser-wasm/agent-demo.html +++ b/packages/browser/tests/browser-wasm/agent-demo.html @@ -3,7 +3,7 @@ - Secure Exec — browser agent with Chrome on-device inference + Agent OS Exec — browser agent with Chrome on-device inference