From 99e7df77ba5d03d311eb8651d33f717c8a9e436c Mon Sep 17 00:00:00 2001 From: Leopere Date: Tue, 24 Feb 2026 16:14:53 -0500 Subject: [PATCH] bump --- OPENCLAW-SETUP.md | 200 ++++++++++++++++++-- README.md | 4 +- docker-compose.yml | 8 + scripts/configure-groq.sh | 29 +++ scripts/install-channel-clients.sh | 71 +++++++ scripts/openclaw-groq-minimal.json.template | 1 + scripts/openclaw-groq.json.template | 1 + 7 files changed, 295 insertions(+), 19 deletions(-) create mode 100755 scripts/configure-groq.sh create mode 100755 scripts/install-channel-clients.sh create mode 100644 scripts/openclaw-groq-minimal.json.template create mode 100644 scripts/openclaw-groq.json.template diff --git a/OPENCLAW-SETUP.md b/OPENCLAW-SETUP.md index 92d6a96..912f870 100644 --- a/OPENCLAW-SETUP.md +++ b/OPENCLAW-SETUP.md @@ -2,6 +2,14 @@ Welcome to Clawtainer! This desktop has OpenClaw Gateway pre-installed and running on port 18789. +## Container layout + +- **Desktop (VNC):** http://localhost:6901 (via nginx proxy) +- **OpenClaw Gateway:** http://localhost:18789 +- **Gateway token:** `clawtainer` (enter in Settings → token) +- **Config:** `~/.openclaw/openclaw.json` (inside the container; `/home/kasm-user/.openclaw/`) +- **Env vars:** Project `.env` is loaded by Docker Compose; `GROQ_API_KEY`, `TELEGRAM_BOT_TOKEN`, etc. are passed into the container. + ## What is OpenClaw? OpenClaw is an open-source AI agent orchestration platform that connects to AI provider APIs. The Gateway is already running in the background, but you need to configure it with your API keys. @@ -30,34 +38,22 @@ This will guide you through: ### Option 3: Manual Configuration -Create or edit `~/.openclaw/openclaw.json`: +Create or edit `~/.openclaw/openclaw.json` inside the desktop (or merge config and `docker cp` it in). For **built-in providers** (Anthropic, OpenAI, Google, Groq), you can also use environment variables: add keys to the project `.env` and ensure they're in `docker-compose.yml` `environment` so they reach the container. + +Example manual `models.providers`: ```json { "models": { "providers": { - "anthropic": { - "apiKey": "sk-ant-your-key-here" - }, - "openai": { - "apiKey": "sk-your-key-here" - }, - "google": { - "apiKey": "AIza-your-key-here" - } + "anthropic": { "apiKey": "sk-ant-your-key-here" }, + "openai": { "apiKey": "sk-your-key-here" }, + "google": { "apiKey": "AIza-your-key-here" } } } } ``` -Or use environment variables in `~/.bashrc`: - -```bash -export ANTHROPIC_API_KEY="sk-ant-your-key-here" -export OPENAI_API_KEY="sk-your-key-here" -export GOOGLE_API_KEY="AIza-your-key-here" -``` - ## Get API Keys You'll need API keys from at least one provider: @@ -78,6 +74,61 @@ You'll need API keys from at least one provider: - Best for: Access to multiple models through one API - Pricing: Varies by model selected +- **Groq**: https://console.groq.com/keys + - Best for: Very fast inference (Llama 3.x, GPT-OSS). OpenAI-compatible API. + - Pricing: Low cost per token, free tier available. + +### Using Groq with Clawtainer + +Put `GROQ_API_KEY` in the project `.env`. Docker Compose passes it into the container. + +**Option A: Script (recommended)** + +From the project root, after `docker compose up -d`: + +```bash +./scripts/configure-groq.sh +docker exec clawtainer openclaw gateway restart +``` + +> **Note:** The script **overwrites** `~/.openclaw/openclaw.json` with a Groq-only config. If you have other providers or channels, run the script first, then add them manually to `openclaw.json`. + +**Option B: Manual config** + +Inside the desktop, edit `~/.openclaw/openclaw.json`. Add under `models.providers` (merge with existing providers if present): + +```json +"groq": { + "baseUrl": "https://api.groq.com/openai/v1", + "api": "openai-completions", + "apiKey": "your-groq-api-key", + "models": [ + { "id": "llama-3.3-70b-versatile", "name": "Llama 3.3 70B", "contextWindow": 131072 }, + { "id": "llama-3.1-8b-instant", "name": "Llama 3.1 8B", "contextWindow": 131072 } + ] +} +``` + +Use `"api": "openai-completions"` (not `"openai"`). Wrong API type can cause **Verification failed: status 404**. + +**Groq model IDs** + +| Model ID | Notes | +|----------|-------| +| `groq/llama-3.3-70b-versatile` | Best quality, 280 tok/s | +| `groq/llama-3.1-8b-instant` | Faster, cheaper | +| `groq/openai/gpt-oss-120b` | OpenAI OSS 120B | + +Set default: add `"agents": { "defaults": { "model": { "primary": "groq/llama-3.3-70b-versatile" } } }` to `openclaw.json`. + +**Verify your Groq key** + +```bash +curl -s "https://api.groq.com/openai/v1/models" -H "Authorization: Bearer $GROQ_API_KEY" | head -20 +``` + +If you get JSON back, the key works. If 401, the key is invalid. If 404, the URL is wrong. + ## Verify Setup After adding keys, test the connection: @@ -88,6 +139,107 @@ openclaw gateway status Or visit `http://localhost:18789` to see the Gateway control panel. +## Messaging Channels (WhatsApp, Telegram, Discord, Signal, …) + +You can add WhatsApp, Telegram, Discord, **Signal**, and other channels so the agent is reachable from your phone or team chat. Config lives in `~/.openclaw/openclaw.json` under `channels`. Restart the gateway after changes: `openclaw gateway restart`. + +**Install all channel plugins (no container rebuild):** Run `./scripts/install-channel-clients.sh` to add Mattermost, Teams, Matrix, Nostr, Zalo, and signal-cli into the running container via `docker exec`. Then restart: `docker exec clawtainer openclaw gateway restart`. + +### Telegram + +1. In Telegram, open a chat with **@BotFather**, run `/newbot`, and copy the bot token. +2. Add the token to `.env` as `TELEGRAM_BOT_TOKEN=...` (Clawtainer passes it into the container), or put it in `openclaw.json` under `channels.telegram.botToken`. +3. Add a `channels.telegram` block in `~/.openclaw/openclaw.json` (merge with existing `channels` if present): + +```json +"channels": { + "telegram": { + "enabled": true, + "dmPolicy": "pairing", + "groups": { "*": { "requireMention": true } } + } +} +``` + +4. Restart the gateway, then approve DMs: `openclaw pairing list telegram` and `openclaw pairing approve telegram `. + +- Docs: https://docs.openclaw.ai/channels/telegram + +### Discord + +1. In the [Discord Developer Portal](https://discord.com/developers/applications), create an application, add a Bot, and copy the bot token. +2. Add to `.env` as `DISCORD_BOT_TOKEN=...` (Clawtainer passes it in), or set `channels.discord.token` in `openclaw.json`. +3. Add a `channels.discord` block: + +```json +"channels": { + "discord": { + "enabled": true, + "dmPolicy": "pairing", + "allowFrom": ["YOUR_DISCORD_USER_ID"] + } +} +``` + +4. Invite the bot to your server (OAuth2 → URL Generator, scopes: bot; permissions as needed). Restart the gateway. + +- Docs: https://docs.openclaw.ai/gateway/configuration-reference (Discord section) + +### WhatsApp + +WhatsApp uses the gateway’s web channel (Baileys). A linked session must exist before WhatsApp will start. + +1. In `~/.openclaw/openclaw.json`, ensure the web channel and WhatsApp are enabled: + +```json +"channels": { + "whatsapp": { + "dmPolicy": "pairing", + "allowFrom": ["+15555550123"], + "groups": { "*": { "requireMention": true } } + } +}, +"web": { "enabled": true } +``` + +2. **Link a session once** (from a terminal inside the Clawtainer desktop, or via the Control UI if it supports pairing): + - Run `openclaw channels login` and complete the QR/linking flow for WhatsApp. +3. Restart the gateway. WhatsApp will start when the linked session exists. + +- Docs: https://docs.openclaw.ai/gateway/configuration-reference (WhatsApp section) + +### Signal + +OpenClaw supports **Signal** (E2E encrypted) via the external CLI **signal-cli**. You get DMs, groups, reactions, read receipts, and media. Use a **dedicated bot number** (recommended) or link an existing account with QR. + +**Requirements:** `signal-cli` must be installed where the gateway runs (inside the Clawtainer container if you use Docker). The native Linux build is preferred (no JVM). + +1. **Path A (QR link)** – Link an existing Signal account: run `signal-cli link -n "OpenClaw"` and scan the QR in Signal. +2. **Path B (dedicated number)** – Register a new number: `signal-cli -a +1… register` (and `--captcha` if required; see [Signal captcha](https://signalcaptchas.org/registration/generate.html)), then `signal-cli -a +1… verify `. +3. Add a `channels.signal` block in `~/.openclaw/openclaw.json`: + +```json +"channels": { + "signal": { + "enabled": true, + "account": "+15551234567", + "cliPath": "signal-cli", + "dmPolicy": "pairing", + "allowFrom": ["+15557654321"] + } +} +``` + +4. Restart the gateway. Approve DMs with `openclaw pairing list signal` and `openclaw pairing approve signal `. + +**Clawtainer note:** The stock image does not include `signal-cli`. Run `./scripts/install-channel-clients.sh` to install it in the running container, or add it in a custom Dockerfile. + +- Docs: https://docs.openclaw.ai/channels/signal + +### Other channels + +OpenClaw also supports **iMessage** (macOS only; uses `imsg` and Messages DB), **Slack** (bot + app tokens), **Google Chat** (service account), and **Mattermost** (plugin: `openclaw plugins install @openclaw/mattermost`). See the [configuration reference](https://docs.openclaw.ai/gateway/configuration-reference) for each. + ## Pre-installed Tools This desktop includes: @@ -108,6 +260,13 @@ You can change this by setting the `OPENCLAW_GATEWAY_TOKEN` environment variable ## Troubleshooting +**"Health offline" in the Control UI?** +The UI connects to the gateway over WebSocket. You must **enter the gateway token** so it can authenticate: +1. Open http://localhost:18789 +2. Open **Settings** (gear or settings panel) +3. Enter token: **`clawtainer`** (or whatever you set in `OPENCLAW_GATEWAY_TOKEN`) +4. Save / connect. Health should show online once the WebSocket connects with the token. + **Gateway not responding?** ```bash # Check if gateway is running @@ -122,6 +281,11 @@ openclaw gateway restart - Verify billing is enabled on the provider's platform - Check for typos in the key +**Groq: "Verification failed: status 404"?** +- Ensure `baseUrl` is exactly `https://api.groq.com/openai/v1` (no trailing slash) +- Use `"api": "openai-completions"` (not `"openai"`) +- Re-run `./scripts/configure-groq.sh` and restart the gateway, or verify your manual config matches the template + **Need help?** - OpenClaw Docs: https://docs.openclaw.ai/ - OpenClaw GitHub: https://github.com/openclaw/openclaw diff --git a/README.md b/README.md index 71e7521..869b22f 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,9 @@ docker compose up -d ``` - **Desktop**: **http://localhost:6901** (no password required) -- **OpenClaw Control UI**: http://localhost:18789 (token: `clawtainer`) +- **OpenClaw Control UI**: http://127.0.0.1:18789 (token: `clawtainer`) + +**If localhost:18789 fails** (common on macOS): use **http://127.0.0.1:18789** instead. Run `./scripts/configure-groq.sh` to set API keys and start the gateway. The nginx proxy strips TLS from the VNC connection for easy browser access. diff --git a/docker-compose.yml b/docker-compose.yml index 6cda35b..8ec2e85 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -8,6 +8,11 @@ services: - "18789:18789" # OpenClaw gateway Control UI environment: OPENCLAW_GATEWAY_TOKEN: ${OPENCLAW_GATEWAY_TOKEN:-clawtainer} + GROQ_API_KEY: ${GROQ_API_KEY:-} + TELEGRAM_BOT_TOKEN: ${TELEGRAM_BOT_TOKEN:-} + DISCORD_BOT_TOKEN: ${DISCORD_BOT_TOKEN:-} + volumes: + - openclaw-data:/home/kasm-user/.openclaw restart: unless-stopped networks: - clawtainer-net @@ -28,3 +33,6 @@ services: networks: clawtainer-net: driver: bridge + +volumes: + openclaw-data: diff --git a/scripts/configure-groq.sh b/scripts/configure-groq.sh new file mode 100755 index 0000000..4bfaa09 --- /dev/null +++ b/scripts/configure-groq.sh @@ -0,0 +1,29 @@ +#!/usr/bin/env bash +# Writes OpenClaw Groq provider config into the running clawtainer container +# using GROQ_API_KEY from project .env. Run after: docker compose up -d +set -e +cd "$(dirname "$0")/.." +if [ ! -f .env ]; then + echo "No .env found. Add GROQ_API_KEY=your-key to .env" + exit 1 +fi +# shellcheck source=/dev/null +source .env +if [ -z "${GROQ_API_KEY}" ]; then + echo "Set GROQ_API_KEY in .env" + exit 1 +fi +# Escape for JSON: \ and " +key_esc="${GROQ_API_KEY//\\/\\\\}" +key_esc="${key_esc//\"/\\\"}" +tmp=$(mktemp) +trap 'rm -f "$tmp"' EXIT +sed "s|GROQ_API_KEY_PLACEHOLDER|$key_esc|g" scripts/openclaw-groq.json.template > "$tmp" +docker exec clawtainer mkdir -p /home/kasm-user/.openclaw/canvas /home/kasm-user/.openclaw/cron /home/kasm-user/.openclaw/workspace +docker cp "$tmp" clawtainer:"/home/kasm-user/.openclaw/openclaw.json" +docker exec -u root clawtainer chown -R 1000:1000 /home/kasm-user/.openclaw +if ! docker exec clawtainer pgrep -x openclaw >/dev/null 2>&1; then + docker exec clawtainer bash -c 'nohup openclaw gateway --bind lan --allow-unconfigured >/tmp/openclaw.log 2>&1 &' + echo "Gateway started." +fi +echo "OpenClaw configured for Groq. Control UI: http://localhost:18789 (token: clawtainer)" diff --git a/scripts/install-channel-clients.sh b/scripts/install-channel-clients.sh new file mode 100755 index 0000000..b43cbc0 --- /dev/null +++ b/scripts/install-channel-clients.sh @@ -0,0 +1,71 @@ +#!/usr/bin/env bash +# Install all OpenClaw channel plugins + signal-cli into the RUNNING clawtainer +# container via docker exec. No image rebuild or container replace. +# Run after: docker compose up -d +set -e +cd "$(dirname "$0")/.." + +CONTAINER="${CLAWTAINER_CONTAINER:-clawtainer}" +OPENCLAW_USER=1000 +SIGNAL_CLI_VER="0.13.24" + +# Channel plugins from npm (official @openclaw) +PLUGINS=( + "@openclaw/mattermost" + "@openclaw/msteams" + "@openclaw/matrix" + "@openclaw/nostr" + "@openclaw/zalo" + "@openclaw/zalouser" +) + +if ! docker ps --format '{{.Names}}' | grep -q "^${CONTAINER}$"; then + echo "Container ${CONTAINER} is not running. Start with: docker compose up -d" + exit 1 +fi + +echo "Installing OpenClaw channel plugins..." +for pkg in "${PLUGINS[@]}"; do + echo " -> $pkg" + docker exec -u "$OPENCLAW_USER" "$CONTAINER" \ + openclaw --yes plugins install "$pkg" || true +done + +echo "Installing signal-cli..." +docker exec -u root "$CONTAINER" bash -c ' + set -e + VER='"$SIGNAL_CLI_VER"' + ARCH=$(uname -m) + INSTALL_DIR=/usr/local + cd /tmp + if command -v signal-cli >/dev/null 2>&1 && signal-cli --version 2>/dev/null | grep -q "$VER"; then + echo " signal-cli $VER already installed" + exit 0 + fi + mkdir -p "$INSTALL_DIR/bin" + if [ "$ARCH" = "x86_64" ] || [ "$ARCH" = "amd64" ]; then + echo " Using native binary (x86_64)" + curl -fsSL -o signal-cli.tar.gz \ + "https://github.com/AsamK/signal-cli/releases/download/v${VER}/signal-cli-${VER}-Linux-native.tar.gz" + tar xzf signal-cli.tar.gz + mv signal-cli "$INSTALL_DIR/bin/" + else + echo " Using JVM build (${ARCH})" + apt-get update -qq && apt-get install -y -qq openjdk-21-jre-headless + curl -fsSL -o signal-cli.tar.gz \ + "https://github.com/AsamK/signal-cli/releases/download/v${VER}/signal-cli-${VER}.tar.gz" + tar xzf signal-cli.tar.gz + cp -a signal-cli-${VER} /opt/signal-cli + ln -sf /opt/signal-cli/bin/signal-cli "$INSTALL_DIR/bin/signal-cli" + fi + chmod +x "$INSTALL_DIR/bin/signal-cli" + rm -rf /tmp/signal-cli* + echo " signal-cli installed" +' + +echo "" +echo "Done. Installed:" +echo " - Plugins: ${PLUGINS[*]}" +echo " - signal-cli (for Signal channel)" +echo "" +echo "Restart the gateway to load plugins: docker exec $CONTAINER openclaw gateway restart" diff --git a/scripts/openclaw-groq-minimal.json.template b/scripts/openclaw-groq-minimal.json.template new file mode 100644 index 0000000..ee6a53d --- /dev/null +++ b/scripts/openclaw-groq-minimal.json.template @@ -0,0 +1 @@ +{"agents":{"defaults":{"model":{"primary":"groq/llama-3.3-70b-versatile"}}}} diff --git a/scripts/openclaw-groq.json.template b/scripts/openclaw-groq.json.template new file mode 100644 index 0000000..e4fdf76 --- /dev/null +++ b/scripts/openclaw-groq.json.template @@ -0,0 +1 @@ +{"gateway":{"controlUi":{"dangerouslyAllowHostHeaderOriginFallback":true}},"agents":{"defaults":{"model":{"primary":"groq/llama-3.3-70b-versatile"}}},"models":{"mode":"merge","providers":{"groq":{"baseUrl":"https://api.groq.com/openai/v1","api":"openai-completions","apiKey":"GROQ_API_KEY_PLACEHOLDER","models":[{"id":"llama-3.3-70b-versatile","name":"Llama 3.3 70B","contextWindow":131072},{"id":"llama-3.1-8b-instant","name":"Llama 3.1 8B","contextWindow":131072}]}}}}