chore: Run pnpm format:fix.

This commit is contained in:
cpojer
2026-01-31 21:13:13 +09:00
parent dcc2de15a6
commit 8cab78abbc
624 changed files with 10729 additions and 7514 deletions

View File

@@ -3,6 +3,7 @@ summary: "Direct `openclaw agent` CLI runs (with optional delivery)"
read_when:
- Adding or modifying the agent CLI entrypoint
---
# `openclaw agent` (direct agent runs)
`openclaw agent` runs a single agent turn without needing an inbound chat message.

View File

@@ -8,6 +8,7 @@ read_when: "Browser control fails on Linux, especially with snap Chromium"
## Problem: "Failed to start Chrome CDP on port 18800"
OpenClaw's browser control server fails to launch Chrome/Brave/Edge/Chromium with the error:
```
{"error":"Error: Failed to start Chrome CDP on port 18800 for profile \"openclaw\"."}
```
@@ -17,6 +18,7 @@ OpenClaw's browser control server fails to launch Chrome/Brave/Edge/Chromium wit
On 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.
The `apt install chromium` command installs a stub package that redirects to snap:
```
Note, selecting 'chromium-browser' instead of 'chromium'
chromium-browser is already the newest version (2:1snap1-0ubuntu2).
@@ -52,6 +54,7 @@ Then update your OpenClaw config (`~/.openclaw/openclaw.json`):
If you must use snap Chromium, configure OpenClaw to attach to a manually-started browser:
1. Update config:
```json
{
"browser": {
@@ -64,6 +67,7 @@ If you must use snap Chromium, configure OpenClaw to attach to a manually-starte
```
2. Start Chromium manually:
```bash
chromium-browser --headless --no-sandbox --disable-gpu \
--remote-debugging-port=18800 \
@@ -72,6 +76,7 @@ chromium-browser --headless --no-sandbox --disable-gpu \
```
3. Optionally create a systemd user service to auto-start Chrome:
```ini
# ~/.config/systemd/user/openclaw-browser.service
[Unit]
@@ -92,11 +97,13 @@ Enable with: `systemctl --user enable --now openclaw-browser.service`
### Verifying the Browser Works
Check status:
```bash
curl -s http://127.0.0.1:18791/ | jq '{running, pid, chosenBrowser}'
```
Test browsing:
```bash
curl -s -X POST http://127.0.0.1:18791/start
curl -s http://127.0.0.1:18791/tabs
@@ -104,14 +111,14 @@ curl -s http://127.0.0.1:18791/tabs
### Config Reference
| Option | Description | Default |
|--------|-------------|---------|
| `browser.enabled` | Enable browser control | `true` |
| Option | Description | Default |
| ------------------------ | -------------------------------------------------------------------- | ----------------------------------------------------------- |
| `browser.enabled` | Enable browser control | `true` |
| `browser.executablePath` | Path to a Chromium-based browser binary (Chrome/Brave/Edge/Chromium) | auto-detected (prefers default browser when Chromium-based) |
| `browser.headless` | Run without GUI | `false` |
| `browser.noSandbox` | Add `--no-sandbox` flag (needed for some Linux setups) | `false` |
| `browser.attachOnly` | Don't launch browser, only attach to existing | `false` |
| `browser.cdpPort` | Chrome DevTools Protocol port | `18800` |
| `browser.headless` | Run without GUI | `false` |
| `browser.noSandbox` | Add `--no-sandbox` flag (needed for some Linux setups) | `false` |
| `browser.attachOnly` | Don't launch browser, only attach to existing | `false` |
| `browser.cdpPort` | Chrome DevTools Protocol port | `18800` |
### Problem: "Chrome extension relay is running, but no tab is connected"
@@ -119,11 +126,13 @@ Youre using the `chrome` profile (extension relay). It expects the OpenClaw
browser extension to be attached to a live tab.
Fix options:
1. **Use the managed browser:** `openclaw browser start --browser-profile openclaw`
(or set `browser.defaultProfile: "openclaw"`).
2. **Use the extension relay:** install the extension, open a tab, and click the
OpenClaw extension icon to attach it.
Notes:
- The `chrome` profile uses your **system default Chromium browser** when possible.
- Local `openclaw` profiles auto-assign `cdpPort`/`cdpUrl`; only set those for remote CDP.

View File

@@ -21,8 +21,8 @@ OpenClaw controls a **dedicated Chrome profile** (named `openclaw`, orangetin
Two easy ways to access it:
1) **Ask the agent to open the browser** and then log in yourself.
2) **Open it via CLI**:
1. **Ask the agent to open the browser** and then log in yourself.
2. **Open it via CLI**:
```bash
openclaw browser start
@@ -50,11 +50,11 @@ If the agent is sandboxed, the browser tool defaults to the sandbox. To allow ho
sandbox: {
mode: "non-main",
browser: {
allowHostControl: true
}
}
}
}
allowHostControl: true,
},
},
},
},
}
```

View File

@@ -13,6 +13,7 @@ It is isolated from your personal browser and is managed through a small local
control service inside the Gateway (loopback only).
Beginner view:
- Think of it as a **separate, agent-only browser**.
- The `openclaw` profile does **not** touch your personal browser profile.
- The agent can **open tabs, read pages, click, and type** in a safe lane.
@@ -56,9 +57,9 @@ Browser settings live in `~/.openclaw/openclaw.json`.
```json5
{
browser: {
enabled: true, // default: true
enabled: true, // default: true
// cdpUrl: "http://127.0.0.1:18792", // legacy single-profile override
remoteCdpTimeoutMs: 1500, // remote CDP HTTP timeout (ms)
remoteCdpTimeoutMs: 1500, // remote CDP HTTP timeout (ms)
remoteCdpHandshakeTimeoutMs: 3000, // remote CDP WebSocket handshake timeout (ms)
defaultProfile: "chrome",
color: "#FF4500",
@@ -69,13 +70,14 @@ Browser settings live in `~/.openclaw/openclaw.json`.
profiles: {
openclaw: { cdpPort: 18800, color: "#FF4500" },
work: { cdpPort: 18801, color: "#0066CC" },
remote: { cdpUrl: "http://10.0.0.42:9222", color: "#00AA00" }
}
}
remote: { cdpUrl: "http://10.0.0.42:9222", color: "#00AA00" },
},
},
}
```
Notes:
- The browser control service binds to loopback on a port derived from `gateway.port`
(default: `18791`, which is gateway + 2). The relay uses the next port (`18792`).
- If you override the Gateway port (`gateway.port` or `OPENCLAW_GATEWAY_PORT`),
@@ -132,6 +134,7 @@ openclaw config set browser.executablePath "/usr/bin/google-chrome"
attach to a remote Chromium-based browser. In this case, OpenClaw will not launch a local browser.
Remote CDP URLs can include auth:
- Query tokens (e.g., `https://provider.example?token=<token>`)
- HTTP Basic auth (e.g., `https://user:pass@provider.example`)
@@ -146,6 +149,7 @@ auto-route browser tool calls to that node without any extra browser config.
This is the default path for remote gateways.
Notes:
- The node host exposes its local browser control server via a **proxy command**.
- Profiles come from the nodes own `browser.profiles` config (same as local).
- Disable if you dont want it:
@@ -159,6 +163,7 @@ CDP endpoints over HTTPS. You can point a OpenClaw browser profile at a
Browserless region endpoint and authenticate with your API key.
Example:
```json5
{
browser: {
@@ -169,36 +174,41 @@ Example:
profiles: {
browserless: {
cdpUrl: "https://production-sfo.browserless.io?token=<BROWSERLESS_API_KEY>",
color: "#00AA00"
}
}
}
color: "#00AA00",
},
},
},
}
```
Notes:
- Replace `<BROWSERLESS_API_KEY>` with your real Browserless token.
- Choose the region endpoint that matches your Browserless account (see their docs).
## Security
Key ideas:
- Browser control is loopback-only; access flows through the Gateways auth or node pairing.
- Keep the Gateway and any node hosts on a private network (Tailscale); avoid public exposure.
- Treat remote CDP URLs/tokens as secrets; prefer env vars or a secrets manager.
Remote CDP tips:
- Prefer HTTPS endpoints and short-lived tokens where possible.
- Avoid embedding long-lived tokens directly in config files.
## Profiles (multi-browser)
OpenClaw supports multiple named profiles (routing configs). Profiles can be:
- **openclaw-managed**: a dedicated Chromium-based browser instance with its own user data directory + CDP port
- **remote**: an explicit CDP URL (Chromium-based browser running elsewhere)
- **extension relay**: your existing Chrome tab(s) via the local relay + Chrome extension
Defaults:
- The `openclaw` profile is auto-created if missing.
- The `chrome` profile is built-in for the Chrome extension relay (points at `http://127.0.0.1:18792` by default).
- Local CDP ports allocate from **1880018899** by default.
@@ -213,6 +223,7 @@ OpenClaw can also drive **your existing Chrome tabs** (no separate “openclaw
Full guide: [Chrome extension](/tools/chrome-extension)
Flow:
- The Gateway runs locally (same machine) or a node host runs on the browser machine.
- A local **relay server** listens at a loopback `cdpUrl` (default: `http://127.0.0.1:18792`).
- You click the **OpenClaw Browser Relay** extension icon on a tab to attach (it does not auto-attach).
@@ -224,12 +235,13 @@ If the Gateway runs elsewhere, run a node host on the browser machine so the Gat
If the agent session is sandboxed, the `browser` tool may default to `target="sandbox"` (sandbox browser).
Chrome extension relay takeover requires host browser control, so either:
- run the session unsandboxed, or
- set `agents.defaults.sandbox.browser.allowHostControl: true` and use `target="host"` when calling the tool.
### Setup
1) Load the extension (dev/unpacked):
1. Load the extension (dev/unpacked):
```bash
openclaw browser extension install
@@ -239,7 +251,8 @@ openclaw browser extension install
- “Load unpacked” → select the directory printed by `openclaw browser extension path`
- Pin the extension, then click it on the tab you want to control (badge shows `ON`).
2) Use it:
2. Use it:
- CLI: `openclaw browser --browser-profile chrome tabs`
- Agent tool: `browser` with `profile="chrome"`
@@ -254,6 +267,7 @@ openclaw browser create-profile \
```
Notes:
- This mode relies on Playwright-on-CDP for most operations (screenshots/snapshots/actions).
- Detach by clicking the extension icon again.
@@ -266,6 +280,7 @@ Notes:
## Browser selection
When launching locally, OpenClaw picks the first available:
1. Chrome
2. Brave
3. Edge
@@ -275,6 +290,7 @@ When launching locally, OpenClaw picks the first available:
You can override with `browser.executablePath`.
Platforms:
- macOS: checks `/Applications` and `~/Applications`.
- Linux: looks for `google-chrome`, `brave`, `microsoft-edge`, `chromium`, etc.
- Windows: checks common install locations.
@@ -312,6 +328,7 @@ OpenClaw with browser support.
## How it works (internal)
High-level flow:
- A small **control server** accepts HTTP requests.
- It connects to Chromium-based browsers (Chrome/Brave/Edge/Chromium) via **CDP**.
- For advanced actions (click/type/snapshot/PDF), it uses **Playwright** on top
@@ -327,6 +344,7 @@ All commands accept `--browser-profile <name>` to target a specific profile.
All commands also accept `--json` for machine-readable output (stable payloads).
Basics:
- `openclaw browser status`
- `openclaw browser start`
- `openclaw browser stop`
@@ -340,6 +358,7 @@ Basics:
- `openclaw browser close abcd1234`
Inspection:
- `openclaw browser screenshot`
- `openclaw browser screenshot --full-page`
- `openclaw browser screenshot --ref 12`
@@ -358,6 +377,7 @@ Inspection:
- `openclaw browser responsebody "**/api" --max-chars 5000`
Actions:
- `openclaw browser navigate https://example.com`
- `openclaw browser resize 1280 720`
- `openclaw browser click 12 --double`
@@ -381,6 +401,7 @@ Actions:
- `openclaw browser trace stop`
State:
- `openclaw browser cookies`
- `openclaw browser cookies set session abc123 --url "https://example.com"`
- `openclaw browser cookies clear`
@@ -399,6 +420,7 @@ State:
- `openclaw browser set device "iPhone 14"`
Notes:
- `upload` and `dialog` are **arming** calls; run them before the click/press
that triggers the chooser/dialog.
- `upload` can also set file inputs directly via `--input-ref` or `--element`.
@@ -430,6 +452,7 @@ OpenClaw supports two “snapshot” styles:
- Add `--labels` to include a viewport screenshot with overlayed `e12` labels.
Ref behavior:
- Refs are **not stable across navigations**; if something fails, re-run `snapshot` and use a fresh ref.
- If the role snapshot was taken with `--frame`, role refs are scoped to that iframe until the next role snapshot.
@@ -520,9 +543,11 @@ For Linux-specific issues (especially snap Chromium), see
## Agent tools + how control works
The agent gets **one tool** for browser automation:
- `browser` — status/start/stop/tabs/open/focus/close/snapshot/screenshot/navigate/act
How it maps:
- `browser snapshot` returns a stable UI tree (AI or ARIA).
- `browser act` uses the snapshot `ref` IDs to click/type/drag/select.
- `browser screenshot` captures pixels (full page or element).

View File

@@ -15,6 +15,7 @@ Attach/detach happens via a **single Chrome toolbar button**.
## What it is (concept)
There are three parts:
- **Browser control service** (Gateway or node): the API the agent/tool calls (via the Gateway)
- **Local relay server** (loopback CDP): bridges between the control server and the extension (`http://127.0.0.1:18792` by default)
- **Chrome MV3 extension**: attaches to the active tab using `chrome.debugger` and pipes CDP messages to the relay
@@ -23,29 +24,31 @@ OpenClaw then controls the attached tab through the normal `browser` tool surfac
## Install / load (unpacked)
1) Install the extension to a stable local path:
1. Install the extension to a stable local path:
```bash
openclaw browser extension install
```
2) Print the installed extension directory path:
2. Print the installed extension directory path:
```bash
openclaw browser extension path
```
3) Chrome → `chrome://extensions`
3. Chrome → `chrome://extensions`
- Enable “Developer mode”
- “Load unpacked” → select the directory printed above
4) Pin the extension.
4. Pin the extension.
## Updates (no build step)
The extension ships inside the OpenClaw release (npm package) as static files. There is no separate “build” step.
After upgrading OpenClaw:
- Re-run `openclaw browser extension install` to refresh the installed files under your OpenClaw state directory.
- Chrome → `chrome://extensions` → click “Reload” on the extension.
@@ -54,6 +57,7 @@ After upgrading OpenClaw:
OpenClaw ships with a built-in browser profile named `chrome` that targets the extension relay on the default port.
Use it:
- CLI: `openclaw browser --browser-profile chrome tabs`
- Agent tool: `browser` with `profile="chrome"`
@@ -87,6 +91,7 @@ openclaw browser create-profile \
- `!`: relay not reachable (most common: browser relay server isnt running on this machine).
If you see `!`:
- Make sure the Gateway is running locally (default setup), or run a node host on this machine if the Gateway runs elsewhere.
- Open the extension Options page; it shows whether the relay is reachable.
@@ -112,6 +117,7 @@ If your agent session is sandboxed (`agents.defaults.sandbox.mode != "off"`), th
- Chrome extension relay takeover requires controlling the **host** browser control server.
Options:
- Easiest: use the extension from a **non-sandboxed** session/agent.
- Or allow host browser control for sandboxed sessions:
@@ -121,11 +127,11 @@ Options:
defaults: {
sandbox: {
browser: {
allowHostControl: true
}
}
}
}
allowHostControl: true,
},
},
},
},
}
```
@@ -158,11 +164,13 @@ This is powerful and risky. Treat it like giving the model “hands on your brow
- If you attach to your daily-driver profile/tab, youre granting access to that account state.
Recommendations:
- Prefer a dedicated Chrome profile (separate from your personal browsing) for extension relay usage.
- Keep the Gateway and any node hosts tailnet-only; rely on Gateway auth + node pairing.
- Avoid exposing relay ports over LAN (`0.0.0.0`) and avoid Funnel (public).
Related:
- Browser tool overview: [Browser](/tools/browser)
- Security audit: [Security](/gateway/security)
- Tailscale setup: [Tailscale](/gateway/tailscale)

View File

@@ -23,12 +23,12 @@ If you want to add new capabilities to your OpenClaw agent, ClawHub is the easie
## Quick start (non-technical)
1) Install the CLI (see next section).
2) Search for something you need:
1. Install the CLI (see next section).
2. Search for something you need:
- `clawhub search "calendar"`
3) Install a skill:
3. Install a skill:
- `clawhub install <skill-slug>`
4) Start a new OpenClaw session so it picks up the new skill.
4. Start a new OpenClaw session so it picks up the new skill.
## Install the CLI

View File

@@ -3,17 +3,21 @@
OpenClaw is designed to be easily extensible. "Skills" are the primary way to add new capabilities to your assistant.
## What is a Skill?
A skill is a directory containing a `SKILL.md` file (which provides instructions and tool definitions to the LLM) and optionally some scripts or resources.
## Step-by-Step: Your First Skill
### 1. Create the Directory
Skills live in your workspace, usually `~/.openclaw/workspace/skills/`. Create a new folder for your skill:
```bash
mkdir -p ~/.openclaw/workspace/skills/hello-world
```
### 2. Define the `SKILL.md`
Create a `SKILL.md` file in that directory. This file uses YAML frontmatter for metadata and Markdown for instructions.
```markdown
@@ -23,19 +27,24 @@ description: A simple skill that says hello.
---
# Hello World Skill
When the user asks for a greeting, use the `echo` tool to say "Hello from your custom skill!".
```
### 3. Add Tools (Optional)
You can define custom tools in the frontmatter or instruct the agent to use existing system tools (like `bash` or `browser`).
### 4. Refresh OpenClaw
Ask your agent to "refresh skills" or restart the gateway. OpenClaw will discover the new directory and index the `SKILL.md`.
## Best Practices
- **Be Concise**: Instruct the model on *what* to do, not how to be an AI.
- **Be Concise**: Instruct the model on _what_ to do, not how to be an AI.
- **Safety First**: If your skill uses `bash`, ensure the prompts don't allow arbitrary command injection from untrusted user input.
- **Test Locally**: Use `openclaw agent --message "use my new skill"` to test.
## Shared Skills
You can also browse and contribute skills to [ClawHub](https://clawhub.com).

View File

@@ -3,9 +3,11 @@ summary: "Elevated exec mode and /elevated directives"
read_when:
- Adjusting elevated mode defaults, allowlists, or slash command behavior
---
# Elevated Mode (/elevated directives)
## What it does
- `/elevated on` runs on the gateway host and keeps exec approvals (same as `/elevated ask`).
- `/elevated full` runs on the gateway host **and** auto-approves exec (skips exec approvals).
- `/elevated ask` runs on the gateway host but keeps exec approvals (same as `/elevated on`).
@@ -15,6 +17,7 @@ read_when:
- Only `on|off|ask|full` are accepted; anything else returns a hint and does not change state.
## What it controls (and what it doesnt)
- **Availability gates**: `tools.elevated` is the global baseline. `agents.list[].tools.elevated` can further restrict elevated per agent (both must allow).
- **Per-session state**: `/elevated on|off|ask|full` sets the elevated level for the current session key.
- **Inline directive**: `/elevated on|ask|full` inside a message applies to that message only.
@@ -26,17 +29,20 @@ read_when:
- **Separate from `/exec`**: `/exec` adjusts per-session defaults for authorized senders and does not require elevated.
## Resolution order
1. Inline directive on the message (applies only to that message).
2. Session override (set by sending a directive-only message).
3. Global default (`agents.defaults.elevatedDefault` in config).
## Setting a session default
- Send a message that is **only** the directive (whitespace allowed), e.g. `/elevated full`.
- Confirmation reply is sent (`Elevated mode set to full...` / `Elevated mode disabled.`).
- If elevated access is disabled or the sender is not on the approved allowlist, the directive replies with an actionable error and does not change session state.
- Send `/elevated` (or `/elevated:`) with no argument to see the current elevated level.
## Availability + allowlists
- Feature gate: `tools.elevated.enabled` (default can be off via config even if the code supports it).
- Sender allowlist: `tools.elevated.allowFrom` with per-provider allowlists (e.g. `discord`, `whatsapp`).
- Per-agent gate: `agents.list[].tools.elevated.enabled` (optional; can only further restrict).
@@ -45,5 +51,6 @@ read_when:
- All gates must pass; otherwise elevated is treated as unavailable.
## Logging + status
- Elevated exec calls are logged at info level.
- Session status includes elevated mode (e.g. `elevated=ask`, `elevated=full`).

View File

@@ -20,10 +20,12 @@ resolved by the **ask fallback** (default: deny).
## Where it applies
Exec approvals are enforced locally on the execution host:
- **gateway host** → `openclaw` process on the gateway machine
- **node host** → node runner (macOS companion app or headless node host)
macOS split:
- **node host service** forwards `system.run` to the **macOS app** over local IPC.
- **macOS app** enforces approvals + executes the command in UI context.
@@ -34,6 +36,7 @@ Approvals live in a local JSON file on the execution host:
`~/.openclaw/exec-approvals.json`
Example schema:
```json
{
"version": 1,
@@ -70,17 +73,21 @@ Example schema:
## Policy knobs
### Security (`exec.security`)
- **deny**: block all host exec requests.
- **allowlist**: allow only allowlisted commands.
- **full**: allow everything (equivalent to elevated).
### Ask (`exec.ask`)
- **off**: never prompt.
- **on-miss**: prompt only when allowlist does not match.
- **always**: prompt on every command.
### Ask fallback (`askFallback`)
If a prompt is required but no UI is reachable, fallback decides:
- **deny**: block.
- **allowlist**: allow only if allowlist matches.
- **full**: allow.
@@ -93,11 +100,13 @@ Patterns should resolve to **binary paths** (basename-only entries are ignored).
Legacy `agents.default` entries are migrated to `agents.main` on load.
Examples:
- `~/Projects/**/bin/bird`
- `~/.local/bin/*`
- `/opt/homebrew/bin/rg`
Each allowlist entry tracks:
- **id** stable UUID used for UI identity (optional)
- **last used** timestamp
- **last used command**
@@ -146,6 +155,7 @@ correlate later system events (`Exec finished` / `Exec denied`). If no decision
timeout, the request is treated as an approval timeout and surfaced as a denial reason.
The confirmation dialog includes:
- command + args
- cwd
- agent id
@@ -153,6 +163,7 @@ The confirmation dialog includes:
- host + policy metadata
Actions:
- **Allow once** → run now
- **Always allow** → add to allowlist + run
- **Deny** → block
@@ -163,6 +174,7 @@ You can forward exec approval prompts to any chat channel (including plugin chan
them with `/approve`. This uses the normal outbound delivery pipeline.
Config:
```json5
{
approvals: {
@@ -173,14 +185,15 @@ Config:
sessionFilter: ["discord"], // substring or regex
targets: [
{ channel: "slack", to: "U12345678" },
{ channel: "telegram", to: "123456789" }
]
}
}
{ channel: "telegram", to: "123456789" },
],
},
},
}
```
Reply in chat:
```
/approve <id> allow-once
/approve <id> allow-always
@@ -188,6 +201,7 @@ Reply in chat:
```
### macOS IPC flow
```
Gateway -> Node Service (WS)
| IPC (UDS + token + HMAC + TTL)
@@ -196,6 +210,7 @@ Gateway -> Node Service (WS)
```
Security notes:
- Unix socket mode `0600`, token stored in `exec-approvals.json`.
- Same-UID peer check.
- Challenge/response (nonce + HMAC token + request hash) + short TTL.
@@ -203,6 +218,7 @@ Security notes:
## System events
Exec lifecycle is surfaced as system messages:
- `Exec running` (only if the command exceeds the running notice threshold)
- `Exec finished`
- `Exec denied`
@@ -221,6 +237,7 @@ Approval-gated execs reuse the approval id as the `runId` in these messages for
To hard-block host exec, set approvals security to `deny` or deny the `exec` tool via tool policy.
Related:
- [Exec tool](/tools/exec)
- [Elevated mode](/tools/elevated)
- [Skills](/tools/skills)

View File

@@ -27,6 +27,7 @@ Background sessions are scoped per agent; `process` only sees sessions from the
- `elevated` (bool): request elevated mode (gateway host); `security=full` is only forced when elevated resolves to `full`
Notes:
- `host` defaults to `sandbox`.
- `elevated` is ignored when sandboxing is off (exec already runs on the host).
- `gateway`/`node` approvals are controlled by `~/.openclaw/exec-approvals.json`.
@@ -50,13 +51,14 @@ Notes:
- `tools.exec.safeBins`: stdin-only safe binaries that can run without explicit allowlist entries.
Example:
```json5
{
tools: {
exec: {
pathPrepend: ["~/bin", "/opt/oss/bin"]
}
}
pathPrepend: ["~/bin", "/opt/oss/bin"],
},
},
}
```
@@ -88,6 +90,7 @@ Use `/exec` to set **per-session** defaults for `host`, `security`, `ask`, and `
Send `/exec` with no arguments to show the current values.
Example:
```
/exec host=gateway security=allowlist ask=on-miss node=mac-1
```
@@ -119,17 +122,20 @@ allowlist mode.
## Examples
Foreground:
```json
{"tool":"exec","command":"ls -la"}
{ "tool": "exec", "command": "ls -la" }
```
Background + poll:
```json
{"tool":"exec","command":"npm run build","yieldMs":1000}
{"tool":"process","action":"poll","sessionId":"<id>"}
```
Send keys (tmux-style):
```json
{"tool":"process","action":"send-keys","sessionId":"<id>","keys":["Enter"]}
{"tool":"process","action":"send-keys","sessionId":"<id>","keys":["C-c"]}
@@ -137,13 +143,15 @@ Send keys (tmux-style):
```
Submit (send CR only):
```json
{"tool":"process","action":"submit","sessionId":"<id>"}
{ "tool": "process", "action": "submit", "sessionId": "<id>" }
```
Paste (bracketed by default):
```json
{"tool":"process","action":"paste","sessionId":"<id>","text":"line1\nline2\n"}
{ "tool": "process", "action": "paste", "sessionId": "<id>", "text": "line1\nline2\n" }
```
## apply_patch (experimental)
@@ -155,13 +163,14 @@ Enable it explicitly:
{
tools: {
exec: {
applyPatch: { enabled: true, allowModels: ["gpt-5.2"] }
}
}
applyPatch: { enabled: true, allowModels: ["gpt-5.2"] },
},
},
}
```
Notes:
- Only available for OpenAI/OpenAI Codex models.
- Tool policy still applies; `allow: ["exec"]` implicitly allows `apply_patch`.
- Config lives under `tools.exec.applyPatch`.

View File

@@ -14,8 +14,8 @@ with JS-heavy sites or pages that block plain HTTP fetches.
## Get an API key
1) Create a Firecrawl account and generate an API key.
2) Store it in config or set `FIRECRAWL_API_KEY` in the gateway environment.
1. Create a Firecrawl account and generate an API key.
2. Store it in config or set `FIRECRAWL_API_KEY` in the gateway environment.
## Configure Firecrawl
@@ -29,15 +29,16 @@ with JS-heavy sites or pages that block plain HTTP fetches.
baseUrl: "https://api.firecrawl.dev",
onlyMainContent: true,
maxAgeMs: 172800000,
timeoutSeconds: 60
}
}
}
}
timeoutSeconds: 60,
},
},
},
},
}
```
Notes:
- `firecrawl.enabled` defaults to true when an API key is present.
- `maxAgeMs` controls how old cached results can be (ms). Default is 2 days.
@@ -51,8 +52,9 @@ than basic-only scraping.
## How `web_fetch` uses Firecrawl
`web_fetch` extraction order:
1) Readability (local)
2) Firecrawl (if configured)
3) Basic HTML cleanup (last fallback)
1. Readability (local)
2. Firecrawl (if configured)
3. Basic HTML cleanup (last fallback)
See [Web tools](/tools/web) for the full web tool setup.

View File

@@ -18,11 +18,12 @@ You can globally allow/deny tools via `tools.allow` / `tools.deny` in `openclaw.
```json5
{
tools: { deny: ["browser"] }
tools: { deny: ["browser"] },
}
```
Notes:
- Matching is case-insensitive.
- `*` wildcards are supported (`"*"` means all tools).
- If `tools.allow` only references unknown or unloaded plugin tool names, OpenClaw logs a warning and ignores the allowlist so core tools stay available.
@@ -33,32 +34,36 @@ Notes:
Per-agent override: `agents.list[].tools.profile`.
Profiles:
- `minimal`: `session_status` only
- `coding`: `group:fs`, `group:runtime`, `group:sessions`, `group:memory`, `image`
- `messaging`: `group:messaging`, `sessions_list`, `sessions_history`, `sessions_send`, `session_status`
- `full`: no restriction (same as unset)
Example (messaging-only by default, allow Slack + Discord tools too):
```json5
{
tools: {
profile: "messaging",
allow: ["slack", "discord"]
}
allow: ["slack", "discord"],
},
}
```
Example (coding profile, but deny exec/process everywhere):
```json5
{
tools: {
profile: "coding",
deny: ["group:runtime"]
}
deny: ["group:runtime"],
},
}
```
Example (global coding profile, messaging-only support agent):
```json5
{
tools: { profile: "coding" },
@@ -66,10 +71,10 @@ Example (global coding profile, messaging-only support agent):
list: [
{
id: "support",
tools: { profile: "messaging", allow: ["slack"] }
}
]
}
tools: { profile: "messaging", allow: ["slack"] },
},
],
},
}
```
@@ -85,30 +90,33 @@ Provider keys accept either `provider` (e.g. `google-antigravity`) or
`provider/model` (e.g. `openai/gpt-5.2`).
Example (keep global coding profile, but minimal tools for Google Antigravity):
```json5
{
tools: {
profile: "coding",
byProvider: {
"google-antigravity": { profile: "minimal" }
}
}
"google-antigravity": { profile: "minimal" },
},
},
}
```
Example (provider/model-specific allowlist for a flaky endpoint):
```json5
{
tools: {
allow: ["group:fs", "group:runtime", "sessions_list"],
byProvider: {
"openai/gpt-5.2": { allow: ["group:fs", "sessions_list"] }
}
}
"openai/gpt-5.2": { allow: ["group:fs", "sessions_list"] },
},
},
}
```
Example (agent-specific override for a single provider):
```json5
{
agents: {
@@ -117,12 +125,12 @@ Example (agent-specific override for a single provider):
id: "support",
tools: {
byProvider: {
"google-antigravity": { allow: ["message", "sessions_list"] }
}
}
}
]
}
"google-antigravity": { allow: ["message", "sessions_list"] },
},
},
},
],
},
}
```
@@ -132,6 +140,7 @@ Tool policies (global, agent, sandbox) support `group:*` entries that expand to
Use these in `tools.allow` / `tools.deny`.
Available groups:
- `group:runtime`: `exec`, `bash`, `process`
- `group:fs`: `read`, `write`, `edit`, `apply_patch`
- `group:sessions`: `sessions_list`, `sessions_history`, `sessions_send`, `sessions_spawn`, `session_status`
@@ -144,11 +153,12 @@ Available groups:
- `group:openclaw`: all built-in OpenClaw tools (excludes provider plugins)
Example (allow only file tools + browser):
```json5
{
tools: {
allow: ["group:fs", "browser"]
}
allow: ["group:fs", "browser"],
},
}
```
@@ -160,19 +170,23 @@ tool usage guidance is injected into prompts. Some plugins ship their own skills
alongside tools (for example, the voice-call plugin).
Optional plugin tools:
- [Lobster](/tools/lobster): typed workflow runtime with resumable approvals (requires the Lobster CLI on the gateway host).
- [LLM Task](/tools/llm-task): JSON-only LLM step for structured workflow output (optional schema validation).
## Tool inventory
### `apply_patch`
Apply structured patches across one or more files. Use for multi-hunk edits.
Experimental: enable via `tools.exec.applyPatch.enabled` (OpenAI models only).
### `exec`
Run shell commands in the workspace.
Core parameters:
- `command` (required)
- `yieldMs` (auto-background after timeout, default 10000)
- `background` (immediate background)
@@ -185,6 +199,7 @@ Core parameters:
- Need a real TTY? Set `pty: true`.
Notes:
- Returns `status: "running"` with a `sessionId` when backgrounded.
- Use `process` to poll/log/write/kill/clear background sessions.
- If `process` is disallowed, `exec` runs synchronously and ignores `yieldMs`/`background`.
@@ -194,38 +209,47 @@ Notes:
- gateway/node approvals and allowlists: [Exec approvals](/tools/exec-approvals).
### `process`
Manage background exec sessions.
Core actions:
- `list`, `poll`, `log`, `write`, `kill`, `clear`, `remove`
Notes:
- `poll` returns new output and exit status when complete.
- `log` supports line-based `offset`/`limit` (omit `offset` to grab the last N lines).
- `process` is scoped per agent; sessions from other agents are not visible.
### `web_search`
Search the web using Brave Search API.
Core parameters:
- `query` (required)
- `count` (110; default from `tools.web.search.maxResults`)
Notes:
- Requires a Brave API key (recommended: `openclaw configure --section web`, or set `BRAVE_API_KEY`).
- Enable via `tools.web.search.enabled`.
- Responses are cached (default 15 min).
- See [Web tools](/tools/web) for setup.
### `web_fetch`
Fetch and extract readable content from a URL (HTML → markdown/text).
Core parameters:
- `url` (required)
- `extractMode` (`markdown` | `text`)
- `maxChars` (truncate long pages)
Notes:
- Enable via `tools.web.fetch.enabled`.
- Responses are cached (default 15 min).
- For JS-heavy sites, prefer the browser tool.
@@ -233,9 +257,11 @@ Notes:
- See [Firecrawl](/tools/firecrawl) for the optional anti-bot fallback.
### `browser`
Control the dedicated OpenClaw-managed browser.
Core actions:
- `status`, `start`, `stop`, `tabs`, `open`, `focus`, `close`
- `snapshot` (aria/ai)
- `screenshot` (returns image block + `MEDIA:<path>`)
@@ -243,16 +269,18 @@ Core actions:
- `navigate`, `console`, `pdf`, `upload`, `dialog`
Profile management:
- `profiles` — list all browser profiles with status
- `create-profile` — create new profile with auto-allocated port (or `cdpUrl`)
- `delete-profile` — stop browser, delete user data, remove from config (local only)
- `reset-profile` — kill orphan process on profile's port (local only)
Common parameters:
- `profile` (optional; defaults to `browser.defaultProfile`)
- `target` (`sandbox` | `host` | `node`)
- `node` (optional; picks a specific node id/name)
Notes:
Notes:
- Requires `browser.enabled=true` (default is `true`; set `false` to disable).
- All actions accept optional `profile` parameter for multi-instance support.
- When `profile` is omitted, uses `browser.defaultProfile` (defaults to "chrome").
@@ -268,23 +296,28 @@ Notes:
- `upload` also supports `inputRef` (aria ref) or `element` (CSS selector) to set `<input type="file">` directly.
### `canvas`
Drive the node Canvas (present, eval, snapshot, A2UI).
Core actions:
- `present`, `hide`, `navigate`, `eval`
- `snapshot` (returns image block + `MEDIA:<path>`)
- `a2ui_push`, `a2ui_reset`
Notes:
- Uses gateway `node.invoke` under the hood.
- If no `node` is provided, the tool picks a default (single connected node or local mac node).
- A2UI is v0.8 only (no `createSurface`); the CLI rejects v0.9 JSONL with line errors.
- Quick smoke: `openclaw nodes canvas a2ui push --node <id> --text "Hello from A2UI"`.
### `nodes`
Discover and target paired nodes; send notifications; capture camera/screen.
Core actions:
- `status`, `describe`
- `pending`, `approve`, `reject` (pairing)
- `notify` (macOS `system.notify`)
@@ -293,6 +326,7 @@ Core actions:
- `location_get`
Notes:
- Camera/screen commands require the node app to be foregrounded.
- Images return image blocks + `MEDIA:<path>`.
- Videos return `FILE:<path>` (mp4).
@@ -300,6 +334,7 @@ Notes:
- `run` params: `command` argv array; optional `cwd`, `env` (`KEY=VAL`), `commandTimeoutMs`, `invokeTimeoutMs`, `needsScreenRecording`.
Example (`run`):
```json
{
"action": "run",
@@ -313,22 +348,27 @@ Example (`run`):
```
### `image`
Analyze an image with the configured image model.
Core parameters:
- `image` (required path or URL)
- `prompt` (optional; defaults to "Describe the image.")
- `model` (optional override)
- `maxBytesMb` (optional size cap)
Notes:
- Only available when `agents.defaults.imageModel` is configured (primary or fallbacks), or when an implicit image model can be inferred from your default model + configured auth (best-effort pairing).
- Uses the image model directly (independent of the main chat model).
### `message`
Send messages and channel actions across Discord/Google Chat/Slack/Telegram/WhatsApp/Signal/iMessage/MS Teams.
Core actions:
- `send` (text + optional media; MS Teams also supports `card` for Adaptive Cards)
- `poll` (WhatsApp/Discord/MS Teams polls)
- `react` / `reactions` / `read` / `edit` / `delete`
@@ -346,26 +386,32 @@ Core actions:
- `timeout` / `kick` / `ban`
Notes:
- `send` routes WhatsApp via the Gateway; other channels go direct.
- `poll` uses the Gateway for WhatsApp and MS Teams; Discord polls go direct.
- When a message tool call is bound to an active chat session, sends are constrained to that sessions target to avoid cross-context leaks.
### `cron`
Manage Gateway cron jobs and wakeups.
Core actions:
- `status`, `list`
- `add`, `update`, `remove`, `run`, `runs`
- `wake` (enqueue system event + optional immediate heartbeat)
Notes:
- `add` expects a full cron job object (same schema as `cron.add` RPC).
- `update` uses `{ id, patch }`.
### `gateway`
Restart or apply updates to the running Gateway process (in-place).
Core actions:
- `restart` (authorizes + sends `SIGUSR1` for in-process restart; `openclaw gateway` restart in-place)
- `config.get` / `config.schema`
- `config.apply` (validate + write config + restart + wake)
@@ -373,13 +419,16 @@ Core actions:
- `update.run` (run update + restart + wake)
Notes:
- Use `delayMs` (defaults to 2000) to avoid interrupting an in-flight reply.
- `restart` is disabled by default; enable with `commands.restart: true`.
### `sessions_list` / `sessions_history` / `sessions_send` / `sessions_spawn` / `session_status`
List sessions, inspect transcript history, or send to another session.
Core parameters:
- `sessions_list`: `kinds?`, `limit?`, `activeMinutes?`, `messageLimit?` (0 = none)
- `sessions_history`: `sessionKey` (or `sessionId`), `limit?`, `includeTools?`
- `sessions_send`: `sessionKey` (or `sessionId`), `message`, `timeoutSeconds?` (0 = fire-and-forget)
@@ -387,6 +436,7 @@ Core parameters:
- `session_status`: `sessionKey?` (default current; accepts `sessionId`), `model?` (`default` clears override)
Notes:
- `main` is the canonical direct-chat key; global/unknown are hidden.
- `messageLimit > 0` fetches last N messages per session (tool messages filtered).
- `sessions_send` waits for final completion when `timeoutSeconds > 0`.
@@ -397,20 +447,24 @@ Notes:
- After the pingpong, the target agent runs an **announce step**; reply `ANNOUNCE_SKIP` to suppress the announcement.
### `agents_list`
List agent ids that the current session may target with `sessions_spawn`.
Notes:
- Result is restricted to per-agent allowlists (`agents.list[].subagents.allowAgents`).
- When `["*"]` is configured, the tool includes all configured agents and marks `allowAny: true`.
## Parameters (common)
Gateway-backed tools (`canvas`, `nodes`, `cron`):
- `gatewayUrl` (default `ws://127.0.0.1:18789`)
- `gatewayToken` (if auth enabled)
- `timeoutMs`
Browser tool:
- `profile` (optional; defaults to `browser.defaultProfile`)
- `target` (`sandbox` | `host` | `node`)
- `node` (optional; pin a specific node id/name)
@@ -418,20 +472,23 @@ Browser tool:
## Recommended agent flows
Browser automation:
1) `browser``status` / `start`
2) `snapshot` (ai or aria)
3) `act` (click/type/press)
4) `screenshot` if you need visual confirmation
1. `browser``status` / `start`
2. `snapshot` (ai or aria)
3. `act` (click/type/press)
4. `screenshot` if you need visual confirmation
Canvas render:
1) `canvas``present`
2) `a2ui_push` (optional)
3) `snapshot`
1. `canvas``present`
2. `a2ui_push` (optional)
3. `snapshot`
Node targeting:
1) `nodes``status`
2) `describe` on the chosen node
3) `notify` / `run` / `camera_snap` / `screen_record`
1. `nodes``status`
2. `describe` on the chosen node
3. `notify` / `run` / `camera_snap` / `screen_record`
## Safety
@@ -443,8 +500,8 @@ Node targeting:
Tools are exposed in two parallel channels:
1) **System prompt text**: a human-readable list + guidance.
2) **Tool schema**: the structured function definitions sent to the model API.
1. **System prompt text**: a human-readable list + guidance.
2. **Tool schema**: the structured function definitions sent to the model API.
That means the agent sees both “what tools exist” and “how to call them.” If a tool
doesnt appear in the system prompt or the schema, the model cannot call it.

View File

@@ -15,7 +15,7 @@ without writing custom OpenClaw code for each workflow.
## Enable the plugin
1) Enable the plugin:
1. Enable the plugin:
```json
{
@@ -27,7 +27,7 @@ without writing custom OpenClaw code for each workflow.
}
```
2) Allowlist the tool (it is registered with `optional: true`):
2. Allowlist the tool (it is registered with `optional: true`):
```json
{

View File

@@ -27,7 +27,7 @@ Today, complex workflows require many back-and-forth tool calls. Each call costs
Lobster is intentionally small. The goal is not "a new language," it's a predictable, AI-friendly pipeline spec with first-class approvals and resume tokens.
- **Approve/resume is built in**: A normal program can prompt a human, but it cant *pause and resume* with a durable token without you inventing that runtime yourself.
- **Approve/resume is built in**: A normal program can prompt a human, but it cant _pause and resume_ with a durable token without you inventing that runtime yourself.
- **Determinism + auditability**: Pipelines are data, so theyre easy to log, diff, replay, and review.
- **Constrained surface for AI**: A tiny grammar + JSON piping reduces “creative” code paths and makes validation realistic.
- **Safety policy baked in**: Timeouts, output caps, sandbox checks, and allowlists are enforced by the runtime, not each script.
@@ -196,6 +196,7 @@ tools, include the core tools or groups you want in the allowlist too.
## Example: Email triage
Without Lobster:
```
User: "Check my email and draft replies"
→ openclaw calls gmail.list
@@ -208,6 +209,7 @@ User: "Check my email and draft replies"
```
With Lobster:
```json
{
"action": "run",
@@ -217,6 +219,7 @@ With Lobster:
```
Returns a JSON envelope (truncated):
```json
{
"ok": true,
@@ -232,6 +235,7 @@ Returns a JSON envelope (truncated):
```
User approves → resume:
```json
{
"action": "resume",

View File

@@ -3,6 +3,7 @@ summary: "Reaction semantics shared across channels"
read_when:
- Working on reactions in any channel
---
# Reaction tooling
Shared reaction semantics across channels:

View File

@@ -4,6 +4,7 @@ read_when:
- Adding or modifying skills config
- Adjusting bundled allowlist or install behavior
---
# Skills Config
All skills-related configuration lives under `skills` in `~/.openclaw/openclaw.json`.
@@ -13,29 +14,26 @@ All skills-related configuration lives under `skills` in `~/.openclaw/openclaw.j
skills: {
allowBundled: ["gemini", "peekaboo"],
load: {
extraDirs: [
"~/Projects/agent-scripts/skills",
"~/Projects/oss/some-skill-pack/skills"
],
extraDirs: ["~/Projects/agent-scripts/skills", "~/Projects/oss/some-skill-pack/skills"],
watch: true,
watchDebounceMs: 250
watchDebounceMs: 250,
},
install: {
preferBrew: true,
nodeManager: "npm" // npm | pnpm | yarn | bun (Gateway runtime still Node; bun not recommended)
nodeManager: "npm", // npm | pnpm | yarn | bun (Gateway runtime still Node; bun not recommended)
},
entries: {
"nano-banana-pro": {
enabled: true,
apiKey: "GEMINI_KEY_HERE",
env: {
GEMINI_API_KEY: "GEMINI_KEY_HERE"
}
GEMINI_API_KEY: "GEMINI_KEY_HERE",
},
},
peekaboo: { enabled: true },
sag: { enabled: false }
}
}
sag: { enabled: false },
},
},
}
```
@@ -53,6 +51,7 @@ All skills-related configuration lives under `skills` in `~/.openclaw/openclaw.j
- `entries.<skillKey>`: per-skill overrides.
Per-skill fields:
- `enabled`: set `false` to disable a skill even if its bundled/installed.
- `env`: environment variables injected for the agent run (only if not already set).
- `apiKey`: optional convenience for skills that declare a primary env var.
@@ -69,6 +68,7 @@ When a session is **sandboxed**, skill processes run inside Docker. The sandbox
does **not** inherit the host `process.env`.
Use one of:
- `agents.defaults.sandbox.docker.env` (or per-agent `agents.list[].sandbox.docker.env`)
- bake the env into your custom sandbox image

View File

@@ -4,6 +4,7 @@ read_when:
- Adding or modifying skills
- Changing skill gating or load rules
---
# Skills (OpenClaw)
OpenClaw uses **[AgentSkills](https://agentskills.io)-compatible** skill folders to teach the agent how to use tools. Each skill is a directory containing a `SKILL.md` with YAML frontmatter and instructions. OpenClaw loads **bundled skills** plus optional local overrides, and filters them at load time based on environment, config, and binary presence.
@@ -12,9 +13,9 @@ OpenClaw uses **[AgentSkills](https://agentskills.io)-compatible** skill folders
Skills are loaded from **three** places:
1) **Bundled skills**: shipped with the install (npm package or OpenClaw.app)
2) **Managed/local skills**: `~/.openclaw/skills`
3) **Workspace skills**: `<workspace>/skills`
1. **Bundled skills**: shipped with the install (npm package or OpenClaw.app)
2. **Managed/local skills**: `~/.openclaw/skills`
3. **Workspace skills**: `<workspace>/skills`
If a skill name conflicts, precedence is:
@@ -84,6 +85,7 @@ description: Generate or edit images via Gemini 3 Pro Image
```
Notes:
- We follow the AgentSkills spec for layout/intent.
- The parser used by the embedded agent supports **single-line** frontmatter keys only.
- `metadata` should be a **single-line JSON object**.
@@ -107,11 +109,19 @@ OpenClaw **filters skills at load time** using `metadata` (single-line JSON):
---
name: nano-banana-pro
description: Generate or edit images via Gemini 3 Pro Image
metadata: {"openclaw":{"requires":{"bins":["uv"],"env":["GEMINI_API_KEY"],"config":["browser.enabled"]},"primaryEnv":"GEMINI_API_KEY"}}
metadata:
{
"openclaw":
{
"requires": { "bins": ["uv"], "env": ["GEMINI_API_KEY"], "config": ["browser.enabled"] },
"primaryEnv": "GEMINI_API_KEY",
},
}
---
```
Fields under `metadata.openclaw`:
- `always: true` — always include the skill (skip other gates).
- `emoji` — optional emoji used by the macOS Skills UI.
- `homepage` — optional URL shown as “Website” in the macOS Skills UI.
@@ -124,6 +134,7 @@ Fields under `metadata.openclaw`:
- `install` — optional array of installer specs used by the macOS Skills UI (brew/node/go/uv/download).
Note on sandboxing:
- `requires.bins` is checked on the **host** at skill load time.
- If an agent is sandboxed, the binary must also exist **inside the container**.
Install it via `agents.defaults.sandbox.docker.setupCommand` (or a custom image).
@@ -138,11 +149,29 @@ Installer example:
---
name: gemini
description: Use Gemini CLI for coding assistance and Google search lookups.
metadata: {"openclaw":{"emoji":"♊️","requires":{"bins":["gemini"]},"install":[{"id":"brew","kind":"brew","formula":"gemini-cli","bins":["gemini"],"label":"Install Gemini CLI (brew)"}]}}
metadata:
{
"openclaw":
{
"emoji": "♊️",
"requires": { "bins": ["gemini"] },
"install":
[
{
"id": "brew",
"kind": "brew",
"formula": "gemini-cli",
"bins": ["gemini"],
"label": "Install Gemini CLI (brew)",
},
],
},
}
---
```
Notes:
- If multiple installers are listed, the gateway picks a **single** preferred option (brew when available, otherwise node).
- If all installers are `download`, OpenClaw lists each entry so you can see the available artifacts.
- Installer specs can include `os: ["darwin"|"linux"|"win32"]` to filter options by platform.
@@ -150,7 +179,7 @@ Notes:
This only affects **skill installs**; the Gateway runtime should still be Node
(Bun is not recommended for WhatsApp/Telegram).
- Go installs: if `go` is missing and `brew` is available, the gateway installs Go via Homebrew first and sets `GOBIN` to Homebrews `bin` when possible.
- Download installs: `url` (required), `archive` (`tar.gz` | `tar.bz2` | `zip`), `extract` (default: auto when archive detected), `stripComponents`, `targetDir` (default: `~/.openclaw/tools/<skillKey>`).
- Download installs: `url` (required), `archive` (`tar.gz` | `tar.bz2` | `zip`), `extract` (default: auto when archive detected), `stripComponents`, `targetDir` (default: `~/.openclaw/tools/<skillKey>`).
If no `metadata.openclaw` is present, the skill is always eligible (unless
disabled in config or blocked by `skills.allowBundled` for bundled skills).
@@ -167,17 +196,17 @@ Bundled/managed skills can be toggled and supplied with env values:
enabled: true,
apiKey: "GEMINI_KEY_HERE",
env: {
GEMINI_API_KEY: "GEMINI_KEY_HERE"
GEMINI_API_KEY: "GEMINI_KEY_HERE",
},
config: {
endpoint: "https://example.invalid",
model: "nano-pro"
}
model: "nano-pro",
},
},
peekaboo: { enabled: true },
sag: { enabled: false }
}
}
sag: { enabled: false },
},
},
}
```
@@ -187,6 +216,7 @@ Config keys match the **skill name** by default. If a skill defines
`metadata.openclaw.skillKey`, use that key under `skills.entries`.
Rules:
- `enabled: false` disables the skill even if its bundled/installed.
- `env`: injected **only if** the variable isnt already set in the process.
- `apiKey`: convenience for skills that declare `metadata.openclaw.primaryEnv`.
@@ -197,11 +227,12 @@ Rules:
## Environment injection (per agent run)
When an agent run starts, OpenClaw:
1) Reads skill metadata.
2) Applies any `skills.entries.<key>.env` or `skills.entries.<key>.apiKey` to
1. Reads skill metadata.
2. Applies any `skills.entries.<key>.env` or `skills.entries.<key>.apiKey` to
`process.env`.
3) Builds the system prompt with **eligible** skills.
4) Restores the original environment after the run ends.
3. Builds the system prompt with **eligible** skills.
4. Restores the original environment after the run ends.
This is **scoped to the agent run**, not a global shell environment.
@@ -226,9 +257,9 @@ By default, OpenClaw watches skill folders and bumps the skills snapshot when `S
skills: {
load: {
watch: true,
watchDebounceMs: 250
}
}
watchDebounceMs: 250,
},
},
}
```
@@ -246,6 +277,7 @@ total = 195 + Σ (97 + len(name_escaped) + len(description_escaped) + len(locati
```
Notes:
- XML escaping expands `& < > " '` into entities (`&amp;`, `&lt;`, etc.), increasing length.
- Token counts vary by model tokenizer. A rough OpenAI-style estimate is ~4 chars/token, so **97 chars ≈ 24 tokens** per skill plus your actual field lengths.

View File

@@ -4,6 +4,7 @@ read_when:
- Using or configuring chat commands
- Debugging command routing or permissions
---
# Slash commands
Commands are handled by the Gateway. Most commands must be sent as a **standalone** message that starts with `/`.
@@ -35,8 +36,8 @@ They run immediately, are stripped before the model sees the message, and the re
config: false,
debug: false,
restart: false,
useAccessGroups: true
}
useAccessGroups: true,
},
}
```
@@ -58,6 +59,7 @@ They run immediately, are stripped before the model sees the message, and the re
## Command list
Text + native (when enabled):
- `/help`
- `/commands`
- `/skill <name> [input]` (run a skill by name)
@@ -90,12 +92,14 @@ Text + native (when enabled):
- `/bash <command>` (host-only; alias for `! <command>`; requires `commands.bash: true` + `tools.elevated` allowlists)
Text-only:
- `/compact [instructions]` (see [/concepts/compaction](/concepts/compaction))
- `! <command>` (host-only; one at a time; use `!poll` + `!stop` for long-running jobs)
- `!poll` (check output / status; accepts optional `sessionId`; `/bash poll` also works)
- `!stop` (stop the running bash job; accepts optional `sessionId`; `/bash stop` also works)
Notes:
- Commands accept an optional `:` between the command and args (e.g. `/think: high`, `/send: on`, `/help:`).
- `/new <model>` accepts a model alias, `provider/model`, or a provider name (fuzzy match); if no match, the text is treated as the message body.
- For full provider usage breakdown, use `openclaw status --usage`.
@@ -139,6 +143,7 @@ Examples:
```
Notes:
- `/model` and `/model list` show a compact, numbered picker (model family + available providers).
- `/model <#>` selects from that picker (and prefers the current provider when possible).
- `/model status` shows the detailed view, including configured provider endpoint (`baseUrl`) and API mode (`api`) when available.
@@ -158,6 +163,7 @@ Examples:
```
Notes:
- Overrides apply immediately to new config reads, but do **not** write to `openclaw.json`.
- Use `/debug reset` to clear all overrides and return to the on-disk config.
@@ -176,6 +182,7 @@ Examples:
```
Notes:
- Config is validated before write; invalid changes are rejected.
- `/config` updates persist across restarts.

View File

@@ -12,6 +12,7 @@ Sub-agents are background agent runs spawned from an existing agent run. They ru
## Slash command
Use `/subagents` to inspect or control sub-agent runs for the **current session**:
- `/subagents list`
- `/subagents stop <id|#|all>`
- `/subagents log <id|#> [limit] [tools]`
@@ -21,6 +22,7 @@ Use `/subagents` to inspect or control sub-agent runs for the **current session*
`/subagents info` shows run metadata (status, timestamps, session id, transcript path, cleanup).
Primary goals:
- Parallelize “research / long task / slow tool” work without blocking the main run.
- Keep sub-agents isolated by default (session separation + optional sandboxing).
- Keep the tool surface hard to misuse: sub-agents do **not** get session tools by default.
@@ -33,11 +35,13 @@ You can configure this via `agents.defaults.subagents.model` or per-agent overri
## Tool
Use `sessions_spawn`:
- Starts a sub-agent run (`deliver: false`, global lane: `subagent`)
- Then runs an announce step and posts the announce reply to the requester chat channel
- Default model: inherits the caller unless you set `agents.defaults.subagents.model` (or per-agent `agents.list[].subagents.model`); an explicit `sessions_spawn.model` still wins.
Tool params:
- `task` (required)
- `label?` (optional)
- `agentId?` (optional; spawn under another agent id if allowed)
@@ -47,12 +51,15 @@ Tool params:
- `cleanup?` (`delete|keep`, default `keep`)
Allowlist:
- `agents.list[].subagents.allowAgents`: list of agent ids that can be targeted via `agentId` (`["*"]` to allow any). Default: only the requester agent.
Discovery:
- Use `agents_list` to see which agent ids are currently allowed for `sessions_spawn`.
Auto-archive:
- Sub-agent sessions are automatically archived after `agents.defaults.subagents.archiveAfterMinutes` (default: 60).
- Archive uses `sessions.delete` and renames the transcript to `*.deleted.<timestamp>` (same folder).
- `cleanup: "delete"` archives immediately after announce (still keeps the transcript via rename).
@@ -62,6 +69,7 @@ Auto-archive:
## Authentication
Sub-agent auth is resolved by **agent id**, not by session type:
- The sub-agent session key is `agent:<agentId>:subagent:<uuid>`.
- The auth store is loaded from that agents `agentDir`.
- The main agents auth profiles are merged in as a **fallback**; agent profiles override main profiles on conflicts.
@@ -71,6 +79,7 @@ Note: the merge is additive, so main profiles are always available as fallbacks.
## Announce
Sub-agents report back via an announce step:
- The announce step runs inside the sub-agent session (not the requester session).
- If the sub-agent replies exactly `ANNOUNCE_SKIP`, nothing is posted.
- Otherwise the announce reply is posted to the requester chat channel via a follow-up `agent` call (`deliver=true`).
@@ -82,6 +91,7 @@ Sub-agents report back via an announce step:
- `Status` is not inferred from model output; it comes from runtime outcome signals.
Announce payloads include a stats line at the end (even when wrapped):
- Runtime (e.g., `runtime 5m12s`)
- Token usage (input/output/total)
- Estimated cost when model pricing is configured (`models.providers.*.models[].cost`)
@@ -90,6 +100,7 @@ Announce payloads include a stats line at the end (even when wrapped):
## Tool Policy (sub-agent tools)
By default, sub-agents get **all tools except session tools**:
- `sessions_list`
- `sessions_history`
- `sessions_send`
@@ -102,9 +113,9 @@ Override via config:
agents: {
defaults: {
subagents: {
maxConcurrent: 1
}
}
maxConcurrent: 1,
},
},
},
tools: {
subagents: {
@@ -113,15 +124,16 @@ Override via config:
deny: ["gateway", "cron"],
// if allow is set, it becomes allow-only (deny still wins)
// allow: ["read", "exec", "process"]
}
}
}
},
},
},
}
```
## Concurrency
Sub-agents use a dedicated in-process queue lane:
- Lane name: `subagent`
- Concurrency: `agents.defaults.subagents.maxConcurrent` (default `8`)

View File

@@ -3,9 +3,11 @@ summary: "Directive syntax for /think + /verbose and how they affect model reaso
read_when:
- Adjusting thinking or verbose directive parsing or defaults
---
# Thinking Levels (/think directives)
## What it does
- Inline directive in any inbound body: `/t <level>`, `/think:<level>`, or `/thinking <level>`.
- Levels (aliases): `off | minimal | low | medium | high | xhigh` (GPT-5.2 + Codex models only)
- minimal → “think”
@@ -18,21 +20,25 @@ read_when:
- Z.AI (`zai/*`) only supports binary thinking (`on`/`off`). Any non-`off` level is treated as `on` (mapped to `low`).
## Resolution order
1. Inline directive on the message (applies only to that message).
2. Session override (set by sending a directive-only message).
3. Global default (`agents.defaults.thinkingDefault` in config).
4. Fallback: low for reasoning-capable models; off otherwise.
## Setting a session default
- Send a message that is **only** the directive (whitespace allowed), e.g. `/think:medium` or `/t high`.
- That sticks for the current session (per-sender by default); cleared by `/think:off` or session idle reset.
- Confirmation reply is sent (`Thinking level set to high.` / `Thinking disabled.`). If the level is invalid (e.g. `/thinking big`), the command is rejected with a hint and the session state is left unchanged.
- Send `/think` (or `/think:`) with no argument to see the current thinking level.
## Application by agent
- **Embedded Pi**: the resolved level is passed to the in-process Pi agent runtime.
## Verbose directives (/verbose or /v)
- Levels: `on` (minimal) | `full` | `off` (default).
- Directive-only message toggles session verbose and replies `Verbose logging enabled.` / `Verbose logging disabled.`; invalid levels return a hint without changing state.
- `/verbose off` stores an explicit session override; clear it via the Sessions UI by choosing `inherit`.
@@ -42,6 +48,7 @@ read_when:
- When verbose is `full`, tool outputs are also forwarded after completion (separate bubble, truncated to a safe length). If you toggle `/verbose on|full|off` while a run is in-flight, subsequent tool bubbles honor the new setting.
## Reasoning visibility (/reasoning)
- Levels: `on|off|stream`.
- Directive-only message toggles whether thinking blocks are shown in replies.
- When enabled, reasoning is sent as a **separate message** prefixed with `Reasoning:`.
@@ -50,13 +57,16 @@ read_when:
- Send `/reasoning` (or `/reasoning:`) with no argument to see the current reasoning level.
## Related
- Elevated mode docs live in [Elevated mode](/tools/elevated).
## Heartbeats
- Heartbeat probe body is the configured heartbeat prompt (default: `Read HEARTBEAT.md if it exists (workspace context). Follow it strictly. Do not infer or repeat old tasks from prior chats. If nothing needs attention, reply HEARTBEAT_OK.`). Inline directives in a heartbeat message apply as usual (but avoid changing session defaults from heartbeats).
- Heartbeat delivery defaults to the final payload only. To also send the separate `Reasoning:` message (when available), set `agents.defaults.heartbeat.includeReasoning: true` or per-agent `agents.list[].heartbeat.includeReasoning: true`.
## Web chat UI
- The web chat thinking selector mirrors the session's stored level from the inbound session store/config when the page loads.
- Picking another level applies only to the next message (`thinkingOnce`); after sending, the selector snaps back to the stored session level.
- To change the session default, send a `/think:<level>` directive (as before); the selector will reflect it after the next reload.

View File

@@ -28,10 +28,10 @@ These are **not** browser automation. For JS-heavy sites or logins, use the
## Choosing a search provider
| Provider | Pros | Cons | API Key |
|----------|------|------|---------|
| **Brave** (default) | Fast, structured results, free tier | Traditional search results | `BRAVE_API_KEY` |
| **Perplexity** | AI-synthesized answers, citations, real-time | Requires Perplexity or OpenRouter access | `OPENROUTER_API_KEY` or `PERPLEXITY_API_KEY` |
| Provider | Pros | Cons | API Key |
| ------------------- | -------------------------------------------- | ---------------------------------------- | -------------------------------------------- |
| **Brave** (default) | Fast, structured results, free tier | Traditional search results | `BRAVE_API_KEY` |
| **Perplexity** | AI-synthesized answers, citations, real-time | Requires Perplexity or OpenRouter access | `OPENROUTER_API_KEY` or `PERPLEXITY_API_KEY` |
See [Brave Search setup](/brave-search) and [Perplexity Sonar](/perplexity) for provider-specific details.
@@ -42,10 +42,10 @@ Set the provider in config:
tools: {
web: {
search: {
provider: "brave" // or "perplexity"
}
}
}
provider: "brave", // or "perplexity"
},
},
},
}
```
@@ -60,19 +60,19 @@ Example: switch to Perplexity Sonar (direct API):
perplexity: {
apiKey: "pplx-...",
baseUrl: "https://api.perplexity.ai",
model: "perplexity/sonar-pro"
}
}
}
}
model: "perplexity/sonar-pro",
},
},
},
},
}
```
## Getting a Brave API key
1) Create a Brave Search API account at https://brave.com/search/api/
2) In the dashboard, choose the **Data for Search** plan (not “Data for AI”) and generate an API key.
3) Run `openclaw configure --section web` to store the key in config (recommended), or set `BRAVE_API_KEY` in your environment.
1. Create a Brave Search API account at https://brave.com/search/api/
2. In the dashboard, choose the **Data for Search** plan (not “Data for AI”) and generate an API key.
3. Run `openclaw configure --section web` to store the key in config (recommended), or set `BRAVE_API_KEY` in your environment.
Brave provides a free tier plus paid plans; check the Brave API portal for the
current limits and pricing.
@@ -94,9 +94,9 @@ crypto/prepaid).
### Getting an OpenRouter API key
1) Create an account at https://openrouter.ai/
2) Add credits (supports crypto, prepaid, or credit card)
3) Generate an API key in your account settings
1. Create an account at https://openrouter.ai/
2. Add credits (supports crypto, prepaid, or credit card)
3. Generate an API key in your account settings
### Setting up Perplexity search
@@ -113,11 +113,11 @@ crypto/prepaid).
// Base URL (key-aware default if omitted)
baseUrl: "https://openrouter.ai/api/v1",
// Model (defaults to perplexity/sonar-pro)
model: "perplexity/sonar-pro"
}
}
}
}
model: "perplexity/sonar-pro",
},
},
},
},
}
```
@@ -132,11 +132,11 @@ If no base URL is set, OpenClaw chooses a default based on the API key source:
### Available Perplexity models
| Model | Description | Best for |
|-------|-------------|----------|
| `perplexity/sonar` | Fast Q&A with web search | Quick lookups |
| Model | Description | Best for |
| -------------------------------- | ------------------------------------ | ----------------- |
| `perplexity/sonar` | Fast Q&A with web search | Quick lookups |
| `perplexity/sonar-pro` (default) | Multi-step reasoning with web search | Complex questions |
| `perplexity/sonar-reasoning-pro` | Chain-of-thought analysis | Deep research |
| `perplexity/sonar-reasoning-pro` | Chain-of-thought analysis | Deep research |
## web_search
@@ -160,10 +160,10 @@ Search the web using your configured provider.
apiKey: "BRAVE_API_KEY_HERE", // optional if BRAVE_API_KEY is set
maxResults: 5,
timeoutSeconds: 30,
cacheTtlMinutes: 15
}
}
}
cacheTtlMinutes: 15,
},
},
},
}
```
@@ -184,7 +184,7 @@ await web_search({
query: "TV online schauen",
count: 10,
country: "DE",
search_lang: "de"
search_lang: "de",
});
// French search with French UI
@@ -192,13 +192,13 @@ await web_search({
query: "actualités",
country: "FR",
search_lang: "fr",
ui_lang: "fr"
ui_lang: "fr",
});
// Recent results (past week)
await web_search({
query: "TMBG interview",
freshness: "pw"
freshness: "pw",
});
```
@@ -231,11 +231,11 @@ Fetch a URL and extract readable content.
baseUrl: "https://api.firecrawl.dev",
onlyMainContent: true,
maxAgeMs: 86400000, // ms (1 day)
timeoutSeconds: 60
}
}
}
}
timeoutSeconds: 60,
},
},
},
},
}
```
@@ -246,6 +246,7 @@ Fetch a URL and extract readable content.
- `maxChars` (truncate long pages)
Notes:
- `web_fetch` uses Readability (main-content extraction) first, then Firecrawl (if configured). If both fail, the tool returns an error.
- Firecrawl requests use bot-circumvention mode and cache results by default.
- `web_fetch` sends a Chrome-like User-Agent and `Accept-Language` by default; override `userAgent` if needed.