mirror of
https://github.com/openclaw/openclaw.git
synced 2026-06-25 16:53:02 +08:00
Compare commits
311 Commits
docs/codex
...
fix/model-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b8ebe38e28 | ||
|
|
cac483733a | ||
|
|
c0b8bdcc91 | ||
|
|
e205625f4a | ||
|
|
6bc0dc8fb6 | ||
|
|
3ffd944e6b | ||
|
|
926068b14f | ||
|
|
5d7d5ca2a9 | ||
|
|
7418adf875 | ||
|
|
a16f8dff15 | ||
|
|
7a63dd3f12 | ||
|
|
f07b00de66 | ||
|
|
3bc99bc70e | ||
|
|
6fea42fc2d | ||
|
|
9439d633ef | ||
|
|
c2bffc6033 | ||
|
|
94275f13fb | ||
|
|
1042b893f6 | ||
|
|
a155b84cda | ||
|
|
8207567cba | ||
|
|
62adf6349d | ||
|
|
d7e2939791 | ||
|
|
2495886287 | ||
|
|
67a2b187b7 | ||
|
|
80608ae26c | ||
|
|
1cfebfe0e1 | ||
|
|
860dad268d | ||
|
|
ec3dbd22a4 | ||
|
|
0c70cb3b9c | ||
|
|
cba92f893d | ||
|
|
129f548c44 | ||
|
|
95db5966a0 | ||
|
|
7330a0c7e0 | ||
|
|
342583348d | ||
|
|
5738201b22 | ||
|
|
712b7c6637 | ||
|
|
6b4f6ca20c | ||
|
|
bbef1c5557 | ||
|
|
da36c1967f | ||
|
|
042c031c5c | ||
|
|
f191dd3d53 | ||
|
|
5b0ee04c0d | ||
|
|
3eb7605318 | ||
|
|
59e2825274 | ||
|
|
e35e6e1d15 | ||
|
|
78a431ed22 | ||
|
|
a08a2e381f | ||
|
|
1981622b92 | ||
|
|
560b04d4c6 | ||
|
|
cc57d56b92 | ||
|
|
c9f2403547 | ||
|
|
660cea680a | ||
|
|
11cffb2300 | ||
|
|
afc0c32bd0 | ||
|
|
b2352c3e24 | ||
|
|
51c11cfd90 | ||
|
|
769ab4a91c | ||
|
|
c15edc3641 | ||
|
|
f6dcf968ca | ||
|
|
3de44fe593 | ||
|
|
11ad1919ed | ||
|
|
5deef28b7a | ||
|
|
11abe5ec49 | ||
|
|
f8573fe9c2 | ||
|
|
0340321c12 | ||
|
|
2fe7c6fed4 | ||
|
|
f738b73107 | ||
|
|
4d1ee3a73e | ||
|
|
90877e0d42 | ||
|
|
3df9fd4354 | ||
|
|
06d46869f8 | ||
|
|
f4ffed8482 | ||
|
|
27b348b3e5 | ||
|
|
1cf79803d7 | ||
|
|
c1ad8076a3 | ||
|
|
32163e0e98 | ||
|
|
16c7de085c | ||
|
|
d9c5479029 | ||
|
|
12f7de3ef3 | ||
|
|
7e49cc87f9 | ||
|
|
d3e66e36f6 | ||
|
|
d5880ae6a5 | ||
|
|
23c7a7d557 | ||
|
|
cbfc21badb | ||
|
|
58f54801b7 | ||
|
|
c05791f619 | ||
|
|
f7a426d516 | ||
|
|
7ba13fbc2b | ||
|
|
bda391e4c2 | ||
|
|
bbe0234720 | ||
|
|
5dfc1b90e1 | ||
|
|
1b997bebd0 | ||
|
|
27c61ed0d4 | ||
|
|
7a958d920c | ||
|
|
3a64aa49a9 | ||
|
|
aef0bb4915 | ||
|
|
6b618f0635 | ||
|
|
f3bcea8732 | ||
|
|
2b45a112cb | ||
|
|
2c701ab296 | ||
|
|
7d1891e6e6 | ||
|
|
4f4288e3b5 | ||
|
|
50667db297 | ||
|
|
1ff07245f3 | ||
|
|
7130e56f87 | ||
|
|
a3ae336c51 | ||
|
|
d3d9b5738f | ||
|
|
5ca6b3568c | ||
|
|
34896839ba | ||
|
|
a6aa151653 | ||
|
|
8f64cd3e4d | ||
|
|
8866544ffe | ||
|
|
60f7a59f5e | ||
|
|
aa3a5f9ff7 | ||
|
|
55c45307d0 | ||
|
|
577ff767fa | ||
|
|
608c08fc54 | ||
|
|
0783090da0 | ||
|
|
04a54cf54e | ||
|
|
6944d7025d | ||
|
|
68b9ad4205 | ||
|
|
ebd7f19a3b | ||
|
|
11fa1d2dc7 | ||
|
|
9faa9d33e6 | ||
|
|
9b7f6250f4 | ||
|
|
2e2a134489 | ||
|
|
4514691300 | ||
|
|
fcaf6a23dd | ||
|
|
9ece33c505 | ||
|
|
320d52a23e | ||
|
|
3814dc860b | ||
|
|
f3c37a946c | ||
|
|
daed93dd30 | ||
|
|
a8edf29bd0 | ||
|
|
01bc49c88c | ||
|
|
4013c65853 | ||
|
|
ed51963c47 | ||
|
|
b453293349 | ||
|
|
83370f0021 | ||
|
|
d38ed0831d | ||
|
|
934dd5b3a7 | ||
|
|
0e7250f37b | ||
|
|
e5f55dd024 | ||
|
|
6831579267 | ||
|
|
b7b66a6047 | ||
|
|
56fe2aab9c | ||
|
|
b5e5f2cede | ||
|
|
c138368040 | ||
|
|
d85dc46e37 | ||
|
|
a79c40a789 | ||
|
|
f03252aaf9 | ||
|
|
cead2ea4b1 | ||
|
|
447105a278 | ||
|
|
028b6c9b13 | ||
|
|
40be5ad581 | ||
|
|
4630ce3d9e | ||
|
|
cc92699ff7 | ||
|
|
6a61cb73c5 | ||
|
|
a52b50ef3c | ||
|
|
0a3da5cd8a | ||
|
|
38caa6832d | ||
|
|
665cc3d537 | ||
|
|
c1b9aa7d96 | ||
|
|
a437666a37 | ||
|
|
aa21d4ea7e | ||
|
|
1e8dc2389e | ||
|
|
69196670b7 | ||
|
|
661f11b947 | ||
|
|
bcdacfa1b3 | ||
|
|
33c0cd1378 | ||
|
|
81666e586a | ||
|
|
4e4aeacae4 | ||
|
|
50e36983bb | ||
|
|
f353a61bab | ||
|
|
e30837910b | ||
|
|
512d3d2287 | ||
|
|
28fc03c386 | ||
|
|
9f8b400630 | ||
|
|
a02a54ff13 | ||
|
|
5b3952e857 | ||
|
|
8ba22ca0dc | ||
|
|
41c5ffc5d5 | ||
|
|
925d11d890 | ||
|
|
8fade9df27 | ||
|
|
48b9452c07 | ||
|
|
bc195b8f53 | ||
|
|
972c7112a2 | ||
|
|
02d7215005 | ||
|
|
ed6b487e20 | ||
|
|
5dd3c37fce | ||
|
|
3d8e6a3aa3 | ||
|
|
0baa8c1763 | ||
|
|
bd1b8448a5 | ||
|
|
b7fba2100f | ||
|
|
f85806b6d7 | ||
|
|
cb4fc58547 | ||
|
|
564f820efa | ||
|
|
fa139b4fca | ||
|
|
ad0fcf9143 | ||
|
|
37c37eecfb | ||
|
|
b588b5a230 | ||
|
|
d29eaeafc1 | ||
|
|
7d9172d5e0 | ||
|
|
bcea5e75eb | ||
|
|
7ac35b4f69 | ||
|
|
350d322180 | ||
|
|
bae7b54a85 | ||
|
|
a53fea3905 | ||
|
|
c3138e372c | ||
|
|
bff212822c | ||
|
|
73288c20bd | ||
|
|
6c509d8d4b | ||
|
|
cc28989b4b | ||
|
|
4f4d2ef1df | ||
|
|
e94c0bf515 | ||
|
|
aca92b2906 | ||
|
|
acbceb8a76 | ||
|
|
b0d2003fe6 | ||
|
|
99d8f699aa | ||
|
|
0ad058a9cb | ||
|
|
5f702b464b | ||
|
|
a62a7f2945 | ||
|
|
d32fdcebc1 | ||
|
|
d91f6a05c6 | ||
|
|
9f4ef6162d | ||
|
|
d4e93e791b | ||
|
|
171322644d | ||
|
|
799a42bd13 | ||
|
|
b2840b93c8 | ||
|
|
6f80082028 | ||
|
|
0304d0ce4e | ||
|
|
c45e4c3cf4 | ||
|
|
1e83357abe | ||
|
|
01e4824fd3 | ||
|
|
960f3b07b1 | ||
|
|
63653f51d8 | ||
|
|
da129727c5 | ||
|
|
864de4a2e9 | ||
|
|
f7157958de | ||
|
|
9755c8a05f | ||
|
|
95f6697bd7 | ||
|
|
b98a6a46fb | ||
|
|
bfa6708c03 | ||
|
|
24bf56ce60 | ||
|
|
9d445f4d68 | ||
|
|
a29233c9af | ||
|
|
da6c29b3d9 | ||
|
|
d3fe591853 | ||
|
|
2e45218ae8 | ||
|
|
9941393c7a | ||
|
|
6f04eee2a1 | ||
|
|
4737a86071 | ||
|
|
3254e961e9 | ||
|
|
29d0e930bb | ||
|
|
a50aef82ba | ||
|
|
959dedb7cf | ||
|
|
a903438707 | ||
|
|
bfc9cb92c5 | ||
|
|
22f23fa5ab | ||
|
|
cb2c36b049 | ||
|
|
569290c36d | ||
|
|
098557623f | ||
|
|
ed6094b301 | ||
|
|
d3dd61f2c5 | ||
|
|
c971c58fc7 | ||
|
|
4d7c4b3298 | ||
|
|
84fc00afda | ||
|
|
a7c1376b20 | ||
|
|
deb300d905 | ||
|
|
1e24d95c54 | ||
|
|
5aa5c4eff2 | ||
|
|
1a002b021f | ||
|
|
c7ee5d8ecf | ||
|
|
51186d2725 | ||
|
|
ac063568d3 | ||
|
|
d717dbba51 | ||
|
|
18c98316f7 | ||
|
|
e2c3225636 | ||
|
|
7acaebeaac | ||
|
|
5b34082106 | ||
|
|
b1d0c14d38 | ||
|
|
76a4c167f7 | ||
|
|
c1dfaef0a0 | ||
|
|
38bb4fefb9 | ||
|
|
c21c8f3059 | ||
|
|
627c19c5cb | ||
|
|
53aac30f51 | ||
|
|
eb6e1245ac | ||
|
|
2fb9c7e3e5 | ||
|
|
ed286078d6 | ||
|
|
88fb6518c2 | ||
|
|
ae609e0249 | ||
|
|
977a4b24af | ||
|
|
86fa8eeb68 | ||
|
|
867714ca45 | ||
|
|
55389f4be2 | ||
|
|
248baba54b | ||
|
|
88b53b7f0a | ||
|
|
9ac52e0737 | ||
|
|
031c3b22de | ||
|
|
a42bd94b21 | ||
|
|
b5779b992f | ||
|
|
e0d3256311 | ||
|
|
69566e43cb | ||
|
|
553162c998 | ||
|
|
5d0887574b | ||
|
|
ffa5f4514f | ||
|
|
e93113db09 | ||
|
|
34f7a93c04 | ||
|
|
3a5e535bed | ||
|
|
7d47183736 |
@@ -49,6 +49,66 @@ pnpm openclaw qa suite \
|
||||
5. If the user wants to watch the live UI, find the current `openclaw-qa` listen port and report `http://127.0.0.1:<port>`.
|
||||
6. If a scenario fails, fix the product or harness root cause, then rerun the full lane.
|
||||
|
||||
## QA credentials and 1Password
|
||||
|
||||
- Use `op` only inside `tmux` for QA secret lookup in this repo.
|
||||
- Quick auth check inside tmux:
|
||||
|
||||
```bash
|
||||
op account list
|
||||
```
|
||||
|
||||
- Direct Telegram npm live test secrets currently live in 1Password item:
|
||||
- vault: `OpenClaw`
|
||||
- item: `Telegram E2E`
|
||||
- That item is the first place to look for:
|
||||
- `OPENCLAW_QA_TELEGRAM_DRIVER_BOT_TOKEN`
|
||||
- `OPENCLAW_QA_TELEGRAM_SUT_BOT_TOKEN`
|
||||
- `OPENCLAW_QA_PROVIDER_MODE`
|
||||
- `OPENCLAW_NPM_TELEGRAM_PACKAGE_SPEC`
|
||||
- Convex QA secrets currently live in 1Password items:
|
||||
- vault: `OpenClaw`
|
||||
- item: `OPENCLAW_QA_CONVEX_SITE_URL`
|
||||
- item: `OPENCLAW_QA_CONVEX_SECRET_MAINTAINER`
|
||||
- item: `OPENCLAW_QA_CONVEX_SECRET_CI`
|
||||
- Additional related notes/login items seen during QA credential work:
|
||||
- vault: `Private`
|
||||
- items: `OPENCLAW QA`, `Convex`, `Telegram`
|
||||
- If a required value is missing from those notes:
|
||||
- do not guess
|
||||
- ask the maintainer/operator for the current value or the current 1Password item name
|
||||
- for Telegram direct runs, `OPENCLAW_QA_TELEGRAM_GROUP_ID` may be stored separately from `Telegram E2E`
|
||||
- for Convex runs, the leased Telegram credential should provide the Telegram group id and bot tokens together; do not require a separate `OPENCLAW_QA_TELEGRAM_GROUP_ID`
|
||||
- for Convex runs, prefer `OpenClaw/OPENCLAW_QA_CONVEX_SITE_URL`; if that is stale or unclear, ask for the active pool URL before running
|
||||
- Prefer direct Telegram envs for the npm Telegram Docker lane when available:
|
||||
|
||||
```bash
|
||||
OPENCLAW_QA_TELEGRAM_GROUP_ID="..." \
|
||||
OPENCLAW_QA_TELEGRAM_DRIVER_BOT_TOKEN="..." \
|
||||
OPENCLAW_QA_TELEGRAM_SUT_BOT_TOKEN="..." \
|
||||
OPENCLAW_QA_PROVIDER_MODE="mock-openai" \
|
||||
OPENCLAW_NPM_TELEGRAM_PACKAGE_SPEC="openclaw@beta" \
|
||||
pnpm test:docker:npm-telegram-live
|
||||
```
|
||||
|
||||
- Prefer Convex mode when the goal is stable shared QA infra:
|
||||
- round-robin credential leasing
|
||||
- thinner wrapper for channel-specific setup
|
||||
- CLI/admin flows around the pooled credentials
|
||||
- Live npm Telegram Docker lane note:
|
||||
- `scripts/e2e/npm-telegram-live-runner.ts` reads `OPENCLAW_NPM_TELEGRAM_PROVIDER_MODE`
|
||||
- do not assume `OPENCLAW_QA_PROVIDER_MODE` is consumed by that wrapper
|
||||
- if a 1Password note only gives `OPENCLAW_QA_PROVIDER_MODE`, map it explicitly to `OPENCLAW_NPM_TELEGRAM_PROVIDER_MODE` before running the Docker lane
|
||||
- Verified live shape:
|
||||
- Convex mode can pass the real Docker lane without direct Telegram env vars
|
||||
- leased Telegram payload includes the group id coupled to the driver/SUT tokens
|
||||
- a real run of `pnpm test:docker:npm-telegram-live` passed with:
|
||||
- `OPENCLAW_QA_CREDENTIAL_SOURCE=convex`
|
||||
- `OPENCLAW_QA_CREDENTIAL_ROLE=maintainer`
|
||||
- `OPENCLAW_QA_CONVEX_SITE_URL`
|
||||
- `OPENCLAW_QA_CONVEX_SECRET_MAINTAINER`
|
||||
- `OPENCLAW_NPM_TELEGRAM_PROVIDER_MODE=mock-openai`
|
||||
|
||||
## Character evals
|
||||
|
||||
Use `qa character-eval` for style/persona/vibe checks across multiple live models.
|
||||
|
||||
@@ -279,8 +279,20 @@ node --import tsx scripts/openclaw-npm-postpublish-verify.ts <published-version>
|
||||
- `node --import tsx scripts/openclaw-npm-postpublish-verify.ts <beta-version>`
|
||||
- install/update smoke against the published beta channel
|
||||
- Docker install/update coverage that exercises the published beta package
|
||||
- published npm Telegram proof: dispatch Actions > `NPM Telegram Beta E2E`
|
||||
from `main` with `package_spec=openclaw@<beta-version>` and
|
||||
`provider_mode=mock-openai`, approve `npm-release`, and require success.
|
||||
This is the default button path for installed-package onboarding,
|
||||
Telegram setup, and real Telegram E2E against the published npm package.
|
||||
Use the local `pnpm test:docker:npm-telegram-live` lane with the matching
|
||||
`OPENCLAW_NPM_TELEGRAM_PACKAGE_SPEC` and Convex CI env only as a fallback
|
||||
or debugging path.
|
||||
- Parallels published beta install/update coverage with both OpenAI and
|
||||
Anthropic provider keys available
|
||||
- Parallels install/update proof must keep plugin installs enabled unless the
|
||||
operator explicitly scopes a harness-only isolation check; a lane that
|
||||
disables bundled plugin installs is not valid plugin/dependency release
|
||||
evidence.
|
||||
- targeted QA reruns only for areas touched by fixes after the full pre-npm
|
||||
roster, unless the operator requests the full QA roster again. If the fix
|
||||
touches live channel QA, credential plumbing, Matrix, Telegram, or the QA
|
||||
@@ -329,10 +341,17 @@ node --import tsx scripts/openclaw-npm-postpublish-verify.ts <published-version>
|
||||
`openclaw/releases-private/.github/workflows/openclaw-npm-dist-tags.yml`
|
||||
workflow because `npm dist-tag` management needs `NPM_TOKEN`, while the
|
||||
public npm release workflow stays OIDC-only.
|
||||
- Prefer fixing the private workflow token path over any local 1Password
|
||||
fallback. The desired setup is a granular npm token stored as the private
|
||||
repo's `NPM_TOKEN` secret, scoped to the `openclaw` package with read/write
|
||||
and 2FA bypass for automation.
|
||||
- If the private dist-tag workflow cannot promote because `NPM_TOKEN` is absent
|
||||
or stale, use the local tmux + 1Password fallback:
|
||||
- Start or reuse a tmux session so interactive `npm login` and OTP prompts
|
||||
are observable and recoverable.
|
||||
- Hard rule: never run `op` directly in the main agent shell during release
|
||||
work. Any 1Password CLI use must happen inside that tmux session so prompts
|
||||
and alerts are contained and observable.
|
||||
- Use the 1Password item `op://Private/Npmjs` for npm credentials and OTP.
|
||||
Do not print passwords, tokens, or OTPs to the transcript; send them through
|
||||
tmux buffers, env vars scoped to the tmux command, or `expect` with
|
||||
@@ -502,9 +521,11 @@ node --import tsx scripts/openclaw-npm-postpublish-verify.ts <published-version>
|
||||
23. Run the post-published beta verification roster. If any lane fails after
|
||||
the beta tag/package is pushed or published, fix, commit/push/pull,
|
||||
increment to the next beta tag, and restart at the full pre-npm beta test
|
||||
roster for the new beta. If a pre-npm lane fails before any tag/package
|
||||
leaves the machine, fix and rerun the same intended beta attempt. Repeat up
|
||||
to the operator's authorized beta-attempt limit, normally 4.
|
||||
roster for the new beta. The roster includes the manual Actions >
|
||||
`NPM Telegram Beta E2E` workflow against the exact published beta package.
|
||||
If a pre-npm lane fails before any tag/package leaves the machine, fix and
|
||||
rerun the same intended beta attempt. Repeat up to the operator's
|
||||
authorized beta-attempt limit, normally 4.
|
||||
24. Announce the beta/stable release on Discord best-effort using Peter's bot
|
||||
token from `.profile`.
|
||||
25. If the operator requested beta only, stop after beta verification and the
|
||||
|
||||
@@ -8,6 +8,14 @@
|
||||
|
||||
.bun-cache
|
||||
.bun
|
||||
.artifacts
|
||||
**/.artifacts
|
||||
.local
|
||||
**/.local
|
||||
.pi
|
||||
**/.pi
|
||||
__openclaw_vitest__
|
||||
**/__openclaw_vitest__
|
||||
.tmp
|
||||
**/.tmp
|
||||
.DS_Store
|
||||
@@ -38,6 +46,9 @@ docs/.generated
|
||||
*.log
|
||||
tmp
|
||||
**/tmp
|
||||
dist-runtime
|
||||
**/dist-runtime
|
||||
openclaw-path-alias-*
|
||||
|
||||
# build artifacts
|
||||
dist
|
||||
|
||||
9
.github/labeler.yml
vendored
9
.github/labeler.yml
vendored
@@ -29,6 +29,11 @@
|
||||
- any-glob-to-any-file:
|
||||
- "extensions/google-meet/**"
|
||||
- "docs/plugins/google-meet.md"
|
||||
"plugin: bonjour":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- "extensions/bonjour/**"
|
||||
- "docs/gateway/bonjour.md"
|
||||
"channel: imessage":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
@@ -382,3 +387,7 @@
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- "extensions/fal/**"
|
||||
"extensions: gradium":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- "extensions/gradium/**"
|
||||
|
||||
26
.github/workflows/ci.yml
vendored
26
.github/workflows/ci.yml
vendored
@@ -3,6 +3,9 @@ name: CI
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
paths-ignore:
|
||||
- "**/*.md"
|
||||
- "docs/**"
|
||||
pull_request:
|
||||
types: [opened, reopened, synchronize, ready_for_review, converted_to_draft]
|
||||
|
||||
@@ -23,7 +26,7 @@ jobs:
|
||||
permissions:
|
||||
contents: read
|
||||
if: github.event_name != 'pull_request' || !github.event.pull_request.draft
|
||||
runs-on: ubuntu-24.04
|
||||
runs-on: ${{ github.repository == 'openclaw/openclaw' && 'blacksmith-4vcpu-ubuntu-2404' || 'ubuntu-24.04' }}
|
||||
timeout-minutes: 20
|
||||
outputs:
|
||||
docs_only: ${{ steps.manifest.outputs.docs_only }}
|
||||
@@ -194,6 +197,11 @@ jobs:
|
||||
}).map((shard) => ({
|
||||
check_name: shard.checkName,
|
||||
extensions_csv: shard.extensionIds.join(","),
|
||||
runner: isCanonicalRepository && [0, 3, 4].includes(shard.index)
|
||||
? "blacksmith-8vcpu-ubuntu-2404"
|
||||
: isCanonicalRepository
|
||||
? "blacksmith-4vcpu-ubuntu-2404"
|
||||
: "ubuntu-24.04",
|
||||
shard_index: shard.index + 1,
|
||||
task: "extensions-batch",
|
||||
}))
|
||||
@@ -208,6 +216,7 @@ jobs:
|
||||
configs: shard.configs,
|
||||
includePatterns: shard.includePatterns,
|
||||
requires_dist: shard.requiresDist,
|
||||
runner: shard.runner,
|
||||
}))
|
||||
: [];
|
||||
const nodeTestNonDistShards = nodeTestShards.filter((shard) => !shard.requires_dist);
|
||||
@@ -913,7 +922,7 @@ jobs:
|
||||
name: ${{ matrix.check_name }}
|
||||
needs: [preflight]
|
||||
if: needs.preflight.outputs.run_checks_fast == 'true'
|
||||
runs-on: ${{ github.repository == 'openclaw/openclaw' && 'blacksmith-8vcpu-ubuntu-2404' || 'ubuntu-24.04' }}
|
||||
runs-on: ${{ matrix.runner }}
|
||||
timeout-minutes: 60
|
||||
strategy:
|
||||
fail-fast: false
|
||||
@@ -1036,7 +1045,7 @@ jobs:
|
||||
name: checks-node-compat-node22
|
||||
needs: [preflight]
|
||||
if: needs.preflight.outputs.run_node == 'true' && github.event_name == 'push'
|
||||
runs-on: ${{ github.repository == 'openclaw/openclaw' && 'blacksmith-8vcpu-ubuntu-2404' || 'ubuntu-24.04' }}
|
||||
runs-on: ${{ github.repository == 'openclaw/openclaw' && 'blacksmith-4vcpu-ubuntu-2404' || 'ubuntu-24.04' }}
|
||||
timeout-minutes: 60
|
||||
steps:
|
||||
- name: Checkout
|
||||
@@ -1113,10 +1122,7 @@ jobs:
|
||||
name: ${{ matrix.check_name }}
|
||||
needs: [preflight]
|
||||
if: needs.preflight.outputs.run_checks_node_core_nondist == 'true'
|
||||
# Keep core shards on GitHub-hosted runners. The Blacksmith pool is already
|
||||
# occupied by build and extension shards; queueing these shards there hides
|
||||
# actual test-speed improvements behind runner wait time.
|
||||
runs-on: ubuntu-24.04
|
||||
runs-on: ${{ github.repository == 'openclaw/openclaw' && (matrix.runner || 'ubuntu-24.04') || 'ubuntu-24.04' }}
|
||||
timeout-minutes: 60
|
||||
strategy:
|
||||
fail-fast: false
|
||||
@@ -1372,16 +1378,16 @@ jobs:
|
||||
runner: ubuntu-24.04
|
||||
- check_name: check-prod-types
|
||||
task: prod-types
|
||||
runner: ubuntu-24.04
|
||||
runner: blacksmith-4vcpu-ubuntu-2404
|
||||
- check_name: check-lint
|
||||
task: lint
|
||||
runner: ubuntu-24.04
|
||||
runner: blacksmith-8vcpu-ubuntu-2404
|
||||
- check_name: check-policy-guards
|
||||
task: policy-guards
|
||||
runner: ubuntu-24.04
|
||||
- check_name: check-test-types
|
||||
task: test-types
|
||||
runner: ubuntu-24.04
|
||||
runner: blacksmith-4vcpu-ubuntu-2404
|
||||
- check_name: check-strict-smoke
|
||||
task: strict-smoke
|
||||
runner: ubuntu-24.04
|
||||
|
||||
29
.github/workflows/docs-sync-publish.yml
vendored
29
.github/workflows/docs-sync-publish.yml
vendored
@@ -63,18 +63,43 @@ jobs:
|
||||
working-directory: publish
|
||||
run: |
|
||||
set -euo pipefail
|
||||
remote_source_sha() {
|
||||
git show refs/remotes/origin/main:.openclaw-sync/source.json 2>/dev/null \
|
||||
| node -e 'const fs = require("node:fs"); try { const data = JSON.parse(fs.readFileSync(0, "utf8")); if (data.sha) process.stdout.write(data.sha); } catch {}' \
|
||||
|| true
|
||||
}
|
||||
|
||||
skip_stale_source() {
|
||||
current_source_sha="$(remote_source_sha)"
|
||||
if [ -z "$current_source_sha" ] || [ "$current_source_sha" = "$GITHUB_SHA" ]; then
|
||||
return
|
||||
fi
|
||||
|
||||
if git -C "$GITHUB_WORKSPACE" merge-base --is-ancestor "$GITHUB_SHA" "$current_source_sha"; then
|
||||
echo "Skipping stale publish sync for $GITHUB_SHA; origin/main already mirrors $current_source_sha."
|
||||
exit 0
|
||||
fi
|
||||
}
|
||||
|
||||
if git diff --quiet -- docs .openclaw-sync; then
|
||||
echo "No publish-repo changes."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if git fetch origin main:refs/remotes/origin/main; then
|
||||
skip_stale_source
|
||||
fi
|
||||
|
||||
git config user.name "openclaw-docs-sync[bot]"
|
||||
git config user.email "openclaw-docs-sync[bot]@users.noreply.github.com"
|
||||
git add docs .openclaw-sync
|
||||
git commit -m "chore(sync): mirror docs from $GITHUB_REPOSITORY@$GITHUB_SHA"
|
||||
for attempt in 1 2 3 4 5; do
|
||||
if git fetch origin main && git rebase origin/main && git push origin HEAD:main; then
|
||||
exit 0
|
||||
if git fetch origin main:refs/remotes/origin/main; then
|
||||
skip_stale_source
|
||||
if git rebase -X theirs origin/main && git push origin HEAD:main; then
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
git rebase --abort >/dev/null 2>&1 || true
|
||||
echo "Publish sync attempt ${attempt} failed; retrying."
|
||||
|
||||
39
.github/workflows/docs.yml
vendored
Normal file
39
.github/workflows/docs.yml
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
name: Docs
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
paths:
|
||||
- "**/*.md"
|
||||
- "docs/**"
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: ${{ format('{0}-{1}', github.workflow, github.ref) }}
|
||||
cancel-in-progress: true
|
||||
|
||||
env:
|
||||
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: "true"
|
||||
|
||||
jobs:
|
||||
docs:
|
||||
runs-on: ubuntu-24.04
|
||||
timeout-minutes: 20
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 1
|
||||
fetch-tags: false
|
||||
persist-credentials: false
|
||||
submodules: false
|
||||
|
||||
- name: Setup Node environment
|
||||
uses: ./.github/actions/setup-node-env
|
||||
with:
|
||||
install-bun: "false"
|
||||
|
||||
- name: Check docs
|
||||
run: pnpm check:docs
|
||||
68
.github/workflows/install-smoke.yml
vendored
68
.github/workflows/install-smoke.yml
vendored
@@ -1,10 +1,6 @@
|
||||
name: Install Smoke
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
pull_request:
|
||||
types: [opened, reopened, synchronize, ready_for_review, converted_to_draft]
|
||||
schedule:
|
||||
- cron: "17 3 * * *"
|
||||
workflow_dispatch:
|
||||
@@ -30,7 +26,7 @@ permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.event_name == 'workflow_dispatch' && format('{0}-manual-{1}', github.workflow, github.run_id) || github.event_name == 'pull_request' && format('{0}-{1}', github.workflow, github.event.pull_request.number) || format('{0}-{1}', github.workflow, github.ref) }}
|
||||
group: ${{ github.event_name == 'workflow_dispatch' && format('{0}-manual-{1}', github.workflow, github.run_id) || format('{0}-{1}', github.workflow, github.ref) }}
|
||||
cancel-in-progress: true
|
||||
|
||||
env:
|
||||
@@ -38,7 +34,6 @@ env:
|
||||
|
||||
jobs:
|
||||
preflight:
|
||||
if: github.event_name != 'pull_request' || !github.event.pull_request.draft
|
||||
runs-on: ubuntu-24.04
|
||||
outputs:
|
||||
docs_only: ${{ steps.manifest.outputs.docs_only }}
|
||||
@@ -56,67 +51,19 @@ jobs:
|
||||
persist-credentials: false
|
||||
submodules: false
|
||||
|
||||
- name: Ensure preflight base commit
|
||||
if: github.event_name != 'workflow_dispatch' && github.event_name != 'schedule' && github.event_name != 'workflow_call'
|
||||
uses: ./.github/actions/ensure-base-commit
|
||||
with:
|
||||
base-sha: ${{ github.event_name == 'push' && github.event.before || github.event.pull_request.base.sha }}
|
||||
fetch-ref: ${{ github.event_name == 'push' && github.ref_name || github.event.pull_request.base.ref }}
|
||||
|
||||
- name: Detect docs-only changes
|
||||
id: docs_scope
|
||||
uses: ./.github/actions/detect-docs-changes
|
||||
|
||||
- name: Detect changed smoke scope
|
||||
id: changed_scope
|
||||
if: github.event_name != 'workflow_dispatch' && github.event_name != 'schedule' && github.event_name != 'workflow_call' && steps.docs_scope.outputs.docs_only != 'true'
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
if [ "${{ github.event_name }}" = "push" ]; then
|
||||
BASE="${{ github.event.before }}"
|
||||
else
|
||||
BASE="${{ github.event.pull_request.base.sha }}"
|
||||
fi
|
||||
|
||||
node scripts/ci-changed-scope.mjs --base "$BASE" --head HEAD
|
||||
|
||||
- name: Build install-smoke CI manifest
|
||||
id: manifest
|
||||
env:
|
||||
OPENCLAW_CI_DOCS_ONLY: ${{ steps.docs_scope.outputs.docs_only }}
|
||||
OPENCLAW_CI_EVENT_NAME: ${{ github.event_name }}
|
||||
OPENCLAW_CI_FORCE_FULL_INSTALL_SMOKE: ${{ (github.event_name == 'workflow_dispatch' || github.event_name == 'schedule' || github.event_name == 'workflow_call') && 'true' || 'false' }}
|
||||
OPENCLAW_CI_WORKFLOW_BUN_GLOBAL_INSTALL_SMOKE: ${{ inputs.run_bun_global_install_smoke || 'false' }}
|
||||
OPENCLAW_CI_RUN_FAST_INSTALL_SMOKE: ${{ steps.changed_scope.outputs.run_fast_install_smoke || steps.changed_scope.outputs.run_changed_smoke || 'false' }}
|
||||
OPENCLAW_CI_RUN_FULL_INSTALL_SMOKE: ${{ steps.changed_scope.outputs.run_full_install_smoke || 'false' }}
|
||||
run: |
|
||||
docs_only="${OPENCLAW_CI_DOCS_ONLY:-false}"
|
||||
event_name="${OPENCLAW_CI_EVENT_NAME:-}"
|
||||
force_full_install_smoke="${OPENCLAW_CI_FORCE_FULL_INSTALL_SMOKE:-false}"
|
||||
workflow_bun_global_install_smoke="${OPENCLAW_CI_WORKFLOW_BUN_GLOBAL_INSTALL_SMOKE:-false}"
|
||||
run_changed_fast_install_smoke="${OPENCLAW_CI_RUN_FAST_INSTALL_SMOKE:-false}"
|
||||
run_changed_full_install_smoke="${OPENCLAW_CI_RUN_FULL_INSTALL_SMOKE:-false}"
|
||||
run_fast_install_smoke=false
|
||||
run_full_install_smoke=false
|
||||
docs_only=false
|
||||
run_fast_install_smoke=true
|
||||
run_full_install_smoke=true
|
||||
run_bun_global_install_smoke=false
|
||||
run_install_smoke=false
|
||||
if [ "$force_full_install_smoke" = "true" ]; then
|
||||
run_fast_install_smoke=true
|
||||
run_full_install_smoke=true
|
||||
run_install_smoke=true
|
||||
elif [ "$docs_only" != "true" ] && [ "$event_name" != "push" ] && [ "$run_changed_full_install_smoke" = "true" ]; then
|
||||
run_fast_install_smoke=true
|
||||
run_full_install_smoke=true
|
||||
run_install_smoke=true
|
||||
elif [ "$docs_only" != "true" ] && [ "$run_changed_full_install_smoke" = "true" ]; then
|
||||
run_fast_install_smoke=true
|
||||
run_install_smoke=true
|
||||
elif [ "$docs_only" != "true" ] && [ "$run_changed_fast_install_smoke" = "true" ]; then
|
||||
run_fast_install_smoke=true
|
||||
run_install_smoke=true
|
||||
fi
|
||||
run_install_smoke=true
|
||||
if [ "$event_name" = "schedule" ]; then
|
||||
run_bun_global_install_smoke=true
|
||||
elif [ "$event_name" = "workflow_dispatch" ] || [ "$event_name" = "workflow_call" ]; then
|
||||
@@ -326,7 +273,6 @@ jobs:
|
||||
provenance: false
|
||||
|
||||
- name: Build installer non-root image
|
||||
if: github.event_name != 'pull_request'
|
||||
uses: useblacksmith/build-push-action@cbd1f60d194a98cb3be5523b15134501eaf0fbf3 # v2
|
||||
with:
|
||||
context: ./scripts/docker
|
||||
@@ -356,8 +302,8 @@ jobs:
|
||||
OPENCLAW_NO_ONBOARD: "1"
|
||||
OPENCLAW_INSTALL_SMOKE_SKIP_CLI: "1"
|
||||
OPENCLAW_INSTALL_SMOKE_SKIP_IMAGE_BUILD: "1"
|
||||
OPENCLAW_INSTALL_NONROOT_SKIP_IMAGE_BUILD: ${{ github.event_name == 'pull_request' && '0' || '1' }}
|
||||
OPENCLAW_INSTALL_SMOKE_SKIP_NONROOT: ${{ github.event_name == 'pull_request' && '1' || '0' }}
|
||||
OPENCLAW_INSTALL_NONROOT_SKIP_IMAGE_BUILD: "1"
|
||||
OPENCLAW_INSTALL_SMOKE_SKIP_NONROOT: "0"
|
||||
OPENCLAW_INSTALL_SMOKE_SKIP_NPM_GLOBAL: "1"
|
||||
OPENCLAW_INSTALL_SMOKE_SKIP_PREVIOUS: "1"
|
||||
OPENCLAW_INSTALL_SMOKE_UPDATE_BASELINE: latest
|
||||
|
||||
210
.github/workflows/npm-telegram-beta-e2e.yml
vendored
Normal file
210
.github/workflows/npm-telegram-beta-e2e.yml
vendored
Normal file
@@ -0,0 +1,210 @@
|
||||
name: NPM Telegram Beta E2E
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
package_spec:
|
||||
description: Published OpenClaw package spec to test
|
||||
required: true
|
||||
default: openclaw@beta
|
||||
type: string
|
||||
provider_mode:
|
||||
description: QA provider mode
|
||||
required: true
|
||||
default: mock-openai
|
||||
type: choice
|
||||
options:
|
||||
- mock-openai
|
||||
- live-frontier
|
||||
scenario:
|
||||
description: Optional comma-separated Telegram scenario ids
|
||||
required: false
|
||||
type: string
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: npm-telegram-beta-e2e-${{ github.run_id }}
|
||||
cancel-in-progress: false
|
||||
|
||||
env:
|
||||
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: "true"
|
||||
NODE_VERSION: "24.x"
|
||||
PNPM_VERSION: "10.33.0"
|
||||
|
||||
jobs:
|
||||
validate_dispatch_ref:
|
||||
name: Validate dispatch ref
|
||||
runs-on: blacksmith-8vcpu-ubuntu-2404
|
||||
steps:
|
||||
- name: Require main workflow ref
|
||||
env:
|
||||
WORKFLOW_REF: ${{ github.ref }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
if [[ "${WORKFLOW_REF}" != "refs/heads/main" ]]; then
|
||||
echo "NPM Telegram beta E2E must be dispatched from main so workflow logic stays controlled." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
approve_release_manager:
|
||||
name: Approve npm Telegram beta E2E
|
||||
needs: validate_dispatch_ref
|
||||
runs-on: ubuntu-latest
|
||||
environment: npm-release
|
||||
steps:
|
||||
- name: Record approval
|
||||
env:
|
||||
PACKAGE_SPEC: ${{ inputs.package_spec }}
|
||||
run: echo "Approved npm Telegram beta E2E for ${PACKAGE_SPEC}"
|
||||
|
||||
prepare_docker_e2e_image:
|
||||
name: Prepare Docker E2E image
|
||||
needs: validate_dispatch_ref
|
||||
runs-on: blacksmith-32vcpu-ubuntu-2404
|
||||
timeout-minutes: 90
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
outputs:
|
||||
image: ${{ steps.image.outputs.image }}
|
||||
env:
|
||||
DOCKER_BUILD_SUMMARY: "false"
|
||||
DOCKER_BUILD_RECORD_UPLOAD: "false"
|
||||
steps:
|
||||
- name: Checkout main
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
ref: ${{ github.sha }}
|
||||
fetch-depth: 1
|
||||
|
||||
- name: Resolve Docker E2E image tag
|
||||
id: image
|
||||
shell: bash
|
||||
env:
|
||||
SELECTED_SHA: ${{ github.sha }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
repository="${GITHUB_REPOSITORY,,}"
|
||||
image="ghcr.io/${repository}-docker-e2e:${SELECTED_SHA}"
|
||||
echo "image=$image" >> "$GITHUB_OUTPUT"
|
||||
echo "Docker E2E image: \`$image\`" >> "$GITHUB_STEP_SUMMARY"
|
||||
|
||||
- name: Set up Blacksmith Docker Builder
|
||||
uses: useblacksmith/setup-docker-builder@ac083cc84672d01c60d5e8561d0a939b697de542 # v1
|
||||
|
||||
- name: Log in to GHCR
|
||||
uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ github.token }}
|
||||
|
||||
- name: Build and push Docker E2E image
|
||||
uses: useblacksmith/build-push-action@cbd1f60d194a98cb3be5523b15134501eaf0fbf3 # v2
|
||||
with:
|
||||
context: .
|
||||
file: ./scripts/e2e/Dockerfile
|
||||
target: build
|
||||
platforms: linux/amd64
|
||||
tags: ${{ steps.image.outputs.image }}
|
||||
provenance: false
|
||||
push: true
|
||||
|
||||
run_npm_telegram_beta_e2e:
|
||||
name: Run published npm Telegram E2E
|
||||
needs: [approve_release_manager, prepare_docker_e2e_image]
|
||||
runs-on: blacksmith-32vcpu-ubuntu-2404
|
||||
timeout-minutes: 60
|
||||
environment: qa-live-shared
|
||||
permissions:
|
||||
contents: read
|
||||
packages: read
|
||||
steps:
|
||||
- name: Checkout main
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
ref: ${{ github.sha }}
|
||||
fetch-depth: 1
|
||||
|
||||
- name: Log in to GHCR
|
||||
uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ github.token }}
|
||||
|
||||
- name: Setup Node environment
|
||||
uses: ./.github/actions/setup-node-env
|
||||
with:
|
||||
node-version: ${{ env.NODE_VERSION }}
|
||||
pnpm-version: ${{ env.PNPM_VERSION }}
|
||||
install-bun: "true"
|
||||
|
||||
- name: Validate inputs and secrets
|
||||
env:
|
||||
PACKAGE_SPEC: ${{ inputs.package_spec }}
|
||||
PROVIDER_MODE: ${{ inputs.provider_mode }}
|
||||
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
|
||||
OPENCLAW_QA_CONVEX_SITE_URL: ${{ secrets.OPENCLAW_QA_CONVEX_SITE_URL }}
|
||||
OPENCLAW_QA_CONVEX_SECRET_CI: ${{ secrets.OPENCLAW_QA_CONVEX_SECRET_CI }}
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
if [[ ! "${PACKAGE_SPEC}" =~ ^openclaw@(beta|latest|[0-9]{4}\.[1-9][0-9]*\.[1-9][0-9]*(-[1-9][0-9]*|-beta\.[1-9][0-9]*)?)$ ]]; then
|
||||
echo "package_spec must be openclaw@beta, openclaw@latest, or an exact OpenClaw release version; got: ${PACKAGE_SPEC}" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
require_var() {
|
||||
local key="$1"
|
||||
if [[ -z "${!key:-}" ]]; then
|
||||
echo "Missing required ${key}." >&2
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
require_var OPENCLAW_QA_CONVEX_SITE_URL
|
||||
require_var OPENCLAW_QA_CONVEX_SECRET_CI
|
||||
if [[ "${PROVIDER_MODE}" == "live-frontier" ]]; then
|
||||
require_var OPENAI_API_KEY
|
||||
fi
|
||||
|
||||
- name: Run npm Telegram beta E2E
|
||||
id: run_lane
|
||||
shell: bash
|
||||
env:
|
||||
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
|
||||
OPENCLAW_SKIP_DOCKER_BUILD: "1"
|
||||
OPENCLAW_DOCKER_E2E_IMAGE: ${{ needs.prepare_docker_e2e_image.outputs.image }}
|
||||
OPENCLAW_NPM_TELEGRAM_PACKAGE_SPEC: ${{ inputs.package_spec }}
|
||||
OPENCLAW_NPM_TELEGRAM_PROVIDER_MODE: ${{ inputs.provider_mode }}
|
||||
OPENCLAW_NPM_TELEGRAM_CREDENTIAL_SOURCE: convex
|
||||
OPENCLAW_NPM_TELEGRAM_CREDENTIAL_ROLE: ci
|
||||
OPENCLAW_QA_CONVEX_SITE_URL: ${{ secrets.OPENCLAW_QA_CONVEX_SITE_URL }}
|
||||
OPENCLAW_QA_CONVEX_SECRET_CI: ${{ secrets.OPENCLAW_QA_CONVEX_SECRET_CI }}
|
||||
OPENCLAW_QA_REDACT_PUBLIC_METADATA: "1"
|
||||
INPUT_SCENARIO: ${{ inputs.scenario }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
output_dir=".artifacts/qa-e2e/npm-telegram-beta-${GITHUB_RUN_ID}-${GITHUB_RUN_ATTEMPT}"
|
||||
echo "output_dir=${output_dir}" >> "$GITHUB_OUTPUT"
|
||||
export OPENCLAW_NPM_TELEGRAM_OUTPUT_DIR="${output_dir}"
|
||||
|
||||
if [[ -n "${INPUT_SCENARIO// }" ]]; then
|
||||
export OPENCLAW_NPM_TELEGRAM_SCENARIOS="${INPUT_SCENARIO}"
|
||||
fi
|
||||
|
||||
pnpm test:docker:npm-telegram-live
|
||||
|
||||
- name: Upload npm Telegram E2E artifacts
|
||||
if: always()
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: npm-telegram-beta-e2e-${{ github.run_id }}-${{ github.run_attempt }}
|
||||
path: ${{ steps.run_lane.outputs.output_dir }}
|
||||
retention-days: 14
|
||||
if-no-files-found: warn
|
||||
@@ -623,6 +623,9 @@ jobs:
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ github.token }}
|
||||
|
||||
- name: Setup Docker builder
|
||||
uses: useblacksmith/setup-docker-builder@ac083cc84672d01c60d5e8561d0a939b697de542 # v1
|
||||
|
||||
- name: Build and push shared Docker E2E image
|
||||
uses: docker/build-push-action@bcafcacb16a39f128d818304e6c9c0c18556b85f # v7.1.0
|
||||
with:
|
||||
|
||||
101
CHANGELOG.md
101
CHANGELOG.md
@@ -6,50 +6,114 @@ Docs: https://docs.openclaw.ai
|
||||
|
||||
### Changes
|
||||
|
||||
- Gradium: add a bundled text-to-speech provider with voice-note and telephony output support. (#64958) Thanks @LaurentMazare.
|
||||
- Plugins/setup: honor explicit `setup.requiresRuntime: false` as a descriptor-only setup contract while keeping omitted values on the legacy setup-api fallback path. Thanks @vincentkoc.
|
||||
- Plugins/setup: report descriptor/runtime drift when setup-api registrations disagree with `setup.providers` or `setup.cliBackends`, without rejecting legacy setup plugins. Thanks @vincentkoc.
|
||||
- TUI/dependencies: remove direct `cli-highlight` usage from the OpenClaw TUI code-block renderer, keeping themed code coloring without the extra root dependency. Thanks @vincentkoc.
|
||||
- Diagnostics/OTEL: export run, model-call, and tool-execution diagnostic lifecycle events as OTEL spans without retaining live span state. Thanks @vincentkoc.
|
||||
- Plugins/activation: expose activation plan reasons and a richer plan API so callers can inspect why a plugin was selected while preserving existing id-list activation behavior. (#70943) Thanks @vincentkoc.
|
||||
- Plugins/source metadata: expose normalized install-source facts on provider and channel catalogs so onboarding can explain npm pinning, integrity state, and local availability before runtime loads. (#70951) Thanks @vincentkoc.
|
||||
- Plugins/catalog: pin the official external WeCom channel source to an exact npm release plus dist integrity, with a guard that official external sources stay integrity-pinned. (#70997) Thanks @vincentkoc.
|
||||
- Plugins/source metadata: warn when `openclaw.install.defaultChoice` is invalid or points at a missing source, keeping catalog diagnostics explicit without breaking existing plugins. Thanks @vincentkoc.
|
||||
- Plugins/source metadata: warn when `openclaw.install.expectedIntegrity` is present without a valid npm source, keeping orphaned integrity metadata visible without rejecting existing plugins. Thanks @vincentkoc.
|
||||
- Plugins/source metadata: warn when provider or channel catalog package identity drifts from `openclaw.install.npmSpec`, keeping diagnostics visible without rejecting compatible external catalogs. Thanks @vincentkoc.
|
||||
- Diagnostics/OTEL: add a lightweight diagnostic trace-context carrier for future span correlation without adding OTEL SDK state to core. Thanks @vincentkoc.
|
||||
- Dependencies/SBOM: add an ownership-backed dependency risk report for root closure size, native/build-risk packages, and missing owner records. Thanks @vincentkoc.
|
||||
- Diagnostics/OTEL: attach diagnostic trace context to exported OTEL logs so log records can correlate with future spans without adding retained process state. Thanks @vincentkoc.
|
||||
- Diagnostics/OTEL: pass immutable per-run diagnostic trace context through agent and tool hook contexts, and parent exported diagnostic spans from validated context without retaining global trace state. Thanks @vincentkoc.
|
||||
- Diagnostics/OTEL: make exporter startup restart-safe so config reloads do not retain stale SDKs, log transports, or diagnostic event listeners. Thanks @vincentkoc.
|
||||
- Diagnostics: emit structured tool execution diagnostic events with trace context, timing, and redacted error metadata. Thanks @vincentkoc.
|
||||
- Diagnostics: emit structured run and model-call diagnostic events with trace context, duration, and non-message error metadata. Thanks @vincentkoc.
|
||||
- Control UI/chat: add a Steer action on queued messages so a browser follow-up can be injected into the active run without retyping it.
|
||||
- Control UI/Talk: add browser WebRTC realtime voice sessions backed by OpenAI Realtime, with Gateway-minted ephemeral client secrets and `openclaw_agent_consult` handoff to the full OpenClaw agent.
|
||||
- Agents/tools: add optional per-call `timeoutMs` support for image, video, music, and TTS generation tools so agents can extend provider request timeouts only when a specific generation needs it.
|
||||
- Agents/subagents: add optional forked context for native `sessions_spawn` runs so agents can let a child inherit the requester transcript when needed, while keeping clean isolated sessions as the default; includes prompt guidance, context-engine hook metadata, docs, and QA coverage.
|
||||
- Codex harness: add structured debug logging for embedded harness selection decisions so `/status` stays simple while gateway logs explain auto-selection and Pi fallback reasons. (#70760) Thanks @100yenadmin.
|
||||
- Dependencies/Pi: update bundled Pi packages to `0.70.0`, use Pi's upstream `gpt-5.5` catalog metadata for OpenAI and OpenAI Codex, and keep only local `gpt-5.5-pro` forward-compat handling.
|
||||
- Plugin SDK/Codex harness: add provider-owned transport/auth/follow-up seams and harness result classification so Codex-style runtimes can participate in fallback policy without core special-casing. (#70772) Thanks @100yenadmin.
|
||||
- Codex harness: bridge Codex-native tool hooks into OpenClaw plugin hooks and approvals, with bounded relay payloads and approval spam protection. (#71008) Thanks @pashpashpash.
|
||||
- Dependencies/Pi: update bundled Pi packages to `0.70.2`, use Pi's upstream `gpt-5.5` and DeepSeek V4 catalog metadata, and keep only local `gpt-5.5-pro` forward-compat handling.
|
||||
- Models/CLI: speed up `openclaw models list --all --provider <id>` for bundled providers with safe static catalogs while keeping live and third-party providers on registry discovery. (#70632) Thanks @shakkernerd.
|
||||
- Models/CLI: avoid broad registry enumeration for default `openclaw models list`, reducing default listing latency while preserving configured-row output. (#70883) Thanks @shakkernerd.
|
||||
- Models/CLI: split `openclaw models list` row-source orchestration and registry loading into narrower helpers without changing list output behavior. (#70867) Thanks @shakkernerd.
|
||||
- Models/commands: deprecate `/models add` so chat attempts now return a deprecation message instead of writing model configuration, and remove the add action from `/models` provider menus.
|
||||
- Codex harness/context-engine: run context-engine bootstrap, assembly, post-turn maintenance, and engine-owned compaction in Codex app-server sessions while keeping native Codex thread state and compaction auditable. (#70809) Thanks @jalehman.
|
||||
- Codex runtime plan: consolidate contract-first Pi/Codex parity coverage and accept legacy Codex auth-provider aliases in app-server profile login and refresh paths. (#71096) Thanks @100yenadmin.
|
||||
- Plugins/Google Meet: add a bundled participant plugin with personal Google auth, explicit meeting URL joins, Chrome and Twilio transports, and realtime voice support. (#70765) Thanks @steipete.
|
||||
- Plugins/Google Meet: default Chrome realtime sessions to OpenAI plus SoX `rec`/`play` audio bridge commands, so the usual setup only needs the plugin enabled and `OPENAI_API_KEY`.
|
||||
- Providers/OpenAI: add image generation and reference-image editing through Codex OAuth, so `openai/gpt-image-2` works without an `OPENAI_API_KEY`. Fixes #70703.
|
||||
- Providers/OpenRouter: add image generation and reference-image editing through `image_generate`, so OpenRouter image models work with `OPENROUTER_API_KEY`. Fixes #55066 via #67668. Thanks @notamicrodose.
|
||||
- Image generation: let agents request provider-supported quality and output format hints, and pass OpenAI-specific background, moderation, compression, and user hints through the `image_generate` tool. (#70503) Thanks @ottodeng.
|
||||
- Plugins/Google Meet: add a `chrome-node` transport so a paired macOS node, such as a Parallels VM, can own Chrome, BlackHole, and SoX while the Gateway machine keeps the agent and model key.
|
||||
- Plugins/Bonjour: move LAN Gateway discovery advertising into a default-enabled bundled plugin with its own `@homebridge/ciao` dependency, so users can disable Bonjour without cutting wide-area discovery. Thanks @vincentkoc.
|
||||
- Providers/Google: add a Gemini Live realtime voice provider for backend Voice Call and Google Meet audio bridges, with bidirectional audio and function-call support.
|
||||
- Plugins/Google Meet: let realtime Meet sessions consult the full OpenClaw agent for deeper answers while staying in the live voice loop.
|
||||
- Providers/DeepSeek: add DeepSeek V4 Flash and V4 Pro to the bundled catalog and make V4 Flash the onboarding default.
|
||||
|
||||
### Fixes
|
||||
|
||||
- Plugins/runtime deps: respect explicit plugin and channel disablement when repairing bundled runtime dependencies, so doctor and health checks no longer install deps for disabled configured channels.
|
||||
- Diagnostics: harden tool and model diagnostic events against hostile errors, blocking listeners, and unsafe stability reason fields. Thanks @vincentkoc.
|
||||
- Plugins/onboarding: record local plugin install source metadata without duplicating raw absolute local paths in persisted `plugins.installs`, while preserving linked load-path cleanup. (#70970) Thanks @vincentkoc.
|
||||
- Browser/tool: tell agents not to pass per-call `timeoutMs` on existing-session type, evaluate, and other Chrome MCP actions that reject timeout overrides.
|
||||
- Codex/GPT-5.4: harden fallback, auth-profile, tool-schema, and replay edge cases across native and embedded runtime paths. (#70743) Thanks @100yenadmin.
|
||||
- Voice-call/Telnyx: preserve inbound/outbound callback metadata and read transcription text from Telnyx's current `transcription_data` payload.
|
||||
- Providers/DeepSeek: wire V4 thinking controls and OpenAI-compatible replay policy so follow-up turns preserve DeepSeek `reasoning_content`, while the None/off thinking path strips replayed reasoning fields. Fixes #70931.
|
||||
- Codex harness: send verbose tool progress to chat channels for native app-server runs, matching the Pi harness `/verbose on` and `/verbose full` behavior. (#70966) Thanks @jalehman.
|
||||
- Codex models: fetch paginated Codex app-server model catalogs, mark truncated `/codex models` output, and keep ChatGPT OAuth defaults on the `openai-codex/gpt-5.5` route instead of the OpenAI API-key route.
|
||||
- Codex status: report Codex CLI OAuth as `oauth (codex-cli)` for native `codex/*` sessions instead of showing unknown auth. Fixes #70688. Thanks @jb510.
|
||||
- Channels/CLI: accept explicit shared-secret, base-URL, and auth-directory setup flags, and map legacy Nextcloud Talk `--url`/`--token` add commands to the bundled plugin setup input. Fixes #61759 and #61923.
|
||||
- Models/CLI: keep `openclaw models list` read-only while still showing eligible configured-provider rows, so listing models no longer rewrites per-agent `models.json`. (#70847) Thanks @shakkernerd.
|
||||
- Agents/transport: propagate configured attempt timeouts into guarded per-request dispatchers, so slow local LLM calls such as Ollama no longer fail at Undici's default 60-second body timeout. Fixes #70829. (#70831) Thanks @DranboFieldston.
|
||||
- Plugins/providers: mirror runtime auth choices in bundled provider manifests and detect `KIMI_API_KEY` for Moonshot/Kimi web search before plugin runtime loads. Thanks @vincentkoc.
|
||||
- Gateway/chat: register chat.send runs in the chat run registry so lifecycle error events reach the client instead of being silently dropped, fixing stuck 'waiting' state and /abort reporting no active run. (#69747) Thanks @wangshu94.
|
||||
- Plugins/QQ Bot: enable the bundled qqbot plugin by default so its runtime dependency `@tencent-connect/qqbot-connector` is installed on first launch, unblocking the QR-code binding flow that dynamically imports the connector before any account is configured. (#71051) Thanks @cxyhhhhh.
|
||||
|
||||
## 2026.4.23
|
||||
|
||||
### Changes
|
||||
|
||||
- Providers/OpenAI: add image generation and reference-image editing through Codex OAuth, so `openai/gpt-image-2` works without an `OPENAI_API_KEY`. Fixes #70703.
|
||||
- Providers/OpenRouter: add image generation and reference-image editing through `image_generate`, so OpenRouter image models work with `OPENROUTER_API_KEY`. Fixes #55066 via #67668. Thanks @notamicrodose.
|
||||
- Image generation: let agents request provider-supported quality and output format hints, and pass OpenAI-specific background, moderation, compression, and user hints through the `image_generate` tool. (#70503) Thanks @ottodeng.
|
||||
- Agents/subagents: add optional forked context for native `sessions_spawn` runs so agents can let a child inherit the requester transcript when needed, while keeping clean isolated sessions as the default; includes prompt guidance, context-engine hook metadata, docs, and QA coverage.
|
||||
- Agents/tools: add optional per-call `timeoutMs` support for image, video, music, and TTS generation tools so agents can extend provider request timeouts only when a specific generation needs it.
|
||||
- Memory/local embeddings: add configurable `memorySearch.local.contextSize` with a 4096 default so local embedding contexts can be tuned for constrained hosts without patching the memory host. (#70544) Thanks @aalekh-sarvam.
|
||||
- Dependencies/Pi: update bundled Pi packages to `0.70.0`, use Pi's upstream `gpt-5.5` catalog metadata for OpenAI and OpenAI Codex, and keep only local `gpt-5.5-pro` forward-compat handling.
|
||||
- Codex harness: add structured debug logging for embedded harness selection decisions so `/status` stays simple while gateway logs explain auto-selection and Pi fallback reasons. (#70760) Thanks @100yenadmin.
|
||||
|
||||
### Fixes
|
||||
|
||||
- Codex harness: route native `request_user_input` prompts back to the originating chat, preserve queued follow-up answers, and honor newer app-server command approval amendment decisions.
|
||||
- Codex harness/context-engine: redact context-engine assembly failures before logging, so fallback warnings do not serialize raw error objects. (#70809) Thanks @jalehman.
|
||||
- WhatsApp/onboarding: keep first-run setup entry loading off the Baileys runtime dependency path, so packaged QuickStart installs can show WhatsApp setup before runtime deps are staged. Fixes #70932.
|
||||
- Block streaming: suppress final assembled text after partial block-delivery aborts when the already-sent text chunks exactly cover the final reply, preventing duplicate replies without dropping unrelated short messages. Fixes #70921.
|
||||
- Codex harness/Windows: resolve npm-installed `codex.cmd` shims through PATHEXT before starting the native app-server, so `codex/*` models work without a manual `.exe` shim. Fixes #70913.
|
||||
- Slack/groups: classify MPIM group DMs as group chat context and suppress verbose tool/plan progress on Slack non-DM surfaces, so internal "Working…" traces no longer leak into rooms. Fixes #70912.
|
||||
- Agents/replay: stop OpenAI/Codex transcript replay from synthesizing missing tool results while still preserving synthetic repair on Anthropic, Gemini, and Bedrock transport-owned sessions. (#61556) Thanks @VictorJeon and @vincentkoc.
|
||||
- Telegram/media replies: parse remote markdown image syntax into outbound media payloads on the final reply path, so Telegram group chats stop falling back to plain-text image URLs when the model or a tool emits `` instead of a `MEDIA:` token. (#66191) Thanks @apezam and @vincentkoc.
|
||||
- Agents/WebChat: surface non-retryable provider failures such as billing, auth, and rate-limit errors from the embedded runner instead of logging `surface_error` and leaving webchat with no rendered error. Fixes #70124. (#70848) Thanks @truffle-dev.
|
||||
- WhatsApp: unify outbound media normalization across direct sends and auto-replies. Thanks @mcaxtr.
|
||||
- Memory/CLI: declare the built-in `local` embedding provider in the memory-core manifest, so standalone `openclaw memory status`, `index`, and `search` can resolve local embeddings just like the gateway runtime. Fixes #70836. (#70873) Thanks @mattznojassist.
|
||||
- Gateway/WebChat: preserve image attachments for text-only primary models by offloading them as media refs instead of dropping them, so configured image tools can still inspect the original file. Fixes #68513, #44276, #51656, #70212.
|
||||
- Plugins/Google Meet: hang up delegated Twilio calls on leave, clean up Chrome realtime audio bridges when launch fails, and use a flat provider-safe tool schema.
|
||||
- Media understanding: honor explicit image-model configuration before native-vision skips, including `agents.defaults.imageModel`, `tools.media.image.models`, and provider image defaults such as MiniMax VL when the active chat model is text-only. Fixes #47614, #63722, #69171.
|
||||
- Codex/media understanding: support `codex/*` image models through bounded Codex app-server image turns, while keeping `openai-codex/*` on the OpenAI Codex OAuth route and validating app-server responses against generated protocol contracts. Fixes #70201.
|
||||
- Providers/OpenAI Codex: synthesize the `openai-codex/gpt-5.5` OAuth model row when Codex catalog discovery omits it, so cron and subagent runs do not fail with `Unknown model` while the account is authenticated.
|
||||
- Models/CLI: keep `openclaw models list` read-only while still showing eligible configured-provider rows, so listing models no longer rewrites per-agent `models.json`. (#70847) Thanks @shakkernerd.
|
||||
- Providers/Google: honor the private-network SSRF opt-in for Gemini image generation requests, so trusted proxy setups that resolve Google API hosts to private addresses can use `image_generate`. Fixes #67216.
|
||||
- Agents/transport: stop embedded runs from lowering the process-wide undici stream timeouts, so slow Gemini image generation and other long-running provider requests no longer inherit short run-attempt headers timeouts. Fixes #70423. Thanks @giangthb.
|
||||
- Providers/OpenRouter: send image-understanding prompts as user text before image parts, restoring non-empty vision responses for OpenRouter multimodal models. Fixes #70410.
|
||||
- Plugins/providers: mirror runtime auth choices in bundled provider manifests and detect `KIMI_API_KEY` for Moonshot/Kimi web search before plugin runtime loads. Thanks @vincentkoc.
|
||||
- Memory/QMD: recreate stale managed QMD collections when startup repair finds the collection name already exists, so root memory narrows back to `MEMORY.md` instead of staying on broad workspace markdown indexing.
|
||||
- Agents/OpenAI: surface selected-model capacity failures from PI, Codex, and auto-reply harness paths with a model-switch hint instead of the generic empty-response error. Thanks @vincentkoc.
|
||||
- Models/Codex: preserve Codex provider metadata when adding models from chat or CLI commands, so manually added Codex models keep the right auth and routing behavior. (#70820) Thanks @Takhoffman.
|
||||
- Providers/OpenAI: route `openai/gpt-image-2` through configured Codex OAuth directly when an `openai-codex` profile is active, instead of probing `OPENAI_API_KEY` first.
|
||||
- Providers/OpenAI: harden image generation auth routing and Codex OAuth response parsing so fallback only applies to public OpenAI API routes and bounded SSE results. Thanks @Takhoffman.
|
||||
- OpenAI/image generation: send reference-image edits as guarded multipart uploads instead of JSON data URLs, restoring complex multi-reference `gpt-image-2` edits. Fixes #70642. Thanks @dashhuang.
|
||||
- Providers/OpenRouter: send image-understanding prompts as user text before image parts, restoring non-empty vision responses for OpenRouter multimodal models. Fixes #70410.
|
||||
- Providers/Google: honor the private-network SSRF opt-in for Gemini image generation requests, so trusted proxy setups that resolve Google API hosts to private addresses can use `image_generate`. Fixes #67216.
|
||||
- Agents/transport: stop embedded runs from lowering the process-wide undici stream timeouts, so slow Gemini image generation and other long-running provider requests no longer inherit short run-attempt headers timeouts. Fixes #70423. Thanks @giangthb.
|
||||
- Providers/OpenAI: honor the private-network SSRF opt-in for OpenAI-compatible image generation endpoints, so trusted LocalAI/LAN `image_generate` routes work without disabling SSRF checks globally. Fixes #62879. Thanks @seitzbg.
|
||||
- Providers/OpenAI: stop advertising the removed `gpt-5.3-codex-spark` Codex model through fallback catalogs, and suppress stale rows with a GPT-5.5 recovery hint.
|
||||
- Control UI/chat: persist assistant-generated images as authenticated managed media and accept paired-device tokens for assistant media fetches, so webchat history reloads keep showing generated images. (#70719, #70741) Thanks @Patrick-Erichsen.
|
||||
- Control UI/chat: queue Stop-button aborts across Gateway reconnects so a disconnected active run is canceled on reconnect instead of only clearing local UI state. (#70673) Thanks @chinar-amrutkar.
|
||||
- Memory/QMD: recreate stale managed QMD collections when startup repair finds the collection name already exists, so root memory narrows back to `MEMORY.md` instead of staying on broad workspace markdown indexing.
|
||||
- Agents/OpenAI: surface selected-model capacity failures from PI, Codex, and auto-reply harness paths with a model-switch hint instead of the generic empty-response error. Thanks @vincentkoc.
|
||||
- Plugins/QR: replace legacy `qrcode-terminal` QR rendering with bounded `qrcode-tui` helpers for plugin login/setup flows. (#65969) Thanks @vincentkoc.
|
||||
- Voice-call/realtime: wait for OpenAI session configuration before greeting or forwarding buffered audio, and reject non-allowlisted Twilio callers before stream setup. (#43501) Thanks @forrestblount.
|
||||
- ACPX/Codex: stop materializing `auth.json` bridge files for Codex ACP, Codex app-server, and Codex CLI runs; Codex-owned runtimes now use their normal `CODEX_HOME`/`~/.codex` auth path directly.
|
||||
- Auto-reply/system events: route async exec-event completion replies through the persisted session delivery context, so long-running command results return to the originating channel instead of being dropped when live origin metadata is missing. (#70258) Thanks @wzfukui.
|
||||
- OpenAI/image generation: send reference-image edits as guarded multipart uploads instead of JSON data URLs, restoring complex multi-reference `gpt-image-2` edits. Fixes #70642. Thanks @dashhuang.
|
||||
- Gateway/sessions: extend the webchat session-mutation guard to `sessions.compact` and `sessions.compaction.restore`, so `WEBCHAT_UI` clients are rejected from compaction-side session mutations consistently with the existing patch/delete guards. (#70716) Thanks @drobison00.
|
||||
- QA channel/security: reject non-HTTP(S) inbound attachment URLs before media fetch, and log rejected schemes so suspicious or misconfigured payloads are visible during debugging. (#70708) Thanks @vincentkoc.
|
||||
- Plugins/install: link the host OpenClaw package into external plugins that declare `openclaw` as a peer dependency, so peer-only plugin SDK imports resolve after install without bundling a duplicate host package. (#70462) Thanks @anishesg.
|
||||
- Plugins/Windows: refresh the packaged plugin SDK alias in place during bundled runtime dependency repair, so gateway and CLI plugin startup no longer race on `ENOTEMPTY`/`EPERM` after same-guest npm updates.
|
||||
- Teams/security: require shared Bot Framework audience tokens to name the configured Teams app via verified `appid` or `azp`, blocking cross-bot token replay on the global audience. (#70724) Thanks @vincentkoc.
|
||||
- Plugins/startup: resolve bundled plugin Jiti loads relative to the target plugin module instead of the central loader, so Bun global installs no longer hang while discovering bundled image providers. (#70073) Thanks @yidianyiko.
|
||||
- Anthropic/CLI security: derive Claude CLI `bypassPermissions` from OpenClaw's existing YOLO exec policy, preserve explicit raw Claude `--permission-mode` overrides, and strip malformed permission-mode args instead of silently falling back to a bypass. (#70723) Thanks @vincentkoc.
|
||||
@@ -59,8 +123,6 @@ Docs: https://docs.openclaw.ai
|
||||
- Approvals/security: require explicit chat exec-approval enablement instead of auto-enabling approval clients just because approvers resolve from config or owner allowlists. (#70715) Thanks @vincentkoc.
|
||||
- Discord/security: keep native slash-command channel policy from bypassing configured owner or member restrictions, while preserving channel-policy fallback when no stricter access rule exists. (#70711) Thanks @vincentkoc.
|
||||
- Android/security: stop `ASK_OPENCLAW` intents from auto-sending injected prompts, so external app actions only prefill the draft instead of dispatching it immediately. (#70714) Thanks @vincentkoc.
|
||||
- Control UI/chat: persist assistant-generated images as authenticated managed media so webchat history reloads show the image instead of dropping it. (#70719)
|
||||
- Control UI/chat: queue Stop-button aborts across Gateway reconnects so a disconnected active run is canceled on reconnect instead of only clearing local UI state. (#70673) Thanks @chinar-amrutkar.
|
||||
- Secrets/Windows: strip UTF-8 BOMs from file-backed secrets and keep unavailable ACL checks fail-closed unless trusted file or exec providers explicitly opt into `allowInsecurePath`. (#70662) Thanks @zhanggpcsu.
|
||||
- Agents/image generation: escape ignored override values in tool warnings so parsed `MEDIA:` directives cannot be injected through unsupported model options. (#70710) Thanks @vincentkoc.
|
||||
- QQBot/security: require framework auth for `/bot-approve` so unauthorized QQ senders cannot change exec approval settings through the unauthenticated pre-dispatch slash-command path. (#70706) Thanks @vincentkoc.
|
||||
@@ -70,6 +132,7 @@ Docs: https://docs.openclaw.ai
|
||||
- WhatsApp/security: keep contact/vCard/location structured-object free text out of the inline message body and render it through fenced untrusted metadata JSON, limiting hidden prompt-injection payloads in names, phone fields, and location labels/comments.
|
||||
- Group-chat/security: keep channel-sourced group names and participant labels out of inline group system prompts and render them through fenced untrusted metadata JSON.
|
||||
- Agents/replay: preserve Kimi-style `functions.<name>:<index>` tool-call IDs during strict replay sanitization so custom OpenAI-compatible Kimi routes keep multi-turn tool use intact. (#70693) Thanks @geri4.
|
||||
- Discord/replies: preserve final reply permission context through outbound delivery so Discord replies keep the same channel/member routing rules at send time.
|
||||
- Plugins/startup: restore bundled plugin `openclaw/plugin-sdk/*` resolution from packaged installs and external runtime-deps stage roots, so Telegram/Discord no longer crash-loop with `Cannot find package 'openclaw'` after missing dependency repair. (#70852) Thanks @simonemacario.
|
||||
- CLI/Claude: run the same prompt-build hooks and trigger/channel context on `claude-cli` turns as on direct embedded runs, keeping Claude Code sessions aligned with OpenClaw workspace identity, routing, and hook-driven prompt mutations. (#70625) Thanks @mbelinky.
|
||||
- Discord/plugin startup: keep subagent hooks lazy behind Discord's channel entry so packaged entry imports stay narrow and report import failures with the channel id and entry path.
|
||||
@@ -78,6 +141,8 @@ Docs: https://docs.openclaw.ai
|
||||
- Codex harness/status: pin embedded harness selection per session, show active non-PI harness ids such as `codex` in `/status`, and keep legacy transcripts on PI until `/new` or `/reset` so config changes cannot hot-switch existing sessions.
|
||||
- Gateway/security: fail closed on agent-driven `gateway config.apply`/`config.patch` runtime edits by allowlisting a narrow set of agent-tunable prompt, model, and mention-gating paths (including Telegram topic-level `requireMention`) instead of relying on a hand-maintained denylist of protected subtrees that could miss new sensitive config keys. (#70726) Thanks @drobison00.
|
||||
- Webhooks/security: re-resolve `SecretRef`-backed webhook route secrets on each request so `openclaw secrets reload` revokes the previous secret immediately instead of waiting for a gateway restart. (#70727) Thanks @drobison00.
|
||||
- Memory/dreaming: decouple the managed dreaming cron from heartbeat by running it as an isolated lightweight agent turn, so dreaming runs even when heartbeat is disabled for the default agent and is no longer skipped by `heartbeat.activeHours`. `openclaw doctor --fix` migrates stale main-session dreaming jobs in persisted cron configs to the new shape. Fixes #69811, #67397, #68972. (#70737) Thanks @jalehman.
|
||||
- Agents/CLI: keep `--agent` plus `--session-id` lookup scoped to the requested agent store, so explicit agent resumes cannot select another agent's session. (#70985) Thanks @frankekn.
|
||||
|
||||
## 2026.4.22
|
||||
|
||||
@@ -251,7 +316,6 @@ Docs: https://docs.openclaw.ai
|
||||
- CLI/channels: resolve channel presence through a shared policy that keeps ambient env vars and stale persisted auth from surfacing disabled bundled plugins in status, doctor, security audit, and cron delivery validation unless the channel or plugin is effectively enabled or explicitly configured. (#69862) Thanks @gumadeiras.
|
||||
- Doctor/plugins: hydrate legacy partial interactive handler state before plugin reload clears dedupe caches, so `openclaw doctor` and post-update doctor runs no longer crash with `Cannot read properties of undefined (reading 'clear')`. (#70135) Thanks @ngutman.
|
||||
- Control UI/config: preserve intentionally empty raw config snapshots when clearing pending updates so reset restores the original bytes instead of synthesizing JSON for blank config files. (#68178) Thanks @BunsDev.
|
||||
- memory-core/dreaming: surface a `Dreaming status: blocked` line in `openclaw memory status` when dreaming is enabled but the heartbeat that drives the managed cron is not firing for the default agent, and add a Troubleshooting section to the dreaming docs covering the two common causes (per-agent `heartbeat` blocks excluding `main`, and `heartbeat.every` set to `0`/empty/invalid), so the silent failure described in #69843 becomes legible on the status surface.
|
||||
- Cron/run-log: report generic `message` tool sends under the resolved delivery channel when they match the cron target, while preserving account-specific mismatch checks for delivery traces. (#69940) Thanks @davehappyminion.
|
||||
- Doctor/channels: merge configured-channel doctor hooks across read-only, loaded, setup, and runtime plugin discovery so partial adapters no longer hide runtime-only compatibility repair or allowlist warnings, preserve disabled-channel opt-outs, and ignore malformed hook values before they can mask valid fallbacks. (#69919) Thanks @gumadeiras.
|
||||
- Models/CLI: show bundled provider-owned static catalog rows in `models list --all` before auth is configured, including Kimi K2.6 rows for Moonshot, OpenRouter, and Vercel AI Gateway, while keeping local-only and workspace plugin catalog paths isolated. (#69909) Thanks @shakkernerd.
|
||||
@@ -275,6 +339,7 @@ Docs: https://docs.openclaw.ai
|
||||
- Gateway/restart: default session-scoped restart sentinels to a one-shot agent continuation, so chat-initiated Gateway restarts acknowledge successful boot automatically. (#70269) Thanks @obviyus.
|
||||
- Build/npm publish: fail postpublish verification when root `dist/*` files import bundled plugin runtime dependencies without mirroring them in the root package manifest, so Slack-style plugin deps cannot silently ship on the wrong module-resolution path again. (#60112) thanks @medns.
|
||||
- Gateway/sessions: extend the webchat session-mutation guard to `sessions.compact` and `sessions.compaction.restore`, so `WEBCHAT_UI` clients are rejected from compaction-side session mutations consistently with the existing patch/delete guards. (#70716) Thanks @drobison00.
|
||||
- WhatsApp/groups+direct: setting `systemPrompt: ""` on a specific `groups.<id>` or `direct.<peerId>` entry now suppresses the wildcard system prompt instead of falling through to it, so users can silence the global prompt for a specific group or peer. (#70381) Thanks @Bluetegu.
|
||||
|
||||
## 2026.4.21
|
||||
|
||||
|
||||
@@ -29,9 +29,9 @@ ARG OPENCLAW_NODE_BOOKWORM_SLIM_DIGEST="sha256:e8e2e91b1378f83c5b2dd15f0247f3411
|
||||
FROM ${OPENCLAW_NODE_BOOKWORM_IMAGE} AS ext-deps
|
||||
ARG OPENCLAW_EXTENSIONS
|
||||
ARG OPENCLAW_BUNDLED_PLUGIN_DIR
|
||||
COPY ${OPENCLAW_BUNDLED_PLUGIN_DIR} /tmp/${OPENCLAW_BUNDLED_PLUGIN_DIR}
|
||||
# Copy package.json for opted-in extensions so pnpm resolves their deps.
|
||||
RUN mkdir -p /out && \
|
||||
RUN --mount=type=bind,source=${OPENCLAW_BUNDLED_PLUGIN_DIR},target=/tmp/${OPENCLAW_BUNDLED_PLUGIN_DIR},readonly \
|
||||
mkdir -p /out && \
|
||||
for ext in $OPENCLAW_EXTENSIONS; do \
|
||||
if [ -f "/tmp/${OPENCLAW_BUNDLED_PLUGIN_DIR}/$ext/package.json" ]; then \
|
||||
mkdir -p "/out/$ext" && \
|
||||
|
||||
35
VISION.md
35
VISION.md
@@ -53,12 +53,24 @@ We prioritize secure defaults, but also expose clear knobs for trusted high-powe
|
||||
|
||||
OpenClaw has an extensive plugin API.
|
||||
Core stays lean; optional capability should usually ship as plugins.
|
||||
We are generally slimming down core while expanding what plugins can do.
|
||||
If a useful feature cannot be built as a plugin yet, we welcome PRs and design discussions that extend the plugin API instead of adding one-off core behavior.
|
||||
|
||||
There are two broad plugin styles:
|
||||
|
||||
- Code plugins run OpenClaw plugin code and are appropriate for deeper runtime extension.
|
||||
- Bundle-style plugins package stable external surfaces such as skills, MCP servers, and related configuration.
|
||||
|
||||
Prefer bundle-style plugins when they can express the capability.
|
||||
They have a smaller, more stable interface and better security boundaries.
|
||||
Use code plugins when the capability needs runtime hooks, providers, channels, tools, or other in-process extension points.
|
||||
|
||||
Preferred plugin path is npm package distribution plus local extension loading for development.
|
||||
If you build a plugin, host and maintain it in your own repository.
|
||||
The bar for adding optional plugins to core is intentionally high.
|
||||
Plugin docs: [`docs/tools/plugin.md`](docs/tools/plugin.md)
|
||||
Community plugin listing + PR bar: https://docs.openclaw.ai/plugins/community
|
||||
Plugin discovery, official publisher status, provenance, and security review live in [ClawHub](https://clawhub.ai/).
|
||||
OpenClaw docs should document core extension points; plugin promotion belongs in ClawHub, preferably under vetted org publishers for official plugins.
|
||||
|
||||
Memory is a special plugin slot where only one memory plugin can be active at a time.
|
||||
Today we ship multiple memory options; over time we plan to converge on one recommended default path.
|
||||
@@ -66,21 +78,16 @@ Today we ship multiple memory options; over time we plan to converge on one reco
|
||||
### Skills
|
||||
|
||||
We still ship some bundled skills for baseline UX.
|
||||
New skills should be published to ClawHub first (`clawhub.ai`), not added to core by default.
|
||||
Core skill additions should be rare and require a strong product or security reason.
|
||||
New skills should be published through [ClawHub](https://clawhub.ai/) first, not added to core by default.
|
||||
Official or bundled promotion should require a clear product, security, or maintainer-ownership reason.
|
||||
|
||||
### MCP Support
|
||||
|
||||
OpenClaw supports MCP through `mcporter`: https://github.com/steipete/mcporter
|
||||
OpenClaw supports MCP as both a server and a runtime integration surface.
|
||||
MCP details live in [`docs/cli/mcp.md`](docs/cli/mcp.md).
|
||||
|
||||
This keeps MCP integration flexible and decoupled from core runtime:
|
||||
|
||||
- add or change MCP servers without restarting the gateway
|
||||
- keep core tool/context surface lean
|
||||
- reduce MCP churn impact on core stability and security
|
||||
|
||||
For now, we prefer this bridge model over building first-class MCP runtime into core.
|
||||
If there is an MCP server or feature `mcporter` does not support yet, please open an issue there.
|
||||
The project goal is pragmatic MCP support without duplicating existing agent,
|
||||
tool, ACPX, plugin, or ClawHub paths.
|
||||
|
||||
### Setup
|
||||
|
||||
@@ -98,11 +105,11 @@ It is widely known, fast to iterate in, and easy to read, modify, and extend.
|
||||
|
||||
## What We Will Not Merge (For Now)
|
||||
|
||||
- New core skills when they can live on ClawHub
|
||||
- New core skills when they can live on [ClawHub](https://clawhub.ai/)
|
||||
- Full-doc translation sets for all docs (deferred; we plan AI-generated translations later)
|
||||
- Commercial service integrations that do not clearly fit the model-provider category
|
||||
- Wrapper channels around already supported channels without a clear capability or security gap
|
||||
- First-class MCP runtime in core when `mcporter` already provides the integration path
|
||||
- MCP work that duplicates existing MCP, ACPX, plugin, or ClawHub paths without a clear product or security gap
|
||||
- Agent-hierarchy frameworks (manager-of-managers / nested planner trees) as a default architecture
|
||||
- Heavy orchestration layers that duplicate existing agent and tool infrastructure
|
||||
|
||||
|
||||
@@ -2330,20 +2330,17 @@ public struct TalkRealtimeSessionParams: Codable, Sendable {
|
||||
public let provider: String?
|
||||
public let model: String?
|
||||
public let voice: String?
|
||||
public let instructions: String?
|
||||
|
||||
public init(
|
||||
sessionkey: String?,
|
||||
provider: String?,
|
||||
model: String?,
|
||||
voice: String?,
|
||||
instructions: String?)
|
||||
voice: String?)
|
||||
{
|
||||
self.sessionkey = sessionkey
|
||||
self.provider = provider
|
||||
self.model = model
|
||||
self.voice = voice
|
||||
self.instructions = instructions
|
||||
}
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
@@ -2351,7 +2348,6 @@ public struct TalkRealtimeSessionParams: Codable, Sendable {
|
||||
case provider
|
||||
case model
|
||||
case voice
|
||||
case instructions
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2330,20 +2330,17 @@ public struct TalkRealtimeSessionParams: Codable, Sendable {
|
||||
public let provider: String?
|
||||
public let model: String?
|
||||
public let voice: String?
|
||||
public let instructions: String?
|
||||
|
||||
public init(
|
||||
sessionkey: String?,
|
||||
provider: String?,
|
||||
model: String?,
|
||||
voice: String?,
|
||||
instructions: String?)
|
||||
voice: String?)
|
||||
{
|
||||
self.sessionkey = sessionkey
|
||||
self.provider = provider
|
||||
self.model = model
|
||||
self.voice = voice
|
||||
self.instructions = instructions
|
||||
}
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
@@ -2351,7 +2348,6 @@ public struct TalkRealtimeSessionParams: Codable, Sendable {
|
||||
case provider
|
||||
case model
|
||||
case voice
|
||||
case instructions
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
d3b5638e205a94e40d07aa1830c8d57135df18ff9388fb7d72ee84c791ac293f config-baseline.json
|
||||
bf00f7910d8f0d8e12592e8a1c6bd0397f8e62fef2c11eb0cbd3b3a3e2a78ffe config-baseline.core.json
|
||||
2894c80bc234b33f14a0ddb09e6f42368da4ca23e0e7faceb13aba52239c1a76 config-baseline.json
|
||||
c8ff25fcdd2389d5fd88f8ba188d77c21f58b56765b555eecf3b37437f743d50 config-baseline.core.json
|
||||
22d7cd6d8279146b2d79c9531a55b80b52a2c99c81338c508104729154fdd02d config-baseline.channel.json
|
||||
a91304e3566ecc8906f199b88a2e38eaee86130aad799bf4d62921e2f0ddc1b5 config-baseline.plugin.json
|
||||
5ce9062d0ab7f9447f149fc0770571068b4c4c89e0fb80ae6ef7b3f2a146c8b3 config-baseline.plugin.json
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
96905c33f4498446f612ae17dee6affdf84ef0e2e5a0f25bf7191c315f5b826f plugin-sdk-api-baseline.json
|
||||
d8eb6331562fde29531eaac18409bb7fabcc70623bf25395f8e5710a49765f0f plugin-sdk-api-baseline.jsonl
|
||||
fa73c88651f46803f660ae5b794ad47b46c7059be1978bfee5e28dac08d05e4a plugin-sdk-api-baseline.json
|
||||
1846e87c56ca75a2431735f49572a26f4bacfb02588d7887c4f8c05b73f8c0e2 plugin-sdk-api-baseline.jsonl
|
||||
|
||||
@@ -331,10 +331,18 @@
|
||||
"source": "Plugin SDK",
|
||||
"target": "插件 SDK"
|
||||
},
|
||||
{
|
||||
"source": "Building plugins",
|
||||
"target": "构建插件"
|
||||
},
|
||||
{
|
||||
"source": "Plugin SDK Overview",
|
||||
"target": "插件 SDK 概览"
|
||||
},
|
||||
{
|
||||
"source": "Plugin SDK overview",
|
||||
"target": "插件 SDK 概览"
|
||||
},
|
||||
{
|
||||
"source": "SDK Overview",
|
||||
"target": "SDK 概览"
|
||||
@@ -343,6 +351,22 @@
|
||||
"source": "Plugin Entry Points",
|
||||
"target": "插件入口点"
|
||||
},
|
||||
{
|
||||
"source": "Plugin entry points",
|
||||
"target": "插件入口点"
|
||||
},
|
||||
{
|
||||
"source": "Plugin hooks",
|
||||
"target": "插件钩子"
|
||||
},
|
||||
{
|
||||
"source": "Internal hooks",
|
||||
"target": "内部钩子"
|
||||
},
|
||||
{
|
||||
"source": "Plugin architecture internals",
|
||||
"target": "插件架构内部机制"
|
||||
},
|
||||
{
|
||||
"source": "Entry Points",
|
||||
"target": "入口点"
|
||||
@@ -403,6 +427,10 @@
|
||||
"source": "Tencent Cloud (TokenHub)",
|
||||
"target": "腾讯云(TokenHub)"
|
||||
},
|
||||
{
|
||||
"source": "Codex Harness Context Engine Port",
|
||||
"target": "Codex Harness Context Engine Port"
|
||||
},
|
||||
{
|
||||
"source": "/gateway/configuration#strict-validation",
|
||||
"target": "/gateway/configuration#strict-validation"
|
||||
|
||||
@@ -76,3 +76,8 @@ For script compatibility, probe errors keep this first line unchanged:
|
||||
`Auth profile credentials are missing or expired.`
|
||||
|
||||
Human-friendly detail and stable reason codes may be added on subsequent lines.
|
||||
|
||||
## Related
|
||||
|
||||
- [Secrets management](/gateway/secrets)
|
||||
- [Auth storage](/concepts/oauth)
|
||||
|
||||
@@ -7,8 +7,6 @@ read_when:
|
||||
title: "Scheduled tasks"
|
||||
---
|
||||
|
||||
# Scheduled Tasks (Cron)
|
||||
|
||||
Cron is the Gateway's built-in scheduler. It persists jobs, wakes the agent at the right time, and can deliver output back to a chat channel or webhook endpoint.
|
||||
|
||||
## Quick start
|
||||
|
||||
@@ -106,7 +106,7 @@ const handler = async (event) => {
|
||||
export default handler;
|
||||
```
|
||||
|
||||
Each event includes: `type`, `action`, `sessionKey`, `timestamp`, `messages` (push to send to user), and `context` (event-specific data).
|
||||
Each event includes: `type`, `action`, `sessionKey`, `timestamp`, `messages` (push to send to user), and `context` (event-specific data). Agent and tool plugin hook contexts can also include `trace`, a read-only W3C-compatible diagnostic trace context that plugins may pass into structured logs for OTEL correlation.
|
||||
|
||||
### Event context highlights
|
||||
|
||||
@@ -205,9 +205,12 @@ Runs `BOOT.md` from the active workspace when the gateway starts.
|
||||
|
||||
## Plugin hooks
|
||||
|
||||
Plugins can register hooks through the Plugin SDK for deeper integration: intercepting tool calls, modifying prompts, controlling message flow, and more. The Plugin SDK exposes 28 hooks covering model resolution, agent lifecycle, message flow, tool execution, subagent coordination, and gateway lifecycle.
|
||||
Plugins can register typed hooks through the Plugin SDK for deeper integration:
|
||||
intercepting tool calls, modifying prompts, controlling message flow, and more.
|
||||
Use plugin hooks when you need `before_tool_call`, `before_agent_reply`,
|
||||
`before_install`, or other in-process lifecycle hooks.
|
||||
|
||||
For the complete plugin hook reference including `before_tool_call`, `before_agent_reply`, `before_install`, and all other plugin hooks, see [Plugin Architecture](/plugins/architecture-internals#provider-runtime-hooks).
|
||||
For the complete plugin hook reference, see [Plugin hooks](/plugins/hooks).
|
||||
|
||||
## Configuration
|
||||
|
||||
@@ -315,5 +318,5 @@ Check for missing binaries (PATH), environment variables, config values, or OS c
|
||||
|
||||
- [CLI Reference: hooks](/cli/hooks)
|
||||
- [Webhooks](/automation/cron-jobs#webhooks)
|
||||
- [Plugin Architecture](/plugins/architecture-internals#provider-runtime-hooks) — full plugin hook reference
|
||||
- [Plugin hooks](/plugins/hooks) — in-process plugin lifecycle hooks
|
||||
- [Configuration](/gateway/configuration-reference#hooks)
|
||||
|
||||
@@ -40,7 +40,7 @@ flowchart TD
|
||||
| Audit what ran and when | Background Tasks | `openclaw tasks list` and `openclaw tasks audit` |
|
||||
| Multi-step research then summarize | Task Flow | Durable orchestration with revision tracking |
|
||||
| Run a script on session reset | Hooks | Event-driven, fires on lifecycle events |
|
||||
| Execute code on every tool call | Hooks | Hooks can filter by event type |
|
||||
| Execute code on every tool call | Plugin hooks | In-process hooks can intercept tool calls |
|
||||
| Always check compliance before replying | Standing Orders | Injected into every session automatically |
|
||||
|
||||
### Scheduled Tasks (Cron) vs Heartbeat
|
||||
@@ -83,7 +83,11 @@ See [Standing Orders](/automation/standing-orders).
|
||||
|
||||
### Hooks
|
||||
|
||||
Hooks are event-driven scripts triggered by agent lifecycle events (`/new`, `/reset`, `/stop`), session compaction, gateway startup, message flow, and tool calls. Hooks are automatically discovered from directories and can be managed with `openclaw hooks`.
|
||||
Internal hooks are event-driven scripts triggered by agent lifecycle events
|
||||
(`/new`, `/reset`, `/stop`), session compaction, gateway startup, and message
|
||||
flow. They are automatically discovered from directories and can be managed
|
||||
with `openclaw hooks`. For in-process tool-call interception, use
|
||||
[Plugin hooks](/plugins/hooks).
|
||||
|
||||
See [Hooks](/automation/hooks).
|
||||
|
||||
@@ -97,7 +101,7 @@ See [Heartbeat](/gateway/heartbeat).
|
||||
|
||||
- **Cron** handles precise schedules (daily reports, weekly reviews) and one-shot reminders. All cron executions create task records.
|
||||
- **Heartbeat** handles routine monitoring (inbox, calendar, notifications) in one batched turn every 30 minutes.
|
||||
- **Hooks** react to specific events (tool calls, session resets, compaction) with custom scripts.
|
||||
- **Hooks** react to specific events (session resets, compaction, message flow) with custom scripts. Plugin hooks cover tool calls.
|
||||
- **Standing orders** give the agent persistent context and authority boundaries.
|
||||
- **Task Flow** coordinates multi-step flows above individual tasks.
|
||||
- **Tasks** automatically track all detached work so you can inspect and audit it.
|
||||
@@ -108,6 +112,7 @@ See [Heartbeat](/gateway/heartbeat).
|
||||
- [Background Tasks](/automation/tasks) — task ledger for all detached work
|
||||
- [Task Flow](/automation/taskflow) — durable multi-step flow orchestration
|
||||
- [Hooks](/automation/hooks) — event-driven lifecycle scripts
|
||||
- [Plugin hooks](/plugins/hooks) — in-process tool, prompt, message, and lifecycle hooks
|
||||
- [Standing Orders](/automation/standing-orders) — persistent agent instructions
|
||||
- [Heartbeat](/gateway/heartbeat) — periodic main-session turns
|
||||
- [Configuration Reference](/gateway/configuration-reference) — all config keys
|
||||
|
||||
@@ -27,7 +27,7 @@ This is the difference between telling your assistant "send the weekly report" e
|
||||
- You only get involved for exceptions and approvals
|
||||
- The agent fills idle time productively
|
||||
|
||||
## How They Work
|
||||
## How they work
|
||||
|
||||
Standing orders are defined in your [agent workspace](/concepts/agent-workspace) files. The recommended approach is to include them directly in `AGENTS.md` (which is auto-injected every session) so the agent always has them in context. For larger configurations, you can also place them in a dedicated file like `standing-orders.md` and reference it from `AGENTS.md`.
|
||||
|
||||
@@ -198,8 +198,6 @@ This pattern prevents the most common agent failure mode: acknowledging a task w
|
||||
For agents managing multiple concerns, organize standing orders as separate programs with clear boundaries:
|
||||
|
||||
```markdown
|
||||
# Standing Orders
|
||||
|
||||
## Program 1: [Domain A] (Weekly)
|
||||
|
||||
...
|
||||
|
||||
@@ -20,6 +20,78 @@ Use Task Flow when work spans multiple sequential or branching steps and you nee
|
||||
| Observe externally created tasks | Task Flow (mirrored) |
|
||||
| One-shot reminder | Cron job |
|
||||
|
||||
## Reliable scheduled workflow pattern
|
||||
|
||||
For recurring workflows such as market intelligence briefings, treat the schedule, orchestration, and reliability checks as separate layers:
|
||||
|
||||
1. Use [Scheduled Tasks](/automation/cron-jobs) for timing.
|
||||
2. Use a persistent cron session when the workflow should build on prior context.
|
||||
3. Use [Lobster](/tools/lobster) for deterministic steps, approval gates, and resume tokens.
|
||||
4. Use Task Flow to track the multi-step run across child tasks, waits, retries, and gateway restarts.
|
||||
|
||||
Example cron shape:
|
||||
|
||||
```bash
|
||||
openclaw cron add \
|
||||
--name "Market intelligence brief" \
|
||||
--cron "0 7 * * 1-5" \
|
||||
--tz "America/New_York" \
|
||||
--session session:market-intel \
|
||||
--message "Run the market-intel Lobster workflow. Verify source freshness before summarizing." \
|
||||
--announce \
|
||||
--channel slack \
|
||||
--to "channel:C1234567890"
|
||||
```
|
||||
|
||||
Use `session:<id>` instead of `isolated` when the recurring workflow needs deliberate history, previous run summaries, or standing context. Use `isolated` when each run should start fresh and all required state is explicit in the workflow.
|
||||
|
||||
Inside the workflow, put reliability checks before the LLM summary step:
|
||||
|
||||
```yaml
|
||||
name: market-intel-brief
|
||||
steps:
|
||||
- id: preflight
|
||||
command: market-intel check --json
|
||||
- id: collect
|
||||
command: market-intel collect --json
|
||||
stdin: $preflight.json
|
||||
- id: summarize
|
||||
command: market-intel summarize --json
|
||||
stdin: $collect.json
|
||||
- id: approve
|
||||
command: market-intel deliver --preview
|
||||
stdin: $summarize.json
|
||||
approval: required
|
||||
- id: deliver
|
||||
command: market-intel deliver --execute
|
||||
stdin: $summarize.json
|
||||
condition: $approve.approved
|
||||
```
|
||||
|
||||
Recommended preflight checks:
|
||||
|
||||
- Browser availability and profile choice, for example `openclaw` for managed state or `user` when a signed-in Chrome session is required. See [Browser](/tools/browser).
|
||||
- API credentials and quota for each source.
|
||||
- Network reachability for required endpoints.
|
||||
- Required tools enabled for the agent, such as `lobster`, `browser`, and `llm-task`.
|
||||
- Failure destination configured for cron so preflight failures are visible. See [Scheduled Tasks](/automation/cron-jobs#delivery-and-output).
|
||||
|
||||
Recommended data provenance fields for every collected item:
|
||||
|
||||
```json
|
||||
{
|
||||
"sourceUrl": "https://example.com/report",
|
||||
"retrievedAt": "2026-04-24T12:00:00Z",
|
||||
"asOf": "2026-04-24",
|
||||
"title": "Example report",
|
||||
"content": "..."
|
||||
}
|
||||
```
|
||||
|
||||
Have the workflow reject or mark stale items before summarization. The LLM step should receive only structured JSON and should be asked to preserve `sourceUrl`, `retrievedAt`, and `asOf` in its output. Use [LLM Task](/tools/llm-task) when you need a schema-validated model step inside the workflow.
|
||||
|
||||
For reusable team or community workflows, package the CLI, `.lobster` files, and any setup notes as a skill or plugin and publish it through [ClawHub](/tools/clawhub). Keep workflow-specific guardrails in that package unless the plugin API is missing a needed generic capability.
|
||||
|
||||
## Sync modes
|
||||
|
||||
### Managed mode
|
||||
|
||||
@@ -101,3 +101,7 @@ await web_search({
|
||||
- Results are cached for 15 minutes by default (configurable via `cacheTtlMinutes`).
|
||||
|
||||
See [Web tools](/tools/web) for the full web_search configuration.
|
||||
|
||||
## Related
|
||||
|
||||
- [Brave search](/tools/brave-search)
|
||||
|
||||
@@ -7,8 +7,6 @@ read_when:
|
||||
title: "BlueBubbles"
|
||||
---
|
||||
|
||||
# BlueBubbles (macOS REST)
|
||||
|
||||
Status: bundled plugin that talks to the BlueBubbles macOS server over HTTP. **Recommended for iMessage integration** due to its richer API and easier setup compared to the legacy imsg channel.
|
||||
|
||||
## Bundled plugin
|
||||
|
||||
@@ -433,14 +433,10 @@ Planned features:
|
||||
- [ ] Dynamic agent selection (choose agents based on message content)
|
||||
- [ ] Agent priorities (some agents respond before others)
|
||||
|
||||
## See Also
|
||||
|
||||
- [Multi-Agent Configuration](/tools/multi-agent-sandbox-tools)
|
||||
- [Routing Configuration](/channels/channel-routing)
|
||||
- [Session Management](/concepts/session)
|
||||
|
||||
## Related
|
||||
|
||||
- [Groups](/channels/groups)
|
||||
- [Channel routing](/channels/channel-routing)
|
||||
- [Pairing](/channels/pairing)
|
||||
- [Multi-agent sandbox tools](/tools/multi-agent-sandbox-tools)
|
||||
- [Session management](/concepts/session)
|
||||
|
||||
@@ -305,7 +305,7 @@ By default, components are single use. Set `components.reusable=true` to allow b
|
||||
|
||||
To restrict who can click a button, set `allowedUsers` on that button (Discord user IDs, tags, or `*`). When configured, unmatched users receive an ephemeral denial.
|
||||
|
||||
The `/model` and `/models` slash commands open an interactive model picker with provider and model dropdowns plus a Submit step. Unless `commands.modelsWrite=false`, `/models add` also supports adding a new provider/model entry from chat, and newly added models show up without restarting the gateway. The picker reply is ephemeral and only the invoking user can use it.
|
||||
The `/model` and `/models` slash commands open an interactive model picker with provider, model, and compatible runtime dropdowns plus a Submit step. `/models add` is deprecated and now returns a deprecation message instead of registering models from chat. The picker reply is ephemeral and only the invoking user can use it.
|
||||
|
||||
File attachments:
|
||||
|
||||
|
||||
@@ -5,8 +5,6 @@ read_when:
|
||||
title: "Group messages"
|
||||
---
|
||||
|
||||
# Group messages (WhatsApp web channel)
|
||||
|
||||
Goal: let Clawd sit in WhatsApp groups, wake up only when pinged, and keep that thread separate from the personal DM session.
|
||||
|
||||
Note: `agents.list[].groupChat.mentionPatterns` is now used by Telegram/Discord/Slack/iMessage as well; this doc focuses on WhatsApp-specific behavior. For multi-agent setups, set `agents.list[].groupChat.mentionPatterns` per agent (or use `messages.groupChat.mentionPatterns` as a global fallback).
|
||||
|
||||
@@ -6,8 +6,6 @@ read_when:
|
||||
title: "iMessage"
|
||||
---
|
||||
|
||||
# iMessage (legacy: imsg)
|
||||
|
||||
<Warning>
|
||||
For new iMessage deployments, use <a href="/channels/bluebubbles">BlueBubbles</a>.
|
||||
|
||||
|
||||
@@ -9,6 +9,16 @@ title: "Chat channels"
|
||||
OpenClaw can talk to you on any chat app you already use. Each channel connects via the Gateway.
|
||||
Text is supported everywhere; media and reactions vary by channel.
|
||||
|
||||
## Delivery notes
|
||||
|
||||
- Telegram replies that contain markdown image syntax, such as ``,
|
||||
are converted into media replies on the final outbound path when possible.
|
||||
- Slack multi-person DMs route as group chats, so group policy, mention
|
||||
behavior, and group-session rules apply to MPIM conversations.
|
||||
- WhatsApp setup is install-on-demand: onboarding can show the setup flow before
|
||||
Baileys runtime dependencies are staged, and the Gateway loads the WhatsApp
|
||||
runtime only when the channel is actually active.
|
||||
|
||||
## Supported channels
|
||||
|
||||
- [BlueBubbles](/channels/bluebubbles) — **Recommended for iMessage**; uses the BlueBubbles macOS server REST API with full feature support (bundled plugin; edit, unsend, effects, reactions, group management — edit currently broken on macOS 26 Tahoe).
|
||||
|
||||
@@ -75,7 +75,7 @@ Disable with:
|
||||
|
||||
- Default: `channels.msteams.dmPolicy = "pairing"`. Unknown senders are ignored until approved.
|
||||
- `channels.msteams.allowFrom` should use stable AAD object IDs.
|
||||
- UPNs/display names are mutable; direct matching is disabled by default and only enabled with `channels.msteams.dangerouslyAllowNameMatching: true`.
|
||||
- Do not rely on UPN/display-name matching for allowlists — they can change. OpenClaw disables direct name matching by default; opt in explicitly with `channels.msteams.dangerouslyAllowNameMatching: true`.
|
||||
- The wizard can resolve names to IDs via Microsoft Graph when credentials allow.
|
||||
|
||||
**Group access**
|
||||
|
||||
@@ -44,6 +44,31 @@ Details: [Plugins](/tools/plugin)
|
||||
4. Configure OpenClaw:
|
||||
- Config: `channels.nextcloud-talk.baseUrl` + `channels.nextcloud-talk.botSecret`
|
||||
- Or env: `NEXTCLOUD_TALK_BOT_SECRET` (default account only)
|
||||
|
||||
CLI setup:
|
||||
|
||||
```bash
|
||||
openclaw channels add --channel nextcloud-talk \
|
||||
--url https://cloud.example.com \
|
||||
--token "<shared-secret>"
|
||||
```
|
||||
|
||||
Equivalent explicit fields:
|
||||
|
||||
```bash
|
||||
openclaw channels add --channel nextcloud-talk \
|
||||
--base-url https://cloud.example.com \
|
||||
--secret "<shared-secret>"
|
||||
```
|
||||
|
||||
File-backed secret:
|
||||
|
||||
```bash
|
||||
openclaw channels add --channel nextcloud-talk \
|
||||
--base-url https://cloud.example.com \
|
||||
--secret-file /path/to/nextcloud-talk-secret
|
||||
```
|
||||
|
||||
5. Restart the gateway (or finish setup).
|
||||
|
||||
Minimal config:
|
||||
|
||||
@@ -6,8 +6,6 @@ read_when:
|
||||
title: "Signal"
|
||||
---
|
||||
|
||||
# Signal (signal-cli)
|
||||
|
||||
Status: external CLI integration. Gateway talks to `signal-cli` over HTTP JSON-RPC + SSE.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
@@ -301,8 +301,8 @@ Surface different features that extend the above defaults.
|
||||
},
|
||||
{
|
||||
"command": "/models",
|
||||
"description": "List providers/models or add a model",
|
||||
"usage_hint": "[provider] [page] [limit=<n>|size=<n>|all] | add <provider> <modelId>"
|
||||
"description": "List providers/models",
|
||||
"usage_hint": "[provider] [page] [limit=<n>|size=<n>|all]"
|
||||
},
|
||||
{
|
||||
"command": "/help",
|
||||
|
||||
@@ -64,6 +64,13 @@ openclaw channels login --channel whatsapp
|
||||
|
||||
```bash
|
||||
openclaw channels login --channel whatsapp --account work
|
||||
```
|
||||
|
||||
To attach an existing/custom WhatsApp Web auth directory before login:
|
||||
|
||||
```bash
|
||||
openclaw channels add --channel whatsapp --account work --auth-dir /path/to/wa-auth
|
||||
openclaw channels login --channel whatsapp --account work
|
||||
```
|
||||
|
||||
</Step>
|
||||
@@ -164,7 +171,7 @@ OpenClaw recommends running WhatsApp on a separate number when possible. (The ch
|
||||
|
||||
- pairings are persisted in channel allow-store and merged with configured `allowFrom`
|
||||
- if no allowlist is configured, the linked self number is allowed by default
|
||||
- outbound `fromMe` DMs are never auto-paired
|
||||
- OpenClaw never auto-pairs outbound `fromMe` DMs (messages you send to yourself from the linked device)
|
||||
|
||||
</Tab>
|
||||
|
||||
@@ -493,15 +500,15 @@ Resolution hierarchy for group messages:
|
||||
|
||||
The effective `groups` map is determined first: if the account defines its own `groups`, it fully replaces the root `groups` map (no deep merge). Prompt lookup then runs on the resulting single map:
|
||||
|
||||
1. **Group-specific system prompt** (`groups["<groupId>"].systemPrompt`): used if the specific group entry defines a `systemPrompt`.
|
||||
2. **Group wildcard system prompt** (`groups["*"].systemPrompt`): used when the specific group entry is absent or defines no `systemPrompt`.
|
||||
1. **Group-specific system prompt** (`groups["<groupId>"].systemPrompt`): used when the specific group entry exists in the map **and** its `systemPrompt` key is defined. If `systemPrompt` is an empty string (`""`), the wildcard is suppressed and no system prompt is applied.
|
||||
2. **Group wildcard system prompt** (`groups["*"].systemPrompt`): used when the specific group entry is absent from the map entirely, or when it exists but defines no `systemPrompt` key.
|
||||
|
||||
Resolution hierarchy for direct messages:
|
||||
|
||||
The effective `direct` map is determined first: if the account defines its own `direct`, it fully replaces the root `direct` map (no deep merge). Prompt lookup then runs on the resulting single map:
|
||||
|
||||
1. **Direct-specific system prompt** (`direct["<peerId>"].systemPrompt`): used if the specific peer entry defines a `systemPrompt`.
|
||||
2. **Direct wildcard system prompt** (`direct["*"].systemPrompt`): used when the specific peer entry is absent or defines no `systemPrompt`.
|
||||
1. **Direct-specific system prompt** (`direct["<peerId>"].systemPrompt`): used when the specific peer entry exists in the map **and** its `systemPrompt` key is defined. If `systemPrompt` is an empty string (`""`), the wildcard is suppressed and no system prompt is applied.
|
||||
2. **Direct wildcard system prompt** (`direct["*"].systemPrompt`): used when the specific peer entry is absent from the map entirely, or when it exists but defines no `systemPrompt` key.
|
||||
|
||||
Note: `dms` remains the lightweight per-DM history override bucket (`dms.<id>.historyLimit`); prompt overrides live under `direct`.
|
||||
|
||||
|
||||
@@ -5,8 +5,6 @@ read_when:
|
||||
title: "Zalo"
|
||||
---
|
||||
|
||||
# Zalo (Bot API)
|
||||
|
||||
Status: experimental. DMs are supported. The [Capabilities](#capabilities) section below reflects current Marketplace-bot behavior.
|
||||
|
||||
## Bundled plugin
|
||||
|
||||
@@ -6,8 +6,6 @@ read_when:
|
||||
title: "Zalo personal"
|
||||
---
|
||||
|
||||
# Zalo Personal (unofficial)
|
||||
|
||||
Status: experimental. This integration automates a **personal Zalo account** via native `zca-js` inside OpenClaw.
|
||||
|
||||
> **Warning:** This is an unofficial integration and may result in account suspension/ban. Use at your own risk.
|
||||
|
||||
@@ -91,7 +91,7 @@ Jobs are ordered so cheap checks fail before expensive ones run:
|
||||
Scope logic lives in `scripts/ci-changed-scope.mjs` and is covered by unit tests in `src/scripts/ci-changed-scope.test.ts`.
|
||||
CI workflow edits validate the Node CI graph plus workflow linting, but do not force Windows, Android, or macOS native builds by themselves; those platform lanes stay scoped to platform source changes.
|
||||
Windows Node checks are scoped to Windows-specific process/path wrappers, npm/pnpm/UI runner helpers, package manager config, and the CI workflow surfaces that execute that lane; unrelated source, plugin, install-smoke, and test-only changes stay on the Linux Node lanes so they do not reserve a 16-vCPU Windows worker for coverage that is already exercised by the normal test shards.
|
||||
The separate `install-smoke` workflow reuses the same scope script through its own `preflight` job. It splits smoke coverage into `run_fast_install_smoke` and `run_full_install_smoke`. Pull requests run the fast path for Docker/package surfaces, bundled plugin package/manifest changes, and core plugin/channel/gateway/Plugin SDK surfaces that the Docker smoke jobs exercise. Source-only bundled plugin changes, test-only edits, and docs-only edits do not reserve Docker workers. The fast path builds the root Dockerfile image once, checks the CLI, runs the container gateway-network e2e, verifies a bundled extension build arg, and runs the bounded bundled-plugin Docker profile under a 120-second command timeout. The full path keeps QR package install and installer Docker/update coverage for nightly scheduled runs, manual dispatches, workflow-call release checks, and pull requests that truly touch installer/package/Docker surfaces. `main` pushes, including merge commits, do not force the full path; when changed-scope logic would request full coverage on a push, the workflow keeps the fast Docker smoke and leaves the full install smoke to nightly or release validation. The slow Bun global install image-provider smoke is separately gated by `run_bun_global_install_smoke`; it runs on the nightly schedule and from the release checks workflow, and manual `install-smoke` dispatches can opt into it, but pull requests and `main` pushes do not run it. QR and installer Docker tests keep their own install-focused Dockerfiles. Local `test:docker:all` prebuilds one shared live-test image and one shared `scripts/e2e/Dockerfile` built-app image, then runs the live/E2E smoke lanes in parallel with `OPENCLAW_SKIP_DOCKER_BUILD=1`; tune the default concurrency of 4 with `OPENCLAW_DOCKER_ALL_PARALLELISM`. The local aggregate stops scheduling new pooled lanes after the first failure by default, and each lane has a 120-minute timeout overrideable with `OPENCLAW_DOCKER_ALL_LANE_TIMEOUT_MS`. Startup- or provider-sensitive lanes run exclusively after the parallel pool. The reusable live/E2E workflow mirrors the shared-image pattern by building and pushing one SHA-tagged GHCR Docker E2E image before the Docker matrix, then running the matrix with `OPENCLAW_SKIP_DOCKER_BUILD=1`. The scheduled live/E2E workflow runs the full release-path Docker suite daily. The full bundled update/channel matrix remains manual/full-suite because it performs repeated real npm update and doctor repair passes.
|
||||
The separate `install-smoke` workflow reuses the same scope script through its own `preflight` job. It splits smoke coverage into `run_fast_install_smoke` and `run_full_install_smoke`. Pull requests run the fast path for Docker/package surfaces, bundled plugin package/manifest changes, and core plugin/channel/gateway/Plugin SDK surfaces that the Docker smoke jobs exercise. Source-only bundled plugin changes, test-only edits, and docs-only edits do not reserve Docker workers. The fast path builds the root Dockerfile image once, checks the CLI, runs the container gateway-network e2e, verifies a bundled extension build arg, and runs the bounded bundled-plugin Docker profile under a 120-second command timeout. The full path keeps QR package install and installer Docker/update coverage for nightly scheduled runs, manual dispatches, workflow-call release checks, and pull requests that truly touch installer/package/Docker surfaces. `main` pushes, including merge commits, do not force the full path; when changed-scope logic would request full coverage on a push, the workflow keeps the fast Docker smoke and leaves the full install smoke to nightly or release validation. The slow Bun global install image-provider smoke is separately gated by `run_bun_global_install_smoke`; it runs on the nightly schedule and from the release checks workflow, and manual `install-smoke` dispatches can opt into it, but pull requests and `main` pushes do not run it. QR and installer Docker tests keep their own install-focused Dockerfiles. Local `test:docker:all` prebuilds one shared live-test image and one shared `scripts/e2e/Dockerfile` built-app image, then runs the live/E2E smoke lanes in parallel with `OPENCLAW_SKIP_DOCKER_BUILD=1`; tune the default main-pool concurrency of 8 with `OPENCLAW_DOCKER_ALL_PARALLELISM` and the provider-sensitive tail-pool concurrency of 8 with `OPENCLAW_DOCKER_ALL_TAIL_PARALLELISM`. Lane starts are staggered by 2 seconds by default to avoid local Docker daemon create storms; override with `OPENCLAW_DOCKER_ALL_START_STAGGER_MS=0` or another millisecond value. The local aggregate stops scheduling new pooled lanes after the first failure by default, and each lane has a 120-minute timeout overrideable with `OPENCLAW_DOCKER_ALL_LANE_TIMEOUT_MS`. The reusable live/E2E workflow mirrors the shared-image pattern by building and pushing one SHA-tagged GHCR Docker E2E image before the Docker matrix, then running the matrix with `OPENCLAW_SKIP_DOCKER_BUILD=1`. The scheduled live/E2E workflow runs the full release-path Docker suite daily. The full bundled update/channel matrix remains manual/full-suite because it performs repeated real npm update and doctor repair passes.
|
||||
|
||||
Local changed-lane logic lives in `scripts/changed-lanes.mjs` and is executed by `scripts/check-changed.mjs`. That local gate is stricter about architecture boundaries than the broad CI platform scope: core production changes run core prod typecheck plus core tests, core test-only changes run only core test typecheck/tests, extension production changes run extension prod typecheck plus extension tests, and extension test-only changes run only extension test typecheck/tests. Public Plugin SDK or plugin-contract changes expand to extension validation because extensions depend on those core contracts. Release metadata-only version bumps run targeted version/config/root-dependency checks. Unknown root/config changes fail safe to all lanes.
|
||||
|
||||
@@ -136,3 +136,8 @@ node scripts/ci-run-timings.mjs --recent 10 # compare recent successful main C
|
||||
pnpm test:perf:groups --full-suite --allow-failures --output .artifacts/test-perf/baseline-before.json
|
||||
pnpm test:perf:groups:compare .artifacts/test-perf/baseline-before.json .artifacts/test-perf/after-agent.json
|
||||
```
|
||||
|
||||
## Related
|
||||
|
||||
- [Install overview](/install)
|
||||
- [Release channels](/install/development-channels)
|
||||
|
||||
@@ -314,3 +314,8 @@ Security note:
|
||||
- `--server-args <args...>`: extra arguments passed to the ACP server.
|
||||
- `--server-verbose`: enable verbose logging on the ACP server.
|
||||
- `--verbose, -v`: verbose client logging.
|
||||
|
||||
## Related
|
||||
|
||||
- [CLI reference](/cli)
|
||||
- [ACP agents](/tools/acp-agents)
|
||||
|
||||
@@ -82,3 +82,7 @@ Practical limits come from the local machine and destination filesystem:
|
||||
Large workspaces are usually the main driver of archive size. If you want a smaller or faster backup, use `--no-include-workspace`.
|
||||
|
||||
For the smallest archive, use `--only-config`.
|
||||
|
||||
## Related
|
||||
|
||||
- [CLI reference](/cli)
|
||||
|
||||
@@ -245,3 +245,8 @@ If the Gateway runs on a different machine than the browser, run a **node host**
|
||||
Use `gateway.nodes.browser.mode` to control auto-routing and `gateway.nodes.browser.node` to pin a specific node if multiple are connected.
|
||||
|
||||
Security + remote setup: [Browser tool](/tools/browser), [Remote access](/gateway/remote), [Tailscale](/gateway/tailscale), [Security](/gateway/security)
|
||||
|
||||
## Related
|
||||
|
||||
- [CLI reference](/cli)
|
||||
- [Browser](/tools/browser)
|
||||
|
||||
@@ -19,3 +19,7 @@ Current supported alias:
|
||||
Prefer modern top-level commands directly:
|
||||
|
||||
- `openclaw clawbot qr` -> `openclaw qr`
|
||||
|
||||
## Related
|
||||
|
||||
- [CLI reference](/cli)
|
||||
|
||||
@@ -33,3 +33,7 @@ openclaw completion --shell bash --write-state
|
||||
- `--install` writes a small "OpenClaw Completion" block into your shell profile and points it at the cached script.
|
||||
- Without `--install` or `--write-state`, the command prints the script to stdout.
|
||||
- Completion generation eagerly loads command trees so nested subcommands are included.
|
||||
|
||||
## Related
|
||||
|
||||
- [CLI reference](/cli)
|
||||
|
||||
@@ -70,3 +70,8 @@ openclaw configure --section web
|
||||
openclaw configure --section model --section channels
|
||||
openclaw configure --section gateway --section daemon
|
||||
```
|
||||
|
||||
## Related
|
||||
|
||||
- [CLI reference](/cli)
|
||||
- [Configuration](/gateway/configuration)
|
||||
|
||||
@@ -174,3 +174,8 @@ Failure-delivery note:
|
||||
delivery mode is `webhook`.
|
||||
- If you do not set any failure destination and the job already announces to a
|
||||
channel, failure notifications reuse that same announce target.
|
||||
|
||||
## Related
|
||||
|
||||
- [CLI reference](/cli)
|
||||
- [Scheduled tasks](/automation/cron-jobs)
|
||||
|
||||
@@ -55,3 +55,8 @@ Notes:
|
||||
## Prefer
|
||||
|
||||
Use [`openclaw gateway`](/cli/gateway) for current docs and examples.
|
||||
|
||||
## Related
|
||||
|
||||
- [CLI reference](/cli)
|
||||
- [Gateway runbook](/gateway)
|
||||
|
||||
@@ -20,3 +20,8 @@ Notes:
|
||||
- `dashboard` resolves configured `gateway.auth.token` SecretRefs when possible.
|
||||
- For SecretRef-managed tokens (resolved or unresolved), `dashboard` prints/copies/opens a non-tokenized URL to avoid exposing external secrets in terminal output, clipboard history, or browser-launch arguments.
|
||||
- If `gateway.auth.token` is SecretRef-managed but unresolved in this command path, the command prints a non-tokenized URL and explicit remediation guidance instead of embedding an invalid token placeholder.
|
||||
|
||||
## Related
|
||||
|
||||
- [CLI reference](/cli)
|
||||
- [Dashboard](/web/dashboard)
|
||||
|
||||
@@ -178,3 +178,8 @@ Related:
|
||||
|
||||
- [Dashboard auth troubleshooting](/web/dashboard#if-you-see-unauthorized-1008)
|
||||
- [Gateway troubleshooting](/gateway/troubleshooting#dashboard-control-ui-connectivity)
|
||||
|
||||
## Related
|
||||
|
||||
- [CLI reference](/cli)
|
||||
- [Nodes](/nodes)
|
||||
|
||||
@@ -61,3 +61,7 @@ openclaw directory groups list --channel zalouser
|
||||
openclaw directory groups list --channel zalouser --query "work"
|
||||
openclaw directory groups members --channel zalouser --group-id <id>
|
||||
```
|
||||
|
||||
## Related
|
||||
|
||||
- [CLI reference](/cli)
|
||||
|
||||
@@ -46,3 +46,8 @@ Notes:
|
||||
- If `--domain` is omitted, OpenClaw uses `discovery.wideArea.domain` from config.
|
||||
- `--apply` currently supports macOS only and expects Homebrew CoreDNS.
|
||||
- `--apply` bootstraps the zone file if needed, ensures the CoreDNS import stanza exists, and restarts the `coredns` brew service.
|
||||
|
||||
## Related
|
||||
|
||||
- [CLI reference](/cli)
|
||||
- [Discovery](/gateway/discovery)
|
||||
|
||||
@@ -26,3 +26,7 @@ Notes:
|
||||
|
||||
- With no query, `openclaw docs` opens the live docs search entrypoint.
|
||||
- Multi-word queries are passed through as one search request.
|
||||
|
||||
## Related
|
||||
|
||||
- [CLI reference](/cli)
|
||||
|
||||
@@ -63,3 +63,8 @@ launchctl getenv OPENCLAW_GATEWAY_PASSWORD
|
||||
launchctl unsetenv OPENCLAW_GATEWAY_TOKEN
|
||||
launchctl unsetenv OPENCLAW_GATEWAY_PASSWORD
|
||||
```
|
||||
|
||||
## Related
|
||||
|
||||
- [CLI reference](/cli)
|
||||
- [Gateway doctor](/gateway/doctor)
|
||||
|
||||
@@ -16,3 +16,8 @@ openclaw tasks flow cancel <lookup>
|
||||
```
|
||||
|
||||
For full documentation see [Task Flow](/automation/taskflow) and the [tasks CLI reference](/cli/tasks).
|
||||
|
||||
## Related
|
||||
|
||||
- [CLI reference](/cli)
|
||||
- [Automation](/automation)
|
||||
|
||||
@@ -371,3 +371,8 @@ Notes:
|
||||
- On `local.` mDNS, `sshPort` and `cliPath` are only broadcast when
|
||||
`discovery.mdns.mode` is `full`. Wide-area DNS-SD still writes `cliPath`; `sshPort`
|
||||
stays optional there too.
|
||||
|
||||
## Related
|
||||
|
||||
- [CLI reference](/cli)
|
||||
- [Gateway runbook](/gateway)
|
||||
|
||||
@@ -34,3 +34,8 @@ Notes:
|
||||
- `--verbose` forces a live probe, prints gateway connection details, and expands the
|
||||
human-readable output across all configured accounts and agents.
|
||||
- Output includes per-agent session stores when multiple agents are configured.
|
||||
|
||||
## Related
|
||||
|
||||
- [CLI reference](/cli)
|
||||
- [Gateway health](/gateway/health)
|
||||
|
||||
@@ -15,7 +15,7 @@ Running `openclaw hooks` with no subcommand is equivalent to `openclaw hooks lis
|
||||
Related:
|
||||
|
||||
- Hooks: [Hooks](/automation/hooks)
|
||||
- Plugin hooks: [Plugin hooks](/plugins/architecture-internals#provider-runtime-hooks)
|
||||
- Plugin hooks: [Plugin hooks](/plugins/hooks)
|
||||
|
||||
## List All Hooks
|
||||
|
||||
|
||||
@@ -121,7 +121,7 @@ This table maps common inference tasks to the corresponding infer command.
|
||||
- Use `--json` when the output will be consumed by another command or script.
|
||||
- Use `--provider` or `--model provider/model` when a specific backend is required.
|
||||
- For `image describe`, `audio transcribe`, and `video describe`, `--model` must use the form `<provider/model>`.
|
||||
- For `image describe`, an explicit `--model` runs that provider/model directly. The model must be image-capable in the model catalog or provider config. `codex/<model>` runs a bounded Codex app-server image-understanding turn; `openai-codex/<model>` uses the OpenAI Codex OAuth provider path.
|
||||
- For `image describe`, an explicit `--model` runs that provider/model directly. The model must be image-capable in the model catalog or provider config. `openai-codex/<model>` uses the OpenAI Codex OAuth provider path. Legacy `codex/<model>` media refs still run a bounded Codex app-server image-understanding turn, but new text-agent configs should use `openai/<model>` plus the Codex harness policy instead.
|
||||
- Stateless execution commands default to local.
|
||||
- Gateway-managed state commands default to gateway.
|
||||
- The normal local path does not require the gateway to be running.
|
||||
|
||||
@@ -57,3 +57,8 @@ openclaw logs --url ws://127.0.0.1:18789 --token "$OPENCLAW_GATEWAY_TOKEN"
|
||||
|
||||
- Use `--local-time` to render timestamps in your local timezone.
|
||||
- If the local loopback Gateway asks for pairing, `openclaw logs` falls back to the configured local log file automatically. Explicit `--url` targets do not use this fallback.
|
||||
|
||||
## Related
|
||||
|
||||
- [CLI reference](/cli)
|
||||
- [Gateway logging](/gateway/logging)
|
||||
|
||||
@@ -174,3 +174,8 @@ Notes:
|
||||
- `memory rem-backfill --path <file-or-dir> --stage-short-term` also seeds grounded durable candidates into the live short-term promotion store so the normal deep phase can rank them.
|
||||
- `memory rem-backfill --rollback` removes previously written grounded diary entries, and `memory rem-backfill --rollback-short-term` removes previously staged grounded short-term candidates.
|
||||
- See [Dreaming](/concepts/dreaming) for full phase descriptions and configuration reference.
|
||||
|
||||
## Related
|
||||
|
||||
- [CLI reference](/cli)
|
||||
- [Memory overview](/concepts/memory)
|
||||
|
||||
@@ -296,3 +296,8 @@ Send a Telegram image as a document to avoid compression:
|
||||
openclaw message send --channel telegram --target @mychat \
|
||||
--media ./diagram.png --force-document
|
||||
```
|
||||
|
||||
## Related
|
||||
|
||||
- [CLI reference](/cli)
|
||||
- [Agent send](/tools/agent-send)
|
||||
|
||||
@@ -74,6 +74,13 @@ Options:
|
||||
- In `gateway.mode=remote`, remote client fields (`gateway.remote.token` / `gateway.remote.password`) are also eligible per remote precedence rules.
|
||||
- Node host auth resolution only honors `OPENCLAW_GATEWAY_*` env vars.
|
||||
|
||||
For a node connecting to a non-loopback `ws://` Gateway on a trusted private
|
||||
network, set `OPENCLAW_ALLOW_INSECURE_PRIVATE_WS=1`. Without it, node startup
|
||||
fails closed and asks you to use `wss://`, an SSH tunnel, or Tailscale.
|
||||
This is a process-environment opt-in, not an `openclaw.json` config key.
|
||||
`openclaw node install` persists it into the supervised node service when it is
|
||||
present in the install command environment.
|
||||
|
||||
## Service (background)
|
||||
|
||||
Install a headless node host as a user service.
|
||||
@@ -135,3 +142,8 @@ For approved async node exec, OpenClaw prepares a canonical `systemRunPlan`
|
||||
before prompting. The later approved `system.run` forward reuses that stored
|
||||
plan, so edits to command/cwd/session fields after the approval request was
|
||||
created are rejected instead of changing what the node executes.
|
||||
|
||||
## Related
|
||||
|
||||
- [CLI reference](/cli)
|
||||
- [Nodes](/nodes)
|
||||
|
||||
@@ -28,6 +28,8 @@ openclaw onboard --mode remote --remote-url wss://gateway-host:18789
|
||||
|
||||
For plaintext private-network `ws://` targets (trusted networks only), set
|
||||
`OPENCLAW_ALLOW_INSECURE_PRIVATE_WS=1` in the onboarding process environment.
|
||||
There is no `openclaw.json` equivalent for this client-side transport
|
||||
break-glass.
|
||||
|
||||
Non-interactive custom provider:
|
||||
|
||||
|
||||
@@ -200,6 +200,23 @@ table view to per-plugin detail lines with source/origin/version/activation
|
||||
metadata. Use `--json` for machine-readable inventory plus registry
|
||||
diagnostics.
|
||||
|
||||
`plugins list` runs discovery from the current CLI environment and config. It is
|
||||
useful for checking whether a plugin is enabled/loadable, but it is not a live
|
||||
runtime probe of an already-running Gateway process. After changing plugin code,
|
||||
enablement, hook policy, or `plugins.load.paths`, restart the Gateway that
|
||||
serves the channel before expecting new `register(api)` code or hooks to run.
|
||||
For remote/container deployments, verify you are restarting the actual
|
||||
`openclaw gateway run` child, not only a wrapper process.
|
||||
|
||||
For runtime hook debugging:
|
||||
|
||||
- `openclaw plugins inspect <id> --json` shows registered hooks and diagnostics
|
||||
from a module-loaded inspection pass.
|
||||
- `openclaw gateway status --deep --require-rpc` confirms the reachable Gateway,
|
||||
service/process hints, config path, and RPC health.
|
||||
- Non-bundled conversation hooks (`llm_input`, `llm_output`, `agent_end`) require
|
||||
`plugins.entries.<id>.hooks.allowConversationAccess=true`.
|
||||
|
||||
Use `--link` to avoid copying a local directory (adds to `plugins.load.paths`):
|
||||
|
||||
```bash
|
||||
|
||||
@@ -43,3 +43,8 @@ openclaw proxy purge
|
||||
- `start` defaults to `127.0.0.1` unless `--host` is set.
|
||||
- `run` starts a local debug proxy and then runs the command after `--`.
|
||||
- Captures are local debugging data; use `openclaw proxy purge` when finished.
|
||||
|
||||
## Related
|
||||
|
||||
- [CLI reference](/cli)
|
||||
- [Trusted proxy auth](/gateway/trusted-proxy-auth)
|
||||
|
||||
@@ -50,3 +50,8 @@ openclaw qr --url wss://gateway.example/ws
|
||||
- After scanning, approve device pairing with:
|
||||
- `openclaw devices list`
|
||||
- `openclaw devices approve <requestId>`
|
||||
|
||||
## Related
|
||||
|
||||
- [CLI reference](/cli)
|
||||
- [Pairing](/cli/pairing)
|
||||
|
||||
@@ -33,3 +33,7 @@ Notes:
|
||||
- Run `openclaw backup create` first if you want a restorable snapshot before removing local state.
|
||||
- If you omit `--scope`, `openclaw reset` uses an interactive prompt to choose what to remove.
|
||||
- `--non-interactive` is only valid when both `--scope` and `--yes` are set.
|
||||
|
||||
## Related
|
||||
|
||||
- [CLI reference](/cli)
|
||||
|
||||
@@ -188,13 +188,9 @@ Sandbox settings live in `~/.openclaw/openclaw.json` under `agents.defaults.sand
|
||||
}
|
||||
```
|
||||
|
||||
## See Also
|
||||
|
||||
- [Sandbox Documentation](/gateway/sandboxing)
|
||||
- [Agent Configuration](/concepts/agent-workspace)
|
||||
- [Doctor Command](/gateway/doctor) - Check sandbox setup
|
||||
|
||||
## Related
|
||||
|
||||
- [CLI reference](/cli)
|
||||
- [Sandboxing](/gateway/sandboxing)
|
||||
- [Agent workspace](/concepts/agent-workspace)
|
||||
- [Doctor](/gateway/doctor) — checks sandbox setup
|
||||
|
||||
@@ -195,3 +195,8 @@ openclaw secrets audit --check
|
||||
```
|
||||
|
||||
If `audit --check` still reports plaintext findings, update the remaining reported target paths and rerun audit.
|
||||
|
||||
## Related
|
||||
|
||||
- [CLI reference](/cli)
|
||||
- [Secrets management](/gateway/secrets)
|
||||
|
||||
@@ -84,3 +84,8 @@ openclaw security audit --fix --json | jq '{fix: .fix.ok, summary: .report.summa
|
||||
- disable tools (`gateway`, `cron`, `exec`, etc.)
|
||||
- change gateway bind/auth/network exposure choices
|
||||
- remove or rewrite plugins/skills
|
||||
|
||||
## Related
|
||||
|
||||
- [CLI reference](/cli)
|
||||
- [Security audit](/gateway/security)
|
||||
|
||||
@@ -43,3 +43,8 @@ Notes:
|
||||
|
||||
- Plain `openclaw setup` initializes config + workspace without the full onboarding flow.
|
||||
- Onboarding auto-runs when any onboarding flags are present (`--wizard`, `--non-interactive`, `--mode`, `--remote-url`, `--remote-token`).
|
||||
|
||||
## Related
|
||||
|
||||
- [CLI reference](/cli)
|
||||
- [Install overview](/install)
|
||||
|
||||
@@ -69,3 +69,7 @@ Flags:
|
||||
|
||||
- Requires a running Gateway reachable by your current config (local or remote).
|
||||
- System events are ephemeral and not persisted across restarts.
|
||||
|
||||
## Related
|
||||
|
||||
- [CLI reference](/cli)
|
||||
|
||||
@@ -94,3 +94,8 @@ openclaw tasks flow cancel <lookup>
|
||||
```
|
||||
|
||||
Inspects or cancels durable Task Flow state under the task ledger.
|
||||
|
||||
## Related
|
||||
|
||||
- [CLI reference](/cli)
|
||||
- [Background tasks](/automation/tasks)
|
||||
|
||||
@@ -65,3 +65,8 @@ Then inside the TUI:
|
||||
|
||||
Apply targeted fixes with `openclaw config set` or `openclaw configure`, then
|
||||
rerun `openclaw config validate`. See [TUI](/web/tui) and [Config](/cli/config).
|
||||
|
||||
## Related
|
||||
|
||||
- [CLI reference](/cli)
|
||||
- [TUI](/web/tui)
|
||||
|
||||
@@ -37,3 +37,8 @@ Notes:
|
||||
- Run `openclaw backup create` first if you want a restorable snapshot before removing state or workspaces.
|
||||
- `--all` is shorthand for removing service, state, workspace, and app together.
|
||||
- `--non-interactive` requires `--yes`.
|
||||
|
||||
## Related
|
||||
|
||||
- [CLI reference](/cli)
|
||||
- [Uninstall](/install/uninstall)
|
||||
|
||||
@@ -33,3 +33,8 @@ openclaw voicecall expose --mode off
|
||||
```
|
||||
|
||||
Security note: only expose the webhook endpoint to networks you trust. Prefer Tailscale Serve over Funnel when possible.
|
||||
|
||||
## Related
|
||||
|
||||
- [CLI reference](/cli)
|
||||
- [Voice call plugin](/plugins/voice-call)
|
||||
|
||||
@@ -89,3 +89,8 @@ openclaw webhooks gmail run --account you@example.com
|
||||
```
|
||||
|
||||
See [Gmail Pub/Sub documentation](/automation/cron-jobs#gmail-pubsub-integration) for the end-to-end setup flow and operational details.
|
||||
|
||||
## Related
|
||||
|
||||
- [CLI reference](/cli)
|
||||
- [Webhook automation](/automation/webhook)
|
||||
|
||||
@@ -212,3 +212,8 @@ These require the official `obsidian` CLI on `PATH` when
|
||||
- `plugins.entries.memory-wiki.config.context.includeCompiledDigestPrompt`
|
||||
|
||||
See [Memory Wiki plugin](/plugins/memory-wiki) for the full config model.
|
||||
|
||||
## Related
|
||||
|
||||
- [CLI reference](/cli)
|
||||
- [Memory wiki](/plugins/memory-wiki)
|
||||
|
||||
@@ -6,8 +6,6 @@ read_when:
|
||||
title: "Agent loop"
|
||||
---
|
||||
|
||||
# Agent Loop (OpenClaw)
|
||||
|
||||
An agentic loop is the full “real” run of an agent: intake → context assembly → model inference →
|
||||
tool execution → streaming replies → persistence. It’s the authoritative path that turns a message
|
||||
into actions and a final reply, while keeping session state consistent.
|
||||
@@ -112,7 +110,7 @@ Hook decision rules for outbound/tool guards:
|
||||
- `message_sending`: `{ cancel: true }` is terminal and stops lower-priority handlers.
|
||||
- `message_sending`: `{ cancel: false }` is a no-op and does not clear a prior cancel.
|
||||
|
||||
See [Plugin hooks](/plugins/architecture-internals#provider-runtime-hooks) for the hook API and registration details.
|
||||
See [Plugin hooks](/plugins/hooks) for the hook API and registration details.
|
||||
|
||||
Harnesses may adapt these hooks differently. The Codex app-server harness keeps
|
||||
OpenClaw plugin hooks as the compatibility contract for documented mirrored
|
||||
|
||||
@@ -5,7 +5,10 @@ read_when:
|
||||
title: "Agent runtime"
|
||||
---
|
||||
|
||||
OpenClaw runs a single embedded agent runtime.
|
||||
OpenClaw runs a **single embedded agent runtime** — one agent process per
|
||||
Gateway, with its own workspace, bootstrap files, and session store. This page
|
||||
covers that runtime contract: what the workspace must contain, which files get
|
||||
injected, and how sessions bootstrap against it.
|
||||
|
||||
## Workspace (required)
|
||||
|
||||
|
||||
@@ -113,20 +113,6 @@ the summary:
|
||||
/compact Focus on the API design decisions
|
||||
```
|
||||
|
||||
## Codex harness compaction
|
||||
|
||||
When an embedded agent session uses the Codex app-server harness, Codex owns the
|
||||
native thread and native compaction operation. OpenClaw keeps a transcript mirror
|
||||
for channel history and future harness switching, but the canonical compacted
|
||||
thread stays in Codex.
|
||||
|
||||
OpenClaw plugin hooks still expose `before_compaction` and `after_compaction`
|
||||
for the Codex harness from the app-server compaction item stream. Codex native
|
||||
`PreCompact` and `PostCompact` hooks, when supported by the installed Codex
|
||||
app-server, are separate Codex command hooks configured through Codex. They are
|
||||
useful for low-level Codex audit or policy, but they do not replace the
|
||||
OpenClaw plugin hook contract.
|
||||
|
||||
## Using a different model
|
||||
|
||||
By default, compaction uses your agent's primary model. You can use a more
|
||||
|
||||
@@ -77,6 +77,10 @@ four lifecycle points:
|
||||
4. **After turn** — called after a run completes. The engine can persist state,
|
||||
trigger background compaction, or update indexes.
|
||||
|
||||
For the bundled non-ACP Codex harness, OpenClaw applies the same lifecycle by
|
||||
projecting assembled context into Codex developer instructions and the current
|
||||
turn prompt. Codex still owns its native thread history and native compactor.
|
||||
|
||||
### Subagent lifecycle (optional)
|
||||
|
||||
OpenClaw calls two optional subagent lifecycle hooks:
|
||||
|
||||
@@ -147,7 +147,7 @@ What persists across messages depends on the mechanism:
|
||||
|
||||
- **Normal history** persists in the session transcript until compacted/pruned by policy.
|
||||
- **Compaction** persists a summary into the transcript and keeps recent messages intact.
|
||||
- **Pruning** removes old tool results from the _in-memory_ prompt for a run, but does not rewrite the transcript.
|
||||
- **Pruning** drops old tool results from the _in-memory_ prompt to free context-window space, but does not rewrite the session transcript — the full history is still inspectable on disk.
|
||||
|
||||
Docs: [Session](/concepts/session), [Compaction](/concepts/compaction), [Session pruning](/concepts/session-pruning).
|
||||
|
||||
|
||||
@@ -227,20 +227,8 @@ When enabled, the Gateway **Dreams** tab shows:
|
||||
- a distinct grounded Scene lane for staged historical replay entries
|
||||
- an expandable Dream Diary reader backed by `doctor.memory.dreamDiary`
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Dreaming never runs (status shows blocked)
|
||||
|
||||
The managed dreaming cron rides the default agent's heartbeat. If heartbeat is not firing for that agent, the cron enqueues a system event that nobody consumes and dreaming silently does not run. Both `openclaw memory status` and `/dreaming status` will report `blocked` in that case and name the agent whose heartbeat is the blocker.
|
||||
|
||||
Two common causes:
|
||||
|
||||
- Another agent declares an explicit `heartbeat:` block. When any entry in `agents.list` has its own `heartbeat` block, only those agents heartbeat — the defaults stop applying to everyone else, so the default agent can go silent. Move the heartbeat settings to `agents.defaults.heartbeat`, or add an explicit `heartbeat` block on the default agent. See [Scope and precedence](/gateway/heartbeat#scope-and-precedence).
|
||||
- `heartbeat.every` is `0`, empty, or unparsable. The cron has no interval to schedule against, so the heartbeat is effectively disabled. Set `every` to a positive duration such as `30m`. See [Defaults](/gateway/heartbeat#defaults).
|
||||
|
||||
## Related
|
||||
|
||||
- [Heartbeat](/gateway/heartbeat)
|
||||
- [Memory](/concepts/memory)
|
||||
- [Memory Search](/concepts/memory-search)
|
||||
- [memory CLI](/cli/memory)
|
||||
|
||||
@@ -25,7 +25,7 @@ Treat them differently from normal config:
|
||||
| ------------------------ | --------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------- |
|
||||
| Local model runtime | `agents.defaults.experimental.localModelLean` | A smaller or stricter local backend chokes on OpenClaw's full default tool surface | [Local Models](/gateway/local-models) |
|
||||
| Memory search | `agents.defaults.memorySearch.experimental.sessionMemory` | You want `memory_search` to index prior session transcripts and accept the extra storage/indexing cost | [Memory configuration reference](/reference/memory-config#session-memory-search-experimental) |
|
||||
| Structured planning tool | `tools.experimental.planTool` | You want the structured `update_plan` tool exposed for multi-step work tracking in compatible runtimes and UIs | [Gateway configuration reference](/gateway/configuration-reference#toolsexperimental) |
|
||||
| Structured planning tool | `tools.experimental.planTool` | You want the structured `update_plan` tool exposed for multi-step work tracking in compatible runtimes and UIs | [Gateway configuration reference](/gateway/config-tools#toolsexperimental) |
|
||||
|
||||
## Local model lean mode
|
||||
|
||||
|
||||
@@ -21,6 +21,15 @@ For model selection rules, see [/concepts/models](/concepts/models).
|
||||
and `openai/<model>` plus `agents.defaults.embeddedHarness.runtime: "codex"`
|
||||
uses the native Codex app-server harness. See [OpenAI](/providers/openai)
|
||||
and [Codex harness](/plugins/codex-harness).
|
||||
- Plugin auto-enable follows that same boundary: `openai-codex/<model>` belongs
|
||||
to the OpenAI plugin, while the Codex plugin is enabled by
|
||||
`embeddedHarness.runtime: "codex"` or legacy `codex/<model>` refs.
|
||||
- CLI runtimes use the same split: choose canonical model refs such as
|
||||
`anthropic/claude-*`, `google/gemini-*`, or `openai/gpt-*`, then set
|
||||
`agents.defaults.embeddedHarness.runtime` to `claude-cli`,
|
||||
`google-gemini-cli`, or `codex-cli` when you want a local CLI backend.
|
||||
Legacy `claude-cli/*`, `google-gemini-cli/*`, and `codex-cli/*` refs migrate
|
||||
back to canonical provider refs with the runtime recorded separately.
|
||||
- GPT-5.5 is currently available through subscription/OAuth routes:
|
||||
`openai-codex/gpt-5.5` in PI or `openai/gpt-5.5` with the Codex app-server
|
||||
harness. The direct API-key route for `openai/gpt-5.5` is supported once
|
||||
@@ -110,6 +119,9 @@ OpenClaw ships with the pi‑ai catalog. These providers require **no**
|
||||
- PI model ref: `openai-codex/gpt-5.5`
|
||||
- Native Codex app-server harness ref: `openai/gpt-5.5` with `agents.defaults.embeddedHarness.runtime: "codex"`
|
||||
- Legacy model refs: `codex/gpt-*`
|
||||
- Plugin boundary: `openai-codex/*` loads the OpenAI plugin; the native Codex
|
||||
app-server plugin is selected only by the Codex harness runtime or legacy
|
||||
`codex/*` refs.
|
||||
- CLI: `openclaw onboard --auth-choice openai-codex` or `openclaw models auth login --provider openai-codex`
|
||||
- Default transport is `auto` (WebSocket-first, SSE fallback)
|
||||
- Override per PI model via `agents.defaults.models["openai-codex/<model>"].params.transport` (`"sse"`, `"websocket"`, or `"auto"`)
|
||||
@@ -229,6 +241,7 @@ See [/providers/kilocode](/providers/kilocode) for setup details.
|
||||
| BytePlus | `byteplus` / `byteplus-plan` | `BYTEPLUS_API_KEY` | `byteplus-plan/ark-code-latest` |
|
||||
| Cerebras | `cerebras` | `CEREBRAS_API_KEY` | `cerebras/zai-glm-4.7` |
|
||||
| Cloudflare AI Gateway | `cloudflare-ai-gateway` | `CLOUDFLARE_AI_GATEWAY_API_KEY` | — |
|
||||
| DeepSeek | `deepseek` | `DEEPSEEK_API_KEY` | `deepseek/deepseek-v4-flash` |
|
||||
| GitHub Copilot | `github-copilot` | `COPILOT_GITHUB_TOKEN` / `GH_TOKEN` / `GITHUB_TOKEN` | — |
|
||||
| Groq | `groq` | `GROQ_API_KEY` | — |
|
||||
| Hugging Face Inference | `huggingface` | `HUGGINGFACE_HUB_TOKEN` or `HF_TOKEN` | `huggingface/deepseek-ai/DeepSeek-R1` |
|
||||
|
||||
@@ -130,9 +130,7 @@ Notes:
|
||||
|
||||
- `/model` (and `/model list`) is a compact, numbered picker (model family + available providers).
|
||||
- On Discord, `/model` and `/models` open an interactive picker with provider and model dropdowns plus a Submit step.
|
||||
- `/models add` is available by default and can be disabled with `commands.modelsWrite=false`.
|
||||
- When enabled, `/models add <provider> <modelId>` is the fastest path; bare `/models add` starts a provider-first guided flow where supported.
|
||||
- After `/models add`, the new model becomes available in `/models` and `/model` without restarting the gateway.
|
||||
- `/models add` is deprecated and now returns a deprecation message instead of registering models from chat.
|
||||
- `/model <#>` selects from that picker.
|
||||
- `/model` persists the new session selection immediately.
|
||||
- If the agent is idle, the next run uses the new model right away.
|
||||
@@ -151,14 +149,6 @@ Notes:
|
||||
|
||||
Full command behavior/config: [Slash commands](/tools/slash-commands).
|
||||
|
||||
Examples:
|
||||
|
||||
```text
|
||||
/models add
|
||||
/models add ollama glm-5.1:cloud
|
||||
/models add lmstudio qwen/qwen3.5-9b
|
||||
```
|
||||
|
||||
## CLI commands
|
||||
|
||||
```bash
|
||||
|
||||
@@ -5,8 +5,6 @@ read_when:
|
||||
title: "Command queue"
|
||||
---
|
||||
|
||||
# Command Queue (2026-01-16)
|
||||
|
||||
We serialize inbound auto-reply runs (all channels) through a tiny in-process queue to prevent multiple agent runs from colliding, while still allowing safe parallelism across sessions.
|
||||
|
||||
## Why
|
||||
|
||||
@@ -83,3 +83,8 @@ node --import tsx scripts/repro/tsx-name-repro.ts
|
||||
- Repro on Node 22/24 to confirm Node 25 regression.
|
||||
- Test `tsx` nightly or pin to earlier version if a known regression exists.
|
||||
- If reproduces on Node LTS, file a minimal repro upstream with the `__name` stack trace.
|
||||
|
||||
## Related
|
||||
|
||||
- [Node.js install](/install/node)
|
||||
- [Gateway troubleshooting](/gateway/troubleshooting)
|
||||
|
||||
@@ -87,3 +87,8 @@ For remote gateways, you can also use `openclaw logs --follow` (see [/cli/logs](
|
||||
- If `logging.level` is set higher than `warn`, these logs may be suppressed. Default `info` is fine.
|
||||
- Flags are safe to leave enabled; they only affect log volume for the specific subsystem.
|
||||
- Use [/logging](/logging) to change log destinations, levels, and redaction.
|
||||
|
||||
## Related
|
||||
|
||||
- [Gateway diagnostics](/gateway/diagnostics)
|
||||
- [Gateway troubleshooting](/gateway/troubleshooting)
|
||||
|
||||
187
docs/docs.json
187
docs/docs.json
@@ -60,6 +60,10 @@
|
||||
"source": "/providers/modelstudio",
|
||||
"destination": "/providers/qwen"
|
||||
},
|
||||
{
|
||||
"source": "/providers/qwen_modelstudio",
|
||||
"destination": "/providers/qwen"
|
||||
},
|
||||
{
|
||||
"source": "/platforms/oracle",
|
||||
"destination": "/install/oracle"
|
||||
@@ -1004,6 +1008,10 @@
|
||||
"install/uninstall",
|
||||
"install/development-channels"
|
||||
]
|
||||
},
|
||||
{
|
||||
"group": "Advanced setup",
|
||||
"pages": ["start/setup", "pi-dev"]
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -1015,30 +1023,40 @@
|
||||
"pages": ["channels/index"]
|
||||
},
|
||||
{
|
||||
"group": "Messaging platforms",
|
||||
"group": "Mainstream messaging",
|
||||
"pages": [
|
||||
"channels/bluebubbles",
|
||||
"channels/discord",
|
||||
"channels/feishu",
|
||||
"channels/slack",
|
||||
"channels/telegram",
|
||||
"channels/whatsapp",
|
||||
"channels/signal",
|
||||
"channels/msteams",
|
||||
"channels/googlechat",
|
||||
"channels/imessage",
|
||||
"channels/irc",
|
||||
"channels/line",
|
||||
"channels/bluebubbles",
|
||||
"channels/matrix",
|
||||
"channels/matrix-push-rules",
|
||||
"channels/matrix-push-rules"
|
||||
]
|
||||
},
|
||||
{
|
||||
"group": "Developer and self-hosted",
|
||||
"pages": [
|
||||
"channels/irc",
|
||||
"channels/mattermost",
|
||||
"channels/msteams",
|
||||
"channels/nextcloud-talk",
|
||||
"channels/nostr",
|
||||
"channels/qqbot",
|
||||
"channels/signal",
|
||||
"channels/slack",
|
||||
"channels/synology-chat",
|
||||
"channels/telegram",
|
||||
"channels/tlon",
|
||||
"channels/twitch",
|
||||
"channels/synology-chat",
|
||||
"channels/twitch"
|
||||
]
|
||||
},
|
||||
{
|
||||
"group": "Regional platforms",
|
||||
"pages": [
|
||||
"channels/line",
|
||||
"channels/wechat",
|
||||
"channels/whatsapp",
|
||||
"channels/qqbot",
|
||||
"channels/feishu",
|
||||
"channels/zalo",
|
||||
"channels/zalouser"
|
||||
]
|
||||
@@ -1052,7 +1070,8 @@
|
||||
"channels/broadcast-groups",
|
||||
"channels/channel-routing",
|
||||
"channels/location",
|
||||
"channels/troubleshooting"
|
||||
"channels/troubleshooting",
|
||||
"channels/qa-channel"
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -1073,7 +1092,8 @@
|
||||
"concepts/soul",
|
||||
"concepts/oauth",
|
||||
"start/bootstrapping",
|
||||
"concepts/experimental-features"
|
||||
"concepts/experimental-features",
|
||||
"concepts/qa-e2e-automation"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -1134,18 +1154,21 @@
|
||||
"plugins/webhooks",
|
||||
"plugins/voice-call",
|
||||
"plugins/memory-wiki",
|
||||
"plugins/message-presentation",
|
||||
"plugins/skill-workshop",
|
||||
"plugins/zalouser",
|
||||
{
|
||||
"group": "Building Plugins",
|
||||
"group": "Building plugins",
|
||||
"pages": [
|
||||
"plugins/building-plugins",
|
||||
"plugins/hooks",
|
||||
"plugins/sdk-channel-plugins",
|
||||
"plugins/sdk-provider-plugins",
|
||||
"plugins/sdk-migration"
|
||||
]
|
||||
},
|
||||
{
|
||||
"group": "SDK Reference",
|
||||
"group": "SDK reference",
|
||||
"pages": [
|
||||
"plugins/sdk-overview",
|
||||
"plugins/sdk-subpaths",
|
||||
@@ -1173,7 +1196,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"group": "Automation & Tasks",
|
||||
"group": "Automation and tasks",
|
||||
"pages": [
|
||||
"automation/index",
|
||||
"automation/cron-jobs",
|
||||
@@ -1207,7 +1230,7 @@
|
||||
"tools/trajectory",
|
||||
"tools/video-generation",
|
||||
{
|
||||
"group": "Web Browser",
|
||||
"group": "Web browser",
|
||||
"pages": [
|
||||
"tools/browser",
|
||||
"tools/browser-control",
|
||||
@@ -1217,7 +1240,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"group": "Web Tools",
|
||||
"group": "Web tools",
|
||||
"pages": [
|
||||
"tools/web-fetch",
|
||||
"tools/web",
|
||||
@@ -1280,6 +1303,7 @@
|
||||
"providers/github-copilot",
|
||||
"providers/glm",
|
||||
"providers/google",
|
||||
"providers/gradium",
|
||||
"providers/groq",
|
||||
"providers/huggingface",
|
||||
"providers/inferrs",
|
||||
@@ -1333,23 +1357,38 @@
|
||||
{
|
||||
"group": "macOS companion app",
|
||||
"pages": [
|
||||
"platforms/mac/dev-setup",
|
||||
"platforms/mac/menu-bar",
|
||||
"platforms/mac/voicewake",
|
||||
"platforms/mac/voice-overlay",
|
||||
"platforms/mac/webchat",
|
||||
"platforms/mac/canvas",
|
||||
"platforms/mac/child-process",
|
||||
"platforms/mac/health",
|
||||
"platforms/mac/icon",
|
||||
"platforms/mac/logging",
|
||||
"platforms/mac/permissions",
|
||||
"platforms/mac/remote",
|
||||
"platforms/mac/signing",
|
||||
"platforms/mac/bundled-gateway",
|
||||
"platforms/mac/xpc",
|
||||
"platforms/mac/skills",
|
||||
"platforms/mac/peekaboo"
|
||||
{
|
||||
"group": "Setup",
|
||||
"pages": [
|
||||
"platforms/mac/dev-setup",
|
||||
"platforms/mac/menu-bar",
|
||||
"platforms/mac/icon",
|
||||
"platforms/mac/permissions",
|
||||
"platforms/mac/signing"
|
||||
]
|
||||
},
|
||||
{
|
||||
"group": "Runtime",
|
||||
"pages": [
|
||||
"platforms/mac/bundled-gateway",
|
||||
"platforms/mac/child-process",
|
||||
"platforms/mac/health",
|
||||
"platforms/mac/logging",
|
||||
"platforms/mac/remote",
|
||||
"platforms/mac/xpc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"group": "Features",
|
||||
"pages": [
|
||||
"platforms/mac/voicewake",
|
||||
"platforms/mac/voice-overlay",
|
||||
"platforms/mac/webchat",
|
||||
"platforms/mac/canvas",
|
||||
"platforms/mac/skills",
|
||||
"platforms/mac/peekaboo"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -1362,28 +1401,44 @@
|
||||
"pages": [
|
||||
"gateway/index",
|
||||
{
|
||||
"group": "Configuration and operations",
|
||||
"group": "Configuration",
|
||||
"pages": [
|
||||
"gateway/configuration",
|
||||
"gateway/configuration-reference",
|
||||
"gateway/config-agents",
|
||||
"gateway/config-channels",
|
||||
"gateway/configuration-examples",
|
||||
"gateway/config-tools",
|
||||
"gateway/configuration-examples"
|
||||
]
|
||||
},
|
||||
{
|
||||
"group": "Authentication and secrets",
|
||||
"pages": [
|
||||
"gateway/authentication",
|
||||
"auth-credential-semantics",
|
||||
"gateway/secrets",
|
||||
"gateway/secrets-plan-contract",
|
||||
"gateway/trusted-proxy-auth",
|
||||
"gateway/trusted-proxy-auth"
|
||||
]
|
||||
},
|
||||
{
|
||||
"group": "Health and diagnostics",
|
||||
"pages": [
|
||||
"gateway/health",
|
||||
"gateway/diagnostics",
|
||||
"gateway/heartbeat",
|
||||
"gateway/doctor",
|
||||
"gateway/logging",
|
||||
"logging",
|
||||
"gateway/troubleshooting"
|
||||
]
|
||||
},
|
||||
{
|
||||
"group": "Scaling and operations",
|
||||
"pages": [
|
||||
"gateway/gateway-lock",
|
||||
"gateway/background-process",
|
||||
"gateway/multiple-gateways",
|
||||
"gateway/troubleshooting"
|
||||
"gateway/multiple-gateways"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -1544,6 +1599,7 @@
|
||||
"cli/dns",
|
||||
"cli/docs",
|
||||
"cli/mcp",
|
||||
"cli/proxy",
|
||||
"cli/wiki"
|
||||
]
|
||||
}
|
||||
@@ -1579,6 +1635,7 @@
|
||||
"reference/transcript-hygiene",
|
||||
"reference/memory-config",
|
||||
"reference/rich-output-protocol",
|
||||
"reference/session-management-compaction",
|
||||
"date-time"
|
||||
]
|
||||
},
|
||||
@@ -1589,7 +1646,9 @@
|
||||
"concepts/markdown-formatting",
|
||||
"concepts/typing-indicators",
|
||||
"concepts/usage-tracking",
|
||||
"concepts/timezone"
|
||||
"concepts/timezone",
|
||||
"help/gpt54-codex-agentic-parity",
|
||||
"help/gpt54-codex-agentic-parity-maintainers"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -1597,8 +1656,8 @@
|
||||
"pages": ["reference/credits"]
|
||||
},
|
||||
{
|
||||
"group": "Release policy",
|
||||
"pages": ["reference/RELEASING", "reference/test"]
|
||||
"group": "Release and CI",
|
||||
"pages": ["reference/RELEASING", "reference/test", "ci", "help/scripts"]
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -1606,40 +1665,24 @@
|
||||
"tab": "Help",
|
||||
"groups": [
|
||||
{
|
||||
"group": "Help",
|
||||
"pages": ["help/index", "help/troubleshooting", "help/faq"]
|
||||
"group": "Start here",
|
||||
"pages": ["help/index", "help/troubleshooting", "help/debugging"]
|
||||
},
|
||||
{
|
||||
"group": "Community",
|
||||
"pages": ["start/lore"]
|
||||
"group": "FAQ",
|
||||
"pages": ["help/faq", "help/faq-first-run", "help/faq-models"]
|
||||
},
|
||||
{
|
||||
"group": "Environment and debugging",
|
||||
"pages": [
|
||||
"help/environment",
|
||||
"help/debugging",
|
||||
"help/testing",
|
||||
"help/testing-live",
|
||||
"help/scripts",
|
||||
"debug/node-issue",
|
||||
"diagnostics/flags"
|
||||
]
|
||||
"group": "Testing",
|
||||
"pages": ["help/testing", "help/testing-live"]
|
||||
},
|
||||
{
|
||||
"group": "Compaction internals",
|
||||
"pages": ["reference/session-management-compaction"]
|
||||
"group": "Diagnostics",
|
||||
"pages": ["help/environment", "diagnostics/flags", "debug/node-issue"]
|
||||
},
|
||||
{
|
||||
"group": "Developer setup",
|
||||
"pages": ["start/setup", "pi-dev"]
|
||||
},
|
||||
{
|
||||
"group": "Contributing",
|
||||
"pages": ["ci"]
|
||||
},
|
||||
{
|
||||
"group": "Docs meta",
|
||||
"pages": ["start/hubs", "start/docs-directory"]
|
||||
"group": "Community and meta",
|
||||
"pages": ["start/lore", "start/hubs", "start/docs-directory"]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -6,8 +6,6 @@ read_when:
|
||||
title: "Authentication"
|
||||
---
|
||||
|
||||
# Authentication (Model Providers)
|
||||
|
||||
<Note>
|
||||
This page covers **model provider** authentication (API keys, OAuth, Claude CLI reuse, and Anthropic setup-token). For **gateway connection** authentication (token, password, trusted-proxy), see [Configuration](/gateway/configuration) and [Trusted Proxy Auth](/gateway/trusted-proxy-auth).
|
||||
</Note>
|
||||
|
||||
@@ -129,3 +129,8 @@ Paste literal text:
|
||||
```json
|
||||
{ "tool": "process", "action": "paste", "sessionId": "<id>", "text": "line1\nline2\n" }
|
||||
```
|
||||
|
||||
## Related
|
||||
|
||||
- [Exec tool](/tools/exec)
|
||||
- [Exec approvals](/tools/exec-approvals)
|
||||
|
||||
@@ -9,9 +9,10 @@ title: "Bonjour discovery"
|
||||
# Bonjour / mDNS discovery
|
||||
|
||||
OpenClaw uses Bonjour (mDNS / DNS‑SD) to discover an active Gateway (WebSocket endpoint).
|
||||
Multicast `local.` browsing is a **LAN-only convenience**. For cross-network discovery, the
|
||||
same beacon can also be published through a configured wide-area DNS-SD domain. Discovery is
|
||||
still best-effort and does **not** replace SSH or Tailnet-based connectivity.
|
||||
Multicast `local.` browsing is a **LAN-only convenience**. The bundled `bonjour`
|
||||
plugin owns LAN advertising and is enabled by default. For cross-network discovery,
|
||||
the same beacon can also be published through a configured wide-area DNS-SD domain.
|
||||
Discovery is still best-effort and does **not** replace SSH or Tailnet-based connectivity.
|
||||
|
||||
## Wide-area Bonjour (Unicast DNS-SD) over Tailscale
|
||||
|
||||
@@ -79,7 +80,9 @@ For tailnet‑only setups:
|
||||
|
||||
## What advertises
|
||||
|
||||
Only the Gateway advertises `_openclaw-gw._tcp`.
|
||||
Only the Gateway advertises `_openclaw-gw._tcp`. LAN multicast advertising is
|
||||
provided by the bundled `bonjour` plugin; wide-area DNS-SD publishing remains
|
||||
Gateway-owned.
|
||||
|
||||
## Service types
|
||||
|
||||
@@ -97,7 +100,7 @@ The Gateway advertises small non‑secret hints to make UI flows convenient:
|
||||
- `gatewayTlsSha256=<sha256>` (only when TLS is enabled and fingerprint is available)
|
||||
- `canvasPort=<port>` (only when the canvas host is enabled; currently the same as `gatewayPort`)
|
||||
- `transport=gateway`
|
||||
- `tailnetDns=<magicdns>` (optional hint when Tailnet is available)
|
||||
- `tailnetDns=<magicdns>` (mDNS full mode only, optional hint when Tailnet is available)
|
||||
- `sshPort=<port>` (mDNS full mode only; wide-area DNS-SD may omit it)
|
||||
- `cliPath=<path>` (mDNS full mode only; wide-area DNS-SD still writes it as a remote-install hint)
|
||||
|
||||
@@ -167,10 +170,12 @@ sequences (e.g. spaces become `\032`).
|
||||
|
||||
## Disabling / configuration
|
||||
|
||||
- `OPENCLAW_DISABLE_BONJOUR=1` disables advertising (legacy: `OPENCLAW_DISABLE_BONJOUR`).
|
||||
- `openclaw plugins disable bonjour` disables LAN multicast advertising by disabling the bundled plugin.
|
||||
- `openclaw plugins enable bonjour` restores the default LAN discovery plugin.
|
||||
- `OPENCLAW_DISABLE_BONJOUR=1` disables LAN multicast advertising without changing plugin config; accepted truthy values are `1`, `true`, `yes`, and `on` (legacy: `OPENCLAW_DISABLE_BONJOUR`).
|
||||
- `gateway.bind` in `~/.openclaw/openclaw.json` controls the Gateway bind mode.
|
||||
- `OPENCLAW_SSH_PORT` overrides the SSH port when `sshPort` is advertised (legacy: `OPENCLAW_SSH_PORT`).
|
||||
- `OPENCLAW_TAILNET_DNS` publishes a MagicDNS hint in TXT (legacy: `OPENCLAW_TAILNET_DNS`).
|
||||
- `OPENCLAW_TAILNET_DNS` publishes a MagicDNS hint in TXT when mDNS full mode is enabled (legacy: `OPENCLAW_TAILNET_DNS`).
|
||||
- `OPENCLAW_CLI_PATH` overrides the advertised CLI path (legacy: `OPENCLAW_CLI_PATH`).
|
||||
|
||||
## Related docs
|
||||
|
||||
@@ -7,8 +7,6 @@ read_when:
|
||||
title: "Bridge protocol"
|
||||
---
|
||||
|
||||
# Bridge protocol (legacy node transport)
|
||||
|
||||
<Warning>
|
||||
The TCP bridge has been **removed**. Current OpenClaw builds do not ship the bridge listener and `bridge.*` config keys are no longer in the schema. This page is kept for historical reference only. Use the [Gateway Protocol](/gateway/protocol) for all node/operator clients.
|
||||
</Warning>
|
||||
@@ -87,3 +85,8 @@ Payload fields (all optional unless noted):
|
||||
The bridge was **implicit v1** (no min/max negotiation). This section is
|
||||
historical reference only; current node/operator clients use the WebSocket
|
||||
[Gateway Protocol](/gateway/protocol).
|
||||
|
||||
## Related
|
||||
|
||||
- [Gateway protocol](/gateway/protocol)
|
||||
- [Nodes](/nodes)
|
||||
|
||||
@@ -7,8 +7,6 @@ read_when:
|
||||
title: "CLI backends"
|
||||
---
|
||||
|
||||
# CLI backends (fallback runtime)
|
||||
|
||||
OpenClaw can run **local AI CLIs** as a **text-only fallback** when API providers are down,
|
||||
rate-limited, or temporarily misbehaving. This is intentionally conservative:
|
||||
|
||||
@@ -370,3 +368,8 @@ backend opts into bundle MCP so background runs stay isolated.
|
||||
- **No session continuity**: ensure `sessionArg` is set and `sessionMode` is not
|
||||
`none` (Codex CLI currently cannot resume with JSON output).
|
||||
- **Images ignored**: set `imageArg` (and verify CLI supports file paths).
|
||||
|
||||
## Related
|
||||
|
||||
- [Gateway runbook](/gateway)
|
||||
- [Local models](/gateway/local-models)
|
||||
|
||||
@@ -315,10 +315,6 @@ Time format in system prompt. Default: `auto` (OS preference).
|
||||
fallbacks: ["openai/gpt-5.4-mini"],
|
||||
},
|
||||
params: { cacheRetention: "long" }, // global default provider params
|
||||
embeddedHarness: {
|
||||
runtime: "auto", // auto | pi | registered harness id, e.g. codex
|
||||
fallback: "pi", // pi | none
|
||||
},
|
||||
pdfMaxBytesMb: 10,
|
||||
pdfMaxPages: 20,
|
||||
thinkingDefault: "low",
|
||||
@@ -369,16 +365,16 @@ Time format in system prompt. Default: `auto` (OS preference).
|
||||
- For direct OpenAI Responses models, server-side compaction is enabled automatically. Use `params.responsesServerCompaction: false` to stop injecting `context_management`, or `params.responsesCompactThreshold` to override the threshold. See [OpenAI server-side compaction](/providers/openai#server-side-compaction-responses-api).
|
||||
- `params`: global default provider parameters applied to all models. Set at `agents.defaults.params` (e.g. `{ cacheRetention: "long" }`).
|
||||
- `params` merge precedence (config): `agents.defaults.params` (global base) is overridden by `agents.defaults.models["provider/model"].params` (per-model), then `agents.list[].params` (matching agent id) overrides by key. See [Prompt Caching](/reference/prompt-caching) for details.
|
||||
- `embeddedHarness`: default low-level embedded agent runtime policy. Use `runtime: "auto"` to let registered plugin harnesses claim supported models, `runtime: "pi"` to force the built-in PI harness, or a registered harness id such as `runtime: "codex"`. Set `fallback: "none"` to disable automatic PI fallback.
|
||||
- `embeddedHarness`: optional low-level embedded agent runtime policy. Omit it for the default auto-with-PI-fallback behavior. Set `runtime: "pi"` to force the built-in PI harness, or a registered harness id such as `runtime: "codex"` to force that harness. Set `fallback: "none"` to disable automatic PI fallback.
|
||||
- Config writers that mutate these fields (for example `/models set`, `/models set-image`, and fallback add/remove commands) save canonical object form and preserve existing fallback lists when possible.
|
||||
- `maxConcurrent`: max parallel agent runs across sessions (each session still serialized). Default: 4.
|
||||
|
||||
### `agents.defaults.embeddedHarness`
|
||||
|
||||
`embeddedHarness` controls which low-level executor runs embedded agent turns.
|
||||
Most deployments should keep the default `{ runtime: "auto", fallback: "pi" }`.
|
||||
Use it when a trusted plugin provides a native harness, such as the bundled
|
||||
Codex app-server harness.
|
||||
Most deployments should omit it; the implicit default is auto selection with PI
|
||||
fallback. Add it only when a trusted plugin provides a native harness you want
|
||||
to force, such as the bundled Codex app-server harness.
|
||||
|
||||
```json5
|
||||
{
|
||||
@@ -905,7 +901,6 @@ scripts/sandbox-browser-setup.sh # optional browser image
|
||||
thinkingDefault: "high", // per-agent thinking level override
|
||||
reasoningDefault: "on", // per-agent reasoning visibility override
|
||||
fastModeDefault: false, // per-agent fast mode override
|
||||
embeddedHarness: { runtime: "auto", fallback: "pi" },
|
||||
params: { cacheRetention: "none" }, // overrides matching defaults.models params by key
|
||||
skills: ["docs-search"], // replaces agents.defaults.skills when set
|
||||
identity: {
|
||||
|
||||
667
docs/gateway/config-tools.md
Normal file
667
docs/gateway/config-tools.md
Normal file
@@ -0,0 +1,667 @@
|
||||
---
|
||||
summary: "Tools config (policy, experimental toggles, provider-backed tools) and custom provider/base-URL setup"
|
||||
read_when:
|
||||
- Configuring `tools.*` policy, allowlists, or experimental features
|
||||
- Registering custom providers or overriding base URLs
|
||||
- Setting up OpenAI-compatible self-hosted endpoints
|
||||
title: "Configuration — tools and custom providers"
|
||||
---
|
||||
|
||||
`tools.*` config keys and custom provider / base-URL setup. For agents,
|
||||
channels, and other top-level config keys, see
|
||||
[Configuration reference](/gateway/configuration-reference).
|
||||
|
||||
## Tools
|
||||
|
||||
### Tool profiles
|
||||
|
||||
`tools.profile` sets a base allowlist before `tools.allow`/`tools.deny`:
|
||||
|
||||
Local onboarding defaults new local configs to `tools.profile: "coding"` when unset (existing explicit profiles are preserved).
|
||||
|
||||
| Profile | Includes |
|
||||
| ----------- | ------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `minimal` | `session_status` only |
|
||||
| `coding` | `group:fs`, `group:runtime`, `group:web`, `group:sessions`, `group:memory`, `cron`, `image`, `image_generate`, `video_generate` |
|
||||
| `messaging` | `group:messaging`, `sessions_list`, `sessions_history`, `sessions_send`, `session_status` |
|
||||
| `full` | No restriction (same as unset) |
|
||||
|
||||
### Tool groups
|
||||
|
||||
| Group | Tools |
|
||||
| ------------------ | ----------------------------------------------------------------------------------------------------------------------- |
|
||||
| `group:runtime` | `exec`, `process`, `code_execution` (`bash` is accepted as an alias for `exec`) |
|
||||
| `group:fs` | `read`, `write`, `edit`, `apply_patch` |
|
||||
| `group:sessions` | `sessions_list`, `sessions_history`, `sessions_send`, `sessions_spawn`, `sessions_yield`, `subagents`, `session_status` |
|
||||
| `group:memory` | `memory_search`, `memory_get` |
|
||||
| `group:web` | `web_search`, `x_search`, `web_fetch` |
|
||||
| `group:ui` | `browser`, `canvas` |
|
||||
| `group:automation` | `cron`, `gateway` |
|
||||
| `group:messaging` | `message` |
|
||||
| `group:nodes` | `nodes` |
|
||||
| `group:agents` | `agents_list` |
|
||||
| `group:media` | `image`, `image_generate`, `video_generate`, `tts` |
|
||||
| `group:openclaw` | All built-in tools (excludes provider plugins) |
|
||||
|
||||
### `tools.allow` / `tools.deny`
|
||||
|
||||
Global tool allow/deny policy (deny wins). Case-insensitive, supports `*` wildcards. Applied even when Docker sandbox is off.
|
||||
|
||||
```json5
|
||||
{
|
||||
tools: { deny: ["browser", "canvas"] },
|
||||
}
|
||||
```
|
||||
|
||||
### `tools.byProvider`
|
||||
|
||||
Further restrict tools for specific providers or models. Order: base profile → provider profile → allow/deny.
|
||||
|
||||
```json5
|
||||
{
|
||||
tools: {
|
||||
profile: "coding",
|
||||
byProvider: {
|
||||
"google-antigravity": { profile: "minimal" },
|
||||
"openai/gpt-5.4": { allow: ["group:fs", "sessions_list"] },
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
### `tools.elevated`
|
||||
|
||||
Controls elevated exec access outside the sandbox:
|
||||
|
||||
```json5
|
||||
{
|
||||
tools: {
|
||||
elevated: {
|
||||
enabled: true,
|
||||
allowFrom: {
|
||||
whatsapp: ["+15555550123"],
|
||||
discord: ["1234567890123", "987654321098765432"],
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
- Per-agent override (`agents.list[].tools.elevated`) can only further restrict.
|
||||
- `/elevated on|off|ask|full` stores state per session; inline directives apply to single message.
|
||||
- Elevated `exec` bypasses sandboxing and uses the configured escape path (`gateway` by default, or `node` when the exec target is `node`).
|
||||
|
||||
### `tools.exec`
|
||||
|
||||
```json5
|
||||
{
|
||||
tools: {
|
||||
exec: {
|
||||
backgroundMs: 10000,
|
||||
timeoutSec: 1800,
|
||||
cleanupMs: 1800000,
|
||||
notifyOnExit: true,
|
||||
notifyOnExitEmptySuccess: false,
|
||||
applyPatch: {
|
||||
enabled: false,
|
||||
allowModels: ["gpt-5.5"],
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
### `tools.loopDetection`
|
||||
|
||||
Tool-loop safety checks are **disabled by default**. Set `enabled: true` to activate detection.
|
||||
Settings can be defined globally in `tools.loopDetection` and overridden per-agent at `agents.list[].tools.loopDetection`.
|
||||
|
||||
```json5
|
||||
{
|
||||
tools: {
|
||||
loopDetection: {
|
||||
enabled: true,
|
||||
historySize: 30,
|
||||
warningThreshold: 10,
|
||||
criticalThreshold: 20,
|
||||
globalCircuitBreakerThreshold: 30,
|
||||
detectors: {
|
||||
genericRepeat: true,
|
||||
knownPollNoProgress: true,
|
||||
pingPong: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
- `historySize`: max tool-call history retained for loop analysis.
|
||||
- `warningThreshold`: repeating no-progress pattern threshold for warnings.
|
||||
- `criticalThreshold`: higher repeating threshold for blocking critical loops.
|
||||
- `globalCircuitBreakerThreshold`: hard stop threshold for any no-progress run.
|
||||
- `detectors.genericRepeat`: warn on repeated same-tool/same-args calls.
|
||||
- `detectors.knownPollNoProgress`: warn/block on known poll tools (`process.poll`, `command_status`, etc.).
|
||||
- `detectors.pingPong`: warn/block on alternating no-progress pair patterns.
|
||||
- If `warningThreshold >= criticalThreshold` or `criticalThreshold >= globalCircuitBreakerThreshold`, validation fails.
|
||||
|
||||
### `tools.web`
|
||||
|
||||
```json5
|
||||
{
|
||||
tools: {
|
||||
web: {
|
||||
search: {
|
||||
enabled: true,
|
||||
apiKey: "brave_api_key", // or BRAVE_API_KEY env
|
||||
maxResults: 5,
|
||||
timeoutSeconds: 30,
|
||||
cacheTtlMinutes: 15,
|
||||
},
|
||||
fetch: {
|
||||
enabled: true,
|
||||
provider: "firecrawl", // optional; omit for auto-detect
|
||||
maxChars: 50000,
|
||||
maxCharsCap: 50000,
|
||||
maxResponseBytes: 2000000,
|
||||
timeoutSeconds: 30,
|
||||
cacheTtlMinutes: 15,
|
||||
maxRedirects: 3,
|
||||
readability: true,
|
||||
userAgent: "custom-ua",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
### `tools.media`
|
||||
|
||||
Configures inbound media understanding (image/audio/video):
|
||||
|
||||
```json5
|
||||
{
|
||||
tools: {
|
||||
media: {
|
||||
concurrency: 2,
|
||||
asyncCompletion: {
|
||||
directSend: false, // opt-in: send finished async music/video directly to the channel
|
||||
},
|
||||
audio: {
|
||||
enabled: true,
|
||||
maxBytes: 20971520,
|
||||
scope: {
|
||||
default: "deny",
|
||||
rules: [{ action: "allow", match: { chatType: "direct" } }],
|
||||
},
|
||||
models: [
|
||||
{ provider: "openai", model: "gpt-4o-mini-transcribe" },
|
||||
{ type: "cli", command: "whisper", args: ["--model", "base", "{{MediaPath}}"] },
|
||||
],
|
||||
},
|
||||
video: {
|
||||
enabled: true,
|
||||
maxBytes: 52428800,
|
||||
models: [{ provider: "google", model: "gemini-3-flash-preview" }],
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
<Accordion title="Media model entry fields">
|
||||
|
||||
**Provider entry** (`type: "provider"` or omitted):
|
||||
|
||||
- `provider`: API provider id (`openai`, `anthropic`, `google`/`gemini`, `groq`, etc.)
|
||||
- `model`: model id override
|
||||
- `profile` / `preferredProfile`: `auth-profiles.json` profile selection
|
||||
|
||||
**CLI entry** (`type: "cli"`):
|
||||
|
||||
- `command`: executable to run
|
||||
- `args`: templated args (supports `{{MediaPath}}`, `{{Prompt}}`, `{{MaxChars}}`, etc.)
|
||||
|
||||
**Common fields:**
|
||||
|
||||
- `capabilities`: optional list (`image`, `audio`, `video`). Defaults: `openai`/`anthropic`/`minimax` → image, `google` → image+audio+video, `groq` → audio.
|
||||
- `prompt`, `maxChars`, `maxBytes`, `timeoutSeconds`, `language`: per-entry overrides.
|
||||
- Failures fall back to the next entry.
|
||||
|
||||
Provider auth follows standard order: `auth-profiles.json` → env vars → `models.providers.*.apiKey`.
|
||||
|
||||
**Async completion fields:**
|
||||
|
||||
- `asyncCompletion.directSend`: when `true`, completed async `music_generate`
|
||||
and `video_generate` tasks try direct channel delivery first. Default: `false`
|
||||
(legacy requester-session wake/model-delivery path).
|
||||
|
||||
</Accordion>
|
||||
|
||||
### `tools.agentToAgent`
|
||||
|
||||
```json5
|
||||
{
|
||||
tools: {
|
||||
agentToAgent: {
|
||||
enabled: false,
|
||||
allow: ["home", "work"],
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
### `tools.sessions`
|
||||
|
||||
Controls which sessions can be targeted by the session tools (`sessions_list`, `sessions_history`, `sessions_send`).
|
||||
|
||||
Default: `tree` (current session + sessions spawned by it, such as subagents).
|
||||
|
||||
```json5
|
||||
{
|
||||
tools: {
|
||||
sessions: {
|
||||
// "self" | "tree" | "agent" | "all"
|
||||
visibility: "tree",
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
Notes:
|
||||
|
||||
- `self`: only the current session key.
|
||||
- `tree`: current session + sessions spawned by the current session (subagents).
|
||||
- `agent`: any session belonging to the current agent id (can include other users if you run per-sender sessions under the same agent id).
|
||||
- `all`: any session. Cross-agent targeting still requires `tools.agentToAgent`.
|
||||
- Sandbox clamp: when the current session is sandboxed and `agents.defaults.sandbox.sessionToolsVisibility="spawned"`, visibility is forced to `tree` even if `tools.sessions.visibility="all"`.
|
||||
|
||||
### `tools.sessions_spawn`
|
||||
|
||||
Controls inline attachment support for `sessions_spawn`.
|
||||
|
||||
```json5
|
||||
{
|
||||
tools: {
|
||||
sessions_spawn: {
|
||||
attachments: {
|
||||
enabled: false, // opt-in: set true to allow inline file attachments
|
||||
maxTotalBytes: 5242880, // 5 MB total across all files
|
||||
maxFiles: 50,
|
||||
maxFileBytes: 1048576, // 1 MB per file
|
||||
retainOnSessionKeep: false, // keep attachments when cleanup="keep"
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
Notes:
|
||||
|
||||
- Attachments are only supported for `runtime: "subagent"`. ACP runtime rejects them.
|
||||
- Files are materialized into the child workspace at `.openclaw/attachments/<uuid>/` with a `.manifest.json`.
|
||||
- Attachment content is automatically redacted from transcript persistence.
|
||||
- Base64 inputs are validated with strict alphabet/padding checks and a pre-decode size guard.
|
||||
- File permissions are `0700` for directories and `0600` for files.
|
||||
- Cleanup follows the `cleanup` policy: `delete` always removes attachments; `keep` retains them only when `retainOnSessionKeep: true`.
|
||||
|
||||
<a id="toolsexperimental"></a>
|
||||
|
||||
### `tools.experimental`
|
||||
|
||||
Experimental built-in tool flags. Default off unless a strict-agentic GPT-5 auto-enable rule applies.
|
||||
|
||||
```json5
|
||||
{
|
||||
tools: {
|
||||
experimental: {
|
||||
planTool: true, // enable experimental update_plan
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
Notes:
|
||||
|
||||
- `planTool`: enables the structured `update_plan` tool for non-trivial multi-step work tracking.
|
||||
- Default: `false` unless `agents.defaults.embeddedPi.executionContract` (or a per-agent override) is set to `"strict-agentic"` for an OpenAI or OpenAI Codex GPT-5-family run. Set `true` to force the tool on outside that scope, or `false` to keep it off even for strict-agentic GPT-5 runs.
|
||||
- When enabled, the system prompt also adds usage guidance so the model only uses it for substantial work and keeps at most one step `in_progress`.
|
||||
|
||||
### `agents.defaults.subagents`
|
||||
|
||||
```json5
|
||||
{
|
||||
agents: {
|
||||
defaults: {
|
||||
subagents: {
|
||||
allowAgents: ["research"],
|
||||
model: "minimax/MiniMax-M2.7",
|
||||
maxConcurrent: 8,
|
||||
runTimeoutSeconds: 900,
|
||||
archiveAfterMinutes: 60,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
- `model`: default model for spawned sub-agents. If omitted, sub-agents inherit the caller's model.
|
||||
- `allowAgents`: default allowlist of target agent ids for `sessions_spawn` when the requester agent does not set its own `subagents.allowAgents` (`["*"]` = any; default: same agent only).
|
||||
- `runTimeoutSeconds`: default timeout (seconds) for `sessions_spawn` when the tool call omits `runTimeoutSeconds`. `0` means no timeout.
|
||||
- Per-subagent tool policy: `tools.subagents.tools.allow` / `tools.subagents.tools.deny`.
|
||||
|
||||
---
|
||||
|
||||
## Custom providers and base URLs
|
||||
|
||||
OpenClaw uses the built-in model catalog. Add custom providers via `models.providers` in config or `~/.openclaw/agents/<agentId>/agent/models.json`.
|
||||
|
||||
```json5
|
||||
{
|
||||
models: {
|
||||
mode: "merge", // merge (default) | replace
|
||||
providers: {
|
||||
"custom-proxy": {
|
||||
baseUrl: "http://localhost:4000/v1",
|
||||
apiKey: "LITELLM_KEY",
|
||||
api: "openai-completions", // openai-completions | openai-responses | anthropic-messages | google-generative-ai
|
||||
models: [
|
||||
{
|
||||
id: "llama-3.1-8b",
|
||||
name: "Llama 3.1 8B",
|
||||
reasoning: false,
|
||||
input: ["text"],
|
||||
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
|
||||
contextWindow: 128000,
|
||||
contextTokens: 96000,
|
||||
maxTokens: 32000,
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
- Use `authHeader: true` + `headers` for custom auth needs.
|
||||
- Override agent config root with `OPENCLAW_AGENT_DIR` (or `PI_CODING_AGENT_DIR`, a legacy environment variable alias).
|
||||
- Merge precedence for matching provider IDs:
|
||||
- Non-empty agent `models.json` `baseUrl` values win.
|
||||
- Non-empty agent `apiKey` values win only when that provider is not SecretRef-managed in current config/auth-profile context.
|
||||
- SecretRef-managed provider `apiKey` values are refreshed from source markers (`ENV_VAR_NAME` for env refs, `secretref-managed` for file/exec refs) instead of persisting resolved secrets.
|
||||
- SecretRef-managed provider header values are refreshed from source markers (`secretref-env:ENV_VAR_NAME` for env refs, `secretref-managed` for file/exec refs).
|
||||
- Empty or missing agent `apiKey`/`baseUrl` fall back to `models.providers` in config.
|
||||
- Matching model `contextWindow`/`maxTokens` use the higher value between explicit config and implicit catalog values.
|
||||
- Matching model `contextTokens` preserves an explicit runtime cap when present; use it to limit effective context without changing native model metadata.
|
||||
- Use `models.mode: "replace"` when you want config to fully rewrite `models.json`.
|
||||
- Marker persistence is source-authoritative: markers are written from the active source config snapshot (pre-resolution), not from resolved runtime secret values.
|
||||
|
||||
### Provider field details
|
||||
|
||||
- `models.mode`: provider catalog behavior (`merge` or `replace`).
|
||||
- `models.providers`: custom provider map keyed by provider id.
|
||||
- Safe edits: use `openclaw config set models.providers.<id> '<json>' --strict-json --merge` or `openclaw config set models.providers.<id>.models '<json-array>' --strict-json --merge` for additive updates. `config set` refuses destructive replacements unless you pass `--replace`.
|
||||
- `models.providers.*.api`: request adapter (`openai-completions`, `openai-responses`, `anthropic-messages`, `google-generative-ai`, etc).
|
||||
- `models.providers.*.apiKey`: provider credential (prefer SecretRef/env substitution).
|
||||
- `models.providers.*.auth`: auth strategy (`api-key`, `token`, `oauth`, `aws-sdk`).
|
||||
- `models.providers.*.injectNumCtxForOpenAICompat`: for Ollama + `openai-completions`, inject `options.num_ctx` into requests (default: `true`).
|
||||
- `models.providers.*.authHeader`: force credential transport in the `Authorization` header when required.
|
||||
- `models.providers.*.baseUrl`: upstream API base URL.
|
||||
- `models.providers.*.headers`: extra static headers for proxy/tenant routing.
|
||||
- `models.providers.*.request`: transport overrides for model-provider HTTP requests.
|
||||
- `request.headers`: extra headers (merged with provider defaults). Values accept SecretRef.
|
||||
- `request.auth`: auth strategy override. Modes: `"provider-default"` (use provider's built-in auth), `"authorization-bearer"` (with `token`), `"header"` (with `headerName`, `value`, optional `prefix`).
|
||||
- `request.proxy`: HTTP proxy override. Modes: `"env-proxy"` (use `HTTP_PROXY`/`HTTPS_PROXY` env vars), `"explicit-proxy"` (with `url`). Both modes accept an optional `tls` sub-object.
|
||||
- `request.tls`: TLS override for direct connections. Fields: `ca`, `cert`, `key`, `passphrase` (all accept SecretRef), `serverName`, `insecureSkipVerify`.
|
||||
- `request.allowPrivateNetwork`: when `true`, allow HTTPS to `baseUrl` when DNS resolves to private, CGNAT, or similar ranges, via the provider HTTP fetch guard (operator opt-in for trusted self-hosted OpenAI-compatible endpoints). WebSocket uses the same `request` for headers/TLS but not that fetch SSRF gate. Default `false`.
|
||||
- `models.providers.*.models`: explicit provider model catalog entries.
|
||||
- `models.providers.*.models.*.contextWindow`: native model context window metadata.
|
||||
- `models.providers.*.models.*.contextTokens`: optional runtime context cap. Use this when you want a smaller effective context budget than the model's native `contextWindow`.
|
||||
- `models.providers.*.models.*.compat.supportsDeveloperRole`: optional compatibility hint. For `api: "openai-completions"` with a non-empty non-native `baseUrl` (host not `api.openai.com`), OpenClaw forces this to `false` at runtime. Empty/omitted `baseUrl` keeps default OpenAI behavior.
|
||||
- `models.providers.*.models.*.compat.requiresStringContent`: optional compatibility hint for string-only OpenAI-compatible chat endpoints. When `true`, OpenClaw flattens pure text `messages[].content` arrays into plain strings before sending the request.
|
||||
- `plugins.entries.amazon-bedrock.config.discovery`: Bedrock auto-discovery settings root.
|
||||
- `plugins.entries.amazon-bedrock.config.discovery.enabled`: turn implicit discovery on/off.
|
||||
- `plugins.entries.amazon-bedrock.config.discovery.region`: AWS region for discovery.
|
||||
- `plugins.entries.amazon-bedrock.config.discovery.providerFilter`: optional provider-id filter for targeted discovery.
|
||||
- `plugins.entries.amazon-bedrock.config.discovery.refreshInterval`: polling interval for discovery refresh.
|
||||
- `plugins.entries.amazon-bedrock.config.discovery.defaultContextWindow`: fallback context window for discovered models.
|
||||
- `plugins.entries.amazon-bedrock.config.discovery.defaultMaxTokens`: fallback max output tokens for discovered models.
|
||||
|
||||
### Provider examples
|
||||
|
||||
<Accordion title="Cerebras (GLM 4.6 / 4.7)">
|
||||
|
||||
```json5
|
||||
{
|
||||
env: { CEREBRAS_API_KEY: "sk-..." },
|
||||
agents: {
|
||||
defaults: {
|
||||
model: {
|
||||
primary: "cerebras/zai-glm-4.7",
|
||||
fallbacks: ["cerebras/zai-glm-4.6"],
|
||||
},
|
||||
models: {
|
||||
"cerebras/zai-glm-4.7": { alias: "GLM 4.7 (Cerebras)" },
|
||||
"cerebras/zai-glm-4.6": { alias: "GLM 4.6 (Cerebras)" },
|
||||
},
|
||||
},
|
||||
},
|
||||
models: {
|
||||
mode: "merge",
|
||||
providers: {
|
||||
cerebras: {
|
||||
baseUrl: "https://api.cerebras.ai/v1",
|
||||
apiKey: "${CEREBRAS_API_KEY}",
|
||||
api: "openai-completions",
|
||||
models: [
|
||||
{ id: "zai-glm-4.7", name: "GLM 4.7 (Cerebras)" },
|
||||
{ id: "zai-glm-4.6", name: "GLM 4.6 (Cerebras)" },
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
Use `cerebras/zai-glm-4.7` for Cerebras; `zai/glm-4.7` for Z.AI direct.
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="OpenCode">
|
||||
|
||||
```json5
|
||||
{
|
||||
agents: {
|
||||
defaults: {
|
||||
model: { primary: "opencode/claude-opus-4-6" },
|
||||
models: { "opencode/claude-opus-4-6": { alias: "Opus" } },
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
Set `OPENCODE_API_KEY` (or `OPENCODE_ZEN_API_KEY`). Use `opencode/...` refs for the Zen catalog or `opencode-go/...` refs for the Go catalog. Shortcut: `openclaw onboard --auth-choice opencode-zen` or `openclaw onboard --auth-choice opencode-go`.
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Z.AI (GLM-4.7)">
|
||||
|
||||
```json5
|
||||
{
|
||||
agents: {
|
||||
defaults: {
|
||||
model: { primary: "zai/glm-4.7" },
|
||||
models: { "zai/glm-4.7": {} },
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
Set `ZAI_API_KEY`. `z.ai/*` and `z-ai/*` are accepted aliases. Shortcut: `openclaw onboard --auth-choice zai-api-key`.
|
||||
|
||||
- General endpoint: `https://api.z.ai/api/paas/v4`
|
||||
- Coding endpoint (default): `https://api.z.ai/api/coding/paas/v4`
|
||||
- For the general endpoint, define a custom provider with the base URL override.
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Moonshot AI (Kimi)">
|
||||
|
||||
```json5
|
||||
{
|
||||
env: { MOONSHOT_API_KEY: "sk-..." },
|
||||
agents: {
|
||||
defaults: {
|
||||
model: { primary: "moonshot/kimi-k2.6" },
|
||||
models: { "moonshot/kimi-k2.6": { alias: "Kimi K2.6" } },
|
||||
},
|
||||
},
|
||||
models: {
|
||||
mode: "merge",
|
||||
providers: {
|
||||
moonshot: {
|
||||
baseUrl: "https://api.moonshot.ai/v1",
|
||||
apiKey: "${MOONSHOT_API_KEY}",
|
||||
api: "openai-completions",
|
||||
models: [
|
||||
{
|
||||
id: "kimi-k2.6",
|
||||
name: "Kimi K2.6",
|
||||
reasoning: false,
|
||||
input: ["text", "image"],
|
||||
cost: { input: 0.95, output: 4, cacheRead: 0.16, cacheWrite: 0 },
|
||||
contextWindow: 262144,
|
||||
maxTokens: 262144,
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
For the China endpoint: `baseUrl: "https://api.moonshot.cn/v1"` or `openclaw onboard --auth-choice moonshot-api-key-cn`.
|
||||
|
||||
Native Moonshot endpoints advertise streaming usage compatibility on the shared
|
||||
`openai-completions` transport, and OpenClaw keys that off endpoint capabilities
|
||||
rather than the built-in provider id alone.
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Kimi Coding">
|
||||
|
||||
```json5
|
||||
{
|
||||
env: { KIMI_API_KEY: "sk-..." },
|
||||
agents: {
|
||||
defaults: {
|
||||
model: { primary: "kimi/kimi-code" },
|
||||
models: { "kimi/kimi-code": { alias: "Kimi Code" } },
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
Anthropic-compatible, built-in provider. Shortcut: `openclaw onboard --auth-choice kimi-code-api-key`.
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Synthetic (Anthropic-compatible)">
|
||||
|
||||
```json5
|
||||
{
|
||||
env: { SYNTHETIC_API_KEY: "sk-..." },
|
||||
agents: {
|
||||
defaults: {
|
||||
model: { primary: "synthetic/hf:MiniMaxAI/MiniMax-M2.5" },
|
||||
models: { "synthetic/hf:MiniMaxAI/MiniMax-M2.5": { alias: "MiniMax M2.5" } },
|
||||
},
|
||||
},
|
||||
models: {
|
||||
mode: "merge",
|
||||
providers: {
|
||||
synthetic: {
|
||||
baseUrl: "https://api.synthetic.new/anthropic",
|
||||
apiKey: "${SYNTHETIC_API_KEY}",
|
||||
api: "anthropic-messages",
|
||||
models: [
|
||||
{
|
||||
id: "hf:MiniMaxAI/MiniMax-M2.5",
|
||||
name: "MiniMax M2.5",
|
||||
reasoning: true,
|
||||
input: ["text"],
|
||||
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
|
||||
contextWindow: 192000,
|
||||
maxTokens: 65536,
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
Base URL should omit `/v1` (Anthropic client appends it). Shortcut: `openclaw onboard --auth-choice synthetic-api-key`.
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="MiniMax M2.7 (direct)">
|
||||
|
||||
```json5
|
||||
{
|
||||
agents: {
|
||||
defaults: {
|
||||
model: { primary: "minimax/MiniMax-M2.7" },
|
||||
models: {
|
||||
"minimax/MiniMax-M2.7": { alias: "Minimax" },
|
||||
},
|
||||
},
|
||||
},
|
||||
models: {
|
||||
mode: "merge",
|
||||
providers: {
|
||||
minimax: {
|
||||
baseUrl: "https://api.minimax.io/anthropic",
|
||||
apiKey: "${MINIMAX_API_KEY}",
|
||||
api: "anthropic-messages",
|
||||
models: [
|
||||
{
|
||||
id: "MiniMax-M2.7",
|
||||
name: "MiniMax M2.7",
|
||||
reasoning: true,
|
||||
input: ["text", "image"],
|
||||
cost: { input: 0.3, output: 1.2, cacheRead: 0.06, cacheWrite: 0.375 },
|
||||
contextWindow: 204800,
|
||||
maxTokens: 131072,
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
Set `MINIMAX_API_KEY`. Shortcuts:
|
||||
`openclaw onboard --auth-choice minimax-global-api` or
|
||||
`openclaw onboard --auth-choice minimax-cn-api`.
|
||||
The model catalog defaults to M2.7 only.
|
||||
On the Anthropic-compatible streaming path, OpenClaw disables MiniMax thinking
|
||||
by default unless you explicitly set `thinking` yourself. `/fast on` or
|
||||
`params.fastMode: true` rewrites `MiniMax-M2.7` to
|
||||
`MiniMax-M2.7-highspeed`.
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Local models (LM Studio)">
|
||||
|
||||
See [Local Models](/gateway/local-models). TL;DR: run a large local model via LM Studio Responses API on serious hardware; keep hosted models merged for fallback.
|
||||
|
||||
</Accordion>
|
||||
|
||||
---
|
||||
|
||||
## Related
|
||||
|
||||
- [Configuration reference](/gateway/configuration-reference) — other top-level keys
|
||||
- [Configuration — agents](/gateway/config-agents)
|
||||
- [Configuration — channels](/gateway/config-channels)
|
||||
- [Tools and plugins](/tools)
|
||||
@@ -43,654 +43,13 @@ Moved to a dedicated page — see
|
||||
- `session.*` (session lifecycle, compaction, pruning)
|
||||
- `messages.*` (message delivery, TTS, markdown rendering)
|
||||
- `talk.*` (Talk mode)
|
||||
- `talk.silenceTimeoutMs`: when unset, Talk keeps the platform default pause window before sending the transcript (`700 ms on macOS and Android, 900 ms on iOS`)
|
||||
|
||||
## Tools
|
||||
## Tools and custom providers
|
||||
|
||||
### Tool profiles
|
||||
|
||||
`tools.profile` sets a base allowlist before `tools.allow`/`tools.deny`:
|
||||
|
||||
Local onboarding defaults new local configs to `tools.profile: "coding"` when unset (existing explicit profiles are preserved).
|
||||
|
||||
| Profile | Includes |
|
||||
| ----------- | ------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `minimal` | `session_status` only |
|
||||
| `coding` | `group:fs`, `group:runtime`, `group:web`, `group:sessions`, `group:memory`, `cron`, `image`, `image_generate`, `video_generate` |
|
||||
| `messaging` | `group:messaging`, `sessions_list`, `sessions_history`, `sessions_send`, `session_status` |
|
||||
| `full` | No restriction (same as unset) |
|
||||
|
||||
### Tool groups
|
||||
|
||||
| Group | Tools |
|
||||
| ------------------ | ----------------------------------------------------------------------------------------------------------------------- |
|
||||
| `group:runtime` | `exec`, `process`, `code_execution` (`bash` is accepted as an alias for `exec`) |
|
||||
| `group:fs` | `read`, `write`, `edit`, `apply_patch` |
|
||||
| `group:sessions` | `sessions_list`, `sessions_history`, `sessions_send`, `sessions_spawn`, `sessions_yield`, `subagents`, `session_status` |
|
||||
| `group:memory` | `memory_search`, `memory_get` |
|
||||
| `group:web` | `web_search`, `x_search`, `web_fetch` |
|
||||
| `group:ui` | `browser`, `canvas` |
|
||||
| `group:automation` | `cron`, `gateway` |
|
||||
| `group:messaging` | `message` |
|
||||
| `group:nodes` | `nodes` |
|
||||
| `group:agents` | `agents_list` |
|
||||
| `group:media` | `image`, `image_generate`, `video_generate`, `tts` |
|
||||
| `group:openclaw` | All built-in tools (excludes provider plugins) |
|
||||
|
||||
### `tools.allow` / `tools.deny`
|
||||
|
||||
Global tool allow/deny policy (deny wins). Case-insensitive, supports `*` wildcards. Applied even when Docker sandbox is off.
|
||||
|
||||
```json5
|
||||
{
|
||||
tools: { deny: ["browser", "canvas"] },
|
||||
}
|
||||
```
|
||||
|
||||
### `tools.byProvider`
|
||||
|
||||
Further restrict tools for specific providers or models. Order: base profile → provider profile → allow/deny.
|
||||
|
||||
```json5
|
||||
{
|
||||
tools: {
|
||||
profile: "coding",
|
||||
byProvider: {
|
||||
"google-antigravity": { profile: "minimal" },
|
||||
"openai/gpt-5.4": { allow: ["group:fs", "sessions_list"] },
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
### `tools.elevated`
|
||||
|
||||
Controls elevated exec access outside the sandbox:
|
||||
|
||||
```json5
|
||||
{
|
||||
tools: {
|
||||
elevated: {
|
||||
enabled: true,
|
||||
allowFrom: {
|
||||
whatsapp: ["+15555550123"],
|
||||
discord: ["1234567890123", "987654321098765432"],
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
- Per-agent override (`agents.list[].tools.elevated`) can only further restrict.
|
||||
- `/elevated on|off|ask|full` stores state per session; inline directives apply to single message.
|
||||
- Elevated `exec` bypasses sandboxing and uses the configured escape path (`gateway` by default, or `node` when the exec target is `node`).
|
||||
|
||||
### `tools.exec`
|
||||
|
||||
```json5
|
||||
{
|
||||
tools: {
|
||||
exec: {
|
||||
backgroundMs: 10000,
|
||||
timeoutSec: 1800,
|
||||
cleanupMs: 1800000,
|
||||
notifyOnExit: true,
|
||||
notifyOnExitEmptySuccess: false,
|
||||
applyPatch: {
|
||||
enabled: false,
|
||||
allowModels: ["gpt-5.5"],
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
### `tools.loopDetection`
|
||||
|
||||
Tool-loop safety checks are **disabled by default**. Set `enabled: true` to activate detection.
|
||||
Settings can be defined globally in `tools.loopDetection` and overridden per-agent at `agents.list[].tools.loopDetection`.
|
||||
|
||||
```json5
|
||||
{
|
||||
tools: {
|
||||
loopDetection: {
|
||||
enabled: true,
|
||||
historySize: 30,
|
||||
warningThreshold: 10,
|
||||
criticalThreshold: 20,
|
||||
globalCircuitBreakerThreshold: 30,
|
||||
detectors: {
|
||||
genericRepeat: true,
|
||||
knownPollNoProgress: true,
|
||||
pingPong: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
- `historySize`: max tool-call history retained for loop analysis.
|
||||
- `warningThreshold`: repeating no-progress pattern threshold for warnings.
|
||||
- `criticalThreshold`: higher repeating threshold for blocking critical loops.
|
||||
- `globalCircuitBreakerThreshold`: hard stop threshold for any no-progress run.
|
||||
- `detectors.genericRepeat`: warn on repeated same-tool/same-args calls.
|
||||
- `detectors.knownPollNoProgress`: warn/block on known poll tools (`process.poll`, `command_status`, etc.).
|
||||
- `detectors.pingPong`: warn/block on alternating no-progress pair patterns.
|
||||
- If `warningThreshold >= criticalThreshold` or `criticalThreshold >= globalCircuitBreakerThreshold`, validation fails.
|
||||
|
||||
### `tools.web`
|
||||
|
||||
```json5
|
||||
{
|
||||
tools: {
|
||||
web: {
|
||||
search: {
|
||||
enabled: true,
|
||||
apiKey: "brave_api_key", // or BRAVE_API_KEY env
|
||||
maxResults: 5,
|
||||
timeoutSeconds: 30,
|
||||
cacheTtlMinutes: 15,
|
||||
},
|
||||
fetch: {
|
||||
enabled: true,
|
||||
provider: "firecrawl", // optional; omit for auto-detect
|
||||
maxChars: 50000,
|
||||
maxCharsCap: 50000,
|
||||
maxResponseBytes: 2000000,
|
||||
timeoutSeconds: 30,
|
||||
cacheTtlMinutes: 15,
|
||||
maxRedirects: 3,
|
||||
readability: true,
|
||||
userAgent: "custom-ua",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
### `tools.media`
|
||||
|
||||
Configures inbound media understanding (image/audio/video):
|
||||
|
||||
```json5
|
||||
{
|
||||
tools: {
|
||||
media: {
|
||||
concurrency: 2,
|
||||
asyncCompletion: {
|
||||
directSend: false, // opt-in: send finished async music/video directly to the channel
|
||||
},
|
||||
audio: {
|
||||
enabled: true,
|
||||
maxBytes: 20971520,
|
||||
scope: {
|
||||
default: "deny",
|
||||
rules: [{ action: "allow", match: { chatType: "direct" } }],
|
||||
},
|
||||
models: [
|
||||
{ provider: "openai", model: "gpt-4o-mini-transcribe" },
|
||||
{ type: "cli", command: "whisper", args: ["--model", "base", "{{MediaPath}}"] },
|
||||
],
|
||||
},
|
||||
video: {
|
||||
enabled: true,
|
||||
maxBytes: 52428800,
|
||||
models: [{ provider: "google", model: "gemini-3-flash-preview" }],
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
<Accordion title="Media model entry fields">
|
||||
|
||||
**Provider entry** (`type: "provider"` or omitted):
|
||||
|
||||
- `provider`: API provider id (`openai`, `anthropic`, `google`/`gemini`, `groq`, etc.)
|
||||
- `model`: model id override
|
||||
- `profile` / `preferredProfile`: `auth-profiles.json` profile selection
|
||||
|
||||
**CLI entry** (`type: "cli"`):
|
||||
|
||||
- `command`: executable to run
|
||||
- `args`: templated args (supports `{{MediaPath}}`, `{{Prompt}}`, `{{MaxChars}}`, etc.)
|
||||
|
||||
**Common fields:**
|
||||
|
||||
- `capabilities`: optional list (`image`, `audio`, `video`). Defaults: `openai`/`anthropic`/`minimax` → image, `google` → image+audio+video, `groq` → audio.
|
||||
- `prompt`, `maxChars`, `maxBytes`, `timeoutSeconds`, `language`: per-entry overrides.
|
||||
- Failures fall back to the next entry.
|
||||
|
||||
Provider auth follows standard order: `auth-profiles.json` → env vars → `models.providers.*.apiKey`.
|
||||
|
||||
**Async completion fields:**
|
||||
|
||||
- `asyncCompletion.directSend`: when `true`, completed async `music_generate`
|
||||
and `video_generate` tasks try direct channel delivery first. Default: `false`
|
||||
(legacy requester-session wake/model-delivery path).
|
||||
|
||||
</Accordion>
|
||||
|
||||
### `tools.agentToAgent`
|
||||
|
||||
```json5
|
||||
{
|
||||
tools: {
|
||||
agentToAgent: {
|
||||
enabled: false,
|
||||
allow: ["home", "work"],
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
### `tools.sessions`
|
||||
|
||||
Controls which sessions can be targeted by the session tools (`sessions_list`, `sessions_history`, `sessions_send`).
|
||||
|
||||
Default: `tree` (current session + sessions spawned by it, such as subagents).
|
||||
|
||||
```json5
|
||||
{
|
||||
tools: {
|
||||
sessions: {
|
||||
// "self" | "tree" | "agent" | "all"
|
||||
visibility: "tree",
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
Notes:
|
||||
|
||||
- `self`: only the current session key.
|
||||
- `tree`: current session + sessions spawned by the current session (subagents).
|
||||
- `agent`: any session belonging to the current agent id (can include other users if you run per-sender sessions under the same agent id).
|
||||
- `all`: any session. Cross-agent targeting still requires `tools.agentToAgent`.
|
||||
- Sandbox clamp: when the current session is sandboxed and `agents.defaults.sandbox.sessionToolsVisibility="spawned"`, visibility is forced to `tree` even if `tools.sessions.visibility="all"`.
|
||||
|
||||
### `tools.sessions_spawn`
|
||||
|
||||
Controls inline attachment support for `sessions_spawn`.
|
||||
|
||||
```json5
|
||||
{
|
||||
tools: {
|
||||
sessions_spawn: {
|
||||
attachments: {
|
||||
enabled: false, // opt-in: set true to allow inline file attachments
|
||||
maxTotalBytes: 5242880, // 5 MB total across all files
|
||||
maxFiles: 50,
|
||||
maxFileBytes: 1048576, // 1 MB per file
|
||||
retainOnSessionKeep: false, // keep attachments when cleanup="keep"
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
Notes:
|
||||
|
||||
- Attachments are only supported for `runtime: "subagent"`. ACP runtime rejects them.
|
||||
- Files are materialized into the child workspace at `.openclaw/attachments/<uuid>/` with a `.manifest.json`.
|
||||
- Attachment content is automatically redacted from transcript persistence.
|
||||
- Base64 inputs are validated with strict alphabet/padding checks and a pre-decode size guard.
|
||||
- File permissions are `0700` for directories and `0600` for files.
|
||||
- Cleanup follows the `cleanup` policy: `delete` always removes attachments; `keep` retains them only when `retainOnSessionKeep: true`.
|
||||
|
||||
<a id="toolsexperimental"></a>
|
||||
|
||||
### `tools.experimental`
|
||||
|
||||
Experimental built-in tool flags. Default off unless a strict-agentic GPT-5 auto-enable rule applies.
|
||||
|
||||
```json5
|
||||
{
|
||||
tools: {
|
||||
experimental: {
|
||||
planTool: true, // enable experimental update_plan
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
Notes:
|
||||
|
||||
- `planTool`: enables the structured `update_plan` tool for non-trivial multi-step work tracking.
|
||||
- Default: `false` unless `agents.defaults.embeddedPi.executionContract` (or a per-agent override) is set to `"strict-agentic"` for an OpenAI or OpenAI Codex GPT-5-family run. Set `true` to force the tool on outside that scope, or `false` to keep it off even for strict-agentic GPT-5 runs.
|
||||
- When enabled, the system prompt also adds usage guidance so the model only uses it for substantial work and keeps at most one step `in_progress`.
|
||||
|
||||
### `agents.defaults.subagents`
|
||||
|
||||
```json5
|
||||
{
|
||||
agents: {
|
||||
defaults: {
|
||||
subagents: {
|
||||
allowAgents: ["research"],
|
||||
model: "minimax/MiniMax-M2.7",
|
||||
maxConcurrent: 8,
|
||||
runTimeoutSeconds: 900,
|
||||
archiveAfterMinutes: 60,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
- `model`: default model for spawned sub-agents. If omitted, sub-agents inherit the caller's model.
|
||||
- `allowAgents`: default allowlist of target agent ids for `sessions_spawn` when the requester agent does not set its own `subagents.allowAgents` (`["*"]` = any; default: same agent only).
|
||||
- `runTimeoutSeconds`: default timeout (seconds) for `sessions_spawn` when the tool call omits `runTimeoutSeconds`. `0` means no timeout.
|
||||
- Per-subagent tool policy: `tools.subagents.tools.allow` / `tools.subagents.tools.deny`.
|
||||
|
||||
---
|
||||
|
||||
## Custom providers and base URLs
|
||||
|
||||
OpenClaw uses the built-in model catalog. Add custom providers via `models.providers` in config or `~/.openclaw/agents/<agentId>/agent/models.json`.
|
||||
|
||||
```json5
|
||||
{
|
||||
models: {
|
||||
mode: "merge", // merge (default) | replace
|
||||
providers: {
|
||||
"custom-proxy": {
|
||||
baseUrl: "http://localhost:4000/v1",
|
||||
apiKey: "LITELLM_KEY",
|
||||
api: "openai-completions", // openai-completions | openai-responses | anthropic-messages | google-generative-ai
|
||||
models: [
|
||||
{
|
||||
id: "llama-3.1-8b",
|
||||
name: "Llama 3.1 8B",
|
||||
reasoning: false,
|
||||
input: ["text"],
|
||||
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
|
||||
contextWindow: 128000,
|
||||
contextTokens: 96000,
|
||||
maxTokens: 32000,
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
- Use `authHeader: true` + `headers` for custom auth needs.
|
||||
- Override agent config root with `OPENCLAW_AGENT_DIR` (or `PI_CODING_AGENT_DIR`, a legacy environment variable alias).
|
||||
- Merge precedence for matching provider IDs:
|
||||
- Non-empty agent `models.json` `baseUrl` values win.
|
||||
- Non-empty agent `apiKey` values win only when that provider is not SecretRef-managed in current config/auth-profile context.
|
||||
- SecretRef-managed provider `apiKey` values are refreshed from source markers (`ENV_VAR_NAME` for env refs, `secretref-managed` for file/exec refs) instead of persisting resolved secrets.
|
||||
- SecretRef-managed provider header values are refreshed from source markers (`secretref-env:ENV_VAR_NAME` for env refs, `secretref-managed` for file/exec refs).
|
||||
- Empty or missing agent `apiKey`/`baseUrl` fall back to `models.providers` in config.
|
||||
- Matching model `contextWindow`/`maxTokens` use the higher value between explicit config and implicit catalog values.
|
||||
- Matching model `contextTokens` preserves an explicit runtime cap when present; use it to limit effective context without changing native model metadata.
|
||||
- Use `models.mode: "replace"` when you want config to fully rewrite `models.json`.
|
||||
- Marker persistence is source-authoritative: markers are written from the active source config snapshot (pre-resolution), not from resolved runtime secret values.
|
||||
|
||||
### Provider field details
|
||||
|
||||
- `models.mode`: provider catalog behavior (`merge` or `replace`).
|
||||
- `models.providers`: custom provider map keyed by provider id.
|
||||
- Safe edits: use `openclaw config set models.providers.<id> '<json>' --strict-json --merge` or `openclaw config set models.providers.<id>.models '<json-array>' --strict-json --merge` for additive updates. `config set` refuses destructive replacements unless you pass `--replace`.
|
||||
- `models.providers.*.api`: request adapter (`openai-completions`, `openai-responses`, `anthropic-messages`, `google-generative-ai`, etc).
|
||||
- `models.providers.*.apiKey`: provider credential (prefer SecretRef/env substitution).
|
||||
- `models.providers.*.auth`: auth strategy (`api-key`, `token`, `oauth`, `aws-sdk`).
|
||||
- `models.providers.*.injectNumCtxForOpenAICompat`: for Ollama + `openai-completions`, inject `options.num_ctx` into requests (default: `true`).
|
||||
- `models.providers.*.authHeader`: force credential transport in the `Authorization` header when required.
|
||||
- `models.providers.*.baseUrl`: upstream API base URL.
|
||||
- `models.providers.*.headers`: extra static headers for proxy/tenant routing.
|
||||
- `models.providers.*.request`: transport overrides for model-provider HTTP requests.
|
||||
- `request.headers`: extra headers (merged with provider defaults). Values accept SecretRef.
|
||||
- `request.auth`: auth strategy override. Modes: `"provider-default"` (use provider's built-in auth), `"authorization-bearer"` (with `token`), `"header"` (with `headerName`, `value`, optional `prefix`).
|
||||
- `request.proxy`: HTTP proxy override. Modes: `"env-proxy"` (use `HTTP_PROXY`/`HTTPS_PROXY` env vars), `"explicit-proxy"` (with `url`). Both modes accept an optional `tls` sub-object.
|
||||
- `request.tls`: TLS override for direct connections. Fields: `ca`, `cert`, `key`, `passphrase` (all accept SecretRef), `serverName`, `insecureSkipVerify`.
|
||||
- `request.allowPrivateNetwork`: when `true`, allow HTTPS to `baseUrl` when DNS resolves to private, CGNAT, or similar ranges, via the provider HTTP fetch guard (operator opt-in for trusted self-hosted OpenAI-compatible endpoints). WebSocket uses the same `request` for headers/TLS but not that fetch SSRF gate. Default `false`.
|
||||
- `models.providers.*.models`: explicit provider model catalog entries.
|
||||
- `models.providers.*.models.*.contextWindow`: native model context window metadata.
|
||||
- `models.providers.*.models.*.contextTokens`: optional runtime context cap. Use this when you want a smaller effective context budget than the model's native `contextWindow`.
|
||||
- `models.providers.*.models.*.compat.supportsDeveloperRole`: optional compatibility hint. For `api: "openai-completions"` with a non-empty non-native `baseUrl` (host not `api.openai.com`), OpenClaw forces this to `false` at runtime. Empty/omitted `baseUrl` keeps default OpenAI behavior.
|
||||
- `models.providers.*.models.*.compat.requiresStringContent`: optional compatibility hint for string-only OpenAI-compatible chat endpoints. When `true`, OpenClaw flattens pure text `messages[].content` arrays into plain strings before sending the request.
|
||||
- `plugins.entries.amazon-bedrock.config.discovery`: Bedrock auto-discovery settings root.
|
||||
- `plugins.entries.amazon-bedrock.config.discovery.enabled`: turn implicit discovery on/off.
|
||||
- `plugins.entries.amazon-bedrock.config.discovery.region`: AWS region for discovery.
|
||||
- `plugins.entries.amazon-bedrock.config.discovery.providerFilter`: optional provider-id filter for targeted discovery.
|
||||
- `plugins.entries.amazon-bedrock.config.discovery.refreshInterval`: polling interval for discovery refresh.
|
||||
- `plugins.entries.amazon-bedrock.config.discovery.defaultContextWindow`: fallback context window for discovered models.
|
||||
- `plugins.entries.amazon-bedrock.config.discovery.defaultMaxTokens`: fallback max output tokens for discovered models.
|
||||
|
||||
### Provider examples
|
||||
|
||||
<Accordion title="Cerebras (GLM 4.6 / 4.7)">
|
||||
|
||||
```json5
|
||||
{
|
||||
env: { CEREBRAS_API_KEY: "sk-..." },
|
||||
agents: {
|
||||
defaults: {
|
||||
model: {
|
||||
primary: "cerebras/zai-glm-4.7",
|
||||
fallbacks: ["cerebras/zai-glm-4.6"],
|
||||
},
|
||||
models: {
|
||||
"cerebras/zai-glm-4.7": { alias: "GLM 4.7 (Cerebras)" },
|
||||
"cerebras/zai-glm-4.6": { alias: "GLM 4.6 (Cerebras)" },
|
||||
},
|
||||
},
|
||||
},
|
||||
models: {
|
||||
mode: "merge",
|
||||
providers: {
|
||||
cerebras: {
|
||||
baseUrl: "https://api.cerebras.ai/v1",
|
||||
apiKey: "${CEREBRAS_API_KEY}",
|
||||
api: "openai-completions",
|
||||
models: [
|
||||
{ id: "zai-glm-4.7", name: "GLM 4.7 (Cerebras)" },
|
||||
{ id: "zai-glm-4.6", name: "GLM 4.6 (Cerebras)" },
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
Use `cerebras/zai-glm-4.7` for Cerebras; `zai/glm-4.7` for Z.AI direct.
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="OpenCode">
|
||||
|
||||
```json5
|
||||
{
|
||||
agents: {
|
||||
defaults: {
|
||||
model: { primary: "opencode/claude-opus-4-6" },
|
||||
models: { "opencode/claude-opus-4-6": { alias: "Opus" } },
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
Set `OPENCODE_API_KEY` (or `OPENCODE_ZEN_API_KEY`). Use `opencode/...` refs for the Zen catalog or `opencode-go/...` refs for the Go catalog. Shortcut: `openclaw onboard --auth-choice opencode-zen` or `openclaw onboard --auth-choice opencode-go`.
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Z.AI (GLM-4.7)">
|
||||
|
||||
```json5
|
||||
{
|
||||
agents: {
|
||||
defaults: {
|
||||
model: { primary: "zai/glm-4.7" },
|
||||
models: { "zai/glm-4.7": {} },
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
Set `ZAI_API_KEY`. `z.ai/*` and `z-ai/*` are accepted aliases. Shortcut: `openclaw onboard --auth-choice zai-api-key`.
|
||||
|
||||
- General endpoint: `https://api.z.ai/api/paas/v4`
|
||||
- Coding endpoint (default): `https://api.z.ai/api/coding/paas/v4`
|
||||
- For the general endpoint, define a custom provider with the base URL override.
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Moonshot AI (Kimi)">
|
||||
|
||||
```json5
|
||||
{
|
||||
env: { MOONSHOT_API_KEY: "sk-..." },
|
||||
agents: {
|
||||
defaults: {
|
||||
model: { primary: "moonshot/kimi-k2.6" },
|
||||
models: { "moonshot/kimi-k2.6": { alias: "Kimi K2.6" } },
|
||||
},
|
||||
},
|
||||
models: {
|
||||
mode: "merge",
|
||||
providers: {
|
||||
moonshot: {
|
||||
baseUrl: "https://api.moonshot.ai/v1",
|
||||
apiKey: "${MOONSHOT_API_KEY}",
|
||||
api: "openai-completions",
|
||||
models: [
|
||||
{
|
||||
id: "kimi-k2.6",
|
||||
name: "Kimi K2.6",
|
||||
reasoning: false,
|
||||
input: ["text", "image"],
|
||||
cost: { input: 0.95, output: 4, cacheRead: 0.16, cacheWrite: 0 },
|
||||
contextWindow: 262144,
|
||||
maxTokens: 262144,
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
For the China endpoint: `baseUrl: "https://api.moonshot.cn/v1"` or `openclaw onboard --auth-choice moonshot-api-key-cn`.
|
||||
|
||||
Native Moonshot endpoints advertise streaming usage compatibility on the shared
|
||||
`openai-completions` transport, and OpenClaw keys that off endpoint capabilities
|
||||
rather than the built-in provider id alone.
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Kimi Coding">
|
||||
|
||||
```json5
|
||||
{
|
||||
env: { KIMI_API_KEY: "sk-..." },
|
||||
agents: {
|
||||
defaults: {
|
||||
model: { primary: "kimi/kimi-code" },
|
||||
models: { "kimi/kimi-code": { alias: "Kimi Code" } },
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
Anthropic-compatible, built-in provider. Shortcut: `openclaw onboard --auth-choice kimi-code-api-key`.
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Synthetic (Anthropic-compatible)">
|
||||
|
||||
```json5
|
||||
{
|
||||
env: { SYNTHETIC_API_KEY: "sk-..." },
|
||||
agents: {
|
||||
defaults: {
|
||||
model: { primary: "synthetic/hf:MiniMaxAI/MiniMax-M2.5" },
|
||||
models: { "synthetic/hf:MiniMaxAI/MiniMax-M2.5": { alias: "MiniMax M2.5" } },
|
||||
},
|
||||
},
|
||||
models: {
|
||||
mode: "merge",
|
||||
providers: {
|
||||
synthetic: {
|
||||
baseUrl: "https://api.synthetic.new/anthropic",
|
||||
apiKey: "${SYNTHETIC_API_KEY}",
|
||||
api: "anthropic-messages",
|
||||
models: [
|
||||
{
|
||||
id: "hf:MiniMaxAI/MiniMax-M2.5",
|
||||
name: "MiniMax M2.5",
|
||||
reasoning: true,
|
||||
input: ["text"],
|
||||
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
|
||||
contextWindow: 192000,
|
||||
maxTokens: 65536,
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
Base URL should omit `/v1` (Anthropic client appends it). Shortcut: `openclaw onboard --auth-choice synthetic-api-key`.
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="MiniMax M2.7 (direct)">
|
||||
|
||||
```json5
|
||||
{
|
||||
agents: {
|
||||
defaults: {
|
||||
model: { primary: "minimax/MiniMax-M2.7" },
|
||||
models: {
|
||||
"minimax/MiniMax-M2.7": { alias: "Minimax" },
|
||||
},
|
||||
},
|
||||
},
|
||||
models: {
|
||||
mode: "merge",
|
||||
providers: {
|
||||
minimax: {
|
||||
baseUrl: "https://api.minimax.io/anthropic",
|
||||
apiKey: "${MINIMAX_API_KEY}",
|
||||
api: "anthropic-messages",
|
||||
models: [
|
||||
{
|
||||
id: "MiniMax-M2.7",
|
||||
name: "MiniMax M2.7",
|
||||
reasoning: true,
|
||||
input: ["text", "image"],
|
||||
cost: { input: 0.3, output: 1.2, cacheRead: 0.06, cacheWrite: 0.375 },
|
||||
contextWindow: 204800,
|
||||
maxTokens: 131072,
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
Set `MINIMAX_API_KEY`. Shortcuts:
|
||||
`openclaw onboard --auth-choice minimax-global-api` or
|
||||
`openclaw onboard --auth-choice minimax-cn-api`.
|
||||
The model catalog defaults to M2.7 only.
|
||||
On the Anthropic-compatible streaming path, OpenClaw disables MiniMax thinking
|
||||
by default unless you explicitly set `thinking` yourself. `/fast on` or
|
||||
`params.fastMode: true` rewrites `MiniMax-M2.7` to
|
||||
`MiniMax-M2.7-highspeed`.
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Local models (LM Studio)">
|
||||
|
||||
See [Local Models](/gateway/local-models). TL;DR: run a large local model via LM Studio Responses API on serious hardware; keep hosted models merged for fallback.
|
||||
|
||||
</Accordion>
|
||||
|
||||
---
|
||||
Tool policy, experimental toggles, provider-backed tool config, and custom
|
||||
provider / base-URL setup moved to a dedicated page — see
|
||||
[Configuration — tools and custom providers](/gateway/config-tools).
|
||||
|
||||
## Skills
|
||||
|
||||
@@ -960,7 +319,12 @@ See [Plugins](/tools/plugin).
|
||||
- `controlUi.allowedOrigins`: explicit browser-origin allowlist for Gateway WebSocket connects. Required when browser clients are expected from non-loopback origins.
|
||||
- `controlUi.dangerouslyAllowHostHeaderOriginFallback`: dangerous mode that enables Host-header origin fallback for deployments that intentionally rely on Host-header origin policy.
|
||||
- `remote.transport`: `ssh` (default) or `direct` (ws/wss). For `direct`, `remote.url` must be `ws://` or `wss://`.
|
||||
- `OPENCLAW_ALLOW_INSECURE_PRIVATE_WS=1`: client-side break-glass override that allows plaintext `ws://` to trusted private-network IPs; default remains loopback-only for plaintext.
|
||||
- `OPENCLAW_ALLOW_INSECURE_PRIVATE_WS=1`: client-side process-environment
|
||||
break-glass override that allows plaintext `ws://` to trusted private-network
|
||||
IPs; default remains loopback-only for plaintext. There is no `openclaw.json`
|
||||
equivalent, and browser private-network config such as
|
||||
`browser.ssrfPolicy.dangerouslyAllowPrivateNetwork` does not affect Gateway
|
||||
WebSocket clients.
|
||||
- `gateway.remote.token` / `.password` are remote-client credential fields. They do not configure gateway auth by themselves.
|
||||
- `gateway.push.apns.relay.baseUrl`: base HTTPS URL for the external APNs relay used by official/TestFlight iOS builds after they publish relay-backed registrations to the gateway. This URL must match the relay URL compiled into the iOS build.
|
||||
- `gateway.push.apns.relay.timeoutMs`: gateway-to-relay send timeout in milliseconds. Defaults to `10000`.
|
||||
@@ -1577,7 +941,7 @@ Metadata written by CLI guided setup flows (`onboard`, `configure`, `doctor`):
|
||||
|
||||
## Identity
|
||||
|
||||
See `agents.list` identity fields under [Agent defaults](#agent-defaults).
|
||||
See `agents.list` identity fields under [Agent defaults](/gateway/config-agents#agent-defaults).
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -151,7 +151,7 @@ is skipped when a candidate contains redacted secret placeholders such as `***`.
|
||||
- Model refs use `provider/model` format (e.g. `anthropic/claude-opus-4-6`).
|
||||
- `agents.defaults.imageMaxDimensionPx` controls transcript/tool image downscaling (default `1200`); lower values usually reduce vision-token usage on screenshot-heavy runs.
|
||||
- See [Models CLI](/concepts/models) for switching models in chat and [Model Failover](/concepts/model-failover) for auth rotation and fallback behavior.
|
||||
- For custom/self-hosted providers, see [Custom providers](/gateway/configuration-reference#custom-providers-and-base-urls) in the reference.
|
||||
- For custom/self-hosted providers, see [Custom providers](/gateway/config-tools#custom-providers-and-base-urls) in the reference.
|
||||
|
||||
</Accordion>
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user