mirror of
https://github.com/openclaw/openclaw.git
synced 2026-06-19 12:52:06 +08:00
Compare commits
2 Commits
codex/loca
...
codex/prob
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
764fc3916e | ||
|
|
1c33856130 |
2
.github/CODEOWNERS
vendored
2
.github/CODEOWNERS
vendored
@@ -31,7 +31,7 @@
|
||||
/src/gateway/**/*secret*.ts @openclaw/openclaw-secops
|
||||
/src/gateway/security-path*.ts @openclaw/openclaw-secops
|
||||
/src/gateway/resolve-configured-secret-input-string*.ts @openclaw/openclaw-secops
|
||||
/packages/gateway-protocol/src/**/*secret*.ts @openclaw/openclaw-secops
|
||||
/src/gateway/protocol/**/*secret*.ts @openclaw/openclaw-secops
|
||||
/src/gateway/server-methods/secrets*.ts @openclaw/openclaw-secops
|
||||
/src/agents/*auth*.ts @openclaw/openclaw-secops
|
||||
/src/agents/**/*auth*.ts @openclaw/openclaw-secops
|
||||
|
||||
10
.github/actions/ensure-base-commit/action.yml
vendored
10
.github/actions/ensure-base-commit/action.yml
vendored
@@ -38,15 +38,9 @@ runs:
|
||||
exit 0
|
||||
fi
|
||||
|
||||
fetch_base_ref() {
|
||||
timeout --signal=TERM --kill-after=10s 30s git \
|
||||
-c protocol.version=2 \
|
||||
fetch "$@"
|
||||
}
|
||||
|
||||
for deepen_by in 25 100 300; do
|
||||
echo "Base commit missing; deepening $FETCH_REF by $deepen_by."
|
||||
if ! fetch_base_ref --no-tags --deepen="$deepen_by" origin -- "$FETCH_REF"; then
|
||||
if ! git fetch --no-tags --deepen="$deepen_by" origin -- "$FETCH_REF"; then
|
||||
echo "::warning title=ensure-base-commit fetch failed::Failed to deepen $FETCH_REF by $deepen_by while looking for $BASE_SHA"
|
||||
fi
|
||||
if git rev-parse --verify "$BASE_SHA^{commit}" >/dev/null 2>&1; then
|
||||
@@ -56,7 +50,7 @@ runs:
|
||||
done
|
||||
|
||||
echo "Base commit still missing; fetching full history for $FETCH_REF."
|
||||
if ! fetch_base_ref --no-tags origin -- "$FETCH_REF"; then
|
||||
if ! git fetch --no-tags origin -- "$FETCH_REF"; then
|
||||
echo "::warning title=ensure-base-commit fetch failed::Failed to fetch full history for $FETCH_REF while looking for $BASE_SHA"
|
||||
fi
|
||||
if git rev-parse --verify "$BASE_SHA^{commit}" >/dev/null 2>&1; then
|
||||
|
||||
@@ -19,7 +19,7 @@ paths:
|
||||
- src/config/types.channel*.ts
|
||||
- src/gateway/server-channel*.ts
|
||||
- src/gateway/server-methods/channels.ts
|
||||
- packages/gateway-protocol/src/schema/channels.ts
|
||||
- src/gateway/protocol/schema/channels.ts
|
||||
- src/infra/channel-*.ts
|
||||
- src/infra/exec-approval-channel-runtime.ts
|
||||
- src/infra/outbound/channel-*.ts
|
||||
|
||||
@@ -30,7 +30,7 @@ paths:
|
||||
- src/gateway/**/*auth*.ts
|
||||
- src/gateway/*secret*.ts
|
||||
- src/gateway/**/*secret*.ts
|
||||
- packages/gateway-protocol/src/**/*secret*.ts
|
||||
- src/gateway/protocol/**/*secret*.ts
|
||||
- src/gateway/resolve-configured-secret-input-string*.ts
|
||||
- src/gateway/security-path*.ts
|
||||
- src/gateway/server-methods/secrets*.ts
|
||||
|
||||
@@ -30,7 +30,7 @@ paths:
|
||||
- src/gateway/**/*auth*.ts
|
||||
- src/gateway/*secret*.ts
|
||||
- src/gateway/**/*secret*.ts
|
||||
- packages/gateway-protocol/src/**/*secret*.ts
|
||||
- src/gateway/protocol/**/*secret*.ts
|
||||
- src/gateway/resolve-configured-secret-input-string*.ts
|
||||
- src/gateway/security-path*.ts
|
||||
- src/gateway/server-methods/secrets*.ts
|
||||
|
||||
@@ -15,7 +15,7 @@ query-filters:
|
||||
|
||||
paths:
|
||||
- src/gateway/method-scopes.ts
|
||||
- packages/gateway-protocol/src
|
||||
- src/gateway/protocol
|
||||
- src/gateway/server-methods
|
||||
- src/gateway/server-methods.ts
|
||||
- src/gateway/server-methods-list.ts
|
||||
|
||||
@@ -9,7 +9,6 @@ queries:
|
||||
paths:
|
||||
- src
|
||||
- extensions
|
||||
- packages/net-policy/src
|
||||
|
||||
paths-ignore:
|
||||
- "**/node_modules"
|
||||
|
||||
@@ -15,6 +15,7 @@ query-filters:
|
||||
|
||||
paths:
|
||||
- src/infra/net
|
||||
- src/shared/net
|
||||
- src/agents/tools/web-fetch.ts
|
||||
- src/agents/tools/web-guarded-fetch.ts
|
||||
- src/agents/tools/web-shared.ts
|
||||
@@ -22,7 +23,6 @@ paths:
|
||||
- src/web-fetch
|
||||
- src/web/provider-runtime-shared.ts
|
||||
- packages/memory-host-sdk/src/host/ssrf-policy.ts
|
||||
- packages/net-policy/src
|
||||
|
||||
paths-ignore:
|
||||
- "**/node_modules"
|
||||
|
||||
@@ -76,8 +76,6 @@ predicate allowedRawSocketClientCall(Expr call) {
|
||||
or
|
||||
allowedOwnerScope(call, "src/proxy-capture/proxy-server.ts", "startDebugProxyServer")
|
||||
or
|
||||
allowedOwnerScope(call, "extensions/codex-supervisor/src/json-rpc-client.ts", "connectCodexSupervisorUnixSocket")
|
||||
or
|
||||
allowedOwnerScope(call, "extensions/irc/src/client.ts", "connectIrcClient")
|
||||
or
|
||||
allowedOwnerScope(call, "extensions/qa-lab/src/lab-server-capture.ts", "probeTcpReachability")
|
||||
|
||||
20
.github/labeler.yml
vendored
20
.github/labeler.yml
vendored
@@ -47,12 +47,6 @@
|
||||
- "extensions/meeting-notes/**"
|
||||
- "docs/plugins/meeting-notes.md"
|
||||
- "src/meeting-notes/**"
|
||||
"plugin: workboard":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- "extensions/workboard/**"
|
||||
- "docs/plugins/workboard.md"
|
||||
- "docs/plugins/reference/workboard.md"
|
||||
"plugin: migrate-hermes":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
@@ -194,7 +188,7 @@
|
||||
- "ui/**"
|
||||
- "src/gateway/control-ui.ts"
|
||||
- "src/gateway/control-ui-shared.ts"
|
||||
- "packages/gateway-protocol/src/**"
|
||||
- "src/gateway/protocol/**"
|
||||
- "src/gateway/server-methods/chat.ts"
|
||||
- "src/infra/control-ui-assets.ts"
|
||||
|
||||
@@ -202,7 +196,6 @@
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- "src/gateway/**"
|
||||
- "packages/gateway-protocol/src/**"
|
||||
- "src/daemon/**"
|
||||
- "docs/gateway/**"
|
||||
|
||||
@@ -405,17 +398,6 @@
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- "extensions/codex/**"
|
||||
"extensions: codex-supervisor":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- "extensions/codex-supervisor/**"
|
||||
- "docs/plugins/reference/codex-supervisor.md"
|
||||
- "docs/specs/claw-supervisor.md"
|
||||
"extensions: copilot":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- "extensions/copilot/**"
|
||||
- "docs/plugins/copilot.md"
|
||||
"extensions: kimi-coding":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
|
||||
@@ -188,10 +188,7 @@ jobs:
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
timeout --signal=TERM --kill-after=10s 30s git \
|
||||
-c protocol.version=2 \
|
||||
fetch --no-tags --prune --no-recurse-submodules --depth=50 origin \
|
||||
"+refs/heads/main:refs/remotes/origin/main"
|
||||
git fetch --no-tags --depth=50 origin "+refs/heads/main:refs/remotes/origin/main"
|
||||
|
||||
node_bin="$(dirname "$(node -p 'process.execPath')")"
|
||||
sudo ln -sf "$node_bin/node" /usr/local/bin/node
|
||||
|
||||
5
.github/workflows/ci-check-testbox.yml
vendored
5
.github/workflows/ci-check-testbox.yml
vendored
@@ -89,10 +89,7 @@ jobs:
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
timeout --signal=TERM --kill-after=10s 30s git \
|
||||
-c protocol.version=2 \
|
||||
fetch --no-tags --prune --no-recurse-submodules --depth=50 origin \
|
||||
"+refs/heads/main:refs/remotes/origin/main"
|
||||
git fetch --no-tags --depth=50 origin "+refs/heads/main:refs/remotes/origin/main"
|
||||
|
||||
node_bin="$(dirname "$(node -p 'process.execPath')")"
|
||||
sudo ln -sf "$node_bin/node" /usr/local/bin/node
|
||||
|
||||
150
.github/workflows/ci.yml
vendored
150
.github/workflows/ci.yml
vendored
@@ -86,38 +86,12 @@ jobs:
|
||||
git init "$GITHUB_WORKSPACE"
|
||||
git -C "$GITHUB_WORKSPACE" config gc.auto 0
|
||||
git -C "$GITHUB_WORKSPACE" remote add origin "https://github.com/${CHECKOUT_REPO}.git"
|
||||
fetch_checkout_ref() {
|
||||
local ref="$1"
|
||||
local fetch_status
|
||||
for attempt in 1 2 3; do
|
||||
timeout --signal=TERM --kill-after=10s 30s git -C "$GITHUB_WORKSPACE" \
|
||||
-c protocol.version=2 \
|
||||
fetch --no-tags --prune --no-recurse-submodules --depth=1 origin \
|
||||
"+${ref}:refs/remotes/origin/checkout" && return 0
|
||||
fetch_status="$?"
|
||||
if [ "$fetch_status" != "124" ] && [ "$fetch_status" != "137" ]; then
|
||||
return "$fetch_status"
|
||||
fi
|
||||
if [ "$attempt" = "3" ]; then
|
||||
return "$fetch_status"
|
||||
fi
|
||||
echo "::warning::checkout fetch for '$ref' timed out on attempt $attempt; retrying"
|
||||
sleep 5
|
||||
done
|
||||
}
|
||||
if fetch_checkout_ref "$CHECKOUT_REF"; then
|
||||
:
|
||||
else
|
||||
fetch_status="$?"
|
||||
if [ "$fetch_status" = "124" ] || [ "$fetch_status" = "137" ]; then
|
||||
echo "::error::checkout fetch for '$CHECKOUT_REF' timed out"
|
||||
exit "$fetch_status"
|
||||
fi
|
||||
if ! git -C "$GITHUB_WORKSPACE" fetch --no-tags --depth=1 origin "+${CHECKOUT_REF}:refs/remotes/origin/checkout"; then
|
||||
if [ "$GITHUB_EVENT_NAME" != "workflow_dispatch" ] || [ "$CHECKOUT_REF" = "$CHECKOUT_FALLBACK_REF" ]; then
|
||||
exit "$fetch_status"
|
||||
exit 1
|
||||
fi
|
||||
echo "::warning::workflow_dispatch target_ref '$CHECKOUT_REF' is unavailable; falling back to head SHA '$CHECKOUT_FALLBACK_REF'"
|
||||
fetch_checkout_ref "$CHECKOUT_FALLBACK_REF"
|
||||
git -C "$GITHUB_WORKSPACE" fetch --no-tags --depth=1 origin "+${CHECKOUT_FALLBACK_REF}:refs/remotes/origin/checkout"
|
||||
fi
|
||||
git -C "$GITHUB_WORKSPACE" checkout --detach refs/remotes/origin/checkout
|
||||
|
||||
@@ -347,38 +321,12 @@ jobs:
|
||||
git init "$GITHUB_WORKSPACE"
|
||||
git -C "$GITHUB_WORKSPACE" config gc.auto 0
|
||||
git -C "$GITHUB_WORKSPACE" remote add origin "https://github.com/${CHECKOUT_REPO}.git"
|
||||
fetch_checkout_ref() {
|
||||
local ref="$1"
|
||||
local fetch_status
|
||||
for attempt in 1 2 3; do
|
||||
timeout --signal=TERM --kill-after=10s 30s git -C "$GITHUB_WORKSPACE" \
|
||||
-c protocol.version=2 \
|
||||
fetch --no-tags --prune --no-recurse-submodules --depth=1 origin \
|
||||
"+${ref}:refs/remotes/origin/checkout" && return 0
|
||||
fetch_status="$?"
|
||||
if [ "$fetch_status" != "124" ] && [ "$fetch_status" != "137" ]; then
|
||||
return "$fetch_status"
|
||||
fi
|
||||
if [ "$attempt" = "3" ]; then
|
||||
return "$fetch_status"
|
||||
fi
|
||||
echo "::warning::checkout fetch for '$ref' timed out on attempt $attempt; retrying"
|
||||
sleep 5
|
||||
done
|
||||
}
|
||||
if fetch_checkout_ref "$CHECKOUT_REF"; then
|
||||
:
|
||||
else
|
||||
fetch_status="$?"
|
||||
if [ "$fetch_status" = "124" ] || [ "$fetch_status" = "137" ]; then
|
||||
echo "::error::checkout fetch for '$CHECKOUT_REF' timed out"
|
||||
exit "$fetch_status"
|
||||
fi
|
||||
if ! git -C "$GITHUB_WORKSPACE" fetch --no-tags --depth=1 origin "+${CHECKOUT_REF}:refs/remotes/origin/checkout"; then
|
||||
if [ "$GITHUB_EVENT_NAME" != "workflow_dispatch" ] || [ "$CHECKOUT_REF" = "$CHECKOUT_FALLBACK_REF" ]; then
|
||||
exit "$fetch_status"
|
||||
exit 1
|
||||
fi
|
||||
echo "::warning::workflow_dispatch target_ref '$CHECKOUT_REF' is unavailable; falling back to head SHA '$CHECKOUT_FALLBACK_REF'"
|
||||
fetch_checkout_ref "$CHECKOUT_FALLBACK_REF"
|
||||
git -C "$GITHUB_WORKSPACE" fetch --no-tags --depth=1 origin "+${CHECKOUT_FALLBACK_REF}:refs/remotes/origin/checkout"
|
||||
fi
|
||||
git -C "$GITHUB_WORKSPACE" checkout --detach refs/remotes/origin/checkout
|
||||
|
||||
@@ -1607,25 +1555,7 @@ jobs:
|
||||
git init "$GITHUB_WORKSPACE"
|
||||
git -C "$GITHUB_WORKSPACE" config gc.auto 0
|
||||
git -C "$GITHUB_WORKSPACE" remote add origin "https://github.com/${CHECKOUT_REPO}.git"
|
||||
fetch_checkout_ref() {
|
||||
local fetch_status
|
||||
for attempt in 1 2 3; do
|
||||
timeout --signal=TERM --kill-after=10s 30s git -C "$GITHUB_WORKSPACE" \
|
||||
-c protocol.version=2 \
|
||||
fetch --no-tags --prune --no-recurse-submodules --depth=1 origin \
|
||||
"+${CHECKOUT_SHA}:refs/remotes/origin/checkout" && return 0
|
||||
fetch_status="$?"
|
||||
if [ "$fetch_status" != "124" ] && [ "$fetch_status" != "137" ]; then
|
||||
return "$fetch_status"
|
||||
fi
|
||||
if [ "$attempt" = "3" ]; then
|
||||
return "$fetch_status"
|
||||
fi
|
||||
echo "::warning::checkout fetch for '$CHECKOUT_SHA' timed out on attempt $attempt; retrying"
|
||||
sleep 5
|
||||
done
|
||||
}
|
||||
fetch_checkout_ref
|
||||
git -C "$GITHUB_WORKSPACE" fetch --no-tags --depth=1 origin "+${CHECKOUT_SHA}:refs/remotes/origin/checkout"
|
||||
git -C "$GITHUB_WORKSPACE" checkout --detach refs/remotes/origin/checkout
|
||||
|
||||
- name: Setup Python
|
||||
@@ -1673,27 +1603,7 @@ jobs:
|
||||
git init "$GITHUB_WORKSPACE"
|
||||
git -C "$GITHUB_WORKSPACE" config gc.auto 0
|
||||
git -C "$GITHUB_WORKSPACE" remote add origin "https://github.com/${CHECKOUT_REPO}.git"
|
||||
fetch_checkout_ref() {
|
||||
git -C "$GITHUB_WORKSPACE" \
|
||||
-c protocol.version=2 \
|
||||
fetch --no-tags --prune --no-recurse-submodules --depth=1 origin \
|
||||
"+${CHECKOUT_SHA}:refs/remotes/origin/checkout" &
|
||||
local fetch_pid="$!"
|
||||
local elapsed=0
|
||||
while kill -0 "$fetch_pid" 2>/dev/null; do
|
||||
if [ "$elapsed" -ge 30 ]; then
|
||||
kill -TERM "$fetch_pid" 2>/dev/null || true
|
||||
sleep 10
|
||||
kill -KILL "$fetch_pid" 2>/dev/null || true
|
||||
wait "$fetch_pid" || true
|
||||
return 124
|
||||
fi
|
||||
sleep 1
|
||||
elapsed=$((elapsed + 1))
|
||||
done
|
||||
wait "$fetch_pid"
|
||||
}
|
||||
fetch_checkout_ref
|
||||
git -C "$GITHUB_WORKSPACE" fetch --no-tags --depth=1 origin "+${CHECKOUT_SHA}:refs/remotes/origin/checkout"
|
||||
git -C "$GITHUB_WORKSPACE" checkout --detach refs/remotes/origin/checkout
|
||||
|
||||
- name: Try to exclude workspace from Windows Defender (best-effort)
|
||||
@@ -1793,27 +1703,7 @@ jobs:
|
||||
git init "$GITHUB_WORKSPACE"
|
||||
git -C "$GITHUB_WORKSPACE" config gc.auto 0
|
||||
git -C "$GITHUB_WORKSPACE" remote add origin "https://github.com/${CHECKOUT_REPO}.git"
|
||||
fetch_checkout_ref() {
|
||||
git -C "$GITHUB_WORKSPACE" \
|
||||
-c protocol.version=2 \
|
||||
fetch --no-tags --prune --no-recurse-submodules --depth=1 origin \
|
||||
"+${CHECKOUT_SHA}:refs/remotes/origin/checkout" &
|
||||
local fetch_pid="$!"
|
||||
local elapsed=0
|
||||
while kill -0 "$fetch_pid" 2>/dev/null; do
|
||||
if [ "$elapsed" -ge 30 ]; then
|
||||
kill -TERM "$fetch_pid" 2>/dev/null || true
|
||||
sleep 10
|
||||
kill -KILL "$fetch_pid" 2>/dev/null || true
|
||||
wait "$fetch_pid" || true
|
||||
return 124
|
||||
fi
|
||||
sleep 1
|
||||
elapsed=$((elapsed + 1))
|
||||
done
|
||||
wait "$fetch_pid"
|
||||
}
|
||||
fetch_checkout_ref
|
||||
git -C "$GITHUB_WORKSPACE" fetch --no-tags --depth=1 origin "+${CHECKOUT_SHA}:refs/remotes/origin/checkout"
|
||||
git -C "$GITHUB_WORKSPACE" checkout --detach refs/remotes/origin/checkout
|
||||
|
||||
- name: Setup Node environment
|
||||
@@ -1859,27 +1749,7 @@ jobs:
|
||||
git init "$GITHUB_WORKSPACE"
|
||||
git -C "$GITHUB_WORKSPACE" config gc.auto 0
|
||||
git -C "$GITHUB_WORKSPACE" remote add origin "https://github.com/${CHECKOUT_REPO}.git"
|
||||
fetch_checkout_ref() {
|
||||
git -C "$GITHUB_WORKSPACE" \
|
||||
-c protocol.version=2 \
|
||||
fetch --no-tags --prune --no-recurse-submodules --depth=1 origin \
|
||||
"+${CHECKOUT_SHA}:refs/remotes/origin/checkout" &
|
||||
local fetch_pid="$!"
|
||||
local elapsed=0
|
||||
while kill -0 "$fetch_pid" 2>/dev/null; do
|
||||
if [ "$elapsed" -ge 30 ]; then
|
||||
kill -TERM "$fetch_pid" 2>/dev/null || true
|
||||
sleep 10
|
||||
kill -KILL "$fetch_pid" 2>/dev/null || true
|
||||
wait "$fetch_pid" || true
|
||||
return 124
|
||||
fi
|
||||
sleep 1
|
||||
elapsed=$((elapsed + 1))
|
||||
done
|
||||
wait "$fetch_pid"
|
||||
}
|
||||
fetch_checkout_ref
|
||||
git -C "$GITHUB_WORKSPACE" fetch --no-tags --depth=1 origin "+${CHECKOUT_SHA}:refs/remotes/origin/checkout"
|
||||
git -C "$GITHUB_WORKSPACE" checkout --detach refs/remotes/origin/checkout
|
||||
|
||||
- name: Install XcodeGen / SwiftLint / SwiftFormat
|
||||
|
||||
9
.github/workflows/clawsweeper-dispatch.yml
vendored
9
.github/workflows/clawsweeper-dispatch.yml
vendored
@@ -24,14 +24,7 @@ concurrency:
|
||||
jobs:
|
||||
dispatch:
|
||||
runs-on: ubuntu-latest
|
||||
if: >-
|
||||
${{
|
||||
github.event_name == 'issue_comment' ||
|
||||
!(
|
||||
endsWith(github.actor, '[bot]') &&
|
||||
(github.event.action == 'labeled' || github.event.action == 'unlabeled')
|
||||
)
|
||||
}}
|
||||
if: ${{ github.event_name == 'issue_comment' || !(endsWith(github.actor, '[bot]') && (github.event.action == 'labeled' || github.event.action == 'unlabeled')) }}
|
||||
env:
|
||||
HAS_CLAWSWEEPER_APP_PRIVATE_KEY: ${{ secrets.CLAWSWEEPER_APP_PRIVATE_KEY != '' }}
|
||||
CLAWSWEEPER_APP_CLIENT_ID: Iv23liOECG0slfuhz093
|
||||
|
||||
11
.github/workflows/codeql-critical-quality.yml
vendored
11
.github/workflows/codeql-critical-quality.yml
vendored
@@ -33,7 +33,6 @@ on:
|
||||
- "packages/plugin-package-contract/**"
|
||||
- "packages/plugin-sdk/**"
|
||||
- "packages/memory-host-sdk/**"
|
||||
- "packages/net-policy/**"
|
||||
- "src/*.ts"
|
||||
- "src/**/*.ts"
|
||||
- "src/config/**"
|
||||
@@ -107,13 +106,13 @@ on:
|
||||
- "src/gateway/**/*auth*.ts"
|
||||
- "src/gateway/*secret*.ts"
|
||||
- "src/gateway/**/*secret*.ts"
|
||||
- "packages/gateway-protocol/src/**/*secret*.ts"
|
||||
- "src/gateway/protocol/**/*secret*.ts"
|
||||
- "src/gateway/resolve-configured-secret-input-string*.ts"
|
||||
- "src/gateway/security-path*.ts"
|
||||
- "src/gateway/server-methods/secrets*.ts"
|
||||
- "src/gateway/server-startup-memory.ts"
|
||||
- "src/gateway/method-scopes.ts"
|
||||
- "packages/gateway-protocol/src/**"
|
||||
- "src/gateway/protocol/**"
|
||||
- "src/gateway/server-methods/**"
|
||||
- "src/gateway/server-methods.ts"
|
||||
- "src/gateway/server-methods-list.ts"
|
||||
@@ -245,14 +244,14 @@ jobs:
|
||||
src/config/*)
|
||||
config=true
|
||||
;;
|
||||
packages/gateway-protocol/src/*secret*.ts|packages/gateway-protocol/src/**/*secret*.ts|src/gateway/server-methods/secrets*.ts)
|
||||
src/gateway/protocol/*secret*.ts|src/gateway/server-methods/secrets*.ts)
|
||||
core_auth_secrets=true
|
||||
gateway=true
|
||||
;;
|
||||
src/agents/*auth*.ts|src/agents/auth-health*.ts|src/agents/auth-profiles|src/agents/auth-profiles/*|src/agents/bash-tools.exec-host-shared.ts|src/agents/sandbox|src/agents/sandbox.ts|src/agents/sandbox-*.ts|src/agents/sandbox/*|src/cron/service/jobs.ts|src/cron/stagger.ts|src/gateway/*auth*.ts|src/gateway/*secret*.ts|src/gateway/resolve-configured-secret-input-string*.ts|src/gateway/security-path*.ts|src/infra/secret-file*.ts|src/secrets/*|src/security/*)
|
||||
core_auth_secrets=true
|
||||
;;
|
||||
packages/gateway-protocol/src/*|packages/gateway-protocol/src/**/*|src/gateway/method-scopes.ts|src/gateway/server-methods/*|src/gateway/server-methods.ts|src/gateway/server-methods-list.ts)
|
||||
src/gateway/method-scopes.ts|src/gateway/protocol/*|src/gateway/server-methods/*|src/gateway/server-methods.ts|src/gateway/server-methods-list.ts)
|
||||
gateway=true
|
||||
;;
|
||||
packages/memory-host-sdk/*|src/commands/doctor-cron-dreaming-payload-migration.ts|src/commands/doctor-memory-search.ts|src/gateway/server-startup-memory.ts|src/memory/*|src/memory-host-sdk/*)
|
||||
@@ -302,7 +301,7 @@ jobs:
|
||||
esac
|
||||
|
||||
case "${file}" in
|
||||
src/*.ts|src/**/*.ts|extensions/*.ts|extensions/**/*.ts|packages/net-policy/src/*|packages/net-policy/src/**/*)
|
||||
src/*.ts|src/**/*.ts|extensions/*.ts|extensions/**/*.ts)
|
||||
network_runtime=true
|
||||
;;
|
||||
esac
|
||||
|
||||
@@ -138,7 +138,7 @@ jobs:
|
||||
OPENAI_API_KEY: ${{ secrets.OPENCLAW_DOCS_I18N_OPENAI_API_KEY || secrets.OPENAI_API_KEY }}
|
||||
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
|
||||
OPENCLAW_CONTROL_UI_I18N_PROVIDER: ${{ secrets.ANTHROPIC_API_KEY != '' && 'anthropic' || 'openai' }}
|
||||
OPENCLAW_CONTROL_UI_I18N_MODEL: ${{ secrets.ANTHROPIC_API_KEY != '' && 'claude-opus-4-8' || vars.OPENCLAW_CI_OPENAI_MODEL_BARE }}
|
||||
OPENCLAW_CONTROL_UI_I18N_MODEL: ${{ secrets.ANTHROPIC_API_KEY != '' && 'claude-opus-4-7' || vars.OPENCLAW_CI_OPENAI_MODEL_BARE }}
|
||||
OPENCLAW_CONTROL_UI_I18N_THINKING: low
|
||||
OPENCLAW_CONTROL_UI_I18N_AUTH_OPTIONAL: "1"
|
||||
LOCALE: ${{ matrix.locale }}
|
||||
|
||||
31
.github/workflows/crabbox-hydrate.yml
vendored
31
.github/workflows/crabbox-hydrate.yml
vendored
@@ -137,10 +137,7 @@ jobs:
|
||||
set -euo pipefail
|
||||
|
||||
if git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
|
||||
timeout --signal=TERM --kill-after=10s 30s git \
|
||||
-c protocol.version=2 \
|
||||
fetch --no-tags --prune --no-recurse-submodules --depth=50 origin \
|
||||
"+refs/heads/main:refs/remotes/origin/main"
|
||||
git fetch --no-tags --depth=50 origin "+refs/heads/main:refs/remotes/origin/main"
|
||||
fi
|
||||
|
||||
- name: Prepare Crabbox shell
|
||||
@@ -321,26 +318,7 @@ jobs:
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
if (git rev-parse --is-inside-work-tree 2>$null) {
|
||||
$repo = (Get-Location).Path
|
||||
$fetchInfo = New-Object System.Diagnostics.ProcessStartInfo
|
||||
$fetchInfo.FileName = "git"
|
||||
$fetchInfo.WorkingDirectory = $repo
|
||||
$fetchInfo.UseShellExecute = $false
|
||||
$fetchInfo.Arguments = '-c protocol.version=2 fetch --no-tags --no-progress --prune --no-recurse-submodules --depth=50 origin "+refs/heads/main:refs/remotes/origin/main"'
|
||||
|
||||
$fetch = New-Object System.Diagnostics.Process
|
||||
$fetch.StartInfo = $fetchInfo
|
||||
if (-not $fetch.Start()) {
|
||||
throw "git fetch failed to start"
|
||||
}
|
||||
if (-not $fetch.WaitForExit(30000)) {
|
||||
$fetch.Kill()
|
||||
$fetch.WaitForExit()
|
||||
throw "git fetch timed out after 30 seconds"
|
||||
}
|
||||
if ($fetch.ExitCode -ne 0) {
|
||||
throw "git fetch failed with exit code $($fetch.ExitCode)"
|
||||
}
|
||||
git fetch --no-tags --depth=50 origin "+refs/heads/main:refs/remotes/origin/main"
|
||||
}
|
||||
|
||||
- name: Setup pnpm and dependencies
|
||||
@@ -535,10 +513,7 @@ jobs:
|
||||
set -euo pipefail
|
||||
|
||||
if git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
|
||||
timeout --signal=TERM --kill-after=10s 30s git \
|
||||
-c protocol.version=2 \
|
||||
fetch --no-tags --prune --no-recurse-submodules --depth=50 origin \
|
||||
"+refs/heads/main:refs/remotes/origin/main"
|
||||
git fetch --no-tags --depth=50 origin "+refs/heads/main:refs/remotes/origin/main"
|
||||
fi
|
||||
|
||||
node_bin="$(dirname "$(node -p 'process.execPath')")"
|
||||
|
||||
@@ -1932,7 +1932,7 @@ jobs:
|
||||
- suite_id: native-live-src-gateway-profiles-anthropic-opus
|
||||
suite_group: native-live-src-gateway-profiles-anthropic
|
||||
label: Native live gateway profiles Anthropic Opus
|
||||
command: OPENCLAW_LIVE_GATEWAY_THINKING=low OPENCLAW_LIVE_GATEWAY_PROVIDERS=anthropic OPENCLAW_LIVE_GATEWAY_MODELS=anthropic/claude-opus-4-8 node .release-harness/scripts/test-live-shard.mjs native-live-src-gateway-profiles
|
||||
command: OPENCLAW_LIVE_GATEWAY_THINKING=low OPENCLAW_LIVE_GATEWAY_PROVIDERS=anthropic OPENCLAW_LIVE_GATEWAY_MODELS=anthropic/claude-opus-4-7 node .release-harness/scripts/test-live-shard.mjs native-live-src-gateway-profiles
|
||||
timeout_minutes: 30
|
||||
profile_env_only: false
|
||||
advisory: true
|
||||
@@ -1947,19 +1947,19 @@ jobs:
|
||||
profiles: full
|
||||
- suite_id: native-live-src-gateway-profiles-google
|
||||
label: Native live gateway profiles Google
|
||||
command: OPENCLAW_LIVE_GATEWAY_PROVIDERS=google OPENCLAW_LIVE_GATEWAY_MODELS=google/gemini-3.1-pro-preview node .release-harness/scripts/test-live-shard.mjs native-live-src-gateway-profiles
|
||||
command: OPENCLAW_LIVE_GATEWAY_PROVIDERS=google OPENCLAW_LIVE_GATEWAY_MODELS=google/gemini-3.1-pro-preview,google/gemini-3-flash-preview node .release-harness/scripts/test-live-shard.mjs native-live-src-gateway-profiles
|
||||
timeout_minutes: 60
|
||||
profile_env_only: false
|
||||
profiles: stable full
|
||||
- suite_id: native-live-src-gateway-profiles-minimax
|
||||
label: Native live gateway profiles MiniMax
|
||||
command: OPENCLAW_LIVE_GATEWAY_PROVIDERS=minimax,minimax-portal OPENCLAW_LIVE_GATEWAY_MODELS=minimax/MiniMax-M2.7,minimax-portal/MiniMax-M2.7 OPENCLAW_LIVE_GATEWAY_MAX_MODELS=2 node .release-harness/scripts/test-live-shard.mjs native-live-src-gateway-profiles
|
||||
command: OPENCLAW_LIVE_GATEWAY_PROVIDERS=minimax,minimax-portal OPENCLAW_LIVE_GATEWAY_MAX_MODELS=2 node .release-harness/scripts/test-live-shard.mjs native-live-src-gateway-profiles
|
||||
timeout_minutes: 60
|
||||
profile_env_only: false
|
||||
profiles: stable full
|
||||
- suite_id: native-live-src-gateway-profiles-openai
|
||||
label: Native live gateway profiles OpenAI
|
||||
command: OPENCLAW_LIVE_GATEWAY_THINKING=off OPENCLAW_LIVE_GATEWAY_PROVIDERS=openai OPENCLAW_LIVE_GATEWAY_MODELS=openai/gpt-5.5 OPENCLAW_LIVE_GATEWAY_STEP_TIMEOUT_MS=180000 OPENCLAW_LIVE_GATEWAY_MODEL_TIMEOUT_MS=600000 node .release-harness/scripts/test-live-shard.mjs native-live-src-gateway-profiles
|
||||
command: OPENCLAW_LIVE_GATEWAY_PROVIDERS=openai OPENCLAW_LIVE_GATEWAY_MODELS=openai/gpt-5.5 OPENCLAW_LIVE_GATEWAY_STEP_TIMEOUT_MS=180000 OPENCLAW_LIVE_GATEWAY_MODEL_TIMEOUT_MS=600000 node .release-harness/scripts/test-live-shard.mjs native-live-src-gateway-profiles
|
||||
timeout_minutes: 60
|
||||
profile_env_only: false
|
||||
profiles: beta minimum stable full
|
||||
@@ -2234,7 +2234,7 @@ jobs:
|
||||
include:
|
||||
- suite_id: live-gateway-docker
|
||||
label: Docker live gateway OpenAI
|
||||
command: OPENCLAW_LIVE_GATEWAY_THINKING=off OPENCLAW_LIVE_GATEWAY_PROVIDERS=openai OPENCLAW_LIVE_GATEWAY_MODELS=openai/gpt-5.5 OPENCLAW_LIVE_GATEWAY_MAX_MODELS=1 OPENCLAW_LIVE_GATEWAY_STEP_TIMEOUT_MS=90000 OPENCLAW_LIVE_GATEWAY_MODEL_TIMEOUT_MS=600000 OPENCLAW_LIVE_DOCKER_REPO_ROOT="$GITHUB_WORKSPACE" timeout --foreground --kill-after=30s 35m bash .release-harness/scripts/test-live-gateway-models-docker.sh
|
||||
command: OPENCLAW_LIVE_GATEWAY_THINKING=low OPENCLAW_LIVE_GATEWAY_PROVIDERS=openai OPENCLAW_LIVE_GATEWAY_MODELS=openai/gpt-5.5 OPENCLAW_LIVE_GATEWAY_MAX_MODELS=1 OPENCLAW_LIVE_GATEWAY_STEP_TIMEOUT_MS=90000 OPENCLAW_LIVE_GATEWAY_MODEL_TIMEOUT_MS=600000 OPENCLAW_LIVE_DOCKER_REPO_ROOT="$GITHUB_WORKSPACE" timeout --foreground --kill-after=30s 35m bash .release-harness/scripts/test-live-gateway-models-docker.sh
|
||||
timeout_minutes: 40
|
||||
profile_env_only: false
|
||||
profiles: beta minimum stable full
|
||||
@@ -2246,13 +2246,13 @@ jobs:
|
||||
profiles: stable full
|
||||
- suite_id: live-gateway-google-docker
|
||||
label: Docker live gateway Google
|
||||
command: OPENCLAW_LIVE_GATEWAY_PROVIDERS=google OPENCLAW_LIVE_GATEWAY_MODELS=google/gemini-3.1-pro-preview OPENCLAW_LIVE_GATEWAY_MAX_MODELS=1 OPENCLAW_LIVE_GATEWAY_STEP_TIMEOUT_MS=90000 OPENCLAW_LIVE_GATEWAY_MODEL_TIMEOUT_MS=180000 OPENCLAW_LIVE_DOCKER_REPO_ROOT="$GITHUB_WORKSPACE" timeout --foreground --kill-after=30s 35m bash .release-harness/scripts/test-live-gateway-models-docker.sh
|
||||
command: OPENCLAW_LIVE_GATEWAY_PROVIDERS=google OPENCLAW_LIVE_GATEWAY_MODELS=google/gemini-3.1-pro-preview,google/gemini-3-flash-preview OPENCLAW_LIVE_GATEWAY_MAX_MODELS=2 OPENCLAW_LIVE_GATEWAY_STEP_TIMEOUT_MS=90000 OPENCLAW_LIVE_GATEWAY_MODEL_TIMEOUT_MS=180000 OPENCLAW_LIVE_DOCKER_REPO_ROOT="$GITHUB_WORKSPACE" timeout --foreground --kill-after=30s 35m bash .release-harness/scripts/test-live-gateway-models-docker.sh
|
||||
timeout_minutes: 40
|
||||
profile_env_only: false
|
||||
profiles: stable full
|
||||
- suite_id: live-gateway-minimax-docker
|
||||
label: Docker live gateway MiniMax
|
||||
command: OPENCLAW_LIVE_GATEWAY_PROVIDERS=minimax,minimax-portal OPENCLAW_LIVE_GATEWAY_MODELS=minimax/MiniMax-M2.7,minimax-portal/MiniMax-M2.7 OPENCLAW_LIVE_GATEWAY_MAX_MODELS=1 OPENCLAW_LIVE_GATEWAY_STEP_TIMEOUT_MS=90000 OPENCLAW_LIVE_GATEWAY_MODEL_TIMEOUT_MS=180000 OPENCLAW_LIVE_DOCKER_REPO_ROOT="$GITHUB_WORKSPACE" timeout --foreground --kill-after=30s 35m bash .release-harness/scripts/test-live-gateway-models-docker.sh
|
||||
command: OPENCLAW_LIVE_GATEWAY_PROVIDERS=minimax,minimax-portal OPENCLAW_LIVE_GATEWAY_MAX_MODELS=1 OPENCLAW_LIVE_GATEWAY_STEP_TIMEOUT_MS=90000 OPENCLAW_LIVE_GATEWAY_MODEL_TIMEOUT_MS=180000 OPENCLAW_LIVE_DOCKER_REPO_ROOT="$GITHUB_WORKSPACE" timeout --foreground --kill-after=30s 35m bash .release-harness/scripts/test-live-gateway-models-docker.sh
|
||||
timeout_minutes: 40
|
||||
profile_env_only: false
|
||||
profiles: stable full
|
||||
|
||||
@@ -813,7 +813,7 @@ jobs:
|
||||
alt_model="openai/gpt-5.5-alt"
|
||||
;;
|
||||
baseline)
|
||||
model="anthropic/claude-opus-4-8"
|
||||
model="anthropic/claude-opus-4-7"
|
||||
alt_model="anthropic/claude-sonnet-4-6"
|
||||
;;
|
||||
*)
|
||||
@@ -885,7 +885,7 @@ jobs:
|
||||
--candidate-summary .artifacts/qa-e2e/openai-candidate/qa-suite-summary.json \
|
||||
--baseline-summary .artifacts/qa-e2e/anthropic-baseline/qa-suite-summary.json \
|
||||
--candidate-label "${OPENCLAW_CI_OPENAI_MODEL}" \
|
||||
--baseline-label anthropic/claude-opus-4-8 \
|
||||
--baseline-label anthropic/claude-opus-4-7 \
|
||||
--output-dir .artifacts/qa-e2e/parity
|
||||
|
||||
- name: Upload parity artifacts
|
||||
|
||||
@@ -122,10 +122,6 @@ jobs:
|
||||
echo "publish_openclaw_npm=true requires dispatching this workflow from main, release/YYYY.M.D, or a Tideclaw alpha branch for alpha prereleases." >&2
|
||||
exit 1
|
||||
fi
|
||||
if [[ "${PUBLISH_OPENCLAW_NPM}" == "true" && "${PLUGIN_PUBLISH_SCOPE}" != "all-publishable" ]]; then
|
||||
echo "publish_openclaw_npm=true requires plugin_publish_scope=all-publishable so every publishable official plugin is released with OpenClaw." >&2
|
||||
exit 1
|
||||
fi
|
||||
if [[ "${PLUGIN_PUBLISH_SCOPE}" == "selected" && -z "${PLUGINS}" ]]; then
|
||||
echo "plugin_publish_scope=selected requires plugins." >&2
|
||||
exit 1
|
||||
|
||||
8
.github/workflows/plugin-clawhub-release.yml
vendored
8
.github/workflows/plugin-clawhub-release.yml
vendored
@@ -431,8 +431,7 @@ jobs:
|
||||
EOF
|
||||
echo "CLAWHUB_CONFIG_PATH=${RUNNER_TEMP}/clawhub-config.json" >> "$GITHUB_ENV"
|
||||
|
||||
- name: Check ClawHub package version
|
||||
id: clawhub_package_version
|
||||
- name: Ensure version is not already published
|
||||
env:
|
||||
PACKAGE_NAME: ${{ matrix.plugin.packageName }}
|
||||
PACKAGE_VERSION: ${{ matrix.plugin.version }}
|
||||
@@ -457,17 +456,14 @@ jobs:
|
||||
done
|
||||
if [[ "${status}" =~ ^2 ]]; then
|
||||
echo "${PACKAGE_NAME}@${PACKAGE_VERSION} is already published on ClawHub."
|
||||
echo "already_published=true" >> "$GITHUB_OUTPUT"
|
||||
exit 0
|
||||
exit 1
|
||||
fi
|
||||
if [[ "${status}" != "404" ]]; then
|
||||
echo "Unexpected ClawHub response (${status}) for ${PACKAGE_NAME}@${PACKAGE_VERSION}."
|
||||
exit 1
|
||||
fi
|
||||
echo "already_published=false" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Publish
|
||||
if: steps.clawhub_package_version.outputs.already_published != 'true'
|
||||
env:
|
||||
CLAWHUB_REGISTRY: ${{ env.CLAWHUB_REGISTRY }}
|
||||
SOURCE_REPO: ${{ github.repository }}
|
||||
|
||||
8
.github/workflows/plugin-npm-release.yml
vendored
8
.github/workflows/plugin-npm-release.yml
vendored
@@ -263,8 +263,7 @@ jobs:
|
||||
node-version: ${{ env.NODE_VERSION }}
|
||||
install-bun: "false"
|
||||
|
||||
- name: Check npm package version
|
||||
id: npm_package_version
|
||||
- name: Ensure version is not already published
|
||||
env:
|
||||
PACKAGE_NAME: ${{ matrix.plugin.packageName }}
|
||||
PACKAGE_VERSION: ${{ matrix.plugin.version }}
|
||||
@@ -272,13 +271,10 @@ jobs:
|
||||
set -euo pipefail
|
||||
if npm view "${PACKAGE_NAME}@${PACKAGE_VERSION}" version >/dev/null 2>&1; then
|
||||
echo "${PACKAGE_NAME}@${PACKAGE_VERSION} is already published on npm."
|
||||
echo "already_published=true" >> "$GITHUB_OUTPUT"
|
||||
else
|
||||
echo "already_published=false" >> "$GITHUB_OUTPUT"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Publish
|
||||
if: steps.npm_package_version.outputs.already_published != 'true'
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
|
||||
@@ -199,13 +199,13 @@ jobs:
|
||||
--alt-model openai/gpt-5.5-alt \
|
||||
--output-dir .artifacts/qa-e2e/openai-candidate
|
||||
|
||||
- name: Run Opus 4.8 lane
|
||||
- name: Run Opus 4.7 lane
|
||||
run: |
|
||||
pnpm openclaw qa suite \
|
||||
--provider-mode mock-openai \
|
||||
--parity-pack agentic \
|
||||
--concurrency "${QA_PARITY_CONCURRENCY}" \
|
||||
--model anthropic/claude-opus-4-8 \
|
||||
--model anthropic/claude-opus-4-7 \
|
||||
--alt-model anthropic/claude-sonnet-4-6 \
|
||||
--output-dir .artifacts/qa-e2e/anthropic-baseline
|
||||
|
||||
@@ -216,7 +216,7 @@ jobs:
|
||||
--candidate-summary .artifacts/qa-e2e/openai-candidate/qa-suite-summary.json \
|
||||
--baseline-summary .artifacts/qa-e2e/anthropic-baseline/qa-suite-summary.json \
|
||||
--candidate-label "${OPENCLAW_CI_OPENAI_MODEL}" \
|
||||
--baseline-label anthropic/claude-opus-4-8 \
|
||||
--baseline-label anthropic/claude-opus-4-7 \
|
||||
--output-dir .artifacts/qa-e2e/parity
|
||||
|
||||
- name: Upload parity artifacts
|
||||
|
||||
15
.github/workflows/workflow-sanity.yml
vendored
15
.github/workflows/workflow-sanity.yml
vendored
@@ -34,10 +34,7 @@ jobs:
|
||||
git init "$GITHUB_WORKSPACE"
|
||||
git -C "$GITHUB_WORKSPACE" config gc.auto 0
|
||||
git -C "$GITHUB_WORKSPACE" remote add origin "https://github.com/${CHECKOUT_REPO}.git"
|
||||
timeout --signal=TERM --kill-after=10s 30s git -C "$GITHUB_WORKSPACE" \
|
||||
-c protocol.version=2 \
|
||||
fetch --no-tags --prune --no-recurse-submodules --depth=1 origin \
|
||||
"+${CHECKOUT_SHA}:refs/remotes/origin/checkout"
|
||||
git -C "$GITHUB_WORKSPACE" fetch --no-tags --depth=1 origin "+${CHECKOUT_SHA}:refs/remotes/origin/checkout"
|
||||
git -C "$GITHUB_WORKSPACE" checkout --detach refs/remotes/origin/checkout
|
||||
|
||||
- name: Fail on tabs in workflow files
|
||||
@@ -78,10 +75,7 @@ jobs:
|
||||
git init "$GITHUB_WORKSPACE"
|
||||
git -C "$GITHUB_WORKSPACE" config gc.auto 0
|
||||
git -C "$GITHUB_WORKSPACE" remote add origin "https://github.com/${CHECKOUT_REPO}.git"
|
||||
timeout --signal=TERM --kill-after=10s 30s git -C "$GITHUB_WORKSPACE" \
|
||||
-c protocol.version=2 \
|
||||
fetch --no-tags --prune --no-recurse-submodules --depth=1 origin \
|
||||
"+${CHECKOUT_SHA}:refs/remotes/origin/checkout"
|
||||
git -C "$GITHUB_WORKSPACE" fetch --no-tags --depth=1 origin "+${CHECKOUT_SHA}:refs/remotes/origin/checkout"
|
||||
git -C "$GITHUB_WORKSPACE" checkout --detach refs/remotes/origin/checkout
|
||||
|
||||
- name: Install actionlint
|
||||
@@ -122,10 +116,7 @@ jobs:
|
||||
git init "$GITHUB_WORKSPACE"
|
||||
git -C "$GITHUB_WORKSPACE" config gc.auto 0
|
||||
git -C "$GITHUB_WORKSPACE" remote add origin "https://github.com/${CHECKOUT_REPO}.git"
|
||||
timeout --signal=TERM --kill-after=10s 30s git -C "$GITHUB_WORKSPACE" \
|
||||
-c protocol.version=2 \
|
||||
fetch --no-tags --prune --no-recurse-submodules --depth=1 origin \
|
||||
"+${CHECKOUT_SHA}:refs/remotes/origin/checkout"
|
||||
git -C "$GITHUB_WORKSPACE" fetch --no-tags --depth=1 origin "+${CHECKOUT_SHA}:refs/remotes/origin/checkout"
|
||||
git -C "$GITHUB_WORKSPACE" checkout --detach refs/remotes/origin/checkout
|
||||
|
||||
- name: Setup Node environment
|
||||
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -178,7 +178,6 @@ mantis/
|
||||
/local/
|
||||
/client_secret_*.json
|
||||
package-lock.json
|
||||
!src/commands/copilot-sdk-install-manifest/package-lock.json
|
||||
.claude/
|
||||
.agent/
|
||||
skills-lock.json
|
||||
|
||||
@@ -186,7 +186,7 @@
|
||||
"node_modules/",
|
||||
"patches/",
|
||||
"pnpm-lock.yaml",
|
||||
"skills/**",
|
||||
"skills/",
|
||||
"src/auto-reply/reply/export-html/template.js",
|
||||
"src/canvas-host/a2ui/a2ui.bundle.js",
|
||||
"vendor/",
|
||||
|
||||
@@ -35,9 +35,9 @@ Skills own workflows; root owns hard policy and routing.
|
||||
|
||||
## Map
|
||||
|
||||
- Core TS: `src/`, `ui/`, `packages/`; plugins: `extensions/`; SDK: `src/plugin-sdk/*`; channels: `src/channels/*`; loader: `src/plugins/*`; protocol: `packages/gateway-protocol/*`; docs/apps: `docs/`, `apps/`.
|
||||
- Core TS: `src/`, `ui/`, `packages/`; plugins: `extensions/`; SDK: `src/plugin-sdk/*`; channels: `src/channels/*`; loader: `src/plugins/*`; protocol: `src/gateway/protocol/*`; docs/apps: `docs/`, `apps/`.
|
||||
- Installers: sibling `../openclaw.ai`.
|
||||
- Scoped guides: `extensions/`, `src/{plugin-sdk,channels,plugins,gateway,agents}/`, `packages/`, `test/helpers*/`, `docs/`, `ui/`, `scripts/`.
|
||||
- Scoped guides: `extensions/`, `src/{plugin-sdk,channels,plugins,gateway,gateway/protocol,agents}/`, `test/helpers*/`, `docs/`, `ui/`, `scripts/`.
|
||||
|
||||
## Docs
|
||||
|
||||
|
||||
@@ -2,13 +2,6 @@
|
||||
|
||||
Docs: https://docs.openclaw.ai
|
||||
|
||||
## Unreleased
|
||||
|
||||
### Fixes
|
||||
|
||||
- Providers: bound generated media downloads from OpenAI, Runway, xAI, MiniMax, BytePlus, DashScope-compatible, FAL, OpenRouter, Google, Vydra, and Comfy providers.
|
||||
- Cron: retry recurring jobs after transient model rate limits before waiting for the next scheduled slot.
|
||||
|
||||
## 2026.5.28
|
||||
|
||||
### Highlights
|
||||
|
||||
@@ -5894,8 +5894,6 @@ public struct ExecApprovalRequestParams: Codable, Sendable {
|
||||
public let turnsourceto: AnyCodable?
|
||||
public let turnsourceaccountid: AnyCodable?
|
||||
public let turnsourcethreadid: AnyCodable?
|
||||
public let requiredeliveryroute: Bool?
|
||||
public let suppressdelivery: Bool?
|
||||
public let timeoutms: Int?
|
||||
public let twophase: Bool?
|
||||
|
||||
@@ -5919,8 +5917,6 @@ public struct ExecApprovalRequestParams: Codable, Sendable {
|
||||
turnsourceto: AnyCodable?,
|
||||
turnsourceaccountid: AnyCodable?,
|
||||
turnsourcethreadid: AnyCodable?,
|
||||
requiredeliveryroute: Bool? = nil,
|
||||
suppressdelivery: Bool? = nil,
|
||||
timeoutms: Int?,
|
||||
twophase: Bool?)
|
||||
{
|
||||
@@ -5943,8 +5939,6 @@ public struct ExecApprovalRequestParams: Codable, Sendable {
|
||||
self.turnsourceto = turnsourceto
|
||||
self.turnsourceaccountid = turnsourceaccountid
|
||||
self.turnsourcethreadid = turnsourcethreadid
|
||||
self.requiredeliveryroute = requiredeliveryroute
|
||||
self.suppressdelivery = suppressdelivery
|
||||
self.timeoutms = timeoutms
|
||||
self.twophase = twophase
|
||||
}
|
||||
@@ -5969,8 +5963,6 @@ public struct ExecApprovalRequestParams: Codable, Sendable {
|
||||
case turnsourceto = "turnSourceTo"
|
||||
case turnsourceaccountid = "turnSourceAccountId"
|
||||
case turnsourcethreadid = "turnSourceThreadId"
|
||||
case requiredeliveryroute = "requireDeliveryRoute"
|
||||
case suppressdelivery = "suppressDelivery"
|
||||
case timeoutms = "timeoutMs"
|
||||
case twophase = "twoPhase"
|
||||
}
|
||||
|
||||
1
changelog/fragments/pr-signal-container-mode.md
Normal file
1
changelog/fragments/pr-signal-container-mode.md
Normal file
@@ -0,0 +1 @@
|
||||
- Signal/container mode: add REST API support for bbernhard/signal-cli-rest-api containerized deployments via a unified adapter layer, with automatic mode detection and `channels.signal.apiMode` config. (#10240) Thanks @Hua688.
|
||||
@@ -27,7 +27,7 @@ const bundledPluginEntries = [
|
||||
"setup-entry.ts!",
|
||||
"{api,contract-api,helper-api,runtime-api,light-runtime-api,update-offset-runtime-api,channel-plugin-api,provider-plugin-api,setup-api}.ts!",
|
||||
"subagent-hooks-api.ts!",
|
||||
"src/{api,runtime-api,light-runtime-api,update-offset-runtime-api,channel-plugin-api,provider-plugin-api,doctor-contract,setup-surface,mcp-serve}.ts!",
|
||||
"src/{api,runtime-api,light-runtime-api,update-offset-runtime-api,channel-plugin-api,provider-plugin-api,doctor-contract,setup-surface}.ts!",
|
||||
"src/subagent-hooks-api.ts!",
|
||||
] as const;
|
||||
|
||||
@@ -168,23 +168,6 @@ const config = {
|
||||
entry: ["src/index.ts!", "src/*.ts!", "src/harness/**/*.ts!"],
|
||||
project: ["src/**/*.ts!"],
|
||||
},
|
||||
"packages/gateway-client": {
|
||||
entry: ["src/index.ts!"],
|
||||
project: ["src/**/*.ts!"],
|
||||
},
|
||||
"packages/gateway-protocol": {
|
||||
entry: ["src/index.ts!", "src/schema.ts!"],
|
||||
project: ["src/**/*.ts!"],
|
||||
},
|
||||
"packages/net-policy": {
|
||||
entry: ["src/index.ts!", "src/ip.ts!"],
|
||||
project: ["src/**/*.ts!"],
|
||||
},
|
||||
"packages/speech-core": {
|
||||
entry: ["api.ts!", "runtime-api.ts!", "speaker.ts!", "voice-models.ts!"],
|
||||
project: ["**/*.ts!"],
|
||||
ignoreDependencies: ["openclaw"],
|
||||
},
|
||||
"packages/*": {
|
||||
entry: ["index.js!", "scripts/postinstall.js!"],
|
||||
project: ["index.js!", "scripts/**/*.js!"],
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
c80dea63b0a3786c8999d06aae62c110786f440b4d6748f9838577aaa2816971 config-baseline.json
|
||||
948323a1507817b6580ed976f9f9449239008f40283cc7e6005148ecf0ca4582 config-baseline.core.json
|
||||
f833ffca6bd88162f062bbea4f0eede783373f46674ebbfc3a390c80353930a2 config-baseline.channel.json
|
||||
bc38b58b67132401a030b3b3a77efdb6c88f207ea1fab9abcb4599e1f9552dda config-baseline.plugin.json
|
||||
c61b32fda64ee6cd4d4aa5ed6950c4c681a585d49bf5c127b92e562608a0a303 config-baseline.json
|
||||
ee4c0f0fb15cda02268f2e83d0c5e1c8d0ec0a2c1b2fdb89cdfce308dadb2b8b config-baseline.core.json
|
||||
ccb0c68e959854b9d54d66b8c78bfba5fe6f8a37e669e2e7e511b02c4c977122 config-baseline.channel.json
|
||||
1b763a5524aca2d7ecf1eea38f845ad1ffed5c1b37e85e62f6a7902a3ee0f920 config-baseline.plugin.json
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
59de21361cab0622926ad313caf3f8dc43c28d420a82ba060680ecc30c472453 plugin-sdk-api-baseline.json
|
||||
05adee9037669db4e834d1a0ca9705d5d94df770083862ab149d2f3e559010d2 plugin-sdk-api-baseline.jsonl
|
||||
91cb45dc1e8aaa3dac9a2c1d3c98c8ff22112e41c305de17f30d0d4420635ee4 plugin-sdk-api-baseline.json
|
||||
3aa4802ffcb68c4f15e367030994eae10e73b55b5f14c8e23d4e9467fae325fe plugin-sdk-api-baseline.jsonl
|
||||
|
||||
@@ -175,26 +175,6 @@
|
||||
"source": "Agent harness plugins",
|
||||
"target": "Agent harness plugins"
|
||||
},
|
||||
{
|
||||
"source": "Agent harness plugins (SDK reference)",
|
||||
"target": "Agent harness plugins (SDK reference)"
|
||||
},
|
||||
{
|
||||
"source": "Copilot SDK harness",
|
||||
"target": "Copilot SDK harness"
|
||||
},
|
||||
{
|
||||
"source": "Copilot plugin",
|
||||
"target": "Copilot plugin"
|
||||
},
|
||||
{
|
||||
"source": "GitHub Copilot agent runtime",
|
||||
"target": "GitHub Copilot agent runtime"
|
||||
},
|
||||
{
|
||||
"source": "copilot",
|
||||
"target": "copilot"
|
||||
},
|
||||
{
|
||||
"source": "Agent loop",
|
||||
"target": "Agent loop"
|
||||
@@ -1103,18 +1083,6 @@
|
||||
"source": "Plugin Manifest",
|
||||
"target": "Plugin Manifest"
|
||||
},
|
||||
{
|
||||
"source": "Workboard plugin",
|
||||
"target": "Workboard 插件"
|
||||
},
|
||||
{
|
||||
"source": "workboard",
|
||||
"target": "workboard"
|
||||
},
|
||||
{
|
||||
"source": "Control UI",
|
||||
"target": "Control UI"
|
||||
},
|
||||
{
|
||||
"source": "Z.AI (GLM)",
|
||||
"target": "Z.AI (GLM)"
|
||||
|
||||
@@ -15,8 +15,9 @@ Cron is the Gateway's built-in scheduler. It persists jobs, wakes the agent at t
|
||||
<Steps>
|
||||
<Step title="Add a one-shot reminder">
|
||||
```bash
|
||||
openclaw cron create "2026-02-01T16:00:00Z" \
|
||||
openclaw cron add \
|
||||
--name "Reminder" \
|
||||
--at "2026-02-01T16:00:00Z" \
|
||||
--session main \
|
||||
--system-event "Reminder: check the cron docs draft" \
|
||||
--wake now \
|
||||
@@ -42,7 +43,6 @@ Cron is the Gateway's built-in scheduler. It persists jobs, wakes the agent at t
|
||||
- Cron runs **inside the Gateway** process (not inside the model).
|
||||
- Job definitions persist at `~/.openclaw/cron/jobs.json` so restarts do not lose schedules.
|
||||
- Runtime execution state persists next to it in `~/.openclaw/cron/jobs-state.json`. If you track cron definitions in git, track `jobs.json` and gitignore `jobs-state.json`.
|
||||
- If `jobs.json` contains malformed rows, the Gateway keeps valid jobs running, removes the malformed rows from the active store, and saves the raw rows beside it in `jobs-quarantine.json` for later repair or review.
|
||||
- After the split, older OpenClaw versions can read `jobs.json` but may treat jobs as fresh because runtime fields now live in `jobs-state.json`.
|
||||
- When `jobs.json` is edited while the Gateway is running or stopped, OpenClaw compares the changed schedule fields with pending runtime slot metadata and clears stale `nextRunAtMs` values. Pure formatting or key-order-only rewrites preserve the pending slot.
|
||||
- All cron executions create [background task](/automation/tasks) records.
|
||||
@@ -146,8 +146,6 @@ This fires ~5–6 times per month instead of 0–1 times per month. OpenClaw use
|
||||
|
||||
Cron jobs can also carry payload-level `fallbacks`. When present, that list replaces the configured fallback chain for the job. Use `fallbacks: []` in the job payload/API when you want a strict cron run that tries only the selected model. If a job has `--model` but neither payload nor configured fallbacks, OpenClaw passes an explicit empty fallback override so the agent primary is not appended as a hidden extra retry target.
|
||||
|
||||
Local-provider preflight checks walk configured fallbacks before marking a cron run `skipped`; `fallbacks: []` keeps that preflight path strict.
|
||||
|
||||
Model-selection precedence for isolated jobs is:
|
||||
|
||||
1. Gmail hook model override (when the run came from Gmail and that override is allowed)
|
||||
@@ -217,11 +215,12 @@ Failure notifications follow a separate destination path:
|
||||
</Tab>
|
||||
<Tab title="Recurring isolated job">
|
||||
```bash
|
||||
openclaw cron create "0 7 * * *" \
|
||||
"Summarize overnight updates." \
|
||||
openclaw cron add \
|
||||
--name "Morning brief" \
|
||||
--cron "0 7 * * *" \
|
||||
--tz "America/Los_Angeles" \
|
||||
--session isolated \
|
||||
--message "Summarize overnight updates." \
|
||||
--announce \
|
||||
--channel slack \
|
||||
--to "channel:C1234567890"
|
||||
@@ -240,14 +239,6 @@ Failure notifications follow a separate destination path:
|
||||
--announce
|
||||
```
|
||||
</Tab>
|
||||
<Tab title="Webhook output">
|
||||
```bash
|
||||
openclaw cron create "0 18 * * 1-5" \
|
||||
"Summarize today's deploys as JSON." \
|
||||
--name "Deploy digest" \
|
||||
--webhook "https://example.invalid/openclaw/cron"
|
||||
```
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
## Webhooks
|
||||
@@ -420,14 +411,12 @@ openclaw cron runs --id <jobId> --run-id <runId>
|
||||
openclaw cron remove <jobId>
|
||||
|
||||
# Agent selection (multi-agent setups)
|
||||
openclaw cron create "0 6 * * *" "Check ops queue" --name "Ops sweep" --session isolated --agent ops
|
||||
openclaw cron add --name "Ops sweep" --cron "0 6 * * *" --session isolated --message "Check ops queue" --agent ops
|
||||
openclaw cron edit <jobId> --clear-agent
|
||||
```
|
||||
|
||||
`openclaw cron run <jobId>` returns after enqueueing the manual run. Use `--wait` for shutdown hooks, maintenance scripts, or other automation that must block until the queued run finishes. Wait mode polls the exact returned `runId`; it exits `0` for status `ok` and non-zero for `error`, `skipped`, or a wait timeout.
|
||||
|
||||
`openclaw cron create` is an alias for `openclaw cron add`, and new jobs can use a positional schedule (`"0 9 * * 1"`, `"every 1h"`, `"20m"`, or an ISO timestamp) followed by a positional agent prompt. Use `--webhook <url>` on `cron add|create` or `cron edit` to POST the finished run payload to an HTTP endpoint. Webhook delivery cannot be combined with chat delivery flags such as `--announce`, `--channel`, `--to`, `--thread-id`, or `--account`.
|
||||
|
||||
<Note>
|
||||
Model override note:
|
||||
|
||||
|
||||
@@ -696,7 +696,6 @@ Default slash command settings:
|
||||
maxLines: 8,
|
||||
maxLineChars: 120,
|
||||
toolProgress: true,
|
||||
commentary: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -709,7 +708,6 @@ Default slash command settings:
|
||||
- Media, error, and explicit-reply finals cancel pending preview edits.
|
||||
- `streaming.preview.toolProgress` (default `true`) controls whether tool/progress updates reuse the preview message.
|
||||
- Tool/progress rows render as compact emoji + title + detail when available, for example `🛠️ Bash: run tests` or `🔎 Web Search: for "query"`.
|
||||
- `streaming.progress.commentary` (default `false`) opts into assistant commentary/preamble text in the temporary progress draft. Commentary is cleaned before display, stays transient, and does not change final answer delivery.
|
||||
- `streaming.progress.maxLineChars` controls the per-line progress preview budget. Prose is shortened on word boundaries; command and path details keep useful suffixes.
|
||||
- `streaming.preview.commandText` / `streaming.progress.commandText` controls command/exec detail in compact progress lines: `raw` (default) or `status` (tool label only).
|
||||
|
||||
@@ -1217,7 +1215,7 @@ Auto-join example:
|
||||
realtime: {
|
||||
provider: "openai",
|
||||
model: "gpt-realtime-2",
|
||||
speakerVoice: "cedar",
|
||||
voice: "cedar",
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -1227,20 +1225,20 @@ Auto-join example:
|
||||
|
||||
Notes:
|
||||
|
||||
- `voice.tts` overrides `messages.tts` for `stt-tts` voice playback only. Realtime modes use `voice.realtime.speakerVoice`.
|
||||
- `voice.tts` overrides `messages.tts` for `stt-tts` voice playback only. Realtime modes use `voice.realtime.voice`.
|
||||
- `voice.mode` controls the conversation path. The default is `agent-proxy`: a realtime voice front end handles turn timing, interruption, and playback, delegates substantive work to the routed OpenClaw agent through `openclaw_agent_consult`, and treats the result like a typed Discord prompt from that speaker. `stt-tts` keeps the older batch STT plus TTS flow. `bidi` lets the realtime model converse directly while exposing `openclaw_agent_consult` for the OpenClaw brain.
|
||||
- `voice.agentSession` controls which OpenClaw conversation receives voice turns. Leave it unset for the voice channel's own session, or set `{ mode: "target", target: "channel:<text-channel-id>" }` to make the voice channel act as the microphone/speaker extension of an existing Discord text channel session such as `#maintainers`.
|
||||
- `voice.model` overrides the OpenClaw agent brain for Discord voice responses and realtime consults. Leave it unset to inherit the routed agent model. It is separate from `voice.realtime.model`.
|
||||
- `voice.followUsers` lets the bot join, move, and leave Discord voice with selected users. See [Follow users in voice](#follow-users-in-voice) for behavior rules and examples.
|
||||
- `agent-proxy` routes speech through `discord-voice`, which preserves normal owner/tool authorization for the speaker and target session but hides the agent `tts` tool because Discord voice owns playback. By default, `agent-proxy` gives the consult full owner-equivalent tool access for owner speakers (`voice.realtime.toolPolicy: "owner"`) and strongly prefers consulting the OpenClaw agent before substantive answers (`voice.realtime.consultPolicy: "always"`). In that default `always` mode, the realtime layer does not auto-speak filler before the consult answer; it captures and transcribes speech, then speaks the routed OpenClaw answer. If multiple forced consult answers finish while Discord is still playing the first answer, later exact-speech answers are queued until playback idles instead of replacing speech mid-sentence.
|
||||
- In `stt-tts` mode, STT uses `tools.media.audio`; `voice.model` does not affect transcription.
|
||||
- In realtime modes, `voice.realtime.provider`, `voice.realtime.model`, and `voice.realtime.speakerVoice` configure the realtime audio session. For OpenAI Realtime 2 plus the Codex brain, use `voice.realtime.model: "gpt-realtime-2"` and `voice.model: "openai-codex/gpt-5.5"`.
|
||||
- In realtime modes, `voice.realtime.provider`, `voice.realtime.model`, and `voice.realtime.voice` configure the realtime audio session. For OpenAI Realtime 2 plus the Codex brain, use `voice.realtime.model: "gpt-realtime-2"` and `voice.model: "openai-codex/gpt-5.5"`.
|
||||
- Realtime voice modes include small `IDENTITY.md`, `USER.md`, and `SOUL.md` profile files in the realtime provider instructions by default so fast direct turns keep the same identity, user grounding, and persona as the routed OpenClaw agent. Set `voice.realtime.bootstrapContextFiles` to a subset to customize this, or `[]` to disable it. The supported realtime bootstrap files are limited to those profile files; `AGENTS.md` stays in the normal agent context. The injected profile context does not replace `openclaw_agent_consult` for workspace work, current facts, memory lookup, or tool-backed actions.
|
||||
- In OpenAI `agent-proxy` realtime mode, set `voice.realtime.requireWakeName: true` to keep Discord realtime voice silent until a transcript starts or ends with a wake name. Configured wake names must be one or two words. If `voice.realtime.wakeNames` is unset, OpenClaw uses the routed agent `name` plus `OpenClaw`, falling back to the agent id plus `OpenClaw`. Wake-name gating disables realtime provider auto-response, routes accepted turns through the OpenClaw agent consult path, and gives a short spoken acknowledgement when a leading wake name is recognized from partial transcription before the final transcript arrives.
|
||||
- The OpenAI realtime provider accepts current Realtime 2 event names and legacy Codex-compatible aliases for output audio and transcript events, so compatible provider snapshots can drift without dropping assistant audio.
|
||||
- `voice.realtime.bargeIn` controls whether Discord speaker-start events interrupt active realtime playback. If unset, it follows the realtime provider's input-audio interruption setting.
|
||||
- `voice.realtime.minBargeInAudioEndMs` controls the minimum assistant playback duration before an OpenAI realtime barge-in truncates audio. Default: `250`. Set `0` for immediate interruption in low-echo rooms, or raise it for echo-heavy speaker setups.
|
||||
- For an OpenAI voice on Discord playback, set `voice.tts.provider: "openai"` and choose a Text-to-speech voice under `voice.tts.providers.openai.speakerVoice`. `cedar` is a good masculine-sounding choice on the current OpenAI TTS model.
|
||||
- For an OpenAI voice on Discord playback, set `voice.tts.provider: "openai"` and choose a Text-to-speech voice under `voice.tts.openai.voice` or `voice.tts.providers.openai.voice`. `cedar` is a good masculine-sounding choice on the current OpenAI TTS model.
|
||||
- Per-channel Discord `systemPrompt` overrides apply to voice transcript turns for that voice channel.
|
||||
- Voice transcript turns derive owner status from Discord `allowFrom` (or `dm.allowFrom`) for owner-gated commands and channel actions. Agent tool visibility follows the configured tool policy for the routed session.
|
||||
- Discord voice is opt-in for text-only configs; set `channels.discord.voice.enabled=true` (or keep an existing `channels.discord.voice` block) to enable `/vc` commands, the voice runtime, and the `GuildVoiceStates` gateway intent.
|
||||
@@ -1331,7 +1329,7 @@ Default agent-proxy voice-channel session example:
|
||||
realtime: {
|
||||
provider: "openai",
|
||||
model: "gpt-realtime-2",
|
||||
speakerVoice: "cedar",
|
||||
voice: "cedar",
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -1353,11 +1351,9 @@ Legacy STT plus TTS example:
|
||||
model: "openai/gpt-5.4-mini",
|
||||
tts: {
|
||||
provider: "openai",
|
||||
providers: {
|
||||
openai: {
|
||||
model: "gpt-4o-mini-tts",
|
||||
speakerVoice: "cedar",
|
||||
},
|
||||
openai: {
|
||||
model: "gpt-4o-mini-tts",
|
||||
voice: "cedar",
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -1379,7 +1375,7 @@ Realtime bidi example:
|
||||
realtime: {
|
||||
provider: "openai",
|
||||
model: "gpt-realtime-2",
|
||||
speakerVoice: "cedar",
|
||||
voice: "cedar",
|
||||
toolPolicy: "safe-read-only",
|
||||
consultPolicy: "always",
|
||||
},
|
||||
@@ -1406,7 +1402,7 @@ Voice as an extension of an existing Discord channel session:
|
||||
realtime: {
|
||||
provider: "openai",
|
||||
model: "gpt-realtime-2",
|
||||
speakerVoice: "cedar",
|
||||
voice: "cedar",
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -1437,7 +1433,7 @@ Echo-heavy OpenAI Realtime example:
|
||||
realtime: {
|
||||
provider: "openai",
|
||||
model: "gpt-realtime-2",
|
||||
speakerVoice: "cedar",
|
||||
voice: "cedar",
|
||||
bargeIn: true,
|
||||
minBargeInAudioEndMs: 500,
|
||||
consultPolicy: "always",
|
||||
|
||||
@@ -15,7 +15,7 @@ Feishu/Lark is an all-in-one collaboration platform where teams chat, share docu
|
||||
## Quick start
|
||||
|
||||
<Note>
|
||||
Requires OpenClaw 2026.5.29 or above. Run `openclaw --version` to check. Upgrade with `openclaw update`.
|
||||
Requires OpenClaw 2026.4.25 or above. Run `openclaw --version` to check. Upgrade with `openclaw update`.
|
||||
</Note>
|
||||
|
||||
<Steps>
|
||||
|
||||
@@ -411,9 +411,9 @@ curl "https://api.telegram.org/bot<bot_token>/getUpdates"
|
||||
|
||||
Preview streaming is separate from block streaming. When block streaming is explicitly enabled for Telegram, OpenClaw skips the preview stream to avoid double-streaming.
|
||||
|
||||
Reasoning stream behavior:
|
||||
Telegram-only reasoning stream:
|
||||
|
||||
- `/reasoning stream` uses a supported channel's reasoning-preview path; on Telegram, it streams reasoning into the live preview while generating
|
||||
- `/reasoning stream` sends reasoning to the live preview while generating
|
||||
- the reasoning preview is deleted after final delivery; use `/reasoning on` when reasoning should remain visible
|
||||
- final answer is sent without reasoning text
|
||||
|
||||
|
||||
@@ -157,8 +157,8 @@ order and tells you what it chose:
|
||||
|
||||
- existing explicit model, if already configured
|
||||
- `OPENAI_API_KEY` -> `openai/gpt-5.5`
|
||||
- `ANTHROPIC_API_KEY` -> `anthropic/claude-opus-4-8`
|
||||
- Claude Code CLI -> `claude-cli/claude-opus-4-8`
|
||||
- `ANTHROPIC_API_KEY` -> `anthropic/claude-opus-4-7`
|
||||
- Claude Code CLI -> `claude-cli/claude-opus-4-7`
|
||||
- Codex -> `openai/gpt-5.5` through the Codex app-server harness
|
||||
|
||||
If none are available, setup still writes the default workspace and leaves the
|
||||
@@ -173,7 +173,7 @@ planner turn through OpenClaw's normal runtime paths. It first uses the
|
||||
configured OpenClaw model. If no configured model is usable yet, it can fall
|
||||
back to local runtimes already present on the machine:
|
||||
|
||||
- Claude Code CLI: `claude-cli/claude-opus-4-8`
|
||||
- Claude Code CLI: `claude-cli/claude-opus-4-7`
|
||||
- Codex app-server harness: `openai/gpt-5.5`
|
||||
|
||||
The model-assisted planner cannot mutate config directly. It must translate the
|
||||
|
||||
@@ -14,26 +14,6 @@ Manage cron jobs for the Gateway scheduler.
|
||||
Run `openclaw cron --help` for the full command surface. See [Cron jobs](/automation/cron-jobs) for the conceptual guide.
|
||||
</Tip>
|
||||
|
||||
## Create jobs quickly
|
||||
|
||||
`openclaw cron create` is an alias for `openclaw cron add`. For new jobs, put the schedule first and the prompt second:
|
||||
|
||||
```bash
|
||||
openclaw cron create "0 7 * * *" \
|
||||
"Summarize overnight updates." \
|
||||
--name "Morning brief" \
|
||||
--agent ops
|
||||
```
|
||||
|
||||
Use `--webhook <url>` when the job should POST the finished payload instead of delivering to a chat target:
|
||||
|
||||
```bash
|
||||
openclaw cron create "0 18 * * 1-5" \
|
||||
"Summarize today's deploys as JSON." \
|
||||
--name "Deploy digest" \
|
||||
--webhook "https://example.invalid/openclaw/cron"
|
||||
```
|
||||
|
||||
## Sessions
|
||||
|
||||
`--session` accepts `main`, `isolated`, `current`, or `session:<id>`.
|
||||
@@ -70,8 +50,6 @@ Isolated cron chat delivery is shared between the agent and the runner:
|
||||
- `webhook` posts the finished payload to a URL.
|
||||
- `none` disables runner fallback delivery.
|
||||
|
||||
Use `cron add|create --webhook <url>` or `cron edit <job-id> --webhook <url>` to set webhook delivery. Do not combine `--webhook` with chat delivery flags such as `--announce`, `--no-deliver`, `--channel`, `--to`, `--thread-id`, or `--account`.
|
||||
|
||||
`--announce` is runner fallback delivery for the final reply. `--no-deliver` disables that fallback but does not remove the agent's `message` tool when a chat route is available.
|
||||
|
||||
Reminders created from an active chat preserve the live chat delivery target for fallback announce delivery. Internal session keys may be lowercase; do not use them as a source of truth for case-sensitive provider IDs such as Matrix room IDs.
|
||||
@@ -118,7 +96,7 @@ Skipped runs are tracked separately from execution errors. They do not affect re
|
||||
|
||||
For isolated jobs that target a local configured model provider, cron runs a lightweight provider preflight before starting the agent turn. Loopback, private-network, and `.local` `api: "ollama"` providers are probed at `/api/tags`; local OpenAI-compatible providers such as vLLM, SGLang, and LM Studio are probed at `/models`. If the endpoint is unreachable, the run is recorded as `skipped` and retried on a later schedule; matching dead endpoints are cached for 5 minutes to avoid many jobs hammering the same local server.
|
||||
|
||||
Note: cron job definitions live in `jobs.json`, while pending runtime state lives in `jobs-state.json`. If `jobs.json` is edited externally, the Gateway reloads changed schedules and clears stale pending slots; formatting-only rewrites do not clear the pending slot. Malformed job rows are removed from active `jobs.json` at load time after their raw contents are copied to `jobs-quarantine.json`.
|
||||
Note: cron job definitions live in `jobs.json`, while pending runtime state lives in `jobs-state.json`. If `jobs.json` is edited externally, the Gateway reloads changed schedules and clears stale pending slots; formatting-only rewrites do not clear the pending slot.
|
||||
|
||||
### Manual runs
|
||||
|
||||
@@ -155,7 +133,6 @@ Cron `--model` is a **job primary**, not a chat-session `/model` override. That
|
||||
- Per-job payload `fallbacks` replaces the configured fallback list when present.
|
||||
- An empty per-job fallback list (`fallbacks: []` in the job payload/API) makes the cron run strict.
|
||||
- When a job has `--model` but no fallback list is configured, OpenClaw passes an explicit empty fallback override so the agent primary is not appended as a hidden retry target.
|
||||
- Local-provider preflight checks walk configured fallbacks before marking a cron run `skipped`.
|
||||
|
||||
`openclaw doctor` reports jobs that already have `payload.model` set, including provider namespace counts and mismatches against `agents.defaults.model`. Use that check when auth, provider, or billing behavior looks different between live chat and scheduled jobs.
|
||||
|
||||
@@ -242,10 +219,11 @@ openclaw cron edit <job-id> --announce --channel telegram --to "-1001234567890"
|
||||
Create an isolated job with lightweight bootstrap context:
|
||||
|
||||
```bash
|
||||
openclaw cron create "0 7 * * *" \
|
||||
"Summarize overnight updates." \
|
||||
openclaw cron add \
|
||||
--name "Lightweight morning brief" \
|
||||
--cron "0 7 * * *" \
|
||||
--session isolated \
|
||||
--message "Summarize overnight updates." \
|
||||
--light-context \
|
||||
--no-deliver
|
||||
```
|
||||
@@ -292,7 +270,6 @@ Delivery tweaks:
|
||||
|
||||
```bash
|
||||
openclaw cron edit <job-id> --announce --channel slack --to "channel:C1234567890"
|
||||
openclaw cron edit <job-id> --webhook "https://example.invalid/openclaw/cron"
|
||||
openclaw cron edit <job-id> --best-effort-deliver
|
||||
openclaw cron edit <job-id> --no-best-effort-deliver
|
||||
openclaw cron edit <job-id> --no-deliver
|
||||
|
||||
@@ -18,13 +18,12 @@ report drift through `doctor --lint`. The final conformance signal is a clean
|
||||
instead of creating a separate health gate.
|
||||
|
||||
Policy currently manages configured channels, MCP servers, model providers,
|
||||
network SSRF posture, ingress/channel access posture, Gateway exposure posture, agent workspace posture,
|
||||
network SSRF posture, Gateway exposure posture, agent workspace posture,
|
||||
OpenClaw config secret provider/auth profile posture, and governed tool
|
||||
declarations. For example, IT or a workspace operator can record that Telegram
|
||||
is not an approved channel provider, restrict MCP servers and model refs to
|
||||
approved entries, require private-network fetch/browser access to remain
|
||||
disabled, require direct-message session isolation and channel ingress posture
|
||||
to stay within reviewed bounds, require Gateway bind/auth/HTTP exposure to stay within reviewed
|
||||
disabled, require Gateway bind/auth/HTTP exposure to stay within reviewed
|
||||
bounds, require agent workspace access and tool denies to stay in a reviewed
|
||||
posture, require OpenClaw config SecretRefs to use managed providers, require
|
||||
config auth profiles to carry provider/mode metadata, require governed tools to
|
||||
@@ -50,9 +49,9 @@ arbitrary plugins. The plugin remains enabled if `policy.jsonc` is missing, so
|
||||
doctor can report the missing artifact.
|
||||
|
||||
Policy is authored, not generated from the user's current settings. A minimal
|
||||
policy for channels, MCP servers, model providers, network posture, ingress/channel access, Gateway
|
||||
exposure, agent workspace posture, configured sandbox runtime posture, OpenClaw
|
||||
config secret provider/auth profile posture, and tool metadata looks like this:
|
||||
policy for channels, MCP servers, model providers, network posture, Gateway
|
||||
exposure, agent workspace posture, OpenClaw config secret provider/auth profile
|
||||
posture, and tool metadata looks like this:
|
||||
|
||||
```jsonc
|
||||
{
|
||||
@@ -82,16 +81,6 @@ config secret provider/auth profile posture, and tool metadata looks like this:
|
||||
"allow": false,
|
||||
},
|
||||
},
|
||||
"ingress": {
|
||||
"session": {
|
||||
"requireDmScope": "per-channel-peer",
|
||||
},
|
||||
"channels": {
|
||||
"allowDmPolicies": ["pairing", "allowlist", "disabled"],
|
||||
"denyOpenGroups": true,
|
||||
"requireMentionInGroups": true,
|
||||
},
|
||||
},
|
||||
"gateway": {
|
||||
"exposure": {
|
||||
"allowNonLoopbackBind": false,
|
||||
@@ -153,9 +142,8 @@ config secret provider/auth profile posture, and tool metadata looks like this:
|
||||
The rules are the authority. A category block is only a namespace; checks run
|
||||
when a concrete rule is present. OpenClaw reads current `channels.*` settings
|
||||
`mcp.servers.*`, `models.providers.*`, selected agent model refs, network SSRF
|
||||
settings, direct-message session scope, channel DM policy, channel group policy,
|
||||
channel/group mention gates, Gateway bind/auth/Control UI/Tailscale/remote/HTTP
|
||||
posture, OpenClaw config agent sandbox workspace access and tool deny posture, config secret
|
||||
settings, Gateway bind/auth/Control UI/Tailscale/remote/HTTP posture, OpenClaw
|
||||
config agent sandbox workspace access and tool deny posture, config secret
|
||||
provider and SecretRef provenance, config auth profile metadata, configured
|
||||
global/per-agent tool posture, and `TOOLS.md` declarations as evidence, then
|
||||
reports observed state that does not conform. If a policy denies non-loopback
|
||||
@@ -184,102 +172,21 @@ present in `policy.jsonc`. The observed state is existing OpenClaw config or
|
||||
workspace metadata; policy reports drift but does not rewrite runtime behavior
|
||||
unless a repair path is explicitly available and enabled.
|
||||
|
||||
Policy overlays keep broad top-level rules global, then let named scope blocks
|
||||
add stricter normal policy sections for explicit selectors. A scope name is a
|
||||
descriptive bucket only; matching uses the selector values inside the scope.
|
||||
The overlay is additive: global claims still run, and a scoped claim can emit
|
||||
its own finding against the same observed config.
|
||||
|
||||
#### Scoped overlays
|
||||
|
||||
Use `scopes.<scopeName>` when one set of agents or channels needs stricter
|
||||
policy than the top-level baseline. Agent-scoped sections use `agentIds`, which
|
||||
supports `tools.*`, `agents.workspace.*`, and `sandbox.*`. Channel-scoped
|
||||
ingress uses `channelIds`, which supports `ingress.channels.*`. Unsupported
|
||||
sections are rejected instead of being ignored. If an `agentIds` entry is not
|
||||
present in `agents.list[]`, OpenClaw evaluates the scoped rule against inherited
|
||||
global/default posture for that runtime agent id.
|
||||
|
||||
```jsonc
|
||||
{
|
||||
"tools": {
|
||||
"exec": {
|
||||
"allowHosts": ["sandbox", "node"],
|
||||
},
|
||||
},
|
||||
"sandbox": {
|
||||
"requireMode": ["all", "non-main"],
|
||||
},
|
||||
"scopes": {
|
||||
"release-workspace": {
|
||||
"agentIds": ["release-agent", "review-agent"],
|
||||
"agents": {
|
||||
"workspace": {
|
||||
"allowedAccess": ["none", "ro"],
|
||||
},
|
||||
},
|
||||
},
|
||||
"release-lockdown": {
|
||||
"agentIds": ["release-agent"],
|
||||
"tools": {
|
||||
"exec": {
|
||||
"allowHosts": ["sandbox"],
|
||||
"allowSecurity": ["deny", "allowlist"],
|
||||
"requireAsk": ["always"],
|
||||
},
|
||||
"denyTools": ["exec", "process", "write", "edit", "apply_patch"],
|
||||
},
|
||||
"sandbox": {
|
||||
"requireMode": ["all"],
|
||||
"allowBackends": ["docker"],
|
||||
},
|
||||
},
|
||||
"shell-sandbox": {
|
||||
"agentIds": ["shell-agent"],
|
||||
"sandbox": {
|
||||
"allowBackends": ["openshell"],
|
||||
"containers": {
|
||||
"requireReadOnlyMounts": false,
|
||||
},
|
||||
},
|
||||
},
|
||||
"telegram-ingress": {
|
||||
"channelIds": ["telegram"],
|
||||
"ingress": {
|
||||
"channels": {
|
||||
"allowDmPolicies": ["pairing"],
|
||||
"denyOpenGroups": true,
|
||||
"requireMentionInGroups": true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
The same agent can appear in multiple scopes when each scope governs different
|
||||
fields, as shown above. A repeated scoped field for the same agent must be
|
||||
equally or more restrictive according to policy metadata; weaker duplicate
|
||||
claims are rejected. Strictness metadata treats allow-lists as subsets,
|
||||
deny-lists as supersets, and required booleans as fixed requirements.
|
||||
|
||||
Container posture policy is evaluated only against evidence OpenClaw can
|
||||
observe for the matched agent. If an enabled `sandbox.containers.*` rule applies
|
||||
to an agent whose sandbox backend cannot expose that field, policy reports
|
||||
`policy/sandbox-container-posture-unobservable` instead of treating the claim as
|
||||
passing. Use separate `agentIds` scopes for agent groups that use different
|
||||
sandbox backends, and leave unsupported container rules unset or false for the
|
||||
groups where those fields cannot be observed.
|
||||
|
||||
Top-level `ingress.session.requireDmScope` remains global because
|
||||
`session.dmScope` is not channel-attributable evidence.
|
||||
|
||||
| Selector | Supported sections | Use when |
|
||||
| ------------ | ------------------------------------------ | ------------------------------------------------- |
|
||||
| `agentIds` | `tools`, `agents.workspace`, and `sandbox` | One or more runtime agents need stricter rules. |
|
||||
| `channelIds` | `ingress.channels` | One or more channels need stricter ingress rules. |
|
||||
|
||||
Every scope present in `policy.jsonc` must be valid and enforceable.
|
||||
Agent-specific policy overlays keep broad `tools.*` and `agents.workspace`
|
||||
posture global, then let named scope blocks add stricter normal policy sections
|
||||
for explicit `agentIds` under `scopes.<scopeName>`. The initial scoped
|
||||
sections are `tools` and `agents.workspace`; sandbox and ingress can use the
|
||||
same container once their evidence is attributable to an agent. Scoped fields
|
||||
carry strictness metadata such as allowlist subset, denylist superset, required
|
||||
boolean, and exact-list semantics so future policy-file conformance can reuse
|
||||
the same rule inventory instead of guessing. The overlay is additive: global
|
||||
claims still run, and a scoped claim can emit its own finding against the same
|
||||
observed config. See [Agent-scoped policy overlays](/plan/policy-agent-scoped-overlays).
|
||||
Every scope present in `policy.jsonc` must be valid and enforceable. Scopes
|
||||
currently require `agentIds`, and that selector supports only `tools.*` and
|
||||
`agents.workspace.*`. If an `agentIds` entry is not present in `agents.list[]`,
|
||||
the scoped rule is evaluated against the inherited global/default posture for
|
||||
that runtime agent id instead of being skipped.
|
||||
|
||||
#### Channels
|
||||
|
||||
@@ -308,15 +215,6 @@ Every scope present in `policy.jsonc` must be valid and enforceable.
|
||||
| ------------------------------ | ----------------------------------- | ------------------------------------------------------------------ |
|
||||
| `network.privateNetwork.allow` | Private-network SSRF escape hatches | Set to `false` to require private-network access to stay disabled. |
|
||||
|
||||
#### Ingress and channel access
|
||||
|
||||
| Policy field | Observed state | Use when |
|
||||
| ----------------------------------------- | -------------------------------------------------------------- | ------------------------------------------------------------------ |
|
||||
| `ingress.session.requireDmScope` | `session.dmScope` | Require a reviewed direct-message isolation scope. |
|
||||
| `ingress.channels.allowDmPolicies` | `channels.*.dmPolicy` and legacy channel DM policy fields | Allow only reviewed direct-message channel policies. |
|
||||
| `ingress.channels.denyOpenGroups` | Channel, account, and group ingress policy | Deny open group ingress for configured channels and accounts. |
|
||||
| `ingress.channels.requireMentionInGroups` | Channel, account, group, guild, and nested mention gate config | Require mention gates when group ingress is open or mention-gated. |
|
||||
|
||||
#### Gateway
|
||||
|
||||
| Policy field | Observed state | Use when |
|
||||
@@ -337,23 +235,6 @@ Every scope present in `policy.jsonc` must be valid and enforceable.
|
||||
| `agents.workspace.allowedAccess` | `agents.defaults.sandbox.workspaceAccess` and `agents.list[].sandbox.workspaceAccess` | Allow only sandbox workspace access values such as `none` or `ro`. |
|
||||
| `agents.workspace.denyTools` | Global and per-agent tool deny config | Require workspace/runtime mutation tools such as `exec`, `process`, `write`, `edit`, or `apply_patch` to be denied. |
|
||||
|
||||
#### Sandbox posture
|
||||
|
||||
| Policy field | Observed state | Use when |
|
||||
| ----------------------------------------------------- | ------------------------------------------------------- | -------------------------------------------------------------- |
|
||||
| `sandbox.requireMode` | `agents.defaults.sandbox.mode` and per-agent mode | Allow only reviewed sandbox modes such as `all` or `non-main`. |
|
||||
| `sandbox.allowBackends` | `agents.defaults.sandbox.backend` and per-agent backend | Allow only reviewed sandbox backends such as `docker`. |
|
||||
| `sandbox.containers.denyHostNetwork` | Container-backed sandbox/browser network mode | Deny host network mode. |
|
||||
| `sandbox.containers.denyContainerNamespaceJoin` | Container-backed sandbox/browser network mode | Deny joining another container network namespace. |
|
||||
| `sandbox.containers.requireReadOnlyMounts` | Container-backed sandbox/browser mount mode | Require mounts to be read-only. |
|
||||
| `sandbox.containers.denyContainerRuntimeSocketMounts` | Container-backed sandbox/browser mount targets | Deny container runtime socket mounts. |
|
||||
| `sandbox.containers.denyUnconfinedProfiles` | Container security profile posture | Deny unconfined container security profiles. |
|
||||
| `sandbox.browser.requireCdpSourceRange` | Sandbox browser CDP source range | Require browser CDP exposure to declare a source range. |
|
||||
|
||||
Policy treats missing `sandbox.mode` as the implicit default `off`, so
|
||||
`sandbox.requireMode` reports a fresh or unconfigured sandbox as outside an
|
||||
allowlist such as `["all"]`.
|
||||
|
||||
#### Secrets
|
||||
|
||||
| Policy field | Observed state | Use when |
|
||||
@@ -400,41 +281,8 @@ openclaw policy check --severity-min error
|
||||
attestation hashes. The same findings also appear in `openclaw doctor --lint`
|
||||
when the Policy plugin is enabled.
|
||||
|
||||
Compare an operator policy file to an authored baseline policy file:
|
||||
|
||||
```bash
|
||||
openclaw policy compare --baseline official.policy.jsonc
|
||||
openclaw policy compare --baseline official.policy.jsonc --policy policy.jsonc --json
|
||||
```
|
||||
|
||||
`policy compare` compares policy file syntax to policy file syntax. It does not
|
||||
inspect OpenClaw runtime state, evidence, credentials, or secrets. The command
|
||||
uses the same policy rule metadata that governs scoped overlays: allowlists must
|
||||
stay equal or narrower, denylists must stay equal or broader, required booleans
|
||||
must keep their required value, ordered strings must move only toward the more
|
||||
restrictive end of the configured order, and exact lists must match.
|
||||
|
||||
The baseline file can be an organization-authored policy. The checked policy can
|
||||
use stricter values or add extra policy rules. A top-level checked rule can also
|
||||
satisfy a scoped baseline rule when it is equally or more restrictive because
|
||||
top-level policy applies broadly. Scope names do not need to match; scoped
|
||||
comparison is keyed by selector value such as `agentIds` or `channelIds` and by
|
||||
the policy field being checked.
|
||||
|
||||
Example clean compare JSON output reports only policy-file comparison state:
|
||||
|
||||
```json
|
||||
{
|
||||
"ok": true,
|
||||
"baselinePath": "official.policy.jsonc",
|
||||
"policyPath": "policy.jsonc",
|
||||
"rulesChecked": 3,
|
||||
"findings": []
|
||||
}
|
||||
```
|
||||
|
||||
Example clean `policy check --json` output includes stable hashes that can be
|
||||
recorded by an operator or supervisor:
|
||||
Example clean JSON output includes stable hashes that can be recorded by an
|
||||
operator or supervisor:
|
||||
|
||||
```json
|
||||
{
|
||||
@@ -674,63 +522,47 @@ choose a different interval.
|
||||
|
||||
Policy currently verifies:
|
||||
|
||||
| Check id | Finding |
|
||||
| ------------------------------------------------- | --------------------------------------------------------------------------------- |
|
||||
| `policy/policy-jsonc-missing` | Policy is enabled but `policy.jsonc` is missing. |
|
||||
| `policy/policy-jsonc-invalid` | Policy cannot be parsed or contains malformed rule entries. |
|
||||
| `policy/policy-hash-mismatch` | Policy does not match configured `expectedHash`. |
|
||||
| `policy/attestation-hash-mismatch` | Current policy evidence no longer matches the accepted attestation. |
|
||||
| `policy/policy-conformance-invalid` | A baseline or checked policy file has invalid comparison syntax. |
|
||||
| `policy/policy-conformance-missing` | A checked policy file is missing a rule required by the baseline policy file. |
|
||||
| `policy/policy-conformance-weaker` | A checked policy file has a weaker value than the baseline policy file. |
|
||||
| `policy/channels-denied-provider` | An enabled channel matches a channel deny rule. |
|
||||
| `policy/mcp-denied-server` | A configured MCP server is denied by policy. |
|
||||
| `policy/mcp-unapproved-server` | A configured MCP server is outside the allowlist. |
|
||||
| `policy/models-denied-provider` | A configured model provider or model ref uses a denied provider. |
|
||||
| `policy/models-unapproved-provider` | A configured model provider or model ref is outside the allowlist. |
|
||||
| `policy/network-private-access-enabled` | A private-network SSRF escape hatch is enabled when policy denies it. |
|
||||
| `policy/ingress-dm-policy-unapproved` | A channel DM policy is outside the policy allowlist. |
|
||||
| `policy/ingress-dm-scope-unapproved` | `session.dmScope` does not match the policy-required DM isolation scope. |
|
||||
| `policy/ingress-open-groups-denied` | A channel group policy is `open` while policy denies open group ingress. |
|
||||
| `policy/ingress-group-mention-required` | A channel or group entry disables mention gates while policy requires them. |
|
||||
| `policy/gateway-non-loopback-bind` | Gateway bind posture permits non-loopback exposure when policy denies it. |
|
||||
| `policy/gateway-auth-disabled` | Gateway authentication is disabled when policy requires auth. |
|
||||
| `policy/gateway-rate-limit-missing` | Gateway auth rate-limit posture is not explicit when policy requires it. |
|
||||
| `policy/gateway-control-ui-insecure` | Gateway Control UI insecure exposure toggles are enabled. |
|
||||
| `policy/gateway-tailscale-funnel` | Gateway Tailscale Funnel exposure is enabled when policy denies it. |
|
||||
| `policy/gateway-remote-enabled` | Gateway remote mode is active when policy denies it. |
|
||||
| `policy/gateway-http-endpoint-enabled` | A Gateway HTTP API endpoint is enabled while denied by policy. |
|
||||
| `policy/gateway-http-url-fetch-unrestricted` | Gateway HTTP URL-fetch input lacks a required URL allowlist. |
|
||||
| `policy/agents-workspace-access-denied` | Agent sandbox mode or workspace access is outside the policy allowlist. |
|
||||
| `policy/agents-tool-not-denied` | An agent or default config does not deny a tool required by policy. |
|
||||
| `policy/tools-profile-unapproved` | A configured global or per-agent tool profile is outside the allowlist. |
|
||||
| `policy/tools-fs-workspace-only-required` | Filesystem tools are not configured with workspace-only path posture. |
|
||||
| `policy/tools-exec-security-unapproved` | Exec security mode is outside the policy allowlist. |
|
||||
| `policy/tools-exec-ask-unapproved` | Exec ask mode is outside the policy allowlist. |
|
||||
| `policy/tools-exec-host-unapproved` | Exec host routing is outside the policy allowlist. |
|
||||
| `policy/tools-elevated-enabled` | Elevated tool mode is enabled when policy denies it. |
|
||||
| `policy/tools-also-allow-missing` | A configured `alsoAllow` list is missing an entry required by policy. |
|
||||
| `policy/tools-also-allow-unexpected` | A configured `alsoAllow` list includes an entry not expected by policy. |
|
||||
| `policy/tools-required-deny-missing` | A global or per-agent tool deny list does not include a required denied tool. |
|
||||
| `policy/sandbox-mode-unapproved` | Sandbox mode is outside the policy allowlist. |
|
||||
| `policy/sandbox-backend-unapproved` | Sandbox backend is outside the policy allowlist. |
|
||||
| `policy/sandbox-container-posture-unobservable` | A container posture rule is enabled for a backend that cannot observe it. |
|
||||
| `policy/sandbox-container-host-network-denied` | A container-backed sandbox or browser uses host network mode. |
|
||||
| `policy/sandbox-container-namespace-join-denied` | A container-backed sandbox or browser joins another container namespace. |
|
||||
| `policy/sandbox-container-mount-mode-required` | A container-backed sandbox or browser mount is not read-only. |
|
||||
| `policy/sandbox-container-runtime-socket-mount` | A container-backed sandbox or browser mount exposes the container runtime socket. |
|
||||
| `policy/sandbox-container-unconfined-profile` | Container sandbox profile is unconfined when policy denies it. |
|
||||
| `policy/sandbox-browser-cdp-source-range-missing` | Sandbox browser CDP source range is missing when policy requires one. |
|
||||
| `policy/secrets-unmanaged-provider` | A config SecretRef references a provider not declared under `secrets.providers`. |
|
||||
| `policy/secrets-denied-provider-source` | A config secret provider or SecretRef uses a source denied by policy. |
|
||||
| `policy/secrets-insecure-provider` | A secret provider opts into insecure posture when policy denies it. |
|
||||
| `policy/auth-profile-invalid-metadata` | A config auth profile is missing valid provider or mode metadata. |
|
||||
| `policy/auth-profile-unapproved-mode` | A config auth profile mode is outside the policy allowlist. |
|
||||
| `policy/tools-missing-risk-level` | A governed tool declaration is missing risk metadata. |
|
||||
| `policy/tools-unknown-risk-level` | A governed tool declaration uses an unknown risk value. |
|
||||
| `policy/tools-missing-sensitivity-token` | A governed tool declaration is missing sensitivity metadata. |
|
||||
| `policy/tools-missing-owner` | A governed tool declaration is missing owner metadata. |
|
||||
| `policy/tools-unknown-sensitivity-token` | A governed tool declaration uses an unknown sensitivity value. |
|
||||
| Check id | Finding |
|
||||
| -------------------------------------------- | -------------------------------------------------------------------------------- |
|
||||
| `policy/policy-jsonc-missing` | Policy is enabled but `policy.jsonc` is missing. |
|
||||
| `policy/policy-jsonc-invalid` | Policy cannot be parsed or contains malformed rule entries. |
|
||||
| `policy/policy-hash-mismatch` | Policy does not match configured `expectedHash`. |
|
||||
| `policy/attestation-hash-mismatch` | Current policy evidence no longer matches the accepted attestation. |
|
||||
| `policy/channels-denied-provider` | An enabled channel matches a channel deny rule. |
|
||||
| `policy/mcp-denied-server` | A configured MCP server is denied by policy. |
|
||||
| `policy/mcp-unapproved-server` | A configured MCP server is outside the allowlist. |
|
||||
| `policy/models-denied-provider` | A configured model provider or model ref uses a denied provider. |
|
||||
| `policy/models-unapproved-provider` | A configured model provider or model ref is outside the allowlist. |
|
||||
| `policy/network-private-access-enabled` | A private-network SSRF escape hatch is enabled when policy denies it. |
|
||||
| `policy/gateway-non-loopback-bind` | Gateway bind posture permits non-loopback exposure when policy denies it. |
|
||||
| `policy/gateway-auth-disabled` | Gateway authentication is disabled when policy requires auth. |
|
||||
| `policy/gateway-rate-limit-missing` | Gateway auth rate-limit posture is not explicit when policy requires it. |
|
||||
| `policy/gateway-control-ui-insecure` | Gateway Control UI insecure exposure toggles are enabled. |
|
||||
| `policy/gateway-tailscale-funnel` | Gateway Tailscale Funnel exposure is enabled when policy denies it. |
|
||||
| `policy/gateway-remote-enabled` | Gateway remote mode is active when policy denies it. |
|
||||
| `policy/gateway-http-endpoint-enabled` | A Gateway HTTP API endpoint is enabled while denied by policy. |
|
||||
| `policy/gateway-http-url-fetch-unrestricted` | Gateway HTTP URL-fetch input lacks a required URL allowlist. |
|
||||
| `policy/agents-workspace-access-denied` | Agent sandbox mode or workspace access is outside the policy allowlist. |
|
||||
| `policy/agents-tool-not-denied` | An agent or default config does not deny a tool required by policy. |
|
||||
| `policy/tools-profile-unapproved` | A configured global or per-agent tool profile is outside the allowlist. |
|
||||
| `policy/tools-fs-workspace-only-required` | Filesystem tools are not configured with workspace-only path posture. |
|
||||
| `policy/tools-exec-security-unapproved` | Exec security mode is outside the policy allowlist. |
|
||||
| `policy/tools-exec-ask-unapproved` | Exec ask mode is outside the policy allowlist. |
|
||||
| `policy/tools-exec-host-unapproved` | Exec host routing is outside the policy allowlist. |
|
||||
| `policy/tools-elevated-enabled` | Elevated tool mode is enabled when policy denies it. |
|
||||
| `policy/tools-also-allow-missing` | A configured `alsoAllow` list is missing an entry required by policy. |
|
||||
| `policy/tools-also-allow-unexpected` | A configured `alsoAllow` list includes an entry not expected by policy. |
|
||||
| `policy/tools-required-deny-missing` | A global or per-agent tool deny list does not include a required denied tool. |
|
||||
| `policy/secrets-unmanaged-provider` | A config SecretRef references a provider not declared under `secrets.providers`. |
|
||||
| `policy/secrets-denied-provider-source` | A config secret provider or SecretRef uses a source denied by policy. |
|
||||
| `policy/secrets-insecure-provider` | A secret provider opts into insecure posture when policy denies it. |
|
||||
| `policy/auth-profile-invalid-metadata` | A config auth profile is missing valid provider or mode metadata. |
|
||||
| `policy/auth-profile-unapproved-mode` | A config auth profile mode is outside the policy allowlist. |
|
||||
| `policy/tools-missing-risk-level` | A governed tool declaration is missing risk metadata. |
|
||||
| `policy/tools-unknown-risk-level` | A governed tool declaration uses an unknown risk value. |
|
||||
| `policy/tools-missing-sensitivity-token` | A governed tool declaration is missing sensitivity metadata. |
|
||||
| `policy/tools-missing-owner` | A governed tool declaration is missing owner metadata. |
|
||||
| `policy/tools-unknown-sensitivity-token` | A governed tool declaration uses an unknown sensitivity value. |
|
||||
|
||||
Policy findings can include both `target` and `requirement`. `target` is the
|
||||
observed workspace thing that does not conform. `requirement` is the authored
|
||||
@@ -874,11 +706,10 @@ configured channel:
|
||||
|
||||
## Exit codes
|
||||
|
||||
| Command | `0` | `1` | `2` |
|
||||
| ---------------- | ------------------------------------------------------ | ------------------------------------------------------------------- | ---------------------------- |
|
||||
| `policy check` | No findings at the threshold. | One or more findings met the threshold. | Argument or runtime failure. |
|
||||
| `policy compare` | The policy file is at least as strict as the baseline. | The policy file is invalid, missing, or weaker than baseline rules. | Argument or runtime failure. |
|
||||
| `policy watch` | No findings and accepted hash is current. | Findings exist or accepted attestation is stale. | Argument or runtime failure. |
|
||||
| Command | `0` | `1` | `2` |
|
||||
| -------------- | ----------------------------------------- | ------------------------------------------------ | ---------------------------- |
|
||||
| `policy check` | No findings at the threshold. | One or more findings met the threshold. | Argument or runtime failure. |
|
||||
| `policy watch` | No findings and accepted hash is current. | Findings exist or accepted attestation is stale. | Argument or runtime failure. |
|
||||
|
||||
## Related
|
||||
|
||||
|
||||
@@ -14,12 +14,12 @@ the finished turn to OpenClaw.
|
||||
Runtimes are easy to confuse with providers because both show up near model
|
||||
configuration. They are different layers:
|
||||
|
||||
| Layer | Examples | What it means |
|
||||
| ------------- | -------------------------------------------- | ------------------------------------------------------------------- |
|
||||
| Provider | `openai`, `anthropic`, `openai-codex` | How OpenClaw authenticates, discovers models, and names model refs. |
|
||||
| Model | `gpt-5.5`, `claude-opus-4-6` | The model selected for the agent turn. |
|
||||
| Agent runtime | `openclaw`, `codex`, `copilot`, `claude-cli` | The low level loop or backend that executes the prepared turn. |
|
||||
| Channel | Telegram, Discord, Slack, WhatsApp | Where messages enter and leave OpenClaw. |
|
||||
| Layer | Examples | What it means |
|
||||
| ------------- | ------------------------------------- | ------------------------------------------------------------------- |
|
||||
| Provider | `openai`, `anthropic`, `openai-codex` | How OpenClaw authenticates, discovers models, and names model refs. |
|
||||
| Model | `gpt-5.5`, `claude-opus-4-6` | The model selected for the agent turn. |
|
||||
| Agent runtime | `openclaw`, `codex`, `claude-cli` | The low level loop or backend that executes the prepared turn. |
|
||||
| Channel | Telegram, Discord, Slack, WhatsApp | Where messages enter and leave OpenClaw. |
|
||||
|
||||
You will also see the word **harness** in code. A harness is the implementation
|
||||
that provides an agent runtime. For example, the bundled Codex harness
|
||||
@@ -33,17 +33,13 @@ There are two runtime families:
|
||||
|
||||
- **Embedded harnesses** run inside OpenClaw's prepared agent loop. Today this
|
||||
is the built-in `openclaw` runtime plus registered plugin harnesses such as
|
||||
`codex` and `copilot`.
|
||||
`codex`.
|
||||
- **CLI backends** run a local CLI process while keeping the model ref
|
||||
canonical. For example, `anthropic/claude-opus-4-8` with
|
||||
canonical. For example, `anthropic/claude-opus-4-7` with
|
||||
a model-scoped `agentRuntime.id: "claude-cli"` means "select the Anthropic
|
||||
model, execute through Claude CLI." `claude-cli` is not an embedded harness id
|
||||
and must not be passed to AgentHarness selection.
|
||||
|
||||
The `copilot` harness is a separate, opt-in plugin harness for the
|
||||
GitHub Copilot CLI; see [GitHub Copilot agent runtime](/plugins/copilot)
|
||||
for the user-facing decision between PI, Codex, and GitHub Copilot agent runtime.
|
||||
|
||||
## Codex surfaces
|
||||
|
||||
Most confusion comes from several different surfaces sharing the Codex name:
|
||||
@@ -174,9 +170,9 @@ Claude CLI form is:
|
||||
{
|
||||
agents: {
|
||||
defaults: {
|
||||
model: "anthropic/claude-opus-4-8",
|
||||
model: "anthropic/claude-opus-4-7",
|
||||
models: {
|
||||
"anthropic/claude-opus-4-8": {
|
||||
"anthropic/claude-opus-4-7": {
|
||||
agentRuntime: { id: "claude-cli" },
|
||||
},
|
||||
},
|
||||
@@ -205,34 +201,6 @@ If `openclaw doctor` warns that the `codex` plugin is enabled while
|
||||
`openai-codex/*` remains in config, treat that as legacy route state. Run
|
||||
`openclaw doctor --fix` to rewrite it to `openai/*` with the Codex runtime.
|
||||
|
||||
## GitHub Copilot agent runtime
|
||||
|
||||
The bundled `copilot` extension registers an opt-in `copilot` runtime
|
||||
backed by the GitHub Copilot CLI (`@github/copilot-sdk`). It claims the
|
||||
canonical subscription `github-copilot` provider and is **never** selected by
|
||||
`auto`. Opt in per-model or per-provider via `agentRuntime.id`:
|
||||
|
||||
```json5
|
||||
{
|
||||
agents: {
|
||||
defaults: {
|
||||
model: "github-copilot/gpt-5.5",
|
||||
models: {
|
||||
"github-copilot/gpt-5.5": {
|
||||
agentRuntime: { id: "copilot" },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
The harness claims its provider, runtime, CLI session key, and auth profile
|
||||
prefix in `extensions/copilot/doctor-contract-api.ts`, which
|
||||
`openclaw doctor` auto-loads. For configuration, auth, transcript mirroring,
|
||||
compaction, the doctor probe surface, and the broader PI vs Codex vs Copilot
|
||||
SDK decision, see [GitHub Copilot agent runtime](/plugins/copilot).
|
||||
|
||||
## Compatibility contract
|
||||
|
||||
When a runtime is not OpenClaw, it should document what OpenClaw surfaces it supports.
|
||||
@@ -268,7 +236,6 @@ runtime policy first. Legacy session runtime pins no longer decide routing.
|
||||
|
||||
- [Codex harness](/plugins/codex-harness)
|
||||
- [Codex harness runtime](/plugins/codex-harness-runtime)
|
||||
- [GitHub Copilot agent runtime](/plugins/copilot)
|
||||
- [OpenAI](/providers/openai)
|
||||
- [Agent harness plugins](/plugins/sdk-agent-harness)
|
||||
- [Agent loop](/concepts/agent-loop)
|
||||
|
||||
@@ -251,20 +251,6 @@ Native Codex and OpenClaw embedded agent runs satisfy `assemble-before-prompt`.
|
||||
Generic CLI backends do not, so engines that require it are rejected before the
|
||||
CLI process starts.
|
||||
|
||||
### Failure isolation
|
||||
|
||||
OpenClaw isolates the selected plugin engine from the core reply path. If a
|
||||
non-legacy engine is missing, fails contract validation, throws during factory
|
||||
creation, or throws from a lifecycle method, OpenClaw quarantines that engine
|
||||
for the current Gateway process and downgrades context-engine work to the
|
||||
built-in `legacy` engine. The error is logged with the failed operation so the
|
||||
operator can repair, update, or disable the plugin without the agent going
|
||||
silent.
|
||||
|
||||
Host requirement failures are different: when an engine declares that a runtime
|
||||
lacks a required capability, OpenClaw fails closed before starting the run. That
|
||||
protects engines that would corrupt state if they ran in an unsupported host.
|
||||
|
||||
### ownsCompaction
|
||||
|
||||
`ownsCompaction` controls whether OpenClaw runtime's built-in in-attempt auto-compaction stays enabled for the run:
|
||||
@@ -335,7 +321,7 @@ The slot is exclusive at run time - only one registered context engine is resolv
|
||||
|
||||
- Use `openclaw doctor` to verify your engine is loading correctly.
|
||||
- If switching engines, existing sessions continue with their current history. The new engine takes over for future runs.
|
||||
- Engine errors are logged and the selected plugin engine is quarantined for the current Gateway process. OpenClaw falls back to `legacy` for user turns so replies can continue, but you should still repair, update, disable, or uninstall the broken plugin.
|
||||
- Engine errors are logged and surfaced in diagnostics. If a plugin engine fails to register or the selected engine id cannot be resolved, OpenClaw does not fall back automatically; runs fail until you fix the plugin or switch `plugins.slots.contextEngine` back to `"legacy"`.
|
||||
- For development, use `openclaw plugins install -l ./my-engine` to link a local plugin directory without copying.
|
||||
|
||||
## Related
|
||||
|
||||
@@ -30,7 +30,7 @@ Treat them differently from normal config:
|
||||
|
||||
## Local model lean mode
|
||||
|
||||
`agents.defaults.experimental.localModelLean: true` is a pressure-release valve for weaker local-model setups. When it is on, OpenClaw drops three default tools — `browser`, `cron`, and `message` — from the model-visible tool surface for every turn. When Code Mode or Tool Search is enabled, those tools can still stay in the hidden catalog behind the compact controls. Use `agents.list[].experimental.localModelLean` to enable or disable the same behavior for one configured agent.
|
||||
`agents.defaults.experimental.localModelLean: true` is a pressure-release valve for weaker local-model setups. When it is on, OpenClaw drops three default tools — `browser`, `cron`, and `message` — from the agent's tool surface for every turn. Nothing else changes. Use `agents.list[].experimental.localModelLean` to enable or disable the same behavior for one configured agent.
|
||||
|
||||
### Why these three tools
|
||||
|
||||
@@ -40,7 +40,7 @@ These three tools have the largest descriptions and the most parameter shapes in
|
||||
- The model picking the right tool vs. emitting malformed tool calls because there are too many similar-looking schemas.
|
||||
- The Chat Completions adapter staying inside the server's structured-output limits vs. tripping a 400 on tool-call payload size.
|
||||
|
||||
Removing them does not silently rewire OpenClaw — it just makes the visible tool list shorter. The model still has `read`, `write`, `edit`, `exec`, `apply_patch`, web search/fetch (when configured), memory, and session/agent tools available. With Code Mode or Tool Search, the compact control can still search for and call hidden catalog tools that policy allowed for the run.
|
||||
Removing them does not silently rewire OpenClaw — it just makes the tool list shorter. The model still has `read`, `write`, `edit`, `exec`, `apply_patch`, web search/fetch (when configured), memory, and session/agent tools available.
|
||||
|
||||
### When to turn it on
|
||||
|
||||
@@ -94,7 +94,7 @@ Restart the Gateway after changing the flag, then confirm the trimmed tool list
|
||||
openclaw status --deep
|
||||
```
|
||||
|
||||
The deep status output lists the active model-visible agent tools; `browser`, `cron`, and `message` should be absent when lean mode is on. If Code Mode or Tool Search is enabled, they may still be available through the hidden catalog.
|
||||
The deep status output lists the active agent tools; `browser`, `cron`, and `message` should be absent when lean mode is on.
|
||||
|
||||
## Experimental does not mean hidden
|
||||
|
||||
|
||||
@@ -116,7 +116,7 @@ Official provider plugins publish their own model catalog rows. These providers
|
||||
- CLI: `openclaw onboard --auth-choice apiKey`
|
||||
- Direct public Anthropic requests support the shared `/fast` toggle and `params.fastMode`, including API-key and OAuth-authenticated traffic sent to `api.anthropic.com`; OpenClaw maps that to Anthropic `service_tier` (`auto` vs `standard_only`)
|
||||
- Preferred Claude CLI config keeps the model ref canonical and selects the CLI
|
||||
backend separately: `anthropic/claude-opus-4-8` with
|
||||
backend separately: `anthropic/claude-opus-4-7` with
|
||||
model-scoped `agentRuntime.id: "claude-cli"`. Legacy
|
||||
`claude-cli/claude-opus-4-7` refs still work for compatibility.
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ sidebarTitle: "Models CLI"
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
Model refs choose a provider and model. They do not usually choose the low-level agent runtime. OpenAI agent refs are the main exception: `openai/gpt-5.5` runs through the Codex app-server runtime by default on the official OpenAI provider. Subscription Copilot refs (`github-copilot/*`) can additionally be opted into the bundled GitHub Copilot agent runtime — that path stays explicit (no `auto` fallback). Explicit runtime overrides belong on provider/model policy, not on the whole agent or session. In Codex runtime mode, the `openai/gpt-*` ref does not imply API-key billing; auth can come from a Codex account or `openai-codex` auth profile. See [Agent runtimes](/concepts/agent-runtimes) and [GitHub Copilot agent runtime](/plugins/copilot).
|
||||
Model refs choose a provider and model. They do not usually choose the low-level agent runtime. OpenAI agent refs are the main exception: `openai/gpt-5.5` runs through the Codex app-server runtime by default on the official OpenAI provider. Explicit runtime overrides belong on provider/model policy, not on the whole agent or session. In Codex runtime mode, the `openai/gpt-*` ref does not imply API-key billing; auth can come from a Codex account or `openai-codex` auth profile. See [Agent runtimes](/concepts/agent-runtimes).
|
||||
|
||||
## How model selection works
|
||||
|
||||
@@ -340,7 +340,7 @@ When live probes run in a TTY, you can select fallbacks interactively. In non-in
|
||||
|
||||
## Models registry (`models.json`)
|
||||
|
||||
Custom providers in `models.providers` are written into `models.json` under the agent directory (default `~/.openclaw/agents/<agentId>/agent/models.json`). Provider-plugin catalogs are stored as generated plugin-owned catalog shards under the agent's plugin state and loaded automatically. This file is merged by default unless `models.mode` is set to `replace`.
|
||||
Custom providers in `models.providers` are written into `models.json` under the agent directory (default `~/.openclaw/agents/<agentId>/agent/models.json`). This file is merged by default unless `models.mode` is set to `replace`.
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="Merge mode precedence">
|
||||
|
||||
@@ -178,50 +178,6 @@ Progress lines are enabled by default in progress mode. They come from real run
|
||||
events: tool starts, item updates, task plans, approvals, command output, patch
|
||||
summaries, and similar agent activity.
|
||||
|
||||
Tools can also emit typed progress while a single tool call is still running.
|
||||
That is how a slow fetch or search can update the visible draft before the tool
|
||||
returns its final result. The progress update is a partial tool result with
|
||||
empty model content and explicit public channel metadata:
|
||||
|
||||
```json
|
||||
{
|
||||
"content": [],
|
||||
"progress": {
|
||||
"text": "Fetching page content...",
|
||||
"visibility": "channel",
|
||||
"privacy": "public",
|
||||
"id": "web_fetch:fetching"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
OpenClaw renders only the `progress.text` in the channel progress UI. The
|
||||
normal tool result still arrives later as `content` and `details`, and is the
|
||||
only part returned to the model.
|
||||
|
||||
When adding progress to a tool, use a short, generic message and delay it until
|
||||
the operation has been pending long enough to be useful:
|
||||
|
||||
```typescript
|
||||
const clearProgressTimer = scheduleToolProgress(
|
||||
onUpdate,
|
||||
{ text: "Fetching page content...", id: "web_fetch:fetching" },
|
||||
5_000,
|
||||
{ signal },
|
||||
);
|
||||
|
||||
try {
|
||||
return await runToolWork();
|
||||
} finally {
|
||||
clearProgressTimer();
|
||||
}
|
||||
```
|
||||
|
||||
This pattern means fast calls do not show a progress line, long calls show one
|
||||
while they are still pending, and canceled calls clear the timer before stale
|
||||
progress can appear. Progress text is a public UI side channel, so it must not
|
||||
include secrets, raw arguments, fetched content, command output, or page text.
|
||||
|
||||
OpenClaw uses the same formatter for progress drafts and `/verbose`:
|
||||
|
||||
```json5
|
||||
|
||||
@@ -889,13 +889,13 @@ pnpm openclaw qa character-eval \
|
||||
--model openai/gpt-5.5,thinking=medium,fast \
|
||||
--model openai/gpt-5.2,thinking=xhigh \
|
||||
--model openai/gpt-5,thinking=xhigh \
|
||||
--model anthropic/claude-opus-4-8,thinking=high \
|
||||
--model anthropic/claude-opus-4-7,thinking=high \
|
||||
--model anthropic/claude-sonnet-4-6,thinking=high \
|
||||
--model zai/glm-5.1,thinking=high \
|
||||
--model moonshot/kimi-k2.5,thinking=high \
|
||||
--model google/gemini-3.1-pro-preview,thinking=high \
|
||||
--judge-model openai/gpt-5.5,thinking=xhigh,fast \
|
||||
--judge-model anthropic/claude-opus-4-8,thinking=high \
|
||||
--judge-model anthropic/claude-opus-4-7,thinking=high \
|
||||
--blind-judge-models \
|
||||
--concurrency 16 \
|
||||
--judge-concurrency 16
|
||||
@@ -926,13 +926,13 @@ Candidate and judge model runs both default to concurrency 16. Lower
|
||||
`--concurrency` or `--judge-concurrency` when provider limits or local gateway
|
||||
pressure make a run too noisy.
|
||||
When no candidate `--model` is passed, the character eval defaults to
|
||||
`openai/gpt-5.5`, `openai/gpt-5.2`, `openai/gpt-5`, `anthropic/claude-opus-4-8`,
|
||||
`openai/gpt-5.5`, `openai/gpt-5.2`, `openai/gpt-5`, `anthropic/claude-opus-4-7`,
|
||||
`anthropic/claude-sonnet-4-6`, `zai/glm-5.1`,
|
||||
`moonshot/kimi-k2.5`, and
|
||||
`google/gemini-3.1-pro-preview` when no `--model` is passed.
|
||||
When no `--judge-model` is passed, the judges default to
|
||||
`openai/gpt-5.5,thinking=xhigh,fast` and
|
||||
`anthropic/claude-opus-4-8,thinking=high`.
|
||||
`anthropic/claude-opus-4-7,thinking=high`.
|
||||
|
||||
## Related docs
|
||||
|
||||
|
||||
@@ -197,12 +197,6 @@ Matrix:
|
||||
|
||||
Preview streaming can also include **tool-progress** updates - short status lines like "searching the web", "reading file", or "calling tool" - that appear in the same preview message while tools are running, ahead of the final reply. In Codex app-server mode, Codex preamble/commentary messages use this same preview path, so short "I am checking..." progress notes can stream into the editable draft without becoming part of the final answer. This keeps multi-step tool turns visually alive rather than silent between the first thinking preview and the final answer.
|
||||
|
||||
Long-running tools may emit typed progress before they return. For example,
|
||||
`web_fetch` arms a five-second timer when it starts: if the fetch is still
|
||||
pending, the preview can show `Fetching page content...`; if the fetch finishes
|
||||
or is canceled before then, no progress line is emitted. The later final tool
|
||||
result is still delivered normally to the model.
|
||||
|
||||
Supported surfaces:
|
||||
|
||||
- **Discord**, **Slack**, **Telegram**, and **Matrix** stream tool-progress and Codex preamble updates into the live preview edit by default when preview streaming is active. Microsoft Teams uses its native progress stream in personal chats.
|
||||
|
||||
@@ -53,8 +53,8 @@ Authoritative advertised **discovery** inventory lives in
|
||||
|
||||
## Where the schemas live
|
||||
|
||||
- Source: `packages/gateway-protocol/src/schema.ts`
|
||||
- Runtime validators (AJV): `packages/gateway-protocol/src/index.ts`
|
||||
- Source: `src/gateway/protocol/schema.ts`
|
||||
- Runtime validators (AJV): `src/gateway/protocol/index.ts`
|
||||
- Advertised feature/discovery registry: `src/gateway/server-methods-list.ts`
|
||||
- Server handshake + method dispatch: `src/gateway/server.impl.ts`
|
||||
- Node client: `src/gateway/client.ts`
|
||||
@@ -195,7 +195,7 @@ Example: add a new `system.echo` request that returns `{ ok: true, text }`.
|
||||
|
||||
1. **Schema (source of truth)**
|
||||
|
||||
Add to `packages/gateway-protocol/src/schema.ts`:
|
||||
Add to `src/gateway/protocol/schema.ts`:
|
||||
|
||||
```ts
|
||||
export const SystemEchoParamsSchema = Type.Object(
|
||||
@@ -223,7 +223,7 @@ export type SystemEchoResult = Static<typeof SystemEchoResultSchema>;
|
||||
|
||||
2. **Validation**
|
||||
|
||||
In `packages/gateway-protocol/src/index.ts`, export an AJV validator:
|
||||
In `src/gateway/protocol/index.ts`, export an AJV validator:
|
||||
|
||||
```ts
|
||||
export const validateSystemEchoParams = ajv.compile<SystemEchoParams>(SystemEchoParamsSchema);
|
||||
@@ -272,7 +272,7 @@ Unknown frame types are preserved as raw payloads for forward compatibility.
|
||||
|
||||
## Versioning + compatibility
|
||||
|
||||
- `PROTOCOL_VERSION` lives in `packages/gateway-protocol/src/version.ts`.
|
||||
- `PROTOCOL_VERSION` lives in `src/gateway/protocol/version.ts`.
|
||||
- Clients send `minProtocol` + `maxProtocol`; the server rejects ranges that
|
||||
do not include its current protocol.
|
||||
- The Swift models keep unknown frame types to avoid breaking older clients.
|
||||
|
||||
@@ -1228,7 +1228,6 @@
|
||||
"plugins/codex-native-plugins",
|
||||
"plugins/codex-computer-use",
|
||||
"plugins/google-meet",
|
||||
"plugins/workboard",
|
||||
"plugins/webhooks",
|
||||
"plugins/admin-http-rpc",
|
||||
"plugins/voice-call",
|
||||
|
||||
@@ -334,7 +334,7 @@ Higher values preserve more visual detail.
|
||||
Image-tool compression/detail preference for images loaded from file paths, URLs, and media references.
|
||||
Default: `auto`.
|
||||
|
||||
OpenClaw adapts the resize ladder to the selected image model. For example, Claude Opus 4.8, OpenAI GPT-5.5, Qwen VL, and hosted Llama 4 vision models can use larger images than older/default high-detail vision paths, while multi-image turns are compressed more aggressively in `auto` mode to control token and latency cost.
|
||||
OpenClaw adapts the resize ladder to the selected image model. For example, Claude Opus 4.7, OpenAI GPT-5.5, Qwen VL, and hosted Llama 4 vision models can use larger images than older/default high-detail vision paths, while multi-image turns are compressed more aggressively in `auto` mode to control token and latency cost.
|
||||
|
||||
Values:
|
||||
|
||||
@@ -483,7 +483,7 @@ Time format in system prompt. Default: `auto` (OS preference).
|
||||
defaults: {
|
||||
model: "openai/gpt-5.5",
|
||||
models: {
|
||||
"anthropic/claude-opus-4-8": {
|
||||
"anthropic/claude-opus-4-7": {
|
||||
agentRuntime: { id: "claude-cli" },
|
||||
},
|
||||
"vllm/*": {
|
||||
@@ -501,7 +501,7 @@ Time format in system prompt. Default: `auto` (OS preference).
|
||||
- Runtime precedence is exact model policy first (`agents.list[].models["provider/model"]`, `agents.defaults.models["provider/model"]`, or `models.providers.<provider>.models[]`), then `agents.list[]` / `agents.defaults.models["provider/*"]`, then provider-wide policy at `models.providers.<provider>.agentRuntime`.
|
||||
- Whole-agent runtime keys are legacy. `agents.defaults.agentRuntime`, `agents.list[].agentRuntime`, session runtime pins, and `OPENCLAW_AGENT_RUNTIME` are ignored by runtime selection. Run `openclaw doctor --fix` to remove stale values.
|
||||
- OpenAI agent models use the Codex harness by default; provider/model `agentRuntime.id: "codex"` remains valid when you want to make that explicit.
|
||||
- For Claude CLI deployments, prefer `model: "anthropic/claude-opus-4-8"` plus model-scoped `agentRuntime.id: "claude-cli"`. Legacy `claude-cli/claude-opus-4-7` model refs still work for compatibility, but new config should keep provider/model selection canonical and put the execution backend in provider/model runtime policy.
|
||||
- For Claude CLI deployments, prefer `model: "anthropic/claude-opus-4-7"` plus model-scoped `agentRuntime.id: "claude-cli"`. Legacy `claude-cli/claude-opus-4-7` model refs still work for compatibility, but new config should keep provider/model selection canonical and put the execution backend in provider/model runtime policy.
|
||||
- This only controls text agent-turn execution. Media generation, vision, PDF, music, video, and TTS still use their provider/model settings.
|
||||
|
||||
**Built-in alias shorthands** (only apply when the model is in `agents.defaults.models`):
|
||||
@@ -521,7 +521,7 @@ Your configured aliases always win over defaults.
|
||||
|
||||
Z.AI GLM-4.x models automatically enable thinking mode unless you set `--thinking off` or define `agents.defaults.models["zai/<model>"].params.thinking` yourself.
|
||||
Z.AI models enable `tool_stream` by default for tool call streaming. Set `agents.defaults.models["zai/<model>"].params.tool_stream` to `false` to disable it.
|
||||
Anthropic Claude Opus 4.8 keeps thinking off by default in OpenClaw; when adaptive thinking is explicitly enabled, Anthropic's provider-owned effort default is `high`. Claude 4.6 models default to `adaptive` when no explicit thinking level is set.
|
||||
Anthropic Claude 4.6 models default to `adaptive` thinking when no explicit thinking level is set.
|
||||
|
||||
### `agents.defaults.cliBackends`
|
||||
|
||||
@@ -1056,7 +1056,7 @@ for provider examples and precedence.
|
||||
params: { cacheRetention: "none" }, // overrides matching defaults.models params by key
|
||||
tts: {
|
||||
providers: {
|
||||
elevenlabs: { speakerVoiceId: "EXAVITQu4vr4xnSDxMaL" },
|
||||
elevenlabs: { voiceId: "EXAVITQu4vr4xnSDxMaL" },
|
||||
},
|
||||
},
|
||||
skills: ["docs-search"], // replaces agents.defaults.skills when set
|
||||
@@ -1415,7 +1415,7 @@ Batches rapid text-only messages from the same sender into a single agent turn.
|
||||
elevenlabs: {
|
||||
apiKey: "elevenlabs_api_key",
|
||||
baseUrl: "https://api.elevenlabs.io",
|
||||
speakerVoiceId: "voice_id",
|
||||
voiceId: "voice_id",
|
||||
modelId: "eleven_multilingual_v2",
|
||||
seed: 42,
|
||||
applyTextNormalization: "auto",
|
||||
@@ -1429,7 +1429,7 @@ Batches rapid text-only messages from the same sender into a single agent turn.
|
||||
},
|
||||
},
|
||||
microsoft: {
|
||||
speakerVoice: "en-US-AvaMultilingualNeural",
|
||||
voice: "en-US-AvaMultilingualNeural",
|
||||
lang: "en-US",
|
||||
outputFormat: "audio-24khz-48kbitrate-mono-mp3",
|
||||
},
|
||||
@@ -1437,7 +1437,7 @@ Batches rapid text-only messages from the same sender into a single agent turn.
|
||||
apiKey: "openai_api_key",
|
||||
baseUrl: "https://api.openai.com/v1",
|
||||
model: "gpt-4o-mini-tts",
|
||||
speakerVoice: "alloy",
|
||||
voice: "alloy",
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -1465,7 +1465,7 @@ Defaults for Talk mode (macOS/iOS/Android).
|
||||
provider: "elevenlabs",
|
||||
providers: {
|
||||
elevenlabs: {
|
||||
speakerVoiceId: "elevenlabs_voice_id",
|
||||
voiceId: "elevenlabs_voice_id",
|
||||
voiceAliases: {
|
||||
Clawd: "EXAVITQu4vr4xnSDxMaL",
|
||||
Roger: "CwhRBWXzGAHq8TQ4Fs17",
|
||||
@@ -1489,7 +1489,7 @@ Defaults for Talk mode (macOS/iOS/Android).
|
||||
providers: {
|
||||
openai: {
|
||||
model: "gpt-realtime-2",
|
||||
speakerVoice: "cedar",
|
||||
voice: "cedar",
|
||||
},
|
||||
},
|
||||
instructions: "Speak warmly and keep answers brief.",
|
||||
|
||||
@@ -488,8 +488,7 @@ Configuring a custom/local provider `baseUrl` is also the narrow network trust d
|
||||
- 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.
|
||||
- Provider-plugin catalogs are stored as generated plugin-owned catalog shards under the agent's plugin state.
|
||||
- Use `models.mode: "replace"` when you want config to fully rewrite `models.json` and active plugin catalog shards.
|
||||
- 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.
|
||||
|
||||
</Accordion>
|
||||
|
||||
@@ -1268,11 +1268,11 @@ Current builds no longer include the TCP bridge. Nodes connect over the Gateway
|
||||
}
|
||||
```
|
||||
|
||||
- `maxAttempts`: maximum retries for cron jobs on transient errors (default: `3`; range: `0`-`10`).
|
||||
- `maxAttempts`: maximum retries for one-shot jobs on transient errors (default: `3`; range: `0`-`10`).
|
||||
- `backoffMs`: array of backoff delays in ms for each retry attempt (default: `[30000, 60000, 300000]`; 1-10 entries).
|
||||
- `retryOn`: error types that trigger retries - `"rate_limit"`, `"overloaded"`, `"network"`, `"timeout"`, `"server_error"`. Omit to retry all transient types.
|
||||
|
||||
One-shot jobs stay enabled until retry attempts are exhausted, then disable while keeping the final error state. Recurring jobs use the same transient retry policy to run again after backoff before their next scheduled slot; permanent errors or exhausted transient retries fall back to the normal recurring schedule with error backoff.
|
||||
Applies only to one-shot cron jobs. Recurring jobs use separate failure handling.
|
||||
|
||||
### `cron.failureAlert`
|
||||
|
||||
|
||||
@@ -264,7 +264,6 @@ That stages grounded durable candidates into the short-term dreaming store while
|
||||
- `routing.transcribeAudio` → `tools.media.audio.models`
|
||||
- `messages.tts.<provider>` (`openai`/`elevenlabs`/`microsoft`/`edge`) → `messages.tts.providers.<provider>`
|
||||
- `messages.tts.provider: "edge"` and `messages.tts.providers.edge` → `messages.tts.provider: "microsoft"` and `messages.tts.providers.microsoft`
|
||||
- TTS speaker selection fields (`voice`/`voiceName`/`voiceId`) → `speakerVoice`/`speakerVoiceId`
|
||||
- `channels.discord.voice.tts.<provider>` (`openai`/`elevenlabs`/`microsoft`/`edge`) → `channels.discord.voice.tts.providers.<provider>`
|
||||
- `channels.discord.accounts.<id>.voice.tts.<provider>` (`openai`/`elevenlabs`/`microsoft`/`edge`) → `channels.discord.accounts.<id>.voice.tts.providers.<provider>`
|
||||
- `plugins.entries.voice-call.config.tts.<provider>` (`openai`/`elevenlabs`/`microsoft`/`edge`) → `plugins.entries.voice-call.config.tts.providers.<provider>`
|
||||
@@ -374,8 +373,6 @@ That stages grounded durable candidates into the short-term dreaming store while
|
||||
- payload `provider` delivery aliases → explicit `delivery.channel`
|
||||
- simple legacy `notify: true` webhook fallback jobs → explicit `delivery.mode="webhook"` with `delivery.to=cron.webhook`
|
||||
|
||||
The Gateway also sanitizes malformed cron rows at load time so valid jobs keep running. Raw malformed rows are copied to `jobs-quarantine.json` next to the active store before they are removed from `jobs.json`; doctor reports quarantined rows so you can review or repair them manually.
|
||||
|
||||
Doctor only auto-migrates `notify: true` jobs when it can do so without changing behavior. If a job combines legacy notify fallback with an existing non-webhook delivery mode, doctor warns and leaves that job for manual review.
|
||||
|
||||
On Linux, doctor also warns when the user's crontab still invokes legacy `~/.openclaw/bin/ensure-whatsapp.sh`. That host-local script is not maintained by current OpenClaw and can write false `Gateway inactive` messages to `~/.openclaw/logs/whatsapp-health.log` when cron cannot reach the systemd user bus. Remove the stale crontab entry with `crontab -e`; use `openclaw channels status --probe`, `openclaw doctor`, and `openclaw gateway status` for current health checks.
|
||||
|
||||
@@ -315,7 +315,7 @@ If the model loads cleanly but full agent turns misbehave, work top-down — con
|
||||
openclaw infer model run --gateway --model <provider/model> --prompt "Reply with exactly: pong" --json
|
||||
```
|
||||
|
||||
3. **Try lean mode.** If both probes pass but real agent turns fail with malformed tool calls or oversized prompts, enable `agents.defaults.experimental.localModelLean: true`. It drops the three heaviest default tools (`browser`, `cron`, `message`) from the visible model surface so the prompt shape is smaller and less brittle. When Code Mode or Tool Search is enabled, those tools can still sit behind the compact catalog controls. See [Experimental Features → Local model lean mode](/concepts/experimental-features#local-model-lean-mode) for the full explanation, when to use it, and how to confirm it is on.
|
||||
3. **Try lean mode.** If both probes pass but real agent turns fail with malformed tool calls or oversized prompts, enable `agents.defaults.experimental.localModelLean: true`. It drops the three heaviest default tools (`browser`, `cron`, `message`) so the prompt shape is smaller and less brittle. See [Experimental Features → Local model lean mode](/concepts/experimental-features#local-model-lean-mode) for the full explanation, when to use it, and how to confirm it is on.
|
||||
|
||||
4. **Disable tools entirely as a last resort.** If lean mode is not enough, set `models.providers.<provider>.models[].compat.supportsTools: false` for that model entry. The agent will then operate without tool calls on that model.
|
||||
|
||||
|
||||
@@ -104,7 +104,7 @@ within their overall connection budget instead of surfacing it as a terminal
|
||||
handshake failure.
|
||||
|
||||
`server`, `features`, `snapshot`, and `policy` are all required by the schema
|
||||
(`packages/gateway-protocol/src/schema/frames.ts`). `auth` is also required and reports
|
||||
(`src/gateway/protocol/schema/frames.ts`). `auth` is also required and reports
|
||||
the negotiated role/scopes. `pluginSurfaceUrls` is optional and maps plugin
|
||||
surface names, such as `canvas`, to scoped hosted URLs.
|
||||
|
||||
@@ -648,7 +648,7 @@ terminal summary, and sanitized error text.
|
||||
|
||||
## Versioning
|
||||
|
||||
- `PROTOCOL_VERSION` lives in `packages/gateway-protocol/src/version.ts`.
|
||||
- `PROTOCOL_VERSION` lives in `src/gateway/protocol/version.ts`.
|
||||
- Clients send `minProtocol` + `maxProtocol`; the server rejects ranges that
|
||||
do not include its current protocol. Current clients and servers require
|
||||
protocol v4.
|
||||
@@ -664,8 +664,8 @@ stable across protocol v4 and are the expected baseline for third-party clients.
|
||||
|
||||
| Constant | Default | Source |
|
||||
| ----------------------------------------- | ----------------------------------------------------- | ------------------------------------------------------------------------------------------ |
|
||||
| `PROTOCOL_VERSION` | `4` | `packages/gateway-protocol/src/version.ts` |
|
||||
| `MIN_CLIENT_PROTOCOL_VERSION` | `4` | `packages/gateway-protocol/src/version.ts` |
|
||||
| `PROTOCOL_VERSION` | `4` | `src/gateway/protocol/version.ts` |
|
||||
| `MIN_CLIENT_PROTOCOL_VERSION` | `4` | `src/gateway/protocol/version.ts` |
|
||||
| Request timeout (per RPC) | `30_000` ms | `src/gateway/client.ts` (`requestTimeoutMs`) |
|
||||
| Preauth / connect-challenge timeout | `15_000` ms | `src/gateway/handshake-timeouts.ts` (config/env can raise the paired server/client budget) |
|
||||
| Initial reconnect backoff | `1_000` ms | `src/gateway/client.ts` (`backoffMs`) |
|
||||
@@ -818,7 +818,7 @@ Migration target:
|
||||
|
||||
This protocol exposes the **full gateway API** (status, channels, models, chat,
|
||||
agent, sessions, nodes, approvals, etc.). The exact surface is defined by the
|
||||
TypeBox schemas in `packages/gateway-protocol/src/schema.ts`.
|
||||
TypeBox schemas in `src/gateway/protocol/schema.ts`.
|
||||
|
||||
## Related
|
||||
|
||||
|
||||
@@ -282,7 +282,7 @@ troubleshooting, see the main [FAQ](/help/faq).
|
||||
<Accordion title="Are opus / sonnet / gpt built-in shortcuts?">
|
||||
Yes. OpenClaw ships a few default shorthands (only applied when the model exists in `agents.defaults.models`):
|
||||
|
||||
- `opus` → `anthropic/claude-opus-4-8`
|
||||
- `opus` → `anthropic/claude-opus-4-7`
|
||||
- `sonnet` → `anthropic/claude-sonnet-4-6`
|
||||
- `gpt` → `openai/gpt-5.4`
|
||||
- `gpt-mini` → `openai/gpt-5.4-mini`
|
||||
@@ -536,11 +536,7 @@ Related: [/concepts/oauth](/concepts/oauth) (OAuth flows, token storage, multi-a
|
||||
<Accordion title="OAuth vs API key - what is the difference?">
|
||||
OpenClaw supports both:
|
||||
|
||||
- **OAuth / CLI login** often leverages subscription access where the
|
||||
provider supports it. For Anthropic, OpenClaw's Claude CLI backend uses
|
||||
Claude Code `claude -p`; Anthropic currently treats that as Agent
|
||||
SDK/programmatic usage, with a separate monthly Agent SDK credit starting
|
||||
June 15, 2026.
|
||||
- **OAuth** often leverages subscription access (where applicable).
|
||||
- **API keys** use pay-per-token billing.
|
||||
|
||||
The wizard explicitly supports Anthropic Claude CLI, OpenAI Codex OAuth, and API keys.
|
||||
|
||||
@@ -109,9 +109,7 @@ docker compose up -d openclaw-gateway
|
||||
<Note>
|
||||
Run `docker compose` from the repo root. If you enabled `OPENCLAW_EXTRA_MOUNTS`
|
||||
or `OPENCLAW_HOME_VOLUME`, the setup script writes `docker-compose.extra.yml`;
|
||||
include it after any standard override file, for example
|
||||
`-f docker-compose.yml -f docker-compose.override.yml -f docker-compose.extra.yml`
|
||||
when both override files exist.
|
||||
include it with `-f docker-compose.yml -f docker-compose.extra.yml`.
|
||||
</Note>
|
||||
|
||||
<Note>
|
||||
|
||||
205
docs/plan/policy-agent-scoped-overlays.md
Normal file
205
docs/plan/policy-agent-scoped-overlays.md
Normal file
@@ -0,0 +1,205 @@
|
||||
---
|
||||
summary: "Per-agent Policy plugin overlays layered on top of global policy rules."
|
||||
read_when:
|
||||
- You are designing per-agent policy requirements
|
||||
- You need to distinguish tool posture policy from workspace policy
|
||||
- You are configuring stricter policy for one named agent
|
||||
title: "Agent-scoped policy overlays"
|
||||
---
|
||||
|
||||
# Agent-scoped policy overlays
|
||||
|
||||
OpenClaw policy supports global requirements and stricter requirements for
|
||||
explicit runtime agent ids. Some deployments need one agent to use a tighter
|
||||
workspace and tool posture than other agents, but deployment-wide rules should
|
||||
not force every agent to use the same posture.
|
||||
|
||||
This page describes the agent-scoped overlay model. The field reference remains
|
||||
[`openclaw policy`](/cli/policy).
|
||||
|
||||
## Design goals
|
||||
|
||||
- Keep global policy as the deployment baseline.
|
||||
- Let a named agent add stricter requirements without weakening global rules.
|
||||
- Reuse existing policy section shapes where the evidence can be attributed to
|
||||
an agent.
|
||||
- Avoid making `agents.workspace` a second tool-permission system.
|
||||
- Leave global-only checks global until their evidence can be mapped to an
|
||||
agent.
|
||||
|
||||
## Shape
|
||||
|
||||
Use `scopes.<scopeName>` for purpose-named agent policy scopes. Each
|
||||
scope lists the runtime `agentIds` it applies to, then reuses the normal
|
||||
top-level policy section grammar where the section evidence can be attributed to
|
||||
those agents. The initial shipped scoped sections are `tools` and
|
||||
`agents.workspace`; sandbox and ingress stay out of this PR and can join the
|
||||
same container once those policy PRs land and their evidence carries agent
|
||||
identity. The scoped field inventory is backed by policy rule metadata that
|
||||
records each field's strictness semantics for later policy-file conformance.
|
||||
|
||||
```jsonc
|
||||
{
|
||||
"tools": {
|
||||
"denyTools": ["process"],
|
||||
},
|
||||
"agents": {
|
||||
"workspace": {
|
||||
"allowedAccess": ["none", "ro"],
|
||||
},
|
||||
},
|
||||
"scopes": {
|
||||
"release-agent-lockdown": {
|
||||
"agentIds": ["release-agent"],
|
||||
"agents": {
|
||||
"workspace": {
|
||||
"allowedAccess": ["none", "ro"],
|
||||
},
|
||||
},
|
||||
"tools": {
|
||||
"profiles": { "allow": ["minimal", "messaging"] },
|
||||
"fs": { "requireWorkspaceOnly": true },
|
||||
"exec": {
|
||||
"allowSecurity": ["deny", "allowlist"],
|
||||
"requireAsk": ["always"],
|
||||
"allowHosts": ["sandbox"],
|
||||
},
|
||||
"elevated": { "allow": false },
|
||||
"alsoAllow": { "expected": ["message", "read"] },
|
||||
"denyTools": ["exec", "process", "write", "edit", "apply_patch"],
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
`agents.workspace` remains the existing all-agent workspace baseline.
|
||||
`scopes.<scopeName>` is a scoped overlay, not a replacement for global
|
||||
policy. The scope name is descriptive only; matching uses `agentIds`, not
|
||||
display names. It deliberately contains normal section names instead of a
|
||||
bespoke per-agent mini-grammar.
|
||||
Every scope present in `policy.jsonc` must be valid and enforceable. In this
|
||||
PR, the only supported selector is `agentIds`, and it supports only `tools.*`
|
||||
and `agents.workspace.*`.
|
||||
|
||||
## Layering semantics
|
||||
|
||||
Policy evaluation is additive:
|
||||
|
||||
1. Top-level policy applies to all matching evidence.
|
||||
2. Existing `agents.workspace` applies to defaults and every listed agent.
|
||||
3. `scopes.<scopeName>` applies to evidence for each normalized runtime
|
||||
id in `agentIds`.
|
||||
4. Multiple scope blocks may target the same agent when they govern
|
||||
different fields, or when a later value for the same field is equally or
|
||||
more restrictive according to policy metadata.
|
||||
5. A named-agent overlay can tighten policy, but it cannot make a global
|
||||
violation acceptable.
|
||||
|
||||
If both global and agent-scoped rules fail, findings should point at the rule
|
||||
that was violated:
|
||||
|
||||
```text
|
||||
oc://policy.jsonc/tools/denyTools
|
||||
oc://policy.jsonc/scopes/release-agent-lockdown/tools/denyTools
|
||||
oc://policy.jsonc/scopes/release-agent-lockdown/agents/workspace/allowedAccess
|
||||
```
|
||||
|
||||
That keeps broad tool posture, named-agent tool posture, and workspace posture
|
||||
auditable as separate requirements even when they observe the same config
|
||||
fields.
|
||||
|
||||
Exact-list claims such as `tools.alsoAllow.expected` compare the configured list
|
||||
to the expected list and report both missing expected entries and unexpected
|
||||
extra entries. This is intended for additive posture such as `alsoAllow`, where
|
||||
one extra entry can widen an agent beyond its reviewed role.
|
||||
|
||||
## Policy and config layering
|
||||
|
||||
The overlay model separates where policy is authored from where OpenClaw config
|
||||
is observed:
|
||||
|
||||
| Policy scope | Observed config | Applies to | Example result |
|
||||
| --------------------------------------- | ---------------------------------------------------- | --------------------------------- | ----------------------------------------------------------------------------- |
|
||||
| Top-level `tools.*` | Global `tools.*` and inherited agent tool posture | All agents using matching posture | Deny `gateway` exec host for every agent unless the global policy allows it. |
|
||||
| Top-level `tools.*` | `agents.list[].tools.*` overrides | Any agent with an override | Flag one agent that overrides `tools.exec.host` to an unapproved value. |
|
||||
| `scopes.<scopeName>.tools.*` | Matching `agents.list[]` entry and inherited posture | Only that named agent | Let most agents use `node` exec host while one agent must use only `sandbox`. |
|
||||
| `agents.workspace` | Defaults and every listed agent workspace posture | Defaults and all listed agents | Require every agent workspace access to be `none` or `ro`. |
|
||||
| `scopes.<scopeName>.agents.workspace.*` | Matching `agents.list[]` workspace posture | Only that named agent | Require one agent to be read-only without requiring the same for `main`. |
|
||||
|
||||
Per-agent overlays are additive. A named-agent rule can be stricter than the
|
||||
top-level rule, but it cannot make a global violation acceptable. For allow-list
|
||||
rules, the effective allowed set is the intersection of the global rule and the
|
||||
named-agent overlay when both are present.
|
||||
|
||||
For example, if top-level `tools.exec.allowHosts` permits `["sandbox", "node"]`
|
||||
and `scopes.release-agent-lockdown.tools.exec.allowHosts` permits only
|
||||
`["sandbox"]`, `release-agent` fails when its effective exec host is `node`;
|
||||
another agent can still pass
|
||||
with `node`.
|
||||
|
||||
## Tool posture versus workspace posture
|
||||
|
||||
Tool posture belongs under `tools` because it describes what tool behavior a
|
||||
configuration may expose. The existing `tools.*` policy observes both global
|
||||
`tools.*` config and per-agent `agents.list[].tools.*` overrides.
|
||||
|
||||
Workspace posture belongs under `workspace` because it describes sandbox mode
|
||||
and workspace access. The workspace section should not grow into a general tool
|
||||
policy namespace. If one agent needs stricter tool restrictions to make its
|
||||
workspace posture meaningful, put those restrictions in the same agent overlay
|
||||
under `scopes.<scopeName>.tools`.
|
||||
|
||||
For a restricted release agent, the intended split is:
|
||||
|
||||
```jsonc
|
||||
{
|
||||
"scopes": {
|
||||
"release-agent-lockdown": {
|
||||
"agentIds": ["release-agent"],
|
||||
"agents": {
|
||||
"workspace": { "allowedAccess": ["none", "ro"] },
|
||||
},
|
||||
"tools": {
|
||||
"denyTools": ["exec", "process", "write", "edit", "apply_patch"],
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
## Section eligibility
|
||||
|
||||
An agent-scoped section should be added only when policy evidence carries an
|
||||
agent id or can be attributed to one without guessing.
|
||||
|
||||
| Section | Initial agent-scoped status | Reason |
|
||||
| ----------- | --------------------------- | ------------------------------------------------------------------------ |
|
||||
| `workspace` | Include | Agent sandbox/workspace evidence already has agent identity. |
|
||||
| `tools` | Include | Tool posture evidence includes global and per-agent tool config. |
|
||||
| `sandbox` | Pipeline follow-up | Keep out until the sandbox posture PR lands and evidence can be scoped. |
|
||||
| `ingress` | Pipeline follow-up | Keep out until ingress/channel posture lands with agent attribution. |
|
||||
| `models` | Include when mapped | Selected model refs can be agent-specific. |
|
||||
| `mcp` | Include when mapped | Use only when MCP server evidence is attributable to an agent. |
|
||||
| `auth` | Defer | Auth profile metadata is a config catalog unless agent binding is clear. |
|
||||
| `channels` | Defer | Channel provider posture is deployment-level until routing is scoped. |
|
||||
| `gateway` | Keep global | Gateway exposure/auth/http posture is process-level. |
|
||||
| `network` | Keep global | Private-network SSRF posture is runtime-level. |
|
||||
| `secrets` | Keep global first | Secret provider posture is shared unless refs are agent-attributed. |
|
||||
|
||||
## Compatibility
|
||||
|
||||
The implementation is additive:
|
||||
|
||||
- keep all existing top-level policy fields valid;
|
||||
- keep `agents.workspace` semantics unchanged;
|
||||
- validate `scopes` before evaluating scoped rules;
|
||||
- reject unsupported scoped sections clearly until their evidence and policy
|
||||
contracts are implemented;
|
||||
- do not reinterpret top-level `tools.requireMetadata` as agent-scoped, because
|
||||
tool metadata describes the declared workspace tool catalog;
|
||||
- include agent-scoped evidence in the attestation hash when any scoped rule is
|
||||
present.
|
||||
|
||||
This lets broad tool posture remain a top-level policy contract while named
|
||||
agents add stricter observable claims without weakening the global baseline.
|
||||
@@ -118,11 +118,7 @@ prompts that nobody is around to answer.
|
||||
|
||||
If Codex's local system requirements file disallows implicit YOLO approval,
|
||||
reviewer, or sandbox values, OpenClaw treats the implicit default as guardian
|
||||
instead and selects allowed guardian permissions. `tools.exec.mode: "auto"`
|
||||
also forces guardian-reviewed Codex approvals and does not preserve unsafe
|
||||
legacy `approvalPolicy: "never"` or `sandbox: "danger-full-access"` overrides;
|
||||
set `tools.exec.mode: "full"` for an intentional no-approval posture.
|
||||
Hostname-matching
|
||||
instead and selects allowed guardian permissions. Hostname-matching
|
||||
`[[remote_sandbox_config]]` entries in the same requirements file are honored
|
||||
for the sandbox default decision.
|
||||
|
||||
|
||||
@@ -362,35 +362,30 @@ turn instead of relying on Codex host-side sandboxing. Shell access is exposed
|
||||
through OpenClaw sandbox-backed dynamic tools such as `sandbox_exec` and
|
||||
`sandbox_process` when the normal exec/process tools are available.
|
||||
|
||||
Use normalized OpenClaw exec mode when you want Codex native auto-review before
|
||||
sandbox escapes or extra permissions:
|
||||
Use guardian mode when you want Codex native auto-review before sandbox escapes
|
||||
or extra permissions:
|
||||
|
||||
```json5
|
||||
{
|
||||
tools: {
|
||||
exec: {
|
||||
mode: "auto",
|
||||
},
|
||||
},
|
||||
plugins: {
|
||||
entries: {
|
||||
codex: {
|
||||
enabled: true,
|
||||
config: {
|
||||
appServer: {
|
||||
mode: "guardian",
|
||||
serviceTier: "priority",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
For Codex app-server sessions, OpenClaw maps `tools.exec.mode: "auto"` to Codex
|
||||
Guardian-reviewed approvals, usually
|
||||
Guardian mode expands to Codex app-server approvals, usually
|
||||
`approvalPolicy: "on-request"`, `approvalsReviewer: "auto_review"`, and
|
||||
`sandbox: "workspace-write"` when the local requirements allow those values.
|
||||
In `tools.exec.mode: "auto"`, OpenClaw does not preserve legacy unsafe Codex
|
||||
`approvalPolicy: "never"` or `sandbox: "danger-full-access"` overrides; use
|
||||
`tools.exec.mode: "full"` for an intentional no-approval Codex posture. The
|
||||
legacy `plugins.entries.codex.config.appServer.mode: "guardian"` preset still
|
||||
works, but `tools.exec.mode: "auto"` is the normalized OpenClaw surface.
|
||||
|
||||
For every app-server field, auth order, environment isolation, discovery, and
|
||||
timeout behavior, see [Codex harness reference](/plugins/codex-harness-reference).
|
||||
|
||||
@@ -1,374 +0,0 @@
|
||||
---
|
||||
summary: "Run OpenClaw embedded agent turns through the bundled GitHub Copilot SDK harness"
|
||||
title: "Copilot SDK harness"
|
||||
read_when:
|
||||
- You want to use the bundled GitHub Copilot SDK harness for an agent
|
||||
- You need configuration examples for the `copilot` runtime
|
||||
- You are wiring an agent to subscription Copilot (github / openclaw / copilot) and want it to run through the Copilot CLI
|
||||
---
|
||||
|
||||
The bundled `copilot` extension lets OpenClaw run embedded subscription
|
||||
Copilot agent turns through the GitHub Copilot CLI (`@github/copilot-sdk`)
|
||||
instead of the built-in PI harness.
|
||||
|
||||
Use the Copilot SDK harness when you want the Copilot CLI session to own the
|
||||
low-level agent loop: native tool execution, native compaction
|
||||
(`infiniteSessions`), and CLI-managed thread state under `copilotHome`.
|
||||
OpenClaw still owns chat channels, session files, model selection, OpenClaw
|
||||
dynamic tools (bridged), approvals, media delivery, the visible transcript
|
||||
mirror, `/btw` side questions (handled by the in-tree PI fallback — see
|
||||
[Side questions (`/btw`)](#side-questions-btw)), and `openclaw doctor`.
|
||||
|
||||
For the broader model/provider/runtime split, start with
|
||||
[Agent runtimes](/concepts/agent-runtimes).
|
||||
|
||||
## Requirements
|
||||
|
||||
- OpenClaw with the bundled `copilot` extension available.
|
||||
- If your config uses `plugins.allow`, include `copilot` (the manifest
|
||||
id in `extensions/copilot/openclaw.plugin.json`). A restrictive
|
||||
allowlist that uses the npm-style `@openclaw/copilot` package name
|
||||
will leave the bundled plugin blocked and the runtime will not load
|
||||
even with `agentRuntime.id: "copilot"`.
|
||||
- A GitHub Copilot subscription that can drive the Copilot CLI (or a
|
||||
`gitHubToken` env / auth-profile entry for headless / cron runs).
|
||||
- A writable `copilotHome` directory. The harness defaults to
|
||||
`~/.openclaw/agents/<agentId>/copilot` for full per-agent isolation. The
|
||||
platform default (`%APPDATA%\copilot` on Windows, `$XDG_CONFIG_HOME/copilot`
|
||||
or `~/.config/copilot` elsewhere) is used as the doctor probe fallback when
|
||||
no explicit home is set.
|
||||
|
||||
`openclaw doctor` runs the bundled
|
||||
[doctor contract](#doctor-and-probes) for the extension; failures there are
|
||||
the canonical way to confirm the environment is ready before opting an agent
|
||||
in.
|
||||
|
||||
## On-demand SDK install
|
||||
|
||||
The Copilot agent runtime ships its small TypeScript code bundled inside
|
||||
the openclaw tarball, but the underlying `@github/copilot-sdk` package
|
||||
(and its platform-specific `@github/copilot-<platform>-<arch>` CLI
|
||||
binary) is **not** installed by default — together they add ~260 MB to
|
||||
your openclaw install footprint, and most openclaw users do not select
|
||||
a Copilot model.
|
||||
|
||||
The wizard offers to install the SDK the first time you select a
|
||||
`github-copilot/*` model **and** your config opts the model (or its
|
||||
provider) into the Copilot agent runtime via
|
||||
`agentRuntime: { id: "copilot" }` (see [Quickstart](#quickstart) below).
|
||||
Without the opt-in, openclaw uses its built-in GitHub Copilot provider
|
||||
and never prompts for the SDK install:
|
||||
|
||||
```
|
||||
The Copilot agent runtime needs @github/copilot-sdk (~260 MB on first
|
||||
install, downloads the @github/copilot CLI binary for your platform).
|
||||
Install now? [Y/n]
|
||||
```
|
||||
|
||||
If you accept, the SDK is installed into
|
||||
`~/.openclaw/npm-runtime/copilot/` and detected on subsequent runs. The
|
||||
install runs `npm ci` against a checked-in `package-lock.json` shipped
|
||||
with openclaw at
|
||||
`src/commands/copilot-sdk-install-manifest/package-lock.json`, so the
|
||||
exact transitive graph reviewed for this release lands on disk on every
|
||||
user machine.
|
||||
|
||||
If you decline, the runtime will fail at first invocation with an
|
||||
actionable install message; re-run `openclaw setup` to retry the install
|
||||
(or copy the pinned manifest into `~/.openclaw/npm-runtime/copilot/` and
|
||||
run `npm ci` yourself if you need to install offline).
|
||||
|
||||
The runtime resolves the SDK in this order:
|
||||
|
||||
1. `import("@github/copilot-sdk")` against the host openclaw install
|
||||
(covers source/dev checkouts and any environment that pre-installs
|
||||
the SDK alongside openclaw).
|
||||
2. The well-known fallback dir `~/.openclaw/npm-runtime/copilot/` (the
|
||||
wizard install target).
|
||||
|
||||
A missing SDK surfaces a single error with code `COPILOT_SDK_MISSING`
|
||||
and the manual install command above.
|
||||
|
||||
## Quickstart
|
||||
|
||||
Pin one model (or one provider) to the harness:
|
||||
|
||||
```json5
|
||||
{
|
||||
agents: {
|
||||
defaults: {
|
||||
model: "github-copilot/gpt-5.5",
|
||||
models: {
|
||||
"github-copilot/gpt-5.5": {
|
||||
agentRuntime: { id: "copilot" },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
Both routes are equivalent. Use `agentRuntime.id` on a single model entry
|
||||
when only that model should be routed through the harness; set
|
||||
`agentRuntime.id` on a provider when every model under that provider should
|
||||
use it.
|
||||
|
||||
## Supported providers
|
||||
|
||||
The harness advertises support for the canonical `github-copilot` provider
|
||||
(the same id owned by `extensions/github-copilot`):
|
||||
|
||||
- `github-copilot`
|
||||
|
||||
Anything outside that set falls through `selection.ts`'s `auto_pi` branch back
|
||||
to PI.
|
||||
|
||||
## Auth
|
||||
|
||||
Per-agent precedence, applied during `runCopilotAttempt`:
|
||||
|
||||
1. **Explicit `useLoggedInUser: true`** on the attempt input. Uses the Copilot
|
||||
CLI's logged-in user resolved under the agent's `copilotHome`.
|
||||
2. **Explicit `gitHubToken`** on the attempt input (with `profileId` +
|
||||
`profileVersion`). Useful for direct CLI invocations and tests where the
|
||||
caller wants to bypass auth-profile resolution.
|
||||
3. **Contract-resolved `resolvedApiKey` + `authProfileId`** from the
|
||||
`EmbeddedRunAttemptParams` shape. This is the **production main path**:
|
||||
core resolves the agent's configured `github-copilot` auth profile
|
||||
(via `src/infra/provider-usage.auth.ts:resolveProviderAuths`) before
|
||||
invoking the harness, and the harness consumes both fields directly.
|
||||
This makes a `github-copilot:<profile>` auth profile work end-to-end
|
||||
for headless / cron / multi-profile setups without env vars.
|
||||
4. **Env-var fallback** for direct CLI / dogfood runs where no auth
|
||||
profile is configured. The runtime checks the following vars in
|
||||
precedence order, mirroring the shipped `github-copilot` provider
|
||||
(`extensions/github-copilot/auth.ts`) and the documented Copilot SDK
|
||||
setup:
|
||||
1. `OPENCLAW_GITHUB_TOKEN` -- harness-specific override; set this
|
||||
to pin a token for the OpenClaw harness without disturbing
|
||||
system-wide `gh` / Copilot CLI config.
|
||||
2. `COPILOT_GITHUB_TOKEN` -- standard Copilot SDK / CLI env var.
|
||||
3. `GH_TOKEN` -- standard `gh` CLI env var (matches the existing
|
||||
`github-copilot` provider precedence).
|
||||
4. `GITHUB_TOKEN` -- generic GitHub token fallback.
|
||||
|
||||
The first non-empty value wins; empty strings are treated as
|
||||
absent. The synthesised pool profile id is `env:<NAME>` and the
|
||||
profileVersion is a non-reversible sha256 fingerprint of the
|
||||
token, so rotating the env value cleanly busts the client pool.
|
||||
|
||||
5. **Default `useLoggedInUser`** when no token signal is available.
|
||||
|
||||
Each agent gets a dedicated `copilotHome` so Copilot CLI tokens, sessions, and
|
||||
config do not leak between agents on the same machine. The default is
|
||||
`<agentDir>/copilot` when the host hands the harness an agent directory
|
||||
(isolating SDK state from OpenClaw's `models.json` / `auth-profiles.json` in
|
||||
the same directory), or `~/.openclaw/agents/<agentId>/copilot` otherwise.
|
||||
Override with `copilotHome: <path>` on the attempt input when you need a
|
||||
custom location (for example, a shared mount for migration).
|
||||
|
||||
`probeCopilotAuthShape` (see [Doctor and probes](#doctor-and-probes)) is the
|
||||
pure shape check that validates which of the modes above will be used.
|
||||
It does not perform a live SDK handshake.
|
||||
|
||||
## Configuration surface
|
||||
|
||||
The harness reads its config from per-attempt input
|
||||
(`runCopilotAttempt({...})`) plus a small set of env defaults inside
|
||||
`extensions/copilot/src/`:
|
||||
|
||||
- `copilotHome` — per-agent CLI state directory (defaults documented above).
|
||||
- `model` — string or `{ provider, id, api? }`. When omitted, OpenClaw uses
|
||||
the agent's normal model selection and the harness verifies the resolved
|
||||
provider is in the supported set.
|
||||
- `reasoningEffort` — `"low" | "medium" | "high" | "xhigh"`. Maps from
|
||||
OpenClaw's `ThinkLevel` / `ReasoningLevel` resolution in
|
||||
`auto-reply/thinking.ts`.
|
||||
- `infiniteSessionConfig` — optional override for the SDK
|
||||
`infiniteSessions` block driven by `harness.compact`. Defaults are safe to
|
||||
leave as-is.
|
||||
- `hooksConfig` — optional bridge config exposing OpenClaw
|
||||
before/after-message-write hooks to the SDK loop.
|
||||
- `permissionPolicy` — optional override for the SDK's
|
||||
`onPermissionRequest` handler used for built-in SDK tool kinds
|
||||
(`shell`, `write`, `read`, `url`, `mcp`, `memory`, `hook`). Defaults
|
||||
to `rejectAllPolicy` as a safety net; in practice the SDK never
|
||||
invokes any of those kinds because every bridged OpenClaw tool is
|
||||
registered with `overridesBuiltInTool: true` and
|
||||
`skipPermission: true` so 100% of tool calls flow through OpenClaw's
|
||||
wrapped `execute()`. See [Permissions and ask_user](#permissions-and-ask_user).
|
||||
- `enableSessionTelemetry` — opt-in OpenTelemetry routing via
|
||||
`telemetry-bridge.ts`.
|
||||
|
||||
Nothing in the rest of OpenClaw needs to know about these fields. Other
|
||||
plugins, channels, and core code only see the standard
|
||||
`AgentHarnessAttemptParams` / `AgentHarnessAttemptResult` shape.
|
||||
|
||||
## Compaction
|
||||
|
||||
When `harness.compact` runs, the Copilot SDK harness:
|
||||
|
||||
1. Enables `infiniteSessions` on the SDK session.
|
||||
2. Lets the SDK perform its native compaction.
|
||||
3. Writes an OpenClaw-shaped marker at
|
||||
`workspacePath/files/openclaw-compaction-<ts>.json` so existing OpenClaw
|
||||
transcript readers still see a familiar artifact.
|
||||
|
||||
The OpenClaw side transcript mirror (see below) continues to receive the
|
||||
post-compaction messages, so user-facing chat history stays consistent.
|
||||
|
||||
## Transcript mirroring
|
||||
|
||||
`runCopilotAttempt` dual-writes each turn's mirrorable messages into the
|
||||
OpenClaw audit transcript via
|
||||
`extensions/copilot/src/dual-write-transcripts.ts`. The mirror is
|
||||
per-session scoped (`copilot:${sessionId}`) and uses a per-message
|
||||
identity (`${role}:${sha256_16(role,content)}`) so re-emits of prior-turn
|
||||
entries collide with existing on-disk keys and do not duplicate.
|
||||
|
||||
The mirror is wrapped in two layers of failure containment so a transcript
|
||||
write failure cannot fail the attempt: an internal best-effort wrapper and a
|
||||
defense-in-depth `.catch(...)` at the attempt level. Failures are logged but
|
||||
not surfaced.
|
||||
|
||||
## Side questions (`/btw`)
|
||||
|
||||
`/btw` is **not** native on this harness. `createCopilotAgentHarness()`
|
||||
deliberately leaves `harness.runSideQuestion` undefined, so OpenClaw's `/btw`
|
||||
dispatcher (`src/agents/btw.ts`) falls through to the same in-tree PI fallback
|
||||
path it uses for every non-Codex runtime: the configured model provider is
|
||||
called directly with a short side-question prompt and streamed back via
|
||||
`streamSimple` (no CLI session, no extra pool slot).
|
||||
|
||||
This keeps Copilot CLI sessions reserved for the agent's main turn loop, and
|
||||
keeps `/btw` behavior identical to other PI-backed runtimes. The contract is
|
||||
asserted in
|
||||
[`extensions/copilot/harness.test.ts`](https://github.com/openclaw/openclaw/blob/main/extensions/copilot/harness.test.ts)
|
||||
under `describe("runSideQuestion")`.
|
||||
|
||||
## Doctor and probes
|
||||
|
||||
`extensions/copilot/doctor-contract-api.ts` is auto-loaded by
|
||||
`src/plugins/doctor-contract-registry.ts`. It contributes:
|
||||
|
||||
- An empty `legacyConfigRules` (no retired fields at MVP).
|
||||
- A no-op `normalizeCompatibilityConfig` (kept so future field retirements
|
||||
have a stable in-tree home).
|
||||
- One `sessionRouteStateOwners` entry claiming provider `github-copilot`;
|
||||
runtime `copilot`; CLI session key `copilot`; auth profile
|
||||
prefix `github-copilot:`.
|
||||
|
||||
`extensions/copilot/src/doctor-probes.ts` exports three imperative probes
|
||||
that hosts (including `openclaw doctor`) can call to verify the environment:
|
||||
|
||||
| Probe | What it checks | Reasons it can fail |
|
||||
| -------------------------- | --------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- |
|
||||
| `probeCopilotCliVersion` | `copilot --version` exits 0 with a non-empty version string | `non-zero-exit`, `empty-version`, `spawn-failed`, `spawn-error`, `probe-timeout` |
|
||||
| `probeCopilotHomeWritable` | `mkdir -p copilotHome` + write + rm a marker file | `copilothome-not-writable` (with the underlying fs error in `details.rawError`) |
|
||||
| `probeCopilotAuthShape` | At least one of `useLoggedInUser`, `gitHubToken`, or `profileId`+`profileVersion` | `no-auth-source` |
|
||||
|
||||
Each probe accepts a DI seam (`spawnFn`, `fsApi`) so tests do not spawn the
|
||||
real Copilot CLI or touch the host fs.
|
||||
|
||||
## Limitations
|
||||
|
||||
- The harness only claims the canonical `github-copilot` provider at MVP.
|
||||
Additional providers (BYOK or otherwise) should land in follow-up PRs that
|
||||
ship the adapter alongside the wire-up.
|
||||
- The harness does not deliver TUI; PI's TUI is unaffected and remains the
|
||||
fallback for whatever runtimes do not have a peer surface.
|
||||
- PI session state is not migrated when an agent switches to `copilot`.
|
||||
Selection is per attempt; existing PI sessions remain valid.
|
||||
- **Interactive `ask_user` is not yet wired.** The SDK's
|
||||
`onUserInputRequest` handler is intentionally not registered, which
|
||||
per the SDK contract hides the `ask_user` tool from the model
|
||||
entirely. Agents running under this harness make best-judgment
|
||||
decisions from the initial prompt rather than asking clarifying
|
||||
questions mid-turn. A follow-up will port the codex pattern at
|
||||
`extensions/codex/src/app-server/user-input-bridge.ts` to route SDK
|
||||
`UserInputRequest`s through the OpenClaw channel/TUI prompt path; the
|
||||
dormant scaffolding in `extensions/copilot/src/user-input-bridge.ts`
|
||||
is the surface that follow-up will wire.
|
||||
|
||||
## Permissions and ask_user
|
||||
|
||||
Permission enforcement for bridged OpenClaw tools happens **inside the
|
||||
tool wrapper**, not via the SDK's `onPermissionRequest` callback. The
|
||||
same `wrapToolWithBeforeToolCallHook` that PI uses
|
||||
(`src/agents/pi-tools.before-tool-call.ts`) is applied by
|
||||
`createOpenClawCodingTools` to every coding tool: loop detection,
|
||||
trusted plugin policies, before-tool-call hooks, and two-phase plugin
|
||||
approvals via the gateway (`plugin.approval.request`) all run with the
|
||||
exact same code path as native PI attempts.
|
||||
|
||||
To let that wrapper own the decision, the SDK Tool returned by
|
||||
`convertOpenClawToolToSdkTool` is marked with:
|
||||
|
||||
- `overridesBuiltInTool: true` — replaces the Copilot CLI's built-in
|
||||
tool of the same name (edit, read, write, bash, …) so every tool
|
||||
invocation routes back to OpenClaw.
|
||||
- `skipPermission: true` — tells the SDK not to fire
|
||||
`onPermissionRequest({kind: "custom-tool"})` before invoking the tool.
|
||||
The wrapped `execute()` performs the richer OpenClaw policy check
|
||||
internally; an SDK-level prompt would either short-circuit OpenClaw's
|
||||
enforcement (if we allow-all) or block every tool call (if we
|
||||
reject-all) — neither matches PI parity.
|
||||
|
||||
The in-tree codex harness uses the same split: bridged OpenClaw tools
|
||||
are wrapped (`extensions/codex/src/app-server/dynamic-tools.ts`) and
|
||||
the codex-app-server's _own_ native approval kinds
|
||||
(`item/commandExecution/requestApproval`,
|
||||
`item/fileChange/requestApproval`,
|
||||
`item/permissions/requestApproval`) are routed through
|
||||
`plugin.approval.request`
|
||||
(`extensions/codex/src/app-server/approval-bridge.ts`). The Copilot SDK
|
||||
equivalent — fail-closed `rejectAllPolicy` for any non-`custom-tool`
|
||||
kind that ever reaches `onPermissionRequest` — is the same safety net,
|
||||
and it does not fire in practice because `overridesBuiltInTool: true`
|
||||
displaces every built-in.
|
||||
|
||||
For the wrapped-tool layer to make policy decisions equivalent to PI,
|
||||
the harness forwards the full PI attempt-tool context to
|
||||
`createOpenClawCodingTools` — identity (`senderIsOwner`,
|
||||
`memberRoleIds`, `ownerOnlyToolAllowlist`, …), channel/routing
|
||||
(`groupId`, `currentChannelId`, `replyToMode`, message-tool toggles),
|
||||
auth (`authProfileStore`), run identity
|
||||
(`sessionKey`/`runSessionKey` derived from `sandboxSessionKey`,
|
||||
`runId`), model context (`modelApi`, `modelContextWindowTokens`,
|
||||
`modelCompat`, `modelHasVision`), and run hooks (`onToolOutcome`,
|
||||
`onYield`). Without those fields, owner-only allowlists silently
|
||||
behave as deny-by-default, plugin-trust policies cannot resolve to the
|
||||
right scope, and `session_status: "current"` resolves to a stale
|
||||
sandbox key. The bridge builder is in
|
||||
`extensions/copilot/src/tool-bridge.ts` and mirrors the PI
|
||||
authoritative call at
|
||||
`src/agents/pi-embedded-runner/run/attempt.ts:1029-1117`. Two PI fields
|
||||
are intentionally **not** forwarded at MVP and tracked as follow-ups:
|
||||
`sandbox` (the harness does not yet route through `resolveSandboxContext`)
|
||||
and the PI tool-search/code-mode machinery
|
||||
(`toolSearchCatalogRef`, `includeCoreTools`,
|
||||
`includeToolSearchControls`, `toolSearchCatalogExecutor`,
|
||||
`toolConstructionPlan`), which has no analog at the SDK boundary.
|
||||
|
||||
### Session-level GitHub token
|
||||
|
||||
The Copilot SDK contract distinguishes the **client-level** GitHub
|
||||
token (`CopilotClientOptions.gitHubToken`, used to authenticate the
|
||||
CLI process itself) from the **session-level** token
|
||||
(`SessionConfig.gitHubToken`, which determines content exclusion,
|
||||
model routing, and quota for that session and is honored on both
|
||||
`createSession` and `resumeSession`). The harness resolves auth once
|
||||
via `resolveCopilotAuth` and sets both fields when the auth mode is
|
||||
`gitHubToken` (an explicit `auth.gitHubToken` or a contract-resolved
|
||||
`resolvedApiKey` from a configured `github-copilot` auth profile).
|
||||
When the resolved mode is `useLoggedInUser`, the session-level field
|
||||
is omitted so the SDK keeps deriving identity from the logged-in
|
||||
identity.
|
||||
|
||||
`ask_user` is intentionally hidden — see Limitations above.
|
||||
|
||||
## Related
|
||||
|
||||
- [Agent runtimes](/concepts/agent-runtimes)
|
||||
- [Codex harness](/plugins/codex-harness)
|
||||
- [Agent harness plugins (SDK reference)](/plugins/sdk-agent-harness)
|
||||
@@ -1124,7 +1124,7 @@ Optional overrides:
|
||||
introMessage: "Say exactly: I'm here.",
|
||||
providers: {
|
||||
google: {
|
||||
speakerVoice: "Kore",
|
||||
voice: "Kore",
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -1141,7 +1141,7 @@ ElevenLabs for both agent-mode listening and speaking:
|
||||
providers: {
|
||||
elevenlabs: {
|
||||
modelId: "eleven_v3",
|
||||
speakerVoiceId: "pMsXgVXv3BLzUgSXRplE",
|
||||
voiceId: "pMsXgVXv3BLzUgSXRplE",
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -1169,11 +1169,11 @@ ElevenLabs for both agent-mode listening and speaking:
|
||||
```
|
||||
|
||||
The persistent Meet voice comes from
|
||||
`messages.tts.providers.elevenlabs.speakerVoiceId`. Agent replies can also use
|
||||
per-reply `[[tts:speakerVoiceId=... model=eleven_v3]]` directives when TTS model
|
||||
`messages.tts.providers.elevenlabs.voiceId`. Agent replies can also use
|
||||
per-reply `[[tts:voiceId=... model=eleven_v3]]` directives when TTS model
|
||||
overrides are enabled, but config is the deterministic default for meetings.
|
||||
On join, the logs should show `transcriptionProvider=elevenlabs` and each
|
||||
spoken reply should log `provider=elevenlabs model=eleven_v3 speakerVoiceId=<voiceId>`.
|
||||
spoken reply should log `provider=elevenlabs model=eleven_v3 voice=<voiceId>`.
|
||||
|
||||
Twilio-only config:
|
||||
|
||||
|
||||
@@ -126,10 +126,9 @@ observation-only.
|
||||
**Messages and delivery**
|
||||
|
||||
- **`inbound_claim`** - claim an inbound message before agent routing (synthetic replies)
|
||||
- `message_received` — observe inbound content, sender, thread, and metadata
|
||||
- **`message_sending`** — rewrite outbound content or cancel delivery
|
||||
- **`reply_payload_sending`** — mutate or cancel normalized reply payloads before delivery
|
||||
- `message_sent` — observe outbound delivery success or failure
|
||||
- `message_received` - observe inbound content, sender, thread, and metadata
|
||||
- **`message_sending`** - rewrite outbound content or cancel delivery
|
||||
- `message_sent` - observe outbound delivery success or failure
|
||||
- **`before_dispatch`** - inspect or rewrite an outbound dispatch before channel handoff
|
||||
- **`reply_dispatch`** - participate in the final reply-dispatch pipeline
|
||||
|
||||
@@ -385,8 +384,6 @@ Use message hooks for channel-level routing and delivery policy:
|
||||
- `message_received`: observe inbound content, sender, `threadId`, `messageId`,
|
||||
`senderId`, optional run/session correlation, and metadata.
|
||||
- `message_sending`: rewrite `content` or return `{ cancel: true }`.
|
||||
- `reply_payload_sending`: rewrite normalized `ReplyPayload` objects (including
|
||||
`presentation`, `delivery`, media refs, and text) or return `{ cancel: true }`.
|
||||
- `message_sent`: observe final success or failure.
|
||||
|
||||
For audio-only TTS replies, `content` may contain the hidden spoken transcript
|
||||
@@ -408,13 +405,6 @@ Decision rules:
|
||||
- `message_sending` with `cancel: false` is treated as no decision.
|
||||
- Rewritten `content` continues to lower-priority hooks unless a later hook
|
||||
cancels delivery.
|
||||
- `reply_payload_sending` runs after payload normalization and before channel
|
||||
delivery, including replies routed back to the originating channel. Handlers
|
||||
run sequentially and each handler sees the latest payload produced by
|
||||
higher-priority handlers.
|
||||
- `reply_payload_sending` payloads do not expose runtime trust markers such as
|
||||
`trustedLocalMedia`; plugins can edit payload shape but cannot grant local
|
||||
media trust.
|
||||
- `message_sending` can return `cancelReason` and bounded `metadata` with a
|
||||
cancellation. New message lifecycle APIs expose this as a suppressed delivery
|
||||
outcome with reason `cancelled_by_message_sending_hook`; legacy direct
|
||||
|
||||
@@ -64,9 +64,7 @@ commands.
|
||||
| [chutes](/plugins/reference/chutes) | Adds Chutes model provider support to OpenClaw. | `@openclaw/chutes-provider`<br />included in OpenClaw | providers: chutes |
|
||||
| [clickclack](/plugins/reference/clickclack) | Adds the Clickclack channel surface for sending and receiving OpenClaw messages. | `@openclaw/clickclack`<br />included in OpenClaw | channels: clickclack |
|
||||
| [cloudflare-ai-gateway](/plugins/reference/cloudflare-ai-gateway) | Adds Cloudflare AI Gateway model provider support to OpenClaw. | `@openclaw/cloudflare-ai-gateway-provider`<br />included in OpenClaw | providers: cloudflare-ai-gateway |
|
||||
| [codex-supervisor](/plugins/reference/codex-supervisor) | Supervise Codex app-server sessions from OpenClaw. | `@openclaw/codex-supervisor`<br />included in OpenClaw | contracts: tools |
|
||||
| [comfy](/plugins/reference/comfy) | Adds ComfyUI model provider support to OpenClaw. | `@openclaw/comfy-provider`<br />included in OpenClaw | providers: comfy; contracts: imageGenerationProviders, musicGenerationProviders, videoGenerationProviders |
|
||||
| [copilot](/plugins/reference/copilot) | Registers the GitHub Copilot agent runtime. | `@openclaw/copilot`<br />included in OpenClaw | plugin |
|
||||
| [copilot-proxy](/plugins/reference/copilot-proxy) | Adds Copilot Proxy model provider support to OpenClaw. | `@openclaw/copilot-proxy`<br />included in OpenClaw | providers: copilot-proxy |
|
||||
| [deepgram](/plugins/reference/deepgram) | Adds media understanding provider support. Adds realtime transcription provider support. | `@openclaw/deepgram-provider`<br />included in OpenClaw | contracts: mediaUnderstandingProviders, realtimeTranscriptionProviders |
|
||||
| [deepinfra](/plugins/reference/deepinfra) | Adds DeepInfra model provider support to OpenClaw. | `@openclaw/deepinfra-provider`<br />included in OpenClaw | providers: deepinfra; contracts: imageGenerationProviders, mediaUnderstandingProviders, memoryEmbeddingProviders, speechProviders, videoGenerationProviders |
|
||||
@@ -136,7 +134,6 @@ commands.
|
||||
| [vydra](/plugins/reference/vydra) | Adds Vydra model provider support to OpenClaw. | `@openclaw/vydra-provider`<br />included in OpenClaw | providers: vydra; contracts: imageGenerationProviders, speechProviders, videoGenerationProviders |
|
||||
| [web-readability](/plugins/reference/web-readability) | Extract readable article content from local HTML web fetch responses. | `@openclaw/web-readability-plugin`<br />included in OpenClaw | contracts: webContentExtractors |
|
||||
| [webhooks](/plugins/reference/webhooks) | Authenticated inbound webhooks that bind external automation to OpenClaw TaskFlows. | `@openclaw/webhooks`<br />included in OpenClaw | plugin |
|
||||
| [workboard](/plugins/reference/workboard) | Dashboard workboard for agent-owned issues and sessions. | `@openclaw/workboard`<br />included in OpenClaw | plugin |
|
||||
| [xai](/plugins/reference/xai) | Adds xAI model provider support to OpenClaw. | `@openclaw/xai-plugin`<br />included in OpenClaw | providers: xai; contracts: imageGenerationProviders, mediaUnderstandingProviders, realtimeTranscriptionProviders, speechProviders, tools, videoGenerationProviders, webSearchProviders |
|
||||
| [xiaomi](/plugins/reference/xiaomi) | Adds Xiaomi model provider support to OpenClaw. | `@openclaw/xiaomi-provider`<br />included in OpenClaw | providers: xiaomi; contracts: speechProviders |
|
||||
| [zai](/plugins/reference/zai) | Adds Z.AI model provider support to OpenClaw. | `@openclaw/zai-provider`<br />included in OpenClaw | providers: zai; contracts: mediaUnderstandingProviders |
|
||||
|
||||
@@ -36,9 +36,7 @@ pnpm plugins:inventory:gen
|
||||
| [clickclack](/plugins/reference/clickclack) | Adds the Clickclack channel surface for sending and receiving OpenClaw messages. | `@openclaw/clickclack`<br />included in OpenClaw | channels: clickclack |
|
||||
| [cloudflare-ai-gateway](/plugins/reference/cloudflare-ai-gateway) | Adds Cloudflare AI Gateway model provider support to OpenClaw. | `@openclaw/cloudflare-ai-gateway-provider`<br />included in OpenClaw | providers: cloudflare-ai-gateway |
|
||||
| [codex](/plugins/reference/codex) | OpenClaw Codex app-server harness and model provider plugin with a Codex-managed GPT catalog. | `@openclaw/codex`<br />npm; ClawHub | providers: codex; contracts: mediaUnderstandingProviders, migrationProviders |
|
||||
| [codex-supervisor](/plugins/reference/codex-supervisor) | Supervise Codex app-server sessions from OpenClaw. | `@openclaw/codex-supervisor`<br />included in OpenClaw | contracts: tools |
|
||||
| [comfy](/plugins/reference/comfy) | Adds ComfyUI model provider support to OpenClaw. | `@openclaw/comfy-provider`<br />included in OpenClaw | providers: comfy; contracts: imageGenerationProviders, musicGenerationProviders, videoGenerationProviders |
|
||||
| [copilot](/plugins/reference/copilot) | Registers the GitHub Copilot agent runtime. | `@openclaw/copilot`<br />included in OpenClaw | plugin |
|
||||
| [copilot-proxy](/plugins/reference/copilot-proxy) | Adds Copilot Proxy model provider support to OpenClaw. | `@openclaw/copilot-proxy`<br />included in OpenClaw | providers: copilot-proxy |
|
||||
| [deepgram](/plugins/reference/deepgram) | Adds media understanding provider support. Adds realtime transcription provider support. | `@openclaw/deepgram-provider`<br />included in OpenClaw | contracts: mediaUnderstandingProviders, realtimeTranscriptionProviders |
|
||||
| [deepinfra](/plugins/reference/deepinfra) | Adds DeepInfra model provider support to OpenClaw. | `@openclaw/deepinfra-provider`<br />included in OpenClaw | providers: deepinfra; contracts: imageGenerationProviders, mediaUnderstandingProviders, memoryEmbeddingProviders, speechProviders, videoGenerationProviders |
|
||||
@@ -135,7 +133,6 @@ pnpm plugins:inventory:gen
|
||||
| [web-readability](/plugins/reference/web-readability) | Extract readable article content from local HTML web fetch responses. | `@openclaw/web-readability-plugin`<br />included in OpenClaw | contracts: webContentExtractors |
|
||||
| [webhooks](/plugins/reference/webhooks) | Authenticated inbound webhooks that bind external automation to OpenClaw TaskFlows. | `@openclaw/webhooks`<br />included in OpenClaw | plugin |
|
||||
| [whatsapp](/plugins/reference/whatsapp) | OpenClaw WhatsApp channel plugin for WhatsApp Web chats. | `@openclaw/whatsapp`<br />ClawHub: `clawhub:@openclaw/whatsapp`; npm | channels: whatsapp |
|
||||
| [workboard](/plugins/reference/workboard) | Dashboard workboard for agent-owned issues and sessions. | `@openclaw/workboard`<br />included in OpenClaw | plugin |
|
||||
| [xai](/plugins/reference/xai) | Adds xAI model provider support to OpenClaw. | `@openclaw/xai-plugin`<br />included in OpenClaw | providers: xai; contracts: imageGenerationProviders, mediaUnderstandingProviders, realtimeTranscriptionProviders, speechProviders, tools, videoGenerationProviders, webSearchProviders |
|
||||
| [xiaomi](/plugins/reference/xiaomi) | Adds Xiaomi model provider support to OpenClaw. | `@openclaw/xiaomi-provider`<br />included in OpenClaw | providers: xiaomi; contracts: speechProviders |
|
||||
| [zai](/plugins/reference/zai) | Adds Z.AI model provider support to OpenClaw. | `@openclaw/zai-provider`<br />included in OpenClaw | providers: zai; contracts: mediaUnderstandingProviders |
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
---
|
||||
summary: "Supervise Codex app-server sessions from OpenClaw."
|
||||
read_when:
|
||||
- You are installing, configuring, or auditing the codex-supervisor plugin
|
||||
title: "Codex Supervisor plugin"
|
||||
---
|
||||
|
||||
# Codex Supervisor plugin
|
||||
|
||||
Supervise Codex app-server sessions from OpenClaw.
|
||||
|
||||
## Distribution
|
||||
|
||||
- Package: `@openclaw/codex-supervisor`
|
||||
- Install route: included in OpenClaw
|
||||
|
||||
## Surface
|
||||
|
||||
contracts: tools
|
||||
@@ -1,23 +0,0 @@
|
||||
---
|
||||
summary: "Registers the GitHub Copilot agent runtime."
|
||||
read_when:
|
||||
- You are installing, configuring, or auditing the copilot plugin
|
||||
title: "Copilot plugin"
|
||||
---
|
||||
|
||||
# Copilot plugin
|
||||
|
||||
Registers the GitHub Copilot agent runtime.
|
||||
|
||||
## Distribution
|
||||
|
||||
- Package: `@openclaw/copilot`
|
||||
- Install route: included in OpenClaw
|
||||
|
||||
## Surface
|
||||
|
||||
plugin
|
||||
|
||||
## Related docs
|
||||
|
||||
- [copilot](/plugins/copilot)
|
||||
@@ -18,55 +18,6 @@ Adds policy-backed doctor checks for workspace conformance.
|
||||
|
||||
plugin
|
||||
|
||||
<!-- openclaw-plugin-reference:manual-start -->
|
||||
|
||||
## Behavior
|
||||
|
||||
The Policy plugin contributes doctor health checks for policy-managed OpenClaw
|
||||
settings and governed workspace declarations. Policy currently covers channel
|
||||
conformance, governed tool metadata, MCP server posture, model-provider posture,
|
||||
private-network access posture, Gateway exposure posture, agent workspace/tool
|
||||
posture, configured global/per-agent tool posture, configured sandbox runtime
|
||||
posture, ingress/channel access posture, and OpenClaw config secret
|
||||
provider/auth profile posture.
|
||||
|
||||
Policy stores authored requirements in `policy.jsonc`, observes existing
|
||||
OpenClaw settings and workspace declarations as evidence, and reports drift
|
||||
through `openclaw policy check` and `openclaw doctor --lint`. A clean policy
|
||||
check emits policy, evidence, findings, and attestation hashes that operators
|
||||
can record for audit.
|
||||
|
||||
`openclaw policy compare --baseline <file>` compares one policy file to another
|
||||
policy file. It is config-level conformance only: it uses policy rule metadata
|
||||
to verify that the checked policy is not missing or weaker than the authored
|
||||
baseline, and it does not inspect runtime state, credentials, or secret values.
|
||||
|
||||
Tool posture rules can require approved profiles, workspace-only filesystem
|
||||
tools, bounded exec security/ask/host settings, disabled elevated mode, exact
|
||||
`alsoAllow` entries, and required tool deny entries. The evidence records
|
||||
additive `alsoAllow` entries because they can widen effective tool posture.
|
||||
These checks observe config conformance only; they do not read runtime approval
|
||||
state or add runtime enforcement.
|
||||
|
||||
Sandbox posture rules can require approved sandbox modes/backends, deny host
|
||||
container networking, deny container namespace joins, require read-only container
|
||||
mounts, deny container runtime socket mounts and unconfined container profiles,
|
||||
and require sandbox browser CDP source ranges.
|
||||
These checks observe config conformance only; they do not read runtime approval
|
||||
state, inspect live containers, or add runtime enforcement.
|
||||
|
||||
Named policy scopes under `scopes.<scopeName>` can add stricter normal policy
|
||||
sections for the selector they list. `agentIds` supports `tools`,
|
||||
`agents.workspace`, and `sandbox`; `channelIds` supports `ingress.channels`.
|
||||
Runtime agent ids that are not explicitly listed in `agents.list[]` are checked
|
||||
against inherited global/default posture rather than silently passing with no
|
||||
evidence. Every scope present in `policy.jsonc` must be valid and enforceable
|
||||
for its selector. Overlay rules are additional claims, so they do not weaken
|
||||
top-level policy and can produce their own findings when the same observed
|
||||
config violates both scopes.
|
||||
|
||||
<!-- openclaw-plugin-reference:manual-end -->
|
||||
|
||||
## Related docs
|
||||
|
||||
- [policy](/cli/policy)
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
---
|
||||
summary: "Dashboard workboard for agent-owned issues and sessions."
|
||||
read_when:
|
||||
- You are installing, configuring, or auditing the workboard plugin
|
||||
title: "Workboard plugin"
|
||||
---
|
||||
|
||||
# Workboard plugin
|
||||
|
||||
Dashboard workboard for agent-owned issues and sessions.
|
||||
|
||||
## Distribution
|
||||
|
||||
- Package: `@openclaw/workboard`
|
||||
- Install route: included in OpenClaw
|
||||
|
||||
## Surface
|
||||
|
||||
plugin
|
||||
|
||||
## Related docs
|
||||
|
||||
- [workboard](/plugins/workboard)
|
||||
@@ -238,9 +238,9 @@ model entry:
|
||||
{
|
||||
"agents": {
|
||||
"defaults": {
|
||||
"model": "anthropic/claude-opus-4-8",
|
||||
"model": "anthropic/claude-opus-4-7",
|
||||
"models": {
|
||||
"anthropic/claude-opus-4-8": {
|
||||
"anthropic/claude-opus-4-7": {
|
||||
"agentRuntime": {
|
||||
"id": "claude-cli"
|
||||
}
|
||||
|
||||
@@ -568,7 +568,6 @@ releases.
|
||||
| `plugin-sdk/dedupe-runtime` | Dedupe helpers | In-memory dedupe caches |
|
||||
| `plugin-sdk/file-access-runtime` | File access helpers | Safe local-file/media path helpers |
|
||||
| `plugin-sdk/transport-ready-runtime` | Transport readiness helpers | `waitForTransportReady` |
|
||||
| `plugin-sdk/exec-approvals-runtime` | Exec approval policy helpers | `loadExecApprovals`, `resolveExecApprovalsFromFile`, `ExecApprovalsFile` |
|
||||
| `plugin-sdk/collection-runtime` | Bounded cache helpers | `pruneMapToMaxSize` |
|
||||
| `plugin-sdk/diagnostic-runtime` | Diagnostic gating helpers | `isDiagnosticFlagEnabled`, `isDiagnosticsEnabled` |
|
||||
| `plugin-sdk/error-runtime` | Error formatting helpers | `formatUncaughtError`, `isApprovalNotFoundError`, error graph helpers |
|
||||
|
||||
@@ -237,7 +237,6 @@ and pairing-path families.
|
||||
| `plugin-sdk/session-store-runtime` | Session workflow helpers (`getSessionEntry`, `listSessionEntries`, `patchSessionEntry`, `upsertSessionEntry`), legacy session store path/session-key helpers, updated-at reads, and deprecated whole-store mutation helpers |
|
||||
| `plugin-sdk/cron-store-runtime` | Cron store path/load/save helpers |
|
||||
| `plugin-sdk/state-paths` | State/OAuth dir path helpers |
|
||||
| `plugin-sdk/plugin-state-runtime` | Plugin sidecar SQLite keyed-state types |
|
||||
| `plugin-sdk/routing` | Route/session-key/account binding helpers such as `resolveAgentRoute`, `buildAgentSessionKey`, and `resolveDefaultAgentBoundAccountId` |
|
||||
| `plugin-sdk/status-helpers` | Shared channel/account status summary helpers, runtime-state defaults, and issue metadata helpers |
|
||||
| `plugin-sdk/target-resolver-runtime` | Shared target resolver helpers |
|
||||
@@ -282,7 +281,6 @@ and pairing-path families.
|
||||
| `plugin-sdk/secure-random-runtime` | Secure token/UUID helpers |
|
||||
| `plugin-sdk/system-event-runtime` | System event queue helpers |
|
||||
| `plugin-sdk/transport-ready-runtime` | Transport readiness wait helper |
|
||||
| `plugin-sdk/exec-approvals-runtime` | Exec approval policy file helpers without the broad infra-runtime barrel |
|
||||
| `plugin-sdk/infra-runtime` | Deprecated compatibility shim; use the focused runtime subpaths above |
|
||||
| `plugin-sdk/collection-runtime` | Small bounded cache helpers |
|
||||
| `plugin-sdk/diagnostic-runtime` | Diagnostic flag, event, and trace-context helpers |
|
||||
|
||||
@@ -115,7 +115,7 @@ Voice-call credentials accept SecretRefs. `plugins.entries.voice-call.config.twi
|
||||
responseSystemPrompt: "You are a concise baseball card specialist.",
|
||||
tts: {
|
||||
providers: {
|
||||
openai: { speakerVoice: "alloy" },
|
||||
openai: { voice: "alloy" },
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -322,7 +322,7 @@ for tool work, current information, memory lookups, or workspace state.
|
||||
google: {
|
||||
apiKey: "${GEMINI_API_KEY}",
|
||||
model: "gemini-2.5-flash-native-audio-preview-12-2025",
|
||||
speakerVoice: "Kore",
|
||||
voice: "Kore",
|
||||
silenceDurationMs: 500,
|
||||
startSensitivity: "high",
|
||||
},
|
||||
@@ -455,7 +455,7 @@ speech on calls. You can override it under the plugin config with the
|
||||
provider: "elevenlabs",
|
||||
providers: {
|
||||
elevenlabs: {
|
||||
speakerVoiceId: "pMsXgVXv3BLzUgSXRplE",
|
||||
voiceId: "pMsXgVXv3BLzUgSXRplE",
|
||||
modelId: "eleven_multilingual_v2",
|
||||
},
|
||||
},
|
||||
@@ -486,7 +486,7 @@ Behavior notes:
|
||||
tts: {
|
||||
provider: "openai",
|
||||
providers: {
|
||||
openai: { speakerVoice: "alloy" },
|
||||
openai: { voice: "alloy" },
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -505,7 +505,7 @@ Behavior notes:
|
||||
providers: {
|
||||
elevenlabs: {
|
||||
apiKey: "elevenlabs_key",
|
||||
speakerVoiceId: "pMsXgVXv3BLzUgSXRplE",
|
||||
voiceId: "pMsXgVXv3BLzUgSXRplE",
|
||||
modelId: "eleven_multilingual_v2",
|
||||
},
|
||||
},
|
||||
@@ -528,7 +528,7 @@ Behavior notes:
|
||||
providers: {
|
||||
openai: {
|
||||
model: "gpt-4o-mini-tts",
|
||||
speakerVoice: "marin",
|
||||
voice: "marin",
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -599,7 +599,7 @@ you can usually override only the provider voice:
|
||||
tts: {
|
||||
provider: "openai",
|
||||
providers: {
|
||||
openai: { speakerVoice: "coral" },
|
||||
openai: { voice: "coral" },
|
||||
},
|
||||
},
|
||||
numbers: {
|
||||
@@ -608,7 +608,7 @@ you can usually override only the provider voice:
|
||||
responseSystemPrompt: "You are a concise baseball card specialist.",
|
||||
tts: {
|
||||
providers: {
|
||||
openai: { speakerVoice: "alloy" },
|
||||
openai: { voice: "alloy" },
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
@@ -1,198 +0,0 @@
|
||||
---
|
||||
summary: "Optional dashboard workboard for agent-owned cards and session handoff"
|
||||
read_when:
|
||||
- You want a Kanban-style workboard in the Control UI
|
||||
- You are enabling or disabling the bundled Workboard plugin
|
||||
- You want to track planned agent work without an external project manager
|
||||
title: "Workboard plugin"
|
||||
---
|
||||
|
||||
The Workboard plugin adds an optional Kanban-style board to the
|
||||
[Control UI](/web/control-ui). Use it to collect agent-sized work cards, assign
|
||||
them to agents, and jump from a card into the linked dashboard session.
|
||||
|
||||
Workboard is intentionally small. It tracks local operating work for an
|
||||
OpenClaw Gateway; it is not a replacement for GitHub Issues, Linear, Jira, or
|
||||
other team project management systems.
|
||||
|
||||
## Default state
|
||||
|
||||
Workboard is a bundled plugin and is disabled by default unless you enable it
|
||||
in plugin config.
|
||||
|
||||
Enable it with:
|
||||
|
||||
```bash
|
||||
openclaw plugins enable workboard
|
||||
openclaw gateway restart
|
||||
```
|
||||
|
||||
Then open the dashboard:
|
||||
|
||||
```bash
|
||||
openclaw dashboard
|
||||
```
|
||||
|
||||
The Workboard tab appears in the dashboard navigation. If the tab is visible
|
||||
but the plugin is disabled or blocked by `plugins.allow` / `plugins.deny`, the
|
||||
view shows a plugin-unavailable state instead of local card data.
|
||||
|
||||
## What cards contain
|
||||
|
||||
Each card stores:
|
||||
|
||||
- title and notes
|
||||
- status: `backlog`, `todo`, `running`, `review`, `blocked`, or `done`
|
||||
- priority: `low`, `normal`, `high`, or `urgent`
|
||||
- labels
|
||||
- optional agent id
|
||||
- optional linked session, run, task, or source URL
|
||||
- optional execution metadata for a Codex or Claude session started from the card
|
||||
- compact metadata for attempts, comments, links, proof, templates, archive state, and stale-session detection
|
||||
- recent card events such as created, moved, linked, attempt, proof, archive, stale, or agent-updated changes
|
||||
|
||||
Cards are stored in the plugin's Gateway state. They are local to the Gateway
|
||||
state directory and move with the rest of that Gateway's OpenClaw state.
|
||||
|
||||
Workboard keeps compact per-card metadata so operators can see how a card moved
|
||||
through the board without opening the linked session. Events, attempt summaries,
|
||||
proof snippets, related links, comments, archive markers, and stale-session
|
||||
markers are intentionally local metadata; they do not replace session
|
||||
transcripts or GitHub issue history.
|
||||
|
||||
## Card executions
|
||||
|
||||
Unlinked cards can start work from the card. Start uses the Gateway's configured
|
||||
default agent and model. Codex and Claude actions are optional explicit model
|
||||
choices:
|
||||
|
||||
- Run Codex or Run Claude creates a dashboard session, sends the card prompt,
|
||||
and marks the card `running`.
|
||||
- Open Codex or Open Claude creates a linked dashboard session without sending
|
||||
the card prompt or moving the card, so you can work manually while it stays
|
||||
attached to the board.
|
||||
|
||||
Execution metadata stores the selected engine, mode, model ref, session key,
|
||||
run id, and lifecycle status on the card. Codex executions use
|
||||
`openai/gpt-5.5`; Claude executions use `anthropic/claude-sonnet-4-6`.
|
||||
|
||||
Each linked execution also records an attempt summary on the same card record.
|
||||
The attempt summary keeps the engine, mode, model, run id, timestamps, status,
|
||||
and rolling failure count so repeated failures remain visible on the board.
|
||||
|
||||
## Session lifecycle sync
|
||||
|
||||
Cards can be linked to existing dashboard sessions or to the session created
|
||||
when you start work from a card. Linked cards show the session lifecycle inline:
|
||||
running, stale, linked idle, done, failed, or missing.
|
||||
|
||||
If the linked session is missing, the card stays linked for context and still
|
||||
offers start controls so you can restart work into a fresh dashboard session.
|
||||
If an active linked session stops reporting recent activity, Workboard marks the
|
||||
card stale and stores the marker as card metadata until the lifecycle clears it.
|
||||
|
||||
You can also capture an existing dashboard session from the Sessions tab with
|
||||
Add to Workboard. The card is linked to that session, uses the session label or
|
||||
recent user prompt as the title, and seeds notes from the recent user prompt plus
|
||||
the latest assistant response when chat history is available.
|
||||
|
||||
Workboard follows the linked session while the card is still in an active work
|
||||
state:
|
||||
|
||||
- active linked session -> `running`
|
||||
- completed linked session -> `review`
|
||||
- failed, killed, timed out, or aborted linked session -> `blocked`
|
||||
|
||||
Manual review states win. If you move a card to `review`, `blocked`, or `done`,
|
||||
Workboard stops auto-moving that card until you move it back to `todo` or
|
||||
`running`.
|
||||
|
||||
## Dashboard workflow
|
||||
|
||||
1. Open the Workboard tab in the Control UI.
|
||||
2. Create a card with a title, notes, priority, labels, optional agent, and
|
||||
optional linked session.
|
||||
3. Or open Sessions and choose Add to Workboard for an existing session.
|
||||
4. Drag the card between columns or use the column controls.
|
||||
5. Start work from the card to create or reuse a dashboard session.
|
||||
6. Open the linked session from the card while the agent works.
|
||||
7. Let lifecycle sync move running work into review or blocked, then manually
|
||||
move the card to done when accepted.
|
||||
|
||||
Starting a card uses normal Gateway sessions. The Workboard plugin only stores
|
||||
card metadata and links; the conversation transcript, model selection, and run
|
||||
lifecycle stay owned by the regular session system.
|
||||
|
||||
Use Stop on a live linked card to abort the active session run. Workboard marks
|
||||
that card `blocked` so it remains visible for follow-up.
|
||||
|
||||
New cards can start from Workboard templates for bugfixes, docs, releases, PR
|
||||
reviews, or plugin work. Templates prefill title, notes, labels, and priority,
|
||||
and the selected template id is stored as card metadata.
|
||||
|
||||
## Permissions
|
||||
|
||||
The plugin registers Gateway RPC methods under the `workboard.*` namespace:
|
||||
|
||||
- `workboard.cards.list` requires `operator.read`
|
||||
- `workboard.cards.export` requires `operator.read`
|
||||
- create, update, move, delete, comment, link, proof, and archive methods require `operator.write`
|
||||
|
||||
Browsers connected with read-only operator access can inspect the board but
|
||||
cannot mutate cards.
|
||||
|
||||
## Configuration
|
||||
|
||||
Workboard has no plugin-specific config today. Enable or disable it with the
|
||||
standard plugin entry:
|
||||
|
||||
```json5
|
||||
{
|
||||
plugins: {
|
||||
entries: {
|
||||
workboard: {
|
||||
enabled: true,
|
||||
config: {},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
Disable it again with:
|
||||
|
||||
```bash
|
||||
openclaw plugins disable workboard
|
||||
openclaw gateway restart
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### The tab says Workboard is unavailable
|
||||
|
||||
Check plugin policy:
|
||||
|
||||
```bash
|
||||
openclaw plugins inspect workboard --runtime --json
|
||||
```
|
||||
|
||||
If `plugins.allow` is configured, add `workboard` to that allowlist. If
|
||||
`plugins.deny` contains `workboard`, remove it before enabling the plugin.
|
||||
|
||||
### Cards do not save
|
||||
|
||||
Confirm the browser connection has `operator.write` access. Read-only operator
|
||||
sessions can list cards but cannot create, edit, move, or delete them.
|
||||
|
||||
### Starting a card does not open the expected session
|
||||
|
||||
Workboard creates links to normal dashboard sessions. Check the card's agent id
|
||||
and linked session, then open the Sessions or Chat view to inspect the actual
|
||||
run state.
|
||||
|
||||
## Related
|
||||
|
||||
- [Control UI](/web/control-ui)
|
||||
- [Plugins](/tools/plugin)
|
||||
- [Manage plugins](/plugins/manage-plugins)
|
||||
- [Sessions](/concepts/session)
|
||||
@@ -8,27 +8,22 @@ title: "Anthropic"
|
||||
Anthropic builds the **Claude** model family. OpenClaw supports two auth routes:
|
||||
|
||||
- **API key** — direct Anthropic API access with usage-based billing (`anthropic/*` models)
|
||||
- **Claude CLI** — reuse an existing Claude Code login on the same host
|
||||
- **Claude CLI** — reuse an existing Claude CLI login on the same host
|
||||
|
||||
<Warning>
|
||||
OpenClaw's Claude CLI backend runs the installed Claude Code CLI in
|
||||
non-interactive print mode. Anthropic's current Claude Code docs describe
|
||||
`claude -p` as Agent SDK/programmatic usage. Starting June 15, 2026, Anthropic
|
||||
says subscription-plan `claude -p` usage no longer draws from normal Claude
|
||||
plan limits; it draws from a separate monthly Agent SDK credit first, then from
|
||||
usage credits at standard API rates when those credits are enabled.
|
||||
Anthropic staff told us OpenClaw-style Claude CLI usage is allowed again, so
|
||||
OpenClaw treats Claude CLI reuse and `claude -p` usage as sanctioned unless
|
||||
Anthropic publishes a new policy.
|
||||
|
||||
Interactive Claude Code still draws from the signed-in Claude plan limits. API
|
||||
key auth remains direct pay-as-you-go API billing. For long-lived gateway hosts,
|
||||
shared automation, and predictable production spend, use an Anthropic API key.
|
||||
For long-lived gateway hosts, Anthropic API keys are still the clearest and
|
||||
most predictable production path.
|
||||
|
||||
Anthropic's current public docs:
|
||||
|
||||
- [Claude Code CLI reference](https://code.claude.com/docs/en/cli-usage)
|
||||
- [Use the Claude Agent SDK with your Claude plan](https://support.claude.com/en/articles/15036540-use-the-claude-agent-sdk-with-your-claude-plan)
|
||||
- [Use Claude Code with your Pro or Max plan](https://support.claude.com/en/articles/11145838-use-claude-code-with-your-pro-or-max-plan)
|
||||
- [Use Claude Code with your Team or Enterprise plan](https://support.claude.com/en/articles/11845131-using-claude-code-with-your-team-or-enterprise-plan)
|
||||
- [Manage Claude Code costs](https://code.claude.com/docs/en/costs)
|
||||
- [Claude Code CLI reference](https://code.claude.com/docs/en/cli-reference)
|
||||
- [Claude Agent SDK overview](https://platform.claude.com/docs/en/agent-sdk/overview)
|
||||
- [Using Claude Code with your Pro or Max plan](https://support.claude.com/en/articles/11145838-using-claude-code-with-your-pro-or-max-plan)
|
||||
- [Using Claude Code with your Team or Enterprise plan](https://support.anthropic.com/en/articles/11845131-using-claude-code-with-your-team-or-enterprise-plan/)
|
||||
|
||||
</Warning>
|
||||
|
||||
@@ -66,7 +61,7 @@ Anthropic's current public docs:
|
||||
```json5
|
||||
{
|
||||
env: { ANTHROPIC_API_KEY: "example-anthropic-key-not-real" },
|
||||
agents: { defaults: { model: { primary: "anthropic/claude-opus-4-8" } } },
|
||||
agents: { defaults: { model: { primary: "anthropic/claude-opus-4-6" } } },
|
||||
}
|
||||
```
|
||||
|
||||
@@ -118,9 +113,9 @@ Anthropic's current public docs:
|
||||
{
|
||||
agents: {
|
||||
defaults: {
|
||||
model: { primary: "anthropic/claude-opus-4-8" },
|
||||
model: { primary: "anthropic/claude-opus-4-7" },
|
||||
models: {
|
||||
"anthropic/claude-opus-4-8": {
|
||||
"anthropic/claude-opus-4-7": {
|
||||
agentRuntime: { id: "claude-cli" },
|
||||
},
|
||||
},
|
||||
@@ -133,36 +128,16 @@ Anthropic's current public docs:
|
||||
compatibility, but new config should keep provider/model selection as
|
||||
`anthropic/*` and put the execution backend in provider/model runtime policy.
|
||||
|
||||
### Billing and `claude -p`
|
||||
|
||||
OpenClaw uses Claude Code's non-interactive `claude -p` path for Claude CLI
|
||||
runs. Anthropic currently treats that path as Agent SDK/programmatic usage:
|
||||
|
||||
- Until June 15, 2026, subscription-plan handling follows Anthropic's active
|
||||
Claude Code rules for the signed-in account.
|
||||
- Starting June 15, 2026, subscription-plan `claude -p` usage draws from the
|
||||
user's monthly Agent SDK credit first, then from usage credits at standard
|
||||
API rates if usage credits are enabled.
|
||||
- Console/API-key logins use pay-as-you-go API billing and do not receive
|
||||
the subscription Agent SDK credit.
|
||||
|
||||
Anthropic can change Claude Code billing and rate-limit behavior without an
|
||||
OpenClaw release. Check `claude auth status`, `/status`, and
|
||||
Anthropic's linked docs when billing predictability matters.
|
||||
|
||||
<Tip>
|
||||
For shared production automation, use an Anthropic API key instead of
|
||||
Claude CLI. OpenClaw also supports subscription-style options from
|
||||
[OpenAI Codex](/providers/openai), [Qwen Cloud](/providers/qwen),
|
||||
[MiniMax](/providers/minimax), and [Z.AI / GLM](/providers/zai).
|
||||
If you want the clearest billing path, use an Anthropic API key instead. OpenClaw also supports subscription-style options from [OpenAI Codex](/providers/openai), [Qwen Cloud](/providers/qwen), [MiniMax](/providers/minimax), and [Z.AI / GLM](/providers/zai).
|
||||
</Tip>
|
||||
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
## Thinking defaults (Claude 4.8 and 4.6)
|
||||
## Thinking defaults (Claude 4.6)
|
||||
|
||||
Claude Opus 4.8 keeps thinking off by default in OpenClaw. When you explicitly enable adaptive thinking with `/think high|xhigh|max`, OpenClaw sends Anthropic's Opus 4.8 effort values; Claude 4.6 models default to `adaptive`.
|
||||
Claude 4.6 models default to `adaptive` thinking in OpenClaw when no explicit thinking level is set.
|
||||
|
||||
Override per-message with `/think:<level>` or in model params:
|
||||
|
||||
@@ -171,8 +146,8 @@ Override per-message with `/think:<level>` or in model params:
|
||||
agents: {
|
||||
defaults: {
|
||||
models: {
|
||||
"anthropic/claude-opus-4-8": {
|
||||
params: { thinking: "high" },
|
||||
"anthropic/claude-opus-4-6": {
|
||||
params: { thinking: "adaptive" },
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -292,7 +267,7 @@ OpenClaw supports Anthropic's prompt caching feature for API-key auth.
|
||||
|
||||
| Property | Value |
|
||||
| --------------- | --------------------- |
|
||||
| Default model | `claude-opus-4-8` |
|
||||
| Default model | `claude-opus-4-7` |
|
||||
| Supported input | Images, PDF documents |
|
||||
|
||||
When an image or PDF is attached to a conversation, OpenClaw automatically
|
||||
@@ -302,7 +277,7 @@ OpenClaw supports Anthropic's prompt caching feature for API-key auth.
|
||||
|
||||
<Accordion title="1M context window">
|
||||
Anthropic's 1M context window is available on GA-capable Claude 4.x models
|
||||
such as Opus 4.8, Opus 4.7, Opus 4.6, and Sonnet 4.6. OpenClaw sizes those models at
|
||||
such as Opus 4.6, Opus 4.7, and Sonnet 4.6. OpenClaw sizes those models at
|
||||
1M automatically:
|
||||
|
||||
```json5
|
||||
@@ -333,8 +308,8 @@ OpenClaw supports Anthropic's prompt caching feature for API-key auth.
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Claude Opus 4.8 1M context">
|
||||
`anthropic/claude-opus-4-8` and its `claude-cli` variant have a 1M context
|
||||
<Accordion title="Claude Opus 4.7 1M context">
|
||||
`anthropic/claude-opus-4-7` and its `claude-cli` variant have a 1M context
|
||||
window by default — no `params.context1m: true` needed.
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
@@ -45,7 +45,7 @@ provider-owned output format through `X-Microsoft-OutputFormat`.
|
||||
provider: "azure-speech",
|
||||
providers: {
|
||||
"azure-speech": {
|
||||
speakerVoice: "en-US-JennyNeural",
|
||||
voice: "en-US-JennyNeural",
|
||||
lang: "en-US",
|
||||
},
|
||||
},
|
||||
@@ -69,7 +69,7 @@ provider-owned output format through `X-Microsoft-OutputFormat`.
|
||||
| `region` | `messages.tts.providers.azure-speech.region` | Azure Speech resource region. Falls back to `AZURE_SPEECH_REGION` or `SPEECH_REGION`. |
|
||||
| `endpoint` | `messages.tts.providers.azure-speech.endpoint` | Optional Azure Speech endpoint/base URL override. |
|
||||
| `baseUrl` | `messages.tts.providers.azure-speech.baseUrl` | Optional Azure Speech base URL override. |
|
||||
| `speakerVoice` | `messages.tts.providers.azure-speech.speakerVoice` | Azure voice ShortName (default `en-US-JennyNeural`). Legacy alias: `voice`. |
|
||||
| `voice` | `messages.tts.providers.azure-speech.voice` | Azure voice ShortName (default `en-US-JennyNeural`). |
|
||||
| `lang` | `messages.tts.providers.azure-speech.lang` | SSML language code (default `en-US`). |
|
||||
| `outputFormat` | `messages.tts.providers.azure-speech.outputFormat` | Audio-file output format (default `audio-24khz-48kbitrate-mono-mp3`). |
|
||||
| `voiceNoteOutputFormat` | `messages.tts.providers.azure-speech.voiceNoteOutputFormat` | Voice-note output format (default `ogg-24khz-16bit-mono-opus`). |
|
||||
|
||||
@@ -12,31 +12,23 @@ title: "Claude Max API proxy"
|
||||
<Warning>
|
||||
This path is technical compatibility only. Anthropic has blocked some subscription
|
||||
usage outside Claude Code in the past. You must decide for yourself whether to use
|
||||
it and verify Anthropic's current billing rules before relying on it.
|
||||
|
||||
Anthropic's current support docs say `claude -p` is Agent SDK/programmatic usage.
|
||||
Starting June 15, 2026, subscription-plan `claude -p` usage draws from a separate
|
||||
monthly Agent SDK credit first, then from usage credits at standard API rates if
|
||||
usage credits are enabled.
|
||||
it and verify Anthropic's current terms before relying on it.
|
||||
</Warning>
|
||||
|
||||
## Why use this?
|
||||
|
||||
| Approach | Cost route | Best for |
|
||||
| ------------------------- | ----------------------------------------------- | ------------------------------------------ |
|
||||
| Anthropic API | Pay per token through Claude Console or cloud | Production apps, shared automation, volume |
|
||||
| Claude subscription proxy | Claude Code / `claude -p` plan and credit rules | Personal experiments with compatible tools |
|
||||
| Approach | Cost | Best For |
|
||||
| ----------------------- | --------------------------------------------------- | ------------------------------------------ |
|
||||
| Anthropic API | Pay per token (~$15/M input, $75/M output for Opus) | Production apps, high volume |
|
||||
| Claude Max subscription | $200/month flat | Personal use, development, unlimited usage |
|
||||
|
||||
If you have a Claude Max or Pro subscription and want to use it with
|
||||
OpenAI-compatible tools, this proxy may fit some personal workflows. It is not an
|
||||
unlimited flat-rate path. API keys remain the clearer policy and billing path for
|
||||
production use.
|
||||
If you have a Claude Max subscription and want to use it with OpenAI-compatible tools, this proxy may reduce cost for some workflows. API keys remain the clearer policy path for production use.
|
||||
|
||||
## How it works
|
||||
|
||||
```
|
||||
Your App → claude-max-api-proxy → Claude Code CLI / claude -p → Anthropic
|
||||
(OpenAI format) (converts format) (uses your login)
|
||||
Your App → claude-max-api-proxy → Claude Code CLI → Anthropic (via subscription)
|
||||
(OpenAI format) (converts format) (uses your login)
|
||||
```
|
||||
|
||||
The proxy:
|
||||
@@ -165,7 +157,6 @@ The proxy:
|
||||
|
||||
- This is a **community tool**, not officially supported by Anthropic or OpenClaw
|
||||
- Requires an active Claude Max/Pro subscription with Claude Code CLI authenticated
|
||||
- Inherits Claude Code `claude -p` billing, usage-credit, and rate-limit behavior
|
||||
- The proxy runs locally and does not send data to any third-party servers
|
||||
- Streaming responses are fully supported
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ export ELEVENLABS_API_KEY="..."
|
||||
providers: {
|
||||
elevenlabs: {
|
||||
apiKey: "${ELEVENLABS_API_KEY}",
|
||||
speakerVoiceId: "pMsXgVXv3BLzUgSXRplE",
|
||||
voiceId: "pMsXgVXv3BLzUgSXRplE",
|
||||
modelId: "eleven_multilingual_v2",
|
||||
},
|
||||
},
|
||||
|
||||
@@ -44,46 +44,24 @@ generation.
|
||||
The bundled `fal` image-generation provider defaults to
|
||||
`fal/fal-ai/flux/dev`.
|
||||
|
||||
| Capability | Value |
|
||||
| -------------- | ------------------------------------------------------------------ |
|
||||
| Max images | 4 per request; Krea 2: 1 per request |
|
||||
| Edit mode | Flux: 1 reference image; GPT Image 2: 10; Nano Banana 2: 14 |
|
||||
| Style refs | Krea 2: up to 10 style references via `image` / `images` |
|
||||
| Size overrides | Supported |
|
||||
| Aspect ratio | Supported for generate, Krea 2, and GPT Image 2/Nano Banana 2 edit |
|
||||
| Resolution | Supported |
|
||||
| Output format | `png` or `jpeg` |
|
||||
| Capability | Value |
|
||||
| -------------- | ----------------------------------------------------------- |
|
||||
| Max images | 4 per request |
|
||||
| Edit mode | Flux: 1 reference image; GPT Image 2: 10; Nano Banana 2: 14 |
|
||||
| Size overrides | Supported |
|
||||
| Aspect ratio | Supported for generate and GPT Image 2/Nano Banana 2 edit |
|
||||
| Resolution | Supported |
|
||||
| Output format | `png` or `jpeg` |
|
||||
|
||||
<Warning>
|
||||
Flux image-to-image requests do **not** support `aspectRatio` overrides. GPT
|
||||
Image 2 and Nano Banana 2 edit requests use fal's `/edit` endpoint and accept
|
||||
aspect-ratio hints. Nano Banana 2 also accepts extra-native wide/tall ratios
|
||||
such as `4:1`, `1:4`, `8:1`, and `1:8`; Krea 2 validates its own smaller
|
||||
aspect-ratio subset.
|
||||
aspect-ratio hints.
|
||||
</Warning>
|
||||
|
||||
Krea 2 models use fal's native Krea payload schema. OpenClaw sends
|
||||
`aspect_ratio`, `creativity`, and `image_style_references` instead of the
|
||||
generic `image_size` / edit-endpoint payload used by Flux. The model refs are:
|
||||
|
||||
- `fal/krea/v2/medium/text-to-image`
|
||||
- `fal/krea/v2/large/text-to-image`
|
||||
|
||||
Use Medium for faster expressive illustration, anime, painting, and artistic
|
||||
styles. Use Large for slower photoreal, raw texture, film grain, and detailed
|
||||
looks. Krea defaults to `fal.creativity: "medium"`; supported values are
|
||||
`raw`, `low`, `medium`, and `high`.
|
||||
|
||||
Krea 2 exposes aspect ratio, not `image_size`, in fal's request schema. Prefer
|
||||
`aspectRatio`; OpenClaw maps `size` to the closest supported Krea aspect ratio
|
||||
and rejects `resolution` for Krea rather than dropping it.
|
||||
|
||||
Use `outputFormat: "png"` when you want PNG output from fal models that expose
|
||||
`output_format`. fal does not declare an explicit transparent-background
|
||||
control in OpenClaw, so `background: "transparent"` is reported as an ignored
|
||||
override for fal models.
|
||||
Krea 2 endpoints do not expose an `output_format` request field through fal, so
|
||||
OpenClaw rejects `outputFormat` overrides for Krea requests.
|
||||
Use `outputFormat: "png"` when you want PNG output. fal does not declare an
|
||||
explicit transparent-background control in OpenClaw, so `background:
|
||||
"transparent"` is reported as an ignored override for fal models.
|
||||
|
||||
To use fal as the default image provider:
|
||||
|
||||
@@ -99,20 +77,6 @@ To use fal as the default image provider:
|
||||
}
|
||||
```
|
||||
|
||||
To use Krea 2 Medium:
|
||||
|
||||
```json5
|
||||
{
|
||||
agents: {
|
||||
defaults: {
|
||||
imageGenerationModel: {
|
||||
primary: "fal/krea/v2/medium/text-to-image",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
## Video generation
|
||||
|
||||
The bundled `fal` video-generation provider defaults to
|
||||
|
||||
@@ -303,7 +303,7 @@ To use Google as the default TTS provider:
|
||||
providers: {
|
||||
google: {
|
||||
model: "gemini-3.1-flash-tts-preview",
|
||||
speakerVoice: "Kore",
|
||||
voiceName: "Kore",
|
||||
audioProfile: "Speak professionally with a calm tone.",
|
||||
},
|
||||
},
|
||||
@@ -367,7 +367,7 @@ Example Voice Call realtime config:
|
||||
providers: {
|
||||
google: {
|
||||
model: "gemini-2.5-flash-native-audio-preview-12-2025",
|
||||
speakerVoice: "Kore",
|
||||
voice: "Kore",
|
||||
activityHandling: "start-of-activity-interrupts",
|
||||
turnCoverage: "only-activity",
|
||||
},
|
||||
|
||||
@@ -57,7 +57,7 @@ The plugin checks the resolved `apiKey` first and falls back to the `GRADIUM_API
|
||||
provider: "gradium",
|
||||
providers: {
|
||||
gradium: {
|
||||
speakerVoiceId: "YTpq7expH9539ERJ",
|
||||
voiceId: "YTpq7expH9539ERJ",
|
||||
// apiKey: "${GRADIUM_API_KEY}",
|
||||
// baseUrl: "https://api.gradium.ai",
|
||||
},
|
||||
@@ -67,11 +67,11 @@ The plugin checks the resolved `apiKey` first and falls back to the `GRADIUM_API
|
||||
}
|
||||
```
|
||||
|
||||
| Key | Type | Description |
|
||||
| ----------------------------------------------- | ------ | --------------------------------------------------------------------------------------------- |
|
||||
| `messages.tts.providers.gradium.apiKey` | string | Resolved API key. Supports `${ENV}` and secret refs. |
|
||||
| `messages.tts.providers.gradium.baseUrl` | string | Override the API origin. Trailing slashes are stripped. Defaults to `https://api.gradium.ai`. |
|
||||
| `messages.tts.providers.gradium.speakerVoiceId` | string | Default voice id used when no directive override is present. |
|
||||
| Key | Type | Description |
|
||||
| ---------------------------------------- | ------ | --------------------------------------------------------------------------------------------- |
|
||||
| `messages.tts.providers.gradium.apiKey` | string | Resolved API key. Supports `${ENV}` and secret refs. |
|
||||
| `messages.tts.providers.gradium.baseUrl` | string | Override the API origin. Trailing slashes are stripped. Defaults to `https://api.gradium.ai`. |
|
||||
| `messages.tts.providers.gradium.voiceId` | string | Default voice id used when no directive override is present. |
|
||||
|
||||
The output audio format is selected automatically by the runtime based on the target surface and is not configurable from `openclaw.json`. See [Output](#output) below.
|
||||
|
||||
@@ -91,7 +91,7 @@ Default voice: Emma.
|
||||
|
||||
### Per-message voice override
|
||||
|
||||
When the active speech policy allows voice overrides, you can switch voices inline using a directive token. Use `speakerVoiceId` for provider-native voice ids.
|
||||
When the active speech policy allows voice overrides, you can switch voices inline using a directive token. All of these resolve to the same `voiceId` override:
|
||||
|
||||
```text
|
||||
/voice:LFZvm12tW_z0xfGo
|
||||
|
||||
@@ -50,7 +50,7 @@ the standard reply-audio pipeline.
|
||||
provider: "inworld",
|
||||
providers: {
|
||||
inworld: {
|
||||
speakerVoiceId: "Sarah",
|
||||
voiceId: "Sarah",
|
||||
modelId: "inworld-tts-1.5-max",
|
||||
},
|
||||
},
|
||||
@@ -68,13 +68,13 @@ the standard reply-audio pipeline.
|
||||
|
||||
## Configuration options
|
||||
|
||||
| Option | Path | Description |
|
||||
| ---------------- | ----------------------------------------------- | ----------------------------------------------------------------- |
|
||||
| `apiKey` | `messages.tts.providers.inworld.apiKey` | Base64 dashboard credential. Falls back to `INWORLD_API_KEY`. |
|
||||
| `baseUrl` | `messages.tts.providers.inworld.baseUrl` | Override Inworld API base URL (default `https://api.inworld.ai`). |
|
||||
| `speakerVoiceId` | `messages.tts.providers.inworld.speakerVoiceId` | Voice identifier (default `Sarah`). |
|
||||
| `modelId` | `messages.tts.providers.inworld.modelId` | TTS model id (default `inworld-tts-1.5-max`). |
|
||||
| `temperature` | `messages.tts.providers.inworld.temperature` | Sampling temperature `0..2` (optional). |
|
||||
| Option | Path | Description |
|
||||
| ------------- | -------------------------------------------- | ----------------------------------------------------------------- |
|
||||
| `apiKey` | `messages.tts.providers.inworld.apiKey` | Base64 dashboard credential. Falls back to `INWORLD_API_KEY`. |
|
||||
| `baseUrl` | `messages.tts.providers.inworld.baseUrl` | Override Inworld API base URL (default `https://api.inworld.ai`). |
|
||||
| `voiceId` | `messages.tts.providers.inworld.voiceId` | Voice identifier (default `Sarah`). |
|
||||
| `modelId` | `messages.tts.providers.inworld.modelId` | TTS model id (default `inworld-tts-1.5-max`). |
|
||||
| `temperature` | `messages.tts.providers.inworld.temperature` | Sampling temperature `0..2` (optional). |
|
||||
|
||||
## Notes
|
||||
|
||||
|
||||
@@ -275,14 +275,14 @@ The bundled `minimax` plugin registers MiniMax T2A v2 as a speech provider for
|
||||
- MiniMax T2A accepts fractional `speed` and `vol`, but `pitch` is sent as an
|
||||
integer; OpenClaw truncates fractional `pitch` values before the API request.
|
||||
|
||||
| Setting | Env var | Default | Description |
|
||||
| ----------------------------------------------- | ---------------------- | ----------------------------- | -------------------------------- |
|
||||
| `messages.tts.providers.minimax.baseUrl` | `MINIMAX_API_HOST` | `https://api.minimax.io` | MiniMax T2A API host. |
|
||||
| `messages.tts.providers.minimax.model` | `MINIMAX_TTS_MODEL` | `speech-2.8-hd` | TTS model id. |
|
||||
| `messages.tts.providers.minimax.speakerVoiceId` | `MINIMAX_TTS_VOICE_ID` | `English_expressive_narrator` | Voice id used for speech output. |
|
||||
| `messages.tts.providers.minimax.speed` | | `1.0` | Playback speed, `0.5..2.0`. |
|
||||
| `messages.tts.providers.minimax.vol` | | `1.0` | Volume, `(0, 10]`. |
|
||||
| `messages.tts.providers.minimax.pitch` | | `0` | Integer pitch shift, `-12..12`. |
|
||||
| Setting | Env var | Default | Description |
|
||||
| ---------------------------------------- | ---------------------- | ----------------------------- | -------------------------------- |
|
||||
| `messages.tts.providers.minimax.baseUrl` | `MINIMAX_API_HOST` | `https://api.minimax.io` | MiniMax T2A API host. |
|
||||
| `messages.tts.providers.minimax.model` | `MINIMAX_TTS_MODEL` | `speech-2.8-hd` | TTS model id. |
|
||||
| `messages.tts.providers.minimax.voiceId` | `MINIMAX_TTS_VOICE_ID` | `English_expressive_narrator` | Voice id used for speech output. |
|
||||
| `messages.tts.providers.minimax.speed` | | `1.0` | Playback speed, `0.5..2.0`. |
|
||||
| `messages.tts.providers.minimax.vol` | | `1.0` | Volume, `(0, 10]`. |
|
||||
| `messages.tts.providers.minimax.pitch` | | `0` | Integer pitch shift, `-12..12`. |
|
||||
|
||||
### Music generation
|
||||
|
||||
|
||||
@@ -679,7 +679,7 @@ Use these as starting points and replace model IDs with the exact names from `ol
|
||||
```
|
||||
|
||||
Use `compat.supportsTools: false` only when the model or server reliably fails on tool schemas. It trades agent capability for stability.
|
||||
`localModelLean` removes the browser, cron, and message tools from the model-visible agent surface, but it does not change Ollama's runtime context or thinking mode. If Code Mode or Tool Search is enabled, those tools can still be called from the hidden catalog. Pair lean mode with explicit `params.num_ctx` and `params.thinking: false` for small Qwen-style thinking models that loop or spend their response budget on hidden reasoning.
|
||||
`localModelLean` removes the browser, cron, and message tools from the agent surface, but it does not change Ollama's runtime context or thinking mode. Pair it with explicit `params.num_ctx` and `params.thinking: false` for small Qwen-style thinking models that loop or spend their response budget on hidden reasoning.
|
||||
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
@@ -621,7 +621,7 @@ Legacy `plugins.entries.openai.config.personality` is still read as a compatibil
|
||||
| Setting | Config path | Default |
|
||||
|---------|------------|---------|
|
||||
| Model | `messages.tts.providers.openai.model` | `gpt-4o-mini-tts` |
|
||||
| Voice | `messages.tts.providers.openai.speakerVoice` | `coral` |
|
||||
| Voice | `messages.tts.providers.openai.voice` | `coral` |
|
||||
| Speed | `messages.tts.providers.openai.speed` | (unset) |
|
||||
| Instructions | `messages.tts.providers.openai.instructions` | (unset, `gpt-4o-mini-tts` only) |
|
||||
| Format | `messages.tts.providers.openai.responseFormat` | `opus` for voice notes, `mp3` for files |
|
||||
@@ -638,7 +638,7 @@ Legacy `plugins.entries.openai.config.personality` is still read as a compatibil
|
||||
messages: {
|
||||
tts: {
|
||||
providers: {
|
||||
openai: { model: "gpt-4o-mini-tts", speakerVoice: "coral" },
|
||||
openai: { model: "gpt-4o-mini-tts", voice: "coral" },
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
@@ -150,7 +150,7 @@ OpenRouter can also be used as a TTS provider through its OpenAI-compatible
|
||||
providers: {
|
||||
openrouter: {
|
||||
model: "hexgrad/kokoro-82m",
|
||||
speakerVoice: "af_alloy",
|
||||
voice: "af_alloy",
|
||||
responseFormat: "mp3",
|
||||
},
|
||||
},
|
||||
|
||||
@@ -144,7 +144,7 @@ OpenClaw uses the same `VYDRA_API_KEY` for all three capabilities.
|
||||
providers: {
|
||||
vydra: {
|
||||
apiKey: "${VYDRA_API_KEY}",
|
||||
speakerVoiceId: "21m00Tcm4TlvDq8ikWAM",
|
||||
voiceId: "21m00Tcm4TlvDq8ikWAM",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
@@ -319,7 +319,7 @@ Legacy aliases still normalize to the canonical bundled ids:
|
||||
provider: "xai",
|
||||
providers: {
|
||||
xai: {
|
||||
speakerVoiceId: "eve",
|
||||
voiceId: "eve",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
@@ -82,7 +82,7 @@ an `assistant` message and optional style guidance as a `user` message.
|
||||
xiaomi: {
|
||||
apiKey: "xiaomi_api_key",
|
||||
model: "mimo-v2.5-tts",
|
||||
speakerVoice: "mimo_default",
|
||||
voice: "mimo_default",
|
||||
format: "mp3",
|
||||
style: "Bright, natural, conversational tone.",
|
||||
},
|
||||
|
||||
@@ -685,12 +685,10 @@ gh workflow run openclaw-release-publish.yml \
|
||||
```
|
||||
|
||||
Use the lower-level `Plugin NPM Release` and `Plugin ClawHub Release` workflows
|
||||
only for focused repair or republish work. `OpenClaw Release Publish` rejects
|
||||
`plugin_publish_scope=selected` when `publish_openclaw_npm=true` so the core
|
||||
package cannot ship without every publishable official plugin, including
|
||||
`@openclaw/diffs-language-pack`. For a selected plugin repair, set
|
||||
`publish_openclaw_npm=false` with `plugin_publish_scope=selected` and
|
||||
`plugins=@openclaw/name`, or dispatch the child workflow directly.
|
||||
only for focused repair or republish work. For a selected plugin repair, pass
|
||||
`plugin_publish_scope=selected` and `plugins=@openclaw/name` to
|
||||
`OpenClaw Release Publish`, or dispatch the child workflow directly when the
|
||||
OpenClaw package must not be published.
|
||||
|
||||
## NPM workflow inputs
|
||||
|
||||
@@ -712,7 +710,7 @@ package cannot ship without every publishable official plugin, including
|
||||
required when `publish_openclaw_npm=true`
|
||||
- `npm_dist_tag`: npm target tag for the OpenClaw package
|
||||
- `plugin_publish_scope`: defaults to `all-publishable`; use `selected` only
|
||||
for focused plugin-only repair work with `publish_openclaw_npm=false`
|
||||
for focused repair work
|
||||
- `plugins`: comma-separated `@openclaw/*` package names when
|
||||
`plugin_publish_scope=selected`
|
||||
- `publish_openclaw_npm`: defaults to `true`; set `false` only when using the
|
||||
|
||||
@@ -205,7 +205,7 @@ override only `cacheRetention` and inherit other model defaults unchanged.
|
||||
|
||||
### Anthropic 1M context
|
||||
|
||||
OpenClaw sizes GA-capable Claude 4.x models such as Opus 4.8, Opus 4.7, Opus 4.6, and
|
||||
OpenClaw sizes GA-capable Claude 4.x models such as Opus 4.6, Opus 4.7, and
|
||||
Sonnet 4.6 with Anthropic's 1M context window. You do not need
|
||||
`params.context1m: true` for those models.
|
||||
|
||||
|
||||
@@ -134,7 +134,7 @@ Configure the proxy to:
|
||||
|
||||
Use this denylist as the starting point for any forward proxy, firewall, or egress policy.
|
||||
|
||||
OpenClaw application-level classifier logic lives in `src/infra/net/ssrf.ts` and `packages/net-policy/src/ip.ts`. The relevant parity hooks are `BLOCKED_HOSTNAMES`, `BLOCKED_IPV4_SPECIAL_USE_RANGES`, `BLOCKED_IPV6_SPECIAL_USE_RANGES`, `RFC2544_BENCHMARK_PREFIX`, and the embedded IPv4 sentinel handling for NAT64, 6to4, Teredo, ISATAP, and IPv4-mapped forms. Those files are useful references when maintaining an external proxy policy, but OpenClaw does not automatically export or enforce those rules in your proxy.
|
||||
OpenClaw application-level classifier logic lives in `src/infra/net/ssrf.ts` and `src/shared/net/ip.ts`. The relevant parity hooks are `BLOCKED_HOSTNAMES`, `BLOCKED_IPV4_SPECIAL_USE_RANGES`, `BLOCKED_IPV6_SPECIAL_USE_RANGES`, `RFC2544_BENCHMARK_PREFIX`, and the embedded IPv4 sentinel handling for NAT64, 6to4, Teredo, ISATAP, and IPv4-mapped forms. Those files are useful references when maintaining an external proxy policy, but OpenClaw does not automatically export or enforce those rules in your proxy.
|
||||
|
||||
| Range or host | Why to block |
|
||||
| ------------------------------------------------------------------------------------ | ---------------------------------------------------- |
|
||||
|
||||
@@ -1,247 +0,0 @@
|
||||
---
|
||||
title: Claw Supervisor
|
||||
description: Fleet supervision plan for Codex app-server sessions controlled by OpenClaw.
|
||||
readWhen:
|
||||
- Designing Codex fleet supervision
|
||||
- Building OpenClaw tools that read, steer, or spawn Codex sessions
|
||||
- Choosing between local, Cloudflare, and VPS deployment for supervised Codex
|
||||
---
|
||||
|
||||
# Claw Supervisor
|
||||
|
||||
## Goal
|
||||
|
||||
Claw Supervisor lets one always-on OpenClaw instance monitor and drive a fleet of Codex sessions without changing the normal Codex user experience. A user can SSH into a host, start Codex, work in the TUI, and still have the supervisor read the session, steer it, interrupt it, spawn related sessions, and accept handoffs. Codex sessions can also call back into OpenClaw through MCP.
|
||||
|
||||
## Product Model
|
||||
|
||||
Codex remains the primary work surface. OpenClaw supervises Codex rather than hiding Codex inside an opaque OpenClaw subagent.
|
||||
|
||||
The OpenClaw plugin is named `codex-supervisor`. `crabfleet` remains the deployment
|
||||
and host-fleet profile for CRAB machines rather than the reusable plugin name.
|
||||
|
||||
The model has three roles:
|
||||
|
||||
- Human-attached Codex: a normal interactive Codex TUI launched through a shared app-server.
|
||||
- Autonomous Codex: a Codex app-server thread spawned by the supervisor that a human can later attach to.
|
||||
- Supervisor Claw: an always-on OpenClaw agent with tools for fleet state, transcript reads, steering, interruption, spawning, and handoff.
|
||||
|
||||
OpenClaw may use its existing subagent machinery internally, but the external contract is an attachable Codex session with a Codex thread id.
|
||||
|
||||
## Architecture
|
||||
|
||||
```text
|
||||
user SSH session
|
||||
-> codex --remote unix://... or ws://...
|
||||
-> local codex app-server daemon
|
||||
<-> host sidecar / supervisor connector
|
||||
<-> OpenClaw fleet supervisor
|
||||
<-> supervisor MCP exposed back to Codex
|
||||
```
|
||||
|
||||
Each Codex-capable host runs:
|
||||
|
||||
- Codex app-server daemon.
|
||||
- A launcher that always starts interactive Codex with `--remote`.
|
||||
- A connector that registers app-server endpoints and live threads with the supervisor.
|
||||
|
||||
The supervisor runs:
|
||||
|
||||
- Endpoint registry.
|
||||
- Session registry.
|
||||
- Codex app-server JSON-RPC client pool.
|
||||
- MCP server for Codex-to-Claw calls.
|
||||
- OpenClaw tools for Claw-to-Codex control.
|
||||
- Policy engine for autonomous actions, approvals, and loop prevention.
|
||||
|
||||
## Codex App-Server Contract
|
||||
|
||||
Use Codex app-server APIs as the canonical control plane:
|
||||
|
||||
- `initialize`, `initialized`
|
||||
- `thread/loaded/list`
|
||||
- `thread/list`
|
||||
- `thread/read`
|
||||
- `thread/resume`
|
||||
- `thread/start`
|
||||
- `turn/start`
|
||||
- `turn/steer`
|
||||
- `turn/interrupt`
|
||||
- `model/list`
|
||||
|
||||
Interactive Codex must be launched with `codex --remote <endpoint>` so the TUI and supervisor connect to the same app-server. Standalone `codex exec` is not a live-shared session today; use app-server APIs for autonomous work until Codex supports `exec --remote`.
|
||||
|
||||
## Session Registry
|
||||
|
||||
Supervisor stores one record per observed Codex thread:
|
||||
|
||||
```json
|
||||
{
|
||||
"sessionId": "codex-thread-id",
|
||||
"endpointId": "host-a",
|
||||
"host": "host-a.example",
|
||||
"workspace": "/workspace/repo",
|
||||
"repo": "owner/repo",
|
||||
"branch": "feature/example",
|
||||
"source": "vscode",
|
||||
"status": "idle",
|
||||
"humanAttached": true,
|
||||
"lastSeenAt": "2026-05-28T10:00:00.000Z",
|
||||
"summary": "Short working-state summary"
|
||||
}
|
||||
```
|
||||
|
||||
The local implementation can derive most fields from Codex thread metadata. Fleet deployment should enrich records with host identity, user attachment state, git state, and sidecar health.
|
||||
|
||||
## MCP Surface For Codex
|
||||
|
||||
Every supervised Codex gets an MCP server named `openclaw-codex-supervisor`.
|
||||
|
||||
Tools:
|
||||
|
||||
- `codex_sessions_list`: list visible Codex sessions.
|
||||
- `codex_session_read`: read one transcript.
|
||||
- `codex_session_send`: send a message to an idle thread or steer an active thread.
|
||||
- `codex_session_interrupt`: interrupt the active turn.
|
||||
- `codex_endpoint_probe`: verify endpoint connectivity.
|
||||
- `claw_report_progress`: publish current task state to the supervisor.
|
||||
- `claw_ask`: ask the supervisor for help or delegation.
|
||||
- `codex_spawn`: create a new autonomous Codex session.
|
||||
- `codex_handoff`: request human or peer takeover.
|
||||
|
||||
Resources:
|
||||
|
||||
- `codex://sessions`
|
||||
- `codex://sessions/{sessionId}`
|
||||
- `codex://sessions/{sessionId}/transcript`
|
||||
|
||||
## Claw Control Surface
|
||||
|
||||
The always-on Claw gets the same primitives as internal tools:
|
||||
|
||||
- list sessions and endpoints
|
||||
- read transcripts
|
||||
- send/steer text
|
||||
- interrupt active work
|
||||
- spawn new sessions
|
||||
- summarize and assign sessions
|
||||
- broadcast instructions to a filtered group
|
||||
- mark sessions blocked, done, or abandoned
|
||||
|
||||
Tool behavior:
|
||||
|
||||
- If a target thread is idle, `codex_session_send` maps to `turn/start`.
|
||||
- If a target thread is active and an in-progress turn id is visible, it maps to `turn/steer`.
|
||||
- If the active turn cannot be identified, the tool fails closed instead of creating an unrelated turn.
|
||||
- Codex-exposed MCP write controls stay disabled unless a trusted supervisor-only policy enables them.
|
||||
- Raw transcript reads stay disabled unless a trusted supervisor-only policy enables them.
|
||||
- Autonomous approval defaults deny tool/file approvals unless an explicit policy says otherwise.
|
||||
|
||||
## Launch Flow
|
||||
|
||||
Interactive host login:
|
||||
|
||||
1. User SSHes into a CRAB host.
|
||||
2. SSH service starts or verifies `codex app-server daemon start`.
|
||||
3. Login wrapper launches `codex --remote unix:// --cd <workspace>`.
|
||||
4. Host connector registers endpoint and loaded thread.
|
||||
5. Supervisor emits a high-priority fleet event: new Codex session, workspace, human-attached state, current task preview.
|
||||
6. Supervisor Claw can read and steer immediately.
|
||||
|
||||
Autonomous spawn:
|
||||
|
||||
1. Supervisor selects host and workspace.
|
||||
2. Host connector opens or resumes a Codex app-server thread.
|
||||
3. Supervisor starts the first turn with task text and MCP config.
|
||||
4. Session registry marks it autonomous and attachable.
|
||||
5. Human can later attach with `codex --remote <endpoint> resume <threadId>` once Codex supports that exact UX, or via current resume flow on the same app-server.
|
||||
|
||||
## Deployment
|
||||
|
||||
Preferred control plane:
|
||||
|
||||
- Host connectors keep outbound WebSocket connections to the supervisor.
|
||||
- Supervisor state lives in OpenClaw Gateway storage.
|
||||
- Codex app-server remains local to each host; never expose a raw unauthenticated app-server to the public internet.
|
||||
|
||||
Cloudflare viability:
|
||||
|
||||
- Good for registry, durable objects, WebSocket fan-in, lightweight event routing, and public MCP/gateway endpoints.
|
||||
- Not enough by itself for direct private host control because Workers cannot dial arbitrary private Unix sockets or local loopback app-servers.
|
||||
- Use Cloudflare when every host connector phones home over outbound WebSocket.
|
||||
|
||||
VPS fallback:
|
||||
|
||||
- Use a Hetzner service when long-lived process control, SSH tunnels, private network routing, or local filesystem access is needed.
|
||||
- Keep the same protocol: host connectors outbound, supervisor registry central, Codex app-server local.
|
||||
|
||||
## Security
|
||||
|
||||
- Default bind is local Unix socket.
|
||||
- Remote app-server uses token or signed bearer auth.
|
||||
- Host connector authenticates to supervisor with a scoped host token.
|
||||
- Supervisor tools enforce per-session policy: read, steer, interrupt, spawn, approval.
|
||||
- Cross-agent messages include `originSessionId`; self-echo is dropped.
|
||||
- Broadcast requires an explicit filter and bounded target count.
|
||||
- Transcript reads redact secrets at OpenClaw boundary.
|
||||
- Approval requests default to deny for supervisor-originated turns unless policy allows them.
|
||||
|
||||
## Implementation Plan
|
||||
|
||||
Phase 1: Local supervisor MVP
|
||||
|
||||
- Add Codex app-server JSON-RPC client for stdio proxy and WebSocket endpoints.
|
||||
- Add supervisor endpoint/session registry.
|
||||
- Add MCP tools: list, read, send, interrupt, probe.
|
||||
- Add local env config for endpoints.
|
||||
- Add fake app-server tests and one live local app-server smoke.
|
||||
|
||||
Phase 2: OpenClaw integration
|
||||
|
||||
- Register supervisor tools in the `codex-supervisor` plugin.
|
||||
- Inject supervisor MCP into Codex thread config.
|
||||
- Add session summaries to agent context.
|
||||
- Add event notifications when new Codex threads appear.
|
||||
- Add policy config for autonomous send/interrupt/spawn.
|
||||
|
||||
Phase 3: Fleet connector
|
||||
|
||||
- Host sidecar registers app-server endpoint, host metadata, git/workspace metadata, and human attachment state.
|
||||
- Add outbound WebSocket connector for Cloudflare or VPS control plane.
|
||||
- Add reconnect, heartbeat, and stale-session cleanup.
|
||||
- Add CRAB SSH launcher wrapper.
|
||||
|
||||
Phase 4: Autonomous operation
|
||||
|
||||
- Add spawn/resume/takeover flows.
|
||||
- Add broadcast and delegation.
|
||||
- Add progress reports and task-state summaries.
|
||||
- Add loop prevention and rate limits.
|
||||
- Add dashboard views.
|
||||
|
||||
Phase 5: Multi-Claw
|
||||
|
||||
- Shard sessions by group.
|
||||
- Add leadership/lease for each session.
|
||||
- Add audit log and replay.
|
||||
- Add escalation between Claw groups.
|
||||
|
||||
## Acceptance Tests
|
||||
|
||||
- A human launches Codex TUI through a shared app-server.
|
||||
- Supervisor lists the live thread via `thread/loaded/list`.
|
||||
- Supervisor reads transcript via `thread/read`.
|
||||
- Supervisor sends text to an idle thread via `turn/start`.
|
||||
- Supervisor steers an active thread via `turn/steer`.
|
||||
- Supervisor interrupt stops an active turn via `turn/interrupt`.
|
||||
- Codex calls supervisor MCP and lists peer sessions.
|
||||
- An autonomous Codex is spawned and later human-attached.
|
||||
- Lost host connector marks sessions stale without deleting history.
|
||||
|
||||
## Open Questions
|
||||
|
||||
- Exact Codex TUI attach UX for an app-server thread spawned without a TUI.
|
||||
- Whether Codex should add `exec --remote` for headless live-shared runs.
|
||||
- Durable state owner: OpenClaw Gateway DB, Cloudflare Durable Object, or VPS database.
|
||||
- Approval policy granularity for supervisor-originated turns.
|
||||
- How much transcript summary should be injected into the always-on Claw context versus kept as a tool/resource.
|
||||
@@ -114,20 +114,6 @@ Example schema:
|
||||
|
||||
## Policy knobs
|
||||
|
||||
### `tools.exec.mode`
|
||||
|
||||
`tools.exec.mode` is the preferred normalized policy surface for host exec.
|
||||
Values are:
|
||||
|
||||
- `deny` - block host exec.
|
||||
- `allowlist` - run only allowlisted commands without asking.
|
||||
- `ask` - use allowlist policy and ask on misses.
|
||||
- `auto` - use allowlist policy, run deterministic matches directly, and send approval misses through OpenClaw's native auto reviewer before falling back to a human approval route.
|
||||
- `full` - run host exec without approval prompts.
|
||||
|
||||
Legacy `tools.exec.security` / `tools.exec.ask` remain supported and still win
|
||||
when set at the narrower session or agent scope.
|
||||
|
||||
### `exec.security`
|
||||
|
||||
<ParamField path="security" type='"deny" | "allowlist" | "full"'>
|
||||
@@ -303,10 +289,7 @@ EOF
|
||||
### Session-only shortcut
|
||||
|
||||
- `/exec security=full ask=off` changes only the current session.
|
||||
- `/elevated full` is a break-glass shortcut that skips exec approvals only when
|
||||
both the requested policy and the host approvals file resolve to
|
||||
`security: "full"` and `ask: "off"`. A stricter host file, such as
|
||||
`ask: "always"`, still prompts.
|
||||
- `/elevated full` is a break-glass shortcut that also skips exec approvals for that session.
|
||||
|
||||
If the host approvals file stays stricter than config, the stricter host
|
||||
policy still wins.
|
||||
|
||||
@@ -68,7 +68,6 @@ Notes:
|
||||
- `host` defaults to `auto`: sandbox when sandbox runtime is active for the session, otherwise gateway.
|
||||
- `host` only accepts `auto`, `sandbox`, `gateway`, or `node`. It is not a hostname selector; hostname-like values are rejected before the command runs.
|
||||
- `auto` is the default routing strategy, not a wildcard. Per-call `host=node` is allowed from `auto`; per-call `host=gateway` is only allowed when no sandbox runtime is active.
|
||||
- `tools.exec.mode` is the normalized policy knob. Values are `deny`, `allowlist`, `ask`, `auto`, and `full`. `auto` runs deterministic allowlist/safe-bin matches directly and routes every remaining exec approval case through OpenClaw's native auto reviewer before asking a human. `ask` / `ask=always` still asks a human every time.
|
||||
- With no extra config, `host=auto` still "just works": no sandbox means it resolves to `gateway`; a live sandbox means it stays in the sandbox.
|
||||
- `elevated` escapes the sandbox onto the configured host path: `gateway` by default, or `node` when `tools.exec.host=node` (or the session default is `host=node`). It is only available when elevated access is enabled for the current session/provider.
|
||||
- `gateway`/`node` approvals are controlled by `~/.openclaw/exec-approvals.json`.
|
||||
@@ -109,7 +108,7 @@ Notes:
|
||||
- YOLO comes from the host-policy defaults (`security=full`, `ask=off`), not from `host=auto`. If you want to force gateway or node routing, set `tools.exec.host` or use `/exec host=...`.
|
||||
- In `security=full` plus `ask=off` mode, host exec follows the configured policy directly; there is no extra heuristic command-obfuscation prefilter or script-preflight rejection layer.
|
||||
- `tools.exec.node` (default: unset)
|
||||
- `tools.exec.strictInlineEval` (default: false): when true, inline interpreter eval forms such as `python -c`, `node -e`, `ruby -e`, `perl -e`, `php -r`, `lua -e`, and `osascript -e` require reviewer or explicit approval. In `mode=auto`, the native auto reviewer may allow a clearly low-risk one-off command; if the reviewer asks, the request goes to a human. `allow-always` can still persist benign interpreter/script invocations, but inline-eval forms do not become durable allow rules.
|
||||
- `tools.exec.strictInlineEval` (default: false): when true, inline interpreter eval forms such as `python -c`, `node -e`, `ruby -e`, `perl -e`, `php -r`, `lua -e`, and `osascript -e` always require explicit approval. `allow-always` can still persist benign interpreter/script invocations, but inline-eval forms still prompt each time.
|
||||
- `tools.exec.commandHighlighting` (default: false): when true, approval prompts can highlight parser-derived command spans in the command text. Set to `true` globally or per agent to enable command text highlighting without changing exec approval policy.
|
||||
- `tools.exec.pathPrepend`: list of directories to prepend to `PATH` for exec runs (gateway + sandbox only).
|
||||
- `tools.exec.safeBins`: stdin-only safe binaries that can run without explicit allowlist entries. For behavior details, see [Safe bins](/tools/exec-approvals-advanced#safe-bins-stdin-only).
|
||||
@@ -210,7 +209,7 @@ Use the two controls for different jobs:
|
||||
Do not treat `safeBins` as a generic allowlist, and do not add interpreter/runtime binaries (for example `python3`, `node`, `ruby`, `bash`). If you need those, use explicit allowlist entries and keep approval prompts enabled.
|
||||
`openclaw security audit` warns when interpreter/runtime `safeBins` entries are missing explicit profiles, and `openclaw doctor --fix` can scaffold missing custom `safeBinProfiles` entries.
|
||||
`openclaw security audit` and `openclaw doctor` also warn when you explicitly add broad-behavior bins such as `jq` back into `safeBins`.
|
||||
If you explicitly allowlist interpreters, enable `tools.exec.strictInlineEval` so inline code-eval forms still require reviewer or explicit approval.
|
||||
If you explicitly allowlist interpreters, enable `tools.exec.strictInlineEval` so inline code-eval forms still require a fresh approval.
|
||||
|
||||
For full policy details and examples, see [Exec approvals](/tools/exec-approvals-advanced#safe-bins-stdin-only) and [Safe bins versus allowlist](/tools/exec-approvals-advanced#safe-bins-versus-allowlist).
|
||||
|
||||
|
||||
@@ -79,15 +79,12 @@ internal image endpoints remain blocked by default.
|
||||
| OpenAI image generation with Codex subscription auth | `openai/gpt-image-2` | OpenAI Codex OAuth |
|
||||
| OpenAI transparent-background PNG/WebP | `openai/gpt-image-1.5` | `OPENAI_API_KEY` or OpenAI Codex OAuth |
|
||||
| DeepInfra image generation | `deepinfra/black-forest-labs/FLUX-1-schnell` | `DEEPINFRA_API_KEY` |
|
||||
| fal Krea 2 expressive/style-directed generation | `fal/krea/v2/medium/text-to-image` | `FAL_KEY` |
|
||||
| OpenRouter image generation | `openrouter/google/gemini-3.1-flash-image-preview` | `OPENROUTER_API_KEY` |
|
||||
| LiteLLM image generation | `litellm/gpt-image-2` | `LITELLM_API_KEY` |
|
||||
| Google Gemini image generation | `google/gemini-3.1-flash-image-preview` | `GEMINI_API_KEY` or `GOOGLE_API_KEY` |
|
||||
|
||||
The same `image_generate` tool handles text-to-image and reference-image
|
||||
editing. Use `image` for one reference or `images` for multiple references.
|
||||
For Krea 2 models on fal, those references are sent as style references
|
||||
instead of edit inputs.
|
||||
Provider-supported output hints such as `quality`, `outputFormat`, and
|
||||
`background` are forwarded when available and reported as ignored when a
|
||||
provider does not support them. Bundled transparent-background support is
|
||||
@@ -124,13 +121,13 @@ current session:
|
||||
|
||||
## Provider capabilities
|
||||
|
||||
| Capability | ComfyUI | DeepInfra | fal | Google | MiniMax | OpenAI | Vydra | xAI |
|
||||
| --------------------- | ------------------ | --------- | ---------------------------------------------- | -------------- | --------------------- | -------------- | ----- | -------------- |
|
||||
| Generate (max count) | Workflow-defined | 4 | 4 | 4 | 9 | 4 | 1 | 4 |
|
||||
| Edit / reference | 1 image (workflow) | 1 image | Flux: 1; GPT: 10; Krea style refs: 10; NB2: 14 | Up to 5 images | 1 image (subject ref) | Up to 5 images | - | Up to 5 images |
|
||||
| Size control | - | ✓ | ✓ | ✓ | - | Up to 4K | - | - |
|
||||
| Aspect ratio | - | - | ✓ | ✓ | ✓ | - | - | ✓ |
|
||||
| Resolution (1K/2K/4K) | - | - | ✓ | ✓ | - | - | - | 1K, 2K |
|
||||
| Capability | ComfyUI | DeepInfra | fal | Google | MiniMax | OpenAI | Vydra | xAI |
|
||||
| --------------------- | ------------------ | --------- | ------------------------- | -------------- | --------------------- | -------------- | ----- | -------------- |
|
||||
| Generate (max count) | Workflow-defined | 4 | 4 | 4 | 9 | 4 | 1 | 4 |
|
||||
| Edit / reference | 1 image (workflow) | 1 image | Flux: 1; GPT: 10; NB2: 14 | Up to 5 images | 1 image (subject ref) | Up to 5 images | - | Up to 5 images |
|
||||
| Size control | - | ✓ | ✓ | ✓ | - | Up to 4K | - | - |
|
||||
| Aspect ratio | - | - | ✓ | ✓ | ✓ | - | - | ✓ |
|
||||
| Resolution (1K/2K/4K) | - | - | ✓ | ✓ | - | - | - | 1K, 2K |
|
||||
|
||||
## Tool parameters
|
||||
|
||||
@@ -149,16 +146,13 @@ current session:
|
||||
Single reference image path or URL for edit mode.
|
||||
</ParamField>
|
||||
<ParamField path="images" type="string[]">
|
||||
Multiple reference images for edit mode or style-reference models (up to 10
|
||||
through the shared tool; provider-specific limits still apply).
|
||||
Multiple reference images for edit mode (up to 5 on supporting providers).
|
||||
</ParamField>
|
||||
<ParamField path="size" type="string">
|
||||
Size hint: `1024x1024`, `1536x1024`, `1024x1536`, `2048x2048`, `3840x2160`.
|
||||
</ParamField>
|
||||
<ParamField path="aspectRatio" type="string">
|
||||
Aspect ratio: `1:1`, `2:3`, `3:2`, `2.35:1`, `3:4`, `4:3`, `4:5`,
|
||||
`5:4`, `9:16`, `16:9`, `21:9`, `4:1`, `1:4`, `8:1`, `1:8`. Providers
|
||||
validate their model-specific subset.
|
||||
Aspect ratio: `1:1`, `2:3`, `3:2`, `3:4`, `4:3`, `4:5`, `5:4`, `9:16`, `16:9`, `21:9`.
|
||||
</ParamField>
|
||||
<ParamField path="resolution" type='"1K" | "2K" | "4K"'>Resolution hint.</ParamField>
|
||||
<ParamField path="quality" type='"low" | "medium" | "high" | "auto"'>
|
||||
@@ -181,9 +175,6 @@ current session:
|
||||
<ParamField path="openai" type="object">
|
||||
OpenAI-only hints: `background`, `moderation`, `outputCompression`, and `user`.
|
||||
</ParamField>
|
||||
<ParamField path="fal.creativity" type='"raw" | "low" | "medium" | "high"'>
|
||||
fal Krea 2 creativity control. Defaults to `medium`.
|
||||
</ParamField>
|
||||
|
||||
<Note>
|
||||
Not all providers support all parameters. When a fallback provider supports a
|
||||
@@ -262,8 +253,7 @@ from each attempt.
|
||||
### Image editing
|
||||
|
||||
OpenAI, OpenRouter, Google, DeepInfra, fal, MiniMax, ComfyUI, and xAI support editing
|
||||
reference images. Krea 2 models on fal use the same `image` / `images` fields
|
||||
as style references instead of edit inputs. Pass a reference image path or URL:
|
||||
reference images. Pass a reference image path or URL:
|
||||
|
||||
```text
|
||||
"Generate a watercolor version of this photo" + image: "/path/to/photo.jpg"
|
||||
@@ -271,8 +261,8 @@ as style references instead of edit inputs. Pass a reference image path or URL:
|
||||
|
||||
OpenAI, OpenRouter, Google, and xAI support up to 5 reference images via the
|
||||
`images` parameter. fal supports 1 reference image for Flux image-to-image, up
|
||||
to 10 for GPT Image 2 edits, up to 10 style references for Krea 2, and up to
|
||||
14 for Nano Banana 2 edits. MiniMax and ComfyUI support 1.
|
||||
to 10 for GPT Image 2 edits, and up to 14 for Nano Banana 2 edits. MiniMax and
|
||||
ComfyUI support 1.
|
||||
|
||||
## Provider deep dives
|
||||
|
||||
@@ -358,46 +348,6 @@ to 10 for GPT Image 2 edits, up to 10 style references for Krea 2, and up to
|
||||
`google/gemini-3-pro-image-preview`, and `openai/gpt-5.4-image-2`. Use
|
||||
`action: "list"` to see what your configured plugin exposes.
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="fal Krea 2">
|
||||
Krea 2 models on fal use fal's native Krea schema instead of the generic
|
||||
`image_size` schema used by Flux. OpenClaw sends:
|
||||
|
||||
- `aspect_ratio` for aspect-ratio hints
|
||||
- `creativity`, defaulting to `medium`
|
||||
- `image_style_references` when `image` or `images` are supplied
|
||||
|
||||
Select Krea 2 Medium for faster expressive illustration and Krea 2 Large
|
||||
for slower, more detailed photoreal and textured looks:
|
||||
|
||||
```json5
|
||||
{
|
||||
agents: {
|
||||
defaults: {
|
||||
imageGenerationModel: {
|
||||
primary: "fal/krea/v2/medium/text-to-image",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
Krea 2 currently returns one image per request. Prefer `aspectRatio` for
|
||||
Krea; OpenClaw maps `size` to the closest supported Krea aspect ratio and
|
||||
rejects `resolution` for Krea rather than dropping it. Use `fal.creativity`
|
||||
when you want a native Krea creativity level:
|
||||
|
||||
```json
|
||||
{
|
||||
"model": "fal/krea/v2/medium/text-to-image",
|
||||
"prompt": "A cyber zine portrait with risograph texture",
|
||||
"aspectRatio": "9:16",
|
||||
"fal": {
|
||||
"creativity": "high"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="MiniMax dual-auth">
|
||||
MiniMax image generation is available through both bundled MiniMax
|
||||
@@ -463,11 +413,6 @@ openclaw infer image generate \
|
||||
<Tab title="Edit (multiple references)">
|
||||
```text
|
||||
/tool image_generate action=generate model=openai/gpt-image-2 prompt="Combine the character identity from the first image with the color palette from the second" images='["/path/to/character.png","/path/to/palette.jpg"]' size=1536x1024
|
||||
```
|
||||
</Tab>
|
||||
<Tab title="Krea style references">
|
||||
```text
|
||||
/tool image_generate action=generate model=fal/krea/v2/medium/text-to-image prompt="An expressive editorial portrait using this color palette and print texture" images='["/path/to/palette.png","/path/to/texture.jpg"]' aspectRatio=9:16 fal='{"creativity":"high"}'
|
||||
```
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
@@ -178,7 +178,7 @@ Per-agent overrides use `agents.list[].subagents.delegationMode`.
|
||||
The task description for the sub-agent.
|
||||
</ParamField>
|
||||
<ParamField path="taskName" type="string">
|
||||
Optional stable handle for identifying a specific child in later status output. Must match `[a-z][a-z0-9_-]{0,63}` and cannot be reserved targets such as `last` or `all`.
|
||||
Optional stable handle for identifying a specific child in later status output. Must match `[a-z][a-z0-9_]{0,63}` and cannot be reserved targets such as `last` or `all`.
|
||||
</ParamField>
|
||||
<ParamField path="label" type="string">
|
||||
Optional human-readable label.
|
||||
|
||||
@@ -13,9 +13,9 @@ title: "Thinking levels"
|
||||
- low → "think hard"
|
||||
- medium → "think harder"
|
||||
- high → "ultrathink" (max budget)
|
||||
- xhigh → "ultrathink+" (GPT-5.2+ and Codex models, plus Anthropic Claude Opus 4.7+ effort)
|
||||
- adaptive → provider-managed adaptive thinking (supported for Claude 4.6 on Anthropic/Bedrock, Anthropic Claude Opus 4.7+, and Google Gemini dynamic thinking)
|
||||
- max → provider max reasoning (Anthropic Claude Opus 4.7+; Ollama maps this to its highest native `think` effort)
|
||||
- xhigh → "ultrathink+" (GPT-5.2+ and Codex models, plus Anthropic Claude Opus 4.7 effort)
|
||||
- adaptive → provider-managed adaptive thinking (supported for Claude 4.6 on Anthropic/Bedrock, Anthropic Claude Opus 4.7, and Google Gemini dynamic thinking)
|
||||
- max → provider max reasoning (Anthropic Claude Opus 4.7; Ollama maps this to its highest native `think` effort)
|
||||
- `x-high`, `x_high`, `extra-high`, `extra high`, and `extra_high` map to `xhigh`.
|
||||
- `highest` maps to `high`.
|
||||
- Provider notes:
|
||||
@@ -23,9 +23,9 @@ title: "Thinking levels"
|
||||
- `adaptive`, `xhigh`, and `max` are only advertised for provider/model profiles that support them. Typed directives for unsupported levels are rejected with that model's valid options.
|
||||
- Existing stored unsupported levels are remapped by provider profile rank. `adaptive` falls back to `medium` on non-adaptive models, while `xhigh` and `max` fall back to the largest supported non-off level for the selected model.
|
||||
- Anthropic Claude 4.6 models default to `adaptive` when no explicit thinking level is set.
|
||||
- Anthropic Claude Opus 4.8 and Opus 4.7 keep thinking off unless you explicitly set a thinking level. Opus 4.8's provider-owned effort default is `high` after adaptive thinking is enabled.
|
||||
- Anthropic Claude Opus 4.7+ maps `/think xhigh` to adaptive thinking plus `output_config.effort: "xhigh"`, because `/think` is a thinking directive and `xhigh` is the Opus effort setting.
|
||||
- Anthropic Claude Opus 4.7+ also exposes `/think max`; it maps to the same provider-owned max effort path.
|
||||
- Anthropic Claude Opus 4.7 does not default to adaptive thinking. Its API effort default remains provider-owned unless you explicitly set a thinking level.
|
||||
- Anthropic Claude Opus 4.7 maps `/think xhigh` to adaptive thinking plus `output_config.effort: "xhigh"`, because `/think` is a thinking directive and `xhigh` is the Opus 4.7 effort setting.
|
||||
- Anthropic Claude Opus 4.7 also exposes `/think max`; it maps to the same provider-owned max effort path.
|
||||
- Direct DeepSeek V4 models expose `/think xhigh|max`; both map to DeepSeek `reasoning_effort: "max"` while lower non-off levels map to `high`.
|
||||
- OpenRouter-routed DeepSeek V4 models expose `/think xhigh` and send OpenRouter-supported `reasoning_effort` values. Stored `max` overrides fall back to `xhigh`.
|
||||
- Ollama thinking-capable models expose `/think low|medium|high|max`; `max` maps to native `think: "high"` because Ollama's native API accepts `low`, `medium`, and `high` effort strings.
|
||||
@@ -105,7 +105,7 @@ title: "Thinking levels"
|
||||
- Levels: `on|off|stream`.
|
||||
- Directive-only message toggles whether thinking blocks are shown in replies.
|
||||
- When enabled, reasoning is sent as a **separate message** prefixed with `Thinking`.
|
||||
- `stream`: streams reasoning while the reply is generating when the active channel supports reasoning previews, then sends the final answer without reasoning.
|
||||
- `stream` (Telegram only): streams reasoning into the Telegram draft bubble while the reply is generating, then sends the final answer without reasoning.
|
||||
- Alias: `/reason`.
|
||||
- Send `/reasoning` (or `/reasoning:`) with no argument to see the current reasoning level.
|
||||
- Resolution order: inline directive, then session override, then per-agent default (`agents.list[].reasoningDefault`), then global default (`agents.defaults.reasoningDefault`), then fallback (`off`).
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user