mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-28 01:20:41 +00:00
Merge remote-tracking branch 'origin/main' into codex/pr-12077-matrix-plugin
# Conflicts: # docs/channels/index.md # pnpm-lock.yaml
This commit is contained in:
409
docs/tools/acp-agents.md
Normal file
409
docs/tools/acp-agents.md
Normal file
@@ -0,0 +1,409 @@
|
||||
---
|
||||
summary: "Use ACP runtime sessions for Pi, Claude Code, Codex, OpenCode, Gemini CLI, and other harness agents"
|
||||
read_when:
|
||||
- Running coding harnesses through ACP
|
||||
- Setting up thread-bound ACP sessions on thread-capable channels
|
||||
- Troubleshooting ACP backend and plugin wiring
|
||||
- Operating /acp commands from chat
|
||||
title: "ACP Agents"
|
||||
---
|
||||
|
||||
# ACP agents
|
||||
|
||||
[Agent Client Protocol (ACP)](https://agentclientprotocol.com/) sessions let OpenClaw run external coding harnesses (for example Pi, Claude Code, Codex, OpenCode, and Gemini CLI) through an ACP backend plugin.
|
||||
|
||||
If you ask OpenClaw in plain language to "run this in Codex" or "start Claude Code in a thread", OpenClaw should route that request to the ACP runtime (not the native sub-agent runtime).
|
||||
|
||||
## Fast operator flow
|
||||
|
||||
Use this when you want a practical `/acp` runbook:
|
||||
|
||||
1. Spawn a session:
|
||||
- `/acp spawn codex --mode persistent --thread auto`
|
||||
2. Work in the bound thread (or target that session key explicitly).
|
||||
3. Check runtime state:
|
||||
- `/acp status`
|
||||
4. Tune runtime options as needed:
|
||||
- `/acp model <provider/model>`
|
||||
- `/acp permissions <profile>`
|
||||
- `/acp timeout <seconds>`
|
||||
5. Nudge an active session without replacing context:
|
||||
- `/acp steer tighten logging and continue`
|
||||
6. Stop work:
|
||||
- `/acp cancel` (stop current turn), or
|
||||
- `/acp close` (close session + remove bindings)
|
||||
|
||||
## Quick start for humans
|
||||
|
||||
Examples of natural requests:
|
||||
|
||||
- "Start a persistent Codex session in a thread here and keep it focused."
|
||||
- "Run this as a one-shot Claude Code ACP session and summarize the result."
|
||||
- "Use Gemini CLI for this task in a thread, then keep follow-ups in that same thread."
|
||||
|
||||
What OpenClaw should do:
|
||||
|
||||
1. Pick `runtime: "acp"`.
|
||||
2. Resolve the requested harness target (`agentId`, for example `codex`).
|
||||
3. If thread binding is requested and the current channel supports it, bind the ACP session to the thread.
|
||||
4. Route follow-up thread messages to that same ACP session until unfocused/closed/expired.
|
||||
|
||||
## ACP versus sub-agents
|
||||
|
||||
Use ACP when you want an external harness runtime. Use sub-agents when you want OpenClaw-native delegated runs.
|
||||
|
||||
| Area | ACP session | Sub-agent run |
|
||||
| ------------- | ------------------------------------- | ---------------------------------- |
|
||||
| Runtime | ACP backend plugin (for example acpx) | OpenClaw native sub-agent runtime |
|
||||
| Session key | `agent:<agentId>:acp:<uuid>` | `agent:<agentId>:subagent:<uuid>` |
|
||||
| Main commands | `/acp ...` | `/subagents ...` |
|
||||
| Spawn tool | `sessions_spawn` with `runtime:"acp"` | `sessions_spawn` (default runtime) |
|
||||
|
||||
See also [Sub-agents](/tools/subagents).
|
||||
|
||||
## Thread-bound sessions (channel-agnostic)
|
||||
|
||||
When thread bindings are enabled for a channel adapter, ACP sessions can be bound to threads:
|
||||
|
||||
- OpenClaw binds a thread to a target ACP session.
|
||||
- Follow-up messages in that thread route to the bound ACP session.
|
||||
- ACP output is delivered back to the same thread.
|
||||
- Unfocus/close/archive/idle-timeout or max-age expiry removes the binding.
|
||||
|
||||
Thread binding support is adapter-specific. If the active channel adapter does not support thread bindings, OpenClaw returns a clear unsupported/unavailable message.
|
||||
|
||||
Required feature flags for thread-bound ACP:
|
||||
|
||||
- `acp.enabled=true`
|
||||
- `acp.dispatch.enabled=true`
|
||||
- Channel-adapter ACP thread-spawn flag enabled (adapter-specific)
|
||||
- Discord: `channels.discord.threadBindings.spawnAcpSessions=true`
|
||||
|
||||
### Thread supporting channels
|
||||
|
||||
- Any channel adapter that exposes session/thread binding capability.
|
||||
- Current built-in support: Discord.
|
||||
- Plugin channels can add support through the same binding interface.
|
||||
|
||||
## Start ACP sessions (interfaces)
|
||||
|
||||
### From `sessions_spawn`
|
||||
|
||||
Use `runtime: "acp"` to start an ACP session from an agent turn or tool call.
|
||||
|
||||
```json
|
||||
{
|
||||
"task": "Open the repo and summarize failing tests",
|
||||
"runtime": "acp",
|
||||
"agentId": "codex",
|
||||
"thread": true,
|
||||
"mode": "session"
|
||||
}
|
||||
```
|
||||
|
||||
Notes:
|
||||
|
||||
- `runtime` defaults to `subagent`, so set `runtime: "acp"` explicitly for ACP sessions.
|
||||
- If `agentId` is omitted, OpenClaw uses `acp.defaultAgent` when configured.
|
||||
- `mode: "session"` requires `thread: true` to keep a persistent bound conversation.
|
||||
|
||||
Interface details:
|
||||
|
||||
- `task` (required): initial prompt sent to the ACP session.
|
||||
- `runtime` (required for ACP): must be `"acp"`.
|
||||
- `agentId` (optional): ACP target harness id. Falls back to `acp.defaultAgent` if set.
|
||||
- `thread` (optional, default `false`): request thread binding flow where supported.
|
||||
- `mode` (optional): `run` (one-shot) or `session` (persistent).
|
||||
- default is `run`
|
||||
- if `thread: true` and mode omitted, OpenClaw may default to persistent behavior per runtime path
|
||||
- `mode: "session"` requires `thread: true`
|
||||
- `cwd` (optional): requested runtime working directory (validated by backend/runtime policy).
|
||||
- `label` (optional): operator-facing label used in session/banner text.
|
||||
|
||||
### From `/acp` command
|
||||
|
||||
Use `/acp spawn` for explicit operator control from chat when needed.
|
||||
|
||||
```text
|
||||
/acp spawn codex --mode persistent --thread auto
|
||||
/acp spawn codex --mode oneshot --thread off
|
||||
/acp spawn codex --thread here
|
||||
```
|
||||
|
||||
Key flags:
|
||||
|
||||
- `--mode persistent|oneshot`
|
||||
- `--thread auto|here|off`
|
||||
- `--cwd <absolute-path>`
|
||||
- `--label <name>`
|
||||
|
||||
See [Slash Commands](/tools/slash-commands).
|
||||
|
||||
## Session target resolution
|
||||
|
||||
Most `/acp` actions accept an optional session target (`session-key`, `session-id`, or `session-label`).
|
||||
|
||||
Resolution order:
|
||||
|
||||
1. Explicit target argument (or `--session` for `/acp steer`)
|
||||
- tries key
|
||||
- then UUID-shaped session id
|
||||
- then label
|
||||
2. Current thread binding (if this conversation/thread is bound to an ACP session)
|
||||
3. Current requester session fallback
|
||||
|
||||
If no target resolves, OpenClaw returns a clear error (`Unable to resolve session target: ...`).
|
||||
|
||||
## Spawn thread modes
|
||||
|
||||
`/acp spawn` supports `--thread auto|here|off`.
|
||||
|
||||
| Mode | Behavior |
|
||||
| ------ | --------------------------------------------------------------------------------------------------- |
|
||||
| `auto` | In an active thread: bind that thread. Outside a thread: create/bind a child thread when supported. |
|
||||
| `here` | Require current active thread; fail if not in one. |
|
||||
| `off` | No binding. Session starts unbound. |
|
||||
|
||||
Notes:
|
||||
|
||||
- On non-thread binding surfaces, default behavior is effectively `off`.
|
||||
- Thread-bound spawn requires channel policy support (for Discord: `channels.discord.threadBindings.spawnAcpSessions=true`).
|
||||
|
||||
## ACP controls
|
||||
|
||||
Available command family:
|
||||
|
||||
- `/acp spawn`
|
||||
- `/acp cancel`
|
||||
- `/acp steer`
|
||||
- `/acp close`
|
||||
- `/acp status`
|
||||
- `/acp set-mode`
|
||||
- `/acp set`
|
||||
- `/acp cwd`
|
||||
- `/acp permissions`
|
||||
- `/acp timeout`
|
||||
- `/acp model`
|
||||
- `/acp reset-options`
|
||||
- `/acp sessions`
|
||||
- `/acp doctor`
|
||||
- `/acp install`
|
||||
|
||||
`/acp status` shows the effective runtime options and, when available, both runtime-level and backend-level session identifiers.
|
||||
|
||||
Some controls depend on backend capabilities. If a backend does not support a control, OpenClaw returns a clear unsupported-control error.
|
||||
|
||||
## ACP command cookbook
|
||||
|
||||
| Command | What it does | Example |
|
||||
| -------------------- | --------------------------------------------------------- | -------------------------------------------------------------- |
|
||||
| `/acp spawn` | Create ACP session; optional thread bind. | `/acp spawn codex --mode persistent --thread auto --cwd /repo` |
|
||||
| `/acp cancel` | Cancel in-flight turn for target session. | `/acp cancel agent:codex:acp:<uuid>` |
|
||||
| `/acp steer` | Send steer instruction to running session. | `/acp steer --session support inbox prioritize failing tests` |
|
||||
| `/acp close` | Close session and unbind thread targets. | `/acp close` |
|
||||
| `/acp status` | Show backend, mode, state, runtime options, capabilities. | `/acp status` |
|
||||
| `/acp set-mode` | Set runtime mode for target session. | `/acp set-mode plan` |
|
||||
| `/acp set` | Generic runtime config option write. | `/acp set model openai/gpt-5.2` |
|
||||
| `/acp cwd` | Set runtime working directory override. | `/acp cwd /Users/user/Projects/repo` |
|
||||
| `/acp permissions` | Set approval policy profile. | `/acp permissions strict` |
|
||||
| `/acp timeout` | Set runtime timeout (seconds). | `/acp timeout 120` |
|
||||
| `/acp model` | Set runtime model override. | `/acp model anthropic/claude-opus-4-5` |
|
||||
| `/acp reset-options` | Remove session runtime option overrides. | `/acp reset-options` |
|
||||
| `/acp sessions` | List recent ACP sessions from store. | `/acp sessions` |
|
||||
| `/acp doctor` | Backend health, capabilities, actionable fixes. | `/acp doctor` |
|
||||
| `/acp install` | Print deterministic install and enable steps. | `/acp install` |
|
||||
|
||||
## Runtime options mapping
|
||||
|
||||
`/acp` has convenience commands and a generic setter.
|
||||
|
||||
Equivalent operations:
|
||||
|
||||
- `/acp model <id>` maps to runtime config key `model`.
|
||||
- `/acp permissions <profile>` maps to runtime config key `approval_policy`.
|
||||
- `/acp timeout <seconds>` maps to runtime config key `timeout`.
|
||||
- `/acp cwd <path>` updates runtime cwd override directly.
|
||||
- `/acp set <key> <value>` is the generic path.
|
||||
- Special case: `key=cwd` uses the cwd override path.
|
||||
- `/acp reset-options` clears all runtime overrides for target session.
|
||||
|
||||
## acpx harness support (current)
|
||||
|
||||
Current acpx built-in harness aliases:
|
||||
|
||||
- `pi`
|
||||
- `claude`
|
||||
- `codex`
|
||||
- `opencode`
|
||||
- `gemini`
|
||||
|
||||
When OpenClaw uses the acpx backend, prefer these values for `agentId` unless your acpx config defines custom agent aliases.
|
||||
|
||||
Direct acpx CLI usage can also target arbitrary adapters via `--agent <command>`, but that raw escape hatch is an acpx CLI feature (not the normal OpenClaw `agentId` path).
|
||||
|
||||
## Required config
|
||||
|
||||
Core ACP baseline:
|
||||
|
||||
```json5
|
||||
{
|
||||
acp: {
|
||||
enabled: true,
|
||||
dispatch: { enabled: true },
|
||||
backend: "acpx",
|
||||
defaultAgent: "codex",
|
||||
allowedAgents: ["pi", "claude", "codex", "opencode", "gemini"],
|
||||
maxConcurrentSessions: 8,
|
||||
stream: {
|
||||
coalesceIdleMs: 300,
|
||||
maxChunkChars: 1200,
|
||||
},
|
||||
runtime: {
|
||||
ttlMinutes: 120,
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
Thread binding config is channel-adapter specific. Example for Discord:
|
||||
|
||||
```json5
|
||||
{
|
||||
session: {
|
||||
threadBindings: {
|
||||
enabled: true,
|
||||
idleHours: 24,
|
||||
maxAgeHours: 0,
|
||||
},
|
||||
},
|
||||
channels: {
|
||||
discord: {
|
||||
threadBindings: {
|
||||
enabled: true,
|
||||
spawnAcpSessions: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
If thread-bound ACP spawn does not work, verify the adapter feature flag first:
|
||||
|
||||
- Discord: `channels.discord.threadBindings.spawnAcpSessions=true`
|
||||
|
||||
See [Configuration Reference](/gateway/configuration-reference).
|
||||
|
||||
## Plugin setup for acpx backend
|
||||
|
||||
Install and enable plugin:
|
||||
|
||||
```bash
|
||||
openclaw plugins install @openclaw/acpx
|
||||
openclaw config set plugins.entries.acpx.enabled true
|
||||
```
|
||||
|
||||
Local workspace install during development:
|
||||
|
||||
```bash
|
||||
openclaw plugins install ./extensions/acpx
|
||||
```
|
||||
|
||||
Then verify backend health:
|
||||
|
||||
```text
|
||||
/acp doctor
|
||||
```
|
||||
|
||||
### acpx command and version configuration
|
||||
|
||||
By default, `@openclaw/acpx` uses the plugin-local pinned binary:
|
||||
|
||||
1. Command defaults to `extensions/acpx/node_modules/.bin/acpx`.
|
||||
2. Expected version defaults to the extension pin.
|
||||
3. Startup registers ACP backend immediately as not-ready.
|
||||
4. A background ensure job verifies `acpx --version`.
|
||||
5. If the plugin-local binary is missing or mismatched, it runs:
|
||||
`npm install --omit=dev --no-save acpx@<pinned>` and re-verifies.
|
||||
|
||||
You can override command/version in plugin config:
|
||||
|
||||
```json
|
||||
{
|
||||
"plugins": {
|
||||
"entries": {
|
||||
"acpx": {
|
||||
"enabled": true,
|
||||
"config": {
|
||||
"command": "../acpx/dist/cli.js",
|
||||
"expectedVersion": "any"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Notes:
|
||||
|
||||
- `command` accepts an absolute path, relative path, or command name (`acpx`).
|
||||
- Relative paths resolve from OpenClaw workspace directory.
|
||||
- `expectedVersion: "any"` disables strict version matching.
|
||||
- When `command` points to a custom binary/path, plugin-local auto-install is disabled.
|
||||
- OpenClaw startup remains non-blocking while the backend health check runs.
|
||||
|
||||
See [Plugins](/tools/plugin).
|
||||
|
||||
## Permission configuration
|
||||
|
||||
ACP sessions run non-interactively — there is no TTY to approve or deny file-write and shell-exec permission prompts. The acpx plugin provides two config keys that control how permissions are handled:
|
||||
|
||||
### `permissionMode`
|
||||
|
||||
Controls which operations the harness agent can perform without prompting.
|
||||
|
||||
| Value | Behavior |
|
||||
| --------------- | --------------------------------------------------------- |
|
||||
| `approve-all` | Auto-approve all file writes and shell commands. |
|
||||
| `approve-reads` | Auto-approve reads only; writes and exec require prompts. |
|
||||
| `deny-all` | Deny all permission prompts. |
|
||||
|
||||
### `nonInteractivePermissions`
|
||||
|
||||
Controls what happens when a permission prompt would be shown but no interactive TTY is available (which is always the case for ACP sessions).
|
||||
|
||||
| Value | Behavior |
|
||||
| ------ | ----------------------------------------------------------------- |
|
||||
| `fail` | Abort the session with `AcpRuntimeError`. **(default)** |
|
||||
| `deny` | Silently deny the permission and continue (graceful degradation). |
|
||||
|
||||
### Configuration
|
||||
|
||||
Set via plugin config:
|
||||
|
||||
```bash
|
||||
openclaw config set plugins.entries.acpx.config.permissionMode approve-all
|
||||
openclaw config set plugins.entries.acpx.config.nonInteractivePermissions fail
|
||||
```
|
||||
|
||||
Restart the gateway after changing these values.
|
||||
|
||||
> **Important:** OpenClaw currently defaults to `permissionMode=approve-reads` and `nonInteractivePermissions=fail`. In non-interactive ACP sessions, any write or exec that triggers a permission prompt can fail with `AcpRuntimeError: Permission prompt unavailable in non-interactive mode`.
|
||||
>
|
||||
> If you need to restrict permissions, set `nonInteractivePermissions` to `deny` so sessions degrade gracefully instead of crashing.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
| Symptom | Likely cause | Fix |
|
||||
| ------------------------------------------------------------------------ | ------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `ACP runtime backend is not configured` | Backend plugin missing or disabled. | Install and enable backend plugin, then run `/acp doctor`. |
|
||||
| `ACP is disabled by policy (acp.enabled=false)` | ACP globally disabled. | Set `acp.enabled=true`. |
|
||||
| `ACP dispatch is disabled by policy (acp.dispatch.enabled=false)` | Dispatch from normal thread messages disabled. | Set `acp.dispatch.enabled=true`. |
|
||||
| `ACP agent "<id>" is not allowed by policy` | Agent not in allowlist. | Use allowed `agentId` or update `acp.allowedAgents`. |
|
||||
| `Unable to resolve session target: ...` | Bad key/id/label token. | Run `/acp sessions`, copy exact key/label, retry. |
|
||||
| `--thread here requires running /acp spawn inside an active ... thread` | `--thread here` used outside a thread context. | Move to target thread or use `--thread auto`/`off`. |
|
||||
| `Only <user-id> can rebind this thread.` | Another user owns thread binding. | Rebind as owner or use a different thread. |
|
||||
| `Thread bindings are unavailable for <channel>.` | Adapter lacks thread binding capability. | Use `--thread off` or move to supported adapter/channel. |
|
||||
| Missing ACP metadata for bound session | Stale/deleted ACP session metadata. | Recreate with `/acp spawn`, then rebind/focus thread. |
|
||||
| `AcpRuntimeError: Permission prompt unavailable in non-interactive mode` | `permissionMode` blocks writes/exec in non-interactive ACP session. | Set `plugins.entries.acpx.config.permissionMode` to `approve-all` and restart gateway. See [Permission configuration](#permission-configuration). |
|
||||
| ACP session fails early with little output | Permission prompts are blocked by `permissionMode`/`nonInteractivePermissions`. | Check gateway logs for `AcpRuntimeError`. For full permissions, set `permissionMode=approve-all`; for graceful degradation, set `nonInteractivePermissions=deny`. |
|
||||
| ACP session stalls indefinitely after completing work | Harness process finished but ACP session did not report completion. | Monitor with `ps aux \| grep acpx`; kill stale processes manually. |
|
||||
358
docs/tools/diffs.md
Normal file
358
docs/tools/diffs.md
Normal file
@@ -0,0 +1,358 @@
|
||||
---
|
||||
title: "Diffs"
|
||||
summary: "Read-only diff viewer and file renderer for agents (optional plugin tool)"
|
||||
description: "Use the optional Diffs plugin to render before and after text or unified patches as a gateway-hosted diff view, a file (PNG or PDF), or both."
|
||||
read_when:
|
||||
- You want agents to show code or markdown edits as diffs
|
||||
- You want a canvas-ready viewer URL or a rendered diff file
|
||||
- You need controlled, temporary diff artifacts with secure defaults
|
||||
---
|
||||
|
||||
# Diffs
|
||||
|
||||
`diffs` is an optional plugin tool that turns change content into a read-only diff artifact for agents.
|
||||
|
||||
It accepts either:
|
||||
|
||||
- `before` and `after` text
|
||||
- a unified `patch`
|
||||
|
||||
It can return:
|
||||
|
||||
- a gateway viewer URL for canvas presentation
|
||||
- a rendered file path (PNG or PDF) for message delivery
|
||||
- both outputs in one call
|
||||
|
||||
## Quick start
|
||||
|
||||
1. Enable the plugin.
|
||||
2. Call `diffs` with `mode: "view"` for canvas-first flows.
|
||||
3. Call `diffs` with `mode: "file"` for chat file delivery flows.
|
||||
4. Call `diffs` with `mode: "both"` when you need both artifacts.
|
||||
|
||||
## Enable the plugin
|
||||
|
||||
```json5
|
||||
{
|
||||
plugins: {
|
||||
entries: {
|
||||
diffs: {
|
||||
enabled: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
## Typical agent workflow
|
||||
|
||||
1. Agent calls `diffs`.
|
||||
2. Agent reads `details` fields.
|
||||
3. Agent either:
|
||||
- opens `details.viewerUrl` with `canvas present`
|
||||
- sends `details.filePath` with `message` using `path` or `filePath`
|
||||
- does both
|
||||
|
||||
## Input examples
|
||||
|
||||
Before and after:
|
||||
|
||||
```json
|
||||
{
|
||||
"before": "# Hello\n\nOne",
|
||||
"after": "# Hello\n\nTwo",
|
||||
"path": "docs/example.md",
|
||||
"mode": "view"
|
||||
}
|
||||
```
|
||||
|
||||
Patch:
|
||||
|
||||
```json
|
||||
{
|
||||
"patch": "diff --git a/src/example.ts b/src/example.ts\n--- a/src/example.ts\n+++ b/src/example.ts\n@@ -1 +1 @@\n-const x = 1;\n+const x = 2;\n",
|
||||
"mode": "both"
|
||||
}
|
||||
```
|
||||
|
||||
## Tool input reference
|
||||
|
||||
All fields are optional unless noted:
|
||||
|
||||
- `before` (`string`): original text. Required with `after` when `patch` is omitted.
|
||||
- `after` (`string`): updated text. Required with `before` when `patch` is omitted.
|
||||
- `patch` (`string`): unified diff text. Mutually exclusive with `before` and `after`.
|
||||
- `path` (`string`): display filename for before and after mode.
|
||||
- `lang` (`string`): language override hint for before and after mode.
|
||||
- `title` (`string`): viewer title override.
|
||||
- `mode` (`"view" | "file" | "both"`): output mode. Defaults to plugin default `defaults.mode`.
|
||||
- `theme` (`"light" | "dark"`): viewer theme. Defaults to plugin default `defaults.theme`.
|
||||
- `layout` (`"unified" | "split"`): diff layout. Defaults to plugin default `defaults.layout`.
|
||||
- `expandUnchanged` (`boolean`): expand unchanged sections when full context is available. Per-call option only (not a plugin default key).
|
||||
- `fileFormat` (`"png" | "pdf"`): rendered file format. Defaults to plugin default `defaults.fileFormat`.
|
||||
- `fileQuality` (`"standard" | "hq" | "print"`): quality preset for PNG or PDF rendering.
|
||||
- `fileScale` (`number`): device scale override (`1`-`4`).
|
||||
- `fileMaxWidth` (`number`): max render width in CSS pixels (`640`-`2400`).
|
||||
- `ttlSeconds` (`number`): viewer artifact TTL in seconds. Default 1800, max 21600.
|
||||
- `baseUrl` (`string`): viewer URL origin override. Must be `http` or `https`, no query/hash.
|
||||
|
||||
Validation and limits:
|
||||
|
||||
- `before` and `after` each max 512 KiB.
|
||||
- `patch` max 2 MiB.
|
||||
- `path` max 2048 bytes.
|
||||
- `lang` max 128 bytes.
|
||||
- `title` max 1024 bytes.
|
||||
- Patch complexity cap: max 128 files and 120000 total lines.
|
||||
- `patch` and `before` or `after` together are rejected.
|
||||
- Rendered file safety limits (apply to PNG and PDF):
|
||||
- `fileQuality: "standard"`: max 8 MP (8,000,000 rendered pixels).
|
||||
- `fileQuality: "hq"`: max 14 MP (14,000,000 rendered pixels).
|
||||
- `fileQuality: "print"`: max 24 MP (24,000,000 rendered pixels).
|
||||
- PDF also has a max of 50 pages.
|
||||
|
||||
## Output details contract
|
||||
|
||||
The tool returns structured metadata under `details`.
|
||||
|
||||
Shared fields for modes that create a viewer:
|
||||
|
||||
- `artifactId`
|
||||
- `viewerUrl`
|
||||
- `viewerPath`
|
||||
- `title`
|
||||
- `expiresAt`
|
||||
- `inputKind`
|
||||
- `fileCount`
|
||||
- `mode`
|
||||
|
||||
File fields when PNG or PDF is rendered:
|
||||
|
||||
- `filePath`
|
||||
- `path` (same value as `filePath`, for message tool compatibility)
|
||||
- `fileBytes`
|
||||
- `fileFormat`
|
||||
- `fileQuality`
|
||||
- `fileScale`
|
||||
- `fileMaxWidth`
|
||||
|
||||
Mode behavior summary:
|
||||
|
||||
- `mode: "view"`: viewer fields only.
|
||||
- `mode: "file"`: file fields only, no viewer artifact.
|
||||
- `mode: "both"`: viewer fields plus file fields. If file rendering fails, viewer still returns with `fileError`.
|
||||
|
||||
## Collapsed unchanged sections
|
||||
|
||||
- The viewer can show rows like `N unmodified lines`.
|
||||
- Expand controls on those rows are conditional and not guaranteed for every input kind.
|
||||
- Expand controls appear when the rendered diff has expandable context data, which is typical for before and after input.
|
||||
- For many unified patch inputs, omitted context bodies are not available in the parsed patch hunks, so the row can appear without expand controls. This is expected behavior.
|
||||
- `expandUnchanged` applies only when expandable context exists.
|
||||
|
||||
## Plugin defaults
|
||||
|
||||
Set plugin-wide defaults in `~/.openclaw/openclaw.json`:
|
||||
|
||||
```json5
|
||||
{
|
||||
plugins: {
|
||||
entries: {
|
||||
diffs: {
|
||||
enabled: true,
|
||||
config: {
|
||||
defaults: {
|
||||
fontFamily: "Fira Code",
|
||||
fontSize: 15,
|
||||
lineSpacing: 1.6,
|
||||
layout: "unified",
|
||||
showLineNumbers: true,
|
||||
diffIndicators: "bars",
|
||||
wordWrap: true,
|
||||
background: true,
|
||||
theme: "dark",
|
||||
fileFormat: "png",
|
||||
fileQuality: "standard",
|
||||
fileScale: 2,
|
||||
fileMaxWidth: 960,
|
||||
mode: "both",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
Supported defaults:
|
||||
|
||||
- `fontFamily`
|
||||
- `fontSize`
|
||||
- `lineSpacing`
|
||||
- `layout`
|
||||
- `showLineNumbers`
|
||||
- `diffIndicators`
|
||||
- `wordWrap`
|
||||
- `background`
|
||||
- `theme`
|
||||
- `fileFormat`
|
||||
- `fileQuality`
|
||||
- `fileScale`
|
||||
- `fileMaxWidth`
|
||||
- `mode`
|
||||
|
||||
Explicit tool parameters override these defaults.
|
||||
|
||||
## Security config
|
||||
|
||||
- `security.allowRemoteViewer` (`boolean`, default `false`)
|
||||
- `false`: non-loopback requests to viewer routes are denied.
|
||||
- `true`: remote viewers are allowed if tokenized path is valid.
|
||||
|
||||
Example:
|
||||
|
||||
```json5
|
||||
{
|
||||
plugins: {
|
||||
entries: {
|
||||
diffs: {
|
||||
enabled: true,
|
||||
config: {
|
||||
security: {
|
||||
allowRemoteViewer: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
## Artifact lifecycle and storage
|
||||
|
||||
- Artifacts are stored under the temp subfolder: `$TMPDIR/openclaw-diffs`.
|
||||
- Viewer artifact metadata contains:
|
||||
- random artifact ID (20 hex chars)
|
||||
- random token (48 hex chars)
|
||||
- `createdAt` and `expiresAt`
|
||||
- stored `viewer.html` path
|
||||
- Default viewer TTL is 30 minutes when not specified.
|
||||
- Maximum accepted viewer TTL is 6 hours.
|
||||
- Cleanup runs opportunistically after artifact creation.
|
||||
- Expired artifacts are deleted.
|
||||
- Fallback cleanup removes stale folders older than 24 hours when metadata is missing.
|
||||
|
||||
## Viewer URL and network behavior
|
||||
|
||||
Viewer route:
|
||||
|
||||
- `/plugins/diffs/view/{artifactId}/{token}`
|
||||
|
||||
Viewer assets:
|
||||
|
||||
- `/plugins/diffs/assets/viewer.js`
|
||||
- `/plugins/diffs/assets/viewer-runtime.js`
|
||||
|
||||
URL construction behavior:
|
||||
|
||||
- If `baseUrl` is provided, it is used after strict validation.
|
||||
- Without `baseUrl`, viewer URL defaults to loopback `127.0.0.1`.
|
||||
- If gateway bind mode is `custom` and `gateway.customBindHost` is set, that host is used.
|
||||
|
||||
`baseUrl` rules:
|
||||
|
||||
- Must be `http://` or `https://`.
|
||||
- Query and hash are rejected.
|
||||
- Origin plus optional base path is allowed.
|
||||
|
||||
## Security model
|
||||
|
||||
Viewer hardening:
|
||||
|
||||
- Loopback-only by default.
|
||||
- Tokenized viewer paths with strict ID and token validation.
|
||||
- Viewer response CSP:
|
||||
- `default-src 'none'`
|
||||
- scripts and assets only from self
|
||||
- no outbound `connect-src`
|
||||
- Remote miss throttling when remote access is enabled:
|
||||
- 40 failures per 60 seconds
|
||||
- 60 second lockout (`429 Too Many Requests`)
|
||||
|
||||
File rendering hardening:
|
||||
|
||||
- Screenshot browser request routing is deny-by-default.
|
||||
- Only local viewer assets from `http://127.0.0.1/plugins/diffs/assets/*` are allowed.
|
||||
- External network requests are blocked.
|
||||
|
||||
## Browser requirements for file mode
|
||||
|
||||
`mode: "file"` and `mode: "both"` need a Chromium-compatible browser.
|
||||
|
||||
Resolution order:
|
||||
|
||||
1. `browser.executablePath` in OpenClaw config.
|
||||
2. Environment variables:
|
||||
- `OPENCLAW_BROWSER_EXECUTABLE_PATH`
|
||||
- `BROWSER_EXECUTABLE_PATH`
|
||||
- `PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH`
|
||||
3. Platform command/path discovery fallback.
|
||||
|
||||
Common failure text:
|
||||
|
||||
- `Diff PNG/PDF rendering requires a Chromium-compatible browser...`
|
||||
|
||||
Fix by installing Chrome, Chromium, Edge, or Brave, or setting one of the executable path options above.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
Input validation errors:
|
||||
|
||||
- `Provide patch or both before and after text.`
|
||||
- Include both `before` and `after`, or provide `patch`.
|
||||
- `Provide either patch or before/after input, not both.`
|
||||
- Do not mix input modes.
|
||||
- `Invalid baseUrl: ...`
|
||||
- Use `http(s)` origin with optional path, no query/hash.
|
||||
- `{field} exceeds maximum size (...)`
|
||||
- Reduce payload size.
|
||||
- Large patch rejection
|
||||
- Reduce patch file count or total lines.
|
||||
|
||||
Viewer accessibility issues:
|
||||
|
||||
- Viewer URL resolves to `127.0.0.1` by default.
|
||||
- For remote access scenarios, either:
|
||||
- pass `baseUrl` per tool call, or
|
||||
- use `gateway.bind=custom` and `gateway.customBindHost`
|
||||
- Enable `security.allowRemoteViewer` only when you intend external viewer access.
|
||||
|
||||
Unmodified-lines row has no expand button:
|
||||
|
||||
- This can happen for patch input when the patch does not carry expandable context.
|
||||
- This is expected and does not indicate a viewer failure.
|
||||
|
||||
Artifact not found:
|
||||
|
||||
- Artifact expired due TTL.
|
||||
- Token or path changed.
|
||||
- Cleanup removed stale data.
|
||||
|
||||
## Operational guidance
|
||||
|
||||
- Prefer `mode: "view"` for local interactive reviews in canvas.
|
||||
- Prefer `mode: "file"` for outbound chat channels that need an attachment.
|
||||
- Keep `allowRemoteViewer` disabled unless your deployment requires remote viewer URLs.
|
||||
- Set explicit short `ttlSeconds` for sensitive diffs.
|
||||
- Avoid sending secrets in diff input when not required.
|
||||
- If your channel compresses images aggressively (for example Telegram or WhatsApp), prefer PDF output (`fileFormat: "pdf"`).
|
||||
|
||||
Diff rendering engine:
|
||||
|
||||
- Powered by [Diffs](https://diffs.com).
|
||||
|
||||
## Related docs
|
||||
|
||||
- [Tools overview](/tools)
|
||||
- [Plugins](/tools/plugin)
|
||||
- [Browser](/tools/browser)
|
||||
@@ -252,6 +252,10 @@ When a prompt is required, the gateway broadcasts `exec.approval.requested` to o
|
||||
The Control UI and macOS app resolve it via `exec.approval.resolve`, then the gateway forwards the
|
||||
approved request to the node host.
|
||||
|
||||
For `host=node`, approval requests include a canonical `systemRunPlan` payload. The gateway uses
|
||||
that plan as the authoritative command/cwd/session context when forwarding approved `system.run`
|
||||
requests.
|
||||
|
||||
When approvals are required, the exec tool returns immediately with an approval id. Use that id to
|
||||
correlate later system events (`Exec finished` / `Exec denied`). If no decision arrives before the
|
||||
timeout, the request is treated as an approval timeout and surfaced as a denial reason.
|
||||
|
||||
@@ -40,6 +40,7 @@ Notes:
|
||||
then falls back to Windows PowerShell 5.1.
|
||||
- Host execution (`gateway`/`node`) rejects `env.PATH` and loader overrides (`LD_*`/`DYLD_*`) to
|
||||
prevent binary hijacking or injected code.
|
||||
- OpenClaw sets `OPENCLAW_SHELL=exec` in the spawned command environment (including PTY and sandbox execution) so shell/profile rules can detect exec-tool context.
|
||||
- Important: sandboxing is **off by default**. If sandboxing is off and `host=sandbox` is explicitly
|
||||
configured/requested, exec now fails closed instead of silently running on the gateway host.
|
||||
Enable sandboxing or use `host=gateway` with approvals.
|
||||
|
||||
@@ -174,6 +174,7 @@ 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).
|
||||
- [Diffs](/tools/diffs): read-only diff viewer and PNG or PDF file renderer for before/after text or unified patches.
|
||||
|
||||
## Tool inventory
|
||||
|
||||
@@ -354,8 +355,9 @@ Core actions:
|
||||
- `pending`, `approve`, `reject` (pairing)
|
||||
- `notify` (macOS `system.notify`)
|
||||
- `run` (macOS `system.run`)
|
||||
- `camera_snap`, `camera_clip`, `screen_record`
|
||||
- `location_get`
|
||||
- `camera_list`, `camera_snap`, `camera_clip`, `screen_record`
|
||||
- `location_get`, `notifications_list`, `notifications_action`
|
||||
- `device_status`, `device_info`, `device_permissions`, `device_health`
|
||||
|
||||
Notes:
|
||||
|
||||
@@ -395,6 +397,26 @@ 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).
|
||||
|
||||
### `pdf`
|
||||
|
||||
Analyze one or more PDF documents.
|
||||
|
||||
Core parameters:
|
||||
|
||||
- `pdf` (single path or URL)
|
||||
- `pdfs` (multiple paths or URLs, up to 10)
|
||||
- `prompt` (optional, defaults to "Analyze this PDF document.")
|
||||
- `pages` (optional page range like `1-5` or `1,3,7-9`)
|
||||
- `model` (optional model override)
|
||||
- `maxBytesMb` (optional size cap)
|
||||
|
||||
Notes:
|
||||
|
||||
- Native PDF provider mode is supported for Anthropic and Google models.
|
||||
- Non-native models use PDF extraction fallback, text first, then rasterized page images when needed.
|
||||
- `pages` filtering is only supported in extraction fallback mode. Native providers return a clear error when `pages` is set.
|
||||
- Defaults are configurable via `agents.defaults.pdfModel`, `agents.defaults.pdfMaxBytesMb`, and `agents.defaults.pdfMaxPages`.
|
||||
|
||||
### `message`
|
||||
|
||||
Send messages and channel actions across Discord/Google Chat/Slack/Telegram/WhatsApp/Signal/iMessage/MS Teams.
|
||||
@@ -464,7 +486,7 @@ 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)
|
||||
- `sessions_spawn`: `task`, `label?`, `agentId?`, `model?`, `thinking?`, `runTimeoutSeconds?`, `thread?`, `mode?`, `cleanup?`
|
||||
- `sessions_spawn`: `task`, `label?`, `runtime?`, `agentId?`, `model?`, `thinking?`, `cwd?`, `runTimeoutSeconds?`, `thread?`, `mode?`, `cleanup?`, `sandbox?`, `attachments?`, `attachAs?`
|
||||
- `session_status`: `sessionKey?` (default current; accepts `sessionId`), `model?` (`default` clears override)
|
||||
|
||||
Notes:
|
||||
@@ -474,6 +496,7 @@ Notes:
|
||||
- Session targeting is controlled by `tools.sessions.visibility` (default `tree`: current session + spawned subagent sessions). If you run a shared agent for multiple users, consider setting `tools.sessions.visibility: "self"` to prevent cross-session browsing.
|
||||
- `sessions_send` waits for final completion when `timeoutSeconds > 0`.
|
||||
- Delivery/announce happens after completion and is best-effort; `status: "ok"` confirms the agent run finished, not that the announce was delivered.
|
||||
- `sessions_spawn` supports `runtime: "subagent" | "acp"` (`subagent` default). For ACP runtime behavior, see [ACP Agents](/tools/acp-agents).
|
||||
- `sessions_spawn` starts a sub-agent run and posts an announce reply back to the requester chat.
|
||||
- Supports one-shot mode (`mode: "run"`) and persistent thread-bound mode (`mode: "session"` with `thread: true`).
|
||||
- If `thread: true` and `mode` is omitted, mode defaults to `session`.
|
||||
@@ -483,6 +506,9 @@ Notes:
|
||||
- Reply format includes `Status`, `Result`, and compact stats.
|
||||
- `Result` is the assistant completion text; if missing, the latest `toolResult` is used as fallback.
|
||||
- Manual completion-mode spawns send directly first, with queue fallback and retry on transient failures (`status: "ok"` means run finished, not that announce delivered).
|
||||
- `sessions_spawn` supports inline file attachments for subagent runtime only (ACP rejects them). Each attachment has `name`, `content`, and optional `encoding` (`utf8` or `base64`) and `mimeType`. Files are materialized into the child workspace at `.openclaw/attachments/<uuid>/` with a `.manifest.json` metadata file. The tool returns a receipt with `count`, `totalBytes`, per file `sha256`, and `relDir`. Attachment content is automatically redacted from transcript persistence.
|
||||
- Configure limits via `tools.sessions_spawn.attachments` (`enabled`, `maxTotalBytes`, `maxFiles`, `maxFileBytes`, `retainOnSessionKeep`).
|
||||
- `attachAs.mountPath` is a reserved hint for future mount implementations.
|
||||
- `sessions_spawn` is non-blocking and returns `status: "accepted"` immediately.
|
||||
- `sessions_send` runs a reply‑back ping‑pong (reply `REPLY_SKIP` to stop; max turns via `session.agentToAgent.maxPingPongTurns`, 0–5).
|
||||
- After the ping‑pong, the target agent runs an **announce step**; reply `ANNOUNCE_SKIP` to suppress the announcement.
|
||||
|
||||
@@ -26,7 +26,7 @@ All skills-related configuration lives under `skills` in `~/.openclaw/openclaw.j
|
||||
entries: {
|
||||
"nano-banana-pro": {
|
||||
enabled: true,
|
||||
apiKey: "GEMINI_KEY_HERE",
|
||||
apiKey: { source: "env", provider: "default", id: "GEMINI_API_KEY" }, // or plaintext string
|
||||
env: {
|
||||
GEMINI_API_KEY: "GEMINI_KEY_HERE",
|
||||
},
|
||||
@@ -56,6 +56,7 @@ 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.
|
||||
Supports plaintext string or SecretRef object (`{ source, provider, id }`).
|
||||
|
||||
## Notes
|
||||
|
||||
|
||||
@@ -195,7 +195,7 @@ Bundled/managed skills can be toggled and supplied with env values:
|
||||
entries: {
|
||||
"nano-banana-pro": {
|
||||
enabled: true,
|
||||
apiKey: "GEMINI_KEY_HERE",
|
||||
apiKey: { source: "env", provider: "default", id: "GEMINI_API_KEY" }, // or plaintext string
|
||||
env: {
|
||||
GEMINI_API_KEY: "GEMINI_KEY_HERE",
|
||||
},
|
||||
@@ -221,6 +221,7 @@ 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`.
|
||||
Supports plaintext string or SecretRef object (`{ source, provider, id }`).
|
||||
- `config`: optional bag for custom per-skill fields; custom keys must live here.
|
||||
- `allowBundled`: optional allowlist for **bundled** skills only. If set, only
|
||||
bundled skills in the list are eligible (managed/workspace skills unaffected).
|
||||
|
||||
@@ -78,8 +78,10 @@ Text + native (when enabled):
|
||||
- `/context [list|detail|json]` (explain “context”; `detail` shows per-file + per-tool + per-skill + system prompt size)
|
||||
- `/export-session [path]` (alias: `/export`) (export current session to HTML with full system prompt)
|
||||
- `/whoami` (show your sender id; alias: `/id`)
|
||||
- `/session ttl <duration|off>` (manage session-level settings, such as TTL)
|
||||
- `/session idle <duration|off>` (manage inactivity auto-unfocus for focused thread bindings)
|
||||
- `/session max-age <duration|off>` (manage hard max-age auto-unfocus for focused thread bindings)
|
||||
- `/subagents list|kill|log|info|send|steer|spawn` (inspect, control, or spawn sub-agent runs for the current session)
|
||||
- `/acp spawn|cancel|steer|close|status|set-mode|set|cwd|permissions|timeout|model|reset-options|doctor|install|sessions` (inspect and control ACP runtime sessions)
|
||||
- `/agents` (list thread-bound agents for this session)
|
||||
- `/focus <target>` (Discord: bind this thread, or a new thread, to a session/subagent target)
|
||||
- `/unfocus` (Discord: remove the current thread binding)
|
||||
@@ -124,7 +126,8 @@ Notes:
|
||||
- `/usage` controls the per-response usage footer; `/usage cost` prints a local cost summary from OpenClaw session logs.
|
||||
- `/restart` is enabled by default; set `commands.restart: false` to disable it.
|
||||
- Discord-only native command: `/vc join|leave|status` controls voice channels (requires `channels.discord.voice` and native commands; not available as text).
|
||||
- Discord thread-binding commands (`/focus`, `/unfocus`, `/agents`, `/session ttl`) require effective thread bindings to be enabled (`session.threadBindings.enabled` and/or `channels.discord.threadBindings.enabled`).
|
||||
- Discord thread-binding commands (`/focus`, `/unfocus`, `/agents`, `/session idle`, `/session max-age`) require effective thread bindings to be enabled (`session.threadBindings.enabled` and/or `channels.discord.threadBindings.enabled`).
|
||||
- ACP command reference and runtime behavior: [ACP Agents](/tools/acp-agents).
|
||||
- `/verbose` is meant for debugging and extra visibility; keep it **off** in normal use.
|
||||
- Tool failure summaries are still shown when relevant, but detailed failure text is only included when `/verbose` is `on` or `full`.
|
||||
- `/reasoning` (and `/verbose`) are risky in group settings: they may reveal internal reasoning or tool output you did not intend to expose. Prefer leaving them off, especially in group chats.
|
||||
@@ -216,3 +219,4 @@ Notes:
|
||||
- Telegram: `telegram:slash:<userId>` (targets the chat session via `CommandTargetSessionKey`)
|
||||
- **`/stop`** targets the active chat session so it can abort the current run.
|
||||
- **Slack:** `channels.slack.slashCommand` is still supported for a single `/openclaw`-style command. If you enable `commands.native`, you must create one Slack slash command per built-in command (same names as `/help`). Command argument menus for Slack are delivered as ephemeral Block Kit buttons.
|
||||
- Slack native exception: register `/agentstatus` (not `/status`) because Slack reserves `/status`. Text `/status` still works in Slack messages.
|
||||
|
||||
@@ -30,7 +30,8 @@ These commands work on channels that support persistent thread bindings. See **T
|
||||
- `/focus <subagent-label|session-key|session-id|session-label>`
|
||||
- `/unfocus`
|
||||
- `/agents`
|
||||
- `/session ttl <duration|off>`
|
||||
- `/session idle <duration|off>`
|
||||
- `/session max-age <duration|off>`
|
||||
|
||||
`/subagents info` shows run metadata (status, timestamps, session id, transcript path, cleanup).
|
||||
|
||||
@@ -44,13 +45,15 @@ These commands work on channels that support persistent thread bindings. See **T
|
||||
- OpenClaw tries direct `agent` delivery first with a stable idempotency key.
|
||||
- If direct delivery fails, it falls back to queue routing.
|
||||
- If queue routing is still not available, the announce is retried with a short exponential backoff before final give-up.
|
||||
- The completion message is a system message and includes:
|
||||
- The completion handoff to the requester session is runtime-generated internal context (not user-authored text) and includes:
|
||||
- `Result` (`assistant` reply text, or latest `toolResult` if the assistant reply is empty)
|
||||
- `Status` (`completed successfully` / `failed` / `timed out`)
|
||||
- `Status` (`completed successfully` / `failed` / `timed out` / `unknown`)
|
||||
- compact runtime/token stats
|
||||
- a delivery instruction telling the requester agent to rewrite in normal assistant voice (not forward raw internal metadata)
|
||||
- `--model` and `--thinking` override defaults for that specific run.
|
||||
- Use `info`/`log` to inspect details and output after completion.
|
||||
- `/subagents spawn` is one-shot mode (`mode: "run"`). For persistent thread-bound sessions, use `sessions_spawn` with `thread: true` and `mode: "session"`.
|
||||
- For ACP harness sessions (Codex, Claude Code, Gemini CLI), use `sessions_spawn` with `runtime: "acp"` and see [ACP Agents](/tools/acp-agents).
|
||||
|
||||
Primary goals:
|
||||
|
||||
@@ -87,6 +90,8 @@ Tool params:
|
||||
- if `thread: true` and `mode` omitted, default becomes `session`
|
||||
- `mode: "session"` requires `thread: true`
|
||||
- `cleanup?` (`delete|keep`, default `keep`)
|
||||
- `sandbox?` (`inherit|require`, default `inherit`; `require` rejects spawn unless target child runtime is sandboxed)
|
||||
- `sessions_spawn` does **not** accept channel-delivery params (`target`, `channel`, `to`, `threadId`, `replyTo`, `transport`). For delivery, use `message`/`sessions_send` from the spawned run.
|
||||
|
||||
## Thread-bound sessions
|
||||
|
||||
@@ -94,14 +99,14 @@ When thread bindings are enabled for a channel, a sub-agent can stay bound to a
|
||||
|
||||
### Thread supporting channels
|
||||
|
||||
- Discord (currently the only supported channel): supports persistent thread-bound subagent sessions (`sessions_spawn` with `thread: true`), manual thread controls (`/focus`, `/unfocus`, `/agents`, `/session ttl`), and adapter keys `channels.discord.threadBindings.enabled`, `channels.discord.threadBindings.ttlHours`, and `channels.discord.threadBindings.spawnSubagentSessions`.
|
||||
- Discord (currently the only supported channel): supports persistent thread-bound subagent sessions (`sessions_spawn` with `thread: true`), manual thread controls (`/focus`, `/unfocus`, `/agents`, `/session idle`, `/session max-age`), and adapter keys `channels.discord.threadBindings.enabled`, `channels.discord.threadBindings.idleHours`, `channels.discord.threadBindings.maxAgeHours`, and `channels.discord.threadBindings.spawnSubagentSessions`.
|
||||
|
||||
Quick flow:
|
||||
|
||||
1. Spawn with `sessions_spawn` using `thread: true` (and optionally `mode: "session"`).
|
||||
2. OpenClaw creates or binds a thread to that session target in the active channel.
|
||||
3. Replies and follow-up messages in that thread route to the bound session.
|
||||
4. Use `/session ttl` to inspect/update auto-unfocus TTL.
|
||||
4. Use `/session idle` to inspect/update inactivity auto-unfocus and `/session max-age` to control the hard cap.
|
||||
5. Use `/unfocus` to detach manually.
|
||||
|
||||
Manual controls:
|
||||
@@ -109,11 +114,11 @@ Manual controls:
|
||||
- `/focus <target>` binds the current thread (or creates one) to a sub-agent/session target.
|
||||
- `/unfocus` removes the binding for the current bound thread.
|
||||
- `/agents` lists active runs and binding state (`thread:<id>` or `unbound`).
|
||||
- `/session ttl` only works for focused bound threads.
|
||||
- `/session idle` and `/session max-age` only work for focused bound threads.
|
||||
|
||||
Config switches:
|
||||
|
||||
- Global default: `session.threadBindings.enabled`, `session.threadBindings.ttlHours`
|
||||
- Global default: `session.threadBindings.enabled`, `session.threadBindings.idleHours`, `session.threadBindings.maxAgeHours`
|
||||
- Channel override and spawn auto-bind keys are adapter-specific. See **Thread supporting channels** above.
|
||||
|
||||
See [Configuration Reference](/gateway/configuration-reference) and [Slash commands](/tools/slash-commands) for current adapter details.
|
||||
@@ -121,6 +126,7 @@ See [Configuration Reference](/gateway/configuration-reference) and [Slash comma
|
||||
Allowlist:
|
||||
|
||||
- `agents.list[].subagents.allowAgents`: list of agent ids that can be targeted via `agentId` (`["*"]` to allow any). Default: only the requester agent.
|
||||
- Sandbox inheritance guard: if the requester session is sandboxed, `sessions_spawn` rejects targets that would run unsandboxed.
|
||||
|
||||
Discovery:
|
||||
|
||||
@@ -210,10 +216,13 @@ Sub-agents report back via an announce step:
|
||||
- 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`).
|
||||
- Announce replies preserve thread/topic routing when available on channel adapters.
|
||||
- Announce messages are normalized to a stable template:
|
||||
- `Status:` derived from the run outcome (`success`, `error`, `timeout`, or `unknown`).
|
||||
- `Result:` the summary content from the announce step (or `(not available)` if missing).
|
||||
- `Notes:` error details and other useful context.
|
||||
- Announce context is normalized to a stable internal event block:
|
||||
- source (`subagent` or `cron`)
|
||||
- child session key/id
|
||||
- announce type + task label
|
||||
- status line derived from runtime outcome (`success`, `error`, `timeout`, or `unknown`)
|
||||
- result content from the announce step (or `(no output)` if missing)
|
||||
- a follow-up instruction describing when to reply vs. stay silent
|
||||
- `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):
|
||||
@@ -222,6 +231,7 @@ Announce payloads include a stats line at the end (even when wrapped):
|
||||
- Token usage (input/output/total)
|
||||
- Estimated cost when model pricing is configured (`models.providers.*.models[].cost`)
|
||||
- `sessionKey`, `sessionId`, and transcript path (so the main agent can fetch history via `sessions_history` or inspect the file on disk)
|
||||
- Internal metadata is meant for orchestration only; user-facing replies should be rewritten in normal assistant voice.
|
||||
|
||||
## Tool Policy (sub-agent tools)
|
||||
|
||||
|
||||
@@ -10,15 +10,17 @@ title: "Thinking Levels"
|
||||
## 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)
|
||||
- Levels (aliases): `off | minimal | low | medium | high | xhigh | adaptive`
|
||||
- minimal → “think”
|
||||
- low → “think hard”
|
||||
- medium → “think harder”
|
||||
- high → “ultrathink” (max budget)
|
||||
- xhigh → “ultrathink+” (GPT-5.2 + Codex models only)
|
||||
- adaptive → provider-managed adaptive reasoning budget (supported for Anthropic Claude 4.6 model family)
|
||||
- `x-high`, `x_high`, `extra-high`, `extra high`, and `extra_high` map to `xhigh`.
|
||||
- `highest`, `max` map to `high`.
|
||||
- Provider notes:
|
||||
- Anthropic Claude 4.6 models default to `adaptive` when no explicit thinking level is set.
|
||||
- Z.AI (`zai/*`) only supports binary thinking (`on`/`off`). Any non-`off` level is treated as `on` (mapped to `low`).
|
||||
|
||||
## Resolution order
|
||||
@@ -26,7 +28,7 @@ title: "Thinking Levels"
|
||||
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.
|
||||
4. Fallback: `adaptive` for Anthropic Claude 4.6 models, `low` for other reasoning-capable models, `off` otherwise.
|
||||
|
||||
## Setting a session default
|
||||
|
||||
|
||||
@@ -194,7 +194,7 @@ For a gateway install, put it in `~/.openclaw/.env`.
|
||||
- Citation URLs from Gemini grounding are automatically resolved from Google's
|
||||
redirect URLs to direct URLs.
|
||||
- Redirect resolution uses the SSRF guard path (HEAD + redirect checks + http/https validation) before returning the final citation URL.
|
||||
- This redirect resolver follows the trusted-network model (private/internal networks allowed by default) to match Gateway operator trust assumptions.
|
||||
- Redirect resolution uses strict SSRF defaults, so redirects to private/internal targets are blocked.
|
||||
- The default model (`gemini-2.5-flash`) is fast and cost-effective.
|
||||
Any Gemini model that supports grounding can be used.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user