Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ https://releases.rivet.dev/agent-os/latest/software/manifest.json
```

The same directory also holds `default-software.json`, the manifest of the
packages every VM installs by default. Consumers pass an artifact URL and
digest from the manifest directly to `software.install`; see
[Software](/agentos/docs/software#install-while-running).
packages every VM installs by default. The library resolves registry names such
as `{ registry: "git" }` against this manifest. To serve packages from a mirror,
copy the `<version>/software/` layout and point `softwareRegistry.url` or
`AGENTOS_SOFTWARE_REGISTRY_URL` at its root; see
[Software](/agentos/docs/software#registry-packages).
10 changes: 7 additions & 3 deletions vendor/agentos/docs/content/docs/host-functions.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ description: "Expose trusted host functions to guest programs in agentOS VMs as
skill: true
---

Host functions expose JavaScript functions from your process to code running inside the VM. They run as in-process callbacks, so they are available in the library only, not on hosted VMs. Each function is defined with a Zod input schema and becomes an auto-generated CLI command at `/bin/agentos-{name}`, plus an async function that inline JavaScript can call directly.
Host functions expose JavaScript functions from your process to code running inside the VM. They run as in-process callbacks, so they are available in the library only, not on hosted VMs. Each function is defined with a Zod input schema and becomes an auto-generated CLI command at `/bin/agentos-{name}`, plus an async function that guest JavaScript can call directly.

## Getting started

Expand Down Expand Up @@ -66,9 +66,13 @@ Missing required flag: --city

## Call host functions from JavaScript

Inline JavaScript and TypeScript get each collection as a frozen global, and each
Every guest Node process gets each collection as a frozen global, and each
host function as an async function, so generated code calls your tools like any
other API. Keys written in camelCase become kebab-case commands and camelCase guest
other API. This covers inline `vm.javascript` and `vm.typescript` executions,
scripts started with `vm.process.spawn("node", ...)` or `vm.process.exec`,
`node` run from the guest shell, and child processes of guest Node. The globals
are defined before the entry script and its imports run, so a module can use
them at its top level. Keys written in camelCase become kebab-case commands and camelCase guest
identifiers, so `orderStore.listOrders` is `agentos-order-store list-orders` on
the CLI and `orderStore.listOrders(input)` in guest JavaScript.

Expand Down
39 changes: 35 additions & 4 deletions vendor/agentos/docs/content/docs/javascript.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ console.log(sum.value); // 3
Returning `undefined`, a function, a symbol, or a circular value fails with
`evaluation_serialization_failed` rather than silently losing the value.

`evaluate()` returns as soon as the expression's promise settles and its
in-flight host calls finish. Work it leaves behind is released as described in
[Keep state between calls](#keep-state-between-calls).

## Execute code

`execute()` runs source and captures its output instead of returning a value.
Expand All @@ -65,6 +69,11 @@ Executions are ephemeral, so capture stdio only when you want it: `"stderr"` for
diagnostics, `"all"` for both streams. `onStdout`/`onStderr` stream live and work
independently of capture.

Without a `contextId`, `execute()` behaves like `node -e`: it finishes when the
event loop is empty, so a ref'd timer or a listening server keeps it running
until `timeoutMs`. Call `unref()` on handles that must not hold it open, or use
`spawn` for long-lived work.

## Pass data into code

In the library, `inputs` hands host values to the guest as real objects, so data never gets
Expand All @@ -79,9 +88,29 @@ calls.

<CodeSnippet file="examples/js-sdk-overview/src/contexts.ts" title="Library" />

A context runs one operation at a time, so reusing a busy `contextId` fails
immediately. Files, npm, Bash, and type checks may pass the same id, but they run
in fresh processes and never touch retained memory.
A call in a context completes when its top-level code, including any promise it
awaits, settles. It does not wait for work it leaves behind. Globals stay, so the
next call sees the state, but agentOS releases what would keep a Node process
alive:

- **Ref'd timers and immediates** are cancelled and never run. A promise that
waits on one never settles.
- **Ref'd sockets, servers, and child processes** are closed. Pending I/O on them
fails with `ERR_AGENTOS_CONTEXT_HANDLE_RELEASED`, never a clean end. A `fetch`
that is still in flight rejects with that error as its `cause`, and reading a
stored `Response` body fails the same way.
- **Unref'd timers and handles** are left alone, but nothing runs between calls,
so they only make progress while a later call is running.

The call's stderr names what was released. Errors raised during that cleanup,
such as an unhandled rejection from a released `fetch`, are written to the same
stderr and never change the call's result. Finish I/O inside one call, and run
long-lived servers with `spawn` instead of a context.

A context runs one call at a time. A call made while another call in the same
context is still running fails immediately with `execution_busy`. Files, npm,
Bash, and type checks may pass the same id, but they run in fresh processes and
never touch retained memory.

JavaScript defaults to `format: "module"`. Each call is a separate root ES
module, so its imports, top-level declarations, and exports are scoped to that
Expand Down Expand Up @@ -192,7 +221,9 @@ See [Filesystem](/agentos/docs/filesystem), [Processes & Shells](/agentos/docs/p
## Host functions

Guest JavaScript calls [host functions](/agentos/docs/host-functions) as async globals, so host
credentials stay outside the VM. Host functions are library-only.
credentials stay outside the VM. The globals exist in every guest Node process,
whether it runs inline code, a spawned script, `node` from the shell, or a child
process. Host functions are library-only.

<CodeSnippet file="examples/embedded/host-functions-javascript.ts" title="Library" />

Expand Down
7 changes: 4 additions & 3 deletions vendor/agentos/docs/content/docs/networking.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ browsers, route requests through your application and forward them with

Guest listeners and loopback traffic stay inside the VM. Outbound access is
limited to the sidecar's default allowlist unless the `network`
[permission](/agentos/docs/permissions) scope allows more. Requests from the
host and previews enter the VM from the host side, so they are subject to
loopback confinement but not to the guest egress policy.
[permission](/agentos/docs/permissions) scope allows more. `network: "deny"`
removes that allowlist and keeps listeners and loopback working. Requests from
the host and previews enter the VM over VM-local loopback, so they are subject
to loopback confinement, not to the guest egress allowlist.
38 changes: 38 additions & 0 deletions vendor/agentos/docs/content/docs/permissions.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,44 @@ processes, environment, listeners, and loopback networking work, and outbound
network access is limited to the sidecar's default allowlist. Library host
functions are governed by the `hostFunction` scope.

## Network

`network: "deny"` denies traffic that crosses the VM boundary and keeps
networking inside the VM working, like a container with no published ports.

| Traffic | `network: "deny"` |
| --- | --- |
| Guest `listen()` on TCP or Unix sockets | Allowed |
| Guest connections to its own listeners over `127.0.0.1`, `localhost`, `::1`, or Unix sockets | Allowed |
| Host requests to guest servers with `fetch`, `httpRequest`, or previews | Allowed |
| DNS lookups | Denied |
| TCP connections and HTTP requests to any non-loopback address | Denied |
| The default allowlist of model provider endpoints | Denied |

Guest listeners are never bound on the host, and guest loopback never reaches a
host loopback service unless that host port is listed in `loopbackExemptPorts`.
`network: "deny"` does not change either rule.

`"deny"` is shorthand for this rule set. A rule set replaces the whole network
scope, so a custom rule set that should keep listeners and loopback working
must include these rules. Omit them to deny VM-local networking too.

```json
{
"network": {
"default": "deny",
"rules": [
{ "mode": "allow", "operations": ["listen"], "patterns": ["tcp://**", "unix:**"] },
{
"mode": "allow",
"operations": ["http"],
"patterns": ["tcp://127.0.0.1:*", "tcp://localhost:*", "tcp://::1:*", "unix:**"]
}
]
}
}
```

See the [Security Model](/agentos/docs/security-model) for the trust boundary
these policies enforce.

14 changes: 14 additions & 0 deletions vendor/agentos/docs/content/docs/processes.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,18 @@ commands or working directories are invalid input.
| Wait for exit | `v1.process.wait` | `process.wait` |
| Inspect | `v1.process.get`, `v1.process.list`, `v1.process.tree` | `process.get`, `process.list`, `process.tree` |

A library `process.spawn` keeps stdin open; pass `streamStdin: false` to give
the process EOF instead.
Writing to stdin after it is closed fails with `EBADF`, as on Linux.

Hosted operations take the process handle `{ generation, pid }`; library
operations take the `pid`. A hosted handle from before a `v1.vm.restart` fails
with `stale_generation`.

Writing to stdin after the process exits fails with `EPIPE`, as a write to a
pipe with no reader does on Linux. Closing stdin after the process exits
succeeds.

`get` and `list` report `startedAtMs` as a Unix timestamp in milliseconds.
`tree` includes guest child processes as well as processes launched through the
API, so it can show more than you started. Use the returned handle or `pid`
Expand Down Expand Up @@ -138,3 +146,9 @@ Interactive terminals allocate a kernel PTY and start a shell attached to it.
| Output | `terminal.output` and `terminal.exit` events, `v1.terminal.output.read` replay | `vm.onShellData`, `vm.onShellStderr`, `vm.onShellExit` |

Hosted VMs also list open terminals with `v1.terminal.list`.

The VM tracks each terminal's cursor and answers a program's cursor-position
query (`ESC[6n`) itself, as a terminal multiplexer does, so a shell keeps
running while no client is attached and several clients can watch one
terminal. The query is removed from the output that clients receive, so their
emulators never answer it.
5 changes: 5 additions & 0 deletions vendor/agentos/docs/content/docs/python.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,11 @@ Executions are ephemeral, so capture stdio only when you want it: `"stderr"` for
diagnostics, `"all"` for both streams. `onStdout`/`onStderr` stream live and work
independently of capture.

The exit code follows CPython. `sys.exit()` and `SystemExit` set it: no
argument exits `0`, an integer exits with that code, and any other value is
printed to stderr and exits `1`. An uncaught exception prints a Python traceback
to stderr and exits `1`.

## Pass data into code

In the library, `inputs` hands host values to the guest as real objects, so data never gets
Expand Down
Loading
Loading