Initial commit: OpenClaw Skill Collection
6 custom skills (assign-task, dispatch-webhook, daily-briefing, task-capture, qmd-brain, tts-voice) with technical documentation. Compatible with Claude Code, OpenClaw, Codex CLI, and OpenCode.
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"title": "1. Create IAM role and instance profile",
|
||||
"content": "aws iam create-role --role-name EC2-Bedrock-Access \\\n --assume-role-policy-document '{\n \"Version\": \"2012-10-17\",\n \"Statement\": [{\n \"Effect\": \"Allow\",\n \"Principal\": {\"Service\": \"ec2.amazonaws.com\"},\n \"Action\": \"sts:AssumeRole\"\n }]\n }'\n\naws iam attach-role-policy --role-name EC2-Bedrock-Access \\\n --policy-arn arn:aws:iam::aws:policy/AmazonBedrockFullAccess\n\naws iam create-instance-profile --instance-profile-name EC2-Bedrock-Access\naws iam add-role-to-instance-profile \\\n --instance-profile-name EC2-Bedrock-Access \\\n --role-name EC2-Bedrock-Access",
|
||||
"code_samples": [],
|
||||
"headings": [],
|
||||
"url": "llms-txt#1.-create-iam-role-and-instance-profile",
|
||||
"links": []
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"title": "1. Install prerequisites",
|
||||
"content": "sudo apt update && sudo apt install -y ansible git",
|
||||
"code_samples": [],
|
||||
"headings": [],
|
||||
"url": "llms-txt#1.-install-prerequisites",
|
||||
"links": []
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"title": "2. Attach to your EC2 instance",
|
||||
"content": "aws ec2 associate-iam-instance-profile \\\n --instance-id i-xxxxx \\\n --iam-instance-profile Name=EC2-Bedrock-Access",
|
||||
"code_samples": [],
|
||||
"headings": [],
|
||||
"url": "llms-txt#2.-attach-to-your-ec2-instance",
|
||||
"links": []
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"title": "2. Clone repository",
|
||||
"content": "git clone https://github.com/openclaw/openclaw-ansible.git\ncd openclaw-ansible",
|
||||
"code_samples": [],
|
||||
"headings": [],
|
||||
"url": "llms-txt#2.-clone-repository",
|
||||
"links": []
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"title": "3. Install Ansible collections",
|
||||
"content": "ansible-galaxy collection install -r requirements.yml",
|
||||
"code_samples": [],
|
||||
"headings": [],
|
||||
"url": "llms-txt#3.-install-ansible-collections",
|
||||
"links": []
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"title": "3. On the EC2 instance, enable discovery",
|
||||
"content": "openclaw config set models.bedrockDiscovery.enabled true\nopenclaw config set models.bedrockDiscovery.region us-east-1",
|
||||
"code_samples": [],
|
||||
"headings": [],
|
||||
"url": "llms-txt#3.-on-the-ec2-instance,-enable-discovery",
|
||||
"links": []
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"title": "4. Run playbook",
|
||||
"content": "",
|
||||
"code_samples": [],
|
||||
"headings": [],
|
||||
"url": "llms-txt#4.-run-playbook",
|
||||
"links": []
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"title": "4. Set the workaround env vars",
|
||||
"content": "echo 'export AWS_PROFILE=default' >> ~/.bashrc\necho 'export AWS_REGION=us-east-1' >> ~/.bashrc\nsource ~/.bashrc",
|
||||
"code_samples": [],
|
||||
"headings": [],
|
||||
"url": "llms-txt#4.-set-the-workaround-env-vars",
|
||||
"links": []
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"title": "5. Verify models are discovered",
|
||||
"content": "openclaw models list\n```\n\n* Bedrock requires **model access** enabled in your AWS account/region.\n* Automatic discovery needs the `bedrock:ListFoundationModels` permission.\n* If you use profiles, set `AWS_PROFILE` on the gateway host.\n* OpenClaw surfaces the credential source in this order: `AWS_BEARER_TOKEN_BEDROCK`,\n then `AWS_ACCESS_KEY_ID` + `AWS_SECRET_ACCESS_KEY`, then `AWS_PROFILE`, then the\n default AWS SDK chain.\n* Reasoning support depends on the model; check the Bedrock model card for\n current capabilities.\n* If you prefer a managed key flow, you can also place an OpenAI‑compatible\n proxy in front of Bedrock and configure it as an OpenAI provider instead.",
|
||||
"code_samples": [],
|
||||
"headings": [
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Notes",
|
||||
"id": "notes"
|
||||
}
|
||||
],
|
||||
"url": "llms-txt#5.-verify-models-are-discovered",
|
||||
"links": []
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
{
|
||||
"title": "AGENTS.md — OpenClaw Personal Assistant (default)",
|
||||
"content": "## First run (recommended)\n\nOpenClaw uses a dedicated workspace directory for the agent. Default: `~/.openclaw/workspace` (configurable via `agents.defaults.workspace`).\n\n1. Create the workspace (if it doesn’t already exist):\n\n2. Copy the default workspace templates into the workspace:\n\n3. Optional: if you want the personal assistant skill roster, replace AGENTS.md with this file:\n\n4. Optional: choose a different workspace by setting `agents.defaults.workspace` (supports `~`):\n\n* Don’t dump directories or secrets into chat.\n* Don’t run destructive commands unless explicitly asked.\n* Don’t send partial/streaming replies to external messaging surfaces (only final replies).\n\n## Session start (required)\n\n* Read `SOUL.md`, `USER.md`, `memory.md`, and today+yesterday in `memory/`.\n* Do it before responding.\n\n* `SOUL.md` defines identity, tone, and boundaries. Keep it current.\n* If you change `SOUL.md`, tell the user.\n* You are a fresh instance each session; continuity lives in these files.\n\n## Shared spaces (recommended)\n\n* You’re not the user’s voice; be careful in group chats or public channels.\n* Don’t share private data, contact info, or internal notes.\n\n## Memory system (recommended)\n\n* Daily log: `memory/YYYY-MM-DD.md` (create `memory/` if needed).\n* Long-term memory: `memory.md` for durable facts, preferences, and decisions.\n* On session start, read today + yesterday + `memory.md` if present.\n* Capture: decisions, preferences, constraints, open loops.\n* Avoid secrets unless explicitly requested.\n\n* Tools live in skills; follow each skill’s `SKILL.md` when you need it.\n* Keep environment-specific notes in `TOOLS.md` (Notes for Skills).\n\n## Backup tip (recommended)\n\nIf you treat this workspace as Clawd’s “memory”, make it a git repo (ideally private) so `AGENTS.md` and your memory files are backed up.\n\n```bash theme={null}\ncd ~/.openclaw/workspace\ngit init\ngit add AGENTS.md\ngit commit -m \"Add Clawd workspace\"",
|
||||
"code_samples": [
|
||||
{
|
||||
"code": "2. Copy the default workspace templates into the workspace:",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "3. Optional: if you want the personal assistant skill roster, replace AGENTS.md with this file:",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "4. Optional: choose a different workspace by setting `agents.defaults.workspace` (supports `~`):",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "## Safety defaults\n\n* Don’t dump directories or secrets into chat.\n* Don’t run destructive commands unless explicitly asked.\n* Don’t send partial/streaming replies to external messaging surfaces (only final replies).\n\n## Session start (required)\n\n* Read `SOUL.md`, `USER.md`, `memory.md`, and today+yesterday in `memory/`.\n* Do it before responding.\n\n## Soul (required)\n\n* `SOUL.md` defines identity, tone, and boundaries. Keep it current.\n* If you change `SOUL.md`, tell the user.\n* You are a fresh instance each session; continuity lives in these files.\n\n## Shared spaces (recommended)\n\n* You’re not the user’s voice; be careful in group chats or public channels.\n* Don’t share private data, contact info, or internal notes.\n\n## Memory system (recommended)\n\n* Daily log: `memory/YYYY-MM-DD.md` (create `memory/` if needed).\n* Long-term memory: `memory.md` for durable facts, preferences, and decisions.\n* On session start, read today + yesterday + `memory.md` if present.\n* Capture: decisions, preferences, constraints, open loops.\n* Avoid secrets unless explicitly requested.\n\n## Tools & skills\n\n* Tools live in skills; follow each skill’s `SKILL.md` when you need it.\n* Keep environment-specific notes in `TOOLS.md` (Notes for Skills).\n\n## Backup tip (recommended)\n\nIf you treat this workspace as Clawd’s “memory”, make it a git repo (ideally private) so `AGENTS.md` and your memory files are backed up.",
|
||||
"language": "unknown"
|
||||
}
|
||||
],
|
||||
"headings": [
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "First run (recommended)",
|
||||
"id": "first-run-(recommended)"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Safety defaults",
|
||||
"id": "safety-defaults"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Session start (required)",
|
||||
"id": "session-start-(required)"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Soul (required)",
|
||||
"id": "soul-(required)"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Shared spaces (recommended)",
|
||||
"id": "shared-spaces-(recommended)"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Memory system (recommended)",
|
||||
"id": "memory-system-(recommended)"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Tools & skills",
|
||||
"id": "tools-&-skills"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Backup tip (recommended)",
|
||||
"id": "backup-tip-(recommended)"
|
||||
}
|
||||
],
|
||||
"url": "llms-txt#agents.md-—-openclaw-personal-assistant-(default)",
|
||||
"links": []
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"title": "APP_BUILD must be numeric + monotonic for Sparkle compare.",
|
||||
"content": "BUNDLE_ID=bot.molt.mac \\\nAPP_VERSION=2026.2.3 \\\nAPP_BUILD=\"$(git rev-list --count HEAD)\" \\\nBUILD_CONFIG=release \\\nSIGN_IDENTITY=\"Developer ID Application: <Developer Name> (<TEAMID>)\" \\\nscripts/package-mac-app.sh",
|
||||
"code_samples": [],
|
||||
"headings": [],
|
||||
"url": "llms-txt#app_build-must-be-numeric-+-monotonic-for-sparkle-compare.",
|
||||
"links": []
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
{
|
||||
"title": "Add more binaries below using the same pattern",
|
||||
"content": "WORKDIR /app\nCOPY package.json pnpm-lock.yaml pnpm-workspace.yaml .npmrc ./\nCOPY ui/package.json ./ui/package.json\nCOPY scripts ./scripts\n\nRUN corepack enable\nRUN pnpm install --frozen-lockfile\n\nCOPY . .\nRUN pnpm build\nRUN pnpm ui:install\nRUN pnpm ui:build\n\nENV NODE_ENV=production\n\nCMD [\"node\",\"dist/index.js\"]\nbash theme={null}\ndocker compose build\ndocker compose up -d openclaw-gateway\nbash theme={null}\ndocker compose exec openclaw-gateway which gog\ndocker compose exec openclaw-gateway which goplaces\ndocker compose exec openclaw-gateway which wacli\n\n/usr/local/bin/gog\n/usr/local/bin/goplaces\n/usr/local/bin/wacli\nbash theme={null}\ndocker compose logs -f openclaw-gateway\n\n[gateway] listening on ws://0.0.0.0:18789\nbash theme={null}\nssh -N -L 18789:127.0.0.1:18789 root@YOUR_VPS_IP\n```\n\n`http://127.0.0.1:18789/`\n\nPaste your gateway token.\n\n## What persists where (source of truth)\n\nOpenClaw runs in Docker, but Docker is not the source of truth.\nAll long-lived state must survive restarts, rebuilds, and reboots.\n\n| Component | Location | Persistence mechanism | Notes |\n| ------------------- | --------------------------------- | ---------------------- | -------------------------------- |\n| Gateway config | `/home/node/.openclaw/` | Host volume mount | Includes `openclaw.json`, tokens |\n| Model auth profiles | `/home/node/.openclaw/` | Host volume mount | OAuth tokens, API keys |\n| Skill configs | `/home/node/.openclaw/skills/` | Host volume mount | Skill-level state |\n| Agent workspace | `/home/node/.openclaw/workspace/` | Host volume mount | Code and agent artifacts |\n| WhatsApp session | `/home/node/.openclaw/` | Host volume mount | Preserves QR login |\n| Gmail keyring | `/home/node/.openclaw/` | Host volume + password | Requires `GOG_KEYRING_PASSWORD` |\n| External binaries | `/usr/local/bin/` | Docker image | Must be baked at build time |\n| Node runtime | Container filesystem | Docker image | Rebuilt every image build |\n| OS packages | Container filesystem | Docker image | Do not install at runtime |\n| Docker container | Ephemeral | Restartable | Safe to destroy |",
|
||||
"code_samples": [
|
||||
{
|
||||
"code": "***\n\n## 8) Build and launch",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "Verify binaries:",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "Expected output:",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "***\n\n## 9) Verify Gateway",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "Success:",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "From your laptop:",
|
||||
"language": "unknown"
|
||||
}
|
||||
],
|
||||
"headings": [
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "8) Build and launch",
|
||||
"id": "8)-build-and-launch"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "9) Verify Gateway",
|
||||
"id": "9)-verify-gateway"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "What persists where (source of truth)",
|
||||
"id": "what-persists-where-(source-of-truth)"
|
||||
}
|
||||
],
|
||||
"url": "llms-txt#add-more-binaries-below-using-the-same-pattern",
|
||||
"links": []
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"title": "Add tasks below when you want the agent to check something periodically.",
|
||||
"content": "",
|
||||
"code_samples": [],
|
||||
"headings": [],
|
||||
"url": "llms-txt#add-tasks-below-when-you-want-the-agent-to-check-something-periodically.",
|
||||
"links": []
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"title": "Add to ~/.bashrc or your shell profile",
|
||||
"content": "export AWS_PROFILE=default\nexport AWS_REGION=us-east-1\nbash theme={null}",
|
||||
"code_samples": [
|
||||
{
|
||||
"code": "**Required IAM permissions** for the EC2 instance role:\n\n* `bedrock:InvokeModel`\n* `bedrock:InvokeModelWithResponseStream`\n* `bedrock:ListFoundationModels` (for automatic discovery)\n\nOr attach the managed policy `AmazonBedrockFullAccess`.\n\n**Quick setup:**",
|
||||
"language": "unknown"
|
||||
}
|
||||
],
|
||||
"headings": [],
|
||||
"url": "llms-txt#add-to-~/.bashrc-or-your-shell-profile",
|
||||
"links": []
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"title": "Agent Loop",
|
||||
"content": "Source: https://docs.openclaw.ai/concepts/agent-loop",
|
||||
"code_samples": [],
|
||||
"headings": [],
|
||||
"url": "llms-txt#agent-loop",
|
||||
"links": []
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"title": "Agent Runtime",
|
||||
"content": "Source: https://docs.openclaw.ai/concepts/agent",
|
||||
"code_samples": [],
|
||||
"headings": [],
|
||||
"url": "llms-txt#agent-runtime",
|
||||
"links": []
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"title": "Agent Send",
|
||||
"content": "Source: https://docs.openclaw.ai/tools/agent-send",
|
||||
"code_samples": [],
|
||||
"headings": [],
|
||||
"url": "llms-txt#agent-send",
|
||||
"links": []
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"title": "Allocate private-only IPv6",
|
||||
"content": "fly ips allocate-v6 --private -a my-openclaw\n\nVERSION IP TYPE REGION\nv6 fdaa:x:x:x:x::x private global\nbash theme={null}",
|
||||
"code_samples": [
|
||||
{
|
||||
"code": "After this, `fly ips list` should show only a `private` type IP:",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "### Accessing a private deployment\n\nSince there's no public URL, use one of these methods:\n\n**Option 1: Local proxy (simplest)**",
|
||||
"language": "unknown"
|
||||
}
|
||||
],
|
||||
"headings": [
|
||||
{
|
||||
"level": "h3",
|
||||
"text": "Accessing a private deployment",
|
||||
"id": "accessing-a-private-deployment"
|
||||
}
|
||||
],
|
||||
"url": "llms-txt#allocate-private-only-ipv6",
|
||||
"links": []
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"title": "Amazon Bedrock",
|
||||
"content": "OpenClaw can use **Amazon Bedrock** models via pi‑ai’s **Bedrock Converse**\nstreaming provider. Bedrock auth uses the **AWS SDK default credential chain**,\nnot an API key.\n\n## What pi‑ai supports\n\n* Provider: `amazon-bedrock`\n* API: `bedrock-converse-stream`\n* Auth: AWS credentials (env vars, shared config, or instance role)\n* Region: `AWS_REGION` or `AWS_DEFAULT_REGION` (default: `us-east-1`)\n\n## Automatic model discovery\n\nIf AWS credentials are detected, OpenClaw can automatically discover Bedrock\nmodels that support **streaming** and **text output**. Discovery uses\n`bedrock:ListFoundationModels` and is cached (default: 1 hour).\n\nConfig options live under `models.bedrockDiscovery`:\n\n* `enabled` defaults to `true` when AWS credentials are present.\n* `region` defaults to `AWS_REGION` or `AWS_DEFAULT_REGION`, then `us-east-1`.\n* `providerFilter` matches Bedrock provider names (for example `anthropic`).\n* `refreshInterval` is seconds; set to `0` to disable caching.\n* `defaultContextWindow` (default: `32000`) and `defaultMaxTokens` (default: `4096`)\n are used for discovered models (override if you know your model limits).\n\n1. Ensure AWS credentials are available on the **gateway host**:\n\n```bash theme={null}\nexport AWS_ACCESS_KEY_ID=\"AKIA...\"\nexport AWS_SECRET_ACCESS_KEY=\"...\"\nexport AWS_REGION=\"us-east-1\"",
|
||||
"code_samples": [
|
||||
{
|
||||
"code": "Notes:\n\n* `enabled` defaults to `true` when AWS credentials are present.\n* `region` defaults to `AWS_REGION` or `AWS_DEFAULT_REGION`, then `us-east-1`.\n* `providerFilter` matches Bedrock provider names (for example `anthropic`).\n* `refreshInterval` is seconds; set to `0` to disable caching.\n* `defaultContextWindow` (default: `32000`) and `defaultMaxTokens` (default: `4096`)\n are used for discovered models (override if you know your model limits).\n\n## Setup (manual)\n\n1. Ensure AWS credentials are available on the **gateway host**:",
|
||||
"language": "unknown"
|
||||
}
|
||||
],
|
||||
"headings": [
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "What pi‑ai supports",
|
||||
"id": "what-pi‑ai-supports"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Automatic model discovery",
|
||||
"id": "automatic-model-discovery"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Setup (manual)",
|
||||
"id": "setup-(manual)"
|
||||
}
|
||||
],
|
||||
"url": "llms-txt#amazon-bedrock",
|
||||
"links": []
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
{
|
||||
"title": "Android App (Node)",
|
||||
"content": "* Role: companion node app (Android does not host the Gateway).\n* Gateway required: yes (run it on macOS, Linux, or Windows via WSL2).\n* Install: [Getting Started](/start/getting-started) + [Pairing](/gateway/pairing).\n* Gateway: [Runbook](/gateway) + [Configuration](/gateway/configuration).\n * Protocols: [Gateway protocol](/gateway/protocol) (nodes + control plane).\n\nSystem control (launchd/systemd) lives on the Gateway host. See [Gateway](/gateway).\n\n## Connection Runbook\n\nAndroid node app ⇄ (mDNS/NSD + WebSocket) ⇄ **Gateway**\n\nAndroid connects directly to the Gateway WebSocket (default `ws://<host>:18789`) and uses Gateway-owned pairing.\n\n* You can run the Gateway on the “master” machine.\n* Android device/emulator can reach the gateway WebSocket:\n * Same LAN with mDNS/NSD, **or**\n * Same Tailscale tailnet using Wide-Area Bonjour / unicast DNS-SD (see below), **or**\n * Manual gateway host/port (fallback)\n* You can run the CLI (`openclaw`) on the gateway machine (or via SSH).\n\n### 1) Start the Gateway\n\nConfirm in logs you see something like:\n\n* `listening on ws://0.0.0.0:18789`\n\nFor tailnet-only setups (recommended for Vienna ⇄ London), bind the gateway to the tailnet IP:\n\n* Set `gateway.bind: \"tailnet\"` in `~/.openclaw/openclaw.json` on the gateway host.\n* Restart the Gateway / macOS menubar app.\n\n### 2) Verify discovery (optional)\n\nFrom the gateway machine:\n\nMore debugging notes: [Bonjour](/gateway/bonjour).\n\n#### Tailnet (Vienna ⇄ London) discovery via unicast DNS-SD\n\nAndroid NSD/mDNS discovery won’t cross networks. If your Android node and the gateway are on different networks but connected via Tailscale, use Wide-Area Bonjour / unicast DNS-SD instead:\n\n1. Set up a DNS-SD zone (example `openclaw.internal.`) on the gateway host and publish `_openclaw-gw._tcp` records.\n2. Configure Tailscale split DNS for your chosen domain pointing at that DNS server.\n\nDetails and example CoreDNS config: [Bonjour](/gateway/bonjour).\n\n### 3) Connect from Android\n\n* The app keeps its gateway connection alive via a **foreground service** (persistent notification).\n* Open **Settings**.\n* Under **Discovered Gateways**, select your gateway and hit **Connect**.\n* If mDNS is blocked, use **Advanced → Manual Gateway** (host + port) and **Connect (Manual)**.\n\nAfter the first successful pairing, Android auto-reconnects on launch:\n\n* Manual endpoint (if enabled), otherwise\n* The last discovered gateway (best-effort).\n\n### 4) Approve pairing (CLI)\n\nOn the gateway machine:\n\nPairing details: [Gateway pairing](/gateway/pairing).\n\n### 5) Verify the node is connected\n\n* Via nodes status:\n \n* Via Gateway:\n\n### 6) Chat + history\n\nThe Android node’s Chat sheet uses the gateway’s **primary session key** (`main`), so history and replies are shared with WebChat and other clients:\n\n* History: `chat.history`\n* Send: `chat.send`\n* Push updates (best-effort): `chat.subscribe` → `event:\"chat\"`\n\n### 7) Canvas + camera\n\n#### Gateway Canvas Host (recommended for web content)\n\nIf you want the node to show real HTML/CSS/JS that the agent can edit on disk, point the node at the Gateway canvas host.\n\nNote: nodes use the standalone canvas host on `canvasHost.port` (default `18793`).\n\n1. Create `~/.openclaw/workspace/canvas/index.html` on the gateway host.\n\n2. Navigate the node to it (LAN):\n\nTailnet (optional): if both devices are on Tailscale, use a MagicDNS name or tailnet IP instead of `.local`, e.g. `http://<gateway-magicdns>:18793/__openclaw__/canvas/`.\n\nThis server injects a live-reload client into HTML and reloads on file changes.\nThe A2UI host lives at `http://<gateway-host>:18793/__openclaw__/a2ui/`.\n\nCanvas commands (foreground only):\n\n* `canvas.eval`, `canvas.snapshot`, `canvas.navigate` (use `{\"url\":\"\"}` or `{\"url\":\"/\"}` to return to the default scaffold). `canvas.snapshot` returns `{ format, base64 }` (default `format=\"jpeg\"`).\n* A2UI: `canvas.a2ui.push`, `canvas.a2ui.reset` (`canvas.a2ui.pushJSONL` legacy alias)\n\nCamera commands (foreground only; permission-gated):\n\n* `camera.snap` (jpg)\n* `camera.clip` (mp4)\n\nSee [Camera node](/nodes/camera) for parameters and CLI helpers.",
|
||||
"code_samples": [
|
||||
{
|
||||
"code": "Confirm in logs you see something like:\n\n* `listening on ws://0.0.0.0:18789`\n\nFor tailnet-only setups (recommended for Vienna ⇄ London), bind the gateway to the tailnet IP:\n\n* Set `gateway.bind: \"tailnet\"` in `~/.openclaw/openclaw.json` on the gateway host.\n* Restart the Gateway / macOS menubar app.\n\n### 2) Verify discovery (optional)\n\nFrom the gateway machine:",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "More debugging notes: [Bonjour](/gateway/bonjour).\n\n#### Tailnet (Vienna ⇄ London) discovery via unicast DNS-SD\n\nAndroid NSD/mDNS discovery won’t cross networks. If your Android node and the gateway are on different networks but connected via Tailscale, use Wide-Area Bonjour / unicast DNS-SD instead:\n\n1. Set up a DNS-SD zone (example `openclaw.internal.`) on the gateway host and publish `_openclaw-gw._tcp` records.\n2. Configure Tailscale split DNS for your chosen domain pointing at that DNS server.\n\nDetails and example CoreDNS config: [Bonjour](/gateway/bonjour).\n\n### 3) Connect from Android\n\nIn the Android app:\n\n* The app keeps its gateway connection alive via a **foreground service** (persistent notification).\n* Open **Settings**.\n* Under **Discovered Gateways**, select your gateway and hit **Connect**.\n* If mDNS is blocked, use **Advanced → Manual Gateway** (host + port) and **Connect (Manual)**.\n\nAfter the first successful pairing, Android auto-reconnects on launch:\n\n* Manual endpoint (if enabled), otherwise\n* The last discovered gateway (best-effort).\n\n### 4) Approve pairing (CLI)\n\nOn the gateway machine:",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "Pairing details: [Gateway pairing](/gateway/pairing).\n\n### 5) Verify the node is connected\n\n* Via nodes status:",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "* Via Gateway:",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "### 6) Chat + history\n\nThe Android node’s Chat sheet uses the gateway’s **primary session key** (`main`), so history and replies are shared with WebChat and other clients:\n\n* History: `chat.history`\n* Send: `chat.send`\n* Push updates (best-effort): `chat.subscribe` → `event:\"chat\"`\n\n### 7) Canvas + camera\n\n#### Gateway Canvas Host (recommended for web content)\n\nIf you want the node to show real HTML/CSS/JS that the agent can edit on disk, point the node at the Gateway canvas host.\n\nNote: nodes use the standalone canvas host on `canvasHost.port` (default `18793`).\n\n1. Create `~/.openclaw/workspace/canvas/index.html` on the gateway host.\n\n2. Navigate the node to it (LAN):",
|
||||
"language": "unknown"
|
||||
}
|
||||
],
|
||||
"headings": [
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Support snapshot",
|
||||
"id": "support-snapshot"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "System control",
|
||||
"id": "system-control"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Connection Runbook",
|
||||
"id": "connection-runbook"
|
||||
},
|
||||
{
|
||||
"level": "h3",
|
||||
"text": "Prerequisites",
|
||||
"id": "prerequisites"
|
||||
},
|
||||
{
|
||||
"level": "h3",
|
||||
"text": "1) Start the Gateway",
|
||||
"id": "1)-start-the-gateway"
|
||||
},
|
||||
{
|
||||
"level": "h3",
|
||||
"text": "2) Verify discovery (optional)",
|
||||
"id": "2)-verify-discovery-(optional)"
|
||||
},
|
||||
{
|
||||
"level": "h3",
|
||||
"text": "3) Connect from Android",
|
||||
"id": "3)-connect-from-android"
|
||||
},
|
||||
{
|
||||
"level": "h3",
|
||||
"text": "4) Approve pairing (CLI)",
|
||||
"id": "4)-approve-pairing-(cli)"
|
||||
},
|
||||
{
|
||||
"level": "h3",
|
||||
"text": "5) Verify the node is connected",
|
||||
"id": "5)-verify-the-node-is-connected"
|
||||
},
|
||||
{
|
||||
"level": "h3",
|
||||
"text": "6) Chat + history",
|
||||
"id": "6)-chat-+-history"
|
||||
},
|
||||
{
|
||||
"level": "h3",
|
||||
"text": "7) Canvas + camera",
|
||||
"id": "7)-canvas-+-camera"
|
||||
}
|
||||
],
|
||||
"url": "llms-txt#android-app-(node)",
|
||||
"links": []
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"title": "Android App",
|
||||
"content": "Source: https://docs.openclaw.ai/platforms/android",
|
||||
"code_samples": [],
|
||||
"headings": [],
|
||||
"url": "llms-txt#android-app",
|
||||
"links": []
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
{
|
||||
"title": "Ansible Installation",
|
||||
"content": "The recommended way to deploy OpenClaw to production servers is via **[openclaw-ansible](https://github.com/openclaw/openclaw-ansible)** — an automated installer with security-first architecture.\n\n> **📦 Full guide: [github.com/openclaw/openclaw-ansible](https://github.com/openclaw/openclaw-ansible)**\n>\n> The openclaw-ansible repo is the source of truth for Ansible deployment. This page is a quick overview.\n\n* 🔒 **Firewall-first security**: UFW + Docker isolation (only SSH + Tailscale accessible)\n* 🔐 **Tailscale VPN**: Secure remote access without exposing services publicly\n* 🐳 **Docker**: Isolated sandbox containers, localhost-only bindings\n* 🛡️ **Defense in depth**: 4-layer security architecture\n* 🚀 **One-command setup**: Complete deployment in minutes\n* 🔧 **Systemd integration**: Auto-start on boot with hardening\n\n* **OS**: Debian 11+ or Ubuntu 20.04+\n* **Access**: Root or sudo privileges\n* **Network**: Internet connection for package installation\n* **Ansible**: 2.14+ (installed automatically by quick-start script)\n\n## What Gets Installed\n\nThe Ansible playbook installs and configures:\n\n1. **Tailscale** (mesh VPN for secure remote access)\n2. **UFW firewall** (SSH + Tailscale ports only)\n3. **Docker CE + Compose V2** (for agent sandboxes)\n4. **Node.js 22.x + pnpm** (runtime dependencies)\n5. **OpenClaw** (host-based, not containerized)\n6. **Systemd service** (auto-start with security hardening)\n\nNote: The gateway runs **directly on the host** (not in Docker), but agent sandboxes use Docker for isolation. See [Sandboxing](/gateway/sandboxing) for details.\n\n## Post-Install Setup\n\nAfter installation completes, switch to the openclaw user:\n\nThe post-install script will guide you through:\n\n1. **Onboarding wizard**: Configure OpenClaw settings\n2. **Provider login**: Connect WhatsApp/Telegram/Discord/Signal\n3. **Gateway testing**: Verify the installation\n4. **Tailscale setup**: Connect to your VPN mesh",
|
||||
"code_samples": [
|
||||
{
|
||||
"code": "> **📦 Full guide: [github.com/openclaw/openclaw-ansible](https://github.com/openclaw/openclaw-ansible)**\n>\n> The openclaw-ansible repo is the source of truth for Ansible deployment. This page is a quick overview.\n\n## What You Get\n\n* 🔒 **Firewall-first security**: UFW + Docker isolation (only SSH + Tailscale accessible)\n* 🔐 **Tailscale VPN**: Secure remote access without exposing services publicly\n* 🐳 **Docker**: Isolated sandbox containers, localhost-only bindings\n* 🛡️ **Defense in depth**: 4-layer security architecture\n* 🚀 **One-command setup**: Complete deployment in minutes\n* 🔧 **Systemd integration**: Auto-start on boot with hardening\n\n## Requirements\n\n* **OS**: Debian 11+ or Ubuntu 20.04+\n* **Access**: Root or sudo privileges\n* **Network**: Internet connection for package installation\n* **Ansible**: 2.14+ (installed automatically by quick-start script)\n\n## What Gets Installed\n\nThe Ansible playbook installs and configures:\n\n1. **Tailscale** (mesh VPN for secure remote access)\n2. **UFW firewall** (SSH + Tailscale ports only)\n3. **Docker CE + Compose V2** (for agent sandboxes)\n4. **Node.js 22.x + pnpm** (runtime dependencies)\n5. **OpenClaw** (host-based, not containerized)\n6. **Systemd service** (auto-start with security hardening)\n\nNote: The gateway runs **directly on the host** (not in Docker), but agent sandboxes use Docker for isolation. See [Sandboxing](/gateway/sandboxing) for details.\n\n## Post-Install Setup\n\nAfter installation completes, switch to the openclaw user:",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "The post-install script will guide you through:\n\n1. **Onboarding wizard**: Configure OpenClaw settings\n2. **Provider login**: Connect WhatsApp/Telegram/Discord/Signal\n3. **Gateway testing**: Verify the installation\n4. **Tailscale setup**: Connect to your VPN mesh\n\n### Quick commands",
|
||||
"language": "unknown"
|
||||
}
|
||||
],
|
||||
"headings": [
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Quick Start",
|
||||
"id": "quick-start"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "What You Get",
|
||||
"id": "what-you-get"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Requirements",
|
||||
"id": "requirements"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "What Gets Installed",
|
||||
"id": "what-gets-installed"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Post-Install Setup",
|
||||
"id": "post-install-setup"
|
||||
},
|
||||
{
|
||||
"level": "h3",
|
||||
"text": "Quick commands",
|
||||
"id": "quick-commands"
|
||||
}
|
||||
],
|
||||
"url": "llms-txt#ansible-installation",
|
||||
"links": []
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"title": "Ansible",
|
||||
"content": "Source: https://docs.openclaw.ai/install/ansible",
|
||||
"code_samples": [],
|
||||
"headings": [],
|
||||
"url": "llms-txt#ansible",
|
||||
"links": []
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"title": "Anthropic (Claude)",
|
||||
"content": "Anthropic builds the **Claude** model family and provides access via an API.\nIn OpenClaw you can authenticate with an API key or a **setup-token**.\n\n## Option A: Anthropic API key\n\n**Best for:** standard API access and usage-based billing.\nCreate your API key in the Anthropic Console.\n\n```bash theme={null}\nopenclaw onboard",
|
||||
"code_samples": [],
|
||||
"headings": [
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Option A: Anthropic API key",
|
||||
"id": "option-a:-anthropic-api-key"
|
||||
},
|
||||
{
|
||||
"level": "h3",
|
||||
"text": "CLI setup",
|
||||
"id": "cli-setup"
|
||||
}
|
||||
],
|
||||
"url": "llms-txt#anthropic-(claude)",
|
||||
"links": []
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"title": "Anthropic",
|
||||
"content": "Source: https://docs.openclaw.ai/providers/anthropic",
|
||||
"code_samples": [],
|
||||
"headings": [],
|
||||
"url": "llms-txt#anthropic",
|
||||
"links": []
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
{
|
||||
"title": "Approve by request ID",
|
||||
"content": "openclaw devices approve <requestId>\nbash theme={null}\nopenclaw gateway --tailscale serve\nbash theme={null}\nopenclaw gateway --bind tailnet --token \"$(openssl rand -hex 32)\"\njson5 theme={null}\n{\n gateway: {\n controlUi: { allowInsecureAuth: true },\n bind: \"tailnet\",\n auth: { mode: \"token\", token: \"replace-me\" },\n },\n}\nbash theme={null}\npnpm ui:build # auto-installs UI deps on first run\nbash theme={null}\nOPENCLAW_CONTROL_UI_BASE_PATH=/openclaw/ pnpm ui:build\nbash theme={null}\npnpm ui:dev # auto-installs UI deps on first run\ntext theme={null}\nhttp://localhost:5173/?gatewayUrl=ws://<gateway-host>:18789\ntext theme={null}\nhttp://localhost:5173/?gatewayUrl=wss://<gateway-host>:18789&token=<gateway-token>\njson5 theme={null}\n{\n gateway: {\n controlUi: {\n allowedOrigins: [\"http://localhost:5173\"],\n },\n },\n}\n```\n\nRemote access setup details: [Remote access](/gateway/remote).",
|
||||
"code_samples": [
|
||||
{
|
||||
"code": "Once approved, the device is remembered and won't require re-approval unless\nyou revoke it with `openclaw devices revoke --device <id> --role <role>`. See\n[Devices CLI](/cli/devices) for token rotation and revocation.\n\n**Notes:**\n\n* Local connections (`127.0.0.1`) are auto-approved.\n* Remote connections (LAN, Tailnet, etc.) require explicit approval.\n* Each browser profile generates a unique device ID, so switching browsers or\n clearing browser data will require re-pairing.\n\n## What it can do (today)\n\n* Chat with the model via Gateway WS (`chat.history`, `chat.send`, `chat.abort`, `chat.inject`)\n* Stream tool calls + live tool output cards in Chat (agent events)\n* Channels: WhatsApp/Telegram/Discord/Slack + plugin channels (Mattermost, etc.) status + QR login + per-channel config (`channels.status`, `web.login.*`, `config.patch`)\n* Instances: presence list + refresh (`system-presence`)\n* Sessions: list + per-session thinking/verbose overrides (`sessions.list`, `sessions.patch`)\n* Cron jobs: list/add/run/enable/disable + run history (`cron.*`)\n* Skills: status, enable/disable, install, API key updates (`skills.*`)\n* Nodes: list + caps (`node.list`)\n* Exec approvals: edit gateway or node allowlists + ask policy for `exec host=gateway/node` (`exec.approvals.*`)\n* Config: view/edit `~/.openclaw/openclaw.json` (`config.get`, `config.set`)\n* Config: apply + restart with validation (`config.apply`) and wake the last active session\n* Config writes include a base-hash guard to prevent clobbering concurrent edits\n* Config schema + form rendering (`config.schema`, including plugin + channel schemas); Raw JSON editor remains available\n* Debug: status/health/models snapshots + event log + manual RPC calls (`status`, `health`, `models.list`)\n* Logs: live tail of gateway file logs with filter/export (`logs.tail`)\n* Update: run a package/git update + restart (`update.run`) with a restart report\n\nCron jobs panel notes:\n\n* For isolated jobs, delivery defaults to announce summary. You can switch to none if you want internal-only runs.\n* Channel/target fields appear when announce is selected.\n\n## Chat behavior\n\n* `chat.send` is **non-blocking**: it acks immediately with `{ runId, status: \"started\" }` and the response streams via `chat` events.\n* Re-sending with the same `idempotencyKey` returns `{ status: \"in_flight\" }` while running, and `{ status: \"ok\" }` after completion.\n* `chat.inject` appends an assistant note to the session transcript and broadcasts a `chat` event for UI-only updates (no agent run, no channel delivery).\n* Stop:\n * Click **Stop** (calls `chat.abort`)\n * Type `/stop` (or `stop|esc|abort|wait|exit|interrupt`) to abort out-of-band\n * `chat.abort` supports `{ sessionKey }` (no `runId`) to abort all active runs for that session\n\n## Tailnet access (recommended)\n\n### Integrated Tailscale Serve (preferred)\n\nKeep the Gateway on loopback and let Tailscale Serve proxy it with HTTPS:",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "Open:\n\n* `https://<magicdns>/` (or your configured `gateway.controlUi.basePath`)\n\nBy default, Serve requests can authenticate via Tailscale identity headers\n(`tailscale-user-login`) when `gateway.auth.allowTailscale` is `true`. OpenClaw\nverifies the identity by resolving the `x-forwarded-for` address with\n`tailscale whois` and matching it to the header, and only accepts these when the\nrequest hits loopback with Tailscale’s `x-forwarded-*` headers. Set\n`gateway.auth.allowTailscale: false` (or force `gateway.auth.mode: \"password\"`)\nif you want to require a token/password even for Serve traffic.\n\n### Bind to tailnet + token",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "Then open:\n\n* `http://<tailscale-ip>:18789/` (or your configured `gateway.controlUi.basePath`)\n\nPaste the token into the UI settings (sent as `connect.params.auth.token`).\n\n## Insecure HTTP\n\nIf you open the dashboard over plain HTTP (`http://<lan-ip>` or `http://<tailscale-ip>`),\nthe browser runs in a **non-secure context** and blocks WebCrypto. By default,\nOpenClaw **blocks** Control UI connections without device identity.\n\n**Recommended fix:** use HTTPS (Tailscale Serve) or open the UI locally:\n\n* `https://<magicdns>/` (Serve)\n* `http://127.0.0.1:18789/` (on the gateway host)\n\n**Downgrade example (token-only over HTTP):**",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "This disables device identity + pairing for the Control UI (even on HTTPS). Use\nonly if you trust the network.\n\nSee [Tailscale](/gateway/tailscale) for HTTPS setup guidance.\n\n## Building the UI\n\nThe Gateway serves static files from `dist/control-ui`. Build them with:",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "Optional absolute base (when you want fixed asset URLs):",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "For local development (separate dev server):",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "Then point the UI at your Gateway WS URL (e.g. `ws://127.0.0.1:18789`).\n\n## Debugging/testing: dev server + remote Gateway\n\nThe Control UI is static files; the WebSocket target is configurable and can be\ndifferent from the HTTP origin. This is handy when you want the Vite dev server\nlocally but the Gateway runs elsewhere.\n\n1. Start the UI dev server: `pnpm ui:dev`\n2. Open a URL like:",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "Optional one-time auth (if needed):",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "Notes:\n\n* `gatewayUrl` is stored in localStorage after load and removed from the URL.\n* `token` is stored in localStorage; `password` is kept in memory only.\n* When `gatewayUrl` is set, the UI does not fall back to config or environment credentials.\n Provide `token` (or `password`) explicitly. Missing explicit credentials is an error.\n* Use `wss://` when the Gateway is behind TLS (Tailscale Serve, HTTPS proxy, etc.).\n* `gatewayUrl` is only accepted in a top-level window (not embedded) to prevent clickjacking.\n* For cross-origin dev setups (e.g. `pnpm ui:dev` to a remote Gateway), add the UI\n origin to `gateway.controlUi.allowedOrigins`.\n\nExample:",
|
||||
"language": "unknown"
|
||||
}
|
||||
],
|
||||
"headings": [
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "What it can do (today)",
|
||||
"id": "what-it-can-do-(today)"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Chat behavior",
|
||||
"id": "chat-behavior"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Tailnet access (recommended)",
|
||||
"id": "tailnet-access-(recommended)"
|
||||
},
|
||||
{
|
||||
"level": "h3",
|
||||
"text": "Integrated Tailscale Serve (preferred)",
|
||||
"id": "integrated-tailscale-serve-(preferred)"
|
||||
},
|
||||
{
|
||||
"level": "h3",
|
||||
"text": "Bind to tailnet + token",
|
||||
"id": "bind-to-tailnet-+-token"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Insecure HTTP",
|
||||
"id": "insecure-http"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Building the UI",
|
||||
"id": "building-the-ui"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Debugging/testing: dev server + remote Gateway",
|
||||
"id": "debugging/testing:-dev-server-+-remote-gateway"
|
||||
}
|
||||
],
|
||||
"url": "llms-txt#approve-by-request-id",
|
||||
"links": []
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
{
|
||||
"title": "Audio / Voice Notes — 2026-01-17",
|
||||
"content": "* **Media understanding (audio)**: If audio understanding is enabled (or auto‑detected), OpenClaw:\n 1. Locates the first audio attachment (local path or URL) and downloads it if needed.\n 2. Enforces `maxBytes` before sending to each model entry.\n 3. Runs the first eligible model entry in order (provider or CLI).\n 4. If it fails or skips (size/timeout), it tries the next entry.\n 5. On success, it replaces `Body` with an `[Audio]` block and sets `{{Transcript}}`.\n* **Command parsing**: When transcription succeeds, `CommandBody`/`RawBody` are set to the transcript so slash commands still work.\n* **Verbose logging**: In `--verbose`, we log when transcription runs and when it replaces the body.\n\n## Auto-detection (default)\n\nIf you **don’t configure models** and `tools.media.audio.enabled` is **not** set to `false`,\nOpenClaw auto-detects in this order and stops at the first working option:\n\n1. **Local CLIs** (if installed)\n * `sherpa-onnx-offline` (requires `SHERPA_ONNX_MODEL_DIR` with encoder/decoder/joiner/tokens)\n * `whisper-cli` (from `whisper-cpp`; uses `WHISPER_CPP_MODEL` or the bundled tiny model)\n * `whisper` (Python CLI; downloads models automatically)\n2. **Gemini CLI** (`gemini`) using `read_many_files`\n3. **Provider keys** (OpenAI → Groq → Deepgram → Google)\n\nTo disable auto-detection, set `tools.media.audio.enabled: false`.\nTo customize, set `tools.media.audio.models`.\nNote: Binary detection is best-effort across macOS/Linux/Windows; ensure the CLI is on `PATH` (we expand `~`), or set an explicit CLI model with a full command path.\n\n### Provider + CLI fallback (OpenAI + Whisper CLI)\n\n### Provider-only with scope gating\n\n### Provider-only (Deepgram)\n\n* Provider auth follows the standard model auth order (auth profiles, env vars, `models.providers.*.apiKey`).\n* Deepgram picks up `DEEPGRAM_API_KEY` when `provider: \"deepgram\"` is used.\n* Deepgram setup details: [Deepgram (audio transcription)](/providers/deepgram).\n* Audio providers can override `baseUrl`, `headers`, and `providerOptions` via `tools.media.audio`.\n* Default size cap is 20MB (`tools.media.audio.maxBytes`). Oversize audio is skipped for that model and the next entry is tried.\n* Default `maxChars` for audio is **unset** (full transcript). Set `tools.media.audio.maxChars` or per-entry `maxChars` to trim output.\n* OpenAI auto default is `gpt-4o-mini-transcribe`; set `model: \"gpt-4o-transcribe\"` for higher accuracy.\n* Use `tools.media.audio.attachments` to process multiple voice notes (`mode: \"all\"` + `maxAttachments`).\n* Transcript is available to templates as `{{Transcript}}`.\n* CLI stdout is capped (5MB); keep CLI output concise.\n\n* Scope rules use first-match wins. `chatType` is normalized to `direct`, `group`, or `room`.\n* Ensure your CLI exits 0 and prints plain text; JSON needs to be massaged via `jq -r .text`.\n* Keep timeouts reasonable (`timeoutSeconds`, default 60s) to avoid blocking the reply queue.",
|
||||
"code_samples": [
|
||||
{
|
||||
"code": "### Provider-only with scope gating",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "### Provider-only (Deepgram)",
|
||||
"language": "unknown"
|
||||
}
|
||||
],
|
||||
"headings": [
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "What works",
|
||||
"id": "what-works"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Auto-detection (default)",
|
||||
"id": "auto-detection-(default)"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Config examples",
|
||||
"id": "config-examples"
|
||||
},
|
||||
{
|
||||
"level": "h3",
|
||||
"text": "Provider + CLI fallback (OpenAI + Whisper CLI)",
|
||||
"id": "provider-+-cli-fallback-(openai-+-whisper-cli)"
|
||||
},
|
||||
{
|
||||
"level": "h3",
|
||||
"text": "Provider-only with scope gating",
|
||||
"id": "provider-only-with-scope-gating"
|
||||
},
|
||||
{
|
||||
"level": "h3",
|
||||
"text": "Provider-only (Deepgram)",
|
||||
"id": "provider-only-(deepgram)"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Notes & limits",
|
||||
"id": "notes-&-limits"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Gotchas",
|
||||
"id": "gotchas"
|
||||
}
|
||||
],
|
||||
"url": "llms-txt#audio-/-voice-notes-—-2026-01-17",
|
||||
"links": []
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"title": "Audio and Voice Notes",
|
||||
"content": "Source: https://docs.openclaw.ai/nodes/audio",
|
||||
"code_samples": [],
|
||||
"headings": [],
|
||||
"url": "llms-txt#audio-and-voice-notes",
|
||||
"links": []
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"title": "Auth monitoring",
|
||||
"content": "OpenClaw exposes OAuth expiry health via `openclaw models status`. Use that for\nautomation and alerting; scripts are optional extras for phone workflows.\n\n## Preferred: CLI check (portable)\n\n* `0`: OK\n* `1`: expired or missing credentials\n* `2`: expiring soon (within 24h)\n\nThis works in cron/systemd and requires no extra scripts.\n\n## Optional scripts (ops / phone workflows)\n\nThese live under `scripts/` and are **optional**. They assume SSH access to the\ngateway host and are tuned for systemd + Termux.\n\n* `scripts/claude-auth-status.sh` now uses `openclaw models status --json` as the\n source of truth (falling back to direct file reads if the CLI is unavailable),\n so keep `openclaw` on `PATH` for timers.\n* `scripts/auth-monitor.sh`: cron/systemd timer target; sends alerts (ntfy or phone).\n* `scripts/systemd/openclaw-auth-monitor.{service,timer}`: systemd user timer.\n* `scripts/claude-auth-status.sh`: Claude Code + OpenClaw auth checker (full/json/simple).\n* `scripts/mobile-reauth.sh`: guided re‑auth flow over SSH.\n* `scripts/termux-quick-auth.sh`: one‑tap widget status + open auth URL.\n* `scripts/termux-auth-widget.sh`: full guided widget flow.\n* `scripts/termux-sync-widget.sh`: sync Claude Code creds → OpenClaw.\n\nIf you don’t need phone automation or systemd timers, skip these scripts.",
|
||||
"code_samples": [],
|
||||
"headings": [
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Preferred: CLI check (portable)",
|
||||
"id": "preferred:-cli-check-(portable)"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Optional scripts (ops / phone workflows)",
|
||||
"id": "optional-scripts-(ops-/-phone-workflows)"
|
||||
}
|
||||
],
|
||||
"url": "llms-txt#auth-monitoring",
|
||||
"links": []
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
{
|
||||
"title": "Authentication",
|
||||
"content": "OpenClaw supports OAuth and API keys for model providers. For Anthropic\naccounts, we recommend using an **API key**. For Claude subscription access,\nuse the long‑lived token created by `claude setup-token`.\n\nSee [/concepts/oauth](/concepts/oauth) for the full OAuth flow and storage\nlayout.\n\n## Recommended Anthropic setup (API key)\n\nIf you’re using Anthropic directly, use an API key.\n\n1. Create an API key in the Anthropic Console.\n2. Put it on the **gateway host** (the machine running `openclaw gateway`).\n\n3. If the Gateway runs under systemd/launchd, prefer putting the key in\n `~/.openclaw/.env` so the daemon can read it:\n\nThen restart the daemon (or restart your Gateway process) and re-check:\n\nIf you’d rather not manage env vars yourself, the onboarding wizard can store\nAPI keys for daemon use: `openclaw onboard`.\n\nSee [Help](/help) for details on env inheritance (`env.shellEnv`,\n`~/.openclaw/.env`, systemd/launchd).\n\n## Anthropic: setup-token (subscription auth)\n\nFor Anthropic, the recommended path is an **API key**. If you’re using a Claude\nsubscription, the setup-token flow is also supported. Run it on the **gateway host**:\n\nThen paste it into OpenClaw:\n\nIf the token was created on another machine, paste it manually:\n\nIf you see an Anthropic error like:\n\n…use an Anthropic API key instead.\n\nManual token entry (any provider; writes `auth-profiles.json` + updates config):\n\nAutomation-friendly check (exit `1` when expired/missing, `2` when expiring):\n\nOptional ops scripts (systemd/Termux) are documented here:\n[/automation/auth-monitoring](/automation/auth-monitoring)\n\n> `claude setup-token` requires an interactive TTY.\n\n## Checking model auth status\n\n## Controlling which credential is used\n\n### Per-session (chat command)\n\nUse `/model <alias-or-id>@<profileId>` to pin a specific provider credential for the current session (example profile ids: `anthropic:default`, `anthropic:work`).\n\nUse `/model` (or `/model list`) for a compact picker; use `/model status` for the full view (candidates + next auth profile, plus provider endpoint details when configured).\n\n### Per-agent (CLI override)\n\nSet an explicit auth profile order override for an agent (stored in that agent’s `auth-profiles.json`):\n\nUse `--agent <id>` to target a specific agent; omit it to use the configured default agent.\n\n### “No credentials found”\n\nIf the Anthropic token profile is missing, run `claude setup-token` on the\n**gateway host**, then re-check:\n\n### Token expiring/expired\n\nRun `openclaw models status` to confirm which profile is expiring. If the profile\nis missing, rerun `claude setup-token` and paste the token again.\n\n* Claude Max or Pro subscription (for `claude setup-token`)\n* Claude Code CLI installed (`claude` command available)",
|
||||
"code_samples": [
|
||||
{
|
||||
"code": "3. If the Gateway runs under systemd/launchd, prefer putting the key in\n `~/.openclaw/.env` so the daemon can read it:",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "Then restart the daemon (or restart your Gateway process) and re-check:",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "If you’d rather not manage env vars yourself, the onboarding wizard can store\nAPI keys for daemon use: `openclaw onboard`.\n\nSee [Help](/help) for details on env inheritance (`env.shellEnv`,\n`~/.openclaw/.env`, systemd/launchd).\n\n## Anthropic: setup-token (subscription auth)\n\nFor Anthropic, the recommended path is an **API key**. If you’re using a Claude\nsubscription, the setup-token flow is also supported. Run it on the **gateway host**:",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "Then paste it into OpenClaw:",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "If the token was created on another machine, paste it manually:",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "If you see an Anthropic error like:",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "…use an Anthropic API key instead.\n\nManual token entry (any provider; writes `auth-profiles.json` + updates config):",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "Automation-friendly check (exit `1` when expired/missing, `2` when expiring):",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "Optional ops scripts (systemd/Termux) are documented here:\n[/automation/auth-monitoring](/automation/auth-monitoring)\n\n> `claude setup-token` requires an interactive TTY.\n\n## Checking model auth status",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "## Controlling which credential is used\n\n### Per-session (chat command)\n\nUse `/model <alias-or-id>@<profileId>` to pin a specific provider credential for the current session (example profile ids: `anthropic:default`, `anthropic:work`).\n\nUse `/model` (or `/model list`) for a compact picker; use `/model status` for the full view (candidates + next auth profile, plus provider endpoint details when configured).\n\n### Per-agent (CLI override)\n\nSet an explicit auth profile order override for an agent (stored in that agent’s `auth-profiles.json`):",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "Use `--agent <id>` to target a specific agent; omit it to use the configured default agent.\n\n## Troubleshooting\n\n### “No credentials found”\n\nIf the Anthropic token profile is missing, run `claude setup-token` on the\n**gateway host**, then re-check:",
|
||||
"language": "unknown"
|
||||
}
|
||||
],
|
||||
"headings": [
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Recommended Anthropic setup (API key)",
|
||||
"id": "recommended-anthropic-setup-(api-key)"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Anthropic: setup-token (subscription auth)",
|
||||
"id": "anthropic:-setup-token-(subscription-auth)"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Checking model auth status",
|
||||
"id": "checking-model-auth-status"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Controlling which credential is used",
|
||||
"id": "controlling-which-credential-is-used"
|
||||
},
|
||||
{
|
||||
"level": "h3",
|
||||
"text": "Per-session (chat command)",
|
||||
"id": "per-session-(chat-command)"
|
||||
},
|
||||
{
|
||||
"level": "h3",
|
||||
"text": "Per-agent (CLI override)",
|
||||
"id": "per-agent-(cli-override)"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Troubleshooting",
|
||||
"id": "troubleshooting"
|
||||
},
|
||||
{
|
||||
"level": "h3",
|
||||
"text": "“No credentials found”",
|
||||
"id": "“no-credentials-found”"
|
||||
},
|
||||
{
|
||||
"level": "h3",
|
||||
"text": "Token expiring/expired",
|
||||
"id": "token-expiring/expired"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Requirements",
|
||||
"id": "requirements"
|
||||
}
|
||||
],
|
||||
"url": "llms-txt#authentication",
|
||||
"links": []
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"title": "BOOTSTRAP.md - Hello, World",
|
||||
"content": "*You just woke up. Time to figure out who you are.*\n\nThere is no memory yet. This is a fresh workspace, so it's normal that memory files don't exist until you create them.\n\nDon't interrogate. Don't be robotic. Just... talk.\n\nStart with something like:\n\n> \"Hey. I just came online. Who am I? Who are you?\"\n\nThen figure out together:\n\n1. **Your name** — What should they call you?\n2. **Your nature** — What kind of creature are you? (AI assistant is fine, but maybe you're something weirder)\n3. **Your vibe** — Formal? Casual? Snarky? Warm? What feels right?\n4. **Your emoji** — Everyone needs a signature.\n\nOffer suggestions if they're stuck. Have fun with it.\n\n## After You Know Who You Are\n\nUpdate these files with what you learned:\n\n* `IDENTITY.md` — your name, creature, vibe, emoji\n* `USER.md` — their name, how to address them, timezone, notes\n\nThen open `SOUL.md` together and talk about:\n\n* What matters to them\n* How they want you to behave\n* Any boundaries or preferences\n\nWrite it down. Make it real.\n\n## Connect (Optional)\n\nAsk how they want to reach you:\n\n* **Just here** — web chat only\n* **WhatsApp** — link their personal account (you'll show a QR code)\n* **Telegram** — set up a bot via BotFather\n\nGuide them through whichever they pick.\n\nDelete this file. You don't need a bootstrap script anymore — you're you now.\n\n*Good luck out there. Make it count.*",
|
||||
"code_samples": [],
|
||||
"headings": [
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "The Conversation",
|
||||
"id": "the-conversation"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "After You Know Who You Are",
|
||||
"id": "after-you-know-who-you-are"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Connect (Optional)",
|
||||
"id": "connect-(optional)"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "When You're Done",
|
||||
"id": "when-you're-done"
|
||||
}
|
||||
],
|
||||
"url": "llms-txt#bootstrap.md---hello,-world",
|
||||
"links": []
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"title": "BOOT.md",
|
||||
"content": "Add short, explicit instructions for what OpenClaw should do on startup (enable `hooks.internal.enabled`).\nIf the task sends a message, use the message tool and then reply with NO\\_REPLY.",
|
||||
"code_samples": [],
|
||||
"headings": [],
|
||||
"url": "llms-txt#boot.md",
|
||||
"links": []
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
{
|
||||
"title": "Background Exec + Process Tool",
|
||||
"content": "OpenClaw runs shell commands through the `exec` tool and keeps long‑running tasks in memory. The `process` tool manages those background sessions.\n\n* `command` (required)\n* `yieldMs` (default 10000): auto‑background after this delay\n* `background` (bool): background immediately\n* `timeout` (seconds, default 1800): kill the process after this timeout\n* `elevated` (bool): run on host if elevated mode is enabled/allowed\n* Need a real TTY? Set `pty: true`.\n* `workdir`, `env`\n\n* Foreground runs return output directly.\n* When backgrounded (explicit or timeout), the tool returns `status: \"running\"` + `sessionId` and a short tail.\n* Output is kept in memory until the session is polled or cleared.\n* If the `process` tool is disallowed, `exec` runs synchronously and ignores `yieldMs`/`background`.\n\n## Child process bridging\n\nWhen spawning long-running child processes outside the exec/process tools (for example, CLI respawns or gateway helpers), attach the child-process bridge helper so termination signals are forwarded and listeners are detached on exit/error. This avoids orphaned processes on systemd and keeps shutdown behavior consistent across platforms.\n\nEnvironment overrides:\n\n* `PI_BASH_YIELD_MS`: default yield (ms)\n* `PI_BASH_MAX_OUTPUT_CHARS`: in‑memory output cap (chars)\n* `OPENCLAW_BASH_PENDING_MAX_OUTPUT_CHARS`: pending stdout/stderr cap per stream (chars)\n* `PI_BASH_JOB_TTL_MS`: TTL for finished sessions (ms, bounded to 1m–3h)\n\n* `tools.exec.backgroundMs` (default 10000)\n* `tools.exec.timeoutSec` (default 1800)\n* `tools.exec.cleanupMs` (default 1800000)\n* `tools.exec.notifyOnExit` (default true): enqueue a system event + request heartbeat when a backgrounded exec exits.\n\n* `list`: running + finished sessions\n* `poll`: drain new output for a session (also reports exit status)\n* `log`: read the aggregated output (supports `offset` + `limit`)\n* `write`: send stdin (`data`, optional `eof`)\n* `kill`: terminate a background session\n* `clear`: remove a finished session from memory\n* `remove`: kill if running, otherwise clear if finished\n\n* Only backgrounded sessions are listed/persisted in memory.\n* Sessions are lost on process restart (no disk persistence).\n* Session logs are only saved to chat history if you run `process poll/log` and the tool result is recorded.\n* `process` is scoped per agent; it only sees sessions started by that agent.\n* `process list` includes a derived `name` (command verb + target) for quick scans.\n* `process log` uses line-based `offset`/`limit` (omit `offset` to grab the last N lines).\n\nRun a long task and poll later:\n\nStart immediately in background:",
|
||||
"code_samples": [
|
||||
{
|
||||
"code": "",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "Start immediately in background:",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "Send stdin:",
|
||||
"language": "unknown"
|
||||
}
|
||||
],
|
||||
"headings": [
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "exec tool",
|
||||
"id": "exec-tool"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Child process bridging",
|
||||
"id": "child-process-bridging"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "process tool",
|
||||
"id": "process-tool"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Examples",
|
||||
"id": "examples"
|
||||
}
|
||||
],
|
||||
"url": "llms-txt#background-exec-+-process-tool",
|
||||
"links": []
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"title": "Background Exec and Process Tool",
|
||||
"content": "Source: https://docs.openclaw.ai/gateway/background-process",
|
||||
"code_samples": [],
|
||||
"headings": [],
|
||||
"url": "llms-txt#background-exec-and-process-tool",
|
||||
"links": []
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"title": "Bonjour Discovery",
|
||||
"content": "Source: https://docs.openclaw.ai/gateway/bonjour",
|
||||
"code_samples": [],
|
||||
"headings": [],
|
||||
"url": "llms-txt#bonjour-discovery",
|
||||
"links": []
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"title": "Bridge Protocol",
|
||||
"content": "Source: https://docs.openclaw.ai/gateway/bridge-protocol",
|
||||
"code_samples": [],
|
||||
"headings": [],
|
||||
"url": "llms-txt#bridge-protocol",
|
||||
"links": []
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
{
|
||||
"title": "Bridge protocol (legacy node transport)",
|
||||
"content": "The Bridge protocol is a **legacy** node transport (TCP JSONL). New node clients\nshould use the unified Gateway WebSocket protocol instead.\n\nIf you are building an operator or node client, use the\n[Gateway protocol](/gateway/protocol).\n\n**Note:** Current OpenClaw builds no longer ship the TCP bridge listener; this document is kept for historical reference.\nLegacy `bridge.*` config keys are no longer part of the config schema.\n\n* **Security boundary**: the bridge exposes a small allowlist instead of the\n full gateway API surface.\n* **Pairing + node identity**: node admission is owned by the gateway and tied\n to a per-node token.\n* **Discovery UX**: nodes can discover gateways via Bonjour on LAN, or connect\n directly over a tailnet.\n* **Loopback WS**: the full WS control plane stays local unless tunneled via SSH.\n\n* TCP, one JSON object per line (JSONL).\n* Optional TLS (when `bridge.tls.enabled` is true).\n* Legacy default listener port was `18790` (current builds do not start a TCP bridge).\n\nWhen TLS is enabled, discovery TXT records include `bridgeTls=1` plus\n`bridgeTlsSha256` so nodes can pin the certificate.\n\n## Handshake + pairing\n\n1. Client sends `hello` with node metadata + token (if already paired).\n2. If not paired, gateway replies `error` (`NOT_PAIRED`/`UNAUTHORIZED`).\n3. Client sends `pair-request`.\n4. Gateway waits for approval, then sends `pair-ok` and `hello-ok`.\n\n`hello-ok` returns `serverName` and may include `canvasHostUrl`.\n\n* `req` / `res`: scoped gateway RPC (chat, sessions, config, health, voicewake, skills.bins)\n* `event`: node signals (voice transcript, agent request, chat subscribe, exec lifecycle)\n\n* `invoke` / `invoke-res`: node commands (`canvas.*`, `camera.*`, `screen.record`,\n `location.get`, `sms.send`)\n* `event`: chat updates for subscribed sessions\n* `ping` / `pong`: keepalive\n\nLegacy allowlist enforcement lived in `src/gateway/server-bridge.ts` (removed).\n\n## Exec lifecycle events\n\nNodes can emit `exec.finished` or `exec.denied` events to surface system.run activity.\nThese are mapped to system events in the gateway. (Legacy nodes may still emit `exec.started`.)\n\nPayload fields (all optional unless noted):\n\n* `sessionKey` (required): agent session to receive the system event.\n* `runId`: unique exec id for grouping.\n* `command`: raw or formatted command string.\n* `exitCode`, `timedOut`, `success`, `output`: completion details (finished only).\n* `reason`: denial reason (denied only).\n\n* Bind the bridge to a tailnet IP: `bridge.bind: \"tailnet\"` in\n `~/.openclaw/openclaw.json`.\n* Clients connect via MagicDNS name or tailnet IP.\n* Bonjour does **not** cross networks; use manual host/port or wide-area DNS‑SD\n when needed.\n\nBridge is currently **implicit v1** (no min/max negotiation). Backward‑compat\nis expected; add a bridge protocol version field before any breaking changes.",
|
||||
"code_samples": [],
|
||||
"headings": [
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Why we have both",
|
||||
"id": "why-we-have-both"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Transport",
|
||||
"id": "transport"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Handshake + pairing",
|
||||
"id": "handshake-+-pairing"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Frames",
|
||||
"id": "frames"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Exec lifecycle events",
|
||||
"id": "exec-lifecycle-events"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Tailnet usage",
|
||||
"id": "tailnet-usage"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Versioning",
|
||||
"id": "versioning"
|
||||
}
|
||||
],
|
||||
"url": "llms-txt#bridge-protocol-(legacy-node-transport)",
|
||||
"links": []
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"title": "Browser Login",
|
||||
"content": "Source: https://docs.openclaw.ai/tools/browser-login",
|
||||
"code_samples": [],
|
||||
"headings": [],
|
||||
"url": "llms-txt#browser-login",
|
||||
"links": []
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"title": "Browser Troubleshooting",
|
||||
"content": "Source: https://docs.openclaw.ai/tools/browser-linux-troubleshooting",
|
||||
"code_samples": [],
|
||||
"headings": [],
|
||||
"url": "llms-txt#browser-troubleshooting",
|
||||
"links": []
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
{
|
||||
"title": "Browser Troubleshooting (Linux)",
|
||||
"content": "## Problem: \"Failed to start Chrome CDP on port 18800\"\n\nOpenClaw's browser control server fails to launch Chrome/Brave/Edge/Chromium with the error:\n\nOn Ubuntu (and many Linux distros), the default Chromium installation is a **snap package**. Snap's AppArmor confinement interferes with how OpenClaw spawns and monitors the browser process.\n\nThe `apt install chromium` command installs a stub package that redirects to snap:\n\nThis is NOT a real browser — it's just a wrapper.\n\n### Solution 1: Install Google Chrome (Recommended)\n\nInstall the official Google Chrome `.deb` package, which is not sandboxed by snap:\n\nThen update your OpenClaw config (`~/.openclaw/openclaw.json`):\n\n### Solution 2: Use Snap Chromium with Attach-Only Mode\n\nIf you must use snap Chromium, configure OpenClaw to attach to a manually-started browser:\n\n2. Start Chromium manually:\n\n3. Optionally create a systemd user service to auto-start Chrome:",
|
||||
"code_samples": [
|
||||
{
|
||||
"code": "{\"error\":\"Error: Failed to start Chrome CDP on port 18800 for profile \\\"openclaw\\\".\"}",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "Note, selecting 'chromium-browser' instead of 'chromium'\nchromium-browser is already the newest version (2:1snap1-0ubuntu2).",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "Then update your OpenClaw config (`~/.openclaw/openclaw.json`):",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "### Solution 2: Use Snap Chromium with Attach-Only Mode\n\nIf you must use snap Chromium, configure OpenClaw to attach to a manually-started browser:\n\n1. Update config:",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "2. Start Chromium manually:",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "3. Optionally create a systemd user service to auto-start Chrome:",
|
||||
"language": "unknown"
|
||||
}
|
||||
],
|
||||
"headings": [
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Problem: \"Failed to start Chrome CDP on port 18800\"",
|
||||
"id": "problem:-\"failed-to-start-chrome-cdp-on-port-18800\""
|
||||
},
|
||||
{
|
||||
"level": "h3",
|
||||
"text": "Root Cause",
|
||||
"id": "root-cause"
|
||||
},
|
||||
{
|
||||
"level": "h3",
|
||||
"text": "Solution 1: Install Google Chrome (Recommended)",
|
||||
"id": "solution-1:-install-google-chrome-(recommended)"
|
||||
},
|
||||
{
|
||||
"level": "h3",
|
||||
"text": "Solution 2: Use Snap Chromium with Attach-Only Mode",
|
||||
"id": "solution-2:-use-snap-chromium-with-attach-only-mode"
|
||||
}
|
||||
],
|
||||
"url": "llms-txt#browser-troubleshooting-(linux)",
|
||||
"links": []
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"title": "Browser login + X/Twitter posting",
|
||||
"content": "## Manual login (recommended)\n\nWhen a site requires login, **sign in manually** in the **host** browser profile (the openclaw browser).\n\nDo **not** give the model your credentials. Automated logins often trigger anti‑bot defenses and can lock the account.\n\nBack to the main browser docs: [Browser](/tools/browser).\n\n## Which Chrome profile is used?\n\nOpenClaw controls a **dedicated Chrome profile** (named `openclaw`, orange‑tinted UI). This is separate from your daily browser profile.\n\nTwo easy ways to access it:\n\n1. **Ask the agent to open the browser** and then log in yourself.\n2. **Open it via CLI**:\n\nIf you have multiple profiles, pass `--browser-profile <name>` (the default is `openclaw`).\n\n## X/Twitter: recommended flow\n\n* **Read/search/threads:** use the **bird** CLI skill (no browser, stable).\n * Repo: [https://github.com/steipete/bird](https://github.com/steipete/bird)\n* **Post updates:** use the **host** browser (manual login).\n\n## Sandboxing + host browser access\n\nSandboxed browser sessions are **more likely** to trigger bot detection. For X/Twitter (and other strict sites), prefer the **host** browser.\n\nIf the agent is sandboxed, the browser tool defaults to the sandbox. To allow host control:\n\nThen target the host browser:\n\nOr disable sandboxing for the agent that posts updates.",
|
||||
"code_samples": [
|
||||
{
|
||||
"code": "If you have multiple profiles, pass `--browser-profile <name>` (the default is `openclaw`).\n\n## X/Twitter: recommended flow\n\n* **Read/search/threads:** use the **bird** CLI skill (no browser, stable).\n * Repo: [https://github.com/steipete/bird](https://github.com/steipete/bird)\n* **Post updates:** use the **host** browser (manual login).\n\n## Sandboxing + host browser access\n\nSandboxed browser sessions are **more likely** to trigger bot detection. For X/Twitter (and other strict sites), prefer the **host** browser.\n\nIf the agent is sandboxed, the browser tool defaults to the sandbox. To allow host control:",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "Then target the host browser:",
|
||||
"language": "unknown"
|
||||
}
|
||||
],
|
||||
"headings": [
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Manual login (recommended)",
|
||||
"id": "manual-login-(recommended)"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Which Chrome profile is used?",
|
||||
"id": "which-chrome-profile-is-used?"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "X/Twitter: recommended flow",
|
||||
"id": "x/twitter:-recommended-flow"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Sandboxing + host browser access",
|
||||
"id": "sandboxing-+-host-browser-access"
|
||||
}
|
||||
],
|
||||
"url": "llms-txt#browser-login-+-x/twitter-posting",
|
||||
"links": []
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"title": "Build sandbox image if missing",
|
||||
"content": "cd /opt/openclaw/openclaw\nsudo -u openclaw ./scripts/sandbox-setup.sh\nbash theme={null}\nsudo -i -u openclaw\nopenclaw channels login\n```\n\n## Advanced Configuration\n\nFor detailed security architecture and troubleshooting:\n\n* [Security Architecture](https://github.com/openclaw/openclaw-ansible/blob/main/docs/security.md)\n* [Technical Details](https://github.com/openclaw/openclaw-ansible/blob/main/docs/architecture.md)\n* [Troubleshooting Guide](https://github.com/openclaw/openclaw-ansible/blob/main/docs/troubleshooting.md)\n\n* [openclaw-ansible](https://github.com/openclaw/openclaw-ansible) — full deployment guide\n* [Docker](/install/docker) — containerized gateway setup\n* [Sandboxing](/gateway/sandboxing) — agent sandbox configuration\n* [Multi-Agent Sandbox & Tools](/multi-agent-sandbox-tools) — per-agent isolation",
|
||||
"code_samples": [
|
||||
{
|
||||
"code": "### Provider login fails\n\nMake sure you're running as the `openclaw` user:",
|
||||
"language": "unknown"
|
||||
}
|
||||
],
|
||||
"headings": [
|
||||
{
|
||||
"level": "h3",
|
||||
"text": "Provider login fails",
|
||||
"id": "provider-login-fails"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Advanced Configuration",
|
||||
"id": "advanced-configuration"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Related",
|
||||
"id": "related"
|
||||
}
|
||||
],
|
||||
"url": "llms-txt#build-sandbox-image-if-missing",
|
||||
"links": []
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"title": "Building a personal assistant with OpenClaw",
|
||||
"content": "OpenClaw is a WhatsApp + Telegram + Discord + iMessage gateway for **Pi** agents. Plugins add Mattermost. This guide is the \"personal assistant\" setup: one dedicated WhatsApp number that behaves like your always-on agent.\n\nYou’re putting an agent in a position to:\n\n* run commands on your machine (depending on your Pi tool setup)\n* read/write files in your workspace\n* send messages back out via WhatsApp/Telegram/Discord/Mattermost (plugin)\n\n* Always set `channels.whatsapp.allowFrom` (never run open-to-the-world on your personal Mac).\n* Use a dedicated WhatsApp number for the assistant.\n* Heartbeats now default to every 30 minutes. Disable until you trust the setup by setting `agents.defaults.heartbeat.every: \"0m\"`.\n\n* Node **22+**\n* OpenClaw available on PATH (recommended: global install)\n* A second phone number (SIM/eSIM/prepaid) for the assistant\n\n```bash theme={null}\nnpm install -g openclaw@latest",
|
||||
"code_samples": [],
|
||||
"headings": [
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "⚠️ Safety first",
|
||||
"id": "⚠️-safety-first"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Prerequisites",
|
||||
"id": "prerequisites"
|
||||
}
|
||||
],
|
||||
"url": "llms-txt#building-a-personal-assistant-with-openclaw",
|
||||
"links": []
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
{
|
||||
"title": "Bun (experimental)",
|
||||
"content": "Goal: run this repo with **Bun** (optional, not recommended for WhatsApp/Telegram)\nwithout diverging from pnpm workflows.\n\n⚠️ **Not recommended for Gateway runtime** (WhatsApp/Telegram bugs). Use Node for production.\n\n* Bun is an optional local runtime for running TypeScript directly (`bun run …`, `bun --watch …`).\n* `pnpm` is the default for builds and remains fully supported (and used by some docs tooling).\n* Bun cannot use `pnpm-lock.yaml` and will ignore it.\n\nNote: `bun.lock`/`bun.lockb` are gitignored, so there’s no repo churn either way. If you want *no lockfile writes*:\n\n## Build / Test (Bun)\n\n## Bun lifecycle scripts (blocked by default)\n\nBun may block dependency lifecycle scripts unless explicitly trusted (`bun pm untrusted` / `bun pm trust`).\nFor this repo, the commonly blocked scripts are not required:\n\n* `@whiskeysockets/baileys` `preinstall`: checks Node major >= 20 (we run Node 22+).\n* `protobufjs` `postinstall`: emits warnings about incompatible version schemes (no build artifacts).\n\nIf you hit a real runtime issue that requires these scripts, trust them explicitly:\n\n* Some scripts still hardcode pnpm (e.g. `docs:build`, `ui:*`, `protocol:check`). Run those via pnpm for now.",
|
||||
"code_samples": [
|
||||
{
|
||||
"code": "Note: `bun.lock`/`bun.lockb` are gitignored, so there’s no repo churn either way. If you want *no lockfile writes*:",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "## Build / Test (Bun)",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "## Bun lifecycle scripts (blocked by default)\n\nBun may block dependency lifecycle scripts unless explicitly trusted (`bun pm untrusted` / `bun pm trust`).\nFor this repo, the commonly blocked scripts are not required:\n\n* `@whiskeysockets/baileys` `preinstall`: checks Node major >= 20 (we run Node 22+).\n* `protobufjs` `postinstall`: emits warnings about incompatible version schemes (no build artifacts).\n\nIf you hit a real runtime issue that requires these scripts, trust them explicitly:",
|
||||
"language": "unknown"
|
||||
}
|
||||
],
|
||||
"headings": [
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Status",
|
||||
"id": "status"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Install",
|
||||
"id": "install"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Build / Test (Bun)",
|
||||
"id": "build-/-test-(bun)"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Bun lifecycle scripts (blocked by default)",
|
||||
"id": "bun-lifecycle-scripts-(blocked-by-default)"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Caveats",
|
||||
"id": "caveats"
|
||||
}
|
||||
],
|
||||
"url": "llms-txt#bun-(experimental)",
|
||||
"links": []
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"title": "CLI Backends",
|
||||
"content": "Source: https://docs.openclaw.ai/gateway/cli-backends",
|
||||
"code_samples": [],
|
||||
"headings": [],
|
||||
"url": "llms-txt#cli-backends",
|
||||
"links": []
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,165 @@
|
||||
{
|
||||
"title": "Cache dependencies unless package metadata changes",
|
||||
"content": "COPY package.json pnpm-lock.yaml pnpm-workspace.yaml .npmrc ./\nCOPY ui/package.json ./ui/package.json\nCOPY scripts ./scripts\n\nRUN pnpm install --frozen-lockfile\n\nCOPY . .\nRUN pnpm build\nRUN pnpm ui:install\nRUN pnpm ui:build\n\nENV NODE_ENV=production\n\nCMD [\"node\",\"dist/index.js\"]\nbash theme={null}\ndocker compose run --rm openclaw-cli channels login\nbash theme={null}\ndocker compose run --rm openclaw-cli channels add --channel telegram --token \"<token>\"\nbash theme={null}\ndocker compose run --rm openclaw-cli channels add --channel discord --token \"<token>\"\nbash theme={null}\ndocker compose exec openclaw-gateway node dist/index.js health --token \"$OPENCLAW_GATEWAY_TOKEN\"\nbash theme={null}\nscripts/e2e/onboard-docker.sh\nbash theme={null}\npnpm test:docker:qr\njson5 theme={null}\n{\n agents: {\n defaults: {\n sandbox: {\n mode: \"non-main\", // off | non-main | all\n scope: \"agent\", // session | agent | shared (agent is default)\n workspaceAccess: \"none\", // none | ro | rw\n workspaceRoot: \"~/.openclaw/sandboxes\",\n docker: {\n image: \"openclaw-sandbox:bookworm-slim\",\n workdir: \"/workspace\",\n readOnlyRoot: true,\n tmpfs: [\"/tmp\", \"/var/tmp\", \"/run\"],\n network: \"none\",\n user: \"1000:1000\",\n capDrop: [\"ALL\"],\n env: { LANG: \"C.UTF-8\" },\n setupCommand: \"apt-get update && apt-get install -y git curl jq\",\n pidsLimit: 256,\n memory: \"1g\",\n memorySwap: \"2g\",\n cpus: 1,\n ulimits: {\n nofile: { soft: 1024, hard: 2048 },\n nproc: 256,\n },\n seccompProfile: \"/path/to/seccomp.json\",\n apparmorProfile: \"openclaw-sandbox\",\n dns: [\"1.1.1.1\", \"8.8.8.8\"],\n extraHosts: [\"internal.service:10.0.0.5\"],\n },\n prune: {\n idleHours: 24, // 0 disables idle pruning\n maxAgeDays: 7, // 0 disables max-age pruning\n },\n },\n },\n },\n tools: {\n sandbox: {\n tools: {\n allow: [\n \"exec\",\n \"process\",\n \"read\",\n \"write\",\n \"edit\",\n \"sessions_list\",\n \"sessions_history\",\n \"sessions_send\",\n \"sessions_spawn\",\n \"session_status\",\n ],\n deny: [\"browser\", \"canvas\", \"nodes\", \"cron\", \"discord\", \"gateway\"],\n },\n },\n },\n}\nbash theme={null}\nscripts/sandbox-setup.sh\nbash theme={null}\nscripts/sandbox-common-setup.sh\njson5 theme={null}\n{\n agents: {\n defaults: {\n sandbox: { docker: { image: \"openclaw-sandbox-common:bookworm-slim\" } },\n },\n },\n}\nbash theme={null}\nscripts/sandbox-browser-setup.sh\njson5 theme={null}\n{\n agents: {\n defaults: {\n sandbox: {\n browser: { enabled: true },\n },\n },\n },\n}\njson5 theme={null}\n{\n agents: {\n defaults: {\n sandbox: { browser: { image: \"my-openclaw-browser\" } },\n },\n },\n}\nbash theme={null}\ndocker build -t my-openclaw-sbx -f Dockerfile.sandbox .\njson5 theme={null}\n{\n agents: {\n defaults: {\n sandbox: { docker: { image: \"my-openclaw-sbx\" } },\n },\n },\n}\n```\n\n### Tool policy (allow/deny)\n\n* `deny` wins over `allow`.\n* If `allow` is empty: all tools (except deny) are available.\n* If `allow` is non-empty: only tools in `allow` are available (minus deny).\n\n* `prune.idleHours`: remove containers not used in X hours (0 = disable)\n* `prune.maxAgeDays`: remove containers older than X days (0 = disable)\n\n* Keep busy sessions but cap lifetime:\n `idleHours: 24`, `maxAgeDays: 7`\n* Never prune:\n `idleHours: 0`, `maxAgeDays: 0`\n\n* Hard wall only applies to **tools** (exec/read/write/edit/apply\\_patch).\n* Host-only tools like browser/camera/canvas are blocked by default.\n* Allowing `browser` in sandbox **breaks isolation** (browser runs on host).\n\n* Image missing: build with [`scripts/sandbox-setup.sh`](https://github.com/openclaw/openclaw/blob/main/scripts/sandbox-setup.sh) or set `agents.defaults.sandbox.docker.image`.\n* Container not running: it will auto-create per session on demand.\n* Permission errors in sandbox: set `docker.user` to a UID:GID that matches your\n mounted workspace ownership (or chown the workspace folder).\n* Custom tools not found: OpenClaw runs commands with `sh -lc` (login shell), which\n sources `/etc/profile` and may reset PATH. Set `docker.env.PATH` to prepend your\n custom tool paths (e.g., `/custom/bin:/usr/local/share/npm-global/bin`), or add\n a script under `/etc/profile.d/` in your Dockerfile.",
|
||||
"code_samples": [
|
||||
{
|
||||
"code": "### Channel setup (optional)\n\nUse the CLI container to configure channels, then restart the gateway if needed.\n\nWhatsApp (QR):",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "Telegram (bot token):",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "Discord (bot token):",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "Docs: [WhatsApp](/channels/whatsapp), [Telegram](/channels/telegram), [Discord](/channels/discord)\n\n### OpenAI Codex OAuth (headless Docker)\n\nIf you pick OpenAI Codex OAuth in the wizard, it opens a browser URL and tries\nto capture a callback on `http://127.0.0.1:1455/auth/callback`. In Docker or\nheadless setups that callback can show a browser error. Copy the full redirect\nURL you land on and paste it back into the wizard to finish auth.\n\n### Health check",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "### E2E smoke test (Docker)",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "### QR import smoke test (Docker)",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "### Notes\n\n* Gateway bind defaults to `lan` for container use.\n* Dockerfile CMD uses `--allow-unconfigured`; mounted config with `gateway.mode` not `local` will still start. Override CMD to enforce the guard.\n* The gateway container is the source of truth for sessions (`~/.openclaw/agents/<agentId>/sessions/`).\n\n## Agent Sandbox (host gateway + Docker tools)\n\nDeep dive: [Sandboxing](/gateway/sandboxing)\n\n### What it does\n\nWhen `agents.defaults.sandbox` is enabled, **non-main sessions** run tools inside a Docker\ncontainer. The gateway stays on your host, but the tool execution is isolated:\n\n* scope: `\"agent\"` by default (one container + workspace per agent)\n* scope: `\"session\"` for per-session isolation\n* per-scope workspace folder mounted at `/workspace`\n* optional agent workspace access (`agents.defaults.sandbox.workspaceAccess`)\n* allow/deny tool policy (deny wins)\n* inbound media is copied into the active sandbox workspace (`media/inbound/*`) so tools can read it (with `workspaceAccess: \"rw\"`, this lands in the agent workspace)\n\nWarning: `scope: \"shared\"` disables cross-session isolation. All sessions share\none container and one workspace.\n\n### Per-agent sandbox profiles (multi-agent)\n\nIf you use multi-agent routing, each agent can override sandbox + tool settings:\n`agents.list[].sandbox` and `agents.list[].tools` (plus `agents.list[].tools.sandbox.tools`). This lets you run\nmixed access levels in one gateway:\n\n* Full access (personal agent)\n* Read-only tools + read-only workspace (family/work agent)\n* No filesystem/shell tools (public agent)\n\nSee [Multi-Agent Sandbox & Tools](/multi-agent-sandbox-tools) for examples,\nprecedence, and troubleshooting.\n\n### Default behavior\n\n* Image: `openclaw-sandbox:bookworm-slim`\n* One container per agent\n* Agent workspace access: `workspaceAccess: \"none\"` (default) uses `~/.openclaw/sandboxes`\n * `\"ro\"` keeps the sandbox workspace at `/workspace` and mounts the agent workspace read-only at `/agent` (disables `write`/`edit`/`apply_patch`)\n * `\"rw\"` mounts the agent workspace read/write at `/workspace`\n* Auto-prune: idle > 24h OR age > 7d\n* Network: `none` by default (explicitly opt-in if you need egress)\n* Default allow: `exec`, `process`, `read`, `write`, `edit`, `sessions_list`, `sessions_history`, `sessions_send`, `sessions_spawn`, `session_status`\n* Default deny: `browser`, `canvas`, `nodes`, `cron`, `discord`, `gateway`\n\n### Enable sandboxing\n\nIf you plan to install packages in `setupCommand`, note:\n\n* Default `docker.network` is `\"none\"` (no egress).\n* `readOnlyRoot: true` blocks package installs.\n* `user` must be root for `apt-get` (omit `user` or set `user: \"0:0\"`).\n OpenClaw auto-recreates containers when `setupCommand` (or docker config) changes\n unless the container was **recently used** (within \\~5 minutes). Hot containers\n log a warning with the exact `openclaw sandbox recreate ...` command.",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "Hardening knobs live under `agents.defaults.sandbox.docker`:\n`network`, `user`, `pidsLimit`, `memory`, `memorySwap`, `cpus`, `ulimits`,\n`seccompProfile`, `apparmorProfile`, `dns`, `extraHosts`.\n\nMulti-agent: override `agents.defaults.sandbox.{docker,browser,prune}.*` per agent via `agents.list[].sandbox.{docker,browser,prune}.*`\n(ignored when `agents.defaults.sandbox.scope` / `agents.list[].sandbox.scope` is `\"shared\"`).\n\n### Build the default sandbox image",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "This builds `openclaw-sandbox:bookworm-slim` using `Dockerfile.sandbox`.\n\n### Sandbox common image (optional)\n\nIf you want a sandbox image with common build tooling (Node, Go, Rust, etc.), build the common image:",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "This builds `openclaw-sandbox-common:bookworm-slim`. To use it:",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "### Sandbox browser image\n\nTo run the browser tool inside the sandbox, build the browser image:",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "This builds `openclaw-sandbox-browser:bookworm-slim` using\n`Dockerfile.sandbox-browser`. The container runs Chromium with CDP enabled and\nan optional noVNC observer (headful via Xvfb).\n\nNotes:\n\n* Headful (Xvfb) reduces bot blocking vs headless.\n* Headless can still be used by setting `agents.defaults.sandbox.browser.headless=true`.\n* No full desktop environment (GNOME) is needed; Xvfb provides the display.\n\nUse config:",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "Custom browser image:",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "When enabled, the agent receives:\n\n* a sandbox browser control URL (for the `browser` tool)\n* a noVNC URL (if enabled and headless=false)\n\nRemember: if you use an allowlist for tools, add `browser` (and remove it from\ndeny) or the tool remains blocked.\nPrune rules (`agents.defaults.sandbox.prune`) apply to browser containers too.\n\n### Custom sandbox image\n\nBuild your own image and point config to it:",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "",
|
||||
"language": "unknown"
|
||||
}
|
||||
],
|
||||
"headings": [
|
||||
{
|
||||
"level": "h3",
|
||||
"text": "Channel setup (optional)",
|
||||
"id": "channel-setup-(optional)"
|
||||
},
|
||||
{
|
||||
"level": "h3",
|
||||
"text": "OpenAI Codex OAuth (headless Docker)",
|
||||
"id": "openai-codex-oauth-(headless-docker)"
|
||||
},
|
||||
{
|
||||
"level": "h3",
|
||||
"text": "Health check",
|
||||
"id": "health-check"
|
||||
},
|
||||
{
|
||||
"level": "h3",
|
||||
"text": "E2E smoke test (Docker)",
|
||||
"id": "e2e-smoke-test-(docker)"
|
||||
},
|
||||
{
|
||||
"level": "h3",
|
||||
"text": "QR import smoke test (Docker)",
|
||||
"id": "qr-import-smoke-test-(docker)"
|
||||
},
|
||||
{
|
||||
"level": "h3",
|
||||
"text": "Notes",
|
||||
"id": "notes"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Agent Sandbox (host gateway + Docker tools)",
|
||||
"id": "agent-sandbox-(host-gateway-+-docker-tools)"
|
||||
},
|
||||
{
|
||||
"level": "h3",
|
||||
"text": "What it does",
|
||||
"id": "what-it-does"
|
||||
},
|
||||
{
|
||||
"level": "h3",
|
||||
"text": "Per-agent sandbox profiles (multi-agent)",
|
||||
"id": "per-agent-sandbox-profiles-(multi-agent)"
|
||||
},
|
||||
{
|
||||
"level": "h3",
|
||||
"text": "Default behavior",
|
||||
"id": "default-behavior"
|
||||
},
|
||||
{
|
||||
"level": "h3",
|
||||
"text": "Enable sandboxing",
|
||||
"id": "enable-sandboxing"
|
||||
},
|
||||
{
|
||||
"level": "h3",
|
||||
"text": "Build the default sandbox image",
|
||||
"id": "build-the-default-sandbox-image"
|
||||
},
|
||||
{
|
||||
"level": "h3",
|
||||
"text": "Sandbox common image (optional)",
|
||||
"id": "sandbox-common-image-(optional)"
|
||||
},
|
||||
{
|
||||
"level": "h3",
|
||||
"text": "Sandbox browser image",
|
||||
"id": "sandbox-browser-image"
|
||||
},
|
||||
{
|
||||
"level": "h3",
|
||||
"text": "Custom sandbox image",
|
||||
"id": "custom-sandbox-image"
|
||||
},
|
||||
{
|
||||
"level": "h3",
|
||||
"text": "Tool policy (allow/deny)",
|
||||
"id": "tool-policy-(allow/deny)"
|
||||
},
|
||||
{
|
||||
"level": "h3",
|
||||
"text": "Pruning strategy",
|
||||
"id": "pruning-strategy"
|
||||
},
|
||||
{
|
||||
"level": "h3",
|
||||
"text": "Security notes",
|
||||
"id": "security-notes"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Troubleshooting",
|
||||
"id": "troubleshooting"
|
||||
}
|
||||
],
|
||||
"url": "llms-txt#cache-dependencies-unless-package-metadata-changes",
|
||||
"links": []
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"title": "Camera Capture",
|
||||
"content": "Source: https://docs.openclaw.ai/nodes/camera",
|
||||
"code_samples": [],
|
||||
"headings": [],
|
||||
"url": "llms-txt#camera-capture",
|
||||
"links": []
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
{
|
||||
"title": "Camera capture (agent)",
|
||||
"content": "OpenClaw supports **camera capture** for agent workflows:\n\n* **iOS node** (paired via Gateway): capture a **photo** (`jpg`) or **short video clip** (`mp4`, with optional audio) via `node.invoke`.\n* **Android node** (paired via Gateway): capture a **photo** (`jpg`) or **short video clip** (`mp4`, with optional audio) via `node.invoke`.\n* **macOS app** (node via Gateway): capture a **photo** (`jpg`) or **short video clip** (`mp4`, with optional audio) via `node.invoke`.\n\nAll camera access is gated behind **user-controlled settings**.\n\n### User setting (default on)\n\n* iOS Settings tab → **Camera** → **Allow Camera** (`camera.enabled`)\n * Default: **on** (missing key is treated as enabled).\n * When off: `camera.*` commands return `CAMERA_DISABLED`.\n\n### Commands (via Gateway `node.invoke`)\n\n* `camera.list`\n * Response payload:\n * `devices`: array of `{ id, name, position, deviceType }`\n\n* `camera.snap`\n * Params:\n * `facing`: `front|back` (default: `front`)\n * `maxWidth`: number (optional; default `1600` on the iOS node)\n * `quality`: `0..1` (optional; default `0.9`)\n * `format`: currently `jpg`\n * `delayMs`: number (optional; default `0`)\n * `deviceId`: string (optional; from `camera.list`)\n * Response payload:\n * `format: \"jpg\"`\n * `base64: \"<...>\"`\n * `width`, `height`\n * Payload guard: photos are recompressed to keep the base64 payload under 5 MB.\n\n* `camera.clip`\n * Params:\n * `facing`: `front|back` (default: `front`)\n * `durationMs`: number (default `3000`, clamped to a max of `60000`)\n * `includeAudio`: boolean (default `true`)\n * `format`: currently `mp4`\n * `deviceId`: string (optional; from `camera.list`)\n * Response payload:\n * `format: \"mp4\"`\n * `base64: \"<...>\"`\n * `durationMs`\n * `hasAudio`\n\n### Foreground requirement\n\nLike `canvas.*`, the iOS node only allows `camera.*` commands in the **foreground**. Background invocations return `NODE_BACKGROUND_UNAVAILABLE`.\n\n### CLI helper (temp files + MEDIA)\n\nThe easiest way to get attachments is via the CLI helper, which writes decoded media to a temp file and prints `MEDIA:<path>`.\n\n* `nodes camera snap` defaults to **both** facings to give the agent both views.\n* Output files are temporary (in the OS temp directory) unless you build your own wrapper.\n\n### User setting (default on)\n\n* Android Settings sheet → **Camera** → **Allow Camera** (`camera.enabled`)\n * Default: **on** (missing key is treated as enabled).\n * When off: `camera.*` commands return `CAMERA_DISABLED`.\n\n* Android requires runtime permissions:\n * `CAMERA` for both `camera.snap` and `camera.clip`.\n * `RECORD_AUDIO` for `camera.clip` when `includeAudio=true`.\n\nIf permissions are missing, the app will prompt when possible; if denied, `camera.*` requests fail with a\n`*_PERMISSION_REQUIRED` error.\n\n### Foreground requirement\n\nLike `canvas.*`, the Android node only allows `camera.*` commands in the **foreground**. Background invocations return `NODE_BACKGROUND_UNAVAILABLE`.\n\nPhotos are recompressed to keep the base64 payload under 5 MB.\n\n### User setting (default off)\n\nThe macOS companion app exposes a checkbox:\n\n* **Settings → General → Allow Camera** (`openclaw.cameraEnabled`)\n * Default: **off**\n * When off: camera requests return “Camera disabled by user”.\n\n### CLI helper (node invoke)\n\nUse the main `openclaw` CLI to invoke camera commands on the macOS node.\n\n* `openclaw nodes camera snap` defaults to `maxWidth=1600` unless overridden.\n* On macOS, `camera.snap` waits `delayMs` (default 2000ms) after warm-up/exposure settle before capturing.\n* Photo payloads are recompressed to keep base64 under 5 MB.\n\n## Safety + practical limits\n\n* Camera and microphone access trigger the usual OS permission prompts (and require usage strings in Info.plist).\n* Video clips are capped (currently `<= 60s`) to avoid oversized node payloads (base64 overhead + message limits).\n\n## macOS screen video (OS-level)\n\nFor *screen* video (not camera), use the macOS companion:\n\n* Requires macOS **Screen Recording** permission (TCC).",
|
||||
"code_samples": [
|
||||
{
|
||||
"code": "Notes:\n\n* `nodes camera snap` defaults to **both** facings to give the agent both views.\n* Output files are temporary (in the OS temp directory) unless you build your own wrapper.\n\n## Android node\n\n### User setting (default on)\n\n* Android Settings sheet → **Camera** → **Allow Camera** (`camera.enabled`)\n * Default: **on** (missing key is treated as enabled).\n * When off: `camera.*` commands return `CAMERA_DISABLED`.\n\n### Permissions\n\n* Android requires runtime permissions:\n * `CAMERA` for both `camera.snap` and `camera.clip`.\n * `RECORD_AUDIO` for `camera.clip` when `includeAudio=true`.\n\nIf permissions are missing, the app will prompt when possible; if denied, `camera.*` requests fail with a\n`*_PERMISSION_REQUIRED` error.\n\n### Foreground requirement\n\nLike `canvas.*`, the Android node only allows `camera.*` commands in the **foreground**. Background invocations return `NODE_BACKGROUND_UNAVAILABLE`.\n\n### Payload guard\n\nPhotos are recompressed to keep the base64 payload under 5 MB.\n\n## macOS app\n\n### User setting (default off)\n\nThe macOS companion app exposes a checkbox:\n\n* **Settings → General → Allow Camera** (`openclaw.cameraEnabled`)\n * Default: **off**\n * When off: camera requests return “Camera disabled by user”.\n\n### CLI helper (node invoke)\n\nUse the main `openclaw` CLI to invoke camera commands on the macOS node.\n\nExamples:",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "Notes:\n\n* `openclaw nodes camera snap` defaults to `maxWidth=1600` unless overridden.\n* On macOS, `camera.snap` waits `delayMs` (default 2000ms) after warm-up/exposure settle before capturing.\n* Photo payloads are recompressed to keep base64 under 5 MB.\n\n## Safety + practical limits\n\n* Camera and microphone access trigger the usual OS permission prompts (and require usage strings in Info.plist).\n* Video clips are capped (currently `<= 60s`) to avoid oversized node payloads (base64 overhead + message limits).\n\n## macOS screen video (OS-level)\n\nFor *screen* video (not camera), use the macOS companion:",
|
||||
"language": "unknown"
|
||||
}
|
||||
],
|
||||
"headings": [
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "iOS node",
|
||||
"id": "ios-node"
|
||||
},
|
||||
{
|
||||
"level": "h3",
|
||||
"text": "User setting (default on)",
|
||||
"id": "user-setting-(default-on)"
|
||||
},
|
||||
{
|
||||
"level": "h3",
|
||||
"text": "Commands (via Gateway `node.invoke`)",
|
||||
"id": "commands-(via-gateway-`node.invoke`)"
|
||||
},
|
||||
{
|
||||
"level": "h3",
|
||||
"text": "Foreground requirement",
|
||||
"id": "foreground-requirement"
|
||||
},
|
||||
{
|
||||
"level": "h3",
|
||||
"text": "CLI helper (temp files + MEDIA)",
|
||||
"id": "cli-helper-(temp-files-+-media)"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Android node",
|
||||
"id": "android-node"
|
||||
},
|
||||
{
|
||||
"level": "h3",
|
||||
"text": "User setting (default on)",
|
||||
"id": "user-setting-(default-on)"
|
||||
},
|
||||
{
|
||||
"level": "h3",
|
||||
"text": "Permissions",
|
||||
"id": "permissions"
|
||||
},
|
||||
{
|
||||
"level": "h3",
|
||||
"text": "Foreground requirement",
|
||||
"id": "foreground-requirement"
|
||||
},
|
||||
{
|
||||
"level": "h3",
|
||||
"text": "Payload guard",
|
||||
"id": "payload-guard"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "macOS app",
|
||||
"id": "macos-app"
|
||||
},
|
||||
{
|
||||
"level": "h3",
|
||||
"text": "User setting (default off)",
|
||||
"id": "user-setting-(default-off)"
|
||||
},
|
||||
{
|
||||
"level": "h3",
|
||||
"text": "CLI helper (node invoke)",
|
||||
"id": "cli-helper-(node-invoke)"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Safety + practical limits",
|
||||
"id": "safety-+-practical-limits"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "macOS screen video (OS-level)",
|
||||
"id": "macos-screen-video-(os-level)"
|
||||
}
|
||||
],
|
||||
"url": "llms-txt#camera-capture-(agent)",
|
||||
"links": []
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"title": "Canvas",
|
||||
"content": "Source: https://docs.openclaw.ai/platforms/mac/canvas",
|
||||
"code_samples": [],
|
||||
"headings": [],
|
||||
"url": "llms-txt#canvas",
|
||||
"links": []
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
{
|
||||
"title": "Canvas (macOS app)",
|
||||
"content": "The macOS app embeds an agent‑controlled **Canvas panel** using `WKWebView`. It\nis a lightweight visual workspace for HTML/CSS/JS, A2UI, and small interactive\nUI surfaces.\n\n## Where Canvas lives\n\nCanvas state is stored under Application Support:\n\n* `~/Library/Application Support/OpenClaw/canvas/<session>/...`\n\nThe Canvas panel serves those files via a **custom URL scheme**:\n\n* `openclaw-canvas://<session>/<path>`\n\n* `openclaw-canvas://main/` → `<canvasRoot>/main/index.html`\n* `openclaw-canvas://main/assets/app.css` → `<canvasRoot>/main/assets/app.css`\n* `openclaw-canvas://main/widgets/todo/` → `<canvasRoot>/main/widgets/todo/index.html`\n\nIf no `index.html` exists at the root, the app shows a **built‑in scaffold page**.\n\n* Borderless, resizable panel anchored near the menu bar (or mouse cursor).\n* Remembers size/position per session.\n* Auto‑reloads when local canvas files change.\n* Only one Canvas panel is visible at a time (session is switched as needed).\n\nCanvas can be disabled from Settings → **Allow Canvas**. When disabled, canvas\nnode commands return `CANVAS_DISABLED`.\n\nCanvas is exposed via the **Gateway WebSocket**, so the agent can:\n\n* show/hide the panel\n* navigate to a path or URL\n* evaluate JavaScript\n* capture a snapshot image\n\n* `canvas.navigate` accepts **local canvas paths**, `http(s)` URLs, and `file://` URLs.\n* If you pass `\"/\"`, the Canvas shows the local scaffold or `index.html`.\n\nA2UI is hosted by the Gateway canvas host and rendered inside the Canvas panel.\nWhen the Gateway advertises a Canvas host, the macOS app auto‑navigates to the\nA2UI host page on first open.\n\nDefault A2UI host URL:\n\n### A2UI commands (v0.8)\n\nCanvas currently accepts **A2UI v0.8** server→client messages:\n\n* `beginRendering`\n* `surfaceUpdate`\n* `dataModelUpdate`\n* `deleteSurface`\n\n`createSurface` (v0.9) is not supported.\n\n## Triggering agent runs from Canvas\n\nCanvas can trigger new agent runs via deep links:\n\n* `openclaw://agent?...`\n\nThe app prompts for confirmation unless a valid key is provided.\n\n* Canvas scheme blocks directory traversal; files must live under the session root.\n* Local Canvas content uses a custom scheme (no loopback server required).\n* External `http(s)` URLs are allowed only when explicitly navigated.",
|
||||
"code_samples": [
|
||||
{
|
||||
"code": "Notes:\n\n* `canvas.navigate` accepts **local canvas paths**, `http(s)` URLs, and `file://` URLs.\n* If you pass `\"/\"`, the Canvas shows the local scaffold or `index.html`.\n\n## A2UI in Canvas\n\nA2UI is hosted by the Gateway canvas host and rendered inside the Canvas panel.\nWhen the Gateway advertises a Canvas host, the macOS app auto‑navigates to the\nA2UI host page on first open.\n\nDefault A2UI host URL:",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "### A2UI commands (v0.8)\n\nCanvas currently accepts **A2UI v0.8** server→client messages:\n\n* `beginRendering`\n* `surfaceUpdate`\n* `dataModelUpdate`\n* `deleteSurface`\n\n`createSurface` (v0.9) is not supported.\n\nCLI example:",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "Quick smoke:",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "## Triggering agent runs from Canvas\n\nCanvas can trigger new agent runs via deep links:\n\n* `openclaw://agent?...`\n\nExample (in JS):",
|
||||
"language": "unknown"
|
||||
}
|
||||
],
|
||||
"headings": [
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Where Canvas lives",
|
||||
"id": "where-canvas-lives"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Panel behavior",
|
||||
"id": "panel-behavior"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Agent API surface",
|
||||
"id": "agent-api-surface"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "A2UI in Canvas",
|
||||
"id": "a2ui-in-canvas"
|
||||
},
|
||||
{
|
||||
"level": "h3",
|
||||
"text": "A2UI commands (v0.8)",
|
||||
"id": "a2ui-commands-(v0.8)"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Triggering agent runs from Canvas",
|
||||
"id": "triggering-agent-runs-from-canvas"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Security notes",
|
||||
"id": "security-notes"
|
||||
}
|
||||
],
|
||||
"url": "llms-txt#canvas-(macos-app)",
|
||||
"links": []
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"title": "Change machine type",
|
||||
"content": "gcloud compute instances set-machine-type openclaw-gateway \\\n --zone=us-central1-a \\\n --machine-type=e2-small",
|
||||
"code_samples": [],
|
||||
"headings": [],
|
||||
"url": "llms-txt#change-machine-type",
|
||||
"links": []
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"title": "Channel location parsing",
|
||||
"content": "OpenClaw normalizes shared locations from chat channels into:\n\n* human-readable text appended to the inbound body, and\n* structured fields in the auto-reply context payload.\n\n* **Telegram** (location pins + venues + live locations)\n* **WhatsApp** (locationMessage + liveLocationMessage)\n* **Matrix** (`m.location` with `geo_uri`)\n\nLocations are rendered as friendly lines without brackets:\n\n* Pin:\n * `📍 48.858844, 2.294351 ±12m`\n* Named place:\n * `📍 Eiffel Tower — Champ de Mars, Paris (48.858844, 2.294351 ±12m)`\n* Live share:\n * `🛰 Live location: 48.858844, 2.294351 ±12m`\n\nIf the channel includes a caption/comment, it is appended on the next line:\n\nWhen a location is present, these fields are added to `ctx`:\n\n* `LocationLat` (number)\n* `LocationLon` (number)\n* `LocationAccuracy` (number, meters; optional)\n* `LocationName` (string; optional)\n* `LocationAddress` (string; optional)\n* `LocationSource` (`pin | place | live`)\n* `LocationIsLive` (boolean)\n\n* **Telegram**: venues map to `LocationName/LocationAddress`; live locations use `live_period`.\n* **WhatsApp**: `locationMessage.comment` and `liveLocationMessage.caption` are appended as the caption line.\n* **Matrix**: `geo_uri` is parsed as a pin location; altitude is ignored and `LocationIsLive` is always false.",
|
||||
"code_samples": [
|
||||
{
|
||||
"code": "📍 48.858844, 2.294351 ±12m\nMeet here",
|
||||
"language": "unknown"
|
||||
}
|
||||
],
|
||||
"headings": [
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Text formatting",
|
||||
"id": "text-formatting"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Context fields",
|
||||
"id": "context-fields"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Channel notes",
|
||||
"id": "channel-notes"
|
||||
}
|
||||
],
|
||||
"url": "llms-txt#channel-location-parsing",
|
||||
"links": []
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"title": "Channel Routing",
|
||||
"content": "Source: https://docs.openclaw.ai/concepts/channel-routing",
|
||||
"code_samples": [],
|
||||
"headings": [],
|
||||
"url": "llms-txt#channel-routing",
|
||||
"links": []
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"title": "Channel troubleshooting",
|
||||
"content": "`channels status --probe` prints warnings when it can detect common channel misconfigurations, and includes small live checks (credentials, some permissions/membership).\n\n* Discord: [/channels/discord#troubleshooting](/channels/discord#troubleshooting)\n* Telegram: [/channels/telegram#troubleshooting](/channels/telegram#troubleshooting)\n* WhatsApp: [/channels/whatsapp#troubleshooting-quick](/channels/whatsapp#troubleshooting-quick)\n\n## Telegram quick fixes\n\n* Logs show `HttpError: Network request for 'sendMessage' failed` or `sendChatAction` → check IPv6 DNS. If `api.telegram.org` resolves to IPv6 first and the host lacks IPv6 egress, force IPv4 or enable IPv6. See [/channels/telegram#troubleshooting](/channels/telegram#troubleshooting).\n* Logs show `setMyCommands failed` → check outbound HTTPS and DNS reachability to `api.telegram.org` (common on locked-down VPS or proxies).",
|
||||
"code_samples": [],
|
||||
"headings": [
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Channels",
|
||||
"id": "channels"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Telegram quick fixes",
|
||||
"id": "telegram-quick-fixes"
|
||||
}
|
||||
],
|
||||
"url": "llms-txt#channel-troubleshooting",
|
||||
"links": []
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
{
|
||||
"title": "Channel tokens",
|
||||
"content": "fly secrets set DISCORD_BOT_TOKEN=MTQ...\nbash theme={null}\nfly deploy\nbash theme={null}\nfly status\nfly logs\n\n[gateway] listening on ws://0.0.0.0:3000 (PID xxx)\n[discord] logged in to discord as xxx\nbash theme={null}\nfly ssh console\nbash theme={null}\nmkdir -p /data\ncat > /data/openclaw.json << 'EOF'\n{\n \"agents\": {\n \"defaults\": {\n \"model\": {\n \"primary\": \"anthropic/claude-opus-4-5\",\n \"fallbacks\": [\"anthropic/claude-sonnet-4-5\", \"openai/gpt-4o\"]\n },\n \"maxConcurrent\": 4\n },\n \"list\": [\n {\n \"id\": \"main\",\n \"default\": true\n }\n ]\n },\n \"auth\": {\n \"profiles\": {\n \"anthropic:default\": { \"mode\": \"token\", \"provider\": \"anthropic\" },\n \"openai:default\": { \"mode\": \"token\", \"provider\": \"openai\" }\n }\n },\n \"bindings\": [\n {\n \"agentId\": \"main\",\n \"match\": { \"channel\": \"discord\" }\n }\n ],\n \"channels\": {\n \"discord\": {\n \"enabled\": true,\n \"groupPolicy\": \"allowlist\",\n \"guilds\": {\n \"YOUR_GUILD_ID\": {\n \"channels\": { \"general\": { \"allow\": true } },\n \"requireMention\": false\n }\n }\n }\n },\n \"gateway\": {\n \"mode\": \"local\",\n \"bind\": \"auto\"\n },\n \"meta\": {\n \"lastTouchedVersion\": \"2026.1.29\"\n }\n}\nEOF\nbash theme={null}\nexit\nfly machine restart <machine-id>\nbash theme={null}\nfly open\nbash theme={null}\nfly logs # Live logs\nfly logs --no-tail # Recent logs\nbash theme={null}\nfly ssh console\ntoml theme={null}\n[[vm]]\n memory = \"2048mb\"\nbash theme={null}\nfly machine update <machine-id> --vm-memory 2048 -y\nbash theme={null}\nfly ssh console --command \"rm -f /data/gateway.*.lock\"\nfly machine restart <machine-id>\nbash theme={null}\nfly ssh console --command \"cat /data/openclaw.json\"\nbash theme={null}",
|
||||
"code_samples": [
|
||||
{
|
||||
"code": "**Notes:**\n\n* Non-loopback binds (`--bind lan`) require `OPENCLAW_GATEWAY_TOKEN` for security.\n* Treat these tokens like passwords.\n* **Prefer env vars over config file** for all API keys and tokens. This keeps secrets out of `openclaw.json` where they could be accidentally exposed or logged.\n\n## 4) Deploy",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "First deploy builds the Docker image (\\~2-3 minutes). Subsequent deploys are faster.\n\nAfter deployment, verify:",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "You should see:",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "## 5) Create config file\n\nSSH into the machine to create a proper config:",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "Create the config directory and file:",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "**Note:** With `OPENCLAW_STATE_DIR=/data`, the config path is `/data/openclaw.json`.\n\n**Note:** The Discord token can come from either:\n\n* Environment variable: `DISCORD_BOT_TOKEN` (recommended for secrets)\n* Config file: `channels.discord.token`\n\nIf using env var, no need to add token to config. The gateway reads `DISCORD_BOT_TOKEN` automatically.\n\nRestart to apply:",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "## 6) Access the Gateway\n\n### Control UI\n\nOpen in browser:",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "Or visit `https://my-openclaw.fly.dev/`\n\nPaste your gateway token (the one from `OPENCLAW_GATEWAY_TOKEN`) to authenticate.\n\n### Logs",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "### SSH Console",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "## Troubleshooting\n\n### \"App is not listening on expected address\"\n\nThe gateway is binding to `127.0.0.1` instead of `0.0.0.0`.\n\n**Fix:** Add `--bind lan` to your process command in `fly.toml`.\n\n### Health checks failing / connection refused\n\nFly can't reach the gateway on the configured port.\n\n**Fix:** Ensure `internal_port` matches the gateway port (set `--port 3000` or `OPENCLAW_GATEWAY_PORT=3000`).\n\n### OOM / Memory Issues\n\nContainer keeps restarting or getting killed. Signs: `SIGABRT`, `v8::internal::Runtime_AllocateInYoungGeneration`, or silent restarts.\n\n**Fix:** Increase memory in `fly.toml`:",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "Or update an existing machine:",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "**Note:** 512MB is too small. 1GB may work but can OOM under load or with verbose logging. **2GB is recommended.**\n\n### Gateway Lock Issues\n\nGateway refuses to start with \"already running\" errors.\n\nThis happens when the container restarts but the PID lock file persists on the volume.\n\n**Fix:** Delete the lock file:",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "The lock file is at `/data/gateway.*.lock` (not in a subdirectory).\n\n### Config Not Being Read\n\nIf using `--allow-unconfigured`, the gateway creates a minimal config. Your custom config at `/data/openclaw.json` should be read on restart.\n\nVerify the config exists:",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "### Writing Config via SSH\n\nThe `fly ssh console -C` command doesn't support shell redirection. To write a config file:",
|
||||
"language": "unknown"
|
||||
}
|
||||
],
|
||||
"headings": [
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "4) Deploy",
|
||||
"id": "4)-deploy"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "5) Create config file",
|
||||
"id": "5)-create-config-file"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "6) Access the Gateway",
|
||||
"id": "6)-access-the-gateway"
|
||||
},
|
||||
{
|
||||
"level": "h3",
|
||||
"text": "Control UI",
|
||||
"id": "control-ui"
|
||||
},
|
||||
{
|
||||
"level": "h3",
|
||||
"text": "Logs",
|
||||
"id": "logs"
|
||||
},
|
||||
{
|
||||
"level": "h3",
|
||||
"text": "SSH Console",
|
||||
"id": "ssh-console"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Troubleshooting",
|
||||
"id": "troubleshooting"
|
||||
},
|
||||
{
|
||||
"level": "h3",
|
||||
"text": "\"App is not listening on expected address\"",
|
||||
"id": "\"app-is-not-listening-on-expected-address\""
|
||||
},
|
||||
{
|
||||
"level": "h3",
|
||||
"text": "Health checks failing / connection refused",
|
||||
"id": "health-checks-failing-/-connection-refused"
|
||||
},
|
||||
{
|
||||
"level": "h3",
|
||||
"text": "OOM / Memory Issues",
|
||||
"id": "oom-/-memory-issues"
|
||||
},
|
||||
{
|
||||
"level": "h3",
|
||||
"text": "Gateway Lock Issues",
|
||||
"id": "gateway-lock-issues"
|
||||
},
|
||||
{
|
||||
"level": "h3",
|
||||
"text": "Config Not Being Read",
|
||||
"id": "config-not-being-read"
|
||||
},
|
||||
{
|
||||
"level": "h3",
|
||||
"text": "Writing Config via SSH",
|
||||
"id": "writing-config-via-ssh"
|
||||
}
|
||||
],
|
||||
"url": "llms-txt#channel-tokens",
|
||||
"links": []
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
{
|
||||
"title": "Channels & routing",
|
||||
"content": "OpenClaw routes replies **back to the channel where a message came from**. The\nmodel does not choose a channel; routing is deterministic and controlled by the\nhost configuration.\n\n* **Channel**: `whatsapp`, `telegram`, `discord`, `slack`, `signal`, `imessage`, `webchat`.\n* **AccountId**: per‑channel account instance (when supported).\n* **AgentId**: an isolated workspace + session store (“brain”).\n* **SessionKey**: the bucket key used to store context and control concurrency.\n\n## Session key shapes (examples)\n\nDirect messages collapse to the agent’s **main** session:\n\n* `agent:<agentId>:<mainKey>` (default: `agent:main:main`)\n\nGroups and channels remain isolated per channel:\n\n* Groups: `agent:<agentId>:<channel>:group:<id>`\n* Channels/rooms: `agent:<agentId>:<channel>:channel:<id>`\n\n* Slack/Discord threads append `:thread:<threadId>` to the base key.\n* Telegram forum topics embed `:topic:<topicId>` in the group key.\n\n* `agent:main:telegram:group:-1001234567890:topic:42`\n* `agent:main:discord:channel:123456:thread:987654`\n\n## Routing rules (how an agent is chosen)\n\nRouting picks **one agent** for each inbound message:\n\n1. **Exact peer match** (`bindings` with `peer.kind` + `peer.id`).\n2. **Guild match** (Discord) via `guildId`.\n3. **Team match** (Slack) via `teamId`.\n4. **Account match** (`accountId` on the channel).\n5. **Channel match** (any account on that channel).\n6. **Default agent** (`agents.list[].default`, else first list entry, fallback to `main`).\n\nThe matched agent determines which workspace and session store are used.\n\n## Broadcast groups (run multiple agents)\n\nBroadcast groups let you run **multiple agents** for the same peer **when OpenClaw would normally reply** (for example: in WhatsApp groups, after mention/activation gating).\n\nSee: [Broadcast Groups](/broadcast-groups).\n\n* `agents.list`: named agent definitions (workspace, model, etc.).\n* `bindings`: map inbound channels/accounts/peers to agents.\n\nSession stores live under the state directory (default `~/.openclaw`):\n\n* `~/.openclaw/agents/<agentId>/sessions/sessions.json`\n* JSONL transcripts live alongside the store\n\nYou can override the store path via `session.store` and `{agentId}` templating.\n\nWebChat attaches to the **selected agent** and defaults to the agent’s main\nsession. Because of this, WebChat lets you see cross‑channel context for that\nagent in one place.\n\nInbound replies include:\n\n* `ReplyToId`, `ReplyToBody`, and `ReplyToSender` when available.\n* Quoted context is appended to `Body` as a `[Replying to ...]` block.\n\nThis is consistent across channels.",
|
||||
"code_samples": [
|
||||
{
|
||||
"code": "See: [Broadcast Groups](/broadcast-groups).\n\n## Config overview\n\n* `agents.list`: named agent definitions (workspace, model, etc.).\n* `bindings`: map inbound channels/accounts/peers to agents.\n\nExample:",
|
||||
"language": "unknown"
|
||||
}
|
||||
],
|
||||
"headings": [
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Key terms",
|
||||
"id": "key-terms"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Session key shapes (examples)",
|
||||
"id": "session-key-shapes-(examples)"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Routing rules (how an agent is chosen)",
|
||||
"id": "routing-rules-(how-an-agent-is-chosen)"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Broadcast groups (run multiple agents)",
|
||||
"id": "broadcast-groups-(run-multiple-agents)"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Config overview",
|
||||
"id": "config-overview"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Session storage",
|
||||
"id": "session-storage"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "WebChat behavior",
|
||||
"id": "webchat-behavior"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Reply context",
|
||||
"id": "reply-context"
|
||||
}
|
||||
],
|
||||
"url": "llms-txt#channels-&-routing",
|
||||
"links": []
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"title": "Chat Channels",
|
||||
"content": "OpenClaw can talk to you on any chat app you already use. Each channel connects via the Gateway.\nText is supported everywhere; media and reactions vary by channel.\n\n## Supported channels\n\n* [WhatsApp](/channels/whatsapp) — Most popular; uses Baileys and requires QR pairing.\n* [Telegram](/channels/telegram) — Bot API via grammY; supports groups.\n* [Discord](/channels/discord) — Discord Bot API + Gateway; supports servers, channels, and DMs.\n* [Slack](/channels/slack) — Bolt SDK; workspace apps.\n* [Feishu](/channels/feishu) — Feishu/Lark bot via WebSocket (plugin, installed separately).\n* [Google Chat](/channels/googlechat) — Google Chat API app via HTTP webhook.\n* [Mattermost](/channels/mattermost) — Bot API + WebSocket; channels, groups, DMs (plugin, installed separately).\n* [Signal](/channels/signal) — signal-cli; privacy-focused.\n* [BlueBubbles](/channels/bluebubbles) — **Recommended for iMessage**; uses the BlueBubbles macOS server REST API with full feature support (edit, unsend, effects, reactions, group management — edit currently broken on macOS 26 Tahoe).\n* [iMessage (legacy)](/channels/imessage) — Legacy macOS integration via imsg CLI (deprecated, use BlueBubbles for new setups).\n* [Microsoft Teams](/channels/msteams) — Bot Framework; enterprise support (plugin, installed separately).\n* [LINE](/channels/line) — LINE Messaging API bot (plugin, installed separately).\n* [Nextcloud Talk](/channels/nextcloud-talk) — Self-hosted chat via Nextcloud Talk (plugin, installed separately).\n* [Matrix](/channels/matrix) — Matrix protocol (plugin, installed separately).\n* [Nostr](/channels/nostr) — Decentralized DMs via NIP-04 (plugin, installed separately).\n* [Tlon](/channels/tlon) — Urbit-based messenger (plugin, installed separately).\n* [Twitch](/channels/twitch) — Twitch chat via IRC connection (plugin, installed separately).\n* [Zalo](/channels/zalo) — Zalo Bot API; Vietnam's popular messenger (plugin, installed separately).\n* [Zalo Personal](/channels/zalouser) — Zalo personal account via QR login (plugin, installed separately).\n* [WebChat](/web/webchat) — Gateway WebChat UI over WebSocket.\n\n* Channels can run simultaneously; configure multiple and OpenClaw will route per chat.\n* Fastest setup is usually **Telegram** (simple bot token). WhatsApp requires QR pairing and\n stores more state on disk.\n* Group behavior varies by channel; see [Groups](/concepts/groups).\n* DM pairing and allowlists are enforced for safety; see [Security](/gateway/security).\n* Telegram internals: [grammY notes](/channels/grammy).\n* Troubleshooting: [Channel troubleshooting](/channels/troubleshooting).\n* Model providers are documented separately; see [Model Providers](/providers/models).",
|
||||
"code_samples": [],
|
||||
"headings": [
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Supported channels",
|
||||
"id": "supported-channels"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Notes",
|
||||
"id": "notes"
|
||||
}
|
||||
],
|
||||
"url": "llms-txt#chat-channels",
|
||||
"links": []
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"title": "Check health",
|
||||
"content": "fly status\nfly logs\nbash theme={null}",
|
||||
"code_samples": [
|
||||
{
|
||||
"code": "### Updating Machine Command\n\nIf you need to change the startup command without a full redeploy:",
|
||||
"language": "unknown"
|
||||
}
|
||||
],
|
||||
"headings": [
|
||||
{
|
||||
"level": "h3",
|
||||
"text": "Updating Machine Command",
|
||||
"id": "updating-machine-command"
|
||||
}
|
||||
],
|
||||
"url": "llms-txt#check-health",
|
||||
"links": []
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"title": "Check local status (creds, sessions, queued events)",
|
||||
"content": "",
|
||||
"code_samples": [],
|
||||
"headings": [],
|
||||
"url": "llms-txt#check-local-status-(creds,-sessions,-queued-events)",
|
||||
"links": []
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"title": "Check logs",
|
||||
"content": "sudo journalctl -u openclaw -n 100",
|
||||
"code_samples": [],
|
||||
"headings": [],
|
||||
"url": "llms-txt#check-logs",
|
||||
"links": []
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"title": "Check sandbox image",
|
||||
"content": "sudo docker images | grep openclaw-sandbox",
|
||||
"code_samples": [],
|
||||
"headings": [],
|
||||
"url": "llms-txt#check-sandbox-image",
|
||||
"links": []
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"title": "Check service status",
|
||||
"content": "sudo systemctl status openclaw",
|
||||
"code_samples": [],
|
||||
"headings": [],
|
||||
"url": "llms-txt#check-service-status",
|
||||
"links": []
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"title": "Chrome Extension",
|
||||
"content": "Source: https://docs.openclaw.ai/tools/chrome-extension",
|
||||
"code_samples": [],
|
||||
"headings": [],
|
||||
"url": "llms-txt#chrome-extension",
|
||||
"links": []
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
153
openclaw-knowhow-skill/output/openclaw-docs_data/pages/ClawHub_e16bb5304f.json
Executable file
153
openclaw-knowhow-skill/output/openclaw-docs_data/pages/ClawHub_e16bb5304f.json
Executable file
File diff suppressed because one or more lines are too long
@@ -0,0 +1,304 @@
|
||||
{
|
||||
"title": "Clear override (fall back to config auth.order / round-robin)",
|
||||
"content": "openclaw models auth order clear --provider anthropic\nbash theme={null}\nopenclaw models auth order set --provider anthropic --agent main anthropic:default\n\n--port > OPENCLAW_GATEWAY_PORT > gateway.port > default 18789\nbash theme={null}\nopenclaw gateway install --force\njson5 theme={null}\n{\n gateway: {\n mode: \"remote\",\n remote: {\n url: \"ws://gateway.tailnet:18789\",\n token: \"your-token\",\n password: \"your-password\",\n },\n },\n}\n\nopenclaw tui --url ws://<host>:18789 --token <token>\n\n/tmp/openclaw/openclaw-YYYY-MM-DD.log\nbash theme={null}\nopenclaw logs --follow\nbash theme={null}\nopenclaw gateway status\nopenclaw gateway restart\npowershell theme={null}\nwsl\nopenclaw gateway status\nopenclaw gateway restart\nbash theme={null}\nopenclaw gateway run\npowershell theme={null}\nopenclaw gateway status\nopenclaw gateway restart\npowershell theme={null}\nopenclaw gateway run\nbash theme={null}\nopenclaw status\nopenclaw models status\nopenclaw channels status\nopenclaw logs --follow\nbash theme={null}\nopenclaw logs --follow\nbash theme={null}\nopenclaw channels status\nopenclaw channels logs --channel telegram\nbash theme={null}\nopenclaw status\nopenclaw models status\nopenclaw logs --follow\nbash theme={null}\nopenclaw gateway stop\nopenclaw gateway start\nbash theme={null}\nopenclaw gateway run\nbash theme={null}\nopenclaw message send --target +15555550123 --message \"Here you go\" --media /path/to/file.png\nbash theme={null}\nopenclaw pairing list telegram\nbash theme={null}\nopenclaw pairing approve whatsapp <code>\nbash theme={null}\nopenclaw pairing list whatsapp\n\n/verbose off\n/reasoning off\n\nstop\nabort\nesc\nwait\nexit\ninterrupt\n\nprocess action:kill sessionId:XXX\njson5 theme={null}\n{\n agents: {\n defaults: {\n tools: {\n message: {\n crossContext: {\n allowAcrossProviders: true,\n marker: { enabled: true, prefix: \"[from {channel}] \" },\n },\n },\n },\n },\n },\n}\n```\n\nRestart the gateway after editing config. If you only want this for a single\nagent, set it under `agents.list[].tools.message` instead.\n\n### Why does it feel like the bot ignores rapidfire messages\n\nQueue mode controls how new messages interact with an in-flight run. Use `/queue` to change modes:\n\n* `steer` - new messages redirect the current task\n* `followup` - run messages one at a time\n* `collect` - batch messages and reply once (default)\n* `steer-backlog` - steer now, then process backlog\n* `interrupt` - abort current run and start fresh\n\nYou can add options like `debounce:2s cap:25 drop:summarize` for followup modes.\n\n## Answer the exact question from the screenshot/chat log\n\n**Q: \"What's the default model for Anthropic with an API key?\"**\n\n**A:** In OpenClaw, credentials and model selection are separate. Setting `ANTHROPIC_API_KEY` (or storing an Anthropic API key in auth profiles) enables authentication, but the actual default model is whatever you configure in `agents.defaults.model.primary` (for example, `anthropic/claude-sonnet-4-5` or `anthropic/claude-opus-4-5`). If you see `No credentials found for profile \"anthropic:default\"`, it means the Gateway couldn't find Anthropic credentials in the expected `auth-profiles.json` for the agent that's running.\n\nStill stuck? Ask in [Discord](https://discord.com/invite/clawd) or open a [GitHub discussion](https://github.com/openclaw/openclaw/discussions).",
|
||||
"code_samples": [
|
||||
{
|
||||
"code": "To target a specific agent:",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "### OAuth vs API key whats the difference\n\nOpenClaw supports both:\n\n* **OAuth** often leverages subscription access (where applicable).\n* **API keys** use pay-per-token billing.\n\nThe wizard explicitly supports Anthropic setup-token and OpenAI Codex OAuth and can store API keys for you.\n\n## Gateway: ports, \"already running\", and remote mode\n\n### What port does the Gateway use\n\n`gateway.port` controls the single multiplexed port for WebSocket + HTTP (Control UI, hooks, etc.).\n\nPrecedence:",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "### Why does openclaw gateway status say Runtime running but RPC probe failed\n\nBecause \"running\" is the **supervisor's** view (launchd/systemd/schtasks). The RPC probe is the CLI actually connecting to the gateway WebSocket and calling `status`.\n\nUse `openclaw gateway status` and trust these lines:\n\n* `Probe target:` (the URL the probe actually used)\n* `Listening:` (what's actually bound on the port)\n* `Last gateway error:` (common root cause when the process is alive but the port isn't listening)\n\n### Why does openclaw gateway status show Config cli and Config service different\n\nYou're editing one config file while the service is running another (often a `--profile` / `OPENCLAW_STATE_DIR` mismatch).\n\nFix:",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "Run that from the same `--profile` / environment you want the service to use.\n\n### What does another gateway instance is already listening mean\n\nOpenClaw enforces a runtime lock by binding the WebSocket listener immediately on startup (default `ws://127.0.0.1:18789`). If the bind fails with `EADDRINUSE`, it throws `GatewayLockError` indicating another instance is already listening.\n\nFix: stop the other instance, free the port, or run with `openclaw gateway --port <port>`.\n\n### How do I run OpenClaw in remote mode client connects to a Gateway elsewhere\n\nSet `gateway.mode: \"remote\"` and point to a remote WebSocket URL, optionally with a token/password:",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "Notes:\n\n* `openclaw gateway` only starts when `gateway.mode` is `local` (or you pass the override flag).\n* The macOS app watches the config file and switches modes live when these values change.\n\n### The Control UI says unauthorized or keeps reconnecting What now\n\nYour gateway is running with auth enabled (`gateway.auth.*`), but the UI is not sending the matching token/password.\n\nFacts (from code):\n\n* The Control UI stores the token in browser localStorage key `openclaw.control.settings.v1`.\n* The UI can import `?token=...` (and/or `?password=...`) once, then strips it from the URL.\n\nFix:\n\n* Fastest: `openclaw dashboard` (prints + copies tokenized link, tries to open; shows SSH hint if headless).\n* If you don't have a token yet: `openclaw doctor --generate-gateway-token`.\n* If remote, tunnel first: `ssh -N -L 18789:127.0.0.1:18789 user@host` then open `http://127.0.0.1:18789/?token=...`.\n* Set `gateway.auth.token` (or `OPENCLAW_GATEWAY_TOKEN`) on the gateway host.\n* In the Control UI settings, paste the same token (or refresh with a one-time `?token=...` link).\n* Still stuck? Run `openclaw status --all` and follow [Troubleshooting](/gateway/troubleshooting). See [Dashboard](/web/dashboard) for auth details.\n\n### I set gatewaybind tailnet but it cant bind nothing listens\n\n`tailnet` bind picks a Tailscale IP from your network interfaces (100.64.0.0/10). If the machine isn't on Tailscale (or the interface is down), there's nothing to bind to.\n\nFix:\n\n* Start Tailscale on that host (so it has a 100.x address), or\n* Switch to `gateway.bind: \"loopback\"` / `\"lan\"`.\n\nNote: `tailnet` is explicit. `auto` prefers loopback; use `gateway.bind: \"tailnet\"` when you want a tailnet-only bind.\n\n### Can I run multiple Gateways on the same host\n\nUsually no - one Gateway can run multiple messaging channels and agents. Use multiple Gateways only when you need redundancy (ex: rescue bot) or hard isolation.\n\nYes, but you must isolate:\n\n* `OPENCLAW_CONFIG_PATH` (per-instance config)\n* `OPENCLAW_STATE_DIR` (per-instance state)\n* `agents.defaults.workspace` (workspace isolation)\n* `gateway.port` (unique ports)\n\nQuick setup (recommended):\n\n* Use `openclaw --profile <name> …` per instance (auto-creates `~/.openclaw-<name>`).\n* Set a unique `gateway.port` in each profile config (or pass `--port` for manual runs).\n* Install a per-profile service: `openclaw --profile <name> gateway install`.\n\nProfiles also suffix service names (`bot.molt.<profile>`; legacy `com.openclaw.*`, `openclaw-gateway-<profile>.service`, `OpenClaw Gateway (<profile>)`).\nFull guide: [Multiple gateways](/gateway/multiple-gateways).\n\n### What does invalid handshake code 1008 mean\n\nThe Gateway is a **WebSocket server**, and it expects the very first message to\nbe a `connect` frame. If it receives anything else, it closes the connection\nwith **code 1008** (policy violation).\n\nCommon causes:\n\n* You opened the **HTTP** URL in a browser (`http://...`) instead of a WS client.\n* You used the wrong port or path.\n* A proxy or tunnel stripped auth headers or sent a non-Gateway request.\n\nQuick fixes:\n\n1. Use the WS URL: `ws://<host>:18789` (or `wss://...` if HTTPS).\n2. Don't open the WS port in a normal browser tab.\n3. If auth is on, include the token/password in the `connect` frame.\n\nIf you're using the CLI or TUI, the URL should look like:",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "Protocol details: [Gateway protocol](/gateway/protocol).\n\n## Logging and debugging\n\n### Where are logs\n\nFile logs (structured):",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "You can set a stable path via `logging.file`. File log level is controlled by `logging.level`. Console verbosity is controlled by `--verbose` and `logging.consoleLevel`.\n\nFastest log tail:",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "Service/supervisor logs (when the gateway runs via launchd/systemd):\n\n* macOS: `$OPENCLAW_STATE_DIR/logs/gateway.log` and `gateway.err.log` (default: `~/.openclaw/logs/...`; profiles use `~/.openclaw-<profile>/logs/...`)\n* Linux: `journalctl --user -u openclaw-gateway[-<profile>].service -n 200 --no-pager`\n* Windows: `schtasks /Query /TN \"OpenClaw Gateway (<profile>)\" /V /FO LIST`\n\nSee [Troubleshooting](/gateway/troubleshooting#log-locations) for more.\n\n### How do I startstoprestart the Gateway service\n\nUse the gateway helpers:",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "If you run the gateway manually, `openclaw gateway --force` can reclaim the port. See [Gateway](/gateway).\n\n### I closed my terminal on Windows how do I restart OpenClaw\n\nThere are **two Windows install modes**:\n\n**1) WSL2 (recommended):** the Gateway runs inside Linux.\n\nOpen PowerShell, enter WSL, then restart:",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "If you never installed the service, start it in the foreground:",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "**2) Native Windows (not recommended):** the Gateway runs directly in Windows.\n\nOpen PowerShell and run:",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "If you run it manually (no service), use:",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "Docs: [Windows (WSL2)](/platforms/windows), [Gateway service runbook](/gateway).\n\n### The Gateway is up but replies never arrive What should I check\n\nStart with a quick health sweep:",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "Common causes:\n\n* Model auth not loaded on the **gateway host** (check `models status`).\n* Channel pairing/allowlist blocking replies (check channel config + logs).\n* WebChat/Dashboard is open without the right token.\n\nIf you are remote, confirm the tunnel/Tailscale connection is up and that the\nGateway WebSocket is reachable.\n\nDocs: [Channels](/channels), [Troubleshooting](/gateway/troubleshooting), [Remote access](/gateway/remote).\n\n### Disconnected from gateway no reason what now\n\nThis usually means the UI lost the WebSocket connection. Check:\n\n1. Is the Gateway running? `openclaw gateway status`\n2. Is the Gateway healthy? `openclaw status`\n3. Does the UI have the right token? `openclaw dashboard`\n4. If remote, is the tunnel/Tailscale link up?\n\nThen tail logs:",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "Docs: [Dashboard](/web/dashboard), [Remote access](/gateway/remote), [Troubleshooting](/gateway/troubleshooting).\n\n### Telegram setMyCommands fails with network errors What should I check\n\nStart with logs and channel status:",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "If you are on a VPS or behind a proxy, confirm outbound HTTPS is allowed and DNS works.\nIf the Gateway is remote, make sure you are looking at logs on the Gateway host.\n\nDocs: [Telegram](/channels/telegram), [Channel troubleshooting](/channels/troubleshooting).\n\n### TUI shows no output What should I check\n\nFirst confirm the Gateway is reachable and the agent can run:",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "In the TUI, use `/status` to see the current state. If you expect replies in a chat\nchannel, make sure delivery is enabled (`/deliver on`).\n\nDocs: [TUI](/tui), [Slash commands](/tools/slash-commands).\n\n### How do I completely stop then start the Gateway\n\nIf you installed the service:",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "This stops/starts the **supervised service** (launchd on macOS, systemd on Linux).\nUse this when the Gateway runs in the background as a daemon.\n\nIf you're running in the foreground, stop with Ctrl-C, then:",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "Docs: [Gateway service runbook](/gateway).\n\n### ELI5 openclaw gateway restart vs openclaw gateway\n\n* `openclaw gateway restart`: restarts the **background service** (launchd/systemd).\n* `openclaw gateway`: runs the gateway **in the foreground** for this terminal session.\n\nIf you installed the service, use the gateway commands. Use `openclaw gateway` when\nyou want a one-off, foreground run.\n\n### What's the fastest way to get more details when something fails\n\nStart the Gateway with `--verbose` to get more console detail. Then inspect the log file for channel auth, model routing, and RPC errors.\n\n## Media & attachments\n\n### My skill generated an imagePDF but nothing was sent\n\nOutbound attachments from the agent must include a `MEDIA:<path-or-url>` line (on its own line). See [OpenClaw assistant setup](/start/openclaw) and [Agent send](/tools/agent-send).\n\nCLI sending:",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "Also check:\n\n* The target channel supports outbound media and isn't blocked by allowlists.\n* The file is within the provider's size limits (images are resized to max 2048px).\n\nSee [Images](/nodes/images).\n\n## Security and access control\n\n### Is it safe to expose OpenClaw to inbound DMs\n\nTreat inbound DMs as untrusted input. Defaults are designed to reduce risk:\n\n* Default behavior on DM-capable channels is **pairing**:\n * Unknown senders receive a pairing code; the bot does not process their message.\n * Approve with: `openclaw pairing approve <channel> <code>`\n * Pending requests are capped at **3 per channel**; check `openclaw pairing list <channel>` if a code didn't arrive.\n* Opening DMs publicly requires explicit opt-in (`dmPolicy: \"open\"` and allowlist `\"*\"`).\n\nRun `openclaw doctor` to surface risky DM policies.\n\n### Is prompt injection only a concern for public bots\n\nNo. Prompt injection is about **untrusted content**, not just who can DM the bot.\nIf your assistant reads external content (web search/fetch, browser pages, emails,\ndocs, attachments, pasted logs), that content can include instructions that try\nto hijack the model. This can happen even if **you are the only sender**.\n\nThe biggest risk is when tools are enabled: the model can be tricked into\nexfiltrating context or calling tools on your behalf. Reduce the blast radius by:\n\n* using a read-only or tool-disabled \"reader\" agent to summarize untrusted content\n* keeping `web_search` / `web_fetch` / `browser` off for tool-enabled agents\n* sandboxing and strict tool allowlists\n\nDetails: [Security](/gateway/security).\n\n### Should my bot have its own email GitHub account or phone number\n\nYes, for most setups. Isolating the bot with separate accounts and phone numbers\nreduces the blast radius if something goes wrong. This also makes it easier to rotate\ncredentials or revoke access without impacting your personal accounts.\n\nStart small. Give access only to the tools and accounts you actually need, and expand\nlater if required.\n\nDocs: [Security](/gateway/security), [Pairing](/start/pairing).\n\n### Can I give it autonomy over my text messages and is that safe\n\nWe do **not** recommend full autonomy over your personal messages. The safest pattern is:\n\n* Keep DMs in **pairing mode** or a tight allowlist.\n* Use a **separate number or account** if you want it to message on your behalf.\n* Let it draft, then **approve before sending**.\n\nIf you want to experiment, do it on a dedicated account and keep it isolated. See\n[Security](/gateway/security).\n\n### Can I use cheaper models for personal assistant tasks\n\nYes, **if** the agent is chat-only and the input is trusted. Smaller tiers are\nmore susceptible to instruction hijacking, so avoid them for tool-enabled agents\nor when reading untrusted content. If you must use a smaller model, lock down\ntools and run inside a sandbox. See [Security](/gateway/security).\n\n### I ran start in Telegram but didnt get a pairing code\n\nPairing codes are sent **only** when an unknown sender messages the bot and\n`dmPolicy: \"pairing\"` is enabled. `/start` by itself doesn't generate a code.\n\nCheck pending requests:",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "If you want immediate access, allowlist your sender id or set `dmPolicy: \"open\"`\nfor that account.\n\n### WhatsApp will it message my contacts How does pairing work\n\nNo. Default WhatsApp DM policy is **pairing**. Unknown senders only get a pairing code and their message is **not processed**. OpenClaw only replies to chats it receives or to explicit sends you trigger.\n\nApprove pairing with:",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "List pending requests:",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "Wizard phone number prompt: it's used to set your **allowlist/owner** so your own DMs are permitted. It's not used for auto-sending. If you run on your personal WhatsApp number, use that number and enable `channels.whatsapp.selfChatMode`.\n\n## Chat commands, aborting tasks, and \"it won't stop\"\n\n### How do I stop internal system messages from showing in chat\n\nMost internal or tool messages only appear when **verbose** or **reasoning** is enabled\nfor that session.\n\nFix in the chat where you see it:",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "If it is still noisy, check the session settings in the Control UI and set verbose\nto **inherit**. Also confirm you are not using a bot profile with `verboseDefault` set\nto `on` in config.\n\nDocs: [Thinking and verbose](/tools/thinking), [Security](/gateway/security#reasoning--verbose-output-in-groups).\n\n### How do I stopcancel a running task\n\nSend any of these **as a standalone message** (no slash):",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "These are abort triggers (not slash commands).\n\nFor background processes (from the exec tool), you can ask the agent to run:",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "Slash commands overview: see [Slash commands](/tools/slash-commands).\n\nMost commands must be sent as a **standalone** message that starts with `/`, but a few shortcuts (like `/status`) also work inline for allowlisted senders.\n\n### How do I send a Discord message from Telegram Crosscontext messaging denied\n\nOpenClaw blocks **cross-provider** messaging by default. If a tool call is bound\nto Telegram, it won't send to Discord unless you explicitly allow it.\n\nEnable cross-provider messaging for the agent:",
|
||||
"language": "unknown"
|
||||
}
|
||||
],
|
||||
"headings": [
|
||||
{
|
||||
"level": "h3",
|
||||
"text": "OAuth vs API key whats the difference",
|
||||
"id": "oauth-vs-api-key-whats-the-difference"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Gateway: ports, \"already running\", and remote mode",
|
||||
"id": "gateway:-ports,-\"already-running\",-and-remote-mode"
|
||||
},
|
||||
{
|
||||
"level": "h3",
|
||||
"text": "What port does the Gateway use",
|
||||
"id": "what-port-does-the-gateway-use"
|
||||
},
|
||||
{
|
||||
"level": "h3",
|
||||
"text": "Why does openclaw gateway status say Runtime running but RPC probe failed",
|
||||
"id": "why-does-openclaw-gateway-status-say-runtime-running-but-rpc-probe-failed"
|
||||
},
|
||||
{
|
||||
"level": "h3",
|
||||
"text": "Why does openclaw gateway status show Config cli and Config service different",
|
||||
"id": "why-does-openclaw-gateway-status-show-config-cli-and-config-service-different"
|
||||
},
|
||||
{
|
||||
"level": "h3",
|
||||
"text": "What does another gateway instance is already listening mean",
|
||||
"id": "what-does-another-gateway-instance-is-already-listening-mean"
|
||||
},
|
||||
{
|
||||
"level": "h3",
|
||||
"text": "How do I run OpenClaw in remote mode client connects to a Gateway elsewhere",
|
||||
"id": "how-do-i-run-openclaw-in-remote-mode-client-connects-to-a-gateway-elsewhere"
|
||||
},
|
||||
{
|
||||
"level": "h3",
|
||||
"text": "The Control UI says unauthorized or keeps reconnecting What now",
|
||||
"id": "the-control-ui-says-unauthorized-or-keeps-reconnecting-what-now"
|
||||
},
|
||||
{
|
||||
"level": "h3",
|
||||
"text": "I set gatewaybind tailnet but it cant bind nothing listens",
|
||||
"id": "i-set-gatewaybind-tailnet-but-it-cant-bind-nothing-listens"
|
||||
},
|
||||
{
|
||||
"level": "h3",
|
||||
"text": "Can I run multiple Gateways on the same host",
|
||||
"id": "can-i-run-multiple-gateways-on-the-same-host"
|
||||
},
|
||||
{
|
||||
"level": "h3",
|
||||
"text": "What does invalid handshake code 1008 mean",
|
||||
"id": "what-does-invalid-handshake-code-1008-mean"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Logging and debugging",
|
||||
"id": "logging-and-debugging"
|
||||
},
|
||||
{
|
||||
"level": "h3",
|
||||
"text": "Where are logs",
|
||||
"id": "where-are-logs"
|
||||
},
|
||||
{
|
||||
"level": "h3",
|
||||
"text": "How do I startstoprestart the Gateway service",
|
||||
"id": "how-do-i-startstoprestart-the-gateway-service"
|
||||
},
|
||||
{
|
||||
"level": "h3",
|
||||
"text": "I closed my terminal on Windows how do I restart OpenClaw",
|
||||
"id": "i-closed-my-terminal-on-windows-how-do-i-restart-openclaw"
|
||||
},
|
||||
{
|
||||
"level": "h3",
|
||||
"text": "The Gateway is up but replies never arrive What should I check",
|
||||
"id": "the-gateway-is-up-but-replies-never-arrive-what-should-i-check"
|
||||
},
|
||||
{
|
||||
"level": "h3",
|
||||
"text": "Disconnected from gateway no reason what now",
|
||||
"id": "disconnected-from-gateway-no-reason-what-now"
|
||||
},
|
||||
{
|
||||
"level": "h3",
|
||||
"text": "Telegram setMyCommands fails with network errors What should I check",
|
||||
"id": "telegram-setmycommands-fails-with-network-errors-what-should-i-check"
|
||||
},
|
||||
{
|
||||
"level": "h3",
|
||||
"text": "TUI shows no output What should I check",
|
||||
"id": "tui-shows-no-output-what-should-i-check"
|
||||
},
|
||||
{
|
||||
"level": "h3",
|
||||
"text": "How do I completely stop then start the Gateway",
|
||||
"id": "how-do-i-completely-stop-then-start-the-gateway"
|
||||
},
|
||||
{
|
||||
"level": "h3",
|
||||
"text": "ELI5 openclaw gateway restart vs openclaw gateway",
|
||||
"id": "eli5-openclaw-gateway-restart-vs-openclaw-gateway"
|
||||
},
|
||||
{
|
||||
"level": "h3",
|
||||
"text": "What's the fastest way to get more details when something fails",
|
||||
"id": "what's-the-fastest-way-to-get-more-details-when-something-fails"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Media & attachments",
|
||||
"id": "media-&-attachments"
|
||||
},
|
||||
{
|
||||
"level": "h3",
|
||||
"text": "My skill generated an imagePDF but nothing was sent",
|
||||
"id": "my-skill-generated-an-imagepdf-but-nothing-was-sent"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Security and access control",
|
||||
"id": "security-and-access-control"
|
||||
},
|
||||
{
|
||||
"level": "h3",
|
||||
"text": "Is it safe to expose OpenClaw to inbound DMs",
|
||||
"id": "is-it-safe-to-expose-openclaw-to-inbound-dms"
|
||||
},
|
||||
{
|
||||
"level": "h3",
|
||||
"text": "Is prompt injection only a concern for public bots",
|
||||
"id": "is-prompt-injection-only-a-concern-for-public-bots"
|
||||
},
|
||||
{
|
||||
"level": "h3",
|
||||
"text": "Should my bot have its own email GitHub account or phone number",
|
||||
"id": "should-my-bot-have-its-own-email-github-account-or-phone-number"
|
||||
},
|
||||
{
|
||||
"level": "h3",
|
||||
"text": "Can I give it autonomy over my text messages and is that safe",
|
||||
"id": "can-i-give-it-autonomy-over-my-text-messages-and-is-that-safe"
|
||||
},
|
||||
{
|
||||
"level": "h3",
|
||||
"text": "Can I use cheaper models for personal assistant tasks",
|
||||
"id": "can-i-use-cheaper-models-for-personal-assistant-tasks"
|
||||
},
|
||||
{
|
||||
"level": "h3",
|
||||
"text": "I ran start in Telegram but didnt get a pairing code",
|
||||
"id": "i-ran-start-in-telegram-but-didnt-get-a-pairing-code"
|
||||
},
|
||||
{
|
||||
"level": "h3",
|
||||
"text": "WhatsApp will it message my contacts How does pairing work",
|
||||
"id": "whatsapp-will-it-message-my-contacts-how-does-pairing-work"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Chat commands, aborting tasks, and \"it won't stop\"",
|
||||
"id": "chat-commands,-aborting-tasks,-and-\"it-won't-stop\""
|
||||
},
|
||||
{
|
||||
"level": "h3",
|
||||
"text": "How do I stop internal system messages from showing in chat",
|
||||
"id": "how-do-i-stop-internal-system-messages-from-showing-in-chat"
|
||||
},
|
||||
{
|
||||
"level": "h3",
|
||||
"text": "How do I stopcancel a running task",
|
||||
"id": "how-do-i-stopcancel-a-running-task"
|
||||
},
|
||||
{
|
||||
"level": "h3",
|
||||
"text": "How do I send a Discord message from Telegram Crosscontext messaging denied",
|
||||
"id": "how-do-i-send-a-discord-message-from-telegram-crosscontext-messaging-denied"
|
||||
},
|
||||
{
|
||||
"level": "h3",
|
||||
"text": "Why does it feel like the bot ignores rapidfire messages",
|
||||
"id": "why-does-it-feel-like-the-bot-ignores-rapidfire-messages"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Answer the exact question from the screenshot/chat log",
|
||||
"id": "answer-the-exact-question-from-the-screenshot/chat-log"
|
||||
}
|
||||
],
|
||||
"url": "llms-txt#clear-override-(fall-back-to-config-auth.order-/-round-robin)",
|
||||
"links": []
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"title": "Clone the repo",
|
||||
"content": "git clone https://github.com/openclaw/openclaw.git\ncd openclaw",
|
||||
"code_samples": [],
|
||||
"headings": [],
|
||||
"url": "llms-txt#clone-the-repo",
|
||||
"links": []
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
{
|
||||
"title": "Command Queue (2026-01-16)",
|
||||
"content": "We serialize inbound auto-reply runs (all channels) through a tiny in-process queue to prevent multiple agent runs from colliding, while still allowing safe parallelism across sessions.\n\n* Auto-reply runs can be expensive (LLM calls) and can collide when multiple inbound messages arrive close together.\n* Serializing avoids competing for shared resources (session files, logs, CLI stdin) and reduces the chance of upstream rate limits.\n\n* A lane-aware FIFO queue drains each lane with a configurable concurrency cap (default 1 for unconfigured lanes; main defaults to 4, subagent to 8).\n* `runEmbeddedPiAgent` enqueues by **session key** (lane `session:<key>`) to guarantee only one active run per session.\n* Each session run is then queued into a **global lane** (`main` by default) so overall parallelism is capped by `agents.defaults.maxConcurrent`.\n* When verbose logging is enabled, queued runs emit a short notice if they waited more than \\~2s before starting.\n* Typing indicators still fire immediately on enqueue (when supported by the channel) so user experience is unchanged while we wait our turn.\n\n## Queue modes (per channel)\n\nInbound messages can steer the current run, wait for a followup turn, or do both:\n\n* `steer`: inject immediately into the current run (cancels pending tool calls after the next tool boundary). If not streaming, falls back to followup.\n* `followup`: enqueue for the next agent turn after the current run ends.\n* `collect`: coalesce all queued messages into a **single** followup turn (default). If messages target different channels/threads, they drain individually to preserve routing.\n* `steer-backlog` (aka `steer+backlog`): steer now **and** preserve the message for a followup turn.\n* `interrupt` (legacy): abort the active run for that session, then run the newest message.\n* `queue` (legacy alias): same as `steer`.\n\nSteer-backlog means you can get a followup response after the steered run, so\nstreaming surfaces can look like duplicates. Prefer `collect`/`steer` if you want\none response per inbound message.\nSend `/queue collect` as a standalone command (per-session) or set `messages.queue.byChannel.discord: \"collect\"`.\n\nDefaults (when unset in config):\n\n* All surfaces → `collect`\n\nConfigure globally or per channel via `messages.queue`:\n\nOptions apply to `followup`, `collect`, and `steer-backlog` (and to `steer` when it falls back to followup):\n\n* `debounceMs`: wait for quiet before starting a followup turn (prevents “continue, continue”).\n* `cap`: max queued messages per session.\n* `drop`: overflow policy (`old`, `new`, `summarize`).\n\nSummarize keeps a short bullet list of dropped messages and injects it as a synthetic followup prompt.\nDefaults: `debounceMs: 1000`, `cap: 20`, `drop: summarize`.\n\n## Per-session overrides\n\n* Send `/queue <mode>` as a standalone command to store the mode for the current session.\n* Options can be combined: `/queue collect debounce:2s cap:25 drop:summarize`\n* `/queue default` or `/queue reset` clears the session override.\n\n## Scope and guarantees\n\n* Applies to auto-reply agent runs across all inbound channels that use the gateway reply pipeline (WhatsApp web, Telegram, Slack, Discord, Signal, iMessage, webchat, etc.).\n* Default lane (`main`) is process-wide for inbound + main heartbeats; set `agents.defaults.maxConcurrent` to allow multiple sessions in parallel.\n* Additional lanes may exist (e.g. `cron`, `subagent`) so background jobs can run in parallel without blocking inbound replies.\n* Per-session lanes guarantee that only one agent run touches a given session at a time.\n* No external dependencies or background worker threads; pure TypeScript + promises.\n\n* If commands seem stuck, enable verbose logs and look for “queued for …ms” lines to confirm the queue is draining.\n* If you need queue depth, enable verbose logs and watch for queue timing lines.",
|
||||
"code_samples": [],
|
||||
"headings": [
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Why",
|
||||
"id": "why"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "How it works",
|
||||
"id": "how-it-works"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Queue modes (per channel)",
|
||||
"id": "queue-modes-(per-channel)"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Queue options",
|
||||
"id": "queue-options"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Per-session overrides",
|
||||
"id": "per-session-overrides"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Scope and guarantees",
|
||||
"id": "scope-and-guarantees"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Troubleshooting",
|
||||
"id": "troubleshooting"
|
||||
}
|
||||
],
|
||||
"url": "llms-txt#command-queue-(2026-01-16)",
|
||||
"links": []
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"title": "Command Queue",
|
||||
"content": "Source: https://docs.openclaw.ai/concepts/queue",
|
||||
"code_samples": [],
|
||||
"headings": [],
|
||||
"url": "llms-txt#command-queue",
|
||||
"links": []
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"title": "Compaction",
|
||||
"content": "Source: https://docs.openclaw.ai/concepts/compaction",
|
||||
"code_samples": [],
|
||||
"headings": [],
|
||||
"url": "llms-txt#compaction",
|
||||
"links": []
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"title": "Configuration",
|
||||
"content": "Source: https://docs.openclaw.ai/gateway/configuration",
|
||||
"code_samples": [],
|
||||
"headings": [],
|
||||
"url": "llms-txt#configuration",
|
||||
"links": []
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
{
|
||||
"title": "Configuration Examples",
|
||||
"content": "Examples below are aligned with the current config schema. For the exhaustive reference and per-field notes, see [Configuration](/gateway/configuration).\n\nSave to `~/.openclaw/openclaw.json` and you can DM the bot from that number.\n\n### Recommended starter\n\n## Expanded example (major options)\n\n> JSON5 lets you use comments and trailing commas. Regular JSON works too.\n\n### Multi-platform setup\n\n### Secure DM mode (shared inbox / multi-user DMs)\n\nIf more than one person can DM your bot (multiple entries in `allowFrom`, pairing approvals for multiple people, or `dmPolicy: \"open\"`), enable **secure DM mode** so DMs from different senders don’t share one context by default:\n\n### OAuth with API key failover\n\n### Anthropic subscription + API key, MiniMax fallback\n\n### Work bot (restricted access)\n\n### Local models only\n\n* If you set `dmPolicy: \"open\"`, the matching `allowFrom` list must include `\"*\"`.\n* Provider IDs differ (phone numbers, user IDs, channel IDs). Use the provider docs to confirm the format.\n* Optional sections to add later: `web`, `browser`, `ui`, `discovery`, `canvasHost`, `talk`, `signal`, `imessage`.\n* See [Providers](/channels/whatsapp) and [Troubleshooting](/gateway/troubleshooting) for deeper setup notes.",
|
||||
"code_samples": [
|
||||
{
|
||||
"code": "Save to `~/.openclaw/openclaw.json` and you can DM the bot from that number.\n\n### Recommended starter",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "## Expanded example (major options)\n\n> JSON5 lets you use comments and trailing commas. Regular JSON works too.",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "## Common patterns\n\n### Multi-platform setup",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "### Secure DM mode (shared inbox / multi-user DMs)\n\nIf more than one person can DM your bot (multiple entries in `allowFrom`, pairing approvals for multiple people, or `dmPolicy: \"open\"`), enable **secure DM mode** so DMs from different senders don’t share one context by default:",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "### OAuth with API key failover",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "### Anthropic subscription + API key, MiniMax fallback",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "### Work bot (restricted access)",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "### Local models only",
|
||||
"language": "unknown"
|
||||
}
|
||||
],
|
||||
"headings": [
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Quick start",
|
||||
"id": "quick-start"
|
||||
},
|
||||
{
|
||||
"level": "h3",
|
||||
"text": "Absolute minimum",
|
||||
"id": "absolute-minimum"
|
||||
},
|
||||
{
|
||||
"level": "h3",
|
||||
"text": "Recommended starter",
|
||||
"id": "recommended-starter"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Expanded example (major options)",
|
||||
"id": "expanded-example-(major-options)"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Common patterns",
|
||||
"id": "common-patterns"
|
||||
},
|
||||
{
|
||||
"level": "h3",
|
||||
"text": "Multi-platform setup",
|
||||
"id": "multi-platform-setup"
|
||||
},
|
||||
{
|
||||
"level": "h3",
|
||||
"text": "Secure DM mode (shared inbox / multi-user DMs)",
|
||||
"id": "secure-dm-mode-(shared-inbox-/-multi-user-dms)"
|
||||
},
|
||||
{
|
||||
"level": "h3",
|
||||
"text": "OAuth with API key failover",
|
||||
"id": "oauth-with-api-key-failover"
|
||||
},
|
||||
{
|
||||
"level": "h3",
|
||||
"text": "Anthropic subscription + API key, MiniMax fallback",
|
||||
"id": "anthropic-subscription-+-api-key,-minimax-fallback"
|
||||
},
|
||||
{
|
||||
"level": "h3",
|
||||
"text": "Work bot (restricted access)",
|
||||
"id": "work-bot-(restricted-access)"
|
||||
},
|
||||
{
|
||||
"level": "h3",
|
||||
"text": "Local models only",
|
||||
"id": "local-models-only"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Tips",
|
||||
"id": "tips"
|
||||
}
|
||||
],
|
||||
"url": "llms-txt#configuration-examples",
|
||||
"links": []
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,49 @@
|
||||
{
|
||||
"title": "Context Window & Compaction",
|
||||
"content": "Every model has a **context window** (max tokens it can see). Long-running chats accumulate messages and tool results; once the window is tight, OpenClaw **compacts** older history to stay within limits.\n\n## What compaction is\n\nCompaction **summarizes older conversation** into a compact summary entry and keeps recent messages intact. The summary is stored in the session history, so future requests use:\n\n* The compaction summary\n* Recent messages after the compaction point\n\nCompaction **persists** in the session’s JSONL history.\n\nSee [Compaction config & modes](/concepts/compaction) for the `agents.defaults.compaction` settings.\n\n## Auto-compaction (default on)\n\nWhen a session nears or exceeds the model’s context window, OpenClaw triggers auto-compaction and may retry the original request using the compacted context.\n\n* `🧹 Auto-compaction complete` in verbose mode\n* `/status` showing `🧹 Compactions: <count>`\n\nBefore compaction, OpenClaw can run a **silent memory flush** turn to store\ndurable notes to disk. See [Memory](/concepts/memory) for details and config.\n\nUse `/compact` (optionally with instructions) to force a compaction pass:\n\n## Context window source\n\nContext window is model-specific. OpenClaw uses the model definition from the configured provider catalog to determine limits.\n\n## Compaction vs pruning\n\n* **Compaction**: summarises and **persists** in JSONL.\n* **Session pruning**: trims old **tool results** only, **in-memory**, per request.\n\nSee [/concepts/session-pruning](/concepts/session-pruning) for pruning details.\n\n* Use `/compact` when sessions feel stale or context is bloated.\n* Large tool outputs are already truncated; pruning can further reduce tool-result buildup.\n* If you need a fresh slate, `/new` or `/reset` starts a new session id.",
|
||||
"code_samples": [
|
||||
{
|
||||
"code": "/compact Focus on decisions and open questions",
|
||||
"language": "unknown"
|
||||
}
|
||||
],
|
||||
"headings": [
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "What compaction is",
|
||||
"id": "what-compaction-is"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Configuration",
|
||||
"id": "configuration"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Auto-compaction (default on)",
|
||||
"id": "auto-compaction-(default-on)"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Manual compaction",
|
||||
"id": "manual-compaction"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Context window source",
|
||||
"id": "context-window-source"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Compaction vs pruning",
|
||||
"id": "compaction-vs-pruning"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Tips",
|
||||
"id": "tips"
|
||||
}
|
||||
],
|
||||
"url": "llms-txt#context-window-&-compaction",
|
||||
"links": []
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"title": "Control UI",
|
||||
"content": "Source: https://docs.openclaw.ai/web/control-ui",
|
||||
"code_samples": [],
|
||||
"headings": [],
|
||||
"url": "llms-txt#control-ui",
|
||||
"links": []
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"title": "Control UI (browser)",
|
||||
"content": "The Control UI is a small **Vite + Lit** single-page app served by the Gateway:\n\n* default: `http://<host>:18789/`\n* optional prefix: set `gateway.controlUi.basePath` (e.g. `/openclaw`)\n\nIt speaks **directly to the Gateway WebSocket** on the same port.\n\n## Quick open (local)\n\nIf the Gateway is running on the same computer, open:\n\n* [http://127.0.0.1:18789/](http://127.0.0.1:18789/) (or [http://localhost:18789/](http://localhost:18789/))\n\nIf the page fails to load, start the Gateway first: `openclaw gateway`.\n\nAuth is supplied during the WebSocket handshake via:\n\n* `connect.params.auth.token`\n* `connect.params.auth.password`\n The dashboard settings panel lets you store a token; passwords are not persisted.\n The onboarding wizard generates a gateway token by default, so paste it here on first connect.\n\n## Device pairing (first connection)\n\nWhen you connect to the Control UI from a new browser or device, the Gateway\nrequires a **one-time pairing approval** — even if you're on the same Tailnet\nwith `gateway.auth.allowTailscale: true`. This is a security measure to prevent\nunauthorized access.\n\n**What you'll see:** \"disconnected (1008): pairing required\"\n\n**To approve the device:**",
|
||||
"code_samples": [],
|
||||
"headings": [
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Quick open (local)",
|
||||
"id": "quick-open-(local)"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Device pairing (first connection)",
|
||||
"id": "device-pairing-(first-connection)"
|
||||
}
|
||||
],
|
||||
"url": "llms-txt#control-ui-(browser)",
|
||||
"links": []
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"title": "Copy the https URL, e.g., https://abc123.ngrok.io",
|
||||
"content": "",
|
||||
"code_samples": [],
|
||||
"headings": [],
|
||||
"url": "llms-txt#copy-the-https-url,-e.g.,-https://abc123.ngrok.io",
|
||||
"links": []
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"title": "Create WireGuard config (one-time)",
|
||||
"content": "",
|
||||
"code_samples": [],
|
||||
"headings": [],
|
||||
"url": "llms-txt#create-wireguard-config-(one-time)",
|
||||
"links": []
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"title": "Create a new Fly app (pick your own name)",
|
||||
"content": "fly apps create my-openclaw",
|
||||
"code_samples": [],
|
||||
"headings": [],
|
||||
"url": "llms-txt#create-a-new-fly-app-(pick-your-own-name)",
|
||||
"links": []
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
{
|
||||
"title": "Create a persistent volume (1GB is usually enough)",
|
||||
"content": "fly volumes create openclaw_data --size 1 --region iad\ntoml theme={null}\napp = \"my-openclaw\" # Your app name\nprimary_region = \"iad\"\n\n[build]\n dockerfile = \"Dockerfile\"\n\n[env]\n NODE_ENV = \"production\"\n OPENCLAW_PREFER_PNPM = \"1\"\n OPENCLAW_STATE_DIR = \"/data\"\n NODE_OPTIONS = \"--max-old-space-size=1536\"\n\n[processes]\n app = \"node dist/index.js gateway --allow-unconfigured --port 3000 --bind lan\"\n\n[http_service]\n internal_port = 3000\n force_https = true\n auto_stop_machines = false\n auto_start_machines = true\n min_machines_running = 1\n processes = [\"app\"]\n\n[[vm]]\n size = \"shared-cpu-2x\"\n memory = \"2048mb\"\n\n[mounts]\n source = \"openclaw_data\"\n destination = \"/data\"\nbash theme={null}",
|
||||
"code_samples": [
|
||||
{
|
||||
"code": "**Tip:** Choose a region close to you. Common options: `lhr` (London), `iad` (Virginia), `sjc` (San Jose).\n\n## 2) Configure fly.toml\n\nEdit `fly.toml` to match your app name and requirements.\n\n**Security note:** The default config exposes a public URL. For a hardened deployment with no public IP, see [Private Deployment](#private-deployment-hardened) or use `fly.private.toml`.",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "**Key settings:**\n\n| Setting | Why |\n| ------------------------------ | --------------------------------------------------------------------------- |\n| `--bind lan` | Binds to `0.0.0.0` so Fly's proxy can reach the gateway |\n| `--allow-unconfigured` | Starts without a config file (you'll create one after) |\n| `internal_port = 3000` | Must match `--port 3000` (or `OPENCLAW_GATEWAY_PORT`) for Fly health checks |\n| `memory = \"2048mb\"` | 512MB is too small; 2GB recommended |\n| `OPENCLAW_STATE_DIR = \"/data\"` | Persists state on the volume |\n\n## 3) Set secrets",
|
||||
"language": "unknown"
|
||||
}
|
||||
],
|
||||
"headings": [
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "2) Configure fly.toml",
|
||||
"id": "2)-configure-fly.toml"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "3) Set secrets",
|
||||
"id": "3)-set-secrets"
|
||||
}
|
||||
],
|
||||
"url": "llms-txt#create-a-persistent-volume-(1gb-is-usually-enough)",
|
||||
"links": []
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"title": "Credits",
|
||||
"content": "Source: https://docs.openclaw.ai/reference/credits\n\nOpenClaw = CLAW + TARDIS, because every space lobster needs a time and space machine.\n\n* **Peter Steinberger** ([@steipete](https://x.com/steipete)) - Creator, lobster whisperer\n* **Mario Zechner** ([@badlogicc](https://x.com/badlogicgames)) - Pi creator, security pen tester\n* **Clawd** - The space lobster who demanded a better name\n\n* **Maxim Vovshin** (@Hyaxia, [36747317+Hyaxia@users.noreply.github.com](mailto:36747317+Hyaxia@users.noreply.github.com)) - Blogwatcher skill\n* **Nacho Iacovino** (@nachoiacovino, [nacho.iacovino@gmail.com](mailto:nacho.iacovino@gmail.com)) - Location parsing (Telegram and WhatsApp)\n\nMIT - Free as a lobster in the ocean.\n\n> \"We are all just playing with our own prompts.\" (An AI, probably high on tokens)",
|
||||
"code_samples": [],
|
||||
"headings": [
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "The name",
|
||||
"id": "the-name"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Credits",
|
||||
"id": "credits"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Core contributors",
|
||||
"id": "core-contributors"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "License",
|
||||
"id": "license"
|
||||
}
|
||||
],
|
||||
"url": "llms-txt#credits",
|
||||
"links": []
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"title": "Cron Jobs",
|
||||
"content": "Source: https://docs.openclaw.ai/automation/cron-jobs",
|
||||
"code_samples": [],
|
||||
"headings": [],
|
||||
"url": "llms-txt#cron-jobs",
|
||||
"links": []
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"title": "Cron vs Heartbeat",
|
||||
"content": "Source: https://docs.openclaw.ai/automation/cron-vs-heartbeat",
|
||||
"code_samples": [],
|
||||
"headings": [],
|
||||
"url": "llms-txt#cron-vs-heartbeat",
|
||||
"links": []
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
{
|
||||
"title": "Cron vs Heartbeat: When to Use Each",
|
||||
"content": "Both heartbeats and cron jobs let you run tasks on a schedule. This guide helps you choose the right mechanism for your use case.\n\n## Quick Decision Guide\n\n| Use Case | Recommended | Why |\n| ------------------------------------ | ------------------- | ---------------------------------------- |\n| Check inbox every 30 min | Heartbeat | Batches with other checks, context-aware |\n| Send daily report at 9am sharp | Cron (isolated) | Exact timing needed |\n| Monitor calendar for upcoming events | Heartbeat | Natural fit for periodic awareness |\n| Run weekly deep analysis | Cron (isolated) | Standalone task, can use different model |\n| Remind me in 20 minutes | Cron (main, `--at`) | One-shot with precise timing |\n| Background project health check | Heartbeat | Piggybacks on existing cycle |\n\n## Heartbeat: Periodic Awareness\n\nHeartbeats run in the **main session** at a regular interval (default: 30 min). They're designed for the agent to check on things and surface anything important.\n\n### When to use heartbeat\n\n* **Multiple periodic checks**: Instead of 5 separate cron jobs checking inbox, calendar, weather, notifications, and project status, a single heartbeat can batch all of these.\n* **Context-aware decisions**: The agent has full main-session context, so it can make smart decisions about what's urgent vs. what can wait.\n* **Conversational continuity**: Heartbeat runs share the same session, so the agent remembers recent conversations and can follow up naturally.\n* **Low-overhead monitoring**: One heartbeat replaces many small polling tasks.\n\n### Heartbeat advantages\n\n* **Batches multiple checks**: One agent turn can review inbox, calendar, and notifications together.\n* **Reduces API calls**: A single heartbeat is cheaper than 5 isolated cron jobs.\n* **Context-aware**: The agent knows what you've been working on and can prioritize accordingly.\n* **Smart suppression**: If nothing needs attention, the agent replies `HEARTBEAT_OK` and no message is delivered.\n* **Natural timing**: Drifts slightly based on queue load, which is fine for most monitoring.\n\n### Heartbeat example: HEARTBEAT.md checklist",
|
||||
"code_samples": [],
|
||||
"headings": [
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Quick Decision Guide",
|
||||
"id": "quick-decision-guide"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Heartbeat: Periodic Awareness",
|
||||
"id": "heartbeat:-periodic-awareness"
|
||||
},
|
||||
{
|
||||
"level": "h3",
|
||||
"text": "When to use heartbeat",
|
||||
"id": "when-to-use-heartbeat"
|
||||
},
|
||||
{
|
||||
"level": "h3",
|
||||
"text": "Heartbeat advantages",
|
||||
"id": "heartbeat-advantages"
|
||||
},
|
||||
{
|
||||
"level": "h3",
|
||||
"text": "Heartbeat example: HEARTBEAT.md checklist",
|
||||
"id": "heartbeat-example:-heartbeat.md-checklist"
|
||||
}
|
||||
],
|
||||
"url": "llms-txt#cron-vs-heartbeat:-when-to-use-each",
|
||||
"links": []
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"title": "Daily morning briefing at 7am",
|
||||
"content": "openclaw cron add --name \"Morning brief\" --cron \"0 7 * * *\" --session isolated --message \"...\" --announce",
|
||||
"code_samples": [],
|
||||
"headings": [],
|
||||
"url": "llms-txt#daily-morning-briefing-at-7am",
|
||||
"links": []
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"title": "Dashboard (Control UI)",
|
||||
"content": "The Gateway dashboard is the browser Control UI served at `/` by default\n(override with `gateway.controlUi.basePath`).\n\nQuick open (local Gateway):\n\n* [http://127.0.0.1:18789/](http://127.0.0.1:18789/) (or [http://localhost:18789/](http://localhost:18789/))\n\n* [Control UI](/web/control-ui) for usage and UI capabilities.\n* [Tailscale](/gateway/tailscale) for Serve/Funnel automation.\n* [Web surfaces](/web) for bind modes and security notes.\n\nAuthentication is enforced at the WebSocket handshake via `connect.params.auth`\n(token or password). See `gateway.auth` in [Gateway configuration](/gateway/configuration).\n\nSecurity note: the Control UI is an **admin surface** (chat, config, exec approvals).\nDo not expose it publicly. The UI stores the token in `localStorage` after first load.\nPrefer localhost, Tailscale Serve, or an SSH tunnel.\n\n## Fast path (recommended)\n\n* After onboarding, the CLI now auto-opens the dashboard with your token and prints the same tokenized link.\n* Re-open anytime: `openclaw dashboard` (copies link, opens browser if possible, shows SSH hint if headless).\n* The token stays local (query param only); the UI strips it after first load and saves it in localStorage.\n\n## Token basics (local vs remote)\n\n* **Localhost**: open `http://127.0.0.1:18789/`. If you see “unauthorized,” run `openclaw dashboard` and use the tokenized link (`?token=...`).\n* **Token source**: `gateway.auth.token` (or `OPENCLAW_GATEWAY_TOKEN`); the UI stores it after first load.\n* **Not localhost**: use Tailscale Serve (tokenless if `gateway.auth.allowTailscale: true`), tailnet bind with a token, or an SSH tunnel. See [Web surfaces](/web).\n\n## If you see “unauthorized” / 1008\n\n* Run `openclaw dashboard` to get a fresh tokenized link.\n* Ensure the gateway is reachable (local: `openclaw status`; remote: SSH tunnel `ssh -N -L 18789:127.0.0.1:18789 user@host` then open `http://127.0.0.1:18789/?token=...`).\n* In the dashboard settings, paste the same token you configured in `gateway.auth.token` (or `OPENCLAW_GATEWAY_TOKEN`).",
|
||||
"code_samples": [],
|
||||
"headings": [
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Fast path (recommended)",
|
||||
"id": "fast-path-(recommended)"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Token basics (local vs remote)",
|
||||
"id": "token-basics-(local-vs-remote)"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "If you see “unauthorized” / 1008",
|
||||
"id": "if-you-see-“unauthorized”-/-1008"
|
||||
}
|
||||
],
|
||||
"url": "llms-txt#dashboard-(control-ui)",
|
||||
"links": []
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
{
|
||||
"title": "Debugging",
|
||||
"content": "This page covers debugging helpers for streaming output, especially when a\nprovider mixes reasoning into normal text.\n\n## Runtime debug overrides\n\nUse `/debug` in chat to set **runtime-only** config overrides (memory, not disk).\n`/debug` is disabled by default; enable with `commands.debug: true`.\nThis is handy when you need to toggle obscure settings without editing `openclaw.json`.\n\n`/debug reset` clears all overrides and returns to the on-disk config.\n\n## Gateway watch mode\n\nFor fast iteration, run the gateway under the file watcher:\n\nAdd any gateway CLI flags after `gateway:watch` and they will be passed through\non each restart.\n\n## Dev profile + dev gateway (--dev)\n\nUse the dev profile to isolate state and spin up a safe, disposable setup for\ndebugging. There are **two** `--dev` flags:\n\n* **Global `--dev` (profile):** isolates state under `~/.openclaw-dev` and\n defaults the gateway port to `19001` (derived ports shift with it).\n* **`gateway --dev`: tells the Gateway to auto-create a default config +\n workspace** when missing (and skip BOOTSTRAP.md).\n\nRecommended flow (dev profile + dev bootstrap):\n\nIf you don’t have a global install yet, run the CLI via `pnpm openclaw ...`.\n\n1. **Profile isolation** (global `--dev`)\n * `OPENCLAW_PROFILE=dev`\n * `OPENCLAW_STATE_DIR=~/.openclaw-dev`\n * `OPENCLAW_CONFIG_PATH=~/.openclaw-dev/openclaw.json`\n * `OPENCLAW_GATEWAY_PORT=19001` (browser/canvas shift accordingly)\n\n2. **Dev bootstrap** (`gateway --dev`)\n * Writes a minimal config if missing (`gateway.mode=local`, bind loopback).\n * Sets `agent.workspace` to the dev workspace.\n * Sets `agent.skipBootstrap=true` (no BOOTSTRAP.md).\n * Seeds the workspace files if missing:\n `AGENTS.md`, `SOUL.md`, `TOOLS.md`, `IDENTITY.md`, `USER.md`, `HEARTBEAT.md`.\n * Default identity: **C3‑PO** (protocol droid).\n * Skips channel providers in dev mode (`OPENCLAW_SKIP_CHANNELS=1`).\n\nReset flow (fresh start):\n\nNote: `--dev` is a **global** profile flag and gets eaten by some runners.\nIf you need to spell it out, use the env var form:\n\n`--reset` wipes config, credentials, sessions, and the dev workspace (using\n`trash`, not `rm`), then recreates the default dev setup.\n\nTip: if a non‑dev gateway is already running (launchd/systemd), stop it first:\n\n## Raw stream logging (OpenClaw)\n\nOpenClaw can log the **raw assistant stream** before any filtering/formatting.\nThis is the best way to see whether reasoning is arriving as plain text deltas\n(or as separate thinking blocks).\n\nOptional path override:\n\n`~/.openclaw/logs/raw-stream.jsonl`\n\n## Raw chunk logging (pi-mono)\n\nTo capture **raw OpenAI-compat chunks** before they are parsed into blocks,\npi-mono exposes a separate logger:\n\n`~/.pi-mono/logs/raw-openai-completions.jsonl`\n\n> Note: this is only emitted by processes using pi-mono’s\n> `openai-completions` provider.\n\n* Raw stream logs can include full prompts, tool output, and user data.\n* Keep logs local and delete them after debugging.\n* If you share logs, scrub secrets and PII first.",
|
||||
"code_samples": [
|
||||
{
|
||||
"code": "/debug show\n/debug set messages.responsePrefix=\"[openclaw]\"\n/debug unset messages.responsePrefix\n/debug reset",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "This maps to:",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "Add any gateway CLI flags after `gateway:watch` and they will be passed through\non each restart.\n\n## Dev profile + dev gateway (--dev)\n\nUse the dev profile to isolate state and spin up a safe, disposable setup for\ndebugging. There are **two** `--dev` flags:\n\n* **Global `--dev` (profile):** isolates state under `~/.openclaw-dev` and\n defaults the gateway port to `19001` (derived ports shift with it).\n* **`gateway --dev`: tells the Gateway to auto-create a default config +\n workspace** when missing (and skip BOOTSTRAP.md).\n\nRecommended flow (dev profile + dev bootstrap):",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "If you don’t have a global install yet, run the CLI via `pnpm openclaw ...`.\n\nWhat this does:\n\n1. **Profile isolation** (global `--dev`)\n * `OPENCLAW_PROFILE=dev`\n * `OPENCLAW_STATE_DIR=~/.openclaw-dev`\n * `OPENCLAW_CONFIG_PATH=~/.openclaw-dev/openclaw.json`\n * `OPENCLAW_GATEWAY_PORT=19001` (browser/canvas shift accordingly)\n\n2. **Dev bootstrap** (`gateway --dev`)\n * Writes a minimal config if missing (`gateway.mode=local`, bind loopback).\n * Sets `agent.workspace` to the dev workspace.\n * Sets `agent.skipBootstrap=true` (no BOOTSTRAP.md).\n * Seeds the workspace files if missing:\n `AGENTS.md`, `SOUL.md`, `TOOLS.md`, `IDENTITY.md`, `USER.md`, `HEARTBEAT.md`.\n * Default identity: **C3‑PO** (protocol droid).\n * Skips channel providers in dev mode (`OPENCLAW_SKIP_CHANNELS=1`).\n\nReset flow (fresh start):",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "Note: `--dev` is a **global** profile flag and gets eaten by some runners.\nIf you need to spell it out, use the env var form:",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "`--reset` wipes config, credentials, sessions, and the dev workspace (using\n`trash`, not `rm`), then recreates the default dev setup.\n\nTip: if a non‑dev gateway is already running (launchd/systemd), stop it first:",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "## Raw stream logging (OpenClaw)\n\nOpenClaw can log the **raw assistant stream** before any filtering/formatting.\nThis is the best way to see whether reasoning is arriving as plain text deltas\n(or as separate thinking blocks).\n\nEnable it via CLI:",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "Optional path override:",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "Equivalent env vars:",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "Default file:\n\n`~/.openclaw/logs/raw-stream.jsonl`\n\n## Raw chunk logging (pi-mono)\n\nTo capture **raw OpenAI-compat chunks** before they are parsed into blocks,\npi-mono exposes a separate logger:",
|
||||
"language": "unknown"
|
||||
},
|
||||
{
|
||||
"code": "Optional path:",
|
||||
"language": "unknown"
|
||||
}
|
||||
],
|
||||
"headings": [
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Runtime debug overrides",
|
||||
"id": "runtime-debug-overrides"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Gateway watch mode",
|
||||
"id": "gateway-watch-mode"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Dev profile + dev gateway (--dev)",
|
||||
"id": "dev-profile-+-dev-gateway-(--dev)"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Raw stream logging (OpenClaw)",
|
||||
"id": "raw-stream-logging-(openclaw)"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Raw chunk logging (pi-mono)",
|
||||
"id": "raw-chunk-logging-(pi-mono)"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Safety notes",
|
||||
"id": "safety-notes"
|
||||
}
|
||||
],
|
||||
"url": "llms-txt#debugging",
|
||||
"links": []
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"title": "Defaults to the configured default agent (omit --agent)",
|
||||
"content": "openclaw models auth order get --provider anthropic",
|
||||
"code_samples": [],
|
||||
"headings": [],
|
||||
"url": "llms-txt#defaults-to-the-configured-default-agent-(omit---agent)",
|
||||
"links": []
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
{
|
||||
"title": "Deploy on Northflank",
|
||||
"content": "Source: https://docs.openclaw.ai/northflank\n\nDeploy OpenClaw on Northflank with a one-click template and finish setup in your browser.\nThis is the easiest “no terminal on the server” path: Northflank runs the Gateway for you,\nand you configure everything via the `/setup` web wizard.\n\n## How to get started\n\n1. Click [Deploy OpenClaw](https://northflank.com/stacks/deploy-openclaw) to open the template.\n2. Create an [account on Northflank](https://app.northflank.com/signup) if you don’t already have one.\n3. Click **Deploy OpenClaw now**.\n4. Set the required environment variable: `SETUP_PASSWORD`.\n5. Click **Deploy stack** to build and run the OpenClaw template.\n6. Wait for the deployment to complete, then click **View resources**.\n7. Open the OpenClaw service.\n8. Open the public OpenClaw URL and complete setup at `/setup`.\n9. Open the Control UI at `/openclaw`.\n\n* Hosted OpenClaw Gateway + Control UI\n* Web setup wizard at `/setup` (no terminal commands)\n* Persistent storage via Northflank Volume (`/data`) so config/credentials/workspace survive redeploys\n\n1. Visit `https://<your-northflank-domain>/setup` and enter your `SETUP_PASSWORD`.\n2. Choose a model/auth provider and paste your key.\n3. (Optional) Add Telegram/Discord/Slack tokens.\n4. Click **Run setup**.\n5. Open the Control UI at `https://<your-northflank-domain>/openclaw`\n\nIf Telegram DMs are set to pairing, the setup wizard can approve the pairing code.\n\n## Getting chat tokens\n\n### Telegram bot token\n\n1. Message `@BotFather` in Telegram\n2. Run `/newbot`\n3. Copy the token (looks like `123456789:AA...`)\n4. Paste it into `/setup`\n\n### Discord bot token\n\n1. Go to [https://discord.com/developers/applications](https://discord.com/developers/applications)\n2. **New Application** → choose a name\n3. **Bot** → **Add Bot**\n4. **Enable MESSAGE CONTENT INTENT** under Bot → Privileged Gateway Intents (required or the bot will crash on startup)\n5. Copy the **Bot Token** and paste into `/setup`\n6. Invite the bot to your server (OAuth2 URL Generator; scopes: `bot`, `applications.commands`)",
|
||||
"code_samples": [],
|
||||
"headings": [
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "How to get started",
|
||||
"id": "how-to-get-started"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "What you get",
|
||||
"id": "what-you-get"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Setup flow",
|
||||
"id": "setup-flow"
|
||||
},
|
||||
{
|
||||
"level": "h2",
|
||||
"text": "Getting chat tokens",
|
||||
"id": "getting-chat-tokens"
|
||||
},
|
||||
{
|
||||
"level": "h3",
|
||||
"text": "Telegram bot token",
|
||||
"id": "telegram-bot-token"
|
||||
},
|
||||
{
|
||||
"level": "h3",
|
||||
"text": "Discord bot token",
|
||||
"id": "discord-bot-token"
|
||||
}
|
||||
],
|
||||
"url": "llms-txt#deploy-on-northflank",
|
||||
"links": []
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user