Skip to content
Merged
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
73 changes: 61 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

<p align="center">
<a href="https://www.npmjs.com/package/perstack"><img src="https://img.shields.io/npm/v/perstack" alt="npm version"></a>
<a href="https://hub.docker.com/r/perstack/perstack"><img src="https://img.shields.io/docker/v/perstack/perstack?label=docker" alt="Docker image version"></a>
<a href="https://www.npmjs.com/package/perstack"><img src="https://img.shields.io/npm/dm/perstack" alt="npm downloads"></a>
<a href="https://github.com/perstack-ai/perstack/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-Apache%202.0-blue" alt="License"></a>
</p>
Expand All @@ -14,16 +15,24 @@

Agentic software in production hits two walls. Build from scratch, and most of the code is plumbing — not prompts. Throw a frontier model at a monolithic agent, and it works but doesn't scale commercially.

Perstack takes a third approach: purpose-specific micro-agents on value-tier models. Narrow tasks don't need Opus-level reasoning. Haiku is enough. And single-purpose prompts are easy to write.
Perstack takes a third approach: purpose-specific micro-agents on value-tier models, running in sandboxed containers. Narrow tasks don't need Opus-level reasoning. Haiku is enough. And single-purpose prompts are easy to write.

`create-expert` generates agent definitions in a `perstack.toml` file. `perstack` executes them on an event-sourced runtime.
Every agent runs inside its own Docker container with an isolated filesystem and network. The host system is never exposed. This makes Perstack safe to run in production — agents can execute shell commands and write files without risk to the host.

`create-expert` generates agent definitions in a `perstack.toml` file. `perstack` executes them on an event-sourced runtime inside a sandboxed container.

```bash
npx create-expert "Form a team named ai-gaming to build a Bun-based CLI indie game playable on Bash for AI."
npx perstack start ai-gaming --model "haiku-4-5" "Make a Wizardry-like dungeon crawler."

docker run --rm -e ANTHROPIC_API_KEY \
-v ./perstack.toml:/workspace/perstack.toml:ro \
-v ./workspace:/workspace/output \
perstack/perstack start ai-gaming --model "haiku-4-5" "Make a Wizardry-like dungeon crawler."
```

A game built with these commands: [demo-dungeon-crawler](https://github.com/perstack-ai/demo-dungeon-crawler). Play it via `npx perstack-demo-dungeon-crawler start`. Built entirely on Claude 4.5 Haiku.
The official [`perstack/perstack`](https://hub.docker.com/r/perstack/perstack) image ships pre-compiled standalone binaries — no Node.js or npm needed. File writes, shell commands, and all agent activity are confined to the container.

A game built with these commands: [demo-dungeon-crawler](https://github.com/perstack-ai/demo-dungeon-crawler). Built entirely on Claude 4.5 Haiku.

## How it works

Expand All @@ -48,7 +57,37 @@ description = "Tests the game and reports bugs"
instruction = "Play-test the game, find bugs, and verify fixes."
```

`perstack start` executes the agents and streams activity in real time. `perstack run` does the same headless with JSON output, for integration into your own applications.
Run with Docker — the config is mounted read-only, and output stays inside the container:

```bash
docker run --rm -e ANTHROPIC_API_KEY \
-v ./perstack.toml:/workspace/perstack.toml:ro \
-v ./output:/workspace/output \
perstack/perstack run ai-gaming "Make a Wizardry-like dungeon crawler."
```

`perstack start` streams activity in real time. `perstack run` does the same headless with JSON output, for integration into your own applications.

## Sandboxed by default

Agents have access to shell execution, file I/O, and MCP tools. Running them directly on the host is a security risk. Docker containers solve this:

- **Filesystem isolation** — agents read and write inside the container. Mount only what you need with `-v`.
- **Network control** — restrict outbound access with `--network=none` or custom Docker networks.
- **Resource limits** — cap CPU and memory with `--cpus` and `--memory`.
- **Disposable environments** — `--rm` ensures nothing persists after execution.

```bash
# Maximum isolation: no network, resource-limited, read-only config
docker run --rm \
--network=none \
--cpus=1 --memory=2g \
-e ANTHROPIC_API_KEY \
-v ./perstack.toml:/workspace/perstack.toml:ro \
perstack/perstack run my-expert "Analyze this codebase."
```

For production deployments, see [Isolation by Design](https://perstack.ai/docs/operating-experts/isolation-by-design/).

## Runtime

Expand All @@ -73,14 +112,24 @@ Custom MCP servers can be added per agent in `perstack.toml`.
## Deployment

```dockerfile
FROM node:22-slim
WORKDIR /app
COPY perstack.toml perstack.lock .
RUN npm install -g perstack && perstack install
ENTRYPOINT ["perstack", "run", "--config", "/app/perstack.toml", "ai-gaming"]
FROM perstack/perstack:latest
COPY perstack.toml .
RUN perstack install
ENTRYPOINT ["perstack", "run", "my-expert"]
```

```bash
docker build -t my-expert .
docker run --rm -e ANTHROPIC_API_KEY my-expert "query"
```

The image is multi-arch (`linux/amd64`, `linux/arm64`) and weighs ~74MB. Pin to a specific version for reproducible builds:

```dockerfile
FROM perstack/perstack:0.0.94
```

The runtime can also be imported directly as a TypeScript library, so it works in Cloudflare Workers, Vercel, or any Node.js environment:
The runtime can also be imported directly as a TypeScript library for serverless environments (Cloudflare Workers, Vercel, etc.):

```typescript
import { run } from "@perstack/runtime"
Expand All @@ -89,7 +138,7 @@ const checkpoint = await run({
setting: {
model: "claude-sonnet-4-5",
providerConfig: { providerName: "anthropic", apiKey: env.ANTHROPIC_API_KEY },
expertKey: "ai-gaming",
expertKey: "my-expert",
input: { text: query },
},
})
Expand Down