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
232 changes: 193 additions & 39 deletions playbooks/supplemental/openclaw-lemonade-server/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ By the end of this playbook you will be able to:
- Learn about **Lemonade Server**
- **Install OpenClaw** and **point it at Lemonade Server** as its AI backend.
- **Start the OpenClaw gateway** and confirm your agent is ready to work.
- **Connect a Discord bot** to your agent so you can chat with it from any device.
- **Connect a communication channel** (Discord or Telegram) so you can chat with your agent from any device.

---

Expand Down Expand Up @@ -54,15 +54,28 @@ By the end of this playbook you will be able to:

---

## Configuring Context Size
## Pull and Load the Recommended Model

For agent workloads, a larger context window lets the model keep more of the task history, tool outputs, and reasoning steps in view at once. Set this once after the server is running:
The recommended model for this playbook is **Qwen3.6-35B-A3B-GGUF**, a strong MoE model with a 263k-token context window that is well-suited to agent workloads. Pull it now:

```bash
lemonade config set ctx_size=190000
lemonade pull Qwen3.6-35B-A3B-GGUF
```

This takes effect for newly loaded models. A context of 190000 tokens is a reasonable floor for agent use; increase it if your model and available RAM support it.
Then load it with a large context window and save that setting for future runs:

```bash
lemonade load Qwen3.6-35B-A3B-GGUF --ctx-size 262144 --save-options
```

The model has a default context length of 262,144 tokens. If you encounter out-of-memory (OOM) errors, consider reducing the context window. However, because Qwen3.6 leverages extended context for complex tasks, we advise maintaining a context length of at least 128K tokens to preserve thinking capabilities.

> **Tip: Disable thinking for faster agent responses:** Qwen3.6-35B-A3B runs in thinking mode by default, which adds latency before each response. For agent loops this overhead accumulates quickly. The [lemonade-sdk/recipes](https://github.com/lemonade-sdk/recipes/blob/main/coding-agents/Qwen3.6-35B-A3B-NoThinking.json) repo provides a ready-made config that disables thinking. To use it, download the file and import it:
>
> ```bash
> curl -LO https://raw.githubusercontent.com/lemonade-sdk/recipes/main/coding-agents/Qwen3.6-35B-A3B-NoThinking.json
> lemonade import Qwen3.6-35B-A3B-NoThinking.json
> ```

---

Expand Down Expand Up @@ -160,30 +173,23 @@ curl -fsSL https://openclaw.ai/install.sh | bash -s -- --no-prompt --no-onboard

The `--no-onboard` flag skips the interactive setup wizard, you will configure the model backend manually in the next step, which gives you precise control over which model and server are used.

After installation, confirm `openclaw` is on your `PATH`:
Open a new terminal and confirm the installation:

```bash
export PATH="$HOME/.npm-global/bin:$HOME/.local/bin:$PATH"
openclaw --version
```

To persist this across terminal sessions:

```bash
echo 'export PATH="$HOME/.npm-global/bin:$HOME/.local/bin:$PATH"' >> ~/.bashrc
```

### Configure OpenClaw to Use Lemonade

Run OpenClaw's non-interactive onboarding, replacing `YOUR_MODEL_ID` with your Lemonade Model ID. Use the plain name (e.g., `Qwen3.5-35B-A3B-GGUF`) for catalog models, or the `user.` prefixed name (e.g., `user.Qwen3.6-35B-A3B-UD-Q4_K_M`) for custom imported ones:
Run OpenClaw's non-interactive onboarding.
<!-- @os:linux -->
```bash
openclaw onboard \
--non-interactive \
--mode local \
--auth-choice custom-api-key \
--custom-base-url "http://127.0.0.1:13305/api/v1" \
--custom-model-id "YOUR_MODEL_ID" \
--custom-model-id "Qwen3.6-35B-A3B-GGUF" \
--custom-provider-id "lemonade" \
--custom-compatibility "openai" \
--custom-api-key "lemonade" \
Expand All @@ -203,7 +209,7 @@ openclaw onboard \
--mode local \
--auth-choice custom-api-key \
--custom-base-url "http://$WINDOWS_HOST:13305/api/v1" \
--custom-model-id "YOUR_MODEL_ID" \
--custom-model-id "Qwen3.6-35B-A3B-GGUF" \
--custom-provider-id "lemonade" \
--custom-compatibility "openai" \
--custom-api-key "lemonade" \
Expand All @@ -217,6 +223,84 @@ openclaw onboard \

This command writes OpenClaw's configuration to `~/.openclaw/openclaw.json`.

> **OpenClaw context window sizing:** OpenClaw's compaction triggers when `contextTokens > contextWindow − reserveTokens`. The default `reserveTokensFloor` is 20,000 tokens, a floor that overrides `reserveTokens` when lower, so any model context below ~37k will trigger an infinite compaction loop. Set a low reserve and disable the floor once in your config and it applies to every model, no per-model tuning needed:
>
> ```json
> "compaction": {
> "reserveTokens": 4096,
> "reserveTokensFloor": 0
> }
> ```
>
> `reserveTokensFloor` is a *floor* (minimum guard), not the reserve itself, setting only the floor has no effect. `reserveTokensFloor: 0` disables the guard so the lower `reserveTokens` is accepted.
>
> **When to apply this:** Use this config if your model's effective context window is below ~37k, either because the model is small (e.g. 8k, 16k, 32k) or because you've intentionally capped it to a lower value (e.g. loading a 128k model but setting context to 16k in Lemonade). Without it, OpenClaw enters an infinite compaction loop on startup.
>
> **Large-context models at full context:** You can skip this entirely. The defaults work fine, compaction will kick in well before the window fills and the model has ample room to generate long responses. If you do apply it, be aware that `reserveTokens: 4096` limits response length to ~4k tokens, which may cut off long file generation or detailed plans.
>
> **Where to add this:** Place the `compaction` block inside `agents.defaults` in your `openclaw.json` (usually at `~/.openclaw/openclaw.json`):
>
> ```json
> {
> "agents": {
> "defaults": {
> "workspace": "/home/<you>/.openclaw/workspace",
> "model": {
> "primary": "lemonade/<your-model-id>"
> },
> "compaction": {
> "reserveTokens": 4096,
> "reserveTokensFloor": 0
> }
> }
> }
> }
> ```
>
> The rest of your config (gateway, channels, models, etc.) stays unchanged, only the `compaction` key needs to be added.

<!-- @os:linux -->
### (Recommended) Enable Docker Sandboxing

OpenClaw can route all agent file and code operations through an isolated Docker container rather than running them directly on your host. This limits the blast radius of any unintended action to the sandbox, leaving your host filesystem and network untouched.

Build the sandbox image once (Docker must be installed):

```bash
docker build -t openclaw-sandbox:bookworm-slim - <<'DOCKERFILE'
FROM debian:bookworm-slim
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update && apt-get install -y --no-install-recommends \
bash ca-certificates curl git jq python3 ripgrep \
&& rm -rf /var/lib/apt/lists/*
RUN useradd --create-home --shell /bin/bash sandbox
USER sandbox
WORKDIR /home/sandbox
CMD ["sleep", "infinity"]
DOCKERFILE
```

Add the following `sandbox` key inside the existing `agents.defaults` block in `~/.openclaw/openclaw.json`:

```json
"agents": {
"defaults": {
"workspace": "...",
"model": { ... },
"sandbox": {
"mode": "non-main",
"scope": "session",
"workspaceAccess": "none"
}
}
}
```

Sandbox containers have **no network access** by default. See the [sandboxing reference](https://docs.openclaw.ai/gateway/sandboxing) for bind mounts and network overrides.

> To verify sandboxing is active, ask the agent to `run hostname` from the dashboard. If you see a short container ID instead of your machine's hostname, the sandbox is working.

<!-- @os:end -->
### Start the OpenClaw Gateway

The gateway is the OpenClaw process that manages the agent loop and serves the dashboard:
Expand All @@ -231,28 +315,45 @@ To open the dashboard, run this in a second terminal while the gateway is still
openclaw dashboard
```

This prints the authenticated URL, open it in your browser. You should see the OpenClaw dashboard with your Lemonade model listed as the active backend. **Your agent is ready.**
Because the gateway binds to loopback, the dashboard auto-authenticates when opened from the same machine, no token entry or device approval is needed for local access. You should see the OpenClaw dashboard with your Lemonade model listed as the active backend.

**Congratulations, you've built a fully local AI agent stack from scratch.**

> **Need the gateway token?** Run `openclaw dashboard --no-open` to print the dashboard URL with the token embedded (it also attempts to copy it to your clipboard). Alternatively, the token is at `gateway.auth.token` in `~/.openclaw/openclaw.json`.
>
> **Approving a remote device:** When you open the dashboard from a second machine or phone, the browser displays a request ID. Back on the machine running the gateway, run:
> ```bash
> openclaw devices approve <requestId>
> ```
> This is only needed for remote or secondary devices, loopback access from the same machine auto-authenticates.

<p align="center">
<img src="assets/openclaw_dashboard.png" width="500" height="300" />
</p>

**Congratulations — you've built a fully local AI agent stack from scratch.**
---

## Optional: Connect a Communication Channel

Once the gateway is running you can reach your local agent from any device. Pick the option that fits your setup. OpenClaw supports [Discord](https://docs.openclaw.ai/channels/discord), [Telegram](https://docs.openclaw.ai/channels/telegram), and other channels, see the full list at [docs.openclaw.ai](https://docs.openclaw.ai).

---

## Optional: Connect a Discord Bot to your Openclaw. [Reference](https://docs.openclaw.ai/channels/discord#ask-your-agent-2)
### Option A: Discord

### Chat with Your Agent via Discord
Discord requires a server where **you have administrator access** to add a bot. If you share servers but don't own one, use Option B (Telegram) instead.

Once the gateway is running, you can reach your local agent through Discord by wiring up a bot. This lets you send commands from your mobile device to your laptop and trigger workloads from anywhere.
#### Create a Discord account and server

If you do not have a Discord account, sign up at [discord.com](https://discord.com). You also need a server where you are administrator, create one by clicking the **+** icon in the Discord sidebar and selecting **Create My Own**. A private server is fine.

#### Create a Discord application and bot

1. Go to the [Discord Developer Portal](https://discord.com/developers/applications) and click **New Application**. Give it a name (e.g. "openclaw-bot").
2. In the sidebar, click **Bot**. Set a username for the bot.
3. Still on the Bot page, scroll to **Privileged Gateway Intents** and enable:
- **Message Content Intent** (required)
- **Server Members Intent** (recommended)
4. Scroll back up and click **Reset Token** to generate your bot token. Copy it.

#### Add the bot to your server
Expand All @@ -272,32 +373,43 @@ Enable Developer Mode in Discord (**User Settings/ Advanced/ Developer Mode**),

Right-click your server icon/ **Privacy Settings**/ toggle on **Direct Messages**. This allows the bot to DM you, which is required for the pairing step.

#### Set the bot token and enable Discord in OpenClaw
#### Configure OpenClaw for Discord

Your bot token is a secret, store it as an environment variable and reference it from config:
Store your bot token as an environment variable, then create a single patch file that enables Discord, references the token, and allowlists your server. Replace `<server_id>` and `<user_id>` with the IDs collected above.

```bash
export DISCORD_BOT_TOKEN="YOUR_BOT_TOKEN"
openclaw config set channels.discord.token \
--ref-provider default --ref-source env --ref-id DISCORD_BOT_TOKEN
openclaw config set channels.discord.enabled true --strict-json

cat > discord.patch.json5 <<JSON5
{
channels: {
discord: {
enabled: true,
token: { source: "env", provider: "default", id: "DISCORD_BOT_TOKEN" },
dmPolicy: "pairing",
groupPolicy: "allowlist",
guilds: {
"<server_id>": {
requireMention: false,
users: ["<user_id>"],
},
},
},
},
}
JSON5
openclaw config patch --file ./discord.patch.json5
```

> **Do not rely on asking the agent to configure this.** When sandboxing is enabled, the agent cannot write to `~/.openclaw/openclaw.json` from inside the sandbox, use the CLI commands above on the host instead.

Restart the gateway so it picks up the new channel config:

```bash
openclaw gateway run --bind loopback --port 18789
```

You should see `logged in to discord as <bot-id>` in the gateway output.

#### Configure Openclaw with the Server details

Open your Openclaw Dashboard and send this message in the chat window replacing `<user_id>` and `<server_id>` with the IDs collected earlier

```bash
I already set my Discord bot token in config. Please finish Discord setup with User ID <user_id> and Server ID <server_id>.
```
You should see `logged in to discord as <bot-name>` in the gateway output within a few seconds.

#### Pair your Discord account

Expand All @@ -307,9 +419,9 @@ DM the bot in Discord. It will reply with a short pairing code.
<img width="400" height="400" src="assets/discord_pair_code.png" />
</p>

Approve it on the machine running OpenClaw Dashboard
Approve it on the machine running OpenClaw:
```bash
openclaw pairing approve <CODE>
openclaw pairing approve discord <CODE>
```

> Pairing codes expire after one hour.
Expand All @@ -322,12 +434,54 @@ You can now chat with your agent directly from Discord and offload tasks to your

---

### Option B: Telegram

Telegram is simpler than Discord for most users, it requires no server and no admin access.

#### Create a Telegram bot

1. Open Telegram and message **@BotFather**.
2. Send `/newbot` and follow the prompts. Save the bot token it gives you.

#### Configure OpenClaw for Telegram

Store the token as an environment variable:

```bash
export TELEGRAM_BOT_TOKEN="YOUR_BOT_TOKEN"
```

Add the channel configuration to `~/.openclaw/openclaw.json` (or patch it via the dashboard):

```json
{
"channels": {
"telegram": {
"enabled": true,
"botToken": "YOUR_BOT_TOKEN",
"dmPolicy": "pairing"
}
}
}
```

Restart the gateway, then send your bot any message in Telegram. Approve the pairing:

```bash
openclaw pairing list telegram
openclaw pairing approve telegram <CODE>
```

Pairing codes expire after one hour. You can now chat with your agent via Telegram DM.

---

## Next Steps

Now that your agent can receive commands from your phone and act on your local machine, here are three directions worth exploring:

1. **Stock market summarizer**: Schedule OpenClaw to fetch data from financial APIs on a fixed interval, summarize the day's movements with your local model, and push a digest to your Discord DM each morning.
1. **Stock market summarizer**: Schedule OpenClaw to fetch data from financial APIs on a fixed interval, summarize the day's movements with your local model, and push a digest to your phone each morning via your chosen channel.

2. **Fine-tuning monitor**: Kick off a training job remotely via Discord, then have the agent tail the training log and report periodic loss values, GPU utilization, and disk usage back to your phone. If the run stalls or VRAM spikes, you find out immediately without needing to be at the machine.
2. **Fine-tuning monitor**: Kick off a training job remotely via Telegram or Discord, then have the agent tail the training log and report periodic loss values, GPU utilization, and disk usage back to your phone. If the run stalls or VRAM spikes, you find out immediately without needing to be at the machine.

3. **IOT with a local VLM**: Point a camera at your front door, run a vision model on Lemonade, and have OpenClaw analyze frames on demand or on a trigger. Ask "did any packages arrive today?" from your phone and get a straight answer from your own hardware.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
32 changes: 32 additions & 0 deletions playbooks/supplemental/openclaw-lemonade-server/playbook.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,38 @@
"halo": [
"windows",
"linux"
],
"stx": [
"linux",
"windows"
],
"krk": [
"linux",
"windows"
]
},
"required_platforms": {
"halo": [
"windows",
"linux"
],
"halo_box": [
"windows",
"linux"
]
},
"published_platforms": {
"halo": [
"windows",
"linux"
],
"stx": [
"linux",
"windows"
],
"krk": [
"linux",
"windows"
]
},
"difficulty": "intermediate",
Expand Down