Skip to main content
Blog

Introducing agentOS Execution API for JavaScript and Python

agentOS now has an execution API for running JavaScript (Node.js) and Python instead of using bash.

Introducing agentOS Execution API for JavaScript and Python

agentOS is a lightweight operating system for agents that runs inside your existing backend, with no sandboxes, no virtual machines, and no third-party service.

It now supports execution APIs for JavaScript (Node.js) and Python, letting agents execute code directly in those languages instead of going through bash. This technique is called Code Mode, and it has a few advantages over raw bash:

  • Fewer tokens: Ten chained operations cost one round trip, not ten.
  • Type checking: You can check generated TypeScript before you run it.
  • Real data processing: map and filter instead of jq and awk.
  • Parallelism: Promise.all instead of shell job control.
  • Real Node.js: The node: standard library, npm packages, and ESM or CommonJS.

JavaScript (Node.js) and Python run through a similar execution API to the one bash already had, with the added power of dynamically evaluating objects and type checking them. Here is what that looks like.

Evaluate an expression

evaluate() returns a JSON-serializable value.

Execute code

execute() runs source and captures its output instead of returning a value.

Executions are ephemeral, so capture stdio only when you want it.

Pass data into code

inputs hands host values to the guest as real objects, so data never gets interpolated into source.

Keep state between calls

Pass a contextId to keep globals, imports, and modules alive across calls.

Type check before running

Type checking validates the agent’s generated code before it executes.

import { AgentOs } from "@rivet-dev/agentos";

const runtime = await AgentOs.create();

try {
	const checked = await runtime.typescript.check(
		`const total: number = "not a number";`,
	);

	for (const diagnostic of checked.diagnostics) {
		// error TS2322: Type 'string' is not assignable to type 'number'.
		// Pass this back to the agent so it can fix the code and try again.
		console.log(
			`${diagnostic.category} TS${diagnostic.code}: ${diagnostic.message}`,
		);
	}

	if (checked.diagnostics.length === 0) {
		await runtime.typescript.execute(`const total: number = 42;`, {
			output: { capture: "all" },
		});
	}
} finally {
	await runtime.dispose();
}

Install packages programmatically

Installs modify the VM-wide filesystem, so a package installed once is importable by every later execution in that VM, in any language.

Background processes and web servers

spawn starts a long-lived process and returns a pid. From there you get stdin, output, signals, and waiting.

A full Linux-compatible environment underneath

There is a real Linux environment behind all of this, shared by every language. If you can do it in a sandbox, you can do it in agentOS.

Get started

npm install @rivet-dev/agentos