Skip to content
Merged
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
135 changes: 135 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
# Contributing

Thanks for contributing to `runtimeuse`.

## Prerequisites

- Git
- Node.js 22 or newer
- Python 3.11 or newer recommended
- `npm`

There is no root workspace setup in this repository today, so install dependencies separately in each package you want to work on.

## Clone the Repository

```bash
git clone https://github.com/getlark/runtimeuse.git
cd runtimeuse
```

## Repository Layout

- `packages/runtimeuse` is the TypeScript runtime that runs inside the sandbox.
- `packages/runtimeuse-client-python` is the Python client used outside the sandbox.
- `docs` is the documentation app.

## Environment Files

Two local env files are useful for advanced development flows. They are not required for the basic local test path:

- `packages/runtimeuse/.env` for the runtime package's `npm run dev-publish` flow. Start from `packages/runtimeuse/.env.example`.
- `packages/runtimeuse-client-python/.env` for sandbox and LLM tests. Start from `packages/runtimeuse-client-python/.env.example`.

## TypeScript Runtime Development

Install dependencies:

```bash
cd packages/runtimeuse
npm install
```

Useful commands:

```bash
npm run build
npm run typecheck
npm test
npm run test:integration
```

Notes:

- `npm test` runs the main unit test suite.
- `npm run test:integration` builds first and then runs the integration tests.
- If you want to use the Claude handler locally, install the CLI with `npm install -g @anthropic-ai/claude-code`.
- `npm run dev-publish` runs `scripts/dev-publish.sh`: it builds the runtime, uploads a zip to S3, and prints a presigned download URL plus a ready-to-use `curl ... && node runtimeuse/dist/cli.js` command.
- `npm run dev-publish` reads `packages/runtimeuse/.env` for `S3_BUCKET` and optionally `S3_PREFIX` and `PRESIGN_EXPIRY`.
- `npm run dev-publish` assumes the AWS CLI is installed and already authenticated with permission to upload to the configured S3 bucket and generate presigned URLs.

## Python Client Development

Create and activate a virtual environment, then install the package in editable mode:

```bash
cd packages/runtimeuse-client-python
python -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]" 2>/dev/null || pip install -e .
pip install pytest pytest-asyncio
```

Run the default test suite:

```bash
pytest test/ -m "not sandbox and not llm"
```

Sandbox-only test flow:

```bash
pytest test/ -m sandbox
```

LLM-only test flow:

```bash
pytest test/ -m llm
```

Notes:

- The Python package declares `python >=3.10`, but CI currently tests on Python 3.11 through 3.13.
- If your change touches the runtime protocol or end-to-end behavior, build `packages/runtimeuse` before running Python tests:

```bash
cd packages/runtimeuse
npm install
npm run build
```

- Copy `packages/runtimeuse-client-python/.env.example` to `.env` before running sandbox or LLM tests locally.
- Sandbox tests create an E2B sandbox and require `E2B_API_KEY`.
- LLM tests also create sandboxes by default and require `E2B_API_KEY` plus the relevant provider credentials such as `OPENAI_API_KEY` or `ANTHROPIC_API_KEY`.
- If you already have a runtime server running, set `TEST_WS_URL` to reuse it instead of creating a fresh sandbox.
- Some LLM tests also require `TEST_S3_BUCKET` for artifact upload verification.
- If you want sandbox tests to run against a dev build instead of `npx -y runtimeuse`, set `RUNTIMEUSE_RUN_COMMAND`. A convenient way to get that command is `packages/runtimeuse` -> `npm run dev-publish`.

## Docs Development

Install and run the docs app:

```bash
cd docs
npm install
npm run dev
```

Useful commands:

```bash
npm run build
npm run types:check
npm run lint
```

## Before Opening a PR

Run the checks relevant to the package you changed:

- `packages/runtimeuse`: `npm run typecheck` and `npm test`
- `packages/runtimeuse-client-python`: `pytest test/ -m "not sandbox and not llm"`
- `docs`: `npm run types:check` and `npm run lint`

If you changed behavior shared between the runtime and Python client, run both the TypeScript and Python checks.
35 changes: 7 additions & 28 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

[![Twitter Follow](https://img.shields.io/twitter/follow/getlark)](https://twitter.com/getlark)

Communicate with AI agents inside sandboxes over WebSocket.
Run AI agents inside sandboxes and communicate with them over WebSocket.

| Package | Language | Role | Install |
| ---------------------------------------------------------- | ---------- | ------------------------------------------ | ------------------------------- |
Expand All @@ -14,10 +14,10 @@ Communicate with AI agents inside sandboxes over WebSocket.
### 1. Start the runtime (inside a sandbox)

```bash
npx -y runtimeuse@latest
npx -y runtimeuse
```

This starts a WebSocket server on port 8080 using the OpenAI agent handler by default. Use `--agent claude` for Claude.
This starts a WebSocket server on port 8080 using the OpenAI agent handler by default. Use `--agent claude` for Claude. The Claude handler also requires the `claude` CLI to be installed in the sandbox, for example with `npm install -g @anthropic-ai/claude-code`.

### 2. Connect from Python

Expand All @@ -41,33 +41,12 @@ async def main():
asyncio.run(main())
```

### 3. Or use the runtime programmatically (TypeScript)

```typescript
import { RuntimeUseServer, openaiHandler } from "runtimeuse";

const server = new RuntimeUseServer({ handler: openaiHandler, port: 8080 });
await server.startListening();
```

## How It Works

```
Python Client ──> WebSocket ──> Runtime (in sandbox) ──> AgentHandler
├── openai (default)
└── claude
```
See the [runtime README](./packages/runtimeuse/README.md) and [client README](./packages/runtimeuse-client-python/README.md) for full API docs.

1. The client sends an `InvocationMessage` over WebSocket
2. The runtime downloads files and runs pre-commands (if any)
3. The `AgentHandler` executes the agent with the given prompts and model
4. Intermediate `AssistantMessage`s stream back to the client
5. Files in the artifacts directory are auto-detected and uploaded via presigned URL handshake
6. A final `ResultMessage` with structured output is sent back
7. The runtime runs post-commands (if any)
## Contributing

See the [runtime README](./packages/runtimeuse/README.md) and [client README](./packages/runtimeuse-client-python/README.md) for full API docs.
See [`CONTRIBUTING.md`](./CONTRIBUTING.md) for local setup, package-specific development commands, and the recommended checks to run before opening a PR.

## License

BSL-1.1
[FSL-1.1-ALv2](./LICENSE.md)
29 changes: 22 additions & 7 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,29 @@
# docs

This is a React Router application generated with
[Create Fumadocs](https://github.com/fuma-nama/fumadocs).
Documentation app for `runtimeuse`, built with React Router and Fumadocs.

Run development server:
## Local Development

Install dependencies and start the dev server from this directory:

```bash
npm install
npm run dev
# or
pnpm dev
# or
yarn dev
```

## Available Scripts

```bash
npm run dev # start the local docs app
npm run build # create a production build
npm run start # serve the built site
npm run types:check # generate route/docs types and run TypeScript checks
npm run lint # run Biome checks
npm run format # format the docs app with Biome
```

## Project Layout

- `content/docs` contains the MDX documentation content.
- `app` contains the React Router application and search/UI code.
- `source.config.ts` configures the Fumadocs content source.
7 changes: 3 additions & 4 deletions docs/app/lib/layout.shared.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
import type { BaseLayoutProps } from 'fumadocs-ui/layouts/shared';

// fill this with your actual GitHub info, for example:
export const gitConfig = {
user: 'fuma-nama',
repo: 'fumadocs',
user: 'getlark',
repo: 'runtimeuse',
branch: 'main',
};

export function baseOptions(): BaseLayoutProps {
return {
nav: {
title: 'React Router',
title: 'RuntimeUse',
},
githubUrl: `https://github.com/${gitConfig.user}/${gitConfig.repo}`,
};
Expand Down
1 change: 1 addition & 0 deletions docs/app/root.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import SearchDialog from '@/components/search';
import NotFound from './routes/not-found';

export const links: Route.LinksFunction = () => [
{ rel: 'icon', href: '/favicon.svg', type: 'image/svg+xml' },
{ rel: 'preconnect', href: 'https://fonts.googleapis.com' },
{
rel: 'preconnect',
Expand Down
18 changes: 14 additions & 4 deletions docs/content/docs/index.mdx
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
---
title: Introduction
description: Run AI agents in sandboxes and communicate over WebSocket.
description: Run AI agents in sandboxes and communicate with them over WebSocket.
---

## What is RuntimeUse?

RuntimeUse lets you run an AI agent inside any sandbox and communicate with it over WebSocket — handling artifact uploads, pre-commands, file downloads, cancellation, and structured results.
RuntimeUse lets you run an AI agent inside any sandbox and communicate with it over WebSocket. It handles the runtime lifecycle for you: file downloads, pre-commands, artifact uploads, cancellation, and structured results.

It is made up of two parts:

1. **NPM Runtime executable** — Run it in any sandbox with `npx runtimeuse`. It sets up your agent of choice (Claude, OpenAI, etc) and starts a WebSocket server to interact with it.
2. **Client libraries** — Simple abstractions for interacting with the sandbox WebSocket server from your API server, worker nodes, etc.
1. **`runtimeuse`**: the TypeScript runtime that runs inside the sandbox and exposes a WebSocket server.
2. **`runtimeuse-client`**: the Python client that connects from outside the sandbox and sends invocations.

Today, the recommended path is to run the runtime in the sandbox and use the Python client from your application code.

## Built-in Agent Handlers

Expand All @@ -21,6 +23,12 @@ The runtime ships with two built-in handlers:

Switch between them with `--agent openai` or `--agent claude`.

The Claude handler also requires the `claude` CLI to be installed in the sandbox, for example:

```bash
npm install -g @anthropic-ai/claude-code
```

## Key Features

- **Sandbox-agnostic** — works with any provider that can run `npx` and expose a port
Expand All @@ -30,4 +38,6 @@ Switch between them with `--agent openai` or `--agent claude`.

<Cards>
<Card title="Quickstart" href="/docs/quickstart" />
<Card title="Runtime Package" href="https://github.com/getlark/runtimeuse/tree/main/packages/runtimeuse" />
<Card title="Python Client" href="https://github.com/getlark/runtimeuse/tree/main/packages/runtimeuse-client-python" />
</Cards>
Loading