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
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ This demo highlights the core developer experience and "Agentic Infrastructure"
2. **State Persistence:** Persistent working memory (volatile RAM) and filesystem state preserved perfectly across hibernation cycles via full-state snapshots.
3. **Agent Swarm Multiplexing:** Demonstrates 30x+ oversubscription by "juggling" a large registry of stateful actors onto a small pool of shared physical pods.

To reproduce this demo in your own cluster, please refer to the detailed walkthroughs in the **[Counter Demo](demos/counter/README.md)** and **[Secret Agent Demo](demos/agent-secret/README.md)**.
To reproduce this demo in your own cluster, please refer to the detailed walkthroughs in the **[Counter Demo](demos/counter/README.md)** and **[Secret Agent Demo](demos/agent-secret/README.md)**, and **[OpenClaw Multiplexing](demos/openclaw/README.md)**.

For more videos and walkthroughs, visit our YouTube channel: **[agent-substrate](https://www.youtube.com/channel/UCN9PPqlTtVxlcpbQ-NWpfZQ)**.

Expand All @@ -53,6 +53,7 @@ Agent Substrate is designed to be **framework and agent harness agnostic**. Beca
* **Agent Development Kit (ADK):** Native support for ADK-compatible session identity and persistent working memory.
* **LangChain:** Ideal execution environment for long-running, stateful LangChain agents and sandboxed tool-calling.
* **Claude Code & CodeX:** Support for high-density, stateful coding environments that preserve terminal and filesystem state across sessions.
* **OpenClaw (Google Claw):** Optimized for multiplexing stateful TypeScript agents with persistent in-memory reasoning and conversation history.
* **Model Context Protocol (MCP):** Deploy secure, sandboxed MCP servers as Substrate Actors to provide durable tools for any LLM.

## Ecosystem & Examples
Expand Down Expand Up @@ -188,6 +189,7 @@ We provide several sample applications demonstrating Agent Substrate's capabilit
2. **[Sandbox Demo (Antigravity)](demos/sandbox/README.md)**: A secure, sandboxed execution environment (running Alpine Linux) that allows arbitrary shell execution while preserving filesystem state across sessions.
3. **[Claude Code Multiplex](demos/claude-code-multiplex/README.md)**: Demonstrates oversubscribing physical hardware by multiplexing multiple Claude Code agents onto a limited pool of workers.
4. **[Secret Agent](demos/agent-secret/README.md)**: Highlights Substrate's "Zero-Idle" self-suspension and re-animation of volatile process memory.
5. **[OpenClaw Multiplexing](demos/openclaw/README.md)**: Showcases 1.5x hardware oversubscription using Google Claw agents, demonstrating stateful rehydration and rapid agent rotation across physical pods.

### Documentation & Guides
* [API Configuration Guide](docs/api-guide.md): Detailed reference for configuring WorkerPools, ActorTemplates, Secrets, and Volumes.
Expand Down
74 changes: 74 additions & 0 deletions demos/sub-agent-multiplex/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# Google Claw on Agent Substrate PoC
# Portable Dockerfile for OSS Substrate Migration

# Stage 1: Build the standalone bundles
FROM node:22-slim AS builder

WORKDIR /app

# Install build dependencies
RUN apt-get update && apt-get install -y --no-install-recommends \
ca-certificates \
curl \
&& rm -rf /var/lib/apt/lists/*

# Copy standalone package files
COPY package.json ./
# Use npm install for simplicity and portability in the standalone package
RUN npm install

# Copy source code
COPY ui/ ./ui/
COPY workload/ ./workload/

# Build zero-dependency bundles
RUN ./node_modules/.bin/esbuild workload/agent.ts \
--bundle \
--platform=node \
--target=node22 \
--outfile=dist/agent.js \
--external:node:*

RUN ./node_modules/.bin/esbuild ui/demo-ui.ts \
--bundle \
--platform=node \
--target=node22 \
--outfile=dist/demo-ui.js \
--external:node:*

# Stage 2: Final Production Image
FROM node:22-slim AS runner

WORKDIR /app

# Copy the entire context to check for local binaries
COPY . .

# Install runtime dependencies (tini for signal forwarding, kubectl for dashboard sync)
RUN apt-get update && apt-get install -y --no-install-recommends \
ca-certificates \
curl \
tini \
&& curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl" \
&& chmod +x kubectl \
&& mv kubectl /usr/local/bin/ \
&& rm -rf /var/lib/apt/lists/*

# Copy built assets
COPY --from=builder /app/dist/ ./dist/
# Copy kubectl-ate binary if it exists in context, otherwise download it
# This makes the Dockerfile portable across environments
RUN if [ -f "./kubectl-ate" ]; then \
mv ./kubectl-ate /usr/local/bin/kubectl-ate; \
else \
curl -L -o /usr/local/bin/kubectl-ate https://github.com/agent-substrate/substrate/releases/latest/download/kubectl-ate-linux-amd64; \
fi && chmod +x /usr/local/bin/kubectl-ate

# Create a /pause hook for Substrate rehydration
RUN echo '#!/bin/sh' > /pause && \
echo 'echo "[pause] Starting Google Claw agent..."' >> /pause && \
echo 'exec /usr/bin/tini -- /usr/local/bin/node /app/dist/agent.js' >> /pause && \
chmod +x /pause

# Default entrypoint (can be overridden by deployment to run demo-ui)
ENTRYPOINT ["/usr/bin/tini", "--", "node", "dist/agent.js"]
98 changes: 98 additions & 0 deletions demos/sub-agent-multiplex/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
# Substrate Multiplex Demo: NanoClaw 1.5x Overcommit

This demo demonstrates the extreme efficiency gains possible with Google Substrate by multiplexing **3 logical NanoClaw agents** onto **2 physical substrate workers** (1.5x density ratio).

## System Information

- **Agent Framework**: NanoClaw (v2.x)
- **Source**: `github.com/nanocoai/nanoclaw`
- **Substrate Mode**: Multi-Actor Multiplexing (1.5x oversubscription)
- **Runtime**: Bun (Node.js compatible) inside Debian Slim
- **Isolation**: gVisor (runsc)

## What this shows

- **High-Density Multiplexing**: Three logical agent identities running on only two physical pods (1.5x oversubscription).
- **State Persistence**: A `taskCounter` maintained in the Node.js process memory survives multiple suspend/resume cycles.
- **Dynamic Rotation**: Agents finish work at different times (3-6s), forcing Substrate to constantly rotate pod ownership.
- **Visual Identity Tracking**: Color-coded agents (Blue/Pink/Gold) and live log tailing to make infrastructure sharing intuitively obvious.

## Audience

This guide is intended for engineers exploring Agent Substrate for hosting large-scale agentic workloads where cost-efficiency and stateful rehydration are critical.

## Prerequisites

- **Agent Substrate Cluster**: A Kubernetes cluster with Substrate installed.
- **Docker**: For building and pushing the unified actor/UI image.
- **GCS Bucket**: Configured for Substrate state snapshots (e.g., `gs://snapshot-substrate-gke-ai-eco-dev/`).
- **kubectl & kubectl-ate**: The Substrate CLI tool for managing logical actors.

## Components

| Path | Purpose |
|---|---|
| `workload/agent.ts` | The workload: A NanoClaw/Hono server with persistent memory state. |
| `ui/demo-ui.ts` | The dashboard: A Node.js backend providing live logs, task queueing, and visual tracking. |
| `sub-agent-multiplex.yaml.tmpl` | Kubernetes manifests for ActorTemplates and WorkerPools. |
| `Dockerfile` | Unified OCI image containing both the actor workload and the dashboard UI. |

## How to Run

### 1. Provision Hardware
Scale the physical `WorkerPool` to the desired replica count (2 for this demo):
```bash
kubectl apply -f sub-agent-multiplex.yaml
```

### 2. Deploy Logical Agents
Create the three "fun-named" actors using the Substrate CLI.
```bash
kubectl-ate create actor agent-luna-v12 --template sub-agent/sub-agent-agent
kubectl-ate create actor agent-mars-v12 --template sub-agent/sub-agent-agent
kubectl-ate create actor agent-nova-v11 --template sub-agent/sub-agent-agent
```

### 3. Launch the Dashboard
The dashboard runs as a standard Kubernetes Deployment with a LoadBalancer.
```bash
kubectl apply -f demo-ui.yaml
```

## Drive the Demo

Open the dashboard and use the following interaction patterns:

- **Pulse (Manual Wakeup)**: Trigger tasks across the registry. Watch the **colored icons** rapidly cycle through the 2 worker slots.
- **Live Logs**: Observe the MT Broker logs. You will see different Agent IDs appearing in the **same log stream**, proving that physical hardware is being recycled in real-time.
- **Cron Tracker**: Observe real-time countdowns as the automated schedule triggers orchestration events.

## Integrating a Real LLM API

Integrating an LLM into a NanoClaw logical actor is straightforward. Because Substrate persists the **entire process memory**, any in-memory conversation history or KV-cache will survive multiple suspend/resume cycles without requiring an external database.

### 1. Add the LLM SDK
Add your preferred SDK (e.g., OpenAI or Anthropic) to the `package.json`:
```bash
npm install openai
```

### 2. Update the Actor Logic
Modify `workload/agent.ts` to initialize the client and maintain a local chat history:
```typescript
import OpenAI from "openai";

const openai = new OpenAI({ apiKey: process.env.LLM_API_KEY });
let history: any[] = []; // This array will survive Substrate snapshots!

app.post("/v1/chat", async (c) => {
const { message } = await c.req.json();
history.push({ role: "user", content: message });

const response = await openai.chat.completions.create({
model: "gpt-4",
messages: history,
});
// ... process response
});
```
20 changes: 20 additions & 0 deletions demos/sub-agent-multiplex/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"name": "openclaw-substrate-poc",
"version": "1.0.0",
"description": "Google Claw on Agent Substrate PoC",
"private": true,
"scripts": {
"build": "esbuild src/agent.ts --bundle --platform=node --target=node22 --outfile=dist/agent.js --external:node:* && esbuild src/demo-ui.ts --bundle --platform=node --target=node22 --outfile=dist/demo-ui.js --external:node:*",
"start:ui": "node dist/demo-ui.js",
"start:agent": "node dist/agent.js"
},
"dependencies": {
"@hono/node-server": "^1.11.1",
"hono": "^4.4.2"
},
"devDependencies": {
"@types/node": "^22.0.0",
"esbuild": "^0.21.5",
"typescript": "^5.5.2"
}
}
84 changes: 84 additions & 0 deletions demos/sub-agent-multiplex/sub-agent-multiplex.yaml.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
apiVersion: ate.dev/v1alpha1
kind: ActorTemplate
metadata:
name: sub-agent-agent
namespace: sub-agent
spec:
containers:
- image: ${SUB_AGENT_IMAGE}
name: agent
ports:
- containerPort: 8080
pauseImage: registry.k8s.io/pause:3.10.2@sha256:f548e0e8e3dc1896ca956272154dde3314e8cc4fde0a57577ee9fa1c63f5baf4
runsc:
amd64:
sha256Hash: a397be1abc2420d26bce6c70e6e2ff96c73aaaab929756c56f5e2089ea842b63
url: gs://gvisor/releases/nightly/2026-05-19/x86_64/runsc
arm64:
sha256Hash: 1ba2366ae2efceba166046f51a4104f9261c9cb72c6db8f5b3fe2dc57dea86b9
url: gs://gvisor/releases/nightly/2026-05-19/aarch64/runsc
snapshotsConfig:
location: gs://${BUCKET_NAME}/sub-agent-agent/v12/
workerPoolRef:
name: agent-pool
namespace: sub-agent
---
apiVersion: ate.dev/v1alpha1
kind: WorkerPool
metadata:
name: agent-pool
namespace: sub-agent
spec:
ateomImage: gcr.io/gke-ai-eco-dev/ate-images/ateom-gvisor-715889664656de67e44382a8d6ab981d@sha256:a877e335fdb6e5576714ab53ad6bf88ee676dfe642516c07673a3d9df56053b3
replicas: 2
---
apiVersion: batch/v1
kind: CronJob
metadata:
name: agent-luna-trigger
namespace: sub-agent
spec:
schedule: "*/1 * * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: trigger
image: curlimages/curl:latest
command: ["curl", "-X", "POST", "http://demo-ui.sub-agent.svc.cluster.local/api/give-task?source=cron&agent=agent-luna"]
restartPolicy: OnFailure
---
apiVersion: batch/v1
kind: CronJob
metadata:
name: agent-mars-trigger
namespace: sub-agent
spec:
schedule: "*/2 * * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: trigger
image: curlimages/curl:latest
command: ["curl", "-X", "POST", "http://demo-ui.sub-agent.svc.cluster.local/api/give-task?source=cron&agent=agent-mars"]
restartPolicy: OnFailure
---
apiVersion: batch/v1
kind: CronJob
metadata:
name: agent-nova-trigger
namespace: sub-agent
spec:
schedule: "*/3 * * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: trigger
image: curlimages/curl:latest
command: ["curl", "-X", "POST", "http://demo-ui.sub-agent.svc.cluster.local/api/give-task?source=cron&agent=agent-nova"]
restartPolicy: OnFailure
14 changes: 14 additions & 0 deletions demos/sub-agent-multiplex/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"compilerOptions": {
"target": "ESNext",
"module": "ESNext",
"moduleResolution": "bundler",
"strict": true,
"skipLibCheck": true,
"isolatedModules": true,
"esModuleInterop": true,
"allowImportingTsExtensions": true,
"noEmit": true
},
"include": ["./**/*"]
}
Loading
Loading