diff --git a/vendor/agentos/docs/content/docs/hosted-api.mdx b/vendor/agentos/docs/content/docs/hosted-api.mdx index 792d1320..23cd09fd 100644 --- a/vendor/agentos/docs/content/docs/hosted-api.mdx +++ b/vendor/agentos/docs/content/docs/hosted-api.mdx @@ -76,8 +76,8 @@ EOF # → { "token": "…", "expires_ts": … } ``` -In TypeScript, `vm.issueToken({ subject, expiresIn })` issues the same token, -and `client.getForId("agentOS", vmId)` reaches the VM with it. +A client created with that token reaches the VM with +`client.getForId("agentOS", vmId)`. ## Call an action diff --git a/vendor/agentos/docs/content/docs/networking.mdx b/vendor/agentos/docs/content/docs/networking.mdx index 5dfa1aaa..c8feb02a 100644 --- a/vendor/agentos/docs/content/docs/networking.mdx +++ b/vendor/agentos/docs/content/docs/networking.mdx @@ -45,6 +45,11 @@ Hosted VMs can expose any port through an expiring preview. A preview is a signed URL path that proxies HTTP to a port inside the VM until it expires or is revoked. `config.preview.defaultTtlMs` sets the default lifetime. +Requests reach a preview through the VM's gateway at +`https://api.rivet.dev/gateway/{vm_id}@{token}/request{path}`, where `path` is +the preview's returned path and `token` can reach the VM, such as a +[scoped JWT](/agentos/docs/hosted-api#authentication). + ```ts Hosted @nocheck import { createAgentOsClient } from "@rivet-dev/agentos"; diff --git a/vendor/agentos/docs/content/docs/quickstart-hosted.mdx b/vendor/agentos/docs/content/docs/quickstart-hosted.mdx index 7b0e19fb..46811123 100644 --- a/vendor/agentos/docs/content/docs/quickstart-hosted.mdx +++ b/vendor/agentos/docs/content/docs/quickstart-hosted.mdx @@ -127,18 +127,26 @@ curl "https://api.rivet.dev/gateway/$VM_ID/action/v1.filesystem.writeFile" \ "content": "Hello, world!" }]}' -curl "https://api.rivet.dev/gateway/$VM_ID/action/v1.filesystem.readFile" \ +curl "https://api.rivet.dev/gateway/$VM_ID/action/v1.process.run" \ -H "x-rivet-token: $VM_TOKEN" \ - --json '{"args": [{"path": "/home/agentos/hello.txt"}]}' + --json '{"args": [{ + "command": "cat", + "args": ["/home/agentos/hello.txt"], + "options": { "captureStdio": true } + }]}' ``` +`v1.filesystem.readFile` returns raw bytes, which the JSON encoding of the HTTP +API cannot carry, so the HTTP example reads the file through a process. + ### Run a Dev Server & Create Preview URLs Start a Node.js server in the VM, then expose its port through a signed URL that expires on its own, or revoke it early. A running server keeps the VM -awake. +awake. Open the preview at `/gateway/$VM_ID@$VM_TOKEN/request` followed by the +returned `path`, with a token that can reach the VM. @@ -255,7 +263,7 @@ their commands appear on `/opt/agentos/bin`. // Registry packages are published next to a manifest with each release. const base = "https://releases.rivet.dev/agent-os/latest/software/"; const { artifacts } = await (await fetch(`${base}manifest.json`)).json(); -const ripgrep = artifacts.find((artifact) => artifact.name === "ripgrep"); +const ripgrep = artifacts.find((artifact: { name: string }) => artifact.name === "ripgrep"); const installed = await vm.v1.software.install({ source: { url: new URL(ripgrep.path, base).href, digest: ripgrep.digest }, @@ -289,10 +297,22 @@ nothing else. ```ts TypeScript @nocheck // Backend: issue a token for this VM only const vmId = await vm.resolve(); -const { token } = await vm.issueToken({ - subject: "user-123", - expiresIn: 3600, +const response = await fetch("https://api.rivet.dev/auth/tokens", { + method: "POST", + headers: { + Authorization: `Bearer ${process.env.RIVET_TOKEN}`, + "Content-Type": "application/json", + }, + body: JSON.stringify({ + namespace: process.env.RIVET_NAMESPACE, + subject: "user-123", + duration: 3600, + grants: [ + { resource: "actor_gateway", target: { id: vmId }, operations: ["read"] }, + ], + }), }); +const { token } = await response.json(); // Client: call the VM directly const userClient = createAgentOsClient({ diff --git a/vendor/agentos/docs/content/docs/self-hosting.mdx b/vendor/agentos/docs/content/docs/self-hosting.mdx index 05e3e573..c70cce0e 100644 --- a/vendor/agentos/docs/content/docs/self-hosting.mdx +++ b/vendor/agentos/docs/content/docs/self-hosting.mdx @@ -28,12 +28,31 @@ it needs neither. + +The control plane requires an admin token. See [Admin token](/docs/deploy/self-host/control-plane/configuration#admin-token). + + ```sh -docker run -p 6420:6420 rivetdev/engine +export RIVET_ADMIN_TOKEN=$(openssl rand -hex 32) + +docker run -p 6420:6420 \ + -e RIVET__AUTH__ADMIN_TOKEN="$RIVET_ADMIN_TOKEN" \ + rivetdev/engine ``` See the [self-hosting guides](/docs/deploy/) for other ways to run it. + + + +The agentOS worker connects to a pool named `services`: + +```sh +curl -X PUT "http://localhost:6420/runner-configs/services?namespace=default" \ + -H "Authorization: Bearer $RIVET_ADMIN_TOKEN" \ + --json '{"datacenters": {"default": {"normal": {}}}}' +``` + @@ -43,13 +62,15 @@ The worker is what actually runs your VMs. It connects to the control plane: docker run \ --add-host=host.docker.internal:host-gateway \ -e RIVET_ENDPOINT=http://host.docker.internal:6420 \ - rivetdev/services + -e RIVET_TOKEN="$RIVET_ADMIN_TOKEN" \ + rivetdev/services:0.2.0 ``` -Create a VM by ID on your control plane from TypeScript or plain HTTP: +Set `RIVET_TOKEN` to the admin token, then create a VM by ID on your control +plane from TypeScript or plain HTTP: @@ -64,6 +85,7 @@ const vm = client.agentOS.getOrCreate(["my-vm"]); ```bash HTTP curl -X PUT "http://localhost:6420/actors?namespace=default" \ + -H "Authorization: Bearer $RIVET_ADMIN_TOKEN" \ --json '{ "name": "agentOS", "key": "my-vm", diff --git a/vendor/agentos/docs/content/docs/software.mdx b/vendor/agentos/docs/content/docs/software.mdx index c9cb8e7a..692e8642 100644 --- a/vendor/agentos/docs/content/docs/software.mdx +++ b/vendor/agentos/docs/content/docs/software.mdx @@ -37,7 +37,7 @@ const vm = client.agentOS.getOrCreate(["my-vm"]); // manifest. Use a release version, or `latest`. const base = "https://releases.rivet.dev/agent-os/latest/software/"; const { artifacts } = await (await fetch(`${base}manifest.json`)).json(); -const ripgrep = artifacts.find((artifact) => artifact.name === "ripgrep"); +const ripgrep = artifacts.find((artifact: { name: string }) => artifact.name === "ripgrep"); const installed = await vm.v1.software.install({ source: { url: new URL(ripgrep.path, base).href, digest: ripgrep.digest }, @@ -50,7 +50,8 @@ for (const software of await vm.v1.software.list({})) { console.log(software.packageId, software.commands); } -await vm.v1.software.uninstall({ packageId: installed.source.packageId }); +const { packageId } = installed.source; +if (packageId) await vm.v1.software.uninstall({ packageId }); ```