chore: Run pnpm format:fix.
This commit is contained in:
@@ -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.
|
||||
|
||||
@@ -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 @@ You’re 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.
|
||||
|
||||
@@ -21,8 +21,8 @@ OpenClaw controls a **dedicated Chrome profile** (named `openclaw`, orange‑tin
|
||||
|
||||
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,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@@ -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 node’s own `browser.profiles` config (same as local).
|
||||
- Disable if you don’t 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 Gateway’s 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 **18800–18899** 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).
|
||||
|
||||
@@ -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 isn’t 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, you’re 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)
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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).
|
||||
|
||||
@@ -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 doesn’t)
|
||||
|
||||
- **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`).
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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`.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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` (1–10; 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 session’s 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 ping‑pong, 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
|
||||
doesn’t appear in the system prompt or the schema, the model cannot call it.
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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 can’t *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 can’t _pause and resume_ with a durable token without you inventing that runtime yourself.
|
||||
- **Determinism + auditability**: Pipelines are data, so they’re 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",
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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 it’s 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
|
||||
|
||||
|
||||
@@ -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 Homebrew’s `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 it’s bundled/installed.
|
||||
- `env`: injected **only if** the variable isn’t 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 (`&`, `<`, 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.
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -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 agent’s `agentDir`.
|
||||
- The main agent’s 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`)
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user